PluginProbe
PDF & Print by BestWebSoft – WordPress Posts and Pages PDF Generator Plugin / 1.5
PDF & Print by BestWebSoft – WordPress Posts and Pages PDF Generator Plugin v1.5
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.5, at mpdf/mpdf.php

32,839 lines 1.2 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.4 based on *
6 // FPDF by Olivier PLATHEY *
7 // HTML2FPDF by Renato Coelho *
8 // Date: 2012-02-14 *
9 // Author: Ian Back <ianb@bpm1.com> *
10 // License: GPL *
11 // *
12 // Changes: See changelog.txt *
13 // ******************************************************************************
14
15
16 define('mPDF_VERSION','5.4');
17
18 //Scale factor
19 define('_MPDFK', (72/25.4)); // Will only use mm
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 // mPDF 5.3.76
54 if(function_exists("date_default_timezone_set")) {
55 if (ini_get("date.timezone")=="") { date_default_timezone_set("Europe/London"); }
56 }
57 if (!function_exists("mb_strlen")) { die("Error - mPDF requires mb_string functions. Ensure that PHP is compiled with php_mbstring.dll enabled."); }
58
59 if (!defined('PHP_VERSION_ID')) {
60 $version = explode('.', PHP_VERSION);
61 define('PHP_VERSION_ID', ($version[0] * 10000 + $version[1] * 100 + $version[2]));
62 }
63 // mPDF 5.3.79 Machine dependent number of bytes used to pack "double" into binary (used in cacheTables)
64 $test = pack("d", 134455.474557333333666);
65 define("_DSIZE", strlen($test));
66
67 class mPDF
68 {
69
70 ///////////////////////////////
71 // EXTERNAL (PUBLIC) VARIABLES
72 // Define these in config.php
73 ///////////////////////////////
74 var $cacheTables; // mPDF 5.3.79
75 var $bookmarkStyles; // mPDF 5.3.39
76 var $useActiveForms;
77
78 var $repackageTTF;
79 var $allowCJKorphans;
80 var $allowCJKoverflow;
81 var $CJKleading;
82 var $CJKfollowing;
83 var $CJKoverflow;
84
85 var $useKerning;
86 var $restrictColorSpace;
87 var $bleedMargin;
88 var $crossMarkMargin;
89 var $cropMarkMargin;
90 var $cropMarkLength;
91 var $nonPrintMargin;
92
93 var $PDFX;
94 var $PDFXauto;
95
96 var $PDFA;
97 var $PDFAauto;
98 var $ICCProfile;
99
100 var $printers_info;
101 var $iterationCounter;
102 var $smCapsScale;
103 var $smCapsStretch;
104
105 var $backupSubsFont;
106 var $backupSIPFont;
107 var $debugfonts;
108 var $useAdobeCJK;
109 var $percentSubset;
110 var $maxTTFFilesize;
111 var $BMPonly;
112
113 var $tableMinSizePriority;
114
115 var $dpi;
116 var $watermarkImgAlphaBlend;
117 var $watermarkImgBehind;
118 var $justifyB4br;
119 var $packTableData;
120 var $pgsIns;
121 var $simpleTables;
122 var $enableImports;
123
124 var $debug;
125 var $showStats;
126 var $setAutoTopMargin;
127 var $setAutoBottomMargin;
128 var $autoMarginPadding;
129 var $collapseBlockMargins;
130 var $falseBoldWeight;
131 var $normalLineheight;
132 var $progressBar;
133 var $incrementFPR1;
134 var $incrementFPR2;
135 var $incrementFPR3;
136 var $incrementFPR4;
137
138 var $hyphenate;
139 var $hyphenateTables;
140 var $SHYlang;
141 var $SHYleftmin;
142 var $SHYrightmin;
143 var $SHYcharmin;
144 var $SHYcharmax;
145 var $SHYlanguages;
146 // PageNumber Conditional Text
147 var $pagenumPrefix;
148 var $pagenumSuffix;
149 var $nbpgPrefix;
150 var $nbpgSuffix;
151 var $showImageErrors;
152 var $allow_output_buffering;
153 var $autoPadding;
154 var $useGraphs;
155 var $autoFontGroupSize;
156 var $tabSpaces;
157 var $useLang;
158 var $restoreBlockPagebreaks;
159 var $watermarkTextAlpha;
160 var $watermarkImageAlpha;
161 var $watermark_size;
162 var $watermark_pos;
163 var $annotSize;
164 var $annotMargin;
165 var $annotOpacity;
166 var $title2annots;
167 var $keepColumns;
168 var $keep_table_proportions;
169 var $ignore_table_widths;
170 var $ignore_table_percents;
171 var $list_align_style;
172 var $list_number_suffix;
173 var $useSubstitutions;
174 var $CSSselectMedia;
175
176 var $forcePortraitHeaders;
177 var $forcePortraitMargins;
178 var $displayDefaultOrientation;
179 var $ignore_invalid_utf8;
180 var $allowedCSStags;
181 var $onlyCoreFonts;
182 var $allow_charset_conversion;
183
184 var $jSWord;
185 var $jSmaxChar;
186 var $jSmaxCharLast;
187 var $jSmaxWordLast;
188
189 var $orphansAllowed;
190 var $max_colH_correction;
191
192
193 var $table_error_report;
194 var $table_error_report_param;
195 var $biDirectional;
196 var $text_input_as_HTML;
197 var $anchor2Bookmark;
198 var $list_indent_first_level;
199 var $shrink_tables_to_fit;
200
201 var $allow_html_optional_endtags;
202
203 var $img_dpi;
204
205 var $defaultheaderfontsize;
206 var $defaultheaderfontstyle;
207 var $defaultheaderline;
208 var $defaultfooterfontsize;
209 var $defaultfooterfontstyle;
210 var $defaultfooterline;
211 var $header_line_spacing;
212 var $footer_line_spacing;
213
214 var $pregUHCchars;
215 var $pregSJISchars;
216 var $pregCJKchars;
217 var $pregASCIIchars1;
218 var $pregASCIIchars2;
219 var $pregASCIIchars3;
220 var $pregVIETchars;
221 var $pregVIETPluschars;
222
223 var $pregRTLchars;
224 var $pregHEBchars;
225 var $pregARABICchars;
226 var $pregNonARABICchars;
227 // INDIC
228 var $pregHIchars;
229 var $pregBNchars;
230 var $pregPAchars;
231 var $pregGUchars;
232 var $pregORchars;
233 var $pregTAchars;
234 var $pregTEchars;
235 var $pregKNchars;
236 var $pregMLchars;
237 var $pregSHchars;
238 var $pregINDextra;
239
240 var $mirrorMargins;
241 var $default_lineheight_correction;
242 var $watermarkText;
243 var $watermarkImage;
244 var $showWatermarkText;
245 var $showWatermarkImage;
246
247 var $fontsizes;
248
249 // Aliases for backward compatability
250 var $UnvalidatedText; // alias = $watermarkText
251 var $TopicIsUnvalidated; // alias = $showWatermarkText
252 var $useOddEven; // alias = $mirrorMargins
253 var $useSubstitutionsMB; // alias = $useSubstitutions
254
255
256
257 //////////////////////
258 // CLASS OBJECTS
259 //////////////////////
260 // mPDF 5.3.89
261 var $grad;
262 var $bmp;
263 var $wmf;
264 var $tocontents;
265 var $form;
266 var $directw;
267
268 //////////////////////
269 // INTERNAL VARIABLES
270 //////////////////////
271
272 var $textshadow; // mPDF 5.3.A2
273
274 var $colsums; // mPDF 5.3.92
275 // mPDF 5.3.61
276 var $spanborder;
277 var $spanborddet;
278
279 var $visibility; // mPDF 5.3.41
280
281 var $useRC128encryption;
282 var $uniqid;
283
284 var $kerning;
285 var $fixedlSpacing;
286 var $minwSpacing;
287 var $lSpacingCSS;
288 var $wSpacingCSS;
289
290 var $listDir;
291 var $spotColorIDs;
292 var $SVGcolors;
293 var $spotColors;
294 var $defTextColor;
295 var $defDrawColor;
296 var $defFillColor;
297
298 var $tableBackgrounds;
299 var $inlineDisplayOff;
300 var $kt_y00;
301 var $kt_p00;
302 var $upperCase;
303 var $checkSIP;
304 var $checkSMP;
305 var $checkCJK;
306 var $tableCJK;
307
308 var $watermarkImgAlpha;
309 var $PDFAXwarnings;
310 var $MetadataRoot;
311 var $OutputIntentRoot;
312 var $InfoRoot;
313 var $current_filename;
314 var $parsers;
315 var $current_parser;
316 var $_obj_stack;
317 var $_don_obj_stack;
318 var $_current_obj_id;
319 var $tpls;
320 var $tpl;
321 var $tplprefix;
322 var $_res;
323
324 var $pdf_version;
325 var $noImageFile;
326 var $lastblockbottommargin;
327 var $baselineC;
328 var $subPos;
329 var $subArrMB;
330 var $ReqFontStyle;
331 var $tableClipPath ;
332 var $forceExactLineheight;
333 var $listOcc;
334
335 var $fullImageHeight;
336 var $inFixedPosBlock; // Internal flag for position:fixed block
337 var $fixedPosBlock; // Buffer string for position:fixed block
338 var $fixedPosBlockDepth;
339 var $fixedPosBlockBBox;
340 var $fixedPosBlockSave;
341 var $maxPosL;
342 var $maxPosR;
343
344 var $loaded;
345
346 var $extraFontSubsets;
347 var $docTemplateStart; // Internal flag for page (page no. -1) that docTemplate starts on
348 var $time0;
349
350 // Classes
351 var $indic;
352 var $barcode;
353
354 var $SHYpatterns;
355 var $loadedSHYpatterns;
356 var $loadedSHYdictionary;
357 var $SHYdictionary;
358 var $SHYdictionaryWords;
359
360 var $spanbgcolorarray;
361 var $default_font;
362 var $list_lineheight;
363 var $headerbuffer;
364 var $lastblocklevelchange;
365 var $nestedtablejustfinished;
366 var $linebreakjustfinished;
367 var $cell_border_dominance_L;
368 var $cell_border_dominance_R;
369 var $cell_border_dominance_T;
370 var $cell_border_dominance_B;
371 var $tbCSSlvl;
372 var $listCSSlvl;
373 var $table_keep_together;
374 var $plainCell_properties;
375 var $inherit_lineheight;
376 var $listitemtype;
377 var $shrin_k1;
378 var $outerfilled;
379
380 var $blockContext;
381 var $floatDivs;
382
383 var $tablecascadeCSS;
384 var $listcascadeCSS;
385
386 var $patterns;
387 var $pageBackgrounds;
388
389 var $bodyBackgroundGradient;
390 var $bodyBackgroundImage;
391 var $bodyBackgroundColor;
392
393 var $writingHTMLheader; // internal flag - used both for writing HTMLHeaders/Footers and FixedPos block
394 var $writingHTMLfooter;
395 var $autoFontGroups;
396 var $angle;
397
398 var $gradients;
399
400 var $kwt_Reference;
401 var $kwt_BMoutlines;
402 var $kwt_toc;
403
404 var $tbrot_Reference;
405 var $tbrot_BMoutlines;
406 var $tbrot_toc;
407
408 var $col_Reference;
409 var $col_BMoutlines;
410 var $col_toc;
411
412 var $currentGraphId;
413 var $graphs;
414
415 var $floatbuffer;
416 var $floatmargins;
417
418 var $bullet;
419 var $bulletarray;
420
421 var $rtlAsArabicFarsi; // DEPRACATED
422
423 var $currentLang;
424 var $default_lang;
425 var $default_available_fonts;
426 var $pageTemplate;
427 var $docTemplate;
428 var $docTemplateContinue;
429
430 var $arabGlyphs;
431 var $arabHex;
432 var $persianGlyphs;
433 var $persianHex;
434 var $arabVowels;
435 var $arabPrevLink;
436 var $arabNextLink;
437
438
439 var $formobjects; // array of Form Objects for WMF
440 var $InlineProperties;
441 var $InlineAnnots;
442 var $ktAnnots;
443 var $tbrot_Annots;
444 var $kwt_Annots;
445 var $columnAnnots;
446 var $columnForms;
447
448 var $PageAnnots;
449
450 var $pageDim; // Keep track of page wxh for orientation changes - set in _beginpage, used in _putannots
451
452 var $breakpoints;
453
454 var $tableLevel;
455 var $tbctr;
456 var $innermostTableLevel;
457 var $saveTableCounter;
458 var $cellBorderBuffer;
459
460 var $saveHTMLFooter_height;
461 var $saveHTMLFooterE_height;
462
463 var $firstPageBoxHeader;
464 var $firstPageBoxHeaderEven;
465 var $firstPageBoxFooter;
466 var $firstPageBoxFooterEven;
467
468 var $page_box;
469 var $show_marks; // crop or cross marks
470
471 var $basepathIsLocal;
472
473 var $use_kwt;
474 var $kwt;
475 var $kwt_height;
476 var $kwt_y0;
477 var $kwt_x0;
478 var $kwt_buffer;
479 var $kwt_Links;
480 var $kwt_moved;
481 var $kwt_saved;
482
483 var $PageNumSubstitutions;
484
485 var $table_borders_separate;
486 var $base_table_properties;
487 var $borderstyles;
488
489 var $listjustfinished;
490 var $blockjustfinished;
491
492 var $orig_bMargin;
493 var $orig_tMargin;
494 var $orig_lMargin;
495 var $orig_rMargin;
496 var $orig_hMargin;
497 var $orig_fMargin;
498
499 var $pageheaders;
500 var $pagefooters;
501
502 var $pageHTMLheaders;
503 var $pageHTMLfooters;
504
505 var $saveHTMLHeader;
506 var $saveHTMLFooter;
507
508 var $HTMLheaderPageLinks;
509 var $HTMLheaderPageAnnots;
510 var $HTMLheaderPageForms;
511
512 // See config_fonts.php for these next 5 values
513 var $available_unifonts;
514 var $sans_fonts;
515 var $serif_fonts;
516 var $mono_fonts;
517 var $defaultSubsFont;
518
519 // List of ALL available CJK fonts (incl. styles) (Adobe add-ons) hw removed
520 var $available_CJK_fonts;
521
522 var $cascadeCSS;
523
524 var $HTMLHeader;
525 var $HTMLFooter;
526 var $HTMLHeaderE;
527 var $HTMLFooterE;
528 var $bufferoutput;
529
530 var $showdefaultpagenos; // DEPRACATED -left for backward compatability
531
532
533 // CJK fonts
534 var $Big5_widths;
535 var $GB_widths;
536 var $SJIS_widths;
537 var $UHC_widths;
538
539 // SetProtection
540 var $encrypted; //whether document is protected
541 var $Uvalue; //U entry in pdf document
542 var $Ovalue; //O entry in pdf document
543 var $Pvalue; //P entry in pdf document
544 var $enc_obj_id; //encryption object id
545 var $last_rc4_key; //last RC4 key encrypted (cached for optimisation)
546 var $last_rc4_key_c; //last RC4 computed key
547 var $encryption_key;
548 var $padding; //used for encryption
549
550
551 // Bookmark
552 var $BMoutlines;
553 var $OutlineRoot;
554 // INDEX
555 var $ColActive;
556 var $Reference;
557 var $CurrCol;
558 var $NbCol;
559 var $y0; //Top ordinate of columns
560 var $ColL;
561 var $ColWidth;
562 var $ColGap;
563 // COLUMNS
564 var $ColR;
565 var $ChangeColumn;
566 var $columnbuffer;
567 var $ColDetails;
568 var $columnLinks;
569 var $colvAlign;
570 // Substitutions
571 var $substitute; // Array of substitution strings e.g. <ttz>112</ttz>
572 var $entsearch; // Array of HTML entities (>ASCII 127) to substitute
573 var $entsubstitute; // Array of substitution decimal unicode for the Hi entities
574
575
576 // Default values if no style sheet offered (cf. http://www.w3.org/TR/CSS21/sample.html)
577 var $defaultCSS;
578
579 var $linemaxfontsize;
580 var $lineheight_correction;
581 var $lastoptionaltag; // Save current block item which HTML specifies optionsl endtag
582 var $pageoutput;
583 var $charset_in;
584 var $blk;
585 var $blklvl;
586 var $ColumnAdjust;
587 var $ws; // Word spacing
588 var $HREF;
589 var $pgwidth;
590 var $fontlist;
591 var $oldx;
592 var $oldy;
593 var $B;
594 var $U; //underlining flag
595 var $S; // SmallCaps flag
596 var $I;
597
598 var $tdbegin;
599 var $table;
600 var $cell;
601 var $col;
602 var $row;
603
604 var $divbegin;
605 var $divalign;
606 var $divwidth;
607 var $divheight;
608 var $divrevert;
609 var $spanbgcolor;
610
611 var $spanlvl;
612 var $listlvl;
613 var $listnum;
614 var $listtype;
615 var $listoccur;
616 var $listlist;
617 var $listitem;
618
619 var $pjustfinished;
620 var $ignorefollowingspaces;
621 var $SUP;
622 var $SUB;
623 var $SMALL;
624 var $BIG;
625 var $toupper;
626 var $tolower;
627 var $capitalize;
628 var $dash_on;
629 var $dotted_on;
630 var $strike;
631
632 var $CSS;
633 var $textbuffer;
634 var $currentfontstyle;
635 var $currentfontfamily;
636 var $currentfontsize;
637 var $colorarray;
638 var $bgcolorarray;
639 var $internallink;
640 var $enabledtags;
641
642 var $lineheight;
643 var $basepath;
644 var $outlineparam;
645 var $outline_on;
646
647 var $specialcontent;
648 var $selectoption;
649 var $objectbuffer;
650
651 // Table Rotation
652 var $table_rotate;
653 var $tbrot_maxw;
654 var $tbrot_maxh;
655 var $tablebuffer;
656 var $tbrot_align;
657 var $tbrot_Links;
658
659 var $divbuffer; // Buffer used when keeping DIV on one page
660 var $keep_block_together; // Keep a Block from page-break-inside: avoid
661 var $ktLinks; // Keep-together Block links array
662 var $ktBlock; // Keep-together Block array
663 var $ktForms;
664 var $ktReference;
665 var $ktBMoutlines;
666 var $_kttoc;
667
668 var $tbrot_y0;
669 var $tbrot_x0;
670 var $tbrot_w;
671 var $tbrot_h;
672
673 var $mb_enc;
674 var $directionality;
675
676 var $extgstates; // Used for alpha channel - Transparency (Watermark)
677 var $mgl;
678 var $mgt;
679 var $mgr;
680 var $mgb;
681
682 var $tts;
683 var $ttz;
684 var $tta;
685
686 var $headerDetails;
687 var $footerDetails;
688
689 // Best to alter the below variables using default stylesheet above
690 var $page_break_after_avoid;
691 var $margin_bottom_collapse;
692 var $list_indent;
693 var $list_align;
694 var $list_margin_bottom;
695 var $default_font_size; // in pts
696 var $original_default_font_size; // used to save default sizes when using table default
697 var $original_default_font;
698 var $watermark_font;
699 var $defaultAlign;
700
701 // TABLE
702 var $defaultTableAlign;
703 var $tablethead;
704 var $thead_font_weight;
705 var $thead_font_style;
706 var $thead_font_smCaps;
707 var $thead_valign_default;
708 var $thead_textalign_default;
709 var $tabletfoot;
710 var $tfoot_font_weight;
711 var $tfoot_font_style;
712 var $tfoot_font_smCaps;
713 var $tfoot_valign_default;
714 var $tfoot_textalign_default;
715
716 var $trow_text_rotate;
717
718 var $cellPaddingL;
719 var $cellPaddingR;
720 var $cellPaddingT;
721 var $cellPaddingB;
722 var $table_lineheight;
723 var $table_border_attr_set;
724 var $table_border_css_set;
725
726 var $shrin_k; // factor with which to shrink tables - used internally - do not change
727 var $shrink_this_table_to_fit; // 0 or false to disable; value (if set) gives maximum factor to reduce fontsize
728 var $MarginCorrection; // corrects for OddEven Margins
729 var $margin_footer;
730 var $margin_header;
731
732 var $tabletheadjustfinished;
733 var $usingCoreFont;
734 var $charspacing;
735
736 //Private properties FROM FPDF
737 var $DisplayPreferences;
738 var $outlines;
739 var $flowingBlockAttr;
740 var $page; //current page number
741 var $n; //current object number
742 var $offsets; //array of object offsets
743 var $buffer; //buffer holding in-memory PDF
744 var $pages; //array containing pages
745 var $state; //current document state
746 var $compress; //compression flag
747 var $DefOrientation; //default orientation
748 var $CurOrientation; //current orientation
749 var $OrientationChanges; //array indicating orientation changes
750 var $k; //scale factor (number of points in user unit)
751 var $fwPt;
752 var $fhPt; //dimensions of page format in points
753 var $fw;
754 var $fh; //dimensions of page format in user unit
755 var $wPt;
756 var $hPt; //current dimensions of page in points
757 var $w;
758 var $h; //current dimensions of page in user unit
759 var $lMargin; //left margin
760 var $tMargin; //top margin
761 var $rMargin; //right margin
762 var $bMargin; //page break margin
763 var $cMarginL; //cell margin Left
764 var $cMarginR; //cell margin Right
765 var $cMarginT; //cell margin Left
766 var $cMarginB; //cell margin Right
767 var $DeflMargin; //Default left margin
768 var $DefrMargin; //Default right margin
769 var $x;
770 var $y; //current position in user unit for cell positioning
771 var $lasth; //height of last cell printed
772 var $LineWidth; //line width in user unit
773 var $CoreFonts; //array of standard font names
774 var $fonts; //array of used fonts
775 var $FontFiles; //array of font files
776 var $images; //array of used images
777 var $PageLinks; //array of links in pages
778 var $links; //array of internal links
779 var $FontFamily; //current font family
780 var $FontStyle; //current font style
781 var $CurrentFont; //current font info
782 var $FontSizePt; //current font size in points
783 var $FontSize; //current font size in user unit
784 var $DrawColor; //commands for drawing color
785 var $FillColor; //commands for filling color
786 var $TextColor; //commands for text color
787 var $ColorFlag; //indicates whether fill and text colors are different
788 var $autoPageBreak; //automatic page breaking
789 var $PageBreakTrigger; //threshold used to trigger page breaks
790 var $InFooter; //flag set when processing footer
791 var $InHTMLFooter;
792
793 var $processingFooter; //flag set when processing footer - added for columns
794 var $processingHeader; //flag set when processing header - added for columns
795 var $ZoomMode; //zoom display mode
796 var $LayoutMode; //layout display mode
797 var $title; //title
798 var $subject; //subject
799 var $author; //author
800 var $keywords; //keywords
801 var $creator; //creator
802
803 var $aliasNbPg; //alias for total number of pages
804 var $aliasNbPgGp; //alias for total number of pages in page group
805 var $aliasNbPgHex;
806 var $aliasNbPgGpHex;
807
808 var $ispre;
809
810 var $outerblocktags;
811 var $innerblocktags;
812
813
814 // **********************************
815 // **********************************
816 // **********************************
817 // **********************************
818 // **********************************
819 // **********************************
820 // **********************************
821 // **********************************
822 // **********************************
823
824 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') {
825
826 // mPDF 5.3.89 5.3.99
827 /*-- BACKGROUNDS --*/
828 if (!class_exists('grad', false)) { include(_MPDF_PATH.'classes/grad.php'); }
829 if (empty($this->grad)) { $this->grad = new grad($this); }
830 /*-- END BACKGROUNDS --*/
831 /*-- FORMS --*/
832 if (!class_exists('form', false)) { include(_MPDF_PATH.'classes/form.php'); }
833 if (empty($this->form)) { $this->form = new form($this); }
834 /*-- END FORMS --*/
835
836 $this->time0 = microtime(true);
837 //Some checks
838 $this->_dochecks();
839
840 // Set up Aliases for backwards compatability
841 $this->UnvalidatedText =& $this->watermarkText;
842 $this->TopicIsUnvalidated =& $this->showWatermarkText;
843 $this->AliasNbPg =& $this->aliasNbPg;
844 $this->AliasNbPgGp =& $this->aliasNbPgGp;
845 $this->BiDirectional =& $this->biDirectional;
846 $this->Anchor2Bookmark =& $this->anchor2Bookmark;
847 $this->KeepColumns =& $this->keepColumns;
848 $this->useOddEven =& $this->mirrorMargins;
849 $this->useSubstitutionsMB =& $this->useSubstitutions;
850
851 $this->visibility='visible'; // mPDF 5.3.41
852
853 //Initialization of properties
854 $this->spotColors=array();
855 $this->spotColorIDs = array();
856 $this->tableBackgrounds = array();
857
858 $this->kt_y00 = '';
859 $this->kt_p00 = '';
860 $this->iterationCounter = false;
861 $this->BMPonly = array();
862 $this->page=0;
863 $this->n=2;
864 $this->buffer='';
865 $this->objectbuffer = array();
866 $this->pages=array();
867 $this->OrientationChanges=array();
868 $this->state=0;
869 $this->fonts=array();
870 $this->FontFiles=array();
871 $this->images=array();
872 $this->links=array();
873 $this->InFooter=false;
874 $this->processingFooter=false;
875 $this->processingHeader=false;
876 $this->lasth=0;
877 $this->FontFamily='';
878 $this->FontStyle='';
879 $this->FontSizePt=9;
880 $this->U=false;
881 // Small Caps
882 $this->upperCase = array();
883 $this->S = false;
884 $this->smCapsScale = 1;
885 $this->smCapsStretch = 100;
886
887 $this->defTextColor = $this->TextColor = $this->SetTColor($this->ConvertColor(0),true);
888 $this->defDrawColor = $this->DrawColor = $this->SetDColor($this->ConvertColor(0),true);
889 $this->defFillColor = $this->FillColor = $this->SetFColor($this->ConvertColor(255),true);
890
891 //SVG color names array
892 //http://www.w3schools.com/css/css_colornames.asp
893 $this->SVGcolors = array('antiquewhite'=>'#FAEBD7','aqua'=>'#00FFFF','aquamarine'=>'#7FFFD4','beige'=>'#F5F5DC','black'=>'#000000',
894 'blue'=>'#0000FF','brown'=>'#A52A2A','cadetblue'=>'#5F9EA0','chocolate'=>'#D2691E','cornflowerblue'=>'#6495ED','crimson'=>'#DC143C',
895 'darkblue'=>'#00008B','darkgoldenrod'=>'#B8860B','darkgreen'=>'#006400','darkmagenta'=>'#8B008B','darkorange'=>'#FF8C00',
896 'darkred'=>'#8B0000','darkseagreen'=>'#8FBC8F','darkslategray'=>'#2F4F4F','darkviolet'=>'#9400D3','deepskyblue'=>'#00BFFF',
897 'dodgerblue'=>'#1E90FF','firebrick'=>'#B22222','forestgreen'=>'#228B22','fuchsia'=>'#FF00FF','gainsboro'=>'#DCDCDC','gold'=>'#FFD700',
898 'gray'=>'#808080','green'=>'#008000','greenyellow'=>'#ADFF2F','hotpink'=>'#FF69B4','indigo'=>'#4B0082','khaki'=>'#F0E68C',
899 'lavenderblush'=>'#FFF0F5','lemonchiffon'=>'#FFFACD','lightcoral'=>'#F08080','lightgoldenrodyellow'=>'#FAFAD2','lightgreen'=>'#90EE90',
900 'lightsalmon'=>'#FFA07A','lightskyblue'=>'#87CEFA','lightslategray'=>'#778899','lightyellow'=>'#FFFFE0','lime'=>'#00FF00','limegreen'=>'#32CD32',
901 'magenta'=>'#FF00FF','maroon'=>'#800000','mediumaquamarine'=>'#66CDAA','mediumorchid'=>'#BA55D3','mediumseagreen'=>'#3CB371',
902 'mediumspringgreen'=>'#00FA9A','mediumvioletred'=>'#C71585','midnightblue'=>'#191970','mintcream'=>'#F5FFFA','moccasin'=>'#FFE4B5','navy'=>'#000080',
903 'olive'=>'#808000','orange'=>'#FFA500','orchid'=>'#DA70D6','palegreen'=>'#98FB98',
904 'palevioletred'=>'#D87093','peachpuff'=>'#FFDAB9','pink'=>'#FFC0CB','powderblue'=>'#B0E0E6','purple'=>'#800080',
905 'red'=>'#FF0000','royalblue'=>'#4169E1','salmon'=>'#FA8072','seagreen'=>'#2E8B57','sienna'=>'#A0522D','silver'=>'#C0C0C0','skyblue'=>'#87CEEB',
906 'slategray'=>'#708090','springgreen'=>'#00FF7F','steelblue'=>'#4682B4','tan'=>'#D2B48C','teal'=>'#008080','thistle'=>'#D8BFD8','turquoise'=>'#40E0D0',
907 'violetred'=>'#D02090','white'=>'#FFFFFF','yellow'=>'#FFFF00',
908 'aliceblue'=>'#f0f8ff', 'azure'=>'#f0ffff', 'bisque'=>'#ffe4c4', 'blanchedalmond'=>'#ffebcd', 'blueviolet'=>'#8a2be2', 'burlywood'=>'#deb887',
909 'chartreuse'=>'#7fff00', 'coral'=>'#ff7f50', 'cornsilk'=>'#fff8dc', 'cyan'=>'#00ffff', 'darkcyan'=>'#008b8b', 'darkgray'=>'#a9a9a9',
910 'darkgrey'=>'#a9a9a9', 'darkkhaki'=>'#bdb76b', 'darkolivegreen'=>'#556b2f', 'darkorchid'=>'#9932cc', 'darksalmon'=>'#e9967a',
911 'darkslateblue'=>'#483d8b', 'darkslategrey'=>'#2f4f4f', 'darkturquoise'=>'#00ced1', 'deeppink'=>'#ff1493', 'dimgray'=>'#696969',
912 'dimgrey'=>'#696969', 'floralwhite'=>'#fffaf0', 'ghostwhite'=>'#f8f8ff', 'goldenrod'=>'#daa520', 'grey'=>'#808080', 'honeydew'=>'#f0fff0',
913 'indianred'=>'#cd5c5c', 'ivory'=>'#fffff0', 'lavender'=>'#e6e6fa', 'lawngreen'=>'#7cfc00', 'lightblue'=>'#add8e6', 'lightcyan'=>'#e0ffff',
914 'lightgray'=>'#d3d3d3', 'lightgrey'=>'#d3d3d3', 'lightpink'=>'#ffb6c1', 'lightseagreen'=>'#20b2aa', 'lightslategrey'=>'#778899',
915 'lightsteelblue'=>'#b0c4de', 'linen'=>'#faf0e6', 'mediumblue'=>'#0000cd', 'mediumpurple'=>'#9370db', 'mediumslateblue'=>'#7b68ee',
916 'mediumturquoise'=>'#48d1cc', 'mistyrose'=>'#ffe4e1', 'navajowhite'=>'#ffdead', 'oldlace'=>'#fdf5e6', 'olivedrab'=>'#6b8e23', 'orangered'=>'#ff4500',
917 'palegoldenrod'=>'#eee8aa', 'paleturquoise'=>'#afeeee', 'papayawhip'=>'#ffefd5', 'peru'=>'#cd853f', 'plum'=>'#dda0dd', 'rosybrown'=>'#bc8f8f',
918 'saddlebrown'=>'#8b4513', 'sandybrown'=>'#f4a460', 'seashell'=>'#fff5ee', 'slateblue'=>'#6a5acd', 'slategrey'=>'#708090', 'snow'=>'#fffafa',
919 'tomato'=>'#ff6347', 'violet'=>'#ee82ee', 'wheat'=>'#f5deb3', 'whitesmoke'=>'#f5f5f5', 'yellowgreen'=>'#9acd32');
920
921 $this->ColorFlag=false;
922 $this->extgstates = array();
923
924 $this->mb_enc='windows-1252';
925 $this->directionality='ltr';
926 $this->defaultAlign = 'L';
927 $this->defaultTableAlign = 'L';
928
929 $this->fixedPosBlockSave = array();
930 $this->extraFontSubsets = 0;
931
932 $this->SHYpatterns = array();
933 $this->loadedSHYdictionary = false;
934 $this->SHYdictionary = array();
935 $this->SHYdictionaryWords = array();
936 $this->blockContext = 1;
937 $this->floatDivs = array();
938 $this->DisplayPreferences='';
939
940 $this->tablecascadeCSS = array();
941 $this->listcascadeCSS = array();
942
943 $this->patterns = array(); // Tiling patterns used for backgrounds
944 $this->pageBackgrounds = array();
945 $this->writingHTMLheader = false; // internal flag - used both for writing HTMLHeaders/Footers and FixedPos block
946 $this->writingHTMLfooter = false; // internal flag - used both for writing HTMLHeaders/Footers and FixedPos block
947 $this->gradients = array();
948
949 $this->kwt_Reference = array();
950 $this->kwt_BMoutlines = array();
951 $this->kwt_toc = array();
952
953 $this->tbrot_Reference = array();
954 $this->tbrot_BMoutlines = array();
955 $this->tbrot_toc = array();
956
957 $this->col_Reference = array();
958 $this->col_BMoutlines = array();
959 $this->col_toc = array();
960 $this->graphs = array();
961
962 $this->pgsIns = array();
963 $this->PDFAXwarnings = array();
964 $this->inlineDisplayOff = false;
965 $this->kerning = false;
966 $this->lSpacingCSS = '';
967 $this->wSpacingCSS = '';
968 $this->fixedlSpacing = false;
969 $this->minwSpacing = 0;
970
971
972 $this->baselineC = 0.35; // Baseline for text
973 $this->noImageFile = str_replace("\\","/",dirname(__FILE__)) . '/includes/no_image.jpg';
974 $this->subPos = 0;
975 $this->forceExactLineheight = false;
976 $this->listOcc = 0;
977 $this->normalLineheight = 1.3;
978 // These are intended as configuration variables, and should be set in config.php - which will override these values;
979 // set here as failsafe as will cause an error if not defined
980 $this->incrementFPR1 = 10;
981 $this->incrementFPR2 = 10;
982 $this->incrementFPR3 = 10;
983 $this->incrementFPR4 = 10;
984
985 $this->fullImageHeight = false;
986 $this->floatbuffer = array();
987 $this->floatmargins = array();
988 $this->autoFontGroups = 0;
989 $this->formobjects=array(); // array of Form Objects for WMF
990 $this->InlineProperties=array();
991 $this->InlineAnnots=array();
992 $this->ktAnnots=array();
993 $this->tbrot_Annots=array();
994 $this->kwt_Annots=array();
995 $this->columnAnnots=array();
996 $this->pageDim=array();
997 $this->breakpoints = array(); // used in columnbuffer
998 $this->tableLevel=0;
999 $this->tbctr=array(); // counter for nested tables at each level
1000 $this->page_box = array();
1001 $this->show_marks = ''; // crop or cross marks
1002 $this->kwt = false;
1003 $this->kwt_height = 0;
1004 $this->kwt_y0 = 0;
1005 $this->kwt_x0 = 0;
1006 $this->kwt_buffer = array();
1007 $this->kwt_Links = array();
1008 $this->kwt_moved = false;
1009 $this->kwt_saved = false;
1010 $this->PageNumSubstitutions = array();
1011 $this->base_table_properties=array();
1012 $this->borderstyles = array('inset','groove','outset','ridge','dotted','dashed','solid','double');
1013 $this->tbrot_align = 'C';
1014 $this->pageheaders=array();
1015 $this->pagefooters=array();
1016
1017 $this->pageHTMLheaders=array();
1018 $this->pageHTMLfooters=array();
1019 $this->HTMLheaderPageLinks = array();
1020 $this->HTMLheaderPageAnnots = array();
1021
1022 $this->ktForms = array();
1023 $this->HTMLheaderPageForms = array();
1024 $this->columnForms = array();
1025 $this->tbrotForms = array();
1026 $this->useRC128encryption = false;
1027 $this->uniqid = '';
1028
1029 $this->cascadeCSS = array();
1030 $this->bufferoutput = false;
1031 $this->encrypted=false; //whether document is protected
1032 $this->BMoutlines=array();
1033 $this->ColActive=0; //Flag indicating that columns are on (the index is being processed)
1034 $this->Reference=array(); //Array containing the references
1035 $this->CurrCol=0; //Current column number
1036 $this->ColL = array(0); // Array of Left pos of columns - absolute - needs Margin correction for Odd-Even
1037 $this->ColR = array(0); // Array of Right pos of columns - absolute pos - needs Margin correction for Odd-Even
1038 $this->ChangeColumn = 0;
1039 $this->columnbuffer = array();
1040 $this->ColDetails = array(); // Keeps track of some column details
1041 $this->columnLinks = array(); // Cross references PageLinks
1042 $this->substitute = array(); // Array of substitution strings e.g. <ttz>112</ttz>
1043 $this->entsearch = array(); // Array of HTML entities (>ASCII 127) to substitute
1044 $this->entsubstitute = array(); // Array of substitution decimal unicode for the Hi entities
1045 $this->lastoptionaltag = '';
1046 $this->charset_in = '';
1047 $this->blk = array();
1048 $this->blklvl = 0;
1049 $this->tts = false;
1050 $this->ttz = false;
1051 $this->tta = false;
1052 $this->ispre=false;
1053
1054 $this->checkSIP = false;
1055 $this->checkSMP = false;
1056 $this->checkCJK = false;
1057 $this->tableCJK = false;
1058
1059 $this->headerDetails=array();
1060 $this->footerDetails=array();
1061 $this->page_break_after_avoid = false;
1062 $this->margin_bottom_collapse = false;
1063 $this->tablethead = 0;
1064 $this->tabletfoot = 0;
1065 $this->table_border_attr_set = 0;
1066 $this->table_border_css_set = 0;
1067 $this->shrin_k = 1.0;
1068 $this->shrink_this_table_to_fit = 0;
1069 $this->MarginCorrection = 0;
1070
1071 $this->tabletheadjustfinished = false;
1072 $this->usingCoreFont = false;
1073 $this->charspacing=0;
1074
1075 $this->outlines=array();
1076 $this->autoPageBreak = true;
1077
1078 require(_MPDF_PATH.'config.php'); // config data
1079
1080 $this->_setPageSize($format, $orientation);
1081 $this->DefOrientation=$orientation;
1082
1083 $this->margin_header=$mgh;
1084 $this->margin_footer=$mgf;
1085
1086 $bmargin=$mgb;
1087
1088 $this->DeflMargin = $mgl;
1089 $this->DefrMargin = $mgr;
1090
1091 $this->orig_tMargin = $mgt;
1092 $this->orig_bMargin = $bmargin;
1093 $this->orig_lMargin = $this->DeflMargin;
1094 $this->orig_rMargin = $this->DefrMargin;
1095 $this->orig_hMargin = $this->margin_header;
1096 $this->orig_fMargin = $this->margin_footer;
1097
1098 if ($this->setAutoTopMargin=='pad') { $mgt += $this->margin_header; }
1099 if ($this->setAutoBottomMargin=='pad') { $mgb += $this->margin_footer; }
1100 $this->SetMargins($this->DeflMargin,$this->DefrMargin,$mgt); // sets l r t margin
1101 //Automatic page break
1102 $this->SetAutoPageBreak($this->autoPageBreak,$bmargin); // sets $this->bMargin & PageBreakTrigger
1103
1104 $this->pgwidth = $this->w - $this->lMargin - $this->rMargin;
1105
1106 //Interior cell margin (1 mm) ? not used
1107 $this->cMarginL = 1;
1108 $this->cMarginR = 1;
1109 //Line width (0.2 mm)
1110 $this->LineWidth=.567/_MPDFK;
1111
1112 //To make the function Footer() work - replaces {nb} with page number
1113 $this->AliasNbPages();
1114 $this->AliasNbPageGroups();
1115
1116 $this->aliasNbPgHex = '{nbHEXmarker}';
1117 $this->aliasNbPgGpHex = '{nbpgHEXmarker}';
1118
1119 //Enable all tags as default
1120 $this->DisableTags();
1121 //Full width display mode
1122 $this->SetDisplayMode(100); // fullwidth? 'fullpage'
1123 //Compression
1124 $this->SetCompression(true);
1125 //Set default display preferences
1126 $this->SetDisplayPreferences('');
1127
1128 // Font data
1129 require(_MPDF_PATH.'config_fonts.php');
1130 // Available fonts
1131 $this->available_unifonts = array();
1132 foreach ($this->fontdata AS $f => $fs) {
1133 if (isset($fs['R']) && $fs['R']) { $this->available_unifonts[] = $f; }
1134 if (isset($fs['B']) && $fs['B']) { $this->available_unifonts[] = $f.'B'; }
1135 if (isset($fs['I']) && $fs['I']) { $this->available_unifonts[] = $f.'I'; }
1136 if (isset($fs['BI']) && $fs['BI']) { $this->available_unifonts[] = $f.'BI'; }
1137 }
1138
1139 $this->default_available_fonts = $this->available_unifonts;
1140
1141 $optcore = false;
1142 $onlyCoreFonts = false;
1143 if (preg_match('/([\-+])aCJK/i',$mode, $m)) {
1144 preg_replace('/([\-+])aCJK/i','',$mode);
1145 if ($m[1]=='+') { $this->useAdobeCJK = true; }
1146 else { $this->useAdobeCJK = false; }
1147 }
1148
1149 if (strlen($mode)==1) {
1150 if ($mode=='s') { $this->percentSubset = 100; $mode = ''; }
1151 else if ($mode=='c') { $onlyCoreFonts = true; $mode = ''; }
1152 }
1153 else if (substr($mode,-2)=='-s') {
1154 $this->percentSubset = 100;
1155 $mode = substr($mode,0,strlen($mode)-2);
1156 }
1157 else if (substr($mode,-2)=='-c') {
1158 $onlyCoreFonts = true;
1159 $mode = substr($mode,0,strlen($mode)-2);
1160 }
1161 else if (substr($mode,-2)=='-x') {
1162 $optcore = true;
1163 $mode = substr($mode,0,strlen($mode)-2);
1164 }
1165
1166 // Autodetect if mode is a language_country string (en-GB or en_GB or en)
1167 if ((strlen($mode) == 5 && $mode != 'UTF-8') || strlen($mode) == 2) {
1168 list ($coreSuitable,$mpdf_pdf_unifonts) = GetLangOpts($mode, $this->useAdobeCJK);
1169 if ($coreSuitable && $optcore) { $onlyCoreFonts = true; }
1170 if ($mpdf_pdf_unifonts) {
1171 $this->RestrictUnicodeFonts($mpdf_pdf_unifonts);
1172 $this->default_available_fonts = $mpdf_pdf_unifonts;
1173 }
1174 $this->currentLang = $mode;
1175 $this->default_lang = $mode;
1176 }
1177
1178 $this->onlyCoreFonts = $onlyCoreFonts;
1179
1180 if ($this->onlyCoreFonts) {
1181 $this->setMBencoding('windows-1252'); // sets $this->mb_enc
1182 }
1183 else {
1184 $this->setMBencoding('UTF-8'); // sets $this->mb_enc
1185 }
1186 @mb_regex_encoding('UTF-8'); // mPDF 5.3.07 // required only for mb_ereg... and mb_split functions
1187
1188
1189 // Adobe CJK fonts
1190 $this->available_CJK_fonts = array('gb','big5','sjis','uhc','gbB','big5B','sjisB','uhcB','gbI','big5I','sjisI','uhcI',
1191 'gbBI','big5BI','sjisBI','uhcBI');
1192
1193
1194 //Standard fonts
1195 $this->CoreFonts=array('ccourier'=>'Courier','ccourierB'=>'Courier-Bold','ccourierI'=>'Courier-Oblique','ccourierBI'=>'Courier-BoldOblique',
1196 'chelvetica'=>'Helvetica','chelveticaB'=>'Helvetica-Bold','chelveticaI'=>'Helvetica-Oblique','chelveticaBI'=>'Helvetica-BoldOblique',
1197 'ctimes'=>'Times-Roman','ctimesB'=>'Times-Bold','ctimesI'=>'Times-Italic','ctimesBI'=>'Times-BoldItalic',
1198 'csymbol'=>'Symbol','czapfdingbats'=>'ZapfDingbats');
1199 $this->fontlist=array("ctimes","ccourier","chelvetica","csymbol","czapfdingbats");
1200
1201 // Substitutions
1202 $this->setHiEntitySubstitutions();
1203
1204 if ($this->onlyCoreFonts) {
1205 $this->useSubstitutions = true;
1206 $this->SetSubstitutions();
1207 }
1208 else { $this->useSubstitutions = false; }
1209
1210 /*-- HTML-CSS --*/
1211 if (file_exists(_MPDF_PATH.'mpdf.css')) {
1212 $css = file_get_contents(_MPDF_PATH.'mpdf.css');
1213 $css2 = $this->ReadDefaultCSS($css);
1214 $this->defaultCSS = $this->array_merge_recursive_unique($this->defaultCSS,$css2);
1215 }
1216 /*-- END HTML-CSS --*/
1217
1218 if ($default_font=='') {
1219 if ($this->onlyCoreFonts) {
1220 if (in_array(strtolower($this->defaultCSS['BODY']['FONT-FAMILY']),$this->mono_fonts)) { $default_font = 'ccourier'; }
1221 else if (in_array(strtolower($this->defaultCSS['BODY']['FONT-FAMILY']),$this->sans_fonts)) { $default_font = 'chelvetica'; }
1222 else { $default_font = 'ctimes'; }
1223 }
1224 else { $default_font = $this->defaultCSS['BODY']['FONT-FAMILY']; }
1225 }
1226 if (!$default_font_size) {
1227 $mmsize = $this->ConvertSize($this->defaultCSS['BODY']['FONT-SIZE']);
1228 $default_font_size = $mmsize*(_MPDFK);
1229 }
1230
1231 if ($default_font) { $this->SetDefaultFont($default_font); }
1232 if ($default_font_size) { $this->SetDefaultFontSize($default_font_size); }
1233
1234 $this->SetLineHeight(); // lineheight is in mm
1235
1236 $this->SetFColor($this->ConvertColor(255));
1237 $this->HREF='';
1238 $this->oldy=-1;
1239 $this->B=0;
1240 $this->U=false;
1241 $this->S=false;
1242 $this->I=0;
1243
1244 $this->listlvl=0;
1245 $this->listnum=0;
1246 $this->listtype='';
1247 $this->listoccur=array();
1248 $this->listlist=array();
1249 $this->listitem=array();
1250
1251 $this->tdbegin=false;
1252 $this->table=array();
1253 $this->cell=array();
1254 $this->col=-1;
1255 $this->row=-1;
1256 $this->cellBorderBuffer = array();
1257
1258 $this->divbegin=false;
1259 $this->divalign='';
1260 $this->divwidth=0;
1261 $this->divheight=0;
1262 $this->spanbgcolor=false;
1263 $this->divrevert=false;
1264 // mPDF 5.3.61
1265 $this->spanborder=false;
1266 $this->spanborddet=array();
1267
1268 $this->blockjustfinished=false;
1269 $this->listjustfinished=false;
1270 $this->ignorefollowingspaces = true; //in order to eliminate exceeding left-side spaces
1271 $this->toupper=false;
1272 $this->tolower=false;
1273 $this->capitalize=false;
1274 $this->dash_on=false;
1275 $this->dotted_on=false;
1276 $this->SUP=false;
1277 $this->SUB=false;
1278 $this->strike=false;
1279 $this->textshadow=''; // mPDF 5.3.A2
1280
1281 $this->currentfontfamily='';
1282 $this->currentfontsize='';
1283 $this->currentfontstyle='';
1284 $this->colorarray=array();
1285 $this->spanbgcolorarray=array();
1286 $this->textbuffer=array();
1287 $this->CSS=array();
1288 $this->internallink=array();
1289 $this->basepath = "";
1290
1291 $this->SetBasePath('');
1292
1293 $this->outlineparam = array();
1294 $this->outline_on = false;
1295
1296 $this->specialcontent = '';
1297 $this->selectoption = array();
1298
1299 /*-- IMPORTS --*/
1300
1301 $this->tpls = array();
1302 $this->tpl = 0;
1303 $this->tplprefix = "/TPL";
1304 $this->res = array();
1305 if ($this->enableImports) {
1306 $this->SetImportUse();
1307 }
1308 /*-- END IMPORTS --*/
1309
1310 if ($this->progressBar) { $this->StartProgressBarOutput($this->progressBar) ; } // *PROGRESS-BAR*
1311 }
1312
1313
1314 function _setPageSize($format, &$orientation) {
1315 //Page format
1316 if(is_string($format))
1317 {
1318 if ($format=='') { $format = 'A4'; }
1319 $pfo = 'P';
1320 if(preg_match('/([0-9a-zA-Z]*)-L/i',$format,$m)) { // e.g. A4-L = A4 landscape
1321 $format=$m[1];
1322 $pfo='L';
1323 }
1324 $format = $this->_getPageFormat($format);
1325 if (!$format) { $this->Error('Unknown page format: '.$format); }
1326 else { $orientation = $pfo; }
1327
1328 $this->fwPt=$format[0];
1329 $this->fhPt=$format[1];
1330 }
1331 else
1332 {
1333 if (!$format[0] || !$format[1]) { $this->Error('Invalid page format: '.$format[0].' '.$format[1]); }
1334 $this->fwPt=$format[0]*_MPDFK;
1335 $this->fhPt=$format[1]*_MPDFK;
1336 }
1337 $this->fw=$this->fwPt/_MPDFK;
1338 $this->fh=$this->fhPt/_MPDFK;
1339 //Page orientation
1340 $orientation=strtolower($orientation);
1341 if($orientation=='p' or $orientation=='portrait')
1342 {
1343 $orientation='P';
1344 $this->wPt=$this->fwPt;
1345 $this->hPt=$this->fhPt;
1346 }
1347 elseif($orientation=='l' or $orientation=='landscape')
1348 {
1349 $orientation='L';
1350 $this->wPt=$this->fhPt;
1351 $this->hPt=$this->fwPt;
1352 }
1353 else $this->Error('Incorrect orientation: '.$orientation);
1354 $this->CurOrientation=$orientation;
1355
1356 $this->w=$this->wPt/_MPDFK;
1357 $this->h=$this->hPt/_MPDFK;
1358 }
1359
1360 function _getPageFormat($format) {
1361 switch (strtoupper($format)) {
1362 case '4A0': {$format = array(4767.87,6740.79); break;}
1363 case '2A0': {$format = array(3370.39,4767.87); break;}
1364 case 'A0': {$format = array(2383.94,3370.39); break;}
1365 case 'A1': {$format = array(1683.78,2383.94); break;}
1366 case 'A2': {$format = array(1190.55,1683.78); break;}
1367 case 'A3': {$format = array(841.89,1190.55); break;}
1368 case 'A4': default: {$format = array(595.28,841.89); break;}
1369 case 'A5': {$format = array(419.53,595.28); break;}
1370 case 'A6': {$format = array(297.64,419.53); break;}
1371 case 'A7': {$format = array(209.76,297.64); break;}
1372 case 'A8': {$format = array(147.40,209.76); break;}
1373 case 'A9': {$format = array(104.88,147.40); break;}
1374 case 'A10': {$format = array(73.70,104.88); break;}
1375 case 'B0': {$format = array(2834.65,4008.19); break;}
1376 case 'B1': {$format = array(2004.09,2834.65); break;}
1377 case 'B2': {$format = array(1417.32,2004.09); break;}
1378 case 'B3': {$format = array(1000.63,1417.32); break;}
1379 case 'B4': {$format = array(708.66,1000.63); break;}
1380 case 'B5': {$format = array(498.90,708.66); break;}
1381 case 'B6': {$format = array(354.33,498.90); break;}
1382 case 'B7': {$format = array(249.45,354.33); break;}
1383 case 'B8': {$format = array(175.75,249.45); break;}
1384 case 'B9': {$format = array(124.72,175.75); break;}
1385 case 'B10': {$format = array(87.87,124.72); break;}
1386 case 'C0': {$format = array(2599.37,3676.54); break;}
1387 case 'C1': {$format = array(1836.85,2599.37); break;}
1388 case 'C2': {$format = array(1298.27,1836.85); break;}
1389 case 'C3': {$format = array(918.43,1298.27); break;}
1390 case 'C4': {$format = array(649.13,918.43); break;}
1391 case 'C5': {$format = array(459.21,649.13); break;}
1392 case 'C6': {$format = array(323.15,459.21); break;}
1393 case 'C7': {$format = array(229.61,323.15); break;}
1394 case 'C8': {$format = array(161.57,229.61); break;}
1395 case 'C9': {$format = array(113.39,161.57); break;}
1396 case 'C10': {$format = array(79.37,113.39); break;}
1397 case 'RA0': {$format = array(2437.80,3458.27); break;}
1398 case 'RA1': {$format = array(1729.13,2437.80); break;}
1399 case 'RA2': {$format = array(1218.90,1729.13); break;}
1400 case 'RA3': {$format = array(864.57,1218.90); break;}
1401 case 'RA4': {$format = array(609.45,864.57); break;}
1402 case 'SRA0': {$format = array(2551.18,3628.35); break;}
1403 case 'SRA1': {$format = array(1814.17,2551.18); break;}
1404 case 'SRA2': {$format = array(1275.59,1814.17); break;}
1405 case 'SRA3': {$format = array(907.09,1275.59); break;}
1406 case 'SRA4': {$format = array(637.80,907.09); break;}
1407 case 'LETTER': {$format = array(612.00,792.00); break;}
1408 case 'LEGAL': {$format = array(612.00,1008.00); break;}
1409 case 'LEDGER': {$format = array(279.00,432.00); break;} // mPDF 5.3.38
1410 case 'TABLOID': {$format = array(279.00,432.00); break;} // mPDF 5.3.38
1411 case 'EXECUTIVE': {$format = array(521.86,756.00); break;}
1412 case 'FOLIO': {$format = array(612.00,936.00); break;}
1413 case 'B': {$format=array(362.83,561.26 ); break;} // 'B' format paperback size 128x198mm
1414 case 'A': {$format=array(314.65,504.57 ); break;} // 'A' format paperback size 111x178mm
1415 case 'DEMY': {$format=array(382.68,612.28 ); break;} // 'Demy' format paperback size 135x216mm
1416 case 'ROYAL': {$format=array(433.70,663.30 ); break;} // 'Royal' format paperback size 153x234mm
1417 default: $format = false;
1418 }
1419 return $format;
1420 }
1421
1422
1423 /*-- PROGRESS-BAR --*/
1424 function StartProgressBarOutput($mode=1) {
1425 // must be relative path, or URI (not a file system path)
1426 if (!defined('_MPDF_URI')) {
1427 $this->progressBar = false;
1428 if ($this->debug) { $this->Error("You need to define _MPDF_URI to use the progress bar!"); }
1429 else return false;
1430 }
1431 $this->progressBar = $mode;
1432 if ($this->progbar_altHTML) {
1433 echo $this->progbar_altHTML;
1434 }
1435 else {
1436 echo '<html>
1437 <head>
1438 <title>mPDF File Progress</title>
1439 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
1440 <link rel="stylesheet" type="text/css" href="'._MPDF_URI.'progbar.css" />
1441 </head>
1442 <body>
1443 <div class="main">
1444 <div class="heading">'.$this->progbar_heading.'</div>
1445 <div class="demo">
1446 ';
1447 if ($this->progressBar==2) { echo ' <table width="100%"><tr><td style="width: 50%;">
1448 <span class="barheading">Writing HTML code</span> <br/>
1449
1450 <div class="progressBar">
1451 <div id="element1" class="innerBar">&nbsp;</div>
1452 </div>
1453 <span class="code" id="box1"></span>
1454 </td><td style="width: 50%;">
1455 <span class="barheading">Autosizing elements</span> <br/>
1456 <div class="progressBar">
1457 <div id="element4" class="innerBar">&nbsp;</div>
1458 </div>
1459 <span class="code" id="box4"></span>
1460 <br/><br/>
1461 <span class="barheading">Writing Tables</span> <br/>
1462 <div class="progressBar">
1463 <div id="element7" class="innerBar">&nbsp;</div>
1464 </div>
1465 <span class="code" id="box7"></span>
1466 </td></tr>
1467 <tr><td><br /><br /></td><td></td></tr>
1468 <tr><td style="width: 50%;">
1469 '; }
1470 echo ' <span class="barheading">Writing PDF file</span> <br/>
1471 <div class="progressBar">
1472 <div id="element2" class="innerBar">&nbsp;</div>
1473 </div>
1474 <span class="code" id="box2"></span>
1475 ';
1476 if ($this->progressBar==2) { echo '
1477 </td><td style="width: 50%;">
1478 <span class="barheading">Memory usage</span> <br/>
1479 <div class="progressBar">
1480 <div id="element5" class="innerBar">&nbsp;</div>
1481 </div>
1482 <span id="box5">0</span> '.ini_get("memory_limit").'<br />
1483 <br/><br/>
1484 <span class="barheading">Memory usage (peak)</span> <br/>
1485 <div class="progressBar">
1486 <div id="element6" class="innerBar">&nbsp;</div>
1487 </div>
1488 <span id="box6">0</span> '.ini_get("memory_limit").'<br />
1489 </td></tr>
1490 </table>
1491 '; }
1492 echo ' <br/><br/>
1493 <span id="box3"></span>
1494
1495 </div>
1496 ';
1497 }
1498 ob_flush();
1499 flush();
1500 }
1501
1502 function UpdateProgressBar($el,$val,$txt='') {
1503 // $val should be a string - 5 = actual value, +15 = increment
1504
1505 if ($this->progressBar<2) {
1506 if ($el>3) { return; }
1507 else if ($el ==1) { $el = 2; }
1508 }
1509 echo '<script type="text/javascript">';
1510 if ($val) { echo ' document.getElementById(\'element'.$el.'\').style.width=\''.$val.'%\'; '; }
1511 if ($txt) { echo ' document.getElementById(\'box'.$el.'\').innerHTML=\''.$txt.'\'; '; }
1512 if ($this->progressBar==2) {
1513 $m = round(memory_get_usage(true)/1048576); // mPDF 5.3.72
1514 $m2 = round(memory_get_peak_usage(true)/1048576); // mPDF 5.3.72
1515 $mem = $m * 100 / (ini_get("memory_limit")+0);
1516 $mem2 = $m2 * 100 / (ini_get("memory_limit")+0);
1517 echo ' document.getElementById(\'element5\').style.width=\''.$mem.'%\'; ';
1518 echo ' document.getElementById(\'element6\').style.width=\''.$mem2.'%\'; ';
1519 echo ' document.getElementById(\'box5\').innerHTML=\''.$m.'MB / \'; ';
1520 echo ' document.getElementById(\'box6\').innerHTML=\''.$m2.'MB / \'; ';
1521 }
1522 echo '</script>'."\n";
1523 ob_flush();
1524 flush();
1525 }
1526 /*-- END PROGRESS-BAR --*/
1527
1528
1529
1530 function RestrictUnicodeFonts($res) {
1531 // $res = array of (Unicode) fonts to restrict to: e.g. norasi|norasiB - language specific
1532 if (count($res)) { // Leave full list of available fonts if passed blank array
1533 $this->available_unifonts = $res;
1534 }
1535 else { $this->available_unifonts = $this->default_available_fonts; }
1536 if (count($this->available_unifonts) == 0) { $this->available_unifonts[] = $this->default_available_fonts[0]; }
1537 $this->available_unifonts = array_values($this->available_unifonts);
1538 }
1539
1540
1541 function setMBencoding($enc) {
1542 // mPDF 5.3.07
1543 if ($this->mb_enc != $enc) {
1544 $this->mb_enc = $enc;
1545 mb_internal_encoding($this->mb_enc);
1546 }
1547 }
1548
1549
1550 function SetMargins($left,$right,$top) {
1551 //Set left, top and right margins
1552 $this->lMargin=$left;
1553 $this->rMargin=$right;
1554 $this->tMargin=$top;
1555 }
1556
1557 function ResetMargins() {
1558 //ReSet left, top margins
1559 if (($this->forcePortraitHeaders || $this->forcePortraitMargins) && $this->DefOrientation=='P' && $this->CurOrientation=='L') {
1560 if (($this->mirrorMargins) && (($this->page)%2==0)) { // EVEN
1561 $this->tMargin=$this->orig_rMargin;
1562 $this->bMargin=$this->orig_lMargin;
1563 }
1564 else { // ODD // OR NOT MIRRORING MARGINS/FOOTERS
1565 $this->tMargin=$this->orig_lMargin;
1566 $this->bMargin=$this->orig_rMargin;
1567 }
1568 $this->lMargin=$this->DeflMargin;
1569 $this->rMargin=$this->DefrMargin;
1570 $this->MarginCorrection = 0;
1571 $this->PageBreakTrigger=$this->h-$this->bMargin;
1572 }
1573 else if (($this->mirrorMargins) && (($this->page)%2==0)) { // EVEN
1574 $this->lMargin=$this->DefrMargin;
1575 $this->rMargin=$this->DeflMargin;
1576 $this->MarginCorrection = $this->DefrMargin-$this->DeflMargin;
1577
1578 }
1579 else { // ODD // OR NOT MIRRORING MARGINS/FOOTERS
1580 $this->lMargin=$this->DeflMargin;
1581 $this->rMargin=$this->DefrMargin;
1582 if ($this->mirrorMargins) { $this->MarginCorrection = $this->DeflMargin-$this->DefrMargin; }
1583 }
1584 $this->x=$this->lMargin;
1585
1586 }
1587
1588 function SetLeftMargin($margin) {
1589 //Set left margin
1590 $this->lMargin=$margin;
1591 if($this->page>0 and $this->x<$margin) $this->x=$margin;
1592 }
1593
1594 function SetTopMargin($margin) {
1595 //Set top margin
1596 $this->tMargin=$margin;
1597 }
1598
1599 function SetRightMargin($margin) {
1600 //Set right margin
1601 $this->rMargin=$margin;
1602 }
1603
1604 function SetAutoPageBreak($auto,$margin=0) {
1605 //Set auto page break mode and triggering margin
1606 $this->autoPageBreak=$auto;
1607 $this->bMargin=$margin;
1608 $this->PageBreakTrigger=$this->h-$margin;
1609 }
1610
1611 function SetDisplayMode($zoom,$layout='continuous') {
1612 //Set display mode in viewer
1613 if($zoom=='fullpage' or $zoom=='fullwidth' or $zoom=='real' or $zoom=='default' or !is_string($zoom))
1614 $this->ZoomMode=$zoom;
1615 else
1616 $this->Error('Incorrect zoom display mode: '.$zoom);
1617 if($layout=='single' or $layout=='continuous' or $layout=='two' or $layout=='twoleft' or $layout=='tworight' or $layout=='default')
1618 $this->LayoutMode=$layout;
1619 else
1620 $this->Error('Incorrect layout display mode: '.$layout);
1621 }
1622
1623 function SetCompression($compress) {
1624 //Set page compression
1625 if(function_exists('gzcompress')) $this->compress=$compress;
1626 else $this->compress=false;
1627 }
1628
1629 function SetTitle($title) {
1630 //Title of document // Arrives as UTF-8
1631 $this->title = $title;
1632 }
1633
1634 function SetSubject($subject) {
1635 //Subject of document
1636 $this->subject= $subject;
1637 }
1638
1639 function SetAuthor($author) {
1640 //Author of document
1641 $this->author= $author;
1642 }
1643
1644 function SetKeywords($keywords) {
1645 //Keywords of document
1646 $this->keywords= $keywords;
1647 }
1648
1649 function SetCreator($creator) {
1650 //Creator of document
1651 $this->creator= $creator;
1652 }
1653
1654
1655 function SetAnchor2Bookmark($x) {
1656 $this->anchor2Bookmark = $x;
1657 }
1658
1659 function AliasNbPages($alias='{nb}') {
1660 //Define an alias for total number of pages
1661 $this->aliasNbPg=$alias;
1662 }
1663
1664 function AliasNbPageGroups($alias='{nbpg}') {
1665 //Define an alias for total number of pages in a group
1666 $this->aliasNbPgGp=$alias;
1667 }
1668
1669 function SetAlpha($alpha, $bm='Normal', $return=false, $mode='B') {
1670 // alpha: real value from 0 (transparent) to 1 (opaque)
1671 // bm: blend mode, one of the following:
1672 // Normal, Multiply, Screen, Overlay, Darken, Lighten, ColorDodge, ColorBurn,
1673 // HardLight, SoftLight, Difference, Exclusion, Hue, Saturation, Color, Luminosity
1674 // set alpha for stroking (CA) and non-stroking (ca) operations
1675 // mode determines F (fill) S (stroke) B (both)
1676 if (($this->PDFA || $this->PDFX) && $alpha!=1) {
1677 if (($this->PDFA && !$this->PDFAauto) || ($this->PDFX && !$this->PDFXauto)) { $this->PDFAXwarnings[] = "Image opacity must be 100% (Opacity changed to 100%)"; }
1678 $alpha = 1;
1679 }
1680 $a = array('BM'=>'/'.$bm);
1681 if ($mode=='F' || $mode='B') $a['ca'] = $alpha;
1682 if ($mode=='S' || $mode='B') $a['CA'] = $alpha;
1683 $gs = $this->AddExtGState($a);
1684 if ($return) { return sprintf('/GS%d gs', $gs); }
1685 else { $this->_out(sprintf('/GS%d gs', $gs)); }
1686 }
1687
1688 function AddExtGState($parms) {
1689 $n = count($this->extgstates);
1690 // check if graphics state already exists
1691 for ($i=1; $i<=$n; $i++) {
1692 if (count($this->extgstates[$i]['parms']) == count($parms)) {
1693 $same = true;
1694 foreach($this->extgstates[$i]['parms'] AS $k=>$v) {
1695 if (!isset($parms[$k]) || $parms[$k] != $v) { $same = false; break; }
1696 }
1697 if ($same) { return $i; }
1698 }
1699 }
1700 $n++;
1701 $this->extgstates[$n]['parms'] = $parms;
1702 return $n;
1703 }
1704
1705 // mPDF 5.3.41
1706 function SetVisibility($v) {
1707 if (($this->PDFA || $this->PDFX) && $this->visibility!='visible') { $this->PDFAXwarnings[] = "Cannot set visibility to anything other than full when using PDFA or PDFX"; return ''; }
1708 else if (!$this->PDFA && !$this->PDFX) // mPDF 5.3.45
1709 $this->pdf_version='1.5';
1710 if($this->visibility!='visible') {
1711 $this->_out('EMC');
1712 $this->hasOC = true; // mPDF 5.3.45
1713 }
1714 if($v=='printonly')
1715 $this->_out('/OC /OC1 BDC');
1716 elseif($v=='screenonly')
1717 $this->_out('/OC /OC2 BDC');
1718 elseif($v=='hidden')
1719 $this->_out('/OC /OC3 BDC');
1720 elseif($v!='visible')
1721 $this->Error('Incorrect visibility: '.$v);
1722 $this->visibility=$v;
1723 }
1724
1725 function Error($msg) {
1726 //Fatal error
1727 header('Content-Type: text/html; charset=utf-8');
1728 die('<B>mPDF error: </B>'.$msg);
1729 }
1730
1731 function Open() {
1732 //Begin document
1733 if($this->state==0) $this->_begindoc();
1734 }
1735
1736 function Close() {
1737 if ($this->progressBar) { $this->UpdateProgressBar(2,'2','Closing last page'); } // *PROGRESS-BAR*
1738 //Terminate document
1739 if($this->state==3) return;
1740 if($this->page==0) $this->AddPage($this->CurOrientation);
1741 if (count($this->cellBorderBuffer)) { $this->printcellbuffer(); } // *TABLES*
1742 if ($this->tablebuffer) { $this->printtablebuffer(); } // *TABLES*
1743 /*-- COLUMNS --*/
1744
1745 if ($this->ColActive) {
1746 $this->SetColumns(0);
1747 $this->ColActive = 0;
1748 if (count($this->columnbuffer)) { $this->printcolumnbuffer(); }
1749 }
1750 /*-- END COLUMNS --*/
1751 if (count($this->divbuffer)) { $this->printdivbuffer(); }
1752
1753 // BODY Backgrounds
1754 $s = '';
1755
1756 $s .= $this->PrintBodyBackgrounds();
1757
1758 $s .= $this->PrintPageBackgrounds();
1759 $this->pages[$this->page] = preg_replace('/(___BACKGROUND___PATTERNS'.date('jY').')/', "\n".$s."\n".'\\1', $this->pages[$this->page]);
1760 $this->pageBackgrounds = array();
1761
1762 // mPDF 5.3.41
1763 if($this->visibility!='visible')
1764 $this->SetVisibility('visible');
1765
1766 if (!$this->tocontents || !$this->tocontents->TOCmark) { //Page footer
1767 $this->InFooter=true;
1768 $this->Footer();
1769 $this->InFooter=false;
1770 }
1771 if ($this->tocontents && ($this->tocontents->TOCmark || count($this->tocontents->m_TOC))) { $this->tocontents->insertTOC(); } // *TOC*
1772
1773 //Close page
1774 $this->_endpage();
1775
1776 //Close document
1777 $this->_enddoc();
1778 }
1779
1780 /*-- BACKGROUNDS --*/
1781 function _resizeBackgroundImage($imw, $imh, $cw, $ch, $resize=0, $repx, $repy) {
1782 $cw = $cw*_MPDFK;
1783 $ch = $ch*_MPDFK;
1784 if (!$resize) { return array($imw, $imh, $repx, $repy); }
1785 if ($resize==1 && $imw > $cw) {
1786 $h = $imh * $cw/$imw;
1787 $repx = false;
1788 return array($cw, $h, $repx, $repy);
1789 }
1790 else if ($resize==2 && $imh > $ch) {
1791 $w = $imw * $ch/$imh;
1792 $repy = false;
1793 return array($w, $ch, $repx, $repy);
1794 }
1795 else if ($resize==3) {
1796 $w = $imw;
1797 $h = $imh;
1798 $saverepx = $repx;
1799 if ($w > $cw) {
1800 $h = $h * $cw/$w;
1801 $w = $cw;
1802 $repx = false;
1803 }
1804 if ($h > $ch) {
1805 $w = $w * $ch/$h;
1806 $h = $ch;
1807 $repy = false;
1808 $repx = $saverepx;
1809 }
1810 return array($w, $h, $repx, $repy);
1811 }
1812 else if ($resize==4) {
1813 $h = $imh * $cw/$imw;
1814 $repx = false;
1815 return array($cw, $h, $repx, $repy);
1816 }
1817 else if ($resize==5) {
1818 $w = $imw * $ch/$imh;
1819 $repy = false;
1820 return array($w, $ch, $repx, $repy);
1821 }
1822 else if ($resize==6) {
1823 $repx = false;
1824 $repy = false;
1825 return array($cw, $ch, $repx, $repy);
1826 }
1827 return array($imw, $imh, $repx, $repy);
1828 }
1829
1830
1831 function SetBackground(&$properties, &$maxwidth) {
1832 if (preg_match('/(-moz-)*(repeating-)*(linear|radial)-gradient/',$properties['BACKGROUND-IMAGE'])) {
1833 return array('gradient'=>$properties['BACKGROUND-IMAGE']);
1834 }
1835 else {
1836 $file = $properties['BACKGROUND-IMAGE'];
1837 $sizesarray = $this->Image($file,0,0,0,0,'','',false, false, false, false, true);
1838 if (isset($sizesarray['IMAGE_ID'])) {
1839 $image_id = $sizesarray['IMAGE_ID'];
1840 $orig_w = $sizesarray['WIDTH']*_MPDFK; // in user units i.e. mm
1841 $orig_h = $sizesarray['HEIGHT']*_MPDFK; // (using $this->img_dpi)
1842 if (isset($properties['BACKGROUND-IMAGE-RESOLUTION'])) {
1843 if (preg_match('/from-image/i', $properties['BACKGROUND-IMAGE-RESOLUTION']) && isset($sizesarray['set-dpi']) && $sizesarray['set-dpi']>0) {
1844 $orig_w *= $this->img_dpi / $sizesarray['set-dpi'];
1845 $orig_h *= $this->img_dpi / $sizesarray['set-dpi'];
1846 }
1847 else if (preg_match('/(\d+)dpi/i', $properties['BACKGROUND-IMAGE-RESOLUTION'], $m)) {
1848 $dpi = $m[1];
1849 if ($dpi > 0) {
1850 $orig_w *= $this->img_dpi / $dpi;
1851 $orig_h *= $this->img_dpi / $dpi;
1852 }
1853 }
1854 }
1855 $x_repeat = true;
1856 $y_repeat = true;
1857 if (isset($properties['BACKGROUND-REPEAT'])) {
1858 if ($properties['BACKGROUND-REPEAT']=='no-repeat' || $properties['BACKGROUND-REPEAT']=='repeat-x') { $y_repeat = false; }
1859 if ($properties['BACKGROUND-REPEAT']=='no-repeat' || $properties['BACKGROUND-REPEAT']=='repeat-y') { $x_repeat = false; }
1860 }
1861 $x_pos = 0;
1862 $y_pos = 0;
1863 if (isset($properties['BACKGROUND-POSITION'])) {
1864 $ppos = preg_split('/\s+/',$properties['BACKGROUND-POSITION']);
1865 $x_pos = $ppos[0];
1866 $y_pos = $ppos[1];
1867 if (!stristr($x_pos ,'%') ) { $x_pos = $this->ConvertSize($x_pos ,$maxwidth,$this->FontSize); }
1868 if (!stristr($y_pos ,'%') ) { $y_pos = $this->ConvertSize($y_pos ,$maxwidth,$this->FontSize); }
1869 }
1870 if (isset($properties['BACKGROUND-IMAGE-RESIZE'])) { $resize = $properties['BACKGROUND-IMAGE-RESIZE']; }
1871 else { $resize = 0; }
1872 if (isset($properties['BACKGROUND-IMAGE-OPACITY'])) { $opacity = $properties['BACKGROUND-IMAGE-OPACITY']; }
1873 else { $opacity = 1; }
1874 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']);
1875 }
1876 }
1877 return false;
1878 }
1879 /*-- END BACKGROUNDS --*/
1880
1881 function PrintBodyBackgrounds() {
1882 $s = '';
1883 $clx = 0;
1884 $cly = 0;
1885 $clw = $this->w;
1886 $clh = $this->h;
1887 // If using bleed and trim margins in paged media
1888 if ($this->pageDim[$this->page]['outer_width_LR'] || $this->pageDim[$this->page]['outer_width_TB']) {
1889 $clx = $this->pageDim[$this->page]['outer_width_LR'] - $this->pageDim[$this->page]['bleedMargin'];
1890 $cly = $this->pageDim[$this->page]['outer_width_TB'] - $this->pageDim[$this->page]['bleedMargin'];
1891 $clw = $this->w - 2*$clx;
1892 $clh = $this->h - 2*$cly;
1893 }
1894
1895 if ($this->bodyBackgroundColor) {
1896 $s .= 'q ' .$this->SetFColor($this->bodyBackgroundColor, true)."\n";
1897 // mPDF 5.3.74
1898 if ($this->bodyBackgroundColor{0}==5) { // RGBa
1899 $s .= $this->SetAlpha(ord($this->bodyBackgroundColor{4})/100, 'Normal', true, 'F')."\n";
1900 }
1901 else if ($this->bodyBackgroundColor{0}==6) { // CMYKa
1902 $s .= $this->SetAlpha(ord($this->bodyBackgroundColor{5})/100, 'Normal', true, 'F')."\n";
1903 }
1904 $s .= sprintf('%.3F %.3F %.3F %.3F re f Q', ($clx*_MPDFK), ($cly*_MPDFK),$clw*_MPDFK,$clh*_MPDFK)."\n";
1905 }
1906
1907 /*-- BACKGROUNDS --*/
1908 if ($this->bodyBackgroundGradient) {
1909 $g = $this->grad->parseBackgroundGradient($this->bodyBackgroundGradient);
1910 if ($g) {
1911 $s .= $this->grad->Gradient($clx, $cly, $clw, $clh, (isset($g['gradtype']) ? $g['gradtype'] : null), $g['stops'], $g['colorspace'], $g['coords'], $g['extend'], true);
1912 }
1913 }
1914 if ($this->bodyBackgroundImage) {
1915 if ( $this->bodyBackgroundImage['gradient'] && preg_match('/(-moz-)*(repeating-)*(linear|radial)-gradient/', $this->bodyBackgroundImage['gradient'])) {
1916 $g = $this->grad->parseMozGradient( $this->bodyBackgroundImage['gradient']);
1917 if ($g) {
1918 $s .= $this->grad->Gradient($clx, $cly, $clw, $clh, $g['type'], $g['stops'], $g['colorspace'], $g['coords'], $g['extend'], true);
1919 }
1920 }
1921 else if ($this->bodyBackgroundImage['image_id']) { // Background pattern
1922 $n = count($this->patterns)+1;
1923 // If using resize, uses TrimBox (not including the bleed)
1924 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']);
1925
1926 $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']);
1927 // mPDF 5.3.12
1928 if (($this->bodyBackgroundImage['opacity']>0 || $this->bodyBackgroundImage['opacity']==='0') && $this->bodyBackgroundImage['opacity']<1) { $opac = $this->SetAlpha($this->bodyBackgroundImage['opacity'],'Normal',true); }
1929 else { $opac = ''; }
1930 $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";
1931 }
1932 }
1933 /*-- END BACKGROUNDS --*/
1934 return $s;
1935 }
1936
1937
1938 function PrintPageBackgrounds($adjustmenty=0) {
1939 $s = '';
1940
1941 ksort($this->pageBackgrounds);
1942 foreach($this->pageBackgrounds AS $bl=>$pbs) {
1943 foreach ($pbs AS $pb) {
1944 // mPDF 5.3.A1
1945 if ((!isset($pb['image_id']) && !isset($pb['gradient'])) || isset($pb['shadowonly'])) { // Background colour or boxshadow
1946 // mPDF 5.3.42 VISIBILITY
1947 if($pb['visibility']!='visible') {
1948 if($pb['visibility']=='printonly')
1949 $s .= '/OC /OC1 BDC'."\n";
1950 else if($pb['visibility']=='screenonly')
1951 $s .= '/OC /OC2 BDC'."\n";
1952 else if($pb['visibility']=='hidden')
1953 $s .= '/OC /OC3 BDC'."\n";
1954 }
1955 // mPDF 5.3.A1
1956 // Box shadow
1957 if (isset($pb['shadow']) && $pb['shadow']) { $s .= $pb['shadow']."\n"; }
1958 if (isset($pb['clippath']) && $pb['clippath']) { $s .= $pb['clippath']."\n"; }
1959 $s .= 'q '.$this->SetFColor($pb['col'], true)."\n";
1960 // mPDF 5.3.74
1961 if ($pb['col']{0}==5) { // RGBa
1962 $s .= $this->SetAlpha(ord($pb['col']{4})/100, 'Normal', true, 'F')."\n";
1963 }
1964 else if ($pb['col']{0}==6) { // CMYKa
1965 $s .= $this->SetAlpha(ord($pb['col']{5})/100, 'Normal', true, 'F')."\n";
1966 }
1967 $s .= sprintf('%.3F %.3F %.3F %.3F re f Q',$pb['x']*_MPDFK,($this->h-$pb['y'])*_MPDFK,$pb['w']*_MPDFK,-$pb['h']*_MPDFK)."\n";
1968 if (isset($pb['clippath']) && $pb['clippath']) { $s .= 'Q'."\n"; }
1969 // mPDF 5.3.42
1970 if($pb['visibility']!='visible')
1971 $s .= 'EMC'."\n";
1972 }
1973 }
1974 /*-- BACKGROUNDS --*/
1975 foreach ($pbs AS $pb) {
1976 // mPDF 5.3.42 VISIBILITY
1977 if($pb['visibility']!='visible') {
1978 if($pb['visibility']=='printonly')
1979 $s .= '/OC /OC1 BDC'."\n";
1980 else if($pb['visibility']=='screenonly')
1981 $s .= '/OC /OC2 BDC'."\n";
1982 else if($pb['visibility']=='hidden')
1983 $s .= '/OC /OC3 BDC'."\n";
1984 }
1985 if (isset($pb['gradient']) && $pb['gradient']) {
1986 if (isset($pb['clippath']) && $pb['clippath']) { $s .= $pb['clippath']."\n"; }
1987 $s .= $this->grad->Gradient($pb['x'], $pb['y'], $pb['w'], $pb['h'], $pb['gradtype'], $pb['stops'], $pb['colorspace'], $pb['coords'], $pb['extend'], true);
1988 if (isset($pb['clippath']) && $pb['clippath']) { $s .= 'Q'."\n"; }
1989 }
1990 else if (isset($pb['image_id']) && $pb['image_id']) { // Background pattern
1991 $pb['y'] -= $adjustmenty;
1992 $pb['h'] += $adjustmenty;
1993 $n = count($this->patterns)+1;
1994 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']);
1995 $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']);
1996 $x = $pb['x']*_MPDFK;
1997 $y = ($this->h - $pb['y'])*_MPDFK;
1998 $w = $pb['w']*_MPDFK;
1999 $h = -$pb['h']*_MPDFK;
2000 if (isset($pb['clippath']) && $pb['clippath']) { $s .= $pb['clippath']."\n"; }
2001 if ($this->writingHTMLfooter || $this->writingHTMLheader) {
2002 $iw = $pb['orig_w']/_MPDFK;
2003 $ih = $pb['orig_h']/_MPDFK;
2004 $w = $pb['w'];
2005 $h = $pb['h'];
2006 $x0 = $pb['x'];
2007 $y0 = $pb['y'];
2008
2009 // Number to repeat
2010 if ($pb['x_repeat']) { $nx = ceil($w/$iw); }
2011 else { $nx = 1; }
2012 if ($pb['y_repeat']) { $ny = ceil($h/$ih); }
2013 else { $ny = 1; }
2014
2015 $x_pos = $pb['x_pos'];
2016 if (stristr($x_pos ,'%') ) {
2017 $x_pos += 0;
2018 $x_pos /= 100;
2019 $x_pos = ($w * $x_pos) - ($iw * $x_pos);
2020 }
2021 $y_pos = $pb['y_pos'];
2022 if (stristr($y_pos ,'%') ) {
2023 $y_pos += 0;
2024 $y_pos /= 100;
2025 $y_pos = ($h * $y_pos) - ($ih * $y_pos);
2026 }
2027 if ($nx>1) {
2028 while($x_pos>0) { $x_pos -= $iw; }
2029 }
2030 if ($ny>1) {
2031 while($y_pos>0) { $y_pos -= $ih; }
2032 }
2033 for($xi=0;$xi<$nx;$xi++) {
2034 for($yi=0;$yi<$ny;$yi++) {
2035 $x = $x0 + $x_pos + ($iw*$xi);
2036 $y = $y0 + $y_pos + ($ih*$yi);
2037 if ($pb['opacity']>0 && $pb['opacity']<1) { $opac = $this->SetAlpha($pb['opacity'],'Normal',true); }
2038 else { $opac = ''; }
2039 $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";
2040 }
2041 }
2042 }
2043 else {
2044 // mPDF 5.3.12
2045 if (($pb['opacity']>0 || $pb['opacity']==='0') && $pb['opacity']<1) { $opac = $this->SetAlpha($pb['opacity'],'Normal',true); }
2046 else { $opac = ''; }
2047 $s .= sprintf('q /Pattern cs /P%d scn %s %.3F %.3F %.3F %.3F re f Q', $n, $opac, $x, $y, $w, $h) ."\n";
2048 }
2049 if (isset($pb['clippath']) && $pb['clippath']) { $s .= 'Q'."\n"; }
2050 }
2051 // mPDF 5.3.42 VISIBILITY
2052 if($pb['visibility']!='visible')
2053 $s .= 'EMC'."\n";
2054
2055 }
2056 /*-- END BACKGROUNDS --*/
2057 }
2058 return $s;
2059 }
2060
2061 function PrintTableBackgrounds($adjustmenty=0) {
2062 $s = '';
2063 /*-- BACKGROUNDS --*/
2064 ksort($this->tableBackgrounds);
2065 foreach($this->tableBackgrounds AS $bl=>$pbs) {
2066 foreach ($pbs AS $pb) {
2067 if ((!isset($pb['gradient']) || !$pb['gradient']) && (!isset($pb['image_id']) || !$pb['image_id'])) {
2068 $s .= 'q '.$this->SetFColor($pb['col'], true)."\n"; // mPDF 5.3.68
2069 // mPDF 5.3.68
2070 // mPDF 5.3.74
2071 if ($pb['col']{0}==5) { // RGBa
2072 $s .= $this->SetAlpha(ord($pb['col']{4})/100, 'Normal', true, 'F')."\n";
2073 }
2074 else if ($pb['col']{0}==6) { // CMYKa
2075 $s .= $this->SetAlpha(ord($pb['col']{5})/100, 'Normal', true, 'F')."\n";
2076 }
2077 $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"; // mPDF 5.3.68
2078 }
2079 if (isset($pb['gradient']) && $pb['gradient']) {
2080 if (isset($pb['clippath']) && $pb['clippath']) { $s .= $pb['clippath']."\n"; }
2081 $s .= $this->grad->Gradient($pb['x'], $pb['y'], $pb['w'], $pb['h'], $pb['gradtype'], $pb['stops'], $pb['colorspace'], $pb['coords'], $pb['extend'], true);
2082 if (isset($pb['clippath']) && $pb['clippath']) { $s .= 'Q'."\n"; }
2083 }
2084 if (isset($pb['image_id']) && $pb['image_id']) { // Background pattern
2085 $pb['y'] -= $adjustmenty;
2086 $pb['h'] += $adjustmenty;
2087 $n = count($this->patterns)+1;
2088 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']);
2089 $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']);
2090 $x = $pb['x']*_MPDFK;
2091 $y = ($this->h - $pb['y'])*_MPDFK;
2092 $w = $pb['w']*_MPDFK;
2093 $h = -$pb['h']*_MPDFK;
2094 if (isset($pb['clippath']) && $pb['clippath']) { $s .= $pb['clippath']."\n"; }
2095 if ($pb['opacity']>0 && $pb['opacity']<1) { $opac = $this->SetAlpha($pb['opacity'],'Normal',true); }
2096 else { $opac = ''; }
2097 $s .= sprintf('q /Pattern cs /P%d scn %s %.3F %.3F %.3F %.3F re f Q', $n, $opac, $x, $y, $w, $h) ."\n";
2098 if (isset($pb['clippath']) && $pb['clippath']) { $s .= 'Q'."\n"; }
2099 }
2100 }
2101 }
2102 /*-- END BACKGROUNDS --*/
2103 return $s;
2104 }
2105
2106
2107 // Depracated - can use AddPage for all
2108 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='')
2109 {
2110 $this->AddPage($orientation,$condition,$resetpagenum, $pagenumstyle, $suppress,$mgl,$mgr,$mgt,$mgb,$mgh,$mgf, $ohname, $ehname, $ofname, $efname, $ohvalue, $ehvalue, $ofvalue, $efvalue,$pagesel,$newformat);
2111 }
2112
2113
2114 function AddPageByArray($a) {
2115 if (!is_array($a)) { $a = array(); }
2116 // mPDF 5.3.26
2117 $orientation = (isset($a['orientation']) ? $a['orientation'] : '');
2118 $condition = (isset($a['condition']) ? $a['condition'] : (isset($a['type']) ? $a['type'] : ''));
2119 $resetpagenum = (isset($a['resetpagenum']) ? $a['resetpagenum'] : '');
2120 $pagenumstyle = (isset($a['pagenumstyle']) ? $a['pagenumstyle'] : '');
2121 $suppress = (isset($a['suppress']) ? $a['suppress'] : '');
2122 $mgl = (isset($a['mgl']) ? $a['mgl'] : (isset($a['margin-left']) ? $a['margin-left'] : ''));
2123 $mgr = (isset($a['mgr']) ? $a['mgr'] : (isset($a['margin-right']) ? $a['margin-right'] : ''));
2124 $mgt = (isset($a['mgt']) ? $a['mgt'] : (isset($a['margin-top']) ? $a['margin-top'] : ''));
2125 $mgb = (isset($a['mgb']) ? $a['mgb'] : (isset($a['margin-bottom']) ? $a['margin-bottom'] : ''));
2126 $mgh = (isset($a['mgh']) ? $a['mgh'] : (isset($a['margin-header']) ? $a['margin-header'] : ''));
2127 $mgf = (isset($a['mgf']) ? $a['mgf'] : (isset($a['margin-footer']) ? $a['margin-footer'] : ''));
2128 $ohname = (isset($a['ohname']) ? $a['ohname'] : (isset($a['odd-header-name']) ? $a['odd-header-name'] : ''));
2129 $ehname = (isset($a['ehname']) ? $a['ehname'] : (isset($a['even-header-name']) ? $a['even-header-name'] : ''));
2130 $ofname = (isset($a['ofname']) ? $a['ofname'] : (isset($a['odd-footer-name']) ? $a['odd-footer-name'] : ''));
2131 $efname = (isset($a['efname']) ? $a['efname'] : (isset($a['even-footer-name']) ? $a['even-footer-name'] : ''));
2132 $ohvalue = (isset($a['ohvalue']) ? $a['ohvalue'] : (isset($a['odd-header-value']) ? $a['odd-header-value'] : 0));
2133 $ehvalue = (isset($a['ehvalue']) ? $a['ehvalue'] : (isset($a['even-header-value']) ? $a['even-header-value'] : 0));
2134 $ofvalue = (isset($a['ofvalue']) ? $a['ofvalue'] : (isset($a['odd-footer-value']) ? $a['odd-footer-value'] : 0));
2135 $efvalue = (isset($a['efvalue']) ? $a['efvalue'] : (isset($a['even-footer-value']) ? $a['even-footer-value'] : 0));
2136 $pagesel = (isset($a['pagesel']) ? $a['pagesel'] : (isset($a['pageselector']) ? $a['pageselector'] : ''));
2137 $newformat = (isset($a['newformat']) ? $a['newformat'] : (isset($a['sheet-size']) ? $a['sheet-size'] : ''));
2138
2139 $this->AddPage($orientation,$condition,$resetpagenum, $pagenumstyle, $suppress,$mgl,$mgr,$mgt,$mgb,$mgh,$mgf, $ohname, $ehname, $ofname, $efname, $ohvalue, $ehvalue, $ofvalue, $efvalue,$pagesel,$newformat);
2140
2141 }
2142
2143
2144
2145
2146 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='')
2147 {
2148 /*-- CSS-FLOAT --*/
2149 // Float DIV
2150 // Cannot do with columns on, or if any change in page orientation/margins etc.
2151 // If next page already exists - i.e background /headers and footers already written
2152 if ($this->state > 0 && $this->page < count($this->pages)) {
2153 $bak_cml = $this->cMarginL;
2154 $bak_cmr = $this->cMarginR;
2155 $bak_dw = $this->divwidth;
2156 // Paint Div Border if necessary
2157 if ($this->blklvl > 0) {
2158 $save_tr = $this->table_rotate; // *TABLES*
2159 $this->table_rotate = 0; // *TABLES*
2160 if ($this->y == $this->blk[$this->blklvl]['y0']) { $this->blk[$this->blklvl]['startpage']++; }
2161 if (($this->y > $this->blk[$this->blklvl]['y0']) || $this->flowingBlockAttr['is_table'] ) { $toplvl = $this->blklvl; }
2162 else { $toplvl = $this->blklvl-1; }
2163 $sy = $this->y;
2164 for ($bl=1;$bl<=$toplvl;$bl++) {
2165 $this->PaintDivBB('pagebottom',0,$bl);
2166 }
2167 $this->y = $sy;
2168 $this->table_rotate = $save_tr; // *TABLES*
2169 }
2170 $s = $this->PrintPageBackgrounds();
2171
2172 // Writes after the marker so not overwritten later by page background etc.
2173 $this->pages[$this->page] = preg_replace('/(___BACKGROUND___PATTERNS'.date('jY').')/', '\\1'."\n".$s."\n", $this->pages[$this->page]);
2174 $this->pageBackgrounds = array();
2175 $family=$this->FontFamily;
2176 $style=$this->FontStyle.($this->U ? 'U' : '').($this->S ? 'S' : '');
2177 $size=$this->FontSizePt;
2178 $lw=$this->LineWidth;
2179 $dc=$this->DrawColor;
2180 $fc=$this->FillColor;
2181 $tc=$this->TextColor;
2182 $cf=$this->ColorFlag;
2183
2184 $this->printfloatbuffer();
2185
2186 //Move to next page
2187 $this->page++;
2188 $this->ResetMargins();
2189 $this->SetAutoPageBreak($this->autoPageBreak,$this->bMargin);
2190 $this->x=$this->lMargin;
2191 $this->y=$this->tMargin;
2192 $this->FontFamily='';
2193 $this->_out('2 J');
2194 $this->LineWidth=$lw;
2195 $this->_out(sprintf('%.3F w',$lw*_MPDFK));
2196 if($family) $this->SetFont($family,$style,$size,true,true);
2197 $this->DrawColor=$dc;
2198 if($dc!=$this->defDrawColor) $this->_out($dc);
2199 $this->FillColor=$fc;
2200 if($fc!=$this->defFillColor) $this->_out($fc);
2201 $this->TextColor=$tc;
2202 $this->ColorFlag=$cf;
2203 for($bl=1;$bl<=$this->blklvl;$bl++) {
2204 $this->blk[$bl]['y0'] = $this->y;
2205 // Don't correct more than once for background DIV containing a Float
2206 if (!isset($this->blk[$bl]['marginCorrected'][$this->page])) { $this->blk[$bl]['x0'] += $this->MarginCorrection; }
2207 $this->blk[$bl]['marginCorrected'][$this->page] = true;
2208 }
2209 $this->cMarginL = $bak_cml;
2210 $this->cMarginR = $bak_cmr;
2211 $this->divwidth = $bak_dw;
2212 return '';
2213 }
2214 /*-- END CSS-FLOAT --*/
2215
2216 //Start a new page
2217 if($this->state==0) $this->Open();
2218
2219 $bak_cml = $this->cMarginL;
2220 $bak_cmr = $this->cMarginR;
2221 $bak_dw = $this->divwidth;
2222
2223
2224 $bak_lh = $this->lineheight;
2225
2226 $orientation = substr(strtoupper($orientation),0,1);
2227 $condition = strtoupper($condition);
2228
2229
2230 if ($condition == 'NEXT-EVEN') { // always adds at least one new page to create an Even page
2231 if (!$this->mirrorMargins) { $condition = ''; }
2232 else {
2233 if ($pagesel) { $pbch = $pagesel; $pagesel = ''; } // *CSS-PAGE*
2234 else { $pbch = false; } // *CSS-PAGE*
2235 $this->AddPage($this->CurOrientation,'O');
2236 if ($pbch ) { $pagesel = $pbch; } // *CSS-PAGE*
2237 $condition = '';
2238 }
2239 }
2240 if ($condition == 'NEXT-ODD') { // always adds at least one new page to create an Odd page
2241 if (!$this->mirrorMargins) { $condition = ''; }
2242 else {
2243 if ($pagesel) { $pbch = $pagesel; $pagesel = ''; } // *CSS-PAGE*
2244 else { $pbch = false; } // *CSS-PAGE*
2245 $this->AddPage($this->CurOrientation,'E');
2246 if ($pbch ) { $pagesel = $pbch; } // *CSS-PAGE*
2247 $condition = '';
2248 }
2249 }
2250
2251
2252 if ($condition == 'E') { // only adds new page if needed to create an Even page
2253 if (!$this->mirrorMargins || ($this->page)%2==0) { return false; }
2254 }
2255 if ($condition == 'O') { // only adds new page if needed to create an Odd page
2256 if (!$this->mirrorMargins || ($this->page)%2==1) { return false; }
2257 }
2258
2259 if ($resetpagenum || $pagenumstyle || $suppress) {
2260 $this->PageNumSubstitutions[] = array('from'=>($this->page+1), 'reset'=> $resetpagenum, 'type'=>$pagenumstyle, 'suppress'=>$suppress);
2261 }
2262
2263
2264 $save_tr = $this->table_rotate; // *TABLES*
2265 $this->table_rotate = 0; // *TABLES*
2266 $save_kwt = $this->kwt;
2267 $this->kwt = 0;
2268
2269 // Paint Div Border if necessary
2270 //PAINTS BACKGROUND COLOUR OR BORDERS for DIV - DISABLED FOR COLUMNS (cf. AcceptPageBreak) AT PRESENT in ->PaintDivBB
2271 if (!$this->ColActive && $this->blklvl > 0) {
2272 if (isset($this->blk[$this->blklvl]['y0']) && $this->y == $this->blk[$this->blklvl]['y0']) {
2273 if (isset($this->blk[$this->blklvl]['startpage'])) { $this->blk[$this->blklvl]['startpage']++; }
2274 else { $this->blk[$this->blklvl]['startpage'] = 1; }
2275 }
2276 if ((isset($this->blk[$this->blklvl]['y0']) && $this->y > $this->blk[$this->blklvl]['y0']) || $this->flowingBlockAttr['is_table'] ) { $toplvl = $this->blklvl; }
2277 else { $toplvl = $this->blklvl-1; }
2278 $sy = $this->y;
2279 for ($bl=1;$bl<=$toplvl;$bl++) {
2280 $this->PaintDivBB('pagebottom',0,$bl);
2281 }
2282 $this->y = $sy;
2283 // RESET block y0 and x0 - see below
2284 }
2285
2286 // BODY Backgrounds
2287 if ($this->page > 0) {
2288 $s = '';
2289 $s .= $this->PrintBodyBackgrounds();
2290
2291 $s .= $this->PrintPageBackgrounds();
2292 $this->pages[$this->page] = preg_replace('/(___BACKGROUND___PATTERNS'.date('jY').')/', "\n".$s."\n".'\\1', $this->pages[$this->page]);
2293 $this->pageBackgrounds = array();
2294 }
2295
2296 $save_kt = $this->keep_block_together;
2297 $this->keep_block_together = 0;
2298
2299 $save_cols = false;
2300 /*-- COLUMNS --*/
2301 if ($this->ColActive) {
2302 $save_cols = true;
2303 $save_nbcol = $this->NbCol; // other values of gap and vAlign will not change by setting Columns off
2304 $this->SetColumns(0);
2305 }
2306 /*-- END COLUMNS --*/
2307
2308 // mPDF 5.3.41
2309 $save_vis = $this->visibility;
2310 if($this->visibility!='visible')
2311 $this->SetVisibility('visible');
2312
2313 $family=$this->FontFamily;
2314 $style=$this->FontStyle.($this->U ? 'U' : '').($this->S ? 'S' : '');
2315 $size=$this->FontSizePt;
2316 $this->ColumnAdjust = true; // enables column height adjustment for the page
2317 $lw=$this->LineWidth;
2318 $dc=$this->DrawColor;
2319 $fc=$this->FillColor;
2320 $tc=$this->TextColor;
2321 $cf=$this->ColorFlag;
2322 if($this->page>0)
2323 {
2324 //Page footer
2325 $this->InFooter=true;
2326
2327 $this->Reset();
2328 $this->pageoutput[$this->page] = array();
2329
2330 $this->Footer();
2331 //Close page
2332 $this->_endpage();
2333 }
2334
2335
2336 //Start new page
2337 $this->_beginpage($orientation,$mgl,$mgr,$mgt,$mgb,$mgh,$mgf,$ohname,$ehname,$ofname,$efname,$ohvalue,$ehvalue,$ofvalue,$efvalue,$pagesel,$newformat);
2338 if ($this->docTemplate) {
2339 $pagecount = $this->SetSourceFile($this->docTemplate);
2340 if (($this->page - $this->docTemplateStart) > $pagecount) {
2341 if ($this->docTemplateContinue) {
2342 $tplIdx = $this->ImportPage($pagecount);
2343 $this->UseTemplate($tplIdx);
2344 }
2345 }
2346 else {
2347 $tplIdx = $this->ImportPage(($this->page - $this->docTemplateStart));
2348 $this->UseTemplate($tplIdx);
2349 }
2350 }
2351 if ($this->pageTemplate) {
2352 $this->UseTemplate($this->pageTemplate);
2353 }
2354
2355 // Tiling Patterns
2356 $this->_out('___PAGE___START'.date('jY'));
2357 $this->_out('___BACKGROUND___PATTERNS'.date('jY'));
2358 $this->_out('___HEADER___MARKER'.date('jY'));
2359 $this->pageBackgrounds = array();
2360
2361 //Set line cap style to square
2362 $this->SetLineCap(2);
2363 //Set line width
2364 $this->LineWidth=$lw;
2365 $this->_out(sprintf('%.3F w',$lw*_MPDFK));
2366 //Set font
2367 if($family) $this->SetFont($family,$style,$size,true,true); // forces write
2368 //Set colors
2369 $this->DrawColor=$dc;
2370 if($dc!=$this->defDrawColor) $this->_out($dc);
2371 $this->FillColor=$fc;
2372 if($fc!=$this->defFillColor) $this->_out($fc);
2373 $this->TextColor=$tc;
2374 $this->ColorFlag=$cf;
2375
2376 //Page header
2377 $this->Header();
2378
2379 //Restore line width
2380 if($this->LineWidth!=$lw)
2381 {
2382 $this->LineWidth=$lw;
2383 $this->_out(sprintf('%.3F w',$lw*_MPDFK));
2384 }
2385 //Restore font
2386 if($family) $this->SetFont($family,$style,$size,true,true); // forces write
2387 //Restore colors
2388 if($this->DrawColor!=$dc)
2389 {
2390 $this->DrawColor=$dc;
2391 $this->_out($dc);
2392 }
2393 if($this->FillColor!=$fc)
2394 {
2395 $this->FillColor=$fc;
2396 $this->_out($fc);
2397 }
2398 $this->TextColor=$tc;
2399 $this->ColorFlag=$cf;
2400 $this->InFooter=false;
2401
2402 // mPDF 5.3.41
2403 if($save_vis!='visible')
2404 $this->SetVisibility($save_vis);
2405
2406 /*-- COLUMNS --*/
2407 if ($save_cols) {
2408 // Restore columns
2409 $this->SetColumns($save_nbcol,$this->colvAlign,$this->ColGap);
2410 }
2411 if ($this->ColActive) { $this->SetCol(0); }
2412 /*-- END COLUMNS --*/
2413
2414
2415 //RESET BLOCK BORDER TOP
2416 if (!$this->ColActive) {
2417 for($bl=1;$bl<=$this->blklvl;$bl++) {
2418 $this->blk[$bl]['y0'] = $this->y;
2419 if (isset($this->blk[$bl]['x0'])) { $this->blk[$bl]['x0'] += $this->MarginCorrection; }
2420 else { $this->blk[$bl]['x0'] = $this->MarginCorrection; }
2421 // Added mPDF 3.0 Float DIV
2422 $this->blk[$bl]['marginCorrected'][$this->page] = true;
2423 }
2424 }
2425
2426
2427 $this->table_rotate = $save_tr; // *TABLES*
2428 $this->kwt = $save_kwt;
2429
2430 $this->keep_block_together = $save_kt ;
2431
2432 $this->cMarginL = $bak_cml;
2433 $this->cMarginR = $bak_cmr;
2434 $this->divwidth = $bak_dw;
2435
2436 $this->lineheight = $bak_lh;
2437 }
2438
2439
2440 function PageNo() {
2441 //Get current page number
2442 return $this->page;
2443 }
2444
2445 function AddSpotColorsFromFile($file) {
2446 $colors = @file($file) or die("Cannot load spot colors file - ".$file);
2447 foreach($colors AS $sc) {
2448 list($name, $c, $m, $y, $k) = preg_split("/\t/",$sc);
2449 $c = intval($c);
2450 $m = intval($m);
2451 $y = intval($y);
2452 $k = intval($k);
2453 $this->AddSpotColor($name, $c, $m, $y, $k);
2454 }
2455 }
2456
2457 function AddSpotColor($name, $c, $m, $y, $k) {
2458 $name = strtoupper(trim($name));
2459 if(!isset($this->spotColors[$name])) {
2460 $i=count($this->spotColors)+1;
2461 $this->spotColors[$name]=array('i'=>$i,'c'=>$c,'m'=>$m,'y'=>$y,'k'=>$k);
2462 $this->spotColorIDs[$i]=$name;
2463 }
2464 }
2465
2466 function SetColor($col, $type='') {
2467 $out = '';
2468 // mPDF 5.3.74
2469 if ($col{0}==3 || $col{0}==5) { // RGB / RGBa
2470 $out = sprintf('%.3F %.3F %.3F rg',ord($col{1})/255,ord($col{2})/255,ord($col{3})/255);
2471 }
2472 else if ($col{0}==1) { // GRAYSCALE
2473 $out = sprintf('%.3F g',ord($col{1})/255);
2474 }
2475 else if ($col{0}==2) { // SPOT COLOR
2476 $out = sprintf('/CS%d cs %.3F scn',ord($col{1}),ord($col{2})/100);
2477 }
2478 else if ($col{0}==4 || $col{0}==6) { // CMYK / CMYKa
2479 $out = sprintf('%.3F %.3F %.3F %.3F k', ord($col{1})/100, ord($col{2})/100, ord($col{3})/100, ord($col{4})/100);
2480 }
2481 if ($type=='Draw') { $out = strtoupper($out); } // e.g. rg => RG
2482 else if ($type=='CodeOnly') { $out = preg_replace('/\s(rg|g|k)/','',$out); }
2483 return $out;
2484 }
2485
2486
2487 function SetDColor($col, $return=false) {
2488 $out = $this->SetColor($col, 'Draw');
2489 if ($return) { return $out; }
2490 if ($out=='') { return ''; }
2491 $this->DrawColor = $out;
2492 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); }
2493 $this->pageoutput[$this->page]['DrawColor'] = $this->DrawColor;
2494 }
2495
2496 function SetFColor($col, $return=false) {
2497 $out = $this->SetColor($col, 'Fill');
2498 if ($return) { return $out; }
2499 if ($out=='') { return ''; }
2500 $this->FillColor = $out;
2501 $this->ColorFlag = ($out != $this->TextColor);
2502 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); }
2503 $this->pageoutput[$this->page]['FillColor'] = $this->FillColor;
2504 }
2505
2506 function SetTColor($col, $return=false) {
2507 $out = $this->SetColor($col, 'Text');
2508 if ($return) { return $out; }
2509 if ($out=='') { return ''; }
2510 $this->TextColor = $out;
2511 $this->ColorFlag = ($this->FillColor != $out);
2512 }
2513
2514
2515 function SetDrawColor($r,$g=-1,$b=-1,$col4=-1, $return=false) {
2516 //Set color for all stroking operations
2517 $col = array();
2518 if(($r==0 and $g==0 and $b==0 && $col4 == -1) or $g==-1) { $col = $this->ConvertColor($r); }
2519 else if ($col4 == -1) { $col = $this->ConvertColor('rgb('.$r.','.$g.','.$b.')'); }
2520 else { $col = $this->ConvertColor('cmyk('.$r.','.$g.','.$b.','.$col4.')'); }
2521 $out = $this->SetDColor($col, $return);
2522 return $out;
2523 }
2524
2525 function SetFillColor($r,$g=-1,$b=-1,$col4=-1, $return=false) {
2526 //Set color for all filling operations
2527 $col = array();
2528 if(($r==0 and $g==0 and $b==0 && $col4 == -1) or $g==-1) { $col = $this->ConvertColor($r); }
2529 else if ($col4 == -1) { $col = $this->ConvertColor('rgb('.$r.','.$g.','.$b.')'); }
2530 else { $col = $this->ConvertColor('cmyk('.$r.','.$g.','.$b.','.$col4.')'); }
2531 $out = $this->SetFColor($col, $return);
2532 return $out;
2533 }
2534
2535 function SetTextColor($r,$g=-1,$b=-1,$col4=-1, $return=false) {
2536 //Set color for text
2537 $col = array();
2538 if(($r==0 and $g==0 and $b==0 && $col4 == -1) or $g==-1) { $col = $this->ConvertColor($r); }
2539 else if ($col4 == -1) { $col = $this->ConvertColor('rgb('.$r.','.$g.','.$b.')'); }
2540 else { $col = $this->ConvertColor('cmyk('.$r.','.$g.','.$b.','.$col4.')'); }
2541 $out = $this->SetTColor($col, $return);
2542 return $out;
2543 }
2544
2545 function _getCharWidth(&$cw, $u, $isdef=true) {
2546 if ($u==0) { $w = false; }
2547 else { $w = (ord($cw[$u*2]) << 8) + ord($cw[$u*2+1]); }
2548 if ($w == 65535) { return 0; }
2549 else if ($w) { return $w; }
2550 else if ($isdef) { return false; }
2551 else { return 0; }
2552 }
2553
2554 function _charDefined(&$cw, $u) {
2555 if ($u==0) { return false; }
2556 $w = (ord($cw[$u*2]) << 8) + ord($cw[$u*2+1]);
2557 if ($w) { return true; }
2558 else { return false; }
2559 }
2560
2561 // mPDF 5.3.04
2562 function GetCharWidthCore($c) {
2563 //Get width of a single character in the current Core font
2564 $c = (string)$c;
2565 $w = 0;
2566 // Soft Hyphens chr(173)
2567 if ($c == chr(173) && $this->FontFamily!='csymbol' && $this->FontFamily!='czapfdingbats') {
2568 return 0; // mPDF 5.3.07
2569 }
2570 else if ($this->S && isset($this->upperCase[ord($c)])) {
2571 $charw = $this->CurrentFont['cw'][chr($this->upperCase[ord($c)])];
2572 if ($charw!==false) {
2573 $charw = $charw*$this->smCapsScale * $this->smCapsStretch/100;
2574 $w+=$charw;
2575 }
2576 }
2577 else if (isset($this->CurrentFont['cw'][$c])) {
2578 $w += $this->CurrentFont['cw'][$c];
2579 }
2580 else if (isset($this->CurrentFont['cw'][ord($c)])) {
2581 $w += $this->CurrentFont['cw'][ord($c)];
2582 }
2583 $w *= ($this->FontSize/ 1000);
2584 if ($this->minwSpacing || $this->fixedlSpacing) {
2585 if ($c==' ') $nb_spaces = 1;
2586 else $nb_spaces = 0;
2587 $w += $this->fixedlSpacing + ($nb_spaces * $this->minwSpacing);
2588 }
2589 return ($w);
2590 }
2591
2592 // mPDF 5.3.04
2593 function GetCharWidthNonCore($c, $addSubset=true) {
2594 //Get width of a single character in the current Non-Core font
2595 $c = (string)$c;
2596 $w = 0;
2597 $unicode = $this->UTF8StringToArray($c, $addSubset); // mPDF 5.3.06
2598 $char = $unicode[0];
2599 /*-- CJK-FONTS --*/
2600 if ($this->CurrentFont['type'] == 'Type0') { // CJK Adobe fonts
2601 if ($char == 173) { return 0; } // Soft Hyphens // mPDF 5.3.07
2602 elseif (isset($this->CurrentFont['cw'][$char])) { $w+=$this->CurrentFont['cw'][$char]; }
2603 elseif(isset($this->CurrentFont['MissingWidth'])) { $w += $this->CurrentFont['MissingWidth']; }
2604 else { $w += 500; }
2605 }
2606 else {
2607 /*-- END CJK-FONTS --*/
2608 if ($char == 173) { return 0; } // Soft Hyphens // mPDF 5.3.07
2609 else if ($this->S && isset($this->upperCase[$char])) {
2610 $charw = $this->_getCharWidth($this->CurrentFont['cw'],$this->upperCase[$char]);
2611 if ($charw!==false) {
2612 $charw = $charw*$this->smCapsScale * $this->smCapsStretch/100;
2613 $w+=$charw;
2614 }
2615 elseif(isset($this->CurrentFont['desc']['MissingWidth'])) { $w += $this->CurrentFont['desc']['MissingWidth']; }
2616 elseif(isset($this->CurrentFont['MissingWidth'])) { $w += $this->CurrentFont['MissingWidth']; }
2617 else { $w += 500; }
2618 }
2619 else {
2620 $charw = $this->_getCharWidth($this->CurrentFont['cw'],$char);
2621 if ($charw!==false) { $w+=$charw; }
2622 elseif(isset($this->CurrentFont['desc']['MissingWidth'])) { $w += $this->CurrentFont['desc']['MissingWidth']; }
2623 elseif(isset($this->CurrentFont['MissingWidth'])) { $w += $this->CurrentFont['MissingWidth']; }
2624 else { $w += 500; }
2625 }
2626 } // *CJK-FONTS*
2627 $w *= ($this->FontSize/ 1000);
2628 if ($this->minwSpacing || $this->fixedlSpacing) {
2629 if ($c==' ') $nb_spaces = 1;
2630 else $nb_spaces = 0;
2631 $w += $this->fixedlSpacing + ($nb_spaces * $this->minwSpacing);
2632 }
2633 return ($w);
2634 }
2635
2636
2637 // mPDF 5.3.04
2638 function GetCharWidth($c, $addSubset=true) {
2639 if (!$this->usingCoreFont) {
2640 return $this->GetCharWidthNonCore($c, $addSubset);
2641 }
2642 else {
2643 return $this->GetCharWidthCore($c);
2644 }
2645 }
2646
2647 function GetStringWidth($s, $addSubset=true) {
2648 //Get width of a string in the current font
2649 $s = (string)$s;
2650 $cw = &$this->CurrentFont['cw'];
2651 $w = 0;
2652 $kerning = 0;
2653 $lastchar = 0;
2654 // mPDF 5.3.04
2655 $nb_carac = 0;
2656 $nb_spaces = 0;
2657 // mPDF ITERATION
2658 if ($this->iterationCounter) $s = preg_replace('/{iteration ([a-zA-Z0-9_]+)}/', '\\1', $s);
2659
2660 if (!$this->usingCoreFont) {
2661 // mPDF 5.3.04
2662 $s = str_replace("\xc2\xad",'',$s );
2663 $unicode = $this->UTF8StringToArray($s, $addSubset);
2664 // mPDF 5.3.04
2665 if ($this->minwSpacing || $this->fixedlSpacing) {
2666 $nb_carac = count($unicode);
2667 $nb_spaces = mb_substr_count($s,' ', $this->mb_enc);
2668 }
2669 /*-- CJK-FONTS --*/
2670 if ($this->CurrentFont['type'] == 'Type0') { // CJK Adobe fonts
2671 foreach($unicode as $char) {
2672 if (isset($cw[$char])) { $w+=$cw[$char]; }
2673 elseif(isset($this->CurrentFont['MissingWidth'])) { $w += $this->CurrentFont['MissingWidth']; }
2674 else { $w += 500; }
2675 }
2676 }
2677 else {
2678 /*-- END CJK-FONTS --*/
2679 foreach($unicode as $char) {
2680 if ($this->S && isset($this->upperCase[$char])) {
2681 $charw = $this->_getCharWidth($cw,$this->upperCase[$char]);
2682 if ($charw!==false) {
2683 $charw = $charw*$this->smCapsScale * $this->smCapsStretch/100;
2684 $w+=$charw;
2685 }
2686 elseif(isset($this->CurrentFont['desc']['MissingWidth'])) { $w += $this->CurrentFont['desc']['MissingWidth']; }
2687 elseif(isset($this->CurrentFont['MissingWidth'])) { $w += $this->CurrentFont['MissingWidth']; }
2688 else { $w += 500; }
2689 }
2690 else {
2691 $charw = $this->_getCharWidth($cw,$char);
2692 if ($charw!==false) { $w+=$charw; }
2693 elseif(isset($this->CurrentFont['desc']['MissingWidth'])) { $w += $this->CurrentFont['desc']['MissingWidth']; }
2694 elseif(isset($this->CurrentFont['MissingWidth'])) { $w += $this->CurrentFont['MissingWidth']; }
2695 else { $w += 500; }
2696 if ($this->kerning && $this->useKerning && $lastchar) {
2697 if (isset($this->CurrentFont['kerninfo'][$lastchar][$char])) {
2698 $kerning += $this->CurrentFont['kerninfo'][$lastchar][$char];
2699 }
2700 }
2701 $lastchar = $char;
2702 }
2703 }
2704 } // *CJK-FONTS*
2705
2706 }
2707 else {
2708 // mPDF 5.3.04
2709 if ($this->FontFamily!='csymbol' && $this->FontFamily!='czapfdingbats') {
2710 $s = str_replace(chr(173),'',$s );
2711 }
2712 $nb_carac = $l = strlen($s);
2713 // mPDF 5.3.04
2714 if ($this->minwSpacing || $this->fixedlSpacing) {
2715 $nb_spaces = substr_count($s,' ');
2716 }
2717 for($i=0; $i<$l; $i++) {
2718 if ($this->S && isset($this->upperCase[ord($s[$i])])) {
2719 $charw = $cw[chr($this->upperCase[ord($s[$i])])];
2720 if ($charw!==false) {
2721 $charw = $charw*$this->smCapsScale * $this->smCapsStretch/100;
2722 $w+=$charw;
2723 }
2724 }
2725 else if (isset($cw[$s[$i]])) {
2726 $w += $cw[$s[$i]];
2727 }
2728 else if (isset($cw[ord($s[$i])])) {
2729 $w += $cw[ord($s[$i])];
2730 }
2731 if ($this->kerning && $this->useKerning && $i>0) { // mPDF 5.3.04
2732 if (isset($this->CurrentFont['kerninfo'][$s[($i-1)]][$s[$i]])) {
2733 $kerning += $this->CurrentFont['kerninfo'][$s[($i-1)]][$s[$i]];
2734 }
2735 }
2736 }
2737 }
2738 unset($cw);
2739 if ($this->kerning && $this->useKerning) { $w += $kerning; }
2740 $w *= ($this->FontSize/ 1000);
2741 // mPDF 5.3.04
2742 $w += (($nb_carac + $nb_spaces) * $this->fixedlSpacing) + ($nb_spaces * $this->minwSpacing);
2743 return ($w);
2744 }
2745
2746 function SetLineWidth($width) {
2747 //Set line width
2748 $this->LineWidth=$width;
2749 $lwout = (sprintf('%.3F w',$width*_MPDFK));
2750 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)) {
2751 $this->_out($lwout);
2752 }
2753 $this->pageoutput[$this->page]['LineWidth'] = $lwout;
2754 }
2755
2756 function Line($x1,$y1,$x2,$y2) {
2757 //Draw a line
2758 $this->_out(sprintf('%.3F %.3F m %.3F %.3F l S',$x1*_MPDFK,($this->h-$y1)*_MPDFK,$x2*_MPDFK,($this->h-$y2)*_MPDFK));
2759 }
2760
2761 function Arrow($x1,$y1,$x2,$y2,$headsize=3,$fill='B',$angle=25) {
2762 //F == fill //S == stroke //B == stroke and fill
2763 // angle = splay of arrowhead - 1 - 89 degrees
2764 if($fill=='F') $fill='f';
2765 elseif($fill=='FD' or $fill=='DF' or $fill=='B') $fill='B';
2766 else $fill='S';
2767 $a = atan2(($y2-$y1),($x2-$x1));
2768 $b = $a + deg2rad($angle);
2769 $c = $a - deg2rad($angle);
2770 $x3 = $x2 - ($headsize* cos($b));
2771 $y3 = $this->h-($y2 - ($headsize* sin($b)));
2772 $x4 = $x2 - ($headsize* cos($c));
2773 $y4 = $this->h-($y2 - ($headsize* sin($c)));
2774
2775 $x5 = $x3-($x3-$x4)/2; // mid point of base of arrowhead - to join arrow line to
2776 $y5 = $y3-($y3-$y4)/2;
2777
2778 $s = '';
2779 $s.=sprintf('%.3F %.3F m %.3F %.3F l S',$x1*_MPDFK,($this->h-$y1)*_MPDFK,$x5*_MPDFK,$y5*_MPDFK);
2780 $this->_out($s);
2781
2782 $s = '';
2783 $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);
2784 $s.=$fill;
2785 $this->_out($s);
2786 }
2787
2788
2789 function Rect($x,$y,$w,$h,$style='') {
2790 //Draw a rectangle
2791 if($style=='F') $op='f';
2792 elseif($style=='FD' or $style=='DF') $op='B';
2793 else $op='S';
2794 $this->_out(sprintf('%.3F %.3F %.3F %.3F re %s',$x*_MPDFK,($this->h-$y)*_MPDFK,$w*_MPDFK,-$h*_MPDFK,$op));
2795 }
2796
2797 function AddFont($family,$style='') {
2798 if(empty($family)) { return; }
2799 $family = strtolower($family);
2800 $style=strtoupper($style);
2801 $style=str_replace('U','',$style);
2802 if($style=='IB') $style='BI';
2803 $fontkey = $family.$style;
2804 // check if the font has been already added
2805 if(isset($this->fonts[$fontkey])) {
2806 return;
2807 }
2808
2809 /*-- CJK-FONTS --*/
2810 if (in_array($family,$this->available_CJK_fonts)) {
2811 if (empty($this->Big5_widths)) { require(_MPDF_PATH . 'includes/CJKdata.php'); }
2812 $this->AddCJKFont($family); // don't need to add style
2813 return;
2814 }
2815 /*-- END CJK-FONTS --*/
2816
2817 if ($this->usingCoreFont) { die("mPDF Error - problem with Font management"); }
2818
2819 $stylekey = $style;
2820 if (!$style) { $stylekey = 'R'; }
2821
2822 if (!isset($this->fontdata[$family][$stylekey]) || !$this->fontdata[$family][$stylekey]) {
2823 die('mPDF Error - Font is not supported - '.$family.' '.$style);
2824 }
2825
2826 $name = '';
2827 $originalsize = 0;
2828 $sip = false;
2829 $smp = false;
2830 $haskerninfo = false;
2831 $BMPselected = false;
2832 @include(_MPDF_TTFONTDATAPATH.$fontkey.'.mtx.php');
2833
2834 $ttffile = '';
2835 if (defined('_MPDF_SYSTEM_TTFONTS')) {
2836 $ttffile = _MPDF_SYSTEM_TTFONTS.$this->fontdata[$family][$stylekey];
2837 if (!file_exists($ttffile)) { $ttffile = ''; }
2838 }
2839 if (!$ttffile) {
2840 $ttffile = _MPDF_TTFONTPATH.$this->fontdata[$family][$stylekey];
2841 if (!file_exists($ttffile)) { die("mPDF Error - cannot find TTF TrueType font file - ".$ttffile); }
2842 }
2843 $ttfstat = stat($ttffile);
2844
2845 if (isset($this->fontdata[$family]['TTCfontID'][$stylekey])) { $TTCfontID = $this->fontdata[$family]['TTCfontID'][$stylekey]; }
2846 else { $TTCfontID = 0; }
2847
2848
2849 $BMPonly = false;
2850 if (in_array($family,$this->BMPonly)) { $BMPonly = true; }
2851 $regenerate = false;
2852 if ($BMPonly && !$BMPselected) { $regenerate = true; }
2853 else if (!$BMPonly && $BMPselected) { $regenerate = true; }
2854 if ($this->useKerning && !$haskerninfo) { $regenerate = true; }
2855
2856 if (!isset($name) || $originalsize != $ttfstat['size'] || $regenerate) {
2857 $mqr=$this->_getMQR();
2858 if ($mqr) { set_magic_quotes_runtime(0); }
2859 if (!class_exists('TTFontFile', false)) { include(_MPDF_PATH .'classes/ttfontsuni.php'); }
2860 $ttf = new TTFontFile();
2861 $ttf->getMetrics($ttffile, $TTCfontID, $this->debugfonts, $BMPonly, $this->useKerning);
2862 $cw = $ttf->charWidths;
2863 $kerninfo = $ttf->kerninfo;
2864 $haskerninfo = true;
2865 $name = preg_replace('/[ ()]/','',$ttf->fullName);
2866 $sip = $ttf->sipset;
2867 $smp = $ttf->smpset;
2868
2869 $desc= array('Ascent'=>round($ttf->ascent),
2870 'Descent'=>round($ttf->descent),
2871 'CapHeight'=>round($ttf->capHeight),
2872 'Flags'=>$ttf->flags,
2873 'FontBBox'=>'['.round($ttf->bbox[0])." ".round($ttf->bbox[1])." ".round($ttf->bbox[2])." ".round($ttf->bbox[3]).']',
2874 'ItalicAngle'=>$ttf->italicAngle,
2875 'StemV'=>round($ttf->stemV),
2876 'MissingWidth'=>round($ttf->defaultWidth));
2877 $panose = '';
2878 if (count($ttf->panose)) { $panose = $ttf->sFamilyClass.' '.$ttf->sFamilySubClass.' '.implode(' ',$ttf->panose); }
2879 $up = round($ttf->underlinePosition);
2880 $ut = round($ttf->underlineThickness);
2881 $originalsize = $ttfstat['size']+0;
2882 $type = 'TTF';
2883 //Generate metrics .php file
2884 $s='<?php'."\n";
2885 $s.='$name=\''.$name."';\n";
2886 $s.='$type=\''.$type."';\n";
2887 $s.='$desc='.var_export($desc,true).";\n";
2888 $s.='$up='.$up.";\n";
2889 $s.='$ut='.$ut.";\n";
2890 $s.='$ttffile=\''.$ttffile."';\n";
2891 $s.='$TTCfontID=\''.$TTCfontID."';\n";
2892 $s.='$originalsize='.$originalsize.";\n";
2893 if ($sip) $s.='$sip=true;'."\n";
2894 else $s.='$sip=false;'."\n";
2895 if ($smp) $s.='$smp=true;'."\n";
2896 else $s.='$smp=false;'."\n";
2897 if ($BMPonly) $s.='$BMPselected=true;'."\n";
2898 else $s.='$BMPselected=false;'."\n";
2899 $s.='$fontkey=\''.$fontkey."';\n";
2900 $s.='$panose=\''.$panose."';\n";
2901 if ($this->useKerning) {
2902 $s.='$kerninfo='.var_export($kerninfo,true).";\n";
2903 $s.='$haskerninfo=true;'."\n";
2904 }
2905 else $s.='$haskerninfo=false;'."\n";
2906 $s.="?>";
2907 if (is_writable(dirname(_MPDF_TTFONTDATAPATH.'x'))) {
2908 $fh = fopen(_MPDF_TTFONTDATAPATH.$fontkey.'.mtx.php',"w");
2909 fwrite($fh,$s,strlen($s));
2910 fclose($fh);
2911 $fh = fopen(_MPDF_TTFONTDATAPATH.$fontkey.'.cw.dat',"wb");
2912 fwrite($fh,$cw,strlen($cw));
2913 fclose($fh);
2914 @unlink(_MPDF_TTFONTDATAPATH.$fontkey.'.cgm');
2915 @unlink(_MPDF_TTFONTDATAPATH.$fontkey.'.z');
2916 @unlink(_MPDF_TTFONTDATAPATH.$fontkey.'.cw127.php');
2917 @unlink(_MPDF_TTFONTDATAPATH.$fontkey.'.cw');
2918 }
2919 else if ($this->debugfonts) { $this->Error('Cannot write to the font caching directory - '._MPDF_TTFONTDATAPATH); }
2920 unset($ttf);
2921 if ($mqr) { set_magic_quotes_runtime($mqr); }
2922 }
2923 else {
2924 $cw = @file_get_contents(_MPDF_TTFONTDATAPATH.$fontkey.'.cw.dat');
2925 }
2926
2927 if (isset($this->fontdata[$family]['indic']) && $this->fontdata[$family]['indic']) { $indic = true; }
2928 else { $indic = false; }
2929 if (isset($this->fontdata[$family]['sip-ext']) && $this->fontdata[$family]['sip-ext']) { $sipext = $this->fontdata[$family]['sip-ext']; }
2930 else { $sipext = ''; }
2931
2932
2933 $i = count($this->fonts)+$this->extraFontSubsets+1;
2934 if ($sip || $smp) {
2935 $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);
2936 }
2937 else {
2938 // mPDF 5.3.31
2939 $ss = array();
2940 for ($s=32; $s<128; $s++) { $ss[$s] = $s; }
2941 $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);
2942 }
2943 if ($this->useKerning && $haskerninfo) { $this->fonts[$fontkey]['kerninfo'] = $kerninfo; }
2944 $this->FontFiles[$fontkey]=array('length1'=>$originalsize, 'type'=>"TTF", 'ttffile'=>$ttffile, 'sip'=>$sip, 'smp'=>$smp);
2945 unset($cw);
2946 }
2947
2948
2949
2950 function SetFont($family,$style='',$size=0, $write=true, $forcewrite=false) {
2951 $family=strtolower($family);
2952 // mPDF 5.3.22
2953 if (!$this->onlyCoreFonts) {
2954 if ($family == 'sans' || $family == 'sans-serif') { $family = $this->sans_fonts[0]; }
2955 if ($family == 'serif') { $family = $this->serif_fonts[0]; }
2956 if ($family == 'mono' || $family == 'monospace') { $family = $this->mono_fonts[0]; }
2957 }
2958 // mPDF 5.3.22
2959 if (isset($this->fonttrans[$family]) && $this->fonttrans[$family]) { $family = $this->fonttrans[$family]; }
2960 if($family=='') {
2961 if ($this->FontFamily) { $family=$this->FontFamily; }
2962 else if ($this->default_font) { $family=$this->default_font; }
2963 else { $this->Error("No font or default font set!"); }
2964 }
2965 $this->ReqFontStyle = $style; // required or requested style - used later for artificial bold/italic
2966
2967 if (($family == 'csymbol') || ($family == 'czapfdingbats') || ($family == 'ctimes') || ($family == 'ccourier') || ($family == 'chelvetica')) {
2968 if ($this->PDFA || $this->PDFX) {
2969 if ($family == 'csymbol' || $family == 'czapfdingbats') {
2970 $this->Error("Symbol and Zapfdingbats cannot be embedded in mPDF (required for PDFA1-b or PDFX/1-a).");
2971 }
2972 if ($family == 'ctimes' || $family == 'ccourier' || $family == 'chelvetica') {
2973 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.)"; }
2974 if ($family == 'chelvetica') { $family = 'sans'; }
2975 if ($family == 'ctimes') { $family = 'serif'; }
2976 if ($family == 'ccourier') { $family = 'mono'; }
2977 }
2978 $this->usingCoreFont = false;
2979 }
2980 else { $this->usingCoreFont = true; }
2981 if($family=='csymbol' || $family=='czapfdingbats') { $style=''; } // mPDF 5.3.05
2982 }
2983 else { $this->usingCoreFont = false; }
2984
2985 // mPDF 5.3.05
2986 $this->U=false;
2987 $this->S=false;
2988 if ($style) {
2989 $style=strtoupper($style);
2990 if(strpos($style,'U')!==false) {
2991 $this->U=true;
2992 $style=str_replace('U','',$style);
2993 }
2994 if(strpos($style,'S')!==false) {
2995 $this->S=true;
2996 // Small Caps
2997 if (empty($this->upperCase)) { @include(_MPDF_PATH.'includes/upperCase.php'); } // mPDF 5.3.99
2998 $style=str_replace('S','',$style);
2999 }
3000 if ($style=='IB') $style='BI';
3001 }
3002 if ($size==0) $size=$this->FontSizePt;
3003
3004 $fontkey=$family.$style;
3005
3006 $stylekey = $style;
3007 if (!$stylekey) { $stylekey = "R"; }
3008
3009 if (!$this->onlyCoreFonts && !$this->usingCoreFont) {
3010 // mPDF 5.3.05
3011 if(!isset($this->fonts[$fontkey]) || count($this->default_available_fonts) != count($this->available_unifonts) ) { // not already added
3012 /*-- CJK-FONTS --*/
3013 // CJK fonts
3014 if (in_array($fontkey,$this->available_CJK_fonts)) {
3015 if(!isset($this->fonts[$fontkey])) { // already added
3016 if (empty($this->Big5_widths)) { require(_MPDF_PATH . 'includes/CJKdata.php'); }
3017 $this->AddCJKFont($family); // don't need to add style
3018 }
3019 }
3020 // Test to see if requested font/style is available - or substitute
3021 else
3022 /*-- END CJK-FONTS --*/
3023 if (!in_array($fontkey,$this->available_unifonts)) {
3024 // If font[nostyle] exists - set it
3025 if (in_array($family,$this->available_unifonts)) {
3026 $style = '';
3027 }
3028
3029 // Else if only one font available - set it (assumes if only one font available it will not have a style)
3030 else if (count($this->available_unifonts) == 1) {
3031 $family = $this->available_unifonts[0];
3032 $style = '';
3033 }
3034
3035 else {
3036 $found = 0;
3037 // else substitute font of similar type
3038 if (in_array($family,$this->sans_fonts)) {
3039 $i = array_intersect($this->sans_fonts,$this->available_unifonts);
3040 if (count($i)) {
3041 $i = array_values($i);
3042 // with requested style if possible
3043 if (!in_array(($i[0].$style),$this->available_unifonts)) {
3044 $style = '';
3045 }
3046 $family = $i[0];
3047 $found = 1;
3048 }
3049 }
3050 else if (in_array($family,$this->serif_fonts)) {
3051 $i = array_intersect($this->serif_fonts,$this->available_unifonts);
3052 if (count($i)) {
3053 $i = array_values($i);
3054 // with requested style if possible
3055 if (!in_array(($i[0].$style),$this->available_unifonts)) {
3056 $style = '';
3057 }
3058 $family = $i[0];
3059 $found = 1;
3060 }
3061 }
3062 else if (in_array($family,$this->mono_fonts)) {
3063 $i = array_intersect($this->mono_fonts,$this->available_unifonts);
3064 if (count($i)) {
3065 $i = array_values($i);
3066 // with requested style if possible
3067 if (!in_array(($i[0].$style),$this->available_unifonts)) {
3068 $style = '';
3069 }
3070 $family = $i[0];
3071 $found = 1;
3072 }
3073 }
3074
3075 if (!$found) {
3076 // set first available font
3077 $fs = $this->available_unifonts[0];
3078 preg_match('/^([a-z_0-9\-]+)([BI]{0,2})$/',$fs,$fas); // Allow "-"
3079 // with requested style if possible
3080 $ws = $fas[1].$style;
3081 if (in_array($ws,$this->available_unifonts)) {
3082 $family = $fas[1]; // leave $style as is
3083 }
3084 else if (in_array($fas[1],$this->available_unifonts)) {
3085 // or without style
3086 $family = $fas[1];
3087 $style = '';
3088 }
3089 else {
3090 // or with the style specified
3091 $family = $fas[1];
3092 $style = $fas[2];
3093 }
3094 }
3095 }
3096 $fontkey = $family.$style;
3097 }
3098 }
3099 // try to add font (if not already added)
3100 $this->AddFont($family, $style);
3101
3102 //Test if font is already selected
3103 if($this->FontFamily == $family && $this->FontFamily == $this->currentfontfamily && $this->FontStyle == $style && $this->FontStyle == $this->currentfontstyle && $this->FontSizePt == $size && $this->FontSizePt == $this->currentfontsize && !$forcewrite) {
3104 return $family;
3105 }
3106
3107 $fontkey = $family.$style;
3108
3109 //Select it
3110 $this->FontFamily = $family;
3111 $this->FontStyle = $style;
3112 $this->FontSizePt = $size;
3113 $this->FontSize = $size / _MPDFK;
3114 $this->CurrentFont = &$this->fonts[$fontkey];
3115 if ($write) {
3116 $fontout = (sprintf('BT /F%d %.3F Tf ET', $this->CurrentFont['i'], $this->FontSizePt));
3117 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); }
3118 $this->pageoutput[$this->page]['Font'] = $fontout;
3119 }
3120
3121
3122
3123 // Added - currentfont (lowercase) used in HTML2PDF
3124 $this->currentfontfamily=$family;
3125 $this->currentfontsize=$size;
3126 $this->currentfontstyle=$style.($this->U ? 'U' : '').($this->S ? 'S' : '');
3127 $this->setMBencoding('UTF-8');
3128 }
3129
3130 else { // if using core fonts
3131
3132
3133 if ($this->PDFA || $this->PDFX) {
3134 $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.');
3135 }
3136 $this->setMBencoding('windows-1252');
3137
3138 //Test if font is already selected
3139 if(($this->FontFamily == $family) AND ($this->FontStyle == $style) AND ($this->FontSizePt == $size) && !$forcewrite) {
3140 return $family;
3141 }
3142
3143 if (!isset($this->CoreFonts[$fontkey])) {
3144 if (in_array($family,$this->serif_fonts)) { $family = 'ctimes'; }
3145 else if (in_array($family,$this->mono_fonts)) { $family = 'ccourier'; }
3146 else { $family = 'chelvetica'; }
3147 $this->usingCoreFont = true;
3148 $fontkey = $family.$style;
3149 }
3150
3151 if(!isset($this->fonts[$fontkey])) {
3152 // STANDARD CORE FONTS
3153 if (isset($this->CoreFonts[$fontkey])) {
3154 //Load metric file
3155 $file=$family;
3156 if($family=='ctimes' || $family=='chelvetica' || $family=='ccourier') { $file.=strtolower($style); }
3157 $file.='.php';
3158 include(_MPDF_PATH.'font/'.$file);
3159 if(!isset($cw)) { $this->Error('Could not include font metric file'); }
3160 $i=count($this->fonts)+$this->extraFontSubsets+1;
3161 $this->fonts[$fontkey]=array('i'=>$i,'type'=>'core','name'=>$this->CoreFonts[$fontkey],'desc'=>$desc,'up'=>$up,'ut'=>$ut,'cw'=>$cw);
3162 if ($this->useKerning) { $this->fonts[$fontkey]['kerninfo'] = $kerninfo; }
3163 }
3164 else {
3165 die('mPDF error - Font not defined');
3166 }
3167 }
3168 //Test if font is already selected
3169 if(($this->FontFamily == $family) AND ($this->FontStyle == $style) AND ($this->FontSizePt == $size) && !$forcewrite) {
3170 return $family;
3171 }
3172 //Select it
3173 $this->FontFamily=$family;
3174 $this->FontStyle=$style;
3175 $this->FontSizePt=$size;
3176 $this->FontSize=$size/_MPDFK;
3177 $this->CurrentFont=&$this->fonts[$fontkey];
3178 if ($write) {
3179 $fontout = (sprintf('BT /F%d %.3F Tf ET', $this->CurrentFont['i'], $this->FontSizePt));
3180 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); }
3181 $this->pageoutput[$this->page]['Font'] = $fontout;
3182 }
3183 // Added - currentfont (lowercase) used in HTML2PDF
3184 $this->currentfontfamily=$family;
3185 $this->currentfontsize=$size;
3186 $this->currentfontstyle=$style.($this->U ? 'U' : '').($this->S ? 'S' : '');
3187
3188 }
3189
3190 return $family;
3191 }
3192
3193 function SetFontSize($size,$write=true) {
3194 //Set font size in points
3195 if($this->FontSizePt==$size) return;
3196 $this->FontSizePt=$size;
3197 $this->FontSize=$size/_MPDFK;
3198 $this->currentfontsize=$size;
3199 if ($write) {
3200 $fontout = (sprintf('BT /F%d %.3F Tf ET', $this->CurrentFont['i'], $this->FontSizePt));
3201 // Edited mPDF 3.0
3202 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); }
3203 $this->pageoutput[$this->page]['Font'] = $fontout;
3204 }
3205 }
3206
3207 function AddLink() {
3208 //Create a new internal link
3209 $n=count($this->links)+1;
3210 $this->links[$n]=array(0,0);
3211 return $n;
3212 }
3213
3214 function SetLink($link,$y=0,$page=-1) {
3215 //Set destination of internal link
3216 if($y==-1) $y=$this->y;
3217 if($page==-1) $page=$this->page;
3218 $this->links[$link]=array($page,$y);
3219 }
3220
3221 function Link($x,$y,$w,$h,$link) {
3222 $l = array($x*_MPDFK,$this->hPt-$y*_MPDFK,$w*_MPDFK,$h*_MPDFK,$link);
3223 if ($this->keep_block_together) { // Save to array - don't write yet
3224 $this->ktLinks[$this->page][]= $l;
3225 return;
3226 }
3227 else if ($this->table_rotate) { // *TABLES*
3228 $this->tbrot_Links[$this->page][]= $l; // *TABLES*
3229 return; // *TABLES*
3230 } // *TABLES*
3231 else if ($this->kwt) {
3232 $this->kwt_Links[$this->page][]= $l;
3233 return;
3234 }
3235
3236 if ($this->writingHTMLheader || $this->writingHTMLfooter) {
3237 $this->HTMLheaderPageLinks[]= $l;
3238 return;
3239 }
3240 //Put a link on the page
3241 $this->PageLinks[$this->page][]= $l;
3242 // Save cross-reference to Column buffer
3243 $ref = count($this->PageLinks[$this->page])-1; // *COLUMNS*
3244 $this->columnLinks[$this->CurrCol][INTVAL($this->x)][INTVAL($this->y)] = $ref; // *COLUMNS*
3245
3246 }
3247
3248 function Text($x,$y,$txt) {
3249 // Output a string
3250 // Called (internally) by Watermark and _tableWrite [rotated cells]
3251 // Expects input to be mb_encoded if necessary and RTL reversed
3252
3253 // ARTIFICIAL BOLD AND ITALIC
3254 $s = 'q ';
3255 if ($this->falseBoldWeight && strpos($this->ReqFontStyle,"B") !== false && strpos($this->FontStyle,"B") === false) {
3256 $s .= '2 Tr 1 J 1 j ';
3257 $s .= sprintf('%.3F w ',($this->FontSize/130)*_MPDFK*$this->falseBoldWeight);
3258 $tc = strtoupper($this->TextColor); // change 0 0 0 rg to 0 0 0 RG
3259 if($this->FillColor!=$tc) { $s .= $tc.' '; } // stroke (outline) = same colour as text(fill)
3260 }
3261 if (strpos($this->ReqFontStyle,"I") !== false && strpos($this->FontStyle,"I") === false) {
3262 $aix = '1 0 0.261799 1 %.3F %.3F Tm';
3263 }
3264 else { $aix = '%.3F %.3F Td'; }
3265
3266 if($this->ColorFlag) $s.=$this->TextColor.' ';
3267
3268 $this->CurrentFont['used']= true;
3269 if ($this->CurrentFont['type']=='TTF' && ($this->CurrentFont['sip'] || $this->CurrentFont['smp'])) {
3270 $txt2 = str_replace(chr(194).chr(160),chr(32),$txt);
3271 $txt2 = $this->UTF8toSubset($txt2);
3272 $s.=sprintf('BT '.$aix.' %s Tj ET ',$x*_MPDFK,($this->h-$y)*_MPDFK,$txt2);
3273 }
3274 else if (!$this->usingCoreFont) { // mPDF 5.3.22
3275 $txt2 = str_replace(chr(194).chr(160),chr(32),$txt);
3276 $this->UTF8StringToArray($txt2); // this is just to add chars to subset list
3277 if ($this->kerning && $this->useKerning) { $s .= $this->_kern($txt2, '', $aix, $x, $y); }
3278 else {
3279 //Convert string to UTF-16BE without BOM
3280 $txt2= $this->UTF8ToUTF16BE($txt2, false);
3281 $s.=sprintf('BT '.$aix.' (%s) Tj ET ',$x*_MPDFK,($this->h-$y)*_MPDFK,$this->_escape($txt2));
3282 }
3283 }
3284 else {
3285 $txt2 = str_replace(chr(160),chr(32),$txt);
3286 if ($this->kerning && $this->useKerning) { $s .= $this->_kern($txt2, '', $aix, $x, $y); }
3287 else {
3288 $s.=sprintf('BT '.$aix.' (%s) Tj ET ',$x*_MPDFK,($this->h-$y)*_MPDFK,$this->_escape($txt2));
3289 }
3290 }
3291 if($this->U && $txt!='') {
3292 // mPDF 5.3.34
3293 $c = strtoupper($this->TextColor); // change 0 0 0 rg to 0 0 0 RG
3294 if($this->FillColor!=$c) { $s.= ' '.$c.' '; }
3295 if (isset($this->CurrentFont['up'])) { $up=$this->CurrentFont['up']; }
3296 else { $up = -100; }
3297 $adjusty = (-$up/1000* $this->FontSize);
3298 if (isset($this->CurrentFont['ut'])) { $ut=$this->CurrentFont['ut']/1000* $this->FontSize; }
3299 else { $ut = 60/1000* $this->FontSize; }
3300 $olw = $this->LineWidth;
3301 $s.=' '.(sprintf(' %.3F w',$ut*_MPDFK));
3302 $s.=' '.$this->_dounderline($x,$y + $adjusty,$txt);
3303 $s.=' '.(sprintf(' %.3F w',$olw*_MPDFK));
3304 if($this->FillColor!=$c) { $s.= ' '.$this->FillColor.' '; }
3305 }
3306 // STRIKETHROUGH // mPDF 5.3.54
3307 if($this->strike && $txt!='') {
3308 $c = strtoupper($this->TextColor); // change 0 0 0 rg to 0 0 0 RG
3309 if($this->FillColor!=$c) { $s.= ' '.$c.' '; }
3310 //Superscript and Subscript Y coordinate adjustment (now for striked-through texts)
3311 if (isset($this->CurrentFont['desc']['CapHeight'])) { $ch=$this->CurrentFont['desc']['CapHeight']; }
3312 else { $ch = 700; }
3313 $adjusty = (-$ch/1000* $this->FontSize) * 0.35;
3314 if (isset($this->CurrentFont['ut'])) { $ut=$this->CurrentFont['ut']/1000* $this->FontSize; }
3315 else { $ut = 60/1000* $this->FontSize; }
3316 $olw = $this->LineWidth;
3317 $s.=' '.(sprintf(' %.3F w',$ut*_MPDFK));
3318 $s.=' '.$this->_dounderline($x,$y+$adjusty,$txt);
3319 $s.=' '.(sprintf(' %.3F w',$olw*_MPDFK));
3320 if($this->FillColor!=$c) { $s.= ' '.$this->FillColor.' '; }
3321 }
3322 $s .= 'Q';
3323 $this->_out($s);
3324 }
3325
3326 /*-- DIRECTW --*/
3327 function WriteText($x,$y,$txt) {
3328 // Output a string using Text() but does encoding and text reversing of RTL
3329 $txt = $this->purify_utf8_text($txt);
3330 if ($this->text_input_as_HTML) {
3331 $txt = $this->all_entities_to_utf8($txt);
3332 }
3333 if ($this->usingCoreFont) { $txt = mb_convert_encoding($txt,$this->mb_enc,'UTF-8'); } // mPDF 5.3.22
3334 // DIRECTIONALITY
3335 if (preg_match("/([".$this->pregRTLchars."])/u", $txt)) { $this->biDirectional = true; } // *RTL*
3336 $this->magic_reverse_dir($txt, true, $this->directionality); // *RTL*
3337 // Font-specific ligature substitution for Indic fonts
3338 if (isset($this->CurrentFont['indic']) && $this->CurrentFont['indic']) $this->ConvertIndic($txt); // *INDIC*
3339 $this->Text($x,$y,$txt);
3340 }
3341
3342 function WriteCell($w,$h=0,$txt='',$border=0,$ln=0,$align='',$fill=0,$link='', $currentx=0) {
3343 //Output a cell using Cell() but does encoding and text reversing of RTL
3344 $txt = $this->purify_utf8_text($txt);
3345 if ($this->text_input_as_HTML) {
3346 $txt = $this->all_entities_to_utf8($txt);
3347 }
3348 if ($this->usingCoreFont) { $txt = mb_convert_encoding($txt,$this->mb_enc,'UTF-8'); } // mPDF 5.3.07 // mPDF 5.3.22
3349 // DIRECTIONALITY
3350 if (preg_match("/([".$this->pregRTLchars."])/u", $txt)) { $this->biDirectional = true; } // *RTL*
3351 $this->magic_reverse_dir($txt, true, $this->directionality); // *RTL*
3352 // Font-specific ligature substitution for Indic fonts
3353 if (isset($this->CurrentFont['indic']) && $this->CurrentFont['indic']) $this->ConvertIndic($txt); // *INDIC*
3354 $this->Cell($w,$h,$txt,$border,$ln,$align,$fill,$link, $currentx);
3355 }
3356 /*-- END DIRECTW --*/
3357
3358
3359 function ResetSpacing() {
3360 if ($this->ws != 0) { $this->_out('BT 0 Tw ET'); }
3361 $this->ws=0;
3362 if ($this->charspacing != 0) { $this->_out('BT 0 Tc ET'); }
3363 $this->charspacing=0;
3364 }
3365
3366
3367 function SetSpacing($cs,$ws) {
3368 if (intval($cs*1000)==0) { $cs = 0; }
3369 if ($cs) { $this->_out(sprintf('BT %.3F Tc ET',$cs)); }
3370 else if ($this->charspacing != 0) { $this->_out('BT 0 Tc ET'); }
3371 $this->charspacing=$cs;
3372 if (intval($ws*1000)==0) { $ws = 0; }
3373 if ($ws) { $this->_out(sprintf('BT %.3F Tw ET',$ws)); }
3374 else if ($this->ws != 0) { $this->_out('BT 0 Tw ET'); }
3375 $this->ws=$ws;
3376 }
3377
3378 // WORD SPACING
3379 function GetJspacing($nc,$ns,$w,$inclCursive) {
3380 $ws = 0;
3381 $charspacing = 0;
3382 $ww = $this->jSWord;
3383 $ncx = $nc-1;
3384 if ($nc == 0) { return array(0,0); }
3385 else if ($nc==1) { $charspacing = $w; }
3386 // Only word spacing allowed / possible
3387 else if ($this->fixedlSpacing !== false || $inclCursive) {
3388 if ($ns) { $ws = $w / $ns; }
3389 }
3390 else if (!$ns) {
3391 $charspacing = $w / ($ncx );
3392 if (($this->jSmaxChar > 0) && ($charspacing > $this->jSmaxChar)) {
3393 $charspacing = $this->jSmaxChar;
3394 }
3395 }
3396 else if ($ns == ($ncx )) {
3397 $charspacing = $w / $ns;
3398 }
3399 else {
3400 if ($this->usingCoreFont) {
3401 $cs = ($w * (1 - $this->jSWord)) / ($ncx );
3402 if (($this->jSmaxChar > 0) && ($cs > $this->jSmaxChar)) {
3403 $cs = $this->jSmaxChar;
3404 $ww = 1 - (($cs * ($ncx ))/$w);
3405 }
3406 $charspacing = $cs;
3407 $ws = ($w * ($ww) ) / $ns;
3408 }
3409 else {
3410 $cs = ($w * (1 - $this->jSWord)) / ($ncx -$ns);
3411 if (($this->jSmaxChar > 0) && ($cs > $this->jSmaxChar)) {
3412 $cs = $this->jSmaxChar;
3413 $ww = 1 - (($cs * ($ncx -$ns))/$w);
3414 }
3415 $charspacing = $cs;
3416 $ws = (($w * ($ww) ) / $ns) - $charspacing;
3417 }
3418 }
3419 return array($charspacing,$ws);
3420 }
3421
3422 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) { // mPDF 5.3.07
3423 //Output a cell
3424 // Expects input to be mb_encoded if necessary and RTL reversed
3425 // NON_BREAKING SPACE
3426 if ($this->usingCoreFont) {
3427 $txt = str_replace(chr(160),chr(32),$txt);
3428 }
3429 else {
3430 $txt = str_replace(chr(194).chr(160),chr(32),$txt);
3431 }
3432
3433 $oldcolumn = $this->CurrCol;
3434 // Automatic page break
3435 // Allows PAGE-BREAK-AFTER = avoid to work
3436
3437 if (!$this->tableLevel && (($this->y+$this->divheight>$this->PageBreakTrigger) || ($this->y+$h>$this->PageBreakTrigger) ||
3438 ($this->y+($h*2)>$this->PageBreakTrigger && $this->blk[$this->blklvl]['page_break_after_avoid'])) and !$this->InFooter and $this->AcceptPageBreak()) {
3439 $x=$this->x;//Current X position
3440
3441
3442 // WORD SPACING
3443 $ws=$this->ws;//Word Spacing
3444 $charspacing=$this->charspacing;//Character Spacing
3445 $this->ResetSpacing();
3446
3447 $this->AddPage($this->CurOrientation);
3448 // Added to correct for OddEven Margins
3449 $x += $this->MarginCorrection;
3450 if ($currentx) {
3451 $currentx += $this->MarginCorrection;
3452 }
3453 $this->x=$x;
3454 // WORD SPACING
3455 $this->SetSpacing($charspacing,$ws);
3456 }
3457
3458 // Test: to put line through centre of cell: $this->Line($this->x,$this->y+($h/2),$this->x+50,$this->y+($h/2));
3459
3460 /*-- COLUMNS --*/
3461 // COLS
3462 // COLUMN CHANGE
3463 if ($this->CurrCol != $oldcolumn) {
3464 if ($currentx) {
3465 $currentx += $this->ChangeColumn * ($this->ColWidth+$this->ColGap);
3466 }
3467 $this->x += $this->ChangeColumn * ($this->ColWidth+$this->ColGap);
3468 }
3469
3470 // COLUMNS Update/overwrite the lowest bottom of printing y value for a column
3471 if ($this->ColActive) {
3472 if ($h) { $this->ColDetails[$this->CurrCol]['bottom_margin'] = $this->y+$h; }
3473 else { $this->ColDetails[$this->CurrCol]['bottom_margin'] = $this->y+$this->divheight; }
3474 }
3475 /*-- END COLUMNS --*/
3476
3477 // KEEP BLOCK TOGETHER Update/overwrite the lowest bottom of printing y value on first page
3478 if ($this->keep_block_together) {
3479 if ($h) { $this->ktBlock[$this->page]['bottom_margin'] = $this->y+$h; }
3480 // else { $this->ktBlock[$this->page]['bottom_margin'] = $this->y+$this->divheight; }
3481 }
3482
3483 if($w==0) $w = $this->w-$this->rMargin-$this->x;
3484 $s='';
3485 if($fill==1 && $this->FillColor) {
3486 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.' '; }
3487 $this->pageoutput[$this->page]['FillColor'] = $this->FillColor;
3488 }
3489
3490
3491 $boxtop = $this->y;
3492 $boxheight = $h;
3493 $boxbottom = $this->y+$h;
3494
3495 if($txt!='') {
3496 // FONT SIZE - this determines the baseline caculation
3497 if ($this->linemaxfontsize && !$this->processingHeader) { $bfs = $this->linemaxfontsize; }
3498 else { $bfs = $this->FontSize; }
3499 //Calculate baseline Superscript and Subscript Y coordinate adjustment
3500 $bfx = $this->baselineC;
3501 $baseline = $bfx*$bfs;
3502 if($this->SUP) { $baseline += ($bfx-1.05)*$this->FontSize; }
3503 else if($this->SUB) { $baseline += ($bfx + 0.04)*$this->FontSize; }
3504 else if($this->bullet) { $baseline += ($bfx-0.7)*$this->FontSize; }
3505
3506 // Vertical align (for Images)
3507 if ($abovefont || $belowfont) { // from flowing block - valign always M
3508 $va = $abovefont + (0.5*$bfs);
3509 }
3510 else if ($this->lineheight_correction) {
3511 if ($valign == 'T') { $va = (0.5 * $bfs * $this->lineheight_correction); }
3512 else if ($valign == 'B') { $va = $h-(0.5 * $bfs * $this->lineheight_correction); }
3513 else { $va = 0.5*$h; } // Middle
3514 }
3515 else {
3516 if ($valign == 'T') { $va = (0.5 * $bfs * $this->default_lineheight_correction); }
3517 else if ($valign == 'B') { $va = $h-(0.5 * $bfs * $this->default_lineheight_correction); }
3518 else { $va = 0.5*$h; } // Middle
3519 }
3520
3521 // ONLY SET THESE IF WANT TO CONFINE BORDER +/- FILL TO FIT FONTSIZE - NOT FULL CELL AS IS ORIGINAL FUNCTION
3522 // spanfill or spanborder are set in FlowingBlock functions
3523 // mPDF 5.3.52
3524 if ($spanfill || !empty($this->spanborddet) || $link!='') { // mPDF 5.3.71
3525 $exth = 0.2; // Add to fontsize to increase height of background / link / border
3526 $boxtop = $this->y+$baseline+$va-($this->FontSize*(1+$exth/2)*(0.5+$bfx));
3527 $boxheight = $this->FontSize * (1+$exth);
3528 $boxbottom = $boxtop + $boxheight;
3529 }
3530 }
3531
3532 // mPDF 5.3.61
3533 $bbw = $tbw = $lbw = $rbw = 0; // Border widths
3534 if (!empty($this->spanborddet)) {
3535 // mPDF 5.3.76
3536 if (!isset($this->spanborddet['B'])) { $this->spanborddet['B'] = array('s' => 0, 'style' => '', 'w' => 0); }
3537 if (!isset($this->spanborddet['T'])) { $this->spanborddet['T'] = array('s' => 0, 'style' => '', 'w' => 0); }
3538 if (!isset($this->spanborddet['L'])) { $this->spanborddet['L'] = array('s' => 0, 'style' => '', 'w' => 0); }
3539 if (!isset($this->spanborddet['R'])) { $this->spanborddet['R'] = array('s' => 0, 'style' => '', 'w' => 0); }
3540 // mPDF 5.3.61
3541 $bbw = $this->spanborddet['B']['w'];
3542 $tbw = $this->spanborddet['T']['w'];
3543 $lbw = $this->spanborddet['L']['w'];
3544 $rbw = $this->spanborddet['R']['w'];
3545 }
3546 if($fill==1 || $border==1 || !empty($this->spanborddet)) { // mPDF 5.3.61
3547 // mPDF 5.3.61
3548 if (!empty($this->spanborddet)) {
3549 if ($fill==1) {
3550 $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);
3551 }
3552 $s.= ' q ';
3553 $dashon = 3;
3554 $dashoff = 3.5;
3555 $dot = 2.5;
3556 if($tbw) { // mPDF 5.3.76
3557 $short = 0;
3558 if ($this->spanborddet['T']['style'] == 'dashed') {
3559 $s.=sprintf(' 0 j 0 J [%.3F %.3F] 0 d ',$tbw*$dashon*_MPDFK,$tbw*$dashoff*_MPDFK);
3560 }
3561 else if ($this->spanborddet['T']['style'] == 'dotted') {
3562 $s.=sprintf(' 1 j 1 J [%.3F %.3F] %.3F d ',0.001,$tbw*$dot*_MPDFK,-$tbw/2*_MPDFK);
3563 $short = $tbw/2;
3564 }
3565 else {
3566 $s.=' 0 j 0 J [] 0 d ';
3567 }
3568 $c = $this->SetDColor($this->spanborddet['T']['c'],true);
3569 if ($this->spanborddet['T']['style'] == 'double') {
3570 $s.=sprintf(' %s %.3F w ',$c,$tbw/3*_MPDFK);
3571 $xadj = $xadj2 = 0;
3572 if ($this->spanborddet['L']['style'] == 'double') { $xadj = $this->spanborddet['L']['w']*2/3; }
3573 if ($this->spanborddet['R']['style'] == 'double') { $xadj2 = $this->spanborddet['R']['w']*2/3; }
3574 $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);
3575 $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);
3576 }
3577 else {
3578 $s.=sprintf(' %s %.3F w ',$c,$tbw*_MPDFK);
3579 $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);
3580 }
3581 }
3582 if($bbw) { // mPDF 5.3.76
3583 $short = 0;
3584 if ($this->spanborddet['B']['style'] == 'dashed') {
3585 $s.=sprintf(' 0 j 0 J [%.3F %.3F] 0 d ',$bbw*$dashon*_MPDFK,$bbw*$dashoff*_MPDFK);
3586 }
3587 else if ($this->spanborddet['B']['style'] == 'dotted') {
3588 $s.=sprintf(' 1 j 1 J [%.3F %.3F] %.3F d ',0.001,$bbw*$dot*_MPDFK,-$bbw/2*_MPDFK);
3589 $short = $bbw/2;
3590 }
3591 else {
3592 $s.=' 0 j 0 J [] 0 d ';
3593 }
3594 $c = $this->SetDColor($this->spanborddet['B']['c'],true);
3595 if ($this->spanborddet['B']['style'] == 'double') {
3596 $s.=sprintf(' %s %.3F w ',$c,$bbw/3*_MPDFK);
3597 $xadj = $xadj2 = 0;
3598 if ($this->spanborddet['L']['style'] == 'double') { $xadj = $this->spanborddet['L']['w']*2/3; }
3599 if ($this->spanborddet['R']['style'] == 'double') { $xadj2 = $this->spanborddet['R']['w']*2/3; }
3600 $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);
3601 $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);
3602 }
3603 else {
3604 $s.=sprintf(' %s %.3F w ',$c,$bbw*_MPDFK);
3605 $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);
3606 }
3607 }
3608 if($lbw) { // mPDF 5.3.76
3609 $short = 0;
3610 if ($this->spanborddet['L']['style'] == 'dashed') {
3611 $s.=sprintf(' 0 j 0 J [%.3F %.3F] 0 d ',$lbw*$dashon*_MPDFK,$lbw*$dashoff*_MPDFK);
3612 }
3613 else if ($this->spanborddet['L']['style'] == 'dotted') {
3614 $s.=sprintf(' 1 j 1 J [%.3F %.3F] %.3F d ',0.001,$lbw*$dot*_MPDFK,-$lbw/2*_MPDFK);
3615 $short = $lbw/2;
3616 }
3617 else {
3618 $s.=' 0 j 0 J [] 0 d ';
3619 }
3620 $c = $this->SetDColor($this->spanborddet['L']['c'],true);
3621 if ($this->spanborddet['L']['style'] == 'double') {
3622 $s.=sprintf(' %s %.3F w ',$c,$lbw/3*_MPDFK);
3623 $yadj = $yadj2 = 0;
3624 if ($this->spanborddet['T']['style'] == 'double') { $yadj = $this->spanborddet['T']['w']*2/3; }
3625 if ($this->spanborddet['B']['style'] == 'double') { $yadj2 = $this->spanborddet['B']['w']*2/3; }
3626 $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);
3627 $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);
3628 }
3629 else {
3630 $s.=sprintf(' %s %.3F w ',$c,$lbw*_MPDFK);
3631 $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);
3632 }
3633 }
3634 if($rbw) { // mPDF 5.3.76
3635 $short = 0;
3636 if ($this->spanborddet['R']['style'] == 'dashed') {
3637 $s.=sprintf(' 0 j 0 J [%.3F %.3F] 0 d ',$rbw*$dashon*_MPDFK,$rbw*$dashoff*_MPDFK);
3638 }
3639 else if ($this->spanborddet['R']['style'] == 'dotted') {
3640 $s.=sprintf(' 1 j 1 J [%.3F %.3F] %.3F d ',0.001,$rbw*$dot*_MPDFK,-$rbw/2*_MPDFK);
3641 $short = $rbw/2;
3642 }
3643 else {
3644 $s.=' 0 j 0 J [] 0 d ';
3645 }
3646 $c = $this->SetDColor($this->spanborddet['R']['c'],true);
3647 if ($this->spanborddet['R']['style'] == 'double') {
3648 $s.=sprintf(' %s %.3F w ',$c,$rbw/3*_MPDFK);
3649 $yadj = $yadj2 = 0;
3650 if ($this->spanborddet['T']['style'] == 'double') { $yadj = $this->spanborddet['T']['w']*2/3; }
3651 if ($this->spanborddet['B']['style'] == 'double') { $yadj2 = $this->spanborddet['B']['w']*2/3; }
3652 $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);
3653 $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);
3654 }
3655 else {
3656 $s.=sprintf(' %s %.3F w ',$c,$rbw*_MPDFK);
3657 $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);
3658 }
3659 }
3660 $s.= ' Q ';
3661 }
3662 else {
3663 if ($fill==1) $op=($border==1) ? 'B' : 'f';
3664 else $op='S';
3665 $s.=sprintf('%.3F %.3F %.3F %.3F re %s ',$this->x*_MPDFK,($this->h-$boxtop)*_MPDFK,$w*_MPDFK,-$boxheight*_MPDFK,$op);
3666 }
3667 }
3668
3669 if(is_string($border)) {
3670 $x=$this->x;
3671 $y=$this->y;
3672 if(is_int(strpos($border,'L')))
3673 $s.=sprintf('%.3F %.3F m %.3F %.3F l S ',$x*_MPDFK,($this->h-$boxtop)*_MPDFK,$x*_MPDFK,($this->h-($boxbottom))*_MPDFK);
3674 if(is_int(strpos($border,'T')))
3675 $s.=sprintf('%.3F %.3F m %.3F %.3F l S ',$x*_MPDFK,($this->h-$boxtop)*_MPDFK,($x+$w)*_MPDFK,($this->h-$boxtop)*_MPDFK);
3676 if(is_int(strpos($border,'R')))
3677 $s.=sprintf('%.3F %.3F m %.3F %.3F l S ',($x+$w)*_MPDFK,($this->h-$boxtop)*_MPDFK,($x+$w)*_MPDFK,($this->h-($boxbottom))*_MPDFK);
3678 if(is_int(strpos($border,'B')))
3679 $s.=sprintf('%.3F %.3F m %.3F %.3F l S ',$x*_MPDFK,($this->h-($boxbottom))*_MPDFK,($x+$w)*_MPDFK,($this->h-($boxbottom))*_MPDFK);
3680 }
3681
3682 if($txt!='') {
3683 if ($exactWidth) // mPDF 5.3.07
3684 $stringWidth = $w;
3685 else // mPDF 5.3.07 // mPDF 5.3.20
3686 $stringWidth = $this->GetStringWidth($txt) + ( $this->charspacing * mb_strlen( $txt, $this->mb_enc ) / _MPDFK )
3687 + ( $this->ws * mb_substr_count( $txt, ' ', $this->mb_enc ) / _MPDFK );
3688
3689 // Set x OFFSET FOR PRINTING
3690 if($align=='R') {
3691 $dx=$w-$this->cMarginR - $stringWidth - $lcpaddingR;
3692 }
3693 elseif($align=='C') {
3694 $dx=(($w - $stringWidth )/2);
3695 }
3696 elseif($align=='L' or $align=='J') $dx=$this->cMarginL + $lcpaddingL;
3697 else $dx = 0;
3698
3699 if($this->ColorFlag) $s .='q '.$this->TextColor.' ';
3700
3701 // OUTLINE
3702 if($this->outline_on && !$this->S) {
3703 $s .=' '.sprintf('%.3F w',$this->LineWidth*_MPDFK).' ';
3704 $s .=" $this->DrawColor ";
3705 $s .=" 2 Tr ";
3706 }
3707 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
3708 $s .= ' 2 Tr 1 J 1 j ';
3709 $s .= ' '.sprintf('%.3F w',($this->FontSize/130)*_MPDFK*$this->falseBoldWeight).' ';
3710 $tc = strtoupper($this->TextColor); // change 0 0 0 rg to 0 0 0 RG
3711 if($this->FillColor!=$tc) { $s .= ' '.$tc.' '; } // stroke (outline) = same colour as text(fill)
3712 }
3713
3714 if (strpos($this->ReqFontStyle,"I") !== false && strpos($this->FontStyle,"I") === false) { // Artificial italic
3715 $aix = '1 0 0.261799 1 %.3F %.3F Tm ';
3716 }
3717 else { $aix = '%.3F %.3F Td '; }
3718
3719 // THE TEXT
3720 // mPDF 5.3.A2 Capture in substring $sub
3721 $sub = '';
3722 $this->CurrentFont['used']= true;
3723
3724 // WORD SPACING
3725 // IF multibyte - Tw has no effect - need to use alternative method - do word spacing using an adjustment before each space
3726 if ($this->ws && !$this->usingCoreFont && !$this->CurrentFont['sip'] && !$this->CurrentFont['smp'] && !$this->S) {
3727 $sub .= ' BT 0 Tw ET ';
3728 if ($this->kerning && $this->useKerning) { $sub .= $this->_kern($txt, 'MBTw', $aix, ($this->x+$dx), ($this->y+$baseline+$va)); }
3729 else {
3730 $space = " ";
3731 //Convert string to UTF-16BE without BOM
3732 $space= $this->UTF8ToUTF16BE($space , false);
3733 $space=$this->_escape($space );
3734 $sub .=sprintf('BT '.$aix,($this->x+$dx)*_MPDFK,($this->h-($this->y+$baseline+$va))*_MPDFK);
3735 $t = explode(' ',$txt);
3736 $sub .=sprintf(' %.3F Tc [',$this->charspacing);
3737 $numt = count($t); // mPDF 5.3.07
3738 for($i=0;$i<$numt;$i++) { // mPDF 5.3.07
3739 $tx = $t[$i];
3740 //Convert string to UTF-16BE without BOM
3741 $tx = $this->UTF8ToUTF16BE($tx , false);
3742 $tx = $this->_escape($tx);
3743 $sub .=sprintf('(%s) ',$tx);
3744 if (($i+1)<$numt) { // mPDF 5.3.07
3745 $adj = -($this->ws)*1000/$this->FontSizePt;
3746 $sub .=sprintf('%d(%s) ',$adj,$space);
3747 }
3748 }
3749 $sub .='] TJ ';
3750 $sub .=' ET';
3751 }
3752 }
3753 else {
3754 $txt2= $txt;
3755 if ($this->CurrentFont['type']=='TTF' && ($this->CurrentFont['sip'] || $this->CurrentFont['smp'])) {
3756 if ($this->S) { $sub .= $this->_smallCaps($txt2, 'SIPSMP', $aix, $dx, _MPDFK, $baseline, $va); }
3757 else {
3758 $txt2 = $this->UTF8toSubset($txt2);
3759 $sub .=sprintf('BT '.$aix.' %s Tj ET',($this->x+$dx)*_MPDFK,($this->h-($this->y+$baseline+$va))*_MPDFK,$txt2);
3760 }
3761 }
3762 else {
3763 if ($this->S) { $sub .= $this->_smallCaps($txt2, '', $aix, $dx, _MPDFK, $baseline, $va); }
3764 else if ($this->kerning && $this->useKerning) { $sub .= $this->_kern($txt2, '', $aix, ($this->x+$dx), ($this->y+$baseline+$va)); }
3765 else {
3766 if (!$this->usingCoreFont) {
3767 $txt2 = $this->UTF8ToUTF16BE($txt2, false);
3768 }
3769 $txt2=$this->_escape($txt2);
3770 $sub .=sprintf('BT '.$aix.' (%s) Tj ET',($this->x+$dx)*_MPDFK,($this->h-($this->y+$baseline+$va))*_MPDFK,$txt2);
3771 }
3772 }
3773 }
3774 // UNDERLINE
3775 if($this->U) {
3776 $c = strtoupper($this->TextColor); // change 0 0 0 rg to 0 0 0 RG
3777 if($this->FillColor!=$c) { $sub .= ' '.$c.' '; }
3778 if (isset($this->CurrentFont['up'])) { $up=$this->CurrentFont['up']; }
3779 else { $up = -100; }
3780 $adjusty = (-$up/1000* $this->FontSize);
3781 if (isset($this->CurrentFont['ut'])) { $ut=$this->CurrentFont['ut']/1000* $this->FontSize; }
3782 else { $ut = 60/1000* $this->FontSize; }
3783 $olw = $this->LineWidth;
3784 $sub .=' '.(sprintf(' %.3F w 0 j 0 J ',$ut*_MPDFK)); // mPDF 5.3.61
3785 $sub .=' '.$this->_dounderline($this->x+$dx,$this->y+$baseline+$va+$adjusty,$txt);
3786 $sub .=' '.(sprintf(' %.3F w 2 j 2 J ',$olw*_MPDFK)); // mPDF 5.3.61
3787 if($this->FillColor!=$c) { $sub .= ' '.$this->FillColor.' '; }
3788 }
3789
3790 // STRIKETHROUGH
3791 if($this->strike) {
3792 $c = strtoupper($this->TextColor); // change 0 0 0 rg to 0 0 0 RG
3793 if($this->FillColor!=$c) { $sub .= ' '.$c.' '; }
3794 //Superscript and Subscript Y coordinate adjustment (now for striked-through texts)
3795 if (isset($this->CurrentFont['desc']['CapHeight'])) { $ch=$this->CurrentFont['desc']['CapHeight']; }
3796 else { $ch = 700; }
3797 $adjusty = (-$ch/1000* $this->FontSize) * 0.35;
3798 if (isset($this->CurrentFont['ut'])) { $ut=$this->CurrentFont['ut']/1000* $this->FontSize; }
3799 else { $ut = 60/1000* $this->FontSize; }
3800 $olw = $this->LineWidth;
3801 $sub .=' '.(sprintf(' %.3F w 0 j 0 J ',$ut*_MPDFK)); // mPDF 5.3.61
3802 $sub .=' '.$this->_dounderline($this->x+$dx,$this->y+$baseline+$va+$adjusty,$txt);
3803 $sub .=' '.(sprintf(' %.3F w 2 j 2 J ',$olw*_MPDFK)); // mPDF 5.3.54 // mPDF 5.3.61
3804 if($this->FillColor!=$c) { $sub .= ' '.$this->FillColor.' '; }
3805 }
3806
3807 // mPDF 5.3.A2
3808 // TEXT SHADOW
3809 if ($this->textshadow) { // First to process is last in CSS comma separated shadows
3810 foreach($this->textshadow AS $ts) {
3811 $s .= ' q ';
3812 $s .= $this->SetTColor($ts['col'], true)."\n";
3813 if ($ts['col']{0}==5 && ord($ts['col']{4})<100) { // RGBa
3814 $s .= $this->SetAlpha(ord($ts['col']{4})/100, 'Normal', true, 'F')."\n";
3815 }
3816 else if ($ts['col']{0}==6 && ord($ts['col']{5})<100) { // CMYKa
3817 $s .= $this->SetAlpha(ord($ts['col']{5})/100, 'Normal', true, 'F')."\n";
3818 }
3819 else if ($ts['col']{0}==1 && $ts['col']{2}==1 && ord($ts['col']{3})<100) { // Gray
3820 $s .= $this->SetAlpha(ord($ts['col']{3})/100, 'Normal', true, 'F')."\n";
3821 }
3822 $s .= sprintf(' q 1 0 0 1 %.4F %.4F cm', $ts['x']*_MPDFK, -$ts['y']*_MPDFK)."\n";
3823 $s .= $sub;
3824 $s .= ' Q ';
3825 $s .= ' Q ';
3826 }
3827 }
3828
3829 $s .= $sub;
3830
3831 // COLOR
3832 if($this->ColorFlag) $s .=' Q';
3833
3834 // LINK
3835 if($link!='') {
3836 // mPDF 5.3.16
3837 // Use same co-ordinates as span FILL above
3838 $this->Link($this->x,$boxtop,$w,$boxheight,$link);
3839 // Use this to add some padding/spacing around the textbox for the LINK
3840 // Use same spacing as span FILL above
3841 // $hsp = $this->FontSize/7;
3842 // $vsp = $this->FontSize/10;
3843 // $this->Link($this->x-$hsp,$boxtop-$vsp,$w+2*$hsp,$boxheight+2*$vsp,$link);
3844 }
3845 }
3846 if($s) $this->_out($s);
3847
3848 // WORD SPACING
3849 if ($this->ws && !$this->usingCoreFont) {
3850 $this->_out(sprintf('BT %.3F Tc ET',$this->charspacing));
3851 }
3852 $this->lasth=$h;
3853 if( strpos($txt,"\n") !== false) $ln=1; // cell recognizes \n from <BR> tag
3854 if($ln>0)
3855 {
3856 //Go to next line
3857 $this->y += $h;
3858 if($ln==1) {
3859 //Move to next line
3860 if ($currentx != 0) { $this->x=$currentx; }
3861 else { $this->x=$this->lMargin; }
3862 }
3863 }
3864 else $this->x+=$w;
3865
3866
3867 }
3868
3869
3870 function _kern($txt, $mode, $aix, $x, $y) {
3871 if ($mode == 'MBTw') { // Multibyte requiring word spacing
3872 $space = ' ';
3873 //Convert string to UTF-16BE without BOM
3874 $space= $this->UTF8ToUTF16BE($space , false);
3875 $space=$this->_escape($space );
3876 $s = sprintf(' BT '.$aix,$x*_MPDFK,($this->h-$y)*_MPDFK);
3877 $t = explode(' ',$txt);
3878 for($i=0;$i<count($t);$i++) {
3879 $tx = $t[$i];
3880
3881 $tj = '(';
3882 $unicode = $this->UTF8StringToArray($tx);
3883 for($ti=0;$ti<count($unicode);$ti++) {
3884 if ($ti > 0 && isset($this->CurrentFont['kerninfo'][$unicode[($ti-1)]][$unicode[$ti]])) {
3885 $kern = -$this->CurrentFont['kerninfo'][$unicode[($ti-1)]][$unicode[$ti]];
3886 $tj .= sprintf(')%d(',$kern);
3887 }
3888 $tc = code2utf($unicode[$ti]);
3889 $tc = $this->UTF8ToUTF16BE($tc, false);
3890 $tj .= $this->_escape($tc);
3891 }
3892 $tj .= ')';
3893 $s.=sprintf(' %.3F Tc [%s] TJ',$this->charspacing,$tj);
3894
3895
3896 if (($i+1)<count($t)) {
3897 $s.=sprintf(' %.3F Tc (%s) Tj',$this->ws+$this->charspacing,$space);
3898 }
3899 }
3900 $s.=' ET ';
3901 }
3902 else if (!$this->usingCoreFont) {
3903 $s = '';
3904 $tj = '(';
3905 $unicode = $this->UTF8StringToArray($txt);
3906 for($i=0;$i<count($unicode);$i++) {
3907 if ($i > 0 && isset($this->CurrentFont['kerninfo'][$unicode[($i-1)]][$unicode[$i]])) {
3908 $kern = -$this->CurrentFont['kerninfo'][$unicode[($i-1)]][$unicode[$i]];
3909 $tj .= sprintf(')%d(',$kern);
3910 }
3911 $tx = code2utf($unicode[$i]);
3912 $tx = $this->UTF8ToUTF16BE($tx, false);
3913 $tj .= $this->_escape($tx);
3914 }
3915 $tj .= ')';
3916 $s.=sprintf(' BT '.$aix.' [%s] TJ ET ',$x*_MPDFK,($this->h-$y)*_MPDFK,$tj);
3917 }
3918 else { // CORE Font
3919 $s = '';
3920 $tj = '(';
3921 $l = strlen($txt);
3922 for($i=0;$i<$l;$i++) {
3923 if ($i > 0 && isset($this->CurrentFont['kerninfo'][$txt[($i-1)]][$txt[$i]])) {
3924 $kern = -$this->CurrentFont['kerninfo'][$txt[($i-1)]][$txt[$i]];
3925 $tj .= sprintf(')%d(',$kern);
3926 }
3927 $tj .= $this->_escape($txt[$i]);
3928 }
3929 $tj .= ')';
3930 $s.=sprintf(' BT '.$aix.' [%s] TJ ET ',$x*_MPDFK,($this->h-$y)*_MPDFK,$tj);
3931 }
3932
3933 return $s;
3934 }
3935
3936
3937 function _smallCaps($txt, $mode, $aix, $dx, $k, $baseline, $va) { // mPDF 5.3.76
3938 $upp = false;
3939 $str = array();
3940 $bits = array();
3941 if (!$this->usingCoreFont) {
3942 $unicode = $this->UTF8StringToArray($txt);
3943 foreach($unicode as $char) {
3944 if ($this->ws && $char == 32) { // space
3945 if (count($str)) { $bits[] = array($upp, $str, false); }
3946 $bits[] = array(false, array(32), true);
3947 $str = array();
3948 $upp = false;
3949 }
3950 else if (isset($this->upperCase[$char])) {
3951 if (!$upp) {
3952 if (count($str)) { $bits[] = array($upp, $str, false); }
3953 $str = array();
3954 }
3955 $str[] = $this->upperCase[$char];
3956 if ((!isset($this->CurrentFont['sip']) || !$this->CurrentFont['sip']) && (!isset($this->CurrentFont['smp']) || !$this->CurrentFont['smp'])) {
3957 $this->CurrentFont['subset'][$this->upperCase[$char]] = $this->upperCase[$char];
3958 }
3959 $upp = true;
3960 }
3961 else {
3962 if ($upp) {
3963 if (count($str)) { $bits[] = array($upp, $str, false); }
3964 $str = array();
3965 }
3966 $str[] = $char;
3967 $upp = false;
3968 }
3969 }
3970 }
3971 else {
3972 for($i=0;$i<strlen($txt);$i++) {
3973 if (isset($this->upperCase[ord($txt[$i])]) && $this->upperCase[ord($txt[$i])] < 256) {
3974 if (!$upp) {
3975 if (count($str)) { $bits[] = array($upp, $str, false); }
3976 $str = array();
3977 }
3978 $str[] = $this->upperCase[ord($txt[$i])];
3979 $upp = true;
3980 }
3981 else {
3982 if ($upp) {
3983 if (count($str)) { $bits[] = array($upp, $str, false); }
3984 $str = array();
3985 }
3986 $str[] = ord($txt[$i]);
3987 $upp = false;
3988 }
3989 }
3990 }
3991 if (count($str)) { $bits[] = array($upp, $str, false); }
3992
3993 $fid = $this->CurrentFont['i'];
3994
3995 $s=sprintf(' BT '.$aix,($this->x+$dx)*$k,($this->h-($this->y+$baseline+$va))*$k); // mPDF 5.3.76
3996 foreach($bits AS $b) {
3997 if ($b[0]) { $upp = true; }
3998 else { $upp = false; }
3999
4000 $size = count ($b[1]);
4001 $txt = '';
4002 for ($i = 0; $i < $size; $i++) {
4003 $txt .= code2utf($b[1][$i]);
4004 }
4005 if ($this->usingCoreFont) {
4006 $txt = utf8_decode($txt);
4007 }
4008 if ($mode == 'SIPSMP') {
4009 $txt = $this->UTF8toSubset($txt);
4010 }
4011 else {
4012 if (!$this->usingCoreFont) {
4013 $txt = $this->UTF8ToUTF16BE($txt, false);
4014 }
4015 $txt=$this->_escape($txt);
4016 $txt = '('.$txt.')';
4017 }
4018 if ($b[2]) { // space
4019 $s.=sprintf(' /F%d %.3F Tf %d Tz', $fid, $this->FontSizePt, 100);
4020 $s.=sprintf(' %.3F Tc', ($this->charspacing+$this->ws));
4021 $s.=sprintf(' %s Tj', $txt);
4022 }
4023 else if ($upp) {
4024 $s.=sprintf(' /F%d %.3F Tf', $fid, $this->FontSizePt*$this->smCapsScale);
4025 $s.=sprintf(' %d Tz', $this->smCapsStretch);
4026 $s.=sprintf(' %.3F Tc', ($this->charspacing*100/$this->smCapsStretch));
4027 $s.=sprintf(' %s Tj', $txt);
4028 }
4029 else {
4030 $s.=sprintf(' /F%d %.3F Tf %d Tz', $fid, $this->FontSizePt, 100);
4031 $s.=sprintf(' %.3F Tc', ($this->charspacing));
4032 $s.=sprintf(' %s Tj', $txt);
4033 }
4034 }
4035 $s.=' ET ';
4036 return $s;
4037 }
4038
4039
4040 function MultiCell($w,$h,$txt,$border=0,$align='',$fill=0,$link='',$directionality='ltr',$encoded=false)
4041 {
4042 // Parameter (pre-)encoded - When called internally from ToC or textarea: mb_encoding already done - but not reverse RTL/Indic
4043 if (!$encoded) {
4044 $txt = $this->purify_utf8_text($txt);
4045 if ($this->text_input_as_HTML) {
4046 $txt = $this->all_entities_to_utf8($txt);
4047 }
4048 if ($this->usingCoreFont) { $txt = mb_convert_encoding($txt,$this->mb_enc,'UTF-8'); }
4049 // Font-specific ligature substitution for Indic fonts
4050 else if (isset($this->CurrentFont['indic']) && $this->CurrentFont['indic']) { // *INDIC*
4051 $this->ConvertIndic($tmp); // *INDIC*
4052 } // *INDIC*
4053 if (preg_match("/([".$this->pregRTLchars."])/u", $txt)) { $this->biDirectional = true; } // *RTL*
4054 }
4055 if (!$align) { $align = $this->defaultAlign; }
4056
4057 //Output text with automatic or explicit line breaks
4058 $cw=&$this->CurrentFont['cw'];
4059 if($w==0) $w=$this->w-$this->rMargin-$this->x;
4060
4061 $wmax = ($w - ($this->cMarginL+$this->cMarginR));
4062 if ($this->usingCoreFont) {
4063 $s=str_replace("\r",'',$txt);
4064 $nb=strlen($s);
4065 while($nb>0 and $s[$nb-1]=="\n") $nb--;
4066 }
4067 else {
4068 $s=str_replace("\r",'',$txt);
4069 $nb=mb_strlen($s, $this->mb_enc );
4070 while($nb>0 and mb_substr($s,$nb-1,1,$this->mb_enc )=="\n") $nb--;
4071 }
4072 $b=0;
4073 if($border) {
4074 if($border==1) {
4075 $border='LTRB';
4076 $b='LRT';
4077 $b2='LR';
4078 }
4079 else {
4080 $b2='';
4081 if(is_int(strpos($border,'L'))) $b2.='L';
4082 if(is_int(strpos($border,'R'))) $b2.='R';
4083 $b=is_int(strpos($border,'T')) ? $b2.'T' : $b2;
4084 }
4085 }
4086 $sep=-1;
4087 $i=0;
4088 $j=0;
4089 $l=0;
4090 $ns=0;
4091 $nl=1;
4092
4093
4094
4095 if (!$this->usingCoreFont) {
4096 $checkCursive=false;
4097 if ($this->biDirectional) { $checkCursive=true; } // *RTL*
4098 else if (isset($this->CurrentFont['indic']) && $this->CurrentFont['indic']) { $checkCursive=true; } // *INDIC*
4099 while($i<$nb) {
4100 //Get next character
4101 $c = mb_substr($s,$i,1,$this->mb_enc );
4102 if($c == "\n") {
4103 //Explicit line break
4104 // WORD SPACING
4105 $this->ResetSpacing();
4106 $tmp = rtrim(mb_substr($s,$j,$i-$j,$this->mb_enc));
4107 // DIRECTIONALITY
4108 $this->magic_reverse_dir($tmp, true, $directionality); // *RTL*
4109
4110 $this->Cell($w,$h,$tmp,$b,2,$align,$fill,$link);
4111 $i++;
4112 $sep=-1;
4113 $j=$i;
4114 $l=0;
4115 $ns=0;
4116 $nl++;
4117 if($border and $nl==2) $b=$b2;
4118 continue;
4119 }
4120 if($c == " ") {
4121 $sep=$i;
4122 $ls=$l;
4123 $ns++;
4124 }
4125
4126 $l += $this->GetCharWidthNonCore($c); // mPDF 5.3.04
4127
4128 if($l>$wmax) {
4129 //Automatic line break
4130 if($sep==-1) { // Only one word
4131 if($i==$j) $i++;
4132 // WORD SPACING
4133 $this->ResetSpacing();
4134 $tmp = rtrim(mb_substr($s,$j,$i-$j,$this->mb_enc));
4135 // DIRECTIONALITY
4136 $this->magic_reverse_dir($tmp, true, $directionality); // *RTL*
4137
4138 $this->Cell($w,$h,$tmp,$b,2,$align,$fill,$link);
4139 }
4140 else {
4141 $tmp = rtrim(mb_substr($s,$j,$sep-$j,$this->mb_enc));
4142 if($align=='J') {
4143 //////////////////////////////////////////
4144 // JUSTIFY J using Unicode fonts (Word spacing doesn't work)
4145 // WORD SPACING UNICODE
4146 // Change NON_BREAKING SPACE to spaces so they are 'spaced' properly
4147 $tmp = str_replace(chr(194).chr(160),chr(32),$tmp );
4148 $len_ligne = $this->GetStringWidth($tmp );
4149 $nb_carac = mb_strlen( $tmp , $this->mb_enc ) ;
4150 $nb_spaces = mb_substr_count( $tmp ,' ', $this->mb_enc ) ;
4151
4152 $inclCursive=false;
4153 if ($checkCursive) {
4154 if (preg_match("/([".$this->pregRTLchars."])/u", $tmp)) { $inclCursive = true; } // *RTL*
4155 if (preg_match("/([".$this->pregHIchars.$this->pregBNchars.$this->pregPAchars."])/u", $tmp)) { $inclCursive = true; } // *INDIC*
4156 }
4157 list($charspacing,$ws) = $this->GetJspacing($nb_carac,$nb_spaces,((($wmax) - $len_ligne) * _MPDFK),$inclCursive);
4158 $this->SetSpacing($charspacing,$ws);
4159 //////////////////////////////////////////
4160 }
4161
4162 // DIRECTIONALITY
4163 $this->magic_reverse_dir($tmp, true, $directionality); // *RTL*
4164
4165 $this->Cell($w,$h,$tmp,$b,2,$align,$fill,$link);
4166 $i=$sep+1;
4167 }
4168 $sep=-1;
4169 $j=$i;
4170 $l=0;
4171 $ns=0;
4172 $nl++;
4173 if($border and $nl==2) $b=$b2;
4174 }
4175 else $i++;
4176 }
4177 //Last chunk
4178 // WORD SPACING
4179
4180 $this->ResetSpacing();
4181
4182 }
4183
4184
4185 else {
4186
4187 while($i<$nb) {
4188 //Get next character
4189 $c=$s[$i];
4190 if($c == "\n") {
4191 //Explicit line break
4192 // WORD SPACING
4193 $this->ResetSpacing();
4194 $this->Cell($w,$h,substr($s,$j,$i-$j),$b,2,$align,$fill,$link);
4195 $i++;
4196 $sep=-1;
4197 $j=$i;
4198 $l=0;
4199 $ns=0;
4200 $nl++;
4201 if($border and $nl==2) $b=$b2;
4202 continue;
4203 }
4204 if($c == " ") {
4205 $sep=$i;
4206 $ls=$l;
4207 $ns++;
4208 }
4209
4210 $l += $this->GetCharWidthCore($c); // mPDF 5.3.04
4211 if($l>$wmax) {
4212 //Automatic line break
4213 if($sep==-1) {
4214 if($i==$j) $i++;
4215 // WORD SPACING
4216 $this->ResetSpacing();
4217 $this->Cell($w,$h,substr($s,$j,$i-$j),$b,2,$align,$fill,$link);
4218 }
4219 else {
4220 if($align=='J') {
4221 $tmp = rtrim(substr($s,$j,$sep-$j));
4222 //////////////////////////////////////////
4223 // JUSTIFY J using Unicode fonts (Word spacing doesn't work)
4224 // WORD SPACING NON_UNICDOE/CJK
4225 // Change NON_BREAKING SPACE to spaces so they are 'spaced' properly
4226 $tmp = str_replace(chr(160),chr(32),$tmp);
4227 $len_ligne = $this->GetStringWidth($tmp );
4228 $nb_carac = strlen( $tmp ) ;
4229 $nb_spaces = substr_count( $tmp ,' ' ) ;
4230 list($charspacing,$ws) = $this->GetJspacing($nb_carac,$nb_spaces,((($wmax) - $len_ligne) * _MPDFK),false);
4231 $this->SetSpacing($charspacing,$ws);
4232 //////////////////////////////////////////
4233 }
4234 $this->Cell($w,$h,substr($s,$j,$sep-$j),$b,2,$align,$fill,$link);
4235 $i=$sep+1;
4236 }
4237 $sep=-1;
4238 $j=$i;
4239 $l=0;
4240 $ns=0;
4241 $nl++;
4242 if($border and $nl==2) $b=$b2;
4243 }
4244 else $i++;
4245 }
4246 //Last chunk
4247 // WORD SPACING
4248
4249 $this->ResetSpacing();
4250
4251 }
4252 //Last chunk
4253 if($border and is_int(strpos($border,'B'))) $b.='B';
4254 if (!$this->usingCoreFont) {
4255 $tmp = rtrim(mb_substr($s,$j,$i-$j,$this->mb_enc));
4256 // DIRECTIONALITY
4257 $this->magic_reverse_dir($tmp, true, $directionality); // *RTL*
4258 $this->Cell($w,$h,$tmp,$b,2,$align,$fill,$link);
4259 }
4260 else { $this->Cell($w,$h,substr($s,$j,$i-$j),$b,2,$align,$fill,$link); }
4261 $this->x=$this->lMargin;
4262 }
4263
4264
4265 /*-- DIRECTW --*/
4266 function Write($h,$txt,$currentx=0,$link='',$directionality='ltr',$align='') {
4267 if (!class_exists('directw', false)) { include(_MPDF_PATH.'classes/directw.php'); }
4268 if (empty($this->directw)) { $this->directw = new directw($this); }
4269 $this->directw->Write($h,$txt,$currentx,$link,$directionality,$align);
4270 }
4271 /*-- END DIRECTW --*/
4272
4273
4274 /*-- HTML-CSS --*/
4275 function saveInlineProperties() {
4276 $saved = array();
4277 $saved[ 'family' ] = $this->FontFamily;
4278 $saved[ 'style' ] = $this->FontStyle;
4279 $saved[ 'sizePt' ] = $this->FontSizePt;
4280 $saved[ 'size' ] = $this->FontSize;
4281 $saved[ 'HREF' ] = $this->HREF;
4282 $saved[ 'underline' ] = $this->U;
4283 $saved[ 'smCaps' ] = $this->S;
4284 $saved[ 'strike' ] = $this->strike;
4285 $saved[ 'textshadow' ] = $this->textshadow; // mPDF 5.3.A2
4286 $saved[ 'SUP' ] = $this->SUP;
4287 $saved[ 'SUB' ] = $this->SUB;
4288 $saved[ 'linewidth' ] = $this->LineWidth;
4289 $saved[ 'drawcolor' ] = $this->DrawColor;
4290 $saved[ 'is_outline' ] = $this->outline_on;
4291 $saved[ 'outlineparam' ] = $this->outlineparam;
4292 $saved[ 'toupper' ] = $this->toupper;
4293 $saved[ 'tolower' ] = $this->tolower;
4294 $saved[ 'capitalize' ] = $this->capitalize;
4295 $saved[ 'fontkerning' ] = $this->kerning;
4296 $saved[ 'lSpacingCSS' ] = $this->lSpacingCSS;
4297 $saved[ 'wSpacingCSS' ] = $this->wSpacingCSS;
4298 $saved[ 'I' ] = $this->I;
4299 $saved[ 'B' ] = $this->B;
4300 $saved[ 'colorarray' ] = $this->colorarray;
4301 $saved[ 'bgcolorarray' ] = $this->spanbgcolorarray;
4302 $saved[ 'border' ] = $this->spanborddet; // mPDF 5.3.61
4303 $saved[ 'color' ] = $this->TextColor;
4304 $saved[ 'bgcolor' ] = $this->FillColor;
4305 $saved['lang'] = $this->currentLang;
4306 $saved['display_off'] = $this->inlineDisplayOff;
4307
4308 return $saved;
4309 }
4310
4311 function restoreInlineProperties( &$saved) {
4312 $FontFamily = $saved[ 'family' ];
4313 $this->FontStyle = $saved[ 'style' ];
4314 $this->FontSizePt = $saved[ 'sizePt' ];
4315 $this->FontSize = $saved[ 'size' ];
4316
4317 $this->currentLang = $saved['lang'];
4318 if ($this->useLang && !$this->usingCoreFont) {
4319 if ($this->currentLang != $this->default_lang && ((strlen($this->currentLang) == 5 && $this->currentLang != 'UTF-8') || strlen($this->currentLang ) == 2)) {
4320 list ($coreSuitable,$mpdf_pdf_unifonts) = GetLangOpts($this->currentLang, $this->useAdobeCJK);
4321 if ($mpdf_pdf_unifonts) { $this->RestrictUnicodeFonts($mpdf_pdf_unifonts); }
4322 else { $this->RestrictUnicodeFonts($this->default_available_fonts ); }
4323 }
4324 else {
4325 $this->RestrictUnicodeFonts($this->default_available_fonts );
4326 }
4327 }
4328
4329 $this->ColorFlag = ($this->FillColor != $this->TextColor); //Restore ColorFlag as well
4330
4331 $this->HREF = $saved[ 'HREF' ];
4332 $this->U = $saved[ 'underline' ];
4333 $this->S = $saved[ 'smCaps' ];
4334 $this->strike = $saved[ 'strike' ];
4335 $this->textshadow = $saved[ 'textshadow' ]; // mPDF 5.3.A2
4336 $this->SUP = $saved[ 'SUP' ];
4337 $this->SUB = $saved[ 'SUB' ];
4338 $this->LineWidth = $saved[ 'linewidth' ];
4339 $this->DrawColor = $saved[ 'drawcolor' ];
4340 $this->outline_on = $saved[ 'is_outline' ];
4341 $this->outlineparam = $saved[ 'outlineparam' ];
4342 $this->inlineDisplayOff = $saved['display_off'];
4343
4344 $this->toupper = $saved[ 'toupper' ];
4345 $this->tolower = $saved[ 'tolower' ];
4346 $this->capitalize = $saved[ 'capitalize' ];
4347 $this->kerning = $saved[ 'fontkerning' ];
4348 $this->lSpacingCSS = $saved[ 'lSpacingCSS' ];
4349 if (($this->lSpacingCSS || $this->lSpacingCSS==='0') && strtoupper($this->lSpacingCSS) != 'NORMAL') {
4350 $this->fixedlSpacing = $this->ConvertSize($this->lSpacingCSS,$this->FontSize);
4351 }
4352 else { $this->fixedlSpacing = false; }
4353 $this->wSpacingCSS = $saved[ 'wSpacingCSS' ];
4354 if ($this->wSpacingCSS && strtoupper($this->wSpacingCSS) != 'NORMAL') {
4355 $this->minwSpacing = $this->ConvertSize($this->wSpacingCSS,$this->FontSize);
4356 }
4357 else { $this->minwSpacing = 0; }
4358
4359 $this->SetFont($FontFamily, $saved[ 'style' ].($this->U ? 'U' : '').($this->S ? 'S' : ''),$saved[ 'sizePt' ],false);
4360
4361 $this->currentfontstyle = $saved[ 'style' ].($this->U ? 'U' : '').($this->S ? 'S' : '');
4362 $this->currentfontsize = $saved[ 'sizePt' ];
4363 $this->SetStylesArray(array('S'=>$this->S, 'U'=>$this->U, 'B'=>$saved[ 'B' ], 'I'=>$saved[ 'I' ]));
4364
4365 $this->TextColor = $saved[ 'color' ];
4366 $this->FillColor = $saved[ 'bgcolor' ];
4367 $this->colorarray = $saved[ 'colorarray' ];
4368 $cor = $saved[ 'colorarray' ];
4369 if ($cor) $this->SetTColor($cor);
4370 $this->spanbgcolorarray = $saved[ 'bgcolorarray' ];
4371 $cor = $saved[ 'bgcolorarray' ];
4372 if ($cor) $this->SetFColor($cor);
4373 $this->spanborddet = $saved[ 'border' ]; // mPDF 5.3.61
4374 }
4375
4376
4377
4378 // Used when ColActive for tables - updated to return first block with background fill OR borders
4379 function GetFirstBlockFill() {
4380 // Returns the first blocklevel that uses a bgcolor fill
4381 $startfill = 0;
4382 for ($i=1;$i<=$this->blklvl;$i++) {
4383 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'] ) {
4384 $startfill = $i;
4385 break;
4386 }
4387 }
4388 return $startfill;
4389 }
4390
4391 function SetBlockFill($blvl) {
4392 if ($this->blk[$blvl]['bgcolor']) {
4393 $this->SetFColor($this->blk[$blvl]['bgcolorarray']);
4394 return 1;
4395 }
4396 else {
4397 $this->SetFColor($this->ConvertColor(255));
4398 return 0;
4399 }
4400 }
4401
4402
4403 //-------------------------FLOWING BLOCK------------------------------------//
4404 //The following functions were originally written by Damon Kohler //
4405 //--------------------------------------------------------------------------//
4406
4407 function saveFont() {
4408 $saved = array();
4409 $saved[ 'family' ] = $this->FontFamily;
4410 $saved[ 'style' ] = $this->FontStyle;
4411 $saved[ 'sizePt' ] = $this->FontSizePt;
4412 $saved[ 'size' ] = $this->FontSize;
4413 $saved[ 'curr' ] = &$this->CurrentFont;
4414 $saved[ 'color' ] = $this->TextColor;
4415 $saved[ 'spanbgcolor' ] = $this->spanbgcolor;
4416 $saved[ 'spanbgcolorarray' ] = $this->spanbgcolorarray;
4417 $saved[ 'bord' ] = $this->spanborder; // mPDF 5.3.61
4418 $saved[ 'border' ] = $this->spanborddet; // mPDF 5.3.61
4419 $saved[ 'HREF' ] = $this->HREF;
4420 $saved[ 'underline' ] = $this->U;
4421 $saved[ 'smCaps' ] = $this->S;
4422 $saved[ 'strike' ] = $this->strike;
4423 $saved[ 'textshadow' ] = $this->textshadow; // mPDF 5.3.A2
4424 $saved[ 'SUP' ] = $this->SUP;
4425 $saved[ 'SUB' ] = $this->SUB;
4426 $saved[ 'linewidth' ] = $this->LineWidth;
4427 $saved[ 'drawcolor' ] = $this->DrawColor;
4428 $saved[ 'is_outline' ] = $this->outline_on;
4429 $saved[ 'outlineparam' ] = $this->outlineparam;
4430 $saved[ 'ReqFontStyle' ] = $this->ReqFontStyle;
4431 $saved[ 'fontkerning' ] = $this->kerning;
4432 $saved[ 'fixedlSpacing' ] = $this->fixedlSpacing;
4433 $saved[ 'minwSpacing' ] = $this->minwSpacing;
4434 return $saved;
4435 }
4436
4437 function restoreFont( &$saved, $write=true) {
4438 if (!isset($saved) || empty($saved)) return;
4439
4440 $this->FontFamily = $saved[ 'family' ];
4441 $this->FontStyle = $saved[ 'style' ];
4442 $this->FontSizePt = $saved[ 'sizePt' ];
4443 $this->FontSize = $saved[ 'size' ];
4444 $this->CurrentFont = &$saved[ 'curr' ];
4445 $this->TextColor = $saved[ 'color' ];
4446 $this->spanbgcolor = $saved[ 'spanbgcolor' ];
4447 $this->spanbgcolorarray = $saved[ 'spanbgcolorarray' ];
4448 $this->spanborder = $saved[ 'bord' ]; // mPDF 5.3.61
4449 $this->spanborddet = $saved[ 'border' ]; // mPDF 5.3.61
4450 $this->ColorFlag = ($this->FillColor != $this->TextColor); //Restore ColorFlag as well
4451 $this->HREF = $saved[ 'HREF' ];
4452 $this->U = $saved[ 'underline' ];
4453 $this->S = $saved[ 'smCaps' ];
4454 $this->kerning = $saved[ 'fontkerning' ];
4455 $this->fixedlSpacing = $saved[ 'fixedlSpacing' ];
4456 $this->minwSpacing = $saved[ 'minwSpacing' ];
4457 $this->strike = $saved[ 'strike' ];
4458 $this->textshadow = $saved[ 'textshadow' ]; // mPDF 5.3.A2
4459 $this->SUP = $saved[ 'SUP' ];
4460 $this->SUB = $saved[ 'SUB' ];
4461 $this->LineWidth = $saved[ 'linewidth' ];
4462 $this->DrawColor = $saved[ 'drawcolor' ];
4463 $this->outline_on = $saved[ 'is_outline' ];
4464 $this->outlineparam = $saved[ 'outlineparam' ];
4465 if ($write) {
4466 $this->SetFont($saved[ 'family' ],$saved[ 'style' ].($this->U ? 'U' : '').($this->S ? 'S' : ''),$saved[ 'sizePt' ],true,true); // force output
4467 $fontout = (sprintf('BT /F%d %.3F Tf ET', $this->CurrentFont['i'], $this->FontSizePt));
4468 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); }
4469 $this->pageoutput[$this->page]['Font'] = $fontout;
4470 }
4471 else
4472 $this->SetFont($saved[ 'family' ],$saved[ 'style' ].($this->U ? 'U' : '').($this->S ? 'S' : ''),$saved[ 'sizePt' ]);
4473 $this->ReqFontStyle = $saved[ 'ReqFontStyle' ];
4474 }
4475
4476 function newFlowingBlock( $w, $h, $a = '', $is_table = false, $is_list = false, $blockstate = 0, $newblock=true, $blockdir='ltr')
4477 {
4478 if (!$a) {
4479 if ($blockdir=='rtl') { $a = 'R'; }
4480 else { $a = 'L'; }
4481 }
4482 $this->flowingBlockAttr[ 'width' ] = ($w * _MPDFK);
4483 // line height in user units
4484 $this->flowingBlockAttr[ 'is_table' ] = $is_table;
4485 $this->flowingBlockAttr[ 'is_list' ] = $is_list;
4486 $this->flowingBlockAttr[ 'height' ] = $h;
4487 $this->flowingBlockAttr[ 'lineCount' ] = 0;
4488 $this->flowingBlockAttr[ 'align' ] = $a;
4489 $this->flowingBlockAttr[ 'font' ] = array();
4490 $this->flowingBlockAttr[ 'content' ] = array();
4491 $this->flowingBlockAttr[ 'contentB' ] = array(); // mPDF 5.3.61
4492 $this->flowingBlockAttr[ 'contentWidth' ] = 0;
4493 $this->flowingBlockAttr[ 'blockstate' ] = $blockstate;
4494
4495 $this->flowingBlockAttr[ 'newblock' ] = $newblock;
4496 $this->flowingBlockAttr[ 'valign' ] = 'M';
4497 $this->flowingBlockAttr['blockdir'] = $blockdir;
4498
4499 }
4500
4501 function finishFlowingBlock($endofblock=false, $next='') {
4502 $currentx = $this->x;
4503 //prints out the last chunk
4504 $is_table = $this->flowingBlockAttr[ 'is_table' ];
4505 $is_list = $this->flowingBlockAttr[ 'is_list' ];
4506 $maxWidth =& $this->flowingBlockAttr[ 'width' ];
4507 $lineHeight =& $this->flowingBlockAttr[ 'height' ];
4508 $align =& $this->flowingBlockAttr[ 'align' ];
4509 $content =& $this->flowingBlockAttr[ 'content' ];
4510 $contentB =& $this->flowingBlockAttr[ 'contentB' ]; // mPDF 5.3.61
4511 $font =& $this->flowingBlockAttr[ 'font' ];
4512 $contentWidth =& $this->flowingBlockAttr[ 'contentWidth' ];
4513 $lineCount =& $this->flowingBlockAttr[ 'lineCount' ];
4514 $valign =& $this->flowingBlockAttr[ 'valign' ];
4515 $blockstate = $this->flowingBlockAttr[ 'blockstate' ];
4516
4517 $newblock = $this->flowingBlockAttr[ 'newblock' ];
4518 $blockdir = $this->flowingBlockAttr['blockdir'];
4519
4520
4521 // *********** BLOCK BACKGROUND COLOR *****************//
4522 if ($this->blk[$this->blklvl]['bgcolor'] && !$is_table) {
4523 $fill = 0;
4524 }
4525 else {
4526 $this->SetFColor($this->ConvertColor(255));
4527 $fill = 0;
4528 }
4529
4530 // Always right trim!
4531 // Right trim content and adjust width if need to justify (later)
4532 // mPDF 5.3.76
4533 if (isset($content[count($content)-1]) && preg_match('/[ ]+$/',$content[count($content)-1], $m)) {
4534 $strip = strlen($m[0]);
4535 $content[count($content)-1] = substr($content[count($content)-1],0,(strlen($content[count($content)-1])-$strip));
4536 $this->restoreFont( $font[ count($content)-1 ],false );
4537 $contentWidth -= $this->GetStringWidth($m[0]) * _MPDFK;
4538 }
4539
4540 // the amount of space taken up so far in user units
4541 $usedWidth = 0;
4542
4543 // COLS
4544 $oldcolumn = $this->CurrCol;
4545
4546 if ($this->ColActive && !$is_table) { $this->breakpoints[$this->CurrCol][] = $this->y; } // *COLUMNS*
4547
4548 // Print out each chunk
4549
4550 /*-- TABLES --*/
4551 if ($is_table) {
4552 $ipaddingL = 0;
4553 $ipaddingR = 0;
4554 $paddingL = 0;
4555 $paddingR = 0;
4556 }
4557 else {
4558 /*-- END TABLES --*/
4559 $ipaddingL = $this->blk[$this->blklvl]['padding_left'];
4560 $ipaddingR = $this->blk[$this->blklvl]['padding_right'];
4561 $paddingL = ($ipaddingL * _MPDFK);
4562 $paddingR = ($ipaddingR * _MPDFK);
4563 $this->cMarginL = $this->blk[$this->blklvl]['border_left']['w'];
4564 $this->cMarginR = $this->blk[$this->blklvl]['border_right']['w'];
4565
4566 // Added mPDF 3.0 Float DIV
4567 $fpaddingR = 0;
4568 $fpaddingL = 0;
4569 /*-- CSS-FLOAT --*/
4570 if (count($this->floatDivs)) {
4571 list($l_exists, $r_exists, $l_max, $r_max, $l_width, $r_width) = $this->GetFloatDivInfo($this->blklvl);
4572 if ($r_exists) { $fpaddingR = $r_width; }
4573 if ($l_exists) { $fpaddingL = $l_width; }
4574 }
4575 /*-- END CSS-FLOAT --*/
4576
4577 $usey = $this->y + 0.002;
4578 if (($newblock) && ($blockstate==1 || $blockstate==3) && ($lineCount == 0) ) {
4579 $usey += $this->blk[$this->blklvl]['margin_top'] + $this->blk[$this->blklvl]['padding_top'] + $this->blk[$this->blklvl]['border_top']['w'];
4580 }
4581 /*-- CSS-IMAGE-FLOAT --*/
4582 // If float exists at this level
4583 if (isset($this->floatmargins['R']) && $usey <= $this->floatmargins['R']['y1'] && $usey >= $this->floatmargins['R']['y0'] && !$this->floatmargins['R']['skipline']) { $fpaddingR += $this->floatmargins['R']['w']; }
4584 if (isset($this->floatmargins['L']) && $usey <= $this->floatmargins['L']['y1'] && $usey >= $this->floatmargins['L']['y0'] && !$this->floatmargins['L']['skipline']) { $fpaddingL += $this->floatmargins['L']['w']; }
4585 /*-- END CSS-IMAGE-FLOAT --*/
4586 } // *TABLES*
4587
4588 // Set Current lineheight (correction factor)
4589 $lhfixed = false;
4590 /*-- LISTS --*/
4591 if ($is_list) {
4592 if (preg_match('/([0-9.,]+)mm/',$this->list_lineheight[$this->listlvl][$this->listOcc],$am)) {
4593 $lhfixed = true;
4594 $def_fontsize = $this->InlineProperties['LISTITEM'][$this->listlvl][$this->listOcc][$this->listnum]['size'];
4595 $this->lineheight_correction = $am[1] / $def_fontsize ;
4596 }
4597 else {
4598 $this->lineheight_correction = $this->list_lineheight[$this->listlvl][$this->listOcc];
4599 }
4600 }
4601 else
4602 /*-- END LISTS --*/
4603 /*-- TABLES --*/
4604 if ($is_table) {
4605 if (preg_match('/([0-9.,]+)mm/',$this->table_lineheight,$am)) {
4606 $lhfixed = true;
4607 $def_fontsize = $this->FontSize; // needs to be default font-size for block ****
4608 $this->lineheight_correction = $lineHeight / $def_fontsize ;
4609 }
4610 else {
4611 $this->lineheight_correction = $this->table_lineheight;
4612 }
4613 }
4614 else
4615 /*-- END TABLES --*/
4616 if (isset($this->blk[$this->blklvl]['line_height']) && $this->blk[$this->blklvl]['line_height']) {
4617 if (preg_match('/([0-9.,]+)mm/',$this->blk[$this->blklvl]['line_height'],$am)) {
4618 $lhfixed = true;
4619 $def_fontsize = $this->blk[$this->blklvl]['InlineProperties']['size']; // needs to be default font-size for block ****
4620 $this->lineheight_correction = $am[1] / $def_fontsize ;
4621 }
4622 else {
4623 $this->lineheight_correction = $this->blk[$this->blklvl]['line_height'];
4624 }
4625 }
4626 else {
4627 $this->lineheight_correction = $this->normalLineheight;
4628 }
4629
4630 // correct lineheight to maximum fontsize
4631 if ($lhfixed) { $maxlineHeight = $this->lineheight; }
4632 else { $maxlineHeight = 0; }
4633 $this->forceExactLineheight = true;
4634 $maxfontsize = 0;
4635 // While we're at it, check if contains cursive text
4636 $checkCursive=false;
4637 if ($this->biDirectional) { $checkCursive=true; } // *RTL*
4638 foreach ( $content as $k => $chunk )
4639 {
4640 $this->restoreFont( $font[ $k ],false );
4641 if (!isset($this->objectbuffer[$k])) {
4642 // Soft Hyphens chr(173)
4643 if (!$this->usingCoreFont) {
4644 $content[$k] = $chunk = str_replace("\xc2\xad",'',$chunk );
4645 if (isset($this->CurrentFont['indic']) && $this->CurrentFont['indic']) { $checkCursive=true; } // *INDIC*
4646 }
4647 else if ($this->FontFamily!='csymbol' && $this->FontFamily!='czapfdingbats') {
4648 $content[$k] = $chunk = str_replace(chr(173),'',$chunk );
4649 }
4650 // Special case of sub/sup carried over on its own to last line
4651 if (($this->SUB || $this->SUP) && count($content)==1) { $actfs = $this->FontSize*100/55; } // 55% is font change for sub/sup
4652 else { $actfs = $this->FontSize; }
4653 if (!$lhfixed) { $maxlineHeight = max($maxlineHeight,$actfs * $this->lineheight_correction ); }
4654 if ($lhfixed && ($actfs > $def_fontsize || ($actfs > ($lineHeight * $this->lineheight_correction) && $is_list))) {
4655 $this->forceExactLineheight = false;
4656 }
4657 $maxfontsize = max($maxfontsize,$actfs);
4658 }
4659 }
4660
4661 if(isset($font[count($font)-1])) {
4662 $lastfontreqstyle = $font[count($font)-1]['ReqFontStyle'];
4663 $lastfontstyle = $font[count($font)-1]['style'];
4664 }
4665 else {
4666 $lastfontreqstyle=null;
4667 $lastfontstyle=null;
4668 }
4669 if ($blockdir == 'ltr' && strpos($lastfontreqstyle,"I") !== false && strpos($lastfontstyle,"I") === false) { // Artificial italic
4670 $lastitalic = $this->FontSize*0.15*_MPDFK;
4671 }
4672 else { $lastitalic = 0; }
4673
4674
4675 /*-- LISTS --*/
4676 if ($is_list && is_array($this->bulletarray) && count($this->bulletarray)) {
4677 $actfs = $this->bulletarray['fontsize'];
4678 if (!$lhfixed) { $maxlineHeight = max($maxlineHeight,$actfs * $this->lineheight_correction ); }
4679 if ($lhfixed && $actfs > $def_fontsize) { $this->forceExactLineheight = false; }
4680 $maxfontsize = max($maxfontsize,$actfs);
4681 }
4682 /*-- END LISTS --*/
4683
4684 // when every text item checked i.e. $maxfontsize is set properly
4685
4686 $af = 0; // Above font
4687 $bf = 0; // Below font
4688 $mta = 0; // Maximum top-aligned
4689 $mba = 0; // Maximum bottom-aligned
4690
4691 foreach ( $content as $k => $chunk )
4692 {
4693 if (isset($this->objectbuffer[$k])) {
4694 $oh = $this->objectbuffer[$k]['OUTER-HEIGHT'];
4695 $va = $this->objectbuffer[$k]['vertical-align']; // = $objattr['vertical-align'] = set as M,T,B,S
4696 if ($lhfixed && $oh > $def_fontsize) { $this->forceExactLineheight = false; }
4697
4698 if ($va == 'BS') { // (BASELINE default)
4699 $af = max($af, ($oh - ($maxfontsize * (0.5 + $this->baselineC))));
4700 }
4701 else if ($va == 'M') {
4702 $af = max($af, ($oh - $maxfontsize)/2);
4703 $bf = max($bf, ($oh - $maxfontsize)/2);
4704 }
4705 else if ($va == 'TT') {
4706 $bf = max($bf, ($oh - $maxfontsize));
4707 }
4708 else if ($va == 'TB') {
4709 $af = max($af, ($oh - $maxfontsize));
4710 }
4711 else if ($va == 'T') {
4712 $mta = max($mta, $oh);
4713 }
4714 else if ($va == 'B') {
4715 $mba = max($mba, $oh);
4716 }
4717 }
4718 }
4719 if ((!$lhfixed || !$this->forceExactLineheight) && ($af > (($maxlineHeight - $maxfontsize)/2) || $bf > (($maxlineHeight - $maxfontsize)/2))) {
4720 $maxlineHeight = $maxfontsize + $af + $bf;
4721 }
4722 else if (!$lhfixed) { $af = $bf = ($maxlineHeight - $maxfontsize)/2; }
4723 if ($mta > $maxlineHeight) {
4724 $bf += ($mta - $maxlineHeight);
4725 $maxlineHeight = $mta;
4726 }
4727 if ($mba > $maxlineHeight) {
4728 $af += ($mba - $maxlineHeight);
4729 $maxlineHeight = $mba;
4730 }
4731
4732 $lineHeight = $maxlineHeight;
4733 // If NOT images, and maxfontsize NOT > lineHeight - this value determines text baseline positioning
4734 if ($lhfixed && $af==0 && $bf==0 && $maxfontsize<=($def_fontsize * $this->lineheight_correction * 0.8 )) {
4735 $this->linemaxfontsize = $def_fontsize;
4736 }
4737 else { $this->linemaxfontsize = $maxfontsize; }
4738
4739 // Get PAGEBREAK TO TEST for height including the bottom border/padding
4740 $check_h = max($this->divheight,$lineHeight);
4741
4742 // This fixes a proven bug...
4743 if ($endofblock && $newblock && $blockstate==0 && !$content) { $check_h = 0; }
4744 // but ? needs to fix potentially more widespread...
4745 // if (!$content) { $check_h = 0; }
4746
4747 if ($this->blklvl > 0 && !$is_table) {
4748 if ($endofblock && $blockstate > 1) {
4749 if ($this->blk[$this->blklvl]['page_break_after_avoid']) { $check_h += $lineHeight; }
4750 $check_h += ($this->blk[$this->blklvl]['padding_bottom'] + $this->blk[$this->blklvl]['border_bottom']['w']);
4751 }
4752 if (($newblock && ($blockstate==1 || $blockstate==3) && $lineCount == 0) || ($endofblock && $blockstate > 1 && $lineCount == 0)) {
4753 $check_h += ($this->blk[$this->blklvl]['padding_top'] + $this->blk[$this->blklvl]['margin_top'] + $this->blk[$this->blklvl]['border_top']['w']);
4754 }
4755 }
4756
4757 // Force PAGE break if column height cannot take check-height
4758 if ($this->ColActive && $check_h > ($this->PageBreakTrigger - $this->y0)) {
4759 $this->SetCol($this->NbCol-1);
4760 }
4761
4762
4763 // PAGEBREAK
4764 //'If' below used in order to fix "first-line of other page with justify on" bug
4765 if(!$is_table && ($this->y+$check_h) > $this->PageBreakTrigger and !$this->InFooter and $this->AcceptPageBreak()) {
4766 $bak_x=$this->x;//Current X position
4767 // WORD SPACING
4768 $ws=$this->ws;//Word Spacing
4769 $charspacing=$this->charspacing;//Character Spacing
4770 $this->ResetSpacing();
4771
4772 $this->AddPage($this->CurOrientation);
4773
4774 $this->x=$bak_x;
4775 // Added to correct for OddEven Margins
4776 $currentx += $this->MarginCorrection;
4777 $this->x += $this->MarginCorrection;
4778
4779 // WORD SPACING
4780 $this->SetSpacing($charspacing,$ws);
4781 }
4782
4783 if ($this->keep_block_together && !$is_table && $this->kt_p00 < $this->page && ($this->y+$check_h) > $this->kt_y00) {
4784 $this->printdivbuffer();
4785 $this->keep_block_together = 0;
4786 }
4787
4788 /*-- COLUMNS --*/
4789 // COLS
4790 // COLUMN CHANGE
4791 if ($this->CurrCol != $oldcolumn) {
4792 $currentx += $this->ChangeColumn * ($this->ColWidth+$this->ColGap);
4793 $this->x += $this->ChangeColumn * ($this->ColWidth+$this->ColGap);
4794 $oldcolumn = $this->CurrCol;
4795 }
4796
4797
4798 if ($this->ColActive && !$is_table) { $this->breakpoints[$this->CurrCol][] = $this->y; }
4799 /*-- END COLUMNS --*/
4800
4801 // TOP MARGIN
4802 if ($newblock && ($blockstate==1 || $blockstate==3) && ($this->blk[$this->blklvl]['margin_top']) && $lineCount == 0 && !$is_table && !$is_list) {
4803 $this->DivLn($this->blk[$this->blklvl]['margin_top'],$this->blklvl-1,true,$this->blk[$this->blklvl]['margin_collapse']);
4804 if ($this->ColActive) { $this->breakpoints[$this->CurrCol][] = $this->y; } // *COLUMNS*
4805 }
4806
4807 if ($newblock && ($blockstate==1 || $blockstate==3) && $lineCount == 0 && !$is_table && !$is_list) {
4808 $this->blk[$this->blklvl]['y0'] = $this->y;
4809 $this->blk[$this->blklvl]['startpage'] = $this->page;
4810 if ($this->ColActive) { $this->breakpoints[$this->CurrCol][] = $this->y; } // *COLUMNS*
4811 }
4812
4813 // ADDED for Paragraph_indent
4814 $WidthCorrection = 0;
4815 if (($newblock) && ($blockstate==1 || $blockstate==3) && isset($this->blk[$this->blklvl]['text_indent']) && ($lineCount == 0) && (!$is_table) && (!$is_list) && ($align != 'C')) {
4816 $ti = $this->ConvertSize($this->blk[$this->blklvl]['text_indent'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
4817 $WidthCorrection = ($ti*_MPDFK);
4818 }
4819
4820
4821 // PADDING and BORDER spacing/fill
4822 if (($newblock) && ($blockstate==1 || $blockstate==3) && (($this->blk[$this->blklvl]['padding_top']) || ($this->blk[$this->blklvl]['border_top'])) && ($lineCount == 0) && (!$is_table) && (!$is_list)) {
4823 // $state = 0 normal; 1 top; 2 bottom; 3 top and bottom
4824 $this->DivLn($this->blk[$this->blklvl]['padding_top'] + $this->blk[$this->blklvl]['border_top']['w'],-3,true,false,1);
4825 if ($this->ColActive) { $this->breakpoints[$this->CurrCol][] = $this->y; } // *COLUMNS*
4826 $this->x = $currentx;
4827 }
4828
4829
4830 // Added mPDF 3.0 Float DIV
4831 $fpaddingR = 0;
4832 $fpaddingL = 0;
4833 /*-- CSS-FLOAT --*/
4834 if (count($this->floatDivs)) {
4835 list($l_exists, $r_exists, $l_max, $r_max, $l_width, $r_width) = $this->GetFloatDivInfo($this->blklvl);
4836 if ($r_exists) { $fpaddingR = $r_width; }
4837 if ($l_exists) { $fpaddingL = $l_width; }
4838 }
4839 /*-- END CSS-FLOAT --*/
4840
4841 $usey = $this->y + 0.002;
4842 if (($newblock) && ($blockstate==1 || $blockstate==3) && ($lineCount == 0) ) {
4843 $usey += $this->blk[$this->blklvl]['margin_top'] + $this->blk[$this->blklvl]['padding_top'] + $this->blk[$this->blklvl]['border_top']['w'];
4844 }
4845 /*-- CSS-IMAGE-FLOAT --*/
4846 // If float exists at this level
4847 if (isset($this->floatmargins['R']) && $usey <= $this->floatmargins['R']['y1'] && $usey >= $this->floatmargins['R']['y0'] && !$this->floatmargins['R']['skipline']) { $fpaddingR += $this->floatmargins['R']['w']; }
4848 if (isset($this->floatmargins['L']) && $usey <= $this->floatmargins['L']['y1'] && $usey >= $this->floatmargins['L']['y0'] && !$this->floatmargins['L']['skipline']) { $fpaddingL += $this->floatmargins['L']['w']; }
4849 /*-- END CSS-IMAGE-FLOAT --*/
4850
4851 if ($content) {
4852
4853 // In FinishFlowing Block no lines are justified as it is always last line
4854 // but if orphansAllowed have allowed content width to go over max width, use J charspacing to compress line
4855 // JUSTIFICATION J - NOT!
4856 $nb_carac = 0;
4857 $nb_spaces = 0;
4858 $jcharspacing = 0;
4859 $jws = 0;
4860 $inclCursive=false;
4861 foreach ( $content as $k => $chunk ) {
4862 if (!isset($this->objectbuffer[$k]) || (isset($this->objectbuffer[$k]) && !$this->objectbuffer[$k])) {
4863 if ($this->usingCoreFont) {
4864 $chunk = str_replace(chr(160),chr(32),$chunk );
4865 }
4866 else {
4867 $chunk = str_replace(chr(194).chr(160),chr(32),$chunk );
4868 }
4869 $nb_carac += mb_strlen( $chunk, $this->mb_enc );
4870 $nb_spaces += mb_substr_count( $chunk,' ', $this->mb_enc );
4871 if ($checkCursive) {
4872 if (preg_match("/([".$this->pregRTLchars."])/u", $chunk)) { $inclCursive = true; } // *RTL*
4873 if (preg_match("/([".$this->pregHIchars.$this->pregBNchars.$this->pregPAchars."])/u", $chunk)) { $inclCursive = true; } // *INDIC*
4874 }
4875 }
4876 }
4877 // 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)
4878 // If "orphans" in fact is just a final space - ignore this
4879 if (((($contentWidth + $lastitalic) > $maxWidth) && ($content[count($content)-1] != ' ') ) ||
4880 (!$endofblock && $align=='J' && ($next=='image' || $next=='select' || $next=='input' || $next=='textarea' || ($next=='br' && $this->justifyB4br)))
4881 ) {
4882 // WORD SPACING
4883 list($jcharspacing,$jws) = $this->GetJspacing($nb_carac,$nb_spaces,($maxWidth-$lastitalic-$contentWidth-$WidthCorrection-(($this->cMarginL+$this->cMarginR)*_MPDFK)-($paddingL+$paddingR +(($fpaddingL + $fpaddingR) * _MPDFK) )),$inclCursive);
4884 }
4885 // Check if will fit at word/char spacing of previous line - if so continue it
4886 // but only allow a maximum of $this->jSmaxWordLast and $this->jSmaxCharLast
4887 else if ($contentWidth < ($maxWidth - $lastitalic-$WidthCorrection - (($this->cMarginL+$this->cMarginR)* _MPDFK) - ($paddingL+$paddingR +(($fpaddingL + $fpaddingR) * _MPDFK))) && !$this->fixedlSpacing) {
4888 if ($this->ws > $this->jSmaxWordLast) {
4889 $jws = $this->jSmaxWordLast;
4890 }
4891 if ($this->charspacing > $this->jSmaxCharLast) {
4892 $jcharspacing = $this->jSmaxCharLast;
4893 }
4894 $check = $maxWidth - $lastitalic-$WidthCorrection - $contentWidth - (($this->cMarginL+$this->cMarginR)* _MPDFK) - ($paddingL+$paddingR +(($fpaddingL + $fpaddingR) * _MPDFK) ) - ( $jcharspacing * $nb_carac) - ( $jws * $nb_spaces);
4895 if ($check <= 0) {
4896 $jcharspacing = 0;
4897 $jws = 0;
4898 }
4899 }
4900
4901 $empty = $maxWidth - $lastitalic-$WidthCorrection - $contentWidth - (($this->cMarginL+$this->cMarginR)* _MPDFK) - ($paddingL+$paddingR +(($fpaddingL + $fpaddingR) * _MPDFK) );
4902
4903 $empty -= ($jcharspacing * $nb_carac);
4904 $empty -= ($jws * $nb_spaces);
4905
4906 $empty /= _MPDFK;
4907
4908 if (!$is_table) {
4909 $this->maxPosR = max($this->maxPosR , ($this->w - $this->rMargin - $this->blk[$this->blklvl]['outer_right_margin'] - $empty));
4910 $this->maxPosL = min($this->maxPosL , ($this->lMargin + $this->blk[$this->blklvl]['outer_left_margin'] + $empty));
4911 }
4912
4913 $arraysize = count($content);
4914
4915 $margins = ($this->cMarginL+$this->cMarginR) + ($ipaddingL+$ipaddingR + $fpaddingR + $fpaddingR );
4916
4917 if (!$is_table) { $this->DivLn($lineHeight,$this->blklvl,false); } // false -> don't advance y
4918
4919 // DIRECTIONALITY RTL
4920 $all_rtl = false;
4921 $contains_rtl = false;
4922 /*-- RTL --*/
4923 if ($blockdir == 'rtl' || $this->biDirectional) {
4924 $all_rtl = true;
4925 foreach ( $content as $k => $chunk ) {
4926 $reversed = $this->magic_reverse_dir($chunk, false, $blockdir);
4927 if ($reversed > 0) { $contains_rtl = true; }
4928 if ($reversed < 2) { $all_rtl = false; }
4929 $content[$k] = $chunk;
4930 }
4931 if (($blockdir =='rtl' && $contains_rtl) || $all_rtl) {
4932 $content = array_reverse($content,false);
4933 $contentB = array_reverse($contentB,false); // mPDF 5.3.61
4934 }
4935 }
4936 /*-- END RTL --*/
4937
4938 $this->x = $currentx + $this->cMarginL + $ipaddingL + $fpaddingL;
4939 if ($align == 'R') { $this->x += $empty; }
4940 else if ($align == 'J' && $blockdir == 'rtl') { $this->x += $empty; }
4941 else if ($align == 'C') { $this->x += ($empty / 2); }
4942
4943
4944 // Paragraph INDENT
4945 $WidthCorrection = 0;
4946 if (($newblock) && ($blockstate==1 || $blockstate==3) && isset($this->blk[$this->blklvl]['text_indent']) && ($lineCount == 0) && (!$is_table) && (!$is_list) && ($align !='C')) {
4947 $ti = $this->ConvertSize($this->blk[$this->blklvl]['text_indent'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
4948 $this->x += $ti;
4949 }
4950
4951
4952 foreach ( $content as $k => $chunk )
4953 {
4954
4955 // FOR IMAGES
4956 if ((($blockdir == 'rtl') && ($contains_rtl )) || $all_rtl ) { $dirk = $arraysize-1 - $k; } else { $dirk = $k; }
4957
4958 $va = 'M'; // default for text
4959 if (isset($this->objectbuffer[$dirk]) && $this->objectbuffer[$dirk]) {
4960 $xadj = $this->x - $this->objectbuffer[$dirk]['OUTER-X'];
4961 $this->objectbuffer[$dirk]['OUTER-X'] += $xadj;
4962 $this->objectbuffer[$dirk]['BORDER-X'] += $xadj;
4963 $this->objectbuffer[$dirk]['INNER-X'] += $xadj;
4964 $va = $this->objectbuffer[$dirk]['vertical-align'];
4965 $yadj = $this->y - $this->objectbuffer[$dirk]['OUTER-Y'];
4966 if ($va == 'BS') {
4967 $yadj += $af + ($this->linemaxfontsize * (0.5 + $this->baselineC)) - $this->objectbuffer[$dirk]['OUTER-HEIGHT'];
4968 }
4969 else if ($va == 'M' || $va == '') {
4970 $yadj += $af + ($this->linemaxfontsize /2) - ($this->objectbuffer[$dirk]['OUTER-HEIGHT']/2);
4971 }
4972 else if ($va == 'TB') {
4973 $yadj += $af + $this->linemaxfontsize - $this->objectbuffer[$dirk]['OUTER-HEIGHT'];
4974 }
4975 else if ($va == 'TT') {
4976 $yadj += $af;
4977 }
4978 else if ($va == 'B') {
4979 $yadj += $af + $this->linemaxfontsize + $bf - $this->objectbuffer[$dirk]['OUTER-HEIGHT'];
4980 }
4981 else if ($va == 'T') {
4982 $yadj += 0;
4983 }
4984 $this->objectbuffer[$dirk]['OUTER-Y'] += $yadj;
4985 $this->objectbuffer[$dirk]['BORDER-Y'] += $yadj;
4986 $this->objectbuffer[$dirk]['INNER-Y'] += $yadj;
4987 }
4988
4989
4990
4991 // DIRECTIONALITY RTL
4992 if ((($blockdir == 'rtl') && ($contains_rtl )) || $all_rtl ) { $this->restoreFont( $font[ $arraysize-1 - $k ] ); }
4993 else { $this->restoreFont( $font[ $k ] ); }
4994
4995 $this->SetSpacing(($this->fixedlSpacing*_MPDFK)+$jcharspacing,($this->fixedlSpacing+$this->minwSpacing)*_MPDFK+$jws);
4996 $this->fixedlSpacing = false;
4997 $this->minwSpacing = 0;
4998
4999 // *********** SPAN BACKGROUND COLOR ***************** //
5000 if (isset($this->spanbgcolor) && $this->spanbgcolor) {
5001 $cor = $this->spanbgcolorarray;
5002 $this->SetFColor($cor);
5003 $save_fill = $fill; $spanfill = 1; $fill = 1;
5004 }
5005 // mPDF 5.3.61
5006 if (!empty($this->spanborddet)) {
5007 if (strpos($contentB[$k],'L')!==false && isset($this->spanborddet['L'])) $this->x += $this->spanborddet['L']['w'];
5008 if (strpos($contentB[$k],'L')===false) $this->spanborddet['L']['s'] = $this->spanborddet['L']['w'] = 0;
5009 if (strpos($contentB[$k],'R')===false) $this->spanborddet['R']['s'] = $this->spanborddet['R']['w'] = 0;
5010 }
5011 // WORD SPACING
5012 $stringWidth = $this->GetStringWidth($chunk ) + ( $this->charspacing * mb_strlen($chunk,$this->mb_enc ) / _MPDFK )
5013 + ( $this->ws * mb_substr_count($chunk,' ',$this->mb_enc ) / _MPDFK );
5014 if (isset($this->objectbuffer[$dirk])) {
5015 if ($this->objectbuffer[$dirk]['type']=='dottab') {
5016 $this->objectbuffer[$dirk]['OUTER-WIDTH'] +=$empty;
5017 }
5018 $stringWidth = $this->objectbuffer[$dirk]['OUTER-WIDTH'];
5019 }
5020
5021 if ($stringWidth==0) { $stringWidth = 0.000001; }
5022 if ($k == $arraysize-1) $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) // mPDF 5.3.07
5023 else $this->Cell( $stringWidth, $lineHeight, $chunk, '', 0, '', $fill, $this->HREF, 0, 0,0,'M', $fill, $af, $bf, true );//first or middle part // mPDF 5.3.07
5024
5025 // mPDF 5.3.61
5026 if (!empty($this->spanborddet)) {
5027 if (strpos($contentB[$k],'R')!==false && $k != $arraysize-1) $this->x += $this->spanborddet['R']['w'];
5028 }
5029 // *********** SPAN BACKGROUND COLOR OFF - RESET BLOCK BGCOLOR ***************** //
5030 if (isset($spanfill) && $spanfill) {
5031 $fill = $save_fill; $spanfill = 0;
5032 if ($fill) { $this->SetFColor($bcor); }
5033 }
5034 }
5035
5036 $this->printobjectbuffer($is_table, $blockdir);
5037
5038
5039 $this->objectbuffer = array();
5040
5041
5042 $this->ResetSpacing();
5043
5044 /*-- LISTS --*/
5045 // LIST BULLETS/NUMBERS
5046 if ($is_list && is_array($this->bulletarray) && ($lineCount == 0) ) {
5047
5048 $savedFont = $this->saveFont();
5049
5050 $bull = $this->bulletarray;
5051 if (isset($bull['level']) && isset($bull['occur']) && isset($this->InlineProperties['LIST'][$bull['level']][$bull['occur']])) {
5052 $this->restoreInlineProperties($this->InlineProperties['LIST'][$bull['level']][$bull['occur']]);
5053 }
5054 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']]); }
5055 if (isset($bull['font']) && $bull['font'] == 'czapfdingbats') {
5056 $this->bullet = true;
5057 $this->SetFont('czapfdingbats','',$this->FontSizePt/2.5);
5058 }
5059 else { $this->SetFont($this->FontFamily,$this->FontStyle,$this->FontSizePt,true,true); } // force output
5060 //Output bullet
5061 $this->x = $currentx;
5062 if (isset($bull['x'])) { $this->x += $bull['x']; }
5063 $this->y -= $lineHeight;
5064 if (is_array($bull['col'])) { $this->SetTColor($bull['col']); }
5065
5066 if (isset($bull['txt'])) { $this->Cell($bull['w'], $lineHeight,$bull['txt'],'','',$bull['align'],0,'',0,-$this->cMarginL, -$this->cMarginR ); }
5067 if (isset($bull['font']) && $bull['font'] == 'czapfdingbats') {
5068 $this->bullet = false;
5069 }
5070 $this->x = $currentx; // Reset
5071 $this->y += $lineHeight;
5072
5073 if ($this->ColActive && !$is_table) { $this->breakpoints[$this->CurrCol][] = $this->y; } // *COLUMNS*
5074
5075 $this->restoreFont( $savedFont );
5076 // $font = array( $savedFont );
5077
5078 $this->bulletarray = array(); // prevents repeat of bullet/number if <li>....<br />.....</li>
5079 }
5080 /*-- END LISTS --*/
5081
5082
5083 } // END IF CONTENT
5084
5085 /*-- CSS-IMAGE-FLOAT --*/
5086 // Update values if set to skipline
5087 if ($this->floatmargins) { $this->_advanceFloatMargins(); }
5088
5089
5090 if ($endofblock && $blockstate>1) {
5091 // If float exists at this level
5092 if (isset($this->floatmargins['R']['y1'])) { $fry1 = $this->floatmargins['R']['y1']; }
5093 else { $fry1 = 0; }
5094 if (isset($this->floatmargins['L']['y1'])) { $fly1 = $this->floatmargins['L']['y1']; }
5095 else { $fly1 = 0; }
5096 if ($this->y < $fry1 || $this->y < $fly1) {
5097 $drop = max($fry1,$fly1) - $this->y;
5098 $this->DivLn($drop);
5099 $this->x = $currentx;
5100 }
5101 }
5102 /*-- END CSS-IMAGE-FLOAT --*/
5103
5104
5105 // PADDING and BORDER spacing/fill
5106 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)) {
5107 // If CSS height set, extend bottom - if on same page as block started, and CSS HEIGHT > actual height,
5108 // and does not force pagebreak
5109 $extra = 0;
5110 if ($this->blk[$this->blklvl]['css_set_height'] && $this->blk[$this->blklvl]['startpage']==$this->page) {
5111 // predicted height
5112 $h1 = ($this->y-$this->blk[$this->blklvl]['y0']) + $this->blk[$this->blklvl]['padding_bottom'] + $this->blk[$this->blklvl]['border_bottom']['w'];
5113 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; }
5114 if($this->y + $this->blk[$this->blklvl]['padding_bottom'] + $this->blk[$this->blklvl]['border_bottom']['w'] + $extra > $this->PageBreakTrigger) {
5115 $extra = $this->PageBreakTrigger - ($this->y + $this->blk[$this->blklvl]['padding_bottom'] + $this->blk[$this->blklvl]['border_bottom']['w']);
5116 }
5117 }
5118
5119 // $state = 0 normal; 1 top; 2 bottom; 3 top and bottom
5120 $this->DivLn($this->blk[$this->blklvl]['padding_bottom'] + $this->blk[$this->blklvl]['border_bottom']['w'] + $extra,-3,true,false,2);
5121 $this->x = $currentx;
5122
5123 if ($this->ColActive) { $this->breakpoints[$this->CurrCol][] = $this->y; } // *COLUMNS*
5124
5125 }
5126
5127 // SET Bottom y1 of block (used for painting borders)
5128 if (($endofblock) && ($blockstate > 1) && (!$is_table) && (!$is_list)) {
5129 $this->blk[$this->blklvl]['y1'] = $this->y;
5130 }
5131
5132 // BOTTOM MARGIN
5133 if (($endofblock) && ($blockstate > 1) && ($this->blk[$this->blklvl]['margin_bottom']) && (!$is_table) && (!$is_list)) {
5134 if($this->y+$this->blk[$this->blklvl]['margin_bottom'] < $this->PageBreakTrigger and !$this->InFooter) {
5135 $this->DivLn($this->blk[$this->blklvl]['margin_bottom'],$this->blklvl-1,true,$this->blk[$this->blklvl]['margin_collapse']);
5136 if ($this->ColActive) { $this->breakpoints[$this->CurrCol][] = $this->y; } // *COLUMNS*
5137 }
5138 }
5139
5140 // Reset lineheight
5141 $lineHeight = $this->divheight;
5142 }
5143
5144
5145
5146
5147
5148 function printobjectbuffer($is_table=false, $blockdir=false) {
5149 if (!$blockdir) { $blockdir = $this->directionality; }
5150 if ($is_table && $this->shrin_k > 1) { $k = $this->shrin_k; }
5151 else { $k = 1; }
5152 $save_y = $this->y;
5153 $save_x = $this->x;
5154 $save_currentfontfamily = $this->FontFamily;
5155 $save_currentfontsize = $this->FontSizePt;
5156 $save_currentfontstyle = $this->FontStyle.($this->U ? 'U' : '').($this->S ? 'S' : '');
5157 if ($blockdir == 'rtl') { $rtlalign = 'R'; } else { $rtlalign = 'L'; }
5158 foreach ($this->objectbuffer AS $ib => $objattr) {
5159 if ($objattr['type'] == 'bookmark' || $objattr['type'] == 'indexentry' || $objattr['type'] == 'toc') {
5160 $x = $objattr['OUTER-X'];
5161 $y = $objattr['OUTER-Y'];
5162 $this->y = $y - $this->FontSize/2;
5163 $this->x = $x;
5164 if ($objattr['type'] == 'bookmark' ) { $this->Bookmark($objattr['CONTENT'],$objattr['bklevel'] ,$y - $this->FontSize); } // *BOOKMARKS*
5165 if ($objattr['type'] == 'indexentry') { $this->IndexEntry($objattr['CONTENT']); } // *INDEX*
5166 if ($objattr['type'] == 'toc') { $this->TOC_Entry($objattr['CONTENT'], $objattr['toclevel'], $objattr['toc_id']); } // *TOC*
5167 }
5168 /*-- ANNOTATIONS --*/
5169 else if ($objattr['type'] == 'annot') {
5170 if ($objattr['POS-X']) { $x = $objattr['POS-X']; }
5171 else if ($this->annotMargin<>0) { $x = -$objattr['OUTER-X']; }
5172 else { $x = $objattr['OUTER-X']; }
5173 if ($objattr['POS-Y']) { $y = $objattr['POS-Y']; }
5174 else { $y = $objattr['OUTER-Y'] - $this->FontSize/2; }
5175 // Create a dummy entry in the _out/columnBuffer with position sensitive data,
5176 // linking $y-1 in the Columnbuffer with entry in $this->columnAnnots
5177 // and when columns are split in length will not break annotation from current line
5178 $this->y = $y-1;
5179 $this->x = $x-1;
5180 $this->Line($x-1,$y-1,$x-1,$y-1);
5181 $this->Annotation($objattr['CONTENT'], $x , $y , $objattr['ICON'], $objattr['AUTHOR'], $objattr['SUBJECT'], $objattr['OPACITY'], $objattr['COLOR'], $objattr['POPUP'], $objattr['FILE']);
5182 }
5183 /*-- END ANNOTATIONS --*/
5184 else {
5185 $y = $objattr['OUTER-Y'];
5186 $x = $objattr['OUTER-X'];
5187 $w = $objattr['OUTER-WIDTH'];
5188 $h = $objattr['OUTER-HEIGHT'];
5189 if (isset($objattr['text'])) { $texto = $objattr['text']; }
5190 $this->y = $y;
5191 $this->x = $x;
5192 if (isset($objattr['fontfamily'])) { $this->SetFont($objattr['fontfamily'],'',$objattr['fontsize'] ); }
5193 }
5194
5195 // HR
5196 if ($objattr['type'] == 'hr') {
5197 $this->SetDColor($objattr['color']);
5198 switch($objattr['align']) {
5199 case 'C':
5200 $empty = $objattr['OUTER-WIDTH'] - $objattr['INNER-WIDTH'];
5201 $empty /= 2;
5202 $x += $empty;
5203 break;
5204 case 'R':
5205 $empty = $objattr['OUTER-WIDTH'] - $objattr['INNER-WIDTH'];
5206 $x += $empty;
5207 break;
5208 }
5209 $oldlinewidth = $this->LineWidth;
5210 $this->SetLineWidth($objattr['linewidth']/$k );
5211 $this->y += ($objattr['linewidth']/2) + $objattr['margin_top']/$k;
5212 $this->Line($x,$this->y,$x+$objattr['INNER-WIDTH'],$this->y);
5213 $this->SetLineWidth($oldlinewidth);
5214 $this->SetDColor($this->ConvertColor(0));
5215 }
5216 // IMAGE
5217 if ($objattr['type'] == 'image') {
5218 // mPDF 5.3.42 VISIBILITY // mPDF 5.3.49
5219 if(isset($objattr['visibility']) && $objattr['visibility']!='visible' && $objattr['visibility']) {
5220 $this->SetVisibility($objattr['visibility']);
5221 }
5222 if (isset($objattr['opacity'])) { $this->SetAlpha($objattr['opacity']); }
5223 $rotate = 0;
5224 $obiw = $objattr['INNER-WIDTH'];
5225 $obih = $objattr['INNER-HEIGHT'];
5226 $sx = $objattr['INNER-WIDTH']*_MPDFK / $objattr['orig_w'];
5227 $sy = abs($objattr['INNER-HEIGHT'])*_MPDFK / abs($objattr['orig_h']);
5228 $sx = ($objattr['INNER-WIDTH']*_MPDFK / $objattr['orig_w']);
5229 $sy = ($objattr['INNER-HEIGHT']*_MPDFK / $objattr['orig_h']);
5230
5231 if (isset($objattr['ROTATE'])) { $rotate = $objattr['ROTATE']; }
5232 if ($rotate==90) {
5233 // Clockwise
5234 $obiw = $objattr['INNER-HEIGHT'];
5235 $obih = $objattr['INNER-WIDTH'];
5236 $tr = $this->transformTranslate(0, -$objattr['INNER-WIDTH'], true) ;
5237 $tr .= ' '. $this->transformRotate(90, $objattr['INNER-X'],($objattr['INNER-Y'] +$objattr['INNER-WIDTH'] ),true) ;
5238 $sx = $obiw*_MPDFK / $objattr['orig_h'];
5239 $sy = $obih*_MPDFK / $objattr['orig_w'];
5240 }
5241 else if ($rotate==-90 || $rotate==270) {
5242 // AntiClockwise
5243 $obiw = $objattr['INNER-HEIGHT'];
5244 $obih = $objattr['INNER-WIDTH'];
5245 $tr = $this->transformTranslate($objattr['INNER-WIDTH'], ($objattr['INNER-HEIGHT']-$objattr['INNER-WIDTH']), true) ;
5246 $tr .= ' '. $this->transformRotate(-90, $objattr['INNER-X'],($objattr['INNER-Y'] +$objattr['INNER-WIDTH'] ),true) ;
5247 $sx = $obiw*_MPDFK / $objattr['orig_h'];
5248 $sy = $obih*_MPDFK / $objattr['orig_w'];
5249 }
5250 else if ($rotate==180) {
5251 // Mirror
5252 $tr = $this->transformTranslate($objattr['INNER-WIDTH'], -$objattr['INNER-HEIGHT'], true) ;
5253 $tr .= ' '. $this->transformRotate(180, $objattr['INNER-X'],($objattr['INNER-Y'] +$objattr['INNER-HEIGHT'] ),true) ;
5254 }
5255 else { $tr = ''; }
5256 $tr = trim($tr);
5257 if ($tr) { $tr .= ' '; }
5258 $gradmask = '';
5259
5260
5261 /*-- BACKGROUNDS --*/
5262 if (isset($objattr['GRADIENT-MASK'])) {
5263 $g = $this->grad->parseMozGradient( $objattr['GRADIENT-MASK'] );
5264 if ($g) {
5265 $dummy = $this->grad->Gradient($objattr['INNER-X'], $objattr['INNER-Y'], $obiw, $obih, $g['type'], $g['stops'], $g['colorspace'], $g['coords'], $g['extend'], true, true);
5266 $gradmask = '/TGS'.count($this->gradients).' gs ';
5267 // $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");
5268 }
5269 }
5270 /*-- END BACKGROUNDS --*/
5271 /*-- IMAGES-WMF --*/
5272 if (isset($objattr['itype']) && $objattr['itype']=='wmf') {
5273 $outstring = sprintf('q '.$tr.'%.3F 0 0 %.3F %.3F %.3F cm /FO%d Do Q', $sx, -$sy, $objattr['INNER-X']*_MPDFK-$sx*$objattr['wmf_x'], (($this->h-$objattr['INNER-Y'])*_MPDFK)+$sy*$objattr['wmf_y'], $objattr['ID']);
5274 }
5275 else
5276 /*-- END IMAGES-WMF --*/
5277 if (isset($objattr['itype']) && $objattr['itype']=='svg') {
5278 $outstring = sprintf('q '.$tr.'%.3F 0 0 %.3F %.3F %.3F cm /FO%d Do Q', $sx, -$sy, $objattr['INNER-X']*_MPDFK-$sx*$objattr['wmf_x'], (($this->h-$objattr['INNER-Y'])*_MPDFK)+$sy*$objattr['wmf_y'], $objattr['ID']);
5279 }
5280 else {
5281 $outstring = sprintf("q ".$tr."%.3F 0 0 %.3F %.3F %.3F cm ".$gradmask."/I%d Do Q",$obiw*_MPDFK, $obih*_MPDFK, $objattr['INNER-X'] *_MPDFK, ($this->h-($objattr['INNER-Y'] +$obih ))*_MPDFK,$objattr['ID'] );
5282 }
5283 $this->_out($outstring);
5284 // LINK
5285 if (isset($objattr['link'])) $this->Link($objattr['INNER-X'],$objattr['INNER-Y'],$objattr['INNER-WIDTH'],$objattr['INNER-HEIGHT'],$objattr['link']);
5286 if (isset($objattr['opacity'])) { $this->SetAlpha(1); }
5287 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); }
5288 // mPDF 5.3.42 VISIBILITY // mPDF 5.3.49
5289 if(isset($objattr['visibility']) && $objattr['visibility']!='visible' && $objattr['visibility']) {
5290 $this->SetVisibility('visible');
5291 }
5292
5293 }
5294
5295 /*-- BARCODES --*/
5296 // BARCODE
5297 if ($objattr['type'] == 'barcode') {
5298 $bgcol = $this->ConvertColor(255);
5299 if (isset($objattr['bgcolor']) && $objattr['bgcolor']) { // mPDF 5.3.A4
5300 $bgcol = $objattr['bgcolor'];
5301 }
5302 $col = $this->ConvertColor(0);
5303 if (isset($objattr['color']) && $objattr['color']) { // mPDF 5.3.A4
5304 $col = $objattr['color'];
5305 }
5306 $this->SetFColor($bgcol);
5307 $this->Rect($objattr['BORDER-X'], $objattr['BORDER-Y'], $objattr['BORDER-WIDTH'], $objattr['BORDER-HEIGHT'], 'F');
5308 $this->SetFColor($this->ConvertColor(255));
5309 if (isset($objattr['BORDER-WIDTH'])) { $this->PaintImgBorder($objattr,$is_table); }
5310 if ($objattr['btype'] == 'EAN13' || $objattr['btype'] == 'ISBN' || $objattr['btype'] == 'ISSN' || $objattr['btype'] == 'UPCA' || $objattr['btype'] == 'UPCE' || $objattr['btype'] == 'EAN8') {
5311 $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);
5312 }
5313 // QR-code
5314 else if ($objattr['btype']=='QR') {
5315 if (!class_exists('QRcode', false)) {
5316 include(_MPDF_PATH.'qrcode/qrcode.class.php');
5317 }
5318 $this->qrcode = new QRcode($objattr['code'], $objattr['errorlevel']);
5319 $this->qrcode->displayFPDF($this, $objattr['INNER-X'], $objattr['INNER-Y'], $objattr['bsize']*25, array(255,255,255), array(0,0,0));
5320 }
5321 else {
5322 $this->WriteBarcode2($objattr['code'], $objattr['INNER-X'], $objattr['INNER-Y'], $objattr['bsize'], $objattr['bheight'], $bgcol, $col, $objattr['btype'], $objattr['pr_ratio'], $k);
5323 }
5324 }
5325 /*-- END BARCODES --*/
5326
5327 // mPDF 5.3.A5
5328 // TEXT CIRCLE
5329 if ($objattr['type'] == 'textcircle') {
5330 $bgcol = $this->ConvertColor(255);
5331 if (isset($objattr['bgcolor']) && $objattr['bgcolor']) {
5332 $bgcol = $objattr['bgcolor'];
5333 }
5334 $col = $this->ConvertColor(0);
5335 if (isset($objattr['color']) && $objattr['color']) {
5336 $col = $objattr['color'];
5337 }
5338 $this->SetTColor($col);
5339 $this->SetFColor($bgcol);
5340 $this->Rect($objattr['BORDER-X'], $objattr['BORDER-Y'], $objattr['BORDER-WIDTH'], $objattr['BORDER-HEIGHT'], 'F');
5341 $this->SetFColor($this->ConvertColor(255));
5342 if (isset($objattr['BORDER-WIDTH'])) { $this->PaintImgBorder($objattr,$is_table); }
5343 if (!class_exists('directw', false)) { include(_MPDF_PATH.'classes/directw.php'); }
5344 if (empty($this->directw)) { $this->directw = new directw($this); }
5345 $save_lmfs = $this->linemaxfontsize;
5346 $this->linemaxfontsize = 0;
5347 if (isset($objattr['top-text'])) {
5348 $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']);
5349 }
5350 if (isset($objattr['bottom-text'])) {
5351 $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']);
5352 }
5353 $this->linemaxfontsize = $save_lmfs;
5354 }
5355
5356 $this->ResetSpacing();
5357
5358 // DOT-TAB
5359 if ($objattr['type'] == 'dottab') {
5360 $sp = $this->GetStringWidth(' ');
5361 $nb=floor(($w-2*$sp)/$this->GetStringWidth('.'));
5362 if ($nb>0) { $dots=' '.str_repeat('.',$nb).' '; }
5363 else { $dots=' '; }
5364 $col = $this->ConvertColor(0);
5365 if (isset($objattr['colorarray']) && is_array($objattr['colorarray'])) {
5366 $col = $objattr['colorarray'];
5367 }
5368 $this->SetTColor($col);
5369 // mPDF 5.3.A3
5370 $save_sbd = $this->spanborddet;
5371 $save_u = $this->U;
5372 $save_s = $this->strike;
5373 $this->spanborddet = '';
5374 $this->U = false;
5375 $this->strike = false;
5376 $this->Cell($w,$h,$dots,0,0,'C');
5377 $this->spanborddet = $save_sbd;
5378 $this->U = $save_u;
5379 $this->strike = $save_s;
5380 // mPDF 5.0
5381 $this->SetTColor($this->ConvertColor(0));
5382 }
5383
5384 /*-- FORMS --*/
5385 // TEXT/PASSWORD INPUT
5386 if ($objattr['type'] == 'input' && ($objattr['subtype'] == 'TEXT' || $objattr['subtype'] == 'PASSWORD')) {
5387 $this->form->print_ob_text($objattr,$w,$h,$texto,$rtlalign,$k,$blockdir);
5388 }
5389
5390 // TEXTAREA
5391 if ($objattr['type'] == 'textarea') {
5392 $this->form->print_ob_textarea($objattr,$w,$h,$texto,$rtlalign,$k,$blockdir);
5393 }
5394
5395 // SELECT
5396 if ($objattr['type'] == 'select') {
5397 $this->form->print_ob_select($objattr,$w,$h,$texto,$rtlalign,$k,$blockdir);
5398 }
5399
5400
5401 // INPUT/BUTTON as IMAGE
5402 if ($objattr['type'] == 'input' && $objattr['subtype'] == 'IMAGE') {
5403 $this->form->print_ob_imageinput($objattr,$w,$h,$texto,$rtlalign,$k,$blockdir);
5404 }
5405
5406 // BUTTON
5407 if ($objattr['type'] == 'input' && ($objattr['subtype'] == 'SUBMIT' || $objattr['subtype'] == 'RESET' || $objattr['subtype'] == 'BUTTON')) {
5408 $this->form->print_ob_button($objattr,$w,$h,$texto,$rtlalign,$k,$blockdir);
5409 }
5410
5411 // CHECKBOX
5412 if ($objattr['type'] == 'input' && ($objattr['subtype'] == 'CHECKBOX')) {
5413 $this->form->print_ob_checkbox($objattr,$w,$h,$texto,$rtlalign,$k,$blockdir,$x,$y);
5414 }
5415 // RADIO
5416 if ($objattr['type'] == 'input' && ($objattr['subtype'] == 'RADIO')) {
5417 $this->form->print_ob_radio($objattr,$w,$h,$texto,$rtlalign,$k,$blockdir,$x,$y);
5418 }
5419 /*-- END FORMS --*/
5420 }
5421 $this->SetFont($save_currentfontfamily,$save_currentfontstyle,$save_currentfontsize);
5422 $this->y = $save_y;
5423 $this->x = $save_x;
5424 unset($content);
5425 }
5426
5427
5428 function WriteFlowingBlock( $s)
5429 {
5430 $currentx = $this->x;
5431 $is_table = $this->flowingBlockAttr[ 'is_table' ];
5432 $is_list = $this->flowingBlockAttr[ 'is_list' ];
5433 // width of all the content so far in points
5434 $contentWidth =& $this->flowingBlockAttr[ 'contentWidth' ];
5435 // cell width in points
5436 $maxWidth =& $this->flowingBlockAttr[ 'width' ];
5437 $lineCount =& $this->flowingBlockAttr[ 'lineCount' ];
5438 // line height in user units
5439 $lineHeight =& $this->flowingBlockAttr[ 'height' ];
5440 $align =& $this->flowingBlockAttr[ 'align' ];
5441 $content =& $this->flowingBlockAttr[ 'content' ];
5442 $contentB =& $this->flowingBlockAttr[ 'contentB' ]; // mPDF 5.3.61
5443 $font =& $this->flowingBlockAttr[ 'font' ];
5444 $valign =& $this->flowingBlockAttr[ 'valign' ];
5445 $blockstate = $this->flowingBlockAttr[ 'blockstate' ];
5446
5447 $newblock = $this->flowingBlockAttr[ 'newblock' ];
5448 $blockdir = $this->flowingBlockAttr['blockdir'];
5449 // *********** BLOCK BACKGROUND COLOR ***************** //
5450 if ($this->blk[$this->blklvl]['bgcolor'] && !$is_table) {
5451 $fill = 0;
5452 }
5453 else {
5454 $this->SetFColor($this->ConvertColor(255));
5455 $fill = 0;
5456 }
5457 $font[] = $this->saveFont();
5458 $content[] = '';
5459 $contentB[] = ''; // mPDF 5.3.61
5460 $currContent =& $content[ count( $content ) - 1 ];
5461 // where the line should be cutoff if it is to be justified
5462 $cutoffWidth = $contentWidth;
5463
5464 $curlyquote = mb_convert_encoding("\xe2\x80\x9e",$this->mb_enc,'UTF-8');
5465 $curlylowquote = mb_convert_encoding("\xe2\x80\x9d",$this->mb_enc,'UTF-8');
5466
5467 $CJKoverflow = false;
5468
5469 // COLS
5470 $oldcolumn = $this->CurrCol;
5471
5472 if ($this->ColActive && !$is_table) { $this->breakpoints[$this->CurrCol][] = $this->y; } // *COLUMNS*
5473
5474 /*-- TABLES --*/
5475 if ($is_table) {
5476 $ipaddingL = 0;
5477 $ipaddingR = 0;
5478 $paddingL = 0;
5479 $paddingR = 0;
5480 $cpaddingadjustL = 0;
5481 $cpaddingadjustR = 0;
5482 // Added mPDF 3.0
5483 $fpaddingR = 0;
5484 $fpaddingL = 0;
5485 }
5486 else {
5487 /*-- END TABLES --*/
5488 $ipaddingL = $this->blk[$this->blklvl]['padding_left'];
5489 $ipaddingR = $this->blk[$this->blklvl]['padding_right'];
5490 $paddingL = ($ipaddingL * _MPDFK);
5491 $paddingR = ($ipaddingR * _MPDFK);
5492 $this->cMarginL = $this->blk[$this->blklvl]['border_left']['w'];
5493 $cpaddingadjustL = -$this->cMarginL;
5494 $this->cMarginR = $this->blk[$this->blklvl]['border_right']['w'];
5495 $cpaddingadjustR = -$this->cMarginR;
5496 // Added mPDF 3.0 Float DIV
5497 $fpaddingR = 0;
5498 $fpaddingL = 0;
5499 /*-- CSS-FLOAT --*/
5500 if (count($this->floatDivs)) {
5501 list($l_exists, $r_exists, $l_max, $r_max, $l_width, $r_width) = $this->GetFloatDivInfo($this->blklvl);
5502 if ($r_exists) { $fpaddingR = $r_width; }
5503 if ($l_exists) { $fpaddingL = $l_width; }
5504 }
5505 /*-- END CSS-FLOAT --*/
5506
5507 $usey = $this->y + 0.002;
5508 if (($newblock) && ($blockstate==1 || $blockstate==3) && ($lineCount == 0) ) {
5509 $usey += $this->blk[$this->blklvl]['margin_top'] + $this->blk[$this->blklvl]['padding_top'] + $this->blk[$this->blklvl]['border_top']['w'];
5510 }
5511 /*-- CSS-IMAGE-FLOAT --*/
5512 // If float exists at this level
5513 if (isset($this->floatmargins['R']) && $usey <= $this->floatmargins['R']['y1'] && $usey >= $this->floatmargins['R']['y0'] && !$this->floatmargins['R']['skipline']) { $fpaddingR += $this->floatmargins['R']['w']; }
5514 if (isset($this->floatmargins['L']) && $usey <= $this->floatmargins['L']['y1'] && $usey >= $this->floatmargins['L']['y0'] && !$this->floatmargins['L']['skipline']) { $fpaddingL += $this->floatmargins['L']['w']; }
5515 /*-- END CSS-IMAGE-FLOAT --*/
5516 } // *TABLES*
5517
5518 //OBJECTS - IMAGES & FORM Elements (NB has already skipped line/page if required - in printbuffer)
5519 if (substr($s,0,3) == "\xbb\xa4\xac") { //identifier has been identified!
5520 $objattr = $this->_getObjAttr($s);
5521 $h_corr = 0;
5522 if ($is_table) { // *TABLES*
5523 $maximumW = ($maxWidth/_MPDFK) - ($this->cellPaddingL + $this->cMarginL + $this->cellPaddingR + $this->cMarginR); // *TABLES*
5524 } // *TABLES*
5525 else { // *TABLES*
5526 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']; }
5527 $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 );
5528 } // *TABLES*
5529 $objattr = $this->inlineObject($objattr['type'],$this->lMargin + $fpaddingL + ($contentWidth/_MPDFK),($this->y + $h_corr), $objattr, $this->lMargin,($contentWidth/_MPDFK),$maximumW,$lineHeight,true,$is_table);
5530
5531 // SET LINEHEIGHT for this line ================ RESET AT END
5532 $lineHeight = MAX($lineHeight,$objattr['OUTER-HEIGHT']);
5533 $this->objectbuffer[count($content)-1] = $objattr;
5534 // if (isset($objattr['vertical-align'])) { $valign = $objattr['vertical-align']; }
5535 // else { $valign = ''; }
5536 $contentWidth += ($objattr['OUTER-WIDTH'] * _MPDFK);
5537 return;
5538 }
5539
5540 // mPDF 5.3.61
5541 $lbw = $rbw = 0; // Border widths
5542 if (!empty($this->spanborddet)) {
5543 if (isset($this->spanborddet['L'])) $lbw = $this->spanborddet['L']['w'];
5544 if (isset($this->spanborddet['R'])) $rbw = $this->spanborddet['R']['w'];
5545 }
5546
5547 if ($this->usingCoreFont) {
5548 $tmp = strlen( $s );
5549 }
5550 else {
5551 $tmp = mb_strlen( $s, $this->mb_enc );
5552 }
5553
5554 $orphs = 0;
5555 $check = 0;
5556
5557 // for every character in the string
5558 for ( $i = 0; $i < $tmp; $i++ ) {
5559 // extract the current character
5560 // get the width of the character in points
5561 if ($this->usingCoreFont) {
5562 $c = $s[$i];
5563 // Soft Hyphens chr(173)
5564 // mPDF 5.3.07
5565 $cw = ($this->GetCharWidthCore($c) * _MPDFK); // mPDF 5.3.04
5566 if ($this->kerning && $this->useKerning && $i > 0) {
5567 if (isset($this->CurrentFont['kerninfo'][$s[($i-1)]][$c])) {
5568 $cw += ($this->CurrentFont['kerninfo'][$s[($i-1)]][$c] * $this->FontSizePt / 1000 );
5569 }
5570 }
5571 }
5572 else {
5573 $c = mb_substr($s,$i,1,$this->mb_enc );
5574 $cw = ($this->GetCharWidthNonCore($c, false) * _MPDFK); // mPDF 5.3.04
5575 if ($this->kerning && $this->useKerning && $i > 0) {
5576 $lastc = mb_substr($s,($i-1),1,$this->mb_enc );
5577 $ulastc = $this->UTF8StringToArray($lastc, false);
5578 $uc = $this->UTF8StringToArray($c, false);
5579 if (isset($this->CurrentFont['kerninfo'][$ulastc[0]][$uc[0]])) {
5580 $cw += ($this->CurrentFont['kerninfo'][$ulastc[0]][$uc[0]] * $this->FontSizePt / 1000 );
5581 }
5582 }
5583 }
5584
5585 // mPDF 5.3.61
5586 if ($i==0) {
5587 $cw += $lbw*_MPDFK;
5588 $contentB[(count($contentB)-1)] .= 'L';
5589 }
5590 if ($i==($tmp-1)) {
5591 $cw += $rbw*_MPDFK;
5592 $contentB[(count($contentB)-1)] .= 'R';
5593 }
5594
5595 if ($c==' ') { $check = 1; }
5596
5597 // CHECK for ORPHANS
5598 else if ($c=='.' || $c==',' || $c==')' || $c==']' || $c==';' || $c==':' || $c=='!' || $c=='?'|| $c=='"' || $c==$curlyquote || $c==$curlylowquote) {$check++; }
5599 /*-- CJK-FONTS --*/
5600 else if ($this->checkCJK) { // mPDF 5.3.07
5601 if ((!$is_table && $this->CJKfollowing && preg_match("/[".$this->CJKfollowing."]/u", $c)) || ($is_table && preg_match("/[".$this->CJKoverflow ."]/u", $c))) { $check++; }
5602 else { $check = 0; }
5603 }
5604 /*-- END CJK-FONTS --*/
5605 else { $check = 0; }
5606
5607 // There's an orphan '. ' or ', ' or <sup>32</sup> about to be cut off at the end of line
5608 if($check==1) {
5609 $currContent .= $c;
5610 $cutoffWidth = $contentWidth;
5611 $contentWidth += $cw;
5612 continue;
5613 }
5614 if(($this->SUP || $this->SUB) && ($orphs < $this->orphansAllowed)) { // ? disable orphans in table if borders used
5615 $currContent .= $c;
5616 $cutoffWidth = $contentWidth;
5617 $contentWidth += $cw;
5618 $orphs++;
5619 continue;
5620 }
5621 else { $orphs = 0; }
5622
5623 // ADDED for Paragraph_indent
5624 $WidthCorrection = 0;
5625 if (($newblock) && ($blockstate==1 || $blockstate==3) && isset($this->blk[$this->blklvl]['text_indent']) && ($lineCount == 0) && (!$is_table) && (!$is_list) && ($align != 'C')) {
5626 $ti = $this->ConvertSize($this->blk[$this->blklvl]['text_indent'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
5627 $WidthCorrection = ($ti*_MPDFK);
5628 }
5629
5630 // Added mPDF 3.0 Float DIV
5631 $fpaddingR = 0;
5632 $fpaddingL = 0;
5633 /*-- CSS-FLOAT --*/
5634 if (count($this->floatDivs)) {
5635 list($l_exists, $r_exists, $l_max, $r_max, $l_width, $r_width) = $this->GetFloatDivInfo($this->blklvl);
5636 if ($r_exists) { $fpaddingR = $r_width; }
5637 if ($l_exists) { $fpaddingL = $l_width; }
5638 }
5639 /*-- END CSS-FLOAT --*/
5640
5641 $usey = $this->y + 0.002;
5642 if (($newblock) && ($blockstate==1 || $blockstate==3) && ($lineCount == 0) ) {
5643 $usey += $this->blk[$this->blklvl]['margin_top'] + $this->blk[$this->blklvl]['padding_top'] + $this->blk[$this->blklvl]['border_top']['w'];
5644 }
5645
5646 /*-- CSS-IMAGE-FLOAT --*/
5647 // If float exists at this level
5648 if (isset($this->floatmargins['R']) && $usey <= $this->floatmargins['R']['y1'] && $usey >= $this->floatmargins['R']['y0'] && !$this->floatmargins['R']['skipline']) { $fpaddingR += $this->floatmargins['R']['w']; }
5649 if (isset($this->floatmargins['L']) && $usey <= $this->floatmargins['L']['y1'] && $usey >= $this->floatmargins['L']['y0'] && !$this->floatmargins['L']['skipline']) { $fpaddingL += $this->floatmargins['L']['w']; }
5650 /*-- END CSS-IMAGE-FLOAT --*/
5651
5652
5653
5654 // try adding another char
5655 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
5656 // it won't fit, output what we already have
5657 $lineCount++;
5658
5659 // contains any content that didn't make it into this print
5660 $savedContent = '';
5661 $savedContentB = ''; // mPDF 5.3.61
5662 $savedFont = array();
5663 $savedObj = array();
5664
5665 // cut off and save any partial words at the end of the string
5666 $words = explode( ' ', $currContent );
5667 ///////////////////
5668 // HYPHENATION
5669 $currWord = $words[count($words)-1] ;
5670 $success = false;
5671 /*-- HYPHENATION --*/
5672 // Soft Hyphens chr(173)
5673 if ((!$this->usingCoreFont && preg_match("/\xc2\xad/",$currWord)) || ($this->usingCoreFont && preg_match("/".chr(173)."/",$currWord) && ($this->FontFamily!='csymbol' && $this->FontFamily!='czapfdingbats')) ) {
5674 $rem = $maxWidth - $WidthCorrection - (($this->cMarginL+$this->cMarginR)*_MPDFK) - ($paddingL+$paddingR +(($fpaddingL + $fpaddingR) * _MPDFK) );
5675 list($success,$pre,$post,$prelength) = $this->softHyphenate($currWord, (($rem-$cutoffWidth)/_MPDFK -$this->GetCharWidthNonCore(" ", false)) ); // mPDF 5.3.04
5676 }
5677
5678 if (!$success && ($this->hyphenate || ($this->hyphenateTables && $is_table))) {
5679 // Look ahead to get current word
5680 for($ac = $i; $ac<(mb_strlen($s)-1); $ac++) {
5681 $addc = mb_substr($s,$ac,1,$this->mb_enc );
5682 if ($addc == ' ') { break; }
5683 $currWord .= $addc;
5684 }
5685 $rem = $maxWidth - $WidthCorrection - (($this->cMarginL+$this->cMarginR)*_MPDFK) - ($paddingL+$paddingR +(($fpaddingL + $fpaddingR) * _MPDFK) );
5686 list($success,$pre,$post,$prelength) = $this->hyphenateWord($currWord, (($rem-$cutoffWidth)/_MPDFK -$this->GetCharWidth(" ", false)) );
5687 }
5688 if ($success) {
5689 $already = array_pop( $words );
5690 $forward = mb_substr($already,$prelength,mb_strlen($already, $this->mb_enc), $this->mb_enc);
5691 $words[] = $pre.'-';
5692 $words[] = $forward;
5693 $currContent = mb_substr($currContent,0,mb_strlen($currContent, $this->mb_enc)+1-mb_strlen($post, $this->mb_enc), $this->mb_enc) . '-';
5694 }
5695 /*-- END HYPHENATION --*/
5696
5697
5698 // if it looks like we didn't finish any words for this chunk
5699 if ( count( $words ) == 1 ) {
5700 // TO correct for error when word too wide for page - but only when one long word from left to right margin
5701 if (count($content) == 1 && $currContent != ' ') {
5702
5703 /////////////////////////////////////////////////////////////////////////////////////
5704
5705
5706 $lastchar = mb_substr($words[0],mb_strlen($words[0], $this->mb_enc)-1, 1, $this->mb_enc);
5707 /*-- CJK-FONTS --*/
5708 // mPDF 5.3.07
5709 if ($this->checkCJK) {
5710 // Last character that fits is not allowed to end a line - move lastchar(s) to start of next line
5711 if (!$is_table && preg_match("/[".$this->CJKleading."]/u", $lastchar)) {
5712 //move lastchar(s) to next line
5713 $m0 = $lastchar;
5714 $m1 = $c;
5715 while(preg_match("/[".$this->CJKleading."]/u", $m0) && mb_strlen($words[0], $this->mb_enc)>2) {
5716 // trim last letter off word[0]
5717 $words[0] = mb_substr($words[0],0,mb_strlen($words[0], $this->mb_enc)-1, $this->mb_enc);
5718 // and add it to savedContent for next line
5719 $savedContent = $m0.$savedContent;
5720 $m1 = $lastchar;
5721 $lastchar = mb_substr($words[0],mb_strlen($words[0], $this->mb_enc)-1, 1, $this->mb_enc);
5722 $m0 = $lastchar;
5723 }
5724 }
5725 // Next character is not allowed to start a new line - move lastchar(s) to next line
5726 else if (!$is_table && preg_match("/[".$this->CJKfollowing."]/u", $c)) {
5727 // try squeezing another character(s) onto this line = Oikomi
5728 if ($this->allowCJKorphans) {
5729 $lookahead = mb_substr($s,$i+1,1,$this->mb_enc );
5730 //if lookahead is not another following char
5731 if ($lookahead && !preg_match("/[".$this->CJKfollowing."]/u", $lookahead)) {
5732 $currContent .= $c;
5733 $cutoffWidth = $contentWidth;
5734 $contentWidth += $cw;
5735 if ($this->allowCJKoverflow && !$is_table && preg_match("/[".$this->CJKoverflow."]/u", $c)) { $CJKoverflow = true; }
5736 continue;
5737 }
5738 }
5739 // or move lastchar(s) to next line to keep $c company = Oidashi
5740 $m0 = $lastchar;
5741 $m1 = $c;
5742 while(preg_match("/[".$this->CJKfollowing."]/u", $m1) && mb_strlen($words[0], $this->mb_enc)>2) {
5743 // trim last letter off word[0]
5744 $words[0] = mb_substr($words[0],0,mb_strlen($words[0], $this->mb_enc)-1, $this->mb_enc);
5745 // and add it to savedContent for next line
5746 $savedContent = $m0.$savedContent;
5747 $m1 = $lastchar;
5748 $lastchar = mb_substr($words[0],mb_strlen($words[0], $this->mb_enc)-1, 1, $this->mb_enc);
5749 $m0 = $lastchar;
5750 }
5751
5752 }
5753 }
5754 /*-- END CJK-FONTS --*/
5755
5756 $lastContent = $words[0];
5757 $savedFont = $this->saveFont();
5758 // replace the current content with the cropped version
5759 $currContent = rtrim( $lastContent );
5760 }
5761 else {
5762 // save and crop off the content currently on the stack
5763 $savedContent = array_pop( $content );
5764 $savedContentB = $contentB[(count($contentB)-1)]; // mPDF 5.3.61
5765 $savedFont = array_pop( $font );
5766 // trim any trailing spaces off the last bit of content
5767 $currContent =& $content[ count( $content ) - 1 ];
5768 $currContent = rtrim( $currContent );
5769 }
5770 }
5771 else { // otherwise, we need to find which bit to cut off
5772 $lastContent = '';
5773 for ( $w = 0; $w < count( $words ) - 1; $w++) { $lastContent .= $words[ $w ]." "; }
5774 $savedContent = $words[ count( $words ) - 1 ];
5775 $savedFont = $this->saveFont();
5776 // replace the current content with the cropped version
5777 $currContent = rtrim( $lastContent );
5778 }
5779 // CJK - strip CJK space at end of line
5780 // &#x3000; = \xe3\x80\x80 = CJK space
5781 if ($this->checkCJK) { $currContent = preg_replace("/\xe3\x80\x80$/",'',$currContent) ; } // *CJK-FONTS*
5782
5783
5784 if (isset($this->objectbuffer[(count($content)-1)]) && $this->objectbuffer[(count($content)-1)]['type']=='dottab') {
5785 $savedObj = array_pop( $this->objectbuffer );
5786 $contentWidth -= ($this->objectbuffer[(count($content)-1)]['OUTER-WIDTH'] * _MPDFK);
5787 }
5788
5789 // Set Current lineheight (correction factor)
5790 $lhfixed = false;
5791 /*-- LISTS --*/
5792 if ($is_list) {
5793 if (preg_match('/([0-9.,]+)mm/',$this->list_lineheight[$this->listlvl][$this->listOcc],$am)) {
5794 $lhfixed = true;
5795 $def_fontsize = $this->InlineProperties['LISTITEM'][$this->listlvl][$this->listOcc][$this->listnum]['size'];
5796 $this->lineheight_correction = $am[1] / $def_fontsize ;
5797 }
5798 else {
5799 $this->lineheight_correction = $this->list_lineheight[$this->listlvl][$this->listOcc];
5800 }
5801 }
5802 else
5803 /*-- END LISTS --*/
5804 /*-- TABLES --*/
5805 if ($is_table) {
5806 if (preg_match('/([0-9.,]+)mm/',$this->table_lineheight,$am)) {
5807 $lhfixed = true;
5808 $def_fontsize = $this->FontSize; // needs to be default font-size for block ****
5809 $this->lineheight_correction = $lineHeight / $def_fontsize ;
5810 }
5811 else {
5812 $this->lineheight_correction = $this->table_lineheight;
5813 }
5814 }
5815 else
5816 /*-- END TABLES --*/
5817 if (isset($this->blk[$this->blklvl]['line_height']) && $this->blk[$this->blklvl]['line_height']) {
5818 if (preg_match('/([0-9.,]+)mm/',$this->blk[$this->blklvl]['line_height'],$am)) {
5819 $lhfixed = true;
5820 $def_fontsize = $this->blk[$this->blklvl]['InlineProperties']['size']; // needs to be default font-size for block ****
5821 $this->lineheight_correction = $am[1] / $def_fontsize ;
5822 }
5823 else {
5824 $this->lineheight_correction = $this->blk[$this->blklvl]['line_height'];
5825 }
5826 }
5827 else {
5828 $this->lineheight_correction = $this->normalLineheight;
5829 }
5830 // update $contentWidth and $cutoffWidth since they changed with cropping
5831 // Also correct lineheight to maximum fontsize (not for tables)
5832 $contentWidth = 0;
5833 // correct lineheight to maximum fontsize
5834 if ($lhfixed) { $maxlineHeight = $this->lineheight; }
5835 else { $maxlineHeight = 0; }
5836 $this->forceExactLineheight = true;
5837 $maxfontsize = 0;
5838 // While we're at it, check for cursive text
5839 $checkCursive=false;
5840 if ($this->biDirectional) { $checkCursive=true; } // *RTL*
5841 foreach ( $content as $k => $chunk )
5842 {
5843 $this->restoreFont( $font[ $k ]);
5844 if (!isset($this->objectbuffer[$k])) {
5845 if (!$this->usingCoreFont) {
5846 $content[$k] = $chunk = str_replace("\xc2\xad",'',$chunk );
5847 if (isset($this->CurrentFont['indic']) && $this->CurrentFont['indic']) { $checkCursive=true; } // *INDIC*
5848 }
5849 // Soft Hyphens chr(173)
5850 else if ($this->FontFamily!='csymbol' && $this->FontFamily!='czapfdingbats') {
5851 $content[$k] = $chunk = str_replace(chr(173),'',$chunk );
5852 }
5853 $contentWidth += $this->GetStringWidth( $chunk ) * _MPDFK;
5854 // mPDF 5.3.61
5855 if (!empty($this->spanborddet)) {
5856 if (strpos($contentB[$k],'L')!==false) $contentWidth += $this->spanborddet['L']['w'] * _MPDFK;
5857 if (strpos($contentB[$k],'R')!==false) $contentWidth += $this->spanborddet['R']['w'] * _MPDFK;
5858 }
5859 if (!$lhfixed) { $maxlineHeight = max($maxlineHeight,$this->FontSize * $this->lineheight_correction ); }
5860 if ($lhfixed && ($this->FontSize > $def_fontsize || ($this->FontSize > ($lineHeight * $this->lineheight_correction) && $is_list))) {
5861 $this->forceExactLineheight = false;
5862 }
5863 $maxfontsize = max($maxfontsize,$this->FontSize);
5864 }
5865 }
5866
5867 $lastfontreqstyle = $font[count($font)-1]['ReqFontStyle'];
5868 $lastfontstyle = $font[count($font)-1]['style'];
5869 if ($blockdir == 'ltr' && strpos($lastfontreqstyle,"I") !== false && strpos($lastfontstyle,"I") === false) { // Artificial italic
5870 $lastitalic = $this->FontSize*0.15*_MPDFK;
5871 }
5872 else { $lastitalic = 0; }
5873
5874
5875 /*-- LISTS --*/
5876 if ($is_list && is_array($this->bulletarray) && $this->bulletarray) {
5877 $actfs = $this->bulletarray['fontsize'];
5878 if (!$lhfixed) { $maxlineHeight = max($maxlineHeight,$actfs * $this->lineheight_correction ); }
5879 if ($lhfixed && $actfs > $def_fontsize) { $this->forceExactLineheight = false; }
5880 $maxfontsize = max($maxfontsize,$actfs);
5881 }
5882 /*-- END LISTS --*/
5883
5884 // when every text item checked i.e. $maxfontsize is set properly
5885
5886 $af = 0; // Above font
5887 $bf = 0; // Below font
5888 $mta = 0; // Maximum top-aligned
5889 $mba = 0; // Maximum bottom-aligned
5890
5891 foreach ( $content as $k => $chunk ) {
5892 if (isset($this->objectbuffer[$k]) && $this->objectbuffer[$k]) {
5893 $contentWidth += $this->objectbuffer[$k]['OUTER-WIDTH'] * _MPDFK;
5894 $oh = $this->objectbuffer[$k]['OUTER-HEIGHT'];
5895 $va = $this->objectbuffer[$k]['vertical-align']; // = $objattr['vertical-align'] = set as M,T,B,S
5896 if ($lhfixed && $oh > $def_fontsize) { $this->forceExactLineheight = false; }
5897
5898 if ($va == 'BS') { // (BASELINE default)
5899 $af = max($af, ($oh - ($maxfontsize * (0.5 + $this->baselineC))));
5900 }
5901 else if ($va == 'M') {
5902 $af = max($af, ($oh - $maxfontsize)/2);
5903 $bf = max($bf, ($oh - $maxfontsize)/2);
5904 }
5905 else if ($va == 'TT') {
5906 $bf = max($bf, ($oh - $maxfontsize));
5907 }
5908 else if ($va == 'TB') {
5909 $af = max($af, ($oh - $maxfontsize));
5910 }
5911 else if ($va == 'T') {
5912 $mta = max($mta, $oh);
5913 }
5914 else if ($va == 'B') {
5915 $mba = max($mba, $oh);
5916 }
5917 }
5918 }
5919 if ((!$lhfixed || !$this->forceExactLineheight) && ($af > (($maxlineHeight - $maxfontsize)/2) || $bf > (($maxlineHeight - $maxfontsize)/2))) {
5920 $maxlineHeight = $maxfontsize + $af + $bf;
5921 }
5922 else if (!$lhfixed) { $af = $bf = ($maxlineHeight - $maxfontsize)/2; }
5923
5924 if ($mta > $maxlineHeight) {
5925 $bf += ($mta - $maxlineHeight);
5926 $maxlineHeight = $mta;
5927 }
5928 if ($mba > $maxlineHeight) {
5929 $af += ($mba - $maxlineHeight);
5930 $maxlineHeight = $mba;
5931 }
5932
5933
5934 $lineHeight = $maxlineHeight;
5935 $cutoffWidth = $contentWidth;
5936 // If NOT images, and maxfontsize NOT > lineHeight - this value determines text baseline positioning
5937 if ($lhfixed && $af==0 && $bf==0 && $maxfontsize<=($def_fontsize * $this->lineheight_correction * 0.8 )) {
5938 $this->linemaxfontsize = $def_fontsize;
5939 }
5940 else { $this->linemaxfontsize = $maxfontsize; }
5941
5942
5943 $inclCursive=false;
5944 foreach ( $content as $k => $chunk ) {
5945 if (!isset($this->objectbuffer[$k]) || (isset($this->objectbuffer[$k]) && !$this->objectbuffer[$k])) {
5946 if ($this->usingCoreFont) {
5947 $content[$k] = str_replace(chr(160),chr(32),$chunk );
5948 }
5949 else {
5950 $content[$k] = str_replace(chr(194).chr(160),chr(32),$chunk );
5951 if ($checkCursive) {
5952 if (preg_match("/([".$this->pregRTLchars."])/u", $chunk)) { $inclCursive = true; } // *RTL*
5953 if (preg_match("/([".$this->pregHIchars.$this->pregBNchars.$this->pregPAchars."])/u", $chunk)) { $inclCursive = true; } // *INDIC*
5954 }
5955 }
5956 }
5957 }
5958
5959 // JUSTIFICATION J
5960 $jcharspacing = 0;
5961 $jws = 0;
5962 $nb_carac = 0;
5963 $nb_spaces = 0;
5964 // 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)
5965 if(( $align == 'J' ) || (($cutoffWidth + $lastitalic > $maxWidth - $WidthCorrection - (($this->cMarginL+$this->cMarginR)*_MPDFK) - ($paddingL+$paddingR +(($fpaddingL + $fpaddingR) * _MPDFK) ) + 0.001) && !$CJKoverflow)) { // 0.001 is to correct for deviations converting mm=>pts
5966 // JUSTIFY J (Use character spacing)
5967 // WORD SPACING
5968 foreach ( $content as $k => $chunk ) {
5969 if (!isset($this->objectbuffer[$k]) || (isset($this->objectbuffer[$k]) && !$this->objectbuffer[$k])) {
5970 $nb_carac += mb_strlen( $chunk, $this->mb_enc ) ;
5971 $nb_spaces += mb_substr_count( $chunk,' ', $this->mb_enc ) ;
5972 }
5973 }
5974 list($jcharspacing,$jws) = $this->GetJspacing($nb_carac,$nb_spaces,($maxWidth-$lastitalic-$cutoffWidth-$WidthCorrection-(($this->cMarginL+$this->cMarginR)*_MPDFK)-($paddingL+$paddingR +(($fpaddingL + $fpaddingR) * _MPDFK) )),$inclCursive);
5975 }
5976
5977
5978 // WORD SPACING
5979 $empty = $maxWidth - $lastitalic-$WidthCorrection - $contentWidth - (($this->cMarginL+$this->cMarginR)* _MPDFK) - ($paddingL+$paddingR +(($fpaddingL + $fpaddingR) * _MPDFK) );
5980
5981 $empty -= ($jcharspacing * $nb_carac);
5982 $empty -= ($jws * $nb_spaces);
5983
5984 $empty /= _MPDFK;
5985 $b = ''; //do not use borders
5986 // Get PAGEBREAK TO TEST for height including the top border/padding
5987 $check_h = max($this->divheight,$lineHeight);
5988 if (($newblock) && ($blockstate==1 || $blockstate==3) && ($this->blklvl > 0) && ($lineCount == 1) && (!$is_table) && (!$is_list)) {
5989 $check_h += ($this->blk[$this->blklvl]['padding_top'] + $this->blk[$this->blklvl]['margin_top'] + $this->blk[$this->blklvl]['border_top']['w']);
5990 }
5991
5992 if ($this->ColActive && $check_h > ($this->PageBreakTrigger - $this->y0)) {
5993 $this->SetCol($this->NbCol-1);
5994 }
5995
5996 // PAGEBREAK
5997 // 'If' below used in order to fix "first-line of other page with justify on" bug
5998 if(!$is_table && ($this->y+$check_h) > $this->PageBreakTrigger and !$this->InFooter and $this->AcceptPageBreak()) {
5999 $bak_x=$this->x;//Current X position
6000
6001 // WORD SPACING
6002 $ws=$this->ws;//Word Spacing
6003 $charspacing=$this->charspacing;//Character Spacing
6004 $this->ResetSpacing();
6005
6006 $this->AddPage($this->CurOrientation);
6007
6008 $this->x = $bak_x;
6009 // Added to correct for OddEven Margins
6010 $currentx += $this->MarginCorrection;
6011 $this->x += $this->MarginCorrection;
6012
6013 // WORD SPACING
6014 $this->SetSpacing($charspacing,$ws);
6015 }
6016
6017 if ($this->keep_block_together && !$is_table && $this->kt_p00 < $this->page && ($this->y+$check_h) > $this->kt_y00) {
6018 $this->printdivbuffer();
6019 $this->keep_block_together = 0;
6020 }
6021
6022
6023 /*-- COLUMNS --*/
6024 // COLS
6025 // COLUMN CHANGE
6026 if ($this->CurrCol != $oldcolumn) {
6027 $currentx += $this->ChangeColumn * ($this->ColWidth+$this->ColGap);
6028 $this->x += $this->ChangeColumn * ($this->ColWidth+$this->ColGap);
6029 $oldcolumn = $this->CurrCol;
6030 }
6031
6032 if ($this->ColActive && !$is_table) { $this->breakpoints[$this->CurrCol][] = $this->y; } // *COLUMNS*
6033 /*-- END COLUMNS --*/
6034
6035 // TOP MARGIN
6036 if (($newblock) && ($blockstate==1 || $blockstate==3) && ($this->blk[$this->blklvl]['margin_top']) && ($lineCount == 1) && (!$is_table) && (!$is_list)) {
6037 $this->DivLn($this->blk[$this->blklvl]['margin_top'],$this->blklvl-1,true,$this->blk[$this->blklvl]['margin_collapse']);
6038 if ($this->ColActive) { $this->breakpoints[$this->CurrCol][] = $this->y; } // *COLUMNS*
6039 }
6040
6041
6042 // Update y0 for top of block (used to paint border)
6043 if (($newblock) && ($blockstate==1 || $blockstate==3) && ($lineCount == 1) && (!$is_table) && (!$is_list)) {
6044 $this->blk[$this->blklvl]['y0'] = $this->y;
6045 $this->blk[$this->blklvl]['startpage'] = $this->page;
6046 }
6047
6048 // TOP PADDING and BORDER spacing/fill
6049 if (($newblock) && ($blockstate==1 || $blockstate==3) && (($this->blk[$this->blklvl]['padding_top']) || ($this->blk[$this->blklvl]['border_top'])) && ($lineCount == 1) && (!$is_table) && (!$is_list)) {
6050 // $state = 0 normal; 1 top; 2 bottom; 3 top and bottom
6051 $this->DivLn($this->blk[$this->blklvl]['padding_top'] + $this->blk[$this->blklvl]['border_top']['w'],-3,true,false,1);
6052 if ($this->ColActive) { $this->breakpoints[$this->CurrCol][] = $this->y; } // *COLUMNS*
6053 }
6054
6055 $arraysize = count($content);
6056
6057 $margins = ($this->cMarginL+$this->cMarginR) + ($ipaddingL+$ipaddingR + $fpaddingR + $fpaddingR );
6058
6059 // PAINT BACKGROUND FOR THIS LINE
6060 if (!$is_table) { $this->DivLn($lineHeight,$this->blklvl,false); } // false -> don't advance y
6061
6062 $this->x = $currentx + $this->cMarginL + $ipaddingL + $fpaddingL ;
6063 if ($align == 'R') { $this->x += $empty; }
6064 else if ($align == 'C') { $this->x += ($empty / 2); }
6065
6066 // Paragraph INDENT
6067 if (isset($this->blk[$this->blklvl]['text_indent']) && ($newblock) && ($blockstate==1 || $blockstate==3) && ($lineCount == 1) && (!$is_table) && ($blockdir !='rtl') && ($align !='C')) {
6068 $ti = $this->ConvertSize($this->blk[$this->blklvl]['text_indent'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
6069 $this->x += $ti;
6070 }
6071
6072 // DIRECTIONALITY RTL
6073 $all_rtl = false;
6074 $contains_rtl = false;
6075 /*-- RTL --*/
6076 if ($blockdir == 'rtl' || $this->biDirectional) {
6077 $all_rtl = true;
6078 foreach ( $content as $k => $chunk ) {
6079 $reversed = $this->magic_reverse_dir($chunk, false, $blockdir);
6080
6081 if ($reversed > 0) { $contains_rtl = true; }
6082 if ($reversed < 2) { $all_rtl = false; }
6083 $content[$k] = $chunk;
6084 }
6085 if (($blockdir =='rtl' && $contains_rtl) || $all_rtl) {
6086 $content = array_reverse($content,false);
6087 $contentB = array_reverse($contentB,false); // mPDF 5.3.61
6088 }
6089 }
6090 /*-- END RTL --*/
6091
6092 foreach ( $content as $k => $chunk ) {
6093
6094 // FOR IMAGES - UPDATE POSITION
6095 if (($blockdir =='rtl' && $contains_rtl) || $all_rtl) { $dirk = $arraysize-1 - $k ; } else { $dirk = $k; }
6096
6097 $va = 'M'; // default for text
6098 if (isset($this->objectbuffer[$dirk]) && $this->objectbuffer[$dirk]) {
6099 $xadj = $this->x - $this->objectbuffer[$dirk]['OUTER-X'] ;
6100 $this->objectbuffer[$dirk]['OUTER-X'] += $xadj;
6101 $this->objectbuffer[$dirk]['BORDER-X'] += $xadj;
6102 $this->objectbuffer[$dirk]['INNER-X'] += $xadj;
6103 $va = $this->objectbuffer[$dirk]['vertical-align'];
6104 $yadj = $this->y - $this->objectbuffer[$dirk]['OUTER-Y'];
6105 if ($va == 'BS') {
6106 $yadj += $af + ($this->linemaxfontsize * (0.5 + $this->baselineC)) - $this->objectbuffer[$dirk]['OUTER-HEIGHT'];
6107 }
6108 else if ($va == 'M' || $va == '') {
6109 $yadj += $af + ($this->linemaxfontsize /2) - ($this->objectbuffer[$dirk]['OUTER-HEIGHT']/2);
6110 }
6111 else if ($va == 'TB') {
6112 $yadj += $af + $this->linemaxfontsize - $this->objectbuffer[$dirk]['OUTER-HEIGHT'];
6113 }
6114 else if ($va == 'TT') {
6115 $yadj += $af;
6116 }
6117 else if ($va == 'B') {
6118 $yadj += $af + $this->linemaxfontsize + $bf - $this->objectbuffer[$dirk]['OUTER-HEIGHT'];
6119 }
6120 else if ($va == 'T') {
6121 $yadj += 0;
6122 }
6123 $this->objectbuffer[$dirk]['OUTER-Y'] += $yadj;
6124 $this->objectbuffer[$dirk]['BORDER-Y'] += $yadj;
6125 $this->objectbuffer[$dirk]['INNER-Y'] += $yadj;
6126 }
6127
6128 // DIRECTIONALITY RTL
6129 if ((($blockdir == 'rtl') && ($contains_rtl )) || ($all_rtl )) { $this->restoreFont($font[$arraysize-1 - $k]); }
6130 else { $this->restoreFont( $font[ $k ] ); }
6131
6132 $this->SetSpacing(($this->fixedlSpacing*_MPDFK)+$jcharspacing,($this->fixedlSpacing+$this->minwSpacing)*_MPDFK+$jws);
6133 // Now unset these values so they don't influence GetStringwidth below or in fn. Cell
6134 $this->fixedlSpacing = false;
6135 $this->minwSpacing = 0;
6136
6137 // *********** SPAN BACKGROUND COLOR ***************** //
6138 if ($this->spanbgcolor) {
6139 $cor = $this->spanbgcolorarray;
6140 $this->SetFColor($cor);
6141 $save_fill = $fill; $spanfill = 1; $fill = 1;
6142 }
6143 // mPDF 5.3.61
6144 if (!empty($this->spanborddet)) {
6145 if (strpos($contentB[$k],'L')!==false) $this->x += $this->spanborddet['L']['w'];
6146 if (strpos($contentB[$k],'L')===false) $this->spanborddet['L']['s'] = $this->spanborddet['L']['w'] = 0;
6147 if (strpos($contentB[$k],'R')===false) $this->spanborddet['R']['s'] = $this->spanborddet['R']['w'] = 0;
6148 }
6149
6150 // WORD SPACING
6151 $stringWidth = $this->GetStringWidth($chunk );
6152 $stringWidth += ( $this->charspacing * mb_strlen($chunk,$this->mb_enc ) / _MPDFK );
6153 $stringWidth += ( $this->ws * mb_substr_count($chunk,' ',$this->mb_enc ) / _MPDFK );
6154 if (isset($this->objectbuffer[$dirk])) { $stringWidth = $this->objectbuffer[$dirk]['OUTER-WIDTH']; }
6155
6156 if ($stringWidth==0) { $stringWidth = 0.000001; }
6157 if ($k == $arraysize-1) {
6158 $stringWidth -= ( $this->charspacing / _MPDFK );
6159 $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) // mPDF 5.3.07
6160 }
6161 else $this->Cell( $stringWidth, $lineHeight, $chunk, '', 0, '', $fill, $this->HREF, 0, 0,0,'M', $fill, $af, $bf, true );//first or middle part // mPDF 5.3.07
6162
6163 // mPDF 5.3.61
6164 if (!empty($this->spanborddet)) {
6165 if (strpos($contentB[$k],'R')!==false && $k != $arraysize-1) $this->x += $this->spanborddet['R']['w'];
6166 }
6167 // *********** SPAN BACKGROUND COLOR OFF - RESET BLOCK BGCOLOR ***************** //
6168 if (isset($spanfill) && $spanfill) {
6169 $fill = $save_fill; $spanfill = 0;
6170 if ($fill) { $this->SetFColor($bcor); }
6171 }
6172 }
6173 if (!$is_table) {
6174 $this->maxPosR = max($this->maxPosR , ($this->w - $this->rMargin - $this->blk[$this->blklvl]['outer_right_margin']));
6175 $this->maxPosL = min($this->maxPosL , ($this->lMargin + $this->blk[$this->blklvl]['outer_left_margin']));
6176 }
6177
6178 // move on to the next line, reset variables, tack on saved content and current char
6179
6180 $this->printobjectbuffer($is_table, $blockdir);
6181 $this->objectbuffer = array();
6182
6183 /*-- LISTS --*/
6184 // LIST BULLETS/NUMBERS
6185 if ($is_list && is_array($this->bulletarray) && ($lineCount == 1) ) {
6186
6187 $this->ResetSpacing();
6188
6189 $bull = $this->bulletarray;
6190 if (isset($bull['level']) && isset($bull['occur']) && isset($this->InlineProperties['LIST'][$bull['level']][$bull['occur']])) {
6191 $this->restoreInlineProperties($this->InlineProperties['LIST'][$bull['level']][$bull['occur']]);
6192 }
6193 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']]); }
6194 if (isset($bull['font']) && $bull['font'] == 'czapfdingbats') {
6195 $this->bullet = true;
6196 $this->SetFont('czapfdingbats','',$this->FontSizePt/2.5);
6197 }
6198 else { $this->SetFont($this->FontFamily,$this->FontStyle,$this->FontSizePt,true,true); } // force output
6199 //Output bullet
6200 $this->x = $currentx;
6201 if (isset($bull['x'])) { $this->x += $bull['x']; }
6202 $this->y -= $lineHeight;
6203 if (is_array($bull['col'])) { $this->SetTColor($bull['col']); }
6204 if (isset($bull['txt'])) { $this->Cell($bull['w'], $lineHeight,$bull['txt'],'','',$bull['align'],0,'',0,-$this->cMarginL, -$this->cMarginR ); }
6205 if (isset($bull['font']) && $bull['font'] == 'czapfdingbats') {
6206 $this->bullet = false;
6207 }
6208 $this->x = $currentx; // Reset
6209 $this->y += $lineHeight;
6210
6211 if ($this->ColActive && !$is_table) { $this->breakpoints[$this->CurrCol][] = $this->y; } // *COLUMNS*
6212
6213 $this->bulletarray = array(); // prevents repeat of bullet/number if <li>....<br />.....</li>
6214 }
6215 /*-- END LISTS --*/
6216
6217
6218 /*-- CSS-IMAGE-FLOAT --*/
6219 // Update values if set to skipline
6220 if ($this->floatmargins) { $this->_advanceFloatMargins(); }
6221 /*-- END CSS-IMAGE-FLOAT --*/
6222
6223 // Reset lineheight
6224 $lineHeight = $this->divheight;
6225 $valign = 'M';
6226
6227 $this->restoreFont( $savedFont );
6228 // mPDF 5.3.61
6229 $lbw = $rbw = 0; // Border widths
6230 if (!empty($this->spanborddet)) {
6231 $lbw = $this->spanborddet['L']['w'];
6232 $rbw = $this->spanborddet['R']['w'];
6233 }
6234
6235 $font = array();
6236 $content = array();
6237 $contentB = array(); // mPDF 5.3.61
6238 $contentWidth = 0;
6239 if (!empty($savedObj)) {
6240 $this->objectbuffer[] = $savedObj;
6241 $font[] = $savedFont;
6242 $content[] = '';
6243 $contentB[] = '';
6244 $contentWidth += $savedObj['OUTER-WIDTH'] * _MPDFK;
6245 }
6246 $font[] = $savedFont;
6247 $content[] = $savedContent . $c;
6248 $contentB[] = $savedContentB ; // mPDF 5.3.61
6249 $currContent =& $content[ (count($content)-1) ];
6250 // CJK - strip CJK space at end of line
6251 // &#x3000; = \xe3\x80\x80 = CJK space
6252 if ($this->checkCJK && $currContent == "\xe3\x80\x80") { $currContent = '' ; } // *CJK-FONTS*
6253 $contentWidth += $this->GetStringWidth( $currContent ) * _MPDFK;
6254 // mPDF 5.3.61
6255 if (strpos($savedContentB,'L')!==false) $contentWidth += $lbw;
6256 $cutoffWidth = $contentWidth;
6257 $CJKoverflow = false;
6258 }
6259 // another character will fit, so add it on
6260 else {
6261 $contentWidth += $cw;
6262 $currContent .= $c;
6263 }
6264 }
6265 unset($content);
6266 unset($contentB); // mPDF 5.3.61
6267 }
6268 //----------------------END OF FLOWING BLOCK------------------------------------//
6269
6270
6271 /*-- CSS-IMAGE-FLOAT --*/
6272 // Update values if set to skipline
6273 function _advanceFloatMargins() {
6274 // Update floatmargins - L
6275 if (isset($this->floatmargins['L']) && $this->floatmargins['L']['skipline'] && $this->floatmargins['L']['y0'] != $this->y) {
6276 $yadj = $this->y - $this->floatmargins['L']['y0'];
6277 $this->floatmargins['L']['y0'] = $this->y;
6278 $this->floatmargins['L']['y1'] += $yadj;
6279
6280 // Update objattr in floatbuffer
6281 if ($this->floatbuffer[$this->floatmargins['L']['id']]['border_left']['w']) {
6282 $this->floatbuffer[$this->floatmargins['L']['id']]['BORDER-Y'] += $yadj;
6283 }
6284 $this->floatbuffer[$this->floatmargins['L']['id']]['INNER-Y'] += $yadj;
6285 $this->floatbuffer[$this->floatmargins['L']['id']]['OUTER-Y'] += $yadj;
6286
6287 // Unset values
6288 $this->floatbuffer[$this->floatmargins['L']['id']]['skipline'] = false;
6289 $this->floatmargins['L']['skipline'] = false;
6290 $this->floatmargins['L']['id'] = '';
6291 }
6292 // Update floatmargins - R
6293 if (isset($this->floatmargins['R']) && $this->floatmargins['R']['skipline'] && $this->floatmargins['R']['y0'] != $this->y) {
6294 $yadj = $this->y - $this->floatmargins['R']['y0'];
6295 $this->floatmargins['R']['y0'] = $this->y;
6296 $this->floatmargins['R']['y1'] += $yadj;
6297
6298 // Update objattr in floatbuffer
6299 if ($this->floatbuffer[$this->floatmargins['R']['id']]['border_left']['w']) {
6300 $this->floatbuffer[$this->floatmargins['R']['id']]['BORDER-Y'] += $yadj;
6301 }
6302 $this->floatbuffer[$this->floatmargins['R']['id']]['INNER-Y'] += $yadj;
6303 $this->floatbuffer[$this->floatmargins['R']['id']]['OUTER-Y'] += $yadj;
6304
6305 // Unset values
6306 $this->floatbuffer[$this->floatmargins['R']['id']]['skipline'] = false;
6307 $this->floatmargins['R']['skipline'] = false;
6308 $this->floatmargins['R']['id'] = '';
6309 }
6310 }
6311 /*-- END CSS-IMAGE-FLOAT --*/
6312
6313
6314
6315 ////////////////////////////////////////////////////////////////////////////////
6316 // ADDED forcewrap - to call from inline OBJECT functions to breakwords if necessary in cell
6317 ////////////////////////////////////////////////////////////////////////////////
6318 function WordWrap(&$text, $maxwidth, $forcewrap = 0) {
6319 $biggestword=0;
6320 $toonarrow=false;
6321
6322 $text = trim($text);
6323
6324 if ($text==='') return 0;
6325 $space = $this->GetCharWidth(' ',false); // mPDF 5.3.04
6326 $lines = explode("\n", $text);
6327 $text = '';
6328 $count = 0;
6329 foreach ($lines as $line) {
6330 $words = explode(' ', $line);
6331 $width = 0;
6332 foreach ($words as $word) {
6333 $word = trim($word);
6334 $wordwidth = $this->GetStringWidth($word);
6335 //Warn user that maxwidth is insufficient
6336 if ($wordwidth > $maxwidth + 0.0001) {
6337 if ($wordwidth > $biggestword) { $biggestword = $wordwidth; }
6338 $toonarrow=true;
6339 // ADDED
6340 if ($forcewrap) {
6341 while($wordwidth > $maxwidth) {
6342 $chw = 0; // check width
6343 for ( $i = 0; $i < mb_strlen($word, $this->mb_enc ); $i++ ) {
6344 $chw = $this->GetStringWidth(mb_substr($word,0,$i+1,$this->mb_enc ));
6345 if ($chw > $maxwidth ) {
6346 if ($text) {
6347 $text = rtrim($text)."\n".mb_substr($word,0,$i,$this->mb_enc );
6348 $count++;
6349 }
6350 else {
6351 $text = mb_substr($word,0,$i,$this->mb_enc );
6352 }
6353 $word = mb_substr($word,$i,mb_strlen($word, $this->mb_enc )-$i,$this->mb_enc );
6354 $wordwidth = $this->GetStringWidth($word);
6355 $width = $maxwidth;
6356 break;
6357 }
6358 }
6359 }
6360 }
6361 }
6362
6363 if ($width + $wordwidth < $maxwidth - 0.0001) {
6364 $width += $wordwidth + $space;
6365 $text .= $word.' ';
6366 }
6367 else {
6368 $width = $wordwidth + $space;
6369 $text = rtrim($text)."\n".$word.' ';
6370 $count++;
6371 }
6372 }
6373 $text .= "\n";
6374 $count++;
6375 }
6376 $text = rtrim($text);
6377
6378 //Return -(wordsize) if word is bigger than maxwidth
6379
6380 // ADDED
6381 if ($forcewrap) { return $count; }
6382 if (($toonarrow) && ($this->table_error_report)) {
6383 $this->Error("Word is too long to fit in table - ".$this->table_error_report_param);
6384 }
6385 if ($toonarrow) return -$biggestword;
6386 else return $count;
6387 }
6388
6389 /*-- END HTML-CSS --*/
6390
6391 function _SetTextRendering($mode) {
6392 if (!(($mode == 0) || ($mode == 1) || ($mode == 2)))
6393 $this->Error("Text rendering mode should be 0, 1 or 2 (value : $mode)");
6394 $tr = ($mode.' Tr');
6395 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); }
6396 $this->pageoutput[$this->page]['TextRendering'] = $tr;
6397
6398 }
6399
6400 function SetTextOutline($width, $col=0) {
6401 if ($width == false) //Now resets all values
6402 {
6403 $this->outline_on = false;
6404 $this->SetLineWidth(0.2);
6405 $this->SetDColor($this->ConvertColor(0));
6406 $this->_SetTextRendering(0);
6407 $tr = ('0 Tr');
6408 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); }
6409 $this->pageoutput[$this->page]['TextRendering'] = $tr;
6410 }
6411 else
6412 {
6413 $this->SetLineWidth($width);
6414 $this->SetDColor($col);
6415 $tr = ('2 Tr');
6416 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); }
6417 $this->pageoutput[$this->page]['TextRendering'] = $tr;
6418 }
6419 }
6420
6421 function Image($file,$x,$y,$w=0,$h=0,$type='',$link='',$paint=true, $constrain=true, $watermark=false, $shownoimg=true, $allowvector=true) {
6422 $orig_srcpath = $file;
6423 $this->GetFullPath($file);
6424
6425 $info=$this->_getImage($file, true, $allowvector, $orig_srcpath );
6426 if(!$info && $paint) {
6427 $info = $this->_getImage($this->noImageFile);
6428 if ($info) {
6429 $file = $this->noImageFile;
6430 $w = ($info['w'] * (25.4/$this->dpi)); // 14 x 16px
6431 $h = ($info['h'] * (25.4/$this->dpi)); // 14 x 16px
6432 }
6433 }
6434 if(!$info) return false;
6435 //Automatic width and height calculation if needed
6436 if($w==0 and $h==0) {
6437 /*-- IMAGES-WMF --*/
6438 if ($info['type']=='wmf') {
6439 // WMF units are twips (1/20pt)
6440 // divide by 20 to get points
6441 // divide by k to get user units
6442 $w = abs($info['w'])/(20*_MPDFK);
6443 $h = abs($info['h']) / (20*_MPDFK);
6444 }
6445 else
6446 /*-- END IMAGES-WMF --*/
6447 if ($info['type']=='svg') {
6448 // returned SVG units are pts
6449 // divide by k to get user units (mm)
6450 $w = abs($info['w'])/_MPDFK;
6451 $h = abs($info['h']) /_MPDFK;
6452 }
6453 else {
6454 //Put image at default image dpi
6455 $w=($info['w']/_MPDFK) * (72/$this->img_dpi);
6456 $h=($info['h']/_MPDFK) * (72/$this->img_dpi);
6457 }
6458 }
6459 if($w==0) $w=abs($h*$info['w']/$info['h']);
6460 if($h==0) $h=abs($w*$info['h']/$info['w']);
6461
6462 /*-- WATERMARK --*/
6463 if ($watermark) {
6464 $maxw = $this->w;
6465 $maxh = $this->h;
6466 // Size = D PF or array
6467 if (is_array($this->watermark_size)) {
6468 $w = $this->watermark_size[0];
6469 $h = $this->watermark_size[1];
6470 }
6471 else if (!is_string($this->watermark_size)) {
6472 $maxw -= $this->watermark_size*2;
6473 $maxh -= $this->watermark_size*2;
6474 $w = $maxw;
6475 $h=abs($w*$info['h']/$info['w']);
6476 if ($h > $maxh ) {
6477 $h = $maxh ; $w=abs($h*$info['w']/$info['h']);
6478 }
6479 }
6480 else if ($this->watermark_size == 'F') {
6481 if ($this->ColActive) { $maxw = $this->w - ($this->DeflMargin + $this->DefrMargin); }
6482 else { $maxw = $this->pgwidth; }
6483 $maxh = $this->h - ($this->tMargin + $this->bMargin);
6484 $w = $maxw;
6485 $h=abs($w*$info['h']/$info['w']);
6486 if ($h > $maxh ) {
6487 $h = $maxh ; $w=abs($h*$info['w']/$info['h']);
6488 }
6489 }
6490 else if ($this->watermark_size == 'P') { // Default P
6491 $w = $maxw;
6492 $h=abs($w*$info['h']/$info['w']);
6493 if ($h > $maxh ) {
6494 $h = $maxh ; $w=abs($h*$info['w']/$info['h']);
6495 }
6496 }
6497 // Automatically resize to maximum dimensions of page if too large
6498 if ($w > $maxw) {
6499 $w = $maxw;
6500 $h=abs($w*$info['h']/$info['w']);
6501 }
6502 if ($h > $maxh ) {
6503 $h = $maxh ;
6504 $w=abs($h*$info['w']/$info['h']);
6505 }
6506 // Position
6507 if (is_array($this->watermark_pos)) {
6508 $x = $this->watermark_pos[0];
6509 $y = $this->watermark_pos[1];
6510 }
6511 else if ($this->watermark_pos == 'F') { // centred on printable area
6512 if ($this->ColActive) { // *COLUMNS*
6513 if (($this->mirrorMargins) && (($this->page)%2==0)) { $xadj = $this->DeflMargin-$this->DefrMargin; } // *COLUMNS*
6514 else { $xadj = 0; } // *COLUMNS*
6515 $x = ($this->DeflMargin - $xadj + ($this->w - ($this->DeflMargin + $this->DefrMargin))/2) - ($w/2); // *COLUMNS*
6516 } // *COLUMNS*
6517 else { // *COLUMNS*
6518 $x = ($this->lMargin + ($this->pgwidth)/2) - ($w/2);
6519 } // *COLUMNS*
6520 $y = ($this->tMargin + ($this->h - ($this->tMargin + $this->bMargin))/2) - ($h/2);
6521 }
6522 else { // default P - centred on whole page
6523 $x = ($this->w/2) - ($w/2);
6524 $y = ($this->h/2) - ($h/2);
6525 }
6526 /*-- IMAGES-WMF --*/
6527 if ($info['type']=='wmf') {
6528 $sx = $w*_MPDFK / $info['w'];
6529 $sy = -$h*_MPDFK / $info['h'];
6530 $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']);
6531 }
6532 else
6533 /*-- END IMAGES-WMF --*/
6534 if ($info['type']=='svg') {
6535 $sx = $w*_MPDFK / $info['w'];
6536 $sy = -$h*_MPDFK / $info['h'];
6537 $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']);
6538 }
6539 else {
6540 $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']);
6541 }
6542
6543 if ($this->watermarkImgBehind) {
6544 $outstring = $this->watermarkImgAlpha . "\n" . $outstring . "\n" . $this->SetAlpha(1, 'Normal', true) . "\n";
6545 $this->pages[$this->page] = preg_replace('/(___BACKGROUND___PATTERNS'.date('jY').')/', "\n".$outstring."\n".'\\1', $this->pages[$this->page]);
6546 }
6547 else { $this->_out($outstring); }
6548
6549 return 0;
6550 } // end of IF watermark
6551 /*-- END WATERMARK --*/
6552
6553 if ($constrain) {
6554 // Automatically resize to maximum dimensions of page if too large
6555 if (isset($this->blk[$this->blklvl]['inner_width']) && $this->blk[$this->blklvl]['inner_width']) { $maxw = $this->blk[$this->blklvl]['inner_width']; }
6556 else { $maxw = $this->pgwidth; }
6557 if ($w > $maxw) {
6558 $w = $maxw;
6559 $h=abs($w*$info['h']/$info['w']);
6560 }
6561 if ($h > $this->h - ($this->tMargin + $this->bMargin + 1)) { // see below - +10 to avoid drawing too close to border of page
6562 $h = $this->h - ($this->tMargin + $this->bMargin + 1) ;
6563 if ($this->fullImageHeight) { $h = $this->fullImageHeight; }
6564 $w=abs($h*$info['w']/$info['h']);
6565 }
6566
6567
6568 //Avoid drawing out of the paper(exceeding width limits).
6569 //if ( ($x + $w) > $this->fw ) {
6570 if ( ($x + $w) > $this->w ) {
6571 $x = $this->lMargin;
6572 $y += 5;
6573 }
6574
6575 $changedpage = false;
6576 $oldcolumn = $this->CurrCol;
6577 //Avoid drawing out of the page.
6578 if($y+$h>$this->PageBreakTrigger and !$this->InFooter and $this->AcceptPageBreak()) {
6579 $this->AddPage($this->CurOrientation);
6580 // Added to correct for OddEven Margins
6581 $x=$x +$this->MarginCorrection;
6582 $y = $tMargin + $this->margin_header;
6583 $changedpage = true;
6584 }
6585 /*-- COLUMNS --*/
6586 // COLS
6587 // COLUMN CHANGE
6588 if ($this->CurrCol != $oldcolumn) {
6589 $y = $this->y0;
6590 $x += $this->ChangeColumn * ($this->ColWidth+$this->ColGap);
6591 $this->x += $this->ChangeColumn * ($this->ColWidth+$this->ColGap);
6592 }
6593 /*-- END COLUMNS --*/
6594 } // end of IF constrain
6595
6596 /*-- IMAGES-WMF --*/
6597 if ($info['type']=='wmf') {
6598 $sx = $w*_MPDFK / $info['w'];
6599 $sy = -$h*_MPDFK / $info['h'];
6600 $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']);
6601 }
6602 else
6603 /*-- END IMAGES-WMF --*/
6604 if ($info['type']=='svg') {
6605 $sx = $w*_MPDFK / $info['w'];
6606 $sy = -$h*_MPDFK / $info['h'];
6607 $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']);
6608 }
6609 else {
6610 $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']);
6611 }
6612
6613 if($paint) {
6614 $this->_out($outstring);
6615 if($link) $this->Link($x,$y,$w,$h,$link);
6616
6617 // Avoid writing text on top of the image. // THIS WAS OUTSIDE THE if ($paint) bit!!!!!!!!!!!!!!!!
6618 $this->y = $y + $h;
6619 }
6620
6621 //Return width-height array
6622 $sizesarray['WIDTH'] = $w;
6623 $sizesarray['HEIGHT'] = $h;
6624 $sizesarray['X'] = $x; //Position before painting image
6625 $sizesarray['Y'] = $y; //Position before painting image
6626 $sizesarray['OUTPUT'] = $outstring;
6627
6628 $sizesarray['IMAGE_ID'] = $info['i'];
6629 $sizesarray['itype'] = $info['type'];
6630 $sizesarray['set-dpi'] = $info['set-dpi'];
6631 return $sizesarray;
6632 }
6633
6634
6635
6636 //=============================================================
6637 //=============================================================
6638 //=============================================================
6639 //=============================================================
6640 //=============================================================
6641 /*-- HTML-CSS --*/
6642
6643 function _getObjAttr($t) {
6644 $c = explode("\xbb\xa4\xac",$t,2);
6645 $c = explode(",",$c[1],2);
6646 foreach($c as $v) {
6647 $v = explode("=",$v,2);
6648 $sp[$v[0]] = $v[1];
6649 }
6650 return (unserialize($sp['objattr']));
6651 }
6652
6653
6654 function inlineObject($type,$x,$y,$objattr,$Lmargin,$widthUsed,$maxWidth,$lineHeight,$paint=false,$is_table=false)
6655 {
6656 if ($is_table) { $k = $this->shrin_k; } else { $k = 1; }
6657
6658 // NB $x is only used when paint=true
6659 // Lmargin not used
6660 $w = 0;
6661 if (isset($objattr['width'])) { $w = $objattr['width']/$k; }
6662 $h = 0;
6663 if (isset($objattr['height'])) { $h = abs($objattr['height']/$k); }
6664 $widthLeft = $maxWidth - $widthUsed;
6665 $maxHeight = $this->h - ($this->tMargin + $this->bMargin + 10) ;
6666 if ($this->fullImageHeight) { $maxHeight = $this->fullImageHeight; }
6667 // For Images
6668 if (isset($objattr['border_left'])) {
6669 $extraWidth = ($objattr['border_left']['w'] + $objattr['border_right']['w'] + $objattr['margin_left']+ $objattr['margin_right'])/$k;
6670 $extraHeight = ($objattr['border_top']['w'] + $objattr['border_bottom']['w'] + $objattr['margin_top']+ $objattr['margin_bottom'])/$k;
6671
6672 if ($type == 'image' || $type == 'barcode' || $type == 'textcircle') { // mPDF 5.3.A5
6673 $extraWidth += ($objattr['padding_left'] + $objattr['padding_right'])/$k;
6674 $extraHeight += ($objattr['padding_top'] + $objattr['padding_bottom'])/$k;
6675 }
6676 }
6677
6678 if (!isset($objattr['vertical-align'])) { $objattr['vertical-align'] = 'M'; }
6679
6680 if ($type == 'image' || (isset($objattr['subtype']) && $objattr['subtype'] == 'IMAGE')) {
6681 if (isset($objattr['itype']) && ($objattr['itype'] == 'wmf' || $objattr['itype'] == 'svg')) {
6682 $file = $objattr['file'];
6683 $info=$this->formobjects[$file];
6684 }
6685 else if (isset($objattr['file'])) {
6686 $file = $objattr['file'];
6687 $info=$this->images[$file];
6688 }
6689 }
6690 if ($type == 'annot' || $type == 'bookmark' || $type == 'indexentry' || $type == 'toc') {
6691 $w = 0.00001;
6692 $h = 0.00001;
6693 }
6694
6695 // TEST whether need to skipline
6696 if (!$paint) {
6697 if ($type == 'hr') { // always force new line
6698 if (($y + $h + $lineHeight > $this->PageBreakTrigger) && !$this->InFooter && !$is_table) { return array(-2, $w ,$h ); } // New page + new line
6699 else { return array(1, $w ,$h ); } // new line
6700 }
6701 else {
6702 if ($widthUsed > 0 && $w > $widthLeft && (!$is_table || $type != 'image')) { // New line needed
6703 if (($y + $h + $lineHeight > $this->PageBreakTrigger) && !$this->InFooter) { return array(-2,$w ,$h ); } // New page + new line
6704 return array(1,$w ,$h ); // new line
6705 }
6706 else if ($widthUsed > 0 && $w > $widthLeft && $is_table) { // New line needed in TABLE
6707 return array(1,$w ,$h ); // new line
6708 }
6709 // Will fit on line but NEW PAGE REQUIRED
6710 else if (($y + $h > $this->PageBreakTrigger) && !$this->InFooter && !$is_table) { return array(-1,$w ,$h ); }
6711 else { return array(0,$w ,$h ); }
6712 }
6713 }
6714
6715 if ($type == 'annot' || $type == 'bookmark' || $type == 'indexentry' || $type == 'toc') {
6716 $w = 0.00001;
6717 $h = 0.00001;
6718 $objattr['BORDER-WIDTH'] = 0;
6719 $objattr['BORDER-HEIGHT'] = 0;
6720 $objattr['BORDER-X'] = $x;
6721 $objattr['BORDER-Y'] = $y;
6722 $objattr['INNER-WIDTH'] = 0;
6723 $objattr['INNER-HEIGHT'] = 0;
6724 $objattr['INNER-X'] = $x;
6725 $objattr['INNER-Y'] = $y;
6726 }
6727
6728 if ($type == 'image') {
6729 // Automatically resize to width remaining
6730 if ($w > $widthLeft && !$is_table) {
6731 $w = $widthLeft ;
6732 $h=abs($w*$info['h']/$info['w']);
6733 }
6734 $img_w = $w - $extraWidth ;
6735 $img_h = $h - $extraHeight ;
6736
6737 $objattr['BORDER-WIDTH'] = $img_w + $objattr['padding_left']/$k + $objattr['padding_right']/$k + (($objattr['border_left']['w']/$k + $objattr['border_right']['w']/$k)/2) ;
6738 $objattr['BORDER-HEIGHT'] = $img_h + $objattr['padding_top']/$k + $objattr['padding_bottom']/$k + (($objattr['border_top']['w']/$k + $objattr['border_bottom']['w']/$k)/2) ;
6739 $objattr['BORDER-X'] = $x + $objattr['margin_left']/$k + (($objattr['border_left']['w']/$k)/2) ;
6740 $objattr['BORDER-Y'] = $y + $objattr['margin_top']/$k + (($objattr['border_top']['w']/$k)/2) ;
6741 $objattr['INNER-WIDTH'] = $img_w;
6742 $objattr['INNER-HEIGHT'] = $img_h;
6743 $objattr['INNER-X'] = $x + $objattr['padding_left']/$k + $objattr['margin_left']/$k + ($objattr['border_left']['w']/$k);
6744 $objattr['INNER-Y'] = $y + $objattr['padding_top']/$k + $objattr['margin_top']/$k + ($objattr['border_top']['w']/$k) ;
6745 $objattr['ID'] = $info['i'];
6746 }
6747
6748 if ($type == 'input' && $objattr['subtype'] == 'IMAGE') {
6749 $img_w = $w - $extraWidth ;
6750 $img_h = $h - $extraHeight ;
6751 $objattr['BORDER-WIDTH'] = $img_w + (($objattr['border_left']['w']/$k + $objattr['border_right']['w']/$k)/2) ;
6752 $objattr['BORDER-HEIGHT'] = $img_h + (($objattr['border_top']['w']/$k + $objattr['border_bottom']['w']/$k)/2) ;
6753 $objattr['BORDER-X'] = $x + $objattr['margin_left']/$k + (($objattr['border_left']['w']/$k)/2) ;
6754 $objattr['BORDER-Y'] = $y + $objattr['margin_top']/$k + (($objattr['border_top']['w']/$k)/2) ;
6755 $objattr['INNER-WIDTH'] = $img_w;
6756 $objattr['INNER-HEIGHT'] = $img_h;
6757 $objattr['INNER-X'] = $x + $objattr['margin_left']/$k + ($objattr['border_left']['w']/$k);
6758 $objattr['INNER-Y'] = $y + $objattr['margin_top']/$k + ($objattr['border_top']['w']/$k) ;
6759 $objattr['ID'] = $info['i'];
6760 }
6761
6762 if ($type == 'barcode' || $type == 'textcircle') { // mPDF 5.3.A5
6763 $b_w = $w - $extraWidth ;
6764 $b_h = $h - $extraHeight ;
6765 $objattr['BORDER-WIDTH'] = $b_w + $objattr['padding_left']/$k + $objattr['padding_right']/$k + (($objattr['border_left']['w']/$k + $objattr['border_right']['w']/$k)/2) ;
6766 $objattr['BORDER-HEIGHT'] = $b_h + $objattr['padding_top']/$k + $objattr['padding_bottom']/$k + (($objattr['border_top']['w']/$k + $objattr['border_bottom']['w']/$k)/2) ;
6767 $objattr['BORDER-X'] = $x + $objattr['margin_left']/$k + (($objattr['border_left']['w']/$k)/2) ;
6768 $objattr['BORDER-Y'] = $y + $objattr['margin_top']/$k + (($objattr['border_top']['w']/$k)/2) ;
6769 $objattr['INNER-X'] = $x + $objattr['padding_left']/$k + $objattr['margin_left']/$k + ($objattr['border_left']['w']/$k);
6770 $objattr['INNER-Y'] = $y + $objattr['padding_top']/$k + $objattr['margin_top']/$k + ($objattr['border_top']['w']/$k) ;
6771 $objattr['INNER-WIDTH'] = $b_w;
6772 $objattr['INNER-HEIGHT'] = $b_h;
6773 }
6774
6775
6776 if ($type == 'textarea') {
6777 // Automatically resize to width remaining
6778 if ($w > $widthLeft && !$is_table) {
6779 $w = $widthLeft ;
6780 }
6781 if (($y + $h > $this->PageBreakTrigger) && !$this->InFooter) {
6782 $h=$this->h - $y - $this->bMargin;
6783 }
6784 }
6785
6786 if ($type == 'hr') {
6787 if ($is_table) {
6788 $objattr['INNER-WIDTH'] = $maxWidth * $objattr['W-PERCENT']/100;
6789 $objattr['width'] = $objattr['INNER-WIDTH'];
6790 $w = $maxWidth;
6791 }
6792 else {
6793 if ($w>$maxWidth) { $w = $maxWidth; }
6794 $objattr['INNER-WIDTH'] = $w;
6795 $w = $maxWidth;
6796 }
6797 }
6798
6799
6800
6801 if (($type == 'select') || ($type == 'input' && ($objattr['subtype'] == 'TEXT' || $objattr['subtype'] == 'PASSWORD'))) {
6802 // Automatically resize to width remaining
6803 if ($w > $widthLeft && !$is_table) {
6804 $w = $widthLeft;
6805 }
6806 }
6807
6808 if ($type == 'textarea' || $type == 'select' || $type == 'input') {
6809 if (isset($objattr['fontsize'])) $objattr['fontsize'] /= $k;
6810 if (isset($objattr['linewidth'])) $objattr['linewidth'] /= $k;
6811 }
6812
6813 if (!isset($objattr['BORDER-Y'])) { $objattr['BORDER-Y'] = 0; }
6814 if (!isset($objattr['BORDER-X'])) { $objattr['BORDER-X'] = 0; }
6815 if (!isset($objattr['INNER-Y'])) { $objattr['INNER-Y'] = 0; }
6816 if (!isset($objattr['INNER-X'])) { $objattr['INNER-X'] = 0; }
6817
6818 //Return width-height array
6819 $objattr['OUTER-WIDTH'] = $w;
6820 $objattr['OUTER-HEIGHT'] = $h;
6821 $objattr['OUTER-X'] = $x;
6822 $objattr['OUTER-Y'] = $y;
6823 return $objattr;
6824 }
6825
6826 /*-- END HTML-CSS --*/
6827
6828 //=============================================================
6829 //=============================================================
6830 //=============================================================
6831 //=============================================================
6832 //=============================================================
6833
6834 function SetLineJoin($mode=0)
6835 {
6836 $s=sprintf('%d j',$mode);
6837 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); }
6838 $this->pageoutput[$this->page]['LineJoin'] = $s;
6839
6840 }
6841 function SetLineCap($mode=2) {
6842 $s=sprintf('%d J',$mode);
6843 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); }
6844 $this->pageoutput[$this->page]['LineCap'] = $s;
6845
6846 }
6847
6848 function SetDash($black=false,$white=false)
6849 {
6850 if($black and $white) $s=sprintf('[%.3F %.3F] 0 d',$black*_MPDFK,$white*_MPDFK);
6851 else $s='[] 0 d';
6852 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); }
6853 $this->pageoutput[$this->page]['Dash'] = $s;
6854
6855 }
6856
6857 function SetDisplayPreferences($preferences) {
6858 // String containing any or none of /HideMenubar/HideToolbar/HideWindowUI/DisplayDocTitle/CenterWindow/FitWindow
6859 $this->DisplayPreferences .= $preferences;
6860 }
6861
6862
6863 function Ln($h='',$collapsible=0)
6864 {
6865 // Added collapsible to allow collapsible top-margin on new page
6866 //Line feed; default value is last cell height
6867 $this->x = $this->lMargin + $this->blk[$this->blklvl]['outer_left_margin'];
6868 if ($collapsible && ($this->y==$this->tMargin) && (!$this->ColActive)) { $h = 0; }
6869 if(is_string($h)) $this->y+=$this->lasth;
6870 else $this->y+=$h;
6871 }
6872
6873 /*-- HTML-CSS --*/
6874 // $state = 0 normal; 1 top; 2 bottom; 3 top and bottom
6875 function DivLn($h,$level=-3,$move_y=true,$collapsible=false,$state=0) {
6876 // this->x is returned as it was
6877 // adds lines (y) where DIV bgcolors are filled in
6878 // allows .00001 as nominal height used for bookmarks/annotations etc.
6879 if ($collapsible && (sprintf("%0.4f", $this->y)==sprintf("%0.4f", $this->tMargin)) && (!$this->ColActive)) { return; }
6880 if ($collapsible && (sprintf("%0.4f", $this->y)==sprintf("%0.4f", $this->y0)) && ($this->ColActive) && $this->CurrCol == 0) { return; } // *COLUMNS*
6881
6882 // Still use this method if columns or page-break-inside: avoid, as it allows repositioning later
6883 // otherwise, now uses PaintDivBB()
6884 if (!$this->ColActive && !$this->keep_block_together && !$this->kwt) {
6885 if ($move_y && !$this->ColActive) { $this->y += $h; }
6886 return;
6887 }
6888
6889 if ($level == -3) { $level = $this->blklvl; }
6890 $firstblockfill = $this->GetFirstBlockFill();
6891 if ($firstblockfill && $this->blklvl > 0 && $this->blklvl >= $firstblockfill) {
6892 $last_x = 0;
6893 $last_w = 0;
6894 $last_fc = $this->FillColor;
6895 $bak_x = $this->x;
6896 $bak_h = $this->divheight;
6897 $this->divheight = 0; // Temporarily turn off divheight - as Cell() uses it to check for PageBreak
6898 for ($blvl=$firstblockfill;$blvl<=$level;$blvl++) {
6899 $this->SetBlockFill($blvl);
6900 $this->x = $this->lMargin + $this->blk[$blvl]['outer_left_margin'];
6901 if ($last_x != $this->lMargin + $this->blk[$blvl]['outer_left_margin'] || $last_w != $this->blk[$blvl]['width'] || $last_fc != $this->FillColor) {
6902 $x = $this->x;
6903 $this->Cell( ($this->blk[$blvl]['width']), $h, '', '', 0, '', 1);
6904 if (!$this->keep_block_together && !$this->writingHTMLheader && !$this->writingHTMLfooter) {
6905 $this->x = $x;
6906 // $state = 0 normal; 1 top; 2 bottom; 3 top and bottom
6907 if ($blvl == $this->blklvl) { $this->PaintDivLnBorder($state,$blvl,$h); }
6908 else { $this->PaintDivLnBorder(0,$blvl,$h); }
6909 }
6910 }
6911 $last_x = $this->lMargin + $this->blk[$blvl]['outer_left_margin'];
6912 $last_w = $this->blk[$blvl]['width'];
6913 $last_fc = $this->FillColor;
6914 }
6915 // Reset current block fill
6916 if (isset($this->blk[$this->blklvl]['bgcolorarray'])) {
6917 $bcor = $this->blk[$this->blklvl]['bgcolorarray'];
6918 $this->SetFColor($bcor);
6919 }
6920 $this->x = $bak_x;
6921 $this->divheight = $bak_h;
6922 }
6923 if ($move_y) { $this->y += $h; }
6924 }
6925 /*-- END HTML-CSS --*/
6926
6927
6928 function SetX($x)
6929 {
6930 //Set x position
6931 if($x >= 0) $this->x=$x;
6932 else $this->x = $this->w + $x;
6933 }
6934
6935 function SetY($y)
6936 {
6937 //Set y position and reset x
6938 $this->x=$this->lMargin;
6939 if($y>=0)
6940 $this->y=$y;
6941 else
6942 $this->y=$this->h+$y;
6943 }
6944
6945 function SetXY($x,$y)
6946 {
6947 //Set x and y positions
6948 $this->SetY($y);
6949 $this->SetX($x);
6950 }
6951
6952
6953 function Output($name='',$dest='')
6954 {
6955 //Output PDF to some destination
6956 if ($this->showStats) {
6957 echo '<div>Generated in '.sprintf('%.2F',(microtime(true) - $this->time0)).' seconds</div>';
6958 }
6959 //Finish document if necessary
6960 if ($this->progressBar) { $this->UpdateProgressBar(1,'100','Finished'); } // *PROGRESS-BAR*
6961 if($this->state < 3) $this->Close();
6962 if ($this->progressBar) { $this->UpdateProgressBar(2,'100','Finished'); } // *PROGRESS-BAR*
6963 // fn. error_get_last is only in PHP>=5.2
6964 if ($this->debug && function_exists('error_get_last') && error_get_last()) {
6965 $e = error_get_last();
6966 if (($e['type'] < 2048 && $e['type'] != 8) || (intval($e['type']) & intval(ini_get("error_reporting")))) {
6967 echo "<p>Error message detected - PDF file generation aborted.</p>";
6968 echo $e['message'].'<br />';
6969 echo 'File: '.$e['file'].'<br />';
6970 echo 'Line: '.$e['line'].'<br />';
6971 exit;
6972 }
6973 }
6974
6975
6976 if (($this->PDFA || $this->PDFX) && $this->encrypted) { $this->Error("PDFA1-b or PDFX/1-a does not permit encryption of documents."); }
6977 if (count($this->PDFAXwarnings) && (($this->PDFA && !$this->PDFAauto) || ($this->PDFX && !$this->PDFXauto))) {
6978 if ($this->PDFA) {
6979 echo '<div>WARNING - This file could not be generated as it stands as a PDFA1-b compliant file.</div>';
6980 echo '<div>These issues can be automatically fixed by mPDF using <i>$mpdf-&gt;PDFAauto=true;</i></div>';
6981 echo '<div>Action that mPDF will take to automatically force PDFA1-b compliance are shown in brackets.</div>';
6982 }
6983 else {
6984 echo '<div>WARNING - This file could not be generated as it stands as a PDFX/1-a compliant file.</div>';
6985 echo '<div>These issues can be automatically fixed by mPDF using <i>$mpdf-&gt;PDFXauto=true;</i></div>';
6986 echo '<div>Action that mPDF will take to automatically force PDFX/1-a compliance are shown in brackets.</div>';
6987 }
6988 echo '<div>Warning(s) generated:</div><ul>';
6989 $this->PDFAXwarnings = array_unique($this->PDFAXwarnings);
6990 foreach($this->PDFAXwarnings AS $w) {
6991 echo '<li>'.$w.'</li>';
6992 }
6993 echo '</ul>';
6994 exit;
6995 }
6996
6997 if ($this->showStats) {
6998 echo '<div>Compiled in '.sprintf('%.2F',(microtime(true) - $this->time0)).' seconds (total)</div>';
6999 echo '<div>Peak Memory usage '.number_format((memory_get_peak_usage(true)/(1024*1024)),2).' MB</div>';
7000 echo '<div>PDF file size '.number_format((strlen($this->buffer)/1024)).' kB</div>';
7001 echo '<div>Number of fonts '.count($this->fonts).'</div>';
7002 exit;
7003 }
7004
7005
7006 if(is_bool($dest)) $dest=$dest ? 'D' : 'F';
7007 $dest=strtoupper($dest);
7008 if($dest=='') {
7009 if($name=='') {
7010 $name='mpdf.pdf';
7011 $dest='I';
7012 }
7013 else { $dest='F'; }
7014 }
7015
7016 /*-- PROGRESS-BAR --*/
7017 if ($this->progressBar && ($dest=='D' || $dest=='I')) {
7018 if($name=='') { $name='mpdf.pdf'; }
7019 $tempfile = '_tempPDF'.RAND(1,10000);
7020 //Save to local file
7021 $f=fopen(_MPDF_TEMP_PATH.$tempfile.'.pdf','wb');
7022 if(!$f) $this->Error('Unable to create temporary output file: '.$tempfile.'.pdf');
7023 fwrite($f,$this->buffer,strlen($this->buffer));
7024 fclose($f);
7025 $this->UpdateProgressBar(3,'','Finished');
7026
7027 echo '<script type="text/javascript">
7028
7029 var form = document.createElement("form");
7030 form.setAttribute("method", "post");
7031 form.setAttribute("action", "'._MPDF_URI.'includes/out.php");
7032
7033 var hiddenField = document.createElement("input");
7034 hiddenField.setAttribute("type", "hidden");
7035 hiddenField.setAttribute("name", "filename");
7036 hiddenField.setAttribute("value", "'.$tempfile.'");
7037 form.appendChild(hiddenField);
7038
7039 var hiddenField = document.createElement("input");
7040 hiddenField.setAttribute("type", "hidden");
7041 hiddenField.setAttribute("name", "dest");
7042 hiddenField.setAttribute("value", "'.$dest.'");
7043 form.appendChild(hiddenField);
7044
7045 var hiddenField = document.createElement("input");
7046 hiddenField.setAttribute("type", "hidden");
7047 hiddenField.setAttribute("name", "opname");
7048 hiddenField.setAttribute("value", "'.$name.'");
7049 form.appendChild(hiddenField);
7050
7051 var hiddenField = document.createElement("input");
7052 hiddenField.setAttribute("type", "hidden");
7053 hiddenField.setAttribute("name", "path");
7054 hiddenField.setAttribute("value", "'.urlencode(_MPDF_TEMP_PATH).'");
7055 form.appendChild(hiddenField);
7056
7057 document.body.appendChild(form);
7058 form.submit();
7059
7060 </script>
7061 </div>
7062 </body>
7063 </html>';
7064 exit;
7065 }
7066 else {
7067 if ($this->progressBar) { $this->UpdateProgressBar(3,'','Finished'); }
7068 /*-- END PROGRESS-BAR --*/
7069
7070 switch($dest) {
7071 case 'I':
7072 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; }
7073 //Send to standard output
7074 if(PHP_SAPI!='cli') {
7075 //We send to a browser
7076 header('Content-Type: application/pdf');
7077 if(headers_sent())
7078 $this->Error('Some data has already been output to browser, can\'t send PDF file');
7079 if (!isset($_SERVER['HTTP_ACCEPT_ENCODING']) OR empty($_SERVER['HTTP_ACCEPT_ENCODING'])) {
7080 // don't use length if server using compression
7081 header('Content-Length: '.strlen($this->buffer));
7082 }
7083 header('Content-disposition: inline; filename="'.$name.'"');
7084 header('Cache-Control: public, must-revalidate, max-age=0');
7085 header('Pragma: public');
7086 header('Expires: Sat, 26 Jul 1997 05:00:00 GMT');
7087 header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT');
7088 }
7089 echo $this->buffer;
7090 break;
7091 case 'D':
7092 //Download file
7093 header('Content-Description: File Transfer');
7094 if (headers_sent())
7095 $this->Error('Some data has already been output to browser, can\'t send PDF file');
7096 header('Content-Transfer-Encoding: binary');
7097 header('Cache-Control: public, must-revalidate, max-age=0');
7098 header('Pragma: public');
7099 header('Expires: Sat, 26 Jul 1997 05:00:00 GMT');
7100 header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT');
7101 header('Content-Type: application/force-download');
7102 header('Content-Type: application/octet-stream', false);
7103 header('Content-Type: application/download', false);
7104 header('Content-Type: application/pdf', false);
7105 if (!isset($_SERVER['HTTP_ACCEPT_ENCODING']) OR empty($_SERVER['HTTP_ACCEPT_ENCODING'])) {
7106 // don't use length if server using compression
7107 header('Content-Length: '.strlen($this->buffer));
7108 }
7109 header('Content-disposition: attachment; filename="'.$name.'"');
7110 echo $this->buffer;
7111 break;
7112 case 'F':
7113 //Save to local file
7114 $f=fopen($name,'wb');
7115 if(!$f) $this->Error('Unable to create output file: '.$name);
7116 fwrite($f,$this->buffer,strlen($this->buffer));
7117 fclose($f);
7118 break;
7119 case 'S':
7120 //Return as a string
7121 return $this->buffer;
7122 default:
7123 $this->Error('Incorrect output destination: '.$dest);
7124 }
7125
7126 } // *PROGRESS-BAR*
7127 //======================================================================================================
7128 // mPDF 5.3.79
7129 // DELETE OLD TMP FILES - Housekeeping
7130 // Delete any files in tmp/ directory that are >1 hrs old
7131 $interval = 3600;
7132 if ($handle = opendir(preg_replace('/\/$/','',_MPDF_TEMP_PATH))) {
7133 while (false !== ($file = readdir($handle))) {
7134 if (((filemtime(_MPDF_TEMP_PATH.$file)+$interval) < time()) && ($file != "..") && ($file != ".")) {
7135 unlink(_MPDF_TEMP_PATH.$file);
7136 }
7137 }
7138 closedir($handle);
7139 }
7140 //==============================================================================================================
7141
7142 return '';
7143 }
7144
7145
7146 // *****************************************************************************
7147 // *
7148 // Protected methods *
7149 // *
7150 // *****************************************************************************
7151 function _dochecks()
7152 {
7153 //Check for locale-related bug
7154 if(1.1==1)
7155 $this->Error('Don\'t alter the locale before including mPDF');
7156 //Check for decimal separator
7157 if(sprintf('%.1f',1.0)!='1.0')
7158 setlocale(LC_NUMERIC,'C');
7159 }
7160
7161 function _begindoc()
7162 {
7163 //Start document
7164 $this->state=1;
7165 $this->_out('%PDF-'.$this->pdf_version);
7166 $this->_out('%'.chr(226).chr(227).chr(207).chr(211)); // 4 chars > 128 to show binary file
7167 }
7168
7169
7170 /*-- HTMLHEADERS-FOOTERS --*/
7171 function _puthtmlheaders() {
7172 $this->state=2;
7173 $nb=$this->page;
7174 for($n=1;$n<=$nb;$n++) {
7175 if ($this->mirrorMargins && $n%2==0) { $OE = 'E'; } // EVEN
7176 else { $OE = 'O'; }
7177 $this->page = $n;
7178 if (isset($this->saveHTMLHeader[$n][$OE])) {
7179 $html = $this->saveHTMLHeader[$n][$OE]['html'];
7180 $this->lMargin = $this->saveHTMLHeader[$n][$OE]['ml'];
7181 $this->rMargin = $this->saveHTMLHeader[$n][$OE]['mr'];
7182 $this->tMargin = $this->saveHTMLHeader[$n][$OE]['mh'];
7183 $this->bMargin = $this->saveHTMLHeader[$n][$OE]['mf'];
7184 $this->margin_header = $this->saveHTMLHeader[$n][$OE]['mh'];
7185 $this->margin_footer = $this->saveHTMLHeader[$n][$OE]['mf'];
7186 $this->w = $this->saveHTMLHeader[$n][$OE]['pw'];
7187 $this->h = $this->saveHTMLHeader[$n][$OE]['ph'];
7188 $rotate = (isset($this->saveHTMLHeader[$n][$OE]['rotate']) ? $this->saveHTMLHeader[$n][$OE]['rotate'] : null);
7189 $this->Reset();
7190 $this->pageoutput[$n] = array();
7191 $this->pgwidth = $this->w - $this->lMargin - $this->rMargin;
7192 $this->x = $this->lMargin;
7193 $this->y = $this->margin_header;
7194
7195 $html = str_replace('{PAGENO}',$this->pagenumPrefix.$this->docPageNum($n).$this->pagenumSuffix,$html);
7196 $html = str_replace($this->aliasNbPgGp,$this->nbpgPrefix.$this->docPageNumTotal($n).$this->nbpgSuffix,$html ); // {nbpg}
7197 $html = str_replace($this->aliasNbPg,$nb,$html ); // {nb}
7198 $html = preg_replace('/\{DATE\s+(.*?)\}/e',"date('\\1')",$html );
7199
7200 $this->HTMLheaderPageLinks = array();
7201 $this->HTMLheaderPageAnnots = array();
7202 $this->HTMLheaderPageForms = array();
7203 $this->pageBackgrounds = array();
7204
7205 $this->writingHTMLheader = true;
7206 $this->WriteHTML($html , 4); // parameter 4 saves output to $this->headerbuffer
7207 $this->writingHTMLheader = false;
7208 $this->Reset();
7209 $this->pageoutput[$n] = array();
7210
7211 $s = $this->PrintPageBackgrounds();
7212 $this->headerbuffer = $s . $this->headerbuffer;
7213 $os = '';
7214 if ($rotate) {
7215 $os .= sprintf('q 0 -1 1 0 0 %.3F cm ',($this->w*_MPDFK));
7216 }
7217 $os .= $this->headerbuffer ;
7218 if ($rotate) {
7219 $os .= ' Q' . "\n";
7220 }
7221
7222 // Writes over the page background but behind any other output on page
7223 $os = preg_replace('/\\\\/','\\\\\\\\',$os);
7224 $this->pages[$n] = preg_replace('/(___HEADER___MARKER'.date('jY').')/', "\n".$os."\n".'\\1', $this->pages[$n]);
7225
7226 $lks = $this->HTMLheaderPageLinks;
7227 foreach($lks AS $lk) {
7228 if ($rotate) {
7229 $lw = $lk[2];
7230 $lh = $lk[3];
7231 $lk[2] = $lh;
7232 $lk[3] = $lw; // swap width and height
7233 $ax = $lk[0]/_MPDFK;
7234 $ay = $lk[1]/_MPDFK;
7235 $bx = $ay-($lh/_MPDFK);
7236 $by = $this->w-$ax;
7237 $lk[0] = $bx*_MPDFK;
7238 $lk[1] = ($this->h-$by)*_MPDFK - $lw;
7239 }
7240 $this->PageLinks[$n][]=$lk;
7241 }
7242 /*-- FORMS --*/
7243 foreach($this->HTMLheaderPageForms AS $f) {
7244 $this->form->forms[$f['n']] = $f;
7245 }
7246 /*-- END FORMS --*/
7247
7248
7249 }
7250 if (isset($this->saveHTMLFooter[$n][$OE])) {
7251 $html = $this->saveHTMLFooter[$this->page][$OE]['html'];
7252 $this->lMargin = $this->saveHTMLFooter[$n][$OE]['ml'];
7253 $this->rMargin = $this->saveHTMLFooter[$n][$OE]['mr'];
7254 $this->tMargin = $this->saveHTMLFooter[$n][$OE]['mh'];
7255 $this->bMargin = $this->saveHTMLFooter[$n][$OE]['mf'];
7256 $this->margin_header = $this->saveHTMLFooter[$n][$OE]['mh'];
7257 $this->margin_footer = $this->saveHTMLFooter[$n][$OE]['mf'];
7258 $this->w = $this->saveHTMLFooter[$n][$OE]['pw'];
7259 $this->h = $this->saveHTMLFooter[$n][$OE]['ph'];
7260 $rotate = (isset($this->saveHTMLFooter[$n][$OE]['rotate']) ? $this->saveHTMLFooter[$n][$OE]['rotate'] : null);
7261 $this->Reset();
7262 $this->pageoutput[$n] = array();
7263 $this->pgwidth = $this->w - $this->lMargin - $this->rMargin;
7264 $this->x = $this->lMargin;
7265 $top_y = $this->y = $this->h - $this->margin_footer;
7266
7267 // if bottom-margin==0, corrects to avoid division by zero
7268 if ($this->y == $this->h) { $top_y = $this->y = ($this->h - 0.1); }
7269
7270 $html = str_replace('{PAGENO}',$this->pagenumPrefix.$this->docPageNum($n).$this->pagenumSuffix,$html);
7271 $html = str_replace($this->aliasNbPgGp,$this->nbpgPrefix.$this->docPageNumTotal($n).$this->nbpgSuffix,$html ); // {nbpg}
7272 $html = str_replace($this->aliasNbPg,$nb,$html ); // {nb}
7273 $html = preg_replace('/\{DATE\s+(.*?)\}/e',"date('\\1')",$html );
7274
7275
7276 $this->HTMLheaderPageLinks = array();
7277 $this->HTMLheaderPageAnnots = array();
7278 $this->HTMLheaderPageForms = array();
7279 $this->pageBackgrounds = array();
7280
7281 $this->writingHTMLfooter = true;
7282 $this->InFooter = true;
7283 $this->WriteHTML($html , 4); // parameter 4 saves output to $this->headerbuffer
7284 $this->writingHTMLfooter = false;
7285 $this->InFooter = false;
7286 $this->Reset();
7287 $this->pageoutput[$n] = array();
7288
7289 $fheight = $this->y - $top_y;
7290 $adj = -$fheight;
7291
7292 $s = $this->PrintPageBackgrounds(-$adj);
7293 $this->headerbuffer = $s . $this->headerbuffer;
7294
7295 $os = '';
7296 $os .= $this->StartTransform(true)."\n";
7297 if ($rotate) {
7298 $os .= sprintf('q 0 -1 1 0 0 %.3F cm ',($this->w*_MPDFK));
7299 }
7300 $os .= $this->transformTranslate(0, $adj, true)."\n";
7301 $os .= $this->headerbuffer ;
7302 if ($rotate) {
7303 $os .= ' Q' . "\n";
7304 }
7305 $os .= $this->StopTransform(true)."\n";
7306 // Writes over the page background but behind any other output on page
7307 $os = preg_replace('/\\\\/','\\\\\\\\',$os);
7308 $this->pages[$n] = preg_replace('/(___HEADER___MARKER'.date('jY').')/', "\n".$os."\n".'\\1', $this->pages[$n]);
7309
7310 $lks = $this->HTMLheaderPageLinks;
7311 foreach($lks AS $lk) {
7312 $lk[1] -= $adj*_MPDFK;
7313 if ($rotate) {
7314 $lw = $lk[2];
7315 $lh = $lk[3];
7316 $lk[2] = $lh;
7317 $lk[3] = $lw; // swap width and height
7318
7319 $ax = $lk[0]/_MPDFK;
7320 $ay = $lk[1]/_MPDFK;
7321 $bx = $ay-($lh/_MPDFK);
7322 $by = $this->w-$ax;
7323 $lk[0] = $bx*_MPDFK;
7324 $lk[1] = ($this->h-$by)*_MPDFK - $lw;
7325 }
7326 $this->PageLinks[$n][]=$lk;
7327 }
7328 /*-- FORMS --*/
7329 foreach($this->HTMLheaderPageForms AS $f) {
7330 $f['y'] += $adj;
7331 $this->form->forms[$f['n']] = $f;
7332 }
7333 /*-- END FORMS --*/
7334 }
7335 }
7336 $this->page=$nb;
7337 $this->state=1;
7338 }
7339 /*-- END HTMLHEADERS-FOOTERS --*/
7340
7341
7342 function _putpages()
7343 {
7344 $nb=$this->page;
7345 $filter=($this->compress) ? '/Filter /FlateDecode ' : '';
7346
7347 if($this->DefOrientation=='P') {
7348 $defwPt=$this->fwPt;
7349 $defhPt=$this->fhPt;
7350 }
7351 else {
7352 $defwPt=$this->fhPt;
7353 $defhPt=$this->fwPt;
7354 }
7355 $annotid=(3+2*$nb);
7356
7357 // Active Forms
7358 $totaladdnum = 0;
7359 for($n=1;$n<=$nb;$n++) {
7360 if (isset($this->PageLinks[$n])) { $totaladdnum += count($this->PageLinks[$n]); }
7361 /*-- ANNOTATIONS --*/
7362 if (isset($this->PageAnnots[$n])) {
7363 foreach ($this->PageAnnots[$n] as $k => $pl) {
7364 if (!empty($pl['opt']['popup']) || !empty($pl['opt']['file'])) { $totaladdnum += 2 ; }
7365 else { $totaladdnum++; }
7366 }
7367 }
7368 /*-- END ANNOTATIONS --*/
7369
7370 /*-- FORMS --*/
7371 if ( count($this->form->forms) > 0 ) {
7372 $this->form->countPageForms($n, $totaladdnum);
7373 }
7374 /*-- END FORMS --*/
7375 }
7376 /*-- FORMS --*/
7377 // Make a note in the radio button group of the obj_id it will have
7378 $ctr = 0;
7379 if (count($this->form->form_radio_groups)) {
7380 foreach($this->form->form_radio_groups AS $name=>$frg) {
7381 $this->form->form_radio_groups[$name]['obj_id'] = $annotid + $totaladdnum + $ctr;
7382 $ctr++;
7383 }
7384 }
7385 /*-- END FORMS --*/
7386
7387 // mPDF 5.3.99
7388 // Select unused fonts (usually default font)
7389 $unused = array();
7390 foreach($this->fonts as $fk=>$font) {
7391 if (!$font['used'] && ($font['type']=='TTF')) {
7392 $unused[] = $fk;
7393 }
7394 }
7395
7396
7397 for($n=1;$n<=$nb;$n++)
7398 {
7399 $thispage = $this->pages[$n]; // mPDF 5.3.99
7400 unset($this->pages[$n]); // mPDF 5.3.99
7401 if(isset($this->OrientationChanges[$n])) {
7402 $hPt=$this->pageDim[$n]['w']*_MPDFK;
7403 $wPt=$this->pageDim[$n]['h']*_MPDFK;
7404 $owidthPt_LR = $this->pageDim[$n]['outer_width_TB']*_MPDFK;
7405 $owidthPt_TB = $this->pageDim[$n]['outer_width_LR']*_MPDFK;
7406 }
7407 else {
7408 $wPt=$this->pageDim[$n]['w']*_MPDFK;
7409 $hPt=$this->pageDim[$n]['h']*_MPDFK;
7410 $owidthPt_LR = $this->pageDim[$n]['outer_width_LR']*_MPDFK;
7411 $owidthPt_TB = $this->pageDim[$n]['outer_width_TB']*_MPDFK;
7412 }
7413 // mPDF 5.3.99
7414 // Remove references to unused fonts (usually default font)
7415 foreach($unused as $fk) {
7416 if ($this->fonts[$fk]['sip'] || $this->fonts[$fk]['smp']) {
7417 foreach($this->fonts[$fk]['subsetfontids'] AS $k => $fid) {
7418 $thispage = preg_replace('/\s\/F'.$fid.' \d[\d.]* Tf\s/is',' ',$thispage);
7419 }
7420 }
7421 else {
7422 $thispage = preg_replace('/\s\/F'.$this->fonts[$fk]['i'].' \d[\d.]* Tf\s/is',' ',$thispage);
7423 }
7424 }
7425 //Replace number of pages
7426 if(!empty($this->aliasNbPg)) {
7427 if (!$this->onlyCoreFonts) { $s1 = $this->UTF8ToUTF16BE($this->aliasNbPg, false); } // mPDF 5.3.22
7428 $s2 = $this->aliasNbPg;
7429 if (!$this->onlyCoreFonts) { $r1 = $this->UTF8ToUTF16BE($nb, false); } // mPDF 5.3.22
7430 $r2 = $nb;
7431 if (preg_match_all('/{mpdfheadernbpg (C|R) ff=(\S*) fs=(\S*) fz=(.*?)}/',$thispage,$m)) {
7432 for($hi=0;$hi<count($m[0]);$hi++) {
7433 $pos = $m[1][$hi];
7434 $hff = $m[2][$hi];
7435 $hfst = $m[3][$hi];
7436 $hfsz = $m[4][$hi];
7437 $this->SetFont($hff,$hfst,$hfsz, false);
7438 $x1 = $this->GetStringWidth($this->aliasNbPg);
7439 $x2 = $this->GetStringWidth($nb);
7440 $xadj = $x1 - $x2;
7441 if ($pos=='C') { $xadj /= 2; }
7442 $rep = sprintf(' q 1 0 0 1 %.3F 0 cm ', $xadj*_MPDFK);
7443 $thispage = str_replace($m[0][$hi], $rep, $thispage);
7444 }
7445 }
7446 if (!$this->onlyCoreFonts) { $thispage=str_replace($s1,$r1,$thispage); } // mPDF 5.3.22
7447 $thispage=str_replace($s2,$r2,$thispage); // mPDF 5.3.22
7448
7449 // And now for any SMP/SIP fonts subset using <HH> format
7450 $r = '';
7451 $nstr = "$nb";
7452 for($i=0;$i<strlen($nstr);$i++) {
7453 $r .= sprintf("%02s", strtoupper(dechex(intval($nstr[$i])+48)));
7454 }
7455 $thispage=str_replace($this->aliasNbPgHex,$r,$thispage);
7456
7457 }
7458 //Replace number of pages in group
7459 if(!empty($this->aliasNbPgGp)) {
7460 if (!$this->onlyCoreFonts) { $s1 = $this->UTF8ToUTF16BE($this->aliasNbPgGp, false); } // mPDF 5.3.22
7461 $s2 = $this->aliasNbPgGp;
7462 $nbt = $this->docPageNumTotal($n);
7463 if (!$this->onlyCoreFonts) { $r1 = $this->UTF8ToUTF16BE($nbt, false); } // mPDF 5.3.22
7464 $r2 = $nbt;
7465 if (preg_match_all('/{mpdfheadernbpggp (C|R) ff=(\S*) fs=(\S*) fz=(.*?)}/',$thispage,$m)) {
7466 for($hi=0;$hi<count($m[0]);$hi++) {
7467 $pos = $m[1][$hi];
7468 $hff = $m[2][$hi];
7469 $hfst = $m[3][$hi];
7470 $hfsz = $m[4][$hi];
7471 $this->SetFont($hff,$hfst,$hfsz, false);
7472 $x1 = $this->GetStringWidth($this->aliasNbPgGp);
7473 $x2 = $this->GetStringWidth($nbt);
7474 $xadj = $x1 - $x2;
7475 if ($pos=='C') { $xadj /= 2; }
7476 $rep = sprintf(' q 1 0 0 1 %.3F 0 cm ', $xadj*_MPDFK);
7477 $thispage = str_replace($m[0][$hi], $rep, $thispage);
7478 }
7479 }
7480 if (!$this->onlyCoreFonts) { $thispage=str_replace($s1,$r1,$thispage); } // mPDF 5.3.22
7481 $thispage=str_replace($s2,$r2,$thispage);
7482
7483 // And now for any SMP/SIP fonts subset using <HH> format
7484 $r = '';
7485 $nstr = "$nbt";
7486 for($i=0;$i<strlen($nstr);$i++) {
7487 $r .= sprintf("%02s", strtoupper(dechex(intval($nstr[$i])+48)));
7488 }
7489 $thispage=str_replace($this->aliasNbPgGpHex,$r,$thispage);
7490
7491 }
7492 $thispage = preg_replace('/(\s*___BACKGROUND___PATTERNS'.date('jY').'\s*)/', " ", $thispage);
7493 $thispage = preg_replace('/(\s*___HEADER___MARKER'.date('jY').'\s*)/', " ", $thispage);
7494 $thispage = preg_replace('/(\s*___PAGE___START'.date('jY').'\s*)/', " ", $thispage);
7495 $thispage = preg_replace('/(\s*___TABLE___BACKGROUNDS'.date('jY').'\s*)/', " ", $thispage);
7496
7497 //Page
7498 $this->_newobj();
7499 $this->_out('<</Type /Page');
7500 $this->_out('/Parent 1 0 R');
7501 if(isset($this->OrientationChanges[$n])) {
7502 $this->_out(sprintf('/MediaBox [0 0 %.3F %.3F]',$hPt,$wPt));
7503 //If BleedBox is defined, it must be larger than the TrimBox, but smaller than the MediaBox
7504 $bleedMargin = $this->pageDim[$n]['bleedMargin']*_MPDFK;
7505 if ($bleedMargin && ($owidthPt_TB || $owidthPt_LR)) {
7506 $x0 = $owidthPt_TB-$bleedMargin;
7507 $y0 = $owidthPt_LR-$bleedMargin;
7508 $x1 = $hPt-$owidthPt_TB+$bleedMargin;
7509 $y1 = $wPt-$owidthPt_LR+$bleedMargin;
7510 $this->_out(sprintf('/BleedBox [%.3F %.3F %.3F %.3F]', $x0, $y0, $x1, $y1));
7511 }
7512 $this->_out(sprintf('/TrimBox [%.3F %.3F %.3F %.3F]', $owidthPt_TB, $owidthPt_LR, ($hPt-$owidthPt_TB), ($wPt-$owidthPt_LR)));
7513 if (isset($this->OrientationChanges[$n]) && $this->displayDefaultOrientation) {
7514 if ($this->DefOrientation=='P') { $this->_out('/Rotate 270'); }
7515 else { $this->_out('/Rotate 90'); }
7516 }
7517 }
7518 //else if($wPt != $defwPt || $hPt != $defhPt) {
7519 else {
7520 $this->_out(sprintf('/MediaBox [0 0 %.3F %.3F]',$wPt,$hPt));
7521 $bleedMargin = $this->pageDim[$n]['bleedMargin']*_MPDFK;
7522 if ($bleedMargin && ($owidthPt_TB || $owidthPt_LR)) {
7523 $x0 = $owidthPt_LR-$bleedMargin;
7524 $y0 = $owidthPt_TB-$bleedMargin;
7525 $x1 = $wPt-$owidthPt_LR+$bleedMargin;
7526 $y1 = $hPt-$owidthPt_TB+$bleedMargin;
7527 $this->_out(sprintf('/BleedBox [%.3F %.3F %.3F %.3F]', $x0, $y0, $x1, $y1));
7528 }
7529 $this->_out(sprintf('/TrimBox [%.3F %.3F %.3F %.3F]', $owidthPt_LR, $owidthPt_TB, ($wPt-$owidthPt_LR), ($hPt-$owidthPt_TB)));
7530 }
7531 $this->_out('/Resources 2 0 R');
7532
7533 // Important to keep in RGB colorSpace when using transparency
7534 if (!$this->PDFA && !$this->PDFX) {
7535 if ($this->restrictColorSpace == 3)
7536 $this->_out('/Group << /Type /Group /S /Transparency /CS /DeviceCMYK >> ');
7537 else if ($this->restrictColorSpace == 1)
7538 $this->_out('/Group << /Type /Group /S /Transparency /CS /DeviceGray >> ');
7539 else
7540 $this->_out('/Group << /Type /Group /S /Transparency /CS /DeviceRGB >> ');
7541 }
7542
7543 $annotsnum = 0;
7544 if (isset($this->PageLinks[$n])) { $annotsnum += count($this->PageLinks[$n]); }
7545 /*-- ANNOTATIONS --*/
7546 if (isset($this->PageAnnots[$n])) {
7547 foreach ($this->PageAnnots[$n] as $k => $pl) {
7548 if (!empty($pl['opt']['popup']) || !empty($pl['opt']['file'])) { $annotsnum += 2 ; }
7549 else { $annotsnum++; }
7550 $this->PageAnnots[$n][$k]['pageobj'] = $this->n;
7551 }
7552 }
7553 /*-- END ANNOTATIONS --*/
7554
7555 /*-- FORMS --*/
7556 // Active Forms
7557 $formsnum = 0;
7558 if ( count($this->form->forms) > 0 ) {
7559 foreach( $this->form->forms as $val ) {
7560 if ( $val['page'] == $n )
7561 $formsnum++;
7562 }
7563 }
7564 /*-- END FORMS --*/
7565 if ($annotsnum || $formsnum) {
7566 $s = '/Annots [ ';
7567 for($i=0;$i<$annotsnum;$i++) {
7568 $s .= ($annotid + $i) . ' 0 R ';
7569 }
7570 $annotid += $annotsnum;
7571 /*-- FORMS --*/
7572 if ( count($this->form->forms) > 0 ) {
7573 $this->form->addFormIds($n, $s, $annotid);
7574 }
7575 /*-- END FORMS --*/
7576 $s .= '] ';
7577 $this->_out($s);
7578 }
7579
7580 $this->_out('/Contents '.($this->n+1).' 0 R>>');
7581 $this->_out('endobj');
7582
7583 //Page content
7584 $this->_newobj();
7585 $p=($this->compress) ? gzcompress($thispage) : $thispage;
7586 $this->_out('<<'.$filter.'/Length '.strlen($p).'>>');
7587 $this->_putstream($p);
7588 $this->_out('endobj');
7589 }
7590 $this->_putannots($n);
7591
7592 //Pages root
7593 $this->offsets[1]=strlen($this->buffer);
7594 $this->_out('1 0 obj');
7595 $this->_out('<</Type /Pages');
7596 $kids='/Kids [';
7597 for($i=0;$i<$nb;$i++)
7598 $kids.=(3+2*$i).' 0 R ';
7599 $this->_out($kids.']');
7600 $this->_out('/Count '.$nb);
7601 $this->_out(sprintf('/MediaBox [0 0 %.3F %.3F]',$defwPt,$defhPt));
7602 $this->_out('>>');
7603 $this->_out('endobj');
7604 }
7605
7606
7607 function _putannots($n) {
7608 $filter=($this->compress) ? '/Filter /FlateDecode ' : '';
7609 $nb=$this->page;
7610 for($n=1;$n<=$nb;$n++)
7611 {
7612 $annotobjs = array();
7613 if(isset($this->PageLinks[$n]) || isset($this->PageAnnots[$n]) || count($this->form->forms) > 0 ) {
7614 $wPt=$this->pageDim[$n]['w']*_MPDFK;
7615 $hPt=$this->pageDim[$n]['h']*_MPDFK;
7616
7617 //Links
7618 if(isset($this->PageLinks[$n])) {
7619 foreach($this->PageLinks[$n] as $key => $pl) {
7620 $this->_newobj();
7621 $annot='';
7622 $rect=sprintf('%.3F %.3F %.3F %.3F',$pl[0],$pl[1],$pl[0]+$pl[2],$pl[1]-$pl[3]);
7623 $annot .= '<</Type /Annot /Subtype /Link /Rect ['.$rect.']';
7624 $annot .= ' /Contents '.$this->_UTF16BEtextstring($pl[4]);
7625 $annot .= ' /NM '.$this->_textstring(sprintf('%04u-%04u', $n, $key));
7626 $annot .= ' /M '.$this->_textstring('D:'.date('YmdHis'));
7627 $annot .= ' /Border [0 0 0]';
7628 // mPDF 5.3.16 5.3.52 Use this (instead of /Border) to specify border around link
7629 // $annot .= ' /BS <</W 1'; // Width on points; 0 = no line
7630 // $annot .= ' /S /D'; // style - [S]olid, [D]ashed, [B]eveled, [I]nset, [U]nderline
7631 // $annot .= ' /D [3 2]'; // Dash array - if dashed
7632 // $annot .= ' >>';
7633 // $annot .= ' /C [1 0 0]'; // Color RGB
7634
7635 if ($this->PDFA || $this->PDFX) { $annot .= ' /F 28'; }
7636 if (strpos($pl[4],'@')===0) {
7637 $p=substr($pl[4],1);
7638 // $h=isset($this->OrientationChanges[$p]) ? $wPt : $hPt;
7639 $htarg=$this->pageDim[$p]['h']*_MPDFK;
7640 $annot.=sprintf(' /Dest [%d 0 R /XYZ 0 %.3F null]>>',1+2*$p,$htarg);
7641 }
7642 else if(is_string($pl[4])) {
7643 $annot .= ' /A <</S /URI /URI '.$this->_textstring($pl[4]).'>> >>';
7644 }
7645 else {
7646 $l=$this->links[$pl[4]];
7647 // may not be set if #link points to non-existent target
7648 if (isset($this->pageDim[$l[0]]['h'])) { $htarg=$this->pageDim[$l[0]]['h']*_MPDFK; }
7649 else { $htarg=$this->h*_MPDFK; } // doesn't really matter
7650 $annot.=sprintf(' /Dest [%d 0 R /XYZ 0 %.3F null]>>',1+2*$l[0],$htarg-$l[1]*_MPDFK);
7651 }
7652 $this->_out($annot);
7653 $this->_out('endobj');
7654 }
7655 }
7656
7657
7658 /*-- ANNOTATIONS --*/
7659 if(isset($this->PageAnnots[$n])) {
7660 foreach ($this->PageAnnots[$n] as $key => $pl) {
7661 if ($pl['opt']['file']) { $FileAttachment=true; }
7662 else { $FileAttachment=false; }
7663 $this->_newobj();
7664 $annot='';
7665 $pl['opt'] = array_change_key_case($pl['opt'], CASE_LOWER);
7666 $x = $pl['x'];
7667 if ($this->annotMargin <> 0 || $x==0 || $x<0) { // Odd page
7668 $x = ($wPt/_MPDFK) - $this->annotMargin;
7669 }
7670 $w = $h = 0;
7671 $a = $x * _MPDFK;
7672 $b = $hPt - ($pl['y'] * _MPDFK);
7673 $annot .= '<</Type /Annot ';
7674 if ($FileAttachment) {
7675 $annot .= '/Subtype /FileAttachment';
7676 // Need to set a size for FileAttachment icons
7677 if ($pl['opt']['icon']=='Paperclip') { $w=8.235; $h=20; } // 7,17
7678 else if ($pl['opt']['icon']=='Tag') { $w=20; $h=16; }
7679 else if ($pl['opt']['icon']=='Graph') { $w=20; $h=20; }
7680 else { $w=14; $h=20; } // PushPin
7681 $f = $pl['opt']['file'];
7682 $f = preg_replace('/^.*\//', '', $f);
7683 $f = preg_replace('/[^a-zA-Z0-9._]/', '', $f);
7684 $annot .= '/FS <</Type /Filespec /F ('.$f.')';
7685 $annot .= '/EF <</F '.($this->n+1).' 0 R>>';
7686 $annot .= '>>';
7687 }
7688 else {
7689 $annot .= '/Subtype /Text';
7690 }
7691 $rect = sprintf('%.3F %.3F %.3F %.3F', $a, $b-$h, $a+$w, $b);
7692 $annot .= '/Rect ['.$rect.']';
7693
7694 // contents = description of file in free text
7695 $annot .= ' /Contents '.$this->_UTF16BEtextstring($pl['txt']);
7696 $annot .= ' /NM '.$this->_textstring(sprintf('%04u-%04u', $n, (2000 + $key)));
7697 $annot .= ' /M '.$this->_textstring('D:'.date('YmdHis'));
7698 $annot .= ' /CreationDate '.$this->_textstring('D:'.date('YmdHis'));
7699 $annot .= ' /Border [0 0 0]';
7700 if ($this->PDFA || $this->PDFX) {
7701 $annot .= ' /F 28';
7702 $annot .= ' /CA 1';
7703 }
7704 else if ($pl['opt']['ca']>0) { $annot .= ' /CA '.$pl['opt']['ca']; }
7705
7706 $annotcolor = ' /C [';
7707 // mPDF 5.3.74
7708 if (isset($pl['opt']['c']) AND $pl['opt']['c']) {
7709 $col = $pl['opt']['c'];
7710 if ($col{0}==3 || $col{0}==5) { $annotcolor .= sprintf("%.3F %.3F %.3F", ord($col{1})/255,ord($col{2})/255,ord($col{3})/255); }
7711 else if ($col{0}==1) { $annotcolor .= sprintf("%.3F", ord($col{1})/255); }
7712 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); }
7713 else { $annotcolor .= '1 1 0'; }
7714 }
7715 else { $annotcolor .= '1 1 0'; }
7716 $annotcolor .= ']';
7717 $annot .= $annotcolor;
7718 // Usually Author
7719 // Use as Title for fileattachment
7720 if (isset($pl['opt']['t']) AND is_string($pl['opt']['t'])) {
7721 $annot .= ' /T '.$this->_UTF16BEtextstring($pl['opt']['t']);
7722 }
7723 if ($FileAttachment) {
7724 $iconsapp = array('Paperclip', 'Graph', 'PushPin', 'Tag');
7725 }
7726 else { $iconsapp = array('Comment', 'Help', 'Insert', 'Key', 'NewParagraph', 'Note', 'Paragraph'); }
7727 if (isset($pl['opt']['icon']) AND in_array($pl['opt']['icon'], $iconsapp)) {
7728 $annot .= ' /Name /'.$pl['opt']['icon'];
7729 }
7730 else if ($FileAttachment) { $annot .= ' /Name /PushPin'; }
7731 else { $annot .= ' /Name /Note'; }
7732 if (!$FileAttachment) {
7733 // /Subj is PDF 1.5 spec.
7734 if (isset($pl['opt']['subj']) && !$this->PDFA && !$this->PDFX) {
7735 $annot .= ' /Subj '.$this->_UTF16BEtextstring($pl['opt']['subj']);
7736 }
7737 if (!empty($pl['opt']['popup'])) {
7738 $annot .= ' /Open true';
7739 $annot .= ' /Popup '.($this->n+1).' 0 R';
7740 }
7741 else { $annot .= ' /Open false'; }
7742 }
7743 $annot .= ' /P '.$pl['pageobj'].' 0 R';
7744 $annot .= '>>';
7745 $this->_out($annot);
7746 $this->_out('endobj');
7747
7748 if ($FileAttachment) {
7749 $file = @file_get_contents($pl['opt']['file']) or die('mPDF Error: Cannot access file attachment - '.$pl['opt']['file']);
7750 $filestream = gzcompress($file);
7751 $this->_newobj();
7752 $this->_out('<</Type /EmbeddedFile');
7753 $this->_out('/Length '.strlen($filestream));
7754 $this->_out('/Filter /FlateDecode');
7755 $this->_out('>>');
7756 $this->_putstream($filestream);
7757 $this->_out('endobj');
7758 }
7759 else if (!empty($pl['opt']['popup'])) {
7760 $this->_newobj();
7761 $annot='';
7762 if (is_array($pl['opt']['popup']) && isset($pl['opt']['popup'][0])) { $x = $pl['opt']['popup'][0] * _MPDFK; }
7763 else { $x = $pl['x'] * _MPDFK; }
7764 if (is_array($pl['opt']['popup']) && isset($pl['opt']['popup'][1])) { $y = $hPt - ($pl['opt']['popup'][1] * _MPDFK); }
7765 else { $y = $hPt - ($pl['y'] * _MPDFK); }
7766 if (is_array($pl['opt']['popup']) && isset($pl['opt']['popup'][2])) { $w = $pl['opt']['popup'][2] * _MPDFK; }
7767 else { $w = 180; }
7768 if (is_array($pl['opt']['popup']) && isset($pl['opt']['popup'][3])) { $h = $pl['opt']['popup'][3] * _MPDFK; }
7769 else { $h = 120; }
7770 $rect = sprintf('%.3F %.3F %.3F %.3F', $x, $y-$h, $x+$w, $y);
7771 $annot .= '<</Type /Annot /Subtype /Popup /Rect ['.$rect.']';
7772 $annot .= ' /M '.$this->_textstring('D:'.date('YmdHis'));
7773 if ($this->PDFA || $this->PDFX) { $annot .= ' /F 28'; }
7774 $annot .= ' /Parent '.($this->n-1).' 0 R';
7775 $annot .= '>>';
7776 $this->_out($annot);
7777 $this->_out('endobj');
7778 }
7779 }
7780 }
7781 /*-- END ANNOTATIONS --*/
7782
7783 /*-- FORMS --*/
7784 // Active Forms
7785 if ( count($this->form->forms) > 0 ) {
7786 $this->form->_putFormItems($n, $hPt);
7787 }
7788 /*-- END FORMS --*/
7789 }
7790 }
7791 /*-- FORMS --*/
7792 // Active Forms - Radio Button Group entries
7793 // Output Radio Button Group form entries (radio_on_obj_id already determined)
7794 if (count($this->form->form_radio_groups)) {
7795 $this->form->_putRadioItems($n);
7796 }
7797 /*-- END FORMS --*/
7798 }
7799
7800
7801 /*-- ANNOTATIONS --*/
7802 function Annotation($text, $x=0, $y=0, $icon='Note', $author='', $subject='', $opacity=0, $colarray=false, $popup='', $file='') {
7803 // mPDF 5.3.94
7804 if (is_array($colarray) && count($colarray)==3) { $colarray = $this->ConvertColor('rgb('.$colarray[0].','.$colarray[1].','.$colarray[2].')'); }
7805 if ($colarray === false) { $colarray = $this->ConvertColor('yellow'); }
7806 if ($x==0) { $x = $this->x; }
7807 if ($y==0) { $y = $this->y; }
7808 $page = $this->page;
7809 if ($page < 1) { // Document has not been started - assume it's for first page
7810 $page = 1;
7811 if ($x==0) { $x = $this->lMargin; }
7812 if ($y==0) { $y = $this->tMargin; }
7813 }
7814
7815 if ($this->PDFA || $this->PDFX) {
7816 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)"; }
7817 $x = ($this->w) - $this->rMargin*0.66;
7818 }
7819 if (!$this->annotMargin) { $y -= $this->FontSize / 2; }
7820
7821 if (!$opacity && $this->annotMargin) { $opacity = 1; }
7822 else if (!$opacity) { $opacity = $this->annotOpacity; }
7823
7824 $an = array('txt' => $text, 'x' => $x, 'y' => $y, 'opt' => array('Icon'=>$icon, 'T'=>$author, 'Subj'=>$subject, 'C'=>$colarray, 'CA'=>$opacity, 'popup'=>$popup, 'file'=>$file));
7825
7826 if ($this->keep_block_together) { // Save to array - don't write yet
7827 $this->ktAnnots[$this->page][]= $an;
7828 return;
7829 }
7830 else if ($this->table_rotate) {
7831 $this->tbrot_Annots[$this->page][]= $an;
7832 return;
7833 }
7834 else if ($this->kwt) {
7835 $this->kwt_Annots[$this->page][]= $an;
7836 return;
7837 }
7838 // mPDF 5.0
7839 if ($this->writingHTMLheader || $this->writingHTMLfooter) {
7840 $this->HTMLheaderPageAnnots[]= $an;
7841 return;
7842 }
7843 //Put an Annotation on the page
7844 $this->PageAnnots[$page][] = $an;
7845 /*-- COLUMNS --*/
7846 // Save cross-reference to Column buffer
7847 $ref = count($this->PageAnnots[$this->page])-1;
7848 $this->columnAnnots[$this->CurrCol][INTVAL($this->x)][INTVAL($this->y)] = $ref;
7849 /*-- END COLUMNS --*/
7850 }
7851 /*-- END ANNOTATIONS --*/
7852
7853
7854 function _putfonts() {
7855 $nf=$this->n;
7856 $mqr=$this->_getMQR();
7857 if ($mqr) { set_magic_quotes_runtime(0); }
7858 foreach($this->FontFiles as $fontkey=>$info) {
7859 // TrueType embedded
7860 if (isset($info['type']) && $info['type']=='TTF' && !$info['sip'] && !$info['smp']) {
7861 $used = true;
7862 $asSubset = false;
7863 foreach($this->fonts AS $k=>$f) {
7864 if ($f['fontkey'] == $fontkey && $f['type']=='TTF') {
7865 $used = $f['used'];
7866 if ($used) {
7867 $nChars = (ord($f['cw'][0]) << 8) + ord($f['cw'][1]);
7868 $usage = intval(count($f['subset'])*100 / $nChars);
7869 $fsize = $info['length1'];
7870 // Always subset the very large TTF files
7871 if ($fsize > ($this->maxTTFFilesize *1024)) { $asSubset = true; }
7872 else if ($usage < $this->percentSubset) { $asSubset = true; }
7873 }
7874 if ($this->PDFA || $this->PDFX) $asSubset = false; // mPDF 5.3.45
7875 $this->fonts[$k]['asSubset'] = $asSubset;
7876 break;
7877 }
7878 }
7879 if ($used && !$asSubset) {
7880 //Font file embedding
7881 $this->_newobj();
7882 $this->FontFiles[$fontkey]['n']=$this->n;
7883 $font='';
7884 $originalsize = $info['length1'];
7885 if ($this->repackageTTF || $this->fonts[$fontkey]['TTCfontID']>0) {
7886 // First see if there is a cached compressed file
7887 if (file_exists(_MPDF_TTFONTDATAPATH.$fontkey.'.ps.z')) {
7888 $f=fopen(_MPDF_TTFONTDATAPATH.$fontkey.'.ps.z','rb');
7889 if(!$f) { $this->Error('Font file .ps.z not found'); }
7890 while(!feof($f)) { $font .= fread($f, 2048); }
7891 fclose($f);
7892 include(_MPDF_TTFONTDATAPATH.$fontkey.'.ps.php'); // sets $originalsize (of repackaged font)
7893 }
7894 else {
7895 if (!class_exists('TTFontFile', false)) { include(_MPDF_PATH .'classes/ttfontsuni.php'); }
7896 $ttf = new TTFontFile();
7897 $font = $ttf->repackageTTF($this->FontFiles[$fontkey]['ttffile'], $this->fonts[$fontkey]['TTCfontID'], $this->debugfonts);
7898
7899 $originalsize = strlen($font);
7900 $font = gzcompress($font);
7901 unset($ttf);
7902 if (is_writable(dirname(_MPDF_TTFONTDATAPATH.'x'))) {
7903 $fh = fopen(_MPDF_TTFONTDATAPATH.$fontkey.'.ps.z',"wb");
7904 fwrite($fh,$font,strlen($font));
7905 fclose($fh);
7906 $fh = fopen(_MPDF_TTFONTDATAPATH.$fontkey.'.ps.php',"wb");
7907 $len = "<?php \n";
7908 $len.='$originalsize='.$originalsize.";\n";
7909 $len.="?>";
7910 fwrite($fh,$len,strlen($len));
7911 fclose($fh);
7912 }
7913 }
7914 }
7915 else {
7916 // First see if there is a cached compressed file
7917 if (file_exists(_MPDF_TTFONTDATAPATH.$fontkey.'.z')) {
7918 $f=fopen(_MPDF_TTFONTDATAPATH.$fontkey.'.z','rb');
7919 if(!$f) { $this->Error('Font file not found'); }
7920 while(!feof($f)) { $font .= fread($f, 2048); }
7921 fclose($f);
7922 }
7923 else {
7924 $f=fopen($this->FontFiles[$fontkey]['ttffile'],'rb');
7925 if(!$f) { $this->Error('Font file not found'); }
7926 while(!feof($f)) { $font .= fread($f, 2048); }
7927 fclose($f);
7928 $font = gzcompress($font);
7929 if (is_writable(dirname(_MPDF_TTFONTDATAPATH.'x'))) {
7930 $fh = fopen(_MPDF_TTFONTDATAPATH.$fontkey.'.z',"wb");
7931 fwrite($fh,$font,strlen($font));
7932 fclose($fh);
7933 }
7934 }
7935 }
7936
7937 $this->_out('<</Length '.strlen($font));
7938 $this->_out('/Filter /FlateDecode');
7939 $this->_out('/Length1 '.$originalsize);
7940 $this->_out('>>');
7941 $this->_putstream($font);
7942 $this->_out('endobj');
7943 }
7944 }
7945 }
7946
7947 $nfonts = count($this->fonts);
7948 $fctr = 1;
7949 foreach($this->fonts as $k=>$font) {
7950 //Font objects
7951 $type=$font['type'];
7952 $name=$font['name'];
7953 if ((!isset($font['used']) || !$font['used']) && $type=='TTF') { continue; }
7954 if ($this->progressBar) { $this->UpdateProgressBar(2,intval($fctr*100/$nfonts),'Writing Fonts'); $fctr++; } // *PROGRESS-BAR*
7955 if (isset($font['asSubset'])) { $asSubset = $font['asSubset']; }
7956 else { $asSubset = ''; }
7957 /*-- CJK-FONTS --*/
7958 if($type=='Type0') { // = Adobe CJK Fonts
7959 $this->fonts[$k]['n']=$this->n+1;
7960 $this->_newobj();
7961 $this->_out('<</Type /Font');
7962 $this->_putType0($font);
7963 }
7964 else
7965 /*-- END CJK-FONTS --*/
7966 if($type=='core') {
7967 //Standard font
7968 $this->fonts[$k]['n']=$this->n+1;
7969 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.)'); }
7970 $this->_newobj();
7971 $this->_out('<</Type /Font');
7972 $this->_out('/BaseFont /'.$name);
7973 $this->_out('/Subtype /Type1');
7974 if($name!='Symbol' && $name!='ZapfDingbats') {
7975 $this->_out('/Encoding /WinAnsiEncoding');
7976 }
7977 $this->_out('>>');
7978 $this->_out('endobj');
7979 }
7980 // TrueType embedded SUBSETS for SIP (CJK extB containing Supplementary Ideographic Plane 2)
7981 // Or Unicode Plane 1 - Supplementary Multilingual Plane
7982 else if ($type=='TTF' && ($font['sip'] || $font['smp'])) {
7983 if (!$font['used']) { continue; }
7984 $ssfaid="AA";
7985 if (!class_exists('TTFontFile', false)) { include(_MPDF_PATH .'classes/ttfontsuni.php'); }
7986 $ttf = new TTFontFile();
7987 for($sfid=0;$sfid<count($font['subsetfontids']);$sfid++) {
7988 $this->fonts[$k]['n'][$sfid]=$this->n+1; // NB an array for subset
7989 $subsetname = 'MPDF'.$ssfaid.'+'.$font['name'];
7990 $ssfaid++;
7991 $subset = $font['subsets'][$sfid];
7992 unset($subset[0]);
7993 $ttfontstream = $ttf->makeSubsetSIP($font['ttffile'], $subset, $font['TTCfontID'], $this->debugfonts);
7994 $ttfontsize = strlen($ttfontstream);
7995 $fontstream = gzcompress($ttfontstream);
7996 $widthstring = '';
7997 $toUnistring = '';
7998 foreach($font['subsets'][$sfid] AS $cp=>$u) {
7999 $w = $this->_getCharWidth($font['cw'], $u);
8000 if ($w !== false) {
8001 $widthstring .= $w.' ';
8002 }
8003 else {
8004 $widthstring .= round($ttf->defaultWidth).' ';
8005 }
8006 if ($u > 65535) {
8007 $utf8 = chr(($u>>18)+240).chr((($u>>12)&63)+128).chr((($u>>6)&63)+128) .chr(($u&63)+128);
8008 $utf16 = mb_convert_encoding($utf8, 'UTF-16BE', 'UTF-8');
8009 $l1 = ord($utf16[0]);
8010 $h1 = ord($utf16[1]);
8011 $l2 = ord($utf16[2]);
8012 $h2 = ord($utf16[3]);
8013 $toUnistring .= sprintf("<%02s> <%02s%02s%02s%02s>\n", strtoupper(dechex($cp)), strtoupper(dechex($l1)), strtoupper(dechex($h1)), strtoupper(dechex($l2)), strtoupper(dechex($h2)));
8014 }
8015 else {
8016 $toUnistring .= sprintf("<%02s> <%04s>\n", strtoupper(dechex($cp)), strtoupper(dechex($u)));
8017 }
8018 }
8019
8020 //Additional Type1 or TrueType font
8021 $this->_newobj();
8022 $this->_out('<</Type /Font');
8023 $this->_out('/BaseFont /'.$subsetname);
8024 $this->_out('/Subtype /TrueType');
8025 $this->_out('/FirstChar 0 /LastChar '.(count($font['subsets'][$sfid])-1));
8026 $this->_out('/Widths '.($this->n+1).' 0 R');
8027 $this->_out('/FontDescriptor '.($this->n+2).' 0 R');
8028 $this->_out('/ToUnicode '.($this->n + 3).' 0 R');
8029 $this->_out('>>');
8030 $this->_out('endobj');
8031
8032 //Widths
8033 $this->_newobj();
8034 $this->_out('['.$widthstring.']');
8035 $this->_out('endobj');
8036
8037 //Descriptor
8038 $this->_newobj();
8039 $s='<</Type /FontDescriptor /FontName /'.$subsetname."\n";
8040 foreach($font['desc'] as $kd=>$v) {
8041 if ($kd == 'Flags') { $v = $v | 4; $v = $v & ~32; } // SYMBOLIC font flag
8042 $s.=' /'.$kd.' '.$v."\n";
8043 }
8044 $s.='/FontFile2 '.($this->n + 2).' 0 R';
8045 $this->_out($s.'>>');
8046 $this->_out('endobj');
8047
8048 // ToUnicode
8049 // mPDF 5.3.35
8050 $this->_newobj();
8051 $toUni = "/CIDInit /ProcSet findresource begin\n";
8052 $toUni .= "12 dict begin\n";
8053 $toUni .= "begincmap\n";
8054 $toUni .= "/CIDSystemInfo\n";
8055 $toUni .= "<</Registry (Adobe)\n";
8056 $toUni .= "/Ordering (UCS)\n";
8057 $toUni .= "/Supplement 0\n";
8058 $toUni .= ">> def\n";
8059 $toUni .= "/CMapName /Adobe-Identity-UCS def\n";
8060 $toUni .= "/CMapType 2 def\n";
8061 $toUni .= "1 begincodespacerange\n";
8062 $toUni .= "<00> <FF>\n";
8063 $toUni .= "endcodespacerange\n";
8064 $toUni .= count($font['subsets'][$sfid])." beginbfchar\n";
8065 $toUni .= $toUnistring;
8066 $toUni .= "endbfchar\n";
8067 $toUni .= "endcmap\n";
8068 $toUni .= "CMapName currentdict /CMap defineresource pop\n";
8069 $toUni .= "end\n";
8070 $toUni .= "end\n";
8071
8072 $this->_out('<</Length '.(strlen($toUni)).'>>');
8073 $this->_putstream($toUni);
8074 $this->_out('endobj');
8075
8076 //Font file
8077 $this->_newobj();
8078 $this->_out('<</Length '.strlen($fontstream));
8079 $this->_out('/Filter /FlateDecode');
8080 $this->_out('/Length1 '.$ttfontsize);
8081 $this->_out('>>');
8082 $this->_putstream($fontstream);
8083 $this->_out('endobj');
8084 } // foreach subset
8085 unset($ttf);
8086 }
8087 // TrueType embedded SUBSETS or FULL
8088 else if ($type=='TTF') {
8089 $this->fonts[$k]['n']=$this->n+1;
8090 if ($asSubset ) {
8091 $ssfaid="A";
8092 if (!class_exists('TTFontFile', false)) { include(_MPDF_PATH .'classes/ttfontsuni.php'); }
8093 $ttf = new TTFontFile();
8094 $fontname = 'MPDFA'.$ssfaid.'+'.$font['name'];
8095 $subset = $font['subset'];
8096 unset($subset[0]);
8097 $ttfontstream = $ttf->makeSubset($font['ttffile'], $subset, $font['TTCfontID'], $this->debugfonts);
8098 $ttfontsize = strlen($ttfontstream);
8099 $fontstream = gzcompress($ttfontstream);
8100 $codeToGlyph = $ttf->codeToGlyph;
8101 unset($codeToGlyph[0]);
8102 }
8103 else { $fontname = $font['name']; }
8104 // Type0 Font
8105 // A composite font - a font composed of other fonts, organized hierarchically
8106 $this->_newobj();
8107 $this->_out('<</Type /Font');
8108 $this->_out('/Subtype /Type0');
8109 $this->_out('/BaseFont /'.$fontname.'');
8110 $this->_out('/Encoding /Identity-H');
8111 $this->_out('/DescendantFonts ['.($this->n + 1).' 0 R]');
8112 $this->_out('/ToUnicode '.($this->n + 2).' 0 R');
8113 $this->_out('>>');
8114 $this->_out('endobj');
8115
8116 // CIDFontType2
8117 // A CIDFont whose glyph descriptions are based on TrueType font technology
8118 $this->_newobj();
8119 $this->_out('<</Type /Font');
8120 $this->_out('/Subtype /CIDFontType2');
8121 $this->_out('/BaseFont /'.$fontname.'');
8122 $this->_out('/CIDSystemInfo '.($this->n + 2).' 0 R');
8123 $this->_out('/FontDescriptor '.($this->n + 3).' 0 R');
8124 if (isset($font['desc']['MissingWidth'])){
8125 $this->_out('/DW '.$font['desc']['MissingWidth'].'');
8126 }
8127
8128 if (!$asSubset && file_exists(_MPDF_TTFONTDATAPATH.$font['fontkey'].'.cw')) {
8129 $w = '';
8130 $w=file_get_contents(_MPDF_TTFONTDATAPATH.$font['fontkey'].'.cw');
8131 $this->_out($w);
8132 }
8133 else {
8134 $this->_putTTfontwidths($font, $asSubset, $ttf->maxUni);
8135 }
8136
8137 $this->_out('/CIDToGIDMap '.($this->n + 4).' 0 R');
8138 $this->_out('>>');
8139 $this->_out('endobj');
8140
8141 // ToUnicode
8142 // mPDF 5.3.35
8143 $this->_newobj();
8144 $toUni = "/CIDInit /ProcSet findresource begin\n";
8145 $toUni .= "12 dict begin\n";
8146 $toUni .= "begincmap\n";
8147 $toUni .= "/CIDSystemInfo\n";
8148 $toUni .= "<</Registry (Adobe)\n";
8149 $toUni .= "/Ordering (UCS)\n";
8150 $toUni .= "/Supplement 0\n";
8151 $toUni .= ">> def\n";
8152 $toUni .= "/CMapName /Adobe-Identity-UCS def\n";
8153 $toUni .= "/CMapType 2 def\n";
8154 $toUni .= "1 begincodespacerange\n";
8155 $toUni .= "<0000> <FFFF>\n";
8156 $toUni .= "endcodespacerange\n";
8157 $toUni .= "1 beginbfrange\n";
8158 $toUni .= "<0000> <FFFF> <0000>\n";
8159 $toUni .= "endbfrange\n";
8160 $toUni .= "endcmap\n";
8161 $toUni .= "CMapName currentdict /CMap defineresource pop\n";
8162 $toUni .= "end\n";
8163 $toUni .= "end\n";
8164 $this->_out('<</Length '.(strlen($toUni)).'>>');
8165 $this->_putstream($toUni);
8166 $this->_out('endobj');
8167
8168
8169 // CIDSystemInfo dictionary
8170 $this->_newobj();
8171 $this->_out('<</Registry (Adobe)');
8172 $this->_out('/Ordering (UCS)');
8173 $this->_out('/Supplement 0');
8174 $this->_out('>>');
8175 $this->_out('endobj');
8176
8177 // Font descriptor
8178 $this->_newobj();
8179 $this->_out('<</Type /FontDescriptor');
8180 $this->_out('/FontName /'.$fontname);
8181 foreach($font['desc'] as $kd=>$v) {
8182 if ($asSubset && $kd == 'Flags') { $v = $v | 4; $v = $v & ~32; } // SYMBOLIC font flag
8183 $this->_out(' /'.$kd.' '.$v);
8184 }
8185 if ($font['panose']) {
8186 $this->_out(' /Style << /Panose <'.$font['panose'].'> >>');
8187 }
8188 if ($asSubset ) {
8189 $this->_out('/FontFile2 '.($this->n + 2).' 0 R');
8190 }
8191 else if ($font['fontkey']) {
8192 // obj ID of a stream containing a TrueType font program
8193 $this->_out('/FontFile2 '.$this->FontFiles[$font['fontkey']]['n'].' 0 R');
8194 }
8195 $this->_out('>>');
8196 $this->_out('endobj');
8197
8198 // Embed CIDToGIDMap
8199 // A specification of the mapping from CIDs to glyph indices
8200 if ($asSubset ) {
8201 $cidtogidmap = '';
8202 $cidtogidmap = str_pad('', 256*256*2, "\x00");
8203 foreach($codeToGlyph as $cc=>$glyph) {
8204 $cidtogidmap[$cc*2] = chr($glyph >> 8);
8205 $cidtogidmap[$cc*2 + 1] = chr($glyph & 0xFF);
8206 }
8207 $cidtogidmap = gzcompress($cidtogidmap);
8208 }
8209 else {
8210 // First see if there is a cached CIDToGIDMapfile
8211 $cidtogidmap = '';
8212 if (file_exists(_MPDF_TTFONTDATAPATH.$font['fontkey'].'.cgm')) {
8213 $f=fopen(_MPDF_TTFONTDATAPATH.$font['fontkey'].'.cgm','rb');
8214 while(!feof($f)) { $cidtogidmap .= fread($f, 2048); }
8215 fclose($f);
8216 }
8217 else {
8218 if (!class_exists('TTFontFile', false)) { include(_MPDF_PATH .'classes/ttfontsuni.php'); }
8219 $ttf = new TTFontFile();
8220 $charToGlyph = $ttf->getCTG($font['ttffile'], $font['TTCfontID'], $this->debugfonts);
8221 $cidtogidmap = str_pad('', 256*256*2, "\x00");
8222 foreach($charToGlyph as $cc=>$glyph) {
8223 $cidtogidmap[$cc*2] = chr($glyph >> 8);
8224 $cidtogidmap[$cc*2 + 1] = chr($glyph & 0xFF);
8225 }
8226 unset($ttf);
8227 $cidtogidmap = gzcompress($cidtogidmap);
8228 if (is_writable(dirname(_MPDF_TTFONTDATAPATH.'x'))) {
8229 $fh = fopen(_MPDF_TTFONTDATAPATH.$font['fontkey'].'.cgm',"wb");
8230 fwrite($fh,$cidtogidmap,strlen($cidtogidmap));
8231 fclose($fh);
8232 }
8233 }
8234 }
8235 $this->_newobj();
8236 $this->_out('<</Length '.strlen($cidtogidmap).'');
8237 $this->_out('/Filter /FlateDecode');
8238 $this->_out('>>');
8239 $this->_putstream($cidtogidmap);
8240 $this->_out('endobj');
8241
8242 //Font file
8243 if ($asSubset ) {
8244 $this->_newobj();
8245 $this->_out('<</Length '.strlen($fontstream));
8246 $this->_out('/Filter /FlateDecode');
8247 $this->_out('/Length1 '.$ttfontsize);
8248 $this->_out('>>');
8249 $this->_putstream($fontstream);
8250 $this->_out('endobj');
8251 unset($ttf);
8252 }
8253 }
8254 else { $this->Error('Unsupported font type: '.$type.' ('.$name.')'); }
8255 }
8256 if ($mqr) { set_magic_quotes_runtime($mqr); }
8257 }
8258
8259
8260
8261 function _putTTfontwidths(&$font, $asSubset, $maxUni) {
8262 if ($asSubset && file_exists(_MPDF_TTFONTDATAPATH.$font['fontkey'].'.cw127.php')) {
8263 include(_MPDF_TTFONTDATAPATH.$font['fontkey'].'.cw127.php') ;
8264 $startcid = 128;
8265 }
8266 else {
8267 $rangeid = 0;
8268 $range = array();
8269 $prevcid = -2;
8270 $prevwidth = -1;
8271 $interval = false;
8272 $startcid = 1;
8273 }
8274 if ($asSubset) { $cwlen = $maxUni + 1; }
8275 else { $cwlen = (strlen($font['cw'])/2); }
8276
8277 // for each character
8278 for ($cid=$startcid; $cid<$cwlen; $cid++) {
8279 if ($cid==128 && $asSubset && (!file_exists(_MPDF_TTFONTDATAPATH.$font['fontkey'].'.cw127.php'))) {
8280 if (is_writable(dirname(_MPDF_TTFONTDATAPATH.'x'))) {
8281 $fh = fopen(_MPDF_TTFONTDATAPATH.$font['fontkey'].'.cw127.php',"wb");
8282 $cw127='<?php'."\n";
8283 $cw127.='$rangeid='.$rangeid.";\n";
8284 $cw127.='$prevcid='.$prevcid.";\n";
8285 $cw127.='$prevwidth='.$prevwidth.";\n";
8286 if ($interval) { $cw127.='$interval=true'.";\n"; }
8287 else { $cw127.='$interval=false'.";\n"; }
8288 $cw127.='$range='.var_export($range,true).";\n";
8289 $cw127.="?>";
8290 fwrite($fh,$cw127,strlen($cw127));
8291 fclose($fh);
8292 }
8293 }
8294 if ($font['cw'][$cid*2] == "\00" && $font['cw'][$cid*2+1] == "\00") { continue; }
8295 $width = (ord($font['cw'][$cid*2]) << 8) + ord($font['cw'][$cid*2+1]);
8296 if ($width == 65535) { $width = 0; }
8297 if ($asSubset && $cid > 255 && (!isset($font['subset'][$cid]) || !$font['subset'][$cid])) {
8298 continue;
8299 }
8300 if (!isset($font['dw']) || (isset($font['dw']) && $width != $font['dw'])) {
8301 if ($cid == ($prevcid + 1)) {
8302 // consecutive CID
8303 if ($width == $prevwidth) {
8304 if ($width == $range[$rangeid][0]) {
8305 $range[$rangeid][] = $width;
8306 } else {
8307 array_pop($range[$rangeid]);
8308 // new range
8309 $rangeid = $prevcid;
8310 $range[$rangeid] = array();
8311 $range[$rangeid][] = $prevwidth;
8312 $range[$rangeid][] = $width;
8313 }
8314 $interval = true;
8315 $range[$rangeid]['interval'] = true;
8316 } else {
8317 if ($interval) {
8318 // new range
8319 $rangeid = $cid;
8320 $range[$rangeid] = array();
8321 $range[$rangeid][] = $width;
8322 } else {
8323 $range[$rangeid][] = $width;
8324 }
8325 $interval = false;
8326 }
8327 } else {
8328 // new range
8329 $rangeid = $cid;
8330 $range[$rangeid] = array();
8331 $range[$rangeid][] = $width;
8332 $interval = false;
8333 }
8334 $prevcid = $cid;
8335 $prevwidth = $width;
8336 }
8337 }
8338 $w = $this->_putfontranges($range);
8339 $this->_out($w);
8340 if (!$asSubset) {
8341 if (is_writable(dirname(_MPDF_TTFONTDATAPATH.'x'))) {
8342 $fh = fopen(_MPDF_TTFONTDATAPATH.$font['fontkey'].'.cw',"wb");
8343 fwrite($fh,$w,strlen($w));
8344 fclose($fh);
8345 }
8346 }
8347 }
8348
8349 function _putfontranges(&$range) {
8350 // optimize ranges
8351 $prevk = -1;
8352 $nextk = -1;
8353 $prevint = false;
8354 foreach ($range as $k => $ws) {
8355 $cws = count($ws);
8356 if (($k == $nextk) AND (!$prevint) AND ((!isset($ws['interval'])) OR ($cws < 4))) {
8357 if (isset($range[$k]['interval'])) {
8358 unset($range[$k]['interval']);
8359 }
8360 $range[$prevk] = array_merge($range[$prevk], $range[$k]);
8361 unset($range[$k]);
8362 } else {
8363 $prevk = $k;
8364 }
8365 $nextk = $k + $cws;
8366 if (isset($ws['interval'])) {
8367 if ($cws > 3) {
8368 $prevint = true;
8369 } else {
8370 $prevint = false;
8371 }
8372 unset($range[$k]['interval']);
8373 --$nextk;
8374 } else {
8375 $prevint = false;
8376 }
8377 }
8378 // output data
8379 $w = '';
8380 foreach ($range as $k => $ws) {
8381 if (count(array_count_values($ws)) == 1) {
8382 // interval mode is more compact
8383 $w .= ' '.$k.' '.($k + count($ws) - 1).' '.$ws[0];
8384 } else {
8385 // range mode
8386 $w .= ' '.$k.' [ '.implode(' ', $ws).' ]' . "\n";
8387 }
8388 }
8389 return '/W ['.$w.' ]';
8390 }
8391
8392
8393 function _putfontwidths(&$font, $cidoffset=0) {
8394 ksort($font['cw']);
8395 unset($font['cw'][65535]);
8396 $rangeid = 0;
8397 $range = array();
8398 $prevcid = -2;
8399 $prevwidth = -1;
8400 $interval = false;
8401 // for each character
8402 foreach ($font['cw'] as $cid => $width) {
8403 $cid -= $cidoffset;
8404 if (!isset($font['dw']) || (isset($font['dw']) && $width != $font['dw'])) {
8405 if ($cid == ($prevcid + 1)) {
8406 // consecutive CID
8407 if ($width == $prevwidth) {
8408 if ($width == $range[$rangeid][0]) {
8409 $range[$rangeid][] = $width;
8410 } else {
8411 array_pop($range[$rangeid]);
8412 // new range
8413 $rangeid = $prevcid;
8414 $range[$rangeid] = array();
8415 $range[$rangeid][] = $prevwidth;
8416 $range[$rangeid][] = $width;
8417 }
8418 $interval = true;
8419 $range[$rangeid]['interval'] = true;
8420 } else {
8421 if ($interval) {
8422 // new range
8423 $rangeid = $cid;
8424 $range[$rangeid] = array();
8425 $range[$rangeid][] = $width;
8426 } else {
8427 $range[$rangeid][] = $width;
8428 }
8429 $interval = false;
8430 }
8431 } else {
8432 // new range
8433 $rangeid = $cid;
8434 $range[$rangeid] = array();
8435 $range[$rangeid][] = $width;
8436 $interval = false;
8437 }
8438 $prevcid = $cid;
8439 $prevwidth = $width;
8440 }
8441 }
8442 $this->_out($this->_putfontranges($range));
8443 }
8444
8445
8446 /*-- CJK-FONTS --*/
8447
8448 // from class PDF_Chinese CJK EXTENSIONS
8449 function _putType0(&$font)
8450 {
8451 //Type0
8452 $this->_out('/Subtype /Type0');
8453 $this->_out('/BaseFont /'.$font['name'].'-'.$font['CMap']);
8454 $this->_out('/Encoding /'.$font['CMap']);
8455 $this->_out('/DescendantFonts ['.($this->n+1).' 0 R]');
8456 $this->_out('>>');
8457 $this->_out('endobj');
8458 //CIDFont
8459 $this->_newobj();
8460 $this->_out('<</Type /Font');
8461 $this->_out('/Subtype /CIDFontType0');
8462 $this->_out('/BaseFont /'.$font['name']);
8463
8464 $cidinfo = '/Registry '.$this->_textstring('Adobe');
8465 $cidinfo .= ' /Ordering '.$this->_textstring($font['registry']['ordering']);
8466 $cidinfo .= ' /Supplement '.$font['registry']['supplement'];
8467 $this->_out('/CIDSystemInfo <<'.$cidinfo.'>>');
8468
8469 $this->_out('/FontDescriptor '.($this->n+1).' 0 R');
8470 if (isset($font['MissingWidth'])){
8471 $this->_out('/DW '.$font['MissingWidth'].'');
8472 }
8473 $this->_putfontwidths($font, 31);
8474 $this->_out('>>');
8475 $this->_out('endobj');
8476
8477 //Font descriptor
8478 $this->_newobj();
8479 $s = '<</Type /FontDescriptor /FontName /'.$font['name'];
8480 foreach ($font['desc'] as $k => $v) {
8481 if ($k != 'Style') {
8482 $s .= ' /'.$k.' '.$v.'';
8483 }
8484 }
8485 $this->_out($s.'>>');
8486 $this->_out('endobj');
8487 }
8488 /*-- END CJK-FONTS --*/
8489
8490
8491
8492 function _putimages()
8493 {
8494 $filter=($this->compress) ? '/Filter /FlateDecode ' : '';
8495 reset($this->images);
8496 while(list($file,$info)=each($this->images)) {
8497 $this->_newobj();
8498 $this->images[$file]['n']=$this->n;
8499 $this->_out('<</Type /XObject');
8500 $this->_out('/Subtype /Image');
8501 $this->_out('/Width '.$info['w']);
8502 $this->_out('/Height '.$info['h']);
8503 if (isset($info['masked'])) {
8504 $this->_out('/SMask '.($this->n - 1).' 0 R');
8505 }
8506 if($info['cs']=='Indexed') {
8507 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.")."); }
8508 $this->_out('/ColorSpace [/Indexed /DeviceRGB '.(strlen($info['pal'])/3-1).' '.($this->n+1).' 0 R]');
8509 }
8510 else {
8511 $this->_out('/ColorSpace /'.$info['cs']);
8512 if($info['cs']=='DeviceCMYK') {
8513 if ($this->PDFA && $this->restrictColorSpace!=3) { $this->Error("PDFA1-b does not permit Images using mixed colour space (".$file.")."); }
8514 if($info['type']=='jpg') { $this->_out('/Decode [1 0 1 0 1 0 1 0]'); }
8515 }
8516 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.")."); }
8517 }
8518 $this->_out('/BitsPerComponent '.$info['bpc']);
8519 if (isset($info['f']) && $info['f']) { $this->_out('/Filter /'.$info['f']); }
8520 if(isset($info['parms'])) { $this->_out($info['parms']); }
8521 if(isset($info['trns']) and is_array($info['trns'])) {
8522 $trns='';
8523 for($i=0;$i<count($info['trns']);$i++)
8524 $trns.=$info['trns'][$i].' '.$info['trns'][$i].' ';
8525 $this->_out('/Mask ['.$trns.']');
8526 }
8527 $this->_out('/Length '.strlen($info['data']).'>>');
8528 $this->_putstream($info['data']);
8529
8530 unset($this->images[$file]['data']);
8531 $this->_out('endobj');
8532 //Palette
8533 if($info['cs']=='Indexed') {
8534 $this->_newobj();
8535 $pal=($this->compress) ? gzcompress($info['pal']) : $info['pal'];
8536 $this->_out('<<'.$filter.'/Length '.strlen($pal).'>>');
8537 $this->_putstream($pal);
8538 $this->_out('endobj');
8539 }
8540 }
8541 }
8542
8543 function _putinfo()
8544 {
8545 $this->_out('/Producer '.$this->_UTF16BEtextstring('mPDF '.mPDF_VERSION));
8546 if(!empty($this->title))
8547 $this->_out('/Title '.$this->_UTF16BEtextstring($this->title));
8548 if(!empty($this->subject))
8549 $this->_out('/Subject '.$this->_UTF16BEtextstring($this->subject));
8550 if(!empty($this->author))
8551 $this->_out('/Author '.$this->_UTF16BEtextstring($this->author));
8552 if(!empty($this->keywords))
8553 $this->_out('/Keywords '.$this->_UTF16BEtextstring($this->keywords));
8554 if(!empty($this->creator))
8555 $this->_out('/Creator '.$this->_UTF16BEtextstring($this->creator));
8556
8557 $z = date('O'); // +0200
8558 $offset = substr($z,0,3)."'".substr($z,3,2)."'";
8559 $this->_out('/CreationDate '.$this->_textstring(date('YmdHis').$offset));
8560 $this->_out('/ModDate '.$this->_textstring(date('YmdHis').$offset));
8561 if ($this->PDFX) {
8562 $this->_out('/Trapped/False');
8563 $this->_out('/GTS_PDFXVersion(PDF/X-1a:2003)');
8564 }
8565 }
8566
8567 function _putmetadata() {
8568 $this->_newobj();
8569 $this->MetadataRoot = $this->n;
8570 $Producer = 'mPDF '.mPDF_VERSION;
8571 $z = date('O'); // +0200
8572 $offset = substr($z,0,3).':'.substr($z,3,2);
8573 $CreationDate = date('Y-m-d\TH:i:s').$offset; // 2006-03-10T10:47:26-05:00 2006-06-19T09:05:17Z
8574 $uuid = sprintf('%04x%04x-%04x-%04x-%04x-%04x%04x%04x', mt_rand(0, 0xffff), mt_rand(0, 0xffff),
8575 mt_rand(0, 0xffff), mt_rand(0, 0x0fff) | 0x4000, mt_rand(0, 0x3fff) | 0x8000,
8576 mt_rand(0, 0xffff), mt_rand(0, 0xffff), mt_rand(0, 0xffff) );
8577
8578
8579 $m = '<?xpacket begin="'.chr(239).chr(187).chr(191).'" id="W5M0MpCehiHzreSzNTczkc9d"?>'."\n"; // begin = FEFF BOM
8580 $m .= ' <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="3.1-701">'."\n";
8581 $m .= ' <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">'."\n";
8582 $m .= ' <rdf:Description rdf:about="uuid:'.$uuid.'" xmlns:pdf="http://ns.adobe.com/pdf/1.3/">'."\n";
8583 $m .= ' <pdf:Producer>'.$Producer.'</pdf:Producer>'."\n";
8584 if(!empty($this->keywords)) { $m .= ' <pdf:Keywords>'.$this->keywords.'</pdf:Keywords>'."\n"; }
8585 $m .= ' </rdf:Description>'."\n";
8586
8587 $m .= ' <rdf:Description rdf:about="uuid:'.$uuid.'" xmlns:xmp="http://ns.adobe.com/xap/1.0/">'."\n";
8588 $m .= ' <xmp:CreateDate>'.$CreationDate.'</xmp:CreateDate>'."\n";
8589 $m .= ' <xmp:ModifyDate>'.$CreationDate.'</xmp:ModifyDate>'."\n";
8590 $m .= ' <xmp:MetadataDate>'.$CreationDate.'</xmp:MetadataDate>'."\n";
8591 if(!empty($this->creator)) { $m .= ' <xmp:CreatorTool>'.$this->creator.'</xmp:CreatorTool>'."\n"; }
8592 $m .= ' </rdf:Description>'."\n";
8593
8594 // DC elements
8595 $m .= ' <rdf:Description rdf:about="uuid:'.$uuid.'" xmlns:dc="http://purl.org/dc/elements/1.1/">'."\n";
8596 $m .= ' <dc:format>application/pdf</dc:format>'."\n";
8597 if(!empty($this->title)) {
8598 $m .= ' <dc:title>
8599 <rdf:Alt>
8600 <rdf:li xml:lang="x-default">'.$this->title.'</rdf:li>
8601 </rdf:Alt>
8602 </dc:title>'."\n";
8603 }
8604 if(!empty($this->keywords)) {
8605 $m .= ' <dc:subject>
8606 <rdf:Bag>
8607 <rdf:li>'.$this->keywords.'</rdf:li>
8608 </rdf:Bag>
8609 </dc:subject>'."\n";
8610 }
8611 if(!empty($this->subject)) {
8612 $m .= ' <dc:description>
8613 <rdf:Alt>
8614 <rdf:li xml:lang="x-default">'.$this->subject.'</rdf:li>
8615 </rdf:Alt>
8616 </dc:description>'."\n";
8617 }
8618 if(!empty($this->author)) {
8619 $m .= ' <dc:creator>
8620 <rdf:Seq>
8621 <rdf:li>'.$this->author.'</rdf:li>
8622 </rdf:Seq>
8623 </dc:creator>'."\n";
8624 }
8625 $m .= ' </rdf:Description>'."\n";
8626
8627
8628 // This bit is specific to PDFX-1a
8629 if ($this->PDFX) {
8630 $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";
8631 }
8632
8633 // This bit is specific to PDFA-1b
8634 else if ($this->PDFA) {
8635 $m .= ' <rdf:Description rdf:about="uuid:'.$uuid.'" xmlns:pdfaid="http://www.aiim.org/pdfa/ns/id/" >'."\n";
8636 $m .= ' <pdfaid:part>1</pdfaid:part>'."\n";
8637 $m .= ' <pdfaid:conformance>B</pdfaid:conformance>'."\n";
8638 $m .= ' <pdfaid:amd>2005</pdfaid:amd>'."\n";
8639 $m .= ' </rdf:Description>'."\n";
8640 }
8641
8642 $m .= ' <rdf:Description rdf:about="uuid:'.$uuid.'" xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/">'."\n";
8643 $m .= ' <xmpMM:DocumentID>uuid:'.$uuid.'</xmpMM:DocumentID>'."\n";
8644 $m .= ' </rdf:Description>'."\n";
8645 $m .= ' </rdf:RDF>'."\n";
8646 $m .= ' </x:xmpmeta>'."\n";
8647 $m .= str_repeat(str_repeat(' ',100)."\n",20); // 2-4kB whitespace padding required
8648 $m .= '<?xpacket end="w"?>'; // "r" read only
8649 $this->_out('<</Type/Metadata/Subtype/XML/Length '.strlen($m).'>>');
8650 $this->_putstream($m);
8651 $this->_out('endobj');
8652 }
8653
8654 function _putoutputintent() {
8655 $this->_newobj();
8656 $this->OutputIntentRoot = $this->n;
8657 $this->_out('<</Type /OutputIntent');
8658
8659 if ($this->PDFA) {
8660 $this->_out('/S /GTS_PDFA1');
8661 if ($this->ICCProfile) {
8662 $this->_out('/Info ('.preg_replace('/_/',' ',$this->ICCProfile).')');
8663 $this->_out('/OutputConditionIdentifier (Custom)');
8664 $this->_out('/OutputCondition ()');
8665 }
8666 else {
8667 $this->_out('/Info (sRGB IEC61966-2.1)');
8668 $this->_out('/OutputConditionIdentifier (sRGB IEC61966-2.1)');
8669 $this->_out('/OutputCondition ()');
8670 }
8671 $this->_out('/DestOutputProfile '.($this->n+1).' 0 R');
8672 }
8673 else if ($this->PDFX) { // always a CMYK profile
8674 $this->_out('/S /GTS_PDFX');
8675 if ($this->ICCProfile) {
8676 $this->_out('/Info ('.preg_replace('/_/',' ',$this->ICCProfile).')');
8677 $this->_out('/OutputConditionIdentifier (Custom)');
8678 $this->_out('/OutputCondition ()');
8679 $this->_out('/DestOutputProfile '.($this->n+1).' 0 R');
8680 }
8681 else {
8682 $this->_out('/Info (CGATS TR 001)');
8683 $this->_out('/OutputConditionIdentifier (CGATS TR 001)');
8684 $this->_out('/OutputCondition (CGATS TR 001 (SWOP))');
8685 $this->_out('/RegistryName (http://www.color.org)');
8686 }
8687 }
8688 $this->_out('>>');
8689 $this->_out('endobj');
8690
8691 if ($this->PDFX && !$this->ICCProfile) { return; } // no ICCProfile embedded
8692
8693 $this->_newobj();
8694 if ($this->ICCProfile)
8695 $s = file_get_contents(_MPDF_PATH.'iccprofiles/'.$this->ICCProfile.'.icc');
8696 else
8697 $s = file_get_contents(_MPDF_PATH.'iccprofiles/sRGB_IEC61966-2-1.icc');
8698 if ($this->compress) { $s = gzcompress($s); }
8699 $this->_out('<<');
8700 if ($this->PDFX || ($this->PDFA && $this->restrictColorSpace == 3)) { $this->_out('/N 4'); }
8701 else { $this->_out('/N 3'); }
8702 if ($this->compress)
8703 $this->_out('/Filter /FlateDecode ');
8704 $this->_out('/Length '.strlen($s).'>>');
8705 $this->_putstream($s);
8706 $this->_out('endobj');
8707 }
8708
8709
8710 function _putcatalog() {
8711 $this->_out('/Type /Catalog');
8712 $this->_out('/Pages 1 0 R');
8713 if($this->ZoomMode=='fullpage') $this->_out('/OpenAction [3 0 R /Fit]');
8714 elseif($this->ZoomMode=='fullwidth') $this->_out('/OpenAction [3 0 R /FitH null]');
8715 elseif($this->ZoomMode=='real') $this->_out('/OpenAction [3 0 R /XYZ null null 1]');
8716 elseif(!is_string($this->ZoomMode)) $this->_out('/OpenAction [3 0 R /XYZ null null '.($this->ZoomMode/100).']');
8717 else $this->_out('/OpenAction [3 0 R /XYZ null null null]');
8718 if($this->LayoutMode=='single') $this->_out('/PageLayout /SinglePage');
8719 elseif($this->LayoutMode=='continuous') $this->_out('/PageLayout /OneColumn');
8720 elseif($this->LayoutMode=='twoleft') $this->_out('/PageLayout /TwoColumnLeft');
8721 elseif($this->LayoutMode=='tworight') $this->_out('/PageLayout /TwoColumnRight');
8722 elseif($this->LayoutMode=='two') {
8723 if ($this->mirrorMargins) { $this->_out('/PageLayout /TwoColumnRight'); }
8724 else { $this->_out('/PageLayout /TwoColumnLeft'); }
8725 }
8726
8727 /*-- BOOKMARKS --*/
8728 if(count($this->BMoutlines)>0) {
8729 $this->_out('/Outlines '.$this->OutlineRoot.' 0 R');
8730 $this->_out('/PageMode /UseOutlines');
8731 }
8732 /*-- END BOOKMARKS --*/
8733 if(is_int(strpos($this->DisplayPreferences,'FullScreen'))) $this->_out('/PageMode /FullScreen');
8734
8735 // Metadata
8736 if ($this->PDFA || $this->PDFX) {
8737 $this->_out('/Metadata '.$this->MetadataRoot.' 0 R');
8738 }
8739 // OutputIntents
8740 if ($this->PDFA || $this->PDFX || $this->ICCProfile) {
8741 $this->_out('/OutputIntents ['.$this->OutputIntentRoot.' 0 R]');
8742 }
8743
8744 /*-- FORMS --*/
8745 if (count($this->form->forms)>0) {
8746 $this->form->_putFormsCatalog();
8747 }
8748 /*-- END FORMS --*/
8749 if ( isset($this->js) ) {
8750 $this->_out('/Names << /JavaScript '.($this->n_js).' 0 R >> ');
8751 }
8752
8753 if($this->DisplayPreferences || $this->directionality == 'rtl' || $this->mirrorMargins) {
8754 $this->_out('/ViewerPreferences<<');
8755 if(is_int(strpos($this->DisplayPreferences,'HideMenubar'))) $this->_out('/HideMenubar true');
8756 if(is_int(strpos($this->DisplayPreferences,'HideToolbar'))) $this->_out('/HideToolbar true');
8757 if(is_int(strpos($this->DisplayPreferences,'HideWindowUI'))) $this->_out('/HideWindowUI true');
8758 if(is_int(strpos($this->DisplayPreferences,'DisplayDocTitle'))) $this->_out('/DisplayDocTitle true');
8759 if(is_int(strpos($this->DisplayPreferences,'CenterWindow'))) $this->_out('/CenterWindow true');
8760 if(is_int(strpos($this->DisplayPreferences,'FitWindow'))) $this->_out('/FitWindow true');
8761 // /PrintScaling is PDF 1.6 spec.
8762 if(is_int(strpos($this->DisplayPreferences,'NoPrintScaling')) && !$this->PDFA && !$this->PDFX)
8763 $this->_out('/PrintScaling /None');
8764 if($this->directionality == 'rtl') $this->_out('/Direction /R2L');
8765 // /Duplex is PDF 1.7 spec.
8766 if($this->mirrorMargins && !$this->PDFA && !$this->PDFX) {
8767 // if ($this->DefOrientation=='P') $this->_out('/Duplex /DuplexFlipShortEdge');
8768 $this->_out('/Duplex /DuplexFlipLongEdge'); // PDF v1.7+
8769 }
8770 $this->_out('>>');
8771 }
8772 if ($this->hasOC) { // mPDF 5.3.45
8773 // mPDF 5.3.41 Visibility
8774 $p=$this->n_ocg_print.' 0 R';
8775 $v=$this->n_ocg_view.' 0 R';
8776 $h=$this->n_ocg_hidden.' 0 R';
8777 $as="<</Event /Print /OCGs [$p $v $h] /Category [/Print]>> <</Event /View /OCGs [$p $v $h] /Category [/View]>>";
8778 $this->_out("/OCProperties <</OCGs [$p $v $h] /D <</ON [$p] /OFF [$v] /OFF [$h] /AS [$as]>>>>");
8779 }
8780 }
8781
8782 // Inactive function left for backwards compatability
8783 function SetUserRights($enable=true, $annots="", $form="", $signature="") {
8784 // Does nothing
8785 }
8786
8787 function _enddoc() {
8788 if ($this->progressBar) { $this->UpdateProgressBar(2,'10','Writing Headers & Footers'); } // *PROGRESS-BAR*
8789 $this->_puthtmlheaders(); // *HTMLHEADERS-FOOTERS*
8790 if ($this->progressBar) { $this->UpdateProgressBar(2,'20','Writing Pages'); } // *PROGRESS-BAR*
8791 // Remove references to unused fonts (usually default font)
8792 foreach($this->fonts as $fk=>$font) {
8793 if (!$font['used'] && ($font['type']=='TTF')) {
8794 if ($font['sip'] || $font['smp']) {
8795 foreach($font['subsetfontids'] AS $k => $fid) {
8796 foreach($this->pages AS $pn=>$page) {
8797 $this->pages[$pn] = preg_replace('/\s\/F'.$fid.' \d[\d.]* Tf\s/is',' ',$this->pages[$pn]);
8798 }
8799 }
8800 }
8801 else {
8802 foreach($this->pages AS $pn=>$page) {
8803 $this->pages[$pn] = preg_replace('/\s\/F'.$font['i'].' \d[\d.]* Tf\s/is',' ',$this->pages[$pn]);
8804 }
8805 }
8806 }
8807 }
8808
8809 $this->_putpages();
8810 if ($this->progressBar) { $this->UpdateProgressBar(2,'30','Writing document resources'); } // *PROGRESS-BAR*
8811
8812 $this->_putresources();
8813 //Info
8814 $this->_newobj();
8815 $this->InfoRoot = $this->n;
8816 $this->_out('<<');
8817 if ($this->progressBar) { $this->UpdateProgressBar(2,'80','Writing document info'); } // *PROGRESS-BAR*
8818 $this->_putinfo();
8819 $this->_out('>>');
8820 $this->_out('endobj');
8821
8822 // METADATA
8823 if ($this->PDFA || $this->PDFX) { $this->_putmetadata(); }
8824 // OUTPUTINTENT
8825 if ($this->PDFA || $this->PDFX || $this->ICCProfile) { $this->_putoutputintent(); }
8826
8827 //Catalog
8828 $this->_newobj();
8829 $this->_out('<<');
8830 if ($this->progressBar) { $this->UpdateProgressBar(2,'90','Writing document catalog'); } // *PROGRESS-BAR*
8831 $this->_putcatalog();
8832 $this->_out('>>');
8833 $this->_out('endobj');
8834 //Cross-ref
8835 $o=strlen($this->buffer);
8836 $this->_out('xref');
8837 $this->_out('0 '.($this->n+1));
8838 $this->_out('0000000000 65535 f ');
8839 for($i=1; $i <= $this->n ; $i++)
8840 $this->_out(sprintf('%010d 00000 n ',$this->offsets[$i]));
8841 //Trailer
8842 $this->_out('trailer');
8843 $this->_out('<<');
8844 $this->_puttrailer();
8845 $this->_out('>>');
8846 $this->_out('startxref');
8847 $this->_out($o);
8848
8849 $this->buffer .= '%%EOF';
8850 $this->state=3;
8851 /*-- IMPORTS --*/
8852
8853 if ($this->enableImports && count($this->parsers) > 0) {
8854 foreach ($this->parsers as $k => $_){
8855 $this->parsers[$k]->closeFile();
8856 $this->parsers[$k] = null;
8857 unset($this->parsers[$k]);
8858 }
8859 }
8860 /*-- END IMPORTS --*/
8861 }
8862
8863 function _beginpage($orientation,$mgl='',$mgr='',$mgt='',$mgb='',$mgh='',$mgf='',$ohname='',$ehname='',$ofname='',$efname='',$ohvalue=0,$ehvalue=0,$ofvalue=0,$efvalue=0,$pagesel='',$newformat='') {
8864 if (!($pagesel && $this->page==1 && (sprintf("%0.4f", $this->y)==sprintf("%0.4f", $this->tMargin)))) {
8865 $this->page++;
8866 $this->pages[$this->page]='';
8867 }
8868 $this->state=2;
8869 $resetHTMLHeadersrequired = false;
8870
8871
8872 if ($newformat) { $this->_setPageSize($newformat, $orientation); }
8873 /*-- CSS-PAGE --*/
8874 // Paged media (page-box)
8875
8876 if ($pagesel || (isset($this->page_box['using']) && $this->page_box['using'])) {
8877 if ($pagesel || $this->page==1) { $first = true; }
8878 else { $first = false; }
8879 if ($this->mirrorMargins && ($this->page % 2==0)) { $oddEven = 'E'; }
8880 else { $oddEven = 'O'; }
8881 if ($pagesel) { $psel = $pagesel; }
8882 else if ($this->page_box['current']) { $psel = $this->page_box['current']; }
8883 else { $psel = ''; }
8884 list($orientation,$mgl,$mgr,$mgt,$mgb,$mgh,$mgf,$hname,$fname,$bg,$resetpagenum,$pagenumstyle,$suppress,$marks,$newformat) = $this->SetPagedMediaCSS($psel, $first, $oddEven);
8885 if ($this->mirrorMargins && ($this->page % 2==0)) {
8886 if ($hname) { $ehvalue = 1; $ehname = $hname; } else { $ehvalue = -1; }
8887 if ($fname) { $efvalue = 1; $efname = $fname; } else { $efvalue = -1; }
8888 }
8889 else {
8890 if ($hname) { $ohvalue = 1; $ohname = $hname; } else { $ohvalue = -1; }
8891 if ($fname) { $ofvalue = 1; $ofname = $fname; } else { $ofvalue = -1; }
8892 }
8893 if ($resetpagenum || $pagenumstyle || $suppress) {
8894 $this->PageNumSubstitutions[] = array('from'=>($this->page), 'reset'=> $resetpagenum, 'type'=>$pagenumstyle, 'suppress'=>$suppress);
8895 }
8896 // PAGED MEDIA - CROP / CROSS MARKS from @PAGE
8897 $this->show_marks = $marks;
8898
8899 // Background color
8900 if (isset($bg['BACKGROUND-COLOR'])) {
8901 $cor = $this->ConvertColor($bg['BACKGROUND-COLOR']);
8902 if ($cor) {
8903 $this->bodyBackgroundColor = $cor;
8904 }
8905 }
8906 else { $this->bodyBackgroundColor = false; }
8907
8908 /*-- BACKGROUNDS --*/
8909 if (isset($bg['BACKGROUND-GRADIENT'])) {
8910 $this->bodyBackgroundGradient = $bg['BACKGROUND-GRADIENT'];
8911 }
8912 else { $this->bodyBackgroundGradient = false; }
8913
8914 // Tiling Patterns
8915 if (isset($bg['BACKGROUND-IMAGE']) && $bg['BACKGROUND-IMAGE']) {
8916 $ret = $this->SetBackground($bg, $this->pgwidth);
8917 if ($ret) { $this->bodyBackgroundImage = $ret; }
8918 }
8919 else { $this->bodyBackgroundImage = false; }
8920 /*-- END BACKGROUNDS --*/
8921
8922 $this->page_box['current'] = $psel;
8923 $this->page_box['using'] = true;
8924 }
8925 /*-- END CSS-PAGE --*/
8926
8927 //Page orientation
8928 if(!$orientation)
8929 $orientation=$this->DefOrientation;
8930 else {
8931 $orientation=strtoupper(substr($orientation,0,1));
8932 if($orientation!=$this->DefOrientation)
8933 $this->OrientationChanges[$this->page]=true;
8934 }
8935 if($orientation!=$this->CurOrientation || $newformat) {
8936
8937 //Change orientation
8938 if($orientation=='P') {
8939 $this->wPt=$this->fwPt;
8940 $this->hPt=$this->fhPt;
8941 $this->w=$this->fw;
8942 $this->h=$this->fh;
8943 if (($this->forcePortraitHeaders || $this->forcePortraitMargins) && $this->DefOrientation=='P') {
8944 $this->tMargin = $this->orig_tMargin;
8945 $this->bMargin = $this->orig_bMargin;
8946 $this->DeflMargin = $this->orig_lMargin;
8947 $this->DefrMargin = $this->orig_rMargin;
8948 $this->margin_header = $this->orig_hMargin;
8949 $this->margin_footer = $this->orig_fMargin;
8950 }
8951 else { $resetHTMLHeadersrequired = true; } // *HTMLHEADERS-FOOTERS*
8952 }
8953 else {
8954 $this->wPt=$this->fhPt;
8955 $this->hPt=$this->fwPt;
8956 $this->w=$this->fh;
8957 $this->h=$this->fw;
8958 if (($this->forcePortraitHeaders || $this->forcePortraitMargins) && $this->DefOrientation=='P') {
8959 $this->tMargin = $this->orig_lMargin;
8960 $this->bMargin = $this->orig_rMargin;
8961 $this->DeflMargin = $this->orig_bMargin;
8962 $this->DefrMargin = $this->orig_tMargin;
8963 $this->margin_header = $this->orig_hMargin;
8964 $this->margin_footer = $this->orig_fMargin;
8965 }
8966 else { $resetHTMLHeadersrequired = true; } // *HTMLHEADERS-FOOTERS*
8967
8968 }
8969 $this->CurOrientation=$orientation;
8970 $this->ResetMargins();
8971 $this->pgwidth = $this->w - $this->lMargin - $this->rMargin;
8972 $this->PageBreakTrigger=$this->h-$this->bMargin;
8973 }
8974
8975 $this->pageDim[$this->page]['w']=$this->w ;
8976 $this->pageDim[$this->page]['h']=$this->h ;
8977
8978 $this->pageDim[$this->page]['outer_width_LR'] = isset($this->page_box['outer_width_LR']) ? $this->page_box['outer_width_LR'] : 0;
8979 $this->pageDim[$this->page]['outer_width_TB'] = isset($this->page_box['outer_width_TB']) ? $this->page_box['outer_width_TB'] : 0;
8980 if (!isset($this->page_box['outer_width_LR']) && !isset($this->page_box['outer_width_TB'])) {
8981 $this->pageDim[$this->page]['bleedMargin'] = 0;
8982 }
8983 else if ($this->bleedMargin <= $this->page_box['outer_width_LR'] && $this->bleedMargin <= $this->page_box['outer_width_TB']) {
8984 $this->pageDim[$this->page]['bleedMargin'] = $this->bleedMargin;
8985 }
8986 else {
8987 $this->pageDim[$this->page]['bleedMargin'] = min($this->page_box['outer_width_LR'], $this->page_box['outer_width_TB'])-0.01;
8988 }
8989
8990 // If Page Margins are re-defined
8991 // strlen()>0 is used to pick up (integer) 0, (string) '0', or set value
8992 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)) {
8993 if (strlen($mgl)>0) $this->DeflMargin = $mgl;
8994 if (strlen($mgr)>0) $this->DefrMargin = $mgr;
8995 if (strlen($mgt)>0) $this->tMargin = $mgt;
8996 if (strlen($mgb)>0) $this->bMargin = $mgb;
8997 if (strlen($mgh)>0) $this->margin_header=$mgh;
8998 if (strlen($mgf)>0) $this->margin_footer=$mgf;
8999 $this->ResetMargins();
9000 $this->SetAutoPageBreak($this->autoPageBreak,$this->bMargin);
9001 $this->pgwidth = $this->w - $this->lMargin - $this->rMargin;
9002 $resetHTMLHeadersrequired = true; // *HTMLHEADERS-FOOTERS*
9003 }
9004
9005 $this->ResetMargins();
9006 $this->pgwidth = $this->w - $this->lMargin - $this->rMargin;
9007 $this->SetAutoPageBreak($this->autoPageBreak,$this->bMargin);
9008
9009 // Reset column top margin
9010 $this->y0 = $this->tMargin;
9011
9012 $this->x=$this->lMargin;
9013 $this->y=$this->tMargin;
9014 $this->FontFamily='';
9015
9016 // HEADERS AND FOOTERS
9017 if ($ohvalue<0 || strtoupper($ohvalue)=='OFF') {
9018 $this->HTMLHeader = '';
9019 $this->headerDetails['odd'] = array();
9020 $resetHTMLHeadersrequired = true; // *HTMLHEADERS-FOOTERS*
9021 }
9022 else if ($ohname && $ohvalue>0) {
9023 /*-- HTMLHEADERS-FOOTERS --*/
9024 if (preg_match('/^html_(.*)$/i',$ohname,$n)) {
9025 if (isset($this->pageHTMLheaders[$n[1]])) { $this->HTMLHeader = $this->pageHTMLheaders[$n[1]]; }
9026 else { $this->HTMLHeader = ''; }
9027 $this->headerDetails['odd'] = array();
9028 $resetHTMLHeadersrequired = true;
9029 }
9030 else {
9031 /*-- END HTMLHEADERS-FOOTERS --*/
9032 if (isset($this->pageheaders[$ohname])) { $this->headerDetails['odd'] = $this->pageheaders[$ohname]; }
9033 else if ($ohname!='_default') { $this->headerDetails['odd'] = array(); }
9034 $this->HTMLHeader = '';
9035 /*-- HTMLHEADERS-FOOTERS --*/
9036 $resetHTMLHeadersrequired = false;
9037 }
9038 /*-- END HTMLHEADERS-FOOTERS --*/
9039 }
9040
9041 if ($ehvalue<0 || strtoupper($ehvalue)=='OFF') {
9042 $this->HTMLHeaderE = '';
9043 $this->headerDetails['even'] = array();
9044 $resetHTMLHeadersrequired = true; // *HTMLHEADERS-FOOTERS*
9045 }
9046 else if ($ehname && $ehvalue>0) {
9047 /*-- HTMLHEADERS-FOOTERS --*/
9048 if (preg_match('/^html_(.*)$/i',$ehname,$n)) {
9049 if (isset($this->pageHTMLheaders[$n[1]])) { $this->HTMLHeaderE = $this->pageHTMLheaders[$n[1]]; }
9050 else { $this->HTMLHeaderE = ''; }
9051 $this->headerDetails['even'] = array();
9052 $resetHTMLHeadersrequired = true;
9053 }
9054 else {
9055 /*-- END HTMLHEADERS-FOOTERS --*/
9056 if (isset($this->pageheaders[$ehname])) { $this->headerDetails['even'] = $this->pageheaders[$ehname]; }
9057 else if ($ehname!='_default') { $this->headerDetails['even'] = array(); }
9058 $this->HTMLHeaderE = '';
9059 /*-- HTMLHEADERS-FOOTERS --*/
9060 $resetHTMLHeadersrequired = false;
9061 }
9062 /*-- END HTMLHEADERS-FOOTERS --*/
9063 }
9064
9065 if ($ofvalue<0 || strtoupper($ofvalue)=='OFF') {
9066 $this->HTMLFooter = '';
9067 $this->footerDetails['odd'] = array();
9068 $resetHTMLHeadersrequired = true; // *HTMLHEADERS-FOOTERS*
9069 }
9070 else if ($ofname && $ofvalue>0) {
9071 /*-- HTMLHEADERS-FOOTERS --*/
9072 if (preg_match('/^html_(.*)$/i',$ofname,$n)) {
9073 if (isset($this->pageHTMLfooters[$n[1]])) { $this->HTMLFooter = $this->pageHTMLfooters[$n[1]]; }
9074 else { $this->HTMLFooter = ''; }
9075 $this->footerDetails['odd'] = array();
9076 $resetHTMLHeadersrequired = true;
9077 }
9078 else {
9079 /*-- END HTMLHEADERS-FOOTERS --*/
9080 if (isset($this->pagefooters[$ofname])) { $this->footerDetails['odd'] = $this->pagefooters[$ofname]; }
9081 else if ($ofname!='_default') { $this->footerDetails['odd'] = array(); }
9082 $this->HTMLFooter = '';
9083 /*-- HTMLHEADERS-FOOTERS --*/
9084 $resetHTMLHeadersrequired = true;
9085 }
9086 /*-- END HTMLHEADERS-FOOTERS --*/
9087 }
9088
9089 if ($efvalue<0 || strtoupper($efvalue)=='OFF') {
9090 $this->HTMLFooterE = '';
9091 $this->footerDetails['even'] = array();
9092 $resetHTMLHeadersrequired = true; // *HTMLHEADERS-FOOTERS*
9093 }
9094 else if ($efname && $efvalue>0) {
9095 /*-- HTMLHEADERS-FOOTERS --*/
9096 if (preg_match('/^html_(.*)$/i',$efname,$n)) {
9097 if (isset($this->pageHTMLfooters[$n[1]])) { $this->HTMLFooterE = $this->pageHTMLfooters[$n[1]]; }
9098 else { $this->HTMLFooterE = ''; }
9099 $this->footerDetails['even'] = array();
9100 $resetHTMLHeadersrequired = true;
9101 }
9102 else {
9103 /*-- END HTMLHEADERS-FOOTERS --*/
9104 if (isset($this->pagefooters[$efname])) { $this->footerDetails['even'] = $this->pagefooters[$efname]; }
9105 else if ($efname!='_default') { $this->footerDetails['even'] = array(); }
9106 $this->HTMLFooterE = '';
9107 /*-- HTMLHEADERS-FOOTERS --*/
9108 $resetHTMLHeadersrequired = true;
9109 }
9110 /*-- END HTMLHEADERS-FOOTERS --*/
9111 }
9112
9113 /*-- HTMLHEADERS-FOOTERS --*/
9114 if ($resetHTMLHeadersrequired) {
9115 $this->SetHTMLHeader($this->HTMLHeader );
9116 $this->SetHTMLHeader($this->HTMLHeaderE ,'E');
9117 $this->SetHTMLFooter($this->HTMLFooter );
9118 $this->SetHTMLFooter($this->HTMLFooterE ,'E');
9119 }
9120 /*-- END HTMLHEADERS-FOOTERS --*/
9121
9122
9123 if (($this->mirrorMargins) && (($this->page)%2==0)) { // EVEN
9124 $this->_setAutoHeaderHeight($this->headerDetails['even'], $this->HTMLHeaderE);
9125 $this->_setAutoFooterHeight($this->footerDetails['even'], $this->HTMLFooterE);
9126 }
9127 else { // ODD or DEFAULT
9128 $this->_setAutoHeaderHeight($this->headerDetails['odd'], $this->HTMLHeader);
9129 $this->_setAutoFooterHeight($this->footerDetails['odd'], $this->HTMLFooter);
9130 }
9131 // Reset column top margin
9132 $this->y0 = $this->tMargin;
9133
9134 $this->x=$this->lMargin;
9135 $this->y=$this->tMargin;
9136 }
9137
9138
9139
9140 function _setAutoHeaderHeight(&$det, &$htmlh) {
9141 if ($this->setAutoTopMargin=='pad') {
9142 if ($htmlh['h']) { $h = $htmlh['h']; }
9143 else if ($det) { $h = $this->_getHFHeight($det,'H'); }
9144 else { $h = 0; }
9145 $this->tMargin = $this->margin_header + $h + $this->orig_tMargin;
9146 }
9147 else if ($this->setAutoTopMargin=='stretch') {
9148 if ($htmlh['h']) { $h = $htmlh['h']; }
9149 else if ($det) { $h = $this->_getHFHeight($det,'H'); }
9150 else { $h = 0; }
9151 $this->tMargin = max($this->orig_tMargin, $this->margin_header + $h + $this->autoMarginPadding);
9152 }
9153 }
9154
9155
9156 function _setAutoFooterHeight(&$det, &$htmlf) {
9157 if ($this->setAutoBottomMargin=='pad') {
9158 if ($htmlf['h']) { $h = $htmlf['h']; }
9159 else if ($det) { $h = $this->_getHFHeight($det,'F'); }
9160 else { $h = 0; }
9161 $this->bMargin = $this->margin_footer + $h + $this->orig_bMargin;
9162 $this->PageBreakTrigger=$this->h-$this->bMargin ;
9163 }
9164 else if ($this->setAutoBottomMargin=='stretch') {
9165 if ($htmlf['h']) { $h = $htmlf['h']; }
9166 else if ($det) { $h = $this->_getHFHeight($det,'F'); }
9167 else { $h = 0; }
9168 $this->bMargin = max($this->orig_bMargin, $this->margin_footer + $h + $this->autoMarginPadding);
9169 $this->PageBreakTrigger=$this->h-$this->bMargin ;
9170 }
9171 }
9172
9173 function _getHFHeight(&$det,$end) {
9174 $h = 0;
9175 if(count($det)) {
9176 foreach(array('L','C','R') AS $pos) {
9177 if (isset($det[$pos]['content']) && $det[$pos]['content']) {
9178 if (isset($det[$pos]['font-size']) && $det[$pos]['font-size']) { $hfsz = $det[$pos]['font-size']; }
9179 else { $hfsz = $this->default_font_size; }
9180 $h = max($h,$hfsz/_MPDFK);
9181 }
9182 }
9183 if ($det['line'] && $end=='H') { $h += $h/_MPDFK*$this->header_line_spacing; }
9184 else if ($det['line'] && $end=='F') { $h += $h/_MPDFK*$this->footer_line_spacing; }
9185 }
9186 return $h;
9187 }
9188
9189
9190 function _endpage() {
9191 /*-- CSS-IMAGE-FLOAT --*/
9192 $this->printfloatbuffer();
9193 /*-- END CSS-IMAGE-FLOAT --*/
9194
9195 // mPDF 5.3.41
9196 if($this->visibility!='visible')
9197 $this->SetVisibility('visible');
9198
9199 //End of page contents
9200 $this->state=1;
9201 }
9202
9203 function _newobj($obj_id=false,$onlynewobj=false) {
9204 if (!$obj_id) {
9205 $obj_id = ++$this->n;
9206 }
9207 //Begin a new object
9208 if (!$onlynewobj) {
9209 $this->offsets[$obj_id] = strlen($this->buffer);
9210 $this->_out($obj_id.' 0 obj');
9211 $this->_current_obj_id = $obj_id; // for later use with encryption
9212 }
9213 }
9214
9215 function _dounderline($x,$y,$txt) {
9216 // Now print line exactly where $y secifies - called from Text() and Cell() - adjust position there
9217 // WORD SPACING
9218 $w =($this->GetStringWidth($txt)*_MPDFK) + ($this->charspacing * mb_strlen( $txt, $this->mb_enc ))
9219 + ( $this->ws * mb_substr_count( $txt, ' ', $this->mb_enc ));
9220 //Draw a line
9221 return sprintf('%.3F %.3F m %.3F %.3F l S',$x*_MPDFK,($this->h-$y)*_MPDFK,($x*_MPDFK)+$w,($this->h-$y)*_MPDFK);
9222 }
9223
9224
9225 function _imageError($file, $firsttime, $msg) {
9226 // Save re-trying image URL's which have already failed
9227 $this->failedimages[$file] = true;
9228 if ($firsttime && ($this->showImageErrors || $this->debug)) {
9229 $this->Error("IMAGE Error (".$file."): ".$msg);
9230 }
9231 return false;
9232 }
9233
9234
9235 function _getImage(&$file, $firsttime=true, $allowvector=true, $orig_srcpath=false) {
9236 // firsttime i.e. whether to add to this->images - use false when calling iteratively
9237 // mPDF 5.3.95
9238 $file = urldecode($file);
9239 if ($orig_srcpath) { $orig_srcpath = urldecode($orig_srcpath); }
9240 // Image Data passed directly as var:varname
9241 if (preg_match('/var:\s*(.*)/',$file, $v)) {
9242 $data = $this->$v[1];
9243 $file = md5($data);
9244 }
9245 $ppUx = 0;
9246 if ($firsttime && preg_match('/(.*\/)([^\/]*)/',$file,$fm)) {
9247 if (strlen($fm[2])) { $file = $fm[1].preg_replace('/ /','%20',$fm[2]); }
9248 }
9249 if ($orig_srcpath && isset($this->images[$orig_srcpath])) { $file=$orig_srcpath; return $this->images[$orig_srcpath]; }
9250 if (isset($this->images[$file])) { return $this->images[$file]; }
9251 else if ($orig_srcpath && isset($this->formobjects[$orig_srcpath])) { $file=$orig_srcpath; return $this->formobjects[$file]; }
9252 else if (isset($this->formobjects[$file])) { return $this->formobjects[$file]; }
9253 // Save re-trying image URL's which have already failed
9254 else if ($firsttime && isset($this->failedimages[$file])) { return $this->_imageError($file, $firsttime, ''); }
9255 if (empty($data)) {
9256 $type = '';
9257 $data = '';
9258 $mqr=$this->_getMQR();
9259 if ($mqr) { set_magic_quotes_runtime(0); }
9260
9261 if ($orig_srcpath && $this->basepathIsLocal && $check = @fopen($orig_srcpath,"rb")) {
9262 fclose($check);
9263 $file=$orig_srcpath;
9264 $data = file_get_contents($file);
9265 $type = $this->_imageTypeFromString($data);
9266 }
9267 if (!$data && $check = @fopen($file,"rb")) {
9268 fclose($check);
9269 $data = file_get_contents($file);
9270 $type = $this->_imageTypeFromString($data);
9271 }
9272 if ((!$data || !$type) && !ini_get('allow_url_fopen')) { // only worth trying if remote file and !ini_get('allow_url_fopen')
9273 $this->file_get_contents_by_socket($file, $data); // needs full url?? even on local (never needed for local)
9274 if ($data) { $type = $this->_imageTypeFromString($data); }
9275 }
9276 if ((!$data || !$type) && !ini_get('allow_url_fopen') && function_exists("curl_init")) {
9277 $this->file_get_contents_by_curl($file, $data); // needs full url?? even on local (never needed for local)
9278 if ($data) { $type = $this->_imageTypeFromString($data); }
9279 }
9280
9281 if ($mqr) { set_magic_quotes_runtime($mqr); }
9282 }
9283 if (!$data) { return $this->_imageError($file, $firsttime, 'Could not find image file'); }
9284 if (empty($type)) { $type = $this->_imageTypeFromString($data); }
9285 if (($type == 'wmf' || $type == 'svg') && !$allowvector) { return $this->_imageError($file, $firsttime, 'WMF or SVG image file not supported in this context'); }
9286
9287 // SVG
9288 if ($type == 'svg') {
9289 if (!class_exists('SVG', false)) { include(_MPDF_PATH .'classes/svg.php'); }
9290 $svg = new SVG($this);
9291 $family=$this->FontFamily;
9292 $style=$this->FontStyle;
9293 $size=$this->FontSizePt;
9294 $info = $svg->ImageSVG($data);
9295 //Restore font
9296 if($family) $this->SetFont($family,$style,$size,false);
9297 if (!$info) { return $this->_imageError($file, $firsttime, 'Error parsing SVG file'); }
9298 $info['type']='svg';
9299 $info['i']=count($this->formobjects)+1;
9300 $this->formobjects[$file]=$info;
9301 return $info;
9302 }
9303
9304 // JPEG
9305 if ($type == 'jpeg' || $type == 'jpg') {
9306 $hdr = $this->_jpgHeaderFromString($data);
9307 if (!$hdr) { return $this->_imageError($file, $firsttime, 'Error parsing JPG header'); }
9308 $a = $this->_jpgDataFromHeader($hdr);
9309 $j = strpos($data,'JFIF');
9310 if ($j) {
9311 //Read resolution
9312 $unitSp=ord(substr($data,($j+7),1));
9313 if ($unitSp > 0) {
9314 $ppUx=$this->_twobytes2int(substr($data,($j+8),2)); // horizontal pixels per meter, usually set to zero
9315 if ($unitSp == 2) { // = dots per cm (if == 1 set as dpi)
9316 $ppUx=round($ppUx/10 *25.4);
9317 }
9318 }
9319 }
9320 if ($a[2] == 'DeviceCMYK' && (($this->PDFA && $this->restrictColorSpace!=3) || $this->restrictColorSpace==2)) {
9321 // convert to RGB image
9322 if (!function_exists("gd_info")) { $this->Error("JPG image may not use CMYK color space (".$file.")."); }
9323 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.)"; }
9324 $im = @imagecreatefromstring($data);
9325 if ($im) {
9326 $tempfile = _MPDF_TEMP_PATH.'_tempImgPNG'.RAND(1,10000).'.png';
9327 imageinterlace($im, false);
9328 $check = @imagepng($im, $tempfile);
9329 if (!$check) { return $this->_imageError($file, $firsttime, 'Error creating temporary file ('.$tempfile.') whilst using GD library to parse JPG(CMYK) image'); }
9330 $info = $this->_getImage($tempfile, false);
9331 if (!$info) { return $this->_imageError($file, $firsttime, 'Error parsing temporary file ('.$tempfile.') created with GD library to parse JPG(CMYK) image'); }
9332 imagedestroy($im);
9333 unlink($tempfile);
9334 $info['type']='jpg';
9335 if ($firsttime) {
9336 $info['i']=count($this->images)+1;
9337 $this->images[$file]=$info;
9338 }
9339 return $info;
9340 }
9341 else { return $this->_imageError($file, $firsttime, 'Error creating GD image file from JPG(CMYK) image'); }
9342 }
9343 else if ($a[2] == 'DeviceRGB' && ($this->PDFX || $this->restrictColorSpace==3)) {
9344 // Convert to CMYK image stream - nominally returned as type='png'
9345 $info = $this->_convImage($data, $a[2], 'DeviceCMYK', $a[0], $a[1], $ppUx, false);
9346 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.)"; }
9347 }
9348 else if (($a[2] == 'DeviceRGB' || $a[2] == 'DeviceCMYK') && $this->restrictColorSpace==1) {
9349 // Convert to Grayscale image stream - nominally returned as type='png'
9350 $info = $this->_convImage($data, $a[2], 'DeviceGray', $a[0], $a[1], $ppUx, false);
9351 }
9352 else {
9353 $info = array('w'=>$a[0],'h'=>$a[1],'cs'=>$a[2],'bpc'=>$a[3],'f'=>'DCTDecode','data'=>$data, 'type'=>'jpg');
9354 if ($ppUx) { $info['set-dpi'] = $ppUx; }
9355 }
9356 if (!$info) { return $this->_imageError($file, $firsttime, 'Error parsing or converting JPG image'); }
9357
9358 if ($firsttime) {
9359 $info['i']=count($this->images)+1;
9360 $this->images[$file]=$info;
9361 }
9362 return $info;
9363 }
9364
9365 // PNG
9366 else if ($type == 'png') {
9367 //Check signature
9368 if(substr($data,0,8)!=chr(137).'PNG'.chr(13).chr(10).chr(26).chr(10)) {
9369 return $this->_imageError($file, $firsttime, 'Error parsing PNG identifier');
9370 }
9371 //Read header chunk
9372 if(substr($data,12,4)!='IHDR') {
9373 return $this->_imageError($file, $firsttime, 'Incorrect PNG file (no IHDR block found)');
9374 }
9375
9376 $w=$this->_fourbytes2int(substr($data,16,4));
9377 $h=$this->_fourbytes2int(substr($data,20,4));
9378 $bpc=ord(substr($data,24,1));
9379 $errpng = false;
9380 $pngalpha = false;
9381 if($bpc>8) { $errpng = 'not 8-bit depth'; }
9382 $ct=ord(substr($data,25,1));
9383 if($ct==0) { $colspace='DeviceGray'; }
9384 elseif($ct==2) { $colspace='DeviceRGB'; }
9385 elseif($ct==3) { $colspace='Indexed'; }
9386 elseif($ct==4) { $colspace='DeviceGray'; $errpng = 'alpha channel'; $pngalpha = true; }
9387 else { $colspace='DeviceRGB'; $errpng = 'alpha channel'; $pngalpha = true; }
9388 if(ord(substr($data,26,1))!=0) { $errpng = 'compression method'; }
9389 if(ord(substr($data,27,1))!=0) { $errpng = 'filter method'; }
9390 if(ord(substr($data,28,1))!=0) { $errpng = 'interlaced file'; }
9391 $j = strpos($data,'pHYs');
9392 if ($j) {
9393 //Read resolution
9394 $unitSp=ord(substr($data,($j+12),1));
9395 if ($unitSp == 1) {
9396 $ppUx=$this->_fourbytes2int(substr($data,($j+4),4)); // horizontal pixels per meter, usually set to zero
9397 $ppUx=round($ppUx/1000 *25.4);
9398 }
9399 }
9400 if (($colspace == 'DeviceRGB' || $colspace == 'Indexed') && ($this->PDFX || $this->restrictColorSpace==3)) {
9401 // Convert to CMYK image stream - nominally returned as type='png'
9402 $info = $this->_convImage($data, $colspace, 'DeviceCMYK', $w, $h, $ppUx, $pngalpha);
9403 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.)"; }
9404 }
9405 else if (($colspace == 'DeviceRGB' || $colspace == 'Indexed') && $this->restrictColorSpace==1) {
9406 // Convert to Grayscale image stream - nominally returned as type='png'
9407 $info = $this->_convImage($data, $colspace, 'DeviceGray', $w, $h, $ppUx, $pngalpha);
9408 }
9409 else if (($this->PDFA || $this->PDFX) && $pngalpha) {
9410 // Remove alpha channel
9411 if ($this->restrictColorSpace==1) { // Grayscale
9412 $info = $this->_convImage($data, $colspace, 'DeviceGray', $w, $h, $ppUx, $pngalpha);
9413 }
9414 else if ($this->restrictColorSpace==3) { // CMYK
9415 $info = $this->_convImage($data, $colspace, 'DeviceCMYK', $w, $h, $ppUx, $pngalpha);
9416 }
9417 else if ($this->PDFA ) { // RGB
9418 $info = $this->_convImage($data, $colspace, 'DeviceRGB', $w, $h, $ppUx, $pngalpha);
9419 }
9420 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.)"; }
9421 }
9422 else if ($errpng || $pngalpha) {
9423 if (function_exists('gd_info')) { $gd = gd_info(); }
9424 else {$gd = array(); }
9425 if (!isset($gd['PNG Support'])) { return $this->_imageError($file, $firsttime, 'GD library required for PNG image ('.$errpng.')'); }
9426 $im = imagecreatefromstring($data);
9427 if (!$im) { return $this->_imageError($file, $firsttime, 'Error creating GD image from PNG file ('.$errpng.')'); }
9428 $w = imagesx($im);
9429 $h = imagesy($im);
9430 if ($im) {
9431 $tempfile = _MPDF_TEMP_PATH.'_tempImgPNG'.RAND(1,10000).'.png';
9432 // Alpha channel set
9433 if ($pngalpha) {
9434 if ($this->PDFA) { $this->Error("PDFA1-b does not permit images with alpha channel transparency (".$file.")."); }
9435 $imgalpha = imagecreate($w, $h);
9436 // generate gray scale pallete
9437 for ($c = 0; $c < 256; ++$c) { ImageColorAllocate($imgalpha, $c, $c, $c); }
9438 // extract alpha channel
9439 $gammacorr = 2.2; // gamma correction // mPDF 5.3.07
9440 for ($xpx = 0; $xpx < $w; ++$xpx) {
9441 for ($ypx = 0; $ypx < $h; ++$ypx) {
9442 // mPDF 5.3.07
9443 //$colorindex = imagecolorat($im, $xpx, $ypx);
9444 //$col = imagecolorsforindex($im, $colorindex);
9445 //$gamma2 = (pow((((127 - $col['alpha']) * 255 / 127) / 255), $gammacorr) * 255);
9446 $alpha = (imagecolorat($im, $xpx, $ypx) & 0x7F000000) >> 24;
9447 if ($alpha < 127) {
9448 if ($alpha==0) { $gamma = 255; }
9449 else
9450 $gamma = (pow((((127 - $alpha) * 255 / 127) / 255), $gammacorr) * 255);
9451 imagesetpixel($imgalpha, $xpx, $ypx, $gamma);
9452 }
9453 }
9454 }
9455 // create temp alpha file
9456 $tempfile_alpha = _MPDF_TEMP_PATH.'_tempMskPNG'.RAND(1,10000).'.png';
9457 if (!is_writable($tempfile_alpha)) {
9458 ob_start();
9459 $check = @imagepng($imgalpha);
9460 if (!$check) { return $this->_imageError($file, $firsttime, 'Error creating temporary image object whilst using GD library to parse PNG image'); }
9461 imagedestroy($imgalpha);
9462 $this->_tempimg = ob_get_contents();
9463 $this->_tempimglnk = 'var:_tempimg';
9464 ob_end_clean();
9465 // extract image without alpha channel
9466 $imgplain = imagecreatetruecolor($w, $h);
9467 imagecopy($imgplain, $im, 0, 0, 0, 0, $w, $h);
9468 // create temp image file
9469 $minfo = $this->_getImage($this->_tempimglnk, false);
9470 if (!$minfo) { return $this->_imageError($file, $firsttime, 'Error parsing temporary file image object created with GD library to parse PNG image'); }
9471 ob_start();
9472 $check = @imagepng($imgplain);
9473 if (!$check) { return $this->_imageError($file, $firsttime, 'Error creating temporary image object whilst using GD library to parse PNG image'); }
9474 $this->_tempimg = ob_get_contents();
9475 $this->_tempimglnk = 'var:_tempimg';
9476 ob_end_clean();
9477 $info = $this->_getImage($this->_tempimglnk, false);
9478 if (!$info) { return $this->_imageError($file, $firsttime, 'Error parsing temporary file image object created with GD library to parse PNG image'); }
9479 imagedestroy($imgplain);
9480 $imgmask = count($this->images)+1;
9481 $minfo['cs'] = 'DeviceGray';
9482 $minfo['i']=$imgmask ;
9483 $this->images[$tempfile_alpha] = $minfo;
9484
9485 }
9486 else {
9487 $check = @imagepng($imgalpha, $tempfile_alpha);
9488 if (!$check) { return $this->_imageError($file, $firsttime, 'Failed to create temporary image file ('.$tempfile_alpha.') parsing PNG image with alpha channel ('.$errpng.')'); }
9489 imagedestroy($imgalpha);
9490
9491 // extract image without alpha channel
9492 $imgplain = imagecreatetruecolor($w, $h);
9493 imagecopy($imgplain, $im, 0, 0, 0, 0, $w, $h);
9494
9495 // create temp image file
9496 $check = @imagepng($imgplain, $tempfile);
9497 if (!$check) { return $this->_imageError($file, $firsttime, 'Failed to create temporary image file ('.$tempfile.') parsing PNG image with alpha channel ('.$errpng.')'); }
9498 imagedestroy($imgplain);
9499 // embed mask image
9500 $minfo = $this->_getImage($tempfile_alpha, false);
9501 unlink($tempfile_alpha);
9502 if (!$minfo) { return $this->_imageError($file, $firsttime, 'Error parsing temporary file ('.$tempfile_alpha.') created with GD library to parse PNG image'); }
9503 $imgmask = count($this->images)+1;
9504 $minfo['cs'] = 'DeviceGray';
9505 $minfo['i']=$imgmask ;
9506 $this->images[$tempfile_alpha] = $minfo;
9507 // embed image, masked with previously embedded mask
9508 $info = $this->_getImage($tempfile, false);
9509 unlink($tempfile);
9510 if (!$info) { return $this->_imageError($file, $firsttime, 'Error parsing temporary file ('.$tempfile.') created with GD library to parse PNG image'); }
9511
9512 }
9513 $info['masked'] = $imgmask;
9514 if ($ppUx) { $info['set-dpi'] = $ppUx; }
9515 $info['type']='png';
9516 if ($firsttime) {
9517 $info['i']=count($this->images)+1;
9518 $this->images[$file]=$info;
9519 }
9520 return $info;
9521 }
9522 else { // No alpha/transparency set
9523 imagealphablending($im, false);
9524 imagesavealpha($im, false);
9525 imageinterlace($im, false);
9526 if (!is_writable($tempfile)) {
9527 ob_start();
9528 $check = @imagepng($im);
9529 if (!$check) { return $this->_imageError($file, $firsttime, 'Error creating temporary image object whilst using GD library to parse PNG image'); }
9530 $this->_tempimg = ob_get_contents();
9531 $this->_tempimglnk = 'var:_tempimg';
9532 ob_end_clean();
9533 $info = $this->_getImage($this->_tempimglnk, false);
9534 if (!$info) { return $this->_imageError($file, $firsttime, 'Error parsing temporary file image object created with GD library to parse PNG image'); }
9535 imagedestroy($im);
9536 }
9537 else {
9538 $check = @imagepng($im, $tempfile );
9539 if (!$check) { return $this->_imageError($file, $firsttime, 'Failed to create temporary image file ('.$tempfile.') parsing PNG image ('.$errpng.')'); }
9540 imagedestroy($im);
9541 $info = $this->_getImage($tempfile, false) ;
9542 unlink($tempfile );
9543 if (!$info) { return $this->_imageError($file, $firsttime, 'Error parsing temporary file ('.$tempfile.') created with GD library to parse PNG image'); }
9544 }
9545 if ($ppUx) { $info['set-dpi'] = $ppUx; }
9546 $info['type']='png';
9547 if ($firsttime) {
9548 $info['i']=count($this->images)+1;
9549 $this->images[$file]=$info;
9550 }
9551 return $info;
9552 }
9553 }
9554 }
9555
9556 else {
9557 $parms='/DecodeParms <</Predictor 15 /Colors '.($ct==2 ? 3 : 1).' /BitsPerComponent '.$bpc.' /Columns '.$w.'>>';
9558 //Scan chunks looking for palette, transparency and image data
9559 $pal='';
9560 $trns='';
9561 $pngdata='';
9562 $p = 33;
9563 do {
9564 $n=$this->_fourbytes2int(substr($data,$p,4)); $p += 4;
9565 $type=substr($data,$p,4); $p += 4;
9566 if($type=='PLTE') {
9567 //Read palette
9568 $pal=substr($data,$p,$n); $p += $n;
9569 $p += 4;
9570 }
9571 elseif($type=='tRNS') {
9572 //Read transparency info
9573 $t=substr($data,$p,$n); $p += $n;
9574 if($ct==0) $trns=array(ord(substr($t,1,1)));
9575 elseif($ct==2) $trns=array(ord(substr($t,1,1)),ord(substr($t,3,1)),ord(substr($t,5,1)));
9576 else
9577 {
9578 $pos=strpos($t,chr(0));
9579 if(is_int($pos)) $trns=array($pos);
9580 }
9581 $p += 4;
9582 }
9583 elseif($type=='IDAT') {
9584 $pngdata.=substr($data,$p,$n); $p += $n;
9585 $p += 4;
9586 }
9587 elseif($type=='IEND') { break; }
9588 else if (preg_match('/[a-zA-Z]{4}/',$type)) { $p += $n+4; }
9589 else { return $this->_imageError($file, $firsttime, 'Error parsing PNG image data'); }
9590 }
9591 while($n);
9592 if (!$pngdata) { return $this->_imageError($file, $firsttime, 'Error parsing PNG image data - no IDAT data found'); }
9593 if($colspace=='Indexed' and empty($pal)) { return $this->_imageError($file, $firsttime, 'Error parsing PNG image data - missing colour palette'); }
9594 $info = array('w'=>$w,'h'=>$h,'cs'=>$colspace,'bpc'=>$bpc,'f'=>'FlateDecode','parms'=>$parms,'pal'=>$pal,'trns'=>$trns,'data'=>$pngdata);
9595 $info['type']='png';
9596 if ($ppUx) { $info['set-dpi'] = $ppUx; }
9597 }
9598
9599 if (!$info) { return $this->_imageError($file, $firsttime, 'Error parsing or converting PNG image'); }
9600
9601 if ($firsttime) {
9602 $info['i']=count($this->images)+1;
9603 $this->images[$file]=$info;
9604 }
9605 return $info;
9606 }
9607
9608 // GIF
9609 else if ($type == 'gif') {
9610 if (function_exists('gd_info')) { $gd = gd_info(); }
9611 else {$gd = array(); }
9612 if (isset($gd['GIF Read Support']) && $gd['GIF Read Support']) {
9613 $im = @imagecreatefromstring($data);
9614 if ($im) {
9615 $tempfile = _MPDF_TEMP_PATH.'_tempImgPNG'.RAND(1,10000).'.png';
9616 imagealphablending($im, false);
9617 imagesavealpha($im, false);
9618 imageinterlace($im, false);
9619 if (!is_writable($tempfile)) {
9620 ob_start();
9621 $check = @imagepng($im);
9622 if (!$check) { return $this->_imageError($file, $firsttime, 'Error creating temporary image object whilst using GD library to parse GIF image'); }
9623 $this->_tempimg = ob_get_contents();
9624 $this->_tempimglnk = 'var:_tempimg';
9625 ob_end_clean();
9626 $info = $this->_getImage($this->_tempimglnk, false);
9627 if (!$info) { return $this->_imageError($file, $firsttime, 'Error parsing temporary file image object created with GD library to parse GIF image'); }
9628 imagedestroy($im);
9629 }
9630 else {
9631 $check = @imagepng($im, $tempfile);
9632 if (!$check) { return $this->_imageError($file, $firsttime, 'Error creating temporary file ('.$tempfile.') whilst using GD library to parse GIF image'); }
9633 $info = $this->_getImage($tempfile, false);
9634 if (!$info) { return $this->_imageError($file, $firsttime, 'Error parsing temporary file ('.$tempfile.') created with GD library to parse GIF image'); }
9635 imagedestroy($im);
9636 unlink($tempfile);
9637 }
9638 $info['type']='gif';
9639 if ($firsttime) {
9640 $info['i']=count($this->images)+1;
9641 $this->images[$file]=$info;
9642 }
9643 return $info;
9644 }
9645 else { return $this->_imageError($file, $firsttime, 'Error creating GD image file from GIF image'); }
9646 }
9647
9648 if (!class_exists('gif', false)) {
9649 include_once(_MPDF_PATH.'classes/gif.php');
9650 }
9651 $gif=new CGIF();
9652
9653 $h=0;
9654 $w=0;
9655 $gif->loadFile($data, 0);
9656
9657 if(isset($gif->m_img->m_gih->m_bLocalClr) && $gif->m_img->m_gih->m_bLocalClr) {
9658 $nColors = $gif->m_img->m_gih->m_nTableSize;
9659 $pal = $gif->m_img->m_gih->m_colorTable->toString();
9660 if($bgColor != -1) {
9661 $bgColor = $gif->m_img->m_gih->m_colorTable->colorIndex($bgColor);
9662 }
9663 $colspace='Indexed';
9664 } elseif(isset($gif->m_gfh->m_bGlobalClr) && $gif->m_gfh->m_bGlobalClr) {
9665 $nColors = $gif->m_gfh->m_nTableSize;
9666 $pal = $gif->m_gfh->m_colorTable->toString();
9667 if((isset($bgColor)) and $bgColor != -1) {
9668 $bgColor = $gif->m_gfh->m_colorTable->colorIndex($bgColor);
9669 }
9670 $colspace='Indexed';
9671 } else {
9672 $nColors = 0;
9673 $bgColor = -1;
9674 $colspace='DeviceGray';
9675 $pal='';
9676 }
9677
9678 $trns='';
9679 if(isset($gif->m_img->m_bTrans) && $gif->m_img->m_bTrans && ($nColors > 0)) {
9680 $trns=array($gif->m_img->m_nTrans);
9681 }
9682 $gifdata=$gif->m_img->m_data;
9683 $w=$gif->m_gfh->m_nWidth;
9684 $h=$gif->m_gfh->m_nHeight;
9685 $gif->ClearData();
9686
9687 if($colspace=='Indexed' and empty($pal)) {
9688 return $this->_imageError($file, $firsttime, 'Error parsing GIF image - missing colour palette');
9689 }
9690 if ($this->compress) {
9691 $gifdata=gzcompress($gifdata);
9692 $info = array( 'w'=>$w, 'h'=>$h, 'cs'=>$colspace, 'bpc'=>8, 'f'=>'FlateDecode', 'pal'=>$pal, 'trns'=>$trns, 'data'=>$gifdata);
9693 }
9694 else {
9695 $info = array( 'w'=>$w, 'h'=>$h, 'cs'=>$colspace, 'bpc'=>8, 'pal'=>$pal, 'trns'=>$trns, 'data'=>$gifdata);
9696 }
9697 $info['type']='gif';
9698 if ($firsttime) {
9699 $info['i']=count($this->images)+1;
9700 $this->images[$file]=$info;
9701 }
9702 return $info;
9703 }
9704
9705 /*-- IMAGES-BMP --*/
9706 // BMP (Windows Bitmap)
9707 else if ($type == 'bmp') {
9708 // mPDF 5.3.89
9709 if (!class_exists('bmp', false)) { include(_MPDF_PATH.'classes/bmp.php'); }
9710 if (empty($this->bmp)) { $this->bmp = new bmp($this); }
9711 $info = $this->bmp->_getBMPimage($data, $file);
9712 if (isset($info['error'])) {
9713 return $this->_imageError($file, $firsttime, $info['error']);
9714 }
9715 if ($firsttime) {
9716 $info['i']=count($this->images)+1;
9717 $this->images[$file]=$info;
9718 }
9719 return $info;
9720 }
9721 /*-- END IMAGES-BMP --*/
9722 /*-- IMAGES-WMF --*/
9723 // WMF
9724 else if ($type == 'wmf') {
9725 // mPDF 5.3.89
9726 if (!class_exists('wmf', false)) { include(_MPDF_PATH.'classes/wmf.php'); }
9727 if (empty($this->wmf)) { $this->wmf = new wmf($this); }
9728 $wmfres = $this->wmf->_getWMFimage($data);
9729 if ($wmfres[0]==0) {
9730 if ($wmfres[1]) { return $this->_imageError($file, $firsttime, $wmfres[1]); }
9731 return $this->_imageError($file, $firsttime, 'Error parsing WMF image');
9732 }
9733 $info = array('x'=>$wmfres[2][0],'y'=>$wmfres[2][1],'w'=>$wmfres[3][0],'h'=>$wmfres[3][1],'data'=>$wmfres[1]);
9734 $info['i']=count($this->formobjects)+1;
9735 $info['type']='wmf';
9736 $this->formobjects[$file]=$info;
9737 return $info;
9738 }
9739 /*-- END IMAGES-WMF --*/
9740
9741 // UNKNOWN TYPE - try GD imagecreatefromstring
9742 else {
9743 if (function_exists('gd_info')) { $gd = gd_info(); }
9744 else {$gd = array(); }
9745 if (isset($gd['PNG Support']) && $gd['PNG Support']) {
9746 $im = @imagecreatefromstring($data);
9747 if (!$im) { return $this->_imageError($file, $firsttime, 'Error parsing image file - image type not recognised, and not supported by GD imagecreate'); }
9748 $tempfile = _MPDF_TEMP_PATH.'_tempImgPNG'.RAND(1,10000).'.png';
9749 imagealphablending($im, false);
9750 imagesavealpha($im, false);
9751 imageinterlace($im, false);
9752 $check = @imagepng($im, $tempfile);
9753 if (!$check) { return $this->_imageError($file, $firsttime, 'Error creating temporary file ('.$tempfile.') whilst using GD library to parse unknown image type'); }
9754 $info = $this->_getImage($tempfile, false);
9755 imagedestroy($im);
9756 unlink($tempfile);
9757 if (!$info) { return $this->_imageError($file, $firsttime, 'Error parsing temporary file ('.$tempfile.') created with GD library to parse unknown image type'); }
9758 $info['type']='png';
9759 if ($firsttime) {
9760 $info['i']=count($this->images)+1;
9761 $this->images[$file]=$info;
9762 }
9763 return $info;
9764 }
9765 }
9766
9767 return $this->_imageError($file, $firsttime, 'Error parsing image file - image type not recognised');
9768 }
9769 //==============================================================
9770 function _convImage(&$data, $colspace, $targetcs, $w, $h, $dpi, $mask) {
9771 if ($this->PDFA || $this->PDFX) { $mask=false; }
9772 $im = @imagecreatefromstring($data);
9773 $info = array();
9774 if ($im) {
9775 $imgdata = '';
9776 $mimgdata = '';
9777 $minfo = array();
9778 //Read transparency info
9779 $trns=array();
9780 $trnsrgb = false;
9781 if (!$this->PDFA && !$this->PDFX) {
9782 $p = strpos($data,'tRNS');
9783 if ($p) {
9784 $n=$this->_fourbytes2int(substr($data,($p-4),4));
9785 $t = substr($data,($p+4),$n);
9786 if ($colspace=='DeviceGray') {
9787 $trns=array(ord(substr($t,1,1)));
9788 $trnsrgb = array($trns[0],$trns[0],$trns[0]);
9789 }
9790 else if ($colspace=='DeviceRGB') {
9791 $trns=array(ord(substr($t,1,1)),ord(substr($t,3,1)),ord(substr($t,5,1)));
9792 $trnsrgb = $trns;
9793 if ($targetcs=='DeviceCMYK') {
9794 $col = $this->rgb2cmyk(array(3,$trns[0],$trns[1],$trns[2]));
9795 $c1 = intval($col[1]*2.55);
9796 $c2 = intval($col[2]*2.55);
9797 $c3 = intval($col[3]*2.55);
9798 $c4 = intval($col[4]*2.55);
9799 $trns = array($c1,$c2,$c3,$c4);
9800 }
9801 else if ($targetcs=='DeviceGray') {
9802 $c = intval(($trns[0] * .21) + ($trns[1] * .71) + ($trns[2] * .07));
9803 $trns = array($c);
9804 }
9805 }
9806 else { // Indexed
9807 $pos = strpos($t,chr(0));
9808 if (is_int($pos)) {
9809 $pal = imagecolorsforindex($im, $pos);
9810 $r = $pal['red'];
9811 $g = $pal['green'];
9812 $b = $pal['blue'];
9813 $trns=array($r,$g,$b); // ****
9814 $trnsrgb = $trns;
9815 if ($targetcs=='DeviceCMYK') {
9816 $col = $this->rgb2cmyk(array(3,$r,$g,$b));
9817 $c1 = intval($col[1]*2.55);
9818 $c2 = intval($col[2]*2.55);
9819 $c3 = intval($col[3]*2.55);
9820 $c4 = intval($col[4]*2.55);
9821 $trns = array($c1,$c2,$c3,$c4);
9822 }
9823 else if ($targetcs=='DeviceGray') {
9824 $c = intval(($r * .21) + ($g * .71) + ($b * .07));
9825 $trns = array($c);
9826 }
9827 }
9828 }
9829 }
9830 }
9831 for ($i = 0; $i < $h; $i++) {
9832 for ($j = 0; $j < $w; $j++) {
9833 $rgb = imagecolorat($im, $j, $i);
9834 $r = ($rgb >> 16) & 0xFF;
9835 $g = ($rgb >> 8) & 0xFF;
9836 $b = $rgb & 0xFF;
9837 if ($colspace=='Indexed') {
9838 $pal = imagecolorsforindex($im, $rgb);
9839 $r = $pal['red'];
9840 $g = $pal['green'];
9841 $b = $pal['blue'];
9842 }
9843
9844 if ($targetcs=='DeviceCMYK') {
9845 $col = $this->rgb2cmyk(array(3,$r,$g,$b));
9846 $c1 = intval($col[1]*2.55);
9847 $c2 = intval($col[2]*2.55);
9848 $c3 = intval($col[3]*2.55);
9849 $c4 = intval($col[4]*2.55);
9850 if ($trnsrgb) {
9851 // original pixel was not set as transparent but processed color does match
9852 if ($trnsrgb!=array($r,$g,$b) && $trns==array($c1,$c2,$c3,$c4)) {
9853 if ($c4==0) { $c4=1; } else { $c4--; }
9854 }
9855 }
9856 $imgdata .= chr($c1).chr($c2).chr($c3).chr($c4);
9857 }
9858 else if ($targetcs=='DeviceGray') {
9859 $c = intval(($r * .21) + ($g * .71) + ($b * .07));
9860 if ($trnsrgb) {
9861 // original pixel was not set as transparent but processed color does match
9862 if ($trnsrgb!=array($r,$g,$b) && $trns==array($c)) {
9863 if ($c==0) { $c=1; } else { $c--; }
9864 }
9865 }
9866 $imgdata .= chr($c);
9867 }
9868 else if ($targetcs=='DeviceRGB') {
9869 $imgdata .= chr($r).chr($g).chr($b);
9870 }
9871 if ($mask) {
9872 $col = imagecolorsforindex($im, $rgb);
9873 $gammacorr = 2.2; // gamma correction
9874 $gamma = intval((pow((((127 - $col['alpha']) * 255 / 127) / 255), $gammacorr) * 255));
9875 $mimgdata .= chr($gamma);
9876 }
9877 }
9878 }
9879
9880 if ($targetcs=='DeviceGray') { $ncols = 1; }
9881 else if ($targetcs=='DeviceRGB') { $ncols = 3; }
9882 else if ($targetcs=='DeviceCMYK') { $ncols = 4; }
9883
9884 $imgdata = gzcompress($imgdata);
9885 $info = array('w'=>$w,'h'=>$h,'cs'=>$targetcs,'bpc'=>8,'f'=>'FlateDecode','data'=>$imgdata, 'type'=>'png',
9886 'parms'=>'/DecodeParms <</Colors '.$ncols.' /BitsPerComponent 8 /Columns '.$w.'>>');
9887 if ($dpi) { $info['set-dpi'] = $dpi; }
9888 if ($mask) {
9889 $mimgdata = gzcompress($mimgdata);
9890 $minfo = array('w'=>$w,'h'=>$h,'cs'=>'DeviceGray','bpc'=>8,'f'=>'FlateDecode','data'=>$mimgdata, 'type'=>'png',
9891 'parms'=>'/DecodeParms <</Colors '.$ncols.' /BitsPerComponent 8 /Columns '.$w.'>>');
9892 if ($dpi) { $minfo['set-dpi'] = $dpi; }
9893 $tempfile = '_tempImgPNG'.RAND(1,10000).'.png';
9894 $imgmask = count($this->images)+1;
9895 $minfo['i']=$imgmask ;
9896 $this->images[$tempfile] = $minfo;
9897 $info['masked'] = $imgmask;
9898 }
9899 else if ($trns) { $info['trns'] = $trns; }
9900 imagedestroy($im);
9901 }
9902 return $info;
9903 }
9904
9905
9906
9907
9908 function _fourbytes2int($s) {
9909 //Read a 4-byte integer from string
9910 return (ord($s[0])<<24) + (ord($s[1])<<16) + (ord($s[2])<<8) + ord($s[3]);
9911 }
9912
9913 function _twobytes2int($s) {
9914 //Read a 2-byte integer from string
9915 return (ord(substr($s, 0, 1))<<8) + ord(substr($s, 1, 1));
9916 }
9917
9918 function _jpgHeaderFromString(&$data) {
9919 $p = 4;
9920 $p += $this->_twobytes2int(substr($data, $p, 2)); // Length of initial marker block
9921 $marker = substr($data, $p, 2);
9922 while($marker != chr(255).chr(192) && $marker != chr(255).chr(194) && $p<strlen($data)) {
9923 // Start of frame marker (FFC0) or (FFC2) mPDF 4.4.004
9924 $p += ($this->_twobytes2int(substr($data, $p+2, 2))) + 2; // Length of marker block
9925 $marker = substr($data, $p, 2);
9926 }
9927 if ($marker != chr(255).chr(192) && $marker != chr(255).chr(194)) { return false; }
9928 return substr($data, $p+2, 10);
9929 }
9930
9931 function _jpgDataFromHeader($hdr) {
9932 $bpc = ord(substr($hdr, 2, 1));
9933 if (!$bpc) { $bpc = 8; }
9934 $h = $this->_twobytes2int(substr($hdr, 3, 2));
9935 $w = $this->_twobytes2int(substr($hdr, 5, 2));
9936 $channels = ord(substr($hdr, 7, 1));
9937 if ($channels==3) { $colspace='DeviceRGB'; }
9938 elseif($channels==4) { $colspace='DeviceCMYK'; }
9939 else { $colspace='DeviceGray'; }
9940 return array($w, $h, $colspace, $bpc);
9941 }
9942
9943 function file_get_contents_by_curl($url, &$data) {
9944 $timeout = 5;
9945 $ch = curl_init($url);
9946 curl_setopt($ch, CURLOPT_HEADER, 0);
9947 curl_setopt($ch, CURLOPT_NOBODY, 0);
9948 curl_setopt ( $ch , CURLOPT_RETURNTRANSFER , 1 );
9949 curl_setopt ( $ch , CURLOPT_CONNECTTIMEOUT , $timeout );
9950 $data = curl_exec($ch);
9951 curl_close($ch);
9952 }
9953
9954
9955 function file_get_contents_by_socket($url, &$data) {
9956 $timeout = 1;
9957 $p = parse_url($url);
9958 $file = $p['path'];
9959 if ($p['query']) { $file .= '?'.$p['query']; }
9960 if(!($fh = @fsockopen($p['host'], 80, $errno, $errstr, $timeout))) { return false; }
9961 $getstring =
9962 "GET ".$file." HTTP/1.0 \r\n" .
9963 "Host: ".$p['host']." \r\n" .
9964 "Connection: close\r\n\r\n";
9965 fwrite($fh, $getstring);
9966 // Get rid of HTTP header
9967 $s = fgets($fh, 1024);
9968 if (!$s) { return false; }
9969 $httpheader .= $s;
9970 while (!feof($fh)) {
9971 $s = fgets($fh, 1024);
9972 if ( $s == "\r\n" ) { break; }
9973 }
9974 $data = '';
9975 while (!feof($fh)) {
9976 $data .= fgets($fh, 1024);
9977 }
9978 fclose($fh);
9979 }
9980
9981 //==============================================================
9982
9983 function _imageTypeFromString(&$data) {
9984 $type = '';
9985 if (substr($data, 6, 4)== 'JFIF' || substr($data, 6, 4)== 'Exif') {
9986 $type = 'jpeg';
9987 }
9988 else if (substr($data, 0, 6)== "GIF87a" || substr($data, 0, 6)== "GIF89a") {
9989 $type = 'gif';
9990 }
9991 else if (substr($data, 0, 8)== chr(137).'PNG'.chr(13).chr(10).chr(26).chr(10)) {
9992 $type = 'png';
9993 }
9994 /*-- IMAGES-WMF --*/
9995 else if (substr($data, 0, 4)== chr(215).chr(205).chr(198).chr(154)) {
9996 $type = 'wmf';
9997 }
9998 /*-- END IMAGES-WMF --*/
9999 else if (preg_match('/<svg.*<\/svg>/is',$data)) {
10000 $type = 'svg';
10001 }
10002 // BMP images
10003 else if (substr($data, 0, 2)== "BM") {
10004 $type = 'bmp';
10005 }
10006 return $type;
10007 }
10008 //==============================================================
10009
10010 // Moved outside WMF as also needed for SVG
10011 function _putformobjects() {
10012 reset($this->formobjects);
10013 while(list($file,$info)=each($this->formobjects)) {
10014 $this->_newobj();
10015 $this->formobjects[$file]['n']=$this->n;
10016 $this->_out('<</Type /XObject');
10017 $this->_out('/Subtype /Form');
10018 $this->_out('/Group '.($this->n+1).' 0 R');
10019 $this->_out('/BBox ['.$info['x'].' '.$info['y'].' '.($info['w']+$info['x']).' '.($info['h']+$info['y']).']');
10020 if ($this->compress)
10021 $this->_out('/Filter /FlateDecode');
10022 $data=($this->compress) ? gzcompress($info['data']) : $info['data'];
10023 $this->_out('/Length '.strlen($data).'>>');
10024 $this->_putstream($data);
10025 unset($this->formobjects[$file]['data']);
10026 $this->_out('endobj');
10027 // Required for SVG transparency (opacity) to work
10028 $this->_newobj();
10029 $this->_out('<</Type /Group');
10030 $this->_out('/S /Transparency');
10031 $this->_out('>>');
10032 $this->_out('endobj');
10033 }
10034 }
10035
10036 function _freadint($f)
10037 {
10038 //Read a 4-byte integer from file
10039 $i=ord(fread($f,1))<<24;
10040 $i+=ord(fread($f,1))<<16;
10041 $i+=ord(fread($f,1))<<8;
10042 $i+=ord(fread($f,1));
10043 return $i;
10044 }
10045
10046 function _UTF16BEtextstring($s) {
10047 $s = $this->UTF8ToUTF16BE($s, true);
10048 /*-- ENCRYPTION --*/
10049 if ($this->encrypted) {
10050 $s = $this->_RC4($this->_objectkey($this->_current_obj_id), $s);
10051 }
10052 /*-- END ENCRYPTION --*/
10053 return '('. $this->_escape($s).')';
10054 }
10055
10056 function _textstring($s) {
10057 /*-- ENCRYPTION --*/
10058 if ($this->encrypted) {
10059 $s = $this->_RC4($this->_objectkey($this->_current_obj_id), $s);
10060 }
10061 /*-- END ENCRYPTION --*/
10062 return '('. $this->_escape($s).')';
10063 }
10064
10065
10066 function _escape($s)
10067 {
10068 // the chr(13) substitution fixes the Bugs item #1421290.
10069 return strtr($s, array(')' => '\\)', '(' => '\\(', '\\' => '\\\\', chr(13) => '\r'));
10070 }
10071
10072 function _putstream($s) {
10073 /*-- ENCRYPTION --*/
10074 if ($this->encrypted) {
10075 $s = $this->_RC4($this->_objectkey($this->_current_obj_id), $s);
10076 }
10077 /*-- END ENCRYPTION --*/
10078 $this->_out('stream');
10079 $this->_out($s);
10080 $this->_out('endstream');
10081 }
10082
10083
10084 function _out($s,$ln=true) {
10085 if($this->state==2) {
10086 if ($this->bufferoutput) {
10087 $this->headerbuffer.= $s."\n";
10088 }
10089 /*-- COLUMNS --*/
10090 else if (($this->ColActive) && !$this->processingHeader && !$this->processingFooter) {
10091 // Captures everything in buffer for columns; Almost everything is sent from fn. Cell() except:
10092 // Images sent from Image() or
10093 // later sent as _out($textto) in printbuffer
10094 // Line()
10095 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
10096 $h = ($m[1]/_MPDFK);
10097 // Update/overwrite the lowest bottom of printing y value for a column
10098 $this->ColDetails[$this->CurrCol]['bottom_margin'] = $this->y+$h;
10099 }
10100 /*-- TABLES --*/
10101 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
10102 $h = ($m[1]/_MPDFK);
10103 // Update/overwrite the lowest bottom of printing y value for a column
10104 $this->ColDetails[$this->CurrCol]['bottom_margin'] = max($this->ColDetails[$this->CurrCol]['bottom_margin'],($this->y+$h));
10105 }
10106 /*-- END TABLES --*/
10107 else { // Td Text Set in Cell()
10108 if (isset($this->ColDetails[$this->CurrCol]['bottom_margin'])) { $h = $this->ColDetails[$this->CurrCol]['bottom_margin'] - $this->y; }
10109 else { $h = 0; }
10110 }
10111 if ($h < 0) { $h = -$h; }
10112 $this->columnbuffer[] = array(
10113 's' => $s, // Text string to output
10114 'col' => $this->CurrCol, // Column when printed
10115 'x' => $this->x, // x when printed
10116 'y' => $this->y, // this->y when printed (after column break)
10117 'h' => $h // actual y at bottom when printed = y+h
10118 );
10119 }
10120 /*-- END COLUMNS --*/
10121 /*-- TABLES --*/
10122 else if ($this->table_rotate && !$this->processingHeader && !$this->processingFooter) {
10123 // Captures eveything in buffer for rotated tables;
10124 $this->tablebuffer .= $s . "\n";
10125 }
10126 /*-- END TABLES --*/
10127 else if ($this->kwt && !$this->processingHeader && !$this->processingFooter) {
10128 // Captures eveything in buffer for keep-with-table (h1-6);
10129 $this->kwt_buffer[] = array(
10130 's' => $s, // Text string to output
10131 'x' => $this->x, // x when printed
10132 'y' => $this->y, // y when printed
10133 );
10134 }
10135 else if (($this->keep_block_together) && !$this->processingHeader && !$this->processingFooter) {
10136 if (!isset($this->ktBlock[$this->page]['bottom_margin'])) {
10137 $this->ktBlock[$this->page]['bottom_margin'] = $this->y;
10138 }
10139
10140 // Captures eveything in buffer;
10141 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
10142 $h = ($m[1]/_MPDFK);
10143 // Update/overwrite the lowest bottom of printing y value for Keep together block
10144 $this->ktBlock[$this->page]['bottom_margin'] = $this->y+$h;
10145 }
10146 else { // Td Text Set in Cell()
10147 if (isset($this->ktBlock[$this->page]['bottom_margin'])) { $h = $this->ktBlock[$this->page]['bottom_margin'] - $this->y; }
10148 else { $h = 0; }
10149 }
10150 if ($h < 0) { $h = -$h; }
10151 $this->divbuffer[] = array(
10152 'page' => $this->page,
10153 's' => $s, // Text string to output
10154 'x' => $this->x, // x when printed
10155 'y' => $this->y, // y when printed (after column break)
10156 'h' => $h // actual y at bottom when printed = y+h
10157 );
10158 }
10159 else {
10160 $this->pages[$this->page] .= $s.($ln == true ? "\n" : '');
10161 }
10162
10163 }
10164 else {
10165 $this->buffer .= $s.($ln == true ? "\n" : '');
10166 }
10167 }
10168
10169 /*-- WATERMARK --*/
10170 // add a watermark
10171 function watermark( $texte, $angle=45, $fontsize=96, $alpha=0.2 ) {
10172 if ($this->PDFA || $this->PDFX) { $this->Error('PDFA and PDFX do not permit transparency, so mPDF does not allow Watermarks!'); }
10173 if (!$this->watermark_font) { $this->watermark_font = $this->default_font; }
10174 $this->SetFont( $this->watermark_font, "B", $fontsize, false ); // Don't output
10175 $texte= $this->purify_utf8_text($texte);
10176 if ($this->text_input_as_HTML) {
10177 $texte= $this->all_entities_to_utf8($texte);
10178 }
10179 if ($this->usingCoreFont) { $texte = mb_convert_encoding($texte,$this->mb_enc,'UTF-8'); }
10180 // DIRECTIONALITY
10181 $this->magic_reverse_dir($texte, true, $this->directionality); // *RTL*
10182 // Font-specific ligature substitution for Indic fonts
10183 if (isset($this->CurrentFont['indic']) && $this->CurrentFont['indic']) $this->ConvertIndic($texte); // *INDIC*
10184
10185 $this->SetAlpha($alpha);
10186
10187 $this->SetTColor($this->ConvertColor(0));
10188 $szfont = $fontsize;
10189 $loop = 0;
10190 $maxlen = (min($this->w,$this->h) ); // sets max length of text as 7/8 width/height of page
10191 while ( $loop == 0 )
10192 {
10193 $this->SetFont( $this->watermark_font, "B", $szfont, false ); // Don't output
10194 $offset = ((sin(deg2rad($angle))) * ($szfont/_MPDFK));
10195
10196 $strlen = $this->GetStringWidth($texte);
10197 if ( $strlen > $maxlen - $offset )
10198 $szfont --;
10199 else
10200 $loop ++;
10201 }
10202
10203 $this->SetFont( $this->watermark_font, "B", $szfont-0.1, true, true); // Output The -0.1 is because SetFont above is not written to PDF
10204 // Repeating it will not output anything as mPDF thinks it is set
10205 $adj = ((cos(deg2rad($angle))) * ($strlen/2));
10206 $opp = ((sin(deg2rad($angle))) * ($strlen/2));
10207 $wx = ($this->w/2) - $adj + $offset/3;
10208 $wy = ($this->h/2) + $opp;
10209 $this->Rotate($angle,$wx,$wy);
10210 $this->Text($wx,$wy,$texte);
10211 $this->Rotate(0);
10212 $this->SetTColor($this->ConvertColor(0));
10213
10214 $this->SetAlpha(1);
10215
10216 }
10217
10218 function watermarkImg( $src, $alpha=0.2 ) {
10219 if ($this->PDFA || $this->PDFX) { $this->Error('PDFA and PDFX do not permit transparency, so mPDF does not allow Watermarks!'); }
10220 if ($this->watermarkImgBehind) { $this->watermarkImgAlpha = $this->SetAlpha($alpha, 'Normal', true); }
10221 else { $this->SetAlpha($alpha, $this->watermarkImgAlphaBlend); }
10222 $this->Image($src,0,0,0,0,'','', true, true, true);
10223 if (!$this->watermarkImgBehind) { $this->SetAlpha(1); }
10224 }
10225 /*-- END WATERMARK --*/
10226
10227
10228 function Rotate($angle,$x=-1,$y=-1)
10229 {
10230 if($x==-1)
10231 $x=$this->x;
10232 if($y==-1)
10233 $y=$this->y;
10234 if($this->angle!=0)
10235 $this->_out('Q');
10236 $this->angle=$angle;
10237 if($angle!=0)
10238 {
10239 $angle*=M_PI/180;
10240 $c=cos($angle);
10241 $s=sin($angle);
10242 $cx=$x*_MPDFK;
10243 $cy=($this->h-$y)*_MPDFK;
10244 $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));
10245 }
10246 }
10247
10248
10249
10250 // mPDF 5.3.40 5.3.51 5.3.53
10251 function CircularText($x, $y, $r, $text, $align='top', $fontfamily='', $fontsize=0, $fontstyle='', $kerning=120, $fontwidth=100) {
10252 if (!class_exists('directw', false)) { include(_MPDF_PATH.'classes/directw.php'); }
10253 if (empty($this->directw)) { $this->directw = new directw($this); }
10254 $this->directw->CircularText($x, $y, $r, $text, $align, $fontfamily, $fontsize, $fontstyle, $kerning, $fontwidth);
10255 }
10256
10257
10258 // From Invoice
10259 function RoundedRect($x, $y, $w, $h, $r, $style = '')
10260 {
10261 $hp = $this->h;
10262 if($style=='F')
10263 $op='f';
10264 elseif($style=='FD' or $style=='DF')
10265 $op='B';
10266 else
10267 $op='S';
10268 $MyArc = 4/3 * (sqrt(2) - 1);
10269 $this->_out(sprintf('%.3F %.3F m',($x+$r)*_MPDFK,($hp-$y)*_MPDFK ));
10270 $xc = $x+$w-$r ;
10271 $yc = $y+$r;
10272 $this->_out(sprintf('%.3F %.3F l', $xc*_MPDFK,($hp-$y)*_MPDFK ));
10273
10274 $this->_Arc($xc + $r*$MyArc, $yc - $r, $xc + $r, $yc - $r*$MyArc, $xc + $r, $yc);
10275 $xc = $x+$w-$r ;
10276 $yc = $y+$h-$r;
10277 $this->_out(sprintf('%.3F %.3F l',($x+$w)*_MPDFK,($hp-$yc)*_MPDFK));
10278 $this->_Arc($xc + $r, $yc + $r*$MyArc, $xc + $r*$MyArc, $yc + $r, $xc, $yc + $r);
10279 $xc = $x+$r ;
10280 $yc = $y+$h-$r;
10281 $this->_out(sprintf('%.3F %.3F l',$xc*_MPDFK,($hp-($y+$h))*_MPDFK));
10282 $this->_Arc($xc - $r*$MyArc, $yc + $r, $xc - $r, $yc + $r*$MyArc, $xc - $r, $yc);
10283 $xc = $x+$r ;
10284 $yc = $y+$r;
10285 $this->_out(sprintf('%.3F %.3F l',($x)*_MPDFK,($hp-$yc)*_MPDFK ));
10286 $this->_Arc($xc - $r, $yc - $r*$MyArc, $xc - $r*$MyArc, $yc - $r, $xc, $yc - $r);
10287 $this->_out($op);
10288 }
10289
10290 function _Arc($x1, $y1, $x2, $y2, $x3, $y3)
10291 {
10292 $h = $this->h;
10293 $this->_out(sprintf('%.3F %.3F %.3F %.3F %.3F %.3F c ', $x1*_MPDFK, ($h-$y1)*_MPDFK,
10294 $x2*_MPDFK, ($h-$y2)*_MPDFK, $x3*_MPDFK, ($h-$y3)*_MPDFK));
10295 }
10296
10297
10298
10299
10300 //====================================================
10301
10302
10303
10304 /*-- DIRECTW --*/
10305 function Shaded_box( $text,$font='',$fontstyle='B',$szfont='',$width='70%',$style='DF',$radius=2.5,$fill='#FFFFFF',$color='#000000',$pad=2 ) {
10306 // F (shading - no line),S (line, no shading),DF (both)
10307 if (!class_exists('directw', false)) { include(_MPDF_PATH.'classes/directw.php'); }
10308 if (empty($this->directw)) { $this->directw = new directw($this); }
10309 $this->directw->Shaded_box( $text,$font,$fontstyle,$szfont,$width,$style,$radius,$fill,$color,$pad);
10310 }
10311 /*-- END DIRECTW --*/
10312
10313
10314 function UTF8StringToArray($str, $addSubset=true) {
10315 $out = array();
10316 $len = strlen($str);
10317 for ($i = 0; $i < $len; $i++) {
10318 $uni = -1;
10319 $h = ord($str[$i]);
10320 if ( $h <= 0x7F )
10321 $uni = $h;
10322 elseif ( $h >= 0xC2 ) {
10323 if ( ($h <= 0xDF) && ($i < $len -1) )
10324 $uni = ($h & 0x1F) << 6 | (ord($str[++$i]) & 0x3F);
10325 elseif ( ($h <= 0xEF) && ($i < $len -2) )
10326 $uni = ($h & 0x0F) << 12 | (ord($str[++$i]) & 0x3F) << 6 | (ord($str[++$i]) & 0x3F);
10327 elseif ( ($h <= 0xF4) && ($i < $len -3) )
10328 $uni = ($h & 0x0F) << 18 | (ord($str[++$i]) & 0x3F) << 12 | (ord($str[++$i]) & 0x3F) << 6 | (ord($str[++$i]) & 0x3F);
10329 }
10330 if ($uni >= 0) {
10331 $out[] = $uni;
10332 if ($addSubset && isset($this->CurrentFont['subset'])) {
10333 $this->CurrentFont['subset'][$uni] = $uni;
10334 }
10335 }
10336 }
10337 return $out;
10338 }
10339
10340
10341 //Convert utf-8 string to <HHHHHH> for Font Subsets
10342 function UTF8toSubset($str) {
10343 $ret = '<';
10344 $str = preg_replace('/'.preg_quote($this->aliasNbPg,'/').'/', chr(7), $str );
10345 $str = preg_replace('/'.preg_quote($this->aliasNbPgGp,'/').'/', chr(8), $str );
10346 $unicode = $this->UTF8StringToArray($str);
10347 $orig_fid = $this->CurrentFont['subsetfontids'][0];
10348 $last_fid = $this->CurrentFont['subsetfontids'][0];
10349 foreach($unicode as $c) {
10350 if ($c == 7 || $c == 8) {
10351 if ($orig_fid != $last_fid) {
10352 $ret .= '> Tj /F'.$orig_fid.' '.$this->FontSizePt.' Tf <';
10353 $last_fid = $orig_fid;
10354 }
10355 if ($c == 7) { $ret .= $this->aliasNbPgHex; }
10356 else { $ret .= $this->aliasNbPgGpHex; }
10357 continue;
10358 }
10359 for ($i=0; $i<99; $i++) {
10360 // return c as decimal char
10361 $init = array_search($c, $this->CurrentFont['subsets'][$i]);
10362 if ($init!==false) {
10363 if ($this->CurrentFont['subsetfontids'][$i] != $last_fid) {
10364 $ret .= '> Tj /F'.$this->CurrentFont['subsetfontids'][$i].' '.$this->FontSizePt.' Tf <';
10365 $last_fid = $this->CurrentFont['subsetfontids'][$i];
10366 }
10367 $ret .= sprintf("%02s", strtoupper(dechex($init)));
10368 break;
10369 }
10370 // TrueType embedded SUBSETS
10371 else if (count($this->CurrentFont['subsets'][$i]) < 255) {
10372 $n = count($this->CurrentFont['subsets'][$i]);
10373 $this->CurrentFont['subsets'][$i][$n] = $c;
10374 if ($this->CurrentFont['subsetfontids'][$i] != $last_fid) {
10375 $ret .= '> Tj /F'.$this->CurrentFont['subsetfontids'][$i].' '.$this->FontSizePt.' Tf <';
10376 $last_fid = $this->CurrentFont['subsetfontids'][$i];
10377 }
10378 $ret .= sprintf("%02s", strtoupper(dechex($n)));
10379 break;
10380 }
10381 else if (!isset($this->CurrentFont['subsets'][($i+1)])) {
10382 // TrueType embedded SUBSETS
10383 $this->CurrentFont['subsets'][($i+1)] = array(0=>0);
10384 $new_fid = count($this->fonts)+$this->extraFontSubsets+1;
10385 $this->CurrentFont['subsetfontids'][($i+1)] = $new_fid;
10386 $this->extraFontSubsets++;
10387 }
10388 }
10389 }
10390 $ret .= '>';
10391 if ($last_fid != $orig_fid) {
10392 $ret .= ' Tj /F'.$orig_fid.' '.$this->FontSizePt.' Tf <> ';
10393 }
10394 return $ret;
10395 }
10396
10397
10398 // Converts UTF-8 strings to UTF16-BE.
10399 function UTF8ToUTF16BE($str, $setbom=true) {
10400 if ($this->checkSIP && preg_match("/([\x{20000}-\x{2FFFF}])/u", $str)) {
10401 if (!in_array($this->currentfontfamily, array('gb','big5','sjis','uhc','gbB','big5B','sjisB','uhcB','gbI','big5I','sjisI','uhcI',
10402 'gbBI','big5BI','sjisBI','uhcBI'))) {
10403 $str = preg_replace("/[\x{20000}-\x{2FFFF}]/u", chr(0), $str);
10404 }
10405 }
10406 if ($this->checkSMP && preg_match("/([\x{10000}-\x{1FFFF}])/u", $str )) {
10407 $str = preg_replace("/[\x{10000}-\x{1FFFF}]/u", chr(0), $str );
10408 }
10409 $outstr = ""; // string to be returned
10410 if ($setbom) {
10411 $outstr .= "\xFE\xFF"; // Byte Order Mark (BOM)
10412 }
10413 $outstr .= mb_convert_encoding($str, 'UTF-16BE', 'UTF-8');
10414 return $outstr;
10415 }
10416
10417
10418
10419
10420
10421 // ====================================================
10422 // ====================================================
10423 /*-- CJK-FONTS --*/
10424
10425 // from class PDF_Chinese CJK EXTENSIONS
10426 function AddCIDFont($family,$style,$name,&$cw,$CMap,$registry,$desc)
10427 {
10428 $fontkey=strtolower($family).strtoupper($style);
10429 if(isset($this->fonts[$fontkey]))
10430 $this->Error("Font already added: $family $style");
10431 $i=count($this->fonts)+$this->extraFontSubsets+1;
10432 $name=str_replace(' ','',$name);
10433 if ($family == 'sjis') { $up = -120; } else { $up = -130; }
10434 // ? 'up' and 'ut' do not seem to be referenced anywhere
10435 $this->fonts[$fontkey]=array('i'=>$i,'type'=>'Type0','name'=>$name,'up'=>$up,'ut'=>40,'cw'=>$cw,'CMap'=>$CMap,'registry'=>$registry,'MissingWidth'=>1000,'desc'=>$desc);
10436 }
10437
10438 function AddCJKFont($family) {
10439
10440 if ($this->PDFA || $this->PDFX) {
10441 $this->Error("Adobe CJK fonts cannot be embedded in mPDF (required for PDFA1-b and PDFX/1-a).");
10442 }
10443 if ($family == 'big5') { $this->AddBig5Font(); }
10444 else if ($family == 'gb') { $this->AddGBFont(); }
10445 else if ($family == 'sjis') { $this->AddSJISFont(); }
10446 else if ($family == 'uhc') { $this->AddUHCFont(); }
10447 }
10448
10449 function AddBig5Font()
10450 {
10451 //Add Big5 font with proportional Latin
10452 $family='big5';
10453 $name='MSungStd-Light-Acro';
10454 $cw=$this->Big5_widths;
10455 $CMap='UniCNS-UTF16-H';
10456 $registry=array('ordering'=>'CNS1','supplement'=>4);
10457 $desc = array(
10458 'Ascent' => 880,
10459 'Descent' => -120,
10460 'CapHeight' => 880,
10461 'Flags' => 6,
10462 'FontBBox' => '[-160 -249 1015 1071]',
10463 'ItalicAngle' => 0,
10464 'StemV' => 93,
10465 );
10466 $this->AddCIDFont($family,'',$name,$cw,$CMap,$registry,$desc);
10467 $this->AddCIDFont($family,'B',$name.',Bold',$cw,$CMap,$registry,$desc);
10468 $this->AddCIDFont($family,'I',$name.',Italic',$cw,$CMap,$registry,$desc);
10469 $this->AddCIDFont($family,'BI',$name.',BoldItalic',$cw,$CMap,$registry,$desc);
10470 }
10471
10472
10473 function AddGBFont()
10474 {
10475 //Add GB font with proportional Latin
10476 $family='gb';
10477 $name='STSongStd-Light-Acro';
10478 $cw=$this->GB_widths;
10479 $CMap='UniGB-UTF16-H';
10480 $registry=array('ordering'=>'GB1','supplement'=>4);
10481 $desc = array(
10482 'Ascent' => 752,
10483 'Descent' => -271,
10484 'CapHeight' => 737,
10485 'Flags' => 6,
10486 'FontBBox' => '[-25 -254 1000 880]',
10487 'ItalicAngle' => 0,
10488 'StemV' => 58,
10489 'Style' => '<< /Panose <000000000400000000000000> >>',
10490 );
10491 $this->AddCIDFont($family,'',$name,$cw,$CMap,$registry,$desc);
10492 $this->AddCIDFont($family,'B',$name.',Bold',$cw,$CMap,$registry,$desc);
10493 $this->AddCIDFont($family,'I',$name.',Italic',$cw,$CMap,$registry,$desc);
10494 $this->AddCIDFont($family,'BI',$name.',BoldItalic',$cw,$CMap,$registry,$desc);
10495 }
10496
10497
10498 function AddSJISFont()
10499 {
10500 //Add SJIS font with proportional Latin
10501 $family='sjis';
10502 $name='KozMinPro-Regular-Acro';
10503 $cw=$this->SJIS_widths;
10504 $CMap='UniJIS-UTF16-H';
10505 $registry=array('ordering'=>'Japan1','supplement'=>5);
10506 $desc = array(
10507 'Ascent' => 880,
10508 'Descent' => -120,
10509 'CapHeight' => 740,
10510 'Flags' => 6,
10511 'FontBBox' => '[-195 -272 1110 1075]',
10512 'ItalicAngle' => 0,
10513 'StemV' => 86,
10514 'XHeight' => 502,
10515 );
10516 $this->AddCIDFont($family,'',$name,$cw,$CMap,$registry,$desc);
10517 $this->AddCIDFont($family,'B',$name.',Bold',$cw,$CMap,$registry,$desc);
10518 $this->AddCIDFont($family,'I',$name.',Italic',$cw,$CMap,$registry,$desc);
10519 $this->AddCIDFont($family,'BI',$name.',BoldItalic',$cw,$CMap,$registry,$desc);
10520 }
10521
10522 function AddUHCFont()
10523 {
10524 //Add UHC font with proportional Latin
10525 $family='uhc';
10526 $name='HYSMyeongJoStd-Medium-Acro';
10527 $cw=$this->UHC_widths;
10528 $CMap='UniKS-UTF16-H';
10529 $registry=array('ordering'=>'Korea1','supplement'=>2);
10530 $desc = array(
10531 'Ascent' => 880,
10532 'Descent' => -120,
10533 'CapHeight' => 720,
10534 'Flags' => 6,
10535 'FontBBox' => '[-28 -148 1001 880]',
10536 'ItalicAngle' => 0,
10537 'StemV' => 60,
10538 'Style' => '<< /Panose <000000000600000000000000> >>',
10539 );
10540 $this->AddCIDFont($family,'',$name,$cw,$CMap,$registry,$desc);
10541 $this->AddCIDFont($family,'B',$name.',Bold',$cw,$CMap,$registry,$desc);
10542 $this->AddCIDFont($family,'I',$name.',Italic',$cw,$CMap,$registry,$desc);
10543 $this->AddCIDFont($family,'BI',$name.',BoldItalic',$cw,$CMap,$registry,$desc);
10544 }
10545
10546 /*-- END CJK-FONTS --*/
10547
10548 //////////////////////////////////////////////////////////////////////////////
10549 //////////////////////////////////////////////////////////////////////////////
10550 //////////////////////////////////////////////////////////////////////////////
10551 //////////////////////////////////////////////////////////////////////////////
10552 //////////////////////////////////////////////////////////////////////////////
10553 //////////////////////////////////////////////////////////////////////////////
10554 //////////////////////////////////////////////////////////////////////////////
10555 function SetAutoFont($af = AUTOFONT_ALL) {
10556 if ($this->onlyCoreFonts) { return false; }
10557 if (!$af && $af !== 0) { $af = AUTOFONT_ALL; }
10558 $this->autoFontGroups = $af;
10559 if ($this->autoFontGroups ) {
10560 $this->useLang = true;
10561 }
10562 }
10563
10564
10565 function SetDefaultFont($font) {
10566 // Disallow embedded fonts to be used as defaults in PDFA
10567 if ($this->PDFA || $this->PDFX) {
10568 if (strtolower($font) == 'ctimes') { $font = 'serif'; }
10569 if (strtolower($font) == 'ccourier') { $font = 'monospace'; }
10570 if (strtolower($font) == 'chelvetica') { $font = 'sans-serif'; }
10571 }
10572 $font = $this->SetFont($font); // returns substituted font if necessary
10573 $this->default_font = $font;
10574 $this->original_default_font = $font;
10575 if (!$this->watermark_font ) { $this->watermark_font = $font; } // *WATERMARK*
10576 $this->defaultCSS['BODY']['FONT-FAMILY'] = $font;
10577 $this->CSS['BODY']['FONT-FAMILY'] = $font;
10578 }
10579
10580 function SetDefaultFontSize($fontsize) {
10581 $this->default_font_size = $fontsize;
10582 $this->original_default_font_size = $fontsize;
10583 $this->SetFontSize($fontsize);
10584 $this->defaultCSS['BODY']['FONT-SIZE'] = $fontsize . 'pt';
10585 $this->CSS['BODY']['FONT-SIZE'] = $fontsize . 'pt';
10586 }
10587
10588 function SetDefaultBodyCSS($prop, $val) {
10589 if ($prop) {
10590 $this->defaultCSS['BODY'][strtoupper($prop)] = $val;
10591 $this->CSS['BODY'][strtoupper($prop)] = $val;
10592 }
10593 }
10594
10595
10596 function SetDirectionality($dir='ltr') {
10597 /*-- RTL --*/
10598 if (strtolower($dir) == 'rtl') {
10599 if ($this->directionality != 'rtl') {
10600 // Swop L/R Margins so page 1 RTL is an 'even' page
10601 $tmp = $this->DeflMargin;
10602 $this->DeflMargin = $this->DefrMargin;
10603 $this->DefrMargin = $tmp;
10604 $this->orig_lMargin = $this->DeflMargin;
10605 $this->orig_rMargin = $this->DefrMargin;
10606
10607 $this->SetMargins($this->DeflMargin,$this->DefrMargin,$this->tMargin);
10608 }
10609 $this->directionality = 'rtl';
10610 $this->defaultAlign = 'R';
10611 $this->defaultTableAlign = 'R';
10612 }
10613 else {
10614 /*-- END RTL --*/
10615 $this->directionality = 'ltr';
10616 $this->defaultAlign = 'L';
10617 $this->defaultTableAlign = 'L';
10618 } // *RTL*
10619 $this->CSS['BODY']['DIRECTION'] = $this->directionality;
10620 }
10621
10622
10623
10624 // Added to set line-height-correction
10625 function SetLineHeightCorrection($val) {
10626 if ($val > 0) { $this->default_lineheight_correction = $val; }
10627 else { $this->default_lineheight_correction = 1.2; }
10628 }
10629
10630 // Set a (fixed) lineheight to an actual value - either to named fontsize(pts) or default
10631 function SetLineHeight($FontPt='',$spacing = '') {
10632 if ($this->shrin_k > 1) { $k = $this->shrin_k; }
10633 else { $k = 1; }
10634 if ($spacing > 0) {
10635 if (preg_match('/mm/',$spacing)) {
10636 $this->lineheight = ($spacing + 0.0) / $k; // convert to number
10637 }
10638 else {
10639 if ($FontPt) { $this->lineheight = (($FontPt/_MPDFK) *$spacing); }
10640 else { $this->lineheight = (($this->FontSizePt/_MPDFK) *$spacing); }
10641 }
10642 }
10643 else {
10644 if ($FontPt) { $this->lineheight = (($FontPt/_MPDFK) *$this->normalLineheight); }
10645 else { $this->lineheight = (($this->FontSizePt/_MPDFK) *$this->normalLineheight); }
10646 }
10647 }
10648
10649 function _computeLineheight($lh, $fs='') {
10650 if ($this->shrin_k > 1) { $k = $this->shrin_k; }
10651 else { $k = 1; }
10652 if (!$fs) { $fs = $this->FontSize; }
10653 if (preg_match('/mm/',$lh)) {
10654 return (($lh + 0.0) / $k); // convert to number
10655 }
10656 else if ($lh > 0) {
10657 return ($fs * $lh);
10658 }
10659 else if (isset($this->normalLineheight)) { return ($fs * $this->normalLineheight); }
10660 else return ($fs * $this->default_lineheight_correction);
10661 }
10662
10663
10664 function SetBasePath($str='') {
10665 if ( isset($_SERVER['HTTP_HOST']) ) { $host = $_SERVER['HTTP_HOST']; }
10666 else if ( isset($_SERVER['SERVER_NAME']) ) { $host = $_SERVER['SERVER_NAME']; }
10667 else { $host = ''; }
10668 if (!$str) {
10669 if ($_SERVER['SCRIPT_NAME']) { $currentPath = dirname($_SERVER['SCRIPT_NAME']); }
10670 else { $currentPath = dirname($_SERVER['PHP_SELF']); }
10671 $currentPath = str_replace("\\","/",$currentPath);
10672 if ($currentPath == '/') { $currentPath = ''; }
10673 if ($host) { $currpath = 'http://' . $host . $currentPath .'/'; }
10674 else { $currpath = ''; }
10675 $this->basepath = $currpath;
10676 $this->basepathIsLocal = true;
10677 return;
10678 }
10679 $str = preg_replace('/\?.*/','',$str);
10680 if (!preg_match('/(http|https|ftp):\/\/.*\//i',$str)) { $str .= '/'; }
10681 $str .= 'xxx'; // in case $str ends in / e.g. http://www.bbc.co.uk/
10682 $this->basepath = dirname($str) . "/"; // returns e.g. e.g. http://www.google.com/dir1/dir2/dir3/
10683 $this->basepath = str_replace("\\","/",$this->basepath); //If on Windows
10684 $tr = parse_url($this->basepath);
10685 if (isset($tr['host']) && ($tr['host'] == $host)) { $this->basepathIsLocal = true; }
10686 else { $this->basepathIsLocal = false; }
10687 }
10688
10689
10690 function GetFullPath(&$path,$basepath='') {
10691 // When parsing CSS need to pass temporary basepath - so links are relative to current stylesheet
10692 if (!$basepath) { $basepath = $this->basepath; }
10693 //Fix path value
10694 $path = str_replace("\\","/",$path); //If on Windows
10695 //Get link info and obtain its absolute path
10696 $regexp = '|^./|'; // Inadvertently corrects "./path/etc" and "//www.domain.com/etc"
10697 $path = preg_replace($regexp,'',$path);
10698
10699 if(substr($path,0,1) == '#') { return; }
10700 if (stristr($path,"mailto:") !== false) { return; }
10701 if (strpos($path,"../") !== false ) { //It is a Relative Link
10702 $backtrackamount = substr_count($path,"../");
10703 $maxbacktrack = substr_count($basepath,"/") - 1;
10704 $filepath = str_replace("../",'',$path);
10705 $path = $basepath;
10706 //If it is an invalid relative link, then make it go to directory root
10707 if ($backtrackamount > $maxbacktrack) $backtrackamount = $maxbacktrack;
10708 //Backtrack some directories
10709 for( $i = 0 ; $i < $backtrackamount + 1 ; $i++ ) $path = substr( $path, 0 , strrpos($path,"/") );
10710 $path = $path . "/" . $filepath; //Make it an absolute path
10711 }
10712 else if( strpos($path,":/") === false || strpos($path,":/") > 10) { //It is a Local Link
10713 if (substr($path,0,1) == "/") {
10714 $tr = parse_url($basepath);
10715 $root = $tr['scheme'].'://'.$tr['host'];
10716 $path = $root . $path;
10717 }
10718 else { $path = $basepath . $path; }
10719 }
10720 //Do nothing if it is an Absolute Link
10721 }
10722
10723
10724 // Used for external CSS files
10725 function _get_file($path) {
10726 // If local file try using local path (? quicker, but also allowed even if allow_url_fopen false)
10727 $contents = '';
10728 $contents = @file_get_contents($path);
10729 if ($contents) { return $contents; }
10730 if ($this->basepathIsLocal) {
10731 $tr = parse_url($path);
10732 $lp=getenv("SCRIPT_NAME");
10733 $ap=realpath($lp);
10734 $ap=str_replace("\\","/",$ap);
10735 $docroot=substr($ap,0,strpos($ap,$lp));
10736 // WriteHTML parses all paths to full URLs; may be local file name
10737 if ($tr['scheme'] && $tr['host'] && $_SERVER["DOCUMENT_ROOT"] ) {
10738 $localpath = $_SERVER["DOCUMENT_ROOT"] . $tr['path'];
10739 }
10740 // DOCUMENT_ROOT is not returned on IIS
10741 else if ($docroot) {
10742 $localpath = $docroot . $tr['path'];
10743 }
10744 else { $localpath = $path; }
10745 $contents = @file_get_contents($localpath);
10746 }
10747 // if not use full URL
10748 else if (!$contents && !ini_get('allow_url_fopen') && function_exists("curl_init")) {
10749 $ch = curl_init($path);
10750 curl_setopt($ch, CURLOPT_HEADER, 0);
10751 curl_setopt ( $ch , CURLOPT_RETURNTRANSFER , 1 );
10752 $contents = curl_exec($ch);
10753 curl_close($ch);
10754 }
10755 return $contents;
10756 }
10757
10758
10759 function docPageNum($num = 0, $extras = false) {
10760 if ($num < 1) { $num = $this->page; }
10761 $type = '1'; // set default decimal
10762 $ppgno = $num;
10763 $suppress = 0;
10764 $offset = 0;
10765
10766 $lastreset = 0;
10767 foreach($this->PageNumSubstitutions AS $psarr) {
10768 if ($num >= $psarr['from']) {
10769 if ($psarr['reset']) {
10770 if ($psarr['reset']>1) { $offset = $psarr['reset']-1; }
10771 $ppgno = $num - $psarr['from'] + 1 + $offset;
10772 $lastreset = $psarr['from'];
10773 }
10774 if ($psarr['type']) { $type = $psarr['type']; }
10775 if (strtoupper($psarr['suppress'])=='ON' || $psarr['suppress']==1) { $suppress = 1; }
10776 else if (strtoupper($psarr['suppress'])=='OFF') { $suppress = 0; }
10777 }
10778 }
10779 if ($suppress) { return ''; }
10780
10781 foreach($this->pgsIns AS $k=>$v) {
10782 if ($k>$lastreset && $k<$num) {
10783 $ppgno -= $v;
10784 }
10785 }
10786 if ($type=='A') { $ppgno = $this->dec2alpha($ppgno,true); }
10787 else if ($type=='a') { $ppgno = $this->dec2alpha($ppgno,false);}
10788 else if ($type=='I') { $ppgno = $this->dec2roman($ppgno,true); }
10789 else if ($type=='i') { $ppgno = $this->dec2roman($ppgno,false); }
10790 if ($extras) { $ppgno = $this->pagenumPrefix . $ppgno . $this->pagenumSuffix; }
10791 return $ppgno;
10792 }
10793
10794
10795 function docPageSettings($num = 0) {
10796 // Returns current type (numberstyle), suppression state for this page number;
10797 // reset is only returned if set for this page number
10798 if ($num < 1) { $num = $this->page; }
10799 $type = '1'; // set default decimal
10800 $ppgno = $num;
10801 $suppress = 0;
10802 $offset = 0;
10803 $reset = '';
10804 foreach($this->PageNumSubstitutions AS $psarr) {
10805 if ($num >= $psarr['from']) {
10806 if ($psarr['reset']) {
10807 if ($psarr['reset']>1) { $offset = $psarr['reset']-1; }
10808 $ppgno = $num - $psarr['from'] + 1 + $offset;
10809 }
10810 if ($psarr['type']) { $type = $psarr['type']; }
10811 if (strtoupper($psarr['suppress'])=='ON' || $psarr['suppress']==1) { $suppress = 1; }
10812 else if (strtoupper($psarr['suppress'])=='OFF') { $suppress = 0; }
10813 }
10814 if ($num == $psarr['from']) { $reset = $psarr['reset']; }
10815 }
10816 if ($suppress) { $suppress = 'on'; }
10817 else { $suppress = 'off'; }
10818 return array($type, $suppress, $reset);
10819 }
10820
10821 function docPageNumTotal($num = 0, $extras = false) {
10822 if ($num < 1) { $num = $this->page; }
10823 $type = '1'; // set default decimal
10824 $ppgstart = 1;
10825 $ppgend = count($this->pages)+1;
10826 $suppress = 0;
10827 $offset = 0;
10828 foreach($this->PageNumSubstitutions AS $psarr) {
10829 if ($num >= $psarr['from']) {
10830 if ($psarr['reset']) {
10831 if ($psarr['reset']>1) { $offset = $psarr['reset']-1; }
10832 $ppgstart = $psarr['from'] + $offset;
10833 $ppgend = count($this->pages)+1 + $offset;
10834 }
10835 if ($psarr['type']) { $type = $psarr['type']; }
10836 if (strtoupper($psarr['suppress'])=='ON' || $psarr['suppress']==1) { $suppress = 1; }
10837 else if (strtoupper($psarr['suppress'])=='OFF') { $suppress = 0; }
10838 }
10839 if ($num < $psarr['from']) {
10840 if ($psarr['reset']) {
10841 $ppgend = $psarr['from'] + $offset;
10842 break;
10843 }
10844 }
10845 }
10846 if ($suppress) { return ''; }
10847 $ppgno = $ppgend-$ppgstart+$offset;
10848 if ($extras) { $ppgno = $this->nbpgPrefix . $ppgno . $this->nbpgSuffix; }
10849 return $ppgno;
10850 }
10851
10852 function RestartDocTemplate() {
10853 $this->docTemplateStart = $this->page;
10854 }
10855
10856
10857
10858 //Page header
10859 function Header($content='') {
10860
10861 $this->cMarginL = 0;
10862 $this->cMarginR = 0;
10863
10864
10865 /*-- HTMLHEADERS-FOOTERS --*/
10866 if (($this->mirrorMargins && ($this->page%2==0) && $this->HTMLHeaderE) || ($this->mirrorMargins && ($this->page%2==1) && $this->HTMLHeader) || (!$this->mirrorMargins && $this->HTMLHeader)) {
10867 $this->writeHTMLHeaders();
10868 return;
10869 }
10870 /*-- END HTMLHEADERS-FOOTERS --*/
10871 $this->processingHeader=true;
10872 $h = $this->headerDetails;
10873 if(count($h)) {
10874
10875 if ($this->forcePortraitHeaders && $this->CurOrientation=='L' && $this->CurOrientation!=$this->DefOrientation) {
10876 $this->_out(sprintf('q 0 -1 1 0 0 %.3F cm ',($this->h*_MPDFK)));
10877 $yadj = $this->w - $this->h;
10878 $headerpgwidth = $this->h - $this->orig_lMargin - $this->orig_rMargin;
10879 if (($this->mirrorMargins) && (($this->page)%2==0)) { // EVEN
10880 $headerlmargin = $this->orig_rMargin;
10881 }
10882 else {
10883 $headerlmargin = $this->orig_lMargin;
10884 }
10885 }
10886 else {
10887 $yadj = 0;
10888 $headerpgwidth = $this->pgwidth;
10889 $headerlmargin = $this->lMargin;
10890 }
10891
10892 $this->y = $this->margin_header - $yadj ;
10893 $this->SetTColor($this->ConvertColor(0));
10894 $this->SUP = false;
10895 $this->SUB = false;
10896 $this->bullet = false;
10897
10898 // only show pagenumber if numbering on
10899 $pgno = $this->docPageNum($this->page, true);
10900
10901 if (($this->mirrorMargins) && (($this->page)%2==0)) { // EVEN
10902 $side = 'even';
10903 }
10904 else { // ODD // OR NOT MIRRORING MARGINS/FOOTERS = DEFAULT
10905 $side = 'odd';
10906 }
10907 $maxfontheight = 0;
10908 foreach(array('L','C','R') AS $pos) {
10909 if (isset($h[$side][$pos]['content']) && $h[$side][$pos]['content']) {
10910 if (isset($h[$side][$pos]['font-size']) && $h[$side][$pos]['font-size']) { $hfsz = $h[$side][$pos]['font-size']; }
10911 else { $hfsz = $this->default_font_size; }
10912 $maxfontheight = max($maxfontheight,$hfsz);
10913 }
10914 }
10915 // LEFT-CENTER-RIGHT
10916 foreach(array('L','C','R') AS $pos) {
10917 if (isset($h[$side][$pos]['content']) && $h[$side][$pos]['content']) {
10918 $hd = str_replace('{PAGENO}',$pgno,$h[$side][$pos]['content']);
10919 $hd = str_replace($this->aliasNbPgGp,$this->nbpgPrefix.$this->aliasNbPgGp.$this->nbpgSuffix,$hd);
10920 $hd = preg_replace('/\{DATE\s+(.*?)\}/e',"date('\\1')",$hd);
10921 if (isset($h[$side][$pos]['font-family']) && $h[$side][$pos]['font-family']) { $hff = $h[$side][$pos]['font-family']; }
10922 else { $hff = $this->original_default_font; }
10923 if (isset($h[$side][$pos]['font-size']) && $h[$side][$pos]['font-size']) { $hfsz = $h[$side][$pos]['font-size']; }
10924 else { $hfsz = $this->original_default_font_size; } // pts
10925 $maxfontheight = max($maxfontheight,$hfsz);
10926 $hfst = '';
10927 if (isset($h[$side][$pos]['font-style']) && $h[$side][$pos]['font-style']) {
10928 $hfst = $h[$side][$pos]['font-style'];
10929 }
10930 if (isset($h[$side][$pos]['color']) && $h[$side][$pos]['color']) {
10931 $hfcol = $h[$side][$pos]['color'];
10932 $cor = $this->ConvertColor($hfcol);
10933 if ($cor) { $this->SetTColor($cor); }
10934 }
10935 else { $hfcol = ''; }
10936 $this->SetFont($hff,$hfst,$hfsz,true,true);
10937 $this->x = $headerlmargin ;
10938 $this->y = $this->margin_header - $yadj ;
10939
10940 $hd = $this->purify_utf8_text($hd);
10941 if ($this->text_input_as_HTML) {
10942 $hd = $this->all_entities_to_utf8($hd);
10943 }
10944 // CONVERT CODEPAGE
10945 if ($this->usingCoreFont) { $hd = mb_convert_encoding($hd,$this->mb_enc,'UTF-8'); }
10946 // DIRECTIONALITY RTL
10947 $this->magic_reverse_dir($hd, true, $this->directionality); // *RTL*
10948 // Font-specific ligature substitution for Indic fonts
10949 if (isset($this->CurrentFont['indic']) && $this->CurrentFont['indic']) $this->ConvertIndic($hd); // *INDIC*
10950 $align = $pos;
10951 /*-- RTL --*/
10952 if ($this->directionality == 'rtl') {
10953 if ($pos == 'L') { $align = 'R'; }
10954 else if ($pos == 'R') { $align = 'L'; }
10955 }
10956 /*-- END RTL --*/
10957 if ($pos!='L' && (strpos($hd,$this->aliasNbPg)!==false || strpos($hd,$this->aliasNbPgGp)!==false)) {
10958 if (strpos($hd,$this->aliasNbPgGp)!==false) { $type= 'nbpggp'; } else { $type= 'nbpg'; }
10959 $this->_out('{mpdfheader'.$type.' '.$pos.' ff='.$hff.' fs='.$hfst.' fz='.$hfsz.'}');
10960 $this->Cell($headerpgwidth ,$maxfontheight/_MPDFK ,$hd,0,0,$align,0,'',0,0,0,'M');
10961 $this->_out('Q');
10962 }
10963 else {
10964 $this->Cell($headerpgwidth ,$maxfontheight/_MPDFK ,$hd,0,0,$align,0,'',0,0,0,'M');
10965 }
10966 if ($hfcol) { $this->SetTColor($this->ConvertColor(0)); }
10967 }
10968 }
10969 //Return Font to normal
10970 $this->SetFont($this->default_font,'',$this->original_default_font_size);
10971 // LINE
10972 if (isset($h[$side]['line']) && $h[$side]['line']) {
10973 $this->SetLineWidth(0.1);
10974 $this->SetDColor($this->ConvertColor(0));
10975 $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 );
10976 }
10977 if ($this->forcePortraitHeaders && $this->CurOrientation=='L' && $this->CurOrientation!=$this->DefOrientation) {
10978 $this->_out('Q');
10979 }
10980 }
10981 $this->SetY($this->tMargin);
10982 if ($this->ColActive) { $this->pgwidth = $this->ColWidth; } // *COLUMNS*
10983
10984 $this->processingHeader=false;
10985 }
10986
10987
10988
10989 /*-- TABLES --*/
10990 function TableHeaderFooter($content='',$tablestartpage='',$tablestartcolumn ='',$horf = 'H',$level, $firstSpread=true, $finalSpread=true) { // mPDF 5.3.36
10991 if(($horf=='H' || $horf=='F') && !empty($content)) { // mPDF 5.3.62
10992 $table = &$this->table[1][1];
10993 // Advance down page by half width of top border
10994
10995 if ($horf=='H') { // Only if header
10996 if ($table['borders_separate']) { $adv = $table['border_spacing_V']/2 + $table['border_details']['T']['w'] + $table['padding']['T']; }
10997 else { $adv = $table['max_cell_border_width']['T'] /2 ; }
10998 if ($adv) {
10999 if ($this->table_rotate) {
11000 $this->y += ($adv);
11001 }
11002 else {
11003 $this->DivLn($adv,$this->blklvl,true);
11004 }
11005 }
11006 }
11007
11008 if ($horf=='F') { // Table Footer
11009 $firstrow = count($table['cells']) - $table['footernrows']; // mPDF 5.3.62
11010 $lastrow = count($table['cells']) - 1;
11011 }
11012 else { // Table Header
11013 $firstrow = 0;
11014 $lastrow = $table['headernrows'] - 1; // mPDF 5.3.62
11015 }
11016
11017 $topy = $content[$firstrow][0]['y']-$this->y;
11018
11019 for ($i=$firstrow ; $i<=$lastrow; $i++) {
11020
11021 $y = $this->y;
11022
11023 /*-- COLUMNS --*/
11024 // If outside columns, this is done in PaintDivBB
11025 if ($this->ColActive) {
11026 //OUTER FILL BGCOLOR of DIVS
11027 if ($this->blklvl > 0) {
11028 $firstblockfill = $this->GetFirstBlockFill();
11029 if ($firstblockfill && $this->blklvl >= $firstblockfill) {
11030 $divh = $content[$i][0]['h'];
11031 $bak_x = $this->x;
11032 $this->DivLn($divh,-3,false);
11033 // Reset current block fill
11034 $bcor = $this->blk[$this->blklvl]['bgcolorarray'];
11035 $this->SetFColor($bcor);
11036 $this->x = $bak_x;
11037 }
11038 }
11039 }
11040 /*-- END COLUMNS --*/
11041
11042 $colctr = 0;
11043 foreach($content[$i] as $tablehf) {
11044 $colctr++;
11045 $y = $tablehf['y'] - $topy;
11046 $this->y = $y;
11047 //Set some cell values
11048 $x = $tablehf['x'];
11049 if (($this->mirrorMargins) && ($tablestartpage == 'ODD') && (($this->page)%2==0)) { // EVEN
11050 $x = $x +$this->MarginCorrection;
11051 }
11052 else if (($this->mirrorMargins) && ($tablestartpage == 'EVEN') && (($this->page)%2==1)) { // ODD
11053 $x = $x +$this->MarginCorrection;
11054 }
11055 /*-- COLUMNS --*/
11056 // Added to correct for Columns
11057 if ($this->ColActive) {
11058 if ($this->directionality == 'rtl') { // *RTL*
11059 $x -= ($this->CurrCol - $tablestartcolumn) * ($this->ColWidth+$this->ColGap); // *RTL*
11060 } // *RTL*
11061 else { // *RTL*
11062 $x += ($this->CurrCol - $tablestartcolumn) * ($this->ColWidth+$this->ColGap);
11063 } // *RTL*
11064 }
11065 /*-- END COLUMNS --*/
11066
11067 if ($colctr==1) { $x0 = $x; }
11068
11069 // mPDF ITERATION
11070 if ($this->iterationCounter) {
11071 foreach($tablehf['textbuffer'] AS $k=>$t) { // mPDF 5.3.78
11072 if (preg_match('/{iteration ([a-zA-Z0-9_]+)}/',$t, $m)) {
11073 $vname = '__'.$m[1].'_';
11074 if (!isset($this->$vname)) { $this->$vname = 1; }
11075 else { $this->$vname++; }
11076 $tablehf['textbuffer'][$k][0] = preg_replace('/{iteration '.$m[1].'}/', $this->$vname, $tablehf['textbuffer'][$k][0]);
11077 }
11078 }
11079 }
11080
11081
11082 $w = $tablehf['w'];
11083 $h = $tablehf['h'];
11084 $va = $tablehf['va'];
11085 $R = $tablehf['R'];
11086 $mih = $tablehf['mih'];
11087 $border = $tablehf['border'];
11088 $border_details = $tablehf['border_details'];
11089 $padding = $tablehf['padding'];
11090 $this->tabletheadjustfinished = true;
11091
11092 $textbuffer = $tablehf['textbuffer'];
11093
11094 $align = $tablehf['a'];
11095 //Align
11096 $this->divalign=$align;
11097 $this->x = $x;
11098
11099 if ($this->ColActive) {
11100 if ($table['borders_separate']) {
11101 $tablefill = isset($table['bgcolor'][-1]) ? $table['bgcolor'][-1] : 0;
11102 if ($tablefill) {
11103 $color = $this->ConvertColor($tablefill);
11104 if ($color) {
11105 $xadj = ($table['border_spacing_H']/2);
11106 $yadj = ($table['border_spacing_V']/2);
11107 $wadj = $table['border_spacing_H'];
11108 $hadj = $table['border_spacing_V'];
11109 if ($i == $firstrow && $horf=='H') { // Top
11110 $yadj += $table['padding']['T'] + $table['border_details']['T']['w'] ;
11111 $hadj += $table['padding']['T'] + $table['border_details']['T']['w'] ;
11112 }
11113 if (($i == ($lastrow) || (isset($tablehf['rowspan']) && ($i+$tablehf['rowspan']) == ($lastrow+1)) || (!isset($tablehf['rowspan']) && ($i+1) == ($lastrow+1))) && $horf=='F') { // Bottom
11114 $hadj += $table['padding']['B'] + $table['border_details']['B']['w'] ;
11115 }
11116 if ($colctr == 1) { // Left
11117 $xadj += $table['padding']['L'] + $table['border_details']['L']['w'] ;
11118 $wadj += $table['padding']['L'] + $table['border_details']['L']['w'] ;
11119 }
11120 if ($colctr == count($content[$i]) ) { // Right
11121 $wadj += $table['padding']['R'] + $table['border_details']['R']['w'] ;
11122 }
11123 $this->SetFColor($color);
11124 $this->Rect($x - $xadj, $y - $yadj, $w + $wadj, $h + $hadj, 'F');
11125 }
11126 }
11127 }
11128 }
11129
11130 if ($table['empty_cells']!='hide' || !empty($textbuffer) || !$table['borders_separate']) { $paintcell = true; }
11131 else { $paintcell = false; }
11132
11133 //Vertical align
11134 if ($R && INTVAL($R) > 0 && isset($va) && $va!='B') { $va='B';}
11135
11136 if (!isset($va) || empty($va) || $va=='M') $this->y += ($h-$mih)/2;
11137 elseif (isset($va) && $va=='B') $this->y += $h-$mih;
11138
11139
11140 //TABLE ROW OR CELL FILL BGCOLOR
11141 $fill = 0;
11142 if (isset($tablehf['bgcolor']) && $tablehf['bgcolor'] && $tablehf['bgcolor']!='transparent') {
11143 $fill = $tablehf['bgcolor'];
11144 $leveladj = 6;
11145 }
11146 else if (isset($content[$i][0]['trbgcolor']) && $content[$i][0]['trbgcolor'] && $content[$i][0]['trbgcolor']!='transparent') { // Row color
11147 $fill = $content[$i][0]['trbgcolor'];
11148 $leveladj = 3;
11149 }
11150 if ($fill && $paintcell) {
11151 $color = $this->ConvertColor($fill);
11152 if ($color) {
11153 if ($table['borders_separate']) {
11154 if ($this->ColActive) {
11155 $this->SetFColor($color);
11156 $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');
11157 }
11158 else {
11159 $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);
11160 }
11161 }
11162 else {
11163 if ($this->ColActive) {
11164 $this->SetFColor($color);
11165 $this->Rect($x, $y, $w, $h, 'F');
11166 }
11167 else {
11168 $this->tableBackgrounds[$level*9+$leveladj][] = array('gradient'=>false, 'x'=>$x, 'y'=>$y, 'w'=>$w, 'h'=>$h, 'col'=>$color);
11169 }
11170 }
11171 }
11172 }
11173
11174
11175 /*-- BACKGROUNDS --*/
11176 if (isset($tablehf['gradient']) && $tablehf['gradient'] && $paintcell){
11177 $g = $this->grad->parseBackgroundGradient($tablehf['gradient']);
11178 if ($g) {
11179 if ($table['borders_separate']) {
11180 $px = $x+ ($table['border_spacing_H']/2);
11181 $py = $y+ ($table['border_spacing_V']/2);
11182 $pw = $w- $table['border_spacing_H'];
11183 $ph = $h- $table['border_spacing_V'];
11184 }
11185 else {
11186 $px = $x;
11187 $py = $y;
11188 $pw = $w;
11189 $ph = $h;
11190 }
11191 if ($this->ColActive) {
11192 $this->grad->Gradient($px, $py, $pw, $ph, $g['type'], $g['stops'], $g['colorspace'], $g['coords'], $g['extend']);
11193 }
11194 else {
11195 $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'=>'');
11196 }
11197 }
11198 }
11199
11200 if (isset($tablehf['background-image']) && $paintcell){
11201 if ($tablehf['background-image']['gradient'] && preg_match('/(-moz-)*(repeating-)*(linear|radial)-gradient/', $tablehf['background-image']['gradient'] )) {
11202 $g = $this->grad->parseMozGradient( $tablehf['background-image']['gradient'] );
11203 if ($g) {
11204 if ($table['borders_separate']) {
11205 $px = $x+ ($table['border_spacing_H']/2);
11206 $py = $y+ ($table['border_spacing_V']/2);
11207 $pw = $w- $table['border_spacing_H'];
11208 $ph = $h- $table['border_spacing_V'];
11209 }
11210 else {
11211 $px = $x;
11212 $py = $y;
11213 $pw = $w;
11214 $ph = $h;
11215 }
11216 if ($this->ColActive) {
11217 $this->grad->Gradient($px, $py, $pw, $ph, $g['type'], $g['stops'], $g['colorspace'], $g['coords'], $g['extend']);
11218 }
11219 else {
11220 $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'=>'');
11221 }
11222 }
11223 }
11224 else if ($tablehf['background-image']['image_id']) { // Background pattern
11225 $n = count($this->patterns)+1;
11226 if ($table['borders_separate']) {
11227 $px = $x+ ($table['border_spacing_H']/2);
11228 $py = $y+ ($table['border_spacing_V']/2);
11229 $pw = $w- $table['border_spacing_H'];
11230 $ph = $h- $table['border_spacing_V'];
11231 }
11232 else {
11233 $px = $x;
11234 $py = $y;
11235 $pw = $w;
11236 $ph = $h;
11237 }
11238 if ($this->ColActive) {
11239 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']);
11240 $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']);
11241 if ($tablehf['background-image']['opacity']>0 && $tablehf['background-image']['opacity']<1) { $opac = $this->SetAlpha($tablehf['background-image']['opacity'],'Normal',true); }
11242 else { $opac = ''; }
11243 $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));
11244 }
11245 else { // mPDF 5.3.99
11246 $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']);
11247 }
11248 }
11249 }
11250 /*-- END BACKGROUNDS --*/
11251
11252 //Cell Border
11253 if ($table['borders_separate'] && $paintcell && $border) {
11254 $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']);
11255 }
11256 else if ($paintcell && $border) {
11257 $this->_tableRect($x, $y, $w, $h, $border, $border_details, true, $table['borders_separate']); // true causes buffer
11258 }
11259
11260 //Print cell content
11261 //$this->divheight = $this->table_lineheight*$this->lineheight;
11262 if (!empty($textbuffer)) {
11263 if ($horf=='F' && preg_match('/{colsum([0-9]*)[_]*}/', $textbuffer[0][0], $m)) { // mPDF 5.3.92
11264 $rep = sprintf("%01.".intval($m[1])."f", $this->colsums[$colctr-1]);
11265 $textbuffer[0][0] = preg_replace('/{colsum[0-9_]*}/', $rep ,$textbuffer[0][0]);
11266 }
11267
11268 if ($R) {
11269 $cellPtSize = $textbuffer[0][11] / $this->shrin_k;
11270 if (!$cellPtSize) { $cellPtSize = $this->default_font_size; }
11271 $cellFontHeight = ($cellPtSize/_MPDFK);
11272 $opx = $this->x;
11273 $opy = $this->y;
11274 $angle = INTVAL($R);
11275 // Only allow 45 - 90 degrees (when bottom-aligned) or -90
11276 if ($angle > 90) { $angle = 90; }
11277 else if ($angle > 0 && (isset($va) && $va!='B')) { $angle = 90; }
11278 else if ($angle > 0 && $angle <45) { $angle = 45; }
11279 else if ($angle < 0) { $angle = -90; }
11280 $offset = ((sin(deg2rad($angle))) * 0.37 * $cellFontHeight);
11281 if (isset($align) && $align =='R') {
11282 $this->x += ($w) + ($offset) - ($cellFontHeight/3) - ($padding['R'] + $border_details['R']['w']);
11283 }
11284 else if (!isset($align ) || $align =='C') {
11285 $this->x += ($w/2) + ($offset);
11286 }
11287 else {
11288 $this->x += ($offset) + ($cellFontHeight/3)+($padding['L'] + $border_details['L']['w']);
11289 }
11290 // mPDF 5.3.78
11291 $str = '';
11292 foreach($tablehf['textbuffer'] AS $t) { $str .= $t[0].' '; }
11293 $str = trim($str);
11294
11295 if (!isset($va) || $va=='M') {
11296 $this->y -= ($h-$mih)/2; //Undo what was added earlier VERTICAL ALIGN
11297 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'])); }
11298 else if ($angle < 0) { $this->y += (($h-$mih)/2)+($padding['T'] + $border_details['T']['w']); }
11299 }
11300 else if (isset($va) && $va=='B') {
11301 $this->y -= $h-$mih; //Undo what was added earlier VERTICAL ALIGN
11302 if ($angle > 0) { $this->y += $h-($border_details['B']['w']+$padding['B']); }
11303 else if ($angle < 0) { $this->y += $h-$mih+($padding['T'] + $border_details['T']['w']); }
11304 }
11305 else if (isset($va) && $va=='T') {
11306 if ($angle > 0) { $this->y += $mih-($border_details['B']['w']+$padding['B']); }
11307 else if ($angle < 0) { $this->y += ($padding['T'] + $border_details['T']['w']); }
11308 }
11309
11310 $this->Rotate($angle,$this->x,$this->y);
11311 $s_fs = $this->FontSizePt;
11312 $s_f = $this->FontFamily;
11313 $s_st = $this->FontStyle;
11314 // mPDF 5.3.54
11315 if (!empty($textbuffer[0][3])) { //Font Color
11316 $cor = $textbuffer[0][3];
11317 $this->SetTColor($cor);
11318 }
11319 $s_str = $this->strike;
11320 $this->strike = $textbuffer[0][8]; //Strikethrough
11321 $this->SetFont($textbuffer[0][4],$textbuffer[0][2],$cellPtSize,true,true);
11322 $this->Text($this->x,$this->y,$str);
11323 $this->Rotate(0);
11324 $this->SetFont($s_f,$s_st,$s_fs,true,true);
11325 $this->SetTColor(0); // mPDF 5.3.54
11326 $this->strike = $s_str; // mPDF 5.3.54
11327 $this->x = $opx;
11328 $this->y = $opy;
11329 }
11330 else {
11331 if ($table['borders_separate']) { // NB twice border width
11332 $xadj = $border_details['L']['w'] + $padding['L'] +($table['border_spacing_H']/2);
11333 $wadj = $border_details['L']['w'] + $border_details['R']['w'] + $padding['L'] +$padding['R'] + $table['border_spacing_H'];
11334 $yadj = $border_details['T']['w'] + $padding['T'] + ($table['border_spacing_H']/2);
11335 }
11336 else {
11337 $xadj = $border_details['L']['w']/2 + $padding['L'];
11338 $wadj = ($border_details['L']['w'] + $border_details['R']['w'])/2 + $padding['L'] + $padding['R'];
11339 $yadj = $border_details['T']['w']/2 + $padding['T'];
11340 }
11341
11342 $this->divwidth=$w-($wadj);
11343 $this->x += $xadj;
11344 $this->y += $yadj;
11345 $this->printbuffer($textbuffer,'',true);
11346 }
11347
11348 }
11349 $textbuffer = array();
11350
11351 /*-- BACKGROUNDS --*/
11352 if (!$this->ColActive) {
11353 if (isset($content[$i][0]['trgradients']) && ($colctr==1 || $table['borders_separate'])) {
11354 $g = $this->grad->parseBackgroundGradient($content[$i][0]['trgradients']);
11355 if ($g) {
11356 $gx = $x0;
11357 $gy = $y;
11358 $gh = $h;
11359 $gw = $table['w'] - ($table['max_cell_border_width']['L']/2) - ($table['max_cell_border_width']['R']/2) - $table['margin']['L'] - $table['margin']['R'];
11360 if ($table['borders_separate']) {
11361 $gw -= ($table['padding']['L'] + $table['border_details']['L']['w'] + $table['padding']['R'] + $table['border_details']['R']['w'] + $table['border_spacing_H']);
11362 $s = '';
11363 $clx = $x+ ($table['border_spacing_H']/2);
11364 $cly = $y+ ($table['border_spacing_V']/2);
11365 $clw = $w- $table['border_spacing_H'];
11366 $clh = $h- $table['border_spacing_V'];
11367 // Set clipping path
11368 $s = ' q 0 w '; // Line width=0
11369 $s .= sprintf('%.3F %.3F m ', ($clx)*_MPDFK, ($this->h-($cly))*_MPDFK); // start point TL before the arc
11370 $s .= sprintf('%.3F %.3F l ', ($clx)*_MPDFK, ($this->h-($cly+$clh))*_MPDFK); // line to BL
11371 $s .= sprintf('%.3F %.3F l ', ($clx+$clw)*_MPDFK, ($this->h-($cly+$clh))*_MPDFK); // line to BR
11372 $s .= sprintf('%.3F %.3F l ', ($clx+$clw)*_MPDFK, ($this->h-($cly))*_MPDFK); // line to TR
11373 $s .= sprintf('%.3F %.3F l ', ($clx)*_MPDFK, ($this->h-($cly))*_MPDFK); // line to TL
11374 $s .= ' W n '; // Ends path no-op & Sets the clipping path
11375 $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);
11376 }
11377 else {
11378 $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'=>'');
11379 }
11380 }
11381 }
11382
11383 if (isset($content[$i][0]['trbackground-images']) && ($colctr==1 || $table['borders_separate'])) {
11384 if ($content[$i][0]['trbackground-images']['gradient'] && preg_match('/(-moz-)*(repeating-)*(linear|radial)-gradient/', $content[$i][0]['trbackground-images']['gradient'] )) {
11385 $g = $this->grad->parseMozGradient( $content[$i][0]['trbackground-images']['gradient'] );
11386 if ($g) {
11387 $gx = $x0;
11388 $gy = $y;
11389 $gh = $h;
11390 $gw = $table['w'] - ($table['max_cell_border_width']['L']/2) - ($table['max_cell_border_width']['R']/2) - $table['margin']['L'] - $table['margin']['R'];
11391 if ($table['borders_separate']) {
11392 $gw -= ($table['padding']['L'] + $table['border_details']['L']['w'] + $table['padding']['R'] + $table['border_details']['R']['w'] + $table['border_spacing_H']);
11393 $s = '';
11394 $clx = $x+ ($table['border_spacing_H']/2);
11395 $cly = $y+ ($table['border_spacing_V']/2);
11396 $clw = $w- $table['border_spacing_H'];
11397 $clh = $h- $table['border_spacing_V'];
11398 // Set clipping path
11399 $s = ' q 0 w '; // Line width=0
11400 $s .= sprintf('%.3F %.3F m ', ($clx)*_MPDFK, ($this->h-($cly))*_MPDFK); // start point TL before the arc
11401 $s .= sprintf('%.3F %.3F l ', ($clx)*_MPDFK, ($this->h-($cly+$clh))*_MPDFK); // line to BL
11402 $s .= sprintf('%.3F %.3F l ', ($clx+$clw)*_MPDFK, ($this->h-($cly+$clh))*_MPDFK); // line to BR
11403 $s .= sprintf('%.3F %.3F l ', ($clx+$clw)*_MPDFK, ($this->h-($cly))*_MPDFK); // line to TR
11404 $s .= sprintf('%.3F %.3F l ', ($clx)*_MPDFK, ($this->h-($cly))*_MPDFK); // line to TL
11405 $s .= ' W n '; // Ends path no-op & Sets the clipping path
11406 $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);
11407 }
11408 else {
11409 $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'=>'');
11410 }
11411 }
11412 }
11413 else {
11414 $image_id = $content[$i][0]['trbackground-images']['image_id'];
11415 $orig_w = $content[$i][0]['trbackground-images']['orig_w'];
11416 $orig_h = $content[$i][0]['trbackground-images']['orig_h'];
11417 $x_pos = $content[$i][0]['trbackground-images']['x_pos'];
11418 $y_pos = $content[$i][0]['trbackground-images']['y_pos'];
11419 $x_repeat = $content[$i][0]['trbackground-images']['x_repeat'];
11420 $y_repeat = $content[$i][0]['trbackground-images']['y_repeat'];
11421 $resize = $content[$i][0]['trbackground-images']['resize'];
11422 $opacity = $content[$i][0]['trbackground-images']['opacity'];
11423 $itype = $content[$i][0]['trbackground-images']['itype']; // mPDF 5.3.99
11424
11425 $clippath = '';
11426 $gx = $x0;
11427 $gy = $y;
11428 $gh = $h;
11429 $gw = $table['w'] - ($table['max_cell_border_width']['L']/2) - ($table['max_cell_border_width']['R']/2) - $table['margin']['L'] - $table['margin']['R'];
11430 if ($table['borders_separate']) {
11431 $gw -= ($table['padding']['L'] + $table['border_details']['L']['w'] + $table['padding']['R'] + $table['border_details']['R']['w'] + $table['border_spacing_H']);
11432 $s = '';
11433 $clx = $x+ ($table['border_spacing_H']/2);
11434 $cly = $y+ ($table['border_spacing_V']/2);
11435 $clw = $w- $table['border_spacing_H'];
11436 $clh = $h- $table['border_spacing_V'];
11437 // Set clipping path
11438 $s = ' q 0 w '; // Line width=0
11439 $s .= sprintf('%.3F %.3F m ', ($clx)*_MPDFK, ($this->h-($cly))*_MPDFK); // start point TL before the arc
11440 $s .= sprintf('%.3F %.3F l ', ($clx)*_MPDFK, ($this->h-($cly+$clh))*_MPDFK); // line to BL
11441 $s .= sprintf('%.3F %.3F l ', ($clx+$clw)*_MPDFK, ($this->h-($cly+$clh))*_MPDFK); // line to BR
11442 $s .= sprintf('%.3F %.3F l ', ($clx+$clw)*_MPDFK, ($this->h-($cly))*_MPDFK); // line to TR
11443 $s .= sprintf('%.3F %.3F l ', ($clx)*_MPDFK, ($this->h-($cly))*_MPDFK); // line to TL
11444 $s .= ' W n '; // Ends path no-op & Sets the clipping path
11445 $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);
11446 }
11447 else {
11448 $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);
11449 }
11450 }
11451 }
11452 }
11453 /*-- END BACKGROUNDS --*/
11454
11455 // TABLE BORDER - if separate OR collapsed and only table border
11456 // mPDF 5.3.15
11457 if (($table['borders_separate'] || ($this->simpleTables && !$table['simple']['border'])) && $table['border']) {
11458 $halfspaceL = $table['padding']['L'] + ($table['border_spacing_H']/2);
11459 $halfspaceR = $table['padding']['R'] + ($table['border_spacing_H']/2);
11460 $halfspaceT = $table['padding']['T'] + ($table['border_spacing_V']/2);
11461 $halfspaceB = $table['padding']['B'] + ($table['border_spacing_V']/2);
11462 $tbx = $x;
11463 $tby = $y;
11464 $tbw = $w;
11465 $tbh = $h;
11466 $tab_bord = 0;
11467 $corner = '';
11468 if ($i == $firstrow && $horf=='H') { // Top
11469 $tby -= $halfspaceT + ($table['border_details']['T']['w']/2);
11470 $tbh += $halfspaceT + ($table['border_details']['T']['w']/2);
11471 $this->setBorder($tab_bord , _BORDER_TOP);
11472 $corner .= 'T';
11473 }
11474 // mPDF 5.3.15
11475 if (($i == ($lastrow) || (isset($tablehf['rowspan']) && ($i+$tablehf['rowspan']) == ($lastrow+1))) && $horf=='F') { // Bottom
11476 $tbh += $halfspaceB + ($table['border_details']['B']['w']/2);
11477 $this->setBorder($tab_bord , _BORDER_BOTTOM);
11478 $corner .= 'B';
11479 }
11480 if ($colctr == 1 && $firstSpread) { // Left // mPDF 5.3.36
11481 $tbx -= $halfspaceL + ($table['border_details']['L']['w']/2);
11482 $tbw += $halfspaceL + ($table['border_details']['L']['w']/2);
11483 $this->setBorder($tab_bord , _BORDER_LEFT);
11484 $corner .= 'L';
11485 }
11486 if ($colctr == count($content[$i]) && $finalSpread) { // Right // mPDF 5.3.36
11487 $tbw += $halfspaceR + ($table['border_details']['R']['w']/2);
11488 $this->setBorder($tab_bord , _BORDER_RIGHT);
11489 $corner .= 'R';
11490 }
11491 $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'] );
11492 }
11493
11494
11495 }// end column $content
11496 $this->y = $y + $h; //Update y coordinate
11497 }// end row $i
11498 unset($table );
11499 $this->colsums = array(); // mPDF 5.3.92
11500 }
11501 }
11502 /*-- END TABLES --*/
11503
11504 /*-- HTMLHEADERS-FOOTERS --*/
11505 function SetHTMLHeader($header='',$OE='',$write=false) {
11506
11507 $height = 0;
11508 if (is_array($header) && isset($header['html']) && $header['html']) {
11509 $Hhtml = $header['html'];
11510 if ($this->setAutoTopMargin) {
11511 if (isset($header['h'])) { $height = $header['h']; }
11512 else { $height = $this->_gethtmlheight($Hhtml); }
11513 }
11514 }
11515 else if (!is_array($header) && $header) {
11516 $Hhtml = $header;
11517 if ($this->setAutoTopMargin) { $height = $this->_gethtmlheight($Hhtml); }
11518 }
11519 else { $Hhtml = ''; }
11520
11521 if ($OE != 'E') { $OE = 'O'; }
11522 if ($OE == 'E') {
11523
11524 if ($Hhtml) {
11525 $this->HTMLHeaderE['html'] = $Hhtml;
11526 $this->HTMLHeaderE['h'] = $height;
11527 }
11528 else { $this->HTMLHeaderE = ''; }
11529 }
11530 else {
11531
11532 if ($Hhtml) {
11533 $this->HTMLHeader['html'] = $Hhtml;
11534 $this->HTMLHeader['h'] = $height;
11535 }
11536 else { $this->HTMLHeader = ''; }
11537 }
11538 if (!$this->mirrorMargins && $OE == 'E') { return; }
11539 if ($Hhtml=='') { return; }
11540 if ($OE == 'E') {
11541 $this->headerDetails['even'] = array(); // override and clear any other non-HTML header/footer
11542 }
11543 else {
11544 $this->headerDetails['odd'] = array(); // override and clear any non-HTML other header/footer
11545 }
11546
11547 if ($this->setAutoTopMargin=='pad') {
11548 $this->tMargin = $this->margin_header + $height + $this->orig_tMargin;
11549 if (isset($this->saveHTMLHeader[$this->page][$OE]['mt'])) { $this->saveHTMLHeader[$this->page][$OE]['mt'] = $this->tMargin; }
11550 }
11551 else if ($this->setAutoTopMargin=='stretch') {
11552 $this->tMargin = max($this->orig_tMargin, $this->margin_header + $height + $this->autoMarginPadding);
11553 if (isset($this->saveHTMLHeader[$this->page][$OE]['mt'])) { $this->saveHTMLHeader[$this->page][$OE]['mt'] = $this->tMargin; }
11554 }
11555 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(); }
11556 }
11557
11558 function SetHTMLFooter($footer='',$OE='') {
11559
11560 $height = 0;
11561 if (is_array($footer) && isset($footer['html']) && $footer['html']) {
11562 $Fhtml = $footer['html'];
11563 if ($this->setAutoBottomMargin) {
11564 if (isset($footer['h'])) { $height = $footer['h']; }
11565 else { $height = $this->_gethtmlheight($Fhtml); }
11566 }
11567 }
11568 else if (!is_array($footer) && $footer) {
11569 $Fhtml = $footer;
11570 if ($this->setAutoBottomMargin) { $height = $this->_gethtmlheight($Fhtml); }
11571 }
11572 else { $Fhtml = ''; }
11573
11574 if ($OE != 'E') { $OE = 'O'; }
11575 if ($OE == 'E') {
11576
11577 if ($Fhtml) {
11578 $this->HTMLFooterE['html'] = $Fhtml;
11579 $this->HTMLFooterE['h'] = $height;
11580 }
11581 else { $this->HTMLFooterE = ''; }
11582 }
11583 else {
11584
11585 if ($Fhtml) {
11586 $this->HTMLFooter['html'] = $Fhtml;
11587 $this->HTMLFooter['h'] = $height;
11588 }
11589 else { $this->HTMLFooter = ''; }
11590 }
11591 if (!$this->mirrorMargins && $OE == 'E') { return; }
11592 if ($Fhtml=='') { return false; }
11593 if ($OE == 'E') {
11594 $this->footerDetails['even'] = array(); // override and clear any other header/footer
11595 }
11596 else {
11597 $this->footerDetails['odd'] = array(); // override and clear any other header/footer
11598 }
11599
11600 if ($this->setAutoBottomMargin=='pad') {
11601 $this->bMargin = $this->margin_footer + $height + $this->orig_bMargin;
11602 $this->PageBreakTrigger=$this->h-$this->bMargin ;
11603 if (isset($this->saveHTMLHeader[$this->page][$OE]['mb'])) { $this->saveHTMLHeader[$this->page][$OE]['mb'] = $this->bMargin; }
11604 }
11605 else if ($this->setAutoBottomMargin=='stretch') {
11606 $this->bMargin = max($this->orig_bMargin, $this->margin_footer + $height + $this->autoMarginPadding);
11607 $this->PageBreakTrigger=$this->h-$this->bMargin ;
11608 if (isset($this->saveHTMLHeader[$this->page][$OE]['mb'])) { $this->saveHTMLHeader[$this->page][$OE]['mb'] = $this->bMargin; }
11609 }
11610 }
11611
11612
11613 function _getHtmlHeight($html) {
11614 $save_state = $this->state;
11615 if($this->state==0) {
11616 $this->AddPage($this->CurOrientation);
11617 }
11618 $this->state = 2;
11619 $this->Reset();
11620 $this->pageoutput[$this->page] = array();
11621 $save_x = $this->x;
11622 $save_y = $this->y;
11623 $this->x = $this->lMargin;
11624 $this->y = $this->margin_header;
11625 $html = str_replace('{PAGENO}',$this->pagenumPrefix.$this->docPageNum($this->page).$this->pagenumSuffix,$html);
11626 $html = str_replace($this->aliasNbPgGp,$this->nbpgPrefix.$this->docPageNumTotal($this->page).$this->nbpgSuffix,$html );
11627 $html = str_replace($this->aliasNbPg,$this->page,$html );
11628 $html = preg_replace('/\{DATE\s+(.*?)\}/e',"date('\\1')",$html );
11629 $this->HTMLheaderPageLinks = array();
11630 $this->HTMLheaderPageAnnots = array();
11631 $this->HTMLheaderPageForms = array();
11632 $savepb = $this->pageBackgrounds;
11633 $this->writingHTMLheader = true;
11634 $this->WriteHTML($html , 4); // parameter 4 saves output to $this->headerbuffer
11635 $this->writingHTMLheader = false;
11636 $h = ($this->y - $this->margin_header);
11637 $this->Reset();
11638 $this->pageoutput[$this->page] = array();
11639 $this->headerbuffer = '';
11640 $this->pageBackgrounds = $savepb;
11641 $this->x = $save_x;
11642 $this->y = $save_y;
11643 $this->state = $save_state;
11644 if($save_state==0) {
11645 unset($this->pages[1]);
11646 $this->page = 0;
11647 }
11648 return $h;
11649 }
11650
11651
11652 // Called internally from Header
11653 function writeHTMLHeaders() {
11654
11655 if ($this->mirrorMargins && ($this->page)%2==0) { $OE = 'E'; } // EVEN
11656 else { $OE = 'O'; }
11657 if ($OE == 'E') {
11658 $this->saveHTMLHeader[$this->page][$OE]['html'] = $this->HTMLHeaderE['html'] ;
11659 }
11660 else {
11661 $this->saveHTMLHeader[$this->page][$OE]['html'] = $this->HTMLHeader['html'] ;
11662 }
11663 if ($this->forcePortraitHeaders && $this->CurOrientation=='L' && $this->CurOrientation!=$this->DefOrientation) {
11664 $this->saveHTMLHeader[$this->page][$OE]['rotate'] = true;
11665 $this->saveHTMLHeader[$this->page][$OE]['ml'] = $this->tMargin;
11666 $this->saveHTMLHeader[$this->page][$OE]['mr'] = $this->bMargin;
11667 $this->saveHTMLHeader[$this->page][$OE]['mh'] = $this->margin_header;
11668 $this->saveHTMLHeader[$this->page][$OE]['mf'] = $this->margin_footer;
11669 $this->saveHTMLHeader[$this->page][$OE]['pw'] = $this->h;
11670 $this->saveHTMLHeader[$this->page][$OE]['ph'] = $this->w;
11671 }
11672 else {
11673 $this->saveHTMLHeader[$this->page][$OE]['ml'] = $this->lMargin;
11674 $this->saveHTMLHeader[$this->page][$OE]['mr'] = $this->rMargin;
11675 $this->saveHTMLHeader[$this->page][$OE]['mh'] = $this->margin_header;
11676 $this->saveHTMLHeader[$this->page][$OE]['mf'] = $this->margin_footer;
11677 $this->saveHTMLHeader[$this->page][$OE]['pw'] = $this->w;
11678 $this->saveHTMLHeader[$this->page][$OE]['ph'] = $this->h;
11679 }
11680 }
11681
11682 function writeHTMLFooters() {
11683
11684 if ($this->mirrorMargins && ($this->page)%2==0) { $OE = 'E'; } // EVEN
11685 else { $OE = 'O'; }
11686 if ($OE == 'E') {
11687 $this->saveHTMLFooter[$this->page][$OE]['html'] = $this->HTMLFooterE['html'] ;
11688 }
11689 else {
11690 $this->saveHTMLFooter[$this->page][$OE]['html'] = $this->HTMLFooter['html'] ;
11691 }
11692 if ($this->forcePortraitHeaders && $this->CurOrientation=='L' && $this->CurOrientation!=$this->DefOrientation) {
11693 $this->saveHTMLFooter[$this->page][$OE]['rotate'] = true;
11694 $this->saveHTMLFooter[$this->page][$OE]['ml'] = $this->tMargin;
11695 $this->saveHTMLFooter[$this->page][$OE]['mr'] = $this->bMargin;
11696 $this->saveHTMLFooter[$this->page][$OE]['mt'] = $this->rMargin;
11697 $this->saveHTMLFooter[$this->page][$OE]['mb'] = $this->lMargin;
11698 $this->saveHTMLFooter[$this->page][$OE]['mh'] = $this->margin_header;
11699 $this->saveHTMLFooter[$this->page][$OE]['mf'] = $this->margin_footer;
11700 $this->saveHTMLFooter[$this->page][$OE]['pw'] = $this->h;
11701 $this->saveHTMLFooter[$this->page][$OE]['ph'] = $this->w;
11702 }
11703 else {
11704 $this->saveHTMLFooter[$this->page][$OE]['ml'] = $this->lMargin;
11705 $this->saveHTMLFooter[$this->page][$OE]['mr'] = $this->rMargin;
11706 $this->saveHTMLFooter[$this->page][$OE]['mt'] = $this->tMargin;
11707 $this->saveHTMLFooter[$this->page][$OE]['mb'] = $this->bMargin;
11708 $this->saveHTMLFooter[$this->page][$OE]['mh'] = $this->margin_header;
11709 $this->saveHTMLFooter[$this->page][$OE]['mf'] = $this->margin_footer;
11710 $this->saveHTMLFooter[$this->page][$OE]['pw'] = $this->w;
11711 $this->saveHTMLFooter[$this->page][$OE]['ph'] = $this->h;
11712 }
11713 }
11714 /*-- END HTMLHEADERS-FOOTERS --*/
11715
11716 function DefHeaderByName($name,$arr) {
11717 if (!$name) { $name = '_default'; }
11718 $this->pageheaders[$name] = $arr;
11719 }
11720
11721 function DefFooterByName($name,$arr) {
11722 if (!$name) { $name = '_default'; }
11723 $this->pagefooters[$name] = $arr;
11724 }
11725
11726 function SetHeaderByName($name,$side='O',$write=false) {
11727 if (!$name) { $name = '_default'; }
11728 if ($side=='E') { $this->headerDetails['even'] = $this->pageheaders[$name]; }
11729 else { $this->headerDetails['odd'] = $this->pageheaders[$name]; }
11730 if ($write) { $this->Header(); }
11731 }
11732
11733 function SetFooterByName($name,$side='O') {
11734 if (!$name) { $name = '_default'; }
11735 if ($side=='E') { $this->footerDetails['even'] = $this->pagefooters[$name]; }
11736 else { $this->footerDetails['odd'] = $this->pagefooters[$name]; }
11737 }
11738
11739 /*-- HTMLHEADERS-FOOTERS --*/
11740 function DefHTMLHeaderByName($name,$html) {
11741 if (!$name) { $name = '_default'; }
11742
11743 $this->pageHTMLheaders[$name]['html'] = $html;
11744 $this->pageHTMLheaders[$name]['h'] = $this->_gethtmlheight($html);
11745 }
11746
11747 function DefHTMLFooterByName($name,$html) {
11748 if (!$name) { $name = '_default'; }
11749
11750 $this->pageHTMLfooters[$name]['html'] = $html;
11751 $this->pageHTMLfooters[$name]['h'] = $this->_gethtmlheight($html);
11752 }
11753
11754 function SetHTMLHeaderByName($name,$side='O',$write=false) {
11755 if (!$name) { $name = '_default'; }
11756 $this->SetHTMLHeader($this->pageHTMLheaders[$name],$side,$write);
11757 }
11758
11759 function SetHTMLFooterByName($name,$side='O') {
11760 if (!$name) { $name = '_default'; }
11761 $this->SetHTMLFooter($this->pageHTMLfooters[$name],$side,$write);
11762 }
11763 /*-- END HTMLHEADERS-FOOTERS --*/
11764
11765
11766 function SetHeader($Harray=array(),$side='',$write=false) {
11767 if (is_string($Harray)) {
11768 if (strlen($Harray)==0) {
11769 if ($side=='O') { $this->headerDetails['odd'] = array(); }
11770 else if ($side=='E') { $this->headerDetails['even'] = array(); }
11771 else { $this->headerDetails = array(); }
11772 }
11773 else if (strpos($Harray,'|') || strpos($Harray,'|')===0) {
11774 $hdet = explode('|',$Harray);
11775 $this->headerDetails = array (
11776 'odd' => array (
11777 'L' => array ('content' => $hdet[0], 'font-size' => $this->defaultheaderfontsize, 'font-style' => $this->defaultheaderfontstyle),
11778 'C' => array ('content' => $hdet[1], 'font-size' => $this->defaultheaderfontsize, 'font-style' => $this->defaultheaderfontstyle),
11779 'R' => array ('content' => $hdet[2], 'font-size' => $this->defaultheaderfontsize, 'font-style' => $this->defaultheaderfontstyle),
11780 'line' => $this->defaultheaderline,
11781 ),
11782 'even' => array (
11783 'R' => array ('content' => $hdet[0], 'font-size' => $this->defaultheaderfontsize, 'font-style' => $this->defaultheaderfontstyle),
11784 'C' => array ('content' => $hdet[1], 'font-size' => $this->defaultheaderfontsize, 'font-style' => $this->defaultheaderfontstyle),
11785 'L' => array ('content' => $hdet[2], 'font-size' => $this->defaultheaderfontsize, 'font-style' => $this->defaultheaderfontstyle),
11786 'line' => $this->defaultheaderline,
11787 )
11788 );
11789 }
11790 else {
11791 $this->headerDetails = array (
11792 'odd' => array (
11793 'R' => array ('content' => $Harray, 'font-size' => $this->defaultheaderfontsize, 'font-style' => $this->defaultheaderfontstyle),
11794 'line' => $this->defaultheaderline,
11795 ),
11796 'even' => array (
11797 'L' => array ('content' => $Harray, 'font-size' => $this->defaultheaderfontsize, 'font-style' => $this->defaultheaderfontstyle),
11798 'line' => $this->defaultheaderline,
11799 )
11800 );
11801 }
11802 }
11803 else if (is_array($Harray)) {
11804 if ($side=='O') { $this->headerDetails['odd'] = $Harray; }
11805 else if ($side=='E') { $this->headerDetails['even'] = $Harray; }
11806 else { $this->headerDetails = $Harray; }
11807 }
11808 /*-- HTMLHEADERS-FOOTERS --*/
11809 // Overwrite any HTML Header previously set
11810 if ($side=='E') { $this->SetHTMLHeader('','E'); }
11811 else if ($side=='O') { $this->SetHTMLHeader(''); }
11812 else {
11813 $this->SetHTMLHeader('');
11814 $this->SetHTMLHeader('','E');
11815 }
11816 /*-- END HTMLHEADERS-FOOTERS --*/
11817
11818 if ($write) {
11819 $save_y = $this->y;
11820 $this->Header();
11821 $this->SetY($save_y) ;
11822 }
11823 }
11824
11825
11826
11827
11828 function SetFooter($Farray=array(),$side='') {
11829 if (is_string($Farray)) {
11830 if (strlen($Farray)==0) {
11831 if ($side=='O') { $this->footerDetails['odd'] = array(); }
11832 else if ($side=='E') { $this->footerDetails['even'] = array(); }
11833 else { $this->footerDetails = array(); }
11834 }
11835 else if (strpos($Farray,'|') || strpos($Farray,'|')===0) {
11836 $fdet = explode('|',$Farray);
11837 $this->footerDetails = array (
11838 'odd' => array (
11839 'L' => array ('content' => $fdet[0], 'font-size' => $this->defaultfooterfontsize, 'font-style' => $this->defaultfooterfontstyle),
11840 'C' => array ('content' => $fdet[1], 'font-size' => $this->defaultfooterfontsize, 'font-style' => $this->defaultfooterfontstyle),
11841 'R' => array ('content' => $fdet[2], 'font-size' => $this->defaultfooterfontsize, 'font-style' => $this->defaultfooterfontstyle),
11842 'line' => $this->defaultfooterline,
11843 ),
11844 'even' => array (
11845 'R' => array ('content' => $fdet[0], 'font-size' => $this->defaultfooterfontsize, 'font-style' => $this->defaultfooterfontstyle),
11846 'C' => array ('content' => $fdet[1], 'font-size' => $this->defaultfooterfontsize, 'font-style' => $this->defaultfooterfontstyle),
11847 'L' => array ('content' => $fdet[2], 'font-size' => $this->defaultfooterfontsize, 'font-style' => $this->defaultfooterfontstyle),
11848 'line' => $this->defaultfooterline,
11849 )
11850 );
11851 }
11852 else {
11853 $this->footerDetails = array (
11854 'odd' => array (
11855 'R' => array ('content' => $Farray, 'font-size' => $this->defaultfooterfontsize, 'font-style' => $this->defaultfooterfontstyle),
11856 'line' => $this->defaultfooterline,
11857 ),
11858 'even' => array (
11859 'L' => array ('content' => $Farray, 'font-size' => $this->defaultfooterfontsize, 'font-style' => $this->defaultfooterfontstyle),
11860 'line' => $this->defaultfooterline,
11861 )
11862 );
11863 }
11864 }
11865 else if (is_array($Farray)) {
11866 if ($side=='O') { $this->footerDetails['odd'] = $Farray; }
11867 else if ($side=='E') { $this->footerDetails['even'] = $Farray; }
11868 else { $this->footerDetails = $Farray; }
11869 }
11870 /*-- HTMLHEADERS-FOOTERS --*/
11871 // Overwrite any HTML Footer previously set
11872 if ($side=='E') { $this->SetHTMLFooter('','E'); }
11873 else if ($side=='O') { $this->SetHTMLFooter(''); }
11874 else {
11875 $this->SetHTMLFooter('');
11876 $this->SetHTMLFooter('','E');
11877 }
11878 /*-- END HTMLHEADERS-FOOTERS --*/
11879 }
11880
11881 /*-- WATERMARK --*/
11882 function setUnvalidatedText($txt='', $alpha=-1) {
11883 if ($alpha>=0) $this->watermarkTextAlpha = $alpha;
11884 $this->watermarkText = $txt;
11885 }
11886 function SetWatermarkText($txt='', $alpha=-1) {
11887 if ($alpha>=0) $this->watermarkTextAlpha = $alpha;
11888 $this->watermarkText = $txt;
11889 }
11890
11891 function SetWatermarkImage($src, $alpha=-1, $size='D', $pos='F') {
11892 if ($alpha>=0) $this->watermarkImageAlpha = $alpha;
11893 $this->watermarkImage = $src;
11894 $this->watermark_size = $size;
11895 $this->watermark_pos = $pos;
11896 }
11897 /*-- END WATERMARK --*/
11898
11899
11900 //Page footer
11901 function Footer() {
11902 /*-- CSS-PAGE --*/
11903 // PAGED MEDIA - CROP / CROSS MARKS from @PAGE
11904 if ($this->show_marks == 'CROP' || $this->show_marks == 'CROPCROSS') {
11905 // Show TICK MARKS
11906 $this->SetLineWidth(0.1); // = 0.1 mm
11907 $this->SetDColor($this->ConvertColor(0));
11908 $l = $this->cropMarkLength;
11909 $m = $this->cropMarkMargin; // Distance of crop mark from margin
11910 $b = $this->nonPrintMargin; // Non-printable border at edge of paper sheet
11911 $ax1 = $b;
11912 $bx = $this->page_box['outer_width_LR'] - $m;
11913 $ax = max($ax1, $bx-$l);
11914 $cx1 = $this->w - $b;
11915 $dx = $this->w - $this->page_box['outer_width_LR'] + $m;
11916 $cx = min($cx1, $dx+$l);
11917 $ay1 = $b;
11918 $by = $this->page_box['outer_width_TB'] - $m;
11919 $ay = max($ay1, $by-$l);
11920 $cy1 = $this->h - $b;
11921 $dy = $this->h - $this->page_box['outer_width_TB'] + $m;
11922 $cy = min($cy1, $dy+$l);
11923
11924 $this->Line($ax, $this->page_box['outer_width_TB'], $bx, $this->page_box['outer_width_TB']);
11925 $this->Line($cx, $this->page_box['outer_width_TB'], $dx, $this->page_box['outer_width_TB']);
11926 $this->Line($ax, $this->h - $this->page_box['outer_width_TB'], $bx, $this->h - $this->page_box['outer_width_TB']);
11927 $this->Line($cx, $this->h - $this->page_box['outer_width_TB'], $dx, $this->h - $this->page_box['outer_width_TB']);
11928 $this->Line($this->page_box['outer_width_LR'], $ay, $this->page_box['outer_width_LR'], $by);
11929 $this->Line($this->page_box['outer_width_LR'], $cy, $this->page_box['outer_width_LR'], $dy);
11930 $this->Line($this->w - $this->page_box['outer_width_LR'], $ay, $this->w - $this->page_box['outer_width_LR'], $by);
11931 $this->Line($this->w - $this->page_box['outer_width_LR'], $cy, $this->w - $this->page_box['outer_width_LR'], $dy);
11932
11933 if ($this->printers_info) {
11934 $hd = date('Y-m-d H:i').' Page '.$this->page.' of {nb}';
11935 $this->SetTColor($this->ConvertColor(0));
11936 $this->SetFont('arial','',7.5,true,true);
11937 $this->x = $this->page_box['outer_width_LR'] + 1.5;
11938 $this->y = 1;
11939 $this->Cell($headerpgwidth ,$this->FontSize,$hd,0,0,'L',0,'',0,0,0,'M');
11940 $this->SetFont($this->default_font,'',$this->original_default_font_size);
11941 }
11942
11943 }
11944 if ($this->show_marks == 'CROSS' || $this->show_marks == 'CROPCROSS') {
11945 $this->SetLineWidth(0.1); // = 0.1 mm
11946 $this->SetDColor($this->ConvertColor(0));
11947 $l = 14 /2; // longer length of the cross line (half)
11948 $w = 6 /2; // shorter width of the cross line (half)
11949 $r = 1.2; // radius of circle
11950 $m = $this->crossMarkMargin; // Distance of cross mark from margin
11951 $x1 = $this->page_box['outer_width_LR'] - $m;
11952 $x2 = $this->w - $this->page_box['outer_width_LR'] + $m;
11953 $y1 = $this->page_box['outer_width_TB'] - $m;
11954 $y2 = $this->h - $this->page_box['outer_width_TB'] + $m;
11955 // Left
11956 $this->Circle($x1, $this->h/2, $r, 'S') ;
11957 $this->Line($x1-$w, $this->h/2, $x1+$w, $this->h/2);
11958 $this->Line($x1, $this->h/2-$l, $x1, $this->h/2+$l);
11959 // Right
11960 $this->Circle($x2, $this->h/2, $r, 'S') ;
11961 $this->Line($x2-$w, $this->h/2, $x2+$w, $this->h/2);
11962 $this->Line($x2, $this->h/2-$l, $x2, $this->h/2+$l);
11963 // Top
11964 $this->Circle($this->w/2, $y1, $r, 'S') ;
11965 $this->Line($this->w/2, $y1-$w, $this->w/2, $y1+$w);
11966 $this->Line($this->w/2-$l, $y1, $this->w/2+$l, $y1);
11967 // Bottom
11968 $this->Circle($this->w/2, $y2, $r, 'S') ;
11969 $this->Line($this->w/2, $y2-$w, $this->w/2, $y2+$w);
11970 $this->Line($this->w/2-$l, $y2, $this->w/2+$l, $y2);
11971 }
11972
11973
11974 // If @page set non-HTML headers/footers named, they were not read until later in the HTML code - so now set them
11975 if ($this->page==1) {
11976 if ($this->firstPageBoxHeader) {
11977 $this->headerDetails['odd'] = $this->pageheaders[$this->firstPageBoxHeader];
11978 $this->Header();
11979 }
11980 if ($this->firstPageBoxFooter) {
11981 $this->footerDetails['odd'] = $this->pagefooters[$this->firstPageBoxFooter];
11982 }
11983 $this->firstPageBoxHeader='';
11984 $this->firstPageBoxFooter='';
11985 }
11986 /*-- END CSS-PAGE --*/
11987
11988
11989
11990 /*-- HTMLHEADERS-FOOTERS --*/
11991 if (($this->mirrorMargins && ($this->page%2==0) && $this->HTMLFooterE) || ($this->mirrorMargins && ($this->page%2==1) && $this->HTMLFooter) || (!$this->mirrorMargins && $this->HTMLFooter)) {
11992 $this->writeHTMLFooters();
11993 /*-- WATERMARK --*/
11994 if (($this->watermarkText) && ($this->showWatermarkText)) {
11995 $this->watermark( $this->watermarkText, 45, 120, $this->watermarkTextAlpha); // Watermark text
11996 }
11997 if (($this->watermarkImage) && ($this->showWatermarkImage)) {
11998 $this->watermarkImg( $this->watermarkImage, $this->watermarkImageAlpha); // Watermark image
11999 }
12000 /*-- END WATERMARK --*/
12001 return;
12002 }
12003 /*-- END HTMLHEADERS-FOOTERS --*/
12004
12005 $this->processingHeader=true;
12006 $this->ResetMargins(); // necessary after columns
12007 $this->pgwidth = $this->w - $this->lMargin - $this->rMargin;
12008 /*-- WATERMARK --*/
12009 if (($this->watermarkText) && ($this->showWatermarkText)) {
12010 $this->watermark( $this->watermarkText, 45, 120, $this->watermarkTextAlpha); // Watermark text
12011 }
12012 if (($this->watermarkImage) && ($this->showWatermarkImage)) {
12013 $this->watermarkImg( $this->watermarkImage, $this->watermarkImageAlpha); // Watermark image
12014 }
12015 /*-- END WATERMARK --*/
12016 $h = $this->footerDetails;
12017 if(count($h)) {
12018
12019 if ($this->forcePortraitHeaders && $this->CurOrientation=='L' && $this->CurOrientation!=$this->DefOrientation) {
12020 $this->_out(sprintf('q 0 -1 1 0 0 %.3F cm ',($this->h*_MPDFK)));
12021 $headerpgwidth = $this->h - $this->orig_lMargin - $this->orig_rMargin;
12022 if (($this->mirrorMargins) && (($this->page)%2==0)) { // EVEN
12023 $headerlmargin = $this->orig_rMargin;
12024 }
12025 else {
12026 $headerlmargin = $this->orig_lMargin;
12027 }
12028 }
12029 else {
12030 $yadj = 0;
12031 $headerpgwidth = $this->pgwidth;
12032 $headerlmargin = $this->lMargin;
12033 }
12034 $this->SetY(-$this->margin_footer);
12035
12036 $this->SetTColor($this->ConvertColor(0));
12037 $this->SUP = false;
12038 $this->SUB = false;
12039 $this->bullet = false;
12040
12041 // only show pagenumber if numbering on
12042 $pgno = $this->docPageNum($this->page, true);
12043
12044 if (($this->mirrorMargins) && (($this->page)%2==0)) { // EVEN
12045 $side = 'even';
12046 }
12047 else { // ODD // OR NOT MIRRORING MARGINS/FOOTERS = DEFAULT
12048 $side = 'odd';
12049 }
12050 $maxfontheight = 0;
12051 foreach(array('L','C','R') AS $pos) {
12052 if (isset($h[$side][$pos]['content']) && $h[$side][$pos]['content']) {
12053 if (isset($h[$side][$pos]['font-size']) && $h[$side][$pos]['font-size']) { $hfsz = $h[$side][$pos]['font-size']; }
12054 else { $hfsz = $this->default_font_size; }
12055 $maxfontheight = max($maxfontheight,$hfsz);
12056 }
12057 }
12058 // LEFT-CENTER-RIGHT
12059 foreach(array('L','C','R') AS $pos) {
12060 if (isset($h[$side][$pos]['content']) && $h[$side][$pos]['content']) {
12061 $hd = str_replace('{PAGENO}',$pgno,$h[$side][$pos]['content']);
12062 $hd = str_replace($this->aliasNbPgGp,$this->nbpgPrefix.$this->aliasNbPgGp.$this->nbpgSuffix,$hd);
12063 $hd = preg_replace('/\{DATE\s+(.*?)\}/e',"date('\\1')",$hd);
12064 if (isset($h[$side][$pos]['font-family']) && $h[$side][$pos]['font-family']) { $hff = $h[$side][$pos]['font-family']; }
12065 else { $hff = $this->original_default_font; }
12066 if (isset($h[$side][$pos]['font-size']) && $h[$side][$pos]['font-size']) { $hfsz = $h[$side][$pos]['font-size']; }
12067 else { $hfsz = $this->original_default_font_size; }
12068 $maxfontheight = max($maxfontheight,$hfsz);
12069 if (isset($h[$side][$pos]['font-style']) && $h[$side][$pos]['font-style']) { $hfst = $h[$side][$pos]['font-style']; }
12070 else { $hfst = ''; }
12071 if (isset($h[$side][$pos]['color']) && $h[$side][$pos]['color']) {
12072 $hfcol = $h[$side][$pos]['color'];
12073 $cor = $this->ConvertColor($hfcol);
12074 if ($cor) { $this->SetTColor($cor); }
12075 }
12076 else { $hfcol = ''; }
12077 $this->SetFont($hff,$hfst,$hfsz,true,true);
12078 $this->x = $headerlmargin ;
12079 $this->y = $this->h - $this->margin_footer - ($maxfontheight/_MPDFK);
12080 $hd = $this->purify_utf8_text($hd);
12081 if ($this->text_input_as_HTML) {
12082 $hd = $this->all_entities_to_utf8($hd);
12083 }
12084 // CONVERT CODEPAGE
12085 if ($this->usingCoreFont) { $hd = mb_convert_encoding($hd,$this->mb_enc,'UTF-8'); }
12086 // DIRECTIONALITY RTL
12087 $this->magic_reverse_dir($hd, true, $this->directionality); // *RTL*
12088 // Font-specific ligature substitution for Indic fonts
12089 if (isset($this->CurrentFont['indic']) && $this->CurrentFont['indic']) $this->ConvertIndic($hd); // *INDIC*
12090 $align = $pos;
12091 if ($this->directionality == 'rtl') {
12092 if ($pos == 'L') { $align = 'R'; }
12093 else if ($pos == 'R') { $align = 'L'; }
12094 }
12095
12096 if ($pos!='L' && (strpos($hd,$this->aliasNbPg)!==false || strpos($hd,$this->aliasNbPgGp)!==false)) {
12097 if (strpos($hd,$this->aliasNbPgGp)!==false) { $type= 'nbpggp'; } else { $type= 'nbpg'; }
12098 $this->_out('{mpdfheader'.$type.' '.$pos.' ff='.$hff.' fs='.$hfst.' fz='.$hfsz.'}');
12099 $this->Cell($headerpgwidth ,$maxfontheight/_MPDFK ,$hd,0,0,$align,0,'',0,0,0,'M');
12100 $this->_out('Q');
12101 }
12102 else {
12103 $this->Cell($headerpgwidth ,$maxfontheight/_MPDFK ,$hd,0,0,$align,0,'',0,0,0,'M');
12104 }
12105 if ($hfcol) { $this->SetTColor($this->ConvertColor(0)); }
12106 }
12107 }
12108 // Return Font to normal
12109 $this->SetFont($this->default_font,'',$this->original_default_font_size);
12110
12111 // LINE
12112
12113 if (isset($h[$side]['line']) && $h[$side]['line']) {
12114 $this->SetLineWidth(0.1);
12115 $this->SetDColor($this->ConvertColor(0));
12116 $this->Line($headerlmargin , $this->y-($maxfontheight*($this->footer_line_spacing)/_MPDFK), $headerlmargin +$headerpgwidth, $this->y-($maxfontheight*($this->footer_line_spacing)/_MPDFK));
12117 }
12118 if ($this->forcePortraitHeaders && $this->CurOrientation=='L' && $this->CurOrientation!=$this->DefOrientation) {
12119 $this->_out('Q');
12120 }
12121 }
12122 $this->processingHeader=false;
12123
12124 }
12125
12126 /*-- HYPHENATION --*/
12127 ///////////////////
12128 ///////////////////
12129 // HYPHENATION
12130 ///////////////////
12131 // Soft hyphs
12132 function softHyphenate($word, $maxWidth) {
12133 // Don't hyphenate web addresses
12134 if (preg_match('/^(http:|www\.)/',$word)) { return array(false,'','',''); }
12135
12136 // Get dictionary
12137 $poss = array();
12138 $softhyphens = array();
12139 $offset = 0;
12140 $p = true;
12141 if ($this->usingCoreFont) {
12142 $wl = strlen($word);
12143 }
12144 else {
12145 $wl = mb_strlen($word,'UTF-8');
12146 }
12147 while($offset < $wl) {
12148 // Soft Hyphens chr(173)
12149 if (!$this->usingCoreFont) {
12150 $p = mb_strpos($word, "\xc2\xad", $offset, 'UTF-8');
12151 }
12152 else if ($this->FontFamily!='csymbol' && $this->FontFamily!='czapfdingbats') {
12153 $p = strpos($word, chr(173), $offset);
12154 }
12155 if ($p !== false) { $poss[] = $p - count($poss); }
12156 else { break; }
12157 $offset = $p+1;
12158 }
12159 $success = false;
12160 foreach($poss AS $i) {
12161 if ($this->usingCoreFont) {
12162 $a = substr($word,0,$i);
12163 if ($this->GetStringWidth($a.'-') > $maxWidth) { break ; }
12164 $pre = $a;
12165 $post = substr($word,$i,strlen($word));
12166 $prelength = strlen($pre);
12167 }
12168 else {
12169 $a = mb_substr($word,0,$i,'UTF-8');
12170 if ($this->GetStringWidth($a.'-') > $maxWidth) { break ; }
12171 $pre = $a;
12172 $post = mb_substr($word,$i,mb_strlen($word,'UTF-8'),'UTF-8');
12173 $prelength = mb_strlen($pre, 'UTF-8');
12174 }
12175 $success = true;
12176 }
12177 return array($success,$pre,$post,$prelength);
12178 }
12179
12180 ///////////////////
12181 // Word hyphenation
12182 function hyphenateWord($word, $maxWidth) {
12183 // Do everything inside this function in utf-8
12184 // Don't hyphenate web addresses
12185 if (preg_match('/^(http:|www\.)/',$word)) { return array(false,'','',''); }
12186
12187
12188 // Get dictionary
12189 if (!$this->loadedSHYdictionary) {
12190 if (file_exists(_MPDF_PATH.'patterns/dictionary.txt')) {
12191 $this->SHYdictionary = file(_MPDF_PATH.'patterns/dictionary.txt',FILE_SKIP_EMPTY_LINES);
12192 foreach($this->SHYdictionary as $entry) {
12193 $entry = trim($entry);
12194 $poss = array();
12195 $offset = 0;
12196 $p = true;
12197 $wl = mb_strlen($entry ,'UTF-8');
12198 while($offset < $wl) {
12199 $p = mb_strpos($entry, '/', $offset, 'UTF-8');
12200 if ($p !== false) { $poss[] = $p - count($poss); }
12201 else { break; }
12202 $offset = $p+1;
12203 }
12204 if (count($poss)) { $this->SHYdictionaryWords[str_replace('/', '', mb_strtolower($entry))] = $poss; }
12205 }
12206 }
12207 $this->loadedSHYdictionary = true;
12208 }
12209
12210 if (!in_array($this->SHYlang,$this->SHYlanguages)) { return array(false,'','',''); }
12211 // If no pattern loaded or not the best one
12212 if (count($this->SHYpatterns) < 1 || ($this->loadedSHYpatterns && $this->loadedSHYpatterns != $this->SHYlang)) {
12213 include(_MPDF_PATH."patterns/" . $this->SHYlang . ".php");
12214 $patterns = explode(' ', $patterns);
12215 $new_patterns = array();
12216 for($i = 0; $i < count($patterns); $i++) {
12217 $value = $patterns[$i];
12218 $new_patterns[preg_replace('/[0-9]/', '', $value)] = $value;
12219 }
12220 $this->SHYpatterns = $new_patterns;
12221 $this->loadedSHYpatterns = $this->SHYlang;
12222 }
12223
12224 if ($this->usingCoreFont) { $word = mb_convert_encoding($word,'UTF-8',$this->mb_enc); }
12225
12226 $prepre = '';
12227 $postpost = '';
12228 $startpunctuation = "\xc2\xab\xc2\xbf\xe2\x80\x98\xe2\x80\x9b\xe2\x80\x9c\xe2\x80\x9f";
12229 $endpunctuation = "\xe2\x80\x9e\xe2\x80\x9d\xe2\x80\x9a\xe2\x80\x99\xc2\xbb";
12230 $pre = '';
12231 $post = '';
12232
12233
12234 if (preg_match('/^(["\''.$startpunctuation .'])+(.{'.$this->SHYcharmin.',})$/u',$word,$m)) {
12235 $prepre = $m[1];
12236 $word = $m[2];
12237 }
12238 if (preg_match('/^(.{'.$this->SHYcharmin.',})([\'\.,;:!?"'.$endpunctuation .']+)$/u',$word,$m)) {
12239 $word = $m[1];
12240 $postpost = $m[2];
12241 }
12242 if(mb_strlen($word,'UTF-8') < $this->SHYcharmin) {
12243 return array(false,'','','');
12244 }
12245 $success = false;
12246
12247 if(isset($this->SHYdictionaryWords[mb_strtolower($word)])) {
12248 foreach($this->SHYdictionaryWords[mb_strtolower($word)] AS $i) {
12249 $a = $prepre . mb_substr($word,0,$i,'UTF-8');
12250 if ($this->usingCoreFont) { $testa = mb_convert_encoding($a,$this->mb_enc,'UTF-8'); }
12251 else { $testa = $a; }
12252 if ($this->GetStringWidth($testa.'-') > $maxWidth) { break ; }
12253 $pre = $a;
12254 $post = mb_substr($word,$i,mb_strlen($word,'UTF-8'),'UTF-8') . $postpost;
12255 $success = true;
12256 }
12257 }
12258
12259 if (!$success) {
12260 $text_word = '_' . $word . '_';
12261 $word_length = mb_strlen($text_word,'UTF-8');
12262
12263 $single_character = preg_split('//u', $text_word);
12264
12265 $text_word = mb_strtolower($text_word,'UTF-8');
12266 $hyphenated_word = array();
12267 $numb3rs = array('0' => true, '1' => true, '2' => true, '3' => true, '4' => true, '5' => true, '6' => true, '7' => true, '8' => true, '9' => true);
12268 for($position = 0; $position <= ($word_length - $this->SHYcharmin); $position++) {
12269 $maxwins = min(($word_length - $position), $this->SHYcharmax);
12270 for($win = $this->SHYcharmin; $win <= $maxwins; $win++) {
12271 if(isset($this->SHYpatterns[mb_substr($text_word, $position, $win,'UTF-8')])) {
12272 $pattern = $this->SHYpatterns[mb_substr($text_word, $position, $win,'UTF-8')];
12273 $digits = 1;
12274 $pattern_length = mb_strlen($pattern,'UTF-8');
12275 for($i = 0; $i < $pattern_length; $i++) {
12276 $char = $pattern[$i];
12277 if(isset($numb3rs[$char])) {
12278 $zero = ($i == 0) ? $position - 1 : $position + $i - $digits;
12279 if(!isset($hyphenated_word[$zero]) || $hyphenated_word[$zero] != $char) $hyphenated_word[$zero] = $char;
12280 $digits++;
12281 }
12282 }
12283 }
12284 }
12285 }
12286
12287 for($i = $this->SHYleftmin; $i <= (mb_strlen($word,'UTF-8') - $this->SHYrightmin); $i++) {
12288 if(isset($hyphenated_word[$i]) && $hyphenated_word[$i] % 2 != 0) {
12289 $a = $prepre . mb_substr($word,0,$i,'UTF-8');
12290 if ($this->usingCoreFont) { $testa = mb_convert_encoding($a,$this->mb_enc,'UTF-8'); }
12291 else { $testa = $a; }
12292 if ($this->GetStringWidth($testa.'-') > $maxWidth + 0.0001) { break ; }
12293 $pre = $a;
12294 $post = mb_substr($word,$i,mb_strlen($word,'UTF-8'),'UTF-8') . $postpost;
12295 $success = true;
12296 }
12297 }
12298 }
12299 if ($this->usingCoreFont) {
12300 $pre = mb_convert_encoding($pre,$this->mb_enc,'UTF-8');
12301 $post = mb_convert_encoding($post,$this->mb_enc,'UTF-8');
12302 $prelength = strlen($pre);
12303 }
12304 else {
12305 $prelength = mb_strlen($pre);
12306 }
12307 return array($success,$pre,$post,$prelength);
12308
12309 }
12310 /*-- END HYPHENATION --*/
12311
12312
12313 /*-- HTML-CSS --*/
12314 ///////////////////
12315 /// HTML parser ///
12316 ///////////////////
12317 function WriteHTML($html,$sub=0,$init=true,$close=true) {
12318 // $sub ADDED - 0 = default; 1=headerCSS only; 2=HTML body (parts) only; 3 - HTML parses only
12319 // 4 - writes HTML headers
12320 // $close Leaves buffers etc. in current state, so that it can continue a block etc.
12321 // $init - Clears and sets buffers to Top level block etc.
12322
12323 if (empty($html)) { $html = ''; }
12324 if ($this->progressBar) { $this->UpdateProgressBar(1,0,'Parsing CSS & Headers'); } // *PROGRESS-BAR*
12325
12326 if ($init) {
12327 $this->headerbuffer='';
12328 $this->textbuffer = array();
12329 $this->fixedPosBlockSave = array();
12330 }
12331 if ($sub == 1) { $html = '<style> '.$html.' </style>'; } // stylesheet only
12332
12333 if ($this->allow_charset_conversion) {
12334 if ($sub < 1) {
12335 $this->ReadCharset($html);
12336 }
12337 if ($this->charset_in) {
12338 $success = iconv($this->charset_in,'UTF-8//TRANSLIT',$html);
12339 if ($success) { $html = $success; }
12340 }
12341 }
12342
12343 $html = $this->purify_utf8($html,false);
12344 if ($init) {
12345 $this->blklvl = 0;
12346 $this->lastblocklevelchange = 0;
12347 $this->blk = array();
12348 $this->initialiseBlock($this->blk[0]);
12349 $this->blk[0]['width'] =& $this->pgwidth;
12350 $this->blk[0]['inner_width'] =& $this->pgwidth;
12351 $this->blk[0]['blockContext'] = $this->blockContext;
12352 }
12353
12354 $zproperties = array();
12355 if ($sub < 2) {
12356 $this->ReadMetaTags($html);
12357
12358 // NB default stylesheet now in mPDF.css - read on initialising class
12359 $html = $this->ReadCSS($html);
12360
12361 if ($this->useLang && !$this->usingCoreFont && preg_match('/<html [^>]*lang=[\'\"](.*?)[\'\"]/ism',$html,$m)) {
12362 $html_lang = $m[1];
12363 }
12364
12365 if (preg_match('/<html [^>]*dir=[\'\"]\s*rtl\s*[\'\"]/ism',$html)) {
12366 $zproperties['DIRECTION'] = 'rtl';
12367 }
12368
12369 // allow in-line CSS for body tag to be parsed // Get <body> tag inline CSS
12370 if (preg_match('/<body([^>]*)>(.*?)<\/body>/ism',$html,$m) || preg_match('/<body([^>]*)>(.*)$/ism',$html,$m)) {
12371 $html = $m[2];
12372 // Changed to allow style="background: url('bg.jpg')"
12373 if (preg_match('/style=[\"](.*?)[\"]/ism',$m[1],$mm) || preg_match('/style=[\'](.*?)[\']/ism',$m[1],$mm)) {
12374 $zproperties = $this->readInlineCSS($mm[1]);
12375 }
12376 if (preg_match('/dir=[\'\"]\s*rtl\s*[\'\"]/ism',$m[1])) {
12377 $zproperties['DIRECTION'] = 'rtl';
12378 }
12379 if (isset($html_lang) && $html_lang) { $zproperties['LANG'] = $html_lang; } // mPDF 5.3.99
12380 if ($this->useLang && !$this->onlyCoreFonts && preg_match('/lang=[\'\"](.*?)[\'\"]/ism',$m[1],$mm)) { // mPDF 5.3.22
12381 $zproperties['LANG'] = $mm[1];
12382 }
12383
12384 }
12385 }
12386 $properties = $this->MergeCSS('BLOCK','BODY','');
12387 if ($zproperties) { $properties = $this->array_merge_recursive_unique($properties,$zproperties); }
12388
12389 if (isset($properties['DIRECTION']) && $properties['DIRECTION']) {
12390 $this->CSS['BODY']['DIRECTION'] = $properties['DIRECTION'];
12391 }
12392 if (!isset($this->CSS['BODY']['DIRECTION'])) {
12393 $this->CSS['BODY']['DIRECTION'] = $this->directionality;
12394 }
12395 else { $this->SetDirectionality($this->CSS['BODY']['DIRECTION']); }
12396
12397 $this->setCSS($properties,'','BODY');
12398 $this->blk[0]['InlineProperties'] = $this->saveInlineProperties();
12399
12400 if ($sub == 1) { return ''; }
12401 if (!isset($this->CSS['BODY'])) { $this->CSS['BODY'] = array(); }
12402
12403 /*-- BACKGROUNDS --*/
12404 if (isset($properties['BACKGROUND-GRADIENT'])) {
12405 $this->bodyBackgroundGradient = $properties['BACKGROUND-GRADIENT'];
12406 }
12407
12408 if (isset($properties['BACKGROUND-IMAGE']) && $properties['BACKGROUND-IMAGE']) {
12409 $ret = $this->SetBackground($properties, $this->pgwidth);
12410 if ($ret) { $this->bodyBackgroundImage = $ret; }
12411 }
12412 /*-- END BACKGROUNDS --*/
12413
12414 /*-- CSS-PAGE --*/
12415 // If page-box is set
12416 if ($this->state==0 && isset($this->CSS['@PAGE']) && $this->CSS['@PAGE'] ) {
12417 $this->page_box['current'] = '';
12418 $this->page_box['using'] = true;
12419 list($pborientation,$pbmgl,$pbmgr,$pbmgt,$pbmgb,$pbmgh,$pbmgf,$hname,$fname,$bg,$resetpagenum,$pagenumstyle,$suppress,$marks,$newformat) = $this->SetPagedMediaCSS('', false, 'O');
12420 $this->DefOrientation = $this->CurOrientation = $pborientation;
12421 $this->orig_lMargin = $this->DeflMargin = $pbmgl;
12422 $this->orig_rMargin = $this->DefrMargin = $pbmgr;
12423 $this->orig_tMargin = $this->tMargin = $pbmgt;
12424 $this->orig_bMargin = $this->bMargin = $pbmgb;
12425 $this->orig_hMargin = $this->margin_header = $pbmgh;
12426 $this->orig_fMargin = $this->margin_footer = $pbmgf;
12427 list($pborientation,$pbmgl,$pbmgr,$pbmgt,$pbmgb,$pbmgh,$pbmgf,$hname,$fname,$bg,$resetpagenum,$pagenumstyle,$suppress,$marks,$newformat) = $this->SetPagedMediaCSS('', true, 'O'); // first page
12428 $this->show_marks = $marks;
12429 if ($hname && !preg_match('/^html_(.*)$/i',$hname)) $this->firstPageBoxHeader = $hname;
12430 if ($fname && !preg_match('/^html_(.*)$/i',$fname)) $this->firstPageBoxFooter = $fname;
12431 }
12432 /*-- END CSS-PAGE --*/
12433
12434
12435 $parseonly = false;
12436 $this->bufferoutput = false;
12437 if ($sub == 3) {
12438 $parseonly = true;
12439 // Close any open block tags
12440 for ($b= $this->blklvl;$b>0;$b--) { $this->CloseTag($this->blk[$b]['tag']); }
12441 // Output any text left in buffer
12442 if (count($this->textbuffer)) { $this->printbuffer($this->textbuffer); }
12443 $this->textbuffer=array();
12444 }
12445 else if ($sub == 4) {
12446 // Close any open block tags
12447 for ($b= $this->blklvl;$b>0;$b--) { $this->CloseTag($this->blk[$b]['tag']); }
12448 // Output any text left in buffer
12449 if (count($this->textbuffer)) { $this->printbuffer($this->textbuffer); }
12450 $this->bufferoutput = true;
12451 $this->textbuffer=array();
12452 $this->headerbuffer='';
12453 $properties = $this->MergeCSS('BLOCK','BODY','');
12454 $this->setCSS($properties,'','BODY');
12455 }
12456
12457 mb_internal_encoding('UTF-8');
12458
12459 $html = $this->AdjustHTML($html, $this->tabSpaces); //Try to make HTML look more like XHTML // mPDF 5.3.60 / 99
12460
12461 if ($this->autoFontGroups) { $html = $this->AutoFont($html); }
12462
12463 /*-- HTMLHEADERS-FOOTERS --*/
12464 preg_match_all('/<htmlpageheader([^>]*)>(.*?)<\/htmlpageheader>/si',$html,$h);
12465 for($i=0;$i<count($h[1]);$i++) {
12466 if (preg_match('/name=[\'|\"](.*?)[\'|\"]/',$h[1][$i],$n)) {
12467 $this->pageHTMLheaders[$n[1]]['html'] = $h[2][$i];
12468 $this->pageHTMLheaders[$n[1]]['h'] = $this->_gethtmlheight($h[2][$i]);
12469 }
12470 }
12471 preg_match_all('/<htmlpagefooter([^>]*)>(.*?)<\/htmlpagefooter>/si',$html,$f);
12472 for($i=0;$i<count($f[1]);$i++) {
12473 if (preg_match('/name=[\'|\"](.*?)[\'|\"]/',$f[1][$i],$n)) {
12474 $this->pageHTMLfooters[$n[1]]['html'] = $f[2][$i];
12475 $this->pageHTMLfooters[$n[1]]['h'] = $this->_gethtmlheight($f[2][$i]);
12476 }
12477 }
12478 /*-- END HTMLHEADERS-FOOTERS --*/
12479 $html = preg_replace('/<htmlpageheader.*?<\/htmlpageheader>/si','',$html);
12480 $html = preg_replace('/<htmlpagefooter.*?<\/htmlpagefooter>/si','',$html);
12481
12482 if($this->state==0 && $sub!=1 && $sub!=3 && $sub!=4) {
12483 $this->AddPage($this->CurOrientation);
12484 }
12485
12486
12487 /*-- HTMLHEADERS-FOOTERS --*/
12488
12489 if (isset($hname) && preg_match('/^html_(.*)$/i',$hname,$n)) $this->SetHTMLHeader($this->pageHTMLheaders[$n[1]],'O',true);
12490 if (isset($fname) && preg_match('/^html_(.*)$/i',$fname,$n)) $this->SetHTMLFooter($this->pageHTMLfooters[$n[1]],'O');
12491
12492 /*-- END HTMLHEADERS-FOOTERS --*/
12493
12494 $html=str_replace('<?','< ',$html); //Fix '<?XML' bug from HTML code generated by MS Word
12495
12496 // mPDF 5.3.18
12497 $this->checkSIP = false;
12498 $this->checkSMP = false;
12499 $this->checkCJK = false;
12500 if ($this->onlyCoreFonts) { $html = $this->SubstituteChars($html); }
12501 else { // mPDF 5.3.18
12502 if (preg_match("/([".$this->pregRTLchars."])/u", $html)) { $this->biDirectional = true; } // *RTL*
12503 if (preg_match("/([\x{20000}-\x{2FFFF}])/u", $html)) { $this->checkSIP = true; }
12504 if (preg_match("/([\x{10000}-\x{1FFFF}])/u", $html)) { $this->checkSMP = true; }
12505 /*-- CJK-FONTS --*/
12506 if (preg_match("/([".$this->pregCJKchars."])/u", $html)) { $this->checkCJK = true; }
12507 /*-- END CJK-FONTS --*/
12508 }
12509
12510 // Don't allow non-breaking spaces that are converted to substituted chars or will break anyway and mess up table width calc.
12511 $html = str_replace('<tta>160</tta>',chr(32),$html);
12512 $html = str_replace('</tta><tta>','|',$html);
12513 $html = str_replace('</tts><tts>','|',$html);
12514 $html = str_replace('</ttz><ttz>','|',$html);
12515
12516 //Add new supported tags in the DisableTags function
12517 $html=strip_tags($html,$this->enabledtags); //remove all unsupported tags, but the ones inside the 'enabledtags' string
12518
12519 //Explode the string in order to parse the HTML code
12520 $a=preg_split('/<(.*?)>/ms',$html,-1,PREG_SPLIT_DELIM_CAPTURE);
12521 // ? more accurate regexp that allows e.g. <a name="Silly <name>">
12522 // if changing - also change in fn.SubstituteChars()
12523 // $a = preg_split ('/<((?:[^<>]+(?:"[^"]*"|\'[^\']*\')?)+)>/ms', $html, -1, PREG_SPLIT_DELIM_CAPTURE);
12524
12525 if ($this->mb_enc) {
12526 mb_internal_encoding($this->mb_enc);
12527 }
12528 $pbc = 0;
12529 if ($this->progressBar) { $this->UpdateProgressBar(1,0); } // *PROGRESS-BAR*
12530 $this->subPos = -1;
12531 $cnt = count($a);
12532 for($i=0;$i<$cnt; $i++) {
12533 $e = $a[$i];
12534 if($i%2==0) {
12535 //TEXT
12536 if ($this->blk[$this->blklvl]['hide']) { continue; }
12537 if ($this->inlineDisplayOff) { continue; }
12538
12539 if ($this->inFixedPosBlock) { $this->fixedPosBlock .= $e; continue; } // *CSS-POSITION*
12540 if (strlen($e) == 0) { continue; }
12541
12542 $e = strcode2utf($e);
12543 $e = $this->lesser_entity_decode($e);
12544
12545 if ($this->usingCoreFont) {
12546 // mPDF 5.3.22
12547 // If core font is selected in document which is not onlyCoreFonts - substitute with non-core font
12548 if ($this->useSubstitutions && !$this->onlyCoreFonts && $this->subPos<$i && !$this->specialcontent) {
12549 $cnt += $this->SubstituteCharsNonCore($a, $i, $e);
12550 }
12551 // CONVERT ENCODING
12552 $e = mb_convert_encoding($e,$this->mb_enc,'UTF-8');
12553 if ($this->toupper) { $e = strtoupper($e); }
12554 if ($this->tolower) { $e = strtolower($e); }
12555 if ($this->capitalize) { $e = ucwords($e); }
12556 }
12557 // mPDF 5.3.21
12558 else {
12559 if ($this->checkSIP && $this->CurrentFont['sipext'] && $this->subPos<$i && !$this->specialcontent) {
12560 $cnt += $this->SubstituteCharsSIP($a, $i, $e);
12561 }
12562 if ($this->useSubstitutions && !$this->onlyCoreFonts && $this->CurrentFont['type']!='Type0' && $this->subPos<$i && !$this->specialcontent) {
12563 $cnt += $this->SubstituteCharsMB($a, $i, $e);
12564 }
12565 if ($this->biDirectional) { // *RTL*
12566 $e = preg_replace("/([".$this->pregRTLchars."]+)/ue", '$this->ArabJoin(stripslashes(\'\\1\'))', $e); // *RTL*
12567 } // *RTL*
12568 // Font-specific ligature substitution for Indic fonts
12569 if (isset($this->CurrentFont['indic']) && $this->CurrentFont['indic']) $this->ConvertIndic($e); // *INDIC*
12570
12571 if ($this->toupper) { $e = mb_strtoupper($e,$this->mb_enc); }
12572 if ($this->tolower) { $e = mb_strtolower($e,$this->mb_enc); }
12573 if ($this->capitalize) { $e = mb_convert_case($e, MB_CASE_TITLE, "UTF-8"); }
12574 }
12575 if (($this->tts) || ($this->ttz) || ($this->tta)) {
12576 $es = explode('|',$e);
12577 $e = '';
12578 foreach($es AS $val) {
12579 $e .= chr($val);
12580 }
12581 }
12582 //Adjust lineheight
12583
12584 // FORM ELEMENTS
12585 if ($this->specialcontent) {
12586 /*-- FORMS --*/
12587 //SELECT tag (form element)
12588 if ($this->specialcontent == "type=select") {
12589 $e = ltrim($e);
12590 $stringwidth = $this->GetStringWidth($e);
12591 if (!isset($this->selectoption['MAXWIDTH']) || $stringwidth > $this->selectoption['MAXWIDTH']) { $this->selectoption['MAXWIDTH'] = $stringwidth; }
12592 if (!isset($this->selectoption['SELECTED']) || $this->selectoption['SELECTED'] == '') { $this->selectoption['SELECTED'] = $e; }
12593 // mPDD 1.4 Active Forms
12594 if (isset($this->selectoption['ACTIVE']) && $this->selectoption['ACTIVE']) {
12595 $this->selectoption['ITEMS'][]=array('exportValue'=>$this->selectoption['currentVAL'], 'content'=>$e, 'selected'=>$this->selectoption['currentSEL']);
12596 }
12597 }
12598 // TEXTAREA
12599 else {
12600 $objattr = unserialize($this->specialcontent);
12601 $objattr['text'] = $e;
12602 $te = "\xbb\xa4\xactype=textarea,objattr=".serialize($objattr)."\xbb\xa4\xac";
12603 if ($this->tdbegin) {
12604 $this->_saveCellTextBuffer($te, $this->HREF); // mPDF 5.3.99
12605 }
12606 else {
12607 $this->_saveTextBuffer($te, $this->HREF); // mPDF 5.3.99
12608 }
12609 }
12610 /*-- END FORMS --*/
12611 }
12612
12613 // TABLE
12614 else if ($this->tableLevel) {
12615 /*-- TABLES --*/
12616 if ($this->tdbegin) {
12617 if (($this->ignorefollowingspaces) && !$this->ispre) { $e = ltrim($e); }
12618 if ($e || $e==='0') {
12619 if (($this->blockjustfinished || $this->listjustfinished) && $this->cell[$this->row][$this->col]['s']>0) {
12620 $this->_saveCellTextBuffer("\n"); // mPDF 5.3.99
12621 if (!isset($this->cell[$this->row][$this->col]['maxs'])) {
12622 $this->cell[$this->row][$this->col]['maxs'] = $this->cell[$this->row][$this->col]['s'];
12623 }
12624 elseif($this->cell[$this->row][$this->col]['maxs'] < $this->cell[$this->row][$this->col]['s']) {
12625 $this->cell[$this->row][$this->col]['maxs'] = $this->cell[$this->row][$this->col]['s'];
12626 }
12627 $this->cell[$this->row][$this->col]['s'] = 0;// reset
12628 }
12629 $this->blockjustfinished=false;
12630 $this->listjustfinished=false;
12631
12632 // mPDF 5.3.76
12633 $this->_saveCellTextBuffer($e, $this->HREF); // mPDF 5.3.99
12634
12635 if (!isset($this->cell[$this->row][$this->col]['R']) || !$this->cell[$this->row][$this->col]['R']) {
12636 if (isset($this->cell[$this->row][$this->col]['s'])) {
12637 $this->cell[$this->row][$this->col]['s'] += $this->GetStringWidth($e, false);
12638 }
12639 else { $this->cell[$this->row][$this->col]['s'] = $this->GetStringWidth($e, false); }
12640 // mPDF 5.3.61
12641 if (!empty($this->spanborddet)) {
12642 $this->cell[$this->row][$this->col]['s'] += $this->spanborddet['L']['w'] + $this->spanborddet['R']['w'];
12643 }
12644 }
12645
12646 if ($this->checkCJK && preg_match("/([".$this->pregCJKchars."])/u", $e)) { $this->tableCJK = true; } // *CJK-FONTS*
12647
12648 if ($this->tableLevel==1 && $this->useGraphs) {
12649 $this->graphs[$this->currentGraphId]['data'][$this->row][$this->col] = $e;
12650 }
12651 $this->nestedtablejustfinished = false;
12652 $this->linebreakjustfinished=false;
12653 }
12654 }
12655 /*-- END TABLES --*/
12656 }
12657 // ALL ELSE
12658 else {
12659 if ($this->ignorefollowingspaces and !$this->ispre) { $e = ltrim($e); }
12660 if ($e || $e==='0') $this->_saveTextBuffer($e, $this->HREF); // mPDF 5.3.99
12661 }
12662 }
12663
12664
12665 else { // TAG **
12666
12667 if($e[0]=='/') {
12668 /*-- PROGRESS-BAR --*/
12669 if ($this->progressBar) { // 10% increments
12670 if (intval($i*10/$cnt) != $pbc) { $pbc = intval($i*10/$cnt); $this->UpdateProgressBar(1,$pbc*10,$tag); }
12671 }
12672 /*-- END PROGRESS-BAR --*/
12673
12674
12675 // Check for tags where HTML specifies optional end tags,
12676 // and/or does not allow nesting e.g. P inside P, or
12677 $endtag = strtoupper(substr($e,1));
12678 if($this->blk[$this->blklvl]['hide']) {
12679 if (in_array($endtag, $this->outerblocktags) || in_array($endtag, $this->innerblocktags)) {
12680 unset($this->blk[$this->blklvl]);
12681 $this->blklvl--;
12682 }
12683 continue;
12684 }
12685
12686 /*-- CSS-POSITION --*/
12687 if ($this->inFixedPosBlock) {
12688 if (in_array($endtag, $this->outerblocktags) || in_array($endtag, $this->innerblocktags)) { $this->fixedPosBlockDepth--; }
12689 if ($this->fixedPosBlockDepth == 0) {
12690 $this->fixedPosBlockSave[] = array($this->fixedPosBlock, $this->fixedPosBlockBBox, $this->page);
12691 $this->fixedPosBlock = '';
12692 $this->inFixedPosBlock = false;
12693 continue;
12694 }
12695 $this->fixedPosBlock .= '<'.$e.'>';
12696 continue;
12697 }
12698 /*-- END CSS-POSITION --*/
12699 if ($this->allow_html_optional_endtags && !$parseonly) {
12700 if (($endtag == 'DIV' || $endtag =='FORM' || $endtag =='CENTER') && $this->lastoptionaltag == 'P') { $this->CloseTag($this->lastoptionaltag ); }
12701 if ($this->lastoptionaltag == 'LI' && $endtag == 'OL') { $this->CloseTag($this->lastoptionaltag ); }
12702 if ($this->lastoptionaltag == 'LI' && $endtag == 'UL') { $this->CloseTag($this->lastoptionaltag ); }
12703 if ($this->lastoptionaltag == 'DD' && $endtag == 'DL') { $this->CloseTag($this->lastoptionaltag ); }
12704 if ($this->lastoptionaltag == 'DT' && $endtag == 'DL') { $this->CloseTag($this->lastoptionaltag ); }
12705 if ($this->lastoptionaltag == 'OPTION' && $endtag == 'SELECT') { $this->CloseTag($this->lastoptionaltag ); }
12706 /*-- TABLES --*/
12707 if ($endtag == 'TABLE') {
12708 if ($this->lastoptionaltag == 'THEAD' || $this->lastoptionaltag == 'TBODY' || $this->lastoptionaltag == 'TFOOT') {
12709 $this->CloseTag($this->lastoptionaltag);
12710 }
12711 if ($this->lastoptionaltag == 'TR') { $this->CloseTag('TR'); }
12712 if ($this->lastoptionaltag == 'TD' || $this->lastoptionaltag == 'TH') { $this->CloseTag($this->lastoptionaltag ); $this->CloseTag('TR'); }
12713 }
12714 if ($endtag == 'THEAD' || $endtag == 'TBODY' || $endtag == 'TFOOT') {
12715 if ($this->lastoptionaltag == 'TR') { $this->CloseTag('TR'); }
12716 if ($this->lastoptionaltag == 'TD' || $this->lastoptionaltag == 'TH') { $this->CloseTag($this->lastoptionaltag ); $this->CloseTag('TR'); }
12717 }
12718 if ($endtag == 'TR') {
12719 if ($this->lastoptionaltag == 'TD' || $this->lastoptionaltag == 'TH') { $this->CloseTag($this->lastoptionaltag ); }
12720 }
12721 /*-- END TABLES --*/
12722 }
12723 $this->CloseTag($endtag);
12724 }
12725
12726 else { // OPENING TAG
12727 if($this->blk[$this->blklvl]['hide']) {
12728 if (strpos($e,' ')) { $te = strtoupper(substr($e,0,strpos($e,' '))); }
12729 else { $te = strtoupper($e); }
12730 if (in_array($te, $this->outerblocktags) || in_array($te, $this->innerblocktags)) {
12731 $this->blklvl++;
12732 $this->blk[$this->blklvl]['hide']=true;
12733 }
12734 continue;
12735 }
12736
12737 /*-- CSS-POSITION --*/
12738 if ($this->inFixedPosBlock) {
12739 if (strpos($e,' ')) { $te = strtoupper(substr($e,0,strpos($e,' '))); }
12740 else { $te = strtoupper($e); }
12741 $this->fixedPosBlock .= '<'.$e.'>';
12742 if (in_array($te, $this->outerblocktags) || in_array($te, $this->innerblocktags)) { $this->fixedPosBlockDepth++; }
12743 continue;
12744 }
12745 /*-- END CSS-POSITION --*/
12746 $regexp = '|=\'(.*?)\'|s'; // eliminate single quotes, if any
12747 $e = preg_replace($regexp,"=\"\$1\"",$e);
12748 // changes anykey=anyvalue to anykey="anyvalue" (only do this inside tags)
12749 if (substr($e,0,10)!='pageheader' && substr($e,0,10)!='pagefooter') {
12750 $regexp = '| (\\w+?)=([^\\s>"]+)|si';
12751 $e = preg_replace($regexp," \$1=\"\$2\"",$e);
12752 }
12753
12754 $e = preg_replace('/ (\\S+?)\s*=\s*"/i', " \\1=\"", $e);
12755
12756 //Fix path values, if needed
12757 $orig_srcpath = '';
12758 if ((stristr($e,"href=") !== false) or (stristr($e,"src=") !== false) ) {
12759 $regexp = '/ (href|src)\s*=\s*"(.*?)"/i';
12760 preg_match($regexp,$e,$auxiliararray);
12761 if (isset($auxiliararray[2])) { $path = $auxiliararray[2]; }
12762 else { $path = ''; }
12763 if (trim($path) != '' && !(stristr($e,"src=") !== false && substr($path,0,4)=='var:')) {
12764 $orig_srcpath = $path;
12765 $this->GetFullPath($path);
12766 $regexp = '/ (href|src)="(.*?)"/i';
12767 $e = preg_replace($regexp,' \\1="'.$path.'"',$e);
12768 }
12769 }//END of Fix path values
12770
12771
12772 //Extract attributes
12773 $contents=array();
12774 // Changed to allow style="background: url('bg.jpg')"
12775 preg_match_all('/\\S*=["][^"]*["]/',$e,$contents1);
12776 preg_match_all('/\\S*=[\'][^\']*[\']/',$e,$contents2);
12777 $contents = array_merge($contents1, $contents2);
12778 preg_match('/\\S+/',$e,$a2);
12779 $tag=strtoupper($a2[0]);
12780 $attr=array();
12781 if ($orig_srcpath) { $attr['ORIG_SRC'] = $orig_srcpath; }
12782 if (!empty($contents)) {
12783 foreach($contents[0] as $v) {
12784 // Changed to allow style="background: url('bg.jpg')"
12785 if(preg_match('/^([^=]*)=["]?([^"]*)["]?$/',$v,$a3) || preg_match('/^([^=]*)=[\']?([^\']*)[\']?$/',$v,$a3)) {
12786 if (strtoupper($a3[1])=='ID' || strtoupper($a3[1])=='CLASS') { // 4.2.013 Omits STYLE
12787 $attr[strtoupper($a3[1])]=trim(strtoupper($a3[2]));
12788 }
12789 // includes header-style-right etc. used for <pageheader>
12790 else if (preg_match('/^(HEADER|FOOTER)-STYLE/i',$a3[1])) {
12791 $attr[strtoupper($a3[1])]=trim(strtoupper($a3[2]));
12792 }
12793 else {
12794 $attr[strtoupper($a3[1])]=trim($a3[2]);
12795 }
12796 }
12797 }
12798 }
12799 $this->OpenTag($tag,$attr);
12800 /*-- CSS-POSITION --*/
12801 if ($this->inFixedPosBlock) {
12802 $this->fixedPosBlockBBox = array($tag,$attr, $this->x, $this->y);
12803 $this->fixedPosBlock = '';
12804 $this->fixedPosBlockDepth = 1;
12805 }
12806 /*-- END CSS-POSITION --*/
12807 }
12808
12809 } // end TAG
12810 } //end of foreach($a as $i=>$e)
12811
12812 if ($close) {
12813
12814 // Close any open block tags
12815 for ($b= $this->blklvl;$b>0;$b--) { $this->CloseTag($this->blk[$b]['tag']); }
12816
12817 // Output any text left in buffer
12818 if (count($this->textbuffer) && !$parseonly) { $this->printbuffer($this->textbuffer); }
12819 if (!$parseonly) $this->textbuffer=array();
12820
12821 /*-- CSS-FLOAT --*/
12822 // If ended with a float, need to move to end page
12823 $currpos = $this->page*1000 + $this->y;
12824 if (isset($this->blk[$this->blklvl]['float_endpos']) && $this->blk[$this->blklvl]['float_endpos'] > $currpos) {
12825 $old_page = $this->page;
12826 $new_page = intval($this->blk[$this->blklvl]['float_endpos'] /1000);
12827 if ($old_page != $new_page) {
12828 $s = $this->PrintPageBackgrounds();
12829 // Writes after the marker so not overwritten later by page background etc.
12830 $this->pages[$this->page] = preg_replace('/(___BACKGROUND___PATTERNS'.date('jY').')/', '\\1'."\n".$s."\n", $this->pages[$this->page]);
12831 $this->pageBackgrounds = array();
12832 $this->page = $new_page;
12833 $this->ResetMargins();
12834 $this->Reset();
12835 $this->pageoutput[$this->page] = array();
12836 }
12837 $this->y = (($this->blk[$this->blklvl]['float_endpos'] *1000) % 1000000)/1000; // mod changes operands to integers before processing
12838 }
12839 /*-- END CSS-FLOAT --*/
12840
12841 /*-- CSS-IMAGE-FLOAT --*/
12842 $this->printfloatbuffer();
12843 /*-- END CSS-IMAGE-FLOAT --*/
12844
12845 //Create Internal Links, if needed
12846 if (!empty($this->internallink) ) {
12847 foreach($this->internallink as $k=>$v) {
12848 if (strpos($k,"#") !== false ) { continue; } //ignore
12849 $ypos = $v['Y'];
12850 $pagenum = $v['PAGE'];
12851 $sharp = "#";
12852 while (array_key_exists($sharp.$k,$this->internallink)) {
12853 $internallink = $this->internallink[$sharp.$k];
12854 $this->SetLink($internallink,$ypos,$pagenum);
12855 $sharp .= "#";
12856 }
12857 }
12858 }
12859
12860 $this->linemaxfontsize = '';
12861 $this->lineheight_correction = $this->default_lineheight_correction;
12862
12863 $this->bufferoutput = false;
12864
12865 /*-- CSS-POSITION --*/
12866 if (count($this->fixedPosBlockSave) && $sub != 4) {
12867 foreach($this->fixedPosBlockSave AS $fpbs) {
12868 $old_page = $this->page;
12869 $this->page = $fpbs[2];
12870 $this->WriteFixedPosHTML($fpbs[0], 0, 0, 100, 100,'auto', $fpbs[1]); // 0,0,10,10 are overwritten by bbox
12871 $this->page = $old_page;
12872 }
12873 }
12874 /*-- END CSS-POSITION --*/
12875
12876 }
12877 }
12878
12879 /*-- CSS-POSITION --*/
12880
12881 function WriteFixedPosHTML($html='',$x, $y, $w, $h, $overflow='visible', $bounding=array()) {
12882 // $overflow can be 'hidden', 'visible' or 'auto' - 'auto' causes autofit to size
12883 // Annotations disabled - enabled in mPDF 5.0
12884 // Links do work
12885 // Will always go on current page (or start Page 1 if required)
12886 // Probably INCOMPATIBLE WITH keep with table, columns etc.
12887 // Called externally or interally via <div style="position: [fixed|absolute]">
12888 // When used internally, $x $y $w $h and $overflow are all overridden by $bounding
12889
12890 $overflow = strtolower($overflow);
12891 if($this->state==0) {
12892 $this->AddPage($this->CurOrientation);
12893 }
12894 $save_y = $this->y;
12895 $save_x = $this->x;
12896 $this->fullImageHeight = $this->h;
12897 $save_cols = false;
12898 /*-- COLUMNS --*/
12899 if ($this->ColActive) {
12900 $save_cols = true;
12901 $save_nbcol = $this->NbCol; // other values of gap and vAlign will not change by setting Columns off
12902 $this->SetColumns(0);
12903 }
12904 /*-- END COLUMNS --*/
12905 $save_annots = $this->title2annots; // *ANNOTATIONS*
12906 $this->writingHTMLheader = true; // a FIX to stop pagebreaks etc.
12907 $this->writingHTMLfooter = true;
12908 $this->InFooter = true; // suppresses autopagebreaks
12909 $save_bgs = $this->pageBackgrounds;
12910 $checkinnerhtml = preg_replace('/\s/','',$html);
12911
12912 if ($w > $this->w) { $x = 0; $w = $this->w; }
12913 if ($h > $this->h) { $y = 0; $h = $this->h; }
12914 if ($x > $this->w) { $x = $this->w - $w; }
12915 if ($y > $this->h) { $y = $this->h - $h; }
12916
12917 if (!empty($bounding)) {
12918 // $cont_ containing block = full physical page (position: absolute) or page inside margins (position: fixed)
12919 // $bbox_ Bounding box is the <div> which is positioned absolutely/fixed
12920 // top/left/right/bottom/width/height/background*/border*/padding*/margin* are taken from bounding
12921 // font*[family/size/style/weight]/line-height/text*[align/decoration/transform/indent]/color are transferred to $inner
12922 // as an enclosing <div> (after having checked ID/CLASS)
12923 // $x, $y, $w, $h are inside of $bbox_ = containing box for $inner_
12924 // $inner_ InnerHTML is the contents of that block to be output
12925 $tag = $bounding[0];
12926 $attr = $bounding[1];
12927 $orig_x0 = $bounding[2];
12928 $orig_y0 = $bounding[3];
12929
12930 // As in WriteHTML() initialising
12931 $this->blklvl = 0;
12932 $this->lastblocklevelchange = 0;
12933 $this->blk = array();
12934 $this->initialiseBlock($this->blk[0]);
12935
12936 $this->blk[0]['width'] =& $this->pgwidth;
12937 $this->blk[0]['inner_width'] =& $this->pgwidth;
12938
12939 $this->blk[0]['blockContext'] = $this->blockContext;
12940
12941 $properties = $this->MergeCSS('BLOCK','BODY','');
12942 $this->setCSS($properties,'','BODY');
12943 $this->blklvl = 1;
12944 $this->initialiseBlock($this->blk[1]);
12945 $this->blk[1]['tag'] = $tag;
12946 $this->blk[1]['attr'] = $attr;
12947 $this->Reset();
12948 $p = $this->MergeCSS('BLOCK',$tag,$attr);
12949 if (isset($p['ROTATE']) && ($p['ROTATE']==90 || $p['ROTATE']==-90)) { $rotate = $p['ROTATE']; }
12950 else { $rotate = 0; }
12951 if (isset($p['OVERFLOW'])) { $overflow = strtolower($p['OVERFLOW']); }
12952 if (strtolower($p['POSITION']) == 'fixed') {
12953 $cont_w = $this->pgwidth; // $this->blk[0]['inner_width'];
12954 $cont_h = $this->h - $this->tMargin - $this->bMargin;
12955 $cont_x = $this->lMargin;
12956 $cont_y = $this->tMargin;
12957 }
12958 else {
12959 $cont_w = $this->w; // ABSOLUTE;
12960 $cont_h = $this->h;
12961 $cont_x = 0;
12962 $cont_y = 0;
12963 }
12964
12965 // Pass on in-line properties to the innerhtml
12966 $css = '';
12967 if (isset($p['TEXT-ALIGN'])) { $css .= 'text-align: '.strtolower($p['TEXT-ALIGN']).'; '; }
12968 if (isset($p['TEXT-TRANSFORM'])) { $css .= 'text-transform: '.strtolower($p['TEXT-TRANSFORM']).'; '; }
12969 if (isset($p['TEXT-INDENT'])) { $css .= 'text-indent: '.strtolower($p['TEXT-INDENT']).'; '; }
12970 if (isset($p['TEXT-DECORATION'])) { $css .= 'text-decoration: '.strtolower($p['TEXT-DECORATION']).'; '; }
12971 if (isset($p['FONT-FAMILY'])) { $css .= 'font-family: '.strtolower($p['FONT-FAMILY']).'; '; }
12972 if (isset($p['FONT-STYLE'])) { $css .= 'font-style: '.strtolower($p['FONT-STYLE']).'; '; }
12973 if (isset($p['FONT-WEIGHT'])) { $css .= 'font-weight: '.strtolower($p['FONT-WEIGHT']).'; '; }
12974 if (isset($p['FONT-SIZE'])) { $css .= 'font-size: '.strtolower($p['FONT-SIZE']).'; '; }
12975 if (isset($p['LINE-HEIGHT'])) { $css .= 'line-height: '.strtolower($p['LINE-HEIGHT']).'; '; }
12976 if (isset($p['TEXT-ALIGN'])) { $css .= 'text-align: '.strtolower($p['TEXT-ALIGN']).'; '; }
12977 if (isset($p['TEXT-SHADOW'])) { $css .= 'text-shadow: '.strtolower($p['TEXT-SHADOW']).'; '; } // mPDF 5.3.A4
12978 if (isset($p['FONT-VARIANT'])) { $css .= 'font-variant: '.strtolower($p['FONT-VARIANT']).'; '; }
12979 if (isset($p['COLOR'])) { $css .= 'color: '.strtolower($p['COLOR']).'; '; }
12980 if ($css) {
12981 $html = '<div style="'.$css.'">'.$html.'</div>';
12982 }
12983 // Copy over (only) the properties to set for border and background
12984 $pb = array();
12985 $pb['MARGIN-TOP'] = $p['MARGIN-TOP'];
12986 $pb['MARGIN-RIGHT'] = $p['MARGIN-RIGHT'];
12987 $pb['MARGIN-BOTTOM'] = $p['MARGIN-BOTTOM'];
12988 $pb['MARGIN-LEFT'] = $p['MARGIN-LEFT'];
12989 $pb['PADDING-TOP'] = $p['PADDING-TOP'];
12990 $pb['PADDING-RIGHT'] = $p['PADDING-RIGHT'];
12991 $pb['PADDING-BOTTOM'] = $p['PADDING-BOTTOM'];
12992 $pb['PADDING-LEFT'] = $p['PADDING-LEFT'];
12993 $pb['BORDER-TOP'] = $p['BORDER-TOP'];
12994 $pb['BORDER-RIGHT'] = $p['BORDER-RIGHT'];
12995 $pb['BORDER-BOTTOM'] = $p['BORDER-BOTTOM'];
12996 $pb['BORDER-LEFT'] = $p['BORDER-LEFT'];
12997 // mPDF 5.3.66
12998 $pb['BORDER-TOP-LEFT-RADIUS-H'] = $p['BORDER-TOP-LEFT-RADIUS-H'];
12999 $pb['BORDER-TOP-LEFT-RADIUS-V'] = $p['BORDER-TOP-LEFT-RADIUS-V'];
13000 $pb['BORDER-TOP-RIGHT-RADIUS-H'] = $p['BORDER-TOP-RIGHT-RADIUS-H'];
13001 $pb['BORDER-TOP-RIGHT-RADIUS-V'] = $p['BORDER-TOP-RIGHT-RADIUS-V'];
13002 $pb['BORDER-BOTTOM-LEFT-RADIUS-H'] = $p['BORDER-BOTTOM-LEFT-RADIUS-H'];
13003 $pb['BORDER-BOTTOM-LEFT-RADIUS-V'] = $p['BORDER-BOTTOM-LEFT-RADIUS-V'];
13004 $pb['BORDER-BOTTOM-RIGHT-RADIUS-H'] = $p['BORDER-BOTTOM-RIGHT-RADIUS-H'];
13005 $pb['BORDER-BOTTOM-RIGHT-RADIUS-V'] = $p['BORDER-BOTTOM-RIGHT-RADIUS-V'];
13006 if (isset($p['BACKGROUND-COLOR'])) { $pb['BACKGROUND-COLOR'] = $p['BACKGROUND-COLOR']; }
13007 if (isset($p['BOX-SHADOW'])) { $pb['BOX-SHADOW'] = $p['BOX-SHADOW']; } // mPDF 5.3.A4
13008 /*-- BACKGROUNDS --*/
13009 if (isset($p['BACKGROUND-IMAGE'])) { $pb['BACKGROUND-IMAGE'] = $p['BACKGROUND-IMAGE']; }
13010 if (isset($p['BACKGROUND-IMAGE-RESIZE'])) { $pb['BACKGROUND-IMAGE-RESIZE'] = $p['BACKGROUND-IMAGE-RESIZE']; }
13011 if (isset($p['BACKGROUND-IMAGE-OPACITY'])) { $pb['BACKGROUND-IMAGE-OPACITY'] = $p['BACKGROUND-IMAGE-OPACITY']; }
13012 if (isset($p['BACKGROUND-REPEAT'])) { $pb['BACKGROUND-REPEAT'] = $p['BACKGROUND-REPEAT']; }
13013 if (isset($p['BACKGROUND-POSITION'])) { $pb['BACKGROUND-POSITION'] = $p['BACKGROUND-POSITION']; }
13014 if (isset($p['BACKGROUND-GRADIENT'])) { $pb['BACKGROUND-GRADIENT'] = $p['BACKGROUND-GRADIENT']; }
13015 /*-- END BACKGROUNDS --*/
13016
13017 $this->setCSS($pb,'BLOCK',$tag);
13018
13019 //================================================================
13020 $bbox_br = $this->blk[1]['border_right']['w'];
13021 $bbox_bl = $this->blk[1]['border_left']['w'];
13022 $bbox_bt = $this->blk[1]['border_top']['w'];
13023 $bbox_bb = $this->blk[1]['border_bottom']['w'];
13024 $bbox_pr = $this->blk[1]['padding_right'];
13025 $bbox_pl = $this->blk[1]['padding_left'];
13026 $bbox_pt = $this->blk[1]['padding_top'];
13027 $bbox_pb = $this->blk[1]['padding_bottom'];
13028 $bbox_mr = $this->blk[1]['margin_right'];
13029 if (strtolower($p['MARGIN-RIGHT'])=='auto') { $bbox_mr = 'auto'; }
13030 $bbox_ml = $this->blk[1]['margin_left'];
13031 if (strtolower($p['MARGIN-LEFT'])=='auto') { $bbox_ml = 'auto'; }
13032 $bbox_mt = $this->blk[1]['margin_top'];
13033 if (strtolower($p['MARGIN-TOP'])=='auto') { $bbox_mt = 'auto'; }
13034 $bbox_mb = $this->blk[1]['margin_bottom'];
13035 if (strtolower($p['MARGIN-BOTTOM'])=='auto') { $bbox_mb = 'auto'; }
13036 if (isset($p['LEFT']) && strtolower($p['LEFT'])!='auto') { $bbox_left = $this->ConvertSize($p['LEFT'], $cont_w, $this->FontSize,false); }
13037 else { $bbox_left = 'auto'; }
13038 if (isset($p['TOP']) && strtolower($p['TOP'])!='auto') { $bbox_top = $this->ConvertSize($p['TOP'], $cont_h, $this->FontSize,false); }
13039 else { $bbox_top = 'auto'; }
13040 if (isset($p['RIGHT']) && strtolower($p['RIGHT'])!='auto') { $bbox_right = $this->ConvertSize($p['RIGHT'], $cont_w, $this->FontSize,false); }
13041 else { $bbox_right = 'auto'; }
13042 if (isset($p['BOTTOM']) && strtolower($p['BOTTOM'])!='auto') { $bbox_bottom = $this->ConvertSize($p['BOTTOM'], $cont_h, $this->FontSize,false); }
13043 else { $bbox_bottom = 'auto'; }
13044 if (isset($p['WIDTH']) && strtolower($p['WIDTH'])!='auto') { $inner_w = $this->ConvertSize($p['WIDTH'], $cont_w, $this->FontSize,false); }
13045 else { $inner_w = 'auto'; }
13046 if (isset($p['HEIGHT']) && strtolower($p['HEIGHT'])!='auto') { $inner_h = $this->ConvertSize($p['HEIGHT'], $cont_h, $this->FontSize,false); }
13047 else { $inner_h = 'auto'; }
13048
13049 // If bottom or right pos are set and not left / top - save this to adjust rotated block later
13050 if ($rotate) {
13051 if ($bbox_left === 'auto' && $bbox_right !== 'auto') { $rot_rpos = $bbox_right; }
13052 else { $rot_rpos = false; }
13053 if ($bbox_top === 'auto' && $bbox_bottom !== 'auto') { $rot_bpos = $bbox_bottom; }
13054 else { $rot_bpos = false; }
13055 }
13056
13057 //================================================================
13058 if ($checkinnerhtml=='' && $inner_h==='auto') { $inner_h = 0.0001; }
13059 if ($checkinnerhtml=='' && $inner_w==='auto') { $inner_w = 2*$this->GetCharWidth('W',false); } // mPDF 5.3.04
13060 //================================================================
13061 // Algorithm from CSS2.1 See http://www.w3.org/TR/CSS21/visudet.html#abs-non-replaced-height
13062 // mPD 5.3.14
13063 // Special case (not CSS) if all not specified, centre vertically on page
13064 if ($bbox_top==='auto' && $inner_h==='auto' && $bbox_bottom==='auto' && $bbox_mt==='auto' && $bbox_mb==='auto') {
13065 $bbox_top_orig = $bbox_top;
13066 if ($bbox_mt==='auto') { $bbox_mt = 0; }
13067 if ($bbox_mb==='auto') { $bbox_mb = 0; }
13068 $bbox_top = $orig_y0 - $bbox_mt - $cont_y;
13069 // solve for $bbox_bottom when content_h known - $inner_h=='auto' && $bbox_bottom=='auto'
13070 }
13071 // mPD 5.3.14
13072 else if ($bbox_top==='auto' && $inner_h==='auto' && $bbox_bottom==='auto') {
13073 $bbox_top_orig = $bbox_top = $orig_y0 - $cont_y;
13074 if ($bbox_mt==='auto') { $bbox_mt = 0; }
13075 if ($bbox_mb==='auto') { $bbox_mb = 0; }
13076 // solve for $bbox_bottom when content_h known - $inner_h=='auto' && $bbox_bottom=='auto'
13077 }
13078 else if ($bbox_top!=='auto' && $inner_h!=='auto' && $bbox_bottom!=='auto') {
13079 if ($bbox_mt==='auto' && $bbox_mb==='auto') {
13080 $x = $cont_h - $bbox_top - $bbox_bt - $bbox_pt - $inner_h - $bbox_pb - $bbox_bb - $bbox_bottom;
13081 $bbox_mt = $bbox_mb = ($x/2);
13082 }
13083 else if ($bbox_mt==='auto') {
13084 $bbox_mt = $cont_h - $bbox_top - $bbox_bt - $bbox_pt - $inner_h - $bbox_pb - $bbox_bb - $bbox_mb - $bbox_bottom;
13085 }
13086 else if ($bbox_mb==='auto') {
13087 $bbox_mb = $cont_h - $bbox_top - $bbox_mt - $bbox_bt - $bbox_pt - $inner_h - $bbox_pb - $bbox_bb - $bbox_bottom;
13088 }
13089 else {
13090 $bbox_bottom = $cont_h - $bbox_top - $bbox_mt - $bbox_bt - $bbox_pt - $inner_h - $bbox_pb - $bbox_bb - $bbox_mt;
13091 }
13092 }
13093 else {
13094 if ($bbox_mt==='auto') { $bbox_mt = 0; }
13095 if ($bbox_mb==='auto') { $bbox_mb = 0; }
13096 if ($bbox_top==='auto' && $inner_h==='auto' && $bbox_bottom!=='auto') {
13097 // solve for $bbox_top when content_h known - $inner_h=='auto' && $bbox_top =='auto'
13098 }
13099 else if ($bbox_top==='auto' && $bbox_bottom==='auto' && $inner_h!=='auto') {
13100 $bbox_top = $orig_y0 - $bbox_mt - $cont_y;
13101 $bbox_bottom = $cont_h - $bbox_top - $bbox_mt - $bbox_bt - $bbox_pt - $inner_h - $bbox_pb - $bbox_bb - $bbox_mt;
13102 }
13103 else if ($inner_h==='auto' && $bbox_bottom==='auto' && $bbox_top!=='auto') {
13104 // solve for $bbox_bottom when content_h known - $inner_h=='auto' && $bbox_bottom=='auto'
13105 }
13106 else if ($bbox_top==='auto' && $inner_h!=='auto' && $bbox_bottom!=='auto') {
13107 $bbox_top = $cont_h - $bbox_mt - $bbox_bt - $bbox_pt - $inner_h - $bbox_pb - $bbox_bb - $bbox_mt - $bbox_bottom;
13108 }
13109 else if ($inner_h==='auto' && $bbox_top!=='auto' && $bbox_bottom!=='auto') {
13110 $inner_h = $cont_h - $bbox_top - $bbox_mt - $bbox_bt - $bbox_pt - $bbox_pb - $bbox_bb - $bbox_mt - $bbox_bottom;
13111 }
13112 else if ($bbox_bottom==='auto' && $bbox_top!=='auto' && $inner_h!=='auto') {
13113 $bbox_bottom = $cont_h - $bbox_top - $bbox_mt - $bbox_bt - $bbox_pt - $inner_h - $bbox_pb - $bbox_bb - $bbox_mt;
13114 }
13115 }
13116
13117 // THEN DO SAME FOR WIDTH
13118 // http://www.w3.org/TR/CSS21/visudet.html#abs-non-replaced-width
13119 if ($bbox_left==='auto' && $inner_w==='auto' && $bbox_right==='auto') {
13120 if ($bbox_ml==='auto') { $bbox_ml = 0; }
13121 if ($bbox_mr==='auto') { $bbox_mr = 0; }
13122 // IF containing element RTL, should set $bbox_right
13123 $bbox_left = $orig_x0 - $bbox_ml - $cont_x;
13124 // solve for $bbox_right when content_w known - $inner_w=='auto' && $bbox_right=='auto'
13125 }
13126 else if ($bbox_left!=='auto' && $inner_w!=='auto' && $bbox_right!=='auto') {
13127 if ($bbox_ml==='auto' && $bbox_mr==='auto') {
13128 $x = $cont_w - $bbox_left - $bbox_bl - $bbox_pl - $inner_w - $bbox_pr - $bbox_br - $bbox_right;
13129 $bbox_ml = $bbox_mr = ($x/2);
13130 }
13131 else if ($bbox_ml==='auto') {
13132 $bbox_ml = $cont_w - $bbox_left - $bbox_bl - $bbox_pl - $inner_w - $bbox_pr - $bbox_br - $bbox_mr - $bbox_right;
13133 }
13134 else if ($bbox_mr==='auto') {
13135 $bbox_mr = $cont_w - $bbox_left - $bbox_ml - $bbox_bl - $bbox_pl - $inner_w - $bbox_pr - $bbox_br - $bbox_right;
13136 }
13137 else {
13138 $bbox_right = $cont_w - $bbox_left - $bbox_ml - $bbox_bl - $bbox_pl - $inner_w - $bbox_pr - $bbox_br - $bbox_ml;
13139 }
13140 }
13141 else {
13142 if ($bbox_ml==='auto') { $bbox_ml = 0; }
13143 if ($bbox_mr==='auto') { $bbox_mr = 0; }
13144 if ($bbox_left==='auto' && $inner_w==='auto' && $bbox_right!=='auto') {
13145 // solve for $bbox_left when content_w known - $inner_w=='auto' && $bbox_left =='auto'
13146 }
13147 else if ($bbox_left==='auto' && $bbox_right==='auto' && $inner_w!=='auto') {
13148 // IF containing element RTL, should set $bbox_right
13149 $bbox_left = $orig_x0 - $bbox_ml - $cont_x;
13150 $bbox_right = $cont_w - $bbox_left - $bbox_ml - $bbox_bl - $bbox_pl - $inner_w - $bbox_pr - $bbox_br - $bbox_ml;
13151 }
13152 else if ($inner_w==='auto' && $bbox_right==='auto' && $bbox_left!=='auto') {
13153 // solve for $bbox_right when content_w known - $inner_w=='auto' && $bbox_right=='auto'
13154 }
13155 else if ($bbox_left==='auto' && $inner_w!=='auto' && $bbox_right!=='auto') {
13156 $bbox_left = $cont_w - $bbox_ml - $bbox_bl - $bbox_pl - $inner_w - $bbox_pr - $bbox_br - $bbox_ml - $bbox_right;
13157 }
13158 else if ($inner_w==='auto' && $bbox_left!=='auto' && $bbox_right!=='auto') {
13159 $inner_w = $cont_w - $bbox_left - $bbox_ml - $bbox_bl - $bbox_pl - $bbox_pr - $bbox_br - $bbox_ml - $bbox_right;
13160 }
13161 else if ($bbox_right==='auto' && $bbox_left!=='auto' && $inner_w!=='auto') {
13162 $bbox_right = $cont_w - $bbox_left - $bbox_ml - $bbox_bl - $bbox_pl - $inner_w - $bbox_pr - $bbox_br - $bbox_ml;
13163 }
13164 }
13165
13166 //================================================================
13167 //================================================================
13168 /*-- BACKGROUNDS --*/
13169 if (isset($pb['BACKGROUND-IMAGE']) && $pb['BACKGROUND-IMAGE']) {
13170 $ret = $this->SetBackground($pb, $this->blk[1]['inner_width']);
13171 if ($ret) { $this->blk[1]['background-image'] = $ret; }
13172 }
13173 /*-- END BACKGROUNDS --*/
13174
13175 //================================================================
13176 $y = $cont_y + $bbox_top + $bbox_mt + $bbox_bt + $bbox_pt;
13177 $h = $cont_h - $bbox_top - $bbox_mt - $bbox_bt - $bbox_pt - $bbox_pb - $bbox_bb - $bbox_mb - $bbox_bottom;
13178 $x = $cont_x + $bbox_left + $bbox_ml + $bbox_bl + $bbox_pl;
13179 $w = $cont_w - $bbox_left - $bbox_ml - $bbox_bl - $bbox_pl - $bbox_pr - $bbox_br - $bbox_mr - $bbox_right;
13180 // Set (temporary) values for x y w h to do first paint, if values are auto
13181 if ($inner_h==='auto' && $bbox_top==='auto') {
13182 $y = $cont_y + $bbox_mt + $bbox_bt + $bbox_pt;
13183 $h = $cont_h - ($bbox_bottom + $bbox_mt + $bbox_mb + $bbox_bt + $bbox_bb + $bbox_pt + $bbox_pb);
13184 }
13185 else if ($inner_h==='auto' && $bbox_bottom==='auto') {
13186 $y = $cont_y + $bbox_top + $bbox_mt + $bbox_bt + $bbox_pt;
13187 $h = $cont_h - ($bbox_top + $bbox_mt + $bbox_mb + $bbox_bt + $bbox_bb + $bbox_pt + $bbox_pb);
13188 }
13189 if ($inner_w==='auto' && $bbox_left==='auto') {
13190 $x = $cont_x + $bbox_ml + $bbox_bl + $bbox_pl;
13191 $w = $cont_w - ($bbox_right + $bbox_ml + $bbox_mr + $bbox_bl + $bbox_br + $bbox_pl + $bbox_pr);
13192 }
13193 else if ($inner_w==='auto' && $bbox_right==='auto') {
13194 $x = $cont_x + $bbox_left + $bbox_ml + $bbox_bl + $bbox_pl;
13195 $w = $cont_w - ($bbox_left + $bbox_ml + $bbox_mr + $bbox_bl + $bbox_br + $bbox_pl + $bbox_pr);
13196 }
13197 $bbox_y = $cont_y + $bbox_top + $bbox_mt;
13198 $bbox_x = $cont_x + $bbox_left + $bbox_ml;
13199 $saved_block1 = $this->blk[1];
13200 unset($p);
13201 unset($pb);
13202 //================================================================
13203 if ($inner_w==='auto') { // do a first write
13204 $this->lMargin=$x;
13205 $this->rMargin=$this->w - $w - $x;
13206 // SET POSITION & FONT VALUES
13207 $this->pgwidth = $this->w - $this->lMargin - $this->rMargin;
13208 $this->pageoutput[$this->page]=array();
13209 $this->x = $x;
13210 $this->y = $y;
13211 $this->HTMLheaderPageLinks = array();
13212 $this->HTMLheaderPageAnnots = array();
13213 $this->HTMLheaderPageForms = array();
13214 $this->pageBackgrounds = array();
13215 $this->maxPosR = 0;
13216 $this->maxPosL = $this->w; // For RTL
13217 $this->WriteHTML($html , 4);
13218 $inner_w = $this->maxPosR - $this->lMargin;
13219 if ($bbox_right==='auto') {
13220 $bbox_right = $cont_w - $bbox_left - $bbox_ml - $bbox_bl - $bbox_pl - $inner_w - $bbox_pr - $bbox_br - $bbox_ml;
13221 }
13222 else if ($bbox_left==='auto') {
13223 $bbox_left = $cont_w - $bbox_ml - $bbox_bl - $bbox_pl - $inner_w - $bbox_pr - $bbox_br - $bbox_ml - $bbox_right;
13224 $bbox_x = $cont_x + $bbox_left + $bbox_ml ;
13225 $inner_x = $bbox_x + $bbox_bl + $bbox_pl;
13226 $x = $inner_x;
13227 }
13228 $w = $inner_w;
13229 $bbox_y = $cont_y + $bbox_top + $bbox_mt;
13230 $bbox_x = $cont_x + $bbox_left + $bbox_ml;
13231 }
13232
13233 if ($inner_h==='auto') { // do a first write
13234 $this->lMargin=$x;
13235 $this->rMargin=$this->w - $w - $x;
13236 // SET POSITION & FONT VALUES
13237 $this->pgwidth = $this->w - $this->lMargin - $this->rMargin;
13238 $this->pageoutput[$this->page]=array();
13239 $this->x = $x;
13240 $this->y = $y;
13241 $this->HTMLheaderPageLinks = array();
13242 $this->HTMLheaderPageAnnots = array();
13243 $this->HTMLheaderPageForms = array();
13244 $this->pageBackgrounds = array();
13245 $this->WriteHTML($html , 4);
13246 $inner_h = $this->y - $y;
13247 if ($overflow!='hidden' && $overflow!='visible') { // constrained
13248 if (($this->y + $bbox_pb + $bbox_bb) > ($cont_y + $cont_h)) {
13249 $adj = ($this->y + $bbox_pb + $bbox_bb) - ($cont_y + $cont_h);
13250 $inner_h -= $adj;
13251 }
13252 }
13253 if ($bbox_bottom==='auto' && $bbox_top_orig==='auto') {
13254 $bbox_bottom = $bbox_top = ($cont_h - $bbox_mt - $bbox_bt - $bbox_pt - $inner_h - $bbox_pb - $bbox_bb - $bbox_mb)/2;
13255 if ($overflow!='hidden' && $overflow!='visible') { // constrained
13256 if ($bbox_top < 0) {
13257 $bbox_top = 0;
13258 $inner_h = $cont_h - $bbox_top - $bbox_mt - $bbox_bt - $bbox_pt - $bbox_pb - $bbox_bb - $bbox_mb - $bbox_bottom;
13259 }
13260 }
13261 $bbox_y = $cont_y + $bbox_top + $bbox_mt;
13262 $inner_y = $bbox_y + $bbox_bt + $bbox_pt;
13263 $y = $inner_y;
13264
13265 }
13266 else if ($bbox_bottom==='auto') {
13267 $bbox_bottom = $cont_h - $bbox_top - $bbox_mt - $bbox_bt - $bbox_pt - $inner_h - $bbox_pb - $bbox_bb - $bbox_mb;
13268 }
13269 else if ($bbox_top==='auto') {
13270 $bbox_top = $cont_h - $bbox_mt - $bbox_bt - $bbox_pt - $inner_h - $bbox_pb - $bbox_bb - $bbox_mb - $bbox_bottom;
13271 if ($overflow!='hidden' && $overflow!='visible') { // constrained
13272 if ($bbox_top < 0) {
13273 $bbox_top = 0;
13274 $inner_h = $cont_h - $bbox_top - $bbox_mt - $bbox_bt - $bbox_pt - $bbox_pb - $bbox_bb - $bbox_mb - $bbox_bottom;
13275 }
13276 }
13277 $bbox_y = $cont_y + $bbox_top + $bbox_mt;
13278 $inner_y = $bbox_y + $bbox_bt + $bbox_pt;
13279 $y = $inner_y;
13280 }
13281 $h = $inner_h;
13282 $bbox_y = $cont_y + $bbox_top + $bbox_mt;
13283 $bbox_x = $cont_x + $bbox_left + $bbox_ml;
13284 }
13285 $inner_w = $w;
13286 $inner_h = $h;
13287
13288 }
13289
13290 $this->lMargin=$x;
13291 $this->rMargin=$this->w - $w - $x;
13292 // SET POSITION & FONT VALUES
13293 $this->pgwidth = $this->w - $this->lMargin - $this->rMargin;
13294 $this->pageoutput[$this->page]=array();
13295 $this->x = $x;
13296 $this->y = $y;
13297 $this->HTMLheaderPageLinks = array();
13298 $this->HTMLheaderPageAnnots = array();
13299 $this->HTMLheaderPageForms = array();
13300 $this->pageBackgrounds = array();
13301 $this->WriteHTML($html , 4); // parameter 4 saves output to $this->headerbuffer
13302 $actual_h = $this->y - $y;
13303 $use_w = $w;
13304 $use_h = $h;
13305 $ratio = $actual_h / $use_w;
13306
13307 if ($overflow!='hidden' && $overflow!='visible') {
13308 $target = $h/$w;
13309 if (($ratio / $target ) > 1) {
13310 $nl = CEIL($actual_h / $this->lineheight);
13311 $l = $use_w * $nl;
13312 $est_w = sqrt(($l * $this->lineheight) / $target) * 0.8;
13313 $use_w += ($est_w - $use_w) - ($w/100);
13314 }
13315 $bpcstart = ($ratio / $target);
13316 $bpcctr = 1;
13317 while(($ratio / $target ) > 1) {
13318
13319 if ($this->progressBar) { $this->UpdateProgressBar(4,intval(100/($ratio/$target)),('Auto-sizing fixed-position block: '.$bpcctr++)); } // *PROGRESS-BAR*
13320
13321 $this->x = $x;
13322 $this->y = $y;
13323
13324 if (($ratio / $target) > 1.5 || ($ratio / $target) < 0.6) {
13325 $use_w += ($w/$this->incrementFPR1);
13326 }
13327 else if (($ratio / $target) > 1.2 || ($ratio / $target) < 0.85) {
13328 $use_w += ($w/$this->incrementFPR2);
13329 }
13330 else if (($ratio / $target) > 1.1 || ($ratio / $target) < 0.91) {
13331 $use_w += ($w/$this->incrementFPR3);
13332 }
13333 else {
13334 $use_w += ($w/$this->incrementFPR4);
13335 }
13336
13337 $use_h = $use_w * $target ;
13338 $this->rMargin=$this->w - $use_w - $x;
13339 $this->pgwidth = $this->w - $this->lMargin - $this->rMargin;
13340 $this->HTMLheaderPageLinks = array();
13341 $this->HTMLheaderPageAnnots = array();
13342 $this->HTMLheaderPageForms = array();
13343 $this->pageBackgrounds = array();
13344 $this->WriteHTML($html , 4); // parameter 4 saves output to $this->headerbuffer
13345 $actual_h = $this->y - $y;
13346 $ratio = $actual_h / $use_w;
13347 }
13348 if ($this->progressBar) { $this->UpdateProgressBar(4,'100',' '); } // *PROGRESS-BAR*
13349 }
13350 $shrink_f = $w/$use_w;
13351
13352 //================================================================
13353
13354 $this->pages[$this->page] .= '___BEFORE_BORDERS___';
13355 $block_s = $this->PrintPageBackgrounds(); // Save to print later inside clipping path
13356 $this->pageBackgrounds = array();
13357
13358 //================================================================
13359
13360 if ($rotate) {
13361 $prerotw = $bbox_bl + $bbox_pl + $inner_w + $bbox_pr + $bbox_br;
13362 $preroth = $bbox_bt + $bbox_pt + $inner_h + $bbox_pb + $bbox_bb;
13363 $rot_start = " q\n";
13364 if ($rotate == 90) {
13365 if ($rot_rpos !== false) { $adjw = $prerotw; } // width before rotation
13366 else { $adjw = $preroth; } // height before rotation
13367 if ($rot_bpos !== false) { $adjh = -$prerotw + $preroth; }
13368 else { $adjh = 0; }
13369 }
13370 else {
13371 if ($rot_rpos !== false) { $adjw = $prerotw - $preroth; }
13372 else { $adjw = 0; }
13373 if ($rot_bpos !== false) { $adjh = $preroth; } // height before rotation
13374 else { $adjh = $prerotw; } // width before rotation
13375 }
13376 $rot_start .= $this->transformTranslate($adjw, $adjh, true)."\n";
13377 $rot_start .= $this->transformRotate($rotate, $bbox_x, $bbox_y, true)."\n";
13378 $rot_end = " Q\n";
13379 }
13380 else {
13381 $rot_start = '';
13382 $rot_end = '';
13383 }
13384
13385 //================================================================
13386 if (!empty($bounding)) {
13387 // WHEN HEIGHT // BOTTOM EDGE IS KNOWN and $this->y is set to the bottom
13388 // Re-instate saved $this->blk[1]
13389 $this->blk[1] = $saved_block1;
13390
13391 // These are only needed when painting border/background
13392 $this->blk[1]['width'] = $bbox_w = $cont_w - $bbox_left - $bbox_ml - $bbox_mr - $bbox_right;
13393 $this->blk[1]['x0'] = $bbox_x;
13394 $this->blk[1]['y0'] = $bbox_y;
13395 $this->blk[1]['startpage'] = $this->page;
13396 $this->blk[1]['y1'] = $bbox_y + $bbox_bt + $bbox_pt + $inner_h + $bbox_pb + $bbox_bb ;
13397 $this->_out($rot_start); // mPDF 5.0
13398 $this->PaintDivBB('',0,1); // Prints borders and sets backgrounds in $this->pageBackgrounds
13399 $this->_out($rot_end);
13400 }
13401
13402 $s = $this->PrintPageBackgrounds();
13403 $s = $rot_start.$s.$rot_end;
13404 $this->pages[$this->page] = preg_replace('/___BEFORE_BORDERS___/', "\n".$s."\n", $this->pages[$this->page]);
13405 $this->pageBackgrounds = array();
13406
13407 $this->_out($rot_start);
13408
13409 // Clipping Output
13410 if ($overflow=='hidden') {
13411 //Bounding rectangle to clip
13412 $clip_y1 = $this->y;
13413 if (!empty($bounding) && ($this->y + $bbox_pb + $bbox_bb) > ($bbox_y + $bbox_bt + $bbox_pt + $inner_h + $bbox_pb + $bbox_bb )) {
13414 $clip_y1 = ($bbox_y + $bbox_bt + $bbox_pt + $inner_h + $bbox_pb + $bbox_bb ) - ($bbox_pb + $bbox_bb);
13415 }
13416 //$op = 'W* n'; // Clipping
13417 $op = 'W n'; // Clipping alternative mode
13418 $this->_out("q");
13419 $ch = $clip_y1 - $y;
13420 $this->_out(sprintf('%.3F %.3F %.3F %.3F re %s',$x*_MPDFK,($this->h-$y)*_MPDFK,$w*_MPDFK,-$ch*_MPDFK,$op));
13421 if (!empty($block_s)) {
13422 $tmp = "q\n".sprintf('%.3F %.3F %.3F %.3F re %s',$x*_MPDFK,($this->h-$y)*_MPDFK,$w*_MPDFK,-$ch*_MPDFK,$op);
13423 $tmp .= "\n".$block_s."\nQ";
13424 $block_s = $tmp ;
13425 }
13426 }
13427
13428
13429 if (!empty($block_s)) {
13430 if ($shrink_f != 1) { // i.e. autofit has resized the box
13431 $tmp = "q\n".$this->transformScale(($shrink_f*100),($shrink_f*100), $x, $y, true);
13432 $tmp .= "\n".$block_s."\nQ";
13433 $block_s = $tmp ;
13434 }
13435 $this->_out($block_s);
13436 }
13437
13438
13439
13440 if ($shrink_f != 1) { // i.e. autofit has resized the box
13441 $this->StartTransform();
13442 $this->transformScale(($shrink_f*100),($shrink_f*100), $x, $y);
13443 }
13444
13445 $this->_out($this->headerbuffer);
13446
13447 if ($shrink_f != 1) { // i.e. autofit has resized the box
13448 $this->StopTransform();
13449 }
13450
13451 if ($overflow=='hidden') {
13452 //End clipping
13453 $this->_out("Q");
13454 }
13455
13456 $this->_out($rot_end);
13457
13458
13459 // Page Links
13460 foreach($this->HTMLheaderPageLinks AS $lk) {
13461 if ($rotate) {
13462 $tmp = $lk[2]; // Switch h - w
13463 $lk[2] = $lk[3];
13464 $lk[3] = $tmp;
13465
13466 $lx1 = (($lk[0]/_MPDFK));
13467 $ly1 = (($this->h-($lk[1]/_MPDFK)));
13468 if ($rotate == 90) {
13469 $adjx = -($lx1-$bbox_x) + ($preroth - ($ly1-$bbox_y));
13470 $adjy = -($ly1-$bbox_y) + ($lx1-$bbox_x);
13471 $lk[2] = -$lk[2];
13472 }
13473 else if ($rotate == -90) {
13474 $adjx = -($lx1-$bbox_x) + ($ly1-$bbox_y);
13475 $adjy = -($ly1-$bbox_y) - ($lx1-$bbox_x) + $prerotw;
13476 $lk[3] = -$lk[3];
13477 }
13478 if ($rot_rpos !== false) { $adjx += $prerotw - $preroth; }
13479 if ($rot_bpos !== false) { $adjy += $preroth - $prerotw; }
13480 $lx1 += $adjx;
13481 $ly1 += $adjy;
13482
13483 $lk[0] = $lx1*_MPDFK;
13484 $lk[1] = ($this->h-$ly1)*_MPDFK;
13485 }
13486 if ($shrink_f != 1) { // i.e. autofit has resized the box
13487 $lx1 = (($lk[0]/_MPDFK)-$x);
13488 $lx2 = $x + ($lx1 * $shrink_f);
13489 $lk[0] = $lx2*_MPDFK;
13490 $ly1 = (($this->h-($lk[1]/_MPDFK))-$y);
13491 $ly2 = $y + ($ly1 * $shrink_f);
13492 $lk[1] = ($this->h-$ly2)*_MPDFK;
13493 $lk[2] *= $shrink_f; // width
13494 $lk[3] *= $shrink_f; // height
13495 }
13496 $this->PageLinks[$this->page][]=$lk;
13497 }
13498
13499 foreach($this->HTMLheaderPageForms AS $n=>$f) {
13500 if ($shrink_f != 1) { // i.e. autofit has resized the box
13501 $f['x'] = $x + (($f['x'] -$x) * $shrink_f);
13502 $f['y'] = $y + (($f['y'] -$y) * $shrink_f);
13503 $f['w'] *= $shrink_f;
13504 $f['h'] *= $shrink_f;
13505 $f['style']['fontsize'] *= $shrink_f;
13506 }
13507 $this->form->forms[$f['n']] = $f;
13508 }
13509 // Page Annotations
13510 foreach($this->HTMLheaderPageAnnots AS $lk) {
13511 if ($rotate) {
13512 if ($rotate == 90) {
13513 $adjx = -($lk['x']-$bbox_x) + ($preroth - ($lk['y']-$bbox_y));
13514 $adjy = -($lk['y']-$bbox_y) + ($lk['x']-$bbox_x);
13515 }
13516 else if ($rotate == -90) {
13517 $adjx = -($lk['x']-$bbox_x) + ($lk['y']-$bbox_y);
13518 $adjy = -($lk['y']-$bbox_y) - ($lk['x']-$bbox_x) + $prerotw;
13519 }
13520 if ($rot_rpos !== false) { $adjx += $prerotw - $preroth; }
13521 if ($rot_bpos !== false) { $adjy += $preroth - $prerotw; }
13522 $lk['x'] += $adjx;
13523 $lk['y'] += $adjy;
13524 }
13525 if ($shrink_f != 1) { // i.e. autofit has resized the box
13526 $lk['x'] = $x + (($lk['x']-$x) * $shrink_f);
13527 $lk['y'] = $y + (($lk['y']-$y) * $shrink_f);
13528 }
13529 $this->PageAnnots[$this->page][]=$lk;
13530 }
13531
13532 // Restore
13533 $this->headerbuffer = '';
13534 $this->HTMLheaderPageLinks = array();
13535 $this->HTMLheaderPageAnnots = array();
13536 $this->HTMLheaderPageForms = array();
13537 $this->pageBackgrounds = $save_bgs;
13538 $this->writingHTMLheader = false;
13539
13540 $this->writingHTMLfooter = false;
13541 $this->fullImageHeight = false;
13542 $this->ResetMargins();
13543 $this->pgwidth = $this->w - $this->lMargin - $this->rMargin;
13544 $this->SetXY($save_x,$save_y) ;
13545 $this->title2annots = $save_annots; // *ANNOTATIONS*
13546 $this->InFooter = false; // turns back on autopagebreaks
13547 $this->pageoutput[$this->page]=array();
13548 $this->pageoutput[$this->page]['Font']='';
13549 /*-- COLUMNS --*/
13550 if ($save_cols) {
13551 $this->SetColumns($save_nbcol,$this->colvAlign,$this->ColGap);
13552 }
13553 /*-- END COLUMNS --*/
13554 }
13555 /*-- END CSS-POSITION --*/
13556
13557
13558
13559 function initialiseBlock(&$blk) {
13560 $blk['margin_top'] = 0;
13561 $blk['margin_left'] = 0;
13562 $blk['margin_bottom'] = 0;
13563 $blk['margin_right'] = 0;
13564 $blk['padding_top'] = 0;
13565 $blk['padding_left'] = 0;
13566 $blk['padding_bottom'] = 0;
13567 $blk['padding_right'] = 0;
13568 $blk['border_top']['w'] = 0;
13569 $blk['border_left']['w'] = 0;
13570 $blk['border_bottom']['w'] = 0;
13571 $blk['border_right']['w'] = 0;
13572 $blk['hide'] = false;
13573 $blk['outer_left_margin'] = 0;
13574 $blk['outer_right_margin'] = 0;
13575 $blk['cascadeCSS'] = array();
13576 $blk['block-align'] = false;
13577 $blk['bgcolor'] = false;
13578 $blk['page_break_after_avoid'] = false;
13579 $blk['keep_block_together'] = false;
13580 $blk['float'] = false;
13581 $blk['line_height'] = '';
13582 $blk['margin_collapse'] = false;
13583 }
13584
13585
13586 function border_details($bd) {
13587 $prop = preg_split('/\s+/',trim($bd));
13588
13589 if (isset($this->blk[$this->blklvl]['inner_width'])) { $refw = $this->blk[$this->blklvl]['inner_width']; }
13590 else if (isset($this->blk[$this->blklvl-1]['inner_width'])) { $refw = $this->blk[$this->blklvl-1]['inner_width']; }
13591 else { $refw = $this->w; }
13592 if ( count($prop) == 1 ) {
13593 $bsize = $this->ConvertSize($prop[0],$refw,$this->FontSize,false);
13594 if ($bsize > 0) {
13595 return array('s' => 1, 'w' => $bsize, 'c' => $this->ConvertColor(0), 'style'=>'solid');
13596 }
13597 else { return array('w' => 0, 's' => 0); }
13598 }
13599
13600 else if (count($prop) == 2 ) {
13601 // 1px solid
13602 if (in_array($prop[1],$this->borderstyles) || $prop[1] == 'none' || $prop[1] == 'hidden' ) { $prop[2] = ''; }
13603 // solid #000000
13604 else if (in_array($prop[0],$this->borderstyles) || $prop[0] == 'none' || $prop[0] == 'hidden' ) { $prop[0] = ''; $prop[1] = $prop[0]; $prop[2] = $prop[1]; }
13605 // 1px #000000
13606 else { $prop[1] = ''; $prop[2] = $prop[1]; }
13607 }
13608 else if ( count($prop) == 3 ) {
13609 // Change #000000 1px solid to 1px solid #000000 (proper)
13610 if (substr($prop[0],0,1) == '#') { $tmp = $prop[0]; $prop[0] = $prop[1]; $prop[1] = $prop[2]; $prop[2] = $tmp; }
13611 // Change solid #000000 1px to 1px solid #000000 (proper)
13612 else if (substr($prop[0],1,1) == '#') { $tmp = $prop[1]; $prop[0] = $prop[2]; $prop[1] = $prop[0]; $prop[2] = $tmp; }
13613 // Change solid 1px #000000 to 1px solid #000000 (proper)
13614 else if (in_array($prop[0],$this->borderstyles) || $prop[0] == 'none' || $prop[0] == 'hidden' ) {
13615 $tmp = $prop[0]; $prop[0] = $prop[1]; $prop[1] = $tmp;
13616 }
13617 }
13618 else { return array(); }
13619 // Size
13620 $bsize = $this->ConvertSize($prop[0],$refw,$this->FontSize,false);
13621 //color
13622 $coul = $this->ConvertColor($prop[2]); // returns array
13623 // Style
13624 $prop[1] = strtolower($prop[1]);
13625 if (in_array($prop[1],$this->borderstyles) && $bsize > 0) { $on = 1; }
13626 else if ($prop[1] == 'hidden') { $on = 1; $bsize = 0; $coul = ''; }
13627 else if ($prop[1] == 'none') { $on = 0; $bsize = 0; $coul = ''; }
13628 else { $on = 0; $bsize = 0; $coul = ''; $prop[1] = ''; }
13629 return array('s' => $on, 'w' => $bsize, 'c' => $coul, 'style'=> $prop[1] );
13630 }
13631
13632
13633 function _fix_borderStr($bd) {
13634 $prop = preg_split('/\s+/',trim($bd));
13635 $w = 'medium';
13636 $c = '#000000';
13637 $s = 'none';
13638
13639 if ( count($prop) == 1 ) {
13640 // solid
13641 if (in_array($prop[0],$this->borderstyles) || $prop[0] == 'none' || $prop[0] == 'hidden' ) { $s = $prop[0]; }
13642 // #000000
13643 else if (is_array($this->ConvertColor($prop[0]))) { $c = $prop[0]; }
13644 // 1px
13645 else { $w = $prop[0]; }
13646 }
13647 else if (count($prop) == 2 ) {
13648 // 1px solid
13649 if (in_array($prop[1],$this->borderstyles) || $prop[1] == 'none' || $prop[1] == 'hidden' ) { $w = $prop[0]; $s = $prop[1]; }
13650 // solid #000000
13651 else if (in_array($prop[0],$this->borderstyles) || $prop[0] == 'none' || $prop[0] == 'hidden' ) { $s = $prop[0]; $c = $prop[1]; }
13652 // 1px #000000
13653 else { $w = $prop[0]; $c = $prop[1]; }
13654 }
13655 else if ( count($prop) == 3 ) {
13656 // Change #000000 1px solid to 1px solid #000000 (proper)
13657 if (substr($prop[0],0,1) == '#') { $c = $prop[0]; $w = $prop[1]; $s = $prop[2]; }
13658 // Change solid #000000 1px to 1px solid #000000 (proper)
13659 else if (substr($prop[0],1,1) == '#') { $s = $prop[0]; $c = $prop[1]; $w = $prop[2]; }
13660 // Change solid 1px #000000 to 1px solid #000000 (proper)
13661 else if (in_array($prop[0],$this->borderstyles) || $prop[0] == 'none' || $prop[0] == 'hidden' ) {
13662 $s = $prop[0]; $w = $prop[1]; $c = $prop[2];
13663 }
13664 else { $w = $prop[0]; $s = $prop[1]; $c = $prop[2]; }
13665 }
13666 else { return ''; }
13667 $s = strtolower($s);
13668 return $w.' '.$s.' '.$c;
13669 }
13670
13671
13672
13673 // NEW FUNCTION FOR CSS MARGIN or PADDING called from SetCSS
13674 function fixCSS($prop) {
13675 if (!is_array($prop) || (count($prop)==0)) return array();
13676 $newprop = array();
13677 foreach($prop AS $k => $v) {
13678 if ($k != 'BACKGROUND-IMAGE' && $k != 'BACKGROUND' && $k != 'ODD-HEADER-NAME' && $k != 'EVEN-HEADER-NAME' && $k != 'ODD-FOOTER-NAME' && $k != 'EVEN-FOOTER-NAME' && $k != 'HEADER' && $k != 'FOOTER') {
13679 $v = strtolower($v);
13680 }
13681
13682 if ($k == 'FONT') {
13683 $s = trim($v);
13684 preg_match_all('/\"(.*?)\"/',$s,$ff);
13685 if (count($ff[1])) {
13686 foreach($ff[1] AS $ffp) {
13687 $w = preg_split('/\s+/',$ffp);
13688 $s = preg_replace('/\"'.$ffp.'\"/',$w[0],$s);
13689 }
13690 }
13691 preg_match_all('/\'(.*?)\'/',$s,$ff);
13692 if (count($ff[1])) {
13693 foreach($ff[1] AS $ffp) {
13694 $w = preg_split('/\s+/',$ffp);
13695 $s = preg_replace('/\''.$ffp.'\'/',$w[0],$s);
13696 }
13697 }
13698 $s = preg_replace('/\s*,\s*/',',',$s);
13699 $bits = preg_split('/\s+/',$s);
13700 if (count($bits)>1) {
13701 $k = 'FONT-FAMILY'; $v = $bits[(count($bits)-1)];
13702 $fs = $bits[(count($bits)-2)];
13703 if (preg_match('/(.*?)\/(.*)/',$fs, $fsp)) {
13704 $newprop['FONT-SIZE'] = $fsp[1];
13705 $newprop['LINE-HEIGHT'] = $fsp[2];
13706 }
13707 else { $newprop['FONT-SIZE'] = $fs; }
13708 if (preg_match('/(italic|oblique)/i',$s)) { $newprop['FONT-STYLE'] = 'italic'; }
13709 else { $newprop['FONT-STYLE'] = 'normal'; }
13710 if (preg_match('/bold/i',$s)) { $newprop['FONT-WEIGHT'] = 'bold'; }
13711 else { $newprop['FONT-WEIGHT'] = 'normal'; }
13712 if (preg_match('/small-caps/i',$s)) { $newprop['TEXT-TRANSFORM'] = 'uppercase'; }
13713 }
13714 }
13715 if ($k == 'FONT-FAMILY') {
13716 $aux_fontlist = explode(",",$v);
13717 $found = 0;
13718 foreach($aux_fontlist AS $f) {
13719 $fonttype = trim($f);
13720 $fonttype = preg_replace('/["\']*(.*?)["\']*/','\\1',$fonttype);
13721 $fonttype = preg_replace('/ /','',$fonttype);
13722 $v = strtolower(trim($fonttype));
13723 if (isset($this->fonttrans[$v]) && $this->fonttrans[$v]) { $v = $this->fonttrans[$v]; }
13724 if ((!$this->onlyCoreFonts && in_array($v,$this->available_unifonts)) ||
13725 in_array($v,array('ccourier','ctimes','chelvetica')) || /* mPDF 5.3.21 & 22 */
13726 ($this->onlyCoreFonts && in_array($v,array('courier','times','helvetica','arial'))) ||
13727 in_array($v, array('sjis','uhc','big5','gb'))) {
13728 $newprop[$k] = $v;
13729 $found = 1;
13730 break;
13731 }
13732 }
13733 if (!$found) {
13734 foreach($aux_fontlist AS $f) {
13735 $fonttype = trim($f);
13736 $fonttype = preg_replace('/["\']*(.*?)["\']*/','\\1',$fonttype);
13737 $fonttype = preg_replace('/ /','',$fonttype);
13738 $v = strtolower(trim($fonttype));
13739 if (isset($this->fonttrans[$v]) && $this->fonttrans[$v]) { $v = $this->fonttrans[$v]; }
13740 if (in_array($v,$this->sans_fonts) || in_array($v,$this->serif_fonts) || in_array($v,$this->mono_fonts) ) {
13741 $newprop[$k] = $v;
13742 break;
13743 }
13744 }
13745 }
13746 }
13747 else if ($k == 'MARGIN') {
13748 $tmp = $this->expand24($v);
13749 $newprop['MARGIN-TOP'] = $tmp['T'];
13750 $newprop['MARGIN-RIGHT'] = $tmp['R'];
13751 $newprop['MARGIN-BOTTOM'] = $tmp['B'];
13752 $newprop['MARGIN-LEFT'] = $tmp['L'];
13753 }
13754 /*-- BORDER-RADIUS --*/
13755 else if ($k == 'BORDER-RADIUS' || $k == 'BORDER-TOP-LEFT-RADIUS' || $k == 'BORDER-TOP-RIGHT-RADIUS' || $k == 'BORDER-BOTTOM-LEFT-RADIUS' || $k == 'BORDER-BOTTOM-RIGHT-RADIUS') {
13756 $tmp = $this->border_radius_expand($v,$k);
13757 if (isset($tmp['TL-H'])) $newprop['BORDER-TOP-LEFT-RADIUS-H'] = $tmp['TL-H'];
13758 if (isset($tmp['TL-V'])) $newprop['BORDER-TOP-LEFT-RADIUS-V'] = $tmp['TL-V'];
13759 if (isset($tmp['TR-H'])) $newprop['BORDER-TOP-RIGHT-RADIUS-H'] = $tmp['TR-H'];
13760 if (isset($tmp['TR-V'])) $newprop['BORDER-TOP-RIGHT-RADIUS-V'] = $tmp['TR-V'];
13761 if (isset($tmp['BL-H'])) $newprop['BORDER-BOTTOM-LEFT-RADIUS-H'] = $tmp['BL-H'];
13762 if (isset($tmp['BL-V'])) $newprop['BORDER-BOTTOM-LEFT-RADIUS-V'] = $tmp['BL-V'];
13763 if (isset($tmp['BR-H'])) $newprop['BORDER-BOTTOM-RIGHT-RADIUS-H'] = $tmp['BR-H'];
13764 if (isset($tmp['BR-V'])) $newprop['BORDER-BOTTOM-RIGHT-RADIUS-V'] = $tmp['BR-V'];
13765 }
13766 /*-- END BORDER-RADIUS --*/
13767 else if ($k == 'PADDING') {
13768 $tmp = $this->expand24($v);
13769 $newprop['PADDING-TOP'] = $tmp['T'];
13770 $newprop['PADDING-RIGHT'] = $tmp['R'];
13771 $newprop['PADDING-BOTTOM'] = $tmp['B'];
13772 $newprop['PADDING-LEFT'] = $tmp['L'];
13773 }
13774 else if ($k == 'BORDER') {
13775 if ($v == '1') { $v = '1px solid #000000'; }
13776 else { $v = $this->_fix_borderStr($v); }
13777 $newprop['BORDER-TOP'] = $v;
13778 $newprop['BORDER-RIGHT'] = $v;
13779 $newprop['BORDER-BOTTOM'] = $v;
13780 $newprop['BORDER-LEFT'] = $v;
13781 }
13782 else if ($k == 'BORDER-TOP') {
13783 $newprop['BORDER-TOP'] = $this->_fix_borderStr($v);
13784 }
13785 else if ($k == 'BORDER-RIGHT') {
13786 $newprop['BORDER-RIGHT'] = $this->_fix_borderStr($v);
13787 }
13788 else if ($k == 'BORDER-BOTTOM') {
13789 $newprop['BORDER-BOTTOM'] = $this->_fix_borderStr($v);
13790 }
13791 else if ($k == 'BORDER-LEFT') {
13792 $newprop['BORDER-LEFT'] = $this->_fix_borderStr($v);
13793 }
13794 else if ($k == 'BORDER-STYLE') {
13795 $e = $this->expand24($v);
13796 $newprop['BORDER-TOP-STYLE'] = $e['T'];
13797 $newprop['BORDER-RIGHT-STYLE'] = $e['R'];
13798 $newprop['BORDER-BOTTOM-STYLE'] = $e['B'];
13799 $newprop['BORDER-LEFT-STYLE'] = $e['L'];
13800 }
13801 else if ($k == 'BORDER-WIDTH') {
13802 $e = $this->expand24($v);
13803 $newprop['BORDER-TOP-WIDTH'] = $e['T'];
13804 $newprop['BORDER-RIGHT-WIDTH'] = $e['R'];
13805 $newprop['BORDER-BOTTOM-WIDTH'] = $e['B'];
13806 $newprop['BORDER-LEFT-WIDTH'] = $e['L'];
13807 }
13808 else if ($k == 'BORDER-COLOR') {
13809 $e = $this->expand24($v);
13810 $newprop['BORDER-TOP-COLOR'] = $e['T'];
13811 $newprop['BORDER-RIGHT-COLOR'] = $e['R'];
13812 $newprop['BORDER-BOTTOM-COLOR'] = $e['B'];
13813 $newprop['BORDER-LEFT-COLOR'] = $e['L'];
13814 }
13815
13816 else if ($k == 'BORDER-SPACING') {
13817 $prop = preg_split('/\s+/',trim($v));
13818 if (count($prop) == 1 ) {
13819 $newprop['BORDER-SPACING-H'] = $prop[0];
13820 $newprop['BORDER-SPACING-V'] = $prop[0];
13821 }
13822 else if (count($prop) == 2 ) {
13823 $newprop['BORDER-SPACING-H'] = $prop[0];
13824 $newprop['BORDER-SPACING-V'] = $prop[1];
13825 }
13826 }
13827 else if ($k == 'SIZE') {
13828 $prop = preg_split('/\s+/',trim($v));
13829 if (preg_match('/(auto|portrait|landscape)/',$prop[0])) {
13830 $newprop['SIZE'] = strtoupper($prop[0]);
13831 }
13832 else if (count($prop) == 1 ) {
13833 $newprop['SIZE']['W'] = $this->ConvertSize($prop[0]);
13834 $newprop['SIZE']['H'] = $this->ConvertSize($prop[0]);
13835 }
13836 else if (count($prop) == 2 ) {
13837 $newprop['SIZE']['W'] = $this->ConvertSize($prop[0]);
13838 $newprop['SIZE']['H'] = $this->ConvertSize($prop[1]);
13839 }
13840 }
13841 else if ($k == 'SHEET-SIZE') {
13842 $prop = preg_split('/\s+/',trim($v));
13843 if (count($prop) == 2 ) {
13844 $newprop['SHEET-SIZE'] = array($this->ConvertSize($prop[0]), $this->ConvertSize($prop[1]));
13845 }
13846 else {
13847 if(preg_match('/([0-9a-zA-Z]*)-L/i',$v,$m)) { // e.g. A4-L = A$ landscape
13848 $ft = $this->_getPageFormat($m[1]);
13849 $format = array($ft[1],$ft[0]);
13850 }
13851 else { $format = $this->_getPageFormat($v); }
13852 if ($format) { $newprop['SHEET-SIZE'] = array($format[0]/_MPDFK, $format[1]/_MPDFK); }
13853 }
13854 }
13855 else if ($k == 'BACKGROUND') {
13856 $bg = $this->parseCSSbackground($v);
13857 if ($bg['c']) { $newprop['BACKGROUND-COLOR'] = $bg['c']; }
13858 else { $newprop['BACKGROUND-COLOR'] = 'transparent'; }
13859 /*-- BACKGROUNDS --*/
13860 if ($bg['i']) {
13861 $newprop['BACKGROUND-IMAGE'] = $bg['i'];
13862 if ($bg['r']) { $newprop['BACKGROUND-REPEAT'] = $bg['r']; }
13863 if ($bg['p']) { $newprop['BACKGROUND-POSITION'] = $bg['p']; }
13864 }
13865 else { $newprop['BACKGROUND-IMAGE'] = ''; }
13866 /*-- END BACKGROUNDS --*/
13867 }
13868 /*-- BACKGROUNDS --*/
13869 else if ($k == 'BACKGROUND-IMAGE') {
13870 if (preg_match('/(-moz-)*(repeating-)*(linear|radial)-gradient\(.*\)/i',$v,$m)) {
13871 $newprop['BACKGROUND-IMAGE'] = $m[0];
13872 continue;
13873 }
13874 if (preg_match('/url\([\'\"]{0,1}(.*?)[\'\"]{0,1}\)/i',$v,$m)) {
13875 $newprop['BACKGROUND-IMAGE'] = $m[1];
13876 }
13877
13878 else if (strtolower($v)=='none') { $newprop['BACKGROUND-IMAGE'] = ''; }
13879
13880 }
13881 else if ($k == 'BACKGROUND-REPEAT') {
13882 if (preg_match('/(repeat-x|repeat-y|no-repeat|repeat)/i',$v,$m)) {
13883 $newprop['BACKGROUND-REPEAT'] = strtolower($m[1]);
13884 }
13885 }
13886 else if ($k == 'BACKGROUND-POSITION') {
13887 $s = $v;
13888 $bits = preg_split('/\s+/',trim($s));
13889 // These should be Position x1 or x2
13890 if (count($bits)==1) {
13891 if (preg_match('/bottom/',$bits[0])) { $bg['p'] = '50% 100%'; }
13892 else if (preg_match('/top/',$bits[0])) { $bg['p'] = '50% 0%'; }
13893 else { $bg['p'] = $bits[0] . ' 50%'; }
13894 }
13895 else if (count($bits)==2) {
13896 // Can be either right center or center right
13897 if (preg_match('/(top|bottom)/',$bits[0]) || preg_match('/(left|right)/',$bits[1])) {
13898 $bg['p'] = $bits[1] . ' '.$bits[0];
13899 }
13900 else {
13901 $bg['p'] = $bits[0] . ' '.$bits[1];
13902 }
13903 }
13904 if ($bg['p']) {
13905 $bg['p'] = preg_replace('/(left|top)/','0%',$bg['p']);
13906 $bg['p'] = preg_replace('/(right|bottom)/','100%',$bg['p']);
13907 $bg['p'] = preg_replace('/(center)/','50%',$bg['p']);
13908 if (!preg_match('/[\-]{0,1}\d+(in|cm|mm|pt|pc|em|ex|px|%)* [\-]{0,1}\d+(in|cm|mm|pt|pc|em|ex|px|%)*/',$bg['p'])) {
13909 $bg['p'] = false;
13910 }
13911 }
13912 if ($bg['p']) { $newprop['BACKGROUND-POSITION'] = $bg['p']; }
13913 }
13914 /*-- END BACKGROUNDS --*/
13915 else if ($k == 'IMAGE-ORIENTATION') {
13916 if (preg_match('/([\-]*[0-9\.]+)(deg|grad|rad)/i',$v,$m)) {
13917 $angle = $m[1] + 0;
13918 if (strtolower($m[2])=='deg') { $angle = $angle; }
13919 else if (strtolower($m[2])=='grad') { $angle *= (360/400); }
13920 else if (strtolower($m[2])=='rad') { $angle = rad2deg($angle); }
13921 while($angle < 0) { $angle += 360; }
13922 $angle = ($angle % 360);
13923 $angle /= 90;
13924 $angle = round($angle) * 90;
13925 $newprop['IMAGE-ORIENTATION'] = $angle;
13926 }
13927 }
13928 else {
13929 $newprop[$k] = $v;
13930 }
13931 }
13932
13933 return $newprop;
13934 }
13935
13936 // mPDF 5.3.A1
13937 function setCSSboxshadow($v) {
13938 $sh = array();
13939 $c = preg_match_all('/(rgba|rgb|cmyka|cmyk|hsla|hsl)\(.*?\)/',$v,$x);
13940 for($i=0; $i<$c; $i++) {
13941 $col = preg_replace('/,/','*',$x[0][$i]);
13942 $v = preg_replace('/'.preg_quote($x[0][$i],'/').'/',$col,$v);
13943 }
13944 $ss = explode(',',$v);
13945 foreach ($ss AS $s) {
13946 $new = array('inset'=>false, 'blur'=>0, 'spread'=>0);
13947 if (preg_match('/inset/i',$s)) { $new['inset'] = true; $s = preg_replace('/\s*inset\s*/','',$s); }
13948 $p = explode(' ',trim($s));
13949 if (isset($p[0])) { $new['x'] = $this->ConvertSize(trim($p[0]),$this->blk[$this->blklvl-1]['inner_width'],$this->FontSize,false); }
13950 if (isset($p[1])) { $new['y'] = $this->ConvertSize(trim($p[1]),$this->blk[$this->blklvl-1]['inner_width'],$this->FontSize,false); }
13951 if (isset($p[2])) {
13952 if (preg_match('/^\s*[\.\-0-9]/',$p[2])) {
13953 $new['blur'] = $this->ConvertSize(trim($p[2]),$this->blk[$this->blklvl-1]['inner_width'],$this->FontSize,false);
13954 }
13955 else { $new['col'] = $this->ConvertColor(preg_replace('/\*/',',',$p[2])); }
13956 if (isset($p[3])) {
13957 if (preg_match('/^\s*[\.\-0-9]/',$p[3])) {
13958 $new['spread'] = $this->ConvertSize(trim($p[3]),$this->blk[$this->blklvl-1]['inner_width'],$this->FontSize,false);
13959 }
13960 else { $new['col'] = $this->ConvertColor(preg_replace('/\*/',',',$p[3])); }
13961 if (isset($p[4])) {
13962 $new['col'] = $this->ConvertColor(preg_replace('/\*/',',',$p[4]));
13963 }
13964 }
13965 }
13966 if (!$new['col']) { $new['col'] = $this->ConvertColor('#888888'); }
13967 if (isset($new['y'])) { array_unshift($sh, $new); }
13968 }
13969 return $sh;
13970 }
13971
13972 // mPDF 5.3.A2
13973 function setCSStextshadow($v) {
13974 $sh = array();
13975 $c = preg_match_all('/(rgba|rgb|cmyka|cmyk|hsla|hsl)\(.*?\)/',$v,$x);
13976 for($i=0; $i<$c; $i++) {
13977 $col = preg_replace('/,/','*',$x[0][$i]);
13978 $v = preg_replace('/'.preg_quote($x[0][$i],'/').'/',$col,$v);
13979 }
13980 $ss = explode(',',$v);
13981 foreach ($ss AS $s) {
13982 $new = array('blur'=>0);
13983 $p = explode(' ',trim($s));
13984 if (isset($p[0])) { $new['x'] = $this->ConvertSize(trim($p[0]),$this->blk[$this->blklvl-1]['inner_width'],$this->FontSize,false); }
13985 if (isset($p[1])) { $new['y'] = $this->ConvertSize(trim($p[1]),$this->blk[$this->blklvl-1]['inner_width'],$this->FontSize,false); }
13986 if (isset($p[2])) {
13987 if (preg_match('/^\s*[\.\-0-9]/',$p[2])) {
13988 $new['blur'] = $this->ConvertSize(trim($p[2]),$this->blk[$this->blklvl-1]['inner_width'],$this->FontSize,false);
13989 }
13990 else { $new['col'] = $this->ConvertColor(preg_replace('/\*/',',',$p[2])); }
13991 if (isset($p[3])) {
13992 $new['col'] = $this->ConvertColor(preg_replace('/\*/',',',$p[3]));
13993 }
13994 }
13995 if (!$new['col']) { $new['col'] = $this->ConvertColor('#888888'); }
13996 if (isset($new['y'])) { array_unshift($sh, $new); }
13997 }
13998 return $sh;
13999 }
14000
14001 function parseCSSbackground($s) {
14002 $bg = array('c'=>false, 'i'=>false, 'r'=>false, 'p'=>false, );
14003 /*-- BACKGROUNDS --*/
14004 if (preg_match('/(-moz-)*(repeating-)*(linear|radial)-gradient\(.*\)/i',$s,$m)) {
14005 $bg['i'] = $m[0];
14006 }
14007 else
14008 /*-- END BACKGROUNDS --*/
14009 if (preg_match('/url\(/i',$s)) {
14010 // If color, set and strip it off
14011 if (preg_match('/^\s*(#[0-9a-fA-F]{3,6}|(rgba|rgb|cmyka|cmyk|hsla|hsl|spot)\(.*?\)|[a-zA-Z]{3,})\s+(url\(.*)/i',$s,$m)) { // mPDF 5.3.68
14012 $bg['c'] = strtolower($m[1]);
14013 $s = $m[3]; // mPDF 5.3.74
14014 }
14015 /*-- BACKGROUNDS --*/
14016 if (preg_match('/url\([\'\"]{0,1}(.*?)[\'\"]{0,1}\)\s*(.*)/i',$s,$m)) {
14017 $bg['i'] = $m[1];
14018 $s = strtolower($m[2]);
14019 if (preg_match('/(repeat-x|repeat-y|no-repeat|repeat)/',$s,$m)) {
14020 $bg['r'] = $m[1];
14021 }
14022 // Remove repeat, attachment (discarded) and also any inherit
14023 $s = preg_replace('/(repeat-x|repeat-y|no-repeat|repeat|scroll|fixed|inherit)/','',$s);
14024 $bits = preg_split('/\s+/',trim($s));
14025 // These should be Position x1 or x2
14026 if (count($bits)==1) {
14027 if (preg_match('/bottom/',$bits[0])) { $bg['p'] = '50% 100%'; }
14028 else if (preg_match('/top/',$bits[0])) { $bg['p'] = '50% 0%'; }
14029 else { $bg['p'] = $bits[0] . ' 50%'; }
14030 }
14031 else if (count($bits)==2) {
14032 // Can be either right center or center right
14033 if (preg_match('/(top|bottom)/',$bits[0]) || preg_match('/(left|right)/',$bits[1])) {
14034 $bg['p'] = $bits[1] . ' '.$bits[0];
14035 }
14036 else {
14037 $bg['p'] = $bits[0] . ' '.$bits[1];
14038 }
14039 }
14040 if ($bg['p']) {
14041 $bg['p'] = preg_replace('/(left|top)/','0%',$bg['p']);
14042 $bg['p'] = preg_replace('/(right|bottom)/','100%',$bg['p']);
14043 $bg['p'] = preg_replace('/(center)/','50%',$bg['p']);
14044 if (!preg_match('/[\-]{0,1}\d+(in|cm|mm|pt|pc|em|ex|px|%)* [\-]{0,1}\d+(in|cm|mm|pt|pc|em|ex|px|%)*/',$bg['p'])) {
14045 $bg['p'] = false;
14046 }
14047 }
14048 }
14049 /*-- END BACKGROUNDS --*/
14050 }
14051 else if (preg_match('/^\s*(#[0-9a-fA-F]{3,6}|(rgba|rgb|cmyka|cmyk|hsla|hsl|spot)\(.*?\)|[a-zA-Z]{3,})/i',$s,$m)) { $bg['c'] = strtolower($m[1]); } // mPDF 5.3.68
14052 return ($bg);
14053 }
14054
14055
14056 function expand24($mp) {
14057 $prop = preg_split('/\s+/',trim($mp));
14058 if (count($prop) == 1 ) {
14059 return array('T' => $prop[0], 'R' => $prop[0], 'B' => $prop[0], 'L'=> $prop[0]);
14060 }
14061 if (count($prop) == 2 ) {
14062 return array('T' => $prop[0], 'R' => $prop[1], 'B' => $prop[0], 'L'=> $prop[1]);
14063 }
14064
14065 if (count($prop) == 3 ) {
14066 return array('T' => $prop[0], 'R' => $prop[1], 'B' => $prop[2], 'L'=> $prop[1]);
14067 }
14068 if (count($prop) == 4 ) {
14069 return array('T' => $prop[0], 'R' => $prop[1], 'B' => $prop[2], 'L'=> $prop[3]);
14070 }
14071 return array();
14072 }
14073
14074 /*-- BORDER-RADIUS --*/
14075 function border_radius_expand($val,$k) {
14076 $b = array();
14077 if ($k == 'BORDER-RADIUS') {
14078 $hv = explode('/',trim($val));
14079 $prop = preg_split('/\s+/',trim($hv[0]));
14080 if (count($prop)==1) {
14081 $b['TL-H'] = $b['TR-H'] = $b['BR-H'] = $b['BL-H'] = $prop[0];
14082 }
14083 else if (count($prop)==2) {
14084 $b['TL-H'] = $b['BR-H'] = $prop[0];
14085 $b['TR-H'] = $b['BL-H'] = $prop[1];
14086 }
14087 else if (count($prop)==3) {
14088 $b['TL-H'] = $prop[0];
14089 $b['TR-H'] = $b['BL-H'] = $prop[1];
14090 $b['BR-H'] = $prop[2];
14091 }
14092 else if (count($prop)==4) {
14093 $b['TL-H'] = $prop[0];
14094 $b['TR-H'] = $prop[1];
14095 $b['BR-H'] = $prop[2];
14096 $b['BL-H'] = $prop[3];
14097 }
14098 if (count($hv)==2) {
14099 $prop = preg_split('/\s+/',trim($hv[1]));
14100 if (count($prop)==1) {
14101 $b['TL-V'] = $b['TR-V'] = $b['BR-V'] = $b['BL-V'] = $prop[0];
14102 }
14103 else if (count($prop)==2) {
14104 $b['TL-V'] = $b['BR-V'] = $prop[0];
14105 $b['TR-V'] = $b['BL-V'] = $prop[1];
14106 }
14107 else if (count($prop)==3) {
14108 $b['TL-V'] = $prop[0];
14109 $b['TR-V'] = $b['BL-V'] = $prop[1];
14110 $b['BR-V'] = $prop[2];
14111 }
14112 else if (count($prop)==4) {
14113 $b['TL-V'] = $prop[0];
14114 $b['TR-V'] = $prop[1];
14115 $b['BR-V'] = $prop[2];
14116 $b['BL-V'] = $prop[3];
14117 }
14118 }
14119 else {
14120 $b['TL-V'] = $b['TL-H'];
14121 $b['TR-V'] = $b['TR-H'];
14122 $b['BL-V'] = $b['BL-H'];
14123 $b['BR-V'] = $b['BR-H'];
14124 }
14125 return $b;
14126 }
14127
14128 // Parse 2
14129 $h = 0;
14130 $v = 0;
14131 $prop = preg_split('/\s+/',trim($val));
14132 if (count($prop)==1) { $h = $v = $val; }
14133 else { $h = $prop[0]; $v = $prop[1]; }
14134 if ($h==0 || $v==0) { $h = $v = 0; }
14135 if ($k == 'BORDER-TOP-LEFT-RADIUS') {
14136 $b['TL-H'] = $h;
14137 $b['TL-V'] = $v;
14138 }
14139 else if ($k == 'BORDER-TOP-RIGHT-RADIUS') {
14140 $b['TR-H'] = $h;
14141 $b['TR-V'] = $v;
14142 }
14143 else if ($k == 'BORDER-BOTTOM-LEFT-RADIUS') {
14144 $b['BL-H'] = $h;
14145 $b['BL-V'] = $v;
14146 }
14147 else if ($k == 'BORDER-BOTTOM-RIGHT-RADIUS') {
14148 $b['BR-H'] = $h;
14149 $b['BR-V'] = $v;
14150 }
14151 return $b;
14152
14153 }
14154 /*-- END BORDER-RADIUS --*/
14155
14156
14157 /*-- END HTML-CSS --*/
14158
14159
14160 // Return either a number (factor) - based on current set fontsize (if % or em) - or exact lineheight (with 'mm' after it)
14161 function fixLineheight($v) {
14162 $lh = false;
14163 if (preg_match('/^[0-9\.,]*$/',$v) && $v >= 0) { return ($v + 0); }
14164 else if (strtoupper($v) == 'NORMAL') {
14165 return $this->normalLineheight;
14166 }
14167 else {
14168 $tlh = $this->ConvertSize($v,$this->FontSize,$this->FontSize,true);
14169 if ($tlh) { return ($tlh.'mm'); }
14170 }
14171 return $this->normalLineheight;
14172 }
14173
14174
14175 /*-- BORDER-RADIUS --*/
14176 function _borderPadding($a, $b, &$px, &$py) {
14177 // $px and py are padding long axis (x) and short axis (y)
14178 $added = 0; // extra padding
14179
14180 $x = $a-$px;
14181 $y = $b-$py;
14182 // Check if Falls within ellipse of border radius
14183 if ( ( (($x+$added)*($x+$added))/($a*$a) + (($y+$added)*($y+$added))/($b*$b) ) <=1 ) { return false; }
14184
14185 $t = atan2($y,$x);
14186
14187 $newx = $b / sqrt((($b*$b)/($a*$a)) + ( tan($t) * tan($t) ) );
14188 $newy = $a / sqrt((($a*$a)/($b*$b)) + ( (1/tan($t)) * (1/tan($t)) ) );
14189 $px = max($px, $a - $newx + $added);
14190 $py = max($py, $b - $newy + $added);
14191 }
14192 /*-- END BORDER-RADIUS --*/
14193
14194
14195 /*-- TABLES --*/
14196 function setBorderDominance($prop, $val) {
14197 if (isset($prop['BORDER-LEFT']) && $prop['BORDER-LEFT']) { $this->cell_border_dominance_L = $val; }
14198 if (isset($prop['BORDER-RIGHT']) && $prop['BORDER-RIGHT']) { $this->cell_border_dominance_R = $val; }
14199 if (isset($prop['BORDER-TOP']) && $prop['BORDER-TOP']) { $this->cell_border_dominance_T = $val; }
14200 if (isset($prop['BORDER-BOTTOM']) && $prop['BORDER-BOTTOM']) { $this->cell_border_dominance_B = $val; }
14201 }
14202 /*-- END TABLES --*/
14203
14204
14205 /*-- HTML-CSS --*/
14206 function _mergeCSS($p, &$t) { // mPDF 5.3.82 $p changed to &$p
14207 // Save Cascading CSS e.g. "div.topic p" at this block level
14208 if (isset($p) && $p) {
14209 if ($t) {
14210 $t = $this->array_merge_recursive_unique($t, $p); // mPDF 5.3.96
14211 }
14212 else { $t = $p; }
14213 }
14214 }
14215
14216 // for CSS handling
14217 function array_merge_recursive_unique($array1, $array2) {
14218 $arrays = func_get_args();
14219 $narrays = count($arrays);
14220 $ret = $arrays[0];
14221 for ($i = 1; $i < $narrays; $i ++) {
14222 foreach ($arrays[$i] as $key => $value) {
14223 if (((string) $key) === ((string) intval($key))) { // integer or string as integer key - append
14224 $ret[] = $value;
14225 }
14226 else { // string key - merge
14227 if (is_array($value) && isset($ret[$key])) {
14228 $ret[$key] = $this->array_merge_recursive_unique($ret[$key], $value);
14229 }
14230 else {
14231 $ret[$key] = $value;
14232 }
14233 }
14234 }
14235 }
14236 return $ret;
14237 }
14238
14239
14240
14241 function _mergeFullCSS($p, &$t, $tag, $classes, $id) { // mPDF 5.3.82 $p changed to &$p
14242 $this->_mergeCSS($p[$tag], $t);
14243 // STYLESHEET CLASS e.g. .smallone{} .redletter{}
14244 foreach($classes AS $class) {
14245 $this->_mergeCSS($p['CLASS>>'.$class], $t);
14246 }
14247 // STYLESHEET nth-child SELECTOR e.g. tr:nth-child(odd) td:nth-child(2n+1)
14248 // mPDF 5.3.82
14249 if ($tag=='TR' && isset($p) && $p) {
14250 foreach($p AS $k=>$val) {
14251 if (preg_match('/'.$tag.'>>SELECTORNTHCHILD>>(.*)/',$k, $m)) {
14252 $select = false;
14253 if ($tag=='TR') {
14254 $row = $this->row; // mPDF 5.3.84
14255 $thnr = (isset($this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['is_thead']) ? count($this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['is_thead']) : 0);
14256 $tfnr = (isset($this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['is_tfoot']) ? count($this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['is_tfoot']) : 0);
14257 if ($this->tabletfoot) { $row -= $thnr; }
14258 else if (!$this->tablethead) { $row -= ($thnr + $tfnr); }
14259 if ($m[1]=='ODD' && ($row % 2) == 0) { $select = true; }
14260 else if ($m[1]=='EVEN' && ($row % 2) == 1) { $select = true; }
14261 else if (preg_match('/(\d+)N\+(\d+)/',$m[1],$a)) {
14262 if ((($row + 1) % $a[1]) == $a[2]) { $select = true; }
14263 }
14264 }
14265 else if ($tag=='TD' || $tag=='TH') {
14266 if ($m[1]=='ODD' && ($this->col % 2) == 0) { $select = true; }
14267 else if ($m[1]=='EVEN' && ($this->col % 2) == 1) { $select = true; }
14268 else if (preg_match('/(\d+)N\+(\d+)/',$m[1],$a)) {
14269 if ((($this->col + 1) % $a[1]) == $a[2]) { $select = true; }
14270 }
14271 }
14272 if ($select) {
14273 $this->_mergeCSS($p[$tag.'>>SELECTORNTHCHILD>>'.$m[1]], $t);
14274 }
14275 }
14276 }
14277 }
14278 // STYLESHEET CLASS e.g. #smallone{} #redletter{}
14279 if (isset($id) && $id) {
14280 $this->_mergeCSS($p['ID>>'.$id], $t);
14281 }
14282 // STYLESHEET CLASS e.g. .smallone{} .redletter{}
14283 foreach($classes AS $class) {
14284 $this->_mergeCSS($p[$tag.'>>CLASS>>'.$class], $t);
14285 }
14286 // STYLESHEET CLASS e.g. #smallone{} #redletter{}
14287 if (isset($id)) {
14288 $this->_mergeCSS($p[$tag.'>>ID>>'.$id], $t);
14289 }
14290 }
14291
14292
14293 function _set_mergedCSS(&$m, &$p, $d=true, $bd=false) {
14294 if (isset($m)) {
14295 if ((isset($m['depth']) && $m['depth']>1) || $d==false) { // include check for 'depth'
14296 if ($bd) { $this->setBorderDominance($m, $bd); } // *TABLES*
14297 if (is_array($m)) {
14298 $p = array_merge($p,$m);
14299 $this->_mergeBorders($p,$m);
14300 }
14301 }
14302 }
14303 }
14304
14305
14306 function _mergeBorders(&$b, &$a) { // Merges $a['BORDER-TOP-STYLE'] to $b['BORDER-TOP'] etc.
14307 foreach(array('TOP','RIGHT','BOTTOM','LEFT') AS $side) {
14308 foreach(array('STYLE','WIDTH','COLOR') AS $el) {
14309 if (isset($a['BORDER-'.$side.'-'.$el])) { // e.g. $b['BORDER-TOP-STYLE']
14310 $s = trim($a['BORDER-'.$side.'-'.$el]);
14311 if (isset($b['BORDER-'.$side])) { // e.g. $b['BORDER-TOP']
14312 $p = trim($b['BORDER-'.$side]);
14313 }
14314 else { $p = ''; }
14315 if ($el=='STYLE') {
14316 if ($p) { $b['BORDER-'.$side] = preg_replace('/(\S+)\s+(\S+)\s+(\S+)/', '\\1 '.$s.' \\3', $p); }
14317 else { $b['BORDER-'.$side] = '0px '.$s.' #000000'; }
14318 }
14319 else if ($el=='WIDTH') {
14320 if ($p) { $b['BORDER-'.$side] = preg_replace('/(\S+)\s+(\S+)\s+(\S+)/', $s.' \\2 \\3', $p); }
14321 else { $b['BORDER-'.$side] = $s.' none #000000'; }
14322 }
14323 else if ($el=='COLOR') {
14324 if ($p) { $b['BORDER-'.$side] = preg_replace('/(\S+)\s+(\S+)\s+(\S+)/', '\\1 \\2 '.$s, $p); }
14325 else { $b['BORDER-'.$side] = '0px none '.$s; }
14326 }
14327 }
14328 }
14329 }
14330 }
14331
14332
14333 function MergeCSS($inherit,$tag,$attr) {
14334 $p = array();
14335 $zp = array();
14336
14337 $classes = array();
14338 if (isset($attr['CLASS'])) {
14339 $classes = preg_split('/\s+/',$attr['CLASS']);
14340 }
14341 if (!isset($attr['ID'])) { $attr['ID']=''; }
14342 //===============================================
14343 /*-- TABLES --*/
14344 // Set Inherited properties
14345 if ($inherit == 'TOPTABLE') { // $tag = TABLE
14346 //===============================================
14347 // Save Cascading CSS e.g. "div.topic p" at this block level
14348
14349 if (isset($this->blk[$this->blklvl]['cascadeCSS'])) {
14350 $this->tablecascadeCSS[0] = $this->blk[$this->blklvl]['cascadeCSS'];
14351 }
14352 else {
14353 $this->tablecascadeCSS[0] = $this->cascadeCSS;
14354 }
14355 }
14356 //===============================================
14357 // Set Inherited properties
14358 if ($inherit == 'TOPTABLE' || $inherit == 'TABLE') {
14359 //Cascade everything from last level that is not an actual property, or defined by current tag/attributes
14360 if (isset($this->tablecascadeCSS[$this->tbCSSlvl-1]) && is_array($this->tablecascadeCSS[$this->tbCSSlvl-1])) {
14361 foreach($this->tablecascadeCSS[$this->tbCSSlvl-1] AS $k=>$v) {
14362 $this->tablecascadeCSS[$this->tbCSSlvl][$k] = $v;
14363 }
14364 }
14365 $this->_mergeFullCSS($this->cascadeCSS, $this->tablecascadeCSS[$this->tbCSSlvl], $tag, $classes, $attr['ID']);
14366 //===============================================
14367 // Cascading forward CSS e.g. "table.topic td" for this table in $this->tablecascadeCSS
14368 //===============================================
14369 // STYLESHEET TAG e.g. table
14370 $this->_mergeFullCSS($this->tablecascadeCSS[$this->tbCSSlvl-1], $this->tablecascadeCSS[$this->tbCSSlvl], $tag, $classes, $attr['ID']);
14371 //===============================================
14372 }
14373 /*-- END TABLES --*/
14374 //===============================================
14375 /*-- LISTS --*/
14376 // Set Inherited properties
14377 if ($inherit == 'TOPLIST') { // $tag = UL,OL
14378 //===============================================
14379 // Save Cascading CSS e.g. "div.topic p" at this block level
14380 if (isset($this->blk[$this->blklvl]['cascadeCSS'])) {
14381 $this->listcascadeCSS[0] = $this->blk[$this->blklvl]['cascadeCSS'];
14382 }
14383 else {
14384 $this->listcascadeCSS[0] = $this->cascadeCSS;
14385 }
14386 }
14387 //===============================================
14388 // Set Inherited properties
14389 if ($inherit == 'TOPLIST' || $inherit == 'LIST') {
14390 //Cascade everything from last level that is not an actual property, or defined by current tag/attributes
14391 if (isset($this->listcascadeCSS[$this->listCSSlvl-1]) && is_array($this->listcascadeCSS[$this->listCSSlvl-1])) {
14392 foreach($this->listcascadeCSS[$this->listCSSlvl-1] AS $k=>$v) {
14393 $this->listcascadeCSS[$this->listCSSlvl][$k] = $v;
14394 }
14395 }
14396 $this->_mergeFullCSS($this->cascadeCSS, $this->listcascadeCSS[$this->listCSSlvl], $tag, $classes, $attr['ID']);
14397 //===============================================
14398 // Cascading forward CSS e.g. "table.topic td" for this list in $this->listcascadeCSS
14399 //===============================================
14400 // STYLESHEET TAG e.g. table
14401 $this->_mergeFullCSS($this->listcascadeCSS[$this->listCSSlvl-1], $this->listcascadeCSS[$this->listCSSlvl], $tag, $classes, $attr['ID']);
14402 //===============================================
14403 }
14404 /*-- END LISTS --*/
14405 //===============================================
14406 // Set Inherited properties
14407 if ($inherit == 'BLOCK') {
14408 if (isset($this->blk[$this->blklvl-1]['cascadeCSS']) && is_array($this->blk[$this->blklvl-1]['cascadeCSS'])) {
14409 foreach($this->blk[$this->blklvl-1]['cascadeCSS'] AS $k=>$v) {
14410 $this->blk[$this->blklvl]['cascadeCSS'][$k] = $v;
14411
14412 }
14413 }
14414
14415 //===============================================
14416 // Save Cascading CSS e.g. "div.topic p" at this block level
14417 $this->_mergeFullCSS($this->cascadeCSS, $this->blk[$this->blklvl]['cascadeCSS'], $tag, $classes, $attr['ID']);
14418 //===============================================
14419 // Cascading forward CSS
14420 //===============================================
14421 $this->_mergeFullCSS($this->blk[$this->blklvl-1]['cascadeCSS'], $this->blk[$this->blklvl]['cascadeCSS'], $tag, $classes, $attr['ID']);
14422 //===============================================
14423 // Block properties
14424 if (isset($this->blk[$this->blklvl-1]['margin_collapse']) && $this->blk[$this->blklvl-1]['margin_collapse']) { $p['MARGIN-COLLAPSE'] = 'COLLAPSE'; } // custom tag, but follows CSS principle that border-collapse is inherited
14425 if (isset($this->blk[$this->blklvl-1]['line_height']) && $this->blk[$this->blklvl-1]['line_height']) { $p['LINE-HEIGHT'] = $this->blk[$this->blklvl-1]['line_height']; }
14426
14427 if (isset($this->blk[$this->blklvl-1]['direction']) && $this->blk[$this->blklvl-1]['direction']) { $p['DIRECTION'] = $this->blk[$this->blklvl-1]['direction']; }
14428
14429 if (isset($this->blk[$this->blklvl-1]['align']) && $this->blk[$this->blklvl-1]['align']) {
14430 if ($this->blk[$this->blklvl-1]['align'] == 'L') { $p['TEXT-ALIGN'] = 'left'; }
14431 else if ($this->blk[$this->blklvl-1]['align'] == 'J') { $p['TEXT-ALIGN'] = 'justify'; }
14432 else if ($this->blk[$this->blklvl-1]['align'] == 'R') { $p['TEXT-ALIGN'] = 'right'; }
14433 else if ($this->blk[$this->blklvl-1]['align'] == 'C') { $p['TEXT-ALIGN'] = 'center'; }
14434 }
14435 if ($this->ColActive || $this->keep_block_together) {
14436 if (isset($this->blk[$this->blklvl-1]['bgcolor']) && $this->blk[$this->blklvl-1]['bgcolor']) { // Doesn't officially inherit, but default value is transparent (?=inherited)
14437 $cor = $this->blk[$this->blklvl-1]['bgcolorarray' ];
14438 $p['BACKGROUND-COLOR'] = $this->_colAtoString($cor);
14439 }
14440 }
14441
14442 if (isset($this->blk[$this->blklvl-1]['text_indent']) && ($this->blk[$this->blklvl-1]['text_indent'] || $this->blk[$this->blklvl-1]['text_indent']===0)) { $p['TEXT-INDENT'] = $this->blk[$this->blklvl-1]['text_indent']; }
14443 if (isset($this->blk[$this->blklvl-1]['InlineProperties'])) {
14444 $biilp = $this->blk[$this->blklvl-1]['InlineProperties'];
14445 }
14446 else { $biilp = null; }
14447 if (isset($biilp[ 'family' ]) && $biilp[ 'family' ]) { $p['FONT-FAMILY'] = $biilp[ 'family' ]; }
14448 if (isset($biilp[ 'I' ]) && $biilp[ 'I' ]) { $p['FONT-STYLE'] = 'italic'; }
14449 if (isset($biilp[ 'sizePt' ]) && $biilp[ 'sizePt' ]) { $p['FONT-SIZE'] = $biilp[ 'sizePt' ] . 'pt'; }
14450 if (isset($biilp[ 'B' ]) && $biilp[ 'B' ]) { $p['FONT-WEIGHT'] = 'bold'; }
14451 if (isset($biilp[ 'colorarray' ]) && $biilp[ 'colorarray' ]) {
14452 $cor = $biilp[ 'colorarray' ];
14453 $p['COLOR'] = $this->_colAtoString($cor);
14454 }
14455 if (isset($biilp[ 'fontkerning' ])) {
14456 if ($biilp[ 'fontkerning' ]) { $p['FONT-KERNING'] = 'normal'; }
14457 else { $p['FONT-KERNING'] = 'none'; }
14458 }
14459 if (isset($biilp[ 'lSpacingCSS' ]) && $biilp[ 'lSpacingCSS' ]) { $p['LETTER-SPACING'] = $biilp[ 'lSpacingCSS' ]; }
14460 if (isset($biilp[ 'wSpacingCSS' ]) && $biilp[ 'wSpacingCSS' ]) { $p['WORD-SPACING'] = $biilp[ 'wSpacingCSS' ]; }
14461 if (isset($biilp[ 'toupper' ]) && $biilp[ 'toupper' ]) { $p['TEXT-TRANSFORM'] = 'uppercase'; }
14462 else if (isset($biilp[ 'tolower' ]) && $biilp[ 'tolower' ]) { $p['TEXT-TRANSFORM'] = 'lowercase'; }
14463 else if (isset($biilp[ 'capitalize' ]) && $biilp[ 'capitalize' ]) { $p['TEXT-TRANSFORM'] = 'capitalize'; }
14464 // CSS says text-decoration is not inherited, but IE7 does??
14465 if (isset($biilp[ 'underline' ]) && $biilp[ 'underline' ]) { $p['TEXT-DECORATION'] = 'underline'; }
14466 if (isset($biilp[ 'smCaps' ]) && $biilp[ 'smCaps' ]) { $p['FONT-VARIANT'] = 'small-caps'; }
14467
14468 }
14469 //===============================================
14470 //===============================================
14471 /*-- LISTS --*/
14472 // Set Inherited properties
14473 if ($inherit == 'TOPLIST') {
14474 if ($this->listCSSlvl == 1) {
14475 $bilp = $this->blk[$this->blklvl]['InlineProperties'];
14476 if (isset($bilp[ 'family' ]) && $bilp[ 'family' ]) { $p['FONT-FAMILY'] = $bilp[ 'family' ]; }
14477 if (isset($bilp[ 'I' ]) && $bilp[ 'I' ]) { $p['FONT-STYLE'] = 'italic'; }
14478 if (isset($bilp[ 'sizePt' ]) && $bilp[ 'sizePt' ]) { $p['FONT-SIZE'] = $bilp[ 'sizePt' ] . 'pt'; }
14479 if (isset($bilp[ 'B' ]) && $bilp[ 'B' ]) { $p['FONT-WEIGHT'] = 'bold'; }
14480 if (isset($bilp[ 'colorarray' ]) && $bilp[ 'colorarray' ]) {
14481 $cor = $bilp[ 'colorarray' ];
14482 $p['COLOR'] = $this->_colAtoString($cor);
14483 }
14484 if (isset($bilp[ 'toupper' ]) && $bilp[ 'toupper' ]) { $p['TEXT-TRANSFORM'] = 'uppercase'; }
14485 else if (isset($bilp[ 'tolower' ]) && $bilp[ 'tolower' ]) { $p['TEXT-TRANSFORM'] = 'lowercase'; }
14486 else if (isset($bilp[ 'capitalize' ]) && $bilp[ 'capitalize' ]) { $p['TEXT-TRANSFORM'] = 'capitalize'; }
14487 if (isset($bilp[ 'fontkerning' ])) {
14488 if ($bilp[ 'fontkerning' ]) { $p['FONT-KERNING'] = 'normal'; }
14489 else { $p['FONT-KERNING'] = 'none'; }
14490 }
14491 if (isset($bilp[ 'lSpacingCSS' ]) && $bilp[ 'lSpacingCSS' ]) { $p['LETTER-SPACING'] = $bilp[ 'lSpacingCSS' ]; }
14492 if (isset($bilp[ 'wSpacingCSS' ]) && $bilp[ 'wSpacingCSS' ]) { $p['WORD-SPACING'] = $bilp[ 'wSpacingCSS' ]; }
14493 // CSS says text-decoration is not inherited, but IE7 does??
14494 if (isset($bilp[ 'underline' ]) && $bilp[ 'underline' ]) { $p['TEXT-DECORATION'] = 'underline'; }
14495 if (isset($bilp[ 'smCaps' ]) && $bilp[ 'smCaps' ]) { $p['FONT-VARIANT'] = 'small-caps'; }
14496 if ($tag=='LI') { // mPDF 5.3.99
14497 // Note to self - this should never work, as TOPLIST is not called when LI (see code removed in v5.3)
14498 $this->Error("If you see this message, please report this as a bug to the mPDF Forum.");
14499 }
14500 }
14501 }
14502 /*-- END LISTS --*/
14503 //===============================================
14504 //===============================================
14505 // DEFAULT for this TAG set in DefaultCSS
14506 if (isset($this->defaultCSS[$tag])) {
14507 $zp = $this->fixCSS($this->defaultCSS[$tag]);
14508 if (is_array($zp)) { // Default overwrites Inherited
14509 $p = array_merge($p,$zp); // !! Note other way round !!
14510 $this->_mergeBorders($p,$zp);
14511 }
14512 }
14513 //===============================================
14514 /*-- TABLES --*/
14515 // cellPadding overwrites TD/TH default but not specific CSS set on cell
14516 if (($tag=='TD' || $tag=='TH') && isset($this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['cell_padding']) && ($this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['cell_padding'] || $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['cell_padding']===0)) {
14517 $p['PADDING-LEFT'] = $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['cell_padding'];
14518 $p['PADDING-RIGHT'] = $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['cell_padding'];
14519 $p['PADDING-TOP'] = $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['cell_padding'];
14520 $p['PADDING-BOTTOM'] = $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['cell_padding'];
14521 }
14522 /*-- END TABLES --*/
14523 //===============================================
14524 // STYLESHEET TAG e.g. h1 p div table
14525 if (isset($this->CSS[$tag]) && $this->CSS[$tag]) {
14526 $zp = $this->CSS[$tag];
14527 if ($tag=='TD' || $tag=='TH') { $this->setBorderDominance($zp, 9); } // *TABLES* // *TABLES-ADVANCED-BORDERS*
14528 if (is_array($zp)) {
14529 $p = array_merge($p,$zp);
14530 $this->_mergeBorders($p,$zp);
14531 }
14532 }
14533 //===============================================
14534 // STYLESHEET CLASS e.g. .smallone{} .redletter{}
14535 foreach($classes AS $class) {
14536 $zp = array();
14537 if (isset($this->CSS['CLASS>>'.$class]) && $this->CSS['CLASS>>'.$class]) { $zp = $this->CSS['CLASS>>'.$class]; }
14538 if ($tag=='TD' || $tag=='TH') { $this->setBorderDominance($zp, 9); } // *TABLES* // *TABLES-ADVANCED-BORDERS*
14539 if (is_array($zp)) {
14540 $p = array_merge($p,$zp);
14541 $this->_mergeBorders($p,$zp);
14542 }
14543 }
14544 //===============================================
14545 /*-- TABLES --*/
14546 // mPDF 5.3.82
14547 // STYLESHEET nth-child SELECTOR e.g. tr:nth-child(odd) td:nth-child(2n+1)
14548 if ($tag=='TR' || $tag=='TD' || $tag=='TH') {
14549 foreach($this->CSS AS $k=>$val) {
14550 if (preg_match('/'.$tag.'>>SELECTORNTHCHILD>>(.*)/',$k, $m)) {
14551 $select = false;
14552 if ($tag=='TR') {
14553 $row = $this->row; // mPDF 5.3.84
14554 $thnr = (isset($this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['is_thead']) ? count($this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['is_thead']) : 0);
14555 $tfnr = (isset($this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['is_tfoot']) ? count($this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['is_tfoot']) : 0);
14556 if ($this->tabletfoot) { $row -= $thnr; }
14557 else if (!$this->tablethead) { $row -= ($thnr + $tfnr); }
14558 if ($m[1]=='ODD' && ($row % 2) == 0) { $select = true; }
14559 else if ($m[1]=='EVEN' && ($row % 2) == 1) { $select = true; }
14560 else if (preg_match('/(\d+)N\+(\d+)/',$m[1],$a)) {
14561 if ((($row + 1) % $a[1]) == $a[2]) { $select = true; }
14562 }
14563 }
14564 else if ($tag=='TD' || $tag=='TH') {
14565 if ($m[1]=='ODD' && ($this->col % 2) == 0) { $select = true; }
14566 else if ($m[1]=='EVEN' && ($this->col % 2) == 1) { $select = true; }
14567 else if (preg_match('/(\d+)N\+(\d+)/',$m[1],$a)) {
14568 if ((($this->col+1) % $a[1]) == $a[2]) { $select = true; }
14569 }
14570 }
14571 if ($select) {
14572 $zp = $this->CSS[$tag.'>>SELECTORNTHCHILD>>'.$m[1]];
14573 if ($tag=='TD' || $tag=='TH') { $this->setBorderDominance($zp, 9); }
14574 if (is_array($zp)) {
14575 $p = array_merge($p,$zp);
14576 $this->_mergeBorders($p,$zp);
14577 }
14578 }
14579 }
14580 }
14581 }
14582 /*-- END TABLES --*/
14583 //===============================================
14584 // STYLESHEET ID e.g. #smallone{} #redletter{}
14585 if (isset($attr['ID']) && isset($this->CSS['ID>>'.$attr['ID']]) && $this->CSS['ID>>'.$attr['ID']]) {
14586 $zp = $this->CSS['ID>>'.$attr['ID']];
14587 if ($tag=='TD' || $tag=='TH') { $this->setBorderDominance($zp, 9); } // *TABLES* // *TABLES-ADVANCED-BORDERS*
14588 if (is_array($zp)) {
14589 $p = array_merge($p,$zp);
14590 $this->_mergeBorders($p,$zp);
14591 }
14592 }
14593 //===============================================
14594 // STYLESHEET CLASS e.g. p.smallone{} div.redletter{}
14595 foreach($classes AS $class) {
14596 $zp = array();
14597 if (isset($this->CSS[$tag.'>>CLASS>>'.$class]) && $this->CSS[$tag.'>>CLASS>>'.$class]) { $zp = $this->CSS[$tag.'>>CLASS>>'.$class]; }
14598 if ($tag=='TD' || $tag=='TH') { $this->setBorderDominance($zp, 9); } // *TABLES* // *TABLES-ADVANCED-BORDERS*
14599 if (is_array($zp)) {
14600 $p = array_merge($p,$zp);
14601 $this->_mergeBorders($p,$zp);
14602 }
14603 }
14604 //===============================================
14605 // STYLESHEET CLASS e.g. p#smallone{} div#redletter{}
14606 if (isset($attr['ID']) && isset($this->CSS[$tag.'>>ID>>'.$attr['ID']]) && $this->CSS[$tag.'>>ID>>'.$attr['ID']]) {
14607 $zp = $this->CSS[$tag.'>>ID>>'.$attr['ID']];
14608 if ($tag=='TD' || $tag=='TH') { $this->setBorderDominance($zp, 9); } // *TABLES* // *TABLES-ADVANCED-BORDERS*
14609 if (is_array($zp)) {
14610 $p = array_merge($p,$zp);
14611 $this->_mergeBorders($p,$zp);
14612 }
14613 }
14614 //===============================================
14615 // Cascaded e.g. div.class p only works for block level
14616 if ($inherit == 'BLOCK') {
14617 $this->_set_mergedCSS($this->blk[$this->blklvl-1]['cascadeCSS'][$tag], $p);
14618 foreach($classes AS $class) {
14619 $this->_set_mergedCSS($this->blk[$this->blklvl-1]['cascadeCSS']['CLASS>>'.$class], $p);
14620 }
14621 $this->_set_mergedCSS($this->blk[$this->blklvl-1]['cascadeCSS']['ID>>'.$attr['ID']], $p);
14622 foreach($classes AS $class) {
14623 $this->_set_mergedCSS($this->blk[$this->blklvl-1]['cascadeCSS'][$tag.'>>CLASS>>'.$class], $p);
14624 }
14625 $this->_set_mergedCSS($this->blk[$this->blklvl-1]['cascadeCSS'][$tag.'>>ID>>'.$attr['ID']], $p);
14626 }
14627 else if ($inherit == 'INLINE') {
14628 $this->_set_mergedCSS($this->blk[$this->blklvl]['cascadeCSS'][$tag], $p);
14629 foreach($classes AS $class) {
14630 $this->_set_mergedCSS($this->blk[$this->blklvl]['cascadeCSS']['CLASS>>'.$class], $p);
14631 }
14632 $this->_set_mergedCSS($this->blk[$this->blklvl]['cascadeCSS']['ID>>'.$attr['ID']], $p);
14633 foreach($classes AS $class) {
14634 $this->_set_mergedCSS($this->blk[$this->blklvl]['cascadeCSS'][$tag.'>>CLASS>>'.$class], $p);
14635 }
14636 $this->_set_mergedCSS($this->blk[$this->blklvl]['cascadeCSS'][$tag.'>>ID>>'.$attr['ID']], $p);
14637 }
14638 /*-- TABLES --*/
14639 else if ($inherit == 'TOPTABLE' || $inherit == 'TABLE') { // NB looks at $this->tablecascadeCSS-1 for cascading CSS
14640 // false, 9 = don't check for 'depth' and do set border dominance
14641 $this->_set_mergedCSS($this->tablecascadeCSS[$this->tbCSSlvl-1][$tag], $p, false, 9);
14642 foreach($classes AS $class) {
14643 $this->_set_mergedCSS($this->tablecascadeCSS[$this->tbCSSlvl-1]['CLASS>>'.$class], $p, false, 9);
14644 }
14645 // STYLESHEET nth-child SELECTOR e.g. tr:nth-child(odd) td:nth-child(2n+1)
14646 // mPDF 5.3.82
14647 if ($tag=='TR' || $tag=='TD' || $tag=='TH') {
14648 foreach($this->tablecascadeCSS[$this->tbCSSlvl-1] AS $k=>$val) {
14649 if (preg_match('/'.$tag.'>>SELECTORNTHCHILD>>(.*)/',$k, $m)) {
14650 $select = false;
14651 if ($tag=='TR') {
14652 $row = $this->row; // mPDF 5.3.84
14653 $thnr = (isset($this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['is_thead']) ? count($this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['is_thead']) : 0);
14654 $tfnr = (isset($this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['is_tfoot']) ? count($this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['is_tfoot']) : 0);
14655 if ($this->tabletfoot) { $row -= $thnr; }
14656 else if (!$this->tablethead) { $row -= ($thnr + $tfnr); }
14657 if ($m[1]=='ODD' && ($row % 2) == 0) { $select = true; }
14658 else if ($m[1]=='EVEN' && ($row % 2) == 1) { $select = true; }
14659 else if (preg_match('/(\d+)N\+(\d+)/',$m[1],$a)) {
14660 if ((($row + 1) % $a[1]) == $a[2]) { $select = true; }
14661 }
14662 }
14663 else if ($tag=='TD' || $tag=='TH') {
14664 if ($m[1]=='ODD' && ($this->col % 2) == 0) { $select = true; }
14665 else if ($m[1]=='EVEN' && ($this->col % 2) == 1) { $select = true; }
14666 else if (preg_match('/(\d+)N\+(\d+)/',$m[1],$a)) {
14667 if ((($this->col + 1) % $a[1]) == $a[2]) { $select = true; }
14668 }
14669 }
14670 if ($select) {
14671 $this->_set_mergedCSS($this->tablecascadeCSS[$this->tbCSSlvl-1][$tag.'>>SELECTORNTHCHILD>>'.$m[1]], $p, false, 9);
14672 }
14673 }
14674 }
14675 }
14676 $this->_set_mergedCSS($this->tablecascadeCSS[$this->tbCSSlvl-1]['ID>>'.$attr['ID']], $p, false, 9);
14677 foreach($classes AS $class) {
14678 $this->_set_mergedCSS($this->tablecascadeCSS[$this->tbCSSlvl-1][$tag.'>>CLASS>>'.$class], $p, false, 9);
14679 }
14680 $this->_set_mergedCSS($this->tablecascadeCSS[$this->tbCSSlvl-1][$tag.'>>ID>>'.$attr['ID']], $p, false, 9);
14681 }
14682 /*-- END TABLES --*/
14683 //===============================================
14684 /*-- LISTS --*/
14685 else if ($inherit == 'TOPLIST' || $inherit == 'LIST') { // NB looks at $this->listcascadeCSS-1 for cascading CSS
14686 // false = don't check for 'depth'
14687 $this->_set_mergedCSS($this->listcascadeCSS[$this->listCSSlvl-1][$tag], $p, false);
14688 foreach($classes AS $class) {
14689 $this->_set_mergedCSS($this->listcascadeCSS[$this->listCSSlvl-1]['CLASS>>'.$class], $p, false);
14690 }
14691 $this->_set_mergedCSS($this->listcascadeCSS[$this->listCSSlvl-1]['ID>>'.$attr['ID']], $p, false);
14692 foreach($classes AS $class) {
14693 $this->_set_mergedCSS($this->listcascadeCSS[$this->listCSSlvl-1][$tag.'>>CLASS>>'.$class], $p, false);
14694 }
14695 $this->_set_mergedCSS($this->listcascadeCSS[$this->listCSSlvl-1][$tag.'>>ID>>'.$attr['ID']], $p, false);
14696 }
14697 /*-- END LISTS --*/
14698 //===============================================
14699 //===============================================
14700 // INLINE STYLE e.g. style="CSS:property"
14701 if (isset($attr['STYLE'])) {
14702 $zp = $this->readInlineCSS($attr['STYLE']);
14703 if ($tag=='TD' || $tag=='TH') { $this->setBorderDominance($zp, 9); } // *TABLES* // *TABLES-ADVANCED-BORDERS*
14704 if (is_array($zp)) {
14705 $p = array_merge($p,$zp);
14706 $this->_mergeBorders($p,$zp);
14707 }
14708 }
14709 //===============================================
14710 //===============================================
14711 // INLINE ATTRIBUTES e.g. .. ALIGN="CENTER">
14712 if (isset($attr['LANG']) and $attr['LANG']!='') {
14713 $p['LANG'] = $attr['LANG'];
14714 }
14715 if (isset($attr['COLOR']) and $attr['COLOR']!='') {
14716 $p['COLOR'] = $attr['COLOR'];
14717 }
14718 if ($tag != 'INPUT') {
14719 if (isset($attr['WIDTH']) and $attr['WIDTH']!='') {
14720 $p['WIDTH'] = $attr['WIDTH'];
14721 }
14722 if (isset($attr['HEIGHT']) and $attr['HEIGHT']!='') {
14723 $p['HEIGHT'] = $attr['HEIGHT'];
14724 }
14725 }
14726 if ($tag == 'FONT') {
14727 if (isset($attr['FACE'])) {
14728 $p['FONT-FAMILY'] = $attr['FACE'];
14729 }
14730 if (isset($attr['SIZE']) and $attr['SIZE']!='') {
14731 $s = '';
14732 if ($attr['SIZE'] === '+1') { $s = '120%'; }
14733 else if ($attr['SIZE'] === '-1') { $s = '86%'; }
14734 else if ($attr['SIZE'] === '1') { $s = 'XX-SMALL'; }
14735 else if ($attr['SIZE'] == '2') { $s = 'X-SMALL'; }
14736 else if ($attr['SIZE'] == '3') { $s = 'SMALL'; }
14737 else if ($attr['SIZE'] == '4') { $s = 'MEDIUM'; }
14738 else if ($attr['SIZE'] == '5') { $s = 'LARGE'; }
14739 else if ($attr['SIZE'] == '6') { $s = 'X-LARGE'; }
14740 else if ($attr['SIZE'] == '7') { $s = 'XX-LARGE'; }
14741 if ($s) $p['FONT-SIZE'] = $s;
14742 }
14743 }
14744 if (isset($attr['VALIGN']) and $attr['VALIGN']!='') {
14745 $p['VERTICAL-ALIGN'] = $attr['VALIGN'];
14746 }
14747 if (isset($attr['VSPACE']) and $attr['VSPACE']!='') {
14748 $p['MARGIN-TOP'] = $attr['VSPACE'];
14749 $p['MARGIN-BOTTOM'] = $attr['VSPACE'];
14750 }
14751 if (isset($attr['HSPACE']) and $attr['HSPACE']!='') {
14752 $p['MARGIN-LEFT'] = $attr['HSPACE'];
14753 $p['MARGIN-RIGHT'] = $attr['HSPACE'];
14754 }
14755 //===============================================
14756 return $p;
14757 }
14758
14759
14760 /*-- CSS-PAGE --*/
14761 function SetPagedMediaCSS($name='', $first, $oddEven) {
14762 if ($oddEven == 'E') {
14763 if ($this->directionality=='rtl') { $side = 'R'; }
14764 else { $side = 'L'; }
14765 }
14766 else {
14767 if ($this->directionality=='rtl') { $side = 'L'; }
14768 else { $side = 'R'; }
14769 }
14770 $name = strtoupper($name);
14771 $p = array();
14772 $p['SIZE'] = 'AUTO';
14773
14774 // Uses mPDF original margins as default
14775 $p['MARGIN-RIGHT'] = strval($this->orig_rMargin).'mm';
14776 $p['MARGIN-LEFT'] = strval($this->orig_lMargin).'mm';
14777 $p['MARGIN-TOP'] = strval($this->orig_tMargin).'mm';
14778 $p['MARGIN-BOTTOM'] = strval($this->orig_bMargin).'mm';
14779 $p['MARGIN-HEADER'] = strval($this->orig_hMargin).'mm';
14780 $p['MARGIN-FOOTER'] = strval($this->orig_fMargin).'mm';
14781
14782 // Basic page + selector
14783 if (isset($this->CSS['@PAGE'])) { $zp = $this->CSS['@PAGE']; }
14784 else { $zp = array(); }
14785 if (is_array($zp) && !empty($zp)) { $p = array_merge($p,$zp); }
14786
14787 if (isset($p['EVEN-HEADER-NAME']) && $oddEven=='E') {
14788 $p['HEADER'] = $p['EVEN-HEADER-NAME']; unset($p['EVEN-HEADER-NAME']);
14789 }
14790 if (isset($p['ODD-HEADER-NAME']) && $oddEven!='E') {
14791 $p['HEADER'] = $p['ODD-HEADER-NAME']; unset($p['ODD-HEADER-NAME']);
14792 }
14793 if (isset($p['EVEN-FOOTER-NAME']) && $oddEven=='E') {
14794 $p['FOOTER'] = $p['EVEN-FOOTER-NAME']; unset($p['EVEN-FOOTER-NAME']);
14795 }
14796 if (isset($p['ODD-FOOTER-NAME']) && $oddEven!='E') {
14797 $p['FOOTER'] = $p['ODD-FOOTER-NAME']; unset($p['ODD-FOOTER-NAME']);
14798 }
14799
14800 // If right/Odd page
14801 if (isset($this->CSS['@PAGE>>PSEUDO>>RIGHT']) && $side=='R') {
14802 $zp = $this->CSS['@PAGE>>PSEUDO>>RIGHT'];
14803 }
14804 else { $zp = array(); }
14805 if (isset($zp['SIZE'])) { unset($zp['SIZE']); }
14806 if (isset($zp['SHEET-SIZE'])) { unset($zp['SHEET-SIZE']); }
14807 // Disallow margin-left or -right on :LEFT or :RIGHT
14808 if (isset($zp['MARGIN-LEFT'])) { unset($zp['MARGIN-LEFT']); }
14809 if (isset($zp['MARGIN-RIGHT'])) { unset($zp['MARGIN-RIGHT']); }
14810 if (is_array($zp) && !empty($zp)) { $p = array_merge($p,$zp); }
14811
14812 // If left/Even page
14813 if (isset($this->CSS['@PAGE>>PSEUDO>>LEFT']) && $side=='L') {
14814 $zp = $this->CSS['@PAGE>>PSEUDO>>LEFT'];
14815 }
14816 else { $zp = array(); }
14817 if (isset($zp['SIZE'])) { unset($zp['SIZE']); }
14818 if (isset($zp['SHEET-SIZE'])) { unset($zp['SHEET-SIZE']); }
14819 // Disallow margin-left or -right on :LEFT or :RIGHT
14820 if (isset($zp['MARGIN-LEFT'])) { unset($zp['MARGIN-LEFT']); }
14821 if (isset($zp['MARGIN-RIGHT'])) { unset($zp['MARGIN-RIGHT']); }
14822 if (is_array($zp) && !empty($zp)) { $p = array_merge($p,$zp); }
14823
14824 // If first page
14825 if (isset($this->CSS['@PAGE>>PSEUDO>>FIRST']) && $first) { $zp = $this->CSS['@PAGE>>PSEUDO>>FIRST']; }
14826 else { $zp = array(); }
14827 if (isset($zp['SIZE'])) { unset($zp['SIZE']); }
14828 if (isset($zp['SHEET-SIZE'])) { unset($zp['SHEET-SIZE']); }
14829 if (is_array($zp) && !empty($zp)) { $p = array_merge($p,$zp); }
14830
14831 // If named page
14832 if ($name) {
14833 if (isset($this->CSS['@PAGE>>NAMED>>'.$name])) { $zp = $this->CSS['@PAGE>>NAMED>>'.$name]; }
14834 else { $zp = array(); }
14835 if (is_array($zp) && !empty($zp)) { $p = array_merge($p,$zp); }
14836
14837 if (isset($p['EVEN-HEADER-NAME']) && $oddEven=='E') {
14838 $p['HEADER'] = $p['EVEN-HEADER-NAME']; unset($p['EVEN-HEADER-NAME']);
14839 }
14840 if (isset($p['ODD-HEADER-NAME']) && $oddEven!='E') {
14841 $p['HEADER'] = $p['ODD-HEADER-NAME']; unset($p['ODD-HEADER-NAME']);
14842 }
14843 if (isset($p['EVEN-FOOTER-NAME']) && $oddEven=='E') {
14844 $p['FOOTER'] = $p['EVEN-FOOTER-NAME']; unset($p['EVEN-FOOTER-NAME']);
14845 }
14846 if (isset($p['ODD-FOOTER-NAME']) && $oddEven!='E') {
14847 $p['FOOTER'] = $p['ODD-FOOTER-NAME']; unset($p['ODD-FOOTER-NAME']);
14848 }
14849
14850 // If named right/Odd page
14851 if (isset($this->CSS['@PAGE>>NAMED>>'.$name.'>>PSEUDO>>RIGHT']) && $side=='R') { $zp = $this->CSS['@PAGE>>NAMED>>'.$name.'>>PSEUDO>>RIGHT']; }
14852 else { $zp = array(); }
14853 if (isset($zp['SIZE'])) { unset($zp['SIZE']); }
14854 if (isset($zp['SHEET-SIZE'])) { unset($zp['SHEET-SIZE']); }
14855 // Disallow margin-left or -right on :LEFT or :RIGHT
14856 if (isset($zp['MARGIN-LEFT'])) { unset($zp['MARGIN-LEFT']); }
14857 if (isset($zp['MARGIN-RIGHT'])) { unset($zp['MARGIN-RIGHT']); }
14858 if (is_array($zp) && !empty($zp)) { $p = array_merge($p,$zp); }
14859
14860 // If named left/Even page
14861 if (isset($this->CSS['@PAGE>>NAMED>>'.$name.'>>PSEUDO>>LEFT']) && $side=='L') { $zp = $this->CSS['@PAGE>>NAMED>>'.$name.'>>PSEUDO>>LEFT']; }
14862 else { $zp = array(); }
14863 if (isset($zp['SIZE'])) { unset($zp['SIZE']); }
14864 if (isset($zp['SHEET-SIZE'])) { unset($zp['SHEET-SIZE']); }
14865 // Disallow margin-left or -right on :LEFT or :RIGHT
14866 if (isset($zp['MARGIN-LEFT'])) { unset($zp['MARGIN-LEFT']); }
14867 if (isset($zp['MARGIN-RIGHT'])) { unset($zp['MARGIN-RIGHT']); }
14868 if (is_array($zp) && !empty($zp)) { $p = array_merge($p,$zp); }
14869
14870 // If named first page
14871 if (isset($this->CSS['@PAGE>>NAMED>>'.$name.'>>PSEUDO>>FIRST']) && $first) { $zp = $this->CSS['@PAGE>>NAMED>>'.$name.'>>PSEUDO>>FIRST']; }
14872 else { $zp = array(); }
14873 if (isset($zp['SIZE'])) { unset($zp['SIZE']); }
14874 if (isset($zp['SHEET-SIZE'])) { unset($zp['SHEET-SIZE']); }
14875 if (is_array($zp) && !empty($zp)) { $p = array_merge($p,$zp); }
14876 }
14877
14878 $orientation = $mgl = $mgr = $mgt = $mgb = $mgh = $mgf = '';
14879 $header = $footer = '';
14880 $resetpagenum = $pagenumstyle = $suppress = '';
14881 $marks = '';
14882 $bg = array();
14883
14884 $newformat = '';
14885
14886
14887 if (isset($p['SHEET-SIZE']) && is_array($p['SHEET-SIZE'])) {
14888 $newformat = $p['SHEET-SIZE'];
14889 if ($newformat[0] > $newformat[1]) { // landscape
14890 $newformat = array_reverse($newformat);
14891 $p['ORIENTATION'] = 'L';
14892 }
14893 else { $p['ORIENTATION'] = 'P'; }
14894 $this->_setPageSize($newformat, $p['ORIENTATION']);
14895 }
14896
14897 if (isset($p['SIZE']) && is_array($p['SIZE']) && !$newformat) {
14898 if ($p['SIZE']['W'] > $p['SIZE']['H']) { $p['ORIENTATION'] = 'L'; }
14899 else { $p['ORIENTATION'] = 'P'; }
14900 }
14901 if (is_array($p['SIZE'])) {
14902 if ($p['SIZE']['W'] > $this->fw) { $p['SIZE']['W'] = $this->fw; } // mPD 4.2 use fw not fPt
14903 if ($p['SIZE']['H'] > $this->fh) { $p['SIZE']['H'] = $this->fh; }
14904 if (($p['ORIENTATION']==$this->DefOrientation && !$newformat) || ($newformat && $p['ORIENTATION']=='P')) {
14905 $outer_width_LR = ($this->fw - $p['SIZE']['W'])/2;
14906 $outer_width_TB = ($this->fh - $p['SIZE']['H'])/2;
14907 }
14908 else {
14909 $outer_width_LR = ($this->fh - $p['SIZE']['W'])/2;
14910 $outer_width_TB = ($this->fw - $p['SIZE']['H'])/2;
14911 }
14912 $pgw = $p['SIZE']['W'];
14913 $pgh = $p['SIZE']['H'];
14914 }
14915 else { // AUTO LANDSCAPE PORTRAIT
14916 $outer_width_LR = 0;
14917 $outer_width_TB = 0;
14918 if (!$newformat) {
14919 if (strtoupper($p['SIZE']) == 'AUTO') { $p['ORIENTATION']=$this->DefOrientation; }
14920 else if (strtoupper($p['SIZE']) == 'LANDSCAPE') { $p['ORIENTATION']='L'; }
14921 else { $p['ORIENTATION']='P'; }
14922 }
14923 if (($p['ORIENTATION']==$this->DefOrientation && !$newformat) || ($newformat && $p['ORIENTATION']=='P')) {
14924 $pgw = $this->fw;
14925 $pgh = $this->fh;
14926 }
14927 else {
14928 $pgw = $this->fh;
14929 $pgh = $this->fw;
14930 }
14931 }
14932
14933 if (isset($p['HEADER']) && $p['HEADER']) { $header = $p['HEADER']; }
14934 if (isset($p['FOOTER']) && $p['FOOTER']) { $footer = $p['FOOTER']; }
14935 if (isset($p['RESETPAGENUM']) && $p['RESETPAGENUM']) { $resetpagenum = $p['RESETPAGENUM']; }
14936 if (isset($p['PAGENUMSTYLE']) && $p['PAGENUMSTYLE']) { $pagenumstyle = $p['PAGENUMSTYLE']; }
14937 if (isset($p['SUPPRESS']) && $p['SUPPRESS']) { $suppress = $p['SUPPRESS']; }
14938
14939 if (preg_match('/cross/i', $p['MARKS']) && preg_match('/crop/i', $p['MARKS'])) { $marks = 'CROPCROSS'; }
14940 else if (strtoupper($p['MARKS']) == 'CROP') { $marks = 'CROP'; }
14941 else if (strtoupper($p['MARKS']) == 'CROSS') { $marks = 'CROSS'; }
14942
14943
14944 if (isset($p['BACKGROUND-COLOR']) && $p['BACKGROUND-COLOR']) { $bg['BACKGROUND-COLOR'] = $p['BACKGROUND-COLOR']; }
14945 /*-- BACKGROUNDS --*/
14946 if (isset($p['BACKGROUND-GRADIENT']) && $p['BACKGROUND-GRADIENT']) { $bg['BACKGROUND-GRADIENT'] = $p['BACKGROUND-GRADIENT']; }
14947 if (isset($p['BACKGROUND-IMAGE']) && $p['BACKGROUND-IMAGE']) { $bg['BACKGROUND-IMAGE'] = $p['BACKGROUND-IMAGE']; }
14948 if (isset($p['BACKGROUND-REPEAT']) && $p['BACKGROUND-REPEAT']) { $bg['BACKGROUND-REPEAT'] = $p['BACKGROUND-REPEAT']; }
14949 if (isset($p['BACKGROUND-POSITION']) && $p['BACKGROUND-POSITION']) { $bg['BACKGROUND-POSITION'] = $p['BACKGROUND-POSITION']; }
14950 if (isset($p['BACKGROUND-IMAGE-RESIZE']) && $p['BACKGROUND-IMAGE-RESIZE']) { $bg['BACKGROUND-IMAGE-RESIZE'] = $p['BACKGROUND-IMAGE-RESIZE']; }
14951 if (isset($p['BACKGROUND-IMAGE-OPACITY'])) { $bg['BACKGROUND-IMAGE-OPACITY'] = $p['BACKGROUND-IMAGE-OPACITY']; } // mPDF 5.3.12
14952 /*-- END BACKGROUNDS --*/
14953
14954 if (isset($p['MARGIN-LEFT'])) { $mgl = $this->ConvertSize($p['MARGIN-LEFT'],$pgw) + $outer_width_LR; }
14955 if (isset($p['MARGIN-RIGHT'])) { $mgr = $this->ConvertSize($p['MARGIN-RIGHT'],$pgw) + $outer_width_LR; }
14956 if (isset($p['MARGIN-BOTTOM'])) { $mgb = $this->ConvertSize($p['MARGIN-BOTTOM'],$pgh) + $outer_width_TB; }
14957 if (isset($p['MARGIN-TOP'])) { $mgt = $this->ConvertSize($p['MARGIN-TOP'],$pgh) + $outer_width_TB; }
14958 if (isset($p['MARGIN-HEADER'])) { $mgh = $this->ConvertSize($p['MARGIN-HEADER'],$pgh) + $outer_width_TB; }
14959 if (isset($p['MARGIN-FOOTER'])) { $mgf = $this->ConvertSize($p['MARGIN-FOOTER'],$pgh) + $outer_width_TB; }
14960
14961 if (isset($p['ORIENTATION']) && $p['ORIENTATION']) { $orientation = $p['ORIENTATION']; }
14962 $this->page_box['outer_width_LR'] = $outer_width_LR; // Used in MARKS:crop etc.
14963 $this->page_box['outer_width_TB'] = $outer_width_TB;
14964
14965 return array($orientation,$mgl,$mgr,$mgt,$mgb,$mgh,$mgf,$header,$footer,$bg,$resetpagenum,$pagenumstyle,$suppress,$marks,$newformat);
14966 }
14967 /*-- END CSS-PAGE --*/
14968
14969 function PreviewBlockCSS($tag,$attr) {
14970 // Looks ahead from current block level to a new level
14971 $p = array();
14972 $zp = array();
14973 $oldcascadeCSS = $this->blk[$this->blklvl]['cascadeCSS'];
14974 $classes = array();
14975 if (isset($attr['CLASS'])) { $classes = preg_split('/\s+/',$attr['CLASS']); }
14976 //===============================================
14977 // DEFAULT for this TAG set in DefaultCSS
14978 if (isset($this->defaultCSS[$tag])) {
14979 $zp = $this->fixCSS($this->defaultCSS[$tag]);
14980 if (is_array($zp)) { $p = array_merge($zp,$p); } // Inherited overwrites default
14981 }
14982 // STYLESHEET TAG e.g. h1 p div table
14983 if (isset($this->CSS[$tag])) {
14984 $zp = $this->CSS[$tag];
14985 if (is_array($zp)) { $p = array_merge($p,$zp); }
14986 }
14987 // STYLESHEET CLASS e.g. .smallone{} .redletter{}
14988 foreach($classes AS $class) {
14989 $zp = array();
14990 if (isset($this->CSS['CLASS>>'.$class])) { $zp = $this->CSS['CLASS>>'.$class]; }
14991 if (is_array($zp)) { $p = array_merge($p,$zp); }
14992 }
14993 // STYLESHEET ID e.g. #smallone{} #redletter{}
14994 if (isset($attr['ID']) && isset($this->CSS['ID>>'.$attr['ID']])) {
14995 $zp = $this->CSS['ID>>'.$attr['ID']];
14996 if (is_array($zp)) { $p = array_merge($p,$zp); }
14997 }
14998 // STYLESHEET CLASS e.g. p.smallone{} div.redletter{}
14999 foreach($classes AS $class) {
15000 $zp = array();
15001 if (isset($this->CSS[$tag.'>>CLASS>>'.$class])) { $zp = $this->CSS[$tag.'>>CLASS>>'.$class]; }
15002 if (is_array($zp)) { $p = array_merge($p,$zp); }
15003 }
15004 // STYLESHEET CLASS e.g. p#smallone{} div#redletter{}
15005 if (isset($attr['ID']) && isset($this->CSS[$tag.'>>ID>>'.$attr['ID']])) {
15006 $zp = $this->CSS[$tag.'>>ID>>'.$attr['ID']];
15007 if (is_array($zp)) { $p = array_merge($p,$zp); }
15008 }
15009 //===============================================
15010 // STYLESHEET TAG e.g. div h1 div p
15011
15012 $this->_set_mergedCSS($oldcascadeCSS[$tag], $p);
15013 // STYLESHEET CLASS e.g. .smallone{} .redletter{}
15014 foreach($classes AS $class) {
15015
15016 $this->_set_mergedCSS($oldcascadeCSS['CLASS>>'.$class], $p);
15017 }
15018 // STYLESHEET CLASS e.g. #smallone{} #redletter{}
15019 if (isset($attr['ID'])) {
15020
15021 $this->_set_mergedCSS($oldcascadeCSS['ID>>'.$attr['ID']], $p);
15022 }
15023 // STYLESHEET CLASS e.g. div.smallone{} p.redletter{}
15024 foreach($classes AS $class) {
15025
15026 $this->_set_mergedCSS($oldcascadeCSS[$tag.'>>CLASS>>'.$class], $p);
15027 }
15028 // STYLESHEET CLASS e.g. div#smallone{} p#redletter{}
15029 if (isset($attr['ID'])) {
15030
15031 $this->_set_mergedCSS($oldcascadeCSS[$tag.'>>ID>>'.$attr['ID']], $p);
15032 }
15033 //===============================================
15034 // INLINE STYLE e.g. style="CSS:property"
15035 if (isset($attr['STYLE'])) {
15036 $zp = $this->readInlineCSS($attr['STYLE']);
15037 if (is_array($zp)) { $p = array_merge($p,$zp); }
15038 }
15039 //===============================================
15040 return $p;
15041 }
15042
15043
15044
15045 /*-- CSS-FLOAT --*/
15046 // Added mPDF 3.0 Float DIV - CLEAR
15047 function ClearFloats($clear, $blklvl=0) {
15048 list($l_exists, $r_exists, $l_max, $r_max, $l_width, $r_width) = $this->GetFloatDivInfo($blklvl,true);
15049 $end = $currpos = ($this->page*1000 + $this->y);
15050 if ($clear == 'BOTH' && ($l_exists || $r_exists)) {
15051 $this->pageoutput[$this->page] = array();
15052 $end = max($l_max, $r_max, $currpos);
15053 }
15054 else if ($clear == 'RIGHT' && $r_exists) {
15055 $this->pageoutput[$this->page] = array();
15056 $end = max($r_max, $currpos);
15057 }
15058 else if ($clear == 'LEFT' && $l_exists ) {
15059 $this->pageoutput[$this->page] = array();
15060 $end = max($l_max, $currpos);
15061 }
15062 else { return; }
15063 $old_page = $this->page;
15064 $new_page = intval($end/1000);
15065 if ($old_page != $new_page) {
15066 $s = $this->PrintPageBackgrounds();
15067 // Writes after the marker so not overwritten later by page background etc.
15068 $this->pages[$this->page] = preg_replace('/(___BACKGROUND___PATTERNS'.date('jY').')/', '\\1'."\n".$s."\n", $this->pages[$this->page]);
15069 $this->pageBackgrounds = array();
15070 $this->page = $new_page;
15071 }
15072 $this->ResetMargins();
15073 $this->pageoutput[$this->page] = array();
15074 $this->y = (($end*1000) % 1000000)/1000; // mod changes operands to integers before processing
15075 }
15076
15077
15078 // Added mPDF 3.0 Float DIV
15079 function GetFloatDivInfo($blklvl=0,$clear=false) {
15080 // If blklvl specified, only returns floats at that level - for ClearFloats
15081 $l_exists = false;
15082 $r_exists = false;
15083 $l_max = 0;
15084 $r_max = 0;
15085 $l_width = 0;
15086 $r_width = 0;
15087 if (count($this->floatDivs)) {
15088 $currpos = ($this->page*1000 + $this->y);
15089 foreach($this->floatDivs AS $f) {
15090 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'])) {
15091 if ($f['side']=='L') {
15092 $l_exists= true;
15093 $l_max = max($l_max, $f['endpos']);
15094 $l_width = max($l_width , $f['w']);
15095 }
15096 if ($f['side']=='R') {
15097 $r_exists= true;
15098 $r_max = max($r_max, $f['endpos']);
15099 $r_width = max($r_width , $f['w']);
15100 }
15101 }
15102 }
15103 }
15104 return array($l_exists, $r_exists, $l_max, $r_max, $l_width, $r_width);
15105 }
15106 /*-- END CSS-FLOAT --*/
15107
15108
15109
15110
15111 function OpenTag($tag,$attr)
15112 {
15113
15114 // What this gets: < $tag $attr['WIDTH']="90px" > does not get content here </closeTag here>
15115 // Correct tags where HTML specifies optional end tags,
15116 // and/or does not allow nesting e.g. P inside P, or
15117 if ($this->allow_html_optional_endtags) {
15118 if (($tag == 'P' || $tag == 'DIV' || $tag == 'H1' || $tag == 'H2' || $tag == 'H3' || $tag == 'H4' || $tag == 'H5' || $tag == 'H6' || $tag == 'UL' || $tag == 'OL' || $tag == 'TABLE' || $tag=='PRE' || $tag=='FORM' || $tag=='ADDRESS' || $tag=='BLOCKQUOTE' || $tag=='CENTER' || $tag=='DL' || $tag == 'HR' ) && $this->lastoptionaltag == 'P') { $this->CloseTag($this->lastoptionaltag ); }
15119 if ($tag == 'DD' && $this->lastoptionaltag == 'DD') { $this->CloseTag($this->lastoptionaltag ); }
15120 if ($tag == 'DD' && $this->lastoptionaltag == 'DT') { $this->CloseTag($this->lastoptionaltag ); }
15121 if ($tag == 'DT' && $this->lastoptionaltag == 'DD') { $this->CloseTag($this->lastoptionaltag ); }
15122 if ($tag == 'DT' && $this->lastoptionaltag == 'DT') { $this->CloseTag($this->lastoptionaltag ); }
15123 if ($tag == 'LI' && $this->lastoptionaltag == 'LI') { $this->CloseTag($this->lastoptionaltag ); }
15124 if (($tag == 'TD' || $tag == 'TH') && $this->lastoptionaltag == 'TD') { $this->CloseTag($this->lastoptionaltag ); } // *TABLES*
15125 if (($tag == 'TD' || $tag == 'TH') && $this->lastoptionaltag == 'TH') { $this->CloseTag($this->lastoptionaltag ); } // *TABLES*
15126 if ($tag == 'TR' && $this->lastoptionaltag == 'TR') { $this->CloseTag($this->lastoptionaltag ); } // *TABLES*
15127 if ($tag == 'TR' && $this->lastoptionaltag == 'TD') { $this->CloseTag($this->lastoptionaltag ); $this->CloseTag('TR'); $this->CloseTag('THEAD'); } // *TABLES*
15128 if ($tag == 'TR' && $this->lastoptionaltag == 'TH') { $this->CloseTag($this->lastoptionaltag ); $this->CloseTag('TR'); $this->CloseTag('THEAD'); } // *TABLES*
15129 if ($tag == 'OPTION' && $this->lastoptionaltag == 'OPTION') { $this->CloseTag($this->lastoptionaltag ); }
15130 }
15131
15132 $align = array('left'=>'L','center'=>'C','right'=>'R','top'=>'T','text-top'=>'TT','middle'=>'M','baseline'=>'BS','bottom'=>'B','text-bottom'=>'TB','justify'=>'J');
15133
15134 $this->ignorefollowingspaces=false;
15135
15136 //Opening tag
15137 switch($tag){
15138
15139 case 'DOTTAB':
15140 $objattr = array();
15141 $objattr['type'] = 'dottab';
15142 $dots=str_repeat('.', 3)." "; // minimum number of dots
15143 $objattr['width'] = $this->GetStringWidth($dots);
15144 $objattr['margin_top'] = 0;
15145 $objattr['margin_bottom'] = 0;
15146 $objattr['margin_left'] = 0;
15147 $objattr['margin_right'] = 0;
15148 $objattr['height'] = 0;
15149 $objattr['colorarray'] = $this->colorarray;
15150 $objattr['border_top']['w'] = 0;
15151 $objattr['border_bottom']['w'] = 0;
15152 $objattr['border_left']['w'] = 0;
15153 $objattr['border_right']['w'] = 0;
15154 $e = "\xbb\xa4\xactype=dottab,objattr=".serialize($objattr)."\xbb\xa4\xac";
15155 /*-- TABLES --*/
15156 // Output it to buffers
15157 if ($this->tableLevel) {
15158 if (!isset($this->cell[$this->row][$this->col]['maxs'])) {
15159 $this->cell[$this->row][$this->col]['maxs'] = $this->cell[$this->row][$this->col]['s'];
15160 }
15161 elseif($this->cell[$this->row][$this->col]['maxs'] < $this->cell[$this->row][$this->col]['s']) {
15162 $this->cell[$this->row][$this->col]['maxs'] = $this->cell[$this->row][$this->col]['s'];
15163 }
15164 $this->cell[$this->row][$this->col]['s'] = 0 ;// reset
15165 $this->_saveCellTextBuffer($e); // mPDF 5.3.99
15166 }
15167 else {
15168 /*-- END TABLES --*/
15169 $this->_saveTextBuffer($e); // mPDF 5.3.99
15170 } // *TABLES*
15171 break;
15172
15173 case 'PAGEHEADER':
15174 case 'PAGEFOOTER':
15175 $this->ignorefollowingspaces = true;
15176 if ($attr['NAME']) { $pname = $attr['NAME']; }
15177 else { $pname = '_default'; }
15178
15179 if ($tag=='PAGEHEADER') { $p = &$this->pageheaders[$pname]; }
15180 else { $p = &$this->pagefooters[$pname]; }
15181
15182 $p['L']=array();
15183 $p['C']=array();
15184 $p['R']=array();
15185 $p['L']['font-style'] = '';
15186 $p['C']['font-style'] = '';
15187 $p['R']['font-style'] = '';
15188
15189 if (isset($attr['CONTENT-LEFT'])) {
15190 $p['L']['content'] = $attr['CONTENT-LEFT'];
15191 }
15192 if (isset($attr['CONTENT-CENTER'])) {
15193 $p['C']['content'] = $attr['CONTENT-CENTER'];
15194 }
15195 if (isset($attr['CONTENT-RIGHT'])) {
15196 $p['R']['content'] = $attr['CONTENT-RIGHT'];
15197 }
15198
15199 if (isset($attr['HEADER-STYLE']) || isset($attr['FOOTER-STYLE'])) { // font-family,size,weight,style,color
15200 if ($tag=='PAGEHEADER') { $properties = $this->readInlineCSS($attr['HEADER-STYLE']); }
15201 else { $properties = $this->readInlineCSS($attr['FOOTER-STYLE']); }
15202 if (isset($properties['FONT-FAMILY'])) {
15203 $p['L']['font-family'] = $properties['FONT-FAMILY'];
15204 $p['C']['font-family'] = $properties['FONT-FAMILY'];
15205 $p['R']['font-family'] = $properties['FONT-FAMILY'];
15206 }
15207 if (isset($properties['FONT-SIZE'])) {
15208 $p['L']['font-size'] = $this->ConvertSize($properties['FONT-SIZE']) * _MPDFK;
15209 $p['C']['font-size'] = $this->ConvertSize($properties['FONT-SIZE']) * _MPDFK;
15210 $p['R']['font-size'] = $this->ConvertSize($properties['FONT-SIZE']) * _MPDFK;
15211 }
15212 if (isset($properties['FONT-WEIGHT']) && $properties['FONT-WEIGHT']=='bold') { // mPDF 5.3.86
15213 $p['L']['font-style'] = 'B';
15214 $p['C']['font-style'] = 'B';
15215 $p['R']['font-style'] = 'B';
15216 }
15217 if (isset($properties['FONT-STYLE']) && $properties['FONT-STYLE']=='italic') { // mPDF 5.3.86
15218 $p['L']['font-style'] .= 'I';
15219 $p['C']['font-style'] .= 'I';
15220 $p['R']['font-style'] .= 'I';
15221 }
15222 if (isset($properties['COLOR'])) {
15223 $p['L']['color'] = $properties['COLOR'];
15224 $p['C']['color'] = $properties['COLOR'];
15225 $p['R']['color'] = $properties['COLOR'];
15226 }
15227 }
15228 if (isset($attr['HEADER-STYLE-LEFT']) || isset($attr['FOOTER-STYLE-LEFT'])) {
15229 if ($tag=='PAGEHEADER') { $properties = $this->readInlineCSS($attr['HEADER-STYLE-LEFT']); }
15230 else { $properties = $this->readInlineCSS($attr['FOOTER-STYLE-LEFT']); }
15231 if (isset($properties['FONT-FAMILY'])) { $p['L']['font-family'] = $properties['FONT-FAMILY']; }
15232 if (isset($properties['FONT-SIZE'])) { $p['L']['font-size'] = $this->ConvertSize($properties['FONT-SIZE']) * _MPDFK; }
15233 if (isset($properties['FONT-WEIGHT']) && $properties['FONT-WEIGHT']=='bold') { $p['L']['font-style'] ='B'; } // mPDF 5.3.86
15234 if (isset($properties['FONT-STYLE']) && $properties['FONT-STYLE']=='italic') { $p['L']['font-style'] .='I'; } // mPDF 5.3.86
15235 if (isset($properties['COLOR'])) { $p['L']['color'] = $properties['COLOR']; }
15236 }
15237 if (isset($attr['HEADER-STYLE-CENTER']) || isset($attr['FOOTER-STYLE-CENTER'])) {
15238 if ($tag=='PAGEHEADER') { $properties = $this->readInlineCSS($attr['HEADER-STYLE-CENTER']); }
15239 else { $properties = $this->readInlineCSS($attr['FOOTER-STYLE-CENTER']); }
15240 if (isset($properties['FONT-FAMILY'])) { $p['C']['font-family'] = $properties['FONT-FAMILY']; }
15241 if (isset($properties['FONT-SIZE'])) { $p['C']['font-size'] = $this->ConvertSize($properties['FONT-SIZE']) * _MPDFK; }
15242 if (isset($properties['FONT-WEIGHT']) && $properties['FONT-WEIGHT']=='bold') { $p['C']['font-style'] = 'B'; } // mPDF 5.3.86
15243 if (isset($properties['FONT-STYLE']) && $properties['FONT-STYLE']=='italic') { $p['C']['font-style'] .= 'I'; } // mPDF 5.3.86
15244 if (isset($properties['COLOR'])) { $p['C']['color'] = $properties['COLOR']; }
15245 }
15246 if (isset($attr['HEADER-STYLE-RIGHT']) || isset($attr['FOOTER-STYLE-RIGHT'])) {
15247 if ($tag=='PAGEHEADER') { $properties = $this->readInlineCSS($attr['HEADER-STYLE-RIGHT']); }
15248 else { $properties = $this->readInlineCSS($attr['FOOTER-STYLE-RIGHT']); }
15249 if (isset($properties['FONT-FAMILY'])) { $p['R']['font-family'] = $properties['FONT-FAMILY']; }
15250 if (isset($properties['FONT-SIZE'])) { $p['R']['font-size'] = $this->ConvertSize($properties['FONT-SIZE']) * _MPDFK; }
15251 if (isset($properties['FONT-WEIGHT']) && $properties['FONT-WEIGHT']=='bold') { $p['R']['font-style'] = 'B'; } // mPDF 5.3.86
15252 if (isset($properties['FONT-STYLE']) && $properties['FONT-STYLE']=='italic') { $p['R']['font-style'] .= 'I'; } // mPDF 5.3.86
15253 if (isset($properties['COLOR'])) { $p['R']['color'] = $properties['COLOR']; }
15254 }
15255 if (isset($attr['LINE']) && $attr['LINE']) { // 0|1|on|off
15256 if ($attr['LINE']=='1' || strtoupper($attr['LINE'])=='ON') { $lineset=1; }
15257 else { $lineset=0; }
15258 $p['line'] = $lineset;
15259 }
15260 break;
15261
15262
15263 /*-- HTMLHEADERS-FOOTERS --*/
15264 case 'SETHTMLPAGEHEADER':
15265 case 'SETHTMLPAGEFOOTER':
15266 $this->ignorefollowingspaces = true;
15267 if (isset($attr['NAME']) && $attr['NAME']) { $pname = $attr['NAME']; }
15268 else { $pname = '_default'; }
15269 if (isset($attr['PAGE']) && $attr['PAGE']) { // O|odd|even|E|ALL|[blank]
15270 if (strtoupper($attr['PAGE'])=='O' || strtoupper($attr['PAGE'])=='ODD') { $side='odd'; }
15271 else if (strtoupper($attr['PAGE'])=='E' || strtoupper($attr['PAGE'])=='EVEN') { $side='even'; }
15272 else if (strtoupper($attr['PAGE'])=='ALL') { $side='both'; }
15273 else { $side='odd'; }
15274 }
15275 else { $side='odd'; }
15276 if (isset($attr['VALUE']) && $attr['VALUE']) { // -1|1|on|off
15277 if ($attr['VALUE']=='1' || strtoupper($attr['VALUE'])=='ON') { $set=1; }
15278 else if ($attr['VALUE']=='-1' || strtoupper($attr['VALUE'])=='OFF') { $set=0; }
15279 else { $set=1; }
15280 }
15281 else { $set=1; }
15282 if (isset($attr['SHOW-THIS-PAGE']) && $attr['SHOW-THIS-PAGE'] && $tag=='SETHTMLPAGEHEADER') { $write = 1; }
15283 else { $write = 0; }
15284 if ($side=='odd' || $side=='both') {
15285 if ($set && $tag=='SETHTMLPAGEHEADER') { $this->SetHTMLHeader($this->pageHTMLheaders[$pname],'O',$write); }
15286 else if ($set && $tag=='SETHTMLPAGEFOOTER') { $this->SetHTMLFooter($this->pageHTMLfooters[$pname],'O'); }
15287 else if ($tag=='SETHTMLPAGEHEADER') { $this->SetHTMLHeader('','O'); }
15288 else { $this->SetHTMLFooter('','O'); }
15289 }
15290 if ($side=='even' || $side=='both') {
15291 if ($set && $tag=='SETHTMLPAGEHEADER') { $this->SetHTMLHeader($this->pageHTMLheaders[$pname],'E',$write); }
15292 else if ($set && $tag=='SETHTMLPAGEFOOTER') { $this->SetHTMLFooter($this->pageHTMLfooters[$pname],'E'); }
15293 else if ($tag=='SETHTMLPAGEHEADER') { $this->SetHTMLHeader('','E'); }
15294 else { $this->SetHTMLFooter('','E'); }
15295 }
15296 break;
15297 /*-- END HTMLHEADERS-FOOTERS --*/
15298
15299 case 'SETPAGEHEADER':
15300 case 'SETPAGEFOOTER':
15301 $this->ignorefollowingspaces = true;
15302 if (isset($attr['NAME']) && $attr['NAME']) { $pname = $attr['NAME']; }
15303 else { $pname = '_default'; }
15304 if (isset($attr['PAGE']) && $attr['PAGE']) { // O|odd|even|E|ALL|[blank]
15305 if (strtoupper($attr['PAGE'])=='O' || strtoupper($attr['PAGE'])=='ODD') { $side='odd'; }
15306 else if (strtoupper($attr['PAGE'])=='E' || strtoupper($attr['PAGE'])=='EVEN') { $side='even'; }
15307 else if (strtoupper($attr['PAGE'])=='ALL') { $side='both'; }
15308 else { $side='odd'; }
15309 }
15310 else { $side='odd'; }
15311 if (isset($attr['VALUE']) && $attr['VALUE']) { // -1|1|on|off
15312 if ($attr['VALUE']=='1' || strtoupper($attr['VALUE'])=='ON') { $set=1; }
15313 else if ($attr['VALUE']=='-1' || strtoupper($attr['VALUE'])=='OFF') { $set=0; }
15314 else { $set=1; }
15315 }
15316 else { $set=1; }
15317 if ($side=='odd' || $side=='both') {
15318 if ($set && $tag=='SETPAGEHEADER') { $this->headerDetails['odd'] = $this->pageheaders[$pname]; }
15319 else if ($set && $tag=='SETPAGEFOOTER') { $this->footerDetails['odd'] = $this->pagefooters[$pname]; }
15320 else if ($tag=='SETPAGEHEADER') { $this->headerDetails['odd'] = array(); }
15321 else { $this->footerDetails['odd'] = array(); }
15322 if (!$this->mirrorMargins || ($this->page)%2!=0) { // ODD
15323 if ($tag=='SETPAGEHEADER') { $this->_setAutoHeaderHeight($this->headerDetails['odd'],$this->HTMLHeader); }
15324 if ($tag=='SETPAGEFOOTER') { $this->_setAutoFooterHeight($this->footerDetails['odd'],$this->HTMLFooter); }
15325 }
15326 }
15327 if ($side=='even' || $side=='both') {
15328 if ($set && $tag=='SETPAGEHEADER') { $this->headerDetails['even'] = $this->pageheaders[$pname]; }
15329 else if ($set && $tag=='SETPAGEFOOTER') { $this->footerDetails['even'] = $this->pagefooters[$pname]; }
15330 else if ($tag=='SETPAGEHEADER') { $this->headerDetails['even'] = array(); }
15331 else { $this->footerDetails['even'] = array(); }
15332 if ($this->mirrorMargins && ($this->page)%2==0) { // EVEN
15333 if ($tag=='SETPAGEHEADER') { $this->_setAutoHeaderHeight($this->headerDetails['even'],$this->HTMLHeaderE); }
15334 if ($tag=='SETPAGEFOOTER') { $this->_setAutoFooterHeight($this->footerDetails['even'],$this->HTMLFooterE); }
15335 }
15336 }
15337 if (isset($attr['SHOW-THIS-PAGE']) && $attr['SHOW-THIS-PAGE'] && $tag=='SETPAGEHEADER') {
15338 $this->Header();
15339 }
15340 break;
15341
15342
15343 /*-- TOC --*/
15344 case 'TOC': //added custom-tag - set Marker for insertion later of ToC
15345 if (!class_exists('tocontents', false)) { include(_MPDF_PATH.'classes/tocontents.php'); }
15346 if (empty($this->tocontents)) { $this->tocontents = new tocontents($this); }
15347 $this->tocontents->openTagTOC($attr);
15348 break;
15349
15350
15351
15352 case 'TOCPAGEBREAK': // custom-tag - set Marker for insertion later of ToC AND adds PAGEBREAK
15353 if (!class_exists('tocontents', false)) { include(_MPDF_PATH.'classes/tocontents.php'); }
15354 if (empty($this->tocontents)) { $this->tocontents = new tocontents($this); }
15355 list($isbreak,$toc_id) = $this->tocontents->openTagTOCPAGEBREAK($attr);
15356 if ($isbreak) break;
15357 // No break - continues as PAGEBREAK...
15358 /*-- END TOC --*/
15359
15360
15361 case 'PAGE_BREAK': //custom-tag
15362 case 'PAGEBREAK': //custom-tag
15363 case 'NEWPAGE': //custom-tag
15364 case 'FORMFEED': //custom-tag
15365
15366 $save_blklvl = $this->blklvl;
15367 $save_blk = $this->blk;
15368 $save_silp = $this->saveInlineProperties();
15369 $save_spanlvl = $this->spanlvl;
15370 $save_ilp = $this->InlineProperties;
15371
15372 // Close any open block tags
15373 for ($b= $this->blklvl;$b>0;$b--) { $this->CloseTag($this->blk[$b]['tag']); }
15374 if(!empty($this->textbuffer)) { //Output previously buffered content
15375 $this->printbuffer($this->textbuffer);
15376 $this->textbuffer=array();
15377 }
15378 $this->ignorefollowingspaces = true;
15379 $save_cols = false;
15380 /*-- COLUMNS --*/
15381 if ($this->ColActive) {
15382 $save_cols = true;
15383 $save_nbcol = $this->NbCol; // other values of gap and vAlign will not change by setting Columns off
15384 $this->SetColumns(0);
15385 }
15386 /*-- END COLUMNS --*/
15387
15388
15389 if (isset($attr['SHEET-SIZE']) && $tag != 'FORMFEED' && !$this->restoreBlockPageBreaks) {
15390 // Convert to same types as accepted in initial mPDF() A4, A4-L, or array(w,h)
15391 $prop = preg_split('/\s+/',trim($attr['SHEET-SIZE']));
15392 if (count($prop) == 2 ) {
15393 $newformat = array($this->ConvertSize($prop[0]), $this->ConvertSize($prop[1]));
15394 }
15395 else { $newformat = $attr['SHEET-SIZE']; }
15396 }
15397 else { $newformat = ''; }
15398
15399
15400 $mgr = $mgl = $mgt = $mgb = $mgh = $mgf = '';
15401 if (isset($attr['MARGIN-RIGHT'])) { $mgr = $this->ConvertSize($attr['MARGIN-RIGHT'],$this->w,$this->FontSize,false); }
15402 if (isset($attr['MARGIN-LEFT'])) { $mgl = $this->ConvertSize($attr['MARGIN-LEFT'],$this->w,$this->FontSize,false); }
15403 if (isset($attr['MARGIN-TOP'])) { $mgt = $this->ConvertSize($attr['MARGIN-TOP'],$this->w,$this->FontSize,false); }
15404 if (isset($attr['MARGIN-BOTTOM'])) { $mgb = $this->ConvertSize($attr['MARGIN-BOTTOM'],$this->w,$this->FontSize,false); }
15405 if (isset($attr['MARGIN-HEADER'])) { $mgh = $this->ConvertSize($attr['MARGIN-HEADER'],$this->w,$this->FontSize,false); }
15406 if (isset($attr['MARGIN-FOOTER'])) { $mgf = $this->ConvertSize($attr['MARGIN-FOOTER'],$this->w,$this->FontSize,false); }
15407 $ohname = $ehname = $ofname = $efname = '';
15408 if (isset($attr['ODD-HEADER-NAME'])) { $ohname = $attr['ODD-HEADER-NAME']; }
15409 if (isset($attr['EVEN-HEADER-NAME'])) { $ehname = $attr['EVEN-HEADER-NAME']; }
15410 if (isset($attr['ODD-FOOTER-NAME'])) { $ofname = $attr['ODD-FOOTER-NAME']; }
15411 if (isset($attr['EVEN-FOOTER-NAME'])) { $efname = $attr['EVEN-FOOTER-NAME']; }
15412 $ohvalue = $ehvalue = $ofvalue = $efvalue = 0;
15413 if (isset($attr['ODD-HEADER-VALUE']) && ($attr['ODD-HEADER-VALUE']=='1' || strtoupper($attr['ODD-HEADER-VALUE'])=='ON')) { $ohvalue = 1; }
15414 else if (isset($attr['ODD-HEADER-VALUE']) && ($attr['ODD-HEADER-VALUE']=='-1' || strtoupper($attr['ODD-HEADER-VALUE'])=='OFF')) { $ohvalue = -1; }
15415 if (isset($attr['EVEN-HEADER-VALUE']) && ($attr['EVEN-HEADER-VALUE']=='1' || strtoupper($attr['EVEN-HEADER-VALUE'])=='ON')) { $ehvalue = 1; }
15416 else if (isset($attr['EVEN-HEADER-VALUE']) && ($attr['EVEN-HEADER-VALUE']=='-1' || strtoupper($attr['EVEN-HEADER-VALUE'])=='OFF')) { $ehvalue = -1; }
15417 if (isset($attr['ODD-FOOTER-VALUE']) && ($attr['ODD-FOOTER-VALUE']=='1' || strtoupper($attr['ODD-FOOTER-VALUE'])=='ON')) { $ofvalue = 1; }
15418 else if (isset($attr['ODD-FOOTER-VALUE']) && ($attr['ODD-FOOTER-VALUE']=='-1' || strtoupper($attr['ODD-FOOTER-VALUE'])=='OFF')) { $ofvalue = -1; }
15419 if (isset($attr['EVEN-FOOTER-VALUE']) && ($attr['EVEN-FOOTER-VALUE']=='1' || strtoupper($attr['EVEN-FOOTER-VALUE'])=='ON')) { $efvalue = 1; }
15420 else if (isset($attr['EVEN-FOOTER-VALUE']) && ($attr['EVEN-FOOTER-VALUE']=='-1' || strtoupper($attr['EVEN-FOOTER-VALUE'])=='OFF')) { $efvalue = -1; }
15421
15422 if (isset($attr['ORIENTATION']) && (strtoupper($attr['ORIENTATION'])=='L' || strtoupper($attr['ORIENTATION'])=='LANDSCAPE')) { $orient = 'L'; }
15423 else if (isset($attr['ORIENTATION']) && (strtoupper($attr['ORIENTATION'])=='P' || strtoupper($attr['ORIENTATION'])=='PORTRAIT')) { $orient = 'P'; }
15424 else { $orient = $this->CurOrientation; }
15425
15426 if (isset($attr['PAGE-SELECTOR']) && $attr['PAGE-SELECTOR']) { $pagesel = $attr['PAGE-SELECTOR']; }
15427 else { $pagesel = ''; }
15428
15429 $resetpagenum = '';
15430 $pagenumstyle = '';
15431 $suppress = '';
15432 if (isset($attr['RESETPAGENUM'])) { $resetpagenum = $attr['RESETPAGENUM']; }
15433 if (isset($attr['PAGENUMSTYLE'])) { $pagenumstyle = $attr['PAGENUMSTYLE']; }
15434 if (isset($attr['SUPPRESS'])) { $suppress = $attr['SUPPRESS']; }
15435
15436 if ($tag == 'TOCPAGEBREAK') { $type = 'NEXT-ODD'; }
15437 else if(isset($attr['TYPE'])) { $type = strtoupper($attr['TYPE']); }
15438 else { $type = ''; }
15439
15440 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); }
15441 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); }
15442 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); }
15443 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); }
15444 else { $this->AddPage($orient,'', $resetpagenum, $pagenumstyle, $suppress,$mgl,$mgr,$mgt,$mgb,$mgh,$mgf,$ohname,$ehname,$ofname,$efname,$ohvalue,$ehvalue,$ofvalue,$efvalue,$pagesel,$newformat); }
15445
15446 /*-- TOC --*/
15447 if ($tag == 'TOCPAGEBREAK') {
15448 if ($toc_id) { $this->tocontents->m_TOC[$toc_id]['TOCmark'] = $this->page; }
15449 else { $this->tocontents->TOCmark = $this->page; }
15450 }
15451 /*-- END TOC --*/
15452
15453 /*-- COLUMNS --*/
15454 if ($save_cols) {
15455 // Restore columns
15456 $this->SetColumns($save_nbcol,$this->colvAlign,$this->ColGap);
15457 }
15458 /*-- END COLUMNS --*/
15459 if (($tag == 'FORMFEED' || $this->restoreBlockPagebreaks) && !$this->tableLevel && !$this->listlvl) {
15460 $this->blk = $save_blk;
15461 // Re-open block tags
15462 $t = $this->blk[0]['tag'];
15463 $a = $this->blk[0]['attr'];
15464 $this->blklvl = 0;
15465 for ($b=0; $b<=$save_blklvl;$b++) {
15466 $tc = $t;
15467 $ac = $a;
15468 $t = $this->blk[$b+1]['tag'];
15469 $a = $this->blk[$b+1]['attr'];
15470 unset($this->blk[$b+1]);
15471 $this->OpenTag($tc,$ac);
15472 }
15473 $this->spanlvl = $save_spanlvl;
15474 $this->InlineProperties = $save_ilp;
15475 $this->restoreInlineProperties($save_silp);
15476 }
15477
15478 break;
15479
15480
15481 /*-- TOC --*/
15482 case 'TOCENTRY':
15483 if (isset($attr['CONTENT']) && $attr['CONTENT']) {
15484 $objattr = array();
15485 $objattr['CONTENT'] = htmlspecialchars_decode($attr['CONTENT'],ENT_QUOTES);
15486 $objattr['type'] = 'toc';
15487 if (isset($attr['LEVEL']) && $attr['LEVEL']) { $objattr['toclevel'] = $attr['LEVEL']; } else { $objattr['toclevel'] = 0; }
15488 if (isset($attr['NAME']) && $attr['NAME']) { $objattr['toc_id'] = $attr['NAME']; } else { $objattr['toc_id'] = 0; }
15489 $e = "\xbb\xa4\xactype=toc,objattr=".serialize($objattr)."\xbb\xa4\xac";
15490 if($this->tableLevel) { $this->cell[$this->row][$this->col]['textbuffer'][] = array($e); } // *TABLES*
15491 else { // *TABLES*
15492 $this->textbuffer[] = array($e);
15493 } // *TABLES*
15494 }
15495 break;
15496 /*-- END TOC --*/
15497
15498 /*-- INDEX --*/
15499 case 'INDEXENTRY':
15500 if (isset($attr['CONTENT']) && $attr['CONTENT']) {
15501 if (isset($attr['XREF']) && $attr['XREF']) {
15502 $this->IndexEntry(htmlspecialchars_decode($attr['CONTENT'],ENT_QUOTES),$attr['XREF']);
15503 break;
15504 }
15505 $objattr = array();
15506 $objattr['CONTENT'] = htmlspecialchars_decode($attr['CONTENT'],ENT_QUOTES);
15507 $objattr['type'] = 'indexentry';
15508 $e = "\xbb\xa4\xactype=indexentry,objattr=".serialize($objattr)."\xbb\xa4\xac";
15509 if($this->tableLevel) { $this->cell[$this->row][$this->col]['textbuffer'][] = array($e); } // *TABLES*
15510 else { // *TABLES*
15511 $this->textbuffer[] = array($e);
15512 } // *TABLES*
15513 }
15514 break;
15515
15516
15517 case 'INDEXINSERT':
15518 if (isset($attr['FONT-SIZE'])) { $reffontsize = $attr['FONT-SIZE']; } else { $reffontsize = ''; }
15519 if (isset($attr['LINE-SPACING']) && $attr['LINE-SPACING']) { $linespacing = $attr['LINE-SPACING']; } else { $linespacing = ''; }
15520 if (isset($attr['DIV-FONT-SIZE']) && $attr['DIV-FONT-SIZE']) { $divlettfontsize = $attr['DIV-FONT-SIZE']; } else { $divlettfontsize = ''; }
15521 if (isset($attr['FONT']) && $attr['FONT']) { $reffont = $attr['FONT']; } else { $reffont = ''; }
15522 if (isset($attr['DIV-FONT']) && $attr['DIV-FONT']) { $divlettfont = $attr['DIV-FONT']; } else { $divlettfont = ''; }
15523 if (isset($attr['COLS']) && $attr['COLS']) { $cols = $attr['COLS']; } else { $cols = 1; }
15524 if (isset($attr['OFFSET']) && $attr['OFFSET']) { $offset = $attr['OFFSET']; } else { $offset = 3; }
15525 if (isset($attr['GAP']) && $attr['GAP']) { $gap = $attr['GAP']; } else { $gap = 5; }
15526
15527 if (isset($attr['USEDIVLETTERS']) && (strtoupper($attr['USEDIVLETTERS'])=='OFF' || $attr['USEDIVLETTERS']==-1 || $attr['USEDIVLETTERS']==='0')) { $usedivletters = 0; }
15528 else { $usedivletters = 1; }
15529
15530 if (isset($attr['LINKS']) && (strtoupper($attr['LINKS'])=='ON' || $attr['LINKS']==1)) { $links = true; }
15531 else { $links = false; }
15532 $this->CreateIndex($cols, $reffontsize, $linespacing, $offset, $usedivletters, $divlettfontsize, $gap, $reffont,$divlettfont, $links);
15533 break;
15534 /*-- END INDEX --*/
15535
15536 /*-- WATERMARK --*/
15537
15538 case 'WATERMARKTEXT':
15539 if (isset($attr['CONTENT']) && $attr['CONTENT']) { $txt = htmlspecialchars_decode($attr['CONTENT'],ENT_QUOTES); } else { $txt = ''; }
15540 if (isset($attr['ALPHA']) && $attr['ALPHA']>0) { $alpha = $attr['ALPHA']; } else { $alpha = -1; }
15541 $this->SetWatermarkText($txt, $alpha);
15542 break;
15543
15544
15545 case 'WATERMARKIMAGE':
15546 if (isset($attr['SRC'])) { $src = $attr['SRC']; } else { $src = ''; }
15547 if (isset($attr['ALPHA']) && $attr['ALPHA']>0) { $alpha = $attr['ALPHA']; } else { $alpha = -1; }
15548 if (isset($attr['SIZE']) && $attr['SIZE']) {
15549 $size = $attr['SIZE'];
15550 if (strpos($size,',')) { $size = explode(',',$size); }
15551 }
15552 else { $size = 'D'; }
15553 if (isset($attr['POS']) && $attr['POS']) {
15554 $pos = $attr['POS'];
15555 if (strpos($pos,',')) { $pos = explode(',',$pos); }
15556 }
15557 else { $pos = 'P'; }
15558 $this->SetWatermarkImage($src, $alpha, $size, $pos);
15559 break;
15560 /*-- END WATERMARK --*/
15561
15562 /*-- BOOKMARKS --*/
15563 case 'BOOKMARK':
15564 if (isset($attr['CONTENT'])) {
15565 $objattr = array();
15566 $objattr['CONTENT'] = htmlspecialchars_decode($attr['CONTENT'],ENT_QUOTES);
15567 $objattr['type'] = 'bookmark';
15568 if (isset($attr['LEVEL']) && $attr['LEVEL']) { $objattr['bklevel'] = $attr['LEVEL']; } else { $objattr['bklevel'] = 0; }
15569 $e = "\xbb\xa4\xactype=bookmark,objattr=".serialize($objattr)."\xbb\xa4\xac";
15570 if($this->tableLevel) { $this->cell[$this->row][$this->col]['textbuffer'][] = array($e); } // *TABLES*
15571 else { // *TABLES*
15572 $this->textbuffer[] = array($e);
15573 } // *TABLES*
15574 }
15575 break;
15576 /*-- END BOOKMARKS --*/
15577
15578 /*-- ANNOTATIONS --*/
15579 case 'ANNOTATION':
15580
15581 //if (isset($attr['CONTENT']) && !$this->writingHTMLheader && !$this->writingHTMLfooter) { // Stops annotations in FixedPos
15582 if (isset($attr['CONTENT'])) {
15583 $objattr = array();
15584 $objattr['margin_top'] = 0;
15585 $objattr['margin_bottom'] = 0;
15586 $objattr['margin_left'] = 0;
15587 $objattr['margin_right'] = 0;
15588 $objattr['width'] = 0;
15589 $objattr['height'] = 0;
15590 $objattr['border_top']['w'] = 0;
15591 $objattr['border_bottom']['w'] = 0;
15592 $objattr['border_left']['w'] = 0;
15593 $objattr['border_right']['w'] = 0;
15594 $objattr['CONTENT'] = htmlspecialchars_decode($attr['CONTENT'],ENT_QUOTES);
15595 $objattr['type'] = 'annot';
15596 $objattr['POPUP'] = '';
15597 }
15598 else { break; }
15599 if (isset($attr['POS-X'])) { $objattr['POS-X'] = $attr['POS-X']; } else { $objattr['POS-X'] = 0; }
15600 if (isset($attr['POS-Y'])) { $objattr['POS-Y'] = $attr['POS-Y']; } else { $objattr['POS-Y'] = 0; }
15601 if (isset($attr['ICON'])) { $objattr['ICON'] = $attr['ICON']; } else { $objattr['ICON'] = 'Note'; }
15602 if (isset($attr['AUTHOR'])) { $objattr['AUTHOR'] = $attr['AUTHOR']; }
15603 else if (isset($attr['TITLE'])) { $objattr['AUTHOR'] = $attr['TITLE']; } else { $objattr['AUTHOR'] = ''; }
15604 if (isset($attr['FILE'])) { $objattr['FILE'] = $attr['FILE']; } else { $objattr['FILE'] = ''; }
15605 if (isset($attr['SUBJECT'])) { $objattr['SUBJECT'] = $attr['SUBJECT']; } else { $objattr['SUBJECT'] = ''; }
15606 if (isset($attr['OPACITY']) && $attr['OPACITY']>0 && $attr['OPACITY']<=1) { $objattr['OPACITY'] = $attr['OPACITY']; }
15607 else if ($this->annotMargin) { $objattr['OPACITY'] = 1; }
15608 else { $objattr['OPACITY'] = $this->annotOpacity; }
15609 if (isset($attr['COLOR'])) {
15610 $cor = $this->ConvertColor($attr['COLOR']);
15611 if ($cor) { $objattr['COLOR'] = $cor; }
15612 else { $objattr['COLOR'] = $this->ConvertColor('yellow'); }
15613 }
15614 else { $objattr['COLOR'] = $this->ConvertColor('yellow'); }
15615
15616 if (isset($attr['POPUP']) && !empty($attr['POPUP'])) {
15617 $pop = preg_split('/\s+/',trim($attr['POPUP']));
15618 if (count($pop)>1) { $objattr['POPUP'] = $pop; }
15619 else { $objattr['POPUP'] = true; }
15620 }
15621 $e = "\xbb\xa4\xactype=annot,objattr=".serialize($objattr)."\xbb\xa4\xac";
15622 if($this->tableLevel) { $this->cell[$this->row][$this->col]['textbuffer'][] = array($e); } // *TABLES*
15623 else { // *TABLES*
15624 $this->textbuffer[] = array($e);
15625 } // *TABLES*
15626 break;
15627 /*-- END ANNOTATIONS --*/
15628
15629
15630 /*-- COLUMNS --*/
15631 case 'COLUMNS': //added custom-tag
15632 if (isset($attr['COLUMN-COUNT']) && ($attr['COLUMN-COUNT'] || $attr['COLUMN-COUNT']==='0')) {
15633 // Close any open block tags
15634 for ($b= $this->blklvl;$b>0;$b--) { $this->CloseTag($this->blk[$b]['tag']); }
15635 if(!empty($this->textbuffer)) { //Output previously buffered content
15636 $this->printbuffer($this->textbuffer);
15637 $this->textbuffer=array();
15638 }
15639
15640 if (isset($attr['VALIGN']) && $attr['VALIGN']) {
15641 if ($attr['VALIGN'] == 'J') { $valign = 'J'; }
15642 else { $valign = $align[$attr['VALIGN']]; }
15643 }
15644 else { $valign = ''; }
15645 if (isset($attr['COLUMN-GAP']) && $attr['COLUMN-GAP']) { $this->SetColumns($attr['COLUMN-COUNT'],$valign,$attr['COLUMN-GAP']); }
15646 else { $this->SetColumns($attr['COLUMN-COUNT'],$valign); }
15647 }
15648 $this->ignorefollowingspaces = true;
15649 break;
15650
15651 case 'COLUMN_BREAK': //custom-tag
15652 case 'COLUMNBREAK': //custom-tag
15653 case 'NEWCOLUMN': //custom-tag
15654 $this->ignorefollowingspaces = true;
15655 $this->NewColumn();
15656 $this->ColumnAdjust = false; // disables all column height adjustment for the page.
15657 break;
15658
15659 /*-- END COLUMNS --*/
15660
15661
15662 case 'BDO':
15663 // $this->biDirectional = true;
15664 break;
15665
15666
15667 case 'TTZ':
15668 $this->ttz = true;
15669 $this->InlineProperties[$tag] = $this->saveInlineProperties();
15670 $this->setCSS(array('FONT-FAMILY'=>'czapfdingbats','FONT-WEIGHT'=>'normal','FONT-STYLE'=>'normal'),'INLINE');
15671 break;
15672
15673 case 'TTS':
15674 $this->tts = true;
15675 $this->InlineProperties[$tag] = $this->saveInlineProperties();
15676 $this->setCSS(array('FONT-FAMILY'=>'csymbol','FONT-WEIGHT'=>'normal','FONT-STYLE'=>'normal'),'INLINE');
15677 break;
15678
15679 case 'TTA':
15680 $this->tta = true;
15681 $this->InlineProperties[$tag] = $this->saveInlineProperties();
15682
15683 if (in_array($this->FontFamily,$this->mono_fonts)) {
15684 $this->setCSS(array('FONT-FAMILY'=>'ccourier'),'INLINE');
15685 }
15686 else if (in_array($this->FontFamily,$this->serif_fonts)) {
15687 $this->setCSS(array('FONT-FAMILY'=>'ctimes'),'INLINE');
15688 }
15689 else {
15690 $this->setCSS(array('FONT-FAMILY'=>'chelvetica'),'INLINE');
15691 }
15692 break;
15693
15694
15695
15696 // INLINE PHRASES OR STYLES
15697 case 'SUB':
15698 case 'SUP':
15699 case 'ACRONYM':
15700 case 'BIG':
15701 case 'SMALL':
15702 case 'INS':
15703 case 'S':
15704 case 'STRIKE':
15705 case 'DEL':
15706 case 'STRONG':
15707 case 'CITE':
15708 case 'Q':
15709 case 'EM':
15710 case 'B':
15711 case 'I':
15712 case 'U':
15713 case 'SAMP':
15714 case 'CODE':
15715 case 'KBD':
15716 case 'TT':
15717 case 'VAR':
15718 case 'FONT':
15719 case 'SPAN':
15720 /*-- ANNOTATIONS --*/
15721 if ($this->title2annots && isset($attr['TITLE'])) {
15722 $objattr = array();
15723 $objattr['margin_top'] = 0;
15724 $objattr['margin_bottom'] = 0;
15725 $objattr['margin_left'] = 0;
15726 $objattr['margin_right'] = 0;
15727 $objattr['width'] = 0;
15728 $objattr['height'] = 0;
15729 $objattr['border_top']['w'] = 0;
15730 $objattr['border_bottom']['w'] = 0;
15731 $objattr['border_left']['w'] = 0;
15732 $objattr['border_right']['w'] = 0;
15733
15734 $objattr['CONTENT'] = $attr['TITLE'];
15735 $objattr['type'] = 'annot';
15736 $objattr['POS-X'] = 0;
15737 $objattr['POS-Y'] = 0;
15738 $objattr['ICON'] = 'Comment';
15739 $objattr['AUTHOR'] = '';
15740 $objattr['SUBJECT'] = '';
15741 $objattr['OPACITY'] = $this->annotOpacity;
15742 $objattr['COLOR'] = $this->ConvertColor('yellow');
15743 $annot = "\xbb\xa4\xactype=annot,objattr=".serialize($objattr)."\xbb\xa4\xac";
15744 }
15745 /*-- END ANNOTATIONS --*/
15746
15747 if ($tag == 'SPAN') {
15748 $this->spanlvl++;
15749 $this->InlineProperties['SPAN'][$this->spanlvl] = $this->saveInlineProperties();
15750 if (isset($annot)) { $this->InlineAnnots[$tag][$this->spanlvl] = $annot; } // *ANNOTATIONS*
15751 }
15752 else {
15753 $this->InlineProperties[$tag] = $this->saveInlineProperties();
15754 if (isset($annot)) { $this->InlineAnnots[$tag] = $annot; } // *ANNOTATIONS*
15755 }
15756 $properties = $this->MergeCSS('INLINE',$tag,$attr);
15757 if (!empty($properties)) $this->setCSS($properties,'INLINE');
15758 break;
15759
15760
15761 case 'A':
15762 if (isset($attr['NAME']) and $attr['NAME'] != '') {
15763 $e = '';
15764 /*-- BOOKMARKS --*/
15765 if ($this->anchor2Bookmark) {
15766 $objattr = array();
15767 $objattr['CONTENT'] = htmlspecialchars_decode($attr['NAME'],ENT_QUOTES);
15768 $objattr['type'] = 'bookmark';
15769 if (isset($attr['LEVEL']) && $attr['LEVEL']) { $objattr['bklevel'] = $attr['LEVEL']; } else { $objattr['bklevel'] = 0; }
15770 $e = "\xbb\xa4\xactype=bookmark,objattr=".serialize($objattr)."\xbb\xa4\xac";
15771 }
15772 /*-- END BOOKMARKS --*/
15773 if($this->tableLevel) { // *TABLES*
15774 $this->_saveCellTextBuffer($e, '', $attr['NAME']); // mPDF 5.3.99 // *TABLES*
15775 } // *TABLES*
15776 else { // *TABLES*
15777 $this->_saveTextBuffer($e, '', $attr['NAME']); // mPDF 5.3.99 //an internal link (adds a space for recognition)
15778 } // *TABLES*
15779 }
15780 if (isset($attr['HREF'])) {
15781 $this->InlineProperties['A'] = $this->saveInlineProperties();
15782 $properties = $this->MergeCSS('',$tag,$attr);
15783 if (!empty($properties)) $this->setCSS($properties,'INLINE');
15784 $this->HREF=htmlspecialchars_decode(urldecode($attr['HREF'])); // mPDF 5.3.95
15785 }
15786 break;
15787
15788
15789
15790 case 'BR':
15791 // Added mPDF 3.0 Float DIV - CLEAR
15792 if (isset($attr['STYLE'])) {
15793 $properties = $this->readInlineCSS($attr['STYLE']);
15794 if (isset($properties['CLEAR'])) { $this->ClearFloats(strtoupper($properties['CLEAR']),$this->blklvl); } // *CSS-FLOAT*
15795 }
15796
15797
15798 /*-- TABLES --*/
15799 if($this->tableLevel) {
15800
15801 if ($this->blockjustfinished || $this->listjustfinished) {
15802 $this->_saveCellTextBuffer("\n"); // mPDF 5.3.99
15803 }
15804
15805 $this->_saveCellTextBuffer("\n"); // mPDF 5.3.99
15806 if (!isset($this->cell[$this->row][$this->col]['maxs'])) {
15807 $this->cell[$this->row][$this->col]['maxs'] = $this->cell[$this->row][$this->col]['s'];
15808 }
15809 elseif($this->cell[$this->row][$this->col]['maxs'] < $this->cell[$this->row][$this->col]['s']) {
15810 $this->cell[$this->row][$this->col]['maxs'] = $this->cell[$this->row][$this->col]['s'];
15811 }
15812 $this->cell[$this->row][$this->col]['s'] = 0 ;// reset
15813 }
15814 else {
15815 /*-- END TABLES --*/
15816 if (count($this->textbuffer)) {
15817 $this->textbuffer[count($this->textbuffer)-1][0] = preg_replace('/ $/','',$this->textbuffer[count($this->textbuffer)-1][0]);
15818 }
15819 $this->_saveTextBuffer("\n"); // mPDF 5.3.99
15820 } // *TABLES*
15821 $this->ignorefollowingspaces = true;
15822 $this->blockjustfinished=false;
15823 $this->listjustfinished=false;
15824
15825 $this->linebreakjustfinished=true;
15826 break;
15827
15828
15829 // *********** BLOCKS ********************
15830
15831 //NB $outerblocktags = array('DIV','FORM','CENTER','DL');
15832 //NB $innerblocktags = array('P','BLOCKQUOTE','ADDRESS','PRE',''H1','H2','H3','H4','H5','H6','DT','DD');
15833
15834 case 'PRE':
15835 $this->ispre=true; // ADDED - Prevents left trim of textbuffer in printbuffer()
15836
15837 case 'DIV':
15838 case 'FORM':
15839 case 'CENTER':
15840
15841 case 'BLOCKQUOTE':
15842 case 'ADDRESS':
15843
15844 case 'CAPTION': // mPDF 5.3.56
15845 case 'P':
15846 case 'H1':
15847 case 'H2':
15848 case 'H3':
15849 case 'H4':
15850 case 'H5':
15851 case 'H6':
15852 case 'DL':
15853 case 'DT':
15854 case 'DD':
15855 $p = $this->PreviewBlockCSS($tag,$attr);
15856 if(isset($p['DISPLAY']) && strtolower($p['DISPLAY'])=='none') {
15857 $this->blklvl++;
15858 $this->blk[$this->blklvl]['hide'] = true;
15859 return;
15860 }
15861 // mPDF 5.3.56
15862 if($tag == 'CAPTION') {
15863 // position is written in AdjstHTML
15864 if (isset($attr['POSITION']) && strtolower($attr['POSITION'])=='bottom') { $divpos = 'B'; }
15865 else { $divpos = 'T'; }
15866 if (isset($attr['ALIGN']) && strtolower($attr['ALIGN'])=='bottom') { $cappos = 'B'; }
15867 else if (isset($p['CAPTION-SIDE']) && strtolower($p['CAPTION-SIDE'])=='bottom') { $cappos = 'B'; }
15868 else { $cappos = 'T'; }
15869 if (isset($attr['ALIGN'])) { unset($attr['ALIGN']); } // mPDF 5.3.A8
15870 if ($cappos != $divpos) {
15871 $this->blklvl++;
15872 $this->blk[$this->blklvl]['hide'] = true;
15873 return;
15874 }
15875 }
15876
15877 /*-- FORMS --*/
15878 if($tag == 'FORM') {
15879 if (isset($attr['METHOD']) && strtolower($attr['METHOD'])=='get') { $this->form->formMethod = 'GET'; }
15880 else { $this->form->formMethod = 'POST'; }
15881 if (isset($attr['ACTION'])) { $this->form->formAction = $attr['ACTION']; }
15882 else { $this->form->formAction = ''; }
15883 }
15884 /*-- END FORMS --*/
15885
15886
15887 /*-- CSS-POSITION --*/
15888 if ((isset($p['POSITION']) && (strtolower($p['POSITION'])=='fixed' || strtolower($p['POSITION'])=='absolute')) && $this->blklvl==0) {
15889 if ($this->inFixedPosBlock) {
15890 $this->Error("Cannot nest block with position:fixed or position:absolute");
15891 }
15892 $this->inFixedPosBlock = true;
15893 return;
15894 }
15895 /*-- END CSS-POSITION --*/
15896 // Start Block
15897 $this->ignorefollowingspaces = true;
15898
15899 if ($this->blockjustfinished && !count($this->textbuffer) && $this->y != $this->tMargin && $this->collapseBlockMargins) { $lastbottommargin = $this->lastblockbottommargin; }
15900 else { $lastbottommargin = 0; }
15901 $this->lastblockbottommargin = 0;
15902 $this->blockjustfinished=false;
15903
15904 /*-- LISTS --*/
15905 if ($this->listlvl>0) { return; }
15906 /*-- END LISTS --*/
15907
15908 $this->InlineProperties = array();
15909 $this->spanlvl = 0;
15910 $this->listjustfinished=false;
15911 $this->divbegin=true;
15912
15913 $this->linebreakjustfinished=false;
15914
15915 /*-- TABLES --*/
15916 if ($this->tableLevel) {
15917
15918 // If already something on the line
15919 if ($this->cell[$this->row][$this->col]['s'] > 0 && !$this->nestedtablejustfinished ) {
15920 $this->_saveCellTextBuffer("\n"); // mPDF 5.3.99
15921 if (!isset($this->cell[$this->row][$this->col]['maxs'])) {
15922 $this->cell[$this->row][$this->col]['maxs'] = $this->cell[$this->row][$this->col]['s'];
15923 }
15924 elseif($this->cell[$this->row][$this->col]['maxs'] < $this->cell[$this->row][$this->col]['s']) {
15925 $this->cell[$this->row][$this->col]['maxs'] = $this->cell[$this->row][$this->col]['s'];
15926 }
15927 $this->cell[$this->row][$this->col]['s'] = 0 ;// reset
15928 }
15929 // Cannot set block properties inside table - use Bold to indicate h1-h6
15930 if ($tag == 'CENTER' && $this->tdbegin) { $this->cell[$this->row][$this->col]['a'] = $align['center']; }
15931
15932 $this->InlineProperties['BLOCKINTABLE'] = $this->saveInlineProperties();
15933 $properties = $this->MergeCSS('',$tag,$attr);
15934 if (!empty($properties)) $this->setCSS($properties,'INLINE');
15935
15936
15937 break;
15938 }
15939 /*-- END TABLES --*/
15940
15941 if ($tag == 'P' || $tag == 'DT' || $tag == 'DD') { $this->lastoptionaltag = $tag; } // Save current HTML specified optional endtag
15942 else { $this->lastoptionaltag = ''; }
15943
15944 if ($this->lastblocklevelchange == 1) { $blockstate = 1; } // Top margins/padding only
15945 else if ($this->lastblocklevelchange < 1) { $blockstate = 0; } // NO margins/padding
15946 $this->printbuffer($this->textbuffer,$blockstate);
15947 $this->textbuffer=array();
15948
15949 // mPDF 5.3.03
15950 $save_blklvl = $this->blklvl;
15951 $save_blk = $this->blk;
15952 $save_silp = $this->saveInlineProperties();
15953 $save_spanlvl = $this->spanlvl;
15954 $save_ilp = $this->InlineProperties;
15955
15956 $this->blklvl++;
15957
15958 $currblk =& $this->blk[$this->blklvl];
15959 $this->initialiseBlock($currblk);
15960 $prevblk =& $this->blk[$this->blklvl-1];
15961
15962 $currblk['tag'] = $tag;
15963 $currblk['attr'] = $attr;
15964
15965 $this->Reset();
15966 $properties = $this->MergeCSS('BLOCK',$tag,$attr);
15967 $pagesel = '';
15968 /*-- CSS-PAGE --*/
15969
15970 if (isset($properties['PAGE'])) { $pagesel = $properties['PAGE']; }
15971 /*-- END CSS-PAGE --*/
15972
15973 // If page-box has changed AND/OR PAGE-BREAK-BEFORE
15974 $save_cols = false;
15975 if (($pagesel && $pagesel != $this->page_box['current']) || (isset($properties['PAGE-BREAK-BEFORE']) && $properties['PAGE-BREAK-BEFORE'])) {
15976 if ($this->blklvl>1) {
15977 // Close any open block tags
15978 for ($b= $this->blklvl;$b>0;$b--) { $this->CloseTag($this->blk[$b]['tag']); }
15979 // Output any text left in buffer
15980 if (count($this->textbuffer)) { $this->printbuffer($this->textbuffer); $this->textbuffer=array(); }
15981 }
15982 /*-- COLUMNS --*/
15983 if ($this->ColActive) {
15984 $save_cols = true;
15985 $save_nbcol = $this->NbCol; // other values of gap and vAlign will not change by setting Columns off
15986 $this->SetColumns(0);
15987 }
15988 /*-- END COLUMNS --*/
15989
15990
15991 // Must Add new page if changed page properties
15992 if (isset($properties['PAGE-BREAK-BEFORE'])) {
15993 if (strtoupper($properties['PAGE-BREAK-BEFORE']) == 'RIGHT') { $this->AddPage($this->CurOrientation,'NEXT-ODD','','','','','', '','', '','','','','','',0,0,0,0,$pagesel); }
15994 else if (strtoupper($properties['PAGE-BREAK-BEFORE']) == 'LEFT') { $this->AddPage($this->CurOrientation,'NEXT-EVEN','','','','','', '','', '','','','','','',0,0,0,0,$pagesel); }
15995 else if (strtoupper($properties['PAGE-BREAK-BEFORE']) == 'ALWAYS') { $this->AddPage($this->CurOrientation,'','','','','','', '','', '','','','','','',0,0,0,0,$pagesel); }
15996 else if ($this->page_box['current'] != $pagesel) { $this->AddPage($this->CurOrientation,'','','','','','', '','', '','','','','','',0,0,0,0,$pagesel); } // *CSS-PAGE*
15997 }
15998 /*-- CSS-PAGE --*/
15999 else if ($pagesel != $this->page_box['current']) { $this->AddPage($this->CurOrientation,'','','','','','', '','', '','','','','','',0,0,0,0,$pagesel); }
16000 /*-- END CSS-PAGE --*/
16001
16002 // if using htmlheaders, the headers need to be rewritten when new page
16003 // done by calling WriteHTML() within resethtmlheaders
16004 // so block is reset to 0 - now we need to resurrect it
16005 // As in WriteHTML() initialising
16006 // mPDF 5.3.03
16007 if (!($this->restoreBlockPagebreaks && isset($properties['PAGE-BREAK-BEFORE']) && $properties['PAGE-BREAK-BEFORE'])) {
16008 $this->blklvl = 0;
16009 $this->lastblocklevelchange = 0;
16010 $this->blk = array();
16011 $this->initialiseBlock($this->blk[0]);
16012 $this->blk[0]['width'] =& $this->pgwidth;
16013 $this->blk[0]['inner_width'] =& $this->pgwidth;
16014 $this->blk[0]['blockContext'] = $this->blockContext;
16015 $properties = $this->MergeCSS('BLOCK','BODY','');
16016 $this->setCSS($properties,'','BODY');
16017 $this->blklvl++;
16018 $currblk =& $this->blk[$this->blklvl];
16019 $prevblk =& $this->blk[$this->blklvl-1];
16020
16021 $this->initialiseBlock($currblk);
16022 $currblk['tag'] = $tag;
16023 $currblk['attr'] = $attr;
16024
16025 $this->Reset();
16026 $properties = $this->MergeCSS('BLOCK',$tag,$attr);
16027 }
16028 /*-- COLUMNS --*/
16029 if ($save_cols) {
16030 // Restore columns
16031 $this->SetColumns($save_nbcol,$this->colvAlign,$this->ColGap);
16032 }
16033 /*-- END COLUMNS --*/
16034 // mPDF 5.3.03
16035 if ($this->restoreBlockPagebreaks && isset($properties['PAGE-BREAK-BEFORE']) && $properties['PAGE-BREAK-BEFORE']) {
16036 $this->blk = $save_blk;
16037 // Re-open block tags
16038 $t = $this->blk[0]['tag'];
16039 $a = $this->blk[0]['attr'];
16040 $this->blklvl = 0;
16041 for ($b=0; $b<=$save_blklvl;$b++) {
16042 $tc = $t;
16043 $ac = $a;
16044 $t = $this->blk[$b+1]['tag'];
16045 $a = $this->blk[$b+1]['attr'];
16046 unset($this->blk[$b+1]);
16047 $this->OpenTag($tc,$ac);
16048 }
16049 $this->spanlvl = $save_spanlvl;
16050 $this->InlineProperties = $save_ilp;
16051 $this->restoreInlineProperties($save_silp);
16052 }
16053 }
16054
16055 if (isset($properties['PAGE-BREAK-INSIDE']) && strtoupper($properties['PAGE-BREAK-INSIDE']) == 'AVOID' && !$this->ColActive && !$this->keep_block_together) {
16056 $currblk['keep_block_together'] = 1;
16057 $this->kt_y00 = $this->y;
16058 $this->kt_p00 = $this->page;
16059 $this->keep_block_together = 1;
16060 $this->divbuffer = array();
16061 $this->ktLinks = array();
16062 $this->ktAnnots = array();
16063 $this->ktForms = array();
16064 $this->ktBlock = array();
16065 $this->ktReference = array();
16066 $this->ktBMoutlines = array();
16067 $this->_kttoc = array();
16068 }
16069 // mPDF 5.3.76
16070 if ($lastbottommargin && isset($properties['MARGIN-TOP']) && $properties['MARGIN-TOP'] && empty($properties['FLOAT'])) { $currblk['lastbottommargin'] = $lastbottommargin; }
16071
16072 $this->setCSS($properties,'BLOCK',$tag); //name(id/class/style) found in the CSS array!
16073 $currblk['InlineProperties'] = $this->saveInlineProperties();
16074
16075 // mPDF 5.3.42 VISIBILITY
16076 if (isset($properties['VISIBILITY'])) {
16077 $v = strtolower($properties['VISIBILITY']);
16078 if (($v == 'hidden' || $v == 'printonly' || $v == 'screenonly') && $this->visibility=='visible' && !$this->tableLevel) {
16079 $currblk['visibility'] = $v;
16080 $this->SetVisibility($v);
16081 }
16082 }
16083
16084 if(isset($attr['DIR']) && $attr['DIR']) { $currblk['direction'] = strtolower($attr['DIR']); }
16085 if(isset($attr['ALIGN']) && $attr['ALIGN']) { $currblk['block-align'] = $align[strtolower($attr['ALIGN'])]; }
16086
16087 if (isset($properties['HEIGHT'])) {
16088 $currblk['css_set_height'] = $this->ConvertSize($properties['HEIGHT'],($this->h - $this->tMargin - $this->bMargin),$this->FontSize,false);
16089 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); }
16090 }
16091 else { $currblk['css_set_height'] = false; }
16092
16093
16094 // Added mPDF 3.0 Float DIV
16095 if (isset($prevblk['blockContext'])) { $currblk['blockContext'] = $prevblk['blockContext'] ; } // *CSS-FLOAT*
16096
16097 if (isset($properties['CLEAR'])) { $this->ClearFloats(strtoupper($properties['CLEAR']), $this->blklvl-1); } // *CSS-FLOAT*
16098
16099 $container_w = $prevblk['inner_width'];
16100 $bdr = $currblk['border_right']['w'];
16101 $bdl = $currblk['border_left']['w'];
16102 $pdr = $currblk['padding_right'];
16103 $pdl = $currblk['padding_left'];
16104
16105 if (isset($currblk['css_set_width'])) { $setwidth = $currblk['css_set_width']; }
16106 else { $setwidth = 0; }
16107
16108 /*-- CSS-FLOAT --*/
16109 if (isset($properties['FLOAT']) && strtoupper($properties['FLOAT']) == 'RIGHT' && !$this->ColActive) {
16110 // Cancel Keep-Block-together
16111 $currblk['keep_block_together'] = false;
16112 $this->kt_y00 = '';
16113 $this->keep_block_together = 0;
16114
16115 $this->blockContext++;
16116 $currblk['blockContext'] = $this->blockContext;
16117
16118 list($l_exists, $r_exists, $l_max, $r_max, $l_width, $r_width) = $this->GetFloatDivInfo($this->blklvl-1);
16119
16120 // DIV is too narrow for text to fit!
16121 $maxw = $container_w - $l_width - $r_width;
16122 if (($setwidth + $currblk['margin_right'] + $bdl + $pdl + $bdr + $pdr) > $maxw || ($maxw - ($currblk['margin_right'] + $bdl + $pdl + $bdr + $pdr)) < (2*$this->GetCharWidth('W',false))) { // mPDF 5.3.04
16123 // Too narrow to fit - try to move down past L or R float
16124 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))) { // mPDF 5.3.04
16125 $this->ClearFloats('LEFT', $this->blklvl-1);
16126 }
16127 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))) { // mPDF 5.3.04
16128 $this->ClearFloats('RIGHT', $this->blklvl-1);
16129 }
16130 else { $this->ClearFloats('BOTH', $this->blklvl-1); }
16131 list($l_exists, $r_exists, $l_max, $r_max, $l_width, $r_width) = $this->GetFloatDivInfo($this->blklvl-1);
16132 }
16133
16134 if ($r_exists) { $currblk['margin_right'] += $r_width; }
16135
16136 $currblk['float'] = 'R';
16137 $currblk['float_start_y'] = $this->y;
16138 if ($currblk['css_set_width']) {
16139 $currblk['margin_left'] = $container_w - ($setwidth + $bdl + $pdl + $bdr + $pdr + $currblk['margin_right']);
16140 $currblk['float_width'] = ($setwidth + $bdl + $pdl + $bdr + $pdr + $currblk['margin_right']);
16141 }
16142 else {
16143 // *** If no width set - would need to buffer and keep track of max width, then Right-align if not full width
16144 // and do borders and backgrounds - For now - just set to maximum width left
16145
16146 if ($l_exists) { $currblk['margin_left'] += $l_width; }
16147 $currblk['css_set_width'] = $container_w - ($currblk['margin_left'] + $currblk['margin_right'] + $bdl + $pdl + $bdr + $pdr);
16148
16149 $currblk['float_width'] = ($currblk['css_set_width'] + $bdl + $pdl + $bdr + $pdr + $currblk['margin_right']);
16150 }
16151 }
16152 else if (isset($properties['FLOAT']) && strtoupper($properties['FLOAT']) == 'LEFT' && !$this->ColActive) {
16153 // Cancel Keep-Block-together
16154 $currblk['keep_block_together'] = false;
16155 $this->kt_y00 = '';
16156 $this->keep_block_together = 0;
16157
16158 $this->blockContext++;
16159 $currblk['blockContext'] = $this->blockContext;
16160
16161 list($l_exists, $r_exists, $l_max, $r_max, $l_width, $r_width) = $this->GetFloatDivInfo($this->blklvl-1);
16162
16163 // DIV is too narrow for text to fit!
16164 $maxw = $container_w - $l_width - $r_width;
16165 if (($setwidth + $currblk['margin_left'] + $bdl + $pdl + $bdr + $pdr) > $maxw || ($maxw - ($currblk['margin_left'] + $bdl + $pdl + $bdr + $pdr)) < (2*$this->GetCharWidth('W',false))) { // mPDF 5.3.04
16166 // Too narrow to fit - try to move down past L or R float
16167 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))) { // mPDF 5.3.04
16168 $this->ClearFloats('LEFT', $this->blklvl-1);
16169 }
16170 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))) { // mPDF 5.3.04
16171 $this->ClearFloats('RIGHT', $this->blklvl-1);
16172 }
16173 else { $this->ClearFloats('BOTH', $this->blklvl-1); }
16174 list($l_exists, $r_exists, $l_max, $r_max, $l_width, $r_width) = $this->GetFloatDivInfo($this->blklvl-1);
16175 }
16176
16177 if ($l_exists) { $currblk['margin_left'] += $l_width; }
16178
16179 $currblk['float'] = 'L';
16180 $currblk['float_start_y'] = $this->y;
16181 if ($setwidth) {
16182 $currblk['margin_right'] = $container_w - ($setwidth + $bdl + $pdl + $bdr + $pdr + $currblk['margin_left']);
16183 $currblk['float_width'] = ($setwidth + $bdl + $pdl + $bdr + $pdr + $currblk['margin_left']);
16184 }
16185 else {
16186 // *** If no width set - would need to buffer and keep track of max width, then Right-align if not full width
16187 // and do borders and backgrounds - For now - just set to maximum width left
16188
16189 if ($r_exists) { $currblk['margin_right'] += $r_width; }
16190 $currblk['css_set_width'] = $container_w - ($currblk['margin_left'] + $currblk['margin_right'] + $bdl + $pdl + $bdr + $pdr);
16191
16192 $currblk['float_width'] = ($currblk['css_set_width'] + $bdl + $pdl + $bdr + $pdr + $currblk['margin_left']);
16193 }
16194 }
16195
16196 else {
16197 // Don't allow overlap - if floats present - adjust padding to avoid overlap with Floats
16198 list($l_exists, $r_exists, $l_max, $r_max, $l_width, $r_width) = $this->GetFloatDivInfo($this->blklvl-1);
16199 $maxw = $container_w - $l_width - $r_width;
16200 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))) { // mPDF 5.3.04
16201 // Too narrow to fit - try to move down past L or R float
16202 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))) { // mPDF 5.3.04
16203 $this->ClearFloats('LEFT', $this->blklvl-1);
16204 }
16205 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))) { // mPDF 5.3.04
16206 $this->ClearFloats('RIGHT', $this->blklvl-1);
16207 }
16208 else { $this->ClearFloats('BOTH', $this->blklvl-1); }
16209 list($l_exists, $r_exists, $l_max, $r_max, $l_width, $r_width) = $this->GetFloatDivInfo($this->blklvl-1);
16210 }
16211 if ($r_exists) { $currblk['padding_right'] = max(($r_width-$currblk['margin_right']-$bdr), $pdr); }
16212 if ($l_exists) { $currblk['padding_left'] = max(($l_width-$currblk['margin_left']-$bdl), $pdl); }
16213 }
16214 /*-- END CSS-FLOAT --*/
16215
16216
16217 /*-- BORDER-RADIUS --*/
16218 // Automatically increase padding if required for border-radius
16219 if ($this->autoPadding && !$this->ColActive && !$this->keep_block_together) {
16220 if ($currblk['border_radius_TL_H']>$currblk['padding_left'] && $currblk['border_radius_TL_V']>$currblk['padding_top']) {
16221 if ($currblk['border_radius_TL_H']>$currblk['border_radius_TL_V']) {
16222 $this->_borderPadding($currblk['border_radius_TL_H'],$currblk['border_radius_TL_V'], $currblk['padding_left'], $currblk['padding_top']);
16223 }
16224 else {
16225 $this->_borderPadding($currblk['border_radius_TL_V'],$currblk['border_radius_TL_H'], $currblk['padding_top'], $currblk['padding_left']);
16226 }
16227 }
16228 if ($currblk['border_radius_TR_H']>$currblk['padding_right'] && $currblk['border_radius_TR_V']>$currblk['padding_top']) {
16229 if ($currblk['border_radius_TR_H']>$currblk['border_radius_TR_V']) {
16230 $this->_borderPadding($currblk['border_radius_TR_H'],$currblk['border_radius_TR_V'], $currblk['padding_right'], $currblk['padding_top']);
16231 }
16232 else {
16233 $this->_borderPadding($currblk['border_radius_TR_V'],$currblk['border_radius_TR_H'], $currblk['padding_top'], $currblk['padding_right']);
16234 }
16235 }
16236 if ($currblk['border_radius_BL_H']>$currblk['padding_left'] && $currblk['border_radius_BL_V']>$currblk['padding_bottom']) {
16237 if ($currblk['border_radius_BL_H']>$currblk['border_radius_BL_V']) {
16238 $this->_borderPadding($currblk['border_radius_BL_H'],$currblk['border_radius_BL_V'], $currblk['padding_left'], $currblk['padding_bottom']);
16239 }
16240 else {
16241 $this->_borderPadding($currblk['border_radius_BL_V'],$currblk['border_radius_BL_H'], $currblk['padding_bottom'], $currblk['padding_left']);
16242 }
16243 }
16244 if ($currblk['border_radius_BR_H']>$currblk['padding_right'] && $currblk['border_radius_BR_V']>$currblk['padding_bottom']) {
16245 if ($currblk['border_radius_BR_H']>$currblk['border_radius_BR_V']) {
16246 $this->_borderPadding($currblk['border_radius_BR_H'],$currblk['border_radius_BR_V'], $currblk['padding_right'], $currblk['padding_bottom']);
16247 }
16248 else {
16249 $this->_borderPadding($currblk['border_radius_BR_V'],$currblk['border_radius_BR_H'], $currblk['padding_bottom'], $currblk['padding_right']);
16250 }
16251 }
16252 }
16253 /*-- END BORDER-RADIUS --*/
16254
16255
16256 // Hanging indent - if negative indent: ensure padding is >= indent
16257 if(!isset($currblk['text_indent'])) { $currblk['text_indent'] = null; }
16258 if(!isset($currblk['inner_width'])) { $currblk['inner_width'] = null; }
16259 $cbti = $this->ConvertSize($currblk['text_indent'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
16260 if ($cbti < 0) {
16261 $hangind = -($cbti);
16262 if ($currblk['direction'] == 'rtl') { // *RTL*
16263 $currblk['padding_right'] = max($currblk['padding_right'],$hangind); // *RTL*
16264 } // *RTL*
16265 else { // *RTL*
16266 $currblk['padding_left'] = max($currblk['padding_left'],$hangind);
16267 } // *RTL*
16268 }
16269
16270 if (isset($currblk['css_set_width'])) {
16271 if (isset($properties['MARGIN-LEFT']) && isset($properties['MARGIN-RIGHT']) && strtolower($properties['MARGIN-LEFT'])=='auto' && strtolower($properties['MARGIN-RIGHT'])=='auto') {
16272 // Try to reduce margins to accomodate - if still too wide, set margin-right/left=0 (reduces width)
16273 $anyextra = $prevblk['inner_width'] - ($currblk['css_set_width'] + $currblk['border_left']['w'] + $currblk['padding_left'] + $currblk['border_right']['w'] + $currblk['padding_right']);
16274 if ($anyextra>0) {
16275 $currblk['margin_left'] = $currblk['margin_right'] = $anyextra /2;
16276 }
16277 else {
16278 $currblk['margin_left'] = $currblk['margin_right'] = 0;
16279 }
16280 }
16281 else if (isset($properties['MARGIN-LEFT']) && strtolower($properties['MARGIN-LEFT'])=='auto') {
16282 // Try to reduce margin-left to accomodate - if still too wide, set margin-left=0 (reduces width)
16283 $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']);
16284 if ($currblk['margin_left'] < 0) {
16285 $currblk['margin_left'] = 0;
16286 }
16287 }
16288 else if (isset($properties['MARGIN-RIGHT']) && strtolower($properties['MARGIN-RIGHT'])=='auto') {
16289 // Try to reduce margin-right to accomodate - if still too wide, set margin-right=0 (reduces width)
16290 $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']);
16291 if ($currblk['margin_right'] < 0) {
16292 $currblk['margin_right'] = 0;
16293 }
16294 }
16295 else {
16296 if ($currblk['direction'] == 'rtl') { // *RTL*
16297 // Try to reduce margin-left to accomodate - if still too wide, set margin-left=0 (reduces width)
16298 $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*
16299 if ($currblk['margin_left'] < 0) { // *RTL*
16300 $currblk['margin_left'] = 0; // *RTL*
16301 } // *RTL*
16302 } // *RTL*
16303 else { // *RTL*
16304 // Try to reduce margin-right to accomodate - if still too wide, set margin-right=0 (reduces width)
16305 $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']);
16306 if ($currblk['margin_right'] < 0) {
16307 $currblk['margin_right'] = 0;
16308 }
16309 } // *RTL*
16310 }
16311 }
16312
16313 $currblk['outer_left_margin'] = $prevblk['outer_left_margin'] + $currblk['margin_left'] + $prevblk['border_left']['w'] + $prevblk['padding_left'];
16314 $currblk['outer_right_margin'] = $prevblk['outer_right_margin'] + $currblk['margin_right'] + $prevblk['border_right']['w'] + $prevblk['padding_right'];
16315
16316 $currblk['width'] = $this->pgwidth - ($currblk['outer_right_margin'] + $currblk['outer_left_margin']);
16317 $currblk['inner_width'] = $currblk['width'] - ($currblk['border_left']['w'] + $currblk['padding_left'] + $currblk['border_right']['w'] + $currblk['padding_right']);
16318
16319 // Check DIV is not now too narrow to fit text
16320 $mw = 2*$this->GetCharWidth('W',false); // mPDF 5.3.04
16321 if ($currblk['inner_width'] < $mw) {
16322 $currblk['padding_left'] = 0;
16323 $currblk['padding_right'] = 0;
16324 $currblk['border_left']['w'] = 0.2;
16325 $currblk['border_right']['w'] = 0.2;
16326 $currblk['margin_left'] = 0;
16327 $currblk['margin_right'] = 0;
16328 $currblk['outer_left_margin'] = $prevblk['outer_left_margin'] + $currblk['margin_left'] + $prevblk['border_left']['w'] + $prevblk['padding_left'];
16329 $currblk['outer_right_margin'] = $prevblk['outer_right_margin'] + $currblk['margin_right'] + $prevblk['border_right']['w'] + $prevblk['padding_right'];
16330 $currblk['width'] = $this->pgwidth - ($currblk['outer_right_margin'] + $currblk['outer_left_margin']);
16331 $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']);
16332 // if ($currblk['inner_width'] < $mw) { $this->Error("DIV is too narrow for text to fit!"); }
16333 }
16334
16335 $this->x = $this->lMargin + $currblk['outer_left_margin'];
16336
16337 /*-- BACKGROUNDS --*/
16338 if (isset($properties['BACKGROUND-IMAGE']) && $properties['BACKGROUND-IMAGE'] && !$this->kwt && !$this->ColActive && !$this->keep_block_together) {
16339 $ret = $this->SetBackground($properties, $currblk['inner_width']);
16340 if ($ret) { $currblk['background-image'] = $ret; }
16341 }
16342 /*-- END BACKGROUNDS --*/
16343
16344 /*-- TABLES --*/
16345 if ($this->use_kwt && isset($attr['KEEP-WITH-TABLE']) && !$this->ColActive && !$this->keep_block_together) {
16346 $this->kwt = true;
16347 $this->kwt_y0 = $this->y;
16348 $this->kwt_x0 = $this->x;
16349 $this->kwt_height = 0;
16350 $this->kwt_buffer = array();
16351 $this->kwt_Links = array();
16352 $this->kwt_Annots = array();
16353 $this->kwt_moved = false;
16354 $this->kwt_saved = false;
16355 $this->kwt_Reference = array();
16356 $this->kwt_BMoutlines = array();
16357 $this->kwt_toc = array();
16358 }
16359 else {
16360 /*-- END TABLES --*/
16361 $this->kwt = false;
16362 } // *TABLES*
16363
16364 //Save x,y coords in case we need to print borders...
16365 $currblk['y0'] = $this->y;
16366 $currblk['x0'] = $this->x;
16367 $currblk['startpage'] = $this->page;
16368 $this->oldy = $this->y;
16369
16370 $this->lastblocklevelchange = 1 ;
16371
16372 break;
16373
16374 case 'HR':
16375 // Added mPDF 3.0 Float DIV - CLEAR
16376 if (isset($attr['STYLE'])) {
16377 $properties = $this->readInlineCSS($attr['STYLE']);
16378 if (isset($properties['CLEAR'])) { $this->ClearFloats(strtoupper($properties['CLEAR']),$this->blklvl); } // *CSS-FLOAT*
16379 }
16380
16381 $this->ignorefollowingspaces = true;
16382
16383 $objattr = array();
16384 $objattr['margin_top'] = 0;
16385 $objattr['margin_bottom'] = 0;
16386 $objattr['margin_left'] = 0;
16387 $objattr['margin_right'] = 0;
16388 $objattr['width'] = 0;
16389 $objattr['height'] = 0;
16390 $objattr['border_top']['w'] = 0;
16391 $objattr['border_bottom']['w'] = 0;
16392 $objattr['border_left']['w'] = 0;
16393 $objattr['border_right']['w'] = 0;
16394 $properties = $this->MergeCSS('',$tag,$attr);
16395 if (isset($properties['MARGIN-TOP'])) { $objattr['margin_top'] = $this->ConvertSize($properties['MARGIN-TOP'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
16396 if (isset($properties['MARGIN-BOTTOM'])) { $objattr['margin_bottom'] = $this->ConvertSize($properties['MARGIN-BOTTOM'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
16397 if (isset($properties['WIDTH'])) { $objattr['width'] = $this->ConvertSize($properties['WIDTH'],$this->blk[$this->blklvl]['inner_width']); }
16398 if (isset($properties['TEXT-ALIGN'])) { $objattr['align'] = $align[strtolower($properties['TEXT-ALIGN'])]; }
16399
16400 if (isset($properties['MARGIN-LEFT']) && strtolower($properties['MARGIN-LEFT'])=='auto') {
16401 $objattr['align'] = 'R';
16402 }
16403 if (isset($properties['MARGIN-RIGHT']) && strtolower($properties['MARGIN-RIGHT'])=='auto') {
16404 $objattr['align'] = 'L';
16405 if (isset($properties['MARGIN-RIGHT']) && strtolower($properties['MARGIN-RIGHT'])=='auto' && isset($properties['MARGIN-LEFT']) && strtolower($properties['MARGIN-LEFT'])=='auto') {
16406 $objattr['align'] = 'C';
16407 }
16408 }
16409 if (isset($properties['COLOR'])) { $objattr['color'] = $this->ConvertColor($properties['COLOR']); }
16410 if (isset($properties['HEIGHT'])) { $objattr['linewidth'] = $this->ConvertSize($properties['HEIGHT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
16411
16412 if(isset($attr['WIDTH']) && $attr['WIDTH'] != '') $objattr['width'] = $this->ConvertSize($attr['WIDTH'],$this->blk[$this->blklvl]['inner_width']);
16413 if(isset($attr['ALIGN']) && $attr['ALIGN'] != '') $objattr['align'] = $align[strtolower($attr['ALIGN'])];
16414 if(isset($attr['COLOR']) && $attr['COLOR'] != '') $objattr['color'] = $this->ConvertColor($attr['COLOR']);
16415
16416 /*-- TABLES --*/
16417 if ($this->tableLevel) {
16418 $objattr['W-PERCENT'] = 100;
16419 if (isset($properties['WIDTH']) && stristr($properties['WIDTH'],'%')) {
16420 $properties['WIDTH'] += 0; //make "90%" become simply "90"
16421 $objattr['W-PERCENT'] = $properties['WIDTH'];
16422 }
16423 if (isset($attr['WIDTH']) && stristr($attr['WIDTH'],'%')) {
16424 $attr['WIDTH'] += 0; //make "90%" become simply "90"
16425 $objattr['W-PERCENT'] = $attr['WIDTH'];
16426 }
16427 }
16428 /*-- END TABLES --*/
16429
16430 $objattr['type'] = 'hr';
16431 $objattr['height'] = $objattr['linewidth'] + $objattr['margin_top'] + $objattr['margin_bottom'];
16432 $e = "\xbb\xa4\xactype=image,objattr=".serialize($objattr)."\xbb\xa4\xac";
16433
16434 // Clear properties - tidy up
16435 $properties = array();
16436
16437 /*-- TABLES --*/
16438 // Output it to buffers
16439 if ($this->tableLevel) {
16440 if (!isset($this->cell[$this->row][$this->col]['maxs'])) {
16441 $this->cell[$this->row][$this->col]['maxs'] = $this->cell[$this->row][$this->col]['s'];
16442 }
16443 elseif($this->cell[$this->row][$this->col]['maxs'] < $this->cell[$this->row][$this->col]['s']) {
16444 $this->cell[$this->row][$this->col]['maxs'] = $this->cell[$this->row][$this->col]['s'];
16445 }
16446 $this->cell[$this->row][$this->col]['s'] = 0 ;// reset
16447 $this->_saveCellTextBuffer($e, $this->HREF); // mPDF 5.3.99
16448 }
16449 else {
16450 /*-- END TABLES --*/
16451 $this->_saveTextBuffer($e, $this->HREF); // mPDF 5.3.99
16452 } // *TABLES*
16453
16454 break;
16455
16456
16457 /*-- BARCODES --*/
16458
16459 case 'BARCODE':
16460 if(isset($attr['CODE']) && $attr['CODE']) {
16461 $objattr = array();
16462 $objattr['margin_top'] = 0;
16463 $objattr['margin_bottom'] = 0;
16464 $objattr['margin_left'] = 0;
16465 $objattr['margin_right'] = 0;
16466 $objattr['padding_top'] = 0;
16467 $objattr['padding_bottom'] = 0;
16468 $objattr['padding_left'] = 0;
16469 $objattr['padding_right'] = 0;
16470 $objattr['width'] = 0;
16471 $objattr['height'] = 0;
16472 $objattr['border_top']['w'] = 0;
16473 $objattr['border_bottom']['w'] = 0;
16474 $objattr['border_left']['w'] = 0;
16475 $objattr['border_right']['w'] = 0;
16476 $objattr['code'] = $attr['CODE'];
16477
16478 if(isset($attr['TYPE'])) {
16479 $objattr['btype'] = trim(strtoupper($attr['TYPE']));
16480 }
16481 else { $objattr['btype'] = 'EAN13'; } // default
16482 if (preg_match('/^(EAN13|ISBN|ISSN|EAN8|UPCA|UPCE)P([25])$/',$objattr['btype'],$m)) {
16483 $objattr['btype'] = $m[1];
16484 $objattr['bsupp'] = $m[2];
16485 if (preg_match('/^(\S+)\s+(.*)$/',$objattr['code'],$mm)) {
16486 $objattr['code'] = $mm[1];
16487 $objattr['bsupp_code'] = $mm[2];
16488 }
16489 }
16490 else { $objattr['bsupp'] = 0; }
16491
16492 if(isset($attr['TEXT']) && $attr['TEXT']==1) { $objattr['showtext'] = 1; }
16493 else { $objattr['showtext'] = 0; }
16494 if(isset($attr['SIZE']) && $attr['SIZE']>0) { $objattr['bsize'] = $attr['SIZE']; }
16495 else { $objattr['bsize'] = 1; }
16496 if(isset($attr['HEIGHT']) && $attr['HEIGHT']>0) { $objattr['bheight'] = $attr['HEIGHT']; }
16497 else { $objattr['bheight'] = 1; }
16498 if(isset($attr['PR']) && $attr['PR']>0) { $objattr['pr_ratio'] = $attr['PR']; }
16499 else { $objattr['pr_ratio'] = ''; }
16500 $properties = $this->MergeCSS('',$tag,$attr);
16501 if(isset($properties ['DISPLAY']) && strtolower($properties ['DISPLAY'])=='none') {
16502 return;
16503 }
16504 if (isset($properties['MARGIN-TOP'])) { $objattr['margin_top']=$this->ConvertSize($properties['MARGIN-TOP'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
16505 if (isset($properties['MARGIN-BOTTOM'])) { $objattr['margin_bottom'] = $this->ConvertSize($properties['MARGIN-BOTTOM'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
16506 if (isset($properties['MARGIN-LEFT'])) { $objattr['margin_left'] = $this->ConvertSize($properties['MARGIN-LEFT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
16507 if (isset($properties['MARGIN-RIGHT'])) { $objattr['margin_right'] = $this->ConvertSize($properties['MARGIN-RIGHT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
16508
16509 if (isset($properties['PADDING-TOP'])) { $objattr['padding_top']=$this->ConvertSize($properties['PADDING-TOP'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
16510 if (isset($properties['PADDING-BOTTOM'])) { $objattr['padding_bottom'] = $this->ConvertSize($properties['PADDING-BOTTOM'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
16511 if (isset($properties['PADDING-LEFT'])) { $objattr['padding_left'] = $this->ConvertSize($properties['PADDING-LEFT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
16512 if (isset($properties['PADDING-RIGHT'])) { $objattr['padding_right'] = $this->ConvertSize($properties['PADDING-RIGHT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
16513
16514 if (isset($properties['BORDER-TOP'])) { $objattr['border_top'] = $this->border_details($properties['BORDER-TOP']); }
16515 if (isset($properties['BORDER-BOTTOM'])) { $objattr['border_bottom'] = $this->border_details($properties['BORDER-BOTTOM']); }
16516 if (isset($properties['BORDER-LEFT'])) { $objattr['border_left'] = $this->border_details($properties['BORDER-LEFT']); }
16517 if (isset($properties['BORDER-RIGHT'])) { $objattr['border_right'] = $this->border_details($properties['BORDER-RIGHT']); }
16518
16519 if (isset($properties['VERTICAL-ALIGN'])) { $objattr['vertical-align'] = $align[strtolower($properties['VERTICAL-ALIGN'])]; }
16520 if (isset($properties['COLOR']) && $properties['COLOR'] != '') { $objattr['color'] = $this->ConvertColor($properties['COLOR']); }
16521 else { $objattr['color'] = false; }
16522 if (isset($properties['BACKGROUND-COLOR']) && $properties['BACKGROUND-COLOR'] != '') { $objattr['bgcolor'] = $this->ConvertColor($properties['BACKGROUND-COLOR']); }
16523 else { $objattr['bgcolor'] = false; }
16524
16525 if (!class_exists('PDFBarcode', false)) {
16526 include(_MPDF_PATH.'classes/barcode.php');
16527 }
16528 $this->barcode = new PDFBarcode();
16529
16530 if ($objattr['btype'] == 'EAN13' || $objattr['btype'] == 'ISBN' || $objattr['btype'] == 'ISSN' || $objattr['btype'] == 'UPCA' || $objattr['btype'] == 'UPCE' || $objattr['btype'] == 'EAN8') {
16531 $code = preg_replace('/\-/','',$objattr['code']);
16532 if ($objattr['btype'] == 'ISSN' || $objattr['btype'] == 'ISBN') {
16533 $arrcode = $this->barcode->getBarcodeArray($code, 'EAN13');
16534 }
16535 else { $arrcode = $this->barcode->getBarcodeArray($code, $objattr['btype'] ); }
16536 if ($arrcode === false) { $this->Error('Error in barcode string.'); }
16537
16538 if ($objattr['bsupp'] == 2 || $objattr['bsupp'] == 5) { // EAN-2 or -5 Supplement
16539 $supparrcode = $this->barcode->getBarcodeArray($objattr['bsupp_code'], 'EAN'.$objattr['bsupp'] );
16540 $w = ($arrcode["maxw"] + $arrcode['lightmL'] + $arrcode['lightmR'] + $supparrcode["maxw"] + $supparrcode['sepM']) * $arrcode['nom-X'] * $objattr['bsize'];
16541 }
16542 else {
16543 $w = ($arrcode["maxw"] + $arrcode['lightmL'] + $arrcode['lightmR']) * $arrcode['nom-X'] * $objattr['bsize'];
16544 }
16545 $h = $arrcode['nom-H'] * $objattr['bsize'] * $objattr['bheight'];
16546 // Add height for ISBN string + margin from top of bars
16547 if (($objattr['showtext'] && $objattr['btype'] == 'EAN13') || $objattr['btype'] == 'ISBN' || $objattr['btype'] == 'ISSN') {
16548 $tisbnm = 1.5 * $objattr['bsize']; // Top margin between TOP TEXT (isbn - if shown) & bars
16549 $isbn_fontsize = 2.1 * $objattr['bsize'];
16550 $h += $isbn_fontsize + $tisbnm ;
16551 }
16552 }
16553 // QR-code
16554 else if ($objattr['btype'] == 'QR') {
16555 $w = $h = $objattr['bsize']*25; // Factor of 25mm (default)
16556 $objattr['errorlevel'] = 'L';
16557 if (isset($attr['ERROR'])) { $objattr['errorlevel'] = $attr['ERROR']; }
16558 }
16559 else if ($objattr['btype'] == 'IMB' || $objattr['btype'] == 'RM4SCC' || $objattr['btype'] == 'KIX' || $objattr['btype'] == 'POSTNET' || $objattr['btype'] == 'PLANET') {
16560 $arrcode = $this->barcode->getBarcodeArray($objattr['code'], $objattr['btype'] );
16561 if ($arrcode === false) { $this->Error('Error in barcode string.'); }
16562 $w = ($arrcode["maxw"] * $arrcode['nom-X'] * $objattr['bsize']) + $arrcode['quietL'] + $arrcode['quietR'];
16563 $h = ($arrcode['nom-H'] * $objattr['bsize']) + (2*$arrcode['quietTB']);
16564 }
16565 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'))) {
16566 $arrcode = $this->barcode->getBarcodeArray($objattr['code'], $objattr['btype'], $objattr['pr_ratio'] );
16567 if ($arrcode === false) { $this->Error('Error in barcode string.'); }
16568 $w = ($arrcode["maxw"] + $arrcode['lightmL'] + $arrcode['lightmR']) * $arrcode['nom-X'] * $objattr['bsize'];
16569 $h = ((2*$arrcode['lightTB'] * $arrcode['nom-X']) + $arrcode['nom-H']) * $objattr['bsize'] * $objattr['bheight'];
16570 }
16571 else { break; }
16572
16573 $extraheight = $objattr['padding_top'] + $objattr['padding_bottom'] + $objattr['margin_top'] + $objattr['margin_bottom'] + $objattr['border_top']['w'] + $objattr['border_bottom']['w'];
16574 $extrawidth = $objattr['padding_left'] + $objattr['padding_right'] + $objattr['margin_left'] + $objattr['margin_right'] + $objattr['border_left']['w'] + $objattr['border_right']['w'];
16575
16576 $objattr['type'] = 'barcode';
16577 $objattr['height'] = $h + $extraheight;
16578 $objattr['width'] = $w + $extrawidth;
16579 $objattr['barcode_height'] = $h;
16580 $objattr['barcode_width'] = $w;
16581 /*-- CSS-IMAGE-FLOAT --*/
16582 if (!$this->ColActive && !$this->tableLevel && !$this->listlvl && !$this->kwt && !$this->keep_block_together) {
16583 if (isset($properties['FLOAT']) && (strtoupper($properties['FLOAT']) == 'RIGHT' || strtoupper($properties['FLOAT']) == 'LEFT')) {
16584 $objattr['float'] = substr(strtoupper($properties['FLOAT']),0,1);
16585 }
16586 }
16587 /*-- END CSS-IMAGE-FLOAT --*/
16588
16589 $e = "\xbb\xa4\xactype=barcode,objattr=".serialize($objattr)."\xbb\xa4\xac";
16590
16591 // Clear properties - tidy up
16592 $properties = array();
16593
16594 /*-- TABLES --*/
16595 // Output it to buffers
16596 if ($this->tableLevel) {
16597 $this->_saveCellTextBuffer($e, $this->HREF); // mPDF 5.3.99
16598 $this->cell[$this->row][$this->col]['s'] += $objattr['width'] ;
16599 }
16600 else {
16601 /*-- END TABLES --*/
16602 $this->_saveTextBuffer($e, $this->HREF); // mPDF 5.3.99
16603
16604 } // *TABLES*
16605 }
16606 break;
16607 /*-- END BARCODES --*/
16608
16609
16610 // *********** FORM ELEMENTS ********************
16611
16612 /*-- FORMS --*/
16613 case 'SELECT':
16614 $this->lastoptionaltag = ''; // Save current HTML specified optional endtag
16615 $this->InlineProperties[$tag] = $this->saveInlineProperties();
16616 $properties = $this->MergeCSS('',$tag,$attr);
16617 if (isset($properties['FONT-FAMILY'])) {
16618 $this->SetFont($properties['FONT-FAMILY'],$this->FontStyle,0,false);
16619 }
16620 if (isset($properties['FONT-SIZE'])) {
16621 $mmsize = $this->ConvertSize($properties['FONT-SIZE'],$this->default_font_size/_MPDFK);
16622 $this->SetFontSize($mmsize*_MPDFK,false);
16623 }
16624 if (isset($attr['SPELLCHECK']) && strtolower($attr['SPELLCHECK'])=='true') {
16625 $this->selectoption['SPELLCHECK'] = true;
16626 }
16627
16628 if (isset($properties['COLOR'])) { $this->selectoption['COLOR'] = $this->ConvertColor($properties['COLOR']); }
16629 $this->specialcontent = "type=select";
16630 if(isset($attr['DISABLED'])) { $this->selectoption['DISABLED'] = $attr['DISABLED']; }
16631 if(isset($attr['READONLY'])) { $this->selectoption['READONLY'] = $attr['READONLY']; }
16632 if(isset($attr['REQUIRED'])) { $this->selectoption['REQUIRED'] = $attr['REQUIRED']; }
16633 if(isset($attr['EDITABLE'])) { $this->selectoption['EDITABLE'] = $attr['EDITABLE']; }
16634 if(isset($attr['TITLE'])) { $this->selectoption['TITLE'] = $attr['TITLE']; }
16635 if(isset($attr['MULTIPLE'])) { $this->selectoption['MULTIPLE'] = $attr['MULTIPLE']; }
16636 if(isset($attr['SIZE']) && $attr['SIZE']>1) { $this->selectoption['SIZE'] = $attr['SIZE']; }
16637 if ($this->useActiveForms) {
16638 if(isset($attr['NAME'])) { $this->selectoption['NAME'] = $attr['NAME']; }
16639 if (isset($attr['ONCHANGE'])) { $this->selectoption['ONCHANGE'] = $attr['ONCHANGE']; }
16640 }
16641
16642 $properties = array();
16643 break;
16644
16645 case 'OPTION':
16646 $this->lastoptionaltag = 'OPTION'; // Save current HTML specified optional endtag
16647 $this->selectoption['ACTIVE'] = true;
16648 $this->selectoption['currentSEL'] = false;
16649 if (empty($this->selectoption)) {
16650 $this->selectoption['MAXWIDTH'] = '';
16651 $this->selectoption['SELECTED'] = '';
16652 }
16653 if (isset($attr['SELECTED'])) {
16654 $this->selectoption['SELECTED'] = '';
16655 $this->selectoption['currentSEL'] = true;
16656 }
16657 // mPDF 5.3.46
16658 if(isset($attr['VALUE'])) {
16659 $attr['VALUE'] = strcode2utf($attr['VALUE']);
16660 $attr['VALUE'] = $this->lesser_entity_decode($attr['VALUE']); // mPDF 5.3.58
16661 if ($this->onlyCoreFonts)
16662 $attr['VALUE'] = mb_convert_encoding($attr['VALUE'], $this->mb_enc,'UTF-8');
16663 // mPDF 5.3.58
16664 }
16665 $this->selectoption['currentVAL'] = $attr['VALUE'];
16666 break;
16667
16668 case 'TEXTAREA':
16669 $objattr = array();
16670 $objattr['margin_top'] = 0;
16671 $objattr['margin_bottom'] = 0;
16672 $objattr['margin_left'] = 0;
16673 $objattr['margin_right'] = 0;
16674 $objattr['width'] = 0;
16675 $objattr['height'] = 0;
16676 $objattr['border_top']['w'] = 0;
16677 $objattr['border_bottom']['w'] = 0;
16678 $objattr['border_left']['w'] = 0;
16679 $objattr['border_right']['w'] = 0;
16680 if(isset($attr['DISABLED'])) { $objattr['disabled'] = true; }
16681 if(isset($attr['READONLY'])) { $objattr['readonly'] = true; }
16682 if(isset($attr['REQUIRED'])) { $objattr['required'] = true; }
16683 if(isset($attr['SPELLCHECK']) && strtolower($attr['SPELLCHECK'])=='true') { $objattr['spellcheck'] = true; }
16684 if(isset($attr['TITLE'])) { $objattr['title'] = $attr['TITLE']; }
16685 if ($this->onlyCoreFonts)
16686 $objattr['title'] = mb_convert_encoding($objattr['title'], $this->mb_enc,'UTF-8');
16687 if ($this->useActiveForms) {
16688 if(isset($attr['NAME'])) { $objattr['fieldname'] = $attr['NAME']; }
16689 $this->form->form_element_spacing['textarea']['outer']['v'] = 0;
16690 $this->form->form_element_spacing['textarea']['inner']['v'] = 0;
16691 // mPDF 5.3.25
16692 if (isset($attr['ONCALCULATE'])) { $objattr['onCalculate'] = $attr['ONCALCULATE']; }
16693 else if (isset($attr['ONCHANGE'])) { $objattr['onCalculate'] = $attr['ONCHANGE']; }
16694 if (isset($attr['ONVALIDATE'])) { $objattr['onValidate'] = $attr['ONVALIDATE']; }
16695 if (isset($attr['ONKEYSTROKE'])) { $objattr['onKeystroke'] = $attr['ONKEYSTROKE']; }
16696 if (isset($attr['ONFORMAT'])) { $objattr['onFormat'] = $attr['ONFORMAT']; } // mPDF 5.3.37
16697 }
16698 $this->InlineProperties[$tag] = $this->saveInlineProperties();
16699 $properties = $this->MergeCSS('',$tag,$attr);
16700 if (isset($properties['FONT-FAMILY'])) {
16701 $this->SetFont($properties['FONT-FAMILY'],'',0,false);
16702 }
16703 if (isset($properties['FONT-SIZE'])) {
16704 $mmsize = $this->ConvertSize($properties['FONT-SIZE'],$this->default_font_size/_MPDFK);
16705 $this->SetFontSize($mmsize*_MPDFK,false);
16706 }
16707 if (isset($properties['COLOR'])) { $objattr['color'] = $this->ConvertColor($properties['COLOR']); }
16708 $objattr['fontfamily'] = $this->FontFamily;
16709 $objattr['fontsize'] = $this->FontSizePt;
16710 if ($this->useActiveForms) {
16711 if(isset($attr['ALIGN'])) { $objattr['text_align'] = $align[strtolower($attr['ALIGN'])]; }
16712 else if(isset($properties['TEXT-ALIGN'])) { $objattr['text_align'] = $align[strtolower($properties['TEXT-ALIGN'])]; }
16713 if (isset($properties['OVERFLOW']) && strtolower($properties['OVERFLOW'])=='hidden') { $objattr['donotscroll'] = true; }
16714 if (isset($properties['BORDER-TOP-COLOR'])) { $objattr['border-col'] = $this->ConvertColor($properties['BORDER-TOP-COLOR']); }
16715 if (isset($properties['BACKGROUND-COLOR'])) { $objattr['background-col'] = $this->ConvertColor($properties['BACKGROUND-COLOR']); }
16716 }
16717 $this->SetLineHeight('',$this->form->textarea_lineheight);
16718 $formLineHeight = $this->lineheight;
16719
16720 $w = 0;
16721 $h = 0;
16722 if(isset($properties['WIDTH'])) $w = $this->ConvertSize($properties['WIDTH'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
16723 if(isset($properties['HEIGHT'])) $h = $this->ConvertSize($properties['HEIGHT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
16724 if ($properties['VERTICAL-ALIGN']) { $objattr['vertical-align'] = $align[strtolower($properties['VERTICAL-ALIGN'])]; }
16725
16726 $colsize = 20; //HTML default value
16727 $rowsize = 2; //HTML default value
16728 if (isset($attr['COLS'])) $colsize = intval($attr['COLS']);
16729 if (isset($attr['ROWS'])) $rowsize = intval($attr['ROWS']);
16730
16731 $charsize = $this->GetCharWidth('w',false); // mPDF 5.3.04
16732 if ($w) { $colsize = round(($w-($this->form->form_element_spacing['textarea']['outer']['h']*2)-($this->form->form_element_spacing['textarea']['inner']['h']*2))/$charsize); }
16733 if ($h) { $rowsize = round(($h-($this->form->form_element_spacing['textarea']['outer']['v']*2)-($this->form->form_element_spacing['textarea']['inner']['v']*2))/$formLineHeight); }
16734
16735 $objattr['type'] = 'textarea';
16736 $objattr['width'] = ($colsize * $charsize) + ($this->form->form_element_spacing['textarea']['outer']['h']*2)+($this->form->form_element_spacing['textarea']['inner']['h']*2);
16737 $objattr['height'] = ($rowsize * $formLineHeight) + ($this->form->form_element_spacing['textarea']['outer']['v']*2)+($this->form->form_element_spacing['textarea']['inner']['v']*2);
16738 $objattr['rows'] = $rowsize;
16739 $objattr['cols'] = $colsize;
16740
16741 $this->specialcontent = serialize($objattr);
16742
16743 if ($this->tableLevel) { // *TABLES*
16744 $this->cell[$this->row][$this->col]['s'] += $objattr['width'] ; // *TABLES*
16745 } // *TABLES*
16746
16747 // Clear properties - tidy up
16748 $properties = array();
16749 break;
16750
16751
16752
16753 // *********** FORM - INPUT ********************
16754
16755 case 'INPUT':
16756 if (!isset($attr['TYPE'])) $attr['TYPE'] == 'TEXT';
16757 $objattr = array();
16758 $objattr['margin_top'] = 0;
16759 $objattr['margin_bottom'] = 0;
16760 $objattr['margin_left'] = 0;
16761 $objattr['margin_right'] = 0;
16762 $objattr['width'] = 0;
16763 $objattr['height'] = 0;
16764 $objattr['border_top']['w'] = 0;
16765 $objattr['border_bottom']['w'] = 0;
16766 $objattr['border_left']['w'] = 0;
16767 $objattr['border_right']['w'] = 0;
16768 $objattr['type'] = 'input';
16769 if(isset($attr['DISABLED'])) { $objattr['disabled'] = true; }
16770 if(isset($attr['READONLY'])) { $objattr['readonly'] = true; }
16771 if(isset($attr['REQUIRED'])) { $objattr['required'] = true; }
16772 if(isset($attr['SPELLCHECK']) && strtolower($attr['SPELLCHECK'])=='true') { $objattr['spellcheck'] = true; }
16773 if(isset($attr['TITLE'])) { $objattr['title'] = $attr['TITLE']; }
16774 else if(isset($attr['ALT'])) { $objattr['title'] = $attr['ALT']; }
16775 // mPDF 5.3.46
16776 else $objattr['title'] = '';
16777 $objattr['title'] = strcode2utf($objattr['title']);
16778 $objattr['title'] = $this->lesser_entity_decode($objattr['title']); // mPDF 5.3.58
16779 if ($this->onlyCoreFonts)
16780 $objattr['title'] = mb_convert_encoding($objattr['title'], $this->mb_enc,'UTF-8');
16781 if ($this->useActiveForms) {
16782 if(isset($attr['NAME'])) { $objattr['fieldname'] = $attr['NAME']; }
16783 }
16784 // mPDF 5.3.46
16785 if(isset($attr['VALUE'])) {
16786 $attr['VALUE'] = strcode2utf($attr['VALUE']);
16787 $attr['VALUE'] = $this->lesser_entity_decode($attr['VALUE']); // mPDF 5.3.58
16788 if ($this->onlyCoreFonts)
16789 $attr['VALUE'] = mb_convert_encoding($attr['VALUE'], $this->mb_enc,'UTF-8');
16790 $objattr['value'] = $attr['VALUE'];
16791 }
16792
16793 $this->InlineProperties[$tag] = $this->saveInlineProperties();
16794 $properties = $this->MergeCSS('',$tag,$attr);
16795 $objattr['vertical-align'] = '';
16796
16797 if (isset($properties['FONT-FAMILY'])) {
16798 $this->SetFont($properties['FONT-FAMILY'],$this->FontStyle,0,false);
16799 }
16800 if (isset($properties['FONT-SIZE'])) {
16801 $mmsize = $this->ConvertSize($properties['FONT-SIZE'],($this->default_font_size/_MPDFK));
16802 $this->SetFontSize($mmsize*_MPDFK,false);
16803 }
16804 if (isset($properties['COLOR'])) { $objattr['color'] = $this->ConvertColor($properties['COLOR']); }
16805 $objattr['fontfamily'] = $this->FontFamily;
16806 $objattr['fontsize'] = $this->FontSizePt;
16807 if ($this->useActiveForms) {
16808 if(isset($attr['ALIGN'])) { $objattr['text_align'] = $align[strtolower($attr['ALIGN'])]; }
16809 else if(isset($properties['TEXT-ALIGN'])) { $objattr['text_align'] = $align[strtolower($properties['TEXT-ALIGN'])]; }
16810 if (isset($properties['BORDER-TOP-COLOR'])) { $objattr['border-col'] = $this->ConvertColor($properties['BORDER-TOP-COLOR']); }
16811 if (isset($properties['BACKGROUND-COLOR'])) { $objattr['background-col'] = $this->ConvertColor($properties['BACKGROUND-COLOR']); }
16812 }
16813
16814 $type = '';
16815 $texto='';
16816 $height = $this->FontSize;
16817 $width = 0;
16818 $spacesize = $this->GetCharWidth(' ',false); // mPDF 5.3.04
16819
16820 $w = 0;
16821 if(isset($properties['WIDTH'])) $w = $this->ConvertSize($properties['WIDTH'],$this->blk[$this->blklvl]['inner_width']);
16822
16823 if ($properties['VERTICAL-ALIGN']) { $objattr['vertical-align'] = $align[strtolower($properties['VERTICAL-ALIGN'])]; }
16824
16825 switch(strtoupper($attr['TYPE'])){
16826 case 'HIDDEN':
16827 $this->ignorefollowingspaces = true; //Eliminate exceeding left-side spaces
16828 if ($this->useActiveForms) {
16829 $this->form->SetFormText( 0, 0, $objattr['fieldname'], $objattr['value'], $objattr['value'], '', 0, '', true );
16830 }
16831 if ($this->InlineProperties[$tag]) { $this->restoreInlineProperties($this->InlineProperties[$tag]); }
16832 unset($this->InlineProperties[$tag]);
16833 break 2;
16834 case 'CHECKBOX': //Draw Checkbox
16835 $type = 'CHECKBOX';
16836 if (isset($attr['CHECKED'])) { $objattr['checked'] = true; }
16837 else { $objattr['checked'] = false; }
16838 $width = $this->FontSize;
16839 $height = $this->FontSize;
16840 break;
16841
16842 case 'RADIO': //Draw Radio button
16843 $type = 'RADIO';
16844 if (isset($attr['CHECKED'])) $objattr['checked'] = true;
16845 $width = $this->FontSize;
16846 $height = $this->FontSize;
16847 break;
16848
16849 /*-- IMAGES-CORE --*/
16850 case 'IMAGE': // Draw an Image button
16851 if(isset($attr['SRC'])) {
16852 $type = 'IMAGE';
16853 $srcpath = $attr['SRC'];
16854 $orig_srcpath = $attr['ORIG_SRC'];
16855 // VSPACE and HSPACE converted to margins in MergeCSS
16856 if (isset($properties['MARGIN-TOP'])) { $objattr['margin_top']=$this->ConvertSize($properties['MARGIN-TOP'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
16857 if (isset($properties['MARGIN-BOTTOM'])) { $objattr['margin_bottom'] = $this->ConvertSize($properties['MARGIN-BOTTOM'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
16858 if (isset($properties['MARGIN-LEFT'])) { $objattr['margin_left'] = $this->ConvertSize($properties['MARGIN-LEFT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
16859 if (isset($properties['MARGIN-RIGHT'])) { $objattr['margin_right'] = $this->ConvertSize($properties['MARGIN-RIGHT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
16860
16861
16862 if (isset($properties['BORDER-TOP'])) { $objattr['border_top'] = $this->border_details($properties['BORDER-TOP']); }
16863 if (isset($properties['BORDER-BOTTOM'])) { $objattr['border_bottom'] = $this->border_details($properties['BORDER-BOTTOM']); }
16864 if (isset($properties['BORDER-LEFT'])) { $objattr['border_left'] = $this->border_details($properties['BORDER-LEFT']); }
16865 if (isset($properties['BORDER-RIGHT'])) { $objattr['border_right'] = $this->border_details($properties['BORDER-RIGHT']); }
16866
16867 $objattr['padding_top'] = 0;
16868 $objattr['padding_bottom'] = 0;
16869 $objattr['padding_left'] = 0;
16870 $objattr['padding_right'] = 0;
16871
16872 if (isset($properties['VERTICAL-ALIGN'])) { $objattr['vertical-align'] = $align[strtolower($properties['VERTICAL-ALIGN'])]; }
16873
16874 $w = 0;
16875 $h = 0;
16876 if(isset($properties['WIDTH'])) $w = $this->ConvertSize($properties['WIDTH'],$this->blk[$this->blklvl]['inner_width']);
16877 if(isset($properties['HEIGHT'])) $h = $this->ConvertSize($properties['HEIGHT'],$this->blk[$this->blklvl]['inner_width']);
16878
16879 $extraheight = $objattr['margin_top'] + $objattr['margin_bottom'] + $objattr['border_top']['w'] + $objattr['border_bottom']['w'];
16880 $extrawidth = $objattr['margin_left'] + $objattr['margin_right'] + $objattr['border_left']['w'] + $objattr['border_right']['w'];
16881
16882 // Image file
16883 $info=$this->_getImage($srcpath, true, true, $orig_srcpath);
16884 if(!$info) {
16885 $info = $this->_getImage($this->noImageFile);
16886 if ($info) {
16887 $srcpath = $this->noImageFile;
16888 $w = ($info['w'] * (25.4/$this->dpi));
16889 $h = ($info['h'] * (25.4/$this->dpi));
16890 }
16891 }
16892 if(!$info) break;
16893 if ($info['cs']=='Indexed') { $objattr['Indexed'] = true; }
16894 $objattr['file'] = $srcpath;
16895 //Default width and height calculation if needed
16896 if($w==0 and $h==0) {
16897 /*-- IMAGES-WMF --*/
16898 if ($info['type']=='wmf') {
16899 // WMF units are twips (1/20pt)
16900 // divide by 20 to get points
16901 // divide by k to get user units
16902 $w = abs($info['w'])/(20*_MPDFK);
16903 $h = abs($info['h']) / (20*_MPDFK);
16904 }
16905 else
16906 /*-- END IMAGES-WMF --*/
16907 if ($info['type']=='svg') {
16908 // SVG units are pixels
16909 $w = abs($info['w'])/_MPDFK;
16910 $h = abs($info['h'])/_MPDFK;
16911 }
16912 else {
16913 //Put image at default image dpi
16914 $w=($info['w']/_MPDFK) * (72/$this->img_dpi);
16915 $h=($info['h']/_MPDFK) * (72/$this->img_dpi);
16916 }
16917 if (isset($properties['IMAGE-RESOLUTION'])) {
16918 if (preg_match('/from-image/i', $properties['IMAGE-RESOLUTION']) && isset($info['set-dpi']) && $info['set-dpi']>0) {
16919 $w *= $this->img_dpi / $info['set-dpi'];
16920 $h *= $this->img_dpi / $info['set-dpi'];
16921 }
16922 else if (preg_match('/(\d+)dpi/i', $properties['IMAGE-RESOLUTION'], $m)) {
16923 $dpi = $m[1];
16924 if ($dpi > 0) {
16925 $w *= $this->img_dpi / $dpi;
16926 $h *= $this->img_dpi / $dpi;
16927 }
16928 }
16929 }
16930 }
16931 // IF WIDTH OR HEIGHT SPECIFIED
16932 if($w==0) $w=$h*$info['w']/$info['h'];
16933 if($h==0) $h=$w*$info['h']/$info['w'];
16934 // Resize to maximum dimensions of page
16935 $maxWidth = $this->blk[$this->blklvl]['inner_width'];
16936 $maxHeight = $this->h - ($this->tMargin + $this->bMargin + 10) ;
16937 if ($this->fullImageHeight) { $maxHeight = $this->fullImageHeight; }
16938 if ($w + $extrawidth > $maxWidth ) {
16939 $w = $maxWidth - $extrawidth;
16940 $h=$w*$info['h']/$info['w'];
16941 }
16942 if ($h + $extraheight > $maxHeight ) {
16943 $h = $maxHeight - $extraheight;
16944 $w=$h*$info['w']/$info['h'];
16945 }
16946 $height = $h + $extraheight;
16947 $width = $w + $extrawidth;
16948 $objattr['type'] = 'image';
16949 $objattr['itype'] = $info['type'];
16950 $objattr['orig_h'] = $info['h'];
16951 $objattr['orig_w'] = $info['w'];
16952 /*-- IMAGES-WMF --*/
16953 if ($info['type']=='wmf') {
16954 $objattr['wmf_x'] = $info['x'];
16955 $objattr['wmf_y'] = $info['y'];
16956 }
16957 else
16958 /*-- END IMAGES-WMF --*/
16959 if ($info['type']=='svg') {
16960 $objattr['wmf_x'] = $info['x'];
16961 $objattr['wmf_y'] = $info['y'];
16962 }
16963 $objattr['height'] = $h + $extraheight;
16964 $objattr['width'] = $w + $extrawidth;
16965
16966 $objattr['image_height'] = $h;
16967 $objattr['image_width'] = $w;
16968 $objattr['ID'] = $info['i'];
16969 $texto = 'X';
16970 if ($this->useActiveForms) {
16971 if (isset($attr['ONCLICK'])) { $objattr['onClick'] = $attr['ONCLICK']; }
16972 $objattr['type'] = 'input';
16973 $type = 'IMAGE';
16974 }
16975 break;
16976 }
16977 /*-- END IMAGES-CORE --*/
16978
16979 case 'BUTTON': // Draw a button
16980 case 'SUBMIT':
16981 case 'RESET':
16982 $type = strtoupper($attr['TYPE']);
16983 if ($type=='IMAGE') { $type = 'BUTTON'; } // src path not found
16984 if(isset($attr['NOPRINT'])) { $objattr['noprint'] = true; }
16985 // mPDF 5.3.46
16986 if (!isset($attr['VALUE'])) {
16987 $objattr['value'] = ucfirst(strtolower($type));
16988 }
16989
16990 $texto = " " . $objattr['value'] . " ";
16991 $width = $this->GetStringWidth($texto) + ($this->form->form_element_spacing['button']['outer']['h']*2)+($this->form->form_element_spacing['button']['inner']['h']*2);
16992 $height = $this->FontSize + ($this->form->form_element_spacing['button']['outer']['v']*2)+($this->form->form_element_spacing['button']['inner']['v']*2);
16993 if ($this->useActiveForms) {
16994 if (isset($attr['ONCLICK'])) { $objattr['onClick'] = $attr['ONCLICK']; }
16995 }
16996 break;
16997
16998 case 'PASSWORD':
16999 case 'TEXT':
17000 default:
17001 if ($type == '') { $type = 'TEXT'; }
17002 if(strtoupper($attr['TYPE'])=='PASSWORD') { $type = 'PASSWORD'; }
17003 if (isset($attr['VALUE'])) {
17004 if ($type == 'PASSWORD') {
17005 $num_stars = mb_strlen($attr['VALUE'],$this->mb_enc );
17006 $texto = str_repeat('*',$num_stars);
17007 }
17008 else { $texto = $attr['VALUE']; }
17009 }
17010 $xw = ($this->form->form_element_spacing['input']['outer']['h']*2)+($this->form->form_element_spacing['input']['inner']['h']*2);
17011 $xh = ($this->form->form_element_spacing['input']['outer']['v']*2)+($this->form->form_element_spacing['input']['inner']['v']*2);
17012 if ($w) { $width = $w + $xw; }
17013 else { $width = (20 * $spacesize) + $xw; } // Default width in chars
17014 if (isset($attr['SIZE']) and ctype_digit($attr['SIZE']) ) $width = ($attr['SIZE'] * $spacesize) + $xw;
17015 $height = $this->FontSize + $xh;
17016 if (isset($attr['MAXLENGTH']) and ctype_digit($attr['MAXLENGTH']) ) $objattr['maxlength'] = $attr['MAXLENGTH'];
17017 if ($this->useActiveForms) {
17018 // mPDF 5.3.25
17019 if (isset($attr['ONCALCULATE'])) { $objattr['onCalculate'] = $attr['ONCALCULATE']; }
17020 else if (isset($attr['ONCHANGE'])) { $objattr['onCalculate'] = $attr['ONCHANGE']; }
17021 if (isset($attr['ONVALIDATE'])) { $objattr['onValidate'] = $attr['ONVALIDATE']; }
17022 if (isset($attr['ONKEYSTROKE'])) { $objattr['onKeystroke'] = $attr['ONKEYSTROKE']; }
17023 if (isset($attr['ONFORMAT'])) { $objattr['onFormat'] = $attr['ONFORMAT']; } // mPDF 5.3.37
17024 }
17025 break;
17026 }
17027
17028 $objattr['subtype'] = $type;
17029 $objattr['text'] = $texto;
17030 $objattr['width'] = $width;
17031 $objattr['height'] = $height;
17032 $e = "\xbb\xa4\xactype=input,objattr=".serialize($objattr)."\xbb\xa4\xac";
17033
17034 // Clear properties - tidy up
17035 $properties = array();
17036
17037 /*-- TABLES --*/
17038 // Output it to buffers
17039 if ($this->tableLevel) {
17040 $this->_saveCellTextBuffer($e, $this->HREF); // mPDF 5.3.99
17041 $this->cell[$this->row][$this->col]['s'] += $objattr['width'] ;
17042
17043 }
17044 else {
17045 /*-- END TABLES --*/
17046 $this->_saveTextBuffer($e, $this->HREF); // mPDF 5.3.99
17047 } // *TABLES*
17048
17049 if ($this->InlineProperties[$tag]) { $this->restoreInlineProperties($this->InlineProperties[$tag]); }
17050 unset($this->InlineProperties[$tag]);
17051
17052 break; // END of INPUT
17053 /*-- END FORMS --*/
17054
17055
17056 // *********** GRAPH ********************
17057 case 'JPGRAPH':
17058 if (!$this->useGraphs) { break; }
17059 if ($attr['TABLE']) { $gid = strtoupper($attr['TABLE']); }
17060 else { $gid = '0'; }
17061 if (!is_array($this->graphs[$gid]) || count($this->graphs[$gid])==0 ) { break; }
17062 include_once(_MPDF_PATH.'graph.php');
17063 $this->graphs[$gid]['attr'] = $attr;
17064
17065
17066 if (isset($this->graphs[$gid]['attr']['WIDTH']) && $this->graphs[$gid]['attr']['WIDTH']) {
17067 $this->graphs[$gid]['attr']['cWIDTH']=$this->ConvertSize($this->graphs[$gid]['attr']['WIDTH'],$pgwidth);
17068 } // mm
17069 if (isset($this->graphs[$gid]['attr']['HEIGHT']) && $this->graphs[$gid]['attr']['HEIGHT']) {
17070 $this->graphs[$gid]['attr']['cHEIGHT']=$this->ConvertSize($this->graphs[$gid]['attr']['HEIGHT'],$pgwidth);
17071 }
17072
17073 $graph_img = print_graph($this->graphs[$gid],$this->blk[$this->blklvl]['inner_width']);
17074 if ($graph_img) {
17075 if(isset($attr['ROTATE'])) {
17076 if ($attr['ROTATE']==90 || $attr['ROTATE']==-90) {
17077 $tmpw = $graph_img['w'];
17078 $graph_img['w']= $graph_img['h'];
17079 $graph_img['h']= $tmpw;
17080 }
17081 }
17082 $attr['SRC'] = $graph_img['file'];
17083 $attr['WIDTH'] = $graph_img['w'];
17084 $attr['HEIGHT'] = $graph_img['h'];
17085 }
17086 else { break; }
17087
17088 // *********** IMAGE ********************
17089 /*-- IMAGES-CORE --*/
17090 case 'IMG':
17091 if ($this->progressBar) { $this->UpdateProgressBar(1,'','IMG'); } // *PROGRESS-BAR*
17092 $objattr = array();
17093 $objattr['margin_top'] = 0;
17094 $objattr['margin_bottom'] = 0;
17095 $objattr['margin_left'] = 0;
17096 $objattr['margin_right'] = 0;
17097 $objattr['padding_top'] = 0;
17098 $objattr['padding_bottom'] = 0;
17099 $objattr['padding_left'] = 0;
17100 $objattr['padding_right'] = 0;
17101 $objattr['width'] = 0;
17102 $objattr['height'] = 0;
17103 $objattr['border_top']['w'] = 0;
17104 $objattr['border_bottom']['w'] = 0;
17105 $objattr['border_left']['w'] = 0;
17106 $objattr['border_right']['w'] = 0;
17107 if(isset($attr['SRC'])) {
17108 $srcpath = $attr['SRC'];
17109 $orig_srcpath = $attr['ORIG_SRC'];
17110 $properties = $this->MergeCSS('',$tag,$attr);
17111 if(isset($properties ['DISPLAY']) && strtolower($properties ['DISPLAY'])=='none') {
17112 return;
17113 }
17114 // mPDF 5.3.42 VISIBILITY
17115 $objattr['visibility'] = 'visible';
17116 if (isset($properties['VISIBILITY'])) {
17117 $v = strtolower($properties['VISIBILITY']);
17118 if (($v == 'hidden' || $v == 'printonly' || $v == 'screenonly') && $this->visibility=='visible') {
17119 $objattr['visibility'] = $v;
17120 }
17121 }
17122
17123 // VSPACE and HSPACE converted to margins in MergeCSS
17124 if (isset($properties['MARGIN-TOP'])) { $objattr['margin_top']=$this->ConvertSize($properties['MARGIN-TOP'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
17125 if (isset($properties['MARGIN-BOTTOM'])) { $objattr['margin_bottom'] = $this->ConvertSize($properties['MARGIN-BOTTOM'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
17126 if (isset($properties['MARGIN-LEFT'])) { $objattr['margin_left'] = $this->ConvertSize($properties['MARGIN-LEFT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
17127 if (isset($properties['MARGIN-RIGHT'])) { $objattr['margin_right'] = $this->ConvertSize($properties['MARGIN-RIGHT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
17128
17129 if (isset($properties['PADDING-TOP'])) { $objattr['padding_top']=$this->ConvertSize($properties['PADDING-TOP'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
17130 if (isset($properties['PADDING-BOTTOM'])) { $objattr['padding_bottom'] = $this->ConvertSize($properties['PADDING-BOTTOM'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
17131 if (isset($properties['PADDING-LEFT'])) { $objattr['padding_left'] = $this->ConvertSize($properties['PADDING-LEFT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
17132 if (isset($properties['PADDING-RIGHT'])) { $objattr['padding_right'] = $this->ConvertSize($properties['PADDING-RIGHT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
17133
17134 if (isset($properties['BORDER-TOP'])) { $objattr['border_top'] = $this->border_details($properties['BORDER-TOP']); }
17135 if (isset($properties['BORDER-BOTTOM'])) { $objattr['border_bottom'] = $this->border_details($properties['BORDER-BOTTOM']); }
17136 if (isset($properties['BORDER-LEFT'])) { $objattr['border_left'] = $this->border_details($properties['BORDER-LEFT']); }
17137 if (isset($properties['BORDER-RIGHT'])) { $objattr['border_right'] = $this->border_details($properties['BORDER-RIGHT']); }
17138
17139 if (isset($properties['VERTICAL-ALIGN'])) { $objattr['vertical-align'] = $align[strtolower($properties['VERTICAL-ALIGN'])]; }
17140 $w = 0;
17141 $h = 0;
17142 if(isset($properties['WIDTH'])) $w = $this->ConvertSize($properties['WIDTH'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
17143 if(isset($properties['HEIGHT'])) $h = $this->ConvertSize($properties['HEIGHT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
17144
17145 if(isset($attr['WIDTH'])) $w = $this->ConvertSize($attr['WIDTH'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
17146 if(isset($attr['HEIGHT'])) $h = $this->ConvertSize($attr['HEIGHT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
17147 if (isset($properties['OPACITY']) && $properties['OPACITY'] > 0 && $properties['OPACITY'] <= 1) { $objattr['opacity'] = $properties['OPACITY']; }
17148 if ($this->HREF) { // mPDF 5.3.78
17149 if (strpos($this->HREF,".") === false && strpos($this->HREF,"@") !== 0) {
17150 $href = $this->HREF;
17151 while(array_key_exists($href,$this->internallink)) $href="#".$href;
17152 $this->internallink[$href] = $this->AddLink();
17153 $objattr['link'] = $this->internallink[$href];
17154 }
17155 else { $objattr['link'] = $this->HREF; }
17156 }
17157 $extraheight = $objattr['padding_top'] + $objattr['padding_bottom'] + $objattr['margin_top'] + $objattr['margin_bottom'] + $objattr['border_top']['w'] + $objattr['border_bottom']['w'];
17158 $extrawidth = $objattr['padding_left'] + $objattr['padding_right'] + $objattr['margin_left'] + $objattr['margin_right'] + $objattr['border_left']['w'] + $objattr['border_right']['w'];
17159
17160 /*-- BACKGROUNDS --*/
17161 if(isset($properties['GRADIENT-MASK']) && preg_match('/(-moz-)*(repeating-)*(linear|radial)-gradient/',$properties['GRADIENT-MASK'])) {
17162 $objattr['GRADIENT-MASK'] = $properties['GRADIENT-MASK'];
17163 }
17164 /*-- END BACKGROUNDS --*/
17165
17166 // Image file
17167 $info=$this->_getImage($srcpath, true, true, $orig_srcpath);
17168 if(!$info) {
17169 $info = $this->_getImage($this->noImageFile);
17170 if ($info) {
17171 $srcpath = $this->noImageFile;
17172 $w = ($info['w'] * (25.4/$this->dpi));
17173 $h = ($info['h'] * (25.4/$this->dpi));
17174 }
17175 }
17176 if(!$info) break;
17177
17178 if(isset($attr['ROTATE'])) { $image_orientation = $attr['ROTATE']; }
17179 else if(isset($properties['IMAGE-ORIENTATION'])) { $image_orientation = $properties['IMAGE-ORIENTATION']; }
17180 else { $image_orientation = 0; }
17181 if($image_orientation) {
17182 if ($image_orientation==90 || $image_orientation==-90 || $image_orientation==270) {
17183 $tmpw = $info['w'];
17184 $info['w'] = $info['h'];
17185 $info['h'] = $tmpw;
17186 }
17187 $objattr['ROTATE'] = $image_orientation;
17188 }
17189
17190 $objattr['file'] = $srcpath;
17191 //Default width and height calculation if needed
17192 if($w==0 and $h==0) {
17193 /*-- IMAGES-WMF --*/
17194 if ($info['type']=='wmf') {
17195 // WMF units are twips (1/20pt)
17196 // divide by 20 to get points
17197 // divide by k to get user units
17198 $w = abs($info['w'])/(20*_MPDFK);
17199 $h = abs($info['h']) / (20*_MPDFK);
17200 }
17201 else
17202 /*-- END IMAGES-WMF --*/
17203 if ($info['type']=='svg') {
17204 // SVG units are pixels
17205 $w = abs($info['w'])/_MPDFK;
17206 $h = abs($info['h'])/_MPDFK;
17207 }
17208 else {
17209 //Put image at default image dpi
17210 $w=($info['w']/_MPDFK) * (72/$this->img_dpi);
17211 $h=($info['h']/_MPDFK) * (72/$this->img_dpi);
17212 }
17213 if (isset($properties['IMAGE-RESOLUTION'])) {
17214 if (preg_match('/from-image/i', $properties['IMAGE-RESOLUTION']) && isset($info['set-dpi']) && $info['set-dpi']>0) {
17215 $w *= $this->img_dpi / $info['set-dpi'];
17216 $h *= $this->img_dpi / $info['set-dpi'];
17217 }
17218 else if (preg_match('/(\d+)dpi/i', $properties['IMAGE-RESOLUTION'], $m)) {
17219 $dpi = $m[1];
17220 if ($dpi > 0) {
17221 $w *= $this->img_dpi / $dpi;
17222 $h *= $this->img_dpi / $dpi;
17223 }
17224 }
17225 }
17226 }
17227 // IF WIDTH OR HEIGHT SPECIFIED
17228 if($w==0) $w=abs($h*$info['w']/$info['h']);
17229 if($h==0) $h=abs($w*$info['h']/$info['w']);
17230
17231 // Resize to maximum dimensions of page
17232 $maxWidth = $this->blk[$this->blklvl]['inner_width'];
17233 $maxHeight = $this->h - ($this->tMargin + $this->bMargin + 1) ;
17234 if ($this->fullImageHeight) { $maxHeight = $this->fullImageHeight; }
17235 if ($w + $extrawidth > $maxWidth ) {
17236 $w = $maxWidth - $extrawidth;
17237 $h=abs($w*$info['h']/$info['w']);
17238 }
17239
17240 if ($h + $extraheight > $maxHeight ) {
17241 $h = $maxHeight - $extraheight;
17242 $w=abs($h*$info['w']/$info['h']);
17243 }
17244 $objattr['type'] = 'image';
17245 $objattr['itype'] = $info['type'];
17246
17247 $objattr['orig_h'] = $info['h'];
17248 $objattr['orig_w'] = $info['w'];
17249 /*-- IMAGES-WMF --*/
17250 if ($info['type']=='wmf') {
17251 $objattr['wmf_x'] = $info['x'];
17252 $objattr['wmf_y'] = $info['y'];
17253 }
17254 else
17255 /*-- END IMAGES-WMF --*/
17256 if ($info['type']=='svg') {
17257 $objattr['wmf_x'] = $info['x'];
17258 $objattr['wmf_y'] = $info['y'];
17259 }
17260 $objattr['height'] = $h + $extraheight;
17261 $objattr['width'] = $w + $extrawidth;
17262 $objattr['image_height'] = $h;
17263 $objattr['image_width'] = $w;
17264 /*-- CSS-IMAGE-FLOAT --*/
17265 if (!$this->ColActive && !$this->tableLevel && !$this->listlvl && !$this->kwt && !$this->keep_block_together) {
17266 if (isset($properties['FLOAT']) && (strtoupper($properties['FLOAT']) == 'RIGHT' || strtoupper($properties['FLOAT']) == 'LEFT')) {
17267 $objattr['float'] = substr(strtoupper($properties['FLOAT']),0,1);
17268 }
17269 }
17270 /*-- END CSS-IMAGE-FLOAT --*/
17271
17272 $e = "\xbb\xa4\xactype=image,objattr=".serialize($objattr)."\xbb\xa4\xac";
17273
17274 // Clear properties - tidy up
17275 $properties = array();
17276
17277 /*-- TABLES --*/
17278 // Output it to buffers
17279 if ($this->tableLevel) {
17280 $this->_saveCellTextBuffer($e, $this->HREF); // mPDF 5.3.99
17281 $this->cell[$this->row][$this->col]['s'] += $objattr['width'] ;
17282 }
17283 else {
17284 /*-- END TABLES --*/
17285 $this->_saveTextBuffer($e, $this->HREF); // mPDF 5.3.99
17286 } // *TABLES*
17287 /*-- ANNOTATIONS --*/
17288 if ($this->title2annots && isset($attr['TITLE'])) {
17289 $objattr = array();
17290 $objattr['margin_top'] = 0;
17291 $objattr['margin_bottom'] = 0;
17292 $objattr['margin_left'] = 0;
17293 $objattr['margin_right'] = 0;
17294 $objattr['width'] = 0;
17295 $objattr['height'] = 0;
17296 $objattr['border_top']['w'] = 0;
17297 $objattr['border_bottom']['w'] = 0;
17298 $objattr['border_left']['w'] = 0;
17299 $objattr['border_right']['w'] = 0;
17300 $objattr['CONTENT'] = $attr['TITLE'];
17301 $objattr['type'] = 'annot';
17302 $objattr['POS-X'] = 0;
17303 $objattr['POS-Y'] = 0;
17304 $objattr['ICON'] = 'Comment';
17305 $objattr['AUTHOR'] = '';
17306 $objattr['SUBJECT'] = '';
17307 $objattr['OPACITY'] = $this->annotOpacity;
17308 $objattr['COLOR'] = $this->ConvertColor('yellow');
17309 $e = "\xbb\xa4\xactype=annot,objattr=".serialize($objattr)."\xbb\xa4\xac";
17310 if($this->tableLevel) { // *TABLES*
17311 $this->cell[$this->row][$this->col]['textbuffer'][] = array($e); // *TABLES*
17312 } // *TABLES*
17313 else { // *TABLES*
17314 $this->textbuffer[] = array($e);
17315 } // *TABLES*
17316 }
17317 /*-- END ANNOTATIONS --*/
17318 }
17319 break;
17320 /*-- END IMAGES-CORE --*/
17321
17322
17323 // *********** CIRCULAR TEXT = TEXTCIRCLE ********************
17324 // mPDF 5.3.A5
17325 case 'TEXTCIRCLE':
17326 $objattr = array();
17327 $objattr['margin_top'] = 0;
17328 $objattr['margin_bottom'] = 0;
17329 $objattr['margin_left'] = 0;
17330 $objattr['margin_right'] = 0;
17331 $objattr['padding_top'] = 0;
17332 $objattr['padding_bottom'] = 0;
17333 $objattr['padding_left'] = 0;
17334 $objattr['padding_right'] = 0;
17335 $objattr['width'] = 0;
17336 $objattr['height'] = 0;
17337 $objattr['border_top']['w'] = 0;
17338 $objattr['border_bottom']['w'] = 0;
17339 $objattr['border_left']['w'] = 0;
17340 $objattr['border_right']['w'] = 0;
17341 $objattr['top-text'] = '';
17342 $objattr['bottom-text'] = '';
17343 $objattr['r'] = 20; // radius (default value here for safety)
17344 $objattr['space-width'] = 120;
17345 $objattr['char-width'] = 100;
17346
17347 $this->InlineProperties[$tag] = $this->saveInlineProperties();
17348 $properties = $this->MergeCSS('',$tag,$attr);
17349 if(isset($properties ['DISPLAY']) && strtolower($properties ['DISPLAY'])=='none') {
17350 return;
17351 }
17352 if (isset($attr['R'])) { $objattr['r']=$this->ConvertSize($attr['R'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
17353 if(isset($attr['TOP-TEXT'])) {
17354 $objattr['top-text'] = strcode2utf($attr['TOP-TEXT']);
17355 $objattr['top-text'] = $this->lesser_entity_decode($objattr['top-text']);
17356 if ($this->onlyCoreFonts)
17357 $objattr['top-text'] = mb_convert_encoding($objattr['top-text'], $this->mb_enc,'UTF-8');
17358 }
17359 if(isset($attr['BOTTOM-TEXT'])) {
17360 $objattr['bottom-text'] = strcode2utf($attr['BOTTOM-TEXT']);
17361 $objattr['bottom-text'] = $this->lesser_entity_decode($objattr['bottom-text']);
17362 if ($this->onlyCoreFonts)
17363 $objattr['bottom-text'] = mb_convert_encoding($objattr['bottom-text'], $this->mb_enc,'UTF-8');
17364 }
17365 if(isset($attr['SPACE-WIDTH']) && $attr['SPACE-WIDTH']) { $objattr['space-width'] = $attr['SPACE-WIDTH']; }
17366 if(isset($attr['CHAR-WIDTH']) && $attr['CHAR-WIDTH']) { $objattr['char-width'] = $attr['CHAR-WIDTH']; }
17367
17368 // VISIBILITY
17369 $objattr['visibility'] = 'visible';
17370 if (isset($properties['VISIBILITY'])) {
17371 $v = strtolower($properties['VISIBILITY']);
17372 if (($v == 'hidden' || $v == 'printonly' || $v == 'screenonly') && $this->visibility=='visible') {
17373 $objattr['visibility'] = $v;
17374 }
17375 }
17376 if (isset($properties['FONT-FAMILY'])) {
17377 $this->SetFont($properties['FONT-FAMILY'],$this->FontStyle,0,false);
17378 }
17379 if (isset($properties['FONT-SIZE'])) {
17380 $mmsize = $this->ConvertSize($properties['FONT-SIZE'],($this->default_font_size/_MPDFK));
17381 $this->SetFontSize($mmsize*_MPDFK,false);
17382 }
17383 if (isset($properties['COLOR'])) { $objattr['color'] = $this->ConvertColor($properties['COLOR']); }
17384 $objattr['fontfamily'] = $this->FontFamily;
17385 $objattr['fontsize'] = $this->FontSizePt;
17386 $objattr['fontstyle'] = '';
17387 if (isset($properties['FONT-WEIGHT'])) {
17388 if (strtoupper($properties['FONT-WEIGHT']) == 'BOLD') { $objattr['fontstyle'] .= 'B'; }
17389 }
17390 if (isset($properties['FONT-STYLE'])) {
17391 if (strtoupper($properties['FONT-STYLE']) == 'ITALIC') { $objattr['fontstyle'] .= 'I'; }
17392 }
17393
17394 // VSPACE and HSPACE converted to margins in MergeCSS
17395 if (isset($properties['MARGIN-TOP'])) { $objattr['margin_top']=$this->ConvertSize($properties['MARGIN-TOP'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
17396 if (isset($properties['MARGIN-BOTTOM'])) { $objattr['margin_bottom'] = $this->ConvertSize($properties['MARGIN-BOTTOM'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
17397 if (isset($properties['MARGIN-LEFT'])) { $objattr['margin_left'] = $this->ConvertSize($properties['MARGIN-LEFT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
17398 if (isset($properties['MARGIN-RIGHT'])) { $objattr['margin_right'] = $this->ConvertSize($properties['MARGIN-RIGHT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
17399
17400 if (isset($properties['PADDING-TOP'])) { $objattr['padding_top']=$this->ConvertSize($properties['PADDING-TOP'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
17401 if (isset($properties['PADDING-BOTTOM'])) { $objattr['padding_bottom'] = $this->ConvertSize($properties['PADDING-BOTTOM'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
17402 if (isset($properties['PADDING-LEFT'])) { $objattr['padding_left'] = $this->ConvertSize($properties['PADDING-LEFT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
17403 if (isset($properties['PADDING-RIGHT'])) { $objattr['padding_right'] = $this->ConvertSize($properties['PADDING-RIGHT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
17404
17405 if (isset($properties['BORDER-TOP'])) { $objattr['border_top'] = $this->border_details($properties['BORDER-TOP']); }
17406 if (isset($properties['BORDER-BOTTOM'])) { $objattr['border_bottom'] = $this->border_details($properties['BORDER-BOTTOM']); }
17407 if (isset($properties['BORDER-LEFT'])) { $objattr['border_left'] = $this->border_details($properties['BORDER-LEFT']); }
17408 if (isset($properties['BORDER-RIGHT'])) { $objattr['border_right'] = $this->border_details($properties['BORDER-RIGHT']); }
17409
17410 if (isset($properties['OPACITY']) && $properties['OPACITY'] > 0 && $properties['OPACITY'] <= 1) { $objattr['opacity'] = $properties['OPACITY']; }
17411 if (isset($properties['BACKGROUND-COLOR']) && $properties['BACKGROUND-COLOR'] != '') { $objattr['bgcolor'] = $this->ConvertColor($properties['BACKGROUND-COLOR']); }
17412 else { $objattr['bgcolor'] = false; }
17413 if ($this->HREF) { // mPDF 5.3.78
17414 if (strpos($this->HREF,".") === false && strpos($this->HREF,"@") !== 0) {
17415 $href = $this->HREF;
17416 while(array_key_exists($href,$this->internallink)) $href="#".$href;
17417 $this->internallink[$href] = $this->AddLink();
17418 $objattr['link'] = $this->internallink[$href];
17419 }
17420 else { $objattr['link'] = $this->HREF; }
17421 }
17422 $extraheight = $objattr['padding_top'] + $objattr['padding_bottom'] + $objattr['margin_top'] + $objattr['margin_bottom'] + $objattr['border_top']['w'] + $objattr['border_bottom']['w'];
17423 $extrawidth = $objattr['padding_left'] + $objattr['padding_right'] + $objattr['margin_left'] + $objattr['margin_right'] + $objattr['border_left']['w'] + $objattr['border_right']['w'];
17424
17425
17426 $w = $objattr['r']*2;
17427 $h = $w;
17428 $objattr['height'] = $h + $extraheight;
17429 $objattr['width'] = $w + $extrawidth;
17430 $objattr['type'] = 'textcircle';
17431
17432 $e = "\xbb\xa4\xactype=image,objattr=".serialize($objattr)."\xbb\xa4\xac";
17433
17434 // Clear properties - tidy up
17435 $properties = array();
17436
17437 /*-- TABLES --*/
17438 // Output it to buffers
17439 if ($this->tableLevel) {
17440 $this->_saveCellTextBuffer($e, $this->HREF);
17441 $this->cell[$this->row][$this->col]['s'] += $objattr['width'] ;
17442 }
17443 else {
17444 /*-- END TABLES --*/
17445 $this->_saveTextBuffer($e, $this->HREF);
17446 } // *TABLES*
17447
17448 if ($this->InlineProperties[$tag]) { $this->restoreInlineProperties($this->InlineProperties[$tag]); }
17449 unset($this->InlineProperties[$tag]);
17450
17451 break;
17452
17453
17454 /*-- TABLES --*/
17455
17456 case 'TABLE': // TABLE-BEGIN
17457 $this->tdbegin = false;
17458 $this->lastoptionaltag = '';
17459 // Disable vertical justification in columns
17460 if ($this->ColActive) { $this->colvAlign = ''; } // *COLUMNS*
17461 if ($this->lastblocklevelchange == 1) { $blockstate = 1; } // Top margins/padding only
17462 else if ($this->lastblocklevelchange < 1) { $blockstate = 0; } // NO margins/padding
17463 // called from block after new div e.g. <div> ... <table> ... Outputs block top margin/border and padding
17464 if (count($this->textbuffer) == 0 && $this->lastblocklevelchange == 1 && !$this->tableLevel && !$this->kwt) {
17465 $this->newFlowingBlock( $this->blk[$this->blklvl]['width'],$this->lineheight,'',false,false,1,true, $this->blk[$this->blklvl]['direction']);
17466 $this->finishFlowingBlock(true); // true = END of flowing block
17467 }
17468 else if (!$this->tableLevel && count($this->textbuffer)) { $this->printbuffer($this->textbuffer,$blockstate); }
17469
17470 $this->textbuffer=array();
17471 $this->lastblocklevelchange = -1;
17472 if ($this->tableLevel) { // i.e. now a nested table coming...
17473 // Save current level table
17474 $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['baseProperties']= $this->base_table_properties;
17475 $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['cells'] = $this->cell;
17476 $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['currrow'] = $this->row;
17477 $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['currcol'] = $this->col;
17478 }
17479 $this->tableLevel++;
17480 $this->tbCSSlvl++;
17481
17482 if ($this->tableLevel>1) { // inherit table properties from cell in which nested
17483 $this->base_table_properties['FONT-KERNING'] = $this->kerning ;
17484 $this->base_table_properties['LETTER-SPACING'] = $this->lSpacingCSS ;
17485 $this->base_table_properties['WORD-SPACING'] = $this->wSpacingCSS ;
17486 }
17487
17488 if (isset($this->tbctr[$this->tableLevel])) { $this->tbctr[$this->tableLevel]++; }
17489 else { $this->tbctr[$this->tableLevel] = 1; }
17490
17491 $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['level'] = $this->tableLevel;
17492 $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['levelid'] = $this->tbctr[$this->tableLevel];
17493
17494 if ($this->tableLevel > $this->innermostTableLevel) { $this->innermostTableLevel = $this->tableLevel; }
17495 if ($this->tableLevel > 1) {
17496 $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['nestedpos'] = array($this->row,$this->col,$this->tbctr[($this->tableLevel-1)]);
17497 }
17498 //++++++++++++++++++++++++++++
17499
17500 $this->cell = array();
17501 $this->col=-1; //int
17502 $this->row=-1; //int
17503 $table = &$this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]];
17504
17505 // mPDF 5.3.79
17506 // New table - any level
17507 if ($this->cacheTables) {
17508 $this->packTableData = true; // required for cacheTables
17509 $this->simpleTables = false; // Cannot co-exist with cacheTables
17510 $table['cache'] = _MPDF_TEMP_PATH.'_tempTblCache'.RAND(1,1000000).'.dat';
17511 $fh = fopen($table['cache'] , "wb") or $this->Error("When using cacheTables, you must have read/write access to cache files (".$table['cache'] .")");
17512 fwrite($fh, "\x00");
17513 fclose($fh);
17514 $table['ptr'] = 1 ; // Must not be 0
17515 }
17516
17517 $table['direction'] = $this->directionality;
17518 $table['bgcolor'] = false;
17519 $table['va'] = false;
17520 $table['txta'] = false;
17521 $table['topntail'] = false;
17522 $table['thead-underline'] = false;
17523 $table['border'] = false;
17524 $table['border_details']['R']['w'] = 0;
17525 $table['border_details']['L']['w'] = 0;
17526 $table['border_details']['T']['w'] = 0;
17527 $table['border_details']['B']['w'] = 0;
17528 $table['border_details']['R']['style'] = '';
17529 $table['border_details']['L']['style'] = '';
17530 $table['border_details']['T']['style'] = '';
17531 $table['border_details']['B']['style'] = '';
17532 $table['max_cell_border_width']['R'] = 0;
17533 $table['max_cell_border_width']['L'] = 0;
17534 $table['max_cell_border_width']['T'] = 0;
17535 $table['max_cell_border_width']['B'] = 0;
17536 $table['padding']['L'] = false;
17537 $table['padding']['R'] = false;
17538 $table['padding']['T'] = false;
17539 $table['padding']['B'] = false;
17540 $table['margin']['L'] = false;
17541 $table['margin']['R'] = false;
17542 $table['margin']['T'] = false;
17543 $table['margin']['B'] = false;
17544 $table['a'] = false;
17545 $table['border_spacing_H'] = false;
17546 $table['border_spacing_V'] = false;
17547
17548 $this->Reset();
17549 $this->InlineProperties = array();
17550 $this->spanlvl = 0;
17551 $table['nc'] = $table['nr'] = 0;
17552 $this->tablethead = 0;
17553 $this->tabletfoot = 0;
17554 $this->tabletheadjustfinished = false;
17555
17556
17557 if ($this->blockjustfinished && !count($this->textbuffer) && $this->y != $this->tMargin && $this->collapseBlockMargins && $this->tableLevel==1) { $lastbottommargin = $this->lastblockbottommargin; }
17558 else { $lastbottommargin = 0; }
17559 $this->lastblockbottommargin = 0;
17560 $this->blockjustfinished=false;
17561
17562 if ($this->tableLevel==1) {
17563 $this->tableCJK = false;
17564 $this->table_lineheight = $this->normalLineheight;
17565 $table['headernrows'] = 0; // mPDF 5.3.62
17566 $table['footernrows'] = 0; // mPDF 5.3.62
17567 $this->base_table_properties = array();
17568 }
17569
17570 // ADDED CSS FUNCIONS FOR TABLE
17571 if ($this->tbCSSlvl==1) {
17572 $properties = $this->MergeCSS('TOPTABLE',$tag,$attr);
17573 }
17574 else {
17575 $properties = $this->MergeCSS('TABLE',$tag,$attr);
17576 }
17577 $w = '';
17578 if (isset($properties['WIDTH'])) { $w = $properties['WIDTH']; }
17579
17580 if(isset($properties['DIRECTION']) && $properties['DIRECTION']) { $table['direction'] = strtolower($properties['DIRECTION']); }
17581 if(isset($attr['DIR']) && $attr['DIR']) { $table['direction'] = strtolower($attr['DIR']); }
17582 else if (!isset($table['direction'])){ $table['direction'] = $this->blk[$this->blklvl]['direction']; }
17583
17584 if (isset($properties['BACKGROUND-COLOR'])) { $table['bgcolor'][-1] = $properties['BACKGROUND-COLOR']; }
17585 else if (isset($properties['BACKGROUND'])) { $table['bgcolor'][-1] = $properties['BACKGROUND']; }
17586 if (isset($properties['VERTICAL-ALIGN'])) { $table['va'] = $align[strtolower($properties['VERTICAL-ALIGN'])]; }
17587 if (isset($properties['TEXT-ALIGN'])) { $table['txta'] = $align[strtolower($properties['TEXT-ALIGN'])]; }
17588 if (isset($properties['AUTOSIZE']) && $properties['AUTOSIZE'] && $this->tableLevel ==1) {
17589 $this->shrink_this_table_to_fit = $properties['AUTOSIZE'];
17590 if ($this->shrink_this_table_to_fit < 1) { $this->shrink_this_table_to_fit = 0; }
17591 }
17592 if (isset($properties['ROTATE']) && $properties['ROTATE'] && $this->tableLevel ==1) {
17593 $this->table_rotate = $properties['ROTATE'];
17594 }
17595 if (isset($properties['TOPNTAIL'])) { $table['topntail'] = $properties['TOPNTAIL']; }
17596 if (isset($properties['THEAD-UNDERLINE'])) { $table['thead-underline'] = $properties['THEAD-UNDERLINE']; }
17597
17598 if (isset($properties['BORDER'])) {
17599 $bord = $this->border_details($properties['BORDER']);
17600 if ($bord['s']) {
17601 $table['border'] = _BORDER_ALL;
17602 $table['border_details']['R'] = $bord;
17603 $table['border_details']['L'] = $bord;
17604 $table['border_details']['T'] = $bord;
17605 $table['border_details']['B'] = $bord;
17606 }
17607 }
17608 if (isset($properties['BORDER-RIGHT'])) {
17609 if ($table['direction'] == 'rtl') { // *RTL*
17610 $table['border_details']['R'] = $this->border_details($properties['BORDER-LEFT']); // *RTL*
17611 } // *RTL*
17612 else { // *RTL*
17613 $table['border_details']['R'] = $this->border_details($properties['BORDER-RIGHT']);
17614 } // *RTL*
17615 $this->setBorder($table['border'], _BORDER_RIGHT, $table['border_details']['R']['s']);
17616 }
17617 if (isset($properties['BORDER-LEFT'])) {
17618 if ($table['direction'] == 'rtl') { // *RTL*
17619 $table['border_details']['L'] = $this->border_details($properties['BORDER-RIGHT']); // *RTL*
17620 } // *RTL*
17621 else { // *RTL*
17622 $table['border_details']['L'] = $this->border_details($properties['BORDER-LEFT']);
17623 } // *RTL*
17624 $this->setBorder($table['border'], _BORDER_LEFT, $table['border_details']['L']['s']);
17625 }
17626 if (isset($properties['BORDER-BOTTOM'])) {
17627 $table['border_details']['B'] = $this->border_details($properties['BORDER-BOTTOM']);
17628 $this->setBorder($table['border'], _BORDER_BOTTOM, $table['border_details']['B']['s']);
17629 }
17630 if (isset($properties['BORDER-TOP'])) {
17631 $table['border_details']['T'] = $this->border_details($properties['BORDER-TOP']);
17632 $this->setBorder($table['border'], _BORDER_TOP, $table['border_details']['T']['s']);
17633 }
17634 if ($table['border']){
17635 $this->table_border_css_set = 1;
17636 }
17637 else {
17638 $this->table_border_css_set = 0;
17639 }
17640
17641 if (isset($properties['FONT-FAMILY'])) {
17642 $this->default_font = $properties['FONT-FAMILY'];
17643 $this->SetFont($this->default_font,'',0,false);
17644 $this->base_table_properties['FONT-FAMILY'] = $properties['FONT-FAMILY'];
17645 }
17646 if (isset($properties['FONT-SIZE'])) {
17647 $mmsize = $this->ConvertSize($properties['FONT-SIZE'],$this->default_font_size/_MPDFK);
17648 if ($mmsize) {
17649 $this->default_font_size = $mmsize*(_MPDFK);
17650 $this->SetFontSize($this->default_font_size,false);
17651 $this->base_table_properties['FONT-SIZE'] = $properties['FONT-SIZE'];
17652 }
17653 }
17654
17655 if (isset($properties['FONT-WEIGHT'])) {
17656 if (strtoupper($properties['FONT-WEIGHT']) == 'BOLD') { $this->base_table_properties['FONT-WEIGHT'] = 'BOLD'; }
17657 }
17658 if (isset($properties['FONT-STYLE'])) {
17659 if (strtoupper($properties['FONT-STYLE']) == 'ITALIC') { $this->base_table_properties['FONT-STYLE'] = 'ITALIC'; }
17660 }
17661 if (isset($properties['COLOR'])) {
17662 $this->base_table_properties['COLOR'] = $properties['COLOR'];
17663 }
17664 if (isset($properties['FONT-KERNING'])) {
17665 $this->base_table_properties['FONT-KERNING'] = $properties['FONT-KERNING'];
17666 }
17667 if (isset($properties['LETTER-SPACING'])) {
17668 $this->base_table_properties['LETTER-SPACING'] = $properties['LETTER-SPACING'];
17669 }
17670 if (isset($properties['WORD-SPACING'])) {
17671 $this->base_table_properties['WORD-SPACING'] = $properties['WORD-SPACING'];
17672 }
17673
17674 if (isset($properties['PADDING-LEFT'])) {
17675 $table['padding']['L'] = $this->ConvertSize($properties['PADDING-LEFT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
17676 }
17677 if (isset($properties['PADDING-RIGHT'])) {
17678 $table['padding']['R'] = $this->ConvertSize($properties['PADDING-RIGHT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
17679 }
17680 if (isset($properties['PADDING-TOP'])) {
17681 $table['padding']['T'] = $this->ConvertSize($properties['PADDING-TOP'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
17682 }
17683 if (isset($properties['PADDING-BOTTOM'])) {
17684 $table['padding']['B'] = $this->ConvertSize($properties['PADDING-BOTTOM'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
17685 }
17686
17687 if (isset($properties['MARGIN-TOP'])) {
17688 if ($lastbottommargin) {
17689 $tmp = $this->ConvertSize($properties['MARGIN-TOP'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
17690 if ($tmp > $lastbottommargin) { $properties['MARGIN-TOP'] -= $lastbottommargin; }
17691 else { $properties['MARGIN-TOP'] = 0; }
17692 }
17693 $table['margin']['T'] = $this->ConvertSize($properties['MARGIN-TOP'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
17694 }
17695
17696 if (isset($properties['MARGIN-BOTTOM'])) {
17697 $table['margin']['B'] = $this->ConvertSize($properties['MARGIN-BOTTOM'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
17698 }
17699 if (isset($properties['MARGIN-LEFT'])) {
17700 $table['margin']['L'] = $this->ConvertSize($properties['MARGIN-LEFT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
17701 }
17702
17703 if (isset($properties['MARGIN-RIGHT'])) {
17704 $table['margin']['R'] = $this->ConvertSize($properties['MARGIN-RIGHT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
17705 }
17706 if (isset($properties['MARGIN-LEFT']) && isset($properties['MARGIN-RIGHT']) && strtolower($properties['MARGIN-LEFT'])=='auto' && strtolower($properties['MARGIN-RIGHT'])=='auto') {
17707 $table['a'] = 'C';
17708 }
17709 else if (isset($properties['MARGIN-LEFT']) && strtolower($properties['MARGIN-LEFT'])=='auto') {
17710 $table['a'] = 'R';
17711 }
17712 else if (isset($properties['MARGIN-RIGHT']) && strtolower($properties['MARGIN-RIGHT'])=='auto') {
17713 $table['a'] = 'L';
17714 }
17715
17716 if (isset($properties['LINE-HEIGHT']) && $this->tableLevel==1) {
17717 $this->table_lineheight = $this->fixLineheight($properties['LINE-HEIGHT']);
17718 if (!$this->table_lineheight) { $this->table_lineheight = $this->normalLineheight; }
17719 }
17720
17721 if (isset($properties['BORDER-COLLAPSE']) && strtoupper($properties['BORDER-COLLAPSE'])=='SEPARATE') {
17722 $table['borders_separate'] = true;
17723 }
17724 else {
17725 $table['borders_separate'] = false;
17726 }
17727
17728 if (isset($properties['BORDER-SPACING-H'])) {
17729 $table['border_spacing_H'] = $this->ConvertSize($properties['BORDER-SPACING-H'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
17730 }
17731 if (isset($properties['BORDER-SPACING-V'])) {
17732 $table['border_spacing_V'] = $this->ConvertSize($properties['BORDER-SPACING-V'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
17733 }
17734
17735 if (isset($properties['EMPTY-CELLS'])) {
17736 $table['empty_cells'] = strtolower($properties['EMPTY-CELLS']); // 'hide' or 'show'
17737 }
17738 else { $table['empty_cells'] = ''; }
17739
17740 if (isset($properties['PAGE-BREAK-INSIDE']) && strtoupper($properties['PAGE-BREAK-INSIDE'])=='AVOID' && $this->tableLevel==1 && !$this->writingHTMLfooter) {
17741 $this->table_keep_together = true;
17742 }
17743 else if ($this->tableLevel==1) {
17744 $this->table_keep_together = false;
17745 }
17746 // mPDF 5.3.55
17747 if (isset($properties['PAGE-BREAK-AFTER']) && $this->tableLevel==1) {
17748 $table['page_break_after'] = strtoupper($properties['PAGE-BREAK-AFTER']);
17749 }
17750
17751 /*-- BACKGROUNDS --*/
17752 if (isset($properties['BACKGROUND-GRADIENT']) && !$this->kwt && !$this->ColActive) { $table['gradient'] = $properties['BACKGROUND-GRADIENT']; }
17753
17754 if (isset($properties['BACKGROUND-IMAGE']) && $properties['BACKGROUND-IMAGE'] && !$this->kwt && !$this->ColActive) {
17755 $ret = $this->SetBackground($properties, $currblk['inner_width']);
17756 if ($ret) { $table['background-image'] = $ret; }
17757 }
17758 /*-- END BACKGROUNDS --*/
17759
17760 if (isset($properties['OVERFLOW'])) {
17761 $table['overflow'] = strtolower($properties['OVERFLOW']); // 'hidden' 'wrap' or 'visible' or 'auto'
17762 if (($this->ColActive || $this->tableLevel>1) && $table['overflow']=='visible') { unset($table['overflow']); } // mPDF 5.3.36
17763 }
17764
17765 $properties = array();
17766
17767 if (!$table['borders_separate']) { $table['border_spacing_H'] = $table['border_spacing_V'] = 0; }
17768 else if (isset($attr['CELLSPACING'])) {
17769 $table['border_spacing_H'] = $table['border_spacing_V'] = $this->ConvertSize($attr['CELLSPACING'],$this->blk[$this->blklvl]['inner_width']);
17770 }
17771
17772
17773 if (isset($attr['CELLPADDING'])) {
17774 $table['cell_padding'] = $attr['CELLPADDING'];
17775 }
17776 else {
17777 $table['cell_padding'] = false;
17778 }
17779
17780 if (isset($attr['BORDER'])) {
17781 $this->table_border_attr_set = 1;
17782 if ($attr['BORDER']=='1') {
17783 $bord = $this->border_details('#000000 1px solid');
17784 if ($bord['s']) {
17785 $table['border'] = _BORDER_ALL;
17786 $table['border_details']['R'] = $bord;
17787 $table['border_details']['L'] = $bord;
17788 $table['border_details']['T'] = $bord;
17789 $table['border_details']['B'] = $bord;
17790 }
17791 }
17792 }
17793 else {
17794 $this->table_border_attr_set = 0;
17795 }
17796 if (isset($attr['ALIGN'])) { $table['a'] = $align[strtolower($attr['ALIGN'])]; }
17797 if (!$table['a']) {
17798 if ($table['direction'] == 'rtl' ) { $table['a'] = 'R'; }
17799 else { $table['a'] = 'L'; }
17800 }
17801 if (isset($attr['BGCOLOR'])) { $table['bgcolor'][-1] = $attr['BGCOLOR']; }
17802
17803 if (isset($attr['WIDTH']) && $attr['WIDTH']) { $w = $attr['WIDTH']; }
17804 if ($w) { // set here or earlier in $properties
17805 $maxwidth = $this->blk[$this->blklvl]['inner_width'];
17806 if ($table['borders_separate']) {
17807 $tblblw = $table['margin']['L'] + $table['margin']['R'] + $table['border_details']['L']['w']/2 + $table['border_details']['R']['w']/2;
17808 }
17809 else {
17810 $tblblw = $table['margin']['L'] + $table['margin']['R'] + $table['max_cell_border_width']['L']/2 + $table['max_cell_border_width']['R']/2;
17811 }
17812 if (strpos($w,'%') && $this->tableLevel == 1 && !$this->ignore_table_percents ) {
17813 // % needs to be of inner box without table margins etc.
17814 $maxwidth -= $tblblw ;
17815 $wmm = $this->ConvertSize($w,$maxwidth,$this->FontSize,false);
17816 $table['w'] = $wmm + $tblblw ;
17817 }
17818 if (strpos($w,'%') && $this->tableLevel > 1 && !$this->ignore_table_percents && $this->keep_table_proportions) {
17819 $table['wpercent'] = $w + 0; // makes 80% -> 80
17820 }
17821 if (!strpos($w,'%') && !$this->ignore_table_widths ) {
17822 $wmm = $this->ConvertSize($w,$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
17823 $table['w'] = $wmm + $tblblw ;
17824 }
17825 if (!$this->keep_table_proportions) {
17826 if (isset($table['w']) && $table['w'] > $this->blk[$this->blklvl]['inner_width']) { $table['w'] = $this->blk[$this->blklvl]['inner_width']; }
17827 }
17828 }
17829
17830 if (isset($attr['AUTOSIZE']) && $this->tableLevel==1) {
17831 $this->shrink_this_table_to_fit = $attr['AUTOSIZE'];
17832 if ($this->shrink_this_table_to_fit < 1) { $this->shrink_this_table_to_fit = 1; }
17833 }
17834 if (isset($attr['ROTATE']) && $this->tableLevel==1) {
17835 $this->table_rotate = $attr['ROTATE'];
17836 }
17837
17838 //++++++++++++++++++++++++++++
17839 // keeping block together on one page
17840 // Autosize is now forced therefore keep block together disabled
17841 if ($this->keep_block_together) {
17842 $this->keep_block_together = 0;
17843 $this->printdivbuffer();
17844 $this->blk[$this->blklvl]['keep_block_together'] = 0;
17845 }
17846 if ($this->table_rotate) {
17847 $this->tbrot_Links = array();
17848 $this->tbrot_Annots = array();
17849 $this->tbrotForms = array();
17850 $this->tbrot_Reference = array();
17851 $this->tbrot_BMoutlines = array();
17852 $this->tbrot_toc = array();
17853 }
17854
17855 if ($this->kwt) {
17856 if ($this->table_rotate) { $this->table_keep_together = true; }
17857 $this->kwt = false;
17858 $this->kwt_saved = true;
17859 }
17860
17861 if ($this->tableLevel==1 && $this->useGraphs) {
17862 if (isset($attr['ID']) && $attr['ID']) { $this->currentGraphId = strtoupper($attr['ID']); }
17863 else { $this->currentGraphId = '0'; }
17864 $this->graphs[$this->currentGraphId] = array();
17865 }
17866 //++++++++++++++++++++++++++++
17867 $this->plainCell_properties = array();
17868 unset($table); // mPDF 5.3.76
17869 break;
17870
17871 case 'THEAD':
17872 $this->lastoptionaltag = $tag; // Save current HTML specified optional endtag
17873 $this->tbCSSlvl++;
17874 $this->tablethead = 1;
17875 $this->tabletfoot = 0;
17876 $properties = $this->MergeCSS('TABLE',$tag,$attr);
17877 if (isset($properties['FONT-WEIGHT'])) {
17878 if (strtoupper($properties['FONT-WEIGHT']) == 'BOLD') { $this->thead_font_weight = 'B'; }
17879 else { $this->thead_font_weight = ''; }
17880 }
17881
17882 if (isset($properties['FONT-STYLE'])) {
17883 if (strtoupper($properties['FONT-STYLE']) == 'ITALIC') { $this->thead_font_style = 'I'; }
17884 else { $this->thead_font_style = ''; }
17885 }
17886 if (isset($properties['FONT-VARIANT'])) {
17887 if (strtoupper($properties['FONT-VARIANT']) == 'SMALL-CAPS') { $this->thead_font_smCaps = 'S'; }
17888 else { $this->thead_font_smCaps = ''; }
17889 }
17890
17891 if (isset($properties['VERTICAL-ALIGN'])) {
17892 $this->thead_valign_default = $properties['VERTICAL-ALIGN'];
17893 }
17894 if (isset($properties['TEXT-ALIGN'])) {
17895 $this->thead_textalign_default = $properties['TEXT-ALIGN'];
17896 }
17897 $properties = array();
17898 break;
17899
17900 case 'TFOOT':
17901 $this->lastoptionaltag = $tag; // Save current HTML specified optional endtag
17902 $this->tbCSSlvl++;
17903 $this->tabletfoot = 1;
17904 $this->tablethead = 0;
17905 $properties = $this->MergeCSS('TABLE',$tag,$attr);
17906 if (isset($properties['FONT-WEIGHT'])) {
17907 if (strtoupper($properties['FONT-WEIGHT']) == 'BOLD') { $this->tfoot_font_weight = 'B'; }
17908 else { $this->tfoot_font_weight = ''; }
17909 }
17910
17911 if (isset($properties['FONT-STYLE'])) {
17912 if (strtoupper($properties['FONT-STYLE']) == 'ITALIC') { $this->tfoot_font_style = 'I'; }
17913 else { $this->tfoot_font_style = ''; }
17914 }
17915 if (isset($properties['FONT-VARIANT'])) {
17916 if (strtoupper($properties['FONT-VARIANT']) == 'SMALL-CAPS') { $this->tfoot_font_smCaps = 'S'; }
17917 else { $this->tfoot_font_smCaps = ''; }
17918 }
17919
17920 if (isset($properties['VERTICAL-ALIGN'])) {
17921 $this->tfoot_valign_default = $properties['VERTICAL-ALIGN'];
17922 }
17923 if (isset($properties['TEXT-ALIGN'])) {
17924 $this->tfoot_textalign_default = $properties['TEXT-ALIGN'];
17925 }
17926 $properties = array();
17927 break;
17928
17929
17930 case 'TBODY':
17931 $this->tablethead = 0;
17932 $this->tabletfoot = 0;
17933 $this->lastoptionaltag = $tag; // Save current HTML specified optional endtag
17934 $this->tbCSSlvl++;
17935 $this->MergeCSS('TABLE',$tag,$attr);
17936 break;
17937
17938
17939 case 'TR':
17940 $this->lastoptionaltag = $tag; // Save current HTML specified optional endtag
17941 $this->tbCSSlvl++;
17942 $this->row++;
17943 $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['nr']++;
17944 $this->col = -1;
17945 $properties = $this->MergeCSS('TABLE',$tag,$attr);
17946
17947 if (!$this->simpleTables && (!isset($this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['borders_separate']) || !$this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['borders_separate'])) {
17948 if (isset($properties['BORDER-LEFT']) && $properties['BORDER-LEFT']) { $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['trborder-left'][$this->row] = $properties['BORDER-LEFT']; }
17949 if (isset($properties['BORDER-RIGHT']) && $properties['BORDER-RIGHT']) { $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['trborder-right'][$this->row] = $properties['BORDER-RIGHT']; }
17950 if (isset($properties['BORDER-TOP']) && $properties['BORDER-TOP']) { $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['trborder-top'][$this->row] = $properties['BORDER-TOP']; }
17951 if (isset($properties['BORDER-BOTTOM']) && $properties['BORDER-BOTTOM']) { $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['trborder-bottom'][$this->row] = $properties['BORDER-BOTTOM']; }
17952 }
17953
17954 if (isset($properties['BACKGROUND-COLOR'])) { $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['bgcolor'][$this->row] = $properties['BACKGROUND-COLOR']; }
17955
17956 /*-- BACKGROUNDS --*/
17957 if (isset($properties['BACKGROUND-GRADIENT']) && !$this->kwt && !$this->ColActive) { $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['trgradients'][$this->row] = $properties['BACKGROUND-GRADIENT']; }
17958
17959 if (isset($properties['BACKGROUND-IMAGE']) && $properties['BACKGROUND-IMAGE'] && !$this->kwt && !$this->ColActive) {
17960 $ret = $this->SetBackground($properties, $currblk['inner_width']);
17961 if ($ret) { $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['trbackground-images'][$this->row] = $ret; }
17962 }
17963 /*-- END BACKGROUNDS --*/
17964
17965
17966
17967
17968 if (isset($properties['TEXT-ROTATE'])) {
17969 $this->trow_text_rotate = $properties['TEXT-ROTATE'];
17970 }
17971 if (isset($attr['TEXT-ROTATE'])) $this->trow_text_rotate = $attr['TEXT-ROTATE'];
17972
17973 if (isset($attr['BGCOLOR'])) $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['bgcolor'][$this->row] = $attr['BGCOLOR'];
17974 if ($this->tablethead) { $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['is_thead'][$this->row] = true; }
17975 if ($this->tabletfoot) { $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['is_tfoot'][$this->row] = true; }
17976 $properties = array();
17977 break;
17978
17979
17980 // mPDF 5.3.75
17981 case 'TH':
17982 case 'TD':
17983 $this->ignorefollowingspaces = true;
17984 $this->lastoptionaltag = $tag; // Save current HTML specified optional endtag
17985 $this->tbCSSlvl++;
17986 $this->InlineProperties = array();
17987 $this->spanlvl = 0;
17988 $this->tdbegin = true;
17989 $this->col++;
17990 while (isset($this->cell[$this->row][$this->col])) { $this->col++; }
17991
17992 //Update number column
17993 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; }
17994
17995 $table = &$this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]];
17996
17997 // mPDF 5.3.77
17998 $c = array('a' => false,
17999 'R' => false,
18000 'nowrap' => false,
18001 'bgcolor' => false,
18002 'padding' => array('L' => false,
18003 'R' => false,
18004 'T' => false,
18005 'B' => false
18006 )
18007 );
18008
18009 if ($this->simpleTables && $this->row==0 && $this->col==0){
18010 $table['simple']['border'] = false;
18011 $table['simple']['border_details']['R']['w'] = 0;
18012 $table['simple']['border_details']['L']['w'] = 0;
18013 $table['simple']['border_details']['T']['w'] = 0;
18014 $table['simple']['border_details']['B']['w'] = 0;
18015 $table['simple']['border_details']['R']['style'] = '';
18016 $table['simple']['border_details']['L']['style'] = '';
18017 $table['simple']['border_details']['T']['style'] = '';
18018 $table['simple']['border_details']['B']['style'] = '';
18019 }
18020 else if (!$this->simpleTables) {
18021 $c['border'] = false;
18022 $c['border_details']['R']['w'] = 0;
18023 $c['border_details']['L']['w'] = 0;
18024 $c['border_details']['T']['w'] = 0;
18025 $c['border_details']['B']['w'] = 0;
18026 $c['border_details']['mbw']['BL'] = 0;
18027 $c['border_details']['mbw']['BR'] = 0;
18028 $c['border_details']['mbw']['RT'] = 0;
18029 $c['border_details']['mbw']['RB'] = 0;
18030 $c['border_details']['mbw']['TL'] = 0;
18031 $c['border_details']['mbw']['TR'] = 0;
18032 $c['border_details']['mbw']['LT'] = 0;
18033 $c['border_details']['mbw']['LB'] = 0;
18034 $c['border_details']['R']['style'] = '';
18035 $c['border_details']['L']['style'] = '';
18036 $c['border_details']['T']['style'] = '';
18037 $c['border_details']['B']['style'] = '';
18038 $c['border_details']['R']['s'] = 0;
18039 $c['border_details']['L']['s'] = 0;
18040 $c['border_details']['T']['s'] = 0;
18041 $c['border_details']['B']['s'] = 0;
18042 $c['border_details']['R']['c'] = $this->ConvertColor(0);
18043 $c['border_details']['L']['c'] = $this->ConvertColor(0);
18044 $c['border_details']['T']['c'] = $this->ConvertColor(0);
18045 $c['border_details']['B']['c'] = $this->ConvertColor(0);
18046 $c['border_details']['R']['dom'] = 0;
18047 $c['border_details']['L']['dom'] = 0;
18048 $c['border_details']['T']['dom'] = 0;
18049 $c['border_details']['B']['dom'] = 0;
18050 }
18051
18052
18053 if ($table['va']) { $c['va'] = $table['va']; }
18054 if ($table['txta']) { $c['a'] = $table['txta']; }
18055 if ($this->table_border_attr_set) {
18056 if ($table['border_details']) {
18057 if (!$this->simpleTables){
18058 $c['border_details']['R'] = $table['border_details']['R'];
18059 $c['border_details']['L'] = $table['border_details']['L'];
18060 $c['border_details']['T'] = $table['border_details']['T'];
18061 $c['border_details']['B'] = $table['border_details']['B'];
18062 $c['border'] = $table['border'];
18063 $c['border_details']['L']['dom'] = 1;
18064 $c['border_details']['R']['dom'] = 1;
18065 $c['border_details']['T']['dom'] = 1;
18066 $c['border_details']['B']['dom'] = 1;
18067 }
18068 else if ($this->simpleTables && $this->row==0 && $this->col==0){
18069 $table['simple']['border_details']['R'] = $table['border_details']['R'];
18070 $table['simple']['border_details']['L'] = $table['border_details']['L'];
18071 $table['simple']['border_details']['T'] = $table['border_details']['T'];
18072 $table['simple']['border_details']['B'] = $table['border_details']['B'];
18073 $table['simple']['border'] = $table['border'];
18074 }
18075 }
18076 }
18077 // INHERITED THEAD CSS Properties
18078 if ($this->tablethead) {
18079 if ($this->thead_valign_default) $c['va'] = $align[strtolower($this->thead_valign_default)];
18080 if ($this->thead_textalign_default) $c['a'] = $align[strtolower($this->thead_textalign_default)];
18081 if ($this->thead_font_weight == 'B') { $this->SetStyle('B',true); }
18082 if ($this->thead_font_style == 'I') { $this->SetStyle('I',true); }
18083 if ($this->thead_font_smCaps == 'S') { $this->SetStyle('S',true); } // mPDF 5.3.76
18084 }
18085
18086 // INHERITED TFOOT CSS Properties
18087 if ($this->tabletfoot) {
18088 if ($this->tfoot_valign_default) $c['va'] = $align[strtolower($this->tfoot_valign_default)];
18089 if ($this->tfoot_textalign_default) $c['a'] = $align[strtolower($this->tfoot_textalign_default)];
18090 if ($this->tfoot_font_weight == 'B') { $this->SetStyle('B',true); }
18091 if ($this->tfoot_font_style == 'I') { $this->SetStyle('I',true); }
18092 if ($this->tfoot_font_style == 'S') { $this->SetStyle('S',true); }
18093 }
18094
18095
18096 if ($this->trow_text_rotate){
18097 $c['R'] = $this->trow_text_rotate;
18098 }
18099
18100 $this->cell_border_dominance_L = 0;
18101 $this->cell_border_dominance_R = 0;
18102 $this->cell_border_dominance_T = 0;
18103 $this->cell_border_dominance_B = 0;
18104
18105 $properties = $this->MergeCSS('TABLE',$tag,$attr);
18106 $properties = $this->array_merge_recursive_unique($this->base_table_properties, $properties);
18107
18108 if (isset($properties['FONT-KERNING']) && (strtoupper($properties['FONT-KERNING'])=='NORMAL' || strtoupper($properties['FONT-KERNING'])=='AUTO')) {
18109 $this->kerning = true;
18110 }
18111 else { $this->kerning = false; }
18112
18113 if (isset($properties['LETTER-SPACING']) && ($properties['LETTER-SPACING'] || $properties['LETTER-SPACING']==='0') && strtoupper($properties['LETTER-SPACING']) != 'NORMAL') {
18114 $this->lSpacingCSS = strtoupper($properties['LETTER-SPACING']);
18115 $this->fixedlSpacing = $this->ConvertSize($this->lSpacingCSS,$this->FontSize);
18116 }
18117 else {
18118 $this->lSpacingCSS = '';
18119 $this->fixedlSpacing = false;
18120 }
18121 if (isset($properties['WORD-SPACING']) && strtoupper($properties['WORD-SPACING']) != 'NORMAL') {
18122 $this->wSpacingCSS = strtoupper($properties['WORD-SPACING']);
18123 $this->minwSpacing = $this->ConvertSize($this->wSpacingCSS,$this->FontSize);
18124 }
18125 else {
18126 $this->minwSpacing = 0;
18127 $this->wSpacingCSS = '';
18128 }
18129
18130 if (isset($properties['BACKGROUND-COLOR'])) { $c['bgcolor'] = $properties['BACKGROUND-COLOR']; }
18131 else if (isset($properties['BACKGROUND'])) { $c['bgcolor'] = $properties['BACKGROUND']; }
18132
18133 /*-- BACKGROUNDS --*/
18134 if (isset($properties['BACKGROUND-GRADIENT'])) { $c['gradient'] = $properties['BACKGROUND-GRADIENT']; }
18135 else { $c['gradient'] = false; }
18136
18137 if (isset($properties['BACKGROUND-IMAGE']) && $properties['BACKGROUND-IMAGE'] && !$this->keep_block_together) {
18138 $ret = $this->SetBackground($properties, $this->blk[$this->blklvl]['inner_width']);
18139 if ($ret) { $c['background-image'] = $ret; }
18140 }
18141 /*-- END BACKGROUNDS --*/
18142
18143 if (isset($properties['VERTICAL-ALIGN'])) { $c['va']=$align[strtolower($properties['VERTICAL-ALIGN'])]; }
18144 if (isset($properties['TEXT-ALIGN'])) { $c['a'] = $align[strtolower($properties['TEXT-ALIGN'])]; }
18145
18146 if (isset($properties['TEXT-ROTATE']) && ($properties['TEXT-ROTATE'] || $properties['TEXT-ROTATE']==="0")){
18147 $c['R'] = $properties['TEXT-ROTATE'];
18148 }
18149 if (isset($properties['BORDER'])) {
18150 $bord = $this->border_details($properties['BORDER']);
18151 if ($bord['s']) {
18152 if (!$this->simpleTables){
18153 $c['border'] = _BORDER_ALL;
18154 $c['border_details']['R'] = $bord;
18155 $c['border_details']['L'] = $bord;
18156 $c['border_details']['T'] = $bord;
18157 $c['border_details']['B'] = $bord;
18158 $c['border_details']['L']['dom'] = $this->cell_border_dominance_L;
18159 $c['border_details']['R']['dom'] = $this->cell_border_dominance_R;
18160 $c['border_details']['T']['dom'] = $this->cell_border_dominance_T;
18161 $c['border_details']['B']['dom'] = $this->cell_border_dominance_B;
18162 }
18163 else if ($this->simpleTables && $this->row==0 && $this->col==0){
18164 $table['simple']['border'] = _BORDER_ALL;
18165 $table['simple']['border_details']['R'] = $bord;
18166 $table['simple']['border_details']['L'] = $bord;
18167 $table['simple']['border_details']['T'] = $bord;
18168 $table['simple']['border_details']['B'] = $bord;
18169 }
18170 }
18171 }
18172 if (!$this->simpleTables){
18173 if (isset($properties['BORDER-RIGHT']) && $properties['BORDER-RIGHT']) {
18174 $c['border_details']['R'] = $this->border_details($properties['BORDER-RIGHT']);
18175 $this->setBorder($c['border'], _BORDER_RIGHT, $c['border_details']['R']['s']);
18176 $c['border_details']['R']['dom'] = $this->cell_border_dominance_R;
18177 }
18178 if (isset($properties['BORDER-LEFT']) && $properties['BORDER-LEFT']) {
18179 $c['border_details']['L'] = $this->border_details($properties['BORDER-LEFT']);
18180 $this->setBorder($c['border'], _BORDER_LEFT, $c['border_details']['L']['s']);
18181 $c['border_details']['L']['dom'] = $this->cell_border_dominance_L;
18182 }
18183 if (isset($properties['BORDER-BOTTOM']) && $properties['BORDER-BOTTOM']) {
18184 $c['border_details']['B'] = $this->border_details($properties['BORDER-BOTTOM']);
18185 $this->setBorder($c['border'], _BORDER_BOTTOM, $c['border_details']['B']['s']);
18186 $c['border_details']['B']['dom'] = $this->cell_border_dominance_B;
18187 }
18188 if (isset($properties['BORDER-TOP']) && $properties['BORDER-TOP']) {
18189 $c['border_details']['T'] = $this->border_details($properties['BORDER-TOP']);
18190 $this->setBorder($c['border'], _BORDER_TOP, $c['border_details']['T']['s']);
18191 $c['border_details']['T']['dom'] = $this->cell_border_dominance_T;
18192 }
18193 }
18194 else if ($this->simpleTables && $this->row==0 && $this->col==0){
18195 if (isset($properties['BORDER-LEFT']) && $properties['BORDER-LEFT']) {
18196 $bord = $this->border_details($properties['BORDER-LEFT']);
18197 if ($bord['s']) { $table['simple']['border'] = _BORDER_ALL; }
18198 else { $table['simple']['border'] = 0; }
18199 $table['simple']['border_details']['R'] = $bord;
18200 $table['simple']['border_details']['L'] = $bord;
18201 $table['simple']['border_details']['T'] = $bord;
18202 $table['simple']['border_details']['B'] = $bord;
18203 }
18204 }
18205
18206 // mPDF 5.3.15
18207 if ($this->simpleTables && $this->row==0 && $this->col==0 && !$table['borders_separate'] && $table['simple']['border'] ){
18208 $table['border_details'] = $table['simple']['border_details'];
18209 $table['border'] = $table['simple']['border'];
18210 }
18211
18212 // mPDF 5.3.78
18213 // Border set on TR (if collapsed only)
18214 if (!$table['borders_separate'] && !$this->simpleTables && isset($table['trborder-left'][$this->row])) {
18215 if ($this->col==0) {
18216 $left = $this->border_details($table['trborder-left'][$this->row]);
18217 $c['border_details']['L'] = $left;
18218 $this->setBorder($c['border'], _BORDER_LEFT, $c['border_details']['L']['s']);
18219 }
18220 $c['border_details']['B'] = $this->border_details($table['trborder-bottom'][$this->row]);
18221 $this->setBorder($c['border'], _BORDER_BOTTOM, $c['border_details']['B']['s']);
18222 $c['border_details']['T'] = $this->border_details($table['trborder-top'][$this->row]);
18223 $this->setBorder($c['border'], _BORDER_TOP, $c['border_details']['T']['s']);
18224 }
18225
18226 if ($this->packTableData && !$this->simpleTables) {
18227 $c['borderbin'] = $this->_packCellBorder($c);
18228 unset($c['border']);
18229 unset($c['border_details']);
18230 }
18231
18232 if (isset($properties['PADDING-LEFT'])) {
18233 $c['padding']['L'] = $this->ConvertSize($properties['PADDING-LEFT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
18234 }
18235 if (isset($properties['PADDING-RIGHT'])) {
18236 $c['padding']['R'] = $this->ConvertSize($properties['PADDING-RIGHT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
18237 }
18238 if (isset($properties['PADDING-BOTTOM'])) {
18239 $c['padding']['B'] = $this->ConvertSize($properties['PADDING-BOTTOM'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
18240 }
18241 if (isset($properties['PADDING-TOP'])) {
18242 $c['padding']['T'] = $this->ConvertSize($properties['PADDING-TOP'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
18243 }
18244
18245 $w = '';
18246 if (isset($properties['WIDTH'])) { $w = $properties['WIDTH']; }
18247 if (isset($attr['WIDTH'])) { $w = $attr['WIDTH']; }
18248 if ($w) {
18249 if (strpos($w,'%') && !$this->ignore_table_percents ) { $c['wpercent'] = $w + 0; } // makes 80% -> 80
18250 else if (!strpos($w,'%') && !$this->ignore_table_widths ) { $c['w'] = $this->ConvertSize($w,$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
18251 }
18252
18253 if (isset($properties['HEIGHT']) && !strpos($properties['HEIGHT'],'%')) { $c['h'] = $this->ConvertSize($properties['HEIGHT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); } // mPDF 5.3.57
18254
18255 if (isset($properties['COLOR'])) {
18256 $cor = $this->ConvertColor($properties['COLOR']);
18257 if ($cor) {
18258 $this->colorarray = $cor;
18259 $this->SetTColor($cor);
18260 }
18261 }
18262 if (isset($properties['FONT-FAMILY'])) {
18263 $this->SetFont($properties['FONT-FAMILY'],'',0,false);
18264 }
18265 if (isset($properties['FONT-SIZE'])) {
18266 $mmsize = $this->ConvertSize($properties['FONT-SIZE'],$this->default_font_size/_MPDFK);
18267 if ($mmsize) {
18268 $this->SetFontSize($mmsize*(_MPDFK),false);
18269 }
18270 }
18271 $c['dfs'] = $this->FontSize; // Default Font size
18272 if (isset($properties['FONT-WEIGHT'])) {
18273 if (strtoupper($properties['FONT-WEIGHT']) == 'BOLD') { $this->SetStyle('B',true); }
18274 }
18275 if (isset($properties['FONT-STYLE'])) {
18276 if (strtoupper($properties['FONT-STYLE']) == 'ITALIC') { $this->SetStyle('I',true); }
18277 }
18278 if (isset($properties['FONT-VARIANT'])) {
18279 if (strtoupper($properties['FONT-VARIANT']) == 'SMALL-CAPS') { $this->SetStyle('S',true); }
18280 }
18281 // mPDF 5.3.34
18282 if (isset($properties['TEXT-DECORATION'])) {
18283 if (strtoupper($properties['TEXT-DECORATION']) == 'LINE-THROUGH') { $this->strike = true; }
18284 else if (strtoupper($properties['TEXT-DECORATION']) == 'UNDERLINE') { $this->SetStyle('U',true); }
18285 }
18286 // mPDF 5.3.A2
18287 if (isset($properties['TEXT-SHADOW'])) {
18288 $ts = $this->setCSStextshadow($properties['TEXT-SHADOW']);
18289 if ($ts) { $this->textshadow = $ts; }
18290 }
18291 // mPDF 5.3.80
18292 if (isset($properties['TEXT-TRANSFORM'])) {
18293 if (strtoupper($properties['TEXT-TRANSFORM']) == 'CAPITALIZE') { $this->capitalize = true; }
18294 else if (strtoupper($properties['TEXT-TRANSFORM']) == 'UPPERCASE') { $this->toupper = true; }
18295 else if (strtoupper($properties['TEXT-TRANSFORM']) == 'LOWERCASE') { $this->tolower = true; }
18296 }
18297 if (isset($properties['WHITE-SPACE'])) {
18298 if (strtoupper($properties['WHITE-SPACE']) == 'NOWRAP') { $c['nowrap']= 1; }
18299 }
18300 $properties = array();
18301
18302
18303 if (isset($attr['HEIGHT']) && !strpos($attr['HEIGHT'],'%')) $c['h'] = $this->ConvertSize($attr['HEIGHT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); // mPDF 5.3.57
18304
18305 if (isset($attr['ALIGN'])) $c['a'] = $align[strtolower($attr['ALIGN'])];
18306
18307 if (!$c['a']) {
18308 if (isset($table['direction']) && $table['direction'] == 'rtl' ) { $c['a'] = 'R'; }
18309 else { $c['a'] = 'L'; }
18310 }
18311 if (isset($attr['VALIGN'])) $c['va'] = $align[strtolower($attr['VALIGN'])];
18312
18313
18314 if (isset($attr['BGCOLOR'])) $c['bgcolor'] = $attr['BGCOLOR'];
18315 if (isset($attr['TEXT-ROTATE'])) {
18316 $c['R'] = $attr['TEXT-ROTATE'];
18317 }
18318 if (isset($attr['NOWRAP']) && $attr['NOWRAP']) $c['nowrap']= 1;
18319
18320 // mPDF 5.3.77
18321 $this->cell[$this->row][$this->col] = $c;
18322 unset($c);
18323 $this->cell[$this->row][$this->col]['s'] = 0 ;
18324
18325 $cs = $rs = 1;
18326 if (isset($attr['COLSPAN']) && $attr['COLSPAN']>1) $cs = $this->cell[$this->row][$this->col]['colspan'] = $attr['COLSPAN'];
18327 if ($this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['nc'] < $this->col+$cs) {
18328 $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['nc'] = $this->col+$cs;
18329 } // mPDF 5.3.79 following code moved outside if...
18330 for($l=$this->col; $l < $this->col+$cs ;$l++) {
18331 if ($l-$this->col) $this->cell[$this->row][$l] = 0;
18332 }
18333 if (isset($attr['ROWSPAN']) && $attr['ROWSPAN']>1) $rs = $this->cell[$this->row][$this->col]['rowspan'] = $attr['ROWSPAN'];
18334 for ($k=$this->row ; $k < $this->row+$rs ;$k++) {
18335 for($l=$this->col; $l < $this->col+$cs ;$l++) {
18336 if ($k-$this->row || $l-$this->col) $this->cell[$k][$l] = 0;
18337 }
18338 }
18339 unset($table); // mPDF 5.3.76
18340 break;
18341 /*-- END TABLES --*/
18342
18343
18344 /*-- LISTS --*/
18345 // *********** LISTS ********************
18346 case 'OL':
18347 case 'UL':
18348 $this->listjustfinished = false;
18349
18350 if ($this->blockjustfinished && !count($this->textbuffer) && $this->y != $this->tMargin && $this->collapseBlockMargins) { $lastbottommargin = $this->lastblockbottommargin; }
18351 else { $lastbottommargin = 0; }
18352 $this->lastblockbottommargin = 0;
18353 $this->blockjustfinished=false;
18354
18355 $this->linebreakjustfinished=false;
18356 $this->lastoptionaltag = ''; // Save current HTML specified optional endtag
18357 $this->listCSSlvl++;
18358 if((!$this->tableLevel) && ($this->listlvl == 0)) {
18359 $blockstate = 0;
18360 //if ($this->lastblocklevelchange == 1) { $blockstate = -1; } // Top margins/padding only
18361 //else if ($this->lastblocklevelchange < 1) { $blockstate = 0; } // NO margins/padding
18362 // called from block after new div e.g. <div> ... <ol> ... Outputs block top margin/border and padding
18363 if (count($this->textbuffer) == 0 && $this->lastblocklevelchange == 1 && !$this->tableLevel && !$this->kwt) {
18364 $this->newFlowingBlock( $this->blk[$this->blklvl]['width'],$this->lineheight,'',false,false,1,true, $this->blk[$this->blklvl]['direction']);
18365 $this->finishFlowingBlock(true); // true = END of flowing block
18366 }
18367 else if (count($this->textbuffer)) { $this->printbuffer($this->textbuffer,$blockstate); }
18368 $this->textbuffer=array();
18369 $this->lastblocklevelchange = -1;
18370 }
18371 // ol and ul types are mixed here
18372 if ($this->listlvl == 0) {
18373 $this->list_indent = array();
18374 $this->list_align = array();
18375 $this->list_lineheight = array();
18376 $this->InlineProperties['LIST'] = array();
18377 $this->InlineProperties['LISTITEM'] = array();
18378 }
18379
18380 /*-- TABLES --*/
18381 // A simple list for inside a table
18382 if($this->tableLevel) {
18383 $this->list_indent[$this->listlvl] = 0; // mm default indent for each level
18384 if ($tag == 'OL') $this->listtype = '1';
18385 else if ($tag == 'UL') $this->listtype = 'disc';
18386 if ($this->listlvl > 0) {
18387 $this->listlist[$this->listlvl]['MAXNUM'] = $this->listnum; //save previous lvl's maxnum
18388 }
18389 $this->listlvl++;
18390 $this->listnum = 0; // reset
18391 $this->listlist[$this->listlvl] = array('TYPE'=>$this->listtype,'MAXNUM'=>$this->listnum);
18392 break;
18393 }
18394 /*-- END TABLES --*/
18395
18396
18397 if (($this->PDFA || $this->PDFX) && $tag == 'UL') {
18398 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 '-')"; }
18399 }
18400
18401 if ($this->listCSSlvl==1) {
18402 $properties = $this->MergeCSS('TOPLIST',$tag,$attr);
18403 }
18404 else {
18405 $properties = $this->MergeCSS('LIST',$tag,$attr);
18406 }
18407 if (!empty($properties)) $this->setCSS($properties,'LIST'); // mPDF 5.3.65
18408 // List-type
18409
18410 $this->listtype = '';
18411 if (isset($attr['TYPE']) && $attr['TYPE']) { $this->listtype = $attr['TYPE']; }
18412 else if (isset($properties['LIST-STYLE-TYPE'])) {
18413 $this->listtype = $this->_getListStyle($properties['LIST-STYLE-TYPE']);
18414 }
18415 else if (isset($properties['LIST-STYLE'])) {
18416 $this->listtype = $this->_getListStyle($properties['LIST-STYLE']);
18417 }
18418 if (!$this->listtype) {
18419 if ($tag == 'OL') $this->listtype = '1';
18420 if ($tag == 'UL') {
18421 if ($this->listlvl % 3 == 0) $this->listtype = 'disc';
18422 elseif ($this->listlvl % 3 == 1) $this->listtype = 'circle';
18423 else $this->listtype = 'square';
18424 }
18425 }
18426 if ($this->listlvl == 0) {
18427 $this->inherit_lineheight = 0;
18428 $this->listlvl++; // first depth level
18429 $this->listnum = 0; // reset
18430 $this->listDir = (isset($this->blk[$this->blklvl]['direction']) ? $this->blk[$this->blklvl]['direction'] : null);
18431 $occur = $this->listoccur[$this->listlvl] = 1;
18432 $this->listlist[$this->listlvl][1] = array('TYPE'=>$this->listtype,'MAXNUM'=>$this->listnum);
18433 }
18434 else {
18435 if (!empty($this->textbuffer))
18436 {
18437 $this->listitem[] = array($this->listlvl,$this->listnum,$this->textbuffer,$this->listoccur[$this->listlvl],$this->listitemtype);
18438 $this->listnum++;
18439 }
18440 // Save current lineheight to inherit
18441 $this->textbuffer = array();
18442 $occur = $this->listoccur[$this->listlvl];
18443 $this->listlist[$this->listlvl][$occur]['MAXNUM'] = $this->listnum; //save previous lvl's maxnum
18444 $this->listlvl++;
18445 $this->listnum = 0; // reset
18446
18447
18448 if (!isset($this->listoccur[$this->listlvl]) || $this->listoccur[$this->listlvl] == 0) $this->listoccur[$this->listlvl] = 1;
18449 else $this->listoccur[$this->listlvl]++;
18450 $occur = $this->listoccur[$this->listlvl];
18451 $this->listlist[$this->listlvl][$occur] = array('TYPE'=>$this->listtype,'MAXNUM'=>$this->listnum);
18452 }
18453
18454
18455 // TOP LEVEL ONLY
18456 if ($this->listlvl == 1) {
18457 if (isset($properties['MARGIN-TOP'])) {
18458 if ($lastbottommargin) {
18459 $tmp = $this->ConvertSize($properties['MARGIN-TOP'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
18460 if ($tmp > $lastbottommargin) { $properties['MARGIN-TOP'] -= $lastbottommargin; }
18461 else { $properties['MARGIN-TOP'] = 0; }
18462 }
18463 $this->DivLn($this->ConvertSize($properties['MARGIN-TOP'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false),$this->blklvl,true,1); // collapsible
18464 }
18465 if (isset($properties['MARGIN-BOTTOM'])) {
18466 $this->list_margin_bottom = $this->ConvertSize($properties['MARGIN-BOTTOM'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
18467 }
18468
18469 if (isset($this->blk[$this->blklvl]['line_height'])) {
18470 $this->list_lineheight[$this->listlvl][$occur] = $this->blk[$this->blklvl]['line_height'];
18471 }
18472
18473 if (isset($properties['DIRECTION']) && $properties['DIRECTION']) { $this->listDir = strtolower($properties['DIRECTION']); }
18474 if (isset($attr['DIR']) && $attr['DIR']) { $this->listDir = strtolower($attr['DIR']); }
18475
18476 }
18477 $this->list_indent[$this->listlvl][$occur] = 5; // mm default indent for each level
18478 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); }
18479
18480 if (isset($properties['TEXT-ALIGN'])) {
18481 $this->list_align[$this->listlvl][$occur] = $align[strtolower($properties['TEXT-ALIGN'])];
18482 }
18483
18484
18485 if (isset($properties['LINE-HEIGHT'])) {
18486 $this->list_lineheight[$this->listlvl][$occur] = $this->fixLineheight($properties['LINE-HEIGHT']);
18487 }
18488 else if ($this->listlvl>1 && isset($this->list_lineheight[($this->listlvl - 1)][1])) {
18489 $this->list_lineheight[$this->listlvl][$occur] = end($this->list_lineheight[($this->listlvl - 1)]);
18490 }
18491 if (!isset($this->list_lineheight[$this->listlvl][$occur]) || !$this->list_lineheight[$this->listlvl][$occur]) {
18492 $this->list_lineheight[$this->listlvl][$occur] = $this->normalLineheight;
18493 }
18494
18495 $this->InlineProperties['LIST'][$this->listlvl][$occur] = $this->saveInlineProperties();
18496 $properties = array();
18497 break;
18498
18499
18500
18501 case 'LI':
18502 // Start Block
18503 $this->lastoptionaltag = $tag; // Save current HTML specified optional endtag
18504 $this->ignorefollowingspaces = true; //Eliminate exceeding left-side spaces
18505 /*-- TABLES --*/
18506 // A simple list for inside a table
18507 if($this->tableLevel) {
18508 $this->blockjustfinished=false;
18509
18510 // If already something in the Cell
18511 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 ) {
18512 $this->_saveCellTextBuffer("\n"); // mPDF 5.3.99
18513 if (!isset($this->cell[$this->row][$this->col]['maxs'])) {
18514 $this->cell[$this->row][$this->col]['maxs'] = $this->cell[$this->row][$this->col]['s'];
18515 }
18516 elseif($this->cell[$this->row][$this->col]['maxs'] < $this->cell[$this->row][$this->col]['s']) {
18517 $this->cell[$this->row][$this->col]['maxs'] = $this->cell[$this->row][$this->col]['s'];
18518 }
18519 $this->cell[$this->row][$this->col]['s'] = 0 ;
18520 }
18521 if ($this->listlvl == 0) { //in case of malformed HTML code. Example:(...)</p><li>Content</li><p>Paragraph1</p>(...)
18522 $this->listlvl++; // first depth level
18523 $this->listnum = 0; // reset
18524 $this->listlist[$this->listlvl] = array('TYPE'=>'disc','MAXNUM'=>$this->listnum);
18525 }
18526
18527 $this->listnum++;
18528 switch($this->listlist[$this->listlvl]['TYPE']) {
18529 case 'A':
18530 $blt = $this->dec2alpha($this->listnum,true).$this->list_number_suffix;
18531 break;
18532 case 'a':
18533 $blt = $this->dec2alpha($this->listnum,false).$this->list_number_suffix;
18534 break;
18535 case 'I':
18536 $blt = $this->dec2roman($this->listnum,true).$this->list_number_suffix;
18537 break;
18538 case 'i':
18539 $blt = $this->dec2roman($this->listnum,false).$this->list_number_suffix;
18540 break;
18541 case '1':
18542 $blt = $this->listnum.$this->list_number_suffix;
18543 break;
18544 default:
18545 if ($this->listlvl % 3 == 1 && $this->_charDefined($this->CurrentFont['cw'],8226)) { $blt = "\xe2\x80\xa2"; } // &#8226;
18546 else if ($this->listlvl % 3 == 2 && $this->_charDefined($this->CurrentFont['cw'],9900)) { $blt = "\xe2\x9a\xac"; } // &#9900;
18547 else if ($this->listlvl % 3 == 0 && $this->_charDefined($this->CurrentFont['cw'],9642)) { $blt = "\xe2\x96\xaa"; } // &#9642;
18548 else { $blt = '-'; }
18549 break;
18550 }
18551
18552 // change to &nbsp; spaces
18553 if ($this->usingCoreFont) {
18554 $ls = str_repeat(chr(160).chr(160),($this->listlvl-1)*2) . $blt . ' ';
18555 }
18556 else {
18557 $ls = str_repeat("\xc2\xa0\xc2\xa0",($this->listlvl-1)*2) . $blt . ' ';
18558 }
18559
18560 $this->_saveCellTextBuffer($ls, $this->HREF); // mPDF 5.3.99
18561 $this->cell[$this->row][$this->col]['s'] += $this->GetStringWidth($ls);
18562 break;
18563 }
18564 /*-- END TABLES --*/
18565 //Observation: </LI> is ignored
18566 if ($this->listlvl == 0) { //in case of malformed HTML code. Example:(...)</p><li>Content</li><p>Paragraph1</p>(...)
18567 //First of all, skip a line
18568 $this->listlvl++; // first depth level
18569 $this->listnum = 0; // reset
18570 $this->listoccur[$this->listlvl] = 1;
18571 $this->listlist[$this->listlvl][1] = array('TYPE'=>'disc','MAXNUM'=>$this->listnum);
18572 }
18573 if ($this->listnum == 0) {
18574 $this->listnum++;
18575 $this->textbuffer = array();
18576 }
18577 else {
18578 if (!empty($this->textbuffer)) {
18579 if (!$this->listjustfinished) { // mPDF 5.3.11
18580 $this->listitem[] = array($this->listlvl,$this->listnum,$this->textbuffer,$this->listoccur[$this->listlvl],$this->listitemtype);
18581 $this->listnum++;
18582 }
18583 else { // mPDF 5.3.10
18584 $this->listitem[] = array($this->listlvl,$this->listnum,$this->textbuffer,$this->listoccur[$this->listlvl],$this->listitemtype, true);
18585 }
18586 }
18587 $this->textbuffer = array();
18588 }
18589 $this->listjustfinished = false; // mPDF 5.3.11
18590
18591 $this->listCSSlvl++;
18592 $properties = $this->MergeCSS('LIST',$tag,$attr);
18593 if (!empty($properties)) $this->setCSS($properties,'LIST'); // mPDF 5.3.98
18594 $this->InlineProperties['LISTITEM'][$this->listlvl][$this->listoccur[$this->listlvl]][$this->listnum] = $this->saveInlineProperties();
18595
18596 // List-type
18597 if (isset($attr['TYPE']) && $attr['TYPE']) { $this->listitemtype = $attr['TYPE']; }
18598 else if (isset($properties['LIST-STYLE-TYPE'])) {
18599 $this->listitemtype = $this->_getListStyle($properties['LIST-STYLE-TYPE']);
18600 }
18601 else if (isset($properties['LIST-STYLE'])) {
18602 $this->listitemtype = $this->_getListStyle($properties['LIST-STYLE']);
18603 }
18604 else $this->listitemtype = '';
18605 break;
18606 /*-- END LISTS --*/
18607
18608 }//end of switch
18609 }
18610
18611 /*-- LISTS --*/
18612
18613 function _getListStyle($ls) {
18614 if (stristr($ls,'decimal')) { return '1'; }
18615 /* CSS3 list-styles numeric (selected) + I added tamil
18616 arabic-indic | bengali | devanagari | gujarati | gurmukhi | kannada | malayalam | oriya | persian | telugu | thai | urdu
18617 */
18618 else if (preg_match('/(disc|circle|square|arabic-indic|bengali|devanagari|gujarati|gurmukhi|kannada|malayalam|oriya|persian|tamil|telugu|thai|urdu)/i',$ls,$m)) {
18619 return strtolower(trim($m[1]));
18620 }
18621 else if (stristr($ls,'lower-roman')) { return 'i'; }
18622 else if (stristr($ls,'upper-roman')) { return 'I'; }
18623 else if (stristr($ls,'lower-latin')|| stristr($ls,'lower-alpha')) { return 'a'; }
18624 else if (stristr($ls,'upper-latin') || stristr($ls,'upper-alpha')) { return 'A'; }
18625 else if (stristr($ls,'none')) { return 'none'; }
18626 else if (preg_match('/U\+([a-fA-F0-9]+)/i',$ls)) { return $ls; }
18627 else { return ''; }
18628 }
18629 /*-- END LISTS --*/
18630
18631
18632
18633 function CloseTag($tag)
18634 {
18635 $this->ignorefollowingspaces = false; //Eliminate exceeding left-side spaces
18636 //Closing tag
18637 if($tag=='OPTION') { $this->selectoption['ACTIVE'] = false; $this->lastoptionaltag = ''; }
18638
18639 if($tag=='TTS' or $tag=='TTA' or $tag=='TTZ') {
18640 if ($this->InlineProperties[$tag]) { $this->restoreInlineProperties($this->InlineProperties[$tag]); }
18641 unset($this->InlineProperties[$tag]);
18642 $ltag = strtolower($tag);
18643 $this->$ltag = false;
18644 }
18645
18646
18647 if($tag=='FONT' || $tag=='SPAN' || $tag=='CODE' || $tag=='KBD' || $tag=='SAMP' || $tag=='TT' || $tag=='VAR'
18648 || $tag=='INS' || $tag=='STRONG' || $tag=='CITE' || $tag=='SUB' || $tag=='SUP' || $tag=='S' || $tag=='STRIKE' || $tag=='DEL'
18649 || $tag=='Q' || $tag=='EM' || $tag=='B' || $tag=='I' || $tag=='U' | $tag=='SMALL' || $tag=='BIG' || $tag=='ACRONYM') {
18650
18651
18652 if ($tag == 'SPAN') {
18653 if (isset($this->InlineProperties['SPAN'][$this->spanlvl]) && $this->InlineProperties['SPAN'][$this->spanlvl]) { $this->restoreInlineProperties($this->InlineProperties['SPAN'][$this->spanlvl]); }
18654 unset($this->InlineProperties['SPAN'][$this->spanlvl]);
18655 if (isset($this->InlineAnnots['SPAN'][$this->spanlvl]) && $this->InlineAnnots['SPAN'][$this->spanlvl]) { $annot = $this->InlineAnnots['SPAN'][$this->spanlvl]; } // *ANNOTATIONS*
18656 unset($this->InlineAnnots['SPAN'][$this->spanlvl]); // *ANNOTATIONS*
18657 $this->spanlvl--;
18658 }
18659 else {
18660 if (isset($this->InlineProperties[$tag]) && $this->InlineProperties[$tag]) { $this->restoreInlineProperties($this->InlineProperties[$tag]); }
18661 unset($this->InlineProperties[$tag]);
18662 if (isset($this->InlineAnnots[$tag]) && $this->InlineAnnots[$tag]) { $annot = $this->InlineAnnots[$tag]; } // *ANNOTATIONS*
18663 unset($this->InlineAnnots[$tag]); // *ANNOTATIONS*
18664 }
18665
18666 /*-- ANNOTATIONS --*/
18667 if (isset($annot)) {
18668 if($this->tableLevel) { // *TABLES*
18669 $this->cell[$this->row][$this->col]['textbuffer'][] = array($annot); // *TABLES*
18670 } // *TABLES*
18671 else { // *TABLES*
18672 $this->textbuffer[] = array($annot);
18673 } // *TABLES*
18674 }
18675 /*-- END ANNOTATIONS --*/
18676 }
18677
18678
18679 if($tag=='A') {
18680 $this->HREF='';
18681 if (isset($this->InlineProperties['A'])) { $this->restoreInlineProperties($this->InlineProperties['A']); }
18682 unset($this->InlineProperties['A']);
18683 }
18684
18685
18686
18687 /*-- FORMS --*/
18688 // *********** FORM ELEMENTS ********************
18689
18690 if($tag=='TEXTAREA') {
18691 $this->specialcontent = '';
18692 if ($this->InlineProperties[$tag]) { $this->restoreInlineProperties($this->InlineProperties[$tag]); }
18693 unset($this->InlineProperties[$tag]);
18694 }
18695
18696
18697 if($tag=='SELECT') {
18698 $this->lastoptionaltag = '';
18699 $texto = '';
18700 if (isset($this->selectoption['SELECTED'])) { $texto = $this->selectoption['SELECTED']; }
18701
18702 if ($this->useActiveForms) { $w = $this->selectoption['MAXWIDTH']; }
18703 else { $w = $this->GetStringWidth($texto); }
18704 if ($w == 0) { $w = 5; }
18705 $objattr['type'] = 'select';
18706 $objattr['text'] = $texto;
18707 if (isset($this->selectoption['NAME'])) { $objattr['fieldname'] = $this->selectoption['NAME']; }
18708 if (isset($this->selectoption['READONLY'])) { $objattr['readonly'] = true; }
18709 if (isset($this->selectoption['REQUIRED'])) { $objattr['required'] = true; }
18710 if (isset($this->selectoption['SPELLCHECK'])) { $objattr['spellcheck'] = true; }
18711 if (isset($this->selectoption['EDITABLE'])) { $objattr['editable'] = true; }
18712 if (isset($this->selectoption['ONCHANGE'])) { $objattr['onChange'] = $this->selectoption['ONCHANGE']; }
18713 if (isset($this->selectoption['ITEMS'])) { $objattr['items'] = $this->selectoption['ITEMS']; }
18714 if (isset($this->selectoption['MULTIPLE'])) { $objattr['multiple'] = $this->selectoption['MULTIPLE']; }
18715 if (isset($this->selectoption['DISABLED'])) { $objattr['disabled'] = $this->selectoption['DISABLED']; }
18716 if (isset($this->selectoption['TITLE'])) { $objattr['title'] = $this->selectoption['TITLE']; }
18717 if (isset($this->selectoption['COLOR'])) { $objattr['color'] = $this->selectoption['COLOR']; }
18718 if (isset($this->selectoption['SIZE'])) { $objattr['size'] = $this->selectoption['SIZE']; }
18719 if (isset($objattr['size']) && $objattr['size']>1) { $rows=$objattr['size']; } else { $rows = 1; }
18720
18721 $objattr['fontfamily'] = $this->FontFamily;
18722 $objattr['fontsize'] = $this->FontSizePt;
18723
18724 $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);
18725 $objattr['height'] = ($this->FontSize*$rows) + ($this->form->form_element_spacing['select']['outer']['v']*2)+($this->form->form_element_spacing['select']['inner']['v']*2);
18726 $e = "\xbb\xa4\xactype=select,objattr=".serialize($objattr)."\xbb\xa4\xac";
18727
18728 // Clear properties - tidy up
18729 $properties = array();
18730
18731 // Output it to buffers
18732 if ($this->tableLevel) { // *TABLES*
18733 $this->_saveCellTextBuffer($e, $this->HREF); // mPDF 5.3.99
18734 $this->cell[$this->row][$this->col]['s'] += $objattr['width'] ; // *TABLES*
18735 } // *TABLES*
18736 else { // *TABLES*
18737 $this->_saveTextBuffer($e, $this->HREF); // mPDF 5.3.99
18738 } // *TABLES*
18739
18740 $this->selectoption = array();
18741 $this->specialcontent = '';
18742
18743 if ($this->InlineProperties[$tag]) { $this->restoreInlineProperties($this->InlineProperties[$tag]); }
18744 unset($this->InlineProperties[$tag]);
18745
18746 }
18747 /*-- END FORMS --*/
18748
18749
18750 // *********** BLOCKS ********************
18751
18752 if($tag=='P' || $tag=='DIV' || $tag=='H1' || $tag=='H2' || $tag=='H3' || $tag=='H4' || $tag=='H5' || $tag=='H6' || $tag=='PRE'
18753 || $tag=='FORM' || $tag=='ADDRESS' || $tag=='BLOCKQUOTE' || $tag=='CENTER' || $tag=='DT' || $tag=='DD' || $tag=='DL' || $tag=='CAPTION' ) {
18754 // mPDF 5.3.56
18755
18756 $this->ignorefollowingspaces = true; //Eliminate exceeding left-side spaces
18757 $this->blockjustfinished=true;
18758
18759 $this->lastblockbottommargin = $this->blk[$this->blklvl]['margin_bottom'];
18760 /*-- LISTS --*/
18761 if ($this->listlvl>0) { return; }
18762 /*-- END LISTS --*/
18763
18764 /*-- TABLES --*/
18765 if($this->tableLevel) {
18766 if ($this->linebreakjustfinished) { $this->blockjustfinished=false; }
18767 if (isset($this->InlineProperties['BLOCKINTABLE'])) {
18768 if ($this->InlineProperties['BLOCKINTABLE']) { $this->restoreInlineProperties($this->InlineProperties['BLOCKINTABLE']); }
18769 unset($this->InlineProperties['BLOCKINTABLE']);
18770 }
18771 if($tag=='PRE') { $this->ispre=false; }
18772 return;
18773 }
18774 /*-- END TABLES --*/
18775 $this->lastoptionaltag = '';
18776 $this->divbegin=false;
18777
18778 $this->linebreakjustfinished=false;
18779
18780 $this->x = $this->lMargin + $this->blk[$this->blklvl]['outer_left_margin'];
18781
18782 /*-- CSS-FLOAT --*/
18783 // If float contained in a float, need to extend bottom to allow for it
18784 $currpos = $this->page*1000 + $this->y;
18785 if (isset($this->blk[$this->blklvl]['float_endpos']) && $this->blk[$this->blklvl]['float_endpos'] > $currpos) {
18786 $old_page = $this->page;
18787 $new_page = intval($this->blk[$this->blklvl]['float_endpos'] /1000);
18788 if ($old_page != $new_page) {
18789 $s = $this->PrintPageBackgrounds();
18790 // Writes after the marker so not overwritten later by page background etc.
18791 $this->pages[$this->page] = preg_replace('/(___BACKGROUND___PATTERNS'.date('jY').')/', '\\1'."\n".$s."\n", $this->pages[$this->page]);
18792 $this->pageBackgrounds = array();
18793 $this->page = $new_page;
18794 $this->ResetMargins();
18795 $this->Reset();
18796 $this->pageoutput[$this->page] = array();
18797 }
18798 $this->y = (($this->blk[$this->blklvl]['float_endpos'] *1000) % 1000000)/1000; // mod changes operands to integers before processing
18799 }
18800 /*-- END CSS-FLOAT --*/
18801
18802 //Print content
18803 if ($this->lastblocklevelchange == 1) { $blockstate = 3; } // Top & bottom margins/padding
18804 else if ($this->lastblocklevelchange == -1) { $blockstate = 2; } // Bottom margins/padding only
18805 else { $blockstate = 0; }
18806 // called from after e.g. </table> </div> </div> ... Outputs block margin/border and padding
18807 if (count($this->textbuffer) && $this->textbuffer[count($this->textbuffer)-1]) {
18808 if (substr($this->textbuffer[count($this->textbuffer)-1][0],0,3) != "\xbb\xa4\xac") { // not special content
18809 if ($this->usingCoreFont) {
18810 $this->textbuffer[count($this->textbuffer)-1][0] = preg_replace('/[ ]+$/', '', $this->textbuffer[count($this->textbuffer)-1][0]);
18811 }
18812 else {
18813 $this->textbuffer[count($this->textbuffer)-1][0] = preg_replace('/[ ]+$/u', '', $this->textbuffer[count($this->textbuffer)-1][0]); }
18814 }
18815 }
18816 if (count($this->textbuffer) == 0 && $this->lastblocklevelchange != 0) {
18817 //$this->newFlowingBlock( $this->blk[$this->blklvl]['width'],$this->lineheight,'',false,false,2,true, $this->blk[$this->blklvl]['direction']);
18818 $this->newFlowingBlock( $this->blk[$this->blklvl]['width'],$this->lineheight,'',false,false,$blockstate,true, $this->blk[$this->blklvl]['direction']); // mPDF 5.3.29
18819 $this->finishFlowingBlock(true); // true = END of flowing block
18820 $this->PaintDivBB('',$blockstate);
18821 }
18822 else {
18823 $this->printbuffer($this->textbuffer,$blockstate);
18824 }
18825
18826
18827 $this->textbuffer=array();
18828
18829 if ($this->blk[$this->blklvl]['keep_block_together']) {
18830 $this->printdivbuffer();
18831 }
18832
18833 if ($this->kwt) {
18834 $this->kwt_height = $this->y - $this->kwt_y0;
18835 }
18836
18837 /*-- CSS-IMAGE-FLOAT --*/
18838 $this->printfloatbuffer();
18839 /*-- END CSS-IMAGE-FLOAT --*/
18840
18841 if($tag=='PRE') { $this->ispre=false; }
18842
18843 /*-- CSS-FLOAT --*/
18844 if ($this->blk[$this->blklvl]['float'] == 'R') {
18845 // If width not set, here would need to adjust and output buffer
18846 $s = $this->PrintPageBackgrounds();
18847 // Writes after the marker so not overwritten later by page background etc.
18848 $this->pages[$this->page] = preg_replace('/(___BACKGROUND___PATTERNS'.date('jY').')/', '\\1'."\n".$s."\n", $this->pages[$this->page]);
18849 $this->pageBackgrounds = array();
18850 $this->Reset();
18851 $this->pageoutput[$this->page] = array();
18852
18853 for($i=($this->blklvl-1); $i >= 0; $i--) {
18854 if (isset($this->blk[$i]['float_endpos'])) { $this->blk[$i]['float_endpos'] = max($this->blk[$i]['float_endpos'], ($this->page*1000 + $this->y)); }
18855 else { $this->blk[$i]['float_endpos'] = $this->page*1000 + $this->y; }
18856 }
18857
18858 $this->floatDivs[] = array(
18859 'side'=>'R',
18860 'startpage'=>$this->blk[$this->blklvl]['startpage'] ,
18861 'y0'=>$this->blk[$this->blklvl]['float_start_y'] ,
18862 'startpos'=> ($this->blk[$this->blklvl]['startpage']*1000 + $this->blk[$this->blklvl]['float_start_y']),
18863 'endpage'=>$this->page ,
18864 'y1'=>$this->y ,
18865 'endpos'=> ($this->page*1000 + $this->y),
18866 'w'=> $this->blk[$this->blklvl]['float_width'],
18867 'blklvl'=>$this->blklvl,
18868 'blockContext' => $this->blk[$this->blklvl-1]['blockContext']
18869 );
18870
18871 $this->y = $this->blk[$this->blklvl]['float_start_y'] ;
18872 $this->page = $this->blk[$this->blklvl]['startpage'] ;
18873 $this->ResetMargins();
18874 $this->pageoutput[$this->page] = array();
18875 }
18876 if ($this->blk[$this->blklvl]['float'] == 'L') {
18877 // If width not set, here would need to adjust and output buffer
18878 $s = $this->PrintPageBackgrounds();
18879 // Writes after the marker so not overwritten later by page background etc.
18880 $this->pages[$this->page] = preg_replace('/(___BACKGROUND___PATTERNS'.date('jY').')/', '\\1'."\n".$s."\n", $this->pages[$this->page]);
18881 $this->pageBackgrounds = array();
18882 $this->Reset();
18883 $this->pageoutput[$this->page] = array();
18884
18885 for($i=($this->blklvl-1); $i >= 0; $i--) {
18886 if (isset($this->blk[$i]['float_endpos'])) { $this->blk[$i]['float_endpos'] = max($this->blk[$i]['float_endpos'], ($this->page*1000 + $this->y)); }
18887 else { $this->blk[$i]['float_endpos'] = $this->page*1000 + $this->y; }
18888 }
18889
18890 $this->floatDivs[] = array(
18891 'side'=>'L',
18892 'startpage'=>$this->blk[$this->blklvl]['startpage'] ,
18893 'y0'=>$this->blk[$this->blklvl]['float_start_y'] ,
18894 'startpos'=> ($this->blk[$this->blklvl]['startpage']*1000 + $this->blk[$this->blklvl]['float_start_y']),
18895 'endpage'=>$this->page ,
18896 'y1'=>$this->y ,
18897 'endpos'=> ($this->page*1000 + $this->y),
18898 'w'=> $this->blk[$this->blklvl]['float_width'],
18899 'blklvl'=>$this->blklvl,
18900 'blockContext' => $this->blk[$this->blklvl-1]['blockContext']
18901 );
18902
18903 $this->y = $this->blk[$this->blklvl]['float_start_y'] ;
18904 $this->page = $this->blk[$this->blklvl]['startpage'] ;
18905 $this->ResetMargins();
18906 $this->pageoutput[$this->page] = array();
18907 }
18908 /*-- END CSS-FLOAT --*/
18909
18910 // mPDF 5.3.42 VISIBILITY
18911 if (isset($this->blk[$this->blklvl]['visibility']) && $this->blk[$this->blklvl]['visibility']!='visible') {
18912 $this->SetVisibility('visible');
18913 }
18914
18915
18916 // mPDF 5.3.03
18917 if (isset($this->blk[$this->blklvl]['page_break_after'])) { $page_break_after = $this->blk[$this->blklvl]['page_break_after']; }
18918 else { $page_break_after = ''; }
18919
18920 //Reset values
18921 $this->Reset();
18922
18923 if ($this->blklvl > 0) { // ==0 SHOULDN'T HAPPEN - NOT XHTML
18924 if ($this->blk[$this->blklvl]['tag'] == $tag) {
18925 unset($this->blk[$this->blklvl]);
18926 $this->blklvl--;
18927 }
18928 //else { echo $tag; exit; } // debug - forces error if incorrectly nested html tags
18929 }
18930
18931 $this->lastblocklevelchange = -1 ;
18932 // Reset Inline-type properties
18933 if (isset($this->blk[$this->blklvl]['InlineProperties'])) { $this->restoreInlineProperties($this->blk[$this->blklvl]['InlineProperties']); }
18934
18935 $this->x = $this->lMargin + $this->blk[$this->blklvl]['outer_left_margin'];
18936
18937 // mPDF 5.3.03
18938 if ($page_break_after) {
18939 $save_blklvl = $this->blklvl;
18940 $save_blk = $this->blk;
18941 $save_silp = $this->saveInlineProperties();
18942 $save_spanlvl = $this->spanlvl;
18943 $save_ilp = $this->InlineProperties;
18944 if ($this->blklvl>1) {
18945 // Close any open block tags
18946 for ($b= $this->blklvl;$b>0;$b--) { $this->CloseTag($this->blk[$b]['tag']); }
18947 // Output any text left in buffer
18948 if (count($this->textbuffer)) { $this->printbuffer($this->textbuffer); $this->textbuffer=array(); }
18949 }
18950 /*-- COLUMNS --*/
18951 $save_cols = false;
18952 if ($this->ColActive) {
18953 $save_cols = true;
18954 $save_nbcol = $this->NbCol; // other values of gap and vAlign will not change by setting Columns off
18955 $this->SetColumns(0);
18956 }
18957 /*-- END COLUMNS --*/
18958 if ($page_break_after == 'RIGHT') { $this->AddPage($this->CurOrientation,'NEXT-ODD','','','','','', '','', '','','','','','',0,0,0,0,$pagesel); }
18959 else if ($page_break_after == 'LEFT') { $this->AddPage($this->CurOrientation,'NEXT-EVEN','','','','','', '','', '','','','','','',0,0,0,0,$pagesel); }
18960 else { $this->AddPage($this->CurOrientation,'','','','','','', '','', '','','','','','',0,0,0,0,$pagesel); }
18961 if (!$this->restoreBlockPagebreaks) {
18962 $this->blklvl = 0;
18963 $this->lastblocklevelchange = 0;
18964 $this->blk = array();
18965 $this->initialiseBlock($this->blk[0]);
18966 $this->blk[0]['width'] =& $this->pgwidth;
18967 $this->blk[0]['inner_width'] =& $this->pgwidth;
18968 $this->blk[0]['blockContext'] = $this->blockContext;
18969 $properties = $this->MergeCSS('BLOCK','BODY','');
18970 $this->setCSS($properties,'','BODY');
18971 $this->blklvl++;
18972 $currblk =& $this->blk[$this->blklvl];
18973 $prevblk =& $this->blk[$this->blklvl-1];
18974
18975 $this->initialiseBlock($currblk);
18976 $currblk['tag'] = $tag;
18977 $currblk['attr'] = $attr;
18978
18979 $this->Reset();
18980 $properties = $this->MergeCSS('BLOCK',$tag,$attr);
18981 }
18982 /*-- COLUMNS --*/
18983 if ($save_cols) {
18984 // Restore columns
18985 $this->SetColumns($save_nbcol,$this->colvAlign,$this->ColGap);
18986 }
18987 /*-- END COLUMNS --*/
18988 if ($this->restoreBlockPagebreaks && !$this->tableLevel && !$this->listlvl) {
18989 $this->blk = $save_blk;
18990 // Re-open block tags
18991 $t = $this->blk[0]['tag'];
18992 $a = $this->blk[0]['attr'];
18993 $this->blklvl = 0;
18994 for ($b=0; $b<=$save_blklvl;$b++) {
18995 $tc = $t;
18996 $ac = $a;
18997 $t = $this->blk[$b+1]['tag'];
18998 $a = $this->blk[$b+1]['attr'];
18999 unset($this->blk[$b+1]);
19000 $this->OpenTag($tc,$ac);
19001 }
19002 $this->spanlvl = $save_spanlvl;
19003 $this->InlineProperties = $save_ilp;
19004 $this->restoreInlineProperties($save_silp);
19005 }
19006 }
19007
19008 }
19009
19010
19011 /*-- TABLES --*/
19012
19013 if($tag=='TH') $this->SetStyle('B',false);
19014
19015 if(($tag=='TH' or $tag=='TD') && $this->tableLevel) {
19016 $this->lastoptionaltag = 'TR';
19017 unset($this->tablecascadeCSS[$this->tbCSSlvl]);
19018 $this->tbCSSlvl--;
19019 if (!$this->tdbegin) { return; } // mPDF 5.3.79
19020 $this->tdbegin = false;
19021 // Added for correct calculation of cell column width - otherwise misses the last line if not end </p> etc.
19022 if (!isset($this->cell[$this->row][$this->col]['maxs'])) {
19023 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;"); }
19024 $this->cell[$this->row][$this->col]['maxs'] = $this->cell[$this->row][$this->col]['s'];
19025 }
19026 elseif($this->cell[$this->row][$this->col]['maxs'] < $this->cell[$this->row][$this->col]['s']) {
19027 $this->cell[$this->row][$this->col]['maxs'] = $this->cell[$this->row][$this->col]['s'];
19028 }
19029
19030 // Remove last <br> if at end of cell
19031 if (isset($this->cell[$this->row][$this->col]['textbuffer'])) { $ntb = count($this->cell[$this->row][$this->col]['textbuffer']); }
19032 else { $ntb = 0; }
19033 if ($ntb>1 && $this->cell[$this->row][$this->col]['textbuffer'][$ntb-1][0] == "\n") {
19034 unset($this->cell[$this->row][$this->col]['textbuffer'][$ntb-1]);
19035 }
19036
19037 // mPDF 5.3.79
19038 if ($this->cacheTables) {
19039 $clen = $this->_cacheCell($this->cell[$this->row][$this->col], $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['cache']);
19040 $this->cell[$this->row][$this->col] = $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['ptr'];
19041 $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['ptr'] += $clen;
19042 }
19043
19044 // mPDF 5.3.62
19045 if ($this->tablethead) {
19046 $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['is_thead'][$this->row] = true;
19047 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)); }
19048 }
19049 if ($this->tabletfoot) {
19050 $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['is_tfoot'][$this->row] = true;
19051 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'] )); }
19052 }
19053 $this->Reset();
19054 }
19055
19056 if($tag=='TR' && $this->tableLevel) {
19057 // mPDF 5.3.78
19058 // If Border set on TR - Update right border
19059 if (isset($this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['trborder-left'][$this->row])) {
19060 // mPDF 5.3.79
19061 if ($this->cacheTables) {
19062 $c = $this->_uncacheCell($this->cell[$this->row][$this->col], $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['cache'], null);
19063 }
19064 else { $c =& $this->cell[$this->row][$this->col]; }
19065 if ($c) {
19066 if ($this->packTableData) {
19067 $cell = $this->_unpackCellBorder($c['borderbin'] );
19068 }
19069 else { $cell = $c; }
19070 $cell['border_details']['R'] = $this->border_details($this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['trborder-right'][$this->row]);
19071 $this->setBorder($cell['border'], _BORDER_RIGHT, $cell['border_details']['R']['s']);
19072 if ($this->packTableData) {
19073 $c['borderbin'] = $this->_packCellBorder($cell);
19074 unset($c['border']);
19075 unset($c['border_details']);
19076 }
19077 else { $c = $cell; }
19078 }
19079 // mPDF 5.3.79
19080 if ($this->cacheTables) {
19081 $fh = fopen($this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['cache'], "r+b");
19082 $this->_cacheUpdateBorder($c, $fh, $this->cell[$this->row][$this->col]);
19083 fclose($fh);
19084 }
19085 }
19086 $this->lastoptionaltag = '';
19087 unset($this->tablecascadeCSS[$this->tbCSSlvl]);
19088 $this->tbCSSlvl--;
19089 $this->trow_text_rotate = '';
19090 $this->tabletheadjustfinished = false;
19091 }
19092
19093 if($tag=='TBODY') {
19094 $this->lastoptionaltag = '';
19095 unset($this->tablecascadeCSS[$this->tbCSSlvl]);
19096 $this->tbCSSlvl--;
19097 }
19098
19099 if($tag=='THEAD') {
19100 $this->lastoptionaltag = '';
19101 unset($this->tablecascadeCSS[$this->tbCSSlvl]);
19102 $this->tbCSSlvl--;
19103 $this->tablethead = 0;
19104 $this->tabletheadjustfinished = true;
19105 $this->ResetStyles();
19106 $this->thead_font_weight = '';
19107 $this->thead_font_style = '';
19108 $this->thead_font_smCaps = '';
19109
19110 $this->thead_valign_default = '';
19111 $this->thead_textalign_default = '';
19112 }
19113
19114 if($tag=='TFOOT') {
19115 $this->lastoptionaltag = '';
19116 unset($this->tablecascadeCSS[$this->tbCSSlvl]);
19117 $this->tbCSSlvl--;
19118 $this->tabletfoot = 0;
19119 $this->ResetStyles();
19120 $this->tfoot_font_weight = '';
19121 $this->tfoot_font_style = '';
19122 $this->tfoot_font_smCaps = '';
19123
19124 $this->tfoot_valign_default = '';
19125 $this->tfoot_textalign_default = '';
19126 }
19127
19128 if($tag=='TABLE') { // TABLE-END (
19129 if ($this->progressBar) { $this->UpdateProgressBar(1,'','TABLE'); } // *PROGRESS-BAR*
19130 if ($this->progressBar) { $this->UpdateProgressBar(7,0,''); } // *PROGRESS-BAR*
19131 $this->lastoptionaltag = '';
19132 unset($this->tablecascadeCSS[$this->tbCSSlvl]);
19133 $this->tbCSSlvl--;
19134 $this->ignorefollowingspaces = true; //Eliminate exceeding left-side spaces
19135 $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['cells'] = $this->cell;
19136 $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));
19137 $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['hr'] = array_pad(array(),$this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['nr'],0);
19138
19139 // Move table footer <tfoot> row to end of table
19140 if (isset($this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['is_tfoot']) && count($this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['is_tfoot'])) {
19141 $tfrows = array();
19142 foreach($this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['is_tfoot'] AS $r=>$val) {
19143 if ($val) { $tfrows[] = $r; }
19144 }
19145 $temp = array();
19146 $temptf = array();
19147 foreach($this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['cells'] AS $k=>$row) {
19148 if (in_array($k,$tfrows)) {
19149 $temptf[] = $row;
19150 }
19151 else {
19152 $temp[] = $row;
19153 }
19154 }
19155 $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['is_tfoot'] = array();
19156 for($i=count($temp) ; $i<(count($temp)+count($temptf)); $i++) {
19157 $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['is_tfoot'][$i] = true;
19158 }
19159 // Update nestedpos row references
19160 if (count($this->table[($this->tableLevel+1)])) {
19161 foreach($this->table[($this->tableLevel+1)] AS $nid=>$nested) {
19162 $this->table[($this->tableLevel+1)][$nid]['nestedpos'][0] -= count($temptf);
19163 }
19164 }
19165 $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['cells'] = array_merge($temp, $temptf);
19166
19167 // Update other arays set on row number
19168 // [trbackground-images] [trgradients]
19169 $temptrbgi = array();
19170 $temptrbgg = array();
19171 $temptrbgc = array();
19172 $temptrbgc[-1] = $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['bgcolor'][-1];
19173 for($k=0; $k<$this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['nr']; $k++) {
19174 if (!in_array($k,$tfrows)) {
19175 $temptrbgi[] = $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['trbackground-images'][$k];
19176 $temptrbgg[] = $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['trgradients'][$k];
19177 $temptrbgc[] = $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['bgcolor'][$k];
19178 }
19179 }
19180 for($k=0; $k<$this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['nr']; $k++) {
19181 if (in_array($k,$tfrows)) {
19182 $temptrbgi[] = $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['trbackground-images'][$k];
19183 $temptrbgg[] = $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['trgradients'][$k];
19184 $temptrbgc[] = $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['bgcolor'][$k];
19185 }
19186 }
19187 $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['trbackground-images'] = $temptrbgi;
19188 $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['trgradients'] = $temptrbgg;
19189 $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['bgcolor'] = $temptrbgc ;
19190 // Should Update all other arays set on row number, but cell properties have been set so not needed
19191 // [bgcolor] [trborder-left] [trborder-right] [trborder-top] [trborder-bottom]
19192 }
19193
19194 if ($this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['direction']=='rtl') {
19195 $this->_reverseTableDir($this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]);
19196 }
19197
19198 // Fix Borders *********************************************
19199 $this->_fixTableBorders($this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]);
19200
19201 if ($this->progressBar) { $this->UpdateProgressBar(7,10,' '); } // *PROGRESS-BAR*
19202
19203 if ($this->ColActive) { $this->table_rotate = 0; } // *COLUMNS*
19204 if ($this->table_rotate <> 0) {
19205 $this->tablebuffer = '';
19206 // Max width for rotated table
19207 $this->tbrot_maxw = $this->h - ($this->y + $this->bMargin + 1);
19208 $this->tbrot_maxh = $this->blk[$this->blklvl]['inner_width'] ; // Max width for rotated table
19209 $this->tbrot_align = $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['a'] ;
19210 }
19211 $this->shrin_k = 1;
19212
19213 if ($this->shrink_tables_to_fit < 1) { $this->shrink_tables_to_fit = 1; }
19214 if (!$this->shrink_this_table_to_fit) { $this->shrink_this_table_to_fit = $this->shrink_tables_to_fit; }
19215
19216 if ($this->tableLevel>1) {
19217 // deal with nested table
19218
19219 $this->_tableColumnWidth($this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]],true);
19220
19221 $tmiw = $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['miw'];
19222 $tmaw = $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['maw'];
19223 $tl = $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['tl'];
19224
19225 // Go down to lower table level
19226 $this->tableLevel--;
19227
19228 // Reset lower level table
19229 $this->base_table_properties = $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['baseProperties'];
19230 $this->cell = $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['cells'];
19231 $this->row = $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['currrow'];
19232 $this->col = $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['currcol'];
19233 $objattr = array();
19234 $objattr['type'] = 'nestedtable';
19235 $objattr['nestedcontent'] = $this->tbctr[($this->tableLevel+1)];
19236 $objattr['table'] = $this->tbctr[$this->tableLevel];
19237 $objattr['row'] = $this->row;
19238 $objattr['col'] = $this->col;
19239 $objattr['level'] = $this->tableLevel;
19240 $e = "\xbb\xa4\xactype=nestedtable,objattr=".serialize($objattr)."\xbb\xa4\xac";
19241 $this->_saveCellTextBuffer($e); // mPDF 5.3.99
19242 $this->cell[$this->row][$this->col]['s'] += $tl ;
19243 if (!isset($this->cell[$this->row][$this->col]['maxs'])) {
19244 $this->cell[$this->row][$this->col]['maxs'] = $this->cell[$this->row][$this->col]['s'];
19245 }
19246 elseif($this->cell[$this->row][$this->col]['maxs'] < $this->cell[$this->row][$this->col]['s']) {
19247 $this->cell[$this->row][$this->col]['maxs'] = $this->cell[$this->row][$this->col]['s'];
19248 }
19249 $this->cell[$this->row][$this->col]['s'] = 0;// reset
19250 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 ; }
19251 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 ; }
19252 // mPDF 5.3.79 ?? Removed as Not needed for anything
19253 // $this->cell[$this->row][$this->col]['nestedcontent'][] = $this->tbctr[($this->tableLevel+1)];
19254 $this->tdbegin = true;
19255 $this->nestedtablejustfinished = true;
19256 $this->ignorefollowingspaces = true;
19257 return;
19258 }
19259 $this->cMarginL = 0;
19260 $this->cMarginR = 0;
19261 $this->cMarginT = 0;
19262 $this->cMarginB = 0;
19263 $this->cellPaddingL = 0;
19264 $this->cellPaddingR = 0;
19265 $this->cellPaddingT = 0;
19266 $this->cellPaddingB = 0;
19267
19268 // mPDF 5.3.36 // mPDF 5.3.76
19269 if (isset($this->table[1][1]['overflow']) && $this->table[1][1]['overflow']=='visible') {
19270 if ($this->kwt || $this->table_rotate || $this->table_keep_together || $this->ColActive) {
19271 $this->kwt = false;
19272 $this->table_rotate = 0;
19273 $this->table_keep_together = false;
19274 //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");
19275 }
19276 $this->_tableColumnWidth($this->table[1][1],true);
19277 $this->_tableWidth($this->table[1][1]);
19278 }
19279 else {
19280 if (!$this->kwt_saved) { $this->kwt_height = 0; }
19281
19282 list($check,$tablemiw) = $this->_tableColumnWidth($this->table[1][1],true);
19283 $save_table = $this->table;
19284 // mPDF 5.3.79
19285 if ($this->cacheTables) { $this->_backupCacheFiles(); }
19286 $reset_to_minimum_width = false;
19287 $added_page = false;
19288
19289 if ($check > 1) {
19290 if ($check > $this->shrink_this_table_to_fit && $this->table_rotate) {
19291 if ($this->y != $this->tMargin) { // mPDF 5.3.69
19292 $this->AddPage($this->CurOrientation);
19293 $this->kwt_moved = true;
19294 }
19295 $added_page = true;
19296 $this->tbrot_maxw = $this->h - ($this->y + $this->bMargin + 5) - $this->kwt_height;
19297 //$check = $tablemiw/$this->tbrot_maxw; // undo any shrink
19298 $check = 1; // undo any shrink
19299 }
19300 $reset_to_minimum_width = true;
19301 }
19302
19303 if ($reset_to_minimum_width) {
19304
19305 $this->shrin_k = $check;
19306
19307 $this->default_font_size /= $this->shrin_k;
19308 $this->SetFontSize($this->default_font_size, false );
19309
19310 $this->shrinkTable($this->table[1][1],$this->shrin_k);
19311
19312 $this->_tableColumnWidth($this->table[1][1],false); // repeat
19313
19314 // Starting at $this->innermostTableLevel
19315 // Shrink table values - and redo columnWidth
19316 for($lvl=2;$lvl<=$this->innermostTableLevel;$lvl++) {
19317 for ($nid=1; $nid<=$this->tbctr[$lvl]; $nid++) {
19318 $this->shrinkTable($this->table[$lvl][$nid],$this->shrin_k);
19319 $this->_tableColumnWidth($this->table[$lvl][$nid],false);
19320 }
19321 }
19322 }
19323
19324 // Set table cell widths for top level table
19325 // Use $shrin_k to resize but don't change again
19326 $this->SetLineHeight('',$this->table_lineheight);
19327
19328 // Top level table
19329 $this->_tableWidth($this->table[1][1]);
19330
19331 } // mPDF 5.3.36
19332
19333
19334 // mPDF 5.3.79
19335 // Now work through any nested tables setting child table[w'] = parent cell['w']
19336 // Now do nested tables _tableWidth
19337 for($lvl=2;$lvl<=$this->innermostTableLevel;$lvl++) {
19338 for ($nid=1; $nid<=$this->tbctr[$lvl]; $nid++) {
19339 // HERE set child table width = cell width
19340
19341 list($parentrow, $parentcol, $parentnid) = $this->table[$lvl][$nid]['nestedpos'];
19342
19343 // mPDF 5.3.79
19344 if ($this->cacheTables) {
19345 $c = $this->_uncacheCell($this->table[($lvl-1)][$parentnid]['cells'][$parentrow][$parentcol], $this->table[($lvl-1)][$parentnid]['cache'], null);
19346 }
19347 else
19348 $c =& $this->table[($lvl-1)][$parentnid]['cells'][$parentrow][$parentcol];
19349
19350 if (isset($c['colspan']) && $c['colspan']> 1) {
19351 $parentwidth = 0;
19352 for($cs=0;$cs<$c['colspan'] ; $cs++) {
19353 $parentwidth += $this->table[($lvl-1)][$parentnid]['wc'][$parentcol+$cs];
19354 }
19355 }
19356 else { $parentwidth = $this->table[($lvl-1)][$parentnid]['wc'][$parentcol]; }
19357
19358
19359 //$parentwidth -= ALLOW FOR PADDING ETC.in parent cell
19360 if (!$this->simpleTables){
19361 if ($this->packTableData) {
19362 list($bt,$br,$bb,$bl) = $this->_getBorderWidths($c['borderbin']);
19363 }
19364 else {
19365 $br = $c['border_details']['R']['w'];
19366 $bl = $c['border_details']['L']['w'];
19367 }
19368 if ($this->table[$lvl-1][$parentnid]['borders_separate']) {
19369 $parentwidth -= $br + $bl
19370 + $c['padding']['L']
19371 + $c['padding']['R']
19372 + $this->table[($lvl-1)][$parentnid]['border_spacing_H'];
19373 }
19374 else {
19375 $parentwidth -= $br/2 + $bl/2
19376 + $c['padding']['L']
19377 + $c['padding']['R'];
19378 }
19379 }
19380 else if ($this->simpleTables){
19381 if ($this->table[$lvl-1][$parentnid]['borders_separate']) {
19382 $parentwidth -= $this->table[($lvl-1)][$parentnid]['simple']['border_details']['L']['w']
19383 + $this->table[($lvl-1)][$parentnid]['simple']['border_details']['R']['w']
19384 + $c['padding']['L']
19385 + $c['padding']['R']
19386 + $this->table[($lvl-1)][$parentnid]['border_spacing_H'];
19387 }
19388 else {
19389 $parentwidth -= $this->table[($lvl-1)][$parentnid]['simple']['border_details']['L']['w']/2
19390 + $this->table[($lvl-1)][$parentnid]['simple']['border_details']['R']['w']/2
19391 + $c['padding']['L']
19392 + $c['padding']['R'];
19393 }
19394 }
19395 if (isset($this->table[$lvl][$nid]['wpercent']) && $this->table[$lvl][$nid]['wpercent'] && $lvl>1) {
19396 $this->table[$lvl][$nid]['w'] = $parentwidth;
19397 }
19398 else if ($parentwidth > $this->table[$lvl][$nid]['maw']) {
19399 $this->table[$lvl][$nid]['w'] = $this->table[$lvl][$nid]['maw'];
19400 }
19401 else {
19402 $this->table[$lvl][$nid]['w'] = $parentwidth;
19403 }
19404 unset($c); // mPDF 5.3.79
19405 $this->_tableWidth($this->table[$lvl][$nid]);
19406 }
19407 }
19408
19409 // Starting at $this->innermostTableLevel
19410 // Cascade back up nested tables: setting heights back up the tree
19411 for($lvl=$this->innermostTableLevel;$lvl>0;$lvl--) {
19412 for ($nid=1; $nid<=$this->tbctr[$lvl]; $nid++) {
19413 list($tableheight,$maxrowheight,$fullpage,$remainingpage, $maxfirstrowheight) = $this->_tableHeight($this->table[$lvl][$nid]); }
19414 }
19415 if ($this->progressBar) { $this->UpdateProgressBar(7,20,' '); } // *PROGRESS-BAR*
19416 // mPDF 5.3.36
19417 if ($this->table[1][1]['overflow']=='visible') {
19418 if ($maxrowheight > $fullpage) { die("mPDF Warning: A Table row is greater than available height. You cannot use CSS overflow:visible"); }
19419 if ($maxfirstrowheight > $remainingpage) { $this->AddPage($this->CurOrientation); }
19420 $r = 0; $c = 0; $p = 0; $y = 0;
19421 while (!$finished) {
19422 list($finished,$r,$c,$p,$y,$y0) = $this->_tableWrite($this->table[1][1],true,$r,$c,$p,$y);
19423 if (!$finished) {
19424 $this->AddPage($this->CurOrientation); // mPDF 5.3.43
19425 // If printed something on first spread, set same y
19426 if ($r==0 && $y0 > -1) { $this->y = $y0; }
19427 }
19428 }
19429 }
19430 else {
19431 $recalculate = 1;
19432 $forcerecalc = false;
19433 // RESIZING ALGORITHM
19434 if ($maxrowheight > $fullpage) {
19435 $recalculate = $this->tbsqrt($maxrowheight / $fullpage, 1);
19436 $forcerecalc = true;
19437 }
19438 else if ($this->table_rotate) { // NB $remainingpage == $fullpage == the width of the page
19439 if ($tableheight > $remainingpage) {
19440 // If can fit on remainder of page whilst respecting autsize value..
19441 if (($this->shrin_k * $this->tbsqrt($tableheight / $remainingpage, 1)) <= $this->shrink_this_table_to_fit) {
19442 $recalculate = $this->tbsqrt($tableheight / $remainingpage, 1);
19443 }
19444 else if (!$added_page) {
19445 if ($this->y != $this->tMargin) { // mPDF 5.3.69
19446 $this->AddPage($this->CurOrientation);
19447 $this->kwt_moved = true;
19448 }
19449 $added_page = true;
19450 $this->tbrot_maxw = $this->h - ($this->y + $this->bMargin + 5) - $this->kwt_height;
19451 // 0.001 to force it to recalculate
19452 $recalculate = (1 / $this->shrin_k) + 0.001; // undo any shrink
19453 }
19454 }
19455 else { $recalculate = 1; }
19456 }
19457 else if ($this->table_keep_together || ($this->table[1][1]['nr']==1 && !$this->writingHTMLfooter)) {
19458 if ($tableheight > $fullpage) {
19459 if (($this->shrin_k * $this->tbsqrt($tableheight / $fullpage, 1)) <= $this->shrink_this_table_to_fit) {
19460 $recalculate = $this->tbsqrt($tableheight / $fullpage, 1);
19461 }
19462 else if ($this->tableMinSizePriority) {
19463 $this->table_keep_together = false;
19464 $recalculate = 1.001;
19465 }
19466 else {
19467 if ($this->y != $this->tMargin) { // mPDF 5.1
19468 $this->AddPage($this->CurOrientation);
19469 $this->kwt_moved = true;
19470 }
19471 $added_page = true;
19472 $this->tbrot_maxw = $this->h - ($this->y + $this->bMargin + 5) - $this->kwt_height;
19473 $recalculate = $this->tbsqrt($tableheight / $fullpage, 1);
19474 }
19475 }
19476 else if ($tableheight > $remainingpage) {
19477 // If can fit on remainder of page whilst respecting autsize value..
19478 if (($this->shrin_k * $this->tbsqrt($tableheight / $remainingpage, 1)) <= $this->shrink_this_table_to_fit) {
19479 $recalculate = $this->tbsqrt($tableheight / $remainingpage, 1);
19480 }
19481 else {
19482 if ($this->y != $this->tMargin) {
19483 $this->AddPage($this->CurOrientation);
19484 $this->kwt_moved = true;
19485 }
19486 $added_page = true;
19487 $this->tbrot_maxw = $this->h - ($this->y + $this->bMargin + 5) - $this->kwt_height;
19488 $recalculate = 1.001;
19489 }
19490 }
19491 else { $recalculate = 1; }
19492 }
19493 else { $recalculate = 1; }
19494
19495 if ($recalculate > $this->shrink_this_table_to_fit && !$forcerecalc) { $recalculate = $this->shrink_this_table_to_fit; }
19496
19497 $iteration = 1;
19498
19499 // RECALCULATE
19500 while($recalculate <> 1) {
19501 $this->shrin_k1 = $recalculate ;
19502 $this->shrin_k *= $recalculate ;
19503 $this->default_font_size /= ($this->shrin_k1) ;
19504 $this->SetFontSize($this->default_font_size, false );
19505 $this->SetLineHeight('',$this->table_lineheight);
19506 $this->table = $save_table;
19507 // mPDF 5.3.79
19508 if ($this->cacheTables) { $this->_restoreCacheFiles(); }
19509 if ($this->shrin_k <> 1) { $this->shrinkTable($this->table[1][1],$this->shrin_k); }
19510 $this->_tableColumnWidth($this->table[1][1],false); // repeat
19511
19512 // Starting at $this->innermostTableLevel
19513 // Shrink table values - and redo columnWidth
19514 for($lvl=2;$lvl<=$this->innermostTableLevel;$lvl++) {
19515 for ($nid=1; $nid<=$this->tbctr[$lvl]; $nid++) {
19516 if ($this->shrin_k <> 1) { $this->shrinkTable($this->table[$lvl][$nid],$this->shrin_k); }
19517 $this->_tableColumnWidth($this->table[$lvl][$nid],false);
19518 }
19519 }
19520 // Set table cell widths for top level table
19521
19522 // Top level table
19523 $this->_tableWidth($this->table[1][1]);
19524
19525 // mPDF 5.3.79
19526 // Now work through any nested tables setting child table[w'] = parent cell['w']
19527 // Now do nested tables _tableWidth
19528 for($lvl=2;$lvl<=$this->innermostTableLevel;$lvl++) {
19529 for ($nid=1; $nid<=$this->tbctr[$lvl]; $nid++) {
19530 // HERE set child table width = cell width
19531
19532 list($parentrow, $parentcol, $parentnid) = $this->table[$lvl][$nid]['nestedpos'];
19533 // mPDF 5.3.79
19534 if ($this->cacheTables) {
19535 $c = $this->_uncacheCell($this->table[($lvl-1)][$parentnid]['cells'][$parentrow][$parentcol], $this->table[($lvl-1)][$parentnid]['cache'], null);
19536 }
19537 else
19538 $c =& $this->table[($lvl-1)][$parentnid]['cells'][$parentrow][$parentcol];
19539
19540 if (isset($c['colspan']) && $c['colspan']> 1) {
19541 $parentwidth = 0;
19542 for($cs=0;$cs<$c['colspan'] ; $cs++) {
19543 $parentwidth += $this->table[($lvl-1)][$parentnid]['wc'][$parentcol+$cs];
19544 }
19545 }
19546 else { $parentwidth = $this->table[($lvl-1)][$parentnid]['wc'][$parentcol]; }
19547
19548 //$parentwidth -= ALLOW FOR PADDING ETC.in parent cell
19549 if (!$this->simpleTables){
19550 if ($this->packTableData) {
19551 list($bt,$br,$bb,$bl) = $this->_getBorderWidths($c['borderbin']);
19552 }
19553 else {
19554 $br = $c['border_details']['R']['w'];
19555 $bl = $c['border_details']['L']['w'];
19556 }
19557 if ($this->table[$lvl-1][$parentnid]['borders_separate']) {
19558 $parentwidth -= $br + $bl
19559 + $c['padding']['L']
19560 + $c['padding']['R']
19561 + $this->table[($lvl-1)][$parentnid]['border_spacing_H'];
19562 }
19563 else {
19564 $parentwidth -= $br/2 + $bl/2
19565 + $c['padding']['L']
19566 + $c['padding']['R'];
19567 }
19568 }
19569 else if ($this->simpleTables){
19570 if ($this->table[$lvl-1][$parentnid]['borders_separate']) {
19571 $parentwidth -= $this->table[($lvl-1)][$parentnid]['simple']['border_details']['L']['w']
19572 + $this->table[($lvl-1)][$parentnid]['simple']['border_details']['R']['w']
19573 + $c['padding']['L']
19574 + $c['padding']['R']
19575 + $this->table[($lvl-1)][$parentnid]['border_spacing_H'];
19576 }
19577 else {
19578 $parentwidth -= ($this->table[($lvl-1)][$parentnid]['simple']['border_details']['L']['w']
19579 + $this->table[($lvl-1)][$parentnid]['simple']['border_details']['R']['w']) /2
19580 + $c['padding']['L']
19581 + $c['padding']['R'];
19582 }
19583 }
19584 if (isset($this->table[$lvl][$nid]['wpercent']) && $this->table[$lvl][$nid]['wpercent'] && $lvl>1) {
19585 $this->table[$lvl][$nid]['w'] = $parentwidth;
19586 }
19587 else if ($parentwidth > $this->table[$lvl][$nid]['maw']) {
19588 $this->table[$lvl][$nid]['w'] = $this->table[$lvl][$nid]['maw'] ;
19589 }
19590 else {
19591 $this->table[$lvl][$nid]['w'] = $parentwidth;
19592 }
19593 unset($c); // mPDF 5.3.79
19594 $this->_tableWidth($this->table[$lvl][$nid]);
19595 }
19596 }
19597
19598 // Starting at $this->innermostTableLevel
19599 // Cascade back up nested tables: setting heights back up the tree
19600 for($lvl=$this->innermostTableLevel;$lvl>0;$lvl--) {
19601 for ($nid=1; $nid<=$this->tbctr[$lvl]; $nid++) {
19602 list($tableheight,$maxrowheight,$fullpage,$remainingpage, $maxfirstrowheight) = $this->_tableHeight($this->table[$lvl][$nid]); }
19603 }
19604
19605 // RESIZING ALGORITHM
19606
19607 if ($maxrowheight > $fullpage) { $recalculate = $this->tbsqrt($maxrowheight / $fullpage, $iteration); $iteration++; }
19608 else if ($this->table_rotate && $tableheight > $remainingpage && !$added_page) {
19609 // If can fit on remainder of page whilst respecting autosize value..
19610 if (($this->shrin_k * $this->tbsqrt($tableheight / $remainingpage, $iteration)) <= $this->shrink_this_table_to_fit) {
19611 $recalculate = $this->tbsqrt($tableheight / $remainingpage, $iteration); $iteration++;
19612 }
19613 else {
19614 if (!$added_page) {
19615 $this->AddPage($this->CurOrientation);
19616 $added_page = true;
19617 $this->kwt_moved = true;
19618 $this->tbrot_maxw = $this->h - ($this->y + $this->bMargin + 5) - $this->kwt_height;
19619 }
19620 // 0.001 to force it to recalculate
19621 $recalculate = (1 / $this->shrin_k) + 0.001; // undo any shrink
19622 }
19623 }
19624 else if ($this->table_keep_together || ($this->table[1][1]['nr']==1 && !$this->writingHTMLfooter)) {
19625 if ($tableheight > $fullpage) {
19626 if (($this->shrin_k * $this->tbsqrt($tableheight / $fullpage, $iteration)) <= $this->shrink_this_table_to_fit) {
19627 $recalculate = $this->tbsqrt($tableheight / $fullpage, $iteration); $iteration++;
19628 }
19629 else if ($this->tableMinSizePriority) {
19630 $this->table_keep_together = false;
19631 $recalculate = (1 / $this->shrin_k) + 0.001;
19632 }
19633 else {
19634 if (!$added_page && $this->y != $this->tMargin) {
19635 $this->AddPage($this->CurOrientation);
19636 $added_page = true;
19637 $this->kwt_moved = true;
19638 $this->tbrot_maxw = $this->h - ($this->y + $this->bMargin + 5) - $this->kwt_height;
19639 }
19640 $recalculate = $this->tbsqrt($tableheight / $fullpage, $iteration); $iteration++;
19641 }
19642 }
19643 else if ($tableheight > $remainingpage) {
19644 // If can fit on remainder of page whilst respecting autosize value..
19645 if (($this->shrin_k * $this->tbsqrt($tableheight / $remainingpage, $iteration)) <= $this->shrink_this_table_to_fit) {
19646 $recalculate = $this->tbsqrt($tableheight / $remainingpage, $iteration); $iteration++;
19647 }
19648 else {
19649 if (!$added_page) {
19650 $this->AddPage($this->CurOrientation);
19651 $added_page = true;
19652 $this->kwt_moved = true;
19653 $this->tbrot_maxw = $this->h - ($this->y + $this->bMargin + 5) - $this->kwt_height;
19654 }
19655
19656 //$recalculate = $this->tbsqrt($tableheight / $fullpage, $iteration); $iteration++;
19657 $recalculate = (1 / $this->shrin_k) + 0.001; // undo any shrink
19658 }
19659 }
19660 else { $recalculate = 1; }
19661 }
19662 else { $recalculate = 1; }
19663 }
19664
19665
19666 if ($maxfirstrowheight > $remainingpage && !$added_page && !$this->table_rotate && !$this->ColActive && !$this->table_keep_together && !$this->writingHTMLheader && !$this->writingHTMLfooter) {
19667 $this->AddPage($this->CurOrientation);
19668 $this->kwt_moved = true;
19669 }
19670
19671 // keep-with-table: if page has advanced, print out buffer now, else done in fn. _Tablewrite()
19672 if ($this->kwt_saved && $this->kwt_moved) {
19673 $this->printkwtbuffer();
19674 $this->kwt_moved = false;
19675 $this->kwt_saved = false;
19676 }
19677
19678 if ($this->progressBar) { $this->UpdateProgressBar(7,30,' '); } // *PROGRESS-BAR*
19679 // Recursively writes all tables starting at top level
19680 $this->_tableWrite($this->table[1][1]);
19681
19682 if ($this->table_rotate && $this->tablebuffer) {
19683 $this->PageBreakTrigger=$this->h-$this->bMargin;
19684 $save_tr = $this->table_rotate;
19685 $save_y = $this->y;
19686 $this->table_rotate = 0;
19687 $this->y = $this->tbrot_y0;
19688 $h = $this->tbrot_w;
19689 $this->DivLn($h,$this->blklvl,true);
19690
19691 $this->table_rotate = $save_tr;
19692 $this->y = $save_y;
19693
19694 $this->printtablebuffer();
19695 }
19696 $this->table_rotate = 0;
19697 } // mPDF 5.3.36
19698
19699
19700 $this->x = $this->lMargin + $this->blk[$this->blklvl]['outer_left_margin'];
19701
19702 // mPDF 5.3.91
19703 $this->maxPosR = max($this->maxPosR , ($this->x + $this->table[1][1]['w']));
19704
19705 $this->blockjustfinished=true;
19706 $this->lastblockbottommargin = $this->table[1][1]['margin']['B'];
19707 //Reset values
19708
19709 // mPDF 5.3.55
19710 if (isset($this->table[1][1]['page_break_after'])) { $page_break_after = $this->table[1][1]['page_break_after']; }
19711 else { $page_break_after = ''; }
19712
19713 // Keep-with-table
19714 $this->kwt = false;
19715 $this->kwt_y0 = 0;
19716 $this->kwt_x0 = 0;
19717 $this->kwt_height = 0;
19718 $this->kwt_buffer = array();
19719 $this->kwt_Links = array();
19720 $this->kwt_Annots = array();
19721 $this->kwt_moved = false;
19722 $this->kwt_saved = false;
19723
19724 $this->kwt_Reference = array();
19725 $this->kwt_BMoutlines = array();
19726 $this->kwt_toc = array();
19727
19728 $this->shrin_k = 1;
19729 $this->shrink_this_table_to_fit = 0;
19730
19731 unset($this->table);
19732 $this->table=array(); //array
19733 $this->tableLevel=0;
19734 $this->tbctr=array();
19735 $this->innermostTableLevel=0;
19736 $this->tbCSSlvl = 0;
19737 $this->tablecascadeCSS = array();
19738
19739 unset($this->cell);
19740 $this->cell=array(); //array
19741
19742 $this->col=-1; //int
19743 $this->row=-1; //int
19744 $this->Reset();
19745
19746 $this->cellPaddingL = 0;
19747 $this->cellPaddingT = 0;
19748 $this->cellPaddingR = 0;
19749 $this->cellPaddingB = 0;
19750 $this->cMarginL = 0;
19751 $this->cMarginT = 0;
19752 $this->cMarginR = 0;
19753 $this->cMarginB = 0;
19754 $this->default_font_size = $this->original_default_font_size;
19755 $this->default_font = $this->original_default_font;
19756 $this->SetFontSize($this->default_font_size, false);
19757 $this->SetFont($this->default_font,'',0,false);
19758 $this->SetLineHeight();
19759 if (isset($this->blk[$this->blklvl]['InlineProperties'])) { $this->restoreInlineProperties($this->blk[$this->blklvl]['InlineProperties']);}
19760 if ($this->progressBar) { $this->UpdateProgressBar(7,100,' '); } // *PROGRESS-BAR*
19761
19762 // mPDF 5.3.55
19763 if ($page_break_after) {
19764 $save_blklvl = $this->blklvl;
19765 $save_blk = $this->blk;
19766 $save_silp = $this->saveInlineProperties();
19767 $save_spanlvl = $this->spanlvl;
19768 $save_ilp = $this->InlineProperties;
19769 if ($this->blklvl>1) {
19770 // Close any open block tags
19771 for ($b= $this->blklvl;$b>0;$b--) { $this->CloseTag($this->blk[$b]['tag']); }
19772 // Output any text left in buffer
19773 if (count($this->textbuffer)) { $this->printbuffer($this->textbuffer); $this->textbuffer=array(); }
19774 }
19775 /*-- COLUMNS --*/
19776 $save_cols = false;
19777 if ($this->ColActive) {
19778 $save_cols = true;
19779 $save_nbcol = $this->NbCol; // other values of gap and vAlign will not change by setting Columns off
19780 $this->SetColumns(0);
19781 }
19782 /*-- END COLUMNS --*/
19783 if ($page_break_after == 'RIGHT') { $this->AddPage($this->CurOrientation,'NEXT-ODD','','','','','', '','', '','','','','','',0,0,0,0,$pagesel); }
19784 else if ($page_break_after == 'LEFT') { $this->AddPage($this->CurOrientation,'NEXT-EVEN','','','','','', '','', '','','','','','',0,0,0,0,$pagesel); }
19785 else { $this->AddPage($this->CurOrientation,'','','','','','', '','', '','','','','','',0,0,0,0,$pagesel); }
19786 if (!$this->restoreBlockPagebreaks) {
19787 $this->blklvl = 0;
19788 $this->lastblocklevelchange = 0;
19789 $this->blk = array();
19790 $this->initialiseBlock($this->blk[0]);
19791 $this->blk[0]['width'] =& $this->pgwidth;
19792 $this->blk[0]['inner_width'] =& $this->pgwidth;
19793 $this->blk[0]['blockContext'] = $this->blockContext;
19794 $properties = $this->MergeCSS('BLOCK','BODY','');
19795 $this->setCSS($properties,'','BODY');
19796 // mPDF 5.3.70
19797 }
19798
19799 /*-- COLUMNS --*/
19800 if ($save_cols) {
19801 // Restore columns
19802 $this->SetColumns($save_nbcol,$this->colvAlign,$this->ColGap);
19803 }
19804 /*-- END COLUMNS --*/
19805 if ($this->restoreBlockPagebreaks) {
19806 $this->blk = $save_blk;
19807 // Re-open block tags
19808 $t = $this->blk[0]['tag'];
19809 $a = $this->blk[0]['attr'];
19810 $this->blklvl = 0;
19811 for ($b=0; $b<=$save_blklvl;$b++) {
19812 $tc = $t;
19813 $ac = $a;
19814 $t = $this->blk[$b+1]['tag'];
19815 $a = $this->blk[$b+1]['attr'];
19816 unset($this->blk[$b+1]);
19817 $this->OpenTag($tc,$ac);
19818 }
19819 $this->spanlvl = $save_spanlvl;
19820 $this->InlineProperties = $save_ilp;
19821 $this->restoreInlineProperties($save_silp);
19822 }
19823 }
19824
19825 }
19826 /*-- END TABLES --*/
19827
19828 /*-- LISTS --*/
19829 // *********** LISTS ********************
19830
19831 if($tag=='LI') {
19832 $this->lastoptionaltag = '';
19833 unset($this->listcascadeCSS[$this->listCSSlvl]);
19834 $this->listCSSlvl--;
19835 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]]); }
19836 }
19837
19838
19839 if(($tag=='UL') or ($tag=='OL')) {
19840 $this->ignorefollowingspaces = true; //Eliminate exceeding left-side spaces
19841 unset($this->listcascadeCSS[$this->listCSSlvl]);
19842 $this->listCSSlvl--;
19843
19844 $this->lastoptionaltag = '';
19845 /*-- TABLES --*/
19846 // A simple list for inside a table
19847 if($this->tableLevel) {
19848 $this->listlist[$this->listlvl]['MAXNUM'] = $this->listnum; //save previous lvl's maxnum
19849 unset($this->listlist[$this->listlvl]);
19850 $this->listlvl--;
19851 if (isset($this->listlist[$this->listlvl]['MAXNUM'])) { $this->listnum = $this->listlist[$this->listlvl]['MAXNUM']; } // restore previous levels
19852 if ($this->listlvl == 0) { $this->listjustfinished = true; }
19853 return;
19854 }
19855 /*-- END TABLES --*/
19856
19857 if ($this->listlvl > 1) { // returning one level
19858 $this->listjustfinished=true;
19859 if (!empty($this->textbuffer)) {
19860 $this->listitem[] = array($this->listlvl,$this->listnum,$this->textbuffer,$this->listoccur[$this->listlvl],$this->listitemtype);
19861 }
19862 else {
19863 $this->listnum--;
19864 }
19865
19866 $this->textbuffer = array();
19867 $occur = $this->listoccur[$this->listlvl];
19868 $this->listlist[$this->listlvl][$occur]['MAXNUM'] = $this->listnum; //save previous lvl's maxnum
19869 $this->listlvl--;
19870 $occur = $this->listoccur[$this->listlvl];
19871 $this->listnum = $this->listlist[$this->listlvl][$occur]['MAXNUM']; // recover previous level's number
19872 $this->listtype = $this->listlist[$this->listlvl][$occur]['TYPE']; // recover previous level's type
19873 if ($this->InlineProperties['LIST'][$this->listlvl][$occur]) { $this->restoreInlineProperties($this->InlineProperties['LIST'][$this->listlvl][$occur]); }
19874
19875 }
19876 else { // We are closing the last OL/UL tag
19877 if (!empty($this->textbuffer)) {
19878 $this->listitem[] = array($this->listlvl,$this->listnum,$this->textbuffer,$this->listoccur[$this->listlvl],$this->listitemtype);
19879 }
19880 else {
19881 $this->listnum--;
19882 }
19883
19884 $occur = $this->listoccur[$this->listlvl];
19885 $this->listlist[$this->listlvl][$occur]['MAXNUM'] = $this->listnum;
19886 $this->textbuffer = array();
19887 $this->listlvl--;
19888
19889 $this->printlistbuffer();
19890 unset($this->InlineProperties['LIST']);
19891 // SPACING AFTER LIST (Top level only)
19892 $this->Ln(0);
19893 if ($this->list_margin_bottom) {
19894 $this->DivLn($this->list_margin_bottom,$this->blklvl,true,1); // collapsible
19895 }
19896 if (isset($this->blk[$this->blklvl]['InlineProperties'])) { $this->restoreInlineProperties($this->blk[$this->blklvl]['InlineProperties']);}
19897 $this->listjustfinished = true;
19898 $this->listCSSlvl = 0;
19899 $this->listcascadeCSS = array();
19900 $this->blockjustfinished=true;
19901 $this->lastblockbottommargin = $this->list_margin_bottom;
19902 }
19903 }
19904 /*-- END LISTS --*/
19905
19906
19907 }
19908
19909
19910 /*-- TABLES --*/
19911 // This function determines the shrink factor when resizing tables
19912 // val is the table_height / page_height_available
19913 // returns a scaling factor used as $shrin_k to resize the table
19914 // Overcompensating will be quicker but may unnecessarily shrink table too much
19915 // Undercompensating means it will reiterate more times (taking more processing time)
19916 function tbsqrt($val, $iteration=3) {
19917 $k = 4; // Alters number of iterations until it returns $val itself - Must be > 2
19918 // Probably best guess and most accurate
19919 if ($iteration==1) return sqrt($val);
19920 // Faster than using sqrt (because it won't undercompensate), and gives reasonable results
19921 //return 1+(($val-1)/2);
19922 $x = 2-(($iteration-2)/($k-2));
19923 if ($x == 0) { $ret = $val+0.00001; }
19924 else if ($x < 0) { $ret = 1 + ( pow(2, ($iteration-2-$k))/1000 ); }
19925 else { $ret = 1+(($val-1)/$x); }
19926 return $ret;
19927 }
19928 /*-- END TABLES --*/
19929
19930
19931 /*-- LISTS --*/
19932 function printlistbuffer() {
19933 //Save x coordinate
19934 $x = $this->lMargin + $this->blk[$this->blklvl]['outer_left_margin'];
19935 $this->cMarginL = 0;
19936 $this->cMarginR = 0;
19937 $currIndentLvl = -1;
19938 $lastIndent = array();
19939 $bak_page = $this->page;
19940 $indent = 0;
19941 foreach($this->listitem as $item)
19942 {
19943 // COLS
19944 $oldcolumn = $this->CurrCol;
19945
19946 $this->bulletarray = array();
19947 //Get list's buffered data
19948 $this->listlvl = $lvl = $item[0];
19949 $num = $item[1];
19950 $this->textbuffer = $item[2];
19951 $occur = $item[3];
19952 if ($item[4]) { $type = $item[4]; } // listitemtype
19953 else { $type = $this->listlist[$lvl][$occur]['TYPE']; }
19954 $maxnum = $this->listlist[$lvl][$occur]['MAXNUM'];
19955 $this->restoreInlineProperties($this->InlineProperties['LIST'][$lvl][$occur]);
19956 $this->SetFont($this->FontFamily,$this->FontStyle,$this->FontSizePt,true,true); // force to write
19957 $clh = $this->FontSize;
19958
19959 $this->SetLineHeight($this->FontSizePt,$this->list_lineheight[$lvl][$occur]);
19960 $this->listOcc = $occur;
19961 $this->listnum = $num;
19962
19963 if (isset($this->list_align[$this->listlvl][$occur])) { $this->divalign = $this->list_align[$this->listlvl][$occur]; }
19964 else {
19965 if (isset($this->blk[$this->blklvl]['direction']) && $this->blk[$this->blklvl]['direction']=='rtl') { $this->divalign = 'R'; }
19966 else { $this->divalign = 'L'; }
19967 }
19968
19969 // Set the bullet fontsize
19970 $bullfs = $this->InlineProperties['LISTITEM'][$lvl][$occur][$num]['size'];
19971
19972 $space_width = $this->GetCharWidth(' ',false) * 1.5; // mPDF 5.3.04
19973
19974 //Set default width & height values
19975 $this->divwidth = $this->blk[$this->blklvl]['inner_width'];
19976 $this->divheight = $this->lineheight;
19977 $typefont = $this->FontFamily;
19978 if (preg_match('/U\+([a-fA-F0-9]+)/i',$type,$m)) {
19979 if ($this->_charDefined($this->CurrentFont['cw'],hexdec($m[1]))) { $list_item_marker = codeHex2utf($m[1]); }
19980 else { $list_item_marker = '-'; }
19981 $blt_width = $this->GetStringWidth($list_item_marker);
19982 $typefont = '';
19983 if (preg_match('/rgb\(.*?\)/',$type,$m)) {
19984 $list_item_color = $this->ConvertColor($m[0]);
19985 }
19986 }
19987 else {
19988 $list_item_color = false;
19989
19990 switch($type) //Format type
19991 {
19992 case '1':
19993 if ($this->listDir == 'rtl') { $list_item_marker = $this->list_number_suffix . $num; }
19994 else { $list_item_marker = $num . $this->list_number_suffix; }
19995 $blt_width = $this->GetStringWidth(str_repeat('5',strlen($maxnum)).$this->list_number_suffix);
19996 break;
19997 case 'none':
19998 $list_item_marker = '';
19999 $blt_width = 0;
20000 break;
20001 case 'A':
20002 $anum = $this->dec2alpha($num,true);
20003 $maxnum = $this->dec2alpha($maxnum,true);
20004 if ($this->listDir == 'rtl') { $list_item_marker = $this->list_number_suffix . $anum; }
20005 else { $list_item_marker = $anum . $this->list_number_suffix; }
20006 $blt_width = $this->GetStringWidth(str_repeat('W',strlen($maxnum)).$this->list_number_suffix);
20007 break;
20008 case 'a':
20009 $anum = $this->dec2alpha($num,false);
20010 $maxnum = $this->dec2alpha($maxnum,false);
20011 if ($this->listDir == 'rtl') { $list_item_marker = $this->list_number_suffix . $anum; }
20012 else { $list_item_marker = $anum . $this->list_number_suffix; }
20013 $blt_width = $this->GetStringWidth(str_repeat('m',strlen($maxnum)).$this->list_number_suffix);
20014 break;
20015 case 'I':
20016 $anum = $this->dec2roman($num,true);
20017 if ($this->listDir == 'rtl') { $list_item_marker = $this->list_number_suffix . $anum; }
20018 else { $list_item_marker = $anum . $this->list_number_suffix; }
20019
20020 if ($maxnum>87) { $bbit = 87; }
20021 else if ($maxnum>86) { $bbit = 86; }
20022 else if ($maxnum>37) { $bbit = 38; }
20023 else if ($maxnum>36) { $bbit = 37; }
20024 else if ($maxnum>27) { $bbit = 28; }
20025 else if ($maxnum>26) { $bbit = 27; }
20026 else if ($maxnum>17) { $bbit = 18; }
20027 else if ($maxnum>16) { $bbit = 17; }
20028 else if ($maxnum>7) { $bbit = 8; }
20029 else if ($maxnum>6) { $bbit = 7; }
20030 else if ($maxnum>3) { $bbit = 4; }
20031 else { $bbit = $maxnum; }
20032 $maxlnum = $this->dec2roman($bbit,true);
20033 $blt_width = $this->GetStringWidth($maxlnum.$this->list_number_suffix);
20034 break;
20035 case 'i':
20036 $anum = $this->dec2roman($num,false);
20037 if ($this->listDir == 'rtl') { $list_item_marker = $this->list_number_suffix . $anum; }
20038 else { $list_item_marker = $anum . $this->list_number_suffix; }
20039
20040 if ($maxnum>87) { $bbit = 87; }
20041 else if ($maxnum>86) { $bbit = 86; }
20042 else if ($maxnum>37) { $bbit = 38; }
20043 else if ($maxnum>36) { $bbit = 37; }
20044 else if ($maxnum>27) { $bbit = 28; }
20045 else if ($maxnum>26) { $bbit = 27; }
20046 else if ($maxnum>17) { $bbit = 18; }
20047 else if ($maxnum>16) { $bbit = 17; }
20048 else if ($maxnum>7) { $bbit = 8; }
20049 else if ($maxnum>6) { $bbit = 7; }
20050 else if ($maxnum>3) { $bbit = 4; }
20051 else { $bbit = $maxnum; }
20052 $maxlnum = $this->dec2roman($bbit,false);
20053
20054 $blt_width = $this->GetStringWidth($maxlnum.$this->list_number_suffix);
20055 break;
20056 case 'disc':
20057 if ($this->PDFA || $this->PDFX) {
20058 if ($this->_charDefined($this->CurrentFont['cw'],8226)) { $list_item_marker = "\xe2\x80\xa2"; } // &#8226;
20059 else { $list_item_marker = '-'; }
20060 $blt_width = $this->GetCharWidth($list_item_marker); // mPDF 5.3.04
20061 break;
20062 }
20063 $list_item_marker = chr(108); // bullet disc in Zapfdingbats 'l'
20064 $typefont = 'czapfdingbats';
20065 $blt_width = (0.791 * $this->FontSize/2.5);
20066 break;
20067 case 'circle':
20068 if ($this->PDFA || $this->PDFX) {
20069 if ($this->_charDefined($this->CurrentFont['cw'],9900)) { $list_item_marker = "\xe2\x9a\xac"; } // &#9900;
20070 else { $list_item_marker = '-'; }
20071 $blt_width = $this->GetCharWidth($list_item_marker); // mPDF 5.3.04
20072 break;
20073 }
20074 $list_item_marker = chr(109); // circle in Zapfdingbats 'm'
20075 $typefont = 'czapfdingbats';
20076 $blt_width = (0.873 * $this->FontSize/2.5);
20077 break;
20078 case 'square':
20079 if ($this->PDFA || $this->PDFX) {
20080 if ($this->_charDefined($this->CurrentFont['cw'],9642)) { $list_item_marker = "\xe2\x96\xaa"; } // &#9642;
20081 else { $list_item_marker = '-'; }
20082 $blt_width = $this->GetCharWidth($list_item_marker); // mPDF 5.3.04
20083 break;
20084 }
20085 $list_item_marker = chr(110); //black square in Zapfdingbats font 'n'
20086 $typefont = 'czapfdingbats';
20087 $blt_width = (0.761 * $this->FontSize/2.5);
20088 break;
20089
20090 /* CSS3 list-styles numeric + I added tamil
20091 arabic-indic | bengali | cambodian | devanagari | gujarati | gurmukhi | kannada | khmer | lao | malayalam | mongolian | myanmar | oriya | persian | telugu | tibetan | thai | urdu
20092 */
20093 case 'arabic-indic':
20094 $cp = 0x0660;
20095 $rnum = $this->dec2other($num, $cp);
20096 $list_item_marker = $this->list_number_suffix . $rnum; // RTL
20097 $blt_width = $this->GetStringWidth(str_repeat($this->dec2other(3, $cp),strlen($maxnum)).$this->list_number_suffix);
20098 break;
20099 case 'persian':
20100 case 'urdu':
20101 $cp = 0x06F0;
20102 $rnum = $this->dec2other($num, $cp);
20103 $list_item_marker = $this->list_number_suffix . $rnum; // RTL
20104 $blt_width = $this->GetStringWidth(str_repeat($this->dec2other(3, $cp),strlen($maxnum)).$this->list_number_suffix);
20105 break;
20106 case 'bengali':
20107 $cp = 0x09E6;
20108 $rnum = $this->dec2other($num, $cp);
20109 $list_item_marker = $rnum . $this->list_number_suffix;
20110 $blt_width = $this->GetStringWidth(str_repeat($this->dec2other(3, $cp),strlen($maxnum)).$this->list_number_suffix);
20111 break;
20112 case 'devanagari':
20113 $cp = 0x0966;
20114 $rnum = $this->dec2other($num, $cp);
20115 $list_item_marker = $rnum . $this->list_number_suffix;
20116 $blt_width = $this->GetStringWidth(str_repeat($this->dec2other(3, $cp),strlen($maxnum)).$this->list_number_suffix);
20117 break;
20118 case 'gujarati':
20119 $cp = 0x0AE6;
20120 $rnum = $this->dec2other($num, $cp);
20121 $list_item_marker = $rnum . $this->list_number_suffix;
20122 $blt_width = $this->GetStringWidth(str_repeat($this->dec2other(3, $cp),strlen($maxnum)).$this->list_number_suffix);
20123 break;
20124 case 'gurmukhi':
20125 $cp = 0x0A66;
20126 $rnum = $this->dec2other($num, $cp);
20127 $list_item_marker = $rnum . $this->list_number_suffix;
20128 $blt_width = $this->GetStringWidth(str_repeat($this->dec2other(3, $cp),strlen($maxnum)).$this->list_number_suffix);
20129 break;
20130 case 'kannada':
20131 $cp = 0x0CE6;
20132 $rnum = $this->dec2other($num, $cp);
20133 $list_item_marker = $rnum . $this->list_number_suffix;
20134 $blt_width = $this->GetStringWidth(str_repeat($this->dec2other(3, $cp),strlen($maxnum)).$this->list_number_suffix);
20135 break;
20136 case 'malayalam':
20137 $cp = 0x0D66;
20138 $rnum = $this->dec2other($num, $cp);
20139 $list_item_marker = $rnum . $this->list_number_suffix;
20140 $blt_width = $this->GetStringWidth(str_repeat($this->dec2other(6, $cp),strlen($maxnum)).$this->list_number_suffix);
20141 break;
20142 case 'oriya':
20143 $cp = 0x0B66;
20144 $rnum = $this->dec2other($num, $cp);
20145 $list_item_marker = $rnum . $this->list_number_suffix;
20146 $blt_width = $this->GetStringWidth(str_repeat($this->dec2other(3, $cp),strlen($maxnum)).$this->list_number_suffix);
20147 break;
20148 case 'telugu':
20149 $cp = 0x0C66;
20150 $rnum = $this->dec2other($num, $cp);
20151 $list_item_marker = $rnum . $this->list_number_suffix;
20152 $blt_width = $this->GetStringWidth(str_repeat($this->dec2other(3, $cp),strlen($maxnum)).$this->list_number_suffix);
20153 break;
20154 case 'tamil':
20155 $cp = 0x0BE6;
20156 $rnum = $this->dec2other($num, $cp);
20157 $list_item_marker = $rnum . $this->list_number_suffix;
20158 $blt_width = $this->GetStringWidth(str_repeat($this->dec2other(9, $cp),strlen($maxnum)).$this->list_number_suffix);
20159 break;
20160 case 'thai':
20161 $cp = 0x0E50;
20162 $rnum = $this->dec2other($num, $cp);
20163 $list_item_marker = $rnum . $this->list_number_suffix;
20164 $blt_width = $this->GetStringWidth(str_repeat($this->dec2other(5, $cp),strlen($maxnum)).$this->list_number_suffix);
20165 break;
20166 default:
20167 if ($this->listDir == 'rtl') { $list_item_marker = $this->list_number_suffix . $num; }
20168 else { $list_item_marker = $num . $this->list_number_suffix; }
20169 $blt_width = $this->GetStringWidth(str_repeat('5',strlen($maxnum)).$this->list_number_suffix);
20170 break;
20171 }
20172 }
20173
20174 if (isset($item[5]) && $item[5]) { $list_item_marker = ''; } // mPDF 5.3.11
20175
20176 if ($currIndentLvl < $lvl) {
20177 if ($lvl > 1 || $this->list_indent_first_level) {
20178 $indent += $this->list_indent[$lvl][$occur];
20179 $lastIndent[$lvl] = $this->list_indent[$lvl][$occur];
20180 }
20181 }
20182 else if ($currIndentLvl > $lvl) {
20183 while ($currIndentLvl > $lvl) {
20184 $indent -= $lastIndent[$currIndentLvl];
20185 $currIndentLvl--;
20186 }
20187 }
20188 $currIndentLvl = $lvl;
20189
20190
20191 /*-- RTL --*/
20192
20193 if ($this->listDir == 'rtl') {
20194 // list_align_style Determines alignment of numbers in numbered lists
20195 if ($this->list_align_style == 'L') { $lalign = 'R'; }
20196 else { $lalign = 'L'; }
20197 $this->divwidth = $this->blk[$this->blklvl]['width'] - ($indent + $blt_width + $space_width) ;
20198 $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)
20199 //Output bullet
20200 $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 );
20201 $this->x = $x;
20202 }
20203 else {
20204 /*-- END RTL --*/
20205
20206 if ($this->list_align_style == 'L') { $lalign = 'L'; }
20207 else { $lalign = 'R'; }
20208 $this->divwidth = $this->blk[$this->blklvl]['width'] - ($indent + $blt_width + $space_width) ;
20209 $xb = $this->blk[$this->blklvl]['padding_left'] + $this->blk[$this->blklvl]['border_left']['w'] - $blt_width - $space_width;
20210 //Output bullet
20211 $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 );
20212 $this->x = $x + $indent + $blt_width + $space_width;
20213 } // *RTL*
20214
20215 //Print content
20216 $this->printbuffer($this->textbuffer,'',false,true);
20217 $this->textbuffer=array();
20218
20219 // Added to correct for OddEven Margins
20220 if ($this->page != $bak_page) {
20221 if (($this->page-$bak_page) % 2 == 1) {
20222 $x += $this->MarginCorrection;
20223 }
20224 $bak_page = $this->page;
20225 }
20226 /*-- COLUMNS --*/
20227 // OR COLUMN CHANGE
20228 if ($this->CurrCol != $oldcolumn) {
20229 if ($this->directionality == 'rtl') { // *RTL*
20230 $x -= ($this->CurrCol - $oldcolumn) * ($this->ColWidth+$this->ColGap); // *RTL*
20231 } // *RTL*
20232 else { // *RTL*
20233 $x += ($this->CurrCol - $oldcolumn) * ($this->ColWidth+$this->ColGap);
20234 } // *RTL*
20235 $oldcolumn = $this->CurrCol;
20236 }
20237 /*-- END COLUMNS --*/
20238
20239 }
20240
20241 //Reset all used values
20242 $this->listoccur = array();
20243 $this->listitem = array();
20244 $this->listlist = array();
20245 $this->listlvl = 0;
20246 $this->listnum = 0;
20247 $this->listtype = '';
20248 $this->textbuffer = array();
20249 $this->divwidth = 0;
20250 $this->divheight = 0;
20251 $this->x = $this->lMargin + $this->blk[$this->blklvl]['outer_left_margin'];
20252 }
20253 /*-- END LISTS --*/
20254
20255 // mPDF 5.3.99 // mPDF 5.3.A2
20256 function _saveTextBuffer($t, $link = '', $intlink = '') {
20257 $this->textbuffer[] = array($t,$link,$this->currentfontstyle,$this->colorarray,$this->currentfontfamily,$this->SUP,$this->SUB,$intlink,$this->strike,$this->outlineparam,$this->spanbgcolorarray,$this->currentfontsize,$this->ReqFontStyle,$this->kerning,$this->lSpacingCSS,$this->wSpacingCSS,$this->spanborddet, $this->textshadow);
20258 }
20259
20260 // mPDF 5.3.99 // mPDF 5.3.A2
20261 function _saveCellTextBuffer($t, $link = '', $intlink = '') {
20262 $this->cell[$this->row][$this->col]['textbuffer'][] = array($t,$link,$this->currentfontstyle,$this->colorarray,$this->currentfontfamily,$this->SUP,$this->SUB,$intlink,$this->strike,$this->outlineparam,$this->spanbgcolorarray,$this->currentfontsize,$this->ReqFontStyle,$this->kerning,$this->lSpacingCSS,$this->wSpacingCSS,$this->spanborddet, $this->textshadow);
20263 }
20264
20265
20266 function printbuffer($arrayaux,$blockstate=0,$is_table=false,$is_list=false)
20267 {
20268 // $blockstate = 0; // NO margins/padding
20269 // $blockstate = 1; // Top margins/padding only
20270 // $blockstate = 2; // Bottom margins/padding only
20271 // $blockstate = 3; // Top & bottom margins/padding
20272 $this->spanbgcolorarray = ''; // mPDF 5.3.76
20273 $this->spanbgcolor = false;
20274 // mPDF 5.3.61
20275 $this->spanborder = false;
20276 $this->spanborddet = array();
20277 $paint_ht_corr = 0;
20278
20279 /*-- CSS-FLOAT --*/
20280 if (count($this->floatDivs)) {
20281 list($l_exists, $r_exists, $l_max, $r_max, $l_width, $r_width) = $this->GetFloatDivInfo($this->blklvl);
20282 if (($this->blk[$this->blklvl]['inner_width']-$l_width-$r_width) < (2*$this->GetCharWidth('W',false))) { // mPDF 5.3.04
20283 // Too narrow to fit - try to move down past L or R float
20284 if ($l_max < $r_max && ($this->blk[$this->blklvl]['inner_width']-$r_width) > (2*$this->GetCharWidth('W',false))) { // mPDF 5.3.04
20285 $this->ClearFloats('LEFT', $this->blklvl);
20286 }
20287 else if ($r_max < $l_max && ($this->blk[$this->blklvl]['inner_width']-$l_width) > (2*$this->GetCharWidth('W',false))) { // mPDF 5.3.04
20288 $this->ClearFloats('RIGHT', $this->blklvl);
20289 }
20290 else { $this->ClearFloats('BOTH', $this->blklvl); }
20291 }
20292 }
20293 /*-- END CSS-FLOAT --*/
20294 $bak_y = $this->y;
20295 $bak_x = $this->x;
20296 $align = '';
20297 if (!$is_table && !$is_list) {
20298 if (isset($this->blk[$this->blklvl]['align']) && $this->blk[$this->blklvl]['align']) { $align = $this->blk[$this->blklvl]['align']; }
20299 // Block-align is set by e.g. <.. align="center"> Takes priority for this block but not inherited
20300 if (isset($this->blk[$this->blklvl]['block-align']) && $this->blk[$this->blklvl]['block-align']) { $align = $this->blk[$this->blklvl]['block-align']; }
20301 // mPDF 5.3.76
20302 if (isset($this->blk[$this->blklvl]['direction'])) $blockdir = $this->blk[$this->blklvl]['direction'];
20303 else $blockdir = "";
20304 $this->divwidth = $this->blk[$this->blklvl]['width'];
20305 }
20306 else {
20307 $align = $this->divalign;
20308 if ($is_table) { $blockdir = $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['direction']; }
20309 else { $blockdir = $this->listDir; }
20310 }
20311 $oldpage = $this->page;
20312
20313 // ADDED for Out of Block now done as Flowing Block
20314 if ($this->divwidth == 0) {
20315 $this->divwidth = $this->pgwidth;
20316 }
20317
20318 if (!$is_table && !$is_list) { $this->SetLineHeight($this->FontSizePt,$this->blk[$this->blklvl]['line_height']); }
20319 $this->divheight = $this->lineheight;
20320 $old_height = $this->divheight;
20321
20322 // As a failsafe - if font has been set but not output to page
20323 $this->SetFont($this->default_font,'',$this->default_font_size,true,true); // force output to page
20324
20325 $array_size = count($arrayaux);
20326 $this->newFlowingBlock( $this->divwidth,$this->divheight,$align,$is_table,$is_list,$blockstate,true,$blockdir);
20327
20328 // Added - Otherwise <div><div><p> did not output top margins/padding for 1st/2nd div
20329 if ($array_size == 0) { $this->finishFlowingBlock(true); } // true = END of flowing block
20330
20331 for($i=0;$i < $array_size; $i++)
20332 {
20333 // COLS
20334 $oldcolumn = $this->CurrCol;
20335
20336 $vetor = $arrayaux[$i];
20337 if ($i == 0 and $vetor[0] != "\n" and !$this->ispre) {
20338 $vetor[0] = ltrim($vetor[0]);
20339 }
20340
20341 // FIXED TO ALLOW IT TO SHOW '0'
20342 if (empty($vetor[0]) && !($vetor[0]==='0') && empty($vetor[7])) { //Ignore empty text and not carrying an internal link
20343 //Check if it is the last element. If so then finish printing the block
20344 if ($i == ($array_size-1)) { $this->finishFlowingBlock(true); } // true = END of flowing block
20345 continue;
20346 }
20347
20348
20349 //Activating buffer properties
20350 if(isset($vetor[11]) and $vetor[11] != '') { // Font Size
20351 if ($is_table && $this->shrin_k) {
20352 $this->SetFontSize($vetor[11]/$this->shrin_k,false);
20353 }
20354 else {
20355 $this->SetFontSize($vetor[11],false);
20356 }
20357 }
20358
20359 // mPDF 5.3.A2
20360 if(isset($vetor[17]) && !empty($vetor[17])) { //TextShadow
20361 $this->textshadow = $vetor[17];
20362 }
20363 // mPDF 5.3.61
20364 if(isset($vetor[16]) && !empty($vetor[16])) { //Border
20365 $this->spanborddet = $vetor[16];
20366 $this->spanborder = true;
20367 }
20368
20369 if(isset($vetor[15])) { // Word spacing
20370 $this->wSpacingCSS = $vetor[15];
20371 if ($this->wSpacingCSS && strtoupper($this->wSpacingCSS) != 'NORMAL') {
20372 $this->minwSpacing = $this->ConvertSize($this->wSpacingCSS,$this->FontSize);
20373 }
20374 }
20375 if(isset($vetor[14])) { // Letter spacing
20376 $this->lSpacingCSS = $vetor[14];
20377 if (($this->lSpacingCSS || $this->lSpacingCSS==='0') && strtoupper($this->lSpacingCSS) != 'NORMAL') {
20378 $this->fixedlSpacing = $this->ConvertSize($this->lSpacingCSS,$this->FontSize);
20379 }
20380 }
20381 if(isset($vetor[13])) { // Font Kerning
20382 $this->kerning = $vetor[13];
20383 }
20384
20385
20386 if(isset($vetor[10]) and !empty($vetor[10])) //Background color
20387 {
20388 $this->spanbgcolorarray = $vetor[10];
20389 $this->spanbgcolor = true;
20390 }
20391 if(isset($vetor[9]) and !empty($vetor[9])) // Outline parameters
20392 {
20393 $cor = $vetor[9]['COLOR'];
20394 $outlinewidth = $vetor[9]['WIDTH'];
20395 $this->SetTextOutline($outlinewidth,$cor);
20396 $this->outline_on = true;
20397 }
20398 if(isset($vetor[8]) and $vetor[8] === true) // strike-through the text
20399 {
20400 $this->strike = true;
20401 }
20402 if(isset($vetor[7]) and $vetor[7] != '') // internal link: <a name="anyvalue">
20403 {
20404 // mPDF 5.3.01
20405 // if ($this->ColActive) { $ily = $this->y0; } else { $ily = $this->y; } // use top of columns
20406 $ily = $this->y;
20407 if ($this->keep_block_together) { $this->internallink[$vetor[7]] = array("Y"=>$ily,"PAGE"=>$this->page, "kt"=>true ); }
20408 else if ($this->table_rotate) { $this->internallink[$vetor[7]] = array("Y"=>$ily,"PAGE"=>$this->page, "tbrot"=>true ); }
20409 else if ($this->kwt) { $this->internallink[$vetor[7]] = array("Y"=>$ily,"PAGE"=>$this->page, "kwt"=>true ); }
20410 else if ($this->ColActive) { $this->internallink[$vetor[7]] = array("Y"=>$ily,"PAGE"=>$this->page, "col"=>$this->CurrCol ); }
20411 else
20412 $this->internallink[$vetor[7]] = array("Y"=>$ily,"PAGE"=>$this->page );
20413 if (empty($vetor[0])) { //Ignore empty text
20414 //Check if it is the last element. If so then finish printing the block
20415 if ($i == ($array_size-1)) { $this->finishFlowingBlock(true); } // true = END of flowing block
20416 continue;
20417 }
20418 }
20419 if(isset($vetor[6]) and $vetor[6] === true) // Subscript
20420 {
20421 $this->SUB = true;
20422 }
20423 if(isset($vetor[5]) and $vetor[5] === true) // Superscript
20424 {
20425 $this->SUP = true;
20426 }
20427 if(isset($vetor[4]) and $vetor[4] != '') { // Font Family
20428 $font = $this->SetFont($vetor[4],$this->FontStyle,0,false);
20429 }
20430 if (!empty($vetor[3])) //Font Color
20431 {
20432 $cor = $vetor[3];
20433 $this->SetTColor($cor);
20434 }
20435 if(isset($vetor[2]) and $vetor[2] != '') //Bold,Italic,Underline styles
20436 {
20437 $this->SetStyles($vetor[2]);
20438 }
20439
20440 if(isset($vetor[12]) and $vetor[12] != '') { //Requested Bold,Italic,Underline
20441 $this->ReqFontStyle = $vetor[12];
20442 }
20443 if(isset($vetor[1]) and $vetor[1] != '') //LINK
20444 {
20445
20446 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.)
20447 {
20448 //Repeated reference to same anchor?
20449 while(array_key_exists($vetor[1],$this->internallink)) $vetor[1]="#".$vetor[1];
20450 $this->internallink[$vetor[1]] = $this->AddLink();
20451 $vetor[1] = $this->internallink[$vetor[1]];
20452 }
20453 $this->HREF = $vetor[1]; // HREF link style set here ******
20454 }
20455
20456 // SPECIAL CONTENT - IMAGES & FORM OBJECTS
20457 //Print-out special content
20458
20459 if (substr($vetor[0],0,3) == "\xbb\xa4\xac") { //identifier has been identified!
20460
20461 $objattr = $this->_getObjAttr($vetor[0]);
20462
20463 /*-- TABLES --*/
20464 if ($objattr['type'] == 'nestedtable') {
20465 // mPDF 5.3.79 NB Following code moved inside the if ...
20466 if ($objattr['nestedcontent']) {
20467 $level = $objattr['level'];
20468 $table = &$this->table[$level][$objattr['table']];
20469 // mPDF 5.3.79
20470 if ($this->cacheTables) {
20471 $fh = fopen($table['cache'], "r+b");
20472 $cell = $this->_uncacheCell($table['cells'][$objattr['row']][$objattr['col']], '', $fh);
20473 }
20474 else {
20475 $fh = null;
20476 $cell = &$table['cells'][$objattr['row']][$objattr['col']];
20477 }
20478 $this->finishFlowingBlock(false,'nestedtable');
20479 $save_dw = $this->divwidth ;
20480 $save_buffer = $this->cellBorderBuffer;
20481 $this->cellBorderBuffer = array();
20482 $ncx = $this->x;
20483 list($dummyx,$w) = $this->_tableGetWidth($table, $objattr['row'], $objattr['col'], $fh); // mPDF 5.3.79
20484 $ntw = $this->table[($level+1)][$objattr['nestedcontent']]['w']; // nested table width
20485 if (!$this->simpleTables){
20486 if ($this->packTableData) {
20487 list($bt,$br,$bb,$bl) = $this->_getBorderWidths($cell['borderbin']);
20488 }
20489 else {
20490 $br = $cell['border_details']['R']['w'];
20491 $bl = $cell['border_details']['L']['w'];
20492 }
20493 if ($table['borders_separate']) {
20494 $innerw = $w - $bl - $br - $cell['padding']['L'] - $cell['padding']['R'] - $table['border_spacing_H'];
20495 }
20496 else {
20497 $innerw = $w - $bl/2 - $br/2 - $cell['padding']['L'] - $cell['padding']['R'];
20498 }
20499 }
20500 else if ($this->simpleTables){
20501 if ($table['borders_separate']) {
20502 $innerw = $w - $table['simple']['border_details']['L']['w'] - $table['simple']['border_details']['R']['w'] - $cell['padding']['L'] - $cell['padding']['R'] - $table['border_spacing_H'];
20503 }
20504 else {
20505 $innerw = $w - $table['simple']['border_details']['L']['w']/2 - $table['simple']['border_details']['R']['w']/2 - $cell['padding']['L'] - $cell['padding']['R'];
20506 }
20507 }
20508 if ($cell['a']=='C' || $this->table[($level+1)][$objattr['nestedcontent']]['a']=='C') {
20509 $ncx += ($innerw-$ntw)/2;
20510 }
20511 elseif ($cell['a']=='R' || $this->table[($level+1)][$objattr['nestedcontent']]['a']=='R') {
20512 $ncx += $innerw- $ntw;
20513 }
20514 $this->x = $ncx ;
20515 // mPDF 5.3.79
20516 if ($this->cacheTables) { fclose($fh); }
20517
20518 $this->_tableWrite($this->table[($level+1)][$objattr['nestedcontent']]);
20519 $this->cellBorderBuffer = $save_buffer;
20520 $this->x = $bak_x ;
20521 $this->divwidth = $save_dw;
20522 $this->newFlowingBlock( $this->divwidth,$this->divheight,$align,$is_table,$is_list,$blockstate,false,$blockdir);
20523 }
20524 }
20525 else {
20526 /*-- END TABLES --*/
20527 if ($is_table) { // *TABLES*
20528 $maxWidth = $this->divwidth; // *TABLES*
20529 } // *TABLES*
20530 else { // *TABLES*
20531 $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']);
20532 } // *TABLES*
20533
20534 /*-- CSS-IMAGE-FLOAT --*/
20535 // If float (already) exists at this level
20536 if (isset($this->floatmargins['R']) && $this->y <= $this->floatmargins['R']['y1'] && $this->y >= $this->floatmargins['R']['y0']) { $maxWidth -= $this->floatmargins['R']['w']; }
20537 if (isset($this->floatmargins['L']) && $this->y <= $this->floatmargins['L']['y1'] && $this->y >= $this->floatmargins['L']['y0']) { $maxWidth -= $this->floatmargins['L']['w']; }
20538 /*-- END CSS-IMAGE-FLOAT --*/
20539
20540 list($skipln) = $this->inlineObject($objattr['type'], '', $this->y, $objattr,$this->lMargin, ($this->flowingBlockAttr['contentWidth']/_MPDFK), $maxWidth, $this->flowingBlockAttr['height'], false, $is_table);
20541 // 1 -> New line needed because of width
20542 // -1 -> Will fit width on line but NEW PAGE REQUIRED because of height
20543 // -2 -> Will not fit on line therefore needs new line but thus NEW PAGE REQUIRED
20544 $iby = $this->y;
20545 $oldpage = $this->page;
20546 $oldcol = $this->CurrCol;
20547 if (($skipln == 1 || $skipln == -2) && !isset($objattr['float'])) {
20548 $this->finishFlowingBlock(false,$objattr['type']);
20549 $this->newFlowingBlock( $this->divwidth,$this->divheight,$align,$is_table,$is_list,$blockstate,false,$blockdir);
20550 }
20551 $thispage = $this->page;
20552 if ($this->CurrCol!=$oldcol) { $changedcol = true; }
20553 else { $changedcol=false; }
20554
20555 // the previous lines can already have triggered page break or column change
20556 if (!$changedcol && $skipln <0 && $this->AcceptPageBreak() && $thispage==$oldpage) {
20557
20558 $this->AddPage($this->CurOrientation);
20559
20560 // Added to correct Images already set on line before page advanced
20561 // i.e. if second inline image on line is higher than first and forces new page
20562 if (count($this->objectbuffer)) {
20563 $yadj = $iby - $this->y;
20564 foreach($this->objectbuffer AS $ib=>$val) {
20565 if ($this->objectbuffer[$ib]['OUTER-Y'] ) $this->objectbuffer[$ib]['OUTER-Y'] -= $yadj;
20566 if ($this->objectbuffer[$ib]['BORDER-Y']) $this->objectbuffer[$ib]['BORDER-Y'] -= $yadj;
20567 if ($this->objectbuffer[$ib]['INNER-Y']) $this->objectbuffer[$ib]['INNER-Y'] -= $yadj;
20568 }
20569 }
20570 }
20571
20572 // Added to correct for OddEven Margins
20573 if ($this->page != $oldpage) {
20574 if (($this->page-$oldpage) % 2 == 1) {
20575 $bak_x += $this->MarginCorrection;
20576 }
20577 $oldpage = $this->page;
20578 $y = $this->tMargin - $paint_ht_corr ;
20579 $this->oldy = $this->tMargin - $paint_ht_corr ;
20580 $old_height = 0;
20581 }
20582 $this->x = $bak_x;
20583 /*-- COLUMNS --*/
20584 // COLS
20585 // OR COLUMN CHANGE
20586 if ($this->CurrCol != $oldcolumn) {
20587 if ($this->directionality == 'rtl') { // *RTL*
20588 $bak_x -= ($this->CurrCol - $oldcolumn) * ($this->ColWidth+$this->ColGap); // *RTL*
20589 } // *RTL*
20590 else { // *RTL*
20591 $bak_x += ($this->CurrCol - $oldcolumn) * ($this->ColWidth+$this->ColGap);
20592 } // *RTL*
20593 $this->x = $bak_x;
20594 $oldcolumn = $this->CurrCol;
20595 $y = $this->y0 - $paint_ht_corr ;
20596 $this->oldy = $this->y0 - $paint_ht_corr ;
20597 $old_height = 0;
20598 }
20599 /*-- END COLUMNS --*/
20600
20601 /*-- CSS-IMAGE-FLOAT --*/
20602 if ($objattr['type'] == 'image' && isset($objattr['float'])) {
20603 $fy = $this->y;
20604
20605 // DIV TOP MARGIN/BORDER/PADDING
20606 if ($this->flowingBlockAttr['newblock'] && ($this->flowingBlockAttr['blockstate']==1 || $this->flowingBlockAttr['blockstate']==3) && $this->flowingBlockAttr['lineCount']== 0) {
20607 $fy += $this->blk[$this->blklvl]['margin_top'] + $this->blk[$this->blklvl]['padding_top'] + $this->blk[$this->blklvl]['border_top']['w'];
20608 }
20609
20610 if ($objattr['float']=='R') {
20611 $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']);
20612
20613
20614 }
20615 else if ($objattr['float']=='L') {
20616 $fx = $this->lMargin + ($this->blk[$this->blklvl]['outer_left_margin'] + $this->blk[$this->blklvl]['border_left']['w'] + $this->blk[$this->blklvl]['padding_left']);
20617 }
20618 $w = $objattr['width'];
20619 $h = abs($objattr['height']);
20620
20621 $widthLeft = $maxWidth - ($this->flowingBlockAttr['contentWidth']/_MPDFK);
20622 $maxHeight = $this->h - ($this->tMargin + $this->margin_header + $this->bMargin + 10) ;
20623 // For Images
20624 $extraWidth = ($objattr['border_left']['w'] + $objattr['border_right']['w'] + $objattr['margin_left']+ $objattr['margin_right']);
20625 $extraHeight = ($objattr['border_top']['w'] + $objattr['border_bottom']['w'] + $objattr['margin_top']+ $objattr['margin_bottom']);
20626
20627 if ($objattr['itype'] == 'wmf' || $objattr['itype'] == 'svg') {
20628 $file = $objattr['file'];
20629 $info=$this->formobjects[$file];
20630 }
20631 else {
20632 $file = $objattr['file'];
20633 $info=$this->images[$file];
20634 }
20635 $img_w = $w - $extraWidth ;
20636 $img_h = $h - $extraHeight ;
20637 if ($objattr['border_left']['w']) {
20638 $objattr['BORDER-WIDTH'] = $img_w + (($objattr['border_left']['w'] + $objattr['border_right']['w'])/2) ;
20639 $objattr['BORDER-HEIGHT'] = $img_h + (($objattr['border_top']['w'] + $objattr['border_bottom']['w'])/2) ;
20640 $objattr['BORDER-X'] = $fx + $objattr['margin_left'] + (($objattr['border_left']['w'])/2) ;
20641 $objattr['BORDER-Y'] = $fy + $objattr['margin_top'] + (($objattr['border_top']['w'])/2) ;
20642 }
20643 $objattr['INNER-WIDTH'] = $img_w;
20644 $objattr['INNER-HEIGHT'] = $img_h;
20645 $objattr['INNER-X'] = $fx + $objattr['margin_left'] + ($objattr['border_left']['w']);
20646 $objattr['INNER-Y'] = $fy + $objattr['margin_top'] + ($objattr['border_top']['w']) ;
20647 $objattr['ID'] = $info['i'];
20648 $objattr['OUTER-WIDTH'] = $w;
20649 $objattr['OUTER-HEIGHT'] = $h;
20650 $objattr['OUTER-X'] = $fx;
20651 $objattr['OUTER-Y'] = $fy;
20652 if ($objattr['float']=='R') {
20653 // If R float already exists at this level
20654 $this->floatmargins['R']['skipline'] = false;
20655 if (isset($this->floatmargins['R']['y1']) && $this->floatmargins['R']['y1'] > 0 && $fy < $this->floatmargins['R']['y1']) {
20656 $this->WriteFlowingBlock($vetor[0]);
20657 }
20658 // If L float already exists at this level
20659 else if (isset($this->floatmargins['L']['y1']) && $this->floatmargins['L']['y1'] > 0 && $fy < $this->floatmargins['L']['y1']) {
20660 // Final check distance between floats is not now too narrow to fit text
20661 $mw = 2*$this->GetCharWidth('W',false); // mPDF 5.3.04
20662 if (($this->blk[$this->blklvl]['inner_width'] - $w - $this->floatmargins['L']['w']) < $mw) {
20663 $this->WriteFlowingBlock($vetor[0]);
20664 }
20665 else {
20666 $this->floatmargins['R']['x'] = $fx;
20667 $this->floatmargins['R']['w'] = $w;
20668 $this->floatmargins['R']['y0'] = $fy;
20669 $this->floatmargins['R']['y1'] = $fy + $h;
20670 if ($skipln == 1) {
20671 $this->floatmargins['R']['skipline'] = true;
20672 $this->floatmargins['R']['id'] = count($this->floatbuffer)+0;
20673 $objattr['skipline'] = true;
20674 }
20675 $this->floatbuffer[] = $objattr;
20676 }
20677 }
20678 else {
20679 $this->floatmargins['R']['x'] = $fx;
20680 $this->floatmargins['R']['w'] = $w;
20681 $this->floatmargins['R']['y0'] = $fy;
20682 $this->floatmargins['R']['y1'] = $fy + $h;
20683 if ($skipln == 1) {
20684 $this->floatmargins['R']['skipline'] = true;
20685 $this->floatmargins['R']['id'] = count($this->floatbuffer)+0;
20686 $objattr['skipline'] = true;
20687 }
20688 $this->floatbuffer[] = $objattr;
20689 }
20690 }
20691 else if ($objattr['float']=='L') {
20692 // If L float already exists at this level
20693 $this->floatmargins['L']['skipline'] = false;
20694 if (isset($this->floatmargins['L']['y1']) && $this->floatmargins['L']['y1'] > 0 && $fy < $this->floatmargins['L']['y1']) {
20695 $this->floatmargins['L']['skipline'] = false;
20696 $this->WriteFlowingBlock($vetor[0]);
20697 }
20698 // If R float already exists at this level
20699 else if (isset($this->floatmargins['R']['y1']) && $this->floatmargins['R']['y1'] > 0 && $fy < $this->floatmargins['R']['y1']) {
20700 // Final check distance between floats is not now too narrow to fit text
20701 $mw = 2*$this->GetCharWidth('W',false); // mPDF 5.3.04
20702 if (($this->blk[$this->blklvl]['inner_width'] - $w - $this->floatmargins['R']['w']) < $mw) {
20703 $this->WriteFlowingBlock($vetor[0]);
20704 }
20705 else {
20706 $this->floatmargins['L']['x'] = $fx + $w;
20707 $this->floatmargins['L']['w'] = $w;
20708 $this->floatmargins['L']['y0'] = $fy;
20709 $this->floatmargins['L']['y1'] = $fy + $h;
20710 if ($skipln == 1) {
20711 $this->floatmargins['L']['skipline'] = true;
20712 $this->floatmargins['L']['id'] = count($this->floatbuffer)+0;
20713 $objattr['skipline'] = true;
20714 }
20715 $this->floatbuffer[] = $objattr;
20716 }
20717 }
20718 else {
20719 $this->floatmargins['L']['x'] = $fx + $w;
20720 $this->floatmargins['L']['w'] = $w;
20721 $this->floatmargins['L']['y0'] = $fy;
20722 $this->floatmargins['L']['y1'] = $fy + $h;
20723 if ($skipln == 1) {
20724 $this->floatmargins['L']['skipline'] = true;
20725 $this->floatmargins['L']['id'] = count($this->floatbuffer)+0;
20726 $objattr['skipline'] = true;
20727 }
20728 $this->floatbuffer[] = $objattr;
20729 }
20730 }
20731 }
20732 else {
20733 /*-- END CSS-IMAGE-FLOAT --*/
20734 $this->WriteFlowingBlock($vetor[0]);
20735 /*-- CSS-IMAGE-FLOAT --*/
20736 }
20737 /*-- END CSS-IMAGE-FLOAT --*/
20738 } // *TABLES*
20739
20740 } // END If special content
20741
20742 else { //THE text
20743 if ($this->tableLevel) { $paint_ht_corr = 0; } // To move the y up when new column/page started if div border needed
20744 else { $paint_ht_corr = $this->blk[$this->blklvl]['border_top']['w']; }
20745
20746 if ($vetor[0] == "\n") { //We are reading a <BR> now turned into newline ("\n")
20747 if ($this->flowingBlockAttr['content']) {
20748 $this->finishFlowingBlock(false,'br');
20749 }
20750 else if ($is_table) {
20751 $this->y+= $this->_computeLineheight($this->table_lineheight);
20752 }
20753 else if (!$is_table) {
20754 $this->DivLn($this->lineheight);
20755 if ($this->ColActive) { $this->breakpoints[$this->CurrCol][] = $this->y; } // *COLUMNS*
20756 }
20757 // Added to correct for OddEven Margins
20758 if ($this->page != $oldpage) {
20759 if (($this->page-$oldpage) % 2 == 1) {
20760 $bak_x += $this->MarginCorrection;
20761 }
20762 $oldpage = $this->page;
20763 $y = $this->tMargin - $paint_ht_corr ;
20764 $this->oldy = $this->tMargin - $paint_ht_corr ;
20765 $old_height = 0;
20766 }
20767 $this->x = $bak_x;
20768 /*-- COLUMNS --*/
20769 // COLS
20770 // OR COLUMN CHANGE
20771 if ($this->CurrCol != $oldcolumn) {
20772 if ($this->directionality == 'rtl') { // *RTL*
20773 $bak_x -= ($this->CurrCol - $oldcolumn) * ($this->ColWidth+$this->ColGap); // *RTL*
20774 } // *RTL*
20775 else { // *RTL*
20776 $bak_x += ($this->CurrCol - $oldcolumn) * ($this->ColWidth+$this->ColGap);
20777 } // *RTL*
20778 $this->x = $bak_x;
20779 $oldcolumn = $this->CurrCol;
20780 $y = $this->y0 - $paint_ht_corr ;
20781 $this->oldy = $this->y0 - $paint_ht_corr ;
20782 $old_height = 0;
20783 }
20784 /*-- END COLUMNS --*/
20785 $this->newFlowingBlock( $this->divwidth,$this->divheight,$align,$is_table,$is_list,$blockstate,false,$blockdir);
20786 }
20787 else {
20788 $this->WriteFlowingBlock( $vetor[0]);
20789
20790 // Added to correct for OddEven Margins
20791 if ($this->page != $oldpage) {
20792 if (($this->page-$oldpage) % 2 == 1) {
20793 $bak_x += $this->MarginCorrection;
20794 $this->x = $bak_x;
20795 }
20796 $oldpage = $this->page;
20797 $y = $this->tMargin - $paint_ht_corr ;
20798 $this->oldy = $this->tMargin - $paint_ht_corr ;
20799 $old_height = 0;
20800 }
20801 /*-- COLUMNS --*/
20802 // COLS
20803 // OR COLUMN CHANGE
20804 if ($this->CurrCol != $oldcolumn) {
20805 if ($this->directionality == 'rtl') { // *RTL*
20806 $bak_x -= ($this->CurrCol - $oldcolumn) * ($this->ColWidth+$this->ColGap); // *RTL*
20807 } // *RTL*
20808 else { // *RTL*
20809 $bak_x += ($this->CurrCol - $oldcolumn) * ($this->ColWidth+$this->ColGap);
20810 } // *RTL*
20811 $this->x = $bak_x;
20812 $oldcolumn = $this->CurrCol;
20813 $y = $this->y0 - $paint_ht_corr ;
20814 $this->oldy = $this->y0 - $paint_ht_corr ;
20815 $old_height = 0;
20816 }
20817 /*-- END COLUMNS --*/
20818 }
20819
20820
20821 }
20822
20823 //Check if it is the last element. If so then finish printing the block
20824 if ($i == ($array_size-1)) {
20825 $this->finishFlowingBlock(true); // true = END of flowing block
20826 // Added to correct for OddEven Margins
20827 if ($this->page != $oldpage) {
20828 if (($this->page-$oldpage) % 2 == 1) {
20829 $bak_x += $this->MarginCorrection;
20830 $this->x = $bak_x;
20831 }
20832 $oldpage = $this->page;
20833 $y = $this->tMargin - $paint_ht_corr ;
20834 $this->oldy = $this->tMargin - $paint_ht_corr ;
20835 $old_height = 0;
20836 }
20837
20838 /*-- COLUMNS --*/
20839 // COLS
20840 // OR COLUMN CHANGE
20841 if ($this->CurrCol != $oldcolumn) {
20842 if ($this->directionality == 'rtl') { // *RTL*
20843 $bak_x -= ($this->CurrCol - $oldcolumn) * ($this->ColWidth+$this->ColGap); // *RTL*
20844 } // *RTL*
20845 else { // *RTL*
20846 $bak_x += ($this->CurrCol - $oldcolumn) * ($this->ColWidth+$this->ColGap);
20847 } // *RTL*
20848 $this->x = $bak_x;
20849 $oldcolumn = $this->CurrCol;
20850 $y = $this->y0 - $paint_ht_corr ;
20851 $this->oldy = $this->y0 - $paint_ht_corr ;
20852 $old_height = 0;
20853 }
20854 /*-- END COLUMNS --*/
20855
20856 }
20857
20858 // RESETTING VALUES
20859 $this->SetTColor($this->ConvertColor(0));
20860 $this->SetDColor($this->ConvertColor(0));
20861 $this->SetFColor($this->ConvertColor(255));
20862 $this->colorarray = ''; // mPDF 5.3.76
20863 $this->spanbgcolorarray = ''; // mPDF 5.3.76
20864 $this->spanbgcolor = false;
20865 // mPDF 5.3.61
20866 $this->spanborder = false;
20867 $this->spanborddet = array();
20868 $this->HREF = '';
20869 $this->outlineparam = array();
20870 $this->SetTextOutline(false);
20871 $this->outline_on = false;
20872 $this->SUP = false;
20873 $this->SUB = false;
20874
20875 $this->strike = false;
20876 $this->textshadow = ''; // mPDF 5.3.A2
20877
20878 $this->currentfontfamily = '';
20879 $this->currentfontsize = '';
20880 $this->currentfontstyle = '';
20881 /*-- TABLES --*/
20882 if ($this->tableLevel) {
20883 $this->SetLineHeight('',$this->table_lineheight); // *TABLES*
20884 }
20885 else
20886 /*-- END TABLES --*/
20887 /*-- LISTS --*/
20888 if ($is_list && $this->list_lineheight[$this->listlvl][$this->listOcc]) { // mPDF 5.3.76
20889 $this->SetLineHeight('',$this->list_lineheight[$this->listlvl][$this->listOcc]); // sets default line height
20890 }
20891 else
20892 /*-- END LISTS --*/
20893 if (isset($this->blk[$this->blklvl]['line_height']) && $this->blk[$this->blklvl]['line_height']) {
20894 $this->SetLineHeight('',$this->blk[$this->blklvl]['line_height']); // sets default line height
20895 }
20896 $this->ResetStyles();
20897 $this->toupper = false;
20898 $this->tolower = false;
20899 $this->capitalize = false;
20900 $this->kerning = false;
20901 $this->lSpacingCSS = '';
20902 $this->wSpacingCSS = '';
20903 $this->fixedlSpacing = false;
20904 $this->minwSpacing = 0;
20905 $this->SetDash();
20906 $this->dash_on = false;
20907 $this->dotted_on = false;
20908
20909 }//end of for(i=0;i<arraysize;i++)
20910
20911
20912 // PAINT DIV BORDER // DISABLED IN COLUMNS AS DOESN'T WORK WHEN BROKEN ACROSS COLS??
20913 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)) { // mPDF 5.3.A1
20914 $bottom_y = $this->y; // Does not include Bottom Margin
20915 if (isset($this->blk[$this->blklvl]['startpage']) && $this->blk[$this->blklvl]['startpage'] != $this->page && $blockstate != 1) {
20916 $this->PaintDivBB('pagetop',$blockstate);
20917 }
20918
20919 else if ($blockstate != 1) {
20920 $this->PaintDivBB('',$blockstate);
20921 }
20922 $this->y = $bottom_y;
20923 $this->x = $bak_x;
20924 }
20925
20926 // Reset Font
20927 $this->SetFontSize($this->default_font_size,false);
20928
20929
20930 }
20931
20932 function _setDashBorder($style, $div, $cp, $side) {
20933 if ($style == 'dashed' && (($side=='L' || $side=='R') || ($side=='T' && $div != 'pagetop' && !$cp) || ($side=='B' && $div!='pagebottom') )) {
20934 $dashsize = 2; // final dash will be this + 1*linewidth
20935 $dashsizek = 1.5; // ratio of Dash/Blank
20936 $this->SetDash($dashsize,($dashsize/$dashsizek)+($this->LineWidth*2));
20937 }
20938 else if ($style == 'dotted' || ($side=='T' && ($div == 'pagetop' || $cp)) || ($side=='B' && $div == 'pagebottom')) {
20939 //Round join and cap
20940 $this->SetLineJoin(1);
20941 $this->SetLineCap(1);
20942 $this->SetDash(0.001,($this->LineWidth*3));
20943 }
20944 }
20945
20946 function _setBorderLine($b, $k=1) {
20947 $this->SetLineWidth($b['w']/$k);
20948 $this->SetDColor($b['c']);
20949 if ($b['c'][0]==5) { // RGBa
20950 $this->SetAlpha($b['c'][4], 'Normal', false, 'S')."\n";
20951 }
20952 else if ($b['c'][0]==6) { // CMYKa
20953 $this->SetAlpha($b['c'][5], 'Normal', false, 'S')."\n";
20954 }
20955 }
20956
20957 function PaintDivBB($divider='',$blockstate=0,$blvl=0) {
20958 // Borders & backgrounds are done elsewhere for columns - messes up the repositioning in printcolumnbuffer
20959 if ($this->ColActive) { return ; } // *COLUMNS*
20960 $save_y = $this->y;
20961 if (!$blvl) { $blvl = $this->blklvl; }
20962 $x0 = $x1 = $y0 = $y1 = 0;
20963
20964 // Added mPDF 3.0 Float DIV
20965 if (isset($this->blk[$blvl]['bb_painted'][$this->page]) && $this->blk[$blvl]['bb_painted'][$this->page]) { return; } // *CSS-FLOAT*
20966
20967 if (isset($this->blk[$blvl]['x0'])) { $x0 = $this->blk[$blvl]['x0']; } // left
20968 if (isset($this->blk[$blvl]['y1'])) { $y1 = $this->blk[$blvl]['y1']; } // bottom
20969
20970 // Added mPDF 3.0 Float DIV - ensures backgrounds/borders are drawn to bottom of page
20971 if ($y1==0) {
20972 if ($divider=='pagebottom') { $y1 = $this->h-$this->bMargin; }
20973 else { $y1 = $this->y; }
20974 }
20975
20976 if (isset($this->blk[$blvl]['startpage']) && $this->blk[$blvl]['startpage'] != $this->page) { $continuingpage = true; } else { $continuingpage = false; }
20977
20978 if (isset($this->blk[$blvl]['y0'])) { $y0 = $this->blk[$blvl]['y0']; }
20979 $h = $y1 - $y0;
20980 $w = $this->blk[$blvl]['width'];
20981 $x1 = $x0 + $w;
20982
20983 // Set border-widths as used here
20984 $border_top = $this->blk[$blvl]['border_top']['w'];
20985 $border_bottom = $this->blk[$blvl]['border_bottom']['w'];
20986 $border_left = $this->blk[$blvl]['border_left']['w'];
20987 $border_right = $this->blk[$blvl]['border_right']['w'];
20988 if (!$this->blk[$blvl]['border_top'] || $divider == 'pagetop' || $continuingpage) {
20989 $border_top = 0;
20990 }
20991 if (!$this->blk[$blvl]['border_bottom'] || $blockstate == 1 || $divider == 'pagebottom') {
20992 $border_bottom = 0;
20993 }
20994
20995 $brTL_H = 0;
20996 $brTL_V = 0;
20997 $brTR_H = 0;
20998 $brTR_V = 0;
20999 $brBL_H = 0;
21000 $brBL_V = 0;
21001 $brBR_H = 0;
21002 $brBR_V = 0;
21003
21004 $brset = false;
21005 /*-- BORDER-RADIUS --*/
21006 if (isset($this->blk[$blvl]['border_radius_TL_H'])) { $brTL_H = $this->blk[$blvl]['border_radius_TL_H']; $brset = true; }
21007 if (isset($this->blk[$blvl]['border_radius_TL_V'])) { $brTL_V = $this->blk[$blvl]['border_radius_TL_V']; $brset = true; }
21008 if (isset($this->blk[$blvl]['border_radius_TR_H'])) { $brTR_H = $this->blk[$blvl]['border_radius_TR_H']; $brset = true; }
21009 if (isset($this->blk[$blvl]['border_radius_TR_V'])) { $brTR_V = $this->blk[$blvl]['border_radius_TR_V']; $brset = true; }
21010 if (isset($this->blk[$blvl]['border_radius_BR_H'])) { $brBR_H = $this->blk[$blvl]['border_radius_BR_H']; $brset = true; }
21011 if (isset($this->blk[$blvl]['border_radius_BR_V'])) { $brBR_V = $this->blk[$blvl]['border_radius_BR_V']; $brset = true; }
21012 if (isset($this->blk[$blvl]['border_radius_BL_H'])) { $brBL_H = $this->blk[$blvl]['border_radius_BL_H']; $brset = true; }
21013 if (isset($this->blk[$blvl]['border_radius_BL_V'])) { $brBL_V = $this->blk[$blvl]['border_radius_BL_V']; $brset = true; }
21014
21015 if (!$this->blk[$blvl]['border_top'] || $divider == 'pagetop' || $continuingpage || $this->keep_block_together) {
21016 $brTL_H = 0;
21017 $brTL_V = 0;
21018 $brTR_H = 0;
21019 $brTR_V = 0;
21020 }
21021 if (!$this->blk[$blvl]['border_bottom'] || $blockstate == 1 || $divider == 'pagebottom' || $this->keep_block_together) {
21022 $brBL_H = 0;
21023 $brBL_V = 0;
21024 $brBR_H = 0;
21025 $brBR_V = 0;
21026 }
21027
21028 // Disallow border-radius if it is smaller than the border width.
21029 if ($brTL_H < min($border_left, $border_top)) { $brTL_H = $brTL_V = 0; }
21030 if ($brTL_V < min($border_left, $border_top)) { $brTL_V = $brTL_H = 0; }
21031 if ($brTR_H < min($border_right, $border_top)) { $brTR_H = $brTR_V = 0; }
21032 if ($brTR_V < min($border_right, $border_top)) { $brTR_V = $brTR_H = 0; }
21033 if ($brBL_H < min($border_left, $border_bottom)) { $brBL_H = $brBL_V = 0; }
21034 if ($brBL_V < min($border_left, $border_bottom)) { $brBL_V = $brBL_H = 0; }
21035 if ($brBR_H < min($border_right, $border_bottom)) { $brBR_H = $brBR_V = 0; }
21036 if ($brBR_V < min($border_right, $border_bottom)) { $brBR_V = $brBR_H = 0; }
21037
21038 // CHECK FOR radii that sum to > width or height of div ********
21039 $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));
21040 if ($f < 1) {
21041 $brTL_H *= $f;
21042 $brTL_V *= $f;
21043 $brTR_H *= $f;
21044 $brTR_V *= $f;
21045 $brBL_H *= $f;
21046 $brBL_V *= $f;
21047 $brBR_H *= $f;
21048 $brBR_V *= $f;
21049 }
21050 /*-- END BORDER-RADIUS --*/
21051
21052 // BORDERS
21053 if (isset($this->blk[$blvl]['y0']) && $this->blk[$blvl]['y0']) { $y0 = $this->blk[$blvl]['y0']; }
21054 $h = $y1 - $y0;
21055 $w = $this->blk[$blvl]['width'];
21056
21057 //if ($this->blk[$blvl]['border_top']) {
21058 // Reinstate line above for dotted line divider when block border crosses a page
21059 if ($this->blk[$blvl]['border_top'] && $divider != 'pagetop' && !$continuingpage) {
21060 $tbd = $this->blk[$blvl]['border_top'];
21061 if (isset($tbd['s']) && $tbd['s']) {
21062 $this->_setBorderLine($tbd);
21063 if ($tbd['style']=='dotted' || $tbd['style']=='dashed') { $this->_setDashBorder($tbd['style'],$divider,$continuingpage,'T'); }
21064 /*-- BORDER-RADIUS --*/
21065 else if (($brTL_V && $brTL_H) || ($brTR_V && $brTR_H)) {
21066 $this->SetLineJoin(0);
21067 $this->SetLineCap(0);
21068 }
21069 if ($brTR_H && $brTR_V) {
21070 $this->_out($this->_EllipseArc($x0 + $w - $brTR_H, $y0 + $brTR_V, $brTR_H - $border_top/2 , $brTR_V - $border_top/2 , 1, 2, true));
21071 }
21072 else {
21073 /*-- END BORDER-RADIUS --*/
21074 $this->_out(sprintf('%.3F %.3F m ',($x0 + $w - ($border_top/2))*_MPDFK, ($this->h-($y0 + ($border_top/2)))*_MPDFK));
21075 /*-- BORDER-RADIUS --*/
21076 }
21077 if ($brTL_H && $brTL_V ) {
21078 $this->_out(sprintf('%.3F %.3F l ',($x0 + ($border_top/2) + $brTL_H )*_MPDFK, ($this->h-($y0 + ($border_top/2)))*_MPDFK));
21079 $this->_out($this->_EllipseArc($x0 + $brTL_H, $y0 + $brTL_V, $brTL_H - $border_top/2 , $brTL_V - $border_top/2 , 2, 1));
21080 }
21081 else {
21082 /*-- END BORDER-RADIUS --*/
21083 $this->_out(sprintf('%.3F %.3F l ',($x0 + ($border_top/2))*_MPDFK, ($this->h-($y0 + ($border_top/2)))*_MPDFK));
21084 /*-- BORDER-RADIUS --*/
21085 }
21086 /*-- END BORDER-RADIUS --*/
21087 $this->_out('S');
21088
21089 // Reset Corners and Dash off
21090 $this->SetLineJoin(2);
21091 $this->SetLineCap(2);
21092 $this->SetDash();
21093 }
21094 }
21095 //if ($this->blk[$blvl]['border_bottom'] && $blockstate != 1) {
21096 // Reinstate line above for dotted line divider when block border crosses a page
21097 if ($this->blk[$blvl]['border_bottom'] && $blockstate != 1 && $divider != 'pagebottom') {
21098 $tbd = $this->blk[$blvl]['border_bottom'];
21099 if (isset($tbd['s']) && $tbd['s']) {
21100 $this->_setBorderLine($tbd);
21101 if ($tbd['style']=='dotted' || $tbd['style']=='dashed') { $this->_setDashBorder($tbd['style'],$divider,$continuingpage,'B'); }
21102 /*-- BORDER-RADIUS --*/
21103 else if (($brBL_V && $brBL_H) || ($brBR_V && $brBR_H)) {
21104 $this->SetLineJoin(0);
21105 $this->SetLineCap(0);
21106 }
21107 if ($brBL_H && $brBL_V) {
21108 $this->_out($this->_EllipseArc($x0 + $brBL_H, $y0 + $h - $brBL_V, $brBL_H - $border_bottom/2 , $brBL_V - $border_bottom/2 , 3, 2, true));
21109 }
21110 else {
21111 /*-- END BORDER-RADIUS --*/
21112 $this->_out(sprintf('%.3F %.3F m ',($x0 + ($border_bottom/2))*_MPDFK, ($this->h-($y0 + $h - ($border_bottom/2)))*_MPDFK));
21113 /*-- BORDER-RADIUS --*/
21114 }
21115 if ($brBR_H && $brBR_V ) {
21116 $this->_out(sprintf('%.3F %.3F l ',($x0 + $w - ($border_bottom/2) - $brBR_H )*_MPDFK, ($this->h-($y0 + $h - ($border_bottom/2)))*_MPDFK));
21117 $this->_out($this->_EllipseArc($x0 + $w - $brBR_H, $y0 + $h - $brBR_V, $brBR_H - $border_bottom/2 , $brBR_V - $border_bottom/2 , 4, 1));
21118 }
21119 else {
21120 /*-- END BORDER-RADIUS --*/
21121 $this->_out(sprintf('%.3F %.3F l ',($x0 + $w - ($border_bottom/2) )*_MPDFK, ($this->h-($y0 + $h - ($border_bottom/2)))*_MPDFK));
21122 /*-- BORDER-RADIUS --*/
21123 }
21124 /*-- END BORDER-RADIUS --*/
21125 $this->_out('S');
21126
21127 // Reset Corners and Dash off
21128 $this->SetLineJoin(2);
21129 $this->SetLineCap(2);
21130 $this->SetDash();
21131 }
21132 }
21133 if ($this->blk[$blvl]['border_left']) {
21134 $tbd = $this->blk[$blvl]['border_left'];
21135 if (isset($tbd['s']) && $tbd['s']) {
21136 $this->_setBorderLine($tbd);
21137 if ($tbd['style']=='dotted' || $tbd['style']=='dashed') { $this->_setDashBorder($tbd['style'],$divider,$continuingpage,'L'); }
21138 /*-- BORDER-RADIUS --*/
21139 else if (($brTL_V && $brTL_H) || ($brBL_V && $brBL_H)) {
21140 $this->SetLineJoin(0);
21141 $this->SetLineCap(0);
21142 }
21143 if ($brTL_V && $brTL_H) {
21144 $this->_out($this->_EllipseArc($x0 + $brTL_H, $y0 + $brTL_V, $brTL_H - $border_left/2 , $brTL_V - $border_left/2, 2, 2, true));
21145 }
21146 else {
21147 /*-- END BORDER-RADIUS --*/
21148 $this->_out(sprintf('%.3F %.3F m ',($x0 + ($border_left/2))*_MPDFK, ($this->h-($y0 + ($border_left/2)))*_MPDFK));
21149 /*-- BORDER-RADIUS --*/
21150 }
21151 if ($brBL_V && $brBL_H ) {
21152 $this->_out(sprintf('%.3F %.3F l ',($x0 + ($border_left/2))*_MPDFK, ($this->h-($y0 + $h - ($border_left/2)- $brBL_V) )*_MPDFK));
21153 $this->_out($this->_EllipseArc($x0 + $brBL_H, $y0 + $h - $brBL_V, $brBL_H - $border_left/2 , $brBL_V - $border_left/2, 3, 1));
21154 }
21155 else {
21156 /*-- END BORDER-RADIUS --*/
21157 $this->_out(sprintf('%.3F %.3F l ',($x0 + ($border_left/2))*_MPDFK, ($this->h-($y0 + $h - ($border_left/2)) )*_MPDFK));
21158 /*-- BORDER-RADIUS --*/
21159 }
21160 /*-- END BORDER-RADIUS --*/
21161 $this->_out('S');
21162
21163 // Reset Corners and Dash off
21164 $this->SetLineJoin(2);
21165 $this->SetLineCap(2);
21166 $this->SetDash();
21167 }
21168 }
21169 if ($this->blk[$blvl]['border_right']) {
21170 $tbd = $this->blk[$blvl]['border_right'];
21171 if (isset($tbd['s']) && $tbd['s']) {
21172 $this->_setBorderLine($tbd);
21173 if ($tbd['style']=='dotted' || $tbd['style']=='dashed') { $this->_setDashBorder($tbd['style'],$divider,$continuingpage,'R'); }
21174 /*-- BORDER-RADIUS --*/
21175 else if (($brTR_V && $brTR_H) || ($brBR_V && $brBR_H)) {
21176 $this->SetLineJoin(0);
21177 $this->SetLineCap(0);
21178 }
21179 if ($brBR_V && $brBR_H) {
21180 $this->_out($this->_EllipseArc($x0 + $w - $brBR_H, $y0 + $h - $brBR_V, $brBR_H - $border_right/2 , $brBR_V - $border_right/2, 4, 2, true));
21181 }
21182 else {
21183 /*-- END BORDER-RADIUS --*/
21184 $this->_out(sprintf('%.3F %.3F m ',($x0 + $w - ($border_right/2))*_MPDFK, ($this->h-($y0 + $h - ($border_right/2)))*_MPDFK));
21185 /*-- BORDER-RADIUS --*/
21186 }
21187 if ($brTR_V && $brTR_H ) {
21188 $this->_out(sprintf('%.3F %.3F l ',($x0 + $w - ($border_right/2))*_MPDFK, ($this->h-($y0 + ($border_right/2) + $brTR_V) )*_MPDFK));
21189 $this->_out($this->_EllipseArc($x0 + $w - $brTR_H, $y0 + $brTR_V, $brTR_H - $border_right/2 , $brTR_V - $border_right/2, 1, 1));
21190 }
21191 else {
21192 /*-- END BORDER-RADIUS --*/
21193 $this->_out(sprintf('%.3F %.3F l ',($x0 + $w - ($border_right/2))*_MPDFK, ($this->h-($y0 + ($border_right/2)) )*_MPDFK));
21194 /*-- BORDER-RADIUS --*/
21195 }
21196 /*-- END BORDER-RADIUS --*/
21197 $this->_out('S');
21198
21199 // Reset Corners and Dash off
21200 $this->SetLineJoin(2);
21201 $this->SetLineCap(2);
21202 $this->SetDash();
21203 }
21204 }
21205
21206 if (!$brset) { // not if border-radius used
21207 $tbcol = $this->ConvertColor(255);
21208 for($l=0; $l <= $blvl; $l++) {
21209 if ($this->blk[$l]['bgcolor']) {
21210 $tbcol = $this->blk[$l]['bgcolorarray'];
21211 }
21212 }
21213 }
21214 if ($this->blk[$blvl]['border_top'] && $divider != 'pagetop' && !$continuingpage) {
21215 $tbd = $this->blk[$blvl]['border_top'];
21216 if (isset($tbd['s']) && $tbd['s']) {
21217 if (!$brset && $tbd['style']=='double') {
21218 $this->SetLineWidth($tbd['w']/3);
21219 $this->SetDColor($tbcol);
21220 $this->_out(sprintf('%.3F %.3F m %.3F %.3F l S', ($x0 + $w - ($border_top/2))*_MPDFK, ($this->h-($y0 + ($border_top/2)))*_MPDFK, ($x0 + ($border_top/2))*_MPDFK, ($this->h-($y0 + ($border_top/2)))*_MPDFK ));
21221 }
21222 }
21223 }
21224 if ($this->blk[$blvl]['border_bottom'] && $blockstate != 1 && $divider != 'pagebottom') {
21225 $tbd = $this->blk[$blvl]['border_bottom'];
21226 if (isset($tbd['s']) && $tbd['s']) {
21227 if (!$brset && $tbd['style']=='double') {
21228 $this->SetLineWidth($tbd['w']/3);
21229 $this->SetDColor($tbcol);
21230 $this->_out(sprintf('%.3F %.3F m %.3F %.3F l S', ($x0 + ($border_bottom/2))*_MPDFK, ($this->h-($y0 + $h - ($border_bottom/2)))*_MPDFK, ($x0 + $w - ($border_bottom/2) )*_MPDFK, ($this->h-($y0 + $h - ($border_bottom/2)))*_MPDFK ));
21231 }
21232 }
21233 }
21234 if ($this->blk[$blvl]['border_left']) {
21235 $tbd = $this->blk[$blvl]['border_left'];
21236 if (isset($tbd['s']) && $tbd['s']) {
21237 if (!$brset && $tbd['style']=='double') {
21238 $this->SetLineWidth($tbd['w']/3);
21239 $this->SetDColor($tbcol);
21240 $this->_out(sprintf('%.3F %.3F m %.3F %.3F l S', ($x0 + ($border_left/2))*_MPDFK, ($this->h-($y0 + ($border_left/2)))*_MPDFK, ($x0 + ($border_left/2))*_MPDFK, ($this->h-($y0 + $h - ($border_left/2)) )*_MPDFK));
21241 }
21242 }
21243 }
21244 if ($this->blk[$blvl]['border_right']) {
21245 $tbd = $this->blk[$blvl]['border_right'];
21246 if (isset($tbd['s']) && $tbd['s']) {
21247 if (!$brset && $tbd['style']=='double') {
21248 $this->SetLineWidth($tbd['w']/3);
21249 $this->SetDColor($tbcol);
21250 $this->_out(sprintf('%.3F %.3F m %.3F %.3F l S', ($x0 + $w - ($border_right/2))*_MPDFK, ($this->h-($y0 + $h - ($border_right/2)))*_MPDFK, ($x0 + $w - ($border_right/2))*_MPDFK, ($this->h-($y0 + ($border_right/2)) )*_MPDFK));
21251 }
21252 }
21253 }
21254
21255
21256 $this->SetDash();
21257 $this->y = $save_y;
21258
21259
21260 // BACKGROUNDS are disabled in columns/kbt/headers - messes up the repositioning in printcolumnbuffer
21261 if ($this->ColActive || $this->kwt || $this->keep_block_together) { return ; }
21262
21263 $bgx0 = $x0;
21264 $bgx1 = $x1;
21265 $bgy0 = $y0;
21266 $bgy1 = $y1;
21267
21268 /*-- BORDER-RADIUS --*/
21269 // Defined br values represent the radius of the outer curve - need to take border-width/2 from each radius for drawing the borders
21270 if (isset($this->blk[$blvl]['background_clip']) && $this->blk[$blvl]['background_clip'] == 'padding-box') {
21271 $brbgTL_H = max(0, $brTL_H - $this->blk[$blvl]['border_left']['w']);
21272 $brbgTL_V = max(0, $brTL_V - $this->blk[$blvl]['border_top']['w']);
21273 $brbgTR_H = max(0, $brTR_H - $this->blk[$blvl]['border_right']['w']);
21274 $brbgTR_V = max(0, $brTR_V - $this->blk[$blvl]['border_top']['w']);
21275 $brbgBL_H = max(0, $brBL_H - $this->blk[$blvl]['border_left']['w']);
21276 $brbgBL_V = max(0, $brBL_V - $this->blk[$blvl]['border_bottom']['w']);
21277 $brbgBR_H = max(0, $brBR_H - $this->blk[$blvl]['border_right']['w']);
21278 $brbgBR_V = max(0, $brBR_V - $this->blk[$blvl]['border_bottom']['w']);
21279 $bgx0 += $this->blk[$blvl]['border_left']['w'];
21280 $bgx1 -= $this->blk[$blvl]['border_right']['w'];
21281 if ($this->blk[$blvl]['border_top'] && $divider != 'pagetop' && !$continuingpage) {
21282 $bgy0 += $this->blk[$blvl]['border_top']['w'];
21283 }
21284 if ($this->blk[$blvl]['border_bottom'] && $blockstate != 1 && $divider != 'pagebottom') {
21285 $bgy1 -= $this->blk[$blvl]['border_bottom']['w'];
21286 }
21287 }
21288 else {
21289 /*-- END BORDER-RADIUS --*/
21290 $brbgTL_H = $brTL_H;
21291 $brbgTL_V = $brTL_V;
21292 $brbgTR_H = $brTR_H;
21293 $brbgTR_V = $brTR_V;
21294 $brbgBL_H = $brBL_H;
21295 $brbgBL_V = $brBL_V;
21296 $brbgBR_H = $brBR_H;
21297 $brbgBR_V = $brBR_V;
21298 /*-- BORDER-RADIUS --*/
21299 }
21300 /*-- END BORDER-RADIUS --*/
21301
21302 // Set clipping path
21303 $s = ' q 0 w '; // Line width=0
21304 $s .= sprintf('%.3F %.3F m ', ($bgx0+$brbgTL_H )*_MPDFK, ($this->h-$bgy0)*_MPDFK); // start point TL before the arc
21305 /*-- BORDER-RADIUS --*/
21306 if ($brbgTL_H || $brbgTL_V) {
21307 $s .= $this->_EllipseArc($bgx0+$brbgTL_H, $bgy0+$brbgTL_V, $brbgTL_H , $brbgTL_V , 2); // segment 2 TL
21308 }
21309 /*-- END BORDER-RADIUS --*/
21310 $s .= sprintf('%.3F %.3F l ', ($bgx0)*_MPDFK, ($this->h-($bgy1-$brbgBL_V ))*_MPDFK); // line to BL
21311 /*-- BORDER-RADIUS --*/
21312 if ($brbgBL_H || $brbgBL_V) {
21313 $s .= $this->_EllipseArc($bgx0+$brbgBL_H, $bgy1-$brbgBL_V, $brbgBL_H , $brbgBL_V , 3); // segment 3 BL
21314 }
21315 /*-- END BORDER-RADIUS --*/
21316 $s .= sprintf('%.3F %.3F l ', ($bgx1-$brbgBR_H )*_MPDFK, ($this->h-($bgy1))*_MPDFK); // line to BR
21317 /*-- BORDER-RADIUS --*/
21318 if ($brbgBR_H || $brbgBR_V) {
21319 $s .= $this->_EllipseArc($bgx1-$brbgBR_H, $bgy1-$brbgBR_V, $brbgBR_H , $brbgBR_V , 4); // segment 4 BR
21320 }
21321 /*-- END BORDER-RADIUS --*/
21322 $s .= sprintf('%.3F %.3F l ', ($bgx1)*_MPDFK, ($this->h-($bgy0+$brbgTR_V))*_MPDFK); // line to TR
21323 /*-- BORDER-RADIUS --*/
21324 if ($brbgTR_H || $brbgTR_V) {
21325 $s .= $this->_EllipseArc($bgx1-$brbgTR_H, $bgy0+$brbgTR_V, $brbgTR_H , $brbgTR_V , 1); // segment 1 TR
21326 }
21327 /*-- END BORDER-RADIUS --*/
21328 $s .= sprintf('%.3F %.3F l ', ($bgx0+$brbgTL_H )*_MPDFK, ($this->h-$bgy0)*_MPDFK); // line to TL
21329
21330
21331 // mPDF 5.3.A1
21332 // Box Shadow
21333 $shadow = '';
21334 if (isset($this->blk[$blvl]['box_shadow']) && $this->blk[$blvl]['box_shadow'] && $h > 0) {
21335 foreach($this->blk[$blvl]['box_shadow'] AS $sh) {
21336 // Colors
21337 if ($sh['col']{0}==1) {
21338 $colspace = 'Gray';
21339 if ($sh['col']{2}==1) { $col1 = '1'.$sh['col'][1].'1'.$sh['col'][3]; }
21340 else { $col1 = '1'.$sh['col'][1].'1'.chr(100); }
21341 $col2 = '1'.$sh['col'][1].'1'.chr(0);
21342 }
21343 else if ($sh['col']{0}==4) { // CMYK
21344 $colspace = 'CMYK';
21345 $col1 = '6'.$sh['col'][1].$sh['col'][2].$sh['col'][3].$sh['col'][4].chr(100);
21346 $col2 = '6'.$sh['col'][1].$sh['col'][2].$sh['col'][3].$sh['col'][4].chr(0);
21347 }
21348 else if ($sh['col']{0}==5) { // RGBa
21349 $colspace = 'RGB';
21350 $col1 = '5'.$sh['col'][1].$sh['col'][2].$sh['col'][3].$sh['col'][4];
21351 $col2 = '5'.$sh['col'][1].$sh['col'][2].$sh['col'][3].chr(0);
21352 }
21353 else if ($sh['col']{0}==6) { // CMYKa
21354 $colspace = 'CMYK';
21355 $col1 = '6'.$sh['col'][1].$sh['col'][2].$sh['col'][3].$sh['col'][4].$sh['col'][5];
21356 $col2 = '6'.$sh['col'][1].$sh['col'][2].$sh['col'][3].$sh['col'][4].chr(0);
21357 }
21358 else {
21359 $colspace = 'RGB';
21360 $col1 = '5'.$sh['col'][1].$sh['col'][2].$sh['col'][3].chr(100);
21361 $col2 = '5'.$sh['col'][1].$sh['col'][2].$sh['col'][3].chr(0);
21362 }
21363
21364 // Use clipping path as set above (and rectangle around page) to clip area outside box
21365 $shadow .= $s; // Use the clipping path with W*
21366 $shadow .= sprintf('0 %.3F m %.3F %.3F l ', $this->h*_MPDFK, $this->w*_MPDFK, $this->h*_MPDFK);
21367 $shadow .= sprintf('%.3F 0 l 0 0 l 0 %.3F l ', $this->w*_MPDFK, $this->h*_MPDFK);
21368 $shadow .= 'W n'."\n";
21369
21370 $sh['blur'] = abs($sh['blur']); // cannot have negative blur value
21371 // Ensure spread/blur do not make effective shadow width/height < 0
21372 // Could do more complex things but this just adjusts spread value
21373 if (-$sh['spread'] + $sh['blur']/2 > min($w/2, $h/2)) {
21374 $sh['spread'] = $sh['blur']/2 - min($w/2, $h/2) + 0.01;
21375 }
21376 // Shadow Offset
21377 if ($sh['x'] || $sh['y']) $shadow .= sprintf(' q 1 0 0 1 %.4F %.4F cm', $sh['x']*_MPDFK, -$sh['y']*_MPDFK)."\n";
21378
21379 // Set path for INNER shadow
21380 $shadow .= ' q 0 w ';
21381 $shadow .= $this->SetFColor($col1, true)."\n";
21382 if ($col1{0}==5 && ord($col1{4})<100) { // RGBa
21383 $shadow .= $this->SetAlpha(ord($col1{4})/100, 'Normal', true, 'F')."\n";
21384 }
21385 else if ($col1{0}==6 && ord($col1{5})<100) { // CMYKa
21386 $shadow .= $this->SetAlpha(ord($col1{5})/100, 'Normal', true, 'F')."\n";
21387 }
21388 else if ($col1{0}==1 && $col1{2}==1 && ord($col1{3})<100) { // Gray
21389 $shadow .= $this->SetAlpha(ord($col1{3})/100, 'Normal', true, 'F')."\n";
21390 }
21391
21392 // Blur edges
21393 $mag = 0.551784; // Bezier Control magic number for 4-part spline for circle/ellipse
21394 $mag2 = 0.551784; // Bezier Control magic number to fill in edge of blurred rectangle
21395 $d1 = $sh['spread']+$sh['blur']/2;
21396 $d2 = $sh['spread']-$sh['blur']/2;
21397 $bl = $sh['blur'];
21398 $x00 = $x0 - $d1;
21399 $y00 = $y0 - $d1;
21400 $w00 = $w + $d1*2;
21401 $h00 = $h + $d1*2;
21402
21403 // If any border-radius is greater width-negative spread(inner edge), ignore radii for shadow or screws up
21404 $flatten = false;
21405 if (max($brbgTR_H, $brbgTL_H, $brbgBR_H, $brbgBL_H) >= $w+$d2) { $flatten = true; }
21406 if (max($brbgTR_V, $brbgTL_V, $brbgBR_V, $brbgBL_V) >= $h+$d2) { $flatten = true; }
21407
21408
21409 // TOP RIGHT corner
21410 $p1x = $x00+$w00-$d1-$brbgTR_H; $p1c2x = $p1x +($d2+$brbgTR_H)*$mag;
21411 $p1y = $y00+$bl;
21412 $p2x = $x00+$w00-$d1-$brbgTR_H; $p2c2x = $p2x + ($d1+$brbgTR_H)*$mag;
21413 $p2y = $y00; $p2c1y = $p2y + $bl/2;
21414 $p3x = $x00+$w00; $p3c2x = $p3x - $bl/2;
21415 $p3y = $y00+$d1+$brbgTR_V; $p3c1y = $p3y - ($d1+$brbgTR_V)*$mag;
21416 $p4x = $x00+$w00-$bl;
21417 $p4y = $y00+$d1+$brbgTR_V; $p4c2y = $p4y - ($d2+$brbgTR_V)*$mag;
21418 if (-$d2 > min($brbgTR_H, $brbgTR_V) || $flatten) {
21419 $p1x = $x00+$w00-$bl; $p1c2x = $p1x;
21420 $p2x = $x00+$w00-$bl; $p2c2x = $p2x + $bl*$mag2;
21421 $p3y = $y00+$bl; $p3c1y = $p3y - $bl*$mag2;
21422 $p4y = $y00+$bl; $p4c2y = $p4y ;
21423 }
21424
21425 $shadow .= sprintf('%.3F %.3F m ', ($p1x )*_MPDFK, ($this->h-($p1y ))*_MPDFK);
21426 $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);
21427 $patch_array[0]['f']=0;
21428 $patch_array[0]['points']=array($p1x,$p1y, $p1x,$p1y,
21429 $p2x,$p2c1y, $p2x,$p2y, $p2c2x,$p2y,
21430 $p3x,$p3c1y, $p3x,$p3y, $p3c2x,$p3y,
21431 $p4x,$p4y, $p4x,$p4y, $p4x,$p4c2y,
21432 $p1c2x,$p1y);
21433 $patch_array[0]['colors'] = array($col1,$col2,$col2,$col1);
21434
21435
21436 // RIGHT
21437 $p1x = $x00+$w00; // control point only matches p3 preceding
21438 $p1y = $y00+$d1+$brbgTR_V;
21439 $p2x = $x00+$w00-$bl; // control point only matches p4 preceding
21440 $p2y = $y00+$d1+$brbgTR_V;
21441 $p3x = $x00+$w00-$bl;
21442 $p3y = $y00+$h00-$d1-$brbgBR_V;
21443 $p4x = $x00+$w00; $p4c1x = $p4x-$bl/2;
21444 $p4y = $y00+$h00-$d1-$brbgBR_V;
21445 if (-$d2 > min($brbgTR_H, $brbgTR_V) || $flatten) {
21446 $p1y = $y00+$bl;
21447 $p2y = $y00+$bl;
21448 }
21449 if (-$d2 > min($brbgBR_H, $brbgBR_V) || $flatten) {
21450 $p3y = $y00+$h00-$bl;
21451 $p4y = $y00+$h00-$bl;
21452 }
21453
21454 $shadow .= sprintf('%.3F %.3F l ', ($p3x )*_MPDFK, ($this->h-($p3y ))*_MPDFK);
21455 $patch_array[1]['f']=2;
21456 $patch_array[1]['points']=array($p2x,$p2y,
21457 $p3x,$p3y, $p3x,$p3y, $p3x,$p3y,
21458 $p4c1x,$p4y, $p4x,$p4y, $p4x,$p4y,
21459 $p1x,$p1y);
21460 $patch_array[1]['colors'] = array($col1,$col2);
21461
21462
21463 // BOTTOM RIGHT corner
21464 $p1x = $x00+$w00-$bl; // control points only matches p3 preceding
21465 $p1y = $y00+$h00-$d1-$brbgBR_V; $p1c2y = $p1y + ($d2+$brbgBR_V)*$mag;
21466 $p2x = $x00+$w00; // control point only matches p4 preceding
21467 $p2y = $y00+$h00-$d1-$brbgBR_V; $p2c2y = $p2y + ($d1+$brbgBR_V)*$mag;
21468 $p3x = $x00+$w00-$d1-$brbgBR_H; $p3c1x = $p3x + ($d1+$brbgBR_H)*$mag;
21469 $p3y = $y00+$h00; $p3c2y = $p3y - $bl/2;
21470 $p4x = $x00+$w00-$d1-$brbgBR_H; $p4c2x = $p4x + ($d2+$brbgBR_H)*$mag;
21471 $p4y = $y00+$h00-$bl;
21472
21473 if (-$d2 > min($brbgBR_H, $brbgBR_V) || $flatten) {
21474 $p1y = $y00+$h00-$bl; $p1c2y = $p1y;
21475 $p2y = $y00+$h00-$bl; $p2c2y = $p2y + $bl*$mag2;
21476 $p3x = $x00+$w00-$bl; $p3c1x = $p3x + $bl*$mag2;
21477 $p4x = $x00+$w00-$bl; $p4c2x = $p4x;
21478 }
21479
21480 $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);
21481 $patch_array[2]['f']=2;
21482 $patch_array[2]['points']=array($p2x,$p2c2y,
21483 $p3c1x,$p3y, $p3x,$p3y, $p3x,$p3c2y,
21484 $p4x,$p4y, $p4x,$p4y, $p4c2x,$p4y,
21485 $p1x,$p1c2y);
21486 $patch_array[2]['colors'] = array($col2,$col1);
21487
21488
21489
21490 // BOTTOM
21491 $p1x = $x00+$w00-$d1-$brbgBR_H; // control point only matches p3 preceding
21492 $p1y = $y00+$h00;
21493 $p2x = $x00+$w00-$d1-$brbgBR_H; // control point only matches p4 preceding
21494 $p2y = $y00+$h00-$bl;
21495 $p3x = $x00+$d1+$brbgBL_H;
21496 $p3y = $y00+$h00-$bl;
21497 $p4x = $x00+$d1+$brbgBL_H;
21498 $p4y = $y00+$h00; $p4c1y = $p4y - $bl/2;
21499
21500 if (-$d2 > min($brbgBR_H, $brbgBR_V) || $flatten) {
21501 $p1x = $x00+$w00-$bl;
21502 $p2x = $x00+$w00-$bl;
21503 }
21504 if (-$d2 > min($brbgBL_H, $brbgBL_V) || $flatten) {
21505 $p3x = $x00+$bl;
21506 $p4x = $x00+$bl;
21507 }
21508
21509 $shadow .= sprintf('%.3F %.3F l ', ($p3x )*_MPDFK, ($this->h-($p3y ))*_MPDFK);
21510 $patch_array[3]['f']=2;
21511 $patch_array[3]['points']=array($p2x,$p2y,
21512 $p3x,$p3y, $p3x,$p3y, $p3x,$p3y,
21513 $p4x,$p4c1y, $p4x,$p4y, $p4x,$p4y,
21514 $p1x,$p1y);
21515 $patch_array[3]['colors'] = array($col1,$col2);
21516
21517 // BOTTOM LEFT corner
21518 $p1x = $x00+$d1+$brbgBL_H; $p1c2x = $p1x - ($d2+$brbgBL_H)*$mag; // control points only matches p3 preceding
21519 $p1y = $y00+$h00-$bl;
21520 $p2x = $x00+$d1+$brbgBL_H; $p2c2x = $p2x - ($d1+$brbgBL_H)*$mag; // control point only matches p4 preceding
21521 $p2y = $y00+$h00;
21522 $p3x = $x00; $p3c2x = $p3x + $bl/2;
21523 $p3y = $y00+$h00-$d1-$brbgBL_V; $p3c1y = $p3y + ($d1+$brbgBL_V)*$mag;
21524 $p4x = $x00+$bl;
21525 $p4y = $y00+$h00-$d1-$brbgBL_V; $p4c2y = $p4y + ($d2+$brbgBL_V)*$mag;
21526 if (-$d2 > min($brbgBL_H, $brbgBL_V) || $flatten) {
21527 $p1x = $x00+$bl; $p1c2x = $p1x;
21528 $p2x = $x00+$bl; $p2c2x = $p2x - $bl*$mag2;
21529 $p3y = $y00+$h00-$bl; $p3c1y = $p3y + $bl*$mag2;
21530 $p4y = $y00+$h00-$bl; $p4c2y = $p4y;
21531 }
21532
21533 $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);
21534 $patch_array[4]['f']=2;
21535 $patch_array[4]['points']=array($p2c2x,$p2y,
21536 $p3x,$p3c1y, $p3x,$p3y, $p3c2x,$p3y,
21537 $p4x,$p4y, $p4x,$p4y, $p4x,$p4c2y,
21538 $p1c2x,$p1y);
21539 $patch_array[4]['colors'] = array($col2,$col1);
21540
21541
21542 // LEFT - joins on the right (C3-C4 of previous): f = 2
21543 $p1x = $x00; // control point only matches p3 preceding
21544 $p1y = $y00+$h00-$d1-$brbgBL_V;
21545 $p2x = $x00+$bl; // control point only matches p4 preceding
21546 $p2y = $y00+$h00-$d1-$brbgBL_V;
21547 $p3x = $x00+$bl;
21548 $p3y = $y00+$d1+$brbgTL_V;
21549 $p4x = $x00; $p4c1x = $p4x + $bl/2;
21550 $p4y = $y00+$d1+$brbgTL_V;
21551 if (-$d2 > min($brbgBL_H, $brbgBL_V) || $flatten) {
21552 $p1y = $y00+$h00-$bl;
21553 $p2y = $y00+$h00-$bl;
21554 }
21555 if (-$d2 > min($brbgTL_H, $brbgTL_V) || $flatten) {
21556 $p3y = $y00+$bl;
21557 $p4y = $y00+$bl;
21558 }
21559
21560 $shadow .= sprintf('%.3F %.3F l ', ($p3x )*_MPDFK, ($this->h-($p3y ))*_MPDFK);
21561 $patch_array[5]['f']=2;
21562 $patch_array[5]['points']=array($p2x,$p2y,
21563 $p3x,$p3y, $p3x,$p3y, $p3x,$p3y,
21564 $p4c1x,$p4y, $p4x,$p4y, $p4x,$p4y,
21565 $p1x,$p1y);
21566 $patch_array[5]['colors'] = array($col1,$col2);
21567
21568 // TOP LEFT corner
21569 $p1x = $x00+$bl; // control points only matches p3 preceding
21570 $p1y = $y00+$d1+$brbgTL_V; $p1c2y = $p1y - ($d2+$brbgTL_V)*$mag;
21571 $p2x = $x00; // control point only matches p4 preceding
21572 $p2y = $y00+$d1+$brbgTL_V; $p2c2y = $p2y - ($d1+$brbgTL_V)*$mag;
21573 $p3x = $x00+$d1+$brbgTL_H; $p3c1x = $p3x - ($d1+$brbgTL_H)*$mag;
21574 $p3y = $y00; $p3c2y = $p3y + $bl/2;
21575 $p4x = $x00+$d1+$brbgTL_H; $p4c2x = $p4x - ($d2+$brbgTL_H)*$mag;
21576 $p4y = $y00+$bl;
21577
21578 if (-$d2 > min($brbgTL_H, $brbgTL_V) || $flatten) {
21579 $p1y = $y00+$bl; $p1c2y = $p1y;
21580 $p2y = $y00+$bl; $p2c2y = $p2y - $bl*$mag2;
21581 $p3x = $x00+$bl; $p3c1x = $p3x - $bl*$mag2;
21582 $p4x = $x00+$bl; $p4c2x = $p4x ;
21583 }
21584
21585 $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);
21586 $patch_array[6]['f']=2;
21587 $patch_array[6]['points']=array($p2x,$p2c2y,
21588 $p3c1x,$p3y, $p3x,$p3y, $p3x,$p3c2y,
21589 $p4x,$p4y, $p4x,$p4y, $p4c2x,$p4y,
21590 $p1x,$p1c2y);
21591 $patch_array[6]['colors'] = array($col2,$col1);
21592
21593
21594 // TOP - joins on the right (C3-C4 of previous): f = 2
21595 $p1x = $x00+$d1+$brbgTL_H; // control point only matches p3 preceding
21596 $p1y = $y00;
21597 $p2x = $x00+$d1+$brbgTL_H; // control point only matches p4 preceding
21598 $p2y = $y00+$bl;
21599 $p3x = $x00+$w00-$d1-$brbgTR_H;
21600 $p3y = $y00+$bl;
21601 $p4x = $x00+$w00-$d1-$brbgTR_H;
21602 $p4y = $y00; $p4c1y = $p4y + $bl/2;
21603 if (-$d2 > min($brbgTL_H, $brbgTL_V) || $flatten) {
21604 $p1x = $x00+$bl;
21605 $p2x = $x00+$bl;
21606 }
21607 if (-$d2 > min($brbgTR_H, $brbgTR_V) || $flatten) {
21608 $p3x = $x00+$w00-$bl;
21609 $p4x = $x00+$w00-$bl;
21610 }
21611
21612 $shadow .= sprintf('%.3F %.3F l ', ($p3x )*_MPDFK, ($this->h-($p3y ))*_MPDFK);
21613 $patch_array[7]['f']=2;
21614 $patch_array[7]['points']=array($p2x,$p2y,
21615 $p3x,$p3y, $p3x,$p3y, $p3x,$p3y,
21616 $p4x,$p4c1y, $p4x,$p4y, $p4x,$p4y,
21617 $p1x,$p1y);
21618 $patch_array[7]['colors'] = array($col1,$col2);
21619
21620 $shadow .= ' h f Q '."\n"; // Close path and Fill the inner solid shadow
21621
21622 if ($bl) $shadow .= $this->grad->CoonsPatchMesh($x00,$y00,$w00,$h00,$patch_array,$x00,$x00+$w00,$y00,$y00+$h00, $colspace, true);
21623
21624 if ($sh['x'] || $sh['y']) $shadow .= ' Q'."\n"; // Shadow Offset
21625 $shadow .= ' Q'."\n"; // Ends path no-op & Sets the clipping path
21626
21627 }
21628 }
21629
21630 $s .= ' W n '; // Ends path no-op & Sets the clipping path
21631
21632 if ($this->blk[$blvl]['bgcolor']) {
21633 $this->pageBackgrounds[$blvl][] = array('x'=>$x0, 'y'=>$y0, 'w'=>$w, 'h'=>$h, 'col'=>$this->blk[$blvl]['bgcolorarray'], 'clippath'=>$s, 'visibility'=>$this->visibility, 'shadow'=>$shadow); // mPDF 5.3.42 // mPDF 5.3.A1
21634 }
21635 // mPDF 5.3.A1
21636 else if ($shadow) {
21637 $this->pageBackgrounds[$blvl][] = array('shadowonly'=>true, 'col'=>'', 'clippath'=>'', 'visibility'=>$this->visibility, 'shadow'=>$shadow); // mPDF 5.3.42 // mPDF 5.3.A1
21638 }
21639
21640 /*-- BACKGROUNDS --*/
21641 if (isset($this->blk[$blvl]['gradient'])) {
21642 $g = $this->grad->parseBackgroundGradient($this->blk[$blvl]['gradient']);
21643 if ($g) {
21644 $gx = $x0;
21645 $gy = $y0;
21646 $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); // mPDF 5.3.42
21647 }
21648 }
21649
21650 if (isset($this->blk[$blvl]['background-image'])) {
21651 if ($this->blk[$blvl]['background-image']['gradient'] && preg_match('/(-moz-)*(repeating-)*(linear|radial)-gradient/', $this->blk[$blvl]['background-image']['gradient'] )) {
21652 $g = $this->grad->parseMozGradient( $this->blk[$blvl]['background-image']['gradient'] );
21653 if ($g) {
21654 $gx = $x0;
21655 $gy = $y0;
21656 $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); // mPDF 5.3.42
21657 }
21658 }
21659 else {
21660 $image_id = $this->blk[$blvl]['background-image']['image_id'];
21661 $orig_w = $this->blk[$blvl]['background-image']['orig_w'];
21662 $orig_h = $this->blk[$blvl]['background-image']['orig_h'];
21663 $x_pos = $this->blk[$blvl]['background-image']['x_pos'];
21664 $y_pos = $this->blk[$blvl]['background-image']['y_pos'];
21665 $x_repeat = $this->blk[$blvl]['background-image']['x_repeat'];
21666 $y_repeat = $this->blk[$blvl]['background-image']['y_repeat'];
21667 $resize = $this->blk[$blvl]['background-image']['resize'];
21668 $opacity = $this->blk[$blvl]['background-image']['opacity'];
21669 $itype = $this->blk[$blvl]['background-image']['itype'];
21670 $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); // mPDF 5.3.42
21671 }
21672 }
21673 /*-- END BACKGROUNDS --*/
21674
21675 // Float DIV
21676 $this->blk[$blvl]['bb_painted'][$this->page] = true;
21677
21678 }
21679
21680 /*-- BORDER-RADIUS --*/
21681
21682 function _EllipseArc($x0, $y0, $rx, $ry, $seg = 1, $part=false, $start=false) { // Anticlockwise segment 1-4 TR-TL-BL-BR (part=1 or 2)
21683 $s = '';
21684 if ($rx<0) { $rx = 0; }
21685 if ($ry<0) { $ry = 0; }
21686 $rx *= _MPDFK;
21687 $ry *= _MPDFK;
21688 $astart = 0;
21689 if ($seg == 1) { // Top Right
21690 $afinish = 90;
21691 $nSeg = 4;
21692 }
21693 else if ($seg == 2) { // Top Left
21694 $afinish = 180;
21695 $nSeg = 8;
21696 }
21697 else if ($seg == 3) { // Bottom Left
21698 $afinish = 270;
21699 $nSeg = 12;
21700 }
21701 else { // Bottom Right
21702 $afinish = 360;
21703 $nSeg = 16;
21704 }
21705 $astart = deg2rad((float) $astart);
21706 $afinish = deg2rad((float) $afinish);
21707 $totalAngle = $afinish - $astart;
21708 $dt = $totalAngle / $nSeg; // segment angle
21709 $dtm = $dt/3;
21710 $x0 *= _MPDFK;
21711 $y0 = ($this->h - $y0) * _MPDFK;
21712 $t1 = $astart;
21713 $a0 = $x0 + ($rx * cos($t1));
21714 $b0 = $y0 + ($ry * sin($t1));
21715 $c0 = -$rx * sin($t1);
21716 $d0 = $ry * cos($t1);
21717 $op = false;
21718 for ($i = 1; $i <= $nSeg; $i++) {
21719 // Draw this bit of the total curve
21720 $t1 = ($i * $dt) + $astart;
21721 $a1 = $x0 + ($rx * cos($t1));
21722 $b1 = $y0 + ($ry * sin($t1));
21723 $c1 = -$rx * sin($t1);
21724 $d1 = $ry * cos($t1);
21725 if ($i>($nSeg-4) && (!$part || ($part == 1 && $i<=$nSeg-2) || ($part == 2 && $i>$nSeg-2))) {
21726 if ($start && !$op) {
21727 $s .= sprintf('%.3F %.3F m ', $a0, $b0);
21728 }
21729 $s .= sprintf('%.3F %.3F %.3F %.3F %.3F %.3F c ', ($a0 + ($c0 * $dtm)), ($b0 + ($d0 * $dtm)), ($a1 - ($c1 * $dtm)) , ($b1 - ($d1 * $dtm)), $a1 , $b1 );
21730 $op = true;
21731 }
21732 $a0 = $a1;
21733 $b0 = $b1;
21734 $c0 = $c1;
21735 $d0 = $d1;
21736 }
21737 return $s;
21738 }
21739 /*-- END BORDER-RADIUS --*/
21740
21741
21742
21743 function PaintDivLnBorder($state=0,$blvl=0,$h) {
21744 // $state = 0 normal; 1 top; 2 bottom; 3 top and bottom
21745
21746 $this->ColDetails[$this->CurrCol]['bottom_margin'] = $this->y + $h;
21747
21748 $save_y = $this->y;
21749
21750 $w = $this->blk[$blvl]['width'];
21751 $x0 = $this->x; // left
21752 $y0 = $this->y; // top
21753 $x1 = $this->x + $w; // bottom
21754 $y1 = $this->y + $h; // bottom
21755
21756 if ($this->blk[$blvl]['border_top'] && ($state==1 || $state==3)) {
21757 $tbd = $this->blk[$blvl]['border_top'];
21758 if (isset($tbd['s']) && $tbd['s']) {
21759 $this->_setBorderLine($tbd);
21760 $this->y = $y0 + ($tbd['w']/2);
21761 if ($tbd['style']=='dotted' || $tbd['style']=='dashed') { $this->_setDashBorder($tbd['style'],'',$continuingpage,'T'); }
21762 $this->Line($x0 + ($tbd['w']/2) , $this->y , $x0 + $w - ($tbd['w']/2), $this->y);
21763 $this->y += $tbd['w'];
21764 // Reset Corners and Dash off
21765 $this->SetLineJoin(2);
21766 $this->SetLineCap(2);
21767 $this->SetDash();
21768 }
21769 }
21770 if ($this->blk[$blvl]['border_left']) {
21771 $tbd = $this->blk[$blvl]['border_left'];
21772 if (isset($tbd['s']) && $tbd['s']) {
21773 $this->_setBorderLine($tbd);
21774 $this->y = $y0 + ($tbd['w']/2);
21775 if ($tbd['style']=='dotted' || $tbd['style']=='dashed') { $this->_setDashBorder($tbd['style'],'',$continuingpage,'L'); }
21776 $this->Line($x0 + ($tbd['w']/2), $this->y, $x0 + ($tbd['w']/2), $y0 + $h -($tbd['w']/2));
21777 $this->y += $tbd['w'];
21778 // Reset Corners and Dash off
21779 $this->SetLineJoin(2);
21780 $this->SetLineCap(2);
21781 $this->SetDash();
21782 }
21783 }
21784 if ($this->blk[$blvl]['border_right']) {
21785 $tbd = $this->blk[$blvl]['border_right'];
21786 if (isset($tbd['s']) && $tbd['s']) {
21787 $this->_setBorderLine($tbd);
21788 $this->y = $y0 + ($tbd['w']/2);
21789 if ($tbd['style']=='dotted' || $tbd['style']=='dashed') { $this->_setDashBorder($tbd['style'],'',$continuingpage,'R'); }
21790 $this->Line($x0 + $w - ($tbd['w']/2), $this->y, $x0 + $w - ($tbd['w']/2), $y0 + $h - ($tbd['w']/2));
21791 $this->y += $tbd['w'];
21792 // Reset Corners and Dash off
21793 $this->SetLineJoin(2);
21794 $this->SetLineCap(2);
21795 $this->SetDash();
21796 }
21797 }
21798 if ($this->blk[$blvl]['border_bottom'] && $state > 1) {
21799 $tbd = $this->blk[$blvl]['border_bottom'];
21800 if (isset($tbd['s']) && $tbd['s']) {
21801 $this->_setBorderLine($tbd);
21802 $this->y = $y0 + $h - ($tbd['w']/2);
21803 if ($tbd['style']=='dotted' || $tbd['style']=='dashed') { $this->_setDashBorder($tbd['style'],'',$continuingpage,'B'); }
21804 $this->Line($x0 + ($tbd['w']/2) , $this->y, $x0 + $w - ($tbd['w']/2), $this->y);
21805 $this->y += $tbd['w'];
21806 // Reset Corners and Dash off
21807 $this->SetLineJoin(2);
21808 $this->SetLineCap(2);
21809 $this->SetDash();
21810 }
21811 }
21812 $this->SetDash();
21813 $this->y = $save_y;
21814 }
21815
21816
21817 function PaintImgBorder($objattr,$is_table) {
21818 // Borders are disabled in columns - messes up the repositioning in printcolumnbuffer
21819 if ($this->ColActive) { return ; } // *COLUMNS*
21820 if ($is_table) { $k = $this->shrin_k; } else { $k = 1; }
21821 $h = (isset($objattr['BORDER-HEIGHT']) ? $objattr['BORDER-HEIGHT'] : 0);
21822 $w = (isset($objattr['BORDER-WIDTH']) ? $objattr['BORDER-WIDTH'] : 0);
21823 $x0 = (isset($objattr['BORDER-X']) ? $objattr['BORDER-X'] : 0);
21824 $y0 = (isset($objattr['BORDER-Y']) ? $objattr['BORDER-Y'] : 0);
21825
21826 // BORDERS
21827 if ($objattr['border_top']) {
21828 $tbd = $objattr['border_top'];
21829 if (!empty($tbd['s'])) {
21830 $this->_setBorderLine($tbd,$k);
21831 if ($tbd['style']=='dotted' || $tbd['style']=='dashed') { $this->_setDashBorder($tbd['style'],'','','T'); }
21832 $this->Line($x0, $y0, $x0 + $w, $y0);
21833 // Reset Corners and Dash off
21834 $this->SetLineJoin(2);
21835 $this->SetLineCap(2);
21836 $this->SetDash();
21837 }
21838 }
21839 if ($objattr['border_left']) {
21840 $tbd = $objattr['border_left'];
21841 if (!empty($tbd['s'])) {
21842 $this->_setBorderLine($tbd,$k);
21843 if ($tbd['style']=='dotted' || $tbd['style']=='dashed') { $this->_setDashBorder($tbd['style'],'','','L'); }
21844 $this->Line($x0, $y0, $x0, $y0 + $h);
21845 // Reset Corners and Dash off
21846 $this->SetLineJoin(2);
21847 $this->SetLineCap(2);
21848 $this->SetDash();
21849 }
21850 }
21851 if ($objattr['border_right']) {
21852 $tbd = $objattr['border_right'];
21853 if (!empty($tbd['s'])) {
21854 $this->_setBorderLine($tbd,$k);
21855 if ($tbd['style']=='dotted' || $tbd['style']=='dashed') { $this->_setDashBorder($tbd['style'],'','','R'); }
21856 $this->Line($x0 + $w, $y0, $x0 + $w, $y0 + $h);
21857 // Reset Corners and Dash off
21858 $this->SetLineJoin(2);
21859 $this->SetLineCap(2);
21860 $this->SetDash();
21861 }
21862 }
21863 if ($objattr['border_bottom']) {
21864 $tbd = $objattr['border_bottom'];
21865 if (!empty($tbd['s'])) {
21866 $this->_setBorderLine($tbd,$k);
21867 if ($tbd['style']=='dotted' || $tbd['style']=='dashed') { $this->_setDashBorder($tbd['style'],'','','B'); }
21868 $this->Line($x0, $y0 + $h, $x0 + $w, $y0 + $h);
21869 // Reset Corners and Dash off
21870 $this->SetLineJoin(2);
21871 $this->SetLineCap(2);
21872 $this->SetDash();
21873 }
21874 }
21875 $this->SetDash();
21876 $this->SetAlpha(1);
21877 }
21878
21879 /*-- END HTML-CSS --*/
21880
21881
21882
21883
21884 function Reset() {
21885 $this->SetTColor($this->ConvertColor(0));
21886 $this->SetDColor($this->ConvertColor(0));
21887 $this->SetFColor($this->ConvertColor(255));
21888 $this->SetAlpha(1);
21889 $this->colorarray = ''; // mPDF 5.3.76
21890
21891 $this->spanbgcolorarray = ''; // mPDF 5.3.76
21892 $this->spanbgcolor = false;
21893 // mPDF 5.3.61
21894 $this->spanborder = false;
21895 $this->spanborddet = array();
21896
21897 $this->ResetStyles();
21898
21899 $this->HREF = '';
21900 $this->outlineparam = array();
21901 $this->outline_on = false;
21902 $this->SetTextOutline(false);
21903
21904 $this->SUP = false;
21905 $this->SUB = false;
21906 $this->strike = false;
21907 $this->textshadow = ''; // mPDF 5.3.A2
21908
21909 $this->SetFont($this->default_font,'',0,false);
21910 $this->SetFontSize($this->default_font_size,false);
21911
21912 $this->currentfontfamily = '';
21913 $this->currentfontsize = '';
21914
21915 /*-- TABLES --*/
21916 if ($this->tableLevel) {
21917 $this->SetLineHeight('',$this->table_lineheight); // *TABLES*
21918 }
21919 else
21920 /*-- END TABLES --*/
21921 /*-- LISTS --*/
21922
21923 if ($this->listlvl && $this->list_lineheight[$this->listlvl][$this->bulletarray['occur']]) {
21924 $this->SetLineHeight('',$this->list_lineheight[$this->listlvl][$this->bulletarray['occur']]); // sets default line height
21925 }
21926 else
21927 /*-- END LISTS --*/
21928 if (isset($this->blk[$this->blklvl]['line_height']) && $this->blk[$this->blklvl]['line_height']) {
21929 $this->SetLineHeight('',$this->blk[$this->blklvl]['line_height']); // sets default line height
21930 }
21931
21932 $this->toupper = false;
21933 $this->tolower = false;
21934 $this->kerning = false;
21935 $this->lSpacingCSS = '';
21936 $this->wSpacingCSS = '';
21937 $this->fixedlSpacing = false;
21938 $this->minwSpacing = 0;
21939 $this->capitalize = false;
21940 $this->SetDash(); //restore to no dash
21941 $this->dash_on = false;
21942 $this->dotted_on = false;
21943 $this->divwidth = 0;
21944 $this->divheight = 0;
21945 $this->divalign = '';
21946 $this->divrevert = false;
21947 $this->oldy = -1;
21948
21949 $bodystyle = array();
21950 if (isset($this->CSS['BODY']['FONT-STYLE'])) { $bodystyle['FONT-STYLE'] = $this->CSS['BODY']['FONT-STYLE']; }
21951 if (isset($this->CSS['BODY']['FONT-WEIGHT'])) { $bodystyle['FONT-WEIGHT'] = $this->CSS['BODY']['FONT-WEIGHT']; }
21952 if (isset($this->CSS['BODY']['COLOR'])) { $bodystyle['COLOR'] = $this->CSS['BODY']['COLOR']; }
21953 if (isset($bodystyle)) { $this->setCSS($bodystyle,'BLOCK','BODY'); }
21954
21955 }
21956
21957 /*-- HTML-CSS --*/
21958 function ReadMetaTags($html) {
21959 // changes anykey=anyvalue to anykey="anyvalue" (only do this when this happens inside tags)
21960 $regexp = '/ (\\w+?)=([^\\s>"]+)/si';
21961 $html = preg_replace($regexp," \$1=\"\$2\"",$html);
21962 if (preg_match('/<title>(.*?)<\/title>/si',$html,$m)) {
21963 $this->SetTitle($m[1]);
21964 }
21965 preg_match_all('/<meta [^>]*?(name|content)="([^>]*?)" [^>]*?(name|content)="([^>]*?)".*?>/si',$html,$aux);
21966 $firstattr = $aux[1];
21967 $secondattr = $aux[3];
21968 for( $i = 0 ; $i < count($aux[0]) ; $i++) {
21969
21970 $name = ( strtoupper($firstattr[$i]) == "NAME" )? strtoupper($aux[2][$i]) : strtoupper($aux[4][$i]);
21971 $content = ( strtoupper($firstattr[$i]) == "CONTENT" )? $aux[2][$i] : $aux[4][$i];
21972 switch($name) {
21973 case "KEYWORDS": $this->SetKeywords($content); break;
21974 case "AUTHOR": $this->SetAuthor($content); break;
21975 case "DESCRIPTION": $this->SetSubject($content); break;
21976 }
21977 }
21978 }
21979
21980
21981 function ReadCharset($html) {
21982 // Charset conversion
21983 if ($this->allow_charset_conversion) {
21984 if (preg_match('/<head.*charset=([^\'\"\s]*).*<\/head>/si',$html,$m)) {
21985 if (strtoupper($m[1]) != 'UTF-8') {
21986 $this->charset_in = strtoupper($m[1]);
21987 }
21988 }
21989 }
21990 }
21991 /*-- END HTML-CSS --*/
21992
21993 //////////////////
21994 /// CSS parser ///
21995 //////////////////
21996 //////////////////
21997 /// CSS parser ///
21998 //////////////////
21999 //////////////////
22000 /// CSS parser ///
22001 //////////////////
22002
22003 /*-- HTML-CSS --*/
22004 function ReadDefaultCSS($CSSstr) {
22005 $CSS = array();
22006 $CSSstr = preg_replace('|/\*.*?\*/|s',' ',$CSSstr);
22007 $CSSstr = preg_replace('/[\s\n\r\t\f]/s',' ',$CSSstr);
22008 $CSSstr = preg_replace('/(<\!\-\-|\-\->)/s',' ',$CSSstr);
22009 if ($CSSstr ) {
22010 preg_match_all('/(.*?)\{(.*?)\}/',$CSSstr,$styles);
22011 for($i=0; $i < count($styles[1]) ; $i++) {
22012 $stylestr= trim($styles[2][$i]);
22013 $stylearr = explode(';',$stylestr);
22014 foreach($stylearr AS $sta) {
22015 if (trim($sta)) {
22016 // Changed to allow style="background: url('http://www.bpm1.com/bg.jpg')"
22017 list($property,$value) = explode(':',$sta,2);
22018 $property = trim($property);
22019 $value = preg_replace('/\s*!important/i','',$value);
22020 $value = trim($value);
22021 if ($property && ($value || $value==='0')) {
22022 $classproperties[strtoupper($property)] = $value;
22023 }
22024 }
22025 }
22026 $classproperties = $this->fixCSS($classproperties);
22027 $tagstr = strtoupper(trim($styles[1][$i]));
22028 $tagarr = explode(',',$tagstr);
22029 foreach($tagarr AS $tg) {
22030 $tags = preg_split('/\s+/',trim($tg));
22031 $level = count($tags);
22032 if ($level == 1) { // e.g. p or .class or #id or p.class or p#id
22033 $t = trim($tags[0]);
22034 if ($t) {
22035 $tag = '';
22036 if (preg_match('/^('.$this->allowedCSStags.')$/',$t)) { $tag= $t; }
22037 if ($this->CSS[$tag] && $tag) { $CSS[$tag] = $this->array_merge_recursive_unique($CSS[$tag], $classproperties); }
22038 else if ($tag) { $CSS[$tag] = $classproperties; }
22039 }
22040 }
22041 }
22042 $properties = array();
22043 $values = array();
22044 $classproperties = array();
22045 }
22046
22047 } // end of if
22048 return $CSS;
22049 }
22050
22051
22052
22053
22054 function ReadCSS($html) {
22055 preg_match_all('/<style[^>]*media=["\']([^"\'>]*)["\'].*?<\/style>/is',$html,$m);
22056 for($i=0; $i<count($m[0]); $i++) {
22057 if ($this->CSSselectMedia && !preg_match('/('.trim($this->CSSselectMedia).'|all)/i',$m[1][$i])) {
22058 $html = preg_replace('/'.preg_quote($m[0][$i],'/').'/','',$html);
22059 }
22060 }
22061 preg_match_all('/<link[^>]*media=["\']([^"\'>]*)["\'].*?>/is',$html,$m);
22062 for($i=0; $i<count($m[0]); $i++) {
22063 if ($this->CSSselectMedia && !preg_match('/('.trim($this->CSSselectMedia).'|all)/i',$m[1][$i])) {
22064 $html = preg_replace('/'.preg_quote($m[0][$i],'/').'/','',$html);
22065 }
22066 }
22067
22068 // Remove Comment tags <!-- --> inside CSS as <style> in HTML document
22069 // Remove Comment tags /* ... */ inside CSS as <style> in HTML document
22070 preg_match_all('/<style.*?>(.*?)<\/style>/si',$html,$m);
22071 if (count($m[1])) {
22072 for($i=0;$i<count($m[1]);$i++) {
22073 // Remove comment tags
22074 $sub = preg_replace('/(<\!\-\-|\-\->)/s',' ',$m[1][$i]);
22075 $sub = preg_replace('|/\*.*?\*/|s',' ',$sub);
22076 $html = preg_replace('/'.preg_quote($m[1][$i], '/').'/si', $sub, $html);
22077 }
22078 }
22079
22080 $html = preg_replace('/<!--mpdf/i','',$html);
22081 $html = preg_replace('/mpdf-->/i','',$html);
22082 $html = preg_replace('/<\!\-\-.*?\-\->/s',' ',$html);
22083
22084 $match = 0; // no match for instance
22085 $regexp = ''; // This helps debugging: showing what is the REAL string being processed
22086 $CSSext = array();
22087
22088 //CSS inside external files
22089 $regexp = '/<link[^>]*rel=["\']stylesheet["\'][^>]*href=["\']([^>"\']*)["\'].*?>/si';
22090 $x = preg_match_all($regexp,$html,$cxt);
22091 if ($x) {
22092 $match += $x;
22093 $CSSext = $cxt[1];
22094 }
22095
22096 $regexp = '/<link[^>]*href=["\']([^>"\']*)["\'][^>]*?rel=["\']stylesheet["\'].*?>/si';
22097 $x = preg_match_all($regexp,$html,$cxt);
22098 if ($x) {
22099 $match += $x;
22100 $CSSext = array_merge($CSSext,$cxt[1]);
22101 }
22102
22103 // look for @import stylesheets
22104 //$regexp = '/@import url\([\'\"]{0,1}([^\)]*?\.css)[\'\"]{0,1}\)/si';
22105 $regexp = '/@import url\([\'\"]{0,1}([^\)]*?\.css(\?\S+)?)[\'\"]{0,1}\)/si'; // mPDF 5.3.63
22106 $x = preg_match_all($regexp,$html,$cxt);
22107 if ($x) {
22108 $match += $x;
22109 $CSSext = array_merge($CSSext,$cxt[1]);
22110 }
22111
22112 // look for @import without the url()
22113 //$regexp = '/@import [\'\"]{0,1}([^;]*?\.css)[\'\"]{0,1}/si';
22114 $regexp = '/@import [\'\"]{0,1}([^;]*?\.css(\?\S+)?)[\'\"]{0,1}/si'; // mPDF 5.3.63
22115 $x = preg_match_all($regexp,$html,$cxt);
22116 if ($x) {
22117 $match += $x;
22118 $CSSext = array_merge($CSSext,$cxt[1]);
22119 }
22120
22121 $ind = 0;
22122 $CSSstr = '';
22123
22124 if (!is_array($this->cascadeCSS)) $this->cascadeCSS = array();
22125
22126 while($match){
22127 $path = $CSSext[$ind];
22128 $this->GetFullPath($path);
22129 $CSSextblock = $this->_get_file($path);
22130 if ($CSSextblock) {
22131 // look for embedded @import stylesheets in other stylesheets
22132 // and fix url paths (including background-images) relative to stylesheet
22133 //$regexpem = '/@import url\([\'\"]{0,1}(.*?\.css)[\'\"]{0,1}\)/si';
22134 $regexpem = '/@import url\([\'\"]{0,1}(.*?\.css(\?\S+)?)[\'\"]{0,1}\)/si'; // mPDF 5.3.63
22135 $xem = preg_match_all($regexpem,$CSSextblock,$cxtem);
22136 $cssBasePath = preg_replace('/\/[^\/]*$/','',$path) . '/';
22137 if ($xem) {
22138 foreach($cxtem[1] AS $cxtembedded) {
22139 // path is relative to original stlyesheet!!
22140 $this->GetFullPath($cxtembedded, $cssBasePath );
22141 $match++;
22142 $CSSext[] = $cxtembedded;
22143 }
22144 }
22145 $regexpem = '/(background[^;]*url\s*\(\s*[\'\"]{0,1})([^\)\'\"]*)([\'\"]{0,1}\s*\))/si';
22146 $xem = preg_match_all($regexpem,$CSSextblock,$cxtem);
22147 if ($xem) {
22148 for ($i=0;$i<count($cxtem[0]);$i++) {
22149 // path is relative to original stlyesheet!!
22150 $embedded = $cxtem[2][$i];
22151 $this->GetFullPath($embedded, $cssBasePath );
22152 $CSSextblock = preg_replace('/'.preg_quote($cxtem[0][$i],'/').'/', ($cxtem[1][$i].$embedded.$cxtem[3][$i]), $CSSextblock);
22153 }
22154 }
22155 $CSSstr .= ' '.$CSSextblock;
22156 }
22157 $match--;
22158 $ind++;
22159 } //end of match
22160
22161 $match = 0; // reset value, if needed
22162 // CSS as <style> in HTML document
22163 $regexp = '/<style.*?>(.*?)<\/style>/si';
22164 $match = preg_match_all($regexp,$html,$CSSblock);
22165 if ($match) {
22166 $tmpCSSstr = implode(' ',$CSSblock[1]);
22167 $regexpem = '/(background[^;]*url\s*\(\s*[\'\"]{0,1})([^\)\'\"]*)([\'\"]{0,1}\s*\))/si';
22168 $xem = preg_match_all($regexpem,$tmpCSSstr ,$cxtem);
22169 if ($xem) {
22170 for ($i=0;$i<count($cxtem[0]);$i++) {
22171 $embedded = $cxtem[2][$i];
22172 $this->GetFullPath($embedded);
22173 $tmpCSSstr = preg_replace('/'.preg_quote($cxtem[0][$i],'/').'/', ($cxtem[1][$i].$embedded.$cxtem[3][$i]), $tmpCSSstr );
22174 }
22175 }
22176 $CSSstr .= ' '.$tmpCSSstr;
22177 }
22178 // Remove comments
22179 $CSSstr = preg_replace('|/\*.*?\*/|s',' ',$CSSstr);
22180 $CSSstr = preg_replace('/[\s\n\r\t\f]/s',' ',$CSSstr);
22181
22182 if (preg_match('/@media/',$CSSstr)) {
22183 preg_match_all('/@media(.*?)\{(([^\{\}]*\{[^\{\}]*\})+)\s*\}/is',$CSSstr,$m);
22184 for($i=0; $i<count($m[0]); $i++) {
22185 if ($this->CSSselectMedia && !preg_match('/('.trim($this->CSSselectMedia).'|all)/i',$m[1][$i])) {
22186 $CSSstr = preg_replace('/'.preg_quote($m[0][$i],'/').'/','',$CSSstr);
22187 }
22188 else {
22189 $CSSstr = preg_replace('/'.preg_quote($m[0][$i],'/').'/',' '.$m[2][$i].' ',$CSSstr);
22190 }
22191 }
22192 }
22193
22194 $CSSstr = preg_replace('/(<\!\-\-|\-\->)/s',' ',$CSSstr);
22195 if ($CSSstr ) {
22196 preg_match_all('/(.*?)\{(.*?)\}/',$CSSstr,$styles);
22197 for($i=0; $i < count($styles[1]) ; $i++) {
22198 // SET array e.g. $classproperties['COLOR'] = '#ffffff';
22199 $stylestr= trim($styles[2][$i]);
22200 $stylearr = explode(';',$stylestr);
22201 foreach($stylearr AS $sta) {
22202 if (trim($sta)) {
22203 // Changed to allow style="background: url('http://www.bpm1.com/bg.jpg')"
22204 list($property,$value) = explode(':',$sta,2);
22205 $property = trim($property);
22206 $value = preg_replace('/\s*!important/i','',$value);
22207 $value = trim($value);
22208 if ($property && ($value || $value==='0')) {
22209 // Ignores -webkit-gradient so doesn't override -moz-
22210 if ((strtoupper($property)=='BACKGROUND-IMAGE' || strtoupper($property)=='BACKGROUND') && preg_match('/-webkit-gradient/i',$value)) {
22211 continue;
22212 }
22213 $classproperties[strtoupper($property)] = $value;
22214 }
22215 }
22216 }
22217 $classproperties = $this->fixCSS($classproperties);
22218 $tagstr = strtoupper(trim($styles[1][$i]));
22219 $tagarr = explode(',',$tagstr);
22220 $pageselectors = false; // used to turn on $this->mirrorMargins
22221 foreach($tagarr AS $tg) {
22222 $tags = preg_split('/\s+/',trim($tg));
22223 $level = count($tags);
22224 $t = '';
22225 $t2 = '';
22226 $t3 = '';
22227 if (trim($tags[0])=='@PAGE') {
22228 if (isset($tags[0])) { $t = trim($tags[0]); }
22229 if (isset($tags[1])) { $t2 = trim($tags[1]); }
22230 if (isset($tags[2])) { $t3 = trim($tags[2]); }
22231 $tag = '';
22232 if ($level==1) { $tag = $t; }
22233 else if ($level==2 && preg_match('/^[:](.*)$/',$t2,$m)) {
22234 $tag = $t.'>>PSEUDO>>'.$m[1];
22235 if ($m[1]=='LEFT' || $m[1]=='RIGHT') { $pageselectors = true; } // used to turn on $this->mirrorMargins
22236 }
22237 else if ($level==2) { $tag = $t.'>>NAMED>>'.$t2; }
22238 else if ($level==3 && preg_match('/^[:](.*)$/',$t3,$m)) {
22239 $tag = $t.'>>NAMED>>'.$t2.'>>PSEUDO>>'.$m[1];
22240 if ($m[1]=='LEFT' || $m[1]=='RIGHT') { $pageselectors = true; } // used to turn on $this->mirrorMargins
22241 }
22242 if (isset($this->CSS[$tag]) && $tag) { $this->CSS[$tag] = $this->array_merge_recursive_unique($this->CSS[$tag], $classproperties); }
22243 else if ($tag) { $this->CSS[$tag] = $classproperties; }
22244 }
22245
22246 else if ($level == 1) { // e.g. p or .class or #id or p.class or p#id
22247 if (isset($tags[0])) { $t = trim($tags[0]); }
22248 if ($t) {
22249 $tag = '';
22250 if (preg_match('/^[.](.*)$/',$t,$m)) { $tag = 'CLASS>>'.$m[1]; }
22251 else if (preg_match('/^[#](.*)$/',$t,$m)) { $tag = 'ID>>'.$m[1]; }
22252 else if (preg_match('/^('.$this->allowedCSStags.')[.](.*)$/',$t,$m)) { $tag = $m[1].'>>CLASS>>'.$m[2]; }
22253 else if (preg_match('/^('.$this->allowedCSStags.')\s*:NTH-CHILD\((.*)\)$/',$t,$m)) { $tag = $m[1].'>>SELECTORNTHCHILD>>'.$m[2]; } // mPDF 5.3.82
22254 else if (preg_match('/^('.$this->allowedCSStags.')[#](.*)$/',$t,$m)) { $tag = $m[1].'>>ID>>'.$m[2]; }
22255 else if (preg_match('/^('.$this->allowedCSStags.')$/',$t)) { $tag= $t; }
22256 if (isset($this->CSS[$tag]) && $tag) { $this->CSS[$tag] = $this->array_merge_recursive_unique($this->CSS[$tag], $classproperties); }
22257 else if ($tag) { $this->CSS[$tag] = $classproperties; }
22258 }
22259 }
22260 else {
22261 $tmp = array();
22262 for($n=0;$n<$level;$n++) {
22263 if (isset($tags[$n])) { $t = trim($tags[$n]); }
22264 else { $t = ''; }
22265 if ($t) {
22266 $tag = '';
22267 if (preg_match('/^[.](.*)$/',$t,$m)) { $tag = 'CLASS>>'.$m[1]; }
22268 else if (preg_match('/^[#](.*)$/',$t,$m)) { $tag = 'ID>>'.$m[1]; }
22269 else if (preg_match('/^('.$this->allowedCSStags.')[.](.*)$/',$t,$m)) { $tag = $m[1].'>>CLASS>>'.$m[2]; }
22270 else if (preg_match('/^('.$this->allowedCSStags.')\s*:NTH-CHILD\((.*)\)$/',$t,$m)) { $tag = $m[1].'>>SELECTORNTHCHILD>>'.$m[2]; } // mPDF 5.3.82
22271 else if (preg_match('/^('.$this->allowedCSStags.')[#](.*)$/',$t,$m)) { $tag = $m[1].'>>ID>>'.$m[2]; }
22272 else if (preg_match('/^('.$this->allowedCSStags.')$/',$t)) { $tag= $t; }
22273
22274 if ($tag) $tmp[] = $tag;
22275 else { break; }
22276 }
22277 }
22278
22279 if ($tag) {
22280 $x = &$this->cascadeCSS;
22281 foreach($tmp AS $tp) { $x = &$x[$tp]; }
22282 $x = $this->array_merge_recursive_unique($x, $classproperties);
22283 $x['depth'] = $level;
22284 }
22285 }
22286 }
22287 if ($pageselectors) { $this->mirrorMargins = true; }
22288 $properties = array();
22289 $values = array();
22290 $classproperties = array();
22291 }
22292 } // end of if
22293 //Remove CSS (tags and content), if any
22294 $regexp = '/<style.*?>(.*?)<\/style>/si'; // it can be <style> or <style type="txt/css">
22295 $html = preg_replace($regexp,'',$html);
22296 //print_r($this->CSS); exit;
22297 //print_r($this->cascadeCSS); exit;
22298 return $html;
22299 }
22300
22301 function readInlineCSS($html) {
22302 //Fix incomplete CSS code
22303 $size = strlen($html)-1;
22304 if (substr($html,$size,1) != ';') $html .= ';';
22305 //Make CSS[Name-of-the-class] = array(key => value)
22306 $regexp = '|\\s*?(\\S+?):(.+?);|i';
22307 preg_match_all( $regexp, $html, $styleinfo);
22308 $properties = $styleinfo[1];
22309 $values = $styleinfo[2];
22310 //Array-properties and Array-values must have the SAME SIZE!
22311 $classproperties = array();
22312 for($i = 0; $i < count($properties) ; $i++) {
22313 // Ignores -webkit-gradient so doesn't override -moz-
22314 if ((strtoupper($properties[$i])=='BACKGROUND-IMAGE' || strtoupper($properties[$i])=='BACKGROUND') && preg_match('/-webkit-gradient/i',$values[$i])) {
22315 continue;
22316 }
22317 $classproperties[strtoupper($properties[$i])] = trim($values[$i]);
22318 }
22319 return $this->fixCSS($classproperties);
22320 }
22321
22322
22323
22324 function setCSS($arrayaux,$type='',$tag='') { // type= INLINE | BLOCK | LIST // tag= BODY
22325 if (!is_array($arrayaux)) return; //Removes PHP Warning
22326 // Set font size first so that e.g. MARGIN 0.83em works on font size for this element
22327 if (isset($arrayaux['FONT-SIZE'])) {
22328 $v = $arrayaux['FONT-SIZE'];
22329 if(is_numeric($v[0])) {
22330 // mPDF 5.3.28
22331 if ($type == 'BLOCK' && $this->blklvl>0 && isset($this->blk[$this->blklvl-1]['InlineProperties']) && isset($this->blk[$this->blklvl-1]['InlineProperties']['size'])) {
22332 $mmsize = $this->ConvertSize($v,$this->blk[$this->blklvl-1]['InlineProperties']['size']);
22333 }
22334 else {
22335 $mmsize = $this->ConvertSize($v,$this->FontSize);
22336 }
22337 $this->SetFontSize( $mmsize*(_MPDFK),false ); //Get size in points (pt)
22338 }
22339 else{
22340 $v = strtoupper($v);
22341 if (isset($this->fontsizes[$v])) {
22342 $this->SetFontSize( $this->fontsizes[$v]* $this->default_font_size,false);
22343 }
22344 }
22345 if ($tag == 'BODY') { $this->SetDefaultFontSize($this->FontSizePt); }
22346 }
22347
22348
22349 if ($this->useLang && !$this->usingCoreFont) {
22350 if (isset($arrayaux['LANG']) && $arrayaux['LANG'] && $arrayaux['LANG'] != $this->default_lang && ((strlen($arrayaux['LANG']) == 5 && $arrayaux['LANG'] != 'UTF-8') || strlen($arrayaux['LANG']) == 2)) {
22351 list ($coreSuitable,$mpdf_pdf_unifonts) = GetLangOpts($arrayaux['LANG'], $this->useAdobeCJK);
22352 if ($mpdf_pdf_unifonts) { $this->RestrictUnicodeFonts($mpdf_pdf_unifonts); }
22353 else { $this->RestrictUnicodeFonts($this->default_available_fonts ); }
22354 if ($tag == 'BODY') {
22355 $this->currentLang = $arrayaux['LANG'];
22356 $this->default_lang = $arrayaux['LANG'];
22357 if ($mpdf_pdf_unifonts) { $this->default_available_fonts = $mpdf_pdf_unifonts; }
22358 }
22359 }
22360 else {
22361 $this->RestrictUnicodeFonts($this->default_available_fonts );
22362 }
22363 }
22364
22365 // FOR INLINE and BLOCK OR 'BODY'
22366 if (isset($arrayaux['FONT-FAMILY'])) {
22367 $v = $arrayaux['FONT-FAMILY'];
22368 //If it is a font list, get all font types
22369 $aux_fontlist = explode(",",$v);
22370 $found = 0;
22371 foreach($aux_fontlist AS $f) {
22372 $fonttype = trim($f);
22373 $fonttype = preg_replace('/["\']*(.*?)["\']*/','\\1',$fonttype);
22374 $fonttype = preg_replace('/ /','',$fonttype);
22375 $v = strtolower(trim($fonttype));
22376 if (isset($this->fonttrans[$v]) && $this->fonttrans[$v]) { $v = $this->fonttrans[$v]; }
22377 if ((!$this->onlyCoreFonts && in_array($v,$this->available_unifonts)) ||
22378 in_array($v,array('ccourier','ctimes','chelvetica')) || /* mPDF 5.3.21 & 22 */
22379 ($this->onlyCoreFonts && in_array($v,array('courier','times','helvetica','arial'))) ||
22380 in_array($v, array('sjis','uhc','big5','gb'))) {
22381 $fonttype = $v;
22382 $found = 1;
22383 break;
22384 }
22385 }
22386 if (!$found) {
22387 foreach($aux_fontlist AS $f) {
22388 $fonttype = trim($f);
22389 $fonttype = preg_replace('/["\']*(.*?)["\']*/','\\1',$fonttype);
22390 $fonttype = preg_replace('/ /','',$fonttype);
22391 $v = strtolower(trim($fonttype));
22392 if (isset($this->fonttrans[$v]) && $this->fonttrans[$v]) { $v = $this->fonttrans[$v]; }
22393 if (in_array($v,$this->sans_fonts) || in_array($v,$this->serif_fonts) || in_array($v,$this->mono_fonts) ) {
22394 $fonttype = $v;
22395 break;
22396 }
22397 }
22398 }
22399
22400 if ($tag == 'BODY') {
22401 $this->SetDefaultFont($fonttype);
22402 }
22403 $this->SetFont($fonttype,$this->currentfontstyle,0,false);
22404 }
22405 else {
22406 $this->SetFont($this->currentfontfamily,$this->currentfontstyle,0,false);
22407 }
22408
22409 foreach($arrayaux as $k => $v) {
22410 if ($type != 'INLINE' && $tag != 'BODY' && $type != 'LIST') { // mPDF 5.3.65
22411 switch($k){
22412 // BORDERS
22413 case 'BORDER-TOP':
22414 $this->blk[$this->blklvl]['border_top'] = $this->border_details($v);
22415 if ($this->blk[$this->blklvl]['border_top']['s']) { $this->blk[$this->blklvl]['border'] = 1; }
22416 break;
22417 case 'BORDER-BOTTOM':
22418 $this->blk[$this->blklvl]['border_bottom'] = $this->border_details($v);
22419 if ($this->blk[$this->blklvl]['border_bottom']['s']) { $this->blk[$this->blklvl]['border'] = 1; }
22420 break;
22421 case 'BORDER-LEFT':
22422 $this->blk[$this->blklvl]['border_left'] = $this->border_details($v);
22423 if ($this->blk[$this->blklvl]['border_left']['s']) { $this->blk[$this->blklvl]['border'] = 1; }
22424 break;
22425 case 'BORDER-RIGHT':
22426 $this->blk[$this->blklvl]['border_right'] = $this->border_details($v);
22427 if ($this->blk[$this->blklvl]['border_right']['s']) { $this->blk[$this->blklvl]['border'] = 1; }
22428 break;
22429
22430 // PADDING
22431 case 'PADDING-TOP':
22432 $this->blk[$this->blklvl]['padding_top'] = $this->ConvertSize($v,$this->blk[$this->blklvl-1]['inner_width'],$this->FontSize,false);
22433 break;
22434 case 'PADDING-BOTTOM':
22435 $this->blk[$this->blklvl]['padding_bottom'] = $this->ConvertSize($v,$this->blk[$this->blklvl-1]['inner_width'],$this->FontSize,false);
22436 break;
22437 case 'PADDING-LEFT':
22438 $this->blk[$this->blklvl]['padding_left'] = $this->ConvertSize($v,$this->blk[$this->blklvl-1]['inner_width'],$this->FontSize,false);
22439 break;
22440 case 'PADDING-RIGHT':
22441 $this->blk[$this->blklvl]['padding_right'] = $this->ConvertSize($v,$this->blk[$this->blklvl-1]['inner_width'],$this->FontSize,false);
22442 break;
22443
22444 // MARGINS
22445 case 'MARGIN-TOP':
22446 $tmp = $this->ConvertSize($v,$this->blk[$this->blklvl-1]['inner_width'],$this->FontSize,false);
22447 if (isset($this->blk[$this->blklvl]['lastbottommargin'])) {
22448 if ($tmp > $this->blk[$this->blklvl]['lastbottommargin']) {
22449 $tmp -= $this->blk[$this->blklvl]['lastbottommargin'];
22450 }
22451 else {
22452 $tmp = 0;
22453 }
22454 }
22455 $this->blk[$this->blklvl]['margin_top'] = $tmp;
22456 break;
22457 case 'MARGIN-BOTTOM':
22458 $this->blk[$this->blklvl]['margin_bottom'] = $this->ConvertSize($v,$this->blk[$this->blklvl-1]['inner_width'],$this->FontSize,false);
22459 break;
22460 case 'MARGIN-LEFT':
22461 $this->blk[$this->blklvl]['margin_left'] = $this->ConvertSize($v,$this->blk[$this->blklvl-1]['inner_width'],$this->FontSize,false);
22462 break;
22463 case 'MARGIN-RIGHT':
22464 $this->blk[$this->blklvl]['margin_right'] = $this->ConvertSize($v,$this->blk[$this->blklvl-1]['inner_width'],$this->FontSize,false);
22465 break;
22466
22467 /*-- BORDER-RADIUS --*/
22468 case 'BORDER-TOP-LEFT-RADIUS-H':
22469 $this->blk[$this->blklvl]['border_radius_TL_H'] = $this->ConvertSize($v,$this->blk[$this->blklvl-1]['inner_width'],$this->FontSize,false);
22470 break;
22471 case 'BORDER-TOP-LEFT-RADIUS-V':
22472 $this->blk[$this->blklvl]['border_radius_TL_V'] = $this->ConvertSize($v,$this->blk[$this->blklvl-1]['inner_width'],$this->FontSize,false);
22473 break;
22474 case 'BORDER-TOP-RIGHT-RADIUS-H':
22475 $this->blk[$this->blklvl]['border_radius_TR_H'] = $this->ConvertSize($v,$this->blk[$this->blklvl-1]['inner_width'],$this->FontSize,false);
22476 break;
22477 case 'BORDER-TOP-RIGHT-RADIUS-V':
22478 $this->blk[$this->blklvl]['border_radius_TR_V'] = $this->ConvertSize($v,$this->blk[$this->blklvl-1]['inner_width'],$this->FontSize,false);
22479 break;
22480 case 'BORDER-BOTTOM-LEFT-RADIUS-H':
22481 $this->blk[$this->blklvl]['border_radius_BL_H'] = $this->ConvertSize($v,$this->blk[$this->blklvl-1]['inner_width'],$this->FontSize,false);
22482 break;
22483 case 'BORDER-BOTTOM-LEFT-RADIUS-V':
22484 $this->blk[$this->blklvl]['border_radius_BL_V'] = $this->ConvertSize($v,$this->blk[$this->blklvl-1]['inner_width'],$this->FontSize,false);
22485 break;
22486 case 'BORDER-BOTTOM-RIGHT-RADIUS-H':
22487 $this->blk[$this->blklvl]['border_radius_BR_H'] = $this->ConvertSize($v,$this->blk[$this->blklvl-1]['inner_width'],$this->FontSize,false);
22488 break;
22489 case 'BORDER-BOTTOM-RIGHT-RADIUS-V':
22490 $this->blk[$this->blklvl]['border_radius_BR_V'] = $this->ConvertSize($v,$this->blk[$this->blklvl-1]['inner_width'],$this->FontSize,false);
22491 break;
22492 /*-- END BORDER-RADIUS --*/
22493
22494 // mPDF 5.3.A1
22495 case 'BOX-SHADOW':
22496 $bs = $this->setCSSboxshadow($v);
22497 if ($bs) { $this->blk[$this->blklvl]['box_shadow'] = $bs; }
22498 break;
22499
22500 case 'BACKGROUND-CLIP':
22501 if (strtoupper($v) == 'PADDING-BOX') { $this->blk[$this->blklvl]['background_clip'] = 'padding-box'; }
22502 break;
22503
22504 case 'PAGE-BREAK-AFTER':
22505 if (strtoupper($v) == 'AVOID') { $this->blk[$this->blklvl]['page_break_after_avoid'] = true; }
22506 // mPDF 5.3.03
22507 else if (strtoupper($v) == 'ALWAYS' || strtoupper($v) == 'LEFT' || strtoupper($v) == 'RIGHT') { $this->blk[$this->blklvl]['page_break_after'] = strtoupper($v) ; }
22508 break;
22509
22510 case 'WIDTH':
22511 if (strtoupper($v) != 'AUTO') {
22512 $this->blk[$this->blklvl]['css_set_width'] = $this->ConvertSize($v,$this->blk[$this->blklvl-1]['inner_width'],$this->FontSize,false);
22513 }
22514 break;
22515
22516 case 'TEXT-INDENT':
22517 // Left as raw value (may include 1% or 2em)
22518 $this->blk[$this->blklvl]['text_indent'] = $v;
22519 break;
22520
22521 }//end of switch($k)
22522 }
22523
22524
22525 if ($type != 'INLINE' && $type != 'LIST') { // includes BODY tag // mPDF 5.3.65
22526 switch($k){
22527
22528 case 'MARGIN-COLLAPSE': // Custom tag to collapse margins at top and bottom of page
22529 if (strtoupper($v) == 'COLLAPSE') { $this->blk[$this->blklvl]['margin_collapse'] = true; }
22530 break;
22531
22532 case 'LINE-HEIGHT':
22533 $this->blk[$this->blklvl]['line_height'] = $this->fixLineheight($v);
22534 if (!$this->blk[$this->blklvl]['line_height'] ) { $this->blk[$this->blklvl]['line_height'] = $this->normalLineheight; }
22535 break;
22536
22537 case 'TEXT-ALIGN': //left right center justify
22538 switch (strtoupper($v)) {
22539 case 'LEFT':
22540 $this->blk[$this->blklvl]['align']="L";
22541 break;
22542 case 'CENTER':
22543 $this->blk[$this->blklvl]['align']="C";
22544 break;
22545 case 'RIGHT':
22546 $this->blk[$this->blklvl]['align']="R";
22547 break;
22548 case 'JUSTIFY':
22549 $this->blk[$this->blklvl]['align']="J";
22550 break;
22551 }
22552 break;
22553
22554 /*-- BACKGROUNDS --*/
22555 case 'BACKGROUND-GRADIENT':
22556 if ($type == 'BLOCK') {
22557 $this->blk[$this->blklvl]['gradient'] = $v;
22558 }
22559 break;
22560 /*-- END BACKGROUNDS --*/
22561
22562 case 'DIRECTION':
22563 if ($v) { $this->blk[$this->blklvl]['direction'] = strtolower($v); }
22564 break;
22565
22566 }//end of switch($k)
22567 }
22568
22569 // FOR INLINE ONLY
22570 if ($type == 'INLINE' || $type == 'LIST') { // mPDF 5.3.65
22571 switch($k){
22572 case 'DISPLAY': // Custom tag to collapse margins at top and bottom of page
22573 if (strtoupper($v) == 'NONE') { $this->inlineDisplayOff = true; }
22574 break;
22575 case 'DIRECTION':
22576 break;
22577 }//end of switch($k)
22578 }
22579 // FOR INLINE ONLY
22580 if ($type == 'INLINE') { // mPDF 5.3.65
22581 switch($k){
22582 // mPDF 5.3.61
22583 // BORDERS
22584 case 'BORDER-TOP':
22585 $this->spanborddet['T'] = $this->border_details($v);
22586 $this->spanborder = true;
22587 break;
22588 case 'BORDER-BOTTOM':
22589 $this->spanborddet['B'] = $this->border_details($v);
22590 $this->spanborder = true;
22591 break;
22592 case 'BORDER-LEFT':
22593 $this->spanborddet['L'] = $this->border_details($v);
22594 $this->spanborder = true;
22595 break;
22596 case 'BORDER-RIGHT':
22597 $this->spanborddet['R'] = $this->border_details($v);
22598 $this->spanborder = true;
22599 break;
22600 }//end of switch($k)
22601 }
22602
22603
22604 // FOR INLINE and BLOCK
22605 switch($k){
22606 case 'TEXT-ALIGN': //left right center justify
22607 if (strtoupper($v) == 'NOJUSTIFY' && $this->blk[$this->blklvl]['align']=="J") {
22608 $this->blk[$this->blklvl]['align']="";
22609 }
22610 break;
22611 // bgcolor only - to stay consistent with original html2fpdf
22612 case 'BACKGROUND':
22613 case 'BACKGROUND-COLOR':
22614 $cor = $this->ConvertColor($v);
22615 if ($cor) {
22616
22617 if ($tag == 'BODY') {
22618 $this->bodyBackgroundColor = $cor;
22619 }
22620 else if ($type == 'INLINE' || $type == 'LIST') { // mPDF 5.3.93
22621 $this->spanbgcolorarray = $cor;
22622 $this->spanbgcolor = true;
22623 }
22624 else {
22625 $this->blk[$this->blklvl]['bgcolorarray'] = $cor;
22626 $this->blk[$this->blklvl]['bgcolor'] = true;
22627 }
22628 }
22629 else if ($type != 'INLINE' && $type != 'LIST') { // mPDF 5.3.93
22630 if ($this->ColActive || $this->keep_block_together) {
22631 $this->blk[$this->blklvl]['bgcolorarray'] = $this->blk[$this->blklvl-1]['bgcolorarray'] ;
22632 $this->blk[$this->blklvl]['bgcolor'] = $this->blk[$this->blklvl-1]['bgcolor'] ;
22633 }
22634 }
22635 break;
22636
22637 // auto | normal | none
22638 case 'FONT-KERNING':
22639 if ((strtoupper($v) == 'NORMAL' || strtoupper($v) == 'AUTO') && $this->useKerning) { $this->kerning = true; }
22640 else if (strtoupper($v) == 'NONE') { $this->kerning = false; }
22641 break;
22642
22643
22644 // normal | <length>
22645 case 'LETTER-SPACING':
22646 $this->lSpacingCSS = $v;
22647 if (($this->lSpacingCSS || $this->lSpacingCSS==='0') && strtoupper($this->lSpacingCSS) != 'NORMAL') {
22648 $this->fixedlSpacing = $this->ConvertSize($this->lSpacingCSS,$this->FontSize);
22649 }
22650 break;
22651
22652 // normal | <length>
22653 case 'WORD-SPACING':
22654 $this->wSpacingCSS = $v;
22655 if ($this->wSpacingCSS && strtoupper($this->wSpacingCSS) != 'NORMAL') {
22656 $this->minwSpacing = $this->ConvertSize($this->wSpacingCSS,$this->FontSize);
22657 }
22658 break;
22659
22660 case 'FONT-STYLE': // italic normal oblique
22661 switch (strtoupper($v)) {
22662 case 'ITALIC':
22663 case 'OBLIQUE':
22664 $this->SetStyle('I',true);
22665 break;
22666 case 'NORMAL':
22667 $this->SetStyle('I',false);
22668 break;
22669 }
22670 break;
22671
22672 case 'FONT-WEIGHT': // normal bold //Does not support: bolder, lighter, 100..900(step value=100)
22673 switch (strtoupper($v)) {
22674 case 'BOLD':
22675 $this->SetStyle('B',true);
22676 break;
22677 case 'NORMAL':
22678 $this->SetStyle('B',false);
22679 break;
22680 }
22681 break;
22682
22683 case 'VERTICAL-ALIGN': //super and sub only dealt with here e.g. <SUB> and <SUP>
22684 switch (strtoupper($v)) {
22685 case 'SUPER':
22686 $this->SUP=true;
22687 break;
22688 case 'SUB':
22689 $this->SUB=true;
22690 break;
22691 }
22692 break;
22693
22694 case 'TEXT-DECORATION': // none underline line-through (strikeout) //Does not support: overline, blink
22695 if (stristr($v,'LINE-THROUGH')) {
22696 $this->strike = true;
22697 }
22698 if (stristr($v,'UNDERLINE')) {
22699 $this->SetStyle('U',true);
22700 }
22701 break;
22702
22703 case 'FONT-VARIANT':
22704 switch (strtoupper($v)) {
22705 case 'SMALL-CAPS':
22706 $this->SetStyle('S',true);
22707 break;
22708 case 'NORMAL':
22709 $this->SetStyle('S',false);
22710 break;
22711 }
22712 break;
22713
22714 case 'TEXT-TRANSFORM': // none uppercase lowercase //Does support: capitalize
22715 switch (strtoupper($v)) { //Not working 100%
22716 case 'CAPITALIZE':
22717 $this->capitalize=true;
22718 break;
22719 case 'UPPERCASE':
22720 $this->toupper=true;
22721 break;
22722 case 'LOWERCASE':
22723 $this->tolower=true;
22724 break;
22725 case 'NONE': break;
22726 }
22727 break;
22728
22729 // mPDF 5.3.A2
22730 case 'TEXT-SHADOW':
22731 $ts = $this->setCSStextshadow($v);
22732 if ($ts) { $this->textshadow = $ts; }
22733 break;
22734
22735 case 'OUTLINE-WIDTH':
22736 switch(strtoupper($v)) {
22737 case 'THIN': $v = '0.03em'; break;
22738 case 'MEDIUM': $v = '0.05em'; break;
22739 case 'THICK': $v = '0.07em'; break;
22740 }
22741 $this->outlineparam['WIDTH'] = $this->ConvertSize($v,$this->blk[$this->blklvl]['inner_width'],$this->FontSize);
22742 break;
22743
22744 case 'OUTLINE-COLOR':
22745 if (strtoupper($v) == 'INVERT') {
22746 if ($this->colorarray) {
22747 $cor = $this->colorarray;
22748 $this->outlineparam['COLOR'] = $this->_invertColor($cor);
22749 }
22750 else {
22751 $this->outlineparam['COLOR'] = $this->ConvertColor(255);
22752 }
22753 }
22754 else {
22755 $cor = $this->ConvertColor($v);
22756 if ($cor) { $this->outlineparam['COLOR'] = $cor ; }
22757 }
22758 break;
22759
22760 case 'COLOR': // font color
22761 $cor = $this->ConvertColor($v);
22762 if ($cor) {
22763 $this->colorarray = $cor;
22764 $this->SetTColor($cor);
22765 }
22766 break;
22767
22768
22769 }//end of switch($k)
22770
22771
22772 }//end of foreach
22773 }
22774 /*-- END HTML-CSS --*/
22775
22776 function SetStyle($tag,$enable) {
22777 $this->$tag=$enable;
22778 $style='';
22779 foreach(array('B','I','U','S') as $s) {
22780 if($this->$s) {
22781 $style.=$s;
22782 }
22783 }
22784 if ($this->S && empty($this->upperCase)) { @include(_MPDF_PATH.'includes/upperCase.php'); } // mPDF 5.3.99
22785 $this->currentfontstyle=$style;
22786 $this->SetFont('',$style,0,false);
22787 }
22788
22789 // Set multiple styles at one $str e.g. "BIS"
22790 function SetStylesArray($arr) {
22791 $style='';
22792 foreach(array('B','I','U','S') as $s) {
22793 if (isset($arr[$s])) {
22794 if ($arr[$s]) {
22795 $this->$s = true;
22796 $style.=$s;
22797 }
22798 else { $this->$s = false; }
22799 }
22800 else if ($this->$s) { $style.=$s; }
22801 }
22802 $this->currentfontstyle=$style;
22803 $this->SetFont('',$style,0,false);
22804 }
22805
22806 // Set multiple styles at one $str e.g. "BIS"
22807 function SetStyles($str) {
22808 $style='';
22809 foreach(array('B','I','U','S') as $s) {
22810 if (strpos($str,$s) !== false) {
22811 $this->$s = true;
22812 $style.=$s;
22813 }
22814 else { $this->$s = false; }
22815 }
22816 $this->currentfontstyle=$style;
22817 $this->SetFont('',$style,0,false);
22818 }
22819
22820 function ResetStyles() {
22821 foreach(array('B','I','U','S') as $s) {
22822 $this->$s = false;
22823 }
22824 $this->currentfontstyle='';
22825 $this->SetFont('','',0,false);
22826 }
22827
22828
22829 function DisableTags($str='')
22830 {
22831 if ($str == '') //enable all tags
22832 {
22833 //Insert new supported tags in the long string below.
22834 $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>"; // mPDF 5.3.56 5.3.A5
22835 }
22836 else
22837 {
22838 $str = explode(",",$str);
22839 foreach($str as $v) $this->enabledtags = str_replace(trim($v),'',$this->enabledtags);
22840 }
22841 }
22842
22843
22844 /*-- TABLES --*/
22845
22846 function finaliseCellLineHeight($lhxt, $maxfontsize, $maxlineHeight, $lhfixed, $forceExactLineheight) {
22847 $af = 0; // Above font
22848 $bf = 0; // Below font
22849 $mta = 0; // Maximum top-aligned
22850 $mba = 0; // Maximum bottom-aligned
22851 if ($lhxt['BS']) {
22852 $af = max($af, ($lhxt['BS'] - ($maxfontsize * (0.5 + $this->baselineC))));
22853 }
22854 if ($lhxt['M']) {
22855 $af = max($af, ($lhxt['M'] - $maxfontsize)/2);
22856 $bf = max($bf, ($lhxt['M'] - $maxfontsize)/2);
22857 }
22858 if ($lhxt['TT']) {
22859 $bf = max($bf, ($lhxt['TT'] - $maxfontsize));
22860 }
22861 if ($lhxt['TB']) {
22862 $af = max($af, ($lhxt['TB'] - $maxfontsize));
22863 }
22864 if ($lhxt['T']) {
22865 $mta = max($mta, $lhxt['T']);
22866 }
22867 if ($lhxt['B']) {
22868 $mba = max($mba, $lhxt['B']);
22869 }
22870 if ((!$lhfixed || !$forceExactLineheight) && ($af > (($maxlineHeight - $maxfontsize)/2) || $bf > (($maxlineHeight - $maxfontsize)/2))) {
22871 $maxlineHeight = $maxfontsize + $af + $bf;
22872 }
22873 else if (!$lhfixed) { $af = $bf = ($maxlineHeight - $maxfontsize)/2; }
22874 if ($mta > $maxlineHeight) {
22875 $bf += ($mta - $maxlineHeight);
22876 $maxlineHeight = $mta;
22877 }
22878 if ($mba > $maxlineHeight) {
22879 $af += ($mba - $maxlineHeight);
22880 $maxlineHeight = $mba;
22881 }
22882 return $maxlineHeight;
22883 }
22884
22885 function TableWordWrap($maxwidth, $forcewrap = 0, $textbuffer = '', $def_fontsize, $returnarray=false) { // NB ** returnarray used in flowchart
22886 $biggestword=0;
22887 $toonarrow=false;
22888
22889 $curlyquote = mb_convert_encoding("\xe2\x80\x9e",$this->mb_enc,'UTF-8');
22890 $curlylowquote = mb_convert_encoding("\xe2\x80\x9d",$this->mb_enc,'UTF-8');
22891
22892 $textbuffer[0][0] = preg_replace('/^[ ]*/','',$textbuffer[0][0]);
22893
22894 if ((count($textbuffer) == 0) or ((count($textbuffer) == 1) && ($textbuffer[0][0] == ''))) { return 0; }
22895
22896 $text = '';
22897 $lhfixed = false;
22898 if (preg_match('/([0-9.,]+)mm/',$this->table_lineheight)) { $lhfixed = true; }
22899 if ($lhfixed) { $def_lineheight = $this->_computeLineheight($this->table_lineheight, $def_fontsize);}
22900 else { $def_lineheight = 0; }
22901 // START OF NEW LINE
22902 // Initialise lineheight variables
22903 $maxfontsize = 0;
22904 $forceExactLineheight = true;
22905 $lhxt = array('BS'=>0, 'M'=>0, 'TT'=>0, 'TB'=>0, 'T'=>0, 'B'=>0);
22906 $maxlineHeight = $def_lineheight ;
22907 $ch = 0;
22908 $width = 0;
22909 $ln = 1; // Counts line number
22910 $mxw = $this->GetCharWidth('W',false); // mPDF 5.3.04
22911 foreach ($textbuffer as $cctr=>$chunk) {
22912 $line = $chunk[0];
22913
22914 //IMAGE
22915 if (substr($line,0,3) == "\xbb\xa4\xac") { //identifier has been identified!
22916 $objattr = $this->_getObjAttr($line);
22917 if ($objattr['type'] == 'nestedtable') {
22918 // END OF LINE
22919 // Finalise & add lineheight
22920 $ch += $this->finaliseCellLineHeight($lhxt, $maxfontsize, $maxlineHeight, $lhfixed, $forceExactLineheight);
22921 $level = $objattr['level'];
22922 $ih = $this->table[($level+1)][$objattr['nestedcontent']]['h']; // nested table width
22923 $ch += $ih;
22924 // START OF NEW LINE
22925 // Initialise lineheight variables
22926 $ln++;
22927 $maxfontsize = 0;
22928 $forceExactLineheight = true;
22929 $lhxt = array('BS'=>0, 'M'=>0, 'TT'=>0, 'TB'=>0, 'T'=>0, 'B'=>0);
22930 $maxlineHeight = $def_lineheight ;
22931 $width = 0;
22932 $text = "";
22933 continue;
22934 }
22935
22936 list($skipln,$iw,$ih) = $this->inlineObject((isset($specialcontent['type']) ? $specialcontent['type'] : null),0,0, $objattr, $this->lMargin,$width,$maxwidth,$maxlineHeight,false,true);
22937 if ($objattr['type'] == 'hr') {
22938 // END OF LINE
22939 // Finalise & add lineheight
22940 $ch += $this->finaliseCellLineHeight($lhxt, $maxfontsize, $maxlineHeight, $lhfixed, $forceExactLineheight);
22941 // Add HR height
22942 $ch += $ih;
22943 // START OF NEW LINE
22944 // Initialise lineheight variables
22945 $ln++;
22946 $maxfontsize = 0;
22947 $forceExactLineheight = true;
22948 $lhxt = array('BS'=>0, 'M'=>0, 'TT'=>0, 'TB'=>0, 'T'=>0, 'B'=>0);
22949 $maxlineHeight = $def_lineheight ;
22950 $width = 0;
22951 $text = "";
22952 continue;
22953 }
22954
22955 if ($skipln==1 || $skipln==-2) {
22956 // Finish last line
22957 // END OF LINE
22958 // Finalise & add lineheight
22959 $ch += $this->finaliseCellLineHeight($lhxt, $maxfontsize, $maxlineHeight, $lhfixed, $forceExactLineheight);
22960 // START OF NEW LINE
22961 // Initialise lineheight variables
22962 $maxfontsize = 0;
22963 $forceExactLineheight = true;
22964 $lhxt = array('BS'=>0, 'M'=>0, 'TT'=>0, 'TB'=>0, 'T'=>0, 'B'=>0);
22965 $maxlineHeight = $def_lineheight ;
22966 $ln++;
22967 $width = 0;
22968 $text = "";
22969 }
22970 $va = (isset($objattr['vertical-align']) ? $objattr['vertical-align'] : null);
22971 if ($va) {
22972 $lhxt[$va] = max($lhxt[$va], $ih);
22973 }
22974 if ($lhfixed && $ih > $def_fontsize) { $forceExactLineheight = false; }
22975 $maxlineHeight = max($maxlineHeight ,$ih);
22976 $width += $iw;
22977 continue;
22978 }
22979
22980 // SET FONT SIZE/STYLE from $chunk[n]
22981 // FONTSIZE
22982 if(isset($chunk[11]) and $chunk[11] != '') {
22983 if ($this->shrin_k) {
22984 $this->SetFontSize($chunk[11]/$this->shrin_k,false);
22985 }
22986 else {
22987 $this->SetFontSize($chunk[11],false);
22988 }
22989 }
22990 if ($line == "\n") {
22991 // END OF LINE
22992 $maxfontsize = max($maxfontsize,$this->FontSize);
22993 $fh = $this->_computeLineheight($this->table_lineheight);
22994 if ($lhfixed && $this->FontSize > $def_fontsize) {
22995 $fh = $this->FontSize;
22996 $forceExactLineheight = false;
22997 }
22998 $maxlineHeight = max($maxlineHeight,$fh);
22999
23000 // Finalise & add lineheight
23001 $ch += $this->finaliseCellLineHeight($lhxt, $maxfontsize, $maxlineHeight, $lhfixed, $forceExactLineheight);
23002 // START OF NEW LINE
23003 // Initialise lineheight variables
23004 $maxfontsize = 0;
23005 $forceExactLineheight = true;
23006 $lhxt = array('BS'=>0, 'M'=>0, 'TT'=>0, 'TB'=>0, 'T'=>0, 'B'=>0);
23007 $maxlineHeight = $this->_computeLineheight($this->table_lineheight);
23008 $ln++;
23009 $text = "";
23010 $width = 0;
23011 if(isset($chunk[11]) and $chunk[11] != '') {
23012 $this->SetFontSize($this->default_font_size,false);
23013 }
23014 continue;
23015 }
23016
23017 // mPDF 5.3.61
23018 $lbw = $rbw = 0; // Border widths
23019 if(isset($chunk[16]) && !empty($chunk[16])) { //Border
23020 $this->spanborddet = $chunk[16];
23021 if (isset($this->spanborddet['L'])) $lbw = $this->spanborddet['L']['w']; // mPDF 5.3.76
23022 if (isset($this->spanborddet['R'])) $rbw = $this->spanborddet['R']['w'];
23023 }
23024 if(isset($chunk[15])) { // Word spacing
23025 $this->wSpacingCSS = $chunk[15];
23026 if ($this->wSpacingCSS && strtoupper($this->wSpacingCSS) != 'NORMAL') {
23027 $this->minwSpacing = $this->ConvertSize($this->wSpacingCSS,$this->FontSize);
23028 }
23029 }
23030 if(isset($chunk[14])) { // Letter spacing
23031 $this->lSpacingCSS = $chunk[14];
23032 if (($this->lSpacingCSS || $this->lSpacingCSS==='0') && strtoupper($this->lSpacingCSS) != 'NORMAL') {
23033 $this->fixedlSpacing = $this->ConvertSize($this->lSpacingCSS,$this->FontSize);
23034 }
23035 }
23036 if(isset($chunk[13])) { // Font Kerning // mPDF 5.3.99
23037 $this->kerning = $chunk[13];
23038 }
23039 // FONTFAMILY
23040 if(isset($chunk[4]) and $chunk[4] != '') { $font = $this->SetFont($chunk[4],$this->FontStyle,0,false); }
23041
23042 // FONT STYLE B I U
23043 if(isset($chunk[2]) and $chunk[2] != '') {
23044 $this->SetStyles($chunk[2]);
23045 }
23046
23047 $space = $this->GetCharWidth(' ',false); // mPDF 5.3.04
23048
23049 if (mb_substr($line,0,1,$this->mb_enc ) == ' ') { // line (chunk) starts with a space
23050 $width += $space;
23051 $text .= ' ';
23052 }
23053
23054 if (mb_substr($line,(mb_strlen($line,$this->mb_enc )-1),1,$this->mb_enc ) == ' ') { $lsend = true; } // line (chunk) ends with a space
23055 else { $lsend = false; }
23056 $line= trim($line);
23057 if ($line == '') { continue; }
23058
23059 // mPDF ITERATION
23060 if ($this->iterationCounter) $line = preg_replace('/{iteration ([a-zA-Z0-9_]+)}/','\\1', $line);
23061
23062 $words = explode(' ', $line);
23063
23064 foreach ($words as $k=>$word) { // mPDF 5.3.61
23065 $word = trim($word);
23066 $wordwidth = $this->GetStringWidth($word);
23067 // mPDF 5.3.61
23068 if ($k==0) { $wordwidth += $lbw; }
23069 if ($k==(count($words)-1)) { $wordwidth += $rbw; }
23070 //maxwidth is insufficient for one word
23071 if ($wordwidth > $maxwidth + 0.0001) {
23072 $firstchunk=true;
23073 while($wordwidth > $maxwidth + 0.0001) {
23074 $chw = 0; // check width
23075 $oneCJKorphan = false;
23076 $mlen = mb_strlen($word, $this->mb_enc ); // mPDF 5.3.07
23077 for ( $i = 0; $i < $mlen; $i++ ) { // mPDF 5.3.07
23078 $chw = $this->GetStringWidth(mb_substr($word,0,$i+1,$this->mb_enc ));
23079 // mPDF 5.3.61
23080 if ($k==0) { $chw += $lbw; }
23081 if ($k==(count($words)-1)) { $chw += $rbw; }
23082 if ($chw > $maxwidth) {
23083 if ($i==0 && $firstchunk) {
23084 // If first letter of line does not fit
23085 $wordwidth = $maxwidth - 0.0001;
23086 if ($this->debug) { $this->Error("Table cell width calculated less than that needed for one character!"); }
23087 break;
23088 }
23089 if (!$oneCJKorphan && (preg_match('/[\.\]),;:!?"'.$curlyquote . $curlylowquote.']$/',mb_substr($word,0,$i+1,$this->mb_enc )) || (!$this->usingCoreFont && preg_match('/['.$this->CJKoverflow.']$/u',mb_substr($word,0,$i+1,$this->mb_enc ))))) {
23090 $wordwidth = $maxwidth - 0.0001;
23091 $oneCJKorphan = true;
23092 continue;
23093 }
23094 if ($text && $firstchunk) {
23095 // END OF LINE
23096 // Finalise & add lineheight
23097 $maxfontsize = max($maxfontsize,$this->FontSize);
23098 $fh = $this->_computeLineheight($this->table_lineheight);
23099 if ($lhfixed && $this->FontSize > $def_fontsize) {
23100 $fh = $this->FontSize;
23101 $forceExactLineheight = false;
23102 }
23103 $maxlineHeight = max($maxlineHeight,$fh);
23104 $ch += $this->finaliseCellLineHeight($lhxt, $maxfontsize, $maxlineHeight, $lhfixed, $forceExactLineheight);
23105 // START OF NEW LINE
23106 // Initialise lineheight variables
23107 $maxfontsize = $this->FontSize;
23108 $forceExactLineheight = true;
23109 $lhxt = array('BS'=>0, 'M'=>0, 'TT'=>0, 'TB'=>0, 'T'=>0, 'B'=>0);
23110 $maxlineHeight = $this->_computeLineheight($this->table_lineheight);
23111 $ln++;
23112 }
23113 // END OF LINE
23114 // Finalise & add lineheight
23115 $maxfontsize = max($maxfontsize,$this->FontSize);
23116 $fh = $this->_computeLineheight($this->table_lineheight);
23117 if ($lhfixed && $this->FontSize > $def_fontsize) {
23118 $fh = $this->FontSize;
23119 $forceExactLineheight = false;
23120 }
23121 $maxlineHeight = max($maxlineHeight,$fh);
23122 $ch += $this->finaliseCellLineHeight($lhxt, $maxfontsize, $maxlineHeight, $lhfixed, $forceExactLineheight);
23123 // START OF NEW LINE
23124 // Initialise lineheight variables
23125 $maxfontsize = $this->FontSize;
23126 $forceExactLineheight = true;
23127 $lhxt = array('BS'=>0, 'M'=>0, 'TT'=>0, 'TB'=>0, 'T'=>0, 'B'=>0);
23128 $maxlineHeight = $this->_computeLineheight($this->table_lineheight);
23129 $ln++;
23130 $mxw = $maxwidth;
23131 $text = mb_substr($word,0,$i,$this->mb_enc );
23132 $word = mb_substr($word,$i,mb_strlen($word, $this->mb_enc )-$i,$this->mb_enc );
23133 $wordwidth = $this->GetStringWidth($word);
23134 $width = 0;
23135 $firstchunk=false;
23136 break;
23137 }
23138 }
23139 if (mb_strlen($word, $this->mb_enc )<2 && $wordwidth > $maxwidth + 0.0001) {
23140 $wordwidth = $maxwidth - 0.0001;
23141 if ($this->debug) { $this->Error("Table cell width calculated less than that needed for single character!"); }
23142 }
23143 $firstchunk=false;
23144 }
23145 }
23146 // Word fits on line...
23147 if ($width + $wordwidth < $maxwidth + 0.0001) {
23148 $mxw = max($mxw, ($width+$wordwidth));
23149 $width += $wordwidth + $space;
23150 $text .= $word.' ';
23151 }
23152 // Word does not fit on line...
23153 else {
23154 $alloworphans = false;
23155 // In case of orphan punctuation or SUB/SUP
23156 // Strip end punctuation
23157 $tmp = preg_replace('/[\.\]),;:!?"'.$curlyquote . $curlylowquote.']{1}$/','',$word);
23158 if (!$this->usingCoreFont) { $tmp = preg_replace('/['.$this->CJKoverflow.']{1}$/u','',$tmp); } // *CJK-FONTS*
23159 if ($tmp !== $word && (($this->usingCoreFont && !preg_match('/[\.\]),;:!?"'.$curlyquote . $curlylowquote.']$/',$tmp)) || (!$this->usingCoreFont && !preg_match('/[\.\]),;:!?"'.$curlyquote . $curlylowquote .$this->CJKoverflow.']$/u',$tmp)))) {
23160 $tmpwidth = $this->GetStringWidth($tmp);
23161 // mPDF 5.3.61
23162 if ($k==0) { $tmpwidth += $lbw; }
23163 if ($k==(count($words)-1)) { $tmpwidth += $rbw; }
23164 if ($width + $tmpwidth < $maxwidth + 0.0001) { $alloworphans = true; }
23165 }
23166 // If line = SUB/SUP to max of orphansallowed ( $this->SUP || $this->SUB )
23167 if(( (isset($chunk[5]) and $chunk[5]) || (isset($chunk[6]) and $chunk[6])) && strlen($word) <= $this->orphansAllowed) {
23168 $alloworphans = true;
23169 }
23170
23171
23172 // if [stripped] word fits
23173 if ($alloworphans) {
23174 $mxw = $maxwidth;
23175 $width += $wordwidth + $space;
23176 $text .= $word.' ';
23177 }
23178 else {
23179 /*-- HYPHENATION --*/
23180 // Soft Hyphens chr(173)
23181 if ((!$this->usingCoreFont && preg_match("/\xc2\xad/",$word)) || ($this->usingCoreFont && preg_match("/".chr(173)."/",$word) && ($this->FontFamily!='csymbol' && $this->FontFamily!='czapfdingbats')) ) {
23182 list($success,$pre,$post,$prelength) = $this->softHyphenate($word, ($maxwidth - $width));
23183 if ($success) {
23184 $text .= $pre.'-';
23185 $word = $post;
23186 $wordwidth = $this->GetStringWidth($word);
23187 // mPDF 5.3.61
23188 if ($k==(count($words)-1)) { $wordwidth += $rbw; }
23189 }
23190 }
23191 else if ($this->hyphenate || ($this->hyphenateTables)) {
23192 list($success,$pre,$post,$prelength) = $this->hyphenateWord($word, ($maxwidth - $width));
23193 if ($success) {
23194 $text .= $pre.'-';
23195 $word = $post;
23196 $wordwidth = $this->GetStringWidth($word);
23197 // mPDF 5.3.61
23198 if ($k==(count($words)-1)) { $wordwidth += $rbw; }
23199 }
23200 }
23201 /*-- END HYPHENATION --*/
23202 // END OF LINE
23203 // Finalise & add lineheight
23204 $maxfontsize = max($maxfontsize,$this->FontSize);
23205 $fh = $this->_computeLineheight($this->table_lineheight);
23206 if ($lhfixed && $this->FontSize > $def_fontsize) {
23207 $fh = $this->FontSize;
23208 $forceExactLineheight = false;
23209 }
23210 $maxlineHeight = max($maxlineHeight,$fh);
23211 $ch += $this->finaliseCellLineHeight($lhxt, $maxfontsize, $maxlineHeight, $lhfixed, $forceExactLineheight);
23212 $mxw = $maxwidth;
23213 // START OF NEW LINE
23214 // Initialise lineheight variables
23215 $maxfontsize = $this->FontSize;
23216 $forceExactLineheight = true;
23217 $lhxt = array('BS'=>0, 'M'=>0, 'TT'=>0, 'TB'=>0, 'T'=>0, 'B'=>0);
23218 $maxlineHeight = $this->_computeLineheight($this->table_lineheight);
23219 $ln++;
23220 $width = $wordwidth + $space;
23221 $text = $word.' ';
23222 }
23223 }
23224 $maxfontsize = max($maxfontsize,$this->FontSize);
23225 $fh = $this->_computeLineheight($this->table_lineheight);
23226 if ($lhfixed && $this->FontSize > $def_fontsize) {
23227 $fh = $this->FontSize;
23228 $forceExactLineheight = false;
23229 }
23230 $maxlineHeight = max($maxlineHeight,$fh);
23231 }
23232
23233 // End of textbuffer chunk
23234 if (!$lsend) {
23235 $width -= $space;
23236 $text = rtrim($text);
23237 }
23238
23239 // RESET FONT SIZE/STYLE
23240 // RESETTING VALUES
23241 //Now we must deactivate what we have used
23242 if(isset($chunk[2]) and $chunk[2] != '') {
23243 $this->ResetStyles();
23244 }
23245 if(isset($chunk[4]) and $chunk[4] != '') {
23246 $this->SetFont($this->default_font,$this->FontStyle,0,false);
23247 }
23248 if(isset($chunk[11]) and $chunk[11] != '') {
23249 $this->SetFontSize($this->default_font_size,false);
23250 }
23251 $this->spanborddet = array(); // mPDF 5.3.61
23252 $this->kerning = false;
23253 $this->lSpacingCSS = '';
23254 $this->wSpacingCSS = '';
23255 $this->fixedlSpacing = false;
23256 $this->minwSpacing = 0;
23257 }
23258 // Finalise lineheight if something output on line and add
23259 if ($width) {
23260 $ch += $this->finaliseCellLineHeight($lhxt, $maxfontsize, $maxlineHeight, $lhfixed, $forceExactLineheight);
23261 }
23262 if ($returnarray) { return array($ch,$ln,$mxw); }
23263 else { return $ch; }
23264
23265 }
23266
23267
23268 function TableCheckMinWidth($maxwidth, $forcewrap = 0, $textbuffer) { // mPDF 5.3.78
23269 $biggestword=0;
23270 $toonarrow=false;
23271 if ((count($textbuffer) == 0) or ((count($textbuffer) == 1) && ($textbuffer[0][0] == ''))) { return 0; }
23272
23273 foreach ($textbuffer as $chunk) {
23274
23275 $line = $chunk[0];
23276 // mPDF ITERATION
23277 if ($this->iterationCounter) $line = preg_replace('/{iteration ([a-zA-Z0-9_]+)}/','\\1', $line);
23278
23279 // IMAGES & FORM ELEMENTS
23280 if (substr($line,0,3) == "\xbb\xa4\xac") { //inline object - FORM element or IMAGE!
23281 $objattr = $this->_getObjAttr($line);
23282 if ($objattr['type']!='hr' && isset($objattr['width']) && ($objattr['width']/$this->shrin_k) > ($maxwidth + 0.0001) ) {
23283 if (($objattr['width']/$this->shrin_k) > $biggestword) { $biggestword = ($objattr['width']/$this->shrin_k); }
23284 $toonarrow=true;
23285 }
23286 continue;
23287 }
23288
23289 if ($line == "\n") {
23290 continue;
23291 }
23292 $line = trim($line );
23293 // SET FONT SIZE/STYLE from $chunk[n]
23294
23295 // FONTSIZE
23296 if(isset($chunk[11]) and $chunk[11] != '') {
23297 if ($this->shrin_k) {
23298 $this->SetFontSize($chunk[11]/$this->shrin_k,false);
23299 }
23300 else {
23301 $this->SetFontSize($chunk[11],false);
23302 }
23303 }
23304 // FONTFAMILY
23305 if(isset($chunk[4]) and $chunk[4] != '') { $font = $this->SetFont($chunk[4],$this->FontStyle,0,false); }
23306 // B I U
23307 if(isset($chunk[2]) and $chunk[2] != '') {
23308 $this->SetStyles($chunk[2]);
23309 }
23310
23311 // mPDF 5.3.61
23312 $lbw = $rbw = 0; // Border widths
23313 if(isset($chunk[16]) && !empty($chunk[16])) { //Border
23314 $this->spanborddet = $chunk[16];
23315 $lbw = $this->spanborddet['L']['w'];
23316 $rbw = $this->spanborddet['R']['w'];
23317 }
23318 if(isset($chunk[15])) { // Word spacing
23319 $this->wSpacingCSS = $chunk[15];
23320 if ($this->wSpacingCSS && strtoupper($this->wSpacingCSS) != 'NORMAL') {
23321 $this->minwSpacing = $this->ConvertSize($this->wSpacingCSS,$this->FontSize);
23322 }
23323 }
23324 if(isset($chunk[14])) { // Letter spacing
23325 $this->lSpacingCSS = $chunk[14];
23326 if (($this->lSpacingCSS || $this->lSpacingCSS==='0') && strtoupper($this->lSpacingCSS) != 'NORMAL') {
23327 $this->fixedlSpacing = $this->ConvertSize($this->lSpacingCSS,$this->FontSize);
23328 }
23329 }
23330 if(isset($chunk[13])) { // Font Kerning
23331 $this->kerning = $chunk[13];
23332 }
23333
23334 $words = explode(' ', $line);
23335 foreach ($words as $k=>$word) { // mPDF 5.3.61
23336 $word = trim($word);
23337 $wordwidth = $this->GetStringWidth($word);
23338 // mPDF 5.3.61
23339 if ($k==0) { $wordwidth += $lbw; }
23340 if ($k==(count($words)-1)) { $wordwidth += $rbw; }
23341
23342 //Warn user that maxwidth is insufficient
23343 if ($wordwidth > $maxwidth + 0.0001) {
23344 if ($wordwidth > $biggestword) { $biggestword = $wordwidth; }
23345 $toonarrow=true;
23346 }
23347 }
23348
23349 // RESET FONT SIZE/STYLE
23350 // RESETTING VALUES
23351 //Now we must deactivate what we have used
23352 if(isset($chunk[2]) and $chunk[2] != '') {
23353 $this->ResetStyles();
23354 }
23355 if(isset($chunk[4]) and $chunk[4] != '') {
23356 $this->SetFont($this->default_font,$this->FontStyle,0,false);
23357 }
23358 if(isset($chunk[11]) and $chunk[11] != '') {
23359 $this->SetFontSize($this->default_font_size,false);
23360 }
23361 // mPDF 5.3.61
23362 $this->spanborddet = array();
23363 $this->kerning = false;
23364 $this->lSpacingCSS = '';
23365 $this->wSpacingCSS = '';
23366 $this->fixedlSpacing = false;
23367 $this->minwSpacing = 0;
23368 }
23369
23370 //Return -(wordsize) if word is bigger than maxwidth
23371 // ADDED
23372 if (($toonarrow) && ($this->table_error_report)) {
23373 $this->Error("Word is too long to fit in table - ".$this->table_error_report_param);
23374 }
23375 if ($toonarrow) return -$biggestword;
23376 else return 1;
23377 }
23378
23379 function shrinkTable(&$table,$k) {
23380 $table['border_spacing_H'] /= $k;
23381 $table['border_spacing_V'] /= $k;
23382
23383 $table['padding']['T'] /= $k;
23384 $table['padding']['R'] /= $k;
23385 $table['padding']['B'] /= $k;
23386 $table['padding']['L'] /= $k;
23387
23388 $table['margin']['T'] /= $k;
23389 $table['margin']['R'] /= $k;
23390 $table['margin']['B'] /= $k;
23391 $table['margin']['L'] /= $k;
23392
23393 $table['border_details']['T']['w'] /= $k;
23394 $table['border_details']['R']['w'] /= $k;
23395 $table['border_details']['B']['w'] /= $k;
23396 $table['border_details']['L']['w'] /= $k;
23397
23398 if (isset($table['max_cell_border_width']['T'])) $table['max_cell_border_width']['T'] /= $k;
23399 if (isset($table['max_cell_border_width']['R'])) $table['max_cell_border_width']['R'] /= $k;
23400 if (isset($table['max_cell_border_width']['B'])) $table['max_cell_border_width']['B'] /= $k;
23401 if (isset($table['max_cell_border_width']['L'])) $table['max_cell_border_width']['L'] /= $k;
23402
23403 if ($this->simpleTables){
23404 $table['simple']['border_details']['T']['w'] /= $k;
23405 $table['simple']['border_details']['R']['w'] /= $k;
23406 $table['simple']['border_details']['B']['w'] /= $k;
23407 $table['simple']['border_details']['L']['w'] /= $k;
23408 }
23409
23410 $table['miw'] /= $k;
23411 $table['maw'] /= $k;
23412
23413 // mPDF 5.3.79
23414 if ($this->cacheTables) { $fh = fopen($table['cache'], "r+b"); }
23415
23416 for($j = 0 ; $j < $table['nc'] ; $j++ ) { //columns
23417
23418 $table['wc'][$j]['miw'] /= $k;
23419 $table['wc'][$j]['maw'] /= $k;
23420
23421 if (isset($table['wc'][$j]['absmiw']) && $table['wc'][$j]['absmiw'] ) $table['wc'][$j]['absmiw'] /= $k;
23422
23423 for($i = 0 ; $i < $table['nr']; $i++ ) { //rows
23424 // mPDF 5.3.79
23425 if ($this->cacheTables) {
23426 $c = $this->_uncacheCell($table['cells'][$i][$j], '', $fh);
23427 }
23428 else
23429 $c = &$table['cells'][$i][$j];
23430 if (isset($c) && $c) {
23431 if (!$this->simpleTables){
23432 if ($this->packTableData) {
23433 $cell = $this->_unpackCellBorder($c['borderbin'] );
23434 $cell['border_details']['T']['w'] /= $k;
23435 $cell['border_details']['R']['w'] /= $k;
23436 $cell['border_details']['B']['w'] /= $k;
23437 $cell['border_details']['L']['w'] /= $k;
23438 $cell['border_details']['mbw']['TL'] /= $k;
23439 $cell['border_details']['mbw']['TR'] /= $k;
23440 $cell['border_details']['mbw']['BL'] /= $k;
23441 $cell['border_details']['mbw']['BR'] /= $k;
23442 $cell['border_details']['mbw']['LT'] /= $k;
23443 $cell['border_details']['mbw']['LB'] /= $k;
23444 $cell['border_details']['mbw']['RT'] /= $k;
23445 $cell['border_details']['mbw']['RB'] /= $k;
23446 $c['borderbin'] = $this->_packCellBorder($cell);
23447 }
23448 else {
23449 $c['border_details']['T']['w'] /= $k;
23450 $c['border_details']['R']['w'] /= $k;
23451 $c['border_details']['B']['w'] /= $k;
23452 $c['border_details']['L']['w'] /= $k;
23453 $c['border_details']['mbw']['TL'] /= $k;
23454 $c['border_details']['mbw']['TR'] /= $k;
23455 $c['border_details']['mbw']['BL'] /= $k;
23456 $c['border_details']['mbw']['BR'] /= $k;
23457 $c['border_details']['mbw']['LT'] /= $k;
23458 $c['border_details']['mbw']['LB'] /= $k;
23459 $c['border_details']['mbw']['RT'] /= $k;
23460 $c['border_details']['mbw']['RB'] /= $k;
23461 }
23462 }
23463 $c['padding']['T'] /= $k;
23464 $c['padding']['R'] /= $k;
23465 $c['padding']['B'] /= $k;
23466 $c['padding']['L'] /= $k;
23467 $c['maxs'] /= $k;
23468 if (isset($c['w'])) { $c['w'] /= $k; }
23469 $c['s'] /= $k;
23470 $c['maw'] /= $k;
23471 $c['miw'] /= $k;
23472 if (isset($c['absmiw'])) $c['absmiw'] /= $k;
23473 if (isset($c['nestedmaw'])) $c['nestedmaw'] /= $k;
23474 if (isset($c['nestedmiw'])) $c['nestedmiw'] /= $k;
23475 // mPDF 5.3.61
23476 if (isset($c['textbuffer'])) {
23477 foreach($c['textbuffer'] AS $n=>$tb) {
23478 if (!empty($tb[16])) {
23479 $c['textbuffer'][$n][16]['T']['w'] /= $k;
23480 $c['textbuffer'][$n][16]['B']['w'] /= $k;
23481 $c['textbuffer'][$n][16]['L']['w'] /= $k;
23482 $c['textbuffer'][$n][16]['R']['w'] /= $k;
23483 }
23484 }
23485 }
23486 // mPDF 5.3.79
23487 if ($this->cacheTables) {
23488 $this->_cacheCell($c, '', "W", $fh, $table['cells'][$i][$j]);
23489 }
23490 unset($c); // mPDF 5.3.79
23491 }
23492 }//rows
23493 }//columns
23494 // mPDF 5.3.79
23495 if ($this->cacheTables) { fclose($fh); }
23496 }
23497
23498 // mPDF 5.3.79
23499 function _cacheCell($c, $file, $mode="A", $fh=null, $offset=0) { // mode = Append or (over)Write (needs offset and fh)
23500 // Requires either $file OR $fh (file_handle)
23501 if (!is_array($c) || !isset($c)) { return ''; }
23502
23503 if(isset($c['w'])) { $cw = $c['w']; } else { $cw = -1; }
23504 if(isset($c['w0'])) { $cw0 = $c['w0']; } else { $cw0 = -1; }
23505 if(isset($c['h0'])) { $ch0 = $c['h0']; } else { $ch0 = -1; }
23506
23507 $data = pack("n2d19A1A1n2sA32A128",
23508 $c['colspan'], /* n (16 bit; 2 bytes) [pos 0] */
23509 $c['rowspan'], /* n (16 bit; 2 bytes) [pos 2] */
23510 $c['s'], /* d NB machine-dependent size (64 bit; 8 bytes on test winOS) [pos 4] */
23511 $c['maxs'], /* d NB machine-dependent size [pos 4 + 1*D] */
23512 $c['nestedmaw'], /* d NB machine-dependent size [pos 4 + 2*D] */
23513 $c['nestedmiw'], /* d NB machine-dependent size [pos 4 + 3*D] */
23514 $c['padding']['L'], /* d NB machine-dependent size [pos 4 + 4*D] */
23515 $c['padding']['R'], /* d NB machine-dependent size [pos 4 + 5*D] */
23516 $c['padding']['T'], /* d NB machine-dependent size [pos 4 + 6*D] */
23517 $c['padding']['B'], /* d NB machine-dependent size [pos 4 + 7*D] */
23518 $c['dfs'], /* d NB machine-dependent size [pos 4 + 8*D] */
23519 $cw, /* d NB machine-dependent size [pos 4 + 9*D] */
23520 $c['h'], /* d NB machine-dependent size [pos 4 + 10*D] */
23521 $c['absmiw'], /* d NB machine-dependent size [pos 4 + 11*D] */
23522 $c['maw'], /* d NB machine-dependent size [pos 4 + 12*D] */
23523 $c['miw'], /* d NB machine-dependent size [pos 4 + 13*D] */
23524 $c['mih'], /* d NB machine-dependent size [pos 4 + 14*D] */
23525 $c['x0'], /* d NB machine-dependent size [pos 4 + 15*D] */
23526 $cw0, /* d NB machine-dependent size [pos 4 + 16*D] */
23527 $c['y0'], /* d NB machine-dependent size [pos 4 + 17*D] */
23528 $ch0, /* d NB machine-dependent size [pos 4 + 18*D] */
23529 $c['a'], /* A1 (1 byte) [pos 4 + 19*D] */
23530 $c['va'], /* A1 (1 byte) [pos 5 + 19*D] */
23531 $c['nowrap'], /* 1 or blank n (16 bit; 2 bytes) [pos 6 + 19*D] */
23532 $c['wpercent'], /* 0 - 100 n (16 bit; 2 bytes) [pos 8 + 19*D] */
23533 $c['R'], /* 90 or -90 s (16 bit; 2 bytes) [pos 10 + 19*D] */
23534 $c['bgcolor'], /* A32 (32 bytes) [pos 12 + 19*D] */
23535 $c['gradient'] /* A128 (128 bytes) [pos 44 + 19*D] */
23536 );
23537
23538 if ($c['background-image']) {
23539 $data .= pack("n2d2A6A6n3dA4A128",
23540 strlen($data), /* offset in main data to start of bgimage data */
23541 $c['background-image']['image_id'], /* n */
23542 $c['background-image']['orig_w'], /* d NB machine-dependent size */
23543 $c['background-image']['orig_h'], /* d NB machine-dependent size */
23544 $c['background-image']['x_pos'], /* A6 calc size or "50%" */
23545 $c['background-image']['y_pos'], /* A6 calc size or "50%" */
23546 $c['background-image']['x_repeat'], /* n true or false*/
23547 $c['background-image']['y_repeat'], /* n true or false */
23548 $c['background-image']['resize'], /* n 0 - 6 */
23549 $c['background-image']['opacity'], /* d 0-1 */
23550 $c['background-image']['itype'], /* A4 jpg etc */
23551 $c['background-image']['gradient'] /* A128 CSS string */
23552 );
23553 }
23554 else $data .= pack("n",0);
23555 $tb_offset = 2 + 186 + 2 + strlen($data);
23556 $stb = serialize($c['textbuffer']).' '; // buffer to allow updating in reverseTableDir
23557 $lentb = strlen($stb);
23558 $data2 = pack("nA".$lentb, $lentb, $stb);
23559
23560 $tempfh = true;
23561 if ($mode=="W" && $offset) {
23562 if (!$fh) { $fh = fopen($file, "r+b"); } // Overwrite (but not truncate)
23563 else $tempfh = false;
23564 fseek($fh, $offset);
23565 }
23566 else {
23567 $fh = fopen($file, "ab"); // APPEND
23568 }
23569 fwrite($fh, pack("n",$tb_offset)); // Offset to Text buffer 2 bytes
23570 fwrite($fh, $c['borderbin']); // border details 186 bytes
23571 fwrite($fh, pack("n",strlen($data))); // Length of Main data
23572 fwrite($fh, $data); // Main data
23573 fwrite($fh, $data2); // Text buffer (starts with "n" length of text buffer)
23574 if ($tempfh) fclose($fh);
23575 return ($tb_offset + 2 + $lentb);
23576 }
23577
23578 // mPDF 5.3.79
23579 function _cacheUpdateTxB($c, $fh, $offset) {
23580 fseek($fh, $offset);
23581 $tb_offset = $this->read_short($fh); // First entry = Offset to Text buffer 2 bytes
23582 fseek($fh, ($tb_offset-2), SEEK_CUR);
23583 $lentb = $this->read_short($fh); // First entry in textbuffer = Length of serialized textbuffer - do not update
23584 $stb = serialize($c['textbuffer']);
23585 fwrite($fh, pack("A".$lentb, $stb));
23586 }
23587
23588 // mPDF 5.3.79
23589 function _cacheUpdateBorder($c, $fh, $offset) {
23590 $offset += 2;
23591 fseek($fh, $offset);
23592 fwrite($fh, $c['borderbin']);
23593 }
23594
23595 // mPDF 5.3.79
23596 function _cacheUpdateMtx($c, $fh, $offset, $var) {
23597 if ($var=='mih') { $offset += (2 + 186 + 2 + 4 + 14*_DSIZE); }
23598 else if ($var=='x0') { $offset += (2 + 186 + 2 + 4 + 15*_DSIZE); } // x0 and w0
23599 else if ($var=='y0') { $offset += (2 + 186 + 2 + 4 + 17*_DSIZE); } // y0 and h0
23600 fseek($fh, $offset);
23601 if ($var=='mih') { fwrite($fh, pack("d",$c['mih'])); }
23602 else if ($var=='x0') { fwrite($fh, pack("d2",$c['x0'],$c['w0'])); }
23603 else if ($var=='y0') { fwrite($fh, pack("d2",$c['y0'],$c['h0'])); }
23604 }
23605
23606 // mPDF 5.3.79
23607 function _uncacheCell($ptr, $file, $fh) {
23608 // Requires either $file or $fh (file_handle)
23609 if ($ptr==0) { return null; }
23610 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 "); }
23611 $tempfh = true;
23612 if (!$fh) { $fh = fopen($file, "rb"); }
23613 else $tempfh = false;
23614 fseek($fh, $ptr);
23615 $c = array();
23616 $tb_offset = $this->read_short($fh); // First entry = Offset to Text buffer 2 bytes
23617 $c['borderbin'] = fread($fh,186); // border details 186 bytes
23618 $maindatalen = $this->read_short($fh); // Length of Main data (2 bytes)
23619 $str = fread($fh,$maindatalen ); // Main data
23620 $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);
23621
23622 if ($data['colspan']>0) $c['colspan'] = $data['colspan']; /* n */
23623 if ($data['rowspan']>0) $c['rowspan'] = $data['rowspan']; /* n */
23624 $c['s'] = $data['s']; /* d NB machine-dependent size */
23625 $c['maxs'] = $data['maxs']; /* d NB machine-dependent size */
23626 if ($data['nmaw']>0) $c['nestedmaw'] = $data['nmaw']; /* d NB machine-dependent size */
23627 if ($data['nmiw']>0) $c['nestedmiw'] = $data['nmiw']; /* d NB machine-dependent size */
23628 $c['padding']['L'] = $data['pl']; /* d NB machine-dependent size */
23629 $c['padding']['R'] = $data['pr']; /* d NB machine-dependent size */
23630 $c['padding']['T'] = $data['pt']; /* d NB machine-dependent size */
23631 $c['padding']['B'] = $data['pb']; /* d NB machine-dependent size */
23632 $c['dfs'] = $data['dfs']; /* d NB machine-dependent size */
23633 if ($data['w']>=0) $c['w'] = $data['w']; /* d NB machine-dependent size */
23634 if ($data['h']>0) $c['h'] = $data['h']; /* d NB machine-dependent size */
23635 if ($data['absmiw']>0) $c['absmiw'] = $data['absmiw']; /* d NB machine-dependent size */
23636 if ($data['maw']>0) $c['maw'] = $data['maw']; /* d NB machine-dependent size */
23637 if ($data['miw']>0) $c['miw'] = $data['miw']; /* d NB machine-dependent size */
23638 if ($data['mih']>0) $c['mih'] = $data['mih']; /* d NB machine-dependent size */
23639 if ($data['w0']>=0) { $c['w0'] = $data['w0']; /* d NB machine-dependent size */
23640 $c['x0'] = $data['x0']; } /* d NB machine-dependent size */
23641 if ($data['h0']>=0) { $c['h0'] = $data['h0']; /* d NB machine-dependent size */
23642 $c['y0'] = $data['y0']; } /* d NB machine-dependent size */
23643 $c['a'] = trim($data['a']); /* A1 */
23644 $c['va'] = trim($data['va']); /* A1 */
23645 if ($data['nowrap']) $c['nowrap'] = $data['nowrap']; /* 1 or blank n */
23646 else $c['nowrap'] = false;
23647 if ($data['wpercent']>0) $c['wpercent'] = $data['wpercent']; /* 0 - 100 n */
23648 if ($data['R']<>0) $c['R'] = $data['R']; /* 90 or -90 s */
23649 else $c['R'] = false;
23650 $c['bgcolor'] = trim($data['bgcol']); /* A32 */
23651 if (trim($data['grad']))
23652 $c['gradient'] = trim($data['grad']); /* A128 */
23653 else $c['gradient'] = false;
23654 if ($data['bgimage']>0) {
23655 $bgidata = substr($str, ($data['bgimage']+2));
23656 $c['background-image'] = unpack("nimage_id/dorig_w/dorig_h/A6x_pos/A6y_pos/nx_repeat/ny_repeat/nresize/dopacity/A4itype/A128gradient", $bgidata);
23657 }
23658
23659 $tblen = $this->read_short($fh); // Length of Textbuffer
23660 $tbsp = fread($fh,$tblen); // Textbuffer (serialised and packed)
23661 $tbs = unpack("A".$tblen."textbuffer",$tbsp); // Textbuffer unpacked
23662 $c['textbuffer'] = unserialize(trim($tbs['textbuffer'])); // Textbuffer unserialized
23663
23664 if ($tempfh) { fclose($fh); }
23665 return ($c);
23666 }
23667 // mPDF 5.3.79
23668 function read_short(&$fh) {
23669 $s = fread($fh,2);
23670 $a = (ord($s[0])<<8) + ord($s[1]);
23671 if ($a & (1 << 15) ) {
23672 $a = ($a - (1 << 16));
23673 }
23674 return $a;
23675 }
23676 // mPDF 5.3.79
23677 function _backupCacheFiles() {
23678 foreach($this->table AS $lvl=>$t) {
23679 foreach($this->table[$lvl] AS $c=>$t2) {
23680 ///////////////////////////if (!file_exists($t2['cache'])) { echo $lvl; echo $c; print_r($this->table); exit; }
23681 copy( $t2['cache'], $t2['cache'].'.bak');
23682 }
23683 }
23684 }
23685 // mPDF 5.3.79
23686 function _restoreCacheFiles() {
23687 foreach($this->table AS $lvl=>$t) {
23688 foreach($this->table[$lvl] AS $c=>$t2) {
23689 copy( $t2['cache'].'.bak', $t2['cache']);
23690 }
23691 }
23692 }
23693
23694
23695 function _packCellBorder($cell) {
23696 if (!is_array($cell) || !isset($cell)) { return ''; }
23697
23698 if (!$this->packTableData) { return $cell; }
23699 // mPDF 5.3.74
23700 // = 186 bytes
23701 $bindata = pack("nnda6A10nnda6A10nnda6A10nnda6A10nd9",
23702 $cell['border'],
23703 $cell['border_details']['R']['s'],
23704 $cell['border_details']['R']['w'],
23705 $cell['border_details']['R']['c'],
23706 $cell['border_details']['R']['style'],
23707 $cell['border_details']['R']['dom'],
23708
23709 $cell['border_details']['L']['s'],
23710 $cell['border_details']['L']['w'],
23711 $cell['border_details']['L']['c'],
23712 $cell['border_details']['L']['style'],
23713 $cell['border_details']['L']['dom'],
23714
23715 $cell['border_details']['T']['s'],
23716 $cell['border_details']['T']['w'],
23717 $cell['border_details']['T']['c'],
23718 $cell['border_details']['T']['style'],
23719 $cell['border_details']['T']['dom'],
23720
23721 $cell['border_details']['B']['s'],
23722 $cell['border_details']['B']['w'],
23723 $cell['border_details']['B']['c'],
23724 $cell['border_details']['B']['style'],
23725 $cell['border_details']['B']['dom'],
23726
23727 $cell['border_details']['mbw']['BL'],
23728 $cell['border_details']['mbw']['BR'],
23729 $cell['border_details']['mbw']['RT'],
23730 $cell['border_details']['mbw']['RB'],
23731 $cell['border_details']['mbw']['TL'],
23732 $cell['border_details']['mbw']['TR'],
23733 $cell['border_details']['mbw']['LT'],
23734 $cell['border_details']['mbw']['LB'],
23735
23736 $cell['border_details']['cellposdom']
23737 );
23738 return $bindata;
23739 }
23740
23741
23742
23743 function _getBorderWidths($bindata) {
23744 if (!$bindata) { return array(0,0,0,0); }
23745 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']); }
23746
23747 // mPDF 5.3.74
23748 $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);
23749 $cell['border_details']['R']['w'] = $bd['rw'];
23750 $cell['border_details']['L']['w'] = $bd['lw'];
23751 $cell['border_details']['T']['w'] = $bd['tw'];
23752 $cell['border_details']['B']['w'] = $bd['bw'];
23753 return array($bd['tw'], $bd['rw'], $bd['bw'], $bd['lw']);
23754 }
23755
23756
23757 function _unpackCellBorder($bindata) {
23758 if (!$bindata) { return array(); }
23759 if (!$this->packTableData) { return $bindata; }
23760
23761 // mPDF 5.3.74
23762 $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);
23763
23764 $cell['border'] = $bd['bord'];
23765 $cell['border_details']['R']['s'] = $bd['rs'];
23766 $cell['border_details']['R']['w'] = $bd['rw'];
23767 $cell['border_details']['R']['c'] = $bd['rca'];
23768 $cell['border_details']['R']['style'] = trim($bd['rst']);
23769 $cell['border_details']['R']['dom'] = $bd['rd'];
23770
23771 $cell['border_details']['L']['s'] = $bd['ls'];
23772 $cell['border_details']['L']['w'] = $bd['lw'];
23773 $cell['border_details']['L']['c'] = $bd['lca'];
23774 $cell['border_details']['L']['style'] = trim($bd['lst']);
23775 $cell['border_details']['L']['dom'] = $bd['ld'];
23776
23777 $cell['border_details']['T']['s'] = $bd['ts'];
23778 $cell['border_details']['T']['w'] = $bd['tw'];
23779 $cell['border_details']['T']['c'] = $bd['tca'];
23780 $cell['border_details']['T']['style'] = trim($bd['tst']);
23781 $cell['border_details']['T']['dom'] = $bd['td'];
23782
23783 $cell['border_details']['B']['s'] = $bd['bs'];
23784 $cell['border_details']['B']['w'] = $bd['bw'];
23785 $cell['border_details']['B']['c'] = $bd['bca'];
23786 $cell['border_details']['B']['style'] = trim($bd['bst']);
23787 $cell['border_details']['B']['dom'] = $bd['bd'];
23788
23789 $cell['border_details']['mbw']['BL'] = $bd['mbl'];
23790 $cell['border_details']['mbw']['BR'] = $bd['mbr'];
23791 $cell['border_details']['mbw']['RT'] = $bd['mrt'];
23792 $cell['border_details']['mbw']['RB'] = $bd['mrb'];
23793 $cell['border_details']['mbw']['TL'] = $bd['mtl'];
23794 $cell['border_details']['mbw']['TR'] = $bd['mtr'];
23795 $cell['border_details']['mbw']['LT'] = $bd['mlt'];
23796 $cell['border_details']['mbw']['LB'] = $bd['mlb'];
23797 $cell['border_details']['cellposdom'] = $bd['cpd'];
23798
23799 return($cell);
23800 }
23801
23802
23803 ////////////////////////TABLE CODE (from PDFTable)/////////////////////////////////////
23804 ////////////////////////TABLE CODE (from PDFTable)/////////////////////////////////////
23805 ////////////////////////TABLE CODE (from PDFTable)/////////////////////////////////////
23806 //table Array of (w, h, bc, nr, wc, hr, cells)
23807 //w Width of table
23808 //h Height of table
23809 //nc Number column
23810 //nr Number row
23811 //hr List of height of each row
23812 //wc List of width of each column
23813 //cells List of cells of each rows, cells[i][j] is a cell in the table
23814 function _tableColumnWidth(&$table,$firstpass=false){
23815 $cs = &$table['cells'];
23816
23817 $nc = $table['nc'];
23818 $nr = $table['nr'];
23819 $listspan = array();
23820
23821 if ($table['borders_separate']) {
23822 $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'];
23823 }
23824 else { $tblbw = $table['max_cell_border_width']['L']/2 + $table['max_cell_border_width']['R']/2 + $table['margin']['L'] + $table['margin']['R']; }
23825
23826 // mPDF 5.3.79
23827 if ($this->cacheTables) { $fh = fopen($table['cache'], "r+b"); }
23828 else { $fh = null; }
23829
23830 // ADDED table['l'][colno]
23831 // = total length of text approx (using $c['s']) in that column - used to approximately distribute col widths in _tableWidth
23832 //
23833 for($j = 0 ; $j < $nc ; $j++ ) { //columns
23834 $wc = &$table['wc'][$j];
23835 for($i = 0 ; $i < $nr ; $i++ ) { //rows
23836 if (isset($cs[$i][$j]) && $cs[$i][$j]) {
23837 // mPDF 5.3.79
23838 if ($this->cacheTables) {
23839 $c = $this->_uncacheCell($table['cells'][$i][$j], '', $fh);
23840 }
23841 else
23842 $c = &$cs[$i][$j];
23843
23844 if ($this->simpleTables){
23845 if ($table['borders_separate']) { // NB twice border width
23846 $extrcw = $table['simple']['border_details']['L']['w'] + $table['simple']['border_details']['R']['w'] + $c['padding']['L'] + $c['padding']['R'] + $table['border_spacing_H'];
23847 }
23848 else {
23849 $extrcw = $table['simple']['border_details']['L']['w']/2 + $table['simple']['border_details']['R']['w']/2 + $c['padding']['L'] + $c['padding']['R'];
23850 }
23851 }
23852 else {
23853 if ($this->packTableData) {
23854 list($bt,$br,$bb,$bl) = $this->_getBorderWidths($c['borderbin']);
23855 }
23856 else {
23857 $br = $c['border_details']['R']['w'];
23858 $bl = $c['border_details']['L']['w'];
23859 }
23860 if ($table['borders_separate']) { // NB twice border width
23861 $extrcw = $bl + $br + $c['padding']['L'] + $c['padding']['R'] + $table['border_spacing_H'];
23862 }
23863 else {
23864 $extrcw = $bl/2 + $br/2 + $c['padding']['L'] + $c['padding']['R'];
23865 }
23866 }
23867
23868 //$mw = $this->GetStringWidth('W') + $extrcw ;
23869 $mw = 0;
23870
23871 $c['absmiw'] = $mw;
23872
23873 if (isset($c['R']) && $c['R']) {
23874 $c['maw'] = $c['miw'] = $this->FontSize + $extrcw ;
23875 if (isset($c['w'])) { // If cell width is specified
23876 if ($c['miw'] <$c['w']) { $c['miw'] = $c['w']; }
23877 }
23878 if (!isset($c['colspan'])) {
23879 if ($wc['miw'] < $c['miw']) { $wc['miw'] = $c['miw']; }
23880 if ($wc['maw'] < $c['maw']) { $wc['maw'] = $c['maw']; }
23881
23882 if ($firstpass) {
23883 if (isset($table['l'][$j]) ) {
23884 $table['l'][$j] += $c['miw'] ;
23885 }
23886 else {
23887 $table['l'][$j] = $c['miw'] ;
23888 }
23889 }
23890 }
23891 if ($c['miw'] > $wc['miw']) { $wc['miw'] = $c['miw']; }
23892 if ($wc['miw'] > $wc['maw']) { $wc['maw'] = $wc['miw']; }
23893 continue;
23894 }
23895
23896 if ($firstpass) {
23897 if (isset($c['s'])) { $c['s'] += $extrcw; }
23898 if (isset($c['maxs'])) { $c['maxs'] += $extrcw; }
23899 if (isset($c['nestedmiw'])) { $c['nestedmiw'] += $extrcw; }
23900 if (isset($c['nestedmaw'])) { $c['nestedmaw'] += $extrcw; }
23901 }
23902
23903
23904 // If minimum width has already been set by a nested table or inline object (image/form), use it
23905 if (isset($c['nestedmiw']) && $this->table[1][1]['overflow']!='visible') { $miw = $c['nestedmiw']; } // mPDF 5.3.36
23906 else { $miw = $mw; }
23907
23908 if (isset($c['maxs']) && $c['maxs'] != '') { $c['s'] = $c['maxs']; }
23909
23910 // If maximum width has already been set by a nested table, use it
23911 if (isset($c['nestedmaw'])) { $c['maw'] = $c['nestedmaw']; }
23912 else $c['maw'] = $c['s'];
23913
23914 // mPDF 5.3.36
23915 if (isset($table['overflow']) && $table['overflow']=='visible' && $table['level']==1) {
23916 if (($c['maw'] + $tblbw) > $this->blk[$this->blklvl]['inner_width']) {
23917 $c['maw'] = $this->blk[$this->blklvl]['inner_width'] - $tblbw;
23918 }
23919 }
23920
23921 if (isset($c['nowrap']) && $c['nowrap']) { $miw = $c['maw']; }
23922
23923 if (isset($c['wpercent']) && $firstpass) {
23924 if (isset($c['colspan'])) { // Not perfect - but % set on colspan is shared equally on cols.
23925 for($k=0;$k<$c['colspan'];$k++) {
23926 $table['wc'][($j+$k)]['wpercent'] = $c['wpercent'] / $c['colspan'];
23927 }
23928 }
23929 else {
23930 if (isset($table['w']) && $table['w']) { $c['w'] = $c['wpercent']/100 * ($table['w'] - $tblbw ); }
23931 $wc['wpercent'] = $c['wpercent'];
23932 }
23933 }
23934
23935 // mPDF 5.3.36
23936 if (isset($table['overflow']) && $table['overflow']=='visible' && $table['level']==1) {
23937 if (($c['w'] + $tblbw) > $this->blk[$this->blklvl]['inner_width']) {
23938 $c['w'] = $this->blk[$this->blklvl]['inner_width'] - $tblbw;
23939 }
23940 }
23941
23942
23943 if (isset($c['w'])) { // If cell width is specified
23944 if ($miw<$c['w']) { $c['miw'] = $c['w']; } // Cell min width = that specified
23945 if ($miw>$c['w']) { $c['miw'] = $c['w'] = $miw; } // If width specified is less than minimum allowed (W) increase it
23946 if (!isset($wc['w'])) { $wc['w'] = 1; } // If the Col width is not specified = set it to 1
23947
23948 }
23949 else { $c['miw'] = $miw; } // If cell width not specified -> set Cell min width it to minimum allowed (W)
23950
23951 if ($c['maw'] < $c['miw']) { $c['maw'] = $c['miw']; } // If Cell max width < Minwidth - increase it to =
23952 if (!isset($c['colspan'])) {
23953 if ($wc['miw'] < $c['miw']) { $wc['miw'] = $c['miw']; } // Update Col Minimum and maximum widths
23954 if ($wc['maw'] < $c['maw']) { $wc['maw'] = $c['maw']; }
23955 if ((isset($wc['absmiw']) && $wc['absmiw'] < $c['absmiw']) || !isset($wc['absmiw'])) { $wc['absmiw'] = $c['absmiw']; } // Update Col Minimum and maximum widths
23956
23957 if (isset($table['l'][$j]) ) {
23958 $table['l'][$j] += $c['s'];
23959 }
23960 else {
23961 $table['l'][$j] = $c['s'];
23962 }
23963
23964 }
23965 else {
23966 $listspan[] = array($i,$j);
23967 }
23968
23969 //Check if minimum width of the whole column is big enough for largest word to fit
23970 if (isset($c['textbuffer']) && !$this->tableCJK && (!isset($table['overflow']) || $table['overflow']!='wrap')) { // mPDF 5.3.50
23971 $minwidth = $this->TableCheckMinWidth($wc['miw']- $extrcw ,0,$c['textbuffer']); // mPDF 5.3.78
23972 }
23973 else { $minwidth = 0; }
23974 if ($minwidth < 0) {
23975 //increase minimum width
23976 if (!isset($c['colspan'])) {
23977 $wc['miw'] = max($wc['miw'],((-$minwidth) + $extrcw) );
23978 }
23979 else {
23980 $c['miw'] = max($c['miw'],((-$minwidth) + $extrcw) );
23981 }
23982 }
23983 if (!isset($c['colspan'])) {
23984 if ($wc['miw'] > $wc['maw']) { $wc['maw'] = $wc['miw']; } //update maximum width, if needed
23985 }
23986 // mPDF 5.3.79
23987 if ($this->cacheTables) {
23988 $this->_cacheCell($c, '', "W", $fh, $table['cells'][$i][$j]);
23989 }
23990 }
23991 unset($c);
23992 }//rows
23993 }//columns
23994
23995
23996 // COLUMN SPANS
23997 $wc = &$table['wc'];
23998 foreach ($listspan as $span) {
23999 list($i,$j) = $span;
24000 // mPDF 5.3.79
24001 if ($this->cacheTables) {
24002 $c = $this->_uncacheCell($cs[$i][$j], '', $fh);
24003 }
24004 else
24005 $c = &$cs[$i][$j];
24006 $lc = $j + $c['colspan'];
24007 if ($lc > $nc) { $lc = $nc; }
24008 $wis = $wisa = 0;
24009 $was = $wasa = 0;
24010 $list = array();
24011 for($k=$j;$k<$lc;$k++) {
24012 if (isset($table['l'][$k]) ) {
24013 if ($c['R']) { $table['l'][$k] += $c['miw']/$c['colspan'] ; }
24014 else { $table['l'][$k] += $c['s']/$c['colspan']; }
24015 }
24016 else {
24017 if ($c['R']) { $table['l'][$k] = $c['miw']/$c['colspan'] ; }
24018 else { $table['l'][$k] = $c['s']/$c['colspan']; }
24019 }
24020 $wis += $wc[$k]['miw'];
24021 $was += $wc[$k]['maw'];
24022 if (!isset($c['w'])) {
24023 $list[] = $k;
24024 $wisa += $wc[$k]['miw'];
24025 $wasa += $wc[$k]['maw'];
24026 }
24027 }
24028 if ($c['miw'] > $wis) {
24029 if (!$wis) {
24030 for($k=$j;$k<$lc;$k++) { $wc[$k]['miw'] = $c['miw']/$c['colspan']; }
24031 }
24032 else if (!count($list)) {
24033 $wi = $c['miw'] - $wis;
24034 for($k=$j;$k<$lc;$k++) { $wc[$k]['miw'] += ($wc[$k]['miw']/$wis)*$wi; }
24035 }
24036 else {
24037 $wi = $c['miw'] - $wis;
24038 foreach ($list as $k) { $wc[$k]['miw'] += ($wc[$k]['miw']/$wisa)*$wi; }
24039 }
24040 }
24041 if ($c['maw'] > $was) {
24042 if (!$wis) {
24043 for($k=$j;$k<$lc;$k++) { $wc[$k]['maw'] = $c['maw']/$c['colspan']; }
24044 }
24045 else if (!count($list)) {
24046 $wi = $c['maw'] - $was;
24047 for($k=$j;$k<$lc;$k++) { $wc[$k]['maw'] += ($wc[$k]['maw']/$was)*$wi; }
24048 }
24049 else {
24050 $wi = $c['maw'] - $was;
24051 foreach ($list as $k) { $wc[$k]['maw'] += ($wc[$k]['maw']/$wasa)*$wi; }
24052 }
24053 }
24054 unset($c);
24055 }
24056
24057 // mPDF 5.3.79
24058 if ($this->cacheTables) { fclose($fh); }
24059
24060 $checkminwidth = 0;
24061 $checkmaxwidth = 0;
24062 $totallength = 0;
24063
24064 for( $i = 0 ; $i < $nc ; $i++ ) {
24065 $checkminwidth += $table['wc'][$i]['miw'];
24066 $checkmaxwidth += $table['wc'][$i]['maw'];
24067 $totallength += $table['l'][$i];
24068 }
24069
24070 if (!isset($table['w']) && $firstpass) {
24071 $sumpc = 0;
24072 $notset = 0;
24073 for( $i = 0 ; $i < $nc ; $i++ ) {
24074 if (isset($table['wc'][$i]['wpercent']) && $table['wc'][$i]['wpercent']) {
24075 $sumpc += $table['wc'][$i]['wpercent'];
24076 }
24077 else { $notset++; }
24078 }
24079
24080 // If sum of widths as % >= 100% and not all columns are set
24081 // Set a nominal width of 1% for unset columns
24082 if ($sumpc >= 100 && $notset) {
24083 for( $i = 0 ; $i < $nc ; $i++ ) {
24084 if ((!isset($table['wc'][$i]['wpercent']) || !$table['wc'][$i]['wpercent']) &&
24085 (!isset($table['wc'][$i]['w']) || !$table['wc'][$i]['w'])) {
24086 $table['wc'][$i]['wpercent'] = 1;
24087 }
24088 }
24089 }
24090
24091
24092 if ($sumpc) { // if any percents are set
24093 $sumnonpc = (100 - $sumpc);
24094 $sumpc = max($sumpc,100);
24095 $miwleft = 0;
24096 $miwleftcount = 0;
24097 $miwsurplusnonpc = 0;
24098 $maxcalcmiw = 0;
24099 $mawleft = 0;
24100 $mawleftcount = 0;
24101 $mawsurplusnonpc = 0;
24102 $maxcalcmaw = 0;
24103 for( $i = 0 ; $i < $nc ; $i++ ) {
24104 if (isset($table['wc'][$i]['wpercent'])) {
24105 $maxcalcmiw = max($maxcalcmiw, ($table['wc'][$i]['miw'] * $sumpc /$table['wc'][$i]['wpercent']) );
24106 $maxcalcmaw = max($maxcalcmaw, ($table['wc'][$i]['maw'] * $sumpc /$table['wc'][$i]['wpercent']) );
24107 }
24108 else {
24109 $miwleft += $table['wc'][$i]['miw'];
24110 $mawleft += $table['wc'][$i]['maw'];
24111 if (!isset($table['wc'][$i]['w'])) { $miwleftcount++; $mawleftcount++; }
24112 }
24113 }
24114 if ($miwleft && $sumnonpc > 0) { $miwnon = $miwleft * 100 / $sumnonpc; }
24115 if ($mawleft && $sumnonpc > 0) { $mawnon = $mawleft * 100 / $sumnonpc; }
24116 if (($miwnon > $checkminwidth || $maxcalcmiw > $checkminwidth) && $this->keep_table_proportions) {
24117 if ($miwnon > $maxcalcmiw) {
24118 $miwsurplusnonpc = round((($miwnon * $sumnonpc / 100) - $miwleft),3);
24119 $checkminwidth = $miwnon;
24120 }
24121 else { $checkminwidth = $maxcalcmiw; }
24122 for( $i = 0 ; $i < $nc ; $i++ ) {
24123 if (isset($table['wc'][$i]['wpercent'])) {
24124 $newmiw = $checkminwidth * $table['wc'][$i]['wpercent']/100;
24125 if ($table['wc'][$i]['miw'] < $newmiw) {
24126 $table['wc'][$i]['miw'] = $newmiw;
24127 }
24128 $table['wc'][$i]['w'] = 1;
24129 }
24130 else if ($miwsurplusnonpc && !$table['wc'][$i]['w']) {
24131 $table['wc'][$i]['miw'] += $miwsurplusnonpc / $miwleftcount;
24132 }
24133 }
24134 }
24135 if (($mawnon > $checkmaxwidth || $maxcalcmaw > $checkmaxwidth )) {
24136 if ($mawnon > $maxcalcmaw) {
24137 $mawsurplusnonpc = round((($mawnon * $sumnonpc / 100) - $mawleft),3);
24138 $checkmaxwidth = $mawnon;
24139 }
24140 else { $checkmaxwidth = $maxcalcmaw; }
24141 for( $i = 0 ; $i < $nc ; $i++ ) {
24142 if (isset($table['wc'][$i]['wpercent'])) {
24143 $newmaw = $checkmaxwidth * $table['wc'][$i]['wpercent']/100;
24144 if ($table['wc'][$i]['maw'] < $newmaw) {
24145 $table['wc'][$i]['maw'] = $newmaw;
24146 }
24147 $table['wc'][$i]['w'] = 1;
24148 }
24149 else if ($mawsurplusnonpc && !$table['wc'][$i]['w']) {
24150 $table['wc'][$i]['maw'] += $mawsurplusnonpc / $mawleftcount;
24151 }
24152 if ($table['wc'][$i]['maw'] < $table['wc'][$i]['miw']) { $table['wc'][$i]['maw'] = $table['wc'][$i]['miw']; }
24153 }
24154 }
24155 if ($checkminwidth > $checkmaxwidth) { $checkmaxwidth = $checkminwidth; }
24156 }
24157 }
24158
24159 if (isset($table['wpercent']) && $table['wpercent']) {
24160 $checkminwidth *= (100 / $table['wpercent']);
24161 $checkmaxwidth *= (100 / $table['wpercent']);
24162 }
24163
24164
24165 $checkminwidth += $tblbw ;
24166 $checkmaxwidth += $tblbw ;
24167
24168 // Table['miw'] set by percent in first pass may be larger than sum of column miw
24169 if ((isset($table['miw']) && $checkminwidth > $table['miw']) || !isset($table['miw'])) { $table['miw'] = $checkminwidth; }
24170 if ((isset($table['maw']) && $checkmaxwidth > $table['maw']) || !isset($table['maw'])) { $table['maw'] = $checkmaxwidth; }
24171 $table['tl'] = $totallength ;
24172
24173
24174 if (!$this->tableCJK) {
24175 if ($this->table_rotate) {
24176 $mxw = $this->tbrot_maxw;
24177 }
24178 else {
24179 $mxw = $this->blk[$this->blklvl]['inner_width'];
24180 }
24181 if(!isset($table['overflow'])) { $table['overflow'] = null; }
24182 // mPDF 5.3.36
24183 if ($table['overflow']=='visible') {
24184 return array(0,0);
24185 }
24186 else if ($table['overflow']=='hidden' && !$this->table_rotate && !$this->ColActive && $checkminwidth > $mxw) { // mPDF 5.3.36
24187 $table['w'] = $table['miw'];
24188 return array(0,0);
24189 }
24190 else if ($table['overflow']=='wrap') { return array(0,0); }
24191
24192 if (isset($table['w']) && $table['w'] ) {
24193 if ($table['w'] >= $checkminwidth && $table['w'] <= $mxw) { $table['maw'] = $mxw = $table['w']; }
24194 else if ($table['w'] >= $checkminwidth && $table['w'] > $mxw && $this->keep_table_proportions) { $checkminwidth = $table['w']; }
24195 else {
24196 unset($table['w']);
24197 }
24198 }
24199 $ratio = $checkminwidth/$mxw;
24200 if ($checkminwidth > $mxw) { return array(($ratio +0.001),$checkminwidth); } // 0.001 to allow for rounded numbers when resizing
24201 }
24202 unset($cs);
24203 return array(0,0);
24204 }
24205
24206
24207
24208 function _tableWidth(&$table){
24209 $widthcols = &$table['wc'];
24210 $numcols = $table['nc'];
24211 $tablewidth = 0;
24212 if ($table['borders_separate']) {
24213 $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'];
24214 }
24215 else { $tblbw = $table['max_cell_border_width']['L']/2 + $table['max_cell_border_width']['R']/2 + $table['margin']['L'] + $table['margin']['R']; }
24216
24217 if ($table['level']>1 && isset($table['w'])) {
24218 if (isset($table['wpercent']) && $table['wpercent']) {
24219 $table['w'] = $temppgwidth = (($table['w']-$tblbw) * $table['wpercent'] / 100) + $tblbw ;
24220 }
24221 else {
24222 $temppgwidth = $table['w'] ;
24223 }
24224 }
24225 else if ($this->table_rotate) {
24226 $temppgwidth = $this->tbrot_maxw;
24227 // If it is less than 1/20th of the remaining page height to finish the DIV (i.e. DIV padding + table bottom margin)
24228 // then allow for this
24229 $enddiv = $this->blk[$this->blklvl]['padding_bottom'] + $this->blk[$this->blklvl]['border_bottom']['w'];
24230 if ($enddiv/$temppgwidth <0.05) { $temppgwidth -= $enddiv; }
24231 }
24232 else {
24233 if (isset($table['w']) && $table['w']< $this->blk[$this->blklvl]['inner_width']) {
24234 $notfullwidth = 1;
24235 $temppgwidth = $table['w'] ;
24236 }
24237 else if ($table['overflow']=='visible' && $table['level'] ==1) { // mPDF 5.3.36
24238 $temppgwidth = null;
24239 }
24240 else if ($table['overflow']=='hidden' && !$this->ColActive && isset($table['w']) && $table['w'] > $this->blk[$this->blklvl]['inner_width'] && $table['w']==$table['miw']) { // mPDF 5.3.36
24241 //$temppgwidth = $this->blk[$this->blklvl]['inner_width'];
24242 $temppgwidth = $table['w'] ; // mPDF 5.3.50
24243 }
24244 else { $temppgwidth = $this->blk[$this->blklvl]['inner_width']; }
24245 }
24246
24247
24248 $totaltextlength = 0; // Added - to sum $table['l'][colno]
24249 $totalatextlength = 0; // Added - to sum $table['l'][colno] for those columns where width not set
24250 $percentages_set = 0;
24251 for ( $i = 0 ; $i < $numcols ; $i++ ) {
24252 if (isset($widthcols[$i]['wpercent'])) { $tablewidth += $widthcols[$i]['maw']; $percentages_set = 1; }
24253 else if (isset($widthcols[$i]['w'])) { $tablewidth += $widthcols[$i]['miw']; }
24254 else { $tablewidth += $widthcols[$i]['maw']; }
24255 $totaltextlength += $table['l'][$i];
24256 }
24257 if (!$totaltextlength) { $totaltextlength =1; }
24258 $tablewidth += $tblbw; // Outer half of table borders
24259
24260 if ($tablewidth > $temppgwidth) {
24261 $table['w'] = $temppgwidth;
24262 }
24263 // if any widths set as percentages and max width fits < page width
24264 else if ($tablewidth < $temppgwidth && !isset($table['w']) && $percentages_set) {
24265 $table['w'] = $table['maw'];
24266 }
24267 // if table width is set and is > allowed width
24268 if (isset($table['w']) && $table['w'] > $temppgwidth) { $table['w'] = $temppgwidth; }
24269 // IF the table width is now set - Need to distribute columns widths
24270 if (isset($table['w'])) {
24271 $wis = $wisa = 0;
24272 $list = array();
24273 $notsetlist = array();
24274 for( $i = 0 ; $i < $numcols ; $i++ ) {
24275 $wis += $widthcols[$i]['miw'];
24276 if (!isset($widthcols[$i]['w']) || ($widthcols[$i]['w'] && $table['w'] > $temppgwidth && !$this->keep_table_proportions && !$notfullwidth )){
24277 $list[] = $i;
24278 $wisa += $widthcols[$i]['miw'];
24279 $totalatextlength += $table['l'][$i];
24280 }
24281 }
24282 if (!$totalatextlength) { $totalatextlength =1; }
24283
24284 // Allocate spare (more than col's minimum width) across the cols according to their approx total text length
24285 // Do it by setting minimum width here
24286 if ($table['w'] > $wis + $tblbw) {
24287 // First set any cell widths set as percentages
24288 if ($table['w'] < $temppgwidth || $this->keep_table_proportions) {
24289 for($k=0;$k<$numcols;$k++) {
24290 if (isset($widthcols[$k]['wpercent'])) {
24291 $curr = $widthcols[$k]['miw'];
24292 $widthcols[$k]['miw'] = ($table['w']-$tblbw) * $widthcols[$k]['wpercent']/100;
24293 $wis += $widthcols[$k]['miw'] - $curr;
24294 $wisa += $widthcols[$k]['miw'] - $curr;
24295 }
24296 }
24297 }
24298 // Now allocate surplus up to maximum width of each column
24299 $surplus = 0; $ttl = 0; // number of surplus columns
24300 if (!count($list)) {
24301 $wi = ($table['w']-($wis + $tblbw)); // i.e. extra space to distribute
24302 for($k=0;$k<$numcols;$k++) {
24303 $spareratio = ($table['l'][$k] / $totaltextlength); // gives ratio to divide up free space
24304 // Don't allocate more than Maximum required width - save rest in surplus
24305 if ($widthcols[$k]['miw'] + ($wi * $spareratio) > $widthcols[$k]['maw']) {
24306 $surplus += ($wi * $spareratio) - ($widthcols[$k]['maw']-$widthcols[$k]['miw']);
24307 $widthcols[$k]['miw'] = $widthcols[$k]['maw'];
24308 }
24309 else {
24310 $notsetlist[] = $k;
24311 $ttl += $table['l'][$k];
24312 $widthcols[$k]['miw'] += ($wi * $spareratio);
24313 }
24314
24315 }
24316 }
24317 else {
24318 $wi = ($table['w'] - ($wis + $tblbw)); // i.e. extra space to distribute
24319 foreach ($list as $k) {
24320 $spareratio = ($table['l'][$k] / $totalatextlength); // gives ratio to divide up free space
24321 // Don't allocate more than Maximum required width - save rest in surplus
24322 if ($widthcols[$k]['miw'] + ($wi * $spareratio) > $widthcols[$k]['maw']) {
24323 $surplus += ($wi * $spareratio) - ($widthcols[$k]['maw']-$widthcols[$k]['miw']);
24324 $widthcols[$k]['miw'] = $widthcols[$k]['maw'];
24325 }
24326 else {
24327 $notsetlist[] = $k;
24328 $ttl += $table['l'][$k];
24329 $widthcols[$k]['miw'] += ($wi * $spareratio);
24330 }
24331 }
24332 }
24333 // If surplus still left over apportion it across columns
24334 if ($surplus) {
24335 // if some are set only add to remaining - otherwise add to all of them
24336 if (count($notsetlist) && count($notsetlist) < $numcols) {
24337 foreach ($notsetlist AS $i) {
24338 if ($ttl) $widthcols[$i]['miw'] += $surplus * $table['l'][$i] / $ttl ;
24339 }
24340 }
24341 // If some widths are defined, and others have been added up to their maxmum
24342 else if (count($list) && count($list) < $numcols) {
24343 foreach ($list AS $i) {
24344 $widthcols[$i]['miw'] += $surplus / count($list) ;
24345 }
24346 }
24347 else if ($numcols) { // If all columns
24348 $ttl = array_sum($table['l']);
24349 for ($i=0;$i<$numcols;$i++) {
24350 $widthcols[$i]['miw'] += $surplus * $table['l'][$i] / $ttl;
24351 }
24352 }
24353 }
24354
24355 }
24356
24357 // This sets the columns all to minimum width (which has been increased above if appropriate)
24358 for ($i=0;$i<$numcols;$i++) {
24359 $widthcols[$i] = $widthcols[$i]['miw'];
24360 }
24361
24362 // TABLE NOT WIDE ENOUGH EVEN FOR MINIMUM CONTENT WIDTH
24363 // If sum of column widths set are too wide for table
24364 $checktablewidth = 0;
24365 for ( $i = 0 ; $i < $numcols ; $i++ ) {
24366 $checktablewidth += $widthcols[$i];
24367 }
24368 if ($checktablewidth > ($temppgwidth + 0.001 - $tblbw)) {
24369 $usedup = 0; $numleft = 0;
24370 for ($i=0;$i<$numcols;$i++) {
24371 if ((isset($widthcols[$i]) && $widthcols[$i] > (($temppgwidth - $tblbw) / $numcols)) && (!isset($widthcols[$i]['w']))) {
24372 $numleft++;
24373 unset($widthcols[$i]);
24374 }
24375 else { $usedup += $widthcols[$i]; }
24376 }
24377 for ($i=0;$i<$numcols;$i++) {
24378 if (!isset($widthcols[$i]) || !$widthcols[$i]) {
24379 $widthcols[$i] = ((($temppgwidth - $tblbw) - $usedup)/ ($numleft));
24380 }
24381 }
24382 }
24383
24384 }
24385 else { //table has no width defined
24386 $table['w'] = $tablewidth;
24387 for ( $i = 0 ; $i < $numcols ; $i++) {
24388 if (isset($widthcols[$i]['wpercent']) && $this->keep_table_proportions) { $colwidth = $widthcols[$i]['maw']; }
24389 else if (isset($widthcols[$i]['w'])) { $colwidth = $widthcols[$i]['miw']; }
24390 else { $colwidth = $widthcols[$i]['maw']; }
24391 unset($widthcols[$i]);
24392 $widthcols[$i] = $colwidth;
24393 }
24394 }
24395
24396 // mPDF 5.3.36
24397 if ($table['overflow']=='visible' && $table['level'] ==1) { // mPDF 5.3.36
24398 if ($tablewidth > $this->blk[$this->blklvl]['inner_width']) {
24399 // mPDF 5.3.79
24400 if ($this->cacheTables) { $fh = fopen($table['cache'], "r+b"); }
24401 else { $fh = null; }
24402 for ($j = 0 ; $j < $numcols; $j++) { //columns
24403 for ($i = 0 ; $i < $table['nr']; $i++) { //rows
24404 if (isset($table['cells'][$i][$j]) && $table['cells'][$i][$j]) {
24405 // mPDF 5.3.79
24406 if ($this->cacheTables) {
24407 $cc = $this->_uncacheCell($table['cells'][$i][$j], '', $fh);
24408 $colspan = $cc['colspan'];
24409 }
24410 else
24411 $colspan = $table['cells'][$i][$j]['colspan'];
24412 if ($colspan > 1) {
24413 $w = 0;
24414 for ($c = $j; $c < ($j + $colspan); $c++) {
24415 $w += $widthcols[$c];
24416 }
24417 if ($w > $this->blk[$this->blklvl]['inner_width']) {
24418 $diff = $w - ($this->blk[$this->blklvl]['inner_width'] - $tblbw);
24419 for ($c = $j; $c < ($j + $colspan); $c++) {
24420 $widthcols[$c] -= $diff * ($widthcols[$c]/$w);
24421 }
24422 $table['w'] -= $diff;
24423 $table['csp'][$j] = $w - $diff; // mPDF 5.3.44
24424 }
24425 }
24426 }
24427
24428 }
24429 }
24430 // mPDF 5.3.79
24431 if ($this->cacheTables) { fclose($fh); }
24432 }
24433 $pgNo = 0;
24434 $currWc = 0;
24435 for ($i = 0 ; $i < $numcols; $i++) { //columns
24436 if (isset($table['csp'][$i])) {
24437 $w = $table['csp'][$i];
24438 unset($table['csp'][$i]);
24439 }
24440 else { $w = $widthcols[$i]; }
24441 if (($currWc + $w + $tblbw) > $this->blk[$this->blklvl]['inner_width']) {
24442 $pgNo++;
24443 $currWc = $widthcols[$i] ;
24444 }
24445 else { $currWc += $widthcols[$i] ; }
24446 $table['colPg'][$i] = $pgNo;
24447 }
24448 }
24449 }
24450
24451
24452
24453 function _tableHeight(&$table){
24454 $level = $table['level'];
24455 $levelid = $table['levelid'];
24456 $cells = &$table['cells'];
24457 $numcols = $table['nc'];
24458 $numrows = $table['nr'];
24459 $listspan = array();
24460 $checkmaxheight = 0;
24461 $headerrowheight = 0;
24462 $checkmaxheightplus = 0;
24463 $headerrowheightplus = 0;
24464 $firstrowheight = 0;
24465
24466 $footerrowheight = 0;
24467 $footerrowheightplus = 0;
24468 if ($this->table_rotate) {
24469 $temppgheight = $this->tbrot_maxh;
24470 $remainingpage = $this->tbrot_maxh;
24471 }
24472 else {
24473 $temppgheight = ($this->h - $this->bMargin - $this->tMargin) - $this->kwt_height;
24474 $remainingpage = ($this->h - $this->bMargin - $this->y) - $this->kwt_height;
24475
24476 // If it is less than 1/20th of the remaining page height to finish the DIV (i.e. DIV padding + table bottom margin)
24477 // then allow for this
24478 $enddiv = $this->blk[$this->blklvl]['padding_bottom'] + $this->blk[$this->blklvl]['border_bottom']['w'] + $table['margin']['B'];
24479 if ($remainingpage > $enddiv && $enddiv/$remainingpage <0.05) { $remainingpage -= $enddiv; }
24480 else if ($remainingpage == 0) { $remainingpage = 0.001; }
24481 if ($temppgheight > $enddiv && $enddiv/$temppgheight <0.05) { $temppgheight -= $enddiv; }
24482 else if ($temppgheight == 0) { $temppgheight = 0.001; }
24483 }
24484
24485 // mPDF 5.3.79
24486 if ($this->cacheTables) { $fh = fopen($table['cache'], "r+b"); }
24487 else { $fh = null; }
24488
24489 for( $i = 0 ; $i < $numrows ; $i++ ) { //rows
24490 $heightrow = &$table['hr'][$i];
24491 for( $j = 0 ; $j < $numcols ; $j++ ) { //columns
24492 if (isset($cells[$i][$j]) && $cells[$i][$j]) {
24493 // mPDF 5.3.79
24494 if ($this->cacheTables) {
24495 $c = $this->_uncacheCell($table['cells'][$i][$j], '', $fh);
24496 }
24497 else
24498 $c = &$cells[$i][$j];
24499
24500 if ($this->simpleTables){
24501 if ($table['borders_separate']) { // NB twice border width
24502 $extraWLR = ($table['simple']['border_details']['L']['w']+$table['simple']['border_details']['R']['w']) + ($c['padding']['L']+$c['padding']['R'])+$table['border_spacing_H'];
24503 $extrh = ($table['simple']['border_details']['T']['w']+$table['simple']['border_details']['B']['w']) + ($c['padding']['T']+$c['padding']['B'])+$table['border_spacing_V'];
24504 }
24505 else {
24506 $extraWLR = ($table['simple']['border_details']['L']['w']+$table['simple']['border_details']['R']['w'])/2 + ($c['padding']['L']+$c['padding']['R']);
24507 $extrh = ($table['simple']['border_details']['T']['w']+$table['simple']['border_details']['B']['w'])/2 + ($c['padding']['T']+$c['padding']['B']);
24508 }
24509 }
24510 else {
24511 if ($this->packTableData) {
24512 list($bt,$br,$bb,$bl) = $this->_getBorderWidths($c['borderbin']);
24513 }
24514 else {
24515 $bt = $c['border_details']['T']['w'];
24516 $bb = $c['border_details']['B']['w'];
24517 $br = $c['border_details']['R']['w'];
24518 $bl = $c['border_details']['L']['w'];
24519 }
24520 if ($table['borders_separate']) { // NB twice border width
24521 $extraWLR = $bl + $br + $c['padding']['L'] + $c['padding']['R'] + $table['border_spacing_H'];
24522 $extrh = $bt + $bb + $c['padding']['T'] + $c['padding']['B'] + $table['border_spacing_V'];
24523 }
24524 else {
24525 $extraWLR = $bl/2 + $br/2 + $c['padding']['L'] + $c['padding']['R'];
24526 $extrh = $bt/2 + $bb/2 + $c['padding']['T']+$c['padding']['B'];
24527 }
24528 }
24529
24530 // mPDF 5.3.36
24531 if ($table['overflow']=='visible' && $level==1)
24532 list($x,$cw) = $this->_splitTableGetWidth($table, $i,$j, $fh);
24533 else
24534 list($x,$cw) = $this->_tableGetWidth($table, $i,$j, $fh);
24535
24536 // Get CELL HEIGHT
24537 // ++ extra parameter forces wrap to break word
24538 if ($c['R']) {
24539 // mPDF 5.3.78
24540 $str = '';
24541 foreach($c['textbuffer'] AS $t) { $str .= $t[0].' '; }
24542 $str = trim($str);
24543 $s_fs = $this->FontSizePt;
24544 $s_f = $this->FontFamily;
24545 $s_st = $this->FontStyle;
24546 $this->SetFont($c['textbuffer'][0][4],$c['textbuffer'][0][2],$c['textbuffer'][0][11] / $this->shrin_k,true,true);
24547 $tempch = $this->GetStringWidth($str); // mPDF 5.3.78
24548 if ($c['R'] >= 45 && $c['R'] < 90) {
24549 $tempch = ((sin(deg2rad($c['R']))) * $tempch ) + ((sin(deg2rad($c['R']))) * (($c['textbuffer'][0][11]/_MPDFK) / $this->shrin_k));
24550 }
24551 $this->SetFont($s_f,$s_st,$s_fs,true,true);
24552 $ch = ($tempch ) + $extrh ;
24553 }
24554 else {
24555 if (isset($c['textbuffer'])) {
24556 $tempch = $this->TableWordWrap(($cw-$extraWLR),1,$c['textbuffer'], $c['dfs']);
24557 }
24558 else { $tempch = 0; }
24559
24560 // Added cellpadding top and bottom. (Lineheight already adjusted to table_lineheight)
24561 $ch = $tempch + $extrh ;
24562 }
24563 //If height is defined and it is bigger than calculated $ch then update values
24564 if (isset($c['h']) && $c['h'] > $ch) {
24565 $c['mih'] = $ch; //in order to keep valign working
24566 $ch = $c['h'];
24567 }
24568 else $c['mih'] = $ch;
24569 // mPDF 5.3.79
24570 if ($this->cacheTables) {
24571 $this->_cacheUpdateMtx($c, $fh, $table['cells'][$i][$j], 'mih');
24572 }
24573 if (isset($c['rowspan'])) $listspan[] = array($i,$j);
24574 elseif ($heightrow < $ch) $heightrow = $ch;
24575
24576 // this is the extra used in _tableWrite to determine whether to trigger a page change
24577 if ($table['borders_separate']) {
24578 if ($i == ($numrows-1) || (isset($c['rowspan']) && ($i+$c['rowspan']) == ($numrows)) ) {
24579 $extra = $table['margin']['B'] + $table['padding']['B'] + $table['border_details']['B']['w'] + $table['border_spacing_V']/2;
24580 }
24581 else {
24582 $extra = $table['border_spacing_V']/2;
24583 }
24584 }
24585 else {
24586 if (!$this->simpleTables){
24587 $extra = $bb/2;
24588 }
24589 else if ($this->simpleTables){
24590 $extra = $table['simple']['border_details']['B']['w'] /2;
24591 }
24592 }
24593 if (isset($table['is_thead'][$i]) && $table['is_thead'][$i]) { // mPDF 5.3.62
24594 if ($j==0) {
24595 $headerrowheight += $ch;
24596 $headerrowheightplus += $ch+$extra;
24597 }
24598 }
24599 else if (isset($table['is_tfoot'][$i]) && $table['is_tfoot'][$i]) {
24600 if ($j==0) {
24601 $footerrowheight += $ch;
24602 $footerrowheightplus += $ch+$extra;
24603 }
24604 }
24605 else {
24606 $checkmaxheight = max($checkmaxheight,$ch);
24607 $checkmaxheightplus = max($checkmaxheightplus,$ch+$extra);
24608 }
24609 if ($this->tableLevel==1 && $i == $table['headernrows']) { $firstrowheight = max($ch,$firstrowheight); } // mPDF 5.3.62 // mPDF 5.3.76
24610 unset($c);
24611 }
24612 }//end of columns
24613 }//end of rows
24614
24615 $heightrow = &$table['hr'];
24616 foreach ($listspan as $span) {
24617 list($i,$j) = $span;
24618 // mPDF 5.3.79
24619 if ($this->cacheTables) {
24620 $c = $this->_uncacheCell($table['cells'][$i][$j], '', $fh);
24621 }
24622 else
24623 $c = &$cells[$i][$j];
24624 $lr = $i + $c['rowspan'];
24625 if ($lr > $numrows) $lr = $numrows;
24626 $hs = $hsa = 0;
24627 $list = array();
24628 for($k=$i;$k<$lr;$k++) {
24629 $hs += $heightrow[$k];
24630 if (!isset($c['h'])) {
24631 $list[] = $k;
24632 $hsa += $heightrow[$k];
24633 }
24634 }
24635
24636 if ($table['borders_separate']) {
24637 if ($i == ($numrows-1) || ($i+$c['rowspan']) == ($numrows) ) {
24638 $extra = $table['margin']['B'] + $table['padding']['B'] + $table['border_details']['B']['w'] + $table['border_spacing_V']/2;
24639 }
24640 else {
24641 $extra = $table['border_spacing_V']/2;
24642 }
24643 }
24644 else {
24645 if (!$this->simpleTables){
24646 if ($this->packTableData) {
24647 list($bt,$br,$bb,$bl) = $this->_getBorderWidths($c['borderbin']);
24648 }
24649 else {
24650 $bb = $c['border_details']['B']['w'];
24651 }
24652 $extra = $bb/2;
24653 }
24654 else if ($this->simpleTables){
24655 $extra = $table['simple']['border_details']['B']['w'] /2;
24656 }
24657 }
24658 if (!empty($table['is_thead'][$i])) { // mPDF 5.3.62
24659 $headerrowheight = max($headerrowheight,$hs);
24660 $headerrowheightplus = max($headerrowheightplus,$hs+$extra);
24661 }
24662 else if (!empty($table['is_tfoot'][$i])) {
24663 $footerrowheight = max($footerrowheight,$hs);
24664 $footerrowheightplus = max($footerrowheightplus,$hs+$extra);
24665 }
24666 else {
24667 $checkmaxheight = max($checkmaxheight,$hs);
24668 $checkmaxheightplus = max($checkmaxheightplus,$hs+$extra);
24669 }
24670 if ($this->tableLevel==1 && $i == $table['headernrows']) { $firstrowheight = max($hs,$firstrowheight); } // mPDF 5.3.62 // mPDF 5.3.76
24671
24672 if ($c['mih'] > $hs) {
24673 if (!$hs) {
24674 for($k=$i;$k<$lr;$k++) $heightrow[$k] = $c['mih']/$c['rowspan'];
24675 }
24676 elseif (!count($list)) {
24677 $hi = $c['mih'] - $hs;
24678 for($k=$i;$k<$lr;$k++) $heightrow[$k] += ($heightrow[$k]/$hs)*$hi;
24679 }
24680 else {
24681 $hi = $c['mih'] - $hsa;
24682 foreach ($list as $k) $heightrow[$k] += ($heightrow[$k]/$hsa)*$hi;
24683 }
24684 }
24685 unset($c);
24686
24687 // If rowspans overlap so that one or more rows do not have a height set...
24688 // i.e. for one or more rows, the only cells (explicit) in that row have rowspan>1
24689 // so heightrow is still == 0
24690 if ($heightrow[$i]==0) {
24691 // Get row extent to analyse above and below
24692 $top = $i;
24693 foreach ($listspan as $checkspan) {
24694 list($cki,$ckj) = $checkspan;
24695 if ($this->cacheTables) {
24696 $c = $this->_uncacheCell($table['cells'][$cki][$ckj], '', $fh);
24697 }
24698 else
24699 $c = &$cells[$cki][$ckj];
24700 if (isset($c['rowspan']) && $c['rowspan']>1) {
24701 if (($cki + $c['rowspan']-1) >= $i) { $top = min($top, $cki); }
24702 }
24703 }
24704 $bottom = $i + $c['rowspan']-1;
24705 // Check for overconstrained conditions
24706 for ($k=$top; $k<=$bottom; $k++) {
24707 // if ['hr'] for any of the others is also 0, then abort (too complicated)
24708 if ($k != $i && $heightrow[$k]==0) { break(1); }
24709 // check again that top and bottom are not crossed by rowspans - or abort (too complicated)
24710 if ($k==$top) {
24711 // ???? take account of colspan as well???
24712 for( $m = 0 ; $m < $numcols ; $m++ ) { //columns
24713 if (!isset($cells[$k][$m]) || $cells[$k][$m]==0) {
24714 break(2);
24715 }
24716 }
24717 }
24718 else if ($k==$bottom) {
24719 // ???? take account of colspan as well???
24720 for( $m = 0 ; $m < $numcols ; $m++ ) { //columns
24721 if ($this->cacheTables) {
24722 $c = $this->_uncacheCell($table['cells'][$k][$m], '', $fh);
24723 }
24724 else
24725 $c = &$cells[$k][$m];
24726 if (isset($c['rowspan']) && $c['rowspan']>1) {
24727 break(2);
24728 }
24729 }
24730 }
24731 }
24732 // By columns add up col height using ['h'] if set or ['mih'] if not
24733 // Intentionally do not substract border-spacing
24734 $colH = array();
24735 $extH = 0;
24736 $newhr = array();
24737 for( $m = 0 ; $m < $numcols ; $m++ ) { //columns
24738 for ($k=$top; $k<=$bottom; $k++) {
24739 if (isset($cells[$k][$m]) && $cells[$k][$m]!=0) {
24740 if ($this->cacheTables) {
24741 $c = $this->_uncacheCell($table['cells'][$k][$m], '', $fh);
24742 }
24743 else
24744 $c = &$cells[$k][$m];
24745 if (isset($c['h']) && $c['h']) {
24746 $useh = $c['h'];
24747 }
24748 // ???? take account of colspan as well???
24749 else {
24750 $useh = $c['mih'];
24751 }
24752 $colH[$m] += $useh;
24753 if (!isset($c['rowspan']) || $c['rowspan']<2) { $newhr[$k] = max($newhr[$k], $useh); }
24754 }
24755 }
24756 $extH = max($tabH, $colH[$m]);
24757 }
24758 $newhr[$i] = $extH - array_sum($newhr);
24759 for ($k=$top; $k<=$bottom; $k++) { $heightrow[$k] = $newhr[$k]; }
24760 }
24761
24762
24763 unset($c);
24764 }
24765
24766 $table['h'] = array_sum($heightrow); // mPDF 5.3.80
24767 unset($heightrow); // mPDF 5.3.80
24768
24769 // mPDF 5.3.79
24770 if ($this->cacheTables) { fclose($fh); }
24771
24772 if ($table['borders_separate']) {
24773 $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'];
24774 }
24775 else {
24776 $table['h'] += $table['margin']['T'] + $table['margin']['B'] + $table['max_cell_border_width']['T']/2 + $table['max_cell_border_width']['B']/2;
24777 }
24778
24779 $maxrowheight = $checkmaxheightplus + $headerrowheightplus + $footerrowheightplus;
24780 $maxfirstrowheight = $firstrowheight + $headerrowheightplus + $footerrowheightplus; // includes thead, 1st row and tfoot
24781 return array($table['h'],$maxrowheight,$temppgheight,$remainingpage,$maxfirstrowheight);
24782 }
24783
24784 function _tableGetWidth(&$table, $i,$j, $fh){
24785 // mPDF 5.3.79
24786 if ($this->cacheTables) {
24787 $cell = $this->_uncacheCell($table['cells'][$i][$j], '', $fh);
24788 }
24789 else
24790 $cell = &$table['cells'][$i][$j];
24791 if ($cell) {
24792 if (isset($cell['x0'])) { return array($cell['x0'], $cell['w0']); }
24793 $x = 0;
24794 $widthcols = &$table['wc'];
24795 for( $k = 0 ; $k < $j ; $k++ ) $x += $widthcols[$k];
24796 $w = $widthcols[$j];
24797 if (isset($cell['colspan'])) {
24798 for ( $k = $j+$cell['colspan']-1 ; $k > $j ; $k-- ) $w += $widthcols[$k];
24799 }
24800 $cell['x0'] = $x;
24801 $cell['w0'] = $w;
24802 // mPDF 5.3.79
24803 if ($this->cacheTables) {
24804 $this->_cacheUpdateMtx($cell, $fh, $table['cells'][$i][$j], 'x0');
24805 }
24806 return array($x, $w);
24807 }
24808 return array(0,0);
24809 }
24810
24811 // mPDF 5.3.36
24812 function _splitTableGetWidth(&$table, $i,$j, $fh){
24813 // mPDF 5.3.79
24814 if ($this->cacheTables) {
24815 $cell = $this->_uncacheCell($table['cells'][$i][$j], '', $fh);
24816 }
24817 else
24818 $cell = &$table['cells'][$i][$j];
24819 if ($cell) {
24820 if (isset($cell['x0'])) return array($cell['x0'], $cell['w0']);
24821 $x = 0;
24822 $widthcols = &$table['wc'];
24823 $pg = $table['colPg'][$j];
24824 for( $k = 0 ; $k < $j ; $k++ ) {
24825 if ($table['colPg'][$k]==$pg) $x += $widthcols[$k];
24826 }
24827 $w = $widthcols[$j];
24828 if (isset($cell['colspan'])) {
24829 for ( $k = $j+$cell['colspan']-1 ; $k > $j ; $k-- ) if ($table['colPg'][$k]==$pg) $w += $widthcols[$k];
24830 }
24831 $cell['x0'] = $x;
24832 $cell['w0'] = $w;
24833 // mPDF 5.3.79
24834 if ($this->cacheTables) {
24835 $this->_cacheUpdateMtx($cell, $fh, $table['cells'][$i][$j], 'x0');
24836 }
24837 return array($x, $w);
24838 }
24839 return array(0,0);
24840 }
24841
24842
24843 function _tableGetHeight(&$table, $i,$j, $fh){
24844 // mPDF 5.3.79
24845 if ($this->cacheTables) {
24846 $cell = $this->_uncacheCell($table['cells'][$i][$j], '', $fh);
24847 }
24848 else
24849 $cell = &$table['cells'][$i][$j];
24850 if ($cell){
24851 if (isset($cell['y0'])) return array($cell['y0'], $cell['h0']);
24852 $y = 0;
24853 $heightrow = &$table['hr'];
24854 for ($k=0;$k<$i;$k++) $y += $heightrow[$k];
24855 $h = $heightrow[$i];
24856 if (isset($cell['rowspan'])){
24857 for ($k=$i+$cell['rowspan']-1;$k>$i;$k--)
24858 $h += $heightrow[$k];
24859 }
24860 $cell['y0'] = $y;
24861 $cell['h0'] = $h;
24862 // mPDF 5.3.79
24863 if ($this->cacheTables) {
24864 $this->_cacheUpdateMtx($cell, $fh, $table['cells'][$i][$j], 'y0');
24865 }
24866 return array($y, $h);
24867 }
24868 return array(0,0);
24869 }
24870
24871 // mPDF 5.3.A7
24872 function _tableGetMaxRowHeight($table, $row, $fh) {
24873 if ($row==$table['nc']-1) { return $table['hr'][$row]; }
24874 $maxrowheight = $table['hr'][$row];
24875 for ($i=$row+1;$i<$table['nr'];$i++) {
24876 $cellsset = 0;
24877 for ($j=0;$j<$table['nc'];$j++) {
24878 if ($this->cacheTables) {
24879 $cell = $this->_uncacheCell($table['cells'][$i][$j], '', $fh);
24880 if ($cell) {
24881 if (isset($cell['colspan'])) { $cellsset += $cell['colspan']; }
24882 else $cellsset += 1;
24883 }
24884 }
24885 else {
24886 if ($table['cells'][$i][$j]) {
24887 if (isset($table['cells'][$i][$j]['colspan'])) { $cellsset += $table['cells'][$i][$j]['colspan']; }
24888 else $cellsset += 1;
24889 }
24890 }
24891 }
24892 if ($cellsset == $table['nc']) { return $maxrowheight; }
24893 else { $maxrowheight += $table['hr'][$i]; }
24894 }
24895 return $maxrowheight;
24896 }
24897
24898
24899 // CHANGED TO ALLOW TABLE BORDER TO BE SPECIFIED CORRECTLY - added border_details
24900 function _tableRect($x, $y, $w, $h, $bord=-1, $details=array(), $buffer=false, $bSeparate=false, $cort='cell', $tablecorner='', $bsv=0, $bsh=0) {
24901
24902 $cellBorderOverlay = array();
24903
24904 if ($bord==-1) { $this->Rect($x, $y, $w, $h); }
24905 else if ($this->simpleTables && ($cort=='cell')) {
24906 $this->SetLineWidth($details['L']['w']);
24907 if ($details['L']['c']) {
24908 $this->SetDColor($details['L']['c']);
24909 }
24910 else { $this->SetDColor($this->ConvertColor(0)); }
24911 $this->SetLineJoin(0);
24912 $this->Rect($x, $y, $w, $h);
24913 }
24914 else if ($bord){
24915 if (!$bSeparate && $buffer) {
24916 $priority = 'LRTB';
24917 for($p=0;$p<strlen($priority);$p++) {
24918 $side = $priority[$p];
24919 $details['p'] = $side ;
24920
24921 $dom = 0;
24922 if (isset($details[$side]['w'])) { $dom += ($details[$side]['w'] * 100000); }
24923 if (isset($details[$side]['style'])) { $dom += (array_search($details[$side]['style'],$this->borderstyles)*100) ; }
24924 if (isset($details[$side]['dom'])) { $dom += ($details[$side]['dom']*10); }
24925
24926 // Precedence to darker colours at joins
24927 $coldom = 0;
24928 if (isset($details[$side]['c']) && is_array($details[$side]['c'])) {
24929 // mPDF 5.3.74
24930 if ($details[$side]['c']{0}==3) { // RGB
24931 $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);
24932 }
24933 } // 10 black - 0 white
24934 if ($coldom) { $dom += $coldom; }
24935 // Lastly precedence to RIGHT and BOTTOM cells at joins
24936 if (isset($details['cellposdom'])) { $dom += $details['cellposdom']; }
24937
24938 $save = false;
24939 if ($side == 'T' && $this->issetBorder($bord, _BORDER_TOP)) { $cbord = _BORDER_TOP; $save = true; }
24940 else if ($side == 'L' && $this->issetBorder($bord, _BORDER_LEFT)) { $cbord = _BORDER_LEFT; $save = true; }
24941 else if ($side == 'R' && $this->issetBorder($bord, _BORDER_RIGHT)) { $cbord = _BORDER_RIGHT; $save = true; }
24942 else if ($side == 'B' && $this->issetBorder($bord, _BORDER_BOTTOM)) { $cbord = _BORDER_BOTTOM; $save = true; }
24943
24944 if ($save) {
24945 // mPDF 5.3.74
24946 $this->cellBorderBuffer[] = pack("A16nCnda6A10d14",
24947 str_pad(sprintf("%08.7f", $dom),16,"0",STR_PAD_LEFT),
24948 $cbord,
24949 ord($side),
24950 $details[$side]['s'],
24951 $details[$side]['w'],
24952 $details[$side]['c'],
24953 $details[$side]['style'],
24954 $x, $y, $w, $h,
24955 $details['mbw']['BL'],
24956 $details['mbw']['BR'],
24957 $details['mbw']['RT'],
24958 $details['mbw']['RB'],
24959 $details['mbw']['TL'],
24960 $details['mbw']['TR'],
24961 $details['mbw']['LT'],
24962 $details['mbw']['LB'],
24963 $details['cellposdom'],
24964 0
24965 );
24966 if ($details[$side]['style'] == 'ridge' || $details[$side]['style'] == 'groove' || $details[$side]['style'] == 'inset' || $details[$side]['style'] == 'outset' || $details[$side]['style'] == 'double' ) {
24967 $details[$side]['overlay'] = true;
24968 // mPDF 5.3.74
24969 $this->cellBorderBuffer[] = pack("A16nCnda6A10d14",
24970 str_pad(sprintf("%08.7f", ($dom+4)),16,"0",STR_PAD_LEFT),
24971 $cbord,
24972 ord($side),
24973 $details[$side]['s'],
24974 $details[$side]['w'],
24975 $details[$side]['c'],
24976 $details[$side]['style'],
24977 $x, $y, $w, $h,
24978 $details['mbw']['BL'],
24979 $details['mbw']['BR'],
24980 $details['mbw']['RT'],
24981 $details['mbw']['RB'],
24982 $details['mbw']['TL'],
24983 $details['mbw']['TR'],
24984 $details['mbw']['LT'],
24985 $details['mbw']['LB'],
24986 $details['cellposdom'],
24987 1
24988 );
24989 }
24990 }
24991 }
24992 return;
24993 }
24994
24995 if (isset($details['p']) && strlen($details['p'])>1) { $priority = $details['p']; }
24996 else { $priority='LTRB'; }
24997 $Tw = 0;
24998 $Rw = 0;
24999 $Bw = 0;
25000 $Lw = 0;
25001 if (isset($details['T']['w'])) { $Tw = $details['T']['w']; }
25002 if (isset($details['R']['w'])) { $Rw = $details['R']['w']; }
25003 if (isset($details['B']['w'])) { $Bw = $details['B']['w']; }
25004 if (isset($details['L']['w'])) { $Lw = $details['L']['w']; }
25005
25006 $x2 = $x + $w; $y2 = $y + $h;
25007 $oldlinewidth = $this->LineWidth;
25008
25009 for($p=0;$p<strlen($priority);$p++) {
25010 $side = $priority[$p];
25011 $xadj = 0;
25012 $xadj2 = 0;
25013 $yadj = 0;
25014 $yadj2 = 0;
25015 $print = false;
25016 if ($Tw && $side=='T' && $this->issetBorder($bord, _BORDER_TOP)) { // TOP
25017 $ly1 = $y;
25018 $ly2 = $y;
25019 $lx1 = $x;
25020 $lx2 = $x2;
25021 $this->SetLineWidth($Tw);
25022 if ($cort == 'cell' || strpos($tablecorner,'L')!==false) {
25023 if ($Tw > $Lw) $xadj = ($Tw - $Lw)/2;
25024 if ($Tw < $Lw) $xadj = ($Tw + $Lw)/2;
25025 }
25026 else { $xadj = $Tw/2 - $bsh/2; }
25027 if ($cort == 'cell' || strpos($tablecorner,'R')!==false) {
25028 if ($Tw > $Rw) $xadj2 = ($Tw - $Rw)/2;
25029 if ($Tw < $Rw) $xadj2 = ($Tw + $Rw)/2;
25030 }
25031 else { $xadj2 = $Tw/2 - $bsh/2; }
25032 if (!$bSeparate && $details['mbw']['TL']) {
25033 $xadj = ($Tw - $details['mbw']['TL'])/2 ;
25034 }
25035 if (!$bSeparate && $details['mbw']['TR']) {
25036 $xadj2 = ($Tw - $details['mbw']['TR'])/2;
25037 }
25038 $print = true;
25039 }
25040 if ($Lw && $side=='L' && $this->issetBorder($bord, _BORDER_LEFT)) { // LEFT
25041 $ly1 = $y;
25042 $ly2 = $y2;
25043 $lx1 = $x;
25044 $lx2 = $x;
25045 $this->SetLineWidth($Lw);
25046 if ($cort == 'cell' || strpos($tablecorner,'T')!==false) {
25047 if ($Lw > $Tw) $yadj = ($Lw - $Tw)/2;
25048 if ($Lw < $Tw) $yadj = ($Lw + $Tw)/2;
25049 }
25050 else { $yadj = $Lw/2 - $bsv/2; }
25051 if ($cort == 'cell' || strpos($tablecorner,'B')!==false) {
25052 if ($Lw > $Bw) $yadj2 = ($Lw - $Bw)/2;
25053 if ($Lw < $Bw) $yadj2 = ($Lw + $Bw)/2;
25054 }
25055 else { $yadj2 = $Lw/2 - $bsv/2; }
25056 if (!$bSeparate && $details['mbw']['LT']) {
25057 $yadj = ($Lw - $details['mbw']['LT'])/2;
25058 }
25059 if (!$bSeparate && $details['mbw']['LB']) {
25060 $yadj2 = ($Lw - $details['mbw']['LB'])/2;
25061 }
25062 $print = true;
25063 }
25064 if ($Rw && $side=='R' && $this->issetBorder($bord, _BORDER_RIGHT)) { // RIGHT
25065 $ly1 = $y;
25066 $ly2 = $y2;
25067 $lx1 = $x2;
25068 $lx2 = $x2;
25069 $this->SetLineWidth($Rw);
25070 if ($cort == 'cell' || strpos($tablecorner,'T')!==false) {
25071 if ($Rw < $Tw) $yadj = ($Rw + $Tw)/2;
25072 if ($Rw > $Tw) $yadj = ($Rw - $Tw)/2;
25073 }
25074 else { $yadj = $Rw/2 - $bsv/2; }
25075
25076 if ($cort == 'cell' || strpos($tablecorner,'B')!==false) {
25077 if ($Rw > $Bw) $yadj2 = ($Rw - $Bw)/2;
25078 if ($Rw < $Bw) $yadj2 = ($Rw + $Bw)/2;
25079 }
25080 else { $yadj2 = $Rw/2 - $bsv/2; }
25081
25082 if (!$bSeparate && $details['mbw']['RT']) {
25083 $yadj = ($Rw - $details['mbw']['RT'])/2;
25084 }
25085 if (!$bSeparate && $details['mbw']['RB']) {
25086 $yadj2 = ($Rw - $details['mbw']['RB'])/2;
25087 }
25088 $print = true;
25089 }
25090 if ($Bw && $side=='B' && $this->issetBorder($bord, _BORDER_BOTTOM)) { // BOTTOM
25091 $ly1 = $y2;
25092 $ly2 = $y2;
25093 $lx1 = $x;
25094 $lx2 = $x2;
25095 $this->SetLineWidth($Bw);
25096 if ($cort == 'cell' || strpos($tablecorner,'L')!==false) {
25097 if ($Bw > $Lw) $xadj = ($Bw - $Lw)/2;
25098 if ($Bw < $Lw) $xadj = ($Bw + $Lw)/2;
25099 }
25100 else { $xadj = $Bw/2 - $bsh/2; }
25101 if ($cort == 'cell' || strpos($tablecorner,'R')!==false) {
25102 if ($Bw > $Rw) $xadj2 = ($Bw - $Rw)/2;
25103 if ($Bw < $Rw) $xadj2 = ($Bw + $Rw)/2;
25104 }
25105 else { $xadj2 = $Bw/2 - $bsh/2; }
25106 if (!$bSeparate && $details['mbw']['BL']) {
25107 $xadj = ($Bw - $details['mbw']['BL'])/2;
25108 }
25109 if (!$bSeparate && $details['mbw']['BR']) {
25110 $xadj2 = ($Bw - $details['mbw']['BR'])/2;
25111 }
25112 $print = true;
25113 }
25114
25115 // Now draw line
25116 if ($print) {
25117 /*-- TABLES-ADVANCED-BORDERS --*/
25118 if ($details[$side]['style'] == 'double') {
25119 if (!isset($details[$side]['overlay']) || !$details[$side]['overlay'] || $bSeparate) {
25120 if ($details[$side]['c']) {
25121 $this->SetDColor($details[$side]['c']);
25122 }
25123 else { $this->SetDColor($this->ConvertColor(0)); }
25124 $this->Line($lx1 + $xadj, $ly1 + $yadj, $lx2 - $xadj2, $ly2 - $yadj2);
25125 }
25126 if ((isset($details[$side]['overlay']) && $details[$side]['overlay']) || $bSeparate) {
25127 if ($bSeparate && $cort=='table') {
25128 if ($side=='T') {
25129 $xadj -= $this->LineWidth/2;
25130 $xadj2 -= $this->LineWidth;
25131 if ($this->issetBorder($bord, _BORDER_LEFT)) {
25132 $xadj += $this->LineWidth/2;
25133 }
25134 if ($this->issetBorder($bord, _BORDER_RIGHT)) {
25135 $xadj2 += $this->LineWidth;
25136 }
25137 }
25138 if ($side=='L') {
25139 $yadj -= $this->LineWidth/2;
25140 $yadj2 -= $this->LineWidth;
25141 if ($this->issetBorder($bord, _BORDER_TOP)) {
25142 $yadj += $this->LineWidth/2;
25143 }
25144 if ($this->issetBorder($bord, _BORDER_BOTTOM)) {
25145 $yadj2 += $this->LineWidth;
25146 }
25147 }
25148 if ($side=='B') {
25149 $xadj -= $this->LineWidth/2;
25150 $xadj2 -= $this->LineWidth;
25151 if ($this->issetBorder($bord, _BORDER_LEFT)) {
25152 $xadj += $this->LineWidth/2;
25153 }
25154 if ($this->issetBorder($bord, _BORDER_RIGHT)) {
25155 $xadj2 += $this->LineWidth;
25156 }
25157 }
25158 if ($side=='R') {
25159 $yadj -= $this->LineWidth/2;
25160 $yadj2 -= $this->LineWidth;
25161 if ($this->issetBorder($bord, _BORDER_TOP)) {
25162 $yadj += $this->LineWidth/2;
25163 }
25164 if ($this->issetBorder($bord, _BORDER_BOTTOM)) {
25165 $yadj2 += $this->LineWidth;
25166 }
25167 }
25168 }
25169
25170 $this->SetLineWidth($this->LineWidth/3);
25171
25172 $tbcol = $this->ConvertColor(255);
25173 for($l=0; $l <= $this->blklvl; $l++) {
25174 if ($this->blk[$l]['bgcolor']) {
25175 $tbcol = array($this->blk[$l]['bgcolorarray']);
25176 }
25177 }
25178
25179 if ($bSeparate) {
25180 $cellBorderOverlay[] = array(
25181 'x' => $lx1 + $xadj,
25182 'y' => $ly1 + $yadj,
25183 'x2' => $lx2 - $xadj2,
25184 'y2' => $ly2 - $yadj2,
25185 'col' => $tbcol,
25186 'lw' => $this->LineWidth,
25187 );
25188 }
25189 else {
25190 $this->SetDColor($tbcol);
25191 $this->Line($lx1 + $xadj, $ly1 + $yadj, $lx2 - $xadj2, $ly2 - $yadj2);
25192 }
25193 }
25194 }
25195
25196
25197 else if (isset($details[$side]['style']) && ($details[$side]['style'] == 'ridge' || $details[$side]['style'] == 'groove' || $details[$side]['style'] == 'inset' || $details[$side]['style'] == 'outset')) {
25198 if (!isset($details[$side]['overlay']) || !$details[$side]['overlay'] || $bSeparate) {
25199 if ($details[$side]['c']) {
25200 $this->SetDColor($details[$side]['c']);
25201 }
25202 else { $this->SetDColor($this->ConvertColor(0)); }
25203 if ($details[$side]['style'] == 'outset' || $details[$side]['style'] == 'groove') {
25204 $nc = $this->_darkenColor($details[$side]['c']);
25205 $this->SetDColor($nc);
25206 }
25207 else if ($details[$side]['style'] == 'ridge' || $details[$side]['style'] == 'inset') {
25208 $nc = $this->_lightenColor($details[$side]['c']);
25209 $this->SetDColor($nc);
25210 }
25211 $this->Line($lx1 + $xadj, $ly1 + $yadj, $lx2 - $xadj2, $ly2 - $yadj2);
25212 }
25213 if ((isset($details[$side]['overlay']) && $details[$side]['overlay']) || $bSeparate) {
25214 if ($details[$side]['c']) {
25215 $this->SetDColor($details[$side]['c']);
25216 }
25217 else { $this->SetDColor($this->ConvertColor(0)); }
25218 $doubleadj = ($this->LineWidth)/3;
25219 $this->SetLineWidth($this->LineWidth/2);
25220 $xadj3 = $yadj3 = $wadj3 = $hadj3 = 0;
25221
25222 if ($details[$side]['style'] == 'ridge' || $details[$side]['style'] == 'inset') {
25223 $nc = $this->_darkenColor($details[$side]['c']);
25224
25225 if ($bSeparate && $cort=='table') {
25226 if ($side=='T') {
25227 $yadj3 = $this->LineWidth/2;
25228 $xadj3 = -$this->LineWidth/2;
25229 $wadj3 = $this->LineWidth;
25230 if ($this->issetBorder($bord, _BORDER_LEFT)) {
25231 $xadj3 += $this->LineWidth; $wadj3 -= $this->LineWidth;
25232 }
25233 if ($this->issetBorder($bord, _BORDER_RIGHT)) {
25234 $wadj3 -= $this->LineWidth*2;
25235 }
25236 }
25237 if ($side=='L') {
25238 $xadj3 = $this->LineWidth/2;
25239 $yadj3 = -$this->LineWidth/2;
25240 $hadj3 = $this->LineWidth;
25241 if ($this->issetBorder($bord, _BORDER_TOP)) {
25242 $yadj3 += $this->LineWidth; $hadj3 -= $this->LineWidth;
25243 }
25244 if ($this->issetBorder($bord, _BORDER_BOTTOM)) {
25245 $hadj3 -= $this->LineWidth*2;
25246 }
25247 }
25248 if ($side=='B') {
25249 $yadj3 = $this->LineWidth/2;
25250 $xadj3 = -$this->LineWidth/2;
25251 $wadj3 = $this->LineWidth;
25252 }
25253 if ($side=='R') {
25254 $xadj3 = $this->LineWidth/2;
25255 $yadj3 = -$this->LineWidth/2;
25256 $hadj3 = $this->LineWidth;
25257 }
25258 }
25259
25260 else if ($side=='T') { $yadj3 = $this->LineWidth/2; $xadj3 = $this->LineWidth/2; $wadj3 = -$this->LineWidth*2; }
25261 else if ($side=='L') { $xadj3 = $this->LineWidth/2; $yadj3 = $this->LineWidth/2; $hadj3 = -$this->LineWidth*2; }
25262
25263 else if ($side=='B' && $bSeparate) { $yadj3 = $this->LineWidth/2; $wadj3 = $this->LineWidth/2; }
25264 else if ($side=='R' && $bSeparate) { $xadj3 = $this->LineWidth/2; $hadj3 = $this->LineWidth/2; }
25265
25266 else if ($side=='B') { $yadj3 = $this->LineWidth/2; $xadj3 = $this->LineWidth/2; }
25267 else if ($side=='R') { $xadj3 = $this->LineWidth/2; $yadj3 = $this->LineWidth/2; }
25268 }
25269 else {
25270 $nc = $this->_lightenColor($details[$side]['c']);
25271
25272 if ($bSeparate && $cort=='table') {
25273 if ($side=='T') {
25274 $yadj3 = $this->LineWidth/2;
25275 $xadj3 = -$this->LineWidth/2;
25276 $wadj3 = $this->LineWidth;
25277 if ($this->issetBorder($bord, _BORDER_LEFT)) {
25278 $xadj3 += $this->LineWidth; $wadj3 -= $this->LineWidth;
25279 }
25280 }
25281 if ($side=='L') {
25282 $xadj3 = $this->LineWidth/2;
25283 $yadj3 = -$this->LineWidth/2;
25284 $hadj3 = $this->LineWidth;
25285 if ($this->issetBorder($bord, _BORDER_TOP)) {
25286 $yadj3 += $this->LineWidth; $hadj3 -= $this->LineWidth;
25287 }
25288 }
25289 if ($side=='B') {
25290 $yadj3 = $this->LineWidth/2;
25291 $xadj3 = -$this->LineWidth/2;
25292 $wadj3 = $this->LineWidth;
25293 if ($this->issetBorder($bord, _BORDER_LEFT)) {
25294 $xadj3 += $this->LineWidth; $wadj3 -= $this->LineWidth;
25295 }
25296 }
25297 if ($side=='R') {
25298 $xadj3 = $this->LineWidth/2;
25299 $yadj3 = -$this->LineWidth/2;
25300 $hadj3 = $this->LineWidth;
25301 if ($this->issetBorder($bord, _BORDER_TOP)) {
25302 $yadj3 += $this->LineWidth; $hadj3 -= $this->LineWidth;
25303 }
25304 }
25305 }
25306
25307 else if ($side=='T') { $yadj3 = $this->LineWidth/2; $xadj3 = $this->LineWidth/2; }
25308 else if ($side=='L') { $xadj3 = $this->LineWidth/2; $yadj3 = $this->LineWidth/2; }
25309
25310 else if ($side=='B' && $bSeparate) { $yadj3 = $this->LineWidth/2; $xadj3 = $this->LineWidth/2; }
25311 else if ($side=='R' && $bSeparate) { $xadj3 = $this->LineWidth/2; $yadj3 = $this->LineWidth/2; }
25312
25313 else if ($side=='B') { $yadj3 = $this->LineWidth/2; $xadj3 = -$this->LineWidth/2; $wadj3 = $this->LineWidth; }
25314 else if ($side=='R') { $xadj3 = $this->LineWidth/2; $yadj3 = -$this->LineWidth/2; $hadj3 = $this->LineWidth; }
25315
25316 }
25317
25318 if ($bSeparate) {
25319 $cellBorderOverlay[] = array(
25320 'x' => $lx1 + $xadj + $xadj3,
25321 'y' => $ly1 + $yadj + $yadj3,
25322 'x2' => $lx2 - $xadj2 + $xadj3 + $wadj3,
25323 'y2' => $ly2 - $yadj2 + $yadj3 + $hadj3,
25324 'col' => $nc,
25325 'lw' => $this->LineWidth,
25326 );
25327 }
25328 else {
25329 $this->SetDColor($nc);
25330 $this->Line($lx1 + $xadj + $xadj3, $ly1 + $yadj + $yadj3, $lx2 - $xadj2 + $xadj3 + $wadj3, $ly2 - $yadj2 + $yadj3 + $hadj3);
25331 }
25332 }
25333 }
25334
25335
25336 else {
25337 /*-- END TABLES-ADVANCED-BORDERS --*/
25338 if ($details[$side]['style'] == 'dashed') {
25339 $dashsize = 2; // final dash will be this + 1*linewidth
25340 $dashsizek = 1.5; // ratio of Dash/Blank
25341 $this->SetDash($dashsize,($dashsize/$dashsizek)+($this->LineWidth*2));
25342 }
25343 else if ($details[$side]['style'] == 'dotted') {
25344 $this->SetLineJoin(1);
25345 $this->SetLineCap(1);
25346 $this->SetDash(0.001,($this->LineWidth*2));
25347 }
25348 if ($details[$side]['c']) {
25349 $this->SetDColor($details[$side]['c']);
25350 }
25351 else { $this->SetDColor($this->ConvertColor(0)); }
25352 $this->Line($lx1 + $xadj, $ly1 + $yadj, $lx2 - $xadj2, $ly2 - $yadj2);
25353 /*-- TABLES-ADVANCED-BORDERS --*/
25354 }
25355 /*-- END TABLES-ADVANCED-BORDERS --*/
25356
25357 // Reset Corners
25358 $this->SetDash();
25359 //BUTT style line cap
25360 $this->SetLineCap(2);
25361 }
25362 }
25363
25364 if ($bSeparate && count($cellBorderOverlay)) {
25365 foreach($cellBorderOverlay AS $cbo) {
25366 $this->SetLineWidth($cbo['lw']);
25367 $this->SetDColor($cbo['col']);
25368 $this->Line($cbo['x'], $cbo['y'], $cbo['x2'], $cbo['y2']);
25369 }
25370 }
25371
25372 // $this->SetLineWidth($oldlinewidth);
25373 // $this->SetDColor($this->ConvertColor(0));
25374 }
25375 }
25376
25377
25378 /*-- TABLES --*/
25379 /*-- TABLES-ADVANCED-BORDERS --*/
25380 function _lightenColor($c) {
25381 // mPDF 5.3.74
25382 if (is_array($c)) { die('Color error in _lightencolor'); }
25383 if ($c{0}==3 || $c{0}==5) { // RGB
25384 list($h,$s,$l) = $this->rgb2hsl(ord($c{1})/255,ord($c{2})/255,ord($c{3})/255);
25385 $l += ((1 - $l)*0.8);
25386 list($r,$g,$b) = $this->hsl2rgb($h,$s,$l);
25387 $ret = array(3,$r,$g,$b);
25388 }
25389 else if ($c{0}==4 || $c{0}==6) { // CMYK
25390 $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)) );
25391 }
25392 else if ($c{0}==1) { // Grayscale
25393 $ret = array(1,min(255,(ord($c{1})+32)));
25394 }
25395 $c = array_pad($ret, 6, 0);
25396 $cstr = pack("a1ccccc", $c[0], ($c[1] & 0xFF), ($c[2] & 0xFF), ($c[3] & 0xFF), ($c[4] & 0xFF), ($c[5] & 0xFF) );
25397 return $cstr;
25398 }
25399
25400
25401 function _darkenColor($c) {
25402 if (is_array($c)) { die('Color error in _darkenColor'); }
25403 // mPDF 5.3.74
25404 if ($c{0}==3 || $c{0}==5) { // RGB
25405 list($h,$s,$l) = $this->rgb2hsl(ord($c{1})/255,ord($c{2})/255,ord($c{3})/255);
25406 $s *= 0.25;
25407 $l *= 0.75;
25408 list($r,$g,$b) = $this->hsl2rgb($h,$s,$l);
25409 $ret = array(3,$r,$g,$b);
25410 }
25411 else if ($c{0}==4 || $c{0}==6) { // CMYK
25412 $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)) );
25413 }
25414 else if ($c{0}==1) { // Grayscale
25415 $ret = array(1,max(0,(ord($c{1})-32)));
25416 }
25417 $c = array_pad($ret, 6, 0);
25418 $cstr = pack("a1ccccc", $c[0], ($c[1] & 0xFF), ($c[2] & 0xFF), ($c[3] & 0xFF), ($c[4] & 0xFF), ($c[5] & 0xFF) );
25419 return $cstr;
25420 }
25421
25422 /*-- END TABLES-ADVANCED-BORDERS --*/
25423
25424
25425
25426 function setBorder(&$var, $flag, $set = true) {
25427 $flag = intval($flag);
25428 if ($set) { $set = true; }
25429 $var = intval($var);
25430 $var = $set ? ($var | $flag) : ($var & ~$flag);
25431 }
25432 function issetBorder($var, $flag) {
25433 $flag = intval($flag);
25434 $var = intval($var);
25435 return (($var & $flag) == $flag);
25436 }
25437
25438
25439 function _table2cellBorder(&$tableb, &$cbdb, &$cellb, $bval) {
25440 if ($tableb && $tableb['w'] > $cbdb['w']) {
25441 $cbdb = $tableb;
25442 $this->setBorder($cellb, $bval);
25443 }
25444 else if ($tableb && $tableb['w'] == $cbdb['w']
25445 && array_search($tableb['style'],$this->borderstyles) > array_search($cbdb['style'],$this->borderstyles)) {
25446 $cbdb = $tableb;
25447 $this->setBorder($cellb, $bval);
25448 }
25449 }
25450
25451 // FIX BORDERS ********************************************
25452 function _fixTableBorders(&$table){
25453 // mPDF 5.3.79
25454 if ($this->cacheTables) { $fh = fopen($table['cache'], "r+b"); }
25455 else { $fh = null; }
25456
25457 if (!$table['borders_separate'] && $table['border_details']['L']['w']) {
25458 $table['max_cell_border_width']['L'] = $table['border_details']['L']['w'];
25459 }
25460 if (!$table['borders_separate'] && $table['border_details']['R']['w']) {
25461 $table['max_cell_border_width']['R'] = $table['border_details']['R']['w'];
25462 }
25463 if (!$table['borders_separate'] && $table['border_details']['T']['w']) {
25464 $table['max_cell_border_width']['T'] = $table['border_details']['T']['w'];
25465 }
25466 if (!$table['borders_separate'] && $table['border_details']['B']['w']) {
25467 $table['max_cell_border_width']['B'] = $table['border_details']['B']['w'];
25468 }
25469 if ($this->simpleTables) { return; }
25470 $cells = &$table['cells'];
25471 $numcols = $table['nc'];
25472 $numrows = $table['nr'];
25473 /*-- TABLES-ADVANCED-BORDERS --*/
25474 // mPDF 5.3.64
25475 if (isset($table['topntail']) && $table['topntail']) { $tntborddet = $this->border_details($table['topntail']); }
25476 if (isset($table['thead-underline']) && $table['thead-underline']) { $thuborddet = $this->border_details($table['thead-underline']); }
25477 /*-- END TABLES-ADVANCED-BORDERS --*/
25478
25479 for( $i = 0 ; $i < $numrows ; $i++ ) { //Rows
25480 for( $j = 0 ; $j < $numcols ; $j++ ) { //Columns
25481 if (isset($cells[$i][$j]) && $cells[$i][$j]) {
25482 // mPDF 5.3.79
25483 if ($this->cacheTables) {
25484 $cell = $this->_uncacheCell($table['cells'][$i][$j], '', $fh);
25485 }
25486 else
25487 $cell = &$cells[$i][$j];
25488 if ($this->packTableData) { // includes $this->cacheTables
25489 $cbord = $this->_unpackCellBorder($cell['borderbin']);
25490 }
25491 else {
25492 $cbord = &$cells[$i][$j];
25493 }
25494
25495 if (!$cbord['border'] && isset($table['border']) && $table['border'] && $this->table_border_attr_set) {
25496 $cbord['border'] = $table['border'];
25497 $cbord['border_details'] = $table['border_details'];
25498 }
25499
25500 if (isset($cell['colspan']) && $cell['colspan']>1) { $ccolsp = $cell['colspan']; }
25501 else { $ccolsp = 1; }
25502 if (isset($cell['rowspan']) && $cell['rowspan']>1) { $crowsp = $cell['rowspan']; }
25503 else { $crowsp = 1; }
25504
25505 $cbord['border_details']['cellposdom'] = ((($i+1)/$numrows) / 10000 ) + ((($j+1)/$numcols) / 10 );
25506 // Inherit Cell border from Table border
25507 if ($this->table_border_css_set && !$table['borders_separate']) {
25508 if ($i == 0) {
25509 $this->_table2cellBorder($table['border_details']['T'], $cbord['border_details']['T'], $cbord['border'], _BORDER_TOP);
25510 }
25511 if ($i == ($numrows-1) || ($i+$crowsp) == ($numrows) ) {
25512 $this->_table2cellBorder($table['border_details']['B'], $cbord['border_details']['B'], $cbord['border'], _BORDER_BOTTOM);
25513 }
25514 if ($j == 0) {
25515 $this->_table2cellBorder($table['border_details']['L'], $cbord['border_details']['L'], $cbord['border'], _BORDER_LEFT);
25516 }
25517 if ($j == ($numcols-1) || ($j+$ccolsp) == ($numcols) ) {
25518 $this->_table2cellBorder($table['border_details']['R'], $cbord['border_details']['R'], $cbord['border'], _BORDER_RIGHT);
25519 }
25520 }
25521
25522 /*-- TABLES-ADVANCED-BORDERS --*/
25523 $fixbottom = true; // mPDF 5.3.64
25524 if (isset($table['topntail']) && $table['topntail']) {
25525 if ($i == 0) {
25526 $cbord['border_details']['T'] = $tntborddet;
25527 $this->setBorder($cbord['border'], _BORDER_TOP);
25528 }
25529 if ($this->tableLevel==1 && $table['headernrows']>0 && $i == $table['headernrows']-1) { // mPDF 5.3.62 // mPDF 5.3.76
25530 $cbord['border_details']['B'] = $tntborddet;
25531 $this->setBorder($cbord['border'], _BORDER_BOTTOM);
25532 $fixbottom = false; // mPDF 5.3.64
25533 }
25534 else if ($this->tableLevel==1 && $table['headernrows']>0 && $i == $table['headernrows']) { // mPDF 5.3.62
25535 if (!$table['borders_separate']) {
25536 $cbord['border_details']['T'] = $tntborddet;
25537 $this->setBorder($cbord['border'], _BORDER_TOP);
25538 }
25539 }
25540 if ($this->tableLevel==1 && $table['footernrows']>0 && $i == ($numrows-$table['footernrows']-1)) { // mPDF 5.3.62
25541 if (!$table['borders_separate']) {
25542 $cbord['border_details']['B'] = $tntborddet;
25543 $this->setBorder($cbord['border'], _BORDER_BOTTOM);
25544 $fixbottom = false; // mPDF 5.3.64
25545 }
25546 }
25547 else if ($this->tableLevel==1 && $table['footernrows']>0 && $i == ($numrows-$table['footernrows'])) { // mPDF 5.3.62
25548 $cbord['border_details']['T'] = $tntborddet;
25549 $this->setBorder($cbord['border'], _BORDER_TOP);
25550 }
25551 if ($this->tabletheadjustfinished) { // $this->tabletheadjustfinished called from tableheader
25552 if (!$table['borders_separate']) {
25553 $cbord['border_details']['T'] = $tntborddet;
25554 $this->setBorder($cbord['border'], _BORDER_TOP);
25555 }
25556 }
25557 if ($i == ($numrows-1) || ($i+$crowsp) == ($numrows) ) {
25558 $cbord['border_details']['B'] = $tntborddet;
25559 $this->setBorder($cbord['border'], _BORDER_BOTTOM);
25560 }
25561 }
25562 if (isset($table['thead-underline']) && $table['thead-underline']) {
25563 if ($table['borders_separate']) {
25564 if ($i == 0) {
25565 $cbord['border_details']['B'] = $thuborddet;
25566 $this->setBorder($cbord['border'], _BORDER_BOTTOM);
25567 $fixbottom = false; // mPDF 5.3.64
25568 }
25569 }
25570 else {
25571 if ($this->tableLevel==1 && $table['headernrows']>0 && $i == $table['headernrows']-1) { // mPDF 5.3.62
25572 $cbord['border_details']['T'] = $thuborddet;
25573 $this->setBorder($cbord['border'], _BORDER_TOP);
25574 }
25575 else if ($this->tabletheadjustfinished) { // $this->tabletheadjustfinished called from tableheader
25576 $cbord['border_details']['T'] = $thuborddet;
25577 $this->setBorder($cbord['border'], _BORDER_TOP);
25578 }
25579 }
25580 }
25581
25582 // Collapse Border - Algorithm for conflicting borders
25583 // Hidden >> Width >> double>solid>dashed>dotted... >> style set on cell>table >> top/left>bottom/right
25584 // Do not turn off border which is overridden
25585 // Needed for page break for TOP/BOTTOM both to be defined in Collapsed borders
25586 // Means it is painted twice. (Left/Right can still disable overridden border)
25587 if (!$table['borders_separate']) { // mPDF 5.3.64
25588 if (($i < ($numrows-1) || ($i+$crowsp) < $numrows ) && $fixbottom ) { // Bottom // mPDF 5.3.64
25589 for ($cspi = 0; $cspi<$ccolsp; $cspi++) {
25590 // already defined Top for adjacent cell below
25591 if (isset($cells[($i+$crowsp)][$j+$cspi])) {
25592 if ($this->packTableData) {
25593 // mPDF 5.3.79
25594 if ($this->cacheTables) {
25595 $adjc = $this->_uncacheCell($table['cells'][$i+$crowsp][$j+$cspi], '', $fh);
25596 }
25597 else { $adjc = $cells[($i+$crowsp)][$j+$cspi]; }
25598 $celladj = $this->_unpackCellBorder($adjc['borderbin']);
25599 }
25600 else { $celladj =& $cells[($i+$crowsp)][$j+$cspi]; }
25601 }
25602 else { $celladj = false; }
25603 if ($celladj && $celladj['border_details']['T']['s'] == 1) {
25604 $csadj = $celladj['border_details']['T']['w'];
25605 $csthis = $cbord['border_details']['B']['w'];
25606 // Hidden
25607 if ($cbord['border_details']['B']['style']=='hidden') {
25608 $celladj['border_details']['T'] = $cbord['border_details']['B'];
25609 $this->setBorder($celladj['border'] , _BORDER_TOP, false);
25610 $this->setBorder($cbord['border'] , _BORDER_BOTTOM , false);
25611 }
25612 else if ($celladj['border_details']['T']['style']=='hidden') {
25613 $cbord['border_details']['B'] = $celladj['border_details']['T'];
25614 $this->setBorder($cbord['border'] , _BORDER_BOTTOM , false);
25615 $this->setBorder($celladj['border'] , _BORDER_TOP, false);
25616 }
25617 // Width
25618 else if ($csthis > $csadj) {
25619 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
25620 $celladj['border_details']['T'] = $cbord['border_details']['B'];
25621 $this->setBorder($cbord['border'] , _BORDER_BOTTOM);
25622 }
25623 }
25624 else if ($csadj > $csthis) {
25625 if ($ccolsp < 2) { // don't overwrite this cell if it spans
25626 $cbord['border_details']['B'] = $celladj['border_details']['T'];
25627 $this->setBorder($celladj['border'] , _BORDER_TOP);
25628 }
25629 }
25630
25631 // double>solid>dashed>dotted...
25632 else if (array_search($cbord['border_details']['B']['style'],$this->borderstyles) > array_search($celladj['border_details']['T']['style'],$this->borderstyles)) {
25633 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
25634 $celladj['border_details']['T'] = $cbord['border_details']['B'];
25635 $this->setBorder($cbord['border'] , _BORDER_BOTTOM );
25636 }
25637 }
25638 else if (array_search($celladj['border_details']['T']['style'],$this->borderstyles) > array_search($cbord['border_details']['B']['style'],$this->borderstyles)) {
25639 if ($ccolsp < 2) { // don't overwrite this cell if it spans
25640 $cbord['border_details']['B'] = $celladj['border_details']['T'];
25641 $this->setBorder($celladj['border'] , _BORDER_TOP);
25642 }
25643 }
25644
25645
25646
25647 // Style set on cell vs. table
25648 else if ($celladj['border_details']['T']['dom'] > $cbord['border_details']['B']['dom']) {
25649 if ($ccolsp < 2) { // don't overwrite this cell if it spans
25650 $cbord['border_details']['B'] = $celladj['border_details']['T'];
25651 $this->setBorder($celladj['border'] , _BORDER_TOP);
25652 }
25653 }
25654 // Style set on cell vs. table - OR - LEFT/TOP (cell) in preference to BOTTOM/RIGHT
25655 else {
25656 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
25657 $celladj['border_details']['T'] = $cbord['border_details']['B'];
25658 $this->setBorder($cbord['border'] , _BORDER_BOTTOM );
25659 }
25660 }
25661 }
25662 else if ($celladj) {
25663 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
25664 $celladj['border_details']['T'] = $cbord['border_details']['B'];
25665 }
25666 }
25667 // mPDF 5.3.79
25668 if ($celladj && $this->packTableData) {
25669 $celladj['borderbin'] = $this->_packCellBorder($celladj);
25670 unset($celladj['border']);
25671 unset($celladj['border_details']);
25672 }
25673 if ($this->cacheTables) {
25674 $this->_cacheUpdateBorder($celladj, $fh, $table['cells'][$i+$crowsp][$j+$cspi]);
25675 }
25676 unset($celladj);
25677 }
25678 }
25679
25680 if ($j < ($numcols-1) || ($j+$ccolsp) < $numcols ) { // Right-Left
25681 for ($cspi = 0; $cspi<$crowsp; $cspi++) {
25682 // already defined Left for adjacent cell to R
25683 if (isset($cells[($i+$cspi)][$j+$ccolsp])) {
25684 if ($this->packTableData) {
25685 // mPDF 5.3.79
25686 if ($this->cacheTables) {
25687 $adjc = $this->_uncacheCell($table['cells'][$i+$cspi][$j+$ccolsp], '', $fh);
25688 }
25689 else { $adjc = $cells[($i+$cspi)][$j+$ccolsp]; }
25690 $celladj = $this->_unpackCellBorder($adjc['borderbin']);
25691 }
25692 else { $celladj =& $cells[$i+$cspi][$j+$ccolsp]; }
25693 }
25694 else { $celladj = false; }
25695 if ($celladj && $celladj['border_details']['L']['s'] == 1) {
25696 $csadj = $celladj['border_details']['L']['w'];
25697 $csthis = $cbord['border_details']['R']['w'];
25698 // Hidden
25699 if ($cbord['border_details']['R']['style']=='hidden') {
25700 $celladj['border_details']['L'] = $cbord['border_details']['R'];
25701 $this->setBorder($celladj['border'] , _BORDER_LEFT, false);
25702 $this->setBorder($cbord['border'] , _BORDER_RIGHT , false);
25703 }
25704 else if ($celladj['border_details']['L']['style']=='hidden') {
25705 $cbord['border_details']['R'] = $celladj['border_details']['L'];
25706 $this->setBorder($cbord['border'] , _BORDER_RIGHT , false);
25707 $this->setBorder($celladj['border'] , _BORDER_LEFT, false);
25708 }
25709 // Width
25710 else if ($csthis > $csadj) {
25711 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
25712 $celladj['border_details']['L'] = $cbord['border_details']['R'];
25713 $this->setBorder($cbord['border'] , _BORDER_RIGHT);
25714 $this->setBorder($celladj['border'] , _BORDER_LEFT, false);
25715 }
25716 }
25717 else if ($csadj > $csthis) {
25718 if ($crowsp < 2) { // don't overwrite this cell if it spans
25719 $cbord['border_details']['R'] = $celladj['border_details']['L'];
25720 $this->setBorder($cbord['border'] , _BORDER_RIGHT, false);
25721 $this->setBorder($celladj['border'] , _BORDER_LEFT);
25722 }
25723 }
25724
25725 // double>solid>dashed>dotted...
25726 else if (array_search($cbord['border_details']['R']['style'],$this->borderstyles) > array_search($celladj['border_details']['L']['style'],$this->borderstyles)) {
25727 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
25728 $celladj['border_details']['L'] = $cbord['border_details']['R'];
25729 $this->setBorder($celladj['border'] , _BORDER_LEFT, false);
25730 $this->setBorder($cbord['border'] , _BORDER_RIGHT);
25731 }
25732 }
25733 else if (array_search($celladj['border_details']['L']['style'],$this->borderstyles) > array_search($cbord['border_details']['R']['style'],$this->borderstyles)) {
25734 if ($crowsp < 2) { // don't overwrite this cell if it spans
25735 $cbord['border_details']['R'] = $celladj['border_details']['L'];
25736 $this->setBorder($cbord['border'] , _BORDER_RIGHT , false);
25737 $this->setBorder($celladj['border'] , _BORDER_LEFT);
25738 }
25739 }
25740
25741
25742 // Style set on cell vs. table
25743 else if ($celladj['border_details']['L']['dom'] > $cbord['border_details']['R']['dom']) {
25744 if ($crowsp < 2) { // don't overwrite this cell if it spans
25745 $cbord['border_details']['R'] = $celladj['border_details']['L'];
25746 $this->setBorder($celladj['border'] , _BORDER_LEFT);
25747 }
25748 }
25749 // Style set on cell vs. table - OR - LEFT/TOP (cell) in preference to BOTTOM/RIGHT
25750 else {
25751 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
25752 $celladj['border_details']['L'] = $cbord['border_details']['R'];
25753 $this->setBorder($cbord['border'] , _BORDER_RIGHT);
25754 }
25755 }
25756 }
25757 else if ($celladj) {
25758 // if right-cell border is not set
25759 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
25760 $celladj['border_details']['L'] = $cbord['border_details']['R'];
25761 }
25762 }
25763 // mPDF 5.3.79
25764 if ($celladj && $this->packTableData) {
25765 $celladj['borderbin'] = $this->_packCellBorder($celladj);
25766 unset($celladj['border']);
25767 unset($celladj['border_details']);
25768 }
25769 if ($this->cacheTables) {
25770 $this->_cacheUpdateBorder($celladj, $fh, $table['cells'][$i+$cspi][$j+$ccolsp]);
25771 }
25772 unset($celladj);
25773 }
25774 }
25775 }
25776
25777
25778 // Set maximum cell border width meeting at LRTB edges of cell - used for extended cell border
25779 // ['border_details']['mbw']['LT'] = meeting border width - Left border - Top end
25780 if (!$table['borders_separate']) {
25781 $cbord['border_details']['mbw']['BL'] = max($cbord['border_details']['mbw']['BL'], $cbord['border_details']['L']['w']);
25782 $cbord['border_details']['mbw']['BR'] = max($cbord['border_details']['mbw']['BR'], $cbord['border_details']['R']['w']);
25783 $cbord['border_details']['mbw']['RT'] = max($cbord['border_details']['mbw']['RT'], $cbord['border_details']['T']['w']);
25784 $cbord['border_details']['mbw']['RB'] = max($cbord['border_details']['mbw']['RB'], $cbord['border_details']['B']['w']);
25785 $cbord['border_details']['mbw']['TL'] = max($cbord['border_details']['mbw']['TL'], $cbord['border_details']['L']['w']);
25786 $cbord['border_details']['mbw']['TR'] = max($cbord['border_details']['mbw']['TR'], $cbord['border_details']['R']['w']);
25787 $cbord['border_details']['mbw']['LT'] = max($cbord['border_details']['mbw']['LT'], $cbord['border_details']['T']['w']);
25788 $cbord['border_details']['mbw']['LB'] = max($cbord['border_details']['mbw']['LB'], $cbord['border_details']['B']['w']);
25789 if (($i+$crowsp) < $numrows && isset($cells[$i+$crowsp][$j])) { // Has Bottom adjoining cell
25790 if ($this->packTableData) {
25791 // mPDF 5.3.79
25792 if ($this->cacheTables) {
25793 $adjc = $this->_uncacheCell($table['cells'][$i+$crowsp][$j], '', $fh);
25794 }
25795 else { $adjc = $cells[$i+$crowsp][$j]; }
25796 $celladj = $this->_unpackCellBorder($adjc['borderbin']);
25797 }
25798 else { $celladj =& $cells[$i+$crowsp][$j]; }
25799 $cbord['border_details']['mbw']['BL'] = max($cbord['border_details']['mbw']['BL'], $celladj['border_details']['L']['w'], $celladj['border_details']['mbw']['TL']);
25800 $cbord['border_details']['mbw']['BR'] = max($cbord['border_details']['mbw']['BR'], $celladj['border_details']['R']['w'], $celladj['border_details']['mbw']['TR']);
25801 $cbord['border_details']['mbw']['LB'] = max($cbord['border_details']['mbw']['LB'], $celladj['border_details']['mbw']['LT']);
25802 $cbord['border_details']['mbw']['RB'] = max($cbord['border_details']['mbw']['RB'], $celladj['border_details']['mbw']['RT']);
25803 unset($celladj);
25804 }
25805 if (($j+$ccolsp) < $numcols && isset($cells[$i][$j+$ccolsp])) { // Has Right adjoining cell
25806 if ($this->packTableData) {
25807 // mPDF 5.3.79
25808 if ($this->cacheTables) {
25809 $adjc = $this->_uncacheCell($table['cells'][$i][$j+$ccolsp], '', $fh);
25810 }
25811 else { $adjc = $cells[$i][$j+$ccolsp]; }
25812 $celladj = $this->_unpackCellBorder($adjc['borderbin']);
25813 }
25814 else { $celladj =& $cells[$i][$j+$ccolsp]; }
25815 $cbord['border_details']['mbw']['RT'] = max($cbord['border_details']['mbw']['RT'], $celladj['border_details']['T']['w'], $celladj['border_details']['mbw']['LT']);
25816 $cbord['border_details']['mbw']['RB'] = max($cbord['border_details']['mbw']['RB'], $celladj['border_details']['B']['w'], $celladj['border_details']['mbw']['LB']);
25817 $cbord['border_details']['mbw']['TR'] = max($cbord['border_details']['mbw']['TR'], $celladj['border_details']['mbw']['TL']);
25818 $cbord['border_details']['mbw']['BR'] = max($cbord['border_details']['mbw']['BR'], $celladj['border_details']['mbw']['BL']);
25819 unset($celladj);
25820 }
25821
25822 if ($i > 0 && isset($cells[$i-1][$j]) && (($this->packTableData && $cells[$i-1][$j]['borderbin']) || $cells[$i-1][$j]['border'])) { // Has Top adjoining cell
25823 if ($this->packTableData) {
25824 // mPDF 5.3.79
25825 if ($this->cacheTables) {
25826 $adjc = $this->_uncacheCell($table['cells'][$i-1][$j], '', $fh);
25827 }
25828 else { $adjc = $cells[$i-1][$j]; }
25829 $celladj = $this->_unpackCellBorder($adjc['borderbin']);
25830 }
25831 else { $celladj =& $cells[$i-1][$j]; }
25832 $cbord['border_details']['mbw']['TL'] = max($cbord['border_details']['mbw']['TL'], $celladj['border_details']['L']['w'], $celladj['border_details']['mbw']['BL']);
25833 $cbord['border_details']['mbw']['TR'] = max($cbord['border_details']['mbw']['TR'], $celladj['border_details']['R']['w'], $celladj['border_details']['mbw']['BR']);
25834 $cbord['border_details']['mbw']['LT'] = max($cbord['border_details']['mbw']['LT'], $celladj['border_details']['mbw']['LB']);
25835 $cbord['border_details']['mbw']['RT'] = max($cbord['border_details']['mbw']['RT'], $celladj['border_details']['mbw']['RB']);
25836
25837 if ($celladj['border_details']['mbw']['BL']) {
25838 $celladj['border_details']['mbw']['BL'] = max($cbord['border_details']['mbw']['TL'], $celladj['border_details']['mbw']['BL']);
25839 }
25840 if ($celladj['border_details']['mbw']['BR'] ) {
25841 $celladj['border_details']['mbw']['BR'] = max($celladj['border_details']['mbw']['BR'], $cbord['border_details']['mbw']['TR']);
25842 }
25843 if ($this->packTableData) { $cells[$i-1][$j]['borderbin'] = $this->_packCellBorder($celladj); }
25844 unset($celladj);
25845 }
25846 if ($j > 0 && isset($cells[$i][$j-1]) && (($this->packTableData && $cells[$i][$j-1]['borderbin']) || $cells[$i][$j-1]['border'])) { // Has Left adjoining cell
25847 if ($this->packTableData) {
25848 // mPDF 5.3.79
25849 if ($this->cacheTables) {
25850 $adjc = $this->_uncacheCell($table['cells'][$i][$j-1], '', $fh);
25851 }
25852 else { $adjc = $cells[$i][$j-1]; }
25853 $celladj = $this->_unpackCellBorder($adjc['borderbin']);
25854 }
25855 else { $celladj =& $cells[$i][$j-1]; }
25856 $cbord['border_details']['mbw']['LT'] = max($cbord['border_details']['mbw']['LT'], $celladj['border_details']['T']['w'], $celladj['border_details']['mbw']['RT']);
25857 $cbord['border_details']['mbw']['LB'] = max($cbord['border_details']['mbw']['LB'], $celladj['border_details']['B']['w'], $celladj['border_details']['mbw']['RB']);
25858 $cbord['border_details']['mbw']['BL'] = max($cbord['border_details']['mbw']['BL'], $celladj['border_details']['mbw']['BR']);
25859 $cbord['border_details']['mbw']['TL'] = max($cbord['border_details']['mbw']['TL'], $celladj['border_details']['mbw']['TR']);
25860
25861 if ($celladj['border_details']['mbw']['RT']) {
25862 $celladj['border_details']['mbw']['RT'] = max($celladj['border_details']['mbw']['RT'], $cbord['border_details']['mbw']['LT']);
25863 }
25864 if ($celladj['border_details']['mbw']['RB']) {
25865 $celladj['border_details']['mbw']['RB'] = max($celladj['border_details']['mbw']['RB'], $cbord['border_details']['mbw']['LB']);
25866 }
25867 if ($this->packTableData) { $cells[$i][$j-1]['borderbin'] = $this->_packCellBorder($celladj); }
25868 unset($celladj);
25869 }
25870
25871
25872 // Update maximum cell border width at LRTB edges of table - used for overall table width
25873 if ($j == 0 && $cbord['border_details']['L']['w']) {
25874 $table['max_cell_border_width']['L'] = max($table['max_cell_border_width']['L'],$cbord['border_details']['L']['w']);
25875 }
25876 if (($j == ($numcols-1) || ($j+$ccolsp) == $numcols ) && $cbord['border_details']['R']['w']) {
25877 $table['max_cell_border_width']['R'] = max($table['max_cell_border_width']['R'],$cbord['border_details']['R']['w']);
25878 }
25879 if ($i == 0 && $cbord['border_details']['T']['w']) {
25880 $table['max_cell_border_width']['T'] = max($table['max_cell_border_width']['T'],$cbord['border_details']['T']['w']);
25881 }
25882 if (($i == ($numrows-1) || ($i+$crowsp) == $numrows ) && $cbord['border_details']['B']['w']) {
25883 $table['max_cell_border_width']['B'] = max($table['max_cell_border_width']['B'],$cbord['border_details']['B']['w']);
25884 }
25885 }
25886 /*-- END TABLES-ADVANCED-BORDERS --*/
25887
25888 if ($this->packTableData) { $cell['borderbin'] = $this->_packCellBorder($cbord); }
25889
25890 // mPDF 5.3.79
25891 if ($this->cacheTables) {
25892 $this->_cacheUpdateBorder($cell, $fh, $table['cells'][$i][$j]);
25893 }
25894 unset($cbord );
25895 unset($cell );
25896 }
25897 }
25898 }
25899 // mPDF 5.3.79
25900 if ($this->cacheTables) { fclose($fh); }
25901 unset($cell );
25902 }
25903 // END FIX BORDERS ************************************************************************************
25904
25905
25906 function _reverseTableDir(&$table) {
25907 // mPDF 5.3.79
25908 if ($this->cacheTables) { $fh = fopen($table['cache'], "r+b"); }
25909 $cells = &$table['cells'];
25910 $numcols = $table['nc'];
25911 $numrows = $table['nr'];
25912 for( $i = 0 ; $i < $numrows ; $i++ ) { //Rows
25913 $row = array();
25914 for( $j = ($numcols-1) ; $j >= 0 ; $j-- ) { //Columns
25915 if (isset($cells[$i][$j]) && $cells[$i][$j]) {
25916 // mPDF 5.3.79
25917 if ($this->cacheTables) {
25918 $cell = $this->_uncacheCell($table['cells'][$i][$j], '', $fh);
25919 }
25920 else
25921 $cell = &$cells[$i][$j];
25922 $col = $numcols - $j - 1;
25923 if (isset($cell['colspan']) && $cell['colspan'] > 1) { $col -= ($cell['colspan']-1); }
25924 // Nested content
25925 for ($n=0; $n < count($cell['textbuffer']); $n++) {
25926 $t = $cell['textbuffer'][$n][0];
25927 if (substr($t,0,19) == "\xbb\xa4\xactype=nestedtable") { // mPDF 5.3.79
25928 $objattr = $this->_getObjAttr($t);
25929 $objattr['col'] = $col;
25930 $cell['textbuffer'][$n][0] = "\xbb\xa4\xactype=nestedtable,objattr=".serialize($objattr)."\xbb\xa4\xac";
25931 $this->table[($this->tableLevel+1)][$objattr['nestedcontent']]['nestedpos'][1] = $col;
25932 // mPDF 5.3.79
25933 if ($this->cacheTables) {
25934 $this->_cacheUpdateTxB($cell, $fh, $table['cells'][$i][$j]);
25935 }
25936 }
25937 }
25938 $row[$col] = $cells[$i][$j];
25939 unset($cell); // mPDF 5.3.79
25940 }
25941 }
25942 for($f=0; $f < $numcols; $f++) {
25943 if (!isset($row[$f])) { $row[$f] = 0; } // mPDF 5.3.79
25944 }
25945 $table['cells'][$i] = $row;
25946 }
25947 // mPDF 5.3.79
25948 if ($this->cacheTables) { fclose($fh); }
25949 }
25950
25951
25952 function _tableWrite(&$table, $split=false, $startrow=0, $startcol=0, $splitpg=0, $rety = 0){ // mPDF 5.3.36
25953 $level = $table['level'];
25954 $levelid = $table['levelid'];
25955
25956 $cells = &$table['cells'];
25957 $numcols = $table['nc'];
25958 $numrows = $table['nr'];
25959
25960 if ($this->ColActive && $level==1) { $this->breakpoints[$this->CurrCol][] = $this->y; } // *COLUMNS*
25961
25962 if (!$split || ($startrow==0 && $splitpg==0) || $startrow>0){ // mPDF 5.3.36
25963 // TABLE TOP MARGIN
25964 if ($table['margin']['T']) {
25965 if (!$this->table_rotate && $level==1) {
25966 $this->DivLn($table['margin']['T'],$this->blklvl,true,1); // collapsible
25967 }
25968 else {
25969 $this->y += ($table['margin']['T']);
25970 }
25971 }
25972 // Advance down page by half width of top border
25973 if ($table['borders_separate']) {
25974 // mPDF 5.3.36
25975 if ($startrow>0 && (!isset($table['is_thead']) || count($table['is_thead'])==0))
25976 $adv = $table['border_spacing_V']/2;
25977 else
25978 $adv = $table['padding']['T'] + $table['border_details']['T']['w'] + $table['border_spacing_V']/2;
25979 }
25980 else {
25981 $adv = $table['max_cell_border_width']['T']/2;
25982 }
25983 if (!$this->table_rotate && $level==1) { $this->DivLn($adv); }
25984 else { $this->y += $adv; }
25985 } // mPDF 5.3.36
25986
25987 if ($level==1) {
25988 $this->x = $this->lMargin + $this->blk[$this->blklvl]['outer_left_margin'] + $this->blk[$this->blklvl]['padding_left'] + $this->blk[$this->blklvl]['border_left']['w'];
25989 $x0 = $this->x;
25990 $y0 = $this->y;
25991 $right = $x0 + $this->blk[$this->blklvl]['inner_width'];
25992 $outerfilled = $this->y; // Keep track of how far down the outer DIV bgcolor is painted (NB rowspans)
25993 $this->outerfilled = $this->y;
25994 $this->colsums = array(); // mPDF 5.3.92
25995 }
25996 else {
25997 $x0 = $this->x;
25998 $y0 = $this->y;
25999 $right = $x0 + $table['w'];
26000 }
26001
26002 if ($this->table_rotate) {
26003 $temppgwidth = $this->tbrot_maxw;
26004 $this->PageBreakTrigger = $pagetrigger = $y0 + ($this->blk[$this->blklvl]['inner_width']);
26005 if ($level==1) {
26006 $this->tbrot_y0 = $this->y - $adv - $table['margin']['T'] ;
26007 $this->tbrot_x0 = $this->x;
26008 $this->tbrot_w = $table['w'];
26009 if ($table['borders_separate']) { $this->tbrot_h = $table['margin']['T'] + $table['padding']['T'] + $table['border_details']['T']['w'] + $table['border_spacing_V']/2; }
26010 else { $this->tbrot_h = $table['margin']['T'] + $table['padding']['T'] + $table['max_cell_border_width']['T']; }
26011 }
26012 }
26013 else {
26014 $this->PageBreakTrigger = $pagetrigger = ($this->h - $this->bMargin);
26015 if ($level==1) {
26016 $temppgwidth = $this->blk[$this->blklvl]['inner_width'];
26017 if (isset($table['a']) and ($table['w'] < $this->blk[$this->blklvl]['inner_width'])) {
26018 if ($table['a']=='C') { $x0 += ((($right-$x0) - $table['w'])/2); }
26019 else if ($table['a']=='R') { $x0 = $right - $table['w']; }
26020 }
26021 }
26022 else {
26023 $temppgwidth = $table['w'];
26024 }
26025 }
26026 if(!isset($table['overflow'])) { $table['overflow'] = null; }
26027 if ($table['overflow']=='hidden' && $level==1 && !$this->table_rotate && !$this->ColActive) {
26028 //Bounding rectangle to clip
26029 $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);
26030 $this->_out($this->tableClipPath);
26031 }
26032 else { $this->tableClipPath = ''; }
26033
26034
26035 if ($table['borders_separate']) { $indent = $table['margin']['L'] + $table['border_details']['L']['w'] + $table['padding']['L'] + $table['border_spacing_H']/2; }
26036 else { $indent = $table['margin']['L'] + $table['max_cell_border_width']['L']/2; }
26037 $x0 += $indent;
26038
26039 $returny = 0;
26040 $lastCol = 0; // mPDF 5.3.36
26041 $tableheader = array();
26042 $tablefooter = array();
26043 $tableheaderrowheight = 0; // mPDF 5.3.36
26044 $tablefooterrowheight = 0;
26045 $footery = 0;
26046
26047 // mPD 3.0 Set the Page & Column where table starts
26048 if (($this->mirrorMargins) && (($this->page)%2==0)) { // EVEN
26049 $tablestartpage = 'EVEN';
26050 }
26051 else if (($this->mirrorMargins) && (($this->page)%2==1)) { // ODD
26052 $tablestartpage = 'ODD';
26053 }
26054 else { $tablestartpage = ''; }
26055 if ($this->ColActive) { $tablestartcolumn = $this->CurrCol; }
26056 else { $tablestartcolumn = ''; }
26057
26058 // mPDF 5.3.79
26059 if ($this->cacheTables) { $fh = fopen($table['cache'], "r+b"); }
26060 else { $fh = null; }
26061
26062 $y = $h = 0;
26063 for( $i = 0; $i < $numrows ; $i++ ) { //Rows
26064 if ($this->progressBar) { $this->UpdateProgressBar(7,intval(30 + ($i*40/$numrows)),' '); } // *PROGRESS-BAR*
26065 if (isset($table['is_tfoot'][$i]) && $table['is_tfoot'][$i] && $level==1) {
26066 $tablefooterrowheight += $table['hr'][$i];
26067 // mPDF 5.3.36
26068 $tablefooter[$i][0]['trbackground-images'] = $table['trbackground-images'][$i];
26069 $tablefooter[$i][0]['trgradients'] = $table['trgradients'][$i];
26070 $tablefooter[$i][0]['trbgcolor'] = $table['bgcolor'][$i];
26071 for( $j = $startcol ; $j < $numcols ; $j++ ) { //Columns // mPDF 5.3.36
26072 if (isset($cells[$i][$j]) && $cells[$i][$j]) {
26073 // mPDF 5.3.79
26074 if ($this->cacheTables) {
26075 $cell = $this->_uncacheCell($table['cells'][$i][$j], '', $fh);
26076 }
26077 else
26078 $cell = &$cells[$i][$j];
26079 // mPDF 5.3.36
26080 if ($split) {
26081 if ($table['colPg'][$j] != $splitpg) { continue; }
26082 list($x,$w) = $this->_splitTableGetWidth($table, $i, $j, $fh);
26083 $js = $j - $startcol;
26084 }
26085 else {
26086 list($x,$w) = $this->_tableGetWidth($table, $i, $j, $fh);
26087 $js = $j;
26088 }
26089
26090 list($y,$h) = $this->_tableGetHeight($table, $i, $j, $fh);
26091 $x += $x0;
26092 $y += $y0;
26093 //Get info of tfoot ==>> table footer
26094 $tablefooter[$i][$js]['x'] = $x;
26095 $tablefooter[$i][$js]['y'] = $y;
26096 $tablefooter[$i][$js]['h'] = $h;
26097 $tablefooter[$i][$js]['w'] = $w;
26098 if (isset($cell['textbuffer'])) { $tablefooter[$i][$js]['textbuffer'] = $cell['textbuffer']; }
26099 else { $tablefooter[$i][$js]['textbuffer'] = ''; }
26100 $tablefooter[$i][$js]['a'] = $cell['a'];
26101 $tablefooter[$i][$js]['R'] = $cell['R'];
26102 $tablefooter[$i][$js]['va'] = $cell['va'];
26103 $tablefooter[$i][$js]['mih'] = $cell['mih'];
26104 $tablefooter[$i][$js]['gradient'] = $cell['gradient']; // *BACKGROUNDS*
26105 $tablefooter[$i][$js]['background-image'] = $cell['background-image']; // *BACKGROUNDS*
26106 //CELL FILL BGCOLOR
26107 if (!$this->simpleTables){
26108 if ($this->packTableData) {
26109 $c = $this->_unpackCellBorder($cell['borderbin']);
26110 $tablefooter[$i][$js]['border'] = $c['border'];
26111 $tablefooter[$i][$js]['border_details'] = $c['border_details'];
26112 }
26113 else {
26114 $tablefooter[$i][$js]['border'] = $cell['border'];
26115 $tablefooter[$i][$js]['border_details'] = $cell['border_details'];
26116 }
26117 }
26118 else if ($this->simpleTables){
26119 $tablefooter[$i][$js]['border'] = $table['simple']['border'];
26120 $tablefooter[$i][$js]['border_details'] = $table['simple']['border_details'];
26121 }
26122 $tablefooter[$i][$js]['bgcolor'] = $cell['bgcolor'];
26123 $tablefooter[$i][$js]['padding'] = $cell['padding'];
26124 $tablefooter[$i][$js]['rowspan'] = $cell['rowspan'];
26125 $tablefooter[$i][$js]['colspan'] = $cell['colspan'];
26126 }
26127 }
26128 }
26129 }
26130
26131 if ($level==1) { $this->_out('___TABLE___BACKGROUNDS'.date('jY')); }
26132 $tableheaderadj = 0;
26133 $tablefooteradj = 0;
26134
26135 $tablestartpageno = $this->page;
26136
26137 //Draw Table Contents and Borders
26138 for( $i = 0; $i < $numrows ; $i++ ) { //Rows
26139 // mPDF 5.3.36
26140 if ($split && $startrow > 0) {
26141 $thnr = (isset($table['is_thead']) ? count($table['is_thead']) : 0);
26142 if ($i >= $thnr && $i < $startrow) { continue; }
26143 if ($i == $startrow){ $returny = $rety - $tableheaderrowheight; }
26144 }
26145
26146 // Get Maximum row/cell height in row - including rowspan>1 + 1 overlapping
26147 // mPDF 5.3.A7
26148 $maxrowheight = $this->_tableGetMaxRowHeight($table, $i, $fh); // mPDF 5.3.6
26149
26150 $skippage = false;
26151 $newpagestarted = false;
26152 for( $j = $startcol ; $j < $numcols ; $j++ ) { //Columns // mPDF 5.3.36
26153 // mPDF 5.3.36
26154 if ($split) {
26155 if ($table['colPg'][$j] > $splitpg) { break; }
26156 $lastCol = $j;
26157 }
26158 if (isset($cells[$i][$j]) && $cells[$i][$j]) {
26159 // mPDF 5.3.79
26160 if ($this->cacheTables) {
26161 $cell = $this->_uncacheCell($table['cells'][$i][$j], '', $fh);
26162 }
26163 else
26164 $cell = &$cells[$i][$j];
26165 // mPDF 5.3.36
26166 if ($split) {
26167 $lastCol = $j + (isset($cell['colspan']) ? ($cell['colspan']-1) : 0) ;
26168 list($x,$w) = $this->_splitTableGetWidth($table, $i, $j, $fh);
26169 }
26170 else { list($x,$w) = $this->_tableGetWidth($table, $i, $j, $fh); }
26171
26172 list($y,$h) = $this->_tableGetHeight($table, $i, $j, $fh);
26173 $x += $x0;
26174 $y += $y0;
26175 $y -= $returny;
26176
26177 if ($table['borders_separate']) {
26178 if (!empty($tablefooter) || $i == ($numrows-1) || (isset($cell['rowspan']) && ($i+$cell['rowspan']) == $numrows) || (!isset($cell['rowspan']) && ($i+1) == $numrows) ) {
26179 $extra = $table['padding']['B'] + $table['border_details']['B']['w'] + $table['border_spacing_V']/2;
26180 //$extra = $table['margin']['B'] + $table['padding']['B'] + $table['border_details']['B']['w'] + $table['border_spacing_V']/2;
26181 }
26182 else {
26183 $extra = $table['border_spacing_V']/2;
26184 }
26185 }
26186 else { $extra = $table['max_cell_border_width']['B']/2; }
26187
26188 // mPDF 5.3.36
26189 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 ) { // mPDF 5.3.62 // mPDF 5.3.76
26190
26191 if (!$skippage) {
26192
26193 // mPDF 5.3.36
26194 $finalSpread = true;
26195 $firstSpread = true;
26196 if ($split) {
26197 for($t=$startcol; $t<$numcols; $t++) {
26198 // Are there more columns to print on a next page?
26199 if ($table['colPg'][$t] > $splitpg) {
26200 $finalSpread = false;
26201 break;
26202 }
26203 }
26204 if ($startcol>0) { $firstSpread = false; }
26205 }
26206
26207 if (($this->keepColumns || !$this->ColActive) && !empty($tablefooter) && $i > 0 ) {
26208 $this->y = $y;
26209 $ya = $this->y;
26210 $this->TableHeaderFooter($tablefooter,$tablestartpage,$tablestartcolumn,'F',$level, $firstSpread, $finalSpread); // mPDF 5.3.36
26211 if ($this->table_rotate) {
26212 $this->tbrot_h += $this->y - $ya ;
26213 }
26214 $tablefooteradj = $this->y - $ya ;
26215 }
26216 $y -= $y0;
26217 $returny += $y;
26218
26219 $oldcolumn = $this->CurrCol;
26220 if ($this->AcceptPageBreak()) {
26221 $newpagestarted = true;
26222 $this->y = $y + $y0;
26223
26224 // Move down to account for border-spacing or
26225 // extra half border width in case page breaks in middle
26226 if($i>0 && !$this->table_rotate && $level==1 && !$this->ColActive) {
26227 if ($table['borders_separate']) {
26228 $adv = $table['border_spacing_V']/2;
26229 // If table footer
26230 if (($this->keepColumns || !$this->ColActive) && !empty($tablefooter) && $i > 0 ) {
26231 $adv += ($table['padding']['B'] + $table['border_details']['B']['w']);
26232 }
26233 }
26234 else {
26235 $maxbwtop = 0;
26236 $maxbwbottom = 0;
26237 if (!$this->simpleTables){
26238 if (!empty($tablefooter)) { $maxbwbottom = $table['max_cell_border_width']['B']; }
26239 else {
26240 $brow = $i-1;
26241 for( $ctj = 0 ; $ctj < $numcols ; $ctj++ ) {
26242 if (isset($cells[$brow][$ctj]) && $cells[$brow][$ctj]) {
26243 // mPDF 5.3.79
26244 if ($this->cacheTables) {
26245 $cadj = $this->_uncacheCell($table['cells'][$brow][$ctj], '', $fh);
26246 list($bt,$br,$bb,$bl) = $this->_getBorderWidths($cadj['borderbin']);
26247 }
26248 else if ($this->packTableData) {
26249 list($bt,$br,$bb,$bl) = $this->_getBorderWidths($cells[$brow][$ctj]['borderbin']);
26250 }
26251 else {
26252 $bb = $cells[$brow][$ctj]['border_details']['B']['w'];
26253 }
26254 $maxbwbottom = max($maxbwbottom , $bb);
26255 }
26256 }
26257 }
26258 if (!empty($tableheader)) { $maxbwtop = $table['max_cell_border_width']['T']; }
26259 else {
26260 $trow = $i-1;
26261 for( $ctj = 0 ; $ctj < $numcols ; $ctj++ ) {
26262 if (isset($cells[$trow][$ctj]) && $cells[$trow][$ctj]) {
26263 // mPDF 5.3.79
26264 if ($this->cacheTables) {
26265 $cadj = $this->_uncacheCell($table['cells'][$trow][$ctj], '', $fh);
26266 list($bt,$br,$bb,$bl) = $this->_getBorderWidths($cadj['borderbin']);
26267 }
26268 else if ($this->packTableData) {
26269 list($bt,$br,$bb,$bl) = $this->_getBorderWidths($cells[$trow][$ctj]['borderbin']);
26270 }
26271 else {
26272 $bt = $cells[$trow][$ctj]['border_details']['T']['w'];
26273 }
26274 $maxbwtop = max($maxbwtop , $bt);
26275 }
26276 }
26277 }
26278 }
26279 else if ($this->simpleTables){
26280 $maxbwtop = $table['simple']['border_details']['T']['w'];
26281 $maxbwbottom = $table['simple']['border_details']['B']['w'];
26282 }
26283 $adv = $maxbwbottom /2;
26284 }
26285 $this->y += $adv;
26286 }
26287
26288 // Rotated table split over pages - needs this->y for borders/backgrounds
26289 if($i>0 && $this->table_rotate && $level==1) {
26290 // $this->y = $y0 + $this->tbrot_w; // mPDF 5.3.62
26291 }
26292
26293 if ($this->tableClipPath ) { $this->_out("Q"); }
26294
26295 $bx = $x0;
26296 $by = $y0;
26297
26298 if ($table['borders_separate']) {
26299 $bx -= ($table['padding']['L'] + $table['border_details']['L']['w'] + $table['border_spacing_H']/2);
26300 if ($tablestartpageno != $this->page) { // IF already broken across a previous pagebreak
26301 $by += $table['max_cell_border_width']['T']/2;
26302 if (empty($tableheader)) { $by -= ($table['border_spacing_V']/2); }
26303 }
26304 else {
26305 $by -= ($table['padding']['T'] + $table['border_details']['T']['w'] + $table['border_spacing_V']/2);
26306 }
26307 }
26308
26309 else if ($tablestartpageno != $this->page && !empty($tableheader)) { $by += $maxbwtop /2; }
26310
26311 $by -= $tableheaderadj;
26312 $bh = $this->y - $by + $tablefooteradj;
26313 if (!$table['borders_separate']) { $bh -= $adv ; }
26314 // mPDF 5.3.36
26315 if ($split) {
26316 $bw = 0;
26317 for($t=$startcol; $t<$numcols; $t++) {
26318 if ($table['colPg'][$t] == $splitpg) { $bw += $table['wc'][$t]; }
26319 if ($table['colPg'][$t] > $splitpg) { break; }
26320 }
26321 if ($table['borders_separate']) {
26322 if ($firstSpread) {
26323 $bw += $table['padding']['L'] + $table['border_details']['L']['w'] + $table['border_spacing_H'];
26324 }
26325 else {
26326 $bx += ($table['padding']['L'] + $table['border_details']['L']['w']);
26327 $bw += $table['border_spacing_H'];
26328 }
26329 if ($finalSpread) {
26330 $bw += $table['padding']['R'] + $table['border_details']['R']['w']/2 + $table['border_spacing_H'];
26331 }
26332 }
26333 }
26334 else {
26335 $bw = $table['w'] - ($table['max_cell_border_width']['L']/2) - ($table['max_cell_border_width']['R']/2) - $table['margin']['L'] - $table['margin']['R'];
26336 }
26337
26338
26339
26340 if (!$this->ColActive && ($i > 0 || $j > 0)) { // mPDF 5.3.36
26341 if (isset($table['bgcolor'][-1])) {
26342 $color = $this->ConvertColor($table['bgcolor'][-1]);
26343 if ($color) {
26344 if (!$table['borders_separate']) { $bh -= $table['max_cell_border_width']['B']/2; }
26345 $this->tableBackgrounds[$level*9][] = array('gradient'=>false, 'x'=>$bx, 'y'=>$by, 'w'=>$bw, 'h'=>$bh, 'col'=>$color);
26346 }
26347 }
26348
26349 /*-- BACKGROUNDS --*/
26350 if (isset($table['gradient'])) {
26351 $g = $this->grad->parseBackgroundGradient($table['gradient']);
26352 if ($g) {
26353 $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'=>'');
26354 }
26355 }
26356
26357 if (isset($table['background-image'])) {
26358 if ($table['background-image']['gradient'] && preg_match('/(-moz-)*(repeating-)*(linear|radial)-gradient/', $table['background-image']['gradient'] )) {
26359 $g = $this->grad->parseMozGradient( $table['background-image']['gradient'] );
26360 if ($g) {
26361 $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'=>'');
26362 }
26363 }
26364 else {
26365 $image_id = $table['background-image']['image_id'];
26366 $orig_w = $table['background-image']['orig_w'];
26367 $orig_h = $table['background-image']['orig_h'];
26368 $x_pos = $table['background-image']['x_pos'];
26369 $y_pos = $table['background-image']['y_pos'];
26370 $x_repeat = $table['background-image']['x_repeat'];
26371 $y_repeat = $table['background-image']['y_repeat'];
26372 $resize = $table['background-image']['resize'];
26373 $opacity = $table['background-image']['opacity'];
26374 $itype = $table['background-image']['itype'];
26375 $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);
26376 }
26377 }
26378 /*-- END BACKGROUNDS --*/
26379 }
26380
26381 // $this->AcceptPageBreak() has moved tablebuffer to $this->pages content
26382 if ($this->tableBackgrounds) {
26383 $s = $this->PrintTableBackgrounds();
26384 if ($this->bufferoutput) {
26385 $this->headerbuffer = preg_replace('/(___TABLE___BACKGROUNDS'.date('jY').')/', '\\1'."\n".$s."\n", $this->headerbuffer);
26386 $this->headerbuffer = preg_replace('/(___TABLE___BACKGROUNDS'.date('jY').')/', " ", $this->headerbuffer );
26387 }
26388 else {
26389 $this->pages[$this->page] = preg_replace('/(___TABLE___BACKGROUNDS'.date('jY').')/', '\\1'."\n".$s."\n", $this->pages[$this->page]);
26390 $this->pages[$this->page] = preg_replace('/(___TABLE___BACKGROUNDS'.date('jY').')/', " ", $this->pages[$this->page]);
26391 }
26392 $this->tableBackgrounds = array();
26393 }
26394
26395 // mPDF 5.3.36
26396 if ($split) {
26397 if ($i == 0 && $j == 0) { $y0 = -1; }
26398 else if ($finalSpread) {
26399 $splitpg = 0;
26400 $startcol = 0;
26401 $startrow = $i;
26402 }
26403 else {
26404 $splitpg++;
26405 $startcol = $t;
26406 $returny -= $y;
26407 }
26408 return array(false, $startrow, $startcol, $splitpg, $returny, $y0);
26409 }
26410
26411 $this->AddPage($this->CurOrientation);
26412
26413 $this->_out('___TABLE___BACKGROUNDS'.date('jY'));
26414
26415
26416 if ($this->tableClipPath ) { $this->_out($this->tableClipPath); }
26417
26418 // Added to correct for OddEven Margins
26419 $x=$x +$this->MarginCorrection;
26420 $x0=$x0 +$this->MarginCorrection;
26421
26422
26423 // Move down to account for half of top border-spacing or
26424 // extra half border width in case page was broken in middle
26425 if($i>0 && !$this->table_rotate && $level==1 && $table['headernrows']==0) { // mPDF 5.3.62
26426 if ($table['borders_separate']) { $adv = $table['border_spacing_V']/2; }
26427 else {
26428 $maxbwtop = 0;
26429 for( $ctj = 0 ; $ctj < $numcols ; $ctj++ ) {
26430 if (isset($cells[$i][$ctj]) && $cells[$i][$ctj]) {
26431 if (!$this->simpleTables){
26432 // mPDF 5.3.79
26433 if ($this->cacheTables) {
26434 $celltj = $this->_uncacheCell($table['cells'][$i][$ctj], '', $fh);
26435 list($bt,$br,$bb,$bl) = $this->_getBorderWidths($celltj['borderbin']);
26436 }
26437 else if ($this->packTableData) {
26438 list($bt,$br,$bb,$bl) = $this->_getBorderWidths($cells[$i][$ctj]['borderbin']);
26439 }
26440 else {
26441 $bt = $cells[$i][$ctj]['border_details']['T']['w'];
26442 }
26443 $maxbwtop = max($maxbwtop, $bt);
26444 }
26445 else if ($this->simpleTables){
26446 $maxbwtop = max($maxbwtop, $table['simple']['border_details']['T']['w']);
26447 }
26448 }
26449 }
26450 $adv = $maxbwtop /2;
26451 }
26452 $this->y += $adv;
26453 }
26454
26455
26456 if ($this->table_rotate) {
26457 $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'];
26458 if ($table['borders_separate']) { $this->tbrot_h = $table['margin']['T'] + $table['padding']['T'] + $table['border_details']['T']['w'] + $table['border_spacing_V']/2; }
26459 else { $this->tbrot_h = $table['margin']['T'] + $table['max_cell_border_width']['T'] ; }
26460 $this->tbrot_y0 = $this->y;
26461 $pagetrigger = $y0 - $tableheaderadj + ($this->blk[$this->blklvl]['inner_width']);
26462 }
26463 else {
26464 $pagetrigger = $this->PageBreakTrigger;
26465 }
26466
26467 if ($this->kwt_saved && $level==1) {
26468 $this->kwt_moved = true;
26469 }
26470
26471
26472 // Disable Table header repeat if Keep Block together
26473 if (!$this->keep_block_together && !empty($tableheader)) { // mPDF 5.3.62
26474 $ya = $this->y;
26475 $this->TableHeaderFooter($tableheader,$tablestartpage,$tablestartcolumn,'H',$level);
26476 if ($this->table_rotate) {
26477 $this->tbrot_h = $this->y - $ya ;
26478 }
26479 $tableheaderadj = $this->y - $ya ;
26480 }
26481
26482 else if ($i==0 && !$this->keep_block_together && !$this->table_rotate && $level==1 && !$this->ColActive) {
26483 // Advance down page
26484 if ($table['borders_separate']) { $adv = $table['border_spacing_V']/2 + $table['border_details']['T']['w'] + $table['padding']['T']; }
26485 else { $adv = $table['max_cell_border_width']['T'] /2 ; }
26486 if ($adv) {
26487 if ($this->table_rotate) {
26488 $this->y += ($adv);
26489 }
26490 else {
26491 $this->DivLn($adv,$this->blklvl,true);
26492 }
26493 }
26494 }
26495
26496 $outerfilled = 0;
26497 $y = $y0 = $this->y;
26498 }
26499
26500 /*-- COLUMNS --*/
26501 // COLS
26502 // COLUMN CHANGE
26503 if ($this->CurrCol != $oldcolumn) {
26504 // Added to correct for Columns
26505 $x += $this->ChangeColumn * ($this->ColWidth+$this->ColGap);
26506 $x0 += $this->ChangeColumn * ($this->ColWidth+$this->ColGap);
26507 if ($this->CurrCol == 0) { // just added a page - possibly with tableheader
26508 $y0 = $this->y; // this->y0 is global used by Columns - $y0 is internal to tablewrite
26509 }
26510 else {
26511 $y0 = $this->y0; // this->y0 is global used by Columns - $y0 is internal to tablewrite
26512 }
26513 $y = $y0;
26514 $outerfilled = 0;
26515 if ($this->CurrCol != 0 && ($this->keepColumns && $this->ColActive) && !empty($tableheader) && $i > 0 ) {
26516 $this->x = $x;
26517 $this->y = $y;
26518 $this->TableHeaderFooter($tableheader,$tablestartpage,$tablestartcolumn,'H',$level);
26519 $y0 = $y=$this->y;
26520 }
26521 }
26522 /*-- END COLUMNS --*/
26523 }
26524 $skippage = true;
26525 }
26526
26527 $this->x = $x;
26528 $this->y = $y;
26529
26530 if ($this->kwt_saved && $level==1) {
26531 $this->printkwtbuffer();
26532 $x0 = $x = $this->x;
26533 $y0 = $y = $this->y;
26534 $this->kwt_moved = false;
26535 $this->kwt_saved = false;
26536 }
26537
26538
26539 // Set the Page & Column where table actually starts
26540 if ($i==0 && $j==0 && $level==1) {
26541 if (($this->mirrorMargins) && (($this->page)%2==0)) { // EVEN
26542 $tablestartpage = 'EVEN';
26543 }
26544 else if (($this->mirrorMargins) && (($this->page)%2==1)) { // ODD
26545 $tablestartpage = 'ODD';
26546 }
26547 else { $tablestartpage = ''; }
26548 $tablestartpageno = $this->page;
26549 if ($this->ColActive) { $tablestartcolumn = $this->CurrCol; } // *COLUMNS*
26550 }
26551
26552
26553 //ALIGN
26554 $align = $cell['a'];
26555
26556
26557 /*-- COLUMNS --*/
26558 // If outside columns, this is done in PaintDivBB
26559 if ($this->ColActive) {
26560 //OUTER FILL BGCOLOR of DIVS
26561 if ($this->blklvl > 0 && ($j==0) && !$this->table_rotate && $level==1) {
26562 $firstblockfill = $this->GetFirstBlockFill();
26563 if ($firstblockfill && $this->blklvl >= $firstblockfill) {
26564 $divh = $maxrowheight;
26565 // Last row
26566 if (isset($cell['rowspan']) && (($i == $numrows-1 && $cell['rowspan']<2) || ($cell['rowspan']>1 && ($i + $cell['rowspan']-1) == $numrows-1))) {
26567 if ($table['borders_separate']) {
26568 $adv = $table['margin']['B'] + $table['padding']['B'] + $table['border_details']['B']['w'] + $table['border_spacing_V']/2;
26569 }
26570 else {
26571 $adv = $table['margin']['B'] + $table['max_cell_border_width']['B']/2;
26572 }
26573 $divh += $adv; //last row: fill bottom half of bottom border (y advanced at end)
26574 }
26575
26576 if (($this->y + $divh) > $outerfilled ) { // if not already painted by previous rowspan
26577 $bak_x = $this->x;
26578 $bak_y = $this->y;
26579 if ($outerfilled > $this->y) {
26580 $divh = ($this->y + $divh) - $outerfilled;
26581 $this->y = $outerfilled;
26582 }
26583
26584 $this->DivLn($divh,-3,false);
26585 $outerfilled = $this->y + $divh;
26586 // Reset current block fill
26587 $bcor = $this->blk[$this->blklvl]['bgcolorarray'];
26588 if ($bcor ) $this->SetFColor($bcor);
26589 $this->x = $bak_x;
26590 $this->y = $bak_y;
26591 }
26592 }
26593 }
26594 }
26595
26596
26597 //TABLE BACKGROUND FILL BGCOLOR - for cellSpacing
26598 if ($this->ColActive) {
26599 if ($table['borders_separate']) {
26600 $fill = isset($table['bgcolor'][-1]) ? $table['bgcolor'][-1] : 0;
26601 if ($fill) {
26602 $color = $this->ConvertColor($fill);
26603 if ($color) {
26604 $xadj = ($table['border_spacing_H']/2);
26605 $yadj = ($table['border_spacing_V']/2);
26606 $wadj = $table['border_spacing_H'];
26607 $hadj = $table['border_spacing_V'];
26608 if ($i == 0) { // Top
26609 $yadj += $table['padding']['T'] + $table['border_details']['T']['w'] ;
26610 $hadj += $table['padding']['T'] + $table['border_details']['T']['w'] ;
26611 }
26612 if ($j == 0) { // Left
26613 $xadj += $table['padding']['L'] + $table['border_details']['L']['w'] ;
26614 $wadj += $table['padding']['L'] + $table['border_details']['L']['w'] ;
26615 }
26616 if ($i == ($numrows-1) || (isset($cell['rowspan']) && ($i+$cell['rowspan']) == $numrows) || (!isset($cell['rowspan']) && ($i+1) == $numrows)) { // Bottom
26617 $hadj += $table['padding']['B'] + $table['border_details']['B']['w'] ;
26618 }
26619 if ($j == ($numcols-1) || (isset($cell['colspan']) && ($j+$cell['colspan']) == $numcols) || (!isset($cell['colspan']) && ($j+1) == $numcols)) { // Right
26620 $wadj += $table['padding']['R'] + $table['border_details']['R']['w'] ;
26621 }
26622 $this->SetFColor($color);
26623 $this->Rect($x - $xadj, $y - $yadj, $w + $wadj, $h + $hadj, 'F');
26624 }
26625 }
26626 }
26627 }
26628 /*-- END COLUMNS --*/
26629
26630 if ($table['empty_cells']!='hide' || !empty($cell['textbuffer']) || (isset($cell['nestedcontent']) && $cell['nestedcontent']) || !$table['borders_separate'] ) { $paintcell = true; }
26631 else { $paintcell = false; }
26632
26633 //Set Borders
26634 $bord = 0;
26635 $bord_det = array();
26636
26637 if (!$this->simpleTables){
26638 if ($this->packTableData) {
26639 if ($cell['borderbin']) {
26640 $c = $this->_unpackCellBorder($cell['borderbin']);
26641 $bord = $c['border'];
26642 $bord_det = $c['border_details'];
26643 }
26644 }
26645 else if ($cell['border']) {
26646 $bord = $cell['border'];
26647 $bord_det = $cell['border_details'];
26648 }
26649 }
26650 else if ($this->simpleTables){
26651 if ($table['simple']['border']) {
26652 $bord = $table['simple']['border'];
26653 $bord_det = $table['simple']['border_details'];
26654 }
26655 }
26656
26657 //TABLE ROW OR CELL FILL BGCOLOR
26658 $fill = 0;
26659 if (isset($cell['bgcolor']) && $cell['bgcolor'] && $cell['bgcolor']!='transparent') {
26660 $fill = $cell['bgcolor'];
26661 $leveladj = 6;
26662 }
26663 else if (isset($table['bgcolor'][$i]) && $table['bgcolor'][$i] && $table['bgcolor'][$i]!='transparent') { // Row color
26664 $fill = $table['bgcolor'][$i];
26665 $leveladj = 3;
26666 }
26667 if ($fill && $paintcell) {
26668 $color = $this->ConvertColor($fill);
26669 if ($color) {
26670 if ($table['borders_separate']) {
26671 if ($this->ColActive) {
26672 $this->SetFColor($color);
26673 $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');
26674 }
26675 else {
26676 $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);
26677 }
26678 }
26679 else {
26680 if ($this->ColActive) {
26681 $this->SetFColor($color);
26682 $this->Rect($x, $y, $w, $h, 'F');
26683 }
26684 else {
26685 $this->tableBackgrounds[$level*9+$leveladj][] = array('gradient'=>false, 'x'=>$x, 'y'=>$y, 'w'=>$w, 'h'=>$h, 'col'=>$color);
26686 }
26687 }
26688 }
26689 }
26690
26691 /*-- BACKGROUNDS --*/
26692 if (isset($cell['gradient']) && $cell['gradient'] && $paintcell){
26693 $g = $this->grad->parseBackgroundGradient($cell['gradient']);
26694 if ($g) {
26695 if ($table['borders_separate']) {
26696 $px = $x+ ($table['border_spacing_H']/2);
26697 $py = $y+ ($table['border_spacing_V']/2);
26698 $pw = $w- $table['border_spacing_H'];
26699 $ph = $h- $table['border_spacing_V'];
26700 }
26701 else {
26702 $px = $x;
26703 $py = $y;
26704 $pw = $w;
26705 $ph = $h;
26706 }
26707 if ($this->ColActive) {
26708 $this->grad->Gradient($px, $py, $pw, $ph, $g['type'], $g['stops'], $g['colorspace'], $g['coords'], $g['extend']);
26709 }
26710 else {
26711 $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'=>'');
26712 }
26713 }
26714 }
26715
26716 if (isset($cell['background-image']) && $paintcell) {
26717 if ($cell['background-image']['gradient'] && preg_match('/(-moz-)*(repeating-)*(linear|radial)-gradient/', $cell['background-image']['gradient'] )) {
26718 $g = $this->grad->parseMozGradient( $cell['background-image']['gradient'] );
26719 if ($g) {
26720 if ($table['borders_separate']) {
26721 $px = $x+ ($table['border_spacing_H']/2);
26722 $py = $y+ ($table['border_spacing_V']/2);
26723 $pw = $w- $table['border_spacing_H'];
26724 $ph = $h- $table['border_spacing_V'];
26725 }
26726 else {
26727 $px = $x;
26728 $py = $y;
26729 $pw = $w;
26730 $ph = $h;
26731 }
26732 if ($this->ColActive) {
26733 $this->grad->Gradient($px, $py, $pw, $ph, $g['type'], $g['stops'], $g['colorspace'], $g['coords'], $g['extend']);
26734 }
26735 else {
26736 $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'=>'');
26737 }
26738 }
26739 }
26740 else if ($cell['background-image']['image_id']) { // Background pattern
26741 $n = count($this->patterns)+1;
26742 if ($table['borders_separate']) {
26743 $px = $x+ ($table['border_spacing_H']/2);
26744 $py = $y+ ($table['border_spacing_V']/2);
26745 $pw = $w- $table['border_spacing_H'];
26746 $ph = $h- $table['border_spacing_V'];
26747 }
26748 else {
26749 $px = $x;
26750 $py = $y;
26751 $pw = $w;
26752 $ph = $h;
26753 }
26754 if ($this->ColActive) {
26755 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']);
26756 $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);
26757 if ($cell['background-image']['opacity']>0 && $cell['background-image']['opacity']<1) { $opac = $this->SetAlpha($cell['background-image']['opacity'],'Normal',true); }
26758 else { $opac = ''; }
26759 $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));
26760 }
26761 else {
26762 $image_id = $cell['background-image']['image_id'];
26763 $orig_w = $cell['background-image']['orig_w'];
26764 $orig_h = $cell['background-image']['orig_h'];
26765 $x_pos = $cell['background-image']['x_pos'];
26766 $y_pos = $cell['background-image']['y_pos'];
26767 $x_repeat = $cell['background-image']['x_repeat'];
26768 $y_repeat = $cell['background-image']['y_repeat'];
26769 $resize = $cell['background-image']['resize'];
26770 $opacity = $cell['background-image']['opacity'];
26771 $itype = $cell['background-image']['itype'];
26772 $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);
26773 }
26774 }
26775 }
26776 /*-- END BACKGROUNDS --*/
26777
26778 if (isset($cell['colspan']) && $cell['colspan']>1) { $ccolsp = $cell['colspan']; }
26779 else { $ccolsp = 1; }
26780 if (isset($cell['rowspan']) && $cell['rowspan']>1) { $crowsp = $cell['rowspan']; }
26781 else { $crowsp = 1; }
26782
26783
26784 // but still need to do this for repeated headers...
26785 if (!$table['borders_separate'] && $this->tabletheadjustfinished && !$this->simpleTables){
26786 if (isset($table['topntail']) && $table['topntail']) {
26787 $bord_det['T'] = $this->border_details($table['topntail']);
26788 $bord_det['T']['w'] /= $this->shrin_k;
26789 $this->setBorder($bord, _BORDER_TOP);
26790 }
26791 if (isset($table['thead-underline']) && $table['thead-underline']) {
26792 $bord_det['T'] = $this->border_details($table['thead-underline']);
26793 $bord_det['T']['w'] /= $this->shrin_k;
26794 $this->setBorder($bord, _BORDER_TOP);
26795 }
26796 }
26797
26798
26799 //Get info of first row ==>> table header
26800 //Use > 1 row if THEAD
26801 if (isset($table['is_thead'][$i]) && $table['is_thead'][$i] && $level==1) { // mPDF 5.3.62
26802 if ($j==0) $tableheaderrowheight += $table['hr'][$i]; // mPDF 5.3.36
26803 $tableheader[$i][0]['trbackground-images'] = (isset($table['trbackground-images'][$i]) ? $table['trbackground-images'][$i] : null);
26804 $tableheader[$i][0]['trgradients'] = (isset($table['trgradients'][$i]) ? $table['trgradients'][$i] : null);
26805 $tableheader[$i][0]['trbgcolor'] = (isset($table['bgcolor'][$i]) ? $table['bgcolor'][$i] : null);
26806 $tableheader[$i][$j]['x'] = $x;
26807 $tableheader[$i][$j]['y'] = $y;
26808 $tableheader[$i][$j]['h'] = $h;
26809 $tableheader[$i][$j]['w'] = $w;
26810 if (isset($cell['textbuffer'])) { $tableheader[$i][$j]['textbuffer'] = $cell['textbuffer']; }
26811 else { $tableheader[$i][$j]['textbuffer'] = ''; }
26812 $tableheader[$i][$j]['a'] = $cell['a'];
26813 $tableheader[$i][$j]['R'] = $cell['R'];
26814
26815 $tableheader[$i][$j]['va'] = $cell['va'];
26816 $tableheader[$i][$j]['mih'] = $cell['mih'];
26817 $tableheader[$i][$j]['gradient'] = (isset($cell['gradient']) ? $cell['gradient'] : null); // *BACKGROUNDS*
26818 $tableheader[$i][$j]['background-image'] = (isset($cell['background-image']) ? $cell['background-image'] : null); // *BACKGROUNDS*
26819 $tableheader[$i][$j]['rowspan'] = (isset($cell['rowspan']) ? $cell['rowspan'] : null);
26820 $tableheader[$i][$j]['colspan'] = (isset($cell['colspan']) ? $cell['colspan'] : null);
26821 $tableheader[$i][$j]['bgcolor'] = $cell['bgcolor'];
26822
26823 if (!$this->simpleTables){
26824 $tableheader[$i][$j]['border'] = $bord;
26825 $tableheader[$i][$j]['border_details'] = $bord_det;
26826 }
26827 else if ($this->simpleTables){
26828 $tableheader[$i][$j]['border'] = $table['simple']['border'];
26829 $tableheader[$i][$j]['border_details'] = $table['simple']['border_details'];
26830 }
26831 $tableheader[$i][$j]['padding'] = $cell['padding'];
26832 }
26833
26834 // CELL BORDER
26835 if ($bord || $bord_det) {
26836 if ($table['borders_separate'] && $paintcell) {
26837 $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']);
26838 }
26839 else if (!$table['borders_separate']) {
26840 $this->_tableRect($x, $y, $w, $h, $bord, $bord_det, true, $table['borders_separate']); // true causes buffer
26841 }
26842
26843 }
26844
26845 //VERTICAL ALIGN
26846 if ($cell['R'] && INTVAL($cell['R']) > 0 && INTVAL($cell['R']) < 90 && isset($cell['va']) && $cell['va']!='B') { $cell['va']='B';}
26847 if (!isset($cell['va']) || $cell['va']=='M') $this->y += ($h-$cell['mih'])/2;
26848 elseif (isset($cell['va']) && $cell['va']=='B') $this->y += $h-$cell['mih'];
26849
26850 // NESTED CONTENT
26851
26852 // TEXT (and nested tables)
26853 $this->divalign=$align;
26854
26855 $this->divwidth=$w;
26856 if (!empty($cell['textbuffer'])) {
26857 if ($level==1) { // mPDF 5.3.92
26858 if (isset($table['is_tfoot'][$i]) && $table['is_tfoot'][$i]) {
26859 if (preg_match('/{colsum([0-9]*)[_]*}/', $cell['textbuffer'][0][0], $m)) {
26860 $rep = sprintf("%01.".intval($m[1])."f", $this->colsums[$j]);
26861 $cell['textbuffer'][0][0] = preg_replace('/{colsum[0-9_]*}/', $rep ,$cell['textbuffer'][0][0]);
26862 }
26863 }
26864 else { $this->colsums[$j] += floatval(preg_replace('/^[^0-9\.\,]*/','',$cell['textbuffer'][0][0])); }
26865 }
26866 $opy = $this->y;
26867 // mPDF ITERATION
26868 if ($this->iterationCounter) {
26869 foreach($cell['textbuffer'] AS $k=>$t) { // mPDF 5.3.78
26870 if (preg_match('/{iteration ([a-zA-Z0-9_]+)}/',$t[0], $m)) {
26871 $vname = '__'.$m[1].'_';
26872 if (!isset($this->$vname)) { $this->$vname = 1; }
26873 else { $this->$vname++; }
26874 $cell['textbuffer'][$k][0] = preg_replace('/{iteration '.$m[1].'}/', $this->$vname, $cell['textbuffer'][$k][0]);
26875 }
26876 }
26877 }
26878
26879
26880 if ($cell['R']) {
26881 $cellPtSize = $cell['textbuffer'][0][11] / $this->shrin_k;
26882 if (!$cellPtSize) { $cellPtSize = $this->default_font_size; }
26883 $cellFontHeight = ($cellPtSize/_MPDFK);
26884 $opx = $this->x;
26885 $angle = INTVAL($cell['R']);
26886 // Only allow 45 to 89 degrees (when bottom-aligned) or exactly 90 or -90
26887 if ($angle > 90) { $angle = 90; }
26888 else if ($angle > 0 && $angle <45) { $angle = 45; }
26889 else if ($angle < 0) { $angle = -90; }
26890 $offset = ((sin(deg2rad($angle))) * 0.37 * $cellFontHeight);
26891 if (isset($cell['a']) && $cell['a']=='R') {
26892 $this->x += ($w) + ($offset) - ($cellFontHeight/3) - ($cell['padding']['R'] + ($table['border_spacing_H']/2));
26893 }
26894 else if (!isset($cell['a']) || $cell['a']=='C') {
26895 $this->x += ($w/2) + ($offset);
26896 }
26897 else {
26898 $this->x += ($offset) + ($cellFontHeight/3)+($cell['padding']['L'] +($table['border_spacing_H']/2));
26899 }
26900 // mPDF 5.3.78
26901 $str = '';
26902 foreach($cell['textbuffer'] AS $t) { $str .= $t[0].' '; }
26903 $str = trim($str);
26904 if (!isset($cell['va']) || $cell['va']=='M') {
26905 $this->y -= ($h-$cell['mih'])/2; //Undo what was added earlier VERTICAL ALIGN
26906 if ($angle > 0) { $this->y += (($h-$cell['mih'])/2) + $cell['padding']['T'] + ($cell['mih']-($cell['padding']['T'] + $cell['padding']['B'])); }
26907 else if ($angle < 0) { $this->y += (($h-$cell['mih'])/2)+ ($cell['padding']['T'] + ($table['border_spacing_V']/2)); }
26908 }
26909 elseif (isset($cell['va']) && $cell['va']=='B') {
26910 $this->y -= $h-$cell['mih']; //Undo what was added earlier VERTICAL ALIGN
26911 if ($angle > 0) { $this->y += $h-($cell['padding']['B'] + ($table['border_spacing_V']/2)); }
26912 else if ($angle < 0) { $this->y += $h-$cell['mih'] + ($cell['padding']['T'] + ($table['border_spacing_V']/2)); }
26913 }
26914 elseif (isset($cell['va']) && $cell['va']=='T') {
26915 if ($angle > 0) { $this->y += $cell['mih']-($cell['padding']['B'] + ($table['border_spacing_V']/2)); }
26916 else if ($angle < 0) { $this->y += ($cell['padding']['T'] + ($table['border_spacing_V']/2)); }
26917 }
26918 $this->Rotate($angle,$this->x,$this->y);
26919 $s_fs = $this->FontSizePt;
26920 $s_f = $this->FontFamily;
26921 $s_st = $this->FontStyle;
26922 // mPDF 5.3.34
26923 if (!empty($cell['textbuffer'][0][3])) { //Font Color
26924 $cor = $cell['textbuffer'][0][3];
26925 $this->SetTColor($cor);
26926 }
26927 // mPDF 5.3.54
26928 $s_str = $this->strike;
26929 $this->strike = $cell['textbuffer'][0][8]; //Strikethrough
26930 $this->SetFont($cell['textbuffer'][0][4],$cell['textbuffer'][0][2],$cellPtSize,true,true);
26931 $this->Text($this->x,$this->y,$str);
26932 $this->Rotate(0);
26933 $this->SetFont($s_f,$s_st,$s_fs,true,true);
26934 $this->SetTColor(0); // mPDF 5.3.34
26935 $this->strike = $s_str; // mPDF 5.3.54
26936 $this->x = $opx;
26937 }
26938 else {
26939
26940 if (!$this->simpleTables){
26941 // mPDF 5.3.76
26942 if ($bord_det) {
26943 $btlw = $bord_det['L']['w'];
26944 $btrw = $bord_det['R']['w'];
26945 $bttw = $bord_det['T']['w'];
26946 }
26947 else {
26948 $btlw = 0;
26949 $btrw = 0;
26950 $bttw = 0;
26951 }
26952 if ($table['borders_separate']) {
26953 $xadj = $btlw + $cell['padding']['L'] +($table['border_spacing_H']/2);
26954 $wadj = $btlw + $btrw + $cell['padding']['L'] +$cell['padding']['R'] + $table['border_spacing_H'];
26955 $yadj = $bttw + $cell['padding']['T'] + ($table['border_spacing_H']/2);
26956 }
26957 else {
26958 $xadj = $btlw/2 + $cell['padding']['L'];
26959 $wadj = ($btlw + $btrw)/2 + $cell['padding']['L'] + $cell['padding']['R'];
26960 $yadj = $bttw/2 + $cell['padding']['T'];
26961 }
26962 }
26963 else if ($this->simpleTables){
26964 if ($table['borders_separate']) { // NB twice border width
26965 $xadj = $table['simple']['border_details']['L']['w'] + $cell['padding']['L'] +($table['border_spacing_H']/2);
26966 $wadj = $table['simple']['border_details']['L']['w'] + $table['simple']['border_details']['R']['w'] + $cell['padding']['L'] +$cell['padding']['R'] + $table['border_spacing_H'];
26967 $yadj = $table['simple']['border_details']['T']['w'] + $cell['padding']['T'] + ($table['border_spacing_H']/2);
26968 }
26969 else {
26970 $xadj = $table['simple']['border_details']['L']['w']/2 + $cell['padding']['L'];
26971 $wadj = ($table['simple']['border_details']['L']['w'] + $table['simple']['border_details']['R']['w'])/2 + $cell['padding']['L'] + $cell['padding']['R'];
26972 $yadj = $table['simple']['border_details']['T']['w']/2 + $cell['padding']['T'];
26973 }
26974 }
26975
26976 $this->divwidth=$w-$wadj;
26977 if ($this->divwidth == 0) { $this->divwidth = 0.0001; }
26978 $this->x += $xadj;
26979 $this->y += $yadj;
26980 $this->printbuffer($cell['textbuffer'],'',true);
26981 }
26982 $this->y = $opy;
26983 }
26984
26985 /*-- BACKGROUNDS --*/
26986 if (!$this->ColActive) {
26987 if (isset($table['trgradients'][$i]) && ($j==0 || $table['borders_separate'])) {
26988 $g = $this->grad->parseBackgroundGradient($table['trgradients'][$i]);
26989 if ($g) {
26990 $gx = $x0;
26991 $gy = $y;
26992 $gh = $h;
26993 $gw = $table['w'] - ($table['max_cell_border_width']['L']/2) - ($table['max_cell_border_width']['R']/2) - $table['margin']['L'] - $table['margin']['R'];
26994 if ($table['borders_separate']) {
26995 $gw -= ($table['padding']['L'] + $table['border_details']['L']['w'] + $table['padding']['R'] + $table['border_details']['R']['w'] + $table['border_spacing_H']);
26996 $s = '';
26997 $clx = $x+ ($table['border_spacing_H']/2);
26998 $cly = $y+ ($table['border_spacing_V']/2);
26999 $clw = $w- $table['border_spacing_H'];
27000 $clh = $h- $table['border_spacing_V'];
27001 // Set clipping path
27002 $s = ' q 0 w '; // Line width=0
27003 $s .= sprintf('%.3F %.3F m ', ($clx)*_MPDFK, ($this->h-($cly))*_MPDFK); // start point TL before the arc
27004 $s .= sprintf('%.3F %.3F l ', ($clx)*_MPDFK, ($this->h-($cly+$clh))*_MPDFK); // line to BL
27005 $s .= sprintf('%.3F %.3F l ', ($clx+$clw)*_MPDFK, ($this->h-($cly+$clh))*_MPDFK); // line to BR
27006 $s .= sprintf('%.3F %.3F l ', ($clx+$clw)*_MPDFK, ($this->h-($cly))*_MPDFK); // line to TR
27007 $s .= sprintf('%.3F %.3F l ', ($clx)*_MPDFK, ($this->h-($cly))*_MPDFK); // line to TL
27008 $s .= ' W n '; // Ends path no-op & Sets the clipping path
27009 $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);
27010 }
27011 else {
27012 $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'=>'');
27013 }
27014 }
27015 }
27016 if (isset($table['trbackground-images'][$i]) && ($j==0 || $table['borders_separate'])) {
27017 if ($table['trbackground-images'][$i]['gradient'] && preg_match('/(-moz-)*(repeating-)*(linear|radial)-gradient/', $table['trbackground-images'][$i]['gradient'] )) {
27018 $g = $this->grad->parseMozGradient( $table['trbackground-images'][$i]['gradient'] );
27019 if ($g) {
27020 $gx = $x0;
27021 $gy = $y;
27022 $gh = $h;
27023 $gw = $table['w'] - ($table['max_cell_border_width']['L']/2) - ($table['max_cell_border_width']['R']/2) - $table['margin']['L'] - $table['margin']['R'];
27024 if ($table['borders_separate']) {
27025 $gw -= ($table['padding']['L'] + $table['border_details']['L']['w'] + $table['padding']['R'] + $table['border_details']['R']['w'] + $table['border_spacing_H']);
27026 $s = '';
27027 $clx = $x+ ($table['border_spacing_H']/2);
27028 $cly = $y+ ($table['border_spacing_V']/2);
27029 $clw = $w- $table['border_spacing_H'];
27030 $clh = $h- $table['border_spacing_V'];
27031 // Set clipping path
27032 $s = ' q 0 w '; // Line width=0
27033 $s .= sprintf('%.3F %.3F m ', ($clx)*_MPDFK, ($this->h-($cly))*_MPDFK); // start point TL before the arc
27034 $s .= sprintf('%.3F %.3F l ', ($clx)*_MPDFK, ($this->h-($cly+$clh))*_MPDFK); // line to BL
27035 $s .= sprintf('%.3F %.3F l ', ($clx+$clw)*_MPDFK, ($this->h-($cly+$clh))*_MPDFK); // line to BR
27036 $s .= sprintf('%.3F %.3F l ', ($clx+$clw)*_MPDFK, ($this->h-($cly))*_MPDFK); // line to TR
27037 $s .= sprintf('%.3F %.3F l ', ($clx)*_MPDFK, ($this->h-($cly))*_MPDFK); // line to TL
27038 $s .= ' W n '; // Ends path no-op & Sets the clipping path
27039 $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);
27040 }
27041 else {
27042 $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'=>'');
27043 }
27044 }
27045 }
27046 else {
27047 $image_id = $table['trbackground-images'][$i]['image_id'];
27048 $orig_w = $table['trbackground-images'][$i]['orig_w'];
27049 $orig_h = $table['trbackground-images'][$i]['orig_h'];
27050 $x_pos = $table['trbackground-images'][$i]['x_pos'];
27051 $y_pos = $table['trbackground-images'][$i]['y_pos'];
27052 $x_repeat = $table['trbackground-images'][$i]['x_repeat'];
27053 $y_repeat = $table['trbackground-images'][$i]['y_repeat'];
27054 $resize = $table['trbackground-images'][$i]['resize'];
27055 $opacity = $table['trbackground-images'][$i]['opacity'];
27056 $itype = $table['trbackground-images'][$i]['itype'];
27057 $clippath = '';
27058 $gx = $x0;
27059 $gy = $y;
27060 $gh = $h;
27061 $gw = $table['w'] - ($table['max_cell_border_width']['L']/2) - ($table['max_cell_border_width']['R']/2) - $table['margin']['L'] - $table['margin']['R'];
27062 if ($table['borders_separate']) {
27063 $gw -= ($table['padding']['L'] + $table['border_details']['L']['w'] + $table['padding']['R'] + $table['border_details']['R']['w'] + $table['border_spacing_H']);
27064 $s = '';
27065 $clx = $x + ($table['border_spacing_H']/2);
27066 $cly = $y + ($table['border_spacing_V']/2);
27067 $clw = $w - $table['border_spacing_H'];
27068 $clh = $h - $table['border_spacing_V'];
27069 // Set clipping path
27070 $s = ' q 0 w '; // Line width=0
27071 $s .= sprintf('%.3F %.3F m ', ($clx)*_MPDFK, ($this->h-($cly))*_MPDFK); // start point TL
27072 $s .= sprintf('%.3F %.3F l ', ($clx)*_MPDFK, ($this->h-($cly+$clh))*_MPDFK); // line to BL
27073 $s .= sprintf('%.3F %.3F l ', ($clx+$clw)*_MPDFK, ($this->h-($cly+$clh))*_MPDFK); // line to BR
27074 $s .= sprintf('%.3F %.3F l ', ($clx+$clw)*_MPDFK, ($this->h-($cly))*_MPDFK); // line to TR
27075 $s .= sprintf('%.3F %.3F l ', ($clx)*_MPDFK, ($this->h-($cly))*_MPDFK); // line to TL
27076 $s .= ' W n '; // Ends path no-op & Sets the clipping path
27077 $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);
27078 }
27079 else {
27080 $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);
27081 }
27082 }
27083 }
27084 }
27085
27086 /*-- END BACKGROUNDS --*/
27087
27088 // TABLE BORDER - if separate
27089 // mPDF 5.3.15
27090 if (($table['borders_separate'] || ($this->simpleTables && !$table['simple']['border'])) && $table['border']) {
27091 $halfspaceL = $table['padding']['L'] + ($table['border_spacing_H']/2);
27092 $halfspaceR = $table['padding']['R'] + ($table['border_spacing_H']/2);
27093 $halfspaceT = $table['padding']['T'] + ($table['border_spacing_V']/2);
27094 $halfspaceB = $table['padding']['B'] + ($table['border_spacing_V']/2);
27095 $tbx = $x;
27096 $tby = $y;
27097 $tbw = $w;
27098 $tbh = $h;
27099 $tab_bord = 0;
27100
27101 $corner = '';
27102 if ($i == 0) { // Top
27103 $tby -= $halfspaceT + ($table['border_details']['T']['w']/2);
27104 $tbh += $halfspaceT + ($table['border_details']['T']['w']/2);
27105 $this->setBorder($tab_bord , _BORDER_TOP);
27106 $corner .= 'T';
27107 }
27108 if ($i == ($numrows-1) || (isset($cell['rowspan']) && ($i+$cell['rowspan']) == $numrows)) { // Bottom // mPDF 5.3.15
27109 $tbh += $halfspaceB + ($table['border_details']['B']['w']/2);
27110 $this->setBorder($tab_bord , _BORDER_BOTTOM);
27111 $corner .= 'B';
27112 }
27113 if ($j == 0) { // Left
27114 $tbx -= $halfspaceL + ($table['border_details']['L']['w']/2);
27115 $tbw += $halfspaceL + ($table['border_details']['L']['w']/2);
27116 $this->setBorder($tab_bord , _BORDER_LEFT);
27117 $corner .= 'L';
27118 }
27119 if ($j == ($numcols-1) || (isset($cell['colspan']) && ($j+$cell['colspan']) == $numcols)) { // Right // mPDF 5.3.15
27120 $tbw += $halfspaceR + ($table['border_details']['R']['w']/2);
27121 $this->setBorder($tab_bord , _BORDER_RIGHT);
27122 $corner .= 'R';
27123 }
27124 $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'] );
27125 }
27126
27127 unset($cell );
27128 //Reset values
27129 $this->Reset();
27130
27131 }//end of (if isset(cells)...)
27132 }// end of columns
27133
27134 $newpagestarted = false;
27135 $this->tabletheadjustfinished = false;
27136
27137 if ($this->ColActive && $i < $numrows-1 && $level==1) { $this->breakpoints[$this->CurrCol][] = $y + $h; } // *COLUMNS*
27138
27139 /*-- COLUMNS --*/
27140 if ($this->ColActive) {
27141 if (count($this->cellBorderBuffer)) { $this->printcellbuffer(); }
27142 }
27143 /*-- END COLUMNS --*/
27144
27145 if ($i == $numrows-1) { $this->y = $y + $h; } //last row jump (update this->y position)
27146 if ($this->table_rotate && $level==1) {
27147 $this->tbrot_h += $h;
27148 }
27149
27150
27151
27152 }// end of rows
27153
27154 if ($this->progressBar) { $this->UpdateProgressBar(7,70,' '); } // *PROGRESS-BAR*
27155
27156 if (count($this->cellBorderBuffer)) { $this->printcellbuffer(); }
27157
27158
27159 if ($this->tableClipPath ) { $this->_out("Q"); }
27160 $this->tableClipPath = '';
27161
27162 // Advance down page by half width of bottom border
27163 if ($table['borders_separate']) { $this->y += $table['padding']['B'] + $table['border_details']['B']['w'] + $table['border_spacing_V']/2; }
27164 else { $this->y += $table['max_cell_border_width']['B']/2; }
27165
27166 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; }
27167 else if ($level==1) { $this->tbrot_h += $table['margin']['B'] + $table['max_cell_border_width']['B']/2; }
27168
27169 $bx = $x0;
27170 $by = $y0;
27171 if ($table['borders_separate']) {
27172 $bx -= ($table['padding']['L'] + $table['border_details']['L']['w'] + $table['border_spacing_H']/2);
27173 if ($tablestartpageno != $this->page) { // IF broken across page
27174 $by += $table['max_cell_border_width']['T']/2;
27175 if (empty($tableheader)) { $by -= ($table['border_spacing_V']/2); }
27176 }
27177 // mPDF 5.3.36
27178 else if ($split && $startrow > 0 && empty($tableheader)) {
27179 $by -= ($table['border_spacing_V']/2);
27180 }
27181 else {
27182 $by -= ($table['padding']['T'] + $table['border_details']['T']['w'] + $table['border_spacing_V']/2);
27183 }
27184 }
27185 else if ($tablestartpageno != $this->page && !empty($tableheader)) { $by += $maxbwtop /2; }
27186 $by -= $tableheaderadj;
27187 $bh = $this->y - $by;
27188 if (!$table['borders_separate']) { $bh -= $table['max_cell_border_width']['B']/2; }
27189
27190 // mPDF 5.3.36
27191 if ($split) {
27192 $bw = 0;
27193 $finalSpread = true;
27194 for($t=$startcol; $t<$numcols; $t++) {
27195 if ($table['colPg'][$t] == $splitpg) { $bw += $table['wc'][$t]; }
27196 if ($table['colPg'][$t] > $splitpg) { $finalSpread = false; break; }
27197 }
27198 if ($startcol==0) { $firstSpread = true; }
27199 else { $firstSpread = false; }
27200 if ($table['borders_separate']) {
27201 // mPDF 5.3.83
27202 $bw += $table['border_spacing_H'];
27203 if ($firstSpread) {
27204 $bw += $table['padding']['L'] + $table['border_details']['L']['w'];
27205 }
27206 else {
27207 $bx += ($table['padding']['L'] + $table['border_details']['L']['w']);
27208 }
27209 if ($finalSpread) {
27210 $bw += $table['padding']['R'] + $table['border_details']['R']['w'];
27211 }
27212 }
27213 }
27214 else {
27215 $bw = $table['w'] - ($table['max_cell_border_width']['L']/2) - ($table['max_cell_border_width']['R']/2) - $table['margin']['L'] - $table['margin']['R'];
27216 }
27217
27218 if (!$this->ColActive) {
27219 if (isset($table['bgcolor'][-1])) {
27220 $color = $this->ConvertColor($table['bgcolor'][-1]);
27221 if ($color) {
27222 $this->tableBackgrounds[$level*9][] = array('gradient'=>false, 'x'=>$bx, 'y'=>$by, 'w'=>$bw, 'h'=>$bh, 'col'=>$color);
27223 }
27224 }
27225
27226 /*-- BACKGROUNDS --*/
27227 if (isset($table['gradient'])) {
27228 $g = $this->grad->parseBackgroundGradient($table['gradient']);
27229 if ($g) {
27230 $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'=>'');
27231 }
27232 }
27233
27234 if (isset($table['background-image'])) {
27235 if ($table['background-image']['gradient'] && preg_match('/(-moz-)*(repeating-)*(linear|radial)-gradient/', $table['background-image']['gradient'] )) {
27236 $g = $this->grad->parseMozGradient( $table['background-image']['gradient'] );
27237 if ($g) {
27238 $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'=>'');
27239 }
27240 }
27241 else {
27242 $image_id = $table['background-image']['image_id'];
27243 $orig_w = $table['background-image']['orig_w'];
27244 $orig_h = $table['background-image']['orig_h'];
27245 $x_pos = $table['background-image']['x_pos'];
27246 $y_pos = $table['background-image']['y_pos'];
27247 $x_repeat = $table['background-image']['x_repeat'];
27248 $y_repeat = $table['background-image']['y_repeat'];
27249 $resize = $table['background-image']['resize'];
27250 $opacity = $table['background-image']['opacity'];
27251 $itype = $table['background-image']['itype'];
27252 $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);
27253 }
27254 }
27255 /*-- END BACKGROUNDS --*/
27256 }
27257
27258 if ($this->tableBackgrounds && $level == 1) {
27259 $s = $this->PrintTableBackgrounds();
27260 if ($this->table_rotate && !$this->processingHeader && !$this->processingFooter) {
27261 $this->tablebuffer = preg_replace('/(___TABLE___BACKGROUNDS'.date('jY').')/', '\\1'."\n".$s."\n", $this->tablebuffer);
27262 if ($level == 1) { $this->tablebuffer = preg_replace('/(___TABLE___BACKGROUNDS'.date('jY').')/', " ", $this->tablebuffer); }
27263 }
27264 else if ($this->bufferoutput) {
27265 $this->headerbuffer = preg_replace('/(___TABLE___BACKGROUNDS'.date('jY').')/', '\\1'."\n".$s."\n", $this->headerbuffer);
27266 if ($level == 1) { $this->headerbuffer = preg_replace('/(___TABLE___BACKGROUNDS'.date('jY').')/', " ", $this->headerbuffer ); }
27267 }
27268 else {
27269 $this->pages[$this->page] = preg_replace('/(___TABLE___BACKGROUNDS'.date('jY').')/', '\\1'."\n".$s."\n", $this->pages[$this->page]);
27270 if ($level == 1) { $this->pages[$this->page] = preg_replace('/(___TABLE___BACKGROUNDS'.date('jY').')/', " ", $this->pages[$this->page]); }
27271 }
27272 $this->tableBackgrounds = array();
27273 }
27274
27275
27276 // TABLE BOTTOM MARGIN
27277 if ($table['margin']['B']) {
27278 if (!$this->table_rotate && $level==1) {
27279 $this->DivLn($table['margin']['B'],$this->blklvl,true); // collapsible
27280 }
27281 else {
27282 $this->y += ($table['margin']['B']);
27283 }
27284 }
27285
27286 if ($this->ColActive && $level==1) { $this->breakpoints[$this->CurrCol][] = $this->y; } // *COLUMNS*
27287
27288 // mPDF 5.3.79
27289 if ($this->cacheTables) { fclose($fh); }
27290
27291 // mPDF 5.3.36
27292 if ($split) {
27293 // Are there more columns to print on a next page?
27294 if ($lastCol < $numcols-1) {
27295 $splitpg++;
27296 $startcol = $lastCol + 1;
27297 return array(false, $startrow, $startcol, $splitpg, $returny, $y0);
27298 }
27299 else {
27300 // mPDF 5.3.79
27301 if ($this->cacheTables) {
27302 unlink($table['cache']);
27303 @unlink($table['cache'].'.bak');
27304 }
27305 return array(true,0,0,0);
27306 }
27307 }
27308 // mPDF 5.3.79
27309 if ($this->cacheTables) {
27310 unlink($table['cache']);
27311 @unlink($table['cache'].'.bak');
27312 }
27313
27314 }//END OF FUNCTION _tableWrite()
27315
27316
27317 /////////////////////////END OF TABLE CODE//////////////////////////////////
27318 /*-- END TABLES --*/
27319
27320
27321 function _putextgstates() {
27322 for ($i = 1; $i <= count($this->extgstates); $i++) {
27323 $this->_newobj();
27324 $this->extgstates[$i]['n'] = $this->n;
27325 $this->_out('<</Type /ExtGState');
27326 foreach ($this->extgstates[$i]['parms'] as $k=>$v)
27327 $this->_out('/'.$k.' '.$v);
27328 $this->_out('>>');
27329 $this->_out('endobj');
27330 }
27331 }
27332
27333 // mPDF 5.3.41 Visibility
27334 function _putocg() {
27335 $this->_newobj();
27336 $this->n_ocg_print=$this->n;
27337 $this->_out('<</Type /OCG /Name '.$this->_textstring('print'));
27338 $this->_out('/Usage <</Print <</PrintState /ON>> /View <</ViewState /OFF>>>>>>');
27339 $this->_out('endobj');
27340 $this->_newobj();
27341 $this->n_ocg_view=$this->n;
27342 $this->_out('<</Type /OCG /Name '.$this->_textstring('view'));
27343 $this->_out('/Usage <</Print <</PrintState /OFF>> /View <</ViewState /ON>>>>>>');
27344 $this->_out('endobj');
27345 $this->_newobj();
27346 $this->n_ocg_hidden=$this->n;
27347 $this->_out('<</Type /OCG /Name '.$this->_textstring('hidden'));
27348 $this->_out('/Usage <</Print <</PrintState /OFF>> /View <</ViewState /OFF>>>>>>');
27349 $this->_out('endobj');
27350 }
27351
27352
27353 /*-- IMPORTS --*/
27354
27355 // from mPDFI
27356 function _putimportedobjects() {
27357 if (is_array($this->parsers) && count($this->parsers) > 0) {
27358 foreach($this->parsers AS $filename => $p) {
27359 $this->current_parser =& $this->parsers[$filename];
27360 if (is_array($this->_obj_stack[$filename])) {
27361 while($n = key($this->_obj_stack[$filename])) {
27362 $nObj = $this->current_parser->pdf_resolve_object($this->current_parser->c,$this->_obj_stack[$filename][$n][1]);
27363 $this->_newobj($this->_obj_stack[$filename][$n][0]);
27364 if ($nObj[0] == PDF_TYPE_STREAM) {
27365 $this->pdf_write_value($nObj);
27366 }
27367 else {
27368 $this->pdf_write_value($nObj[1]);
27369 }
27370 $this->_out('endobj');
27371 $this->_obj_stack[$filename][$n] = null; // free memory
27372 unset($this->_obj_stack[$filename][$n]);
27373 reset($this->_obj_stack[$filename]);
27374 }
27375 }
27376 }
27377 }
27378 }
27379
27380
27381 function _putformxobjects() {
27382 $filter=($this->compress) ? '/Filter /FlateDecode ' : '';
27383 reset($this->tpls);
27384 foreach($this->tpls AS $tplidx => $tpl) {
27385 $p=($this->compress) ? gzcompress($tpl['buffer']) : $tpl['buffer'];
27386 $this->_newobj();
27387 $this->tpls[$tplidx]['n'] = $this->n;
27388 $this->_out('<<'.$filter.'/Type /XObject');
27389 $this->_out('/Subtype /Form');
27390 $this->_out('/FormType 1');
27391 // Left/Bottom/Right/Top
27392 $this->_out(sprintf('/BBox [%.2F %.2F %.2F %.2F]',
27393 $tpl['box']['x']*_MPDFK,
27394 $tpl['box']['y']*_MPDFK,
27395 ($tpl['box']['x'] + $tpl['box']['w'])*_MPDFK,
27396 ($tpl['box']['y'] + $tpl['box']['h'])*_MPDFK )
27397 );
27398
27399
27400 if (isset($tpl['box']))
27401 $this->_out(sprintf('/Matrix [1 0 0 1 %.5F %.5F]',-$tpl['box']['x']*_MPDFK, -$tpl['box']['y']*_MPDFK));
27402 $this->_out('/Resources ');
27403
27404 if (isset($tpl['resources'])) {
27405 $this->current_parser =& $tpl['parser'];
27406 $this->pdf_write_value($tpl['resources']);
27407 } else {
27408 $this->_out('<</ProcSet [/PDF /Text /ImageB /ImageC /ImageI]');
27409 if (isset($this->_res['tpl'][$tplidx]['fonts']) && count($this->_res['tpl'][$tplidx]['fonts'])) {
27410 $this->_out('/Font <<');
27411 foreach($this->_res['tpl'][$tplidx]['fonts'] as $font)
27412 $this->_out('/F'.$font['i'].' '.$font['n'].' 0 R');
27413 $this->_out('>>');
27414 }
27415 if(isset($this->_res['tpl'][$tplidx]['images']) && count($this->_res['tpl'][$tplidx]['images']) ||
27416 isset($this->_res['tpl'][$tplidx]['tpls']) && count($this->_res['tpl'][$tplidx]['tpls']))
27417 {
27418 $this->_out('/XObject <<');
27419 if (isset($this->_res['tpl'][$tplidx]['images']) && count($this->_res['tpl'][$tplidx]['images'])) {
27420 foreach($this->_res['tpl'][$tplidx]['images'] as $image)
27421 $this->_out('/I'.$image['i'].' '.$image['n'].' 0 R');
27422 }
27423 if (isset($this->_res['tpl'][$tplidx]['tpls']) && count($this->_res['tpl'][$tplidx]['tpls'])) {
27424 foreach($this->_res['tpl'][$tplidx]['tpls'] as $i => $itpl)
27425 $this->_out($this->tplprefix.$i.' '.$itpl['n'].' 0 R');
27426 }
27427 $this->_out('>>');
27428 }
27429 $this->_out('>>');
27430 }
27431
27432 $this->_out('/Length '.strlen($p).' >>');
27433 $this->_putstream($p);
27434 $this->_out('endobj');
27435 }
27436 }
27437
27438 /*-- END IMPORTS --*/
27439
27440
27441 function _putpatterns() {
27442 for ($i = 1; $i <= count($this->patterns); $i++) {
27443 $x = $this->patterns[$i]['x'];
27444 $y = $this->patterns[$i]['y'];
27445 $w = $this->patterns[$i]['w'];
27446 $h = $this->patterns[$i]['h'];
27447 $pgh = $this->patterns[$i]['pgh'];
27448 $orig_w = $this->patterns[$i]['orig_w'];
27449 $orig_h = $this->patterns[$i]['orig_h'];
27450 $image_id = $this->patterns[$i]['image_id'];
27451 $itype = $this->patterns[$i]['itype'];
27452
27453 if ($this->patterns[$i]['x_repeat']) { $x_repeat = true; }
27454 else { $x_repeat = false; }
27455 if ($this->patterns[$i]['y_repeat']) { $y_repeat = true; }
27456 else { $y_repeat = false; }
27457 $x_pos = $this->patterns[$i]['x_pos'];
27458 if (stristr($x_pos ,'%') ) {
27459 $x_pos += 0;
27460 $x_pos /= 100;
27461 $x_pos = ($w * $x_pos) - ($orig_w/_MPDFK * $x_pos);
27462 }
27463 $y_pos = $this->patterns[$i]['y_pos'];
27464 if (stristr($y_pos ,'%') ) {
27465 $y_pos += 0;
27466 $y_pos /= 100;
27467 $y_pos = ($h * $y_pos) - ($orig_h/_MPDFK * $y_pos);
27468 }
27469 $adj_x = ($x_pos + $x) *_MPDFK;
27470 $adj_y = (($pgh - $y_pos - $y)*_MPDFK) - $orig_h ;
27471 $img_obj = false;
27472 if ($itype == 'svg' || $itype == 'wmf') {
27473 foreach($this->formobjects AS $fo) {
27474 if ($fo['i'] == $image_id) {
27475 $img_obj = $fo['n'];
27476 $fo_w = $fo['w'];
27477 $fo_h = -$fo['h'];
27478 $wmf_x = $fo['x'];
27479 $wmf_y = $fo['y'];
27480 break;
27481 }
27482 }
27483 }
27484 else {
27485 foreach($this->images AS $img) {
27486 if ($img['i'] == $image_id) { $img_obj = $img['n']; break; }
27487 }
27488 }
27489 if (!$img_obj ) { echo "Problem: Image object not found for background pattern ".$img['i']; exit; }
27490
27491 $this->_newobj();
27492 $this->_out('<</ProcSet [/PDF /Text /ImageB /ImageC /ImageI]');
27493 if ($itype == 'svg' || $itype == 'wmf') {
27494 $this->_out('/XObject <</FO'.$image_id.' '.$img_obj.' 0 R >>');
27495 // ******* ADD ANY ExtGStates, Shading AND Fonts needed for the FormObject
27496 // Set in classes/svg array['fo'] = true
27497 // Required that _putshaders comes before _putpatterns in _putresources
27498 // This adds any resources associated with any FormObject to every Formobject - overkill but works!
27499 if (count($this->extgstates)) {
27500 $this->_out('/ExtGState <<');
27501 foreach($this->extgstates as $k=>$extgstate)
27502 if (isset($extgstate['fo']) && $extgstate['fo']) {
27503 if (isset($extgstate['trans'])) $this->_out('/'.$extgstate['trans'].' '.$extgstate['n'].' 0 R');
27504 else $this->_out('/GS'.$k.' '.$extgstate['n'].' 0 R');
27505 }
27506 $this->_out('>>');
27507 }
27508 /*-- BACKGROUNDS --*/
27509 if (isset($this->gradients) AND (count($this->gradients) > 0)) {
27510 $this->_out('/Shading <<');
27511 foreach ($this->gradients as $id => $grad) {
27512 if (isset($grad['fo']) && $grad['fo']) {
27513 $this->_out('/Sh'.$id.' '.$grad['id'].' 0 R');
27514 }
27515 }
27516 $this->_out('>>');
27517 }
27518 /*-- END BACKGROUNDS --*/
27519 $this->_out('/Font <<');
27520 foreach($this->fonts as $font) {
27521 if (!$font['used'] && $font['type']=='TTF') { continue; }
27522 if (isset($font['fo']) && $font['fo']) {
27523 if ($font['type']=='TTF' && ($font['sip'] || $font['smp'])) {
27524 foreach($font['n'] AS $k => $fid) {
27525 $this->_out('/F'.$font['subsetfontids'][$k].' '.$font['n'][$k].' 0 R');
27526 }
27527 }
27528 else {
27529 $this->_out('/F'.$font['i'].' '.$font['n'].' 0 R');
27530 }
27531 }
27532 }
27533 $this->_out('>>');
27534 }
27535 else {
27536 $this->_out('/XObject <</I'.$image_id.' '.$img_obj.' 0 R >>');
27537 }
27538 $this->_out('>>');
27539 $this->_out('endobj');
27540
27541 $this->_newobj();
27542 $this->patterns[$i]['n'] = $this->n;
27543 $this->_out('<< /Type /Pattern /PatternType 1 /PaintType 1 /TilingType 2');
27544 $this->_out('/Resources '. ($this->n-1) .' 0 R');
27545
27546 $this->_out(sprintf('/BBox [0 0 %.3F %.3F]',$orig_w,$orig_h));
27547 if ($x_repeat) { $this->_out(sprintf('/XStep %.3F',$orig_w)); }
27548 else { $this->_out(sprintf('/XStep %d',99999)); }
27549 if ($y_repeat) { $this->_out(sprintf('/YStep %.3F',$orig_h)); }
27550 else { $this->_out(sprintf('/YStep %d',99999)); }
27551
27552 if ($itype == 'svg' || $itype == 'wmf') {
27553 $this->_out(sprintf('/Matrix [1 0 0 -1 %.3F %.3F]', $adj_x, ($adj_y+$orig_h)));
27554 $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);
27555 }
27556 else {
27557 $this->_out(sprintf('/Matrix [1 0 0 1 %.3F %.3F]',$adj_x,$adj_y));
27558 $s = sprintf("q %.3F 0 0 %.3F 0 0 cm /I%d Do Q",$orig_w,$orig_h,$image_id);
27559 }
27560
27561 if ($this->compress) {
27562 $this->_out('/Filter /FlateDecode');
27563 $s = gzcompress($s);
27564 }
27565 $this->_out('/Length '.strlen($s).'>>');
27566 $this->_putstream($s);
27567 $this->_out('endobj');
27568 }
27569 }
27570
27571 /*-- BACKGROUNDS --*/
27572 function _putshaders() {
27573 $maxid = count($this->gradients); //index for transparency gradients
27574 foreach ($this->gradients as $id => $grad) {
27575 if (($grad['type'] == 2 || $grad['type'] == 3) && empty($grad['is_mask'])) {
27576 $this->_newobj();
27577 $this->_out('<<');
27578 $this->_out('/FunctionType 3');
27579 $this->_out('/Domain [0 1]');
27580 $fn = array();
27581 $bd = array();
27582 $en = array();
27583 for($i=0; $i<(count($grad['stops'])-1); $i++) {
27584 $fn[] = ($this->n+1+$i).' 0 R';
27585 $en[] = '0 1';
27586 if ($i>0) { $bd[] = sprintf('%.3F', $grad['stops'][$i]['offset']); }
27587 }
27588 $this->_out('/Functions ['.implode(' ',$fn).']');
27589 $this->_out('/Bounds ['.implode(' ',$bd).']');
27590 $this->_out('/Encode ['.implode(' ',$en).']');
27591 $this->_out('>>');
27592 $this->_out('endobj');
27593 $f1 = $this->n;
27594 for($i=0; $i<(count($grad['stops'])-1); $i++) {
27595 $this->_newobj();
27596 $this->_out('<<');
27597 $this->_out('/FunctionType 2');
27598 $this->_out('/Domain [0 1]');
27599 $this->_out('/C0 ['.$grad['stops'][$i]['col'].']');
27600 $this->_out('/C1 ['.$grad['stops'][$i+1]['col'].']');
27601 $this->_out('/N 1');
27602 $this->_out('>>');
27603 $this->_out('endobj');
27604 }
27605 }
27606 if ($grad['type'] == 2 || $grad['type'] == 3) { // mPDF 5.3.A1
27607 if (isset($grad['trans']) && $grad['trans']) {
27608 $this->_newobj();
27609 $this->_out('<<');
27610 $this->_out('/FunctionType 3');
27611 $this->_out('/Domain [0 1]');
27612 $fn = array();
27613 $bd = array();
27614 $en = array();
27615 for($i=0; $i<(count($grad['stops'])-1); $i++) {
27616 $fn[] = ($this->n+1+$i).' 0 R';
27617 $en[] = '0 1';
27618 if ($i>0) { $bd[] = sprintf('%.3F', $grad['stops'][$i]['offset']); }
27619 }
27620 $this->_out('/Functions ['.implode(' ',$fn).']');
27621 $this->_out('/Bounds ['.implode(' ',$bd).']');
27622 $this->_out('/Encode ['.implode(' ',$en).']');
27623 $this->_out('>>');
27624 $this->_out('endobj');
27625 $f2 = $this->n;
27626 for($i=0; $i<(count($grad['stops'])-1); $i++) {
27627 $this->_newobj();
27628 $this->_out('<<');
27629 $this->_out('/FunctionType 2');
27630 $this->_out('/Domain [0 1]');
27631 $this->_out(sprintf('/C0 [%.3F]', $grad['stops'][$i]['opacity']));
27632 $this->_out(sprintf('/C1 [%.3F]', $grad['stops'][$i+1]['opacity']));
27633 $this->_out('/N 1');
27634 $this->_out('>>');
27635 $this->_out('endobj');
27636 }
27637 }
27638 }
27639
27640 if (empty($grad['is_mask'])) {
27641 $this->_newobj();
27642 $this->_out('<<');
27643 $this->_out('/ShadingType '.$grad['type']);
27644 if (isset($grad['colorspace'])) {
27645 $this->_out('/ColorSpace /Device'.$grad['colorspace']); // Can use CMYK if all C0 and C1 above have 4 values
27646 } else {
27647 $this->_out('/ColorSpace /DeviceRGB');
27648 }
27649 if ($grad['type'] == 2) {
27650 $this->_out(sprintf('/Coords [%.3F %.3F %.3F %.3F]', $grad['coords'][0], $grad['coords'][1], $grad['coords'][2], $grad['coords'][3]));
27651 $this->_out('/Function '.$f1.' 0 R');
27652 $this->_out('/Extend ['.$grad['extend'][0].' '.$grad['extend'][1].'] ');
27653 $this->_out('>>');
27654 }
27655 else if ($grad['type'] == 3) {
27656 //x0, y0, r0, x1, y1, r1
27657 //at this this time radius of inner circle is 0
27658 $ir = 0;
27659 if (isset($grad['coords'][5]) && $grad['coords'][5]) { $ir = $grad['coords'][5]; }
27660 $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]));
27661 $this->_out('/Function '.$f1.' 0 R');
27662 $this->_out('/Extend ['.$grad['extend'][0].' '.$grad['extend'][1].'] ');
27663 $this->_out('>>');
27664 }
27665 // mPDF 5.3.A1
27666 else if ($grad['type']==6) {
27667 $this->_out('/BitsPerCoordinate 16');
27668 $this->_out('/BitsPerComponent 8');
27669 if ($grad['colorspace'] == 'CMYK') { $this->_out('/Decode[0 1 0 1 0 1 0 1 0 1 0 1]'); }
27670 else if ($grad['colorspace'] == 'Gray') { $this->_out('/Decode[0 1 0 1 0 1]'); }
27671 else { $this->_out('/Decode[0 1 0 1 0 1 0 1 0 1]'); }
27672 $this->_out('/BitsPerFlag 8');
27673 $this->_out('/Length '.strlen($grad['stream']));
27674 $this->_out('>>');
27675 $this->_putstream($grad['stream']);
27676 }
27677 $this->_out('endobj');
27678 }
27679
27680 $this->gradients[$id]['id'] = $this->n;
27681
27682 // set pattern object
27683 $this->_newobj();
27684 $out = '<< /Type /Pattern /PatternType 2';
27685 $out .= ' /Shading '.$this->gradients[$id]['id'].' 0 R';
27686 $out .= ' >>';
27687 $out .= "\n".'endobj';
27688 $this->_out($out);
27689
27690
27691 $this->gradients[$id]['pattern'] = $this->n;
27692
27693 if (isset($grad['trans']) && $grad['trans']) {
27694 // luminosity pattern
27695 $transid = $id + $maxid;
27696 $this->_newobj();
27697 $this->_out('<<');
27698 $this->_out('/ShadingType '.$grad['type']);
27699 $this->_out('/ColorSpace /DeviceGray');
27700 if ($grad['type'] == 2) {
27701 $this->_out(sprintf('/Coords [%.3F %.3F %.3F %.3F]', $grad['coords'][0], $grad['coords'][1], $grad['coords'][2], $grad['coords'][3]));
27702 $this->_out('/Function '.$f2.' 0 R');
27703 $this->_out('/Extend ['.$grad['extend'][0].' '.$grad['extend'][1].'] ');
27704 $this->_out('>>');
27705 }
27706 else if ($grad['type'] == 3) {
27707 //x0, y0, r0, x1, y1, r1
27708 //at this this time radius of inner circle is 0
27709 $ir = 0;
27710 if (isset($grad['coords'][5]) && $grad['coords'][5]) { $ir = $grad['coords'][5]; }
27711 $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]));
27712 $this->_out('/Function '.$f2.' 0 R');
27713 $this->_out('/Extend ['.$grad['extend'][0].' '.$grad['extend'][1].'] ');
27714 $this->_out('>>');
27715 }
27716 // mPDF 5.3.A1
27717 else if ($grad['type']==6) {
27718 $this->_out('/BitsPerCoordinate 16');
27719 $this->_out('/BitsPerComponent 8');
27720 $this->_out('/Decode[0 1 0 1 0 1]');
27721 $this->_out('/BitsPerFlag 8');
27722 $this->_out('/Length '.strlen($grad['stream_trans']));
27723 $this->_out('>>');
27724 $this->_putstream($grad['stream_trans']);
27725 }
27726 $this->_out('endobj');
27727
27728 $this->gradients[$transid]['id'] = $this->n;
27729 $this->_newobj();
27730 $this->_out('<< /Type /Pattern /PatternType 2');
27731 $this->_out('/Shading '.$this->gradients[$transid]['id'].' 0 R');
27732 $this->_out('>>');
27733 $this->_out('endobj');
27734 $this->gradients[$transid]['pattern'] = $this->n;
27735 $this->_newobj();
27736 // Need to extend size of viewing box in case of transformations
27737 $str = 'q /a0 gs /Pattern cs /p'.$transid.' scn -'.($this->wPt/2).' -'.($this->hPt/2).' '.(2*$this->wPt).' '.(2*$this->hPt).' re f Q';
27738 $filter=($this->compress) ? '/Filter /FlateDecode ' : '';
27739 $p=($this->compress) ? gzcompress($str) : $str;
27740 $this->_out('<< /Type /XObject /Subtype /Form /FormType 1 '.$filter);
27741 $this->_out('/Length '.strlen($p));
27742 $this->_out('/BBox [-'.($this->wPt/2).' -'.($this->hPt/2).' '.(2*$this->wPt).' '.(2*$this->hPt).']');
27743 $this->_out('/Group << /Type /Group /S /Transparency /CS /DeviceGray >>');
27744 $this->_out('/Resources <<');
27745 $this->_out('/ExtGState << /a0 << /ca 1 /CA 1 >> >>');
27746 $this->_out('/Pattern << /p'.$transid.' '.$this->gradients[$transid]['pattern'].' 0 R >>');
27747 $this->_out('>>');
27748 $this->_out('>>');
27749 $this->_putstream($p);
27750 $this->_out('endobj');
27751 $this->_newobj();
27752 $this->_out('<< /Type /Mask /S /Luminosity /G '.($this->n - 1).' 0 R >>'."\n".'endobj');
27753 $this->_newobj();
27754 $this->_out('<< /Type /ExtGState /SMask '.($this->n - 1).' 0 R /AIS false >>'."\n".'endobj');
27755 if ($grad['fo']) { $this->extgstates[] = array('n' => $this->n, 'trans' => 'TGS'.$id, 'fo'=>true); }
27756 else { $this->extgstates[] = array('n' => $this->n, 'trans' => 'TGS'.$id); }
27757 }
27758 }
27759 }
27760 /*-- END BACKGROUNDS --*/
27761
27762 function _putspotcolors() {
27763 foreach($this->spotColors as $name=>$color) {
27764 $this->_newobj();
27765 $this->_out('[/Separation /'.str_replace(' ','#20',$name));
27766 $this->_out('/DeviceCMYK <<');
27767 $this->_out('/Range [0 1 0 1 0 1 0 1] /C0 [0 0 0 0] ');
27768 $this->_out(sprintf('/C1 [%.3F %.3F %.3F %.3F] ',$color['c']/100,$color['m']/100,$color['y']/100,$color['k']/100));
27769 $this->_out('/FunctionType 2 /Domain [0 1] /N 1>>]');
27770 $this->_out('endobj');
27771 $this->spotColors[$name]['n']=$this->n;
27772 }
27773 }
27774
27775
27776 function _putresources() {
27777 if ($this->hasOC) // mPDF 5.3.45
27778 $this->_putocg(); // mPDF 5.3.41 Visibility
27779 $this->_putextgstates();
27780 $this->_putspotcolors();
27781 if ($this->progressBar) { $this->UpdateProgressBar(2,'40','Compiling Fonts'); } // *PROGRESS-BAR*
27782 $this->_putfonts();
27783 if ($this->progressBar) { $this->UpdateProgressBar(2,'50','Compiling Images'); } // *PROGRESS-BAR*
27784 $this->_putimages();
27785 $this->_putformobjects(); // *IMAGES-CORE*
27786
27787 /*-- IMPORTS --*/
27788 if ($this->enableImports) {
27789 $this->_putformxobjects();
27790 $this->_putimportedobjects();
27791 }
27792 /*-- END IMPORTS --*/
27793
27794 /*-- BACKGROUNDS --*/
27795 $this->_putshaders();
27796 $this->_putpatterns();
27797 /*-- END BACKGROUNDS --*/
27798
27799 //Resource dictionary
27800 $this->offsets[2]=strlen($this->buffer);
27801 $this->_out('2 0 obj');
27802 $this->_out('<</ProcSet [/PDF /Text /ImageB /ImageC /ImageI]');
27803
27804 $this->_out('/Font <<');
27805 foreach($this->fonts as $font) {
27806 if (!$font['used'] && $font['type']=='TTF') { continue; }
27807 if ($font['type']=='TTF' && ($font['sip'] || $font['smp'])) {
27808 foreach($font['n'] AS $k => $fid) {
27809 $this->_out('/F'.$font['subsetfontids'][$k].' '.$font['n'][$k].' 0 R');
27810 }
27811 }
27812 else {
27813 $this->_out('/F'.$font['i'].' '.$font['n'].' 0 R');
27814 }
27815 }
27816 $this->_out('>>');
27817
27818 if (count($this->spotColors)) {
27819 $this->_out('/ColorSpace <<');
27820 foreach($this->spotColors as $color)
27821 $this->_out('/CS'.$color['i'].' '.$color['n'].' 0 R');
27822 $this->_out('>>');
27823 }
27824
27825 if (count($this->extgstates)) {
27826 $this->_out('/ExtGState <<');
27827 foreach($this->extgstates as $k=>$extgstate)
27828 if (isset($extgstate['trans'])) $this->_out('/'.$extgstate['trans'].' '.$extgstate['n'].' 0 R');
27829 else $this->_out('/GS'.$k.' '.$extgstate['n'].' 0 R');
27830 $this->_out('>>');
27831 }
27832
27833 /*-- BACKGROUNDS --*/
27834 if (isset($this->gradients) AND (count($this->gradients) > 0)) {
27835 $this->_out('/Shading <<');
27836 foreach ($this->gradients as $id => $grad) {
27837 $this->_out('/Sh'.$id.' '.$grad['id'].' 0 R');
27838 }
27839 $this->_out('>>');
27840
27841 /*
27842 // ??? Not needed !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
27843 $this->_out('/Pattern <<');
27844 foreach ($this->gradients as $id => $grad) {
27845 $this->_out('/P'.$id.' '.$grad['pattern'].' 0 R');
27846 }
27847 $this->_out('>>');
27848 */
27849 }
27850 /*-- END BACKGROUNDS --*/
27851
27852 if(count($this->images) || count($this->formobjects) || ($this->enableImports && count($this->tpls))) {
27853 $this->_out('/XObject <<');
27854 foreach($this->images as $image)
27855 $this->_out('/I'.$image['i'].' '.$image['n'].' 0 R');
27856 foreach($this->formobjects as $formobject)
27857 $this->_out('/FO'.$formobject['i'].' '.$formobject['n'].' 0 R');
27858 /*-- IMPORTS --*/
27859 if ($this->enableImports && count($this->tpls)) {
27860 foreach($this->tpls as $tplidx => $tpl) {
27861 $this->_out($this->tplprefix.$tplidx.' '.$tpl['n'].' 0 R');
27862 }
27863 }
27864 /*-- END IMPORTS --*/
27865 $this->_out('>>');
27866 }
27867
27868 /*-- BACKGROUNDS --*/
27869
27870 if (count($this->patterns)) {
27871 $this->_out('/Pattern <<');
27872 foreach($this->patterns as $k=>$patterns)
27873 $this->_out('/P'.$k.' '.$patterns['n'].' 0 R');
27874 $this->_out('>>');
27875 }
27876 /*-- END BACKGROUNDS --*/
27877
27878 // mPDF 5.3.41 Visibility
27879 if ($this->hasOC) // mPDF 5.3.45
27880 $this->_out('/Properties <</OC1 '.$this->n_ocg_print.' 0 R /OC2 '.$this->n_ocg_view.' 0 R /OC3 '.$this->n_ocg_hidden.' 0 R>>');
27881
27882 $this->_out('>>');
27883 $this->_out('endobj'); // end resource dictionary
27884
27885 $this->_putbookmarks(); // *BOOKMARKS*
27886
27887 if (isset($this->js) && $this->js) {
27888 $this->_putjavascript();
27889 }
27890
27891 /*-- ENCRYPTION --*/
27892 if ($this->encrypted) {
27893 $this->_newobj();
27894 $this->enc_obj_id = $this->n;
27895 $this->_out('<<');
27896 $this->_putencryption();
27897 $this->_out('>>');
27898 $this->_out('endobj');
27899 }
27900 /*-- END ENCRYPTION --*/
27901 }
27902
27903
27904 function _putjavascript() {
27905 $this->_newobj();
27906 $this->n_js = $this->n;
27907 $this->_out('<<');
27908 $this->_out('/Names [(EmbeddedJS) '.(1 + $this->n).' 0 R ]');
27909 $this->_out('>>');
27910 $this->_out('endobj');
27911
27912 $this->_newobj();
27913 $this->_out('<<');
27914 $this->_out('/S /JavaScript');
27915 $this->_out('/JS '.$this->_textstring($this->js));
27916 $this->_out('>>');
27917 $this->_out('endobj');
27918 }
27919
27920
27921
27922
27923 /*-- ENCRYPTION --*/
27924 function _putencryption() {
27925 $this->_out('/Filter /Standard');
27926 if ($this->useRC128encryption) {
27927 $this->_out('/V 2');
27928 $this->_out('/R 3');
27929 $this->_out('/Length 128');
27930 }
27931 else {
27932 $this->_out('/V 1');
27933 $this->_out('/R 2');
27934 }
27935 $this->_out('/O ('.$this->_escape($this->Ovalue).')');
27936 $this->_out('/U ('.$this->_escape($this->Uvalue).')');
27937 $this->_out('/P '.$this->Pvalue);
27938 }
27939 /*-- END ENCRYPTION --*/
27940
27941 function _puttrailer() {
27942 $this->_out('/Size '.($this->n+1));
27943 $this->_out('/Root '.$this->n.' 0 R');
27944 $this->_out('/Info '.$this->InfoRoot.' 0 R');
27945 /*-- ENCRYPTION --*/
27946 if ($this->encrypted) {
27947 $this->_out('/Encrypt '.$this->enc_obj_id.' 0 R');
27948 $this->_out('/ID [<'.$this->uniqid.'> <'.$this->uniqid.'>]');
27949 }
27950 else {
27951 /*-- END ENCRYPTION --*/
27952 $uniqid = md5(time() . $this->buffer);
27953 $this->_out('/ID [<'.$uniqid.'> <'.$uniqid.'>]');
27954 /*-- ENCRYPTION --*/
27955 }
27956 /*-- END ENCRYPTION --*/
27957 }
27958
27959 /*-- ENCRYPTION --*/
27960 function SetProtection($permissions=array(),$user_pass='',$owner_pass=null, $length=40) {
27961 $this->encrypted=false;
27962 if (is_string($permissions) && strlen($permissions)>0) { $permissions = array($permissions); }
27963 else if (!is_array($permissions)) { return 0; }
27964 $this->last_rc4_key='';
27965 $this->padding="\x28\xBF\x4E\x5E\x4E\x75\x8A\x41\x64\x00\x4E\x56\xFF\xFA\x01\x08".
27966 "\x2E\x2E\x00\xB6\xD0\x68\x3E\x80\x2F\x0C\xA9\xFE\x64\x53\x69\x7A";
27967
27968 $options = array(
27969 'print' => 4, // bit 3
27970 'modify' => 8, // bit 4
27971 'copy' => 16, // bit 5
27972 'annot-forms' => 32, // bit 6
27973 'fill-forms' => 256, // bit 9
27974 'extract' => 512, // bit 10
27975 'assemble' => 1024,// bit 11
27976 'print-highres' => 2048 // bit 12
27977 );
27978 // bit 31 = 1073741824
27979 // bit 32 = 2147483648
27980 // bits 13-31 = 2147479552
27981 // bits 13-32 = 4294963200 + 192 = 4294963392
27982 $protection = 4294963392; // bits 7,8,13-32
27983 foreach ($permissions as $permission) {
27984 if (!isset($options[$permission]))
27985 $this->Error('Incorrect permission: '.$permission);
27986 if ($options[$permission] > 32) { $this->useRC128encryption = true; }
27987 if (isset($options[$permission])) $protection += $options[$permission];
27988 }
27989 if ($length==128) { $this->useRC128encryption = true; }
27990 if ($owner_pass === null)
27991 $owner_pass = uniqid(rand());
27992 $this->encrypted = true;
27993 $this->_generateencryptionkey($user_pass, $owner_pass, $protection);
27994 }
27995
27996
27997 // Compute key depending on object number where the encrypted data is stored
27998 function _objectkey($n) {
27999 if ($this->useRC128encryption)
28000 $len = 16;
28001 else
28002 $len = 10;
28003 return substr($this->_md5_16($this->encryption_key.pack('VXxx',$n)),0,$len);
28004 }
28005
28006 // RC4 is the standard encryption algorithm used in PDF format
28007 function _RC4($key, $text) {
28008 if ($this->last_rc4_key != $key) {
28009 $k = str_repeat($key, 256/strlen($key)+1);
28010 $rc4 = range(0,255);
28011 $j = 0;
28012 for ($i=0; $i<256; $i++){
28013 $t = $rc4[$i];
28014 $j = ($j + $t + ord($k[$i])) % 256;
28015 $rc4[$i] = $rc4[$j];
28016 $rc4[$j] = $t;
28017 }
28018 $this->last_rc4_key = $key;
28019 $this->last_rc4_key_c = $rc4;
28020 } else {
28021 $rc4 = $this->last_rc4_key_c;
28022 }
28023
28024 $len = strlen($text);
28025 $a = 0;
28026 $b = 0;
28027 $out = '';
28028 for ($i=0; $i<$len; $i++){
28029 $a = ($a+1)%256;
28030 $t= $rc4[$a];
28031 $b = ($b+$t)%256;
28032 $rc4[$a] = $rc4[$b];
28033 $rc4[$b] = $t;
28034 $k = $rc4[($rc4[$a]+$rc4[$b])%256];
28035 $out.= chr(ord($text[$i]) ^ $k);
28036 }
28037 return $out;
28038 }
28039
28040 // Get MD5 as binary string
28041 function _md5_16($string) {
28042 return pack('H*',md5($string));
28043 }
28044
28045 // Compute O value
28046 function _Ovalue($user_pass, $owner_pass) {
28047 $tmp = $this->_md5_16($owner_pass);
28048 if ($this->useRC128encryption) {
28049 for ($i = 0; $i < 50; ++$i) {
28050 $tmp = $this->_md5_16($tmp);
28051 }
28052 }
28053 if ($this->useRC128encryption)
28054 $keybytelen = (128 / 8);
28055 else
28056 $keybytelen = (40 / 8);
28057 $owner_RC4_key = substr($tmp,0,$keybytelen);
28058 $enc = $this->_RC4($owner_RC4_key, $user_pass);
28059 if ($this->useRC128encryption) {
28060 $len = strlen($owner_RC4_key);
28061 for ($i = 1; $i <= 19; ++$i) {
28062 $key = '';
28063 for ($j = 0; $j < $len; ++$j) {
28064 $key .= chr(ord($owner_RC4_key{$j}) ^ $i);
28065 }
28066 $enc = $this->_RC4($key, $enc);
28067 }
28068 }
28069 return $enc;
28070 }
28071
28072 // Compute U value
28073 function _Uvalue() {
28074 if ($this->useRC128encryption) {
28075 $tmp = $this->_md5_16($this->padding.$this->_hexToString($this->uniqid));
28076 $enc = $this->_RC4($this->encryption_key, $tmp);
28077 $len = strlen($tmp);
28078 for ($i=1; $i<=19; ++$i) {
28079 $key = '';
28080 for ($j=0; $j<$len; ++$j) {
28081 $key .= chr(ord($this->encryption_key{$j}) ^ $i);
28082 }
28083 $enc = $this->_RC4($key, $enc);
28084 }
28085 $enc .= str_repeat("\x00", 16);
28086 return substr($enc, 0, 32);
28087 }
28088 else {
28089 return $this->_RC4($this->encryption_key, $this->padding);
28090 }
28091 }
28092
28093 // Compute encryption key
28094 function _generateencryptionkey($user_pass, $owner_pass, $protection) {
28095 // Pad passwords
28096 $user_pass = substr($user_pass.$this->padding,0,32);
28097 $owner_pass = substr($owner_pass.$this->padding,0,32);
28098 $chars = 'ABCDEF1234567890';
28099 $id = '';
28100 for ($i=0; $i<32; $i++) { $id .= $chars{rand(0, 15)}; }
28101 $this->uniqid = md5($id);
28102 // Compute O value
28103 $this->Ovalue = $this->_Ovalue($user_pass,$owner_pass);
28104 // Compute encyption key
28105 if ($this->useRC128encryption)
28106 $keybytelen = (128/8);
28107 else
28108 $keybytelen = (40/8);
28109 $prot = sprintf('%032b', $protection);
28110 $perms = chr(bindec(substr($prot,24,8)));
28111 $perms .= chr(bindec(substr($prot,16,8)));
28112 $perms .= chr(bindec(substr($prot,8,8)));
28113 $perms .= chr(bindec(substr($prot,0,8)));
28114 $tmp = $this->_md5_16($user_pass.$this->Ovalue.$perms.$this->_hexToString($this->uniqid));
28115 if ($this->useRC128encryption) {
28116 for ($i=0; $i<50; ++$i) {
28117 $tmp = $this->_md5_16(substr($tmp, 0, $keybytelen));
28118 }
28119 }
28120 $this->encryption_key = substr($tmp,0,$keybytelen);
28121 // Compute U value
28122 $this->Uvalue = $this->_Uvalue();
28123 // Compute P value
28124 $this->Pvalue = $protection;
28125 }
28126
28127
28128 function _hexToString($hs) {
28129 $s = '';
28130 $len = strlen($hs);
28131 if (($len % 2) != 0) {
28132 $hs .= '0';
28133 ++$len;
28134 }
28135 for ($i = 0; $i < $len; $i += 2) {
28136 $s .= chr(hexdec($hs{$i}.$hs{($i + 1)}));
28137 }
28138 return $s;
28139 }
28140
28141 /*-- END ENCRYPTION --*/
28142
28143 //=========================================
28144 /*-- BOOKMARKS --*/
28145 // FROM class PDF_Bookmark
28146
28147 function Bookmark($txt,$level=0,$y=0) {
28148 $txt = $this->purify_utf8_text($txt);
28149 if ($this->text_input_as_HTML) {
28150 $txt = $this->all_entities_to_utf8($txt);
28151 }
28152 if($y==-1) {
28153 if (!$this->ColActive){ $y=$this->y; }
28154 else { $y = $this->y0; } // If columns are on - mark top of columns
28155 }
28156 // else y is used as set, or =0 i.e. top of page
28157 // DIRECTIONALITY RTL
28158 $bmo = array('t'=>$txt,'l'=>$level,'y'=>$y,'p'=>$this->page);
28159 if ($this->keep_block_together) {
28160 $this->ktBMoutlines[]= $bmo;
28161 }
28162 /*-- TABLES --*/
28163 else if ($this->table_rotate) {
28164 $this->tbrot_BMoutlines[]= $bmo;
28165 }
28166 else if ($this->kwt) {
28167 $this->kwt_BMoutlines[]= $bmo;
28168 }
28169 /*-- END TABLES --*/
28170 else if ($this->ColActive) { // *COLUMNS*
28171 $this->col_BMoutlines[]= $bmo; // *COLUMNS*
28172 } // *COLUMNS*
28173 else {
28174 $this->BMoutlines[]= $bmo;
28175 }
28176 }
28177
28178
28179 function _putbookmarks()
28180 {
28181 $nb=count($this->BMoutlines);
28182 if($nb==0)
28183 return;
28184 $lru=array();
28185 $level=0;
28186 foreach($this->BMoutlines as $i=>$o)
28187 {
28188 if($o['l']>0)
28189 {
28190 $parent=$lru[$o['l']-1];
28191 //Set parent and last pointers
28192 $this->BMoutlines[$i]['parent']=$parent;
28193 $this->BMoutlines[$parent]['last']=$i;
28194 if($o['l']>$level)
28195 {
28196 //Level increasing: set first pointer
28197 $this->BMoutlines[$parent]['first']=$i;
28198 }
28199 }
28200 else
28201 $this->BMoutlines[$i]['parent']=$nb;
28202 if($o['l']<=$level and $i>0)
28203 {
28204 //Set prev and next pointers
28205 $prev=$lru[$o['l']];
28206 $this->BMoutlines[$prev]['next']=$i;
28207 $this->BMoutlines[$i]['prev']=$prev;
28208 }
28209 $lru[$o['l']]=$i;
28210 $level=$o['l'];
28211 }
28212
28213 //Outline items
28214 $n=$this->n+1;
28215 foreach($this->BMoutlines as $i=>$o)
28216 {
28217 $this->_newobj();
28218 $this->_out('<</Title '.$this->_UTF16BEtextstring($o['t']));
28219 $this->_out('/Parent '.($n+$o['parent']).' 0 R');
28220 if(isset($o['prev']))
28221 $this->_out('/Prev '.($n+$o['prev']).' 0 R');
28222 if(isset($o['next']))
28223 $this->_out('/Next '.($n+$o['next']).' 0 R');
28224 if(isset($o['first']))
28225 $this->_out('/First '.($n+$o['first']).' 0 R');
28226 if(isset($o['last']))
28227 $this->_out('/Last '.($n+$o['last']).' 0 R');
28228
28229
28230 if (isset($this->pageDim[$o['p']]['h'])) { $h=$this->pageDim[$o['p']]['h']; }
28231 else { $h = 0; }
28232
28233 $this->_out(sprintf('/Dest [%d 0 R /XYZ 0 %.3F null]',1+2*($o['p']),($h-$o['y'])*_MPDFK));
28234 // mPDF 5.3.39
28235 if (isset($this->bookmarkStyles) && isset($this->bookmarkStyles[$o['l']])) {
28236 // font style
28237 $bms = $this->bookmarkStyles[$o['l']]['style'];
28238 $style = 0;
28239 if (strpos($bms,'B') !== false) { $style += 2; }
28240 if (strpos($bms,'I') !== false) { $style += 1; }
28241 $this->_out(sprintf('/F %d', $style));
28242 // Colour
28243 $col = $this->bookmarkStyles[$o['l']]['color'];
28244 if (isset($col) && is_array($col) && count($col)==3) {
28245 $this->_out(sprintf('/C [%.3F %.3F %.3F]', ($col[0]/255), ($col[1]/255), ($col[2]/255)));
28246 }
28247 }
28248
28249 $this->_out('/Count 0>>');
28250 $this->_out('endobj');
28251 }
28252 //Outline root
28253 $this->_newobj();
28254 $this->OutlineRoot=$this->n;
28255 $this->_out('<</Type /BMoutlines /First '.$n.' 0 R');
28256 $this->_out('/Last '.($n+$lru[0]).' 0 R>>');
28257 $this->_out('endobj');
28258 }
28259 /*-- END BOOKMARKS --*/
28260 // *BOOKMARKS*
28261
28262
28263
28264 //======================================================
28265
28266
28267 // DEPRACATED but included for backwards compatability
28268 function startPageNums() {
28269 }
28270
28271 //======================================================
28272 /*-- TOC --*/
28273 // ToC TABLE OF CONTENTS
28274
28275 // Initiate, and Mark a place for the Table of Contents to be inserted
28276 function TOC($tocfont='', $tocfontsize=8, $tocindent=5, $resetpagenum='', $pagenumstyle='', $suppress='', $toc_orientation='', $TOCusePaging=true, $TOCuseLinking=false, $toc_id=0) {
28277 if (!class_exists('tocontents', false)) { include(_MPDF_PATH.'classes/tocontents.php'); }
28278 if (empty($this->tocontents)) { $this->tocontents = new tocontents($this); }
28279 $this->tocontents->TOC($tocfont, $tocfontsize, $tocindent, $resetpagenum, $pagenumstyle, $suppress, $toc_orientation, $TOCusePaging, $TOCuseLinking, $toc_id);
28280 }
28281
28282
28283 function TOCpagebreakByArray($a) {
28284 if (!is_array($a)) { $a = array(); }
28285 if (!class_exists('tocontents', false)) { include(_MPDF_PATH.'classes/tocontents.php'); }
28286 if (empty($this->tocontents)) { $this->tocontents = new tocontents($this); }
28287 // mPDF 5.3.48
28288 $tocfont = (isset($a['tocfont']) ? $a['tocfont'] : (isset($a['font']) ? $a['font'] : ''));
28289 $tocfontsize = (isset($a['tocfontsize']) ? $a['tocfontsize'] : (isset($a['font-size']) ? $a['font-size'] : ''));
28290 $tocindent = (isset($a['tocindent']) ? $a['tocindent'] : (isset($a['indent']) ? $a['indent'] : ''));
28291 $TOCusePaging = (isset($a['TOCusePaging']) ? $a['TOCusePaging'] : (isset($a['paging']) ? $a['paging'] : true));
28292 $TOCuseLinking = (isset($a['TOCuseLinking']) ? $a['TOCuseLinking'] : (isset($a['links']) ? $a['links'] : ''));
28293 $toc_orientation = (isset($a['toc_orientation']) ? $a['toc_orientation'] : (isset($a['toc-orientation']) ? $a['toc-orientation'] : ''));
28294 $toc_mgl = (isset($a['toc_mgl']) ? $a['toc_mgl'] : (isset($a['toc-margin-left']) ? $a['toc-margin-left'] : ''));
28295 $toc_mgr = (isset($a['toc_mgr']) ? $a['toc_mgr'] : (isset($a['toc-margin-right']) ? $a['toc-margin-right'] : ''));
28296 $toc_mgt = (isset($a['toc_mgt']) ? $a['toc_mgt'] : (isset($a['toc-margin-top']) ? $a['toc-margin-top'] : ''));
28297 $toc_mgb = (isset($a['toc_mgb']) ? $a['toc_mgb'] : (isset($a['toc-margin-bottom']) ? $a['toc-margin-bottom'] : ''));
28298 $toc_mgh = (isset($a['toc_mgh']) ? $a['toc_mgh'] : (isset($a['toc-margin-header']) ? $a['toc-margin-header'] : ''));
28299 $toc_mgf = (isset($a['toc_mgf']) ? $a['toc_mgf'] : (isset($a['toc-margin-footer']) ? $a['toc-margin-footer'] : ''));
28300 $toc_ohname = (isset($a['toc_ohname']) ? $a['toc_ohname'] : (isset($a['toc-odd-header-name']) ? $a['toc-odd-header-name'] : ''));
28301 $toc_ehname = (isset($a['toc_ehname']) ? $a['toc_ehname'] : (isset($a['toc-even-header-name']) ? $a['toc-even-header-name'] : ''));
28302 $toc_ofname = (isset($a['toc_ofname']) ? $a['toc_ofname'] : (isset($a['toc-odd-footer-name']) ? $a['toc-odd-footer-name'] : ''));
28303 $toc_efname = (isset($a['toc_efname']) ? $a['toc_efname'] : (isset($a['toc-even-footer-name']) ? $a['toc-even-footer-name'] : ''));
28304 $toc_ohvalue = (isset($a['toc_ohvalue']) ? $a['toc_ohvalue'] : (isset($a['toc-odd-header-value']) ? $a['toc-odd-header-value'] : 0));
28305 $toc_ehvalue = (isset($a['toc_ehvalue']) ? $a['toc_ehvalue'] : (isset($a['toc-even-header-value']) ? $a['toc-even-header-value'] : 0));
28306 $toc_ofvalue = (isset($a['toc_ofvalue']) ? $a['toc_ofvalue'] : (isset($a['toc-odd-footer-value']) ? $a['toc-odd-footer-value'] : 0));
28307 $toc_efvalue = (isset($a['toc_efvalue']) ? $a['toc_efvalue'] : (isset($a['toc-even-footer-value']) ? $a['toc-even-footer-value'] : 0));
28308 $toc_preHTML = (isset($a['toc_preHTML']) ? $a['toc_preHTML'] : (isset($a['toc-preHTML']) ? $a['toc-preHTML'] : ''));
28309 $toc_postHTML = (isset($a['toc_postHTML']) ? $a['toc_postHTML'] : (isset($a['toc-postHTML']) ? $a['toc-postHTML'] : ''));
28310 $toc_bookmarkText = (isset($a['toc_bookmarkText']) ? $a['toc_bookmarkText'] : (isset($a['toc-bookmarkText']) ? $a['toc-bookmarkText'] : ''));
28311 $resetpagenum = (isset($a['resetpagenum']) ? $a['resetpagenum'] : '');
28312 $pagenumstyle = (isset($a['pagenumstyle']) ? $a['pagenumstyle'] : '');
28313 $suppress = (isset($a['suppress']) ? $a['suppress'] : '');
28314 $orientation = (isset($a['orientation']) ? $a['orientation'] : '');
28315 $mgl = (isset($a['mgl']) ? $a['mgl'] : (isset($a['margin-left']) ? $a['margin-left'] : ''));
28316 $mgr = (isset($a['mgr']) ? $a['mgr'] : (isset($a['margin-right']) ? $a['margin-right'] : ''));
28317 $mgt = (isset($a['mgt']) ? $a['mgt'] : (isset($a['margin-top']) ? $a['margin-top'] : ''));
28318 $mgb = (isset($a['mgb']) ? $a['mgb'] : (isset($a['margin-bottom']) ? $a['margin-bottom'] : ''));
28319 $mgh = (isset($a['mgh']) ? $a['mgh'] : (isset($a['margin-header']) ? $a['margin-header'] : ''));
28320 $mgf = (isset($a['mgf']) ? $a['mgf'] : (isset($a['margin-footer']) ? $a['margin-footer'] : ''));
28321 $ohname = (isset($a['ohname']) ? $a['ohname'] : (isset($a['odd-header-name']) ? $a['odd-header-name'] : ''));
28322 $ehname = (isset($a['ehname']) ? $a['ehname'] : (isset($a['even-header-name']) ? $a['even-header-name'] : ''));
28323 $ofname = (isset($a['ofname']) ? $a['ofname'] : (isset($a['odd-footer-name']) ? $a['odd-footer-name'] : ''));
28324 $efname = (isset($a['efname']) ? $a['efname'] : (isset($a['even-footer-name']) ? $a['even-footer-name'] : ''));
28325 $ohvalue = (isset($a['ohvalue']) ? $a['ohvalue'] : (isset($a['odd-header-value']) ? $a['odd-header-value'] : 0));
28326 $ehvalue = (isset($a['ehvalue']) ? $a['ehvalue'] : (isset($a['even-header-value']) ? $a['even-header-value'] : 0));
28327 $ofvalue = (isset($a['ofvalue']) ? $a['ofvalue'] : (isset($a['odd-footer-value']) ? $a['odd-footer-value'] : 0));
28328 $efvalue = (isset($a['efvalue']) ? $a['efvalue'] : (isset($a['even-footer-value']) ? $a['even-footer-value'] : 0));
28329 $toc_id = (isset($a['toc_id']) ? $a['toc_id'] : (isset($a['name']) ? $a['name'] : 0));
28330 $pagesel = (isset($a['pagesel']) ? $a['pagesel'] : (isset($a['pageselector']) ? $a['pageselector'] : ''));
28331 $toc_pagesel = (isset($a['toc_pagesel']) ? $a['toc_pagesel'] : (isset($a['toc-pageselector']) ? $a['toc-pageselector'] : ''));
28332 $sheetsize = (isset($a['sheetsize']) ? $a['sheetsize'] : (isset($a['sheet-size']) ? $a['sheet-size'] : ''));
28333 $toc_sheetsize = (isset($a['toc_sheetsize']) ? $a['toc_sheetsize'] : (isset($a['toc-sheet-size']) ? $a['toc-sheet-size'] : ''));
28334
28335 $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);
28336
28337 }
28338
28339 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='') {
28340 if (!class_exists('tocontents', false)) { include(_MPDF_PATH.'classes/tocontents.php'); }
28341 if (empty($this->tocontents)) { $this->tocontents = new tocontents($this); }
28342 //Start a new page
28343 if($this->state==0) $this->AddPage();
28344 if ($this->y == $this->tMargin && (!$this->mirrorMargins ||($this->mirrorMargins && $this->page % 2==1))) {
28345 // Don't add a page
28346 if ($this->page==1 && count($this->PageNumSubstitutions)==0) {
28347 if (!$suppress) { $suppress = 'off'; }
28348 if (!$resetpagenum) { $resetpagenum= 1; }
28349 //$this->PageNumSubstitutions[] = array('from'=>1, 'reset'=> $resetpagenum, 'type'=>$pagenumstyle, 'suppress'=> $suppress);
28350 }
28351 $this->PageNumSubstitutions[] = array('from'=>$this->page, 'reset'=> $resetpagenum, 'type'=>$pagenumstyle, 'suppress'=> $suppress);
28352 }
28353 else {
28354 $this->AddPage($orientation,'NEXT-ODD', $resetpagenum, $pagenumstyle, $suppress,$mgl,$mgr,$mgt,$mgb,$mgh,$mgf,$ohname,$ehname,$ofname,$efname,$ohvalue,$ehvalue,$ofvalue,$efvalue,$pagesel,$sheetsize);
28355 }
28356
28357 $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);
28358 }
28359
28360 function TOC_Entry($txt, $level=0, $toc_id=0) {
28361 $txt = $this->purify_utf8_text($txt);
28362 if ($this->text_input_as_HTML) {
28363 $txt = $this->all_entities_to_utf8($txt);
28364 }
28365 if ($this->usingCoreFont) { $txt = mb_convert_encoding($txt,$this->mb_enc,'UTF-8'); }
28366 if ($this->ColActive) { $ily = $this->y0; } else { $ily = $this->y; } // use top of columns
28367 $linkn = $this->AddLink();
28368 $this->SetLink($linkn,$ily,$this->page);
28369 /*-- RTL --*/
28370 if ($this->biDirectional) {
28371 $txt = preg_replace("/([".$this->pregRTLchars."]+)/ue", '$this->ArabJoin(stripslashes(\'\\1\'))', $txt );
28372 }
28373 /*-- END RTL --*/
28374 if (strtoupper($toc_id)=='ALL') { $toc_id = '_mpdf_all'; }
28375 else if (!$toc_id) { $toc_id = 0; }
28376 else { $toc_id = strtolower($toc_id); }
28377 $btoc = array('t'=>$txt,'l'=>$level,'p'=>$this->page, 'link'=>$linkn, 'toc_id'=>$toc_id);
28378 if ($this->keep_block_together) {
28379 $this->_kttoc[]= $btoc;
28380 }
28381 /*-- TABLES --*/
28382 else if ($this->table_rotate) {
28383 $this->tbrot_toc[]= $btoc;
28384 }
28385 else if ($this->kwt) {
28386 $this->kwt_toc[]= $btoc;
28387 }
28388 /*-- END TABLES --*/
28389 else if ($this->ColActive) { // *COLUMNS*
28390 $this->col_toc[]= $btoc; // *COLUMNS*
28391 } // *COLUMNS*
28392 else {
28393 $this->tocontents->_toc[]= $btoc;
28394 }
28395 }
28396
28397 /*-- END TOC --*/
28398
28399 //======================================================
28400 function MovePages($target_page, $start_page, $end_page=-1) {
28401 // move a page/pages EARLIER in the document
28402 if ($end_page<1) { $end_page = $start_page; }
28403 $n_toc = $end_page - $start_page + 1;
28404
28405 // Set/Update PageNumSubstitutions changes before moving anything
28406 if (count($this->PageNumSubstitutions)) {
28407 $tp_present = false;
28408 $sp_present = false;
28409 $ep_present = false;
28410 foreach($this->PageNumSubstitutions AS $k=>$v) {
28411 if ($this->PageNumSubstitutions[$k]['from']==$target_page) {
28412 $tp_present = true;
28413 if ($this->PageNumSubstitutions[$k]['suppress']!='on' && $this->PageNumSubstitutions[$k]['suppress']!=1) {
28414 $this->PageNumSubstitutions[$k]['suppress']='off';
28415 }
28416 }
28417 if ($this->PageNumSubstitutions[$k]['from']==$start_page) {
28418 $sp_present = true;
28419 if ($this->PageNumSubstitutions[$k]['suppress']!='on' && $this->PageNumSubstitutions[$k]['suppress']!=1) {
28420 $this->PageNumSubstitutions[$k]['suppress']='off';
28421 }
28422 }
28423 if ($this->PageNumSubstitutions[$k]['from']==($end_page+1)) {
28424 $ep_present = true;
28425 if ($this->PageNumSubstitutions[$k]['suppress']!='on' && $this->PageNumSubstitutions[$k]['suppress']!=1) {
28426 $this->PageNumSubstitutions[$k]['suppress']='off';
28427 }
28428 }
28429 }
28430
28431 if (!$tp_present) {
28432 list($tp_type, $tp_suppress, $tp_reset) = $this->docPageSettings($target_page);
28433 }
28434 if (!$sp_present) {
28435 list($sp_type, $sp_suppress, $sp_reset) = $this->docPageSettings($start_page);
28436 }
28437 if (!$ep_present) {
28438 list($ep_type, $ep_suppress, $ep_reset) = $this->docPageSettings($start_page-1);
28439 }
28440
28441 }
28442
28443 $last = array();
28444 //store pages
28445 for($i = $start_page;$i <= $end_page ;$i++)
28446 $last[]=$this->pages[$i];
28447 //move pages
28448 for($i=$start_page - 1;$i>=($target_page);$i--) {
28449 $this->pages[$i+$n_toc]=$this->pages[$i];
28450 }
28451 //Put toc pages at insert point
28452 for($i = 0;$i < $n_toc;$i++) {
28453 $this->pages[$target_page + $i]=$last[$i];
28454 }
28455
28456 /*-- BOOKMARKS --*/
28457 // Update Bookmarks
28458 foreach($this->BMoutlines as $i=>$o) {
28459 if($o['p']>=$target_page) {
28460 $this->BMoutlines[$i]['p'] += $n_toc;
28461 }
28462 }
28463 /*-- END BOOKMARKS --*/
28464
28465 // Update Page Links
28466 if (count($this->PageLinks)) {
28467 $newarr = array();
28468 foreach($this->PageLinks as $i=>$o) {
28469 foreach($this->PageLinks[$i] as $key => $pl) {
28470 if (strpos($pl[4],'@')===0) {
28471 $p=substr($pl[4],1);
28472 if($p>=$start_page && $p<=$end_page) {
28473 $this->PageLinks[$i][$key][4] = '@'.($p + ($target_page - $start_page));
28474 }
28475 else if($p>=$target_page && $p<$start_page) {
28476 $this->PageLinks[$i][$key][4] = '@'.($p+$n_toc);
28477 }
28478 }
28479 }
28480 if($i>=$start_page && $i<=$end_page) {
28481 $newarr[($i + ($target_page - $start_page))] = $this->PageLinks[$i];
28482 }
28483 else if($i>=$target_page && $i<$start_page) {
28484 $newarr[($i + $n_toc)] = $this->PageLinks[$i];
28485 }
28486 else {
28487 $newarr[$i] = $this->PageLinks[$i];
28488 }
28489 }
28490 $this->PageLinks = $newarr;
28491 }
28492
28493 // OrientationChanges
28494 if (count($this->OrientationChanges)) {
28495 $newarr = array();
28496 foreach($this->OrientationChanges AS $p=>$v) {
28497 if($p>=$start_page && $p<=$end_page) { $newarr[($p + ($target_page - $start_page))] = $this->OrientationChanges[$p]; }
28498 else if($p>=$target_page && $p<$start_page) { $newarr[$p+$n_toc] = $this->OrientationChanges[$p]; }
28499 else { $newarr[$p] = $this->OrientationChanges[$p]; }
28500 }
28501 ksort($newarr);
28502 $this->OrientationChanges = $newarr;
28503 }
28504
28505 // Page Dimensions
28506 if (count($this->pageDim)) {
28507 $newarr = array();
28508 foreach($this->pageDim AS $p=>$v) {
28509 if($p>=$start_page && $p<=$end_page) { $newarr[($p + ($target_page - $start_page))] = $this->pageDim[$p]; }
28510 else if($p>=$target_page && $p<$start_page) { $newarr[$p+$n_toc] = $this->pageDim[$p]; }
28511 else { $newarr[$p] = $this->pageDim[$p]; }
28512 }
28513 ksort($newarr);
28514 $this->pageDim = $newarr;
28515 }
28516
28517 // HTML Headers & Footers
28518 if (count($this->saveHTMLHeader)) {
28519 $newarr = array();
28520 foreach($this->saveHTMLHeader AS $p=>$v) {
28521 if($p>=$start_page && $p<=$end_page) { $newarr[($p + ($target_page - $start_page))] = $this->saveHTMLHeader[$p]; }
28522 else if($p>=$target_page && $p<$start_page) { $newarr[$p+$n_toc] = $this->saveHTMLHeader[$p]; }
28523 else { $newarr[$p] = $this->saveHTMLHeader[$p]; }
28524 }
28525 ksort($newarr);
28526 $this->saveHTMLHeader = $newarr;
28527 }
28528 if (count($this->saveHTMLFooter)) {
28529 $newarr = array();
28530 foreach($this->saveHTMLFooter AS $p=>$v) {
28531 if($p>=$start_page && $p<=$end_page) { $newarr[($p + ($target_page - $start_page))] = $this->saveHTMLFooter[$p]; }
28532 else if($p>=$target_page && $p<$start_page) { $newarr[$p+$n_toc] = $this->saveHTMLFooter[$p]; }
28533 else { $newarr[$p] = $this->saveHTMLFooter[$p]; }
28534 }
28535 ksort($newarr);
28536 $this->saveHTMLFooter = $newarr;
28537 }
28538
28539 // Update Internal Links
28540 if (count($this->internallink)) {
28541 foreach($this->internallink as $key=>$o) {
28542 if($o['PAGE']>=$start_page && $o['PAGE']<=$end_page) {
28543 $this->internallink[$key]['PAGE'] += ($target_page - $start_page);
28544 }
28545 else if($o['PAGE']>=$target_page && $o['PAGE']<$start_page) {
28546 $this->internallink[$key]['PAGE'] += $n_toc;
28547 }
28548 }
28549 }
28550
28551 // Update Links
28552 if (count($this->links)) {
28553 foreach($this->links as $key=>$o) {
28554 if($o[0]>=$start_page && $o[0]<=$end_page) {
28555 $this->links[$key][0] += ($target_page - $start_page);
28556 }
28557 if($o[0]>=$target_page && $o[0]<$start_page) {
28558 $this->links[$key][0] += $n_toc;
28559 }
28560 }
28561 }
28562
28563 // Update Form fields
28564 if (count($this->form->forms)) {
28565 foreach($this->form->forms as $key=>$f) {
28566 if($f['page']>=$start_page && $f['page']<=$end_page) {
28567 $this->form->forms[$key]['page'] += ($target_page - $start_page);
28568 }
28569 if($f['page']>=$target_page && $f['page']<$start_page) {
28570 $this->form->forms[$key]['page'] += $n_toc;
28571 }
28572 }
28573 }
28574
28575 /*-- ANNOTATIONS --*/
28576 // Update Annotations
28577 if (count($this->PageAnnots)) {
28578 $newarr = array();
28579 foreach($this->PageAnnots as $p=>$anno) {
28580 if($p>=$start_page && $p<=$end_page) {
28581 $np = $p + ($target_page - $start_page);
28582 foreach($anno as $o) {
28583 $newarr[$np][] = $o;
28584 }
28585 }
28586 else if($p>=$target_page && $p<$start_page) {
28587 $np = $p + $n_toc;
28588 foreach($anno as $o) {
28589 $newarr[$np][] = $o;
28590 }
28591 }
28592 else {
28593 $newarr[$p] = $this->PageAnnots[$p];
28594 }
28595 }
28596 $this->PageAnnots = $newarr;
28597 unset($newarr);
28598 }
28599 /*-- END ANNOTATIONS --*/
28600
28601 // Update PageNumSubstitutions
28602 if (count($this->PageNumSubstitutions)) {
28603 $newarr = array();
28604 foreach($this->PageNumSubstitutions AS $k=>$v) {
28605 if($this->PageNumSubstitutions[$k]['from']>=$start_page && $this->PageNumSubstitutions[$k]['from']<=$end_page) {
28606 $this->PageNumSubstitutions[$k]['from'] += ($target_page - $start_page);
28607 $newarr[$this->PageNumSubstitutions[$k]['from']] = $this->PageNumSubstitutions[$k];
28608 }
28609 else if($this->PageNumSubstitutions[$k]['from']>=$target_page && $this->PageNumSubstitutions[$k]['from']<$start_page) {
28610 $this->PageNumSubstitutions[$k]['from'] += $n_toc;
28611 $newarr[$this->PageNumSubstitutions[$k]['from']] = $this->PageNumSubstitutions[$k];
28612 }
28613 else {
28614 $newarr[$this->PageNumSubstitutions[$k]['from']] = $this->PageNumSubstitutions[$k];
28615 }
28616 }
28617
28618 if (!$sp_present) {
28619 $newarr[$target_page] = array('from'=>$target_page, 'suppress'=>$sp_suppress, 'reset'=>$sp_reset, 'type'=>$sp_type);
28620 }
28621 if (!$tp_present) {
28622 $newarr[($target_page + $n_toc)] = array('from'=>($target_page+$n_toc), 'suppress'=>$tp_suppress, 'reset'=>$tp_reset, 'type'=>$tp_type);
28623 }
28624 if (!$ep_present && $end_page>count($this->pages)) {
28625 $newarr[($end_page+1)] = array('from'=>($end_page+1), 'suppress'=>$ep_suppress, 'reset'=>$ep_reset, 'type'=>$ep_type);
28626 }
28627 ksort($newarr);
28628 $this->PageNumSubstitutions = array();
28629 foreach($newarr as $v) {
28630 $this->PageNumSubstitutions[] = $v;
28631 }
28632 }
28633 }
28634
28635 //======================================================
28636 function DeletePages($start_page, $end_page=-1) {
28637 // move a page/pages EARLIER in the document
28638 if ($end_page<1) { $end_page = $start_page; }
28639 $n_tod = $end_page - $start_page + 1;
28640 $last_page = count($this->pages);
28641 $n_atend = $last_page - $end_page + 1;
28642
28643 //move pages
28644 for($i=0;$i<$n_atend;$i++) {
28645 $this->pages[$start_page+$i]=$this->pages[$end_page+1+$i];
28646 }
28647 //delete pages
28648 for($i = 0;$i < $n_tod ;$i++)
28649 unset($this->pages[$last_page-$i]);
28650
28651
28652 /*-- BOOKMARKS --*/
28653 // Update Bookmarks
28654 foreach($this->BMoutlines as $i=>$o) {
28655 if($o['p']>=$end_page) { $this->BMoutlines[$i]['p'] -= $n_tod; }
28656 else if($p<$start_page) { unset($this->BMoutlines[$i]); }
28657 }
28658 /*-- END BOOKMARKS --*/
28659
28660 // Update Page Links
28661 if (count($this->PageLinks)) {
28662 $newarr = array();
28663 foreach($this->PageLinks as $i=>$o) {
28664 foreach($this->PageLinks[$i] as $key => $pl) {
28665 if (strpos($pl[4],'@')===0) {
28666 $p=substr($pl[4],1);
28667 if($p>$end_page) { $this->PageLinks[$i][$key][4] = '@'.($p - $n_tod); }
28668 else if($p<$start_page) { unset($this->PageLinks[$i][$key]); }
28669 }
28670 }
28671 if($i>$end_page) { $newarr[($i - $n_tod)] = $this->PageLinks[$i]; }
28672 else if($p<$start_page) { $newarr[$i] = $this->PageLinks[$i]; }
28673 }
28674 $this->PageLinks = $newarr;
28675 }
28676
28677 // OrientationChanges
28678 if (count($this->OrientationChanges)) {
28679 $newarr = array();
28680 foreach($this->OrientationChanges AS $p=>$v) {
28681 if($p>$end_page) { $newarr[($p - $t_tod)] = $this->OrientationChanges[$p]; }
28682 else if($p<$start_page) { $newarr[$p] = $this->OrientationChanges[$p]; }
28683 }
28684 ksort($newarr);
28685 $this->OrientationChanges = $newarr;
28686 }
28687
28688 // Page Dimensions
28689 if (count($this->pageDim)) {
28690 $newarr = array();
28691 foreach($this->pageDim AS $p=>$v) {
28692 if($p>$end_page) { $newarr[($p - $n_tod)] = $this->pageDim[$p]; }
28693 else if($p<$start_page) { $newarr[$p] = $this->pageDim[$p]; }
28694 }
28695 ksort($newarr);
28696 $this->pageDim = $newarr;
28697 }
28698
28699 // HTML Headers & Footers
28700 if (count($this->saveHTMLHeader)) {
28701 foreach($this->saveHTMLHeader AS $p=>$v) {
28702 if($p>end_page) { $newarr[($p - $n_tod)] = $this->saveHTMLHeader[$p]; }
28703 else if($p<$start_page) { $newarr[$p] = $this->saveHTMLHeader[$p]; }
28704 }
28705 ksort($newarr);
28706 $this->saveHTMLHeader = $newarr;
28707 }
28708 if (count($this->saveHTMLFooter)) {
28709 $newarr = array();
28710 foreach($this->saveHTMLFooter AS $p=>$v) {
28711 if($p>$end_page) { $newarr[($p - $n_tod)] = $this->saveHTMLFooter[$p]; }
28712 else if($p<$start_page) { $newarr[$p] = $this->saveHTMLFooter[$p]; }
28713 }
28714 ksort($newarr);
28715 $this->saveHTMLFooter = $newarr;
28716 }
28717
28718 // Update Internal Links
28719 foreach($this->internallink as $key=>$o) {
28720 if($o['PAGE']>$end_page) { $this->internallink[$key]['PAGE'] -= $n_tod; }
28721 else if($o['PAGE']<$start_page) { unset($this->internallink[$key]); }
28722 }
28723
28724 // Update Links
28725 foreach($this->links as $key=>$o) {
28726 if($o[0]>$end_page) { $this->links[$key][0] -= $n_tod; }
28727 else if($o[0]<$start_page) { unset($this->links[$key]); }
28728 }
28729
28730 // Update Form fields
28731 foreach($this->form->forms as $key=>$f) {
28732 if($f['page']>$end_page) { $this->form->forms[$key]['page'] -= $n_tod; }
28733 else if($f['page']<$start_page) { unset($this->form->forms[$key]); }
28734 }
28735
28736 /*-- ANNOTATIONS --*/
28737 // Update Annotations
28738 if (count($this->PageAnnots)) {
28739 $newarr = array();
28740 foreach($this->PageAnnots as $p=>$anno) {
28741 if($p>$end_page) { foreach($anno as $o) { $newarr[($p - $n_tod)][] = $o; } }
28742 else if($p<$start_page) { $newarr[$p] = $this->PageAnnots[$p]; }
28743 }
28744 ksort($newarr);
28745 $this->PageAnnots = $newarr;
28746 }
28747 /*-- END ANNOTATIONS --*/
28748
28749 // Update PageNumSubstitutions
28750 foreach($this->PageNumSubstitutions AS $k=>$v) {
28751 if($this->PageNumSubstitutions[$k]['from']>$end_page) { $this->PageNumSubstitutions[$k]['from'] -= $n_tod; }
28752 else if($this->PageNumSubstitutions[$k]['from']<$start_page) { unset($this->PageNumSubstitutions[$k]); }
28753 }
28754
28755 unset($newarr);
28756 $this->page = count($this->pages);
28757 }
28758
28759
28760 //======================================================
28761 /*-- INDEX --*/
28762 // FROM class PDF_Ref == INDEX
28763
28764 function Reference($txt) {
28765 $this->IndexEntry($txt);
28766 }
28767
28768
28769 function IndexEntry($txt, $xref='') {
28770 if ($xref) {
28771 $this->IndexEntrySee($txt,$xref);
28772 return;
28773 }
28774 $txt = strip_tags($txt);
28775 $txt = $this->purify_utf8_text($txt);
28776 if ($this->text_input_as_HTML) {
28777 $txt = $this->all_entities_to_utf8($txt);
28778 }
28779 if ($this->usingCoreFont) { $txt = mb_convert_encoding($txt,$this->mb_enc,'UTF-8'); }
28780
28781 $Present=0;
28782 $size=sizeof($this->Reference);
28783
28784 if ($this->directionality == 'rtl') { // *RTL*
28785 $txt = str_replace(':',' - ',$txt); // *RTL*
28786 } // *RTL*
28787 else { // *RTL*
28788 $txt = str_replace(':',', ',$txt);
28789 } // *RTL*
28790
28791
28792 //Search the reference (AND Ref/PageNo) in the array
28793 for ($i=0;$i<$size;$i++){
28794 if ($this->keep_block_together) {
28795 if (isset($this->ktReference[$i]['t']) && $this->ktReference[$i]['t']==$txt){
28796 $Present=1;
28797 if (!in_array($this->page,$this->ktReference[$i]['p'])) {
28798 $this->ktReference[$i]['op'] = $this->page;
28799 }
28800 }
28801 }
28802 /*-- TABLES --*/
28803 else if ($this->table_rotate) {
28804 if (isset($this->tbrot_Reference[$i]['t']) && $this->tbrot_Reference[$i]['t']==$txt){
28805 $Present=1;
28806 if (!in_array($this->page,$this->tbrot_Reference[$i]['p'])) {
28807 $this->tbrot_Reference[$i]['op'] = $this->page;
28808 }
28809 }
28810 }
28811 else if ($this->kwt) {
28812 if (isset($this->kwt_Reference[$i]['t']) && $this->kwt_Reference[$i]['t']==$txt){
28813 $Present=1;
28814 if (!in_array($this->page,$this->kwt_Reference[$i]['p'])) {
28815 $this->kwt_Reference[$i]['op'] = $this->page;
28816 }
28817 }
28818 }
28819 /*-- END TABLES --*/
28820 /*-- COLUMNS --*/
28821 else if ($this->ColActive) {
28822 if (isset($this->col_Reference[$i]['t']) && $this->col_Reference[$i]['t']==$txt){
28823 $Present=1;
28824 if (!in_array($this->page,$this->col_Reference[$i]['p'])) {
28825 $this->col_Reference[$i]['op'] = $this->page;
28826 }
28827 }
28828 }
28829 /*-- END COLUMNS --*/
28830 else {
28831 if (isset($this->Reference[$i]['t']) && $this->Reference[$i]['t']==$txt){
28832 $Present=1;
28833 if (!in_array($this->page,$this->Reference[$i]['p'])) {
28834 $this->Reference[$i]['p'][] = $this->page;
28835 }
28836 }
28837 }
28838 }
28839 //If not found, add it
28840 if ($Present==0) {
28841 $opr = array('t'=>$txt, 'op'=>$this->page);
28842 if ($this->keep_block_together) {
28843 $this->ktReference[]= $opr;
28844 }
28845 /*-- TABLES --*/
28846 else if ($this->table_rotate) {
28847 $this->tbrot_Reference[]= $opr;
28848 }
28849 else if ($this->kwt) {
28850 $this->kwt_Reference[]= $opr;
28851 }
28852 /*-- END TABLES --*/
28853 /*-- COLUMNS --*/
28854 else if ($this->ColActive) {
28855 $this->col_Reference[]= $opr;
28856 }
28857 /*-- END COLUMNS --*/
28858 else {
28859 $this->Reference[]=array('t'=>$txt,'p'=>array($this->page));
28860 }
28861 }
28862 }
28863
28864 // Added function to add a reference "Elephants. See Chickens"
28865 function ReferenceSee($txta,$txtb) {
28866 $this->IndexEntrySee($txta,$txtb);
28867 }
28868
28869 function IndexEntrySee($txta,$txtb) {
28870 $txta = strip_tags($txta);
28871 $txtb = strip_tags($txtb);
28872 $txta = $this->purify_utf8_text($txta);
28873 $txtb = $this->purify_utf8_text($txtb);
28874 if ($this->text_input_as_HTML) {
28875 $txta = $this->all_entities_to_utf8($txta);
28876 $txtb = $this->all_entities_to_utf8($txtb);
28877 }
28878 if ($this->usingCoreFont) {
28879 $txta = mb_convert_encoding($txta,$this->mb_enc,'UTF-8');
28880 $txtb = mb_convert_encoding($txtb,$this->mb_enc,'UTF-8');
28881 }
28882 if ($this->directionality == 'rtl') { // *RTL*
28883 $txta = str_replace(':',' - ',$txta); // *RTL*
28884 $txtb = str_replace(':',' - ',$txtb); // *RTL*
28885 } // *RTL*
28886 else { // *RTL*
28887 $txta = str_replace(':',', ',$txta);
28888 $txtb = str_replace(':',', ',$txtb);
28889 } // *RTL*
28890 $this->Reference[]=array('t'=>$txta.' - see '.$txtb,'p'=>array());
28891 }
28892
28893 function CreateReference($NbCol=1, $reffontsize='', $linespacing='', $offset=3, $usedivletters=1, $divlettfontsize='', $gap=5, $reffont='',$divlettfont='', $useLinking=false) {
28894 $this->CreateIndex($NbCol, $reffontsize, $linespacing, $offset, $usedivletters, $divlettfontsize, $gap, $reffont, $divlettfont, $useLinking);
28895 }
28896
28897 function CreateIndex($NbCol=1, $reffontsize='', $linespacing='', $offset=3, $usedivletters=1, $divlettfontsize='', $gap=5, $reffont='',$divlettfont='', $useLinking=false) {
28898 if (!$reffontsize) { $reffontsize = $this->default_font_size; }
28899 if (!$divlettfontsize) { $divlettfontsize = ($this->default_font_size * 1.8); }
28900 if (!$reffont) { $reffont = $this->default_font; }
28901 if (!$divlettfont) { $divlettfont = $reffont; }
28902 if (!$linespacing) { $linespacing= $this->default_lineheight_correction; }
28903 if ($this->ColActive) { $this->SetColumns(0); } // *COLUMNS*
28904 $size=sizeof($this->Reference);
28905 if ($size == 0) { return false; }
28906
28907
28908 if ($NbCol<2) {
28909 $NbCol = 1;
28910 $colWidth = $this->pgwidth;
28911 }
28912 else {
28913 $this->SetColumns($NbCol,'',$gap);
28914 $colWidth = $this->ColWidth;
28915 }
28916 if ($this->directionality == 'rtl') { $align = 'R'; }
28917 else { $align = 'L'; }
28918 $lett = '';
28919 if (!function_exists('cmp')) { // mPDF 5.3.07
28920 function cmp ($a, $b) {
28921 return strnatcmp(strtolower($a['t']), strtolower($b['t']));
28922 }
28923 }
28924 //Alphabetic sort of the references
28925 usort($this->Reference, 'cmp');
28926 $size=sizeof($this->Reference);
28927 $this->breakpoints[$this->CurrCol][] = $this->y; // *COLUMNS*
28928
28929 $divlettjuststarted = false;
28930
28931 $this->OpenTag('DIV',array('STYLE'=>'line-height: '.$linespacing.'; font-family: '.$reffont.'; font-size: '.$reffontsize.'pt; '));
28932
28933 $last_lett = '';
28934 for ($i=0;$i<$size;$i++){
28935 if ($this->Reference[$i]['t']) {
28936 if ($usedivletters) {
28937
28938 $lett = mb_strtoupper(mb_substr($this->Reference[$i]['t'],0,1,$this->mb_enc ),$this->mb_enc );
28939 if ($lett != $last_lett) {
28940
28941 $save_bp = $this->breakpoints[$this->CurrCol]; // *COLUMNS*
28942 $divlettjuststarted = true;
28943
28944 if ($i>0) {
28945 $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; '));
28946 }
28947 else {
28948 $this->OpenTag('DIV',array('STYLE'=>'line-height: '.$linespacing.'; font-family: '.$divlettfont.'; font-size: '.$divlettfontsize.'pt; font-weight: bold; page-break-after: avoid; '));
28949 }
28950 $this->_saveTextBuffer($lett); // mPDF 5.3.99
28951 $this->CloseTag('DIV');
28952 }
28953 }
28954
28955 $this->OpenTag('DIV',array('STYLE'=>'text-indent: -'.$offset.'mm; line-height: '.$linespacing.'; font-family: '.$reffont.'; font-size: '.$reffontsize.'pt; '));
28956
28957 /*-- RTL --*/
28958 // Change Arabic + Persian. to Presentation Forms
28959 if ($this->biDirectional) {
28960 $this->Reference[$i]['t'] = preg_replace("/([".$this->pregRTLchars."]+)/ue", '$this->ArabJoin(stripslashes(\'\\1\'))', $this->Reference[$i]['t'] );
28961 }
28962 /*-- END RTL --*/
28963
28964 // Font-specific ligature substitution for Indic fonts
28965 if (isset($this->CurrentFont['indic']) && $this->CurrentFont['indic']) $this->ConvertIndic($this->Reference[$i]['t']); // *INDIC*
28966
28967 $this->_saveTextBuffer($this->Reference[$i]['t']); // mPDF 5.3.99
28968 $ppp = $this->Reference[$i]['p']; // = array of page numbers to point to
28969 if (count($ppp)) {
28970 sort($ppp);
28971 $newarr = array();
28972 $range_start = $ppp[0];
28973 $range_end = 0;
28974
28975 if (!$this->usingCoreFont) { $spacer = "\xc2\xa0 "; }
28976 else { $spacer = chr(160).' '; }
28977 $this->_saveTextBuffer($spacer); // mPDF 5.3.99
28978 if ($this->directionality == 'rtl') { $sep = '.'; $joiner = '-'; }
28979 else { $sep = ', '; $joiner = '-'; }
28980 for ($zi=1;$zi<count($ppp);$zi++) {
28981 // RTL - Each number separately
28982 if ($this->directionality == 'rtl') {
28983 /*-- RTL --*/
28984 if ($zi<count($ppp)-1) {
28985 $txt = $sep . $this->docPageNum($ppp[$zi]);
28986 if ($useLinking) { $href = '@'.$ppp[$zi]; }
28987 else { $href = ''; }
28988 $this->_saveTextBuffer($txt, $href); // mPDF 5.3.99
28989 }
28990 /*-- END RTL --*/
28991 }
28992
28993 else if ($ppp[$zi] == ($ppp[($zi-1)]+1)) {
28994 $range_end = $ppp[$zi];
28995 }
28996 else {
28997 if ($range_end) {
28998 if ($range_end == $range_start+1) {
28999 if ($useLinking) { $href = '@'.$range_start; }
29000 else { $href = ''; }
29001 $txt = $this->docPageNum($range_start) . $sep;
29002 $this->_saveTextBuffer($txt, $href); // mPDF 5.3.99
29003 if ($useLinking) { $href = '@'.$ppp[$zi-1]; }
29004 else { $href = ''; }
29005 $txt = $this->docPageNum($ppp[$zi-1]) . $sep;
29006 $this->_saveTextBuffer($txt, $href); // mPDF 5.3.99
29007 }
29008 else {
29009 if ($useLinking) { $href = '@'.$range_start; }
29010 else { $href = ''; }
29011 }
29012 }
29013 else {
29014 if ($useLinking) { $href = '@'.$ppp[$zi-1]; }
29015 else { $href = ''; }
29016 $txt = $this->docPageNum($ppp[$zi-1]) . $sep;
29017 $this->_saveTextBuffer($txt, $href); // mPDF 5.3.99
29018 }
29019 $range_start = $ppp[$zi];
29020 $range_end = 0;
29021 }
29022 }
29023
29024 if ($range_end) {
29025 if ($range_end == $range_start+1) {
29026 if ($useLinking) { $href = '@'.$range_start; }
29027 else { $href = ''; }
29028 $txt = $this->docPageNum($range_start) . $sep;
29029 $this->_saveTextBuffer($txt, $href); // mPDF 5.3.99
29030 if ($useLinking) { $href = '@'.$range_end; }
29031 else { $href = ''; }
29032 $txt = $this->docPageNum($range_end);
29033 $this->_saveTextBuffer($txt, $href); // mPDF 5.3.99
29034 }
29035 else {
29036 if ($useLinking) { $href = '@'.$range_start; }
29037 else { $href = ''; }
29038 $txt = $this->docPageNum($range_start) . $joiner;
29039 $this->_saveTextBuffer($txt, $href); // mPDF 5.3.99
29040 if ($useLinking) { $href = '@'.$range_end; }
29041 else { $href = ''; }
29042 $txt = $this->docPageNum($range_end);
29043 $this->_saveTextBuffer($txt, $href); // mPDF 5.3.99
29044 }
29045 }
29046 else {
29047 if ($useLinking) { $href = '@'.$ppp[(count($ppp)-1)]; }
29048 else { $href = ''; }
29049 $txt = $this->docPageNum($ppp[(count($ppp)-1)]);
29050 $this->_saveTextBuffer($txt, $href); // mPDF 5.3.99
29051 }
29052 }
29053 }
29054 $this->CloseTag('DIV');
29055
29056 if ($divlettjuststarted) { $this->breakpoints[$this->CurrCol] = $save_bp; } // *COLUMNS*
29057 $divlettjuststarted = false;
29058
29059 $this->breakpoints[$this->CurrCol][] = $this->y; // *COLUMNS*
29060 $last_lett = $lett;
29061 }
29062 $this->CloseTag('DIV');
29063 $this->breakpoints[$this->CurrCol][] = $this->y; // *COLUMNS*
29064 if ($this->ColActive) { $this->SetColumns(0); } // *COLUMNS*
29065 }
29066 /*-- END INDEX --*/
29067
29068
29069 function AcceptPageBreak() {
29070 if (count($this->cellBorderBuffer)) { $this->printcellbuffer(); } // *TABLES*
29071 /*-- COLUMNS --*/
29072 if ($this->ColActive==1) {
29073 if($this->CurrCol<$this->NbCol-1) {
29074 //Go to the next column
29075 $this->CurrCol++;
29076 $this->SetCol($this->CurrCol);
29077 $this->y=$this->y0;
29078 $this->ChangeColumn=1; // Number (and direction) of columns changed +1, +2, -2 etc.
29079 // DIRECTIONALITY RTL
29080 if ($this->directionality == 'rtl') { $this->ChangeColumn = -($this->ChangeColumn); } // *RTL*
29081
29082 //Stay on the page
29083 return false;
29084 }
29085 else {
29086 //Go back to the first column - NEW PAGE
29087 if (count($this->columnbuffer)) { $this->printcolumnbuffer(); }
29088 $this->SetCol(0);
29089 $this->y0 = $this->tMargin;
29090 $this->ChangeColumn= -($this->NbCol-1);
29091 // DIRECTIONALITY RTL
29092 if ($this->directionality == 'rtl') { $this->ChangeColumn = -($this->ChangeColumn); } // *RTL*
29093 //Page break
29094 return true;
29095 }
29096 }
29097 /*-- END COLUMNS --*/
29098 /*-- TABLES --*/
29099 else if ($this->table_rotate) {
29100 if ($this->tablebuffer) { $this->printtablebuffer(); }
29101 return true;
29102 }
29103 /*-- END TABLES --*/
29104 else { // *COLUMNS*
29105 $this->ChangeColumn=0;
29106 return $this->autoPageBreak;
29107 } // *COLUMNS*
29108 return $this->autoPageBreak;
29109 }
29110
29111
29112 //----------- COLUMNS ---------------------
29113 /*-- COLUMNS --*/
29114
29115 function SetColumns($NbCol,$vAlign='',$gap=5) {
29116 // NbCol = number of columns
29117 // CurrCol = Number of the current column starting at 0
29118 // Called externally to set columns on/off and number
29119 // Integer 2 upwards sets columns on to that number
29120 // Anything less than 2 turns columns off
29121 if ($NbCol<2) { // SET COLUMNS OFF
29122 if ($this->ColActive) {
29123 $this->ColActive=0;
29124 if (count($this->columnbuffer)) { $this->printcolumnbuffer(); }
29125 $this->NbCol=1;
29126 $this->ResetMargins();
29127 $this->pgwidth = $this->w - $this->lMargin - $this->rMargin;
29128 $this->divwidth = 0;
29129 $this->Ln();
29130 }
29131 $this->ColActive=0;
29132 $this->columnbuffer = array();
29133 $this->ColDetails = array();
29134 $this->columnLinks = array();
29135 $this->columnAnnots = array();
29136 $this->columnForms = array();
29137 $this->col_Reference = array();
29138 $this->col_BMoutlines = array();
29139 $this->col_toc = array();
29140 $this->breakpoints = array();
29141 }
29142 else { // SET COLUMNS ON
29143 if ($this->ColActive) {
29144 $this->ColActive=0;
29145 if (count($this->columnbuffer)) { $this->printcolumnbuffer(); }
29146 $this->ResetMargins();
29147 }
29148 if (isset($this->y) && $this->y>$this->tMargin) $this->Ln();
29149 $this->NbCol=$NbCol;
29150 $this->ColGap = $gap;
29151 $this->divwidth = 0;
29152 $this->ColActive=1;
29153 $this->ColumnAdjust = true; // enables column height adjustment for the page
29154 $this->columnbuffer = array();
29155 $this->ColDetails = array();
29156 $this->columnLinks = array();
29157 $this->columnAnnots = array();
29158 $this->columnForms = array();
29159 $this->col_Reference = array();
29160 $this->col_BMoutlines = array();
29161 $this->col_toc = array();
29162 $this->breakpoints = array();
29163 if ((strtoupper($vAlign) == 'J') || (strtoupper($vAlign) == 'JUSTIFY')) { $vAlign = 'J'; }
29164 else { $vAlign = ''; }
29165 $this->colvAlign = $vAlign;
29166 //Save the ordinate
29167 $absL = $this->DeflMargin-($gap/2);
29168 $absR = $this->DefrMargin-($gap/2);
29169 $PageWidth = $this->w-$absL-$absR; // virtual pagewidth for calculation only
29170 $ColWidth = (($PageWidth - ($gap * ($NbCol)))/$NbCol);
29171 $this->ColWidth = $ColWidth;
29172 /*-- RTL --*/
29173
29174 if ($this->directionality == 'rtl') {
29175 for ($i=0;$i<$this->NbCol;$i++) {
29176 $this->ColL[$i] = $absL + ($gap/2) + (($NbCol - ($i+1))*($PageWidth/$NbCol)) ;
29177 $this->ColR[$i] = $this->ColL[$i] + $ColWidth; // NB This is not R margin -> R pos
29178 }
29179 }
29180 else {
29181 /*-- END RTL --*/
29182 for ($i=0;$i<$this->NbCol;$i++) {
29183 $this->ColL[$i] = $absL + ($gap/2) + ($i* ($PageWidth/$NbCol) );
29184 $this->ColR[$i] = $this->ColL[$i] + $ColWidth; // NB This is not R margin -> R pos
29185 }
29186 } // *RTL*
29187 $this->pgwidth = $ColWidth;
29188 $this->SetCol(0);
29189 $this->y0=$this->y;
29190 }
29191 $this->x = $this->lMargin;
29192 }
29193
29194 function SetCol($CurrCol) {
29195 // Used internally to set column by number: 0 is 1st column
29196 //Set position on a column
29197 $this->CurrCol=$CurrCol;
29198 $x = $this->ColL[$CurrCol];
29199 $xR = $this->ColR[$CurrCol]; // NB This is not R margin -> R pos
29200 if (($this->mirrorMargins) && (($this->page)%2==0)) { // EVEN
29201 $x += $this->MarginCorrection ;
29202 $xR += $this->MarginCorrection ;
29203 }
29204 $this->SetMargins($x,($this->w - $xR),$this->tMargin);
29205 }
29206
29207 function AddColumn() {
29208 $this->NewColumn();
29209 $this->ColumnAdjust = false; // disables all column height adjustment for the page.
29210 }
29211 function NewColumn() {
29212 if ($this->ColActive==1) {
29213 if($this->CurrCol<$this->NbCol-1) {
29214 //Go to the next column
29215 $this->CurrCol++;
29216 $this->SetCol($this->CurrCol);
29217 $this->y = $this->y0;
29218 $this->ChangeColumn=1;
29219 // DIRECTIONALITY RTL
29220 if ($this->directionality == 'rtl') { $this->ChangeColumn = -($this->ChangeColumn); } // *RTL*
29221 //Stay on the page
29222 }
29223 else {
29224 //Go back to the first column
29225 //Page break
29226 if (count($this->columnbuffer)) { $this->printcolumnbuffer(); }
29227 $this->AddPage($this->CurOrientation);
29228 $this->SetCol(0);
29229 $this->y0 = $this->tMargin;
29230 $this->ChangeColumn= -($this->NbCol-1);
29231 // DIRECTIONALITY RTL
29232 if ($this->directionality == 'rtl') { $this->ChangeColumn = -($this->ChangeColumn); } // *RTL*
29233 }
29234 $this->x = $this->lMargin;
29235 }
29236 else {
29237 $this->AddPage($this->CurOrientation);
29238 }
29239 }
29240
29241 function printcolumnbuffer() {
29242 // Columns ended (but page not ended) -> try to match all columns - unless disabled by using a custom column-break
29243 if (!$this->ColActive && $this->ColumnAdjust && !$this->keepColumns) {
29244 // Calculate adjustment to add to each column to calculate rel_y value
29245 $this->ColDetails[0]['add_y'] = 0;
29246 $last_col = 0;
29247 // Recursively add previous column's height
29248 for($i=1;$i<$this->NbCol;$i++) {
29249 if (isset($this->ColDetails[$i]['bottom_margin']) && $this->ColDetails[$i]['bottom_margin']) { // If any entries in the column
29250 $this->ColDetails[$i]['add_y'] = ($this->ColDetails[$i-1]['bottom_margin'] - $this->y0) + $this->ColDetails[$i-1]['add_y'];
29251 $last_col = $i; // Last column actually printed
29252 }
29253 }
29254
29255 // Calculate value for each position sensitive entry as though for one column
29256 foreach($this->columnbuffer AS $key=>$s) {
29257 $t = $s['s'];
29258 if ($t == 'ACROFORM') {
29259 $this->columnbuffer[$key]['rel_y'] = $s['y'] + $this->ColDetails[$s['col']]['add_y'] - $this->y0;
29260 $this->columnbuffer[$key]['s'] = '';
29261 }
29262 else if (preg_match('/BT \d+\.\d\d+ (\d+\.\d\d+) Td/',$t)) {
29263 $this->columnbuffer[$key]['rel_y'] = $s['y'] + $this->ColDetails[$s['col']]['add_y'] - $this->y0;
29264 }
29265 else if (preg_match('/\d+\.\d\d+ (\d+\.\d\d+) \d+\.\d\d+ [\-]{0,1}\d+\.\d\d+ re/',$t)) {
29266 $this->columnbuffer[$key]['rel_y'] = $s['y'] + $this->ColDetails[$s['col']]['add_y'] - $this->y0;
29267 }
29268 else if (preg_match('/\d+\.\d\d+ (\d+\.\d\d+) m/',$t)) {
29269 $this->columnbuffer[$key]['rel_y'] = $s['y'] + $this->ColDetails[$s['col']]['add_y'] - $this->y0;
29270 }
29271 else if (preg_match('/\d+\.\d\d+ (\d+\.\d\d+) l/',$t)) {
29272 $this->columnbuffer[$key]['rel_y'] = $s['y'] + $this->ColDetails[$s['col']]['add_y'] - $this->y0;
29273 }
29274 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)) {
29275 $this->columnbuffer[$key]['rel_y'] = $s['y'] + $this->ColDetails[$s['col']]['add_y'] - $this->y0;
29276 }
29277 else if (preg_match('/\d+\.\d\d+ (\d+\.\d\d+) \d+\.\d\d+ \d+\.\d\d+ \d+\.\d\d+ \d+\.\d\d+ c/',$t)) {
29278 $this->columnbuffer[$key]['rel_y'] = $s['y'] + $this->ColDetails[$s['col']]['add_y'] - $this->y0;
29279 }
29280 }
29281 // mPDF 5.3.01
29282 foreach($this->internallink AS $key => $f) {
29283 if (is_array($f) && isset($f['col'])) {
29284 $this->internallink[$key]['rel_y'] = $f['Y'] + $this->ColDetails[$f['col']]['add_y'] - $this->y0;
29285 }
29286 }
29287
29288 $breaks = array();
29289 foreach($this->breakpoints AS $c => $bpa) {
29290 foreach($bpa AS $rely) {
29291 $breaks[] = $rely + $this->ColDetails[$c]['add_y'] - $this->y0;
29292 }
29293 }
29294
29295 if (isset($this->ColDetails[$last_col]['bottom_margin'])) { $lcbm = $this->ColDetails[$last_col]['bottom_margin']; }
29296 else { $lcbm = 0; }
29297 $sum_h = $this->ColDetails[$last_col]['add_y'] + $lcbm - $this->y0;
29298 //$sum_h = max($this->ColDetails[$last_col]['add_y'] + $this->ColDetails[$last_col]['bottom_margin'] - $this->y0, end($breaks));
29299 $target_h = ($sum_h / $this->NbCol);
29300
29301 $cbr = array();
29302 for($i=1;$i<$this->NbCol;$i++) {
29303 $th = ($sum_h * $i / $this->NbCol);
29304 foreach($breaks AS $bk=>$val) {
29305 if ($val > $th) {
29306 if (($val-$th) < ($th-$breaks[$bk-1])) { $cbr[$i-1] = $val; }
29307 else { $cbr[$i-1] = $breaks[$bk-1]; }
29308 break;
29309 }
29310 }
29311 }
29312 $cbr[($this->NbCol-1)] = $sum_h;
29313
29314 // Now update the columns - divide into columns of approximately equal value
29315 $last_new_col = 0;
29316 $yadj = 0; // mm
29317 $xadj = 0;
29318 $last_col_bottom = 0;
29319 $lowest_bottom_y = 0;
29320 $block_bottom = 0;
29321 $newcolumn = 0;
29322 foreach($this->columnbuffer AS $key=>$s) {
29323 if (isset($s['rel_y'])) { // only process position sensitive data
29324 if ($s['rel_y'] >= $cbr[$newcolumn]) {
29325 $newcolumn++;
29326 }
29327 else {
29328 $newcolumn = $last_new_col ;
29329 }
29330
29331
29332 $block_bottom = max($block_bottom,($s['rel_y']+$s['h']));
29333
29334 if ($this->directionality == 'rtl') { // *RTL*
29335 $xadj = -(($newcolumn - $s['col']) * ($this->ColWidth + $this->ColGap)); // *RTL*
29336 } // *RTL*
29337 else { // *RTL*
29338 $xadj = ($newcolumn - $s['col']) * ($this->ColWidth + $this->ColGap);
29339 } // *RTL*
29340
29341 if ($last_new_col != $newcolumn) { // Added new column
29342 $last_col_bottom = $this->columnbuffer[$key]['rel_y'];
29343 $block_bottom = 0;
29344 }
29345 $yadj = ($s['rel_y'] - $s['y']) - ($last_col_bottom)+$this->y0;
29346 // callback function in htmltoolkit
29347 $t = $s['s'];
29348 $t = preg_replace('/BT (\d+\.\d\d+) (\d+\.\d\d+) Td/e',"\$this->columnAdjustAdd('Td',_MPDFK,$xadj,$yadj,'\\1','\\2')",$t);
29349 $t = preg_replace('/(\d+\.\d\d+) (\d+\.\d\d+) (\d+\.\d\d+) ([\-]{0,1}\d+\.\d\d+) re/e',"\$this->columnAdjustAdd('re',_MPDFK,$xadj,$yadj,'\\1','\\2','\\3','\\4')",$t);
29350 $t = preg_replace('/(\d+\.\d\d+) (\d+\.\d\d+) l/e',"\$this->columnAdjustAdd('l',_MPDFK,$xadj,$yadj,'\\1','\\2')",$t);
29351 $t = preg_replace('/q (\d+\.\d\d+) 0 0 (\d+\.\d\d+) (\d+\.\d\d+) (\d+\.\d\d+) cm \/(I|FO)/e',"\$this->columnAdjustAdd('img',_MPDFK,$xadj,$yadj,'\\1','\\2','\\3','\\4','\\5')",$t);
29352 $t = preg_replace('/(\d+\.\d\d+) (\d+\.\d\d+) m/e',"\$this->columnAdjustAdd('draw',_MPDFK,$xadj,$yadj,'\\1','\\2')",$t);
29353 $t = preg_replace('/(\d+\.\d\d+) (\d+\.\d\d+) (\d+\.\d\d+) (\d+\.\d\d+) (\d+\.\d\d+) (\d+\.\d\d+) c/e',"\$this->columnAdjustAdd('bezier',_MPDFK,$xadj,$yadj,'\\1','\\2','\\3','\\4','\\5','\\6')",$t);
29354
29355 $this->columnbuffer[$key]['s'] = $t;
29356 $this->columnbuffer[$key]['newcol'] = $newcolumn;
29357 $this->columnbuffer[$key]['newy'] = $s['y'] + $yadj;
29358 $last_new_col = $newcolumn;
29359 $clb = $s['y'] + $yadj + $s['h'] ; // bottom_margin of current
29360 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; }
29361 if ($clb > $lowest_bottom_y) { $lowest_bottom_y = $clb; }
29362 // Adjust LINKS
29363 if (isset($this->columnLinks[$s['col']][INTVAL($s['x'])][INTVAL($s['y'])])) {
29364 $ref = $this->columnLinks[$s['col']][INTVAL($s['x'])][INTVAL($s['y'])];
29365 $this->PageLinks[$this->page][$ref][0] += ($xadj*_MPDFK);
29366 $this->PageLinks[$this->page][$ref][1] -= ($yadj*_MPDFK);
29367 unset($this->columnLinks[$s['col']][INTVAL($s['x'])][INTVAL($s['y'])]);
29368 }
29369 // Adjust FORM FIELDS
29370 if (isset($this->columnForms[$s['col']][INTVAL($s['x'])][INTVAL($s['y'])])) {
29371 $ref = $this->columnForms[$s['col']][INTVAL($s['x'])][INTVAL($s['y'])];
29372 $this->form->forms[$ref]['x'] += ($xadj);
29373 $this->form->forms[$ref]['y'] += ($yadj);
29374 unset($this->columnForms[$s['col']][INTVAL($s['x'])][INTVAL($s['y'])]);
29375 }
29376 /*-- ANNOTATIONS --*/
29377 if (isset($this->columnAnnots[$s['col']][INTVAL($s['x'])][INTVAL($s['y'])])) {
29378 $ref = $this->columnAnnots[$s['col']][INTVAL($s['x'])][INTVAL($s['y'])];
29379 if ($this->PageAnnots[$this->page][$ref]['x'] < 0) {
29380 $this->PageAnnots[$this->page][$ref]['x'] -= ($xadj);
29381 }
29382 else {
29383 $this->PageAnnots[$this->page][$ref]['x'] += ($xadj);
29384 }
29385 $this->PageAnnots[$this->page][$ref]['y'] += ($yadj); // unlike PageLinks, Page annots has y values from top in mm
29386 unset($this->columnAnnots[$s['col']][INTVAL($s['x'])][INTVAL($s['y'])]);
29387 }
29388 /*-- END ANNOTATIONS --*/
29389 }
29390 }
29391
29392 /*-- BOOKMARKS --*/
29393 // Adjust Bookmarks
29394 foreach($this->col_BMoutlines AS $v) {
29395 $this->BMoutlines[]=array('t'=>$v['t'],'l'=>$v['l'],'y'=>$this->y0,'p'=>$v['p']);
29396 }
29397 /*-- END BOOKMARKS --*/
29398
29399 /*-- INDEX --*/
29400 // Adjust Reference (index)
29401 foreach($this->col_Reference AS $v) {
29402 $Present=0;
29403 //Search the reference (AND Ref/PageNo) in the array
29404 for ($i=0;$i<count($this->Reference);$i++){
29405 if ($this->Reference[$i]['t']==$v['t']){
29406 $Present=1;
29407 if (!in_array($v['op'],$this->Reference[$i]['p'])) {
29408 $this->Reference[$i]['p'][] = $v['op'];
29409 }
29410 }
29411 }
29412 if ($Present==0) {
29413 $this->Reference[]=array('t'=>$v['t'],'p'=>array($v['op']));
29414 }
29415 }
29416 /*-- END INDEX --*/
29417
29418 /*-- TOC --*/
29419
29420 // Adjust ToC
29421 foreach($this->col_toc AS $v) {
29422 $this->tocontents->_toc[]=array('t'=>$v['t'],'l'=>$v['l'],'p'=>$v['p'],'link'=>$v['link'],'toc_id'=>$v['toc_id']);
29423 $this->links[$v['link']][1] = $this->y0;
29424 }
29425 /*-- END TOC --*/
29426
29427 // Adjust column length to be equal
29428 if ($this->colvAlign == 'J') {
29429 foreach($this->columnbuffer AS $key=>$s) {
29430 if (isset($s['rel_y'])) { // only process position sensitive data
29431 // Set ratio to expand y values or heights
29432 if (isset($this->ColDetails[$s['newcol']]['max_bottom']) && $this->ColDetails[$s['newcol']]['max_bottom'] && $this->ColDetails[$s['newcol']]['max_bottom']!=$this->y0) {
29433 $ratio = ($lowest_bottom_y - ($this->y0)) / ($this->ColDetails[$s['newcol']]['max_bottom'] - ($this->y0));
29434 }
29435 else { $ratio = 1; }
29436 if (($ratio > 1) && ($ratio <= $this->max_colH_correction)) {
29437 $yadj = ($s['newy'] - $this->y0) * ($ratio - 1);
29438
29439 // Adjust LINKS
29440 if (isset($this->columnLinks[$s['col']][INTVAL($s['x'])][INTVAL($s['y'])])) {
29441 $ref = $this->columnLinks[$s['col']][INTVAL($s['x'])][INTVAL($s['y'])];
29442 $this->PageLinks[$this->page][$ref][1] -= ($yadj*_MPDFK); // y value
29443 $this->PageLinks[$this->page][$ref][3] *= $ratio; // height
29444 unset($this->columnLinks[$s['col']][INTVAL($s['x'])][INTVAL($s['y'])]);
29445 }
29446 // Adjust FORM FIELDS
29447 if (isset($this->columnForms[$s['col']][INTVAL($s['x'])][INTVAL($s['y'])])) {
29448 $ref = $this->columnForms[$s['col']][INTVAL($s['x'])][INTVAL($s['y'])];
29449 $this->form->forms[$ref]['x'] += ($xadj);
29450 $this->form->forms[$ref]['y'] += ($yadj);
29451 unset($this->columnForms[$s['col']][INTVAL($s['x'])][INTVAL($s['y'])]);
29452 }
29453 /*-- ANNOTATIONS --*/
29454 if (isset($this->columnAnnots[$s['col']][INTVAL($s['x'])][INTVAL($s['y'])])) {
29455 $ref = $this->columnAnnots[$s['col']][INTVAL($s['x'])][INTVAL($s['y'])];
29456 $this->PageAnnots[$this->page][$ref]['y'] += ($yadj);
29457 unset($this->columnAnnots[$s['col']][INTVAL($s['x'])][INTVAL($s['y'])]);
29458 }
29459 /*-- END ANNOTATIONS --*/
29460 }
29461 }
29462 }
29463 // mPDF 5.3.01
29464 foreach($this->internallink AS $key => $f) {
29465 if (is_array($f) && isset($f['col'])) {
29466 $last_col_bottom = 0;
29467 for ($nbc=0; $nbc<$this->NbCol; $nbc++) {
29468 if ($f['rel_y'] >= $cbr[$nbc]) { $last_col_bottom = $cbr[$nbc]; }
29469 }
29470 $yadj = ($f['rel_y'] - $f['Y']) - $last_col_bottom + $this->y0;
29471 $f['Y'] += $yadj;
29472 unset($f['col']);
29473 unset($f['rel_y']);
29474 $this->internallink[$key] = $f;
29475 }
29476 }
29477
29478 $last_col = -1;
29479 $trans_on = false;
29480 foreach($this->columnbuffer AS $key=>$s) {
29481 if (isset($s['rel_y'])) { // only process position sensitive data
29482 // Set ratio to expand y values or heights
29483 if (isset($this->ColDetails[$s['newcol']]['max_bottom']) && $this->ColDetails[$s['newcol']]['max_bottom'] && $this->ColDetails[$s['newcol']]['max_bottom']!=$this->y0) {
29484 $ratio = ($lowest_bottom_y - ($this->y0)) / ($this->ColDetails[$s['newcol']]['max_bottom'] - ($this->y0));
29485 }
29486 else { $ratio = 1; }
29487 if (($ratio > 1) && ($ratio <= $this->max_colH_correction)) {
29488 //Start Transformation
29489 $this->pages[$this->page] .= $this->StartTransform(true)."\n";
29490 $this->pages[$this->page] .= $this->transformScale(100, $ratio*100, $x='', $this->y0, true)."\n";
29491 $trans_on = true;
29492 }
29493 }
29494 // Now output the adjusted values
29495 $this->pages[$this->page] .= $s['s']."\n";
29496 if (isset($s['rel_y']) && ($ratio > 1) && ($ratio <= $this->max_colH_correction)) { // only process position sensitive data
29497 //Stop Transformation
29498 $this->pages[$this->page] .= $this->StopTransform(true)."\n";
29499 $trans_on = false;
29500 }
29501 }
29502 if ($trans_on) { $this->pages[$this->page] .= $this->StopTransform(true)."\n"; }
29503 }
29504 else { // if NOT $this->colvAlign == 'J'
29505 // Now output the adjusted values
29506 foreach($this->columnbuffer AS $s) {
29507 $this->pages[$this->page] .= $s['s']."\n";
29508 }
29509 }
29510 if ($lowest_bottom_y > 0) { $this->y = $lowest_bottom_y ; }
29511 }
29512
29513 // Columns not ended but new page -> align columns (can leave the columns alone - just tidy up the height)
29514 else if ($this->colvAlign == 'J' && $this->ColumnAdjust && !$this->keepColumns) {
29515 // calculate the lowest bottom margin
29516 $lowest_bottom_y = 0;
29517 foreach($this->columnbuffer AS $key=>$s) {
29518 // Only process output data
29519 $t = $s['s'];
29520 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)) ||
29521 (preg_match('/\d+\.\d\d+ (\d+\.\d\d+) l/',$t)) ||
29522 (preg_match('/q \d+\.\d\d+ 0 0 \d+\.\d\d+ \d+\.\d\d+ (\d+\.\d\d+) cm \/(I|FO)\d+ Do Q/',$t)) ||
29523 (preg_match('/\d+\.\d\d+ (\d+\.\d\d+) m/',$t)) ||
29524 (preg_match('/\d+\.\d\d+ (\d+\.\d\d+) \d+\.\d\d+ \d+\.\d\d+ \d+\.\d\d+ \d+\.\d\d+ c/',$t)) ) {
29525
29526 $clb = $s['y'] + $s['h'];
29527 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; }
29528 if ($clb > $lowest_bottom_y) { $lowest_bottom_y = $clb; }
29529 $this->columnbuffer[$key]['rel_y'] = $s['y']; // Marks position sensitive data to process later
29530 if ($t == 'ACROFORM') { $this->columnbuffer[$key]['s'] = ''; }
29531 }
29532 }
29533 // Adjust column length equal
29534 foreach($this->columnbuffer AS $key=>$s) {
29535 // Set ratio to expand y values or heights
29536 if (isset($this->ColDetails[$s['col']]['max_bottom']) && $this->ColDetails[$s['col']]['max_bottom']) {
29537 $ratio = ($lowest_bottom_y - ($this->y0)) / ($this->ColDetails[$s['col']]['max_bottom'] - ($this->y0));
29538 }
29539 else { $ratio = 1; }
29540 if (($ratio > 1) && ($ratio <= $this->max_colH_correction)) {
29541 $yadj = ($s['y'] - $this->y0) * ($ratio - 1);
29542
29543 // Adjust LINKS
29544 if (isset($s['rel_y'])) { // only process position sensitive data
29545 // otherwise triggers for all entries in column buffer (.e.g. formatting) and makes below adjustments more than once
29546 if (isset($this->columnLinks[$s['col']][INTVAL($s['x'])][INTVAL($s['y'])])) {
29547 $ref = $this->columnLinks[$s['col']][INTVAL($s['x'])][INTVAL($s['y'])];
29548 $this->PageLinks[$this->page][$ref][1] -= ($yadj*_MPDFK); // y value
29549 $this->PageLinks[$this->page][$ref][3] *= $ratio; // height
29550 unset($this->columnLinks[$s['col']][INTVAL($s['x'])][INTVAL($s['y'])]);
29551 }
29552 // Adjust FORM FIELDS
29553 if (isset($this->columnForms[$s['col']][INTVAL($s['x'])][INTVAL($s['y'])])) {
29554 $ref = $this->columnForms[$s['col']][INTVAL($s['x'])][INTVAL($s['y'])];
29555 $this->form->forms[$ref]['x'] += ($xadj);
29556 $this->form->forms[$ref]['y'] += ($yadj);
29557 unset($this->columnForms[$s['col']][INTVAL($s['x'])][INTVAL($s['y'])]);
29558 }
29559 /*-- ANNOTATIONS --*/
29560 if (isset($this->columnAnnots[$s['col']][INTVAL($s['x'])][INTVAL($s['y'])])) {
29561 $ref = $this->columnAnnots[$s['col']][INTVAL($s['x'])][INTVAL($s['y'])];
29562 $this->PageAnnots[$this->page][$ref]['y'] += ($yadj);
29563 unset($this->columnAnnots[$s['col']][INTVAL($s['x'])][INTVAL($s['y'])]);
29564 }
29565 /*-- END ANNOTATIONS --*/
29566 }
29567 }
29568 }
29569
29570 /*-- BOOKMARKS --*/
29571
29572 // Adjust Bookmarks
29573 foreach($this->col_BMoutlines AS $v) {
29574 $this->BMoutlines[]=array('t'=>$v['t'],'l'=>$v['l'],'y'=>$this->y0,'p'=>$v['p']);
29575 }
29576 /*-- END BOOKMARKS --*/
29577
29578 /*-- INDEX --*/
29579
29580 // Adjust Reference (index)
29581 foreach($this->col_Reference AS $v) {
29582 $Present=0;
29583 //Search the reference (AND Ref/PageNo) in the array
29584 for ($i=0;$i<count($this->Reference);$i++){
29585 if ($this->Reference[$i]['t']==$v['t']){
29586 $Present=1;
29587 if (!in_array($v['op'],$this->Reference[$i]['p'])) {
29588 $this->Reference[$i]['p'][] = $v['op'];
29589 }
29590 }
29591 }
29592 if ($Present==0) {
29593 $this->Reference[]=array('t'=>$v['t'],'p'=>array($v['op']));
29594 }
29595 }
29596 /*-- END INDEX --*/
29597
29598 /*-- TOC --*/
29599
29600 // Adjust ToC
29601 foreach($this->col_toc AS $v) {
29602 $this->tocontents->_toc[]=array('t'=>$v['t'],'l'=>$v['l'],'p'=>$v['p'],'link'=>$v['link'],'toc_id'=>$v['toc_id']);
29603 $this->links[$v['link']][1] = $this->y0;
29604 }
29605 /*-- END TOC --*/
29606 $trans_on = false;
29607 foreach($this->columnbuffer AS $key=>$s) {
29608 if (isset($s['rel_y'])) { // only process position sensitive data
29609 // Set ratio to expand y values or heights
29610 if ($this->ColDetails[$s['col']]['max_bottom']) {
29611 $ratio = ($lowest_bottom_y - ($this->y0)) / ($this->ColDetails[$s['col']]['max_bottom'] - ($this->y0));
29612 }
29613 else { $ratio = 1; }
29614 if (($ratio > 1) && ($ratio <= $this->max_colH_correction)) {
29615 //Start Transformation
29616 $this->pages[$this->page] .= $this->StartTransform(true)."\n";
29617 $this->pages[$this->page] .= $this->transformScale(100, $ratio*100, $x='', $this->y0, true)."\n";
29618 $trans_on = true;
29619 }
29620 }
29621 // Now output the adjusted values
29622 $this->pages[$this->page] .= $s['s']."\n";
29623 if (isset($s['rel_y']) && ($ratio > 1) && ($ratio <= $this->max_colH_correction)) {
29624 //Stop Transformation
29625 $this->pages[$this->page] .= $this->StopTransform(true)."\n";
29626 $trans_on = false; // mPDF 5.1.001
29627 }
29628 }
29629 if ($trans_on) { $this->pages[$this->page] .= $this->StopTransform(true)."\n"; }
29630
29631 if ($lowest_bottom_y > 0) { $this->y = $lowest_bottom_y ; }
29632 }
29633
29634
29635 // Just reproduce the page as it was
29636 else {
29637 // If page has not ended but height adjustment was disabled by custom column-break - adjust y
29638 $lowest_bottom_y = 0;
29639 if (!$this->ColActive && (!$this->ColumnAdjust || $this->keepColumns)) {
29640 // calculate the lowest bottom margin
29641 foreach($this->columnbuffer AS $key=>$s) {
29642 // Only process output data
29643 $t = $s['s'];
29644 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)) ||
29645 (preg_match('/\d+\.\d\d+ (\d+\.\d\d+) l/',$t)) ||
29646 (preg_match('/q \d+\.\d\d+ 0 0 \d+\.\d\d+ \d+\.\d\d+ (\d+\.\d\d+) cm \/(I|FO)\d+ Do Q/',$t)) ||
29647 (preg_match('/\d+\.\d\d+ (\d+\.\d\d+) m/',$t)) ||
29648 (preg_match('/\d+\.\d\d+ (\d+\.\d\d+) \d+\.\d\d+ \d+\.\d\d+ \d+\.\d\d+ \d+\.\d\d+ c/',$t)) ) {
29649
29650 $clb = $s['y'] + $s['h'];
29651 if ($clb > $this->ColDetails[$s['col']]['max_bottom']) { $this->ColDetails[$s['col']]['max_bottom'] = $clb; }
29652 if ($clb > $lowest_bottom_y) { $lowest_bottom_y = $clb; }
29653 }
29654 }
29655 }
29656 foreach($this->columnbuffer AS $key=>$s) {
29657 if ($s['s'] != 'ACROFORM')
29658 $this->pages[$this->page] .= $s['s']."\n";
29659 }
29660 if ($lowest_bottom_y > 0) { $this->y = $lowest_bottom_y ; }
29661 /*-- INDEX --*/
29662
29663 // Output Reference (index)
29664 foreach($this->col_Reference AS $v) {
29665 $Present=0;
29666 for ($i=0;$i<count($this->Reference);$i++){
29667 if ($this->Reference[$i]['t']==$v['t']){
29668 $Present=1;
29669 if (!in_array($v['op'],$this->Reference[$i]['p'])) {
29670 $this->Reference[$i]['p'][] = $v['op'];
29671 }
29672 }
29673 }
29674 if ($Present==0) {
29675 $this->Reference[]=array('t'=>$v['t'],'p'=>array($v['op']));
29676 }
29677 }
29678 /*-- END INDEX --*/
29679 /*-- BOOKMARKS --*/
29680 // Output Bookmarks
29681 foreach($this->col_BMoutlines AS $v) {
29682 $this->BMoutlines[]=array('t'=>$v['t'],'l'=>$v['l'],'y'=>$v['y'],'p'=>$v['p']);
29683 }
29684 /*-- END BOOKMARKS --*/
29685 /*-- TOC --*/
29686 // Output ToC
29687 foreach($this->col_toc AS $v) {
29688 $this->tocontents->_toc[]=array('t'=>$v['t'],'l'=>$v['l'],'p'=>$v['p'],'link'=>$v['link'],'toc_id'=>$v['toc_id']);
29689 }
29690 /*-- END TOC --*/
29691 }
29692 // mPDF 5.3.01
29693 foreach($this->internallink AS $key => $f) {
29694 if (isset($this->internallink[$key]['col'])) unset($this->internallink[$key]['col']);
29695 if (isset($this->internallink[$key]['rel_y'])) unset($this->internallink[$key]['rel_y']);
29696 }
29697
29698 $this->columnbuffer = array();
29699 $this->ColDetails = array();
29700 $this->columnLinks = array();
29701 $this->columnAnnots = array();
29702 $this->columnForms = array();
29703
29704 $this->col_Reference = array();
29705 $this->col_BMoutlines = array();
29706 $this->col_toc = array();
29707 $this->breakpoints = array();
29708 }
29709
29710 /*-- END COLUMNS --*/
29711
29712
29713 //==================================================================
29714 /*-- TABLES --*/
29715 function printcellbuffer() {
29716 if (count($this->cellBorderBuffer )) {
29717 sort($this->cellBorderBuffer);
29718 foreach($this->cellBorderBuffer AS $cbb) {
29719 // mPDF 5.3.74
29720 $cba = unpack("A16dom/nbord/A1side/ns/dbw/a6ca/A10style/dx/dy/dw/dh/dmbl/dmbr/dmrt/dmrb/dmtl/dmtr/dmlt/dmlb/dcpd/dover/", $cbb);
29721 $side = $cba['side'];
29722 $details = array();
29723 $details[$side]['dom'] = (float) $cba['dom'];
29724 $details[$side]['s'] = $cba['s'];
29725 $details[$side]['w'] = $cba['bw'];
29726 $details[$side]['c'] = $cba['ca'];
29727 $details[$side]['style'] = trim($cba['style']);
29728 $details['mbw']['BL'] = $cba['mbl'];
29729 $details['mbw']['BR'] = $cba['mbr'];
29730 $details['mbw']['RT'] = $cba['mrt'];
29731 $details['mbw']['RB'] = $cba['mrb'];
29732 $details['mbw']['TL'] = $cba['mtl'];
29733 $details['mbw']['TR'] = $cba['mtr'];
29734 $details['mbw']['LT'] = $cba['mlt'];
29735 $details['mbw']['LB'] = $cba['mlb'];
29736 $details['cellposdom'] = $cba['cpd'];
29737 $details['p'] = $side;
29738 if ($cba['over']==1) { $details[$side]['overlay'] = true; }
29739 else { $details[$side]['overlay'] = false; }
29740 $this->_tableRect($cba['x'],$cba['y'],$cba['w'],$cba['h'],$cba['bord'],$details, false, false);
29741
29742 }
29743 $this->cellBorderBuffer = array();
29744 }
29745 }
29746 //==================================================================
29747 function printtablebuffer() {
29748
29749 if (!$this->table_rotate) {
29750 $this->pages[$this->page] .= $this->tablebuffer;
29751 foreach($this->tbrot_Links AS $p => $l) {
29752 foreach($l AS $v) {
29753 $this->PageLinks[$p][] = $v;
29754 }
29755 }
29756 $this->tbrot_Links = array();
29757 /*-- ANNOTATIONS --*/
29758 foreach($this->tbrot_Annots AS $p => $l) {
29759 foreach($l AS $v) {
29760 $this->PageAnnots[$p][] = $v;
29761 }
29762 }
29763 $this->tbrot_Annots = array();
29764 /*-- END ANNOTATIONS --*/
29765
29766 /*-- INDEX --*/
29767 // Output Reference (index)
29768 foreach($this->tbrot_Reference AS $v) {
29769 $Present=0;
29770 for ($i=0;$i<count($this->Reference);$i++){
29771 if ($this->Reference[$i]['t']==$v['t']){
29772 $Present=1;
29773 if (!in_array($v['op'],$this->Reference[$i]['p'])) {
29774 $this->Reference[$i]['p'][] = $v['op'];
29775 }
29776 }
29777 }
29778 if ($Present==0) {
29779 $this->Reference[]=array('t'=>$v['t'],'p'=>array($v['op']));
29780 }
29781 }
29782 $this->tbrot_Reference = array();
29783 /*-- END INDEX --*/
29784
29785 /*-- BOOKMARKS --*/
29786 // Output Bookmarks
29787 foreach($this->tbrot_BMoutlines AS $v) {
29788 $this->BMoutlines[]=array('t'=>$v['t'],'l'=>$v['l'],'y'=>$v['y'],'p'=>$v['p']);
29789 }
29790 $this->tbrot_BMoutlines = array();
29791 /*-- END BOOKMARKS --*/
29792
29793 /*-- TOC --*/
29794 // Output ToC
29795 foreach($this->tbrot_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 }
29798 $this->tbrot_toc = array();
29799 /*-- END TOC --*/
29800
29801 return;
29802 }
29803
29804 // else if rotated
29805 $lm = $this->lMargin + $this->blk[$this->blklvl]['outer_left_margin'] + $this->blk[$this->blklvl]['border_left']['w'] + $this->blk[$this->blklvl]['padding_left'];
29806 $pw = $this->blk[$this->blklvl]['inner_width'];
29807 //Start Transformation
29808 $this->pages[$this->page] .= $this->StartTransform(true)."\n";
29809
29810 if ($this->table_rotate > 1) { // clockwise
29811 if ($this->tbrot_align == 'L') {
29812 $xadj = $this->tbrot_h ; // align L (as is)
29813 }
29814 else if ($this->tbrot_align == 'R') {
29815 $xadj = $lm-$this->tbrot_x0+($pw) ; // align R
29816 }
29817 else {
29818 $xadj = $lm-$this->tbrot_x0+(($pw + $this->tbrot_h)/2) ; // align C
29819 }
29820 $yadj = 0;
29821 }
29822 else { // anti-clockwise
29823 if ($this->tbrot_align == 'L') {
29824 $xadj = 0 ; // align L (as is)
29825 }
29826 else if ($this->tbrot_align == 'R') {
29827 $xadj = $lm-$this->tbrot_x0+($pw - $this->tbrot_h) ; // align R
29828 }
29829 else {
29830 $xadj = $lm-$this->tbrot_x0+(($pw - $this->tbrot_h)/2) ; // align C
29831 }
29832 $yadj = $this->tbrot_w;
29833 }
29834
29835
29836 $this->pages[$this->page] .= $this->transformTranslate($xadj, $yadj , true)."\n";
29837 $this->pages[$this->page] .= $this->transformRotate($this->table_rotate, $this->tbrot_x0 , $this->tbrot_y0 , true)."\n";
29838
29839 // Now output the adjusted values
29840 $this->pages[$this->page] .= $this->tablebuffer;
29841
29842
29843 foreach($this->tbrot_Links AS $p => $l) {
29844 foreach($l AS $v) {
29845 $w = $v[2]/_MPDFK;
29846 $h = $v[3]/_MPDFK;
29847 $ax = ($v[0]/_MPDFK) - $this->tbrot_x0;
29848 $ay = (($this->hPt-$v[1])/_MPDFK) - $this->tbrot_y0;
29849 if ($this->table_rotate > 1) { // clockwise
29850 $bx = $this->tbrot_x0+$xadj-$ay-$h;
29851 $by = $this->tbrot_y0+$yadj+$ax;
29852 }
29853 else {
29854 $bx = $this->tbrot_x0+$xadj+$ay;
29855 $by = $this->tbrot_y0+$yadj-$ax-$w;
29856 }
29857 $v[0] = $bx*_MPDFK;
29858 $v[1] = ($this->h-$by)*_MPDFK;
29859 $v[2] = $h*_MPDFK; // swap width and height
29860 $v[3] = $w*_MPDFK;
29861 $this->PageLinks[$p][] = $v;
29862 }
29863 }
29864 $this->tbrot_Links = array();
29865 // mPDF 5.3.01
29866 foreach($this->internallink AS $key => $f) {
29867 if (is_array($f) && isset($f['tbrot'])) {
29868 $f['Y'] = $this->tbrot_y0;
29869 $f['PAGE'] = $this->page;
29870 unset($f['tbrot']);
29871 $this->internallink[$key] = $f;
29872 }
29873 }
29874 /*-- ANNOTATIONS --*/
29875 foreach($this->tbrot_Annots AS $p => $l) {
29876 foreach($l AS $v) {
29877 $ax = abs($v['x']) - $this->tbrot_x0; // abs because -ve values are internally set and held for reference if annotMargin set
29878 $ay = $v['y'] - $this->tbrot_y0;
29879 if ($this->table_rotate > 1) { // clockwise
29880 $bx = $this->tbrot_x0+$xadj-$ay;
29881 $by = $this->tbrot_y0+$yadj+$ax;
29882 }
29883 else {
29884 $bx = $this->tbrot_x0+$xadj+$ay;
29885 $by = $this->tbrot_y0+$yadj-$ax;
29886 }
29887 if ($v['x'] < 0) {
29888 $v['x'] = -$bx;
29889 }
29890 else {
29891 $v['x'] = $bx;
29892 }
29893 $v['y'] = ($by);
29894 $this->PageAnnots[$p][] = $v;
29895 }
29896 }
29897 $this->tbrot_Annots = array();
29898 /*-- END ANNOTATIONS --*/
29899
29900
29901 /*-- BOOKMARKS --*/
29902
29903 // Adjust Bookmarks
29904 foreach($this->tbrot_BMoutlines AS $v) {
29905 $v['y'] = $this->tbrot_y0;
29906 $this->BMoutlines[]=array('t'=>$v['t'],'l'=>$v['l'],'y'=>$v['y'],'p'=>$this->page);
29907 }
29908 /*-- END BOOKMARKS --*/
29909
29910 /*-- INDEX --*/
29911
29912 // Adjust Reference (index)
29913 foreach($this->tbrot_Reference AS $v) {
29914 $Present=0;
29915 //Search the reference (AND Ref/PageNo) in the array
29916 for ($i=0;$i<count($this->Reference);$i++){
29917 if ($this->Reference[$i]['t']==$v['t']){
29918 $Present=1;
29919 if (!in_array($this->page,$this->Reference[$i]['p'])) {
29920 $this->Reference[$i]['p'][] = $this->page;
29921 }
29922 }
29923 }
29924 if ($Present==0) {
29925 $this->Reference[]=array('t'=>$v['t'],'p'=>array($this->page));
29926 }
29927 }
29928 /*-- END INDEX --*/
29929
29930 /*-- TOC --*/
29931
29932 // Adjust ToC - uses document page number
29933 foreach($this->tbrot_toc AS $v) {
29934 $this->tocontents->_toc[]=array('t'=>$v['t'],'l'=>$v['l'],'p'=>$this->page,'link'=>$v['link'],'toc_id'=>$v['toc_id']);
29935 $this->links[$v['link']][1] = $this->tbrot_y0;
29936 }
29937 /*-- END TOC --*/
29938
29939
29940
29941 $this->tbrot_Reference = array();
29942 $this->tbrot_BMoutlines = array();
29943 $this->tbrot_toc = array();
29944
29945 //Stop Transformation
29946 $this->pages[$this->page] .= $this->StopTransform(true)."\n";
29947
29948
29949 $this->y = $this->tbrot_y0 + $this->tbrot_w;
29950 $this->x = $this->lMargin;
29951
29952 $this->tablebuffer = '';
29953 }
29954
29955 //==================================================================
29956 // Keep-with-table This buffers contents of h1-6 to keep on page with table
29957 function printkwtbuffer() {
29958 if (!$this->kwt_moved) {
29959 foreach($this->kwt_buffer AS $s) { $this->pages[$this->page] .= $s['s']."\n"; }
29960 foreach($this->kwt_Links AS $p => $l) {
29961 foreach($l AS $v) {
29962 $this->PageLinks[$p][] = $v;
29963 }
29964 }
29965 $this->kwt_Links = array();
29966 /*-- ANNOTATIONS --*/
29967 foreach($this->kwt_Annots AS $p => $l) {
29968 foreach($l AS $v) {
29969 $this->PageAnnots[$p][] = $v;
29970 }
29971 }
29972 $this->kwt_Annots = array();
29973 /*-- END ANNOTATIONS --*/
29974
29975 /*-- INDEX --*/
29976 // Output Reference (index)
29977 foreach($this->kwt_Reference AS $v) {
29978 $Present=0;
29979 for ($i=0;$i<count($this->Reference);$i++){
29980 if ($this->Reference[$i]['t']==$v['t']){
29981 $Present=1;
29982 if (!in_array($v['op'],$this->Reference[$i]['p'])) {
29983 $this->Reference[$i]['p'][] = $v['op'];
29984 }
29985 }
29986 }
29987 if ($Present==0) {
29988 $this->Reference[]=array('t'=>$v['t'],'p'=>array($v['op']));
29989 }
29990 }
29991 $this->kwt_Reference = array();
29992 /*-- END INDEX --*/
29993
29994 /*-- BOOKMARKS --*/
29995 // Output Bookmarks
29996 foreach($this->kwt_BMoutlines AS $v) {
29997 $this->BMoutlines[]=array('t'=>$v['t'],'l'=>$v['l'],'y'=>$v['y'],'p'=>$v['p']);
29998 }
29999 $this->kwt_BMoutlines = array();
30000 /*-- END BOOKMARKS --*/
30001
30002 /*-- TOC --*/
30003 // Output ToC
30004 foreach($this->kwt_toc AS $v) {
30005 $this->tocontents->_toc[]=array('t'=>$v['t'],'l'=>$v['l'],'p'=>$v['p'],'link'=>$v['link'],'toc_id'=>$v['toc_id']);
30006 }
30007 $this->kwt_toc = array();
30008 /*-- END TOC --*/
30009
30010 return;
30011 }
30012
30013 //Start Transformation
30014 $this->pages[$this->page] .= $this->StartTransform(true)."\n";
30015 $xadj = $this->lMargin - $this->kwt_x0 ;
30016 //$yadj = $this->y - $this->kwt_y0 ;
30017 $yadj = $this->tMargin - $this->kwt_y0 ;
30018
30019 $this->pages[$this->page] .= $this->transformTranslate($xadj, $yadj , true)."\n";
30020
30021 // Now output the adjusted values
30022 foreach($this->kwt_buffer AS $s) { $this->pages[$this->page] .= $s['s']."\n"; }
30023
30024 // Adjust hyperLinks
30025 foreach($this->kwt_Links AS $p => $l) {
30026 foreach($l AS $v) {
30027 $bx = $this->kwt_x0+$xadj;
30028 $by = $this->kwt_y0+$yadj;
30029 $v[0] = $bx*_MPDFK;
30030 $v[1] = ($this->h-$by)*_MPDFK;
30031 $this->PageLinks[$p][] = $v;
30032 }
30033 }
30034 // mPDF 5.3.01
30035 foreach($this->internallink AS $key => $f) {
30036 if (is_array($f) && isset($f['kwt'])) {
30037 $f['Y'] += $yadj;
30038 $f['PAGE'] = $this->page;
30039 unset($f['kwt']);
30040 $this->internallink[$key] = $f;
30041 }
30042 }
30043 /*-- ANNOTATIONS --*/
30044 foreach($this->kwt_Annots AS $p => $l) {
30045 foreach($l AS $v) {
30046 $bx = $this->kwt_x0+$xadj;
30047 $by = $this->kwt_y0+$yadj;
30048 if ($v['x'] < 0) {
30049 $v['x'] = -$bx;
30050 }
30051 else {
30052 $v['x'] = $bx;
30053 }
30054 $v['y'] = $by;
30055 $this->PageAnnots[$p][] = $v;
30056 }
30057 }
30058 /*-- END ANNOTATIONS --*/
30059
30060 /*-- BOOKMARKS --*/
30061
30062 // Adjust Bookmarks
30063 foreach($this->kwt_BMoutlines AS $v) {
30064 if ($v['y'] != 0) { $v['y'] += $yadj; }
30065 $this->BMoutlines[]=array('t'=>$v['t'],'l'=>$v['l'],'y'=>$v['y'],'p'=>$this->page);
30066 }
30067 /*-- END BOOKMARKS --*/
30068
30069 /*-- INDEX --*/
30070
30071 // Adjust Reference (index)
30072 foreach($this->kwt_Reference AS $v) {
30073 $Present=0;
30074 //Search the reference (AND Ref/PageNo) in the array
30075 for ($i=0;$i<count($this->Reference);$i++){
30076 if ($this->Reference[$i]['t']==$v['t']){
30077 $Present=1;
30078 if (!in_array($this->page,$this->Reference[$i]['p'])) {
30079 $this->Reference[$i]['p'][] = $this->page;
30080 }
30081 }
30082 }
30083 if ($Present==0) {
30084 $this->Reference[]=array('t'=>$v['t'],'p'=>array($this->page));
30085 }
30086 }
30087 /*-- END INDEX --*/
30088
30089 /*-- TOC --*/
30090
30091 // Adjust ToC
30092 foreach($this->kwt_toc AS $v) {
30093 $this->tocontents->_toc[]=array('t'=>$v['t'],'l'=>$v['l'],'p'=>$this->page,'link'=>$v['link'],'toc_id'=>$v['toc_id']);
30094 $this->links[$v['link']][0] = $this->page;
30095 $this->links[$v['link']][1] += $yadj;
30096 }
30097 /*-- END TOC --*/
30098
30099
30100 $this->kwt_Links = array();
30101 $this->kwt_Annots = array();
30102
30103 $this->kwt_Reference = array();
30104 $this->kwt_BMoutlines = array();
30105 $this->kwt_toc = array();
30106 //Stop Transformation
30107 $this->pages[$this->page] .= $this->StopTransform(true)."\n";
30108
30109 $this->kwt_buffer = array();
30110
30111 $this->y += $this->kwt_height;
30112 }
30113
30114 /*-- END TABLES --*/
30115
30116
30117 //==================================================================
30118
30119 function printfloatbuffer() {
30120 if (count($this->floatbuffer)) {
30121 $this->objectbuffer = $this->floatbuffer;
30122 $this->printobjectbuffer(false);
30123 $this->objectbuffer = array();
30124 $this->floatbuffer = array();
30125 $this->floatmargins = array();
30126 }
30127 }
30128 //==================================================================
30129
30130 function printdivbuffer() {
30131 $p1 = $this->blk[$this->blklvl]['startpage'];
30132 $p2 = $this->page;
30133 $bottom[$p1] = $this->ktBlock[$p1]['bottom_margin'];
30134 $bottom[$p2] = $this->y; // $this->ktBlock[$p2]['bottom_margin'];
30135 $top[$p1] = $this->kt_y00;
30136
30137 $top2 = $this->h;
30138 foreach($this->divbuffer AS $key=>$s) {
30139 if ($s['page'] == $p2) {
30140 $top2 = MIN($s['y'], $top2);
30141 }
30142 }
30143 $top[$p2] = $top2;
30144 $height[$p1] = ($bottom[$p1] - $top[$p1]);
30145 $height[$p2] = ($bottom[$p2] - $top[$p2]);
30146 $xadj[$p1] = $this->MarginCorrection;
30147 $yadj[$p1] = -($top[$p1] - $top[$p2]);
30148 $xadj[$p2] = 0;
30149 $yadj[$p2] = $height[$p1];
30150
30151 // Output without any transformation
30152 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) {
30153 foreach($this->divbuffer AS $s) { $this->pages[$s['page']] .= $s['s']."\n"; }
30154 foreach($this->ktLinks AS $p => $l) {
30155 foreach($l AS $v) {
30156 $this->PageLinks[$p][] = $v;
30157 }
30158 }
30159 foreach($this->ktForms AS $key => $f) {
30160 $this->form->forms[$f['n']] = $f;
30161 }
30162 /*-- ANNOTATIONS --*/
30163 foreach($this->ktAnnots AS $p => $l) {
30164 foreach($l AS $v) {
30165 $this->PageAnnots[$p][] = $v;
30166 }
30167 }
30168 /*-- END ANNOTATIONS --*/
30169 /*-- INDEX --*/
30170 // Adjust Reference (index)
30171 foreach($this->ktReference AS $v) {
30172 $Present=0;
30173 //Search the reference (AND Ref/PageNo) in the array
30174 for ($i=0;$i<count($this->Reference);$i++){
30175 if ($this->Reference[$i]['t']==$v['t']){
30176 $Present=1;
30177 if (!in_array($p2,$this->Reference[$i]['p'])) {
30178 $this->Reference[$i]['p'][] = $p2;
30179 }
30180 }
30181 }
30182 //If not found, add it
30183 if ($Present==0) {
30184 $this->Reference[]=array('t'=>$v['t'],'p'=>array($p2));
30185 }
30186 }
30187 /*-- END INDEX --*/
30188
30189 /*-- BOOKMARKS --*/
30190 // Adjust Bookmarks
30191 foreach($this->ktBMoutlines AS $v) {
30192 $this->BMoutlines[]=array('t'=>$v['t'],'l'=>$v['l'],'y'=>$v['y'],'p'=>$v['p']);
30193 }
30194 /*-- END BOOKMARKS --*/
30195
30196 /*-- TOC --*/
30197 // Adjust ToC
30198 foreach($this->_kttoc AS $v) {
30199 $this->tocontents->_toc[]=array('t'=>$v['t'],'l'=>$v['l'],'p'=>$v['p'],'link'=>$v['link'],'toc_id'=>$v['toc_id']);
30200 }
30201 /*-- END TOC --*/
30202
30203 $this->divbuffer = array();
30204 $this->ktLinks = array();
30205 $this->ktAnnots = array();
30206 $this->ktForms = array();
30207 $this->ktBlock = array();
30208 $this->ktReference = array();
30209 $this->ktBMoutlines = array();
30210 $this->_kttoc = array();
30211 $this->keep_block_together = 0;
30212 return;
30213 }
30214 else {
30215 $np = '';
30216 $pre = '';
30217 $ispre = true;
30218 foreach($this->divbuffer AS $key=>$s) {
30219 // callback function
30220 $t = $s['s'];
30221 $p = $s['page'];
30222 if (preg_match('/(___PAGE___START'.date('jY').')/', $t)) { $ispre = false; }
30223 else if (preg_match('/(___HEADER___MARKER'.date('jY').')/', $t)) {
30224 $np .= $t."\n".$pre;
30225 continue;
30226 }
30227 else {
30228 $t = preg_replace('/BT (\d+\.\d\d+) (\d+\.\d\d+) Td/e',"\$this->blockAdjust('Td',_MPDFK,$xadj[$p],$yadj[$p],'\\1','\\2')",$t);
30229 $t = preg_replace('/(\d+\.\d\d+) (\d+\.\d\d+) (\d+\.\d\d+) ([\-]{0,1}\d+\.\d\d+) re/e',"\$this->blockAdjust('re',_MPDFK,$xadj[$p],$yadj[$p],'\\1','\\2','\\3','\\4')",$t);
30230 $t = preg_replace('/(\d+\.\d\d+) (\d+\.\d\d+) l/e',"\$this->blockAdjust('l',_MPDFK,$xadj[$p],$yadj[$p],'\\1','\\2')",$t);
30231 $t = preg_replace('/q (\d+\.\d\d+) 0 0 (\d+\.\d\d+) (\d+\.\d\d+) (\d+\.\d\d+) cm \/(I|FO)/e',"\$this->blockAdjust('img',_MPDFK,$xadj[$p],$yadj[$p],'\\1','\\2','\\3','\\4','\\5')",$t);
30232 $t = preg_replace('/(\d+\.\d\d+) (\d+\.\d\d+) m/e',"\$this->blockAdjust('draw',_MPDFK,$xadj[$p],$yadj[$p],'\\1','\\2')",$t);
30233 $t = preg_replace('/(\d+\.\d\d+) (\d+\.\d\d+) (\d+\.\d\d+) (\d+\.\d\d+) (\d+\.\d\d+) (\d+\.\d\d+) c/e',"\$this->blockAdjust('bezier',_MPDFK,$xadj[$p],$yadj[$p],'\\1','\\2','\\3','\\4','\\5','\\6')",$t);
30234 }
30235 if ($ispre) $pre .= $t."\n";
30236 else $np .= $t."\n";
30237 }
30238 if ($ispre && $pre) $np = $pre ."\n". $np;
30239 $this->pages[$this->page] .= $np;
30240
30241 // Adjust hyperLinks
30242 foreach($this->ktLinks AS $p => $l) {
30243 foreach($l AS $v) {
30244 $v[0] += ($xadj[$p]*_MPDFK);
30245 $v[1] -= ($yadj[$p]*_MPDFK);
30246 $this->PageLinks[$p2][] = $v;
30247 }
30248 }
30249 foreach($this->ktForms AS $key => $f) {
30250 $p = $f['page'];
30251 $f['x'] += ($xadj[$p]);
30252 $f['y'] += ($yadj[$p]);
30253 $f['page'] = $p2;
30254 $this->form->forms[$f['n']] = $f;
30255 }
30256 // mPDF 5.3.01
30257 foreach($this->internallink AS $key => $f) {
30258 if (is_array($f) && isset($f['kt'])) {
30259 $f['Y'] += ($yadj[$f['PAGE']]);
30260 $f['PAGE'] = $p2;
30261 unset($f['kt']);
30262 $this->internallink[$key] = $f;
30263 }
30264 }
30265 /*-- ANNOTATIONS --*/
30266 foreach($this->ktAnnots AS $p => $l) {
30267 foreach($l AS $v) {
30268 if ($v['x']>0) { $v['x'] += $xadj[$p]; }
30269 else if ($v['x']<0) { $v['x'] -= $xadj[$p]; }
30270 $v['y'] += $yadj[$p];
30271 $this->PageAnnots[$p2][] = $v;
30272 }
30273 }
30274 /*-- END ANNOTATIONS --*/
30275
30276 /*-- BOOKMARKS --*/
30277 // Adjust Bookmarks
30278 foreach($this->ktBMoutlines AS $v) {
30279 if ($v['y'] != 0) { $v['y'] += ($yadj[$v['p']]); }
30280 $this->BMoutlines[]=array('t'=>$v['t'],'l'=>$v['l'],'y'=>$v['y'],'p'=>$p2);
30281 }
30282 /*-- END BOOKMARKS --*/
30283
30284 /*-- INDEX --*/
30285 // Adjust Reference (index)
30286 foreach($this->ktReference AS $v) {
30287 $Present=0;
30288 //Search the reference (AND Ref/PageNo) in the array
30289 for ($i=0;$i<count($this->Reference);$i++){
30290 if ($this->Reference[$i]['t']==$v['t']){
30291 $Present=1;
30292 if (!in_array($p2,$this->Reference[$i]['p'])) {
30293 $this->Reference[$i]['p'][] = $p2;
30294 }
30295 }
30296 }
30297 //If not found, add it
30298 if ($Present==0) {
30299 $this->Reference[]=array('t'=>$v['t'],'p'=>array($p2));
30300 }
30301 }
30302 /*-- END INDEX --*/
30303
30304 /*-- TOC --*/
30305 // Adjust ToC
30306 foreach($this->_kttoc AS $v) {
30307 $this->tocontents->_toc[]=array('t'=>$v['t'],'l'=>$v['l'],'p'=>$p2,'link'=>$v['link'],'toc_id'=>$v['toc_id']);
30308 $this->links[$v['link']][0] = $p2;
30309 $this->links[$v['link']][1] += $yadj[$v['p']]; // mPDF 5.3.02
30310 }
30311 /*-- END TOC --*/
30312
30313 $this->y = $top[$p2] + $height[$p1] + $height[$p2];
30314 $this->x = $this->lMargin;
30315
30316 $this->divbuffer = array();
30317 $this->ktLinks = array();
30318 $this->ktAnnots = array();
30319 $this->ktForms = array();
30320 $this->ktBlock = array();
30321 $this->ktReference = array();
30322 $this->ktBMoutlines = array();
30323 $this->_kttoc = array();
30324 $this->keep_block_together = 0;
30325 }
30326 }
30327
30328
30329 //==================================================================
30330 // Added ELLIPSES and CIRCLES
30331 function Circle($x,$y,$r,$style='S') {
30332 $this->Ellipse($x,$y,$r,$r,$style);
30333 }
30334
30335 function Ellipse($x,$y,$rx,$ry,$style='S') {
30336 if($style=='F') { $op='f'; }
30337 elseif($style=='FD' or $style=='DF') { $op='B'; }
30338 else { $op='S'; }
30339 $lx=4/3*(M_SQRT2-1)*$rx;
30340 $ly=4/3*(M_SQRT2-1)*$ry;
30341 $h=$this->h;
30342 $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));
30343 $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));
30344 $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));
30345 $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));
30346 }
30347
30348 /*-- DIRECTW --*/
30349 // Added adaptation of shaded_box = AUTOSIZE-TEXT
30350 function AutosizeText($text,$w,$font,$style,$szfont=72) {
30351 $text = $this->purify_utf8_text($text);
30352 if ($this->text_input_as_HTML) {
30353 $text = $this->all_entities_to_utf8($text);
30354 }
30355 if ($this->usingCoreFont) { $text = mb_convert_encoding($text,$this->mb_enc,'UTF-8'); } // mPDF 5.3.22
30356 $text = ' '.$text.' ';
30357 $width = $this->ConvertSize($w);
30358 $loop = 0;
30359 while ( $loop == 0 ) {
30360 $this->SetFont($font,$style,$szfont);
30361 $sz = $this->GetStringWidth( $text );
30362 if ( $sz > $w ) { $szfont --; }
30363 else { $loop ++; }
30364 }
30365 $this->SetFont($font,$style,$szfont);
30366 $this->Cell($w, 0, $text, 0, 0, "C");
30367 }
30368 /*-- END DIRECTW --*/
30369
30370
30371
30372
30373
30374 // ====================================================
30375 // ====================================================
30376 /*-- RTL --*/
30377 function reverse_letters($str) {
30378 $str = strtr($str, '{}[]()', '}{][)(');
30379 return $this->mb_strrev($str, $this->mb_enc);
30380 }
30381
30382 function magic_reverse_dir(&$chunk, $join=true, $dir) {
30383 if ($this->usingCoreFont) { return 0; }
30384 if ($this->biDirectional) {
30385 // Change Arabic + Persian. to Presentation Forms
30386 if ($join) {
30387 $chunk = preg_replace("/([".$this->pregRTLchars."]+)/ue", '$this->ArabJoin(stripslashes(\'\\1\'))', $chunk );
30388 }
30389 $contains_rtl = false;
30390 $all_rtl = true;
30391 $initSpace = false;
30392 $endSpace = false;
30393 $nonDirchars = "\x{A0}\"\'\(\)\{\}\[\].,:\-=";
30394 if (preg_match("/[".$this->pregRTLchars."]/u",$chunk)) { // Chunk contains RTL characters
30395 if (preg_match("/^[ ]/",$chunk)) { $initSpace = true; $chunk = preg_replace("/^[ ]/",'',$chunk); }
30396 if (preg_match("/[ ]$/",$chunk)) { $endSpace = true; $chunk = preg_replace("/[ ]$/",'',$chunk); }
30397 if (preg_match("/[^".$this->pregRTLchars.$nonDirchars." ]/u",$chunk)) { // Chunk also contains LTR characters
30398 $all_rtl = false;
30399 if ($dir == 'rtl') {
30400 $chunk = preg_replace("/([^".$this->pregRTLchars.$nonDirchars."][".$nonDirchars."]*) ([".$nonDirchars."]*[^".$this->pregRTLchars.$nonDirchars."])/u","\\1\x07\\2",$chunk);
30401 }
30402 $chunk = preg_replace("/([".$this->pregRTLchars."][".$nonDirchars."]*) ([".$nonDirchars."]*[".$this->pregRTLchars."])/u","\\1\x07\\2",$chunk);
30403 $bits = explode(' ',$chunk);
30404 foreach($bits AS $bitkey=>$bit) {
30405 $bit = preg_replace("/\x07/"," ",$bit);
30406 if (preg_match("/^[".$this->pregRTLchars.$nonDirchars." ]*$/u",$bit)) {
30407 $bits[$bitkey] = $this->reverse_letters($bit);
30408 }
30409 else if (preg_match("/[".$this->pregRTLchars."]/u",$bit)) {
30410 if ($dir == 'rtl') {
30411 $bit = preg_replace("/([^".$this->pregRTLchars.$nonDirchars." ])([".$nonDirchars."]*[".$this->pregRTLchars."])/u","\\1\x07\\2",$bit );
30412 $bit = preg_replace("/([".$this->pregRTLchars."][".$nonDirchars."]*)([^".$this->pregRTLchars.$nonDirchars." ])/u","\\1\x07\\2",$bit );
30413 }
30414 else {
30415 $bit = preg_replace("/([^".$this->pregRTLchars." ][".$nonDirchars."]*)([".$this->pregRTLchars." ])/u","\\1\x07\\2",$bit );
30416 $bit = preg_replace("/([".$this->pregRTLchars." ])([".$nonDirchars."]*[^".$this->pregRTLchars." ])/u","\\1\x07\\2",$bit );
30417 }
30418 $sbits = explode("\x07",$bit );
30419 foreach($sbits AS $sbitkey=>$sbit) {
30420 $sbit = preg_replace("/\x07/","",$sbit);
30421 if (preg_match("/^[".$this->pregRTLchars.$nonDirchars." ]*$/u",$sbit)) {
30422 $sbits[$sbitkey] = $this->reverse_letters($sbit);
30423 }
30424 else if (preg_match("/[".$this->pregRTLchars."]/u",$sbit) && $dir=='rtl') {
30425 $sbits[$sbitkey] = $this->reverse_letters($sbit);
30426 }
30427 else {
30428 $sbits[$sbitkey] = $sbit;
30429 }
30430 }
30431 if ($dir == 'rtl') { $sbits = array_reverse($sbits,false); }
30432 $bits[$bitkey] = implode('',$sbits);
30433 }
30434 else if (preg_match("/[".$this->pregRTLchars."]/u",$bit) && $dir=='rtl') {
30435 $bits[$bitkey] = $this->reverse_letters($bit);
30436 }
30437 else {
30438 $bits[$bitkey] = $bit;
30439 }
30440 }
30441 if ($dir == 'rtl') { $bits = array_reverse($bits,false); }
30442 $chunk = implode(' ',$bits);
30443 }
30444 else { $chunk = $this->reverse_letters($chunk); }
30445 $contains_rtl = true;
30446
30447 // Un-Reverse numerals back to ltr
30448 $chunk = preg_replace("/([\x{0660}-\x{0669}]+)/ue", '$this->reverse_letters(\'\\1\')', $chunk );
30449
30450 if ($dir == 'rtl') {
30451 if ($endSpace) { $chunk = ' '.$chunk; }
30452 if ($initSpace) { $chunk .= ' '; }
30453 }
30454 else {
30455 if ($initSpace) { $chunk = ' '.$chunk; }
30456 if ($endSpace) { $chunk .= ' '; }
30457 }
30458 }
30459 else { $all_rtl = false; }
30460 if ($all_rtl) { return 2; }
30461 else if ($contains_rtl) { return 1; }
30462 else { return 0; }
30463 }
30464 return 0;
30465 }
30466 /*-- END RTL --*/
30467
30468 //
30469 // ****************************
30470 // ****************************
30471
30472
30473 function SetSubstitutions() {
30474 $subsarray = array();
30475 @include(_MPDF_PATH.'includes/subs_win-1252.php');
30476 $this->substitute = array();
30477 foreach($subsarray AS $key => $val) {
30478 $this->substitute[code2utf($key)] = $val;
30479 }
30480 }
30481
30482
30483 function SubstituteChars($html) {
30484 // only substitute characters between tags
30485 if (count($this->substitute)) {
30486 $a=preg_split('/(<.*?>)/ms',$html,-1,PREG_SPLIT_DELIM_CAPTURE);
30487 $html = '';
30488 foreach($a as $i => $e) {
30489 if($i%2==0) {
30490 $e = strtr($e, $this->substitute);
30491 }
30492 $html .= $e;
30493 }
30494 }
30495 return $html;
30496 }
30497
30498
30499 function SubstituteCharsSIP(&$writehtml_a, &$writehtml_i, &$writehtml_e) {
30500 if (preg_match("/^(.*?)([\x{20000}-\x{2FFFF}]+)(.*)/u", $writehtml_e, $m)) {
30501 if (isset($this->CurrentFont['sipext']) && $this->CurrentFont['sipext']) {
30502 $font = $this->CurrentFont['sipext'];
30503 if (!in_array($font, $this->available_unifonts)) { return 0; }
30504 $writehtml_a[$writehtml_i] = $writehtml_e = $m[1];
30505 array_splice($writehtml_a, $writehtml_i+1, 0, array('span style="font-family: '.$font.'"', $m[2], '/span', $m[3]));
30506 $this->subPos = $writehtml_i;
30507 return 4;
30508 }
30509 }
30510 return 0;
30511 }
30512
30513 // mPDF 5.3.22
30514 // If core font is selected in document which is not onlyCoreFonts - substitute with non-core font
30515 function SubstituteCharsNonCore(&$writehtml_a, &$writehtml_i, &$writehtml_e) {
30516 if (mb_convert_encoding(mb_convert_encoding($writehtml_e, $this->mb_enc, "UTF-8"), "UTF-8", $this->mb_enc) == $writehtml_e) {
30517 return 0;
30518 }
30519 $cw = &$this->CurrentFont['cw'];
30520 $unicode = $this->UTF8StringToArray($writehtml_e, false);
30521 $start = -1;
30522 $end = 0;
30523 $flag = 0;
30524 $ftype = '';
30525 $u = array();
30526 if (!$this->subArrMB) {
30527 include(_MPDF_PATH.'includes/subs_core.php');
30528 $this->subArrMB['a'] = $aarr;
30529 $this->subArrMB['s'] = $sarr;
30530 $this->subArrMB['z'] = $zarr;
30531 }
30532 foreach($unicode AS $c => $char) {
30533 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)) {
30534 if ($flag==0) { $start=$c; }
30535 $flag=1;
30536 $u[] = $char;
30537 }
30538 else if ($flag>0) { $end=$c-1; break; }
30539 }
30540 if ($flag>0 && !$end) { $end=count($unicode)-1; }
30541 if ($start==-1) { return 0; }
30542 // TRY IN BACKUP SUBS FONT
30543 if (!is_array($this->backupSubsFont)) { $this->backupSubsFont = array("$this->backupSubsFont"); }
30544 foreach($this->backupSubsFont AS $bsfctr=>$bsf) {
30545 if ($this->fonttrans[$bsf] == 'chelvetica' || $this->fonttrans[$bsf] == 'ctimes' || $this->fonttrans[$bsf] == 'ccourier') { continue; }
30546 $font = $bsf;
30547 unset($cw);
30548 $cw = '';
30549 if (isset($this->fonts[$font])) { $cw = &$this->fonts[$font]['cw']; }
30550 else if (file_exists(_MPDF_TTFONTDATAPATH.$font.'.cw.dat')) { $cw = @file_get_contents(_MPDF_TTFONTDATAPATH.$font.'.cw.dat'); }
30551 else {
30552
30553 $prevFontFamily = $this->FontFamily;
30554 $prevFontStyle = $this->currentfontstyle;
30555 $prevFontSizePt = $this->FontSizePt;
30556 $this->SetFont($bsf, '', '', false);
30557 $cw = @file_get_contents(_MPDF_TTFONTDATAPATH.$font.'.cw.dat');
30558 $this->SetFont($prevFontFamily, $prevFontStyle, $prevFontSizePt, false);
30559 }
30560 if (!$cw) { continue; }
30561 $l = 0;
30562 foreach($u AS $char) {
30563 if ($char == 173 || $this->_charDefined($cw,$char) || ($char>1536 && $char<1791) || ($char>2304 && $char<3455 )) {
30564 $l++;
30565 }
30566 else {
30567 if ($l==0 && $bsfctr == (count($this->backupSubsFont)-1)) { // Not found even in last backup font
30568 $cont = mb_substr($writehtml_e, $start+1);
30569 $writehtml_e = mb_substr($writehtml_e, 0, $start+1, 'UTF-8');
30570 array_splice($writehtml_a, $writehtml_i+1, 0, array('', $cont));
30571 $this->subPos = $writehtml_i+1;
30572 return 2;
30573 }
30574 else { break; }
30575 }
30576 }
30577 if ($l > 0) {
30578 $patt = mb_substr($writehtml_e, $start, $l, 'UTF-8');
30579 if (preg_match("/(.*?)(".preg_quote($patt,'/').")(.*)/u", $writehtml_e, $m)) {
30580 $writehtml_e = $m[1];
30581 array_splice($writehtml_a, $writehtml_i+1, 0, array('span style="font-family: '.$font.'"', $m[2], '/span', $m[3]));
30582 $this->subPos = $writehtml_i+3;
30583 return 4;
30584 }
30585 }
30586 }
30587
30588 unset($cw);
30589 return 0;
30590 }
30591
30592
30593 function SubstituteCharsMB(&$writehtml_a, &$writehtml_i, &$writehtml_e) {
30594 $cw = &$this->CurrentFont['cw'];
30595 $unicode = $this->UTF8StringToArray($writehtml_e, false);
30596 $start = -1;
30597 $end = 0;
30598 $flag = 0;
30599 $ftype = '';
30600 $u = array();
30601 foreach($unicode AS $c => $char) {
30602 if (($flag == 0 || $flag==2) && (!$this->_charDefined($cw,$char) || ($flag==2 && $char==32)) && $this->checkSIP && $char > 131071) { // Unicode Plane 2 (SIP)
30603 if (in_array($this->FontFamily ,$this->available_CJK_fonts)) { return 0; }
30604 if ($flag==0) { $start=$c; }
30605 $flag=2;
30606 $u[] = $char;
30607 }
30608 //else if (($flag == 0 || $flag==1) && $char != 173 && !$this->_charDefined($cw,$char) && ($char<1423 || ($char>3583 && $char < 11263))) {
30609 else if (($flag == 0 || $flag==1) && $char != 173 && (!$this->_charDefined($cw,$char) || ($flag==1 && $char==32)) && ($char<1536 || ($char>1791 && $char < 2304) || $char>3455)) {
30610 if ($flag==0) { $start=$c; }
30611 $flag=1;
30612 $u[] = $char;
30613 }
30614 else if ($flag>0) { $end=$c-1; break; }
30615 }
30616 if ($flag>0 && !$end) { $end=count($unicode)-1; }
30617 if ($start==-1) { return 0; }
30618 if ($flag == 2) { // SIP
30619 // Check if current CJK font has a ext-B related font
30620 if (isset($this->CurrentFont['sipext']) && $this->CurrentFont['sipext']) {
30621 $font = $this->CurrentFont['sipext'];
30622 unset($cw);
30623 $cw = '';
30624 if (isset($this->fonts[$font])) { $cw = &$this->fonts[$font]['cw']; }
30625 else if (file_exists(_MPDF_TTFONTDATAPATH.$font.'.cw.dat')) { $cw = @file_get_contents(_MPDF_TTFONTDATAPATH.$font.'.cw.dat'); }
30626 else {
30627 $prevFontFamily = $this->FontFamily;
30628 $prevFontStyle = $this->currentfontstyle;
30629 $prevFontSizePt = $this->FontSizePt;
30630 $this->SetFont($font, '', '', false);
30631 $cw = @file_get_contents(_MPDF_TTFONTDATAPATH.$font.'.cw.dat');
30632 $this->SetFont($prevFontFamily, $prevFontStyle, $prevFontSizePt, false);
30633 }
30634 if (!$cw) { return 0; }
30635 $l = 0;
30636 foreach($u AS $char) {
30637 if ($this->_charDefined($cw,$char) || $char > 131071) {
30638 $l++;
30639 }
30640 else { break; }
30641 }
30642 if ($l > 0) {
30643 $patt = mb_substr($writehtml_e, $start, $l);
30644 if (preg_match("/(.*?)(".preg_quote($patt,'/').")(.*)/u", $writehtml_e, $m)) {
30645 $writehtml_e = $m[1];
30646 array_splice($writehtml_a, $writehtml_i+1, 0, array('span style="font-family: '.$font.'"', $m[2], '/span', $m[3]));
30647 $this->subPos = $writehtml_i+3;
30648 return 4;
30649 }
30650 }
30651 }
30652 // Check Backup SIP font (defined in config_fonts.php)
30653 if (isset($this->backupSIPFont) && $this->backupSIPFont) {
30654 if ($this->currentfontfamily != $this->backupSIPFont) { $font = $this->backupSIPFont; }
30655 else { unset($cw); return 0; }
30656 unset($cw);
30657 $cw = '';
30658 if (isset($this->fonts[$font])) { $cw = &$this->fonts[$font]['cw']; }
30659 else if (file_exists(_MPDF_TTFONTDATAPATH.$font.'.cw.dat')) { $cw = @file_get_contents(_MPDF_TTFONTDATAPATH.$font.'.cw.dat'); }
30660 else {
30661 $prevFontFamily = $this->FontFamily;
30662 $prevFontStyle = $this->currentfontstyle;
30663 $prevFontSizePt = $this->FontSizePt;
30664 $this->SetFont($this->backupSIPFont, '', '', false);
30665 $cw = @file_get_contents(_MPDF_TTFONTDATAPATH.$font.'.cw.dat');
30666 $this->SetFont($prevFontFamily, $prevFontStyle, $prevFontSizePt, false);
30667 }
30668 if (!$cw) { return 0; }
30669 $l = 0;
30670 foreach($u AS $char) {
30671 if ($this->_charDefined($cw,$char) || $char > 131071) {
30672 $l++;
30673 }
30674 else { break; }
30675 }
30676 if ($l > 0) {
30677 $patt = mb_substr($writehtml_e, $start, $l);
30678 if (preg_match("/(.*?)(".preg_quote($patt,'/').")(.*)/u", $writehtml_e, $m)) {
30679 $writehtml_e = $m[1];
30680 array_splice($writehtml_a, $writehtml_i+1, 0, array('span style="font-family: '.$font.'"', $m[2], '/span', $m[3]));
30681 $this->subPos = $writehtml_i+3;
30682 return 4;
30683 }
30684 }
30685 }
30686 return 0;
30687 }
30688
30689
30690 // FIRST TRY CORE FONTS
30691 if (!$this->PDFA && !$this->PDFX) {
30692 $repl = array();
30693 if (!$this->subArrMB) {
30694 include(_MPDF_PATH.'includes/subs_core.php');
30695 $this->subArrMB['a'] = $aarr;
30696 $this->subArrMB['s'] = $sarr;
30697 $this->subArrMB['z'] = $zarr;
30698 }
30699 if (isset($this->subArrMB['a'][$u[0]])) {
30700 $font = 'tta'; $ftype = 'C';
30701 foreach($u AS $char) {
30702 if ($this->subArrMB['a'][$char]) { $repl[] = $this->subArrMB['a'][$char]; }
30703 else { break; }
30704 }
30705 }
30706 else if (isset($this->subArrMB['z'][$u[0]])) {
30707 $font = 'ttz'; $ftype = 'C';
30708 foreach($u AS $char) {
30709 if ($this->subArrMB['z'][$char]) { $repl[] = $this->subArrMB['z'][$char]; }
30710 else { break; }
30711 }
30712 }
30713 else if (isset($this->subArrMB['s'][$u[0]])) {
30714 $font = 'tts'; $ftype = 'C';
30715 foreach($u AS $char) {
30716 if ($this->subArrMB['s'][$char]) { $repl[] = $this->subArrMB['s'][$char]; }
30717 else { break; }
30718 }
30719 }
30720 if ($ftype=='C') {
30721 $patt = mb_substr($writehtml_e, $start, count($repl));
30722 if (preg_match("/(.*?)(".preg_quote($patt,'/').")(.*)/u", $writehtml_e, $m)) {
30723 $writehtml_e = $m[1];
30724 array_splice($writehtml_a, $writehtml_i+1, 0, array($font, implode('|', $repl), '/'.$font, $m[3])); // e.g. <tts>
30725 $this->subPos = $writehtml_i+3;
30726 return 4;
30727 }
30728 return 0;
30729 }
30730 }
30731
30732 // FIND IN DEFAULT FONT - removed mPDF 5.0
30733
30734 // LASTLY TRY IN BACKUP SUBS FONT
30735 if (!is_array($this->backupSubsFont)) { $this->backupSubsFont = array("$this->backupSubsFont"); }
30736 foreach($this->backupSubsFont AS $bsfctr=>$bsf) {
30737 if ($this->currentfontfamily != $bsf) { $font = $bsf; }
30738 else { continue; }
30739 unset($cw);
30740 $cw = '';
30741 if (isset($this->fonts[$font])) { $cw = &$this->fonts[$font]['cw']; }
30742 else if (file_exists(_MPDF_TTFONTDATAPATH.$font.'.cw.dat')) { $cw = @file_get_contents(_MPDF_TTFONTDATAPATH.$font.'.cw.dat'); }
30743 else {
30744 $prevFontFamily = $this->FontFamily;
30745 $prevFontStyle = $this->currentfontstyle;
30746 $prevFontSizePt = $this->FontSizePt;
30747 $this->SetFont($bsf, '', '', false);
30748 $cw = @file_get_contents(_MPDF_TTFONTDATAPATH.$font.'.cw.dat');
30749 $this->SetFont($prevFontFamily, $prevFontStyle, $prevFontSizePt, false);
30750 }
30751 if (!$cw) { continue; }
30752 $l = 0;
30753 foreach($u AS $char) {
30754 if ($char == 173 || $this->_charDefined($cw,$char) || ($char>1536 && $char<1791) || ($char>2304 && $char<3455 )) { // Arabic and Indic
30755 $l++;
30756 }
30757 else {
30758 if ($l==0 && $bsfctr == (count($this->backupSubsFont)-1)) { // Not found even in last backup font
30759 $cont = mb_substr($writehtml_e, $start+1);
30760 $writehtml_e = mb_substr($writehtml_e, 0, $start+1);
30761 array_splice($writehtml_a, $writehtml_i+1, 0, array('', $cont));
30762 $this->subPos = $writehtml_i+1;
30763 return 2;
30764 }
30765 else { break; }
30766 }
30767 }
30768 if ($l > 0) {
30769 $patt = mb_substr($writehtml_e, $start, $l);
30770 if (preg_match("/(.*?)(".preg_quote($patt,'/').")(.*)/u", $writehtml_e, $m)) {
30771 $writehtml_e = $m[1];
30772 array_splice($writehtml_a, $writehtml_i+1, 0, array('span style="font-family: '.$font.'"', $m[2], '/span', $m[3]));
30773 $this->subPos = $writehtml_i+3;
30774 return 4;
30775 }
30776 }
30777 }
30778
30779 unset($cw);
30780 return 0;
30781 }
30782
30783
30784 function setHiEntitySubstitutions() {
30785 $entarr = array (
30786 'nbsp' => '160', 'iexcl' => '161', 'cent' => '162', 'pound' => '163', 'curren' => '164', 'yen' => '165', 'brvbar' => '166', 'sect' => '167',
30787 'uml' => '168', 'copy' => '169', 'ordf' => '170', 'laquo' => '171', 'not' => '172', 'shy' => '173', 'reg' => '174', 'macr' => '175',
30788 'deg' => '176', 'plusmn' => '177', 'sup2' => '178', 'sup3' => '179', 'acute' => '180', 'micro' => '181', 'para' => '182', 'middot' => '183',
30789 'cedil' => '184', 'sup1' => '185', 'ordm' => '186', 'raquo' => '187', 'frac14' => '188', 'frac12' => '189', 'frac34' => '190',
30790 'iquest' => '191', 'Agrave' => '192', 'Aacute' => '193', 'Acirc' => '194', 'Atilde' => '195', 'Auml' => '196', 'Aring' => '197',
30791 'AElig' => '198', 'Ccedil' => '199', 'Egrave' => '200', 'Eacute' => '201', 'Ecirc' => '202', 'Euml' => '203', 'Igrave' => '204',
30792 'Iacute' => '205', 'Icirc' => '206', 'Iuml' => '207', 'ETH' => '208', 'Ntilde' => '209', 'Ograve' => '210', 'Oacute' => '211',
30793 'Ocirc' => '212', 'Otilde' => '213', 'Ouml' => '214', 'times' => '215', 'Oslash' => '216', 'Ugrave' => '217', 'Uacute' => '218',
30794 'Ucirc' => '219', 'Uuml' => '220', 'Yacute' => '221', 'THORN' => '222', 'szlig' => '223', 'agrave' => '224', 'aacute' => '225',
30795 'acirc' => '226', 'atilde' => '227', 'auml' => '228', 'aring' => '229', 'aelig' => '230', 'ccedil' => '231', 'egrave' => '232',
30796 'eacute' => '233', 'ecirc' => '234', 'euml' => '235', 'igrave' => '236', 'iacute' => '237', 'icirc' => '238', 'iuml' => '239',
30797 'eth' => '240', 'ntilde' => '241', 'ograve' => '242', 'oacute' => '243', 'ocirc' => '244', 'otilde' => '245', 'ouml' => '246',
30798 'divide' => '247', 'oslash' => '248', 'ugrave' => '249', 'uacute' => '250', 'ucirc' => '251', 'uuml' => '252', 'yacute' => '253',
30799 'thorn' => '254', 'yuml' => '255', 'OElig' => '338', 'oelig' => '339', 'Scaron' => '352', 'scaron' => '353', 'Yuml' => '376',
30800 'fnof' => '402', 'circ' => '710', 'tilde' => '732', 'Alpha' => '913', 'Beta' => '914', 'Gamma' => '915', 'Delta' => '916',
30801 'Epsilon' => '917', 'Zeta' => '918', 'Eta' => '919', 'Theta' => '920', 'Iota' => '921', 'Kappa' => '922', 'Lambda' => '923',
30802 'Mu' => '924', 'Nu' => '925', 'Xi' => '926', 'Omicron' => '927', 'Pi' => '928', 'Rho' => '929', 'Sigma' => '931', 'Tau' => '932',
30803 'Upsilon' => '933', 'Phi' => '934', 'Chi' => '935', 'Psi' => '936', 'Omega' => '937', 'alpha' => '945', 'beta' => '946', 'gamma' => '947',
30804 'delta' => '948', 'epsilon' => '949', 'zeta' => '950', 'eta' => '951', 'theta' => '952', 'iota' => '953', 'kappa' => '954',
30805 'lambda' => '955', 'mu' => '956', 'nu' => '957', 'xi' => '958', 'omicron' => '959', 'pi' => '960', 'rho' => '961', 'sigmaf' => '962',
30806 'sigma' => '963', 'tau' => '964', 'upsilon' => '965', 'phi' => '966', 'chi' => '967', 'psi' => '968', 'omega' => '969',
30807 'thetasym' => '977', 'upsih' => '978', 'piv' => '982', 'ensp' => '8194', 'emsp' => '8195', 'thinsp' => '8201', 'zwnj' => '8204',
30808 'zwj' => '8205', 'lrm' => '8206', 'rlm' => '8207', 'ndash' => '8211', 'mdash' => '8212', 'lsquo' => '8216', 'rsquo' => '8217',
30809 'sbquo' => '8218', 'ldquo' => '8220', 'rdquo' => '8221', 'bdquo' => '8222', 'dagger' => '8224', 'Dagger' => '8225', 'bull' => '8226',
30810 'hellip' => '8230', 'permil' => '8240', 'prime' => '8242', 'Prime' => '8243', 'lsaquo' => '8249', 'rsaquo' => '8250', 'oline' => '8254',
30811 'frasl' => '8260', 'euro' => '8364', 'image' => '8465', 'weierp' => '8472', 'real' => '8476', 'trade' => '8482', 'alefsym' => '8501',
30812 'larr' => '8592', 'uarr' => '8593', 'rarr' => '8594', 'darr' => '8595', 'harr' => '8596', 'crarr' => '8629', 'lArr' => '8656',
30813 'uArr' => '8657', 'rArr' => '8658', 'dArr' => '8659', 'hArr' => '8660', 'forall' => '8704', 'part' => '8706', 'exist' => '8707',
30814 'empty' => '8709', 'nabla' => '8711', 'isin' => '8712', 'notin' => '8713', 'ni' => '8715', 'prod' => '8719', 'sum' => '8721',
30815 'minus' => '8722', 'lowast' => '8727', 'radic' => '8730', 'prop' => '8733', 'infin' => '8734', 'ang' => '8736', 'and' => '8743',
30816 'or' => '8744', 'cap' => '8745', 'cup' => '8746', 'int' => '8747', 'there4' => '8756', 'sim' => '8764', 'cong' => '8773',
30817 'asymp' => '8776', 'ne' => '8800', 'equiv' => '8801', 'le' => '8804', 'ge' => '8805', 'sub' => '8834', 'sup' => '8835', 'nsub' => '8836',
30818 'sube' => '8838', 'supe' => '8839', 'oplus' => '8853', 'otimes' => '8855', 'perp' => '8869', 'sdot' => '8901', 'lceil' => '8968',
30819 'rceil' => '8969', 'lfloor' => '8970', 'rfloor' => '8971', 'lang' => '9001', 'rang' => '9002', 'loz' => '9674', 'spades' => '9824',
30820 'clubs' => '9827', 'hearts' => '9829', 'diams' => '9830',
30821 );
30822 foreach($entarr AS $key => $val) {
30823 $this->entsearch[] = '&'.$key.';';
30824 $this->entsubstitute[] = code2utf($val);
30825 }
30826 }
30827
30828 function SubstituteHiEntities($html) {
30829 // converts html_entities > ASCII 127 to unicode
30830 // Leaves in particular &lt; to distinguish from tag marker
30831 if (count($this->entsearch)) {
30832 $html = str_replace($this->entsearch,$this->entsubstitute,$html);
30833 }
30834 return $html;
30835 }
30836
30837
30838 // Edited v1.2 Pass by reference; option to continue if invalid UTF-8 chars
30839 function is_utf8(&$string) {
30840 if ($string === mb_convert_encoding(mb_convert_encoding($string, "UTF-32", "UTF-8"), "UTF-8", "UTF-32")) {
30841 return true;
30842 }
30843 else {
30844 if ($this->ignore_invalid_utf8) {
30845 $string = mb_convert_encoding(mb_convert_encoding($string, "UTF-32", "UTF-8"), "UTF-8", "UTF-32") ;
30846 return true;
30847 }
30848 else {
30849 return false;
30850 }
30851 }
30852 }
30853
30854
30855 function purify_utf8($html,$lo=true) {
30856 // For HTML
30857 // Checks string is valid UTF-8 encoded
30858 // converts html_entities > ASCII 127 to UTF-8
30859 // Only exception - leaves low ASCII entities e.g. &lt; &amp; etc.
30860 // Leaves in particular &lt; to distinguish from tag marker
30861 if (!$this->is_utf8($html)) {
30862 echo "<p><b>HTML contains invalid UTF-8 character(s)</b></p>";
30863 while (mb_convert_encoding(mb_convert_encoding($html, "UTF-32", "UTF-8"), "UTF-8", "UTF-32") != $html) {
30864 $a = iconv('UTF-8', 'UTF-8', $html);
30865 echo ($a);
30866 $pos = $start = strlen($a);
30867 $err = '';
30868 while ( ord(substr($html,$pos,1)) > 128 ) {
30869 $err .= '[[#'.ord(substr($html,$pos,1)).']]';
30870 $pos++;
30871 }
30872 echo '<span style="color:red; font-weight:bold">'.$err.'</span>';
30873 $html = substr($html, $pos);
30874 }
30875 echo $html;
30876 $this->Error("");
30877 }
30878 $html = preg_replace("/\r/", "", $html );
30879
30880 // converts html_entities > ASCII 127 to UTF-8
30881 // Leaves in particular &lt; to distinguish from tag marker
30882 $html = $this->SubstituteHiEntities($html);
30883
30884 // converts all &#nnn; or &#xHHH; to UTF-8 multibyte
30885 // If $lo==true then includes ASCII < 128
30886 $html = strcode2utf($html,$lo);
30887 return ($html);
30888 }
30889
30890 function purify_utf8_text($txt) {
30891 // For TEXT
30892 // Make sure UTF-8 string of characters
30893 if (!$this->is_utf8($txt)) { $this->Error("Text contains invalid UTF-8 character(s)"); }
30894
30895 $txt = preg_replace("/\r/", "", $txt );
30896
30897 return ($txt);
30898 }
30899 function all_entities_to_utf8($txt) {
30900 // converts txt_entities > ASCII 127 to UTF-8
30901 // Leaves in particular &lt; to distinguish from tag marker
30902 $txt = $this->SubstituteHiEntities($txt);
30903
30904 // converts all &#nnn; or &#xHHH; to UTF-8 multibyte
30905 $txt = strcode2utf($txt);
30906
30907 $txt = $this->lesser_entity_decode($txt);
30908 return ($txt);
30909 }
30910
30911
30912 // ====================================================
30913 /*-- BARCODES --*/
30914 // UPC/EAN barcode
30915 // EAN13, EAN8, UPCA, UPCE, ISBN, ISSN
30916 // Accepts 12 or 13 digits with or without - hyphens
30917 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) {
30918 if (empty($code)) {
30919 return;
30920 }
30921 $codestr = $code;
30922 $code = preg_replace('/\-/','',$code);
30923
30924 if (!class_exists('PDFBarcode', false)) {
30925 include(_MPDF_PATH.'classes/barcode.php');
30926 }
30927 $this->barcode = new PDFBarcode();
30928 if ($btype == 'ISSN' || $btype == 'ISBN') {
30929 $arrcode = $this->barcode->getBarcodeArray($code, 'EAN13');
30930 }
30931 else { $arrcode = $this->barcode->getBarcodeArray($code, $btype); }
30932
30933 if ($arrcode === false) { $this->Error('Error in barcode string: '.$codestr); }
30934 if((($btype=='EAN13' || $btype=='ISBN' || $btype=='ISSN') && strlen($code) == 12) || ($btype=='UPCA' && strlen($code) == 11)
30935 || ($btype=='UPCE' && strlen($code) == 11) || ($btype=='EAN8' && strlen($code) == 7)) {
30936 $code .= $arrcode['checkdigit'];
30937 if (stristr($codestr,'-')) { $codestr .= '-' . $arrcode['checkdigit']; }
30938 else { $codestr .= $arrcode['checkdigit']; }
30939 }
30940 if ($btype == 'ISBN') { $codestr = 'ISBN '.$codestr; }
30941 if ($btype == 'ISSN') { $codestr = 'ISSN '.$codestr; }
30942
30943 if (empty($x)) {
30944 $x = $this->x;
30945 }
30946 if (empty($y)) {
30947 $y = $this->y;
30948 }
30949 // set foreground color
30950 $prevDrawColor = $this->DrawColor;
30951 $prevTextColor = $this->TextColor;
30952 $prevFillColor = $this->FillColor;
30953 $lw = $this->LineWidth;
30954 $this->SetLineWidth(0.01);
30955
30956 $size /= $k; // in case resized in a table
30957
30958 $xres = $arrcode['nom-X'] * $size;
30959 $llm = $arrcode['lightmL'] * $arrcode['nom-X'] * $size; // Left Light margin
30960 $rlm = $arrcode['lightmR'] * $arrcode['nom-X'] * $size; // Right Light margin
30961
30962 $bcw = ($arrcode["maxw"] * $xres); // Barcode width = Should always be 31.35mm * $size
30963
30964 $fbw = $bcw + $llm + $rlm; // Full barcode width incl. light margins
30965 $ow = $fbw + $paddingL + $paddingR; // Full overall width incl. user-defined padding
30966
30967 $fbwi = $fbw - 2; // Full barcode width incl. light margins - 2mm - for isbn string
30968
30969 // cf. http://www.gs1uk.org/downloads/bar_code/Bar coding getting it right.pdf
30970 $num_height = 3 * $size; // Height of numerals
30971 $fbh = $arrcode['nom-H'] * $size * $height; // Full barcode height incl. numerals
30972 $bch = $fbh - (1.5 * $size); // Barcode height of bars (3mm for numerals)
30973
30974 if (($btype=='EAN13' && $showtext) || $btype == 'ISSN' || $btype == 'ISBN') { // Add height for ISBN string + margin from top of bars
30975 $tisbnm = 1.5 * $size; // Top margin between isbn (if shown) & bars
30976 $codestr_fontsize = 2.1 * $size;
30977 $paddingT += $codestr_fontsize + $tisbnm ;
30978 }
30979 $oh = $fbh + $paddingT + $paddingB; // Full overall height incl. user-defined padding
30980
30981 // PRINT border background color
30982 $xpos = $x;
30983 $ypos = $y;
30984 if ($col) { // from <barcode /> // mPDF 5.3.A4
30985 $this->SetDColor($col);
30986 $this->SetTColor($col);
30987 }
30988 else {
30989 $this->SetDColor($this->ConvertColor(0));
30990 $this->SetTColor($this->ConvertColor(0));
30991 }
30992 if ($bgcol) { // mPDF 5.3.A4
30993 $this->SetFColor($bgcol);
30994 }
30995 else { $this->SetFColor($this->ConvertColor(255)); }
30996 if (!$bgcol && !$col) { // fn. called directly - not via HTML
30997 if ($border) { $fillb = 'DF'; } else { $fillb = 'F'; }
30998 $this->Rect($xpos, $ypos, $ow, $oh, $fillb);
30999 }
31000
31001
31002 // PRINT BARS
31003 $xpos = $x + $paddingL + $llm ;
31004 $ypos = $y + $paddingT;
31005 if ($col) { $this->SetFColor($col); } // mPDF 5.3.A4
31006 else { $this->SetFColor($this->ConvertColor(0)); }
31007 if ($arrcode !== false) {
31008 foreach ($arrcode["bcode"] AS $v) {
31009 $bw = ($v["w"] * $xres);
31010 if ($v["t"]) {
31011 // draw a vertical bar
31012 $this->Rect($xpos, $ypos, $bw, $bch, 'F');
31013 }
31014 $xpos += $bw;
31015 }
31016 }
31017
31018
31019 // print text
31020 $prevFontFamily = $this->FontFamily;
31021 $prevFontStyle = $this->FontStyle;
31022 $prevFontSizePt = $this->FontSizePt;
31023
31024 // ISBN string
31025 if (($btype=='EAN13' && $showtext) || $btype=='ISBN' || $btype=='ISSN') {
31026 if ($this->onlyCoreFonts) {
31027 $this->SetFont('chelvetica');
31028 }
31029 else {
31030 $this->SetFont('sans');
31031 }
31032
31033 if ($bgcol) { $this->SetFColor($bgcol); } // mPDF 5.3.A4
31034 else { $this->SetFColor($this->ConvertColor(255)); }
31035 $this->x = $x + $paddingL + 1; // 1mm left margin (cf. $fbwi above)
31036 // max width is $fbwi
31037 $loop = 0;
31038 while ( $loop == 0 ) {
31039 $this->SetFontSize($codestr_fontsize*1.4*_MPDFK, false); // don't write
31040 $sz = $this->GetStringWidth( $codestr );
31041 if ($sz > $fbwi)
31042 $codestr_fontsize -= 0.1;
31043 else
31044 $loop ++;
31045 }
31046 $this->SetFont('','',$codestr_fontsize*1.4*_MPDFK, true, true); // * 1.4 because font height is only 7/10 of given mm
31047 // WORD SPACING
31048 if ($fbwi > $sz) {
31049 $xtra = $fbwi - $sz;
31050 $charspacing = $xtra / (strlen($codestr)-1);
31051 if ($charspacing) { $this->_out(sprintf('BT %.3F Tc ET',$charspacing*_MPDFK)); }
31052 }
31053 $this->y = $y + $paddingT - ($codestr_fontsize ) - $tisbnm ;
31054 $this->Cell($fbw , $codestr_fontsize, $codestr);
31055 if ($charspacing) { $this->_out('BT 0 Tc ET'); }
31056 }
31057
31058
31059 // Bottom NUMERALS
31060 if ($this->onlyCoreFonts) {
31061 $this->SetFont('mono');
31062 }
31063 else {
31064 if (in_array('ocrb',$this->available_unifonts)) { $this->SetFont('ocrb'); }
31065 else { $this->SetFont('mono'); }
31066 }
31067 // mPDF 5.3.A9
31068 if (isset($this->CurrentFont['desc']['CapHeight'])) { $fh = (1000/$this->CurrentFont['desc']['CapHeight']); }
31069 else if (isset($this->CurrentFont['desc']['Ascent'])) { $fh = (1000/$this->CurrentFont['desc']['Ascent']); }
31070 else { $fh = 1.2; }
31071
31072 $charRO = '';
31073 if ($btype=='EAN13' || $btype=='ISBN' || $btype=='ISSN') {
31074 $outerfontsize = 3; // Inner fontsize = 3
31075 $outerp = $xres * 4;
31076 $innerp = $xres * 2.5;
31077 $textw = ($bcw*0.5) - $outerp - $innerp;
31078 $chars = 6; // number of numerals in each half
31079 $charLO = substr($code,0,1); // Left Outer
31080 $charLI = substr($code,1,6); // Left Inner
31081 $charRI = substr($code,7,6); // Right Inner
31082 if (!$supplement) $charRO = '>'; // Right Outer
31083 }
31084 else if ($btype=='UPCA') {
31085 $outerfontsize = 2.3; // Inner fontsize = 3
31086 $outerp = $xres * 10;
31087 $innerp = $xres * 2.5;
31088 $textw = ($bcw*0.5) - $outerp - $innerp;
31089 $chars = 5;
31090 $charLO = substr($code,0,1); // Left Outer
31091 $charLI = substr($code,1,5); // Left Inner
31092 $charRI = substr($code,6,5); // Right Inner
31093 $charRO = substr($code,11,1); // Right Outer
31094 }
31095 else if ($btype=='UPCE') {
31096 $outerfontsize = 2.3; // Inner fontsize = 3
31097 $outerp = $xres * 4;
31098 $innerp = 0;
31099 $textw = ($bcw*0.5) - $outerp - $innerp;
31100 $chars = 3;
31101 $upce_code = $arrcode['code'];
31102 $charLO = substr($code,0,1); // Left Outer
31103 $charLI = substr($upce_code,0,3); // Left Inner
31104 $charRI = substr($upce_code,3,3); // Right Inner
31105 $charRO = substr($code,11,1); // Right Outer
31106 }
31107 else if ($btype=='EAN8') {
31108 $outerfontsize = 3; // Inner fontsize = 3
31109 $outerp = $xres * 4;
31110 $innerp = $xres * 2.5;
31111 $textw = ($bcw*0.5) - $outerp - $innerp;
31112 $chars = 4;
31113 $charLO = '<'; // Left Outer
31114 $charLI = substr($code,0,4); // Left Inner
31115 $charRI = substr($code,4,4); // Right Inner
31116 if (!$supplement) $charRO = '>'; // Right Outer
31117 }
31118
31119 $this->SetFontSize(($outerfontsize/3)*3*$fh*$size*_MPDFK); // 3mm numerals (FontSize is larger to account for space above/below characters)
31120
31121 if (!$this->usingCoreFont) { $cw = $this->_getCharWidth($this->CurrentFont['cw'],32)*3*$fh*$size/1000; } // character width at 3mm
31122 else { $cw = $this->_getCharWidth($this->CurrentFont['cw'],48)*3*$fh*$size/1000; } // 48 == char "0"
31123
31124 // Outer left character
31125 $y_text = $y + $paddingT + $bch - ($num_height/2);
31126 $y_text_outer = $y + $paddingT + $bch - ($num_height*($outerfontsize/3)/2);
31127
31128 $this->x = $x + $paddingL - ($cw*($outerfontsize/3)*0.1); // 0.1 is correction as char does not fill full width;
31129 $this->y = $y_text_outer;
31130 $this->Cell($cw, $num_height, $charLO );
31131
31132 // WORD SPACING for inner chars
31133 $xtra = $textw - ($cw*$chars);
31134 $charspacing = $xtra / ($chars-1);
31135 if ($charspacing) { $this->_out(sprintf('BT %.3F Tc ET',$charspacing*_MPDFK)); }
31136
31137 if ($bgcol) { $this->SetFColor($bgcol); } // mPDF 5.3.A4
31138 else { $this->SetFColor($this->ConvertColor(255)); }
31139
31140 $this->SetFontSize(3*$fh*$size*_MPDFK); // 3mm numerals (FontSize is larger to account for space above/below characters)
31141
31142 // Inner left half characters
31143 $this->x = $x + $paddingL + $llm + $outerp;
31144 $this->y = $y_text;
31145 $this->Cell($textw, $num_height, $charLI , 0, 0, '', 1);
31146
31147 // Inner right half characters
31148 $this->x = $x + $paddingL + $llm + ($bcw*0.5) + $innerp;
31149 $this->y = $y_text;
31150 $this->Cell($textw, $num_height, $charRI , 0, 0, '', 1);
31151
31152 if ($charspacing) { $this->_out('BT 0 Tc ET'); }
31153
31154 // Outer Right character
31155 $this->SetFontSize(($outerfontsize/3)*3*$fh*$size*_MPDFK); // 3mm numerals (FontSize is larger to account for space above/below characters)
31156
31157 $this->x = $x + $paddingL + $llm + $bcw + $rlm - ($cw*($outerfontsize/3)*0.9); // 0.9 is correction as char does not fill full width
31158 $this->y = $y_text_outer;
31159 $this->Cell($cw*($outerfontsize/3), $num_height, $charRO , 0, 0, 'R');
31160
31161 if ($supplement) { // EAN-2 or -5 Supplement
31162 // PRINT BARS
31163 $supparrcode = $this->barcode->getBarcodeArray($supplement_code, 'EAN'.$supplement);
31164 if ($supparrcode === false) { $this->Error('Error in barcode string (supplement): '.$codestr.' '.$supplement_code); }
31165 if(strlen($supplement_code) != $supplement) {
31166 $this->Error('Barcode supplement incorrect: '.$supplement_code);
31167 }
31168 $llm = $fbw - (($arrcode['lightmR'] - $supparrcode['sepM']) * $arrcode['nom-X'] * $size); // Left Light margin
31169 $rlm = $arrcode['lightmR'] * $arrcode['nom-X'] * $size; // Right Light margin
31170
31171 $bcw = ($supparrcode["maxw"] * $xres); // Barcode width = Should always be 31.35mm * $size
31172
31173 $fbw = $bcw + $llm + $rlm; // Full barcode width incl. light margins
31174 $ow = $fbw + $paddingL + $paddingR; // Full overall width incl. user-defined padding
31175 $bch = $fbh - (1.5 * $size) - ($num_height + 0.5); // Barcode height of bars (3mm for numerals)
31176
31177 $xpos = $x + $paddingL + $llm ;
31178 $ypos = $y + $paddingT + $num_height + 0.5;
31179 if ($col) { $this->SetFColor($col); } // mPDF 5.3.A4
31180 else { $this->SetFColor($this->ConvertColor(0)); }
31181 if ($supparrcode !== false) {
31182 foreach ($supparrcode["bcode"] AS $v) {
31183 $bw = ($v["w"] * $xres);
31184 if ($v["t"]) {
31185 // draw a vertical bar
31186 $this->Rect($xpos, $ypos, $bw, $bch, 'F');
31187 }
31188 $xpos += $bw;
31189 }
31190 }
31191
31192 // Characters
31193 if ($bgcol) { $this->SetFColor($bgcol); } // mPDF 5.3.A4
31194 else { $this->SetFColor($this->ConvertColor(255)); }
31195 $this->SetFontSize(3*$fh*$size*_MPDFK); // 3mm numerals (FontSize is larger to account for space above/below characters)
31196 $this->x = $x + $paddingL + $llm;
31197 $this->y = $y + $paddingT;
31198 $this->Cell($bcw, $num_height, $supplement_code, 0, 0, 'C');
31199
31200 // Outer Right character (light margin)
31201 $this->SetFontSize(($outerfontsize/3)*3*$fh*$size*_MPDFK); // 3mm numerals (FontSize is larger to account for space above/below characters)
31202 $this->x = $x + $paddingL + $llm + $bcw + $rlm - ($cw*0.9); // 0.9 is correction as char does not fill full width
31203 $this->y = $y + $paddingT;
31204 $this->Cell($cw*($outerfontsize/3), $num_height, '>', 0, 0, 'R');
31205 }
31206
31207
31208
31209 // Restore **************
31210 $this->SetFont($prevFontFamily, $prevFontStyle, $prevFontSizePt);
31211 $this->DrawColor = $prevDrawColor;
31212 $this->TextColor = $prevTextColor;
31213 $this->FillColor = $prevFillColor;
31214 $this->SetLineWidth($lw);
31215 $this->SetY($y);
31216 }
31217
31218
31219
31220 // ====================================================
31221 // POSTAL and OTHER barcodes
31222 function WriteBarcode2($code, $x='', $y='', $size=1, $height=1, $bgcol=false, $col=false, $btype='IMB', $print_ratio='', $k=1) {
31223 if (empty($code)) { return; }
31224 if (!class_exists('PDFBarcode', false)) {
31225 include(_MPDF_PATH.'classes/barcode.php');
31226 }
31227 $this->barcode = new PDFBarcode();
31228 $arrcode = $this->barcode->getBarcodeArray($code, $btype, $print_ratio);
31229
31230 if ($arrcode === false) { $this->Error('Error in barcode string: '.$code); }
31231 if (empty($x)) { $x = $this->x; }
31232 if (empty($y)) { $y = $this->y; }
31233 $prevDrawColor = $this->DrawColor;
31234 $prevTextColor = $this->TextColor;
31235 $prevFillColor = $this->FillColor;
31236 $lw = $this->LineWidth;
31237 $this->SetLineWidth(0.01);
31238 $size /= $k; // in case resized in a table
31239 $xres = $arrcode['nom-X'] * $size;
31240
31241 if ($btype == 'IMB' || $btype == 'RM4SCC' || $btype == 'KIX' || $btype == 'POSTNET' || $btype == 'PLANET') {
31242 $llm = $arrcode['quietL'] / $k; // Left Quiet margin
31243 $rlm = $arrcode['quietR'] / $k; // Right Quiet margin
31244 $tlm = $blm = $arrcode['quietTB'] / $k;
31245 $height=1; // Overrides
31246 }
31247 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'))) {
31248 $llm = $arrcode['lightmL'] * $xres; // Left Quiet margin
31249 $rlm = $arrcode['lightmR'] * $xres; // Right Quiet margin
31250 $tlm = $blm = $arrcode['lightTB'] * $xres * $height;
31251 }
31252
31253
31254 $bcw = ($arrcode["maxw"] * $xres);
31255 $fbw = $bcw + $llm + $rlm; // Full barcode width incl. light margins
31256
31257 $bch = ($arrcode["nom-H"] * $size * $height);
31258 $fbh = $bch + $tlm + $blm; // Full barcode height
31259
31260 // PRINT border background color
31261 $xpos = $x;
31262 $ypos = $y;
31263 if ($col) { // from <barcode /> // mPDF 5.3.A4
31264 $this->SetDColor($col);
31265 $this->SetTColor($col);
31266 }
31267 else {
31268 $this->SetDColor($this->ConvertColor(0));
31269 $this->SetTColor($this->ConvertColor(0));
31270 }
31271 if ($bgcol) { // from <barcode /> // mPDF 5.3.A4
31272 $this->SetFColor($bgcol);
31273 }
31274 else { $this->SetFColor($this->ConvertColor(255)); }
31275
31276 // PRINT BARS
31277 if ($col) { $this->SetFColor($col); } // mPDF 5.3.A4
31278 else { $this->SetFColor($this->ConvertColor(0)); }
31279 $xpos = $x + $llm ;
31280
31281 if ($arrcode !== false) {
31282 foreach ($arrcode["bcode"] AS $v) {
31283 $bw = ($v["w"] * $xres);
31284 if ($v["t"]) {
31285 $ypos = $y + $tlm + ($bch * $v['p'] / $arrcode['maxh']);
31286 $this->Rect($xpos, $ypos, $bw, ($v['h'] * $bch / $arrcode['maxh']), 'F');
31287 }
31288 $xpos += $bw;
31289 }
31290 }
31291
31292 // PRINT BEARER BARS
31293 if ($btype == 'I25B' || $btype == 'I25B+') {
31294 $this->Rect($x, $y, $fbw, ($arrcode['lightTB'] * $xres * $height), 'F');
31295 $this->Rect($x, $y+$tlm+$bch, $fbw, ($arrcode['lightTB'] * $xres * $height), 'F');
31296 }
31297
31298 // Restore **************
31299 $this->SetFont($prevFontFamily, $prevFontStyle, $prevFontSizePt);
31300 $this->DrawColor = $prevDrawColor;
31301 $this->TextColor = $prevTextColor;
31302 $this->FillColor = $prevFillColor;
31303 $this->SetLineWidth($lw);
31304 $this->SetY($y);
31305 }
31306
31307 /*-- END BARCODES --*/
31308
31309 // ====================================================
31310 // ====================================================
31311
31312 function StartTransform($returnstring=false) {
31313 if ($returnstring) { return('q'); }
31314 else { $this->_out('q'); }
31315 }
31316 function StopTransform($returnstring=false) {
31317 if ($returnstring) { return('Q'); }
31318 else { $this->_out('Q'); }
31319 }
31320 function transformScale($s_x, $s_y, $x='', $y='', $returnstring=false) {
31321 if ($x === '') {
31322 $x=$this->x;
31323 }
31324 if ($y === '') {
31325 $y=$this->y;
31326 }
31327 if (($s_x == 0) OR ($s_y == 0)) {
31328 $this->Error('Please do not use values equal to zero for scaling');
31329 }
31330 $y = ($this->h - $y) * _MPDFK;
31331 $x *= _MPDFK;
31332 //calculate elements of transformation matrix
31333 $s_x /= 100;
31334 $s_y /= 100;
31335 $tm[0] = $s_x;
31336 $tm[1] = 0;
31337 $tm[2] = 0;
31338 $tm[3] = $s_y;
31339 $tm[4] = $x * (1 - $s_x);
31340 $tm[5] = $y * (1 - $s_y);
31341 //scale the coordinate system
31342 if ($returnstring) { return($this->_transform($tm, true)); }
31343 else { $this->_transform($tm); }
31344 }
31345 function transformTranslate($t_x, $t_y, $returnstring=false) {
31346 //calculate elements of transformation matrix
31347 $tm[0] = 1;
31348 $tm[1] = 0;
31349 $tm[2] = 0;
31350 $tm[3] = 1;
31351 $tm[4] = $t_x * _MPDFK;
31352 $tm[5] = -$t_y * _MPDFK;
31353 //translate the coordinate system
31354 if ($returnstring) { return($this->_transform($tm, true)); }
31355 else { $this->_transform($tm); }
31356 }
31357 function transformRotate($angle, $x='', $y='', $returnstring=false) {
31358 if ($x === '') {
31359 $x=$this->x;
31360 }
31361 if ($y === '') {
31362 $y=$this->y;
31363 }
31364 $angle = -$angle;
31365 $y = ($this->h - $y) * _MPDFK;
31366 $x *= _MPDFK;
31367 //calculate elements of transformation matrix
31368 $tm[0] = cos(deg2rad($angle));
31369 $tm[1] = sin(deg2rad($angle));
31370 $tm[2] = -$tm[1];
31371 $tm[3] = $tm[0];
31372 $tm[4] = $x + $tm[1] * $y - $tm[0] * $x;
31373 $tm[5] = $y - $tm[0] * $y - $tm[1] * $x;
31374 //rotate the coordinate system around ($x,$y)
31375 if ($returnstring) { return($this->_transform($tm, true)); }
31376 else { $this->_transform($tm); }
31377 }
31378 function _transform($tm, $returnstring=false) {
31379 // mPDF 5.3.53
31380 if ($returnstring) { return(sprintf('%.4F %.4F %.4F %.4F %.4F %.4F cm', $tm[0], $tm[1], $tm[2], $tm[3], $tm[4], $tm[5])); }
31381 else { $this->_out(sprintf('%.4F %.4F %.4F %.4F %.4F %.4F cm', $tm[0], $tm[1], $tm[2], $tm[3], $tm[4], $tm[5])); }
31382 }
31383
31384
31385
31386 /*-- INDIC --*/
31387 // INDIC ============================
31388 // This conversion can only be done when font is set
31389 function ConvertIndic(&$str) {
31390 if (preg_match('/^ind_([a-z]{2})_/',$this->currentfontfamily, $m)) {
31391 if (!class_exists('indic', false)) { include(_MPDF_PATH.'classes/indic.php'); }
31392 if (empty($this->indic)) { $this->indic = new indic($this); }
31393 $earr = $this->UTF8StringToArray($str, false);
31394 $str = $this->indic->substituteIndic($earr, $m[1], $this->currentfontfamily);
31395 }
31396 }
31397 /*-- END INDIC --*/
31398
31399 // AUTOFONT =========================
31400 function AutoFont($html) {
31401 if ($this->onlyCoreFonts) { return $html; } // mPDF 5.3.22
31402 $this->useLang = true;
31403 if ($this->autoFontGroupSize == 1) { $extra = $this->pregASCIIchars1; }
31404 else if ($this->autoFontGroupSize == 3) { $extra = $this->pregASCIIchars3; }
31405 else { $extra = $this->pregASCIIchars2; }
31406 $n = '';
31407 $a=preg_split('/<(.*?)>/ms',$html,-1,PREG_SPLIT_DELIM_CAPTURE);
31408 foreach($a as $i => $e) {
31409 if($i%2==0) {
31410 $e = strcode2utf($e);
31411 $e = $this->lesser_entity_decode($e);
31412
31413 // Use U=FFF0 and U+FFF1 to mark start and end of span tags to prevent nesting occurring
31414 // "\xef\xbf\xb0" ##lthtmltag## "\xef\xbf\xb1" ##gthtmltag##
31415
31416 /*-- CJK-FONTS --*/
31417 if ($this->autoFontGroups & AUTOFONT_CJK) {
31418 $e = preg_replace("/([".$this->pregCJKchars.$extra."]*[".$this->pregCJKchars."][".$this->pregCJKchars.$extra."]*)/ue", '$this->replaceCJK(stripslashes(\'\\1\'))', $e);
31419 }
31420 /*-- END CJK-FONTS --*/
31421
31422 /*-- RTL --*/
31423 if ($this->autoFontGroups & AUTOFONT_RTL) {
31424 // HEBREW
31425 $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);
31426 // All Arabic
31427 $e = preg_replace("/([".$this->pregARABICchars .$extra."]*[".$this->pregARABICchars ."][".$this->pregARABICchars .$extra."]*)/ue", '$this->replaceArabic(stripslashes(\'\\1\'))', $e);
31428 }
31429 /*-- END RTL --*/
31430
31431 /*-- INDIC --*/
31432 // INDIC
31433 if ($this->autoFontGroups & AUTOFONT_INDIC) {
31434 // Bengali
31435 $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);
31436 // Devanagari (= script for Hindi, Nepali + Sindhi)
31437 $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);
31438 // Gujarati
31439 $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);
31440 // Malayalam
31441 $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);
31442 // Kannada
31443 $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);
31444 // Oriya
31445 $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);
31446 // Punjabi ?= Gurmuhki
31447 $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);
31448 // Tamil
31449 $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);
31450 // Telugu
31451 $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);
31452 }
31453 /*-- END INDIC --*/
31454
31455
31456 if ($this->autoFontGroups & AUTOFONT_THAIVIET) {
31457 // THAI
31458 $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);
31459 // Vietnamese
31460 $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);
31461 }
31462
31463 $e = preg_replace('/[&]/','&amp;',$e);
31464 $e = preg_replace('/[<]/','&lt;',$e);
31465 $e = preg_replace('/[>]/','&gt;',$e);
31466 $e = preg_replace("/(\xef\xbf\xb0span lang=\"([a-z\-A-Z]{2,5})\"\xef\xbf\xb1)\s+/",' \\1',$e);
31467 $e = preg_replace("/[ ]+(\xef\xbf\xb0\/span\xef\xbf\xb1)/",'\\1 ',$e);
31468
31469 $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);
31470
31471 $e = preg_replace("/\xef\xbf\xb0/",'<',$e);
31472 $e = preg_replace("/\xef\xbf\xb1/",'>',$e);
31473
31474 $a[$i] = $e;
31475 }
31476 else {
31477 $a[$i] = '<'.$e.'>';
31478 }
31479 }
31480 $n = implode('',$a);
31481 return $n;
31482 }
31483
31484
31485 /*-- CJK-FONTS --*/
31486 function replaceCJK($str) {
31487 // Use U=FFF0 and U+FFF1 to mark start and end of span tags to prevent nesting occurring
31488 // "\xef\xbf\xb0" ##lthtmltag## "\xef\xbf\xb1" ##gthtmltag##
31489 if (preg_match("/[".$this->pregUHCchars."]/u", $str)) {
31490 return "\xef\xbf\xb0span lang=\"ko\"\xef\xbf\xb1" . $str ."\xef\xbf\xb0/span\xef\xbf\xb1";
31491 }
31492 else if (preg_match("/[".$this->pregSJISchars."]/u", $str)) {
31493 return "\xef\xbf\xb0span lang=\"ja\"\xef\xbf\xb1" . $str ."\xef\xbf\xb0/span\xef\xbf\xb1";
31494 }
31495 // if in Unicode Plane 2, probably HKCS (incl in BIG5) if not Japanese
31496 else if (preg_match("/[\x{20000}-\x{2FFFF}]/u", $str)) {
31497 return "\xef\xbf\xb0span lang=\"zh-HK\"\xef\xbf\xb1" . $str ."\xef\xbf\xb0/span\xef\xbf\xb1";
31498 }
31499 else{
31500 return "\xef\xbf\xb0span lang=\"zh-CN\"\xef\xbf\xb1" . $str ."\xef\xbf\xb0/span\xef\xbf\xb1";
31501 }
31502 return $str;
31503 }
31504 /*-- END CJK-FONTS --*/
31505
31506 /*-- RTL --*/
31507 function replaceArabic($str) {
31508 // PASHTO, SINDHI, URDU, ARABIC, PERSIAN
31509 $persian = "\x{067E}\x{0686}\x{0698}\x{06AF}";
31510
31511 $urdu = "\x{0679}\x{0688}\x{0691}\x{06BA}\x{06BE}\x{06C1}\x{06D2}";
31512 $pashto = "\x{067C}\x{0681}\x{0685}\x{0689}\x{0693}\x{0696}\x{069A}\x{06BC}\x{06D0}";
31513 $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}";
31514 // Use U=FFF0 and U+FFF1 to mark start and end of span tags to prevent nesting occurring
31515 // "\xef\xbf\xb0" ##lthtmltag## "\xef\xbf\xb1" ##gthtmltag##
31516
31517 if (preg_match("/[".$this->pregNonARABICchars ."]/u", $str) ) {
31518 if (preg_match("/[".$sindhi ."]/u", $str) ) {
31519 return "\xef\xbf\xb0span lang=\"sd\"\xef\xbf\xb1".$str."\xef\xbf\xb0/span\xef\xbf\xb1";
31520 }
31521 else if (preg_match("/[".$urdu ."]/u", $str) ) {
31522 return "\xef\xbf\xb0span lang=\"ur\"\xef\xbf\xb1".$str."\xef\xbf\xb0/span\xef\xbf\xb1";
31523 }
31524 else if (preg_match("/[".$pashto ."]/u", $str) ) {
31525 return "\xef\xbf\xb0span lang=\"ps\"\xef\xbf\xb1".$str."\xef\xbf\xb0/span\xef\xbf\xb1";
31526 }
31527 else if (preg_match("/[".$persian ."]/u", $str) ) {
31528 return "\xef\xbf\xb0span lang=\"fa\"\xef\xbf\xb1".$str."\xef\xbf\xb0/span\xef\xbf\xb1";
31529 }
31530 else {
31531 return "\xef\xbf\xb0span lang=\"ar\"\xef\xbf\xb1".$str."\xef\xbf\xb0/span\xef\xbf\xb1";
31532 }
31533 }
31534 if (preg_match("/[".$persian ."]/u", $str) ) {
31535 return "\xef\xbf\xb0span lang=\"fa\"\xef\xbf\xb1".$str."\xef\xbf\xb0/span\xef\xbf\xb1";
31536 }
31537 else {
31538 return "\xef\xbf\xb0span lang=\"ar\"\xef\xbf\xb1".$str."\xef\xbf\xb0/span\xef\xbf\xb1";
31539 }
31540 return $str;
31541 }
31542
31543 // ARABIC ===========================
31544 function InitArabic() {
31545
31546 // JOIN TO FOLLOWING LETTER IN LOGICAL ORDER
31547 // U+060c U+061f; U+061b; U+0640; U+0626; U+0628; U+062a; U+062b; U+062c; U+062d; U+062e; U+0633; U+0634; U+0635; U+0636; U+0637;
31548 // U+0638; U+0639; U+063a; U+0641; U+0642; U+0643; U+0644; U+0645; U+0646; U+0647; U+064a; U+06a9; U+06cc; U+0686; U+06af; U+067e;
31549 // U+06D0; U+0681; U+06C1;
31550 $this->arabPrevLink = "\xd8\x8c\xd8\x9f\xd8\x9b\xd9\x80\xd8\xa6\xd8\xa8\xd8\xaa\xd8\xab\xd8\xac\xd8\xad\xd8\xae\xd8\xb3\xd8\xb4\xd8\xb5\xd8\xb6\xd8\xb7\xd8\xb8\xd8\xb9\xd8\xba\xd9\x81\xd9\x82\xd9\x83\xd9\x84\xd9\x85\xd9\x86\xd9\x87\xd9\x8a\xda\xa9\xdb\x8c\xda\x86\xda\xaf\xd9\xbe\xdb\x90\xda\x81\xdb\x81";
31551
31552
31553 // \xda\x98 (U+0698) removed from arabPrevLink
31554 // \xd9\xb1 (U+0671) added to arabNextLink & final form added to Persian Glyphs (FB51)
31555
31556
31557 // JOIN TO PREVIOUS LETTER IN LOGICAL ORDER
31558 // U+0640 U+0622; U+0623; U+0624; U+0625; U+0627; U+0626; U+0628; U+0629; U+062a; U+062b; U+062c; U+062d; U+062e; U+062f; U+0630;
31559 // U+0631; U+0632; U+0633; U+0634; U+0635; U+0636; U+0637; U+0638; U+0639; U+063a; U+0641; U+0642; U+0643; U+0644; U+0645; U+0646;
31560 // U+0647; U+0648; U+0649; U+064a; U+06a9; U+06cc; U+0686; U+06af; U+0698; U+067e;
31561 // U+0671; U+06D0; U+0696; U+0693; U+06D2; U+06C1;
31562 $this->arabNextLink = "\xd9\x80\xd8\xa2\xd8\xa3\xd8\xa4\xd8\xa5\xd8\xa7\xd8\xa6\xd8\xa8\xd8\xa9\xd8\xaa\xd8\xab\xd8\xac\xd8\xad\xd8\xae\xd8\xaf\xd8\xb0\xd8\xb1\xd8\xb2\xd8\xb3\xd8\xb4\xd8\xb5\xd8\xb6\xd8\xb7\xd8\xb8\xd8\xb9\xd8\xba\xd9\x81\xd9\x82\xd9\x83\xd9\x84\xd9\x85\xd9\x86\xd9\x87\xd9\x88\xd9\x89\xd9\x8a\xda\xa9\xdb\x8c\xda\x86\xda\xaf\xda\x98\xd9\xbe\xd9\xb1\xdb\x90\xda\x96\xda\x93\xdb\x92\xdb\x81";
31563
31564
31565 // U+064b U+064c; U+064d; U+064e; U+064f; U+0650; U+0651; U+0652;
31566 $this->arabVowels = "\xd9\x8b\xd9\x8c\xd9\x8d\xd9\x8e\xd9\x8f\xd9\x90\xd9\x91\xd9\x92";
31567
31568 // Added chars that may not be vowels but should not interrupt joining
31569 // U+0670; U+0653;
31570 $this->arabVowels .= "\xd9\xb0\xd9\x93";
31571 // ? should also add - U+615, 616, 617-61A, 653-65E, 6D6-6DC, 6DF-6E4, 6E7, 6E8, 6EA-6ED
31572
31573 // DON'T ADD ANY MORE TO ARABGLYPHS - cf. ArabJoin() counts 48 then does ligatures - use PersianGlyphs below
31574 // ISOLATED FORM :: FINAL :: INITIAL :: MEDIAL
31575
31576 // U+064B; U+064C; U+064D; U+064E; U+064F; U+0650; U+0651; U+0652;
31577 $this->arabGlyphs = "\xd9\x8b\xd9\x8c\xd9\x8d\xd9\x8e\xd9\x8f\xd9\x90\xd9\x91\xd9\x92";
31578 $this->arabHex = '064B064B064B064B064C064C064C064C064D064D064D064D064E064E064E064E064F064F064F064F065006500650065006510651065106510652065206520652';
31579
31580 // U+0621; U+0622; U+0623; U+0624; U+0625; U+0626; U+0627; U+0628;
31581 $this->arabGlyphs .= "\xd8\xa1\xd8\xa2\xd8\xa3\xd8\xa4\xd8\xa5\xd8\xa6\xd8\xa7\xd8\xa8";
31582 $this->arabHex .= '06210621062106210622FE820622FE820623FE840623FE840624FE860624FE860625FE880625FE880626FE8AFE8BFE8C0627FE8E0627FE8E0628FE90FE91FE92';
31583
31584
31585 // U+0629; U+062A; U+062B; U+062C; U+062D; U+062E; U+062F; U+0630;
31586 $this->arabGlyphs .= "\xd8\xa9\xd8\xaa\xd8\xab\xd8\xac\xd8\xad\xd8\xae\xd8\xaf\xd8\xb0";
31587 $this->arabHex .= '0629FE940629FE94062AFE96FE97FE98062BFE9AFE9BFE9C062CFE9EFE9FFEA0062DFEA2FEA3FEA4062EFEA6FEA7FEA8062FFEAA062FFEAA0630FEAC0630FEAC';
31588
31589
31590 // U+0631; U+0632; U+0633; U+0634; U+0635; U+0636; U+0637; U+0638;
31591 $this->arabGlyphs .= "\xd8\xb1\xd8\xb2\xd8\xb3\xd8\xb4\xd8\xb5\xd8\xb6\xd8\xb7\xd8\xb8";
31592 $this->arabHex .= '0631FEAE0631FEAE0632FEB00632FEB00633FEB2FEB3FEB40634FEB6FEB7FEB80635FEBAFEBBFEBC0636FEBEFEBFFEC00637FEC2FEC3FEC40638FEC6FEC7FEC8';
31593
31594
31595 // U+0639; U+063A; U+0641; U+0642; U+0643; U+0644; U+0645; U+0646;
31596 $this->arabGlyphs .= "\xd8\xb9\xd8\xba\xd9\x81\xd9\x82\xd9\x83\xd9\x84\xd9\x85\xd9\x86";
31597 $this->arabHex .= '0639FECAFECBFECC063AFECEFECFFED00641FED2FED3FED40642FED6FED7FED80643FEDAFEDBFEDC0644FEDEFEDFFEE00645FEE2FEE3FEE40646FEE6FEE7FEE8';
31598
31599
31600 // U+0647; U+0648; U+0649; U+064A; U+0640; U+060C; U+061F; U+061B;
31601 $this->arabGlyphs .= "\xd9\x87\xd9\x88\xd9\x89\xd9\x8a\xd9\x80\xd8\x8c\xd8\x9f\xd8\x9b";
31602 // 0649 Initial or medial probably meant to be YEH (064A) so Initial and Medial forms of YEH given
31603 $this->arabHex .= '0647FEEAFEEBFEEC0648FEEE0648FEEE0649FEF0FEF3FEF4064AFEF2FEF3FEF40640064006400640060C060C060C060C061F061F061F061F061B061B061B061B';
31604 // 0649 Alef Maksura should only appear at end of word (in Arabic) So final form given as FEF0. Initial and medial are shown as isolated/final
31605 // $this->arabHex .= '0647FEEAFEEBFEEC0648FEEE0648FEEE0649FEF00649FEF0064AFEF2FEF3FEF40640064006400640060C060C060C060C061F061F061F061F061B061B061B061B';
31606 // 0649 Alef Maksura Initial and Medial forms as given in Unicode FBE8 and FBE9 (not in most fonts) - dotless vesions of above
31607 // $this->arabHex .= '0647FEEAFEEBFEEC0648FEEE0648FEEE0649FEF0FBE8FBE9064AFEF2FEF3FEF40640064006400640060C060C060C060C061F061F061F061F061B061B061B061B';
31608
31609 // LAM with ALEF ligatures
31610 // U+0644; U+0622; U+0644; U+0623; U+0644; U+0625; U+0644; U+0627;
31611 $this->arabGlyphs .= "\xd9\x84\xd8\xa2\xd9\x84\xd8\xa3\xd9\x84\xd8\xa5\xd9\x84\xd8\xa7";
31612 $this->arabHex .= 'FEF5FEF6FEF5FEF6FEF7FEF8FEF7FEF8FEF9FEFAFEF9FEFAFEFBFEFCFEFBFEFC';
31613
31614
31615
31616 // Added Arabic Presentation Forms - A - for Persian and other langauges
31617 // U+067B; U+067E; U+0680; U+067A; U+067F; U+0679; U+06A4; U+06A6;
31618 $this->persianGlyphs = "\xd9\xbb\xd9\xbe\xda\x80\xd9\xba\xd9\xbf\xd9\xb9\xda\xa4\xda\xa6";
31619 $this->persianHex = '067BFB53FB54FB55067EFB57FB58FB590680FB5BFB5CFB5D067AFB5FFB60FB61067FFB63FB64FB650679FB67FB68FB6906A4FB6BFB6CFB6D06A6FB6FFB70FB71';
31620
31621 // U+0684; U+0683; U+0686; U+0687; U+0698; U+0691; U+06A9; U+06Af;
31622 $this->persianGlyphs .= "\xda\x84\xda\x83\xda\x86\xda\x87\xda\x98\xda\x91\xda\xa9\xda\xaf";
31623 $this->persianHex .= '0684FB73FB74FB750683FB77FB78FB790686FB7BFB7CFB7D0687FB7FFB80FB810698FB8B0698FB8B0691FB8D0691FB8D06A9FB8FFB90FB9106AfFB93FB94FB95';
31624
31625 // U+06BA; U+06CC; U+06C1; U+0671; U+06D0; U+06D2;
31626 // 06C1 final form is same as isolated so use 06C1
31627 $this->persianGlyphs .= "\xda\xba\xdb\x8c\xdb\x81\xd9\xb1\xdb\x90\xdb\x92";
31628 $this->persianHex .= '06BAFB9F06BAFB9F06CCFBFDFBFEFBFF06C106C1FBA8FBA90671FB510671FB5106D0FBE5FBE6FBE706D2FBAF06D2FBAF';
31629
31630 }
31631 // ----------------------------------------------------------------------
31632 // Derived from ArPHP
31633 // by Khaled Al-Shamaa
31634 // http://www.ar-php.org
31635 // ----------------------------------------------------------------------
31636 function ArabJoin($str) {
31637 if (!$this->arabGlyphs) { $this->InitArabic(); }
31638 $crntChar = null;
31639 $prevChar = null;
31640 $nextChar = null;
31641 $output = array();
31642 $chars = preg_split('//u', $str);
31643 $max = count($chars);
31644 for ($i = $max - 1; $i >= 0; $i--) {
31645 $crntChar = $chars[$i];
31646 if ($i > 0){ $prevChar = $chars[$i - 1]; }
31647 else{ $prevChar = NULL; }
31648 if ($prevChar && mb_strpos($this->arabVowels, $prevChar, 0, 'utf-8') !== false) {
31649 $prevChar = $chars[$i - 2];
31650 if ($prevChar && mb_strpos($this->arabVowels, $prevChar, 0, 'utf-8') !== false) {
31651 $prevChar = $chars[$i - 3];
31652 }
31653 }
31654 if ($crntChar && mb_strpos($this->arabVowels, $crntChar, 0, 'utf-8') !== false) {
31655 // If next_char = nextLink && prev_char = prevLink:
31656 // Added && $prevchar (defined) else error on mb_strpos()
31657 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)) {
31658 $output[] = '&#x' . $this->get_arab_glyphs($crntChar, 1) . ';'; // <final> form
31659 }
31660 else {
31661 $output[] = '&#x' . $this->get_arab_glyphs($crntChar, 0) . ';'; // <isolated> form
31662 }
31663 continue;
31664 }
31665 // NB = &#x622 &#x623; &#x625; &#x627; &#x644;
31666 if (isset($chars[$i + 1]) && in_array($chars[$i + 1], array("\xd8\xa2","\xd8\xa3","\xd8\xa5","\xd8\xa7")) && $crntChar == "\xd9\x84"){
31667 continue;
31668 }
31669 if (ord($crntChar) < 128) {
31670 $output[] = $crntChar;
31671 $nextChar = $crntChar;
31672 continue;
31673 }
31674 $form = 0;
31675 if (in_array($crntChar, array("\xd8\xa2", "\xd8\xa3", "\xd8\xa5", "\xd8\xa7")) && $prevChar == "\xd9\x84") {
31676 if ($chars[$i - 2] && mb_strpos($this->arabPrevLink, $chars[$i - 2], 0, 'utf-8') !== false) {
31677 $form++; // <final> form
31678 }
31679 $output[] = '&#x' . $this->get_arab_glyphs($prevChar . $crntChar, $form) . ';';
31680 $nextChar = $prevChar;
31681 continue;
31682 }
31683 if ($prevChar && mb_strpos($this->arabPrevLink, $prevChar, 0, 'utf-8') !== false) {
31684 $form++;
31685 }
31686 if ($nextChar && mb_strpos($this->arabNextLink, $nextChar, 0, 'utf-8') !== false) {
31687 $form += 2;
31688 }
31689 $output[] = '&#x' . $this->get_arab_glyphs($crntChar, $form) . ';';
31690 $nextChar = $crntChar;
31691 }
31692 $ra = array_reverse($output);
31693 $s = implode($ra);
31694 $s = strcode2utf($s);
31695 return $s;
31696 }
31697
31698 function get_arab_glyphs($char, $type) {
31699 $pos = mb_strpos($this->arabGlyphs, $char, 0, 'utf-8');
31700 if ($pos === false) { // If character not covered here
31701 $pos = mb_strpos($this->persianGlyphs, $char, 0, 'utf-8'); // Try Persian additions
31702 if ($pos === false) { // return original character
31703 $x = mb_encode_numericentity ($char, array (0x0, 0xffff, 0, 0xffff), 'UTF-8');
31704 preg_match('/&#(\d+);/', $x, $m);
31705 return dechex($m[1]);
31706 }
31707 else { // if covered by Added Persian chars
31708 $pos = $pos*16 + $type*4;
31709 return mb_substr($this->persianHex, $pos, 4, 'utf-8');
31710 }
31711 }
31712 if ($pos > 48){
31713 $pos = ($pos-48)/2 + 48;
31714 }
31715 $pos = $pos*16 + $type*4;
31716 return mb_substr($this->arabHex, $pos, 4, 'utf-8');
31717 }
31718 /*-- END RTL --*/
31719
31720
31721 function _getMQR() {
31722 $mqr=ini_get("magic_quotes_runtime");
31723 if (PHP_VERSION_ID < 50300) { return @get_magic_quotes_runtime(); }
31724 else { return 0; }
31725 }
31726
31727 //===========================
31728 // Functions originally in htmltoolkit - moved mPDF 4.0
31729
31730 // Call-back function Used for usort in fn _tableWrite
31731
31732 function _cmpdom($a, $b) {
31733 return ($a["dom"] < $b["dom"]) ? -1 : 1;
31734 }
31735
31736 function mb_strrev($str, $enc = 'utf-8'){
31737 $ch = array();
31738 $ch = preg_split('//u',$str);
31739 $revch = array_reverse($ch);
31740 return implode('',$revch);
31741 }
31742
31743 /*-- COLUMNS --*/
31744 // Callback function from function printcolumnbuffer in mpdf
31745 function columnAdjustAdd($type,$k,$xadj,$yadj,$a,$b,$c=0,$d=0,$e=0,$f=0) {
31746 if ($type == 'Td') { // xpos,ypos
31747 $a += ($xadj * $k);
31748 $b -= ($yadj * $k);
31749 return 'BT '.sprintf('%.3F %.3F',$a,$b).' Td';
31750 }
31751 else if ($type == 're') { // xpos,ypos,width,height
31752 $a += ($xadj * $k);
31753 $b -= ($yadj * $k);
31754 return sprintf('%.3F %.3F %.3F %.3F',$a,$b,$c,$d).' re';
31755 }
31756 else if ($type == 'l') { // xpos,ypos,x2pos,y2pos
31757 $a += ($xadj * $k);
31758 $b -= ($yadj * $k);
31759 return sprintf('%.3F %.3F l',$a,$b);
31760 }
31761 else if ($type == 'img') { // width,height,xpos,ypos
31762 $c += ($xadj * $k);
31763 $d -= ($yadj * $k);
31764 return sprintf('q %.3F 0 0 %.3F %.3F %.3F',$a,$b,$c,$d).' cm /'.$e;
31765 }
31766 else if ($type == 'draw') { // xpos,ypos
31767 $a += ($xadj * $k);
31768 $b -= ($yadj * $k);
31769 return sprintf('%.3F %.3F m',$a,$b);
31770 }
31771 else if ($type == 'bezier') { // xpos,ypos,x2pos,y2pos,x3pos,y3pos
31772 $a += ($xadj * $k);
31773 $b -= ($yadj * $k);
31774 $c += ($xadj * $k);
31775 $d -= ($yadj * $k);
31776 $e += ($xadj * $k);
31777 $f -= ($yadj * $k);
31778 return sprintf('%.3F %.3F %.3F %.3F %.3F %.3F',$a,$b,$c,$d,$e,$f).' c';
31779 }
31780 }
31781 /*-- END COLUMNS --*/
31782
31783 // Callback function from function printdivbuffer in mpdf - keeping block together on one page
31784 function blockAdjust($type,$k,$xadj,$yadj,$a,$b,$c=0,$d=0,$e=0,$f=0) {
31785 if ($type == 'Td') { // xpos,ypos
31786 $a += ($xadj * $k);
31787 $b -= ($yadj * $k);
31788 return 'BT '.sprintf('%.3F %.3F',$a,$b).' Td';
31789 }
31790 else if ($type == 're') { // xpos,ypos,width,height
31791 $a += ($xadj * $k);
31792 $b -= ($yadj * $k);
31793 return sprintf('%.3F %.3F %.3F %.3F',$a,$b,$c,$d).' re';
31794 }
31795 else if ($type == 'l') { // xpos,ypos,x2pos,y2pos
31796 $a += ($xadj * $k);
31797 $b -= ($yadj * $k);
31798 return sprintf('%.3F %.3F l',$a,$b);
31799 }
31800 else if ($type == 'img') { // width,height,xpos,ypos
31801 $c += ($xadj * $k);
31802 $d -= ($yadj * $k);
31803 return sprintf('q %.3F 0 0 %.3F %.3F %.3F',$a,$b,$c,$d).' cm /'.$e;
31804 }
31805 else if ($type == 'draw') { // xpos,ypos
31806 $a += ($xadj * $k);
31807 $b -= ($yadj * $k);
31808 return sprintf('%.3F %.3F m',$a,$b);
31809 }
31810 else if ($type == 'bezier') { // xpos,ypos,x2pos,y2pos,x3pos,y3pos
31811 $a += ($xadj * $k);
31812 $b -= ($yadj * $k);
31813 $c += ($xadj * $k);
31814 $d -= ($yadj * $k);
31815 $e += ($xadj * $k);
31816 $f -= ($yadj * $k);
31817 return sprintf('%.3F %.3F %.3F %.3F %.3F %.3F',$a,$b,$c,$d,$e,$f).' c';
31818 }
31819 }
31820
31821
31822
31823 function ConvertColor($color="#000000"){
31824 $color = trim(strtolower($color));
31825 $c = false;
31826 if ($color=='transparent') { return false; }
31827 else if ($color=='inherit') { return false; }
31828 else if (isset($this->SVGcolors[$color])) $color = $this->SVGcolors[$color];
31829
31830 if (preg_match('/^[\d]+$/',$color)) { $c = (array(1,$color)); } // i.e. integer only
31831 else if ($color[0] == '#') { //case of #nnnnnn or #nnn
31832 $cor = preg_replace('/\s+.*/','',$color); // in case of Background: #CCC url() x-repeat etc.
31833 if (strlen($cor) == 4) { // Turn #RGB into #RRGGBB
31834 $cor = "#" . $cor[1] . $cor[1] . $cor[2] . $cor[2] . $cor[3] . $cor[3];
31835 }
31836 $r = hexdec(substr($cor, 1, 2));
31837 $g = hexdec(substr($cor, 3, 2));
31838 $b = hexdec(substr($cor, 5, 2));
31839 $c = array(3,$r,$g,$b);
31840 }
31841 else if (preg_match('/(rgba|rgb|cmyka|cmyk|hsla|hsl|spot)\((.*?)\)/',$color,$m)) {
31842 $type= $m[1];
31843 $cores = explode(",", $m[2]);
31844 $ncores = count($cores); // mPDF 5.3.76
31845 if (stristr($cores[0],'%') ) {
31846 $cores[0] += 0;
31847 if ($type=='rgb' || $type=='rgba') { $cores[0] = intval($cores[0]*255/100); }
31848 }
31849 if ($ncores>1 && stristr($cores[1],'%') ) {
31850 $cores[1] += 0;
31851 if ($type=='rgb' || $type=='rgba') { $cores[1] = intval($cores[1]*255/100); }
31852 if ($type=='hsl' || $type=='hsla') { $cores[1] = $cores[1]/100; }
31853 }
31854 if ($ncores>2 && stristr($cores[2],'%') ) {
31855 $cores[2] += 0;
31856 if ($type=='rgb' || $type=='rgba') { $cores[2] = intval($cores[2]*255/100); }
31857 if ($type=='hsl' || $type=='hsla') { $cores[2] = $cores[2]/100; }
31858 }
31859 if ($ncores>3 && stristr($cores[3],'%') ) {
31860 $cores[3] += 0;
31861 }
31862
31863 if ($type=='rgb') { $c = array(3,$cores[0],$cores[1],$cores[2]); }
31864 else if ($type=='rgba') { $c = array(5,$cores[0],$cores[1],$cores[2],$cores[3]*100); } // mPDF 5.3.74
31865 else if ($type=='cmyk') { $c = array(4,$cores[0],$cores[1],$cores[2],$cores[3]); }
31866 else if ($type=='cmyka') { $c = array(6,$cores[0],$cores[1],$cores[2],$cores[3],$cores[4]*100); } // mPDF 5.3.74
31867 else if ($type=='hsl' || $type=='hsla') {
31868 $conv = $this->hsl2rgb($cores[0]/360,$cores[1],$cores[2]);
31869 if ($type=='hsl') { $c = array(3,$conv[0],$conv[1],$conv[2]); }
31870 else if ($type=='hsla') { $c = array(5,$conv[0],$conv[1],$conv[2],$cores[3]*100); } // mPDF 5.3.74
31871 }
31872 else if ($type=='spot') {
31873 $name = strtoupper(trim($cores[0]));
31874 if(!isset($this->spotColors[$name])) $this->Error('Undefined spot color: '.$name);
31875 $c = array(2,$this->spotColors[$name]['i'],$cores[1]);
31876 }
31877 }
31878
31879
31880 // $this->restrictColorSpace
31881 // 1 - allow GRAYSCALE only [convert CMYK/RGB->gray]
31882 // 2 - allow RGB / SPOT COLOR / Grayscale [convert CMYK->RGB]
31883 // 3 - allow CMYK / SPOT COLOR / Grayscale [convert RGB->CMYK]
31884 if ($this->PDFA || $this->PDFX || $this->restrictColorSpace) {
31885 if ($c[0]==1) { // GRAYSCALE
31886 }
31887 else if ($c[0]==2) { // SPOT COLOR
31888 if (!isset($this->spotColorIDs[$c[1]])) { die('Error: Spot colour has not been defined - '.$this->spotColorIDs[$c[1]]); }
31889 if ($this->PDFA) {
31890 if ($this->PDFA && !$this->PDFAauto) { $this->PDFAXwarnings[] = "Spot color specified '".$this->spotColorIDs[$c[1]]."' (converted to process color)"; }
31891 if ($this->restrictColorSpace!=3) {
31892 $sp = $this->spotColors[$this->spotColorIDs[$c[1]]];
31893 $c = $this->cmyk2rgb(array(4,$sp['c'],$sp['m'],$sp['y'],$sp['k']));
31894 }
31895 }
31896 else if ($this->restrictColorSpace==1) {
31897 $sp = $this->spotColors[$this->spotColorIDs[$c[1]]];
31898 $c = $this->cmyk2gray(array(4,$sp['c'],$sp['m'],$sp['y'],$sp['k']));
31899 }
31900 }
31901 else if ($c[0]==3) { // RGB
31902 if ($this->PDFX || ($this->PDFA && $this->restrictColorSpace==3)) {
31903 if (($this->PDFA && !$this->PDFAauto) || ($this->PDFX && !$this->PDFXauto)) { $this->PDFAXwarnings[] = "RGB color specified '".$color."' (converted to CMYK)"; }
31904 $c = $this->rgb2cmyk($c);
31905 }
31906 else if ($this->restrictColorSpace==1) { $c = $this->rgb2gray($c); }
31907 else if ($this->restrictColorSpace==3) { $c = $this->rgb2cmyk($c); }
31908 }
31909 else if ($c[0]==4) { // CMYK
31910 if ($this->PDFA && $this->restrictColorSpace!=3) {
31911 if ($this->PDFA && !$this->PDFAauto) { $this->PDFAXwarnings[] = "CMYK color specified '".$color."' (converted to RGB)"; }
31912 $c = $this->cmyk2rgb($c);
31913 }
31914 else if ($this->restrictColorSpace==1) { $c = $this->cmyk2gray($c); }
31915 else if ($this->restrictColorSpace==2) { $c = $this->cmyk2rgb($c); }
31916 }
31917 else if ($c[0]==5) { // RGBa
31918 if ($this->PDFX || ($this->PDFA && $this->restrictColorSpace==3)) {
31919 if (($this->PDFA && !$this->PDFAauto) || ($this->PDFX && !$this->PDFXauto)) { $this->PDFAXwarnings[] = "RGB color with transparency specified '".$color."' (converted to CMYK without transparency)"; }
31920 $c = $this->rgb2cmyk($c);
31921 $c = array(4, $c[1], $c[2], $c[3], $c[4]);
31922 }
31923 else if ($this->PDFA && $this->restrictColorSpace!=3) {
31924 if (!$this->PDFAauto) { $this->PDFAXwarnings[] = "RGB color with transparency specified '".$color."' (converted to RGB without transparency)"; }
31925 $c = $this->rgb2cmyk($c);
31926 $c = array(4, $c[1], $c[2], $c[3], $c[4]);
31927 }
31928 else if ($this->restrictColorSpace==1) { $c = $this->rgb2gray($c); }
31929 else if ($this->restrictColorSpace==3) { $c = $this->rgb2cmyk($c); }
31930 }
31931 else if ($c[0]==6) { // CMYKa
31932 if ($this->PDFA && $this->restrictColorSpace!=3) {
31933 if (($this->PDFA && !$this->PDFAauto) || ($this->PDFX && !$this->PDFXauto)) { $this->PDFAXwarnings[] = "CMYK color with transparency specified '".$color."' (converted to RGB without transparency)"; }
31934 $c = $this->cmyk2rgb($c);
31935 $c = array(3, $c[1], $c[2], $c[3]);
31936 }
31937 else if ($this->PDFX || ($this->PDFA && $this->restrictColorSpace==3)) {
31938 if (($this->PDFA && !$this->PDFAauto) || ($this->PDFX && !$this->PDFXauto)) { $this->PDFAXwarnings[] = "CMYK color with transparency specified '".$color."' (converted to CMYK without transparency)"; }
31939 $c = $this->cmyk2rgb($c);
31940 $c = array(3, $c[1], $c[2], $c[3]);
31941 }
31942 else if ($this->restrictColorSpace==1) { $c = $this->cmyk2gray($c); }
31943 else if ($this->restrictColorSpace==2) { $c = $this->cmyk2rgb($c); }
31944 }
31945 }
31946 // mPDF 5.3.74
31947 if (is_array($c)) {
31948 $c = array_pad($c, 6, 0);
31949 $cstr = pack("a1ccccc", $c[0], ($c[1] & 0xFF), ($c[2] & 0xFF), ($c[3] & 0xFF), ($c[4] & 0xFF), ($c[5] & 0xFF) );
31950 }
31951 return $cstr;
31952 }
31953
31954 function rgb2gray($c) {
31955 // mPDF 5.3.74
31956 if (isset($c[4])) { return array(1,(($c[1] * .21) + ($c[2] * .71) + ($c[3] * .07)), ord(1), $c[4]); }
31957 else { return array(1,(($c[1] * .21) + ($c[2] * .71) + ($c[3] * .07))); }
31958 }
31959
31960 function cmyk2gray($c) {
31961 $rgb = $this->cmyk2rgb($c);
31962 return $this->rgb2gray($rgb);
31963 }
31964
31965 function rgb2cmyk($c) {
31966 $cyan = 1 - ($c[1] / 255);
31967 $magenta = 1 - ($c[2] / 255);
31968 $yellow = 1 - ($c[3] / 255);
31969 $min = min($cyan, $magenta, $yellow);
31970
31971 if ($min == 1) {
31972 if ($c[0]==5) { return array (6,100,100,100,100, $c[4]); }
31973 else { return array (4,100,100,100,100); }
31974 // For K-Black
31975 //if ($c[0]==5) { return array (6,0,0,0,100, $c[4]); }
31976 //else { return array (4,0,0,0,100); }
31977 }
31978 $K = $min;
31979 $black = 1 - $K;
31980 if ($c[0]==5) { return array (6,($cyan-$K)*100/$black, ($magenta-$K)*100/$black, ($yellow-$K)*100/$black, $K*100, $c[4]); }
31981 else { return array (4,($cyan-$K)*100/$black, ($magenta-$K)*100/$black, ($yellow-$K)*100/$black, $K*100); }
31982 }
31983
31984
31985 function cmyk2rgb($c) {
31986 $rgb = array();
31987 $colors = 255 - ($c[4]*2.55);
31988 $rgb[0] = intval($colors * (255 - ($c[1]*2.55))/255);
31989 $rgb[1] = intval($colors * (255 - ($c[2]*2.55))/255);
31990 $rgb[2] = intval($colors * (255 - ($c[3]*2.55))/255);
31991 if ($c[0]==6) { return array (5,$rgb[0],$rgb[1],$rgb[2], $c[5]); }
31992 else { return array (3,$rgb[0],$rgb[1],$rgb[2]); }
31993 }
31994
31995 function rgb2hsl($var_r, $var_g, $var_b) {
31996 $var_min = min($var_r,$var_g,$var_b);
31997 $var_max = max($var_r,$var_g,$var_b);
31998 $del_max = $var_max - $var_min;
31999 $l = ($var_max + $var_min) / 2;
32000 if ($del_max == 0) {
32001 $h = 0;
32002 $s = 0;
32003 }
32004 else {
32005 if ($l < 0.5) { $s = $del_max / ($var_max + $var_min); }
32006 else { $s = $del_max / (2 - $var_max - $var_min); }
32007 $del_r = ((($var_max - $var_r) / 6) + ($del_max / 2)) / $del_max;
32008 $del_g = ((($var_max - $var_g) / 6) + ($del_max / 2)) / $del_max;
32009 $del_b = ((($var_max - $var_b) / 6) + ($del_max / 2)) / $del_max;
32010 if ($var_r == $var_max) { $h = $del_b - $del_g; }
32011 elseif ($var_g == $var_max) { $h = (1 / 3) + $del_r - $del_b; }
32012 elseif ($var_b == $var_max) { $h = (2 / 3) + $del_g - $del_r; };
32013 if ($h < 0) { $h += 1; }
32014 if ($h > 1) { $h -= 1; }
32015 }
32016 return array($h,$s,$l);
32017 }
32018
32019
32020 function hsl2rgb($h2,$s2,$l2) {
32021 // Input is HSL value of complementary colour, held in $h2, $s, $l as fractions of 1
32022 // Output is RGB in normal 255 255 255 format, held in $r, $g, $b
32023 // Hue is converted using function hue_2_rgb, shown at the end of this code
32024 if ($s2 == 0) {
32025 $r = $l2 * 255;
32026 $g = $l2 * 255;
32027 $b = $l2 * 255;
32028 }
32029 else {
32030 if ($l2 < 0.5) { $var_2 = $l2 * (1 + $s2); }
32031 else { $var_2 = ($l2 + $s2) - ($s2 * $l2); }
32032 $var_1 = 2 * $l2 - $var_2;
32033 $r = round(255 * $this->hue_2_rgb($var_1,$var_2,$h2 + (1 / 3)));
32034 $g = round(255 * $this->hue_2_rgb($var_1,$var_2,$h2));
32035 $b = round(255 * $this->hue_2_rgb($var_1,$var_2,$h2 - (1 / 3)));
32036 }
32037 return array($r,$g,$b);
32038 }
32039
32040 function hue_2_rgb($v1,$v2,$vh) {
32041 // Function to convert hue to RGB, called from above
32042 if ($vh < 0) { $vh += 1; };
32043 if ($vh > 1) { $vh -= 1; };
32044 if ((6 * $vh) < 1) { return ($v1 + ($v2 - $v1) * 6 * $vh); };
32045 if ((2 * $vh) < 1) { return ($v2); };
32046 if ((3 * $vh) < 2) { return ($v1 + ($v2 - $v1) * ((2 / 3 - $vh) * 6)); };
32047 return ($v1);
32048 }
32049
32050 function _invertColor($cor) {
32051 if ($cor[0]==3 || $cor[0]==5) { // RGB
32052 return array(3, (255-$cor[1]), (255-$cor[2]), (255-$cor[3]));
32053 }
32054 else if ($cor[0]==4 || $cor[0]==6) { // CMYK
32055 return array(4, (100-$cor[1]), (100-$cor[2]), (100-$cor[3]), (100-$cor[4]));
32056 }
32057 else if ($cor[0]==1) { // Grayscale
32058 return array(1, (255-$cor[1]));
32059 }
32060 // Cannot cope with non-RGB colors at present
32061 die('Error in _invertColor - trying to invert non-RGB color');
32062 }
32063
32064 function _colAtoString($cor) {
32065 $s = '';
32066 // mPDF 5.3.74
32067 if ($cor{0}==1) $s = 'rgb('.ord($cor{1}).','.ord($cor{1}).','.ord($cor{1}).')';
32068 else if ($cor{0}==2) $s = 'spot('.ord($cor{1}).','.ord($cor{2}).')'; // SPOT COLOR
32069 else if ($cor{0}==3) $s = 'rgb('.ord($cor{1}).','.ord($cor{2}).','.ord($cor{3}).')';
32070 else if ($cor{0}==4) $s = 'cmyk('.ord($cor{1}).','.ord($cor{2}).','.ord($cor{3}).','.ord($cor{4}).')';
32071 else if ($cor{0}==5) $s = 'rgba('.ord($cor{1}).','.ord($cor{2}).','.ord($cor{3}).','.sprintf('%0.2F',ord($cor{4})/100).')';
32072 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).')';
32073 return $s;
32074 }
32075
32076 function ConvertSize($size=5,$maxsize=0,$fontsize=false,$usefontsize=true){
32077 // usefontsize - setfalse for e.g. margins - will ignore fontsize for % values
32078 // Depends of maxsize value to make % work properly. Usually maxsize == pagewidth
32079 // For text $maxsize = Fontsize
32080 // Setting e.g. margin % will use maxsize (pagewidth) and em will use fontsize
32081 //Identify size (remember: we are using 'mm' units here)
32082 $size = trim(strtolower($size));
32083
32084 if ( $size == 'thin' ) $size = 1*(25.4/$this->dpi); //1 pixel width for table borders
32085 elseif ( stristr($size,'px') ) $size *= (25.4/$this->dpi); //pixels
32086 elseif ( stristr($size,'cm') ) $size *= 10; //centimeters
32087 elseif ( stristr($size,'mm') ) $size += 0; //millimeters
32088 elseif ( stristr($size,'pt') ) $size *= 25.4/72; //72 pts/inch
32089 elseif ( stristr($size,'em') ) {
32090 $size += 0; //make "0.83em" become simply "0.83"
32091 if ($fontsize) { $size *= $fontsize; }
32092 else { $size *= $maxsize; }
32093 }
32094 elseif ( stristr($size,'%') ) {
32095 $size += 0; //make "90%" become simply "90"
32096 if ($fontsize && $usefontsize) { $size *= $fontsize/100; }
32097 else { $size *= $maxsize/100; }
32098 }
32099 elseif ( stristr($size,'in') ) $size *= 25.4; //inches
32100 elseif ( stristr($size,'pc') ) $size *= 38.1/9; //PostScript picas
32101 elseif ( stristr($size,'ex') ) { // Approximates "ex" as half of font height
32102 $size += 0; //make "3.5ex" become simply "3.5"
32103 if ($fontsize) { $size *= $fontsize/2; }
32104 else { $size *= $maxsize/2; }
32105 }
32106 elseif ( $size == 'medium' ) $size = 3*(25.4/$this->dpi); //3 pixel width for table borders
32107 elseif ( $size == 'thick' ) $size = 5*(25.4/$this->dpi); //5 pixel width for table borders
32108 elseif ($size == 'xx-small') {
32109 if ($fontsize) { $size *= $fontsize*0.7; }
32110 else { $size *= $maxsize*0.7; }
32111 }
32112 elseif ($size == 'x-small') {
32113 if ($fontsize) { $size *= $fontsize*0.77; }
32114 else { $size *= $maxsize*0.77; }
32115 }
32116 elseif ($size == 'small') {
32117 if ($fontsize) { $size *= $fontsize*0.86; }
32118 else { $size *= $maxsize*0.86; }
32119 }
32120 elseif ($size == 'medium') {
32121 if ($fontsize) { $size *= $fontsize; }
32122 else { $size *= $maxsize; }
32123 }
32124 elseif ($size == 'large') {
32125 if ($fontsize) { $size *= $fontsize*1.2; }
32126 else { $size *= $maxsize*1.2; }
32127 }
32128 elseif ($size == 'x-large') {
32129 if ($fontsize) { $size *= $fontsize*1.5; }
32130 else { $size *= $maxsize*1.5; }
32131 }
32132 elseif ($size == 'xx-large') {
32133 if ($fontsize) { $size *= $fontsize*2; }
32134 else { $size *= $maxsize*2; }
32135 }
32136 else $size *= (25.4/$this->dpi); //nothing == px
32137
32138 return $size;
32139 }
32140
32141
32142 function lesser_entity_decode($html) {
32143 //supports the most used entity codes (only does ascii safe characters)
32144 //$html = str_replace("&nbsp;"," ",$html); // mPDF 5.3.59
32145 $html = str_replace("&lt;","<",$html);
32146 $html = str_replace("&gt;",">",$html);
32147
32148 $html = str_replace("&apos;","'",$html);
32149 $html = str_replace("&quot;",'"',$html);
32150 $html = str_replace("&amp;","&",$html);
32151 return $html;
32152 }
32153
32154 function AdjustHTML($html, $tabSpaces=8) { // mPDF 5.3.99
32155 //Try to make the html text more manageable (turning it into XHTML)
32156 // mPDF 5.3.97
32157 if (PHP_VERSION_ID < 50307) {
32158 if (strlen($html) > 100000) {
32159 if (PHP_VERSION_ID < 50200) $this->Error("The HTML code is more than 100,000 characters. You should use WriteHTML() with smaller string lengths.");
32160 else ini_set("pcre.backtrack_limit","1000000");
32161 }
32162 }
32163
32164 /*-- ANNOTATIONS --*/
32165 preg_match_all("/(<annotation.*?>)/si", $html, $m);
32166 if (count($m[1])) {
32167 for($i=0;$i<count($m[1]);$i++) {
32168 $sub = preg_replace("/\n/si", "\xbb\xa4\xac", $m[1][$i]);
32169 $html = preg_replace('/'.preg_quote($m[1][$i], '/').'/si', $sub, $html);
32170 }
32171 }
32172 /*-- END ANNOTATIONS --*/
32173
32174 // mPDF 5.3.A6
32175 preg_match_all("/(<svg.*?<\/svg>)/si", $html, $svgi);
32176 if (count($svgi[0])) {
32177 for($i=0;$i<count($svgi[0]);$i++) {
32178 $file = _MPDF_TEMP_PATH.'_tempSVG'.RAND(1,10000).'_'.$i.'.svg';
32179 //Save to local file
32180 file_put_contents($file, $svgi[0][$i]);
32181 $html = preg_replace('/'.preg_quote($svgi[0][$i], '/').'/si', '<img src="'.$file.'" />', $html);
32182 }
32183 }
32184
32185
32186 //Remove javascript code from HTML (should not appear in the PDF file)
32187 $html = preg_replace('/<script.*?<\/script>/is','',$html);
32188
32189 //Remove special comments
32190 $html = preg_replace('/<!--mpdf/i','',$html);
32191 $html = preg_replace('/mpdf-->/i','',$html);
32192
32193 //Remove comments from HTML (should not appear in the PDF file)
32194 $html = preg_replace('/<!--.*?-->/s','',$html);
32195
32196 $html = preg_replace('/\f/','',$html); //replace formfeed by nothing
32197 $html = preg_replace('/\r/','',$html); //replace carriage return by nothing
32198
32199 // Well formed XHTML end tags
32200 $html = preg_replace('/<(br|hr)\/>/i',"<\\1 />",$html);
32201 // Get rid of empty <thead></thead>
32202 $html = preg_replace('/<thead>\s*<\/thead>/i','',$html);
32203 $html = preg_replace('/<tfoot>\s*<\/tfoot>/i','',$html);
32204 $html = preg_replace('/<table[^>]*>\s*<\/table>/i','',$html);
32205 $html = preg_replace('/<tr>\s*<\/tr>/i','',$html);
32206
32207 // Remove spaces at end of table cells
32208 $html = preg_replace("/[ ]+<\/t(d|h)/",'</t\\1',$html);
32209
32210 $html = preg_replace("/[ ]*<dottab\s*[\/]*>[ ]*/",'<dottab />',$html);
32211
32212 // Concatenates any Substitute characters from symbols/dingbats
32213 $html = str_replace('</tts><tts>','|',$html);
32214 $html = str_replace('</ttz><ttz>','|',$html);
32215 $html = str_replace('</tta><tta>','|',$html);
32216
32217 $html = preg_replace('/<br \/>\s*/is',"<br />",$html); // mPDF 5.3.07
32218
32219 // Preserve '\n's in content between the tags <pre> and </pre>
32220 if (preg_match('/<pre/',$html)) {
32221 $html_a = preg_split('/(\<\/?pre[^\>]*\>)/', $html, -1, 2);
32222 $h = array();
32223 $c=0;
32224 foreach($html_a AS $s) {
32225 if ($c>1 && preg_match('/^<\/pre/i',$s)) { $c--; $s=preg_replace('/<\/pre/i','</innerpre',$s); }
32226 else if ($c>0 && preg_match('/^<pre/i',$s)) { $c++; $s=preg_replace('/<pre/i','<innerpre',$s); }
32227 else if (preg_match('/^<pre/i',$s)) { $c++; }
32228 else if (preg_match('/^<\/pre/i',$s)) { $c--; }
32229 array_push($h, $s);
32230 }
32231 $html = implode("", $h);
32232 }
32233 $thereispre = preg_match_all('#<pre(.*?)>(.*?)</pre>#si',$html,$temp);
32234 // Preserve '\n's in content between the tags <textarea> and </textarea>
32235 $thereistextarea = preg_match_all('#<textarea(.*?)>(.*?)</textarea>#si',$html,$temp2);
32236 $html = preg_replace('/[\n]/',' ',$html); //replace linefeed by spaces
32237 $html = preg_replace('/[\t]/',' ',$html); //replace tabs by spaces
32238
32239 // Converts < to &lt; when not a tag
32240 $html = preg_replace('/<([^!\/a-zA-Z])/i','&lt;\\1',$html);
32241 $html = preg_replace("/[ ]+/",' ',$html);
32242
32243 $html = preg_replace('/\/li>\s+<\/(u|o)l/i','/li></\\1l',$html);
32244 $html = preg_replace('/\/(u|o)l>\s+<\/li/i','/\\1l></li',$html);
32245 $html = preg_replace('/\/li>\s+<\/(u|o)l/i','/li></\\1l',$html);
32246 $html = preg_replace('/\/li>\s+<li/i','/li><li',$html);
32247 $html = preg_replace('/<(u|o)l([^>]*)>[ ]+/i','<\\1l\\2>',$html);
32248 $html = preg_replace('/[ ]+<(u|o)l/i','<\\1l',$html);
32249
32250 $iterator = 0;
32251 while($thereispre) //Recover <pre attributes>content</pre>
32252 {
32253 $temp[2][$iterator] = preg_replace("/^([^\n\t]*?)\t/me", "stripslashes('\\1') . str_repeat(' ', ( $tabSpaces - (mb_strlen(stripslashes('\\1')) % $tabSpaces)) )",$temp[2][$iterator]);
32254 $temp[2][$iterator] = preg_replace('/\t/',str_repeat(" ",$tabSpaces),$temp[2][$iterator]);
32255
32256 $temp[2][$iterator] = preg_replace('/\n/',"<br />",$temp[2][$iterator]);
32257 $temp[2][$iterator] = str_replace('\\',"\\\\",$temp[2][$iterator]); // mPDF 5.3.88
32258 $html = preg_replace('#<pre(.*?)>(.*?)</pre>#si','<erp'.$temp[1][$iterator].'>'.$temp[2][$iterator].'</erp>',$html,1);
32259 $thereispre--;
32260 $iterator++;
32261 }
32262 $iterator = 0;
32263 while($thereistextarea) //Recover <textarea attributes>content</textarea>
32264 {
32265 // $temp2[2][$iterator] = preg_replace('/&/',"&amp;",$temp2[2][$iterator]); // mPDF 5.3.59
32266 // $temp2[2][$iterator] = preg_replace('/</',"&lt;",$temp2[2][$iterator]); // mPDF 5.3.59
32267 $temp2[2][$iterator] = preg_replace('/\t/',str_repeat(" ",$tabSpaces),$temp2[2][$iterator]);
32268 $temp2[2][$iterator] = str_replace('\\',"\\\\",$temp2[2][$iterator]); // mPDF 5.3.88
32269 // $temp2[2][$iterator] = preg_replace('/[ ]/',"&nbsp;",$temp2[2][$iterator]); // mPDF 5.3.59
32270 $html = preg_replace('#<textarea(.*?)>(.*?)</textarea>#si','<aeratxet'.$temp2[1][$iterator].'>'.trim($temp2[2][$iterator]) .'</aeratxet>',$html,1);
32271 $thereistextarea--;
32272 $iterator++;
32273 }
32274 //Restore original tag names
32275 $html = str_replace("<erp","<pre",$html);
32276 $html = str_replace("</erp>","</pre>",$html);
32277 $html = str_replace("<aeratxet","<textarea",$html);
32278 $html = str_replace("</aeratxet>","</textarea>",$html);
32279 $html = str_replace("</innerpre","</pre",$html);
32280 $html = str_replace("<innerpre","<pre",$html);
32281
32282 $html = preg_replace('/<textarea([^>]*)><\/textarea>/si','<textarea\\1> </textarea>',$html);
32283 // mPDF 5.3.56
32284 $html = preg_replace('/(<table[^>]*>)\s*(<caption)(.*?<\/caption>)(.*?<\/table>)/si','\\2 position="top"\\3\\1\\4\\2 position="bottom"\\3',$html); // *TABLES*
32285 $html = preg_replace('/<(h[1-6])([^>]*)(>(?:(?!h[1-6]).)*?<\/\\1>\s*<table)/si','<\\1\\2 keep-with-table="1"\\3',$html); // *TABLES*
32286 $html = preg_replace("/\xbb\xa4\xac/", "\n", $html);
32287 return $html;
32288 }
32289
32290 /*-- LISTS --*/
32291 function dec2other($num, $cp) {
32292 $nstr = (string) $num;
32293 $rnum = '';
32294 for ($i=0;$i<strlen($nstr);$i++) {
32295 if ($this->_charDefined($this->CurrentFont['cw'],$cp+intval($nstr[$i]))) { // contains arabic-indic numbers
32296 $rnum .= code2utf($cp+intval($nstr[$i]));
32297 }
32298 else { $rnum .= $nstr[$i]; }
32299 }
32300 return $rnum;
32301 }
32302
32303 function dec2alpha($valor,$toupper="true"){
32304 // returns a string from A-Z to AA-ZZ to AAA-ZZZ
32305 // OBS: A = 65 ASCII TABLE VALUE
32306 if (($valor < 1) || ($valor > 18278)) return "?"; //supports 'only' up to 18278
32307 $c1 = $c2 = $c3 = '';
32308 if ($valor > 702) // 3 letters (up to 18278)
32309 {
32310 $c1 = 65 + floor(($valor-703)/676);
32311 $c2 = 65 + floor((($valor-703)%676)/26);
32312 $c3 = 65 + floor((($valor-703)%676)%26);
32313 }
32314 elseif ($valor > 26) // 2 letters (up to 702)
32315 {
32316 $c1 = (64 + (int)(($valor-1) / 26));
32317 $c2 = (64 + (int)($valor % 26));
32318 if ($c2 == 64) $c2 += 26;
32319 }
32320 else // 1 letter (up to 26)
32321 {
32322 $c1 = (64 + $valor);
32323 }
32324 $alpha = chr($c1);
32325 if ($c2 != '') $alpha .= chr($c2);
32326 if ($c3 != '') $alpha .= chr($c3);
32327 if (!$toupper) $alpha = strtolower($alpha);
32328 return $alpha;
32329 }
32330
32331
32332 function dec2roman($valor,$toupper=true){
32333 //returns a string as a roman numeral
32334 $r1=$r2=$r3=$r4='';
32335 if (($valor >= 5000) || ($valor < 1)) return "?"; //supports 'only' up to 4999
32336 $aux = (int)($valor/1000);
32337 if ($aux!==0)
32338 {
32339 $valor %= 1000;
32340 while($aux!==0)
32341 {
32342 $r1 .= "M";
32343 $aux--;
32344 }
32345 }
32346 $aux = (int)($valor/100);
32347 if ($aux!==0)
32348 {
32349 $valor %= 100;
32350 switch($aux){
32351 case 3: $r2="C";
32352 case 2: $r2.="C";
32353 case 1: $r2.="C"; break;
32354 case 9: $r2="CM"; break;
32355 case 8: $r2="C";
32356 case 7: $r2.="C";
32357 case 6: $r2.="C";
32358 case 5: $r2="D".$r2; break;
32359 case 4: $r2="CD"; break;
32360 default: break;
32361 }
32362 }
32363 $aux = (int)($valor/10);
32364 if ($aux!==0)
32365 {
32366 $valor %= 10;
32367 switch($aux){
32368 case 3: $r3="X";
32369 case 2: $r3.="X";
32370 case 1: $r3.="X"; break;
32371 case 9: $r3="XC"; break;
32372 case 8: $r3="X";
32373 case 7: $r3.="X";
32374 case 6: $r3.="X";
32375 case 5: $r3="L".$r3; break;
32376 case 4: $r3="XL"; break;
32377 default: break;
32378 }
32379 }
32380 switch($valor){
32381 case 3: $r4="I";
32382 case 2: $r4.="I";
32383 case 1: $r4.="I"; break;
32384 case 9: $r4="IX"; break;
32385 case 8: $r4="I";
32386 case 7: $r4.="I";
32387 case 6: $r4.="I";
32388 case 5: $r4="V".$r4; break;
32389 case 4: $r4="IV"; break;
32390 default: break;
32391 }
32392 $roman = $r1.$r2.$r3.$r4;
32393 if (!$toupper) $roman = strtolower($roman);
32394 return $roman;
32395 }
32396 /*-- END LISTS --*/
32397
32398
32399 //===========================
32400 /*-- IMPORTS --*/
32401 function SetImportUse() {
32402 $this->enableImports = true;
32403 ini_set('auto_detect_line_endings',1);
32404 require_once(_MPDF_PATH."mpdfi/pdf_context.php");
32405 require_once(_MPDF_PATH."mpdfi/pdf_parser.php");
32406 require_once(_MPDF_PATH."mpdfi/fpdi_pdf_parser.php");
32407 }
32408
32409 // from mPDFI
32410 function hex2str($hex) {
32411 return pack("H*", str_replace(array("\r","\n"," "),"", $hex));
32412 }
32413
32414 function str2hex($str) {
32415 return current(unpack("H*",$str));
32416 }
32417
32418
32419 function pdf_write_value(&$value) {
32420 switch ($value[0]) {
32421 case PDF_TYPE_NUMERIC :
32422 case PDF_TYPE_TOKEN :
32423 // A numeric value or a token.
32424 // Simply output them
32425 $this->_out($value[1]." ", false);
32426 break;
32427
32428 case PDF_TYPE_ARRAY :
32429 // An array. Output the proper
32430 // structure and move on.
32431 $this->_out("[",false);
32432 for ($i = 0; $i < count($value[1]); $i++) {
32433 $this->pdf_write_value($value[1][$i]);
32434 }
32435 $this->_out("]");
32436 break;
32437
32438 case PDF_TYPE_DICTIONARY :
32439 // A dictionary.
32440 $this->_out("<<",false);
32441 reset ($value[1]);
32442 while (list($k, $v) = each($value[1])) {
32443 $this->_out($k . " ",false);
32444 $this->pdf_write_value($v);
32445 }
32446 $this->_out(">>");
32447 break;
32448
32449 case PDF_TYPE_OBJREF :
32450 // An indirect object reference
32451 // Fill the object stack if needed
32452 $cpfn =& $this->current_parser->filename;
32453 if (!isset($this->_don_obj_stack[$cpfn][$value[1]])) {
32454 $this->_newobj(false,true);
32455 $this->_obj_stack[$cpfn][$value[1]] = array($this->n, $value);
32456 $this->_don_obj_stack[$cpfn][$value[1]] = array($this->n, $value);
32457 }
32458 $objid = $this->_don_obj_stack[$cpfn][$value[1]][0];
32459 $this->_out("{$objid} 0 R"); //{$value[2]}
32460 break;
32461
32462 case PDF_TYPE_STRING :
32463 if ($this->encrypted) {
32464 $value[1] = $this->_RC4($this->_objectkey($this->_current_obj_id), $value[1]);
32465 $value[1] = $this->_escape($value[1]);
32466 }
32467 // A string.
32468 $this->_out('('.$value[1].')');
32469 break;
32470
32471 case PDF_TYPE_STREAM :
32472 // A stream. First, output the
32473 // stream dictionary, then the
32474 // stream data itself.
32475 $this->pdf_write_value($value[1]);
32476 if ($this->encrypted) {
32477 $value[2][1] = $this->_RC4($this->_objectkey($this->_current_obj_id), $value[2][1]);
32478 }
32479 $this->_out("stream");
32480 $this->_out($value[2][1]);
32481 $this->_out("endstream");
32482 break;
32483
32484 case PDF_TYPE_HEX :
32485 if ($this->encrypted) {
32486 $value[1] = $this->hex2str($value[1]);
32487 $value[1] = $this->_RC4($this->_objectkey($this->_current_obj_id), $value[1]);
32488 // remake hexstring of encrypted string
32489 $value[1] = $this->str2hex($value[1]);
32490 }
32491 $this->_out("<".$value[1].">");
32492 break;
32493
32494 case PDF_TYPE_NULL :
32495 // The null object.
32496 $this->_out("null");
32497 break;
32498 }
32499 }
32500
32501 // ========== OVERWRITE SEARCH STRING IN A PDF FILE ================
32502 function OverWrite($file_in, $search, $replacement, $dest="D", $file_out="mpdf" ) {
32503 $pdf = file_get_contents($file_in);
32504
32505 if (!is_array($search)) {
32506 $x = $search;
32507 $search = array($x);
32508 }
32509 if (!is_array($replacement)) {
32510 $x = $replacement;
32511 $search = array($x);
32512 }
32513
32514 if (!$this->onlyCoreFonts && !$this->usingCoreFont) {
32515 foreach($search AS $k=>$val) {
32516 $search[$k] = $this->UTF8ToUTF16BE($search[$k] , false);
32517 $search[$k] = $this->_escape($search[$k]);
32518 $replacement[$k] = $this->UTF8ToUTF16BE($replacement[$k], false);
32519 $replacement[$k] = $this->_escape($replacement[$k]);
32520 }
32521 }
32522 else {
32523 foreach($replacement AS $k=>$val) {
32524 $replacement[$k] = mb_convert_encoding($replacement[$k],$this->mb_enc,'utf-8');
32525 $replacement[$k] = $this->_escape($replacement[$k]);
32526 }
32527 }
32528
32529 // Get xref into array
32530 $xref = array();
32531 preg_match("/xref\n0 (\d+)\n(.*?)\ntrailer/s",$pdf,$m);
32532 $xref_objid = $m[1];
32533 preg_match_all('/(\d{10}) (\d{5}) (f|n)/',$m[2],$x);
32534 for($i=0; $i<count($x[0]); $i++) {
32535 $xref[] = array(intval($x[1][$i]), $x[2][$i], $x[3][$i]);
32536 }
32537
32538 $changes = array();
32539 preg_match("/<<\s*\/Type\s*\/Pages\s*\/Kids\s*\[(.*?)\]\s*\/Count/s",$pdf,$m);
32540 preg_match_all("/(\d+) 0 R /s",$m[1],$o);
32541 $objlist = $o[1];
32542 foreach($objlist AS $obj) {
32543 if ($this->compress) {
32544 preg_match("/".($obj+1)." 0 obj\n<<\s*\/Filter\s*\/FlateDecode\s*\/Length (\d+)>>\nstream\n(.*?)\nendstream\n/s",$pdf,$m);
32545 }
32546 else {
32547 preg_match("/".($obj+1)." 0 obj\n<<\s*\/Length (\d+)>>\nstream\n(.*?)\nendstream\n/s",$pdf,$m);
32548 }
32549 $s = $m[2];
32550 if (!$s) { continue; }
32551 $oldlen = $m[1];
32552 if ($this->encrypted) {
32553 $s = $this->_RC4($this->_objectkey($obj+1), $s);
32554 }
32555 if ($this->compress) {
32556 $s = gzuncompress($s);
32557 }
32558 foreach($search AS $k=>$val) {
32559 $s = str_replace($search[$k],$replacement[$k],$s);
32560 }
32561 if ($this->compress) {
32562 $s = gzcompress($s);
32563 }
32564 if ($this->encrypted) {
32565 $s = $this->_RC4($this->_objectkey($obj+1), $s);
32566 }
32567 $newlen = strlen($s);
32568 $changes[($xref[$obj+1][0])] = ($newlen - $oldlen) + (strlen($newlen) - strlen($oldlen ));
32569 if ($this->compress) {
32570 $newstr = ($obj+1) . " 0 obj\n<</Filter /FlateDecode /Length ".$newlen.">>\nstream\n".$s."\nendstream\n";
32571 }
32572 else {
32573 $newstr = ($obj+1) . " 0 obj\n<</Length ".$newlen.">>\nstream\n".$s."\nendstream\n";
32574 }
32575 $pdf = str_replace($m[0],$newstr,$pdf);
32576 }
32577
32578 // Update xref in PDF
32579 krsort($changes);
32580 $newxref = "xref\n0 ".$xref_objid."\n";
32581 foreach($xref AS $v) {
32582 foreach($changes AS $ck => $cv) {
32583 if ($v[0] > $ck) { $v[0] += $cv; }
32584 }
32585 $newxref .= sprintf('%010d',$v[0]) . ' ' . $v[1] . ' ' .$v[2] . " \n";
32586 }
32587 $newxref .= "trailer";
32588 $pdf = preg_replace("/xref\n0 \d+\n.*?\ntrailer/s",$newxref,$pdf);
32589
32590 // Update startxref in PDF
32591 preg_match("/startxref\n(\d+)\n%%EOF/s", $pdf, $m);
32592 $startxref = $m[1];
32593 $startxref += array_sum($changes);
32594 $pdf = preg_replace("/startxref\n(\d+)\n%%EOF/s","startxref\n".$startxref."\n%%EOF",$pdf);
32595
32596 // OUTPUT
32597 switch($dest) {
32598 case 'I':
32599 //Send to standard output
32600 if(isset($_SERVER['SERVER_NAME']))
32601 {
32602 //We send to a browser
32603 Header('Content-Type: application/pdf');
32604 Header('Content-Length: '.strlen($pdf));
32605 Header('Content-disposition: inline; filename='.$file_out);
32606 }
32607 echo $pdf;
32608 break;
32609 case 'F':
32610 //Save to local file
32611 if (!$file_out) { $file_out = 'mpdf.pdf'; }
32612 $f=fopen($file_out,'wb');
32613 if(!$f) die('Unable to create output file: '.$file_out);
32614 fwrite($f,$pdf,strlen($pdf));
32615 fclose($f);
32616 break;
32617 case 'S':
32618 //Return as a string
32619 return $pdf;
32620 case 'D':
32621 default:
32622 //Download file
32623 if(isset($_SERVER['HTTP_USER_AGENT']) and strpos($_SERVER['HTTP_USER_AGENT'],'MSIE'))
32624 Header('Content-Type: application/force-download');
32625 else
32626 Header('Content-Type: application/octet-stream');
32627 Header('Content-Length: '.strlen($pdf));
32628 Header('Content-disposition: attachment; filename='.$file_out);
32629 echo $pdf;
32630 break;
32631 }
32632 }
32633
32634
32635 function GetTemplateSize($tplidx, $_w=0, $_h=0) {
32636 if (!$this->tpls[$tplidx])
32637 return false;
32638 $w = $this->tpls[$tplidx]['box']['w'];
32639 $h = $this->tpls[$tplidx]['box']['h'];
32640 if ($_w == 0 and $_h == 0) {
32641 $_w = $w;
32642 $_h = $h;
32643 }
32644 if($_w==0)
32645 $_w=$_h*$w/$h;
32646 if($_h==0)
32647 $_h=$_w*$h/$w;
32648 return array("w" => $_w, "h" => $_h);
32649 }
32650
32651 // Thumbnails
32652 function Thumbnail($file, $npr=3, $spacing=10) { //$npr = number per row
32653 $w = (($this->pgwidth + $spacing)/$npr) - $spacing;
32654 $oldlinewidth = $this->LineWidth;
32655 $this->SetLineWidth(0.02);
32656 $this->SetDColor($this->ConvertColor(0));
32657 $h = 0;
32658 $maxh = 0;
32659 $x = $_x = $this->lMargin;
32660 $_y = $this->tMargin;
32661 if ($this->y==0) { $y = $_y; } else { $y = $this->y; }
32662 $pagecount = $this->SetSourceFile($file);
32663 for ($n = 1; $n <= $pagecount; $n++) {
32664 $tplidx = $this->ImportPage($n);
32665 $size = $this->useTemplate($tplidx, $x, $y, $w);
32666 $this->Rect($x, $y, $size['w'], $size['h']);
32667 $h = max($h, $size['h']);
32668 $maxh = max($h, $maxh);
32669 if ($n % $npr == 0) {
32670 if (($y + $h + $spacing + $maxh)>$this->PageBreakTrigger && $n != $pagecount) {
32671 $this->AddPage();
32672 $x = $_x;
32673 $y = $_y;
32674 }
32675 else {
32676 $y += $h+$spacing ;
32677 $x = $_x;
32678 $h = 0;
32679 }
32680 }
32681 else {
32682 $x += $w+$spacing ;
32683 }
32684 }
32685 $this->SetLineWidth($oldlinewidth);
32686 }
32687
32688 function SetSourceFile($filename) {
32689 $this->current_filename = $filename;
32690 $fn =& $this->current_filename;
32691 if (!isset($this->parsers[$fn]))
32692 // $this->parsers[$fn] =& new fpdi_pdf_parser($fn,$this);
32693 $this->parsers[$fn] = new fpdi_pdf_parser($fn,$this);
32694 if (!$this->parsers[$fn]->success) {
32695 $this->Error($this->parsers[$fn]->errormsg); // Delete this line to return false on fail
32696 return false;
32697 }
32698 $this->current_parser =& $this->parsers[$fn];
32699 return $this->parsers[$fn]->getPageCount();
32700 }
32701 function ImportPage($pageno=1, $crop_x=null, $crop_y=null, $crop_w=0, $crop_h=0, $boxName='/CropBox') {
32702 $fn =& $this->current_filename;
32703 $parser =& $this->parsers[$fn];
32704 $parser->setPageno($pageno);
32705
32706 $this->tpl++;
32707 $this->tpls[$this->tpl] = array();
32708 $tpl =& $this->tpls[$this->tpl];
32709 $tpl['parser'] =& $parser;
32710 $tpl['resources'] = $parser->getPageResources();
32711 $tpl['buffer'] = $parser->getContent();
32712 if (!in_array($boxName, $parser->availableBoxes))
32713 return $this->Error(sprintf("Unknown box: %s", $boxName));
32714 $pageboxes = $parser->getPageBoxes($pageno);
32715 /**
32716 * MediaBox
32717 * CropBox: Default -> MediaBox
32718 * BleedBox: Default -> CropBox
32719 * TrimBox: Default -> CropBox
32720 * ArtBox: Default -> CropBox
32721 */
32722 if (!isset($pageboxes[$boxName]) && ($boxName == "/BleedBox" || $boxName == "/TrimBox" || $boxName == "/ArtBox"))
32723 $boxName = "/CropBox";
32724 if (!isset($pageboxes[$boxName]) && $boxName == "/CropBox")
32725 $boxName = "/MediaBox";
32726 if (!isset($pageboxes[$boxName]))
32727 return false;
32728 $box = $pageboxes[$boxName];
32729
32730 $tpl['box'] = $box;
32731 // To build an array that can be used by useTemplate()
32732 $this->tpls[$this->tpl] = array_merge($this->tpls[$this->tpl],$box);
32733 // An imported page will start at 0,0 everytime. Translation will be set in _putformxobjects()
32734 $tpl['x'] = 0;
32735 $tpl['y'] = 0;
32736 $tpl['w'] = $tpl['box']['w'] ;
32737 $tpl['h'] = $tpl['box']['h'] ;
32738 if ($crop_w) { $tpl['box']['w'] = $crop_w; }
32739 if ($crop_h) { $tpl['box']['h'] = $crop_h; }
32740 if (isset($crop_x)) { $tpl['box']['x'] = $crop_x; }
32741 if (isset($crop_y)) {$tpl['box']['y'] = $tpl['h'] - $crop_y - $crop_h ; }
32742
32743 $page =& $parser->pages[$parser->pageno];
32744 // fix for rotated pages
32745 $rotation = $parser->getPageRotation($pageno);
32746
32747 if (isset($rotation[1]) && ($angle = $rotation[1] % 360) != 0 && $tpl['box']['w'] == $tpl['w']) {
32748 $steps = $angle / 90;
32749
32750 $_w = $tpl['w'];
32751 $_h = $tpl['h'];
32752 $tpl['w'] = $steps % 2 == 0 ? $_w : $_h;
32753 $tpl['h'] = $steps % 2 == 0 ? $_h : $_w;
32754 if ($steps % 2 != 0) {
32755 $x = $y = ($steps == 1 || $steps == -3) ? $tpl['h'] : $tpl['w'];
32756 } else {
32757 $x = $tpl['w'];
32758 $y = $tpl['h'];
32759 }
32760 $cx=($x/2+$tpl['box']['x'])*_MPDFK;
32761 $cy=($y/2+$tpl['box']['y'])*_MPDFK;
32762 $angle*=-1;
32763 $angle*=M_PI/180;
32764 $c=cos($angle);
32765 $s=sin($angle);
32766 $tpl['box']['w'] = $tpl['w'] ;
32767 $tpl['box']['h'] = $tpl['h'] ;
32768 $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']);
32769 }
32770 return $this->tpl;
32771 }
32772 function UseTemplate($tplidx, $_x=null, $_y=null, $_w=0, $_h=0) {
32773 if (!isset($this->tpls[$tplidx]))
32774 $this->Error("Template does not exist!");
32775 if($this->state==0) { $this->AddPage(); }
32776 $out = 'q 0 J 1 w 0 j 0 G'."\n"; // reset standard values
32777 $x = $this->tpls[$tplidx]['x'];
32778 $y = $this->tpls[$tplidx]['y'];
32779 $w = $this->tpls[$tplidx]['w'];
32780 $h = $this->tpls[$tplidx]['h'];
32781 if ($_x == null) { $_x = $x; }
32782 if ($_y == null) { $_y = $y; }
32783 if ($_x === -1) { $_x = $this->x; }
32784 if ($_y === -1) { $_y = $this->y; }
32785
32786 $wh = $this->getTemplateSize($tplidx,$_w,$_h);
32787 $_w = $wh['w'];
32788 $_h = $wh['h'];
32789 $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";
32790 $out .= $this->tplprefix.$tplidx." Do Q\n";
32791
32792 $s = array("w" => $_w, "h" => $_h);
32793 $out .= "Q\n";
32794 $this->pages[$this->page] = $out . $this->pages[$this->page];
32795 return $s;
32796 }
32797 function SetPageTemplate($tplidx='') {
32798 if (!isset($this->tpls[$tplidx])) {
32799 $this->pageTemplate = '';
32800 return false;
32801 }
32802 $this->pageTemplate = $tplidx;
32803 }
32804 function SetDocTemplate($file='', $continue=0) {
32805 $this->docTemplate = $file;
32806 $this->docTemplateContinue = $continue;
32807 }
32808 /*-- END IMPORTS --*/
32809
32810
32811 /* ---------------------------------------------- */
32812 /* ---------------------------------------------- */
32813 /* ---------------------------------------------- */
32814 /* ---------------------------------------------- */
32815 /* ---------------------------------------------- */
32816
32817 // JAVASCRIPT
32818 function _set_object_javascript ($string) {
32819 $this->_newobj();
32820 $this->_out('<<');
32821 $this->_out('/S /JavaScript ');
32822 $this->_out('/JS '.$this->_textstring($string));
32823 $this->_out('>>');
32824 $this->_out('endobj');
32825 }
32826
32827 function SetJS($script) {
32828 $this->js = $script;
32829 }
32830
32831
32832
32833
32834 }//end of Class
32835
32836
32837
32838
32839 ?>