]> git.immae.eu Git - github/wallabag/wallabag.git/blob - inc/3rdparty/libraries/mpdf/mpdf.php
add pdf and mobi libraries
[github/wallabag/wallabag.git] / inc / 3rdparty / libraries / mpdf / mpdf.php
1 <?php
2
3 // ******************************************************************************
4 // Software: mPDF, Unicode-HTML Free PDF generator *
5 // Version: 5.7 based on *
6 // FPDF by Olivier PLATHEY *
7 // HTML2FPDF by Renato Coelho *
8 // Date: 2013-07-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.7');
17
18 //Scale factor
19 define('_MPDFK', (72/25.4));
20
21 /*-- HTML-CSS --*/
22 define('AUTOFONT_CJK',1);
23 define('AUTOFONT_THAIVIET',2);
24 define('AUTOFONT_RTL',4);
25 define('AUTOFONT_INDIC',8);
26 define('AUTOFONT_ALL',15);
27
28 define('_BORDER_ALL',15);
29 define('_BORDER_TOP',8);
30 define('_BORDER_RIGHT',4);
31 define('_BORDER_BOTTOM',2);
32 define('_BORDER_LEFT',1);
33 /*-- END HTML-CSS --*/
34
35 if (!defined('_MPDF_PATH')) define('_MPDF_PATH', dirname(preg_replace('/\\\\/','/',__FILE__)) . '/');
36 if (!defined('_MPDF_URI')) define('_MPDF_URI',_MPDF_PATH);
37
38 require_once(_MPDF_PATH.'includes/functions.php');
39 require_once(_MPDF_PATH.'config_cp.php');
40
41 if (!defined('_JPGRAPH_PATH')) define("_JPGRAPH_PATH", _MPDF_PATH.'jpgraph/');
42
43 if (!defined('_MPDF_TEMP_PATH')) define("_MPDF_TEMP_PATH", _MPDF_PATH.'tmp/');
44
45 if (!defined('_MPDF_TTFONTPATH')) { define('_MPDF_TTFONTPATH',_MPDF_PATH.'ttfonts/'); }
46 if (!defined('_MPDF_TTFONTDATAPATH')) { define('_MPDF_TTFONTDATAPATH',_MPDF_PATH.'ttfontdata/'); }
47
48 $errorlevel=error_reporting();
49 $errorlevel=error_reporting($errorlevel & ~E_NOTICE);
50
51 //error_reporting(E_ALL);
52
53 if(function_exists("date_default_timezone_set")) {
54 if (ini_get("date.timezone")=="") { date_default_timezone_set("Europe/London"); }
55 }
56 if (!function_exists("mb_strlen")) { die("Error - mPDF requires mb_string functions. Ensure that PHP is compiled with php_mbstring.dll enabled."); }
57
58 if (!defined('PHP_VERSION_ID')) {
59 $version = explode('.', PHP_VERSION);
60 define('PHP_VERSION_ID', ($version[0] * 10000 + $version[1] * 100 + $version[2]));
61 }
62 // Machine dependent number of bytes used to pack "double" into binary (used in cacheTables)
63 $test = pack("d", 134455.474557333333666);
64 define("_DSIZE", strlen($test));
65
66 class mPDF
67 {
68
69 ///////////////////////////////
70 // EXTERNAL (PUBLIC) VARIABLES
71 // Define these in config.php
72 ///////////////////////////////
73 var $CJKforceend; // mPDF 5.6.40
74 // mPDF 5.6.34
75 var $h2bookmarks;
76 var $h2toc;
77 var $decimal_align; // mPDF 5.6.13
78 var $margBuffer; // mPDF 5.4.04
79 var $splitTableBorderWidth; // mPDF 5.4.16
80
81 var $cacheTables;
82 var $bookmarkStyles;
83 var $useActiveForms;
84
85 var $repackageTTF;
86 var $allowCJKorphans;
87 var $allowCJKoverflow;
88
89 var $useKerning;
90 var $restrictColorSpace;
91 var $bleedMargin;
92 var $crossMarkMargin;
93 var $cropMarkMargin;
94 var $cropMarkLength;
95 var $nonPrintMargin;
96
97 var $PDFX;
98 var $PDFXauto;
99
100 var $PDFA;
101 var $PDFAauto;
102 var $ICCProfile;
103
104 var $printers_info;
105 var $iterationCounter;
106 var $smCapsScale;
107 var $smCapsStretch;
108
109 var $backupSubsFont;
110 var $backupSIPFont;
111 var $debugfonts;
112 var $useAdobeCJK;
113 var $percentSubset;
114 var $maxTTFFilesize;
115 var $BMPonly;
116
117 var $tableMinSizePriority;
118
119 var $dpi;
120 var $watermarkImgAlphaBlend;
121 var $watermarkImgBehind;
122 var $justifyB4br;
123 var $packTableData;
124 var $pgsIns;
125 var $simpleTables;
126 var $enableImports;
127
128 var $debug;
129 var $showStats;
130 var $setAutoTopMargin;
131 var $setAutoBottomMargin;
132 var $autoMarginPadding;
133 var $collapseBlockMargins;
134 var $falseBoldWeight;
135 var $normalLineheight;
136 var $progressBar;
137 var $incrementFPR1;
138 var $incrementFPR2;
139 var $incrementFPR3;
140 var $incrementFPR4;
141
142 var $SHYlang;
143 var $SHYleftmin;
144 var $SHYrightmin;
145 var $SHYcharmin;
146 var $SHYcharmax;
147 var $SHYlanguages;
148 // PageNumber Conditional Text
149 var $pagenumPrefix;
150 var $pagenumSuffix;
151 var $nbpgPrefix;
152 var $nbpgSuffix;
153 var $showImageErrors;
154 var $allow_output_buffering;
155 var $autoPadding;
156 var $useGraphs;
157 var $autoFontGroupSize;
158 var $tabSpaces;
159 var $useLang;
160 var $restoreBlockPagebreaks;
161 var $watermarkTextAlpha;
162 var $watermarkImageAlpha;
163 var $watermark_size;
164 var $watermark_pos;
165 var $annotSize;
166 var $annotMargin;
167 var $annotOpacity;
168 var $title2annots;
169 var $keepColumns;
170 var $keep_table_proportions;
171 var $ignore_table_widths;
172 var $ignore_table_percents;
173 var $list_align_style;
174 var $list_number_suffix;
175 var $useSubstitutions;
176 var $CSSselectMedia;
177
178 var $forcePortraitHeaders;
179 var $forcePortraitMargins;
180 var $displayDefaultOrientation;
181 var $ignore_invalid_utf8;
182 var $allowedCSStags;
183 var $onlyCoreFonts;
184 var $allow_charset_conversion;
185
186 var $jSWord;
187 var $jSmaxChar;
188 var $jSmaxCharLast;
189 var $jSmaxWordLast;
190
191 var $max_colH_correction;
192
193
194 var $table_error_report;
195 var $table_error_report_param;
196 var $biDirectional;
197 var $text_input_as_HTML;
198 var $anchor2Bookmark;
199 var $list_indent_first_level;
200 var $shrink_tables_to_fit;
201
202 var $allow_html_optional_endtags;
203
204 var $img_dpi;
205
206 var $defaultheaderfontsize;
207 var $defaultheaderfontstyle;
208 var $defaultheaderline;
209 var $defaultfooterfontsize;
210 var $defaultfooterfontstyle;
211 var $defaultfooterline;
212 var $header_line_spacing;
213 var $footer_line_spacing;
214
215 var $pregUHCchars;
216 var $pregSJISchars;
217 var $pregCJKchars;
218 var $pregASCIIchars1;
219 var $pregASCIIchars2;
220 var $pregASCIIchars3;
221 var $pregVIETchars;
222 var $pregVIETPluschars;
223
224 var $pregRTLchars;
225 var $pregHEBchars;
226 var $pregARABICchars;
227 var $pregNonARABICchars;
228 // INDIC
229 var $pregHIchars;
230 var $pregBNchars;
231 var $pregPAchars;
232 var $pregGUchars;
233 var $pregORchars;
234 var $pregTAchars;
235 var $pregTEchars;
236 var $pregKNchars;
237 var $pregMLchars;
238 var $pregSHchars;
239 var $pregINDextra;
240
241 var $mirrorMargins;
242 var $default_lineheight_correction;
243 var $watermarkText;
244 var $watermarkImage;
245 var $showWatermarkText;
246 var $showWatermarkImage;
247
248 var $fontsizes;
249
250 // Aliases for backward compatability
251 var $UnvalidatedText; // alias = $watermarkText
252 var $TopicIsUnvalidated; // alias = $showWatermarkText
253 var $useOddEven; // alias = $mirrorMargins
254 var $useSubstitutionsMB; // alias = $useSubstitutions
255
256
257
258 //////////////////////
259 // CLASS OBJECTS
260 //////////////////////
261 var $cssmgr;
262 var $grad;
263 var $bmp;
264 var $wmf;
265 var $tocontents;
266 var $form;
267 var $directw;
268
269 //////////////////////
270 // INTERNAL VARIABLES
271 //////////////////////
272 var $writingToC; // mPDF 5.6.38
273 // mPDF 5.6.01
274 var $layers;
275 var $current_layer;
276 var $open_layer_pane;
277 var $decimal_offset; // mPDF 5.6.13
278 var $inMeter; // mPDF 5.5.09
279
280 var $CJKleading;
281 var $CJKfollowing;
282 var $CJKoverflow;
283
284 var $textshadow;
285
286 var $colsums;
287 var $spanborder;
288 var $spanborddet;
289
290 var $visibility;
291
292 var $useRC128encryption;
293 var $uniqid;
294
295 var $kerning;
296 var $fixedlSpacing;
297 var $minwSpacing;
298 var $lSpacingCSS;
299 var $wSpacingCSS;
300
301 var $listDir;
302 var $spotColorIDs;
303 var $SVGcolors;
304 var $spotColors;
305 var $defTextColor;
306 var $defDrawColor;
307 var $defFillColor;
308
309 var $tableBackgrounds;
310 var $inlineDisplayOff;
311 var $kt_y00;
312 var $kt_p00;
313 var $upperCase;
314 var $checkSIP;
315 var $checkSMP;
316 var $checkCJK;
317 var $tableCJK;
318
319 var $watermarkImgAlpha;
320 var $PDFAXwarnings;
321 var $MetadataRoot;
322 var $OutputIntentRoot;
323 var $InfoRoot;
324 var $current_filename;
325 var $parsers;
326 var $current_parser;
327 var $_obj_stack;
328 var $_don_obj_stack;
329 var $_current_obj_id;
330 var $tpls;
331 var $tpl;
332 var $tplprefix;
333 var $_res;
334
335 var $pdf_version;
336 var $noImageFile;
337 var $lastblockbottommargin;
338 var $baselineC;
339 var $subPos;
340 var $subArrMB;
341 var $ReqFontStyle;
342 var $tableClipPath ;
343 var $forceExactLineheight;
344 var $listOcc;
345
346 var $fullImageHeight;
347 var $inFixedPosBlock; // Internal flag for position:fixed block
348 var $fixedPosBlock; // Buffer string for position:fixed block
349 var $fixedPosBlockDepth;
350 var $fixedPosBlockBBox;
351 var $fixedPosBlockSave;
352 var $maxPosL;
353 var $maxPosR;
354
355 var $loaded;
356
357 var $extraFontSubsets;
358 var $docTemplateStart; // Internal flag for page (page no. -1) that docTemplate starts on
359 var $time0;
360
361 // Classes
362 var $indic;
363 var $barcode;
364
365 var $SHYpatterns;
366 var $loadedSHYpatterns;
367 var $loadedSHYdictionary;
368 var $SHYdictionary;
369 var $SHYdictionaryWords;
370
371 var $spanbgcolorarray;
372 var $default_font;
373 var $list_lineheight;
374 var $headerbuffer;
375 var $lastblocklevelchange;
376 var $nestedtablejustfinished;
377 var $linebreakjustfinished;
378 var $cell_border_dominance_L;
379 var $cell_border_dominance_R;
380 var $cell_border_dominance_T;
381 var $cell_border_dominance_B;
382 var $table_keep_together;
383 var $plainCell_properties;
384 var $inherit_lineheight;
385 var $listitemtype;
386 var $shrin_k1;
387 var $outerfilled;
388
389 var $blockContext;
390 var $floatDivs;
391
392
393 var $patterns;
394 var $pageBackgrounds;
395
396 var $bodyBackgroundGradient;
397 var $bodyBackgroundImage;
398 var $bodyBackgroundColor;
399
400 var $writingHTMLheader; // internal flag - used both for writing HTMLHeaders/Footers and FixedPos block
401 var $writingHTMLfooter;
402 var $autoFontGroups;
403 var $angle;
404
405 var $gradients;
406
407 var $kwt_Reference;
408 var $kwt_BMoutlines;
409 var $kwt_toc;
410
411 var $tbrot_Reference;
412 var $tbrot_BMoutlines;
413 var $tbrot_toc;
414
415 var $col_Reference;
416 var $col_BMoutlines;
417 var $col_toc;
418
419 var $currentGraphId;
420 var $graphs;
421
422 var $floatbuffer;
423 var $floatmargins;
424
425 var $bullet;
426 var $bulletarray;
427
428 var $rtlAsArabicFarsi; // DEPRACATED
429
430 var $currentLang;
431 var $default_lang;
432 var $default_available_fonts;
433 var $pageTemplate;
434 var $docTemplate;
435 var $docTemplateContinue;
436
437 var $arabGlyphs;
438 var $arabHex;
439 var $persianGlyphs;
440 var $persianHex;
441 var $arabVowels;
442 var $arabPrevLink;
443 var $arabNextLink;
444
445
446 var $formobjects; // array of Form Objects for WMF
447 var $InlineProperties;
448 var $InlineAnnots;
449 var $ktAnnots;
450 var $tbrot_Annots;
451 var $kwt_Annots;
452 var $columnAnnots;
453 var $columnForms;
454
455 var $PageAnnots;
456
457 var $pageDim; // Keep track of page wxh for orientation changes - set in _beginpage, used in _putannots
458
459 var $breakpoints;
460
461 var $tableLevel;
462 var $tbctr;
463 var $innermostTableLevel;
464 var $saveTableCounter;
465 var $cellBorderBuffer;
466
467 var $saveHTMLFooter_height;
468 var $saveHTMLFooterE_height;
469
470 var $firstPageBoxHeader;
471 var $firstPageBoxHeaderEven;
472 var $firstPageBoxFooter;
473 var $firstPageBoxFooterEven;
474
475 var $page_box;
476 var $show_marks; // crop or cross marks
477
478 var $basepathIsLocal;
479
480 var $use_kwt;
481 var $kwt;
482 var $kwt_height;
483 var $kwt_y0;
484 var $kwt_x0;
485 var $kwt_buffer;
486 var $kwt_Links;
487 var $kwt_moved;
488 var $kwt_saved;
489
490 var $PageNumSubstitutions;
491
492 var $table_borders_separate;
493 var $base_table_properties;
494 var $borderstyles;
495
496 var $listjustfinished;
497 var $blockjustfinished;
498
499 var $orig_bMargin;
500 var $orig_tMargin;
501 var $orig_lMargin;
502 var $orig_rMargin;
503 var $orig_hMargin;
504 var $orig_fMargin;
505
506 var $pageheaders;
507 var $pagefooters;
508
509 var $pageHTMLheaders;
510 var $pageHTMLfooters;
511
512 var $saveHTMLHeader;
513 var $saveHTMLFooter;
514
515 var $HTMLheaderPageLinks;
516 var $HTMLheaderPageAnnots;
517 var $HTMLheaderPageForms;
518
519 // See config_fonts.php for these next 5 values
520 var $available_unifonts;
521 var $sans_fonts;
522 var $serif_fonts;
523 var $mono_fonts;
524 var $defaultSubsFont;
525
526 // List of ALL available CJK fonts (incl. styles) (Adobe add-ons) hw removed
527 var $available_CJK_fonts;
528
529 var $HTMLHeader;
530 var $HTMLFooter;
531 var $HTMLHeaderE;
532 var $HTMLFooterE;
533 var $bufferoutput;
534
535 var $showdefaultpagenos; // DEPRACATED -left for backward compatability
536
537
538 // CJK fonts
539 var $Big5_widths;
540 var $GB_widths;
541 var $SJIS_widths;
542 var $UHC_widths;
543
544 // SetProtection
545 var $encrypted; //whether document is protected
546 var $Uvalue; //U entry in pdf document
547 var $Ovalue; //O entry in pdf document
548 var $Pvalue; //P entry in pdf document
549 var $enc_obj_id; //encryption object id
550 var $last_rc4_key; //last RC4 key encrypted (cached for optimisation)
551 var $last_rc4_key_c; //last RC4 computed key
552 var $encryption_key;
553 var $padding; //used for encryption
554
555
556 // Bookmark
557 var $BMoutlines;
558 var $OutlineRoot;
559 // INDEX
560 var $ColActive;
561 var $Reference;
562 var $CurrCol;
563 var $NbCol;
564 var $y0; //Top ordinate of columns
565 var $ColL;
566 var $ColWidth;
567 var $ColGap;
568 // COLUMNS
569 var $ColR;
570 var $ChangeColumn;
571 var $columnbuffer;
572 var $ColDetails;
573 var $columnLinks;
574 var $colvAlign;
575 // Substitutions
576 var $substitute; // Array of substitution strings e.g. <ttz>112</ttz>
577 var $entsearch; // Array of HTML entities (>ASCII 127) to substitute
578 var $entsubstitute; // Array of substitution decimal unicode for the Hi entities
579
580
581 // Default values if no style sheet offered (cf. http://www.w3.org/TR/CSS21/sample.html)
582 var $defaultCSS;
583
584 var $linemaxfontsize;
585 var $lineheight_correction;
586 var $lastoptionaltag; // Save current block item which HTML specifies optionsl endtag
587 var $pageoutput;
588 var $charset_in;
589 var $blk;
590 var $blklvl;
591 var $ColumnAdjust;
592 var $ws; // Word spacing
593 var $HREF;
594 var $pgwidth;
595 var $fontlist;
596 var $oldx;
597 var $oldy;
598 var $B;
599 var $U; //underlining flag
600 var $S; // SmallCaps flag
601 var $I;
602
603 var $tdbegin;
604 var $table;
605 var $cell;
606 var $col;
607 var $row;
608
609 var $divbegin;
610 var $divalign;
611 var $divwidth;
612 var $divheight;
613 var $divrevert;
614 var $spanbgcolor;
615
616 var $spanlvl;
617 var $listlvl;
618 var $listnum;
619 var $listtype;
620 var $listoccur;
621 var $listlist;
622 var $listitem;
623
624 var $pjustfinished;
625 var $ignorefollowingspaces;
626 var $SUP;
627 var $SUB;
628 var $SMALL;
629 var $BIG;
630 var $toupper;
631 var $tolower;
632 var $capitalize;
633 var $dash_on;
634 var $dotted_on;
635 var $strike;
636
637 var $textbuffer;
638 var $currentfontstyle;
639 var $currentfontfamily;
640 var $currentfontsize;
641 var $colorarray;
642 var $bgcolorarray;
643 var $internallink;
644 var $enabledtags;
645
646 var $lineheight;
647 var $basepath;
648 var $textparam;
649
650 var $specialcontent;
651 var $selectoption;
652 var $objectbuffer;
653
654 // Table Rotation
655 var $table_rotate;
656 var $tbrot_maxw;
657 var $tbrot_maxh;
658 var $tablebuffer;
659 var $tbrot_align;
660 var $tbrot_Links;
661
662 var $divbuffer; // Buffer used when keeping DIV on one page
663 var $keep_block_together; // Keep a Block from page-break-inside: avoid
664 var $ktLinks; // Keep-together Block links array
665 var $ktBlock; // Keep-together Block array
666 var $ktForms;
667 var $ktReference;
668 var $ktBMoutlines;
669 var $_kttoc;
670
671 var $tbrot_y0;
672 var $tbrot_x0;
673 var $tbrot_w;
674 var $tbrot_h;
675
676 var $mb_enc;
677 var $directionality;
678
679 var $extgstates; // Used for alpha channel - Transparency (Watermark)
680 var $mgl;
681 var $mgt;
682 var $mgr;
683 var $mgb;
684
685 var $tts;
686 var $ttz;
687 var $tta;
688
689 var $headerDetails;
690 var $footerDetails;
691
692 // Best to alter the below variables using default stylesheet above
693 var $page_break_after_avoid;
694 var $margin_bottom_collapse;
695 var $list_indent;
696 var $list_align;
697 var $list_margin_bottom;
698 var $default_font_size; // in pts
699 var $original_default_font_size; // used to save default sizes when using table default
700 var $original_default_font;
701 var $watermark_font;
702 var $defaultAlign;
703
704 // TABLE
705 var $defaultTableAlign;
706 var $tablethead;
707 var $thead_font_weight;
708 var $thead_font_style;
709 var $thead_font_smCaps;
710 var $thead_valign_default;
711 var $thead_textalign_default;
712 var $tabletfoot;
713 var $tfoot_font_weight;
714 var $tfoot_font_style;
715 var $tfoot_font_smCaps;
716 var $tfoot_valign_default;
717 var $tfoot_textalign_default;
718
719 var $trow_text_rotate;
720
721 var $cellPaddingL;
722 var $cellPaddingR;
723 var $cellPaddingT;
724 var $cellPaddingB;
725 var $table_lineheight;
726 var $table_border_attr_set;
727 var $table_border_css_set;
728
729 var $shrin_k; // factor with which to shrink tables - used internally - do not change
730 var $shrink_this_table_to_fit; // 0 or false to disable; value (if set) gives maximum factor to reduce fontsize
731 var $MarginCorrection; // corrects for OddEven Margins
732 var $margin_footer;
733 var $margin_header;
734
735 var $tabletheadjustfinished;
736 var $usingCoreFont;
737 var $charspacing;
738
739 //Private properties FROM FPDF
740 var $DisplayPreferences;
741 var $flowingBlockAttr;
742 var $page; //current page number
743 var $n; //current object number
744 var $offsets; //array of object offsets
745 var $buffer; //buffer holding in-memory PDF
746 var $pages; //array containing pages
747 var $state; //current document state
748 var $compress; //compression flag
749 var $DefOrientation; //default orientation
750 var $CurOrientation; //current orientation
751 var $OrientationChanges; //array indicating orientation changes
752 var $k; //scale factor (number of points in user unit)
753 var $fwPt;
754 var $fhPt; //dimensions of page format in points
755 var $fw;
756 var $fh; //dimensions of page format in user unit
757 var $wPt;
758 var $hPt; //current dimensions of page in points
759 var $w;
760 var $h; //current dimensions of page in user unit
761 var $lMargin; //left margin
762 var $tMargin; //top margin
763 var $rMargin; //right margin
764 var $bMargin; //page break margin
765 var $cMarginL; //cell margin Left
766 var $cMarginR; //cell margin Right
767 var $cMarginT; //cell margin Left
768 var $cMarginB; //cell margin Right
769 var $DeflMargin; //Default left margin
770 var $DefrMargin; //Default right margin
771 var $x;
772 var $y; //current position in user unit for cell positioning
773 var $lasth; //height of last cell printed
774 var $LineWidth; //line width in user unit
775 var $CoreFonts; //array of standard font names
776 var $fonts; //array of used fonts
777 var $FontFiles; //array of font files
778 var $images; //array of used images
779 var $PageLinks; //array of links in pages
780 var $links; //array of internal links
781 var $FontFamily; //current font family
782 var $FontStyle; //current font style
783 var $CurrentFont; //current font info
784 var $FontSizePt; //current font size in points
785 var $FontSize; //current font size in user unit
786 var $DrawColor; //commands for drawing color
787 var $FillColor; //commands for filling color
788 var $TextColor; //commands for text color
789 var $ColorFlag; //indicates whether fill and text colors are different
790 var $autoPageBreak; //automatic page breaking
791 var $PageBreakTrigger; //threshold used to trigger page breaks
792 var $InFooter; //flag set when processing footer
793 var $InHTMLFooter;
794
795 var $processingFooter; //flag set when processing footer - added for columns
796 var $processingHeader; //flag set when processing header - added for columns
797 var $ZoomMode; //zoom display mode
798 var $LayoutMode; //layout display mode
799 var $title; //title
800 var $subject; //subject
801 var $author; //author
802 var $keywords; //keywords
803 var $creator; //creator
804
805 var $aliasNbPg; //alias for total number of pages
806 var $aliasNbPgGp; //alias for total number of pages in page group
807 var $aliasNbPgHex;
808 var $aliasNbPgGpHex;
809
810 var $ispre;
811
812 var $outerblocktags;
813 var $innerblocktags;
814
815
816 // **********************************
817 // **********************************
818 // **********************************
819 // **********************************
820 // **********************************
821 // **********************************
822 // **********************************
823 // **********************************
824 // **********************************
825
826 function mPDF($mode='',$format='A4',$default_font_size=0,$default_font='',$mgl=15,$mgr=15,$mgt=16,$mgb=16,$mgh=9,$mgf=9, $orientation='P') {
827
828 /*-- BACKGROUNDS --*/
829 if (!class_exists('grad', false)) { include(_MPDF_PATH.'classes/grad.php'); }
830 if (empty($this->grad)) { $this->grad = new grad($this); }
831 /*-- END BACKGROUNDS --*/
832 /*-- FORMS --*/
833 if (!class_exists('form', false)) { include(_MPDF_PATH.'classes/form.php'); }
834 if (empty($this->form)) { $this->form = new form($this); }
835 /*-- END FORMS --*/
836
837 $this->time0 = microtime(true);
838 //Some checks
839 $this->_dochecks();
840
841 // Set up Aliases for backwards compatability
842 $this->UnvalidatedText =& $this->watermarkText;
843 $this->TopicIsUnvalidated =& $this->showWatermarkText;
844 $this->AliasNbPg =& $this->aliasNbPg;
845 $this->AliasNbPgGp =& $this->aliasNbPgGp;
846 $this->BiDirectional =& $this->biDirectional;
847 $this->Anchor2Bookmark =& $this->anchor2Bookmark;
848 $this->KeepColumns =& $this->keepColumns;
849 $this->useOddEven =& $this->mirrorMargins;
850 $this->useSubstitutionsMB =& $this->useSubstitutions;
851
852 $this->writingToC = false; // mPDF 5.6.38
853 // mPDF 5.6.01
854 $this->layers = array();
855 $this->current_layer = 0;
856 $this->open_layer_pane = false;
857
858 $this->visibility='visible';
859
860 //Initialization of properties
861 $this->spotColors=array();
862 $this->spotColorIDs = array();
863 $this->tableBackgrounds = array();
864
865 $this->kt_y00 = '';
866 $this->kt_p00 = '';
867 $this->iterationCounter = false;
868 $this->BMPonly = array();
869 $this->page=0;
870 $this->n=2;
871 $this->buffer='';
872 $this->objectbuffer = array();
873 $this->pages=array();
874 $this->OrientationChanges=array();
875 $this->state=0;
876 $this->fonts=array();
877 $this->FontFiles=array();
878 $this->images=array();
879 $this->links=array();
880 $this->InFooter=false;
881 $this->processingFooter=false;
882 $this->processingHeader=false;
883 $this->lasth=0;
884 $this->FontFamily='';
885 $this->FontStyle='';
886 $this->FontSizePt=9;
887 $this->U=false;
888 // Small Caps
889 $this->upperCase = array();
890 $this->S = false;
891 $this->smCapsScale = 1;
892 $this->smCapsStretch = 100;
893 $this->margBuffer = 0; // mPDF 5.4.04
894 $this->inMeter = false; // mPDF 5.5.09
895 $this->decimal_offset = 0;
896
897 $this->defTextColor = $this->TextColor = $this->SetTColor($this->ConvertColor(0),true);
898 $this->defDrawColor = $this->DrawColor = $this->SetDColor($this->ConvertColor(0),true);
899 $this->defFillColor = $this->FillColor = $this->SetFColor($this->ConvertColor(255),true);
900
901 //SVG color names array
902 //http://www.w3schools.com/css/css_colornames.asp
903 $this->SVGcolors = array('antiquewhite'=>'#FAEBD7','aqua'=>'#00FFFF','aquamarine'=>'#7FFFD4','beige'=>'#F5F5DC','black'=>'#000000',
904 'blue'=>'#0000FF','brown'=>'#A52A2A','cadetblue'=>'#5F9EA0','chocolate'=>'#D2691E','cornflowerblue'=>'#6495ED','crimson'=>'#DC143C',
905 'darkblue'=>'#00008B','darkgoldenrod'=>'#B8860B','darkgreen'=>'#006400','darkmagenta'=>'#8B008B','darkorange'=>'#FF8C00',
906 'darkred'=>'#8B0000','darkseagreen'=>'#8FBC8F','darkslategray'=>'#2F4F4F','darkviolet'=>'#9400D3','deepskyblue'=>'#00BFFF',
907 'dodgerblue'=>'#1E90FF','firebrick'=>'#B22222','forestgreen'=>'#228B22','fuchsia'=>'#FF00FF','gainsboro'=>'#DCDCDC','gold'=>'#FFD700',
908 'gray'=>'#808080','green'=>'#008000','greenyellow'=>'#ADFF2F','hotpink'=>'#FF69B4','indigo'=>'#4B0082','khaki'=>'#F0E68C',
909 'lavenderblush'=>'#FFF0F5','lemonchiffon'=>'#FFFACD','lightcoral'=>'#F08080','lightgoldenrodyellow'=>'#FAFAD2','lightgreen'=>'#90EE90',
910 'lightsalmon'=>'#FFA07A','lightskyblue'=>'#87CEFA','lightslategray'=>'#778899','lightyellow'=>'#FFFFE0','lime'=>'#00FF00','limegreen'=>'#32CD32',
911 'magenta'=>'#FF00FF','maroon'=>'#800000','mediumaquamarine'=>'#66CDAA','mediumorchid'=>'#BA55D3','mediumseagreen'=>'#3CB371',
912 'mediumspringgreen'=>'#00FA9A','mediumvioletred'=>'#C71585','midnightblue'=>'#191970','mintcream'=>'#F5FFFA','moccasin'=>'#FFE4B5','navy'=>'#000080',
913 'olive'=>'#808000','orange'=>'#FFA500','orchid'=>'#DA70D6','palegreen'=>'#98FB98',
914 'palevioletred'=>'#D87093','peachpuff'=>'#FFDAB9','pink'=>'#FFC0CB','powderblue'=>'#B0E0E6','purple'=>'#800080',
915 'red'=>'#FF0000','royalblue'=>'#4169E1','salmon'=>'#FA8072','seagreen'=>'#2E8B57','sienna'=>'#A0522D','silver'=>'#C0C0C0','skyblue'=>'#87CEEB',
916 'slategray'=>'#708090','springgreen'=>'#00FF7F','steelblue'=>'#4682B4','tan'=>'#D2B48C','teal'=>'#008080','thistle'=>'#D8BFD8','turquoise'=>'#40E0D0',
917 'violetred'=>'#D02090','white'=>'#FFFFFF','yellow'=>'#FFFF00',
918 'aliceblue'=>'#f0f8ff', 'azure'=>'#f0ffff', 'bisque'=>'#ffe4c4', 'blanchedalmond'=>'#ffebcd', 'blueviolet'=>'#8a2be2', 'burlywood'=>'#deb887',
919 'chartreuse'=>'#7fff00', 'coral'=>'#ff7f50', 'cornsilk'=>'#fff8dc', 'cyan'=>'#00ffff', 'darkcyan'=>'#008b8b', 'darkgray'=>'#a9a9a9',
920 'darkgrey'=>'#a9a9a9', 'darkkhaki'=>'#bdb76b', 'darkolivegreen'=>'#556b2f', 'darkorchid'=>'#9932cc', 'darksalmon'=>'#e9967a',
921 'darkslateblue'=>'#483d8b', 'darkslategrey'=>'#2f4f4f', 'darkturquoise'=>'#00ced1', 'deeppink'=>'#ff1493', 'dimgray'=>'#696969',
922 'dimgrey'=>'#696969', 'floralwhite'=>'#fffaf0', 'ghostwhite'=>'#f8f8ff', 'goldenrod'=>'#daa520', 'grey'=>'#808080', 'honeydew'=>'#f0fff0',
923 'indianred'=>'#cd5c5c', 'ivory'=>'#fffff0', 'lavender'=>'#e6e6fa', 'lawngreen'=>'#7cfc00', 'lightblue'=>'#add8e6', 'lightcyan'=>'#e0ffff',
924 'lightgray'=>'#d3d3d3', 'lightgrey'=>'#d3d3d3', 'lightpink'=>'#ffb6c1', 'lightseagreen'=>'#20b2aa', 'lightslategrey'=>'#778899',
925 'lightsteelblue'=>'#b0c4de', 'linen'=>'#faf0e6', 'mediumblue'=>'#0000cd', 'mediumpurple'=>'#9370db', 'mediumslateblue'=>'#7b68ee',
926 'mediumturquoise'=>'#48d1cc', 'mistyrose'=>'#ffe4e1', 'navajowhite'=>'#ffdead', 'oldlace'=>'#fdf5e6', 'olivedrab'=>'#6b8e23', 'orangered'=>'#ff4500',
927 'palegoldenrod'=>'#eee8aa', 'paleturquoise'=>'#afeeee', 'papayawhip'=>'#ffefd5', 'peru'=>'#cd853f', 'plum'=>'#dda0dd', 'rosybrown'=>'#bc8f8f',
928 'saddlebrown'=>'#8b4513', 'sandybrown'=>'#f4a460', 'seashell'=>'#fff5ee', 'slateblue'=>'#6a5acd', 'slategrey'=>'#708090', 'snow'=>'#fffafa',
929 'tomato'=>'#ff6347', 'violet'=>'#ee82ee', 'wheat'=>'#f5deb3', 'whitesmoke'=>'#f5f5f5', 'yellowgreen'=>'#9acd32');
930
931 $this->ColorFlag=false;
932 $this->extgstates = array();
933
934 $this->mb_enc='windows-1252';
935 $this->directionality='ltr';
936 $this->defaultAlign = 'L';
937 $this->defaultTableAlign = 'L';
938
939 $this->fixedPosBlockSave = array();
940 $this->extraFontSubsets = 0;
941
942 $this->SHYpatterns = array();
943 $this->loadedSHYdictionary = false;
944 $this->SHYdictionary = array();
945 $this->SHYdictionaryWords = array();
946 $this->blockContext = 1;
947 $this->floatDivs = array();
948 $this->DisplayPreferences='';
949
950 $this->patterns = array(); // Tiling patterns used for backgrounds
951 $this->pageBackgrounds = array();
952 $this->writingHTMLheader = false; // internal flag - used both for writing HTMLHeaders/Footers and FixedPos block
953 $this->writingHTMLfooter = false; // internal flag - used both for writing HTMLHeaders/Footers and FixedPos block
954 $this->gradients = array();
955
956 $this->kwt_Reference = array();
957 $this->kwt_BMoutlines = array();
958 $this->kwt_toc = array();
959
960 $this->tbrot_Reference = array();
961 $this->tbrot_BMoutlines = array();
962 $this->tbrot_toc = array();
963
964 $this->col_Reference = array();
965 $this->col_BMoutlines = array();
966 $this->col_toc = array();
967 $this->graphs = array();
968
969 $this->pgsIns = array();
970 $this->PDFAXwarnings = array();
971 $this->inlineDisplayOff = false;
972 $this->kerning = false;
973 $this->lSpacingCSS = '';
974 $this->wSpacingCSS = '';
975 $this->fixedlSpacing = false;
976 $this->minwSpacing = 0;
977
978
979 $this->baselineC = 0.35; // Baseline for text
980 $this->noImageFile = str_replace("\\","/",dirname(__FILE__)) . '/includes/no_image.jpg';
981 $this->subPos = 0;
982 $this->forceExactLineheight = false;
983 $this->listOcc = 0;
984 $this->normalLineheight = 1.3;
985 // These are intended as configuration variables, and should be set in config.php - which will override these values;
986 // set here as failsafe as will cause an error if not defined
987 $this->incrementFPR1 = 10;
988 $this->incrementFPR2 = 10;
989 $this->incrementFPR3 = 10;
990 $this->incrementFPR4 = 10;
991
992 $this->fullImageHeight = false;
993 $this->floatbuffer = array();
994 $this->floatmargins = array();
995 $this->autoFontGroups = 0;
996 $this->formobjects=array(); // array of Form Objects for WMF
997 $this->InlineProperties=array();
998 $this->InlineAnnots=array();
999 $this->ktAnnots=array();
1000 $this->tbrot_Annots=array();
1001 $this->kwt_Annots=array();
1002 $this->columnAnnots=array();
1003 $this->pageDim=array();
1004 $this->breakpoints = array(); // used in columnbuffer
1005 $this->tableLevel=0;
1006 $this->tbctr=array(); // counter for nested tables at each level
1007 $this->page_box = array();
1008 $this->show_marks = ''; // crop or cross marks
1009 $this->kwt = false;
1010 $this->kwt_height = 0;
1011 $this->kwt_y0 = 0;
1012 $this->kwt_x0 = 0;
1013 $this->kwt_buffer = array();
1014 $this->kwt_Links = array();
1015 $this->kwt_moved = false;
1016 $this->kwt_saved = false;
1017 $this->PageNumSubstitutions = array();
1018 $this->base_table_properties=array();
1019 $this->borderstyles = array('inset','groove','outset','ridge','dotted','dashed','solid','double');
1020 $this->tbrot_align = 'C';
1021 $this->pageheaders=array();
1022 $this->pagefooters=array();
1023
1024 $this->pageHTMLheaders=array();
1025 $this->pageHTMLfooters=array();
1026 $this->HTMLheaderPageLinks = array();
1027 $this->HTMLheaderPageAnnots = array();
1028
1029 $this->ktForms = array();
1030 $this->HTMLheaderPageForms = array();
1031 $this->columnForms = array();
1032 $this->tbrotForms = array();
1033 $this->useRC128encryption = false;
1034 $this->uniqid = '';
1035
1036 $this->bufferoutput = false;
1037 $this->encrypted=false; //whether document is protected
1038 $this->BMoutlines=array();
1039 $this->ColActive=0; //Flag indicating that columns are on (the index is being processed)
1040 $this->Reference=array(); //Array containing the references
1041 $this->CurrCol=0; //Current column number
1042 $this->ColL = array(0); // Array of Left pos of columns - absolute - needs Margin correction for Odd-Even
1043 $this->ColR = array(0); // Array of Right pos of columns - absolute pos - needs Margin correction for Odd-Even
1044 $this->ChangeColumn = 0;
1045 $this->columnbuffer = array();
1046 $this->ColDetails = array(); // Keeps track of some column details
1047 $this->columnLinks = array(); // Cross references PageLinks
1048 $this->substitute = array(); // Array of substitution strings e.g. <ttz>112</ttz>
1049 $this->entsearch = array(); // Array of HTML entities (>ASCII 127) to substitute
1050 $this->entsubstitute = array(); // Array of substitution decimal unicode for the Hi entities
1051 $this->lastoptionaltag = '';
1052 $this->charset_in = '';
1053 $this->blk = array();
1054 $this->blklvl = 0;
1055 $this->tts = false;
1056 $this->ttz = false;
1057 $this->tta = false;
1058 $this->ispre=false;
1059
1060 $this->checkSIP = false;
1061 $this->checkSMP = false;
1062 $this->checkCJK = false;
1063 $this->tableCJK = false;
1064
1065 $this->headerDetails=array();
1066 $this->footerDetails=array();
1067 $this->page_break_after_avoid = false;
1068 $this->margin_bottom_collapse = false;
1069 $this->tablethead = 0;
1070 $this->tabletfoot = 0;
1071 $this->table_border_attr_set = 0;
1072 $this->table_border_css_set = 0;
1073 $this->shrin_k = 1.0;
1074 $this->shrink_this_table_to_fit = 0;
1075 $this->MarginCorrection = 0;
1076
1077 $this->tabletheadjustfinished = false;
1078 $this->usingCoreFont = false;
1079 $this->charspacing=0;
1080
1081 $this->autoPageBreak = true;
1082
1083 require(_MPDF_PATH.'config.php'); // config data
1084
1085 $this->_setPageSize($format, $orientation);
1086 $this->DefOrientation=$orientation;
1087
1088 $this->margin_header=$mgh;
1089 $this->margin_footer=$mgf;
1090
1091 $bmargin=$mgb;
1092
1093 $this->DeflMargin = $mgl;
1094 $this->DefrMargin = $mgr;
1095
1096 $this->orig_tMargin = $mgt;
1097 $this->orig_bMargin = $bmargin;
1098 $this->orig_lMargin = $this->DeflMargin;
1099 $this->orig_rMargin = $this->DefrMargin;
1100 $this->orig_hMargin = $this->margin_header;
1101 $this->orig_fMargin = $this->margin_footer;
1102
1103 if ($this->setAutoTopMargin=='pad') { $mgt += $this->margin_header; }
1104 if ($this->setAutoBottomMargin=='pad') { $mgb += $this->margin_footer; }
1105 $this->SetMargins($this->DeflMargin,$this->DefrMargin,$mgt); // sets l r t margin
1106 //Automatic page break
1107 $this->SetAutoPageBreak($this->autoPageBreak,$bmargin); // sets $this->bMargin & PageBreakTrigger
1108
1109 $this->pgwidth = $this->w - $this->lMargin - $this->rMargin;
1110
1111 //Interior cell margin (1 mm) ? not used
1112 $this->cMarginL = 1;
1113 $this->cMarginR = 1;
1114 //Line width (0.2 mm)
1115 $this->LineWidth=.567/_MPDFK;
1116
1117 //To make the function Footer() work - replaces {nb} with page number
1118 $this->AliasNbPages();
1119 $this->AliasNbPageGroups();
1120
1121 $this->aliasNbPgHex = '{nbHEXmarker}';
1122 $this->aliasNbPgGpHex = '{nbpgHEXmarker}';
1123
1124 //Enable all tags as default
1125 $this->DisableTags();
1126 //Full width display mode
1127 $this->SetDisplayMode(100); // fullwidth? 'fullpage'
1128 //Compression
1129 $this->SetCompression(true);
1130 //Set default display preferences
1131 $this->SetDisplayPreferences('');
1132
1133 // Font data
1134 require(_MPDF_PATH.'config_fonts.php');
1135 // Available fonts
1136 $this->available_unifonts = array();
1137 foreach ($this->fontdata AS $f => $fs) {
1138 if (isset($fs['R']) && $fs['R']) { $this->available_unifonts[] = $f; }
1139 if (isset($fs['B']) && $fs['B']) { $this->available_unifonts[] = $f.'B'; }
1140 if (isset($fs['I']) && $fs['I']) { $this->available_unifonts[] = $f.'I'; }
1141 if (isset($fs['BI']) && $fs['BI']) { $this->available_unifonts[] = $f.'BI'; }
1142 }
1143
1144 $this->default_available_fonts = $this->available_unifonts;
1145
1146 $optcore = false;
1147 $onlyCoreFonts = false;
1148 if (preg_match('/([\-+])aCJK/i',$mode, $m)) {
1149 preg_replace('/([\-+])aCJK/i','',$mode);
1150 if ($m[1]=='+') { $this->useAdobeCJK = true; }
1151 else { $this->useAdobeCJK = false; }
1152 }
1153
1154 if (strlen($mode)==1) {
1155 if ($mode=='s') { $this->percentSubset = 100; $mode = ''; }
1156 else if ($mode=='c') { $onlyCoreFonts = true; $mode = ''; }
1157 }
1158 else if (substr($mode,-2)=='-s') {
1159 $this->percentSubset = 100;
1160 $mode = substr($mode,0,strlen($mode)-2);
1161 }
1162 else if (substr($mode,-2)=='-c') {
1163 $onlyCoreFonts = true;
1164 $mode = substr($mode,0,strlen($mode)-2);
1165 }
1166 else if (substr($mode,-2)=='-x') {
1167 $optcore = true;
1168 $mode = substr($mode,0,strlen($mode)-2);
1169 }
1170
1171 // Autodetect if mode is a language_country string (en-GB or en_GB or en)
1172 if ((strlen($mode) == 5 && $mode != 'UTF-8') || strlen($mode) == 2) {
1173 list ($coreSuitable,$mpdf_pdf_unifonts) = GetLangOpts($mode, $this->useAdobeCJK);
1174 if ($coreSuitable && $optcore) { $onlyCoreFonts = true; }
1175 if ($mpdf_pdf_unifonts) {
1176 $this->RestrictUnicodeFonts($mpdf_pdf_unifonts);
1177 $this->default_available_fonts = $mpdf_pdf_unifonts;
1178 }
1179 $this->currentLang = $mode;
1180 $this->default_lang = $mode;
1181 }
1182
1183 $this->onlyCoreFonts = $onlyCoreFonts;
1184
1185 if ($this->onlyCoreFonts) {
1186 $this->setMBencoding('windows-1252'); // sets $this->mb_enc
1187 }
1188 else {
1189 $this->setMBencoding('UTF-8'); // sets $this->mb_enc
1190 }
1191 @mb_regex_encoding('UTF-8'); // required only for mb_ereg... and mb_split functions
1192
1193
1194 // Adobe CJK fonts
1195 $this->available_CJK_fonts = array('gb','big5','sjis','uhc','gbB','big5B','sjisB','uhcB','gbI','big5I','sjisI','uhcI',
1196 'gbBI','big5BI','sjisBI','uhcBI');
1197
1198
1199 //Standard fonts
1200 $this->CoreFonts=array('ccourier'=>'Courier','ccourierB'=>'Courier-Bold','ccourierI'=>'Courier-Oblique','ccourierBI'=>'Courier-BoldOblique',
1201 'chelvetica'=>'Helvetica','chelveticaB'=>'Helvetica-Bold','chelveticaI'=>'Helvetica-Oblique','chelveticaBI'=>'Helvetica-BoldOblique',
1202 'ctimes'=>'Times-Roman','ctimesB'=>'Times-Bold','ctimesI'=>'Times-Italic','ctimesBI'=>'Times-BoldItalic',
1203 'csymbol'=>'Symbol','czapfdingbats'=>'ZapfDingbats');
1204 $this->fontlist=array("ctimes","ccourier","chelvetica","csymbol","czapfdingbats");
1205
1206 // Substitutions
1207 $this->setHiEntitySubstitutions();
1208
1209 if ($this->onlyCoreFonts) {
1210 $this->useSubstitutions = true;
1211 $this->SetSubstitutions();
1212 }
1213 else { $this->useSubstitutions = false; }
1214
1215 /*-- HTML-CSS --*/
1216
1217 if (!class_exists('cssmgr', false)) { include(_MPDF_PATH .'classes/cssmgr.php'); }
1218 $this->cssmgr = new cssmgr($this);
1219 if (file_exists(_MPDF_PATH.'mpdf.css')) {
1220 $css = file_get_contents(_MPDF_PATH.'mpdf.css');
1221 $css2 = $this->cssmgr->ReadDefaultCSS($css);
1222 $this->defaultCSS = $this->cssmgr->array_merge_recursive_unique($this->defaultCSS,$css2);
1223 }
1224 /*-- END HTML-CSS --*/
1225
1226 if ($default_font=='') {
1227 if ($this->onlyCoreFonts) {
1228 if (in_array(strtolower($this->defaultCSS['BODY']['FONT-FAMILY']),$this->mono_fonts)) { $default_font = 'ccourier'; }
1229 else if (in_array(strtolower($this->defaultCSS['BODY']['FONT-FAMILY']),$this->sans_fonts)) { $default_font = 'chelvetica'; }
1230 else { $default_font = 'ctimes'; }
1231 }
1232 else { $default_font = $this->defaultCSS['BODY']['FONT-FAMILY']; }
1233 }
1234 if (!$default_font_size) {
1235 $mmsize = $this->ConvertSize($this->defaultCSS['BODY']['FONT-SIZE']);
1236 $default_font_size = $mmsize*(_MPDFK);
1237 }
1238
1239 if ($default_font) { $this->SetDefaultFont($default_font); }
1240 if ($default_font_size) { $this->SetDefaultFontSize($default_font_size); }
1241
1242 $this->SetLineHeight(); // lineheight is in mm
1243
1244 $this->SetFColor($this->ConvertColor(255));
1245 $this->HREF='';
1246 $this->oldy=-1;
1247 $this->B=0;
1248 $this->U=false;
1249 $this->S=false;
1250 $this->I=0;
1251
1252 $this->listlvl=0;
1253 $this->listnum=0;
1254 $this->listtype='';
1255 $this->listoccur=array();
1256 $this->listlist=array();
1257 $this->listitem=array();
1258
1259 $this->tdbegin=false;
1260 $this->table=array();
1261 $this->cell=array();
1262 $this->col=-1;
1263 $this->row=-1;
1264 $this->cellBorderBuffer = array();
1265
1266 $this->divbegin=false;
1267 $this->divalign='';
1268 $this->divwidth=0;
1269 $this->divheight=0;
1270 $this->spanbgcolor=false;
1271 $this->divrevert=false;
1272 $this->spanborder=false;
1273 $this->spanborddet=array();
1274
1275 $this->blockjustfinished=false;
1276 $this->listjustfinished=false;
1277 $this->ignorefollowingspaces = true; //in order to eliminate exceeding left-side spaces
1278 $this->toupper=false;
1279 $this->tolower=false;
1280 $this->capitalize=false;
1281 $this->dash_on=false;
1282 $this->dotted_on=false;
1283 $this->SUP=false;
1284 $this->SUB=false;
1285 $this->strike=false;
1286 $this->textshadow='';
1287
1288 $this->currentfontfamily='';
1289 $this->currentfontsize='';
1290 $this->currentfontstyle='';
1291 $this->colorarray=array();
1292 $this->spanbgcolorarray=array();
1293 $this->textbuffer=array();
1294 $this->internallink=array();
1295 $this->basepath = "";
1296
1297 $this->SetBasePath('');
1298
1299 $this->textparam = array();
1300
1301 $this->specialcontent = '';
1302 $this->selectoption = array();
1303
1304 /*-- IMPORTS --*/
1305
1306 $this->tpls = array();
1307 $this->tpl = 0;
1308 $this->tplprefix = "/TPL";
1309 $this->res = array();
1310 if ($this->enableImports) {
1311 $this->SetImportUse();
1312 }
1313 /*-- END IMPORTS --*/
1314
1315 if ($this->progressBar) { $this->StartProgressBarOutput($this->progressBar) ; } // *PROGRESS-BAR*
1316 }
1317
1318
1319 function _setPageSize($format, &$orientation) {
1320 //Page format
1321 if(is_string($format))
1322 {
1323 if ($format=='') { $format = 'A4'; }
1324 $pfo = 'P';
1325 if(preg_match('/([0-9a-zA-Z]*)-L/i',$format,$m)) { // e.g. A4-L = A4 landscape
1326 $format=$m[1];
1327 $pfo='L';
1328 }
1329 $format = $this->_getPageFormat($format);
1330 if (!$format) { $this->Error('Unknown page format: '.$format); }
1331 else { $orientation = $pfo; }
1332
1333 $this->fwPt=$format[0];
1334 $this->fhPt=$format[1];
1335 }
1336 else
1337 {
1338 if (!$format[0] || !$format[1]) { $this->Error('Invalid page format: '.$format[0].' '.$format[1]); }
1339 $this->fwPt=$format[0]*_MPDFK;
1340 $this->fhPt=$format[1]*_MPDFK;
1341 }
1342 $this->fw=$this->fwPt/_MPDFK;
1343 $this->fh=$this->fhPt/_MPDFK;
1344 //Page orientation
1345 $orientation=strtolower($orientation);
1346 if($orientation=='p' or $orientation=='portrait')
1347 {
1348 $orientation='P';
1349 $this->wPt=$this->fwPt;
1350 $this->hPt=$this->fhPt;
1351 }
1352 elseif($orientation=='l' or $orientation=='landscape')
1353 {
1354 $orientation='L';
1355 $this->wPt=$this->fhPt;
1356 $this->hPt=$this->fwPt;
1357 }
1358 else $this->Error('Incorrect orientation: '.$orientation);
1359 $this->CurOrientation=$orientation;
1360
1361 $this->w=$this->wPt/_MPDFK;
1362 $this->h=$this->hPt/_MPDFK;
1363 }
1364
1365 function _getPageFormat($format) {
1366 switch (strtoupper($format)) {
1367 case '4A0': {$format = array(4767.87,6740.79); break;}
1368 case '2A0': {$format = array(3370.39,4767.87); break;}
1369 case 'A0': {$format = array(2383.94,3370.39); break;}
1370 case 'A1': {$format = array(1683.78,2383.94); break;}
1371 case 'A2': {$format = array(1190.55,1683.78); break;}
1372 case 'A3': {$format = array(841.89,1190.55); break;}
1373 case 'A4': default: {$format = array(595.28,841.89); break;}
1374 case 'A5': {$format = array(419.53,595.28); break;}
1375 case 'A6': {$format = array(297.64,419.53); break;}
1376 case 'A7': {$format = array(209.76,297.64); break;}
1377 case 'A8': {$format = array(147.40,209.76); break;}
1378 case 'A9': {$format = array(104.88,147.40); break;}
1379 case 'A10': {$format = array(73.70,104.88); break;}
1380 case 'B0': {$format = array(2834.65,4008.19); break;}
1381 case 'B1': {$format = array(2004.09,2834.65); break;}
1382 case 'B2': {$format = array(1417.32,2004.09); break;}
1383 case 'B3': {$format = array(1000.63,1417.32); break;}
1384 case 'B4': {$format = array(708.66,1000.63); break;}
1385 case 'B5': {$format = array(498.90,708.66); break;}
1386 case 'B6': {$format = array(354.33,498.90); break;}
1387 case 'B7': {$format = array(249.45,354.33); break;}
1388 case 'B8': {$format = array(175.75,249.45); break;}
1389 case 'B9': {$format = array(124.72,175.75); break;}
1390 case 'B10': {$format = array(87.87,124.72); break;}
1391 case 'C0': {$format = array(2599.37,3676.54); break;}
1392 case 'C1': {$format = array(1836.85,2599.37); break;}
1393 case 'C2': {$format = array(1298.27,1836.85); break;}
1394 case 'C3': {$format = array(918.43,1298.27); break;}
1395 case 'C4': {$format = array(649.13,918.43); break;}
1396 case 'C5': {$format = array(459.21,649.13); break;}
1397 case 'C6': {$format = array(323.15,459.21); break;}
1398 case 'C7': {$format = array(229.61,323.15); break;}
1399 case 'C8': {$format = array(161.57,229.61); break;}
1400 case 'C9': {$format = array(113.39,161.57); break;}
1401 case 'C10': {$format = array(79.37,113.39); break;}
1402 case 'RA0': {$format = array(2437.80,3458.27); break;}
1403 case 'RA1': {$format = array(1729.13,2437.80); break;}
1404 case 'RA2': {$format = array(1218.90,1729.13); break;}
1405 case 'RA3': {$format = array(864.57,1218.90); break;}
1406 case 'RA4': {$format = array(609.45,864.57); break;}
1407 case 'SRA0': {$format = array(2551.18,3628.35); break;}
1408 case 'SRA1': {$format = array(1814.17,2551.18); break;}
1409 case 'SRA2': {$format = array(1275.59,1814.17); break;}
1410 case 'SRA3': {$format = array(907.09,1275.59); break;}
1411 case 'SRA4': {$format = array(637.80,907.09); break;}
1412 case 'LETTER': {$format = array(612.00,792.00); break;}
1413 case 'LEGAL': {$format = array(612.00,1008.00); break;}
1414 case 'LEDGER': {$format = array(279.00,432.00); break;}
1415 case 'TABLOID': {$format = array(279.00,432.00); break;}
1416 case 'EXECUTIVE': {$format = array(521.86,756.00); break;}
1417 case 'FOLIO': {$format = array(612.00,936.00); break;}
1418 case 'B': {$format=array(362.83,561.26 ); break;} // 'B' format paperback size 128x198mm
1419 case 'A': {$format=array(314.65,504.57 ); break;} // 'A' format paperback size 111x178mm
1420 case 'DEMY': {$format=array(382.68,612.28 ); break;} // 'Demy' format paperback size 135x216mm
1421 case 'ROYAL': {$format=array(433.70,663.30 ); break;} // 'Royal' format paperback size 153x234mm
1422 default: $format = false;
1423 }
1424 return $format;
1425 }
1426
1427
1428 /*-- PROGRESS-BAR --*/
1429 function StartProgressBarOutput($mode=1) {
1430 // must be relative path, or URI (not a file system path)
1431 if (!defined('_MPDF_URI')) {
1432 $this->progressBar = false;
1433 if ($this->debug) { $this->Error("You need to define _MPDF_URI to use the progress bar!"); }
1434 else return false;
1435 }
1436 $this->progressBar = $mode;
1437 if ($this->progbar_altHTML) {
1438 echo $this->progbar_altHTML;
1439 }
1440 else {
1441 echo '<html>
1442 <head>
1443 <title>mPDF File Progress</title>
1444 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
1445 <link rel="stylesheet" type="text/css" href="'._MPDF_URI.'progbar.css" />
1446 </head>
1447 <body>
1448 <div class="main">
1449 <div class="heading">'.$this->progbar_heading.'</div>
1450 <div class="demo">
1451 ';
1452 if ($this->progressBar==2) { echo ' <table width="100%"><tr><td style="width: 50%;">
1453 <span class="barheading">Writing HTML code</span> <br/>
1454
1455 <div class="progressBar">
1456 <div id="element1" class="innerBar">&nbsp;</div>
1457 </div>
1458 <span class="code" id="box1"></span>
1459 </td><td style="width: 50%;">
1460 <span class="barheading">Autosizing elements</span> <br/>
1461 <div class="progressBar">
1462 <div id="element4" class="innerBar">&nbsp;</div>
1463 </div>
1464 <span class="code" id="box4"></span>
1465 <br/><br/>
1466 <span class="barheading">Writing Tables</span> <br/>
1467 <div class="progressBar">
1468 <div id="element7" class="innerBar">&nbsp;</div>
1469 </div>
1470 <span class="code" id="box7"></span>
1471 </td></tr>
1472 <tr><td><br /><br /></td><td></td></tr>
1473 <tr><td style="width: 50%;">
1474 '; }
1475 echo ' <span class="barheading">Writing PDF file</span> <br/>
1476 <div class="progressBar">
1477 <div id="element2" class="innerBar">&nbsp;</div>
1478 </div>
1479 <span class="code" id="box2"></span>
1480 ';
1481 if ($this->progressBar==2) { echo '
1482 </td><td style="width: 50%;">
1483 <span class="barheading">Memory usage</span> <br/>
1484 <div class="progressBar">
1485 <div id="element5" class="innerBar">&nbsp;</div>
1486 </div>
1487 <span id="box5">0</span> '.ini_get("memory_limit").'<br />
1488 <br/><br/>
1489 <span class="barheading">Memory usage (peak)</span> <br/>
1490 <div class="progressBar">
1491 <div id="element6" class="innerBar">&nbsp;</div>
1492 </div>
1493 <span id="box6">0</span> '.ini_get("memory_limit").'<br />
1494 </td></tr>
1495 </table>
1496 '; }
1497 echo ' <br/><br/>
1498 <span id="box3"></span>
1499
1500 </div>
1501 ';
1502 }
1503 ob_flush();
1504 flush();
1505 }
1506
1507 function UpdateProgressBar($el,$val,$txt='') {
1508 // $val should be a string - 5 = actual value, +15 = increment
1509
1510 if ($this->progressBar<2) {
1511 if ($el>3) { return; }
1512 else if ($el ==1) { $el = 2; }
1513 }
1514 echo '<script type="text/javascript">';
1515 if ($val) { echo ' document.getElementById(\'element'.$el.'\').style.width=\''.$val.'%\'; '; }
1516 if ($txt) { echo ' document.getElementById(\'box'.$el.'\').innerHTML=\''.$txt.'\'; '; }
1517 if ($this->progressBar==2) {
1518 $m = round(memory_get_usage(true)/1048576);
1519 $m2 = round(memory_get_peak_usage(true)/1048576);
1520 $mem = $m * 100 / (ini_get("memory_limit")+0);
1521 $mem2 = $m2 * 100 / (ini_get("memory_limit")+0);
1522 echo ' document.getElementById(\'element5\').style.width=\''.$mem.'%\'; ';
1523 echo ' document.getElementById(\'element6\').style.width=\''.$mem2.'%\'; ';
1524 echo ' document.getElementById(\'box5\').innerHTML=\''.$m.'MB / \'; ';
1525 echo ' document.getElementById(\'box6\').innerHTML=\''.$m2.'MB / \'; ';
1526 }
1527 echo '</script>'."\n";
1528 ob_flush();
1529 flush();
1530 }
1531 /*-- END PROGRESS-BAR --*/
1532
1533
1534
1535 function RestrictUnicodeFonts($res) {
1536 // $res = array of (Unicode) fonts to restrict to: e.g. norasi|norasiB - language specific
1537 if (count($res)) { // Leave full list of available fonts if passed blank array
1538 $this->available_unifonts = $res;
1539 }
1540 else { $this->available_unifonts = $this->default_available_fonts; }
1541 if (count($this->available_unifonts) == 0) { $this->available_unifonts[] = $this->default_available_fonts[0]; }
1542 $this->available_unifonts = array_values($this->available_unifonts);
1543 }
1544
1545
1546 function setMBencoding($enc) {
1547 if ($this->mb_enc != $enc) {
1548 $this->mb_enc = $enc;
1549 mb_internal_encoding($this->mb_enc);
1550 }
1551 }
1552
1553
1554 function SetMargins($left,$right,$top) {
1555 //Set left, top and right margins
1556 $this->lMargin=$left;
1557 $this->rMargin=$right;
1558 $this->tMargin=$top;
1559 }
1560
1561 function ResetMargins() {
1562 //ReSet left, top margins
1563 if (($this->forcePortraitHeaders || $this->forcePortraitMargins) && $this->DefOrientation=='P' && $this->CurOrientation=='L') {
1564 if (($this->mirrorMargins) && (($this->page)%2==0)) { // EVEN
1565 $this->tMargin=$this->orig_rMargin;
1566 $this->bMargin=$this->orig_lMargin;
1567 }
1568 else { // ODD // OR NOT MIRRORING MARGINS/FOOTERS
1569 $this->tMargin=$this->orig_lMargin;
1570 $this->bMargin=$this->orig_rMargin;
1571 }
1572 $this->lMargin=$this->DeflMargin;
1573 $this->rMargin=$this->DefrMargin;
1574 $this->MarginCorrection = 0;
1575 $this->PageBreakTrigger=$this->h-$this->bMargin;
1576 }
1577 else if (($this->mirrorMargins) && (($this->page)%2==0)) { // EVEN
1578 $this->lMargin=$this->DefrMargin;
1579 $this->rMargin=$this->DeflMargin;
1580 $this->MarginCorrection = $this->DefrMargin-$this->DeflMargin;
1581
1582 }
1583 else { // ODD // OR NOT MIRRORING MARGINS/FOOTERS
1584 $this->lMargin=$this->DeflMargin;
1585 $this->rMargin=$this->DefrMargin;
1586 if ($this->mirrorMargins) { $this->MarginCorrection = $this->DeflMargin-$this->DefrMargin; }
1587 }
1588 $this->x=$this->lMargin;
1589
1590 }
1591
1592 function SetLeftMargin($margin) {
1593 //Set left margin
1594 $this->lMargin=$margin;
1595 if($this->page>0 and $this->x<$margin) $this->x=$margin;
1596 }
1597
1598 function SetTopMargin($margin) {
1599 //Set top margin
1600 $this->tMargin=$margin;
1601 }
1602
1603 function SetRightMargin($margin) {
1604 //Set right margin
1605 $this->rMargin=$margin;
1606 }
1607
1608 function SetAutoPageBreak($auto,$margin=0) {
1609 //Set auto page break mode and triggering margin
1610 $this->autoPageBreak=$auto;
1611 $this->bMargin=$margin;
1612 $this->PageBreakTrigger=$this->h-$margin;
1613 }
1614
1615 function SetDisplayMode($zoom,$layout='continuous') {
1616 //Set display mode in viewer
1617 if($zoom=='fullpage' or $zoom=='fullwidth' or $zoom=='real' or $zoom=='default' or !is_string($zoom))
1618 $this->ZoomMode=$zoom;
1619 else
1620 $this->Error('Incorrect zoom display mode: '.$zoom);
1621 if($layout=='single' or $layout=='continuous' or $layout=='two' or $layout=='twoleft' or $layout=='tworight' or $layout=='default')
1622 $this->LayoutMode=$layout;
1623 else
1624 $this->Error('Incorrect layout display mode: '.$layout);
1625 }
1626
1627 function SetCompression($compress) {
1628 //Set page compression
1629 if(function_exists('gzcompress')) $this->compress=$compress;
1630 else $this->compress=false;
1631 }
1632
1633 function SetTitle($title) {
1634 //Title of document // Arrives as UTF-8
1635 $this->title = $title;
1636 }
1637
1638 function SetSubject($subject) {
1639 //Subject of document
1640 $this->subject= $subject;
1641 }
1642
1643 function SetAuthor($author) {
1644 //Author of document
1645 $this->author= $author;
1646 }
1647
1648 function SetKeywords($keywords) {
1649 //Keywords of document
1650 $this->keywords= $keywords;
1651 }
1652
1653 function SetCreator($creator) {
1654 //Creator of document
1655 $this->creator= $creator;
1656 }
1657
1658
1659 function SetAnchor2Bookmark($x) {
1660 $this->anchor2Bookmark = $x;
1661 }
1662
1663 function AliasNbPages($alias='{nb}') {
1664 //Define an alias for total number of pages
1665 $this->aliasNbPg=$alias;
1666 }
1667
1668 function AliasNbPageGroups($alias='{nbpg}') {
1669 //Define an alias for total number of pages in a group
1670 $this->aliasNbPgGp=$alias;
1671 }
1672
1673 function SetAlpha($alpha, $bm='Normal', $return=false, $mode='B') {
1674 // alpha: real value from 0 (transparent) to 1 (opaque)
1675 // bm: blend mode, one of the following:
1676 // Normal, Multiply, Screen, Overlay, Darken, Lighten, ColorDodge, ColorBurn,
1677 // HardLight, SoftLight, Difference, Exclusion, Hue, Saturation, Color, Luminosity
1678 // set alpha for stroking (CA) and non-stroking (ca) operations
1679 // mode determines F (fill) S (stroke) B (both)
1680 if (($this->PDFA || $this->PDFX) && $alpha!=1) {
1681 if (($this->PDFA && !$this->PDFAauto) || ($this->PDFX && !$this->PDFXauto)) { $this->PDFAXwarnings[] = "Image opacity must be 100% (Opacity changed to 100%)"; }
1682 $alpha = 1;
1683 }
1684 $a = array('BM'=>'/'.$bm);
1685 if ($mode=='F' || $mode='B') $a['ca'] = $alpha;
1686 if ($mode=='S' || $mode='B') $a['CA'] = $alpha;
1687 $gs = $this->AddExtGState($a);
1688 if ($return) { return sprintf('/GS%d gs', $gs); }
1689 else { $this->_out(sprintf('/GS%d gs', $gs)); }
1690 }
1691
1692 function AddExtGState($parms) {
1693 $n = count($this->extgstates);
1694 // check if graphics state already exists
1695 for ($i=1; $i<=$n; $i++) {
1696 if (count($this->extgstates[$i]['parms']) == count($parms)) {
1697 $same = true;
1698 foreach($this->extgstates[$i]['parms'] AS $k=>$v) {
1699 if (!isset($parms[$k]) || $parms[$k] != $v) { $same = false; break; }
1700 }
1701 if ($same) { return $i; }
1702 }
1703 }
1704 $n++;
1705 $this->extgstates[$n]['parms'] = $parms;
1706 return $n;
1707 }
1708
1709 function SetVisibility($v) {
1710 if (($this->PDFA || $this->PDFX) && $this->visibility!='visible') { $this->PDFAXwarnings[] = "Cannot set visibility to anything other than full when using PDFA or PDFX"; return ''; }
1711 else if (!$this->PDFA && !$this->PDFX)
1712 $this->pdf_version='1.5';
1713 if($this->visibility!='visible') {
1714 $this->_out('EMC');
1715 $this->hasOC=intval($this->hasOC ); // mPDF 5.6.01
1716 }
1717 if($v=='printonly') {
1718 $this->_out('/OC /OC1 BDC');
1719 $this->hasOC=($this->hasOC | 1); // mPDF 5.6.01
1720 }
1721 elseif($v=='screenonly') {
1722 $this->_out('/OC /OC2 BDC');
1723 $this->hasOC=($this->hasOC | 2); // mPDF 5.6.01
1724 }
1725 elseif($v=='hidden') {
1726 $this->_out('/OC /OC3 BDC');
1727 $this->hasOC=($this->hasOC | 4); // mPDF 5.6.01
1728 }
1729 elseif($v!='visible')
1730 $this->Error('Incorrect visibility: '.$v);
1731 $this->visibility=$v;
1732 }
1733
1734 function Error($msg) {
1735 //Fatal error
1736 header('Content-Type: text/html; charset=utf-8');
1737 die('<B>mPDF error: </B>'.$msg);
1738 }
1739
1740 function Open() {
1741 //Begin document
1742 if($this->state==0) $this->_begindoc();
1743 }
1744
1745 function Close() {
1746 if ($this->progressBar) { $this->UpdateProgressBar(2,'2','Closing last page'); } // *PROGRESS-BAR*
1747 //Terminate document
1748 if($this->state==3) return;
1749 if($this->page==0) $this->AddPage($this->CurOrientation);
1750 if (count($this->cellBorderBuffer)) { $this->printcellbuffer(); } // *TABLES*
1751 if ($this->tablebuffer) { $this->printtablebuffer(); } // *TABLES*
1752 /*-- COLUMNS --*/
1753
1754 if ($this->ColActive) {
1755 $this->SetColumns(0);
1756 $this->ColActive = 0;
1757 if (count($this->columnbuffer)) { $this->printcolumnbuffer(); }
1758 }
1759 /*-- END COLUMNS --*/
1760 if (count($this->divbuffer)) { $this->printdivbuffer(); }
1761
1762 // BODY Backgrounds
1763 $s = '';
1764
1765 $s .= $this->PrintBodyBackgrounds();
1766
1767 $s .= $this->PrintPageBackgrounds();
1768 $this->pages[$this->page] = preg_replace('/(___BACKGROUND___PATTERNS'.date('jY').')/', "\n".$s."\n".'\\1', $this->pages[$this->page]);
1769 $this->pageBackgrounds = array();
1770
1771 if($this->visibility!='visible')
1772 $this->SetVisibility('visible');
1773 // mPDF 5.6.01 - LAYERS
1774 $this->EndLayer();
1775
1776 if (!$this->tocontents || !$this->tocontents->TOCmark) { //Page footer
1777 $this->InFooter=true;
1778 $this->Footer();
1779 $this->InFooter=false;
1780 }
1781 if ($this->tocontents && ($this->tocontents->TOCmark || count($this->tocontents->m_TOC))) { $this->tocontents->insertTOC(); } // *TOC*
1782
1783 //Close page
1784 $this->_endpage();
1785
1786 //Close document
1787 $this->_enddoc();
1788 }
1789
1790 /*-- BACKGROUNDS --*/
1791 function _resizeBackgroundImage($imw, $imh, $cw, $ch, $resize=0, $repx, $repy, $pba=array(), $size=array()) { // mPDF 5.6.10
1792 // pba is background positioning area (from CSS background-origin) may not always be set [x,y,w,h]
1793 // size is from CSS3 background-size - takes precendence over old resize
1794 // $w - absolute length or % or auto or cover | contain
1795 // $h - absolute length or % or auto or cover | contain
1796 // mPDF 5.6.10
1797 if (isset($pba['w'])) $cw = $pba['w'];
1798 if (isset($pba['h'])) $ch = $pba['h'];
1799
1800 $cw = $cw*_MPDFK;
1801 $ch = $ch*_MPDFK;
1802 if (empty($size) && !$resize) { return array($imw, $imh, $repx, $repy); }
1803
1804 // mPDF 5.6.10
1805 if (isset($size['w']) && $size['w']) {
1806 if ($size['w']=='contain') {
1807 // Scale the image, while preserving its intrinsic aspect ratio (if any), to the largest size such that both its width and its height can fit inside the background positioning area.
1808 // Same as resize==3
1809 $h = $imh * $cw/$imw;
1810 $w = $cw;
1811 if ($h > $ch) {
1812 $w = $w * $ch/$h;
1813 $h = $ch;
1814 }
1815 }
1816 else if ($size['w']=='cover') {
1817 // Scale the image, while preserving its intrinsic aspect ratio (if any), to the smallest size such that both its width and its height can completely cover the background positioning area.
1818 $h = $imh * $cw/$imw;
1819 $w = $cw;
1820 if ($h < $ch) {
1821 $w = $w * $h/$ch;
1822 $h = $ch;
1823 }
1824 }
1825 else {
1826 if (stristr($size['w'] ,'%')) {
1827 $size['w'] += 0;
1828 $size['w'] /= 100;
1829 $size['w'] = ($cw * $size['w']);
1830 }
1831 if (stristr($size['h'] ,'%')) {
1832 $size['h'] += 0;
1833 $size['h'] /= 100;
1834 $size['h'] = ($ch * $size['h']);
1835 }
1836 if ($size['w']=='auto' && $size['h']=='auto') {
1837 $w = $imw;
1838 $h = $imh;
1839 }
1840 else if ($size['w']=='auto' && $size['h']!='auto') {
1841 $w = $imw * $size['h']/$imh;
1842 $h = $size['h'];
1843 }
1844 else if ($size['w']!='auto' && $size['h']=='auto') {
1845 $h = $imh * $size['w']/$imw;
1846 $w = $size['w'];
1847 }
1848 else {
1849 $w = $size['w'];
1850 $h = $size['h'];
1851 }
1852 }
1853 return array($w, $h, $repx, $repy);
1854 }
1855 else if ($resize==1 && $imw > $cw) {
1856 $h = $imh * $cw/$imw;
1857 return array($cw, $h, $repx, $repy);
1858 }
1859 else if ($resize==2 && $imh > $ch) {
1860 $w = $imw * $ch/$imh;
1861 return array($w, $ch, $repx, $repy);
1862 }
1863 else if ($resize==3) {
1864 $w = $imw;
1865 $h = $imh;
1866 if ($w > $cw) {
1867 $h = $h * $cw/$w;
1868 $w = $cw;
1869 }
1870 if ($h > $ch) {
1871 $w = $w * $ch/$h;
1872 $h = $ch;
1873 }
1874 return array($w, $h, $repx, $repy);
1875 }
1876 else if ($resize==4) {
1877 $h = $imh * $cw/$imw;
1878 return array($cw, $h, $repx, $repy);
1879 }
1880 else if ($resize==5) {
1881 $w = $imw * $ch/$imh;
1882 return array($w, $ch, $repx, $repy);
1883 }
1884 else if ($resize==6) {
1885 return array($cw, $ch, $repx, $repy);
1886 }
1887 return array($imw, $imh, $repx, $repy);
1888 }
1889
1890
1891 function SetBackground(&$properties, &$maxwidth) {
1892 // mPDF 5.6.10 5.6.11
1893 if (isset($properties['BACKGROUND-ORIGIN']) && ($properties['BACKGROUND-ORIGIN']=='border-box' || $properties['BACKGROUND-ORIGIN']== 'content-box')) { $origin = $properties['BACKGROUND-ORIGIN']; }
1894 else { $origin = 'padding-box'; }
1895 // mPDF 5.6.10
1896 if (isset($properties['BACKGROUND-SIZE'])) {
1897 if (stristr($properties['BACKGROUND-SIZE'] ,'contain') ) { $bsw = $bsh = 'contain'; }
1898 else if (stristr($properties['BACKGROUND-SIZE'] ,'cover') ) { $bsw = $bsh = 'cover'; }
1899 else {
1900 $bsw = $bsh = 'auto';
1901 $sz = preg_split('/\s+/',trim($properties['BACKGROUND-SIZE']));
1902 if (count($sz)==2) { $bsw = $sz[0]; $bsh = $sz[1]; }
1903 else { $bsw = $sz[0]; }
1904 if (!stristr($bsw ,'%') && !stristr($bsw ,'auto') ) { $bsw = $this->ConvertSize($bsw ,$maxwidth,$this->FontSize); }
1905 if (!stristr($bsh ,'%') && !stristr($bsh ,'auto') ) { $bsh = $this->ConvertSize($bsh ,$maxwidth,$this->FontSize); }
1906 }
1907 $size = array('w'=>$bsw, 'h'=>$bsh);
1908 }
1909 if (preg_match('/(-moz-)*(repeating-)*(linear|radial)-gradient/',$properties['BACKGROUND-IMAGE'])) {
1910 return array('gradient'=>$properties['BACKGROUND-IMAGE'], 'origin'=>$origin, 'size'=>$size ); // mPDF 5.6.10
1911 }
1912 else {
1913 $file = $properties['BACKGROUND-IMAGE'];
1914 $sizesarray = $this->Image($file,0,0,0,0,'','',false, false, false, false, true);
1915 if (isset($sizesarray['IMAGE_ID'])) {
1916 $image_id = $sizesarray['IMAGE_ID'];
1917 $orig_w = $sizesarray['WIDTH']*_MPDFK; // in user units i.e. mm
1918 $orig_h = $sizesarray['HEIGHT']*_MPDFK; // (using $this->img_dpi)
1919 if (isset($properties['BACKGROUND-IMAGE-RESOLUTION'])) {
1920 if (preg_match('/from-image/i', $properties['BACKGROUND-IMAGE-RESOLUTION']) && isset($sizesarray['set-dpi']) && $sizesarray['set-dpi']>0) {
1921 $orig_w *= $this->img_dpi / $sizesarray['set-dpi'];
1922 $orig_h *= $this->img_dpi / $sizesarray['set-dpi'];
1923 }
1924 else if (preg_match('/(\d+)dpi/i', $properties['BACKGROUND-IMAGE-RESOLUTION'], $m)) {
1925 $dpi = $m[1];
1926 if ($dpi > 0) {
1927 $orig_w *= $this->img_dpi / $dpi;
1928 $orig_h *= $this->img_dpi / $dpi;
1929 }
1930 }
1931 }
1932 $x_repeat = true;
1933 $y_repeat = true;
1934 if (isset($properties['BACKGROUND-REPEAT'])) {
1935 if ($properties['BACKGROUND-REPEAT']=='no-repeat' || $properties['BACKGROUND-REPEAT']=='repeat-x') { $y_repeat = false; }
1936 if ($properties['BACKGROUND-REPEAT']=='no-repeat' || $properties['BACKGROUND-REPEAT']=='repeat-y') { $x_repeat = false; }
1937 }
1938 $x_pos = 0;
1939 $y_pos = 0;
1940 if (isset($properties['BACKGROUND-POSITION'])) {
1941 $ppos = preg_split('/\s+/',$properties['BACKGROUND-POSITION']);
1942 $x_pos = $ppos[0];
1943 $y_pos = $ppos[1];
1944 if (!stristr($x_pos ,'%') ) { $x_pos = $this->ConvertSize($x_pos ,$maxwidth,$this->FontSize); }
1945 if (!stristr($y_pos ,'%') ) { $y_pos = $this->ConvertSize($y_pos ,$maxwidth,$this->FontSize); }
1946 }
1947 if (isset($properties['BACKGROUND-IMAGE-RESIZE'])) { $resize = $properties['BACKGROUND-IMAGE-RESIZE']; }
1948 else { $resize = 0; }
1949 if (isset($properties['BACKGROUND-IMAGE-OPACITY'])) { $opacity = $properties['BACKGROUND-IMAGE-OPACITY']; }
1950 else { $opacity = 1; }
1951 return array('image_id'=>$image_id, 'orig_w'=>$orig_w, 'orig_h'=>$orig_h, 'x_pos'=>$x_pos, 'y_pos'=>$y_pos, 'x_repeat'=>$x_repeat, 'y_repeat'=>$y_repeat, 'resize'=>$resize, 'opacity'=>$opacity, 'itype'=>$sizesarray['itype'], 'origin'=>$origin, 'size'=>$size );
1952 }
1953 }
1954 return false;
1955 }
1956 /*-- END BACKGROUNDS --*/
1957
1958 function PrintBodyBackgrounds() {
1959 $s = '';
1960 $clx = 0;
1961 $cly = 0;
1962 $clw = $this->w;
1963 $clh = $this->h;
1964 // If using bleed and trim margins in paged media
1965 if ($this->pageDim[$this->page]['outer_width_LR'] || $this->pageDim[$this->page]['outer_width_TB']) {
1966 $clx = $this->pageDim[$this->page]['outer_width_LR'] - $this->pageDim[$this->page]['bleedMargin'];
1967 $cly = $this->pageDim[$this->page]['outer_width_TB'] - $this->pageDim[$this->page]['bleedMargin'];
1968 $clw = $this->w - 2*$clx;
1969 $clh = $this->h - 2*$cly;
1970 }
1971
1972 if ($this->bodyBackgroundColor) {
1973 $s .= 'q ' .$this->SetFColor($this->bodyBackgroundColor, true)."\n";
1974 if ($this->bodyBackgroundColor{0}==5) { // RGBa
1975 $s .= $this->SetAlpha(ord($this->bodyBackgroundColor{4})/100, 'Normal', true, 'F')."\n";
1976 }
1977 else if ($this->bodyBackgroundColor{0}==6) { // CMYKa
1978 $s .= $this->SetAlpha(ord($this->bodyBackgroundColor{5})/100, 'Normal', true, 'F')."\n";
1979 }
1980 $s .= sprintf('%.3F %.3F %.3F %.3F re f Q', ($clx*_MPDFK), ($cly*_MPDFK),$clw*_MPDFK,$clh*_MPDFK)."\n";
1981 }
1982
1983 /*-- BACKGROUNDS --*/
1984 if ($this->bodyBackgroundGradient) {
1985 $g = $this->grad->parseBackgroundGradient($this->bodyBackgroundGradient);
1986 if ($g) {
1987 $s .= $this->grad->Gradient($clx, $cly, $clw, $clh, (isset($g['gradtype']) ? $g['gradtype'] : null), $g['stops'], $g['colorspace'], $g['coords'], $g['extend'], true);
1988 }
1989 }
1990 if ($this->bodyBackgroundImage) {
1991 if ( $this->bodyBackgroundImage['gradient'] && preg_match('/(-moz-)*(repeating-)*(linear|radial)-gradient/', $this->bodyBackgroundImage['gradient'])) {
1992 $g = $this->grad->parseMozGradient( $this->bodyBackgroundImage['gradient']);
1993 if ($g) {
1994 $s .= $this->grad->Gradient($clx, $cly, $clw, $clh, $g['type'], $g['stops'], $g['colorspace'], $g['coords'], $g['extend'], true);
1995 }
1996 }
1997 else if ($this->bodyBackgroundImage['image_id']) { // Background pattern
1998 $n = count($this->patterns)+1;
1999 // If using resize, uses TrimBox (not including the bleed)
2000 list($orig_w, $orig_h, $x_repeat, $y_repeat) = $this->_resizeBackgroundImage($this->bodyBackgroundImage['orig_w'], $this->bodyBackgroundImage['orig_h'], $clw, $clh, $this->bodyBackgroundImage['resize'], $this->bodyBackgroundImage['x_repeat'], $this->bodyBackgroundImage['y_repeat']);
2001
2002 $this->patterns[$n] = array('x'=>$clx, 'y'=>$cly, 'w'=>$clw, 'h'=>$clh, 'pgh'=>$this->h, 'image_id'=>$this->bodyBackgroundImage['image_id'], 'orig_w'=>$orig_w, 'orig_h'=>$orig_h, 'x_pos'=>$this->bodyBackgroundImage['x_pos'], 'y_pos'=>$this->bodyBackgroundImage['y_pos'], 'x_repeat'=>$x_repeat, 'y_repeat'=>$y_repeat, 'itype'=>$this->bodyBackgroundImage['itype']);
2003 if (($this->bodyBackgroundImage['opacity']>0 || $this->bodyBackgroundImage['opacity']==='0') && $this->bodyBackgroundImage['opacity']<1) { $opac = $this->SetAlpha($this->bodyBackgroundImage['opacity'],'Normal',true); }
2004 else { $opac = ''; }
2005 $s .= sprintf('q /Pattern cs /P%d scn %s %.3F %.3F %.3F %.3F re f Q', $n, $opac, ($clx*_MPDFK), ($cly*_MPDFK),$clw*_MPDFK, $clh*_MPDFK) ."\n";
2006 }
2007 }
2008 /*-- END BACKGROUNDS --*/
2009 return $s;
2010 }
2011
2012
2013 function PrintPageBackgrounds($adjustmenty=0) {
2014 $s = '';
2015
2016 ksort($this->pageBackgrounds);
2017 foreach($this->pageBackgrounds AS $bl=>$pbs) {
2018 foreach ($pbs AS $pb) {
2019 if ((!isset($pb['image_id']) && !isset($pb['gradient'])) || isset($pb['shadowonly'])) { // Background colour or boxshadow
2020 // mPDF 5.6.01 - LAYERS
2021 if($pb['z-index']>0) {
2022 $this->current_layer = $pb['z-index'];
2023 $s .= "\n".'/OCBZ-index /ZI'.$pb['z-index'].' BDC'."\n";
2024 }
2025
2026 if($pb['visibility']!='visible') {
2027 if($pb['visibility']=='printonly')
2028 $s .= '/OC /OC1 BDC'."\n";
2029 else if($pb['visibility']=='screenonly')
2030 $s .= '/OC /OC2 BDC'."\n";
2031 else if($pb['visibility']=='hidden')
2032 $s .= '/OC /OC3 BDC'."\n";
2033 }
2034 // Box shadow
2035 if (isset($pb['shadow']) && $pb['shadow']) { $s .= $pb['shadow']."\n"; }
2036 if (isset($pb['clippath']) && $pb['clippath']) { $s .= $pb['clippath']."\n"; }
2037 $s .= 'q '.$this->SetFColor($pb['col'], true)."\n";
2038 if ($pb['col']{0}==5) { // RGBa
2039 $s .= $this->SetAlpha(ord($pb['col']{4})/100, 'Normal', true, 'F')."\n";
2040 }
2041 else if ($pb['col']{0}==6) { // CMYKa
2042 $s .= $this->SetAlpha(ord($pb['col']{5})/100, 'Normal', true, 'F')."\n";
2043 }
2044 $s .= sprintf('%.3F %.3F %.3F %.3F re f Q',$pb['x']*_MPDFK,($this->h-$pb['y'])*_MPDFK,$pb['w']*_MPDFK,-$pb['h']*_MPDFK)."\n";
2045 if (isset($pb['clippath']) && $pb['clippath']) { $s .= 'Q'."\n"; }
2046 if($pb['visibility']!='visible')
2047 $s .= 'EMC'."\n";
2048
2049 // mPDF 5.6.01 - LAYERS
2050 if($pb['z-index']>0) {
2051 $s .= "\n".'EMCBZ-index'."\n";
2052 $this->current_layer = 0;
2053 }
2054 }
2055 }
2056 /*-- BACKGROUNDS --*/
2057 foreach ($pbs AS $pb) {
2058 // mPDF 5.6.01 - LAYERS
2059 if ((isset($pb['gradient']) && $pb['gradient']) || (isset($pb['image_id']) && $pb['image_id'])) {
2060 if($pb['z-index']>0) {
2061 $this->current_layer = $pb['z-index'];
2062 $s .= "\n".'/OCGZ-index /ZI'.$pb['z-index'].' BDC'."\n";
2063 }
2064 if($pb['visibility']!='visible') {
2065 if($pb['visibility']=='printonly')
2066 $s .= '/OC /OC1 BDC'."\n";
2067 else if($pb['visibility']=='screenonly')
2068 $s .= '/OC /OC2 BDC'."\n";
2069 else if($pb['visibility']=='hidden')
2070 $s .= '/OC /OC3 BDC'."\n";
2071 }
2072 }
2073 if (isset($pb['gradient']) && $pb['gradient']) {
2074 if (isset($pb['clippath']) && $pb['clippath']) { $s .= $pb['clippath']."\n"; }
2075 $s .= $this->grad->Gradient($pb['x'], $pb['y'], $pb['w'], $pb['h'], $pb['gradtype'], $pb['stops'], $pb['colorspace'], $pb['coords'], $pb['extend'], true);
2076 if (isset($pb['clippath']) && $pb['clippath']) { $s .= 'Q'."\n"; }
2077 }
2078 else if (isset($pb['image_id']) && $pb['image_id']) { // Background Image
2079 $pb['y'] -= $adjustmenty;
2080 $pb['h'] += $adjustmenty;
2081 $n = count($this->patterns)+1;
2082 list($orig_w, $orig_h, $x_repeat, $y_repeat) = $this->_resizeBackgroundImage($pb['orig_w'], $pb['orig_h'], $pb['w'], $pb['h'], $pb['resize'], $pb['x_repeat'], $pb['y_repeat'], $pb['bpa'], $pb['size']); // mPDF 5.6.10
2083 $this->patterns[$n] = array('x'=>$pb['x'], 'y'=>$pb['y'], 'w'=>$pb['w'], 'h'=>$pb['h'], 'pgh'=>$this->h, 'image_id'=>$pb['image_id'], 'orig_w'=>$orig_w, 'orig_h'=>$orig_h, 'x_pos'=>$pb['x_pos'], 'y_pos'=>$pb['y_pos'], 'x_repeat'=>$x_repeat, 'y_repeat'=>$y_repeat, 'itype'=>$pb['itype'], 'bpa'=>$pb['bpa']); // mPDF 5.6.10
2084 $x = $pb['x']*_MPDFK;
2085 $y = ($this->h - $pb['y'])*_MPDFK;
2086 $w = $pb['w']*_MPDFK;
2087 $h = -$pb['h']*_MPDFK;
2088 if (isset($pb['clippath']) && $pb['clippath']) { $s .= $pb['clippath']."\n"; }
2089 if ($this->writingHTMLfooter || $this->writingHTMLheader) { // Write each (tiles) image rather than use as a pattern
2090 $iw = $pb['orig_w']/_MPDFK;
2091 $ih = $pb['orig_h']/_MPDFK;
2092
2093 $w = $pb['w'];
2094 $h = $pb['h'];
2095 $x0 = $pb['x'];
2096 $y0 = $pb['y'];
2097
2098 // mPDF 5.6.11
2099 if (isset($pb['bpa']) && $pb['bpa']) {
2100 $w = $pb['bpa']['w'];
2101 $h = $pb['bpa']['h'];
2102 $x0 = $pb['bpa']['x'];
2103 $y0 = $pb['bpa']['y'];
2104 }
2105
2106 // mPDF 5.6.11
2107 if (isset($pb['size']['w']) && $pb['size']['w']) {
2108 $size = $pb['size'];
2109
2110 if ($size['w']=='contain') {
2111 // Scale the image, while preserving its intrinsic aspect ratio (if any), to the largest size such that both its width and its height can fit inside the background positioning area.
2112 // Same as resize==3
2113 $ih = $ih * $pb['bpa']['w']/$iw;
2114 $iw = $pb['bpa']['w'];
2115 if ($ih > $pb['bpa']['h']) {
2116 $iw = $iw * $pb['bpa']['h']/$ih;
2117 $ih = $pb['bpa']['h'];
2118 }
2119 }
2120 else if ($size['w']=='cover') {
2121 // Scale the image, while preserving its intrinsic aspect ratio (if any), to the smallest size such that both its width and its height can completely cover the background positioning area.
2122 $ih = $ih * $pb['bpa']['w']/$iw;
2123 $iw = $pb['bpa']['w'];
2124 if ($ih < $pb['bpa']['h']) {
2125 $iw = $iw * $ih/$pb['bpa']['h'];
2126 $ih = $pb['bpa']['h'];
2127 }
2128 }
2129 else {
2130 if (stristr($size['w'] ,'%')) {
2131 $size['w'] += 0;
2132 $size['w'] /= 100;
2133 $size['w'] = ($pb['bpa']['w'] * $size['w']);
2134 }
2135 if (stristr($size['h'] ,'%')) {
2136 $size['h'] += 0;
2137 $size['h'] /= 100;
2138 $size['h'] = ($pb['bpa']['h'] * $size['h']);
2139 }
2140 if ($size['w']=='auto' && $size['h']=='auto') {
2141 $iw = $iw;
2142 $ih = $ih;
2143 }
2144 else if ($size['w']=='auto' && $size['h']!='auto') {
2145 $iw = $iw * $size['h']/$ih;
2146 $ih = $size['h'];
2147 }
2148 else if ($size['w']!='auto' && $size['h']=='auto') {
2149 $ih = $ih * $size['w']/$iw;
2150 $iw = $size['w'];
2151 }
2152 else {
2153 $iw = $size['w'];
2154 $ih = $size['h'];
2155 }
2156 }
2157 }
2158
2159 // Number to repeat
2160 if ($pb['x_repeat']) { $nx = ceil($pb['w']/$iw)+1; } // mPDF 5.6.11
2161 else { $nx = 1; }
2162 if ($pb['y_repeat']) { $ny = ceil($pb['h']/$ih)+1; } // mPDF 5.6.11
2163 else { $ny = 1; }
2164
2165 $x_pos = $pb['x_pos'];
2166 if (stristr($x_pos ,'%') ) {
2167 $x_pos += 0;
2168 $x_pos /= 100;
2169 $x_pos = ($pb['bpa']['w'] * $x_pos) - ($iw * $x_pos); // mPDF 5.6.11
2170 }
2171 $y_pos = $pb['y_pos'];
2172 if (stristr($y_pos ,'%') ) {
2173 $y_pos += 0;
2174 $y_pos /= 100;
2175 $y_pos = ($pb['bpa']['h'] * $y_pos) - ($ih * $y_pos); // mPDF 5.6.11
2176 }
2177 if ($nx>1) {
2178 while($x_pos>($pb['x']-$pb['bpa']['x'])) { $x_pos -= $iw; } // mPDF 5.6.11
2179 }
2180 if ($ny>1) {
2181 while($y_pos>($pb['y']-$pb['bpa']['y'])) { $y_pos -= $ih; } // mPDF 5.6.11
2182 }
2183 for($xi=0;$xi<$nx;$xi++) {
2184 for($yi=0;$yi<$ny;$yi++) {
2185 $x = $x0 + $x_pos + ($iw*$xi);
2186 $y = $y0 + $y_pos + ($ih*$yi);
2187 if ($pb['opacity']>0 && $pb['opacity']<1) { $opac = $this->SetAlpha($pb['opacity'],'Normal',true); }
2188 else { $opac = ''; }
2189 $s .= sprintf("q %s %.3F 0 0 %.3F %.3F %.3F cm /I%d Do Q", $opac,$iw*_MPDFK,$ih*_MPDFK,$x*_MPDFK,($this->h-($y+$ih))*_MPDFK,$pb['image_id']) ."\n";
2190 }
2191 }
2192 }
2193 else {
2194 if (($pb['opacity']>0 || $pb['opacity']==='0') && $pb['opacity']<1) { $opac = $this->SetAlpha($pb['opacity'],'Normal',true); }
2195 else { $opac = ''; }
2196 $s .= sprintf('q /Pattern cs /P%d scn %s %.3F %.3F %.3F %.3F re f Q', $n, $opac, $x, $y, $w, $h) ."\n";
2197 }
2198 if (isset($pb['clippath']) && $pb['clippath']) { $s .= 'Q'."\n"; }
2199 }
2200 if ((isset($pb['gradient']) && $pb['gradient']) || (isset($pb['image_id']) && $pb['image_id'])) {
2201 if($pb['visibility']!='visible')
2202 $s .= 'EMC'."\n";
2203
2204 // mPDF 5.6.01 - LAYERS
2205 if($pb['z-index']>0) {
2206 $s .= "\n".'EMCGZ-index'."\n";
2207 $this->current_layer = 0;
2208 }
2209 }
2210
2211 }
2212 /*-- END BACKGROUNDS --*/
2213 }
2214 return $s;
2215 }
2216
2217 function PrintTableBackgrounds($adjustmenty=0) {
2218 $s = '';
2219 /*-- BACKGROUNDS --*/
2220 ksort($this->tableBackgrounds);
2221 foreach($this->tableBackgrounds AS $bl=>$pbs) {
2222 foreach ($pbs AS $pb) {
2223 if ((!isset($pb['gradient']) || !$pb['gradient']) && (!isset($pb['image_id']) || !$pb['image_id'])) {
2224 $s .= 'q '.$this->SetFColor($pb['col'], true)."\n";
2225 if ($pb['col']{0}==5) { // RGBa
2226 $s .= $this->SetAlpha(ord($pb['col']{4})/100, 'Normal', true, 'F')."\n";
2227 }
2228 else if ($pb['col']{0}==6) { // CMYKa
2229 $s .= $this->SetAlpha(ord($pb['col']{5})/100, 'Normal', true, 'F')."\n";
2230 }
2231 $s .= sprintf('%.3F %.3F %.3F %.3F re %s Q',$pb['x']*_MPDFK,($this->h-$pb['y'])*_MPDFK,$pb['w']*_MPDFK,-$pb['h']*_MPDFK,'f')."\n";
2232 }
2233 if (isset($pb['gradient']) && $pb['gradient']) {
2234 if (isset($pb['clippath']) && $pb['clippath']) { $s .= $pb['clippath']."\n"; }
2235 $s .= $this->grad->Gradient($pb['x'], $pb['y'], $pb['w'], $pb['h'], $pb['gradtype'], $pb['stops'], $pb['colorspace'], $pb['coords'], $pb['extend'], true);
2236 if (isset($pb['clippath']) && $pb['clippath']) { $s .= 'Q'."\n"; }
2237 }
2238 if (isset($pb['image_id']) && $pb['image_id']) { // Background pattern
2239 $pb['y'] -= $adjustmenty;
2240 $pb['h'] += $adjustmenty;
2241 $n = count($this->patterns)+1;
2242 list($orig_w, $orig_h, $x_repeat, $y_repeat) = $this->_resizeBackgroundImage($pb['orig_w'], $pb['orig_h'], $pb['w'], $pb['h'], $pb['resize'], $pb['x_repeat'], $pb['y_repeat']);
2243 $this->patterns[$n] = array('x'=>$pb['x'], 'y'=>$pb['y'], 'w'=>$pb['w'], 'h'=>$pb['h'], 'pgh'=>$this->h, 'image_id'=>$pb['image_id'], 'orig_w'=>$orig_w, 'orig_h'=>$orig_h, 'x_pos'=>$pb['x_pos'], 'y_pos'=>$pb['y_pos'], 'x_repeat'=>$x_repeat, 'y_repeat'=>$y_repeat, 'itype'=>$pb['itype']);
2244 $x = $pb['x']*_MPDFK;
2245 $y = ($this->h - $pb['y'])*_MPDFK;
2246 $w = $pb['w']*_MPDFK;
2247 $h = -$pb['h']*_MPDFK;
2248 if (isset($pb['clippath']) && $pb['clippath']) { $s .= $pb['clippath']."\n"; }
2249 if ($pb['opacity']>0 && $pb['opacity']<1) { $opac = $this->SetAlpha($pb['opacity'],'Normal',true); }
2250 else { $opac = ''; }
2251 $s .= sprintf('q /Pattern cs /P%d scn %s %.3F %.3F %.3F %.3F re f Q', $n, $opac, $x, $y, $w, $h) ."\n";
2252 if (isset($pb['clippath']) && $pb['clippath']) { $s .= 'Q'."\n"; }
2253 }
2254 }
2255 }
2256 /*-- END BACKGROUNDS --*/
2257 return $s;
2258 }
2259
2260 // mPDF 5.6.01 - LAYERS
2261 function BeginLayer($id) {
2262 if($this->current_layer>0) $this->EndLayer();
2263 if ($id < 1) { return false; }
2264 if (!isset($this->layers[$id])) {
2265 $this->layers[$id] = array('name'=>'Layer '.($id) );
2266 if (($this->PDFA || $this->PDFX)) { $this->PDFAXwarnings[] = "Cannot use layers when using PDFA or PDFX"; return ''; }
2267 else if (!$this->PDFA && !$this->PDFX) { $this->pdf_version='1.5'; }
2268 }
2269 $this->current_layer = $id;
2270 $this->_out('/OCZ-index /ZI'.$id.' BDC');
2271
2272 $this->pageoutput[$this->page] = array();
2273 }
2274
2275 function EndLayer() {
2276 if($this->current_layer>0) {
2277 $this->_out('EMCZ-index');
2278 $this->current_layer = 0;
2279 }
2280 }
2281
2282
2283
2284 // Depracated - can use AddPage for all
2285 function AddPages($orientation='',$condition='', $resetpagenum='', $pagenumstyle='', $suppress='',$mgl='',$mgr='',$mgt='',$mgb='',$mgh='',$mgf='',$ohname='',$ehname='',$ofname='',$efname='',$ohvalue=0,$ehvalue=0,$ofvalue=0,$efvalue=0,$pagesel='',$newformat='')
2286 {
2287 $this->AddPage($orientation,$condition,$resetpagenum, $pagenumstyle, $suppress,$mgl,$mgr,$mgt,$mgb,$mgh,$mgf, $ohname, $ehname, $ofname, $efname, $ohvalue, $ehvalue, $ofvalue, $efvalue,$pagesel,$newformat);
2288 }
2289
2290
2291 function AddPageByArray($a) {
2292 if (!is_array($a)) { $a = array(); }
2293 $orientation = (isset($a['orientation']) ? $a['orientation'] : '');
2294 $condition = (isset($a['condition']) ? $a['condition'] : (isset($a['type']) ? $a['type'] : ''));
2295 $resetpagenum = (isset($a['resetpagenum']) ? $a['resetpagenum'] : '');
2296 $pagenumstyle = (isset($a['pagenumstyle']) ? $a['pagenumstyle'] : '');
2297 $suppress = (isset($a['suppress']) ? $a['suppress'] : '');
2298 $mgl = (isset($a['mgl']) ? $a['mgl'] : (isset($a['margin-left']) ? $a['margin-left'] : ''));
2299 $mgr = (isset($a['mgr']) ? $a['mgr'] : (isset($a['margin-right']) ? $a['margin-right'] : ''));
2300 $mgt = (isset($a['mgt']) ? $a['mgt'] : (isset($a['margin-top']) ? $a['margin-top'] : ''));
2301 $mgb = (isset($a['mgb']) ? $a['mgb'] : (isset($a['margin-bottom']) ? $a['margin-bottom'] : ''));
2302 $mgh = (isset($a['mgh']) ? $a['mgh'] : (isset($a['margin-header']) ? $a['margin-header'] : ''));
2303 $mgf = (isset($a['mgf']) ? $a['mgf'] : (isset($a['margin-footer']) ? $a['margin-footer'] : ''));
2304 $ohname = (isset($a['ohname']) ? $a['ohname'] : (isset($a['odd-header-name']) ? $a['odd-header-name'] : ''));
2305 $ehname = (isset($a['ehname']) ? $a['ehname'] : (isset($a['even-header-name']) ? $a['even-header-name'] : ''));
2306 $ofname = (isset($a['ofname']) ? $a['ofname'] : (isset($a['odd-footer-name']) ? $a['odd-footer-name'] : ''));
2307 $efname = (isset($a['efname']) ? $a['efname'] : (isset($a['even-footer-name']) ? $a['even-footer-name'] : ''));
2308 $ohvalue = (isset($a['ohvalue']) ? $a['ohvalue'] : (isset($a['odd-header-value']) ? $a['odd-header-value'] : 0));
2309 $ehvalue = (isset($a['ehvalue']) ? $a['ehvalue'] : (isset($a['even-header-value']) ? $a['even-header-value'] : 0));
2310 $ofvalue = (isset($a['ofvalue']) ? $a['ofvalue'] : (isset($a['odd-footer-value']) ? $a['odd-footer-value'] : 0));
2311 $efvalue = (isset($a['efvalue']) ? $a['efvalue'] : (isset($a['even-footer-value']) ? $a['even-footer-value'] : 0));
2312 $pagesel = (isset($a['pagesel']) ? $a['pagesel'] : (isset($a['pageselector']) ? $a['pageselector'] : ''));
2313 $newformat = (isset($a['newformat']) ? $a['newformat'] : (isset($a['sheet-size']) ? $a['sheet-size'] : ''));
2314
2315 $this->AddPage($orientation,$condition,$resetpagenum, $pagenumstyle, $suppress,$mgl,$mgr,$mgt,$mgb,$mgh,$mgf, $ohname, $ehname, $ofname, $efname, $ohvalue, $ehvalue, $ofvalue, $efvalue,$pagesel,$newformat);
2316
2317 }
2318
2319
2320 function AddPage($orientation='',$condition='', $resetpagenum='', $pagenumstyle='', $suppress='',$mgl='',$mgr='',$mgt='',$mgb='',$mgh='',$mgf='',$ohname='',$ehname='',$ofname='',$efname='',$ohvalue=0,$ehvalue=0,$ofvalue=0,$efvalue=0,$pagesel='',$newformat='')
2321 {
2322 /*-- CSS-FLOAT --*/
2323 // Float DIV
2324 // Cannot do with columns on, or if any change in page orientation/margins etc.
2325 // If next page already exists - i.e background /headers and footers already written
2326 if ($this->state > 0 && $this->page < count($this->pages)) {
2327 $bak_cml = $this->cMarginL;
2328 $bak_cmr = $this->cMarginR;
2329 $bak_dw = $this->divwidth;
2330 // Paint Div Border if necessary
2331 if ($this->blklvl > 0) {
2332 $save_tr = $this->table_rotate; // *TABLES*
2333 $this->table_rotate = 0; // *TABLES*
2334 if ($this->y == $this->blk[$this->blklvl]['y0']) { $this->blk[$this->blklvl]['startpage']++; }
2335 if (($this->y > $this->blk[$this->blklvl]['y0']) || $this->flowingBlockAttr['is_table'] ) { $toplvl = $this->blklvl; }
2336 else { $toplvl = $this->blklvl-1; }
2337 $sy = $this->y;
2338 for ($bl=1;$bl<=$toplvl;$bl++) {
2339 $this->PaintDivBB('pagebottom',0,$bl);
2340 }
2341 $this->y = $sy;
2342 $this->table_rotate = $save_tr; // *TABLES*
2343 }
2344 $s = $this->PrintPageBackgrounds();
2345
2346 // Writes after the marker so not overwritten later by page background etc.
2347 $this->pages[$this->page] = preg_replace('/(___BACKGROUND___PATTERNS'.date('jY').')/', '\\1'."\n".$s."\n", $this->pages[$this->page]);
2348 $this->pageBackgrounds = array();
2349 $family=$this->FontFamily;
2350 $style=$this->FontStyle.($this->U ? 'U' : '').($this->S ? 'S' : '');
2351 $size=$this->FontSizePt;
2352 $lw=$this->LineWidth;
2353 $dc=$this->DrawColor;
2354 $fc=$this->FillColor;
2355 $tc=$this->TextColor;
2356 $cf=$this->ColorFlag;
2357
2358 $this->printfloatbuffer();
2359
2360 //Move to next page
2361 $this->page++;
2362 $this->ResetMargins();
2363 $this->SetAutoPageBreak($this->autoPageBreak,$this->bMargin);
2364 $this->x=$this->lMargin;
2365 $this->y=$this->tMargin;
2366 $this->FontFamily='';
2367 $this->_out('2 J');
2368 $this->LineWidth=$lw;
2369 $this->_out(sprintf('%.3F w',$lw*_MPDFK));
2370 if($family) $this->SetFont($family,$style,$size,true,true);
2371 $this->DrawColor=$dc;
2372 if($dc!=$this->defDrawColor) $this->_out($dc);
2373 $this->FillColor=$fc;
2374 if($fc!=$this->defFillColor) $this->_out($fc);
2375 $this->TextColor=$tc;
2376 $this->ColorFlag=$cf;
2377 for($bl=1;$bl<=$this->blklvl;$bl++) {
2378 $this->blk[$bl]['y0'] = $this->y;
2379 // Don't correct more than once for background DIV containing a Float
2380 if (!isset($this->blk[$bl]['marginCorrected'][$this->page])) { $this->blk[$bl]['x0'] += $this->MarginCorrection; }
2381 $this->blk[$bl]['marginCorrected'][$this->page] = true;
2382 }
2383 $this->cMarginL = $bak_cml;
2384 $this->cMarginR = $bak_cmr;
2385 $this->divwidth = $bak_dw;
2386 return '';
2387 }
2388 /*-- END CSS-FLOAT --*/
2389
2390 //Start a new page
2391 if($this->state==0) $this->Open();
2392
2393 $bak_cml = $this->cMarginL;
2394 $bak_cmr = $this->cMarginR;
2395 $bak_dw = $this->divwidth;
2396
2397
2398 $bak_lh = $this->lineheight;
2399
2400 $orientation = substr(strtoupper($orientation),0,1);
2401 $condition = strtoupper($condition);
2402
2403
2404 if ($condition == 'NEXT-EVEN') { // always adds at least one new page to create an Even page
2405 if (!$this->mirrorMargins) { $condition = ''; }
2406 else {
2407 if ($pagesel) { $pbch = $pagesel; $pagesel = ''; } // *CSS-PAGE*
2408 else { $pbch = false; } // *CSS-PAGE*
2409 $this->AddPage($this->CurOrientation,'O');
2410 if ($pbch ) { $pagesel = $pbch; } // *CSS-PAGE*
2411 $condition = '';
2412 }
2413 }
2414 if ($condition == 'NEXT-ODD') { // always adds at least one new page to create an Odd page
2415 if (!$this->mirrorMargins) { $condition = ''; }
2416 else {
2417 if ($pagesel) { $pbch = $pagesel; $pagesel = ''; } // *CSS-PAGE*
2418 else { $pbch = false; } // *CSS-PAGE*
2419 $this->AddPage($this->CurOrientation,'E');
2420 if ($pbch ) { $pagesel = $pbch; } // *CSS-PAGE*
2421 $condition = '';
2422 }
2423 }
2424
2425
2426 if ($condition == 'E') { // only adds new page if needed to create an Even page
2427 if (!$this->mirrorMargins || ($this->page)%2==0) { return false; }
2428 }
2429 if ($condition == 'O') { // only adds new page if needed to create an Odd page
2430 if (!$this->mirrorMargins || ($this->page)%2==1) { return false; }
2431 }
2432
2433 if ($resetpagenum || $pagenumstyle || $suppress) {
2434 $this->PageNumSubstitutions[] = array('from'=>($this->page+1), 'reset'=> $resetpagenum, 'type'=>$pagenumstyle, 'suppress'=>$suppress);
2435 }
2436
2437
2438 $save_tr = $this->table_rotate; // *TABLES*
2439 $this->table_rotate = 0; // *TABLES*
2440 $save_kwt = $this->kwt;
2441 $this->kwt = 0;
2442 // mPDF 5.6.01 - LAYERS
2443 $save_layer = $this->current_layer;
2444 $save_vis = $this->visibility;
2445
2446 if($this->visibility!='visible')
2447 $this->SetVisibility('visible');
2448 // mPDF 5.6.01 - LAYERS
2449 $this->EndLayer();
2450
2451 // Paint Div Border if necessary
2452 //PAINTS BACKGROUND COLOUR OR BORDERS for DIV - DISABLED FOR COLUMNS (cf. AcceptPageBreak) AT PRESENT in ->PaintDivBB
2453 if (!$this->ColActive && $this->blklvl > 0) {
2454 if (isset($this->blk[$this->blklvl]['y0']) && $this->y == $this->blk[$this->blklvl]['y0']) {
2455 if (isset($this->blk[$this->blklvl]['startpage'])) { $this->blk[$this->blklvl]['startpage']++; }
2456 else { $this->blk[$this->blklvl]['startpage'] = 1; }
2457 }
2458 if ((isset($this->blk[$this->blklvl]['y0']) && $this->y > $this->blk[$this->blklvl]['y0']) || $this->flowingBlockAttr['is_table'] ) { $toplvl = $this->blklvl; }
2459 else { $toplvl = $this->blklvl-1; }
2460 $sy = $this->y;
2461 for ($bl=1;$bl<=$toplvl;$bl++) {
2462
2463 // mPDF 5.6.01 - LAYERS
2464 if ($this->blk[$bl]['z-index']>0) {
2465 $this->BeginLayer($this->blk[$bl]['z-index']);
2466 }
2467 if (isset($this->blk[$bl]['visibility']) && $this->blk[$bl]['visibility'] && $this->blk[$bl]['visibility']!='visible') {
2468 $this->SetVisibility($this->blk[$bl]['visibility']);
2469 }
2470
2471 $this->PaintDivBB('pagebottom',0,$bl);
2472 }
2473 $this->y = $sy;
2474 // RESET block y0 and x0 - see below
2475 }
2476
2477 if($this->visibility!='visible')
2478 $this->SetVisibility('visible');
2479 // mPDF 5.6.01 - LAYERS
2480 $this->EndLayer();
2481
2482 // BODY Backgrounds
2483 if ($this->page > 0) {
2484 $s = '';
2485 $s .= $this->PrintBodyBackgrounds();
2486
2487 $s .= $this->PrintPageBackgrounds();
2488 $this->pages[$this->page] = preg_replace('/(___BACKGROUND___PATTERNS'.date('jY').')/', "\n".$s."\n".'\\1', $this->pages[$this->page]);
2489 $this->pageBackgrounds = array();
2490 }
2491
2492 $save_kt = $this->keep_block_together;
2493 $this->keep_block_together = 0;
2494
2495 $save_cols = false;
2496 /*-- COLUMNS --*/
2497 if ($this->ColActive) {
2498 $save_cols = true;
2499 $save_nbcol = $this->NbCol; // other values of gap and vAlign will not change by setting Columns off
2500 $this->SetColumns(0);
2501 }
2502 /*-- END COLUMNS --*/
2503
2504
2505 $family=$this->FontFamily;
2506 $style=$this->FontStyle.($this->U ? 'U' : '').($this->S ? 'S' : '');
2507 $size=$this->FontSizePt;
2508 $this->ColumnAdjust = true; // enables column height adjustment for the page
2509 $lw=$this->LineWidth;
2510 $dc=$this->DrawColor;
2511 $fc=$this->FillColor;
2512 $tc=$this->TextColor;
2513 $cf=$this->ColorFlag;
2514 if($this->page>0)
2515 {
2516 //Page footer
2517 $this->InFooter=true;
2518
2519 $this->Reset();
2520 $this->pageoutput[$this->page] = array();
2521
2522 $this->Footer();
2523 //Close page
2524 $this->_endpage();
2525 }
2526
2527
2528 //Start new page
2529 $this->_beginpage($orientation,$mgl,$mgr,$mgt,$mgb,$mgh,$mgf,$ohname,$ehname,$ofname,$efname,$ohvalue,$ehvalue,$ofvalue,$efvalue,$pagesel,$newformat);
2530 if ($this->docTemplate) {
2531 $pagecount = $this->SetSourceFile($this->docTemplate);
2532 if (($this->page - $this->docTemplateStart) > $pagecount) {
2533 if ($this->docTemplateContinue) {
2534 $tplIdx = $this->ImportPage($pagecount);
2535 $this->UseTemplate($tplIdx);
2536 }
2537 }
2538 else {
2539 $tplIdx = $this->ImportPage(($this->page - $this->docTemplateStart));
2540 $this->UseTemplate($tplIdx);
2541 }
2542 }
2543 if ($this->pageTemplate) {
2544 $this->UseTemplate($this->pageTemplate);
2545 }
2546
2547 // Tiling Patterns
2548 $this->_out('___PAGE___START'.date('jY'));
2549 $this->_out('___BACKGROUND___PATTERNS'.date('jY'));
2550 $this->_out('___HEADER___MARKER'.date('jY'));
2551 $this->pageBackgrounds = array();
2552
2553 //Set line cap style to square
2554 $this->SetLineCap(2);
2555 //Set line width
2556 $this->LineWidth=$lw;
2557 $this->_out(sprintf('%.3F w',$lw*_MPDFK));
2558 //Set font
2559 if($family) $this->SetFont($family,$style,$size,true,true); // forces write
2560 //Set colors
2561 $this->DrawColor=$dc;
2562 if($dc!=$this->defDrawColor) $this->_out($dc);
2563 $this->FillColor=$fc;
2564 if($fc!=$this->defFillColor) $this->_out($fc);
2565 $this->TextColor=$tc;
2566 $this->ColorFlag=$cf;
2567
2568 //Page header
2569 $this->Header();
2570
2571 //Restore line width
2572 if($this->LineWidth!=$lw)
2573 {
2574 $this->LineWidth=$lw;
2575 $this->_out(sprintf('%.3F w',$lw*_MPDFK));
2576 }
2577 //Restore font
2578 if($family) $this->SetFont($family,$style,$size,true,true); // forces write
2579 //Restore colors
2580 if($this->DrawColor!=$dc)
2581 {
2582 $this->DrawColor=$dc;
2583 $this->_out($dc);
2584 }
2585 if($this->FillColor!=$fc)
2586 {
2587 $this->FillColor=$fc;
2588 $this->_out($fc);
2589 }
2590 $this->TextColor=$tc;
2591 $this->ColorFlag=$cf;
2592 $this->InFooter=false;
2593
2594 // mPDF 5.6.01 - LAYERS
2595 if ($save_layer>0)
2596 $this->BeginLayer($save_layer);
2597
2598 if($save_vis!='visible')
2599 $this->SetVisibility($save_vis);
2600
2601 /*-- COLUMNS --*/
2602 if ($save_cols) {
2603 // Restore columns
2604 $this->SetColumns($save_nbcol,$this->colvAlign,$this->ColGap);
2605 }
2606 if ($this->ColActive) { $this->SetCol(0); }
2607 /*-- END COLUMNS --*/
2608
2609
2610 //RESET BLOCK BORDER TOP
2611 if (!$this->ColActive) {
2612 for($bl=1;$bl<=$this->blklvl;$bl++) {
2613 $this->blk[$bl]['y0'] = $this->y;
2614 if (isset($this->blk[$bl]['x0'])) { $this->blk[$bl]['x0'] += $this->MarginCorrection; }
2615 else { $this->blk[$bl]['x0'] = $this->MarginCorrection; }
2616 // Added mPDF 3.0 Float DIV
2617 $this->blk[$bl]['marginCorrected'][$this->page] = true;
2618 }
2619 }
2620
2621
2622 $this->table_rotate = $save_tr; // *TABLES*
2623 $this->kwt = $save_kwt;
2624
2625 $this->keep_block_together = $save_kt ;
2626
2627 $this->cMarginL = $bak_cml;
2628 $this->cMarginR = $bak_cmr;
2629 $this->divwidth = $bak_dw;
2630
2631 $this->lineheight = $bak_lh;
2632 }
2633
2634
2635 function PageNo() {
2636 //Get current page number
2637 return $this->page;
2638 }
2639
2640 function AddSpotColorsFromFile($file) {
2641 $colors = @file($file) or die("Cannot load spot colors file - ".$file);
2642 foreach($colors AS $sc) {
2643 list($name, $c, $m, $y, $k) = preg_split("/\t/",$sc);
2644 $c = intval($c);
2645 $m = intval($m);
2646 $y = intval($y);
2647 $k = intval($k);
2648 $this->AddSpotColor($name, $c, $m, $y, $k);
2649 }
2650 }
2651
2652 function AddSpotColor($name, $c, $m, $y, $k) {
2653 $name = strtoupper(trim($name));
2654 if(!isset($this->spotColors[$name])) {
2655 $i=count($this->spotColors)+1;
2656 $this->spotColors[$name]=array('i'=>$i,'c'=>$c,'m'=>$m,'y'=>$y,'k'=>$k);
2657 $this->spotColorIDs[$i]=$name;
2658 }
2659 }
2660
2661 function SetColor($col, $type='') {
2662 $out = '';
2663 if ($col{0}==3 || $col{0}==5) { // RGB / RGBa
2664 $out = sprintf('%.3F %.3F %.3F rg',ord($col{1})/255,ord($col{2})/255,ord($col{3})/255);
2665 }
2666 else if ($col{0}==1) { // GRAYSCALE
2667 $out = sprintf('%.3F g',ord($col{1})/255);
2668 }
2669 else if ($col{0}==2) { // SPOT COLOR
2670 $out = sprintf('/CS%d cs %.3F scn',ord($col{1}),ord($col{2})/100);
2671 }
2672 else if ($col{0}==4 || $col{0}==6) { // CMYK / CMYKa
2673 $out = sprintf('%.3F %.3F %.3F %.3F k', ord($col{1})/100, ord($col{2})/100, ord($col{3})/100, ord($col{4})/100);
2674 }
2675 if ($type=='Draw') { $out = strtoupper($out); } // e.g. rg => RG
2676 else if ($type=='CodeOnly') { $out = preg_replace('/\s(rg|g|k)/','',$out); }
2677 return $out;
2678 }
2679
2680
2681 function SetDColor($col, $return=false) {
2682 $out = $this->SetColor($col, 'Draw');
2683 if ($return) { return $out; }
2684 if ($out=='') { return ''; }
2685 $this->DrawColor = $out;
2686 if($this->page>0 && ((isset($this->pageoutput[$this->page]['DrawColor']) && $this->pageoutput[$this->page]['DrawColor'] != $this->DrawColor) || !isset($this->pageoutput[$this->page]['DrawColor']) || $this->keep_block_together)) { $this->_out($this->DrawColor); }
2687 $this->pageoutput[$this->page]['DrawColor'] = $this->DrawColor;
2688 }
2689
2690 function SetFColor($col, $return=false) {
2691 $out = $this->SetColor($col, 'Fill');
2692 if ($return) { return $out; }
2693 if ($out=='') { return ''; }
2694 $this->FillColor = $out;
2695 $this->ColorFlag = ($out != $this->TextColor);
2696 if($this->page>0 && ((isset($this->pageoutput[$this->page]['FillColor']) && $this->pageoutput[$this->page]['FillColor'] != $this->FillColor) || !isset($this->pageoutput[$this->page]['FillColor']) || $this->keep_block_together)) { $this->_out($this->FillColor); }
2697 $this->pageoutput[$this->page]['FillColor'] = $this->FillColor;
2698 }
2699
2700 function SetTColor($col, $return=false) {
2701 $out = $this->SetColor($col, 'Text');
2702 if ($return) { return $out; }
2703 if ($out=='') { return ''; }
2704 $this->TextColor = $out;
2705 $this->ColorFlag = ($this->FillColor != $out);
2706 }
2707
2708
2709 function SetDrawColor($r,$g=-1,$b=-1,$col4=-1, $return=false) {
2710 //Set color for all stroking operations
2711 $col = array();
2712 if(($r==0 and $g==0 and $b==0 && $col4 == -1) or $g==-1) { $col = $this->ConvertColor($r); }
2713 else if ($col4 == -1) { $col = $this->ConvertColor('rgb('.$r.','.$g.','.$b.')'); }
2714 else { $col = $this->ConvertColor('cmyk('.$r.','.$g.','.$b.','.$col4.')'); }
2715 $out = $this->SetDColor($col, $return);
2716 return $out;
2717 }
2718
2719 function SetFillColor($r,$g=-1,$b=-1,$col4=-1, $return=false) {
2720 //Set color for all filling operations
2721 $col = array();
2722 if(($r==0 and $g==0 and $b==0 && $col4 == -1) or $g==-1) { $col = $this->ConvertColor($r); }
2723 else if ($col4 == -1) { $col = $this->ConvertColor('rgb('.$r.','.$g.','.$b.')'); }
2724 else { $col = $this->ConvertColor('cmyk('.$r.','.$g.','.$b.','.$col4.')'); }
2725 $out = $this->SetFColor($col, $return);
2726 return $out;
2727 }
2728
2729 function SetTextColor($r,$g=-1,$b=-1,$col4=-1, $return=false) {
2730 //Set color for text
2731 $col = array();
2732 if(($r==0 and $g==0 and $b==0 && $col4 == -1) or $g==-1) { $col = $this->ConvertColor($r); }
2733 else if ($col4 == -1) { $col = $this->ConvertColor('rgb('.$r.','.$g.','.$b.')'); }
2734 else { $col = $this->ConvertColor('cmyk('.$r.','.$g.','.$b.','.$col4.')'); }
2735 $out = $this->SetTColor($col, $return);
2736 return $out;
2737 }
2738
2739 function _getCharWidth(&$cw, $u, $isdef=true) {
2740 if ($u==0) { $w = false; }
2741 else { $w = (ord($cw[$u*2]) << 8) + ord($cw[$u*2+1]); }
2742 if ($w == 65535) { return 0; }
2743 else if ($w) { return $w; }
2744 else if ($isdef) { return false; }
2745 else { return 0; }
2746 }
2747
2748 function _charDefined(&$cw, $u) {
2749 if ($u==0) { return false; }
2750 $w = (ord($cw[$u*2]) << 8) + ord($cw[$u*2+1]);
2751 if ($w) { return true; }
2752 else { return false; }
2753 }
2754
2755 function GetCharWidthCore($c) {
2756 //Get width of a single character in the current Core font
2757 $c = (string)$c;
2758 $w = 0;
2759 // Soft Hyphens chr(173)
2760 if ($c == chr(173) && $this->FontFamily!='csymbol' && $this->FontFamily!='czapfdingbats') {
2761 return 0;
2762 }
2763 else if ($this->S && isset($this->upperCase[ord($c)])) {
2764 $charw = $this->CurrentFont['cw'][chr($this->upperCase[ord($c)])];
2765 if ($charw!==false) {
2766 $charw = $charw*$this->smCapsScale * $this->smCapsStretch/100;
2767 $w+=$charw;
2768 }
2769 }
2770 else if (isset($this->CurrentFont['cw'][$c])) {
2771 $w += $this->CurrentFont['cw'][$c];
2772 }
2773 else if (isset($this->CurrentFont['cw'][ord($c)])) {
2774 $w += $this->CurrentFont['cw'][ord($c)];
2775 }
2776 $w *= ($this->FontSize/ 1000);
2777 if ($this->minwSpacing || $this->fixedlSpacing) {
2778 if ($c==' ') $nb_spaces = 1;
2779 else $nb_spaces = 0;
2780 $w += $this->fixedlSpacing + ($nb_spaces * $this->minwSpacing);
2781 }
2782 return ($w);
2783 }
2784
2785 function GetCharWidthNonCore($c, $addSubset=true) {
2786 //Get width of a single character in the current Non-Core font
2787 $c = (string)$c;
2788 $w = 0;
2789 $unicode = $this->UTF8StringToArray($c, $addSubset);
2790 $char = $unicode[0];
2791 /*-- CJK-FONTS --*/
2792 if ($this->CurrentFont['type'] == 'Type0') { // CJK Adobe fonts
2793 if ($char == 173) { return 0; } // Soft Hyphens
2794 elseif (isset($this->CurrentFont['cw'][$char])) { $w+=$this->CurrentFont['cw'][$char]; }
2795 elseif(isset($this->CurrentFont['MissingWidth'])) { $w += $this->CurrentFont['MissingWidth']; }
2796 else { $w += 500; }
2797 }
2798 else {
2799 /*-- END CJK-FONTS --*/
2800 if ($char == 173) { return 0; } // Soft Hyphens
2801 else if ($this->S && isset($this->upperCase[$char])) {
2802 $charw = $this->_getCharWidth($this->CurrentFont['cw'],$this->upperCase[$char]);
2803 if ($charw!==false) {
2804 $charw = $charw*$this->smCapsScale * $this->smCapsStretch/100;
2805 $w+=$charw;
2806 }
2807 elseif(isset($this->CurrentFont['desc']['MissingWidth'])) { $w += $this->CurrentFont['desc']['MissingWidth']; }
2808 elseif(isset($this->CurrentFont['MissingWidth'])) { $w += $this->CurrentFont['MissingWidth']; }
2809 else { $w += 500; }
2810 }
2811 else {
2812 $charw = $this->_getCharWidth($this->CurrentFont['cw'],$char);
2813 if ($charw!==false) { $w+=$charw; }
2814 elseif(isset($this->CurrentFont['desc']['MissingWidth'])) { $w += $this->CurrentFont['desc']['MissingWidth']; }
2815 elseif(isset($this->CurrentFont['MissingWidth'])) { $w += $this->CurrentFont['MissingWidth']; }
2816 else { $w += 500; }
2817 }
2818 } // *CJK-FONTS*
2819 $w *= ($this->FontSize/ 1000);
2820 if ($this->minwSpacing || $this->fixedlSpacing) {
2821 if ($c==' ') $nb_spaces = 1;
2822 else $nb_spaces = 0;
2823 $w += $this->fixedlSpacing + ($nb_spaces * $this->minwSpacing);
2824 }
2825 return ($w);
2826 }
2827
2828
2829 function GetCharWidth($c, $addSubset=true) {
2830 if (!$this->usingCoreFont) {
2831 return $this->GetCharWidthNonCore($c, $addSubset);
2832 }
2833 else {
2834 return $this->GetCharWidthCore($c);
2835 }
2836 }
2837
2838 function GetStringWidth($s, $addSubset=true) {
2839 //Get width of a string in the current font
2840 $s = (string)$s;
2841 $cw = &$this->CurrentFont['cw'];
2842 $w = 0;
2843 $kerning = 0;
2844 $lastchar = 0;
2845 $nb_carac = 0;
2846 $nb_spaces = 0;
2847 // mPDF ITERATION
2848 if ($this->iterationCounter) $s = preg_replace('/{iteration ([a-zA-Z0-9_]+)}/', '\\1', $s);
2849
2850 if (!$this->usingCoreFont) {
2851 $s = str_replace("\xc2\xad",'',$s );
2852 $unicode = $this->UTF8StringToArray($s, $addSubset);
2853 if ($this->minwSpacing || $this->fixedlSpacing) {
2854 $nb_carac = count($unicode);
2855 $nb_spaces = mb_substr_count($s,' ', $this->mb_enc);
2856 }
2857 /*-- CJK-FONTS --*/
2858 if ($this->CurrentFont['type'] == 'Type0') { // CJK Adobe fonts
2859 foreach($unicode as $char) {
2860 if (isset($cw[$char])) { $w+=$cw[$char]; }
2861 elseif(isset($this->CurrentFont['MissingWidth'])) { $w += $this->CurrentFont['MissingWidth']; }
2862 else { $w += 500; }
2863 }
2864 }
2865 else {
2866 /*-- END CJK-FONTS --*/
2867 foreach($unicode as $char) {
2868 if ($this->S && isset($this->upperCase[$char])) {
2869 $charw = $this->_getCharWidth($cw,$this->upperCase[$char]);
2870 if ($charw!==false) {
2871 $charw = $charw*$this->smCapsScale * $this->smCapsStretch/100;
2872 $w+=$charw;
2873 }
2874 elseif(isset($this->CurrentFont['desc']['MissingWidth'])) { $w += $this->CurrentFont['desc']['MissingWidth']; }
2875 elseif(isset($this->CurrentFont['MissingWidth'])) { $w += $this->CurrentFont['MissingWidth']; }
2876 else { $w += 500; }
2877 }
2878 else {
2879 $charw = $this->_getCharWidth($cw,$char);
2880 if ($charw!==false) { $w+=$charw; }
2881 elseif(isset($this->CurrentFont['desc']['MissingWidth'])) { $w += $this->CurrentFont['desc']['MissingWidth']; }
2882 elseif(isset($this->CurrentFont['MissingWidth'])) { $w += $this->CurrentFont['MissingWidth']; }
2883 else { $w += 500; }
2884 if ($this->kerning && $this->useKerning && $lastchar) {
2885 if (isset($this->CurrentFont['kerninfo'][$lastchar][$char])) {
2886 $kerning += $this->CurrentFont['kerninfo'][$lastchar][$char];
2887 }
2888 }
2889 $lastchar = $char;
2890 }
2891 }
2892 } // *CJK-FONTS*
2893
2894 }
2895 else {
2896 if ($this->FontFamily!='csymbol' && $this->FontFamily!='czapfdingbats') {
2897 $s = str_replace(chr(173),'',$s );
2898 }
2899 $nb_carac = $l = strlen($s);
2900 if ($this->minwSpacing || $this->fixedlSpacing) {
2901 $nb_spaces = substr_count($s,' ');
2902 }
2903 for($i=0; $i<$l; $i++) {
2904 if ($this->S && isset($this->upperCase[ord($s[$i])])) {
2905 $charw = $cw[chr($this->upperCase[ord($s[$i])])];
2906 if ($charw!==false) {
2907 $charw = $charw*$this->smCapsScale * $this->smCapsStretch/100;
2908 $w+=$charw;
2909 }
2910 }
2911 else if (isset($cw[$s[$i]])) {
2912 $w += $cw[$s[$i]];
2913 }
2914 else if (isset($cw[ord($s[$i])])) {
2915 $w += $cw[ord($s[$i])];
2916 }
2917 if ($this->kerning && $this->useKerning && $i>0) {
2918 if (isset($this->CurrentFont['kerninfo'][$s[($i-1)]][$s[$i]])) {
2919 $kerning += $this->CurrentFont['kerninfo'][$s[($i-1)]][$s[$i]];
2920 }
2921 }
2922 }
2923 }
2924 unset($cw);
2925 if ($this->kerning && $this->useKerning) { $w += $kerning; }
2926 $w *= ($this->FontSize/ 1000);
2927 $w += (($nb_carac + $nb_spaces) * $this->fixedlSpacing) + ($nb_spaces * $this->minwSpacing);
2928 return ($w);
2929 }
2930
2931 function SetLineWidth($width) {
2932 //Set line width
2933 $this->LineWidth=$width;
2934 $lwout = (sprintf('%.3F w',$width*_MPDFK));
2935 if($this->page>0 && ((isset($this->pageoutput[$this->page]['LineWidth']) && $this->pageoutput[$this->page]['LineWidth'] != $lwout) || !isset($this->pageoutput[$this->page]['LineWidth']) || $this->keep_block_together)) {
2936 $this->_out($lwout);
2937 }
2938 $this->pageoutput[$this->page]['LineWidth'] = $lwout;
2939 }
2940
2941 function Line($x1,$y1,$x2,$y2) {
2942 //Draw a line
2943 $this->_out(sprintf('%.3F %.3F m %.3F %.3F l S',$x1*_MPDFK,($this->h-$y1)*_MPDFK,$x2*_MPDFK,($this->h-$y2)*_MPDFK));
2944 }
2945
2946 function Arrow($x1,$y1,$x2,$y2,$headsize=3,$fill='B',$angle=25) {
2947 //F == fill //S == stroke //B == stroke and fill
2948 // angle = splay of arrowhead - 1 - 89 degrees
2949 if($fill=='F') $fill='f';
2950 elseif($fill=='FD' or $fill=='DF' or $fill=='B') $fill='B';
2951 else $fill='S';
2952 $a = atan2(($y2-$y1),($x2-$x1));
2953 $b = $a + deg2rad($angle);
2954 $c = $a - deg2rad($angle);
2955 $x3 = $x2 - ($headsize* cos($b));
2956 $y3 = $this->h-($y2 - ($headsize* sin($b)));
2957 $x4 = $x2 - ($headsize* cos($c));
2958 $y4 = $this->h-($y2 - ($headsize* sin($c)));
2959
2960 $x5 = $x3-($x3-$x4)/2; // mid point of base of arrowhead - to join arrow line to
2961 $y5 = $y3-($y3-$y4)/2;
2962
2963 $s = '';
2964 $s.=sprintf('%.3F %.3F m %.3F %.3F l S',$x1*_MPDFK,($this->h-$y1)*_MPDFK,$x5*_MPDFK,$y5*_MPDFK);
2965 $this->_out($s);
2966
2967 $s = '';
2968 $s.=sprintf('%.3F %.3F m %.3F %.3F l %.3F %.3F l %.3F %.3F l %.3F %.3F l ',$x5*_MPDFK,$y5*_MPDFK,$x3*_MPDFK,$y3*_MPDFK,$x2*_MPDFK,($this->h-$y2)*_MPDFK,$x4*_MPDFK,$y4*_MPDFK,$x5*_MPDFK,$y5*_MPDFK);
2969 $s.=$fill;
2970 $this->_out($s);
2971 }
2972
2973
2974 function Rect($x,$y,$w,$h,$style='') {
2975 //Draw a rectangle
2976 if($style=='F') $op='f';
2977 elseif($style=='FD' or $style=='DF') $op='B';
2978 else $op='S';
2979 $this->_out(sprintf('%.3F %.3F %.3F %.3F re %s',$x*_MPDFK,($this->h-$y)*_MPDFK,$w*_MPDFK,-$h*_MPDFK,$op));
2980 }
2981
2982 function AddFont($family,$style='') {
2983 if(empty($family)) { return; }
2984 $family = strtolower($family);
2985 $style=strtoupper($style);
2986 $style=str_replace('U','',$style);
2987 if($style=='IB') $style='BI';
2988 $fontkey = $family.$style;
2989 // check if the font has been already added
2990 if(isset($this->fonts[$fontkey])) {
2991 return;
2992 }
2993
2994 /*-- CJK-FONTS --*/
2995 if (in_array($family,$this->available_CJK_fonts)) {
2996 if (empty($this->Big5_widths)) { require(_MPDF_PATH . 'includes/CJKdata.php'); }
2997 $this->AddCJKFont($family); // don't need to add style
2998 return;
2999 }
3000 /*-- END CJK-FONTS --*/
3001
3002 if ($this->usingCoreFont) { die("mPDF Error - problem with Font management"); }
3003
3004 $stylekey = $style;
3005 if (!$style) { $stylekey = 'R'; }
3006
3007 if (!isset($this->fontdata[$family][$stylekey]) || !$this->fontdata[$family][$stylekey]) {
3008 die('mPDF Error - Font is not supported - '.$family.' '.$style);
3009 }
3010
3011 $name = '';
3012 $originalsize = 0;
3013 $sip = false;
3014 $smp = false;
3015 $unAGlyphs = false; // mPDF 5.4.05
3016 $haskerninfo = false;
3017 $BMPselected = false;
3018 @include(_MPDF_TTFONTDATAPATH.$fontkey.'.mtx.php');
3019
3020 $ttffile = '';
3021 if (defined('_MPDF_SYSTEM_TTFONTS')) {
3022 $ttffile = _MPDF_SYSTEM_TTFONTS.$this->fontdata[$family][$stylekey];
3023 if (!file_exists($ttffile)) { $ttffile = ''; }
3024 }
3025 if (!$ttffile) {
3026 $ttffile = _MPDF_TTFONTPATH.$this->fontdata[$family][$stylekey];
3027 if (!file_exists($ttffile)) { die("mPDF Error - cannot find TTF TrueType font file - ".$ttffile); }
3028 }
3029 $ttfstat = stat($ttffile);
3030
3031 if (isset($this->fontdata[$family]['TTCfontID'][$stylekey])) { $TTCfontID = $this->fontdata[$family]['TTCfontID'][$stylekey]; }
3032 else { $TTCfontID = 0; }
3033
3034
3035 $BMPonly = false;
3036 if (in_array($family,$this->BMPonly)) { $BMPonly = true; }
3037 $regenerate = false;
3038 if ($BMPonly && !$BMPselected) { $regenerate = true; }
3039 else if (!$BMPonly && $BMPselected) { $regenerate = true; }
3040 if ($this->useKerning && !$haskerninfo) { $regenerate = true; }
3041 // mPDF 5.4.05
3042 if (isset($this->fontdata[$family]['unAGlyphs']) && $this->fontdata[$family]['unAGlyphs'] && !$unAGlyphs) {
3043 $regenerate = true;
3044 $unAGlyphs = true;
3045 }
3046 else if ((!isset($this->fontdata[$family]['unAGlyphs']) || !$this->fontdata[$family]['unAGlyphs']) && $unAGlyphs) {
3047 $regenerate = true;
3048 $unAGlyphs = false;
3049 }
3050 if (!isset($name) || $originalsize != $ttfstat['size'] || $regenerate) {
3051 if (!class_exists('TTFontFile', false)) { include(_MPDF_PATH .'classes/ttfontsuni.php'); }
3052 $ttf = new TTFontFile();
3053 $ttf->getMetrics($ttffile, $TTCfontID, $this->debugfonts, $BMPonly, $this->useKerning, $unAGlyphs); // mPDF 5.4.05
3054 $cw = $ttf->charWidths;
3055 $kerninfo = $ttf->kerninfo;
3056 $haskerninfo = true;
3057 $name = preg_replace('/[ ()]/','',$ttf->fullName);
3058 $sip = $ttf->sipset;
3059 $smp = $ttf->smpset;
3060
3061 $desc= array('Ascent'=>round($ttf->ascent),
3062 'Descent'=>round($ttf->descent),
3063 'CapHeight'=>round($ttf->capHeight),
3064 'Flags'=>$ttf->flags,
3065 'FontBBox'=>'['.round($ttf->bbox[0])." ".round($ttf->bbox[1])." ".round($ttf->bbox[2])." ".round($ttf->bbox[3]).']',
3066 'ItalicAngle'=>$ttf->italicAngle,
3067 'StemV'=>round($ttf->stemV),
3068 'MissingWidth'=>round($ttf->defaultWidth));
3069 $panose = '';
3070 // mPDF 5.5.19
3071 if (count($ttf->panose)) {
3072 $panoseArray = array_merge(array($ttf->sFamilyClass, $ttf->sFamilySubClass), $ttf->panose);
3073 foreach($panoseArray as $value)
3074 $panose .= ' '.dechex($value);
3075 }
3076 $up = round($ttf->underlinePosition);
3077 $ut = round($ttf->underlineThickness);
3078 $originalsize = $ttfstat['size']+0;
3079 $type = 'TTF';
3080 //Generate metrics .php file
3081 $s='<?php'."\n";
3082 $s.='$name=\''.$name."';\n";
3083 $s.='$type=\''.$type."';\n";
3084 $s.='$desc='.var_export($desc,true).";\n";
3085 $s.='$up='.$up.";\n";
3086 $s.='$ut='.$ut.";\n";
3087 $s.='$ttffile=\''.$ttffile."';\n";
3088 $s.='$TTCfontID=\''.$TTCfontID."';\n";
3089 $s.='$originalsize='.$originalsize.";\n";
3090 if ($sip) $s.='$sip=true;'."\n";
3091 else $s.='$sip=false;'."\n";
3092 if ($smp) $s.='$smp=true;'."\n";
3093 else $s.='$smp=false;'."\n";
3094 if ($BMPonly) $s.='$BMPselected=true;'."\n";
3095 else $s.='$BMPselected=false;'."\n";
3096 $s.='$fontkey=\''.$fontkey."';\n";
3097 $s.='$panose=\''.$panose."';\n";
3098 if ($this->useKerning) {
3099 $s.='$kerninfo='.var_export($kerninfo,true).";\n";
3100 $s.='$haskerninfo=true;'."\n";
3101 }
3102 else $s.='$haskerninfo=false;'."\n";
3103 // mPDF 5.4.05
3104 if ($this->fontdata[$family]['unAGlyphs']) {
3105 $s.='$unAGlyphs=true;'."\n";
3106 }
3107 else $s.='$unAGlyphs=false;'."\n";
3108 $s.="?>";
3109 if (is_writable(dirname(_MPDF_TTFONTDATAPATH.'x'))) {
3110 $fh = fopen(_MPDF_TTFONTDATAPATH.$fontkey.'.mtx.php',"w");
3111 fwrite($fh,$s,strlen($s));
3112 fclose($fh);
3113 $fh = fopen(_MPDF_TTFONTDATAPATH.$fontkey.'.cw.dat',"wb");
3114 fwrite($fh,$cw,strlen($cw));
3115 fclose($fh);
3116 @unlink(_MPDF_TTFONTDATAPATH.$fontkey.'.cgm');
3117 @unlink(_MPDF_TTFONTDATAPATH.$fontkey.'.z');
3118 @unlink(_MPDF_TTFONTDATAPATH.$fontkey.'.cw127.php');
3119 @unlink(_MPDF_TTFONTDATAPATH.$fontkey.'.cw');
3120 }
3121 else if ($this->debugfonts) { $this->Error('Cannot write to the font caching directory - '._MPDF_TTFONTDATAPATH); }
3122 unset($ttf);
3123 }
3124 else {
3125 $cw = @file_get_contents(_MPDF_TTFONTDATAPATH.$fontkey.'.cw.dat');
3126 }
3127
3128 if (isset($this->fontdata[$family]['indic']) && $this->fontdata[$family]['indic']) { $indic = true; }
3129 else { $indic = false; }
3130 if (isset($this->fontdata[$family]['sip-ext']) && $this->fontdata[$family]['sip-ext']) { $sipext = $this->fontdata[$family]['sip-ext']; }
3131 else { $sipext = ''; }
3132
3133
3134 $i = count($this->fonts)+$this->extraFontSubsets+1;
3135 if ($sip || $smp) {
3136 $this->fonts[$fontkey] = array('i'=>$i, 'type'=>$type, 'name'=>$name, 'desc'=>$desc, 'panose'=>$panose, 'up'=>$up, 'ut'=>$ut, 'cw'=>$cw, 'ttffile'=>$ttffile, 'fontkey'=>$fontkey, 'subsets'=>array(0=>range(0,127)), 'subsetfontids'=>array($i), 'used'=>false, 'indic'=>$indic, 'sip'=>$sip, 'sipext'=>$sipext, 'smp'=>$smp, 'TTCfontID' => $TTCfontID, 'unAGlyphs' => false); // mPDF 5.4.05
3137 }
3138 else {
3139 $ss = array();
3140 for ($s=32; $s<128; $s++) { $ss[$s] = $s; }
3141 $this->fonts[$fontkey] = array('i'=>$i, 'type'=>$type, 'name'=>$name, 'desc'=>$desc, 'panose'=>$panose, 'up'=>$up, 'ut'=>$ut, 'cw'=>$cw, 'ttffile'=>$ttffile, 'fontkey'=>$fontkey, 'subset'=>$ss, 'used'=>false, 'indic'=>$indic, 'sip'=>$sip, 'sipext'=>$sipext, 'smp'=>$smp, 'TTCfontID' => $TTCfontID, 'unAGlyphs' => $unAGlyphs); // mPDF 5.4.05
3142 }
3143 if ($this->useKerning && $haskerninfo) { $this->fonts[$fontkey]['kerninfo'] = $kerninfo; }
3144 $this->FontFiles[$fontkey]=array('length1'=>$originalsize, 'type'=>"TTF", 'ttffile'=>$ttffile, 'sip'=>$sip, 'smp'=>$smp);
3145 unset($cw);
3146 }
3147
3148
3149
3150 function SetFont($family,$style='',$size=0, $write=true, $forcewrite=false) {
3151 $family=strtolower($family);
3152 if (!$this->onlyCoreFonts) {
3153 if ($family == 'sans' || $family == 'sans-serif') { $family = $this->sans_fonts[0]; }
3154 if ($family == 'serif') { $family = $this->serif_fonts[0]; }
3155 if ($family == 'mono' || $family == 'monospace') { $family = $this->mono_fonts[0]; }
3156 }
3157 if (isset($this->fonttrans[$family]) && $this->fonttrans[$family]) { $family = $this->fonttrans[$family]; }
3158 if($family=='') {
3159 if ($this->FontFamily) { $family=$this->FontFamily; }
3160 else if ($this->default_font) { $family=$this->default_font; }
3161 else { $this->Error("No font or default font set!"); }
3162 }
3163 $this->ReqFontStyle = $style; // required or requested style - used later for artificial bold/italic
3164
3165 if (($family == 'csymbol') || ($family == 'czapfdingbats') || ($family == 'ctimes') || ($family == 'ccourier') || ($family == 'chelvetica')) {
3166 if ($this->PDFA || $this->PDFX) {
3167 if ($family == 'csymbol' || $family == 'czapfdingbats') {
3168 $this->Error("Symbol and Zapfdingbats cannot be embedded in mPDF (required for PDFA1-b or PDFX/1-a).");
3169 }
3170 if ($family == 'ctimes' || $family == 'ccourier' || $family == 'chelvetica') {
3171 if (($this->PDFA && !$this->PDFAauto) || ($this->PDFX && !$this->PDFXauto)) { $this->PDFAXwarnings[] = "Core Adobe font ".ucfirst($family)." cannot be embedded in mPDF, which is required for PDFA1-b or PDFX/1-a. (Embedded font will be substituted.)"; }
3172 if ($family == 'chelvetica') { $family = 'sans'; }
3173 if ($family == 'ctimes') { $family = 'serif'; }
3174 if ($family == 'ccourier') { $family = 'mono'; }
3175 }
3176 $this->usingCoreFont = false;
3177 }
3178 else { $this->usingCoreFont = true; }
3179 if($family=='csymbol' || $family=='czapfdingbats') { $style=''; }
3180 }
3181 else { $this->usingCoreFont = false; }
3182
3183 $this->U=false;
3184 $this->S=false;
3185 if ($style) {
3186 $style=strtoupper($style);
3187 if(strpos($style,'U')!==false) {
3188 $this->U=true;
3189 $style=str_replace('U','',$style);
3190 }
3191 if(strpos($style,'S')!==false) {
3192 $this->S=true;
3193 // Small Caps
3194 if (empty($this->upperCase)) { @include(_MPDF_PATH.'includes/upperCase.php'); }
3195 $style=str_replace('S','',$style);
3196 }
3197 if ($style=='IB') $style='BI';
3198 }
3199 if ($size==0) $size=$this->FontSizePt;
3200
3201 $fontkey=$family.$style;
3202
3203 $stylekey = $style;
3204 if (!$stylekey) { $stylekey = "R"; }
3205
3206 if (!$this->onlyCoreFonts && !$this->usingCoreFont) {
3207 if(!isset($this->fonts[$fontkey]) || count($this->default_available_fonts) != count($this->available_unifonts) ) { // not already added
3208 /*-- CJK-FONTS --*/
3209 // CJK fonts
3210 if (in_array($fontkey,$this->available_CJK_fonts)) {
3211 if(!isset($this->fonts[$fontkey])) { // already added
3212 if (empty($this->Big5_widths)) { require(_MPDF_PATH . 'includes/CJKdata.php'); }
3213 $this->AddCJKFont($family); // don't need to add style
3214 }
3215 }
3216 // Test to see if requested font/style is available - or substitute
3217 else
3218 /*-- END CJK-FONTS --*/
3219 if (!in_array($fontkey,$this->available_unifonts)) {
3220 // If font[nostyle] exists - set it
3221 if (in_array($family,$this->available_unifonts)) {
3222 $style = '';
3223 }
3224
3225 // Else if only one font available - set it (assumes if only one font available it will not have a style)
3226 else if (count($this->available_unifonts) == 1) {
3227 $family = $this->available_unifonts[0];
3228 $style = '';
3229 }
3230
3231 else {
3232 $found = 0;
3233 // else substitute font of similar type
3234 if (in_array($family,$this->sans_fonts)) {
3235 $i = array_intersect($this->sans_fonts,$this->available_unifonts);
3236 if (count($i)) {
3237 $i = array_values($i);
3238 // with requested style if possible
3239 if (!in_array(($i[0].$style),$this->available_unifonts)) {
3240 $style = '';
3241 }
3242 $family = $i[0];
3243 $found = 1;
3244 }
3245 }
3246 else if (in_array($family,$this->serif_fonts)) {
3247 $i = array_intersect($this->serif_fonts,$this->available_unifonts);
3248 if (count($i)) {
3249 $i = array_values($i);
3250 // with requested style if possible
3251 if (!in_array(($i[0].$style),$this->available_unifonts)) {
3252 $style = '';
3253 }
3254 $family = $i[0];
3255 $found = 1;
3256 }
3257 }
3258 else if (in_array($family,$this->mono_fonts)) {
3259 $i = array_intersect($this->mono_fonts,$this->available_unifonts);
3260 if (count($i)) {
3261 $i = array_values($i);
3262 // with requested style if possible
3263 if (!in_array(($i[0].$style),$this->available_unifonts)) {
3264 $style = '';
3265 }
3266 $family = $i[0];
3267 $found = 1;
3268 }
3269 }
3270
3271 if (!$found) {
3272 // set first available font
3273 $fs = $this->available_unifonts[0];
3274 preg_match('/^([a-z_0-9\-]+)([BI]{0,2})$/',$fs,$fas); // Allow "-"
3275 // with requested style if possible
3276 $ws = $fas[1].$style;
3277 if (in_array($ws,$this->available_unifonts)) {
3278 $family = $fas[1]; // leave $style as is
3279 }
3280 else if (in_array($fas[1],$this->available_unifonts)) {
3281 // or without style
3282 $family = $fas[1];
3283 $style = '';
3284 }
3285 else {
3286 // or with the style specified
3287 $family = $fas[1];
3288 $style = $fas[2];
3289 }
3290 }
3291 }
3292 $fontkey = $family.$style;
3293 }
3294 }
3295 // try to add font (if not already added)
3296 $this->AddFont($family, $style);
3297
3298 //Test if font is already selected
3299 if($this->FontFamily == $family && $this->FontFamily == $this->currentfontfamily && $this->FontStyle == $style && $this->FontStyle == $this->currentfontstyle && $this->FontSizePt == $size && $this->FontSizePt == $this->currentfontsize && !$forcewrite) {
3300 return $family;
3301 }
3302
3303 $fontkey = $family.$style;
3304
3305 //Select it
3306 $this->FontFamily = $family;
3307 $this->FontStyle = $style;
3308 $this->FontSizePt = $size;
3309 $this->FontSize = $size / _MPDFK;
3310 $this->CurrentFont = &$this->fonts[$fontkey];
3311 if ($write) {
3312 $fontout = (sprintf('BT /F%d %.3F Tf ET', $this->CurrentFont['i'], $this->FontSizePt));
3313 if($this->page>0 && ((isset($this->pageoutput[$this->page]['Font']) && $this->pageoutput[$this->page]['Font'] != $fontout) || !isset($this->pageoutput[$this->page]['Font']) || $this->keep_block_together)) { $this->_out($fontout); }
3314 $this->pageoutput[$this->page]['Font'] = $fontout;
3315 }
3316
3317
3318
3319 // Added - currentfont (lowercase) used in HTML2PDF
3320 $this->currentfontfamily=$family;
3321 $this->currentfontsize=$size;
3322 $this->currentfontstyle=$style.($this->U ? 'U' : '').($this->S ? 'S' : '');
3323 $this->setMBencoding('UTF-8');
3324 }
3325
3326 else { // if using core fonts
3327
3328
3329 if ($this->PDFA || $this->PDFX) {
3330 $this->Error('Core Adobe fonts cannot be embedded in mPDF (required for PDFA1-b or PDFX/1-a) - cannot use option to use core fonts.');
3331 }
3332 $this->setMBencoding('windows-1252');
3333
3334 //Test if font is already selected
3335 if(($this->FontFamily == $family) AND ($this->FontStyle == $style) AND ($this->FontSizePt == $size) && !$forcewrite) {
3336 return $family;
3337 }
3338
3339 if (!isset($this->CoreFonts[$fontkey])) {
3340 if (in_array($family,$this->serif_fonts)) { $family = 'ctimes'; }
3341 else if (in_array($family,$this->mono_fonts)) { $family = 'ccourier'; }
3342 else { $family = 'chelvetica'; }
3343 $this->usingCoreFont = true;
3344 $fontkey = $family.$style;
3345 }
3346
3347 if(!isset($this->fonts[$fontkey])) {
3348 // STANDARD CORE FONTS
3349 if (isset($this->CoreFonts[$fontkey])) {
3350 //Load metric file
3351 $file=$family;
3352 if($family=='ctimes' || $family=='chelvetica' || $family=='ccourier') { $file.=strtolower($style); }
3353 $file.='.php';
3354 include(_MPDF_PATH.'font/'.$file);
3355 if(!isset($cw)) { $this->Error('Could not include font metric file'); }
3356 $i=count($this->fonts)+$this->extraFontSubsets+1;
3357 $this->fonts[$fontkey]=array('i'=>$i,'type'=>'core','name'=>$this->CoreFonts[$fontkey],'desc'=>$desc,'up'=>$up,'ut'=>$ut,'cw'=>$cw);
3358 if ($this->useKerning) { $this->fonts[$fontkey]['kerninfo'] = $kerninfo; }
3359 }
3360 else {
3361 die('mPDF error - Font not defined');
3362 }
3363 }
3364 //Test if font is already selected
3365 if(($this->FontFamily == $family) AND ($this->FontStyle == $style) AND ($this->FontSizePt == $size) && !$forcewrite) {
3366 return $family;
3367 }
3368 //Select it
3369 $this->FontFamily=$family;
3370 $this->FontStyle=$style;
3371 $this->FontSizePt=$size;
3372 $this->FontSize=$size/_MPDFK;
3373 $this->CurrentFont=&$this->fonts[$fontkey];
3374 if ($write) {
3375 $fontout = (sprintf('BT /F%d %.3F Tf ET', $this->CurrentFont['i'], $this->FontSizePt));
3376 if($this->page>0 && ((isset($this->pageoutput[$this->page]['Font']) && $this->pageoutput[$this->page]['Font'] != $fontout) || !isset($this->pageoutput[$this->page]['Font']) || $this->keep_block_together)) { $this->_out($fontout); }
3377 $this->pageoutput[$this->page]['Font'] = $fontout;
3378 }
3379 // Added - currentfont (lowercase) used in HTML2PDF
3380 $this->currentfontfamily=$family;
3381 $this->currentfontsize=$size;
3382 $this->currentfontstyle=$style.($this->U ? 'U' : '').($this->S ? 'S' : '');
3383
3384 }
3385
3386 return $family;
3387 }
3388
3389 function SetFontSize($size,$write=true) {
3390 //Set font size in points
3391 if($this->FontSizePt==$size) return;
3392 $this->FontSizePt=$size;
3393 $this->FontSize=$size/_MPDFK;
3394 $this->currentfontsize=$size;
3395 if ($write) {
3396 $fontout = (sprintf('BT /F%d %.3F Tf ET', $this->CurrentFont['i'], $this->FontSizePt));
3397 // Edited mPDF 3.0
3398 if($this->page>0 && ((isset($this->pageoutput[$this->page]['Font']) && $this->pageoutput[$this->page]['Font'] != $fontout) || !isset($this->pageoutput[$this->page]['Font']) || $this->keep_block_together)) { $this->_out($fontout); }
3399 $this->pageoutput[$this->page]['Font'] = $fontout;
3400 }
3401 }
3402
3403 function AddLink() {
3404 //Create a new internal link
3405 $n=count($this->links)+1;
3406 $this->links[$n]=array(0,0);
3407 return $n;
3408 }
3409
3410 function SetLink($link,$y=0,$page=-1) {
3411 //Set destination of internal link
3412 if($y==-1) $y=$this->y;
3413 if($page==-1) $page=$this->page;
3414 $this->links[$link]=array($page,$y);
3415 }
3416
3417 function Link($x,$y,$w,$h,$link) {
3418 $l = array($x*_MPDFK,$this->hPt-$y*_MPDFK,$w*_MPDFK,$h*_MPDFK,$link);
3419 if ($this->keep_block_together) { // Save to array - don't write yet
3420 $this->ktLinks[$this->page][]= $l;
3421 return;
3422 }
3423 else if ($this->table_rotate) { // *TABLES*
3424 $this->tbrot_Links[$this->page][]= $l; // *TABLES*
3425 return; // *TABLES*
3426 } // *TABLES*
3427 else if ($this->kwt) {
3428 $this->kwt_Links[$this->page][]= $l;
3429 return;
3430 }
3431
3432 if ($this->writingHTMLheader || $this->writingHTMLfooter) {
3433 $this->HTMLheaderPageLinks[]= $l;
3434 return;
3435 }
3436 //Put a link on the page
3437 $this->PageLinks[$this->page][]= $l;
3438 // Save cross-reference to Column buffer
3439 $ref = count($this->PageLinks[$this->page])-1; // *COLUMNS*
3440 $this->columnLinks[$this->CurrCol][INTVAL($this->x)][INTVAL($this->y)] = $ref; // *COLUMNS*
3441
3442 }
3443
3444 function Text($x,$y,$txt) {
3445 // Output a string
3446 // Called (internally) by Watermark and _tableWrite [rotated cells]
3447 // Expects input to be mb_encoded if necessary and RTL reversed
3448
3449 // ARTIFICIAL BOLD AND ITALIC
3450 $s = 'q ';
3451 if ($this->falseBoldWeight && strpos($this->ReqFontStyle,"B") !== false && strpos($this->FontStyle,"B") === false) {
3452 $s .= '2 Tr 1 J 1 j ';
3453 $s .= sprintf('%.3F w ',($this->FontSize/130)*_MPDFK*$this->falseBoldWeight);
3454 $tc = strtoupper($this->TextColor); // change 0 0 0 rg to 0 0 0 RG
3455 if($this->FillColor!=$tc) { $s .= $tc.' '; } // stroke (outline) = same colour as text(fill)
3456 }
3457 if (strpos($this->ReqFontStyle,"I") !== false && strpos($this->FontStyle,"I") === false) {
3458 $aix = '1 0 0.261799 1 %.3F %.3F Tm';
3459 }
3460 else { $aix = '%.3F %.3F Td'; }
3461
3462 if($this->ColorFlag) $s.=$this->TextColor.' ';
3463
3464 $this->CurrentFont['used']= true;
3465 if ($this->CurrentFont['type']=='TTF' && ($this->CurrentFont['sip'] || $this->CurrentFont['smp'])) {
3466 $txt2 = str_replace(chr(194).chr(160),chr(32),$txt);
3467 $txt2 = $this->UTF8toSubset($txt2);
3468 $s.=sprintf('BT '.$aix.' %s Tj ET ',$x*_MPDFK,($this->h-$y)*_MPDFK,$txt2);
3469 }
3470 else if (!$this->usingCoreFont) {
3471 $txt2 = str_replace(chr(194).chr(160),chr(32),$txt);
3472 $this->UTF8StringToArray($txt2); // this is just to add chars to subset list
3473 if ($this->kerning && $this->useKerning) { $s .= $this->_kern($txt2, '', $aix, $x, $y); }
3474 else {
3475 //Convert string to UTF-16BE without BOM
3476 $txt2= $this->UTF8ToUTF16BE($txt2, false);
3477 $s.=sprintf('BT '.$aix.' (%s) Tj ET ',$x*_MPDFK,($this->h-$y)*_MPDFK,$this->_escape($txt2));
3478 }
3479 }
3480 else {
3481 $txt2 = str_replace(chr(160),chr(32),$txt);
3482 if ($this->kerning && $this->useKerning) { $s .= $this->_kern($txt2, '', $aix, $x, $y); }
3483 else {
3484 $s.=sprintf('BT '.$aix.' (%s) Tj ET ',$x*_MPDFK,($this->h-$y)*_MPDFK,$this->_escape($txt2));
3485 }
3486 }
3487 if($this->U && $txt!='') {
3488 $c = strtoupper($this->TextColor); // change 0 0 0 rg to 0 0 0 RG
3489 if($this->FillColor!=$c) { $s.= ' '.$c.' '; }
3490 if (isset($this->CurrentFont['up'])) { $up=$this->CurrentFont['up']; }
3491 else { $up = -100; }
3492 $adjusty = (-$up/1000* $this->FontSize);
3493 if (isset($this->CurrentFont['ut'])) { $ut=$this->CurrentFont['ut']/1000* $this->FontSize; }
3494 else { $ut = 60/1000* $this->FontSize; }
3495 $olw = $this->LineWidth;
3496 $s.=' '.(sprintf(' %.3F w',$ut*_MPDFK));
3497 $s.=' '.$this->_dounderline($x,$y + $adjusty,$txt);
3498 $s.=' '.(sprintf(' %.3F w',$olw*_MPDFK));
3499 if($this->FillColor!=$c) { $s.= ' '.$this->FillColor.' '; }
3500 }
3501 // STRIKETHROUGH
3502 if($this->strike && $txt!='') {
3503 $c = strtoupper($this->TextColor); // change 0 0 0 rg to 0 0 0 RG
3504 if($this->FillColor!=$c) { $s.= ' '.$c.' '; }
3505 //Superscript and Subscript Y coordinate adjustment (now for striked-through texts)
3506 if (isset($this->CurrentFont['desc']['CapHeight'])) { $ch=$this->CurrentFont['desc']['CapHeight']; }
3507 else { $ch = 700; }
3508 $adjusty = (-$ch/1000* $this->FontSize) * 0.35;
3509 if (isset($this->CurrentFont['ut'])) { $ut=$this->CurrentFont['ut']/1000* $this->FontSize; }
3510 else { $ut = 60/1000* $this->FontSize; }
3511 $olw = $this->LineWidth;
3512 $s.=' '.(sprintf(' %.3F w',$ut*_MPDFK));
3513 $s.=' '.$this->_dounderline($x,$y+$adjusty,$txt);
3514 $s.=' '.(sprintf(' %.3F w',$olw*_MPDFK));
3515 if($this->FillColor!=$c) { $s.= ' '.$this->FillColor.' '; }
3516 }
3517 $s .= 'Q';
3518 $this->_out($s);
3519 }
3520
3521 /*-- DIRECTW --*/
3522 function WriteText($x,$y,$txt) {
3523 // Output a string using Text() but does encoding and text reversing of RTL
3524 $txt = $this->purify_utf8_text($txt);
3525 if ($this->text_input_as_HTML) {
3526 $txt = $this->all_entities_to_utf8($txt);
3527 }
3528 if ($this->usingCoreFont) { $txt = mb_convert_encoding($txt,$this->mb_enc,'UTF-8'); }
3529 // DIRECTIONALITY
3530 if (preg_match("/([".$this->pregRTLchars."])/u", $txt)) { $this->biDirectional = true; } // *RTL*
3531 $this->magic_reverse_dir($txt, true, $this->directionality); // *RTL*
3532 // Font-specific ligature substitution for Indic fonts
3533 if (isset($this->CurrentFont['indic']) && $this->CurrentFont['indic']) $this->ConvertIndic($txt); // *INDIC*
3534 $this->Text($x,$y,$txt);
3535 }
3536
3537 function WriteCell($w,$h=0,$txt='',$border=0,$ln=0,$align='',$fill=0,$link='', $currentx=0) {
3538 //Output a cell using Cell() but does encoding and text reversing of RTL
3539 $txt = $this->purify_utf8_text($txt);
3540 if ($this->text_input_as_HTML) {
3541 $txt = $this->all_entities_to_utf8($txt);
3542 }
3543 if ($this->usingCoreFont) { $txt = mb_convert_encoding($txt,$this->mb_enc,'UTF-8'); }
3544 // DIRECTIONALITY
3545 if (preg_match("/([".$this->pregRTLchars."])/u", $txt)) { $this->biDirectional = true; } // *RTL*
3546 $this->magic_reverse_dir($txt, true, $this->directionality); // *RTL*
3547 // Font-specific ligature substitution for Indic fonts
3548 if (isset($this->CurrentFont['indic']) && $this->CurrentFont['indic']) $this->ConvertIndic($txt); // *INDIC*
3549 $this->Cell($w,$h,$txt,$border,$ln,$align,$fill,$link, $currentx);
3550 }
3551 /*-- END DIRECTW --*/
3552
3553
3554 function ResetSpacing() {
3555 if ($this->ws != 0) { $this->_out('BT 0 Tw ET'); }
3556 $this->ws=0;
3557 if ($this->charspacing != 0) { $this->_out('BT 0 Tc ET'); }
3558 $this->charspacing=0;
3559 }
3560
3561
3562 function SetSpacing($cs,$ws) {
3563 if (intval($cs*1000)==0) { $cs = 0; }
3564 if ($cs) { $this->_out(sprintf('BT %.3F Tc ET',$cs)); }
3565 else if ($this->charspacing != 0) { $this->_out('BT 0 Tc ET'); }
3566 $this->charspacing=$cs;
3567 if (intval($ws*1000)==0) { $ws = 0; }
3568 if ($ws) { $this->_out(sprintf('BT %.3F Tw ET',$ws)); }
3569 else if ($this->ws != 0) { $this->_out('BT 0 Tw ET'); }
3570 $this->ws=$ws;
3571 }
3572
3573 // WORD SPACING
3574 function GetJspacing($nc,$ns,$w,$inclCursive) {
3575 $ws = 0;
3576 $charspacing = 0;
3577 $ww = $this->jSWord;
3578 $ncx = $nc-1;
3579 if ($nc == 0) { return array(0,0); }
3580 else if ($nc==1) { $charspacing = $w; }
3581 // Only word spacing allowed / possible
3582 else if ($this->fixedlSpacing !== false || $inclCursive) {
3583 if ($ns) { $ws = $w / $ns; }
3584 }
3585 else if (!$ns) {
3586 $charspacing = $w / ($ncx );
3587 if (($this->jSmaxChar > 0) && ($charspacing > $this->jSmaxChar)) {
3588 $charspacing = $this->jSmaxChar;
3589 }
3590 }
3591 else if ($ns == ($ncx )) {
3592 $charspacing = $w / $ns;
3593 }
3594 else {
3595 if ($this->usingCoreFont) {
3596 $cs = ($w * (1 - $this->jSWord)) / ($ncx );
3597 if (($this->jSmaxChar > 0) && ($cs > $this->jSmaxChar)) {
3598 $cs = $this->jSmaxChar;
3599 $ww = 1 - (($cs * ($ncx ))/$w);
3600 }
3601 $charspacing = $cs;
3602 $ws = ($w * ($ww) ) / $ns;
3603 }
3604 else {
3605 $cs = ($w * (1 - $this->jSWord)) / ($ncx -$ns);
3606 if (($this->jSmaxChar > 0) && ($cs > $this->jSmaxChar)) {
3607 $cs = $this->jSmaxChar;
3608 $ww = 1 - (($cs * ($ncx -$ns))/$w);
3609 }
3610 $charspacing = $cs;
3611 $ws = (($w * ($ww) ) / $ns) - $charspacing;
3612 }
3613 }
3614 return array($charspacing,$ws);
3615 }
3616
3617 function Cell($w,$h=0,$txt='',$border=0,$ln=0,$align='',$fill=0,$link='', $currentx=0, $lcpaddingL=0, $lcpaddingR=0, $valign='M', $spanfill=0, $abovefont=0, $belowfont=0, $exactWidth=false) {
3618 //Output a cell
3619 // Expects input to be mb_encoded if necessary and RTL reversed
3620 // NON_BREAKING SPACE
3621 if ($this->usingCoreFont) {
3622 $txt = str_replace(chr(160),chr(32),$txt);
3623 }
3624 else {
3625 $txt = str_replace(chr(194).chr(160),chr(32),$txt);
3626 }
3627
3628 $oldcolumn = $this->CurrCol;
3629 // Automatic page break
3630 // Allows PAGE-BREAK-AFTER = avoid to work
3631
3632 if (!$this->tableLevel && (($this->y+$this->divheight>$this->PageBreakTrigger) || ($this->y+$h>$this->PageBreakTrigger) ||
3633 ($this->y+($h*2)>$this->PageBreakTrigger && $this->blk[$this->blklvl]['page_break_after_avoid'])) and !$this->InFooter and $this->AcceptPageBreak()) {
3634 $x=$this->x;//Current X position
3635
3636
3637 // WORD SPACING
3638 $ws=$this->ws;//Word Spacing
3639 $charspacing=$this->charspacing;//Character Spacing
3640 $this->ResetSpacing();
3641
3642 $this->AddPage($this->CurOrientation);
3643 // Added to correct for OddEven Margins
3644 $x += $this->MarginCorrection;
3645 if ($currentx) {
3646 $currentx += $this->MarginCorrection;
3647 }
3648 $this->x=$x;
3649 // WORD SPACING
3650 $this->SetSpacing($charspacing,$ws);
3651 }
3652
3653 // Test: to put line through centre of cell: $this->Line($this->x,$this->y+($h/2),$this->x+50,$this->y+($h/2));
3654
3655 /*-- COLUMNS --*/
3656 // COLS
3657 // COLUMN CHANGE
3658 if ($this->CurrCol != $oldcolumn) {
3659 if ($currentx) {
3660 $currentx += $this->ChangeColumn * ($this->ColWidth+$this->ColGap);
3661 }
3662 $this->x += $this->ChangeColumn * ($this->ColWidth+$this->ColGap);
3663 }
3664
3665 // COLUMNS Update/overwrite the lowest bottom of printing y value for a column
3666 if ($this->ColActive) {
3667 if ($h) { $this->ColDetails[$this->CurrCol]['bottom_margin'] = $this->y+$h; }
3668 else { $this->ColDetails[$this->CurrCol]['bottom_margin'] = $this->y+$this->divheight; }
3669 }
3670 /*-- END COLUMNS --*/
3671
3672 // KEEP BLOCK TOGETHER Update/overwrite the lowest bottom of printing y value on first page
3673 if ($this->keep_block_together) {
3674 if ($h) { $this->ktBlock[$this->page]['bottom_margin'] = $this->y+$h; }
3675 // else { $this->ktBlock[$this->page]['bottom_margin'] = $this->y+$this->divheight; }
3676 }
3677
3678 if($w==0) $w = $this->w-$this->rMargin-$this->x;
3679 $s='';
3680 if($fill==1 && $this->FillColor) {
3681 if((isset($this->pageoutput[$this->page]['FillColor']) && $this->pageoutput[$this->page]['FillColor'] != $this->FillColor) || !isset($this->pageoutput[$this->page]['FillColor']) || $this->keep_block_together) { $s .= $this->FillColor.' '; }
3682 $this->pageoutput[$this->page]['FillColor'] = $this->FillColor;
3683 }
3684
3685
3686 $boxtop = $this->y;
3687 $boxheight = $h;
3688 $boxbottom = $this->y+$h;
3689
3690 if($txt!='') {
3691 // FONT SIZE - this determines the baseline caculation
3692 if ($this->linemaxfontsize && !$this->processingHeader) { $bfs = $this->linemaxfontsize; }
3693 else { $bfs = $this->FontSize; }
3694 //Calculate baseline Superscript and Subscript Y coordinate adjustment
3695 $bfx = $this->baselineC;
3696 $baseline = $bfx*$bfs;
3697 if($this->SUP) { $baseline += ($bfx-1.05)*$this->FontSize; }
3698 else if($this->SUB) { $baseline += ($bfx + 0.04)*$this->FontSize; }
3699 else if($this->bullet) { $baseline += ($bfx-0.7)*$this->FontSize; }
3700
3701 // Vertical align (for Images)
3702 if ($abovefont || $belowfont) { // from flowing block - valign always M
3703 $va = $abovefont + (0.5*$bfs);
3704 }
3705 else if ($this->lineheight_correction) {
3706 if ($valign == 'T') { $va = (0.5 * $bfs * $this->lineheight_correction); }
3707 else if ($valign == 'B') { $va = $h-(0.5 * $bfs * $this->lineheight_correction); }
3708 else { $va = 0.5*$h; } // Middle
3709 }
3710 else {
3711 if ($valign == 'T') { $va = (0.5 * $bfs * $this->default_lineheight_correction); }
3712 else if ($valign == 'B') { $va = $h-(0.5 * $bfs * $this->default_lineheight_correction); }
3713 else { $va = 0.5*$h; } // Middle
3714 }
3715
3716 // ONLY SET THESE IF WANT TO CONFINE BORDER +/- FILL TO FIT FONTSIZE - NOT FULL CELL AS IS ORIGINAL FUNCTION
3717 // spanfill or spanborder are set in FlowingBlock functions
3718 if ($spanfill || !empty($this->spanborddet) || $link!='') {
3719 $exth = 0.2; // Add to fontsize to increase height of background / link / border
3720 $boxtop = $this->y+$baseline+$va-($this->FontSize*(1+$exth/2)*(0.5+$bfx));
3721 $boxheight = $this->FontSize * (1+$exth);
3722 $boxbottom = $boxtop + $boxheight;
3723 }
3724 }
3725
3726 $bbw = $tbw = $lbw = $rbw = 0; // Border widths
3727 if (!empty($this->spanborddet)) {
3728 if (!isset($this->spanborddet['B'])) { $this->spanborddet['B'] = array('s' => 0, 'style' => '', 'w' => 0); }
3729 if (!isset($this->spanborddet['T'])) { $this->spanborddet['T'] = array('s' => 0, 'style' => '', 'w' => 0); }
3730 if (!isset($this->spanborddet['L'])) { $this->spanborddet['L'] = array('s' => 0, 'style' => '', 'w' => 0); }
3731 if (!isset($this->spanborddet['R'])) { $this->spanborddet['R'] = array('s' => 0, 'style' => '', 'w' => 0); }
3732 $bbw = $this->spanborddet['B']['w'];
3733 $tbw = $this->spanborddet['T']['w'];
3734 $lbw = $this->spanborddet['L']['w'];
3735 $rbw = $this->spanborddet['R']['w'];
3736 }
3737 if($fill==1 || $border==1 || !empty($this->spanborddet)) {
3738 if (!empty($this->spanborddet)) {
3739 if ($fill==1) {
3740 $s.=sprintf('%.3F %.3F %.3F %.3F re f ',($this->x-$lbw)*_MPDFK,($this->h-$boxtop+$tbw)*_MPDFK,($w+$lbw+$rbw)*_MPDFK,(-$boxheight-$tbw-$bbw)*_MPDFK);
3741 }
3742 $s.= ' q ';
3743 $dashon = 3;
3744 $dashoff = 3.5;
3745 $dot = 2.5;
3746 if($tbw) {
3747 $short = 0;
3748 if ($this->spanborddet['T']['style'] == 'dashed') {
3749 $s.=sprintf(' 0 j 0 J [%.3F %.3F] 0 d ',$tbw*$dashon*_MPDFK,$tbw*$dashoff*_MPDFK);
3750 }
3751 else if ($this->spanborddet['T']['style'] == 'dotted') {
3752 $s.=sprintf(' 1 j 1 J [%.3F %.3F] %.3F d ',0.001,$tbw*$dot*_MPDFK,-$tbw/2*_MPDFK);
3753 $short = $tbw/2;
3754 }
3755 else {
3756 $s.=' 0 j 0 J [] 0 d ';
3757 }
3758 $c = $this->SetDColor($this->spanborddet['T']['c'],true);
3759 if ($this->spanborddet['T']['style'] == 'double') {
3760 $s.=sprintf(' %s %.3F w ',$c,$tbw/3*_MPDFK);
3761 $xadj = $xadj2 = 0;
3762 if ($this->spanborddet['L']['style'] == 'double') { $xadj = $this->spanborddet['L']['w']*2/3; }
3763 if ($this->spanborddet['R']['style'] == 'double') { $xadj2 = $this->spanborddet['R']['w']*2/3; }
3764 $s.=sprintf('%.3F %.3F m %.3F %.3F l S ',($this->x-$lbw)*_MPDFK,($this->h-$boxtop+$tbw*5/6)*_MPDFK,($this->x+$w+$rbw-$short)*_MPDFK,($this->h-$boxtop+$tbw*5/6)*_MPDFK);
3765 $s.=sprintf('%.3F %.3F m %.3F %.3F l S ',($this->x-$lbw+$xadj)*_MPDFK,($this->h-$boxtop+$tbw/6)*_MPDFK,($this->x+$w+$rbw-$short-$xadj2)*_MPDFK,($this->h-$boxtop+$tbw/6)*_MPDFK);
3766 }
3767 else {
3768 $s.=sprintf(' %s %.3F w ',$c,$tbw*_MPDFK);
3769 $s.=sprintf('%.3F %.3F m %.3F %.3F l S ',($this->x-$lbw)*_MPDFK,($this->h-$boxtop+$tbw/2)*_MPDFK,($this->x+$w+$rbw-$short)*_MPDFK,($this->h-$boxtop+$tbw/2)*_MPDFK);
3770 }
3771 }
3772 if($bbw) {
3773 $short = 0;
3774 if ($this->spanborddet['B']['style'] == 'dashed') {
3775 $s.=sprintf(' 0 j 0 J [%.3F %.3F] 0 d ',$bbw*$dashon*_MPDFK,$bbw*$dashoff*_MPDFK);
3776 }
3777 else if ($this->spanborddet['B']['style'] == 'dotted') {
3778 $s.=sprintf(' 1 j 1 J [%.3F %.3F] %.3F d ',0.001,$bbw*$dot*_MPDFK,-$bbw/2*_MPDFK);
3779 $short = $bbw/2;
3780 }
3781 else {
3782 $s.=' 0 j 0 J [] 0 d ';
3783 }
3784 $c = $this->SetDColor($this->spanborddet['B']['c'],true);
3785 if ($this->spanborddet['B']['style'] == 'double') {
3786 $s.=sprintf(' %s %.3F w ',$c,$bbw/3*_MPDFK);
3787 $xadj = $xadj2 = 0;
3788 if ($this->spanborddet['L']['style'] == 'double') { $xadj = $this->spanborddet['L']['w']*2/3; }
3789 if ($this->spanborddet['R']['style'] == 'double') { $xadj2 = $this->spanborddet['R']['w']*2/3; }
3790 $s.=sprintf('%.3F %.3F m %.3F %.3F l S ',($this->x-$lbw+$xadj)*_MPDFK,($this->h-$boxbottom-$bbw/6)*_MPDFK,($this->x+$w+$rbw-$short-$xadj2)*_MPDFK,($this->h-$boxbottom-$bbw/6)*_MPDFK);
3791 $s.=sprintf('%.3F %.3F m %.3F %.3F l S ',($this->x-$lbw)*_MPDFK,($this->h-$boxbottom-$bbw*5/6)*_MPDFK,($this->x+$w+$rbw-$short)*_MPDFK,($this->h-$boxbottom-$bbw*5/6)*_MPDFK);
3792 }
3793 else {
3794 $s.=sprintf(' %s %.3F w ',$c,$bbw*_MPDFK);
3795 $s.=sprintf('%.3F %.3F m %.3F %.3F l S ',($this->x-$lbw)*_MPDFK,($this->h-$boxbottom-$bbw/2)*_MPDFK,($this->x+$w+$rbw-$short)*_MPDFK,($this->h-$boxbottom-$bbw/2)*_MPDFK);
3796 }
3797 }
3798 if($lbw) {
3799 $short = 0;
3800 if ($this->spanborddet['L']['style'] == 'dashed') {
3801 $s.=sprintf(' 0 j 0 J [%.3F %.3F] 0 d ',$lbw*$dashon*_MPDFK,$lbw*$dashoff*_MPDFK);
3802 }
3803 else if ($this->spanborddet['L']['style'] == 'dotted') {
3804 $s.=sprintf(' 1 j 1 J [%.3F %.3F] %.3F d ',0.001,$lbw*$dot*_MPDFK,-$lbw/2*_MPDFK);
3805 $short = $lbw/2;
3806 }
3807 else {
3808 $s.=' 0 j 0 J [] 0 d ';
3809 }
3810 $c = $this->SetDColor($this->spanborddet['L']['c'],true);
3811 if ($this->spanborddet['L']['style'] == 'double') {
3812 $s.=sprintf(' %s %.3F w ',$c,$lbw/3*_MPDFK);
3813 $yadj = $yadj2 = 0;
3814 if ($this->spanborddet['T']['style'] == 'double') { $yadj = $this->spanborddet['T']['w']*2/3; }
3815 if ($this->spanborddet['B']['style'] == 'double') { $yadj2 = $this->spanborddet['B']['w']*2/3; }
3816 $s.=sprintf('%.3F %.3F m %.3F %.3F l S ',($this->x-$lbw/6)*_MPDFK,($this->h-$boxtop+$tbw-$yadj)*_MPDFK,($this->x-$lbw/6)*_MPDFK,($this->h-$boxbottom-$bbw+$short+$yadj2)*_MPDFK);
3817 $s.=sprintf('%.3F %.3F m %.3F %.3F l S ',($this->x-$lbw*5/6)*_MPDFK,($this->h-$boxtop+$tbw)*_MPDFK,($this->x-$lbw*5/6)*_MPDFK,($this->h-$boxbottom-$bbw+$short)*_MPDFK);
3818 }
3819 else {
3820 $s.=sprintf(' %s %.3F w ',$c,$lbw*_MPDFK);
3821 $s.=sprintf('%.3F %.3F m %.3F %.3F l S ',($this->x-$lbw/2)*_MPDFK,($this->h-$boxtop+$tbw)*_MPDFK,($this->x-$lbw/2)*_MPDFK,($this->h-$boxbottom-$bbw+$short)*_MPDFK);
3822 }
3823 }
3824 if($rbw) {
3825 $short = 0;
3826 if ($this->spanborddet['R']['style'] == 'dashed') {
3827 $s.=sprintf(' 0 j 0 J [%.3F %.3F] 0 d ',$rbw*$dashon*_MPDFK,$rbw*$dashoff*_MPDFK);
3828 }
3829 else if ($this->spanborddet['R']['style'] == 'dotted') {
3830 $s.=sprintf(' 1 j 1 J [%.3F %.3F] %.3F d ',0.001,$rbw*$dot*_MPDFK,-$rbw/2*_MPDFK);
3831 $short = $rbw/2;
3832 }
3833 else {
3834 $s.=' 0 j 0 J [] 0 d ';
3835 }
3836 $c = $this->SetDColor($this->spanborddet['R']['c'],true);
3837 if ($this->spanborddet['R']['style'] == 'double') {
3838 $s.=sprintf(' %s %.3F w ',$c,$rbw/3*_MPDFK);
3839 $yadj = $yadj2 = 0;
3840 if ($this->spanborddet['T']['style'] == 'double') { $yadj = $this->spanborddet['T']['w']*2/3; }
3841 if ($this->spanborddet['B']['style'] == 'double') { $yadj2 = $this->spanborddet['B']['w']*2/3; }
3842 $s.=sprintf('%.3F %.3F m %.3F %.3F l S ',($this->x+$w+$rbw/6)*_MPDFK,($this->h-$boxtop+$tbw-$yadj)*_MPDFK,($this->x+$w+$rbw/6)*_MPDFK,($this->h-$boxbottom-$bbw+$short+$yadj2)*_MPDFK);
3843 $s.=sprintf('%.3F %.3F m %.3F %.3F l S ',($this->x+$w+$rbw*5/6)*_MPDFK,($this->h-$boxtop+$tbw)*_MPDFK,($this->x+$w+$rbw*5/6)*_MPDFK,($this->h-$boxbottom-$bbw+$short)*_MPDFK);
3844 }
3845 else {
3846 $s.=sprintf(' %s %.3F w ',$c,$rbw*_MPDFK);
3847 $s.=sprintf('%.3F %.3F m %.3F %.3F l S ',($this->x+$w+$rbw/2)*_MPDFK,($this->h-$boxtop+$tbw)*_MPDFK,($this->x+$w+$rbw/2)*_MPDFK,($this->h-$boxbottom-$bbw+$short)*_MPDFK);
3848 }
3849 }
3850 $s.= ' Q ';
3851 }
3852 else {
3853 if ($fill==1) $op=($border==1) ? 'B' : 'f';
3854 else $op='S';
3855 $s.=sprintf('%.3F %.3F %.3F %.3F re %s ',$this->x*_MPDFK,($this->h-$boxtop)*_MPDFK,$w*_MPDFK,-$boxheight*_MPDFK,$op);
3856 }
3857 }
3858
3859 if(is_string($border)) {
3860 $x=$this->x;
3861 $y=$this->y;
3862 if(is_int(strpos($border,'L')))
3863 $s.=sprintf('%.3F %.3F m %.3F %.3F l S ',$x*_MPDFK,($this->h-$boxtop)*_MPDFK,$x*_MPDFK,($this->h-($boxbottom))*_MPDFK);
3864 if(is_int(strpos($border,'T')))
3865 $s.=sprintf('%.3F %.3F m %.3F %.3F l S ',$x*_MPDFK,($this->h-$boxtop)*_MPDFK,($x+$w)*_MPDFK,($this->h-$boxtop)*_MPDFK);
3866 if(is_int(strpos($border,'R')))
3867 $s.=sprintf('%.3F %.3F m %.3F %.3F l S ',($x+$w)*_MPDFK,($this->h-$boxtop)*_MPDFK,($x+$w)*_MPDFK,($this->h-($boxbottom))*_MPDFK);
3868 if(is_int(strpos($border,'B')))
3869 $s.=sprintf('%.3F %.3F m %.3F %.3F l S ',$x*_MPDFK,($this->h-($boxbottom))*_MPDFK,($x+$w)*_MPDFK,($this->h-($boxbottom))*_MPDFK);
3870 }
3871
3872 if($txt!='') {
3873 if ($exactWidth)
3874 $stringWidth = $w;
3875 else
3876 $stringWidth = $this->GetStringWidth($txt) + ( $this->charspacing * mb_strlen( $txt, $this->mb_enc ) / _MPDFK )
3877 + ( $this->ws * mb_substr_count( $txt, ' ', $this->mb_enc ) / _MPDFK );
3878
3879 // Set x OFFSET FOR PRINTING
3880 if($align=='R') {
3881 $dx=$w-$this->cMarginR - $stringWidth - $lcpaddingR;
3882 }
3883 elseif($align=='C') {
3884 $dx=(($w - $stringWidth )/2);
3885 }
3886 elseif($align=='L' or $align=='J') $dx=$this->cMarginL + $lcpaddingL;
3887 else $dx = 0;
3888
3889 if($this->ColorFlag) $s .='q '.$this->TextColor.' ';
3890
3891 // OUTLINE
3892 if($this->textparam['outline-s'] && !$this->S) { // mPDF 5.6.07
3893 $s .=' '.sprintf('%.3F w',$this->LineWidth*_MPDFK).' ';
3894 $s .=" $this->DrawColor ";
3895 $s .=" 2 Tr ";
3896 }
3897 else if ($this->falseBoldWeight && strpos($this->ReqFontStyle,"B") !== false && strpos($this->FontStyle,"B") === false && !$this->S) { // can't use together with OUTLINE or Small Caps
3898 $s .= ' 2 Tr 1 J 1 j ';
3899 $s .= ' '.sprintf('%.3F w',($this->FontSize/130)*_MPDFK*$this->falseBoldWeight).' ';
3900 $tc = strtoupper($this->TextColor); // change 0 0 0 rg to 0 0 0 RG
3901 if($this->FillColor!=$tc) { $s .= ' '.$tc.' '; } // stroke (outline) = same colour as text(fill)
3902 }
3903 else { $s .=" 0 Tr "; } // mPDF 5.6.07
3904
3905 if (strpos($this->ReqFontStyle,"I") !== false && strpos($this->FontStyle,"I") === false) { // Artificial italic
3906 $aix = '1 0 0.261799 1 %.3F %.3F Tm ';
3907 }
3908 else { $aix = '%.3F %.3F Td '; }
3909
3910 // THE TEXT
3911 $sub = '';
3912 $this->CurrentFont['used']= true;
3913
3914 // WORD SPACING
3915 // IF multibyte - Tw has no effect - need to use alternative method - do word spacing using an adjustment before each space
3916 if ($this->ws && !$this->usingCoreFont && !$this->CurrentFont['sip'] && !$this->CurrentFont['smp'] && !$this->S) {
3917 $sub .= ' BT 0 Tw ET ';
3918 if ($this->kerning && $this->useKerning) { $sub .= $this->_kern($txt, 'MBTw', $aix, ($this->x+$dx), ($this->y+$baseline+$va)); }
3919 else {
3920 $space = " ";
3921 //Convert string to UTF-16BE without BOM
3922 $space= $this->UTF8ToUTF16BE($space , false);
3923 $space=$this->_escape($space );
3924 $sub .=sprintf('BT '.$aix,($this->x+$dx)*_MPDFK,($this->h-($this->y+$baseline+$va))*_MPDFK);
3925 $t = explode(' ',$txt);
3926 $sub .=sprintf(' %.3F Tc [',$this->charspacing);
3927 $numt = count($t);
3928 for($i=0;$i<$numt;$i++) {
3929 $tx = $t[$i];
3930 //Convert string to UTF-16BE without BOM
3931 $tx = $this->UTF8ToUTF16BE($tx , false);
3932 $tx = $this->_escape($tx);
3933 $sub .=sprintf('(%s) ',$tx);
3934 if (($i+1)<$numt) {
3935 $adj = -($this->ws)*1000/$this->FontSizePt;
3936 $sub .=sprintf('%d(%s) ',$adj,$space);
3937 }
3938 }
3939 $sub .='] TJ ';
3940 $sub .=' ET';
3941 }
3942 }
3943 else {
3944 $txt2= $txt;
3945 if ($this->CurrentFont['type']=='TTF' && ($this->CurrentFont['sip'] || $this->CurrentFont['smp'])) {
3946 if ($this->S) { $sub .= $this->_smallCaps($txt2, 'SIPSMP', $aix, $dx, _MPDFK, $baseline, $va); }
3947 else {
3948 $txt2 = $this->UTF8toSubset($txt2);
3949 $sub .=sprintf('BT '.$aix.' %s Tj ET',($this->x+$dx)*_MPDFK,($this->h-($this->y+$baseline+$va))*_MPDFK,$txt2);
3950 }
3951 }
3952 else {
3953 if ($this->S) { $sub .= $this->_smallCaps($txt2, '', $aix, $dx, _MPDFK, $baseline, $va); }
3954 else if ($this->kerning && $this->useKerning) { $sub .= $this->_kern($txt2, '', $aix, ($this->x+$dx), ($this->y+$baseline+$va)); }
3955 else {
3956 if (!$this->usingCoreFont) {
3957 $txt2 = $this->UTF8ToUTF16BE($txt2, false);
3958 }
3959 $txt2=$this->_escape($txt2);
3960 $sub .=sprintf('BT '.$aix.' (%s) Tj ET',($this->x+$dx)*_MPDFK,($this->h-($this->y+$baseline+$va))*_MPDFK,$txt2);
3961 }
3962 }
3963 }
3964 // UNDERLINE
3965 if($this->U) {
3966 $c = strtoupper($this->TextColor); // change 0 0 0 rg to 0 0 0 RG
3967 if($this->FillColor!=$c) { $sub .= ' '.$c.' '; }
3968 if (isset($this->CurrentFont['up'])) { $up=$this->CurrentFont['up']; }
3969 else { $up = -100; }
3970 $adjusty = (-$up/1000* $this->FontSize);
3971 if (isset($this->CurrentFont['ut'])) { $ut=$this->CurrentFont['ut']/1000* $this->FontSize; }
3972 else { $ut = 60/1000* $this->FontSize; }
3973 $olw = $this->LineWidth;
3974 $sub .=' '.(sprintf(' %.3F w 0 j 0 J ',$ut*_MPDFK));
3975 $sub .=' '.$this->_dounderline($this->x+$dx,$this->y+$baseline+$va+$adjusty,$txt);
3976 $sub .=' '.(sprintf(' %.3F w 2 j 2 J ',$olw*_MPDFK));
3977 if($this->FillColor!=$c) { $sub .= ' '.$this->FillColor.' '; }
3978 }
3979
3980 // STRIKETHROUGH
3981 if($this->strike) {
3982 $c = strtoupper($this->TextColor); // change 0 0 0 rg to 0 0 0 RG
3983 if($this->FillColor!=$c) { $sub .= ' '.$c.' '; }
3984 //Superscript and Subscript Y coordinate adjustment (now for striked-through texts)
3985 if (isset($this->CurrentFont['desc']['CapHeight'])) { $ch=$this->CurrentFont['desc']['CapHeight']; }
3986 else { $ch = 700; }
3987 $adjusty = (-$ch/1000* $this->FontSize) * 0.35;
3988 if (isset($this->CurrentFont['ut'])) { $ut=$this->CurrentFont['ut']/1000* $this->FontSize; }
3989 else { $ut = 60/1000* $this->FontSize; }
3990 $olw = $this->LineWidth;
3991 $sub .=' '.(sprintf(' %.3F w 0 j 0 J ',$ut*_MPDFK));
3992 $sub .=' '.$this->_dounderline($this->x+$dx,$this->y+$baseline+$va+$adjusty,$txt);
3993 $sub .=' '.(sprintf(' %.3F w 2 j 2 J ',$olw*_MPDFK));
3994 if($this->FillColor!=$c) { $sub .= ' '.$this->FillColor.' '; }
3995 }
3996
3997 // TEXT SHADOW
3998 if ($this->textshadow) { // First to process is last in CSS comma separated shadows
3999 foreach($this->textshadow AS $ts) {
4000 $s .= ' q ';
4001 $s .= $this->SetTColor($ts['col'], true)."\n";
4002 if ($ts['col']{0}==5 && ord($ts['col']{4})<100) { // RGBa
4003 $s .= $this->SetAlpha(ord($ts['col']{4})/100, 'Normal', true, 'F')."\n";
4004 }
4005 else if ($ts['col']{0}==6 && ord($ts['col']{5})<100) { // CMYKa
4006 $s .= $this->SetAlpha(ord($ts['col']{5})/100, 'Normal', true, 'F')."\n";
4007 }
4008 else if ($ts['col']{0}==1 && $ts['col']{2}==1 && ord($ts['col']{3})<100) { // Gray
4009 $s .= $this->SetAlpha(ord($ts['col']{3})/100, 'Normal', true, 'F')."\n";
4010 }
4011 $s .= sprintf(' 1 0 0 1 %.4F %.4F cm', $ts['x']*_MPDFK, -$ts['y']*_MPDFK)."\n";
4012 $s .= $sub;
4013 $s .= ' Q ';
4014 }
4015 }
4016
4017 $s .= $sub;
4018
4019 // COLOR
4020 if($this->ColorFlag) $s .=' Q';
4021
4022 // LINK
4023 if($link!='') {
4024 $this->Link($this->x,$boxtop,$w,$boxheight,$link);
4025 }
4026 }
4027 if($s) $this->_out($s);
4028
4029 // WORD SPACING
4030 if ($this->ws && !$this->usingCoreFont) {
4031 $this->_out(sprintf('BT %.3F Tc ET',$this->charspacing));
4032 }
4033 $this->lasth=$h;
4034 if( strpos($txt,"\n") !== false) $ln=1; // cell recognizes \n from <BR> tag
4035 if($ln>0)
4036 {
4037 //Go to next line
4038 $this->y += $h;
4039 if($ln==1) {
4040 //Move to next line
4041 if ($currentx != 0) { $this->x=$currentx; }
4042 else { $this->x=$this->lMargin; }
4043 }
4044 }
4045 else $this->x+=$w;
4046
4047
4048 }
4049
4050
4051 function _kern($txt, $mode, $aix, $x, $y) {
4052 if ($mode == 'MBTw') { // Multibyte requiring word spacing
4053 $space = ' ';
4054 //Convert string to UTF-16BE without BOM
4055 $space= $this->UTF8ToUTF16BE($space , false);
4056 $space=$this->_escape($space );
4057 $s = sprintf(' BT '.$aix,$x*_MPDFK,($this->h-$y)*_MPDFK);
4058 $t = explode(' ',$txt);
4059 for($i=0;$i<count($t);$i++) {
4060 $tx = $t[$i];
4061
4062 $tj = '(';
4063 $unicode = $this->UTF8StringToArray($tx);
4064 for($ti=0;$ti<count($unicode);$ti++) {
4065 if ($ti > 0 && isset($this->CurrentFont['kerninfo'][$unicode[($ti-1)]][$unicode[$ti]])) {
4066 $kern = -$this->CurrentFont['kerninfo'][$unicode[($ti-1)]][$unicode[$ti]];
4067 $tj .= sprintf(')%d(',$kern);
4068 }
4069 $tc = code2utf($unicode[$ti]);
4070 $tc = $this->UTF8ToUTF16BE($tc, false);
4071 $tj .= $this->_escape($tc);
4072 }
4073 $tj .= ')';
4074 $s.=sprintf(' %.3F Tc [%s] TJ',$this->charspacing,$tj);
4075
4076
4077 if (($i+1)<count($t)) {
4078 $s.=sprintf(' %.3F Tc (%s) Tj',$this->ws+$this->charspacing,$space);
4079 }
4080 }
4081 $s.=' ET ';
4082 }
4083 else if (!$this->usingCoreFont) {
4084 $s = '';
4085 $tj = '(';
4086 $unicode = $this->UTF8StringToArray($txt);
4087 for($i=0;$i<count($unicode);$i++) {
4088 if ($i > 0 && isset($this->CurrentFont['kerninfo'][$unicode[($i-1)]][$unicode[$i]])) {
4089 $kern = -$this->CurrentFont['kerninfo'][$unicode[($i-1)]][$unicode[$i]];
4090 $tj .= sprintf(')%d(',$kern);
4091 }
4092 $tx = code2utf($unicode[$i]);
4093 $tx = $this->UTF8ToUTF16BE($tx, false);
4094 $tj .= $this->_escape($tx);
4095 }
4096 $tj .= ')';
4097 $s.=sprintf(' BT '.$aix.' [%s] TJ ET ',$x*_MPDFK,($this->h-$y)*_MPDFK,$tj);
4098 }
4099 else { // CORE Font
4100 $s = '';
4101 $tj = '(';
4102 $l = strlen($txt);
4103 for($i=0;$i<$l;$i++) {
4104 if ($i > 0 && isset($this->CurrentFont['kerninfo'][$txt[($i-1)]][$txt[$i]])) {
4105 $kern = -$this->CurrentFont['kerninfo'][$txt[($i-1)]][$txt[$i]];
4106 $tj .= sprintf(')%d(',$kern);
4107 }
4108 $tj .= $this->_escape($txt[$i]);
4109 }
4110 $tj .= ')';
4111 $s.=sprintf(' BT '.$aix.' [%s] TJ ET ',$x*_MPDFK,($this->h-$y)*_MPDFK,$tj);
4112 }
4113
4114 return $s;
4115 }
4116
4117
4118 function _smallCaps($txt, $mode, $aix, $dx, $k, $baseline, $va) {
4119 $upp = false;
4120 $str = array();
4121 $bits = array();
4122 if (!$this->usingCoreFont) {
4123 $unicode = $this->UTF8StringToArray($txt);
4124 foreach($unicode as $char) {
4125 if ($this->ws && $char == 32) { // space
4126 if (count($str)) { $bits[] = array($upp, $str, false); }
4127 $bits[] = array(false, array(32), true);
4128 $str = array();
4129 $upp = false;
4130 }
4131 else if (isset($this->upperCase[$char])) {
4132 if (!$upp) {
4133 if (count($str)) { $bits[] = array($upp, $str, false); }
4134 $str = array();
4135 }
4136 $str[] = $this->upperCase[$char];
4137 if ((!isset($this->CurrentFont['sip']) || !$this->CurrentFont['sip']) && (!isset($this->CurrentFont['smp']) || !$this->CurrentFont['smp'])) {
4138 $this->CurrentFont['subset'][$this->upperCase[$char]] = $this->upperCase[$char];
4139 }
4140 $upp = true;
4141 }
4142 else {
4143 if ($upp) {
4144 if (count($str)) { $bits[] = array($upp, $str, false); }
4145 $str = array();
4146 }
4147 $str[] = $char;
4148 $upp = false;
4149 }
4150 }
4151 }
4152 else {
4153 for($i=0;$i<strlen($txt);$i++) {
4154 if (isset($this->upperCase[ord($txt[$i])]) && $this->upperCase[ord($txt[$i])] < 256) {
4155 if (!$upp) {
4156 if (count($str)) { $bits[] = array($upp, $str, false); }
4157 $str = array();
4158 }
4159 $str[] = $this->upperCase[ord($txt[$i])];
4160 $upp = true;
4161 }
4162 else {
4163 if ($upp) {
4164 if (count($str)) { $bits[] = array($upp, $str, false); }
4165 $str = array();
4166 }
4167 $str[] = ord($txt[$i]);
4168 $upp = false;
4169 }
4170 }
4171 }
4172 if (count($str)) { $bits[] = array($upp, $str, false); }
4173
4174 $fid = $this->CurrentFont['i'];
4175
4176 $s=sprintf(' BT '.$aix,($this->x+$dx)*$k,($this->h-($this->y+$baseline+$va))*$k);
4177 foreach($bits AS $b) {
4178 if ($b[0]) { $upp = true; }
4179 else { $upp = false; }
4180
4181 $size = count ($b[1]);
4182 $txt = '';
4183 for ($i = 0; $i < $size; $i++) {
4184 $txt .= code2utf($b[1][$i]);
4185 }
4186 if ($this->usingCoreFont) {
4187 $txt = utf8_decode($txt);
4188 }
4189 if ($mode == 'SIPSMP') {
4190 $txt = $this->UTF8toSubset($txt);
4191 }
4192 else {
4193 if (!$this->usingCoreFont) {
4194 $txt = $this->UTF8ToUTF16BE($txt, false);
4195 }
4196 $txt=$this->_escape($txt);
4197 $txt = '('.$txt.')';
4198 }
4199 if ($b[2]) { // space
4200 $s.=sprintf(' /F%d %.3F Tf %d Tz', $fid, $this->FontSizePt, 100);
4201 $s.=sprintf(' %.3F Tc', ($this->charspacing+$this->ws));
4202 $s.=sprintf(' %s Tj', $txt);
4203 }
4204 else if ($upp) {
4205 $s.=sprintf(' /F%d %.3F Tf', $fid, $this->FontSizePt*$this->smCapsScale);
4206 $s.=sprintf(' %d Tz', $this->smCapsStretch);
4207 $s.=sprintf(' %.3F Tc', ($this->charspacing*100/$this->smCapsStretch));
4208 $s.=sprintf(' %s Tj', $txt);
4209 }
4210 else {
4211 $s.=sprintf(' /F%d %.3F Tf %d Tz', $fid, $this->FontSizePt, 100);
4212 $s.=sprintf(' %.3F Tc', ($this->charspacing));
4213 $s.=sprintf(' %s Tj', $txt);
4214 }
4215 }
4216 $s.=' ET ';
4217 return $s;
4218 }
4219
4220
4221 function MultiCell($w,$h,$txt,$border=0,$align='',$fill=0,$link='',$directionality='ltr',$encoded=false)
4222 {
4223 // Parameter (pre-)encoded - When called internally from ToC or textarea: mb_encoding already done - but not reverse RTL/Indic
4224 if (!$encoded) {
4225 $txt = $this->purify_utf8_text($txt);
4226 if ($this->text_input_as_HTML) {
4227 $txt = $this->all_entities_to_utf8($txt);
4228 }
4229 if ($this->usingCoreFont) { $txt = mb_convert_encoding($txt,$this->mb_enc,'UTF-8'); }
4230 // Font-specific ligature substitution for Indic fonts
4231 else if (isset($this->CurrentFont['indic']) && $this->CurrentFont['indic']) { // *INDIC*
4232 $this->ConvertIndic($tmp); // *INDIC*
4233 } // *INDIC*
4234 if (preg_match("/([".$this->pregRTLchars."])/u", $txt)) { $this->biDirectional = true; } // *RTL*
4235 }
4236 if (!$align) { $align = $this->defaultAlign; }
4237
4238 //Output text with automatic or explicit line breaks
4239 $cw=&$this->CurrentFont['cw'];
4240 if($w==0) $w=$this->w-$this->rMargin-$this->x;
4241
4242 $wmax = ($w - ($this->cMarginL+$this->cMarginR));
4243 if ($this->usingCoreFont) {
4244 $s=str_replace("\r",'',$txt);
4245 $nb=strlen($s);
4246 while($nb>0 and $s[$nb-1]=="\n") $nb--;
4247 }
4248 else {
4249 $s=str_replace("\r",'',$txt);
4250 $nb=mb_strlen($s, $this->mb_enc );
4251 while($nb>0 and mb_substr($s,$nb-1,1,$this->mb_enc )=="\n") $nb--;
4252 }
4253 $b=0;
4254 if($border) {
4255 if($border==1) {
4256 $border='LTRB';
4257 $b='LRT';
4258 $b2='LR';
4259 }
4260 else {
4261 $b2='';
4262 if(is_int(strpos($border,'L'))) $b2.='L';
4263 if(is_int(strpos($border,'R'))) $b2.='R';
4264 $b=is_int(strpos($border,'T')) ? $b2.'T' : $b2;
4265 }
4266 }
4267 $sep=-1;
4268 $i=0;
4269 $j=0;
4270 $l=0;
4271 $ns=0;
4272 $nl=1;
4273
4274
4275
4276 if (!$this->usingCoreFont) {
4277 $checkCursive=false;
4278 if ($this->biDirectional) { $checkCursive=true; }
4279 else if (isset($this->CurrentFont['indic']) && $this->CurrentFont['indic']) { $checkCursive=true; } // *INDIC*
4280 while($i<$nb) {
4281 //Get next character
4282 $c = mb_substr($s,$i,1,$this->mb_enc );
4283 if($c == "\n") {
4284 //Explicit line break
4285 // WORD SPACING
4286 $this->ResetSpacing();
4287 $tmp = rtrim(mb_substr($s,$j,$i-$j,$this->mb_enc));
4288 // DIRECTIONALITY
4289 $this->magic_reverse_dir($tmp, true, $directionality); // *RTL*
4290
4291 $this->Cell($w,$h,$tmp,$b,2,$align,$fill,$link);
4292 $i++;
4293 $sep=-1;
4294 $j=$i;
4295 $l=0;
4296 $ns=0;
4297 $nl++;
4298 if($border and $nl==2) $b=$b2;
4299 continue;
4300 }
4301 if($c == " ") {
4302 $sep=$i;
4303 $ls=$l;
4304 $ns++;
4305 }
4306
4307 $l += $this->GetCharWidthNonCore($c);
4308
4309 if($l>$wmax) {
4310 //Automatic line break
4311 if($sep==-1) { // Only one word
4312 if($i==$j) $i++;
4313 // WORD SPACING
4314 $this->ResetSpacing();
4315 $tmp = rtrim(mb_substr($s,$j,$i-$j,$this->mb_enc));
4316 // DIRECTIONALITY
4317 $this->magic_reverse_dir($tmp, true, $directionality); // *RTL*
4318
4319 $this->Cell($w,$h,$tmp,$b,2,$align,$fill,$link);
4320 }
4321 else {
4322 $tmp = rtrim(mb_substr($s,$j,$sep-$j,$this->mb_enc));
4323 if($align=='J') {
4324 //////////////////////////////////////////
4325 // JUSTIFY J using Unicode fonts (Word spacing doesn't work)
4326 // WORD SPACING UNICODE
4327 // Change NON_BREAKING SPACE to spaces so they are 'spaced' properly
4328 $tmp = str_replace(chr(194).chr(160),chr(32),$tmp );
4329 $len_ligne = $this->GetStringWidth($tmp );
4330 $nb_carac = mb_strlen( $tmp , $this->mb_enc ) ;
4331 $nb_spaces = mb_substr_count( $tmp ,' ', $this->mb_enc ) ;
4332
4333 $inclCursive=false;
4334 if ($checkCursive) {
4335 if (preg_match("/([".$this->pregRTLchars."])/u", $tmp)) { $inclCursive = true; } // *RTL*
4336 if (preg_match("/([".$this->pregHIchars.$this->pregBNchars.$this->pregPAchars."])/u", $tmp)) { $inclCursive = true; } // *INDIC*
4337 }
4338 list($charspacing,$ws) = $this->GetJspacing($nb_carac,$nb_spaces,((($wmax) - $len_ligne) * _MPDFK),$inclCursive);
4339 $this->SetSpacing($charspacing,$ws);
4340 //////////////////////////////////////////
4341 }
4342
4343 // DIRECTIONALITY
4344 $this->magic_reverse_dir($tmp, true, $directionality); // *RTL*
4345
4346 $this->Cell($w,$h,$tmp,$b,2,$align,$fill,$link);
4347 $i=$sep+1;
4348 }
4349 $sep=-1;
4350 $j=$i;
4351 $l=0;
4352 $ns=0;
4353 $nl++;
4354 if($border and $nl==2) $b=$b2;
4355 }
4356 else $i++;
4357 }
4358 //Last chunk
4359 // WORD SPACING
4360
4361 $this->ResetSpacing();
4362
4363 }
4364
4365
4366 else {
4367
4368 while($i<$nb) {
4369 //Get next character
4370 $c=$s[$i];
4371 if($c == "\n") {
4372 //Explicit line break
4373 // WORD SPACING
4374 $this->ResetSpacing();
4375 $this->Cell($w,$h,substr($s,$j,$i-$j),$b,2,$align,$fill,$link);
4376 $i++;
4377 $sep=-1;
4378 $j=$i;
4379 $l=0;
4380 $ns=0;
4381 $nl++;
4382 if($border and $nl==2) $b=$b2;
4383 continue;
4384 }
4385 if($c == " ") {
4386 $sep=$i;
4387 $ls=$l;
4388 $ns++;
4389 }
4390
4391 $l += $this->GetCharWidthCore($c);
4392 if($l>$wmax) {
4393 //Automatic line break
4394 if($sep==-1) {
4395 if($i==$j) $i++;
4396 // WORD SPACING
4397 $this->ResetSpacing();
4398 $this->Cell($w,$h,substr($s,$j,$i-$j),$b,2,$align,$fill,$link);
4399 }
4400 else {
4401 if($align=='J') {
4402 $tmp = rtrim(substr($s,$j,$sep-$j));
4403 //////////////////////////////////////////
4404 // JUSTIFY J using Unicode fonts (Word spacing doesn't work)
4405 // WORD SPACING NON_UNICDOE/CJK
4406 // Change NON_BREAKING SPACE to spaces so they are 'spaced' properly
4407 $tmp = str_replace(chr(160),chr(32),$tmp);
4408 $len_ligne = $this->GetStringWidth($tmp );
4409 $nb_carac = strlen( $tmp ) ;
4410 $nb_spaces = substr_count( $tmp ,' ' ) ;
4411 list($charspacing,$ws) = $this->GetJspacing($nb_carac,$nb_spaces,((($wmax) - $len_ligne) * _MPDFK),false);
4412 $this->SetSpacing($charspacing,$ws);
4413 //////////////////////////////////////////
4414 }
4415 $this->Cell($w,$h,substr($s,$j,$sep-$j),$b,2,$align,$fill,$link);
4416 $i=$sep+1;
4417 }
4418 $sep=-1;
4419 $j=$i;
4420 $l=0;
4421 $ns=0;
4422 $nl++;
4423 if($border and $nl==2) $b=$b2;
4424 }
4425 else $i++;
4426 }
4427 //Last chunk
4428 // WORD SPACING
4429
4430 $this->ResetSpacing();
4431
4432 }
4433 //Last chunk
4434 if($border and is_int(strpos($border,'B'))) $b.='B';
4435 if (!$this->usingCoreFont) {
4436 $tmp = rtrim(mb_substr($s,$j,$i-$j,$this->mb_enc));
4437 // DIRECTIONALITY
4438 $this->magic_reverse_dir($tmp, true, $directionality); // *RTL*
4439 $this->Cell($w,$h,$tmp,$b,2,$align,$fill,$link);
4440 }
4441 else { $this->Cell($w,$h,substr($s,$j,$i-$j),$b,2,$align,$fill,$link); }
4442 $this->x=$this->lMargin;
4443 }
4444
4445
4446 /*-- DIRECTW --*/
4447 function Write($h,$txt,$currentx=0,$link='',$directionality='ltr',$align='') {
4448 if (!class_exists('directw', false)) { include(_MPDF_PATH.'classes/directw.php'); }
4449 if (empty($this->directw)) { $this->directw = new directw($this); }
4450 $this->directw->Write($h,$txt,$currentx,$link,$directionality,$align);
4451 }
4452 /*-- END DIRECTW --*/
4453
4454
4455 /*-- HTML-CSS --*/
4456 function saveInlineProperties() {
4457 $saved = array();
4458 $saved[ 'family' ] = $this->FontFamily;
4459 $saved[ 'style' ] = $this->FontStyle;
4460 $saved[ 'sizePt' ] = $this->FontSizePt;
4461 $saved[ 'size' ] = $this->FontSize;
4462 $saved[ 'HREF' ] = $this->HREF;
4463 $saved[ 'underline' ] = $this->U;
4464 $saved[ 'smCaps' ] = $this->S;
4465 $saved[ 'strike' ] = $this->strike;
4466 $saved[ 'textshadow' ] = $this->textshadow;
4467 $saved[ 'SUP' ] = $this->SUP;
4468 $saved[ 'SUB' ] = $this->SUB;
4469 $saved[ 'linewidth' ] = $this->LineWidth;
4470 $saved[ 'drawcolor' ] = $this->DrawColor;
4471 $saved[ 'textparam' ] = $this->textparam;
4472 $saved[ 'toupper' ] = $this->toupper;
4473 $saved[ 'tolower' ] = $this->tolower;
4474 $saved[ 'capitalize' ] = $this->capitalize;
4475 $saved[ 'fontkerning' ] = $this->kerning;
4476 $saved[ 'lSpacingCSS' ] = $this->lSpacingCSS;
4477 $saved[ 'wSpacingCSS' ] = $this->wSpacingCSS;
4478 $saved[ 'I' ] = $this->I;
4479 $saved[ 'B' ] = $this->B;
4480 $saved[ 'colorarray' ] = $this->colorarray;
4481 $saved[ 'bgcolorarray' ] = $this->spanbgcolorarray;
4482 $saved[ 'border' ] = $this->spanborddet;
4483 $saved[ 'color' ] = $this->TextColor;
4484 $saved[ 'bgcolor' ] = $this->FillColor;
4485 $saved[ 'lang' ] = $this->currentLang;
4486 $saved[ 'display_off' ] = $this->inlineDisplayOff;
4487
4488 return $saved;
4489 }
4490
4491 function restoreInlineProperties( &$saved) {
4492 $FontFamily = $saved[ 'family' ];
4493 $this->FontStyle = $saved[ 'style' ];
4494 $this->FontSizePt = $saved[ 'sizePt' ];
4495 $this->FontSize = $saved[ 'size' ];
4496
4497 $this->currentLang = $saved['lang'];
4498 if ($this->useLang && !$this->usingCoreFont) {
4499 if ($this->currentLang != $this->default_lang && ((strlen($this->currentLang) == 5 && $this->currentLang != 'UTF-8') || strlen($this->currentLang ) == 2)) {
4500 list ($coreSuitable,$mpdf_pdf_unifonts) = GetLangOpts($this->currentLang, $this->useAdobeCJK);
4501 if ($mpdf_pdf_unifonts) { $this->RestrictUnicodeFonts($mpdf_pdf_unifonts); }
4502 else { $this->RestrictUnicodeFonts($this->default_available_fonts ); }
4503 }
4504 else {
4505 $this->RestrictUnicodeFonts($this->default_available_fonts );
4506 }
4507 }
4508
4509 $this->ColorFlag = ($this->FillColor != $this->TextColor); //Restore ColorFlag as well
4510
4511 $this->HREF = $saved[ 'HREF' ];
4512 $this->U = $saved[ 'underline' ];
4513 $this->S = $saved[ 'smCaps' ];
4514 $this->strike = $saved[ 'strike' ];
4515 $this->textshadow = $saved[ 'textshadow' ];
4516 $this->SUP = $saved[ 'SUP' ];
4517 $this->SUB = $saved[ 'SUB' ];
4518 $this->LineWidth = $saved[ 'linewidth' ];
4519 $this->DrawColor = $saved[ 'drawcolor' ];
4520 $this->textparam = $saved[ 'textparam' ];
4521 $this->inlineDisplayOff = $saved['display_off'];
4522
4523 $this->toupper = $saved[ 'toupper' ];
4524 $this->tolower = $saved[ 'tolower' ];
4525 $this->capitalize = $saved[ 'capitalize' ];
4526 $this->kerning = $saved[ 'fontkerning' ];
4527 $this->lSpacingCSS = $saved[ 'lSpacingCSS' ];
4528 if (($this->lSpacingCSS || $this->lSpacingCSS==='0') && strtoupper($this->lSpacingCSS) != 'NORMAL') {
4529 $this->fixedlSpacing = $this->ConvertSize($this->lSpacingCSS,$this->FontSize);
4530 }
4531 else { $this->fixedlSpacing = false; }
4532 $this->wSpacingCSS = $saved[ 'wSpacingCSS' ];
4533 if ($this->wSpacingCSS && strtoupper($this->wSpacingCSS) != 'NORMAL') {
4534 $this->minwSpacing = $this->ConvertSize($this->wSpacingCSS,$this->FontSize);
4535 }
4536 else { $this->minwSpacing = 0; }
4537
4538 $this->SetFont($FontFamily, $saved[ 'style' ].($this->U ? 'U' : '').($this->S ? 'S' : ''),$saved[ 'sizePt' ],false);
4539
4540 $this->currentfontstyle = $saved[ 'style' ].($this->U ? 'U' : '').($this->S ? 'S' : '');
4541 $this->currentfontsize = $saved[ 'sizePt' ];
4542 $this->SetStylesArray(array('S'=>$this->S, 'U'=>$this->U, 'B'=>$saved[ 'B' ], 'I'=>$saved[ 'I' ]));
4543
4544 $this->TextColor = $saved[ 'color' ];
4545 $this->FillColor = $saved[ 'bgcolor' ];
4546 $this->colorarray = $saved[ 'colorarray' ];
4547 $cor = $saved[ 'colorarray' ];
4548 if ($cor) $this->SetTColor($cor);
4549 $this->spanbgcolorarray = $saved[ 'bgcolorarray' ];
4550 $cor = $saved[ 'bgcolorarray' ];
4551 if ($cor) $this->SetFColor($cor);
4552 $this->spanborddet = $saved[ 'border' ];
4553 }
4554
4555
4556
4557 // Used when ColActive for tables - updated to return first block with background fill OR borders
4558 function GetFirstBlockFill() {
4559 // Returns the first blocklevel that uses a bgcolor fill
4560 $startfill = 0;
4561 for ($i=1;$i<=$this->blklvl;$i++) {
4562 if ($this->blk[$i]['bgcolor'] || $this->blk[$i]['border_left']['w'] || $this->blk[$i]['border_right']['w'] || $this->blk[$i]['border_top']['w'] || $this->blk[$i]['border_bottom']['w'] ) {
4563 $startfill = $i;
4564 break;
4565 }
4566 }
4567 return $startfill;
4568 }
4569
4570 function SetBlockFill($blvl) {
4571 if ($this->blk[$blvl]['bgcolor']) {
4572 $this->SetFColor($this->blk[$blvl]['bgcolorarray']);
4573 return 1;
4574 }
4575 else {
4576 $this->SetFColor($this->ConvertColor(255));
4577 return 0;
4578 }
4579 }
4580
4581
4582 //-------------------------FLOWING BLOCK------------------------------------//
4583 //The following functions were originally written by Damon Kohler //
4584 //--------------------------------------------------------------------------//
4585
4586 function saveFont() {
4587 $saved = array();
4588 $saved[ 'family' ] = $this->FontFamily;
4589 $saved[ 'style' ] = $this->FontStyle;
4590 $saved[ 'sizePt' ] = $this->FontSizePt;
4591 $saved[ 'size' ] = $this->FontSize;
4592 $saved[ 'curr' ] = &$this->CurrentFont;
4593 $saved[ 'color' ] = $this->TextColor;
4594 $saved[ 'spanbgcolor' ] = $this->spanbgcolor;
4595 $saved[ 'spanbgcolorarray' ] = $this->spanbgcolorarray;
4596 $saved[ 'bord' ] = $this->spanborder;
4597 $saved[ 'border' ] = $this->spanborddet;
4598 $saved[ 'HREF' ] = $this->HREF;
4599 $saved[ 'underline' ] = $this->U;
4600 $saved[ 'smCaps' ] = $this->S;
4601 $saved[ 'strike' ] = $this->strike;
4602 $saved[ 'textshadow' ] = $this->textshadow;
4603 $saved[ 'SUP' ] = $this->SUP;
4604 $saved[ 'SUB' ] = $this->SUB;
4605 $saved[ 'linewidth' ] = $this->LineWidth;
4606 $saved[ 'drawcolor' ] = $this->DrawColor;
4607 $saved[ 'textparam' ] = $this->textparam;
4608 $saved[ 'ReqFontStyle' ] = $this->ReqFontStyle;
4609 $saved[ 'fontkerning' ] = $this->kerning;
4610 $saved[ 'fixedlSpacing' ] = $this->fixedlSpacing;
4611 $saved[ 'minwSpacing' ] = $this->minwSpacing;
4612 return $saved;
4613 }
4614
4615 function restoreFont( &$saved, $write=true) {
4616 if (!isset($saved) || empty($saved)) return;
4617
4618 $this->FontFamily = $saved[ 'family' ];
4619 $this->FontStyle = $saved[ 'style' ];
4620 $this->FontSizePt = $saved[ 'sizePt' ];
4621 $this->FontSize = $saved[ 'size' ];
4622 $this->CurrentFont = &$saved[ 'curr' ];
4623 $this->TextColor = $saved[ 'color' ];
4624 $this->spanbgcolor = $saved[ 'spanbgcolor' ];
4625 $this->spanbgcolorarray = $saved[ 'spanbgcolorarray' ];
4626 $this->spanborder = $saved[ 'bord' ];
4627 $this->spanborddet = $saved[ 'border' ];
4628 $this->ColorFlag = ($this->FillColor != $this->TextColor); //Restore ColorFlag as well
4629 $this->HREF = $saved[ 'HREF' ];
4630 $this->U = $saved[ 'underline' ];
4631 $this->S = $saved[ 'smCaps' ];
4632 $this->kerning = $saved[ 'fontkerning' ];
4633 $this->fixedlSpacing = $saved[ 'fixedlSpacing' ];
4634 $this->minwSpacing = $saved[ 'minwSpacing' ];
4635 $this->strike = $saved[ 'strike' ];
4636 $this->textshadow = $saved[ 'textshadow' ];
4637 $this->SUP = $saved[ 'SUP' ];
4638 $this->SUB = $saved[ 'SUB' ];
4639 $this->LineWidth = $saved[ 'linewidth' ];
4640 $this->DrawColor = $saved[ 'drawcolor' ];
4641 $this->textparam = $saved[ 'textparam' ];
4642 if ($write) {
4643 $this->SetFont($saved[ 'family' ],$saved[ 'style' ].($this->U ? 'U' : '').($this->S ? 'S' : ''),$saved[ 'sizePt' ],true,true); // force output
4644 $fontout = (sprintf('BT /F%d %.3F Tf ET', $this->CurrentFont['i'], $this->FontSizePt));
4645 if($this->page>0 && ((isset($this->pageoutput[$this->page]['Font']) && $this->pageoutput[$this->page]['Font'] != $fontout) || !isset($this->pageoutput[$this->page]['Font']) || $this->keep_block_together)) { $this->_out($fontout); }
4646 $this->pageoutput[$this->page]['Font'] = $fontout;
4647 }
4648 else
4649 $this->SetFont($saved[ 'family' ],$saved[ 'style' ].($this->U ? 'U' : '').($this->S ? 'S' : ''),$saved[ 'sizePt' ]);
4650 $this->ReqFontStyle = $saved[ 'ReqFontStyle' ];
4651 }
4652
4653 function newFlowingBlock( $w, $h, $a = '', $is_table = false, $is_list = false, $blockstate = 0, $newblock=true, $blockdir='ltr')
4654 {
4655 if (!$a) {
4656 if ($blockdir=='rtl') { $a = 'R'; }
4657 else { $a = 'L'; }
4658 }
4659 $this->flowingBlockAttr[ 'width' ] = ($w * _MPDFK);
4660 // line height in user units
4661 $this->flowingBlockAttr[ 'is_table' ] = $is_table;
4662 $this->flowingBlockAttr[ 'is_list' ] = $is_list;
4663 $this->flowingBlockAttr[ 'height' ] = $h;
4664 $this->flowingBlockAttr[ 'lineCount' ] = 0;
4665 $this->flowingBlockAttr[ 'align' ] = $a;
4666 $this->flowingBlockAttr[ 'font' ] = array();
4667 $this->flowingBlockAttr[ 'content' ] = array();
4668 $this->flowingBlockAttr[ 'contentB' ] = array();
4669 $this->flowingBlockAttr[ 'contentWidth' ] = 0;
4670 $this->flowingBlockAttr[ 'blockstate' ] = $blockstate;
4671
4672 $this->flowingBlockAttr[ 'newblock' ] = $newblock;
4673 $this->flowingBlockAttr[ 'valign' ] = 'M';
4674 $this->flowingBlockAttr['blockdir'] = $blockdir;
4675
4676 }
4677
4678 function finishFlowingBlock($endofblock=false, $next='') {
4679 $currentx = $this->x;
4680 //prints out the last chunk
4681 $is_table = $this->flowingBlockAttr[ 'is_table' ];
4682 $is_list = $this->flowingBlockAttr[ 'is_list' ];
4683 $maxWidth =& $this->flowingBlockAttr[ 'width' ];
4684 $lineHeight =& $this->flowingBlockAttr[ 'height' ];
4685 $align =& $this->flowingBlockAttr[ 'align' ];
4686 $content =& $this->flowingBlockAttr[ 'content' ];
4687 $contentB =& $this->flowingBlockAttr[ 'contentB' ];
4688 $font =& $this->flowingBlockAttr[ 'font' ];
4689 $contentWidth =& $this->flowingBlockAttr[ 'contentWidth' ];
4690 $lineCount =& $this->flowingBlockAttr[ 'lineCount' ];
4691 $valign =& $this->flowingBlockAttr[ 'valign' ];
4692 $blockstate = $this->flowingBlockAttr[ 'blockstate' ];
4693
4694 $newblock = $this->flowingBlockAttr[ 'newblock' ];
4695 $blockdir = $this->flowingBlockAttr['blockdir'];
4696
4697
4698 // *********** BLOCK BACKGROUND COLOR *****************//
4699 if ($this->blk[$this->blklvl]['bgcolor'] && !$is_table) {
4700 $fill = 0;
4701 }
4702 else {
4703 $this->SetFColor($this->ConvertColor(255));
4704 $fill = 0;
4705 }
4706
4707 $hanger = ''; // mPDF 5.6.40
4708
4709 // Always right trim!
4710 // Right trim content and adjust width if need to justify (later)
4711 if (isset($content[count($content)-1]) && preg_match('/[ ]+$/',$content[count($content)-1], $m)) {
4712 $strip = strlen($m[0]);
4713 $content[count($content)-1] = substr($content[count($content)-1],0,(strlen($content[count($content)-1])-$strip));
4714 $this->restoreFont( $font[ count($content)-1 ],false );
4715 $contentWidth -= $this->GetStringWidth($m[0]) * _MPDFK;
4716 }
4717
4718 // the amount of space taken up so far in user units
4719 $usedWidth = 0;
4720
4721 // COLS
4722 $oldcolumn = $this->CurrCol;
4723
4724 if ($this->ColActive && !$is_table) { $this->breakpoints[$this->CurrCol][] = $this->y; } // *COLUMNS*
4725
4726 // Print out each chunk
4727
4728 /*-- TABLES --*/
4729 if ($is_table) {
4730 $ipaddingL = 0;
4731 $ipaddingR = 0;
4732 $paddingL = 0;
4733 $paddingR = 0;
4734 }
4735 else {
4736 /*-- END TABLES --*/
4737 $ipaddingL = $this->blk[$this->blklvl]['padding_left'];
4738 $ipaddingR = $this->blk[$this->blklvl]['padding_right'];
4739 $paddingL = ($ipaddingL * _MPDFK);
4740 $paddingR = ($ipaddingR * _MPDFK);
4741 $this->cMarginL = $this->blk[$this->blklvl]['border_left']['w'];
4742 $this->cMarginR = $this->blk[$this->blklvl]['border_right']['w'];
4743
4744 // Added mPDF 3.0 Float DIV
4745 $fpaddingR = 0;
4746 $fpaddingL = 0;
4747 /*-- CSS-FLOAT --*/
4748 if (count($this->floatDivs)) {
4749 list($l_exists, $r_exists, $l_max, $r_max, $l_width, $r_width) = $this->GetFloatDivInfo($this->blklvl);
4750 if ($r_exists) { $fpaddingR = $r_width; }
4751 if ($l_exists) { $fpaddingL = $l_width; }
4752 }
4753 /*-- END CSS-FLOAT --*/
4754
4755 $usey = $this->y + 0.002;
4756 if (($newblock) && ($blockstate==1 || $blockstate==3) && ($lineCount == 0) ) {
4757 $usey += $this->blk[$this->blklvl]['margin_top'] + $this->blk[$this->blklvl]['padding_top'] + $this->blk[$this->blklvl]['border_top']['w'];
4758 }
4759 /*-- CSS-IMAGE-FLOAT --*/
4760 // If float exists at this level
4761 if (isset($this->floatmargins['R']) && $usey <= $this->floatmargins['R']['y1'] && $usey >= $this->floatmargins['R']['y0'] && !$this->floatmargins['R']['skipline']) { $fpaddingR += $this->floatmargins['R']['w']; }
4762 if (isset($this->floatmargins['L']) && $usey <= $this->floatmargins['L']['y1'] && $usey >= $this->floatmargins['L']['y0'] && !$this->floatmargins['L']['skipline']) { $fpaddingL += $this->floatmargins['L']['w']; }
4763 /*-- END CSS-IMAGE-FLOAT --*/
4764 } // *TABLES*
4765
4766 // Set Current lineheight (correction factor)
4767 $lhfixed = false;
4768 /*-- LISTS --*/
4769 if ($is_list) {
4770 if (preg_match('/([0-9.,]+)mm/',$this->list_lineheight[$this->listlvl][$this->listOcc],$am)) {
4771 $lhfixed = true;
4772 $def_fontsize = $this->InlineProperties['LISTITEM'][$this->listlvl][$this->listOcc][$this->listnum]['size'];
4773 $this->lineheight_correction = $am[1] / $def_fontsize ;
4774 }
4775 else {
4776 $this->lineheight_correction = $this->list_lineheight[$this->listlvl][$this->listOcc];
4777 }
4778 }
4779 else
4780 /*-- END LISTS --*/
4781 /*-- TABLES --*/
4782 if ($is_table) {
4783 if (preg_match('/([0-9.,]+)mm/',$this->table_lineheight,$am)) {
4784 $lhfixed = true;
4785 $def_fontsize = $this->FontSize; // needs to be default font-size for block ****
4786 $this->lineheight_correction = $lineHeight / $def_fontsize ;
4787 }
4788 else {
4789 $this->lineheight_correction = $this->table_lineheight;
4790 }
4791 }
4792 else
4793 /*-- END TABLES --*/
4794 if (isset($this->blk[$this->blklvl]['line_height']) && $this->blk[$this->blklvl]['line_height']) {
4795 if (preg_match('/([0-9.,]+)mm/',$this->blk[$this->blklvl]['line_height'],$am)) {
4796 $lhfixed = true;
4797 $def_fontsize = $this->blk[$this->blklvl]['InlineProperties']['size']; // needs to be default font-size for block ****
4798 $this->lineheight_correction = $am[1] / $def_fontsize ;
4799 }
4800 else {
4801 $this->lineheight_correction = $this->blk[$this->blklvl]['line_height'];
4802 }
4803 }
4804 else {
4805 $this->lineheight_correction = $this->normalLineheight;
4806 }
4807
4808 // correct lineheight to maximum fontsize
4809 if ($lhfixed) { $maxlineHeight = $this->lineheight; }
4810 else { $maxlineHeight = 0; }
4811 $this->forceExactLineheight = true;
4812 $maxfontsize = 0;
4813 // While we're at it, check if contains cursive text
4814 $checkCursive=false;
4815 if ($this->biDirectional) { $checkCursive=true; } // *RTL*
4816 foreach ( $content as $k => $chunk )
4817 {
4818 $this->restoreFont( $font[ $k ],false );
4819 if (!isset($this->objectbuffer[$k])) {
4820 // Soft Hyphens chr(173)
4821 if (!$this->usingCoreFont) {
4822 $content[$k] = $chunk = str_replace("\xc2\xad",'',$chunk );
4823 if (isset($this->CurrentFont['indic']) && $this->CurrentFont['indic']) { $checkCursive=true; } // *INDIC*
4824 }
4825 else if ($this->FontFamily!='csymbol' && $this->FontFamily!='czapfdingbats') {
4826 $content[$k] = $chunk = str_replace(chr(173),'',$chunk );
4827 }
4828 // Special case of sub/sup carried over on its own to last line
4829 if (($this->SUB || $this->SUP) && count($content)==1) { $actfs = $this->FontSize*100/55; } // 55% is font change for sub/sup
4830 else { $actfs = $this->FontSize; }
4831 if (!$lhfixed) { $maxlineHeight = max($maxlineHeight,$actfs * $this->lineheight_correction ); }
4832 if ($lhfixed && ($actfs > $def_fontsize || ($actfs > ($lineHeight * $this->lineheight_correction) && $is_list))) {
4833 $this->forceExactLineheight = false;
4834 }
4835 $maxfontsize = max($maxfontsize,$actfs);
4836 }
4837 }
4838
4839 if(isset($font[count($font)-1])) {
4840 $lastfontreqstyle = $font[count($font)-1]['ReqFontStyle'];
4841 $lastfontstyle = $font[count($font)-1]['style'];
4842 }
4843 else {
4844 $lastfontreqstyle=null;
4845 $lastfontstyle=null;
4846 }
4847 if ($blockdir == 'ltr' && strpos($lastfontreqstyle,"I") !== false && strpos($lastfontstyle,"I") === false) { // Artificial italic
4848 $lastitalic = $this->FontSize*0.15*_MPDFK;
4849 }
4850 else { $lastitalic = 0; }
4851
4852
4853 /*-- LISTS --*/
4854 if ($is_list && is_array($this->bulletarray) && count($this->bulletarray)) {
4855 $actfs = $this->bulletarray['fontsize'];
4856 if (!$lhfixed) { $maxlineHeight = max($maxlineHeight,$actfs * $this->lineheight_correction ); }
4857 if ($lhfixed && $actfs > $def_fontsize) { $this->forceExactLineheight = false; }
4858 $maxfontsize = max($maxfontsize,$actfs);
4859 }
4860 /*-- END LISTS --*/
4861
4862 // when every text item checked i.e. $maxfontsize is set properly
4863
4864 $af = 0; // Above font
4865 $bf = 0; // Below font
4866 $mta = 0; // Maximum top-aligned
4867 $mba = 0; // Maximum bottom-aligned
4868
4869 foreach ( $content as $k => $chunk )
4870 {
4871 if (isset($this->objectbuffer[$k])) {
4872 $oh = $this->objectbuffer[$k]['OUTER-HEIGHT'];
4873 $va = $this->objectbuffer[$k]['vertical-align']; // = $objattr['vertical-align'] = set as M,T,B,S
4874 if ($lhfixed && $oh > $def_fontsize) { $this->forceExactLineheight = false; }
4875
4876 if ($va == 'BS') { // (BASELINE default)
4877 $af = max($af, ($oh - ($maxfontsize * (0.5 + $this->baselineC))));
4878 }
4879 else if ($va == 'M') {
4880 $af = max($af, ($oh - $maxfontsize)/2);
4881 $bf = max($bf, ($oh - $maxfontsize)/2);
4882 }
4883 else if ($va == 'TT') {
4884 $bf = max($bf, ($oh - $maxfontsize));
4885 }
4886 else if ($va == 'TB') {
4887 $af = max($af, ($oh - $maxfontsize));
4888 }
4889 else if ($va == 'T') {
4890 $mta = max($mta, $oh);
4891 }
4892 else if ($va == 'B') {
4893 $mba = max($mba, $oh);
4894 }
4895 }
4896 }
4897 if ((!$lhfixed || !$this->forceExactLineheight) && ($af > (($maxlineHeight - $maxfontsize)/2) || $bf > (($maxlineHeight - $maxfontsize)/2))) {
4898 $maxlineHeight = $maxfontsize + $af + $bf;
4899 }
4900 else if (!$lhfixed) { $af = $bf = ($maxlineHeight - $maxfontsize)/2; }
4901 if ($mta > $maxlineHeight) {
4902 $bf += ($mta - $maxlineHeight);
4903 $maxlineHeight = $mta;
4904 }
4905 if ($mba > $maxlineHeight) {
4906 $af += ($mba - $maxlineHeight);
4907 $maxlineHeight = $mba;
4908 }
4909
4910 $lineHeight = $maxlineHeight;
4911 // If NOT images, and maxfontsize NOT > lineHeight - this value determines text baseline positioning
4912 if ($lhfixed && $af==0 && $bf==0 && $maxfontsize<=($def_fontsize * $this->lineheight_correction * 0.8 )) {
4913 $this->linemaxfontsize = $def_fontsize;
4914 }
4915 else { $this->linemaxfontsize = $maxfontsize; }
4916
4917 // Get PAGEBREAK TO TEST for height including the bottom border/padding
4918 $check_h = max($this->divheight,$lineHeight);
4919
4920 // This fixes a proven bug...
4921 if ($endofblock && $newblock && $blockstate==0 && !$content) { $check_h = 0; }
4922 // but ? needs to fix potentially more widespread...
4923 // if (!$content) { $check_h = 0; }
4924
4925 if ($this->blklvl > 0 && !$is_table) {
4926 if ($endofblock && $blockstate > 1) {
4927 if ($this->blk[$this->blklvl]['page_break_after_avoid']) { $check_h += $lineHeight; }
4928 $check_h += ($this->blk[$this->blklvl]['padding_bottom'] + $this->blk[$this->blklvl]['border_bottom']['w']);
4929 }
4930 // mPDF 5.4.03
4931 if (($newblock && ($blockstate==1 || $blockstate==3) && $lineCount == 0) || ($endofblock && $blockstate ==3 && $lineCount == 0)) {
4932 $check_h += ($this->blk[$this->blklvl]['padding_top'] + $this->blk[$this->blklvl]['margin_top'] + $this->blk[$this->blklvl]['border_top']['w']);
4933 }
4934 }
4935
4936 // Force PAGE break if column height cannot take check-height
4937 if ($this->ColActive && $check_h > ($this->PageBreakTrigger - $this->y0)) {
4938 $this->SetCol($this->NbCol-1);
4939 }
4940
4941 // mPDF 5.4.04
4942 // Avoid just border/background-color moved on to next page
4943 if ($endofblock && $blockstate > 1 && !$content) { $buff = $this->margBuffer; }
4944 else { $buff = 0; }
4945
4946
4947 // PAGEBREAK
4948 // mPDF 5.4.04
4949 if(!$is_table && ($this->y+$check_h) > ($this->PageBreakTrigger + $buff) and !$this->InFooter and $this->AcceptPageBreak()) {
4950 $bak_x=$this->x;//Current X position
4951 // WORD SPACING
4952 $ws=$this->ws;//Word Spacing
4953 $charspacing=$this->charspacing;//Character Spacing
4954 $this->ResetSpacing();
4955
4956 $this->AddPage($this->CurOrientation);
4957
4958 $this->x=$bak_x;
4959 // Added to correct for OddEven Margins
4960 $currentx += $this->MarginCorrection;
4961 $this->x += $this->MarginCorrection;
4962
4963 // WORD SPACING
4964 $this->SetSpacing($charspacing,$ws);
4965 }
4966
4967 if ($this->keep_block_together && !$is_table && $this->kt_p00 < $this->page && ($this->y+$check_h) > $this->kt_y00) {
4968 $this->printdivbuffer();
4969 $this->keep_block_together = 0;
4970 }
4971
4972 /*-- COLUMNS --*/
4973 // COLS
4974 // COLUMN CHANGE
4975 if ($this->CurrCol != $oldcolumn) {
4976 $currentx += $this->ChangeColumn * ($this->ColWidth+$this->ColGap);
4977 $this->x += $this->ChangeColumn * ($this->ColWidth+$this->ColGap);
4978 $oldcolumn = $this->CurrCol;
4979 }
4980
4981
4982 if ($this->ColActive && !$is_table) { $this->breakpoints[$this->CurrCol][] = $this->y; }
4983 /*-- END COLUMNS --*/
4984
4985 // TOP MARGIN
4986 if ($newblock && ($blockstate==1 || $blockstate==3) && ($this->blk[$this->blklvl]['margin_top']) && $lineCount == 0 && !$is_table && !$is_list) {
4987 $this->DivLn($this->blk[$this->blklvl]['margin_top'],$this->blklvl-1,true,$this->blk[$this->blklvl]['margin_collapse']);
4988 if ($this->ColActive) { $this->breakpoints[$this->CurrCol][] = $this->y; } // *COLUMNS*
4989 }
4990
4991 if ($newblock && ($blockstate==1 || $blockstate==3) && $lineCount == 0 && !$is_table && !$is_list) {
4992 $this->blk[$this->blklvl]['y0'] = $this->y;
4993 $this->blk[$this->blklvl]['startpage'] = $this->page;
4994 if ($this->blk[$this->blklvl]['float']) { $this->blk[$this->blklvl]['float_start_y'] = $this->y; } // mPDF 5.6.63
4995 if ($this->ColActive) { $this->breakpoints[$this->CurrCol][] = $this->y; } // *COLUMNS*
4996 }
4997
4998 // ADDED for Paragraph_indent
4999 $WidthCorrection = 0;
5000 if (($newblock) && ($blockstate==1 || $blockstate==3) && isset($this->blk[$this->blklvl]['text_indent']) && ($lineCount == 0) && (!$is_table) && (!$is_list) && ($align != 'C')) {
5001 $ti = $this->ConvertSize($this->blk[$this->blklvl]['text_indent'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
5002 $WidthCorrection = ($ti*_MPDFK);
5003 }
5004
5005
5006 // PADDING and BORDER spacing/fill
5007 if (($newblock) && ($blockstate==1 || $blockstate==3) && (($this->blk[$this->blklvl]['padding_top']) || ($this->blk[$this->blklvl]['border_top'])) && ($lineCount == 0) && (!$is_table) && (!$is_list)) {
5008 // $state = 0 normal; 1 top; 2 bottom; 3 top and bottom
5009 $this->DivLn($this->blk[$this->blklvl]['padding_top'] + $this->blk[$this->blklvl]['border_top']['w'],-3,true,false,1);
5010 if ($this->ColActive) { $this->breakpoints[$this->CurrCol][] = $this->y; } // *COLUMNS*
5011 $this->x = $currentx;
5012 }
5013
5014
5015 // Added mPDF 3.0 Float DIV
5016 $fpaddingR = 0;
5017 $fpaddingL = 0;
5018 /*-- CSS-FLOAT --*/
5019 if (count($this->floatDivs)) {
5020 list($l_exists, $r_exists, $l_max, $r_max, $l_width, $r_width) = $this->GetFloatDivInfo($this->blklvl);
5021 if ($r_exists) { $fpaddingR = $r_width; }
5022 if ($l_exists) { $fpaddingL = $l_width; }
5023 }
5024 /*-- END CSS-FLOAT --*/
5025
5026 $usey = $this->y + 0.002;
5027 if (($newblock) && ($blockstate==1 || $blockstate==3) && ($lineCount == 0) ) {
5028 $usey += $this->blk[$this->blklvl]['margin_top'] + $this->blk[$this->blklvl]['padding_top'] + $this->blk[$this->blklvl]['border_top']['w'];
5029 }
5030 /*-- CSS-IMAGE-FLOAT --*/
5031 // If float exists at this level
5032 if (isset($this->floatmargins['R']) && $usey <= $this->floatmargins['R']['y1'] && $usey >= $this->floatmargins['R']['y0'] && !$this->floatmargins['R']['skipline']) { $fpaddingR += $this->floatmargins['R']['w']; }
5033 if (isset($this->floatmargins['L']) && $usey <= $this->floatmargins['L']['y1'] && $usey >= $this->floatmargins['L']['y0'] && !$this->floatmargins['L']['skipline']) { $fpaddingL += $this->floatmargins['L']['w']; }
5034 /*-- END CSS-IMAGE-FLOAT --*/
5035
5036 if ($content) {
5037
5038 // In FinishFlowing Block no lines are justified as it is always last line
5039 // but if CJKorphan has allowed content width to go over max width, use J charspacing to compress line
5040 // JUSTIFICATION J - NOT!
5041 $nb_carac = 0;
5042 $nb_spaces = 0;
5043 $jcharspacing = 0;
5044 $jws = 0;
5045 $inclCursive=false;
5046 $dottab = false; // mPDF 5.6.19
5047 foreach ( $content as $k => $chunk ) {
5048 if (!isset($this->objectbuffer[$k]) || (isset($this->objectbuffer[$k]) && !$this->objectbuffer[$k])) {
5049 if ($this->usingCoreFont) {
5050 $chunk = str_replace(chr(160),chr(32),$chunk );
5051 }
5052 else {
5053 $chunk = str_replace(chr(194).chr(160),chr(32),$chunk );
5054 }
5055 $nb_carac += mb_strlen( $chunk, $this->mb_enc );
5056 $nb_spaces += mb_substr_count( $chunk,' ', $this->mb_enc );
5057 if ($checkCursive) {
5058 if (preg_match("/([".$this->pregRTLchars."])/u", $chunk)) { $inclCursive = true; } // *RTL*
5059 if (preg_match("/([".$this->pregHIchars.$this->pregBNchars.$this->pregPAchars."])/u", $chunk)) { $inclCursive = true; } // *INDIC*
5060 }
5061 }
5062 else if ($this->objectbuffer[$k]['type']=='dottab') { $dottab = $this->objectbuffer[$k]['outdent']; } // mPDF 5.6.19
5063 }
5064 // if it's justified, we need to find the char/word spacing (or if orphans have allowed length of line to go over the maxwidth)
5065 // If "orphans" in fact is just a final space - ignore this
5066 // mPDF 5.6.40
5067 $lastchar = mb_substr($content[(count($content)-1)],mb_strlen($content[(count($content)-1)], $this->mb_enc)-1, 1, $this->mb_enc);
5068 if (preg_match("/[".$this->CJKoverflow."]/u", $lastchar)) { $CJKoverflow = true; }
5069 else {$CJKoverflow = false; }
5070 if ((((($contentWidth + $lastitalic) > $maxWidth) && ($content[count($content)-1] != ' ') ) ||
5071 (!$endofblock && $align=='J' && ($next=='image' || $next=='select' || $next=='input' || $next=='textarea' || ($next=='br' && $this->justifyB4br)))) && !($CJKoverflow && $this->allowCJKoverflow) ) { // mPDF 5.6.40
5072 // WORD SPACING
5073 list($jcharspacing,$jws) = $this->GetJspacing($nb_carac,$nb_spaces,($maxWidth-$lastitalic-$contentWidth-$WidthCorrection-(($this->cMarginL+$this->cMarginR)*_MPDFK)-($paddingL+$paddingR +(($fpaddingL + $fpaddingR) * _MPDFK) )),$inclCursive);
5074 }
5075 /*-- CJK-FONTS --*/
5076 // mPDF 5.6.40
5077 else if ($this->checkCJK && $align=='J' && $CJKoverflow && $this->allowCJKoverflow && $this->CJKforceend) {
5078 // force-end overhang
5079 $hanger = mb_substr($content[count($content)-1],mb_strlen($content[count($content)-1],$this->mb_enc)-1,1,$this->mb_enc );
5080 if (preg_match("/[".$this->CJKoverflow."]/u", $hanger)) {
5081 $content[count($content)-1] = mb_substr($content[count($content)-1],0,mb_strlen($content[count($content)-1],$this->mb_enc)-1,$this->mb_enc );
5082 $this->restoreFont( $font[ count($content)-1 ],false );
5083 $contentWidth -= $this->GetStringWidth($hanger) * _MPDFK;
5084 $nb_carac -= 1;
5085 list($jcharspacing,$jws) = $this->GetJspacing($nb_carac,$nb_spaces,($maxWidth-$lastitalic-$contentWidth-$WidthCorrection-(($this->cMarginL+$this->cMarginR)*_MPDFK)-($paddingL+$paddingR +(($fpaddingL + $fpaddingR) * _MPDFK) )),$inclCursive);
5086 }
5087 }
5088 /*-- END CJK-FONTS --*/
5089
5090 // Check if will fit at word/char spacing of previous line - if so continue it
5091 // but only allow a maximum of $this->jSmaxWordLast and $this->jSmaxCharLast
5092 else if ($contentWidth < ($maxWidth - $lastitalic-$WidthCorrection - (($this->cMarginL+$this->cMarginR)* _MPDFK) - ($paddingL+$paddingR +(($fpaddingL + $fpaddingR) * _MPDFK))) && !$this->fixedlSpacing) {
5093 if ($this->ws > $this->jSmaxWordLast) {
5094 $jws = $this->jSmaxWordLast;
5095 }
5096 if ($this->charspacing > $this->jSmaxCharLast) {
5097 $jcharspacing = $this->jSmaxCharLast;
5098 }
5099 $check = $maxWidth - $lastitalic-$WidthCorrection - $contentWidth - (($this->cMarginL+$this->cMarginR)* _MPDFK) - ($paddingL+$paddingR +(($fpaddingL + $fpaddingR) * _MPDFK) ) - ( $jcharspacing * $nb_carac) - ( $jws * $nb_spaces);
5100 if ($check <= 0) {
5101 $jcharspacing = 0;
5102 $jws = 0;
5103 }
5104 }
5105
5106 $empty = $maxWidth - $lastitalic-$WidthCorrection - $contentWidth - (($this->cMarginL+$this->cMarginR)* _MPDFK) - ($paddingL+$paddingR +(($fpaddingL + $fpaddingR) * _MPDFK) );
5107
5108 $empty -= ($jcharspacing * $nb_carac);
5109 $empty -= ($jws * $nb_spaces);
5110
5111 $empty /= _MPDFK;
5112
5113 if (!$is_table) {
5114 $this->maxPosR = max($this->maxPosR , ($this->w - $this->rMargin - $this->blk[$this->blklvl]['outer_right_margin'] - $empty));
5115 $this->maxPosL = min($this->maxPosL , ($this->lMargin + $this->blk[$this->blklvl]['outer_left_margin'] + $empty));
5116 }
5117
5118 $arraysize = count($content);
5119
5120 $margins = ($this->cMarginL+$this->cMarginR) + ($ipaddingL+$ipaddingR + $fpaddingR + $fpaddingR );
5121
5122 if (!$is_table) { $this->DivLn($lineHeight,$this->blklvl,false); } // false -> don't advance y
5123
5124 // DIRECTIONALITY RTL
5125 $all_rtl = false;
5126 $contains_rtl = false;
5127 /*-- RTL --*/
5128 if ($blockdir == 'rtl' || $this->biDirectional) {
5129 $all_rtl = true;
5130 foreach ( $content as $k => $chunk ) {
5131 $reversed = $this->magic_reverse_dir($chunk, false, $blockdir);
5132 if ($reversed > 0) { $contains_rtl = true; }
5133 if ($reversed < 2) { $all_rtl = false; }
5134 $content[$k] = $chunk;
5135 }
5136 if (($blockdir =='rtl' && $contains_rtl) || $all_rtl) {
5137 $content = array_reverse($content,false);
5138 $contentB = array_reverse($contentB,false);
5139 }
5140 }
5141 /*-- END RTL --*/
5142
5143 $this->x = $currentx + $this->cMarginL + $ipaddingL + $fpaddingL;
5144 if ($dottab !== false && $blockdir=='rtl') { $this->x -= $dottab; } // mPDF 5.6.19
5145 else if ($align == 'R') { $this->x += $empty; }
5146 else if ($align == 'J' && $blockdir == 'rtl') { $this->x += $empty; }
5147 else if ($align == 'C') { $this->x += ($empty / 2); }
5148
5149 // Paragraph INDENT
5150 $WidthCorrection = 0;
5151 if (($newblock) && ($blockstate==1 || $blockstate==3) && isset($this->blk[$this->blklvl]['text_indent']) && ($lineCount == 0) && (!$is_table) && (!$is_list) && ($align !='C')) {
5152 $ti = $this->ConvertSize($this->blk[$this->blklvl]['text_indent'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
5153 $this->x += $ti;
5154 }
5155
5156
5157 foreach ( $content as $k => $chunk )
5158 {
5159
5160 // FOR IMAGES
5161 if ((($blockdir == 'rtl') && ($contains_rtl )) || $all_rtl ) { $dirk = $arraysize-1 - $k; } else { $dirk = $k; }
5162
5163 $va = 'M'; // default for text
5164 if (isset($this->objectbuffer[$dirk]) && $this->objectbuffer[$dirk]) {
5165 $xadj = $this->x - $this->objectbuffer[$dirk]['OUTER-X'];
5166 $this->objectbuffer[$dirk]['OUTER-X'] += $xadj;
5167 $this->objectbuffer[$dirk]['BORDER-X'] += $xadj;
5168 $this->objectbuffer[$dirk]['INNER-X'] += $xadj;
5169 $va = $this->objectbuffer[$dirk]['vertical-align'];
5170 $yadj = $this->y - $this->objectbuffer[$dirk]['OUTER-Y'];
5171 if ($va == 'BS') {
5172 $yadj += $af + ($this->linemaxfontsize * (0.5 + $this->baselineC)) - $this->objectbuffer[$dirk]['OUTER-HEIGHT'];
5173 }
5174 else if ($va == 'M' || $va == '') {
5175 $yadj += $af + ($this->linemaxfontsize /2) - ($this->objectbuffer[$dirk]['OUTER-HEIGHT']/2);
5176 }
5177 else if ($va == 'TB') {
5178 $yadj += $af + $this->linemaxfontsize - $this->objectbuffer[$dirk]['OUTER-HEIGHT'];
5179 }
5180 else if ($va == 'TT') {
5181 $yadj += $af;
5182 }
5183 else if ($va == 'B') {
5184 $yadj += $af + $this->linemaxfontsize + $bf - $this->objectbuffer[$dirk]['OUTER-HEIGHT'];
5185 }
5186 else if ($va == 'T') {
5187 $yadj += 0;
5188 }
5189 $this->objectbuffer[$dirk]['OUTER-Y'] += $yadj;
5190 $this->objectbuffer[$dirk]['BORDER-Y'] += $yadj;
5191 $this->objectbuffer[$dirk]['INNER-Y'] += $yadj;
5192 }
5193
5194
5195 // DIRECTIONALITY RTL
5196 if ((($blockdir == 'rtl') && ($contains_rtl )) || $all_rtl ) { $this->restoreFont( $font[ $arraysize-1 - $k ] ); }
5197 else { $this->restoreFont( $font[ $k ] ); }
5198
5199 // mPDF 5.6.13 Decimal alignment - set in _tableWrite
5200 if ($is_table && substr($align,0,1)=='D' && $k==0 ) {
5201 $dp = $this->decimal_align[substr($align,0,2)];
5202 $s = preg_split('/'.preg_quote($dp,'/').'/', $content[0], 2); // ? needs to be /u if not core
5203 $s0 = $this->GetStringWidth($s[0], false);
5204 $this->x += ($this->decimal_offset - $s0);
5205 }
5206
5207 $this->SetSpacing(($this->fixedlSpacing*_MPDFK)+$jcharspacing,($this->fixedlSpacing+$this->minwSpacing)*_MPDFK+$jws);
5208 $this->fixedlSpacing = false;
5209 $this->minwSpacing = 0;
5210
5211 // mPDF 5.6.26
5212 $save_vis = $this->visibility;
5213 if (isset($this->textparam['visibility']) && $this->textparam['visibility'] && $this->textparam['visibility'] != $this->visibility) {
5214 $this->SetVisibility($this->textparam['visibility']);
5215 }
5216
5217 // *********** SPAN BACKGROUND COLOR ***************** //
5218 if (isset($this->spanbgcolor) && $this->spanbgcolor) {
5219 $cor = $this->spanbgcolorarray;
5220 $this->SetFColor($cor);
5221 $save_fill = $fill; $spanfill = 1; $fill = 1;
5222 }
5223 if (!empty($this->spanborddet)) {
5224 if (strpos($contentB[$k],'L')!==false && isset($this->spanborddet['L'])) $this->x += $this->spanborddet['L']['w'];
5225 if (strpos($contentB[$k],'L')===false) $this->spanborddet['L']['s'] = $this->spanborddet['L']['w'] = 0;
5226 if (strpos($contentB[$k],'R')===false) $this->spanborddet['R']['s'] = $this->spanborddet['R']['w'] = 0;
5227 }
5228 // WORD SPACING
5229 $stringWidth = $this->GetStringWidth($chunk ) + ( $this->charspacing * mb_strlen($chunk,$this->mb_enc ) / _MPDFK )
5230 + ( $this->ws * mb_substr_count($chunk,' ',$this->mb_enc ) / _MPDFK );
5231 if (isset($this->objectbuffer[$dirk])) {
5232 if ($this->objectbuffer[$dirk]['type']=='dottab') {
5233 $this->objectbuffer[$dirk]['OUTER-WIDTH'] +=$empty;
5234 $this->objectbuffer[$dirk]['OUTER-WIDTH'] +=$this->objectbuffer[$dirk]['outdent']; // mPDF 5.6.19
5235 }
5236 $stringWidth = $this->objectbuffer[$dirk]['OUTER-WIDTH'];
5237 }
5238
5239 if ($stringWidth==0) { $stringWidth = 0.000001; }
5240 if ($k == $arraysize-1) {
5241 // mPDF 5.6.40
5242 if ($this->checkCJK && $CJKoverflow && $align=='J' && $this->allowCJKoverflow && $hanger && $this->CJKforceend) {
5243 // force-end overhang
5244 $this->Cell( $stringWidth, $lineHeight, $chunk, '', 0, '', $fill, $this->HREF, $currentx,0,0,'M', $fill, $af, $bf, true );
5245 $this->Cell( $this->GetStringWidth($hanger), $lineHeight, $hanger, '', 1, '', $fill, $this->HREF, $currentx,0,0,'M', $fill, $af, $bf, true );
5246 }
5247 else {
5248 $this->Cell( $stringWidth, $lineHeight, $chunk, '', 1, '', $fill, $this->HREF, $currentx,0,0,'M', $fill, $af, $bf, true );
5249 }
5250 }
5251 else $this->Cell( $stringWidth, $lineHeight, $chunk, '', 0, '', $fill, $this->HREF, 0, 0,0,'M', $fill, $af, $bf, true );//first or middle part
5252
5253
5254 if (!empty($this->spanborddet)) {
5255 if (strpos($contentB[$k],'R')!==false && $k != $arraysize-1) $this->x += $this->spanborddet['R']['w'];
5256 }
5257 // *********** SPAN BACKGROUND COLOR OFF - RESET BLOCK BGCOLOR ***************** //
5258 if (isset($spanfill) && $spanfill) {
5259 $fill = $save_fill; $spanfill = 0;
5260 if ($fill) { $this->SetFColor($bcor); }
5261 }
5262 // mPDF 5.6.26
5263 if (isset($this->textparam['visibility']) && $this->textparam['visibility'] && $this->visibility != $save_vis) {
5264 $this->SetVisibility($save_vis);
5265 }
5266
5267 }
5268
5269 $this->printobjectbuffer($is_table, $blockdir);
5270
5271 $this->objectbuffer = array();
5272
5273 $this->ResetSpacing();
5274
5275 /*-- LISTS --*/
5276 // LIST BULLETS/NUMBERS
5277 if ($is_list && is_array($this->bulletarray) && ($lineCount == 0) ) {
5278
5279 $savedFont = $this->saveFont();
5280
5281 $bull = $this->bulletarray;
5282 if (isset($bull['level']) && isset($bull['occur']) && isset($this->InlineProperties['LIST'][$bull['level']][$bull['occur']])) {
5283 $this->restoreInlineProperties($this->InlineProperties['LIST'][$bull['level']][$bull['occur']]);
5284 }
5285 if (isset($bull['level']) && isset($bull['occur']) && isset($bull['num']) && isset($this->InlineProperties['LISTITEM'][$bull['level']][$bull['occur']][$bull['num']]) && $this->InlineProperties['LISTITEM'][$bull['level']][$bull['occur']][$bull['num']]) { $this->restoreInlineProperties($this->InlineProperties['LISTITEM'][$bull['level']][$bull['occur']][$bull['num']]); }
5286 if (isset($bull['font']) && $bull['font'] == 'czapfdingbats') {
5287 $this->bullet = true;
5288 $this->SetFont('czapfdingbats','',$this->FontSizePt/2.5);
5289 }
5290 else { $this->SetFont($this->FontFamily,$this->FontStyle,$this->FontSizePt,true,true); } // force output
5291 //Output bullet
5292 $this->x = $currentx;
5293 if (isset($bull['x'])) { $this->x += $bull['x']; }
5294 $this->y -= $lineHeight;
5295 if (isset($bull['col']) && $bull['col']) { $this->SetTColor($bull['col']); } // mPDF 5.6.67
5296
5297 if (isset($bull['txt'])) { $this->Cell($bull['w'], $lineHeight,$bull['txt'],'','',$bull['align'],0,'',0,-$this->cMarginL, -$this->cMarginR ); }
5298 if (isset($bull['font']) && $bull['font'] == 'czapfdingbats') {
5299 $this->bullet = false;
5300 }
5301 $this->x = $currentx; // Reset
5302 $this->y += $lineHeight;
5303
5304 if ($this->ColActive && !$is_table) { $this->breakpoints[$this->CurrCol][] = $this->y; } // *COLUMNS*
5305
5306 $this->restoreFont( $savedFont );
5307 // $font = array( $savedFont );
5308
5309 $this->bulletarray = array(); // prevents repeat of bullet/number if <li>....<br />.....</li>
5310 }
5311 /*-- END LISTS --*/
5312
5313
5314 } // END IF CONTENT
5315
5316 /*-- CSS-IMAGE-FLOAT --*/
5317 // Update values if set to skipline
5318 if ($this->floatmargins) { $this->_advanceFloatMargins(); }
5319
5320
5321 if ($endofblock && $blockstate>1) {
5322 // If float exists at this level
5323 if (isset($this->floatmargins['R']['y1'])) { $fry1 = $this->floatmargins['R']['y1']; }
5324 else { $fry1 = 0; }
5325 if (isset($this->floatmargins['L']['y1'])) { $fly1 = $this->floatmargins['L']['y1']; }
5326 else { $fly1 = 0; }
5327 if ($this->y < $fry1 || $this->y < $fly1) {
5328 $drop = max($fry1,$fly1) - $this->y;
5329 $this->DivLn($drop);
5330 $this->x = $currentx;
5331 }
5332 }
5333 /*-- END CSS-IMAGE-FLOAT --*/
5334
5335
5336 // PADDING and BORDER spacing/fill
5337 if ($endofblock && ($blockstate > 1) && ($this->blk[$this->blklvl]['padding_bottom'] || $this->blk[$this->blklvl]['border_bottom'] || $this->blk[$this->blklvl]['css_set_height']) && (!$is_table) && (!$is_list)) {
5338 // If CSS height set, extend bottom - if on same page as block started, and CSS HEIGHT > actual height,
5339 // and does not force pagebreak
5340 $extra = 0;
5341 if ($this->blk[$this->blklvl]['css_set_height'] && $this->blk[$this->blklvl]['startpage']==$this->page) {
5342 // predicted height
5343 $h1 = ($this->y-$this->blk[$this->blklvl]['y0']) + $this->blk[$this->blklvl]['padding_bottom'] + $this->blk[$this->blklvl]['border_bottom']['w'];
5344 if ($h1 < ($this->blk[$this->blklvl]['css_set_height']+$this->blk[$this->blklvl]['padding_bottom']+$this->blk[$this->blklvl]['padding_top'])) { $extra = ($this->blk[$this->blklvl]['css_set_height']+$this->blk[$this->blklvl]['padding_bottom']+$this->blk[$this->blklvl]['padding_top']) - $h1; }
5345 if($this->y + $this->blk[$this->blklvl]['padding_bottom'] + $this->blk[$this->blklvl]['border_bottom']['w'] + $extra > $this->PageBreakTrigger) {
5346 $extra = $this->PageBreakTrigger - ($this->y + $this->blk[$this->blklvl]['padding_bottom'] + $this->blk[$this->blklvl]['border_bottom']['w']);
5347 }
5348 }
5349
5350 // $state = 0 normal; 1 top; 2 bottom; 3 top and bottom
5351 $this->DivLn($this->blk[$this->blklvl]['padding_bottom'] + $this->blk[$this->blklvl]['border_bottom']['w'] + $extra,-3,true,false,2);
5352 $this->x = $currentx;
5353
5354 if ($this->ColActive) { $this->breakpoints[$this->CurrCol][] = $this->y; } // *COLUMNS*
5355
5356 }
5357
5358 // SET Bottom y1 of block (used for painting borders)
5359 if (($endofblock) && ($blockstate > 1) && (!$is_table) && (!$is_list)) {
5360 $this->blk[$this->blklvl]['y1'] = $this->y;
5361 }
5362
5363 // BOTTOM MARGIN
5364 if (($endofblock) && ($blockstate > 1) && ($this->blk[$this->blklvl]['margin_bottom']) && (!$is_table) && (!$is_list)) {
5365 if($this->y+$this->blk[$this->blklvl]['margin_bottom'] < $this->PageBreakTrigger and !$this->InFooter) {
5366 $this->DivLn($this->blk[$this->blklvl]['margin_bottom'],$this->blklvl-1,true,$this->blk[$this->blklvl]['margin_collapse']);
5367 if ($this->ColActive) { $this->breakpoints[$this->CurrCol][] = $this->y; } // *COLUMNS*
5368 }
5369 }
5370
5371 // Reset lineheight
5372 $lineHeight = $this->divheight;
5373 }
5374
5375
5376
5377
5378
5379 function printobjectbuffer($is_table=false, $blockdir=false) {
5380 if (!$blockdir) { $blockdir = $this->directionality; }
5381 if ($is_table && $this->shrin_k > 1) { $k = $this->shrin_k; }
5382 else { $k = 1; }
5383 $save_y = $this->y;
5384 $save_x = $this->x;
5385 $save_currentfontfamily = $this->FontFamily;
5386 $save_currentfontsize = $this->FontSizePt;
5387 $save_currentfontstyle = $this->FontStyle.($this->U ? 'U' : '').($this->S ? 'S' : '');
5388 if ($blockdir == 'rtl') { $rtlalign = 'R'; } else { $rtlalign = 'L'; }
5389 foreach ($this->objectbuffer AS $ib => $objattr) {
5390 if ($objattr['type'] == 'bookmark' || $objattr['type'] == 'indexentry' || $objattr['type'] == 'toc') {
5391 $x = $objattr['OUTER-X'];
5392 $y = $objattr['OUTER-Y'];
5393 $this->y = $y - $this->FontSize/2;
5394 $this->x = $x;
5395 if ($objattr['type'] == 'bookmark' ) { $this->Bookmark($objattr['CONTENT'],$objattr['bklevel'] ,$y - $this->FontSize); } // *BOOKMARKS*
5396 if ($objattr['type'] == 'indexentry') { $this->IndexEntry($objattr['CONTENT']); } // *INDEX*
5397 if ($objattr['type'] == 'toc') { $this->TOC_Entry($objattr['CONTENT'], $objattr['toclevel'], $objattr['toc_id']); } // *TOC*
5398 }
5399 /*-- ANNOTATIONS --*/
5400 else if ($objattr['type'] == 'annot') {
5401 if ($objattr['POS-X']) { $x = $objattr['POS-X']; }
5402 else if ($this->annotMargin<>0) { $x = -$objattr['OUTER-X']; }
5403 else { $x = $objattr['OUTER-X']; }
5404 if ($objattr['POS-Y']) { $y = $objattr['POS-Y']; }
5405 else { $y = $objattr['OUTER-Y'] - $this->FontSize/2; }
5406 // Create a dummy entry in the _out/columnBuffer with position sensitive data,
5407 // linking $y-1 in the Columnbuffer with entry in $this->columnAnnots
5408 // and when columns are split in length will not break annotation from current line
5409 $this->y = $y-1;
5410 $this->x = $x-1;
5411 $this->Line($x-1,$y-1,$x-1,$y-1);
5412 $this->Annotation($objattr['CONTENT'], $x , $y , $objattr['ICON'], $objattr['AUTHOR'], $objattr['SUBJECT'], $objattr['OPACITY'], $objattr['COLOR'], $objattr['POPUP'], $objattr['FILE']);
5413 }
5414 /*-- END ANNOTATIONS --*/
5415 else {
5416 $y = $objattr['OUTER-Y'];
5417 $x = $objattr['OUTER-X'];
5418 $w = $objattr['OUTER-WIDTH'];
5419 $h = $objattr['OUTER-HEIGHT'];
5420 if (isset($objattr['text'])) { $texto = $objattr['text']; }
5421 $this->y = $y;
5422 $this->x = $x;
5423 if (isset($objattr['fontfamily'])) { $this->SetFont($objattr['fontfamily'],'',$objattr['fontsize'] ); }
5424 }
5425
5426 // HR
5427 if ($objattr['type'] == 'hr') {
5428 $this->SetDColor($objattr['color']);
5429 switch($objattr['align']) {
5430 case 'C':
5431 $empty = $objattr['OUTER-WIDTH'] - $objattr['INNER-WIDTH'];
5432 $empty /= 2;
5433 $x += $empty;
5434 break;
5435 case 'R':
5436 $empty = $objattr['OUTER-WIDTH'] - $objattr['INNER-WIDTH'];
5437 $x += $empty;
5438 break;
5439 }
5440 $oldlinewidth = $this->LineWidth;
5441 $this->SetLineWidth($objattr['linewidth']/$k );
5442 $this->y += ($objattr['linewidth']/2) + $objattr['margin_top']/$k;
5443 $this->Line($x,$this->y,$x+$objattr['INNER-WIDTH'],$this->y);
5444 $this->SetLineWidth($oldlinewidth);
5445 $this->SetDColor($this->ConvertColor(0));
5446 }
5447 // IMAGE
5448 if ($objattr['type'] == 'image') {
5449 // mPDF 5.6.01 - LAYERS
5450 if (isset($objattr['z-index']) && $objattr['z-index'] > 0 && $this->currentlayer==0) {
5451 $this->BeginLayer($objattr['z-index']);
5452 }
5453 if(isset($objattr['visibility']) && $objattr['visibility']!='visible' && $objattr['visibility']) {
5454 $this->SetVisibility($objattr['visibility']);
5455 }
5456 if (isset($objattr['opacity'])) { $this->SetAlpha($objattr['opacity']); }
5457 $rotate = 0;
5458 $obiw = $objattr['INNER-WIDTH'];
5459 $obih = $objattr['INNER-HEIGHT'];
5460 $sx = $objattr['INNER-WIDTH']*_MPDFK / $objattr['orig_w'];
5461 $sy = abs($objattr['INNER-HEIGHT'])*_MPDFK / abs($objattr['orig_h']);
5462 $sx = ($objattr['INNER-WIDTH']*_MPDFK / $objattr['orig_w']);
5463 $sy = ($objattr['INNER-HEIGHT']*_MPDFK / $objattr['orig_h']);
5464
5465 if (isset($objattr['ROTATE'])) { $rotate = $objattr['ROTATE']; }
5466 if ($rotate==90) {
5467 // Clockwise
5468 $obiw = $objattr['INNER-HEIGHT'];
5469 $obih = $objattr['INNER-WIDTH'];
5470 $tr = $this->transformTranslate(0, -$objattr['INNER-WIDTH'], true) ;
5471 $tr .= ' '. $this->transformRotate(90, $objattr['INNER-X'],($objattr['INNER-Y'] +$objattr['INNER-WIDTH'] ),true) ;
5472 $sx = $obiw*_MPDFK / $objattr['orig_h'];
5473 $sy = $obih*_MPDFK / $objattr['orig_w'];
5474 }
5475 else if ($rotate==-90 || $rotate==270) {
5476 // AntiClockwise
5477 $obiw = $objattr['INNER-HEIGHT'];
5478 $obih = $objattr['INNER-WIDTH'];
5479 $tr = $this->transformTranslate($objattr['INNER-WIDTH'], ($objattr['INNER-HEIGHT']-$objattr['INNER-WIDTH']), true) ;
5480 $tr .= ' '. $this->transformRotate(-90, $objattr['INNER-X'],($objattr['INNER-Y'] +$objattr['INNER-WIDTH'] ),true) ;
5481 $sx = $obiw*_MPDFK / $objattr['orig_h'];
5482 $sy = $obih*_MPDFK / $objattr['orig_w'];
5483 }
5484 else if ($rotate==180) {
5485 // Mirror
5486 $tr = $this->transformTranslate($objattr['INNER-WIDTH'], -$objattr['INNER-HEIGHT'], true) ;
5487 $tr .= ' '. $this->transformRotate(180, $objattr['INNER-X'],($objattr['INNER-Y'] +$objattr['INNER-HEIGHT'] ),true) ;
5488 }
5489 else { $tr = ''; }
5490 $tr = trim($tr);
5491 if ($tr) { $tr .= ' '; }
5492 $gradmask = '';
5493
5494
5495 /*-- BACKGROUNDS --*/
5496 if (isset($objattr['GRADIENT-MASK'])) {
5497 $g = $this->grad->parseMozGradient( $objattr['GRADIENT-MASK'] );
5498 if ($g) {
5499 $dummy = $this->grad->Gradient($objattr['INNER-X'], $objattr['INNER-Y'], $obiw, $obih, $g['type'], $g['stops'], $g['colorspace'], $g['coords'], $g['extend'], true, true);
5500 $gradmask = '/TGS'.count($this->gradients).' gs ';
5501 // $this->_out("q ".$tr.$this->grad->Gradient($objattr['INNER-X'], $objattr['INNER-Y'], $obiw, $obih, $g['type'], $g['stops'], $g['colorspace'], $g['coords'], $g['extend'], true)." Q");
5502 }
5503 }
5504 /*-- END BACKGROUNDS --*/
5505 /*-- IMAGES-WMF --*/
5506 if (isset($objattr['itype']) && $objattr['itype']=='wmf') {
5507 $outstring = sprintf('q '.$tr.'%.3F 0 0 %.3F %.3F %.3F cm /FO%d Do Q', $sx, -$sy, $objattr['INNER-X']*_MPDFK-$sx*$objattr['wmf_x'], (($this->h-$objattr['INNER-Y'])*_MPDFK)+$sy*$objattr['wmf_y'], $objattr['ID']);
5508 }
5509 else
5510 /*-- END IMAGES-WMF --*/
5511 if (isset($objattr['itype']) && $objattr['itype']=='svg') {
5512 $outstring = sprintf('q '.$tr.'%.3F 0 0 %.3F %.3F %.3F cm /FO%d Do Q', $sx, -$sy, $objattr['INNER-X']*_MPDFK-$sx*$objattr['wmf_x'], (($this->h-$objattr['INNER-Y'])*_MPDFK)+$sy*$objattr['wmf_y'], $objattr['ID']);
5513 }
5514 else {
5515 $outstring = sprintf("q ".$tr."%.3F 0 0 %.3F %.3F %.3F cm ".$gradmask."/I%d Do Q",$obiw*_MPDFK, $obih*_MPDFK, $objattr['INNER-X'] *_MPDFK, ($this->h-($objattr['INNER-Y'] +$obih ))*_MPDFK,$objattr['ID'] );
5516 }
5517 $this->_out($outstring);
5518 // LINK
5519 if (isset($objattr['link'])) $this->Link($objattr['INNER-X'],$objattr['INNER-Y'],$objattr['INNER-WIDTH'],$objattr['INNER-HEIGHT'],$objattr['link']);
5520 if (isset($objattr['opacity'])) { $this->SetAlpha(1); }
5521 if ((isset($objattr['border_top']) && $objattr['border_top']>0) || (isset($objattr['border_left']) && $objattr['border_left']>0) || (isset($objattr['border_right']) && $objattr['border_right']>0) || (isset($objattr['border_bottom']) && $objattr['border_bottom']>0)) { $this->PaintImgBorder($objattr,$is_table); }
5522 if(isset($objattr['visibility']) && $objattr['visibility']!='visible' && $objattr['visibility']) {
5523 $this->SetVisibility('visible');
5524 }
5525 // mPDF 5.6.01 - LAYERS
5526 if (isset($objattr['z-index']) && $objattr['z-index'] > 0 && $this->currentlayer==0) {
5527 $this->EndLayer();
5528 }
5529
5530 }
5531
5532 /*-- BARCODES --*/
5533 // BARCODE
5534 if ($objattr['type'] == 'barcode') {
5535 $bgcol = $this->ConvertColor(255);
5536 if (isset($objattr['bgcolor']) && $objattr['bgcolor']) {
5537 $bgcol = $objattr['bgcolor'];
5538 }
5539 $col = $this->ConvertColor(0);
5540 if (isset($objattr['color']) && $objattr['color']) {
5541 $col = $objattr['color'];
5542 }
5543 $this->SetFColor($bgcol);
5544 $this->Rect($objattr['BORDER-X'], $objattr['BORDER-Y'], $objattr['BORDER-WIDTH'], $objattr['BORDER-HEIGHT'], 'F');
5545 $this->SetFColor($this->ConvertColor(255));
5546 if (isset($objattr['BORDER-WIDTH'])) { $this->PaintImgBorder($objattr,$is_table); }
5547 if ($objattr['btype'] == 'EAN13' || $objattr['btype'] == 'ISBN' || $objattr['btype'] == 'ISSN' || $objattr['btype'] == 'UPCA' || $objattr['btype'] == 'UPCE' || $objattr['btype'] == 'EAN8') {
5548 $this->WriteBarcode($objattr['code'], $objattr['showtext'], $objattr['INNER-X'], $objattr['INNER-Y'], $objattr['bsize'], 0, 0, 0, 0, 0, $objattr['bheight'], $bgcol, $col, $objattr['btype'], $objattr['bsupp'], $objattr['bsupp_code'], $k);
5549 }
5550 // QR-code
5551 else if ($objattr['btype']=='QR') {
5552 if (!class_exists('QRcode', false)) {
5553 include(_MPDF_PATH.'qrcode/qrcode.class.php');
5554 }
5555 $this->qrcode = new QRcode($objattr['code'], $objattr['errorlevel']);
5556 $this->qrcode->displayFPDF($this, $objattr['INNER-X'], $objattr['INNER-Y'], $objattr['bsize']*25, array(255,255,255), array(0,0,0));
5557 }
5558 else {
5559 $this->WriteBarcode2($objattr['code'], $objattr['INNER-X'], $objattr['INNER-Y'], $objattr['bsize'], $objattr['bheight'], $bgcol, $col, $objattr['btype'], $objattr['pr_ratio'], $k);
5560 }
5561 }
5562 /*-- END BARCODES --*/
5563
5564 // TEXT CIRCLE
5565 if ($objattr['type'] == 'textcircle') {
5566 $bgcol = ''; // mPDF 5.5.14
5567 if (isset($objattr['bgcolor']) && $objattr['bgcolor']) {
5568 $bgcol = $objattr['bgcolor'];
5569 }
5570 $col = $this->ConvertColor(0);
5571 if (isset($objattr['color']) && $objattr['color']) {
5572 $col = $objattr['color'];
5573 }
5574 $this->SetTColor($col);
5575 $this->SetFColor($bgcol);
5576 if ($bgcol) $this->Rect($objattr['BORDER-X'], $objattr['BORDER-Y'], $objattr['BORDER-WIDTH'], $objattr['BORDER-HEIGHT'], 'F'); // mPDF 5.5.14
5577 $this->SetFColor($this->ConvertColor(255));
5578 if (isset($objattr['BORDER-WIDTH'])) { $this->PaintImgBorder($objattr,$is_table); }
5579 if (!class_exists('directw', false)) { include(_MPDF_PATH.'classes/directw.php'); }
5580 if (empty($this->directw)) { $this->directw = new directw($this); }
5581 $save_lmfs = $this->linemaxfontsize;
5582 $this->linemaxfontsize = 0;
5583 if (isset($objattr['top-text'])) {
5584 $this->directw->CircularText($objattr['INNER-X']+$objattr['INNER-WIDTH']/2, $objattr['INNER-Y']+$objattr['INNER-HEIGHT']/2, $objattr['r']/$k, $objattr['top-text'], 'top', $objattr['fontfamily'], $objattr['fontsize']/$k, $objattr['fontstyle'], $objattr['space-width'], $objattr['char-width'], $objattr['divider']); // mPDF 5.5.23
5585 }
5586 if (isset($objattr['bottom-text'])) {
5587 $this->directw->CircularText($objattr['INNER-X']+$objattr['INNER-WIDTH']/2, $objattr['INNER-Y']+$objattr['INNER-HEIGHT']/2, $objattr['r']/$k, $objattr['bottom-text'], 'bottom', $objattr['fontfamily'], $objattr['fontsize']/$k, $objattr['fontstyle'], $objattr['space-width'], $objattr['char-width'], $objattr['divider']); // mPDF 5.5.23
5588 }
5589 $this->linemaxfontsize = $save_lmfs;
5590 }
5591
5592 $this->ResetSpacing();
5593
5594 // DOT-TAB
5595 if ($objattr['type'] == 'dottab') {
5596 // mPDF 5.6.19
5597 if (isset($objattr['fontfamily'])) { $this->SetFont($objattr['fontfamily'],'',$objattr['fontsize'] ); }
5598 $sp = $this->GetStringWidth(' ');
5599 $nb=floor(($w-2*$sp)/$this->GetStringWidth('.'));
5600 if ($nb>0) { $dots=' '.str_repeat('.',$nb).' '; }
5601 else { $dots=' '; }
5602 $col = $this->ConvertColor(0);
5603 if (isset($objattr['colorarray']) && ($objattr['colorarray'])) { // mPDF 5.6.19
5604 $col = $objattr['colorarray'];
5605 }
5606 $this->SetTColor($col);
5607 $save_dh = $this->divheight; // mPDF 5.6.19
5608 $save_sbd = $this->spanborddet;
5609 $save_u = $this->U;
5610 $save_s = $this->strike;
5611 $this->spanborddet = '';
5612 $this->divheight = 0; // mPDF 5.6.19
5613 $this->U = false;
5614 $this->strike = false;
5615 $this->Cell($w,$h,$dots,0,0,'C');
5616 $this->spanborddet = $save_sbd;
5617 $this->U = $save_u;
5618 $this->strike = $save_s;
5619 $this->divheight = $save_dh; // mPDF 5.6.19
5620 // mPDF 5.0
5621 $this->SetTColor($this->ConvertColor(0));
5622 }
5623
5624 /*-- FORMS --*/
5625 // TEXT/PASSWORD INPUT
5626 if ($objattr['type'] == 'input' && ($objattr['subtype'] == 'TEXT' || $objattr['subtype'] == 'PASSWORD')) {
5627 $this->form->print_ob_text($objattr,$w,$h,$texto,$rtlalign,$k,$blockdir);
5628 }
5629
5630 // TEXTAREA
5631 if ($objattr['type'] == 'textarea') {
5632 $this->form->print_ob_textarea($objattr,$w,$h,$texto,$rtlalign,$k,$blockdir);
5633 }
5634
5635 // SELECT
5636 if ($objattr['type'] == 'select') {
5637 $this->form->print_ob_select($objattr,$w,$h,$texto,$rtlalign,$k,$blockdir);
5638 }
5639
5640
5641 // INPUT/BUTTON as IMAGE
5642 if ($objattr['type'] == 'input' && $objattr['subtype'] == 'IMAGE') {
5643 $this->form->print_ob_imageinput($objattr,$w,$h,$texto,$rtlalign,$k,$blockdir);
5644 }
5645
5646 // BUTTON
5647 if ($objattr['type'] == 'input' && ($objattr['subtype'] == 'SUBMIT' || $objattr['subtype'] == 'RESET' || $objattr['subtype'] == 'BUTTON')) {
5648 $this->form->print_ob_button($objattr,$w,$h,$texto,$rtlalign,$k,$blockdir);
5649 }
5650
5651 // CHECKBOX
5652 if ($objattr['type'] == 'input' && ($objattr['subtype'] == 'CHECKBOX')) {
5653 $this->form->print_ob_checkbox($objattr,$w,$h,$texto,$rtlalign,$k,$blockdir,$x,$y);
5654 }
5655 // RADIO
5656 if ($objattr['type'] == 'input' && ($objattr['subtype'] == 'RADIO')) {
5657 $this->form->print_ob_radio($objattr,$w,$h,$texto,$rtlalign,$k,$blockdir,$x,$y);
5658 }
5659 /*-- END FORMS --*/
5660 }
5661 $this->SetFont($save_currentfontfamily,$save_currentfontstyle,$save_currentfontsize);
5662 $this->y = $save_y;
5663 $this->x = $save_x;
5664 unset($content);
5665 }
5666
5667
5668 function WriteFlowingBlock( $s)
5669 {
5670 $currentx = $this->x;
5671 $is_table = $this->flowingBlockAttr[ 'is_table' ];
5672 $is_list = $this->flowingBlockAttr[ 'is_list' ];
5673 // width of all the content so far in points
5674 $contentWidth =& $this->flowingBlockAttr[ 'contentWidth' ];
5675 // cell width in points
5676 $maxWidth =& $this->flowingBlockAttr[ 'width' ];
5677 $lineCount =& $this->flowingBlockAttr[ 'lineCount' ];
5678 // line height in user units
5679 $lineHeight =& $this->flowingBlockAttr[ 'height' ];
5680 $align =& $this->flowingBlockAttr[ 'align' ];
5681 $content =& $this->flowingBlockAttr[ 'content' ];
5682 $contentB =& $this->flowingBlockAttr[ 'contentB' ];
5683 $font =& $this->flowingBlockAttr[ 'font' ];
5684 $valign =& $this->flowingBlockAttr[ 'valign' ];
5685 $blockstate = $this->flowingBlockAttr[ 'blockstate' ];
5686
5687 $newblock = $this->flowingBlockAttr[ 'newblock' ];
5688 $blockdir = $this->flowingBlockAttr['blockdir'];
5689 // *********** BLOCK BACKGROUND COLOR ***************** //
5690 if ($this->blk[$this->blklvl]['bgcolor'] && !$is_table) {
5691 $fill = 0;
5692 }
5693 else {
5694 $this->SetFColor($this->ConvertColor(255));
5695 $fill = 0;
5696 }
5697 $font[] = $this->saveFont();
5698 $content[] = '';
5699 $contentB[] = '';
5700 $currContent =& $content[ count( $content ) - 1 ];
5701 // where the line should be cutoff if it is to be justified
5702 $cutoffWidth = $contentWidth;
5703
5704 $CJKoverflow = false;
5705 $hanger = ''; // mPDF 5.6.40
5706
5707 // COLS
5708 $oldcolumn = $this->CurrCol;
5709
5710 if ($this->ColActive && !$is_table) { $this->breakpoints[$this->CurrCol][] = $this->y; } // *COLUMNS*
5711
5712 /*-- TABLES --*/
5713 if ($is_table) {
5714 $ipaddingL = 0;
5715 $ipaddingR = 0;
5716 $paddingL = 0;
5717 $paddingR = 0;
5718 $cpaddingadjustL = 0;
5719 $cpaddingadjustR = 0;
5720 // Added mPDF 3.0
5721 $fpaddingR = 0;
5722 $fpaddingL = 0;
5723 }
5724 else {
5725 /*-- END TABLES --*/
5726 $ipaddingL = $this->blk[$this->blklvl]['padding_left'];
5727 $ipaddingR = $this->blk[$this->blklvl]['padding_right'];
5728 $paddingL = ($ipaddingL * _MPDFK);
5729 $paddingR = ($ipaddingR * _MPDFK);
5730 $this->cMarginL = $this->blk[$this->blklvl]['border_left']['w'];
5731 $cpaddingadjustL = -$this->cMarginL;
5732 $this->cMarginR = $this->blk[$this->blklvl]['border_right']['w'];
5733 $cpaddingadjustR = -$this->cMarginR;
5734 // Added mPDF 3.0 Float DIV
5735 $fpaddingR = 0;
5736 $fpaddingL = 0;
5737 /*-- CSS-FLOAT --*/
5738 if (count($this->floatDivs)) {
5739 list($l_exists, $r_exists, $l_max, $r_max, $l_width, $r_width) = $this->GetFloatDivInfo($this->blklvl);
5740 if ($r_exists) { $fpaddingR = $r_width; }
5741 if ($l_exists) { $fpaddingL = $l_width; }
5742 }
5743 /*-- END CSS-FLOAT --*/
5744
5745 $usey = $this->y + 0.002;
5746 if (($newblock) && ($blockstate==1 || $blockstate==3) && ($lineCount == 0) ) {
5747 $usey += $this->blk[$this->blklvl]['margin_top'] + $this->blk[$this->blklvl]['padding_top'] + $this->blk[$this->blklvl]['border_top']['w'];
5748 }
5749 /*-- CSS-IMAGE-FLOAT --*/
5750 // If float exists at this level
5751 if (isset($this->floatmargins['R']) && $usey <= $this->floatmargins['R']['y1'] && $usey >= $this->floatmargins['R']['y0'] && !$this->floatmargins['R']['skipline']) { $fpaddingR += $this->floatmargins['R']['w']; }
5752 if (isset($this->floatmargins['L']) && $usey <= $this->floatmargins['L']['y1'] && $usey >= $this->floatmargins['L']['y0'] && !$this->floatmargins['L']['skipline']) { $fpaddingL += $this->floatmargins['L']['w']; }
5753 /*-- END CSS-IMAGE-FLOAT --*/
5754 } // *TABLES*
5755
5756 //OBJECTS - IMAGES & FORM Elements (NB has already skipped line/page if required - in printbuffer)
5757 if (substr($s,0,3) == "\xbb\xa4\xac") { //identifier has been identified!
5758 $objattr = $this->_getObjAttr($s);
5759 $h_corr = 0;
5760 if ($is_table) { // *TABLES*
5761 $maximumW = ($maxWidth/_MPDFK) - ($this->cellPaddingL + $this->cMarginL + $this->cellPaddingR + $this->cMarginR); // *TABLES*
5762 } // *TABLES*
5763 else { // *TABLES*
5764 if (($newblock) && ($blockstate==1 || $blockstate==3) && ($lineCount == 0) && (!$is_table)) { $h_corr = $this->blk[$this->blklvl]['padding_top'] + $this->blk[$this->blklvl]['border_top']['w']; }
5765 $maximumW = ($maxWidth/_MPDFK) - ($this->blk[$this->blklvl]['padding_left'] + $this->blk[$this->blklvl]['border_left']['w'] + $this->blk[$this->blklvl]['padding_right'] + $this->blk[$this->blklvl]['border_right']['w'] + $fpaddingL + $fpaddingR );
5766 } // *TABLES*
5767 $objattr = $this->inlineObject($objattr['type'],$this->lMargin + $fpaddingL + ($contentWidth/_MPDFK),($this->y + $h_corr), $objattr, $this->lMargin,($contentWidth/_MPDFK),$maximumW,$lineHeight,true,$is_table);
5768
5769 // SET LINEHEIGHT for this line ================ RESET AT END
5770 $lineHeight = MAX($lineHeight,$objattr['OUTER-HEIGHT']);
5771 $this->objectbuffer[count($content)-1] = $objattr;
5772 // if (isset($objattr['vertical-align'])) { $valign = $objattr['vertical-align']; }
5773 // else { $valign = ''; }
5774 $contentWidth += ($objattr['OUTER-WIDTH'] * _MPDFK);
5775 return;
5776 }
5777
5778 $lbw = $rbw = 0; // Border widths
5779 if (!empty($this->spanborddet)) {
5780 if (isset($this->spanborddet['L'])) $lbw = $this->spanborddet['L']['w'];
5781 if (isset($this->spanborddet['R'])) $rbw = $this->spanborddet['R']['w'];
5782 }
5783
5784 if ($this->usingCoreFont) {
5785 $tmp = strlen( $s );
5786 }
5787 else {
5788 $tmp = mb_strlen( $s, $this->mb_enc );
5789 }
5790
5791 // for every character in the string
5792 for ( $i = 0; $i < $tmp; $i++ ) {
5793 // extract the current character
5794 // get the width of the character in points
5795 if ($this->usingCoreFont) {
5796 $c = $s[$i];
5797 // Soft Hyphens chr(173)
5798 $cw = ($this->GetCharWidthCore($c) * _MPDFK);
5799 if ($this->kerning && $this->useKerning && $i > 0) {
5800 if (isset($this->CurrentFont['kerninfo'][$s[($i-1)]][$c])) {
5801 $cw += ($this->CurrentFont['kerninfo'][$s[($i-1)]][$c] * $this->FontSizePt / 1000 );
5802 }
5803 }
5804 }
5805 else {
5806 $c = mb_substr($s,$i,1,$this->mb_enc );
5807 $cw = ($this->GetCharWidthNonCore($c, false) * _MPDFK);
5808 if ($this->kerning && $this->useKerning && $i > 0) {
5809 $lastc = mb_substr($s,($i-1),1,$this->mb_enc );
5810 $ulastc = $this->UTF8StringToArray($lastc, false);
5811 $uc = $this->UTF8StringToArray($c, false);
5812 if (isset($this->CurrentFont['kerninfo'][$ulastc[0]][$uc[0]])) {
5813 $cw += ($this->CurrentFont['kerninfo'][$ulastc[0]][$uc[0]] * $this->FontSizePt / 1000 );
5814 }
5815 }
5816 }
5817
5818 if ($i==0) {
5819 $cw += $lbw*_MPDFK;
5820 $contentB[(count($contentB)-1)] .= 'L';
5821 }
5822 if ($i==($tmp-1)) {
5823 $cw += $rbw*_MPDFK;
5824 $contentB[(count($contentB)-1)] .= 'R';
5825 }
5826 // mPDF 5.6.45
5827 if ($c==' ') {
5828 $currContent .= $c;
5829 $cutoffWidth = $contentWidth;
5830 $contentWidth += $cw;
5831 continue;
5832 }
5833
5834 // ADDED for Paragraph_indent
5835 $WidthCorrection = 0;
5836 if (($newblock) && ($blockstate==1 || $blockstate==3) && isset($this->blk[$this->blklvl]['text_indent']) && ($lineCount == 0) && (!$is_table) && (!$is_list) && ($align != 'C')) {
5837 $ti = $this->ConvertSize($this->blk[$this->blklvl]['text_indent'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
5838 $WidthCorrection = ($ti*_MPDFK);
5839 }
5840
5841 // Added mPDF 3.0 Float DIV
5842 $fpaddingR = 0;
5843 $fpaddingL = 0;
5844 /*-- CSS-FLOAT --*/
5845 if (count($this->floatDivs)) {
5846 list($l_exists, $r_exists, $l_max, $r_max, $l_width, $r_width) = $this->GetFloatDivInfo($this->blklvl);
5847 if ($r_exists) { $fpaddingR = $r_width; }
5848 if ($l_exists) { $fpaddingL = $l_width; }
5849 }
5850 /*-- END CSS-FLOAT --*/
5851
5852 $usey = $this->y + 0.002;
5853 if (($newblock) && ($blockstate==1 || $blockstate==3) && ($lineCount == 0) ) {
5854 $usey += $this->blk[$this->blklvl]['margin_top'] + $this->blk[$this->blklvl]['padding_top'] + $this->blk[$this->blklvl]['border_top']['w'];
5855 }
5856
5857 /*-- CSS-IMAGE-FLOAT --*/
5858 // If float exists at this level
5859 if (isset($this->floatmargins['R']) && $usey <= $this->floatmargins['R']['y1'] && $usey >= $this->floatmargins['R']['y0'] && !$this->floatmargins['R']['skipline']) { $fpaddingR += $this->floatmargins['R']['w']; }
5860 if (isset($this->floatmargins['L']) && $usey <= $this->floatmargins['L']['y1'] && $usey >= $this->floatmargins['L']['y0'] && !$this->floatmargins['L']['skipline']) { $fpaddingL += $this->floatmargins['L']['w']; }
5861 /*-- END CSS-IMAGE-FLOAT --*/
5862
5863
5864
5865 // try adding another char
5866 if (( $contentWidth + $cw > $maxWidth - $WidthCorrection - (($this->cMarginL+$this->cMarginR)*_MPDFK) - ($paddingL+$paddingR +(($fpaddingL + $fpaddingR) * _MPDFK) ) + 0.001)) {// 0.001 is to correct for deviations converting mm=>pts
5867 // it won't fit, output what we already have
5868 $lineCount++;
5869
5870 // contains any content that didn't make it into this print
5871 $savedContent = '';
5872 $savedContentB = '';
5873 $savedFont = array();
5874 $savedObj = array();
5875 // mPDF 5.6.20
5876 $savedPreContent = array();
5877 $savedPreContentB = array();
5878 $savedPreFont = array();
5879
5880 // cut off and save any partial words at the end of the string
5881 $words = explode( ' ', $currContent );
5882 ///////////////////
5883 // HYPHENATION
5884 $currWord = $words[count($words)-1] ;
5885 $success = false;
5886
5887 // mPDF 5.6.21 Hard Hyphens -
5888 $hardsuccess = false;
5889 if ($this->textparam['hyphens'] != 2 && preg_match("/\-/",$currWord)) {
5890 $rem = $maxWidth - $WidthCorrection - (($this->cMarginL+$this->cMarginR)*_MPDFK) - ($paddingL+$paddingR +(($fpaddingL + $fpaddingR) * _MPDFK) );
5891 list($hardsuccess,$pre,$post,$prelength) = $this->hardHyphenate($currWord, (($rem-$cutoffWidth)/_MPDFK -$this->GetCharWidth("-", false)) );
5892 if ($hardsuccess) {
5893 $already = array_pop( $words );
5894 $forward = mb_substr($already,$prelength+1,mb_strlen($already, $this->mb_enc), $this->mb_enc);
5895 $words[] = $pre.'-';
5896 $words[] = $forward;
5897 $currContent = mb_substr($currContent,0,mb_strlen($currContent, $this->mb_enc)+1-mb_strlen($post, $this->mb_enc), $this->mb_enc) . '-';
5898 }
5899 }
5900
5901 /*-- HYPHENATION --*/
5902 // Soft Hyphens chr(173)
5903 else if ($this->textparam['hyphens'] != 2 && (!$this->usingCoreFont && preg_match("/\xc2\xad/",$currWord)) || ($this->usingCoreFont && preg_match("/".chr(173)."/",$currWord) && ($this->FontFamily!='csymbol' && $this->FontFamily!='czapfdingbats')) ) { // mPDF 5.6.06
5904 $rem = $maxWidth - $WidthCorrection - (($this->cMarginL+$this->cMarginR)*_MPDFK) - ($paddingL+$paddingR +(($fpaddingL + $fpaddingR) * _MPDFK) );
5905 list($success,$pre,$post,$prelength) = $this->softHyphenate($currWord, (($rem-$cutoffWidth)/_MPDFK -$this->GetCharWidth(" ", false)) );
5906 }
5907
5908 if (!$success && !$hardsuccess && $this->textparam['hyphens'] == 1 ) { // mPDF 5.6.06 // mPDF 5.6.21
5909 // Look ahead to get current word
5910 for($ac = $i; $ac<(mb_strlen($s)-1); $ac++) {
5911 $addc = mb_substr($s,$ac,1,$this->mb_enc );
5912 if ($addc == ' ') { break; }
5913 $currWord .= $addc;
5914 }
5915 $rem = $maxWidth - $WidthCorrection - (($this->cMarginL+$this->cMarginR)*_MPDFK) - ($paddingL+$paddingR +(($fpaddingL + $fpaddingR) * _MPDFK) );
5916 list($success,$pre,$post,$prelength) = $this->hyphenateWord($currWord, (($rem-$cutoffWidth)/_MPDFK -$this->GetCharWidth(" ", false)) );
5917 }
5918 if ($success) {
5919 $already = array_pop( $words );
5920 $forward = mb_substr($already,$prelength,mb_strlen($already, $this->mb_enc), $this->mb_enc);
5921 $words[] = $pre.'-';
5922 $words[] = $forward;
5923 $currContent = mb_substr($currContent,0,mb_strlen($currContent, $this->mb_enc)+1-mb_strlen($post, $this->mb_enc), $this->mb_enc) . '-';
5924 }
5925 /*-- END HYPHENATION --*/
5926
5927 // mPDF 5.6.13 Decimal alignment (cancel if wraps to > 1 line)
5928 if ($is_table && substr($align,0,1)=='D' ) { $align=substr($align,2,1); }
5929
5930 /*-- CJK-FONTS --*/
5931 // mPDF 5.6.42
5932 if ($this->checkCJK) {
5933 $lastchar = mb_substr($words[(count($words)-1)],mb_strlen($words[(count($words)-1)], $this->mb_enc)-1, 1, $this->mb_enc);
5934 }
5935 // Next character is suitable to add as overhanging or squeezed punctuation
5936 if ($this->checkCJK && preg_match("/[".$this->CJKoverflow."]/u", $c) && $this->allowCJKorphans && !$CJKoverflow) {
5937 // add character onto this line
5938 $currContent .= $c;
5939 $cutoffWidth = $contentWidth;
5940 $contentWidth += $cw;
5941 $CJKoverflow = true;
5942 continue;
5943 }
5944 // Last character that fits is not allowed to end a line - move lastchar(s) to start of next line
5945 else if ($this->checkCJK && preg_match("/[".$this->CJKleading."]/u", $lastchar)) {
5946 //move lastchar(s) to next line
5947 $m0 = $lastchar;
5948 $m1 = $c;
5949 while(preg_match("/[".$this->CJKleading."]/u", $m0) && mb_strlen($words[(count($words)-1)], $this->mb_enc)>2) {
5950 // trim last letter off word[0]
5951 $words[(count($words)-1)] = mb_substr($words[(count($words)-1)],0,mb_strlen($words[(count($words)-1)], $this->mb_enc)-1, $this->mb_enc);
5952 // and add it to savedContent for next line
5953 $savedContent = $m0.$savedContent;
5954 $m1 = $lastchar;
5955 $lastchar = mb_substr($words[(count($words)-1)],mb_strlen($words[(count($words)-1)], $this->mb_enc)-1, 1, $this->mb_enc);
5956 $m0 = $lastchar;
5957 }
5958 $lastContent = '';
5959 for ( $w = 0; $w < count( $words ) ; $w++) { $lastContent .= $words[ $w ]." "; }
5960 $savedFont = $this->saveFont();
5961 // replace the current content with the cropped version
5962 $currContent = rtrim( $lastContent );
5963 }
5964 // Next character is not allowed to start a new line
5965 else if ($this->checkCJK && preg_match("/[".$this->CJKfollowing."]/u", $c)) {
5966 // try squeezing another character(s) onto this line = Oikomi
5967 if ($this->allowCJKorphans && !$CJKoverflow) { // mPDF 5.6.40
5968 $lookahead = mb_substr($s,$i+1,1,$this->mb_enc );
5969 //if lookahead is not another following char
5970 if (!$lookahead || ($lookahead && !preg_match("/[".$this->CJKfollowing."]/u", $lookahead))) {
5971 $currContent .= $c;
5972 $cutoffWidth = $contentWidth;
5973 $contentWidth += $cw;
5974 if ($this->allowCJKoverflow && preg_match("/[".$this->CJKoverflow."]/u", $c)) { $CJKoverflow = true; }
5975 continue;
5976 }
5977 }
5978 // or move lastchar(s) to next line to keep $c company = Oidashi
5979 $m0 = $lastchar;
5980 $m1 = $c;
5981 while(preg_match("/[".$this->CJKfollowing."]/u", $m1) && mb_strlen($words[(count($words)-1)], $this->mb_enc)>2) {
5982 // trim last letter off word[0]
5983 $words[(count($words)-1)] = mb_substr($words[(count($words)-1)],0,mb_strlen($words[(count($words)-1)], $this->mb_enc)-1, $this->mb_enc);
5984 // and add it to savedContent for next line
5985 $savedContent = $m0.$savedContent;
5986 $m1 = $lastchar;
5987 $lastchar = mb_substr($words[(count($words)-1)],mb_strlen($words[(count($words)-1)], $this->mb_enc)-1, 1, $this->mb_enc);
5988 $m0 = $lastchar;
5989 }
5990 $lastContent = '';
5991 for ( $w = 0; $w < count( $words ) ; $w++) { $lastContent .= $words[ $w ]." "; }
5992 $savedFont = $this->saveFont();
5993 // replace the current content with the cropped version
5994 $currContent = rtrim( $lastContent );
5995 }
5996 // mPDF 5.6.42
5997 else if ($this->checkCJK && preg_match("/([".$this->pregCJKchars."]+[0-9\x{ff10}-\x{ff19}]+$)/u", $words[0])) {
5998 $lookahead = mb_substr($s,$i,16,$this->mb_enc );
5999 //and if lookahead starts with a few numerals
6000 if ($lookahead && (preg_match("/^([0-9\x{ff10}-\x{ff19}]+[".$this->pregCJKchars."]+)/u", $lookahead) || preg_match("/^([0-9\x{ff10}-\x{ff19}]+$)/u", $lookahead)) ) {
6001 // or move lastchar(s) to next line to keep numerals together
6002 $m0 = $lastchar;
6003 while(preg_match("/[0-9\x{ff10}-\x{ff19}]/u", $m0) && mb_strlen($words[(count($words)-1)], $this->mb_enc)>2) {
6004 // trim last letter off word[0]
6005 $words[(count($words)-1)] = mb_substr($words[(count($words)-1)],0,mb_strlen($words[(count($words)-1)], $this->mb_enc)-1, $this->mb_enc);
6006 // and add it to savedContent for next line
6007 $savedContent = $m0.$savedContent;
6008 $lastchar = mb_substr($words[(count($words)-1)],mb_strlen($words[(count($words)-1)], $this->mb_enc)-1, 1, $this->mb_enc);
6009 $m0 = $lastchar;
6010 }
6011 }
6012 $lastContent = '';
6013 for ( $w = 0; $w < count( $words ) ; $w++) { $lastContent .= $words[ $w ]." "; }
6014 $savedFont = $this->saveFont();
6015 // replace the current content with the cropped version
6016 $currContent = rtrim( $lastContent );
6017 }
6018 else
6019 /*-- END CJK-FONTS --*/
6020 // if it looks like we didn't finish any words for this chunk
6021 if ( count( $words ) == 1 ) {
6022 // TO correct for error when word too wide for page - but only when one long word from left to right margin
6023 if (count($content) == 1 && $currContent != ' ') {
6024 $lastchar = mb_substr($words[0],mb_strlen($words[0], $this->mb_enc)-1, 1, $this->mb_enc);
6025 $lastContent = $words[0];
6026 $savedFont = $this->saveFont();
6027 // replace the current content with the cropped version
6028 $currContent = rtrim( $lastContent );
6029 }
6030 // mPDF 5.6.20
6031 else if ( count($content)>1
6032 && (!isset($this->objectbuffer[(count($content)-1)]) && !isset($this->objectbuffer[(count($content)-2)]))
6033 && substr($content[count($content)-2],-1,1) != ' '
6034 && substr($currContent,0,1) != ' '
6035 ) {
6036 // Go back to find a space in a previous chunk of content
6037 $found = false;
6038 for ($ix=count($content)-1;$ix>=0;$ix--) {
6039 // mPDF 5.6.29
6040 if ($this->usingCoreFont && preg_match('/[ '.chr(173).']/',$content[$ix],$m)) { $match = $m[0]; $found = $ix; break; }
6041 else if (!$this->usingCoreFont) {
6042 if (preg_match('/[ ]/',$content[$ix])) { $match = ' '; $found = $ix; break; }
6043 else if (preg_match('/[\x{00AD}]/u',$content[$ix])) {
6044 // even though it is UTF-8 replace it temporarily with chr(173)
6045 $content[$ix] = preg_replace('/[\x{00AD}]/u',chr(173),$content[$ix]);
6046 $match = chr(173); $found = $ix; break;
6047 }
6048 }
6049 }
6050 if ($found !== false) {
6051 $charpos = strrpos($content[$found],$match); // mPDF 5.6.29
6052 for ($ix=count($content)-1;$ix>$found;$ix--) {
6053 // save and crop off any subsequent chunks
6054 $savedPreContent[] = array_pop($content);
6055 $savedPreContentB[] = array_pop($contentB);
6056 $savedPreFont[] = array_pop($font);
6057 }
6058 if (substr($content[count($content)-1],$charpos+1,strlen($content[count($content)-1])-1) != '') {
6059 $savedPreContent[] = substr($content[count($content)-1],$charpos+1,strlen($content[count($content)-1])-1);
6060 $savedPreContentB[] = preg_replace('/L/','',$contentB[count($content)-1]); // ???
6061 $savedPreFont[] = $font[count($content)-1];
6062 }
6063 $savedContent = '';
6064 $savedContentB = '';
6065 $savedFont = array();
6066
6067 $currContent =& $content[ count( $content ) - 1 ];
6068 $currContent = substr($currContent,0,$charpos);
6069 if ($match == chr(173)) { $currContent .= '-'; } // mPDF 5.6.29
6070 if (strpos($contentB[(count($contentB)-1)],'R')!==false) { // ???
6071 $contentB[count($content)-1] = preg_replace('/R/','',$contentB[count($content)-1]); // ???
6072 }
6073
6074 $currContent = rtrim( $currContent );
6075 }
6076 else {
6077 $savedContent = array_pop( $content );
6078 $savedContentB = array_pop($contentB);
6079 $savedFont = array_pop( $font );
6080 $currContent =& $content[ count( $content ) - 1 ];
6081 $currContent = rtrim( $currContent );
6082 }
6083 }
6084 else {
6085 // save and crop off the content currently on the stack
6086 $savedContent = array_pop( $content );
6087 $savedContentB = array_pop($contentB); // mPDF 5.6.20
6088 $savedFont = array_pop( $font );
6089 // trim any trailing spaces off the last bit of content
6090 $currContent =& $content[ count( $content ) - 1 ];
6091 $currContent = rtrim( $currContent );
6092 }
6093 }
6094 else { // otherwise, we need to find which bit to cut off
6095 $lastContent = '';
6096 for ( $w = 0; $w < count( $words ) - 1; $w++) { $lastContent .= $words[ $w ]." "; }
6097 $savedContent = $words[ count( $words ) - 1 ];
6098 $savedFont = $this->saveFont();
6099 // replace the current content with the cropped version
6100 $currContent = rtrim( $lastContent );
6101 }
6102 // CJK - strip CJK space at end of line
6103 // &#x3000; = \xe3\x80\x80 = CJK space
6104 if ($this->checkCJK) { $currContent = preg_replace("/\xe3\x80\x80$/",'',$currContent) ; } // *CJK-FONTS*
6105
6106
6107 if (isset($this->objectbuffer[(count($content)-1)]) && $this->objectbuffer[(count($content)-1)]['type']=='dottab') {
6108 $savedObj = array_pop( $this->objectbuffer );
6109 $contentWidth -= ($this->objectbuffer[(count($content)-1)]['OUTER-WIDTH'] * _MPDFK);
6110 }
6111
6112 // Set Current lineheight (correction factor)
6113 $lhfixed = false;
6114 /*-- LISTS --*/
6115 if ($is_list) {
6116 if (preg_match('/([0-9.,]+)mm/',$this->list_lineheight[$this->listlvl][$this->listOcc],$am)) {
6117 $lhfixed = true;
6118 $def_fontsize = $this->InlineProperties['LISTITEM'][$this->listlvl][$this->listOcc][$this->listnum]['size'];
6119 $this->lineheight_correction = $am[1] / $def_fontsize ;
6120 }
6121 else {
6122 $this->lineheight_correction = $this->list_lineheight[$this->listlvl][$this->listOcc];
6123 }
6124 }
6125 else
6126 /*-- END LISTS --*/
6127 /*-- TABLES --*/
6128 if ($is_table) {
6129 if (preg_match('/([0-9.,]+)mm/',$this->table_lineheight,$am)) {
6130 $lhfixed = true;
6131 $def_fontsize = $this->FontSize; // needs to be default font-size for block ****
6132 $this->lineheight_correction = $lineHeight / $def_fontsize ;
6133 }
6134 else {
6135 $this->lineheight_correction = $this->table_lineheight;
6136 }
6137 }
6138 else
6139 /*-- END TABLES --*/
6140 if (isset($this->blk[$this->blklvl]['line_height']) && $this->blk[$this->blklvl]['line_height']) {
6141 if (preg_match('/([0-9.,]+)mm/',$this->blk[$this->blklvl]['line_height'],$am)) {
6142 $lhfixed = true;
6143 $def_fontsize = $this->blk[$this->blklvl]['InlineProperties']['size']; // needs to be default font-size for block ****
6144 $this->lineheight_correction = $am[1] / $def_fontsize ;
6145 }
6146 else {
6147 $this->lineheight_correction = $this->blk[$this->blklvl]['line_height'];
6148 }
6149 }
6150 else {
6151 $this->lineheight_correction = $this->normalLineheight;
6152 }
6153 // update $contentWidth and $cutoffWidth since they changed with cropping
6154 // Also correct lineheight to maximum fontsize (not for tables)
6155 $contentWidth = 0;
6156 // correct lineheight to maximum fontsize
6157 if ($lhfixed) { $maxlineHeight = $this->lineheight; }
6158 else { $maxlineHeight = 0; }
6159 $this->forceExactLineheight = true;
6160 $maxfontsize = 0;
6161 // While we're at it, check for cursive text
6162 $checkCursive=false;
6163 if ($this->biDirectional) { $checkCursive=true; } // *RTL*
6164 foreach ( $content as $k => $chunk )
6165 {
6166 $this->restoreFont( $font[ $k ]);
6167 if (!isset($this->objectbuffer[$k])) {
6168 // mPDF 5.6.40
6169 if ($this->checkCJK && $k == count($content)-1 && $CJKoverflow && $align=='J' && $this->allowCJKoverflow && $this->CJKforceend) {
6170 // force-end overhang
6171 $hanger = mb_substr($chunk,mb_strlen($chunk,$this->mb_enc)-1,1,$this->mb_enc );
6172 $content[$k] = $chunk = mb_substr($chunk,0,mb_strlen($chunk,$this->mb_enc)-1,$this->mb_enc );
6173 }
6174 if (!$this->usingCoreFont) {
6175 $content[$k] = $chunk = str_replace("\xc2\xad",'',$chunk );
6176 if (isset($this->CurrentFont['indic']) && $this->CurrentFont['indic']) { $checkCursive=true; } // *INDIC*
6177 }
6178 // Soft Hyphens chr(173)
6179 else if ($this->FontFamily!='csymbol' && $this->FontFamily!='czapfdingbats') {
6180 $content[$k] = $chunk = str_replace(chr(173),'',$chunk );
6181 }
6182 $contentWidth += $this->GetStringWidth( $chunk ) * _MPDFK;
6183 if (!empty($this->spanborddet)) {
6184 if (strpos($contentB[$k],'L')!==false) $contentWidth += $this->spanborddet['L']['w'] * _MPDFK;
6185 if (strpos($contentB[$k],'R')!==false) $contentWidth += $this->spanborddet['R']['w'] * _MPDFK;
6186 }
6187 if (!$lhfixed) { $maxlineHeight = max($maxlineHeight,$this->FontSize * $this->lineheight_correction ); }
6188 if ($lhfixed && ($this->FontSize > $def_fontsize || ($this->FontSize > ($lineHeight * $this->lineheight_correction) && $is_list))) {
6189 $this->forceExactLineheight = false;
6190 }
6191 $maxfontsize = max($maxfontsize,$this->FontSize);
6192 }
6193 }
6194
6195 $lastfontreqstyle = $font[count($font)-1]['ReqFontStyle'];
6196 $lastfontstyle = $font[count($font)-1]['style'];
6197 if ($blockdir == 'ltr' && strpos($lastfontreqstyle,"I") !== false && strpos($lastfontstyle,"I") === false) { // Artificial italic
6198 $lastitalic = $this->FontSize*0.15*_MPDFK;
6199 }
6200 else { $lastitalic = 0; }
6201
6202
6203 /*-- LISTS --*/
6204 if ($is_list && is_array($this->bulletarray) && $this->bulletarray) {
6205 $actfs = $this->bulletarray['fontsize'];
6206 if (!$lhfixed) { $maxlineHeight = max($maxlineHeight,$actfs * $this->lineheight_correction ); }
6207 if ($lhfixed && $actfs > $def_fontsize) { $this->forceExactLineheight = false; }
6208 $maxfontsize = max($maxfontsize,$actfs);
6209 }
6210 /*-- END LISTS --*/
6211
6212 // when every text item checked i.e. $maxfontsize is set properly
6213
6214 $af = 0; // Above font
6215 $bf = 0; // Below font
6216 $mta = 0; // Maximum top-aligned
6217 $mba = 0; // Maximum bottom-aligned
6218
6219 foreach ( $content as $k => $chunk ) {
6220 if (isset($this->objectbuffer[$k]) && $this->objectbuffer[$k]) {
6221 $contentWidth += $this->objectbuffer[$k]['OUTER-WIDTH'] * _MPDFK;
6222 $oh = $this->objectbuffer[$k]['OUTER-HEIGHT'];
6223 $va = $this->objectbuffer[$k]['vertical-align']; // = $objattr['vertical-align'] = set as M,T,B,S
6224 if ($lhfixed && $oh > $def_fontsize) { $this->forceExactLineheight = false; }
6225
6226 if ($va == 'BS') { // (BASELINE default)
6227 $af = max($af, ($oh - ($maxfontsize * (0.5 + $this->baselineC))));
6228 }
6229 else if ($va == 'M') {
6230 $af = max($af, ($oh - $maxfontsize)/2);
6231 $bf = max($bf, ($oh - $maxfontsize)/2);
6232 }
6233 else if ($va == 'TT') {
6234 $bf = max($bf, ($oh - $maxfontsize));
6235 }
6236 else if ($va == 'TB') {
6237 $af = max($af, ($oh - $maxfontsize));
6238 }
6239 else if ($va == 'T') {
6240 $mta = max($mta, $oh);
6241 }
6242 else if ($va == 'B') {
6243 $mba = max($mba, $oh);
6244 }
6245 }
6246 }
6247 if ((!$lhfixed || !$this->forceExactLineheight) && ($af > (($maxlineHeight - $maxfontsize)/2) || $bf > (($maxlineHeight - $maxfontsize)/2))) {
6248 $maxlineHeight = $maxfontsize + $af + $bf;
6249 }
6250 else if (!$lhfixed) { $af = $bf = ($maxlineHeight - $maxfontsize)/2; }
6251
6252 if ($mta > $maxlineHeight) {
6253 $bf += ($mta - $maxlineHeight);
6254 $maxlineHeight = $mta;
6255 }
6256 if ($mba > $maxlineHeight) {
6257 $af += ($mba - $maxlineHeight);
6258 $maxlineHeight = $mba;
6259 }
6260
6261
6262 $lineHeight = $maxlineHeight;
6263 $cutoffWidth = $contentWidth;
6264 // If NOT images, and maxfontsize NOT > lineHeight - this value determines text baseline positioning
6265 if ($lhfixed && $af==0 && $bf==0 && $maxfontsize<=($def_fontsize * $this->lineheight_correction * 0.8 )) {
6266 $this->linemaxfontsize = $def_fontsize;
6267 }
6268 else { $this->linemaxfontsize = $maxfontsize; }
6269
6270
6271 $inclCursive=false;
6272 foreach ( $content as $k => $chunk ) {
6273 if (!isset($this->objectbuffer[$k]) || (isset($this->objectbuffer[$k]) && !$this->objectbuffer[$k])) {
6274 if ($this->usingCoreFont) {
6275 $content[$k] = str_replace(chr(160),chr(32),$chunk );
6276 }
6277 else {
6278 $content[$k] = str_replace(chr(194).chr(160),chr(32),$chunk );
6279 if ($checkCursive) {
6280 if (preg_match("/([".$this->pregRTLchars."])/u", $chunk)) { $inclCursive = true; } // *RTL*
6281 if (preg_match("/([".$this->pregHIchars.$this->pregBNchars.$this->pregPAchars."])/u", $chunk)) { $inclCursive = true; } // *INDIC*
6282 }
6283 }
6284 }
6285 }
6286
6287 // JUSTIFICATION J
6288 $jcharspacing = 0;
6289 $jws = 0;
6290 $nb_carac = 0;
6291 $nb_spaces = 0;
6292 // if it's justified, we need to find the char/word spacing (or if orphans have allowed length of line to go over the maxwidth)
6293 if ( ($align == 'J' && !$CJKoverflow) || (($cutoffWidth + $lastitalic > $maxWidth - $WidthCorrection - (($this->cMarginL+$this->cMarginR)*_MPDFK) - ($paddingL+$paddingR +(($fpaddingL + $fpaddingR) * _MPDFK) ) + 0.001) && (!$CJKoverflow || ($CJKoverflow && !$this->allowCJKoverflow))) || $CJKoverflow && $align=='J' && $this->allowCJKoverflow && $hanger && $this->CJKforceend) { // 0.001 is to correct for deviations converting mm=>pts // mPDF 5.6.40
6294 // JUSTIFY J (Use character spacing)
6295 // WORD SPACING
6296 foreach ( $content as $k => $chunk ) {
6297 if (!isset($this->objectbuffer[$k]) || (isset($this->objectbuffer[$k]) && !$this->objectbuffer[$k])) {
6298 $nb_carac += mb_strlen( $chunk, $this->mb_enc ) ;
6299 $nb_spaces += mb_substr_count( $chunk,' ', $this->mb_enc ) ;
6300 }
6301 }
6302 list($jcharspacing,$jws) = $this->GetJspacing($nb_carac,$nb_spaces,($maxWidth-$lastitalic-$cutoffWidth-$WidthCorrection-(($this->cMarginL+$this->cMarginR)*_MPDFK)-($paddingL+$paddingR +(($fpaddingL + $fpaddingR) * _MPDFK) )),$inclCursive);
6303 }
6304
6305
6306 // WORD SPACING
6307 $empty = $maxWidth - $lastitalic-$WidthCorrection - $contentWidth - (($this->cMarginL+$this->cMarginR)* _MPDFK) - ($paddingL+$paddingR +(($fpaddingL + $fpaddingR) * _MPDFK) );
6308
6309 $empty -= ($jcharspacing * $nb_carac);
6310 $empty -= ($jws * $nb_spaces);
6311
6312 $empty /= _MPDFK;
6313 $b = ''; //do not use borders
6314 // Get PAGEBREAK TO TEST for height including the top border/padding
6315 $check_h = max($this->divheight,$lineHeight);
6316 if (($newblock) && ($blockstate==1 || $blockstate==3) && ($this->blklvl > 0) && ($lineCount == 1) && (!$is_table) && (!$is_list)) {
6317 $check_h += ($this->blk[$this->blklvl]['padding_top'] + $this->blk[$this->blklvl]['margin_top'] + $this->blk[$this->blklvl]['border_top']['w']);
6318 }
6319
6320 if ($this->ColActive && $check_h > ($this->PageBreakTrigger - $this->y0)) {
6321 $this->SetCol($this->NbCol-1);
6322 }
6323
6324 // PAGEBREAK
6325 // 'If' below used in order to fix "first-line of other page with justify on" bug
6326 if(!$is_table && ($this->y+$check_h) > $this->PageBreakTrigger and !$this->InFooter and $this->AcceptPageBreak()) {
6327 $bak_x=$this->x;//Current X position
6328
6329 // WORD SPACING
6330 $ws=$this->ws;//Word Spacing
6331 $charspacing=$this->charspacing;//Character Spacing
6332 $this->ResetSpacing();
6333
6334 $this->AddPage($this->CurOrientation);
6335
6336 $this->x = $bak_x;
6337 // Added to correct for OddEven Margins
6338 $currentx += $this->MarginCorrection;
6339 $this->x += $this->MarginCorrection;
6340
6341 // WORD SPACING
6342 $this->SetSpacing($charspacing,$ws);
6343 }
6344
6345 if ($this->keep_block_together && !$is_table && $this->kt_p00 < $this->page && ($this->y+$check_h) > $this->kt_y00) {
6346 $this->printdivbuffer();
6347 $this->keep_block_together = 0;
6348 }
6349
6350
6351 /*-- COLUMNS --*/
6352 // COLS
6353 // COLUMN CHANGE
6354 if ($this->CurrCol != $oldcolumn) {
6355 $currentx += $this->ChangeColumn * ($this->ColWidth+$this->ColGap);
6356 $this->x += $this->ChangeColumn * ($this->ColWidth+$this->ColGap);
6357 $oldcolumn = $this->CurrCol;
6358 }
6359
6360 if ($this->ColActive && !$is_table) { $this->breakpoints[$this->CurrCol][] = $this->y; } // *COLUMNS*
6361 /*-- END COLUMNS --*/
6362
6363 // TOP MARGIN
6364 if (($newblock) && ($blockstate==1 || $blockstate==3) && ($this->blk[$this->blklvl]['margin_top']) && ($lineCount == 1) && (!$is_table) && (!$is_list)) {
6365 $this->DivLn($this->blk[$this->blklvl]['margin_top'],$this->blklvl-1,true,$this->blk[$this->blklvl]['margin_collapse']);
6366 if ($this->ColActive) { $this->breakpoints[$this->CurrCol][] = $this->y; } // *COLUMNS*
6367 }
6368
6369
6370 // Update y0 for top of block (used to paint border)
6371 if (($newblock) && ($blockstate==1 || $blockstate==3) && ($lineCount == 1) && (!$is_table) && (!$is_list)) {
6372 $this->blk[$this->blklvl]['y0'] = $this->y;
6373 $this->blk[$this->blklvl]['startpage'] = $this->page;
6374 if ($this->blk[$this->blklvl]['float']) { $this->blk[$this->blklvl]['float_start_y'] = $this->y; } // mPDF 5.6.63
6375 }
6376
6377 // TOP PADDING and BORDER spacing/fill
6378 if (($newblock) && ($blockstate==1 || $blockstate==3) && (($this->blk[$this->blklvl]['padding_top']) || ($this->blk[$this->blklvl]['border_top'])) && ($lineCount == 1) && (!$is_table) && (!$is_list)) {
6379 // $state = 0 normal; 1 top; 2 bottom; 3 top and bottom
6380 $this->DivLn($this->blk[$this->blklvl]['padding_top'] + $this->blk[$this->blklvl]['border_top']['w'],-3,true,false,1);
6381 if ($this->ColActive) { $this->breakpoints[$this->CurrCol][] = $this->y; } // *COLUMNS*
6382 }
6383
6384 $arraysize = count($content);
6385
6386 $margins = ($this->cMarginL+$this->cMarginR) + ($ipaddingL+$ipaddingR + $fpaddingR + $fpaddingR );
6387
6388 // PAINT BACKGROUND FOR THIS LINE
6389 if (!$is_table) { $this->DivLn($lineHeight,$this->blklvl,false); } // false -> don't advance y
6390
6391 $this->x = $currentx + $this->cMarginL + $ipaddingL + $fpaddingL ;
6392 if ($align == 'R') { $this->x += $empty; }
6393 else if ($align == 'C') { $this->x += ($empty / 2); }
6394
6395 // Paragraph INDENT
6396 if (isset($this->blk[$this->blklvl]['text_indent']) && ($newblock) && ($blockstate==1 || $blockstate==3) && ($lineCount == 1) && (!$is_table) && ($blockdir !='rtl') && ($align !='C')) {
6397 $ti = $this->ConvertSize($this->blk[$this->blklvl]['text_indent'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
6398 $this->x += $ti;
6399 }
6400
6401 // DIRECTIONALITY RTL
6402 $all_rtl = false;
6403 $contains_rtl = false;
6404 /*-- RTL --*/
6405 if ($blockdir == 'rtl' || $this->biDirectional) {
6406 $all_rtl = true;
6407 foreach ( $content as $k => $chunk ) {
6408 $reversed = $this->magic_reverse_dir($chunk, false, $blockdir);
6409
6410 if ($reversed > 0) { $contains_rtl = true; }
6411 if ($reversed < 2) { $all_rtl = false; }
6412 $content[$k] = $chunk;
6413 }
6414 if (($blockdir =='rtl' && $contains_rtl) || $all_rtl) {
6415 $content = array_reverse($content,false);
6416 $contentB = array_reverse($contentB,false);
6417 }
6418 }
6419 /*-- END RTL --*/
6420
6421 foreach ( $content as $k => $chunk ) {
6422
6423 // FOR IMAGES - UPDATE POSITION
6424 if (($blockdir =='rtl' && $contains_rtl) || $all_rtl) { $dirk = $arraysize-1 - $k ; } else { $dirk = $k; }
6425
6426 $va = 'M'; // default for text
6427 if (isset($this->objectbuffer[$dirk]) && $this->objectbuffer[$dirk]) {
6428 $xadj = $this->x - $this->objectbuffer[$dirk]['OUTER-X'] ;
6429 $this->objectbuffer[$dirk]['OUTER-X'] += $xadj;
6430 $this->objectbuffer[$dirk]['BORDER-X'] += $xadj;
6431 $this->objectbuffer[$dirk]['INNER-X'] += $xadj;
6432 $va = $this->objectbuffer[$dirk]['vertical-align'];
6433 $yadj = $this->y - $this->objectbuffer[$dirk]['OUTER-Y'];
6434 if ($va == 'BS') {
6435 $yadj += $af + ($this->linemaxfontsize * (0.5 + $this->baselineC)) - $this->objectbuffer[$dirk]['OUTER-HEIGHT'];
6436 }
6437 else if ($va == 'M' || $va == '') {
6438 $yadj += $af + ($this->linemaxfontsize /2) - ($this->objectbuffer[$dirk]['OUTER-HEIGHT']/2);
6439 }
6440 else if ($va == 'TB') {
6441 $yadj += $af + $this->linemaxfontsize - $this->objectbuffer[$dirk]['OUTER-HEIGHT'];
6442 }
6443 else if ($va == 'TT') {
6444 $yadj += $af;
6445 }
6446 else if ($va == 'B') {
6447 $yadj += $af + $this->linemaxfontsize + $bf - $this->objectbuffer[$dirk]['OUTER-HEIGHT'];
6448 }
6449 else if ($va == 'T') {
6450 $yadj += 0;
6451 }
6452 $this->objectbuffer[$dirk]['OUTER-Y'] += $yadj;
6453 $this->objectbuffer[$dirk]['BORDER-Y'] += $yadj;
6454 $this->objectbuffer[$dirk]['INNER-Y'] += $yadj;
6455 }
6456
6457 // DIRECTIONALITY RTL
6458 if ((($blockdir == 'rtl') && ($contains_rtl )) || ($all_rtl )) { $this->restoreFont($font[$arraysize-1 - $k]); }
6459 else { $this->restoreFont( $font[ $k ] ); }
6460
6461 $this->SetSpacing(($this->fixedlSpacing*_MPDFK)+$jcharspacing,($this->fixedlSpacing+$this->minwSpacing)*_MPDFK+$jws);
6462 // Now unset these values so they don't influence GetStringwidth below or in fn. Cell
6463 $this->fixedlSpacing = false;
6464 $this->minwSpacing = 0;
6465
6466 // mPDF 5.6.26
6467 $save_vis = $this->visibility;
6468 if (isset($this->textparam['visibility']) && $this->textparam['visibility'] && $this->textparam['visibility'] != $this->visibility) {
6469 $this->SetVisibility($this->textparam['visibility']);
6470 }
6471 // *********** SPAN BACKGROUND COLOR ***************** //
6472 if ($this->spanbgcolor) {
6473 $cor = $this->spanbgcolorarray;
6474 $this->SetFColor($cor);
6475 $save_fill = $fill; $spanfill = 1; $fill = 1;
6476 }
6477 if (!empty($this->spanborddet)) {
6478 if (strpos($contentB[$k],'L')!==false) $this->x += $this->spanborddet['L']['w'];
6479 if (strpos($contentB[$k],'L')===false) $this->spanborddet['L']['s'] = $this->spanborddet['L']['w'] = 0;
6480 if (strpos($contentB[$k],'R')===false) $this->spanborddet['R']['s'] = $this->spanborddet['R']['w'] = 0;
6481 }
6482
6483 // WORD SPACING
6484 $stringWidth = $this->GetStringWidth($chunk );
6485 $stringWidth += ( $this->charspacing * mb_strlen($chunk,$this->mb_enc ) / _MPDFK );
6486 $stringWidth += ( $this->ws * mb_substr_count($chunk,' ',$this->mb_enc ) / _MPDFK );
6487 if (isset($this->objectbuffer[$dirk])) { $stringWidth = $this->objectbuffer[$dirk]['OUTER-WIDTH']; }
6488
6489 if ($stringWidth==0) { $stringWidth = 0.000001; }
6490 if ($k == $arraysize-1) {
6491 $stringWidth -= ( $this->charspacing / _MPDFK );
6492 // mPDF 5.6.40
6493 if ($this->checkCJK && $CJKoverflow && $align=='J' && $this->allowCJKoverflow && $hanger && $this->CJKforceend) {
6494 // force-end overhang
6495 $this->Cell( $stringWidth, $lineHeight, $chunk, '', 0, '', $fill, $this->HREF, $currentx,0,0,'M', $fill, $af, $bf, true );
6496 $this->Cell( $this->GetStringWidth($hanger), $lineHeight, $hanger, '', 1, '', $fill, $this->HREF, $currentx,0,0,'M', $fill, $af, $bf, true );
6497 }
6498 else {
6499 $this->Cell( $stringWidth, $lineHeight, $chunk, '', 1, '', $fill, $this->HREF, $currentx,0,0,'M', $fill, $af, $bf, true ); //mono-style line or last part (skips line)
6500 }
6501
6502 }
6503 else $this->Cell( $stringWidth, $lineHeight, $chunk, '', 0, '', $fill, $this->HREF, 0, 0,0,'M', $fill, $af, $bf, true );//first or middle part
6504
6505 if (!empty($this->spanborddet)) {
6506 if (strpos($contentB[$k],'R')!==false && $k != $arraysize-1) $this->x += $this->spanborddet['R']['w'];
6507 }
6508 // *********** SPAN BACKGROUND COLOR OFF - RESET BLOCK BGCOLOR ***************** //
6509 if (isset($spanfill) && $spanfill) {
6510 $fill = $save_fill; $spanfill = 0;
6511 if ($fill) { $this->SetFColor($bcor); }
6512 }
6513 // mPDF 5.6.26
6514 if (isset($this->textparam['visibility']) && $this->textparam['visibility'] && $this->visibility != $save_vis) {
6515 $this->SetVisibility($save_vis);
6516 }
6517
6518 }
6519 if (!$is_table) {
6520 $this->maxPosR = max($this->maxPosR , ($this->w - $this->rMargin - $this->blk[$this->blklvl]['outer_right_margin']));
6521 $this->maxPosL = min($this->maxPosL , ($this->lMargin + $this->blk[$this->blklvl]['outer_left_margin']));
6522 }
6523
6524 // move on to the next line, reset variables, tack on saved content and current char
6525
6526 $this->printobjectbuffer($is_table, $blockdir);
6527 $this->objectbuffer = array();
6528
6529 /*-- LISTS --*/
6530 // LIST BULLETS/NUMBERS
6531 if ($is_list && is_array($this->bulletarray) && ($lineCount == 1) ) {
6532
6533 $this->ResetSpacing();
6534
6535 $bull = $this->bulletarray;
6536 if (isset($bull['level']) && isset($bull['occur']) && isset($this->InlineProperties['LIST'][$bull['level']][$bull['occur']])) {
6537 $this->restoreInlineProperties($this->InlineProperties['LIST'][$bull['level']][$bull['occur']]);
6538 }
6539 if (isset($bull['level']) && isset($bull['occur']) && isset($bull['num']) && isset($this->InlineProperties['LISTITEM'][$bull['level']][$bull['occur']][$bull['num']]) && $this->InlineProperties['LISTITEM'][$bull['level']][$bull['occur']][$bull['num']]) { $this->restoreInlineProperties($this->InlineProperties['LISTITEM'][$bull['level']][$bull['occur']][$bull['num']]); }
6540 if (isset($bull['font']) && $bull['font'] == 'czapfdingbats') {
6541 $this->bullet = true;
6542 $this->SetFont('czapfdingbats','',$this->FontSizePt/2.5);
6543 }
6544 else { $this->SetFont($this->FontFamily,$this->FontStyle,$this->FontSizePt,true,true); } // force output
6545 //Output bullet
6546 $this->x = $currentx;
6547 if (isset($bull['x'])) { $this->x += $bull['x']; }
6548 $this->y -= $lineHeight;
6549 if (isset($bull['col']) && $bull['col']) { $this->SetTColor($bull['col']); } // mPDF 5.6.67
6550 if (isset($bull['txt'])) { $this->Cell($bull['w'], $lineHeight,$bull['txt'],'','',$bull['align'],0,'',0,-$this->cMarginL, -$this->cMarginR ); }
6551 if (isset($bull['font']) && $bull['font'] == 'czapfdingbats') {
6552 $this->bullet = false;
6553 }
6554 $this->x = $currentx; // Reset
6555 $this->y += $lineHeight;
6556
6557 if ($this->ColActive && !$is_table) { $this->breakpoints[$this->CurrCol][] = $this->y; } // *COLUMNS*
6558
6559 $this->bulletarray = array(); // prevents repeat of bullet/number if <li>....<br />.....</li>
6560 }
6561 /*-- END LISTS --*/
6562
6563
6564 /*-- CSS-IMAGE-FLOAT --*/
6565 // Update values if set to skipline
6566 if ($this->floatmargins) { $this->_advanceFloatMargins(); }
6567 /*-- END CSS-IMAGE-FLOAT --*/
6568
6569 // Reset lineheight
6570 $lineHeight = $this->divheight;
6571 $valign = 'M';
6572
6573 $font = array();
6574 $content = array();
6575 $contentB = array();
6576 $contentWidth = 0;
6577 if (!empty($savedObj)) {
6578 $this->objectbuffer[] = $savedObj;
6579 $font[] = $savedFont;
6580 $content[] = '';
6581 $contentB[] = '';
6582 $contentWidth += $savedObj['OUTER-WIDTH'] * _MPDFK;
6583 }
6584 // mPDF 5.6.20
6585 if (count($savedPreContent) > 0) {
6586 for($ix=count($savedPreContent)-1;$ix>=0;$ix--) {
6587 $font[] = $savedPreFont[$ix];
6588 $content[] = $savedPreContent[$ix];
6589 $contentB[] = $savedPreContentB[$ix];
6590 $this->restoreFont( $savedPreFont[$ix] );
6591 $lbw = $rbw = 0; // Border widths
6592 if (!empty($this->spanborddet)) {
6593 $lbw = $this->spanborddet['L']['w'];
6594 $rbw = $this->spanborddet['R']['w'];
6595 }
6596 if ($ix>0) {
6597 $contentWidth += $this->GetStringWidth( $savedPreContent[$ix] ) * _MPDFK;
6598 if (strpos($savedPreContentB[$ix],'L')!==false) $contentWidth += $lbw;
6599 if (strpos($savedPreContentB[$ix],'R')!==false) $contentWidth += $rbw;
6600 }
6601 }
6602 $savedPreContent = array();
6603 $savedPreContentB = array();
6604 $savedPreFont = array();
6605 $content[ (count($content)-1) ] .= $c;
6606 }
6607 else {
6608 $font[] = $savedFont;
6609 $content[] = $savedContent . $c;
6610 $contentB[] = $savedContentB ;
6611 }
6612
6613 $currContent =& $content[ (count($content)-1) ];
6614
6615 // CJK - strip CJK space at end of line
6616 // &#x3000; = \xe3\x80\x80 = CJK space
6617 if ($this->checkCJK && $currContent == "\xe3\x80\x80") { $currContent = '' ; } // *CJK-FONTS*
6618
6619 $this->restoreFont( $savedFont );
6620 $lbw = $rbw = 0; // Border widths
6621 if (!empty($this->spanborddet)) {
6622 $lbw = $this->spanborddet['L']['w'];
6623 $rbw = $this->spanborddet['R']['w'];
6624 }
6625 $contentWidth += $this->GetStringWidth( $currContent ) * _MPDFK;
6626 if (strpos($savedContentB,'L')!==false) $contentWidth += $lbw;
6627 $cutoffWidth = $contentWidth;
6628 $CJKoverflow = false;
6629 $hanger = ''; // mPDF 5.6.40
6630 }
6631 // another character will fit, so add it on
6632 else {
6633 $contentWidth += $cw;
6634 $currContent .= $c;
6635 }
6636 }
6637 unset($content);
6638 unset($contentB);
6639 }
6640 //----------------------END OF FLOWING BLOCK------------------------------------//
6641
6642
6643 /*-- CSS-IMAGE-FLOAT --*/
6644 // Update values if set to skipline
6645 function _advanceFloatMargins() {
6646 // Update floatmargins - L
6647 if (isset($this->floatmargins['L']) && $this->floatmargins['L']['skipline'] && $this->floatmargins['L']['y0'] != $this->y) {
6648 $yadj = $this->y - $this->floatmargins['L']['y0'];
6649 $this->floatmargins['L']['y0'] = $this->y;
6650 $this->floatmargins['L']['y1'] += $yadj;
6651
6652 // Update objattr in floatbuffer
6653 if ($this->floatbuffer[$this->floatmargins['L']['id']]['border_left']['w']) {
6654 $this->floatbuffer[$this->floatmargins['L']['id']]['BORDER-Y'] += $yadj;
6655 }
6656 $this->floatbuffer[$this->floatmargins['L']['id']]['INNER-Y'] += $yadj;
6657 $this->floatbuffer[$this->floatmargins['L']['id']]['OUTER-Y'] += $yadj;
6658
6659 // Unset values
6660 $this->floatbuffer[$this->floatmargins['L']['id']]['skipline'] = false;
6661 $this->floatmargins['L']['skipline'] = false;
6662 $this->floatmargins['L']['id'] = '';
6663 }
6664 // Update floatmargins - R
6665 if (isset($this->floatmargins['R']) && $this->floatmargins['R']['skipline'] && $this->floatmargins['R']['y0'] != $this->y) {
6666 $yadj = $this->y - $this->floatmargins['R']['y0'];
6667 $this->floatmargins['R']['y0'] = $this->y;
6668 $this->floatmargins['R']['y1'] += $yadj;
6669
6670 // Update objattr in floatbuffer
6671 if ($this->floatbuffer[$this->floatmargins['R']['id']]['border_left']['w']) {
6672 $this->floatbuffer[$this->floatmargins['R']['id']]['BORDER-Y'] += $yadj;
6673 }
6674 $this->floatbuffer[$this->floatmargins['R']['id']]['INNER-Y'] += $yadj;
6675 $this->floatbuffer[$this->floatmargins['R']['id']]['OUTER-Y'] += $yadj;
6676
6677 // Unset values
6678 $this->floatbuffer[$this->floatmargins['R']['id']]['skipline'] = false;
6679 $this->floatmargins['R']['skipline'] = false;
6680 $this->floatmargins['R']['id'] = '';
6681 }
6682 }
6683 /*-- END CSS-IMAGE-FLOAT --*/
6684
6685
6686
6687 ////////////////////////////////////////////////////////////////////////////////
6688 // ADDED forcewrap - to call from inline OBJECT functions to breakwords if necessary in cell
6689 ////////////////////////////////////////////////////////////////////////////////
6690 function WordWrap(&$text, $maxwidth, $forcewrap = 0) {
6691 $biggestword=0;
6692 $toonarrow=false;
6693
6694 $text = trim($text);
6695
6696 if ($text==='') return 0;
6697 $space = $this->GetCharWidth(' ',false);
6698 $lines = explode("\n", $text);
6699 $text = '';
6700 $count = 0;
6701 foreach ($lines as $line) {
6702 $words = explode(' ', $line);
6703 $width = 0;
6704 foreach ($words as $word) {
6705 $word = trim($word);
6706 $wordwidth = $this->GetStringWidth($word);
6707 //Warn user that maxwidth is insufficient
6708 if ($wordwidth > $maxwidth + 0.0001) {
6709 if ($wordwidth > $biggestword) { $biggestword = $wordwidth; }
6710 $toonarrow=true;
6711 // ADDED
6712 if ($forcewrap) {
6713 while($wordwidth > $maxwidth) {
6714 $chw = 0; // check width
6715 for ( $i = 0; $i < mb_strlen($word, $this->mb_enc ); $i++ ) {
6716 $chw = $this->GetStringWidth(mb_substr($word,0,$i+1,$this->mb_enc ));
6717 if ($chw > $maxwidth ) {
6718 if ($text) {
6719 $text = rtrim($text)."\n".mb_substr($word,0,$i,$this->mb_enc );
6720 $count++;
6721 }
6722 else {
6723 $text = mb_substr($word,0,$i,$this->mb_enc );
6724 }
6725 $word = mb_substr($word,$i,mb_strlen($word, $this->mb_enc )-$i,$this->mb_enc );
6726 $wordwidth = $this->GetStringWidth($word);
6727 $width = $maxwidth;
6728 break;
6729 }
6730 }
6731 }
6732 }
6733 }
6734
6735 if ($width + $wordwidth < $maxwidth - 0.0001) {
6736 $width += $wordwidth + $space;
6737 $text .= $word.' ';
6738 }
6739 else {
6740 $width = $wordwidth + $space;
6741 $text = rtrim($text)."\n".$word.' ';
6742 $count++;
6743 }
6744 }
6745 $text .= "\n";
6746 $count++;
6747 }
6748 $text = rtrim($text);
6749
6750 //Return -(wordsize) if word is bigger than maxwidth
6751
6752 // ADDED
6753 if ($forcewrap) { return $count; }
6754 if (($toonarrow) && ($this->table_error_report)) {
6755 $this->Error("Word is too long to fit in table - ".$this->table_error_report_param);
6756 }
6757 if ($toonarrow) return -$biggestword;
6758 else return $count;
6759 }
6760
6761 /*-- END HTML-CSS --*/
6762
6763 function _SetTextRendering($mode) {
6764 if (!(($mode == 0) || ($mode == 1) || ($mode == 2)))
6765 $this->Error("Text rendering mode should be 0, 1 or 2 (value : $mode)");
6766 $tr = ($mode.' Tr');
6767 if($this->page>0 && ((isset($this->pageoutput[$this->page]['TextRendering']) && $this->pageoutput[$this->page]['TextRendering'] != $tr) || !isset($this->pageoutput[$this->page]['TextRendering']) || $this->keep_block_together)) { $this->_out($tr); }
6768 $this->pageoutput[$this->page]['TextRendering'] = $tr;
6769
6770 }
6771
6772 function SetTextOutline($params=array()) { // mPDF 5.6.07
6773 if (isset($params['outline-s']) && $params['outline-s'])
6774 {
6775 $this->SetLineWidth($params['outline-WIDTH']);
6776 $this->SetDColor($params['outline-COLOR']);
6777 $tr = ('2 Tr');
6778 if($this->page>0 && ((isset($this->pageoutput[$this->page]['TextRendering']) && $this->pageoutput[$this->page]['TextRendering'] != $tr) || !isset($this->pageoutput[$this->page]['TextRendering']) || $this->keep_block_together)) { $this->_out($tr); }
6779 $this->pageoutput[$this->page]['TextRendering'] = $tr;
6780 }
6781 else //Now resets all values
6782 {
6783 $this->SetLineWidth(0.2);
6784 $this->SetDColor($this->ConvertColor(0));
6785 $this->_SetTextRendering(0);
6786 $tr = ('0 Tr');
6787 if($this->page>0 && ((isset($this->pageoutput[$this->page]['TextRendering']) && $this->pageoutput[$this->page]['TextRendering'] != $tr) || !isset($this->pageoutput[$this->page]['TextRendering']) || $this->keep_block_together)) { $this->_out($tr); }
6788 $this->pageoutput[$this->page]['TextRendering'] = $tr;
6789 }
6790 }
6791
6792 function Image($file,$x,$y,$w=0,$h=0,$type='',$link='',$paint=true, $constrain=true, $watermark=false, $shownoimg=true, $allowvector=true) {
6793 $orig_srcpath = $file;
6794 $this->GetFullPath($file);
6795
6796 $info=$this->_getImage($file, true, $allowvector, $orig_srcpath );
6797 if(!$info && $paint) {
6798 $info = $this->_getImage($this->noImageFile);
6799 if ($info) {
6800 $file = $this->noImageFile;
6801 $w = ($info['w'] * (25.4/$this->dpi)); // 14 x 16px
6802 $h = ($info['h'] * (25.4/$this->dpi)); // 14 x 16px
6803 }
6804 }
6805 if(!$info) return false;
6806 //Automatic width and height calculation if needed
6807 if($w==0 and $h==0) {
6808 /*-- IMAGES-WMF --*/
6809 if ($info['type']=='wmf') {
6810 // WMF units are twips (1/20pt)
6811 // divide by 20 to get points
6812 // divide by k to get user units
6813 $w = abs($info['w'])/(20*_MPDFK);
6814 $h = abs($info['h']) / (20*_MPDFK);
6815 }
6816 else
6817 /*-- END IMAGES-WMF --*/
6818 if ($info['type']=='svg') {
6819 // returned SVG units are pts
6820 // divide by k to get user units (mm)
6821 $w = abs($info['w'])/_MPDFK;
6822 $h = abs($info['h']) /_MPDFK;
6823 }
6824 else {
6825 //Put image at default image dpi
6826 $w=($info['w']/_MPDFK) * (72/$this->img_dpi);
6827 $h=($info['h']/_MPDFK) * (72/$this->img_dpi);
6828 }
6829 }
6830 if($w==0) $w=abs($h*$info['w']/$info['h']);
6831 if($h==0) $h=abs($w*$info['h']/$info['w']);
6832
6833 /*-- WATERMARK --*/
6834 if ($watermark) {
6835 $maxw = $this->w;
6836 $maxh = $this->h;
6837 // Size = D PF or array
6838 if (is_array($this->watermark_size)) {
6839 $w = $this->watermark_size[0];
6840 $h = $this->watermark_size[1];
6841 }
6842 else if (!is_string($this->watermark_size)) {
6843 $maxw -= $this->watermark_size*2;
6844 $maxh -= $this->watermark_size*2;
6845 $w = $maxw;
6846 $h=abs($w*$info['h']/$info['w']);
6847 if ($h > $maxh ) {
6848 $h = $maxh ; $w=abs($h*$info['w']/$info['h']);
6849 }
6850 }
6851 else if ($this->watermark_size == 'F') {
6852 if ($this->ColActive) { $maxw = $this->w - ($this->DeflMargin + $this->DefrMargin); }
6853 else { $maxw = $this->pgwidth; }
6854 $maxh = $this->h - ($this->tMargin + $this->bMargin);
6855 $w = $maxw;
6856 $h=abs($w*$info['h']/$info['w']);
6857 if ($h > $maxh ) {
6858 $h = $maxh ; $w=abs($h*$info['w']/$info['h']);
6859 }
6860 }
6861 else if ($this->watermark_size == 'P') { // Default P
6862 $w = $maxw;
6863 $h=abs($w*$info['h']/$info['w']);
6864 if ($h > $maxh ) {
6865 $h = $maxh ; $w=abs($h*$info['w']/$info['h']);
6866 }
6867 }
6868 // Automatically resize to maximum dimensions of page if too large
6869 if ($w > $maxw) {
6870 $w = $maxw;
6871 $h=abs($w*$info['h']/$info['w']);
6872 }
6873 if ($h > $maxh ) {
6874 $h = $maxh ;
6875 $w=abs($h*$info['w']/$info['h']);
6876 }
6877 // Position
6878 if (is_array($this->watermark_pos)) {
6879 $x = $this->watermark_pos[0];
6880 $y = $this->watermark_pos[1];
6881 }
6882 else if ($this->watermark_pos == 'F') { // centred on printable area
6883 if ($this->ColActive) { // *COLUMNS*
6884 if (($this->mirrorMargins) && (($this->page)%2==0)) { $xadj = $this->DeflMargin-$this->DefrMargin; } // *COLUMNS*
6885 else { $xadj = 0; } // *COLUMNS*
6886 $x = ($this->DeflMargin - $xadj + ($this->w - ($this->DeflMargin + $this->DefrMargin))/2) - ($w/2); // *COLUMNS*
6887 } // *COLUMNS*
6888 else { // *COLUMNS*
6889 $x = ($this->lMargin + ($this->pgwidth)/2) - ($w/2);
6890 } // *COLUMNS*
6891 $y = ($this->tMargin + ($this->h - ($this->tMargin + $this->bMargin))/2) - ($h/2);
6892 }
6893 else { // default P - centred on whole page
6894 $x = ($this->w/2) - ($w/2);
6895 $y = ($this->h/2) - ($h/2);
6896 }
6897 /*-- IMAGES-WMF --*/
6898 if ($info['type']=='wmf') {
6899 $sx = $w*_MPDFK / $info['w'];
6900 $sy = -$h*_MPDFK / $info['h'];
6901 $outstring = sprintf('q %.3F 0 0 %.3F %.3F %.3F cm /FO%d Do Q', $sx, $sy, $x*_MPDFK-$sx*$info['x'], (($this->h-$y)*_MPDFK)-$sy*$info['y'], $info['i']);
6902 }
6903 else
6904 /*-- END IMAGES-WMF --*/
6905 if ($info['type']=='svg') {
6906 $sx = $w*_MPDFK / $info['w'];
6907 $sy = -$h*_MPDFK / $info['h'];
6908 $outstring = sprintf('q %.3F 0 0 %.3F %.3F %.3F cm /FO%d Do Q', $sx, $sy, $x*_MPDFK-$sx*$info['x'], (($this->h-$y)*_MPDFK)-$sy*$info['y'], $info['i']);
6909 }
6910 else {
6911 $outstring = sprintf("q %.3F 0 0 %.3F %.3F %.3F cm /I%d Do Q",$w*_MPDFK,$h*_MPDFK,$x*_MPDFK,($this->h-($y+$h))*_MPDFK,$info['i']);
6912 }
6913
6914 if ($this->watermarkImgBehind) {
6915 $outstring = $this->watermarkImgAlpha . "\n" . $outstring . "\n" . $this->SetAlpha(1, 'Normal', true) . "\n";
6916 $this->pages[$this->page] = preg_replace('/(___BACKGROUND___PATTERNS'.date('jY').')/', "\n".$outstring."\n".'\\1', $this->pages[$this->page]);
6917 }
6918 else { $this->_out($outstring); }
6919
6920 return 0;
6921 } // end of IF watermark
6922 /*-- END WATERMARK --*/
6923
6924 if ($constrain) {
6925 // Automatically resize to maximum dimensions of page if too large
6926 if (isset($this->blk[$this->blklvl]['inner_width']) && $this->blk[$this->blklvl]['inner_width']) { $maxw = $this->blk[$this->blklvl]['inner_width']; }
6927 else { $maxw = $this->pgwidth; }
6928 if ($w > $maxw) {
6929 $w = $maxw;
6930 $h=abs($w*$info['h']/$info['w']);
6931 }
6932 if ($h > $this->h - ($this->tMargin + $this->bMargin + 1)) { // see below - +10 to avoid drawing too close to border of page
6933 $h = $this->h - ($this->tMargin + $this->bMargin + 1) ;
6934 if ($this->fullImageHeight) { $h = $this->fullImageHeight; }
6935 $w=abs($h*$info['w']/$info['h']);
6936 }
6937
6938
6939 //Avoid drawing out of the paper(exceeding width limits).
6940 //if ( ($x + $w) > $this->fw ) {
6941 if ( ($x + $w) > $this->w ) {
6942 $x = $this->lMargin;
6943 $y += 5;
6944 }
6945
6946 $changedpage = false;
6947 $oldcolumn = $this->CurrCol;
6948 //Avoid drawing out of the page.
6949 if($y+$h>$this->PageBreakTrigger and !$this->InFooter and $this->AcceptPageBreak()) {
6950 $this->AddPage($this->CurOrientation);
6951 // Added to correct for OddEven Margins
6952 $x=$x +$this->MarginCorrection;
6953 $y = $tMargin + $this->margin_header;
6954 $changedpage = true;
6955 }
6956 /*-- COLUMNS --*/
6957 // COLS
6958 // COLUMN CHANGE
6959 if ($this->CurrCol != $oldcolumn) {
6960 $y = $this->y0;
6961 $x += $this->ChangeColumn * ($this->ColWidth+$this->ColGap);
6962 $this->x += $this->ChangeColumn * ($this->ColWidth+$this->ColGap);
6963 }
6964 /*-- END COLUMNS --*/
6965 } // end of IF constrain
6966
6967 /*-- IMAGES-WMF --*/
6968 if ($info['type']=='wmf') {
6969 $sx = $w*_MPDFK / $info['w'];
6970 $sy = -$h*_MPDFK / $info['h'];
6971 $outstring = sprintf('q %.3F 0 0 %.3F %.3F %.3F cm /FO%d Do Q', $sx, $sy, $x*_MPDFK-$sx*$info['x'], (($this->h-$y)*_MPDFK)-$sy*$info['y'], $info['i']);
6972 }
6973 else
6974 /*-- END IMAGES-WMF --*/
6975 if ($info['type']=='svg') {
6976 $sx = $w*_MPDFK / $info['w'];
6977 $sy = -$h*_MPDFK / $info['h'];
6978 $outstring = sprintf('q %.3F 0 0 %.3F %.3F %.3F cm /FO%d Do Q', $sx, $sy, $x*_MPDFK-$sx*$info['x'], (($this->h-$y)*_MPDFK)-$sy*$info['y'], $info['i']);
6979 }
6980 else {
6981 $outstring = sprintf("q %.3F 0 0 %.3F %.3F %.3F cm /I%d Do Q",$w*_MPDFK,$h*_MPDFK,$x*_MPDFK,($this->h-($y+$h))*_MPDFK,$info['i']);
6982 }
6983
6984 if($paint) {
6985 $this->_out($outstring);
6986 if($link) $this->Link($x,$y,$w,$h,$link);
6987
6988 // Avoid writing text on top of the image. // THIS WAS OUTSIDE THE if ($paint) bit!!!!!!!!!!!!!!!!
6989 $this->y = $y + $h;
6990 }
6991
6992 //Return width-height array
6993 $sizesarray['WIDTH'] = $w;
6994 $sizesarray['HEIGHT'] = $h;
6995 $sizesarray['X'] = $x; //Position before painting image
6996 $sizesarray['Y'] = $y; //Position before painting image
6997 $sizesarray['OUTPUT'] = $outstring;
6998
6999 $sizesarray['IMAGE_ID'] = $info['i'];
7000 $sizesarray['itype'] = $info['type'];
7001 $sizesarray['set-dpi'] = $info['set-dpi'];
7002 return $sizesarray;
7003 }
7004
7005
7006
7007 //=============================================================
7008 //=============================================================
7009 //=============================================================
7010 //=============================================================
7011 //=============================================================
7012 /*-- HTML-CSS --*/
7013
7014 function _getObjAttr($t) {
7015 $c = explode("\xbb\xa4\xac",$t,2);
7016 $c = explode(",",$c[1],2);
7017 foreach($c as $v) {
7018 $v = explode("=",$v,2);
7019 $sp[$v[0]] = $v[1];
7020 }
7021 return (unserialize($sp['objattr']));
7022 }
7023
7024
7025 function inlineObject($type,$x,$y,$objattr,$Lmargin,$widthUsed,$maxWidth,$lineHeight,$paint=false,$is_table=false)
7026 {
7027 if ($is_table) { $k = $this->shrin_k; } else { $k = 1; }
7028
7029 // NB $x is only used when paint=true
7030 // Lmargin not used
7031 $w = 0;
7032 if (isset($objattr['width'])) { $w = $objattr['width']/$k; }
7033 $h = 0;
7034 if (isset($objattr['height'])) { $h = abs($objattr['height']/$k); }
7035 $widthLeft = $maxWidth - $widthUsed;
7036 $maxHeight = $this->h - ($this->tMargin + $this->bMargin + 10) ;
7037 if ($this->fullImageHeight) { $maxHeight = $this->fullImageHeight; }
7038 // For Images
7039 if (isset($objattr['border_left'])) {
7040 $extraWidth = ($objattr['border_left']['w'] + $objattr['border_right']['w'] + $objattr['margin_left']+ $objattr['margin_right'])/$k;
7041 $extraHeight = ($objattr['border_top']['w'] + $objattr['border_bottom']['w'] + $objattr['margin_top']+ $objattr['margin_bottom'])/$k;
7042
7043 if ($type == 'image' || $type == 'barcode' || $type == 'textcircle') {
7044 $extraWidth += ($objattr['padding_left'] + $objattr['padding_right'])/$k;
7045 $extraHeight += ($objattr['padding_top'] + $objattr['padding_bottom'])/$k;
7046 }
7047 }
7048
7049 if (!isset($objattr['vertical-align'])) { $objattr['vertical-align'] = 'M'; }
7050
7051 if ($type == 'image' || (isset($objattr['subtype']) && $objattr['subtype'] == 'IMAGE')) {
7052 if (isset($objattr['itype']) && ($objattr['itype'] == 'wmf' || $objattr['itype'] == 'svg')) {
7053 $file = $objattr['file'];
7054 $info=$this->formobjects[$file];
7055 }
7056 else if (isset($objattr['file'])) {
7057 $file = $objattr['file'];
7058 $info=$this->images[$file];
7059 }
7060 }
7061 if ($type == 'annot' || $type == 'bookmark' || $type == 'indexentry' || $type == 'toc') {
7062 $w = 0.00001;
7063 $h = 0.00001;
7064 }
7065
7066 // TEST whether need to skipline
7067 if (!$paint) {
7068 if ($type == 'hr') { // always force new line
7069 if (($y + $h + $lineHeight > $this->PageBreakTrigger) && !$this->InFooter && !$is_table) { return array(-2, $w ,$h ); } // New page + new line
7070 else { return array(1, $w ,$h ); } // new line
7071 }
7072 else {
7073 if ($widthUsed > 0 && $w > $widthLeft && (!$is_table || $type != 'image')) { // New line needed
7074 if (($y + $h + $lineHeight > $this->PageBreakTrigger) && !$this->InFooter) { return array(-2,$w ,$h ); } // New page + new line
7075 return array(1,$w ,$h ); // new line
7076 }
7077 else if ($widthUsed > 0 && $w > $widthLeft && $is_table) { // New line needed in TABLE
7078 return array(1,$w ,$h ); // new line
7079 }
7080 // Will fit on line but NEW PAGE REQUIRED
7081 else if (($y + $h > $this->PageBreakTrigger) && !$this->InFooter && !$is_table) { return array(-1,$w ,$h ); }
7082 else { return array(0,$w ,$h ); }
7083 }
7084 }
7085
7086 if ($type == 'annot' || $type == 'bookmark' || $type == 'indexentry' || $type == 'toc') {
7087 $w = 0.00001;
7088 $h = 0.00001;
7089 $objattr['BORDER-WIDTH'] = 0;
7090 $objattr['BORDER-HEIGHT'] = 0;
7091 $objattr['BORDER-X'] = $x;
7092 $objattr['BORDER-Y'] = $y;
7093 $objattr['INNER-WIDTH'] = 0;
7094 $objattr['INNER-HEIGHT'] = 0;
7095 $objattr['INNER-X'] = $x;
7096 $objattr['INNER-Y'] = $y;
7097 }
7098
7099 if ($type == 'image') {
7100 // Automatically resize to width remaining
7101 if ($w > $widthLeft && !$is_table) {
7102 $w = $widthLeft ;
7103 $h=abs($w*$info['h']/$info['w']);
7104 }
7105 $img_w = $w - $extraWidth ;
7106 $img_h = $h - $extraHeight ;
7107
7108 $objattr['BORDER-WIDTH'] = $img_w + $objattr['padding_left']/$k + $objattr['padding_right']/$k + (($objattr['border_left']['w']/$k + $objattr['border_right']['w']/$k)/2) ;
7109 $objattr['BORDER-HEIGHT'] = $img_h + $objattr['padding_top']/$k + $objattr['padding_bottom']/$k + (($objattr['border_top']['w']/$k + $objattr['border_bottom']['w']/$k)/2) ;
7110 $objattr['BORDER-X'] = $x + $objattr['margin_left']/$k + (($objattr['border_left']['w']/$k)/2) ;
7111 $objattr['BORDER-Y'] = $y + $objattr['margin_top']/$k + (($objattr['border_top']['w']/$k)/2) ;
7112 $objattr['INNER-WIDTH'] = $img_w;
7113 $objattr['INNER-HEIGHT'] = $img_h;
7114 $objattr['INNER-X'] = $x + $objattr['padding_left']/$k + $objattr['margin_left']/$k + ($objattr['border_left']['w']/$k);
7115 $objattr['INNER-Y'] = $y + $objattr['padding_top']/$k + $objattr['margin_top']/$k + ($objattr['border_top']['w']/$k) ;
7116 $objattr['ID'] = $info['i'];
7117 }
7118
7119 if ($type == 'input' && $objattr['subtype'] == 'IMAGE') {
7120 $img_w = $w - $extraWidth ;
7121 $img_h = $h - $extraHeight ;
7122 $objattr['BORDER-WIDTH'] = $img_w + (($objattr['border_left']['w']/$k + $objattr['border_right']['w']/$k)/2) ;
7123 $objattr['BORDER-HEIGHT'] = $img_h + (($objattr['border_top']['w']/$k + $objattr['border_bottom']['w']/$k)/2) ;
7124 $objattr['BORDER-X'] = $x + $objattr['margin_left']/$k + (($objattr['border_left']['w']/$k)/2) ;
7125 $objattr['BORDER-Y'] = $y + $objattr['margin_top']/$k + (($objattr['border_top']['w']/$k)/2) ;
7126 $objattr['INNER-WIDTH'] = $img_w;
7127 $objattr['INNER-HEIGHT'] = $img_h;
7128 $objattr['INNER-X'] = $x + $objattr['margin_left']/$k + ($objattr['border_left']['w']/$k);
7129 $objattr['INNER-Y'] = $y + $objattr['margin_top']/$k + ($objattr['border_top']['w']/$k) ;
7130 $objattr['ID'] = $info['i'];
7131 }
7132
7133 if ($type == 'barcode' || $type == 'textcircle') {
7134 $b_w = $w - $extraWidth ;
7135 $b_h = $h - $extraHeight ;
7136 $objattr['BORDER-WIDTH'] = $b_w + $objattr['padding_left']/$k + $objattr['padding_right']/$k + (($objattr['border_left']['w']/$k + $objattr['border_right']['w']/$k)/2) ;
7137 $objattr['BORDER-HEIGHT'] = $b_h + $objattr['padding_top']/$k + $objattr['padding_bottom']/$k + (($objattr['border_top']['w']/$k + $objattr['border_bottom']['w']/$k)/2) ;
7138 $objattr['BORDER-X'] = $x + $objattr['margin_left']/$k + (($objattr['border_left']['w']/$k)/2) ;
7139 $objattr['BORDER-Y'] = $y + $objattr['margin_top']/$k + (($objattr['border_top']['w']/$k)/2) ;
7140 $objattr['INNER-X'] = $x + $objattr['padding_left']/$k + $objattr['margin_left']/$k + ($objattr['border_left']['w']/$k);
7141 $objattr['INNER-Y'] = $y + $objattr['padding_top']/$k + $objattr['margin_top']/$k + ($objattr['border_top']['w']/$k) ;
7142 $objattr['INNER-WIDTH'] = $b_w;
7143 $objattr['INNER-HEIGHT'] = $b_h;
7144 }
7145
7146
7147 if ($type == 'textarea') {
7148 // Automatically resize to width remaining
7149 if ($w > $widthLeft && !$is_table) {
7150 $w = $widthLeft ;
7151 }
7152 if (($y + $h > $this->PageBreakTrigger) && !$this->InFooter) {
7153 $h=$this->h - $y - $this->bMargin;
7154 }
7155 }
7156
7157 if ($type == 'hr') {
7158 if ($is_table) {
7159 $objattr['INNER-WIDTH'] = $maxWidth * $objattr['W-PERCENT']/100;
7160 $objattr['width'] = $objattr['INNER-WIDTH'];
7161 $w = $maxWidth;
7162 }
7163 else {
7164 if ($w>$maxWidth) { $w = $maxWidth; }
7165 $objattr['INNER-WIDTH'] = $w;
7166 $w = $maxWidth;
7167 }
7168 }
7169
7170
7171
7172 if (($type == 'select') || ($type == 'input' && ($objattr['subtype'] == 'TEXT' || $objattr['subtype'] == 'PASSWORD'))) {
7173 // Automatically resize to width remaining
7174 if ($w > $widthLeft && !$is_table) {
7175 $w = $widthLeft;
7176 }
7177 }
7178
7179 if ($type == 'textarea' || $type == 'select' || $type == 'input') {
7180 if (isset($objattr['fontsize'])) $objattr['fontsize'] /= $k;
7181 if (isset($objattr['linewidth'])) $objattr['linewidth'] /= $k;
7182 }
7183
7184 if (!isset($objattr['BORDER-Y'])) { $objattr['BORDER-Y'] = 0; }
7185 if (!isset($objattr['BORDER-X'])) { $objattr['BORDER-X'] = 0; }
7186 if (!isset($objattr['INNER-Y'])) { $objattr['INNER-Y'] = 0; }
7187 if (!isset($objattr['INNER-X'])) { $objattr['INNER-X'] = 0; }
7188
7189 //Return width-height array
7190 $objattr['OUTER-WIDTH'] = $w;
7191 $objattr['OUTER-HEIGHT'] = $h;
7192 $objattr['OUTER-X'] = $x;
7193 $objattr['OUTER-Y'] = $y;
7194 return $objattr;
7195 }
7196
7197 /*-- END HTML-CSS --*/
7198
7199 //=============================================================
7200 //=============================================================
7201 //=============================================================
7202 //=============================================================
7203 //=============================================================
7204
7205 function SetLineJoin($mode=0)
7206 {
7207 $s=sprintf('%d j',$mode);
7208 if($this->page>0 && ((isset($this->pageoutput[$this->page]['LineJoin']) && $this->pageoutput[$this->page]['LineJoin'] != $s) || !isset($this->pageoutput[$this->page]['LineJoin']) || $this->keep_block_together)) { $this->_out($s); }
7209 $this->pageoutput[$this->page]['LineJoin'] = $s;
7210
7211 }
7212 function SetLineCap($mode=2) {
7213 $s=sprintf('%d J',$mode);
7214 if($this->page>0 && ((isset($this->pageoutput[$this->page]['LineCap']) && $this->pageoutput[$this->page]['LineCap'] != $s) || !isset($this->pageoutput[$this->page]['LineCap']) || $this->keep_block_together)) { $this->_out($s); }
7215 $this->pageoutput[$this->page]['LineCap'] = $s;
7216
7217 }
7218
7219 function SetDash($black=false,$white=false)
7220 {
7221 if($black and $white) $s=sprintf('[%.3F %.3F] 0 d',$black*_MPDFK,$white*_MPDFK);
7222 else $s='[] 0 d';
7223 if($this->page>0 && ((isset($this->pageoutput[$this->page]['Dash']) && $this->pageoutput[$this->page]['Dash'] != $s) || !isset($this->pageoutput[$this->page]['Dash']) || $this->keep_block_together)) { $this->_out($s); }
7224 $this->pageoutput[$this->page]['Dash'] = $s;
7225
7226 }
7227
7228 function SetDisplayPreferences($preferences) {
7229 // String containing any or none of /HideMenubar/HideToolbar/HideWindowUI/DisplayDocTitle/CenterWindow/FitWindow
7230 $this->DisplayPreferences .= $preferences;
7231 }
7232
7233
7234 function Ln($h='',$collapsible=0)
7235 {
7236 // Added collapsible to allow collapsible top-margin on new page
7237 //Line feed; default value is last cell height
7238 $this->x = $this->lMargin + $this->blk[$this->blklvl]['outer_left_margin'];
7239 if ($collapsible && ($this->y==$this->tMargin) && (!$this->ColActive)) { $h = 0; }
7240 if(is_string($h)) $this->y+=$this->lasth;
7241 else $this->y+=$h;
7242 }
7243
7244 /*-- HTML-CSS --*/
7245 // $state = 0 normal; 1 top; 2 bottom; 3 top and bottom
7246 function DivLn($h,$level=-3,$move_y=true,$collapsible=false,$state=0) {
7247 // this->x is returned as it was
7248 // adds lines (y) where DIV bgcolors are filled in
7249 // allows .00001 as nominal height used for bookmarks/annotations etc.
7250 if ($collapsible && (sprintf("%0.4f", $this->y)==sprintf("%0.4f", $this->tMargin)) && (!$this->ColActive)) { return; }
7251 if ($collapsible && (sprintf("%0.4f", $this->y)==sprintf("%0.4f", $this->y0)) && ($this->ColActive) && $this->CurrCol == 0) { return; } // *COLUMNS*
7252
7253 // Still use this method if columns or page-break-inside: avoid, as it allows repositioning later
7254 // otherwise, now uses PaintDivBB()
7255 if (!$this->ColActive && !$this->keep_block_together && !$this->kwt) {
7256 if ($move_y && !$this->ColActive) { $this->y += $h; }
7257 return;
7258 }
7259
7260 if ($level == -3) { $level = $this->blklvl; }
7261 $firstblockfill = $this->GetFirstBlockFill();
7262 if ($firstblockfill && $this->blklvl > 0 && $this->blklvl >= $firstblockfill) {
7263 $last_x = 0;
7264 $last_w = 0;
7265 $last_fc = $this->FillColor;
7266 $bak_x = $this->x;
7267 $bak_h = $this->divheight;
7268 $this->divheight = 0; // Temporarily turn off divheight - as Cell() uses it to check for PageBreak
7269 for ($blvl=$firstblockfill;$blvl<=$level;$blvl++) {
7270 $this->SetBlockFill($blvl);
7271 $this->x = $this->lMargin + $this->blk[$blvl]['outer_left_margin'];
7272 if ($last_x != $this->lMargin + $this->blk[$blvl]['outer_left_margin'] || $last_w != $this->blk[$blvl]['width'] || $last_fc != $this->FillColor || $this->blk[$blvl]['border_top']['s'] || $this->blk[$blvl]['border_bottom']['s'] || $this->blk[$blvl]['border_left']['s'] || $this->blk[$blvl]['border_right']['s']) { // mPDF 5.6.55
7273 $x = $this->x;
7274 $this->Cell( ($this->blk[$blvl]['width']), $h, '', '', 0, '', 1);
7275 if (!$this->keep_block_together && !$this->writingHTMLheader && !$this->writingHTMLfooter) {
7276 $this->x = $x;
7277 // $state = 0 normal; 1 top; 2 bottom; 3 top and bottom
7278 if ($blvl == $this->blklvl) { $this->PaintDivLnBorder($state,$blvl,$h); }
7279 else { $this->PaintDivLnBorder(0,$blvl,$h); }
7280 }
7281 }
7282 $last_x = $this->lMargin + $this->blk[$blvl]['outer_left_margin'];
7283 $last_w = $this->blk[$blvl]['width'];
7284 $last_fc = $this->FillColor;
7285 }
7286 // Reset current block fill
7287 if (isset($this->blk[$this->blklvl]['bgcolorarray'])) {
7288 $bcor = $this->blk[$this->blklvl]['bgcolorarray'];
7289 $this->SetFColor($bcor);
7290 }
7291 $this->x = $bak_x;
7292 $this->divheight = $bak_h;
7293 }
7294 if ($move_y) { $this->y += $h; }
7295 }
7296 /*-- END HTML-CSS --*/
7297
7298
7299 function SetX($x)
7300 {
7301 //Set x position
7302 if($x >= 0) $this->x=$x;
7303 else $this->x = $this->w + $x;
7304 }
7305
7306 function SetY($y)
7307 {
7308 //Set y position and reset x
7309 $this->x=$this->lMargin;
7310 if($y>=0)
7311 $this->y=$y;
7312 else
7313 $this->y=$this->h+$y;
7314 }
7315
7316 function SetXY($x,$y)
7317 {
7318 //Set x and y positions
7319 $this->SetY($y);
7320 $this->SetX($x);
7321 }
7322
7323
7324 function Output($name='',$dest='')
7325 {
7326 //Output PDF to some destination
7327 if ($this->showStats) {
7328 echo '<div>Generated in '.sprintf('%.2F',(microtime(true) - $this->time0)).' seconds</div>';
7329 }
7330 //Finish document if necessary
7331 if ($this->progressBar) { $this->UpdateProgressBar(1,'100','Finished'); } // *PROGRESS-BAR*
7332 if($this->state < 3) $this->Close();
7333 if ($this->progressBar) { $this->UpdateProgressBar(2,'100','Finished'); } // *PROGRESS-BAR*
7334 // fn. error_get_last is only in PHP>=5.2
7335 if ($this->debug && function_exists('error_get_last') && error_get_last()) {
7336 $e = error_get_last();
7337 if (($e['type'] < 2048 && $e['type'] != 8) || (intval($e['type']) & intval(ini_get("error_reporting")))) {
7338 echo "<p>Error message detected - PDF file generation aborted.</p>";
7339 echo $e['message'].'<br />';
7340 echo 'File: '.$e['file'].'<br />';
7341 echo 'Line: '.$e['line'].'<br />';
7342 exit;
7343 }
7344 }
7345
7346
7347 if (($this->PDFA || $this->PDFX) && $this->encrypted) { $this->Error("PDFA1-b or PDFX/1-a does not permit encryption of documents."); }
7348 if (count($this->PDFAXwarnings) && (($this->PDFA && !$this->PDFAauto) || ($this->PDFX && !$this->PDFXauto))) {
7349 if ($this->PDFA) {
7350 echo '<div>WARNING - This file could not be generated as it stands as a PDFA1-b compliant file.</div>';
7351 echo '<div>These issues can be automatically fixed by mPDF using <i>$mpdf-&gt;PDFAauto=true;</i></div>';
7352 echo '<div>Action that mPDF will take to automatically force PDFA1-b compliance are shown in brackets.</div>';
7353 }
7354 else {
7355 echo '<div>WARNING - This file could not be generated as it stands as a PDFX/1-a compliant file.</div>';
7356 echo '<div>These issues can be automatically fixed by mPDF using <i>$mpdf-&gt;PDFXauto=true;</i></div>';
7357 echo '<div>Action that mPDF will take to automatically force PDFX/1-a compliance are shown in brackets.</div>';
7358 }
7359 echo '<div>Warning(s) generated:</div><ul>';
7360 $this->PDFAXwarnings = array_unique($this->PDFAXwarnings);
7361 foreach($this->PDFAXwarnings AS $w) {
7362 echo '<li>'.$w.'</li>';
7363 }
7364 echo '</ul>';
7365 exit;
7366 }
7367
7368 if ($this->showStats) {
7369 echo '<div>Compiled in '.sprintf('%.2F',(microtime(true) - $this->time0)).' seconds (total)</div>';
7370 echo '<div>Peak Memory usage '.number_format((memory_get_peak_usage(true)/(1024*1024)),2).' MB</div>';
7371 echo '<div>PDF file size '.number_format((strlen($this->buffer)/1024)).' kB</div>';
7372 echo '<div>Number of fonts '.count($this->fonts).'</div>';
7373 exit;
7374 }
7375
7376
7377 if(is_bool($dest)) $dest=$dest ? 'D' : 'F';
7378 $dest=strtoupper($dest);
7379 if($dest=='') {
7380 if($name=='') {
7381 $name='mpdf.pdf';
7382 $dest='I';
7383 }
7384 else { $dest='F'; }
7385 }
7386
7387 /*-- PROGRESS-BAR --*/
7388 if ($this->progressBar && ($dest=='D' || $dest=='I')) {
7389 if($name=='') { $name='mpdf.pdf'; }
7390 $tempfile = '_tempPDF'.RAND(1,10000);
7391 //Save to local file
7392 $f=fopen(_MPDF_TEMP_PATH.$tempfile.'.pdf','wb');
7393 if(!$f) $this->Error('Unable to create temporary output file: '.$tempfile.'.pdf');
7394 fwrite($f,$this->buffer,strlen($this->buffer));
7395 fclose($f);
7396 $this->UpdateProgressBar(3,'','Finished');
7397
7398 echo '<script type="text/javascript">
7399
7400 var form = document.createElement("form");
7401 form.setAttribute("method", "post");
7402 form.setAttribute("action", "'._MPDF_URI.'includes/out.php");
7403
7404 var hiddenField = document.createElement("input");
7405 hiddenField.setAttribute("type", "hidden");
7406 hiddenField.setAttribute("name", "filename");
7407 hiddenField.setAttribute("value", "'.$tempfile.'");
7408 form.appendChild(hiddenField);
7409
7410 var hiddenField = document.createElement("input");
7411 hiddenField.setAttribute("type", "hidden");
7412 hiddenField.setAttribute("name", "dest");
7413 hiddenField.setAttribute("value", "'.$dest.'");
7414 form.appendChild(hiddenField);
7415
7416 var hiddenField = document.createElement("input");
7417 hiddenField.setAttribute("type", "hidden");
7418 hiddenField.setAttribute("name", "opname");
7419 hiddenField.setAttribute("value", "'.$name.'");
7420 form.appendChild(hiddenField);
7421
7422 var hiddenField = document.createElement("input");
7423 hiddenField.setAttribute("type", "hidden");
7424 hiddenField.setAttribute("name", "path");
7425 hiddenField.setAttribute("value", "'.urlencode(_MPDF_TEMP_PATH).'");
7426 form.appendChild(hiddenField);
7427
7428 document.body.appendChild(form);
7429 form.submit();
7430
7431 </script>
7432 </div>
7433 </body>
7434 </html>';
7435 exit;
7436 }
7437 else {
7438 if ($this->progressBar) { $this->UpdateProgressBar(3,'','Finished'); }
7439 /*-- END PROGRESS-BAR --*/
7440
7441 switch($dest) {
7442 case 'I':
7443 if ($this->debug && !$this->allow_output_buffering && ob_get_contents()) { echo "<p>Output has already been sent from the script - PDF file generation aborted.</p>"; exit; }
7444 //Send to standard output
7445 if(PHP_SAPI!='cli') {
7446 //We send to a browser
7447 header('Content-Type: application/pdf');
7448 if(headers_sent())
7449 $this->Error('Some data has already been output to browser, can\'t send PDF file');
7450 if (!isset($_SERVER['HTTP_ACCEPT_ENCODING']) OR empty($_SERVER['HTTP_ACCEPT_ENCODING'])) {
7451 // don't use length if server using compression
7452 header('Content-Length: '.strlen($this->buffer));
7453 }
7454 header('Content-disposition: inline; filename="'.$name.'"');
7455 header('Cache-Control: public, must-revalidate, max-age=0');
7456 header('Pragma: public');
7457 header('Expires: Sat, 26 Jul 1997 05:00:00 GMT');
7458 header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT');
7459 }
7460 echo $this->buffer;
7461 break;
7462 case 'D':
7463 //Download file
7464 header('Content-Description: File Transfer');
7465 if (headers_sent())
7466 $this->Error('Some data has already been output to browser, can\'t send PDF file');
7467 header('Content-Transfer-Encoding: binary');
7468 header('Cache-Control: public, must-revalidate, max-age=0');
7469 header('Pragma: public');
7470 header('Expires: Sat, 26 Jul 1997 05:00:00 GMT');
7471 header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT');
7472 header('Content-Type: application/force-download');
7473 header('Content-Type: application/octet-stream', false);
7474 header('Content-Type: application/download', false);
7475 header('Content-Type: application/pdf', false);
7476 if (!isset($_SERVER['HTTP_ACCEPT_ENCODING']) OR empty($_SERVER['HTTP_ACCEPT_ENCODING'])) {
7477 // don't use length if server using compression
7478 header('Content-Length: '.strlen($this->buffer));
7479 }
7480 header('Content-disposition: attachment; filename="'.$name.'"');
7481 echo $this->buffer;
7482 break;
7483 case 'F':
7484 //Save to local file
7485 $f=fopen($name,'wb');
7486 if(!$f) $this->Error('Unable to create output file: '.$name);
7487 fwrite($f,$this->buffer,strlen($this->buffer));
7488 fclose($f);
7489 break;
7490 case 'S':
7491 //Return as a string
7492 return $this->buffer;
7493 default:
7494 $this->Error('Incorrect output destination: '.$dest);
7495 }
7496
7497 } // *PROGRESS-BAR*
7498 //======================================================================================================
7499 // DELETE OLD TMP FILES - Housekeeping
7500 // Delete any files in tmp/ directory that are >1 hrs old
7501 $interval = 3600;
7502 if ($handle = opendir(preg_replace('/\/$/','',_MPDF_TEMP_PATH))) {
7503 while (false !== ($file = readdir($handle))) {
7504 if (!is_dir($file) && ((filemtime(_MPDF_TEMP_PATH.$file)+$interval) < time()) && ($file != "..") && ($file != ".")) { // mPDF 5.4.19
7505 unlink(_MPDF_TEMP_PATH.$file);
7506 }
7507 }
7508 closedir($handle);
7509 }
7510 //==============================================================================================================
7511
7512 return '';
7513 }
7514
7515
7516 // *****************************************************************************
7517 // *
7518 // Protected methods *
7519 // *
7520 // *****************************************************************************
7521 function _dochecks()
7522 {
7523 //Check for locale-related bug
7524 if(1.1==1)
7525 $this->Error('Don\'t alter the locale before including mPDF');
7526 //Check for decimal separator
7527 if(sprintf('%.1f',1.0)!='1.0')
7528 setlocale(LC_NUMERIC,'C');
7529 // mPDF 5.4.11
7530 $mqr=ini_get("magic_quotes_runtime");
7531 if ($mqr) { $this->Error('mPDF requires magic_quotes_runtime to be turned off e.g. by using ini_set("magic_quotes_runtime", 0);'); }
7532 }
7533
7534 function _begindoc()
7535 {
7536 //Start document
7537 $this->state=1;
7538 $this->_out('%PDF-'.$this->pdf_version);
7539 $this->_out('%'.chr(226).chr(227).chr(207).chr(211)); // 4 chars > 128 to show binary file
7540 }
7541
7542
7543 /*-- HTMLHEADERS-FOOTERS --*/
7544 function _puthtmlheaders() {
7545 $this->state=2;
7546 $nb=$this->page;
7547 for($n=1;$n<=$nb;$n++) {
7548 if ($this->mirrorMargins && $n%2==0) { $OE = 'E'; } // EVEN
7549 else { $OE = 'O'; }
7550 $this->page = $n;
7551 if (isset($this->saveHTMLHeader[$n][$OE])) {
7552 $html = $this->saveHTMLHeader[$n][$OE]['html'];
7553 $this->lMargin = $this->saveHTMLHeader[$n][$OE]['ml'];
7554 $this->rMargin = $this->saveHTMLHeader[$n][$OE]['mr'];
7555 $this->tMargin = $this->saveHTMLHeader[$n][$OE]['mh'];
7556 $this->bMargin = $this->saveHTMLHeader[$n][$OE]['mf'];
7557 $this->margin_header = $this->saveHTMLHeader[$n][$OE]['mh'];
7558 $this->margin_footer = $this->saveHTMLHeader[$n][$OE]['mf'];
7559 $this->w = $this->saveHTMLHeader[$n][$OE]['pw'];
7560 $this->h = $this->saveHTMLHeader[$n][$OE]['ph'];
7561 $rotate = (isset($this->saveHTMLHeader[$n][$OE]['rotate']) ? $this->saveHTMLHeader[$n][$OE]['rotate'] : null);
7562 $this->Reset();
7563 $this->pageoutput[$n] = array();
7564 $this->pgwidth = $this->w - $this->lMargin - $this->rMargin;
7565 $this->x = $this->lMargin;
7566 $this->y = $this->margin_header;
7567 // mPDF 5.6.47
7568 $pn = $this->docPageNum($n);
7569 if ($pn)
7570 $pnstr = $this->pagenumPrefix.$pn.$this->pagenumSuffix;
7571 else { $pnstr = ''; }
7572 $html = str_replace('{PAGENO}',$pnstr,$html);
7573 $pnt = $this->docPageNumTotal($n);
7574 if ($pnt)
7575 $pntstr = $this->nbpgPrefix.$pnt.$this->nbpgSuffix;
7576 else { $pntstr = ''; }
7577 $html = str_replace($this->aliasNbPgGp,$pntstr,$html ); // {nbpg}
7578 $html = str_replace($this->aliasNbPg,$nb,$html ); // {nb}
7579 $html = preg_replace('/\{DATE\s+(.*?)\}/e',"date('\\1')",$html );
7580
7581 $this->HTMLheaderPageLinks = array();
7582 $this->HTMLheaderPageAnnots = array();
7583 $this->HTMLheaderPageForms = array();
7584 $this->pageBackgrounds = array();
7585
7586 $this->writingHTMLheader = true;
7587 $this->WriteHTML($html , 4); // parameter 4 saves output to $this->headerbuffer
7588 $this->writingHTMLheader = false;
7589 $this->Reset();
7590 $this->pageoutput[$n] = array();
7591
7592 $s = $this->PrintPageBackgrounds();
7593 $this->headerbuffer = $s . $this->headerbuffer;
7594 $os = '';
7595 if ($rotate) {
7596 $os .= sprintf('q 0 -1 1 0 0 %.3F cm ',($this->w*_MPDFK));
7597 }
7598 $os .= $this->headerbuffer ;
7599 if ($rotate) {
7600 $os .= ' Q' . "\n";
7601 }
7602
7603 // Writes over the page background but behind any other output on page
7604 $os = preg_replace('/\\\\/','\\\\\\\\',$os);
7605 $this->pages[$n] = preg_replace('/(___HEADER___MARKER'.date('jY').')/', "\n".$os."\n".'\\1', $this->pages[$n]);
7606
7607 $lks = $this->HTMLheaderPageLinks;
7608 foreach($lks AS $lk) {
7609 if ($rotate) {
7610 $lw = $lk[2];
7611 $lh = $lk[3];
7612 $lk[2] = $lh;
7613 $lk[3] = $lw; // swap width and height
7614 $ax = $lk[0]/_MPDFK;
7615 $ay = $lk[1]/_MPDFK;
7616 $bx = $ay-($lh/_MPDFK);
7617 $by = $this->w-$ax;
7618 $lk[0] = $bx*_MPDFK;
7619 $lk[1] = ($this->h-$by)*_MPDFK - $lw;
7620 }
7621 $this->PageLinks[$n][]=$lk;
7622 }
7623 /*-- FORMS --*/
7624 foreach($this->HTMLheaderPageForms AS $f) {
7625 $this->form->forms[$f['n']] = $f;
7626 }
7627 /*-- END FORMS --*/
7628
7629
7630 }
7631 if (isset($this->saveHTMLFooter[$n][$OE])) {
7632 $html = $this->saveHTMLFooter[$this->page][$OE]['html'];
7633 $this->lMargin = $this->saveHTMLFooter[$n][$OE]['ml'];
7634 $this->rMargin = $this->saveHTMLFooter[$n][$OE]['mr'];
7635 $this->tMargin = $this->saveHTMLFooter[$n][$OE]['mh'];
7636 $this->bMargin = $this->saveHTMLFooter[$n][$OE]['mf'];
7637 $this->margin_header = $this->saveHTMLFooter[$n][$OE]['mh'];
7638 $this->margin_footer = $this->saveHTMLFooter[$n][$OE]['mf'];
7639 $this->w = $this->saveHTMLFooter[$n][$OE]['pw'];
7640 $this->h = $this->saveHTMLFooter[$n][$OE]['ph'];
7641 $rotate = (isset($this->saveHTMLFooter[$n][$OE]['rotate']) ? $this->saveHTMLFooter[$n][$OE]['rotate'] : null);
7642 $this->Reset();
7643 $this->pageoutput[$n] = array();
7644 $this->pgwidth = $this->w - $this->lMargin - $this->rMargin;
7645 $this->x = $this->lMargin;
7646 $top_y = $this->y = $this->h - $this->margin_footer;
7647
7648 // if bottom-margin==0, corrects to avoid division by zero
7649 if ($this->y == $this->h) { $top_y = $this->y = ($this->h - 0.1); }
7650 // mPDF 5.6.47
7651 $pn = $this->docPageNum($n);
7652 if ($pn)
7653 $pnstr = $this->pagenumPrefix.$pn.$this->pagenumSuffix;
7654 else { $pnstr = ''; }
7655 $html = str_replace('{PAGENO}',$pnstr,$html);
7656 $pnt = $this->docPageNumTotal($n);
7657 if ($pnt)
7658 $pntstr = $this->nbpgPrefix.$pnt.$this->nbpgSuffix;
7659 else { $pntstr = ''; }
7660 $html = str_replace($this->aliasNbPgGp,$pntstr,$html ); // {nbpg}
7661 $html = str_replace($this->aliasNbPg,$nb,$html ); // {nb}
7662 $html = preg_replace('/\{DATE\s+(.*?)\}/e',"date('\\1')",$html );
7663
7664
7665 $this->HTMLheaderPageLinks = array();
7666 $this->HTMLheaderPageAnnots = array();
7667 $this->HTMLheaderPageForms = array();
7668 $this->pageBackgrounds = array();
7669
7670 $this->writingHTMLfooter = true;
7671 $this->InFooter = true;
7672 $this->WriteHTML($html , 4); // parameter 4 saves output to $this->headerbuffer
7673 $this->writingHTMLfooter = false;
7674 $this->InFooter = false;
7675 $this->Reset();
7676 $this->pageoutput[$n] = array();
7677
7678 $fheight = $this->y - $top_y;
7679 $adj = -$fheight;
7680
7681 $s = $this->PrintPageBackgrounds(-$adj);
7682 $this->headerbuffer = $s . $this->headerbuffer;
7683
7684 $os = '';
7685 $os .= $this->StartTransform(true)."\n";
7686 if ($rotate) {
7687 $os .= sprintf('q 0 -1 1 0 0 %.3F cm ',($this->w*_MPDFK));
7688 }
7689 $os .= $this->transformTranslate(0, $adj, true)."\n";
7690 $os .= $this->headerbuffer ;
7691 if ($rotate) {
7692 $os .= ' Q' . "\n";
7693 }
7694 $os .= $this->StopTransform(true)."\n";
7695 // Writes over the page background but behind any other output on page
7696 $os = preg_replace('/\\\\/','\\\\\\\\',$os);
7697 $this->pages[$n] = preg_replace('/(___HEADER___MARKER'.date('jY').')/', "\n".$os."\n".'\\1', $this->pages[$n]);
7698
7699 $lks = $this->HTMLheaderPageLinks;
7700 foreach($lks AS $lk) {
7701 $lk[1] -= $adj*_MPDFK;
7702 if ($rotate) {
7703 $lw = $lk[2];
7704 $lh = $lk[3];
7705 $lk[2] = $lh;
7706 $lk[3] = $lw; // swap width and height
7707
7708 $ax = $lk[0]/_MPDFK;
7709 $ay = $lk[1]/_MPDFK;
7710 $bx = $ay-($lh/_MPDFK);
7711 $by = $this->w-$ax;
7712 $lk[0] = $bx*_MPDFK;
7713 $lk[1] = ($this->h-$by)*_MPDFK - $lw;
7714 }
7715 $this->PageLinks[$n][]=$lk;
7716 }
7717 /*-- FORMS --*/
7718 foreach($this->HTMLheaderPageForms AS $f) {
7719 $f['y'] += $adj;
7720 $this->form->forms[$f['n']] = $f;
7721 }
7722 /*-- END FORMS --*/
7723 }
7724 }
7725 $this->page=$nb;
7726 $this->state=1;
7727 }
7728 /*-- END HTMLHEADERS-FOOTERS --*/
7729
7730
7731 function _putpages()
7732 {
7733 $nb=$this->page;
7734 $filter=($this->compress) ? '/Filter /FlateDecode ' : '';
7735
7736 if($this->DefOrientation=='P') {
7737 $defwPt=$this->fwPt;
7738 $defhPt=$this->fhPt;
7739 }
7740 else {
7741 $defwPt=$this->fhPt;
7742 $defhPt=$this->fwPt;
7743 }
7744 $annotid=(3+2*$nb);
7745
7746 // Active Forms
7747 $totaladdnum = 0;
7748 for($n=1;$n<=$nb;$n++) {
7749 if (isset($this->PageLinks[$n])) { $totaladdnum += count($this->PageLinks[$n]); }
7750 /*-- ANNOTATIONS --*/
7751 if (isset($this->PageAnnots[$n])) {
7752 foreach ($this->PageAnnots[$n] as $k => $pl) {
7753 if (!empty($pl['opt']['popup']) || !empty($pl['opt']['file'])) { $totaladdnum += 2 ; }
7754 else { $totaladdnum++; }
7755 }
7756 }
7757 /*-- END ANNOTATIONS --*/
7758
7759 /*-- FORMS --*/
7760 if ( count($this->form->forms) > 0 ) {
7761 $this->form->countPageForms($n, $totaladdnum);
7762 }
7763 /*-- END FORMS --*/
7764 }
7765 /*-- FORMS --*/
7766 // Make a note in the radio button group of the obj_id it will have
7767 $ctr = 0;
7768 if (count($this->form->form_radio_groups)) {
7769 foreach($this->form->form_radio_groups AS $name=>$frg) {
7770 $this->form->form_radio_groups[$name]['obj_id'] = $annotid + $totaladdnum + $ctr;
7771 $ctr++;
7772 }
7773 }
7774 /*-- END FORMS --*/
7775
7776 // Select unused fonts (usually default font)
7777 $unused = array();
7778 foreach($this->fonts as $fk=>$font) {
7779 if (!$font['used'] && ($font['type']=='TTF')) {
7780 $unused[] = $fk;
7781 }
7782 }
7783
7784
7785 for($n=1;$n<=$nb;$n++)
7786 {
7787 $thispage = $this->pages[$n];
7788 // unset($this->pages[$n]); // mPDF 5.6.47
7789 if(isset($this->OrientationChanges[$n])) {
7790 $hPt=$this->pageDim[$n]['w']*_MPDFK;
7791 $wPt=$this->pageDim[$n]['h']*_MPDFK;
7792 $owidthPt_LR = $this->pageDim[$n]['outer_width_TB']*_MPDFK;
7793 $owidthPt_TB = $this->pageDim[$n]['outer_width_LR']*_MPDFK;
7794 }
7795 else {
7796 $wPt=$this->pageDim[$n]['w']*_MPDFK;
7797 $hPt=$this->pageDim[$n]['h']*_MPDFK;
7798 $owidthPt_LR = $this->pageDim[$n]['outer_width_LR']*_MPDFK;
7799 $owidthPt_TB = $this->pageDim[$n]['outer_width_TB']*_MPDFK;
7800 }
7801 // Remove references to unused fonts (usually default font)
7802 foreach($unused as $fk) {
7803 if ($this->fonts[$fk]['sip'] || $this->fonts[$fk]['smp']) {
7804 foreach($this->fonts[$fk]['subsetfontids'] AS $k => $fid) {
7805 $thispage = preg_replace('/\s\/F'.$fid.' \d[\d.]* Tf\s/is',' ',$thispage);
7806 }
7807 }
7808 else {
7809 $thispage = preg_replace('/\s\/F'.$this->fonts[$fk]['i'].' \d[\d.]* Tf\s/is',' ',$thispage);
7810 }
7811 }
7812 //Replace number of pages
7813 if(!empty($this->aliasNbPg)) {
7814 if (!$this->onlyCoreFonts) { $s1 = $this->UTF8ToUTF16BE($this->aliasNbPg, false); }
7815 $s2 = $this->aliasNbPg;
7816 if (!$this->onlyCoreFonts) { $r1 = $this->UTF8ToUTF16BE($nb, false); }
7817 $r2 = $nb;
7818 if (preg_match_all('/{mpdfheadernbpg (C|R) ff=(\S*) fs=(\S*) fz=(.*?)}/',$thispage,$m)) {
7819 for($hi=0;$hi<count($m[0]);$hi++) {
7820 $pos = $m[1][$hi];
7821 $hff = $m[2][$hi];
7822 $hfst = $m[3][$hi];
7823 $hfsz = $m[4][$hi];
7824 $this->SetFont($hff,$hfst,$hfsz, false);
7825 $x1 = $this->GetStringWidth($this->aliasNbPg);
7826 $x2 = $this->GetStringWidth($nb);
7827 $xadj = $x1 - $x2;
7828 if ($pos=='C') { $xadj /= 2; }
7829 $rep = sprintf(' q 1 0 0 1 %.3F 0 cm ', $xadj*_MPDFK);
7830 $thispage = str_replace($m[0][$hi], $rep, $thispage);
7831 }
7832 }
7833 if (!$this->onlyCoreFonts) { $thispage=str_replace($s1,$r1,$thispage); }
7834 $thispage=str_replace($s2,$r2,$thispage);
7835
7836 // And now for any SMP/SIP fonts subset using <HH> format
7837 $r = '';
7838 $nstr = "$nb";
7839 for($i=0;$i<strlen($nstr);$i++) {
7840 $r .= sprintf("%02s", strtoupper(dechex(intval($nstr[$i])+48)));
7841 }
7842 $thispage=str_replace($this->aliasNbPgHex,$r,$thispage);
7843
7844 }
7845 //Replace number of pages in group
7846 if(!empty($this->aliasNbPgGp)) {
7847 if (!$this->onlyCoreFonts) { $s1 = $this->UTF8ToUTF16BE($this->aliasNbPgGp, false); }
7848 $s2 = $this->aliasNbPgGp;
7849 $nbt = $this->docPageNumTotal($n);
7850 if (!$this->onlyCoreFonts) { $r1 = $this->UTF8ToUTF16BE($nbt, false); }
7851 $r2 = $nbt;
7852 if (preg_match_all('/{mpdfheadernbpggp (C|R) ff=(\S*) fs=(\S*) fz=(.*?)}/',$thispage,$m)) {
7853 for($hi=0;$hi<count($m[0]);$hi++) {
7854 $pos = $m[1][$hi];
7855 $hff = $m[2][$hi];
7856 $hfst = $m[3][$hi];
7857 $hfsz = $m[4][$hi];
7858 $this->SetFont($hff,$hfst,$hfsz, false);
7859 $x1 = $this->GetStringWidth($this->aliasNbPgGp);
7860 $x2 = $this->GetStringWidth($nbt);
7861 $xadj = $x1 - $x2;
7862 if ($pos=='C') { $xadj /= 2; }
7863 $rep = sprintf(' q 1 0 0 1 %.3F 0 cm ', $xadj*_MPDFK);
7864 $thispage = str_replace($m[0][$hi], $rep, $thispage);
7865 }
7866 }
7867 if (!$this->onlyCoreFonts) { $thispage=str_replace($s1,$r1,$thispage); }
7868 $thispage=str_replace($s2,$r2,$thispage);
7869
7870 // And now for any SMP/SIP fonts subset using <HH> format
7871 $r = '';
7872 $nstr = "$nbt";
7873 for($i=0;$i<strlen($nstr);$i++) {
7874 $r .= sprintf("%02s", strtoupper(dechex(intval($nstr[$i])+48)));
7875 }
7876 $thispage=str_replace($this->aliasNbPgGpHex,$r,$thispage);
7877
7878 }
7879 $thispage = preg_replace('/(\s*___BACKGROUND___PATTERNS'.date('jY').'\s*)/', " ", $thispage);
7880 $thispage = preg_replace('/(\s*___HEADER___MARKER'.date('jY').'\s*)/', " ", $thispage);
7881 $thispage = preg_replace('/(\s*___PAGE___START'.date('jY').'\s*)/', " ", $thispage);
7882 $thispage = preg_replace('/(\s*___TABLE___BACKGROUNDS'.date('jY').'\s*)/', " ", $thispage);
7883
7884 //Page
7885 $this->_newobj();
7886 $this->_out('<</Type /Page');
7887 $this->_out('/Parent 1 0 R');
7888 if(isset($this->OrientationChanges[$n])) {
7889 $this->_out(sprintf('/MediaBox [0 0 %.3F %.3F]',$hPt,$wPt));
7890 //If BleedBox is defined, it must be larger than the TrimBox, but smaller than the MediaBox
7891 $bleedMargin = $this->pageDim[$n]['bleedMargin']*_MPDFK;
7892 if ($bleedMargin && ($owidthPt_TB || $owidthPt_LR)) {
7893 $x0 = $owidthPt_TB-$bleedMargin;
7894 $y0 = $owidthPt_LR-$bleedMargin;
7895 $x1 = $hPt-$owidthPt_TB+$bleedMargin;
7896 $y1 = $wPt-$owidthPt_LR+$bleedMargin;
7897 $this->_out(sprintf('/BleedBox [%.3F %.3F %.3F %.3F]', $x0, $y0, $x1, $y1));
7898 }
7899 $this->_out(sprintf('/TrimBox [%.3F %.3F %.3F %.3F]', $owidthPt_TB, $owidthPt_LR, ($hPt-$owidthPt_TB), ($wPt-$owidthPt_LR)));
7900 if (isset($this->OrientationChanges[$n]) && $this->displayDefaultOrientation) {
7901 if ($this->DefOrientation=='P') { $this->_out('/Rotate 270'); }
7902 else { $this->_out('/Rotate 90'); }
7903 }
7904 }
7905 //else if($wPt != $defwPt || $hPt != $defhPt) {
7906 else {
7907 $this->_out(sprintf('/MediaBox [0 0 %.3F %.3F]',$wPt,$hPt));
7908 $bleedMargin = $this->pageDim[$n]['bleedMargin']*_MPDFK;
7909 if ($bleedMargin && ($owidthPt_TB || $owidthPt_LR)) {
7910 $x0 = $owidthPt_LR-$bleedMargin;
7911 $y0 = $owidthPt_TB-$bleedMargin;
7912 $x1 = $wPt-$owidthPt_LR+$bleedMargin;
7913 $y1 = $hPt-$owidthPt_TB+$bleedMargin;
7914 $this->_out(sprintf('/BleedBox [%.3F %.3F %.3F %.3F]', $x0, $y0, $x1, $y1));
7915 }
7916 $this->_out(sprintf('/TrimBox [%.3F %.3F %.3F %.3F]', $owidthPt_LR, $owidthPt_TB, ($wPt-$owidthPt_LR), ($hPt-$owidthPt_TB)));
7917 }
7918 $this->_out('/Resources 2 0 R');
7919
7920 // Important to keep in RGB colorSpace when using transparency
7921 if (!$this->PDFA && !$this->PDFX) {
7922 if ($this->restrictColorSpace == 3)
7923 $this->_out('/Group << /Type /Group /S /Transparency /CS /DeviceCMYK >> ');
7924 else if ($this->restrictColorSpace == 1)
7925 $this->_out('/Group << /Type /Group /S /Transparency /CS /DeviceGray >> ');
7926 else
7927 $this->_out('/Group << /Type /Group /S /Transparency /CS /DeviceRGB >> ');
7928 }
7929
7930 $annotsnum = 0;
7931 if (isset($this->PageLinks[$n])) { $annotsnum += count($this->PageLinks[$n]); }
7932 /*-- ANNOTATIONS --*/
7933 if (isset($this->PageAnnots[$n])) {
7934 foreach ($this->PageAnnots[$n] as $k => $pl) {
7935 if (!empty($pl['opt']['popup']) || !empty($pl['opt']['file'])) { $annotsnum += 2 ; }
7936 else { $annotsnum++; }
7937 $this->PageAnnots[$n][$k]['pageobj'] = $this->n;
7938 }
7939 }
7940 /*-- END ANNOTATIONS --*/
7941
7942 /*-- FORMS --*/
7943 // Active Forms
7944 $formsnum = 0;
7945 if ( count($this->form->forms) > 0 ) {
7946 foreach( $this->form->forms as $val ) {
7947 if ( $val['page'] == $n )
7948 $formsnum++;
7949 }
7950 }
7951 /*-- END FORMS --*/
7952 if ($annotsnum || $formsnum) {
7953 $s = '/Annots [ ';
7954 for($i=0;$i<$annotsnum;$i++) {
7955 $s .= ($annotid + $i) . ' 0 R ';
7956 }
7957 $annotid += $annotsnum;
7958 /*-- FORMS --*/
7959 if ( count($this->form->forms) > 0 ) {
7960 $this->form->addFormIds($n, $s, $annotid);
7961 }
7962 /*-- END FORMS --*/
7963 $s .= '] ';
7964 $this->_out($s);
7965 }
7966
7967 $this->_out('/Contents '.($this->n+1).' 0 R>>');
7968 $this->_out('endobj');
7969
7970 //Page content
7971 $this->_newobj();
7972 $p=($this->compress) ? gzcompress($thispage) : $thispage;
7973 $this->_out('<<'.$filter.'/Length '.strlen($p).'>>');
7974 $this->_putstream($p);
7975 $this->_out('endobj');
7976 }
7977 $this->_putannots($n);
7978
7979 //Pages root
7980 $this->offsets[1]=strlen($this->buffer);
7981 $this->_out('1 0 obj');
7982 $this->_out('<</Type /Pages');
7983 $kids='/Kids [';
7984 for($i=0;$i<$nb;$i++)
7985 $kids.=(3+2*$i).' 0 R ';
7986 $this->_out($kids.']');
7987 $this->_out('/Count '.$nb);
7988 $this->_out(sprintf('/MediaBox [0 0 %.3F %.3F]',$defwPt,$defhPt));
7989 $this->_out('>>');
7990 $this->_out('endobj');
7991 }
7992
7993
7994 function _putannots($n) {
7995 $filter=($this->compress) ? '/Filter /FlateDecode ' : '';
7996 $nb=$this->page;
7997 for($n=1;$n<=$nb;$n++)
7998 {
7999 $annotobjs = array();
8000 if(isset($this->PageLinks[$n]) || isset($this->PageAnnots[$n]) || count($this->form->forms) > 0 ) {
8001 $wPt=$this->pageDim[$n]['w']*_MPDFK;
8002 $hPt=$this->pageDim[$n]['h']*_MPDFK;
8003
8004 //Links
8005 if(isset($this->PageLinks[$n])) {
8006 foreach($this->PageLinks[$n] as $key => $pl) {
8007 $this->_newobj();
8008 $annot='';
8009 $rect=sprintf('%.3F %.3F %.3F %.3F',$pl[0],$pl[1],$pl[0]+$pl[2],$pl[1]-$pl[3]);
8010 $annot .= '<</Type /Annot /Subtype /Link /Rect ['.$rect.']';
8011 $annot .= ' /Contents '.$this->_UTF16BEtextstring($pl[4]);
8012 $annot .= ' /NM '.$this->_textstring(sprintf('%04u-%04u', $n, $key));
8013 $annot .= ' /M '.$this->_textstring('D:'.date('YmdHis'));
8014 $annot .= ' /Border [0 0 0]';
8015 // Use this (instead of /Border) to specify border around link
8016 // $annot .= ' /BS <</W 1'; // Width on points; 0 = no line
8017 // $annot .= ' /S /D'; // style - [S]olid, [D]ashed, [B]eveled, [I]nset, [U]nderline
8018 // $annot .= ' /D [3 2]'; // Dash array - if dashed
8019 // $annot .= ' >>';
8020 // $annot .= ' /C [1 0 0]'; // Color RGB
8021
8022 if ($this->PDFA || $this->PDFX) { $annot .= ' /F 28'; }
8023 if (strpos($pl[4],'@')===0) {
8024 $p=substr($pl[4],1);
8025 // $h=isset($this->OrientationChanges[$p]) ? $wPt : $hPt;
8026 $htarg=$this->pageDim[$p]['h']*_MPDFK;
8027 $annot.=sprintf(' /Dest [%d 0 R /XYZ 0 %.3F null]>>',1+2*$p,$htarg);
8028 }
8029 else if(is_string($pl[4])) {
8030 $annot .= ' /A <</S /URI /URI '.$this->_textstring($pl[4]).'>> >>';
8031 }
8032 else {
8033 $l=$this->links[$pl[4]];
8034 // may not be set if #link points to non-existent target
8035 if (isset($this->pageDim[$l[0]]['h'])) { $htarg=$this->pageDim[$l[0]]['h']*_MPDFK; }
8036 else { $htarg=$this->h*_MPDFK; } // doesn't really matter
8037 $annot.=sprintf(' /Dest [%d 0 R /XYZ 0 %.3F null]>>',1+2*$l[0],$htarg-$l[1]*_MPDFK);
8038 }
8039 $this->_out($annot);
8040 $this->_out('endobj');
8041 }
8042 }
8043
8044
8045 /*-- ANNOTATIONS --*/
8046 if(isset($this->PageAnnots[$n])) {
8047 foreach ($this->PageAnnots[$n] as $key => $pl) {
8048 if ($pl['opt']['file']) { $FileAttachment=true; }
8049 else { $FileAttachment=false; }
8050 $this->_newobj();
8051 $annot='';
8052 $pl['opt'] = array_change_key_case($pl['opt'], CASE_LOWER);
8053 $x = $pl['x'];
8054 if ($this->annotMargin <> 0 || $x==0 || $x<0) { // Odd page
8055 $x = ($wPt/_MPDFK) - $this->annotMargin;
8056 }
8057 $w = $h = 0;
8058 $a = $x * _MPDFK;
8059 $b = $hPt - ($pl['y'] * _MPDFK);
8060 $annot .= '<</Type /Annot ';
8061 if ($FileAttachment) {
8062 $annot .= '/Subtype /FileAttachment';
8063 // Need to set a size for FileAttachment icons
8064 if ($pl['opt']['icon']=='Paperclip') { $w=8.235; $h=20; } // 7,17
8065 else if ($pl['opt']['icon']=='Tag') { $w=20; $h=16; }
8066 else if ($pl['opt']['icon']=='Graph') { $w=20; $h=20; }
8067 else { $w=14; $h=20; } // PushPin
8068 $f = $pl['opt']['file'];
8069 $f = preg_replace('/^.*\//', '', $f);
8070 $f = preg_replace('/[^a-zA-Z0-9._]/', '', $f);
8071 $annot .= '/FS <</Type /Filespec /F ('.$f.')';
8072 $annot .= '/EF <</F '.($this->n+1).' 0 R>>';
8073 $annot .= '>>';
8074 }
8075 else {
8076 $annot .= '/Subtype /Text';
8077 }
8078 $rect = sprintf('%.3F %.3F %.3F %.3F', $a, $b-$h, $a+$w, $b);
8079 $annot .= '/Rect ['.$rect.']';
8080
8081 // contents = description of file in free text
8082 $annot .= ' /Contents '.$this->_UTF16BEtextstring($pl['txt']);
8083 $annot .= ' /NM '.$this->_textstring(sprintf('%04u-%04u', $n, (2000 + $key)));
8084 $annot .= ' /M '.$this->_textstring('D:'.date('YmdHis'));
8085 $annot .= ' /CreationDate '.$this->_textstring('D:'.date('YmdHis'));
8086 $annot .= ' /Border [0 0 0]';
8087 if ($this->PDFA || $this->PDFX) {
8088 $annot .= ' /F 28';
8089 $annot .= ' /CA 1';
8090 }
8091 else if ($pl['opt']['ca']>0) { $annot .= ' /CA '.$pl['opt']['ca']; }
8092
8093 $annotcolor = ' /C [';
8094 if (isset($pl['opt']['c']) AND $pl['opt']['c']) {
8095 $col = $pl['opt']['c'];
8096 if ($col{0}==3 || $col{0}==5) { $annotcolor .= sprintf("%.3F %.3F %.3F", ord($col{1})/255,ord($col{2})/255,ord($col{3})/255); }
8097 else if ($col{0}==1) { $annotcolor .= sprintf("%.3F", ord($col{1})/255); }
8098 else if ($col{0}==4 || $col{0}==6) { $annotcolor .= sprintf("%.3F %.3F %.3F %.3F", ord($col{1})/100,ord($col{2})/100,ord($col{3})/100,ord($col{4})/100); }
8099 else { $annotcolor .= '1 1 0'; }
8100 }
8101 else { $annotcolor .= '1 1 0'; }
8102 $annotcolor .= ']';
8103 $annot .= $annotcolor;
8104 // Usually Author
8105 // Use as Title for fileattachment
8106 if (isset($pl['opt']['t']) AND is_string($pl['opt']['t'])) {
8107 $annot .= ' /T '.$this->_UTF16BEtextstring($pl['opt']['t']);
8108 }
8109 if ($FileAttachment) {
8110 $iconsapp = array('Paperclip', 'Graph', 'PushPin', 'Tag');
8111 }
8112 else { $iconsapp = array('Comment', 'Help', 'Insert', 'Key', 'NewParagraph', 'Note', 'Paragraph'); }
8113 if (isset($pl['opt']['icon']) AND in_array($pl['opt']['icon'], $iconsapp)) {
8114 $annot .= ' /Name /'.$pl['opt']['icon'];
8115 }
8116 else if ($FileAttachment) { $annot .= ' /Name /PushPin'; }
8117 else { $annot .= ' /Name /Note'; }
8118 if (!$FileAttachment) {
8119 // /Subj is PDF 1.5 spec.
8120 if (isset($pl['opt']['subj']) && !$this->PDFA && !$this->PDFX) {
8121 $annot .= ' /Subj '.$this->_UTF16BEtextstring($pl['opt']['subj']);
8122 }
8123 if (!empty($pl['opt']['popup'])) {
8124 $annot .= ' /Open true';
8125 $annot .= ' /Popup '.($this->n+1).' 0 R';
8126 }
8127 else { $annot .= ' /Open false'; }
8128 }
8129 $annot .= ' /P '.$pl['pageobj'].' 0 R';
8130 $annot .= '>>';
8131 $this->_out($annot);
8132 $this->_out('endobj');
8133
8134 if ($FileAttachment) {
8135 $file = @file_get_contents($pl['opt']['file']) or die('mPDF Error: Cannot access file attachment - '.$pl['opt']['file']);
8136 $filestream = gzcompress($file);
8137 $this->_newobj();
8138 $this->_out('<</Type /EmbeddedFile');
8139 $this->_out('/Length '.strlen($filestream));
8140 $this->_out('/Filter /FlateDecode');
8141 $this->_out('>>');
8142 $this->_putstream($filestream);
8143 $this->_out('endobj');
8144 }
8145 else if (!empty($pl['opt']['popup'])) {
8146 $this->_newobj();
8147 $annot='';
8148 if (is_array($pl['opt']['popup']) && isset($pl['opt']['popup'][0])) { $x = $pl['opt']['popup'][0] * _MPDFK; }
8149 else { $x = $pl['x'] * _MPDFK; }
8150 if (is_array($pl['opt']['popup']) && isset($pl['opt']['popup'][1])) { $y = $hPt - ($pl['opt']['popup'][1] * _MPDFK); }
8151 else { $y = $hPt - ($pl['y'] * _MPDFK); }
8152 if (is_array($pl['opt']['popup']) && isset($pl['opt']['popup'][2])) { $w = $pl['opt']['popup'][2] * _MPDFK; }
8153 else { $w = 180; }
8154 if (is_array($pl['opt']['popup']) && isset($pl['opt']['popup'][3])) { $h = $pl['opt']['popup'][3] * _MPDFK; }
8155 else { $h = 120; }
8156 $rect = sprintf('%.3F %.3F %.3F %.3F', $x, $y-$h, $x+$w, $y);
8157 $annot .= '<</Type /Annot /Subtype /Popup /Rect ['.$rect.']';
8158 $annot .= ' /M '.$this->_textstring('D:'.date('YmdHis'));
8159 if ($this->PDFA || $this->PDFX) { $annot .= ' /F 28'; }
8160 $annot .= ' /Parent '.($this->n-1).' 0 R';
8161 $annot .= '>>';
8162 $this->_out($annot);
8163 $this->_out('endobj');
8164 }
8165 }
8166 }
8167 /*-- END ANNOTATIONS --*/
8168
8169 /*-- FORMS --*/
8170 // Active Forms
8171 if ( count($this->form->forms) > 0 ) {
8172 $this->form->_putFormItems($n, $hPt);
8173 }
8174 /*-- END FORMS --*/
8175 }
8176 }
8177 /*-- FORMS --*/
8178 // Active Forms - Radio Button Group entries
8179 // Output Radio Button Group form entries (radio_on_obj_id already determined)
8180 if (count($this->form->form_radio_groups)) {
8181 $this->form->_putRadioItems($n);
8182 }
8183 /*-- END FORMS --*/
8184 }
8185
8186
8187 /*-- ANNOTATIONS --*/
8188 function Annotation($text, $x=0, $y=0, $icon='Note', $author='', $subject='', $opacity=0, $colarray=false, $popup='', $file='') {
8189 if (is_array($colarray) && count($colarray)==3) { $colarray = $this->ConvertColor('rgb('.$colarray[0].','.$colarray[1].','.$colarray[2].')'); }
8190 if ($colarray === false) { $colarray = $this->ConvertColor('yellow'); }
8191 if ($x==0) { $x = $this->x; }
8192 if ($y==0) { $y = $this->y; }
8193 $page = $this->page;
8194 if ($page < 1) { // Document has not been started - assume it's for first page
8195 $page = 1;
8196 if ($x==0) { $x = $this->lMargin; }
8197 if ($y==0) { $y = $this->tMargin; }
8198 }
8199
8200 if ($this->PDFA || $this->PDFX) {
8201 if (($this->PDFA && !$this->PDFAauto) || ($this->PDFX && !$this->PDFXauto)) { $this->PDFAXwarnings[] = "Annotation markers cannot be semi-transparent in PDFA1-b or PDFX/1-a, so they may make underlying text unreadable. (Annotation markers moved to right margin)"; }
8202 $x = ($this->w) - $this->rMargin*0.66;
8203 }
8204 if (!$this->annotMargin) { $y -= $this->FontSize / 2; }
8205
8206 if (!$opacity && $this->annotMargin) { $opacity = 1; }
8207 else if (!$opacity) { $opacity = $this->annotOpacity; }
8208
8209 $an = array('txt' => $text, 'x' => $x, 'y' => $y, 'opt' => array('Icon'=>$icon, 'T'=>$author, 'Subj'=>$subject, 'C'=>$colarray, 'CA'=>$opacity, 'popup'=>$popup, 'file'=>$file));
8210
8211 if ($this->keep_block_together) { // Save to array - don't write yet
8212 $this->ktAnnots[$this->page][]= $an;
8213 return;
8214 }
8215 else if ($this->table_rotate) {
8216 $this->tbrot_Annots[$this->page][]= $an;
8217 return;
8218 }
8219 else if ($this->kwt) {
8220 $this->kwt_Annots[$this->page][]= $an;
8221 return;
8222 }
8223 // mPDF 5.0
8224 if ($this->writingHTMLheader || $this->writingHTMLfooter) {
8225 $this->HTMLheaderPageAnnots[]= $an;
8226 return;
8227 }
8228 //Put an Annotation on the page
8229 $this->PageAnnots[$page][] = $an;
8230 /*-- COLUMNS --*/
8231 // Save cross-reference to Column buffer
8232 $ref = count($this->PageAnnots[$this->page])-1;
8233 $this->columnAnnots[$this->CurrCol][INTVAL($this->x)][INTVAL($this->y)] = $ref;
8234 /*-- END COLUMNS --*/
8235 }
8236 /*-- END ANNOTATIONS --*/
8237
8238
8239 function _putfonts() {
8240 $nf=$this->n;
8241 foreach($this->FontFiles as $fontkey=>$info) {
8242 // TrueType embedded
8243 if (isset($info['type']) && $info['type']=='TTF' && !$info['sip'] && !$info['smp']) {
8244 $used = true;
8245 $asSubset = false;
8246 foreach($this->fonts AS $k=>$f) {
8247 if ($f['fontkey'] == $fontkey && $f['type']=='TTF') {
8248 $used = $f['used'];
8249 if ($used) {
8250 $nChars = (ord($f['cw'][0]) << 8) + ord($f['cw'][1]);
8251 $usage = intval(count($f['subset'])*100 / $nChars);
8252 $fsize = $info['length1'];
8253 // Always subset the very large TTF files
8254 if ($fsize > ($this->maxTTFFilesize *1024)) { $asSubset = true; }
8255 else if ($usage < $this->percentSubset) { $asSubset = true; }
8256 }
8257 if ($f['unAGlyphs']) $aaSubset = true; // mPDF 5.4.05
8258 if ($this->PDFA || $this->PDFX) $asSubset = false;
8259 $this->fonts[$k]['asSubset'] = $asSubset;
8260 break;
8261 }
8262 }
8263 if ($used && !$asSubset) {
8264 //Font file embedding
8265 $this->_newobj();
8266 $this->FontFiles[$fontkey]['n']=$this->n;
8267 $font='';
8268 $originalsize = $info['length1'];
8269 if ($this->repackageTTF || $this->fonts[$fontkey]['TTCfontID']>0) {
8270 // First see if there is a cached compressed file
8271 if (file_exists(_MPDF_TTFONTDATAPATH.$fontkey.'.ps.z')) {
8272 $f=fopen(_MPDF_TTFONTDATAPATH.$fontkey.'.ps.z','rb');
8273 if(!$f) { $this->Error('Font file .ps.z not found'); }
8274 while(!feof($f)) { $font .= fread($f, 2048); }
8275 fclose($f);
8276 include(_MPDF_TTFONTDATAPATH.$fontkey.'.ps.php'); // sets $originalsize (of repackaged font)
8277 }
8278 else {
8279 if (!class_exists('TTFontFile', false)) { include(_MPDF_PATH .'classes/ttfontsuni.php'); }
8280 $ttf = new TTFontFile();
8281 $font = $ttf->repackageTTF($this->FontFiles[$fontkey]['ttffile'], $this->fonts[$fontkey]['TTCfontID'], $this->debugfonts, $this->fonts[$fontkey]['unAGlyphs']); // mPDF 5.4.05
8282
8283 $originalsize = strlen($font);
8284 $font = gzcompress($font);
8285 unset($ttf);
8286 if (is_writable(dirname(_MPDF_TTFONTDATAPATH.'x'))) {
8287 $fh = fopen(_MPDF_TTFONTDATAPATH.$fontkey.'.ps.z',"wb");
8288 fwrite($fh,$font,strlen($font));
8289 fclose($fh);
8290 $fh = fopen(_MPDF_TTFONTDATAPATH.$fontkey.'.ps.php',"wb");
8291 $len = "<?php \n";
8292 $len.='$originalsize='.$originalsize.";\n";
8293 $len.="?>";
8294 fwrite($fh,$len,strlen($len));
8295 fclose($fh);
8296 }
8297 }
8298 }
8299 else {
8300 // First see if there is a cached compressed file
8301 if (file_exists(_MPDF_TTFONTDATAPATH.$fontkey.'.z')) {
8302 $f=fopen(_MPDF_TTFONTDATAPATH.$fontkey.'.z','rb');
8303 if(!$f) { $this->Error('Font file not found'); }
8304 while(!feof($f)) { $font .= fread($f, 2048); }
8305 fclose($f);
8306 }
8307 else {
8308 $f=fopen($this->FontFiles[$fontkey]['ttffile'],'rb');
8309 if(!$f) { $this->Error('Font file not found'); }
8310 while(!feof($f)) { $font .= fread($f, 2048); }
8311 fclose($f);
8312 $font = gzcompress($font);
8313 if (is_writable(dirname(_MPDF_TTFONTDATAPATH.'x'))) {
8314 $fh = fopen(_MPDF_TTFONTDATAPATH.$fontkey.'.z',"wb");
8315 fwrite($fh,$font,strlen($font));
8316 fclose($fh);
8317 }
8318 }
8319 }
8320
8321 $this->_out('<</Length '.strlen($font));
8322 $this->_out('/Filter /FlateDecode');
8323 $this->_out('/Length1 '.$originalsize);
8324 $this->_out('>>');
8325 $this->_putstream($font);
8326 $this->_out('endobj');
8327 }
8328 }
8329 }
8330
8331 $nfonts = count($this->fonts);
8332 $fctr = 1;
8333 foreach($this->fonts as $k=>$font) {
8334 //Font objects
8335 $type=$font['type'];
8336 $name=$font['name'];
8337 if ((!isset($font['used']) || !$font['used']) && $type=='TTF') { continue; }
8338 if ($this->progressBar) { $this->UpdateProgressBar(2,intval($fctr*100/$nfonts),'Writing Fonts'); $fctr++; } // *PROGRESS-BAR*
8339 if (isset($font['asSubset'])) { $asSubset = $font['asSubset']; }
8340 else { $asSubset = ''; }
8341 /*-- CJK-FONTS --*/
8342 if($type=='Type0') { // = Adobe CJK Fonts
8343 $this->fonts[$k]['n']=$this->n+1;
8344 $this->_newobj();
8345 $this->_out('<</Type /Font');
8346 $this->_putType0($font);
8347 }
8348 else
8349 /*-- END CJK-FONTS --*/
8350 if($type=='core') {
8351 //Standard font
8352 $this->fonts[$k]['n']=$this->n+1;
8353 if ($this->PDFA || $this->PDFX) { $this->Error('Core fonts are not allowed in PDF/A1-b or PDFX/1-a files (Times, Helvetica, Courier etc.)'); }
8354 $this->_newobj();
8355 $this->_out('<</Type /Font');
8356 $this->_out('/BaseFont /'.$name);
8357 $this->_out('/Subtype /Type1');
8358 if($name!='Symbol' && $name!='ZapfDingbats') {
8359 $this->_out('/Encoding /WinAnsiEncoding');
8360 }
8361 $this->_out('>>');
8362 $this->_out('endobj');
8363 }
8364 // TrueType embedded SUBSETS for SIP (CJK extB containing Supplementary Ideographic Plane 2)
8365 // Or Unicode Plane 1 - Supplementary Multilingual Plane
8366 else if ($type=='TTF' && ($font['sip'] || $font['smp'])) {
8367 if (!$font['used']) { continue; }
8368 $ssfaid="AA";
8369 if (!class_exists('TTFontFile', false)) { include(_MPDF_PATH .'classes/ttfontsuni.php'); }
8370 $ttf = new TTFontFile();
8371 for($sfid=0;$sfid<count($font['subsetfontids']);$sfid++) {
8372 $this->fonts[$k]['n'][$sfid]=$this->n+1; // NB an array for subset
8373 $subsetname = 'MPDF'.$ssfaid.'+'.$font['name'];
8374 $ssfaid++;
8375 $subset = $font['subsets'][$sfid];
8376 unset($subset[0]);
8377 $ttfontstream = $ttf->makeSubsetSIP($font['ttffile'], $subset, $font['TTCfontID'], $this->debugfonts);
8378 $ttfontsize = strlen($ttfontstream);
8379 $fontstream = gzcompress($ttfontstream);
8380 $widthstring = '';
8381 $toUnistring = '';
8382 foreach($font['subsets'][$sfid] AS $cp=>$u) {
8383 $w = $this->_getCharWidth($font['cw'], $u);
8384 if ($w !== false) {
8385 $widthstring .= $w.' ';
8386 }
8387 else {
8388 $widthstring .= round($ttf->defaultWidth).' ';
8389 }
8390 if ($u > 65535) {
8391 $utf8 = chr(($u>>18)+240).chr((($u>>12)&63)+128).chr((($u>>6)&63)+128) .chr(($u&63)+128);
8392 $utf16 = mb_convert_encoding($utf8, 'UTF-16BE', 'UTF-8');
8393 $l1 = ord($utf16[0]);
8394 $h1 = ord($utf16[1]);
8395 $l2 = ord($utf16[2]);
8396 $h2 = ord($utf16[3]);
8397 $toUnistring .= sprintf("<%02s> <%02s%02s%02s%02s>\n", strtoupper(dechex($cp)), strtoupper(dechex($l1)), strtoupper(dechex($h1)), strtoupper(dechex($l2)), strtoupper(dechex($h2)));
8398 }
8399 else {
8400 $toUnistring .= sprintf("<%02s> <%04s>\n", strtoupper(dechex($cp)), strtoupper(dechex($u)));
8401 }
8402 }
8403
8404 //Additional Type1 or TrueType font
8405 $this->_newobj();
8406 $this->_out('<</Type /Font');
8407 $this->_out('/BaseFont /'.$subsetname);
8408 $this->_out('/Subtype /TrueType');
8409 $this->_out('/FirstChar 0 /LastChar '.(count($font['subsets'][$sfid])-1));
8410 $this->_out('/Widths '.($this->n+1).' 0 R');
8411 $this->_out('/FontDescriptor '.($this->n+2).' 0 R');
8412 $this->_out('/ToUnicode '.($this->n + 3).' 0 R');
8413 $this->_out('>>');
8414 $this->_out('endobj');
8415
8416 //Widths
8417 $this->_newobj();
8418 $this->_out('['.$widthstring.']');
8419 $this->_out('endobj');
8420
8421 //Descriptor
8422 $this->_newobj();
8423 $s='<</Type /FontDescriptor /FontName /'.$subsetname."\n";
8424 foreach($font['desc'] as $kd=>$v) {
8425 if ($kd == 'Flags') { $v = $v | 4; $v = $v & ~32; } // SYMBOLIC font flag
8426 $s.=' /'.$kd.' '.$v."\n";
8427 }
8428 $s.='/FontFile2 '.($this->n + 2).' 0 R';
8429 $this->_out($s.'>>');
8430 $this->_out('endobj');
8431
8432 // ToUnicode
8433 $this->_newobj();
8434 $toUni = "/CIDInit /ProcSet findresource begin\n";
8435 $toUni .= "12 dict begin\n";
8436 $toUni .= "begincmap\n";
8437 $toUni .= "/CIDSystemInfo\n";
8438 $toUni .= "<</Registry (Adobe)\n";
8439 $toUni .= "/Ordering (UCS)\n";
8440 $toUni .= "/Supplement 0\n";
8441 $toUni .= ">> def\n";
8442 $toUni .= "/CMapName /Adobe-Identity-UCS def\n";
8443 $toUni .= "/CMapType 2 def\n";
8444 $toUni .= "1 begincodespacerange\n";
8445 $toUni .= "<00> <FF>\n";
8446 $toUni .= "endcodespacerange\n";
8447 $toUni .= count($font['subsets'][$sfid])." beginbfchar\n";
8448 $toUni .= $toUnistring;
8449 $toUni .= "endbfchar\n";
8450 $toUni .= "endcmap\n";
8451 $toUni .= "CMapName currentdict /CMap defineresource pop\n";
8452 $toUni .= "end\n";
8453 $toUni .= "end\n";
8454
8455 $this->_out('<</Length '.(strlen($toUni)).'>>');
8456 $this->_putstream($toUni);
8457 $this->_out('endobj');
8458
8459 //Font file
8460 $this->_newobj();
8461 $this->_out('<</Length '.strlen($fontstream));
8462 $this->_out('/Filter /FlateDecode');
8463 $this->_out('/Length1 '.$ttfontsize);
8464 $this->_out('>>');
8465 $this->_putstream($fontstream);
8466 $this->_out('endobj');
8467 } // foreach subset
8468 unset($ttf);
8469 }
8470 // TrueType embedded SUBSETS or FULL
8471 else if ($type=='TTF') {
8472 $this->fonts[$k]['n']=$this->n+1;
8473 if ($asSubset ) {
8474 $ssfaid="A";
8475 if (!class_exists('TTFontFile', false)) { include(_MPDF_PATH .'classes/ttfontsuni.php'); }
8476 $ttf = new TTFontFile();
8477 $fontname = 'MPDFA'.$ssfaid.'+'.$font['name'];
8478 $subset = $font['subset'];
8479 unset($subset[0]);
8480 $ttfontstream = $ttf->makeSubset($font['ttffile'], $subset, $font['TTCfontID'], $this->debugfonts, $font['unAGlyphs']); // mPDF 5.4.05
8481 $ttfontsize = strlen($ttfontstream);
8482 $fontstream = gzcompress($ttfontstream);
8483 $codeToGlyph = $ttf->codeToGlyph;
8484 unset($codeToGlyph[0]);
8485 }
8486 else { $fontname = $font['name']; }
8487 // Type0 Font
8488 // A composite font - a font composed of other fonts, organized hierarchically
8489 $this->_newobj();
8490 $this->_out('<</Type /Font');
8491 $this->_out('/Subtype /Type0');
8492 $this->_out('/BaseFont /'.$fontname.'');
8493 $this->_out('/Encoding /Identity-H');
8494 $this->_out('/DescendantFonts ['.($this->n + 1).' 0 R]');
8495 $this->_out('/ToUnicode '.($this->n + 2).' 0 R');
8496 $this->_out('>>');
8497 $this->_out('endobj');
8498
8499 // CIDFontType2
8500 // A CIDFont whose glyph descriptions are based on TrueType font technology
8501 $this->_newobj();
8502 $this->_out('<</Type /Font');
8503 $this->_out('/Subtype /CIDFontType2');
8504 $this->_out('/BaseFont /'.$fontname.'');
8505 $this->_out('/CIDSystemInfo '.($this->n + 2).' 0 R');
8506 $this->_out('/FontDescriptor '.($this->n + 3).' 0 R');
8507 if (isset($font['desc']['MissingWidth'])){
8508 $this->_out('/DW '.$font['desc']['MissingWidth'].'');
8509 }
8510
8511 if (!$asSubset && file_exists(_MPDF_TTFONTDATAPATH.$font['fontkey'].'.cw')) {
8512 $w = '';
8513 $w=file_get_contents(_MPDF_TTFONTDATAPATH.$font['fontkey'].'.cw');
8514 $this->_out($w);
8515 }
8516 else {
8517 $this->_putTTfontwidths($font, $asSubset, $ttf->maxUni);
8518 }
8519
8520 $this->_out('/CIDToGIDMap '.($this->n + 4).' 0 R');
8521 $this->_out('>>');
8522 $this->_out('endobj');
8523
8524 // ToUnicode
8525 $this->_newobj();
8526 $toUni = "/CIDInit /ProcSet findresource begin\n";
8527 $toUni .= "12 dict begin\n";
8528 $toUni .= "begincmap\n";
8529 $toUni .= "/CIDSystemInfo\n";
8530 $toUni .= "<</Registry (Adobe)\n";
8531 $toUni .= "/Ordering (UCS)\n";
8532 $toUni .= "/Supplement 0\n";
8533 $toUni .= ">> def\n";
8534 $toUni .= "/CMapName /Adobe-Identity-UCS def\n";
8535 $toUni .= "/CMapType 2 def\n";
8536 $toUni .= "1 begincodespacerange\n";
8537 $toUni .= "<0000> <FFFF>\n";
8538 $toUni .= "endcodespacerange\n";
8539 $toUni .= "1 beginbfrange\n";
8540 $toUni .= "<0000> <FFFF> <0000>\n";
8541 $toUni .= "endbfrange\n";
8542 $toUni .= "endcmap\n";
8543 $toUni .= "CMapName currentdict /CMap defineresource pop\n";
8544 $toUni .= "end\n";
8545 $toUni .= "end\n";
8546 $this->_out('<</Length '.(strlen($toUni)).'>>');
8547 $this->_putstream($toUni);
8548 $this->_out('endobj');
8549
8550
8551 // CIDSystemInfo dictionary
8552 $this->_newobj();
8553 $this->_out('<</Registry (Adobe)');
8554 $this->_out('/Ordering (UCS)');
8555 $this->_out('/Supplement 0');
8556 $this->_out('>>');
8557 $this->_out('endobj');
8558
8559 // Font descriptor
8560 $this->_newobj();
8561 $this->_out('<</Type /FontDescriptor');
8562 $this->_out('/FontName /'.$fontname);
8563 foreach($font['desc'] as $kd=>$v) {
8564 if ($asSubset && $kd == 'Flags') { $v = $v | 4; $v = $v & ~32; } // SYMBOLIC font flag
8565 $this->_out(' /'.$kd.' '.$v);
8566 }
8567 if ($font['panose']) {
8568 $this->_out(' /Style << /Panose <'.$font['panose'].'> >>');
8569 }
8570 if ($asSubset ) {
8571 $this->_out('/FontFile2 '.($this->n + 2).' 0 R');
8572 }
8573 else if ($font['fontkey']) {
8574 // obj ID of a stream containing a TrueType font program
8575 $this->_out('/FontFile2 '.$this->FontFiles[$font['fontkey']]['n'].' 0 R');
8576 }
8577 $this->_out('>>');
8578 $this->_out('endobj');
8579
8580 // Embed CIDToGIDMap
8581 // A specification of the mapping from CIDs to glyph indices
8582 if ($asSubset ) {
8583 $cidtogidmap = '';
8584 $cidtogidmap = str_pad('', 256*256*2, "\x00");
8585 foreach($codeToGlyph as $cc=>$glyph) {
8586 $cidtogidmap[$cc*2] = chr($glyph >> 8);
8587 $cidtogidmap[$cc*2 + 1] = chr($glyph & 0xFF);
8588 }
8589 $cidtogidmap = gzcompress($cidtogidmap);
8590 }
8591 else {
8592 // First see if there is a cached CIDToGIDMapfile
8593 $cidtogidmap = '';
8594 if (file_exists(_MPDF_TTFONTDATAPATH.$font['fontkey'].'.cgm')) {
8595 $f=fopen(_MPDF_TTFONTDATAPATH.$font['fontkey'].'.cgm','rb');
8596 while(!feof($f)) { $cidtogidmap .= fread($f, 2048); }
8597 fclose($f);
8598 }
8599 else {
8600 if (!class_exists('TTFontFile', false)) { include(_MPDF_PATH .'classes/ttfontsuni.php'); }
8601 $ttf = new TTFontFile();
8602 $charToGlyph = $ttf->getCTG($font['ttffile'], $font['TTCfontID'], $this->debugfonts, $font['unAGlyphs']); // mPDF 5.4.05
8603 $cidtogidmap = str_pad('', 256*256*2, "\x00");
8604 foreach($charToGlyph as $cc=>$glyph) {
8605 $cidtogidmap[$cc*2] = chr($glyph >> 8);
8606 $cidtogidmap[$cc*2 + 1] = chr($glyph & 0xFF);
8607 }
8608 unset($ttf);
8609 $cidtogidmap = gzcompress($cidtogidmap);
8610 if (is_writable(dirname(_MPDF_TTFONTDATAPATH.'x'))) {
8611 $fh = fopen(_MPDF_TTFONTDATAPATH.$font['fontkey'].'.cgm',"wb");
8612 fwrite($fh,$cidtogidmap,strlen($cidtogidmap));
8613 fclose($fh);
8614 }
8615 }
8616 }
8617 $this->_newobj();
8618 $this->_out('<</Length '.strlen($cidtogidmap).'');
8619 $this->_out('/Filter /FlateDecode');
8620 $this->_out('>>');
8621 $this->_putstream($cidtogidmap);
8622 $this->_out('endobj');
8623
8624 //Font file
8625 if ($asSubset ) {
8626 $this->_newobj();
8627 $this->_out('<</Length '.strlen($fontstream));
8628 $this->_out('/Filter /FlateDecode');
8629 $this->_out('/Length1 '.$ttfontsize);
8630 $this->_out('>>');
8631 $this->_putstream($fontstream);
8632 $this->_out('endobj');
8633 unset($ttf);
8634 }
8635 }
8636 else { $this->Error('Unsupported font type: '.$type.' ('.$name.')'); }
8637 }
8638 }
8639
8640
8641
8642 function _putTTfontwidths(&$font, $asSubset, $maxUni) {
8643 if ($asSubset && file_exists(_MPDF_TTFONTDATAPATH.$font['fontkey'].'.cw127.php')) {
8644 include(_MPDF_TTFONTDATAPATH.$font['fontkey'].'.cw127.php') ;
8645 $startcid = 128;
8646 }
8647 else {
8648 $rangeid = 0;
8649 $range = array();
8650 $prevcid = -2;
8651 $prevwidth = -1;
8652 $interval = false;
8653 $startcid = 1;
8654 }
8655 if ($asSubset) { $cwlen = $maxUni + 1; }
8656 else { $cwlen = (strlen($font['cw'])/2); }
8657
8658 // for each character
8659 for ($cid=$startcid; $cid<$cwlen; $cid++) {
8660 if ($cid==128 && $asSubset && (!file_exists(_MPDF_TTFONTDATAPATH.$font['fontkey'].'.cw127.php'))) {
8661 if (is_writable(dirname(_MPDF_TTFONTDATAPATH.'x'))) {
8662 $fh = fopen(_MPDF_TTFONTDATAPATH.$font['fontkey'].'.cw127.php',"wb");
8663 $cw127='<?php'."\n";
8664 $cw127.='$rangeid='.$rangeid.";\n";
8665 $cw127.='$prevcid='.$prevcid.";\n";
8666 $cw127.='$prevwidth='.$prevwidth.";\n";
8667 if ($interval) { $cw127.='$interval=true'.";\n"; }
8668 else { $cw127.='$interval=false'.";\n"; }
8669 $cw127.='$range='.var_export($range,true).";\n";
8670 $cw127.="?>";
8671 fwrite($fh,$cw127,strlen($cw127));
8672 fclose($fh);
8673 }
8674 }
8675 if ($font['cw'][$cid*2] == "\00" && $font['cw'][$cid*2+1] == "\00") { continue; }
8676 $width = (ord($font['cw'][$cid*2]) << 8) + ord($font['cw'][$cid*2+1]);
8677 if ($width == 65535) { $width = 0; }
8678 if ($asSubset && $cid > 255 && (!isset($font['subset'][$cid]) || !$font['subset'][$cid])) {
8679 continue;
8680 }
8681 if (!isset($font['dw']) || (isset($font['dw']) && $width != $font['dw'])) {
8682 if ($cid == ($prevcid + 1)) {
8683 // consecutive CID
8684 if ($width == $prevwidth) {
8685 if ($width == $range[$rangeid][0]) {
8686 $range[$rangeid][] = $width;
8687 } else {
8688 array_pop($range[$rangeid]);
8689 // new range
8690 $rangeid = $prevcid;
8691 $range[$rangeid] = array();
8692 $range[$rangeid][] = $prevwidth;
8693 $range[$rangeid][] = $width;
8694 }
8695 $interval = true;
8696 $range[$rangeid]['interval'] = true;
8697 } else {
8698 if ($interval) {
8699 // new range
8700 $rangeid = $cid;
8701 $range[$rangeid] = array();
8702 $range[$rangeid][] = $width;
8703 } else {
8704 $range[$rangeid][] = $width;
8705 }
8706 $interval = false;
8707 }
8708 } else {
8709 // new range
8710 $rangeid = $cid;
8711 $range[$rangeid] = array();
8712 $range[$rangeid][] = $width;
8713 $interval = false;
8714 }
8715 $prevcid = $cid;
8716 $prevwidth = $width;
8717 }
8718 }
8719 $w = $this->_putfontranges($range);
8720 $this->_out($w);
8721 if (!$asSubset) {
8722 if (is_writable(dirname(_MPDF_TTFONTDATAPATH.'x'))) {
8723 $fh = fopen(_MPDF_TTFONTDATAPATH.$font['fontkey'].'.cw',"wb");
8724 fwrite($fh,$w,strlen($w));
8725 fclose($fh);
8726 }
8727 }
8728 }
8729
8730 function _putfontranges(&$range) {
8731 // optimize ranges
8732 $prevk = -1;
8733 $nextk = -1;
8734 $prevint = false;
8735 foreach ($range as $k => $ws) {
8736 $cws = count($ws);
8737 if (($k == $nextk) AND (!$prevint) AND ((!isset($ws['interval'])) OR ($cws < 4))) {
8738 if (isset($range[$k]['interval'])) {
8739 unset($range[$k]['interval']);
8740 }
8741 $range[$prevk] = array_merge($range[$prevk], $range[$k]);
8742 unset($range[$k]);
8743 } else {
8744 $prevk = $k;
8745 }
8746 $nextk = $k + $cws;
8747 if (isset($ws['interval'])) {
8748 if ($cws > 3) {
8749 $prevint = true;
8750 } else {
8751 $prevint = false;
8752 }
8753 unset($range[$k]['interval']);
8754 --$nextk;
8755 } else {
8756 $prevint = false;
8757 }
8758 }
8759 // output data
8760 $w = '';
8761 foreach ($range as $k => $ws) {
8762 if (count(array_count_values($ws)) == 1) {
8763 // interval mode is more compact
8764 $w .= ' '.$k.' '.($k + count($ws) - 1).' '.$ws[0];
8765 } else {
8766 // range mode
8767 $w .= ' '.$k.' [ '.implode(' ', $ws).' ]' . "\n";
8768 }
8769 }
8770 return '/W ['.$w.' ]';
8771 }
8772
8773
8774 function _putfontwidths(&$font, $cidoffset=0) {
8775 ksort($font['cw']);
8776 unset($font['cw'][65535]);
8777 $rangeid = 0;
8778 $range = array();
8779 $prevcid = -2;
8780 $prevwidth = -1;
8781 $interval = false;
8782 // for each character
8783 foreach ($font['cw'] as $cid => $width) {
8784 $cid -= $cidoffset;
8785 if (!isset($font['dw']) || (isset($font['dw']) && $width != $font['dw'])) {
8786 if ($cid == ($prevcid + 1)) {
8787 // consecutive CID
8788 if ($width == $prevwidth) {
8789 if ($width == $range[$rangeid][0]) {
8790 $range[$rangeid][] = $width;
8791 } else {
8792 array_pop($range[$rangeid]);
8793 // new range
8794 $rangeid = $prevcid;
8795 $range[$rangeid] = array();
8796 $range[$rangeid][] = $prevwidth;
8797 $range[$rangeid][] = $width;
8798 }
8799 $interval = true;
8800 $range[$rangeid]['interval'] = true;
8801 } else {
8802 if ($interval) {
8803 // new range
8804 $rangeid = $cid;
8805 $range[$rangeid] = array();
8806 $range[$rangeid][] = $width;
8807 } else {
8808 $range[$rangeid][] = $width;
8809 }
8810 $interval = false;
8811 }
8812 } else {
8813 // new range
8814 $rangeid = $cid;
8815 $range[$rangeid] = array();
8816 $range[$rangeid][] = $width;
8817 $interval = false;
8818 }
8819 $prevcid = $cid;
8820 $prevwidth = $width;
8821 }
8822 }
8823 $this->_out($this->_putfontranges($range));
8824 }
8825
8826
8827 /*-- CJK-FONTS --*/
8828
8829 // from class PDF_Chinese CJK EXTENSIONS
8830 function _putType0(&$font)
8831 {
8832 //Type0
8833 $this->_out('/Subtype /Type0');
8834 $this->_out('/BaseFont /'.$font['name'].'-'.$font['CMap']);
8835 $this->_out('/Encoding /'.$font['CMap']);
8836 $this->_out('/DescendantFonts ['.($this->n+1).' 0 R]');
8837 $this->_out('>>');
8838 $this->_out('endobj');
8839 //CIDFont
8840 $this->_newobj();
8841 $this->_out('<</Type /Font');
8842 $this->_out('/Subtype /CIDFontType0');
8843 $this->_out('/BaseFont /'.$font['name']);
8844
8845 $cidinfo = '/Registry '.$this->_textstring('Adobe');
8846 $cidinfo .= ' /Ordering '.$this->_textstring($font['registry']['ordering']);
8847 $cidinfo .= ' /Supplement '.$font['registry']['supplement'];
8848 $this->_out('/CIDSystemInfo <<'.$cidinfo.'>>');
8849
8850 $this->_out('/FontDescriptor '.($this->n+1).' 0 R');
8851 if (isset($font['MissingWidth'])){
8852 $this->_out('/DW '.$font['MissingWidth'].'');
8853 }
8854 $this->_putfontwidths($font, 31);
8855 $this->_out('>>');
8856 $this->_out('endobj');
8857
8858 //Font descriptor
8859 $this->_newobj();
8860 $s = '<</Type /FontDescriptor /FontName /'.$font['name'];
8861 foreach ($font['desc'] as $k => $v) {
8862 if ($k != 'Style') {
8863 $s .= ' /'.$k.' '.$v.'';
8864 }
8865 }
8866 $this->_out($s.'>>');
8867 $this->_out('endobj');
8868 }
8869 /*-- END CJK-FONTS --*/
8870
8871
8872
8873 function _putimages()
8874 {
8875 $filter=($this->compress) ? '/Filter /FlateDecode ' : '';
8876 reset($this->images);
8877 while(list($file,$info)=each($this->images)) {
8878 $this->_newobj();
8879 $this->images[$file]['n']=$this->n;
8880 $this->_out('<</Type /XObject');
8881 $this->_out('/Subtype /Image');
8882 $this->_out('/Width '.$info['w']);
8883 $this->_out('/Height '.$info['h']);
8884 if (isset($info['masked'])) {
8885 $this->_out('/SMask '.($this->n - 1).' 0 R');
8886 }
8887 if($info['cs']=='Indexed') {
8888 if ($this->PDFX || ($this->PDFA && $this->restrictColorSpace==3)) { $this->Error("PDFA1-b and PDFX/1-a files do not permit using mixed colour space (".$file.")."); }
8889 $this->_out('/ColorSpace [/Indexed /DeviceRGB '.(strlen($info['pal'])/3-1).' '.($this->n+1).' 0 R]');
8890 }
8891 else {
8892 $this->_out('/ColorSpace /'.$info['cs']);
8893 if($info['cs']=='DeviceCMYK') {
8894 if ($this->PDFA && $this->restrictColorSpace!=3) { $this->Error("PDFA1-b does not permit Images using mixed colour space (".$file.")."); }
8895 if($info['type']=='jpg') { $this->_out('/Decode [1 0 1 0 1 0 1 0]'); }
8896 }
8897 else if ($info['cs']=='DeviceRGB' && ($this->PDFX || ($this->PDFA && $this->restrictColorSpace==3))) { $this->Error("PDFA1-b and PDFX/1-a files do not permit using mixed colour space (".$file.")."); }
8898 }
8899 $this->_out('/BitsPerComponent '.$info['bpc']);
8900 if (isset($info['f']) && $info['f']) { $this->_out('/Filter /'.$info['f']); }
8901 if(isset($info['parms'])) { $this->_out($info['parms']); }
8902 if(isset($info['trns']) and is_array($info['trns'])) {
8903 $trns='';
8904 for($i=0;$i<count($info['trns']);$i++)
8905 $trns.=$info['trns'][$i].' '.$info['trns'][$i].' ';
8906 $this->_out('/Mask ['.$trns.']');
8907 }
8908 $this->_out('/Length '.strlen($info['data']).'>>');
8909 $this->_putstream($info['data']);
8910
8911 unset($this->images[$file]['data']);
8912 $this->_out('endobj');
8913 //Palette
8914 if($info['cs']=='Indexed') {
8915 $this->_newobj();
8916 $pal=($this->compress) ? gzcompress($info['pal']) : $info['pal'];
8917 $this->_out('<<'.$filter.'/Length '.strlen($pal).'>>');
8918 $this->_putstream($pal);
8919 $this->_out('endobj');
8920 }
8921 }
8922 }
8923
8924 function _putinfo()
8925 {
8926 $this->_out('/Producer '.$this->_UTF16BEtextstring('mPDF '.mPDF_VERSION));
8927 if(!empty($this->title))
8928 $this->_out('/Title '.$this->_UTF16BEtextstring($this->title));
8929 if(!empty($this->subject))
8930 $this->_out('/Subject '.$this->_UTF16BEtextstring($this->subject));
8931 if(!empty($this->author))
8932 $this->_out('/Author '.$this->_UTF16BEtextstring($this->author));
8933 if(!empty($this->keywords))
8934 $this->_out('/Keywords '.$this->_UTF16BEtextstring($this->keywords));
8935 if(!empty($this->creator))
8936 $this->_out('/Creator '.$this->_UTF16BEtextstring($this->creator));
8937
8938 $z = date('O'); // +0200
8939 $offset = substr($z,0,3)."'".substr($z,3,2)."'";
8940 $this->_out('/CreationDate '.$this->_textstring(date('YmdHis').$offset));
8941 $this->_out('/ModDate '.$this->_textstring(date('YmdHis').$offset));
8942 if ($this->PDFX) {
8943 $this->_out('/Trapped/False');
8944 $this->_out('/GTS_PDFXVersion(PDF/X-1a:2003)');
8945 }
8946 }
8947
8948 function _putmetadata() {
8949 $this->_newobj();
8950 $this->MetadataRoot = $this->n;
8951 $Producer = 'mPDF '.mPDF_VERSION;
8952 $z = date('O'); // +0200
8953 $offset = substr($z,0,3).':'.substr($z,3,2);
8954 $CreationDate = date('Y-m-d\TH:i:s').$offset; // 2006-03-10T10:47:26-05:00 2006-06-19T09:05:17Z
8955 $uuid = sprintf('%04x%04x-%04x-%04x-%04x-%04x%04x%04x', mt_rand(0, 0xffff), mt_rand(0, 0xffff),
8956 mt_rand(0, 0xffff), mt_rand(0, 0x0fff) | 0x4000, mt_rand(0, 0x3fff) | 0x8000,
8957 mt_rand(0, 0xffff), mt_rand(0, 0xffff), mt_rand(0, 0xffff) );
8958
8959
8960 $m = '<?xpacket begin="'.chr(239).chr(187).chr(191).'" id="W5M0MpCehiHzreSzNTczkc9d"?>'."\n"; // begin = FEFF BOM
8961 $m .= ' <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="3.1-701">'."\n";
8962 $m .= ' <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">'."\n";
8963 $m .= ' <rdf:Description rdf:about="uuid:'.$uuid.'" xmlns:pdf="http://ns.adobe.com/pdf/1.3/">'."\n";
8964 $m .= ' <pdf:Producer>'.$Producer.'</pdf:Producer>'."\n";
8965 if(!empty($this->keywords)) { $m .= ' <pdf:Keywords>'.$this->keywords.'</pdf:Keywords>'."\n"; }
8966 $m .= ' </rdf:Description>'."\n";
8967
8968 $m .= ' <rdf:Description rdf:about="uuid:'.$uuid.'" xmlns:xmp="http://ns.adobe.com/xap/1.0/">'."\n";
8969 $m .= ' <xmp:CreateDate>'.$CreationDate.'</xmp:CreateDate>'."\n";
8970 $m .= ' <xmp:ModifyDate>'.$CreationDate.'</xmp:ModifyDate>'."\n";
8971 $m .= ' <xmp:MetadataDate>'.$CreationDate.'</xmp:MetadataDate>'."\n";
8972 if(!empty($this->creator)) { $m .= ' <xmp:CreatorTool>'.$this->creator.'</xmp:CreatorTool>'."\n"; }
8973 $m .= ' </rdf:Description>'."\n";
8974
8975 // DC elements
8976 $m .= ' <rdf:Description rdf:about="uuid:'.$uuid.'" xmlns:dc="http://purl.org/dc/elements/1.1/">'."\n";
8977 $m .= ' <dc:format>application/pdf</dc:format>'."\n";
8978 if(!empty($this->title)) {
8979 $m .= ' <dc:title>
8980 <rdf:Alt>
8981 <rdf:li xml:lang="x-default">'.$this->title.'</rdf:li>
8982 </rdf:Alt>
8983 </dc:title>'."\n";
8984 }
8985 if(!empty($this->keywords)) {
8986 $m .= ' <dc:subject>
8987 <rdf:Bag>
8988 <rdf:li>'.$this->keywords.'</rdf:li>
8989 </rdf:Bag>
8990 </dc:subject>'."\n";
8991 }
8992 if(!empty($this->subject)) {
8993 $m .= ' <dc:description>
8994 <rdf:Alt>
8995 <rdf:li xml:lang="x-default">'.$this->subject.'</rdf:li>
8996 </rdf:Alt>
8997 </dc:description>'."\n";
8998 }
8999 if(!empty($this->author)) {
9000 $m .= ' <dc:creator>
9001 <rdf:Seq>
9002 <rdf:li>'.$this->author.'</rdf:li>
9003 </rdf:Seq>
9004 </dc:creator>'."\n";
9005 }
9006 $m .= ' </rdf:Description>'."\n";
9007
9008
9009 // This bit is specific to PDFX-1a
9010 if ($this->PDFX) {
9011 $m .= ' <rdf:Description rdf:about="uuid:'.$uuid.'" xmlns:pdfx="http://ns.adobe.com/pdfx/1.3/" pdfx:Apag_PDFX_Checkup="1.3" pdfx:GTS_PDFXConformance="PDF/X-1a:2003" pdfx:GTS_PDFXVersion="PDF/X-1:2003"/>'."\n";
9012 }
9013
9014 // This bit is specific to PDFA-1b
9015 else if ($this->PDFA) {
9016 $m .= ' <rdf:Description rdf:about="uuid:'.$uuid.'" xmlns:pdfaid="http://www.aiim.org/pdfa/ns/id/" >'."\n";
9017 $m .= ' <pdfaid:part>1</pdfaid:part>'."\n";
9018 $m .= ' <pdfaid:conformance>B</pdfaid:conformance>'."\n";
9019 $m .= ' <pdfaid:amd>2005</pdfaid:amd>'."\n";
9020 $m .= ' </rdf:Description>'."\n";
9021 }
9022
9023 $m .= ' <rdf:Description rdf:about="uuid:'.$uuid.'" xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/">'."\n";
9024 $m .= ' <xmpMM:DocumentID>uuid:'.$uuid.'</xmpMM:DocumentID>'."\n";
9025 $m .= ' </rdf:Description>'."\n";
9026 $m .= ' </rdf:RDF>'."\n";
9027 $m .= ' </x:xmpmeta>'."\n";
9028 $m .= str_repeat(str_repeat(' ',100)."\n",20); // 2-4kB whitespace padding required
9029 $m .= '<?xpacket end="w"?>'; // "r" read only
9030 $this->_out('<</Type/Metadata/Subtype/XML/Length '.strlen($m).'>>');
9031 $this->_putstream($m);
9032 $this->_out('endobj');
9033 }
9034
9035 function _putoutputintent() {
9036 $this->_newobj();
9037 $this->OutputIntentRoot = $this->n;
9038 $this->_out('<</Type /OutputIntent');
9039
9040 if ($this->PDFA) {
9041 $this->_out('/S /GTS_PDFA1');
9042 if ($this->ICCProfile) {
9043 $this->_out('/Info ('.preg_replace('/_/',' ',$this->ICCProfile).')');
9044 $this->_out('/OutputConditionIdentifier (Custom)');
9045 $this->_out('/OutputCondition ()');
9046 }
9047 else {
9048 $this->_out('/Info (sRGB IEC61966-2.1)');
9049 $this->_out('/OutputConditionIdentifier (sRGB IEC61966-2.1)');
9050 $this->_out('/OutputCondition ()');
9051 }
9052 $this->_out('/DestOutputProfile '.($this->n+1).' 0 R');
9053 }
9054 else if ($this->PDFX) { // always a CMYK profile
9055 $this->_out('/S /GTS_PDFX');
9056 if ($this->ICCProfile) {
9057 $this->_out('/Info ('.preg_replace('/_/',' ',$this->ICCProfile).')');
9058 $this->_out('/OutputConditionIdentifier (Custom)');
9059 $this->_out('/OutputCondition ()');
9060 $this->_out('/DestOutputProfile '.($this->n+1).' 0 R');
9061 }
9062 else {
9063 $this->_out('/Info (CGATS TR 001)');
9064 $this->_out('/OutputConditionIdentifier (CGATS TR 001)');
9065 $this->_out('/OutputCondition (CGATS TR 001 (SWOP))');
9066 $this->_out('/RegistryName (http://www.color.org)');
9067 }
9068 }
9069 $this->_out('>>');
9070 $this->_out('endobj');
9071
9072 if ($this->PDFX && !$this->ICCProfile) { return; } // no ICCProfile embedded
9073
9074 $this->_newobj();
9075 if ($this->ICCProfile)
9076 $s = file_get_contents(_MPDF_PATH.'iccprofiles/'.$this->ICCProfile.'.icc');
9077 else
9078 $s = file_get_contents(_MPDF_PATH.'iccprofiles/sRGB_IEC61966-2-1.icc');
9079 if ($this->compress) { $s = gzcompress($s); }
9080 $this->_out('<<');
9081 if ($this->PDFX || ($this->PDFA && $this->restrictColorSpace == 3)) { $this->_out('/N 4'); }
9082 else { $this->_out('/N 3'); }
9083 if ($this->compress)
9084 $this->_out('/Filter /FlateDecode ');
9085 $this->_out('/Length '.strlen($s).'>>');
9086 $this->_putstream($s);
9087 $this->_out('endobj');
9088 }
9089
9090
9091 function _putcatalog() {
9092 $this->_out('/Type /Catalog');
9093 $this->_out('/Pages 1 0 R');
9094 if($this->ZoomMode=='fullpage') $this->_out('/OpenAction [3 0 R /Fit]');
9095 elseif($this->ZoomMode=='fullwidth') $this->_out('/OpenAction [3 0 R /FitH null]');
9096 elseif($this->ZoomMode=='real') $this->_out('/OpenAction [3 0 R /XYZ null null 1]');
9097 elseif(!is_string($this->ZoomMode)) $this->_out('/OpenAction [3 0 R /XYZ null null '.($this->ZoomMode/100).']');
9098 else $this->_out('/OpenAction [3 0 R /XYZ null null null]');
9099 if($this->LayoutMode=='single') $this->_out('/PageLayout /SinglePage');
9100 elseif($this->LayoutMode=='continuous') $this->_out('/PageLayout /OneColumn');
9101 elseif($this->LayoutMode=='twoleft') $this->_out('/PageLayout /TwoColumnLeft');
9102 elseif($this->LayoutMode=='tworight') $this->_out('/PageLayout /TwoColumnRight');
9103 elseif($this->LayoutMode=='two') {
9104 if ($this->mirrorMargins) { $this->_out('/PageLayout /TwoColumnRight'); }
9105 else { $this->_out('/PageLayout /TwoColumnLeft'); }
9106 }
9107
9108 /*-- BOOKMARKS --*/
9109 if(count($this->BMoutlines)>0) {
9110 $this->_out('/Outlines '.$this->OutlineRoot.' 0 R');
9111 $this->_out('/PageMode /UseOutlines');
9112 }
9113 /*-- END BOOKMARKS --*/
9114 if(is_int(strpos($this->DisplayPreferences,'FullScreen'))) $this->_out('/PageMode /FullScreen');
9115
9116 // Metadata
9117 if ($this->PDFA || $this->PDFX) {
9118 $this->_out('/Metadata '.$this->MetadataRoot.' 0 R');
9119 }
9120 // OutputIntents
9121 if ($this->PDFA || $this->PDFX || $this->ICCProfile) {
9122 $this->_out('/OutputIntents ['.$this->OutputIntentRoot.' 0 R]');
9123 }
9124
9125 /*-- FORMS --*/
9126 if (count($this->form->forms)>0) {
9127 $this->form->_putFormsCatalog();
9128 }
9129 /*-- END FORMS --*/
9130 if ( isset($this->js) ) {
9131 $this->_out('/Names << /JavaScript '.($this->n_js).' 0 R >> ');
9132 }
9133
9134 if($this->DisplayPreferences || $this->directionality == 'rtl' || $this->mirrorMargins) {
9135 $this->_out('/ViewerPreferences<<');
9136 if(is_int(strpos($this->DisplayPreferences,'HideMenubar'))) $this->_out('/HideMenubar true');
9137 if(is_int(strpos($this->DisplayPreferences,'HideToolbar'))) $this->_out('/HideToolbar true');
9138 if(is_int(strpos($this->DisplayPreferences,'HideWindowUI'))) $this->_out('/HideWindowUI true');
9139 if(is_int(strpos($this->DisplayPreferences,'DisplayDocTitle'))) $this->_out('/DisplayDocTitle true');
9140 if(is_int(strpos($this->DisplayPreferences,'CenterWindow'))) $this->_out('/CenterWindow true');
9141 if(is_int(strpos($this->DisplayPreferences,'FitWindow'))) $this->_out('/FitWindow true');
9142 // /PrintScaling is PDF 1.6 spec.
9143 if(is_int(strpos($this->DisplayPreferences,'NoPrintScaling')) && !$this->PDFA && !$this->PDFX)
9144 $this->_out('/PrintScaling /None');
9145 if($this->directionality == 'rtl') $this->_out('/Direction /R2L');
9146 // /Duplex is PDF 1.7 spec.
9147 if($this->mirrorMargins && !$this->PDFA && !$this->PDFX) {
9148 // if ($this->DefOrientation=='P') $this->_out('/Duplex /DuplexFlipShortEdge');
9149 $this->_out('/Duplex /DuplexFlipLongEdge'); // PDF v1.7+
9150 }
9151 $this->_out('>>');
9152 }
9153 // mPDF 5.6.01
9154 if($this->open_layer_pane && ($this->hasOC || count($this->layers)))
9155 $this->_out('/PageMode /UseOC');
9156
9157 // mPDF 5.6.01
9158 if ($this->hasOC || count($this->layers)) {
9159 $p = $v = $h = $l = $loff = $lall = $as = ''; // mPDF 5.6.28
9160 if ($this->hasOC) {
9161 if (($this->hasOC & 1) == 1) $p=$this->n_ocg_print.' 0 R';
9162 if (($this->hasOC & 2) == 2) $v=$this->n_ocg_view.' 0 R';
9163 if (($this->hasOC & 4) == 4) $h=$this->n_ocg_hidden.' 0 R';
9164 $as="<</Event /Print /OCGs [$p $v $h] /Category [/Print]>> <</Event /View /OCGs [$p $v $h] /Category [/View]>>";
9165 }
9166
9167 if(count($this->layers)) {
9168 foreach($this->layers as $k=>$layer) { // mPDF 5.6.28
9169 if (strtolower($this->layerDetails[$k]['state'])=='hidden') { $loff .= $layer['n'].' 0 R '; }
9170 else { $l .= $layer['n'].' 0 R '; }
9171 $lall .= $layer['n'].' 0 R ';
9172 }
9173 }
9174 $this->_out("/OCProperties <</OCGs [$p $v $h $lall] /D <</ON [$p $l] /OFF [$v $h $loff] "); // mPDF 5.6.28
9175 $this->_out("/Order [$v $p $h $lall] "); // mPDF 5.6.28
9176 if ($as) $this->_out("/AS [$as] ");
9177 $this->_out(">>>>");
9178
9179 }
9180
9181 }
9182
9183 // Inactive function left for backwards compatability
9184 function SetUserRights($enable=true, $annots="", $form="", $signature="") {
9185 // Does nothing
9186 }
9187
9188 function _enddoc() {
9189 if ($this->progressBar) { $this->UpdateProgressBar(2,'10','Writing Headers & Footers'); } // *PROGRESS-BAR*
9190 $this->_puthtmlheaders(); // *HTMLHEADERS-FOOTERS*
9191 if ($this->progressBar) { $this->UpdateProgressBar(2,'20','Writing Pages'); } // *PROGRESS-BAR*
9192 // Remove references to unused fonts (usually default font)
9193 foreach($this->fonts as $fk=>$font) {
9194 if (!$font['used'] && ($font['type']=='TTF')) {
9195 if ($font['sip'] || $font['smp']) {
9196 foreach($font['subsetfontids'] AS $k => $fid) {
9197 foreach($this->pages AS $pn=>$page) {
9198 $this->pages[$pn] = preg_replace('/\s\/F'.$fid.' \d[\d.]* Tf\s/is',' ',$this->pages[$pn]);
9199 }
9200 }
9201 }
9202 else {
9203 foreach($this->pages AS $pn=>$page) {
9204 $this->pages[$pn] = preg_replace('/\s\/F'.$font['i'].' \d[\d.]* Tf\s/is',' ',$this->pages[$pn]);
9205 }
9206 }
9207 }
9208 }
9209
9210 // mPDF 5.6.01 - LAYERS
9211 if (count($this->layers)) {
9212 foreach($this->pages AS $pn=>$page) {
9213 preg_match_all('/\/OCZ-index \/ZI(\d+) BDC(.*?)(EMCZ)-index/is',$this->pages[$pn],$m1);
9214 preg_match_all('/\/OCBZ-index \/ZI(\d+) BDC(.*?)(EMCBZ)-index/is',$this->pages[$pn],$m2);
9215 preg_match_all('/\/OCGZ-index \/ZI(\d+) BDC(.*?)(EMCGZ)-index/is',$this->pages[$pn],$m3);
9216 $m = array();
9217 for ($i=0;$i<4;$i++) {
9218 $m[$i] = array_merge($m1[$i],$m2[$i],$m3[$i]);
9219 }
9220 if (count($m[0])) {
9221 $sortarr = array();
9222 for($i=0;$i<count($m[0]);$i++) {
9223 $key = $m[1][$i]*2;
9224 if ($m[3][$i]=='EMCZ') $key +=2; // background first then gradient then normal
9225 else if ($m[3][$i]=='EMCGZ') $key +=1;
9226 $sortarr[$i] = $key;
9227 }
9228 asort($sortarr);
9229 foreach($sortarr AS $i=>$k) {
9230 $this->pages[$pn] = str_replace($m[0][$i],'',$this->pages[$pn] );
9231 $this->pages[$pn] .= "\n".$m[0][$i]."\n";
9232 }
9233 $this->pages[$pn] = preg_replace('/\/OC[BG]{0,1}Z-index \/ZI(\d+) BDC/is','/OC /ZI\\1 BDC ',$this->pages[$pn]);
9234 $this->pages[$pn] = preg_replace('/EMC[BG]{0,1}Z-index/is','EMC',$this->pages[$pn]);
9235 }
9236 }
9237 }
9238
9239 $this->_putpages();
9240 if ($this->progressBar) { $this->UpdateProgressBar(2,'30','Writing document resources'); } // *PROGRESS-BAR*
9241
9242 $this->_putresources();
9243 //Info
9244 $this->_newobj();
9245 $this->InfoRoot = $this->n;
9246 $this->_out('<<');
9247 if ($this->progressBar) { $this->UpdateProgressBar(2,'80','Writing document info'); } // *PROGRESS-BAR*
9248 $this->_putinfo();
9249 $this->_out('>>');
9250 $this->_out('endobj');
9251
9252 // METADATA
9253 if ($this->PDFA || $this->PDFX) { $this->_putmetadata(); }
9254 // OUTPUTINTENT
9255 if ($this->PDFA || $this->PDFX || $this->ICCProfile) { $this->_putoutputintent(); }
9256
9257 //Catalog
9258 $this->_newobj();
9259 $this->_out('<<');
9260 if ($this->progressBar) { $this->UpdateProgressBar(2,'90','Writing document catalog'); } // *PROGRESS-BAR*
9261 $this->_putcatalog();
9262 $this->_out('>>');
9263 $this->_out('endobj');
9264 //Cross-ref
9265 $o=strlen($this->buffer);
9266 $this->_out('xref');
9267 $this->_out('0 '.($this->n+1));
9268 $this->_out('0000000000 65535 f ');
9269 for($i=1; $i <= $this->n ; $i++)
9270 $this->_out(sprintf('%010d 00000 n ',$this->offsets[$i]));
9271 //Trailer
9272 $this->_out('trailer');
9273 $this->_out('<<');
9274 $this->_puttrailer();
9275 $this->_out('>>');
9276 $this->_out('startxref');
9277 $this->_out($o);
9278
9279 $this->buffer .= '%%EOF';
9280 $this->state=3;
9281 /*-- IMPORTS --*/
9282
9283 if ($this->enableImports && count($this->parsers) > 0) {
9284 foreach ($this->parsers as $k => $_){
9285 $this->parsers[$k]->closeFile();
9286 $this->parsers[$k] = null;
9287 unset($this->parsers[$k]);
9288 }
9289 }
9290 /*-- END IMPORTS --*/
9291 }
9292
9293 function _beginpage($orientation,$mgl='',$mgr='',$mgt='',$mgb='',$mgh='',$mgf='',$ohname='',$ehname='',$ofname='',$efname='',$ohvalue=0,$ehvalue=0,$ofvalue=0,$efvalue=0,$pagesel='',$newformat='') {
9294 if (!($pagesel && $this->page==1 && (sprintf("%0.4f", $this->y)==sprintf("%0.4f", $this->tMargin)))) {
9295 $this->page++;
9296 $this->pages[$this->page]='';
9297 }
9298 $this->state=2;
9299 $resetHTMLHeadersrequired = false;
9300
9301 if ($newformat) { $this->_setPageSize($newformat, $orientation); }
9302 /*-- CSS-PAGE --*/
9303 // Paged media (page-box)
9304
9305 if ($pagesel || (isset($this->page_box['using']) && $this->page_box['using'])) {
9306 if ($pagesel || $this->page==1) { $first = true; }
9307 else { $first = false; }
9308 if ($this->mirrorMargins && ($this->page % 2==0)) { $oddEven = 'E'; }
9309 else { $oddEven = 'O'; }
9310 if ($pagesel) { $psel = $pagesel; }
9311 else if ($this->page_box['current']) { $psel = $this->page_box['current']; }
9312 else { $psel = ''; }
9313 list($orientation,$mgl,$mgr,$mgt,$mgb,$mgh,$mgf,$hname,$fname,$bg,$resetpagenum,$pagenumstyle,$suppress,$marks,$newformat) = $this->SetPagedMediaCSS($psel, $first, $oddEven);
9314 if ($this->mirrorMargins && ($this->page % 2==0)) {
9315 if ($hname) { $ehvalue = 1; $ehname = $hname; } else { $ehvalue = -1; }
9316 if ($fname) { $efvalue = 1; $efname = $fname; } else { $efvalue = -1; }
9317 }
9318 else {
9319 if ($hname) { $ohvalue = 1; $ohname = $hname; } else { $ohvalue = -1; }
9320 if ($fname) { $ofvalue = 1; $ofname = $fname; } else { $ofvalue = -1; }
9321 }
9322 if ($resetpagenum || $pagenumstyle || $suppress) {
9323 $this->PageNumSubstitutions[] = array('from'=>($this->page), 'reset'=> $resetpagenum, 'type'=>$pagenumstyle, 'suppress'=>$suppress);
9324 }
9325 // PAGED MEDIA - CROP / CROSS MARKS from @PAGE
9326 $this->show_marks = $marks;
9327
9328 // Background color
9329 if (isset($bg['BACKGROUND-COLOR'])) {
9330 $cor = $this->ConvertColor($bg['BACKGROUND-COLOR']);
9331 if ($cor) {
9332 $this->bodyBackgroundColor = $cor;
9333 }
9334 }
9335 else { $this->bodyBackgroundColor = false; }
9336
9337 /*-- BACKGROUNDS --*/
9338 if (isset($bg['BACKGROUND-GRADIENT'])) {
9339 $this->bodyBackgroundGradient = $bg['BACKGROUND-GRADIENT'];
9340 }
9341 else { $this->bodyBackgroundGradient = false; }
9342
9343 // Tiling Patterns
9344 if (isset($bg['BACKGROUND-IMAGE']) && $bg['BACKGROUND-IMAGE']) {
9345 $ret = $this->SetBackground($bg, $this->pgwidth);
9346 if ($ret) { $this->bodyBackgroundImage = $ret; }
9347 }
9348 else { $this->bodyBackgroundImage = false; }
9349 /*-- END BACKGROUNDS --*/
9350
9351 $this->page_box['current'] = $psel;
9352 $this->page_box['using'] = true;
9353 }
9354 /*-- END CSS-PAGE --*/
9355
9356 //Page orientation
9357 if(!$orientation)
9358 $orientation=$this->DefOrientation;
9359 else {
9360 $orientation=strtoupper(substr($orientation,0,1));
9361 if($orientation!=$this->DefOrientation)
9362 $this->OrientationChanges[$this->page]=true;
9363 }
9364 if($orientation!=$this->CurOrientation || $newformat) {
9365
9366 //Change orientation
9367 if($orientation=='P') {
9368 $this->wPt=$this->fwPt;
9369 $this->hPt=$this->fhPt;
9370 $this->w=$this->fw;
9371 $this->h=$this->fh;
9372 if (($this->forcePortraitHeaders || $this->forcePortraitMargins) && $this->DefOrientation=='P') {
9373 $this->tMargin = $this->orig_tMargin;
9374 $this->bMargin = $this->orig_bMargin;
9375 $this->DeflMargin = $this->orig_lMargin;
9376 $this->DefrMargin = $this->orig_rMargin;
9377 $this->margin_header = $this->orig_hMargin;
9378 $this->margin_footer = $this->orig_fMargin;
9379 }
9380 else { $resetHTMLHeadersrequired = true; } // *HTMLHEADERS-FOOTERS*
9381 }
9382 else {
9383 $this->wPt=$this->fhPt;
9384 $this->hPt=$this->fwPt;
9385 $this->w=$this->fh;
9386 $this->h=$this->fw;
9387 if (($this->forcePortraitHeaders || $this->forcePortraitMargins) && $this->DefOrientation=='P') {
9388 $this->tMargin = $this->orig_lMargin;
9389 $this->bMargin = $this->orig_rMargin;
9390 $this->DeflMargin = $this->orig_bMargin;
9391 $this->DefrMargin = $this->orig_tMargin;
9392 $this->margin_header = $this->orig_hMargin;
9393 $this->margin_footer = $this->orig_fMargin;
9394 }
9395 else { $resetHTMLHeadersrequired = true; } // *HTMLHEADERS-FOOTERS*
9396
9397 }
9398 $this->CurOrientation=$orientation;
9399 $this->ResetMargins();
9400 $this->pgwidth = $this->w - $this->lMargin - $this->rMargin;
9401 $this->PageBreakTrigger=$this->h-$this->bMargin;
9402 }
9403
9404 $this->pageDim[$this->page]['w']=$this->w ;
9405 $this->pageDim[$this->page]['h']=$this->h ;
9406
9407 $this->pageDim[$this->page]['outer_width_LR'] = isset($this->page_box['outer_width_LR']) ? $this->page_box['outer_width_LR'] : 0;
9408 $this->pageDim[$this->page]['outer_width_TB'] = isset($this->page_box['outer_width_TB']) ? $this->page_box['outer_width_TB'] : 0;
9409 if (!isset($this->page_box['outer_width_LR']) && !isset($this->page_box['outer_width_TB'])) {
9410 $this->pageDim[$this->page]['bleedMargin'] = 0;
9411 }
9412 else if ($this->bleedMargin <= $this->page_box['outer_width_LR'] && $this->bleedMargin <= $this->page_box['outer_width_TB']) {
9413 $this->pageDim[$this->page]['bleedMargin'] = $this->bleedMargin;
9414 }
9415 else {
9416 $this->pageDim[$this->page]['bleedMargin'] = min($this->page_box['outer_width_LR'], $this->page_box['outer_width_TB'])-0.01;
9417 }
9418
9419 // If Page Margins are re-defined
9420 // strlen()>0 is used to pick up (integer) 0, (string) '0', or set value
9421 if ((strlen($mgl)>0 && $this->DeflMargin != $mgl) || (strlen($mgr)>0 && $this->DefrMargin != $mgr) || (strlen($mgt)>0 && $this->tMargin != $mgt) || (strlen($mgb)>0 && $this->bMargin != $mgb) || (strlen($mgh)>0 && $this->margin_header!=$mgh) || (strlen($mgf)>0 && $this->margin_footer!=$mgf)) {
9422 if (strlen($mgl)>0) $this->DeflMargin = $mgl;
9423 if (strlen($mgr)>0) $this->DefrMargin = $mgr;
9424 if (strlen($mgt)>0) $this->tMargin = $mgt;
9425 if (strlen($mgb)>0) $this->bMargin = $mgb;
9426 if (strlen($mgh)>0) $this->margin_header=$mgh;
9427 if (strlen($mgf)>0) $this->margin_footer=$mgf;
9428 $this->ResetMargins();
9429 $this->SetAutoPageBreak($this->autoPageBreak,$this->bMargin);
9430 $this->pgwidth = $this->w - $this->lMargin - $this->rMargin;
9431 $resetHTMLHeadersrequired = true; // *HTMLHEADERS-FOOTERS*
9432 }
9433
9434 $this->ResetMargins();
9435 $this->pgwidth = $this->w - $this->lMargin - $this->rMargin;
9436 $this->SetAutoPageBreak($this->autoPageBreak,$this->bMargin);
9437
9438 // Reset column top margin
9439 $this->y0 = $this->tMargin;
9440
9441 $this->x=$this->lMargin;
9442 $this->y=$this->tMargin;
9443 $this->FontFamily='';
9444
9445 // HEADERS AND FOOTERS
9446 if ($ohvalue<0 || strtoupper($ohvalue)=='OFF') {
9447 $this->HTMLHeader = '';
9448 $this->headerDetails['odd'] = array();
9449 $resetHTMLHeadersrequired = true; // *HTMLHEADERS-FOOTERS*
9450 }
9451 else if ($ohname && $ohvalue>0) {
9452 /*-- HTMLHEADERS-FOOTERS --*/
9453 if (preg_match('/^html_(.*)$/i',$ohname,$n)) {
9454 if (isset($this->pageHTMLheaders[$n[1]])) { $this->HTMLHeader = $this->pageHTMLheaders[$n[1]]; }
9455 else { $this->HTMLHeader = ''; }
9456 $this->headerDetails['odd'] = array();
9457 $resetHTMLHeadersrequired = true;
9458 }
9459 else {
9460 /*-- END HTMLHEADERS-FOOTERS --*/
9461 if (isset($this->pageheaders[$ohname])) { $this->headerDetails['odd'] = $this->pageheaders[$ohname]; }
9462 else if ($ohname!='_default') { $this->headerDetails['odd'] = array(); }
9463 $this->HTMLHeader = '';
9464 /*-- HTMLHEADERS-FOOTERS --*/
9465 $resetHTMLHeadersrequired = false;
9466 }
9467 /*-- END HTMLHEADERS-FOOTERS --*/
9468 }
9469
9470 if ($ehvalue<0 || strtoupper($ehvalue)=='OFF') {
9471 $this->HTMLHeaderE = '';
9472 $this->headerDetails['even'] = array();
9473 $resetHTMLHeadersrequired = true; // *HTMLHEADERS-FOOTERS*
9474 }
9475 else if ($ehname && $ehvalue>0) {
9476 /*-- HTMLHEADERS-FOOTERS --*/
9477 if (preg_match('/^html_(.*)$/i',$ehname,$n)) {
9478 if (isset($this->pageHTMLheaders[$n[1]])) { $this->HTMLHeaderE = $this->pageHTMLheaders[$n[1]]; }
9479 else { $this->HTMLHeaderE = ''; }
9480 $this->headerDetails['even'] = array();
9481 $resetHTMLHeadersrequired = true;
9482 }
9483 else {
9484 /*-- END HTMLHEADERS-FOOTERS --*/
9485 if (isset($this->pageheaders[$ehname])) { $this->headerDetails['even'] = $this->pageheaders[$ehname]; }
9486 else if ($ehname!='_default') { $this->headerDetails['even'] = array(); }
9487 $this->HTMLHeaderE = '';
9488 /*-- HTMLHEADERS-FOOTERS --*/
9489 $resetHTMLHeadersrequired = false;
9490 }
9491 /*-- END HTMLHEADERS-FOOTERS --*/
9492 }
9493
9494 if ($ofvalue<0 || strtoupper($ofvalue)=='OFF') {
9495 $this->HTMLFooter = '';
9496 $this->footerDetails['odd'] = array();
9497 $resetHTMLHeadersrequired = true; // *HTMLHEADERS-FOOTERS*
9498 }
9499 else if ($ofname && $ofvalue>0) {
9500 /*-- HTMLHEADERS-FOOTERS --*/
9501 if (preg_match('/^html_(.*)$/i',$ofname,$n)) {
9502 if (isset($this->pageHTMLfooters[$n[1]])) { $this->HTMLFooter = $this->pageHTMLfooters[$n[1]]; }
9503 else { $this->HTMLFooter = ''; }
9504 $this->footerDetails['odd'] = array();
9505 $resetHTMLHeadersrequired = true;
9506 }
9507 else {
9508 /*-- END HTMLHEADERS-FOOTERS --*/
9509 if (isset($this->pagefooters[$ofname])) { $this->footerDetails['odd'] = $this->pagefooters[$ofname]; }
9510 else if ($ofname!='_default') { $this->footerDetails['odd'] = array(); }
9511 $this->HTMLFooter = '';
9512 /*-- HTMLHEADERS-FOOTERS --*/
9513 $resetHTMLHeadersrequired = true;
9514 }
9515 /*-- END HTMLHEADERS-FOOTERS --*/
9516 }
9517
9518 if ($efvalue<0 || strtoupper($efvalue)=='OFF') {
9519 $this->HTMLFooterE = '';
9520 $this->footerDetails['even'] = array();
9521 $resetHTMLHeadersrequired = true; // *HTMLHEADERS-FOOTERS*
9522 }
9523 else if ($efname && $efvalue>0) {
9524 /*-- HTMLHEADERS-FOOTERS --*/
9525 if (preg_match('/^html_(.*)$/i',$efname,$n)) {
9526 if (isset($this->pageHTMLfooters[$n[1]])) { $this->HTMLFooterE = $this->pageHTMLfooters[$n[1]]; }
9527 else { $this->HTMLFooterE = ''; }
9528 $this->footerDetails['even'] = array();
9529 $resetHTMLHeadersrequired = true;
9530 }
9531 else {
9532 /*-- END HTMLHEADERS-FOOTERS --*/
9533 if (isset($this->pagefooters[$efname])) { $this->footerDetails['even'] = $this->pagefooters[$efname]; }
9534 else if ($efname!='_default') { $this->footerDetails['even'] = array(); }
9535 $this->HTMLFooterE = '';
9536 /*-- HTMLHEADERS-FOOTERS --*/
9537 $resetHTMLHeadersrequired = true;
9538 }
9539 /*-- END HTMLHEADERS-FOOTERS --*/
9540 }
9541 /*-- HTMLHEADERS-FOOTERS --*/
9542 if ($resetHTMLHeadersrequired) {
9543 $this->SetHTMLHeader($this->HTMLHeader );
9544 $this->SetHTMLHeader($this->HTMLHeaderE ,'E');
9545 $this->SetHTMLFooter($this->HTMLFooter );
9546 $this->SetHTMLFooter($this->HTMLFooterE ,'E');
9547 }
9548 /*-- END HTMLHEADERS-FOOTERS --*/
9549
9550
9551 if (($this->mirrorMargins) && (($this->page)%2==0)) { // EVEN
9552 $this->_setAutoHeaderHeight($this->headerDetails['even'], $this->HTMLHeaderE);
9553 $this->_setAutoFooterHeight($this->footerDetails['even'], $this->HTMLFooterE);
9554 }
9555 else { // ODD or DEFAULT
9556 $this->_setAutoHeaderHeight($this->headerDetails['odd'], $this->HTMLHeader);
9557 $this->_setAutoFooterHeight($this->footerDetails['odd'], $this->HTMLFooter);
9558 }
9559 // Reset column top margin
9560 $this->y0 = $this->tMargin;
9561
9562 $this->x=$this->lMargin;
9563 $this->y=$this->tMargin;
9564 }
9565
9566
9567
9568 function _setAutoHeaderHeight(&$det, &$htmlh) {
9569 if ($this->setAutoTopMargin=='pad') {
9570 if ($htmlh['h']) { $h = $htmlh['h']; }
9571 else if ($det) { $h = $this->_getHFHeight($det,'H'); }
9572 else { $h = 0; }
9573 $this->tMargin = $this->margin_header + $h + $this->orig_tMargin;
9574 }
9575 else if ($this->setAutoTopMargin=='stretch') {
9576 if ($htmlh['h']) { $h = $htmlh['h']; }
9577 else if ($det) { $h = $this->_getHFHeight($det,'H'); }
9578 else { $h = 0; }
9579 $this->tMargin = max($this->orig_tMargin, $this->margin_header + $h + $this->autoMarginPadding);
9580 }
9581 }
9582
9583
9584 function _setAutoFooterHeight(&$det, &$htmlf) {
9585 if ($this->setAutoBottomMargin=='pad') {
9586 if ($htmlf['h']) { $h = $htmlf['h']; }
9587 else if ($det) { $h = $this->_getHFHeight($det,'F'); }
9588 else { $h = 0; }
9589 $this->bMargin = $this->margin_footer + $h + $this->orig_bMargin;
9590 $this->PageBreakTrigger=$this->h-$this->bMargin ;
9591 }
9592 else if ($this->setAutoBottomMargin=='stretch') {
9593 if ($htmlf['h']) { $h = $htmlf['h']; }
9594 else if ($det) { $h = $this->_getHFHeight($det,'F'); }
9595 else { $h = 0; }
9596 $this->bMargin = max($this->orig_bMargin, $this->margin_footer + $h + $this->autoMarginPadding);
9597 $this->PageBreakTrigger=$this->h-$this->bMargin ;
9598 }
9599 }
9600
9601 function _getHFHeight(&$det,$end) {
9602 $h = 0;
9603 if(count($det)) {
9604 foreach(array('L','C','R') AS $pos) {
9605 if (isset($det[$pos]['content']) && $det[$pos]['content']) {
9606 if (isset($det[$pos]['font-size']) && $det[$pos]['font-size']) { $hfsz = $det[$pos]['font-size']; }
9607 else { $hfsz = $this->default_font_size; }
9608 $h = max($h,$hfsz/_MPDFK);
9609 }
9610 }
9611 if ($det['line'] && $end=='H') { $h += $h/_MPDFK*$this->header_line_spacing; }
9612 else if ($det['line'] && $end=='F') { $h += $h/_MPDFK*$this->footer_line_spacing; }
9613 }
9614 return $h;
9615 }
9616
9617
9618 function _endpage() {
9619 /*-- CSS-IMAGE-FLOAT --*/
9620 $this->printfloatbuffer();
9621 /*-- END CSS-IMAGE-FLOAT --*/
9622
9623 if($this->visibility!='visible')
9624 $this->SetVisibility('visible');
9625 $this->EndLayer(); // mPDF 5.6.01
9626 //End of page contents
9627 $this->state=1;
9628 }
9629
9630 function _newobj($obj_id=false,$onlynewobj=false) {
9631 if (!$obj_id) {
9632 $obj_id = ++$this->n;
9633 }
9634 //Begin a new object
9635 if (!$onlynewobj) {
9636 $this->offsets[$obj_id] = strlen($this->buffer);
9637 $this->_out($obj_id.' 0 obj');
9638 $this->_current_obj_id = $obj_id; // for later use with encryption
9639 }
9640 }
9641
9642 function _dounderline($x,$y,$txt) {
9643 // Now print line exactly where $y secifies - called from Text() and Cell() - adjust position there
9644 // WORD SPACING
9645 $w =($this->GetStringWidth($txt)*_MPDFK) + ($this->charspacing * mb_strlen( $txt, $this->mb_enc ))
9646 + ( $this->ws * mb_substr_count( $txt, ' ', $this->mb_enc ));
9647 //Draw a line
9648 return sprintf('%.3F %.3F m %.3F %.3F l S',$x*_MPDFK,($this->h-$y)*_MPDFK,($x*_MPDFK)+$w,($this->h-$y)*_MPDFK);
9649 }
9650
9651
9652 function _imageError($file, $firsttime, $msg) {
9653 // Save re-trying image URL's which have already failed
9654 $this->failedimages[$file] = true;
9655 if ($firsttime && ($this->showImageErrors || $this->debug)) {
9656 $this->Error("IMAGE Error (".$file."): ".$msg);
9657 }
9658 return false;
9659 }
9660
9661
9662 function _getImage(&$file, $firsttime=true, $allowvector=true, $orig_srcpath=false) {
9663 // firsttime i.e. whether to add to this->images - use false when calling iteratively
9664 // Image Data passed directly as var:varname
9665 if (preg_match('/var:\s*(.*)/',$file, $v)) {
9666 $data = $this->$v[1];
9667 $file = md5($data);
9668 }
9669 // mPDF 5.5.13
9670 if (preg_match('/data:image\/(gif|jpeg|png);base64,(.*)/',$file, $v)) {
9671 $type = $v[1];
9672 $data = base64_decode($v[2]);
9673 $file = md5($data);
9674 }
9675
9676 // mPDF 5.6.02
9677 if ($firsttime && $file && substr($file,0,5)!='data:') { $file = urlencode_part($file); }
9678 if ($firsttime && $orig_srcpath && substr($orig_srcpath,0,5)!='data:') { $orig_srcpath = urlencode_part($orig_srcpath); }
9679
9680 $ppUx = 0;
9681 if ($orig_srcpath && isset($this->images[$orig_srcpath])) { $file=$orig_srcpath; return $this->images[$orig_srcpath]; }
9682 if (isset($this->images[$file])) { return $this->images[$file]; }
9683 else if ($orig_srcpath && isset($this->formobjects[$orig_srcpath])) { $file=$orig_srcpath; return $this->formobjects[$file]; }
9684 else if (isset($this->formobjects[$file])) { return $this->formobjects[$file]; }
9685 // Save re-trying image URL's which have already failed
9686 else if ($firsttime && isset($this->failedimages[$file])) { return $this->_imageError($file, $firsttime, ''); }
9687 if (empty($data)) {
9688 $type = '';
9689 $data = '';
9690
9691 if ($orig_srcpath && $this->basepathIsLocal && $check = @fopen($orig_srcpath,"rb")) {
9692 fclose($check);
9693 $file=$orig_srcpath;
9694 $data = file_get_contents($file);
9695 $type = $this->_imageTypeFromString($data);
9696 }
9697 if (!$data && $check = @fopen($file,"rb")) {
9698 fclose($check);
9699 $data = file_get_contents($file);
9700 $type = $this->_imageTypeFromString($data);
9701 }
9702 if ((!$data || !$type) && !ini_get('allow_url_fopen') ) { // only worth trying if remote file and !ini_get('allow_url_fopen')
9703 $this->file_get_contents_by_socket($file, $data); // needs full url?? even on local (never needed for local)
9704 if ($data) { $type = $this->_imageTypeFromString($data); }
9705 }
9706 if ((!$data || !$type) && !ini_get('allow_url_fopen') && function_exists("curl_init")) {
9707 $this->file_get_contents_by_curl($file, $data); // needs full url?? even on local (never needed for local)
9708 if ($data) { $type = $this->_imageTypeFromString($data); }
9709 }
9710
9711 }
9712 if (!$data) { return $this->_imageError($file, $firsttime, 'Could not find image file'); }
9713 if (empty($type)) { $type = $this->_imageTypeFromString($data); }
9714 if (($type == 'wmf' || $type == 'svg') && !$allowvector) { return $this->_imageError($file, $firsttime, 'WMF or SVG image file not supported in this context'); }
9715
9716 // SVG
9717 if ($type == 'svg') {
9718 if (!class_exists('SVG', false)) { include(_MPDF_PATH .'classes/svg.php'); }
9719 $svg = new SVG($this);
9720 $family=$this->FontFamily;
9721 $style=$this->FontStyle;
9722 $size=$this->FontSizePt;
9723 $info = $svg->ImageSVG($data);
9724 //Restore font
9725 if($family) $this->SetFont($family,$style,$size,false);
9726 if (!$info) { return $this->_imageError($file, $firsttime, 'Error parsing SVG file'); }
9727 $info['type']='svg';
9728 $info['i']=count($this->formobjects)+1;
9729 $this->formobjects[$file]=$info;
9730 return $info;
9731 }
9732
9733 // JPEG
9734 if ($type == 'jpeg' || $type == 'jpg') {
9735 $hdr = $this->_jpgHeaderFromString($data);
9736 if (!$hdr) { return $this->_imageError($file, $firsttime, 'Error parsing JPG header'); }
9737 $a = $this->_jpgDataFromHeader($hdr);
9738 $j = strpos($data,'JFIF');
9739 if ($j) {
9740 //Read resolution
9741 $unitSp=ord(substr($data,($j+7),1));
9742 if ($unitSp > 0) {
9743 $ppUx=$this->_twobytes2int(substr($data,($j+8),2)); // horizontal pixels per meter, usually set to zero
9744 if ($unitSp == 2) { // = dots per cm (if == 1 set as dpi)
9745 $ppUx=round($ppUx/10 *25.4);
9746 }
9747 }
9748 }
9749 if ($a[2] == 'DeviceCMYK' && (($this->PDFA && $this->restrictColorSpace!=3) || $this->restrictColorSpace==2)) {
9750 // convert to RGB image
9751 if (!function_exists("gd_info")) { $this->Error("JPG image may not use CMYK color space (".$file.")."); }
9752 if ($this->PDFA && !$this->PDFAauto) { $this->PDFAXwarnings[] = "JPG image may not use CMYK color space - ".$file." - (Image converted to RGB. NB This will alter the colour profile of the image.)"; }
9753 $im = @imagecreatefromstring($data);
9754 if ($im) {
9755 $tempfile = _MPDF_TEMP_PATH.'_tempImgPNG'.RAND(1,10000).'.png';
9756 imageinterlace($im, false);
9757 $check = @imagepng($im, $tempfile);
9758 if (!$check) { return $this->_imageError($file, $firsttime, 'Error creating temporary file ('.$tempfile.') whilst using GD library to parse JPG(CMYK) image'); }
9759 $info = $this->_getImage($tempfile, false);
9760 if (!$info) { return $this->_imageError($file, $firsttime, 'Error parsing temporary file ('.$tempfile.') created with GD library to parse JPG(CMYK) image'); }
9761 imagedestroy($im);
9762 unlink($tempfile);
9763 $info['type']='jpg';
9764 if ($firsttime) {
9765 $info['i']=count($this->images)+1;
9766 $this->images[$file]=$info;
9767 }
9768 return $info;
9769 }
9770 else { return $this->_imageError($file, $firsttime, 'Error creating GD image file from JPG(CMYK) image'); }
9771 }
9772 else if ($a[2] == 'DeviceRGB' && ($this->PDFX || $this->restrictColorSpace==3)) {
9773 // Convert to CMYK image stream - nominally returned as type='png'
9774 $info = $this->_convImage($data, $a[2], 'DeviceCMYK', $a[0], $a[1], $ppUx, false);
9775 if (($this->PDFA && !$this->PDFAauto) || ($this->PDFX && !$this->PDFXauto)) { $this->PDFAXwarnings[] = "JPG image may not use RGB color space - ".$file." - (Image converted to CMYK. NB This will alter the colour profile of the image.)"; }
9776 }
9777 else if (($a[2] == 'DeviceRGB' || $a[2] == 'DeviceCMYK') && $this->restrictColorSpace==1) {
9778 // Convert to Grayscale image stream - nominally returned as type='png'
9779 $info = $this->_convImage($data, $a[2], 'DeviceGray', $a[0], $a[1], $ppUx, false);
9780 }
9781 else {
9782 $info = array('w'=>$a[0],'h'=>$a[1],'cs'=>$a[2],'bpc'=>$a[3],'f'=>'DCTDecode','data'=>$data, 'type'=>'jpg');
9783 if ($ppUx) { $info['set-dpi'] = $ppUx; }
9784 }
9785 if (!$info) { return $this->_imageError($file, $firsttime, 'Error parsing or converting JPG image'); }
9786
9787 if ($firsttime) {
9788 $info['i']=count($this->images)+1;
9789 $this->images[$file]=$info;
9790 }
9791 return $info;
9792 }
9793
9794 // PNG
9795 else if ($type == 'png') {
9796 //Check signature
9797 if(substr($data,0,8)!=chr(137).'PNG'.chr(13).chr(10).chr(26).chr(10)) {
9798 return $this->_imageError($file, $firsttime, 'Error parsing PNG identifier');
9799 }
9800 //Read header chunk
9801 if(substr($data,12,4)!='IHDR') {
9802 return $this->_imageError($file, $firsttime, 'Incorrect PNG file (no IHDR block found)');
9803 }
9804
9805 $w=$this->_fourbytes2int(substr($data,16,4));
9806 $h=$this->_fourbytes2int(substr($data,20,4));
9807 $bpc=ord(substr($data,24,1));
9808 $errpng = false;
9809 $pngalpha = false;
9810 if($bpc>8) { $errpng = 'not 8-bit depth'; }
9811 $ct=ord(substr($data,25,1));
9812 if($ct==0) { $colspace='DeviceGray'; }
9813 elseif($ct==2) { $colspace='DeviceRGB'; }
9814 elseif($ct==3) { $colspace='Indexed'; }
9815 elseif($ct==4) { $colspace='DeviceGray'; $errpng = 'alpha channel'; $pngalpha = true; }
9816 else { $colspace='DeviceRGB'; $errpng = 'alpha channel'; $pngalpha = true; }
9817 if(ord(substr($data,26,1))!=0) { $errpng = 'compression method'; }
9818 if(ord(substr($data,27,1))!=0) { $errpng = 'filter method'; }
9819 if(ord(substr($data,28,1))!=0) { $errpng = 'interlaced file'; }
9820 $j = strpos($data,'pHYs');
9821 if ($j) {
9822 //Read resolution
9823 $unitSp=ord(substr($data,($j+12),1));
9824 if ($unitSp == 1) {
9825 $ppUx=$this->_fourbytes2int(substr($data,($j+4),4)); // horizontal pixels per meter, usually set to zero
9826 $ppUx=round($ppUx/1000 *25.4);
9827 }
9828 }
9829 if (($colspace == 'DeviceRGB' || $colspace == 'Indexed') && ($this->PDFX || $this->restrictColorSpace==3)) {
9830 // Convert to CMYK image stream - nominally returned as type='png'
9831 $info = $this->_convImage($data, $colspace, 'DeviceCMYK', $w, $h, $ppUx, $pngalpha);
9832 if (($this->PDFA && !$this->PDFAauto) || ($this->PDFX && !$this->PDFXauto)) { $this->PDFAXwarnings[] = "PNG image may not use RGB color space - ".$file." - (Image converted to CMYK. NB This will alter the colour profile of the image.)"; }
9833 }
9834 else if (($colspace == 'DeviceRGB' || $colspace == 'Indexed') && $this->restrictColorSpace==1) {
9835 // Convert to Grayscale image stream - nominally returned as type='png'
9836 $info = $this->_convImage($data, $colspace, 'DeviceGray', $w, $h, $ppUx, $pngalpha);
9837 }
9838 else if (($this->PDFA || $this->PDFX) && $pngalpha) {
9839 // Remove alpha channel
9840 if ($this->restrictColorSpace==1) { // Grayscale
9841 $info = $this->_convImage($data, $colspace, 'DeviceGray', $w, $h, $ppUx, $pngalpha);
9842 }
9843 else if ($this->restrictColorSpace==3) { // CMYK
9844 $info = $this->_convImage($data, $colspace, 'DeviceCMYK', $w, $h, $ppUx, $pngalpha);
9845 }
9846 else if ($this->PDFA ) { // RGB
9847 $info = $this->_convImage($data, $colspace, 'DeviceRGB', $w, $h, $ppUx, $pngalpha);
9848 }
9849 if (($this->PDFA && !$this->PDFAauto) || ($this->PDFX && !$this->PDFXauto)) { $this->PDFAXwarnings[] = "Transparency (alpha channel) not permitted in PDFA or PDFX files - ".$file." - (Image converted to one without transparency.)"; }
9850 }
9851 else if ($errpng || $pngalpha) {
9852 if (function_exists('gd_info')) { $gd = gd_info(); }
9853 else {$gd = array(); }
9854 if (!isset($gd['PNG Support'])) { return $this->_imageError($file, $firsttime, 'GD library required for PNG image ('.$errpng.')'); }
9855 $im = imagecreatefromstring($data);
9856 if (!$im) { return $this->_imageError($file, $firsttime, 'Error creating GD image from PNG file ('.$errpng.')'); }
9857 $w = imagesx($im);
9858 $h = imagesy($im);
9859 if ($im) {
9860 $tempfile = _MPDF_TEMP_PATH.'_tempImgPNG'.RAND(1,10000).'.png';
9861 // Alpha channel set
9862 if ($pngalpha) {
9863 if ($this->PDFA) { $this->Error("PDFA1-b does not permit images with alpha channel transparency (".$file.")."); }
9864 $imgalpha = imagecreate($w, $h);
9865 // generate gray scale pallete
9866 for ($c = 0; $c < 256; ++$c) { ImageColorAllocate($imgalpha, $c, $c, $c); }
9867 // extract alpha channel
9868 $gammacorr = 2.2; // gamma correction
9869 for ($xpx = 0; $xpx < $w; ++$xpx) {
9870 for ($ypx = 0; $ypx < $h; ++$ypx) {
9871 //$colorindex = imagecolorat($im, $xpx, $ypx);
9872 //$col = imagecolorsforindex($im, $colorindex);
9873 //$gamma2 = (pow((((127 - $col['alpha']) * 255 / 127) / 255), $gammacorr) * 255);
9874 $alpha = (imagecolorat($im, $xpx, $ypx) & 0x7F000000) >> 24;
9875 if ($alpha < 127) {
9876 if ($alpha==0) { $gamma = 255; }
9877 else
9878 $gamma = (pow((((127 - $alpha) * 255 / 127) / 255), $gammacorr) * 255);
9879 imagesetpixel($imgalpha, $xpx, $ypx, $gamma);
9880 }
9881 }
9882 }
9883 // create temp alpha file
9884 $tempfile_alpha = _MPDF_TEMP_PATH.'_tempMskPNG'.RAND(1,10000).'.png';
9885 if (!is_writable($tempfile_alpha)) {
9886 ob_start();
9887 $check = @imagepng($imgalpha);
9888 if (!$check) { return $this->_imageError($file, $firsttime, 'Error creating temporary image object whilst using GD library to parse PNG image'); }
9889 imagedestroy($imgalpha);
9890 $this->_tempimg = ob_get_contents();
9891 $this->_tempimglnk = 'var:_tempimg';
9892 ob_end_clean();
9893 // extract image without alpha channel
9894 $imgplain = imagecreatetruecolor($w, $h);
9895 imagecopy($imgplain, $im, 0, 0, 0, 0, $w, $h);
9896 // create temp image file
9897 $minfo = $this->_getImage($this->_tempimglnk, false);
9898 if (!$minfo) { return $this->_imageError($file, $firsttime, 'Error parsing temporary file image object created with GD library to parse PNG image'); }
9899 ob_start();
9900 $check = @imagepng($imgplain);
9901 if (!$check) { return $this->_imageError($file, $firsttime, 'Error creating temporary image object whilst using GD library to parse PNG image'); }
9902 $this->_tempimg = ob_get_contents();
9903 $this->_tempimglnk = 'var:_tempimg';
9904 ob_end_clean();
9905 $info = $this->_getImage($this->_tempimglnk, false);
9906 if (!$info) { return $this->_imageError($file, $firsttime, 'Error parsing temporary file image object created with GD library to parse PNG image'); }
9907 imagedestroy($imgplain);
9908 $imgmask = count($this->images)+1;
9909 $minfo['cs'] = 'DeviceGray';
9910 $minfo['i']=$imgmask ;
9911 $this->images[$tempfile_alpha] = $minfo;
9912
9913 }
9914 else {
9915 $check = @imagepng($imgalpha, $tempfile_alpha);
9916 if (!$check) { return $this->_imageError($file, $firsttime, 'Failed to create temporary image file ('.$tempfile_alpha.') parsing PNG image with alpha channel ('.$errpng.')'); }
9917 imagedestroy($imgalpha);
9918
9919 // extract image without alpha channel
9920 $imgplain = imagecreatetruecolor($w, $h);
9921 imagecopy($imgplain, $im, 0, 0, 0, 0, $w, $h);
9922
9923 // create temp image file
9924 $check = @imagepng($imgplain, $tempfile);
9925 if (!$check) { return $this->_imageError($file, $firsttime, 'Failed to create temporary image file ('.$tempfile.') parsing PNG image with alpha channel ('.$errpng.')'); }
9926 imagedestroy($imgplain);
9927 // embed mask image
9928 $minfo = $this->_getImage($tempfile_alpha, false);
9929 unlink($tempfile_alpha);
9930 if (!$minfo) { return $this->_imageError($file, $firsttime, 'Error parsing temporary file ('.$tempfile_alpha.') created with GD library to parse PNG image'); }
9931 $imgmask = count($this->images)+1;
9932 $minfo['cs'] = 'DeviceGray';
9933 $minfo['i']=$imgmask ;
9934 $this->images[$tempfile_alpha] = $minfo;
9935 // embed image, masked with previously embedded mask
9936 $info = $this->_getImage($tempfile, false);
9937 unlink($tempfile);
9938 if (!$info) { return $this->_imageError($file, $firsttime, 'Error parsing temporary file ('.$tempfile.') created with GD library to parse PNG image'); }
9939
9940 }
9941 $info['masked'] = $imgmask;
9942 if ($ppUx) { $info['set-dpi'] = $ppUx; }
9943 $info['type']='png';
9944 if ($firsttime) {
9945 $info['i']=count($this->images)+1;
9946 $this->images[$file]=$info;
9947 }
9948 return $info;
9949 }
9950 else { // No alpha/transparency set
9951 imagealphablending($im, false);
9952 imagesavealpha($im, false);
9953 imageinterlace($im, false);
9954 if (!is_writable($tempfile)) {
9955 ob_start();
9956 $check = @imagepng($im);
9957 if (!$check) { return $this->_imageError($file, $firsttime, 'Error creating temporary image object whilst using GD library to parse PNG image'); }
9958 $this->_tempimg = ob_get_contents();
9959 $this->_tempimglnk = 'var:_tempimg';
9960 ob_end_clean();
9961 $info = $this->_getImage($this->_tempimglnk, false);
9962 if (!$info) { return $this->_imageError($file, $firsttime, 'Error parsing temporary file image object created with GD library to parse PNG image'); }
9963 imagedestroy($im);
9964 }
9965 else {
9966 $check = @imagepng($im, $tempfile );
9967 if (!$check) { return $this->_imageError($file, $firsttime, 'Failed to create temporary image file ('.$tempfile.') parsing PNG image ('.$errpng.')'); }
9968 imagedestroy($im);
9969 $info = $this->_getImage($tempfile, false) ;
9970 unlink($tempfile );
9971 if (!$info) { return $this->_imageError($file, $firsttime, 'Error parsing temporary file ('.$tempfile.') created with GD library to parse PNG image'); }
9972 }
9973 if ($ppUx) { $info['set-dpi'] = $ppUx; }
9974 $info['type']='png';
9975 if ($firsttime) {
9976 $info['i']=count($this->images)+1;
9977 $this->images[$file]=$info;
9978 }
9979 return $info;
9980 }
9981 }
9982 }
9983
9984 else {
9985 $parms='/DecodeParms <</Predictor 15 /Colors '.($ct==2 ? 3 : 1).' /BitsPerComponent '.$bpc.' /Columns '.$w.'>>';
9986 //Scan chunks looking for palette, transparency and image data
9987 $pal='';
9988 $trns='';
9989 $pngdata='';
9990 $p = 33;
9991 do {
9992 $n=$this->_fourbytes2int(substr($data,$p,4)); $p += 4;
9993 $type=substr($data,$p,4); $p += 4;
9994 if($type=='PLTE') {
9995 //Read palette
9996 $pal=substr($data,$p,$n); $p += $n;
9997 $p += 4;
9998 }
9999 elseif($type=='tRNS') {
10000 //Read transparency info
10001 $t=substr($data,$p,$n); $p += $n;
10002 if($ct==0) $trns=array(ord(substr($t,1,1)));
10003 elseif($ct==2) $trns=array(ord(substr($t,1,1)),ord(substr($t,3,1)),ord(substr($t,5,1)));
10004 else
10005 {
10006 $pos=strpos($t,chr(0));
10007 if(is_int($pos)) $trns=array($pos);
10008 }
10009 $p += 4;
10010 }
10011 elseif($type=='IDAT') {
10012 $pngdata.=substr($data,$p,$n); $p += $n;
10013 $p += 4;
10014 }
10015 elseif($type=='IEND') { break; }
10016 else if (preg_match('/[a-zA-Z]{4}/',$type)) { $p += $n+4; }
10017 else { return $this->_imageError($file, $firsttime, 'Error parsing PNG image data'); }
10018 }
10019 while($n);
10020 if (!$pngdata) { return $this->_imageError($file, $firsttime, 'Error parsing PNG image data - no IDAT data found'); }
10021 if($colspace=='Indexed' and empty($pal)) { return $this->_imageError($file, $firsttime, 'Error parsing PNG image data - missing colour palette'); }
10022 $info = array('w'=>$w,'h'=>$h,'cs'=>$colspace,'bpc'=>$bpc,'f'=>'FlateDecode','parms'=>$parms,'pal'=>$pal,'trns'=>$trns,'data'=>$pngdata);
10023 $info['type']='png';
10024 if ($ppUx) { $info['set-dpi'] = $ppUx; }
10025 }
10026
10027 if (!$info) { return $this->_imageError($file, $firsttime, 'Error parsing or converting PNG image'); }
10028
10029 if ($firsttime) {
10030 $info['i']=count($this->images)+1;
10031 $this->images[$file]=$info;
10032 }
10033 return $info;
10034 }
10035
10036 // GIF
10037 else if ($type == 'gif') {
10038 if (function_exists('gd_info')) { $gd = gd_info(); }
10039 else {$gd = array(); }
10040 if (isset($gd['GIF Read Support']) && $gd['GIF Read Support']) {
10041 $im = @imagecreatefromstring($data);
10042 if ($im) {
10043 $tempfile = _MPDF_TEMP_PATH.'_tempImgPNG'.RAND(1,10000).'.png';
10044 imagealphablending($im, false);
10045 imagesavealpha($im, false);
10046 imageinterlace($im, false);
10047 if (!is_writable($tempfile)) {
10048 ob_start();
10049 $check = @imagepng($im);
10050 if (!$check) { return $this->_imageError($file, $firsttime, 'Error creating temporary image object whilst using GD library to parse GIF image'); }
10051 $this->_tempimg = ob_get_contents();
10052 $this->_tempimglnk = 'var:_tempimg';
10053 ob_end_clean();
10054 $info = $this->_getImage($this->_tempimglnk, false);
10055 if (!$info) { return $this->_imageError($file, $firsttime, 'Error parsing temporary file image object created with GD library to parse GIF image'); }
10056 imagedestroy($im);
10057 }
10058 else {
10059 $check = @imagepng($im, $tempfile);
10060 if (!$check) { return $this->_imageError($file, $firsttime, 'Error creating temporary file ('.$tempfile.') whilst using GD library to parse GIF image'); }
10061 $info = $this->_getImage($tempfile, false);
10062 if (!$info) { return $this->_imageError($file, $firsttime, 'Error parsing temporary file ('.$tempfile.') created with GD library to parse GIF image'); }
10063 imagedestroy($im);
10064 unlink($tempfile);
10065 }
10066 $info['type']='gif';
10067 if ($firsttime) {
10068 $info['i']=count($this->images)+1;
10069 $this->images[$file]=$info;
10070 }
10071 return $info;
10072 }
10073 else { return $this->_imageError($file, $firsttime, 'Error creating GD image file from GIF image'); }
10074 }
10075
10076 if (!class_exists('gif', false)) {
10077 include_once(_MPDF_PATH.'classes/gif.php');
10078 }
10079 $gif=new CGIF();
10080
10081 $h=0;
10082 $w=0;
10083 $gif->loadFile($data, 0);
10084
10085 if(isset($gif->m_img->m_gih->m_bLocalClr) && $gif->m_img->m_gih->m_bLocalClr) {
10086 $nColors = $gif->m_img->m_gih->m_nTableSize;
10087 $pal = $gif->m_img->m_gih->m_colorTable->toString();
10088 if($bgColor != -1) {
10089 $bgColor = $gif->m_img->m_gih->m_colorTable->colorIndex($bgColor);
10090 }
10091 $colspace='Indexed';
10092 } elseif(isset($gif->m_gfh->m_bGlobalClr) && $gif->m_gfh->m_bGlobalClr) {
10093 $nColors = $gif->m_gfh->m_nTableSize;
10094 $pal = $gif->m_gfh->m_colorTable->toString();
10095 if((isset($bgColor)) and $bgColor != -1) {
10096 $bgColor = $gif->m_gfh->m_colorTable->colorIndex($bgColor);
10097 }
10098 $colspace='Indexed';
10099 } else {
10100 $nColors = 0;
10101 $bgColor = -1;
10102 $colspace='DeviceGray';
10103 $pal='';
10104 }
10105
10106 $trns='';
10107 if(isset($gif->m_img->m_bTrans) && $gif->m_img->m_bTrans && ($nColors > 0)) {
10108 $trns=array($gif->m_img->m_nTrans);
10109 }
10110 $gifdata=$gif->m_img->m_data;
10111 $w=$gif->m_gfh->m_nWidth;
10112 $h=$gif->m_gfh->m_nHeight;
10113 $gif->ClearData();
10114
10115 if($colspace=='Indexed' and empty($pal)) {
10116 return $this->_imageError($file, $firsttime, 'Error parsing GIF image - missing colour palette');
10117 }
10118 if ($this->compress) {
10119 $gifdata=gzcompress($gifdata);
10120 $info = array( 'w'=>$w, 'h'=>$h, 'cs'=>$colspace, 'bpc'=>8, 'f'=>'FlateDecode', 'pal'=>$pal, 'trns'=>$trns, 'data'=>$gifdata);
10121 }
10122 else {
10123 $info = array( 'w'=>$w, 'h'=>$h, 'cs'=>$colspace, 'bpc'=>8, 'pal'=>$pal, 'trns'=>$trns, 'data'=>$gifdata);
10124 }
10125 $info['type']='gif';
10126 if ($firsttime) {
10127 $info['i']=count($this->images)+1;
10128 $this->images[$file]=$info;
10129 }
10130 return $info;
10131 }
10132
10133 /*-- IMAGES-BMP --*/
10134 // BMP (Windows Bitmap)
10135 else if ($type == 'bmp') {
10136 if (!class_exists('bmp', false)) { include(_MPDF_PATH.'classes/bmp.php'); }
10137 if (empty($this->bmp)) { $this->bmp = new bmp($this); }
10138 $info = $this->bmp->_getBMPimage($data, $file);
10139 if (isset($info['error'])) {
10140 return $this->_imageError($file, $firsttime, $info['error']);
10141 }
10142 if ($firsttime) {
10143 $info['i']=count($this->images)+1;
10144 $this->images[$file]=$info;
10145 }
10146 return $info;
10147 }
10148 /*-- END IMAGES-BMP --*/
10149 /*-- IMAGES-WMF --*/
10150 // WMF
10151 else if ($type == 'wmf') {
10152 if (!class_exists('wmf', false)) { include(_MPDF_PATH.'classes/wmf.php'); }
10153 if (empty($this->wmf)) { $this->wmf = new wmf($this); }
10154 $wmfres = $this->wmf->_getWMFimage($data);
10155 if ($wmfres[0]==0) {
10156 if ($wmfres[1]) { return $this->_imageError($file, $firsttime, $wmfres[1]); }
10157 return $this->_imageError($file, $firsttime, 'Error parsing WMF image');
10158 }
10159 $info = array('x'=>$wmfres[2][0],'y'=>$wmfres[2][1],'w'=>$wmfres[3][0],'h'=>$wmfres[3][1],'data'=>$wmfres[1]);
10160 $info['i']=count($this->formobjects)+1;
10161 $info['type']='wmf';
10162 $this->formobjects[$file]=$info;
10163 return $info;
10164 }
10165 /*-- END IMAGES-WMF --*/
10166
10167 // UNKNOWN TYPE - try GD imagecreatefromstring
10168 else {
10169 if (function_exists('gd_info')) { $gd = gd_info(); }
10170 else {$gd = array(); }
10171 if (isset($gd['PNG Support']) && $gd['PNG Support']) {
10172 $im = @imagecreatefromstring($data);
10173 if (!$im) { return $this->_imageError($file, $firsttime, 'Error parsing image file - image type not recognised, and not supported by GD imagecreate'); }
10174 $tempfile = _MPDF_TEMP_PATH.'_tempImgPNG'.RAND(1,10000).'.png';
10175 imagealphablending($im, false);
10176 imagesavealpha($im, false);
10177 imageinterlace($im, false);
10178 $check = @imagepng($im, $tempfile);
10179 if (!$check) { return $this->_imageError($file, $firsttime, 'Error creating temporary file ('.$tempfile.') whilst using GD library to parse unknown image type'); }
10180 $info = $this->_getImage($tempfile, false);
10181 imagedestroy($im);
10182 unlink($tempfile);
10183 if (!$info) { return $this->_imageError($file, $firsttime, 'Error parsing temporary file ('.$tempfile.') created with GD library to parse unknown image type'); }
10184 $info['type']='png';
10185 if ($firsttime) {
10186 $info['i']=count($this->images)+1;
10187 $this->images[$file]=$info;
10188 }
10189 return $info;
10190 }
10191 }
10192
10193 return $this->_imageError($file, $firsttime, 'Error parsing image file - image type not recognised');
10194 }
10195 //==============================================================
10196 function _convImage(&$data, $colspace, $targetcs, $w, $h, $dpi, $mask) {
10197 if ($this->PDFA || $this->PDFX) { $mask=false; }
10198 $im = @imagecreatefromstring($data);
10199 $info = array();
10200 if ($im) {
10201 $imgdata = '';
10202 $mimgdata = '';
10203 $minfo = array();
10204 //Read transparency info
10205 $trns=array();
10206 $trnsrgb = false;
10207 if (!$this->PDFA && !$this->PDFX) {
10208 $p = strpos($data,'tRNS');
10209 if ($p) {
10210 $n=$this->_fourbytes2int(substr($data,($p-4),4));
10211 $t = substr($data,($p+4),$n);
10212 if ($colspace=='DeviceGray') {
10213 $trns=array(ord(substr($t,1,1)));
10214 $trnsrgb = array($trns[0],$trns[0],$trns[0]);
10215 }
10216 else if ($colspace=='DeviceRGB') {
10217 $trns=array(ord(substr($t,1,1)),ord(substr($t,3,1)),ord(substr($t,5,1)));
10218 $trnsrgb = $trns;
10219 if ($targetcs=='DeviceCMYK') {
10220 $col = $this->rgb2cmyk(array(3,$trns[0],$trns[1],$trns[2]));
10221 $c1 = intval($col[1]*2.55);
10222 $c2 = intval($col[2]*2.55);
10223 $c3 = intval($col[3]*2.55);
10224 $c4 = intval($col[4]*2.55);
10225 $trns = array($c1,$c2,$c3,$c4);
10226 }
10227 else if ($targetcs=='DeviceGray') {
10228 $c = intval(($trns[0] * .21) + ($trns[1] * .71) + ($trns[2] * .07));
10229 $trns = array($c);
10230 }
10231 }
10232 else { // Indexed
10233 $pos = strpos($t,chr(0));
10234 if (is_int($pos)) {
10235 $pal = imagecolorsforindex($im, $pos);
10236 $r = $pal['red'];
10237 $g = $pal['green'];
10238 $b = $pal['blue'];
10239 $trns=array($r,$g,$b); // ****
10240 $trnsrgb = $trns;
10241 if ($targetcs=='DeviceCMYK') {
10242 $col = $this->rgb2cmyk(array(3,$r,$g,$b));
10243 $c1 = intval($col[1]*2.55);
10244 $c2 = intval($col[2]*2.55);
10245 $c3 = intval($col[3]*2.55);
10246 $c4 = intval($col[4]*2.55);
10247 $trns = array($c1,$c2,$c3,$c4);
10248 }
10249 else if ($targetcs=='DeviceGray') {
10250 $c = intval(($r * .21) + ($g * .71) + ($b * .07));
10251 $trns = array($c);
10252 }
10253 }
10254 }
10255 }
10256 }
10257 for ($i = 0; $i < $h; $i++) {
10258 for ($j = 0; $j < $w; $j++) {
10259 $rgb = imagecolorat($im, $j, $i);
10260 $r = ($rgb >> 16) & 0xFF;
10261 $g = ($rgb >> 8) & 0xFF;
10262 $b = $rgb & 0xFF;
10263 if ($colspace=='Indexed') {
10264 $pal = imagecolorsforindex($im, $rgb);
10265 $r = $pal['red'];
10266 $g = $pal['green'];
10267 $b = $pal['blue'];
10268 }
10269
10270 if ($targetcs=='DeviceCMYK') {
10271 $col = $this->rgb2cmyk(array(3,$r,$g,$b));
10272 $c1 = intval($col[1]*2.55);
10273 $c2 = intval($col[2]*2.55);
10274 $c3 = intval($col[3]*2.55);
10275 $c4 = intval($col[4]*2.55);
10276 if ($trnsrgb) {
10277 // original pixel was not set as transparent but processed color does match
10278 if ($trnsrgb!=array($r,$g,$b) && $trns==array($c1,$c2,$c3,$c4)) {
10279 if ($c4==0) { $c4=1; } else { $c4--; }
10280 }
10281 }
10282 $imgdata .= chr($c1).chr($c2).chr($c3).chr($c4);
10283 }
10284 else if ($targetcs=='DeviceGray') {
10285 $c = intval(($r * .21) + ($g * .71) + ($b * .07));
10286 if ($trnsrgb) {
10287 // original pixel was not set as transparent but processed color does match
10288 if ($trnsrgb!=array($r,$g,$b) && $trns==array($c)) {
10289 if ($c==0) { $c=1; } else { $c--; }
10290 }
10291 }
10292 $imgdata .= chr($c);
10293 }
10294 else if ($targetcs=='DeviceRGB') {
10295 $imgdata .= chr($r).chr($g).chr($b);
10296 }
10297 if ($mask) {
10298 $col = imagecolorsforindex($im, $rgb);
10299 $gammacorr = 2.2; // gamma correction
10300 $gamma = intval((pow((((127 - $col['alpha']) * 255 / 127) / 255), $gammacorr) * 255));
10301 $mimgdata .= chr($gamma);
10302 }
10303 }
10304 }
10305
10306 if ($targetcs=='DeviceGray') { $ncols = 1; }
10307 else if ($targetcs=='DeviceRGB') { $ncols = 3; }
10308 else if ($targetcs=='DeviceCMYK') { $ncols = 4; }
10309
10310 $imgdata = gzcompress($imgdata);
10311 $info = array('w'=>$w,'h'=>$h,'cs'=>$targetcs,'bpc'=>8,'f'=>'FlateDecode','data'=>$imgdata, 'type'=>'png',
10312 'parms'=>'/DecodeParms <</Colors '.$ncols.' /BitsPerComponent 8 /Columns '.$w.'>>');
10313 if ($dpi) { $info['set-dpi'] = $dpi; }
10314 if ($mask) {
10315 $mimgdata = gzcompress($mimgdata);
10316 $minfo = array('w'=>$w,'h'=>$h,'cs'=>'DeviceGray','bpc'=>8,'f'=>'FlateDecode','data'=>$mimgdata, 'type'=>'png',
10317 'parms'=>'/DecodeParms <</Colors '.$ncols.' /BitsPerComponent 8 /Columns '.$w.'>>');
10318 if ($dpi) { $minfo['set-dpi'] = $dpi; }
10319 $tempfile = '_tempImgPNG'.RAND(1,10000).'.png';
10320 $imgmask = count($this->images)+1;
10321 $minfo['i']=$imgmask ;
10322 $this->images[$tempfile] = $minfo;
10323 $info['masked'] = $imgmask;
10324 }
10325 else if ($trns) { $info['trns'] = $trns; }
10326 imagedestroy($im);
10327 }
10328 return $info;
10329 }
10330
10331
10332
10333
10334 function _fourbytes2int($s) {
10335 //Read a 4-byte integer from string
10336 return (ord($s[0])<<24) + (ord($s[1])<<16) + (ord($s[2])<<8) + ord($s[3]);
10337 }
10338
10339 function _twobytes2int($s) {
10340 //Read a 2-byte integer from string
10341 return (ord(substr($s, 0, 1))<<8) + ord(substr($s, 1, 1));
10342 }
10343
10344 function _jpgHeaderFromString(&$data) {
10345 $p = 4;
10346 $p += $this->_twobytes2int(substr($data, $p, 2)); // Length of initial marker block
10347 $marker = substr($data, $p, 2);
10348 while($marker != chr(255).chr(192) && $marker != chr(255).chr(194) && $p<strlen($data)) {
10349 // Start of frame marker (FFC0) or (FFC2) mPDF 4.4.004
10350 $p += ($this->_twobytes2int(substr($data, $p+2, 2))) + 2; // Length of marker block
10351 $marker = substr($data, $p, 2);
10352 }
10353 if ($marker != chr(255).chr(192) && $marker != chr(255).chr(194)) { return false; }
10354 return substr($data, $p+2, 10);
10355 }
10356
10357 function _jpgDataFromHeader($hdr) {
10358 $bpc = ord(substr($hdr, 2, 1));
10359 if (!$bpc) { $bpc = 8; }
10360 $h = $this->_twobytes2int(substr($hdr, 3, 2));
10361 $w = $this->_twobytes2int(substr($hdr, 5, 2));
10362 $channels = ord(substr($hdr, 7, 1));
10363 if ($channels==3) { $colspace='DeviceRGB'; }
10364 elseif($channels==4) { $colspace='DeviceCMYK'; }
10365 else { $colspace='DeviceGray'; }
10366 return array($w, $h, $colspace, $bpc);
10367 }
10368
10369 function file_get_contents_by_curl($url, &$data) {
10370 $timeout = 5;
10371 $ch = curl_init($url);
10372 curl_setopt($ch, CURLOPT_HEADER, 0);
10373 curl_setopt($ch, CURLOPT_NOBODY, 0);
10374 curl_setopt ( $ch , CURLOPT_RETURNTRANSFER , 1 );
10375 curl_setopt ( $ch , CURLOPT_CONNECTTIMEOUT , $timeout );
10376 $data = curl_exec($ch);
10377 curl_close($ch);
10378 }
10379
10380
10381 function file_get_contents_by_socket($url, &$data) {
10382 $timeout = 1;
10383 $p = parse_url($url);
10384 $file = $p['path'];
10385 if ($p['query']) { $file .= '?'.$p['query']; }
10386 if(!($fh = @fsockopen($p['host'], 80, $errno, $errstr, $timeout))) { return false; }
10387 $getstring =
10388 "GET ".$file." HTTP/1.0 \r\n" .
10389 "Host: ".$p['host']." \r\n" .
10390 "Connection: close\r\n\r\n";
10391 fwrite($fh, $getstring);
10392 // Get rid of HTTP header
10393 $s = fgets($fh, 1024);
10394 if (!$s) { return false; }
10395 $httpheader .= $s;
10396 while (!feof($fh)) {
10397 $s = fgets($fh, 1024);
10398 if ( $s == "\r\n" ) { break; }
10399 }
10400 $data = '';
10401 while (!feof($fh)) {
10402 $data .= fgets($fh, 1024);
10403 }
10404 fclose($fh);
10405 }
10406
10407 //==============================================================
10408
10409 function _imageTypeFromString(&$data) {
10410 $type = '';
10411 if (substr($data, 6, 4)== 'JFIF' || substr($data, 6, 4)== 'Exif') {
10412 $type = 'jpeg';
10413 }
10414 else if (substr($data, 0, 6)== "GIF87a" || substr($data, 0, 6)== "GIF89a") {
10415 $type = 'gif';
10416 }
10417 else if (substr($data, 0, 8)== chr(137).'PNG'.chr(13).chr(10).chr(26).chr(10)) {
10418 $type = 'png';
10419 }
10420 /*-- IMAGES-WMF --*/
10421 else if (substr($data, 0, 4)== chr(215).chr(205).chr(198).chr(154)) {
10422 $type = 'wmf';
10423 }
10424 /*-- END IMAGES-WMF --*/
10425 else if (preg_match('/<svg.*<\/svg>/is',$data)) {
10426 $type = 'svg';
10427 }
10428 // BMP images
10429 else if (substr($data, 0, 2)== "BM") {
10430 $type = 'bmp';
10431 }
10432 return $type;
10433 }
10434 //==============================================================
10435
10436 // Moved outside WMF as also needed for SVG
10437 function _putformobjects() {
10438 reset($this->formobjects);
10439 while(list($file,$info)=each($this->formobjects)) {
10440 $this->_newobj();
10441 $this->formobjects[$file]['n']=$this->n;
10442 $this->_out('<</Type /XObject');
10443 $this->_out('/Subtype /Form');
10444 $this->_out('/Group '.($this->n+1).' 0 R');
10445 $this->_out('/BBox ['.$info['x'].' '.$info['y'].' '.($info['w']+$info['x']).' '.($info['h']+$info['y']).']');
10446 if ($this->compress)
10447 $this->_out('/Filter /FlateDecode');
10448 $data=($this->compress) ? gzcompress($info['data']) : $info['data'];
10449 $this->_out('/Length '.strlen($data).'>>');
10450 $this->_putstream($data);
10451 unset($this->formobjects[$file]['data']);
10452 $this->_out('endobj');
10453 // Required for SVG transparency (opacity) to work
10454 $this->_newobj();
10455 $this->_out('<</Type /Group');
10456 $this->_out('/S /Transparency');
10457 $this->_out('>>');
10458 $this->_out('endobj');
10459 }
10460 }
10461
10462 function _freadint($f)
10463 {
10464 //Read a 4-byte integer from file
10465 $i=ord(fread($f,1))<<24;
10466 $i+=ord(fread($f,1))<<16;
10467 $i+=ord(fread($f,1))<<8;
10468 $i+=ord(fread($f,1));
10469 return $i;
10470 }
10471
10472 function _UTF16BEtextstring($s) {
10473 $s = $this->UTF8ToUTF16BE($s, true);
10474 /*-- ENCRYPTION --*/
10475 if ($this->encrypted) {
10476 $s = $this->_RC4($this->_objectkey($this->_current_obj_id), $s);
10477 }
10478 /*-- END ENCRYPTION --*/
10479 return '('. $this->_escape($s).')';
10480 }
10481
10482 function _textstring($s) {
10483 /*-- ENCRYPTION --*/
10484 if ($this->encrypted) {
10485 $s = $this->_RC4($this->_objectkey($this->_current_obj_id), $s);
10486 }
10487 /*-- END ENCRYPTION --*/
10488 return '('. $this->_escape($s).')';
10489 }
10490
10491
10492 function _escape($s)
10493 {
10494 // the chr(13) substitution fixes the Bugs item #1421290.
10495 return strtr($s, array(')' => '\\)', '(' => '\\(', '\\' => '\\\\', chr(13) => '\r'));
10496 }
10497
10498 function _putstream($s) {
10499 /*-- ENCRYPTION --*/
10500 if ($this->encrypted) {
10501 $s = $this->_RC4($this->_objectkey($this->_current_obj_id), $s);
10502 }
10503 /*-- END ENCRYPTION --*/
10504 $this->_out('stream');
10505 $this->_out($s);
10506 $this->_out('endstream');
10507 }
10508
10509
10510 function _out($s,$ln=true) {
10511 if($this->state==2) {
10512 if ($this->bufferoutput) {
10513 $this->headerbuffer.= $s."\n";
10514 }
10515 /*-- COLUMNS --*/
10516 else if (($this->ColActive) && !$this->processingHeader && !$this->processingFooter) {
10517 // Captures everything in buffer for columns; Almost everything is sent from fn. Cell() except:
10518 // Images sent from Image() or
10519 // later sent as _out($textto) in printbuffer
10520 // Line()
10521 if (preg_match('/q \d+\.\d\d+ 0 0 (\d+\.\d\d+) \d+\.\d\d+ \d+\.\d\d+ cm \/(I|FO)\d+ Do Q/',$s,$m)) { // Image data
10522 $h = ($m[1]/_MPDFK);
10523 // Update/overwrite the lowest bottom of printing y value for a column
10524 $this->ColDetails[$this->CurrCol]['bottom_margin'] = $this->y+$h;
10525 }
10526 /*-- TABLES --*/
10527 else if (preg_match('/\d+\.\d\d+ \d+\.\d\d+ \d+\.\d\d+ ([\-]{0,1}\d+\.\d\d+) re/',$s,$m) && $this->tableLevel>0) { // Rect in table
10528 $h = ($m[1]/_MPDFK);
10529 // Update/overwrite the lowest bottom of printing y value for a column
10530 $this->ColDetails[$this->CurrCol]['bottom_margin'] = max($this->ColDetails[$this->CurrCol]['bottom_margin'],($this->y+$h));
10531 }
10532 /*-- END TABLES --*/
10533 else { // Td Text Set in Cell()
10534 if (isset($this->ColDetails[$this->CurrCol]['bottom_margin'])) { $h = $this->ColDetails[$this->CurrCol]['bottom_margin'] - $this->y; }
10535 else { $h = 0; }
10536 }
10537 if ($h < 0) { $h = -$h; }
10538 $this->columnbuffer[] = array(
10539 's' => $s, // Text string to output
10540 'col' => $this->CurrCol, // Column when printed
10541 'x' => $this->x, // x when printed
10542 'y' => $this->y, // this->y when printed (after column break)
10543 'h' => $h // actual y at bottom when printed = y+h
10544 );
10545 }
10546 /*-- END COLUMNS --*/
10547 /*-- TABLES --*/
10548 else if ($this->table_rotate && !$this->processingHeader && !$this->processingFooter) {
10549 // Captures eveything in buffer for rotated tables;
10550 $this->tablebuffer .= $s . "\n";
10551 }
10552 /*-- END TABLES --*/
10553 else if ($this->kwt && !$this->processingHeader && !$this->processingFooter) {
10554 // Captures eveything in buffer for keep-with-table (h1-6);
10555 $this->kwt_buffer[] = array(
10556 's' => $s, // Text string to output
10557 'x' => $this->x, // x when printed
10558 'y' => $this->y, // y when printed
10559 );
10560 }
10561 else if (($this->keep_block_together) && !$this->processingHeader && !$this->processingFooter) {
10562 if (!isset($this->ktBlock[$this->page]['bottom_margin'])) {
10563 $this->ktBlock[$this->page]['bottom_margin'] = $this->y;
10564 }
10565
10566 // Captures eveything in buffer;
10567 if (preg_match('/q \d+\.\d\d+ 0 0 (\d+\.\d\d+) \d+\.\d\d+ \d+\.\d\d+ cm \/(I|FO)\d+ Do Q/',$s,$m)) { // Image data
10568 $h = ($m[1]/_MPDFK);
10569 // Update/overwrite the lowest bottom of printing y value for Keep together block
10570 $this->ktBlock[$this->page]['bottom_margin'] = $this->y+$h;
10571 }
10572 else { // Td Text Set in Cell()
10573 if (isset($this->ktBlock[$this->page]['bottom_margin'])) { $h = $this->ktBlock[$this->page]['bottom_margin'] - $this->y; }
10574 else { $h = 0; }
10575 }
10576 if ($h < 0) { $h = -$h; }
10577 $this->divbuffer[] = array(
10578 'page' => $this->page,
10579 's' => $s, // Text string to output
10580 'x' => $this->x, // x when printed
10581 'y' => $this->y, // y when printed (after column break)
10582 'h' => $h // actual y at bottom when printed = y+h
10583 );
10584 }
10585 else {
10586 $this->pages[$this->page] .= $s.($ln == true ? "\n" : '');
10587 }
10588
10589 }
10590 else {
10591 $this->buffer .= $s.($ln == true ? "\n" : '');
10592 }
10593 }
10594
10595 /*-- WATERMARK --*/
10596 // add a watermark
10597 function watermark( $texte, $angle=45, $fontsize=96, $alpha=0.2 ) {
10598 if ($this->PDFA || $this->PDFX) { $this->Error('PDFA and PDFX do not permit transparency, so mPDF does not allow Watermarks!'); }
10599 if (!$this->watermark_font) { $this->watermark_font = $this->default_font; }
10600 $this->SetFont( $this->watermark_font, "B", $fontsize, false ); // Don't output
10601 $texte= $this->purify_utf8_text($texte);
10602 if ($this->text_input_as_HTML) {
10603 $texte= $this->all_entities_to_utf8($texte);
10604 }
10605 if ($this->usingCoreFont) { $texte = mb_convert_encoding($texte,$this->mb_enc,'UTF-8'); }
10606 // DIRECTIONALITY
10607 $this->magic_reverse_dir($texte, true, $this->directionality); // *RTL*
10608 // Font-specific ligature substitution for Indic fonts
10609 if (isset($this->CurrentFont['indic']) && $this->CurrentFont['indic']) $this->ConvertIndic($texte); // *INDIC*
10610
10611 $this->SetAlpha($alpha);
10612
10613 $this->SetTColor($this->ConvertColor(0));
10614 $szfont = $fontsize;
10615 $loop = 0;
10616 $maxlen = (min($this->w,$this->h) ); // sets max length of text as 7/8 width/height of page
10617 while ( $loop == 0 )
10618 {
10619 $this->SetFont( $this->watermark_font, "B", $szfont, false ); // Don't output
10620 $offset = ((sin(deg2rad($angle))) * ($szfont/_MPDFK));
10621
10622 $strlen = $this->GetStringWidth($texte);
10623 if ( $strlen > $maxlen - $offset )
10624 $szfont --;
10625 else
10626 $loop ++;
10627 }
10628
10629 $this->SetFont( $this->watermark_font, "B", $szfont-0.1, true, true); // Output The -0.1 is because SetFont above is not written to PDF
10630 // Repeating it will not output anything as mPDF thinks it is set
10631 $adj = ((cos(deg2rad($angle))) * ($strlen/2));
10632 $opp = ((sin(deg2rad($angle))) * ($strlen/2));
10633 $wx = ($this->w/2) - $adj + $offset/3;
10634 $wy = ($this->h/2) + $opp;
10635 $this->Rotate($angle,$wx,$wy);
10636 $this->Text($wx,$wy,$texte);
10637 $this->Rotate(0);
10638 $this->SetTColor($this->ConvertColor(0));
10639
10640 $this->SetAlpha(1);
10641
10642 }
10643
10644 function watermarkImg( $src, $alpha=0.2 ) {
10645 if ($this->PDFA || $this->PDFX) { $this->Error('PDFA and PDFX do not permit transparency, so mPDF does not allow Watermarks!'); }
10646 if ($this->watermarkImgBehind) { $this->watermarkImgAlpha = $this->SetAlpha($alpha, 'Normal', true); }
10647 else { $this->SetAlpha($alpha, $this->watermarkImgAlphaBlend); }
10648 $this->Image($src,0,0,0,0,'','', true, true, true);
10649 if (!$this->watermarkImgBehind) { $this->SetAlpha(1); }
10650 }
10651 /*-- END WATERMARK --*/
10652
10653
10654 function Rotate($angle,$x=-1,$y=-1)
10655 {
10656 if($x==-1)
10657 $x=$this->x;
10658 if($y==-1)
10659 $y=$this->y;
10660 if($this->angle!=0)
10661 $this->_out('Q');
10662 $this->angle=$angle;
10663 if($angle!=0)
10664 {
10665 $angle*=M_PI/180;
10666 $c=cos($angle);
10667 $s=sin($angle);
10668 $cx=$x*_MPDFK;
10669 $cy=($this->h-$y)*_MPDFK;
10670 $this->_out(sprintf('q %.5F %.5F %.5F %.5F %.3F %.3F cm 1 0 0 1 %.3F %.3F cm',$c,$s,-$s,$c,$cx,$cy,-$cx,-$cy));
10671 }
10672 }
10673
10674
10675
10676 function CircularText($x, $y, $r, $text, $align='top', $fontfamily='', $fontsize=0, $fontstyle='', $kerning=120, $fontwidth=100, $divider) { // mPDF 5.5.23
10677 if (!class_exists('directw', false)) { include(_MPDF_PATH.'classes/directw.php'); }
10678 if (empty($this->directw)) { $this->directw = new directw($this); }
10679 $this->directw->CircularText($x, $y, $r, $text, $align, $fontfamily, $fontsize, $fontstyle, $kerning, $fontwidth, $divider); // mPDF 5.5.23
10680 }
10681
10682
10683 // From Invoice
10684 function RoundedRect($x, $y, $w, $h, $r, $style = '')
10685 {
10686 $hp = $this->h;
10687 if($style=='F')
10688 $op='f';
10689 elseif($style=='FD' or $style=='DF')
10690 $op='B';
10691 else
10692 $op='S';
10693 $MyArc = 4/3 * (sqrt(2) - 1);
10694 $this->_out(sprintf('%.3F %.3F m',($x+$r)*_MPDFK,($hp-$y)*_MPDFK ));
10695 $xc = $x+$w-$r ;
10696 $yc = $y+$r;
10697 $this->_out(sprintf('%.3F %.3F l', $xc*_MPDFK,($hp-$y)*_MPDFK ));
10698
10699 $this->_Arc($xc + $r*$MyArc, $yc - $r, $xc + $r, $yc - $r*$MyArc, $xc + $r, $yc);
10700 $xc = $x+$w-$r ;
10701 $yc = $y+$h-$r;
10702 $this->_out(sprintf('%.3F %.3F l',($x+$w)*_MPDFK,($hp-$yc)*_MPDFK));
10703 $this->_Arc($xc + $r, $yc + $r*$MyArc, $xc + $r*$MyArc, $yc + $r, $xc, $yc + $r);
10704 $xc = $x+$r ;
10705 $yc = $y+$h-$r;
10706 $this->_out(sprintf('%.3F %.3F l',$xc*_MPDFK,($hp-($y+$h))*_MPDFK));
10707 $this->_Arc($xc - $r*$MyArc, $yc + $r, $xc - $r, $yc + $r*$MyArc, $xc - $r, $yc);
10708 $xc = $x+$r ;
10709 $yc = $y+$r;
10710 $this->_out(sprintf('%.3F %.3F l',($x)*_MPDFK,($hp-$yc)*_MPDFK ));
10711 $this->_Arc($xc - $r, $yc - $r*$MyArc, $xc - $r*$MyArc, $yc - $r, $xc, $yc - $r);
10712 $this->_out($op);
10713 }
10714
10715 function _Arc($x1, $y1, $x2, $y2, $x3, $y3)
10716 {
10717 $h = $this->h;
10718 $this->_out(sprintf('%.3F %.3F %.3F %.3F %.3F %.3F c ', $x1*_MPDFK, ($h-$y1)*_MPDFK,
10719 $x2*_MPDFK, ($h-$y2)*_MPDFK, $x3*_MPDFK, ($h-$y3)*_MPDFK));
10720 }
10721
10722
10723
10724
10725 //====================================================
10726
10727
10728
10729 /*-- DIRECTW --*/
10730 function Shaded_box( $text,$font='',$fontstyle='B',$szfont='',$width='70%',$style='DF',$radius=2.5,$fill='#FFFFFF',$color='#000000',$pad=2 ) {
10731 // F (shading - no line),S (line, no shading),DF (both)
10732 if (!class_exists('directw', false)) { include(_MPDF_PATH.'classes/directw.php'); }
10733 if (empty($this->directw)) { $this->directw = new directw($this); }
10734 $this->directw->Shaded_box( $text,$font,$fontstyle,$szfont,$width,$style,$radius,$fill,$color,$pad);
10735 }
10736 /*-- END DIRECTW --*/
10737
10738
10739 function UTF8StringToArray($str, $addSubset=true) {
10740 $out = array();
10741 $len = strlen($str);
10742 for ($i = 0; $i < $len; $i++) {
10743 $uni = -1;
10744 $h = ord($str[$i]);
10745 if ( $h <= 0x7F )
10746 $uni = $h;
10747 elseif ( $h >= 0xC2 ) {
10748 if ( ($h <= 0xDF) && ($i < $len -1) )
10749 $uni = ($h & 0x1F) << 6 | (ord($str[++$i]) & 0x3F);
10750 elseif ( ($h <= 0xEF) && ($i < $len -2) )
10751 $uni = ($h & 0x0F) << 12 | (ord($str[++$i]) & 0x3F) << 6 | (ord($str[++$i]) & 0x3F);
10752 elseif ( ($h <= 0xF4) && ($i < $len -3) )
10753 $uni = ($h & 0x0F) << 18 | (ord($str[++$i]) & 0x3F) << 12 | (ord($str[++$i]) & 0x3F) << 6 | (ord($str[++$i]) & 0x3F);
10754 }
10755 if ($uni >= 0) {
10756 $out[] = $uni;
10757 if ($addSubset && isset($this->CurrentFont['subset'])) {
10758 $this->CurrentFont['subset'][$uni] = $uni;
10759 }
10760 }
10761 }
10762 return $out;
10763 }
10764
10765
10766 //Convert utf-8 string to <HHHHHH> for Font Subsets
10767 function UTF8toSubset($str) {
10768 $ret = '<';
10769 $str = preg_replace('/'.preg_quote($this->aliasNbPg,'/').'/', chr(7), $str );
10770 $str = preg_replace('/'.preg_quote($this->aliasNbPgGp,'/').'/', chr(8), $str );
10771 $unicode = $this->UTF8StringToArray($str);
10772 $orig_fid = $this->CurrentFont['subsetfontids'][0];
10773 $last_fid = $this->CurrentFont['subsetfontids'][0];
10774 foreach($unicode as $c) {
10775 if ($c == 7 || $c == 8) {
10776 if ($orig_fid != $last_fid) {
10777 $ret .= '> Tj /F'.$orig_fid.' '.$this->FontSizePt.' Tf <';
10778 $last_fid = $orig_fid;
10779 }
10780 if ($c == 7) { $ret .= $this->aliasNbPgHex; }
10781 else { $ret .= $this->aliasNbPgGpHex; }
10782 continue;
10783 }
10784 for ($i=0; $i<99; $i++) {
10785 // return c as decimal char
10786 $init = array_search($c, $this->CurrentFont['subsets'][$i]);
10787 if ($init!==false) {
10788 if ($this->CurrentFont['subsetfontids'][$i] != $last_fid) {
10789 $ret .= '> Tj /F'.$this->CurrentFont['subsetfontids'][$i].' '.$this->FontSizePt.' Tf <';
10790 $last_fid = $this->CurrentFont['subsetfontids'][$i];
10791 }
10792 $ret .= sprintf("%02s", strtoupper(dechex($init)));
10793 break;
10794 }
10795 // TrueType embedded SUBSETS
10796 else if (count($this->CurrentFont['subsets'][$i]) < 255) {
10797 $n = count($this->CurrentFont['subsets'][$i]);
10798 $this->CurrentFont['subsets'][$i][$n] = $c;
10799 if ($this->CurrentFont['subsetfontids'][$i] != $last_fid) {
10800 $ret .= '> Tj /F'.$this->CurrentFont['subsetfontids'][$i].' '.$this->FontSizePt.' Tf <';
10801 $last_fid = $this->CurrentFont['subsetfontids'][$i];
10802 }
10803 $ret .= sprintf("%02s", strtoupper(dechex($n)));
10804 break;
10805 }
10806 else if (!isset($this->CurrentFont['subsets'][($i+1)])) {
10807 // TrueType embedded SUBSETS
10808 $this->CurrentFont['subsets'][($i+1)] = array(0=>0);
10809 $new_fid = count($this->fonts)+$this->extraFontSubsets+1;
10810 $this->CurrentFont['subsetfontids'][($i+1)] = $new_fid;
10811 $this->extraFontSubsets++;
10812 }
10813 }
10814 }
10815 $ret .= '>';
10816 if ($last_fid != $orig_fid) {
10817 $ret .= ' Tj /F'.$orig_fid.' '.$this->FontSizePt.' Tf <> ';
10818 }
10819 return $ret;
10820 }
10821
10822
10823 // Converts UTF-8 strings to UTF16-BE.
10824 function UTF8ToUTF16BE($str, $setbom=true) {
10825 if ($this->checkSIP && preg_match("/([\x{20000}-\x{2FFFF}])/u", $str)) {
10826 if (!in_array($this->currentfontfamily, array('gb','big5','sjis','uhc','gbB','big5B','sjisB','uhcB','gbI','big5I','sjisI','uhcI',
10827 'gbBI','big5BI','sjisBI','uhcBI'))) {
10828 $str = preg_replace("/[\x{20000}-\x{2FFFF}]/u", chr(0), $str);
10829 }
10830 }
10831 if ($this->checkSMP && preg_match("/([\x{10000}-\x{1FFFF}])/u", $str )) {
10832 $str = preg_replace("/[\x{10000}-\x{1FFFF}]/u", chr(0), $str );
10833 }
10834 $outstr = ""; // string to be returned
10835 if ($setbom) {
10836 $outstr .= "\xFE\xFF"; // Byte Order Mark (BOM)
10837 }
10838 $outstr .= mb_convert_encoding($str, 'UTF-16BE', 'UTF-8');
10839 return $outstr;
10840 }
10841
10842
10843
10844
10845
10846 // ====================================================
10847 // ====================================================
10848 /*-- CJK-FONTS --*/
10849
10850 // from class PDF_Chinese CJK EXTENSIONS
10851 function AddCIDFont($family,$style,$name,&$cw,$CMap,$registry,$desc)
10852 {
10853 $fontkey=strtolower($family).strtoupper($style);
10854 if(isset($this->fonts[$fontkey]))
10855 $this->Error("Font already added: $family $style");
10856 $i=count($this->fonts)+$this->extraFontSubsets+1;
10857 $name=str_replace(' ','',$name);
10858 if ($family == 'sjis') { $up = -120; } else { $up = -130; }
10859 // ? 'up' and 'ut' do not seem to be referenced anywhere
10860 $this->fonts[$fontkey]=array('i'=>$i,'type'=>'Type0','name'=>$name,'up'=>$up,'ut'=>40,'cw'=>$cw,'CMap'=>$CMap,'registry'=>$registry,'MissingWidth'=>1000,'desc'=>$desc);
10861 }
10862
10863 function AddCJKFont($family) {
10864
10865 if ($this->PDFA || $this->PDFX) {
10866 $this->Error("Adobe CJK fonts cannot be embedded in mPDF (required for PDFA1-b and PDFX/1-a).");
10867 }
10868 if ($family == 'big5') { $this->AddBig5Font(); }
10869 else if ($family == 'gb') { $this->AddGBFont(); }
10870 else if ($family == 'sjis') { $this->AddSJISFont(); }
10871 else if ($family == 'uhc') { $this->AddUHCFont(); }
10872 }
10873
10874 function AddBig5Font()
10875 {
10876 //Add Big5 font with proportional Latin
10877 $family='big5';
10878 $name='MSungStd-Light-Acro';
10879 $cw=$this->Big5_widths;
10880 $CMap='UniCNS-UTF16-H';
10881 $registry=array('ordering'=>'CNS1','supplement'=>4);
10882 $desc = array(
10883 'Ascent' => 880,
10884 'Descent' => -120,
10885 'CapHeight' => 880,
10886 'Flags' => 6,
10887 'FontBBox' => '[-160 -249 1015 1071]',
10888 'ItalicAngle' => 0,
10889 'StemV' => 93,
10890 );
10891 $this->AddCIDFont($family,'',$name,$cw,$CMap,$registry,$desc);
10892 $this->AddCIDFont($family,'B',$name.',Bold',$cw,$CMap,$registry,$desc);
10893 $this->AddCIDFont($family,'I',$name.',Italic',$cw,$CMap,$registry,$desc);
10894 $this->AddCIDFont($family,'BI',$name.',BoldItalic',$cw,$CMap,$registry,$desc);
10895 }
10896
10897
10898 function AddGBFont()
10899 {
10900 //Add GB font with proportional Latin
10901 $family='gb';
10902 $name='STSongStd-Light-Acro';
10903 $cw=$this->GB_widths;
10904 $CMap='UniGB-UTF16-H';
10905 $registry=array('ordering'=>'GB1','supplement'=>4);
10906 $desc = array(
10907 'Ascent' => 752,
10908 'Descent' => -271,
10909 'CapHeight' => 737,
10910 'Flags' => 6,
10911 'FontBBox' => '[-25 -254 1000 880]',
10912 'ItalicAngle' => 0,
10913 'StemV' => 58,
10914 'Style' => '<< /Panose <000000000400000000000000> >>',
10915 );
10916 $this->AddCIDFont($family,'',$name,$cw,$CMap,$registry,$desc);
10917 $this->AddCIDFont($family,'B',$name.',Bold',$cw,$CMap,$registry,$desc);
10918 $this->AddCIDFont($family,'I',$name.',Italic',$cw,$CMap,$registry,$desc);
10919 $this->AddCIDFont($family,'BI',$name.',BoldItalic',$cw,$CMap,$registry,$desc);
10920 }
10921
10922
10923 function AddSJISFont()
10924 {
10925 //Add SJIS font with proportional Latin
10926 $family='sjis';
10927 $name='KozMinPro-Regular-Acro';
10928 $cw=$this->SJIS_widths;
10929 $CMap='UniJIS-UTF16-H';
10930 $registry=array('ordering'=>'Japan1','supplement'=>5);
10931 $desc = array(
10932 'Ascent' => 880,
10933 'Descent' => -120,
10934 'CapHeight' => 740,
10935 'Flags' => 6,
10936 'FontBBox' => '[-195 -272 1110 1075]',
10937 'ItalicAngle' => 0,
10938 'StemV' => 86,
10939 'XHeight' => 502,
10940 );
10941 $this->AddCIDFont($family,'',$name,$cw,$CMap,$registry,$desc);
10942 $this->AddCIDFont($family,'B',$name.',Bold',$cw,$CMap,$registry,$desc);
10943 $this->AddCIDFont($family,'I',$name.',Italic',$cw,$CMap,$registry,$desc);
10944 $this->AddCIDFont($family,'BI',$name.',BoldItalic',$cw,$CMap,$registry,$desc);
10945 }
10946
10947 function AddUHCFont()
10948 {
10949 //Add UHC font with proportional Latin
10950 $family='uhc';
10951 $name='HYSMyeongJoStd-Medium-Acro';
10952 $cw=$this->UHC_widths;
10953 $CMap='UniKS-UTF16-H';
10954 $registry=array('ordering'=>'Korea1','supplement'=>2);
10955 $desc = array(
10956 'Ascent' => 880,
10957 'Descent' => -120,
10958 'CapHeight' => 720,
10959 'Flags' => 6,
10960 'FontBBox' => '[-28 -148 1001 880]',
10961 'ItalicAngle' => 0,
10962 'StemV' => 60,
10963 'Style' => '<< /Panose <000000000600000000000000> >>',
10964 );
10965 $this->AddCIDFont($family,'',$name,$cw,$CMap,$registry,$desc);
10966 $this->AddCIDFont($family,'B',$name.',Bold',$cw,$CMap,$registry,$desc);
10967 $this->AddCIDFont($family,'I',$name.',Italic',$cw,$CMap,$registry,$desc);
10968 $this->AddCIDFont($family,'BI',$name.',BoldItalic',$cw,$CMap,$registry,$desc);
10969 }
10970
10971 /*-- END CJK-FONTS --*/
10972
10973 //////////////////////////////////////////////////////////////////////////////
10974 //////////////////////////////////////////////////////////////////////////////
10975 //////////////////////////////////////////////////////////////////////////////
10976 //////////////////////////////////////////////////////////////////////////////
10977 //////////////////////////////////////////////////////////////////////////////
10978 //////////////////////////////////////////////////////////////////////////////
10979 //////////////////////////////////////////////////////////////////////////////
10980 function SetAutoFont($af = AUTOFONT_ALL) {
10981 if ($this->onlyCoreFonts) { return false; }
10982 if (!$af && $af !== 0) { $af = AUTOFONT_ALL; }
10983 $this->autoFontGroups = $af;
10984 if ($this->autoFontGroups ) {
10985 $this->useLang = true;
10986 }
10987 }
10988
10989
10990 function SetDefaultFont($font) {
10991 // Disallow embedded fonts to be used as defaults in PDFA
10992 if ($this->PDFA || $this->PDFX) {
10993 if (strtolower($font) == 'ctimes') { $font = 'serif'; }
10994 if (strtolower($font) == 'ccourier') { $font = 'monospace'; }
10995 if (strtolower($font) == 'chelvetica') { $font = 'sans-serif'; }
10996 }
10997 $font = $this->SetFont($font); // returns substituted font if necessary
10998 $this->default_font = $font;
10999 $this->original_default_font = $font;
11000 if (!$this->watermark_font ) { $this->watermark_font = $font; } // *WATERMARK*
11001 $this->defaultCSS['BODY']['FONT-FAMILY'] = $font;
11002 $this->cssmgr->CSS['BODY']['FONT-FAMILY'] = $font;
11003 }
11004
11005 function SetDefaultFontSize($fontsize) {
11006 $this->default_font_size = $fontsize;
11007 $this->original_default_font_size = $fontsize;
11008 $this->SetFontSize($fontsize);
11009 $this->defaultCSS['BODY']['FONT-SIZE'] = $fontsize . 'pt';
11010 $this->cssmgr->CSS['BODY']['FONT-SIZE'] = $fontsize . 'pt';
11011 }
11012
11013 function SetDefaultBodyCSS($prop, $val) {
11014 if ($prop) {
11015 $this->defaultCSS['BODY'][strtoupper($prop)] = $val;
11016 $this->cssmgr->CSS['BODY'][strtoupper($prop)] = $val;
11017 }
11018 }
11019
11020
11021 function SetDirectionality($dir='ltr') {
11022 /*-- RTL --*/
11023 if (strtolower($dir) == 'rtl') {
11024 if ($this->directionality != 'rtl') {
11025 // Swop L/R Margins so page 1 RTL is an 'even' page
11026 $tmp = $this->DeflMargin;
11027 $this->DeflMargin = $this->DefrMargin;
11028 $this->DefrMargin = $tmp;
11029 $this->orig_lMargin = $this->DeflMargin;
11030 $this->orig_rMargin = $this->DefrMargin;
11031
11032 $this->SetMargins($this->DeflMargin,$this->DefrMargin,$this->tMargin);
11033 }
11034 $this->directionality = 'rtl';
11035 $this->defaultAlign = 'R';
11036 $this->defaultTableAlign = 'R';
11037 }
11038 else {
11039 /*-- END RTL --*/
11040 $this->directionality = 'ltr';
11041 $this->defaultAlign = 'L';
11042 $this->defaultTableAlign = 'L';
11043 } // *RTL*
11044 $this->cssmgr->CSS['BODY']['DIRECTION'] = $this->directionality;
11045 }
11046
11047
11048
11049 // Added to set line-height-correction
11050 function SetLineHeightCorrection($val) {
11051 if ($val > 0) { $this->default_lineheight_correction = $val; }
11052 else { $this->default_lineheight_correction = 1.2; }
11053 }
11054
11055 // Set a (fixed) lineheight to an actual value - either to named fontsize(pts) or default
11056 function SetLineHeight($FontPt='',$spacing = '') {
11057 if ($this->shrin_k > 1) { $k = $this->shrin_k; }
11058 else { $k = 1; }
11059 if ($spacing > 0) {
11060 if (preg_match('/mm/',$spacing)) {
11061 $this->lineheight = ($spacing + 0.0) / $k; // convert to number
11062 }
11063 else {
11064 if ($FontPt) { $this->lineheight = (($FontPt/_MPDFK) *$spacing); }
11065 else { $this->lineheight = (($this->FontSizePt/_MPDFK) *$spacing); }
11066 }
11067 }
11068 else {
11069 if ($FontPt) { $this->lineheight = (($FontPt/_MPDFK) *$this->normalLineheight); }
11070 else { $this->lineheight = (($this->FontSizePt/_MPDFK) *$this->normalLineheight); }
11071 }
11072 }
11073
11074 function _computeLineheight($lh, $fs='') {
11075 if ($this->shrin_k > 1) { $k = $this->shrin_k; }
11076 else { $k = 1; }
11077 if (!$fs) { $fs = $this->FontSize; }
11078 if (preg_match('/mm/',$lh)) {
11079 return (($lh + 0.0) / $k); // convert to number
11080 }
11081 else if ($lh > 0) {
11082 return ($fs * $lh);
11083 }
11084 else if (isset($this->normalLineheight)) { return ($fs * $this->normalLineheight); }
11085 else return ($fs * $this->default_lineheight_correction);
11086 }
11087
11088
11089 function SetBasePath($str='') {
11090 if ( isset($_SERVER['HTTP_HOST']) ) { $host = $_SERVER['HTTP_HOST']; }
11091 else if ( isset($_SERVER['SERVER_NAME']) ) { $host = $_SERVER['SERVER_NAME']; }
11092 else { $host = ''; }
11093 if (!$str) {
11094 if ($_SERVER['SCRIPT_NAME']) { $currentPath = dirname($_SERVER['SCRIPT_NAME']); }
11095 else { $currentPath = dirname($_SERVER['PHP_SELF']); }
11096 $currentPath = str_replace("\\","/",$currentPath);
11097 if ($currentPath == '/') { $currentPath = ''; }
11098 if ($host) { $currpath = 'http://' . $host . $currentPath .'/'; }
11099 else { $currpath = ''; }
11100 $this->basepath = $currpath;
11101 $this->basepathIsLocal = true;
11102 return;
11103 }
11104 $str = preg_replace('/\?.*/','',$str);
11105 if (!preg_match('/(http|https|ftp):\/\/.*\//i',$str)) { $str .= '/'; }
11106 $str .= 'xxx'; // in case $str ends in / e.g. http://www.bbc.co.uk/
11107 $this->basepath = dirname($str) . "/"; // returns e.g. e.g. http://www.google.com/dir1/dir2/dir3/
11108 $this->basepath = str_replace("\\","/",$this->basepath); //If on Windows
11109 $tr = parse_url($this->basepath);
11110 if (isset($tr['host']) && ($tr['host'] == $host)) { $this->basepathIsLocal = true; }
11111 else { $this->basepathIsLocal = false; }
11112 }
11113
11114
11115 function GetFullPath(&$path,$basepath='') {
11116 // When parsing CSS need to pass temporary basepath - so links are relative to current stylesheet
11117 if (!$basepath) { $basepath = $this->basepath; }
11118 //Fix path value
11119 $path = str_replace("\\","/",$path); //If on Windows
11120 $path = preg_replace('/^\/\//','http://',$path); // mPDF 5.6.27
11121 $regexp = '|^./|'; // Inadvertently corrects "./path/etc" and "//www.domain.com/etc"
11122 $path = preg_replace($regexp,'',$path);
11123
11124
11125 if(substr($path,0,1) == '#') { return; }
11126 if (stristr($path,"mailto:") !== false) { return; }
11127 if (strpos($path,"../") !== false ) { //It is a Relative Link
11128 $backtrackamount = substr_count($path,"../");
11129 $maxbacktrack = substr_count($basepath,"/") - 3; // mPDF 5.6.18
11130 $filepath = str_replace("../",'',$path);
11131 $path = $basepath;
11132 //If it is an invalid relative link, then make it go to directory root
11133 if ($backtrackamount > $maxbacktrack) $backtrackamount = $maxbacktrack;
11134 //Backtrack some directories
11135 for( $i = 0 ; $i < $backtrackamount + 1 ; $i++ ) $path = substr( $path, 0 , strrpos($path,"/") );
11136 $path = $path . "/" . $filepath; //Make it an absolute path
11137 }
11138 else if( strpos($path,":/") === false || strpos($path,":/") > 10) { //It is a Local Link
11139 if (substr($path,0,1) == "/") {
11140 $tr = parse_url($basepath);
11141 $root = $tr['scheme'].'://'.$tr['host'];
11142 $path = $root . $path;
11143 }
11144 else { $path = $basepath . $path; }
11145 }
11146 //Do nothing if it is an Absolute Link
11147 }
11148
11149
11150 // Used for external CSS files
11151 function _get_file($path) {
11152 // If local file try using local path (? quicker, but also allowed even if allow_url_fopen false)
11153 $contents = '';
11154 $contents = @file_get_contents($path);
11155 if ($contents) { return $contents; }
11156 if ($this->basepathIsLocal) {
11157 $tr = parse_url($path);
11158 $lp=getenv("SCRIPT_NAME");
11159 $ap=realpath($lp);
11160 $ap=str_replace("\\","/",$ap);
11161 $docroot=substr($ap,0,strpos($ap,$lp));
11162 // WriteHTML parses all paths to full URLs; may be local file name
11163 if ($tr['scheme'] && $tr['host'] && $_SERVER["DOCUMENT_ROOT"] ) {
11164 $localpath = $_SERVER["DOCUMENT_ROOT"] . $tr['path'];
11165 }
11166 // DOCUMENT_ROOT is not returned on IIS
11167 else if ($docroot) {
11168 $localpath = $docroot . $tr['path'];
11169 }
11170 else { $localpath = $path; }
11171 $contents = @file_get_contents($localpath);
11172 }
11173 // if not use full URL
11174 else if (!$contents && !ini_get('allow_url_fopen') && function_exists("curl_init")) {
11175 $ch = curl_init($path);
11176 curl_setopt($ch, CURLOPT_HEADER, 0);
11177 curl_setopt ( $ch , CURLOPT_RETURNTRANSFER , 1 );
11178 $contents = curl_exec($ch);
11179 curl_close($ch);
11180 }
11181 return $contents;
11182 }
11183
11184
11185 function docPageNum($num = 0, $extras = false) {
11186 if ($num < 1) { $num = $this->page; }
11187 $type = '1'; // set default decimal
11188 $ppgno = $num;
11189 $suppress = 0;
11190 $offset = 0;
11191 $lastreset = 0;
11192 foreach($this->PageNumSubstitutions AS $psarr) {
11193 if ($num >= $psarr['from']) {
11194 if ($psarr['reset']) {
11195 if ($psarr['reset']>1) { $offset = $psarr['reset']-1; }
11196 $ppgno = $num - $psarr['from'] + 1 + $offset;
11197 $lastreset = $psarr['from'];
11198 }
11199 if ($psarr['type']) { $type = $psarr['type']; }
11200 if (strtoupper($psarr['suppress'])=='ON' || $psarr['suppress']==1) { $suppress = 1; }
11201 else if (strtoupper($psarr['suppress'])=='OFF') { $suppress = 0; }
11202 }
11203 }
11204 if ($suppress) { return ''; }
11205
11206 foreach($this->pgsIns AS $k=>$v) {
11207 if ($k>$lastreset && $k<$num) {
11208 $ppgno -= $v;
11209 }
11210 }
11211 if ($type=='A') { $ppgno = $this->dec2alpha($ppgno,true); }
11212 else if ($type=='a') { $ppgno = $this->dec2alpha($ppgno,false);}
11213 else if ($type=='I') { $ppgno = $this->dec2roman($ppgno,true); }
11214 else if ($type=='i') { $ppgno = $this->dec2roman($ppgno,false); }
11215 if ($extras) { $ppgno = $this->pagenumPrefix . $ppgno . $this->pagenumSuffix; }
11216 return $ppgno;
11217 }
11218
11219
11220 function docPageSettings($num = 0) {
11221 // Returns current type (numberstyle), suppression state for this page number;
11222 // reset is only returned if set for this page number
11223 if ($num < 1) { $num = $this->page; }
11224 $type = '1'; // set default decimal
11225 $ppgno = $num;
11226 $suppress = 0;
11227 $offset = 0;
11228 $reset = '';
11229 foreach($this->PageNumSubstitutions AS $psarr) {
11230 if ($num >= $psarr['from']) {
11231 if ($psarr['reset']) {
11232 if ($psarr['reset']>1) { $offset = $psarr['reset']-1; }
11233 $ppgno = $num - $psarr['from'] + 1 + $offset;
11234 }
11235 if ($psarr['type']) { $type = $psarr['type']; }
11236 if (strtoupper($psarr['suppress'])=='ON' || $psarr['suppress']==1) { $suppress = 1; }
11237 else if (strtoupper($psarr['suppress'])=='OFF') { $suppress = 0; }
11238 }
11239 if ($num == $psarr['from']) { $reset = $psarr['reset']; }
11240 }
11241 if ($suppress) { $suppress = 'on'; }
11242 else { $suppress = 'off'; }
11243 return array($type, $suppress, $reset);
11244 }
11245
11246 function docPageNumTotal($num = 0, $extras = false) {
11247 if ($num < 1) { $num = $this->page; }
11248 $type = '1'; // set default decimal
11249 $ppgstart = 1;
11250 $ppgend = count($this->pages)+1;
11251 $suppress = 0;
11252 $offset = 0;
11253 foreach($this->PageNumSubstitutions AS $psarr) {
11254 if ($num >= $psarr['from']) {
11255 if ($psarr['reset']) {
11256 if ($psarr['reset']>1) { $offset = $psarr['reset']-1; }
11257 $ppgstart = $psarr['from'] + $offset;
11258 $ppgend = count($this->pages)+1 + $offset;
11259 }
11260 if ($psarr['type']) { $type = $psarr['type']; }
11261 if (strtoupper($psarr['suppress'])=='ON' || $psarr['suppress']==1) { $suppress = 1; }
11262 else if (strtoupper($psarr['suppress'])=='OFF') { $suppress = 0; }
11263 }
11264 if ($num < $psarr['from']) {
11265 if ($psarr['reset']) {
11266 $ppgend = $psarr['from'] + $offset;
11267 break;
11268 }
11269 }
11270 }
11271 if ($suppress) { return ''; }
11272 $ppgno = $ppgend-$ppgstart+$offset;
11273
11274 // mPDF 5.6.47
11275 foreach($this->pgsIns AS $k => $v) {
11276 if ($k>$ppgstart && $k<$ppgend) {
11277 $ppgno -= $v;
11278 }
11279 }
11280
11281 if ($extras) { $ppgno = $this->nbpgPrefix . $ppgno . $this->nbpgSuffix; }
11282 return $ppgno;
11283 }
11284
11285 function RestartDocTemplate() {
11286 $this->docTemplateStart = $this->page;
11287 }
11288
11289
11290
11291 //Page header
11292 function Header($content='') {
11293
11294 $this->cMarginL = 0;
11295 $this->cMarginR = 0;
11296
11297
11298 /*-- HTMLHEADERS-FOOTERS --*/
11299 if (($this->mirrorMargins && ($this->page%2==0) && $this->HTMLHeaderE) || ($this->mirrorMargins && ($this->page%2==1) && $this->HTMLHeader) || (!$this->mirrorMargins && $this->HTMLHeader)) {
11300 $this->writeHTMLHeaders();
11301 return;
11302 }
11303 /*-- END HTMLHEADERS-FOOTERS --*/
11304 $this->processingHeader=true;
11305 $h = $this->headerDetails;
11306 if(count($h)) {
11307
11308 if ($this->forcePortraitHeaders && $this->CurOrientation=='L' && $this->CurOrientation!=$this->DefOrientation) {
11309 $this->_out(sprintf('q 0 -1 1 0 0 %.3F cm ',($this->h*_MPDFK)));
11310 $yadj = $this->w - $this->h;
11311 $headerpgwidth = $this->h - $this->orig_lMargin - $this->orig_rMargin;
11312 if (($this->mirrorMargins) && (($this->page)%2==0)) { // EVEN
11313 $headerlmargin = $this->orig_rMargin;
11314 }
11315 else {
11316 $headerlmargin = $this->orig_lMargin;
11317 }
11318 }
11319 else {
11320 $yadj = 0;
11321 $headerpgwidth = $this->pgwidth;
11322 $headerlmargin = $this->lMargin;
11323 }
11324
11325 $this->y = $this->margin_header - $yadj ;
11326 $this->SetTColor($this->ConvertColor(0));
11327 $this->SUP = false;
11328 $this->SUB = false;
11329 $this->bullet = false;
11330
11331 // only show pagenumber if numbering on
11332 $pgno = $this->docPageNum($this->page, true);
11333
11334 if (($this->mirrorMargins) && (($this->page)%2==0)) { // EVEN
11335 $side = 'even';
11336 }
11337 else { // ODD // OR NOT MIRRORING MARGINS/FOOTERS = DEFAULT
11338 $side = 'odd';
11339 }
11340 $maxfontheight = 0;
11341 foreach(array('L','C','R') AS $pos) {
11342 if (isset($h[$side][$pos]['content']) && $h[$side][$pos]['content']) {
11343 if (isset($h[$side][$pos]['font-size']) && $h[$side][$pos]['font-size']) { $hfsz = $h[$side][$pos]['font-size']; }
11344 else { $hfsz = $this->default_font_size; }
11345 $maxfontheight = max($maxfontheight,$hfsz);
11346 }
11347 }
11348 // LEFT-CENTER-RIGHT
11349 foreach(array('L','C','R') AS $pos) {
11350 if (isset($h[$side][$pos]['content']) && $h[$side][$pos]['content']) {
11351 $hd = str_replace('{PAGENO}',$pgno,$h[$side][$pos]['content']);
11352 $hd = str_replace($this->aliasNbPgGp,$this->nbpgPrefix.$this->aliasNbPgGp.$this->nbpgSuffix,$hd);
11353 $hd = preg_replace('/\{DATE\s+(.*?)\}/e',"date('\\1')",$hd);
11354 if (isset($h[$side][$pos]['font-family']) && $h[$side][$pos]['font-family']) { $hff = $h[$side][$pos]['font-family']; }
11355 else { $hff = $this->original_default_font; }
11356 if (isset($h[$side][$pos]['font-size']) && $h[$side][$pos]['font-size']) { $hfsz = $h[$side][$pos]['font-size']; }
11357 else { $hfsz = $this->original_default_font_size; } // pts
11358 $maxfontheight = max($maxfontheight,$hfsz);
11359 $hfst = '';
11360 if (isset($h[$side][$pos]['font-style']) && $h[$side][$pos]['font-style']) {
11361 $hfst = $h[$side][$pos]['font-style'];
11362 }
11363 if (isset($h[$side][$pos]['color']) && $h[$side][$pos]['color']) {
11364 $hfcol = $h[$side][$pos]['color'];
11365 $cor = $this->ConvertColor($hfcol);
11366 if ($cor) { $this->SetTColor($cor); }
11367 }
11368 else { $hfcol = ''; }
11369 $this->SetFont($hff,$hfst,$hfsz,true,true);
11370 $this->x = $headerlmargin ;
11371 $this->y = $this->margin_header - $yadj ;
11372
11373 $hd = $this->purify_utf8_text($hd);
11374 if ($this->text_input_as_HTML) {
11375 $hd = $this->all_entities_to_utf8($hd);
11376 }
11377 // CONVERT CODEPAGE
11378 if ($this->usingCoreFont) { $hd = mb_convert_encoding($hd,$this->mb_enc,'UTF-8'); }
11379 // DIRECTIONALITY RTL
11380 $this->magic_reverse_dir($hd, true, $this->directionality); // *RTL*
11381 // Font-specific ligature substitution for Indic fonts
11382 if (isset($this->CurrentFont['indic']) && $this->CurrentFont['indic']) $this->ConvertIndic($hd); // *INDIC*
11383 $align = $pos;
11384 /*-- RTL --*/
11385 if ($this->directionality == 'rtl') {
11386 if ($pos == 'L') { $align = 'R'; }
11387 else if ($pos == 'R') { $align = 'L'; }
11388 }
11389 /*-- END RTL --*/
11390 if ($pos!='L' && (strpos($hd,$this->aliasNbPg)!==false || strpos($hd,$this->aliasNbPgGp)!==false)) {
11391 if (strpos($hd,$this->aliasNbPgGp)!==false) { $type= 'nbpggp'; } else { $type= 'nbpg'; }
11392 $this->_out('{mpdfheader'.$type.' '.$pos.' ff='.$hff.' fs='.$hfst.' fz='.$hfsz.'}');
11393 $this->Cell($headerpgwidth ,$maxfontheight/_MPDFK ,$hd,0,0,$align,0,'',0,0,0,'M');
11394 $this->_out('Q');
11395 }
11396 else {
11397 $this->Cell($headerpgwidth ,$maxfontheight/_MPDFK ,$hd,0,0,$align,0,'',0,0,0,'M');
11398 }
11399 if ($hfcol) { $this->SetTColor($this->ConvertColor(0)); }
11400 }
11401 }
11402 //Return Font to normal
11403 $this->SetFont($this->default_font,'',$this->original_default_font_size);
11404 // LINE
11405 if (isset($h[$side]['line']) && $h[$side]['line']) {
11406 $this->SetLineWidth(0.1);
11407 $this->SetDColor($this->ConvertColor(0));
11408 $this->Line($headerlmargin , $this->margin_header + ($maxfontheight*(1+$this->header_line_spacing)/_MPDFK) - $yadj , $headerlmargin + $headerpgwidth, $this->margin_header + ($maxfontheight*(1+$this->header_line_spacing)/_MPDFK) - $yadj );
11409 }
11410 if ($this->forcePortraitHeaders && $this->CurOrientation=='L' && $this->CurOrientation!=$this->DefOrientation) {
11411 $this->_out('Q');
11412 }
11413 }
11414 $this->SetY($this->tMargin);
11415 if ($this->ColActive) { $this->pgwidth = $this->ColWidth; } // *COLUMNS*
11416
11417 $this->processingHeader=false;
11418 }
11419
11420
11421
11422 /*-- TABLES --*/
11423 function TableHeaderFooter($content='',$tablestartpage='',$tablestartcolumn ='',$horf = 'H',$level, $firstSpread=true, $finalSpread=true) {
11424 if(($horf=='H' || $horf=='F') && !empty($content) && !empty($content[0])) { // mPDF 5.6.61
11425 $table = &$this->table[1][1];
11426 // Advance down page by half width of top border
11427
11428 if ($horf=='H') { // Only if header
11429 if ($table['borders_separate']) { $adv = $table['border_spacing_V']/2 + $table['border_details']['T']['w'] + $table['padding']['T']; }
11430 else { $adv = $table['max_cell_border_width']['T'] /2 ; }
11431 if ($adv) {
11432 if ($this->table_rotate) {
11433 $this->y += ($adv);
11434 }
11435 else {
11436 $this->DivLn($adv,$this->blklvl,true);
11437 }
11438 }
11439 }
11440
11441 if ($horf=='F') { // Table Footer
11442 $firstrow = count($table['cells']) - $table['footernrows'];
11443 $lastrow = count($table['cells']) - 1;
11444 }
11445 else { // Table Header
11446 $firstrow = 0;
11447 $lastrow = $table['headernrows'] - 1;
11448 }
11449
11450 $topy = $content[$firstrow][0]['y']-$this->y;
11451
11452 for ($i=$firstrow ; $i<=$lastrow; $i++) {
11453
11454 $y = $this->y;
11455
11456 /*-- COLUMNS --*/
11457 // If outside columns, this is done in PaintDivBB
11458 if ($this->ColActive) {
11459 //OUTER FILL BGCOLOR of DIVS
11460 if ($this->blklvl > 0) {
11461 $firstblockfill = $this->GetFirstBlockFill();
11462 if ($firstblockfill && $this->blklvl >= $firstblockfill) {
11463 $divh = $content[$i][0]['h'];
11464 $bak_x = $this->x;
11465 $this->DivLn($divh,-3,false);
11466 // Reset current block fill
11467 $bcor = $this->blk[$this->blklvl]['bgcolorarray'];
11468 $this->SetFColor($bcor);
11469 $this->x = $bak_x;
11470 }
11471 }
11472 }
11473 /*-- END COLUMNS --*/
11474
11475 $colctr = 0;
11476 foreach($content[$i] as $tablehf) {
11477 $colctr++;
11478 $y = $tablehf['y'] - $topy;
11479 $this->y = $y;
11480 //Set some cell values
11481 $x = $tablehf['x'];
11482 if (($this->mirrorMargins) && ($tablestartpage == 'ODD') && (($this->page)%2==0)) { // EVEN
11483 $x = $x +$this->MarginCorrection;
11484 }
11485 else if (($this->mirrorMargins) && ($tablestartpage == 'EVEN') && (($this->page)%2==1)) { // ODD
11486 $x = $x +$this->MarginCorrection;
11487 }
11488 /*-- COLUMNS --*/
11489 // Added to correct for Columns
11490 if ($this->ColActive) {
11491 if ($this->directionality == 'rtl') { // *RTL*
11492 $x -= ($this->CurrCol - $tablestartcolumn) * ($this->ColWidth+$this->ColGap); // *RTL*
11493 } // *RTL*
11494 else { // *RTL*
11495 $x += ($this->CurrCol - $tablestartcolumn) * ($this->ColWidth+$this->ColGap);
11496 } // *RTL*
11497 }
11498 /*-- END COLUMNS --*/
11499
11500 if ($colctr==1) { $x0 = $x; }
11501
11502 // mPDF ITERATION
11503 if ($this->iterationCounter) {
11504 foreach($tablehf['textbuffer'] AS $k=>$t) {
11505 if (!is_array($t[0]) && preg_match('/{iteration ([a-zA-Z0-9_]+)}/',$t[0], $m)) { // mPDF 5.5.06
11506 $vname = '__'.$m[1].'_';
11507 if (!isset($this->$vname)) { $this->$vname = 1; }
11508 else { $this->$vname++; }
11509 $tablehf['textbuffer'][$k][0] = preg_replace('/{iteration '.$m[1].'}/', $this->$vname, $tablehf['textbuffer'][$k][0]);
11510 }
11511 }
11512 }
11513
11514
11515 $w = $tablehf['w'];
11516 $h = $tablehf['h'];
11517 $va = $tablehf['va'];
11518 $R = $tablehf['R'];
11519 $mih = $tablehf['mih'];
11520 $border = $tablehf['border'];
11521 $border_details = $tablehf['border_details'];
11522 $padding = $tablehf['padding'];
11523 $this->tabletheadjustfinished = true;
11524
11525 $textbuffer = $tablehf['textbuffer'];
11526
11527 $align = $tablehf['a'];
11528 //Align
11529 $this->divalign=$align;
11530 $this->x = $x;
11531
11532 if ($this->ColActive) {
11533 if ($table['borders_separate']) {
11534 $tablefill = isset($table['bgcolor'][-1]) ? $table['bgcolor'][-1] : 0;
11535 if ($tablefill) {
11536 $color = $this->ConvertColor($tablefill);
11537 if ($color) {
11538 $xadj = ($table['border_spacing_H']/2);
11539 $yadj = ($table['border_spacing_V']/2);
11540 $wadj = $table['border_spacing_H'];
11541 $hadj = $table['border_spacing_V'];
11542 if ($i == $firstrow && $horf=='H') { // Top
11543 $yadj += $table['padding']['T'] + $table['border_details']['T']['w'] ;
11544 $hadj += $table['padding']['T'] + $table['border_details']['T']['w'] ;
11545 }
11546 if (($i == ($lastrow) || (isset($tablehf['rowspan']) && ($i+$tablehf['rowspan']) == ($lastrow+1)) || (!isset($tablehf['rowspan']) && ($i+1) == ($lastrow+1))) && $horf=='F') { // Bottom
11547 $hadj += $table['padding']['B'] + $table['border_details']['B']['w'] ;
11548 }
11549 if ($colctr == 1) { // Left
11550 $xadj += $table['padding']['L'] + $table['border_details']['L']['w'] ;
11551 $wadj += $table['padding']['L'] + $table['border_details']['L']['w'] ;
11552 }
11553 if ($colctr == count($content[$i]) ) { // Right
11554 $wadj += $table['padding']['R'] + $table['border_details']['R']['w'] ;
11555 }
11556 $this->SetFColor($color);
11557 $this->Rect($x - $xadj, $y - $yadj, $w + $wadj, $h + $hadj, 'F');
11558 }
11559 }
11560 }
11561 }
11562
11563 if ($table['empty_cells']!='hide' || !empty($textbuffer) || !$table['borders_separate']) { $paintcell = true; }
11564 else { $paintcell = false; }
11565
11566 //Vertical align
11567 if ($R && INTVAL($R) > 0 && isset($va) && $va!='B') { $va='B';}
11568
11569 if (!isset($va) || empty($va) || $va=='M') $this->y += ($h-$mih)/2;
11570 elseif (isset($va) && $va=='B') $this->y += $h-$mih;
11571
11572
11573 //TABLE ROW OR CELL FILL BGCOLOR
11574 $fill = 0;
11575 if (isset($tablehf['bgcolor']) && $tablehf['bgcolor'] && $tablehf['bgcolor']!='transparent') {
11576 $fill = $tablehf['bgcolor'];
11577 $leveladj = 6;
11578 }
11579 else if (isset($content[$i][0]['trbgcolor']) && $content[$i][0]['trbgcolor'] && $content[$i][0]['trbgcolor']!='transparent') { // Row color
11580 $fill = $content[$i][0]['trbgcolor'];
11581 $leveladj = 3;
11582 }
11583 if ($fill && $paintcell) {
11584 $color = $this->ConvertColor($fill);
11585 if ($color) {
11586 if ($table['borders_separate']) {
11587 if ($this->ColActive) {
11588 $this->SetFColor($color);
11589 $this->Rect($x+ ($table['border_spacing_H']/2), $y+ ($table['border_spacing_V']/2), $w- $table['border_spacing_H'], $h- $table['border_spacing_V'], 'F');
11590 }
11591 else {
11592 $this->tableBackgrounds[$level*9+$leveladj][] = array('gradient'=>false, 'x'=>($x + ($table['border_spacing_H']/2)), 'y'=>($y + ($table['border_spacing_V']/2)), 'w'=>($w - $table['border_spacing_H']), 'h'=>($h - $table['border_spacing_V']), 'col'=>$color);
11593 }
11594 }
11595 else {
11596 if ($this->ColActive) {
11597 $this->SetFColor($color);
11598 $this->Rect($x, $y, $w, $h, 'F');
11599 }
11600 else {
11601 $this->tableBackgrounds[$level*9+$leveladj][] = array('gradient'=>false, 'x'=>$x, 'y'=>$y, 'w'=>$w, 'h'=>$h, 'col'=>$color);
11602 }
11603 }
11604 }
11605 }
11606
11607
11608 /*-- BACKGROUNDS --*/
11609 if (isset($tablehf['gradient']) && $tablehf['gradient'] && $paintcell){
11610 $g = $this->grad->parseBackgroundGradient($tablehf['gradient']);
11611 if ($g) {
11612 if ($table['borders_separate']) {
11613 $px = $x+ ($table['border_spacing_H']/2);
11614 $py = $y+ ($table['border_spacing_V']/2);
11615 $pw = $w- $table['border_spacing_H'];
11616 $ph = $h- $table['border_spacing_V'];
11617 }
11618 else {
11619 $px = $x;
11620 $py = $y;
11621 $pw = $w;
11622 $ph = $h;
11623 }
11624 if ($this->ColActive) {
11625 $this->grad->Gradient($px, $py, $pw, $ph, $g['type'], $g['stops'], $g['colorspace'], $g['coords'], $g['extend']);
11626 }
11627 else {
11628 $this->tableBackgrounds[$level*9+7][] = array('gradient'=>true, 'x'=>$px, 'y'=>$py, 'w'=>$pw, 'h'=>$ph, 'gradtype'=>$g['type'], 'stops'=>$g['stops'], 'colorspace'=>$g['colorspace'], 'coords'=>$g['coords'], 'extend'=>$g['extend'], 'clippath'=>'');
11629 }
11630 }
11631 }
11632
11633 if (isset($tablehf['background-image']) && $paintcell){
11634 if ($tablehf['background-image']['gradient'] && preg_match('/(-moz-)*(repeating-)*(linear|radial)-gradient/', $tablehf['background-image']['gradient'] )) {
11635 $g = $this->grad->parseMozGradient( $tablehf['background-image']['gradient'] );
11636 if ($g) {
11637 if ($table['borders_separate']) {
11638 $px = $x+ ($table['border_spacing_H']/2);
11639 $py = $y+ ($table['border_spacing_V']/2);
11640 $pw = $w- $table['border_spacing_H'];
11641 $ph = $h- $table['border_spacing_V'];
11642 }
11643 else {
11644 $px = $x;
11645 $py = $y;
11646 $pw = $w;
11647 $ph = $h;
11648 }
11649 if ($this->ColActive) {
11650 $this->grad->Gradient($px, $py, $pw, $ph, $g['type'], $g['stops'], $g['colorspace'], $g['coords'], $g['extend']);
11651 }
11652 else {
11653 $this->tableBackgrounds[$level*9+7][] = array('gradient'=>true, 'x'=>$px, 'y'=>$py, 'w'=>$pw, 'h'=>$ph, 'gradtype'=>$g['type'], 'stops'=>$g['stops'], 'colorspace'=>$g['colorspace'], 'coords'=>$g['coords'], 'extend'=>$g['extend'], 'clippath'=>'');
11654 }
11655 }
11656 }
11657 else if ($tablehf['background-image']['image_id']) { // Background pattern
11658 $n = count($this->patterns)+1;
11659 if ($table['borders_separate']) {
11660 $px = $x+ ($table['border_spacing_H']/2);
11661 $py = $y+ ($table['border_spacing_V']/2);
11662 $pw = $w- $table['border_spacing_H'];
11663 $ph = $h- $table['border_spacing_V'];
11664 }
11665 else {
11666 $px = $x;
11667 $py = $y;
11668 $pw = $w;
11669 $ph = $h;
11670 }
11671 if ($this->ColActive) {
11672 list($orig_w, $orig_h, $x_repeat, $y_repeat) = $this->_resizeBackgroundImage($tablehf['background-image']['orig_w'], $tablehf['background-image']['orig_h'], $pw, $ph, $tablehf['background-image']['resize'], $tablehf['background-image']['x_repeat'] , $tablehf['background-image']['y_repeat']);
11673 $this->patterns[$n] = array('x'=>$px, 'y'=>$py, 'w'=>$pw, 'h'=>$ph, 'pgh'=>$this->h, 'image_id'=>$tablehf['background-image']['image_id'], 'orig_w'=>$orig_w, 'orig_h'=>$orig_h, 'x_pos'=>$tablehf['background-image']['x_pos'] , 'y_pos'=>$tablehf['background-image']['y_pos'] , 'x_repeat'=>$x_repeat, 'y_repeat'=>$y_repeat, 'itype'=>$tablehf['background-image']['itype']);
11674 if ($tablehf['background-image']['opacity']>0 && $tablehf['background-image']['opacity']<1) { $opac = $this->SetAlpha($tablehf['background-image']['opacity'],'Normal',true); }
11675 else { $opac = ''; }
11676 $this->_out(sprintf('q /Pattern cs /P%d scn %s %.3F %.3F %.3F %.3F re f Q', $n, $opac, $px*_MPDFK, ($this->h-$py)*_MPDFK, $pw*_MPDFK, -$ph*_MPDFK));
11677 }
11678 else {
11679 $this->tableBackgrounds[$level*9+8][] = array('x'=>$px, 'y'=>$py, 'w'=>$pw, 'h'=>$ph, 'image_id'=>$tablehf['background-image']['image_id'], 'orig_w'=>$tablehf['background-image']['orig_w'], 'orig_h'=>$tablehf['background-image']['orig_h'], 'x_pos'=>$tablehf['background-image']['x_pos'], 'y_pos'=>$tablehf['background-image']['y_pos'], 'x_repeat'=>$tablehf['background-image']['x_repeat'], 'y_repeat'=>$tablehf['background-image']['y_repeat'], 'clippath'=>'', 'resize'=>$tablehf['background-image']['resize'], 'opacity'=>$tablehf['background-image']['opacity'], 'itype'=>$tablehf['background-image']['itype']);
11680 }
11681 }
11682 }
11683 /*-- END BACKGROUNDS --*/
11684
11685 //Cell Border
11686 if ($table['borders_separate'] && $paintcell && $border) {
11687 $this->_tableRect($x+ ($table['border_spacing_H']/2)+($border_details['L']['w'] /2), $y+ ($table['border_spacing_V']/2)+($border_details['T']['w'] /2), $w-$table['border_spacing_H']-($border_details['L']['w'] /2)-($border_details['R']['w'] /2), $h- $table['border_spacing_V']-($border_details['T']['w'] /2)-($border_details['B']['w']/2), $border, $border_details, false, $table['borders_separate']);
11688 }
11689 else if ($paintcell && $border) {
11690 $this->_tableRect($x, $y, $w, $h, $border, $border_details, true, $table['borders_separate']); // true causes buffer
11691 }
11692
11693 //Print cell content
11694 //$this->divheight = $this->table_lineheight*$this->lineheight;
11695 if (!empty($textbuffer)) {
11696 if ($horf=='F' && preg_match('/{colsum([0-9]*)[_]*}/', $textbuffer[0][0], $m)) {
11697 $rep = sprintf("%01.".intval($m[1])."f", $this->colsums[$colctr-1]);
11698 $textbuffer[0][0] = preg_replace('/{colsum[0-9_]*}/', $rep ,$textbuffer[0][0]);
11699 }
11700
11701 if ($R) {
11702 $cellPtSize = $textbuffer[0][11] / $this->shrin_k;
11703 if (!$cellPtSize) { $cellPtSize = $this->default_font_size; }
11704 $cellFontHeight = ($cellPtSize/_MPDFK);
11705 $opx = $this->x;
11706 $opy = $this->y;
11707 $angle = INTVAL($R);
11708 // Only allow 45 - 90 degrees (when bottom-aligned) or -90
11709 if ($angle > 90) { $angle = 90; }
11710 else if ($angle > 0 && (isset($va) && $va!='B')) { $angle = 90; }
11711 else if ($angle > 0 && $angle <45) { $angle = 45; }
11712 else if ($angle < 0) { $angle = -90; }
11713 $offset = ((sin(deg2rad($angle))) * 0.37 * $cellFontHeight);
11714 if (isset($align) && $align =='R') {
11715 $this->x += ($w) + ($offset) - ($cellFontHeight/3) - ($padding['R'] + $border_details['R']['w']);
11716 }
11717 else if (!isset($align ) || $align =='C') {
11718 $this->x += ($w/2) + ($offset);
11719 }
11720 else {
11721 $this->x += ($offset) + ($cellFontHeight/3)+($padding['L'] + $border_details['L']['w']);
11722 }
11723 $str = '';
11724 foreach($tablehf['textbuffer'] AS $t) { $str .= $t[0].' '; }
11725 $str = trim($str);
11726
11727 if (!isset($va) || $va=='M') {
11728 $this->y -= ($h-$mih)/2; //Undo what was added earlier VERTICAL ALIGN
11729 if ($angle > 0) { $this->y += (($h-$mih)/2)+($padding['T'] + $border_details['T']['w']) + ($mih-($padding['T'] + $border_details['T']['w']+$border_details['B']['w']+$padding['B'])); }
11730 else if ($angle < 0) { $this->y += (($h-$mih)/2)+($padding['T'] + $border_details['T']['w']); }
11731 }
11732 else if (isset($va) && $va=='B') {
11733 $this->y -= $h-$mih; //Undo what was added earlier VERTICAL ALIGN
11734 if ($angle > 0) { $this->y += $h-($border_details['B']['w']+$padding['B']); }
11735 else if ($angle < 0) { $this->y += $h-$mih+($padding['T'] + $border_details['T']['w']); }
11736 }
11737 else if (isset($va) && $va=='T') {
11738 if ($angle > 0) { $this->y += $mih-($border_details['B']['w']+$padding['B']); }
11739 else if ($angle < 0) { $this->y += ($padding['T'] + $border_details['T']['w']); }
11740 }
11741
11742 $this->Rotate($angle,$this->x,$this->y);
11743 $s_fs = $this->FontSizePt;
11744 $s_f = $this->FontFamily;
11745 $s_st = $this->FontStyle;
11746 if (!empty($textbuffer[0][3])) { //Font Color
11747 $cor = $textbuffer[0][3];
11748 $this->SetTColor($cor);
11749 }
11750 $s_str = $this->strike;
11751 $this->strike = $textbuffer[0][8]; //Strikethrough
11752 $this->SetFont($textbuffer[0][4],$textbuffer[0][2],$cellPtSize,true,true);
11753 $this->Text($this->x,$this->y,$str);
11754 $this->Rotate(0);
11755 $this->SetFont($s_f,$s_st,$s_fs,true,true);
11756 $this->SetTColor(0);
11757 $this->strike = $s_str;
11758 $this->x = $opx;
11759 $this->y = $opy;
11760 }
11761 else {
11762 if ($table['borders_separate']) { // NB twice border width
11763 $xadj = $border_details['L']['w'] + $padding['L'] +($table['border_spacing_H']/2);
11764 $wadj = $border_details['L']['w'] + $border_details['R']['w'] + $padding['L'] +$padding['R'] + $table['border_spacing_H'];
11765 $yadj = $border_details['T']['w'] + $padding['T'] + ($table['border_spacing_H']/2);
11766 }
11767 else {
11768 $xadj = $border_details['L']['w']/2 + $padding['L'];
11769 $wadj = ($border_details['L']['w'] + $border_details['R']['w'])/2 + $padding['L'] + $padding['R'];
11770 $yadj = $border_details['T']['w']/2 + $padding['T'];
11771 }
11772
11773 $this->divwidth=$w-($wadj);
11774 $this->x += $xadj;
11775 $this->y += $yadj;
11776 $this->printbuffer($textbuffer,'',true);
11777 }
11778
11779 }
11780 $textbuffer = array();
11781
11782 /*-- BACKGROUNDS --*/
11783 if (!$this->ColActive) {
11784 if (isset($content[$i][0]['trgradients']) && ($colctr==1 || $table['borders_separate'])) {
11785 $g = $this->grad->parseBackgroundGradient($content[$i][0]['trgradients']);
11786 if ($g) {
11787 $gx = $x0;
11788 $gy = $y;
11789 $gh = $h;
11790 $gw = $table['w'] - ($table['max_cell_border_width']['L']/2) - ($table['max_cell_border_width']['R']/2) - $table['margin']['L'] - $table['margin']['R'];
11791 if ($table['borders_separate']) {
11792 $gw -= ($table['padding']['L'] + $table['border_details']['L']['w'] + $table['padding']['R'] + $table['border_details']['R']['w'] + $table['border_spacing_H']);
11793 $s = '';
11794 $clx = $x+ ($table['border_spacing_H']/2);
11795 $cly = $y+ ($table['border_spacing_V']/2);
11796 $clw = $w- $table['border_spacing_H'];
11797 $clh = $h- $table['border_spacing_V'];
11798 // Set clipping path
11799 $s = ' q 0 w '; // Line width=0
11800 $s .= sprintf('%.3F %.3F m ', ($clx)*_MPDFK, ($this->h-($cly))*_MPDFK); // start point TL before the arc
11801 $s .= sprintf('%.3F %.3F l ', ($clx)*_MPDFK, ($this->h-($cly+$clh))*_MPDFK); // line to BL
11802 $s .= sprintf('%.3F %.3F l ', ($clx+$clw)*_MPDFK, ($this->h-($cly+$clh))*_MPDFK); // line to BR
11803 $s .= sprintf('%.3F %.3F l ', ($clx+$clw)*_MPDFK, ($this->h-($cly))*_MPDFK); // line to TR
11804 $s .= sprintf('%.3F %.3F l ', ($clx)*_MPDFK, ($this->h-($cly))*_MPDFK); // line to TL
11805 $s .= ' W n '; // Ends path no-op & Sets the clipping path
11806 $this->tableBackgrounds[$level*9+4][] = array('gradient'=>true, 'x'=>$gx + ($table['border_spacing_H']/2), 'y'=>$gy + ($table['border_spacing_V']/2), 'w'=>$gw - $table['border_spacing_V'], 'h'=>$gh - $table['border_spacing_H'], 'gradtype'=>$g['type'], 'stops'=>$g['stops'], 'colorspace'=>$g['colorspace'], 'coords'=>$g['coords'], 'extend'=>$g['extend'], 'clippath'=>$s);
11807 }
11808 else {
11809 $this->tableBackgrounds[$level*9+4][] = array('gradient'=>true, 'x'=>$gx, 'y'=>$gy, 'w'=>$gw, 'h'=>$gh, 'gradtype'=>$g['type'], 'stops'=>$g['stops'], 'colorspace'=>$g['colorspace'], 'coords'=>$g['coords'], 'extend'=>$g['extend'], 'clippath'=>'');
11810 }
11811 }
11812 }
11813
11814 if (isset($content[$i][0]['trbackground-images']) && ($colctr==1 || $table['borders_separate'])) {
11815 if ($content[$i][0]['trbackground-images']['gradient'] && preg_match('/(-moz-)*(repeating-)*(linear|radial)-gradient/', $content[$i][0]['trbackground-images']['gradient'] )) {
11816 $g = $this->grad->parseMozGradient( $content[$i][0]['trbackground-images']['gradient'] );
11817 if ($g) {
11818 $gx = $x0;
11819 $gy = $y;
11820 $gh = $h;
11821 $gw = $table['w'] - ($table['max_cell_border_width']['L']/2) - ($table['max_cell_border_width']['R']/2) - $table['margin']['L'] - $table['margin']['R'];
11822 if ($table['borders_separate']) {
11823 $gw -= ($table['padding']['L'] + $table['border_details']['L']['w'] + $table['padding']['R'] + $table['border_details']['R']['w'] + $table['border_spacing_H']);
11824 $s = '';
11825 $clx = $x+ ($table['border_spacing_H']/2);
11826 $cly = $y+ ($table['border_spacing_V']/2);
11827 $clw = $w- $table['border_spacing_H'];
11828 $clh = $h- $table['border_spacing_V'];
11829 // Set clipping path
11830 $s = ' q 0 w '; // Line width=0
11831 $s .= sprintf('%.3F %.3F m ', ($clx)*_MPDFK, ($this->h-($cly))*_MPDFK); // start point TL before the arc
11832 $s .= sprintf('%.3F %.3F l ', ($clx)*_MPDFK, ($this->h-($cly+$clh))*_MPDFK); // line to BL
11833 $s .= sprintf('%.3F %.3F l ', ($clx+$clw)*_MPDFK, ($this->h-($cly+$clh))*_MPDFK); // line to BR
11834 $s .= sprintf('%.3F %.3F l ', ($clx+$clw)*_MPDFK, ($this->h-($cly))*_MPDFK); // line to TR
11835 $s .= sprintf('%.3F %.3F l ', ($clx)*_MPDFK, ($this->h-($cly))*_MPDFK); // line to TL
11836 $s .= ' W n '; // Ends path no-op & Sets the clipping path
11837 $this->tableBackgrounds[$level*9+4][] = array('gradient'=>true, 'x'=>$gx + ($table['border_spacing_H']/2), 'y'=>$gy + ($table['border_spacing_V']/2), 'w'=>$gw - $table['border_spacing_V'], 'h'=>$gh - $table['border_spacing_H'], 'gradtype'=>$g['type'], 'stops'=>$g['stops'], 'colorspace'=>$g['colorspace'], 'coords'=>$g['coords'], 'extend'=>$g['extend'], 'clippath'=>$s);
11838 }
11839 else {
11840 $this->tableBackgrounds[$level*9+4][] = array('gradient'=>true, 'x'=>$gx, 'y'=>$gy, 'w'=>$gw, 'h'=>$gh, 'gradtype'=>$g['type'], 'stops'=>$g['stops'], 'colorspace'=>$g['colorspace'], 'coords'=>$g['coords'], 'extend'=>$g['extend'], 'clippath'=>'');
11841 }
11842 }
11843 }
11844 else {
11845 $image_id = $content[$i][0]['trbackground-images']['image_id'];
11846 $orig_w = $content[$i][0]['trbackground-images']['orig_w'];
11847 $orig_h = $content[$i][0]['trbackground-images']['orig_h'];
11848 $x_pos = $content[$i][0]['trbackground-images']['x_pos'];
11849 $y_pos = $content[$i][0]['trbackground-images']['y_pos'];
11850 $x_repeat = $content[$i][0]['trbackground-images']['x_repeat'];
11851 $y_repeat = $content[$i][0]['trbackground-images']['y_repeat'];
11852 $resize = $content[$i][0]['trbackground-images']['resize'];
11853 $opacity = $content[$i][0]['trbackground-images']['opacity'];
11854 $itype = $content[$i][0]['trbackground-images']['itype'];
11855
11856 $clippath = '';
11857 $gx = $x0;
11858 $gy = $y;
11859 $gh = $h;
11860 $gw = $table['w'] - ($table['max_cell_border_width']['L']/2) - ($table['max_cell_border_width']['R']/2) - $table['margin']['L'] - $table['margin']['R'];
11861 if ($table['borders_separate']) {
11862 $gw -= ($table['padding']['L'] + $table['border_details']['L']['w'] + $table['padding']['R'] + $table['border_details']['R']['w'] + $table['border_spacing_H']);
11863 $s = '';
11864 $clx = $x+ ($table['border_spacing_H']/2);
11865 $cly = $y+ ($table['border_spacing_V']/2);
11866 $clw = $w- $table['border_spacing_H'];
11867 $clh = $h- $table['border_spacing_V'];
11868 // Set clipping path
11869 $s = ' q 0 w '; // Line width=0
11870 $s .= sprintf('%.3F %.3F m ', ($clx)*_MPDFK, ($this->h-($cly))*_MPDFK); // start point TL before the arc
11871 $s .= sprintf('%.3F %.3F l ', ($clx)*_MPDFK, ($this->h-($cly+$clh))*_MPDFK); // line to BL
11872 $s .= sprintf('%.3F %.3F l ', ($clx+$clw)*_MPDFK, ($this->h-($cly+$clh))*_MPDFK); // line to BR
11873 $s .= sprintf('%.3F %.3F l ', ($clx+$clw)*_MPDFK, ($this->h-($cly))*_MPDFK); // line to TR
11874 $s .= sprintf('%.3F %.3F l ', ($clx)*_MPDFK, ($this->h-($cly))*_MPDFK); // line to TL
11875 $s .= ' W n '; // Ends path no-op & Sets the clipping path
11876 $this->tableBackgrounds[$level*9+5][] = array('x'=>$gx + ($table['border_spacing_H']/2), 'y'=>$gy + ($table['border_spacing_V']/2), 'w'=>$gw - $table['border_spacing_V'], 'h'=>$gh - $table['border_spacing_H'], 'image_id'=>$image_id, 'orig_w'=>$orig_w, 'orig_h'=>$orig_h, 'x_pos'=>$x_pos, 'y_pos'=>$y_pos, 'x_repeat'=>$x_repeat, 'y_repeat'=>$y_repeat, 'clippath'=>$s, 'resize'=>$resize, 'opacity'=>$opacity, 'itype'=>$itype);
11877 }
11878 else {
11879 $this->tableBackgrounds[$level*9+5][] = array('x'=>$gx, 'y'=>$gy, 'w'=>$gw, 'h'=>$gh, 'image_id'=>$image_id, 'orig_w'=>$orig_w, 'orig_h'=>$orig_h, 'x_pos'=>$x_pos, 'y_pos'=>$y_pos, 'x_repeat'=>$x_repeat, 'y_repeat'=>$y_repeat, 'clippath'=>'', 'resize'=>$resize, 'opacity'=>$opacity, 'itype'=>$itype);
11880 }
11881 }
11882 }
11883 }
11884 /*-- END BACKGROUNDS --*/
11885
11886 // TABLE BORDER - if separate OR collapsed and only table border
11887 if (($table['borders_separate'] || ($this->simpleTables && !$table['simple']['border'])) && $table['border']) {
11888 $halfspaceL = $table['padding']['L'] + ($table['border_spacing_H']/2);
11889 $halfspaceR = $table['padding']['R'] + ($table['border_spacing_H']/2);
11890 $halfspaceT = $table['padding']['T'] + ($table['border_spacing_V']/2);
11891 $halfspaceB = $table['padding']['B'] + ($table['border_spacing_V']/2);
11892 $tbx = $x;
11893 $tby = $y;
11894 $tbw = $w;
11895 $tbh = $h;
11896 $tab_bord = 0;
11897 $corner = '';
11898 if ($i == $firstrow && $horf=='H') { // Top
11899 $tby -= $halfspaceT + ($table['border_details']['T']['w']/2);
11900 $tbh += $halfspaceT + ($table['border_details']['T']['w']/2);
11901 $this->setBorder($tab_bord , _BORDER_TOP);
11902 $corner .= 'T';
11903 }
11904 if (($i == ($lastrow) || (isset($tablehf['rowspan']) && ($i+$tablehf['rowspan']) == ($lastrow+1))) && $horf=='F') { // Bottom
11905 $tbh += $halfspaceB + ($table['border_details']['B']['w']/2);
11906 $this->setBorder($tab_bord , _BORDER_BOTTOM);
11907 $corner .= 'B';
11908 }
11909 if ($colctr == 1 && $firstSpread) { // Left
11910 $tbx -= $halfspaceL + ($table['border_details']['L']['w']/2);
11911 $tbw += $halfspaceL + ($table['border_details']['L']['w']/2);
11912 $this->setBorder($tab_bord , _BORDER_LEFT);
11913 $corner .= 'L';
11914 }
11915 if ($colctr == count($content[$i]) && $finalSpread) { // Right
11916 $tbw += $halfspaceR + ($table['border_details']['R']['w']/2);
11917 $this->setBorder($tab_bord , _BORDER_RIGHT);
11918 $corner .= 'R';
11919 }
11920 $this->_tableRect($tbx, $tby, $tbw, $tbh, $tab_bord , $table['border_details'], false, $table['borders_separate'], 'table', $corner, $table['border_spacing_V'], $table['border_spacing_H'] );
11921 }
11922
11923
11924 }// end column $content
11925 $this->y = $y + $h; //Update y coordinate
11926 }// end row $i
11927 unset($table );
11928 $this->colsums = array();
11929 }
11930 }
11931 /*-- END TABLES --*/
11932
11933 /*-- HTMLHEADERS-FOOTERS --*/
11934 function SetHTMLHeader($header='',$OE='',$write=false) {
11935
11936 $height = 0;
11937 if (is_array($header) && isset($header['html']) && $header['html']) {
11938 $Hhtml = $header['html'];
11939 if ($this->setAutoTopMargin) {
11940 if (isset($header['h'])) { $height = $header['h']; }
11941 else { $height = $this->_gethtmlheight($Hhtml); }
11942 }
11943 }
11944 else if (!is_array($header) && $header) {
11945 $Hhtml = $header;
11946 if ($this->setAutoTopMargin) { $height = $this->_gethtmlheight($Hhtml); }
11947 }
11948 else { $Hhtml = ''; }
11949
11950 if ($OE != 'E') { $OE = 'O'; }
11951 if ($OE == 'E') {
11952
11953 if ($Hhtml) {
11954 $this->HTMLHeaderE['html'] = $Hhtml;
11955 $this->HTMLHeaderE['h'] = $height;
11956 }
11957 else { $this->HTMLHeaderE = ''; }
11958 }
11959 else {
11960
11961 if ($Hhtml) {
11962 $this->HTMLHeader['html'] = $Hhtml;
11963 $this->HTMLHeader['h'] = $height;
11964 }
11965 else { $this->HTMLHeader = ''; }
11966 }
11967 if (!$this->mirrorMargins && $OE == 'E') { return; }
11968 if ($Hhtml=='') { return; }
11969 if ($OE == 'E') {
11970 $this->headerDetails['even'] = array(); // override and clear any other non-HTML header/footer
11971 }
11972 else {
11973 $this->headerDetails['odd'] = array(); // override and clear any non-HTML other header/footer
11974 }
11975
11976 if ($this->setAutoTopMargin=='pad') {
11977 $this->tMargin = $this->margin_header + $height + $this->orig_tMargin;
11978 if (isset($this->saveHTMLHeader[$this->page][$OE]['mt'])) { $this->saveHTMLHeader[$this->page][$OE]['mt'] = $this->tMargin; }
11979 }
11980 else if ($this->setAutoTopMargin=='stretch') {
11981 $this->tMargin = max($this->orig_tMargin, $this->margin_header + $height + $this->autoMarginPadding);
11982 if (isset($this->saveHTMLHeader[$this->page][$OE]['mt'])) { $this->saveHTMLHeader[$this->page][$OE]['mt'] = $this->tMargin; }
11983 }
11984 if ($write && $this->state!=0 && (($this->mirrorMargins && $OE == 'E' && ($this->page)%2==0) || ($this->mirrorMargins && $OE != 'E' && ($this->page)%2==1) || !$this->mirrorMargins)) { $this->writeHTMLHeaders(); }
11985 }
11986
11987 function SetHTMLFooter($footer='',$OE='') {
11988
11989 $height = 0;
11990 if (is_array($footer) && isset($footer['html']) && $footer['html']) {
11991 $Fhtml = $footer['html'];
11992 if ($this->setAutoBottomMargin) {
11993 if (isset($footer['h'])) { $height = $footer['h']; }
11994 else { $height = $this->_gethtmlheight($Fhtml); }
11995 }
11996 }
11997 else if (!is_array($footer) && $footer) {
11998 $Fhtml = $footer;
11999 if ($this->setAutoBottomMargin) { $height = $this->_gethtmlheight($Fhtml); }
12000 }
12001 else { $Fhtml = ''; }
12002
12003 if ($OE != 'E') { $OE = 'O'; }
12004 if ($OE == 'E') {
12005
12006 if ($Fhtml) {
12007 $this->HTMLFooterE['html'] = $Fhtml;
12008 $this->HTMLFooterE['h'] = $height;
12009 }
12010 else { $this->HTMLFooterE = ''; }
12011 }
12012 else {
12013
12014 if ($Fhtml) {
12015 $this->HTMLFooter['html'] = $Fhtml;
12016 $this->HTMLFooter['h'] = $height;
12017 }
12018 else { $this->HTMLFooter = ''; }
12019 }
12020 if (!$this->mirrorMargins && $OE == 'E') { return; }
12021 if ($Fhtml=='') { return false; }
12022 if ($OE == 'E') {
12023 $this->footerDetails['even'] = array(); // override and clear any other header/footer
12024 }
12025 else {
12026 $this->footerDetails['odd'] = array(); // override and clear any other header/footer
12027 }
12028
12029 if ($this->setAutoBottomMargin=='pad') {
12030 $this->bMargin = $this->margin_footer + $height + $this->orig_bMargin;
12031 $this->PageBreakTrigger=$this->h-$this->bMargin ;
12032 if (isset($this->saveHTMLHeader[$this->page][$OE]['mb'])) { $this->saveHTMLHeader[$this->page][$OE]['mb'] = $this->bMargin; }
12033 }
12034 else if ($this->setAutoBottomMargin=='stretch') {
12035 $this->bMargin = max($this->orig_bMargin, $this->margin_footer + $height + $this->autoMarginPadding);
12036 $this->PageBreakTrigger=$this->h-$this->bMargin ;
12037 if (isset($this->saveHTMLHeader[$this->page][$OE]['mb'])) { $this->saveHTMLHeader[$this->page][$OE]['mb'] = $this->bMargin; }
12038 }
12039 }
12040
12041
12042 function _getHtmlHeight($html) {
12043 $save_state = $this->state;
12044 if($this->state==0) {
12045 $this->AddPage($this->CurOrientation);
12046 }
12047 $this->state = 2;
12048 $this->Reset();
12049 $this->pageoutput[$this->page] = array();
12050 $save_x = $this->x;
12051 $save_y = $this->y;
12052 $this->x = $this->lMargin;
12053 $this->y = $this->margin_header;
12054 $html = str_replace('{PAGENO}',$this->pagenumPrefix.$this->docPageNum($this->page).$this->pagenumSuffix,$html);
12055 $html = str_replace($this->aliasNbPgGp,$this->nbpgPrefix.$this->docPageNumTotal($this->page).$this->nbpgSuffix,$html );
12056 $html = str_replace($this->aliasNbPg,$this->page,$html );
12057 $html = preg_replace('/\{DATE\s+(.*?)\}/e',"date('\\1')",$html );
12058 $this->HTMLheaderPageLinks = array();
12059 $this->HTMLheaderPageAnnots = array();
12060 $this->HTMLheaderPageForms = array();
12061 $savepb = $this->pageBackgrounds;
12062 $this->writingHTMLheader = true;
12063 $this->WriteHTML($html , 4); // parameter 4 saves output to $this->headerbuffer
12064 $this->writingHTMLheader = false;
12065 $h = ($this->y - $this->margin_header);
12066 $this->Reset();
12067 $this->pageoutput[$this->page] = array();
12068 $this->headerbuffer = '';
12069 $this->pageBackgrounds = $savepb;
12070 $this->x = $save_x;
12071 $this->y = $save_y;
12072 $this->state = $save_state;
12073 if($save_state==0) {
12074 unset($this->pages[1]);
12075 $this->page = 0;
12076 }
12077 return $h;
12078 }
12079
12080
12081 // Called internally from Header
12082 function writeHTMLHeaders() {
12083
12084 if ($this->mirrorMargins && ($this->page)%2==0) { $OE = 'E'; } // EVEN
12085 else { $OE = 'O'; }
12086 if ($OE == 'E') {
12087 $this->saveHTMLHeader[$this->page][$OE]['html'] = $this->HTMLHeaderE['html'] ;
12088 }
12089 else {
12090 $this->saveHTMLHeader[$this->page][$OE]['html'] = $this->HTMLHeader['html'] ;
12091 }
12092 if ($this->forcePortraitHeaders && $this->CurOrientation=='L' && $this->CurOrientation!=$this->DefOrientation) {
12093 $this->saveHTMLHeader[$this->page][$OE]['rotate'] = true;
12094 $this->saveHTMLHeader[$this->page][$OE]['ml'] = $this->tMargin;
12095 $this->saveHTMLHeader[$this->page][$OE]['mr'] = $this->bMargin;
12096 $this->saveHTMLHeader[$this->page][$OE]['mh'] = $this->margin_header;
12097 $this->saveHTMLHeader[$this->page][$OE]['mf'] = $this->margin_footer;
12098 $this->saveHTMLHeader[$this->page][$OE]['pw'] = $this->h;
12099 $this->saveHTMLHeader[$this->page][$OE]['ph'] = $this->w;
12100 }
12101 else {
12102 $this->saveHTMLHeader[$this->page][$OE]['ml'] = $this->lMargin;
12103 $this->saveHTMLHeader[$this->page][$OE]['mr'] = $this->rMargin;
12104 $this->saveHTMLHeader[$this->page][$OE]['mh'] = $this->margin_header;
12105 $this->saveHTMLHeader[$this->page][$OE]['mf'] = $this->margin_footer;
12106 $this->saveHTMLHeader[$this->page][$OE]['pw'] = $this->w;
12107 $this->saveHTMLHeader[$this->page][$OE]['ph'] = $this->h;
12108 }
12109 }
12110
12111 function writeHTMLFooters() {
12112
12113 if ($this->mirrorMargins && ($this->page)%2==0) { $OE = 'E'; } // EVEN
12114 else { $OE = 'O'; }
12115 if ($OE == 'E') {
12116 $this->saveHTMLFooter[$this->page][$OE]['html'] = $this->HTMLFooterE['html'] ;
12117 }
12118 else {
12119 $this->saveHTMLFooter[$this->page][$OE]['html'] = $this->HTMLFooter['html'] ;
12120 }
12121 if ($this->forcePortraitHeaders && $this->CurOrientation=='L' && $this->CurOrientation!=$this->DefOrientation) {
12122 $this->saveHTMLFooter[$this->page][$OE]['rotate'] = true;
12123 $this->saveHTMLFooter[$this->page][$OE]['ml'] = $this->tMargin;
12124 $this->saveHTMLFooter[$this->page][$OE]['mr'] = $this->bMargin;
12125 $this->saveHTMLFooter[$this->page][$OE]['mt'] = $this->rMargin;
12126 $this->saveHTMLFooter[$this->page][$OE]['mb'] = $this->lMargin;
12127 $this->saveHTMLFooter[$this->page][$OE]['mh'] = $this->margin_header;
12128 $this->saveHTMLFooter[$this->page][$OE]['mf'] = $this->margin_footer;
12129 $this->saveHTMLFooter[$this->page][$OE]['pw'] = $this->h;
12130 $this->saveHTMLFooter[$this->page][$OE]['ph'] = $this->w;
12131 }
12132 else {
12133 $this->saveHTMLFooter[$this->page][$OE]['ml'] = $this->lMargin;
12134 $this->saveHTMLFooter[$this->page][$OE]['mr'] = $this->rMargin;
12135 $this->saveHTMLFooter[$this->page][$OE]['mt'] = $this->tMargin;
12136 $this->saveHTMLFooter[$this->page][$OE]['mb'] = $this->bMargin;
12137 $this->saveHTMLFooter[$this->page][$OE]['mh'] = $this->margin_header;
12138 $this->saveHTMLFooter[$this->page][$OE]['mf'] = $this->margin_footer;
12139 $this->saveHTMLFooter[$this->page][$OE]['pw'] = $this->w;
12140 $this->saveHTMLFooter[$this->page][$OE]['ph'] = $this->h;
12141 }
12142 }
12143 /*-- END HTMLHEADERS-FOOTERS --*/
12144
12145 function DefHeaderByName($name,$arr) {
12146 if (!$name) { $name = '_default'; }
12147 $this->pageheaders[$name] = $arr;
12148 }
12149
12150 function DefFooterByName($name,$arr) {
12151 if (!$name) { $name = '_default'; }
12152 $this->pagefooters[$name] = $arr;
12153 }
12154
12155 function SetHeaderByName($name,$side='O',$write=false) {
12156 if (!$name) { $name = '_default'; }
12157 if ($side=='E') { $this->headerDetails['even'] = $this->pageheaders[$name]; }
12158 else { $this->headerDetails['odd'] = $this->pageheaders[$name]; }
12159 if ($write) { $this->Header(); }
12160 }
12161
12162 function SetFooterByName($name,$side='O') {
12163 if (!$name) { $name = '_default'; }
12164 if ($side=='E') { $this->footerDetails['even'] = $this->pagefooters[$name]; }
12165 else { $this->footerDetails['odd'] = $this->pagefooters[$name]; }
12166 }
12167
12168 /*-- HTMLHEADERS-FOOTERS --*/
12169 function DefHTMLHeaderByName($name,$html) {
12170 if (!$name) { $name = '_default'; }
12171
12172 $this->pageHTMLheaders[$name]['html'] = $html;
12173 $this->pageHTMLheaders[$name]['h'] = $this->_gethtmlheight($html);
12174 }
12175
12176 function DefHTMLFooterByName($name,$html) {
12177 if (!$name) { $name = '_default'; }
12178
12179 $this->pageHTMLfooters[$name]['html'] = $html;
12180 $this->pageHTMLfooters[$name]['h'] = $this->_gethtmlheight($html);
12181 }
12182
12183 function SetHTMLHeaderByName($name,$side='O',$write=false) {
12184 if (!$name) { $name = '_default'; }
12185 $this->SetHTMLHeader($this->pageHTMLheaders[$name],$side,$write);
12186 }
12187
12188 function SetHTMLFooterByName($name,$side='O') {
12189 if (!$name) { $name = '_default'; }
12190 $this->SetHTMLFooter($this->pageHTMLfooters[$name],$side,$write);
12191 }
12192 /*-- END HTMLHEADERS-FOOTERS --*/
12193
12194
12195 function SetHeader($Harray=array(),$side='',$write=false) {
12196 if (is_string($Harray)) {
12197 if (strlen($Harray)==0) {
12198 if ($side=='O') { $this->headerDetails['odd'] = array(); }
12199 else if ($side=='E') { $this->headerDetails['even'] = array(); }
12200 else { $this->headerDetails = array(); }
12201 }
12202 else if (strpos($Harray,'|') || strpos($Harray,'|')===0) {
12203 $hdet = explode('|',$Harray);
12204 $this->headerDetails = array (
12205 'odd' => array (
12206 'L' => array ('content' => $hdet[0], 'font-size' => $this->defaultheaderfontsize, 'font-style' => $this->defaultheaderfontstyle),
12207 'C' => array ('content' => $hdet[1], 'font-size' => $this->defaultheaderfontsize, 'font-style' => $this->defaultheaderfontstyle),
12208 'R' => array ('content' => $hdet[2], 'font-size' => $this->defaultheaderfontsize, 'font-style' => $this->defaultheaderfontstyle),
12209 'line' => $this->defaultheaderline,
12210 ),
12211 'even' => array (
12212 'R' => array ('content' => $hdet[0], 'font-size' => $this->defaultheaderfontsize, 'font-style' => $this->defaultheaderfontstyle),
12213 'C' => array ('content' => $hdet[1], 'font-size' => $this->defaultheaderfontsize, 'font-style' => $this->defaultheaderfontstyle),
12214 'L' => array ('content' => $hdet[2], 'font-size' => $this->defaultheaderfontsize, 'font-style' => $this->defaultheaderfontstyle),
12215 'line' => $this->defaultheaderline,
12216 )
12217 );
12218 }
12219 else {
12220 $this->headerDetails = array (
12221 'odd' => array (
12222 'R' => array ('content' => $Harray, 'font-size' => $this->defaultheaderfontsize, 'font-style' => $this->defaultheaderfontstyle),
12223 'line' => $this->defaultheaderline,
12224 ),
12225 'even' => array (
12226 'L' => array ('content' => $Harray, 'font-size' => $this->defaultheaderfontsize, 'font-style' => $this->defaultheaderfontstyle),
12227 'line' => $this->defaultheaderline,
12228 )
12229 );
12230 }
12231 }
12232 else if (is_array($Harray)) {
12233 if ($side=='O') { $this->headerDetails['odd'] = $Harray; }
12234 else if ($side=='E') { $this->headerDetails['even'] = $Harray; }
12235 else { $this->headerDetails = $Harray; }
12236 }
12237 /*-- HTMLHEADERS-FOOTERS --*/
12238 // Overwrite any HTML Header previously set
12239 if ($side=='E') { $this->SetHTMLHeader('','E'); }
12240 else if ($side=='O') { $this->SetHTMLHeader(''); }
12241 else {
12242 $this->SetHTMLHeader('');
12243 $this->SetHTMLHeader('','E');
12244 }
12245 /*-- END HTMLHEADERS-FOOTERS --*/
12246
12247 if ($write) {
12248 $save_y = $this->y;
12249 $this->Header();
12250 $this->SetY($save_y) ;
12251 }
12252 }
12253
12254
12255
12256
12257 function SetFooter($Farray=array(),$side='') {
12258 if (is_string($Farray)) {
12259 if (strlen($Farray)==0) {
12260 if ($side=='O') { $this->footerDetails['odd'] = array(); }
12261 else if ($side=='E') { $this->footerDetails['even'] = array(); }
12262 else { $this->footerDetails = array(); }
12263 }
12264 else if (strpos($Farray,'|') || strpos($Farray,'|')===0) {
12265 $fdet = explode('|',$Farray);
12266 $this->footerDetails = array (
12267 'odd' => array (
12268 'L' => array ('content' => $fdet[0], 'font-size' => $this->defaultfooterfontsize, 'font-style' => $this->defaultfooterfontstyle),
12269 'C' => array ('content' => $fdet[1], 'font-size' => $this->defaultfooterfontsize, 'font-style' => $this->defaultfooterfontstyle),
12270 'R' => array ('content' => $fdet[2], 'font-size' => $this->defaultfooterfontsize, 'font-style' => $this->defaultfooterfontstyle),
12271 'line' => $this->defaultfooterline,
12272 ),
12273 'even' => array (
12274 'R' => array ('content' => $fdet[0], 'font-size' => $this->defaultfooterfontsize, 'font-style' => $this->defaultfooterfontstyle),
12275 'C' => array ('content' => $fdet[1], 'font-size' => $this->defaultfooterfontsize, 'font-style' => $this->defaultfooterfontstyle),
12276 'L' => array ('content' => $fdet[2], 'font-size' => $this->defaultfooterfontsize, 'font-style' => $this->defaultfooterfontstyle),
12277 'line' => $this->defaultfooterline,
12278 )
12279 );
12280 }
12281 else {
12282 $this->footerDetails = array (
12283 'odd' => array (
12284 'R' => array ('content' => $Farray, 'font-size' => $this->defaultfooterfontsize, 'font-style' => $this->defaultfooterfontstyle),
12285 'line' => $this->defaultfooterline,
12286 ),
12287 'even' => array (
12288 'L' => array ('content' => $Farray, 'font-size' => $this->defaultfooterfontsize, 'font-style' => $this->defaultfooterfontstyle),
12289 'line' => $this->defaultfooterline,
12290 )
12291 );
12292 }
12293 }
12294 else if (is_array($Farray)) {
12295 if ($side=='O') { $this->footerDetails['odd'] = $Farray; }
12296 else if ($side=='E') { $this->footerDetails['even'] = $Farray; }
12297 else { $this->footerDetails = $Farray; }
12298 }
12299 /*-- HTMLHEADERS-FOOTERS --*/
12300 // Overwrite any HTML Footer previously set
12301 if ($side=='E') { $this->SetHTMLFooter('','E'); }
12302 else if ($side=='O') { $this->SetHTMLFooter(''); }
12303 else {
12304 $this->SetHTMLFooter('');
12305 $this->SetHTMLFooter('','E');
12306 }
12307 /*-- END HTMLHEADERS-FOOTERS --*/
12308 }
12309
12310 /*-- WATERMARK --*/
12311 function setUnvalidatedText($txt='', $alpha=-1) {
12312 if ($alpha>=0) $this->watermarkTextAlpha = $alpha;
12313 $this->watermarkText = $txt;
12314 }
12315 function SetWatermarkText($txt='', $alpha=-1) {
12316 if ($alpha>=0) $this->watermarkTextAlpha = $alpha;
12317 $this->watermarkText = $txt;
12318 }
12319
12320 function SetWatermarkImage($src, $alpha=-1, $size='D', $pos='F') {
12321 if ($alpha>=0) $this->watermarkImageAlpha = $alpha;
12322 $this->watermarkImage = $src;
12323 $this->watermark_size = $size;
12324 $this->watermark_pos = $pos;
12325 }
12326 /*-- END WATERMARK --*/
12327
12328
12329 //Page footer
12330 function Footer() {
12331 /*-- CSS-PAGE --*/
12332 // PAGED MEDIA - CROP / CROSS MARKS from @PAGE
12333 if ($this->show_marks == 'CROP' || $this->show_marks == 'CROPCROSS') {
12334 // Show TICK MARKS
12335 $this->SetLineWidth(0.1); // = 0.1 mm
12336 $this->SetDColor($this->ConvertColor(0));
12337 $l = $this->cropMarkLength;
12338 $m = $this->cropMarkMargin; // Distance of crop mark from margin
12339 $b = $this->nonPrintMargin; // Non-printable border at edge of paper sheet
12340 $ax1 = $b;
12341 $bx = $this->page_box['outer_width_LR'] - $m;
12342 $ax = max($ax1, $bx-$l);
12343 $cx1 = $this->w - $b;
12344 $dx = $this->w - $this->page_box['outer_width_LR'] + $m;
12345 $cx = min($cx1, $dx+$l);
12346 $ay1 = $b;
12347 $by = $this->page_box['outer_width_TB'] - $m;
12348 $ay = max($ay1, $by-$l);
12349 $cy1 = $this->h - $b;
12350 $dy = $this->h - $this->page_box['outer_width_TB'] + $m;
12351 $cy = min($cy1, $dy+$l);
12352
12353 $this->Line($ax, $this->page_box['outer_width_TB'], $bx, $this->page_box['outer_width_TB']);
12354 $this->Line($cx, $this->page_box['outer_width_TB'], $dx, $this->page_box['outer_width_TB']);
12355 $this->Line($ax, $this->h - $this->page_box['outer_width_TB'], $bx, $this->h - $this->page_box['outer_width_TB']);
12356 $this->Line($cx, $this->h - $this->page_box['outer_width_TB'], $dx, $this->h - $this->page_box['outer_width_TB']);
12357 $this->Line($this->page_box['outer_width_LR'], $ay, $this->page_box['outer_width_LR'], $by);
12358 $this->Line($this->page_box['outer_width_LR'], $cy, $this->page_box['outer_width_LR'], $dy);
12359 $this->Line($this->w - $this->page_box['outer_width_LR'], $ay, $this->w - $this->page_box['outer_width_LR'], $by);
12360 $this->Line($this->w - $this->page_box['outer_width_LR'], $cy, $this->w - $this->page_box['outer_width_LR'], $dy);
12361
12362 if ($this->printers_info) {
12363 $hd = date('Y-m-d H:i').' Page '.$this->page.' of {nb}';
12364 $this->SetTColor($this->ConvertColor(0));
12365 $this->SetFont('arial','',7.5,true,true);
12366 $this->x = $this->page_box['outer_width_LR'] + 1.5;
12367 $this->y = 1;
12368 $this->Cell($headerpgwidth ,$this->FontSize,$hd,0,0,'L',0,'',0,0,0,'M');
12369 $this->SetFont($this->default_font,'',$this->original_default_font_size);
12370 }
12371
12372 }
12373 if ($this->show_marks == 'CROSS' || $this->show_marks == 'CROPCROSS') {
12374 $this->SetLineWidth(0.1); // = 0.1 mm
12375 $this->SetDColor($this->ConvertColor(0));
12376 $l = 14 /2; // longer length of the cross line (half)
12377 $w = 6 /2; // shorter width of the cross line (half)
12378 $r = 1.2; // radius of circle
12379 $m = $this->crossMarkMargin; // Distance of cross mark from margin
12380 $x1 = $this->page_box['outer_width_LR'] - $m;
12381 $x2 = $this->w - $this->page_box['outer_width_LR'] + $m;
12382 $y1 = $this->page_box['outer_width_TB'] - $m;
12383 $y2 = $this->h - $this->page_box['outer_width_TB'] + $m;
12384 // Left
12385 $this->Circle($x1, $this->h/2, $r, 'S') ;
12386 $this->Line($x1-$w, $this->h/2, $x1+$w, $this->h/2);
12387 $this->Line($x1, $this->h/2-$l, $x1, $this->h/2+$l);
12388 // Right
12389 $this->Circle($x2, $this->h/2, $r, 'S') ;
12390 $this->Line($x2-$w, $this->h/2, $x2+$w, $this->h/2);
12391 $this->Line($x2, $this->h/2-$l, $x2, $this->h/2+$l);
12392 // Top
12393 $this->Circle($this->w/2, $y1, $r, 'S') ;
12394 $this->Line($this->w/2, $y1-$w, $this->w/2, $y1+$w);
12395 $this->Line($this->w/2-$l, $y1, $this->w/2+$l, $y1);
12396 // Bottom
12397 $this->Circle($this->w/2, $y2, $r, 'S') ;
12398 $this->Line($this->w/2, $y2-$w, $this->w/2, $y2+$w);
12399 $this->Line($this->w/2-$l, $y2, $this->w/2+$l, $y2);
12400 }
12401
12402
12403 // If @page set non-HTML headers/footers named, they were not read until later in the HTML code - so now set them
12404 if ($this->page==1) {
12405 if ($this->firstPageBoxHeader) {
12406 $this->headerDetails['odd'] = $this->pageheaders[$this->firstPageBoxHeader];
12407 $this->Header();
12408 }
12409 if ($this->firstPageBoxFooter) {
12410 $this->footerDetails['odd'] = $this->pagefooters[$this->firstPageBoxFooter];
12411 }
12412 $this->firstPageBoxHeader='';
12413 $this->firstPageBoxFooter='';
12414 }
12415 /*-- END CSS-PAGE --*/
12416
12417
12418
12419 /*-- HTMLHEADERS-FOOTERS --*/
12420 if (($this->mirrorMargins && ($this->page%2==0) && $this->HTMLFooterE) || ($this->mirrorMargins && ($this->page%2==1) && $this->HTMLFooter) || (!$this->mirrorMargins && $this->HTMLFooter)) {
12421 $this->writeHTMLFooters();
12422 /*-- WATERMARK --*/
12423 if (($this->watermarkText) && ($this->showWatermarkText)) {
12424 $this->watermark( $this->watermarkText, 45, 120, $this->watermarkTextAlpha); // Watermark text
12425 }
12426 if (($this->watermarkImage) && ($this->showWatermarkImage)) {
12427 $this->watermarkImg( $this->watermarkImage, $this->watermarkImageAlpha); // Watermark image
12428 }
12429 /*-- END WATERMARK --*/
12430 return;
12431 }
12432 /*-- END HTMLHEADERS-FOOTERS --*/
12433
12434 $this->processingHeader=true;
12435 $this->ResetMargins(); // necessary after columns
12436 $this->pgwidth = $this->w - $this->lMargin - $this->rMargin;
12437 /*-- WATERMARK --*/
12438 if (($this->watermarkText) && ($this->showWatermarkText)) {
12439 $this->watermark( $this->watermarkText, 45, 120, $this->watermarkTextAlpha); // Watermark text
12440 }
12441 if (($this->watermarkImage) && ($this->showWatermarkImage)) {
12442 $this->watermarkImg( $this->watermarkImage, $this->watermarkImageAlpha); // Watermark image
12443 }
12444 /*-- END WATERMARK --*/
12445 $h = $this->footerDetails;
12446 if(count($h)) {
12447
12448 if ($this->forcePortraitHeaders && $this->CurOrientation=='L' && $this->CurOrientation!=$this->DefOrientation) {
12449 $this->_out(sprintf('q 0 -1 1 0 0 %.3F cm ',($this->h*_MPDFK)));
12450 $headerpgwidth = $this->h - $this->orig_lMargin - $this->orig_rMargin;
12451 if (($this->mirrorMargins) && (($this->page)%2==0)) { // EVEN
12452 $headerlmargin = $this->orig_rMargin;
12453 }
12454 else {
12455 $headerlmargin = $this->orig_lMargin;
12456 }
12457 }
12458 else {
12459 $yadj = 0;
12460 $headerpgwidth = $this->pgwidth;
12461 $headerlmargin = $this->lMargin;
12462 }
12463 $this->SetY(-$this->margin_footer);
12464
12465 $this->SetTColor($this->ConvertColor(0));
12466 $this->SUP = false;
12467 $this->SUB = false;
12468 $this->bullet = false;
12469
12470 // only show pagenumber if numbering on
12471 $pgno = $this->docPageNum($this->page, true);
12472
12473 if (($this->mirrorMargins) && (($this->page)%2==0)) { // EVEN
12474 $side = 'even';
12475 }
12476 else { // ODD // OR NOT MIRRORING MARGINS/FOOTERS = DEFAULT
12477 $side = 'odd';
12478 }
12479 $maxfontheight = 0;
12480 foreach(array('L','C','R') AS $pos) {
12481 if (isset($h[$side][$pos]['content']) && $h[$side][$pos]['content']) {
12482 if (isset($h[$side][$pos]['font-size']) && $h[$side][$pos]['font-size']) { $hfsz = $h[$side][$pos]['font-size']; }
12483 else { $hfsz = $this->default_font_size; }
12484 $maxfontheight = max($maxfontheight,$hfsz);
12485 }
12486 }
12487 // LEFT-CENTER-RIGHT
12488 foreach(array('L','C','R') AS $pos) {
12489 if (isset($h[$side][$pos]['content']) && $h[$side][$pos]['content']) {
12490 $hd = str_replace('{PAGENO}',$pgno,$h[$side][$pos]['content']);
12491 $hd = str_replace($this->aliasNbPgGp,$this->nbpgPrefix.$this->aliasNbPgGp.$this->nbpgSuffix,$hd);
12492 $hd = preg_replace('/\{DATE\s+(.*?)\}/e',"date('\\1')",$hd);
12493 if (isset($h[$side][$pos]['font-family']) && $h[$side][$pos]['font-family']) { $hff = $h[$side][$pos]['font-family']; }
12494 else { $hff = $this->original_default_font; }
12495 if (isset($h[$side][$pos]['font-size']) && $h[$side][$pos]['font-size']) { $hfsz = $h[$side][$pos]['font-size']; }
12496 else { $hfsz = $this->original_default_font_size; }
12497 $maxfontheight = max($maxfontheight,$hfsz);
12498 if (isset($h[$side][$pos]['font-style']) && $h[$side][$pos]['font-style']) { $hfst = $h[$side][$pos]['font-style']; }
12499 else { $hfst = ''; }
12500 if (isset($h[$side][$pos]['color']) && $h[$side][$pos]['color']) {
12501 $hfcol = $h[$side][$pos]['color'];
12502 $cor = $this->ConvertColor($hfcol);
12503 if ($cor) { $this->SetTColor($cor); }
12504 }
12505 else { $hfcol = ''; }
12506 $this->SetFont($hff,$hfst,$hfsz,true,true);
12507 $this->x = $headerlmargin ;
12508 $this->y = $this->h - $this->margin_footer - ($maxfontheight/_MPDFK);
12509 $hd = $this->purify_utf8_text($hd);
12510 if ($this->text_input_as_HTML) {
12511 $hd = $this->all_entities_to_utf8($hd);
12512 }
12513 // CONVERT CODEPAGE
12514 if ($this->usingCoreFont) { $hd = mb_convert_encoding($hd,$this->mb_enc,'UTF-8'); }
12515 // DIRECTIONALITY RTL
12516 $this->magic_reverse_dir($hd, true, $this->directionality); // *RTL*
12517 // Font-specific ligature substitution for Indic fonts
12518 if (isset($this->CurrentFont['indic']) && $this->CurrentFont['indic']) $this->ConvertIndic($hd); // *INDIC*
12519 $align = $pos;
12520 if ($this->directionality == 'rtl') {
12521 if ($pos == 'L') { $align = 'R'; }
12522 else if ($pos == 'R') { $align = 'L'; }
12523 }
12524
12525 if ($pos!='L' && (strpos($hd,$this->aliasNbPg)!==false || strpos($hd,$this->aliasNbPgGp)!==false)) {
12526 if (strpos($hd,$this->aliasNbPgGp)!==false) { $type= 'nbpggp'; } else { $type= 'nbpg'; }
12527 $this->_out('{mpdfheader'.$type.' '.$pos.' ff='.$hff.' fs='.$hfst.' fz='.$hfsz.'}');
12528 $this->Cell($headerpgwidth ,$maxfontheight/_MPDFK ,$hd,0,0,$align,0,'',0,0,0,'M');
12529 $this->_out('Q');
12530 }
12531 else {
12532 $this->Cell($headerpgwidth ,$maxfontheight/_MPDFK ,$hd,0,0,$align,0,'',0,0,0,'M');
12533 }
12534 if ($hfcol) { $this->SetTColor($this->ConvertColor(0)); }
12535 }
12536 }
12537 // Return Font to normal
12538 $this->SetFont($this->default_font,'',$this->original_default_font_size);
12539
12540 // LINE
12541
12542 if (isset($h[$side]['line']) && $h[$side]['line']) {
12543 $this->SetLineWidth(0.1);
12544 $this->SetDColor($this->ConvertColor(0));
12545 $this->Line($headerlmargin , $this->y-($maxfontheight*($this->footer_line_spacing)/_MPDFK), $headerlmargin +$headerpgwidth, $this->y-($maxfontheight*($this->footer_line_spacing)/_MPDFK));
12546 }
12547 if ($this->forcePortraitHeaders && $this->CurOrientation=='L' && $this->CurOrientation!=$this->DefOrientation) {
12548 $this->_out('Q');
12549 }
12550 }
12551 $this->processingHeader=false;
12552
12553 }
12554
12555 ///////////////////
12556 // HYPHENATION
12557 ///////////////////
12558 // mPDF 5.6.21
12559 // Hard hyphens
12560 function hardHyphenate($word, $maxWidth) {
12561 // Don't hyphenate web addresses
12562 if (preg_match('/^(http:|www\.)/',$word)) { return array(false,'','',''); }
12563
12564 // Get dictionary
12565 $poss = array();
12566 $softhyphens = array();
12567 $offset = 0;
12568 $p = true;
12569 if ($this->usingCoreFont) {
12570 $wl = strlen($word);
12571 }
12572 else {
12573 $wl = mb_strlen($word,'UTF-8');
12574 }
12575 while($offset < $wl) {
12576 if (!$this->usingCoreFont) {
12577 $p = mb_strpos($word, "-", $offset, 'UTF-8');
12578 }
12579 else if ($this->FontFamily!='csymbol' && $this->FontFamily!='czapfdingbats') {
12580 $p = strpos($word, "-", $offset);
12581 }
12582 if ($p !== false) { $poss[] = $p - count($poss); }
12583 else { break; }
12584 $offset = $p+1;
12585 }
12586 $success = false;
12587 foreach($poss AS $i) {
12588 if ($this->usingCoreFont) {
12589 $a = substr($word,0,$i);
12590 if ($this->GetStringWidth($a.'-') > $maxWidth) { break ; }
12591 $pre = $a;
12592 $post = substr($word,$i,strlen($word));
12593 $prelength = strlen($pre);
12594 }
12595 else {
12596 $a = mb_substr($word,0,$i,'UTF-8');
12597 if ($this->GetStringWidth($a.'-') > $maxWidth) { break ; }
12598 $pre = $a;
12599 $post = mb_substr($word,$i,mb_strlen($word,'UTF-8'),'UTF-8');
12600 $prelength = mb_strlen($pre, 'UTF-8');
12601 }
12602 $success = true;
12603 }
12604 return array($success,$pre,$post,$prelength);
12605 }
12606
12607
12608 /*-- HYPHENATION --*/
12609 ///////////////////
12610 ///////////////////
12611 // HYPHENATION
12612 ///////////////////
12613 // Soft hyphs
12614 function softHyphenate($word, $maxWidth) {
12615 // Don't hyphenate web addresses
12616 if (preg_match('/^(http:|www\.)/',$word)) { return array(false,'','',''); }
12617
12618 // Get dictionary
12619 $poss = array();
12620 $softhyphens = array();
12621 $offset = 0;
12622 $p = true;
12623 if ($this->usingCoreFont) {
12624 $wl = strlen($word);
12625 }
12626 else {
12627 $wl = mb_strlen($word,'UTF-8');
12628 }
12629 while($offset < $wl) {
12630 // Soft Hyphens chr(173)
12631 if (!$this->usingCoreFont) {
12632 $p = mb_strpos($word, "\xc2\xad", $offset, 'UTF-8');
12633 }
12634 else if ($this->FontFamily!='csymbol' && $this->FontFamily!='czapfdingbats') {
12635 $p = strpos($word, chr(173), $offset);
12636 }
12637 if ($p !== false) { $poss[] = $p - count($poss); }
12638 else { break; }
12639 $offset = $p+1;
12640 }
12641 $success = false;
12642 foreach($poss AS $i) {
12643 if ($this->usingCoreFont) {
12644 $a = substr($word,0,$i);
12645 if ($this->GetStringWidth($a.'-') > $maxWidth) { break ; }
12646 $pre = $a;
12647 $post = substr($word,$i,strlen($word));
12648 $prelength = strlen($pre);
12649 }
12650 else {
12651 $a = mb_substr($word,0,$i,'UTF-8');
12652 if ($this->GetStringWidth($a.'-') > $maxWidth) { break ; }
12653 $pre = $a;
12654 $post = mb_substr($word,$i,mb_strlen($word,'UTF-8'),'UTF-8');
12655 $prelength = mb_strlen($pre, 'UTF-8');
12656 }
12657 $success = true;
12658 }
12659 return array($success,$pre,$post,$prelength);
12660 }
12661
12662 ///////////////////
12663 // Word hyphenation
12664 function hyphenateWord($word, $maxWidth) {
12665 // Do everything inside this function in utf-8
12666 // Don't hyphenate web addresses
12667 if (preg_match('/^(http:|www\.)/',$word)) { return array(false,'','',''); }
12668
12669
12670 // Get dictionary
12671 if (!$this->loadedSHYdictionary) {
12672 if (file_exists(_MPDF_PATH.'patterns/dictionary.txt')) {
12673 $this->SHYdictionary = file(_MPDF_PATH.'patterns/dictionary.txt',FILE_SKIP_EMPTY_LINES);
12674 foreach($this->SHYdictionary as $entry) {
12675 $entry = trim($entry);
12676 $poss = array();
12677 $offset = 0;
12678 $p = true;
12679 $wl = mb_strlen($entry ,'UTF-8');
12680 while($offset < $wl) {
12681 $p = mb_strpos($entry, '/', $offset, 'UTF-8');
12682 if ($p !== false) { $poss[] = $p - count($poss); }
12683 else { break; }
12684 $offset = $p+1;
12685 }
12686 if (count($poss)) { $this->SHYdictionaryWords[str_replace('/', '', mb_strtolower($entry))] = $poss; }
12687 }
12688 }
12689 $this->loadedSHYdictionary = true;
12690 }
12691
12692 if (!in_array($this->SHYlang,$this->SHYlanguages)) { return array(false,'','',''); }
12693 // If no pattern loaded or not the best one
12694 if (count($this->SHYpatterns) < 1 || ($this->loadedSHYpatterns && $this->loadedSHYpatterns != $this->SHYlang)) {
12695 include(_MPDF_PATH."patterns/" . $this->SHYlang . ".php");
12696 $patterns = explode(' ', $patterns);
12697 $new_patterns = array();
12698 for($i = 0; $i < count($patterns); $i++) {
12699 $value = $patterns[$i];
12700 $new_patterns[preg_replace('/[0-9]/', '', $value)] = $value;
12701 }
12702 $this->SHYpatterns = $new_patterns;
12703 $this->loadedSHYpatterns = $this->SHYlang;
12704 }
12705
12706 if ($this->usingCoreFont) { $word = mb_convert_encoding($word,'UTF-8',$this->mb_enc); }
12707
12708 $prepre = '';
12709 $postpost = '';
12710 $startpunctuation = "\xc2\xab\xc2\xbf\xe2\x80\x98\xe2\x80\x9b\xe2\x80\x9c\xe2\x80\x9f";
12711 $endpunctuation = "\xe2\x80\x9e\xe2\x80\x9d\xe2\x80\x9a\xe2\x80\x99\xc2\xbb";
12712 $pre = '';
12713 $post = '';
12714
12715
12716 if (preg_match('/^(["\''.$startpunctuation .'])+(.{'.$this->SHYcharmin.',})$/u',$word,$m)) {
12717 $prepre = $m[1];
12718 $word = $m[2];
12719 }
12720 if (preg_match('/^(.{'.$this->SHYcharmin.',})([\'\.,;:!?"'.$endpunctuation .']+)$/u',$word,$m)) {
12721 $word = $m[1];
12722 $postpost = $m[2];
12723 }
12724 if(mb_strlen($word,'UTF-8') < $this->SHYcharmin) {
12725 return array(false,'','','');
12726 }
12727 $success = false;
12728
12729 if(isset($this->SHYdictionaryWords[mb_strtolower($word)])) {
12730 foreach($this->SHYdictionaryWords[mb_strtolower($word)] AS $i) {
12731 $a = $prepre . mb_substr($word,0,$i,'UTF-8');
12732 if ($this->usingCoreFont) { $testa = mb_convert_encoding($a,$this->mb_enc,'UTF-8'); }
12733 else { $testa = $a; }
12734 if ($this->GetStringWidth($testa.'-') > $maxWidth) { break ; }
12735 $pre = $a;
12736 $post = mb_substr($word,$i,mb_strlen($word,'UTF-8'),'UTF-8') . $postpost;
12737 $success = true;
12738 }
12739 }
12740
12741 if (!$success) {
12742 $text_word = '_' . $word . '_';
12743 $word_length = mb_strlen($text_word,'UTF-8');
12744
12745 $single_character = preg_split('//u', $text_word);
12746
12747 $text_word = mb_strtolower($text_word,'UTF-8');
12748 $hyphenated_word = array();
12749 $numb3rs = array('0' => true, '1' => true, '2' => true, '3' => true, '4' => true, '5' => true, '6' => true, '7' => true, '8' => true, '9' => true);
12750 for($position = 0; $position <= ($word_length - $this->SHYcharmin); $position++) {
12751 $maxwins = min(($word_length - $position), $this->SHYcharmax);
12752 for($win = $this->SHYcharmin; $win <= $maxwins; $win++) {
12753 if(isset($this->SHYpatterns[mb_substr($text_word, $position, $win,'UTF-8')])) {
12754 $pattern = $this->SHYpatterns[mb_substr($text_word, $position, $win,'UTF-8')];
12755 $digits = 1;
12756 $pattern_length = mb_strlen($pattern,'UTF-8');
12757 for($i = 0; $i < $pattern_length; $i++) {
12758 $char = $pattern[$i];
12759 if(isset($numb3rs[$char])) {
12760 $zero = ($i == 0) ? $position - 1 : $position + $i - $digits;
12761 if(!isset($hyphenated_word[$zero]) || $hyphenated_word[$zero] != $char) $hyphenated_word[$zero] = $char;
12762 $digits++;
12763 }
12764 }
12765 }
12766 }
12767 }
12768
12769 for($i = $this->SHYleftmin; $i <= (mb_strlen($word,'UTF-8') - $this->SHYrightmin); $i++) {
12770 if(isset($hyphenated_word[$i]) && $hyphenated_word[$i] % 2 != 0) {
12771 $a = $prepre . mb_substr($word,0,$i,'UTF-8');
12772 if ($this->usingCoreFont) { $testa = mb_convert_encoding($a,$this->mb_enc,'UTF-8'); }
12773 else { $testa = $a; }
12774 if ($this->GetStringWidth($testa.'-') > $maxWidth + 0.0001) { break ; }
12775 $pre = $a;
12776 $post = mb_substr($word,$i,mb_strlen($word,'UTF-8'),'UTF-8') . $postpost;
12777 $success = true;
12778 }
12779 }
12780 }
12781 if ($this->usingCoreFont) {
12782 $pre = mb_convert_encoding($pre,$this->mb_enc,'UTF-8');
12783 $post = mb_convert_encoding($post,$this->mb_enc,'UTF-8');
12784 $prelength = strlen($pre);
12785 }
12786 else {
12787 $prelength = mb_strlen($pre);
12788 }
12789 return array($success,$pre,$post,$prelength);
12790
12791 }
12792 /*-- END HYPHENATION --*/
12793
12794
12795 /*-- HTML-CSS --*/
12796 ///////////////////
12797 /// HTML parser ///
12798 ///////////////////
12799 function WriteHTML($html,$sub=0,$init=true,$close=true) {
12800 // $sub ADDED - 0 = default; 1=headerCSS only; 2=HTML body (parts) only; 3 - HTML parses only
12801 // 4 - writes HTML headers
12802 // $close Leaves buffers etc. in current state, so that it can continue a block etc.
12803 // $init - Clears and sets buffers to Top level block etc.
12804
12805 if (empty($html)) { $html = ''; }
12806 if ($this->progressBar) { $this->UpdateProgressBar(1,0,'Parsing CSS & Headers'); } // *PROGRESS-BAR*
12807
12808 if ($init) {
12809 $this->headerbuffer='';
12810 $this->textbuffer = array();
12811 $this->fixedPosBlockSave = array();
12812 }
12813 if ($sub == 1) { $html = '<style> '.$html.' </style>'; } // stylesheet only
12814
12815 if ($this->allow_charset_conversion) {
12816 if ($sub < 1) {
12817 $this->ReadCharset($html);
12818 }
12819 if ($this->charset_in && $sub!=4) { // mPDF 5.4.14
12820 $success = iconv($this->charset_in,'UTF-8//TRANSLIT',$html);
12821 if ($success) { $html = $success; }
12822 }
12823 }
12824 $html = $this->purify_utf8($html,false);
12825 if ($init) {
12826 $this->blklvl = 0;
12827 $this->lastblocklevelchange = 0;
12828 $this->blk = array();
12829 $this->initialiseBlock($this->blk[0]);
12830 $this->blk[0]['width'] =& $this->pgwidth;
12831 $this->blk[0]['inner_width'] =& $this->pgwidth;
12832 $this->blk[0]['blockContext'] = $this->blockContext;
12833 }
12834
12835 $zproperties = array();
12836 if ($sub < 2) {
12837 $this->ReadMetaTags($html);
12838
12839 // mPDF 5.6.18
12840 if (preg_match('/<base[^>]*href=["\']([^"\'>]*)["\']/i', $html, $m)) {
12841 $this->SetBasePath($m[1]);
12842 }
12843 // NB default stylesheet now in mPDF.css - read on initialising class
12844 $html = $this->cssmgr->ReadCSS($html);
12845
12846 if ($this->useLang && !$this->usingCoreFont && preg_match('/<html [^>]*lang=[\'\"](.*?)[\'\"]/ism',$html,$m)) {
12847 $html_lang = $m[1];
12848 }
12849
12850 if (preg_match('/<html [^>]*dir=[\'\"]\s*rtl\s*[\'\"]/ism',$html)) {
12851 $zproperties['DIRECTION'] = 'rtl';
12852 }
12853
12854 // allow in-line CSS for body tag to be parsed // Get <body> tag inline CSS
12855 if (preg_match('/<body([^>]*)>(.*?)<\/body>/ism',$html,$m) || preg_match('/<body([^>]*)>(.*)$/ism',$html,$m)) {
12856 $html = $m[2];
12857 // Changed to allow style="background: url('bg.jpg')"
12858 if (preg_match('/style=[\"](.*?)[\"]/ism',$m[1],$mm) || preg_match('/style=[\'](.*?)[\']/ism',$m[1],$mm)) {
12859 $zproperties = $this->cssmgr->readInlineCSS($mm[1]);
12860 }
12861 if (preg_match('/dir=[\'\"]\s*rtl\s*[\'\"]/ism',$m[1])) {
12862 $zproperties['DIRECTION'] = 'rtl';
12863 }
12864 if (isset($html_lang) && $html_lang) { $zproperties['LANG'] = $html_lang; }
12865 if ($this->useLang && !$this->onlyCoreFonts && preg_match('/lang=[\'\"](.*?)[\'\"]/ism',$m[1],$mm)) {
12866 $zproperties['LANG'] = $mm[1];
12867 }
12868
12869 }
12870 }
12871 $properties = $this->cssmgr->MergeCSS('BLOCK','BODY','');
12872 if ($zproperties) { $properties = $this->cssmgr->array_merge_recursive_unique($properties,$zproperties); }
12873
12874 if (isset($properties['DIRECTION']) && $properties['DIRECTION']) {
12875 $this->cssmgr->CSS['BODY']['DIRECTION'] = $properties['DIRECTION'];
12876 }
12877 if (!isset($this->cssmgr->CSS['BODY']['DIRECTION'])) {
12878 $this->cssmgr->CSS['BODY']['DIRECTION'] = $this->directionality;
12879 }
12880 else { $this->SetDirectionality($this->cssmgr->CSS['BODY']['DIRECTION']); }
12881
12882 $this->setCSS($properties,'','BODY');
12883 $this->blk[0]['InlineProperties'] = $this->saveInlineProperties();
12884
12885 if ($sub == 1) { return ''; }
12886 if (!isset($this->cssmgr->CSS['BODY'])) { $this->cssmgr->CSS['BODY'] = array(); }
12887
12888 /*-- BACKGROUNDS --*/
12889 if (isset($properties['BACKGROUND-GRADIENT'])) {
12890 $this->bodyBackgroundGradient = $properties['BACKGROUND-GRADIENT'];
12891 }
12892
12893 if (isset($properties['BACKGROUND-IMAGE']) && $properties['BACKGROUND-IMAGE']) {
12894 $ret = $this->SetBackground($properties, $this->pgwidth);
12895 if ($ret) { $this->bodyBackgroundImage = $ret; }
12896 }
12897 /*-- END BACKGROUNDS --*/
12898
12899 /*-- CSS-PAGE --*/
12900 // If page-box is set
12901 if ($this->state==0 && isset($this->cssmgr->CSS['@PAGE']) && $this->cssmgr->CSS['@PAGE'] ) {
12902 $this->page_box['current'] = '';
12903 $this->page_box['using'] = true;
12904 list($pborientation,$pbmgl,$pbmgr,$pbmgt,$pbmgb,$pbmgh,$pbmgf,$hname,$fname,$bg,$resetpagenum,$pagenumstyle,$suppress,$marks,$newformat) = $this->SetPagedMediaCSS('', false, 'O');
12905 $this->DefOrientation = $this->CurOrientation = $pborientation;
12906 $this->orig_lMargin = $this->DeflMargin = $pbmgl;
12907 $this->orig_rMargin = $this->DefrMargin = $pbmgr;
12908 $this->orig_tMargin = $this->tMargin = $pbmgt;
12909 $this->orig_bMargin = $this->bMargin = $pbmgb;
12910 $this->orig_hMargin = $this->margin_header = $pbmgh;
12911 $this->orig_fMargin = $this->margin_footer = $pbmgf;
12912 list($pborientation,$pbmgl,$pbmgr,$pbmgt,$pbmgb,$pbmgh,$pbmgf,$hname,$fname,$bg,$resetpagenum,$pagenumstyle,$suppress,$marks,$newformat) = $this->SetPagedMediaCSS('', true, 'O'); // first page
12913 $this->show_marks = $marks;
12914 if ($hname && !preg_match('/^html_(.*)$/i',$hname)) $this->firstPageBoxHeader = $hname;
12915 if ($fname && !preg_match('/^html_(.*)$/i',$fname)) $this->firstPageBoxFooter = $fname;
12916 }
12917 /*-- END CSS-PAGE --*/
12918
12919 $parseonly = false;
12920 $this->bufferoutput = false;
12921 if ($sub == 3) {
12922 $parseonly = true;
12923 // Close any open block tags
12924 for ($b= $this->blklvl;$b>0;$b--) { $this->CloseTag($this->blk[$b]['tag']); }
12925 // Output any text left in buffer
12926 if (count($this->textbuffer)) { $this->printbuffer($this->textbuffer); }
12927 $this->textbuffer=array();
12928 }
12929 else if ($sub == 4) {
12930 // Close any open block tags
12931 for ($b= $this->blklvl;$b>0;$b--) { $this->CloseTag($this->blk[$b]['tag']); }
12932 // Output any text left in buffer
12933 if (count($this->textbuffer)) { $this->printbuffer($this->textbuffer); }
12934 $this->bufferoutput = true;
12935 $this->textbuffer=array();
12936 $this->headerbuffer='';
12937 $properties = $this->cssmgr->MergeCSS('BLOCK','BODY','');
12938 $this->setCSS($properties,'','BODY');
12939 }
12940
12941 mb_internal_encoding('UTF-8');
12942
12943 $html = $this->AdjustHTML($html, $this->tabSpaces); //Try to make HTML look more like XHTML
12944
12945 if ($this->autoFontGroups) { $html = $this->AutoFont($html); }
12946
12947 /*-- HTMLHEADERS-FOOTERS --*/
12948 preg_match_all('/<htmlpageheader([^>]*)>(.*?)<\/htmlpageheader>/si',$html,$h);
12949 for($i=0;$i<count($h[1]);$i++) {
12950 if (preg_match('/name=[\'|\"](.*?)[\'|\"]/',$h[1][$i],$n)) {
12951 $this->pageHTMLheaders[$n[1]]['html'] = $h[2][$i];
12952 $this->pageHTMLheaders[$n[1]]['h'] = $this->_gethtmlheight($h[2][$i]);
12953 }
12954 }
12955 preg_match_all('/<htmlpagefooter([^>]*)>(.*?)<\/htmlpagefooter>/si',$html,$f);
12956 for($i=0;$i<count($f[1]);$i++) {
12957 if (preg_match('/name=[\'|\"](.*?)[\'|\"]/',$f[1][$i],$n)) {
12958 $this->pageHTMLfooters[$n[1]]['html'] = $f[2][$i];
12959 $this->pageHTMLfooters[$n[1]]['h'] = $this->_gethtmlheight($f[2][$i]);
12960 }
12961 }
12962 /*-- END HTMLHEADERS-FOOTERS --*/
12963 $html = preg_replace('/<htmlpageheader.*?<\/htmlpageheader>/si','',$html);
12964 $html = preg_replace('/<htmlpagefooter.*?<\/htmlpagefooter>/si','',$html);
12965
12966 if($this->state==0 && $sub!=1 && $sub!=3 && $sub!=4) {
12967 $this->AddPage($this->CurOrientation);
12968 }
12969
12970
12971 /*-- HTMLHEADERS-FOOTERS --*/
12972
12973 if (isset($hname) && preg_match('/^html_(.*)$/i',$hname,$n)) $this->SetHTMLHeader($this->pageHTMLheaders[$n[1]],'O',true);
12974 if (isset($fname) && preg_match('/^html_(.*)$/i',$fname,$n)) $this->SetHTMLFooter($this->pageHTMLfooters[$n[1]],'O');
12975
12976 /*-- END HTMLHEADERS-FOOTERS --*/
12977
12978 $html=str_replace('<?','< ',$html); //Fix '<?XML' bug from HTML code generated by MS Word
12979
12980 $this->checkSIP = false;
12981 $this->checkSMP = false;
12982 $this->checkCJK = false;
12983 if ($this->onlyCoreFonts) { $html = $this->SubstituteChars($html); }
12984 else {
12985 if (preg_match("/([".$this->pregRTLchars."])/u", $html)) { $this->biDirectional = true; } // *RTL*
12986 if (preg_match("/([\x{20000}-\x{2FFFF}])/u", $html)) { $this->checkSIP = true; }
12987 if (preg_match("/([\x{10000}-\x{1FFFF}])/u", $html)) { $this->checkSMP = true; }
12988 /*-- CJK-FONTS --*/
12989 if (preg_match("/([".$this->pregCJKchars."])/u", $html)) { $this->checkCJK = true; }
12990 /*-- END CJK-FONTS --*/
12991 }
12992
12993 // Don't allow non-breaking spaces that are converted to substituted chars or will break anyway and mess up table width calc.
12994 $html = str_replace('<tta>160</tta>',chr(32),$html);
12995 $html = str_replace('</tta><tta>','|',$html);
12996 $html = str_replace('</tts><tts>','|',$html);
12997 $html = str_replace('</ttz><ttz>','|',$html);
12998
12999 //Add new supported tags in the DisableTags function
13000 $html=strip_tags($html,$this->enabledtags); //remove all unsupported tags, but the ones inside the 'enabledtags' string
13001
13002 //Explode the string in order to parse the HTML code
13003 $a=preg_split('/<(.*?)>/ms',$html,-1,PREG_SPLIT_DELIM_CAPTURE);
13004 // ? more accurate regexp that allows e.g. <a name="Silly <name>">
13005 // if changing - also change in fn.SubstituteChars()
13006 // $a = preg_split ('/<((?:[^<>]+(?:"[^"]*"|\'[^\']*\')?)+)>/ms', $html, -1, PREG_SPLIT_DELIM_CAPTURE);
13007
13008 if ($this->mb_enc) {
13009 mb_internal_encoding($this->mb_enc);
13010 }
13011 $pbc = 0;
13012 if ($this->progressBar) { $this->UpdateProgressBar(1,0); } // *PROGRESS-BAR*
13013 $this->subPos = -1;
13014 $cnt = count($a);
13015 for($i=0;$i<$cnt; $i++) {
13016 $e = $a[$i];
13017 if($i%2==0) {
13018 //TEXT
13019 if ($this->blk[$this->blklvl]['hide']) { continue; }
13020 if ($this->inlineDisplayOff) { continue; }
13021 if ($this->inMeter) { continue; } // mPDF 5.5.09
13022
13023 if ($this->inFixedPosBlock) { $this->fixedPosBlock .= $e; continue; } // *CSS-POSITION*
13024 if (strlen($e) == 0) { continue; }
13025
13026 $e = strcode2utf($e);
13027 $e = $this->lesser_entity_decode($e);
13028
13029 if ($this->usingCoreFont) {
13030 // If core font is selected in document which is not onlyCoreFonts - substitute with non-core font
13031 if ($this->useSubstitutions && !$this->onlyCoreFonts && $this->subPos<$i && !$this->specialcontent) {
13032 $cnt += $this->SubstituteCharsNonCore($a, $i, $e);
13033 }
13034 // CONVERT ENCODING
13035 $e = mb_convert_encoding($e,$this->mb_enc,'UTF-8');
13036 // mPDF 5.6.41
13037 if ($this->toupper) { $e = mb_strtoupper($e,$this->mb_enc); }
13038 if ($this->tolower) { $e = mb_strtolower($e,$this->mb_enc); }
13039 if ($this->capitalize) { $e = mb_convert_case($e, MB_CASE_TITLE, "UTF-8"); }
13040 }
13041 else {
13042 if ($this->checkSIP && $this->CurrentFont['sipext'] && $this->subPos<$i && !$this->specialcontent) {
13043 $cnt += $this->SubstituteCharsSIP($a, $i, $e);
13044 }
13045
13046 if ($this->useSubstitutions && !$this->onlyCoreFonts && $this->CurrentFont['type']!='Type0' && $this->subPos<$i && !$this->specialcontent) {
13047 // mPDF 5.6.62 removes U+200E/U+200F LTR and RTL mark and U+200C/U+200D Zero-width Joiner and Non-joiner
13048 $e = preg_replace("/[\xe2\x80\x8c\xe2\x80\x8d\xe2\x80\x8e\xe2\x80\x8f]/u",'',$e);
13049 $cnt += $this->SubstituteCharsMB($a, $i, $e);
13050 }
13051 if ($this->biDirectional) { // *RTL*
13052 $e = preg_replace("/([".$this->pregRTLchars."]+)/ue", '$this->ArabJoin(stripslashes(\'\\1\'))', $e); // *RTL*
13053 } // *RTL*
13054 // Font-specific ligature substitution for Indic fonts
13055 if (isset($this->CurrentFont['indic']) && $this->CurrentFont['indic']) $this->ConvertIndic($e); // *INDIC*
13056
13057 // mPDF 5.6.62 removes U+200E/U+200F LTR and RTL mark and U+200C/U+200D Zero-width Joiner and Non-joiner
13058 $e = preg_replace("/[\xe2\x80\x8c\xe2\x80\x8d\xe2\x80\x8e\xe2\x80\x8f]/u",'',$e);
13059
13060 if ($this->toupper) { $e = mb_strtoupper($e,$this->mb_enc); }
13061 if ($this->tolower) { $e = mb_strtolower($e,$this->mb_enc); }
13062 if ($this->capitalize) { $e = mb_convert_case($e, MB_CASE_TITLE, "UTF-8"); }
13063 }
13064 if (($this->tts) || ($this->ttz) || ($this->tta)) {
13065 $es = explode('|',$e);
13066 $e = '';
13067 foreach($es AS $val) {
13068 $e .= chr($val);
13069 }
13070 }
13071 //Adjust lineheight
13072
13073 // FORM ELEMENTS
13074 if ($this->specialcontent) {
13075 /*-- FORMS --*/
13076 //SELECT tag (form element)
13077 if ($this->specialcontent == "type=select") {
13078 $e = ltrim($e);
13079 $stringwidth = $this->GetStringWidth($e);
13080 if (!isset($this->selectoption['MAXWIDTH']) || $stringwidth > $this->selectoption['MAXWIDTH']) { $this->selectoption['MAXWIDTH'] = $stringwidth; }
13081 if (!isset($this->selectoption['SELECTED']) || $this->selectoption['SELECTED'] == '') { $this->selectoption['SELECTED'] = $e; }
13082 // mPDD 1.4 Active Forms
13083 if (isset($this->selectoption['ACTIVE']) && $this->selectoption['ACTIVE']) {
13084 $this->selectoption['ITEMS'][]=array('exportValue'=>$this->selectoption['currentVAL'], 'content'=>$e, 'selected'=>$this->selectoption['currentSEL']);
13085 }
13086 }
13087 // TEXTAREA
13088 else {
13089 $objattr = unserialize($this->specialcontent);
13090 $objattr['text'] = $e;
13091 $te = "\xbb\xa4\xactype=textarea,objattr=".serialize($objattr)."\xbb\xa4\xac";
13092 if ($this->tdbegin) {
13093 $this->_saveCellTextBuffer($te, $this->HREF);
13094 }
13095 else {
13096 $this->_saveTextBuffer($te, $this->HREF);
13097 }
13098 }
13099 /*-- END FORMS --*/
13100 }
13101
13102 // TABLE
13103 else if ($this->tableLevel) {
13104 /*-- TABLES --*/
13105 if ($this->tdbegin) {
13106 if (($this->ignorefollowingspaces) && !$this->ispre) { $e = ltrim($e); }
13107 if ($e || $e==='0') {
13108 if (($this->blockjustfinished || $this->listjustfinished) && $this->cell[$this->row][$this->col]['s']>0) {
13109 $this->_saveCellTextBuffer("\n");
13110 if (!isset($this->cell[$this->row][$this->col]['maxs'])) {
13111 $this->cell[$this->row][$this->col]['maxs'] = $this->cell[$this->row][$this->col]['s'];
13112 }
13113 elseif($this->cell[$this->row][$this->col]['maxs'] < $this->cell[$this->row][$this->col]['s']) {
13114 $this->cell[$this->row][$this->col]['maxs'] = $this->cell[$this->row][$this->col]['s'];
13115 }
13116 $this->cell[$this->row][$this->col]['s'] = 0;// reset
13117 }
13118 $this->blockjustfinished=false;
13119 $this->listjustfinished=false;
13120
13121 $this->_saveCellTextBuffer($e, $this->HREF);
13122
13123 if (!isset($this->cell[$this->row][$this->col]['R']) || !$this->cell[$this->row][$this->col]['R']) {
13124 if (isset($this->cell[$this->row][$this->col]['s'])) {
13125 $this->cell[$this->row][$this->col]['s'] += $this->GetStringWidth($e, false);
13126 }
13127 else { $this->cell[$this->row][$this->col]['s'] = $this->GetStringWidth($e, false); }
13128 if (!empty($this->spanborddet)) {
13129 $this->cell[$this->row][$this->col]['s'] += $this->spanborddet['L']['w'] + $this->spanborddet['R']['w'];
13130 }
13131 }
13132
13133 if ($this->checkCJK && preg_match("/([".$this->pregCJKchars."])/u", $e)) { $this->tableCJK = true; } // *CJK-FONTS*
13134
13135 // mPDF 5.6.13 Decimal mark alignment
13136 if (substr($this->cell[$this->row][$this->col]['a'],0,1) == 'D') {
13137 $dp = $this->decimal_align[substr($this->cell[$this->row][$this->col]['a'],0,2)];
13138 $s = preg_split('/'.preg_quote($dp,'/').'/', $e, 2); // ? needs to be /u if not core
13139 $s0 = $this->GetStringWidth($s[0], false);
13140 if ($s[1]) { $s1 = $this->GetStringWidth(($s[1].$dp), false); }
13141 else $s1 = 0;
13142 if (!isset($this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['decimal_align'][$this->col]['maxs0'])) {
13143 $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['decimal_align'][$this->col]['maxs0'] = $s0;
13144 }
13145 else {
13146 $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['decimal_align'][$this->col]['maxs0'] = max($s0, $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['decimal_align'][$this->col]['maxs0']);
13147 }
13148 if (!isset($this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['decimal_align'][$this->col]['maxs1'])) {
13149 $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['decimal_align'][$this->col]['maxs1'] = $s1;
13150 }
13151 else {
13152 $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['decimal_align'][$this->col]['maxs1'] = max($s1, $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['decimal_align'][$this->col]['maxs1']);
13153 }
13154 }
13155
13156 if ($this->tableLevel==1 && $this->useGraphs) {
13157 $this->graphs[$this->currentGraphId]['data'][$this->row][$this->col] = $e;
13158 }
13159 $this->nestedtablejustfinished = false;
13160 $this->linebreakjustfinished=false;
13161 }
13162 }
13163 /*-- END TABLES --*/
13164 }
13165 // ALL ELSE
13166 else {
13167 if ($this->ignorefollowingspaces and !$this->ispre) { $e = ltrim($e); }
13168 if ($e || $e==='0') $this->_saveTextBuffer($e, $this->HREF);
13169 }
13170 }
13171
13172
13173 else { // TAG **
13174
13175 if($e[0]=='/') {
13176 /*-- PROGRESS-BAR --*/
13177 if ($this->progressBar) { // 10% increments
13178 if (intval($i*10/$cnt) != $pbc) { $pbc = intval($i*10/$cnt); $this->UpdateProgressBar(1,$pbc*10,$tag); }
13179 }
13180 /*-- END PROGRESS-BAR --*/
13181
13182
13183 // Check for tags where HTML specifies optional end tags,
13184 // and/or does not allow nesting e.g. P inside P, or
13185 $endtag = trim(strtoupper(substr($e,1))); // mPDF 5.4.20
13186 if($this->blk[$this->blklvl]['hide']) {
13187 if (in_array($endtag, $this->outerblocktags) || in_array($endtag, $this->innerblocktags)) {
13188 unset($this->blk[$this->blklvl]);
13189 $this->blklvl--;
13190 }
13191 continue;
13192 }
13193
13194 /*-- CSS-POSITION --*/
13195 if ($this->inFixedPosBlock) {
13196 if (in_array($endtag, $this->outerblocktags) || in_array($endtag, $this->innerblocktags)) { $this->fixedPosBlockDepth--; }
13197 if ($this->fixedPosBlockDepth == 0) {
13198 $this->fixedPosBlockSave[] = array($this->fixedPosBlock, $this->fixedPosBlockBBox, $this->page);
13199 $this->fixedPosBlock = '';
13200 $this->inFixedPosBlock = false;
13201 continue;
13202 }
13203 $this->fixedPosBlock .= '<'.$e.'>';
13204 continue;
13205 }
13206 /*-- END CSS-POSITION --*/
13207 if ($this->allow_html_optional_endtags && !$parseonly) {
13208 if (($endtag == 'DIV' || $endtag =='FORM' || $endtag =='CENTER') && $this->lastoptionaltag == 'P') { $this->CloseTag($this->lastoptionaltag ); }
13209 if ($this->lastoptionaltag == 'LI' && $endtag == 'OL') { $this->CloseTag($this->lastoptionaltag ); }
13210 if ($this->lastoptionaltag == 'LI' && $endtag == 'UL') { $this->CloseTag($this->lastoptionaltag ); }
13211 if ($this->lastoptionaltag == 'DD' && $endtag == 'DL') { $this->CloseTag($this->lastoptionaltag ); }
13212 if ($this->lastoptionaltag == 'DT' && $endtag == 'DL') { $this->CloseTag($this->lastoptionaltag ); }
13213 if ($this->lastoptionaltag == 'OPTION' && $endtag == 'SELECT') { $this->CloseTag($this->lastoptionaltag ); }
13214 /*-- TABLES --*/
13215 if ($endtag == 'TABLE') {
13216 if ($this->lastoptionaltag == 'THEAD' || $this->lastoptionaltag == 'TBODY' || $this->lastoptionaltag == 'TFOOT') {
13217 $this->CloseTag($this->lastoptionaltag);
13218 }
13219 if ($this->lastoptionaltag == 'TR') { $this->CloseTag('TR'); }
13220 if ($this->lastoptionaltag == 'TD' || $this->lastoptionaltag == 'TH') { $this->CloseTag($this->lastoptionaltag ); $this->CloseTag('TR'); }
13221 }
13222 if ($endtag == 'THEAD' || $endtag == 'TBODY' || $endtag == 'TFOOT') {
13223 if ($this->lastoptionaltag == 'TR') { $this->CloseTag('TR'); }
13224 if ($this->lastoptionaltag == 'TD' || $this->lastoptionaltag == 'TH') { $this->CloseTag($this->lastoptionaltag ); $this->CloseTag('TR'); }
13225 }
13226 if ($endtag == 'TR') {
13227 if ($this->lastoptionaltag == 'TD' || $this->lastoptionaltag == 'TH') { $this->CloseTag($this->lastoptionaltag ); }
13228 }
13229 /*-- END TABLES --*/
13230 }
13231 $this->CloseTag($endtag);
13232 }
13233
13234 else { // OPENING TAG
13235 if($this->blk[$this->blklvl]['hide']) {
13236 if (strpos($e,' ')) { $te = strtoupper(substr($e,0,strpos($e,' '))); }
13237 else { $te = strtoupper($e); }
13238 if (in_array($te, $this->outerblocktags) || in_array($te, $this->innerblocktags)) {
13239 $this->blklvl++;
13240 $this->blk[$this->blklvl]['hide']=true;
13241 }
13242 continue;
13243 }
13244
13245 /*-- CSS-POSITION --*/
13246 if ($this->inFixedPosBlock) {
13247 if (strpos($e,' ')) { $te = strtoupper(substr($e,0,strpos($e,' '))); }
13248 else { $te = strtoupper($e); }
13249 $this->fixedPosBlock .= '<'.$e.'>';
13250 if (in_array($te, $this->outerblocktags) || in_array($te, $this->innerblocktags)) { $this->fixedPosBlockDepth++; }
13251 continue;
13252 }
13253 /*-- END CSS-POSITION --*/
13254 $regexp = '|=\'(.*?)\'|s'; // eliminate single quotes, if any
13255 $e = preg_replace($regexp,"=\"\$1\"",$e);
13256 // changes anykey=anyvalue to anykey="anyvalue" (only do this inside [some] tags)
13257 if (substr($e,0,10)!='pageheader' && substr($e,0,10)!='pagefooter' && substr($e,0,12)!='tocpagebreak') { // mPDF 5.6.69
13258 $regexp = '| (\\w+?)=([^\\s>"]+)|si';
13259 $e = preg_replace($regexp," \$1=\"\$2\"",$e);
13260 }
13261
13262 $e = preg_replace('/ (\\S+?)\s*=\s*"/i', " \\1=\"", $e);
13263
13264 //Fix path values, if needed
13265 $orig_srcpath = '';
13266 if ((stristr($e,"href=") !== false) or (stristr($e,"src=") !== false) ) {
13267 $regexp = '/ (href|src)\s*=\s*"(.*?)"/i';
13268 preg_match($regexp,$e,$auxiliararray);
13269 if (isset($auxiliararray[2])) { $path = $auxiliararray[2]; }
13270 else { $path = ''; }
13271 if (trim($path) != '' && !(stristr($e,"src=") !== false && substr($path,0,4)=='var:')) {
13272 $orig_srcpath = $path;
13273 $this->GetFullPath($path);
13274 $regexp = '/ (href|src)="(.*?)"/i';
13275 $e = preg_replace($regexp,' \\1="'.$path.'"',$e);
13276 }
13277 }//END of Fix path values
13278
13279
13280 //Extract attributes
13281 $contents=array();
13282 $contents1=array(); // mPDF 5.5.17
13283 $contents2=array();
13284 // Changed to allow style="background: url('bg.jpg')"
13285 // mPDF 5.5.17 Changed to improve performance; maximum length of \S (attribute) = 16
13286 // mPDF 5.6.30 Increase allowed attribute name to 32 - cutting off "toc-even-header-name" etc.
13287 preg_match_all('/\\S{1,32}=["][^"]*["]/',$e,$contents1);
13288 preg_match_all('/\\S{1,32}=[\'][^\']*[\']/i',$e,$contents2);
13289
13290 $contents = array_merge($contents1, $contents2);
13291 preg_match('/\\S+/',$e,$a2);
13292 $tag=strtoupper($a2[0]);
13293 $attr=array();
13294 if ($orig_srcpath) { $attr['ORIG_SRC'] = $orig_srcpath; }
13295 if (!empty($contents)) {
13296 foreach($contents[0] as $v) {
13297 // Changed to allow style="background: url('bg.jpg')"
13298 if(preg_match('/^([^=]*)=["]?([^"]*)["]?$/',$v,$a3) || preg_match('/^([^=]*)=[\']?([^\']*)[\']?$/',$v,$a3)) {
13299 if (strtoupper($a3[1])=='ID' || strtoupper($a3[1])=='CLASS') { // 4.2.013 Omits STYLE
13300 $attr[strtoupper($a3[1])]=trim(strtoupper($a3[2]));
13301 }
13302 // includes header-style-right etc. used for <pageheader>
13303 else if (preg_match('/^(HEADER|FOOTER)-STYLE/i',$a3[1])) {
13304 $attr[strtoupper($a3[1])]=trim(strtoupper($a3[2]));
13305 }
13306 else {
13307 $attr[strtoupper($a3[1])]=trim($a3[2]);
13308 }
13309 }
13310 }
13311 }
13312 $this->OpenTag($tag,$attr);
13313 /*-- CSS-POSITION --*/
13314 if ($this->inFixedPosBlock) {
13315 $this->fixedPosBlockBBox = array($tag,$attr, $this->x, $this->y);
13316 $this->fixedPosBlock = '';
13317 $this->fixedPosBlockDepth = 1;
13318 }
13319 /*-- END CSS-POSITION --*/
13320 // mPDF 5.5.09
13321 if (preg_match('/\/$/',$e)) { $this->closeTag($tag); }
13322
13323 }
13324
13325 } // end TAG
13326 } //end of foreach($a as $i=>$e)
13327
13328 if ($close) {
13329
13330 // Close any open block tags
13331 for ($b= $this->blklvl;$b>0;$b--) { $this->CloseTag($this->blk[$b]['tag']); }
13332
13333 // Output any text left in buffer
13334 if (count($this->textbuffer) && !$parseonly) { $this->printbuffer($this->textbuffer); }
13335 if (!$parseonly) $this->textbuffer=array();
13336
13337 /*-- CSS-FLOAT --*/
13338 // If ended with a float, need to move to end page
13339 $currpos = $this->page*1000 + $this->y;
13340 if (isset($this->blk[$this->blklvl]['float_endpos']) && $this->blk[$this->blklvl]['float_endpos'] > $currpos) {
13341 $old_page = $this->page;
13342 $new_page = intval($this->blk[$this->blklvl]['float_endpos'] /1000);
13343 if ($old_page != $new_page) {
13344 $s = $this->PrintPageBackgrounds();
13345 // Writes after the marker so not overwritten later by page background etc.
13346 $this->pages[$this->page] = preg_replace('/(___BACKGROUND___PATTERNS'.date('jY').')/', '\\1'."\n".$s."\n", $this->pages[$this->page]);
13347 $this->pageBackgrounds = array();
13348 $this->page = $new_page;
13349 $this->ResetMargins();
13350 $this->Reset();
13351 $this->pageoutput[$this->page] = array();
13352 }
13353 $this->y = (($this->blk[$this->blklvl]['float_endpos'] *1000) % 1000000)/1000; // mod changes operands to integers before processing
13354 }
13355 /*-- END CSS-FLOAT --*/
13356
13357 /*-- CSS-IMAGE-FLOAT --*/
13358 $this->printfloatbuffer();
13359 /*-- END CSS-IMAGE-FLOAT --*/
13360
13361 //Create Internal Links, if needed
13362 if (!empty($this->internallink) ) {
13363 foreach($this->internallink as $k=>$v) {
13364 if (strpos($k,"#") !== false ) { continue; } //ignore
13365 $ypos = $v['Y'];
13366 $pagenum = $v['PAGE'];
13367 $sharp = "#";
13368 while (array_key_exists($sharp.$k,$this->internallink)) {
13369 $internallink = $this->internallink[$sharp.$k];
13370 $this->SetLink($internallink,$ypos,$pagenum);
13371 $sharp .= "#";
13372 }
13373 }
13374 }
13375
13376 $this->linemaxfontsize = '';
13377 $this->lineheight_correction = $this->default_lineheight_correction;
13378
13379 $this->bufferoutput = false;
13380
13381 /*-- CSS-POSITION --*/
13382 if (count($this->fixedPosBlockSave) && $sub != 4) {
13383 foreach($this->fixedPosBlockSave AS $fpbs) {
13384 $old_page = $this->page;
13385 $this->page = $fpbs[2];
13386 $this->WriteFixedPosHTML($fpbs[0], 0, 0, 100, 100,'auto', $fpbs[1]); // 0,0,10,10 are overwritten by bbox
13387 $this->page = $old_page;
13388 }
13389 }
13390 /*-- END CSS-POSITION --*/
13391
13392 }
13393 }
13394
13395 /*-- CSS-POSITION --*/
13396
13397 function WriteFixedPosHTML($html='',$x, $y, $w, $h, $overflow='visible', $bounding=array()) {
13398 // $overflow can be 'hidden', 'visible' or 'auto' - 'auto' causes autofit to size
13399 // Annotations disabled - enabled in mPDF 5.0
13400 // Links do work
13401 // Will always go on current page (or start Page 1 if required)
13402 // Probably INCOMPATIBLE WITH keep with table, columns etc.
13403 // Called externally or interally via <div style="position: [fixed|absolute]">
13404 // When used internally, $x $y $w $h and $overflow are all overridden by $bounding
13405
13406 $overflow = strtolower($overflow);
13407 if($this->state==0) {
13408 $this->AddPage($this->CurOrientation);
13409 }
13410 $save_y = $this->y;
13411 $save_x = $this->x;
13412 $this->fullImageHeight = $this->h;
13413 $save_cols = false;
13414 /*-- COLUMNS --*/
13415 if ($this->ColActive) {
13416 $save_cols = true;
13417 $save_nbcol = $this->NbCol; // other values of gap and vAlign will not change by setting Columns off
13418 $this->SetColumns(0);
13419 }
13420 /*-- END COLUMNS --*/
13421 $save_annots = $this->title2annots; // *ANNOTATIONS*
13422 $this->writingHTMLheader = true; // a FIX to stop pagebreaks etc.
13423 $this->writingHTMLfooter = true;
13424 $this->InFooter = true; // suppresses autopagebreaks
13425 $save_bgs = $this->pageBackgrounds;
13426 $checkinnerhtml = preg_replace('/\s/','',$html);
13427
13428 if ($w > $this->w) { $x = 0; $w = $this->w; }
13429 if ($h > $this->h) { $y = 0; $h = $this->h; }
13430 if ($x > $this->w) { $x = $this->w - $w; }
13431 if ($y > $this->h) { $y = $this->h - $h; }
13432
13433 if (!empty($bounding)) {
13434 // $cont_ containing block = full physical page (position: absolute) or page inside margins (position: fixed)
13435 // $bbox_ Bounding box is the <div> which is positioned absolutely/fixed
13436 // top/left/right/bottom/width/height/background*/border*/padding*/margin* are taken from bounding
13437 // font*[family/size/style/weight]/line-height/text*[align/decoration/transform/indent]/color are transferred to $inner
13438 // as an enclosing <div> (after having checked ID/CLASS)
13439 // $x, $y, $w, $h are inside of $bbox_ = containing box for $inner_
13440 // $inner_ InnerHTML is the contents of that block to be output
13441 $tag = $bounding[0];
13442 $attr = $bounding[1];
13443 $orig_x0 = $bounding[2];
13444 $orig_y0 = $bounding[3];
13445
13446 // As in WriteHTML() initialising
13447 $this->blklvl = 0;
13448 $this->lastblocklevelchange = 0;
13449 $this->blk = array();
13450 $this->initialiseBlock($this->blk[0]);
13451
13452 $this->blk[0]['width'] =& $this->pgwidth;
13453 $this->blk[0]['inner_width'] =& $this->pgwidth;
13454
13455 $this->blk[0]['blockContext'] = $this->blockContext;
13456
13457 $properties = $this->cssmgr->MergeCSS('BLOCK','BODY','');
13458 $this->setCSS($properties,'','BODY');
13459 $this->blklvl = 1;
13460 $this->initialiseBlock($this->blk[1]);
13461 $this->blk[1]['tag'] = $tag;
13462 $this->blk[1]['attr'] = $attr;
13463 $this->Reset();
13464 $p = $this->cssmgr->MergeCSS('BLOCK',$tag,$attr);
13465 if (isset($p['ROTATE']) && ($p['ROTATE']==90 || $p['ROTATE']==-90)) { $rotate = $p['ROTATE']; }
13466 else { $rotate = 0; }
13467 if (isset($p['OVERFLOW'])) { $overflow = strtolower($p['OVERFLOW']); }
13468 if (strtolower($p['POSITION']) == 'fixed') {
13469 $cont_w = $this->pgwidth; // $this->blk[0]['inner_width'];
13470 $cont_h = $this->h - $this->tMargin - $this->bMargin;
13471 $cont_x = $this->lMargin;
13472 $cont_y = $this->tMargin;
13473 }
13474 else {
13475 $cont_w = $this->w; // ABSOLUTE;
13476 $cont_h = $this->h;
13477 $cont_x = 0;
13478 $cont_y = 0;
13479 }
13480
13481 // Pass on in-line properties to the innerhtml
13482 $css = '';
13483 if (isset($p['TEXT-ALIGN'])) { $css .= 'text-align: '.strtolower($p['TEXT-ALIGN']).'; '; }
13484 if (isset($p['TEXT-TRANSFORM'])) { $css .= 'text-transform: '.strtolower($p['TEXT-TRANSFORM']).'; '; }
13485 if (isset($p['TEXT-INDENT'])) { $css .= 'text-indent: '.strtolower($p['TEXT-INDENT']).'; '; }
13486 if (isset($p['TEXT-DECORATION'])) { $css .= 'text-decoration: '.strtolower($p['TEXT-DECORATION']).'; '; }
13487 if (isset($p['FONT-FAMILY'])) { $css .= 'font-family: '.strtolower($p['FONT-FAMILY']).'; '; }
13488 if (isset($p['FONT-STYLE'])) { $css .= 'font-style: '.strtolower($p['FONT-STYLE']).'; '; }
13489 if (isset($p['FONT-WEIGHT'])) { $css .= 'font-weight: '.strtolower($p['FONT-WEIGHT']).'; '; }
13490 if (isset($p['FONT-SIZE'])) { $css .= 'font-size: '.strtolower($p['FONT-SIZE']).'; '; }
13491 if (isset($p['LINE-HEIGHT'])) { $css .= 'line-height: '.strtolower($p['LINE-HEIGHT']).'; '; }
13492 if (isset($p['TEXT-SHADOW'])) { $css .= 'text-shadow: '.strtolower($p['TEXT-SHADOW']).'; '; }
13493 if (isset($p['LETTER-SPACING'])) { $css .= 'letter-spacing: '.strtolower($p['LETTER-SPACING']).'; '; }
13494 if (isset($p['FONT-VARIANT'])) { $css .= 'font-variant: '.strtolower($p['FONT-VARIANT']).'; '; }
13495 if (isset($p['COLOR'])) { $css .= 'color: '.strtolower($p['COLOR']).'; '; }
13496 if (isset($p['Z-INDEX'])) { $css .= 'z-index: '.$p['Z-INDEX'].'; '; } // mPDF 5.6.01
13497 if ($css) {
13498 $html = '<div style="'.$css.'">'.$html.'</div>';
13499 }
13500 // Copy over (only) the properties to set for border and background
13501 $pb = array();
13502 $pb['MARGIN-TOP'] = $p['MARGIN-TOP'];
13503 $pb['MARGIN-RIGHT'] = $p['MARGIN-RIGHT'];
13504 $pb['MARGIN-BOTTOM'] = $p['MARGIN-BOTTOM'];
13505 $pb['MARGIN-LEFT'] = $p['MARGIN-LEFT'];
13506 $pb['PADDING-TOP'] = $p['PADDING-TOP'];
13507 $pb['PADDING-RIGHT'] = $p['PADDING-RIGHT'];
13508 $pb['PADDING-BOTTOM'] = $p['PADDING-BOTTOM'];
13509 $pb['PADDING-LEFT'] = $p['PADDING-LEFT'];
13510 $pb['BORDER-TOP'] = $p['BORDER-TOP'];
13511 $pb['BORDER-RIGHT'] = $p['BORDER-RIGHT'];
13512 $pb['BORDER-BOTTOM'] = $p['BORDER-BOTTOM'];
13513 $pb['BORDER-LEFT'] = $p['BORDER-LEFT'];
13514 $pb['BORDER-TOP-LEFT-RADIUS-H'] = $p['BORDER-TOP-LEFT-RADIUS-H'];
13515 $pb['BORDER-TOP-LEFT-RADIUS-V'] = $p['BORDER-TOP-LEFT-RADIUS-V'];
13516 $pb['BORDER-TOP-RIGHT-RADIUS-H'] = $p['BORDER-TOP-RIGHT-RADIUS-H'];
13517 $pb['BORDER-TOP-RIGHT-RADIUS-V'] = $p['BORDER-TOP-RIGHT-RADIUS-V'];
13518 $pb['BORDER-BOTTOM-LEFT-RADIUS-H'] = $p['BORDER-BOTTOM-LEFT-RADIUS-H'];
13519 $pb['BORDER-BOTTOM-LEFT-RADIUS-V'] = $p['BORDER-BOTTOM-LEFT-RADIUS-V'];
13520 $pb['BORDER-BOTTOM-RIGHT-RADIUS-H'] = $p['BORDER-BOTTOM-RIGHT-RADIUS-H'];
13521 $pb['BORDER-BOTTOM-RIGHT-RADIUS-V'] = $p['BORDER-BOTTOM-RIGHT-RADIUS-V'];
13522 if (isset($p['BACKGROUND-COLOR'])) { $pb['BACKGROUND-COLOR'] = $p['BACKGROUND-COLOR']; }
13523 if (isset($p['BOX-SHADOW'])) { $pb['BOX-SHADOW'] = $p['BOX-SHADOW']; }
13524 /*-- BACKGROUNDS --*/
13525 if (isset($p['BACKGROUND-IMAGE'])) { $pb['BACKGROUND-IMAGE'] = $p['BACKGROUND-IMAGE']; }
13526 if (isset($p['BACKGROUND-IMAGE-RESIZE'])) { $pb['BACKGROUND-IMAGE-RESIZE'] = $p['BACKGROUND-IMAGE-RESIZE']; }
13527 if (isset($p['BACKGROUND-IMAGE-OPACITY'])) { $pb['BACKGROUND-IMAGE-OPACITY'] = $p['BACKGROUND-IMAGE-OPACITY']; }
13528 if (isset($p['BACKGROUND-REPEAT'])) { $pb['BACKGROUND-REPEAT'] = $p['BACKGROUND-REPEAT']; }
13529 if (isset($p['BACKGROUND-POSITION'])) { $pb['BACKGROUND-POSITION'] = $p['BACKGROUND-POSITION']; }
13530 if (isset($p['BACKGROUND-GRADIENT'])) { $pb['BACKGROUND-GRADIENT'] = $p['BACKGROUND-GRADIENT']; }
13531 if (isset($p['BACKGROUND-SIZE'])) { $pb['BACKGROUND-SIZE'] = $p['BACKGROUND-SIZE']; } // mPDF 5.6.12
13532 if (isset($p['BACKGROUND-ORIGIN'])) { $pb['BACKGROUND-ORIGIN'] = $p['BACKGROUND-ORIGIN']; } // mPDF 5.6.12
13533 if (isset($p['BACKGROUND-CLIP'])) { $pb['BACKGROUND-CLIP'] = $p['BACKGROUND-CLIP']; } // mPDF 5.6.12
13534
13535 /*-- END BACKGROUNDS --*/
13536
13537 $this->setCSS($pb,'BLOCK',$tag);
13538
13539 //================================================================
13540 $bbox_br = $this->blk[1]['border_right']['w'];
13541 $bbox_bl = $this->blk[1]['border_left']['w'];
13542 $bbox_bt = $this->blk[1]['border_top']['w'];
13543 $bbox_bb = $this->blk[1]['border_bottom']['w'];
13544 $bbox_pr = $this->blk[1]['padding_right'];
13545 $bbox_pl = $this->blk[1]['padding_left'];
13546 $bbox_pt = $this->blk[1]['padding_top'];
13547 $bbox_pb = $this->blk[1]['padding_bottom'];
13548 $bbox_mr = $this->blk[1]['margin_right'];
13549 if (strtolower($p['MARGIN-RIGHT'])=='auto') { $bbox_mr = 'auto'; }
13550 $bbox_ml = $this->blk[1]['margin_left'];
13551 if (strtolower($p['MARGIN-LEFT'])=='auto') { $bbox_ml = 'auto'; }
13552 $bbox_mt = $this->blk[1]['margin_top'];
13553 if (strtolower($p['MARGIN-TOP'])=='auto') { $bbox_mt = 'auto'; }
13554 $bbox_mb = $this->blk[1]['margin_bottom'];
13555 if (strtolower($p['MARGIN-BOTTOM'])=='auto') { $bbox_mb = 'auto'; }
13556 if (isset($p['LEFT']) && strtolower($p['LEFT'])!='auto') { $bbox_left = $this->ConvertSize($p['LEFT'], $cont_w, $this->FontSize,false); }
13557 else { $bbox_left = 'auto'; }
13558 if (isset($p['TOP']) && strtolower($p['TOP'])!='auto') { $bbox_top = $this->ConvertSize($p['TOP'], $cont_h, $this->FontSize,false); }
13559 else { $bbox_top = 'auto'; }
13560 if (isset($p['RIGHT']) && strtolower($p['RIGHT'])!='auto') { $bbox_right = $this->ConvertSize($p['RIGHT'], $cont_w, $this->FontSize,false); }
13561 else { $bbox_right = 'auto'; }
13562 if (isset($p['BOTTOM']) && strtolower($p['BOTTOM'])!='auto') { $bbox_bottom = $this->ConvertSize($p['BOTTOM'], $cont_h, $this->FontSize,false); }
13563 else { $bbox_bottom = 'auto'; }
13564 if (isset($p['WIDTH']) && strtolower($p['WIDTH'])!='auto') { $inner_w = $this->ConvertSize($p['WIDTH'], $cont_w, $this->FontSize,false); }
13565 else { $inner_w = 'auto'; }
13566 if (isset($p['HEIGHT']) && strtolower($p['HEIGHT'])!='auto') { $inner_h = $this->ConvertSize($p['HEIGHT'], $cont_h, $this->FontSize,false); }
13567 else { $inner_h = 'auto'; }
13568
13569 // If bottom or right pos are set and not left / top - save this to adjust rotated block later
13570 if ($rotate) {
13571 if ($bbox_left === 'auto' && $bbox_right !== 'auto') { $rot_rpos = $bbox_right; }
13572 else { $rot_rpos = false; }
13573 if ($bbox_top === 'auto' && $bbox_bottom !== 'auto') { $rot_bpos = $bbox_bottom; }
13574 else { $rot_bpos = false; }
13575 }
13576
13577 //================================================================
13578 if ($checkinnerhtml=='' && $inner_h==='auto') { $inner_h = 0.0001; }
13579 if ($checkinnerhtml=='' && $inner_w==='auto') { $inner_w = 2*$this->GetCharWidth('W',false); }
13580 //================================================================
13581 // Algorithm from CSS2.1 See http://www.w3.org/TR/CSS21/visudet.html#abs-non-replaced-height
13582 // mPD 5.3.14
13583 // Special case (not CSS) if all not specified, centre vertically on page
13584 if ($bbox_top==='auto' && $inner_h==='auto' && $bbox_bottom==='auto' && $bbox_mt==='auto' && $bbox_mb==='auto') {
13585 $bbox_top_orig = $bbox_top;
13586 if ($bbox_mt==='auto') { $bbox_mt = 0; }
13587 if ($bbox_mb==='auto') { $bbox_mb = 0; }
13588 $bbox_top = $orig_y0 - $bbox_mt - $cont_y;
13589 // solve for $bbox_bottom when content_h known - $inner_h=='auto' && $bbox_bottom=='auto'
13590 }
13591 // mPD 5.3.14
13592 else if ($bbox_top==='auto' && $inner_h==='auto' && $bbox_bottom==='auto') {
13593 $bbox_top_orig = $bbox_top = $orig_y0 - $cont_y;
13594 if ($bbox_mt==='auto') { $bbox_mt = 0; }
13595 if ($bbox_mb==='auto') { $bbox_mb = 0; }
13596 // solve for $bbox_bottom when content_h known - $inner_h=='auto' && $bbox_bottom=='auto'
13597 }
13598 else if ($bbox_top!=='auto' && $inner_h!=='auto' && $bbox_bottom!=='auto') {
13599 if ($bbox_mt==='auto' && $bbox_mb==='auto') {
13600 $x = $cont_h - $bbox_top - $bbox_bt - $bbox_pt - $inner_h - $bbox_pb - $bbox_bb - $bbox_bottom;
13601 $bbox_mt = $bbox_mb = ($x/2);
13602 }
13603 else if ($bbox_mt==='auto') {
13604 $bbox_mt = $cont_h - $bbox_top - $bbox_bt - $bbox_pt - $inner_h - $bbox_pb - $bbox_bb - $bbox_mb - $bbox_bottom;
13605 }
13606 else if ($bbox_mb==='auto') {
13607 $bbox_mb = $cont_h - $bbox_top - $bbox_mt - $bbox_bt - $bbox_pt - $inner_h - $bbox_pb - $bbox_bb - $bbox_bottom;
13608 }
13609 else {
13610 $bbox_bottom = $cont_h - $bbox_top - $bbox_mt - $bbox_bt - $bbox_pt - $inner_h - $bbox_pb - $bbox_bb - $bbox_mt;
13611 }
13612 }
13613 else {
13614 if ($bbox_mt==='auto') { $bbox_mt = 0; }
13615 if ($bbox_mb==='auto') { $bbox_mb = 0; }
13616 if ($bbox_top==='auto' && $inner_h==='auto' && $bbox_bottom!=='auto') {
13617 // solve for $bbox_top when content_h known - $inner_h=='auto' && $bbox_top =='auto'
13618 }
13619 else if ($bbox_top==='auto' && $bbox_bottom==='auto' && $inner_h!=='auto') {
13620 $bbox_top = $orig_y0 - $bbox_mt - $cont_y;
13621 $bbox_bottom = $cont_h - $bbox_top - $bbox_mt - $bbox_bt - $bbox_pt - $inner_h - $bbox_pb - $bbox_bb - $bbox_mt;
13622 }
13623 else if ($inner_h==='auto' && $bbox_bottom==='auto' && $bbox_top!=='auto') {
13624 // solve for $bbox_bottom when content_h known - $inner_h=='auto' && $bbox_bottom=='auto'
13625 }
13626 else if ($bbox_top==='auto' && $inner_h!=='auto' && $bbox_bottom!=='auto') {
13627 $bbox_top = $cont_h - $bbox_mt - $bbox_bt - $bbox_pt - $inner_h - $bbox_pb - $bbox_bb - $bbox_mt - $bbox_bottom;
13628 }
13629 else if ($inner_h==='auto' && $bbox_top!=='auto' && $bbox_bottom!=='auto') {
13630 $inner_h = $cont_h - $bbox_top - $bbox_mt - $bbox_bt - $bbox_pt - $bbox_pb - $bbox_bb - $bbox_mt - $bbox_bottom;
13631 }
13632 else if ($bbox_bottom==='auto' && $bbox_top!=='auto' && $inner_h!=='auto') {
13633 $bbox_bottom = $cont_h - $bbox_top - $bbox_mt - $bbox_bt - $bbox_pt - $inner_h - $bbox_pb - $bbox_bb - $bbox_mt;
13634 }
13635 }
13636
13637 // THEN DO SAME FOR WIDTH
13638 // http://www.w3.org/TR/CSS21/visudet.html#abs-non-replaced-width
13639 if ($bbox_left==='auto' && $inner_w==='auto' && $bbox_right==='auto') {
13640 if ($bbox_ml==='auto') { $bbox_ml = 0; }
13641 if ($bbox_mr==='auto') { $bbox_mr = 0; }
13642 // IF containing element RTL, should set $bbox_right
13643 $bbox_left = $orig_x0 - $bbox_ml - $cont_x;
13644 // solve for $bbox_right when content_w known - $inner_w=='auto' && $bbox_right=='auto'
13645 }
13646 else if ($bbox_left!=='auto' && $inner_w!=='auto' && $bbox_right!=='auto') {
13647 if ($bbox_ml==='auto' && $bbox_mr==='auto') {
13648 $x = $cont_w - $bbox_left - $bbox_bl - $bbox_pl - $inner_w - $bbox_pr - $bbox_br - $bbox_right;
13649 $bbox_ml = $bbox_mr = ($x/2);
13650 }
13651 else if ($bbox_ml==='auto') {
13652 $bbox_ml = $cont_w - $bbox_left - $bbox_bl - $bbox_pl - $inner_w - $bbox_pr - $bbox_br - $bbox_mr - $bbox_right;
13653 }
13654 else if ($bbox_mr==='auto') {
13655 $bbox_mr = $cont_w - $bbox_left - $bbox_ml - $bbox_bl - $bbox_pl - $inner_w - $bbox_pr - $bbox_br - $bbox_right;
13656 }
13657 else {
13658 $bbox_right = $cont_w - $bbox_left - $bbox_ml - $bbox_bl - $bbox_pl - $inner_w - $bbox_pr - $bbox_br - $bbox_ml;
13659 }
13660 }
13661 else {
13662 if ($bbox_ml==='auto') { $bbox_ml = 0; }
13663 if ($bbox_mr==='auto') { $bbox_mr = 0; }
13664 if ($bbox_left==='auto' && $inner_w==='auto' && $bbox_right!=='auto') {
13665 // solve for $bbox_left when content_w known - $inner_w=='auto' && $bbox_left =='auto'
13666 }
13667 else if ($bbox_left==='auto' && $bbox_right==='auto' && $inner_w!=='auto') {
13668 // IF containing element RTL, should set $bbox_right
13669 $bbox_left = $orig_x0 - $bbox_ml - $cont_x;
13670 $bbox_right = $cont_w - $bbox_left - $bbox_ml - $bbox_bl - $bbox_pl - $inner_w - $bbox_pr - $bbox_br - $bbox_ml;
13671 }
13672 else if ($inner_w==='auto' && $bbox_right==='auto' && $bbox_left!=='auto') {
13673 // solve for $bbox_right when content_w known - $inner_w=='auto' && $bbox_right=='auto'
13674 }
13675 else if ($bbox_left==='auto' && $inner_w!=='auto' && $bbox_right!=='auto') {
13676 $bbox_left = $cont_w - $bbox_ml - $bbox_bl - $bbox_pl - $inner_w - $bbox_pr - $bbox_br - $bbox_ml - $bbox_right;
13677 }
13678 else if ($inner_w==='auto' && $bbox_left!=='auto' && $bbox_right!=='auto') {
13679 $inner_w = $cont_w - $bbox_left - $bbox_ml - $bbox_bl - $bbox_pl - $bbox_pr - $bbox_br - $bbox_ml - $bbox_right;
13680 }
13681 else if ($bbox_right==='auto' && $bbox_left!=='auto' && $inner_w!=='auto') {
13682 $bbox_right = $cont_w - $bbox_left - $bbox_ml - $bbox_bl - $bbox_pl - $inner_w - $bbox_pr - $bbox_br - $bbox_ml;
13683 }
13684 }
13685
13686 //================================================================
13687 //================================================================
13688 /*-- BACKGROUNDS --*/
13689 if (isset($pb['BACKGROUND-IMAGE']) && $pb['BACKGROUND-IMAGE']) {
13690 $ret = $this->SetBackground($pb, $this->blk[1]['inner_width']);
13691 if ($ret) { $this->blk[1]['background-image'] = $ret; }
13692 }
13693 /*-- END BACKGROUNDS --*/
13694
13695 //================================================================
13696 $y = $cont_y + $bbox_top + $bbox_mt + $bbox_bt + $bbox_pt;
13697 $h = $cont_h - $bbox_top - $bbox_mt - $bbox_bt - $bbox_pt - $bbox_pb - $bbox_bb - $bbox_mb - $bbox_bottom;
13698 $x = $cont_x + $bbox_left + $bbox_ml + $bbox_bl + $bbox_pl;
13699 $w = $cont_w - $bbox_left - $bbox_ml - $bbox_bl - $bbox_pl - $bbox_pr - $bbox_br - $bbox_mr - $bbox_right;
13700 // Set (temporary) values for x y w h to do first paint, if values are auto
13701 if ($inner_h==='auto' && $bbox_top==='auto') {
13702 $y = $cont_y + $bbox_mt + $bbox_bt + $bbox_pt;
13703 $h = $cont_h - ($bbox_bottom + $bbox_mt + $bbox_mb + $bbox_bt + $bbox_bb + $bbox_pt + $bbox_pb);
13704 }
13705 else if ($inner_h==='auto' && $bbox_bottom==='auto') {
13706 $y = $cont_y + $bbox_top + $bbox_mt + $bbox_bt + $bbox_pt;
13707 $h = $cont_h - ($bbox_top + $bbox_mt + $bbox_mb + $bbox_bt + $bbox_bb + $bbox_pt + $bbox_pb);
13708 }
13709 if ($inner_w==='auto' && $bbox_left==='auto') {
13710 $x = $cont_x + $bbox_ml + $bbox_bl + $bbox_pl;
13711 $w = $cont_w - ($bbox_right + $bbox_ml + $bbox_mr + $bbox_bl + $bbox_br + $bbox_pl + $bbox_pr);
13712 }
13713 else if ($inner_w==='auto' && $bbox_right==='auto') {
13714 $x = $cont_x + $bbox_left + $bbox_ml + $bbox_bl + $bbox_pl;
13715 $w = $cont_w - ($bbox_left + $bbox_ml + $bbox_mr + $bbox_bl + $bbox_br + $bbox_pl + $bbox_pr);
13716 }
13717 $bbox_y = $cont_y + $bbox_top + $bbox_mt;
13718 $bbox_x = $cont_x + $bbox_left + $bbox_ml;
13719 $saved_block1 = $this->blk[1];
13720 unset($p);
13721 unset($pb);
13722 //================================================================
13723 if ($inner_w==='auto') { // do a first write
13724 $this->lMargin=$x;
13725 $this->rMargin=$this->w - $w - $x;
13726 // SET POSITION & FONT VALUES
13727 $this->pgwidth = $this->w - $this->lMargin - $this->rMargin;
13728 $this->pageoutput[$this->page]=array();
13729 $this->x = $x;
13730 $this->y = $y;
13731 $this->HTMLheaderPageLinks = array();
13732 $this->HTMLheaderPageAnnots = array();
13733 $this->HTMLheaderPageForms = array();
13734 $this->pageBackgrounds = array();
13735 $this->maxPosR = 0;
13736 $this->maxPosL = $this->w; // For RTL
13737 $this->WriteHTML($html , 4);
13738 $inner_w = $this->maxPosR - $this->lMargin;
13739 if ($bbox_right==='auto') {
13740 $bbox_right = $cont_w - $bbox_left - $bbox_ml - $bbox_bl - $bbox_pl - $inner_w - $bbox_pr - $bbox_br - $bbox_ml;
13741 }
13742 else if ($bbox_left==='auto') {
13743 $bbox_left = $cont_w - $bbox_ml - $bbox_bl - $bbox_pl - $inner_w - $bbox_pr - $bbox_br - $bbox_ml - $bbox_right;
13744 $bbox_x = $cont_x + $bbox_left + $bbox_ml ;
13745 $inner_x = $bbox_x + $bbox_bl + $bbox_pl;
13746 $x = $inner_x;
13747 }
13748 $w = $inner_w;
13749 $bbox_y = $cont_y + $bbox_top + $bbox_mt;
13750 $bbox_x = $cont_x + $bbox_left + $bbox_ml;
13751 }
13752
13753 if ($inner_h==='auto') { // do a first write
13754 $this->lMargin=$x;
13755 $this->rMargin=$this->w - $w - $x;
13756 // SET POSITION & FONT VALUES
13757 $this->pgwidth = $this->w - $this->lMargin - $this->rMargin;
13758 $this->pageoutput[$this->page]=array();
13759 $this->x = $x;
13760 $this->y = $y;
13761 $this->HTMLheaderPageLinks = array();
13762 $this->HTMLheaderPageAnnots = array();
13763 $this->HTMLheaderPageForms = array();
13764 $this->pageBackgrounds = array();
13765 $this->WriteHTML($html , 4);
13766 $inner_h = $this->y - $y;
13767 if ($overflow!='hidden' && $overflow!='visible') { // constrained
13768 if (($this->y + $bbox_pb + $bbox_bb) > ($cont_y + $cont_h)) {
13769 $adj = ($this->y + $bbox_pb + $bbox_bb) - ($cont_y + $cont_h);
13770 $inner_h -= $adj;
13771 }
13772 }
13773 if ($bbox_bottom==='auto' && $bbox_top_orig==='auto') {
13774 $bbox_bottom = $bbox_top = ($cont_h - $bbox_mt - $bbox_bt - $bbox_pt - $inner_h - $bbox_pb - $bbox_bb - $bbox_mb)/2;
13775 if ($overflow!='hidden' && $overflow!='visible') { // constrained
13776 if ($bbox_top < 0) {
13777 $bbox_top = 0;
13778 $inner_h = $cont_h - $bbox_top - $bbox_mt - $bbox_bt - $bbox_pt - $bbox_pb - $bbox_bb - $bbox_mb - $bbox_bottom;
13779 }
13780 }
13781 $bbox_y = $cont_y + $bbox_top + $bbox_mt;
13782 $inner_y = $bbox_y + $bbox_bt + $bbox_pt;
13783 $y = $inner_y;
13784
13785 }
13786 else if ($bbox_bottom==='auto') {
13787 $bbox_bottom = $cont_h - $bbox_top - $bbox_mt - $bbox_bt - $bbox_pt - $inner_h - $bbox_pb - $bbox_bb - $bbox_mb;
13788 }
13789 else if ($bbox_top==='auto') {
13790 $bbox_top = $cont_h - $bbox_mt - $bbox_bt - $bbox_pt - $inner_h - $bbox_pb - $bbox_bb - $bbox_mb - $bbox_bottom;
13791 if ($overflow!='hidden' && $overflow!='visible') { // constrained
13792 if ($bbox_top < 0) {
13793 $bbox_top = 0;
13794 $inner_h = $cont_h - $bbox_top - $bbox_mt - $bbox_bt - $bbox_pt - $bbox_pb - $bbox_bb - $bbox_mb - $bbox_bottom;
13795 }
13796 }
13797 $bbox_y = $cont_y + $bbox_top + $bbox_mt;
13798 $inner_y = $bbox_y + $bbox_bt + $bbox_pt;
13799 $y = $inner_y;
13800 }
13801 $h = $inner_h;
13802 $bbox_y = $cont_y + $bbox_top + $bbox_mt;
13803 $bbox_x = $cont_x + $bbox_left + $bbox_ml;
13804 }
13805 $inner_w = $w;
13806 $inner_h = $h;
13807
13808 }
13809 $this->lMargin=$x;
13810 $this->rMargin=$this->w - $w - $x;
13811 // SET POSITION & FONT VALUES
13812 $this->pgwidth = $this->w - $this->lMargin - $this->rMargin;
13813 $this->pageoutput[$this->page]=array();
13814 $this->x = $x;
13815 $this->y = $y;
13816 $this->HTMLheaderPageLinks = array();
13817 $this->HTMLheaderPageAnnots = array();
13818 $this->HTMLheaderPageForms = array();
13819 $this->pageBackgrounds = array();
13820 $this->WriteHTML($html , 4); // parameter 4 saves output to $this->headerbuffer
13821 $actual_h = $this->y - $y;
13822 $use_w = $w;
13823 $use_h = $h;
13824 $ratio = $actual_h / $use_w;
13825
13826 if ($overflow!='hidden' && $overflow!='visible') {
13827 $target = $h/$w;
13828 if (($ratio / $target ) > 1) {
13829 $nl = CEIL($actual_h / $this->lineheight);
13830 $l = $use_w * $nl;
13831 $est_w = sqrt(($l * $this->lineheight) / $target) * 0.8;
13832 $use_w += ($est_w - $use_w) - ($w/100);
13833 }
13834 $bpcstart = ($ratio / $target);
13835 $bpcctr = 1;
13836 while(($ratio / $target ) > 1) {
13837
13838 if ($this->progressBar) { $this->UpdateProgressBar(4,intval(100/($ratio/$target)),('Auto-sizing fixed-position block: '.$bpcctr++)); } // *PROGRESS-BAR*
13839
13840 $this->x = $x;
13841 $this->y = $y;
13842
13843 if (($ratio / $target) > 1.5 || ($ratio / $target) < 0.6) {
13844 $use_w += ($w/$this->incrementFPR1);
13845 }
13846 else if (($ratio / $target) > 1.2 || ($ratio / $target) < 0.85) {
13847 $use_w += ($w/$this->incrementFPR2);
13848 }
13849 else if (($ratio / $target) > 1.1 || ($ratio / $target) < 0.91) {
13850 $use_w += ($w/$this->incrementFPR3);
13851 }
13852 else {
13853 $use_w += ($w/$this->incrementFPR4);
13854 }
13855
13856 $use_h = $use_w * $target ;
13857 $this->rMargin=$this->w - $use_w - $x;
13858 $this->pgwidth = $this->w - $this->lMargin - $this->rMargin;
13859 $this->HTMLheaderPageLinks = array();
13860 $this->HTMLheaderPageAnnots = array();
13861 $this->HTMLheaderPageForms = array();
13862 $this->pageBackgrounds = array();
13863 $this->WriteHTML($html , 4); // parameter 4 saves output to $this->headerbuffer
13864 $actual_h = $this->y - $y;
13865 $ratio = $actual_h / $use_w;
13866 }
13867 if ($this->progressBar) { $this->UpdateProgressBar(4,'100',' '); } // *PROGRESS-BAR*
13868 }
13869 $shrink_f = $w/$use_w;
13870
13871 //================================================================
13872
13873 $this->pages[$this->page] .= '___BEFORE_BORDERS___';
13874 $block_s = $this->PrintPageBackgrounds(); // Save to print later inside clipping path
13875 $this->pageBackgrounds = array();
13876
13877 //================================================================
13878
13879 if ($rotate) {
13880 $prerotw = $bbox_bl + $bbox_pl + $inner_w + $bbox_pr + $bbox_br;
13881 $preroth = $bbox_bt + $bbox_pt + $inner_h + $bbox_pb + $bbox_bb;
13882 $rot_start = " q\n";
13883 if ($rotate == 90) {
13884 if ($rot_rpos !== false) { $adjw = $prerotw; } // width before rotation
13885 else { $adjw = $preroth; } // height before rotation
13886 if ($rot_bpos !== false) { $adjh = -$prerotw + $preroth; }
13887 else { $adjh = 0; }
13888 }
13889 else {
13890 if ($rot_rpos !== false) { $adjw = $prerotw - $preroth; }
13891 else { $adjw = 0; }
13892 if ($rot_bpos !== false) { $adjh = $preroth; } // height before rotation
13893 else { $adjh = $prerotw; } // width before rotation
13894 }
13895 $rot_start .= $this->transformTranslate($adjw, $adjh, true)."\n";
13896 $rot_start .= $this->transformRotate($rotate, $bbox_x, $bbox_y, true)."\n";
13897 $rot_end = " Q\n";
13898 }
13899 else {
13900 $rot_start = '';
13901 $rot_end = '';
13902 }
13903
13904 //================================================================
13905 if (!empty($bounding)) {
13906 // WHEN HEIGHT // BOTTOM EDGE IS KNOWN and $this->y is set to the bottom
13907 // Re-instate saved $this->blk[1]
13908 $this->blk[1] = $saved_block1;
13909
13910 // These are only needed when painting border/background
13911 $this->blk[1]['width'] = $bbox_w = $cont_w - $bbox_left - $bbox_ml - $bbox_mr - $bbox_right;
13912 $this->blk[1]['x0'] = $bbox_x;
13913 $this->blk[1]['y0'] = $bbox_y;
13914 $this->blk[1]['startpage'] = $this->page;
13915 $this->blk[1]['y1'] = $bbox_y + $bbox_bt + $bbox_pt + $inner_h + $bbox_pb + $bbox_bb ;
13916 $this->_out($rot_start); // mPDF 5.0
13917 $this->PaintDivBB('',0,1); // Prints borders and sets backgrounds in $this->pageBackgrounds
13918 $this->_out($rot_end);
13919 }
13920
13921 $s = $this->PrintPageBackgrounds();
13922 $s = $rot_start.$s.$rot_end;
13923 $this->pages[$this->page] = preg_replace('/___BEFORE_BORDERS___/', "\n".$s."\n", $this->pages[$this->page]);
13924 $this->pageBackgrounds = array();
13925
13926 $this->_out($rot_start);
13927
13928 // Clipping Output
13929 if ($overflow=='hidden') {
13930 //Bounding rectangle to clip
13931 $clip_y1 = $this->y;
13932 if (!empty($bounding) && ($this->y + $bbox_pb + $bbox_bb) > ($bbox_y + $bbox_bt + $bbox_pt + $inner_h + $bbox_pb + $bbox_bb )) {
13933 $clip_y1 = ($bbox_y + $bbox_bt + $bbox_pt + $inner_h + $bbox_pb + $bbox_bb ) - ($bbox_pb + $bbox_bb);
13934 }
13935 //$op = 'W* n'; // Clipping
13936 $op = 'W n'; // Clipping alternative mode
13937 $this->_out("q");
13938 $ch = $clip_y1 - $y;
13939 $this->_out(sprintf('%.3F %.3F %.3F %.3F re %s',$x*_MPDFK,($this->h-$y)*_MPDFK,$w*_MPDFK,-$ch*_MPDFK,$op));
13940 if (!empty($block_s)) {
13941 $tmp = "q\n".sprintf('%.3F %.3F %.3F %.3F re %s',$x*_MPDFK,($this->h-$y)*_MPDFK,$w*_MPDFK,-$ch*_MPDFK,$op);
13942 $tmp .= "\n".$block_s."\nQ";
13943 $block_s = $tmp ;
13944 }
13945 }
13946
13947
13948 if (!empty($block_s)) {
13949 if ($shrink_f != 1) { // i.e. autofit has resized the box
13950 $tmp = "q\n".$this->transformScale(($shrink_f*100),($shrink_f*100), $x, $y, true);
13951 $tmp .= "\n".$block_s."\nQ";
13952 $block_s = $tmp ;
13953 }
13954 $this->_out($block_s);
13955 }
13956
13957
13958
13959 if ($shrink_f != 1) { // i.e. autofit has resized the box
13960 $this->StartTransform();
13961 $this->transformScale(($shrink_f*100),($shrink_f*100), $x, $y);
13962 }
13963
13964 $this->_out($this->headerbuffer);
13965
13966 if ($shrink_f != 1) { // i.e. autofit has resized the box
13967 $this->StopTransform();
13968 }
13969
13970 if ($overflow=='hidden') {
13971 //End clipping
13972 $this->_out("Q");
13973 }
13974
13975 $this->_out($rot_end);
13976
13977
13978 // Page Links
13979 foreach($this->HTMLheaderPageLinks AS $lk) {
13980 if ($rotate) {
13981 $tmp = $lk[2]; // Switch h - w
13982 $lk[2] = $lk[3];
13983 $lk[3] = $tmp;
13984
13985 $lx1 = (($lk[0]/_MPDFK));
13986 $ly1 = (($this->h-($lk[1]/_MPDFK)));
13987 if ($rotate == 90) {
13988 $adjx = -($lx1-$bbox_x) + ($preroth - ($ly1-$bbox_y));
13989 $adjy = -($ly1-$bbox_y) + ($lx1-$bbox_x);
13990 $lk[2] = -$lk[2];
13991 }
13992 else if ($rotate == -90) {
13993 $adjx = -($lx1-$bbox_x) + ($ly1-$bbox_y);
13994 $adjy = -($ly1-$bbox_y) - ($lx1-$bbox_x) + $prerotw;
13995 $lk[3] = -$lk[3];
13996 }
13997 if ($rot_rpos !== false) { $adjx += $prerotw - $preroth; }
13998 if ($rot_bpos !== false) { $adjy += $preroth - $prerotw; }
13999 $lx1 += $adjx;
14000 $ly1 += $adjy;
14001
14002 $lk[0] = $lx1*_MPDFK;
14003 $lk[1] = ($this->h-$ly1)*_MPDFK;
14004 }
14005 if ($shrink_f != 1) { // i.e. autofit has resized the box
14006 $lx1 = (($lk[0]/_MPDFK)-$x);
14007 $lx2 = $x + ($lx1 * $shrink_f);
14008 $lk[0] = $lx2*_MPDFK;
14009 $ly1 = (($this->h-($lk[1]/_MPDFK))-$y);
14010 $ly2 = $y + ($ly1 * $shrink_f);
14011 $lk[1] = ($this->h-$ly2)*_MPDFK;
14012 $lk[2] *= $shrink_f; // width
14013 $lk[3] *= $shrink_f; // height
14014 }
14015 $this->PageLinks[$this->page][]=$lk;
14016 }
14017
14018 foreach($this->HTMLheaderPageForms AS $n=>$f) {
14019 if ($shrink_f != 1) { // i.e. autofit has resized the box
14020 $f['x'] = $x + (($f['x'] -$x) * $shrink_f);
14021 $f['y'] = $y + (($f['y'] -$y) * $shrink_f);
14022 $f['w'] *= $shrink_f;
14023 $f['h'] *= $shrink_f;
14024 $f['style']['fontsize'] *= $shrink_f;
14025 }
14026 $this->form->forms[$f['n']] = $f;
14027 }
14028 // Page Annotations
14029 foreach($this->HTMLheaderPageAnnots AS $lk) {
14030 if ($rotate) {
14031 if ($rotate == 90) {
14032 $adjx = -($lk['x']-$bbox_x) + ($preroth - ($lk['y']-$bbox_y));
14033 $adjy = -($lk['y']-$bbox_y) + ($lk['x']-$bbox_x);
14034 }
14035 else if ($rotate == -90) {
14036 $adjx = -($lk['x']-$bbox_x) + ($lk['y']-$bbox_y);
14037 $adjy = -($lk['y']-$bbox_y) - ($lk['x']-$bbox_x) + $prerotw;
14038 }
14039 if ($rot_rpos !== false) { $adjx += $prerotw - $preroth; }
14040 if ($rot_bpos !== false) { $adjy += $preroth - $prerotw; }
14041 $lk['x'] += $adjx;
14042 $lk['y'] += $adjy;
14043 }
14044 if ($shrink_f != 1) { // i.e. autofit has resized the box
14045 $lk['x'] = $x + (($lk['x']-$x) * $shrink_f);
14046 $lk['y'] = $y + (($lk['y']-$y) * $shrink_f);
14047 }
14048 $this->PageAnnots[$this->page][]=$lk;
14049 }
14050
14051 // Restore
14052 $this->headerbuffer = '';
14053 $this->HTMLheaderPageLinks = array();
14054 $this->HTMLheaderPageAnnots = array();
14055 $this->HTMLheaderPageForms = array();
14056 $this->pageBackgrounds = $save_bgs;
14057 $this->writingHTMLheader = false;
14058
14059 $this->writingHTMLfooter = false;
14060 $this->fullImageHeight = false;
14061 $this->ResetMargins();
14062 $this->pgwidth = $this->w - $this->lMargin - $this->rMargin;
14063 $this->SetXY($save_x,$save_y) ;
14064 $this->title2annots = $save_annots; // *ANNOTATIONS*
14065 $this->InFooter = false; // turns back on autopagebreaks
14066 $this->pageoutput[$this->page]=array();
14067 $this->pageoutput[$this->page]['Font']='';
14068 /*-- COLUMNS --*/
14069 if ($save_cols) {
14070 $this->SetColumns($save_nbcol,$this->colvAlign,$this->ColGap);
14071 }
14072 /*-- END COLUMNS --*/
14073 }
14074 /*-- END CSS-POSITION --*/
14075
14076
14077
14078 function initialiseBlock(&$blk) {
14079 $blk['margin_top'] = 0;
14080 $blk['margin_left'] = 0;
14081 $blk['margin_bottom'] = 0;
14082 $blk['margin_right'] = 0;
14083 $blk['padding_top'] = 0;
14084 $blk['padding_left'] = 0;
14085 $blk['padding_bottom'] = 0;
14086 $blk['padding_right'] = 0;
14087 $blk['border_top']['w'] = 0;
14088 $blk['border_left']['w'] = 0;
14089 $blk['border_bottom']['w'] = 0;
14090 $blk['border_right']['w'] = 0;
14091 $blk['hide'] = false;
14092 $blk['outer_left_margin'] = 0;
14093 $blk['outer_right_margin'] = 0;
14094 $blk['cascadeCSS'] = array();
14095 $blk['block-align'] = false;
14096 $blk['bgcolor'] = false;
14097 $blk['page_break_after_avoid'] = false;
14098 $blk['keep_block_together'] = false;
14099 $blk['float'] = false;
14100 $blk['line_height'] = '';
14101 $blk['margin_collapse'] = false;
14102 }
14103
14104
14105 function border_details($bd) {
14106 $prop = preg_split('/\s+/',trim($bd));
14107
14108 if (isset($this->blk[$this->blklvl]['inner_width'])) { $refw = $this->blk[$this->blklvl]['inner_width']; }
14109 else if (isset($this->blk[$this->blklvl-1]['inner_width'])) { $refw = $this->blk[$this->blklvl-1]['inner_width']; }
14110 else { $refw = $this->w; }
14111 if ( count($prop) == 1 ) {
14112 $bsize = $this->ConvertSize($prop[0],$refw,$this->FontSize,false);
14113 if ($bsize > 0) {
14114 return array('s' => 1, 'w' => $bsize, 'c' => $this->ConvertColor(0), 'style'=>'solid');
14115 }
14116 else { return array('w' => 0, 's' => 0); }
14117 }
14118
14119 else if (count($prop) == 2 ) {
14120 // 1px solid
14121 if (in_array($prop[1],$this->borderstyles) || $prop[1] == 'none' || $prop[1] == 'hidden' ) { $prop[2] = ''; }
14122 // solid #000000
14123 else if (in_array($prop[0],$this->borderstyles) || $prop[0] == 'none' || $prop[0] == 'hidden' ) { $prop[0] = ''; $prop[1] = $prop[0]; $prop[2] = $prop[1]; }
14124 // 1px #000000
14125 else { $prop[1] = ''; $prop[2] = $prop[1]; }
14126 }
14127 else if ( count($prop) == 3 ) {
14128 // Change #000000 1px solid to 1px solid #000000 (proper)
14129 if (substr($prop[0],0,1) == '#') { $tmp = $prop[0]; $prop[0] = $prop[1]; $prop[1] = $prop[2]; $prop[2] = $tmp; }
14130 // Change solid #000000 1px to 1px solid #000000 (proper)
14131 else if (substr($prop[0],1,1) == '#') { $tmp = $prop[1]; $prop[0] = $prop[2]; $prop[1] = $prop[0]; $prop[2] = $tmp; }
14132 // Change solid 1px #000000 to 1px solid #000000 (proper)
14133 else if (in_array($prop[0],$this->borderstyles) || $prop[0] == 'none' || $prop[0] == 'hidden' ) {
14134 $tmp = $prop[0]; $prop[0] = $prop[1]; $prop[1] = $tmp;
14135 }
14136 }
14137 else { return array(); }
14138 // Size
14139 $bsize = $this->ConvertSize($prop[0],$refw,$this->FontSize,false);
14140 //color
14141 $coul = $this->ConvertColor($prop[2]); // returns array
14142 // Style
14143 $prop[1] = strtolower($prop[1]);
14144 if (in_array($prop[1],$this->borderstyles) && $bsize > 0) { $on = 1; }
14145 else if ($prop[1] == 'hidden') { $on = 1; $bsize = 0; $coul = ''; }
14146 else if ($prop[1] == 'none') { $on = 0; $bsize = 0; $coul = ''; }
14147 else { $on = 0; $bsize = 0; $coul = ''; $prop[1] = ''; }
14148 return array('s' => $on, 'w' => $bsize, 'c' => $coul, 'style'=> $prop[1] );
14149 }
14150
14151
14152
14153 /*-- END HTML-CSS --*/
14154
14155
14156 // Return either a number (factor) - based on current set fontsize (if % or em) - or exact lineheight (with 'mm' after it)
14157 function fixLineheight($v) {
14158 $lh = false;
14159 if (preg_match('/^[0-9\.,]*$/',$v) && $v >= 0) { return ($v + 0); }
14160 else if (strtoupper($v) == 'NORMAL') {
14161 return $this->normalLineheight;
14162 }
14163 else {
14164 $tlh = $this->ConvertSize($v,$this->FontSize,$this->FontSize,true);
14165 if ($tlh) { return ($tlh.'mm'); }
14166 }
14167 return $this->normalLineheight;
14168 }
14169
14170
14171 /*-- BORDER-RADIUS --*/
14172 function _borderPadding($a, $b, &$px, &$py) {
14173 // $px and py are padding long axis (x) and short axis (y)
14174 $added = 0; // extra padding
14175
14176 $x = $a-$px;
14177 $y = $b-$py;
14178 // Check if Falls within ellipse of border radius
14179 if ( ( (($x+$added)*($x+$added))/($a*$a) + (($y+$added)*($y+$added))/($b*$b) ) <=1 ) { return false; }
14180
14181 $t = atan2($y,$x);
14182
14183 $newx = $b / sqrt((($b*$b)/($a*$a)) + ( tan($t) * tan($t) ) );
14184 $newy = $a / sqrt((($a*$a)/($b*$b)) + ( (1/tan($t)) * (1/tan($t)) ) );
14185 $px = max($px, $a - $newx + $added);
14186 $py = max($py, $b - $newy + $added);
14187 }
14188 /*-- END BORDER-RADIUS --*/
14189
14190
14191
14192 /*-- HTML-CSS --*/
14193
14194
14195 /*-- CSS-PAGE --*/
14196 function SetPagedMediaCSS($name='', $first, $oddEven) {
14197 if ($oddEven == 'E') {
14198 if ($this->directionality=='rtl') { $side = 'R'; }
14199 else { $side = 'L'; }
14200 }
14201 else {
14202 if ($this->directionality=='rtl') { $side = 'L'; }
14203 else { $side = 'R'; }
14204 }
14205 $name = strtoupper($name);
14206 $p = array();
14207 $p['SIZE'] = 'AUTO';
14208
14209 // Uses mPDF original margins as default
14210 $p['MARGIN-RIGHT'] = strval($this->orig_rMargin).'mm';
14211 $p['MARGIN-LEFT'] = strval($this->orig_lMargin).'mm';
14212 $p['MARGIN-TOP'] = strval($this->orig_tMargin).'mm';
14213 $p['MARGIN-BOTTOM'] = strval($this->orig_bMargin).'mm';
14214 $p['MARGIN-HEADER'] = strval($this->orig_hMargin).'mm';
14215 $p['MARGIN-FOOTER'] = strval($this->orig_fMargin).'mm';
14216
14217 // Basic page + selector
14218 if (isset($this->cssmgr->CSS['@PAGE'])) { $zp = $this->cssmgr->CSS['@PAGE']; }
14219 else { $zp = array(); }
14220 if (is_array($zp) && !empty($zp)) { $p = array_merge($p,$zp); }
14221
14222 if (isset($p['EVEN-HEADER-NAME']) && $oddEven=='E') {
14223 $p['HEADER'] = $p['EVEN-HEADER-NAME']; unset($p['EVEN-HEADER-NAME']);
14224 }
14225 if (isset($p['ODD-HEADER-NAME']) && $oddEven!='E') {
14226 $p['HEADER'] = $p['ODD-HEADER-NAME']; unset($p['ODD-HEADER-NAME']);
14227 }
14228 if (isset($p['EVEN-FOOTER-NAME']) && $oddEven=='E') {
14229 $p['FOOTER'] = $p['EVEN-FOOTER-NAME']; unset($p['EVEN-FOOTER-NAME']);
14230 }
14231 if (isset($p['ODD-FOOTER-NAME']) && $oddEven!='E') {
14232 $p['FOOTER'] = $p['ODD-FOOTER-NAME']; unset($p['ODD-FOOTER-NAME']);
14233 }
14234
14235 // If right/Odd page
14236 if (isset($this->cssmgr->CSS['@PAGE>>PSEUDO>>RIGHT']) && $side=='R') {
14237 $zp = $this->cssmgr->CSS['@PAGE>>PSEUDO>>RIGHT'];
14238 }
14239 else { $zp = array(); }
14240 if (isset($zp['SIZE'])) { unset($zp['SIZE']); }
14241 if (isset($zp['SHEET-SIZE'])) { unset($zp['SHEET-SIZE']); }
14242 // Disallow margin-left or -right on :LEFT or :RIGHT
14243 if (isset($zp['MARGIN-LEFT'])) { unset($zp['MARGIN-LEFT']); }
14244 if (isset($zp['MARGIN-RIGHT'])) { unset($zp['MARGIN-RIGHT']); }
14245 if (is_array($zp) && !empty($zp)) { $p = array_merge($p,$zp); }
14246
14247 // If left/Even page
14248 if (isset($this->cssmgr->CSS['@PAGE>>PSEUDO>>LEFT']) && $side=='L') {
14249 $zp = $this->cssmgr->CSS['@PAGE>>PSEUDO>>LEFT'];
14250 }
14251 else { $zp = array(); }
14252 if (isset($zp['SIZE'])) { unset($zp['SIZE']); }
14253 if (isset($zp['SHEET-SIZE'])) { unset($zp['SHEET-SIZE']); }
14254 // Disallow margin-left or -right on :LEFT or :RIGHT
14255 if (isset($zp['MARGIN-LEFT'])) { unset($zp['MARGIN-LEFT']); }
14256 if (isset($zp['MARGIN-RIGHT'])) { unset($zp['MARGIN-RIGHT']); }
14257 if (is_array($zp) && !empty($zp)) { $p = array_merge($p,$zp); }
14258
14259 // If first page
14260 if (isset($this->cssmgr->CSS['@PAGE>>PSEUDO>>FIRST']) && $first) { $zp = $this->cssmgr->CSS['@PAGE>>PSEUDO>>FIRST']; }
14261 else { $zp = array(); }
14262 if (isset($zp['SIZE'])) { unset($zp['SIZE']); }
14263 if (isset($zp['SHEET-SIZE'])) { unset($zp['SHEET-SIZE']); }
14264 if (is_array($zp) && !empty($zp)) { $p = array_merge($p,$zp); }
14265
14266 // If named page
14267 if ($name) {
14268 if (isset($this->cssmgr->CSS['@PAGE>>NAMED>>'.$name])) { $zp = $this->cssmgr->CSS['@PAGE>>NAMED>>'.$name]; }
14269 else { $zp = array(); }
14270 if (is_array($zp) && !empty($zp)) { $p = array_merge($p,$zp); }
14271
14272 if (isset($p['EVEN-HEADER-NAME']) && $oddEven=='E') {
14273 $p['HEADER'] = $p['EVEN-HEADER-NAME']; unset($p['EVEN-HEADER-NAME']);
14274 }
14275 if (isset($p['ODD-HEADER-NAME']) && $oddEven!='E') {
14276 $p['HEADER'] = $p['ODD-HEADER-NAME']; unset($p['ODD-HEADER-NAME']);
14277 }
14278 if (isset($p['EVEN-FOOTER-NAME']) && $oddEven=='E') {
14279 $p['FOOTER'] = $p['EVEN-FOOTER-NAME']; unset($p['EVEN-FOOTER-NAME']);
14280 }
14281 if (isset($p['ODD-FOOTER-NAME']) && $oddEven!='E') {
14282 $p['FOOTER'] = $p['ODD-FOOTER-NAME']; unset($p['ODD-FOOTER-NAME']);
14283 }
14284
14285 // If named right/Odd page
14286 if (isset($this->cssmgr->CSS['@PAGE>>NAMED>>'.$name.'>>PSEUDO>>RIGHT']) && $side=='R') { $zp = $this->cssmgr->CSS['@PAGE>>NAMED>>'.$name.'>>PSEUDO>>RIGHT']; }
14287 else { $zp = array(); }
14288 if (isset($zp['SIZE'])) { unset($zp['SIZE']); }
14289 if (isset($zp['SHEET-SIZE'])) { unset($zp['SHEET-SIZE']); }
14290 // Disallow margin-left or -right on :LEFT or :RIGHT
14291 if (isset($zp['MARGIN-LEFT'])) { unset($zp['MARGIN-LEFT']); }
14292 if (isset($zp['MARGIN-RIGHT'])) { unset($zp['MARGIN-RIGHT']); }
14293 if (is_array($zp) && !empty($zp)) { $p = array_merge($p,$zp); }
14294
14295 // If named left/Even page
14296 if (isset($this->cssmgr->CSS['@PAGE>>NAMED>>'.$name.'>>PSEUDO>>LEFT']) && $side=='L') { $zp = $this->cssmgr->CSS['@PAGE>>NAMED>>'.$name.'>>PSEUDO>>LEFT']; }
14297 else { $zp = array(); }
14298 if (isset($zp['SIZE'])) { unset($zp['SIZE']); }
14299 if (isset($zp['SHEET-SIZE'])) { unset($zp['SHEET-SIZE']); }
14300 // Disallow margin-left or -right on :LEFT or :RIGHT
14301 if (isset($zp['MARGIN-LEFT'])) { unset($zp['MARGIN-LEFT']); }
14302 if (isset($zp['MARGIN-RIGHT'])) { unset($zp['MARGIN-RIGHT']); }
14303 if (is_array($zp) && !empty($zp)) { $p = array_merge($p,$zp); }
14304
14305 // If named first page
14306 if (isset($this->cssmgr->CSS['@PAGE>>NAMED>>'.$name.'>>PSEUDO>>FIRST']) && $first) { $zp = $this->cssmgr->CSS['@PAGE>>NAMED>>'.$name.'>>PSEUDO>>FIRST']; }
14307 else { $zp = array(); }
14308 if (isset($zp['SIZE'])) { unset($zp['SIZE']); }
14309 if (isset($zp['SHEET-SIZE'])) { unset($zp['SHEET-SIZE']); }
14310 if (is_array($zp) && !empty($zp)) { $p = array_merge($p,$zp); }
14311 }
14312
14313 $orientation = $mgl = $mgr = $mgt = $mgb = $mgh = $mgf = '';
14314 $header = $footer = '';
14315 $resetpagenum = $pagenumstyle = $suppress = '';
14316 $marks = '';
14317 $bg = array();
14318
14319 $newformat = '';
14320
14321
14322 if (isset($p['SHEET-SIZE']) && is_array($p['SHEET-SIZE'])) {
14323 $newformat = $p['SHEET-SIZE'];
14324 if ($newformat[0] > $newformat[1]) { // landscape
14325 $newformat = array_reverse($newformat);
14326 $p['ORIENTATION'] = 'L';
14327 }
14328 else { $p['ORIENTATION'] = 'P'; }
14329 $this->_setPageSize($newformat, $p['ORIENTATION']);
14330 }
14331
14332 if (isset($p['SIZE']) && is_array($p['SIZE']) && !$newformat) {
14333 if ($p['SIZE']['W'] > $p['SIZE']['H']) { $p['ORIENTATION'] = 'L'; }
14334 else { $p['ORIENTATION'] = 'P'; }
14335 }
14336 if (is_array($p['SIZE'])) {
14337 if ($p['SIZE']['W'] > $this->fw) { $p['SIZE']['W'] = $this->fw; } // mPD 4.2 use fw not fPt
14338 if ($p['SIZE']['H'] > $this->fh) { $p['SIZE']['H'] = $this->fh; }
14339 if (($p['ORIENTATION']==$this->DefOrientation && !$newformat) || ($newformat && $p['ORIENTATION']=='P')) {
14340 $outer_width_LR = ($this->fw - $p['SIZE']['W'])/2;
14341 $outer_width_TB = ($this->fh - $p['SIZE']['H'])/2;
14342 }
14343 else {
14344 $outer_width_LR = ($this->fh - $p['SIZE']['W'])/2;
14345 $outer_width_TB = ($this->fw - $p['SIZE']['H'])/2;
14346 }
14347 $pgw = $p['SIZE']['W'];
14348 $pgh = $p['SIZE']['H'];
14349 }
14350 else { // AUTO LANDSCAPE PORTRAIT
14351 $outer_width_LR = 0;
14352 $outer_width_TB = 0;
14353 if (!$newformat) {
14354 if (strtoupper($p['SIZE']) == 'AUTO') { $p['ORIENTATION']=$this->DefOrientation; }
14355 else if (strtoupper($p['SIZE']) == 'LANDSCAPE') { $p['ORIENTATION']='L'; }
14356 else { $p['ORIENTATION']='P'; }
14357 }
14358 if (($p['ORIENTATION']==$this->DefOrientation && !$newformat) || ($newformat && $p['ORIENTATION']=='P')) {
14359 $pgw = $this->fw;
14360 $pgh = $this->fh;
14361 }
14362 else {
14363 $pgw = $this->fh;
14364 $pgh = $this->fw;
14365 }
14366 }
14367
14368 if (isset($p['HEADER']) && $p['HEADER']) { $header = $p['HEADER']; }
14369 if (isset($p['FOOTER']) && $p['FOOTER']) { $footer = $p['FOOTER']; }
14370 if (isset($p['RESETPAGENUM']) && $p['RESETPAGENUM']) { $resetpagenum = $p['RESETPAGENUM']; }
14371 if (isset($p['PAGENUMSTYLE']) && $p['PAGENUMSTYLE']) { $pagenumstyle = $p['PAGENUMSTYLE']; }
14372 if (isset($p['SUPPRESS']) && $p['SUPPRESS']) { $suppress = $p['SUPPRESS']; }
14373
14374 if (preg_match('/cross/i', $p['MARKS']) && preg_match('/crop/i', $p['MARKS'])) { $marks = 'CROPCROSS'; }
14375 else if (strtoupper($p['MARKS']) == 'CROP') { $marks = 'CROP'; }
14376 else if (strtoupper($p['MARKS']) == 'CROSS') { $marks = 'CROSS'; }
14377
14378
14379 if (isset($p['BACKGROUND-COLOR']) && $p['BACKGROUND-COLOR']) { $bg['BACKGROUND-COLOR'] = $p['BACKGROUND-COLOR']; }
14380 /*-- BACKGROUNDS --*/
14381 if (isset($p['BACKGROUND-GRADIENT']) && $p['BACKGROUND-GRADIENT']) { $bg['BACKGROUND-GRADIENT'] = $p['BACKGROUND-GRADIENT']; }
14382 if (isset($p['BACKGROUND-IMAGE']) && $p['BACKGROUND-IMAGE']) { $bg['BACKGROUND-IMAGE'] = $p['BACKGROUND-IMAGE']; }
14383 if (isset($p['BACKGROUND-REPEAT']) && $p['BACKGROUND-REPEAT']) { $bg['BACKGROUND-REPEAT'] = $p['BACKGROUND-REPEAT']; }
14384 if (isset($p['BACKGROUND-POSITION']) && $p['BACKGROUND-POSITION']) { $bg['BACKGROUND-POSITION'] = $p['BACKGROUND-POSITION']; }
14385 if (isset($p['BACKGROUND-IMAGE-RESIZE']) && $p['BACKGROUND-IMAGE-RESIZE']) { $bg['BACKGROUND-IMAGE-RESIZE'] = $p['BACKGROUND-IMAGE-RESIZE']; }
14386 if (isset($p['BACKGROUND-IMAGE-OPACITY'])) { $bg['BACKGROUND-IMAGE-OPACITY'] = $p['BACKGROUND-IMAGE-OPACITY']; }
14387 /*-- END BACKGROUNDS --*/
14388
14389 if (isset($p['MARGIN-LEFT'])) { $mgl = $this->ConvertSize($p['MARGIN-LEFT'],$pgw) + $outer_width_LR; }
14390 if (isset($p['MARGIN-RIGHT'])) { $mgr = $this->ConvertSize($p['MARGIN-RIGHT'],$pgw) + $outer_width_LR; }
14391 if (isset($p['MARGIN-BOTTOM'])) { $mgb = $this->ConvertSize($p['MARGIN-BOTTOM'],$pgh) + $outer_width_TB; }
14392 if (isset($p['MARGIN-TOP'])) { $mgt = $this->ConvertSize($p['MARGIN-TOP'],$pgh) + $outer_width_TB; }
14393 if (isset($p['MARGIN-HEADER'])) { $mgh = $this->ConvertSize($p['MARGIN-HEADER'],$pgh) + $outer_width_TB; }
14394 if (isset($p['MARGIN-FOOTER'])) { $mgf = $this->ConvertSize($p['MARGIN-FOOTER'],$pgh) + $outer_width_TB; }
14395
14396 if (isset($p['ORIENTATION']) && $p['ORIENTATION']) { $orientation = $p['ORIENTATION']; }
14397 $this->page_box['outer_width_LR'] = $outer_width_LR; // Used in MARKS:crop etc.
14398 $this->page_box['outer_width_TB'] = $outer_width_TB;
14399
14400 return array($orientation,$mgl,$mgr,$mgt,$mgb,$mgh,$mgf,$header,$footer,$bg,$resetpagenum,$pagenumstyle,$suppress,$marks,$newformat);
14401 }
14402 /*-- END CSS-PAGE --*/
14403
14404
14405
14406 /*-- CSS-FLOAT --*/
14407 // Added mPDF 3.0 Float DIV - CLEAR
14408 function ClearFloats($clear, $blklvl=0) {
14409 list($l_exists, $r_exists, $l_max, $r_max, $l_width, $r_width) = $this->GetFloatDivInfo($blklvl,true);
14410 $end = $currpos = ($this->page*1000 + $this->y);
14411 if ($clear == 'BOTH' && ($l_exists || $r_exists)) {
14412 $this->pageoutput[$this->page] = array();
14413 $end = max($l_max, $r_max, $currpos);
14414 }
14415 else if ($clear == 'RIGHT' && $r_exists) {
14416 $this->pageoutput[$this->page] = array();
14417 $end = max($r_max, $currpos);
14418 }
14419 else if ($clear == 'LEFT' && $l_exists ) {
14420 $this->pageoutput[$this->page] = array();
14421 $end = max($l_max, $currpos);
14422 }
14423 else { return; }
14424 $old_page = $this->page;
14425 $new_page = intval($end/1000);
14426 if ($old_page != $new_page) {
14427 $s = $this->PrintPageBackgrounds();
14428 // Writes after the marker so not overwritten later by page background etc.
14429 $this->pages[$this->page] = preg_replace('/(___BACKGROUND___PATTERNS'.date('jY').')/', '\\1'."\n".$s."\n", $this->pages[$this->page]);
14430 $this->pageBackgrounds = array();
14431 $this->page = $new_page;
14432 }
14433 $this->ResetMargins();
14434 $this->pageoutput[$this->page] = array();
14435 $this->y = (($end*1000) % 1000000)/1000; // mod changes operands to integers before processing
14436 }
14437
14438
14439 // Added mPDF 3.0 Float DIV
14440 function GetFloatDivInfo($blklvl=0,$clear=false) {
14441 // If blklvl specified, only returns floats at that level - for ClearFloats
14442 $l_exists = false;
14443 $r_exists = false;
14444 $l_max = 0;
14445 $r_max = 0;
14446 $l_width = 0;
14447 $r_width = 0;
14448 if (count($this->floatDivs)) {
14449 $currpos = ($this->page*1000 + $this->y);
14450 foreach($this->floatDivs AS $f) {
14451 if (($clear && $f['blockContext'] == $this->blk[$blklvl]['blockContext']) || (!$clear && $currpos >= $f['startpos'] && $currpos < ($f['endpos']-0.001) && $f['blklvl'] > $blklvl && $f['blockContext'] == $this->blk[$blklvl]['blockContext'])) {
14452 if ($f['side']=='L') {
14453 $l_exists= true;
14454 $l_max = max($l_max, $f['endpos']);
14455 $l_width = max($l_width , $f['w']);
14456 }
14457 if ($f['side']=='R') {
14458 $r_exists= true;
14459 $r_max = max($r_max, $f['endpos']);
14460 $r_width = max($r_width , $f['w']);
14461 }
14462 }
14463 }
14464 }
14465 return array($l_exists, $r_exists, $l_max, $r_max, $l_width, $r_width);
14466 }
14467 /*-- END CSS-FLOAT --*/
14468
14469
14470
14471
14472 function OpenTag($tag,$attr)
14473 {
14474
14475 // What this gets: < $tag $attr['WIDTH']="90px" > does not get content here </closeTag here>
14476 // Correct tags where HTML specifies optional end tags,
14477 // and/or does not allow nesting e.g. P inside P, or
14478 if ($this->allow_html_optional_endtags) {
14479 if (($tag == 'P' || $tag == 'DIV' || $tag == 'H1' || $tag == 'H2' || $tag == 'H3' || $tag == 'H4' || $tag == 'H5' || $tag == 'H6' || $tag == 'UL' || $tag == 'OL' || $tag == 'TABLE' || $tag=='PRE' || $tag=='FORM' || $tag=='ADDRESS' || $tag=='BLOCKQUOTE' || $tag=='CENTER' || $tag=='DL' || $tag == 'HR' ) && $this->lastoptionaltag == 'P') { $this->CloseTag($this->lastoptionaltag ); }
14480 if ($tag == 'DD' && $this->lastoptionaltag == 'DD') { $this->CloseTag($this->lastoptionaltag ); }
14481 if ($tag == 'DD' && $this->lastoptionaltag == 'DT') { $this->CloseTag($this->lastoptionaltag ); }
14482 if ($tag == 'DT' && $this->lastoptionaltag == 'DD') { $this->CloseTag($this->lastoptionaltag ); }
14483 if ($tag == 'DT' && $this->lastoptionaltag == 'DT') { $this->CloseTag($this->lastoptionaltag ); }
14484 if ($tag == 'LI' && $this->lastoptionaltag == 'LI') { $this->CloseTag($this->lastoptionaltag ); }
14485 if (($tag == 'TD' || $tag == 'TH') && $this->lastoptionaltag == 'TD') { $this->CloseTag($this->lastoptionaltag ); } // *TABLES*
14486 if (($tag == 'TD' || $tag == 'TH') && $this->lastoptionaltag == 'TH') { $this->CloseTag($this->lastoptionaltag ); } // *TABLES*
14487 if ($tag == 'TR' && $this->lastoptionaltag == 'TR') { $this->CloseTag($this->lastoptionaltag ); } // *TABLES*
14488 if ($tag == 'TR' && $this->lastoptionaltag == 'TD') { $this->CloseTag($this->lastoptionaltag ); $this->CloseTag('TR'); $this->CloseTag('THEAD'); } // *TABLES*
14489 if ($tag == 'TR' && $this->lastoptionaltag == 'TH') { $this->CloseTag($this->lastoptionaltag ); $this->CloseTag('TR'); $this->CloseTag('THEAD'); } // *TABLES*
14490 if ($tag == 'OPTION' && $this->lastoptionaltag == 'OPTION') { $this->CloseTag($this->lastoptionaltag ); }
14491 }
14492
14493 $align = array('left'=>'L','center'=>'C','right'=>'R','top'=>'T','text-top'=>'TT','middle'=>'M','baseline'=>'BS','bottom'=>'B','text-bottom'=>'TB','justify'=>'J');
14494
14495 $this->ignorefollowingspaces=false;
14496
14497 //Opening tag
14498 switch($tag){
14499
14500 case 'DOTTAB':
14501 $objattr = array();
14502 $objattr['type'] = 'dottab';
14503 $dots=str_repeat('.', 3)." "; // minimum number of dots
14504 $objattr['width'] = $this->GetStringWidth($dots);
14505 $objattr['margin_top'] = 0;
14506 $objattr['margin_bottom'] = 0;
14507 $objattr['margin_left'] = 0;
14508 $objattr['margin_right'] = 0;
14509 $objattr['height'] = 0;
14510 $objattr['colorarray'] = $this->colorarray;
14511 $objattr['border_top']['w'] = 0;
14512 $objattr['border_bottom']['w'] = 0;
14513 $objattr['border_left']['w'] = 0;
14514 $objattr['border_right']['w'] = 0;
14515
14516 // mPDF 5.6.19
14517 $properties = $this->cssmgr->MergeCSS('INLINE',$tag,$attr); // mPDF 5.6.33
14518 if (isset($properties['OUTDENT'])) { // mPDF 5.6.33
14519 $objattr['outdent'] = $this->ConvertSize($properties['OUTDENT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
14520 }
14521 else if (isset($attr['OUTDENT'])) {
14522 $objattr['outdent'] = $this->ConvertSize($attr['OUTDENT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
14523 }
14524 else { $objattr['outdent'] = 0; }
14525
14526 $objattr['fontfamily'] = $this->FontFamily;
14527 $objattr['fontsize'] = $this->FontSizePt;
14528
14529 $e = "\xbb\xa4\xactype=dottab,objattr=".serialize($objattr)."\xbb\xa4\xac";
14530 /*-- TABLES --*/
14531 // Output it to buffers
14532 if ($this->tableLevel) {
14533 if (!isset($this->cell[$this->row][$this->col]['maxs'])) {
14534 $this->cell[$this->row][$this->col]['maxs'] = $this->cell[$this->row][$this->col]['s'];
14535 }
14536 elseif($this->cell[$this->row][$this->col]['maxs'] < $this->cell[$this->row][$this->col]['s']) {
14537 $this->cell[$this->row][$this->col]['maxs'] = $this->cell[$this->row][$this->col]['s'];
14538 }
14539 $this->cell[$this->row][$this->col]['s'] = 0 ;// reset
14540 $this->_saveCellTextBuffer($e);
14541 }
14542 else {
14543 /*-- END TABLES --*/
14544 $this->_saveTextBuffer($e);
14545 } // *TABLES*
14546 break;
14547
14548 case 'PAGEHEADER':
14549 case 'PAGEFOOTER':
14550 $this->ignorefollowingspaces = true;
14551 if ($attr['NAME']) { $pname = $attr['NAME']; }
14552 else { $pname = '_default'; }
14553
14554 if ($tag=='PAGEHEADER') { $p = &$this->pageheaders[$pname]; }
14555 else { $p = &$this->pagefooters[$pname]; }
14556
14557 $p['L']=array();
14558 $p['C']=array();
14559 $p['R']=array();
14560 $p['L']['font-style'] = '';
14561 $p['C']['font-style'] = '';
14562 $p['R']['font-style'] = '';
14563
14564 if (isset($attr['CONTENT-LEFT'])) {
14565 $p['L']['content'] = $attr['CONTENT-LEFT'];
14566 }
14567 if (isset($attr['CONTENT-CENTER'])) {
14568 $p['C']['content'] = $attr['CONTENT-CENTER'];
14569 }
14570 if (isset($attr['CONTENT-RIGHT'])) {
14571 $p['R']['content'] = $attr['CONTENT-RIGHT'];
14572 }
14573
14574 if (isset($attr['HEADER-STYLE']) || isset($attr['FOOTER-STYLE'])) { // font-family,size,weight,style,color
14575 if ($tag=='PAGEHEADER') { $properties = $this->cssmgr->readInlineCSS($attr['HEADER-STYLE']); }
14576 else { $properties = $this->cssmgr->readInlineCSS($attr['FOOTER-STYLE']); }
14577 if (isset($properties['FONT-FAMILY'])) {
14578 $p['L']['font-family'] = $properties['FONT-FAMILY'];
14579 $p['C']['font-family'] = $properties['FONT-FAMILY'];
14580 $p['R']['font-family'] = $properties['FONT-FAMILY'];
14581 }
14582 if (isset($properties['FONT-SIZE'])) {
14583 $p['L']['font-size'] = $this->ConvertSize($properties['FONT-SIZE']) * _MPDFK;
14584 $p['C']['font-size'] = $this->ConvertSize($properties['FONT-SIZE']) * _MPDFK;
14585 $p['R']['font-size'] = $this->ConvertSize($properties['FONT-SIZE']) * _MPDFK;
14586 }
14587 if (isset($properties['FONT-WEIGHT']) && $properties['FONT-WEIGHT']=='bold') {
14588 $p['L']['font-style'] = 'B';
14589 $p['C']['font-style'] = 'B';
14590 $p['R']['font-style'] = 'B';
14591 }
14592 if (isset($properties['FONT-STYLE']) && $properties['FONT-STYLE']=='italic') {
14593 $p['L']['font-style'] .= 'I';
14594 $p['C']['font-style'] .= 'I';
14595 $p['R']['font-style'] .= 'I';
14596 }
14597 if (isset($properties['COLOR'])) {
14598 $p['L']['color'] = $properties['COLOR'];
14599 $p['C']['color'] = $properties['COLOR'];
14600 $p['R']['color'] = $properties['COLOR'];
14601 }
14602 }
14603 if (isset($attr['HEADER-STYLE-LEFT']) || isset($attr['FOOTER-STYLE-LEFT'])) {
14604 if ($tag=='PAGEHEADER') { $properties = $this->cssmgr->readInlineCSS($attr['HEADER-STYLE-LEFT']); }
14605 else { $properties = $this->cssmgr->readInlineCSS($attr['FOOTER-STYLE-LEFT']); }
14606 if (isset($properties['FONT-FAMILY'])) { $p['L']['font-family'] = $properties['FONT-FAMILY']; }
14607 if (isset($properties['FONT-SIZE'])) { $p['L']['font-size'] = $this->ConvertSize($properties['FONT-SIZE']) * _MPDFK; }
14608 if (isset($properties['FONT-WEIGHT']) && $properties['FONT-WEIGHT']=='bold') { $p['L']['font-style'] ='B'; }
14609 if (isset($properties['FONT-STYLE']) && $properties['FONT-STYLE']=='italic') { $p['L']['font-style'] .='I'; }
14610 if (isset($properties['COLOR'])) { $p['L']['color'] = $properties['COLOR']; }
14611 }
14612 if (isset($attr['HEADER-STYLE-CENTER']) || isset($attr['FOOTER-STYLE-CENTER'])) {
14613 if ($tag=='PAGEHEADER') { $properties = $this->cssmgr->readInlineCSS($attr['HEADER-STYLE-CENTER']); }
14614 else { $properties = $this->cssmgr->readInlineCSS($attr['FOOTER-STYLE-CENTER']); }
14615 if (isset($properties['FONT-FAMILY'])) { $p['C']['font-family'] = $properties['FONT-FAMILY']; }
14616 if (isset($properties['FONT-SIZE'])) { $p['C']['font-size'] = $this->ConvertSize($properties['FONT-SIZE']) * _MPDFK; }
14617 if (isset($properties['FONT-WEIGHT']) && $properties['FONT-WEIGHT']=='bold') { $p['C']['font-style'] = 'B'; }
14618 if (isset($properties['FONT-STYLE']) && $properties['FONT-STYLE']=='italic') { $p['C']['font-style'] .= 'I'; }
14619 if (isset($properties['COLOR'])) { $p['C']['color'] = $properties['COLOR']; }
14620 }
14621 if (isset($attr['HEADER-STYLE-RIGHT']) || isset($attr['FOOTER-STYLE-RIGHT'])) {
14622 if ($tag=='PAGEHEADER') { $properties = $this->cssmgr->readInlineCSS($attr['HEADER-STYLE-RIGHT']); }
14623 else { $properties = $this->cssmgr->readInlineCSS($attr['FOOTER-STYLE-RIGHT']); }
14624 if (isset($properties['FONT-FAMILY'])) { $p['R']['font-family'] = $properties['FONT-FAMILY']; }
14625 if (isset($properties['FONT-SIZE'])) { $p['R']['font-size'] = $this->ConvertSize($properties['FONT-SIZE']) * _MPDFK; }
14626 if (isset($properties['FONT-WEIGHT']) && $properties['FONT-WEIGHT']=='bold') { $p['R']['font-style'] = 'B'; }
14627 if (isset($properties['FONT-STYLE']) && $properties['FONT-STYLE']=='italic') { $p['R']['font-style'] .= 'I'; }
14628 if (isset($properties['COLOR'])) { $p['R']['color'] = $properties['COLOR']; }
14629 }
14630 if (isset($attr['LINE']) && $attr['LINE']) { // 0|1|on|off
14631 if ($attr['LINE']=='1' || strtoupper($attr['LINE'])=='ON') { $lineset=1; }
14632 else { $lineset=0; }
14633 $p['line'] = $lineset;
14634 }
14635 break;
14636
14637
14638 /*-- HTMLHEADERS-FOOTERS --*/
14639 case 'SETHTMLPAGEHEADER':
14640 case 'SETHTMLPAGEFOOTER':
14641 $this->ignorefollowingspaces = true;
14642 if (isset($attr['NAME']) && $attr['NAME']) { $pname = $attr['NAME']; }
14643 else { $pname = '_default'; }
14644 if (isset($attr['PAGE']) && $attr['PAGE']) { // O|odd|even|E|ALL|[blank]
14645 if (strtoupper($attr['PAGE'])=='O' || strtoupper($attr['PAGE'])=='ODD') { $side='odd'; }
14646 else if (strtoupper($attr['PAGE'])=='E' || strtoupper($attr['PAGE'])=='EVEN') { $side='even'; }
14647 else if (strtoupper($attr['PAGE'])=='ALL') { $side='both'; }
14648 else { $side='odd'; }
14649 }
14650 else { $side='odd'; }
14651 if (isset($attr['VALUE']) && $attr['VALUE']) { // -1|1|on|off
14652 if ($attr['VALUE']=='1' || strtoupper($attr['VALUE'])=='ON') { $set=1; }
14653 else if ($attr['VALUE']=='-1' || strtoupper($attr['VALUE'])=='OFF') { $set=0; }
14654 else { $set=1; }
14655 }
14656 else { $set=1; }
14657 if (isset($attr['SHOW-THIS-PAGE']) && $attr['SHOW-THIS-PAGE'] && $tag=='SETHTMLPAGEHEADER') { $write = 1; }
14658 else { $write = 0; }
14659 if ($side=='odd' || $side=='both') {
14660 if ($set && $tag=='SETHTMLPAGEHEADER') { $this->SetHTMLHeader($this->pageHTMLheaders[$pname],'O',$write); }
14661 else if ($set && $tag=='SETHTMLPAGEFOOTER') { $this->SetHTMLFooter($this->pageHTMLfooters[$pname],'O'); }
14662 else if ($tag=='SETHTMLPAGEHEADER') { $this->SetHTMLHeader('','O'); }
14663 else { $this->SetHTMLFooter('','O'); }
14664 }
14665 if ($side=='even' || $side=='both') {
14666 if ($set && $tag=='SETHTMLPAGEHEADER') { $this->SetHTMLHeader($this->pageHTMLheaders[$pname],'E',$write); }
14667 else if ($set && $tag=='SETHTMLPAGEFOOTER') { $this->SetHTMLFooter($this->pageHTMLfooters[$pname],'E'); }
14668 else if ($tag=='SETHTMLPAGEHEADER') { $this->SetHTMLHeader('','E'); }
14669 else { $this->SetHTMLFooter('','E'); }
14670 }
14671 break;
14672 /*-- END HTMLHEADERS-FOOTERS --*/
14673
14674 case 'SETPAGEHEADER':
14675 case 'SETPAGEFOOTER':
14676 $this->ignorefollowingspaces = true;
14677 if (isset($attr['NAME']) && $attr['NAME']) { $pname = $attr['NAME']; }
14678 else { $pname = '_default'; }
14679 if (isset($attr['PAGE']) && $attr['PAGE']) { // O|odd|even|E|ALL|[blank]
14680 if (strtoupper($attr['PAGE'])=='O' || strtoupper($attr['PAGE'])=='ODD') { $side='odd'; }
14681 else if (strtoupper($attr['PAGE'])=='E' || strtoupper($attr['PAGE'])=='EVEN') { $side='even'; }
14682 else if (strtoupper($attr['PAGE'])=='ALL') { $side='both'; }
14683 else { $side='odd'; }
14684 }
14685 else { $side='odd'; }
14686 if (isset($attr['VALUE']) && $attr['VALUE']) { // -1|1|on|off
14687 if ($attr['VALUE']=='1' || strtoupper($attr['VALUE'])=='ON') { $set=1; }
14688 else if ($attr['VALUE']=='-1' || strtoupper($attr['VALUE'])=='OFF') { $set=0; }
14689 else { $set=1; }
14690 }
14691 else { $set=1; }
14692 if ($side=='odd' || $side=='both') {
14693 if ($set && $tag=='SETPAGEHEADER') { $this->headerDetails['odd'] = $this->pageheaders[$pname]; }
14694 else if ($set && $tag=='SETPAGEFOOTER') { $this->footerDetails['odd'] = $this->pagefooters[$pname]; }
14695 else if ($tag=='SETPAGEHEADER') { $this->headerDetails['odd'] = array(); }
14696 else { $this->footerDetails['odd'] = array(); }
14697 if (!$this->mirrorMargins || ($this->page)%2!=0) { // ODD
14698 if ($tag=='SETPAGEHEADER') { $this->_setAutoHeaderHeight($this->headerDetails['odd'],$this->HTMLHeader); }
14699 if ($tag=='SETPAGEFOOTER') { $this->_setAutoFooterHeight($this->footerDetails['odd'],$this->HTMLFooter); }
14700 }
14701 }
14702 if ($side=='even' || $side=='both') {
14703 if ($set && $tag=='SETPAGEHEADER') { $this->headerDetails['even'] = $this->pageheaders[$pname]; }
14704 else if ($set && $tag=='SETPAGEFOOTER') { $this->footerDetails['even'] = $this->pagefooters[$pname]; }
14705 else if ($tag=='SETPAGEHEADER') { $this->headerDetails['even'] = array(); }
14706 else { $this->footerDetails['even'] = array(); }
14707 if ($this->mirrorMargins && ($this->page)%2==0) { // EVEN
14708 if ($tag=='SETPAGEHEADER') { $this->_setAutoHeaderHeight($this->headerDetails['even'],$this->HTMLHeaderE); }
14709 if ($tag=='SETPAGEFOOTER') { $this->_setAutoFooterHeight($this->footerDetails['even'],$this->HTMLFooterE); }
14710 }
14711 }
14712 if (isset($attr['SHOW-THIS-PAGE']) && $attr['SHOW-THIS-PAGE'] && $tag=='SETPAGEHEADER') {
14713 $this->Header();
14714 }
14715 break;
14716
14717
14718 /*-- TOC --*/
14719 case 'TOC': //added custom-tag - set Marker for insertion later of ToC
14720 if (!class_exists('tocontents', false)) { include(_MPDF_PATH.'classes/tocontents.php'); }
14721 if (empty($this->tocontents)) { $this->tocontents = new tocontents($this); }
14722 $this->tocontents->openTagTOC($attr);
14723 break;
14724
14725
14726
14727 case 'TOCPAGEBREAK': // custom-tag - set Marker for insertion later of ToC AND adds PAGEBREAK
14728 if (!class_exists('tocontents', false)) { include(_MPDF_PATH.'classes/tocontents.php'); }
14729 if (empty($this->tocontents)) { $this->tocontents = new tocontents($this); }
14730 list($isbreak,$toc_id) = $this->tocontents->openTagTOCPAGEBREAK($attr);
14731 if ($isbreak) break;
14732 // No break - continues as PAGEBREAK...
14733 /*-- END TOC --*/
14734
14735
14736 case 'PAGE_BREAK': //custom-tag
14737 case 'PAGEBREAK': //custom-tag
14738 case 'NEWPAGE': //custom-tag
14739 case 'FORMFEED': //custom-tag
14740
14741 $save_blklvl = $this->blklvl;
14742 $save_blk = $this->blk;
14743 $save_silp = $this->saveInlineProperties();
14744 $save_spanlvl = $this->spanlvl;
14745 $save_ilp = $this->InlineProperties;
14746
14747 // Close any open block tags
14748 for ($b= $this->blklvl;$b>0;$b--) { $this->CloseTag($this->blk[$b]['tag']); }
14749 if(!empty($this->textbuffer)) { //Output previously buffered content
14750 $this->printbuffer($this->textbuffer);
14751 $this->textbuffer=array();
14752 }
14753 $this->ignorefollowingspaces = true;
14754 $save_cols = false;
14755 /*-- COLUMNS --*/
14756 if ($this->ColActive) {
14757 $save_cols = true;
14758 $save_nbcol = $this->NbCol; // other values of gap and vAlign will not change by setting Columns off
14759 $this->SetColumns(0);
14760 }
14761 /*-- END COLUMNS --*/
14762
14763
14764 if (isset($attr['SHEET-SIZE']) && $tag != 'FORMFEED' && !$this->restoreBlockPageBreaks) {
14765 // Convert to same types as accepted in initial mPDF() A4, A4-L, or array(w,h)
14766 $prop = preg_split('/\s+/',trim($attr['SHEET-SIZE']));
14767 if (count($prop) == 2 ) {
14768 $newformat = array($this->ConvertSize($prop[0]), $this->ConvertSize($prop[1]));
14769 }
14770 else { $newformat = $attr['SHEET-SIZE']; }
14771 }
14772 else { $newformat = ''; }
14773
14774 $mgr = $mgl = $mgt = $mgb = $mgh = $mgf = '';
14775 if (isset($attr['MARGIN-RIGHT'])) { $mgr = $this->ConvertSize($attr['MARGIN-RIGHT'],$this->w,$this->FontSize,false); }
14776 if (isset($attr['MARGIN-LEFT'])) { $mgl = $this->ConvertSize($attr['MARGIN-LEFT'],$this->w,$this->FontSize,false); }
14777 if (isset($attr['MARGIN-TOP'])) { $mgt = $this->ConvertSize($attr['MARGIN-TOP'],$this->w,$this->FontSize,false); }
14778 if (isset($attr['MARGIN-BOTTOM'])) { $mgb = $this->ConvertSize($attr['MARGIN-BOTTOM'],$this->w,$this->FontSize,false); }
14779 if (isset($attr['MARGIN-HEADER'])) { $mgh = $this->ConvertSize($attr['MARGIN-HEADER'],$this->w,$this->FontSize,false); }
14780 if (isset($attr['MARGIN-FOOTER'])) { $mgf = $this->ConvertSize($attr['MARGIN-FOOTER'],$this->w,$this->FontSize,false); }
14781 $ohname = $ehname = $ofname = $efname = '';
14782 if (isset($attr['ODD-HEADER-NAME'])) { $ohname = $attr['ODD-HEADER-NAME']; }
14783 if (isset($attr['EVEN-HEADER-NAME'])) { $ehname = $attr['EVEN-HEADER-NAME']; }
14784 if (isset($attr['ODD-FOOTER-NAME'])) { $ofname = $attr['ODD-FOOTER-NAME']; }
14785 if (isset($attr['EVEN-FOOTER-NAME'])) { $efname = $attr['EVEN-FOOTER-NAME']; }
14786 $ohvalue = $ehvalue = $ofvalue = $efvalue = 0;
14787 if (isset($attr['ODD-HEADER-VALUE']) && ($attr['ODD-HEADER-VALUE']=='1' || strtoupper($attr['ODD-HEADER-VALUE'])=='ON')) { $ohvalue = 1; }
14788 else if (isset($attr['ODD-HEADER-VALUE']) && ($attr['ODD-HEADER-VALUE']=='-1' || strtoupper($attr['ODD-HEADER-VALUE'])=='OFF')) { $ohvalue = -1; }
14789 if (isset($attr['EVEN-HEADER-VALUE']) && ($attr['EVEN-HEADER-VALUE']=='1' || strtoupper($attr['EVEN-HEADER-VALUE'])=='ON')) { $ehvalue = 1; }
14790 else if (isset($attr['EVEN-HEADER-VALUE']) && ($attr['EVEN-HEADER-VALUE']=='-1' || strtoupper($attr['EVEN-HEADER-VALUE'])=='OFF')) { $ehvalue = -1; }
14791 if (isset($attr['ODD-FOOTER-VALUE']) && ($attr['ODD-FOOTER-VALUE']=='1' || strtoupper($attr['ODD-FOOTER-VALUE'])=='ON')) { $ofvalue = 1; }
14792 else if (isset($attr['ODD-FOOTER-VALUE']) && ($attr['ODD-FOOTER-VALUE']=='-1' || strtoupper($attr['ODD-FOOTER-VALUE'])=='OFF')) { $ofvalue = -1; }
14793 if (isset($attr['EVEN-FOOTER-VALUE']) && ($attr['EVEN-FOOTER-VALUE']=='1' || strtoupper($attr['EVEN-FOOTER-VALUE'])=='ON')) { $efvalue = 1; }
14794 else if (isset($attr['EVEN-FOOTER-VALUE']) && ($attr['EVEN-FOOTER-VALUE']=='-1' || strtoupper($attr['EVEN-FOOTER-VALUE'])=='OFF')) { $efvalue = -1; }
14795
14796 if (isset($attr['ORIENTATION']) && (strtoupper($attr['ORIENTATION'])=='L' || strtoupper($attr['ORIENTATION'])=='LANDSCAPE')) { $orient = 'L'; }
14797 else if (isset($attr['ORIENTATION']) && (strtoupper($attr['ORIENTATION'])=='P' || strtoupper($attr['ORIENTATION'])=='PORTRAIT')) { $orient = 'P'; }
14798 else { $orient = $this->CurOrientation; }
14799
14800 if (isset($attr['PAGE-SELECTOR']) && $attr['PAGE-SELECTOR']) { $pagesel = $attr['PAGE-SELECTOR']; }
14801 else { $pagesel = ''; }
14802
14803 $resetpagenum = '';
14804 $pagenumstyle = '';
14805 $suppress = '';
14806 if (isset($attr['RESETPAGENUM'])) { $resetpagenum = $attr['RESETPAGENUM']; }
14807 if (isset($attr['PAGENUMSTYLE'])) { $pagenumstyle = $attr['PAGENUMSTYLE']; }
14808 if (isset($attr['SUPPRESS'])) { $suppress = $attr['SUPPRESS']; }
14809
14810 if ($tag == 'TOCPAGEBREAK') { $type = 'NEXT-ODD'; }
14811 else if(isset($attr['TYPE'])) { $type = strtoupper($attr['TYPE']); }
14812 else { $type = ''; }
14813
14814 if ($type == 'E' || $type == 'EVEN') { $this->AddPage($orient,'E', $resetpagenum, $pagenumstyle, $suppress,$mgl,$mgr,$mgt,$mgb,$mgh,$mgf,$ohname,$ehname,$ofname,$efname,$ohvalue,$ehvalue,$ofvalue,$efvalue,$pagesel,$newformat); }
14815 else if ($type == 'O' || $type == 'ODD') { $this->AddPage($orient,'O', $resetpagenum, $pagenumstyle, $suppress,$mgl,$mgr,$mgt,$mgb,$mgh,$mgf,$ohname,$ehname,$ofname,$efname,$ohvalue,$ehvalue,$ofvalue,$efvalue,$pagesel,$newformat); }
14816 else if ($type == 'NEXT-ODD') { $this->AddPage($orient,'NEXT-ODD', $resetpagenum, $pagenumstyle, $suppress,$mgl,$mgr,$mgt,$mgb,$mgh,$mgf,$ohname,$ehname,$ofname,$efname,$ohvalue,$ehvalue,$ofvalue,$efvalue,$pagesel,$newformat); }
14817 else if ($type == 'NEXT-EVEN') { $this->AddPage($orient,'NEXT-EVEN', $resetpagenum, $pagenumstyle, $suppress,$mgl,$mgr,$mgt,$mgb,$mgh,$mgf,$ohname,$ehname,$ofname,$efname,$ohvalue,$ehvalue,$ofvalue,$efvalue,$pagesel,$newformat); }
14818 else { $this->AddPage($orient,'', $resetpagenum, $pagenumstyle, $suppress,$mgl,$mgr,$mgt,$mgb,$mgh,$mgf,$ohname,$ehname,$ofname,$efname,$ohvalue,$ehvalue,$ofvalue,$efvalue,$pagesel,$newformat); }
14819
14820 /*-- TOC --*/
14821 if ($tag == 'TOCPAGEBREAK') {
14822 if ($toc_id) { $this->tocontents->m_TOC[$toc_id]['TOCmark'] = $this->page; }
14823 else { $this->tocontents->TOCmark = $this->page; }
14824 }
14825 /*-- END TOC --*/
14826
14827 /*-- COLUMNS --*/
14828 if ($save_cols) {
14829 // Restore columns
14830 $this->SetColumns($save_nbcol,$this->colvAlign,$this->ColGap);
14831 }
14832 /*-- END COLUMNS --*/
14833 if (($tag == 'FORMFEED' || $this->restoreBlockPagebreaks) && !$this->tableLevel && !$this->listlvl) {
14834 $this->blk = $save_blk;
14835 // Re-open block tags
14836 $t = $this->blk[0]['tag'];
14837 $a = $this->blk[0]['attr'];
14838 $this->blklvl = 0;
14839 for ($b=0; $b<=$save_blklvl;$b++) {
14840 $tc = $t;
14841 $ac = $a;
14842 $t = $this->blk[$b+1]['tag'];
14843 $a = $this->blk[$b+1]['attr'];
14844 unset($this->blk[$b+1]);
14845 $this->OpenTag($tc,$ac);
14846 }
14847 $this->spanlvl = $save_spanlvl;
14848 $this->InlineProperties = $save_ilp;
14849 $this->restoreInlineProperties($save_silp);
14850 }
14851
14852 break;
14853
14854
14855 /*-- TOC --*/
14856 case 'TOCENTRY':
14857 if (isset($attr['CONTENT']) && $attr['CONTENT']) {
14858 $objattr = array();
14859 $objattr['CONTENT'] = htmlspecialchars_decode($attr['CONTENT'],ENT_QUOTES);
14860 $objattr['type'] = 'toc';
14861 if (isset($attr['LEVEL']) && $attr['LEVEL']) { $objattr['toclevel'] = $attr['LEVEL']; } else { $objattr['toclevel'] = 0; }
14862 if (isset($attr['NAME']) && $attr['NAME']) { $objattr['toc_id'] = $attr['NAME']; } else { $objattr['toc_id'] = 0; }
14863 $e = "\xbb\xa4\xactype=toc,objattr=".serialize($objattr)."\xbb\xa4\xac";
14864 if($this->tableLevel) { $this->cell[$this->row][$this->col]['textbuffer'][] = array($e); } // *TABLES*
14865 else { // *TABLES*
14866 $this->textbuffer[] = array($e);
14867 } // *TABLES*
14868 }
14869 break;
14870 /*-- END TOC --*/
14871
14872 /*-- INDEX --*/
14873 case 'INDEXENTRY':
14874 if (isset($attr['CONTENT']) && $attr['CONTENT']) {
14875 if (isset($attr['XREF']) && $attr['XREF']) {
14876 $this->IndexEntry(htmlspecialchars_decode($attr['CONTENT'],ENT_QUOTES),$attr['XREF']);
14877 break;
14878 }
14879 $objattr = array();
14880 $objattr['CONTENT'] = htmlspecialchars_decode($attr['CONTENT'],ENT_QUOTES);
14881 $objattr['type'] = 'indexentry';
14882 $e = "\xbb\xa4\xactype=indexentry,objattr=".serialize($objattr)."\xbb\xa4\xac";
14883 if($this->tableLevel) { $this->cell[$this->row][$this->col]['textbuffer'][] = array($e); } // *TABLES*
14884 else { // *TABLES*
14885 $this->textbuffer[] = array($e);
14886 } // *TABLES*
14887 }
14888 break;
14889
14890
14891 case 'INDEXINSERT':
14892 if (isset($attr['FONT-SIZE'])) { $reffontsize = $attr['FONT-SIZE']; } else { $reffontsize = ''; }
14893 if (isset($attr['LINE-SPACING']) && $attr['LINE-SPACING']) { $linespacing = $attr['LINE-SPACING']; } else { $linespacing = ''; }
14894 if (isset($attr['DIV-FONT-SIZE']) && $attr['DIV-FONT-SIZE']) { $divlettfontsize = $attr['DIV-FONT-SIZE']; } else { $divlettfontsize = ''; }
14895 if (isset($attr['FONT']) && $attr['FONT']) { $reffont = $attr['FONT']; } else { $reffont = ''; }
14896 if (isset($attr['DIV-FONT']) && $attr['DIV-FONT']) { $divlettfont = $attr['DIV-FONT']; } else { $divlettfont = ''; }
14897 if (isset($attr['COLS']) && $attr['COLS']) { $cols = $attr['COLS']; } else { $cols = 1; }
14898 if (isset($attr['OFFSET']) && $attr['OFFSET']) { $offset = $attr['OFFSET']; } else { $offset = 3; }
14899 if (isset($attr['GAP']) && $attr['GAP']) { $gap = $attr['GAP']; } else { $gap = 5; }
14900
14901 if (isset($attr['USEDIVLETTERS']) && (strtoupper($attr['USEDIVLETTERS'])=='OFF' || $attr['USEDIVLETTERS']==-1 || $attr['USEDIVLETTERS']==='0')) { $usedivletters = 0; }
14902 else { $usedivletters = 1; }
14903
14904 if (isset($attr['LINKS']) && (strtoupper($attr['LINKS'])=='ON' || $attr['LINKS']==1)) { $links = true; }
14905 else { $links = false; }
14906 $this->CreateIndex($cols, $reffontsize, $linespacing, $offset, $usedivletters, $divlettfontsize, $gap, $reffont,$divlettfont, $links);
14907 break;
14908 /*-- END INDEX --*/
14909
14910 /*-- WATERMARK --*/
14911
14912 case 'WATERMARKTEXT':
14913 if (isset($attr['CONTENT']) && $attr['CONTENT']) { $txt = htmlspecialchars_decode($attr['CONTENT'],ENT_QUOTES); } else { $txt = ''; }
14914 if (isset($attr['ALPHA']) && $attr['ALPHA']>0) { $alpha = $attr['ALPHA']; } else { $alpha = -1; }
14915 $this->SetWatermarkText($txt, $alpha);
14916 break;
14917
14918
14919 case 'WATERMARKIMAGE':
14920 if (isset($attr['SRC'])) { $src = $attr['SRC']; } else { $src = ''; }
14921 if (isset($attr['ALPHA']) && $attr['ALPHA']>0) { $alpha = $attr['ALPHA']; } else { $alpha = -1; }
14922 if (isset($attr['SIZE']) && $attr['SIZE']) {
14923 $size = $attr['SIZE'];
14924 if (strpos($size,',')) { $size = explode(',',$size); }
14925 }
14926 else { $size = 'D'; }
14927 if (isset($attr['POS']) && $attr['POS']) {
14928 $pos = $attr['POS'];
14929 if (strpos($pos,',')) { $pos = explode(',',$pos); }
14930 }
14931 else { $pos = 'P'; }
14932 $this->SetWatermarkImage($src, $alpha, $size, $pos);
14933 break;
14934 /*-- END WATERMARK --*/
14935
14936 /*-- BOOKMARKS --*/
14937 case 'BOOKMARK':
14938 if (isset($attr['CONTENT'])) {
14939 $objattr = array();
14940 $objattr['CONTENT'] = htmlspecialchars_decode($attr['CONTENT'],ENT_QUOTES);
14941 $objattr['type'] = 'bookmark';
14942 if (isset($attr['LEVEL']) && $attr['LEVEL']) { $objattr['bklevel'] = $attr['LEVEL']; } else { $objattr['bklevel'] = 0; }
14943 $e = "\xbb\xa4\xactype=bookmark,objattr=".serialize($objattr)."\xbb\xa4\xac";
14944 if($this->tableLevel) { $this->cell[$this->row][$this->col]['textbuffer'][] = array($e); } // *TABLES*
14945 else { // *TABLES*
14946 $this->textbuffer[] = array($e);
14947 } // *TABLES*
14948 }
14949 break;
14950 /*-- END BOOKMARKS --*/
14951
14952 /*-- ANNOTATIONS --*/
14953 case 'ANNOTATION':
14954
14955 //if (isset($attr['CONTENT']) && !$this->writingHTMLheader && !$this->writingHTMLfooter) { // Stops annotations in FixedPos
14956 if (isset($attr['CONTENT'])) {
14957 $objattr = array();
14958 $objattr['margin_top'] = 0;
14959 $objattr['margin_bottom'] = 0;
14960 $objattr['margin_left'] = 0;
14961 $objattr['margin_right'] = 0;
14962 $objattr['width'] = 0;
14963 $objattr['height'] = 0;
14964 $objattr['border_top']['w'] = 0;
14965 $objattr['border_bottom']['w'] = 0;
14966 $objattr['border_left']['w'] = 0;
14967 $objattr['border_right']['w'] = 0;
14968 $objattr['CONTENT'] = htmlspecialchars_decode($attr['CONTENT'],ENT_QUOTES);
14969 $objattr['type'] = 'annot';
14970 $objattr['POPUP'] = '';
14971 }
14972 else { break; }
14973 if (isset($attr['POS-X'])) { $objattr['POS-X'] = $attr['POS-X']; } else { $objattr['POS-X'] = 0; }
14974 if (isset($attr['POS-Y'])) { $objattr['POS-Y'] = $attr['POS-Y']; } else { $objattr['POS-Y'] = 0; }
14975 if (isset($attr['ICON'])) { $objattr['ICON'] = $attr['ICON']; } else { $objattr['ICON'] = 'Note'; }
14976 if (isset($attr['AUTHOR'])) { $objattr['AUTHOR'] = $attr['AUTHOR']; }
14977 else if (isset($attr['TITLE'])) { $objattr['AUTHOR'] = $attr['TITLE']; } else { $objattr['AUTHOR'] = ''; }
14978 if (isset($attr['FILE'])) { $objattr['FILE'] = $attr['FILE']; } else { $objattr['FILE'] = ''; }
14979 if (isset($attr['SUBJECT'])) { $objattr['SUBJECT'] = $attr['SUBJECT']; } else { $objattr['SUBJECT'] = ''; }
14980 if (isset($attr['OPACITY']) && $attr['OPACITY']>0 && $attr['OPACITY']<=1) { $objattr['OPACITY'] = $attr['OPACITY']; }
14981 else if ($this->annotMargin) { $objattr['OPACITY'] = 1; }
14982 else { $objattr['OPACITY'] = $this->annotOpacity; }
14983 if (isset($attr['COLOR'])) {
14984 $cor = $this->ConvertColor($attr['COLOR']);
14985 if ($cor) { $objattr['COLOR'] = $cor; }
14986 else { $objattr['COLOR'] = $this->ConvertColor('yellow'); }
14987 }
14988 else { $objattr['COLOR'] = $this->ConvertColor('yellow'); }
14989
14990 if (isset($attr['POPUP']) && !empty($attr['POPUP'])) {
14991 $pop = preg_split('/\s+/',trim($attr['POPUP']));
14992 if (count($pop)>1) { $objattr['POPUP'] = $pop; }
14993 else { $objattr['POPUP'] = true; }
14994 }
14995 $e = "\xbb\xa4\xactype=annot,objattr=".serialize($objattr)."\xbb\xa4\xac";
14996 if($this->tableLevel) { $this->cell[$this->row][$this->col]['textbuffer'][] = array($e); } // *TABLES*
14997 else { // *TABLES*
14998 $this->textbuffer[] = array($e);
14999 } // *TABLES*
15000 break;
15001 /*-- END ANNOTATIONS --*/
15002
15003
15004 /*-- COLUMNS --*/
15005 case 'COLUMNS': //added custom-tag
15006 if (isset($attr['COLUMN-COUNT']) && ($attr['COLUMN-COUNT'] || $attr['COLUMN-COUNT']==='0')) {
15007 // Close any open block tags
15008 for ($b= $this->blklvl;$b>0;$b--) { $this->CloseTag($this->blk[$b]['tag']); }
15009 if(!empty($this->textbuffer)) { //Output previously buffered content
15010 $this->printbuffer($this->textbuffer);
15011 $this->textbuffer=array();
15012 }
15013
15014 if (isset($attr['VALIGN']) && $attr['VALIGN']) {
15015 if ($attr['VALIGN'] == 'J') { $valign = 'J'; }
15016 else { $valign = $align[$attr['VALIGN']]; }
15017 }
15018 else { $valign = ''; }
15019 if (isset($attr['COLUMN-GAP']) && $attr['COLUMN-GAP']) { $this->SetColumns($attr['COLUMN-COUNT'],$valign,$attr['COLUMN-GAP']); }
15020 else { $this->SetColumns($attr['COLUMN-COUNT'],$valign); }
15021 }
15022 $this->ignorefollowingspaces = true;
15023 break;
15024
15025 case 'COLUMN_BREAK': //custom-tag
15026 case 'COLUMNBREAK': //custom-tag
15027 case 'NEWCOLUMN': //custom-tag
15028 $this->ignorefollowingspaces = true;
15029 $this->NewColumn();
15030 $this->ColumnAdjust = false; // disables all column height adjustment for the page.
15031 break;
15032
15033 /*-- END COLUMNS --*/
15034
15035
15036 case 'BDO':
15037 // $this->biDirectional = true;
15038 break;
15039
15040
15041 case 'TTZ':
15042 $this->ttz = true;
15043 $this->InlineProperties[$tag] = $this->saveInlineProperties();
15044 $this->setCSS(array('FONT-FAMILY'=>'czapfdingbats','FONT-WEIGHT'=>'normal','FONT-STYLE'=>'normal'),'INLINE');
15045 break;
15046
15047 case 'TTS':
15048 $this->tts = true;
15049 $this->InlineProperties[$tag] = $this->saveInlineProperties();
15050 $this->setCSS(array('FONT-FAMILY'=>'csymbol','FONT-WEIGHT'=>'normal','FONT-STYLE'=>'normal'),'INLINE');
15051 break;
15052
15053 case 'TTA':
15054 $this->tta = true;
15055 $this->InlineProperties[$tag] = $this->saveInlineProperties();
15056
15057 if (in_array($this->FontFamily,$this->mono_fonts)) {
15058 $this->setCSS(array('FONT-FAMILY'=>'ccourier'),'INLINE');
15059 }
15060 else if (in_array($this->FontFamily,$this->serif_fonts)) {
15061 $this->setCSS(array('FONT-FAMILY'=>'ctimes'),'INLINE');
15062 }
15063 else {
15064 $this->setCSS(array('FONT-FAMILY'=>'chelvetica'),'INLINE');
15065 }
15066 break;
15067
15068
15069
15070 // INLINE PHRASES OR STYLES
15071 case 'SUB':
15072 case 'SUP':
15073 case 'ACRONYM':
15074 case 'BIG':
15075 case 'SMALL':
15076 case 'INS':
15077 case 'S':
15078 case 'STRIKE':
15079 case 'DEL':
15080 case 'STRONG':
15081 case 'CITE':
15082 case 'Q':
15083 case 'EM':
15084 case 'B':
15085 case 'I':
15086 case 'U':
15087 case 'SAMP':
15088 case 'CODE':
15089 case 'KBD':
15090 case 'TT':
15091 case 'VAR':
15092 case 'FONT':
15093 case 'MARK': // mPDF 5.5.09
15094 case 'TIME':
15095
15096 case 'SPAN':
15097 /*-- ANNOTATIONS --*/
15098 if ($this->title2annots && isset($attr['TITLE'])) {
15099 $objattr = array();
15100 $objattr['margin_top'] = 0;
15101 $objattr['margin_bottom'] = 0;
15102 $objattr['margin_left'] = 0;
15103 $objattr['margin_right'] = 0;
15104 $objattr['width'] = 0;
15105 $objattr['height'] = 0;
15106 $objattr['border_top']['w'] = 0;
15107 $objattr['border_bottom']['w'] = 0;
15108 $objattr['border_left']['w'] = 0;
15109 $objattr['border_right']['w'] = 0;
15110
15111 $objattr['CONTENT'] = $attr['TITLE'];
15112 $objattr['type'] = 'annot';
15113 $objattr['POS-X'] = 0;
15114 $objattr['POS-Y'] = 0;
15115 $objattr['ICON'] = 'Comment';
15116 $objattr['AUTHOR'] = '';
15117 $objattr['SUBJECT'] = '';
15118 $objattr['OPACITY'] = $this->annotOpacity;
15119 $objattr['COLOR'] = $this->ConvertColor('yellow');
15120 $annot = "\xbb\xa4\xactype=annot,objattr=".serialize($objattr)."\xbb\xa4\xac";
15121 }
15122 /*-- END ANNOTATIONS --*/
15123
15124 if ($tag == 'SPAN') {
15125 $this->spanlvl++;
15126 $this->InlineProperties['SPAN'][$this->spanlvl] = $this->saveInlineProperties();
15127 if (isset($annot)) { $this->InlineAnnots[$tag][$this->spanlvl] = $annot; } // *ANNOTATIONS*
15128 }
15129 else {
15130 if (!isset($this->InlineProperties[$tag])) $this->InlineProperties[$tag] = $this->saveInlineProperties(); // mPDF 5.4.13
15131 if (isset($annot)) { $this->InlineAnnots[$tag] = $annot; } // *ANNOTATIONS*
15132 }
15133 $properties = $this->cssmgr->MergeCSS('INLINE',$tag,$attr);
15134 if (!empty($properties)) $this->setCSS($properties,'INLINE');
15135 break;
15136
15137
15138 case 'A':
15139 if (isset($attr['NAME']) and $attr['NAME'] != '') {
15140 $e = '';
15141 /*-- BOOKMARKS --*/
15142 if ($this->anchor2Bookmark) {
15143 $objattr = array();
15144 $objattr['CONTENT'] = htmlspecialchars_decode($attr['NAME'],ENT_QUOTES);
15145 $objattr['type'] = 'bookmark';
15146 if (isset($attr['LEVEL']) && $attr['LEVEL']) { $objattr['bklevel'] = $attr['LEVEL']; } else { $objattr['bklevel'] = 0; }
15147 $e = "\xbb\xa4\xactype=bookmark,objattr=".serialize($objattr)."\xbb\xa4\xac";
15148 }
15149 /*-- END BOOKMARKS --*/
15150 if($this->tableLevel) { // *TABLES*
15151 $this->_saveCellTextBuffer($e, '', $attr['NAME']); // *TABLES*
15152 } // *TABLES*
15153 else { // *TABLES*
15154 $this->_saveTextBuffer($e, '', $attr['NAME']); //an internal link (adds a space for recognition)
15155 } // *TABLES*
15156 }
15157 if (isset($attr['HREF'])) {
15158 $this->InlineProperties['A'] = $this->saveInlineProperties();
15159 $properties = $this->cssmgr->MergeCSS('',$tag,$attr);
15160 if (!empty($properties)) $this->setCSS($properties,'INLINE');
15161 $this->HREF=htmlspecialchars_decode(urldecode($attr['HREF']));
15162 }
15163 break;
15164
15165 case 'LEGEND': // mPDF 5.4.18
15166 $this->InlineProperties['LEGEND'] = $this->saveInlineProperties();
15167 $properties = $this->cssmgr->MergeCSS('',$tag,$attr);
15168 if (!empty($properties)) $this->setCSS($properties,'INLINE');
15169 break;
15170
15171
15172
15173 case 'PROGRESS': // mPDF 5.5.09
15174 case 'METER': // mPDF 5.5.09
15175 $this->inMeter = true; // mPDF 5.5.09
15176
15177 if (isset($attr['MAX']) && $attr['MAX']) { $max = $attr['MAX']; }
15178 else { $max = 1; }
15179 if (isset($attr['MIN']) && $attr['MIN'] && $tag=='METER') { $min = $attr['MIN']; }
15180 else { $min = 0; }
15181 if ($max < $min) { $max = $min; }
15182
15183 if (isset($attr['VALUE']) && ($attr['VALUE'] || $attr['VALUE']==='0')) {
15184 $value = $attr['VALUE'];
15185 if ($value < $min) { $value = $min; }
15186 else if ($value > $max) { $value = $max; }
15187 }
15188 else { $value = ''; }
15189
15190 if (isset($attr['LOW']) && $attr['LOW']) { $low = $attr['LOW']; }
15191 else { $low = $min; }
15192 if ($low < $min) { $low = $min; }
15193 else if ($low > $max) { $low = $max; }
15194 if (isset($attr['HIGH']) && $attr['HIGH']) { $high = $attr['HIGH']; }
15195 else { $high = $max; }
15196 if ($high < $low) { $high = $low; }
15197 else if ($high > $max) { $high = $max; }
15198 if (isset($attr['OPTIMUM']) && $attr['OPTIMUM']) { $optimum = $attr['OPTIMUM']; }
15199 else { $optimum = $min + (($max-$min)/2); }
15200 if ($optimum < $min) { $optimum = $min; }
15201 else if ($optimum > $max) { $optimum = $max; }
15202 if (isset($attr['TYPE']) && $attr['TYPE']) { $type = $attr['TYPE']; }
15203 else { $type = ''; }
15204 $objattr = array();
15205 $objattr['margin_top'] = 0;
15206 $objattr['margin_bottom'] = 0;
15207 $objattr['margin_left'] = 0;
15208 $objattr['margin_right'] = 0;
15209 $objattr['padding_top'] = 0;
15210 $objattr['padding_bottom'] = 0;
15211 $objattr['padding_left'] = 0;
15212 $objattr['padding_right'] = 0;
15213 $objattr['width'] = 0;
15214 $objattr['height'] = 0;
15215 $objattr['border_top']['w'] = 0;
15216 $objattr['border_bottom']['w'] = 0;
15217 $objattr['border_left']['w'] = 0;
15218 $objattr['border_right']['w'] = 0;
15219
15220 $properties = $this->cssmgr->MergeCSS('',$tag,$attr);
15221 if(isset($properties ['DISPLAY']) && strtolower($properties ['DISPLAY'])=='none') {
15222 return;
15223 }
15224 $objattr['visibility'] = 'visible';
15225 if (isset($properties['VISIBILITY'])) {
15226 $v = strtolower($properties['VISIBILITY']);
15227 if (($v == 'hidden' || $v == 'printonly' || $v == 'screenonly') && $this->visibility=='visible') {
15228 $objattr['visibility'] = $v;
15229 }
15230 }
15231
15232 if (isset($properties['MARGIN-TOP'])) { $objattr['margin_top']=$this->ConvertSize($properties['MARGIN-TOP'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
15233 if (isset($properties['MARGIN-BOTTOM'])) { $objattr['margin_bottom'] = $this->ConvertSize($properties['MARGIN-BOTTOM'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
15234 if (isset($properties['MARGIN-LEFT'])) { $objattr['margin_left'] = $this->ConvertSize($properties['MARGIN-LEFT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
15235 if (isset($properties['MARGIN-RIGHT'])) { $objattr['margin_right'] = $this->ConvertSize($properties['MARGIN-RIGHT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
15236
15237 if (isset($properties['PADDING-TOP'])) { $objattr['padding_top']=$this->ConvertSize($properties['PADDING-TOP'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
15238 if (isset($properties['PADDING-BOTTOM'])) { $objattr['padding_bottom'] = $this->ConvertSize($properties['PADDING-BOTTOM'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
15239 if (isset($properties['PADDING-LEFT'])) { $objattr['padding_left'] = $this->ConvertSize($properties['PADDING-LEFT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
15240 if (isset($properties['PADDING-RIGHT'])) { $objattr['padding_right'] = $this->ConvertSize($properties['PADDING-RIGHT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
15241
15242 if (isset($properties['BORDER-TOP'])) { $objattr['border_top'] = $this->border_details($properties['BORDER-TOP']); }
15243 if (isset($properties['BORDER-BOTTOM'])) { $objattr['border_bottom'] = $this->border_details($properties['BORDER-BOTTOM']); }
15244 if (isset($properties['BORDER-LEFT'])) { $objattr['border_left'] = $this->border_details($properties['BORDER-LEFT']); }
15245 if (isset($properties['BORDER-RIGHT'])) { $objattr['border_right'] = $this->border_details($properties['BORDER-RIGHT']); }
15246
15247 if (isset($properties['VERTICAL-ALIGN'])) { $objattr['vertical-align'] = $align[strtolower($properties['VERTICAL-ALIGN'])]; }
15248 $w = 0;
15249 $h = 0;
15250 if(isset($properties['WIDTH'])) $w = $this->ConvertSize($properties['WIDTH'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
15251 else if(isset($attr['WIDTH'])) $w = $this->ConvertSize($attr['WIDTH'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
15252
15253 if(isset($properties['HEIGHT'])) $h = $this->ConvertSize($properties['HEIGHT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
15254 else if(isset($attr['HEIGHT'])) $h = $this->ConvertSize($attr['HEIGHT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
15255
15256 if (isset($properties['OPACITY']) && $properties['OPACITY'] > 0 && $properties['OPACITY'] <= 1) { $objattr['opacity'] = $properties['OPACITY']; }
15257 if ($this->HREF) {
15258 if (strpos($this->HREF,".") === false && strpos($this->HREF,"@") !== 0) {
15259 $href = $this->HREF;
15260 while(array_key_exists($href,$this->internallink)) $href="#".$href;
15261 $this->internallink[$href] = $this->AddLink();
15262 $objattr['link'] = $this->internallink[$href];
15263 }
15264 else { $objattr['link'] = $this->HREF; }
15265 }
15266 $extraheight = $objattr['padding_top'] + $objattr['padding_bottom'] + $objattr['margin_top'] + $objattr['margin_bottom'] + $objattr['border_top']['w'] + $objattr['border_bottom']['w'];
15267 $extrawidth = $objattr['padding_left'] + $objattr['padding_right'] + $objattr['margin_left'] + $objattr['margin_right'] + $objattr['border_left']['w'] + $objattr['border_right']['w'];
15268
15269 // Image file
15270 if (!class_exists('meter', false)) {
15271 include(_MPDF_PATH.'classes/meter.php');
15272 }
15273 $this->meter = new meter();
15274 $svg = $this->meter->makeSVG(strtolower($tag), $type, $value, $max, $min, $optimum, $low, $high);
15275 //Save to local file
15276 $srcpath= _MPDF_TEMP_PATH.'_tempSVG'.RAND(1,10000).'_'.strtolower($tag).'.svg';
15277 file_put_contents($srcpath, $svg);
15278 $orig_srcpath = $srcpath;
15279 $this->GetFullPath($srcpath);
15280
15281 $info=$this->_getImage($srcpath, true, true, $orig_srcpath);
15282 if(!$info) {
15283 $info = $this->_getImage($this->noImageFile);
15284 if ($info) {
15285 $srcpath = $this->noImageFile;
15286 $w = ($info['w'] * (25.4/$this->dpi));
15287 $h = ($info['h'] * (25.4/$this->dpi));
15288 }
15289 }
15290 if(!$info) break;
15291
15292 $objattr['file'] = $srcpath;
15293 //Default width and height calculation if needed
15294 if($w==0 and $h==0) {
15295 // SVG units are pixels
15296 $w = $this->FontSize/(10/_MPDFK) * abs($info['w'])/_MPDFK; // mPDF 5.5.21
15297 $h = $this->FontSize/(10/_MPDFK) * abs($info['h'])/_MPDFK;
15298 }
15299 // IF WIDTH OR HEIGHT SPECIFIED
15300 if($w==0) $w=abs($h*$info['w']/$info['h']);
15301 if($h==0) $h=abs($w*$info['h']/$info['w']);
15302
15303 // Resize to maximum dimensions of page
15304 $maxWidth = $this->blk[$this->blklvl]['inner_width'];
15305 $maxHeight = $this->h - ($this->tMargin + $this->bMargin + 1) ;
15306 if ($this->fullImageHeight) { $maxHeight = $this->fullImageHeight; }
15307 if ($w + $extrawidth > $maxWidth ) {
15308 $w = $maxWidth - $extrawidth;
15309 $h=abs($w*$info['h']/$info['w']);
15310 }
15311
15312 if ($h + $extraheight > $maxHeight ) {
15313 $h = $maxHeight - $extraheight;
15314 $w=abs($h*$info['w']/$info['h']);
15315 }
15316 $objattr['type'] = 'image';
15317 $objattr['itype'] = $info['type'];
15318
15319 $objattr['orig_h'] = $info['h'];
15320 $objattr['orig_w'] = $info['w'];
15321 $objattr['wmf_x'] = $info['x'];
15322 $objattr['wmf_y'] = $info['y'];
15323 $objattr['height'] = $h + $extraheight;
15324 $objattr['width'] = $w + $extrawidth;
15325 $objattr['image_height'] = $h;
15326 $objattr['image_width'] = $w;
15327 $e = "\xbb\xa4\xactype=image,objattr=".serialize($objattr)."\xbb\xa4\xac";
15328 $properties = array();
15329 if ($this->tableLevel) {
15330 $this->_saveCellTextBuffer($e, $this->HREF);
15331 $this->cell[$this->row][$this->col]['s'] += $objattr['width'] ;
15332 }
15333 else {
15334 $this->_saveTextBuffer($e, $this->HREF);
15335 }
15336
15337 break;
15338
15339
15340 case 'BR':
15341 // Added mPDF 3.0 Float DIV - CLEAR
15342 if (isset($attr['STYLE'])) {
15343 $properties = $this->cssmgr->readInlineCSS($attr['STYLE']);
15344 if (isset($properties['CLEAR'])) { $this->ClearFloats(strtoupper($properties['CLEAR']),$this->blklvl); } // *CSS-FLOAT*
15345 }
15346
15347
15348 /*-- TABLES --*/
15349 if($this->tableLevel) {
15350
15351 if ($this->blockjustfinished || $this->listjustfinished) {
15352 $this->_saveCellTextBuffer("\n");
15353 }
15354
15355 $this->_saveCellTextBuffer("\n");
15356 if (!isset($this->cell[$this->row][$this->col]['maxs'])) {
15357 $this->cell[$this->row][$this->col]['maxs'] = $this->cell[$this->row][$this->col]['s'];
15358 }
15359 elseif($this->cell[$this->row][$this->col]['maxs'] < $this->cell[$this->row][$this->col]['s']) {
15360 $this->cell[$this->row][$this->col]['maxs'] = $this->cell[$this->row][$this->col]['s'];
15361 }
15362 $this->cell[$this->row][$this->col]['s'] = 0 ;// reset
15363 }
15364 else {
15365 /*-- END TABLES --*/
15366 if (count($this->textbuffer)) {
15367 $this->textbuffer[count($this->textbuffer)-1][0] = preg_replace('/ $/','',$this->textbuffer[count($this->textbuffer)-1][0]);
15368 }
15369 $this->_saveTextBuffer("\n");
15370 } // *TABLES*
15371 $this->ignorefollowingspaces = true;
15372 $this->blockjustfinished=false;
15373 $this->listjustfinished=false;
15374
15375 $this->linebreakjustfinished=true;
15376 break;
15377
15378
15379 // *********** BLOCKS ********************
15380
15381
15382 case 'PRE':
15383 $this->ispre=true; // ADDED - Prevents left trim of textbuffer in printbuffer()
15384
15385 case 'DIV':
15386 case 'FORM':
15387 case 'CENTER':
15388
15389 case 'BLOCKQUOTE':
15390 case 'ADDRESS':
15391
15392 case 'CAPTION':
15393 case 'P':
15394 case 'H1':
15395 case 'H2':
15396 case 'H3':
15397 case 'H4':
15398 case 'H5':
15399 case 'H6':
15400 case 'DL':
15401 case 'DT':
15402 case 'DD':
15403 case 'FIELDSET':
15404 // mPDF 5.5.22
15405 case 'DETAILS':
15406 case 'SUMMARY':
15407 // mPDF 5.5.09
15408 case 'ARTICLE':
15409 case 'ASIDE':
15410 case 'FIGURE':
15411 case 'FIGCAPTION':
15412 case 'FOOTER':
15413 case 'HEADER':
15414 case 'HGROUP':
15415 case 'NAV':
15416 case 'SECTION':
15417 $p = $this->cssmgr->PreviewBlockCSS($tag,$attr);
15418 if(isset($p['DISPLAY']) && strtolower($p['DISPLAY'])=='none') {
15419 $this->blklvl++;
15420 $this->blk[$this->blklvl]['hide'] = true;
15421 return;
15422 }
15423 if($tag == 'CAPTION') {
15424 // position is written in AdjstHTML
15425 if (isset($attr['POSITION']) && strtolower($attr['POSITION'])=='bottom') { $divpos = 'B'; }
15426 else { $divpos = 'T'; }
15427 if (isset($attr['ALIGN']) && strtolower($attr['ALIGN'])=='bottom') { $cappos = 'B'; }
15428 else if (isset($p['CAPTION-SIDE']) && strtolower($p['CAPTION-SIDE'])=='bottom') { $cappos = 'B'; }
15429 else { $cappos = 'T'; }
15430 if (isset($attr['ALIGN'])) { unset($attr['ALIGN']); }
15431 if ($cappos != $divpos) {
15432 $this->blklvl++;
15433 $this->blk[$this->blklvl]['hide'] = true;
15434 return;
15435 }
15436 }
15437
15438 /*-- FORMS --*/
15439 if($tag == 'FORM') {
15440 if (isset($attr['METHOD']) && strtolower($attr['METHOD'])=='get') { $this->form->formMethod = 'GET'; }
15441 else { $this->form->formMethod = 'POST'; }
15442 if (isset($attr['ACTION'])) { $this->form->formAction = $attr['ACTION']; }
15443 else { $this->form->formAction = ''; }
15444 }
15445 /*-- END FORMS --*/
15446
15447
15448 /*-- CSS-POSITION --*/
15449 if ((isset($p['POSITION']) && (strtolower($p['POSITION'])=='fixed' || strtolower($p['POSITION'])=='absolute')) && $this->blklvl==0) {
15450 if ($this->inFixedPosBlock) {
15451 $this->Error("Cannot nest block with position:fixed or position:absolute");
15452 }
15453 $this->inFixedPosBlock = true;
15454 return;
15455 }
15456 /*-- END CSS-POSITION --*/
15457 // Start Block
15458 $this->ignorefollowingspaces = true;
15459
15460 if ($this->blockjustfinished && !count($this->textbuffer) && $this->y != $this->tMargin && $this->collapseBlockMargins) { $lastbottommargin = $this->lastblockbottommargin; }
15461 else { $lastbottommargin = 0; }
15462 $this->lastblockbottommargin = 0;
15463 $this->blockjustfinished=false;
15464
15465 /*-- LISTS --*/
15466 if ($this->listlvl>0) { return; }
15467 /*-- END LISTS --*/
15468
15469 $this->InlineProperties = array();
15470 $this->spanlvl = 0;
15471 $this->listjustfinished=false;
15472 $this->divbegin=true;
15473
15474 $this->linebreakjustfinished=false;
15475
15476 /*-- TABLES --*/
15477 if ($this->tableLevel) {
15478
15479 // If already something on the line
15480 if ($this->cell[$this->row][$this->col]['s'] > 0 && !$this->nestedtablejustfinished ) {
15481 $this->_saveCellTextBuffer("\n");
15482 if (!isset($this->cell[$this->row][$this->col]['maxs'])) {
15483 $this->cell[$this->row][$this->col]['maxs'] = $this->cell[$this->row][$this->col]['s'];
15484 }
15485 elseif($this->cell[$this->row][$this->col]['maxs'] < $this->cell[$this->row][$this->col]['s']) {
15486 $this->cell[$this->row][$this->col]['maxs'] = $this->cell[$this->row][$this->col]['s'];
15487 }
15488 $this->cell[$this->row][$this->col]['s'] = 0 ;// reset
15489 }
15490 // Cannot set block properties inside table - use Bold to indicate h1-h6
15491 if ($tag == 'CENTER' && $this->tdbegin) { $this->cell[$this->row][$this->col]['a'] = $align['center']; }
15492
15493 $this->InlineProperties['BLOCKINTABLE'] = $this->saveInlineProperties();
15494 $properties = $this->cssmgr->MergeCSS('',$tag,$attr);
15495 if (!empty($properties)) $this->setCSS($properties,'INLINE');
15496
15497
15498 break;
15499 }
15500 /*-- END TABLES --*/
15501
15502 if ($tag == 'P' || $tag == 'DT' || $tag == 'DD') { $this->lastoptionaltag = $tag; } // Save current HTML specified optional endtag
15503 else { $this->lastoptionaltag = ''; }
15504
15505 if ($this->lastblocklevelchange == 1) { $blockstate = 1; } // Top margins/padding only
15506 else if ($this->lastblocklevelchange < 1) { $blockstate = 0; } // NO margins/padding
15507 $this->printbuffer($this->textbuffer,$blockstate);
15508 $this->textbuffer=array();
15509
15510 $save_blklvl = $this->blklvl;
15511 $save_blk = $this->blk;
15512 $save_silp = $this->saveInlineProperties();
15513 $save_spanlvl = $this->spanlvl;
15514 $save_ilp = $this->InlineProperties;
15515
15516 $this->blklvl++;
15517
15518 $currblk =& $this->blk[$this->blklvl];
15519 $this->initialiseBlock($currblk);
15520 $prevblk =& $this->blk[$this->blklvl-1];
15521
15522 $currblk['tag'] = $tag;
15523 $currblk['attr'] = $attr;
15524
15525 $this->Reset();
15526 $properties = $this->cssmgr->MergeCSS('BLOCK',$tag,$attr);
15527 $pagesel = '';
15528 /*-- CSS-PAGE --*/
15529
15530 if (isset($properties['PAGE'])) { $pagesel = $properties['PAGE']; }
15531 /*-- END CSS-PAGE --*/
15532
15533 // If page-box has changed AND/OR PAGE-BREAK-BEFORE
15534 $save_cols = false;
15535 if (($pagesel && $pagesel != $this->page_box['current']) || (isset($properties['PAGE-BREAK-BEFORE']) && $properties['PAGE-BREAK-BEFORE'])) {
15536 if ($this->blklvl>1) {
15537 // Close any open block tags
15538 for ($b= $this->blklvl;$b>0;$b--) { $this->CloseTag($this->blk[$b]['tag']); }
15539 // Output any text left in buffer
15540 if (count($this->textbuffer)) { $this->printbuffer($this->textbuffer); $this->textbuffer=array(); }
15541 }
15542 /*-- COLUMNS --*/
15543 if ($this->ColActive) {
15544 $save_cols = true;
15545 $save_nbcol = $this->NbCol; // other values of gap and vAlign will not change by setting Columns off
15546 $this->SetColumns(0);
15547 }
15548 /*-- END COLUMNS --*/
15549
15550
15551 // Must Add new page if changed page properties
15552 if (isset($properties['PAGE-BREAK-BEFORE'])) {
15553 if (strtoupper($properties['PAGE-BREAK-BEFORE']) == 'RIGHT') { $this->AddPage($this->CurOrientation,'NEXT-ODD','','','','','', '','', '','','','','','',0,0,0,0,$pagesel); }
15554 else if (strtoupper($properties['PAGE-BREAK-BEFORE']) == 'LEFT') { $this->AddPage($this->CurOrientation,'NEXT-EVEN','','','','','', '','', '','','','','','',0,0,0,0,$pagesel); }
15555 else if (strtoupper($properties['PAGE-BREAK-BEFORE']) == 'ALWAYS') { $this->AddPage($this->CurOrientation,'','','','','','', '','', '','','','','','',0,0,0,0,$pagesel); }
15556 else if ($this->page_box['current'] != $pagesel) { $this->AddPage($this->CurOrientation,'','','','','','', '','', '','','','','','',0,0,0,0,$pagesel); } // *CSS-PAGE*
15557 }
15558 /*-- CSS-PAGE --*/
15559 else if ($pagesel != $this->page_box['current']) { $this->AddPage($this->CurOrientation,'','','','','','', '','', '','','','','','',0,0,0,0,$pagesel); }
15560 /*-- END CSS-PAGE --*/
15561
15562 // if using htmlheaders, the headers need to be rewritten when new page
15563 // done by calling WriteHTML() within resethtmlheaders
15564 // so block is reset to 0 - now we need to resurrect it
15565 // As in WriteHTML() initialising
15566 if (!($this->restoreBlockPagebreaks && isset($properties['PAGE-BREAK-BEFORE']) && $properties['PAGE-BREAK-BEFORE'])) {
15567 $this->blklvl = 0;
15568 $this->lastblocklevelchange = 0;
15569 $this->blk = array();
15570 $this->initialiseBlock($this->blk[0]);
15571 $this->blk[0]['width'] =& $this->pgwidth;
15572 $this->blk[0]['inner_width'] =& $this->pgwidth;
15573 $this->blk[0]['blockContext'] = $this->blockContext;
15574 $properties = $this->cssmgr->MergeCSS('BLOCK','BODY','');
15575 $this->setCSS($properties,'','BODY');
15576 $this->blklvl++;
15577 $currblk =& $this->blk[$this->blklvl];
15578 $prevblk =& $this->blk[$this->blklvl-1];
15579
15580 $this->initialiseBlock($currblk);
15581 $currblk['tag'] = $tag;
15582 $currblk['attr'] = $attr;
15583
15584 $this->Reset();
15585 $properties = $this->cssmgr->MergeCSS('BLOCK',$tag,$attr);
15586 }
15587 /*-- COLUMNS --*/
15588 if ($save_cols) {
15589 // Restore columns
15590 $this->SetColumns($save_nbcol,$this->colvAlign,$this->ColGap);
15591 }
15592 /*-- END COLUMNS --*/
15593 if ($this->restoreBlockPagebreaks && isset($properties['PAGE-BREAK-BEFORE']) && $properties['PAGE-BREAK-BEFORE']) {
15594 $this->blk = $save_blk;
15595 // Re-open block tags
15596 $t = $this->blk[0]['tag'];
15597 $a = $this->blk[0]['attr'];
15598 $this->blklvl = 0;
15599 for ($b=0; $b<=$save_blklvl;$b++) {
15600 $tc = $t;
15601 $ac = $a;
15602 $t = $this->blk[$b+1]['tag'];
15603 $a = $this->blk[$b+1]['attr'];
15604 unset($this->blk[$b+1]);
15605 $this->OpenTag($tc,$ac);
15606 }
15607 $this->spanlvl = $save_spanlvl;
15608 $this->InlineProperties = $save_ilp;
15609 $this->restoreInlineProperties($save_silp);
15610 }
15611 }
15612
15613 if (isset($properties['PAGE-BREAK-INSIDE']) && strtoupper($properties['PAGE-BREAK-INSIDE']) == 'AVOID' && !$this->ColActive && !$this->keep_block_together) {
15614 $currblk['keep_block_together'] = 1;
15615 $this->kt_y00 = $this->y;
15616 $this->kt_p00 = $this->page;
15617 $this->keep_block_together = 1;
15618 $this->divbuffer = array();
15619 $this->ktLinks = array();
15620 $this->ktAnnots = array();
15621 $this->ktForms = array();
15622 $this->ktBlock = array();
15623 $this->ktReference = array();
15624 $this->ktBMoutlines = array();
15625 $this->_kttoc = array();
15626 }
15627 if ($lastbottommargin && isset($properties['MARGIN-TOP']) && $properties['MARGIN-TOP'] && empty($properties['FLOAT'])) { $currblk['lastbottommargin'] = $lastbottommargin; }
15628
15629 // mPDF 5.6.01 - LAYERS
15630 if (isset($properties['Z-INDEX']) && $this->currentlayer==0) {
15631 $v = intval($properties['Z-INDEX']);
15632 if ($v > 0) {
15633 $currblk['z-index'] = $v;
15634 $this->BeginLayer($v);
15635 }
15636 }
15637
15638 $this->setCSS($properties,'BLOCK',$tag); //name(id/class/style) found in the CSS array!
15639 $currblk['InlineProperties'] = $this->saveInlineProperties();
15640
15641 if (isset($properties['VISIBILITY'])) {
15642 $v = strtolower($properties['VISIBILITY']);
15643 if (($v == 'hidden' || $v == 'printonly' || $v == 'screenonly') && $this->visibility=='visible' && !$this->tableLevel) {
15644 $currblk['visibility'] = $v;
15645 $this->SetVisibility($v);
15646 }
15647 }
15648
15649 if(isset($attr['DIR']) && $attr['DIR']) { $currblk['direction'] = strtolower($attr['DIR']); }
15650 if(isset($attr['ALIGN']) && $attr['ALIGN']) { $currblk['block-align'] = $align[strtolower($attr['ALIGN'])]; }
15651
15652 if (isset($properties['HEIGHT'])) {
15653 $currblk['css_set_height'] = $this->ConvertSize($properties['HEIGHT'],($this->h - $this->tMargin - $this->bMargin),$this->FontSize,false);
15654 if (($currblk['css_set_height'] + $this->y) > $this->PageBreakTrigger && $this->y > $this->tMargin+5 && $currblk['css_set_height'] < ($this->h - ($this->tMargin + $this->bMargin))) { $this->AddPage($this->CurOrientation); }
15655 }
15656 else { $currblk['css_set_height'] = false; }
15657
15658
15659 // Added mPDF 3.0 Float DIV
15660 if (isset($prevblk['blockContext'])) { $currblk['blockContext'] = $prevblk['blockContext'] ; } // *CSS-FLOAT*
15661
15662 if (isset($properties['CLEAR'])) { $this->ClearFloats(strtoupper($properties['CLEAR']), $this->blklvl-1); } // *CSS-FLOAT*
15663
15664 $container_w = $prevblk['inner_width'];
15665 $bdr = $currblk['border_right']['w'];
15666 $bdl = $currblk['border_left']['w'];
15667 $pdr = $currblk['padding_right'];
15668 $pdl = $currblk['padding_left'];
15669
15670 if (isset($currblk['css_set_width'])) { $setwidth = $currblk['css_set_width']; }
15671 else { $setwidth = 0; }
15672
15673 /*-- CSS-FLOAT --*/
15674 if (isset($properties['FLOAT']) && strtoupper($properties['FLOAT']) == 'RIGHT' && !$this->ColActive) {
15675 // Cancel Keep-Block-together
15676 $currblk['keep_block_together'] = false;
15677 $this->kt_y00 = '';
15678 $this->keep_block_together = 0;
15679
15680 $this->blockContext++;
15681 $currblk['blockContext'] = $this->blockContext;
15682
15683 list($l_exists, $r_exists, $l_max, $r_max, $l_width, $r_width) = $this->GetFloatDivInfo($this->blklvl-1);
15684
15685 // DIV is too narrow for text to fit!
15686 $maxw = $container_w - $l_width - $r_width;
15687 if (($setwidth + $currblk['margin_right'] + $bdl + $pdl + $bdr + $pdr) > $maxw || ($maxw - ($currblk['margin_right'] + $bdl + $pdl + $bdr + $pdr)) < (2*$this->GetCharWidth('W',false))) {
15688 // Too narrow to fit - try to move down past L or R float
15689 if ($l_max < $r_max && ($setwidth + $currblk['margin_right'] + $bdl + $pdl + $bdr + $pdr) <= ($container_w - $r_width) && (($container_w - $r_width) - ($currblk['margin_right'] + $bdl + $pdl + $bdr + $pdr)) > (2*$this->GetCharWidth('W',false))) {
15690 $this->ClearFloats('LEFT', $this->blklvl-1);
15691 }
15692 else if ($r_max < $l_max && ($setwidth + $currblk['margin_right'] + $bdl + $pdl + $bdr + $pdr) <= ($container_w - $l_width) && (($container_w - $l_width) - ($currblk['margin_right'] + $bdl + $pdl + $bdr + $pdr)) > (2*$this->GetCharWidth('W',false))) {
15693 $this->ClearFloats('RIGHT', $this->blklvl-1);
15694 }
15695 else { $this->ClearFloats('BOTH', $this->blklvl-1); }
15696 list($l_exists, $r_exists, $l_max, $r_max, $l_width, $r_width) = $this->GetFloatDivInfo($this->blklvl-1);
15697 }
15698
15699 if ($r_exists) { $currblk['margin_right'] += $r_width; }
15700
15701 $currblk['float'] = 'R';
15702 $currblk['float_start_y'] = $this->y;
15703 if ($currblk['css_set_width']) {
15704 $currblk['margin_left'] = $container_w - ($setwidth + $bdl + $pdl + $bdr + $pdr + $currblk['margin_right']);
15705 $currblk['float_width'] = ($setwidth + $bdl + $pdl + $bdr + $pdr + $currblk['margin_right']);
15706 }
15707 else {
15708 // *** If no width set - would need to buffer and keep track of max width, then Right-align if not full width
15709 // and do borders and backgrounds - For now - just set to maximum width left
15710
15711 if ($l_exists) { $currblk['margin_left'] += $l_width; }
15712 $currblk['css_set_width'] = $container_w - ($currblk['margin_left'] + $currblk['margin_right'] + $bdl + $pdl + $bdr + $pdr);
15713
15714 $currblk['float_width'] = ($currblk['css_set_width'] + $bdl + $pdl + $bdr + $pdr + $currblk['margin_right']);
15715 }
15716 }
15717 else if (isset($properties['FLOAT']) && strtoupper($properties['FLOAT']) == 'LEFT' && !$this->ColActive) {
15718 // Cancel Keep-Block-together
15719 $currblk['keep_block_together'] = false;
15720 $this->kt_y00 = '';
15721 $this->keep_block_together = 0;
15722
15723 $this->blockContext++;
15724 $currblk['blockContext'] = $this->blockContext;
15725
15726 list($l_exists, $r_exists, $l_max, $r_max, $l_width, $r_width) = $this->GetFloatDivInfo($this->blklvl-1);
15727
15728 // DIV is too narrow for text to fit!
15729 $maxw = $container_w - $l_width - $r_width;
15730 if (($setwidth + $currblk['margin_left'] + $bdl + $pdl + $bdr + $pdr) > $maxw || ($maxw - ($currblk['margin_left'] + $bdl + $pdl + $bdr + $pdr)) < (2*$this->GetCharWidth('W',false))) {
15731 // Too narrow to fit - try to move down past L or R float
15732 if ($l_max < $r_max && ($setwidth + $currblk['margin_right'] + $bdl + $pdl + $bdr + $pdr) <= ($container_w - $r_width) && (($container_w - $r_width) - ($currblk['margin_right'] + $bdl + $pdl + $bdr + $pdr)) > (2*$this->GetCharWidth('W',false))) {
15733 $this->ClearFloats('LEFT', $this->blklvl-1);
15734 }
15735 else if ($r_max < $l_max && ($setwidth + $currblk['margin_right'] + $bdl + $pdl + $bdr + $pdr) <= ($container_w - $l_width) && (($container_w - $l_width) - ($currblk['margin_right'] + $bdl + $pdl + $bdr + $pdr)) > (2*$this->GetCharWidth('W',false))) {
15736 $this->ClearFloats('RIGHT', $this->blklvl-1);
15737 }
15738 else { $this->ClearFloats('BOTH', $this->blklvl-1); }
15739 list($l_exists, $r_exists, $l_max, $r_max, $l_width, $r_width) = $this->GetFloatDivInfo($this->blklvl-1);
15740 }
15741
15742 if ($l_exists) { $currblk['margin_left'] += $l_width; }
15743
15744 $currblk['float'] = 'L';
15745 $currblk['float_start_y'] = $this->y;
15746 if ($setwidth) {
15747 $currblk['margin_right'] = $container_w - ($setwidth + $bdl + $pdl + $bdr + $pdr + $currblk['margin_left']);
15748 $currblk['float_width'] = ($setwidth + $bdl + $pdl + $bdr + $pdr + $currblk['margin_left']);
15749 }
15750 else {
15751 // *** If no width set - would need to buffer and keep track of max width, then Right-align if not full width
15752 // and do borders and backgrounds - For now - just set to maximum width left
15753
15754 if ($r_exists) { $currblk['margin_right'] += $r_width; }
15755 $currblk['css_set_width'] = $container_w - ($currblk['margin_left'] + $currblk['margin_right'] + $bdl + $pdl + $bdr + $pdr);
15756
15757 $currblk['float_width'] = ($currblk['css_set_width'] + $bdl + $pdl + $bdr + $pdr + $currblk['margin_left']);
15758 }
15759 }
15760
15761 else {
15762 // Don't allow overlap - if floats present - adjust padding to avoid overlap with Floats
15763 list($l_exists, $r_exists, $l_max, $r_max, $l_width, $r_width) = $this->GetFloatDivInfo($this->blklvl-1);
15764 $maxw = $container_w - $l_width - $r_width;
15765 if (($setwidth + $currblk['margin_left'] + $currblk['margin_right'] + $bdl + $pdl + $bdr + $pdr) > $maxw || ($maxw - ($currblk['margin_right'] + $currblk['margin_left'] + $bdl + $pdl + $bdr + $pdr)) < (2*$this->GetCharWidth('W',false))) {
15766 // Too narrow to fit - try to move down past L or R float
15767 if ($l_max < $r_max && ($setwidth + $currblk['margin_left'] + $currblk['margin_right'] + $bdl + $pdl + $bdr + $pdr) <= ($container_w - $r_width) && (($container_w - $r_width) - ($currblk['margin_right'] + $currblk['margin_left'] + $bdl + $pdl + $bdr + $pdr)) > (2*$this->GetCharWidth('W',false))) {
15768 $this->ClearFloats('LEFT', $this->blklvl-1);
15769 }
15770 else if ($r_max < $l_max && ($setwidth + $currblk['margin_left'] + $currblk['margin_right'] + $bdl + $pdl + $bdr + $pdr) <= ($container_w - $l_width) && (($container_w - $l_width) - ($currblk['margin_right'] + $currblk['margin_left'] + $bdl + $pdl + $bdr + $pdr)) > (2*$this->GetCharWidth('W',false))) {
15771 $this->ClearFloats('RIGHT', $this->blklvl-1);
15772 }
15773 else { $this->ClearFloats('BOTH', $this->blklvl-1); }
15774 list($l_exists, $r_exists, $l_max, $r_max, $l_width, $r_width) = $this->GetFloatDivInfo($this->blklvl-1);
15775 }
15776 if ($r_exists) { $currblk['padding_right'] = max(($r_width-$currblk['margin_right']-$bdr), $pdr); }
15777 if ($l_exists) { $currblk['padding_left'] = max(($l_width-$currblk['margin_left']-$bdl), $pdl); }
15778 }
15779 /*-- END CSS-FLOAT --*/
15780
15781
15782 /*-- BORDER-RADIUS --*/
15783 // Automatically increase padding if required for border-radius
15784 if ($this->autoPadding && !$this->ColActive && !$this->keep_block_together) {
15785 if ($currblk['border_radius_TL_H']>$currblk['padding_left'] && $currblk['border_radius_TL_V']>$currblk['padding_top']) {
15786 if ($currblk['border_radius_TL_H']>$currblk['border_radius_TL_V']) {
15787 $this->_borderPadding($currblk['border_radius_TL_H'],$currblk['border_radius_TL_V'], $currblk['padding_left'], $currblk['padding_top']);
15788 }
15789 else {
15790 $this->_borderPadding($currblk['border_radius_TL_V'],$currblk['border_radius_TL_H'], $currblk['padding_top'], $currblk['padding_left']);
15791 }
15792 }
15793 if ($currblk['border_radius_TR_H']>$currblk['padding_right'] && $currblk['border_radius_TR_V']>$currblk['padding_top']) {
15794 if ($currblk['border_radius_TR_H']>$currblk['border_radius_TR_V']) {
15795 $this->_borderPadding($currblk['border_radius_TR_H'],$currblk['border_radius_TR_V'], $currblk['padding_right'], $currblk['padding_top']);
15796 }
15797 else {
15798 $this->_borderPadding($currblk['border_radius_TR_V'],$currblk['border_radius_TR_H'], $currblk['padding_top'], $currblk['padding_right']);
15799 }
15800 }
15801 if ($currblk['border_radius_BL_H']>$currblk['padding_left'] && $currblk['border_radius_BL_V']>$currblk['padding_bottom']) {
15802 if ($currblk['border_radius_BL_H']>$currblk['border_radius_BL_V']) {
15803 $this->_borderPadding($currblk['border_radius_BL_H'],$currblk['border_radius_BL_V'], $currblk['padding_left'], $currblk['padding_bottom']);
15804 }
15805 else {
15806 $this->_borderPadding($currblk['border_radius_BL_V'],$currblk['border_radius_BL_H'], $currblk['padding_bottom'], $currblk['padding_left']);
15807 }
15808 }
15809 if ($currblk['border_radius_BR_H']>$currblk['padding_right'] && $currblk['border_radius_BR_V']>$currblk['padding_bottom']) {
15810 if ($currblk['border_radius_BR_H']>$currblk['border_radius_BR_V']) {
15811 $this->_borderPadding($currblk['border_radius_BR_H'],$currblk['border_radius_BR_V'], $currblk['padding_right'], $currblk['padding_bottom']);
15812 }
15813 else {
15814 $this->_borderPadding($currblk['border_radius_BR_V'],$currblk['border_radius_BR_H'], $currblk['padding_bottom'], $currblk['padding_right']);
15815 }
15816 }
15817 }
15818 /*-- END BORDER-RADIUS --*/
15819
15820
15821 // Hanging indent - if negative indent: ensure padding is >= indent
15822 if(!isset($currblk['text_indent'])) { $currblk['text_indent'] = null; }
15823 if(!isset($currblk['inner_width'])) { $currblk['inner_width'] = null; }
15824 $cbti = $this->ConvertSize($currblk['text_indent'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
15825 if ($cbti < 0) {
15826 $hangind = -($cbti);
15827 if ($currblk['direction'] == 'rtl') { // *RTL*
15828 $currblk['padding_right'] = max($currblk['padding_right'],$hangind); // *RTL*
15829 } // *RTL*
15830 else { // *RTL*
15831 $currblk['padding_left'] = max($currblk['padding_left'],$hangind);
15832 } // *RTL*
15833 }
15834
15835 if (isset($currblk['css_set_width'])) {
15836 if (isset($properties['MARGIN-LEFT']) && isset($properties['MARGIN-RIGHT']) && strtolower($properties['MARGIN-LEFT'])=='auto' && strtolower($properties['MARGIN-RIGHT'])=='auto') {
15837 // Try to reduce margins to accomodate - if still too wide, set margin-right/left=0 (reduces width)
15838 $anyextra = $prevblk['inner_width'] - ($currblk['css_set_width'] + $currblk['border_left']['w'] + $currblk['padding_left'] + $currblk['border_right']['w'] + $currblk['padding_right']);
15839 if ($anyextra>0) {
15840 $currblk['margin_left'] = $currblk['margin_right'] = $anyextra /2;
15841 }
15842 else {
15843 $currblk['margin_left'] = $currblk['margin_right'] = 0;
15844 }
15845 }
15846 else if (isset($properties['MARGIN-LEFT']) && strtolower($properties['MARGIN-LEFT'])=='auto') {
15847 // Try to reduce margin-left to accomodate - if still too wide, set margin-left=0 (reduces width)
15848 $currblk['margin_left'] = $prevblk['inner_width'] - ($currblk['css_set_width'] + $currblk['border_left']['w'] + $currblk['padding_left'] + $currblk['border_right']['w'] + $currblk['padding_right'] + $currblk['margin_right']);
15849 if ($currblk['margin_left'] < 0) {
15850 $currblk['margin_left'] = 0;
15851 }
15852 }
15853 else if (isset($properties['MARGIN-RIGHT']) && strtolower($properties['MARGIN-RIGHT'])=='auto') {
15854 // Try to reduce margin-right to accomodate - if still too wide, set margin-right=0 (reduces width)
15855 $currblk['margin_right'] = $prevblk['inner_width'] - ($currblk['css_set_width'] + $currblk['border_left']['w'] + $currblk['padding_left'] + $currblk['border_right']['w'] + $currblk['padding_right'] + $currblk['margin_left']);
15856 if ($currblk['margin_right'] < 0) {
15857 $currblk['margin_right'] = 0;
15858 }
15859 }
15860 else {
15861 if ($currblk['direction'] == 'rtl') { // *RTL*
15862 // Try to reduce margin-left to accomodate - if still too wide, set margin-left=0 (reduces width)
15863 $currblk['margin_left'] = $prevblk['inner_width'] - ($currblk['css_set_width'] + $currblk['border_left']['w'] + $currblk['padding_left'] + $currblk['border_right']['w'] + $currblk['padding_right'] + $currblk['margin_right']); // *RTL*
15864 if ($currblk['margin_left'] < 0) { // *RTL*
15865 $currblk['margin_left'] = 0; // *RTL*
15866 } // *RTL*
15867 } // *RTL*
15868 else { // *RTL*
15869 // Try to reduce margin-right to accomodate - if still too wide, set margin-right=0 (reduces width)
15870 $currblk['margin_right'] = $prevblk['inner_width'] - ($currblk['css_set_width'] + $currblk['border_left']['w'] + $currblk['padding_left'] + $currblk['border_right']['w'] + $currblk['padding_right'] + $currblk['margin_left']);
15871 if ($currblk['margin_right'] < 0) {
15872 $currblk['margin_right'] = 0;
15873 }
15874 } // *RTL*
15875 }
15876 }
15877
15878 $currblk['outer_left_margin'] = $prevblk['outer_left_margin'] + $currblk['margin_left'] + $prevblk['border_left']['w'] + $prevblk['padding_left'];
15879 $currblk['outer_right_margin'] = $prevblk['outer_right_margin'] + $currblk['margin_right'] + $prevblk['border_right']['w'] + $prevblk['padding_right'];
15880
15881 $currblk['width'] = $this->pgwidth - ($currblk['outer_right_margin'] + $currblk['outer_left_margin']);
15882 $currblk['inner_width'] = $currblk['width'] - ($currblk['border_left']['w'] + $currblk['padding_left'] + $currblk['border_right']['w'] + $currblk['padding_right']);
15883
15884 // Check DIV is not now too narrow to fit text
15885 $mw = 2*$this->GetCharWidth('W',false);
15886 if ($currblk['inner_width'] < $mw) {
15887 $currblk['padding_left'] = 0;
15888 $currblk['padding_right'] = 0;
15889 $currblk['border_left']['w'] = 0.2;
15890 $currblk['border_right']['w'] = 0.2;
15891 $currblk['margin_left'] = 0;
15892 $currblk['margin_right'] = 0;
15893 $currblk['outer_left_margin'] = $prevblk['outer_left_margin'] + $currblk['margin_left'] + $prevblk['border_left']['w'] + $prevblk['padding_left'];
15894 $currblk['outer_right_margin'] = $prevblk['outer_right_margin'] + $currblk['margin_right'] + $prevblk['border_right']['w'] + $prevblk['padding_right'];
15895 $currblk['width'] = $this->pgwidth - ($currblk['outer_right_margin'] + $currblk['outer_left_margin']);
15896 $currblk['inner_width'] = $this->pgwidth - ($currblk['outer_right_margin'] + $currblk['outer_left_margin'] + $currblk['border_left']['w'] + $currblk['padding_left'] + $currblk['border_right']['w'] + $currblk['padding_right']);
15897 // if ($currblk['inner_width'] < $mw) { $this->Error("DIV is too narrow for text to fit!"); }
15898 }
15899
15900 $this->x = $this->lMargin + $currblk['outer_left_margin'];
15901
15902 /*-- BACKGROUNDS --*/
15903 if (isset($properties['BACKGROUND-IMAGE']) && $properties['BACKGROUND-IMAGE'] && !$this->kwt && !$this->ColActive && !$this->keep_block_together) {
15904 $ret = $this->SetBackground($properties, $currblk['inner_width']);
15905 if ($ret) { $currblk['background-image'] = $ret; }
15906 }
15907 /*-- END BACKGROUNDS --*/
15908
15909 /*-- TABLES --*/
15910 if ($this->use_kwt && isset($attr['KEEP-WITH-TABLE']) && !$this->ColActive && !$this->keep_block_together) {
15911 $this->kwt = true;
15912 $this->kwt_y0 = $this->y;
15913 $this->kwt_x0 = $this->x;
15914 $this->kwt_height = 0;
15915 $this->kwt_buffer = array();
15916 $this->kwt_Links = array();
15917 $this->kwt_Annots = array();
15918 $this->kwt_moved = false;
15919 $this->kwt_saved = false;
15920 $this->kwt_Reference = array();
15921 $this->kwt_BMoutlines = array();
15922 $this->kwt_toc = array();
15923 }
15924 else {
15925 /*-- END TABLES --*/
15926 $this->kwt = false;
15927 } // *TABLES*
15928
15929 //Save x,y coords in case we need to print borders...
15930 $currblk['y0'] = $this->y;
15931 $currblk['x0'] = $this->x;
15932 $currblk['startpage'] = $this->page;
15933 $this->oldy = $this->y;
15934
15935 $this->lastblocklevelchange = 1 ;
15936
15937 break;
15938
15939 case 'HR':
15940 // Added mPDF 3.0 Float DIV - CLEAR
15941 if (isset($attr['STYLE'])) {
15942 $properties = $this->cssmgr->readInlineCSS($attr['STYLE']);
15943 if (isset($properties['CLEAR'])) { $this->ClearFloats(strtoupper($properties['CLEAR']),$this->blklvl); } // *CSS-FLOAT*
15944 }
15945
15946 $this->ignorefollowingspaces = true;
15947
15948 $objattr = array();
15949 $objattr['margin_top'] = 0;
15950 $objattr['margin_bottom'] = 0;
15951 $objattr['margin_left'] = 0;
15952 $objattr['margin_right'] = 0;
15953 $objattr['width'] = 0;
15954 $objattr['height'] = 0;
15955 $objattr['border_top']['w'] = 0;
15956 $objattr['border_bottom']['w'] = 0;
15957 $objattr['border_left']['w'] = 0;
15958 $objattr['border_right']['w'] = 0;
15959 $properties = $this->cssmgr->MergeCSS('',$tag,$attr);
15960 if (isset($properties['MARGIN-TOP'])) { $objattr['margin_top'] = $this->ConvertSize($properties['MARGIN-TOP'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
15961 if (isset($properties['MARGIN-BOTTOM'])) { $objattr['margin_bottom'] = $this->ConvertSize($properties['MARGIN-BOTTOM'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
15962 if (isset($properties['WIDTH'])) { $objattr['width'] = $this->ConvertSize($properties['WIDTH'],$this->blk[$this->blklvl]['inner_width']); }
15963 else if(isset($attr['WIDTH']) && $attr['WIDTH'] != '') $objattr['width'] = $this->ConvertSize($attr['WIDTH'],$this->blk[$this->blklvl]['inner_width']);
15964 if (isset($properties['TEXT-ALIGN'])) { $objattr['align'] = $align[strtolower($properties['TEXT-ALIGN'])]; }
15965 else if(isset($attr['ALIGN']) && $attr['ALIGN'] != '') $objattr['align'] = $align[strtolower($attr['ALIGN'])];
15966
15967 if (isset($properties['MARGIN-LEFT']) && strtolower($properties['MARGIN-LEFT'])=='auto') {
15968 $objattr['align'] = 'R';
15969 }
15970 if (isset($properties['MARGIN-RIGHT']) && strtolower($properties['MARGIN-RIGHT'])=='auto') {
15971 $objattr['align'] = 'L';
15972 if (isset($properties['MARGIN-RIGHT']) && strtolower($properties['MARGIN-RIGHT'])=='auto' && isset($properties['MARGIN-LEFT']) && strtolower($properties['MARGIN-LEFT'])=='auto') {
15973 $objattr['align'] = 'C';
15974 }
15975 }
15976 if (isset($properties['COLOR'])) { $objattr['color'] = $this->ConvertColor($properties['COLOR']); }
15977 else if(isset($attr['COLOR']) && $attr['COLOR'] != '') $objattr['color'] = $this->ConvertColor($attr['COLOR']);
15978 if (isset($properties['HEIGHT'])) { $objattr['linewidth'] = $this->ConvertSize($properties['HEIGHT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
15979
15980
15981 /*-- TABLES --*/
15982 if ($this->tableLevel) {
15983 $objattr['W-PERCENT'] = 100;
15984 if (isset($properties['WIDTH']) && stristr($properties['WIDTH'],'%')) {
15985 $properties['WIDTH'] += 0; //make "90%" become simply "90"
15986 $objattr['W-PERCENT'] = $properties['WIDTH'];
15987 }
15988 if (isset($attr['WIDTH']) && stristr($attr['WIDTH'],'%')) {
15989 $attr['WIDTH'] += 0; //make "90%" become simply "90"
15990 $objattr['W-PERCENT'] = $attr['WIDTH'];
15991 }
15992 }
15993 /*-- END TABLES --*/
15994
15995 $objattr['type'] = 'hr';
15996 $objattr['height'] = $objattr['linewidth'] + $objattr['margin_top'] + $objattr['margin_bottom'];
15997 $e = "\xbb\xa4\xactype=image,objattr=".serialize($objattr)."\xbb\xa4\xac";
15998
15999 // Clear properties - tidy up
16000 $properties = array();
16001
16002 /*-- TABLES --*/
16003 // Output it to buffers
16004 if ($this->tableLevel) {
16005 if (!isset($this->cell[$this->row][$this->col]['maxs'])) {
16006 $this->cell[$this->row][$this->col]['maxs'] = $this->cell[$this->row][$this->col]['s'];
16007 }
16008 elseif($this->cell[$this->row][$this->col]['maxs'] < $this->cell[$this->row][$this->col]['s']) {
16009 $this->cell[$this->row][$this->col]['maxs'] = $this->cell[$this->row][$this->col]['s'];
16010 }
16011 $this->cell[$this->row][$this->col]['s'] = 0 ;// reset
16012 $this->_saveCellTextBuffer($e, $this->HREF);
16013 }
16014 else {
16015 /*-- END TABLES --*/
16016 $this->_saveTextBuffer($e, $this->HREF);
16017 } // *TABLES*
16018
16019 break;
16020
16021
16022 /*-- BARCODES --*/
16023
16024 case 'BARCODE':
16025 if(isset($attr['CODE']) && $attr['CODE']) {
16026 $objattr = array();
16027 $objattr['margin_top'] = 0;
16028 $objattr['margin_bottom'] = 0;
16029 $objattr['margin_left'] = 0;
16030 $objattr['margin_right'] = 0;
16031 $objattr['padding_top'] = 0;
16032 $objattr['padding_bottom'] = 0;
16033 $objattr['padding_left'] = 0;
16034 $objattr['padding_right'] = 0;
16035 $objattr['width'] = 0;
16036 $objattr['height'] = 0;
16037 $objattr['border_top']['w'] = 0;
16038 $objattr['border_bottom']['w'] = 0;
16039 $objattr['border_left']['w'] = 0;
16040 $objattr['border_right']['w'] = 0;
16041 $objattr['code'] = $attr['CODE'];
16042
16043 if(isset($attr['TYPE'])) {
16044 $objattr['btype'] = trim(strtoupper($attr['TYPE']));
16045 }
16046 else { $objattr['btype'] = 'EAN13'; } // default
16047 if (preg_match('/^(EAN13|ISBN|ISSN|EAN8|UPCA|UPCE)P([25])$/',$objattr['btype'],$m)) {
16048 $objattr['btype'] = $m[1];
16049 $objattr['bsupp'] = $m[2];
16050 if (preg_match('/^(\S+)\s+(.*)$/',$objattr['code'],$mm)) {
16051 $objattr['code'] = $mm[1];
16052 $objattr['bsupp_code'] = $mm[2];
16053 }
16054 }
16055 else { $objattr['bsupp'] = 0; }
16056
16057 if(isset($attr['TEXT']) && $attr['TEXT']==1) { $objattr['showtext'] = 1; }
16058 else { $objattr['showtext'] = 0; }
16059 if(isset($attr['SIZE']) && $attr['SIZE']>0) { $objattr['bsize'] = $attr['SIZE']; }
16060 else { $objattr['bsize'] = 1; }
16061 if(isset($attr['HEIGHT']) && $attr['HEIGHT']>0) { $objattr['bheight'] = $attr['HEIGHT']; }
16062 else { $objattr['bheight'] = 1; }
16063 if(isset($attr['PR']) && $attr['PR']>0) { $objattr['pr_ratio'] = $attr['PR']; }
16064 else { $objattr['pr_ratio'] = ''; }
16065 $properties = $this->cssmgr->MergeCSS('',$tag,$attr);
16066 if(isset($properties ['DISPLAY']) && strtolower($properties ['DISPLAY'])=='none') {
16067 return;
16068 }
16069 if (isset($properties['MARGIN-TOP'])) { $objattr['margin_top']=$this->ConvertSize($properties['MARGIN-TOP'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
16070 if (isset($properties['MARGIN-BOTTOM'])) { $objattr['margin_bottom'] = $this->ConvertSize($properties['MARGIN-BOTTOM'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
16071 if (isset($properties['MARGIN-LEFT'])) { $objattr['margin_left'] = $this->ConvertSize($properties['MARGIN-LEFT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
16072 if (isset($properties['MARGIN-RIGHT'])) { $objattr['margin_right'] = $this->ConvertSize($properties['MARGIN-RIGHT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
16073
16074 if (isset($properties['PADDING-TOP'])) { $objattr['padding_top']=$this->ConvertSize($properties['PADDING-TOP'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
16075 if (isset($properties['PADDING-BOTTOM'])) { $objattr['padding_bottom'] = $this->ConvertSize($properties['PADDING-BOTTOM'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
16076 if (isset($properties['PADDING-LEFT'])) { $objattr['padding_left'] = $this->ConvertSize($properties['PADDING-LEFT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
16077 if (isset($properties['PADDING-RIGHT'])) { $objattr['padding_right'] = $this->ConvertSize($properties['PADDING-RIGHT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
16078
16079 if (isset($properties['BORDER-TOP'])) { $objattr['border_top'] = $this->border_details($properties['BORDER-TOP']); }
16080 if (isset($properties['BORDER-BOTTOM'])) { $objattr['border_bottom'] = $this->border_details($properties['BORDER-BOTTOM']); }
16081 if (isset($properties['BORDER-LEFT'])) { $objattr['border_left'] = $this->border_details($properties['BORDER-LEFT']); }
16082 if (isset($properties['BORDER-RIGHT'])) { $objattr['border_right'] = $this->border_details($properties['BORDER-RIGHT']); }
16083
16084 if (isset($properties['VERTICAL-ALIGN'])) { $objattr['vertical-align'] = $align[strtolower($properties['VERTICAL-ALIGN'])]; }
16085 if (isset($properties['COLOR']) && $properties['COLOR'] != '') { $objattr['color'] = $this->ConvertColor($properties['COLOR']); }
16086 else { $objattr['color'] = false; }
16087 if (isset($properties['BACKGROUND-COLOR']) && $properties['BACKGROUND-COLOR'] != '') { $objattr['bgcolor'] = $this->ConvertColor($properties['BACKGROUND-COLOR']); }
16088 else { $objattr['bgcolor'] = false; }
16089
16090 if (!class_exists('PDFBarcode', false)) {
16091 include(_MPDF_PATH.'classes/barcode.php');
16092 }
16093 $this->barcode = new PDFBarcode();
16094
16095 if ($objattr['btype'] == 'EAN13' || $objattr['btype'] == 'ISBN' || $objattr['btype'] == 'ISSN' || $objattr['btype'] == 'UPCA' || $objattr['btype'] == 'UPCE' || $objattr['btype'] == 'EAN8') {
16096 $code = preg_replace('/\-/','',$objattr['code']);
16097 if ($objattr['btype'] == 'ISSN' || $objattr['btype'] == 'ISBN') {
16098 $arrcode = $this->barcode->getBarcodeArray($code, 'EAN13');
16099 }
16100 else { $arrcode = $this->barcode->getBarcodeArray($code, $objattr['btype'] ); }
16101 if ($arrcode === false) { $this->Error('Error in barcode string.'); }
16102
16103 if ($objattr['bsupp'] == 2 || $objattr['bsupp'] == 5) { // EAN-2 or -5 Supplement
16104 $supparrcode = $this->barcode->getBarcodeArray($objattr['bsupp_code'], 'EAN'.$objattr['bsupp'] );
16105 $w = ($arrcode["maxw"] + $arrcode['lightmL'] + $arrcode['lightmR'] + $supparrcode["maxw"] + $supparrcode['sepM']) * $arrcode['nom-X'] * $objattr['bsize'];
16106 }
16107 else {
16108 $w = ($arrcode["maxw"] + $arrcode['lightmL'] + $arrcode['lightmR']) * $arrcode['nom-X'] * $objattr['bsize'];
16109 }
16110 $h = $arrcode['nom-H'] * $objattr['bsize'] * $objattr['bheight'];
16111 // Add height for ISBN string + margin from top of bars
16112 if (($objattr['showtext'] && $objattr['btype'] == 'EAN13') || $objattr['btype'] == 'ISBN' || $objattr['btype'] == 'ISSN') {
16113 $tisbnm = 1.5 * $objattr['bsize']; // Top margin between TOP TEXT (isbn - if shown) & bars
16114 $isbn_fontsize = 2.1 * $objattr['bsize'];
16115 $h += $isbn_fontsize + $tisbnm ;
16116 }
16117 }
16118 // QR-code
16119 else if ($objattr['btype'] == 'QR') {
16120 $w = $h = $objattr['bsize']*25; // Factor of 25mm (default)
16121 $objattr['errorlevel'] = 'L';
16122 if (isset($attr['ERROR'])) { $objattr['errorlevel'] = $attr['ERROR']; }
16123 }
16124 else if ($objattr['btype'] == 'IMB' || $objattr['btype'] == 'RM4SCC' || $objattr['btype'] == 'KIX' || $objattr['btype'] == 'POSTNET' || $objattr['btype'] == 'PLANET') {
16125 $arrcode = $this->barcode->getBarcodeArray($objattr['code'], $objattr['btype'] );
16126 if ($arrcode === false) { $this->Error('Error in barcode string.'); }
16127 $w = ($arrcode["maxw"] * $arrcode['nom-X'] * $objattr['bsize']) + $arrcode['quietL'] + $arrcode['quietR'];
16128 $h = ($arrcode['nom-H'] * $objattr['bsize']) + (2*$arrcode['quietTB']);
16129 }
16130 else if (in_array($objattr['btype'], array('C128A','C128B','C128C','EAN128A','EAN128B','EAN128C','C39','C39+','C39E','C39E+','S25','S25+','I25','I25+','I25B','I25B+','C93','MSI','MSI+','CODABAR','CODE11'))) {
16131 $arrcode = $this->barcode->getBarcodeArray($objattr['code'], $objattr['btype'], $objattr['pr_ratio'] );
16132 if ($arrcode === false) { $this->Error('Error in barcode string.'); }
16133 $w = ($arrcode["maxw"] + $arrcode['lightmL'] + $arrcode['lightmR']) * $arrcode['nom-X'] * $objattr['bsize'];
16134 $h = ((2*$arrcode['lightTB'] * $arrcode['nom-X']) + $arrcode['nom-H']) * $objattr['bsize'] * $objattr['bheight'];
16135 }
16136 else { break; }
16137
16138 $extraheight = $objattr['padding_top'] + $objattr['padding_bottom'] + $objattr['margin_top'] + $objattr['margin_bottom'] + $objattr['border_top']['w'] + $objattr['border_bottom']['w'];
16139 $extrawidth = $objattr['padding_left'] + $objattr['padding_right'] + $objattr['margin_left'] + $objattr['margin_right'] + $objattr['border_left']['w'] + $objattr['border_right']['w'];
16140
16141 $objattr['type'] = 'barcode';
16142 $objattr['height'] = $h + $extraheight;
16143 $objattr['width'] = $w + $extrawidth;
16144 $objattr['barcode_height'] = $h;
16145 $objattr['barcode_width'] = $w;
16146 /*-- CSS-IMAGE-FLOAT --*/
16147 if (!$this->ColActive && !$this->tableLevel && !$this->listlvl && !$this->kwt && !$this->keep_block_together) {
16148 if (isset($properties['FLOAT']) && (strtoupper($properties['FLOAT']) == 'RIGHT' || strtoupper($properties['FLOAT']) == 'LEFT')) {
16149 $objattr['float'] = substr(strtoupper($properties['FLOAT']),0,1);
16150 }
16151 }
16152 /*-- END CSS-IMAGE-FLOAT --*/
16153
16154 $e = "\xbb\xa4\xactype=barcode,objattr=".serialize($objattr)."\xbb\xa4\xac";
16155
16156 // Clear properties - tidy up
16157 $properties = array();
16158
16159 /*-- TABLES --*/
16160 // Output it to buffers
16161 if ($this->tableLevel) {
16162 $this->_saveCellTextBuffer($e, $this->HREF);
16163 $this->cell[$this->row][$this->col]['s'] += $objattr['width'] ;
16164 }
16165 else {
16166 /*-- END TABLES --*/
16167 $this->_saveTextBuffer($e, $this->HREF);
16168
16169 } // *TABLES*
16170 }
16171 break;
16172 /*-- END BARCODES --*/
16173
16174
16175 // *********** FORM ELEMENTS ********************
16176
16177 /*-- FORMS --*/
16178 case 'SELECT':
16179 $this->lastoptionaltag = ''; // Save current HTML specified optional endtag
16180 $this->InlineProperties[$tag] = $this->saveInlineProperties();
16181 $properties = $this->cssmgr->MergeCSS('',$tag,$attr);
16182 if (isset($properties['FONT-FAMILY'])) {
16183 $this->SetFont($properties['FONT-FAMILY'],$this->FontStyle,0,false);
16184 }
16185 if (isset($properties['FONT-SIZE'])) {
16186 $mmsize = $this->ConvertSize($properties['FONT-SIZE'],$this->default_font_size/_MPDFK);
16187 $this->SetFontSize($mmsize*_MPDFK,false);
16188 }
16189 if (isset($attr['SPELLCHECK']) && strtolower($attr['SPELLCHECK'])=='true') {
16190 $this->selectoption['SPELLCHECK'] = true;
16191 }
16192
16193 if (isset($properties['COLOR'])) { $this->selectoption['COLOR'] = $this->ConvertColor($properties['COLOR']); }
16194 $this->specialcontent = "type=select";
16195 if(isset($attr['DISABLED'])) { $this->selectoption['DISABLED'] = $attr['DISABLED']; }
16196 if(isset($attr['READONLY'])) { $this->selectoption['READONLY'] = $attr['READONLY']; }
16197 if(isset($attr['REQUIRED'])) { $this->selectoption['REQUIRED'] = $attr['REQUIRED']; }
16198 if(isset($attr['EDITABLE'])) { $this->selectoption['EDITABLE'] = $attr['EDITABLE']; }
16199 if(isset($attr['TITLE'])) { $this->selectoption['TITLE'] = $attr['TITLE']; }
16200 if(isset($attr['MULTIPLE'])) { $this->selectoption['MULTIPLE'] = $attr['MULTIPLE']; }
16201 if(isset($attr['SIZE']) && $attr['SIZE']>1) { $this->selectoption['SIZE'] = $attr['SIZE']; }
16202 if ($this->useActiveForms) {
16203 if(isset($attr['NAME'])) { $this->selectoption['NAME'] = $attr['NAME']; }
16204 if (isset($attr['ONCHANGE'])) { $this->selectoption['ONCHANGE'] = $attr['ONCHANGE']; }
16205 }
16206
16207 $properties = array();
16208 break;
16209
16210 case 'OPTION':
16211 $this->lastoptionaltag = 'OPTION'; // Save current HTML specified optional endtag
16212 $this->selectoption['ACTIVE'] = true;
16213 $this->selectoption['currentSEL'] = false;
16214 if (empty($this->selectoption)) {
16215 $this->selectoption['MAXWIDTH'] = '';
16216 $this->selectoption['SELECTED'] = '';
16217 }
16218 if (isset($attr['SELECTED'])) {
16219 $this->selectoption['SELECTED'] = '';
16220 $this->selectoption['currentSEL'] = true;
16221 }
16222 if(isset($attr['VALUE'])) {
16223 $attr['VALUE'] = strcode2utf($attr['VALUE']);
16224 $attr['VALUE'] = $this->lesser_entity_decode($attr['VALUE']);
16225 if ($this->onlyCoreFonts)
16226 $attr['VALUE'] = mb_convert_encoding($attr['VALUE'], $this->mb_enc,'UTF-8');
16227 }
16228 $this->selectoption['currentVAL'] = $attr['VALUE'];
16229 break;
16230
16231 case 'TEXTAREA':
16232 $objattr = array();
16233 $objattr['margin_top'] = 0;
16234 $objattr['margin_bottom'] = 0;
16235 $objattr['margin_left'] = 0;
16236 $objattr['margin_right'] = 0;
16237 $objattr['width'] = 0;
16238 $objattr['height'] = 0;
16239 $objattr['border_top']['w'] = 0;
16240 $objattr['border_bottom']['w'] = 0;
16241 $objattr['border_left']['w'] = 0;
16242 $objattr['border_right']['w'] = 0;
16243 if(isset($attr['DISABLED'])) { $objattr['disabled'] = true; }
16244 if(isset($attr['READONLY'])) { $objattr['readonly'] = true; }
16245 if(isset($attr['REQUIRED'])) { $objattr['required'] = true; }
16246 if(isset($attr['SPELLCHECK']) && strtolower($attr['SPELLCHECK'])=='true') { $objattr['spellcheck'] = true; }
16247 if(isset($attr['TITLE'])) { $objattr['title'] = $attr['TITLE']; }
16248 if ($this->onlyCoreFonts)
16249 $objattr['title'] = mb_convert_encoding($objattr['title'], $this->mb_enc,'UTF-8');
16250 if ($this->useActiveForms) {
16251 if(isset($attr['NAME'])) { $objattr['fieldname'] = $attr['NAME']; }
16252 $this->form->form_element_spacing['textarea']['outer']['v'] = 0;
16253 $this->form->form_element_spacing['textarea']['inner']['v'] = 0;
16254 if (isset($attr['ONCALCULATE'])) { $objattr['onCalculate'] = $attr['ONCALCULATE']; }
16255 else if (isset($attr['ONCHANGE'])) { $objattr['onCalculate'] = $attr['ONCHANGE']; }
16256 if (isset($attr['ONVALIDATE'])) { $objattr['onValidate'] = $attr['ONVALIDATE']; }
16257 if (isset($attr['ONKEYSTROKE'])) { $objattr['onKeystroke'] = $attr['ONKEYSTROKE']; }
16258 if (isset($attr['ONFORMAT'])) { $objattr['onFormat'] = $attr['ONFORMAT']; }
16259 }
16260 $this->InlineProperties[$tag] = $this->saveInlineProperties();
16261 $properties = $this->cssmgr->MergeCSS('',$tag,$attr);
16262 if (isset($properties['FONT-FAMILY'])) {
16263 $this->SetFont($properties['FONT-FAMILY'],'',0,false);
16264 }
16265 if (isset($properties['FONT-SIZE'])) {
16266 $mmsize = $this->ConvertSize($properties['FONT-SIZE'],$this->default_font_size/_MPDFK);
16267 $this->SetFontSize($mmsize*_MPDFK,false);
16268 }
16269 if (isset($properties['COLOR'])) { $objattr['color'] = $this->ConvertColor($properties['COLOR']); }
16270 $objattr['fontfamily'] = $this->FontFamily;
16271 $objattr['fontsize'] = $this->FontSizePt;
16272 if ($this->useActiveForms) {
16273 if(isset($properties['TEXT-ALIGN'])) { $objattr['text_align'] = $align[strtolower($properties['TEXT-ALIGN'])]; }
16274 else if(isset($attr['ALIGN'])) { $objattr['text_align'] = $align[strtolower($attr['ALIGN'])]; }
16275 if (isset($properties['OVERFLOW']) && strtolower($properties['OVERFLOW'])=='hidden') { $objattr['donotscroll'] = true; }
16276 if (isset($properties['BORDER-TOP-COLOR'])) { $objattr['border-col'] = $this->ConvertColor($properties['BORDER-TOP-COLOR']); }
16277 if (isset($properties['BACKGROUND-COLOR'])) { $objattr['background-col'] = $this->ConvertColor($properties['BACKGROUND-COLOR']); }
16278 }
16279 $this->SetLineHeight('',$this->form->textarea_lineheight);
16280 $formLineHeight = $this->lineheight;
16281
16282 $w = 0;
16283 $h = 0;
16284 if(isset($properties['WIDTH'])) $w = $this->ConvertSize($properties['WIDTH'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
16285 if(isset($properties['HEIGHT'])) $h = $this->ConvertSize($properties['HEIGHT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
16286 if ($properties['VERTICAL-ALIGN']) { $objattr['vertical-align'] = $align[strtolower($properties['VERTICAL-ALIGN'])]; }
16287
16288 $colsize = 20; //HTML default value
16289 $rowsize = 2; //HTML default value
16290 if (isset($attr['COLS'])) $colsize = intval($attr['COLS']);
16291 if (isset($attr['ROWS'])) $rowsize = intval($attr['ROWS']);
16292
16293 $charsize = $this->GetCharWidth('w',false);
16294 if ($w) { $colsize = round(($w-($this->form->form_element_spacing['textarea']['outer']['h']*2)-($this->form->form_element_spacing['textarea']['inner']['h']*2))/$charsize); }
16295 if ($h) { $rowsize = round(($h-($this->form->form_element_spacing['textarea']['outer']['v']*2)-($this->form->form_element_spacing['textarea']['inner']['v']*2))/$formLineHeight); }
16296
16297 $objattr['type'] = 'textarea';
16298 $objattr['width'] = ($colsize * $charsize) + ($this->form->form_element_spacing['textarea']['outer']['h']*2)+($this->form->form_element_spacing['textarea']['inner']['h']*2);
16299 $objattr['height'] = ($rowsize * $formLineHeight) + ($this->form->form_element_spacing['textarea']['outer']['v']*2)+($this->form->form_element_spacing['textarea']['inner']['v']*2);
16300 $objattr['rows'] = $rowsize;
16301 $objattr['cols'] = $colsize;
16302
16303 $this->specialcontent = serialize($objattr);
16304
16305 if ($this->tableLevel) { // *TABLES*
16306 $this->cell[$this->row][$this->col]['s'] += $objattr['width'] ; // *TABLES*
16307 } // *TABLES*
16308
16309 // Clear properties - tidy up
16310 $properties = array();
16311 break;
16312
16313
16314
16315 // *********** FORM - INPUT ********************
16316
16317 case 'INPUT':
16318 if (!isset($attr['TYPE'])) $attr['TYPE'] == 'TEXT';
16319 $objattr = array();
16320 $objattr['margin_top'] = 0;
16321 $objattr['margin_bottom'] = 0;
16322 $objattr['margin_left'] = 0;
16323 $objattr['margin_right'] = 0;
16324 $objattr['width'] = 0;
16325 $objattr['height'] = 0;
16326 $objattr['border_top']['w'] = 0;
16327 $objattr['border_bottom']['w'] = 0;
16328 $objattr['border_left']['w'] = 0;
16329 $objattr['border_right']['w'] = 0;
16330 $objattr['type'] = 'input';
16331 if(isset($attr['DISABLED'])) { $objattr['disabled'] = true; }
16332 if(isset($attr['READONLY'])) { $objattr['readonly'] = true; }
16333 if(isset($attr['REQUIRED'])) { $objattr['required'] = true; }
16334 if(isset($attr['SPELLCHECK']) && strtolower($attr['SPELLCHECK'])=='true') { $objattr['spellcheck'] = true; }
16335 if(isset($attr['TITLE'])) { $objattr['title'] = $attr['TITLE']; }
16336 else if(isset($attr['ALT'])) { $objattr['title'] = $attr['ALT']; }
16337 else $objattr['title'] = '';
16338 $objattr['title'] = strcode2utf($objattr['title']);
16339 $objattr['title'] = $this->lesser_entity_decode($objattr['title']);
16340 if ($this->onlyCoreFonts)
16341 $objattr['title'] = mb_convert_encoding($objattr['title'], $this->mb_enc,'UTF-8');
16342 if ($this->useActiveForms) {
16343 if(isset($attr['NAME'])) { $objattr['fieldname'] = $attr['NAME']; }
16344 }
16345 if(isset($attr['VALUE'])) {
16346 $attr['VALUE'] = strcode2utf($attr['VALUE']);
16347 $attr['VALUE'] = $this->lesser_entity_decode($attr['VALUE']);
16348 if ($this->onlyCoreFonts)
16349 $attr['VALUE'] = mb_convert_encoding($attr['VALUE'], $this->mb_enc,'UTF-8');
16350 $objattr['value'] = $attr['VALUE'];
16351 }
16352
16353 $this->InlineProperties[$tag] = $this->saveInlineProperties();
16354 $properties = $this->cssmgr->MergeCSS('',$tag,$attr);
16355 $objattr['vertical-align'] = '';
16356
16357 if (isset($properties['FONT-FAMILY'])) {
16358 $this->SetFont($properties['FONT-FAMILY'],$this->FontStyle,0,false);
16359 }
16360 if (isset($properties['FONT-SIZE'])) {
16361 $mmsize = $this->ConvertSize($properties['FONT-SIZE'],($this->default_font_size/_MPDFK));
16362 $this->SetFontSize($mmsize*_MPDFK,false);
16363 }
16364 if (isset($properties['COLOR'])) { $objattr['color'] = $this->ConvertColor($properties['COLOR']); }
16365 $objattr['fontfamily'] = $this->FontFamily;
16366 $objattr['fontsize'] = $this->FontSizePt;
16367 if ($this->useActiveForms) {
16368 if(isset($attr['ALIGN'])) { $objattr['text_align'] = $align[strtolower($attr['ALIGN'])]; }
16369 else if(isset($properties['TEXT-ALIGN'])) { $objattr['text_align'] = $align[strtolower($properties['TEXT-ALIGN'])]; }
16370 if (isset($properties['BORDER-TOP-COLOR'])) { $objattr['border-col'] = $this->ConvertColor($properties['BORDER-TOP-COLOR']); }
16371 if (isset($properties['BACKGROUND-COLOR'])) { $objattr['background-col'] = $this->ConvertColor($properties['BACKGROUND-COLOR']); }
16372 }
16373
16374 $type = '';
16375 $texto='';
16376 $height = $this->FontSize;
16377 $width = 0;
16378 $spacesize = $this->GetCharWidth(' ',false);
16379
16380 $w = 0;
16381 if(isset($properties['WIDTH'])) $w = $this->ConvertSize($properties['WIDTH'],$this->blk[$this->blklvl]['inner_width']);
16382
16383 if ($properties['VERTICAL-ALIGN']) { $objattr['vertical-align'] = $align[strtolower($properties['VERTICAL-ALIGN'])]; }
16384
16385 switch(strtoupper($attr['TYPE'])){
16386 case 'HIDDEN':
16387 $this->ignorefollowingspaces = true; //Eliminate exceeding left-side spaces
16388 if ($this->useActiveForms) {
16389 $this->form->SetFormText( 0, 0, $objattr['fieldname'], $objattr['value'], $objattr['value'], '', 0, '', true );
16390 }
16391 if ($this->InlineProperties[$tag]) { $this->restoreInlineProperties($this->InlineProperties[$tag]); }
16392 unset($this->InlineProperties[$tag]);
16393 break 2;
16394 case 'CHECKBOX': //Draw Checkbox
16395 $type = 'CHECKBOX';
16396 if (isset($attr['CHECKED'])) { $objattr['checked'] = true; }
16397 else { $objattr['checked'] = false; }
16398 $width = $this->FontSize;
16399 $height = $this->FontSize;
16400 break;
16401
16402 case 'RADIO': //Draw Radio button
16403 $type = 'RADIO';
16404 if (isset($attr['CHECKED'])) $objattr['checked'] = true;
16405 $width = $this->FontSize;
16406 $height = $this->FontSize;
16407 break;
16408
16409 /*-- IMAGES-CORE --*/
16410 case 'IMAGE': // Draw an Image button
16411 if(isset($attr['SRC'])) {
16412 $type = 'IMAGE';
16413 $srcpath = $attr['SRC'];
16414 $orig_srcpath = $attr['ORIG_SRC'];
16415 // VSPACE and HSPACE converted to margins in MergeCSS
16416 if (isset($properties['MARGIN-TOP'])) { $objattr['margin_top']=$this->ConvertSize($properties['MARGIN-TOP'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
16417 if (isset($properties['MARGIN-BOTTOM'])) { $objattr['margin_bottom'] = $this->ConvertSize($properties['MARGIN-BOTTOM'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
16418 if (isset($properties['MARGIN-LEFT'])) { $objattr['margin_left'] = $this->ConvertSize($properties['MARGIN-LEFT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
16419 if (isset($properties['MARGIN-RIGHT'])) { $objattr['margin_right'] = $this->ConvertSize($properties['MARGIN-RIGHT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
16420
16421
16422 if (isset($properties['BORDER-TOP'])) { $objattr['border_top'] = $this->border_details($properties['BORDER-TOP']); }
16423 if (isset($properties['BORDER-BOTTOM'])) { $objattr['border_bottom'] = $this->border_details($properties['BORDER-BOTTOM']); }
16424 if (isset($properties['BORDER-LEFT'])) { $objattr['border_left'] = $this->border_details($properties['BORDER-LEFT']); }
16425 if (isset($properties['BORDER-RIGHT'])) { $objattr['border_right'] = $this->border_details($properties['BORDER-RIGHT']); }
16426
16427 $objattr['padding_top'] = 0;
16428 $objattr['padding_bottom'] = 0;
16429 $objattr['padding_left'] = 0;
16430 $objattr['padding_right'] = 0;
16431
16432 if (isset($properties['VERTICAL-ALIGN'])) { $objattr['vertical-align'] = $align[strtolower($properties['VERTICAL-ALIGN'])]; }
16433
16434 $w = 0;
16435 $h = 0;
16436 if(isset($properties['WIDTH'])) $w = $this->ConvertSize($properties['WIDTH'],$this->blk[$this->blklvl]['inner_width']);
16437 if(isset($properties['HEIGHT'])) $h = $this->ConvertSize($properties['HEIGHT'],$this->blk[$this->blklvl]['inner_width']);
16438
16439 $extraheight = $objattr['margin_top'] + $objattr['margin_bottom'] + $objattr['border_top']['w'] + $objattr['border_bottom']['w'];
16440 $extrawidth = $objattr['margin_left'] + $objattr['margin_right'] + $objattr['border_left']['w'] + $objattr['border_right']['w'];
16441
16442 // Image file
16443 $info=$this->_getImage($srcpath, true, true, $orig_srcpath);
16444 if(!$info) {
16445 $info = $this->_getImage($this->noImageFile);
16446 if ($info) {
16447 $srcpath = $this->noImageFile;
16448 $w = ($info['w'] * (25.4/$this->dpi));
16449 $h = ($info['h'] * (25.4/$this->dpi));
16450 }
16451 }
16452 if(!$info) break;
16453 if ($info['cs']=='Indexed') { $objattr['Indexed'] = true; }
16454 $objattr['file'] = $srcpath;
16455 //Default width and height calculation if needed
16456 if($w==0 and $h==0) {
16457 /*-- IMAGES-WMF --*/
16458 if ($info['type']=='wmf') {
16459 // WMF units are twips (1/20pt)
16460 // divide by 20 to get points
16461 // divide by k to get user units
16462 $w = abs($info['w'])/(20*_MPDFK);
16463 $h = abs($info['h']) / (20*_MPDFK);
16464 }
16465 else
16466 /*-- END IMAGES-WMF --*/
16467 if ($info['type']=='svg') {
16468 // SVG units are pixels
16469 $w = abs($info['w'])/_MPDFK;
16470 $h = abs($info['h'])/_MPDFK;
16471 }
16472 else {
16473 //Put image at default image dpi
16474 $w=($info['w']/_MPDFK) * (72/$this->img_dpi);
16475 $h=($info['h']/_MPDFK) * (72/$this->img_dpi);
16476 }
16477 if (isset($properties['IMAGE-RESOLUTION'])) {
16478 if (preg_match('/from-image/i', $properties['IMAGE-RESOLUTION']) && isset($info['set-dpi']) && $info['set-dpi']>0) {
16479 $w *= $this->img_dpi / $info['set-dpi'];
16480 $h *= $this->img_dpi / $info['set-dpi'];
16481 }
16482 else if (preg_match('/(\d+)dpi/i', $properties['IMAGE-RESOLUTION'], $m)) {
16483 $dpi = $m[1];
16484 if ($dpi > 0) {
16485 $w *= $this->img_dpi / $dpi;
16486 $h *= $this->img_dpi / $dpi;
16487 }
16488 }
16489 }
16490 }
16491 // IF WIDTH OR HEIGHT SPECIFIED
16492 if($w==0) $w=$h*$info['w']/$info['h'];
16493 if($h==0) $h=$w*$info['h']/$info['w'];
16494 // Resize to maximum dimensions of page
16495 $maxWidth = $this->blk[$this->blklvl]['inner_width'];
16496 $maxHeight = $this->h - ($this->tMargin + $this->bMargin + 10) ;
16497 if ($this->fullImageHeight) { $maxHeight = $this->fullImageHeight; }
16498 if ($w + $extrawidth > $maxWidth ) {
16499 $w = $maxWidth - $extrawidth;
16500 $h=$w*$info['h']/$info['w'];
16501 }
16502 if ($h + $extraheight > $maxHeight ) {
16503 $h = $maxHeight - $extraheight;
16504 $w=$h*$info['w']/$info['h'];
16505 }
16506 $height = $h + $extraheight;
16507 $width = $w + $extrawidth;
16508 $objattr['type'] = 'image';
16509 $objattr['itype'] = $info['type'];
16510 $objattr['orig_h'] = $info['h'];
16511 $objattr['orig_w'] = $info['w'];
16512 /*-- IMAGES-WMF --*/
16513 if ($info['type']=='wmf') {
16514 $objattr['wmf_x'] = $info['x'];
16515 $objattr['wmf_y'] = $info['y'];
16516 }
16517 else
16518 /*-- END IMAGES-WMF --*/
16519 if ($info['type']=='svg') {
16520 $objattr['wmf_x'] = $info['x'];
16521 $objattr['wmf_y'] = $info['y'];
16522 }
16523 $objattr['height'] = $h + $extraheight;
16524 $objattr['width'] = $w + $extrawidth;
16525
16526 $objattr['image_height'] = $h;
16527 $objattr['image_width'] = $w;
16528 $objattr['ID'] = $info['i'];
16529 $texto = 'X';
16530 if ($this->useActiveForms) {
16531 if (isset($attr['ONCLICK'])) { $objattr['onClick'] = $attr['ONCLICK']; }
16532 $objattr['type'] = 'input';
16533 $type = 'IMAGE';
16534 }
16535 break;
16536 }
16537 /*-- END IMAGES-CORE --*/
16538
16539 case 'BUTTON': // Draw a button
16540 case 'SUBMIT':
16541 case 'RESET':
16542 $type = strtoupper($attr['TYPE']);
16543 if ($type=='IMAGE') { $type = 'BUTTON'; } // src path not found
16544 if(isset($attr['NOPRINT'])) { $objattr['noprint'] = true; }
16545 if (!isset($attr['VALUE'])) {
16546 $objattr['value'] = ucfirst(strtolower($type));
16547 }
16548
16549 $texto = " " . $objattr['value'] . " ";
16550 $width = $this->GetStringWidth($texto) + ($this->form->form_element_spacing['button']['outer']['h']*2)+($this->form->form_element_spacing['button']['inner']['h']*2);
16551 $height = $this->FontSize + ($this->form->form_element_spacing['button']['outer']['v']*2)+($this->form->form_element_spacing['button']['inner']['v']*2);
16552 if ($this->useActiveForms) {
16553 if (isset($attr['ONCLICK'])) { $objattr['onClick'] = $attr['ONCLICK']; }
16554 }
16555 break;
16556
16557 case 'PASSWORD':
16558 case 'TEXT':
16559 default:
16560 if ($type == '') { $type = 'TEXT'; }
16561 if(strtoupper($attr['TYPE'])=='PASSWORD') { $type = 'PASSWORD'; }
16562 if (isset($attr['VALUE'])) {
16563 if ($type == 'PASSWORD') {
16564 $num_stars = mb_strlen($attr['VALUE'],$this->mb_enc );
16565 $texto = str_repeat('*',$num_stars);
16566 }
16567 else { $texto = $attr['VALUE']; }
16568 }
16569 $xw = ($this->form->form_element_spacing['input']['outer']['h']*2)+($this->form->form_element_spacing['input']['inner']['h']*2);
16570 $xh = ($this->form->form_element_spacing['input']['outer']['v']*2)+($this->form->form_element_spacing['input']['inner']['v']*2);
16571 if ($w) { $width = $w + $xw; }
16572 else { $width = (20 * $spacesize) + $xw; } // Default width in chars
16573 if (isset($attr['SIZE']) and ctype_digit($attr['SIZE']) ) $width = ($attr['SIZE'] * $spacesize) + $xw;
16574 $height = $this->FontSize + $xh;
16575 if (isset($attr['MAXLENGTH']) and ctype_digit($attr['MAXLENGTH']) ) $objattr['maxlength'] = $attr['MAXLENGTH'];
16576 if ($this->useActiveForms) {
16577 if (isset($attr['ONCALCULATE'])) { $objattr['onCalculate'] = $attr['ONCALCULATE']; }
16578 else if (isset($attr['ONCHANGE'])) { $objattr['onCalculate'] = $attr['ONCHANGE']; }
16579 if (isset($attr['ONVALIDATE'])) { $objattr['onValidate'] = $attr['ONVALIDATE']; }
16580 if (isset($attr['ONKEYSTROKE'])) { $objattr['onKeystroke'] = $attr['ONKEYSTROKE']; }
16581 if (isset($attr['ONFORMAT'])) { $objattr['onFormat'] = $attr['ONFORMAT']; }
16582 }
16583 break;
16584 }
16585
16586 $objattr['subtype'] = $type;
16587 $objattr['text'] = $texto;
16588 $objattr['width'] = $width;
16589 $objattr['height'] = $height;
16590 $e = "\xbb\xa4\xactype=input,objattr=".serialize($objattr)."\xbb\xa4\xac";
16591
16592 // Clear properties - tidy up
16593 $properties = array();
16594
16595 /*-- TABLES --*/
16596 // Output it to buffers
16597 if ($this->tableLevel) {
16598 $this->_saveCellTextBuffer($e, $this->HREF);
16599 $this->cell[$this->row][$this->col]['s'] += $objattr['width'] ;
16600
16601 }
16602 else {
16603 /*-- END TABLES --*/
16604 $this->_saveTextBuffer($e, $this->HREF);
16605 } // *TABLES*
16606
16607 if ($this->InlineProperties[$tag]) { $this->restoreInlineProperties($this->InlineProperties[$tag]); }
16608 unset($this->InlineProperties[$tag]);
16609
16610 break; // END of INPUT
16611 /*-- END FORMS --*/
16612
16613
16614 // *********** GRAPH ********************
16615 case 'JPGRAPH':
16616 if (!$this->useGraphs) { break; }
16617 if ($attr['TABLE']) { $gid = strtoupper($attr['TABLE']); }
16618 else { $gid = '0'; }
16619 if (!is_array($this->graphs[$gid]) || count($this->graphs[$gid])==0 ) { break; }
16620 include_once(_MPDF_PATH.'graph.php');
16621 $this->graphs[$gid]['attr'] = $attr;
16622
16623
16624 if (isset($this->graphs[$gid]['attr']['WIDTH']) && $this->graphs[$gid]['attr']['WIDTH']) {
16625 $this->graphs[$gid]['attr']['cWIDTH']=$this->ConvertSize($this->graphs[$gid]['attr']['WIDTH'],$pgwidth);
16626 } // mm
16627 if (isset($this->graphs[$gid]['attr']['HEIGHT']) && $this->graphs[$gid]['attr']['HEIGHT']) {
16628 $this->graphs[$gid]['attr']['cHEIGHT']=$this->ConvertSize($this->graphs[$gid]['attr']['HEIGHT'],$pgwidth);
16629 }
16630
16631 $graph_img = print_graph($this->graphs[$gid],$this->blk[$this->blklvl]['inner_width']);
16632 if ($graph_img) {
16633 if(isset($attr['ROTATE'])) {
16634 if ($attr['ROTATE']==90 || $attr['ROTATE']==-90) {
16635 $tmpw = $graph_img['w'];
16636 $graph_img['w']= $graph_img['h'];
16637 $graph_img['h']= $tmpw;
16638 }
16639 }
16640 $attr['SRC'] = $graph_img['file'];
16641 $attr['WIDTH'] = $graph_img['w'];
16642 $attr['HEIGHT'] = $graph_img['h'];
16643 }
16644 else { break; }
16645
16646 // *********** IMAGE ********************
16647 /*-- IMAGES-CORE --*/
16648 case 'IMG':
16649 if ($this->progressBar) { $this->UpdateProgressBar(1,'','IMG'); } // *PROGRESS-BAR*
16650 $objattr = array();
16651 $objattr['margin_top'] = 0;
16652 $objattr['margin_bottom'] = 0;
16653 $objattr['margin_left'] = 0;
16654 $objattr['margin_right'] = 0;
16655 $objattr['padding_top'] = 0;
16656 $objattr['padding_bottom'] = 0;
16657 $objattr['padding_left'] = 0;
16658 $objattr['padding_right'] = 0;
16659 $objattr['width'] = 0;
16660 $objattr['height'] = 0;
16661 $objattr['border_top']['w'] = 0;
16662 $objattr['border_bottom']['w'] = 0;
16663 $objattr['border_left']['w'] = 0;
16664 $objattr['border_right']['w'] = 0;
16665 if(isset($attr['SRC'])) {
16666 $srcpath = $attr['SRC'];
16667 $orig_srcpath = $attr['ORIG_SRC'];
16668 $properties = $this->cssmgr->MergeCSS('',$tag,$attr);
16669 if(isset($properties ['DISPLAY']) && strtolower($properties ['DISPLAY'])=='none') {
16670 return;
16671 }
16672 // mPDF 5.6.01 - LAYERS
16673 if (isset($properties['Z-INDEX']) && $this->currentlayer==0) {
16674 $v = intval($properties['Z-INDEX']);
16675 if ($v > 0) {
16676 $objattr['z-index'] = $v;
16677 }
16678 }
16679
16680 $objattr['visibility'] = 'visible';
16681 if (isset($properties['VISIBILITY'])) {
16682 $v = strtolower($properties['VISIBILITY']);
16683 if (($v == 'hidden' || $v == 'printonly' || $v == 'screenonly') && $this->visibility=='visible') {
16684 $objattr['visibility'] = $v;
16685 }
16686 }
16687
16688 // VSPACE and HSPACE converted to margins in MergeCSS
16689 if (isset($properties['MARGIN-TOP'])) { $objattr['margin_top']=$this->ConvertSize($properties['MARGIN-TOP'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
16690 if (isset($properties['MARGIN-BOTTOM'])) { $objattr['margin_bottom'] = $this->ConvertSize($properties['MARGIN-BOTTOM'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
16691 if (isset($properties['MARGIN-LEFT'])) { $objattr['margin_left'] = $this->ConvertSize($properties['MARGIN-LEFT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
16692 if (isset($properties['MARGIN-RIGHT'])) { $objattr['margin_right'] = $this->ConvertSize($properties['MARGIN-RIGHT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
16693
16694 if (isset($properties['PADDING-TOP'])) { $objattr['padding_top']=$this->ConvertSize($properties['PADDING-TOP'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
16695 if (isset($properties['PADDING-BOTTOM'])) { $objattr['padding_bottom'] = $this->ConvertSize($properties['PADDING-BOTTOM'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
16696 if (isset($properties['PADDING-LEFT'])) { $objattr['padding_left'] = $this->ConvertSize($properties['PADDING-LEFT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
16697 if (isset($properties['PADDING-RIGHT'])) { $objattr['padding_right'] = $this->ConvertSize($properties['PADDING-RIGHT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
16698
16699 if (isset($properties['BORDER-TOP'])) { $objattr['border_top'] = $this->border_details($properties['BORDER-TOP']); }
16700 if (isset($properties['BORDER-BOTTOM'])) { $objattr['border_bottom'] = $this->border_details($properties['BORDER-BOTTOM']); }
16701 if (isset($properties['BORDER-LEFT'])) { $objattr['border_left'] = $this->border_details($properties['BORDER-LEFT']); }
16702 if (isset($properties['BORDER-RIGHT'])) { $objattr['border_right'] = $this->border_details($properties['BORDER-RIGHT']); }
16703
16704 if (isset($properties['VERTICAL-ALIGN'])) { $objattr['vertical-align'] = $align[strtolower($properties['VERTICAL-ALIGN'])]; }
16705 $w = 0;
16706 $h = 0;
16707 if(isset($properties['WIDTH'])) $w = $this->ConvertSize($properties['WIDTH'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
16708 else if(isset($attr['WIDTH'])) $w = $this->ConvertSize($attr['WIDTH'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
16709 if(isset($properties['HEIGHT'])) $h = $this->ConvertSize($properties['HEIGHT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
16710 else if(isset($attr['HEIGHT'])) $h = $this->ConvertSize($attr['HEIGHT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
16711 // mPDF 5.5.15 // mPDF 5.6.60
16712 $maxw=$maxh=$minw=$minh=false;
16713 if(isset($properties['MAX-WIDTH'])) $maxw = $this->ConvertSize($properties['MAX-WIDTH'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
16714 else if(isset($attr['MAX-WIDTH'])) $maxw = $this->ConvertSize($attr['MAX-WIDTH'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
16715 if(isset($properties['MAX-HEIGHT'])) $maxh = $this->ConvertSize($properties['MAX-HEIGHT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
16716 else if(isset($attr['MAX-HEIGHT'])) $maxh = $this->ConvertSize($attr['MAX-HEIGHT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
16717 if(isset($properties['MIN-WIDTH'])) $minw = $this->ConvertSize($properties['MIN-WIDTH'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
16718 else if(isset($attr['MIN-WIDTH'])) $minw = $this->ConvertSize($attr['MIN-WIDTH'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
16719 if(isset($properties['MIN-HEIGHT'])) $minh = $this->ConvertSize($properties['MIN-HEIGHT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
16720 else if(isset($attr['MIN-HEIGHT'])) $minh = $this->ConvertSize($attr['MIN-HEIGHT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
16721
16722 if (isset($properties['OPACITY']) && $properties['OPACITY'] > 0 && $properties['OPACITY'] <= 1) { $objattr['opacity'] = $properties['OPACITY']; }
16723 if ($this->HREF) {
16724 if (strpos($this->HREF,".") === false && strpos($this->HREF,"@") !== 0) {
16725 $href = $this->HREF;
16726 while(array_key_exists($href,$this->internallink)) $href="#".$href;
16727 $this->internallink[$href] = $this->AddLink();
16728 $objattr['link'] = $this->internallink[$href];
16729 }
16730 else { $objattr['link'] = $this->HREF; }
16731 }
16732 $extraheight = $objattr['padding_top'] + $objattr['padding_bottom'] + $objattr['margin_top'] + $objattr['margin_bottom'] + $objattr['border_top']['w'] + $objattr['border_bottom']['w'];
16733 $extrawidth = $objattr['padding_left'] + $objattr['padding_right'] + $objattr['margin_left'] + $objattr['margin_right'] + $objattr['border_left']['w'] + $objattr['border_right']['w'];
16734
16735 /*-- BACKGROUNDS --*/
16736 if(isset($properties['GRADIENT-MASK']) && preg_match('/(-moz-)*(repeating-)*(linear|radial)-gradient/',$properties['GRADIENT-MASK'])) {
16737 $objattr['GRADIENT-MASK'] = $properties['GRADIENT-MASK'];
16738 }
16739 /*-- END BACKGROUNDS --*/
16740
16741 // Image file
16742 $info=$this->_getImage($srcpath, true, true, $orig_srcpath);
16743 if(!$info) {
16744 $info = $this->_getImage($this->noImageFile);
16745 if ($info) {
16746 $srcpath = $this->noImageFile;
16747 $w = ($info['w'] * (25.4/$this->dpi));
16748 $h = ($info['h'] * (25.4/$this->dpi));
16749 }
16750 }
16751 if(!$info) break;
16752
16753 if(isset($attr['ROTATE'])) { $image_orientation = $attr['ROTATE']; }
16754 else if(isset($properties['IMAGE-ORIENTATION'])) { $image_orientation = $properties['IMAGE-ORIENTATION']; }
16755 else { $image_orientation = 0; }
16756 if($image_orientation) {
16757 if ($image_orientation==90 || $image_orientation==-90 || $image_orientation==270) {
16758 $tmpw = $info['w'];
16759 $info['w'] = $info['h'];
16760 $info['h'] = $tmpw;
16761 }
16762 $objattr['ROTATE'] = $image_orientation;
16763 }
16764
16765 $objattr['file'] = $srcpath;
16766 //Default width and height calculation if needed
16767 if($w==0 and $h==0) {
16768 /*-- IMAGES-WMF --*/
16769 if ($info['type']=='wmf') {
16770 // WMF units are twips (1/20pt)
16771 // divide by 20 to get points
16772 // divide by k to get user units
16773 $w = abs($info['w'])/(20*_MPDFK);
16774 $h = abs($info['h']) / (20*_MPDFK);
16775 }
16776 else
16777 /*-- END IMAGES-WMF --*/
16778 if ($info['type']=='svg') {
16779 // SVG units are pixels
16780 $w = abs($info['w'])/_MPDFK;
16781 $h = abs($info['h'])/_MPDFK;
16782 }
16783 else {
16784 //Put image at default image dpi
16785 $w=($info['w']/_MPDFK) * (72/$this->img_dpi);
16786 $h=($info['h']/_MPDFK) * (72/$this->img_dpi);
16787 }
16788 if (isset($properties['IMAGE-RESOLUTION'])) {
16789 if (preg_match('/from-image/i', $properties['IMAGE-RESOLUTION']) && isset($info['set-dpi']) && $info['set-dpi']>0) {
16790 $w *= $this->img_dpi / $info['set-dpi'];
16791 $h *= $this->img_dpi / $info['set-dpi'];
16792 }
16793 else if (preg_match('/(\d+)dpi/i', $properties['IMAGE-RESOLUTION'], $m)) {
16794 $dpi = $m[1];
16795 if ($dpi > 0) {
16796 $w *= $this->img_dpi / $dpi;
16797 $h *= $this->img_dpi / $dpi;
16798 }
16799 }
16800 }
16801 }
16802 // IF WIDTH OR HEIGHT SPECIFIED
16803 if($w==0) $w=abs($h*$info['w']/$info['h']);
16804 if($h==0) $h=abs($w*$info['h']/$info['w']);
16805
16806 // mPDF 5.5.15
16807 if ($minw && $w<$minw) { $w = $minw; $h=abs($w*$info['h']/$info['w']); }
16808 if ($maxw && $w>$maxw) { $w = $maxw; $h=abs($w*$info['h']/$info['w']); }
16809 if ($minh && $h<$minh) { $h = $minh; $w=abs($h*$info['w']/$info['h']); }
16810 if ($maxh && $h>$maxh) { $h = $maxh; $w=abs($h*$info['w']/$info['h']); }
16811
16812 // Resize to maximum dimensions of page
16813 $maxWidth = $this->blk[$this->blklvl]['inner_width'];
16814 $maxHeight = $this->h - ($this->tMargin + $this->bMargin + 1) ;
16815 if ($this->fullImageHeight) { $maxHeight = $this->fullImageHeight; }
16816 if ($w + $extrawidth > $maxWidth ) {
16817 $w = $maxWidth - $extrawidth;
16818 $h=abs($w*$info['h']/$info['w']);
16819 }
16820
16821 if ($h + $extraheight > $maxHeight ) {
16822 $h = $maxHeight - $extraheight;
16823 $w=abs($h*$info['w']/$info['h']);
16824 }
16825 $objattr['type'] = 'image';
16826 $objattr['itype'] = $info['type'];
16827
16828 $objattr['orig_h'] = $info['h'];
16829 $objattr['orig_w'] = $info['w'];
16830 /*-- IMAGES-WMF --*/
16831 if ($info['type']=='wmf') {
16832 $objattr['wmf_x'] = $info['x'];
16833 $objattr['wmf_y'] = $info['y'];
16834 }
16835 else
16836 /*-- END IMAGES-WMF --*/
16837 if ($info['type']=='svg') {
16838 $objattr['wmf_x'] = $info['x'];
16839 $objattr['wmf_y'] = $info['y'];
16840 }
16841 $objattr['height'] = $h + $extraheight;
16842 $objattr['width'] = $w + $extrawidth;
16843 $objattr['image_height'] = $h;
16844 $objattr['image_width'] = $w;
16845 /*-- CSS-IMAGE-FLOAT --*/
16846 if (!$this->ColActive && !$this->tableLevel && !$this->listlvl && !$this->kwt && !$this->keep_block_together) {
16847 if (isset($properties['FLOAT']) && (strtoupper($properties['FLOAT']) == 'RIGHT' || strtoupper($properties['FLOAT']) == 'LEFT')) {
16848 $objattr['float'] = substr(strtoupper($properties['FLOAT']),0,1);
16849 }
16850 }
16851 /*-- END CSS-IMAGE-FLOAT --*/
16852
16853 $e = "\xbb\xa4\xactype=image,objattr=".serialize($objattr)."\xbb\xa4\xac";
16854
16855 // Clear properties - tidy up
16856 $properties = array();
16857
16858 /*-- TABLES --*/
16859 // Output it to buffers
16860 if ($this->tableLevel) {
16861 $this->_saveCellTextBuffer($e, $this->HREF);
16862 $this->cell[$this->row][$this->col]['s'] += $objattr['width'] ;
16863 }
16864 else {
16865 /*-- END TABLES --*/
16866 $this->_saveTextBuffer($e, $this->HREF);
16867 } // *TABLES*
16868 /*-- ANNOTATIONS --*/
16869 if ($this->title2annots && isset($attr['TITLE'])) {
16870 $objattr = array();
16871 $objattr['margin_top'] = 0;
16872 $objattr['margin_bottom'] = 0;
16873 $objattr['margin_left'] = 0;
16874 $objattr['margin_right'] = 0;
16875 $objattr['width'] = 0;
16876 $objattr['height'] = 0;
16877 $objattr['border_top']['w'] = 0;
16878 $objattr['border_bottom']['w'] = 0;
16879 $objattr['border_left']['w'] = 0;
16880 $objattr['border_right']['w'] = 0;
16881 $objattr['CONTENT'] = $attr['TITLE'];
16882 $objattr['type'] = 'annot';
16883 $objattr['POS-X'] = 0;
16884 $objattr['POS-Y'] = 0;
16885 $objattr['ICON'] = 'Comment';
16886 $objattr['AUTHOR'] = '';
16887 $objattr['SUBJECT'] = '';
16888 $objattr['OPACITY'] = $this->annotOpacity;
16889 $objattr['COLOR'] = $this->ConvertColor('yellow');
16890 $e = "\xbb\xa4\xactype=annot,objattr=".serialize($objattr)."\xbb\xa4\xac";
16891 if($this->tableLevel) { // *TABLES*
16892 $this->cell[$this->row][$this->col]['textbuffer'][] = array($e); // *TABLES*
16893 } // *TABLES*
16894 else { // *TABLES*
16895 $this->textbuffer[] = array($e);
16896 } // *TABLES*
16897 }
16898 /*-- END ANNOTATIONS --*/
16899 }
16900 break;
16901 /*-- END IMAGES-CORE --*/
16902
16903
16904 // *********** CIRCULAR TEXT = TEXTCIRCLE ********************
16905 case 'TEXTCIRCLE':
16906 $objattr = array();
16907 $objattr['margin_top'] = 0;
16908 $objattr['margin_bottom'] = 0;
16909 $objattr['margin_left'] = 0;
16910 $objattr['margin_right'] = 0;
16911 $objattr['padding_top'] = 0;
16912 $objattr['padding_bottom'] = 0;
16913 $objattr['padding_left'] = 0;
16914 $objattr['padding_right'] = 0;
16915 $objattr['width'] = 0;
16916 $objattr['height'] = 0;
16917 $objattr['border_top']['w'] = 0;
16918 $objattr['border_bottom']['w'] = 0;
16919 $objattr['border_left']['w'] = 0;
16920 $objattr['border_right']['w'] = 0;
16921 $objattr['top-text'] = '';
16922 $objattr['bottom-text'] = '';
16923 $objattr['r'] = 20; // radius (default value here for safety)
16924 $objattr['space-width'] = 120;
16925 $objattr['char-width'] = 100;
16926
16927 $this->InlineProperties[$tag] = $this->saveInlineProperties();
16928 $properties = $this->cssmgr->MergeCSS('INLINE',$tag,$attr);
16929
16930 if(isset($properties ['DISPLAY']) && strtolower($properties ['DISPLAY'])=='none') {
16931 return;
16932 }
16933 if (isset($attr['R'])) { $objattr['r']=$this->ConvertSize($attr['R'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
16934 if(isset($attr['TOP-TEXT'])) {
16935 $objattr['top-text'] = strcode2utf($attr['TOP-TEXT']);
16936 $objattr['top-text'] = $this->lesser_entity_decode($objattr['top-text']);
16937 if ($this->onlyCoreFonts)
16938 $objattr['top-text'] = mb_convert_encoding($objattr['top-text'], $this->mb_enc,'UTF-8');
16939 }
16940 if(isset($attr['BOTTOM-TEXT'])) {
16941 $objattr['bottom-text'] = strcode2utf($attr['BOTTOM-TEXT']);
16942 $objattr['bottom-text'] = $this->lesser_entity_decode($objattr['bottom-text']);
16943 if ($this->onlyCoreFonts)
16944 $objattr['bottom-text'] = mb_convert_encoding($objattr['bottom-text'], $this->mb_enc,'UTF-8');
16945 }
16946 if(isset($attr['SPACE-WIDTH']) && $attr['SPACE-WIDTH']) { $objattr['space-width'] = $attr['SPACE-WIDTH']; }
16947 if(isset($attr['CHAR-WIDTH']) && $attr['CHAR-WIDTH']) { $objattr['char-width'] = $attr['CHAR-WIDTH']; }
16948
16949 // VISIBILITY
16950 $objattr['visibility'] = 'visible';
16951 if (isset($properties['VISIBILITY'])) {
16952 $v = strtolower($properties['VISIBILITY']);
16953 if (($v == 'hidden' || $v == 'printonly' || $v == 'screenonly') && $this->visibility=='visible') {
16954 $objattr['visibility'] = $v;
16955 }
16956 }
16957 // mPDF 5.5.23
16958 if (isset($properties['FONT-SIZE'])) {
16959 if (strtolower($properties['FONT-SIZE'])=='auto') {
16960 if ($objattr['top-text'] && $objattr['bottom-text']) {
16961 $objattr['fontsize'] = -2;
16962 }
16963 else {
16964 $objattr['fontsize'] = -1;
16965 }
16966 }
16967 else {
16968 $mmsize = $this->ConvertSize($properties['FONT-SIZE'],($this->default_font_size/_MPDFK));
16969 $this->SetFontSize($mmsize*_MPDFK,false);
16970 $objattr['fontsize'] = $this->FontSizePt;
16971 }
16972 }
16973 // mPDF 5.5.23
16974 if(isset($attr['DIVIDER'])) {
16975 $objattr['divider'] = strcode2utf($attr['DIVIDER']);
16976 $objattr['divider'] = $this->lesser_entity_decode($objattr['divider']);
16977 if ($this->onlyCoreFonts)
16978 $objattr['divider'] = mb_convert_encoding($objattr['divider'], $this->mb_enc,'UTF-8');
16979
16980 }
16981
16982 if (isset($properties['COLOR'])) { $objattr['color'] = $this->ConvertColor($properties['COLOR']); }
16983
16984 $objattr['fontstyle'] = '';
16985 if (isset($properties['FONT-WEIGHT'])) {
16986 if (strtoupper($properties['FONT-WEIGHT']) == 'BOLD') { $objattr['fontstyle'] .= 'B'; }
16987 }
16988 if (isset($properties['FONT-STYLE'])) {
16989 if (strtoupper($properties['FONT-STYLE']) == 'ITALIC') { $objattr['fontstyle'] .= 'I'; }
16990 }
16991
16992 if (isset($properties['FONT-FAMILY'])) {
16993 $this->SetFont($properties['FONT-FAMILY'],$this->FontStyle,0,false);
16994 }
16995 $objattr['fontfamily'] = $this->FontFamily;
16996
16997 // VSPACE and HSPACE converted to margins in MergeCSS
16998 if (isset($properties['MARGIN-TOP'])) { $objattr['margin_top']=$this->ConvertSize($properties['MARGIN-TOP'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
16999 if (isset($properties['MARGIN-BOTTOM'])) { $objattr['margin_bottom'] = $this->ConvertSize($properties['MARGIN-BOTTOM'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
17000 if (isset($properties['MARGIN-LEFT'])) { $objattr['margin_left'] = $this->ConvertSize($properties['MARGIN-LEFT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
17001 if (isset($properties['MARGIN-RIGHT'])) { $objattr['margin_right'] = $this->ConvertSize($properties['MARGIN-RIGHT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
17002
17003 if (isset($properties['PADDING-TOP'])) { $objattr['padding_top']=$this->ConvertSize($properties['PADDING-TOP'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
17004 if (isset($properties['PADDING-BOTTOM'])) { $objattr['padding_bottom'] = $this->ConvertSize($properties['PADDING-BOTTOM'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
17005 if (isset($properties['PADDING-LEFT'])) { $objattr['padding_left'] = $this->ConvertSize($properties['PADDING-LEFT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
17006 if (isset($properties['PADDING-RIGHT'])) { $objattr['padding_right'] = $this->ConvertSize($properties['PADDING-RIGHT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
17007
17008 if (isset($properties['BORDER-TOP'])) { $objattr['border_top'] = $this->border_details($properties['BORDER-TOP']); }
17009 if (isset($properties['BORDER-BOTTOM'])) { $objattr['border_bottom'] = $this->border_details($properties['BORDER-BOTTOM']); }
17010 if (isset($properties['BORDER-LEFT'])) { $objattr['border_left'] = $this->border_details($properties['BORDER-LEFT']); }
17011 if (isset($properties['BORDER-RIGHT'])) { $objattr['border_right'] = $this->border_details($properties['BORDER-RIGHT']); }
17012
17013 if (isset($properties['OPACITY']) && $properties['OPACITY'] > 0 && $properties['OPACITY'] <= 1) { $objattr['opacity'] = $properties['OPACITY']; }
17014 if (isset($properties['BACKGROUND-COLOR']) && $properties['BACKGROUND-COLOR'] != '') { $objattr['bgcolor'] = $this->ConvertColor($properties['BACKGROUND-COLOR']); }
17015 else { $objattr['bgcolor'] = false; }
17016 if ($this->HREF) {
17017 if (strpos($this->HREF,".") === false && strpos($this->HREF,"@") !== 0) {
17018 $href = $this->HREF;
17019 while(array_key_exists($href,$this->internallink)) $href="#".$href;
17020 $this->internallink[$href] = $this->AddLink();
17021 $objattr['link'] = $this->internallink[$href];
17022 }
17023 else { $objattr['link'] = $this->HREF; }
17024 }
17025 $extraheight = $objattr['padding_top'] + $objattr['padding_bottom'] + $objattr['margin_top'] + $objattr['margin_bottom'] + $objattr['border_top']['w'] + $objattr['border_bottom']['w'];
17026 $extrawidth = $objattr['padding_left'] + $objattr['padding_right'] + $objattr['margin_left'] + $objattr['margin_right'] + $objattr['border_left']['w'] + $objattr['border_right']['w'];
17027
17028
17029 $w = $objattr['r']*2;
17030 $h = $w;
17031 $objattr['height'] = $h + $extraheight;
17032 $objattr['width'] = $w + $extrawidth;
17033 $objattr['type'] = 'textcircle';
17034
17035 $e = "\xbb\xa4\xactype=image,objattr=".serialize($objattr)."\xbb\xa4\xac";
17036
17037 // Clear properties - tidy up
17038 $properties = array();
17039
17040 /*-- TABLES --*/
17041 // Output it to buffers
17042 if ($this->tableLevel) {
17043 $this->_saveCellTextBuffer($e, $this->HREF);
17044 $this->cell[$this->row][$this->col]['s'] += $objattr['width'] ;
17045 }
17046 else {
17047 /*-- END TABLES --*/
17048 $this->_saveTextBuffer($e, $this->HREF);
17049 } // *TABLES*
17050
17051 if ($this->InlineProperties[$tag]) { $this->restoreInlineProperties($this->InlineProperties[$tag]); }
17052 unset($this->InlineProperties[$tag]);
17053
17054 break;
17055
17056
17057 /*-- TABLES --*/
17058
17059 case 'TABLE': // TABLE-BEGIN
17060 $this->tdbegin = false;
17061 $this->lastoptionaltag = '';
17062 // Disable vertical justification in columns
17063 if ($this->ColActive) { $this->colvAlign = ''; } // *COLUMNS*
17064 if ($this->lastblocklevelchange == 1) { $blockstate = 1; } // Top margins/padding only
17065 else if ($this->lastblocklevelchange < 1) { $blockstate = 0; } // NO margins/padding
17066 // called from block after new div e.g. <div> ... <table> ... Outputs block top margin/border and padding
17067 if (count($this->textbuffer) == 0 && $this->lastblocklevelchange == 1 && !$this->tableLevel && !$this->kwt) {
17068 $this->newFlowingBlock( $this->blk[$this->blklvl]['width'],$this->lineheight,'',false,false,1,true, $this->blk[$this->blklvl]['direction']);
17069 $this->finishFlowingBlock(true); // true = END of flowing block
17070 }
17071 else if (!$this->tableLevel && count($this->textbuffer)) { $this->printbuffer($this->textbuffer,$blockstate); }
17072
17073 $this->textbuffer=array();
17074 $this->lastblocklevelchange = -1;
17075 if ($this->tableLevel) { // i.e. now a nested table coming...
17076 // Save current level table
17077 // mPDF 5.4.10
17078 $this->cell['PARENTCELL'] = $this->saveInlineProperties();
17079 $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['baseProperties']= $this->base_table_properties;
17080 $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['cells'] = $this->cell;
17081 $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['currrow'] = $this->row;
17082 $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['currcol'] = $this->col;
17083 }
17084 $this->tableLevel++;
17085 $this->cssmgr->tbCSSlvl++;
17086
17087 if ($this->tableLevel>1) { // inherit table properties from cell in which nested
17088 $this->base_table_properties['FONT-KERNING'] = $this->kerning ;
17089 $this->base_table_properties['LETTER-SPACING'] = $this->lSpacingCSS ;
17090 $this->base_table_properties['WORD-SPACING'] = $this->wSpacingCSS ;
17091 }
17092
17093 if (isset($this->tbctr[$this->tableLevel])) { $this->tbctr[$this->tableLevel]++; }
17094 else { $this->tbctr[$this->tableLevel] = 1; }
17095
17096 $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['level'] = $this->tableLevel;
17097 $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['levelid'] = $this->tbctr[$this->tableLevel];
17098
17099 if ($this->tableLevel > $this->innermostTableLevel) { $this->innermostTableLevel = $this->tableLevel; }
17100 if ($this->tableLevel > 1) {
17101 $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['nestedpos'] = array($this->row,$this->col,$this->tbctr[($this->tableLevel-1)]);
17102 }
17103 //++++++++++++++++++++++++++++
17104
17105 $this->cell = array();
17106 $this->col=-1; //int
17107 $this->row=-1; //int
17108 $table = &$this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]];
17109
17110 // New table - any level
17111 if ($this->cacheTables) {
17112 $this->packTableData = true; // required for cacheTables
17113 $this->simpleTables = false; // Cannot co-exist with cacheTables
17114 $table['cache'] = _MPDF_TEMP_PATH.'_tempTblCache'.RAND(1,1000000).'.dat';
17115 $fh = fopen($table['cache'] , "wb") or $this->Error("When using cacheTables, you must have read/write access to cache files (".$table['cache'] .")");
17116 fwrite($fh, "\x00");
17117 fclose($fh);
17118 $table['ptr'] = 1 ; // Must not be 0
17119 }
17120
17121 $table['direction'] = $this->directionality;
17122 $table['bgcolor'] = false;
17123 $table['va'] = false;
17124 $table['txta'] = false;
17125 $table['topntail'] = false;
17126 $table['thead-underline'] = false;
17127 $table['border'] = false;
17128 $table['border_details']['R']['w'] = 0;
17129 $table['border_details']['L']['w'] = 0;
17130 $table['border_details']['T']['w'] = 0;
17131 $table['border_details']['B']['w'] = 0;
17132 $table['border_details']['R']['style'] = '';
17133 $table['border_details']['L']['style'] = '';
17134 $table['border_details']['T']['style'] = '';
17135 $table['border_details']['B']['style'] = '';
17136 $table['max_cell_border_width']['R'] = 0;
17137 $table['max_cell_border_width']['L'] = 0;
17138 $table['max_cell_border_width']['T'] = 0;
17139 $table['max_cell_border_width']['B'] = 0;
17140 $table['padding']['L'] = false;
17141 $table['padding']['R'] = false;
17142 $table['padding']['T'] = false;
17143 $table['padding']['B'] = false;
17144 $table['margin']['L'] = false;
17145 $table['margin']['R'] = false;
17146 $table['margin']['T'] = false;
17147 $table['margin']['B'] = false;
17148 $table['a'] = false;
17149 $table['border_spacing_H'] = false;
17150 $table['border_spacing_V'] = false;
17151 $table['decimal_align'] = false; // mPDF 5.6.13
17152 $this->Reset();
17153 $this->InlineProperties = array();
17154 $this->spanlvl = 0;
17155 $table['nc'] = $table['nr'] = 0;
17156 $this->tablethead = 0;
17157 $this->tabletfoot = 0;
17158 $this->tabletheadjustfinished = false;
17159
17160
17161 if ($this->blockjustfinished && !count($this->textbuffer) && $this->y != $this->tMargin && $this->collapseBlockMargins && $this->tableLevel==1) { $lastbottommargin = $this->lastblockbottommargin; }
17162 else { $lastbottommargin = 0; }
17163 $this->lastblockbottommargin = 0;
17164 $this->blockjustfinished=false;
17165
17166 if ($this->tableLevel==1) {
17167 $this->tableCJK = false;
17168 $this->table_lineheight = $this->normalLineheight;
17169 $table['headernrows'] = 0;
17170 $table['footernrows'] = 0;
17171 $this->base_table_properties = array();
17172 }
17173
17174 // ADDED CSS FUNCIONS FOR TABLE
17175 if ($this->cssmgr->tbCSSlvl==1) {
17176 $properties = $this->cssmgr->MergeCSS('TOPTABLE',$tag,$attr);
17177 }
17178 else {
17179 $properties = $this->cssmgr->MergeCSS('TABLE',$tag,$attr);
17180 }
17181 $w = '';
17182 if (isset($properties['WIDTH'])) { $w = $properties['WIDTH']; }
17183 else if (isset($attr['WIDTH']) && $attr['WIDTH']) { $w = $attr['WIDTH']; }
17184
17185
17186 if(isset($properties['DIRECTION']) && $properties['DIRECTION']) { $table['direction'] = strtolower($properties['DIRECTION']); }
17187 else if(isset($attr['DIR']) && $attr['DIR']) { $table['direction'] = strtolower($attr['DIR']); }
17188 else if (!isset($table['direction'])){ $table['direction'] = $this->blk[$this->blklvl]['direction']; }
17189
17190 if (isset($properties['BACKGROUND-COLOR'])) { $table['bgcolor'][-1] = $properties['BACKGROUND-COLOR']; }
17191 else if (isset($properties['BACKGROUND'])) { $table['bgcolor'][-1] = $properties['BACKGROUND']; }
17192 else if (isset($attr['BGCOLOR'])) { $table['bgcolor'][-1] = $attr['BGCOLOR']; }
17193 if (isset($properties['VERTICAL-ALIGN'])) { $table['va'] = $align[strtolower($properties['VERTICAL-ALIGN'])]; }
17194 if (isset($properties['TEXT-ALIGN'])) { $table['txta'] = $align[strtolower($properties['TEXT-ALIGN'])]; }
17195 if (isset($attr['ALIGN'])) { $table['a'] = $align[strtolower($attr['ALIGN'])]; }
17196 if (!$table['a']) {
17197 if ($table['direction'] == 'rtl' ) { $table['a'] = 'R'; }
17198 else { $table['a'] = 'L'; }
17199 }
17200
17201 if (isset($properties['AUTOSIZE']) && $properties['AUTOSIZE'] && $this->tableLevel ==1) {
17202 $this->shrink_this_table_to_fit = $properties['AUTOSIZE'];
17203 if ($this->shrink_this_table_to_fit < 1) { $this->shrink_this_table_to_fit = 0; }
17204 }
17205 if (isset($properties['ROTATE']) && $properties['ROTATE'] && $this->tableLevel ==1) {
17206 $this->table_rotate = $properties['ROTATE'];
17207 }
17208 if (isset($properties['TOPNTAIL'])) { $table['topntail'] = $properties['TOPNTAIL']; }
17209 if (isset($properties['THEAD-UNDERLINE'])) { $table['thead-underline'] = $properties['THEAD-UNDERLINE']; }
17210
17211 if (isset($properties['BORDER'])) {
17212 $bord = $this->border_details($properties['BORDER']);
17213 if ($bord['s']) {
17214 $table['border'] = _BORDER_ALL;
17215 $table['border_details']['R'] = $bord;
17216 $table['border_details']['L'] = $bord;
17217 $table['border_details']['T'] = $bord;
17218 $table['border_details']['B'] = $bord;
17219 }
17220 }
17221 if (isset($properties['BORDER-RIGHT'])) {
17222 if ($table['direction'] == 'rtl') { // *RTL*
17223 $table['border_details']['R'] = $this->border_details($properties['BORDER-LEFT']); // *RTL*
17224 } // *RTL*
17225 else { // *RTL*
17226 $table['border_details']['R'] = $this->border_details($properties['BORDER-RIGHT']);
17227 } // *RTL*
17228 $this->setBorder($table['border'], _BORDER_RIGHT, $table['border_details']['R']['s']);
17229 }
17230 if (isset($properties['BORDER-LEFT'])) {
17231 if ($table['direction'] == 'rtl') { // *RTL*
17232 $table['border_details']['L'] = $this->border_details($properties['BORDER-RIGHT']); // *RTL*
17233 } // *RTL*
17234 else { // *RTL*
17235 $table['border_details']['L'] = $this->border_details($properties['BORDER-LEFT']);
17236 } // *RTL*
17237 $this->setBorder($table['border'], _BORDER_LEFT, $table['border_details']['L']['s']);
17238 }
17239 if (isset($properties['BORDER-BOTTOM'])) {
17240 $table['border_details']['B'] = $this->border_details($properties['BORDER-BOTTOM']);
17241 $this->setBorder($table['border'], _BORDER_BOTTOM, $table['border_details']['B']['s']);
17242 }
17243 if (isset($properties['BORDER-TOP'])) {
17244 $table['border_details']['T'] = $this->border_details($properties['BORDER-TOP']);
17245 $this->setBorder($table['border'], _BORDER_TOP, $table['border_details']['T']['s']);
17246 }
17247 if ($table['border']){
17248 $this->table_border_css_set = 1;
17249 }
17250 else {
17251 $this->table_border_css_set = 0;
17252 }
17253
17254 if (isset($properties['FONT-FAMILY'])) {
17255 $this->default_font = $properties['FONT-FAMILY'];
17256 $this->SetFont($this->default_font,'',0,false);
17257 }
17258 $this->base_table_properties['FONT-FAMILY'] = $this->FontFamily; // mPDF 5.4.10
17259
17260 if (isset($properties['FONT-SIZE'])) {
17261 // mPDF 5.4.10
17262 if ($this->tableLevel>1) { $mmsize = $this->ConvertSize($properties['FONT-SIZE'], $this->base_table_properties['FONT-SIZE']); }
17263 else { $mmsize = $this->ConvertSize($properties['FONT-SIZE'],$this->default_font_size/_MPDFK); }
17264 if ($mmsize) {
17265 $this->default_font_size = $mmsize*(_MPDFK);
17266 $this->SetFontSize($this->default_font_size,false);
17267 }
17268 }
17269 $this->base_table_properties['FONT-SIZE'] = $this->FontSize.'mm'; // mPDF 5.4.10
17270
17271 if (isset($properties['FONT-WEIGHT'])) {
17272 if (strtoupper($properties['FONT-WEIGHT']) == 'BOLD') { $this->base_table_properties['FONT-WEIGHT'] = 'BOLD'; }
17273 }
17274 if (isset($properties['FONT-STYLE'])) {
17275 if (strtoupper($properties['FONT-STYLE']) == 'ITALIC') { $this->base_table_properties['FONT-STYLE'] = 'ITALIC'; }
17276 }
17277 if (isset($properties['COLOR'])) {
17278 $this->base_table_properties['COLOR'] = $properties['COLOR'];
17279 }
17280 if (isset($properties['FONT-KERNING'])) {
17281 $this->base_table_properties['FONT-KERNING'] = $properties['FONT-KERNING'];
17282 }
17283 if (isset($properties['LETTER-SPACING'])) {
17284 $this->base_table_properties['LETTER-SPACING'] = $properties['LETTER-SPACING'];
17285 }
17286 if (isset($properties['WORD-SPACING'])) {
17287 $this->base_table_properties['WORD-SPACING'] = $properties['WORD-SPACING'];
17288 }
17289
17290 if (isset($properties['PADDING-LEFT'])) {
17291 $table['padding']['L'] = $this->ConvertSize($properties['PADDING-LEFT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
17292 }
17293 if (isset($properties['PADDING-RIGHT'])) {
17294 $table['padding']['R'] = $this->ConvertSize($properties['PADDING-RIGHT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
17295 }
17296 if (isset($properties['PADDING-TOP'])) {
17297 $table['padding']['T'] = $this->ConvertSize($properties['PADDING-TOP'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
17298 }
17299 if (isset($properties['PADDING-BOTTOM'])) {
17300 $table['padding']['B'] = $this->ConvertSize($properties['PADDING-BOTTOM'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
17301 }
17302
17303 if (isset($properties['MARGIN-TOP'])) {
17304 if ($lastbottommargin) {
17305 $tmp = $this->ConvertSize($properties['MARGIN-TOP'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
17306 if ($tmp > $lastbottommargin) { $properties['MARGIN-TOP'] -= $lastbottommargin; }
17307 else { $properties['MARGIN-TOP'] = 0; }
17308 }
17309 $table['margin']['T'] = $this->ConvertSize($properties['MARGIN-TOP'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
17310 }
17311
17312 if (isset($properties['MARGIN-BOTTOM'])) {
17313 $table['margin']['B'] = $this->ConvertSize($properties['MARGIN-BOTTOM'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
17314 }
17315 if (isset($properties['MARGIN-LEFT'])) {
17316 $table['margin']['L'] = $this->ConvertSize($properties['MARGIN-LEFT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
17317 }
17318
17319 if (isset($properties['MARGIN-RIGHT'])) {
17320 $table['margin']['R'] = $this->ConvertSize($properties['MARGIN-RIGHT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
17321 }
17322 if (isset($properties['MARGIN-LEFT']) && isset($properties['MARGIN-RIGHT']) && strtolower($properties['MARGIN-LEFT'])=='auto' && strtolower($properties['MARGIN-RIGHT'])=='auto') {
17323 $table['a'] = 'C';
17324 }
17325 else if (isset($properties['MARGIN-LEFT']) && strtolower($properties['MARGIN-LEFT'])=='auto') {
17326 $table['a'] = 'R';
17327 }
17328 else if (isset($properties['MARGIN-RIGHT']) && strtolower($properties['MARGIN-RIGHT'])=='auto') {
17329 $table['a'] = 'L';
17330 }
17331
17332 if (isset($properties['LINE-HEIGHT']) && $this->tableLevel==1) {
17333 $this->table_lineheight = $this->fixLineheight($properties['LINE-HEIGHT']);
17334 if (!$this->table_lineheight) { $this->table_lineheight = $this->normalLineheight; }
17335 }
17336
17337 if (isset($properties['BORDER-COLLAPSE']) && strtoupper($properties['BORDER-COLLAPSE'])=='SEPARATE') {
17338 $table['borders_separate'] = true;
17339 }
17340 else {
17341 $table['borders_separate'] = false;
17342 }
17343
17344 if (!$table['borders_separate']) { $table['border_spacing_H'] = $table['border_spacing_V'] = 0; }
17345 else if (isset($attr['CELLSPACING'])) {
17346 $table['border_spacing_H'] = $table['border_spacing_V'] = $this->ConvertSize($attr['CELLSPACING'],$this->blk[$this->blklvl]['inner_width']);
17347 }
17348 if (isset($properties['BORDER-SPACING-H'])) {
17349 $table['border_spacing_H'] = $this->ConvertSize($properties['BORDER-SPACING-H'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
17350 }
17351 if (isset($properties['BORDER-SPACING-V'])) {
17352 $table['border_spacing_V'] = $this->ConvertSize($properties['BORDER-SPACING-V'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
17353 }
17354
17355 if (isset($properties['EMPTY-CELLS'])) {
17356 $table['empty_cells'] = strtolower($properties['EMPTY-CELLS']); // 'hide' or 'show'
17357 }
17358 else { $table['empty_cells'] = ''; }
17359
17360 if (isset($properties['PAGE-BREAK-INSIDE']) && strtoupper($properties['PAGE-BREAK-INSIDE'])=='AVOID' && $this->tableLevel==1 && !$this->writingHTMLfooter) {
17361 $this->table_keep_together = true;
17362 }
17363 else if ($this->tableLevel==1) {
17364 $this->table_keep_together = false;
17365 }
17366 if (isset($properties['PAGE-BREAK-AFTER']) && $this->tableLevel==1) {
17367 $table['page_break_after'] = strtoupper($properties['PAGE-BREAK-AFTER']);
17368 }
17369
17370 /*-- BACKGROUNDS --*/
17371 if (isset($properties['BACKGROUND-GRADIENT']) && !$this->kwt && !$this->ColActive) { $table['gradient'] = $properties['BACKGROUND-GRADIENT']; }
17372
17373 if (isset($properties['BACKGROUND-IMAGE']) && $properties['BACKGROUND-IMAGE'] && !$this->kwt && !$this->ColActive) {
17374 $ret = $this->SetBackground($properties, $currblk['inner_width']);
17375 if ($ret) { $table['background-image'] = $ret; }
17376 }
17377 /*-- END BACKGROUNDS --*/
17378
17379 if (isset($properties['OVERFLOW'])) {
17380 $table['overflow'] = strtolower($properties['OVERFLOW']); // 'hidden' 'wrap' or 'visible' or 'auto'
17381 if (($this->ColActive || $this->tableLevel>1) && $table['overflow']=='visible') { unset($table['overflow']); }
17382 }
17383
17384 $properties = array();
17385
17386
17387
17388 if (isset($attr['CELLPADDING'])) {
17389 $table['cell_padding'] = $attr['CELLPADDING'];
17390 }
17391 else {
17392 $table['cell_padding'] = false;
17393 }
17394
17395 if (isset($attr['BORDER']) && $attr['BORDER']=='1') { // mPDF 5.5.08
17396 $this->table_border_attr_set = 1; // mPDF 5.5.08
17397 $bord = $this->border_details('#000000 1px solid');
17398 if ($bord['s']) {
17399 $table['border'] = _BORDER_ALL;
17400 $table['border_details']['R'] = $bord;
17401 $table['border_details']['L'] = $bord;
17402 $table['border_details']['T'] = $bord;
17403 $table['border_details']['B'] = $bord;
17404 }
17405 }
17406 else {
17407 $this->table_border_attr_set = 0;
17408 }
17409
17410 if ($w) {
17411 $maxwidth = $this->blk[$this->blklvl]['inner_width'];
17412 if ($table['borders_separate']) {
17413 $tblblw = $table['margin']['L'] + $table['margin']['R'] + $table['border_details']['L']['w']/2 + $table['border_details']['R']['w']/2;
17414 }
17415 else {
17416 $tblblw = $table['margin']['L'] + $table['margin']['R'] + $table['max_cell_border_width']['L']/2 + $table['max_cell_border_width']['R']/2;
17417 }
17418 if (strpos($w,'%') && $this->tableLevel == 1 && !$this->ignore_table_percents ) {
17419 // % needs to be of inner box without table margins etc.
17420 $maxwidth -= $tblblw ;
17421 $wmm = $this->ConvertSize($w,$maxwidth,$this->FontSize,false);
17422 $table['w'] = $wmm + $tblblw ;
17423 }
17424 if (strpos($w,'%') && $this->tableLevel > 1 && !$this->ignore_table_percents && $this->keep_table_proportions) {
17425 $table['wpercent'] = $w + 0; // makes 80% -> 80
17426 }
17427 if (!strpos($w,'%') && !$this->ignore_table_widths ) {
17428 $wmm = $this->ConvertSize($w,$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
17429 $table['w'] = $wmm + $tblblw ;
17430 }
17431 if (!$this->keep_table_proportions) {
17432 if (isset($table['w']) && $table['w'] > $this->blk[$this->blklvl]['inner_width']) { $table['w'] = $this->blk[$this->blklvl]['inner_width']; }
17433 }
17434 }
17435
17436 if (isset($attr['AUTOSIZE']) && $this->tableLevel==1) {
17437 $this->shrink_this_table_to_fit = $attr['AUTOSIZE'];
17438 if ($this->shrink_this_table_to_fit < 1) { $this->shrink_this_table_to_fit = 1; }
17439 }
17440 if (isset($attr['ROTATE']) && $this->tableLevel==1) {
17441 $this->table_rotate = $attr['ROTATE'];
17442 }
17443
17444 //++++++++++++++++++++++++++++
17445 // keeping block together on one page
17446 // Autosize is now forced therefore keep block together disabled
17447 if ($this->keep_block_together) {
17448 $this->keep_block_together = 0;
17449 $this->printdivbuffer();
17450 $this->blk[$this->blklvl]['keep_block_together'] = 0;
17451 }
17452 if ($this->table_rotate) {
17453 $this->tbrot_Links = array();
17454 $this->tbrot_Annots = array();
17455 $this->tbrotForms = array();
17456 $this->tbrot_Reference = array();
17457 $this->tbrot_BMoutlines = array();
17458 $this->tbrot_toc = array();
17459 }
17460
17461 if ($this->kwt) {
17462 if ($this->table_rotate) { $this->table_keep_together = true; }
17463 $this->kwt = false;
17464 $this->kwt_saved = true;
17465 }
17466
17467 if ($this->tableLevel==1 && $this->useGraphs) {
17468 if (isset($attr['ID']) && $attr['ID']) { $this->currentGraphId = strtoupper($attr['ID']); }
17469 else { $this->currentGraphId = '0'; }
17470 $this->graphs[$this->currentGraphId] = array();
17471 }
17472 //++++++++++++++++++++++++++++
17473 $this->plainCell_properties = array();
17474 unset($table);
17475 break;
17476
17477 case 'THEAD':
17478 $this->lastoptionaltag = $tag; // Save current HTML specified optional endtag
17479 $this->cssmgr->tbCSSlvl++;
17480 $this->tablethead = 1;
17481 $this->tabletfoot = 0;
17482 $properties = $this->cssmgr->MergeCSS('TABLE',$tag,$attr);
17483 if (isset($properties['FONT-WEIGHT'])) {
17484 if (strtoupper($properties['FONT-WEIGHT']) == 'BOLD') { $this->thead_font_weight = 'B'; }
17485 else { $this->thead_font_weight = ''; }
17486 }
17487
17488 if (isset($properties['FONT-STYLE'])) {
17489 if (strtoupper($properties['FONT-STYLE']) == 'ITALIC') { $this->thead_font_style = 'I'; }
17490 else { $this->thead_font_style = ''; }
17491 }
17492 if (isset($properties['FONT-VARIANT'])) {
17493 if (strtoupper($properties['FONT-VARIANT']) == 'SMALL-CAPS') { $this->thead_font_smCaps = 'S'; }
17494 else { $this->thead_font_smCaps = ''; }
17495 }
17496
17497 if (isset($properties['VERTICAL-ALIGN'])) {
17498 $this->thead_valign_default = $properties['VERTICAL-ALIGN'];
17499 }
17500 if (isset($properties['TEXT-ALIGN'])) {
17501 $this->thead_textalign_default = $properties['TEXT-ALIGN'];
17502 }
17503 $properties = array();
17504 break;
17505
17506 case 'TFOOT':
17507 $this->lastoptionaltag = $tag; // Save current HTML specified optional endtag
17508 $this->cssmgr->tbCSSlvl++;
17509 $this->tabletfoot = 1;
17510 $this->tablethead = 0;
17511 $properties = $this->cssmgr->MergeCSS('TABLE',$tag,$attr);
17512 if (isset($properties['FONT-WEIGHT'])) {
17513 if (strtoupper($properties['FONT-WEIGHT']) == 'BOLD') { $this->tfoot_font_weight = 'B'; }
17514 else { $this->tfoot_font_weight = ''; }
17515 }
17516
17517 if (isset($properties['FONT-STYLE'])) {
17518 if (strtoupper($properties['FONT-STYLE']) == 'ITALIC') { $this->tfoot_font_style = 'I'; }
17519 else { $this->tfoot_font_style = ''; }
17520 }
17521 if (isset($properties['FONT-VARIANT'])) {
17522 if (strtoupper($properties['FONT-VARIANT']) == 'SMALL-CAPS') { $this->tfoot_font_smCaps = 'S'; }
17523 else { $this->tfoot_font_smCaps = ''; }
17524 }
17525
17526 if (isset($properties['VERTICAL-ALIGN'])) {
17527 $this->tfoot_valign_default = $properties['VERTICAL-ALIGN'];
17528 }
17529 if (isset($properties['TEXT-ALIGN'])) {
17530 $this->tfoot_textalign_default = $properties['TEXT-ALIGN'];
17531 }
17532 $properties = array();
17533 break;
17534
17535
17536 case 'TBODY':
17537 $this->tablethead = 0;
17538 $this->tabletfoot = 0;
17539 $this->lastoptionaltag = $tag; // Save current HTML specified optional endtag
17540 $this->cssmgr->tbCSSlvl++;
17541 $this->cssmgr->MergeCSS('TABLE',$tag,$attr);
17542 break;
17543
17544
17545 case 'TR':
17546 $this->lastoptionaltag = $tag; // Save current HTML specified optional endtag
17547 $this->cssmgr->tbCSSlvl++;
17548 $this->row++;
17549 $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['nr']++;
17550 $this->col = -1;
17551 $properties = $this->cssmgr->MergeCSS('TABLE',$tag,$attr);
17552
17553 if (!$this->simpleTables && (!isset($this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['borders_separate']) || !$this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['borders_separate'])) {
17554 if (isset($properties['BORDER-LEFT']) && $properties['BORDER-LEFT']) { $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['trborder-left'][$this->row] = $properties['BORDER-LEFT']; }
17555 if (isset($properties['BORDER-RIGHT']) && $properties['BORDER-RIGHT']) { $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['trborder-right'][$this->row] = $properties['BORDER-RIGHT']; }
17556 if (isset($properties['BORDER-TOP']) && $properties['BORDER-TOP']) { $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['trborder-top'][$this->row] = $properties['BORDER-TOP']; }
17557 if (isset($properties['BORDER-BOTTOM']) && $properties['BORDER-BOTTOM']) { $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['trborder-bottom'][$this->row] = $properties['BORDER-BOTTOM']; }
17558 }
17559
17560 if (isset($properties['BACKGROUND-COLOR'])) { $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['bgcolor'][$this->row] = $properties['BACKGROUND-COLOR']; }
17561 else if (isset($attr['BGCOLOR'])) $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['bgcolor'][$this->row] = $attr['BGCOLOR'];
17562
17563 /*-- BACKGROUNDS --*/
17564 if (isset($properties['BACKGROUND-GRADIENT']) && !$this->kwt && !$this->ColActive) { $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['trgradients'][$this->row] = $properties['BACKGROUND-GRADIENT']; }
17565
17566 if (isset($properties['BACKGROUND-IMAGE']) && $properties['BACKGROUND-IMAGE'] && !$this->kwt && !$this->ColActive) {
17567 $ret = $this->SetBackground($properties, $currblk['inner_width']);
17568 if ($ret) { $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['trbackground-images'][$this->row] = $ret; }
17569 }
17570 /*-- END BACKGROUNDS --*/
17571
17572
17573 if (isset($properties['TEXT-ROTATE'])) {
17574 $this->trow_text_rotate = $properties['TEXT-ROTATE'];
17575 }
17576 if (isset($attr['TEXT-ROTATE'])) $this->trow_text_rotate = $attr['TEXT-ROTATE'];
17577
17578 if ($this->tablethead) { $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['is_thead'][$this->row] = true; }
17579 if ($this->tabletfoot) { $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['is_tfoot'][$this->row] = true; }
17580 $properties = array();
17581 break;
17582
17583
17584 case 'TH':
17585 case 'TD':
17586 $this->ignorefollowingspaces = true;
17587 $this->lastoptionaltag = $tag; // Save current HTML specified optional endtag
17588 $this->cssmgr->tbCSSlvl++;
17589 $this->InlineProperties = array();
17590 $this->spanlvl = 0;
17591 $this->tdbegin = true;
17592 $this->col++;
17593 while (isset($this->cell[$this->row][$this->col])) { $this->col++; }
17594
17595 //Update number column
17596 if ($this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['nc'] < $this->col+1) { $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['nc'] = $this->col+1; }
17597
17598 $table = &$this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]];
17599
17600 $c = array('a' => false,
17601 'R' => false,
17602 'nowrap' => false,
17603 'bgcolor' => false,
17604 'padding' => array('L' => false,
17605 'R' => false,
17606 'T' => false,
17607 'B' => false
17608 )
17609 );
17610
17611 if ($this->simpleTables && $this->row==0 && $this->col==0){
17612 $table['simple']['border'] = false;
17613 $table['simple']['border_details']['R']['w'] = 0;
17614 $table['simple']['border_details']['L']['w'] = 0;
17615 $table['simple']['border_details']['T']['w'] = 0;
17616 $table['simple']['border_details']['B']['w'] = 0;
17617 $table['simple']['border_details']['R']['style'] = '';
17618 $table['simple']['border_details']['L']['style'] = '';
17619 $table['simple']['border_details']['T']['style'] = '';
17620 $table['simple']['border_details']['B']['style'] = '';
17621 }
17622 else if (!$this->simpleTables) {
17623 $c['border'] = false;
17624 $c['border_details']['R']['w'] = 0;
17625 $c['border_details']['L']['w'] = 0;
17626 $c['border_details']['T']['w'] = 0;
17627 $c['border_details']['B']['w'] = 0;
17628 $c['border_details']['mbw']['BL'] = 0;
17629 $c['border_details']['mbw']['BR'] = 0;
17630 $c['border_details']['mbw']['RT'] = 0;
17631 $c['border_details']['mbw']['RB'] = 0;
17632 $c['border_details']['mbw']['TL'] = 0;
17633 $c['border_details']['mbw']['TR'] = 0;
17634 $c['border_details']['mbw']['LT'] = 0;
17635 $c['border_details']['mbw']['LB'] = 0;
17636 $c['border_details']['R']['style'] = '';
17637 $c['border_details']['L']['style'] = '';
17638 $c['border_details']['T']['style'] = '';
17639 $c['border_details']['B']['style'] = '';
17640 $c['border_details']['R']['s'] = 0;
17641 $c['border_details']['L']['s'] = 0;
17642 $c['border_details']['T']['s'] = 0;
17643 $c['border_details']['B']['s'] = 0;
17644 $c['border_details']['R']['c'] = $this->ConvertColor(0);
17645 $c['border_details']['L']['c'] = $this->ConvertColor(0);
17646 $c['border_details']['T']['c'] = $this->ConvertColor(0);
17647 $c['border_details']['B']['c'] = $this->ConvertColor(0);
17648 $c['border_details']['R']['dom'] = 0;
17649 $c['border_details']['L']['dom'] = 0;
17650 $c['border_details']['T']['dom'] = 0;
17651 $c['border_details']['B']['dom'] = 0;
17652 }
17653
17654
17655 if ($table['va']) { $c['va'] = $table['va']; }
17656 if ($table['txta']) { $c['a'] = $table['txta']; }
17657 if ($this->table_border_attr_set) {
17658 if ($table['border_details']) {
17659 if (!$this->simpleTables){
17660 $c['border_details']['R'] = $table['border_details']['R'];
17661 $c['border_details']['L'] = $table['border_details']['L'];
17662 $c['border_details']['T'] = $table['border_details']['T'];
17663 $c['border_details']['B'] = $table['border_details']['B'];
17664 $c['border'] = $table['border'];
17665 $c['border_details']['L']['dom'] = 1;
17666 $c['border_details']['R']['dom'] = 1;
17667 $c['border_details']['T']['dom'] = 1;
17668 $c['border_details']['B']['dom'] = 1;
17669 }
17670 else if ($this->simpleTables && $this->row==0 && $this->col==0){
17671 $table['simple']['border_details']['R'] = $table['border_details']['R'];
17672 $table['simple']['border_details']['L'] = $table['border_details']['L'];
17673 $table['simple']['border_details']['T'] = $table['border_details']['T'];
17674 $table['simple']['border_details']['B'] = $table['border_details']['B'];
17675 $table['simple']['border'] = $table['border'];
17676 }
17677 }
17678 }
17679 // INHERITED THEAD CSS Properties
17680 if ($this->tablethead) {
17681 if ($this->thead_valign_default) $c['va'] = $align[strtolower($this->thead_valign_default)];
17682 if ($this->thead_textalign_default) $c['a'] = $align[strtolower($this->thead_textalign_default)];
17683 if ($this->thead_font_weight == 'B') { $this->SetStyle('B',true); }
17684 if ($this->thead_font_style == 'I') { $this->SetStyle('I',true); }
17685 if ($this->thead_font_smCaps == 'S') { $this->SetStyle('S',true); }
17686 }
17687
17688 // INHERITED TFOOT CSS Properties
17689 if ($this->tabletfoot) {
17690 if ($this->tfoot_valign_default) $c['va'] = $align[strtolower($this->tfoot_valign_default)];
17691 if ($this->tfoot_textalign_default) $c['a'] = $align[strtolower($this->tfoot_textalign_default)];
17692 if ($this->tfoot_font_weight == 'B') { $this->SetStyle('B',true); }
17693 if ($this->tfoot_font_style == 'I') { $this->SetStyle('I',true); }
17694 if ($this->tfoot_font_style == 'S') { $this->SetStyle('S',true); }
17695 }
17696
17697
17698 if ($this->trow_text_rotate){
17699 $c['R'] = $this->trow_text_rotate;
17700 }
17701
17702 $this->cell_border_dominance_L = 0;
17703 $this->cell_border_dominance_R = 0;
17704 $this->cell_border_dominance_T = 0;
17705 $this->cell_border_dominance_B = 0;
17706
17707 $properties = $this->cssmgr->MergeCSS('TABLE',$tag,$attr);
17708 $properties = $this->cssmgr->array_merge_recursive_unique($this->base_table_properties, $properties);
17709
17710 if (isset($properties['FONT-KERNING']) && (strtoupper($properties['FONT-KERNING'])=='NORMAL' || strtoupper($properties['FONT-KERNING'])=='AUTO')) {
17711 $this->kerning = true;
17712 }
17713 else { $this->kerning = false; }
17714
17715 if (isset($properties['LETTER-SPACING']) && ($properties['LETTER-SPACING'] || $properties['LETTER-SPACING']==='0') && strtoupper($properties['LETTER-SPACING']) != 'NORMAL') {
17716 $this->lSpacingCSS = strtoupper($properties['LETTER-SPACING']);
17717 $this->fixedlSpacing = $this->ConvertSize($this->lSpacingCSS,$this->FontSize);
17718 }
17719 else {
17720 $this->lSpacingCSS = '';
17721 $this->fixedlSpacing = false;
17722 }
17723 if (isset($properties['WORD-SPACING']) && strtoupper($properties['WORD-SPACING']) != 'NORMAL') {
17724 $this->wSpacingCSS = strtoupper($properties['WORD-SPACING']);
17725 $this->minwSpacing = $this->ConvertSize($this->wSpacingCSS,$this->FontSize);
17726 }
17727 else {
17728 $this->minwSpacing = 0;
17729 $this->wSpacingCSS = '';
17730 }
17731 // mPDF 5.6.08
17732 if (isset($properties['HYPHENS']) && $properties['HYPHENS']) {
17733 if (strtoupper($properties['HYPHENS']) == 'NONE') { $this->textparam['hyphens'] = 2; }
17734 else if (strtoupper($properties['HYPHENS']) == 'AUTO') { $this->textparam['hyphens'] = 1; }
17735 else if (strtoupper($properties['HYPHENS']) == 'MANUAL') { $this->textparam['hyphens'] = 0; }
17736 }
17737
17738 if (isset($properties['BACKGROUND-COLOR'])) { $c['bgcolor'] = $properties['BACKGROUND-COLOR']; }
17739 else if (isset($properties['BACKGROUND'])) { $c['bgcolor'] = $properties['BACKGROUND']; }
17740 else if (isset($attr['BGCOLOR'])) $c['bgcolor'] = $attr['BGCOLOR'];
17741
17742
17743
17744 /*-- BACKGROUNDS --*/
17745 if (isset($properties['BACKGROUND-GRADIENT'])) { $c['gradient'] = $properties['BACKGROUND-GRADIENT']; }
17746 else { $c['gradient'] = false; }
17747
17748 if (isset($properties['BACKGROUND-IMAGE']) && $properties['BACKGROUND-IMAGE'] && !$this->keep_block_together) {
17749 $ret = $this->SetBackground($properties, $this->blk[$this->blklvl]['inner_width']);
17750 if ($ret) { $c['background-image'] = $ret; }
17751 }
17752 /*-- END BACKGROUNDS --*/
17753 if (isset($properties['VERTICAL-ALIGN'])) { $c['va']=$align[strtolower($properties['VERTICAL-ALIGN'])]; }
17754 else if (isset($attr['VALIGN'])) $c['va'] = $align[strtolower($attr['VALIGN'])];
17755
17756
17757 // mPDF 5.6.13
17758 if (isset($properties['TEXT-ALIGN']) && $properties['TEXT-ALIGN']) {
17759 if (substr($properties['TEXT-ALIGN'],0,1)=='D') { $c['a'] = $properties['TEXT-ALIGN']; }
17760 else { $c['a'] = $align[strtolower($properties['TEXT-ALIGN'])]; }
17761 }
17762 // mPDF 5.6.13
17763 if (isset($attr['ALIGN']) && $attr['ALIGN']) {
17764 if (strtolower($attr['ALIGN']) == 'char') {
17765 if (isset($attr['CHAR']) && $attr['CHAR']) {
17766 $char = html_entity_decode($attr['CHAR']);
17767 $char = strcode2utf($char);
17768 $d = array_search($char,$this->decimal_align);
17769 if ($d !== false) { $c['a'] = $d.'R'; }
17770 }
17771 else { $c['a'] = 'DPR'; }
17772 }
17773 else { $c['a'] = $align[strtolower($attr['ALIGN'])]; }
17774 }
17775
17776 if (!$c['a']) {
17777 if (isset($table['direction']) && $table['direction'] == 'rtl' ) { $c['a'] = 'R'; }
17778 else { $c['a'] = 'L'; }
17779 }
17780
17781
17782 if (isset($properties['TEXT-ROTATE']) && ($properties['TEXT-ROTATE'] || $properties['TEXT-ROTATE']==="0")){
17783 $c['R'] = $properties['TEXT-ROTATE'];
17784 }
17785 if (isset($properties['BORDER'])) {
17786 $bord = $this->border_details($properties['BORDER']);
17787 if ($bord['s']) {
17788 if (!$this->simpleTables){
17789 $c['border'] = _BORDER_ALL;
17790 $c['border_details']['R'] = $bord;
17791 $c['border_details']['L'] = $bord;
17792 $c['border_details']['T'] = $bord;
17793 $c['border_details']['B'] = $bord;
17794 $c['border_details']['L']['dom'] = $this->cell_border_dominance_L;
17795 $c['border_details']['R']['dom'] = $this->cell_border_dominance_R;
17796 $c['border_details']['T']['dom'] = $this->cell_border_dominance_T;
17797 $c['border_details']['B']['dom'] = $this->cell_border_dominance_B;
17798 }
17799 else if ($this->simpleTables && $this->row==0 && $this->col==0){
17800 $table['simple']['border'] = _BORDER_ALL;
17801 $table['simple']['border_details']['R'] = $bord;
17802 $table['simple']['border_details']['L'] = $bord;
17803 $table['simple']['border_details']['T'] = $bord;
17804 $table['simple']['border_details']['B'] = $bord;
17805 }
17806 }
17807 }
17808 if (!$this->simpleTables){
17809 if (isset($properties['BORDER-RIGHT']) && $properties['BORDER-RIGHT']) {
17810 $c['border_details']['R'] = $this->border_details($properties['BORDER-RIGHT']);
17811 $this->setBorder($c['border'], _BORDER_RIGHT, $c['border_details']['R']['s']);
17812 $c['border_details']['R']['dom'] = $this->cell_border_dominance_R;
17813 }
17814 if (isset($properties['BORDER-LEFT']) && $properties['BORDER-LEFT']) {
17815 $c['border_details']['L'] = $this->border_details($properties['BORDER-LEFT']);
17816 $this->setBorder($c['border'], _BORDER_LEFT, $c['border_details']['L']['s']);
17817 $c['border_details']['L']['dom'] = $this->cell_border_dominance_L;
17818 }
17819 if (isset($properties['BORDER-BOTTOM']) && $properties['BORDER-BOTTOM']) {
17820 $c['border_details']['B'] = $this->border_details($properties['BORDER-BOTTOM']);
17821 $this->setBorder($c['border'], _BORDER_BOTTOM, $c['border_details']['B']['s']);
17822 $c['border_details']['B']['dom'] = $this->cell_border_dominance_B;
17823 }
17824 if (isset($properties['BORDER-TOP']) && $properties['BORDER-TOP']) {
17825 $c['border_details']['T'] = $this->border_details($properties['BORDER-TOP']);
17826 $this->setBorder($c['border'], _BORDER_TOP, $c['border_details']['T']['s']);
17827 $c['border_details']['T']['dom'] = $this->cell_border_dominance_T;
17828 }
17829 }
17830 else if ($this->simpleTables && $this->row==0 && $this->col==0){
17831 if (isset($properties['BORDER-LEFT']) && $properties['BORDER-LEFT']) {
17832 $bord = $this->border_details($properties['BORDER-LEFT']);
17833 if ($bord['s']) { $table['simple']['border'] = _BORDER_ALL; }
17834 else { $table['simple']['border'] = 0; }
17835 $table['simple']['border_details']['R'] = $bord;
17836 $table['simple']['border_details']['L'] = $bord;
17837 $table['simple']['border_details']['T'] = $bord;
17838 $table['simple']['border_details']['B'] = $bord;
17839 }
17840 }
17841
17842 if ($this->simpleTables && $this->row==0 && $this->col==0 && !$table['borders_separate'] && $table['simple']['border'] ){
17843 $table['border_details'] = $table['simple']['border_details'];
17844 $table['border'] = $table['simple']['border'];
17845 }
17846
17847 // Border set on TR (if collapsed only)
17848 if (!$table['borders_separate'] && !$this->simpleTables && isset($table['trborder-left'][$this->row])) {
17849 if ($this->col==0) {
17850 $left = $this->border_details($table['trborder-left'][$this->row]);
17851 $c['border_details']['L'] = $left;
17852 $this->setBorder($c['border'], _BORDER_LEFT, $c['border_details']['L']['s']);
17853 }
17854 $c['border_details']['B'] = $this->border_details($table['trborder-bottom'][$this->row]);
17855 $this->setBorder($c['border'], _BORDER_BOTTOM, $c['border_details']['B']['s']);
17856 $c['border_details']['T'] = $this->border_details($table['trborder-top'][$this->row]);
17857 $this->setBorder($c['border'], _BORDER_TOP, $c['border_details']['T']['s']);
17858 }
17859
17860 if ($this->packTableData && !$this->simpleTables) {
17861 $c['borderbin'] = $this->_packCellBorder($c);
17862 unset($c['border']);
17863 unset($c['border_details']);
17864 }
17865
17866 if (isset($properties['PADDING-LEFT'])) {
17867 $c['padding']['L'] = $this->ConvertSize($properties['PADDING-LEFT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
17868 }
17869 if (isset($properties['PADDING-RIGHT'])) {
17870 $c['padding']['R'] = $this->ConvertSize($properties['PADDING-RIGHT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
17871 }
17872 if (isset($properties['PADDING-BOTTOM'])) {
17873 $c['padding']['B'] = $this->ConvertSize($properties['PADDING-BOTTOM'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
17874 }
17875 if (isset($properties['PADDING-TOP'])) {
17876 $c['padding']['T'] = $this->ConvertSize($properties['PADDING-TOP'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
17877 }
17878
17879 $w = '';
17880 if (isset($properties['WIDTH'])) { $w = $properties['WIDTH']; }
17881 else if (isset($attr['WIDTH'])) { $w = $attr['WIDTH']; }
17882 if ($w) {
17883 if (strpos($w,'%') && !$this->ignore_table_percents ) { $c['wpercent'] = $w + 0; } // makes 80% -> 80
17884 else if (!strpos($w,'%') && !$this->ignore_table_widths ) { $c['w'] = $this->ConvertSize($w,$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
17885 }
17886
17887 if (isset($properties['HEIGHT']) && !strpos($properties['HEIGHT'],'%')) { $c['h'] = $this->ConvertSize($properties['HEIGHT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
17888 else if (isset($attr['HEIGHT']) && !strpos($attr['HEIGHT'],'%')) $c['h'] = $this->ConvertSize($attr['HEIGHT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
17889
17890
17891 if (isset($properties['COLOR'])) {
17892 $cor = $this->ConvertColor($properties['COLOR']);
17893 if ($cor) {
17894 $this->colorarray = $cor;
17895 $this->SetTColor($cor);
17896 }
17897 }
17898 if (isset($properties['FONT-FAMILY'])) {
17899 $this->SetFont($properties['FONT-FAMILY'],'',0,false);
17900 }
17901 if (isset($properties['FONT-SIZE'])) {
17902 $mmsize = $this->ConvertSize($properties['FONT-SIZE'],$this->default_font_size/_MPDFK);
17903 if ($mmsize) {
17904 $this->SetFontSize($mmsize*(_MPDFK),false);
17905 }
17906 }
17907 $c['dfs'] = $this->FontSize; // Default Font size
17908 if (isset($properties['FONT-WEIGHT'])) {
17909 if (strtoupper($properties['FONT-WEIGHT']) == 'BOLD') { $this->SetStyle('B',true); }
17910 }
17911 if (isset($properties['FONT-STYLE'])) {
17912 if (strtoupper($properties['FONT-STYLE']) == 'ITALIC') { $this->SetStyle('I',true); }
17913 }
17914 if (isset($properties['FONT-VARIANT'])) {
17915 if (strtoupper($properties['FONT-VARIANT']) == 'SMALL-CAPS') { $this->SetStyle('S',true); }
17916 }
17917 if (isset($properties['TEXT-DECORATION'])) {
17918 if (strtoupper($properties['TEXT-DECORATION']) == 'LINE-THROUGH') { $this->strike = true; }
17919 else if (strtoupper($properties['TEXT-DECORATION']) == 'UNDERLINE') { $this->SetStyle('U',true); }
17920 }
17921 if (isset($properties['TEXT-SHADOW'])) {
17922 $ts = $this->cssmgr->setCSStextshadow($properties['TEXT-SHADOW']);
17923 if ($ts) { $this->textshadow = $ts; }
17924 }
17925 if (isset($properties['TEXT-TRANSFORM'])) {
17926 if (strtoupper($properties['TEXT-TRANSFORM']) == 'CAPITALIZE') { $this->capitalize = true; }
17927 else if (strtoupper($properties['TEXT-TRANSFORM']) == 'UPPERCASE') { $this->toupper = true; }
17928 else if (strtoupper($properties['TEXT-TRANSFORM']) == 'LOWERCASE') { $this->tolower = true; }
17929 }
17930 if (isset($properties['WHITE-SPACE'])) {
17931 if (strtoupper($properties['WHITE-SPACE']) == 'NOWRAP') { $c['nowrap']= 1; }
17932 }
17933 $properties = array();
17934
17935 if (isset($attr['TEXT-ROTATE'])) {
17936 $c['R'] = $attr['TEXT-ROTATE'];
17937 }
17938 if (isset($attr['NOWRAP']) && $attr['NOWRAP']) $c['nowrap']= 1;
17939
17940 $this->cell[$this->row][$this->col] = $c;
17941 unset($c);
17942 $this->cell[$this->row][$this->col]['s'] = 0 ;
17943
17944 $cs = $rs = 1;
17945 if (isset($attr['COLSPAN']) && $attr['COLSPAN']>1) $cs = $this->cell[$this->row][$this->col]['colspan'] = $attr['COLSPAN'];
17946 if ($this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['nc'] < $this->col+$cs) {
17947 $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['nc'] = $this->col+$cs;
17948 } // following code moved outside if...
17949 for($l=$this->col; $l < $this->col+$cs ;$l++) {
17950 if ($l-$this->col) $this->cell[$this->row][$l] = 0;
17951 }
17952 if (isset($attr['ROWSPAN']) && $attr['ROWSPAN']>1) $rs = $this->cell[$this->row][$this->col]['rowspan'] = $attr['ROWSPAN'];
17953 for ($k=$this->row ; $k < $this->row+$rs ;$k++) {
17954 for($l=$this->col; $l < $this->col+$cs ;$l++) {
17955 if ($k-$this->row || $l-$this->col) $this->cell[$k][$l] = 0;
17956 }
17957 }
17958 unset($table);
17959 break;
17960 /*-- END TABLES --*/
17961
17962
17963 /*-- LISTS --*/
17964 // *********** LISTS ********************
17965 case 'OL':
17966 case 'UL':
17967 $this->listjustfinished = false;
17968
17969 if ($this->blockjustfinished && !count($this->textbuffer) && $this->y != $this->tMargin && $this->collapseBlockMargins) { $lastbottommargin = $this->lastblockbottommargin; }
17970 else { $lastbottommargin = 0; }
17971 $this->lastblockbottommargin = 0;
17972 $this->blockjustfinished=false;
17973
17974 $this->linebreakjustfinished=false;
17975 $this->lastoptionaltag = ''; // Save current HTML specified optional endtag
17976 $this->cssmgr->listCSSlvl++;
17977 if((!$this->tableLevel) && ($this->listlvl == 0)) {
17978 $blockstate = 0;
17979 //if ($this->lastblocklevelchange == 1) { $blockstate = -1; } // Top margins/padding only
17980 //else if ($this->lastblocklevelchange < 1) { $blockstate = 0; } // NO margins/padding
17981 // called from block after new div e.g. <div> ... <ol> ... Outputs block top margin/border and padding
17982 if (count($this->textbuffer) == 0 && $this->lastblocklevelchange == 1 && !$this->tableLevel && !$this->kwt) {
17983 $this->newFlowingBlock( $this->blk[$this->blklvl]['width'],$this->lineheight,'',false,false,1,true, $this->blk[$this->blklvl]['direction']);
17984 $this->finishFlowingBlock(true); // true = END of flowing block
17985 }
17986 else if (count($this->textbuffer)) { $this->printbuffer($this->textbuffer,$blockstate); }
17987 $this->textbuffer=array();
17988 $this->lastblocklevelchange = -1;
17989 }
17990 // ol and ul types are mixed here
17991 if ($this->listlvl == 0) {
17992 $this->list_indent = array();
17993 $this->list_align = array();
17994 $this->list_lineheight = array();
17995 $this->InlineProperties['LIST'] = array();
17996 $this->InlineProperties['LISTITEM'] = array();
17997 }
17998
17999 /*-- TABLES --*/
18000 // A simple list for inside a table
18001 if($this->tableLevel) {
18002 $this->list_indent[$this->listlvl] = 0; // mm default indent for each level
18003 if ($tag == 'OL') $this->listtype = '1';
18004 else if ($tag == 'UL') $this->listtype = 'disc';
18005 if ($this->listlvl > 0) {
18006 $this->listlist[$this->listlvl]['MAXNUM'] = $this->listnum; //save previous lvl's maxnum
18007 }
18008 $this->listlvl++;
18009 // mPDF 5.6.15
18010 if (isset($attr['START'])) { $this->listnum = intval($attr['START']); }
18011 else { $this->listnum = 0; }
18012 $this->listlist[$this->listlvl] = array('TYPE'=>$this->listtype,'MAXNUM'=>$this->listnum);
18013 break;
18014 }
18015 /*-- END TABLES --*/
18016
18017
18018 if (($this->PDFA || $this->PDFX) && $tag == 'UL') {
18019 if (($this->PDFA && !$this->PDFAauto) || ($this->PDFX && !$this->PDFXauto)) { $this->PDFAXwarnings[] = "List bullets cannot use core font Zapfdingbats in PDFA1-b or PDFX/1-a. (Substitute characters from current font used if available, otherwise substitutes hyphen '-')"; }
18020 }
18021
18022 if ($this->cssmgr->listCSSlvl==1) {
18023 $properties = $this->cssmgr->MergeCSS('TOPLIST',$tag,$attr);
18024 }
18025 else {
18026 $properties = $this->cssmgr->MergeCSS('LIST',$tag,$attr);
18027 }
18028 if (!empty($properties)) $this->setCSS($properties,'LIST');
18029 // List-type
18030
18031 $this->listtype = '';
18032 if (isset($properties['LIST-STYLE-TYPE'])) {
18033 $this->listtype = $this->_getListStyle($properties['LIST-STYLE-TYPE']);
18034 }
18035 else if (isset($properties['LIST-STYLE'])) {
18036 $this->listtype = $this->_getListStyle($properties['LIST-STYLE']);
18037 }
18038 else if (isset($attr['TYPE']) && $attr['TYPE']) { $this->listtype = $attr['TYPE']; }
18039 if (!$this->listtype) {
18040 if ($tag == 'OL') $this->listtype = '1';
18041 if ($tag == 'UL') {
18042 if ($this->listlvl % 3 == 0) $this->listtype = 'disc';
18043 elseif ($this->listlvl % 3 == 1) $this->listtype = 'circle';
18044 else $this->listtype = 'square';
18045 }
18046 }
18047 if ($this->listlvl == 0) {
18048 $this->inherit_lineheight = 0;
18049 $this->listlvl++; // first depth level
18050 // mPDF 5.6.15
18051 if (isset($attr['START'])) { $this->listnum = intval($attr['START']); }
18052 else { $this->listnum = 0; }
18053 $this->listDir = (isset($this->blk[$this->blklvl]['direction']) ? $this->blk[$this->blklvl]['direction'] : null);
18054 $occur = $this->listoccur[$this->listlvl] = 1;
18055 $this->listlist[$this->listlvl][1] = array('TYPE'=>$this->listtype,'MAXNUM'=>$this->listnum);
18056 }
18057 else {
18058 if (!empty($this->textbuffer))
18059 {
18060 $this->listitem[] = array($this->listlvl,$this->listnum,$this->textbuffer,$this->listoccur[$this->listlvl],$this->listitemtype);
18061 $this->listnum++;
18062 }
18063 // Save current lineheight to inherit
18064 $this->textbuffer = array();
18065 $occur = $this->listoccur[$this->listlvl];
18066 $this->listlist[$this->listlvl][$occur]['MAXNUM'] = $this->listnum; //save previous lvl's maxnum
18067 $this->listlvl++;
18068 // mPDF 5.6.15
18069 if (isset($attr['START'])) { $this->listnum = intval($attr['START']); }
18070 else { $this->listnum = 0; }
18071
18072
18073 if (!isset($this->listoccur[$this->listlvl]) || $this->listoccur[$this->listlvl] == 0) $this->listoccur[$this->listlvl] = 1;
18074 else $this->listoccur[$this->listlvl]++;
18075 $occur = $this->listoccur[$this->listlvl];
18076 $this->listlist[$this->listlvl][$occur] = array('TYPE'=>$this->listtype,'MAXNUM'=>$this->listnum);
18077 }
18078
18079
18080 // TOP LEVEL ONLY
18081 if ($this->listlvl == 1) {
18082 if (isset($properties['MARGIN-TOP'])) {
18083 if ($lastbottommargin) {
18084 $tmp = $this->ConvertSize($properties['MARGIN-TOP'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
18085 if ($tmp > $lastbottommargin) { $properties['MARGIN-TOP'] -= $lastbottommargin; }
18086 else { $properties['MARGIN-TOP'] = 0; }
18087 }
18088 $this->DivLn($this->ConvertSize($properties['MARGIN-TOP'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false),$this->blklvl,true,1); // collapsible
18089 }
18090 if (isset($properties['MARGIN-BOTTOM'])) {
18091 $this->list_margin_bottom = $this->ConvertSize($properties['MARGIN-BOTTOM'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
18092 }
18093
18094 if (isset($this->blk[$this->blklvl]['line_height'])) {
18095 $this->list_lineheight[$this->listlvl][$occur] = $this->blk[$this->blklvl]['line_height'];
18096 }
18097
18098 if (isset($properties['DIRECTION']) && $properties['DIRECTION']) { $this->listDir = strtolower($properties['DIRECTION']); }
18099 else if (isset($attr['DIR']) && $attr['DIR']) { $this->listDir = strtolower($attr['DIR']); }
18100
18101 }
18102 $this->list_indent[$this->listlvl][$occur] = 5; // mm default indent for each level
18103 if (isset($properties['TEXT-INDENT'])) { $this->list_indent[$this->listlvl][$occur] = $this->ConvertSize($properties['TEXT-INDENT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
18104
18105 if (isset($properties['TEXT-ALIGN'])) {
18106 $this->list_align[$this->listlvl][$occur] = $align[strtolower($properties['TEXT-ALIGN'])];
18107 }
18108
18109
18110 if (isset($properties['LINE-HEIGHT'])) {
18111 $this->list_lineheight[$this->listlvl][$occur] = $this->fixLineheight($properties['LINE-HEIGHT']);
18112 }
18113 else if ($this->listlvl>1 && isset($this->list_lineheight[($this->listlvl - 1)][1])) {
18114 $this->list_lineheight[$this->listlvl][$occur] = end($this->list_lineheight[($this->listlvl - 1)]);
18115 }
18116 if (!isset($this->list_lineheight[$this->listlvl][$occur]) || !$this->list_lineheight[$this->listlvl][$occur]) {
18117 $this->list_lineheight[$this->listlvl][$occur] = $this->normalLineheight;
18118 }
18119
18120 $this->InlineProperties['LIST'][$this->listlvl][$occur] = $this->saveInlineProperties();
18121 $properties = array();
18122 break;
18123
18124
18125
18126 case 'LI':
18127 // Start Block
18128 $this->lastoptionaltag = $tag; // Save current HTML specified optional endtag
18129 $this->ignorefollowingspaces = true; //Eliminate exceeding left-side spaces
18130 /*-- TABLES --*/
18131 // A simple list for inside a table
18132 if($this->tableLevel) {
18133 $this->blockjustfinished=false;
18134
18135 // If already something in the Cell
18136 if ((isset($this->cell[$this->row][$this->col]['maxs']) && $this->cell[$this->row][$this->col]['maxs'] > 0 ) || $this->cell[$this->row][$this->col]['s'] > 0 ) {
18137 $this->_saveCellTextBuffer("\n");
18138 if (!isset($this->cell[$this->row][$this->col]['maxs'])) {
18139 $this->cell[$this->row][$this->col]['maxs'] = $this->cell[$this->row][$this->col]['s'];
18140 }
18141 elseif($this->cell[$this->row][$this->col]['maxs'] < $this->cell[$this->row][$this->col]['s']) {
18142 $this->cell[$this->row][$this->col]['maxs'] = $this->cell[$this->row][$this->col]['s'];
18143 }
18144 $this->cell[$this->row][$this->col]['s'] = 0 ;
18145 }
18146 if ($this->listlvl == 0) { //in case of malformed HTML code. Example:(...)</p><li>Content</li><p>Paragraph1</p>(...)
18147 $this->listlvl++; // first depth level
18148 $this->listnum = 0; // reset
18149 $this->listlist[$this->listlvl] = array('TYPE'=>'disc','MAXNUM'=>$this->listnum);
18150 }
18151
18152 $this->listnum++;
18153 switch($this->listlist[$this->listlvl]['TYPE']) {
18154 case 'A':
18155 $blt = $this->dec2alpha($this->listnum,true).$this->list_number_suffix;
18156 break;
18157 case 'a':
18158 $blt = $this->dec2alpha($this->listnum,false).$this->list_number_suffix;
18159 break;
18160 case 'I':
18161 $blt = $this->dec2roman($this->listnum,true).$this->list_number_suffix;
18162 break;
18163 case 'i':
18164 $blt = $this->dec2roman($this->listnum,false).$this->list_number_suffix;
18165 break;
18166 case '1':
18167 $blt = $this->listnum.$this->list_number_suffix;
18168 break;
18169 default:
18170 if ($this->listlvl % 3 == 1 && $this->_charDefined($this->CurrentFont['cw'],8226)) { $blt = "\xe2\x80\xa2"; } // &#8226;
18171 else if ($this->listlvl % 3 == 2 && $this->_charDefined($this->CurrentFont['cw'],9900)) { $blt = "\xe2\x9a\xac"; } // &#9900;
18172 else if ($this->listlvl % 3 == 0 && $this->_charDefined($this->CurrentFont['cw'],9642)) { $blt = "\xe2\x96\xaa"; } // &#9642;
18173 else { $blt = '-'; }
18174 break;
18175 }
18176
18177 // change to &nbsp; spaces
18178 if ($this->usingCoreFont) {
18179 $ls = str_repeat(chr(160).chr(160),($this->listlvl-1)*2) . $blt . ' ';
18180 }
18181 else {
18182 $ls = str_repeat("\xc2\xa0\xc2\xa0",($this->listlvl-1)*2) . $blt . ' ';
18183 }
18184
18185 $this->_saveCellTextBuffer($ls, $this->HREF);
18186 $this->cell[$this->row][$this->col]['s'] += $this->GetStringWidth($ls);
18187 break;
18188 }
18189 /*-- END TABLES --*/
18190 //Observation: </LI> is ignored
18191 if ($this->listlvl == 0) { //in case of malformed HTML code. Example:(...)</p><li>Content</li><p>Paragraph1</p>(...)
18192 //First of all, skip a line
18193 $this->listlvl++; // first depth level
18194 $this->listnum = 0; // reset
18195 $this->listoccur[$this->listlvl] = 1;
18196 $this->listlist[$this->listlvl][1] = array('TYPE'=>'disc','MAXNUM'=>$this->listnum);
18197 }
18198 if ($this->listnum == 0) {
18199 $this->listnum++;
18200 $this->textbuffer = array();
18201 }
18202 else {
18203 if (!empty($this->textbuffer)) {
18204 if (!$this->listjustfinished) {
18205 $this->listitem[] = array($this->listlvl,$this->listnum,$this->textbuffer,$this->listoccur[$this->listlvl],$this->listitemtype);
18206 $this->listnum++;
18207 }
18208 else {
18209 $this->listitem[] = array($this->listlvl,$this->listnum,$this->textbuffer,$this->listoccur[$this->listlvl],$this->listitemtype, true);
18210 }
18211 }
18212 $this->textbuffer = array();
18213 }
18214 $this->listjustfinished = false;
18215
18216 $this->cssmgr->listCSSlvl++;
18217 $properties = $this->cssmgr->MergeCSS('LIST',$tag,$attr);
18218 if (!empty($properties)) $this->setCSS($properties,'LIST');
18219 $this->InlineProperties['LISTITEM'][$this->listlvl][$this->listoccur[$this->listlvl]][$this->listnum] = $this->saveInlineProperties();
18220
18221 // List-type
18222 if (isset($properties['LIST-STYLE-TYPE'])) {
18223 $this->listitemtype = $this->_getListStyle($properties['LIST-STYLE-TYPE']);
18224 }
18225 else if (isset($properties['LIST-STYLE'])) {
18226 $this->listitemtype = $this->_getListStyle($properties['LIST-STYLE']);
18227 }
18228 else if (isset($attr['TYPE']) && $attr['TYPE']) { $this->listitemtype = $attr['TYPE']; }
18229 else $this->listitemtype = '';
18230 break;
18231 /*-- END LISTS --*/
18232
18233 }//end of switch
18234 }
18235
18236 /*-- LISTS --*/
18237
18238 function _getListStyle($ls) {
18239 if (stristr($ls,'decimal')) { return '1'; }
18240 /* CSS3 list-styles numeric (selected) + I added tamil
18241 arabic-indic | bengali | devanagari | gujarati | gurmukhi | kannada | malayalam | oriya | persian | telugu | thai | urdu
18242 */
18243 else if (preg_match('/(disc|circle|square|arabic-indic|bengali|devanagari|gujarati|gurmukhi|kannada|malayalam|oriya|persian|tamil|telugu|thai|urdu)/i',$ls,$m)) {
18244 return strtolower(trim($m[1]));
18245 }
18246 else if (stristr($ls,'lower-roman')) { return 'i'; }
18247 else if (stristr($ls,'upper-roman')) { return 'I'; }
18248 else if (stristr($ls,'lower-latin')|| stristr($ls,'lower-alpha')) { return 'a'; }
18249 else if (stristr($ls,'upper-latin') || stristr($ls,'upper-alpha')) { return 'A'; }
18250 else if (stristr($ls,'none')) { return 'none'; }
18251 else if (preg_match('/U\+([a-fA-F0-9]+)/i',$ls)) { return $ls; }
18252 else { return ''; }
18253 }
18254 /*-- END LISTS --*/
18255
18256
18257
18258 function CloseTag($tag)
18259 {
18260 $this->ignorefollowingspaces = false; //Eliminate exceeding left-side spaces
18261 //Closing tag
18262 if($tag=='OPTION') { $this->selectoption['ACTIVE'] = false; $this->lastoptionaltag = ''; }
18263
18264 if($tag=='TTS' or $tag=='TTA' or $tag=='TTZ') {
18265 if ($this->InlineProperties[$tag]) { $this->restoreInlineProperties($this->InlineProperties[$tag]); }
18266 unset($this->InlineProperties[$tag]);
18267 $ltag = strtolower($tag);
18268 $this->$ltag = false;
18269 }
18270
18271
18272 if($tag=='FONT' || $tag=='SPAN' || $tag=='CODE' || $tag=='KBD' || $tag=='SAMP' || $tag=='TT' || $tag=='VAR'
18273 || $tag=='INS' || $tag=='STRONG' || $tag=='CITE' || $tag=='SUB' || $tag=='SUP' || $tag=='S' || $tag=='STRIKE' || $tag=='DEL'
18274 || $tag=='Q' || $tag=='EM' || $tag=='B' || $tag=='I' || $tag=='U' | $tag=='SMALL' || $tag=='BIG' || $tag=='ACRONYM'
18275 || $tag=='MARK' || $tag=='TIME' || $tag=='PROGRESS' || $tag=='METER'
18276 ) { // mPDF 5.5.09
18277
18278 if ($tag == 'SPAN') {
18279 if (isset($this->InlineProperties['SPAN'][$this->spanlvl]) && $this->InlineProperties['SPAN'][$this->spanlvl]) { $this->restoreInlineProperties($this->InlineProperties['SPAN'][$this->spanlvl]); }
18280 unset($this->InlineProperties['SPAN'][$this->spanlvl]);
18281 if (isset($this->InlineAnnots['SPAN'][$this->spanlvl]) && $this->InlineAnnots['SPAN'][$this->spanlvl]) { $annot = $this->InlineAnnots['SPAN'][$this->spanlvl]; } // *ANNOTATIONS*
18282 unset($this->InlineAnnots['SPAN'][$this->spanlvl]); // *ANNOTATIONS*
18283 $this->spanlvl--;
18284 }
18285 else {
18286 if (isset($this->InlineProperties[$tag]) && $this->InlineProperties[$tag]) { $this->restoreInlineProperties($this->InlineProperties[$tag]); }
18287 unset($this->InlineProperties[$tag]);
18288 if (isset($this->InlineAnnots[$tag]) && $this->InlineAnnots[$tag]) { $annot = $this->InlineAnnots[$tag]; } // *ANNOTATIONS*
18289 unset($this->InlineAnnots[$tag]); // *ANNOTATIONS*
18290 }
18291
18292 /*-- ANNOTATIONS --*/
18293 if (isset($annot)) {
18294 if($this->tableLevel) { // *TABLES*
18295 $this->cell[$this->row][$this->col]['textbuffer'][] = array($annot); // *TABLES*
18296 } // *TABLES*
18297 else { // *TABLES*
18298 $this->textbuffer[] = array($annot);
18299 } // *TABLES*
18300 }
18301 /*-- END ANNOTATIONS --*/
18302 }
18303
18304 if($tag=='METER' || $tag=='PROGRESS') {
18305 $this->inMeter = false; // mPDF 5.5.09
18306 }
18307
18308
18309 if($tag=='A') {
18310 $this->HREF='';
18311 if (isset($this->InlineProperties['A'])) { $this->restoreInlineProperties($this->InlineProperties['A']); }
18312 unset($this->InlineProperties['A']);
18313 }
18314
18315 if($tag=='LEGEND') { // mPDF 5.4.18
18316 if (count($this->textbuffer) && !$this->tableLevel) {
18317 $leg = $this->textbuffer[(count($this->textbuffer)-1)];
18318 unset($this->textbuffer[(count($this->textbuffer)-1)]);
18319 $this->textbuffer = array_values($this->textbuffer);
18320 $this->blk[$this->blklvl]['border_legend'] = $leg;
18321 $this->blk[$this->blklvl]['margin_top'] += ($leg[11]/2)/_MPDFK;
18322 $this->blk[$this->blklvl]['padding_top'] += ($leg[11]/2)/_MPDFK;
18323 }
18324 if (isset($this->InlineProperties['LEGEND'])) { $this->restoreInlineProperties($this->InlineProperties['LEGEND']); }
18325 unset($this->InlineProperties['LEGEND']);
18326 $this->ignorefollowingspaces = true; //Eliminate exceeding left-side spaces
18327 }
18328
18329
18330
18331 /*-- FORMS --*/
18332 // *********** FORM ELEMENTS ********************
18333
18334 if($tag=='TEXTAREA') {
18335 $this->specialcontent = '';
18336 if ($this->InlineProperties[$tag]) { $this->restoreInlineProperties($this->InlineProperties[$tag]); }
18337 unset($this->InlineProperties[$tag]);
18338 }
18339
18340
18341 if($tag=='SELECT') {
18342 $this->lastoptionaltag = '';
18343 $texto = '';
18344 if (isset($this->selectoption['SELECTED'])) { $texto = $this->selectoption['SELECTED']; }
18345
18346 if ($this->useActiveForms) { $w = $this->selectoption['MAXWIDTH']; }
18347 else { $w = $this->GetStringWidth($texto); }
18348 if ($w == 0) { $w = 5; }
18349 $objattr['type'] = 'select';
18350 $objattr['text'] = $texto;
18351 if (isset($this->selectoption['NAME'])) { $objattr['fieldname'] = $this->selectoption['NAME']; }
18352 if (isset($this->selectoption['READONLY'])) { $objattr['readonly'] = true; }
18353 if (isset($this->selectoption['REQUIRED'])) { $objattr['required'] = true; }
18354 if (isset($this->selectoption['SPELLCHECK'])) { $objattr['spellcheck'] = true; }
18355 if (isset($this->selectoption['EDITABLE'])) { $objattr['editable'] = true; }
18356 if (isset($this->selectoption['ONCHANGE'])) { $objattr['onChange'] = $this->selectoption['ONCHANGE']; }
18357 if (isset($this->selectoption['ITEMS'])) { $objattr['items'] = $this->selectoption['ITEMS']; }
18358 if (isset($this->selectoption['MULTIPLE'])) { $objattr['multiple'] = $this->selectoption['MULTIPLE']; }
18359 if (isset($this->selectoption['DISABLED'])) { $objattr['disabled'] = $this->selectoption['DISABLED']; }
18360 if (isset($this->selectoption['TITLE'])) { $objattr['title'] = $this->selectoption['TITLE']; }
18361 if (isset($this->selectoption['COLOR'])) { $objattr['color'] = $this->selectoption['COLOR']; }
18362 if (isset($this->selectoption['SIZE'])) { $objattr['size'] = $this->selectoption['SIZE']; }
18363 if (isset($objattr['size']) && $objattr['size']>1) { $rows=$objattr['size']; } else { $rows = 1; }
18364
18365 $objattr['fontfamily'] = $this->FontFamily;
18366 $objattr['fontsize'] = $this->FontSizePt;
18367
18368 $objattr['width'] = $w + ($this->form->form_element_spacing['select']['outer']['h']*2)+($this->form->form_element_spacing['select']['inner']['h']*2) + ($this->FontSize*1.4);
18369 $objattr['height'] = ($this->FontSize*$rows) + ($this->form->form_element_spacing['select']['outer']['v']*2)+($this->form->form_element_spacing['select']['inner']['v']*2);
18370 $e = "\xbb\xa4\xactype=select,objattr=".serialize($objattr)."\xbb\xa4\xac";
18371
18372 // Clear properties - tidy up
18373 $properties = array();
18374
18375 // Output it to buffers
18376 if ($this->tableLevel) { // *TABLES*
18377 $this->_saveCellTextBuffer($e, $this->HREF);
18378 $this->cell[$this->row][$this->col]['s'] += $objattr['width'] ; // *TABLES*
18379 } // *TABLES*
18380 else { // *TABLES*
18381 $this->_saveTextBuffer($e, $this->HREF);
18382 } // *TABLES*
18383
18384 $this->selectoption = array();
18385 $this->specialcontent = '';
18386
18387 if ($this->InlineProperties[$tag]) { $this->restoreInlineProperties($this->InlineProperties[$tag]); }
18388 unset($this->InlineProperties[$tag]);
18389
18390 }
18391 /*-- END FORMS --*/
18392
18393
18394 // *********** BLOCKS ********************
18395 // mPDF 5.4.18
18396 if($tag=='P' || $tag=='DIV' || $tag=='H1' || $tag=='H2' || $tag=='H3' || $tag=='H4' || $tag=='H5' || $tag=='H6' || $tag=='PRE'
18397 || $tag=='FORM' || $tag=='ADDRESS' || $tag=='BLOCKQUOTE' || $tag=='CENTER' || $tag=='DT' || $tag=='DD' || $tag=='DL'
18398 || $tag=='CAPTION' || $tag=='FIELDSET'
18399 || $tag=='ARTICLE' || $tag=='ASIDE' || $tag=='FIGURE' || $tag=='FIGCAPTION' || $tag=='FOOTER' || $tag=='HEADER' || $tag=='HGROUP'
18400 || $tag=='NAV' || $tag=='SECTION' || $tag=='DETAILS' || $tag=='SUMMARY'
18401 ) { // mPDF 5.5.09 // mPDF 5.5.22
18402
18403 $this->ignorefollowingspaces = true; //Eliminate exceeding left-side spaces
18404 $this->blockjustfinished=true;
18405
18406 $this->lastblockbottommargin = $this->blk[$this->blklvl]['margin_bottom'];
18407 /*-- LISTS --*/
18408 if ($this->listlvl>0) { return; }
18409 /*-- END LISTS --*/
18410
18411 // mPDF 5.6.34
18412 if (preg_match('/^H\d/',$tag) && !$this->tableLevel && !$this->writingToC) { // mPDF 5.6.38
18413 if (isset($this->h2toc[$tag]) || isset($this->h2bookmarks[$tag])) {
18414 $content = '';
18415 if (count($this->textbuffer)==1) { $content = $this->textbuffer[0][0]; }
18416 else {
18417 for ($i=0;$i<count($this->textbuffer);$i++) {
18418 if (substr($this->textbuffer[$i][0],0,3) != "\xbb\xa4\xac") { //inline object
18419 $content .= $this->textbuffer[$i][0];
18420 }
18421 }
18422 }
18423 /*-- TOC --*/
18424 if (isset($this->h2toc[$tag])) {
18425 $objattr = array();
18426 $objattr['type'] = 'toc';
18427 $objattr['toclevel'] = $this->h2toc[$tag];
18428 $objattr['CONTENT'] = htmlspecialchars($content); // mPDF 5.6.37
18429 $e = "\xbb\xa4\xactype=toc,objattr=".serialize($objattr)."\xbb\xa4\xac";
18430 array_unshift($this->textbuffer,array($e));
18431 }
18432 /*-- END TOC --*/
18433 /*-- BOOKMARKS --*/
18434 if (isset($this->h2bookmarks[$tag])) {
18435 $objattr = array();
18436 $objattr['type'] = 'bookmark';
18437 $objattr['bklevel'] = $this->h2bookmarks[$tag];
18438 $objattr['CONTENT'] = $content;
18439 $e = "\xbb\xa4\xactype=toc,objattr=".serialize($objattr)."\xbb\xa4\xac";
18440 array_unshift($this->textbuffer,array($e));
18441 }
18442 /*-- END BOOKMARKS --*/
18443 }
18444 }
18445
18446 /*-- TABLES --*/
18447 if($this->tableLevel) {
18448 if ($this->linebreakjustfinished) { $this->blockjustfinished=false; }
18449 if (isset($this->InlineProperties['BLOCKINTABLE'])) {
18450 if ($this->InlineProperties['BLOCKINTABLE']) { $this->restoreInlineProperties($this->InlineProperties['BLOCKINTABLE']); }
18451 unset($this->InlineProperties['BLOCKINTABLE']);
18452 }
18453 if($tag=='PRE') { $this->ispre=false; }
18454 return;
18455 }
18456 /*-- END TABLES --*/
18457 $this->lastoptionaltag = '';
18458 $this->divbegin=false;
18459
18460 $this->linebreakjustfinished=false;
18461
18462 $this->x = $this->lMargin + $this->blk[$this->blklvl]['outer_left_margin'];
18463
18464 /*-- CSS-FLOAT --*/
18465 // If float contained in a float, need to extend bottom to allow for it
18466 $currpos = $this->page*1000 + $this->y;
18467 if (isset($this->blk[$this->blklvl]['float_endpos']) && $this->blk[$this->blklvl]['float_endpos'] > $currpos) {
18468 $old_page = $this->page;
18469 $new_page = intval($this->blk[$this->blklvl]['float_endpos'] /1000);
18470 if ($old_page != $new_page) {
18471 $s = $this->PrintPageBackgrounds();
18472 // Writes after the marker so not overwritten later by page background etc.
18473 $this->pages[$this->page] = preg_replace('/(___BACKGROUND___PATTERNS'.date('jY').')/', '\\1'."\n".$s."\n", $this->pages[$this->page]);
18474 $this->pageBackgrounds = array();
18475 $this->page = $new_page;
18476 $this->ResetMargins();
18477 $this->Reset();
18478 $this->pageoutput[$this->page] = array();
18479 }
18480 $this->y = (($this->blk[$this->blklvl]['float_endpos'] *1000) % 1000000)/1000; // mod changes operands to integers before processing
18481 }
18482 /*-- END CSS-FLOAT --*/
18483
18484
18485 //Print content
18486 if ($this->lastblocklevelchange == 1) { $blockstate = 3; } // Top & bottom margins/padding
18487 else if ($this->lastblocklevelchange == -1) { $blockstate = 2; } // Bottom margins/padding only
18488 else { $blockstate = 0; }
18489 // called from after e.g. </table> </div> </div> ... Outputs block margin/border and padding
18490 if (count($this->textbuffer) && $this->textbuffer[count($this->textbuffer)-1]) {
18491 if (substr($this->textbuffer[count($this->textbuffer)-1][0],0,3) != "\xbb\xa4\xac") { // not special content
18492 if ($this->usingCoreFont) {
18493 $this->textbuffer[count($this->textbuffer)-1][0] = preg_replace('/[ ]+$/', '', $this->textbuffer[count($this->textbuffer)-1][0]);
18494 }
18495 else {
18496 $this->textbuffer[count($this->textbuffer)-1][0] = preg_replace('/[ ]+$/u', '', $this->textbuffer[count($this->textbuffer)-1][0]); }
18497 }
18498 }
18499
18500 if (count($this->textbuffer) == 0 && $this->lastblocklevelchange != 0) {
18501 //$this->newFlowingBlock( $this->blk[$this->blklvl]['width'],$this->lineheight,'',false,false,2,true, $this->blk[$this->blklvl]['direction']);
18502 $this->newFlowingBlock( $this->blk[$this->blklvl]['width'],$this->lineheight,'',false,false,$blockstate,true, $this->blk[$this->blklvl]['direction']);
18503 $this->finishFlowingBlock(true); // true = END of flowing block
18504 $this->PaintDivBB('',$blockstate);
18505 }
18506 else {
18507 $this->printbuffer($this->textbuffer,$blockstate);
18508 }
18509
18510
18511 $this->textbuffer=array();
18512
18513 if ($this->blk[$this->blklvl]['keep_block_together']) {
18514 $this->printdivbuffer();
18515 }
18516
18517 if ($this->kwt) {
18518 $this->kwt_height = $this->y - $this->kwt_y0;
18519 }
18520
18521 /*-- CSS-IMAGE-FLOAT --*/
18522 $this->printfloatbuffer();
18523 /*-- END CSS-IMAGE-FLOAT --*/
18524
18525 if($tag=='PRE') { $this->ispre=false; }
18526
18527 /*-- CSS-FLOAT --*/
18528 if ($this->blk[$this->blklvl]['float'] == 'R') {
18529 // If width not set, here would need to adjust and output buffer
18530 $s = $this->PrintPageBackgrounds();
18531 // Writes after the marker so not overwritten later by page background etc.
18532 $this->pages[$this->page] = preg_replace('/(___BACKGROUND___PATTERNS'.date('jY').')/', '\\1'."\n".$s."\n", $this->pages[$this->page]);
18533 $this->pageBackgrounds = array();
18534 $this->Reset();
18535 $this->pageoutput[$this->page] = array();
18536
18537 for($i=($this->blklvl-1); $i >= 0; $i--) {
18538 if (isset($this->blk[$i]['float_endpos'])) { $this->blk[$i]['float_endpos'] = max($this->blk[$i]['float_endpos'], ($this->page*1000 + $this->y)); }
18539 else { $this->blk[$i]['float_endpos'] = $this->page*1000 + $this->y; }
18540 }
18541
18542 $this->floatDivs[] = array(
18543 'side'=>'R',
18544 'startpage'=>$this->blk[$this->blklvl]['startpage'] ,
18545 'y0'=>$this->blk[$this->blklvl]['float_start_y'] ,
18546 'startpos'=> ($this->blk[$this->blklvl]['startpage']*1000 + $this->blk[$this->blklvl]['float_start_y']),
18547 'endpage'=>$this->page ,
18548 'y1'=>$this->y ,
18549 'endpos'=> ($this->page*1000 + $this->y),
18550 'w'=> $this->blk[$this->blklvl]['float_width'],
18551 'blklvl'=>$this->blklvl,
18552 'blockContext' => $this->blk[$this->blklvl-1]['blockContext']
18553 );
18554
18555 $this->y = $this->blk[$this->blklvl]['float_start_y'] ;
18556 $this->page = $this->blk[$this->blklvl]['startpage'] ;
18557 $this->ResetMargins();
18558 $this->pageoutput[$this->page] = array();
18559 }
18560 if ($this->blk[$this->blklvl]['float'] == 'L') {
18561 // If width not set, here would need to adjust and output buffer
18562 $s = $this->PrintPageBackgrounds();
18563 // Writes after the marker so not overwritten later by page background etc.
18564 $this->pages[$this->page] = preg_replace('/(___BACKGROUND___PATTERNS'.date('jY').')/', '\\1'."\n".$s."\n", $this->pages[$this->page]);
18565 $this->pageBackgrounds = array();
18566 $this->Reset();
18567 $this->pageoutput[$this->page] = array();
18568
18569 for($i=($this->blklvl-1); $i >= 0; $i--) {
18570 if (isset($this->blk[$i]['float_endpos'])) { $this->blk[$i]['float_endpos'] = max($this->blk[$i]['float_endpos'], ($this->page*1000 + $this->y)); }
18571 else { $this->blk[$i]['float_endpos'] = $this->page*1000 + $this->y; }
18572 }
18573
18574 $this->floatDivs[] = array(
18575 'side'=>'L',
18576 'startpage'=>$this->blk[$this->blklvl]['startpage'] ,
18577 'y0'=>$this->blk[$this->blklvl]['float_start_y'] ,
18578 'startpos'=> ($this->blk[$this->blklvl]['startpage']*1000 + $this->blk[$this->blklvl]['float_start_y']),
18579 'endpage'=>$this->page ,
18580 'y1'=>$this->y ,
18581 'endpos'=> ($this->page*1000 + $this->y),
18582 'w'=> $this->blk[$this->blklvl]['float_width'],
18583 'blklvl'=>$this->blklvl,
18584 'blockContext' => $this->blk[$this->blklvl-1]['blockContext']
18585 );
18586
18587 $this->y = $this->blk[$this->blklvl]['float_start_y'] ;
18588 $this->page = $this->blk[$this->blklvl]['startpage'] ;
18589 $this->ResetMargins();
18590 $this->pageoutput[$this->page] = array();
18591 }
18592 /*-- END CSS-FLOAT --*/
18593
18594 if (isset($this->blk[$this->blklvl]['visibility']) && $this->blk[$this->blklvl]['visibility']!='visible') {
18595 $this->SetVisibility('visible');
18596 }
18597
18598 if (isset($this->blk[$this->blklvl]['page_break_after'])) { $page_break_after = $this->blk[$this->blklvl]['page_break_after']; }
18599 else { $page_break_after = ''; }
18600
18601 //Reset values
18602 $this->Reset();
18603
18604 // mPDF 5.6.01 - LAYERS
18605 if (isset($this->blk[$this->blklvl]['z-index']) && $this->blk[$this->blklvl]['z-index'] > 0) {
18606 $this->EndLayer();
18607 }
18608
18609 if ($this->blklvl > 0) { // ==0 SHOULDN'T HAPPEN - NOT XHTML
18610 if ($this->blk[$this->blklvl]['tag'] == $tag) {
18611 unset($this->blk[$this->blklvl]);
18612 $this->blklvl--;
18613 }
18614 //else { echo $tag; exit; } // debug - forces error if incorrectly nested html tags
18615 }
18616
18617 $this->lastblocklevelchange = -1 ;
18618 // Reset Inline-type properties
18619 if (isset($this->blk[$this->blklvl]['InlineProperties'])) { $this->restoreInlineProperties($this->blk[$this->blklvl]['InlineProperties']); }
18620
18621 $this->x = $this->lMargin + $this->blk[$this->blklvl]['outer_left_margin'];
18622
18623 if ($page_break_after) {
18624 $save_blklvl = $this->blklvl;
18625 $save_blk = $this->blk;
18626 $save_silp = $this->saveInlineProperties();
18627 $save_spanlvl = $this->spanlvl;
18628 $save_ilp = $this->InlineProperties;
18629 if ($this->blklvl>1) {
18630 // Close any open block tags
18631 for ($b= $this->blklvl;$b>0;$b--) { $this->CloseTag($this->blk[$b]['tag']); }
18632 // Output any text left in buffer
18633 if (count($this->textbuffer)) { $this->printbuffer($this->textbuffer); $this->textbuffer=array(); }
18634 }
18635 /*-- COLUMNS --*/
18636 $save_cols = false;
18637 if ($this->ColActive) {
18638 $save_cols = true;
18639 $save_nbcol = $this->NbCol; // other values of gap and vAlign will not change by setting Columns off
18640 $this->SetColumns(0);
18641 }
18642 /*-- END COLUMNS --*/
18643 if ($page_break_after == 'RIGHT') { $this->AddPage($this->CurOrientation,'NEXT-ODD','','','','','', '','', '','','','','','',0,0,0,0,$pagesel); }
18644 else if ($page_break_after == 'LEFT') { $this->AddPage($this->CurOrientation,'NEXT-EVEN','','','','','', '','', '','','','','','',0,0,0,0,$pagesel); }
18645 else { $this->AddPage($this->CurOrientation,'','','','','','', '','', '','','','','','',0,0,0,0,$pagesel); }
18646 if (!$this->restoreBlockPagebreaks) {
18647 $this->blklvl = 0;
18648 $this->lastblocklevelchange = 0;
18649 $this->blk = array();
18650 $this->initialiseBlock($this->blk[0]);
18651 $this->blk[0]['width'] =& $this->pgwidth;
18652 $this->blk[0]['inner_width'] =& $this->pgwidth;
18653 $this->blk[0]['blockContext'] = $this->blockContext;
18654 $properties = $this->cssmgr->MergeCSS('BLOCK','BODY','');
18655 $this->setCSS($properties,'','BODY');
18656 $this->blklvl++;
18657 $currblk =& $this->blk[$this->blklvl];
18658 $prevblk =& $this->blk[$this->blklvl-1];
18659
18660 $this->initialiseBlock($currblk);
18661 $currblk['tag'] = $tag;
18662 $currblk['attr'] = $attr;
18663
18664 $this->Reset();
18665 $properties = $this->cssmgr->MergeCSS('BLOCK',$tag,$attr);
18666 }
18667 /*-- COLUMNS --*/
18668 if ($save_cols) {
18669 // Restore columns
18670 $this->SetColumns($save_nbcol,$this->colvAlign,$this->ColGap);
18671 }
18672 /*-- END COLUMNS --*/
18673 if ($this->restoreBlockPagebreaks && !$this->tableLevel && !$this->listlvl) {
18674 $this->blk = $save_blk;
18675 // Re-open block tags
18676 $t = $this->blk[0]['tag'];
18677 $a = $this->blk[0]['attr'];
18678 $this->blklvl = 0;
18679 for ($b=0; $b<=$save_blklvl;$b++) {
18680 $tc = $t;
18681 $ac = $a;
18682 $t = $this->blk[$b+1]['tag'];
18683 $a = $this->blk[$b+1]['attr'];
18684 unset($this->blk[$b+1]);
18685 $this->OpenTag($tc,$ac);
18686 }
18687 $this->spanlvl = $save_spanlvl;
18688 $this->InlineProperties = $save_ilp;
18689 $this->restoreInlineProperties($save_silp);
18690 }
18691 }
18692
18693 }
18694
18695
18696 /*-- TABLES --*/
18697
18698 if($tag=='TH') $this->SetStyle('B',false);
18699
18700 if(($tag=='TH' or $tag=='TD') && $this->tableLevel) {
18701 $this->lastoptionaltag = 'TR';
18702 unset($this->cssmgr->tablecascadeCSS[$this->cssmgr->tbCSSlvl]);
18703 $this->cssmgr->tbCSSlvl--;
18704 if (!$this->tdbegin) { return; }
18705 $this->tdbegin = false;
18706 // Added for correct calculation of cell column width - otherwise misses the last line if not end </p> etc.
18707 if (!isset($this->cell[$this->row][$this->col]['maxs'])) {
18708 if (!is_array($this->cell[$this->row][$this->col])) { $this->Error("You may have an error in your HTML code e.g. &lt;/td&gt;&lt;/td&gt;"); }
18709 $this->cell[$this->row][$this->col]['maxs'] = $this->cell[$this->row][$this->col]['s'];
18710 }
18711 elseif($this->cell[$this->row][$this->col]['maxs'] < $this->cell[$this->row][$this->col]['s']) {
18712 $this->cell[$this->row][$this->col]['maxs'] = $this->cell[$this->row][$this->col]['s'];
18713 }
18714
18715 // Remove last <br> if at end of cell
18716 if (isset($this->cell[$this->row][$this->col]['textbuffer'])) { $ntb = count($this->cell[$this->row][$this->col]['textbuffer']); }
18717 else { $ntb = 0; }
18718 if ($ntb>1 && $this->cell[$this->row][$this->col]['textbuffer'][$ntb-1][0] == "\n") {
18719 unset($this->cell[$this->row][$this->col]['textbuffer'][$ntb-1]);
18720 }
18721
18722 if ($this->cacheTables) {
18723 $clen = $this->_cacheCell($this->cell[$this->row][$this->col], $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['cache']);
18724 $this->cell[$this->row][$this->col] = $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['ptr'];
18725 $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['ptr'] += $clen;
18726 }
18727
18728 if ($this->tablethead) {
18729 $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['is_thead'][$this->row] = true;
18730 if ($this->tableLevel==1) { $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['headernrows'] = max($this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['headernrows'] , ($this->row+1)); }
18731 }
18732 if ($this->tabletfoot) {
18733 $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['is_tfoot'][$this->row] = true;
18734 if ($this->tableLevel==1) { $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['footernrows'] = max($this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['footernrows'] , ($this->row+1 - $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['headernrows'] )); }
18735 }
18736 $this->Reset();
18737 }
18738
18739 if($tag=='TR' && $this->tableLevel) {
18740 // If Border set on TR - Update right border
18741 if (isset($this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['trborder-left'][$this->row])) {
18742 if ($this->cacheTables) {
18743 $c = $this->_uncacheCell($this->cell[$this->row][$this->col], $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['cache'], null);
18744 }
18745 else { $c =& $this->cell[$this->row][$this->col]; }
18746 if ($c) {
18747 if ($this->packTableData) {
18748 $cell = $this->_unpackCellBorder($c['borderbin'] );
18749 }
18750 else { $cell = $c; }
18751 $cell['border_details']['R'] = $this->border_details($this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['trborder-right'][$this->row]);
18752 $this->setBorder($cell['border'], _BORDER_RIGHT, $cell['border_details']['R']['s']);
18753 if ($this->packTableData) {
18754 $c['borderbin'] = $this->_packCellBorder($cell);
18755 unset($c['border']);
18756 unset($c['border_details']);
18757 }
18758 else { $c = $cell; }
18759 }
18760 if ($this->cacheTables) {
18761 $fh = fopen($this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['cache'], "r+b");
18762 $this->_cacheUpdateBorder($c, $fh, $this->cell[$this->row][$this->col]);
18763 fclose($fh);
18764 }
18765 }
18766 $this->lastoptionaltag = '';
18767 unset($this->cssmgr->tablecascadeCSS[$this->cssmgr->tbCSSlvl]);
18768 $this->cssmgr->tbCSSlvl--;
18769 $this->trow_text_rotate = '';
18770 $this->tabletheadjustfinished = false;
18771 }
18772
18773 if($tag=='TBODY') {
18774 $this->lastoptionaltag = '';
18775 unset($this->cssmgr->tablecascadeCSS[$this->cssmgr->tbCSSlvl]);
18776 $this->cssmgr->tbCSSlvl--;
18777 }
18778
18779 if($tag=='THEAD') {
18780 $this->lastoptionaltag = '';
18781 unset($this->cssmgr->tablecascadeCSS[$this->cssmgr->tbCSSlvl]);
18782 $this->cssmgr->tbCSSlvl--;
18783 $this->tablethead = 0;
18784 $this->tabletheadjustfinished = true;
18785 $this->ResetStyles();
18786 $this->thead_font_weight = '';
18787 $this->thead_font_style = '';
18788 $this->thead_font_smCaps = '';
18789
18790 $this->thead_valign_default = '';
18791 $this->thead_textalign_default = '';
18792 }
18793
18794 if($tag=='TFOOT') {
18795 $this->lastoptionaltag = '';
18796 unset($this->cssmgr->tablecascadeCSS[$this->cssmgr->tbCSSlvl]);
18797 $this->cssmgr->tbCSSlvl--;
18798 $this->tabletfoot = 0;
18799 $this->ResetStyles();
18800 $this->tfoot_font_weight = '';
18801 $this->tfoot_font_style = '';
18802 $this->tfoot_font_smCaps = '';
18803
18804 $this->tfoot_valign_default = '';
18805 $this->tfoot_textalign_default = '';
18806 }
18807
18808 if($tag=='TABLE') { // TABLE-END (
18809 if ($this->progressBar) { $this->UpdateProgressBar(1,'','TABLE'); } // *PROGRESS-BAR*
18810 if ($this->progressBar) { $this->UpdateProgressBar(7,0,''); } // *PROGRESS-BAR*
18811 $this->lastoptionaltag = '';
18812 unset($this->cssmgr->tablecascadeCSS[$this->cssmgr->tbCSSlvl]);
18813 $this->cssmgr->tbCSSlvl--;
18814 $this->ignorefollowingspaces = true; //Eliminate exceeding left-side spaces
18815 $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['cells'] = $this->cell;
18816 $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['wc'] = array_pad(array(),$this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['nc'],array('miw'=>0,'maw'=>0));
18817 $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['hr'] = array_pad(array(),$this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['nr'],0);
18818
18819 // Move table footer <tfoot> row to end of table
18820 if (isset($this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['is_tfoot']) && count($this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['is_tfoot'])) {
18821 $tfrows = array();
18822 foreach($this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['is_tfoot'] AS $r=>$val) {
18823 if ($val) { $tfrows[] = $r; }
18824 }
18825 $temp = array();
18826 $temptf = array();
18827 foreach($this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['cells'] AS $k=>$row) {
18828 if (in_array($k,$tfrows)) {
18829 $temptf[] = $row;
18830 }
18831 else {
18832 $temp[] = $row;
18833 }
18834 }
18835 $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['is_tfoot'] = array();
18836 for($i=count($temp) ; $i<(count($temp)+count($temptf)); $i++) {
18837 $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['is_tfoot'][$i] = true;
18838 }
18839 // Update nestedpos row references
18840 if (count($this->table[($this->tableLevel+1)])) {
18841 foreach($this->table[($this->tableLevel+1)] AS $nid=>$nested) {
18842 $this->table[($this->tableLevel+1)][$nid]['nestedpos'][0] -= count($temptf);
18843 }
18844 }
18845 $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['cells'] = array_merge($temp, $temptf);
18846
18847 // Update other arays set on row number
18848 // [trbackground-images] [trgradients]
18849 $temptrbgi = array();
18850 $temptrbgg = array();
18851 $temptrbgc = array();
18852 $temptrbgc[-1] = $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['bgcolor'][-1];
18853 for($k=0; $k<$this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['nr']; $k++) {
18854 if (!in_array($k,$tfrows)) {
18855 $temptrbgi[] = $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['trbackground-images'][$k];
18856 $temptrbgg[] = $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['trgradients'][$k];
18857 $temptrbgc[] = $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['bgcolor'][$k];
18858 }
18859 }
18860 for($k=0; $k<$this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['nr']; $k++) {
18861 if (in_array($k,$tfrows)) {
18862 $temptrbgi[] = $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['trbackground-images'][$k];
18863 $temptrbgg[] = $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['trgradients'][$k];
18864 $temptrbgc[] = $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['bgcolor'][$k];
18865 }
18866 }
18867 $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['trbackground-images'] = $temptrbgi;
18868 $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['trgradients'] = $temptrbgg;
18869 $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['bgcolor'] = $temptrbgc ;
18870 // Should Update all other arays set on row number, but cell properties have been set so not needed
18871 // [bgcolor] [trborder-left] [trborder-right] [trborder-top] [trborder-bottom]
18872 }
18873
18874 if ($this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['direction']=='rtl') {
18875 $this->_reverseTableDir($this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]);
18876 }
18877
18878 // Fix Borders *********************************************
18879 $this->_fixTableBorders($this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]);
18880
18881 if ($this->progressBar) { $this->UpdateProgressBar(7,10,' '); } // *PROGRESS-BAR*
18882
18883 if ($this->ColActive) { $this->table_rotate = 0; } // *COLUMNS*
18884 if ($this->table_rotate <> 0) {
18885 $this->tablebuffer = '';
18886 // Max width for rotated table
18887 $this->tbrot_maxw = $this->h - ($this->y + $this->bMargin + 1);
18888 $this->tbrot_maxh = $this->blk[$this->blklvl]['inner_width'] ; // Max width for rotated table
18889 $this->tbrot_align = $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['a'] ;
18890 }
18891 $this->shrin_k = 1;
18892
18893 if ($this->shrink_tables_to_fit < 1) { $this->shrink_tables_to_fit = 1; }
18894 if (!$this->shrink_this_table_to_fit) { $this->shrink_this_table_to_fit = $this->shrink_tables_to_fit; }
18895
18896 if ($this->tableLevel>1) {
18897 // deal with nested table
18898
18899 $this->_tableColumnWidth($this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]],true);
18900
18901 $tmiw = $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['miw'];
18902 $tmaw = $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['maw'];
18903 $tl = $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['tl'];
18904
18905 // Go down to lower table level
18906 $this->tableLevel--;
18907
18908 // Reset lower level table
18909 $this->base_table_properties = $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['baseProperties'];
18910 $this->cell = $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['cells'];
18911 // mPDF 5.4.10
18912 if (isset($this->cell['PARENTCELL'])) {
18913 if ($this->cell['PARENTCELL']) { $this->restoreInlineProperties($this->cell['PARENTCELL']); }
18914 unset($this->cell['PARENTCELL']);
18915 }
18916 $this->row = $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['currrow'];
18917 $this->col = $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['currcol'];
18918 $objattr = array();
18919 $objattr['type'] = 'nestedtable';
18920 $objattr['nestedcontent'] = $this->tbctr[($this->tableLevel+1)];
18921 $objattr['table'] = $this->tbctr[$this->tableLevel];
18922 $objattr['row'] = $this->row;
18923 $objattr['col'] = $this->col;
18924 $objattr['level'] = $this->tableLevel;
18925 $e = "\xbb\xa4\xactype=nestedtable,objattr=".serialize($objattr)."\xbb\xa4\xac";
18926 $this->_saveCellTextBuffer($e);
18927 $this->cell[$this->row][$this->col]['s'] += $tl ;
18928 if (!isset($this->cell[$this->row][$this->col]['maxs'])) {
18929 $this->cell[$this->row][$this->col]['maxs'] = $this->cell[$this->row][$this->col]['s'];
18930 }
18931 elseif($this->cell[$this->row][$this->col]['maxs'] < $this->cell[$this->row][$this->col]['s']) {
18932 $this->cell[$this->row][$this->col]['maxs'] = $this->cell[$this->row][$this->col]['s'];
18933 }
18934 $this->cell[$this->row][$this->col]['s'] = 0;// reset
18935 if ((isset($this->cell[$this->row][$this->col]['nestedmaw']) && $this->cell[$this->row][$this->col]['nestedmaw'] < $tmaw) || !isset($this->cell[$this->row][$this->col]['nestedmaw'])) { $this->cell[$this->row][$this->col]['nestedmaw'] = $tmaw ; }
18936 if ((isset($this->cell[$this->row][$this->col]['nestedmiw']) && $this->cell[$this->row][$this->col]['nestedmiw'] < $tmiw) || !isset($this->cell[$this->row][$this->col]['nestedmiw'])) { $this->cell[$this->row][$this->col]['nestedmiw'] = $tmiw ; }
18937 $this->tdbegin = true;
18938 $this->nestedtablejustfinished = true;
18939 $this->ignorefollowingspaces = true;
18940 return;
18941 }
18942 $this->cMarginL = 0;
18943 $this->cMarginR = 0;
18944 $this->cMarginT = 0;
18945 $this->cMarginB = 0;
18946 $this->cellPaddingL = 0;
18947 $this->cellPaddingR = 0;
18948 $this->cellPaddingT = 0;
18949 $this->cellPaddingB = 0;
18950
18951 if (isset($this->table[1][1]['overflow']) && $this->table[1][1]['overflow']=='visible') {
18952 if ($this->kwt || $this->table_rotate || $this->table_keep_together || $this->ColActive) {
18953 $this->kwt = false;
18954 $this->table_rotate = 0;
18955 $this->table_keep_together = false;
18956 //die("mPDF Warning: You cannot use CSS overflow:visible together with any of these functions: 'Keep-with-table', rotated tables, page-break-inside:avoid, or columns");
18957 }
18958 $this->_tableColumnWidth($this->table[1][1],true);
18959 $this->_tableWidth($this->table[1][1]);
18960 }
18961 else {
18962 if (!$this->kwt_saved) { $this->kwt_height = 0; }
18963
18964 list($check,$tablemiw) = $this->_tableColumnWidth($this->table[1][1],true);
18965 $save_table = $this->table;
18966 if ($this->cacheTables) { $this->_backupCacheFiles(); }
18967 $reset_to_minimum_width = false;
18968 $added_page = false;
18969
18970 if ($check > 1) {
18971 if ($check > $this->shrink_this_table_to_fit && $this->table_rotate) {
18972 if ($this->y != $this->tMargin) {
18973 $this->AddPage($this->CurOrientation);
18974 $this->kwt_moved = true;
18975 }
18976 $added_page = true;
18977 $this->tbrot_maxw = $this->h - ($this->y + $this->bMargin + 5) - $this->kwt_height;
18978 //$check = $tablemiw/$this->tbrot_maxw; // undo any shrink
18979 $check = 1; // undo any shrink
18980 }
18981 $reset_to_minimum_width = true;
18982 }
18983
18984 if ($reset_to_minimum_width) {
18985
18986 $this->shrin_k = $check;
18987
18988 $this->default_font_size /= $this->shrin_k;
18989 $this->SetFontSize($this->default_font_size, false );
18990
18991 $this->shrinkTable($this->table[1][1],$this->shrin_k);
18992
18993 $this->_tableColumnWidth($this->table[1][1],false); // repeat
18994
18995 // Starting at $this->innermostTableLevel
18996 // Shrink table values - and redo columnWidth
18997 for($lvl=2;$lvl<=$this->innermostTableLevel;$lvl++) {
18998 for ($nid=1; $nid<=$this->tbctr[$lvl]; $nid++) {
18999 $this->shrinkTable($this->table[$lvl][$nid],$this->shrin_k);
19000 $this->_tableColumnWidth($this->table[$lvl][$nid],false);
19001 }
19002 }
19003 }
19004
19005 // Set table cell widths for top level table
19006 // Use $shrin_k to resize but don't change again
19007 $this->SetLineHeight('',$this->table_lineheight);
19008
19009 // Top level table
19010 $this->_tableWidth($this->table[1][1]);
19011
19012 }
19013
19014
19015 // Now work through any nested tables setting child table[w'] = parent cell['w']
19016 // Now do nested tables _tableWidth
19017 for($lvl=2;$lvl<=$this->innermostTableLevel;$lvl++) {
19018 for ($nid=1; $nid<=$this->tbctr[$lvl]; $nid++) {
19019 // HERE set child table width = cell width
19020
19021 list($parentrow, $parentcol, $parentnid) = $this->table[$lvl][$nid]['nestedpos'];
19022
19023 if ($this->cacheTables) {
19024 $c = $this->_uncacheCell($this->table[($lvl-1)][$parentnid]['cells'][$parentrow][$parentcol], $this->table[($lvl-1)][$parentnid]['cache'], null);
19025 }
19026 else
19027 $c =& $this->table[($lvl-1)][$parentnid]['cells'][$parentrow][$parentcol];
19028
19029 if (isset($c['colspan']) && $c['colspan']> 1) {
19030 $parentwidth = 0;
19031 for($cs=0;$cs<$c['colspan'] ; $cs++) {
19032 $parentwidth += $this->table[($lvl-1)][$parentnid]['wc'][$parentcol+$cs];
19033 }
19034 }
19035 else { $parentwidth = $this->table[($lvl-1)][$parentnid]['wc'][$parentcol]; }
19036
19037
19038 //$parentwidth -= ALLOW FOR PADDING ETC.in parent cell
19039 if (!$this->simpleTables){
19040 if ($this->packTableData) {
19041 list($bt,$br,$bb,$bl) = $this->_getBorderWidths($c['borderbin']);
19042 }
19043 else {
19044 $br = $c['border_details']['R']['w'];
19045 $bl = $c['border_details']['L']['w'];
19046 }
19047 if ($this->table[$lvl-1][$parentnid]['borders_separate']) {
19048 $parentwidth -= $br + $bl
19049 + $c['padding']['L']
19050 + $c['padding']['R']
19051 + $this->table[($lvl-1)][$parentnid]['border_spacing_H'];
19052 }
19053 else {
19054 $parentwidth -= $br/2 + $bl/2
19055 + $c['padding']['L']
19056 + $c['padding']['R'];
19057 }
19058 }
19059 else if ($this->simpleTables){
19060 if ($this->table[$lvl-1][$parentnid]['borders_separate']) {
19061 $parentwidth -= $this->table[($lvl-1)][$parentnid]['simple']['border_details']['L']['w']
19062 + $this->table[($lvl-1)][$parentnid]['simple']['border_details']['R']['w']
19063 + $c['padding']['L']
19064 + $c['padding']['R']
19065 + $this->table[($lvl-1)][$parentnid]['border_spacing_H'];
19066 }
19067 else {
19068 $parentwidth -= $this->table[($lvl-1)][$parentnid]['simple']['border_details']['L']['w']/2
19069 + $this->table[($lvl-1)][$parentnid]['simple']['border_details']['R']['w']/2
19070 + $c['padding']['L']
19071 + $c['padding']['R'];
19072 }
19073 }
19074 if (isset($this->table[$lvl][$nid]['wpercent']) && $this->table[$lvl][$nid]['wpercent'] && $lvl>1) {
19075 $this->table[$lvl][$nid]['w'] = $parentwidth;
19076 }
19077 else if ($parentwidth > $this->table[$lvl][$nid]['maw']) {
19078 $this->table[$lvl][$nid]['w'] = $this->table[$lvl][$nid]['maw'];
19079 }
19080 else {
19081 $this->table[$lvl][$nid]['w'] = $parentwidth;
19082 }
19083 unset($c);
19084 $this->_tableWidth($this->table[$lvl][$nid]);
19085 }
19086 }
19087
19088 // Starting at $this->innermostTableLevel
19089 // Cascade back up nested tables: setting heights back up the tree
19090 for($lvl=$this->innermostTableLevel;$lvl>0;$lvl--) {
19091 for ($nid=1; $nid<=$this->tbctr[$lvl]; $nid++) {
19092 list($tableheight,$maxrowheight,$fullpage,$remainingpage, $maxfirstrowheight) = $this->_tableHeight($this->table[$lvl][$nid]); }
19093 }
19094 if ($this->progressBar) { $this->UpdateProgressBar(7,20,' '); } // *PROGRESS-BAR*
19095 if ($this->table[1][1]['overflow']=='visible') {
19096 if ($maxrowheight > $fullpage) { die("mPDF Warning: A Table row is greater than available height. You cannot use CSS overflow:visible"); }
19097 if ($maxfirstrowheight > $remainingpage) { $this->AddPage($this->CurOrientation); }
19098 $r = 0; $c = 0; $p = 0; $y = 0;
19099 while (!$finished) {
19100 list($finished,$r,$c,$p,$y,$y0) = $this->_tableWrite($this->table[1][1],true,$r,$c,$p,$y);
19101 if (!$finished) {
19102 $this->AddPage($this->CurOrientation);
19103 // If printed something on first spread, set same y
19104 if ($r==0 && $y0 > -1) { $this->y = $y0; }
19105 }
19106 }
19107 }
19108 else {
19109 $recalculate = 1;
19110 $forcerecalc = false;
19111 // RESIZING ALGORITHM
19112 if ($maxrowheight > $fullpage) {
19113 $recalculate = $this->tbsqrt($maxrowheight / $fullpage, 1);
19114 $forcerecalc = true;
19115 }
19116 else if ($this->table_rotate) { // NB $remainingpage == $fullpage == the width of the page
19117 if ($tableheight > $remainingpage) {
19118 // If can fit on remainder of page whilst respecting autsize value..
19119 if (($this->shrin_k * $this->tbsqrt($tableheight / $remainingpage, 1)) <= $this->shrink_this_table_to_fit) {
19120 $recalculate = $this->tbsqrt($tableheight / $remainingpage, 1);
19121 }
19122 else if (!$added_page) {
19123 if ($this->y != $this->tMargin) {
19124 $this->AddPage($this->CurOrientation);
19125 $this->kwt_moved = true;
19126 }
19127 $added_page = true;
19128 $this->tbrot_maxw = $this->h - ($this->y + $this->bMargin + 5) - $this->kwt_height;
19129 // 0.001 to force it to recalculate
19130 $recalculate = (1 / $this->shrin_k) + 0.001; // undo any shrink
19131 }
19132 }
19133 else { $recalculate = 1; }
19134 }
19135 else if ($this->table_keep_together || ($this->table[1][1]['nr']==1 && !$this->writingHTMLfooter)) {
19136 if ($tableheight > $fullpage) {
19137 if (($this->shrin_k * $this->tbsqrt($tableheight / $fullpage, 1)) <= $this->shrink_this_table_to_fit) {
19138 $recalculate = $this->tbsqrt($tableheight / $fullpage, 1);
19139 }
19140 else if ($this->tableMinSizePriority) {
19141 $this->table_keep_together = false;
19142 $recalculate = 1.001;
19143 }
19144 else {
19145 if ($this->y != $this->tMargin) { // mPDF 5.1
19146 $this->AddPage($this->CurOrientation);
19147 $this->kwt_moved = true;
19148 }
19149 $added_page = true;
19150 $this->tbrot_maxw = $this->h - ($this->y + $this->bMargin + 5) - $this->kwt_height;
19151 $recalculate = $this->tbsqrt($tableheight / $fullpage, 1);
19152 }
19153 }
19154 else if ($tableheight > $remainingpage) {
19155 // If can fit on remainder of page whilst respecting autsize value..
19156 if (($this->shrin_k * $this->tbsqrt($tableheight / $remainingpage, 1)) <= $this->shrink_this_table_to_fit) {
19157 $recalculate = $this->tbsqrt($tableheight / $remainingpage, 1);
19158 }
19159 else {
19160 if ($this->y != $this->tMargin) {
19161 $this->AddPage($this->CurOrientation);
19162 $this->kwt_moved = true;
19163 }
19164 $added_page = true;
19165 $this->tbrot_maxw = $this->h - ($this->y + $this->bMargin + 5) - $this->kwt_height;
19166 $recalculate = 1.001;
19167 }
19168 }
19169 else { $recalculate = 1; }
19170 }
19171 else { $recalculate = 1; }
19172
19173 if ($recalculate > $this->shrink_this_table_to_fit && !$forcerecalc) { $recalculate = $this->shrink_this_table_to_fit; }
19174
19175 $iteration = 1;
19176
19177 // RECALCULATE
19178 while($recalculate <> 1) {
19179 $this->shrin_k1 = $recalculate ;
19180 $this->shrin_k *= $recalculate ;
19181 $this->default_font_size /= ($this->shrin_k1) ;
19182 $this->SetFontSize($this->default_font_size, false );
19183 $this->SetLineHeight('',$this->table_lineheight);
19184 $this->table = $save_table;
19185 if ($this->cacheTables) { $this->_restoreCacheFiles(); }
19186 if ($this->shrin_k <> 1) { $this->shrinkTable($this->table[1][1],$this->shrin_k); }
19187 $this->_tableColumnWidth($this->table[1][1],false); // repeat
19188
19189 // Starting at $this->innermostTableLevel
19190 // Shrink table values - and redo columnWidth
19191 for($lvl=2;$lvl<=$this->innermostTableLevel;$lvl++) {
19192 for ($nid=1; $nid<=$this->tbctr[$lvl]; $nid++) {
19193 if ($this->shrin_k <> 1) { $this->shrinkTable($this->table[$lvl][$nid],$this->shrin_k); }
19194 $this->_tableColumnWidth($this->table[$lvl][$nid],false);
19195 }
19196 }
19197 // Set table cell widths for top level table
19198
19199 // Top level table
19200 $this->_tableWidth($this->table[1][1]);
19201
19202 // Now work through any nested tables setting child table[w'] = parent cell['w']
19203 // Now do nested tables _tableWidth
19204 for($lvl=2;$lvl<=$this->innermostTableLevel;$lvl++) {
19205 for ($nid=1; $nid<=$this->tbctr[$lvl]; $nid++) {
19206 // HERE set child table width = cell width
19207
19208 list($parentrow, $parentcol, $parentnid) = $this->table[$lvl][$nid]['nestedpos'];
19209 if ($this->cacheTables) {
19210 $c = $this->_uncacheCell($this->table[($lvl-1)][$parentnid]['cells'][$parentrow][$parentcol], $this->table[($lvl-1)][$parentnid]['cache'], null);
19211 }
19212 else
19213 $c =& $this->table[($lvl-1)][$parentnid]['cells'][$parentrow][$parentcol];
19214
19215 if (isset($c['colspan']) && $c['colspan']> 1) {
19216 $parentwidth = 0;
19217 for($cs=0;$cs<$c['colspan'] ; $cs++) {
19218 $parentwidth += $this->table[($lvl-1)][$parentnid]['wc'][$parentcol+$cs];
19219 }
19220 }
19221 else { $parentwidth = $this->table[($lvl-1)][$parentnid]['wc'][$parentcol]; }
19222
19223 //$parentwidth -= ALLOW FOR PADDING ETC.in parent cell
19224 if (!$this->simpleTables){
19225 if ($this->packTableData) {
19226 list($bt,$br,$bb,$bl) = $this->_getBorderWidths($c['borderbin']);
19227 }
19228 else {
19229 $br = $c['border_details']['R']['w'];
19230 $bl = $c['border_details']['L']['w'];
19231 }
19232 if ($this->table[$lvl-1][$parentnid]['borders_separate']) {
19233 $parentwidth -= $br + $bl
19234 + $c['padding']['L']
19235 + $c['padding']['R']
19236 + $this->table[($lvl-1)][$parentnid]['border_spacing_H'];
19237 }
19238 else {
19239 $parentwidth -= $br/2 + $bl/2
19240 + $c['padding']['L']
19241 + $c['padding']['R'];
19242 }
19243 }
19244 else if ($this->simpleTables){
19245 if ($this->table[$lvl-1][$parentnid]['borders_separate']) {
19246 $parentwidth -= $this->table[($lvl-1)][$parentnid]['simple']['border_details']['L']['w']
19247 + $this->table[($lvl-1)][$parentnid]['simple']['border_details']['R']['w']
19248 + $c['padding']['L']
19249 + $c['padding']['R']
19250 + $this->table[($lvl-1)][$parentnid]['border_spacing_H'];
19251 }
19252 else {
19253 $parentwidth -= ($this->table[($lvl-1)][$parentnid]['simple']['border_details']['L']['w']
19254 + $this->table[($lvl-1)][$parentnid]['simple']['border_details']['R']['w']) /2
19255 + $c['padding']['L']
19256 + $c['padding']['R'];
19257 }
19258 }
19259 if (isset($this->table[$lvl][$nid]['wpercent']) && $this->table[$lvl][$nid]['wpercent'] && $lvl>1) {
19260 $this->table[$lvl][$nid]['w'] = $parentwidth;
19261 }
19262 else if ($parentwidth > $this->table[$lvl][$nid]['maw']) {
19263 $this->table[$lvl][$nid]['w'] = $this->table[$lvl][$nid]['maw'] ;
19264 }
19265 else {
19266 $this->table[$lvl][$nid]['w'] = $parentwidth;
19267 }
19268 unset($c);
19269 $this->_tableWidth($this->table[$lvl][$nid]);
19270 }
19271 }
19272
19273 // Starting at $this->innermostTableLevel
19274 // Cascade back up nested tables: setting heights back up the tree
19275 for($lvl=$this->innermostTableLevel;$lvl>0;$lvl--) {
19276 for ($nid=1; $nid<=$this->tbctr[$lvl]; $nid++) {
19277 list($tableheight,$maxrowheight,$fullpage,$remainingpage, $maxfirstrowheight) = $this->_tableHeight($this->table[$lvl][$nid]); }
19278 }
19279
19280 // RESIZING ALGORITHM
19281
19282 if ($maxrowheight > $fullpage) { $recalculate = $this->tbsqrt($maxrowheight / $fullpage, $iteration); $iteration++; }
19283 else if ($this->table_rotate && $tableheight > $remainingpage && !$added_page) {
19284 // If can fit on remainder of page whilst respecting autosize value..
19285 if (($this->shrin_k * $this->tbsqrt($tableheight / $remainingpage, $iteration)) <= $this->shrink_this_table_to_fit) {
19286 $recalculate = $this->tbsqrt($tableheight / $remainingpage, $iteration); $iteration++;
19287 }
19288 else {
19289 if (!$added_page) {
19290 $this->AddPage($this->CurOrientation);
19291 $added_page = true;
19292 $this->kwt_moved = true;
19293 $this->tbrot_maxw = $this->h - ($this->y + $this->bMargin + 5) - $this->kwt_height;
19294 }
19295 // 0.001 to force it to recalculate
19296 $recalculate = (1 / $this->shrin_k) + 0.001; // undo any shrink
19297 }
19298 }
19299 else if ($this->table_keep_together || ($this->table[1][1]['nr']==1 && !$this->writingHTMLfooter)) {
19300 if ($tableheight > $fullpage) {
19301 if (($this->shrin_k * $this->tbsqrt($tableheight / $fullpage, $iteration)) <= $this->shrink_this_table_to_fit) {
19302 $recalculate = $this->tbsqrt($tableheight / $fullpage, $iteration); $iteration++;
19303 }
19304 else if ($this->tableMinSizePriority) {
19305 $this->table_keep_together = false;
19306 $recalculate = (1 / $this->shrin_k) + 0.001;
19307 }
19308 else {
19309 if (!$added_page && $this->y != $this->tMargin) {
19310 $this->AddPage($this->CurOrientation);
19311 $added_page = true;
19312 $this->kwt_moved = true;
19313 $this->tbrot_maxw = $this->h - ($this->y + $this->bMargin + 5) - $this->kwt_height;
19314 }
19315 $recalculate = $this->tbsqrt($tableheight / $fullpage, $iteration); $iteration++;
19316 }
19317 }
19318 else if ($tableheight > $remainingpage) {
19319 // If can fit on remainder of page whilst respecting autosize value..
19320 if (($this->shrin_k * $this->tbsqrt($tableheight / $remainingpage, $iteration)) <= $this->shrink_this_table_to_fit) {
19321 $recalculate = $this->tbsqrt($tableheight / $remainingpage, $iteration); $iteration++;
19322 }
19323 else {
19324 if (!$added_page) {
19325 $this->AddPage($this->CurOrientation);
19326 $added_page = true;
19327 $this->kwt_moved = true;
19328 $this->tbrot_maxw = $this->h - ($this->y + $this->bMargin + 5) - $this->kwt_height;
19329 }
19330
19331 //$recalculate = $this->tbsqrt($tableheight / $fullpage, $iteration); $iteration++;
19332 $recalculate = (1 / $this->shrin_k) + 0.001; // undo any shrink
19333 }
19334 }
19335 else { $recalculate = 1; }
19336 }
19337 else { $recalculate = 1; }
19338 }
19339
19340
19341 if ($maxfirstrowheight > $remainingpage && !$added_page && !$this->table_rotate && !$this->ColActive && !$this->table_keep_together && !$this->writingHTMLheader && !$this->writingHTMLfooter) {
19342 $this->AddPage($this->CurOrientation);
19343 $this->kwt_moved = true;
19344 }
19345
19346 // keep-with-table: if page has advanced, print out buffer now, else done in fn. _Tablewrite()
19347 if ($this->kwt_saved && $this->kwt_moved) {
19348 $this->printkwtbuffer();
19349 $this->kwt_moved = false;
19350 $this->kwt_saved = false;
19351 }
19352
19353 if ($this->progressBar) { $this->UpdateProgressBar(7,30,' '); } // *PROGRESS-BAR*
19354 // Recursively writes all tables starting at top level
19355 $this->_tableWrite($this->table[1][1]);
19356
19357 if ($this->table_rotate && $this->tablebuffer) {
19358 $this->PageBreakTrigger=$this->h-$this->bMargin;
19359 $save_tr = $this->table_rotate;
19360 $save_y = $this->y;
19361 $this->table_rotate = 0;
19362 $this->y = $this->tbrot_y0;
19363 $h = $this->tbrot_w;
19364 $this->DivLn($h,$this->blklvl,true);
19365
19366 $this->table_rotate = $save_tr;
19367 $this->y = $save_y;
19368
19369 $this->printtablebuffer();
19370 }
19371 $this->table_rotate = 0;
19372 }
19373
19374
19375 $this->x = $this->lMargin + $this->blk[$this->blklvl]['outer_left_margin'];
19376
19377 $this->maxPosR = max($this->maxPosR , ($this->x + $this->table[1][1]['w']));
19378
19379 $this->blockjustfinished=true;
19380 $this->lastblockbottommargin = $this->table[1][1]['margin']['B'];
19381 //Reset values
19382
19383 if (isset($this->table[1][1]['page_break_after'])) { $page_break_after = $this->table[1][1]['page_break_after']; }
19384 else { $page_break_after = ''; }
19385
19386 // Keep-with-table
19387 $this->kwt = false;
19388 $this->kwt_y0 = 0;
19389 $this->kwt_x0 = 0;
19390 $this->kwt_height = 0;
19391 $this->kwt_buffer = array();
19392 $this->kwt_Links = array();
19393 $this->kwt_Annots = array();
19394 $this->kwt_moved = false;
19395 $this->kwt_saved = false;
19396
19397 $this->kwt_Reference = array();
19398 $this->kwt_BMoutlines = array();
19399 $this->kwt_toc = array();
19400
19401 $this->shrin_k = 1;
19402 $this->shrink_this_table_to_fit = 0;
19403
19404 unset($this->table);
19405 $this->table=array(); //array
19406 $this->tableLevel=0;
19407 $this->tbctr=array();
19408 $this->innermostTableLevel=0;
19409 $this->cssmgr->tbCSSlvl = 0;
19410 $this->cssmgr->tablecascadeCSS = array();
19411
19412 unset($this->cell);
19413 $this->cell=array(); //array
19414
19415 $this->col=-1; //int
19416 $this->row=-1; //int
19417 $this->Reset();
19418
19419 $this->cellPaddingL = 0;
19420 $this->cellPaddingT = 0;
19421 $this->cellPaddingR = 0;
19422 $this->cellPaddingB = 0;
19423 $this->cMarginL = 0;
19424 $this->cMarginT = 0;
19425 $this->cMarginR = 0;
19426 $this->cMarginB = 0;
19427 $this->default_font_size = $this->original_default_font_size;
19428 $this->default_font = $this->original_default_font;
19429 $this->SetFontSize($this->default_font_size, false);
19430 $this->SetFont($this->default_font,'',0,false);
19431 $this->SetLineHeight();
19432 if (isset($this->blk[$this->blklvl]['InlineProperties'])) { $this->restoreInlineProperties($this->blk[$this->blklvl]['InlineProperties']);}
19433 if ($this->progressBar) { $this->UpdateProgressBar(7,100,' '); } // *PROGRESS-BAR*
19434
19435 if ($page_break_after) {
19436 $save_blklvl = $this->blklvl;
19437 $save_blk = $this->blk;
19438 $save_silp = $this->saveInlineProperties();
19439 $save_spanlvl = $this->spanlvl;
19440 $save_ilp = $this->InlineProperties;
19441 if ($this->blklvl>1) {
19442 // Close any open block tags
19443 for ($b= $this->blklvl;$b>0;$b--) { $this->CloseTag($this->blk[$b]['tag']); }
19444 // Output any text left in buffer
19445 if (count($this->textbuffer)) { $this->printbuffer($this->textbuffer); $this->textbuffer=array(); }
19446 }
19447 /*-- COLUMNS --*/
19448 $save_cols = false;
19449 if ($this->ColActive) {
19450 $save_cols = true;
19451 $save_nbcol = $this->NbCol; // other values of gap and vAlign will not change by setting Columns off
19452 $this->SetColumns(0);
19453 }
19454 /*-- END COLUMNS --*/
19455 if ($page_break_after == 'RIGHT') { $this->AddPage($this->CurOrientation,'NEXT-ODD','','','','','', '','', '','','','','','',0,0,0,0,$pagesel); }
19456 else if ($page_break_after == 'LEFT') { $this->AddPage($this->CurOrientation,'NEXT-EVEN','','','','','', '','', '','','','','','',0,0,0,0,$pagesel); }
19457 else { $this->AddPage($this->CurOrientation,'','','','','','', '','', '','','','','','',0,0,0,0,$pagesel); }
19458 if (!$this->restoreBlockPagebreaks) {
19459 $this->blklvl = 0;
19460 $this->lastblocklevelchange = 0;
19461 $this->blk = array();
19462 $this->initialiseBlock($this->blk[0]);
19463 $this->blk[0]['width'] =& $this->pgwidth;
19464 $this->blk[0]['inner_width'] =& $this->pgwidth;
19465 $this->blk[0]['blockContext'] = $this->blockContext;
19466 $properties = $this->cssmgr->MergeCSS('BLOCK','BODY','');
19467 $this->setCSS($properties,'','BODY');
19468 }
19469
19470 /*-- COLUMNS --*/
19471 if ($save_cols) {
19472 // Restore columns
19473 $this->SetColumns($save_nbcol,$this->colvAlign,$this->ColGap);
19474 }
19475 /*-- END COLUMNS --*/
19476 if ($this->restoreBlockPagebreaks) {
19477 $this->blk = $save_blk;
19478 // Re-open block tags
19479 $t = $this->blk[0]['tag'];
19480 $a = $this->blk[0]['attr'];
19481 $this->blklvl = 0;
19482 for ($b=0; $b<=$save_blklvl;$b++) {
19483 $tc = $t;
19484 $ac = $a;
19485 $t = $this->blk[$b+1]['tag'];
19486 $a = $this->blk[$b+1]['attr'];
19487 unset($this->blk[$b+1]);
19488 $this->OpenTag($tc,$ac);
19489 }
19490 $this->spanlvl = $save_spanlvl;
19491 $this->InlineProperties = $save_ilp;
19492 $this->restoreInlineProperties($save_silp);
19493 }
19494 }
19495
19496 }
19497 /*-- END TABLES --*/
19498
19499 /*-- LISTS --*/
19500 // *********** LISTS ********************
19501
19502 if($tag=='LI') {
19503 $this->lastoptionaltag = '';
19504 unset($this->cssmgr->listcascadeCSS[$this->cssmgr->listCSSlvl]);
19505 $this->cssmgr->listCSSlvl--;
19506 if (isset($this->listoccur[$this->listlvl]) && isset($this->InlineProperties['LIST'][$this->listlvl][$this->listoccur[$this->listlvl]])) { $this->restoreInlineProperties($this->InlineProperties['LIST'][$this->listlvl][$this->listoccur[$this->listlvl]]); }
19507 }
19508
19509
19510 if(($tag=='UL') or ($tag=='OL')) {
19511 $this->ignorefollowingspaces = true; //Eliminate exceeding left-side spaces
19512 unset($this->cssmgr->listcascadeCSS[$this->cssmgr->listCSSlvl]);
19513 $this->cssmgr->listCSSlvl--;
19514
19515 $this->lastoptionaltag = '';
19516 /*-- TABLES --*/
19517 // A simple list for inside a table
19518 if($this->tableLevel) {
19519 $this->listlist[$this->listlvl]['MAXNUM'] = $this->listnum; //save previous lvl's maxnum
19520 unset($this->listlist[$this->listlvl]);
19521 $this->listlvl--;
19522 if (isset($this->listlist[$this->listlvl]['MAXNUM'])) { $this->listnum = $this->listlist[$this->listlvl]['MAXNUM']; } // restore previous levels
19523 if ($this->listlvl == 0) { $this->listjustfinished = true; }
19524 return;
19525 }
19526 /*-- END TABLES --*/
19527
19528 if ($this->listlvl > 1) { // returning one level
19529 $this->listjustfinished=true;
19530 if (!empty($this->textbuffer)) {
19531 $this->listitem[] = array($this->listlvl,$this->listnum,$this->textbuffer,$this->listoccur[$this->listlvl],$this->listitemtype);
19532 }
19533 else {
19534 $this->listnum--;
19535 }
19536
19537 $this->textbuffer = array();
19538 $occur = $this->listoccur[$this->listlvl];
19539 $this->listlist[$this->listlvl][$occur]['MAXNUM'] = $this->listnum; //save previous lvl's maxnum
19540 $this->listlvl--;
19541 $occur = $this->listoccur[$this->listlvl];
19542 $this->listnum = $this->listlist[$this->listlvl][$occur]['MAXNUM']; // recover previous level's number
19543 $this->listtype = $this->listlist[$this->listlvl][$occur]['TYPE']; // recover previous level's type
19544 if ($this->InlineProperties['LIST'][$this->listlvl][$occur]) { $this->restoreInlineProperties($this->InlineProperties['LIST'][$this->listlvl][$occur]); }
19545
19546 }
19547 else { // We are closing the last OL/UL tag
19548 if (!empty($this->textbuffer)) {
19549 $this->listitem[] = array($this->listlvl,$this->listnum,$this->textbuffer,$this->listoccur[$this->listlvl],$this->listitemtype);
19550 }
19551 else {
19552 $this->listnum--;
19553 }
19554
19555 $occur = $this->listoccur[$this->listlvl];
19556 $this->listlist[$this->listlvl][$occur]['MAXNUM'] = $this->listnum;
19557 $this->textbuffer = array();
19558 $this->listlvl--;
19559
19560 $this->printlistbuffer();
19561 unset($this->InlineProperties['LIST']);
19562 // SPACING AFTER LIST (Top level only)
19563 $this->Ln(0);
19564 if ($this->list_margin_bottom) {
19565 $this->DivLn($this->list_margin_bottom,$this->blklvl,true,1); // collapsible
19566 }
19567 if (isset($this->blk[$this->blklvl]['InlineProperties'])) { $this->restoreInlineProperties($this->blk[$this->blklvl]['InlineProperties']);}
19568 $this->listjustfinished = true;
19569 $this->cssmgr->listCSSlvl = 0;
19570 $this->cssmgr->listcascadeCSS = array();
19571 $this->blockjustfinished=true;
19572 $this->lastblockbottommargin = $this->list_margin_bottom;
19573 }
19574 }
19575 /*-- END LISTS --*/
19576
19577
19578 }
19579
19580
19581 /*-- TABLES --*/
19582 // This function determines the shrink factor when resizing tables
19583 // val is the table_height / page_height_available
19584 // returns a scaling factor used as $shrin_k to resize the table
19585 // Overcompensating will be quicker but may unnecessarily shrink table too much
19586 // Undercompensating means it will reiterate more times (taking more processing time)
19587 function tbsqrt($val, $iteration=3) {
19588 $k = 4; // Alters number of iterations until it returns $val itself - Must be > 2
19589 // Probably best guess and most accurate
19590 if ($iteration==1) return sqrt($val);
19591 // Faster than using sqrt (because it won't undercompensate), and gives reasonable results
19592 //return 1+(($val-1)/2);
19593 $x = 2-(($iteration-2)/($k-2));
19594 if ($x == 0) { $ret = $val+0.00001; }
19595 else if ($x < 0) { $ret = 1 + ( pow(2, ($iteration-2-$k))/1000 ); }
19596 else { $ret = 1+(($val-1)/$x); }
19597 return $ret;
19598 }
19599 /*-- END TABLES --*/
19600
19601
19602 /*-- LISTS --*/
19603 function printlistbuffer() {
19604 //Save x coordinate
19605 $x = $this->lMargin + $this->blk[$this->blklvl]['outer_left_margin'];
19606 $this->cMarginL = 0;
19607 $this->cMarginR = 0;
19608 $currIndentLvl = -1;
19609 $lastIndent = array();
19610 $bak_page = $this->page;
19611 $indent = 0;
19612 foreach($this->listitem as $item)
19613 {
19614 // COLS
19615 $oldcolumn = $this->CurrCol;
19616
19617 $this->bulletarray = array();
19618 //Get list's buffered data
19619 $this->listlvl = $lvl = $item[0];
19620 $num = $item[1];
19621 $this->textbuffer = $item[2];
19622 $occur = $item[3];
19623 if ($item[4]) { $type = $item[4]; } // listitemtype
19624 else { $type = $this->listlist[$lvl][$occur]['TYPE']; }
19625 $maxnum = $this->listlist[$lvl][$occur]['MAXNUM'];
19626 $this->restoreInlineProperties($this->InlineProperties['LIST'][$lvl][$occur]);
19627 $this->SetFont($this->FontFamily,$this->FontStyle,$this->FontSizePt,true,true); // force to write
19628 $clh = $this->FontSize;
19629
19630 $this->SetLineHeight($this->FontSizePt,$this->list_lineheight[$lvl][$occur]);
19631 $this->listOcc = $occur;
19632 $this->listnum = $num;
19633
19634 if (isset($this->list_align[$this->listlvl][$occur])) { $this->divalign = $this->list_align[$this->listlvl][$occur]; }
19635 else {
19636 if (isset($this->blk[$this->blklvl]['direction']) && $this->blk[$this->blklvl]['direction']=='rtl') { $this->divalign = 'R'; }
19637 else { $this->divalign = 'L'; }
19638 }
19639
19640 // Set the bullet fontsize
19641 $bullfs = $this->InlineProperties['LISTITEM'][$lvl][$occur][$num]['size'];
19642
19643 $space_width = $this->GetCharWidth(' ',false) * 1.5;
19644
19645 //Set default width & height values
19646 $this->divwidth = $this->blk[$this->blklvl]['inner_width'];
19647 $this->divheight = $this->lineheight;
19648 $typefont = $this->FontFamily;
19649 if (preg_match('/U\+([a-fA-F0-9]+)/i',$type,$m)) {
19650 if ($this->_charDefined($this->CurrentFont['cw'],hexdec($m[1]))) { $list_item_marker = codeHex2utf($m[1]); }
19651 else { $list_item_marker = '-'; }
19652 $blt_width = $this->GetStringWidth($list_item_marker);
19653 $typefont = '';
19654 if (preg_match('/rgb\(.*?\)/',$type,$m)) {
19655 $list_item_color = $this->ConvertColor($m[0]);
19656 }
19657 }
19658 else {
19659 $list_item_color = false;
19660
19661 switch($type) //Format type
19662 {
19663 case '1':
19664 if ($this->listDir == 'rtl') { $list_item_marker = $this->list_number_suffix . $num; }
19665 else { $list_item_marker = $num . $this->list_number_suffix; }
19666 $blt_width = $this->GetStringWidth(str_repeat('5',strlen($maxnum)).$this->list_number_suffix);
19667 break;
19668 case 'none':
19669 $list_item_marker = '';
19670 $blt_width = 0;
19671 break;
19672 case 'A':
19673 $anum = $this->dec2alpha($num,true);
19674 $maxnum = $this->dec2alpha($maxnum,true);
19675 if ($this->listDir == 'rtl') { $list_item_marker = $this->list_number_suffix . $anum; }
19676 else { $list_item_marker = $anum . $this->list_number_suffix; }
19677 $blt_width = $this->GetStringWidth(str_repeat('W',strlen($maxnum)).$this->list_number_suffix);
19678 break;
19679 case 'a':
19680 $anum = $this->dec2alpha($num,false);
19681 $maxnum = $this->dec2alpha($maxnum,false);
19682 if ($this->listDir == 'rtl') { $list_item_marker = $this->list_number_suffix . $anum; }
19683 else { $list_item_marker = $anum . $this->list_number_suffix; }
19684 $blt_width = $this->GetStringWidth(str_repeat('m',strlen($maxnum)).$this->list_number_suffix);
19685 break;
19686 case 'I':
19687 $anum = $this->dec2roman($num,true);
19688 if ($this->listDir == 'rtl') { $list_item_marker = $this->list_number_suffix . $anum; }
19689 else { $list_item_marker = $anum . $this->list_number_suffix; }
19690
19691 if ($maxnum>87) { $bbit = 87; }
19692 else if ($maxnum>86) { $bbit = 86; }
19693 else if ($maxnum>37) { $bbit = 38; }
19694 else if ($maxnum>36) { $bbit = 37; }
19695 else if ($maxnum>27) { $bbit = 28; }
19696 else if ($maxnum>26) { $bbit = 27; }
19697 else if ($maxnum>17) { $bbit = 18; }
19698 else if ($maxnum>16) { $bbit = 17; }
19699 else if ($maxnum>7) { $bbit = 8; }
19700 else if ($maxnum>6) { $bbit = 7; }
19701 else if ($maxnum>3) { $bbit = 4; }
19702 else { $bbit = $maxnum; }
19703 $maxlnum = $this->dec2roman($bbit,true);
19704 $blt_width = $this->GetStringWidth($maxlnum.$this->list_number_suffix);
19705 break;
19706 case 'i':
19707 $anum = $this->dec2roman($num,false);
19708 if ($this->listDir == 'rtl') { $list_item_marker = $this->list_number_suffix . $anum; }
19709 else { $list_item_marker = $anum . $this->list_number_suffix; }
19710
19711 if ($maxnum>87) { $bbit = 87; }
19712 else if ($maxnum>86) { $bbit = 86; }
19713 else if ($maxnum>37) { $bbit = 38; }
19714 else if ($maxnum>36) { $bbit = 37; }
19715 else if ($maxnum>27) { $bbit = 28; }
19716 else if ($maxnum>26) { $bbit = 27; }
19717 else if ($maxnum>17) { $bbit = 18; }
19718 else if ($maxnum>16) { $bbit = 17; }
19719 else if ($maxnum>7) { $bbit = 8; }
19720 else if ($maxnum>6) { $bbit = 7; }
19721 else if ($maxnum>3) { $bbit = 4; }
19722 else { $bbit = $maxnum; }
19723 $maxlnum = $this->dec2roman($bbit,false);
19724
19725 $blt_width = $this->GetStringWidth($maxlnum.$this->list_number_suffix);
19726 break;
19727 case 'disc':
19728 if ($this->PDFA || $this->PDFX) {
19729 if ($this->_charDefined($this->CurrentFont['cw'],8226)) { $list_item_marker = "\xe2\x80\xa2"; } // &#8226;
19730 else { $list_item_marker = '-'; }
19731 $blt_width = $this->GetCharWidth($list_item_marker);
19732 break;
19733 }
19734 $list_item_marker = chr(108); // bullet disc in Zapfdingbats 'l'
19735 $typefont = 'czapfdingbats';
19736 $blt_width = (0.791 * $this->FontSize/2.5);
19737 break;
19738 case 'circle':
19739 if ($this->PDFA || $this->PDFX) {
19740 if ($this->_charDefined($this->CurrentFont['cw'],9900)) { $list_item_marker = "\xe2\x9a\xac"; } // &#9900;
19741 else { $list_item_marker = '-'; }
19742 $blt_width = $this->GetCharWidth($list_item_marker);
19743 break;
19744 }
19745 $list_item_marker = chr(109); // circle in Zapfdingbats 'm'
19746 $typefont = 'czapfdingbats';
19747 $blt_width = (0.873 * $this->FontSize/2.5);
19748 break;
19749 case 'square':
19750 if ($this->PDFA || $this->PDFX) {
19751 if ($this->_charDefined($this->CurrentFont['cw'],9642)) { $list_item_marker = "\xe2\x96\xaa"; } // &#9642;
19752 else { $list_item_marker = '-'; }
19753 $blt_width = $this->GetCharWidth($list_item_marker);
19754 break;
19755 }
19756 $list_item_marker = chr(110); //black square in Zapfdingbats font 'n'
19757 $typefont = 'czapfdingbats';
19758 $blt_width = (0.761 * $this->FontSize/2.5);
19759 break;
19760
19761 /* CSS3 list-styles numeric + I added tamil
19762 arabic-indic | bengali | cambodian | devanagari | gujarati | gurmukhi | kannada | khmer | lao | malayalam | mongolian | myanmar | oriya | persian | telugu | tibetan | thai | urdu
19763 */
19764 case 'arabic-indic':
19765 $cp = 0x0660;
19766 $rnum = $this->dec2other($num, $cp);
19767 $list_item_marker = $this->list_number_suffix . $rnum; // RTL
19768 $blt_width = $this->GetStringWidth(str_repeat($this->dec2other(3, $cp),strlen($maxnum)).$this->list_number_suffix);
19769 break;
19770 case 'persian':
19771 case 'urdu':
19772 $cp = 0x06F0;
19773 $rnum = $this->dec2other($num, $cp);
19774 $list_item_marker = $this->list_number_suffix . $rnum; // RTL
19775 $blt_width = $this->GetStringWidth(str_repeat($this->dec2other(3, $cp),strlen($maxnum)).$this->list_number_suffix);
19776 break;
19777 case 'bengali':
19778 $cp = 0x09E6;
19779 $rnum = $this->dec2other($num, $cp);
19780 $list_item_marker = $rnum . $this->list_number_suffix;
19781 $blt_width = $this->GetStringWidth(str_repeat($this->dec2other(3, $cp),strlen($maxnum)).$this->list_number_suffix);
19782 break;
19783 case 'devanagari':
19784 $cp = 0x0966;
19785 $rnum = $this->dec2other($num, $cp);
19786 $list_item_marker = $rnum . $this->list_number_suffix;
19787 $blt_width = $this->GetStringWidth(str_repeat($this->dec2other(3, $cp),strlen($maxnum)).$this->list_number_suffix);
19788 break;
19789 case 'gujarati':
19790 $cp = 0x0AE6;
19791 $rnum = $this->dec2other($num, $cp);
19792 $list_item_marker = $rnum . $this->list_number_suffix;
19793 $blt_width = $this->GetStringWidth(str_repeat($this->dec2other(3, $cp),strlen($maxnum)).$this->list_number_suffix);
19794 break;
19795 case 'gurmukhi':
19796 $cp = 0x0A66;
19797 $rnum = $this->dec2other($num, $cp);
19798 $list_item_marker = $rnum . $this->list_number_suffix;
19799 $blt_width = $this->GetStringWidth(str_repeat($this->dec2other(3, $cp),strlen($maxnum)).$this->list_number_suffix);
19800 break;
19801 case 'kannada':
19802 $cp = 0x0CE6;
19803 $rnum = $this->dec2other($num, $cp);
19804 $list_item_marker = $rnum . $this->list_number_suffix;
19805 $blt_width = $this->GetStringWidth(str_repeat($this->dec2other(3, $cp),strlen($maxnum)).$this->list_number_suffix);
19806 break;
19807 case 'malayalam':
19808 $cp = 0x0D66;
19809 $rnum = $this->dec2other($num, $cp);
19810 $list_item_marker = $rnum . $this->list_number_suffix;
19811 $blt_width = $this->GetStringWidth(str_repeat($this->dec2other(6, $cp),strlen($maxnum)).$this->list_number_suffix);
19812 break;
19813 case 'oriya':
19814 $cp = 0x0B66;
19815 $rnum = $this->dec2other($num, $cp);
19816 $list_item_marker = $rnum . $this->list_number_suffix;
19817 $blt_width = $this->GetStringWidth(str_repeat($this->dec2other(3, $cp),strlen($maxnum)).$this->list_number_suffix);
19818 break;
19819 case 'telugu':
19820 $cp = 0x0C66;
19821 $rnum = $this->dec2other($num, $cp);
19822 $list_item_marker = $rnum . $this->list_number_suffix;
19823 $blt_width = $this->GetStringWidth(str_repeat($this->dec2other(3, $cp),strlen($maxnum)).$this->list_number_suffix);
19824 break;
19825 case 'tamil':
19826 $cp = 0x0BE6;
19827 $rnum = $this->dec2other($num, $cp);
19828 $list_item_marker = $rnum . $this->list_number_suffix;
19829 $blt_width = $this->GetStringWidth(str_repeat($this->dec2other(9, $cp),strlen($maxnum)).$this->list_number_suffix);
19830 break;
19831 case 'thai':
19832 $cp = 0x0E50;
19833 $rnum = $this->dec2other($num, $cp);
19834 $list_item_marker = $rnum . $this->list_number_suffix;
19835 $blt_width = $this->GetStringWidth(str_repeat($this->dec2other(5, $cp),strlen($maxnum)).$this->list_number_suffix);
19836 break;
19837 default:
19838 if ($this->listDir == 'rtl') { $list_item_marker = $this->list_number_suffix . $num; }
19839 else { $list_item_marker = $num . $this->list_number_suffix; }
19840 $blt_width = $this->GetStringWidth(str_repeat('5',strlen($maxnum)).$this->list_number_suffix);
19841 break;
19842 }
19843 }
19844
19845 if (isset($item[5]) && $item[5]) { $list_item_marker = ''; }
19846
19847 if ($currIndentLvl < $lvl) {
19848 if ($lvl > 1 || $this->list_indent_first_level) {
19849 $indent += $this->list_indent[$lvl][$occur];
19850 $lastIndent[$lvl] = $this->list_indent[$lvl][$occur];
19851 }
19852 }
19853 else if ($currIndentLvl > $lvl) {
19854 while ($currIndentLvl > $lvl) {
19855 $indent -= $lastIndent[$currIndentLvl];
19856 $currIndentLvl--;
19857 }
19858 }
19859 $currIndentLvl = $lvl;
19860
19861
19862 /*-- RTL --*/
19863
19864 if ($this->listDir == 'rtl') {
19865 // list_align_style Determines alignment of numbers in numbered lists
19866 if ($this->list_align_style == 'L') { $lalign = 'R'; }
19867 else { $lalign = 'L'; }
19868 $this->divwidth = $this->blk[$this->blklvl]['width'] - ($indent + $blt_width + $space_width) ;
19869 $xb = $this->blk[$this->blklvl]['inner_width'] + $this->blk[$this->blklvl]['border_left']['w'] + $this->blk[$this->blklvl]['padding_left'] - $indent - $blt_width; //Bullet position (relative)
19870 //Output bullet
19871 $this->bulletarray = array('w'=>$blt_width,'h'=>$clh,'txt'=>$list_item_marker,'x'=>$xb,'align'=>$lalign,'font'=>$typefont,'level'=>$lvl, 'occur'=>$occur, 'num'=>$num, 'fontsize'=>$bullfs, 'col'=>$list_item_color );
19872 $this->x = $x;
19873 }
19874 else {
19875 /*-- END RTL --*/
19876
19877 if ($this->list_align_style == 'L') { $lalign = 'L'; }
19878 else { $lalign = 'R'; }
19879 $this->divwidth = $this->blk[$this->blklvl]['width'] - ($indent + $blt_width + $space_width) ;
19880 $xb = $this->blk[$this->blklvl]['padding_left'] + $this->blk[$this->blklvl]['border_left']['w'] - $blt_width - $space_width;
19881 //Output bullet
19882 $this->bulletarray = array('w'=>$blt_width,'h'=>$clh,'txt'=>$list_item_marker,'x'=>$xb,'align'=>$lalign,'font'=>$typefont,'level'=>$lvl, 'occur'=>$occur, 'num'=>$num, 'fontsize'=>$bullfs, 'col'=>$list_item_color );
19883 $this->x = $x + $indent + $blt_width + $space_width;
19884 } // *RTL*
19885
19886 //Print content
19887 $this->printbuffer($this->textbuffer,'',false,true);
19888 $this->textbuffer=array();
19889
19890 // Added to correct for OddEven Margins
19891 if ($this->page != $bak_page) {
19892 if (($this->page-$bak_page) % 2 == 1) {
19893 $x += $this->MarginCorrection;
19894 }
19895 $bak_page = $this->page;
19896 }
19897 /*-- COLUMNS --*/
19898 // OR COLUMN CHANGE
19899 if ($this->CurrCol != $oldcolumn) {
19900 if ($this->directionality == 'rtl') { // *RTL*
19901 $x -= ($this->CurrCol - $oldcolumn) * ($this->ColWidth+$this->ColGap); // *RTL*
19902 } // *RTL*
19903 else { // *RTL*
19904 $x += ($this->CurrCol - $oldcolumn) * ($this->ColWidth+$this->ColGap);
19905 } // *RTL*
19906 $oldcolumn = $this->CurrCol;
19907 }
19908 /*-- END COLUMNS --*/
19909
19910 }
19911
19912 //Reset all used values
19913 $this->listoccur = array();
19914 $this->listitem = array();
19915 $this->listlist = array();
19916 $this->listlvl = 0;
19917 $this->listnum = 0;
19918 $this->listtype = '';
19919 $this->textbuffer = array();
19920 $this->divwidth = 0;
19921 $this->divheight = 0;
19922 $this->x = $this->lMargin + $this->blk[$this->blklvl]['outer_left_margin'];
19923 }
19924 /*-- END LISTS --*/
19925
19926 function _saveTextBuffer($t, $link = '', $intlink = '') {
19927 // $this->textbuffer[] = array($t,$link,$this->currentfontstyle,$this->colorarray,$this->currentfontfamily,$this->SUP,$this->SUB,$intlink,$this->strike,$this->textparam,$this->spanbgcolorarray,$this->currentfontsize,$this->ReqFontStyle,$this->kerning,$this->lSpacingCSS,$this->wSpacingCSS,$this->spanborddet, $this->textshadow);
19928 // mPDF 5.6.14
19929 $arr = array();
19930 $arr[0] = $t;
19931 if (isset($link) && $link) $arr[1] = $link;
19932 $arr[2] = $this->currentfontstyle;
19933 if (isset($this->colorarray) && $this->colorarray) $arr[3] = $this->colorarray;
19934 $arr[4] = $this->currentfontfamily;
19935 if (isset($this->SUP) && $this->SUP) $arr[5] = $this->SUP;
19936 if (isset($this->SUB) && $this->SUB) $arr[6] = $this->SUB;
19937 if (isset($intlink) && $intlink) $arr[7] = $intlink;
19938 if (isset($this->strike) && $this->strike) $arr[8] = $this->strike;
19939 if (isset($this->textparam) && $this->textparam) $arr[9] = $this->textparam;
19940 if (isset($this->spanbgcolorarray) && $this->spanbgcolorarray) $arr[10] = $this->spanbgcolorarray;
19941 $arr[11] = $this->currentfontsize;
19942 if (isset($this->ReqFontStyle) && $this->ReqFontStyle) $arr[12] = $this->ReqFontStyle;
19943 if (isset($this->kerning) && $this->kerning) $arr[13] = $this->kerning;
19944 if (isset($this->lSpacingCSS) && $this->lSpacingCSS) $arr[14] = $this->lSpacingCSS;
19945 if (isset($this->wSpacingCSS) && $this->wSpacingCSS) $arr[15] = $this->wSpacingCSS;
19946 if (isset($this->spanborddet) && $this->spanborddet) $arr[16] = $this->spanborddet;
19947 if (isset($this->textshadow) && $this->textshadow) $arr[17] = $this->textshadow;
19948 $this->textbuffer[] = $arr;
19949 }
19950
19951 function _saveCellTextBuffer($t, $link = '', $intlink = '') {
19952 // $this->cell[$this->row][$this->col]['textbuffer'][] = array($t,$link,$this->currentfontstyle,$this->colorarray,$this->currentfontfamily,$this->SUP,$this->SUB,$intlink,$this->strike,$this->textparam,$this->spanbgcolorarray,$this->currentfontsize,$this->ReqFontStyle,$this->kerning,$this->lSpacingCSS,$this->wSpacingCSS,$this->spanborddet, $this->textshadow);
19953 // mPDF 5.6.14
19954 $arr = array();
19955 $arr[0] = $t;
19956 if (isset($link) && $link) $arr[1] = $link;
19957 $arr[2] = $this->currentfontstyle;
19958 if (isset($this->colorarray) && $this->colorarray) $arr[3] = $this->colorarray;
19959 $arr[4] = $this->currentfontfamily;
19960 if (isset($this->SUP) && $this->SUP) $arr[5] = $this->SUP;
19961 if (isset($this->SUB) && $this->SUB) $arr[6] = $this->SUB;
19962 if (isset($intlink) && $intlink) $arr[7] = $intlink;
19963 if (isset($this->strike) && $this->strike) $arr[8] = $this->strike;
19964 if (isset($this->textparam) && $this->textparam) $arr[9] = $this->textparam;
19965 if (isset($this->spanbgcolorarray) && $this->spanbgcolorarray) $arr[10] = $this->spanbgcolorarray;
19966 $arr[11] = $this->currentfontsize;
19967 if (isset($this->ReqFontStyle) && $this->ReqFontStyle) $arr[12] = $this->ReqFontStyle;
19968 if (isset($this->kerning) && $this->kerning) $arr[13] = $this->kerning;
19969 if (isset($this->lSpacingCSS) && $this->lSpacingCSS) $arr[14] = $this->lSpacingCSS;
19970 if (isset($this->wSpacingCSS) && $this->wSpacingCSS) $arr[15] = $this->wSpacingCSS;
19971 if (isset($this->spanborddet) && $this->spanborddet) $arr[16] = $this->spanborddet;
19972 if (isset($this->textshadow) && $this->textshadow) $arr[17] = $this->textshadow;
19973 $this->cell[$this->row][$this->col]['textbuffer'][] = $arr;
19974 }
19975
19976
19977 function printbuffer($arrayaux,$blockstate=0,$is_table=false,$is_list=false)
19978 {
19979 // $blockstate = 0; // NO margins/padding
19980 // $blockstate = 1; // Top margins/padding only
19981 // $blockstate = 2; // Bottom margins/padding only
19982 // $blockstate = 3; // Top & bottom margins/padding
19983 $this->spanbgcolorarray = '';
19984 $this->spanbgcolor = false;
19985 $this->spanborder = false;
19986 $this->spanborddet = array();
19987 $paint_ht_corr = 0;
19988
19989 /*-- CSS-FLOAT --*/
19990 if (count($this->floatDivs)) {
19991 list($l_exists, $r_exists, $l_max, $r_max, $l_width, $r_width) = $this->GetFloatDivInfo($this->blklvl);
19992 if (($this->blk[$this->blklvl]['inner_width']-$l_width-$r_width) < (2*$this->GetCharWidth('W',false))) {
19993 // Too narrow to fit - try to move down past L or R float
19994 if ($l_max < $r_max && ($this->blk[$this->blklvl]['inner_width']-$r_width) > (2*$this->GetCharWidth('W',false))) {
19995 $this->ClearFloats('LEFT', $this->blklvl);
19996 }
19997 else if ($r_max < $l_max && ($this->blk[$this->blklvl]['inner_width']-$l_width) > (2*$this->GetCharWidth('W',false))) {
19998 $this->ClearFloats('RIGHT', $this->blklvl);
19999 }
20000 else { $this->ClearFloats('BOTH', $this->blklvl); }
20001 }
20002 }
20003 /*-- END CSS-FLOAT --*/
20004 $bak_y = $this->y;
20005 $bak_x = $this->x;
20006 $align = '';
20007 if (!$is_table && !$is_list) {
20008 if (isset($this->blk[$this->blklvl]['align']) && $this->blk[$this->blklvl]['align']) { $align = $this->blk[$this->blklvl]['align']; }
20009 // Block-align is set by e.g. <.. align="center"> Takes priority for this block but not inherited
20010 if (isset($this->blk[$this->blklvl]['block-align']) && $this->blk[$this->blklvl]['block-align']) { $align = $this->blk[$this->blklvl]['block-align']; }
20011 if (isset($this->blk[$this->blklvl]['direction'])) $blockdir = $this->blk[$this->blklvl]['direction'];
20012 else $blockdir = "";
20013 $this->divwidth = $this->blk[$this->blklvl]['width'];
20014 }
20015 else {
20016 $align = $this->divalign;
20017 if ($is_table) { $blockdir = $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['direction']; }
20018 else { $blockdir = $this->listDir; }
20019 }
20020 $oldpage = $this->page;
20021
20022 // ADDED for Out of Block now done as Flowing Block
20023 if ($this->divwidth == 0) {
20024 $this->divwidth = $this->pgwidth;
20025 }
20026
20027 if (!$is_table && !$is_list) { $this->SetLineHeight($this->FontSizePt,$this->blk[$this->blklvl]['line_height']); }
20028 $this->divheight = $this->lineheight;
20029 $old_height = $this->divheight;
20030
20031 // As a failsafe - if font has been set but not output to page
20032 $this->SetFont($this->default_font,'',$this->default_font_size,true,true); // force output to page
20033
20034 $array_size = count($arrayaux);
20035 $this->newFlowingBlock( $this->divwidth,$this->divheight,$align,$is_table,$is_list,$blockstate,true,$blockdir);
20036
20037 // Added - Otherwise <div><div><p> did not output top margins/padding for 1st/2nd div
20038 if ($array_size == 0) { $this->finishFlowingBlock(true); } // true = END of flowing block
20039
20040 for($i=0;$i < $array_size; $i++)
20041 {
20042 // COLS
20043 $oldcolumn = $this->CurrCol;
20044
20045 $vetor = $arrayaux[$i];
20046 if ($i == 0 and $vetor[0] != "\n" and !$this->ispre) {
20047 $vetor[0] = ltrim($vetor[0]);
20048 }
20049
20050 // FIXED TO ALLOW IT TO SHOW '0'
20051 if (empty($vetor[0]) && !($vetor[0]==='0') && empty($vetor[7])) { //Ignore empty text and not carrying an internal link
20052 //Check if it is the last element. If so then finish printing the block
20053 if ($i == ($array_size-1)) { $this->finishFlowingBlock(true); } // true = END of flowing block
20054 continue;
20055 }
20056
20057
20058 //Activating buffer properties
20059 if(isset($vetor[11]) and $vetor[11] != '') { // Font Size
20060 if ($is_table && $this->shrin_k) {
20061 $this->SetFontSize($vetor[11]/$this->shrin_k,false);
20062 }
20063 else {
20064 $this->SetFontSize($vetor[11],false);
20065 }
20066 }
20067
20068 if(isset($vetor[17]) && !empty($vetor[17])) { //TextShadow
20069 $this->textshadow = $vetor[17];
20070 }
20071 if(isset($vetor[16]) && !empty($vetor[16])) { //Border
20072 $this->spanborddet = $vetor[16];
20073 $this->spanborder = true;
20074 }
20075
20076 if(isset($vetor[15])) { // Word spacing
20077 $this->wSpacingCSS = $vetor[15];
20078 if ($this->wSpacingCSS && strtoupper($this->wSpacingCSS) != 'NORMAL') {
20079 $this->minwSpacing = $this->ConvertSize($this->wSpacingCSS,$this->FontSize);
20080 }
20081 }
20082 if(isset($vetor[14])) { // Letter spacing
20083 $this->lSpacingCSS = $vetor[14];
20084 if (($this->lSpacingCSS || $this->lSpacingCSS==='0') && strtoupper($this->lSpacingCSS) != 'NORMAL') {
20085 $this->fixedlSpacing = $this->ConvertSize($this->lSpacingCSS,$this->FontSize);
20086 }
20087 }
20088 if(isset($vetor[13])) { // Font Kerning
20089 $this->kerning = $vetor[13];
20090 }
20091
20092
20093 if(isset($vetor[10]) and !empty($vetor[10])) //Background color
20094 {
20095 $this->spanbgcolorarray = $vetor[10];
20096 $this->spanbgcolor = true;
20097 }
20098 if(isset($vetor[9]) and !empty($vetor[9])) // Text parameters - Outline + hyphens
20099 {
20100 $this->textparam = $vetor[9] ; // mPDF 5.6.14
20101 $this->SetTextOutline($this->textparam); // mPDF 5.6.07
20102 }
20103 if(isset($vetor[8]) and $vetor[8] === true) // strike-through the text
20104 {
20105 $this->strike = true;
20106 }
20107 if(isset($vetor[7]) and $vetor[7] != '') // internal target: <a name="anyvalue">
20108 {
20109 $ily = $this->y;
20110 if ($this->keep_block_together) { $this->internallink[$vetor[7]] = array("Y"=>$ily,"PAGE"=>$this->page, "kt"=>true ); }
20111 else if ($this->table_rotate) { $this->internallink[$vetor[7]] = array("Y"=>$ily,"PAGE"=>$this->page, "tbrot"=>true ); }
20112 else if ($this->kwt) { $this->internallink[$vetor[7]] = array("Y"=>$ily,"PAGE"=>$this->page, "kwt"=>true ); }
20113 else if ($this->ColActive) { $this->internallink[$vetor[7]] = array("Y"=>$ily,"PAGE"=>$this->page, "col"=>$this->CurrCol ); }
20114 else
20115 $this->internallink[$vetor[7]] = array("Y"=>$ily,"PAGE"=>$this->page );
20116 if (empty($vetor[0])) { //Ignore empty text
20117 //Check if it is the last element. If so then finish printing the block
20118 if ($i == ($array_size-1)) { $this->finishFlowingBlock(true); } // true = END of flowing block
20119 continue;
20120 }
20121 }
20122 if(isset($vetor[6]) and $vetor[6] === true) // Subscript
20123 {
20124 $this->SUB = true;
20125 }
20126 if(isset($vetor[5]) and $vetor[5] === true) // Superscript
20127 {
20128 $this->SUP = true;
20129 }
20130 if(isset($vetor[4]) and $vetor[4] != '') { // Font Family
20131 $font = $this->SetFont($vetor[4],$this->FontStyle,0,false);
20132 }
20133 if (!empty($vetor[3])) //Font Color
20134 {
20135 $cor = $vetor[3];
20136 $this->SetTColor($cor);
20137 }
20138 if(isset($vetor[2]) and $vetor[2] != '') //Bold,Italic,Underline styles
20139 {
20140 $this->SetStyles($vetor[2]);
20141 }
20142
20143 if(isset($vetor[12]) and $vetor[12] != '') { //Requested Bold,Italic,Underline
20144 $this->ReqFontStyle = $vetor[12];
20145 }
20146 if(isset($vetor[1]) and $vetor[1] != '') //LINK
20147 {
20148 if (strpos($vetor[1],".") === false && strpos($vetor[1],"@") !== 0) //assuming every external link has a dot indicating extension (e.g: .html .txt .zip www.somewhere.com etc.)
20149 {
20150 //Repeated reference to same anchor?
20151 while(array_key_exists($vetor[1],$this->internallink)) $vetor[1]="#".$vetor[1];
20152 $this->internallink[$vetor[1]] = $this->AddLink();
20153 $vetor[1] = $this->internallink[$vetor[1]];
20154 }
20155 $this->HREF = $vetor[1]; // HREF link style set here ******
20156 }
20157
20158 // SPECIAL CONTENT - IMAGES & FORM OBJECTS
20159 //Print-out special content
20160
20161 if (substr($vetor[0],0,3) == "\xbb\xa4\xac") { //identifier has been identified!
20162
20163 $objattr = $this->_getObjAttr($vetor[0]);
20164
20165 /*-- TABLES --*/
20166 if ($objattr['type'] == 'nestedtable') {
20167 if ($objattr['nestedcontent']) {
20168 $level = $objattr['level'];
20169 $table = &$this->table[$level][$objattr['table']];
20170 if ($this->cacheTables) {
20171 $fh = fopen($table['cache'], "r+b");
20172 $cell = $this->_uncacheCell($table['cells'][$objattr['row']][$objattr['col']], '', $fh);
20173 }
20174 else {
20175 $fh = null;
20176 $cell = &$table['cells'][$objattr['row']][$objattr['col']];
20177 }
20178 $this->finishFlowingBlock(false,'nestedtable');
20179 $save_dw = $this->divwidth ;
20180 $save_buffer = $this->cellBorderBuffer;
20181 $this->cellBorderBuffer = array();
20182 $ncx = $this->x;
20183 list($dummyx,$w) = $this->_tableGetWidth($table, $objattr['row'], $objattr['col'], $fh);
20184 $ntw = $this->table[($level+1)][$objattr['nestedcontent']]['w']; // nested table width
20185 if (!$this->simpleTables){
20186 if ($this->packTableData) {
20187 list($bt,$br,$bb,$bl) = $this->_getBorderWidths($cell['borderbin']);
20188 }
20189 else {
20190 $br = $cell['border_details']['R']['w'];
20191 $bl = $cell['border_details']['L']['w'];
20192 }
20193 if ($table['borders_separate']) {
20194 $innerw = $w - $bl - $br - $cell['padding']['L'] - $cell['padding']['R'] - $table['border_spacing_H'];
20195 }
20196 else {
20197 $innerw = $w - $bl/2 - $br/2 - $cell['padding']['L'] - $cell['padding']['R'];
20198 }
20199 }
20200 else if ($this->simpleTables){
20201 if ($table['borders_separate']) {
20202 $innerw = $w - $table['simple']['border_details']['L']['w'] - $table['simple']['border_details']['R']['w'] - $cell['padding']['L'] - $cell['padding']['R'] - $table['border_spacing_H'];
20203 }
20204 else {
20205 $innerw = $w - $table['simple']['border_details']['L']['w']/2 - $table['simple']['border_details']['R']['w']/2 - $cell['padding']['L'] - $cell['padding']['R'];
20206 }
20207 }
20208 if ($cell['a']=='C' || $this->table[($level+1)][$objattr['nestedcontent']]['a']=='C') {
20209 $ncx += ($innerw-$ntw)/2;
20210 }
20211 elseif ($cell['a']=='R' || $this->table[($level+1)][$objattr['nestedcontent']]['a']=='R') {
20212 $ncx += $innerw- $ntw;
20213 }
20214 $this->x = $ncx ;
20215 if ($this->cacheTables) { fclose($fh); }
20216
20217 $this->_tableWrite($this->table[($level+1)][$objattr['nestedcontent']]);
20218 $this->cellBorderBuffer = $save_buffer;
20219 $this->x = $bak_x ;
20220 $this->divwidth = $save_dw;
20221 $this->newFlowingBlock( $this->divwidth,$this->divheight,$align,$is_table,$is_list,$blockstate,false,$blockdir);
20222 }
20223 }
20224 else {
20225 /*-- END TABLES --*/
20226 if ($is_table) { // *TABLES*
20227 $maxWidth = $this->divwidth; // *TABLES*
20228 } // *TABLES*
20229 else { // *TABLES*
20230 $maxWidth = $this->divwidth - ($this->blk[$this->blklvl]['padding_left'] + $this->blk[$this->blklvl]['border_left']['w'] + $this->blk[$this->blklvl]['padding_right'] + $this->blk[$this->blklvl]['border_right']['w']);
20231 } // *TABLES*
20232
20233 /*-- CSS-IMAGE-FLOAT --*/
20234 // If float (already) exists at this level
20235 if (isset($this->floatmargins['R']) && $this->y <= $this->floatmargins['R']['y1'] && $this->y >= $this->floatmargins['R']['y0']) { $maxWidth -= $this->floatmargins['R']['w']; }
20236 if (isset($this->floatmargins['L']) && $this->y <= $this->floatmargins['L']['y1'] && $this->y >= $this->floatmargins['L']['y0']) { $maxWidth -= $this->floatmargins['L']['w']; }
20237 /*-- END CSS-IMAGE-FLOAT --*/
20238
20239 list($skipln) = $this->inlineObject($objattr['type'], '', $this->y, $objattr,$this->lMargin, ($this->flowingBlockAttr['contentWidth']/_MPDFK), $maxWidth, $this->flowingBlockAttr['height'], false, $is_table);
20240 // 1 -> New line needed because of width
20241 // -1 -> Will fit width on line but NEW PAGE REQUIRED because of height
20242 // -2 -> Will not fit on line therefore needs new line but thus NEW PAGE REQUIRED
20243 $iby = $this->y;
20244 $oldpage = $this->page;
20245 $oldcol = $this->CurrCol;
20246 if (($skipln == 1 || $skipln == -2) && !isset($objattr['float'])) {
20247 $this->finishFlowingBlock(false,$objattr['type']);
20248 $this->newFlowingBlock( $this->divwidth,$this->divheight,$align,$is_table,$is_list,$blockstate,false,$blockdir);
20249 }
20250 $thispage = $this->page;
20251 if ($this->CurrCol!=$oldcol) { $changedcol = true; }
20252 else { $changedcol=false; }
20253
20254 // the previous lines can already have triggered page break or column change
20255 if (!$changedcol && $skipln <0 && $this->AcceptPageBreak() && $thispage==$oldpage) {
20256
20257 $this->AddPage($this->CurOrientation);
20258
20259 // Added to correct Images already set on line before page advanced
20260 // i.e. if second inline image on line is higher than first and forces new page
20261 if (count($this->objectbuffer)) {
20262 $yadj = $iby - $this->y;
20263 foreach($this->objectbuffer AS $ib=>$val) {
20264 if ($this->objectbuffer[$ib]['OUTER-Y'] ) $this->objectbuffer[$ib]['OUTER-Y'] -= $yadj;
20265 if ($this->objectbuffer[$ib]['BORDER-Y']) $this->objectbuffer[$ib]['BORDER-Y'] -= $yadj;
20266 if ($this->objectbuffer[$ib]['INNER-Y']) $this->objectbuffer[$ib]['INNER-Y'] -= $yadj;
20267 }
20268 }
20269 }
20270
20271 // Added to correct for OddEven Margins
20272 if ($this->page != $oldpage) {
20273 if (($this->page-$oldpage) % 2 == 1) {
20274 $bak_x += $this->MarginCorrection;
20275 }
20276 $oldpage = $this->page;
20277 $y = $this->tMargin - $paint_ht_corr ;
20278 $this->oldy = $this->tMargin - $paint_ht_corr ;
20279 $old_height = 0;
20280 }
20281 $this->x = $bak_x;
20282 /*-- COLUMNS --*/
20283 // COLS
20284 // OR COLUMN CHANGE
20285 if ($this->CurrCol != $oldcolumn) {
20286 if ($this->directionality == 'rtl') { // *RTL*
20287 $bak_x -= ($this->CurrCol - $oldcolumn) * ($this->ColWidth+$this->ColGap); // *RTL*
20288 } // *RTL*
20289 else { // *RTL*
20290 $bak_x += ($this->CurrCol - $oldcolumn) * ($this->ColWidth+$this->ColGap);
20291 } // *RTL*
20292 $this->x = $bak_x;
20293 $oldcolumn = $this->CurrCol;
20294 $y = $this->y0 - $paint_ht_corr ;
20295 $this->oldy = $this->y0 - $paint_ht_corr ;
20296 $old_height = 0;
20297 }
20298 /*-- END COLUMNS --*/
20299
20300 /*-- CSS-IMAGE-FLOAT --*/
20301 if ($objattr['type'] == 'image' && isset($objattr['float'])) {
20302 $fy = $this->y;
20303
20304 // DIV TOP MARGIN/BORDER/PADDING
20305 if ($this->flowingBlockAttr['newblock'] && ($this->flowingBlockAttr['blockstate']==1 || $this->flowingBlockAttr['blockstate']==3) && $this->flowingBlockAttr['lineCount']== 0) {
20306 $fy += $this->blk[$this->blklvl]['margin_top'] + $this->blk[$this->blklvl]['padding_top'] + $this->blk[$this->blklvl]['border_top']['w'];
20307 }
20308
20309 if ($objattr['float']=='R') {
20310 $fx = $this->w - $this->rMargin - $objattr['width'] - ($this->blk[$this->blklvl]['outer_right_margin'] + $this->blk[$this->blklvl]['border_right']['w'] + $this->blk[$this->blklvl]['padding_right']);
20311
20312
20313 }
20314 else if ($objattr['float']=='L') {
20315 $fx = $this->lMargin + ($this->blk[$this->blklvl]['outer_left_margin'] + $this->blk[$this->blklvl]['border_left']['w'] + $this->blk[$this->blklvl]['padding_left']);
20316 }
20317 $w = $objattr['width'];
20318 $h = abs($objattr['height']);
20319
20320 $widthLeft = $maxWidth - ($this->flowingBlockAttr['contentWidth']/_MPDFK);
20321 $maxHeight = $this->h - ($this->tMargin + $this->margin_header + $this->bMargin + 10) ;
20322 // For Images
20323 $extraWidth = ($objattr['border_left']['w'] + $objattr['border_right']['w'] + $objattr['margin_left']+ $objattr['margin_right']);
20324 $extraHeight = ($objattr['border_top']['w'] + $objattr['border_bottom']['w'] + $objattr['margin_top']+ $objattr['margin_bottom']);
20325
20326 if ($objattr['itype'] == 'wmf' || $objattr['itype'] == 'svg') {
20327 $file = $objattr['file'];
20328 $info=$this->formobjects[$file];
20329 }
20330 else {
20331 $file = $objattr['file'];
20332 $info=$this->images[$file];
20333 }
20334 $img_w = $w - $extraWidth ;
20335 $img_h = $h - $extraHeight ;
20336 if ($objattr['border_left']['w']) {
20337 $objattr['BORDER-WIDTH'] = $img_w + (($objattr['border_left']['w'] + $objattr['border_right']['w'])/2) ;
20338 $objattr['BORDER-HEIGHT'] = $img_h + (($objattr['border_top']['w'] + $objattr['border_bottom']['w'])/2) ;
20339 $objattr['BORDER-X'] = $fx + $objattr['margin_left'] + (($objattr['border_left']['w'])/2) ;
20340 $objattr['BORDER-Y'] = $fy + $objattr['margin_top'] + (($objattr['border_top']['w'])/2) ;
20341 }
20342 $objattr['INNER-WIDTH'] = $img_w;
20343 $objattr['INNER-HEIGHT'] = $img_h;
20344 $objattr['INNER-X'] = $fx + $objattr['margin_left'] + ($objattr['border_left']['w']);
20345 $objattr['INNER-Y'] = $fy + $objattr['margin_top'] + ($objattr['border_top']['w']) ;
20346 $objattr['ID'] = $info['i'];
20347 $objattr['OUTER-WIDTH'] = $w;
20348 $objattr['OUTER-HEIGHT'] = $h;
20349 $objattr['OUTER-X'] = $fx;
20350 $objattr['OUTER-Y'] = $fy;
20351 if ($objattr['float']=='R') {
20352 // If R float already exists at this level
20353 $this->floatmargins['R']['skipline'] = false;
20354 if (isset($this->floatmargins['R']['y1']) && $this->floatmargins['R']['y1'] > 0 && $fy < $this->floatmargins['R']['y1']) {
20355 $this->WriteFlowingBlock($vetor[0]);
20356 }
20357 // If L float already exists at this level
20358 else if (isset($this->floatmargins['L']['y1']) && $this->floatmargins['L']['y1'] > 0 && $fy < $this->floatmargins['L']['y1']) {
20359 // Final check distance between floats is not now too narrow to fit text
20360 $mw = 2*$this->GetCharWidth('W',false);
20361 if (($this->blk[$this->blklvl]['inner_width'] - $w - $this->floatmargins['L']['w']) < $mw) {
20362 $this->WriteFlowingBlock($vetor[0]);
20363 }
20364 else {
20365 $this->floatmargins['R']['x'] = $fx;
20366 $this->floatmargins['R']['w'] = $w;
20367 $this->floatmargins['R']['y0'] = $fy;
20368 $this->floatmargins['R']['y1'] = $fy + $h;
20369 if ($skipln == 1) {
20370 $this->floatmargins['R']['skipline'] = true;
20371 $this->floatmargins['R']['id'] = count($this->floatbuffer)+0;
20372 $objattr['skipline'] = true;
20373 }
20374 $this->floatbuffer[] = $objattr;
20375 }
20376 }
20377 else {
20378 $this->floatmargins['R']['x'] = $fx;
20379 $this->floatmargins['R']['w'] = $w;
20380 $this->floatmargins['R']['y0'] = $fy;
20381 $this->floatmargins['R']['y1'] = $fy + $h;
20382 if ($skipln == 1) {
20383 $this->floatmargins['R']['skipline'] = true;
20384 $this->floatmargins['R']['id'] = count($this->floatbuffer)+0;
20385 $objattr['skipline'] = true;
20386 }
20387 $this->floatbuffer[] = $objattr;
20388 }
20389 }
20390 else if ($objattr['float']=='L') {
20391 // If L float already exists at this level
20392 $this->floatmargins['L']['skipline'] = false;
20393 if (isset($this->floatmargins['L']['y1']) && $this->floatmargins['L']['y1'] > 0 && $fy < $this->floatmargins['L']['y1']) {
20394 $this->floatmargins['L']['skipline'] = false;
20395 $this->WriteFlowingBlock($vetor[0]);
20396 }
20397 // If R float already exists at this level
20398 else if (isset($this->floatmargins['R']['y1']) && $this->floatmargins['R']['y1'] > 0 && $fy < $this->floatmargins['R']['y1']) {
20399 // Final check distance between floats is not now too narrow to fit text
20400 $mw = 2*$this->GetCharWidth('W',false);
20401 if (($this->blk[$this->blklvl]['inner_width'] - $w - $this->floatmargins['R']['w']) < $mw) {
20402 $this->WriteFlowingBlock($vetor[0]);
20403 }
20404 else {
20405 $this->floatmargins['L']['x'] = $fx + $w;
20406 $this->floatmargins['L']['w'] = $w;
20407 $this->floatmargins['L']['y0'] = $fy;
20408 $this->floatmargins['L']['y1'] = $fy + $h;
20409 if ($skipln == 1) {
20410 $this->floatmargins['L']['skipline'] = true;
20411 $this->floatmargins['L']['id'] = count($this->floatbuffer)+0;
20412 $objattr['skipline'] = true;
20413 }
20414 $this->floatbuffer[] = $objattr;
20415 }
20416 }
20417 else {
20418 $this->floatmargins['L']['x'] = $fx + $w;
20419 $this->floatmargins['L']['w'] = $w;
20420 $this->floatmargins['L']['y0'] = $fy;
20421 $this->floatmargins['L']['y1'] = $fy + $h;
20422 if ($skipln == 1) {
20423 $this->floatmargins['L']['skipline'] = true;
20424 $this->floatmargins['L']['id'] = count($this->floatbuffer)+0;
20425 $objattr['skipline'] = true;
20426 }
20427 $this->floatbuffer[] = $objattr;
20428 }
20429 }
20430 }
20431 else {
20432 /*-- END CSS-IMAGE-FLOAT --*/
20433 $this->WriteFlowingBlock($vetor[0]);
20434 /*-- CSS-IMAGE-FLOAT --*/
20435 }
20436 /*-- END CSS-IMAGE-FLOAT --*/
20437 } // *TABLES*
20438
20439 } // END If special content
20440 else { //THE text
20441 if ($this->tableLevel) { $paint_ht_corr = 0; } // To move the y up when new column/page started if div border needed
20442 else { $paint_ht_corr = $this->blk[$this->blklvl]['border_top']['w']; }
20443
20444 if ($vetor[0] == "\n") { //We are reading a <BR> now turned into newline ("\n")
20445 if ($this->flowingBlockAttr['content']) {
20446 $this->finishFlowingBlock(false,'br');
20447 }
20448 else if ($is_table) {
20449 $this->y+= $this->_computeLineheight($this->table_lineheight);
20450 }
20451 else if (!$is_table) {
20452 $this->DivLn($this->lineheight);
20453 if ($this->ColActive) { $this->breakpoints[$this->CurrCol][] = $this->y; } // *COLUMNS*
20454 }
20455 // Added to correct for OddEven Margins
20456 if ($this->page != $oldpage) {
20457 if (($this->page-$oldpage) % 2 == 1) {
20458 $bak_x += $this->MarginCorrection;
20459 }
20460 $oldpage = $this->page;
20461 $y = $this->tMargin - $paint_ht_corr ;
20462 $this->oldy = $this->tMargin - $paint_ht_corr ;
20463 $old_height = 0;
20464 }
20465 $this->x = $bak_x;
20466 /*-- COLUMNS --*/
20467 // COLS
20468 // OR COLUMN CHANGE
20469 if ($this->CurrCol != $oldcolumn) {
20470 if ($this->directionality == 'rtl') { // *RTL*
20471 $bak_x -= ($this->CurrCol - $oldcolumn) * ($this->ColWidth+$this->ColGap); // *RTL*
20472 } // *RTL*
20473 else { // *RTL*
20474 $bak_x += ($this->CurrCol - $oldcolumn) * ($this->ColWidth+$this->ColGap);
20475 } // *RTL*
20476 $this->x = $bak_x;
20477 $oldcolumn = $this->CurrCol;
20478 $y = $this->y0 - $paint_ht_corr ;
20479 $this->oldy = $this->y0 - $paint_ht_corr ;
20480 $old_height = 0;
20481 }
20482 /*-- END COLUMNS --*/
20483 $this->newFlowingBlock( $this->divwidth,$this->divheight,$align,$is_table,$is_list,$blockstate,false,$blockdir);
20484 }
20485 else {
20486 $this->WriteFlowingBlock( $vetor[0]);
20487
20488 // Added to correct for OddEven Margins
20489 if ($this->page != $oldpage) {
20490 if (($this->page-$oldpage) % 2 == 1) {
20491 $bak_x += $this->MarginCorrection;
20492 $this->x = $bak_x;
20493 }
20494 $oldpage = $this->page;
20495 $y = $this->tMargin - $paint_ht_corr ;
20496 $this->oldy = $this->tMargin - $paint_ht_corr ;
20497 $old_height = 0;
20498 }
20499 /*-- COLUMNS --*/
20500 // COLS
20501 // OR COLUMN CHANGE
20502 if ($this->CurrCol != $oldcolumn) {
20503 if ($this->directionality == 'rtl') { // *RTL*
20504 $bak_x -= ($this->CurrCol - $oldcolumn) * ($this->ColWidth+$this->ColGap); // *RTL*
20505 } // *RTL*
20506 else { // *RTL*
20507 $bak_x += ($this->CurrCol - $oldcolumn) * ($this->ColWidth+$this->ColGap);
20508 } // *RTL*
20509 $this->x = $bak_x;
20510 $oldcolumn = $this->CurrCol;
20511 $y = $this->y0 - $paint_ht_corr ;
20512 $this->oldy = $this->y0 - $paint_ht_corr ;
20513 $old_height = 0;
20514 }
20515 /*-- END COLUMNS --*/
20516 }
20517
20518
20519 }
20520
20521 //Check if it is the last element. If so then finish printing the block
20522 if ($i == ($array_size-1)) {
20523 $this->finishFlowingBlock(true); // true = END of flowing block
20524 // Added to correct for OddEven Margins
20525 if ($this->page != $oldpage) {
20526 if (($this->page-$oldpage) % 2 == 1) {
20527 $bak_x += $this->MarginCorrection;
20528 $this->x = $bak_x;
20529 }
20530 $oldpage = $this->page;
20531 $y = $this->tMargin - $paint_ht_corr ;
20532 $this->oldy = $this->tMargin - $paint_ht_corr ;
20533 $old_height = 0;
20534 }
20535
20536 /*-- COLUMNS --*/
20537 // COLS
20538 // OR COLUMN CHANGE
20539 if ($this->CurrCol != $oldcolumn) {
20540 if ($this->directionality == 'rtl') { // *RTL*
20541 $bak_x -= ($this->CurrCol - $oldcolumn) * ($this->ColWidth+$this->ColGap); // *RTL*
20542 } // *RTL*
20543 else { // *RTL*
20544 $bak_x += ($this->CurrCol - $oldcolumn) * ($this->ColWidth+$this->ColGap);
20545 } // *RTL*
20546 $this->x = $bak_x;
20547 $oldcolumn = $this->CurrCol;
20548 $y = $this->y0 - $paint_ht_corr ;
20549 $this->oldy = $this->y0 - $paint_ht_corr ;
20550 $old_height = 0;
20551 }
20552 /*-- END COLUMNS --*/
20553
20554 }
20555
20556 // RESETTING VALUES
20557 $this->SetTColor($this->ConvertColor(0));
20558 $this->SetDColor($this->ConvertColor(0));
20559 $this->SetFColor($this->ConvertColor(255));
20560 $this->colorarray = '';
20561 $this->spanbgcolorarray = '';
20562 $this->spanbgcolor = false;
20563 $this->spanborder = false;
20564 $this->spanborddet = array();
20565 $this->HREF = '';
20566 $this->textparam = array();
20567 $this->SetTextOutline();
20568 $this->SUP = false;
20569 $this->SUB = false;
20570
20571 $this->strike = false;
20572 $this->textshadow = '';
20573
20574 $this->currentfontfamily = '';
20575 $this->currentfontsize = '';
20576 $this->currentfontstyle = '';
20577 /*-- TABLES --*/
20578 if ($this->tableLevel) {
20579 $this->SetLineHeight('',$this->table_lineheight); // *TABLES*
20580 }
20581 else
20582 /*-- END TABLES --*/
20583 /*-- LISTS --*/
20584 if ($is_list && $this->list_lineheight[$this->listlvl][$this->listOcc]) {
20585 $this->SetLineHeight('',$this->list_lineheight[$this->listlvl][$this->listOcc]); // sets default line height
20586 }
20587 else
20588 /*-- END LISTS --*/
20589 if (isset($this->blk[$this->blklvl]['line_height']) && $this->blk[$this->blklvl]['line_height']) {
20590 $this->SetLineHeight('',$this->blk[$this->blklvl]['line_height']); // sets default line height
20591 }
20592 $this->ResetStyles();
20593 $this->toupper = false;
20594 $this->tolower = false;
20595 $this->capitalize = false;
20596 $this->kerning = false;
20597 $this->lSpacingCSS = '';
20598 $this->wSpacingCSS = '';
20599 $this->fixedlSpacing = false;
20600 $this->minwSpacing = 0;
20601 $this->SetDash();
20602 $this->dash_on = false;
20603 $this->dotted_on = false;
20604
20605 }//end of for(i=0;i<arraysize;i++)
20606
20607
20608 // PAINT DIV BORDER // DISABLED IN COLUMNS AS DOESN'T WORK WHEN BROKEN ACROSS COLS??
20609 if ((isset($this->blk[$this->blklvl]['border']) || isset($this->blk[$this->blklvl]['bgcolor']) || isset($this->blk[$this->blklvl]['box_shadow'])) && $blockstate && ($this->y != $this->oldy)) {
20610 $bottom_y = $this->y; // Does not include Bottom Margin
20611 if (isset($this->blk[$this->blklvl]['startpage']) && $this->blk[$this->blklvl]['startpage'] != $this->page && $blockstate != 1) {
20612 $this->PaintDivBB('pagetop',$blockstate);
20613 }
20614
20615 else if ($blockstate != 1) {
20616 $this->PaintDivBB('',$blockstate);
20617 }
20618 $this->y = $bottom_y;
20619 $this->x = $bak_x;
20620 }
20621
20622 // Reset Font
20623 $this->SetFontSize($this->default_font_size,false);
20624
20625
20626 }
20627
20628 function _setDashBorder($style, $div, $cp, $side) {
20629 if ($style == 'dashed' && (($side=='L' || $side=='R') || ($side=='T' && $div != 'pagetop' && !$cp) || ($side=='B' && $div!='pagebottom') )) {
20630 $dashsize = 2; // final dash will be this + 1*linewidth
20631 $dashsizek = 1.5; // ratio of Dash/Blank
20632 $this->SetDash($dashsize,($dashsize/$dashsizek)+($this->LineWidth*2));
20633 }
20634 else if ($style == 'dotted' || ($side=='T' && ($div == 'pagetop' || $cp)) || ($side=='B' && $div == 'pagebottom')) {
20635 //Round join and cap
20636 $this->SetLineJoin(1);
20637 $this->SetLineCap(1);
20638 $this->SetDash(0.001,($this->LineWidth*3));
20639 }
20640 }
20641
20642 function _setBorderLine($b, $k=1) {
20643 $this->SetLineWidth($b['w']/$k);
20644 $this->SetDColor($b['c']);
20645 if ($b['c'][0]==5) { // RGBa
20646 $this->SetAlpha($b['c'][4], 'Normal', false, 'S')."\n";
20647 }
20648 else if ($b['c'][0]==6) { // CMYKa
20649 $this->SetAlpha($b['c'][5], 'Normal', false, 'S')."\n";
20650 }
20651 }
20652
20653 // mPDF 5.6.52
20654 function PaintDivBB($divider='',$blockstate=0,$blvl=0) {
20655 // Borders & backgrounds are done elsewhere for columns - messes up the repositioning in printcolumnbuffer
20656 if ($this->ColActive) { return ; } // *COLUMNS*
20657 $save_y = $this->y;
20658 if (!$blvl) { $blvl = $this->blklvl; }
20659 $x0 = $x1 = $y0 = $y1 = 0;
20660
20661 // Added mPDF 3.0 Float DIV
20662 if (isset($this->blk[$blvl]['bb_painted'][$this->page]) && $this->blk[$blvl]['bb_painted'][$this->page]) { return; } // *CSS-FLOAT*
20663
20664 if (isset($this->blk[$blvl]['x0'])) { $x0 = $this->blk[$blvl]['x0']; } // left
20665 if (isset($this->blk[$blvl]['y1'])) { $y1 = $this->blk[$blvl]['y1']; } // bottom
20666
20667 // Added mPDF 3.0 Float DIV - ensures backgrounds/borders are drawn to bottom of page
20668 if ($y1==0) {
20669 if ($divider=='pagebottom') { $y1 = $this->h-$this->bMargin; }
20670 else { $y1 = $this->y; }
20671 }
20672
20673 if (isset($this->blk[$blvl]['startpage']) && $this->blk[$blvl]['startpage'] != $this->page) { $continuingpage = true; } else { $continuingpage = false; }
20674
20675 if (isset($this->blk[$blvl]['y0'])) { $y0 = $this->blk[$blvl]['y0']; }
20676 $h = $y1 - $y0;
20677 $w = $this->blk[$blvl]['width'];
20678 $x1 = $x0 + $w;
20679
20680 // Set border-widths as used here
20681 $border_top = $this->blk[$blvl]['border_top']['w'];
20682 $border_bottom = $this->blk[$blvl]['border_bottom']['w'];
20683 $border_left = $this->blk[$blvl]['border_left']['w'];
20684 $border_right = $this->blk[$blvl]['border_right']['w'];
20685 if (!$this->blk[$blvl]['border_top'] || $divider == 'pagetop' || $continuingpage) {
20686 $border_top = 0;
20687 }
20688 if (!$this->blk[$blvl]['border_bottom'] || $blockstate == 1 || $divider == 'pagebottom') {
20689 $border_bottom = 0;
20690 }
20691
20692 $brTL_H = 0;
20693 $brTL_V = 0;
20694 $brTR_H = 0;
20695 $brTR_V = 0;
20696 $brBL_H = 0;
20697 $brBL_V = 0;
20698 $brBR_H = 0;
20699 $brBR_V = 0;
20700
20701 $brset = false;
20702 /*-- BORDER-RADIUS --*/
20703 if (isset($this->blk[$blvl]['border_radius_TL_H'])) { $brTL_H = $this->blk[$blvl]['border_radius_TL_H']; $brset = true; }
20704 if (isset($this->blk[$blvl]['border_radius_TL_V'])) { $brTL_V = $this->blk[$blvl]['border_radius_TL_V']; $brset = true; }
20705 if (isset($this->blk[$blvl]['border_radius_TR_H'])) { $brTR_H = $this->blk[$blvl]['border_radius_TR_H']; $brset = true; }
20706 if (isset($this->blk[$blvl]['border_radius_TR_V'])) { $brTR_V = $this->blk[$blvl]['border_radius_TR_V']; $brset = true; }
20707 if (isset($this->blk[$blvl]['border_radius_BR_H'])) { $brBR_H = $this->blk[$blvl]['border_radius_BR_H']; $brset = true; }
20708 if (isset($this->blk[$blvl]['border_radius_BR_V'])) { $brBR_V = $this->blk[$blvl]['border_radius_BR_V']; $brset = true; }
20709 if (isset($this->blk[$blvl]['border_radius_BL_H'])) { $brBL_H = $this->blk[$blvl]['border_radius_BL_H']; $brset = true; }
20710 if (isset($this->blk[$blvl]['border_radius_BL_V'])) { $brBL_V = $this->blk[$blvl]['border_radius_BL_V']; $brset = true; }
20711
20712 // mPDF 5.4.17
20713 //if (!$this->blk[$blvl]['border_top'] || $divider == 'pagetop' || $continuingpage || $this->keep_block_together) {
20714 if (!$this->blk[$blvl]['border_top'] || $divider == 'pagetop' || $continuingpage) {
20715 $brTL_H = 0;
20716 $brTL_V = 0;
20717 $brTR_H = 0;
20718 $brTR_V = 0;
20719 }
20720 // mPDF 5.4.17
20721 //if (!$this->blk[$blvl]['border_bottom'] || $blockstate == 1 || $divider == 'pagebottom' || $this->keep_block_together) {
20722 if (!$this->blk[$blvl]['border_bottom'] || $blockstate == 1 || $divider == 'pagebottom') {
20723 $brBL_H = 0;
20724 $brBL_V = 0;
20725 $brBR_H = 0;
20726 $brBR_V = 0;
20727 }
20728
20729 // Disallow border-radius if it is smaller than the border width.
20730 if ($brTL_H < min($border_left, $border_top)) { $brTL_H = $brTL_V = 0; }
20731 if ($brTL_V < min($border_left, $border_top)) { $brTL_V = $brTL_H = 0; }
20732 if ($brTR_H < min($border_right, $border_top)) { $brTR_H = $brTR_V = 0; }
20733 if ($brTR_V < min($border_right, $border_top)) { $brTR_V = $brTR_H = 0; }
20734 if ($brBL_H < min($border_left, $border_bottom)) { $brBL_H = $brBL_V = 0; }
20735 if ($brBL_V < min($border_left, $border_bottom)) { $brBL_V = $brBL_H = 0; }
20736 if ($brBR_H < min($border_right, $border_bottom)) { $brBR_H = $brBR_V = 0; }
20737 if ($brBR_V < min($border_right, $border_bottom)) { $brBR_V = $brBR_H = 0; }
20738
20739 // CHECK FOR radii that sum to > width or height of div ********
20740 $f = min($h/($brTL_V + $brBL_V + 0.001), $h/($brTR_V + $brBR_V + 0.001), $w/($brTL_H + $brTR_H + 0.001), $w/($brBL_H + $brBR_H + 0.001));
20741 if ($f < 1) {
20742 $brTL_H *= $f;
20743 $brTL_V *= $f;
20744 $brTR_H *= $f;
20745 $brTR_V *= $f;
20746 $brBL_H *= $f;
20747 $brBL_V *= $f;
20748 $brBR_H *= $f;
20749 $brBR_V *= $f;
20750 }
20751 /*-- END BORDER-RADIUS --*/
20752
20753 $tbcol = $this->ConvertColor(255);
20754 for($l=0; $l <= $blvl; $l++) {
20755 if ($this->blk[$l]['bgcolor']) {
20756 $tbcol = $this->blk[$l]['bgcolorarray'];
20757 }
20758 }
20759
20760 // BORDERS
20761 if (isset($this->blk[$blvl]['y0']) && $this->blk[$blvl]['y0']) { $y0 = $this->blk[$blvl]['y0']; }
20762 $h = $y1 - $y0;
20763 $w = $this->blk[$blvl]['width'];
20764
20765 //if ($this->blk[$blvl]['border_top']) {
20766 // Reinstate line above for dotted line divider when block border crosses a page
20767 if ($this->blk[$blvl]['border_top'] && $divider != 'pagetop' && !$continuingpage) {
20768 $tbd = $this->blk[$blvl]['border_top'];
20769
20770 // mPDF 5.4.18
20771 $legend = '';
20772 if (isset($this->blk[$blvl]['border_legend']) && $this->blk[$blvl]['border_legend']) {
20773 $legend = $this->blk[$blvl]['border_legend']; // Same structure array as textbuffer
20774 $txt = ltrim($legend[0]);
20775
20776 //Set font, size, style, color
20777 $this->SetFont($legend[4],$legend[2],$legend[11]);
20778 if ($legend[3]) {
20779 $cor = $legend[3];
20780 $this->SetTColor($cor);
20781 }
20782 $stringWidth = $this->GetStringWidth($txt );
20783 $save_x = $this->x;
20784 $save_y = $this->y;
20785 $save_currentfontfamily = $this->FontFamily;
20786 $save_currentfontsize = $this->FontSizePt;
20787 $save_currentfontstyle = $this->FontStyle.($this->U ? 'U' : '').($this->S ? 'S' : '');
20788 $this->y = $y0 - $this->FontSize/2 + $this->blk[$blvl]['border_top']['w']/2;
20789 $this->x = $x0 + $this->blk[$blvl]['padding_left'] + $this->blk[$blvl]['border_left']['w'];
20790
20791 // Set the distance from the border line to the text ? make configurable variable
20792 $gap = 0.2 * $this->FontSize;
20793
20794 $legbreakL = $this->x - $gap;
20795 $legbreakR = $this->x + $stringWidth + $gap;
20796
20797 $this->Cell( $stringWidth, $this->FontSize, $txt , '', 0, 'C', $fill, '', 0, 0,0,'M', $fill);
20798 // Reset
20799 $this->x = $save_x;
20800 $this->y = $save_y;
20801 $this->SetFont($save_currentfontfamily,$save_currentfontstyle,$save_currentfontsize);
20802 $this->SetTColor($this->ConvertColor(0));
20803 }
20804
20805 if (isset($tbd['s']) && $tbd['s']) {
20806 if (!$brset && $tbd['style']!='dotted' && $tbd['style']!='dashed') {
20807 $this->_out('q');
20808 $this->SetLineWidth(0);
20809 $this->_out(sprintf('%.3F %.3F m ',($x0)*_MPDFK, ($this->h-($y0))*_MPDFK));
20810 $this->_out(sprintf('%.3F %.3F l ',($x0 + $border_left)*_MPDFK, ($this->h-($y0 + $border_top))*_MPDFK));
20811 $this->_out(sprintf('%.3F %.3F l ',($x0 + $w - $border_right)*_MPDFK, ($this->h-($y0 + $border_top))*_MPDFK));
20812 $this->_out(sprintf('%.3F %.3F l ',($x0 + $w)*_MPDFK, ($this->h-($y0))*_MPDFK));
20813 $this->_out(' h W n '); // Ends path no-op & Sets the clipping path
20814 }
20815
20816 $this->_setBorderLine($tbd);
20817 if ($tbd['style']=='dotted' || $tbd['style']=='dashed') {
20818 $legbreakL -= $border_top/2; // because line cap different
20819 $legbreakR += $border_top/2;
20820 $this->_setDashBorder($tbd['style'],$divider,$continuingpage,'T');
20821 }
20822 /*-- BORDER-RADIUS --*/
20823 else if (($brTL_V && $brTL_H) || ($brTR_V && $brTR_H) || $tbd['style']=='solid' || $tbd['style']=='double' ) { // mPDF 5.6.58
20824 $this->SetLineJoin(0);
20825 $this->SetLineCap(0);
20826 }
20827 $s = '';
20828 if ($brTR_H && $brTR_V) {
20829 $s .= ($this->_EllipseArc($x0 + $w - $brTR_H, $y0 + $brTR_V, $brTR_H - $border_top/2 , $brTR_V - $border_top/2 , 1, 2, true))."\n";
20830 }
20831 else
20832 /*-- END BORDER-RADIUS --*/
20833 if ($tbd['style']=='solid' || $tbd['style']=='double') {
20834 $s .= (sprintf('%.3F %.3F m ',($x0 + $w)*_MPDFK, ($this->h-($y0 + ($border_top/2)))*_MPDFK))."\n";
20835 }
20836 else {
20837 $s .= (sprintf('%.3F %.3F m ',($x0 + $w - ($border_top/2))*_MPDFK, ($this->h-($y0 + ($border_top/2)))*_MPDFK))."\n";
20838 }
20839 /*-- BORDER-RADIUS --*/
20840 if ($brTL_H && $brTL_V ) {
20841 // mPDF 5.4.18
20842 if ($legend) {
20843 if ($legbreakR < ($x0 + $w - $brTR_H)) {
20844 $s .= (sprintf('%.3F %.3F l ', $legbreakR*_MPDFK, ($this->h-($y0 + ($border_top/2)))*_MPDFK))."\n";
20845 }
20846 if ($legbreakL > ($x0 + $brTL_H )) {
20847 $s .= (sprintf('%.3F %.3F m ',$legbreakL*_MPDFK, ($this->h-($y0 + ($border_top/2)))*_MPDFK))."\n";
20848 $s .= (sprintf('%.3F %.3F l ',($x0 + $brTL_H )*_MPDFK, ($this->h-($y0 + ($border_top/2)))*_MPDFK)."\n");
20849 }
20850 else {
20851 $s .= (sprintf('%.3F %.3F m ',($x0 + $brTL_H )*_MPDFK, ($this->h-($y0 + ($border_top/2)))*_MPDFK))."\n";
20852 }
20853 }
20854 else {
20855 $s .= (sprintf('%.3F %.3F l ',($x0 + $brTL_H )*_MPDFK, ($this->h-($y0 + ($border_top/2)))*_MPDFK))."\n";
20856 }
20857 $s .= ($this->_EllipseArc($x0 + $brTL_H, $y0 + $brTL_V, $brTL_H - $border_top/2 , $brTL_V - $border_top/2 , 2, 1))."\n";
20858 }
20859 else {
20860 /*-- END BORDER-RADIUS --*/
20861 // mPDF 5.4.18
20862 if ($legend) {
20863 if ($legbreakR < ($x0 + $w)) {
20864 $s .= (sprintf('%.3F %.3F l ',$legbreakR*_MPDFK, ($this->h-($y0 + ($border_top/2)))*_MPDFK))."\n";
20865 }
20866 if ($legbreakL > ($x0)) {
20867 $s .= (sprintf('%.3F %.3F m ',$legbreakL*_MPDFK, ($this->h-($y0 + ($border_top/2)))*_MPDFK))."\n";
20868 if ($tbd['style']=='solid' || $tbd['style']=='double') {
20869 $s .= (sprintf('%.3F %.3F l ',($x0)*_MPDFK, ($this->h-($y0 + ($border_top/2)))*_MPDFK))."\n";
20870 }
20871 else {
20872 $s .= (sprintf('%.3F %.3F l ',($x0 + ($border_top/2))*_MPDFK, ($this->h-($y0 + ($border_top/2)))*_MPDFK))."\n";
20873 }
20874 }
20875 else if ($tbd['style']=='solid' || $tbd['style']=='double') {
20876 $s .= (sprintf('%.3F %.3F m ', ($x0)*_MPDFK, ($this->h-($y0 + ($border_top/2)))*_MPDFK))."\n";
20877 }
20878 else {
20879 $s .= (sprintf('%.3F %.3F m ', ($x0 + $border_top/2)*_MPDFK, ($this->h-($y0 + ($border_top/2)))*_MPDFK))."\n";
20880 }
20881 }
20882 else if ($tbd['style']=='solid' || $tbd['style']=='double') {
20883 $s .= (sprintf('%.3F %.3F l ',($x0)*_MPDFK, ($this->h-($y0 + ($border_top/2)))*_MPDFK))."\n";
20884 }
20885 else {
20886 $s .= (sprintf('%.3F %.3F l ',($x0 + ($border_top/2))*_MPDFK, ($this->h-($y0 + ($border_top/2)))*_MPDFK))."\n";
20887 }
20888 /*-- BORDER-RADIUS --*/
20889 }
20890 /*-- END BORDER-RADIUS --*/
20891 $s .= 'S'."\n";
20892 $this->_out($s);
20893
20894 if ($tbd['style']=='double') {
20895 $this->SetLineWidth($tbd['w']/3);
20896 $this->SetDColor($tbcol);
20897 $this->_out($s);
20898 }
20899 if (!$brset && $tbd['style']!='dotted' && $tbd['style']!='dashed') { $this->_out('Q'); }
20900
20901 // Reset Corners and Dash off
20902 $this->SetLineWidth(0.1); // mPDF 5.6.57
20903 $this->SetDColor($this->ConvertColor(0));
20904 $this->SetLineJoin(2);
20905 $this->SetLineCap(2);
20906 $this->SetDash();
20907 }
20908 }
20909 //if ($this->blk[$blvl]['border_bottom'] && $blockstate != 1) {
20910 // Reinstate line above for dotted line divider when block border crosses a page
20911 if ($this->blk[$blvl]['border_bottom'] && $blockstate != 1 && $divider != 'pagebottom') {
20912 $tbd = $this->blk[$blvl]['border_bottom'];
20913 if (isset($tbd['s']) && $tbd['s']) {
20914 if (!$brset && $tbd['style']!='dotted' && $tbd['style']!='dashed') {
20915 $this->_out('q');
20916 $this->SetLineWidth(0);
20917 $this->_out(sprintf('%.3F %.3F m ',($x0)*_MPDFK, ($this->h-($y0 + $h))*_MPDFK));
20918 $this->_out(sprintf('%.3F %.3F l ',($x0 + $border_left)*_MPDFK, ($this->h-($y0 + $h - $border_bottom))*_MPDFK));
20919 $this->_out(sprintf('%.3F %.3F l ',($x0 + $w - $border_right)*_MPDFK, ($this->h-($y0 + $h - $border_bottom))*_MPDFK));
20920 $this->_out(sprintf('%.3F %.3F l ',($x0 + $w)*_MPDFK, ($this->h-($y0 + $h))*_MPDFK));
20921 $this->_out(' h W n '); // Ends path no-op & Sets the clipping path
20922 }
20923
20924 $this->_setBorderLine($tbd);
20925 if ($tbd['style']=='dotted' || $tbd['style']=='dashed') { $this->_setDashBorder($tbd['style'],$divider,$continuingpage,'B'); }
20926 /*-- BORDER-RADIUS --*/
20927 else if (($brBL_V && $brBL_H) || ($brBR_V && $brBR_H) || $tbd['style']=='solid' || $tbd['style']=='double' ) { // mPDF 5.6.58
20928 $this->SetLineJoin(0);
20929 $this->SetLineCap(0);
20930 }
20931 $s = '';
20932 if ($brBL_H && $brBL_V) {
20933 $s .= ($this->_EllipseArc($x0 + $brBL_H, $y0 + $h - $brBL_V, $brBL_H - $border_bottom/2 , $brBL_V - $border_bottom/2 , 3, 2, true))."\n";
20934 }
20935 else
20936 /*-- END BORDER-RADIUS --*/
20937 if ($tbd['style']=='solid' || $tbd['style']=='double') {
20938 $s .= (sprintf('%.3F %.3F m ',($x0)*_MPDFK, ($this->h-($y0 + $h - ($border_bottom/2)))*_MPDFK))."\n";
20939 }
20940 else {
20941 $s .= (sprintf('%.3F %.3F m ',($x0 + ($border_bottom/2))*_MPDFK, ($this->h-($y0 + $h - ($border_bottom/2)))*_MPDFK))."\n";
20942 }
20943 /*-- BORDER-RADIUS --*/
20944 if ($brBR_H && $brBR_V ) {
20945 $s .= (sprintf('%.3F %.3F l ',($x0 + $w - ($border_bottom/2) - $brBR_H )*_MPDFK, ($this->h-($y0 + $h - ($border_bottom/2)))*_MPDFK))."\n";
20946 $s .= ($this->_EllipseArc($x0 + $w - $brBR_H, $y0 + $h - $brBR_V, $brBR_H - $border_bottom/2 , $brBR_V - $border_bottom/2 , 4, 1))."\n";
20947 }
20948 else
20949 /*-- END BORDER-RADIUS --*/
20950 if ($tbd['style']=='solid' || $tbd['style']=='double') {
20951 $s .= (sprintf('%.3F %.3F l ',($x0 + $w)*_MPDFK, ($this->h-($y0 + $h - ($border_bottom/2)))*_MPDFK))."\n";
20952 }
20953 else {
20954 $s .= (sprintf('%.3F %.3F l ',($x0 + $w - ($border_bottom/2))*_MPDFK, ($this->h-($y0 + $h - ($border_bottom/2)))*_MPDFK))."\n";
20955 }
20956 $s .= 'S'."\n";
20957 $this->_out($s);
20958
20959 if ($tbd['style']=='double') {
20960 $this->SetLineWidth($tbd['w']/3);
20961 $this->SetDColor($tbcol);
20962 $this->_out($s);
20963 }
20964 if (!$brset && $tbd['style']!='dotted' && $tbd['style']!='dashed') { $this->_out('Q'); }
20965
20966
20967 // Reset Corners and Dash off
20968 $this->SetLineWidth(0.1); // mPDF 5.6.57
20969 $this->SetDColor($this->ConvertColor(0));
20970 $this->SetLineJoin(2);
20971 $this->SetLineCap(2);
20972 $this->SetDash();
20973 }
20974 }
20975 if ($this->blk[$blvl]['border_left']) {
20976 $tbd = $this->blk[$blvl]['border_left'];
20977 if (isset($tbd['s']) && $tbd['s']) {
20978 if (!$brset && $tbd['style']!='dotted' && $tbd['style']!='dashed') {
20979 $this->_out('q');
20980 $this->SetLineWidth(0);
20981 $this->_out(sprintf('%.3F %.3F m ',($x0)*_MPDFK, ($this->h-($y0))*_MPDFK));
20982 $this->_out(sprintf('%.3F %.3F l ',($x0 + $border_left)*_MPDFK, ($this->h-($y0+$border_top))*_MPDFK));
20983 $this->_out(sprintf('%.3F %.3F l ',($x0 + $border_left)*_MPDFK, ($this->h-($y0 + $h - $border_bottom))*_MPDFK));
20984 $this->_out(sprintf('%.3F %.3F l ',($x0)*_MPDFK, ($this->h-($y0 + $h))*_MPDFK));
20985 $this->_out(' h W n '); // Ends path no-op & Sets the clipping path
20986 }
20987
20988 $this->_setBorderLine($tbd);
20989 if ($tbd['style']=='dotted' || $tbd['style']=='dashed') { $this->_setDashBorder($tbd['style'],$divider,$continuingpage,'L'); }
20990 /*-- BORDER-RADIUS --*/
20991 else if (($brTL_V && $brTL_H) || ($brBL_V && $brBL_H) || $tbd['style']=='solid' || $tbd['style']=='double' ) { // mPDF 5.6.58
20992 $this->SetLineJoin(0);
20993 $this->SetLineCap(0);
20994 }
20995 $s = '';
20996 if ($brTL_V && $brTL_H) {
20997 $s .= ($this->_EllipseArc($x0 + $brTL_H, $y0 + $brTL_V, $brTL_H - $border_left/2 , $brTL_V - $border_left/2, 2, 2, true))."\n";
20998 }
20999 else
21000 /*-- END BORDER-RADIUS --*/
21001 if ($tbd['style']=='solid' || $tbd['style']=='double') {
21002 $s .= (sprintf('%.3F %.3F m ',($x0 + ($border_left/2))*_MPDFK, ($this->h-($y0))*_MPDFK))."\n";
21003 }
21004 else {
21005 $s .= (sprintf('%.3F %.3F m ',($x0 + ($border_left/2))*_MPDFK, ($this->h-($y0 + ($border_left/2)))*_MPDFK))."\n";
21006 }
21007 /*-- BORDER-RADIUS --*/
21008 if ($brBL_V && $brBL_H ) {
21009 $s .= (sprintf('%.3F %.3F l ',($x0 + ($border_left/2))*_MPDFK, ($this->h-($y0 + $h - ($border_left/2)- $brBL_V) )*_MPDFK))."\n";
21010 $s .= ($this->_EllipseArc($x0 + $brBL_H, $y0 + $h - $brBL_V, $brBL_H - $border_left/2 , $brBL_V - $border_left/2, 3, 1))."\n";
21011 }
21012 else
21013 /*-- END BORDER-RADIUS --*/
21014 if ($tbd['style']=='solid' || $tbd['style']=='double') {
21015 $s .= (sprintf('%.3F %.3F l ',($x0 + ($border_left/2))*_MPDFK, ($this->h-($y0 + $h) )*_MPDFK))."\n";
21016 }
21017 else {
21018 $s .= (sprintf('%.3F %.3F l ',($x0 + ($border_left/2))*_MPDFK, ($this->h-($y0 + $h - ($border_left/2)) )*_MPDFK))."\n";
21019 }
21020 $s .= 'S'."\n";
21021 $this->_out($s);
21022
21023 if ($tbd['style']=='double') {
21024 $this->SetLineWidth($tbd['w']/3);
21025 $this->SetDColor($tbcol);
21026 $this->_out($s);
21027 }
21028 if (!$brset && $tbd['style']!='dotted' && $tbd['style']!='dashed') { $this->_out('Q'); }
21029
21030 // Reset Corners and Dash off
21031 $this->SetLineWidth(0.1); // mPDF 5.6.57
21032 $this->SetDColor($this->ConvertColor(0));
21033 $this->SetLineJoin(2);
21034 $this->SetLineCap(2);
21035 $this->SetDash();
21036 }
21037 }
21038 if ($this->blk[$blvl]['border_right']) {
21039 $tbd = $this->blk[$blvl]['border_right'];
21040 if (isset($tbd['s']) && $tbd['s']) {
21041 if (!$brset && $tbd['style']!='dotted' && $tbd['style']!='dashed') {
21042 $this->_out('q');
21043 $this->SetLineWidth(0);
21044 $this->_out(sprintf('%.3F %.3F m ',($x0 + $w)*_MPDFK, ($this->h-($y0))*_MPDFK));
21045 $this->_out(sprintf('%.3F %.3F l ',($x0 + $w - $border_right)*_MPDFK, ($this->h-($y0+$border_top))*_MPDFK));
21046 $this->_out(sprintf('%.3F %.3F l ',($x0 + $w - $border_right)*_MPDFK, ($this->h-($y0 + $h - $border_bottom))*_MPDFK));
21047 $this->_out(sprintf('%.3F %.3F l ',($x0 + $w)*_MPDFK, ($this->h-($y0 + $h))*_MPDFK));
21048 $this->_out(' h W n '); // Ends path no-op & Sets the clipping path
21049 }
21050
21051 $this->_setBorderLine($tbd);
21052 if ($tbd['style']=='dotted' || $tbd['style']=='dashed') { $this->_setDashBorder($tbd['style'],$divider,$continuingpage,'R'); }
21053 /*-- BORDER-RADIUS --*/
21054 else if (($brTR_V && $brTR_H) || ($brBR_V && $brBR_H) || $tbd['style']=='solid' || $tbd['style']=='double' ) { // mPDF 5.6.58
21055 $this->SetLineJoin(0);
21056 $this->SetLineCap(0);
21057 }
21058 $s = '';
21059 if ($brBR_V && $brBR_H) {
21060 $s .= ($this->_EllipseArc($x0 + $w - $brBR_H, $y0 + $h - $brBR_V, $brBR_H - $border_right/2 , $brBR_V - $border_right/2, 4, 2, true))."\n";
21061 }
21062 else
21063 /*-- END BORDER-RADIUS --*/
21064 if ($tbd['style']=='solid' || $tbd['style']=='double') {
21065 $s .= (sprintf('%.3F %.3F m ',($x0 + $w - ($border_right/2))*_MPDFK, ($this->h-($y0 + $h))*_MPDFK))."\n";
21066 }
21067 else {
21068 $s .= (sprintf('%.3F %.3F m ',($x0 + $w - ($border_right/2))*_MPDFK, ($this->h-($y0 + $h - ($border_right/2)))*_MPDFK))."\n";
21069 }
21070 /*-- BORDER-RADIUS --*/
21071 if ($brTR_V && $brTR_H ) {
21072 $s .= (sprintf('%.3F %.3F l ',($x0 + $w - ($border_right/2))*_MPDFK, ($this->h-($y0 + ($border_right/2) + $brTR_V) )*_MPDFK))."\n";
21073 $s .= ($this->_EllipseArc($x0 + $w - $brTR_H, $y0 + $brTR_V, $brTR_H - $border_right/2 , $brTR_V - $border_right/2, 1, 1))."\n";
21074 }
21075 else
21076 /*-- END BORDER-RADIUS --*/
21077 if ($tbd['style']=='solid' || $tbd['style']=='double') {
21078 $s .= (sprintf('%.3F %.3F l ',($x0 + $w - ($border_right/2))*_MPDFK, ($this->h-($y0) )*_MPDFK))."\n";
21079 }
21080 else {
21081 $s .= (sprintf('%.3F %.3F l ',($x0 + $w - ($border_right/2))*_MPDFK, ($this->h-($y0 + ($border_right/2)) )*_MPDFK))."\n";
21082 }
21083 $s .= 'S'."\n";
21084 $this->_out($s);
21085
21086 if ($tbd['style']=='double') {
21087 $this->SetLineWidth($tbd['w']/3);
21088 $this->SetDColor($tbcol);
21089 $this->_out($s);
21090 }
21091 if (!$brset && $tbd['style']!='dotted' && $tbd['style']!='dashed') { $this->_out('Q'); }
21092
21093 // Reset Corners and Dash off
21094 $this->SetLineWidth(0.1); // mPDF 5.6.57
21095 $this->SetDColor($this->ConvertColor(0));
21096 $this->SetLineJoin(2);
21097 $this->SetLineCap(2);
21098 $this->SetDash();
21099 }
21100 }
21101
21102
21103 $this->SetDash();
21104 $this->y = $save_y;
21105
21106
21107 // BACKGROUNDS are disabled in columns/kbt/headers - messes up the repositioning in printcolumnbuffer
21108 if ($this->ColActive || $this->kwt || $this->keep_block_together) { return ; }
21109
21110
21111 $bgx0 = $x0;
21112 $bgx1 = $x1;
21113 $bgy0 = $y0;
21114 $bgy1 = $y1;
21115
21116 // Defined br values represent the radius of the outer curve - need to take border-width/2 from each radius for drawing the borders
21117 if (isset($this->blk[$blvl]['background_clip']) && $this->blk[$blvl]['background_clip'] == 'padding-box') {
21118 $brbgTL_H = max(0, $brTL_H - $this->blk[$blvl]['border_left']['w']);
21119 $brbgTL_V = max(0, $brTL_V - $this->blk[$blvl]['border_top']['w']);
21120 $brbgTR_H = max(0, $brTR_H - $this->blk[$blvl]['border_right']['w']);
21121 $brbgTR_V = max(0, $brTR_V - $this->blk[$blvl]['border_top']['w']);
21122 $brbgBL_H = max(0, $brBL_H - $this->blk[$blvl]['border_left']['w']);
21123 $brbgBL_V = max(0, $brBL_V - $this->blk[$blvl]['border_bottom']['w']);
21124 $brbgBR_H = max(0, $brBR_H - $this->blk[$blvl]['border_right']['w']);
21125 $brbgBR_V = max(0, $brBR_V - $this->blk[$blvl]['border_bottom']['w']);
21126 $bgx0 += $this->blk[$blvl]['border_left']['w'];
21127 $bgx1 -= $this->blk[$blvl]['border_right']['w'];
21128 if ($this->blk[$blvl]['border_top'] && $divider != 'pagetop' && !$continuingpage) {
21129 $bgy0 += $this->blk[$blvl]['border_top']['w'];
21130 }
21131 if ($this->blk[$blvl]['border_bottom'] && $blockstate != 1 && $divider != 'pagebottom') {
21132 $bgy1 -= $this->blk[$blvl]['border_bottom']['w'];
21133 }
21134 }
21135 // mPDF 5.6.09
21136 else if (isset($this->blk[$blvl]['background_clip']) && $this->blk[$blvl]['background_clip'] == 'content-box') {
21137 $brbgTL_H = max(0, $brTL_H - $this->blk[$blvl]['border_left']['w'] - $this->blk[$blvl]['padding_left']);
21138 $brbgTL_V = max(0, $brTL_V - $this->blk[$blvl]['border_top']['w'] - $this->blk[$blvl]['padding_top']);
21139 $brbgTR_H = max(0, $brTR_H - $this->blk[$blvl]['border_right']['w'] - $this->blk[$blvl]['padding_right']);
21140 $brbgTR_V = max(0, $brTR_V - $this->blk[$blvl]['border_top']['w'] - $this->blk[$blvl]['padding_top']);
21141 $brbgBL_H = max(0, $brBL_H - $this->blk[$blvl]['border_left']['w'] - $this->blk[$blvl]['padding_left']);
21142 $brbgBL_V = max(0, $brBL_V - $this->blk[$blvl]['border_bottom']['w'] - $this->blk[$blvl]['padding_bottom']);
21143 $brbgBR_H = max(0, $brBR_H - $this->blk[$blvl]['border_right']['w'] - $this->blk[$blvl]['padding_right']);
21144 $brbgBR_V = max(0, $brBR_V - $this->blk[$blvl]['border_bottom']['w'] - $this->blk[$blvl]['padding_bottom']);
21145 $bgx0 += $this->blk[$blvl]['border_left']['w'] + $this->blk[$blvl]['padding_left'];
21146 $bgx1 -= $this->blk[$blvl]['border_right']['w'] + $this->blk[$blvl]['padding_right'];
21147 if (($this->blk[$blvl]['border_top']['w'] || $this->blk[$blvl]['padding_top']) && $divider != 'pagetop' && !$continuingpage) {
21148 $bgy0 += $this->blk[$blvl]['border_top']['w'] + $this->blk[$blvl]['padding_top'];
21149 }
21150 if (($this->blk[$blvl]['border_bottom']['w'] || $this->blk[$blvl]['padding_bottom']) && $blockstate != 1 && $divider != 'pagebottom') {
21151 $bgy1 -= $this->blk[$blvl]['border_bottom']['w'] + $this->blk[$blvl]['padding_bottom'];
21152 }
21153 }
21154 else {
21155 $brbgTL_H = $brTL_H;
21156 $brbgTL_V = $brTL_V;
21157 $brbgTR_H = $brTR_H;
21158 $brbgTR_V = $brTR_V;
21159 $brbgBL_H = $brBL_H;
21160 $brbgBL_V = $brBL_V;
21161 $brbgBR_H = $brBR_H;
21162 $brbgBR_V = $brBR_V;
21163 }
21164
21165 // Set clipping path
21166 $s = ' q 0 w '; // Line width=0
21167 $s .= sprintf('%.3F %.3F m ', ($bgx0+$brbgTL_H )*_MPDFK, ($this->h-$bgy0)*_MPDFK); // start point TL before the arc
21168 /*-- BORDER-RADIUS --*/
21169 if ($brbgTL_H || $brbgTL_V) {
21170 $s .= $this->_EllipseArc($bgx0+$brbgTL_H, $bgy0+$brbgTL_V, $brbgTL_H , $brbgTL_V , 2); // segment 2 TL
21171 }
21172 /*-- END BORDER-RADIUS --*/
21173 $s .= sprintf('%.3F %.3F l ', ($bgx0)*_MPDFK, ($this->h-($bgy1-$brbgBL_V ))*_MPDFK); // line to BL
21174 /*-- BORDER-RADIUS --*/
21175 if ($brbgBL_H || $brbgBL_V) {
21176 $s .= $this->_EllipseArc($bgx0+$brbgBL_H, $bgy1-$brbgBL_V, $brbgBL_H , $brbgBL_V , 3); // segment 3 BL
21177 }
21178 /*-- END BORDER-RADIUS --*/
21179 $s .= sprintf('%.3F %.3F l ', ($bgx1-$brbgBR_H )*_MPDFK, ($this->h-($bgy1))*_MPDFK); // line to BR
21180 /*-- BORDER-RADIUS --*/
21181 if ($brbgBR_H || $brbgBR_V) {
21182 $s .= $this->_EllipseArc($bgx1-$brbgBR_H, $bgy1-$brbgBR_V, $brbgBR_H , $brbgBR_V , 4); // segment 4 BR
21183 }
21184 /*-- END BORDER-RADIUS --*/
21185 $s .= sprintf('%.3F %.3F l ', ($bgx1)*_MPDFK, ($this->h-($bgy0+$brbgTR_V))*_MPDFK); // line to TR
21186 /*-- BORDER-RADIUS --*/
21187 if ($brbgTR_H || $brbgTR_V) {
21188 $s .= $this->_EllipseArc($bgx1-$brbgTR_H, $bgy0+$brbgTR_V, $brbgTR_H , $brbgTR_V , 1); // segment 1 TR
21189 }
21190 /*-- END BORDER-RADIUS --*/
21191 $s .= sprintf('%.3F %.3F l ', ($bgx0+$brbgTL_H )*_MPDFK, ($this->h-$bgy0)*_MPDFK); // line to TL
21192
21193
21194 // Box Shadow
21195 $shadow = '';
21196 if (isset($this->blk[$blvl]['box_shadow']) && $this->blk[$blvl]['box_shadow'] && $h > 0) {
21197 foreach($this->blk[$blvl]['box_shadow'] AS $sh) {
21198 // Colors
21199 if ($sh['col']{0}==1) {
21200 $colspace = 'Gray';
21201 if ($sh['col']{2}==1) { $col1 = '1'.$sh['col'][1].'1'.$sh['col'][3]; }
21202 else { $col1 = '1'.$sh['col'][1].'1'.chr(100); }
21203 $col2 = '1'.$sh['col'][1].'1'.chr(0);
21204 }
21205 else if ($sh['col']{0}==4) { // CMYK
21206 $colspace = 'CMYK';
21207 $col1 = '6'.$sh['col'][1].$sh['col'][2].$sh['col'][3].$sh['col'][4].chr(100);
21208 $col2 = '6'.$sh['col'][1].$sh['col'][2].$sh['col'][3].$sh['col'][4].chr(0);
21209 }
21210 else if ($sh['col']{0}==5) { // RGBa
21211 $colspace = 'RGB';
21212 $col1 = '5'.$sh['col'][1].$sh['col'][2].$sh['col'][3].$sh['col'][4];
21213 $col2 = '5'.$sh['col'][1].$sh['col'][2].$sh['col'][3].chr(0);
21214 }
21215 else if ($sh['col']{0}==6) { // CMYKa
21216 $colspace = 'CMYK';
21217 $col1 = '6'.$sh['col'][1].$sh['col'][2].$sh['col'][3].$sh['col'][4].$sh['col'][5];
21218 $col2 = '6'.$sh['col'][1].$sh['col'][2].$sh['col'][3].$sh['col'][4].chr(0);
21219 }
21220 else {
21221 $colspace = 'RGB';
21222 $col1 = '5'.$sh['col'][1].$sh['col'][2].$sh['col'][3].chr(100);
21223 $col2 = '5'.$sh['col'][1].$sh['col'][2].$sh['col'][3].chr(0);
21224 }
21225
21226 // Use clipping path as set above (and rectangle around page) to clip area outside box
21227 $shadow .= $s; // Use the clipping path with W*
21228 $shadow .= sprintf('0 %.3F m %.3F %.3F l ', $this->h*_MPDFK, $this->w*_MPDFK, $this->h*_MPDFK);
21229 $shadow .= sprintf('%.3F 0 l 0 0 l 0 %.3F l ', $this->w*_MPDFK, $this->h*_MPDFK);
21230 $shadow .= 'W n'."\n";
21231
21232 $sh['blur'] = abs($sh['blur']); // cannot have negative blur value
21233 // Ensure spread/blur do not make effective shadow width/height < 0
21234 // Could do more complex things but this just adjusts spread value
21235 if (-$sh['spread'] + $sh['blur']/2 > min($w/2, $h/2)) {
21236 $sh['spread'] = $sh['blur']/2 - min($w/2, $h/2) + 0.01;
21237 }
21238 // Shadow Offset
21239 if ($sh['x'] || $sh['y']) $shadow .= sprintf(' q 1 0 0 1 %.4F %.4F cm', $sh['x']*_MPDFK, -$sh['y']*_MPDFK)."\n";
21240
21241 // Set path for INNER shadow
21242 $shadow .= ' q 0 w ';
21243 $shadow .= $this->SetFColor($col1, true)."\n";
21244 if ($col1{0}==5 && ord($col1{4})<100) { // RGBa
21245 $shadow .= $this->SetAlpha(ord($col1{4})/100, 'Normal', true, 'F')."\n";
21246 }
21247 else if ($col1{0}==6 && ord($col1{5})<100) { // CMYKa
21248 $shadow .= $this->SetAlpha(ord($col1{5})/100, 'Normal', true, 'F')."\n";
21249 }
21250 else if ($col1{0}==1 && $col1{2}==1 && ord($col1{3})<100) { // Gray
21251 $shadow .= $this->SetAlpha(ord($col1{3})/100, 'Normal', true, 'F')."\n";
21252 }
21253
21254 // Blur edges
21255 $mag = 0.551784; // Bezier Control magic number for 4-part spline for circle/ellipse
21256 $mag2 = 0.551784; // Bezier Control magic number to fill in edge of blurred rectangle
21257 $d1 = $sh['spread']+$sh['blur']/2;
21258 $d2 = $sh['spread']-$sh['blur']/2;
21259 $bl = $sh['blur'];
21260 $x00 = $x0 - $d1;
21261 $y00 = $y0 - $d1;
21262 $w00 = $w + $d1*2;
21263 $h00 = $h + $d1*2;
21264
21265 // If any border-radius is greater width-negative spread(inner edge), ignore radii for shadow or screws up
21266 $flatten = false;
21267 if (max($brbgTR_H, $brbgTL_H, $brbgBR_H, $brbgBL_H) >= $w+$d2) { $flatten = true; }
21268 if (max($brbgTR_V, $brbgTL_V, $brbgBR_V, $brbgBL_V) >= $h+$d2) { $flatten = true; }
21269
21270
21271 // TOP RIGHT corner
21272 $p1x = $x00+$w00-$d1-$brbgTR_H; $p1c2x = $p1x +($d2+$brbgTR_H)*$mag;
21273 $p1y = $y00+$bl;
21274 $p2x = $x00+$w00-$d1-$brbgTR_H; $p2c2x = $p2x + ($d1+$brbgTR_H)*$mag;
21275 $p2y = $y00; $p2c1y = $p2y + $bl/2;
21276 $p3x = $x00+$w00; $p3c2x = $p3x - $bl/2;
21277 $p3y = $y00+$d1+$brbgTR_V; $p3c1y = $p3y - ($d1+$brbgTR_V)*$mag;
21278 $p4x = $x00+$w00-$bl;
21279 $p4y = $y00+$d1+$brbgTR_V; $p4c2y = $p4y - ($d2+$brbgTR_V)*$mag;
21280 if (-$d2 > min($brbgTR_H, $brbgTR_V) || $flatten) {
21281 $p1x = $x00+$w00-$bl; $p1c2x = $p1x;
21282 $p2x = $x00+$w00-$bl; $p2c2x = $p2x + $bl*$mag2;
21283 $p3y = $y00+$bl; $p3c1y = $p3y - $bl*$mag2;
21284 $p4y = $y00+$bl; $p4c2y = $p4y ;
21285 }
21286
21287 $shadow .= sprintf('%.3F %.3F m ', ($p1x )*_MPDFK, ($this->h-($p1y ))*_MPDFK);
21288 $shadow .= sprintf('%.3F %.3F %.3F %.3F %.3F %.3F c ', ($p1c2x)*_MPDFK, ($this->h-($p1y))*_MPDFK, ($p4x)*_MPDFK, ($this->h-($p4c2y))*_MPDFK, ($p4x)*_MPDFK, ($this->h-($p4y))*_MPDFK);
21289 $patch_array[0]['f']=0;
21290 $patch_array[0]['points']=array($p1x,$p1y, $p1x,$p1y,
21291 $p2x,$p2c1y, $p2x,$p2y, $p2c2x,$p2y,
21292 $p3x,$p3c1y, $p3x,$p3y, $p3c2x,$p3y,
21293 $p4x,$p4y, $p4x,$p4y, $p4x,$p4c2y,
21294 $p1c2x,$p1y);
21295 $patch_array[0]['colors'] = array($col1,$col2,$col2,$col1);
21296
21297
21298 // RIGHT
21299 $p1x = $x00+$w00; // control point only matches p3 preceding
21300 $p1y = $y00+$d1+$brbgTR_V;
21301 $p2x = $x00+$w00-$bl; // control point only matches p4 preceding
21302 $p2y = $y00+$d1+$brbgTR_V;
21303 $p3x = $x00+$w00-$bl;
21304 $p3y = $y00+$h00-$d1-$brbgBR_V;
21305 $p4x = $x00+$w00; $p4c1x = $p4x-$bl/2;
21306 $p4y = $y00+$h00-$d1-$brbgBR_V;
21307 if (-$d2 > min($brbgTR_H, $brbgTR_V) || $flatten) {
21308 $p1y = $y00+$bl;
21309 $p2y = $y00+$bl;
21310 }
21311 if (-$d2 > min($brbgBR_H, $brbgBR_V) || $flatten) {
21312 $p3y = $y00+$h00-$bl;
21313 $p4y = $y00+$h00-$bl;
21314 }
21315
21316 $shadow .= sprintf('%.3F %.3F l ', ($p3x )*_MPDFK, ($this->h-($p3y ))*_MPDFK);
21317 $patch_array[1]['f']=2;
21318 $patch_array[1]['points']=array($p2x,$p2y,
21319 $p3x,$p3y, $p3x,$p3y, $p3x,$p3y,
21320 $p4c1x,$p4y, $p4x,$p4y, $p4x,$p4y,
21321 $p1x,$p1y);
21322 $patch_array[1]['colors'] = array($col1,$col2);
21323
21324
21325 // BOTTOM RIGHT corner
21326 $p1x = $x00+$w00-$bl; // control points only matches p3 preceding
21327 $p1y = $y00+$h00-$d1-$brbgBR_V; $p1c2y = $p1y + ($d2+$brbgBR_V)*$mag;
21328 $p2x = $x00+$w00; // control point only matches p4 preceding
21329 $p2y = $y00+$h00-$d1-$brbgBR_V; $p2c2y = $p2y + ($d1+$brbgBR_V)*$mag;
21330 $p3x = $x00+$w00-$d1-$brbgBR_H; $p3c1x = $p3x + ($d1+$brbgBR_H)*$mag;
21331 $p3y = $y00+$h00; $p3c2y = $p3y - $bl/2;
21332 $p4x = $x00+$w00-$d1-$brbgBR_H; $p4c2x = $p4x + ($d2+$brbgBR_H)*$mag;
21333 $p4y = $y00+$h00-$bl;
21334
21335 if (-$d2 > min($brbgBR_H, $brbgBR_V) || $flatten) {
21336 $p1y = $y00+$h00-$bl; $p1c2y = $p1y;
21337 $p2y = $y00+$h00-$bl; $p2c2y = $p2y + $bl*$mag2;
21338 $p3x = $x00+$w00-$bl; $p3c1x = $p3x + $bl*$mag2;
21339 $p4x = $x00+$w00-$bl; $p4c2x = $p4x;
21340 }
21341
21342 $shadow .= sprintf('%.3F %.3F %.3F %.3F %.3F %.3F c ', ($p1x)*_MPDFK, ($this->h-($p1c2y))*_MPDFK, ($p4c2x)*_MPDFK, ($this->h-($p4y))*_MPDFK, ($p4x)*_MPDFK, ($this->h-($p4y))*_MPDFK);
21343 $patch_array[2]['f']=2;
21344 $patch_array[2]['points']=array($p2x,$p2c2y,
21345 $p3c1x,$p3y, $p3x,$p3y, $p3x,$p3c2y,
21346 $p4x,$p4y, $p4x,$p4y, $p4c2x,$p4y,
21347 $p1x,$p1c2y);
21348 $patch_array[2]['colors'] = array($col2,$col1);
21349
21350
21351
21352 // BOTTOM
21353 $p1x = $x00+$w00-$d1-$brbgBR_H; // control point only matches p3 preceding
21354 $p1y = $y00+$h00;
21355 $p2x = $x00+$w00-$d1-$brbgBR_H; // control point only matches p4 preceding
21356 $p2y = $y00+$h00-$bl;
21357 $p3x = $x00+$d1+$brbgBL_H;
21358 $p3y = $y00+$h00-$bl;
21359 $p4x = $x00+$d1+$brbgBL_H;
21360 $p4y = $y00+$h00; $p4c1y = $p4y - $bl/2;
21361
21362 if (-$d2 > min($brbgBR_H, $brbgBR_V) || $flatten) {
21363 $p1x = $x00+$w00-$bl;
21364 $p2x = $x00+$w00-$bl;
21365 }
21366 if (-$d2 > min($brbgBL_H, $brbgBL_V) || $flatten) {
21367 $p3x = $x00+$bl;
21368 $p4x = $x00+$bl;
21369 }
21370
21371 $shadow .= sprintf('%.3F %.3F l ', ($p3x )*_MPDFK, ($this->h-($p3y ))*_MPDFK);
21372 $patch_array[3]['f']=2;
21373 $patch_array[3]['points']=array($p2x,$p2y,
21374 $p3x,$p3y, $p3x,$p3y, $p3x,$p3y,
21375 $p4x,$p4c1y, $p4x,$p4y, $p4x,$p4y,
21376 $p1x,$p1y);
21377 $patch_array[3]['colors'] = array($col1,$col2);
21378
21379 // BOTTOM LEFT corner
21380 $p1x = $x00+$d1+$brbgBL_H; $p1c2x = $p1x - ($d2+$brbgBL_H)*$mag; // control points only matches p3 preceding
21381 $p1y = $y00+$h00-$bl;
21382 $p2x = $x00+$d1+$brbgBL_H; $p2c2x = $p2x - ($d1+$brbgBL_H)*$mag; // control point only matches p4 preceding
21383 $p2y = $y00+$h00;
21384 $p3x = $x00; $p3c2x = $p3x + $bl/2;
21385 $p3y = $y00+$h00-$d1-$brbgBL_V; $p3c1y = $p3y + ($d1+$brbgBL_V)*$mag;
21386 $p4x = $x00+$bl;
21387 $p4y = $y00+$h00-$d1-$brbgBL_V; $p4c2y = $p4y + ($d2+$brbgBL_V)*$mag;
21388 if (-$d2 > min($brbgBL_H, $brbgBL_V) || $flatten) {
21389 $p1x = $x00+$bl; $p1c2x = $p1x;
21390 $p2x = $x00+$bl; $p2c2x = $p2x - $bl*$mag2;
21391 $p3y = $y00+$h00-$bl; $p3c1y = $p3y + $bl*$mag2;
21392 $p4y = $y00+$h00-$bl; $p4c2y = $p4y;
21393 }
21394
21395 $shadow .= sprintf('%.3F %.3F %.3F %.3F %.3F %.3F c ', ($p1c2x)*_MPDFK, ($this->h-($p1y))*_MPDFK, ($p4x)*_MPDFK, ($this->h-($p4c2y))*_MPDFK, ($p4x)*_MPDFK, ($this->h-($p4y))*_MPDFK);
21396 $patch_array[4]['f']=2;
21397 $patch_array[4]['points']=array($p2c2x,$p2y,
21398 $p3x,$p3c1y, $p3x,$p3y, $p3c2x,$p3y,
21399 $p4x,$p4y, $p4x,$p4y, $p4x,$p4c2y,
21400 $p1c2x,$p1y);
21401 $patch_array[4]['colors'] = array($col2,$col1);
21402
21403
21404 // LEFT - joins on the right (C3-C4 of previous): f = 2
21405 $p1x = $x00; // control point only matches p3 preceding
21406 $p1y = $y00+$h00-$d1-$brbgBL_V;
21407 $p2x = $x00+$bl; // control point only matches p4 preceding
21408 $p2y = $y00+$h00-$d1-$brbgBL_V;
21409 $p3x = $x00+$bl;
21410 $p3y = $y00+$d1+$brbgTL_V;
21411 $p4x = $x00; $p4c1x = $p4x + $bl/2;
21412 $p4y = $y00+$d1+$brbgTL_V;
21413 if (-$d2 > min($brbgBL_H, $brbgBL_V) || $flatten) {
21414 $p1y = $y00+$h00-$bl;
21415 $p2y = $y00+$h00-$bl;
21416 }
21417 if (-$d2 > min($brbgTL_H, $brbgTL_V) || $flatten) {
21418 $p3y = $y00+$bl;
21419 $p4y = $y00+$bl;
21420 }
21421
21422 $shadow .= sprintf('%.3F %.3F l ', ($p3x )*_MPDFK, ($this->h-($p3y ))*_MPDFK);
21423 $patch_array[5]['f']=2;
21424 $patch_array[5]['points']=array($p2x,$p2y,
21425 $p3x,$p3y, $p3x,$p3y, $p3x,$p3y,
21426 $p4c1x,$p4y, $p4x,$p4y, $p4x,$p4y,
21427 $p1x,$p1y);
21428 $patch_array[5]['colors'] = array($col1,$col2);
21429
21430 // TOP LEFT corner
21431 $p1x = $x00+$bl; // control points only matches p3 preceding
21432 $p1y = $y00+$d1+$brbgTL_V; $p1c2y = $p1y - ($d2+$brbgTL_V)*$mag;
21433 $p2x = $x00; // control point only matches p4 preceding
21434 $p2y = $y00+$d1+$brbgTL_V; $p2c2y = $p2y - ($d1+$brbgTL_V)*$mag;
21435 $p3x = $x00+$d1+$brbgTL_H; $p3c1x = $p3x - ($d1+$brbgTL_H)*$mag;
21436 $p3y = $y00; $p3c2y = $p3y + $bl/2;
21437 $p4x = $x00+$d1+$brbgTL_H; $p4c2x = $p4x - ($d2+$brbgTL_H)*$mag;
21438 $p4y = $y00+$bl;
21439
21440 if (-$d2 > min($brbgTL_H, $brbgTL_V) || $flatten) {
21441 $p1y = $y00+$bl; $p1c2y = $p1y;
21442 $p2y = $y00+$bl; $p2c2y = $p2y - $bl*$mag2;
21443 $p3x = $x00+$bl; $p3c1x = $p3x - $bl*$mag2;
21444 $p4x = $x00+$bl; $p4c2x = $p4x ;
21445 }
21446
21447 $shadow .= sprintf('%.3F %.3F %.3F %.3F %.3F %.3F c ', ($p1x)*_MPDFK, ($this->h-($p1c2y))*_MPDFK, ($p4c2x)*_MPDFK, ($this->h-($p4y))*_MPDFK, ($p4x)*_MPDFK, ($this->h-($p4y))*_MPDFK);
21448 $patch_array[6]['f']=2;
21449 $patch_array[6]['points']=array($p2x,$p2c2y,
21450 $p3c1x,$p3y, $p3x,$p3y, $p3x,$p3c2y,
21451 $p4x,$p4y, $p4x,$p4y, $p4c2x,$p4y,
21452 $p1x,$p1c2y);
21453 $patch_array[6]['colors'] = array($col2,$col1);
21454
21455
21456 // TOP - joins on the right (C3-C4 of previous): f = 2
21457 $p1x = $x00+$d1+$brbgTL_H; // control point only matches p3 preceding
21458 $p1y = $y00;
21459 $p2x = $x00+$d1+$brbgTL_H; // control point only matches p4 preceding
21460 $p2y = $y00+$bl;
21461 $p3x = $x00+$w00-$d1-$brbgTR_H;
21462 $p3y = $y00+$bl;
21463 $p4x = $x00+$w00-$d1-$brbgTR_H;
21464 $p4y = $y00; $p4c1y = $p4y + $bl/2;
21465 if (-$d2 > min($brbgTL_H, $brbgTL_V) || $flatten) {
21466 $p1x = $x00+$bl;
21467 $p2x = $x00+$bl;
21468 }
21469 if (-$d2 > min($brbgTR_H, $brbgTR_V) || $flatten) {
21470 $p3x = $x00+$w00-$bl;
21471 $p4x = $x00+$w00-$bl;
21472 }
21473
21474 $shadow .= sprintf('%.3F %.3F l ', ($p3x )*_MPDFK, ($this->h-($p3y ))*_MPDFK);
21475 $patch_array[7]['f']=2;
21476 $patch_array[7]['points']=array($p2x,$p2y,
21477 $p3x,$p3y, $p3x,$p3y, $p3x,$p3y,
21478 $p4x,$p4c1y, $p4x,$p4y, $p4x,$p4y,
21479 $p1x,$p1y);
21480 $patch_array[7]['colors'] = array($col1,$col2);
21481
21482 $shadow .= ' h f Q '."\n"; // Close path and Fill the inner solid shadow
21483
21484 if ($bl) $shadow .= $this->grad->CoonsPatchMesh($x00,$y00,$w00,$h00,$patch_array,$x00,$x00+$w00,$y00,$y00+$h00, $colspace, true);
21485
21486 if ($sh['x'] || $sh['y']) $shadow .= ' Q'."\n"; // Shadow Offset
21487 $shadow .= ' Q'."\n"; // Ends path no-op & Sets the clipping path
21488
21489 }
21490 }
21491
21492 $s .= ' W n '; // Ends path no-op & Sets the clipping path
21493
21494 if ($this->blk[$blvl]['bgcolor']) {
21495 $this->pageBackgrounds[$blvl][] = array('x'=>$x0, 'y'=>$y0, 'w'=>$w, 'h'=>$h, 'col'=>$this->blk[$blvl]['bgcolorarray'], 'clippath'=>$s, 'visibility'=>$this->visibility, 'shadow'=>$shadow, 'z-index'=>$this->current_layer); // mPDF 5.6.01
21496 }
21497 else if ($shadow) {
21498 $this->pageBackgrounds[$blvl][] = array('shadowonly'=>true, 'col'=>'', 'clippath'=>'', 'visibility'=>$this->visibility, 'shadow'=>$shadow, 'z-index'=>$this->current_layer); // mPDF 5.6.01
21499 }
21500
21501 /*-- BACKGROUNDS --*/
21502 if (isset($this->blk[$blvl]['gradient'])) {
21503 $g = $this->grad->parseBackgroundGradient($this->blk[$blvl]['gradient']);
21504 if ($g) {
21505 $gx = $x0;
21506 $gy = $y0;
21507 $this->pageBackgrounds[$blvl][] = array('gradient'=>true, 'x'=>$gx, 'y'=>$gy, 'w'=>$w, 'h'=>$h, 'gradtype'=>$g['type'], 'stops'=>$g['stops'], 'colorspace'=>$g['colorspace'], 'coords'=>$g['coords'], 'extend'=>$g['extend'], 'clippath'=>$s, 'visibility'=>$this->visibility, 'z-index'=>$this->current_layer); // mPDF 5.6.01
21508 }
21509 }
21510 if (isset($this->blk[$blvl]['background-image'])) {
21511 if ($this->blk[$blvl]['background-image']['gradient'] && preg_match('/(-moz-)*(repeating-)*(linear|radial)-gradient/', $this->blk[$blvl]['background-image']['gradient'] )) {
21512 $g = $this->grad->parseMozGradient( $this->blk[$blvl]['background-image']['gradient'] );
21513 if ($g) {
21514 $gx = $x0;
21515 $gy = $y0;
21516 // mPDF 5.6.11
21517 // origin specifies the background-positioning-area (bpa)
21518 if ($this->blk[$blvl]['background-image']['origin'] == 'padding-box') {
21519 $gx += $this->blk[$blvl]['border_left']['w'];
21520 $w -= ($this->blk[$blvl]['border_left']['w'] + $this->blk[$blvl]['border_right']['w']);
21521 if ($this->blk[$blvl]['border_top'] && $divider != 'pagetop' && !$continuingpage) {
21522 $gy += $this->blk[$blvl]['border_top']['w'];
21523 }
21524 if ($this->blk[$blvl]['border_bottom'] && $blockstate != 1 && $divider != 'pagebottom') {
21525 $gy1 = $y1 - $this->blk[$blvl]['border_bottom']['w'];
21526 }
21527 else { $gy1 = $y1; }
21528 $h = $gy1 - $gy;
21529 }
21530 else if ($this->blk[$blvl]['background-image']['origin'] == 'content-box') {
21531 $gx += $this->blk[$blvl]['border_left']['w'] + $this->blk[$blvl]['padding_left'];
21532 $w -= ($this->blk[$blvl]['border_left']['w'] + $this->blk[$blvl]['padding_left'] + $this->blk[$blvl]['border_right']['w'] + $this->blk[$blvl]['padding_right']);
21533 if ($this->blk[$blvl]['border_top'] && $divider != 'pagetop' && !$continuingpage) {
21534 $gy += $this->blk[$blvl]['border_top']['w'] + $this->blk[$blvl]['padding_top'];
21535 }
21536 if ($this->blk[$blvl]['border_bottom'] && $blockstate != 1 && $divider != 'pagebottom') {
21537 $gy1 = $y1 - ($this->blk[$blvl]['border_bottom']['w'] + $this->blk[$blvl]['padding_bottom']);
21538 }
21539 else { $gy1 = $y1 - $this->blk[$blvl]['padding_bottom']; }
21540 $h = $gy1 - $gy;
21541 }
21542
21543 if (isset($this->blk[$blvl]['background-image']['size']['w']) && $this->blk[$blvl]['background-image']['size']['w']) {
21544 $size = $this->blk[$blvl]['background-image']['size'];
21545 if ($size['w']!='contain' && $size['w']!='cover') {
21546 if (stristr($size['w'] ,'%')) {
21547 $size['w'] += 0;
21548 $size['w'] /= 100;
21549 $w *= $size['w'];
21550 }
21551 else if ($size['w']!='auto') {
21552 $w = $size['w'];
21553 }
21554 if (stristr($size['h'] ,'%')) {
21555 $size['h'] += 0;
21556 $size['h'] /= 100;
21557 $h *= $size['h'];
21558 }
21559 else if ($size['h']!='auto') {
21560 $h = $size['h'];
21561 }
21562 }
21563 }
21564 $this->pageBackgrounds[$blvl][] = array('gradient'=>true, 'x'=>$gx, 'y'=>$gy, 'w'=>$w, 'h'=>$h, 'gradtype'=>$g['type'], 'stops'=>$g['stops'], 'colorspace'=>$g['colorspace'], 'coords'=>$g['coords'], 'extend'=>$g['extend'], 'clippath'=>$s, 'visibility'=>$this->visibility, 'z-index'=>$this->current_layer); // mPDF 5.6.01
21565 }
21566 }
21567 else {
21568 $image_id = $this->blk[$blvl]['background-image']['image_id'];
21569 $orig_w = $this->blk[$blvl]['background-image']['orig_w'];
21570 $orig_h = $this->blk[$blvl]['background-image']['orig_h'];
21571 $x_pos = $this->blk[$blvl]['background-image']['x_pos'];
21572 $y_pos = $this->blk[$blvl]['background-image']['y_pos'];
21573 $x_repeat = $this->blk[$blvl]['background-image']['x_repeat'];
21574 $y_repeat = $this->blk[$blvl]['background-image']['y_repeat'];
21575 $resize = $this->blk[$blvl]['background-image']['resize'];
21576 $opacity = $this->blk[$blvl]['background-image']['opacity'];
21577 $itype = $this->blk[$blvl]['background-image']['itype'];
21578 $size = $this->blk[$blvl]['background-image']['size']; // mPDF 5.6.10
21579 // mPDF 5.6.10
21580 // origin specifies the background-positioning-area (bpa)
21581 $bpa = array('x'=>$x0, 'y'=>$y0, 'w'=>$w, 'h'=>$h);
21582 if ($this->blk[$blvl]['background-image']['origin'] == 'padding-box') {
21583 $bpa['x'] = $x0 + $this->blk[$blvl]['border_left']['w'];
21584 $bpa['w'] = $w - ($this->blk[$blvl]['border_left']['w'] + $this->blk[$blvl]['border_right']['w']);
21585 if ($this->blk[$blvl]['border_top'] && $divider != 'pagetop' && !$continuingpage) {
21586 $bpa['y'] = $y0 + $this->blk[$blvl]['border_top']['w'];
21587 }
21588 else { $bpa['y'] = $y0; }
21589 if ($this->blk[$blvl]['border_bottom'] && $blockstate != 1 && $divider != 'pagebottom') {
21590 $bpay = $y1 - $this->blk[$blvl]['border_bottom']['w'];
21591 }
21592 else { $bpay = $y1; }
21593 $bpa['h'] = $bpay - $bpa['y'];
21594 }
21595 // mPDF 5.6.09
21596 else if ($this->blk[$blvl]['background-image']['origin'] == 'content-box') {
21597 $bpa['x'] = $x0 + $this->blk[$blvl]['border_left']['w'] + $this->blk[$blvl]['padding_left'];
21598 $bpa['w'] = $w - ($this->blk[$blvl]['border_left']['w'] + $this->blk[$blvl]['padding_left'] + $this->blk[$blvl]['border_right']['w'] + $this->blk[$blvl]['padding_right']);
21599 if ($this->blk[$blvl]['border_top'] && $divider != 'pagetop' && !$continuingpage) {
21600 $bpa['y'] = $y0 + $this->blk[$blvl]['border_top']['w'] + $this->blk[$blvl]['padding_top'];
21601 }
21602 else { $bpa['y'] = $y0 + $this->blk[$blvl]['padding_top']; }
21603 if ($this->blk[$blvl]['border_bottom'] && $blockstate != 1 && $divider != 'pagebottom') {
21604 $bpay = $y1 - ($this->blk[$blvl]['border_bottom']['w'] + $this->blk[$blvl]['padding_bottom']);
21605 }
21606 else { $bpay = $y1 - $this->blk[$blvl]['padding_bottom']; }
21607 $bpa['h'] = $bpay - $bpa['y'];
21608 }
21609 $this->pageBackgrounds[$blvl][] = array('x'=>$x0, 'y'=>$y0, 'w'=>$w, 'h'=>$h, 'image_id'=>$image_id, 'orig_w'=>$orig_w, 'orig_h'=>$orig_h, 'x_pos'=>$x_pos, 'y_pos'=>$y_pos, 'x_repeat'=>$x_repeat, 'y_repeat'=>$y_repeat, 'clippath'=>$s, 'resize'=>$resize, 'opacity'=>$opacity, 'itype'=>$itype, 'visibility'=>$this->visibility, 'z-index'=>$this->current_layer, 'size'=>$size, 'bpa'=>$bpa ); // mPDF 5.6.01 5.6.10
21610 }
21611 }
21612 /*-- END BACKGROUNDS --*/
21613
21614 // Float DIV
21615 $this->blk[$blvl]['bb_painted'][$this->page] = true;
21616
21617 }
21618
21619 /*-- BORDER-RADIUS --*/
21620
21621 function _EllipseArc($x0, $y0, $rx, $ry, $seg = 1, $part=false, $start=false) { // Anticlockwise segment 1-4 TR-TL-BL-BR (part=1 or 2)
21622 $s = '';
21623 if ($rx<0) { $rx = 0; }
21624 if ($ry<0) { $ry = 0; }
21625 $rx *= _MPDFK;
21626 $ry *= _MPDFK;
21627 $astart = 0;
21628 if ($seg == 1) { // Top Right
21629 $afinish = 90;
21630 $nSeg = 4;
21631 }
21632 else if ($seg == 2) { // Top Left
21633 $afinish = 180;
21634 $nSeg = 8;
21635 }
21636 else if ($seg == 3) { // Bottom Left
21637 $afinish = 270;
21638 $nSeg = 12;
21639 }
21640 else { // Bottom Right
21641 $afinish = 360;
21642 $nSeg = 16;
21643 }
21644 $astart = deg2rad((float) $astart);
21645 $afinish = deg2rad((float) $afinish);
21646 $totalAngle = $afinish - $astart;
21647 $dt = $totalAngle / $nSeg; // segment angle
21648 $dtm = $dt/3;
21649 $x0 *= _MPDFK;
21650 $y0 = ($this->h - $y0) * _MPDFK;
21651 $t1 = $astart;
21652 $a0 = $x0 + ($rx * cos($t1));
21653 $b0 = $y0 + ($ry * sin($t1));
21654 $c0 = -$rx * sin($t1);
21655 $d0 = $ry * cos($t1);
21656 $op = false;
21657 for ($i = 1; $i <= $nSeg; $i++) {
21658 // Draw this bit of the total curve
21659 $t1 = ($i * $dt) + $astart;
21660 $a1 = $x0 + ($rx * cos($t1));
21661 $b1 = $y0 + ($ry * sin($t1));
21662 $c1 = -$rx * sin($t1);
21663 $d1 = $ry * cos($t1);
21664 if ($i>($nSeg-4) && (!$part || ($part == 1 && $i<=$nSeg-2) || ($part == 2 && $i>$nSeg-2))) {
21665 if ($start && !$op) {
21666 $s .= sprintf('%.3F %.3F m ', $a0, $b0);
21667 }
21668 $s .= sprintf('%.3F %.3F %.3F %.3F %.3F %.3F c ', ($a0 + ($c0 * $dtm)), ($b0 + ($d0 * $dtm)), ($a1 - ($c1 * $dtm)) , ($b1 - ($d1 * $dtm)), $a1 , $b1 );
21669 $op = true;
21670 }
21671 $a0 = $a1;
21672 $b0 = $b1;
21673 $c0 = $c1;
21674 $d0 = $d1;
21675 }
21676 return $s;
21677 }
21678 /*-- END BORDER-RADIUS --*/
21679
21680
21681
21682 function PaintDivLnBorder($state=0,$blvl=0,$h) {
21683 // $state = 0 normal; 1 top; 2 bottom; 3 top and bottom
21684 $this->ColDetails[$this->CurrCol]['bottom_margin'] = $this->y + $h;
21685
21686 $save_y = $this->y;
21687
21688 $w = $this->blk[$blvl]['width'];
21689 $x0 = $this->x; // left
21690 $y0 = $this->y; // top
21691 $x1 = $this->x + $w; // bottom
21692 $y1 = $this->y + $h; // bottom
21693
21694 if ($this->blk[$blvl]['border_top'] && ($state==1 || $state==3)) {
21695 $tbd = $this->blk[$blvl]['border_top'];
21696 if (isset($tbd['s']) && $tbd['s']) {
21697 $this->_setBorderLine($tbd);
21698 $this->y = $y0 + ($tbd['w']/2);
21699 // mPDF 5.6.56
21700 if ($tbd['style']=='dotted' || $tbd['style']=='dashed') {
21701 $this->_setDashBorder($tbd['style'],'',$continuingpage,'T');
21702 $this->Line($x0 + ($tbd['w']/2) , $this->y , $x0 + $w - ($tbd['w']/2), $this->y);
21703 }
21704 else {
21705 $this->SetLineJoin(0);
21706 $this->SetLineCap(0);
21707 $this->Line($x0, $this->y , $x0 + $w, $this->y);
21708 }
21709 $this->y += $tbd['w'];
21710 // Reset Corners and Dash off
21711 $this->SetLineJoin(2);
21712 $this->SetLineCap(2);
21713 $this->SetDash();
21714 }
21715 }
21716 if ($this->blk[$blvl]['border_left']) {
21717 $tbd = $this->blk[$blvl]['border_left'];
21718 if (isset($tbd['s']) && $tbd['s']) {
21719 $this->_setBorderLine($tbd);
21720 // mPDF 5.6.56
21721 if ($tbd['style']=='dotted' || $tbd['style']=='dashed') {
21722 $this->y = $y0 + ($tbd['w']/2);
21723 $this->_setDashBorder($tbd['style'],'',$continuingpage,'L');
21724 $this->Line($x0 + ($tbd['w']/2), $this->y, $x0 + ($tbd['w']/2), $y0 + $h -($tbd['w']/2));
21725 }
21726 else {
21727 $this->y = $y0;
21728 $this->SetLineJoin(0);
21729 $this->SetLineCap(0);
21730 $this->Line($x0 + ($tbd['w']/2), $this->y, $x0 + ($tbd['w']/2), $y0 + $h);
21731 }
21732 $this->y += $tbd['w'];
21733 // Reset Corners and Dash off
21734 $this->SetLineJoin(2);
21735 $this->SetLineCap(2);
21736 $this->SetDash();
21737 }
21738 }
21739 if ($this->blk[$blvl]['border_right']) {
21740 $tbd = $this->blk[$blvl]['border_right'];
21741 if (isset($tbd['s']) && $tbd['s']) {
21742 $this->_setBorderLine($tbd);
21743 // mPDF 5.6.56
21744 if ($tbd['style']=='dotted' || $tbd['style']=='dashed') {
21745 $this->y = $y0 + ($tbd['w']/2);
21746 $this->_setDashBorder($tbd['style'],'',$continuingpage,'R');
21747 $this->Line($x0 + $w - ($tbd['w']/2), $this->y, $x0 + $w - ($tbd['w']/2), $y0 + $h - ($tbd['w']/2));
21748 }
21749 else {
21750 $this->y = $y0;
21751 $this->SetLineJoin(0);
21752 $this->SetLineCap(0);
21753 $this->Line($x0 + $w - ($tbd['w']/2), $this->y, $x0 + $w - ($tbd['w']/2), $y0 + $h);
21754 }
21755 $this->y += $tbd['w'];
21756 // Reset Corners and Dash off
21757 $this->SetLineJoin(2);
21758 $this->SetLineCap(2);
21759 $this->SetDash();
21760 }
21761 }
21762 if ($this->blk[$blvl]['border_bottom'] && $state > 1) {
21763 $tbd = $this->blk[$blvl]['border_bottom'];
21764 if (isset($tbd['s']) && $tbd['s']) {
21765 $this->_setBorderLine($tbd);
21766 $this->y = $y0 + $h - ($tbd['w']/2);
21767 // mPDF 5.6.56
21768 if ($tbd['style']=='dotted' || $tbd['style']=='dashed') {
21769 $this->_setDashBorder($tbd['style'],'',$continuingpage,'B');
21770 $this->Line($x0 + ($tbd['w']/2) , $this->y, $x0 + $w - ($tbd['w']/2), $this->y);
21771 }
21772 else {
21773 $this->SetLineJoin(0);
21774 $this->SetLineCap(0);
21775 $this->Line($x0, $this->y, $x0 + $w, $this->y);
21776 }
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 $this->SetDash();
21785 $this->y = $save_y;
21786 }
21787
21788
21789 function PaintImgBorder($objattr,$is_table) {
21790 // Borders are disabled in columns - messes up the repositioning in printcolumnbuffer
21791 if ($this->ColActive) { return ; } // *COLUMNS*
21792 if ($is_table) { $k = $this->shrin_k; } else { $k = 1; }
21793 $h = (isset($objattr['BORDER-HEIGHT']) ? $objattr['BORDER-HEIGHT'] : 0);
21794 $w = (isset($objattr['BORDER-WIDTH']) ? $objattr['BORDER-WIDTH'] : 0);
21795 $x0 = (isset($objattr['BORDER-X']) ? $objattr['BORDER-X'] : 0);
21796 $y0 = (isset($objattr['BORDER-Y']) ? $objattr['BORDER-Y'] : 0);
21797
21798 // BORDERS
21799 if ($objattr['border_top']) {
21800 $tbd = $objattr['border_top'];
21801 if (!empty($tbd['s'])) {
21802 $this->_setBorderLine($tbd,$k);
21803 if ($tbd['style']=='dotted' || $tbd['style']=='dashed') { $this->_setDashBorder($tbd['style'],'','','T'); }
21804 $this->Line($x0, $y0, $x0 + $w, $y0);
21805 // Reset Corners and Dash off
21806 $this->SetLineJoin(2);
21807 $this->SetLineCap(2);
21808 $this->SetDash();
21809 }
21810 }
21811 if ($objattr['border_left']) {
21812 $tbd = $objattr['border_left'];
21813 if (!empty($tbd['s'])) {
21814 $this->_setBorderLine($tbd,$k);
21815 if ($tbd['style']=='dotted' || $tbd['style']=='dashed') { $this->_setDashBorder($tbd['style'],'','','L'); }
21816 $this->Line($x0, $y0, $x0, $y0 + $h);
21817 // Reset Corners and Dash off
21818 $this->SetLineJoin(2);
21819 $this->SetLineCap(2);
21820 $this->SetDash();
21821 }
21822 }
21823 if ($objattr['border_right']) {
21824 $tbd = $objattr['border_right'];
21825 if (!empty($tbd['s'])) {
21826 $this->_setBorderLine($tbd,$k);
21827 if ($tbd['style']=='dotted' || $tbd['style']=='dashed') { $this->_setDashBorder($tbd['style'],'','','R'); }
21828 $this->Line($x0 + $w, $y0, $x0 + $w, $y0 + $h);
21829 // Reset Corners and Dash off
21830 $this->SetLineJoin(2);
21831 $this->SetLineCap(2);
21832 $this->SetDash();
21833 }
21834 }
21835 if ($objattr['border_bottom']) {
21836 $tbd = $objattr['border_bottom'];
21837 if (!empty($tbd['s'])) {
21838 $this->_setBorderLine($tbd,$k);
21839 if ($tbd['style']=='dotted' || $tbd['style']=='dashed') { $this->_setDashBorder($tbd['style'],'','','B'); }
21840 $this->Line($x0, $y0 + $h, $x0 + $w, $y0 + $h);
21841 // Reset Corners and Dash off
21842 $this->SetLineJoin(2);
21843 $this->SetLineCap(2);
21844 $this->SetDash();
21845 }
21846 }
21847 $this->SetDash();
21848 $this->SetAlpha(1);
21849 }
21850
21851 /*-- END HTML-CSS --*/
21852
21853
21854
21855
21856 function Reset() {
21857 $this->SetTColor($this->ConvertColor(0));
21858 $this->SetDColor($this->ConvertColor(0));
21859 $this->SetFColor($this->ConvertColor(255));
21860 $this->SetAlpha(1);
21861 $this->colorarray = '';
21862
21863 $this->spanbgcolorarray = '';
21864 $this->spanbgcolor = false;
21865 $this->spanborder = false;
21866 $this->spanborddet = array();
21867
21868 $this->ResetStyles();
21869
21870 $this->HREF = '';
21871 $this->textparam = array();
21872 $this->SetTextOutline();
21873
21874 $this->SUP = false;
21875 $this->SUB = false;
21876 $this->strike = false;
21877 $this->textshadow = '';
21878
21879 $this->SetFont($this->default_font,'',0,false);
21880 $this->SetFontSize($this->default_font_size,false);
21881
21882 $this->currentfontfamily = '';
21883 $this->currentfontsize = '';
21884
21885 /*-- TABLES --*/
21886 if ($this->tableLevel) {
21887 $this->SetLineHeight('',$this->table_lineheight); // *TABLES*
21888 }
21889 else
21890 /*-- END TABLES --*/
21891 /*-- LISTS --*/
21892
21893 if ($this->listlvl && $this->list_lineheight[$this->listlvl][$this->bulletarray['occur']]) {
21894 $this->SetLineHeight('',$this->list_lineheight[$this->listlvl][$this->bulletarray['occur']]); // sets default line height
21895 }
21896 else
21897 /*-- END LISTS --*/
21898 if (isset($this->blk[$this->blklvl]['line_height']) && $this->blk[$this->blklvl]['line_height']) {
21899 $this->SetLineHeight('',$this->blk[$this->blklvl]['line_height']); // sets default line height
21900 }
21901
21902 $this->toupper = false;
21903 $this->tolower = false;
21904 $this->kerning = false;
21905 $this->lSpacingCSS = '';
21906 $this->wSpacingCSS = '';
21907 $this->fixedlSpacing = false;
21908 $this->minwSpacing = 0;
21909 $this->capitalize = false;
21910 $this->SetDash(); //restore to no dash
21911 $this->dash_on = false;
21912 $this->dotted_on = false;
21913 $this->divwidth = 0;
21914 $this->divheight = 0;
21915 $this->divalign = '';
21916 $this->divrevert = false;
21917 $this->oldy = -1;
21918
21919 $bodystyle = array();
21920 if (isset($this->cssmgr->CSS['BODY']['FONT-STYLE'])) { $bodystyle['FONT-STYLE'] = $this->cssmgr->CSS['BODY']['FONT-STYLE']; }
21921 if (isset($this->cssmgr->CSS['BODY']['FONT-WEIGHT'])) { $bodystyle['FONT-WEIGHT'] = $this->cssmgr->CSS['BODY']['FONT-WEIGHT']; }
21922 if (isset($this->cssmgr->CSS['BODY']['COLOR'])) { $bodystyle['COLOR'] = $this->cssmgr->CSS['BODY']['COLOR']; }
21923 if (isset($bodystyle)) { $this->setCSS($bodystyle,'BLOCK','BODY'); }
21924
21925 }
21926
21927 /*-- HTML-CSS --*/
21928 function ReadMetaTags($html) {
21929 // changes anykey=anyvalue to anykey="anyvalue" (only do this when this happens inside tags)
21930 $regexp = '/ (\\w+?)=([^\\s>"]+)/si';
21931 $html = preg_replace($regexp," \$1=\"\$2\"",$html);
21932 if (preg_match('/<title>(.*?)<\/title>/si',$html,$m)) {
21933 $this->SetTitle($m[1]);
21934 }
21935 preg_match_all('/<meta [^>]*?(name|content)="([^>]*?)" [^>]*?(name|content)="([^>]*?)".*?>/si',$html,$aux);
21936 $firstattr = $aux[1];
21937 $secondattr = $aux[3];
21938 for( $i = 0 ; $i < count($aux[0]) ; $i++) {
21939
21940 $name = ( strtoupper($firstattr[$i]) == "NAME" )? strtoupper($aux[2][$i]) : strtoupper($aux[4][$i]);
21941 $content = ( strtoupper($firstattr[$i]) == "CONTENT" )? $aux[2][$i] : $aux[4][$i];
21942 switch($name) {
21943 case "KEYWORDS": $this->SetKeywords($content); break;
21944 case "AUTHOR": $this->SetAuthor($content); break;
21945 case "DESCRIPTION": $this->SetSubject($content); break;
21946 }
21947 }
21948 }
21949
21950
21951 function ReadCharset($html) {
21952 // Charset conversion
21953 if ($this->allow_charset_conversion) {
21954 if (preg_match('/<head.*charset=([^\'\"\s]*).*<\/head>/si',$html,$m)) {
21955 if (strtoupper($m[1]) != 'UTF-8') {
21956 $this->charset_in = strtoupper($m[1]);
21957 }
21958 }
21959 }
21960 }
21961
21962 function setCSS($arrayaux,$type='',$tag='') { // type= INLINE | BLOCK | LIST // tag= BODY
21963 if (!is_array($arrayaux)) return; //Removes PHP Warning
21964 // Set font size first so that e.g. MARGIN 0.83em works on font size for this element
21965 if (isset($arrayaux['FONT-SIZE'])) {
21966 $v = $arrayaux['FONT-SIZE'];
21967 if(is_numeric($v[0])) {
21968 if ($type == 'BLOCK' && $this->blklvl>0 && isset($this->blk[$this->blklvl-1]['InlineProperties']) && isset($this->blk[$this->blklvl-1]['InlineProperties']['size'])) {
21969 $mmsize = $this->ConvertSize($v,$this->blk[$this->blklvl-1]['InlineProperties']['size']);
21970 }
21971 else {
21972 $mmsize = $this->ConvertSize($v,$this->FontSize);
21973 }
21974 $this->SetFontSize( $mmsize*(_MPDFK),false ); //Get size in points (pt)
21975 }
21976 else{
21977 $v = strtoupper($v);
21978 if (isset($this->fontsizes[$v])) {
21979 $this->SetFontSize( $this->fontsizes[$v]* $this->default_font_size,false);
21980 }
21981 }
21982 if ($tag == 'BODY') { $this->SetDefaultFontSize($this->FontSizePt); }
21983 }
21984
21985
21986 if ($this->useLang && !$this->usingCoreFont) {
21987 if (isset($arrayaux['LANG']) && $arrayaux['LANG'] && $arrayaux['LANG'] != $this->default_lang && ((strlen($arrayaux['LANG']) == 5 && $arrayaux['LANG'] != 'UTF-8') || strlen($arrayaux['LANG']) == 2)) {
21988 list ($coreSuitable,$mpdf_pdf_unifonts) = GetLangOpts($arrayaux['LANG'], $this->useAdobeCJK);
21989 if ($mpdf_pdf_unifonts) { $this->RestrictUnicodeFonts($mpdf_pdf_unifonts); }
21990 else { $this->RestrictUnicodeFonts($this->default_available_fonts ); }
21991 if ($tag == 'BODY') {
21992 $this->currentLang = $arrayaux['LANG'];
21993 $this->default_lang = $arrayaux['LANG'];
21994 if ($mpdf_pdf_unifonts) { $this->default_available_fonts = $mpdf_pdf_unifonts; }
21995 }
21996 }
21997 else {
21998 $this->RestrictUnicodeFonts($this->default_available_fonts );
21999 }
22000 }
22001
22002 // FOR INLINE and BLOCK OR 'BODY'
22003 if (isset($arrayaux['FONT-FAMILY'])) {
22004 $v = $arrayaux['FONT-FAMILY'];
22005 //If it is a font list, get all font types
22006 $aux_fontlist = explode(",",$v);
22007 $found = 0;
22008 foreach($aux_fontlist AS $f) {
22009 $fonttype = trim($f);
22010 $fonttype = preg_replace('/["\']*(.*?)["\']*/','\\1',$fonttype);
22011 $fonttype = preg_replace('/ /','',$fonttype);
22012 $v = strtolower(trim($fonttype));
22013 if (isset($this->fonttrans[$v]) && $this->fonttrans[$v]) { $v = $this->fonttrans[$v]; }
22014 if ((!$this->onlyCoreFonts && in_array($v,$this->available_unifonts)) ||
22015 in_array($v,array('ccourier','ctimes','chelvetica')) ||
22016 ($this->onlyCoreFonts && in_array($v,array('courier','times','helvetica','arial'))) ||
22017 in_array($v, array('sjis','uhc','big5','gb'))) {
22018 $fonttype = $v;
22019 $found = 1;
22020 break;
22021 }
22022 }
22023 if (!$found) {
22024 foreach($aux_fontlist AS $f) {
22025 $fonttype = trim($f);
22026 $fonttype = preg_replace('/["\']*(.*?)["\']*/','\\1',$fonttype);
22027 $fonttype = preg_replace('/ /','',$fonttype);
22028 $v = strtolower(trim($fonttype));
22029 if (isset($this->fonttrans[$v]) && $this->fonttrans[$v]) { $v = $this->fonttrans[$v]; }
22030 if (in_array($v,$this->sans_fonts) || in_array($v,$this->serif_fonts) || in_array($v,$this->mono_fonts) ) {
22031 $fonttype = $v;
22032 break;
22033 }
22034 }
22035 }
22036
22037 if ($tag == 'BODY') {
22038 $this->SetDefaultFont($fonttype);
22039 }
22040 $this->SetFont($fonttype,$this->currentfontstyle,0,false);
22041 }
22042 else {
22043 $this->SetFont($this->currentfontfamily,$this->currentfontstyle,0,false);
22044 }
22045
22046 foreach($arrayaux as $k => $v) {
22047 if ($type != 'INLINE' && $tag != 'BODY' && $type != 'LIST') {
22048 switch($k){
22049 // BORDERS
22050 case 'BORDER-TOP':
22051 $this->blk[$this->blklvl]['border_top'] = $this->border_details($v);
22052 if ($this->blk[$this->blklvl]['border_top']['s']) { $this->blk[$this->blklvl]['border'] = 1; }
22053 break;
22054 case 'BORDER-BOTTOM':
22055 $this->blk[$this->blklvl]['border_bottom'] = $this->border_details($v);
22056 if ($this->blk[$this->blklvl]['border_bottom']['s']) { $this->blk[$this->blklvl]['border'] = 1; }
22057 break;
22058 case 'BORDER-LEFT':
22059 $this->blk[$this->blklvl]['border_left'] = $this->border_details($v);
22060 if ($this->blk[$this->blklvl]['border_left']['s']) { $this->blk[$this->blklvl]['border'] = 1; }
22061 break;
22062 case 'BORDER-RIGHT':
22063 $this->blk[$this->blklvl]['border_right'] = $this->border_details($v);
22064 if ($this->blk[$this->blklvl]['border_right']['s']) { $this->blk[$this->blklvl]['border'] = 1; }
22065 break;
22066
22067 // PADDING
22068 case 'PADDING-TOP':
22069 $this->blk[$this->blklvl]['padding_top'] = $this->ConvertSize($v,$this->blk[$this->blklvl-1]['inner_width'],$this->FontSize,false);
22070 break;
22071 case 'PADDING-BOTTOM':
22072 $this->blk[$this->blklvl]['padding_bottom'] = $this->ConvertSize($v,$this->blk[$this->blklvl-1]['inner_width'],$this->FontSize,false);
22073 break;
22074 case 'PADDING-LEFT':
22075 $this->blk[$this->blklvl]['padding_left'] = $this->ConvertSize($v,$this->blk[$this->blklvl-1]['inner_width'],$this->FontSize,false);
22076 break;
22077 case 'PADDING-RIGHT':
22078 $this->blk[$this->blklvl]['padding_right'] = $this->ConvertSize($v,$this->blk[$this->blklvl-1]['inner_width'],$this->FontSize,false);
22079 break;
22080
22081 // MARGINS
22082 case 'MARGIN-TOP':
22083 $tmp = $this->ConvertSize($v,$this->blk[$this->blklvl-1]['inner_width'],$this->FontSize,false);
22084 if (isset($this->blk[$this->blklvl]['lastbottommargin'])) {
22085 if ($tmp > $this->blk[$this->blklvl]['lastbottommargin']) {
22086 $tmp -= $this->blk[$this->blklvl]['lastbottommargin'];
22087 }
22088 else {
22089 $tmp = 0;
22090 }
22091 }
22092 $this->blk[$this->blklvl]['margin_top'] = $tmp;
22093 break;
22094 case 'MARGIN-BOTTOM':
22095 $this->blk[$this->blklvl]['margin_bottom'] = $this->ConvertSize($v,$this->blk[$this->blklvl-1]['inner_width'],$this->FontSize,false);
22096 break;
22097 case 'MARGIN-LEFT':
22098 $this->blk[$this->blklvl]['margin_left'] = $this->ConvertSize($v,$this->blk[$this->blklvl-1]['inner_width'],$this->FontSize,false);
22099 break;
22100 case 'MARGIN-RIGHT':
22101 $this->blk[$this->blklvl]['margin_right'] = $this->ConvertSize($v,$this->blk[$this->blklvl-1]['inner_width'],$this->FontSize,false);
22102 break;
22103
22104 /*-- BORDER-RADIUS --*/
22105 case 'BORDER-TOP-LEFT-RADIUS-H':
22106 $this->blk[$this->blklvl]['border_radius_TL_H'] = $this->ConvertSize($v,$this->blk[$this->blklvl-1]['inner_width'],$this->FontSize,false);
22107 break;
22108 case 'BORDER-TOP-LEFT-RADIUS-V':
22109 $this->blk[$this->blklvl]['border_radius_TL_V'] = $this->ConvertSize($v,$this->blk[$this->blklvl-1]['inner_width'],$this->FontSize,false);
22110 break;
22111 case 'BORDER-TOP-RIGHT-RADIUS-H':
22112 $this->blk[$this->blklvl]['border_radius_TR_H'] = $this->ConvertSize($v,$this->blk[$this->blklvl-1]['inner_width'],$this->FontSize,false);
22113 break;
22114 case 'BORDER-TOP-RIGHT-RADIUS-V':
22115 $this->blk[$this->blklvl]['border_radius_TR_V'] = $this->ConvertSize($v,$this->blk[$this->blklvl-1]['inner_width'],$this->FontSize,false);
22116 break;
22117 case 'BORDER-BOTTOM-LEFT-RADIUS-H':
22118 $this->blk[$this->blklvl]['border_radius_BL_H'] = $this->ConvertSize($v,$this->blk[$this->blklvl-1]['inner_width'],$this->FontSize,false);
22119 break;
22120 case 'BORDER-BOTTOM-LEFT-RADIUS-V':
22121 $this->blk[$this->blklvl]['border_radius_BL_V'] = $this->ConvertSize($v,$this->blk[$this->blklvl-1]['inner_width'],$this->FontSize,false);
22122 break;
22123 case 'BORDER-BOTTOM-RIGHT-RADIUS-H':
22124 $this->blk[$this->blklvl]['border_radius_BR_H'] = $this->ConvertSize($v,$this->blk[$this->blklvl-1]['inner_width'],$this->FontSize,false);
22125 break;
22126 case 'BORDER-BOTTOM-RIGHT-RADIUS-V':
22127 $this->blk[$this->blklvl]['border_radius_BR_V'] = $this->ConvertSize($v,$this->blk[$this->blklvl-1]['inner_width'],$this->FontSize,false);
22128 break;
22129 /*-- END BORDER-RADIUS --*/
22130
22131 case 'BOX-SHADOW':
22132 $bs = $this->cssmgr->setCSSboxshadow($v);
22133 if ($bs) { $this->blk[$this->blklvl]['box_shadow'] = $bs; }
22134 break;
22135
22136 case 'BACKGROUND-CLIP':
22137 if (strtoupper($v) == 'PADDING-BOX') { $this->blk[$this->blklvl]['background_clip'] = 'padding-box'; }
22138 else if (strtoupper($v) == 'CONTENT-BOX') { $this->blk[$this->blklvl]['background_clip'] = 'content-box'; } // mPDF 5.6.09
22139 break;
22140
22141 case 'PAGE-BREAK-AFTER':
22142 if (strtoupper($v) == 'AVOID') { $this->blk[$this->blklvl]['page_break_after_avoid'] = true; }
22143 else if (strtoupper($v) == 'ALWAYS' || strtoupper($v) == 'LEFT' || strtoupper($v) == 'RIGHT') { $this->blk[$this->blklvl]['page_break_after'] = strtoupper($v) ; }
22144 break;
22145
22146 case 'WIDTH':
22147 if (strtoupper($v) != 'AUTO') {
22148 $this->blk[$this->blklvl]['css_set_width'] = $this->ConvertSize($v,$this->blk[$this->blklvl-1]['inner_width'],$this->FontSize,false);
22149 }
22150 break;
22151
22152 case 'TEXT-INDENT':
22153 // Left as raw value (may include 1% or 2em)
22154 $this->blk[$this->blklvl]['text_indent'] = $v;
22155 break;
22156
22157 }//end of switch($k)
22158 }
22159
22160
22161 if ($type != 'INLINE' && $type != 'LIST') { // includes BODY tag
22162 switch($k){
22163
22164 case 'MARGIN-COLLAPSE': // Custom tag to collapse margins at top and bottom of page
22165 if (strtoupper($v) == 'COLLAPSE') { $this->blk[$this->blklvl]['margin_collapse'] = true; }
22166 break;
22167
22168 case 'LINE-HEIGHT':
22169 $this->blk[$this->blklvl]['line_height'] = $this->fixLineheight($v);
22170 if (!$this->blk[$this->blklvl]['line_height'] ) { $this->blk[$this->blklvl]['line_height'] = $this->normalLineheight; }
22171 break;
22172
22173 case 'TEXT-ALIGN': //left right center justify
22174 switch (strtoupper($v)) {
22175 case 'LEFT':
22176 $this->blk[$this->blklvl]['align']="L";
22177 break;
22178 case 'CENTER':
22179 $this->blk[$this->blklvl]['align']="C";
22180 break;
22181 case 'RIGHT':
22182 $this->blk[$this->blklvl]['align']="R";
22183 break;
22184 case 'JUSTIFY':
22185 $this->blk[$this->blklvl]['align']="J";
22186 break;
22187 }
22188 break;
22189
22190 /*-- BACKGROUNDS --*/
22191 case 'BACKGROUND-GRADIENT':
22192 if ($type == 'BLOCK') {
22193 $this->blk[$this->blklvl]['gradient'] = $v;
22194 }
22195 break;
22196 /*-- END BACKGROUNDS --*/
22197
22198 case 'DIRECTION':
22199 if ($v) { $this->blk[$this->blklvl]['direction'] = strtolower($v); }
22200 break;
22201
22202 }//end of switch($k)
22203 }
22204
22205 // FOR INLINE ONLY
22206 if ($type == 'INLINE' || $type == 'LIST') {
22207 switch($k){
22208 case 'DISPLAY': // Custom tag to collapse margins at top and bottom of page
22209 if (strtoupper($v) == 'NONE') { $this->inlineDisplayOff = true; }
22210 break;
22211 case 'DIRECTION':
22212 break;
22213 }//end of switch($k)
22214 }
22215 // FOR INLINE ONLY
22216 if ($type == 'INLINE') {
22217 switch($k){
22218 // BORDERS
22219 case 'BORDER-TOP':
22220 $this->spanborddet['T'] = $this->border_details($v);
22221 $this->spanborder = true;
22222 break;
22223 case 'BORDER-BOTTOM':
22224 $this->spanborddet['B'] = $this->border_details($v);
22225 $this->spanborder = true;
22226 break;
22227 case 'BORDER-LEFT':
22228 $this->spanborddet['L'] = $this->border_details($v);
22229 $this->spanborder = true;
22230 break;
22231 case 'BORDER-RIGHT':
22232 $this->spanborddet['R'] = $this->border_details($v);
22233 $this->spanborder = true;
22234 break;
22235 // mPDF 5.6.26
22236 case 'VISIBILITY': // block is set in OpenTag
22237 $v = strtolower($v);
22238 if ($v == 'visible' || $v == 'hidden' || $v == 'printonly' || $v == 'screenonly') {
22239 $this->textparam['visibility'] = $v;
22240 }
22241 break;
22242 }//end of switch($k)
22243 }
22244
22245
22246 // FOR INLINE and BLOCK
22247 switch($k){
22248 case 'TEXT-ALIGN': //left right center justify
22249 if (strtoupper($v) == 'NOJUSTIFY' && $this->blk[$this->blklvl]['align']=="J") {
22250 $this->blk[$this->blklvl]['align']="";
22251 }
22252 break;
22253 // bgcolor only - to stay consistent with original html2fpdf
22254 case 'BACKGROUND':
22255 case 'BACKGROUND-COLOR':
22256 $cor = $this->ConvertColor($v);
22257 if ($cor) {
22258 if ($tag == 'BODY') {
22259 $this->bodyBackgroundColor = $cor;
22260 }
22261 else if ($type == 'INLINE' || $type == 'LIST') {
22262 $this->spanbgcolorarray = $cor;
22263 $this->spanbgcolor = true;
22264 }
22265 else {
22266 $this->blk[$this->blklvl]['bgcolorarray'] = $cor;
22267 $this->blk[$this->blklvl]['bgcolor'] = true;
22268 }
22269 }
22270 else if ($type != 'INLINE' && $type != 'LIST') {
22271 if ($this->ColActive || $this->keep_block_together) {
22272 $this->blk[$this->blklvl]['bgcolorarray'] = $this->blk[$this->blklvl-1]['bgcolorarray'] ;
22273 $this->blk[$this->blklvl]['bgcolor'] = $this->blk[$this->blklvl-1]['bgcolor'] ;
22274 }
22275 }
22276 break;
22277
22278 // auto | normal | none
22279 case 'FONT-KERNING':
22280 if ((strtoupper($v) == 'NORMAL' || strtoupper($v) == 'AUTO') && $this->useKerning) { $this->kerning = true; }
22281 else if (strtoupper($v) == 'NONE') { $this->kerning = false; }
22282 break;
22283
22284
22285 // normal | <length>
22286 case 'LETTER-SPACING':
22287 $this->lSpacingCSS = $v;
22288 if (($this->lSpacingCSS || $this->lSpacingCSS==='0') && strtoupper($this->lSpacingCSS) != 'NORMAL') {
22289 $this->fixedlSpacing = $this->ConvertSize($this->lSpacingCSS,$this->FontSize);
22290 }
22291 break;
22292
22293 // normal | <length>
22294 case 'WORD-SPACING':
22295 $this->wSpacingCSS = $v;
22296 if ($this->wSpacingCSS && strtoupper($this->wSpacingCSS) != 'NORMAL') {
22297 $this->minwSpacing = $this->ConvertSize($this->wSpacingCSS,$this->FontSize);
22298 }
22299 break;
22300
22301 case 'FONT-STYLE': // italic normal oblique
22302 switch (strtoupper($v)) {
22303 case 'ITALIC':
22304 case 'OBLIQUE':
22305 $this->SetStyle('I',true);
22306 break;
22307 case 'NORMAL':
22308 $this->SetStyle('I',false);
22309 break;
22310 }
22311 break;
22312
22313 case 'FONT-WEIGHT': // normal bold //Does not support: bolder, lighter, 100..900(step value=100)
22314 switch (strtoupper($v)) {
22315 case 'BOLD':
22316 $this->SetStyle('B',true);
22317 break;
22318 case 'NORMAL':
22319 $this->SetStyle('B',false);
22320 break;
22321 }
22322 break;
22323
22324 case 'VERTICAL-ALIGN': //super and sub only dealt with here e.g. <SUB> and <SUP>
22325 switch (strtoupper($v)) {
22326 case 'SUPER':
22327 $this->SUP=true;
22328 $this->SUB=false; // mPDF 5.6.07
22329 break;
22330 case 'SUB':
22331 $this->SUB=true;
22332 $this->SUP=false; // mPDF 5.6.07
22333 break;
22334 case 'BASELINE': // mPDF 5.6.07
22335 $this->SUB=false;
22336 $this->SUP=false;
22337 break;
22338 }
22339 break;
22340
22341 case 'TEXT-DECORATION': // none underline line-through (strikeout) //Does not support: overline, blink
22342 if (stristr($v,'LINE-THROUGH')) {
22343 $this->strike = true;
22344 }
22345 else if (stristr($v,'UNDERLINE')) {
22346 $this->SetStyle('U',true);
22347 }
22348 else if (stristr($v,'NONE')) {
22349 $this->SetStyle('U',false);
22350 $this->strike = false; // mPDF 5.6.07
22351 }
22352 break;
22353
22354 case 'FONT-VARIANT':
22355 switch (strtoupper($v)) {
22356 case 'SMALL-CAPS':
22357 $this->SetStyle('S',true);
22358 break;
22359 case 'NORMAL':
22360 $this->SetStyle('S',false);
22361 break;
22362 }
22363 break;
22364
22365 case 'TEXT-TRANSFORM': // none uppercase lowercase //Does support: capitalize
22366 switch (strtoupper($v)) { //Not working 100%
22367 case 'CAPITALIZE':
22368 $this->capitalize=true;
22369 break;
22370 case 'UPPERCASE':
22371 $this->toupper=true;
22372 break;
22373 case 'LOWERCASE':
22374 $this->tolower=true;
22375 break;
22376 case 'NONE': break;
22377 }
22378 break;
22379
22380 case 'TEXT-SHADOW':
22381 $ts = $this->cssmgr->setCSStextshadow($v);
22382 if ($ts) { $this->textshadow = $ts; }
22383 break;
22384
22385 case 'HYPHENS': // mPDF 5.6.08
22386 if (strtoupper($v)=='NONE') {
22387 $this->textparam['hyphens'] = 2;
22388 }
22389 else if (strtoupper($v)=='AUTO') {
22390 $this->textparam['hyphens'] = 1;
22391 }
22392 else if (strtoupper($v)=='MANUAL') {
22393 $this->textparam['hyphens'] = 0;
22394 }
22395 break;
22396
22397 case 'TEXT-OUTLINE': // mPDF 5.6.07
22398 if (strtoupper($v)=='NONE') {
22399 $this->textparam['outline-s'] = false;
22400 }
22401 break;
22402
22403 case 'TEXT-OUTLINE-WIDTH': // mPDF 5.6.07
22404 case 'OUTLINE-WIDTH':
22405 switch(strtoupper($v)) {
22406 case 'THIN': $v = '0.03em'; break;
22407 case 'MEDIUM': $v = '0.05em'; break;
22408 case 'THICK': $v = '0.07em'; break;
22409 }
22410 $w = $this->ConvertSize($v,$this->blk[$this->blklvl]['inner_width'],$this->FontSize);
22411 if ($w) {
22412 $this->textparam['outline-WIDTH'] = $w;
22413 $this->textparam['outline-s'] = true;
22414 }
22415 else { $this->textparam['outline-s'] = false; }
22416 break;
22417
22418 case 'TEXT-OUTLINE-COLOR': // mPDF 5.6.07
22419 case 'OUTLINE-COLOR':
22420 if (strtoupper($v) == 'INVERT') {
22421 if ($this->colorarray) {
22422 $cor = $this->colorarray;
22423 $this->textparam['outline-COLOR'] = $this->_invertColor($cor);
22424 }
22425 else {
22426 $this->textparam['outline-COLOR'] = $this->ConvertColor(255);
22427 }
22428 }
22429 else {
22430 $cor = $this->ConvertColor($v);
22431 if ($cor) { $this->textparam['outline-COLOR'] = $cor ; }
22432 }
22433 break;
22434
22435 case 'COLOR': // font color
22436 $cor = $this->ConvertColor($v);
22437 if ($cor) {
22438 $this->colorarray = $cor;
22439 $this->SetTColor($cor);
22440 }
22441 break;
22442
22443
22444 }//end of switch($k)
22445
22446
22447 }//end of foreach
22448 }
22449
22450 /*-- END HTML-CSS --*/
22451
22452
22453 function SetStyle($tag,$enable) {
22454 $this->$tag=$enable;
22455 $style='';
22456 foreach(array('B','I','U','S') as $s) {
22457 if($this->$s) {
22458 $style.=$s;
22459 }
22460 }
22461 if ($this->S && empty($this->upperCase)) { @include(_MPDF_PATH.'includes/upperCase.php'); }
22462 $this->currentfontstyle=$style;
22463 $this->SetFont('',$style,0,false);
22464 }
22465
22466 // Set multiple styles at one $str e.g. "BIS"
22467 function SetStylesArray($arr) {
22468 $style='';
22469 foreach(array('B','I','U','S') as $s) {
22470 if (isset($arr[$s])) {
22471 if ($arr[$s]) {
22472 $this->$s = true;
22473 $style.=$s;
22474 }
22475 else { $this->$s = false; }
22476 }
22477 else if ($this->$s) { $style.=$s; }
22478 }
22479 $this->currentfontstyle=$style;
22480 $this->SetFont('',$style,0,false);
22481 }
22482
22483 // Set multiple styles at one $str e.g. "BIS"
22484 function SetStyles($str) {
22485 $style='';
22486 foreach(array('B','I','U','S') as $s) {
22487 if (strpos($str,$s) !== false) {
22488 $this->$s = true;
22489 $style.=$s;
22490 }
22491 else { $this->$s = false; }
22492 }
22493 $this->currentfontstyle=$style;
22494 $this->SetFont('',$style,0,false);
22495 }
22496
22497 function ResetStyles() {
22498 foreach(array('B','I','U','S') as $s) {
22499 $this->$s = false;
22500 }
22501 $this->currentfontstyle='';
22502 $this->SetFont('','',0,false);
22503 }
22504
22505
22506 function DisableTags($str='')
22507 {
22508 if ($str == '') //enable all tags
22509 {
22510 //Insert new supported tags in the long string below.
22511 $this->enabledtags = "<span><s><strike><del><bdo><big><small><ins><cite><acronym><font><sup><sub><b><u><i><a><strong><em><code><samp><tt><kbd><var><q><table><thead><tfoot><tbody><tr><th><td><ol><ul><li><dl><dt><dd><form><input><select><textarea><option><div><p><h1><h2><h3><h4><h5><h6><pre><center><blockquote><address><hr><img><br><indexentry><indexinsert><bookmark><watermarktext><watermarkimage><tts><ttz><tta><column_break><columnbreak><newcolumn><newpage><page_break><pagebreak><formfeed><columns><toc><tocentry><tocpagebreak><pageheader><pagefooter><setpageheader><setpagefooter><sethtmlpageheader><sethtmlpagefooter><annotation><template><jpgraph><barcode><dottab><caption><textcircle><fieldset><legend><article><aside><figure><figcaption><footer><header><hgroup><nav><section><mark><details><summary><meter><progress><time>"; // mPDF 5.5.09
22512 }
22513 else
22514 {
22515 $str = explode(",",$str);
22516 foreach($str as $v) $this->enabledtags = str_replace(trim($v),'',$this->enabledtags);
22517 }
22518 }
22519
22520
22521 /*-- TABLES --*/
22522
22523 function finaliseCellLineHeight($lhxt, $maxfontsize, $maxlineHeight, $lhfixed, $forceExactLineheight) {
22524 $af = 0; // Above font
22525 $bf = 0; // Below font
22526 $mta = 0; // Maximum top-aligned
22527 $mba = 0; // Maximum bottom-aligned
22528 if ($lhxt['BS']) {
22529 $af = max($af, ($lhxt['BS'] - ($maxfontsize * (0.5 + $this->baselineC))));
22530 }
22531 if ($lhxt['M']) {
22532 $af = max($af, ($lhxt['M'] - $maxfontsize)/2);
22533 $bf = max($bf, ($lhxt['M'] - $maxfontsize)/2);
22534 }
22535 if ($lhxt['TT']) {
22536 $bf = max($bf, ($lhxt['TT'] - $maxfontsize));
22537 }
22538 if ($lhxt['TB']) {
22539 $af = max($af, ($lhxt['TB'] - $maxfontsize));
22540 }
22541 if ($lhxt['T']) {
22542 $mta = max($mta, $lhxt['T']);
22543 }
22544 if ($lhxt['B']) {
22545 $mba = max($mba, $lhxt['B']);
22546 }
22547 if ((!$lhfixed || !$forceExactLineheight) && ($af > (($maxlineHeight - $maxfontsize)/2) || $bf > (($maxlineHeight - $maxfontsize)/2))) {
22548 $maxlineHeight = $maxfontsize + $af + $bf;
22549 }
22550 else if (!$lhfixed) { $af = $bf = ($maxlineHeight - $maxfontsize)/2; }
22551 if ($mta > $maxlineHeight) {
22552 $bf += ($mta - $maxlineHeight);
22553 $maxlineHeight = $mta;
22554 }
22555 if ($mba > $maxlineHeight) {
22556 $af += ($mba - $maxlineHeight);
22557 $maxlineHeight = $mba;
22558 }
22559 return $maxlineHeight;
22560 }
22561
22562 function TableWordWrap($maxwidth, $forcewrap = 0, $textbuffer = '', $def_fontsize, $returnarray=false) { // NB ** returnarray used in flowchart
22563 $biggestword=0;
22564 $toonarrow=false;
22565
22566 $textbuffer[0][0] = preg_replace('/^[ ]*/','',$textbuffer[0][0]);
22567 if ((count($textbuffer) == 0) or ((count($textbuffer) == 1) && ($textbuffer[0][0] == ''))) { return 0; }
22568
22569 $text = '';
22570 $lhfixed = false;
22571 if (preg_match('/([0-9.,]+)mm/',$this->table_lineheight)) { $lhfixed = true; }
22572 if ($lhfixed) { $def_lineheight = $this->_computeLineheight($this->table_lineheight, $def_fontsize);}
22573 else { $def_lineheight = 0; }
22574 // START OF NEW LINE
22575 // Initialise lineheight variables
22576 $maxfontsize = 0;
22577 $forceExactLineheight = true;
22578 $lhxt = array('BS'=>0, 'M'=>0, 'TT'=>0, 'TB'=>0, 'T'=>0, 'B'=>0);
22579 $maxlineHeight = $def_lineheight ;
22580 $ch = 0;
22581 $width = 0;
22582 $ln = 1; // Counts line number
22583 $mxw = $this->GetCharWidth('W',false);
22584 for($cctr=0;$cctr<count($textbuffer);$cctr++) { // mPDF 5.6.22
22585 $chunk = $textbuffer[$cctr]; // mPDF 5.6.22
22586 $line = $chunk[0];
22587 //IMAGE
22588 if (substr($line,0,3) == "\xbb\xa4\xac") { //identifier has been identified!
22589 $objattr = $this->_getObjAttr($line);
22590 if ($objattr['type'] == 'nestedtable') {
22591 // END OF LINE
22592 // Finalise & add lineheight
22593 $ch += $this->finaliseCellLineHeight($lhxt, $maxfontsize, $maxlineHeight, $lhfixed, $forceExactLineheight);
22594 $level = $objattr['level'];
22595 $ih = $this->table[($level+1)][$objattr['nestedcontent']]['h']; // nested table width
22596 $ch += $ih;
22597 // START OF NEW LINE
22598 // Initialise lineheight variables
22599 $ln++;
22600 $maxfontsize = 0;
22601 $forceExactLineheight = true;
22602 $lhxt = array('BS'=>0, 'M'=>0, 'TT'=>0, 'TB'=>0, 'T'=>0, 'B'=>0);
22603 $maxlineHeight = $def_lineheight ;
22604 $width = 0;
22605 $text = "";
22606 continue;
22607 }
22608
22609 list($skipln,$iw,$ih) = $this->inlineObject((isset($specialcontent['type']) ? $specialcontent['type'] : null),0,0, $objattr, $this->lMargin,$width,$maxwidth,$maxlineHeight,false,true);
22610 if ($objattr['type'] == 'hr') {
22611 // END OF LINE
22612 // Finalise & add lineheight
22613 $ch += $this->finaliseCellLineHeight($lhxt, $maxfontsize, $maxlineHeight, $lhfixed, $forceExactLineheight);
22614 // Add HR height
22615 $ch += $ih;
22616 // START OF NEW LINE
22617 // Initialise lineheight variables
22618 $ln++;
22619 $maxfontsize = 0;
22620 $forceExactLineheight = true;
22621 $lhxt = array('BS'=>0, 'M'=>0, 'TT'=>0, 'TB'=>0, 'T'=>0, 'B'=>0);
22622 $maxlineHeight = $def_lineheight ;
22623 $width = 0;
22624 $text = "";
22625 continue;
22626 }
22627
22628 if ($skipln==1 || $skipln==-2) {
22629 // Finish last line
22630 // END OF LINE
22631 // Finalise & add lineheight
22632 $ch += $this->finaliseCellLineHeight($lhxt, $maxfontsize, $maxlineHeight, $lhfixed, $forceExactLineheight);
22633 // START OF NEW LINE
22634 // Initialise lineheight variables
22635 $maxfontsize = 0;
22636 $forceExactLineheight = true;
22637 $lhxt = array('BS'=>0, 'M'=>0, 'TT'=>0, 'TB'=>0, 'T'=>0, 'B'=>0);
22638 $maxlineHeight = $def_lineheight ;
22639 $ln++;
22640 $width = 0;
22641 $text = "";
22642 }
22643 $va = (isset($objattr['vertical-align']) ? $objattr['vertical-align'] : null);
22644 if ($va) {
22645 $lhxt[$va] = max($lhxt[$va], $ih);
22646 }
22647 if ($lhfixed && $ih > $def_fontsize) { $forceExactLineheight = false; }
22648 $maxlineHeight = max($maxlineHeight ,$ih);
22649 $width += $iw;
22650 continue;
22651 }
22652
22653 // SET FONT SIZE/STYLE from $chunk[n]
22654 // FONTSIZE
22655 if(isset($chunk[11]) and $chunk[11] != '') {
22656 if ($this->shrin_k) {
22657 $this->SetFontSize($chunk[11]/$this->shrin_k,false);
22658 }
22659 else {
22660 $this->SetFontSize($chunk[11],false);
22661 }
22662 }
22663 if ($line == "\n") {
22664 // END OF LINE
22665 $maxfontsize = max($maxfontsize,$this->FontSize);
22666 $fh = $this->_computeLineheight($this->table_lineheight);
22667 if ($lhfixed && $this->FontSize > $def_fontsize) {
22668 $fh = $this->FontSize;
22669 $forceExactLineheight = false;
22670 }
22671 $maxlineHeight = max($maxlineHeight,$fh);
22672
22673 // Finalise & add lineheight
22674 $ch += $this->finaliseCellLineHeight($lhxt, $maxfontsize, $maxlineHeight, $lhfixed, $forceExactLineheight);
22675 // START OF NEW LINE
22676 // Initialise lineheight variables
22677 $maxfontsize = 0;
22678 $forceExactLineheight = true;
22679 $lhxt = array('BS'=>0, 'M'=>0, 'TT'=>0, 'TB'=>0, 'T'=>0, 'B'=>0);
22680 $maxlineHeight = $this->_computeLineheight($this->table_lineheight);
22681 $ln++;
22682 $text = "";
22683 $width = 0;
22684 if(isset($chunk[11]) and $chunk[11] != '') {
22685 $this->SetFontSize($this->default_font_size,false);
22686 }
22687 continue;
22688 }
22689
22690 $lbw = $rbw = 0; // Border widths
22691 if(isset($chunk[16]) && !empty($chunk[16])) { //Border
22692 $this->spanborddet = $chunk[16];
22693 if (isset($this->spanborddet['L'])) $lbw = $this->spanborddet['L']['w'];
22694 if (isset($this->spanborddet['R'])) $rbw = $this->spanborddet['R']['w'];
22695 }
22696 if(isset($chunk[15])) { // Word spacing
22697 $this->wSpacingCSS = $chunk[15];
22698 if ($this->wSpacingCSS && strtoupper($this->wSpacingCSS) != 'NORMAL') {
22699 $this->minwSpacing = $this->ConvertSize($this->wSpacingCSS,$this->FontSize);
22700 }
22701 }
22702 if(isset($chunk[14])) { // Letter spacing
22703 $this->lSpacingCSS = $chunk[14];
22704 if (($this->lSpacingCSS || $this->lSpacingCSS==='0') && strtoupper($this->lSpacingCSS) != 'NORMAL') {
22705 $this->fixedlSpacing = $this->ConvertSize($this->lSpacingCSS,$this->FontSize);
22706 }
22707 }
22708 if(isset($chunk[13])) { // Font Kerning
22709 $this->kerning = $chunk[13];
22710 }
22711 if(isset($chunk[9])) { // Text params - Outline, hyphens // mPDF 5.6.08
22712 $this->textparam = $chunk[9];
22713 }
22714 // FONTFAMILY
22715 if(isset($chunk[4]) and $chunk[4] != '') { $font = $this->SetFont($chunk[4],$this->FontStyle,0,false); }
22716
22717 // FONT STYLE B I U
22718 if(isset($chunk[2]) and $chunk[2] != '') {
22719 $this->SetStyles($chunk[2]);
22720 }
22721
22722 $space = $this->GetCharWidth(' ',false);
22723
22724 if (mb_substr($line,0,1,$this->mb_enc ) == ' ') { // line (chunk) starts with a space
22725 $width += $space;
22726 $text .= ' ';
22727 }
22728
22729 if (mb_substr($line,(mb_strlen($line,$this->mb_enc )-1),1,$this->mb_enc ) == ' ') { $lsend = true; } // line (chunk) ends with a space
22730 else { $lsend = false; }
22731 $line= trim($line);
22732 if ($line == '') { continue; }
22733
22734 // mPDF ITERATION
22735 if ($this->iterationCounter) $line = preg_replace('/{iteration ([a-zA-Z0-9_]+)}/','\\1', $line);
22736
22737 $words = explode(' ', $line);
22738
22739 foreach ($words as $k=>$word) {
22740 $word = trim($word);
22741 $wordwidth = $this->GetStringWidth($word);
22742 if ($k==0) { $wordwidth += $lbw; }
22743 if ($k==(count($words)-1)) { $wordwidth += $rbw; }
22744 //maxwidth is insufficient for one word
22745 if ($wordwidth > $maxwidth + 0.0001) {
22746 $firstchunk=true;
22747 while($wordwidth > $maxwidth + 0.0001) {
22748 $chw = 0; // check width
22749 $oneCJKorphan = false;
22750 $mlen = mb_strlen($word, $this->mb_enc );
22751 for ( $i = 0; $i < $mlen; $i++ ) {
22752 $chw = $this->GetStringWidth(mb_substr($word,0,$i+1,$this->mb_enc ));
22753 if ($k==0) { $chw += $lbw; }
22754 if ($k==(count($words)-1)) { $chw += $rbw; }
22755 if ($chw > $maxwidth) {
22756 if ($i==0 && $firstchunk) {
22757 // If first letter of line does not fit
22758 $wordwidth = $maxwidth - 0.0001;
22759 if ($this->debug) { $this->Error("Table cell width calculated less than that needed for one character!"); }
22760 break;
22761 }
22762 /*-- CJK-FONTS --*/
22763 // mPDF 5.6.40 mPDF 5.6.44
22764 if ($this->checkCJK && !$this->usingCoreFont && preg_match("/[".$this->pregCJKchars."]/u", $word)) { // mPDF 5.6.44
22765 if (!$oneCJKorphan && preg_match('/['.$this->CJKoverflow.']$/u',mb_substr($word,0,$i+1,$this->mb_enc )) && $this->allowCJKorphans) {
22766 $wordwidth = $maxwidth - 0.0001;
22767 $oneCJKorphan = true;
22768 continue;
22769 }
22770 $cjkfix = 0;
22771 // Last character that fits is not allowed to end a line - move lastchar(s) to start of next line
22772 if ($i>0 && preg_match("/[".$this->CJKleading."$]/u", mb_substr($word,0,$i,$this->mb_enc ))) {
22773 $cjkfix = 1;
22774 }
22775 // Next character is not allowed to start a new line
22776 else if (preg_match("/[".$this->CJKfollowing."]/u", mb_substr($word,$i,1,$this->mb_enc ))) {
22777 // try squeezing another character(s) onto this line = Oikomi
22778 if ($this->allowCJKorphans && !$oneCJKorphan) {
22779 //if lookahead is not another following char
22780 if ($i==($mlen-1) || ($i<($mlen-1) && !preg_match("/[".$this->CJKfollowing."]/u", mb_substr($word,$i+1,1,$this->mb_enc )))) {
22781 $wordwidth = $maxwidth - 0.0001;
22782 $oneCJKorphan = true;
22783 continue;
22784 }
22785 }
22786 // or move lastchar(s) to next line
22787 $cjkfix = 2;
22788 }
22789 // mPDF 5.6.42
22790 // CJK numerals kept together
22791 else if (preg_match("/([".$this->pregCJKchars."]+[0-9\x{ff10}-\x{ff19}]+$)/u", mb_substr($word,0,$i,$this->mb_enc )) && preg_match("/^([0-9\x{ff10}-\x{ff19}]+[".$this->pregCJKchars."]+)/u", mb_substr($word,$i,16,$this->mb_enc ))) {
22792 $cjkfix = 3;
22793 }
22794 if ($cjkfix) {
22795 //move lastchar(s) to next line
22796 $m0 = mb_substr($word,$i-1,1,$this->mb_enc ); // chars to move
22797 $m1 = mb_substr($word,0,$i-1,$this->mb_enc ); // str after stripped chars to move
22798 $mi = $i - 1;
22799 if ($cjkfix == 3) { $match = "0-9\x{ff10}-\x{ff19}"; }
22800 else { $match = $this->CJKleading; }
22801 while(preg_match("/[".$match."$]/u", $m1) && mb_strlen($m1, $this->mb_enc)>2) {
22802 $m0 = mb_substr($m1,$mi-1,1,$this->mb_enc ).$m0; // chars to move
22803 $m1 = mb_substr($m1,0,$mi-1,$this->mb_enc ); // str after stripped chars to move
22804 $mi--;
22805 }
22806 // Insert $m0 into $word at $i
22807 $word = mb_substr($word,0,$i,$this->mb_enc ) . $m0 . mb_substr($word,$i,mb_strlen($word, $this->mb_enc )-$i,$this->mb_enc );
22808 $mlen = mb_strlen($word, $this->mb_enc ); // increment max for loop counter
22809 }
22810
22811
22812
22813 }
22814 /*-- END CJK-FONTS --*/
22815
22816 if ($text && $firstchunk) {
22817 // END OF LINE
22818 // Finalise & add lineheight
22819 $maxfontsize = max($maxfontsize,$this->FontSize);
22820 $fh = $this->_computeLineheight($this->table_lineheight);
22821 if ($lhfixed && $this->FontSize > $def_fontsize) {
22822 $fh = $this->FontSize;
22823 $forceExactLineheight = false;
22824 }
22825 $maxlineHeight = max($maxlineHeight,$fh);
22826 $ch += $this->finaliseCellLineHeight($lhxt, $maxfontsize, $maxlineHeight, $lhfixed, $forceExactLineheight);
22827 // START OF NEW LINE
22828 // Initialise lineheight variables
22829 $maxfontsize = $this->FontSize;
22830 $forceExactLineheight = true;
22831 $lhxt = array('BS'=>0, 'M'=>0, 'TT'=>0, 'TB'=>0, 'T'=>0, 'B'=>0);
22832 $maxlineHeight = $this->_computeLineheight($this->table_lineheight);
22833 $ln++;
22834 }
22835 // END OF LINE
22836 // Finalise & add lineheight
22837 $maxfontsize = max($maxfontsize,$this->FontSize);
22838 $fh = $this->_computeLineheight($this->table_lineheight);
22839 if ($lhfixed && $this->FontSize > $def_fontsize) {
22840 $fh = $this->FontSize;
22841 $forceExactLineheight = false;
22842 }
22843 $maxlineHeight = max($maxlineHeight,$fh);
22844 $ch += $this->finaliseCellLineHeight($lhxt, $maxfontsize, $maxlineHeight, $lhfixed, $forceExactLineheight);
22845 // START OF NEW LINE
22846 // Initialise lineheight variables
22847 $maxfontsize = $this->FontSize;
22848 $forceExactLineheight = true;
22849 $lhxt = array('BS'=>0, 'M'=>0, 'TT'=>0, 'TB'=>0, 'T'=>0, 'B'=>0);
22850 $maxlineHeight = $this->_computeLineheight($this->table_lineheight);
22851 $ln++;
22852 $mxw = $maxwidth;
22853 $text = mb_substr($word,0,$i,$this->mb_enc );
22854 $word = mb_substr($word,$i,mb_strlen($word, $this->mb_enc )-$i,$this->mb_enc );
22855 $wordwidth = $this->GetStringWidth($word);
22856 $width = 0;
22857 $firstchunk=false;
22858 break;
22859 }
22860 }
22861 if (mb_strlen($word, $this->mb_enc )<2 && $wordwidth > $maxwidth + 0.0001) {
22862 $wordwidth = $maxwidth - 0.0001;
22863 if ($this->debug) { $this->Error("Table cell width calculated less than that needed for single character!"); }
22864 }
22865 $firstchunk=false;
22866 }
22867 }
22868 // Word fits on line...
22869 if ($width + $wordwidth < $maxwidth + 0.0001) {
22870 $mxw = max($mxw, ($width+$wordwidth));
22871 $width += $wordwidth + $space;
22872 $text .= $word.' ';
22873 }
22874 // Word does not fit on line...
22875 else {
22876 // mPDF 5.6.21 hard hyphens
22877 if ($this->textparam['hyphens'] != 2 && preg_match('/\-/',$word)) {
22878 list($hardsuccess,$pre,$post,$prelength) = $this->hardHyphenate($word, ($maxwidth - $width)-$this->GetCharWidth("-", false));
22879 if ($hardsuccess) {
22880 $text .= $pre.'-';
22881 $word = $post;
22882 $wordwidth = $this->GetStringWidth($word);
22883 if ($k==(count($words)-1)) { $wordwidth += $rbw; }
22884 }
22885 }
22886 /*-- HYPHENATION --*/
22887 // Soft Hyphens chr(173)
22888 else if ($this->textparam['hyphens'] != 2 && (!$this->usingCoreFont && preg_match("/\xc2\xad/",$word)) || ($this->usingCoreFont && preg_match("/".chr(173)."/",$word) && ($this->FontFamily!='csymbol' && $this->FontFamily!='czapfdingbats')) ) { // mPDF 5.6.06 5.6.08
22889 list($success,$pre,$post,$prelength) = $this->softHyphenate($word, ($maxwidth - $width));
22890 if ($success) {
22891 $text .= $pre.'-';
22892 $word = $post;
22893 $wordwidth = $this->GetStringWidth($word);
22894 if ($k==(count($words)-1)) { $wordwidth += $rbw; }
22895 }
22896 }
22897 else if ($this->textparam['hyphens'] == 1) { // mPDF 5.6.06 5.6.08
22898 list($success,$pre,$post,$prelength) = $this->hyphenateWord($word, ($maxwidth - $width));
22899 if ($success) {
22900 $text .= $pre.'-';
22901 $word = $post;
22902 $wordwidth = $this->GetStringWidth($word);
22903 if ($k==(count($words)-1)) { $wordwidth += $rbw; }
22904 }
22905 }
22906 /*-- END HYPHENATION --*/
22907
22908
22909 // mPDF 5.6.22
22910 if ( count($textbuffer)>1 && $cctr > 0 && $k==0
22911 && (substr($textbuffer[$cctr][0],0,3) != "\xbb\xa4\xac")
22912 && (substr($textbuffer[$cctr-1][0],0,3) != "\xbb\xa4\xac")
22913 && substr($textbuffer[$cctr-1][0],-1,1) != ' '
22914 && substr($textbuffer[$cctr][0],0,1) != ' '
22915 ) {
22916 // Go back to find a space in a previous chunk of content
22917 $found = false;
22918 for ($ix=$cctr-1;$ix>=0;$ix--) {
22919 if (preg_match('/[ ]/',$textbuffer[$ix][0])) { $found = $ix; break; }
22920 }
22921 if ($found !== false) {
22922 $charpos = strrpos($textbuffer[$found][0],' ');
22923 // mPDF 5.6.24
22924 $a1 = $a2 = $textbuffer[$found];
22925 $a1[0] = "\n";
22926 $a2[0] = substr($textbuffer[$found][0], $charpos+1, strlen($textbuffer[$found][0])-$charpos);
22927 $textbuffer[$found][0] = substr($textbuffer[$found][0], 0, $charpos);
22928 array_insert($textbuffer, $a1, $found+1);
22929 array_insert($textbuffer, $a2, $found+2);
22930 // Initialise all variables
22931 $biggestword=0;
22932 $toonarrow=false;
22933 $lhfixed = false;
22934 if (preg_match('/([0-9.,]+)mm/',$this->table_lineheight)) { $lhfixed = true; }
22935 if ($lhfixed) { $def_lineheight = $this->_computeLineheight($this->table_lineheight, $def_fontsize);}
22936 else { $def_lineheight = 0; }
22937 $maxfontsize = 0;
22938 $forceExactLineheight = true;
22939 $lhxt = array('BS'=>0, 'M'=>0, 'TT'=>0, 'TB'=>0, 'T'=>0, 'B'=>0);
22940 $maxlineHeight = $def_lineheight ;
22941 $ch = 0;
22942 $width = 0;
22943 $ln = 1; // Counts line number
22944 $mxw = $this->GetCharWidth('W',false);
22945 $text = '';
22946
22947 $cctr = -1;
22948 break;
22949 }
22950 }
22951
22952 // END OF LINE
22953 // Finalise & add lineheight
22954 $maxfontsize = max($maxfontsize,$this->FontSize);
22955 $fh = $this->_computeLineheight($this->table_lineheight);
22956 if ($lhfixed && $this->FontSize > $def_fontsize) {
22957 $fh = $this->FontSize;
22958 $forceExactLineheight = false;
22959 }
22960 $maxlineHeight = max($maxlineHeight,$fh);
22961 $ch += $this->finaliseCellLineHeight($lhxt, $maxfontsize, $maxlineHeight, $lhfixed, $forceExactLineheight);
22962 $mxw = $maxwidth;
22963 // START OF NEW LINE
22964 // Initialise lineheight variables
22965 $maxfontsize = $this->FontSize;
22966 $forceExactLineheight = true;
22967 $lhxt = array('BS'=>0, 'M'=>0, 'TT'=>0, 'TB'=>0, 'T'=>0, 'B'=>0);
22968 $maxlineHeight = $this->_computeLineheight($this->table_lineheight);
22969 $ln++;
22970 $width = $wordwidth + $space;
22971 $text = $word.' ';
22972 }
22973 $maxfontsize = max($maxfontsize,$this->FontSize);
22974 $fh = $this->_computeLineheight($this->table_lineheight);
22975 if ($lhfixed && $this->FontSize > $def_fontsize) {
22976 $fh = $this->FontSize;
22977 $forceExactLineheight = false;
22978 }
22979 $maxlineHeight = max($maxlineHeight,$fh);
22980 }
22981
22982 // End of textbuffer chunk
22983 if (!$lsend) {
22984 $width -= $space;
22985 $text = rtrim($text);
22986 }
22987
22988 // RESET FONT SIZE/STYLE
22989 // RESETTING VALUES
22990 //Now we must deactivate what we have used
22991 if(isset($chunk[2]) and $chunk[2] != '') {
22992 $this->ResetStyles();
22993 }
22994 if(isset($chunk[4]) and $chunk[4] != '') {
22995 $this->SetFont($this->default_font,$this->FontStyle,0,false);
22996 }
22997 if(isset($chunk[11]) and $chunk[11] != '') {
22998 $this->SetFontSize($this->default_font_size,false);
22999 }
23000 $this->spanborddet = array();
23001 $this->kerning = false;
23002 $this->lSpacingCSS = '';
23003 $this->wSpacingCSS = '';
23004 $this->fixedlSpacing = false;
23005 $this->minwSpacing = 0;
23006 }
23007 // Finalise lineheight if something output on line and add
23008 if ($width) {
23009 $ch += $this->finaliseCellLineHeight($lhxt, $maxfontsize, $maxlineHeight, $lhfixed, $forceExactLineheight);
23010 }
23011 if ($returnarray) { return array($ch,$ln,$mxw); }
23012 else { return $ch; }
23013
23014 }
23015
23016
23017 function TableCheckMinWidth($maxwidth, $forcewrap = 0, $textbuffer) {
23018 $biggestword=0;
23019 $toonarrow=false;
23020 if ((count($textbuffer) == 0) or ((count($textbuffer) == 1) && ($textbuffer[0][0] == ''))) { return 0; }
23021
23022 foreach ($textbuffer as $chunk) {
23023
23024 $line = $chunk[0];
23025 // mPDF ITERATION
23026 if ($this->iterationCounter) $line = preg_replace('/{iteration ([a-zA-Z0-9_]+)}/','\\1', $line);
23027
23028 // IMAGES & FORM ELEMENTS
23029 if (substr($line,0,3) == "\xbb\xa4\xac") { //inline object - FORM element or IMAGE!
23030 $objattr = $this->_getObjAttr($line);
23031 if ($objattr['type']!='hr' && isset($objattr['width']) && ($objattr['width']/$this->shrin_k) > ($maxwidth + 0.0001) ) {
23032 if (($objattr['width']/$this->shrin_k) > $biggestword) { $biggestword = ($objattr['width']/$this->shrin_k); }
23033 $toonarrow=true;
23034 }
23035 continue;
23036 }
23037
23038 if ($line == "\n") {
23039 continue;
23040 }
23041 $line = trim($line );
23042 // SET FONT SIZE/STYLE from $chunk[n]
23043
23044 // FONTSIZE
23045 if(isset($chunk[11]) and $chunk[11] != '') {
23046 if ($this->shrin_k) {
23047 $this->SetFontSize($chunk[11]/$this->shrin_k,false);
23048 }
23049 else {
23050 $this->SetFontSize($chunk[11],false);
23051 }
23052 }
23053 // FONTFAMILY
23054 if(isset($chunk[4]) and $chunk[4] != '') { $font = $this->SetFont($chunk[4],$this->FontStyle,0,false); }
23055 // B I U
23056 if(isset($chunk[2]) and $chunk[2] != '') {
23057 $this->SetStyles($chunk[2]);
23058 }
23059
23060 $lbw = $rbw = 0; // Border widths
23061 if(isset($chunk[16]) && !empty($chunk[16])) { //Border
23062 $this->spanborddet = $chunk[16];
23063 $lbw = $this->spanborddet['L']['w'];
23064 $rbw = $this->spanborddet['R']['w'];
23065 }
23066 if(isset($chunk[15])) { // Word spacing
23067 $this->wSpacingCSS = $chunk[15];
23068 if ($this->wSpacingCSS && strtoupper($this->wSpacingCSS) != 'NORMAL') {
23069 $this->minwSpacing = $this->ConvertSize($this->wSpacingCSS,$this->FontSize);
23070 }
23071 }
23072 if(isset($chunk[14])) { // Letter spacing
23073 $this->lSpacingCSS = $chunk[14];
23074 if (($this->lSpacingCSS || $this->lSpacingCSS==='0') && strtoupper($this->lSpacingCSS) != 'NORMAL') {
23075 $this->fixedlSpacing = $this->ConvertSize($this->lSpacingCSS,$this->FontSize);
23076 }
23077 }
23078 if(isset($chunk[13])) { // Font Kerning
23079 $this->kerning = $chunk[13];
23080 }
23081
23082 $words = explode(' ', $line);
23083 foreach ($words as $k=>$word) {
23084 $word = trim($word);
23085 $wordwidth = $this->GetStringWidth($word);
23086 if ($k==0) { $wordwidth += $lbw; }
23087 if ($k==(count($words)-1)) { $wordwidth += $rbw; }
23088
23089 //Warn user that maxwidth is insufficient
23090 if ($wordwidth > $maxwidth + 0.0001) {
23091 if ($wordwidth > $biggestword) { $biggestword = $wordwidth; }
23092 $toonarrow=true;
23093 }
23094 }
23095
23096 // RESET FONT SIZE/STYLE
23097 // RESETTING VALUES
23098 //Now we must deactivate what we have used
23099 if(isset($chunk[2]) and $chunk[2] != '') {
23100 $this->ResetStyles();
23101 }
23102 if(isset($chunk[4]) and $chunk[4] != '') {
23103 $this->SetFont($this->default_font,$this->FontStyle,0,false);
23104 }
23105 if(isset($chunk[11]) and $chunk[11] != '') {
23106 $this->SetFontSize($this->default_font_size,false);
23107 }
23108 $this->spanborddet = array();
23109 $this->kerning = false;
23110 $this->lSpacingCSS = '';
23111 $this->wSpacingCSS = '';
23112 $this->fixedlSpacing = false;
23113 $this->minwSpacing = 0;
23114 }
23115
23116 //Return -(wordsize) if word is bigger than maxwidth
23117 // ADDED
23118 if (($toonarrow) && ($this->table_error_report)) {
23119 $this->Error("Word is too long to fit in table - ".$this->table_error_report_param);
23120 }
23121 if ($toonarrow) return -$biggestword;
23122 else return 1;
23123 }
23124
23125 function shrinkTable(&$table,$k) {
23126 $table['border_spacing_H'] /= $k;
23127 $table['border_spacing_V'] /= $k;
23128
23129 $table['padding']['T'] /= $k;
23130 $table['padding']['R'] /= $k;
23131 $table['padding']['B'] /= $k;
23132 $table['padding']['L'] /= $k;
23133
23134 $table['margin']['T'] /= $k;
23135 $table['margin']['R'] /= $k;
23136 $table['margin']['B'] /= $k;
23137 $table['margin']['L'] /= $k;
23138
23139 $table['border_details']['T']['w'] /= $k;
23140 $table['border_details']['R']['w'] /= $k;
23141 $table['border_details']['B']['w'] /= $k;
23142 $table['border_details']['L']['w'] /= $k;
23143
23144 if (isset($table['max_cell_border_width']['T'])) $table['max_cell_border_width']['T'] /= $k;
23145 if (isset($table['max_cell_border_width']['R'])) $table['max_cell_border_width']['R'] /= $k;
23146 if (isset($table['max_cell_border_width']['B'])) $table['max_cell_border_width']['B'] /= $k;
23147 if (isset($table['max_cell_border_width']['L'])) $table['max_cell_border_width']['L'] /= $k;
23148
23149 if ($this->simpleTables){
23150 $table['simple']['border_details']['T']['w'] /= $k;
23151 $table['simple']['border_details']['R']['w'] /= $k;
23152 $table['simple']['border_details']['B']['w'] /= $k;
23153 $table['simple']['border_details']['L']['w'] /= $k;
23154 }
23155
23156 $table['miw'] /= $k;
23157 $table['maw'] /= $k;
23158
23159 if ($this->cacheTables) { $fh = fopen($table['cache'], "r+b"); }
23160
23161 for($j = 0 ; $j < $table['nc'] ; $j++ ) { //columns
23162
23163 $table['wc'][$j]['miw'] /= $k;
23164 $table['wc'][$j]['maw'] /= $k;
23165
23166 // mPDF 5.6.13
23167 if (isset($table['decimal_align'][$j]['maxs0']) && $table['decimal_align'][$j]['maxs0']) { $table['decimal_align'][$j]['maxs0'] /= $k; }
23168 if (isset($table['decimal_align'][$j]['maxs1']) && $table['decimal_align'][$j]['maxs1']) { $table['decimal_align'][$j]['maxs1'] /= $k; }
23169
23170 if (isset($table['wc'][$j]['absmiw']) && $table['wc'][$j]['absmiw'] ) $table['wc'][$j]['absmiw'] /= $k;
23171
23172 for($i = 0 ; $i < $table['nr']; $i++ ) { //rows
23173 if ($this->cacheTables) {
23174 $c = $this->_uncacheCell($table['cells'][$i][$j], '', $fh);
23175 }
23176 else
23177 $c = &$table['cells'][$i][$j];
23178 if (isset($c) && $c) {
23179 if (!$this->simpleTables){
23180 if ($this->packTableData) {
23181 $cell = $this->_unpackCellBorder($c['borderbin'] );
23182 $cell['border_details']['T']['w'] /= $k;
23183 $cell['border_details']['R']['w'] /= $k;
23184 $cell['border_details']['B']['w'] /= $k;
23185 $cell['border_details']['L']['w'] /= $k;
23186 $cell['border_details']['mbw']['TL'] /= $k;
23187 $cell['border_details']['mbw']['TR'] /= $k;
23188 $cell['border_details']['mbw']['BL'] /= $k;
23189 $cell['border_details']['mbw']['BR'] /= $k;
23190 $cell['border_details']['mbw']['LT'] /= $k;
23191 $cell['border_details']['mbw']['LB'] /= $k;
23192 $cell['border_details']['mbw']['RT'] /= $k;
23193 $cell['border_details']['mbw']['RB'] /= $k;
23194 $c['borderbin'] = $this->_packCellBorder($cell);
23195 }
23196 else {
23197 $c['border_details']['T']['w'] /= $k;
23198 $c['border_details']['R']['w'] /= $k;
23199 $c['border_details']['B']['w'] /= $k;
23200 $c['border_details']['L']['w'] /= $k;
23201 $c['border_details']['mbw']['TL'] /= $k;
23202 $c['border_details']['mbw']['TR'] /= $k;
23203 $c['border_details']['mbw']['BL'] /= $k;
23204 $c['border_details']['mbw']['BR'] /= $k;
23205 $c['border_details']['mbw']['LT'] /= $k;
23206 $c['border_details']['mbw']['LB'] /= $k;
23207 $c['border_details']['mbw']['RT'] /= $k;
23208 $c['border_details']['mbw']['RB'] /= $k;
23209 }
23210 }
23211 $c['padding']['T'] /= $k;
23212 $c['padding']['R'] /= $k;
23213 $c['padding']['B'] /= $k;
23214 $c['padding']['L'] /= $k;
23215 $c['maxs'] /= $k;
23216 if (isset($c['w'])) { $c['w'] /= $k; }
23217 $c['s'] /= $k;
23218 $c['maw'] /= $k;
23219 $c['miw'] /= $k;
23220 if (isset($c['absmiw'])) $c['absmiw'] /= $k;
23221 if (isset($c['nestedmaw'])) $c['nestedmaw'] /= $k;
23222 if (isset($c['nestedmiw'])) $c['nestedmiw'] /= $k;
23223 if (isset($c['textbuffer'])) {
23224 foreach($c['textbuffer'] AS $n=>$tb) {
23225 if (!empty($tb[16])) {
23226 $c['textbuffer'][$n][16]['T']['w'] /= $k;
23227 $c['textbuffer'][$n][16]['B']['w'] /= $k;
23228 $c['textbuffer'][$n][16]['L']['w'] /= $k;
23229 $c['textbuffer'][$n][16]['R']['w'] /= $k;
23230 }
23231 }
23232 }
23233 if ($this->cacheTables) {
23234 $this->_cacheCell($c, '', "W", $fh, $table['cells'][$i][$j]);
23235 }
23236 unset($c);
23237 }
23238 }//rows
23239 }//columns
23240 if ($this->cacheTables) { fclose($fh); }
23241 }
23242
23243 function _cacheCell($c, $file, $mode="A", $fh=null, $offset=0) { // mode = Append or (over)Write (needs offset and fh)
23244 // Requires either $file OR $fh (file_handle)
23245 if (!is_array($c) || !isset($c)) { return ''; }
23246
23247 if(isset($c['w'])) { $cw = $c['w']; } else { $cw = -1; }
23248 if(isset($c['w0'])) { $cw0 = $c['w0']; } else { $cw0 = -1; }
23249 if(isset($c['h0'])) { $ch0 = $c['h0']; } else { $ch0 = -1; }
23250
23251 $data = pack("n2d19A1A1n2sA32A128",
23252 $c['colspan'], /* n (16 bit; 2 bytes) [pos 0] */
23253 $c['rowspan'], /* n (16 bit; 2 bytes) [pos 2] */
23254 $c['s'], /* d NB machine-dependent size (64 bit; 8 bytes on test winOS) [pos 4] */
23255 $c['maxs'], /* d NB machine-dependent size [pos 4 + 1*D] */
23256 $c['nestedmaw'], /* d NB machine-dependent size [pos 4 + 2*D] */
23257 $c['nestedmiw'], /* d NB machine-dependent size [pos 4 + 3*D] */
23258 $c['padding']['L'], /* d NB machine-dependent size [pos 4 + 4*D] */
23259 $c['padding']['R'], /* d NB machine-dependent size [pos 4 + 5*D] */
23260 $c['padding']['T'], /* d NB machine-dependent size [pos 4 + 6*D] */
23261 $c['padding']['B'], /* d NB machine-dependent size [pos 4 + 7*D] */
23262 $c['dfs'], /* d NB machine-dependent size [pos 4 + 8*D] */
23263 $cw, /* d NB machine-dependent size [pos 4 + 9*D] */
23264 $c['h'], /* d NB machine-dependent size [pos 4 + 10*D] */
23265 $c['absmiw'], /* d NB machine-dependent size [pos 4 + 11*D] */
23266 $c['maw'], /* d NB machine-dependent size [pos 4 + 12*D] */
23267 $c['miw'], /* d NB machine-dependent size [pos 4 + 13*D] */
23268 $c['mih'], /* d NB machine-dependent size [pos 4 + 14*D] */
23269 $c['x0'], /* d NB machine-dependent size [pos 4 + 15*D] */
23270 $cw0, /* d NB machine-dependent size [pos 4 + 16*D] */
23271 $c['y0'], /* d NB machine-dependent size [pos 4 + 17*D] */
23272 $ch0, /* d NB machine-dependent size [pos 4 + 18*D] */
23273 $c['a'], /* A1 (1 byte) [pos 4 + 19*D] */
23274 $c['va'], /* A1 (1 byte) [pos 5 + 19*D] */
23275 $c['nowrap'], /* 1 or blank n (16 bit; 2 bytes) [pos 6 + 19*D] */
23276 $c['wpercent'], /* 0 - 100 n (16 bit; 2 bytes) [pos 8 + 19*D] */
23277 $c['R'], /* 90 or -90 s (16 bit; 2 bytes) [pos 10 + 19*D] */
23278 $c['bgcolor'], /* A32 (32 bytes) [pos 12 + 19*D] */
23279 $c['gradient'] /* A128 (128 bytes) [pos 44 + 19*D] */
23280 );
23281
23282 if ($c['background-image']) {
23283 $data .= pack("n2d2A6A6n3dA4A128",
23284 strlen($data), /* offset in main data to start of bgimage data */
23285 $c['background-image']['image_id'], /* n */
23286 $c['background-image']['orig_w'], /* d NB machine-dependent size */
23287 $c['background-image']['orig_h'], /* d NB machine-dependent size */
23288 $c['background-image']['x_pos'], /* A6 calc size or "50%" */
23289 $c['background-image']['y_pos'], /* A6 calc size or "50%" */
23290 $c['background-image']['x_repeat'], /* n true or false*/
23291 $c['background-image']['y_repeat'], /* n true or false */
23292 $c['background-image']['resize'], /* n 0 - 6 */
23293 $c['background-image']['opacity'], /* d 0-1 */
23294 $c['background-image']['itype'], /* A4 jpg etc */
23295 $c['background-image']['gradient'] /* A128 CSS string */
23296 );
23297 }
23298 else $data .= pack("n",0);
23299 $tb_offset = 2 + 186 + 2 + strlen($data);
23300 $stb = serialize($c['textbuffer']).' '; // buffer to allow updating in reverseTableDir
23301 $lentb = strlen($stb);
23302 $data2 = pack("nA".$lentb, $lentb, $stb);
23303
23304 $tempfh = true;
23305 if ($mode=="W" && $offset) {
23306 if (!$fh) { $fh = fopen($file, "r+b"); } // Overwrite (but not truncate)
23307 else $tempfh = false;
23308 fseek($fh, $offset);
23309 }
23310 else {
23311 $fh = fopen($file, "ab"); // APPEND
23312 }
23313 fwrite($fh, pack("n",$tb_offset)); // Offset to Text buffer 2 bytes
23314 fwrite($fh, $c['borderbin']); // border details 186 bytes
23315 fwrite($fh, pack("n",strlen($data))); // Length of Main data
23316 fwrite($fh, $data); // Main data
23317 fwrite($fh, $data2); // Text buffer (starts with "n" length of text buffer)
23318 if ($tempfh) fclose($fh);
23319 return ($tb_offset + 2 + $lentb);
23320 }
23321
23322 function _cacheUpdateTxB($c, $fh, $offset) {
23323 fseek($fh, $offset);
23324 $tb_offset = $this->read_short($fh); // First entry = Offset to Text buffer 2 bytes
23325 fseek($fh, ($tb_offset-2), SEEK_CUR);
23326 $lentb = $this->read_short($fh); // First entry in textbuffer = Length of serialized textbuffer - do not update
23327 $stb = serialize($c['textbuffer']);
23328 fwrite($fh, pack("A".$lentb, $stb));
23329 }
23330
23331 function _cacheUpdateBorder($c, $fh, $offset) {
23332 $offset += 2;
23333 fseek($fh, $offset);
23334 fwrite($fh, $c['borderbin']);
23335 }
23336
23337 function _cacheUpdateMtx($c, $fh, $offset, $var) {
23338 if ($var=='mih') { $offset += (2 + 186 + 2 + 4 + 14*_DSIZE); }
23339 else if ($var=='x0') { $offset += (2 + 186 + 2 + 4 + 15*_DSIZE); } // x0 and w0
23340 else if ($var=='y0') { $offset += (2 + 186 + 2 + 4 + 17*_DSIZE); } // y0 and h0
23341 fseek($fh, $offset);
23342 if ($var=='mih') { fwrite($fh, pack("d",$c['mih'])); }
23343 else if ($var=='x0') { fwrite($fh, pack("d2",$c['x0'],$c['w0'])); }
23344 else if ($var=='y0') { fwrite($fh, pack("d2",$c['y0'],$c['h0'])); }
23345 }
23346
23347 function _uncacheCell($ptr, $file, $fh) {
23348 // Requires either $file or $fh (file_handle)
23349 if ($ptr==0) { return null; }
23350 if (is_array($ptr)) { $this->Error("Probable cause - missing end tag &lt;/td&gt;. You may be able to change the configurable variable: allow_html_optional_endtags "); }
23351 $tempfh = true;
23352 if (!$fh) { $fh = fopen($file, "rb"); }
23353 else $tempfh = false;
23354 fseek($fh, $ptr);
23355 $c = array();
23356 $tb_offset = $this->read_short($fh); // First entry = Offset to Text buffer 2 bytes
23357 $c['borderbin'] = fread($fh,186); // border details 186 bytes
23358 $maindatalen = $this->read_short($fh); // Length of Main data (2 bytes)
23359 $str = fread($fh,$maindatalen ); // Main data
23360 $data = unpack("ncolspan/nrowspan/ds/dmaxs/dnmaw/dnmiw/dpl/dpr/dpt/dpb/ddfs/dw/dh/dabsmiw/dmaw/dmiw/dmih/dx0/dw0/dy0/dh0/A1a/A1va/nnowrap/nwpercent/sR/A32bgcol/A128grad/nbgimage", $str);
23361
23362 if ($data['colspan']>0) $c['colspan'] = $data['colspan']; /* n */
23363 if ($data['rowspan']>0) $c['rowspan'] = $data['rowspan']; /* n */
23364 $c['s'] = $data['s']; /* d NB machine-dependent size */
23365 $c['maxs'] = $data['maxs']; /* d NB machine-dependent size */
23366 if ($data['nmaw']>0) $c['nestedmaw'] = $data['nmaw']; /* d NB machine-dependent size */
23367 if ($data['nmiw']>0) $c['nestedmiw'] = $data['nmiw']; /* d NB machine-dependent size */
23368 $c['padding']['L'] = $data['pl']; /* d NB machine-dependent size */
23369 $c['padding']['R'] = $data['pr']; /* d NB machine-dependent size */
23370 $c['padding']['T'] = $data['pt']; /* d NB machine-dependent size */
23371 $c['padding']['B'] = $data['pb']; /* d NB machine-dependent size */
23372 $c['dfs'] = $data['dfs']; /* d NB machine-dependent size */
23373 if ($data['w']>=0) $c['w'] = $data['w']; /* d NB machine-dependent size */
23374 if ($data['h']>0) $c['h'] = $data['h']; /* d NB machine-dependent size */
23375 if ($data['absmiw']>0) $c['absmiw'] = $data['absmiw']; /* d NB machine-dependent size */
23376 if ($data['maw']>0) $c['maw'] = $data['maw']; /* d NB machine-dependent size */
23377 if ($data['miw']>0) $c['miw'] = $data['miw']; /* d NB machine-dependent size */
23378 if ($data['mih']>0) $c['mih'] = $data['mih']; /* d NB machine-dependent size */
23379 if ($data['w0']>=0) { $c['w0'] = $data['w0']; /* d NB machine-dependent size */
23380 $c['x0'] = $data['x0']; } /* d NB machine-dependent size */
23381 if ($data['h0']>=0) { $c['h0'] = $data['h0']; /* d NB machine-dependent size */
23382 $c['y0'] = $data['y0']; } /* d NB machine-dependent size */
23383 $c['a'] = trim($data['a']); /* A1 */
23384 $c['va'] = trim($data['va']); /* A1 */
23385 if ($data['nowrap']) $c['nowrap'] = $data['nowrap']; /* 1 or blank n */
23386 else $c['nowrap'] = false;
23387 if ($data['wpercent']>0) $c['wpercent'] = $data['wpercent']; /* 0 - 100 n */
23388 if ($data['R']<>0) $c['R'] = $data['R']; /* 90 or -90 s */
23389 else $c['R'] = false;
23390 $c['bgcolor'] = trim($data['bgcol']); /* A32 */
23391 if (trim($data['grad']))
23392 $c['gradient'] = trim($data['grad']); /* A128 */
23393 else $c['gradient'] = false;
23394 if ($data['bgimage']>0) {
23395 $bgidata = substr($str, ($data['bgimage']+2));
23396 $c['background-image'] = unpack("nimage_id/dorig_w/dorig_h/A6x_pos/A6y_pos/nx_repeat/ny_repeat/nresize/dopacity/A4itype/A128gradient", $bgidata);
23397 }
23398
23399 $tblen = $this->read_short($fh); // Length of Textbuffer
23400 $tbsp = fread($fh,$tblen); // Textbuffer (serialised and packed)
23401 $tbs = unpack("A".$tblen."textbuffer",$tbsp); // Textbuffer unpacked
23402 $c['textbuffer'] = unserialize(trim($tbs['textbuffer'])); // Textbuffer unserialized
23403
23404 if ($tempfh) { fclose($fh); }
23405 return ($c);
23406 }
23407 function read_short(&$fh) {
23408 $s = fread($fh,2);
23409 $a = (ord($s[0])<<8) + ord($s[1]);
23410 if ($a & (1 << 15) ) {
23411 $a = ($a - (1 << 16));
23412 }
23413 return $a;
23414 }
23415 function _backupCacheFiles() {
23416 foreach($this->table AS $lvl=>$t) {
23417 foreach($this->table[$lvl] AS $c=>$t2) {
23418 ///////////////////////////if (!file_exists($t2['cache'])) { echo $lvl; echo $c; print_r($this->table); exit; }
23419 copy( $t2['cache'], $t2['cache'].'.bak');
23420 }
23421 }
23422 }
23423 function _restoreCacheFiles() {
23424 foreach($this->table AS $lvl=>$t) {
23425 foreach($this->table[$lvl] AS $c=>$t2) {
23426 copy( $t2['cache'].'.bak', $t2['cache']);
23427 }
23428 }
23429 }
23430
23431
23432 function _packCellBorder($cell) {
23433 if (!is_array($cell) || !isset($cell)) { return ''; }
23434
23435 if (!$this->packTableData) { return $cell; }
23436 // = 186 bytes
23437 $bindata = pack("nnda6A10nnda6A10nnda6A10nnda6A10nd9",
23438 $cell['border'],
23439 $cell['border_details']['R']['s'],
23440 $cell['border_details']['R']['w'],
23441 $cell['border_details']['R']['c'],
23442 $cell['border_details']['R']['style'],
23443 $cell['border_details']['R']['dom'],
23444
23445 $cell['border_details']['L']['s'],
23446 $cell['border_details']['L']['w'],
23447 $cell['border_details']['L']['c'],
23448 $cell['border_details']['L']['style'],
23449 $cell['border_details']['L']['dom'],
23450
23451 $cell['border_details']['T']['s'],
23452 $cell['border_details']['T']['w'],
23453 $cell['border_details']['T']['c'],
23454 $cell['border_details']['T']['style'],
23455 $cell['border_details']['T']['dom'],
23456
23457 $cell['border_details']['B']['s'],
23458 $cell['border_details']['B']['w'],
23459 $cell['border_details']['B']['c'],
23460 $cell['border_details']['B']['style'],
23461 $cell['border_details']['B']['dom'],
23462
23463 $cell['border_details']['mbw']['BL'],
23464 $cell['border_details']['mbw']['BR'],
23465 $cell['border_details']['mbw']['RT'],
23466 $cell['border_details']['mbw']['RB'],
23467 $cell['border_details']['mbw']['TL'],
23468 $cell['border_details']['mbw']['TR'],
23469 $cell['border_details']['mbw']['LT'],
23470 $cell['border_details']['mbw']['LB'],
23471
23472 $cell['border_details']['cellposdom']
23473 );
23474 return $bindata;
23475 }
23476
23477
23478
23479 function _getBorderWidths($bindata) {
23480 if (!$bindata) { return array(0,0,0,0); }
23481 if (!$this->packTableData) { return array($bindata['border_details']['T']['w'], $bindata['border_details']['R']['w'], $bindata['border_details']['B']['w'], $bindata['border_details']['L']['w']); }
23482
23483 $bd = unpack("nbord/nrs/drw/a6rca/A10rst/nrd/nls/dlw/a6lca/A10lst/nld/nts/dtw/a6tca/A10tst/ntd/nbs/dbw/a6bca/A10bst/nbd/dmbl/dmbr/dmrt/dmrb/dmtl/dmtr/dmlt/dmlb/dcpd", $bindata);
23484 $cell['border_details']['R']['w'] = $bd['rw'];
23485 $cell['border_details']['L']['w'] = $bd['lw'];
23486 $cell['border_details']['T']['w'] = $bd['tw'];
23487 $cell['border_details']['B']['w'] = $bd['bw'];
23488 return array($bd['tw'], $bd['rw'], $bd['bw'], $bd['lw']);
23489 }
23490
23491
23492 function _unpackCellBorder($bindata) {
23493 if (!$bindata) { return array(); }
23494 if (!$this->packTableData) { return $bindata; }
23495
23496 $bd = unpack("nbord/nrs/drw/a6rca/A10rst/nrd/nls/dlw/a6lca/A10lst/nld/nts/dtw/a6tca/A10tst/ntd/nbs/dbw/a6bca/A10bst/nbd/dmbl/dmbr/dmrt/dmrb/dmtl/dmtr/dmlt/dmlb/dcpd", $bindata);
23497
23498 $cell['border'] = $bd['bord'];
23499 $cell['border_details']['R']['s'] = $bd['rs'];
23500 $cell['border_details']['R']['w'] = $bd['rw'];
23501 $cell['border_details']['R']['c'] = $bd['rca'];
23502 $cell['border_details']['R']['style'] = trim($bd['rst']);
23503 $cell['border_details']['R']['dom'] = $bd['rd'];
23504
23505 $cell['border_details']['L']['s'] = $bd['ls'];
23506 $cell['border_details']['L']['w'] = $bd['lw'];
23507 $cell['border_details']['L']['c'] = $bd['lca'];
23508 $cell['border_details']['L']['style'] = trim($bd['lst']);
23509 $cell['border_details']['L']['dom'] = $bd['ld'];
23510
23511 $cell['border_details']['T']['s'] = $bd['ts'];
23512 $cell['border_details']['T']['w'] = $bd['tw'];
23513 $cell['border_details']['T']['c'] = $bd['tca'];
23514 $cell['border_details']['T']['style'] = trim($bd['tst']);
23515 $cell['border_details']['T']['dom'] = $bd['td'];
23516
23517 $cell['border_details']['B']['s'] = $bd['bs'];
23518 $cell['border_details']['B']['w'] = $bd['bw'];
23519 $cell['border_details']['B']['c'] = $bd['bca'];
23520 $cell['border_details']['B']['style'] = trim($bd['bst']);
23521 $cell['border_details']['B']['dom'] = $bd['bd'];
23522
23523 $cell['border_details']['mbw']['BL'] = $bd['mbl'];
23524 $cell['border_details']['mbw']['BR'] = $bd['mbr'];
23525 $cell['border_details']['mbw']['RT'] = $bd['mrt'];
23526 $cell['border_details']['mbw']['RB'] = $bd['mrb'];
23527 $cell['border_details']['mbw']['TL'] = $bd['mtl'];
23528 $cell['border_details']['mbw']['TR'] = $bd['mtr'];
23529 $cell['border_details']['mbw']['LT'] = $bd['mlt'];
23530 $cell['border_details']['mbw']['LB'] = $bd['mlb'];
23531 $cell['border_details']['cellposdom'] = $bd['cpd'];
23532
23533 return($cell);
23534 }
23535
23536
23537 ////////////////////////TABLE CODE (from PDFTable)/////////////////////////////////////
23538 ////////////////////////TABLE CODE (from PDFTable)/////////////////////////////////////
23539 ////////////////////////TABLE CODE (from PDFTable)/////////////////////////////////////
23540 //table Array of (w, h, bc, nr, wc, hr, cells)
23541 //w Width of table
23542 //h Height of table
23543 //nc Number column
23544 //nr Number row
23545 //hr List of height of each row
23546 //wc List of width of each column
23547 //cells List of cells of each rows, cells[i][j] is a cell in the table
23548 function _tableColumnWidth(&$table,$firstpass=false){
23549 $cs = &$table['cells'];
23550
23551 $nc = $table['nc'];
23552 $nr = $table['nr'];
23553 $listspan = array();
23554
23555 if ($table['borders_separate']) {
23556 $tblbw = $table['border_details']['L']['w'] + $table['border_details']['R']['w'] + $table['margin']['L'] + $table['margin']['R'] + $table['padding']['L'] + $table['padding']['R'] + $table['border_spacing_H'];
23557 }
23558 else { $tblbw = $table['max_cell_border_width']['L']/2 + $table['max_cell_border_width']['R']/2 + $table['margin']['L'] + $table['margin']['R']; }
23559
23560 if ($this->cacheTables) { $fh = fopen($table['cache'], "r+b"); }
23561 else { $fh = null; }
23562
23563 // ADDED table['l'][colno]
23564 // = total length of text approx (using $c['s']) in that column - used to approximately distribute col widths in _tableWidth
23565 //
23566 for($j = 0 ; $j < $nc ; $j++ ) { //columns
23567 $wc = &$table['wc'][$j];
23568 for($i = 0 ; $i < $nr ; $i++ ) { //rows
23569 if (isset($cs[$i][$j]) && $cs[$i][$j]) {
23570 if ($this->cacheTables) {
23571 $c = $this->_uncacheCell($table['cells'][$i][$j], '', $fh);
23572 }
23573 else
23574 $c = &$cs[$i][$j];
23575
23576 if ($this->simpleTables){
23577 if ($table['borders_separate']) { // NB twice border width
23578 $extrcw = $table['simple']['border_details']['L']['w'] + $table['simple']['border_details']['R']['w'] + $c['padding']['L'] + $c['padding']['R'] + $table['border_spacing_H'];
23579 }
23580 else {
23581 $extrcw = $table['simple']['border_details']['L']['w']/2 + $table['simple']['border_details']['R']['w']/2 + $c['padding']['L'] + $c['padding']['R'];
23582 }
23583 }
23584 else {
23585 if ($this->packTableData) {
23586 list($bt,$br,$bb,$bl) = $this->_getBorderWidths($c['borderbin']);
23587 }
23588 else {
23589 $br = $c['border_details']['R']['w'];
23590 $bl = $c['border_details']['L']['w'];
23591 }
23592 if ($table['borders_separate']) { // NB twice border width
23593 $extrcw = $bl + $br + $c['padding']['L'] + $c['padding']['R'] + $table['border_spacing_H'];
23594 }
23595 else {
23596 $extrcw = $bl/2 + $br/2 + $c['padding']['L'] + $c['padding']['R'];
23597 }
23598 }
23599
23600 //$mw = $this->GetStringWidth('W') + $extrcw ;
23601 $mw = 0;
23602 // mPDF 5.6.13 Decimal point alignment
23603 if(substr($c['a'],0,1) == 'D') {
23604 $mw = $table['decimal_align'][$j]['maxs0'] + $table['decimal_align'][$j]['maxs1'] + $extrcw ;
23605 }
23606
23607 $c['absmiw'] = $mw;
23608
23609 if (isset($c['R']) && $c['R']) {
23610 $c['maw'] = $c['miw'] = $this->FontSize + $extrcw ;
23611 if (isset($c['w'])) { // If cell width is specified
23612 if ($c['miw'] <$c['w']) { $c['miw'] = $c['w']; }
23613 }
23614 if (!isset($c['colspan'])) {
23615 if ($wc['miw'] < $c['miw']) { $wc['miw'] = $c['miw']; }
23616 if ($wc['maw'] < $c['maw']) { $wc['maw'] = $c['maw']; }
23617
23618 if ($firstpass) {
23619 if (isset($table['l'][$j]) ) {
23620 $table['l'][$j] += $c['miw'] ;
23621 }
23622 else {
23623 $table['l'][$j] = $c['miw'] ;
23624 }
23625 }
23626 }
23627 if ($c['miw'] > $wc['miw']) { $wc['miw'] = $c['miw']; }
23628 if ($wc['miw'] > $wc['maw']) { $wc['maw'] = $wc['miw']; }
23629 continue;
23630 }
23631
23632 if ($firstpass) {
23633 if (isset($c['s'])) { $c['s'] += $extrcw; }
23634 if (isset($c['maxs'])) { $c['maxs'] += $extrcw; }
23635 if (isset($c['nestedmiw'])) { $c['nestedmiw'] += $extrcw; }
23636 if (isset($c['nestedmaw'])) { $c['nestedmaw'] += $extrcw; }
23637 }
23638
23639
23640 // If minimum width has already been set by a nested table or inline object (image/form), use it
23641 if (isset($c['nestedmiw']) && $this->table[1][1]['overflow']!='visible') { $miw = $c['nestedmiw']; }
23642 else { $miw = $mw; }
23643
23644 if (isset($c['maxs']) && $c['maxs'] != '') { $c['s'] = $c['maxs']; }
23645
23646 // If maximum width has already been set by a nested table, use it
23647 if (isset($c['nestedmaw'])) { $c['maw'] = $c['nestedmaw']; }
23648 else $c['maw'] = $c['s'];
23649
23650 if (isset($table['overflow']) && $table['overflow']=='visible' && $table['level']==1) {
23651 if (($c['maw'] + $tblbw) > $this->blk[$this->blklvl]['inner_width']) {
23652 $c['maw'] = $this->blk[$this->blklvl]['inner_width'] - $tblbw;
23653 }
23654 }
23655
23656 if (isset($c['nowrap']) && $c['nowrap']) { $miw = $c['maw']; }
23657
23658 if (isset($c['wpercent']) && $firstpass) {
23659 if (isset($c['colspan'])) { // Not perfect - but % set on colspan is shared equally on cols.
23660 for($k=0;$k<$c['colspan'];$k++) {
23661 $table['wc'][($j+$k)]['wpercent'] = $c['wpercent'] / $c['colspan'];
23662 }
23663 }
23664 else {
23665 if (isset($table['w']) && $table['w']) { $c['w'] = $c['wpercent']/100 * ($table['w'] - $tblbw ); }
23666 $wc['wpercent'] = $c['wpercent'];
23667 }
23668 }
23669
23670 if (isset($table['overflow']) && $table['overflow']=='visible' && $table['level']==1) {
23671 if (($c['w'] + $tblbw) > $this->blk[$this->blklvl]['inner_width']) {
23672 $c['w'] = $this->blk[$this->blklvl]['inner_width'] - $tblbw;
23673 }
23674 }
23675
23676
23677 if (isset($c['w'])) { // If cell width is specified
23678 if ($miw<$c['w']) { $c['miw'] = $c['w']; } // Cell min width = that specified
23679 if ($miw>$c['w']) { $c['miw'] = $c['w'] = $miw; } // If width specified is less than minimum allowed (W) increase it
23680 if (!isset($wc['w'])) { $wc['w'] = 1; } // If the Col width is not specified = set it to 1
23681
23682 }
23683 else { $c['miw'] = $miw; } // If cell width not specified -> set Cell min width it to minimum allowed (W)
23684
23685 if ($c['maw'] < $c['miw']) { $c['maw'] = $c['miw']; } // If Cell max width < Minwidth - increase it to =
23686 if (!isset($c['colspan'])) {
23687 if ($wc['miw'] < $c['miw']) { $wc['miw'] = $c['miw']; } // Update Col Minimum and maximum widths
23688 if ($wc['maw'] < $c['maw']) { $wc['maw'] = $c['maw']; }
23689 if ((isset($wc['absmiw']) && $wc['absmiw'] < $c['absmiw']) || !isset($wc['absmiw'])) { $wc['absmiw'] = $c['absmiw']; } // Update Col Minimum and maximum widths
23690
23691 if (isset($table['l'][$j]) ) {
23692 $table['l'][$j] += $c['s'];
23693 }
23694 else {
23695 $table['l'][$j] = $c['s'];
23696 }
23697
23698 }
23699 else {
23700 $listspan[] = array($i,$j);
23701 }
23702
23703 //Check if minimum width of the whole column is big enough for largest word to fit
23704 if (isset($c['textbuffer']) && (!isset($table['overflow']) || $table['overflow']!='wrap')) { // mPDF 5.5.11
23705 $minwidth = $this->TableCheckMinWidth($wc['miw']- $extrcw ,0,$c['textbuffer']);
23706 }
23707 else { $minwidth = 0; }
23708 if ($minwidth < 0) {
23709 //increase minimum width
23710 if (!isset($c['colspan'])) {
23711 $wc['miw'] = max($wc['miw'],((-$minwidth) + $extrcw) );
23712 }
23713 else {
23714 $c['miw'] = max($c['miw'],((-$minwidth) + $extrcw) );
23715 }
23716 }
23717 if (!isset($c['colspan'])) {
23718 if ($wc['miw'] > $wc['maw']) { $wc['maw'] = $wc['miw']; } //update maximum width, if needed
23719 }
23720 if ($this->cacheTables) {
23721 $this->_cacheCell($c, '', "W", $fh, $table['cells'][$i][$j]);
23722 }
23723 }
23724 unset($c);
23725 }//rows
23726 }//columns
23727
23728
23729 // COLUMN SPANS
23730 $wc = &$table['wc'];
23731 foreach ($listspan as $span) {
23732 list($i,$j) = $span;
23733 if ($this->cacheTables) {
23734 $c = $this->_uncacheCell($cs[$i][$j], '', $fh);
23735 }
23736 else
23737 $c = &$cs[$i][$j];
23738 $lc = $j + $c['colspan'];
23739 if ($lc > $nc) { $lc = $nc; }
23740 $wis = $wisa = 0;
23741 $was = $wasa = 0;
23742 $list = array();
23743 for($k=$j;$k<$lc;$k++) {
23744 if (isset($table['l'][$k]) ) {
23745 if ($c['R']) { $table['l'][$k] += $c['miw']/$c['colspan'] ; }
23746 else { $table['l'][$k] += $c['s']/$c['colspan']; }
23747 }
23748 else {
23749 if ($c['R']) { $table['l'][$k] = $c['miw']/$c['colspan'] ; }
23750 else { $table['l'][$k] = $c['s']/$c['colspan']; }
23751 }
23752 $wis += $wc[$k]['miw'];
23753 $was += $wc[$k]['maw'];
23754 if (!isset($c['w'])) {
23755 $list[] = $k;
23756 $wisa += $wc[$k]['miw'];
23757 $wasa += $wc[$k]['maw'];
23758 }
23759 }
23760 if ($c['miw'] > $wis) {
23761 if (!$wis) {
23762 for($k=$j;$k<$lc;$k++) { $wc[$k]['miw'] = $c['miw']/$c['colspan']; }
23763 }
23764 else if (!count($list)) {
23765 $wi = $c['miw'] - $wis;
23766 for($k=$j;$k<$lc;$k++) { $wc[$k]['miw'] += ($wc[$k]['miw']/$wis)*$wi; }
23767 }
23768 else {
23769 $wi = $c['miw'] - $wis;
23770 foreach ($list as $k) { $wc[$k]['miw'] += ($wc[$k]['miw']/$wisa)*$wi; }
23771 }
23772 }
23773 if ($c['maw'] > $was) {
23774 if (!$wis) {
23775 for($k=$j;$k<$lc;$k++) { $wc[$k]['maw'] = $c['maw']/$c['colspan']; }
23776 }
23777 else if (!count($list)) {
23778 $wi = $c['maw'] - $was;
23779 for($k=$j;$k<$lc;$k++) { $wc[$k]['maw'] += ($wc[$k]['maw']/$was)*$wi; }
23780 }
23781 else {
23782 $wi = $c['maw'] - $was;
23783 foreach ($list as $k) { $wc[$k]['maw'] += ($wc[$k]['maw']/$wasa)*$wi; }
23784 }
23785 }
23786 unset($c);
23787 }
23788
23789 if ($this->cacheTables) { fclose($fh); }
23790
23791 $checkminwidth = 0;
23792 $checkmaxwidth = 0;
23793 $totallength = 0;
23794
23795 for( $i = 0 ; $i < $nc ; $i++ ) {
23796 $checkminwidth += $table['wc'][$i]['miw'];
23797 $checkmaxwidth += $table['wc'][$i]['maw'];
23798 $totallength += $table['l'][$i];
23799 }
23800
23801 if (!isset($table['w']) && $firstpass) {
23802 $sumpc = 0;
23803 $notset = 0;
23804 for( $i = 0 ; $i < $nc ; $i++ ) {
23805 if (isset($table['wc'][$i]['wpercent']) && $table['wc'][$i]['wpercent']) {
23806 $sumpc += $table['wc'][$i]['wpercent'];
23807 }
23808 else { $notset++; }
23809 }
23810
23811 // If sum of widths as % >= 100% and not all columns are set
23812 // Set a nominal width of 1% for unset columns
23813 if ($sumpc >= 100 && $notset) {
23814 for( $i = 0 ; $i < $nc ; $i++ ) {
23815 if ((!isset($table['wc'][$i]['wpercent']) || !$table['wc'][$i]['wpercent']) &&
23816 (!isset($table['wc'][$i]['w']) || !$table['wc'][$i]['w'])) {
23817 $table['wc'][$i]['wpercent'] = 1;
23818 }
23819 }
23820 }
23821
23822
23823 if ($sumpc) { // if any percents are set
23824 $sumnonpc = (100 - $sumpc);
23825 $sumpc = max($sumpc,100);
23826 $miwleft = 0;
23827 $miwleftcount = 0;
23828 $miwsurplusnonpc = 0;
23829 $maxcalcmiw = 0;
23830 $mawleft = 0;
23831 $mawleftcount = 0;
23832 $mawsurplusnonpc = 0;
23833 $maxcalcmaw = 0;
23834 for( $i = 0 ; $i < $nc ; $i++ ) {
23835 if (isset($table['wc'][$i]['wpercent'])) {
23836 $maxcalcmiw = max($maxcalcmiw, ($table['wc'][$i]['miw'] * $sumpc /$table['wc'][$i]['wpercent']) );
23837 $maxcalcmaw = max($maxcalcmaw, ($table['wc'][$i]['maw'] * $sumpc /$table['wc'][$i]['wpercent']) );
23838 }
23839 else {
23840 $miwleft += $table['wc'][$i]['miw'];
23841 $mawleft += $table['wc'][$i]['maw'];
23842 if (!isset($table['wc'][$i]['w'])) { $miwleftcount++; $mawleftcount++; }
23843 }
23844 }
23845 if ($miwleft && $sumnonpc > 0) { $miwnon = $miwleft * 100 / $sumnonpc; }
23846 if ($mawleft && $sumnonpc > 0) { $mawnon = $mawleft * 100 / $sumnonpc; }
23847 if (($miwnon > $checkminwidth || $maxcalcmiw > $checkminwidth) && $this->keep_table_proportions) {
23848 if ($miwnon > $maxcalcmiw) {
23849 $miwsurplusnonpc = round((($miwnon * $sumnonpc / 100) - $miwleft),3);
23850 $checkminwidth = $miwnon;
23851 }
23852 else { $checkminwidth = $maxcalcmiw; }
23853 for( $i = 0 ; $i < $nc ; $i++ ) {
23854 if (isset($table['wc'][$i]['wpercent'])) {
23855 $newmiw = $checkminwidth * $table['wc'][$i]['wpercent']/100;
23856 if ($table['wc'][$i]['miw'] < $newmiw) {
23857 $table['wc'][$i]['miw'] = $newmiw;
23858 }
23859 $table['wc'][$i]['w'] = 1;
23860 }
23861 else if ($miwsurplusnonpc && !$table['wc'][$i]['w']) {
23862 $table['wc'][$i]['miw'] += $miwsurplusnonpc / $miwleftcount;
23863 }
23864 }
23865 }
23866 if (($mawnon > $checkmaxwidth || $maxcalcmaw > $checkmaxwidth )) {
23867 if ($mawnon > $maxcalcmaw) {
23868 $mawsurplusnonpc = round((($mawnon * $sumnonpc / 100) - $mawleft),3);
23869 $checkmaxwidth = $mawnon;
23870 }
23871 else { $checkmaxwidth = $maxcalcmaw; }
23872 for( $i = 0 ; $i < $nc ; $i++ ) {
23873 if (isset($table['wc'][$i]['wpercent'])) {
23874 $newmaw = $checkmaxwidth * $table['wc'][$i]['wpercent']/100;
23875 if ($table['wc'][$i]['maw'] < $newmaw) {
23876 $table['wc'][$i]['maw'] = $newmaw;
23877 }
23878 $table['wc'][$i]['w'] = 1;
23879 }
23880 else if ($mawsurplusnonpc && !$table['wc'][$i]['w']) {
23881 $table['wc'][$i]['maw'] += $mawsurplusnonpc / $mawleftcount;
23882 }
23883 if ($table['wc'][$i]['maw'] < $table['wc'][$i]['miw']) { $table['wc'][$i]['maw'] = $table['wc'][$i]['miw']; }
23884 }
23885 }
23886 if ($checkminwidth > $checkmaxwidth) { $checkmaxwidth = $checkminwidth; }
23887 }
23888 }
23889
23890 if (isset($table['wpercent']) && $table['wpercent']) {
23891 $checkminwidth *= (100 / $table['wpercent']);
23892 $checkmaxwidth *= (100 / $table['wpercent']);
23893 }
23894
23895
23896 $checkminwidth += $tblbw ;
23897 $checkmaxwidth += $tblbw ;
23898
23899 // Table['miw'] set by percent in first pass may be larger than sum of column miw
23900 if ((isset($table['miw']) && $checkminwidth > $table['miw']) || !isset($table['miw'])) { $table['miw'] = $checkminwidth; }
23901 if ((isset($table['maw']) && $checkmaxwidth > $table['maw']) || !isset($table['maw'])) { $table['maw'] = $checkmaxwidth; }
23902 $table['tl'] = $totallength ;
23903
23904
23905 if (!$this->tableCJK) {
23906 if ($this->table_rotate) {
23907 $mxw = $this->tbrot_maxw;
23908 }
23909 else {
23910 $mxw = $this->blk[$this->blklvl]['inner_width'];
23911 }
23912 if(!isset($table['overflow'])) { $table['overflow'] = null; }
23913 if ($table['overflow']=='visible') {
23914 return array(0,0);
23915 }
23916 else if ($table['overflow']=='hidden' && !$this->table_rotate && !$this->ColActive && $checkminwidth > $mxw) {
23917 $table['w'] = $table['miw'];
23918 return array(0,0);
23919 }
23920 else if ($table['overflow']=='wrap') { return array(0,0); }
23921
23922 if (isset($table['w']) && $table['w'] ) {
23923 if ($table['w'] >= $checkminwidth && $table['w'] <= $mxw) { $table['maw'] = $mxw = $table['w']; }
23924 else if ($table['w'] >= $checkminwidth && $table['w'] > $mxw && $this->keep_table_proportions) { $checkminwidth = $table['w']; }
23925 else {
23926 unset($table['w']);
23927 }
23928 }
23929 $ratio = $checkminwidth/$mxw;
23930 if ($checkminwidth > $mxw) { return array(($ratio +0.001),$checkminwidth); } // 0.001 to allow for rounded numbers when resizing
23931 }
23932 unset($cs);
23933 return array(0,0);
23934 }
23935
23936
23937
23938 function _tableWidth(&$table){
23939 $widthcols = &$table['wc'];
23940 $numcols = $table['nc'];
23941 $tablewidth = 0;
23942 if ($table['borders_separate']) {
23943 $tblbw = $table['border_details']['L']['w'] + $table['border_details']['R']['w'] + $table['margin']['L'] + $table['margin']['R'] + $table['padding']['L'] + $table['padding']['R'] + $table['border_spacing_H'];
23944 }
23945 else { $tblbw = $table['max_cell_border_width']['L']/2 + $table['max_cell_border_width']['R']/2 + $table['margin']['L'] + $table['margin']['R']; }
23946
23947 if ($table['level']>1 && isset($table['w'])) {
23948 if (isset($table['wpercent']) && $table['wpercent']) {
23949 $table['w'] = $temppgwidth = (($table['w']-$tblbw) * $table['wpercent'] / 100) + $tblbw ;
23950 }
23951 else {
23952 $temppgwidth = $table['w'] ;
23953 }
23954 }
23955 else if ($this->table_rotate) {
23956 $temppgwidth = $this->tbrot_maxw;
23957 // If it is less than 1/20th of the remaining page height to finish the DIV (i.e. DIV padding + table bottom margin)
23958 // then allow for this
23959 $enddiv = $this->blk[$this->blklvl]['padding_bottom'] + $this->blk[$this->blklvl]['border_bottom']['w'];
23960 if ($enddiv/$temppgwidth <0.05) { $temppgwidth -= $enddiv; }
23961 }
23962 else {
23963 if (isset($table['w']) && $table['w']< $this->blk[$this->blklvl]['inner_width']) {
23964 $notfullwidth = 1;
23965 $temppgwidth = $table['w'] ;
23966 }
23967 else if ($table['overflow']=='visible' && $table['level'] ==1) {
23968 $temppgwidth = null;
23969 }
23970 else if ($table['overflow']=='hidden' && !$this->ColActive && isset($table['w']) && $table['w'] > $this->blk[$this->blklvl]['inner_width'] && $table['w']==$table['miw']) {
23971 //$temppgwidth = $this->blk[$this->blklvl]['inner_width'];
23972 $temppgwidth = $table['w'] ;
23973 }
23974 else { $temppgwidth = $this->blk[$this->blklvl]['inner_width']; }
23975 }
23976
23977
23978 $totaltextlength = 0; // Added - to sum $table['l'][colno]
23979 $totalatextlength = 0; // Added - to sum $table['l'][colno] for those columns where width not set
23980 $percentages_set = 0;
23981 for ( $i = 0 ; $i < $numcols ; $i++ ) {
23982 if (isset($widthcols[$i]['wpercent'])) { $tablewidth += $widthcols[$i]['maw']; $percentages_set = 1; }
23983 else if (isset($widthcols[$i]['w'])) { $tablewidth += $widthcols[$i]['miw']; }
23984 else { $tablewidth += $widthcols[$i]['maw']; }
23985 $totaltextlength += $table['l'][$i];
23986 }
23987 if (!$totaltextlength) { $totaltextlength =1; }
23988 $tablewidth += $tblbw; // Outer half of table borders
23989
23990 if ($tablewidth > $temppgwidth) {
23991 $table['w'] = $temppgwidth;
23992 }
23993 // if any widths set as percentages and max width fits < page width
23994 else if ($tablewidth < $temppgwidth && !isset($table['w']) && $percentages_set) {
23995 $table['w'] = $table['maw'];
23996 }
23997 // if table width is set and is > allowed width
23998 if (isset($table['w']) && $table['w'] > $temppgwidth) { $table['w'] = $temppgwidth; }
23999 // IF the table width is now set - Need to distribute columns widths
24000 if (isset($table['w'])) {
24001 $wis = $wisa = 0;
24002 $list = array();
24003 $notsetlist = array();
24004 for( $i = 0 ; $i < $numcols ; $i++ ) {
24005 $wis += $widthcols[$i]['miw'];
24006 if (!isset($widthcols[$i]['w']) || ($widthcols[$i]['w'] && $table['w'] > $temppgwidth && !$this->keep_table_proportions && !$notfullwidth )){
24007 $list[] = $i;
24008 $wisa += $widthcols[$i]['miw'];
24009 $totalatextlength += $table['l'][$i];
24010 }
24011 }
24012 if (!$totalatextlength) { $totalatextlength =1; }
24013
24014 // Allocate spare (more than col's minimum width) across the cols according to their approx total text length
24015 // Do it by setting minimum width here
24016 if ($table['w'] > $wis + $tblbw) {
24017 // First set any cell widths set as percentages
24018 if ($table['w'] < $temppgwidth || $this->keep_table_proportions) {
24019 for($k=0;$k<$numcols;$k++) {
24020 if (isset($widthcols[$k]['wpercent'])) {
24021 $curr = $widthcols[$k]['miw'];
24022 $widthcols[$k]['miw'] = ($table['w']-$tblbw) * $widthcols[$k]['wpercent']/100;
24023 $wis += $widthcols[$k]['miw'] - $curr;
24024 $wisa += $widthcols[$k]['miw'] - $curr;
24025 }
24026 }
24027 }
24028 // Now allocate surplus up to maximum width of each column
24029 $surplus = 0; $ttl = 0; // number of surplus columns
24030 if (!count($list)) {
24031 $wi = ($table['w']-($wis + $tblbw)); // i.e. extra space to distribute
24032 for($k=0;$k<$numcols;$k++) {
24033 $spareratio = ($table['l'][$k] / $totaltextlength); // gives ratio to divide up free space
24034 // Don't allocate more than Maximum required width - save rest in surplus
24035 if ($widthcols[$k]['miw'] + ($wi * $spareratio) > $widthcols[$k]['maw']) {
24036 $surplus += ($wi * $spareratio) - ($widthcols[$k]['maw']-$widthcols[$k]['miw']);
24037 $widthcols[$k]['miw'] = $widthcols[$k]['maw'];
24038 }
24039 else {
24040 $notsetlist[] = $k;
24041 $ttl += $table['l'][$k];
24042 $widthcols[$k]['miw'] += ($wi * $spareratio);
24043 }
24044
24045 }
24046 }
24047 else {
24048 $wi = ($table['w'] - ($wis + $tblbw)); // i.e. extra space to distribute
24049 foreach ($list as $k) {
24050 $spareratio = ($table['l'][$k] / $totalatextlength); // gives ratio to divide up free space
24051 // Don't allocate more than Maximum required width - save rest in surplus
24052 if ($widthcols[$k]['miw'] + ($wi * $spareratio) > $widthcols[$k]['maw']) {
24053 $surplus += ($wi * $spareratio) - ($widthcols[$k]['maw']-$widthcols[$k]['miw']);
24054 $widthcols[$k]['miw'] = $widthcols[$k]['maw'];
24055 }
24056 else {
24057 $notsetlist[] = $k;
24058 $ttl += $table['l'][$k];
24059 $widthcols[$k]['miw'] += ($wi * $spareratio);
24060 }
24061 }
24062 }
24063 // If surplus still left over apportion it across columns
24064 if ($surplus) {
24065 // if some are set only add to remaining - otherwise add to all of them
24066 if (count($notsetlist) && count($notsetlist) < $numcols) {
24067 foreach ($notsetlist AS $i) {
24068 if ($ttl) $widthcols[$i]['miw'] += $surplus * $table['l'][$i] / $ttl ;
24069 }
24070 }
24071 // If some widths are defined, and others have been added up to their maxmum
24072 else if (count($list) && count($list) < $numcols) {
24073 foreach ($list AS $i) {
24074 $widthcols[$i]['miw'] += $surplus / count($list) ;
24075 }
24076 }
24077 else if ($numcols) { // If all columns
24078 $ttl = array_sum($table['l']);
24079 for ($i=0;$i<$numcols;$i++) {
24080 $widthcols[$i]['miw'] += $surplus * $table['l'][$i] / $ttl;
24081 }
24082 }
24083 }
24084
24085 }
24086
24087 // This sets the columns all to minimum width (which has been increased above if appropriate)
24088 for ($i=0;$i<$numcols;$i++) {
24089 $widthcols[$i] = $widthcols[$i]['miw'];
24090 }
24091
24092 // TABLE NOT WIDE ENOUGH EVEN FOR MINIMUM CONTENT WIDTH
24093 // If sum of column widths set are too wide for table
24094 $checktablewidth = 0;
24095 for ( $i = 0 ; $i < $numcols ; $i++ ) {
24096 $checktablewidth += $widthcols[$i];
24097 }
24098 if ($checktablewidth > ($temppgwidth + 0.001 - $tblbw)) {
24099 $usedup = 0; $numleft = 0;
24100 for ($i=0;$i<$numcols;$i++) {
24101 if ((isset($widthcols[$i]) && $widthcols[$i] > (($temppgwidth - $tblbw) / $numcols)) && (!isset($widthcols[$i]['w']))) {
24102 $numleft++;
24103 unset($widthcols[$i]);
24104 }
24105 else { $usedup += $widthcols[$i]; }
24106 }
24107 for ($i=0;$i<$numcols;$i++) {
24108 if (!isset($widthcols[$i]) || !$widthcols[$i]) {
24109 $widthcols[$i] = ((($temppgwidth - $tblbw) - $usedup)/ ($numleft));
24110 }
24111 }
24112 }
24113
24114 }
24115 else { //table has no width defined
24116 $table['w'] = $tablewidth;
24117 for ( $i = 0 ; $i < $numcols ; $i++) {
24118 if (isset($widthcols[$i]['wpercent']) && $this->keep_table_proportions) { $colwidth = $widthcols[$i]['maw']; }
24119 else if (isset($widthcols[$i]['w'])) { $colwidth = $widthcols[$i]['miw']; }
24120 else { $colwidth = $widthcols[$i]['maw']; }
24121 unset($widthcols[$i]);
24122 $widthcols[$i] = $colwidth;
24123 }
24124 }
24125
24126 if ($table['overflow']=='visible' && $table['level'] ==1) {
24127 if ($tablewidth > $this->blk[$this->blklvl]['inner_width']) {
24128 if ($this->cacheTables) { $fh = fopen($table['cache'], "r+b"); }
24129 else { $fh = null; }
24130 for ($j = 0 ; $j < $numcols; $j++) { //columns
24131 for ($i = 0 ; $i < $table['nr']; $i++) { //rows
24132 if (isset($table['cells'][$i][$j]) && $table['cells'][$i][$j]) {
24133 if ($this->cacheTables) {
24134 $cc = $this->_uncacheCell($table['cells'][$i][$j], '', $fh);
24135 $colspan = $cc['colspan'];
24136 }
24137 else
24138 $colspan = $table['cells'][$i][$j]['colspan'];
24139 if ($colspan > 1) {
24140 $w = 0;
24141 for ($c = $j; $c < ($j + $colspan); $c++) {
24142 $w += $widthcols[$c];
24143 }
24144 if ($w > $this->blk[$this->blklvl]['inner_width']) {
24145 $diff = $w - ($this->blk[$this->blklvl]['inner_width'] - $tblbw);
24146 for ($c = $j; $c < ($j + $colspan); $c++) {
24147 $widthcols[$c] -= $diff * ($widthcols[$c]/$w);
24148 }
24149 $table['w'] -= $diff;
24150 $table['csp'][$j] = $w - $diff;
24151 }
24152 }
24153 }
24154
24155 }
24156 }
24157 if ($this->cacheTables) { fclose($fh); }
24158 }
24159 $pgNo = 0;
24160 $currWc = 0;
24161 for ($i = 0 ; $i < $numcols; $i++) { //columns
24162 if (isset($table['csp'][$i])) {
24163 $w = $table['csp'][$i];
24164 unset($table['csp'][$i]);
24165 }
24166 else { $w = $widthcols[$i]; }
24167 if (($currWc + $w + $tblbw) > $this->blk[$this->blklvl]['inner_width']) {
24168 $pgNo++;
24169 $currWc = $widthcols[$i] ;
24170 }
24171 else { $currWc += $widthcols[$i] ; }
24172 $table['colPg'][$i] = $pgNo;
24173 }
24174 }
24175 }
24176
24177
24178
24179 function _tableHeight(&$table){
24180 $level = $table['level'];
24181 $levelid = $table['levelid'];
24182 $cells = &$table['cells'];
24183 $numcols = $table['nc'];
24184 $numrows = $table['nr'];
24185 $listspan = array();
24186 $checkmaxheight = 0;
24187 $headerrowheight = 0;
24188 $checkmaxheightplus = 0;
24189 $headerrowheightplus = 0;
24190 $firstrowheight = 0;
24191
24192 $footerrowheight = 0;
24193 $footerrowheightplus = 0;
24194 if ($this->table_rotate) {
24195 $temppgheight = $this->tbrot_maxh;
24196 $remainingpage = $this->tbrot_maxh;
24197 }
24198 else {
24199 $temppgheight = ($this->h - $this->bMargin - $this->tMargin) - $this->kwt_height;
24200 $remainingpage = ($this->h - $this->bMargin - $this->y) - $this->kwt_height;
24201
24202 // If it is less than 1/20th of the remaining page height to finish the DIV (i.e. DIV padding + table bottom margin)
24203 // then allow for this
24204 $enddiv = $this->blk[$this->blklvl]['padding_bottom'] + $this->blk[$this->blklvl]['border_bottom']['w'] + $table['margin']['B'];
24205 if ($remainingpage > $enddiv && $enddiv/$remainingpage <0.05) { $remainingpage -= $enddiv; }
24206 else if ($remainingpage == 0) { $remainingpage = 0.001; }
24207 if ($temppgheight > $enddiv && $enddiv/$temppgheight <0.05) { $temppgheight -= $enddiv; }
24208 else if ($temppgheight == 0) { $temppgheight = 0.001; }
24209 }
24210 if ($remainingpage < 0) { $remainingpage = 0.001; } // mPDF 5.6.64
24211 if ($temppgheight < 0) { $temppgheight = 0.001; } // mPDF 5.6.64
24212
24213 if ($this->cacheTables) { $fh = fopen($table['cache'], "r+b"); }
24214 else { $fh = null; }
24215
24216 for( $i = 0 ; $i < $numrows ; $i++ ) { //rows
24217 $heightrow = &$table['hr'][$i];
24218 for( $j = 0 ; $j < $numcols ; $j++ ) { //columns
24219 if (isset($cells[$i][$j]) && $cells[$i][$j]) {
24220 if ($this->cacheTables) {
24221 $c = $this->_uncacheCell($table['cells'][$i][$j], '', $fh);
24222 }
24223 else
24224 $c = &$cells[$i][$j];
24225
24226 if ($this->simpleTables){
24227 if ($table['borders_separate']) { // NB twice border width
24228 $extraWLR = ($table['simple']['border_details']['L']['w']+$table['simple']['border_details']['R']['w']) + ($c['padding']['L']+$c['padding']['R'])+$table['border_spacing_H'];
24229 $extrh = ($table['simple']['border_details']['T']['w']+$table['simple']['border_details']['B']['w']) + ($c['padding']['T']+$c['padding']['B'])+$table['border_spacing_V'];
24230 }
24231 else {
24232 $extraWLR = ($table['simple']['border_details']['L']['w']+$table['simple']['border_details']['R']['w'])/2 + ($c['padding']['L']+$c['padding']['R']);
24233 $extrh = ($table['simple']['border_details']['T']['w']+$table['simple']['border_details']['B']['w'])/2 + ($c['padding']['T']+$c['padding']['B']);
24234 }
24235 }
24236 else {
24237 if ($this->packTableData) {
24238 list($bt,$br,$bb,$bl) = $this->_getBorderWidths($c['borderbin']);
24239 }
24240 else {
24241 $bt = $c['border_details']['T']['w'];
24242 $bb = $c['border_details']['B']['w'];
24243 $br = $c['border_details']['R']['w'];
24244 $bl = $c['border_details']['L']['w'];
24245 }
24246 if ($table['borders_separate']) { // NB twice border width
24247 $extraWLR = $bl + $br + $c['padding']['L'] + $c['padding']['R'] + $table['border_spacing_H'];
24248 $extrh = $bt + $bb + $c['padding']['T'] + $c['padding']['B'] + $table['border_spacing_V'];
24249 }
24250 else {
24251 $extraWLR = $bl/2 + $br/2 + $c['padding']['L'] + $c['padding']['R'];
24252 $extrh = $bt/2 + $bb/2 + $c['padding']['T']+$c['padding']['B'];
24253 }
24254 }
24255
24256 if ($table['overflow']=='visible' && $level==1)
24257 list($x,$cw) = $this->_splitTableGetWidth($table, $i,$j, $fh);
24258 else
24259 list($x,$cw) = $this->_tableGetWidth($table, $i,$j, $fh);
24260
24261 // Get CELL HEIGHT
24262 // ++ extra parameter forces wrap to break word
24263 if ($c['R'] && isset($c['textbuffer'])) { // mPDF 5.4.01
24264 $str = '';
24265 foreach($c['textbuffer'] AS $t) { $str .= $t[0].' '; }
24266 $str = trim($str);
24267 $s_fs = $this->FontSizePt;
24268 $s_f = $this->FontFamily;
24269 $s_st = $this->FontStyle;
24270 $this->SetFont($c['textbuffer'][0][4],$c['textbuffer'][0][2],$c['textbuffer'][0][11] / $this->shrin_k,true,true);
24271 $tempch = $this->GetStringWidth($str);
24272 if ($c['R'] >= 45 && $c['R'] < 90) {
24273 $tempch = ((sin(deg2rad($c['R']))) * $tempch ) + ((sin(deg2rad($c['R']))) * (($c['textbuffer'][0][11]/_MPDFK) / $this->shrin_k));
24274 }
24275 $this->SetFont($s_f,$s_st,$s_fs,true,true);
24276 $ch = ($tempch ) + $extrh ;
24277 }
24278 else {
24279 if (isset($c['textbuffer'])) {
24280 $tempch = $this->TableWordWrap(($cw-$extraWLR),1,$c['textbuffer'], $c['dfs']);
24281 }
24282 else { $tempch = 0; }
24283
24284 // Added cellpadding top and bottom. (Lineheight already adjusted to table_lineheight)
24285 $ch = $tempch + $extrh ;
24286 }
24287 //If height is defined and it is bigger than calculated $ch then update values
24288 if (isset($c['h']) && $c['h'] > $ch) {
24289 $c['mih'] = $ch; //in order to keep valign working
24290 $ch = $c['h'];
24291 }
24292 else $c['mih'] = $ch;
24293 if ($this->cacheTables) {
24294 $this->_cacheUpdateMtx($c, $fh, $table['cells'][$i][$j], 'mih');
24295 }
24296 if (isset($c['rowspan'])) $listspan[] = array($i,$j);
24297 elseif ($heightrow < $ch) $heightrow = $ch;
24298
24299 // this is the extra used in _tableWrite to determine whether to trigger a page change
24300 if ($table['borders_separate']) {
24301 if ($i == ($numrows-1) || (isset($c['rowspan']) && ($i+$c['rowspan']) == ($numrows)) ) {
24302 $extra = $table['margin']['B'] + $table['padding']['B'] + $table['border_details']['B']['w'] + $table['border_spacing_V']/2;
24303 }
24304 else {
24305 $extra = $table['border_spacing_V']/2;
24306 }
24307 }
24308 else {
24309 if (!$this->simpleTables){
24310 $extra = $bb/2;
24311 }
24312 else if ($this->simpleTables){
24313 $extra = $table['simple']['border_details']['B']['w'] /2;
24314 }
24315 }
24316 if (isset($table['is_thead'][$i]) && $table['is_thead'][$i]) {
24317 if ($j==0) {
24318 $headerrowheight += $ch;
24319 $headerrowheightplus += $ch+$extra;
24320 }
24321 }
24322 else if (isset($table['is_tfoot'][$i]) && $table['is_tfoot'][$i]) {
24323 if ($j==0) {
24324 $footerrowheight += $ch;
24325 $footerrowheightplus += $ch+$extra;
24326 }
24327 }
24328 else {
24329 $checkmaxheight = max($checkmaxheight,$ch);
24330 $checkmaxheightplus = max($checkmaxheightplus,$ch+$extra);
24331 }
24332 if ($this->tableLevel==1 && $i == $table['headernrows']) { $firstrowheight = max($ch,$firstrowheight); }
24333 unset($c);
24334 }
24335 }//end of columns
24336 }//end of rows
24337
24338 $heightrow = &$table['hr'];
24339 foreach ($listspan as $span) {
24340 list($i,$j) = $span;
24341 if ($this->cacheTables) {
24342 $c = $this->_uncacheCell($table['cells'][$i][$j], '', $fh);
24343 }
24344 else
24345 $c = &$cells[$i][$j];
24346 $lr = $i + $c['rowspan'];
24347 if ($lr > $numrows) $lr = $numrows;
24348 $hs = $hsa = 0;
24349 $list = array();
24350 for($k=$i;$k<$lr;$k++) {
24351 $hs += $heightrow[$k];
24352 if (!isset($c['h'])) {
24353 $list[] = $k;
24354 $hsa += $heightrow[$k];
24355 }
24356 }
24357
24358 if ($table['borders_separate']) {
24359 if ($i == ($numrows-1) || ($i+$c['rowspan']) == ($numrows) ) {
24360 $extra = $table['margin']['B'] + $table['padding']['B'] + $table['border_details']['B']['w'] + $table['border_spacing_V']/2;
24361 }
24362 else {
24363 $extra = $table['border_spacing_V']/2;
24364 }
24365 }
24366 else {
24367 if (!$this->simpleTables){
24368 if ($this->packTableData) {
24369 list($bt,$br,$bb,$bl) = $this->_getBorderWidths($c['borderbin']);
24370 }
24371 else {
24372 $bb = $c['border_details']['B']['w'];
24373 }
24374 $extra = $bb/2;
24375 }
24376 else if ($this->simpleTables){
24377 $extra = $table['simple']['border_details']['B']['w'] /2;
24378 }
24379 }
24380 if (!empty($table['is_thead'][$i])) {
24381 $headerrowheight = max($headerrowheight,$hs);
24382 $headerrowheightplus = max($headerrowheightplus,$hs+$extra);
24383 }
24384 else if (!empty($table['is_tfoot'][$i])) {
24385 $footerrowheight = max($footerrowheight,$hs);
24386 $footerrowheightplus = max($footerrowheightplus,$hs+$extra);
24387 }
24388 else {
24389 $checkmaxheight = max($checkmaxheight,$hs);
24390 $checkmaxheightplus = max($checkmaxheightplus,$hs+$extra);
24391 }
24392 if ($this->tableLevel==1 && $i == $table['headernrows']) { $firstrowheight = max($hs,$firstrowheight); }
24393
24394 if ($c['mih'] > $hs) {
24395 if (!$hs) {
24396 for($k=$i;$k<$lr;$k++) $heightrow[$k] = $c['mih']/$c['rowspan'];
24397 }
24398 elseif (!count($list)) {
24399 $hi = $c['mih'] - $hs;
24400 for($k=$i;$k<$lr;$k++) $heightrow[$k] += ($heightrow[$k]/$hs)*$hi;
24401 }
24402 else {
24403 $hi = $c['mih'] - $hsa;
24404 foreach ($list as $k) $heightrow[$k] += ($heightrow[$k]/$hsa)*$hi;
24405 }
24406 }
24407 unset($c);
24408
24409 // If rowspans overlap so that one or more rows do not have a height set...
24410 // i.e. for one or more rows, the only cells (explicit) in that row have rowspan>1
24411 // so heightrow is still == 0
24412 if ($heightrow[$i]==0) {
24413 // Get row extent to analyse above and below
24414 $top = $i;
24415 foreach ($listspan as $checkspan) {
24416 list($cki,$ckj) = $checkspan;
24417 if ($this->cacheTables) {
24418 $c = $this->_uncacheCell($table['cells'][$cki][$ckj], '', $fh);
24419 }
24420 else
24421 $c = &$cells[$cki][$ckj];
24422 if (isset($c['rowspan']) && $c['rowspan']>1) {
24423 if (($cki + $c['rowspan']-1) >= $i) { $top = min($top, $cki); }
24424 }
24425 }
24426 $bottom = $i + $c['rowspan']-1;
24427 // Check for overconstrained conditions
24428 for ($k=$top; $k<=$bottom; $k++) {
24429 // if ['hr'] for any of the others is also 0, then abort (too complicated)
24430 if ($k != $i && $heightrow[$k]==0) { break(1); }
24431 // check again that top and bottom are not crossed by rowspans - or abort (too complicated)
24432 if ($k==$top) {
24433 // ???? take account of colspan as well???
24434 for( $m = 0 ; $m < $numcols ; $m++ ) { //columns
24435 if (!isset($cells[$k][$m]) || $cells[$k][$m]==0) {
24436 break(2);
24437 }
24438 }
24439 }
24440 else if ($k==$bottom) {
24441 // ???? take account of colspan as well???
24442 for( $m = 0 ; $m < $numcols ; $m++ ) { //columns
24443 if ($this->cacheTables) {
24444 $c = $this->_uncacheCell($table['cells'][$k][$m], '', $fh);
24445 }
24446 else
24447 $c = &$cells[$k][$m];
24448 if (isset($c['rowspan']) && $c['rowspan']>1) {
24449 break(2);
24450 }
24451 }
24452 }
24453 }
24454 // By columns add up col height using ['h'] if set or ['mih'] if not
24455 // Intentionally do not substract border-spacing
24456 $colH = array();
24457 $extH = 0;
24458 $newhr = array();
24459 for( $m = 0 ; $m < $numcols ; $m++ ) { //columns
24460 for ($k=$top; $k<=$bottom; $k++) {
24461 if (isset($cells[$k][$m]) && $cells[$k][$m]!=0) {
24462 if ($this->cacheTables) {
24463 $c = $this->_uncacheCell($table['cells'][$k][$m], '', $fh);
24464 }
24465 else
24466 $c = &$cells[$k][$m];
24467 if (isset($c['h']) && $c['h']) {
24468 $useh = $c['h'];
24469 }
24470 // ???? take account of colspan as well???
24471 else {
24472 $useh = $c['mih'];
24473 }
24474 $colH[$m] += $useh;
24475 if (!isset($c['rowspan']) || $c['rowspan']<2) { $newhr[$k] = max($newhr[$k], $useh); }
24476 }
24477 }
24478 $extH = max($tabH, $colH[$m]);
24479 }
24480 $newhr[$i] = $extH - array_sum($newhr);
24481 for ($k=$top; $k<=$bottom; $k++) { $heightrow[$k] = $newhr[$k]; }
24482 }
24483
24484
24485 unset($c);
24486 }
24487
24488 $table['h'] = array_sum($heightrow);
24489 unset($heightrow);
24490
24491 if ($this->cacheTables) { fclose($fh); }
24492
24493 if ($table['borders_separate']) {
24494 $table['h'] += $table['margin']['T'] + $table['margin']['B'] + $table['border_details']['T']['w'] + $table['border_details']['B']['w'] + $table['border_spacing_V'] + $table['padding']['T'] + $table['padding']['B'];
24495 }
24496 else {
24497 $table['h'] += $table['margin']['T'] + $table['margin']['B'] + $table['max_cell_border_width']['T']/2 + $table['max_cell_border_width']['B']/2;
24498 }
24499
24500 $maxrowheight = $checkmaxheightplus + $headerrowheightplus + $footerrowheightplus;
24501 $maxfirstrowheight = $firstrowheight + $headerrowheightplus + $footerrowheightplus; // includes thead, 1st row and tfoot
24502 return array($table['h'],$maxrowheight,$temppgheight,$remainingpage,$maxfirstrowheight);
24503 }
24504
24505 function _tableGetWidth(&$table, $i,$j, $fh){
24506 if ($this->cacheTables) {
24507 $cell = $this->_uncacheCell($table['cells'][$i][$j], '', $fh);
24508 }
24509 else
24510 $cell = &$table['cells'][$i][$j];
24511 if ($cell) {
24512 if (isset($cell['x0'])) { return array($cell['x0'], $cell['w0']); }
24513 $x = 0;
24514 $widthcols = &$table['wc'];
24515 for( $k = 0 ; $k < $j ; $k++ ) $x += $widthcols[$k];
24516 $w = $widthcols[$j];
24517 if (isset($cell['colspan'])) {
24518 for ( $k = $j+$cell['colspan']-1 ; $k > $j ; $k-- ) $w += $widthcols[$k];
24519 }
24520 $cell['x0'] = $x;
24521 $cell['w0'] = $w;
24522 if ($this->cacheTables) {
24523 $this->_cacheUpdateMtx($cell, $fh, $table['cells'][$i][$j], 'x0');
24524 }
24525 return array($x, $w);
24526 }
24527 return array(0,0);
24528 }
24529
24530 function _splitTableGetWidth(&$table, $i,$j, $fh){
24531 if ($this->cacheTables) {
24532 $cell = $this->_uncacheCell($table['cells'][$i][$j], '', $fh);
24533 }
24534 else
24535 $cell = &$table['cells'][$i][$j];
24536 if ($cell) {
24537 if (isset($cell['x0'])) return array($cell['x0'], $cell['w0']);
24538 $x = 0;
24539 $widthcols = &$table['wc'];
24540 $pg = $table['colPg'][$j];
24541 for( $k = 0 ; $k < $j ; $k++ ) {
24542 if ($table['colPg'][$k]==$pg) $x += $widthcols[$k];
24543 }
24544 $w = $widthcols[$j];
24545 if (isset($cell['colspan'])) {
24546 for ( $k = $j+$cell['colspan']-1 ; $k > $j ; $k-- ) if ($table['colPg'][$k]==$pg) $w += $widthcols[$k];
24547 }
24548 $cell['x0'] = $x;
24549 $cell['w0'] = $w;
24550 if ($this->cacheTables) {
24551 $this->_cacheUpdateMtx($cell, $fh, $table['cells'][$i][$j], 'x0');
24552 }
24553 return array($x, $w);
24554 }
24555 return array(0,0);
24556 }
24557
24558
24559 function _tableGetHeight(&$table, $i,$j, $fh){
24560 if ($this->cacheTables) {
24561 $cell = $this->_uncacheCell($table['cells'][$i][$j], '', $fh);
24562 }
24563 else
24564 $cell = &$table['cells'][$i][$j];
24565 if ($cell){
24566 if (isset($cell['y0'])) return array($cell['y0'], $cell['h0']);
24567 $y = 0;
24568 $heightrow = &$table['hr'];
24569 for ($k=0;$k<$i;$k++) $y += $heightrow[$k];
24570 $h = $heightrow[$i];
24571 if (isset($cell['rowspan'])){
24572 for ($k=$i+$cell['rowspan']-1;$k>$i;$k--)
24573 $h += $heightrow[$k];
24574 }
24575 $cell['y0'] = $y;
24576 $cell['h0'] = $h;
24577 if ($this->cacheTables) {
24578 $this->_cacheUpdateMtx($cell, $fh, $table['cells'][$i][$j], 'y0');
24579 }
24580 return array($y, $h);
24581 }
24582 return array(0,0);
24583 }
24584
24585 function _tableGetMaxRowHeight($table, $row, $fh) {
24586 if ($row==$table['nc']-1) { return $table['hr'][$row]; }
24587 $maxrowheight = $table['hr'][$row];
24588 for ($i=$row+1;$i<$table['nr'];$i++) {
24589 $cellsset = 0;
24590 for ($j=0;$j<$table['nc'];$j++) {
24591 if ($this->cacheTables) {
24592 $cell = $this->_uncacheCell($table['cells'][$i][$j], '', $fh);
24593 if ($cell) {
24594 if (isset($cell['colspan'])) { $cellsset += $cell['colspan']; }
24595 else $cellsset += 1;
24596 }
24597 }
24598 else {
24599 if ($table['cells'][$i][$j]) {
24600 if (isset($table['cells'][$i][$j]['colspan'])) { $cellsset += $table['cells'][$i][$j]['colspan']; }
24601 else $cellsset += 1;
24602 }
24603 }
24604 }
24605 if ($cellsset == $table['nc']) { return $maxrowheight; }
24606 else { $maxrowheight += $table['hr'][$i]; }
24607 }
24608 return $maxrowheight;
24609 }
24610
24611
24612 // CHANGED TO ALLOW TABLE BORDER TO BE SPECIFIED CORRECTLY - added border_details
24613 function _tableRect($x, $y, $w, $h, $bord=-1, $details=array(), $buffer=false, $bSeparate=false, $cort='cell', $tablecorner='', $bsv=0, $bsh=0) {
24614 $cellBorderOverlay = array();
24615
24616 if ($bord==-1) { $this->Rect($x, $y, $w, $h); }
24617 else if ($this->simpleTables && ($cort=='cell')) {
24618 $this->SetLineWidth($details['L']['w']);
24619 if ($details['L']['c']) {
24620 $this->SetDColor($details['L']['c']);
24621 }
24622 else { $this->SetDColor($this->ConvertColor(0)); }
24623 $this->SetLineJoin(0);
24624 $this->Rect($x, $y, $w, $h);
24625 }
24626 else if ($bord){
24627 if (!$bSeparate && $buffer) {
24628 $priority = 'LRTB';
24629 for($p=0;$p<strlen($priority);$p++) {
24630 $side = $priority[$p];
24631 $details['p'] = $side ;
24632
24633 $dom = 0;
24634 if (isset($details[$side]['w'])) { $dom += ($details[$side]['w'] * 100000); }
24635 if (isset($details[$side]['style'])) { $dom += (array_search($details[$side]['style'],$this->borderstyles)*100) ; }
24636 if (isset($details[$side]['dom'])) { $dom += ($details[$side]['dom']*10); }
24637
24638 // Precedence to darker colours at joins
24639 $coldom = 0;
24640 if (isset($details[$side]['c']) && is_array($details[$side]['c'])) {
24641 if ($details[$side]['c']{0}==3) { // RGB
24642 $coldom = 10-(((ord($details[$side]['c']{1})*1.00)+(ord($details[$side]['c']{2})*1.00)+(ord($details[$side]['c']{3})*1.00))/76.5);
24643 }
24644 } // 10 black - 0 white
24645 if ($coldom) { $dom += $coldom; }
24646 // Lastly precedence to RIGHT and BOTTOM cells at joins
24647 if (isset($details['cellposdom'])) { $dom += $details['cellposdom']; }
24648
24649 $save = false;
24650 if ($side == 'T' && $this->issetBorder($bord, _BORDER_TOP)) { $cbord = _BORDER_TOP; $save = true; }
24651 else if ($side == 'L' && $this->issetBorder($bord, _BORDER_LEFT)) { $cbord = _BORDER_LEFT; $save = true; }
24652 else if ($side == 'R' && $this->issetBorder($bord, _BORDER_RIGHT)) { $cbord = _BORDER_RIGHT; $save = true; }
24653 else if ($side == 'B' && $this->issetBorder($bord, _BORDER_BOTTOM)) { $cbord = _BORDER_BOTTOM; $save = true; }
24654
24655 if ($save) {
24656 $this->cellBorderBuffer[] = pack("A16nCnda6A10d14",
24657 str_pad(sprintf("%08.7f", $dom),16,"0",STR_PAD_LEFT),
24658 $cbord,
24659 ord($side),
24660 $details[$side]['s'],
24661 $details[$side]['w'],
24662 $details[$side]['c'],
24663 $details[$side]['style'],
24664 $x, $y, $w, $h,
24665 $details['mbw']['BL'],
24666 $details['mbw']['BR'],
24667 $details['mbw']['RT'],
24668 $details['mbw']['RB'],
24669 $details['mbw']['TL'],
24670 $details['mbw']['TR'],
24671 $details['mbw']['LT'],
24672 $details['mbw']['LB'],
24673 $details['cellposdom'],
24674 0
24675 );
24676 if ($details[$side]['style'] == 'ridge' || $details[$side]['style'] == 'groove' || $details[$side]['style'] == 'inset' || $details[$side]['style'] == 'outset' || $details[$side]['style'] == 'double' ) {
24677 $details[$side]['overlay'] = true;
24678 $this->cellBorderBuffer[] = pack("A16nCnda6A10d14",
24679 str_pad(sprintf("%08.7f", ($dom+4)),16,"0",STR_PAD_LEFT),
24680 $cbord,
24681 ord($side),
24682 $details[$side]['s'],
24683 $details[$side]['w'],
24684 $details[$side]['c'],
24685 $details[$side]['style'],
24686 $x, $y, $w, $h,
24687 $details['mbw']['BL'],
24688 $details['mbw']['BR'],
24689 $details['mbw']['RT'],
24690 $details['mbw']['RB'],
24691 $details['mbw']['TL'],
24692 $details['mbw']['TR'],
24693 $details['mbw']['LT'],
24694 $details['mbw']['LB'],
24695 $details['cellposdom'],
24696 1
24697 );
24698 }
24699 }
24700 }
24701 return;
24702 }
24703
24704 if (isset($details['p']) && strlen($details['p'])>1) { $priority = $details['p']; }
24705 else { $priority='LTRB'; }
24706 $Tw = 0;
24707 $Rw = 0;
24708 $Bw = 0;
24709 $Lw = 0;
24710 if (isset($details['T']['w'])) { $Tw = $details['T']['w']; }
24711 if (isset($details['R']['w'])) { $Rw = $details['R']['w']; }
24712 if (isset($details['B']['w'])) { $Bw = $details['B']['w']; }
24713 if (isset($details['L']['w'])) { $Lw = $details['L']['w']; }
24714
24715 $x2 = $x + $w; $y2 = $y + $h;
24716 $oldlinewidth = $this->LineWidth;
24717
24718 for($p=0;$p<strlen($priority);$p++) {
24719 $side = $priority[$p];
24720 $xadj = 0;
24721 $xadj2 = 0;
24722 $yadj = 0;
24723 $yadj2 = 0;
24724 $print = false;
24725 if ($Tw && $side=='T' && $this->issetBorder($bord, _BORDER_TOP)) { // TOP
24726 $ly1 = $y;
24727 $ly2 = $y;
24728 $lx1 = $x;
24729 $lx2 = $x2;
24730 $this->SetLineWidth($Tw);
24731 if ($cort == 'cell' || strpos($tablecorner,'L')!==false) {
24732 if ($Tw > $Lw) $xadj = ($Tw - $Lw)/2;
24733 if ($Tw < $Lw) $xadj = ($Tw + $Lw)/2;
24734 }
24735 else { $xadj = $Tw/2 - $bsh/2; }
24736 if ($cort == 'cell' || strpos($tablecorner,'R')!==false) {
24737 if ($Tw > $Rw) $xadj2 = ($Tw - $Rw)/2;
24738 if ($Tw < $Rw) $xadj2 = ($Tw + $Rw)/2;
24739 }
24740 else { $xadj2 = $Tw/2 - $bsh/2; }
24741 if (!$bSeparate && $details['mbw']['TL']) {
24742 $xadj = ($Tw - $details['mbw']['TL'])/2 ;
24743 }
24744 if (!$bSeparate && $details['mbw']['TR']) {
24745 $xadj2 = ($Tw - $details['mbw']['TR'])/2;
24746 }
24747 $print = true;
24748 }
24749 if ($Lw && $side=='L' && $this->issetBorder($bord, _BORDER_LEFT)) { // LEFT
24750 $ly1 = $y;
24751 $ly2 = $y2;
24752 $lx1 = $x;
24753 $lx2 = $x;
24754 $this->SetLineWidth($Lw);
24755 if ($cort == 'cell' || strpos($tablecorner,'T')!==false) {
24756 if ($Lw > $Tw) $yadj = ($Lw - $Tw)/2;
24757 if ($Lw < $Tw) $yadj = ($Lw + $Tw)/2;
24758 }
24759 else { $yadj = $Lw/2 - $bsv/2; }
24760 if ($cort == 'cell' || strpos($tablecorner,'B')!==false) {
24761 if ($Lw > $Bw) $yadj2 = ($Lw - $Bw)/2;
24762 if ($Lw < $Bw) $yadj2 = ($Lw + $Bw)/2;
24763 }
24764 else { $yadj2 = $Lw/2 - $bsv/2; }
24765 if (!$bSeparate && $details['mbw']['LT']) {
24766 $yadj = ($Lw - $details['mbw']['LT'])/2;
24767 }
24768 if (!$bSeparate && $details['mbw']['LB']) {
24769 $yadj2 = ($Lw - $details['mbw']['LB'])/2;
24770 }
24771 $print = true;
24772 }
24773 if ($Rw && $side=='R' && $this->issetBorder($bord, _BORDER_RIGHT)) { // RIGHT
24774 $ly1 = $y;
24775 $ly2 = $y2;
24776 $lx1 = $x2;
24777 $lx2 = $x2;
24778 $this->SetLineWidth($Rw);
24779 if ($cort == 'cell' || strpos($tablecorner,'T')!==false) {
24780 if ($Rw < $Tw) $yadj = ($Rw + $Tw)/2;
24781 if ($Rw > $Tw) $yadj = ($Rw - $Tw)/2;
24782 }
24783 else { $yadj = $Rw/2 - $bsv/2; }
24784
24785 if ($cort == 'cell' || strpos($tablecorner,'B')!==false) {
24786 if ($Rw > $Bw) $yadj2 = ($Rw - $Bw)/2;
24787 if ($Rw < $Bw) $yadj2 = ($Rw + $Bw)/2;
24788 }
24789 else { $yadj2 = $Rw/2 - $bsv/2; }
24790
24791 if (!$bSeparate && $details['mbw']['RT']) {
24792 $yadj = ($Rw - $details['mbw']['RT'])/2;
24793 }
24794 if (!$bSeparate && $details['mbw']['RB']) {
24795 $yadj2 = ($Rw - $details['mbw']['RB'])/2;
24796 }
24797 $print = true;
24798 }
24799 if ($Bw && $side=='B' && $this->issetBorder($bord, _BORDER_BOTTOM)) { // BOTTOM
24800 $ly1 = $y2;
24801 $ly2 = $y2;
24802 $lx1 = $x;
24803 $lx2 = $x2;
24804 $this->SetLineWidth($Bw);
24805 if ($cort == 'cell' || strpos($tablecorner,'L')!==false) {
24806 if ($Bw > $Lw) $xadj = ($Bw - $Lw)/2;
24807 if ($Bw < $Lw) $xadj = ($Bw + $Lw)/2;
24808 }
24809 else { $xadj = $Bw/2 - $bsh/2; }
24810 if ($cort == 'cell' || strpos($tablecorner,'R')!==false) {
24811 if ($Bw > $Rw) $xadj2 = ($Bw - $Rw)/2;
24812 if ($Bw < $Rw) $xadj2 = ($Bw + $Rw)/2;
24813 }
24814 else { $xadj2 = $Bw/2 - $bsh/2; }
24815 if (!$bSeparate && $details['mbw']['BL']) {
24816 $xadj = ($Bw - $details['mbw']['BL'])/2;
24817 }
24818 if (!$bSeparate && $details['mbw']['BR']) {
24819 $xadj2 = ($Bw - $details['mbw']['BR'])/2;
24820 }
24821 $print = true;
24822 }
24823
24824 // Now draw line
24825 if ($print) {
24826 /*-- TABLES-ADVANCED-BORDERS --*/
24827 if ($details[$side]['style'] == 'double') {
24828 if (!isset($details[$side]['overlay']) || !$details[$side]['overlay'] || $bSeparate) {
24829 if ($details[$side]['c']) {
24830 $this->SetDColor($details[$side]['c']);
24831 }
24832 else { $this->SetDColor($this->ConvertColor(0)); }
24833 $this->Line($lx1 + $xadj, $ly1 + $yadj, $lx2 - $xadj2, $ly2 - $yadj2);
24834 }
24835 if ((isset($details[$side]['overlay']) && $details[$side]['overlay']) || $bSeparate) {
24836 if ($bSeparate && $cort=='table') {
24837 if ($side=='T') {
24838 $xadj -= $this->LineWidth/2;
24839 $xadj2 -= $this->LineWidth;
24840 if ($this->issetBorder($bord, _BORDER_LEFT)) {
24841 $xadj += $this->LineWidth/2;
24842 }
24843 if ($this->issetBorder($bord, _BORDER_RIGHT)) {
24844 $xadj2 += $this->LineWidth;
24845 }
24846 }
24847 if ($side=='L') {
24848 $yadj -= $this->LineWidth/2;
24849 $yadj2 -= $this->LineWidth;
24850 if ($this->issetBorder($bord, _BORDER_TOP)) {
24851 $yadj += $this->LineWidth/2;
24852 }
24853 if ($this->issetBorder($bord, _BORDER_BOTTOM)) {
24854 $yadj2 += $this->LineWidth;
24855 }
24856 }
24857 if ($side=='B') {
24858 $xadj -= $this->LineWidth/2;
24859 $xadj2 -= $this->LineWidth;
24860 if ($this->issetBorder($bord, _BORDER_LEFT)) {
24861 $xadj += $this->LineWidth/2;
24862 }
24863 if ($this->issetBorder($bord, _BORDER_RIGHT)) {
24864 $xadj2 += $this->LineWidth;
24865 }
24866 }
24867 if ($side=='R') {
24868 $yadj -= $this->LineWidth/2;
24869 $yadj2 -= $this->LineWidth;
24870 if ($this->issetBorder($bord, _BORDER_TOP)) {
24871 $yadj += $this->LineWidth/2;
24872 }
24873 if ($this->issetBorder($bord, _BORDER_BOTTOM)) {
24874 $yadj2 += $this->LineWidth;
24875 }
24876 }
24877 }
24878
24879 $this->SetLineWidth($this->LineWidth/3);
24880
24881 $tbcol = $this->ConvertColor(255);
24882 for($l=0; $l <= $this->blklvl; $l++) {
24883 if ($this->blk[$l]['bgcolor']) {
24884 $tbcol = ($this->blk[$l]['bgcolorarray']); // mPDF 5.6.53
24885 }
24886 }
24887
24888 if ($bSeparate) {
24889 $cellBorderOverlay[] = array(
24890 'x' => $lx1 + $xadj,
24891 'y' => $ly1 + $yadj,
24892 'x2' => $lx2 - $xadj2,
24893 'y2' => $ly2 - $yadj2,
24894 'col' => $tbcol,
24895 'lw' => $this->LineWidth,
24896 );
24897 }
24898 else {
24899 $this->SetDColor($tbcol);
24900 $this->Line($lx1 + $xadj, $ly1 + $yadj, $lx2 - $xadj2, $ly2 - $yadj2);
24901 }
24902 }
24903 }
24904
24905
24906 else if (isset($details[$side]['style']) && ($details[$side]['style'] == 'ridge' || $details[$side]['style'] == 'groove' || $details[$side]['style'] == 'inset' || $details[$side]['style'] == 'outset')) {
24907 if (!isset($details[$side]['overlay']) || !$details[$side]['overlay'] || $bSeparate) {
24908 if ($details[$side]['c']) {
24909 $this->SetDColor($details[$side]['c']);
24910 }
24911 else { $this->SetDColor($this->ConvertColor(0)); }
24912 if ($details[$side]['style'] == 'outset' || $details[$side]['style'] == 'groove') {
24913 $nc = $this->_darkenColor($details[$side]['c']);
24914 $this->SetDColor($nc);
24915 }
24916 else if ($details[$side]['style'] == 'ridge' || $details[$side]['style'] == 'inset') {
24917 $nc = $this->_lightenColor($details[$side]['c']);
24918 $this->SetDColor($nc);
24919 }
24920 $this->Line($lx1 + $xadj, $ly1 + $yadj, $lx2 - $xadj2, $ly2 - $yadj2);
24921 }
24922 if ((isset($details[$side]['overlay']) && $details[$side]['overlay']) || $bSeparate) {
24923 if ($details[$side]['c']) {
24924 $this->SetDColor($details[$side]['c']);
24925 }
24926 else { $this->SetDColor($this->ConvertColor(0)); }
24927 $doubleadj = ($this->LineWidth)/3;
24928 $this->SetLineWidth($this->LineWidth/2);
24929 $xadj3 = $yadj3 = $wadj3 = $hadj3 = 0;
24930
24931 if ($details[$side]['style'] == 'ridge' || $details[$side]['style'] == 'inset') {
24932 $nc = $this->_darkenColor($details[$side]['c']);
24933
24934 if ($bSeparate && $cort=='table') {
24935 if ($side=='T') {
24936 $yadj3 = $this->LineWidth/2;
24937 $xadj3 = -$this->LineWidth/2;
24938 $wadj3 = $this->LineWidth;
24939 if ($this->issetBorder($bord, _BORDER_LEFT)) {
24940 $xadj3 += $this->LineWidth; $wadj3 -= $this->LineWidth;
24941 }
24942 if ($this->issetBorder($bord, _BORDER_RIGHT)) {
24943 $wadj3 -= $this->LineWidth*2;
24944 }
24945 }
24946 if ($side=='L') {
24947 $xadj3 = $this->LineWidth/2;
24948 $yadj3 = -$this->LineWidth/2;
24949 $hadj3 = $this->LineWidth;
24950 if ($this->issetBorder($bord, _BORDER_TOP)) {
24951 $yadj3 += $this->LineWidth; $hadj3 -= $this->LineWidth;
24952 }
24953 if ($this->issetBorder($bord, _BORDER_BOTTOM)) {
24954 $hadj3 -= $this->LineWidth*2;
24955 }
24956 }
24957 if ($side=='B') {
24958 $yadj3 = $this->LineWidth/2;
24959 $xadj3 = -$this->LineWidth/2;
24960 $wadj3 = $this->LineWidth;
24961 }
24962 if ($side=='R') {
24963 $xadj3 = $this->LineWidth/2;
24964 $yadj3 = -$this->LineWidth/2;
24965 $hadj3 = $this->LineWidth;
24966 }
24967 }
24968
24969 else if ($side=='T') { $yadj3 = $this->LineWidth/2; $xadj3 = $this->LineWidth/2; $wadj3 = -$this->LineWidth*2; }
24970 else if ($side=='L') { $xadj3 = $this->LineWidth/2; $yadj3 = $this->LineWidth/2; $hadj3 = -$this->LineWidth*2; }
24971
24972 else if ($side=='B' && $bSeparate) { $yadj3 = $this->LineWidth/2; $wadj3 = $this->LineWidth/2; }
24973 else if ($side=='R' && $bSeparate) { $xadj3 = $this->LineWidth/2; $hadj3 = $this->LineWidth/2; }
24974
24975 else if ($side=='B') { $yadj3 = $this->LineWidth/2; $xadj3 = $this->LineWidth/2; }
24976 else if ($side=='R') { $xadj3 = $this->LineWidth/2; $yadj3 = $this->LineWidth/2; }
24977 }
24978 else {
24979 $nc = $this->_lightenColor($details[$side]['c']);
24980
24981 if ($bSeparate && $cort=='table') {
24982 if ($side=='T') {
24983 $yadj3 = $this->LineWidth/2;
24984 $xadj3 = -$this->LineWidth/2;
24985 $wadj3 = $this->LineWidth;
24986 if ($this->issetBorder($bord, _BORDER_LEFT)) {
24987 $xadj3 += $this->LineWidth; $wadj3 -= $this->LineWidth;
24988 }
24989 }
24990 if ($side=='L') {
24991 $xadj3 = $this->LineWidth/2;
24992 $yadj3 = -$this->LineWidth/2;
24993 $hadj3 = $this->LineWidth;
24994 if ($this->issetBorder($bord, _BORDER_TOP)) {
24995 $yadj3 += $this->LineWidth; $hadj3 -= $this->LineWidth;
24996 }
24997 }
24998 if ($side=='B') {
24999 $yadj3 = $this->LineWidth/2;
25000 $xadj3 = -$this->LineWidth/2;
25001 $wadj3 = $this->LineWidth;
25002 if ($this->issetBorder($bord, _BORDER_LEFT)) {
25003 $xadj3 += $this->LineWidth; $wadj3 -= $this->LineWidth;
25004 }
25005 }
25006 if ($side=='R') {
25007 $xadj3 = $this->LineWidth/2;
25008 $yadj3 = -$this->LineWidth/2;
25009 $hadj3 = $this->LineWidth;
25010 if ($this->issetBorder($bord, _BORDER_TOP)) {
25011 $yadj3 += $this->LineWidth; $hadj3 -= $this->LineWidth;
25012 }
25013 }
25014 }
25015
25016 else if ($side=='T') { $yadj3 = $this->LineWidth/2; $xadj3 = $this->LineWidth/2; }
25017 else if ($side=='L') { $xadj3 = $this->LineWidth/2; $yadj3 = $this->LineWidth/2; }
25018
25019 else if ($side=='B' && $bSeparate) { $yadj3 = $this->LineWidth/2; $xadj3 = $this->LineWidth/2; }
25020 else if ($side=='R' && $bSeparate) { $xadj3 = $this->LineWidth/2; $yadj3 = $this->LineWidth/2; }
25021
25022 else if ($side=='B') { $yadj3 = $this->LineWidth/2; $xadj3 = -$this->LineWidth/2; $wadj3 = $this->LineWidth; }
25023 else if ($side=='R') { $xadj3 = $this->LineWidth/2; $yadj3 = -$this->LineWidth/2; $hadj3 = $this->LineWidth; }
25024
25025 }
25026
25027 if ($bSeparate) {
25028 $cellBorderOverlay[] = array(
25029 'x' => $lx1 + $xadj + $xadj3,
25030 'y' => $ly1 + $yadj + $yadj3,
25031 'x2' => $lx2 - $xadj2 + $xadj3 + $wadj3,
25032 'y2' => $ly2 - $yadj2 + $yadj3 + $hadj3,
25033 'col' => $nc,
25034 'lw' => $this->LineWidth,
25035 );
25036 }
25037 else {
25038 $this->SetDColor($nc);
25039 $this->Line($lx1 + $xadj + $xadj3, $ly1 + $yadj + $yadj3, $lx2 - $xadj2 + $xadj3 + $wadj3, $ly2 - $yadj2 + $yadj3 + $hadj3);
25040 }
25041 }
25042 }
25043
25044
25045 else {
25046 /*-- END TABLES-ADVANCED-BORDERS --*/
25047 if ($details[$side]['style'] == 'dashed') {
25048 $dashsize = 2; // final dash will be this + 1*linewidth
25049 $dashsizek = 1.5; // ratio of Dash/Blank
25050 $this->SetDash($dashsize,($dashsize/$dashsizek)+($this->LineWidth*2));
25051 }
25052 else if ($details[$side]['style'] == 'dotted') {
25053 $this->SetLineJoin(1);
25054 $this->SetLineCap(1);
25055 $this->SetDash(0.001,($this->LineWidth*2));
25056 }
25057 if ($details[$side]['c']) {
25058 $this->SetDColor($details[$side]['c']);
25059 }
25060 else { $this->SetDColor($this->ConvertColor(0)); }
25061 $this->Line($lx1 + $xadj, $ly1 + $yadj, $lx2 - $xadj2, $ly2 - $yadj2);
25062 /*-- TABLES-ADVANCED-BORDERS --*/
25063 }
25064 /*-- END TABLES-ADVANCED-BORDERS --*/
25065
25066 // Reset Corners
25067 $this->SetDash();
25068 //BUTT style line cap
25069 $this->SetLineCap(2);
25070 }
25071 }
25072
25073 if ($bSeparate && count($cellBorderOverlay)) {
25074 foreach($cellBorderOverlay AS $cbo) {
25075 $this->SetLineWidth($cbo['lw']);
25076 $this->SetDColor($cbo['col']);
25077 $this->Line($cbo['x'], $cbo['y'], $cbo['x2'], $cbo['y2']);
25078 }
25079 }
25080
25081 // $this->SetLineWidth($oldlinewidth);
25082 // $this->SetDColor($this->ConvertColor(0));
25083 }
25084 }
25085
25086
25087 /*-- TABLES --*/
25088 /*-- TABLES-ADVANCED-BORDERS --*/
25089 function _lightenColor($c) {
25090 if (is_array($c)) { die('Color error in _lightencolor'); }
25091 if ($c{0}==3 || $c{0}==5) { // RGB
25092 list($h,$s,$l) = $this->rgb2hsl(ord($c{1})/255,ord($c{2})/255,ord($c{3})/255);
25093 $l += ((1 - $l)*0.8);
25094 list($r,$g,$b) = $this->hsl2rgb($h,$s,$l);
25095 $ret = array(3,$r,$g,$b);
25096 }
25097 else if ($c{0}==4 || $c{0}==6) { // CMYK
25098 $ret = array(4, max(0,(ord($c{1})-20)), max(0,(ord($c{2})-20)), max(0,(ord($c{3})-20)), max(0,(ord($c{4})-20)) );
25099 }
25100 else if ($c{0}==1) { // Grayscale
25101 $ret = array(1,min(255,(ord($c{1})+32)));
25102 }
25103 $c = array_pad($ret, 6, 0);
25104 $cstr = pack("a1ccccc", $c[0], ($c[1] & 0xFF), ($c[2] & 0xFF), ($c[3] & 0xFF), ($c[4] & 0xFF), ($c[5] & 0xFF) );
25105 return $cstr;
25106 }
25107
25108
25109 function _darkenColor($c) {
25110 if (is_array($c)) { die('Color error in _darkenColor'); }
25111 if ($c{0}==3 || $c{0}==5) { // RGB
25112 list($h,$s,$l) = $this->rgb2hsl(ord($c{1})/255,ord($c{2})/255,ord($c{3})/255);
25113 $s *= 0.25;
25114 $l *= 0.75;
25115 list($r,$g,$b) = $this->hsl2rgb($h,$s,$l);
25116 $ret = array(3,$r,$g,$b);
25117 }
25118 else if ($c{0}==4 || $c{0}==6) { // CMYK
25119 $ret = array(4, min(100,(ord($c{1})+20)), min(100,(ord($c{2})+20)), min(100,(ord($c{3})+20)), min(100,(ord($c{4})+20)) );
25120 }
25121 else if ($c{0}==1) { // Grayscale
25122 $ret = array(1,max(0,(ord($c{1})-32)));
25123 }
25124 $c = array_pad($ret, 6, 0);
25125 $cstr = pack("a1ccccc", $c[0], ($c[1] & 0xFF), ($c[2] & 0xFF), ($c[3] & 0xFF), ($c[4] & 0xFF), ($c[5] & 0xFF) );
25126 return $cstr;
25127 }
25128
25129 /*-- END TABLES-ADVANCED-BORDERS --*/
25130
25131
25132
25133 function setBorder(&$var, $flag, $set = true) {
25134 $flag = intval($flag);
25135 if ($set) { $set = true; }
25136 $var = intval($var);
25137 $var = $set ? ($var | $flag) : ($var & ~$flag);
25138 }
25139 function issetBorder($var, $flag) {
25140 $flag = intval($flag);
25141 $var = intval($var);
25142 return (($var & $flag) == $flag);
25143 }
25144
25145
25146 function _table2cellBorder(&$tableb, &$cbdb, &$cellb, $bval) {
25147 if ($tableb && $tableb['w'] > $cbdb['w']) {
25148 $cbdb = $tableb;
25149 $this->setBorder($cellb, $bval);
25150 }
25151 else if ($tableb && $tableb['w'] == $cbdb['w']
25152 && array_search($tableb['style'],$this->borderstyles) > array_search($cbdb['style'],$this->borderstyles)) {
25153 $cbdb = $tableb;
25154 $this->setBorder($cellb, $bval);
25155 }
25156 }
25157
25158 // FIX BORDERS ********************************************
25159 function _fixTableBorders(&$table){
25160 if ($this->cacheTables) { $fh = fopen($table['cache'], "r+b"); }
25161 else { $fh = null; }
25162
25163 if (!$table['borders_separate'] && $table['border_details']['L']['w']) {
25164 $table['max_cell_border_width']['L'] = $table['border_details']['L']['w'];
25165 }
25166 if (!$table['borders_separate'] && $table['border_details']['R']['w']) {
25167 $table['max_cell_border_width']['R'] = $table['border_details']['R']['w'];
25168 }
25169 if (!$table['borders_separate'] && $table['border_details']['T']['w']) {
25170 $table['max_cell_border_width']['T'] = $table['border_details']['T']['w'];
25171 }
25172 if (!$table['borders_separate'] && $table['border_details']['B']['w']) {
25173 $table['max_cell_border_width']['B'] = $table['border_details']['B']['w'];
25174 }
25175 if ($this->simpleTables) { return; }
25176 $cells = &$table['cells'];
25177 $numcols = $table['nc'];
25178 $numrows = $table['nr'];
25179 /*-- TABLES-ADVANCED-BORDERS --*/
25180 if (isset($table['topntail']) && $table['topntail']) { $tntborddet = $this->border_details($table['topntail']); }
25181 if (isset($table['thead-underline']) && $table['thead-underline']) { $thuborddet = $this->border_details($table['thead-underline']); }
25182 /*-- END TABLES-ADVANCED-BORDERS --*/
25183
25184 for( $i = 0 ; $i < $numrows ; $i++ ) { //Rows
25185 for( $j = 0 ; $j < $numcols ; $j++ ) { //Columns
25186 if (isset($cells[$i][$j]) && $cells[$i][$j]) {
25187 if ($this->cacheTables) {
25188 $cell = $this->_uncacheCell($table['cells'][$i][$j], '', $fh);
25189 }
25190 else
25191 $cell = &$cells[$i][$j];
25192 if ($this->packTableData) { // includes $this->cacheTables
25193 $cbord = $this->_unpackCellBorder($cell['borderbin']);
25194 }
25195 else {
25196 $cbord = &$cells[$i][$j];
25197 }
25198
25199 if (!$cbord['border'] && isset($table['border']) && $table['border'] && $this->table_border_attr_set) {
25200 $cbord['border'] = $table['border'];
25201 $cbord['border_details'] = $table['border_details'];
25202 }
25203
25204 if (isset($cell['colspan']) && $cell['colspan']>1) { $ccolsp = $cell['colspan']; }
25205 else { $ccolsp = 1; }
25206 if (isset($cell['rowspan']) && $cell['rowspan']>1) { $crowsp = $cell['rowspan']; }
25207 else { $crowsp = 1; }
25208
25209 $cbord['border_details']['cellposdom'] = ((($i+1)/$numrows) / 10000 ) + ((($j+1)/$numcols) / 10 );
25210 // Inherit Cell border from Table border
25211 if ($this->table_border_css_set && !$table['borders_separate']) {
25212 if ($i == 0) {
25213 $this->_table2cellBorder($table['border_details']['T'], $cbord['border_details']['T'], $cbord['border'], _BORDER_TOP);
25214 }
25215 if ($i == ($numrows-1) || ($i+$crowsp) == ($numrows) ) {
25216 $this->_table2cellBorder($table['border_details']['B'], $cbord['border_details']['B'], $cbord['border'], _BORDER_BOTTOM);
25217 }
25218 if ($j == 0) {
25219 $this->_table2cellBorder($table['border_details']['L'], $cbord['border_details']['L'], $cbord['border'], _BORDER_LEFT);
25220 }
25221 if ($j == ($numcols-1) || ($j+$ccolsp) == ($numcols) ) {
25222 $this->_table2cellBorder($table['border_details']['R'], $cbord['border_details']['R'], $cbord['border'], _BORDER_RIGHT);
25223 }
25224 }
25225
25226 /*-- TABLES-ADVANCED-BORDERS --*/
25227 $fixbottom = true;
25228 if (isset($table['topntail']) && $table['topntail']) {
25229 if ($i == 0) {
25230 $cbord['border_details']['T'] = $tntborddet;
25231 $this->setBorder($cbord['border'], _BORDER_TOP);
25232 }
25233 if ($this->tableLevel==1 && $table['headernrows']>0 && $i == $table['headernrows']-1) {
25234 $cbord['border_details']['B'] = $tntborddet;
25235 $this->setBorder($cbord['border'], _BORDER_BOTTOM);
25236 $fixbottom = false;
25237 }
25238 else if ($this->tableLevel==1 && $table['headernrows']>0 && $i == $table['headernrows']) {
25239 if (!$table['borders_separate']) {
25240 $cbord['border_details']['T'] = $tntborddet;
25241 $this->setBorder($cbord['border'], _BORDER_TOP);
25242 }
25243 }
25244 if ($this->tableLevel==1 && $table['footernrows']>0 && $i == ($numrows-$table['footernrows']-1)) {
25245 if (!$table['borders_separate']) {
25246 $cbord['border_details']['B'] = $tntborddet;
25247 $this->setBorder($cbord['border'], _BORDER_BOTTOM);
25248 $fixbottom = false;
25249 }
25250 }
25251 else if ($this->tableLevel==1 && $table['footernrows']>0 && $i == ($numrows-$table['footernrows'])) {
25252 $cbord['border_details']['T'] = $tntborddet;
25253 $this->setBorder($cbord['border'], _BORDER_TOP);
25254 }
25255 if ($this->tabletheadjustfinished) { // $this->tabletheadjustfinished called from tableheader
25256 if (!$table['borders_separate']) {
25257 $cbord['border_details']['T'] = $tntborddet;
25258 $this->setBorder($cbord['border'], _BORDER_TOP);
25259 }
25260 }
25261 if ($i == ($numrows-1) || ($i+$crowsp) == ($numrows) ) {
25262 $cbord['border_details']['B'] = $tntborddet;
25263 $this->setBorder($cbord['border'], _BORDER_BOTTOM);
25264 }
25265 }
25266 if (isset($table['thead-underline']) && $table['thead-underline']) {
25267 if ($table['borders_separate']) {
25268 if ($i == 0) {
25269 $cbord['border_details']['B'] = $thuborddet;
25270 $this->setBorder($cbord['border'], _BORDER_BOTTOM);
25271 $fixbottom = false;
25272 }
25273 }
25274 else {
25275 if ($this->tableLevel==1 && $table['headernrows']>0 && $i == $table['headernrows']-1) {
25276 $cbord['border_details']['T'] = $thuborddet;
25277 $this->setBorder($cbord['border'], _BORDER_TOP);
25278 }
25279 else if ($this->tabletheadjustfinished) { // $this->tabletheadjustfinished called from tableheader
25280 $cbord['border_details']['T'] = $thuborddet;
25281 $this->setBorder($cbord['border'], _BORDER_TOP);
25282 }
25283 }
25284 }
25285
25286 // Collapse Border - Algorithm for conflicting borders
25287 // Hidden >> Width >> double>solid>dashed>dotted... >> style set on cell>table >> top/left>bottom/right
25288 // Do not turn off border which is overridden
25289 // Needed for page break for TOP/BOTTOM both to be defined in Collapsed borders
25290 // Means it is painted twice. (Left/Right can still disable overridden border)
25291 if (!$table['borders_separate']) {
25292 if (($i < ($numrows-1) || ($i+$crowsp) < $numrows ) && $fixbottom ) { // Bottom
25293 for ($cspi = 0; $cspi<$ccolsp; $cspi++) {
25294 // already defined Top for adjacent cell below
25295 if (isset($cells[($i+$crowsp)][$j+$cspi])) {
25296 if ($this->packTableData) {
25297 if ($this->cacheTables) {
25298 $adjc = $this->_uncacheCell($table['cells'][$i+$crowsp][$j+$cspi], '', $fh);
25299 }
25300 else { $adjc = $cells[($i+$crowsp)][$j+$cspi]; }
25301 $celladj = $this->_unpackCellBorder($adjc['borderbin']);
25302 }
25303 else { $celladj =& $cells[($i+$crowsp)][$j+$cspi]; }
25304 }
25305 else { $celladj = false; }
25306 if ($celladj && $celladj['border_details']['T']['s'] == 1) {
25307 $csadj = $celladj['border_details']['T']['w'];
25308 $csthis = $cbord['border_details']['B']['w'];
25309 // Hidden
25310 if ($cbord['border_details']['B']['style']=='hidden') {
25311 $celladj['border_details']['T'] = $cbord['border_details']['B'];
25312 $this->setBorder($celladj['border'] , _BORDER_TOP, false);
25313 $this->setBorder($cbord['border'] , _BORDER_BOTTOM , false);
25314 }
25315 else if ($celladj['border_details']['T']['style']=='hidden') {
25316 $cbord['border_details']['B'] = $celladj['border_details']['T'];
25317 $this->setBorder($cbord['border'] , _BORDER_BOTTOM , false);
25318 $this->setBorder($celladj['border'] , _BORDER_TOP, false);
25319 }
25320 // Width
25321 else if ($csthis > $csadj) {
25322 if (!isset($cells[($i+$crowsp)][$j+$cspi]['colspan']) || (isset($cells[($i+$crowsp)][$j+$cspi]['colspan']) && $cells[($i+$crowsp)][$j+$cspi]['colspan']<2)) { // don't overwrite bordering cells that span
25323 $celladj['border_details']['T'] = $cbord['border_details']['B'];
25324 $this->setBorder($cbord['border'] , _BORDER_BOTTOM);
25325 }
25326 }
25327 else if ($csadj > $csthis) {
25328 if ($ccolsp < 2) { // don't overwrite this cell if it spans
25329 $cbord['border_details']['B'] = $celladj['border_details']['T'];
25330 $this->setBorder($celladj['border'] , _BORDER_TOP);
25331 }
25332 }
25333
25334 // double>solid>dashed>dotted...
25335 else if (array_search($cbord['border_details']['B']['style'],$this->borderstyles) > array_search($celladj['border_details']['T']['style'],$this->borderstyles)) {
25336 if (!isset($cells[($i+$crowsp)][$j+$cspi]['colspan']) || (isset($cells[($i+$crowsp)][$j+$cspi]['colspan']) && $cells[($i+$crowsp)][$j+$cspi]['colspan']<2)) { // don't overwrite bordering cells that span
25337 $celladj['border_details']['T'] = $cbord['border_details']['B'];
25338 $this->setBorder($cbord['border'] , _BORDER_BOTTOM );
25339 }
25340 }
25341 else if (array_search($celladj['border_details']['T']['style'],$this->borderstyles) > array_search($cbord['border_details']['B']['style'],$this->borderstyles)) {
25342 if ($ccolsp < 2) { // don't overwrite this cell if it spans
25343 $cbord['border_details']['B'] = $celladj['border_details']['T'];
25344 $this->setBorder($celladj['border'] , _BORDER_TOP);
25345 }
25346 }
25347
25348
25349
25350 // Style set on cell vs. table
25351 else if ($celladj['border_details']['T']['dom'] > $cbord['border_details']['B']['dom']) {
25352 if ($ccolsp < 2) { // don't overwrite this cell if it spans
25353 $cbord['border_details']['B'] = $celladj['border_details']['T'];
25354 $this->setBorder($celladj['border'] , _BORDER_TOP);
25355 }
25356 }
25357 // Style set on cell vs. table - OR - LEFT/TOP (cell) in preference to BOTTOM/RIGHT
25358 else {
25359 if (!isset($cells[($i+$crowsp)][$j+$cspi]['colspan']) || (isset($cells[($i+$crowsp)][$j+$cspi]['colspan']) && $cells[($i+$crowsp)][$j+$cspi]['colspan']<2)) { // don't overwrite bordering cells that span
25360 $celladj['border_details']['T'] = $cbord['border_details']['B'];
25361 $this->setBorder($cbord['border'] , _BORDER_BOTTOM );
25362 }
25363 }
25364 }
25365 else if ($celladj) {
25366 if (!isset($cells[($i+$crowsp)][$j+$cspi]['colspan']) || (isset($cells[($i+$crowsp)][$j+$cspi]['colspan']) && $cells[($i+$crowsp)][$j+$cspi]['colspan']<2)) { // don't overwrite bordering cells that span
25367 $celladj['border_details']['T'] = $cbord['border_details']['B'];
25368 }
25369 }
25370 if ($celladj && $this->packTableData) {
25371 $celladj['borderbin'] = $this->_packCellBorder($celladj);
25372 unset($celladj['border']);
25373 unset($celladj['border_details']);
25374 }
25375 if ($this->cacheTables) {
25376 $this->_cacheUpdateBorder($celladj, $fh, $table['cells'][$i+$crowsp][$j+$cspi]);
25377 }
25378 unset($celladj);
25379 }
25380 }
25381
25382 if ($j < ($numcols-1) || ($j+$ccolsp) < $numcols ) { // Right-Left
25383 for ($cspi = 0; $cspi<$crowsp; $cspi++) {
25384 // already defined Left for adjacent cell to R
25385 if (isset($cells[($i+$cspi)][$j+$ccolsp])) {
25386 if ($this->packTableData) {
25387 if ($this->cacheTables) {
25388 $adjc = $this->_uncacheCell($table['cells'][$i+$cspi][$j+$ccolsp], '', $fh);
25389 }
25390 else { $adjc = $cells[($i+$cspi)][$j+$ccolsp]; }
25391 $celladj = $this->_unpackCellBorder($adjc['borderbin']);
25392 }
25393 else { $celladj =& $cells[$i+$cspi][$j+$ccolsp]; }
25394 }
25395 else { $celladj = false; }
25396 if ($celladj && $celladj['border_details']['L']['s'] == 1) {
25397 $csadj = $celladj['border_details']['L']['w'];
25398 $csthis = $cbord['border_details']['R']['w'];
25399 // Hidden
25400 if ($cbord['border_details']['R']['style']=='hidden') {
25401 $celladj['border_details']['L'] = $cbord['border_details']['R'];
25402 $this->setBorder($celladj['border'] , _BORDER_LEFT, false);
25403 $this->setBorder($cbord['border'] , _BORDER_RIGHT , false);
25404 }
25405 else if ($celladj['border_details']['L']['style']=='hidden') {
25406 $cbord['border_details']['R'] = $celladj['border_details']['L'];
25407 $this->setBorder($cbord['border'] , _BORDER_RIGHT , false);
25408 $this->setBorder($celladj['border'] , _BORDER_LEFT, false);
25409 }
25410 // Width
25411 else if ($csthis > $csadj) {
25412 if (!isset($cells[($i+$cspi)][$j+$ccolsp]['rowspan']) || (isset($cells[($i+$cspi)][$j+$ccolsp]['rowspan']) && $cells[($i+$cspi)][$j+$ccolsp]['rowspan']<2)) { // don't overwrite bordering cells that span
25413 $celladj['border_details']['L'] = $cbord['border_details']['R'];
25414 $this->setBorder($cbord['border'] , _BORDER_RIGHT);
25415 $this->setBorder($celladj['border'] , _BORDER_LEFT, false);
25416 }
25417 }
25418 else if ($csadj > $csthis) {
25419 if ($crowsp < 2) { // don't overwrite this cell if it spans
25420 $cbord['border_details']['R'] = $celladj['border_details']['L'];
25421 $this->setBorder($cbord['border'] , _BORDER_RIGHT, false);
25422 $this->setBorder($celladj['border'] , _BORDER_LEFT);
25423 }
25424 }
25425
25426 // double>solid>dashed>dotted...
25427 else if (array_search($cbord['border_details']['R']['style'],$this->borderstyles) > array_search($celladj['border_details']['L']['style'],$this->borderstyles)) {
25428 if (!isset($cells[($i+$cspi)][$j+$ccolsp]['rowspan']) || (isset($cells[($i+$cspi)][$j+$ccolsp]['rowspan']) && $cells[($i+$cspi)][$j+$ccolsp]['rowspan']<2)) { // don't overwrite bordering cells that span
25429 $celladj['border_details']['L'] = $cbord['border_details']['R'];
25430 $this->setBorder($celladj['border'] , _BORDER_LEFT, false);
25431 $this->setBorder($cbord['border'] , _BORDER_RIGHT);
25432 }
25433 }
25434 else if (array_search($celladj['border_details']['L']['style'],$this->borderstyles) > array_search($cbord['border_details']['R']['style'],$this->borderstyles)) {
25435 if ($crowsp < 2) { // don't overwrite this cell if it spans
25436 $cbord['border_details']['R'] = $celladj['border_details']['L'];
25437 $this->setBorder($cbord['border'] , _BORDER_RIGHT , false);
25438 $this->setBorder($celladj['border'] , _BORDER_LEFT);
25439 }
25440 }
25441
25442
25443 // Style set on cell vs. table
25444 else if ($celladj['border_details']['L']['dom'] > $cbord['border_details']['R']['dom']) {
25445 if ($crowsp < 2) { // don't overwrite this cell if it spans
25446 $cbord['border_details']['R'] = $celladj['border_details']['L'];
25447 $this->setBorder($celladj['border'] , _BORDER_LEFT);
25448 }
25449 }
25450 // Style set on cell vs. table - OR - LEFT/TOP (cell) in preference to BOTTOM/RIGHT
25451 else {
25452 if (!isset($cells[($i+$cspi)][$j+$ccolsp]['rowspan']) || (isset($cells[($i+$cspi)][$j+$ccolsp]['rowspan']) && $cells[($i+$cspi)][$j+$ccolsp]['rowspan']<2)) { // don't overwrite bordering cells that span
25453 $celladj['border_details']['L'] = $cbord['border_details']['R'];
25454 $this->setBorder($cbord['border'] , _BORDER_RIGHT);
25455 }
25456 }
25457 }
25458 else if ($celladj) {
25459 // if right-cell border is not set
25460 if (!isset($cells[($i+$cspi)][$j+$ccolsp]['rowspan']) || (isset($cells[($i+$cspi)][$j+$ccolsp]['rowspan']) && $cells[($i+$cspi)][$j+$ccolsp]['rowspan']<2)) { // don't overwrite bordering cells that span
25461 $celladj['border_details']['L'] = $cbord['border_details']['R'];
25462 }
25463 }
25464 if ($celladj && $this->packTableData) {
25465 $celladj['borderbin'] = $this->_packCellBorder($celladj);
25466 unset($celladj['border']);
25467 unset($celladj['border_details']);
25468 }
25469 if ($this->cacheTables) {
25470 $this->_cacheUpdateBorder($celladj, $fh, $table['cells'][$i+$cspi][$j+$ccolsp]);
25471 }
25472 unset($celladj);
25473 }
25474 }
25475 }
25476
25477
25478 // Set maximum cell border width meeting at LRTB edges of cell - used for extended cell border
25479 // ['border_details']['mbw']['LT'] = meeting border width - Left border - Top end
25480 if (!$table['borders_separate']) {
25481 $cbord['border_details']['mbw']['BL'] = max($cbord['border_details']['mbw']['BL'], $cbord['border_details']['L']['w']);
25482 $cbord['border_details']['mbw']['BR'] = max($cbord['border_details']['mbw']['BR'], $cbord['border_details']['R']['w']);
25483 $cbord['border_details']['mbw']['RT'] = max($cbord['border_details']['mbw']['RT'], $cbord['border_details']['T']['w']);
25484 $cbord['border_details']['mbw']['RB'] = max($cbord['border_details']['mbw']['RB'], $cbord['border_details']['B']['w']);
25485 $cbord['border_details']['mbw']['TL'] = max($cbord['border_details']['mbw']['TL'], $cbord['border_details']['L']['w']);
25486 $cbord['border_details']['mbw']['TR'] = max($cbord['border_details']['mbw']['TR'], $cbord['border_details']['R']['w']);
25487 $cbord['border_details']['mbw']['LT'] = max($cbord['border_details']['mbw']['LT'], $cbord['border_details']['T']['w']);
25488 $cbord['border_details']['mbw']['LB'] = max($cbord['border_details']['mbw']['LB'], $cbord['border_details']['B']['w']);
25489 if (($i+$crowsp) < $numrows && isset($cells[$i+$crowsp][$j])) { // Has Bottom adjoining cell
25490 if ($this->packTableData) {
25491 if ($this->cacheTables) {
25492 $adjc = $this->_uncacheCell($table['cells'][$i+$crowsp][$j], '', $fh);
25493 }
25494 else { $adjc = $cells[$i+$crowsp][$j]; }
25495 $celladj = $this->_unpackCellBorder($adjc['borderbin']);
25496 }
25497 else { $celladj =& $cells[$i+$crowsp][$j]; }
25498 $cbord['border_details']['mbw']['BL'] = max($cbord['border_details']['mbw']['BL'], $celladj['border_details']['L']['w'], $celladj['border_details']['mbw']['TL']);
25499 $cbord['border_details']['mbw']['BR'] = max($cbord['border_details']['mbw']['BR'], $celladj['border_details']['R']['w'], $celladj['border_details']['mbw']['TR']);
25500 $cbord['border_details']['mbw']['LB'] = max($cbord['border_details']['mbw']['LB'], $celladj['border_details']['mbw']['LT']);
25501 $cbord['border_details']['mbw']['RB'] = max($cbord['border_details']['mbw']['RB'], $celladj['border_details']['mbw']['RT']);
25502 unset($celladj);
25503 }
25504 if (($j+$ccolsp) < $numcols && isset($cells[$i][$j+$ccolsp])) { // Has Right adjoining cell
25505 if ($this->packTableData) {
25506 if ($this->cacheTables) {
25507 $adjc = $this->_uncacheCell($table['cells'][$i][$j+$ccolsp], '', $fh);
25508 }
25509 else { $adjc = $cells[$i][$j+$ccolsp]; }
25510 $celladj = $this->_unpackCellBorder($adjc['borderbin']);
25511 }
25512 else { $celladj =& $cells[$i][$j+$ccolsp]; }
25513 $cbord['border_details']['mbw']['RT'] = max($cbord['border_details']['mbw']['RT'], $celladj['border_details']['T']['w'], $celladj['border_details']['mbw']['LT']);
25514 $cbord['border_details']['mbw']['RB'] = max($cbord['border_details']['mbw']['RB'], $celladj['border_details']['B']['w'], $celladj['border_details']['mbw']['LB']);
25515 $cbord['border_details']['mbw']['TR'] = max($cbord['border_details']['mbw']['TR'], $celladj['border_details']['mbw']['TL']);
25516 $cbord['border_details']['mbw']['BR'] = max($cbord['border_details']['mbw']['BR'], $celladj['border_details']['mbw']['BL']);
25517 unset($celladj);
25518 }
25519
25520 if ($i > 0 && isset($cells[$i-1][$j]) && (($this->packTableData && $cells[$i-1][$j]['borderbin']) || $cells[$i-1][$j]['border'])) { // Has Top adjoining cell
25521 if ($this->packTableData) {
25522 if ($this->cacheTables) {
25523 $adjc = $this->_uncacheCell($table['cells'][$i-1][$j], '', $fh);
25524 }
25525 else { $adjc = $cells[$i-1][$j]; }
25526 $celladj = $this->_unpackCellBorder($adjc['borderbin']);
25527 }
25528 else { $celladj =& $cells[$i-1][$j]; }
25529 $cbord['border_details']['mbw']['TL'] = max($cbord['border_details']['mbw']['TL'], $celladj['border_details']['L']['w'], $celladj['border_details']['mbw']['BL']);
25530 $cbord['border_details']['mbw']['TR'] = max($cbord['border_details']['mbw']['TR'], $celladj['border_details']['R']['w'], $celladj['border_details']['mbw']['BR']);
25531 $cbord['border_details']['mbw']['LT'] = max($cbord['border_details']['mbw']['LT'], $celladj['border_details']['mbw']['LB']);
25532 $cbord['border_details']['mbw']['RT'] = max($cbord['border_details']['mbw']['RT'], $celladj['border_details']['mbw']['RB']);
25533
25534 if ($celladj['border_details']['mbw']['BL']) {
25535 $celladj['border_details']['mbw']['BL'] = max($cbord['border_details']['mbw']['TL'], $celladj['border_details']['mbw']['BL']);
25536 }
25537 if ($celladj['border_details']['mbw']['BR'] ) {
25538 $celladj['border_details']['mbw']['BR'] = max($celladj['border_details']['mbw']['BR'], $cbord['border_details']['mbw']['TR']);
25539 }
25540 if ($this->packTableData) { $cells[$i-1][$j]['borderbin'] = $this->_packCellBorder($celladj); }
25541 unset($celladj);
25542 }
25543 if ($j > 0 && isset($cells[$i][$j-1]) && (($this->packTableData && $cells[$i][$j-1]['borderbin']) || $cells[$i][$j-1]['border'])) { // Has Left adjoining cell
25544 if ($this->packTableData) {
25545 if ($this->cacheTables) {
25546 $adjc = $this->_uncacheCell($table['cells'][$i][$j-1], '', $fh);
25547 }
25548 else { $adjc = $cells[$i][$j-1]; }
25549 $celladj = $this->_unpackCellBorder($adjc['borderbin']);
25550 }
25551 else { $celladj =& $cells[$i][$j-1]; }
25552 $cbord['border_details']['mbw']['LT'] = max($cbord['border_details']['mbw']['LT'], $celladj['border_details']['T']['w'], $celladj['border_details']['mbw']['RT']);
25553 $cbord['border_details']['mbw']['LB'] = max($cbord['border_details']['mbw']['LB'], $celladj['border_details']['B']['w'], $celladj['border_details']['mbw']['RB']);
25554 $cbord['border_details']['mbw']['BL'] = max($cbord['border_details']['mbw']['BL'], $celladj['border_details']['mbw']['BR']);
25555 $cbord['border_details']['mbw']['TL'] = max($cbord['border_details']['mbw']['TL'], $celladj['border_details']['mbw']['TR']);
25556
25557 if ($celladj['border_details']['mbw']['RT']) {
25558 $celladj['border_details']['mbw']['RT'] = max($celladj['border_details']['mbw']['RT'], $cbord['border_details']['mbw']['LT']);
25559 }
25560 if ($celladj['border_details']['mbw']['RB']) {
25561 $celladj['border_details']['mbw']['RB'] = max($celladj['border_details']['mbw']['RB'], $cbord['border_details']['mbw']['LB']);
25562 }
25563 if ($this->packTableData) { $cells[$i][$j-1]['borderbin'] = $this->_packCellBorder($celladj); }
25564 unset($celladj);
25565 }
25566
25567
25568 // Update maximum cell border width at LRTB edges of table - used for overall table width
25569 if ($j == 0 && $cbord['border_details']['L']['w']) {
25570 $table['max_cell_border_width']['L'] = max($table['max_cell_border_width']['L'],$cbord['border_details']['L']['w']);
25571 }
25572 if (($j == ($numcols-1) || ($j+$ccolsp) == $numcols ) && $cbord['border_details']['R']['w']) {
25573 $table['max_cell_border_width']['R'] = max($table['max_cell_border_width']['R'],$cbord['border_details']['R']['w']);
25574 }
25575 if ($i == 0 && $cbord['border_details']['T']['w']) {
25576 $table['max_cell_border_width']['T'] = max($table['max_cell_border_width']['T'],$cbord['border_details']['T']['w']);
25577 }
25578 if (($i == ($numrows-1) || ($i+$crowsp) == $numrows ) && $cbord['border_details']['B']['w']) {
25579 $table['max_cell_border_width']['B'] = max($table['max_cell_border_width']['B'],$cbord['border_details']['B']['w']);
25580 }
25581 }
25582 /*-- END TABLES-ADVANCED-BORDERS --*/
25583
25584 if ($this->packTableData) { $cell['borderbin'] = $this->_packCellBorder($cbord); }
25585
25586 if ($this->cacheTables) {
25587 $this->_cacheUpdateBorder($cell, $fh, $table['cells'][$i][$j]);
25588 }
25589 unset($cbord );
25590 unset($cell );
25591 }
25592 }
25593 }
25594 if ($this->cacheTables) { fclose($fh); }
25595 unset($cell );
25596 }
25597 // END FIX BORDERS ************************************************************************************
25598
25599
25600 function _reverseTableDir(&$table) {
25601 if ($this->cacheTables) { $fh = fopen($table['cache'], "r+b"); }
25602 $cells = &$table['cells'];
25603 $numcols = $table['nc'];
25604 $numrows = $table['nr'];
25605 for( $i = 0 ; $i < $numrows ; $i++ ) { //Rows
25606 $row = array();
25607 for( $j = ($numcols-1) ; $j >= 0 ; $j-- ) { //Columns
25608 if (isset($cells[$i][$j]) && $cells[$i][$j]) {
25609 if ($this->cacheTables) {
25610 $cell = $this->_uncacheCell($table['cells'][$i][$j], '', $fh);
25611 }
25612 else
25613 $cell = &$cells[$i][$j];
25614 $col = $numcols - $j - 1;
25615 if (isset($cell['colspan']) && $cell['colspan'] > 1) { $col -= ($cell['colspan']-1); }
25616 // Nested content
25617 for ($n=0; $n < count($cell['textbuffer']); $n++) {
25618 $t = $cell['textbuffer'][$n][0];
25619 if (substr($t,0,19) == "\xbb\xa4\xactype=nestedtable") {
25620 $objattr = $this->_getObjAttr($t);
25621 $objattr['col'] = $col;
25622 $cell['textbuffer'][$n][0] = "\xbb\xa4\xactype=nestedtable,objattr=".serialize($objattr)."\xbb\xa4\xac";
25623 $this->table[($this->tableLevel+1)][$objattr['nestedcontent']]['nestedpos'][1] = $col;
25624 if ($this->cacheTables) {
25625 $this->_cacheUpdateTxB($cell, $fh, $table['cells'][$i][$j]);
25626 }
25627 }
25628 }
25629 $row[$col] = $cells[$i][$j];
25630 unset($cell);
25631 }
25632 }
25633 for($f=0; $f < $numcols; $f++) {
25634 if (!isset($row[$f])) { $row[$f] = 0; }
25635 }
25636 $table['cells'][$i] = $row;
25637 }
25638 if ($this->cacheTables) { fclose($fh); }
25639 }
25640
25641
25642 function _tableWrite(&$table, $split=false, $startrow=0, $startcol=0, $splitpg=0, $rety = 0){
25643 $level = $table['level'];
25644 $levelid = $table['levelid'];
25645
25646 $cells = &$table['cells'];
25647 $numcols = $table['nc'];
25648 $numrows = $table['nr'];
25649
25650 if ($this->ColActive && $level==1) { $this->breakpoints[$this->CurrCol][] = $this->y; } // *COLUMNS*
25651
25652 if (!$split || ($startrow==0 && $splitpg==0) || $startrow>0){
25653 // TABLE TOP MARGIN
25654 if ($table['margin']['T']) {
25655 if (!$this->table_rotate && $level==1) {
25656 $this->DivLn($table['margin']['T'],$this->blklvl,true,1); // collapsible
25657 }
25658 else {
25659 $this->y += ($table['margin']['T']);
25660 }
25661 }
25662 // Advance down page by half width of top border
25663 if ($table['borders_separate']) {
25664 if ($startrow>0 && (!isset($table['is_thead']) || count($table['is_thead'])==0))
25665 $adv = $table['border_spacing_V']/2;
25666 else
25667 $adv = $table['padding']['T'] + $table['border_details']['T']['w'] + $table['border_spacing_V']/2;
25668 }
25669 else {
25670 $adv = $table['max_cell_border_width']['T']/2;
25671 }
25672 if (!$this->table_rotate && $level==1) { $this->DivLn($adv); }
25673 else { $this->y += $adv; }
25674 }
25675
25676 if ($level==1) {
25677 $this->x = $this->lMargin + $this->blk[$this->blklvl]['outer_left_margin'] + $this->blk[$this->blklvl]['padding_left'] + $this->blk[$this->blklvl]['border_left']['w'];
25678 $x0 = $this->x;
25679 $y0 = $this->y;
25680 $right = $x0 + $this->blk[$this->blklvl]['inner_width'];
25681 $outerfilled = $this->y; // Keep track of how far down the outer DIV bgcolor is painted (NB rowspans)
25682 $this->outerfilled = $this->y;
25683 $this->colsums = array();
25684 }
25685 else {
25686 $x0 = $this->x;
25687 $y0 = $this->y;
25688 $right = $x0 + $table['w'];
25689 }
25690
25691 if ($this->table_rotate) {
25692 $temppgwidth = $this->tbrot_maxw;
25693 $this->PageBreakTrigger = $pagetrigger = $y0 + ($this->blk[$this->blklvl]['inner_width']);
25694 if ($level==1) {
25695 $this->tbrot_y0 = $this->y - $adv - $table['margin']['T'] ;
25696 $this->tbrot_x0 = $this->x;
25697 $this->tbrot_w = $table['w'];
25698 if ($table['borders_separate']) { $this->tbrot_h = $table['margin']['T'] + $table['padding']['T'] + $table['border_details']['T']['w'] + $table['border_spacing_V']/2; }
25699 else { $this->tbrot_h = $table['margin']['T'] + $table['padding']['T'] + $table['max_cell_border_width']['T']; }
25700 }
25701 }
25702 else {
25703 $this->PageBreakTrigger = $pagetrigger = ($this->h - $this->bMargin);
25704 if ($level==1) {
25705 $temppgwidth = $this->blk[$this->blklvl]['inner_width'];
25706 if (isset($table['a']) and ($table['w'] < $this->blk[$this->blklvl]['inner_width'])) {
25707 if ($table['a']=='C') { $x0 += ((($right-$x0) - $table['w'])/2); }
25708 else if ($table['a']=='R') { $x0 = $right - $table['w']; }
25709 }
25710 }
25711 else {
25712 $temppgwidth = $table['w'];
25713 }
25714 }
25715 if(!isset($table['overflow'])) { $table['overflow'] = null; }
25716 if ($table['overflow']=='hidden' && $level==1 && !$this->table_rotate && !$this->ColActive) {
25717 //Bounding rectangle to clip
25718 $this->tableClipPath = sprintf('q %.3F %.3F %.3F %.3F re W n',$x0*_MPDFK,$this->h*_MPDFK,$this->blk[$this->blklvl]['inner_width']*_MPDFK,-$this->h*_MPDFK);
25719 $this->_out($this->tableClipPath);
25720 }
25721 else { $this->tableClipPath = ''; }
25722
25723
25724 if ($table['borders_separate']) { $indent = $table['margin']['L'] + $table['border_details']['L']['w'] + $table['padding']['L'] + $table['border_spacing_H']/2; }
25725 else { $indent = $table['margin']['L'] + $table['max_cell_border_width']['L']/2; }
25726 $x0 += $indent;
25727
25728 $returny = 0;
25729 $lastCol = 0;
25730 $tableheader = array();
25731 $tablefooter = array();
25732 $tableheaderrowheight = 0;
25733 $tablefooterrowheight = 0;
25734 $footery = 0;
25735
25736 // mPD 3.0 Set the Page & Column where table starts
25737 if (($this->mirrorMargins) && (($this->page)%2==0)) { // EVEN
25738 $tablestartpage = 'EVEN';
25739 }
25740 else if (($this->mirrorMargins) && (($this->page)%2==1)) { // ODD
25741 $tablestartpage = 'ODD';
25742 }
25743 else { $tablestartpage = ''; }
25744 if ($this->ColActive) { $tablestartcolumn = $this->CurrCol; }
25745 else { $tablestartcolumn = ''; }
25746
25747 if ($this->cacheTables) { $fh = fopen($table['cache'], "r+b"); }
25748 else { $fh = null; }
25749
25750 $y = $h = 0;
25751 for( $i = 0; $i < $numrows ; $i++ ) { //Rows
25752 if ($this->progressBar) { $this->UpdateProgressBar(7,intval(30 + ($i*40/$numrows)),' '); } // *PROGRESS-BAR*
25753 if (isset($table['is_tfoot'][$i]) && $table['is_tfoot'][$i] && $level==1) {
25754 $tablefooterrowheight += $table['hr'][$i];
25755 $tablefooter[$i][0]['trbackground-images'] = $table['trbackground-images'][$i];
25756 $tablefooter[$i][0]['trgradients'] = $table['trgradients'][$i];
25757 $tablefooter[$i][0]['trbgcolor'] = $table['bgcolor'][$i];
25758 for( $j = $startcol ; $j < $numcols ; $j++ ) { //Columns
25759 if (isset($cells[$i][$j]) && $cells[$i][$j]) {
25760 if ($this->cacheTables) {
25761 $cell = $this->_uncacheCell($table['cells'][$i][$j], '', $fh);
25762 }
25763 else
25764 $cell = &$cells[$i][$j];
25765 if ($split) {
25766 if ($table['colPg'][$j] != $splitpg) { continue; }
25767 list($x,$w) = $this->_splitTableGetWidth($table, $i, $j, $fh);
25768 $js = $j - $startcol;
25769 }
25770 else {
25771 list($x,$w) = $this->_tableGetWidth($table, $i, $j, $fh);
25772 $js = $j;
25773 }
25774
25775 list($y,$h) = $this->_tableGetHeight($table, $i, $j, $fh);
25776 $x += $x0;
25777 $y += $y0;
25778 //Get info of tfoot ==>> table footer
25779 $tablefooter[$i][$js]['x'] = $x;
25780 $tablefooter[$i][$js]['y'] = $y;
25781 $tablefooter[$i][$js]['h'] = $h;
25782 $tablefooter[$i][$js]['w'] = $w;
25783 if (isset($cell['textbuffer'])) { $tablefooter[$i][$js]['textbuffer'] = $cell['textbuffer']; }
25784 else { $tablefooter[$i][$js]['textbuffer'] = ''; }
25785 $tablefooter[$i][$js]['a'] = $cell['a'];
25786 $tablefooter[$i][$js]['R'] = $cell['R'];
25787 $tablefooter[$i][$js]['va'] = $cell['va'];
25788 $tablefooter[$i][$js]['mih'] = $cell['mih'];
25789 $tablefooter[$i][$js]['gradient'] = $cell['gradient']; // *BACKGROUNDS*
25790 $tablefooter[$i][$js]['background-image'] = $cell['background-image']; // *BACKGROUNDS*
25791 //CELL FILL BGCOLOR
25792 if (!$this->simpleTables){
25793 if ($this->packTableData) {
25794 $c = $this->_unpackCellBorder($cell['borderbin']);
25795 $tablefooter[$i][$js]['border'] = $c['border'];
25796 $tablefooter[$i][$js]['border_details'] = $c['border_details'];
25797 }
25798 else {
25799 $tablefooter[$i][$js]['border'] = $cell['border'];
25800 $tablefooter[$i][$js]['border_details'] = $cell['border_details'];
25801 }
25802 }
25803 else if ($this->simpleTables){
25804 $tablefooter[$i][$js]['border'] = $table['simple']['border'];
25805 $tablefooter[$i][$js]['border_details'] = $table['simple']['border_details'];
25806 }
25807 $tablefooter[$i][$js]['bgcolor'] = $cell['bgcolor'];
25808 $tablefooter[$i][$js]['padding'] = $cell['padding'];
25809 $tablefooter[$i][$js]['rowspan'] = $cell['rowspan'];
25810 $tablefooter[$i][$js]['colspan'] = $cell['colspan'];
25811 }
25812 }
25813 }
25814 }
25815
25816 if ($level==1) { $this->_out('___TABLE___BACKGROUNDS'.date('jY')); }
25817 $tableheaderadj = 0;
25818 $tablefooteradj = 0;
25819
25820 $tablestartpageno = $this->page;
25821
25822 //Draw Table Contents and Borders
25823 for( $i = 0; $i < $numrows ; $i++ ) { //Rows
25824 if ($split && $startrow > 0) {
25825 $thnr = (isset($table['is_thead']) ? count($table['is_thead']) : 0);
25826 if ($i >= $thnr && $i < $startrow) { continue; }
25827 if ($i == $startrow){ $returny = $rety - $tableheaderrowheight; }
25828 }
25829
25830 // Get Maximum row/cell height in row - including rowspan>1 + 1 overlapping
25831 $maxrowheight = $this->_tableGetMaxRowHeight($table, $i, $fh);
25832
25833 $skippage = false;
25834 $newpagestarted = false;
25835 for( $j = $startcol ; $j < $numcols ; $j++ ) { //Columns
25836 if ($split) {
25837 if ($table['colPg'][$j] > $splitpg) { break; }
25838 $lastCol = $j;
25839 }
25840 if (isset($cells[$i][$j]) && $cells[$i][$j]) {
25841 if ($this->cacheTables) {
25842 $cell = $this->_uncacheCell($table['cells'][$i][$j], '', $fh);
25843 }
25844 else
25845 $cell = &$cells[$i][$j];
25846 if ($split) {
25847 $lastCol = $j + (isset($cell['colspan']) ? ($cell['colspan']-1) : 0) ;
25848 list($x,$w) = $this->_splitTableGetWidth($table, $i, $j, $fh);
25849 }
25850 else { list($x,$w) = $this->_tableGetWidth($table, $i, $j, $fh); }
25851
25852 list($y,$h) = $this->_tableGetHeight($table, $i, $j, $fh);
25853 $x += $x0;
25854 $y += $y0;
25855 $y -= $returny;
25856
25857 if ($table['borders_separate']) {
25858 if (!empty($tablefooter) || $i == ($numrows-1) || (isset($cell['rowspan']) && ($i+$cell['rowspan']) == $numrows) || (!isset($cell['rowspan']) && ($i+1) == $numrows) ) {
25859 $extra = $table['padding']['B'] + $table['border_details']['B']['w'] + $table['border_spacing_V']/2;
25860 //$extra = $table['margin']['B'] + $table['padding']['B'] + $table['border_details']['B']['w'] + $table['border_spacing_V']/2;
25861 }
25862 else {
25863 $extra = $table['border_spacing_V']/2;
25864 }
25865 }
25866 else { $extra = $table['max_cell_border_width']['B']/2; }
25867
25868 if ($j==$startcol && ((($y + $maxrowheight + $extra ) > ($pagetrigger+0.001)) || (($this->keepColumns || !$this->ColActive) && !empty($tablefooter) && ($y + $maxrowheight + $tablefooterrowheight + $extra) > $pagetrigger) && ($this->tableLevel==1 && $i < ($numrows - $table['headernrows']))) && ($y0 >0 || $x0 > 0) && !$this->InFooter && $this->autoPageBreak ) {
25869
25870 if (!$skippage) {
25871 $finalSpread = true;
25872 $firstSpread = true;
25873 if ($split) {
25874 for($t=$startcol; $t<$numcols; $t++) {
25875 // Are there more columns to print on a next page?
25876 if ($table['colPg'][$t] > $splitpg) {
25877 $finalSpread = false;
25878 break;
25879 }
25880 }
25881 if ($startcol>0) { $firstSpread = false; }
25882 }
25883
25884 if (($this->keepColumns || !$this->ColActive) && !empty($tablefooter) && $i > 0 ) {
25885 $this->y = $y;
25886 $ya = $this->y;
25887 $this->TableHeaderFooter($tablefooter,$tablestartpage,$tablestartcolumn,'F',$level, $firstSpread, $finalSpread);
25888 if ($this->table_rotate) {
25889 $this->tbrot_h += $this->y - $ya ;
25890 }
25891 $tablefooteradj = $this->y - $ya ;
25892 }
25893 $y -= $y0;
25894 $returny += $y;
25895
25896 $oldcolumn = $this->CurrCol;
25897 if ($this->AcceptPageBreak()) {
25898 $newpagestarted = true;
25899 $this->y = $y + $y0;
25900
25901 // Move down to account for border-spacing or
25902 // extra half border width in case page breaks in middle
25903 if($i>0 && !$this->table_rotate && $level==1 && !$this->ColActive) {
25904 if ($table['borders_separate']) {
25905 $adv = $table['border_spacing_V']/2;
25906 // If table footer
25907 if (($this->keepColumns || !$this->ColActive) && !empty($tablefooter) && $i > 0 ) {
25908 $adv += ($table['padding']['B'] + $table['border_details']['B']['w']);
25909 }
25910 }
25911 else {
25912 $maxbwtop = 0;
25913 $maxbwbottom = 0;
25914 if (!$this->simpleTables){
25915 if (!empty($tablefooter)) { $maxbwbottom = $table['max_cell_border_width']['B']; }
25916 else {
25917 $brow = $i-1;
25918 for( $ctj = 0 ; $ctj < $numcols ; $ctj++ ) {
25919 if (isset($cells[$brow][$ctj]) && $cells[$brow][$ctj]) {
25920 if ($this->cacheTables) {
25921 $cadj = $this->_uncacheCell($table['cells'][$brow][$ctj], '', $fh);
25922 list($bt,$br,$bb,$bl) = $this->_getBorderWidths($cadj['borderbin']);
25923 }
25924 else if ($this->packTableData) {
25925 list($bt,$br,$bb,$bl) = $this->_getBorderWidths($cells[$brow][$ctj]['borderbin']);
25926 }
25927 else {
25928 $bb = $cells[$brow][$ctj]['border_details']['B']['w'];
25929 }
25930 $maxbwbottom = max($maxbwbottom , $bb);
25931 }
25932 }
25933 }
25934 if (!empty($tableheader)) { $maxbwtop = $table['max_cell_border_width']['T']; }
25935 else {
25936 $trow = $i-1;
25937 for( $ctj = 0 ; $ctj < $numcols ; $ctj++ ) {
25938 if (isset($cells[$trow][$ctj]) && $cells[$trow][$ctj]) {
25939 if ($this->cacheTables) {
25940 $cadj = $this->_uncacheCell($table['cells'][$trow][$ctj], '', $fh);
25941 list($bt,$br,$bb,$bl) = $this->_getBorderWidths($cadj['borderbin']);
25942 }
25943 else if ($this->packTableData) {
25944 list($bt,$br,$bb,$bl) = $this->_getBorderWidths($cells[$trow][$ctj]['borderbin']);
25945 }
25946 else {
25947 $bt = $cells[$trow][$ctj]['border_details']['T']['w'];
25948 }
25949 $maxbwtop = max($maxbwtop , $bt);
25950 }
25951 }
25952 }
25953 }
25954 else if ($this->simpleTables){
25955 $maxbwtop = $table['simple']['border_details']['T']['w'];
25956 $maxbwbottom = $table['simple']['border_details']['B']['w'];
25957 }
25958 $adv = $maxbwbottom /2;
25959 }
25960 $this->y += $adv;
25961 }
25962
25963 // Rotated table split over pages - needs this->y for borders/backgrounds
25964 if($i>0 && $this->table_rotate && $level==1) {
25965 // $this->y = $y0 + $this->tbrot_w;
25966 }
25967
25968 if ($this->tableClipPath ) { $this->_out("Q"); }
25969
25970 $bx = $x0;
25971 $by = $y0;
25972
25973 if ($table['borders_separate']) {
25974 $bx -= ($table['padding']['L'] + $table['border_details']['L']['w'] + $table['border_spacing_H']/2);
25975 if ($tablestartpageno != $this->page) { // IF already broken across a previous pagebreak
25976 $by += $table['max_cell_border_width']['T']/2;
25977 if (empty($tableheader)) { $by -= ($table['border_spacing_V']/2); }
25978 }
25979 else {
25980 $by -= ($table['padding']['T'] + $table['border_details']['T']['w'] + $table['border_spacing_V']/2);
25981 }
25982 }
25983
25984 else if ($tablestartpageno != $this->page && !empty($tableheader)) { $by += $maxbwtop /2; }
25985
25986 $by -= $tableheaderadj;
25987 $bh = $this->y - $by + $tablefooteradj;
25988 if (!$table['borders_separate']) { $bh -= $adv ; }
25989 if ($split) {
25990 $bw = 0;
25991 for($t=$startcol; $t<$numcols; $t++) {
25992 if ($table['colPg'][$t] == $splitpg) { $bw += $table['wc'][$t]; }
25993 if ($table['colPg'][$t] > $splitpg) { break; }
25994 }
25995 if ($table['borders_separate']) {
25996 if ($firstSpread) {
25997 $bw += $table['padding']['L'] + $table['border_details']['L']['w'] + $table['border_spacing_H'];
25998 }
25999 else {
26000 $bx += ($table['padding']['L'] + $table['border_details']['L']['w']);
26001 $bw += $table['border_spacing_H'];
26002 }
26003 if ($finalSpread) {
26004 $bw += $table['padding']['R'] + $table['border_details']['R']['w']/2 + $table['border_spacing_H'];
26005 }
26006 }
26007 }
26008 else {
26009 $bw = $table['w'] - ($table['max_cell_border_width']['L']/2) - ($table['max_cell_border_width']['R']/2) - $table['margin']['L'] - $table['margin']['R'];
26010 }
26011
26012 // mPDF 5.4.16
26013 if ($this->splitTableBorderWidth && ($this->keepColumns || !$this->ColActive) && empty($tablefooter) && $i > 0 && $table['border_details']['B']['w']) {
26014 $prevDrawColor = $this->DrawColor;
26015 $lw = $this->LineWidth;
26016 $this->SetLineWidth($this->splitTableBorderWidth);
26017 $this->SetDColor($table['border_details']['B']['c']);
26018 $this->SetLineJoin(0);
26019 $this->SetLineCap(0);
26020 $blx = $bx;
26021 $blw = $bw;
26022 if (!$table['borders_separate']) {
26023 $blx -= ($table['max_cell_border_width']['L']/2);
26024 $blw += ($table['max_cell_border_width']['L']/2 + $table['max_cell_border_width']['R']/2);
26025 }
26026 $this->Line($blx,$this->y+($this->splitTableBorderWidth/2),$blx+$blw,$this->y+($this->splitTableBorderWidth/2));
26027 $this->DrawColor = $prevDrawColor;
26028 $this->_out($this->DrawColor);
26029 $this->SetLineWidth($lw);
26030 $this->SetLineJoin(2);
26031 $this->SetLineCap(2);
26032 }
26033
26034 if (!$this->ColActive && ($i > 0 || $j > 0)) {
26035 if (isset($table['bgcolor'][-1])) {
26036 $color = $this->ConvertColor($table['bgcolor'][-1]);
26037 if ($color) {
26038 if (!$table['borders_separate']) { $bh -= $table['max_cell_border_width']['B']/2; }
26039 $this->tableBackgrounds[$level*9][] = array('gradient'=>false, 'x'=>$bx, 'y'=>$by, 'w'=>$bw, 'h'=>$bh, 'col'=>$color);
26040 }
26041 }
26042
26043 /*-- BACKGROUNDS --*/
26044 if (isset($table['gradient'])) {
26045 $g = $this->grad->parseBackgroundGradient($table['gradient']);
26046 if ($g) {
26047 $this->tableBackgrounds[$level*9+1][] = array('gradient'=>true, 'x'=>$bx, 'y'=>$by, 'w'=>$bw, 'h'=>$bh, 'gradtype'=>$g['type'], 'stops'=>$g['stops'], 'colorspace'=>$g['colorspace'], 'coords'=>$g['coords'], 'extend'=>$g['extend'], 'clippath'=>'');
26048 }
26049 }
26050
26051 if (isset($table['background-image'])) {
26052 if ($table['background-image']['gradient'] && preg_match('/(-moz-)*(repeating-)*(linear|radial)-gradient/', $table['background-image']['gradient'] )) {
26053 $g = $this->grad->parseMozGradient( $table['background-image']['gradient'] );
26054 if ($g) {
26055 $this->tableBackgrounds[$level*9+1][] = array('gradient'=>true, 'x'=>$bx, 'y'=>$by, 'w'=>$bw, 'h'=>$bh, 'gradtype'=>$g['type'], 'stops'=>$g['stops'], 'colorspace'=>$g['colorspace'], 'coords'=>$g['coords'], 'extend'=>$g['extend'], 'clippath'=>'');
26056 }
26057 }
26058 else {
26059 $image_id = $table['background-image']['image_id'];
26060 $orig_w = $table['background-image']['orig_w'];
26061 $orig_h = $table['background-image']['orig_h'];
26062 $x_pos = $table['background-image']['x_pos'];
26063 $y_pos = $table['background-image']['y_pos'];
26064 $x_repeat = $table['background-image']['x_repeat'];
26065 $y_repeat = $table['background-image']['y_repeat'];
26066 $resize = $table['background-image']['resize'];
26067 $opacity = $table['background-image']['opacity'];
26068 $itype = $table['background-image']['itype'];
26069 $this->tableBackgrounds[$level*9+2][] = array('x'=>$bx, 'y'=>$by, 'w'=>$bw, 'h'=>$bh, 'image_id'=>$image_id, 'orig_w'=>$orig_w, 'orig_h'=>$orig_h, 'x_pos'=>$x_pos, 'y_pos'=>$y_pos, 'x_repeat'=>$x_repeat, 'y_repeat'=>$y_repeat, 'clippath'=>'', 'resize'=>$resize, 'opacity'=>$opacity, 'itype'=>$itype);
26070 }
26071 }
26072 /*-- END BACKGROUNDS --*/
26073 }
26074
26075 // $this->AcceptPageBreak() has moved tablebuffer to $this->pages content
26076 if ($this->tableBackgrounds) {
26077 $s = $this->PrintTableBackgrounds();
26078 if ($this->bufferoutput) {
26079 $this->headerbuffer = preg_replace('/(___TABLE___BACKGROUNDS'.date('jY').')/', '\\1'."\n".$s."\n", $this->headerbuffer);
26080 $this->headerbuffer = preg_replace('/(___TABLE___BACKGROUNDS'.date('jY').')/', " ", $this->headerbuffer );
26081 }
26082 else {
26083 $this->pages[$this->page] = preg_replace('/(___TABLE___BACKGROUNDS'.date('jY').')/', '\\1'."\n".$s."\n", $this->pages[$this->page]);
26084 $this->pages[$this->page] = preg_replace('/(___TABLE___BACKGROUNDS'.date('jY').')/', " ", $this->pages[$this->page]);
26085 }
26086 $this->tableBackgrounds = array();
26087 }
26088
26089 if ($split) {
26090 if ($i == 0 && $j == 0) { $y0 = -1; }
26091 else if ($finalSpread) {
26092 $splitpg = 0;
26093 $startcol = 0;
26094 $startrow = $i;
26095 }
26096 else {
26097 $splitpg++;
26098 $startcol = $t;
26099 $returny -= $y;
26100 }
26101 return array(false, $startrow, $startcol, $splitpg, $returny, $y0);
26102 }
26103
26104 $this->AddPage($this->CurOrientation);
26105
26106 $this->_out('___TABLE___BACKGROUNDS'.date('jY'));
26107
26108
26109 if ($this->tableClipPath ) { $this->_out($this->tableClipPath); }
26110
26111 // Added to correct for OddEven Margins
26112 $x= $x + $this->MarginCorrection;
26113 $x0= $x0 + $this->MarginCorrection;
26114
26115 // mPDF 5.4.16
26116 if ($this->splitTableBorderWidth && ($this->keepColumns || !$this->ColActive) && empty($tableheader) && $i > 0 && $table['border_details']['T']['w'] ) {
26117 $prevDrawColor = $this->DrawColor;
26118 $lw = $this->LineWidth;
26119 $this->SetLineWidth($this->splitTableBorderWidth);
26120 $this->SetDColor($table['border_details']['T']['c']);
26121 $this->SetLineJoin(0);
26122 $this->SetLineCap(0);
26123 $blx += $this->MarginCorrection;
26124 $this->Line($blx,$this->y-($this->splitTableBorderWidth/2),$blx+$blw,$this->y-($this->splitTableBorderWidth/2));
26125 $this->DrawColor = $prevDrawColor;
26126 $this->_out($this->DrawColor);
26127 $this->SetLineWidth($lw);
26128 $this->SetLineJoin(2);
26129 $this->SetLineCap(2);
26130 }
26131
26132 // Move down to account for half of top border-spacing or
26133 // extra half border width in case page was broken in middle
26134 if($i>0 && !$this->table_rotate && $level==1 && $table['headernrows']==0) {
26135 if ($table['borders_separate']) { $adv = $table['border_spacing_V']/2; }
26136 else {
26137 $maxbwtop = 0;
26138 for( $ctj = 0 ; $ctj < $numcols ; $ctj++ ) {
26139 if (isset($cells[$i][$ctj]) && $cells[$i][$ctj]) {
26140 if (!$this->simpleTables){
26141 if ($this->cacheTables) {
26142 $celltj = $this->_uncacheCell($table['cells'][$i][$ctj], '', $fh);
26143 list($bt,$br,$bb,$bl) = $this->_getBorderWidths($celltj['borderbin']);
26144 }
26145 else if ($this->packTableData) {
26146 list($bt,$br,$bb,$bl) = $this->_getBorderWidths($cells[$i][$ctj]['borderbin']);
26147 }
26148 else {
26149 $bt = $cells[$i][$ctj]['border_details']['T']['w'];
26150 }
26151 $maxbwtop = max($maxbwtop, $bt);
26152 }
26153 else if ($this->simpleTables){
26154 $maxbwtop = max($maxbwtop, $table['simple']['border_details']['T']['w']);
26155 }
26156 }
26157 }
26158 $adv = $maxbwtop /2;
26159 }
26160 $this->y += $adv;
26161 }
26162
26163
26164 if ($this->table_rotate) {
26165 $this->tbrot_x0 = $this->lMargin + $this->blk[$this->blklvl]['outer_left_margin'] + $this->blk[$this->blklvl]['padding_left'] + $this->blk[$this->blklvl]['border_left']['w'];
26166 if ($table['borders_separate']) { $this->tbrot_h = $table['margin']['T'] + $table['padding']['T'] + $table['border_details']['T']['w'] + $table['border_spacing_V']/2; }
26167 else { $this->tbrot_h = $table['margin']['T'] + $table['max_cell_border_width']['T'] ; }
26168 $this->tbrot_y0 = $this->y;
26169 $pagetrigger = $y0 - $tableheaderadj + ($this->blk[$this->blklvl]['inner_width']);
26170 }
26171 else {
26172 $pagetrigger = $this->PageBreakTrigger;
26173 }
26174
26175 if ($this->kwt_saved && $level==1) {
26176 $this->kwt_moved = true;
26177 }
26178
26179
26180 // Disable Table header repeat if Keep Block together
26181 if (!$this->keep_block_together && !empty($tableheader)) {
26182 $ya = $this->y;
26183 $this->TableHeaderFooter($tableheader,$tablestartpage,$tablestartcolumn,'H',$level);
26184 if ($this->table_rotate) {
26185 $this->tbrot_h = $this->y - $ya ;
26186 }
26187 $tableheaderadj = $this->y - $ya ;
26188 }
26189
26190 else if ($i==0 && !$this->keep_block_together && !$this->table_rotate && $level==1 && !$this->ColActive) {
26191 // Advance down page
26192 if ($table['borders_separate']) { $adv = $table['border_spacing_V']/2 + $table['border_details']['T']['w'] + $table['padding']['T']; }
26193 else { $adv = $table['max_cell_border_width']['T'] /2 ; }
26194 if ($adv) {
26195 if ($this->table_rotate) {
26196 $this->y += ($adv);
26197 }
26198 else {
26199 $this->DivLn($adv,$this->blklvl,true);
26200 }
26201 }
26202 }
26203
26204 $outerfilled = 0;
26205 $y = $y0 = $this->y;
26206 }
26207
26208 /*-- COLUMNS --*/
26209 // COLS
26210 // COLUMN CHANGE
26211 if ($this->CurrCol != $oldcolumn) {
26212 // Added to correct for Columns
26213 $x += $this->ChangeColumn * ($this->ColWidth+$this->ColGap);
26214 $x0 += $this->ChangeColumn * ($this->ColWidth+$this->ColGap);
26215 if ($this->CurrCol == 0) { // just added a page - possibly with tableheader
26216 $y0 = $this->y; // this->y0 is global used by Columns - $y0 is internal to tablewrite
26217 }
26218 else {
26219 $y0 = $this->y0; // this->y0 is global used by Columns - $y0 is internal to tablewrite
26220 }
26221 $y = $y0;
26222 $outerfilled = 0;
26223 if ($this->CurrCol != 0 && ($this->keepColumns && $this->ColActive) && !empty($tableheader) && $i > 0 ) {
26224 $this->x = $x;
26225 $this->y = $y;
26226 $this->TableHeaderFooter($tableheader,$tablestartpage,$tablestartcolumn,'H',$level);
26227 $y0 = $y=$this->y;
26228 }
26229 }
26230 /*-- END COLUMNS --*/
26231 }
26232 $skippage = true;
26233 }
26234
26235 $this->x = $x;
26236 $this->y = $y;
26237
26238 if ($this->kwt_saved && $level==1) {
26239 $this->printkwtbuffer();
26240 $x0 = $x = $this->x;
26241 $y0 = $y = $this->y;
26242 $this->kwt_moved = false;
26243 $this->kwt_saved = false;
26244 }
26245
26246
26247 // Set the Page & Column where table actually starts
26248 if ($i==0 && $j==0 && $level==1) {
26249 if (($this->mirrorMargins) && (($this->page)%2==0)) { // EVEN
26250 $tablestartpage = 'EVEN';
26251 }
26252 else if (($this->mirrorMargins) && (($this->page)%2==1)) { // ODD
26253 $tablestartpage = 'ODD';
26254 }
26255 else { $tablestartpage = ''; }
26256 $tablestartpageno = $this->page;
26257 if ($this->ColActive) { $tablestartcolumn = $this->CurrCol; } // *COLUMNS*
26258 }
26259
26260
26261 //ALIGN
26262 $align = $cell['a'];
26263
26264
26265 /*-- COLUMNS --*/
26266 // If outside columns, this is done in PaintDivBB
26267 if ($this->ColActive) {
26268 //OUTER FILL BGCOLOR of DIVS
26269 if ($this->blklvl > 0 && ($j==0) && !$this->table_rotate && $level==1) {
26270 $firstblockfill = $this->GetFirstBlockFill();
26271 if ($firstblockfill && $this->blklvl >= $firstblockfill) {
26272 $divh = $maxrowheight;
26273 // Last row
26274 if ((!isset($cell['rowspan']) && $i == $numrows-1) || (isset($cell['rowspan']) && (($i == $numrows-1 && $cell['rowspan']<2) || ($cell['rowspan']>1 && ($i + $cell['rowspan']-1) == $numrows-1)))) { // mPDF 5.6.54
26275 if ($table['borders_separate']) {
26276 $adv = $table['margin']['B'] + $table['padding']['B'] + $table['border_details']['B']['w'] + $table['border_spacing_V']/2;
26277 }
26278 else {
26279 $adv = $table['margin']['B'] + $table['max_cell_border_width']['B']/2;
26280 }
26281 $divh += $adv; //last row: fill bottom half of bottom border (y advanced at end)
26282 }
26283
26284 if (($this->y + $divh) > $outerfilled ) { // if not already painted by previous rowspan
26285 $bak_x = $this->x;
26286 $bak_y = $this->y;
26287 if ($outerfilled > $this->y) {
26288 $divh = ($this->y + $divh) - $outerfilled;
26289 $this->y = $outerfilled;
26290 }
26291
26292 $this->DivLn($divh,-3,false);
26293 $outerfilled = $this->y + $divh;
26294 // Reset current block fill
26295 $bcor = $this->blk[$this->blklvl]['bgcolorarray'];
26296 if ($bcor ) $this->SetFColor($bcor);
26297 $this->x = $bak_x;
26298 $this->y = $bak_y;
26299 }
26300 }
26301 }
26302 }
26303
26304
26305 //TABLE BACKGROUND FILL BGCOLOR - for cellSpacing
26306 if ($this->ColActive) {
26307 if ($table['borders_separate']) {
26308 $fill = isset($table['bgcolor'][-1]) ? $table['bgcolor'][-1] : 0;
26309 if ($fill) {
26310 $color = $this->ConvertColor($fill);
26311 if ($color) {
26312 $xadj = ($table['border_spacing_H']/2);
26313 $yadj = ($table['border_spacing_V']/2);
26314 $wadj = $table['border_spacing_H'];
26315 $hadj = $table['border_spacing_V'];
26316 if ($i == 0) { // Top
26317 $yadj += $table['padding']['T'] + $table['border_details']['T']['w'] ;
26318 $hadj += $table['padding']['T'] + $table['border_details']['T']['w'] ;
26319 }
26320 if ($j == 0) { // Left
26321 $xadj += $table['padding']['L'] + $table['border_details']['L']['w'] ;
26322 $wadj += $table['padding']['L'] + $table['border_details']['L']['w'] ;
26323 }
26324 if ($i == ($numrows-1) || (isset($cell['rowspan']) && ($i+$cell['rowspan']) == $numrows) || (!isset($cell['rowspan']) && ($i+1) == $numrows)) { // Bottom
26325 $hadj += $table['padding']['B'] + $table['border_details']['B']['w'] ;
26326 }
26327 if ($j == ($numcols-1) || (isset($cell['colspan']) && ($j+$cell['colspan']) == $numcols) || (!isset($cell['colspan']) && ($j+1) == $numcols)) { // Right
26328 $wadj += $table['padding']['R'] + $table['border_details']['R']['w'] ;
26329 }
26330 $this->SetFColor($color);
26331 $this->Rect($x - $xadj, $y - $yadj, $w + $wadj, $h + $hadj, 'F');
26332 }
26333 }
26334 }
26335 }
26336 /*-- END COLUMNS --*/
26337
26338 if ($table['empty_cells']!='hide' || !empty($cell['textbuffer']) || (isset($cell['nestedcontent']) && $cell['nestedcontent']) || !$table['borders_separate'] ) { $paintcell = true; }
26339 else { $paintcell = false; }
26340
26341 //Set Borders
26342 $bord = 0;
26343 $bord_det = array();
26344
26345 if (!$this->simpleTables){
26346 if ($this->packTableData) {
26347 if ($cell['borderbin']) {
26348 $c = $this->_unpackCellBorder($cell['borderbin']);
26349 $bord = $c['border'];
26350 $bord_det = $c['border_details'];
26351 }
26352 }
26353 else if ($cell['border']) {
26354 $bord = $cell['border'];
26355 $bord_det = $cell['border_details'];
26356 }
26357 }
26358 else if ($this->simpleTables){
26359 if ($table['simple']['border']) {
26360 $bord = $table['simple']['border'];
26361 $bord_det = $table['simple']['border_details'];
26362 }
26363 }
26364
26365 //TABLE ROW OR CELL FILL BGCOLOR
26366 $fill = 0;
26367 if (isset($cell['bgcolor']) && $cell['bgcolor'] && $cell['bgcolor']!='transparent') {
26368 $fill = $cell['bgcolor'];
26369 $leveladj = 6;
26370 }
26371 else if (isset($table['bgcolor'][$i]) && $table['bgcolor'][$i] && $table['bgcolor'][$i]!='transparent') { // Row color
26372 $fill = $table['bgcolor'][$i];
26373 $leveladj = 3;
26374 }
26375 if ($fill && $paintcell) {
26376 $color = $this->ConvertColor($fill);
26377 if ($color) {
26378 if ($table['borders_separate']) {
26379 if ($this->ColActive) {
26380 $this->SetFColor($color);
26381 $this->Rect($x+ ($table['border_spacing_H']/2), $y+ ($table['border_spacing_V']/2), $w- $table['border_spacing_H'], $h- $table['border_spacing_V'], 'F');
26382 }
26383 else {
26384 $this->tableBackgrounds[$level*9+$leveladj][] = array('gradient'=>false, 'x'=>($x + ($table['border_spacing_H']/2)), 'y'=>($y + ($table['border_spacing_V']/2)), 'w'=>($w - $table['border_spacing_H']), 'h'=>($h - $table['border_spacing_V']), 'col'=>$color);
26385 }
26386 }
26387 else {
26388 if ($this->ColActive) {
26389 $this->SetFColor($color);
26390 $this->Rect($x, $y, $w, $h, 'F');
26391 }
26392 else {
26393 $this->tableBackgrounds[$level*9+$leveladj][] = array('gradient'=>false, 'x'=>$x, 'y'=>$y, 'w'=>$w, 'h'=>$h, 'col'=>$color);
26394 }
26395 }
26396 }
26397 }
26398
26399 /*-- BACKGROUNDS --*/
26400 if (isset($cell['gradient']) && $cell['gradient'] && $paintcell){
26401 $g = $this->grad->parseBackgroundGradient($cell['gradient']);
26402 if ($g) {
26403 if ($table['borders_separate']) {
26404 $px = $x+ ($table['border_spacing_H']/2);
26405 $py = $y+ ($table['border_spacing_V']/2);
26406 $pw = $w- $table['border_spacing_H'];
26407 $ph = $h- $table['border_spacing_V'];
26408 }
26409 else {
26410 $px = $x;
26411 $py = $y;
26412 $pw = $w;
26413 $ph = $h;
26414 }
26415 if ($this->ColActive) {
26416 $this->grad->Gradient($px, $py, $pw, $ph, $g['type'], $g['stops'], $g['colorspace'], $g['coords'], $g['extend']);
26417 }
26418 else {
26419 $this->tableBackgrounds[$level*9+7][] = array('gradient'=>true, 'x'=>$px, 'y'=>$py, 'w'=>$pw, 'h'=>$ph, 'gradtype'=>$g['type'], 'stops'=>$g['stops'], 'colorspace'=>$g['colorspace'], 'coords'=>$g['coords'], 'extend'=>$g['extend'], 'clippath'=>'');
26420 }
26421 }
26422 }
26423
26424 if (isset($cell['background-image']) && $paintcell) {
26425 if ($cell['background-image']['gradient'] && preg_match('/(-moz-)*(repeating-)*(linear|radial)-gradient/', $cell['background-image']['gradient'] )) {
26426 $g = $this->grad->parseMozGradient( $cell['background-image']['gradient'] );
26427 if ($g) {
26428 if ($table['borders_separate']) {
26429 $px = $x+ ($table['border_spacing_H']/2);
26430 $py = $y+ ($table['border_spacing_V']/2);
26431 $pw = $w- $table['border_spacing_H'];
26432 $ph = $h- $table['border_spacing_V'];
26433 }
26434 else {
26435 $px = $x;
26436 $py = $y;
26437 $pw = $w;
26438 $ph = $h;
26439 }
26440 if ($this->ColActive) {
26441 $this->grad->Gradient($px, $py, $pw, $ph, $g['type'], $g['stops'], $g['colorspace'], $g['coords'], $g['extend']);
26442 }
26443 else {
26444 $this->tableBackgrounds[$level*9+7][] = array('gradient'=>true, 'x'=>$px, 'y'=>$py, 'w'=>$pw, 'h'=>$ph, 'gradtype'=>$g['type'], 'stops'=>$g['stops'], 'colorspace'=>$g['colorspace'], 'coords'=>$g['coords'], 'extend'=>$g['extend'], 'clippath'=>'');
26445 }
26446 }
26447 }
26448 else if ($cell['background-image']['image_id']) { // Background pattern
26449 $n = count($this->patterns)+1;
26450 if ($table['borders_separate']) {
26451 $px = $x+ ($table['border_spacing_H']/2);
26452 $py = $y+ ($table['border_spacing_V']/2);
26453 $pw = $w- $table['border_spacing_H'];
26454 $ph = $h- $table['border_spacing_V'];
26455 }
26456 else {
26457 $px = $x;
26458 $py = $y;
26459 $pw = $w;
26460 $ph = $h;
26461 }
26462 if ($this->ColActive) {
26463 list($orig_w, $orig_h, $x_repeat, $y_repeat) = $this->_resizeBackgroundImage($cell['background-image']['orig_w'], $cell['background-image']['orig_h'], $pw, $ph, $cell['background-image']['resize'], $cell['background-image']['x_repeat'], $cell['background-image']['y_repeat']);
26464 $this->patterns[$n] = array('x'=>$px, 'y'=>$py, 'w'=>$pw, 'h'=>$ph, 'pgh'=>$this->h, 'image_id'=>$cell['background-image']['image_id'], 'orig_w'=>$orig_w, 'orig_h'=>$orig_h, 'x_pos'=>$cell['background-image']['x_pos'] , 'y_pos'=>$cell['background-image']['y_pos'] , 'x_repeat'=>$x_repeat, 'y_repeat'=>$y_repeat);
26465 if ($cell['background-image']['opacity']>0 && $cell['background-image']['opacity']<1) { $opac = $this->SetAlpha($cell['background-image']['opacity'],'Normal',true); }
26466 else { $opac = ''; }
26467 $this->_out(sprintf('q /Pattern cs /P%d scn %s %.3F %.3F %.3F %.3F re f Q', $n, $opac, $px*_MPDFK, ($this->h-$py)*_MPDFK, $pw*_MPDFK, -$ph*_MPDFK));
26468 }
26469 else {
26470 $image_id = $cell['background-image']['image_id'];
26471 $orig_w = $cell['background-image']['orig_w'];
26472 $orig_h = $cell['background-image']['orig_h'];
26473 $x_pos = $cell['background-image']['x_pos'];
26474 $y_pos = $cell['background-image']['y_pos'];
26475 $x_repeat = $cell['background-image']['x_repeat'];
26476 $y_repeat = $cell['background-image']['y_repeat'];
26477 $resize = $cell['background-image']['resize'];
26478 $opacity = $cell['background-image']['opacity'];
26479 $itype = $cell['background-image']['itype'];
26480 $this->tableBackgrounds[$level*9+8][] = array('x'=>$px, 'y'=>$py, 'w'=>$pw, 'h'=>$ph, 'image_id'=>$image_id, 'orig_w'=>$orig_w, 'orig_h'=>$orig_h, 'x_pos'=>$x_pos, 'y_pos'=>$y_pos, 'x_repeat'=>$x_repeat, 'y_repeat'=>$y_repeat, 'clippath'=>'', 'resize'=>$resize, 'opacity'=>$opacity, 'itype'=>$itype);
26481 }
26482 }
26483 }
26484 /*-- END BACKGROUNDS --*/
26485
26486 if (isset($cell['colspan']) && $cell['colspan']>1) { $ccolsp = $cell['colspan']; }
26487 else { $ccolsp = 1; }
26488 if (isset($cell['rowspan']) && $cell['rowspan']>1) { $crowsp = $cell['rowspan']; }
26489 else { $crowsp = 1; }
26490
26491
26492 // but still need to do this for repeated headers...
26493 if (!$table['borders_separate'] && $this->tabletheadjustfinished && !$this->simpleTables){
26494 if (isset($table['topntail']) && $table['topntail']) {
26495 $bord_det['T'] = $this->border_details($table['topntail']);
26496 $bord_det['T']['w'] /= $this->shrin_k;
26497 $this->setBorder($bord, _BORDER_TOP);
26498 }
26499 if (isset($table['thead-underline']) && $table['thead-underline']) {
26500 $bord_det['T'] = $this->border_details($table['thead-underline']);
26501 $bord_det['T']['w'] /= $this->shrin_k;
26502 $this->setBorder($bord, _BORDER_TOP);
26503 }
26504 }
26505
26506
26507 //Get info of first row ==>> table header
26508 //Use > 1 row if THEAD
26509 if (isset($table['is_thead'][$i]) && $table['is_thead'][$i] && $level==1) {
26510 if ($j==0) $tableheaderrowheight += $table['hr'][$i];
26511 $tableheader[$i][0]['trbackground-images'] = (isset($table['trbackground-images'][$i]) ? $table['trbackground-images'][$i] : null);
26512 $tableheader[$i][0]['trgradients'] = (isset($table['trgradients'][$i]) ? $table['trgradients'][$i] : null);
26513 $tableheader[$i][0]['trbgcolor'] = (isset($table['bgcolor'][$i]) ? $table['bgcolor'][$i] : null);
26514 $tableheader[$i][$j]['x'] = $x;
26515 $tableheader[$i][$j]['y'] = $y;
26516 $tableheader[$i][$j]['h'] = $h;
26517 $tableheader[$i][$j]['w'] = $w;
26518 if (isset($cell['textbuffer'])) { $tableheader[$i][$j]['textbuffer'] = $cell['textbuffer']; }
26519 else { $tableheader[$i][$j]['textbuffer'] = ''; }
26520 $tableheader[$i][$j]['a'] = $cell['a'];
26521 $tableheader[$i][$j]['R'] = $cell['R'];
26522
26523 $tableheader[$i][$j]['va'] = $cell['va'];
26524 $tableheader[$i][$j]['mih'] = $cell['mih'];
26525 $tableheader[$i][$j]['gradient'] = (isset($cell['gradient']) ? $cell['gradient'] : null); // *BACKGROUNDS*
26526 $tableheader[$i][$j]['background-image'] = (isset($cell['background-image']) ? $cell['background-image'] : null); // *BACKGROUNDS*
26527 $tableheader[$i][$j]['rowspan'] = (isset($cell['rowspan']) ? $cell['rowspan'] : null);
26528 $tableheader[$i][$j]['colspan'] = (isset($cell['colspan']) ? $cell['colspan'] : null);
26529 $tableheader[$i][$j]['bgcolor'] = $cell['bgcolor'];
26530
26531 if (!$this->simpleTables){
26532 $tableheader[$i][$j]['border'] = $bord;
26533 $tableheader[$i][$j]['border_details'] = $bord_det;
26534 }
26535 else if ($this->simpleTables){
26536 $tableheader[$i][$j]['border'] = $table['simple']['border'];
26537 $tableheader[$i][$j]['border_details'] = $table['simple']['border_details'];
26538 }
26539 $tableheader[$i][$j]['padding'] = $cell['padding'];
26540 }
26541
26542 // CELL BORDER
26543 if ($bord || $bord_det) {
26544 if ($table['borders_separate'] && $paintcell) {
26545 $this->_tableRect($x + ($table['border_spacing_H']/2)+($bord_det['L']['w'] /2), $y+ ($table['border_spacing_V']/2)+($bord_det['T']['w'] /2), $w-$table['border_spacing_H']-($bord_det['L']['w'] /2)-($bord_det['R']['w'] /2), $h- $table['border_spacing_V']-($bord_det['T']['w'] /2)-($bord_det['B']['w']/2), $bord, $bord_det, false, $table['borders_separate']);
26546 }
26547 else if (!$table['borders_separate']) {
26548 $this->_tableRect($x, $y, $w, $h, $bord, $bord_det, true, $table['borders_separate']); // true causes buffer
26549 }
26550
26551 }
26552
26553 //VERTICAL ALIGN
26554 if ($cell['R'] && INTVAL($cell['R']) > 0 && INTVAL($cell['R']) < 90 && isset($cell['va']) && $cell['va']!='B') { $cell['va']='B';}
26555 if (!isset($cell['va']) || $cell['va']=='M') $this->y += ($h-$cell['mih'])/2;
26556 elseif (isset($cell['va']) && $cell['va']=='B') $this->y += $h-$cell['mih'];
26557
26558 // NESTED CONTENT
26559
26560 // TEXT (and nested tables)
26561 $this->divalign=$align;
26562
26563 $this->divwidth=$w;
26564 if (!empty($cell['textbuffer'])) {
26565 if ($level==1) {
26566 if (isset($table['is_tfoot'][$i]) && $table['is_tfoot'][$i]) {
26567 if (preg_match('/{colsum([0-9]*)[_]*}/', $cell['textbuffer'][0][0], $m)) {
26568 $rep = sprintf("%01.".intval($m[1])."f", $this->colsums[$j]);
26569 $cell['textbuffer'][0][0] = preg_replace('/{colsum[0-9_]*}/', $rep ,$cell['textbuffer'][0][0]);
26570 }
26571 }
26572 else if (!isset($table['is_thead'][$i])) { $this->colsums[$j] += floatval(preg_replace('/^[^0-9\.\,]*/','',$cell['textbuffer'][0][0])); } // mPDF 5.6.66
26573 }
26574 $opy = $this->y;
26575 // mPDF ITERATION
26576 if ($this->iterationCounter) {
26577 foreach($cell['textbuffer'] AS $k=>$t) {
26578 if (preg_match('/{iteration ([a-zA-Z0-9_]+)}/',$t[0], $m)) {
26579 $vname = '__'.$m[1].'_';
26580 if (!isset($this->$vname)) { $this->$vname = 1; }
26581 else { $this->$vname++; }
26582 $cell['textbuffer'][$k][0] = preg_replace('/{iteration '.$m[1].'}/', $this->$vname, $cell['textbuffer'][$k][0]);
26583 }
26584 }
26585 }
26586
26587
26588 if ($cell['R']) {
26589 $cellPtSize = $cell['textbuffer'][0][11] / $this->shrin_k;
26590 if (!$cellPtSize) { $cellPtSize = $this->default_font_size; }
26591 $cellFontHeight = ($cellPtSize/_MPDFK);
26592 $opx = $this->x;
26593 $angle = INTVAL($cell['R']);
26594 // Only allow 45 to 89 degrees (when bottom-aligned) or exactly 90 or -90
26595 if ($angle > 90) { $angle = 90; }
26596 else if ($angle > 0 && $angle <45) { $angle = 45; }
26597 else if ($angle < 0) { $angle = -90; }
26598 $offset = ((sin(deg2rad($angle))) * 0.37 * $cellFontHeight);
26599 if (isset($cell['a']) && $cell['a']=='R') {
26600 $this->x += ($w) + ($offset) - ($cellFontHeight/3) - ($cell['padding']['R'] + ($table['border_spacing_H']/2));
26601 }
26602 else if (!isset($cell['a']) || $cell['a']=='C') {
26603 $this->x += ($w/2) + ($offset);
26604 }
26605 else {
26606 $this->x += ($offset) + ($cellFontHeight/3)+($cell['padding']['L'] +($table['border_spacing_H']/2));
26607 }
26608 $str = '';
26609 foreach($cell['textbuffer'] AS $t) { $str .= $t[0].' '; }
26610 $str = trim($str);
26611 if (!isset($cell['va']) || $cell['va']=='M') {
26612 $this->y -= ($h-$cell['mih'])/2; //Undo what was added earlier VERTICAL ALIGN
26613 if ($angle > 0) { $this->y += (($h-$cell['mih'])/2) + $cell['padding']['T'] + ($cell['mih']-($cell['padding']['T'] + $cell['padding']['B'])); }
26614 else if ($angle < 0) { $this->y += (($h-$cell['mih'])/2)+ ($cell['padding']['T'] + ($table['border_spacing_V']/2)); }
26615 }
26616 elseif (isset($cell['va']) && $cell['va']=='B') {
26617 $this->y -= $h-$cell['mih']; //Undo what was added earlier VERTICAL ALIGN
26618 if ($angle > 0) { $this->y += $h-($cell['padding']['B'] + ($table['border_spacing_V']/2)); }
26619 else if ($angle < 0) { $this->y += $h-$cell['mih'] + ($cell['padding']['T'] + ($table['border_spacing_V']/2)); }
26620 }
26621 elseif (isset($cell['va']) && $cell['va']=='T') {
26622 if ($angle > 0) { $this->y += $cell['mih']-($cell['padding']['B'] + ($table['border_spacing_V']/2)); }
26623 else if ($angle < 0) { $this->y += ($cell['padding']['T'] + ($table['border_spacing_V']/2)); }
26624 }
26625 $this->Rotate($angle,$this->x,$this->y);
26626 $s_fs = $this->FontSizePt;
26627 $s_f = $this->FontFamily;
26628 $s_st = $this->FontStyle;
26629 if (!empty($cell['textbuffer'][0][3])) { //Font Color
26630 $cor = $cell['textbuffer'][0][3];
26631 $this->SetTColor($cor);
26632 }
26633 $s_str = $this->strike;
26634 $this->strike = $cell['textbuffer'][0][8]; //Strikethrough
26635 $this->SetFont($cell['textbuffer'][0][4],$cell['textbuffer'][0][2],$cellPtSize,true,true);
26636 $this->Text($this->x,$this->y,$str);
26637 $this->Rotate(0);
26638 $this->SetFont($s_f,$s_st,$s_fs,true,true);
26639 $this->SetTColor(0);
26640 $this->strike = $s_str;
26641 $this->x = $opx;
26642 }
26643 else {
26644
26645 if (!$this->simpleTables){
26646 if ($bord_det) {
26647 $btlw = $bord_det['L']['w'];
26648 $btrw = $bord_det['R']['w'];
26649 $bttw = $bord_det['T']['w'];
26650 }
26651 else {
26652 $btlw = 0;
26653 $btrw = 0;
26654 $bttw = 0;
26655 }
26656 if ($table['borders_separate']) {
26657 $xadj = $btlw + $cell['padding']['L'] +($table['border_spacing_H']/2);
26658 $wadj = $btlw + $btrw + $cell['padding']['L'] +$cell['padding']['R'] + $table['border_spacing_H'];
26659 $yadj = $bttw + $cell['padding']['T'] + ($table['border_spacing_H']/2);
26660 }
26661 else {
26662 $xadj = $btlw/2 + $cell['padding']['L'];
26663 $wadj = ($btlw + $btrw)/2 + $cell['padding']['L'] + $cell['padding']['R'];
26664 $yadj = $bttw/2 + $cell['padding']['T'];
26665 }
26666 }
26667 else if ($this->simpleTables){
26668 if ($table['borders_separate']) { // NB twice border width
26669 $xadj = $table['simple']['border_details']['L']['w'] + $cell['padding']['L'] +($table['border_spacing_H']/2);
26670 $wadj = $table['simple']['border_details']['L']['w'] + $table['simple']['border_details']['R']['w'] + $cell['padding']['L'] +$cell['padding']['R'] + $table['border_spacing_H'];
26671 $yadj = $table['simple']['border_details']['T']['w'] + $cell['padding']['T'] + ($table['border_spacing_H']/2);
26672 }
26673 else {
26674 $xadj = $table['simple']['border_details']['L']['w']/2 + $cell['padding']['L'];
26675 $wadj = ($table['simple']['border_details']['L']['w'] + $table['simple']['border_details']['R']['w'])/2 + $cell['padding']['L'] + $cell['padding']['R'];
26676 $yadj = $table['simple']['border_details']['T']['w']/2 + $cell['padding']['T'];
26677 }
26678 }
26679 // mPDF 5.6.13
26680 $this->decimal_offset = 0;
26681 if(substr($cell['a'],0,1) == 'D') {
26682 if ($cell['colspan'] > 1) { $this->divalign = $c['a'] = substr($cell['a'],2,1); }
26683 else {
26684 $smax = $table['decimal_align'][$j]['maxs0'];
26685 $d_content = $table['decimal_align'][$j]['maxs0'] + $table['decimal_align'][$j]['maxs1'];
26686 $this->decimal_offset = $smax;
26687 $extra = ($w - $d_content - $wadj);
26688 if ($extra > 0) {
26689 if(substr($cell['a'],2,1) == 'R') { $this->decimal_offset += $extra; }
26690 else if(substr($cell['a'],2,1) == 'C') { $this->decimal_offset += ($extra)/2; }
26691 }
26692 }
26693 }
26694 $this->divwidth=$w-$wadj;
26695 if ($this->divwidth == 0) { $this->divwidth = 0.0001; }
26696 $this->x += $xadj;
26697 $this->y += $yadj;
26698 $this->printbuffer($cell['textbuffer'],'',true);
26699 }
26700 $this->y = $opy;
26701 }
26702
26703 /*-- BACKGROUNDS --*/
26704 if (!$this->ColActive) {
26705 if (isset($table['trgradients'][$i]) && ($j==0 || $table['borders_separate'])) {
26706 $g = $this->grad->parseBackgroundGradient($table['trgradients'][$i]);
26707 if ($g) {
26708 $gx = $x0;
26709 $gy = $y;
26710 $gh = $h;
26711 $gw = $table['w'] - ($table['max_cell_border_width']['L']/2) - ($table['max_cell_border_width']['R']/2) - $table['margin']['L'] - $table['margin']['R'];
26712 if ($table['borders_separate']) {
26713 $gw -= ($table['padding']['L'] + $table['border_details']['L']['w'] + $table['padding']['R'] + $table['border_details']['R']['w'] + $table['border_spacing_H']);
26714 $s = '';
26715 $clx = $x+ ($table['border_spacing_H']/2);
26716 $cly = $y+ ($table['border_spacing_V']/2);
26717 $clw = $w- $table['border_spacing_H'];
26718 $clh = $h- $table['border_spacing_V'];
26719 // Set clipping path
26720 $s = ' q 0 w '; // Line width=0
26721 $s .= sprintf('%.3F %.3F m ', ($clx)*_MPDFK, ($this->h-($cly))*_MPDFK); // start point TL before the arc
26722 $s .= sprintf('%.3F %.3F l ', ($clx)*_MPDFK, ($this->h-($cly+$clh))*_MPDFK); // line to BL
26723 $s .= sprintf('%.3F %.3F l ', ($clx+$clw)*_MPDFK, ($this->h-($cly+$clh))*_MPDFK); // line to BR
26724 $s .= sprintf('%.3F %.3F l ', ($clx+$clw)*_MPDFK, ($this->h-($cly))*_MPDFK); // line to TR
26725 $s .= sprintf('%.3F %.3F l ', ($clx)*_MPDFK, ($this->h-($cly))*_MPDFK); // line to TL
26726 $s .= ' W n '; // Ends path no-op & Sets the clipping path
26727 $this->tableBackgrounds[$level*9+4][] = array('gradient'=>true, 'x'=>$gx + ($table['border_spacing_H']/2), 'y'=>$gy + ($table['border_spacing_V']/2), 'w'=>$gw - $table['border_spacing_V'], 'h'=>$gh - $table['border_spacing_H'], 'gradtype'=>$g['type'], 'stops'=>$g['stops'], 'colorspace'=>$g['colorspace'], 'coords'=>$g['coords'], 'extend'=>$g['extend'], 'clippath'=>$s);
26728 }
26729 else {
26730 $this->tableBackgrounds[$level*9+4][] = array('gradient'=>true, 'x'=>$gx, 'y'=>$gy, 'w'=>$gw, 'h'=>$gh, 'gradtype'=>$g['type'], 'stops'=>$g['stops'], 'colorspace'=>$g['colorspace'], 'coords'=>$g['coords'], 'extend'=>$g['extend'], 'clippath'=>'');
26731 }
26732 }
26733 }
26734 if (isset($table['trbackground-images'][$i]) && ($j==0 || $table['borders_separate'])) {
26735 if ($table['trbackground-images'][$i]['gradient'] && preg_match('/(-moz-)*(repeating-)*(linear|radial)-gradient/', $table['trbackground-images'][$i]['gradient'] )) {
26736 $g = $this->grad->parseMozGradient( $table['trbackground-images'][$i]['gradient'] );
26737 if ($g) {
26738 $gx = $x0;
26739 $gy = $y;
26740 $gh = $h;
26741 $gw = $table['w'] - ($table['max_cell_border_width']['L']/2) - ($table['max_cell_border_width']['R']/2) - $table['margin']['L'] - $table['margin']['R'];
26742 if ($table['borders_separate']) {
26743 $gw -= ($table['padding']['L'] + $table['border_details']['L']['w'] + $table['padding']['R'] + $table['border_details']['R']['w'] + $table['border_spacing_H']);
26744 $s = '';
26745 $clx = $x+ ($table['border_spacing_H']/2);
26746 $cly = $y+ ($table['border_spacing_V']/2);
26747 $clw = $w- $table['border_spacing_H'];
26748 $clh = $h- $table['border_spacing_V'];
26749 // Set clipping path
26750 $s = ' q 0 w '; // Line width=0
26751 $s .= sprintf('%.3F %.3F m ', ($clx)*_MPDFK, ($this->h-($cly))*_MPDFK); // start point TL before the arc
26752 $s .= sprintf('%.3F %.3F l ', ($clx)*_MPDFK, ($this->h-($cly+$clh))*_MPDFK); // line to BL
26753 $s .= sprintf('%.3F %.3F l ', ($clx+$clw)*_MPDFK, ($this->h-($cly+$clh))*_MPDFK); // line to BR
26754 $s .= sprintf('%.3F %.3F l ', ($clx+$clw)*_MPDFK, ($this->h-($cly))*_MPDFK); // line to TR
26755 $s .= sprintf('%.3F %.3F l ', ($clx)*_MPDFK, ($this->h-($cly))*_MPDFK); // line to TL
26756 $s .= ' W n '; // Ends path no-op & Sets the clipping path
26757 $this->tableBackgrounds[$level*9+4][] = array('gradient'=>true, 'x'=>$gx + ($table['border_spacing_H']/2), 'y'=>$gy + ($table['border_spacing_V']/2), 'w'=>$gw - $table['border_spacing_V'], 'h'=>$gh - $table['border_spacing_H'], 'gradtype'=>$g['type'], 'stops'=>$g['stops'], 'colorspace'=>$g['colorspace'], 'coords'=>$g['coords'], 'extend'=>$g['extend'], 'clippath'=>$s);
26758 }
26759 else {
26760 $this->tableBackgrounds[$level*9+4][] = array('gradient'=>true, 'x'=>$gx, 'y'=>$gy, 'w'=>$gw, 'h'=>$gh, 'gradtype'=>$g['type'], 'stops'=>$g['stops'], 'colorspace'=>$g['colorspace'], 'coords'=>$g['coords'], 'extend'=>$g['extend'], 'clippath'=>'');
26761 }
26762 }
26763 }
26764 else {
26765 $image_id = $table['trbackground-images'][$i]['image_id'];
26766 $orig_w = $table['trbackground-images'][$i]['orig_w'];
26767 $orig_h = $table['trbackground-images'][$i]['orig_h'];
26768 $x_pos = $table['trbackground-images'][$i]['x_pos'];
26769 $y_pos = $table['trbackground-images'][$i]['y_pos'];
26770 $x_repeat = $table['trbackground-images'][$i]['x_repeat'];
26771 $y_repeat = $table['trbackground-images'][$i]['y_repeat'];
26772 $resize = $table['trbackground-images'][$i]['resize'];
26773 $opacity = $table['trbackground-images'][$i]['opacity'];
26774 $itype = $table['trbackground-images'][$i]['itype'];
26775 $clippath = '';
26776 $gx = $x0;
26777 $gy = $y;
26778 $gh = $h;
26779 $gw = $table['w'] - ($table['max_cell_border_width']['L']/2) - ($table['max_cell_border_width']['R']/2) - $table['margin']['L'] - $table['margin']['R'];
26780 if ($table['borders_separate']) {
26781 $gw -= ($table['padding']['L'] + $table['border_details']['L']['w'] + $table['padding']['R'] + $table['border_details']['R']['w'] + $table['border_spacing_H']);
26782 $s = '';
26783 $clx = $x + ($table['border_spacing_H']/2);
26784 $cly = $y + ($table['border_spacing_V']/2);
26785 $clw = $w - $table['border_spacing_H'];
26786 $clh = $h - $table['border_spacing_V'];
26787 // Set clipping path
26788 $s = ' q 0 w '; // Line width=0
26789 $s .= sprintf('%.3F %.3F m ', ($clx)*_MPDFK, ($this->h-($cly))*_MPDFK); // start point TL
26790 $s .= sprintf('%.3F %.3F l ', ($clx)*_MPDFK, ($this->h-($cly+$clh))*_MPDFK); // line to BL
26791 $s .= sprintf('%.3F %.3F l ', ($clx+$clw)*_MPDFK, ($this->h-($cly+$clh))*_MPDFK); // line to BR
26792 $s .= sprintf('%.3F %.3F l ', ($clx+$clw)*_MPDFK, ($this->h-($cly))*_MPDFK); // line to TR
26793 $s .= sprintf('%.3F %.3F l ', ($clx)*_MPDFK, ($this->h-($cly))*_MPDFK); // line to TL
26794 $s .= ' W n '; // Ends path no-op & Sets the clipping path
26795 $this->tableBackgrounds[$level*9+5][] = array('x'=>$gx + ($table['border_spacing_H']/2), 'y'=>$gy + ($table['border_spacing_V']/2), 'w'=>$gw - $table['border_spacing_V'], 'h'=>$gh - $table['border_spacing_H'], 'image_id'=>$image_id, 'orig_w'=>$orig_w, 'orig_h'=>$orig_h, 'x_pos'=>$x_pos, 'y_pos'=>$y_pos, 'x_repeat'=>$x_repeat, 'y_repeat'=>$y_repeat, 'clippath'=>$s, 'resize'=>$resize, 'opacity'=>$opacity, 'itype'=>$itype);
26796 }
26797 else {
26798 $this->tableBackgrounds[$level*9+5][] = array('x'=>$gx, 'y'=>$gy, 'w'=>$gw, 'h'=>$gh, 'image_id'=>$image_id, 'orig_w'=>$orig_w, 'orig_h'=>$orig_h, 'x_pos'=>$x_pos, 'y_pos'=>$y_pos, 'x_repeat'=>$x_repeat, 'y_repeat'=>$y_repeat, 'clippath'=>'', 'resize'=>$resize, 'opacity'=>$opacity, 'itype'=>$itype);
26799 }
26800 }
26801 }
26802 }
26803
26804 /*-- END BACKGROUNDS --*/
26805
26806 // TABLE BORDER - if separate
26807 if (($table['borders_separate'] || ($this->simpleTables && !$table['simple']['border'])) && $table['border']) {
26808 $halfspaceL = $table['padding']['L'] + ($table['border_spacing_H']/2);
26809 $halfspaceR = $table['padding']['R'] + ($table['border_spacing_H']/2);
26810 $halfspaceT = $table['padding']['T'] + ($table['border_spacing_V']/2);
26811 $halfspaceB = $table['padding']['B'] + ($table['border_spacing_V']/2);
26812 $tbx = $x;
26813 $tby = $y;
26814 $tbw = $w;
26815 $tbh = $h;
26816 $tab_bord = 0;
26817
26818 $corner = '';
26819 if ($i == 0) { // Top
26820 $tby -= $halfspaceT + ($table['border_details']['T']['w']/2);
26821 $tbh += $halfspaceT + ($table['border_details']['T']['w']/2);
26822 $this->setBorder($tab_bord , _BORDER_TOP);
26823 $corner .= 'T';
26824 }
26825 if ($i == ($numrows-1) || (isset($cell['rowspan']) && ($i+$cell['rowspan']) == $numrows)) { // Bottom
26826 $tbh += $halfspaceB + ($table['border_details']['B']['w']/2);
26827 $this->setBorder($tab_bord , _BORDER_BOTTOM);
26828 $corner .= 'B';
26829 }
26830 if ($j == 0) { // Left
26831 $tbx -= $halfspaceL + ($table['border_details']['L']['w']/2);
26832 $tbw += $halfspaceL + ($table['border_details']['L']['w']/2);
26833 $this->setBorder($tab_bord , _BORDER_LEFT);
26834 $corner .= 'L';
26835 }
26836 if ($j == ($numcols-1) || (isset($cell['colspan']) && ($j+$cell['colspan']) == $numcols)) { // Right
26837 $tbw += $halfspaceR + ($table['border_details']['R']['w']/2);
26838 $this->setBorder($tab_bord , _BORDER_RIGHT);
26839 $corner .= 'R';
26840 }
26841 $this->_tableRect($tbx, $tby, $tbw, $tbh, $tab_bord , $table['border_details'], false, $table['borders_separate'], 'table', $corner, $table['border_spacing_V'], $table['border_spacing_H'] );
26842 }
26843
26844 unset($cell );
26845 //Reset values
26846 $this->Reset();
26847
26848 }//end of (if isset(cells)...)
26849 }// end of columns
26850
26851 $newpagestarted = false;
26852 $this->tabletheadjustfinished = false;
26853
26854 if ($this->ColActive && $i < $numrows-1 && $level==1) { $this->breakpoints[$this->CurrCol][] = $y + $h; } // *COLUMNS*
26855
26856 /*-- COLUMNS --*/
26857 if ($this->ColActive) {
26858 if (count($this->cellBorderBuffer)) { $this->printcellbuffer(); }
26859 }
26860 /*-- END COLUMNS --*/
26861
26862 if ($i == $numrows-1) { $this->y = $y + $h; } //last row jump (update this->y position)
26863 if ($this->table_rotate && $level==1) {
26864 $this->tbrot_h += $h;
26865 }
26866
26867
26868
26869 }// end of rows
26870
26871 if ($this->progressBar) { $this->UpdateProgressBar(7,70,' '); } // *PROGRESS-BAR*
26872
26873 if (count($this->cellBorderBuffer)) { $this->printcellbuffer(); }
26874
26875
26876 if ($this->tableClipPath ) { $this->_out("Q"); }
26877 $this->tableClipPath = '';
26878
26879 // Advance down page by half width of bottom border
26880 if ($table['borders_separate']) { $this->y += $table['padding']['B'] + $table['border_details']['B']['w'] + $table['border_spacing_V']/2; }
26881 else { $this->y += $table['max_cell_border_width']['B']/2; }
26882
26883 if ($table['borders_separate'] && $level==1) { $this->tbrot_h += $table['margin']['B'] + $table['padding']['B'] + $table['border_details']['B']['w'] + $table['border_spacing_V']/2; }
26884 else if ($level==1) { $this->tbrot_h += $table['margin']['B'] + $table['max_cell_border_width']['B']/2; }
26885
26886 $bx = $x0;
26887 $by = $y0;
26888 if ($table['borders_separate']) {
26889 $bx -= ($table['padding']['L'] + $table['border_details']['L']['w'] + $table['border_spacing_H']/2);
26890 if ($tablestartpageno != $this->page) { // IF broken across page
26891 $by += $table['max_cell_border_width']['T']/2;
26892 if (empty($tableheader)) { $by -= ($table['border_spacing_V']/2); }
26893 }
26894 else if ($split && $startrow > 0 && empty($tableheader)) {
26895 $by -= ($table['border_spacing_V']/2);
26896 }
26897 else {
26898 $by -= ($table['padding']['T'] + $table['border_details']['T']['w'] + $table['border_spacing_V']/2);
26899 }
26900 }
26901 else if ($tablestartpageno != $this->page && !empty($tableheader)) { $by += $maxbwtop /2; }
26902 $by -= $tableheaderadj;
26903 $bh = $this->y - $by;
26904 if (!$table['borders_separate']) { $bh -= $table['max_cell_border_width']['B']/2; }
26905
26906 if ($split) {
26907 $bw = 0;
26908 $finalSpread = true;
26909 for($t=$startcol; $t<$numcols; $t++) {
26910 if ($table['colPg'][$t] == $splitpg) { $bw += $table['wc'][$t]; }
26911 if ($table['colPg'][$t] > $splitpg) { $finalSpread = false; break; }
26912 }
26913 if ($startcol==0) { $firstSpread = true; }
26914 else { $firstSpread = false; }
26915 if ($table['borders_separate']) {
26916 $bw += $table['border_spacing_H'];
26917 if ($firstSpread) {
26918 $bw += $table['padding']['L'] + $table['border_details']['L']['w'];
26919 }
26920 else {
26921 $bx += ($table['padding']['L'] + $table['border_details']['L']['w']);
26922 }
26923 if ($finalSpread) {
26924 $bw += $table['padding']['R'] + $table['border_details']['R']['w'];
26925 }
26926 }
26927 }
26928 else {
26929 $bw = $table['w'] - ($table['max_cell_border_width']['L']/2) - ($table['max_cell_border_width']['R']/2) - $table['margin']['L'] - $table['margin']['R'];
26930 }
26931
26932 if (!$this->ColActive) {
26933 if (isset($table['bgcolor'][-1])) {
26934 $color = $this->ConvertColor($table['bgcolor'][-1]);
26935 if ($color) {
26936 $this->tableBackgrounds[$level*9][] = array('gradient'=>false, 'x'=>$bx, 'y'=>$by, 'w'=>$bw, 'h'=>$bh, 'col'=>$color);
26937 }
26938 }
26939
26940 /*-- BACKGROUNDS --*/
26941 if (isset($table['gradient'])) {
26942 $g = $this->grad->parseBackgroundGradient($table['gradient']);
26943 if ($g) {
26944 $this->tableBackgrounds[$level*9+1][] = array('gradient'=>true, 'x'=>$bx, 'y'=>$by, 'w'=>$bw, 'h'=>$bh, 'gradtype'=>$g['type'], 'stops'=>$g['stops'], 'colorspace'=>$g['colorspace'], 'coords'=>$g['coords'], 'extend'=>$g['extend'], 'clippath'=>'');
26945 }
26946 }
26947
26948 if (isset($table['background-image'])) {
26949 if ($table['background-image']['gradient'] && preg_match('/(-moz-)*(repeating-)*(linear|radial)-gradient/', $table['background-image']['gradient'] )) {
26950 $g = $this->grad->parseMozGradient( $table['background-image']['gradient'] );
26951 if ($g) {
26952 $this->tableBackgrounds[$level*9+1][] = array('gradient'=>true, 'x'=>$bx, 'y'=>$by, 'w'=>$bw, 'h'=>$bh, 'gradtype'=>$g['type'], 'stops'=>$g['stops'], 'colorspace'=>$g['colorspace'], 'coords'=>$g['coords'], 'extend'=>$g['extend'], 'clippath'=>'');
26953 }
26954 }
26955 else {
26956 $image_id = $table['background-image']['image_id'];
26957 $orig_w = $table['background-image']['orig_w'];
26958 $orig_h = $table['background-image']['orig_h'];
26959 $x_pos = $table['background-image']['x_pos'];
26960 $y_pos = $table['background-image']['y_pos'];
26961 $x_repeat = $table['background-image']['x_repeat'];
26962 $y_repeat = $table['background-image']['y_repeat'];
26963 $resize = $table['background-image']['resize'];
26964 $opacity = $table['background-image']['opacity'];
26965 $itype = $table['background-image']['itype'];
26966 $this->tableBackgrounds[$level*9+2][] = array('x'=>$bx, 'y'=>$by, 'w'=>$bw, 'h'=>$bh, 'image_id'=>$image_id, 'orig_w'=>$orig_w, 'orig_h'=>$orig_h, 'x_pos'=>$x_pos, 'y_pos'=>$y_pos, 'x_repeat'=>$x_repeat, 'y_repeat'=>$y_repeat, 'clippath'=>'', 'resize'=>$resize, 'opacity'=>$opacity, 'itype'=>$itype);
26967 }
26968 }
26969 /*-- END BACKGROUNDS --*/
26970 }
26971
26972 if ($this->tableBackgrounds && $level == 1) {
26973 $s = $this->PrintTableBackgrounds();
26974 if ($this->table_rotate && !$this->processingHeader && !$this->processingFooter) {
26975 $this->tablebuffer = preg_replace('/(___TABLE___BACKGROUNDS'.date('jY').')/', '\\1'."\n".$s."\n", $this->tablebuffer);
26976 if ($level == 1) { $this->tablebuffer = preg_replace('/(___TABLE___BACKGROUNDS'.date('jY').')/', " ", $this->tablebuffer); }
26977 }
26978 else if ($this->bufferoutput) {
26979 $this->headerbuffer = preg_replace('/(___TABLE___BACKGROUNDS'.date('jY').')/', '\\1'."\n".$s."\n", $this->headerbuffer);
26980 if ($level == 1) { $this->headerbuffer = preg_replace('/(___TABLE___BACKGROUNDS'.date('jY').')/', " ", $this->headerbuffer ); }
26981 }
26982 else {
26983 $this->pages[$this->page] = preg_replace('/(___TABLE___BACKGROUNDS'.date('jY').')/', '\\1'."\n".$s."\n", $this->pages[$this->page]);
26984 if ($level == 1) { $this->pages[$this->page] = preg_replace('/(___TABLE___BACKGROUNDS'.date('jY').')/', " ", $this->pages[$this->page]); }
26985 }
26986 $this->tableBackgrounds = array();
26987 }
26988
26989
26990 // TABLE BOTTOM MARGIN
26991 if ($table['margin']['B']) {
26992 if (!$this->table_rotate && $level==1) {
26993 $this->DivLn($table['margin']['B'],$this->blklvl,true); // collapsible
26994 }
26995 else {
26996 $this->y += ($table['margin']['B']);
26997 }
26998 }
26999
27000 if ($this->ColActive && $level==1) { $this->breakpoints[$this->CurrCol][] = $this->y; } // *COLUMNS*
27001
27002 if ($this->cacheTables) { fclose($fh); }
27003
27004 if ($split) {
27005 // Are there more columns to print on a next page?
27006 if ($lastCol < $numcols-1) {
27007 $splitpg++;
27008 $startcol = $lastCol + 1;
27009 return array(false, $startrow, $startcol, $splitpg, $returny, $y0);
27010 }
27011 else {
27012 if ($this->cacheTables) {
27013 unlink($table['cache']);
27014 @unlink($table['cache'].'.bak');
27015 }
27016 return array(true,0,0,0);
27017 }
27018 }
27019 if ($this->cacheTables) {
27020 unlink($table['cache']);
27021 @unlink($table['cache'].'.bak');
27022 }
27023
27024 }//END OF FUNCTION _tableWrite()
27025
27026
27027 /////////////////////////END OF TABLE CODE//////////////////////////////////
27028 /*-- END TABLES --*/
27029
27030 function _putextgstates() {
27031 for ($i = 1; $i <= count($this->extgstates); $i++) {
27032 $this->_newobj();
27033 $this->extgstates[$i]['n'] = $this->n;
27034 $this->_out('<</Type /ExtGState');
27035 foreach ($this->extgstates[$i]['parms'] as $k=>$v)
27036 $this->_out('/'.$k.' '.$v);
27037 $this->_out('>>');
27038 $this->_out('endobj');
27039 }
27040 }
27041
27042 function _putocg() {
27043 if ($this->hasOC) { // mPDF 5.6.01
27044 $this->_newobj();
27045 $this->n_ocg_print=$this->n;
27046 $this->_out('<</Type /OCG /Name '.$this->_textstring('Print only'));
27047 $this->_out('/Usage <</Print <</PrintState /ON>> /View <</ViewState /OFF>>>>>>');
27048 $this->_out('endobj');
27049 $this->_newobj();
27050 $this->n_ocg_view=$this->n;
27051 $this->_out('<</Type /OCG /Name '.$this->_textstring('Screen only'));
27052 $this->_out('/Usage <</Print <</PrintState /OFF>> /View <</ViewState /ON>>>>>>');
27053 $this->_out('endobj');
27054 $this->_newobj();
27055 $this->n_ocg_hidden=$this->n;
27056 $this->_out('<</Type /OCG /Name '.$this->_textstring('Hidden'));
27057 $this->_out('/Usage <</Print <</PrintState /OFF>> /View <</ViewState /OFF>>>>>>');
27058 $this->_out('endobj');
27059 }
27060 // mPDF 5.6.01 Add Layers
27061 if (count($this->layers)) {
27062 ksort($this->layers);
27063 foreach($this->layers as $id=>$layer) {
27064 $this->_newobj();
27065 $this->layers[$id]['n'] = $this->n;
27066 // mPDF 5.6.28
27067 if (isset($this->layerDetails[$id]['name']) && $this->layerDetails[$id]['name']) {
27068 $name = $this->layerDetails[$id]['name'];
27069 }
27070 else { $name = $layer['name']; }
27071 $this->_out('<</Type /OCG /Name '.$this->_UTF16BEtextstring($name).'>>');
27072 $this->_out('endobj');
27073 }
27074 }
27075 }
27076
27077
27078 /*-- IMPORTS --*/
27079
27080 // from mPDFI
27081 function _putimportedobjects() {
27082 if (is_array($this->parsers) && count($this->parsers) > 0) {
27083 foreach($this->parsers AS $filename => $p) {
27084 $this->current_parser =& $this->parsers[$filename];
27085 if (is_array($this->_obj_stack[$filename])) {
27086 while($n = key($this->_obj_stack[$filename])) {
27087 $nObj = $this->current_parser->pdf_resolve_object($this->current_parser->c,$this->_obj_stack[$filename][$n][1]);
27088 $this->_newobj($this->_obj_stack[$filename][$n][0]);
27089 if ($nObj[0] == PDF_TYPE_STREAM) {
27090 $this->pdf_write_value($nObj);
27091 }
27092 else {
27093 $this->pdf_write_value($nObj[1]);
27094 }
27095 $this->_out('endobj');
27096 $this->_obj_stack[$filename][$n] = null; // free memory
27097 unset($this->_obj_stack[$filename][$n]);
27098 reset($this->_obj_stack[$filename]);
27099 }
27100 }
27101 }
27102 }
27103 }
27104
27105
27106 function _putformxobjects() {
27107 $filter=($this->compress) ? '/Filter /FlateDecode ' : '';
27108 reset($this->tpls);
27109 foreach($this->tpls AS $tplidx => $tpl) {
27110 $p=($this->compress) ? gzcompress($tpl['buffer']) : $tpl['buffer'];
27111 $this->_newobj();
27112 $this->tpls[$tplidx]['n'] = $this->n;
27113 $this->_out('<<'.$filter.'/Type /XObject');
27114 $this->_out('/Subtype /Form');
27115 $this->_out('/FormType 1');
27116 // Left/Bottom/Right/Top
27117 $this->_out(sprintf('/BBox [%.2F %.2F %.2F %.2F]',
27118 $tpl['box']['x']*_MPDFK,
27119 $tpl['box']['y']*_MPDFK,
27120 ($tpl['box']['x'] + $tpl['box']['w'])*_MPDFK,
27121 ($tpl['box']['y'] + $tpl['box']['h'])*_MPDFK )
27122 );
27123
27124
27125 if (isset($tpl['box']))
27126 $this->_out(sprintf('/Matrix [1 0 0 1 %.5F %.5F]',-$tpl['box']['x']*_MPDFK, -$tpl['box']['y']*_MPDFK));
27127 $this->_out('/Resources ');
27128
27129 if (isset($tpl['resources'])) {
27130 $this->current_parser =& $tpl['parser'];
27131 $this->pdf_write_value($tpl['resources']);
27132 } else {
27133 $this->_out('<</ProcSet [/PDF /Text /ImageB /ImageC /ImageI]');
27134 if (isset($this->_res['tpl'][$tplidx]['fonts']) && count($this->_res['tpl'][$tplidx]['fonts'])) {
27135 $this->_out('/Font <<');
27136 foreach($this->_res['tpl'][$tplidx]['fonts'] as $font)
27137 $this->_out('/F'.$font['i'].' '.$font['n'].' 0 R');
27138 $this->_out('>>');
27139 }
27140 if(isset($this->_res['tpl'][$tplidx]['images']) && count($this->_res['tpl'][$tplidx]['images']) ||
27141 isset($this->_res['tpl'][$tplidx]['tpls']) && count($this->_res['tpl'][$tplidx]['tpls']))
27142 {
27143 $this->_out('/XObject <<');
27144 if (isset($this->_res['tpl'][$tplidx]['images']) && count($this->_res['tpl'][$tplidx]['images'])) {
27145 foreach($this->_res['tpl'][$tplidx]['images'] as $image)
27146 $this->_out('/I'.$image['i'].' '.$image['n'].' 0 R');
27147 }
27148 if (isset($this->_res['tpl'][$tplidx]['tpls']) && count($this->_res['tpl'][$tplidx]['tpls'])) {
27149 foreach($this->_res['tpl'][$tplidx]['tpls'] as $i => $itpl)
27150 $this->_out($this->tplprefix.$i.' '.$itpl['n'].' 0 R');
27151 }
27152 $this->_out('>>');
27153 }
27154 $this->_out('>>');
27155 }
27156
27157 $this->_out('/Length '.strlen($p).' >>');
27158 $this->_putstream($p);
27159 $this->_out('endobj');
27160 }
27161 }
27162
27163 /*-- END IMPORTS --*/
27164
27165
27166 function _putpatterns() {
27167 for ($i = 1; $i <= count($this->patterns); $i++) {
27168 $x = $this->patterns[$i]['x'];
27169 $y = $this->patterns[$i]['y'];
27170 $w = $this->patterns[$i]['w'];
27171 $h = $this->patterns[$i]['h'];
27172 $pgh = $this->patterns[$i]['pgh'];
27173 $orig_w = $this->patterns[$i]['orig_w'];
27174 $orig_h = $this->patterns[$i]['orig_h'];
27175 $image_id = $this->patterns[$i]['image_id'];
27176 $itype = $this->patterns[$i]['itype'];
27177 $bpa = $this->patterns[$i]['bpa']; // mPDF 5.6.10 background positioning area
27178
27179 if ($this->patterns[$i]['x_repeat']) { $x_repeat = true; }
27180 else { $x_repeat = false; }
27181 if ($this->patterns[$i]['y_repeat']) { $y_repeat = true; }
27182 else { $y_repeat = false; }
27183 $x_pos = $this->patterns[$i]['x_pos'];
27184 if (stristr($x_pos ,'%') ) {
27185 $x_pos += 0;
27186 $x_pos /= 100;
27187 if (isset($bpa['w']) && $bpa['w']) $x_pos = ($bpa['w'] * $x_pos) - ($orig_w/_MPDFK * $x_pos); // mPDF 5.6.10
27188 else $x_pos = ($w * $x_pos) - ($orig_w/_MPDFK * $x_pos);
27189 }
27190 $y_pos = $this->patterns[$i]['y_pos'];
27191 if (stristr($y_pos ,'%') ) {
27192 $y_pos += 0;
27193 $y_pos /= 100;
27194 if (isset($bpa['h']) && $bpa['h']) $y_pos = ($bpa['h'] * $y_pos) - ($orig_h/_MPDFK * $y_pos); // mPDF 5.6.10
27195 else $y_pos = ($h * $y_pos) - ($orig_h/_MPDFK * $y_pos);
27196 }
27197 if (isset($bpa['x']) && $bpa['x']) $adj_x = ($x_pos + $bpa['x']) *_MPDFK; // mPDF 5.6.10
27198 else $adj_x = ($x_pos + $x) *_MPDFK;
27199 if (isset($bpa['y']) && $bpa['y']) $adj_y = (($pgh - $y_pos - $bpa['y'])*_MPDFK) - $orig_h ; // mPDF 5.6.10
27200 else $adj_y = (($pgh - $y_pos - $y)*_MPDFK) - $orig_h ;
27201 $img_obj = false;
27202 if ($itype == 'svg' || $itype == 'wmf') {
27203 foreach($this->formobjects AS $fo) {
27204 if ($fo['i'] == $image_id) {
27205 $img_obj = $fo['n'];
27206 $fo_w = $fo['w'];
27207 $fo_h = -$fo['h'];
27208 $wmf_x = $fo['x'];
27209 $wmf_y = $fo['y'];
27210 break;
27211 }
27212 }
27213 }
27214 else {
27215 foreach($this->images AS $img) {
27216 if ($img['i'] == $image_id) { $img_obj = $img['n']; break; }
27217 }
27218 }
27219 if (!$img_obj ) { echo "Problem: Image object not found for background pattern ".$img['i']; exit; }
27220
27221 $this->_newobj();
27222 $this->_out('<</ProcSet [/PDF /Text /ImageB /ImageC /ImageI]');
27223 if ($itype == 'svg' || $itype == 'wmf') {
27224 $this->_out('/XObject <</FO'.$image_id.' '.$img_obj.' 0 R >>');
27225 // ******* ADD ANY ExtGStates, Shading AND Fonts needed for the FormObject
27226 // Set in classes/svg array['fo'] = true
27227 // Required that _putshaders comes before _putpatterns in _putresources
27228 // This adds any resources associated with any FormObject to every Formobject - overkill but works!
27229 if (count($this->extgstates)) {
27230 $this->_out('/ExtGState <<');
27231 foreach($this->extgstates as $k=>$extgstate)
27232 if (isset($extgstate['fo']) && $extgstate['fo']) {
27233 if (isset($extgstate['trans'])) $this->_out('/'.$extgstate['trans'].' '.$extgstate['n'].' 0 R');
27234 else $this->_out('/GS'.$k.' '.$extgstate['n'].' 0 R');
27235 }
27236 $this->_out('>>');
27237 }
27238 /*-- BACKGROUNDS --*/
27239 if (isset($this->gradients) AND (count($this->gradients) > 0)) {
27240 $this->_out('/Shading <<');
27241 foreach ($this->gradients as $id => $grad) {
27242 if (isset($grad['fo']) && $grad['fo']) {
27243 $this->_out('/Sh'.$id.' '.$grad['id'].' 0 R');
27244 }
27245 }
27246 $this->_out('>>');
27247 }
27248 /*-- END BACKGROUNDS --*/
27249 $this->_out('/Font <<');
27250 foreach($this->fonts as $font) {
27251 if (!$font['used'] && $font['type']=='TTF') { continue; }
27252 if (isset($font['fo']) && $font['fo']) {
27253 if ($font['type']=='TTF' && ($font['sip'] || $font['smp'])) {
27254 foreach($font['n'] AS $k => $fid) {
27255 $this->_out('/F'.$font['subsetfontids'][$k].' '.$font['n'][$k].' 0 R');
27256 }
27257 }
27258 else {
27259 $this->_out('/F'.$font['i'].' '.$font['n'].' 0 R');
27260 }
27261 }
27262 }
27263 $this->_out('>>');
27264 }
27265 else {
27266 $this->_out('/XObject <</I'.$image_id.' '.$img_obj.' 0 R >>');
27267 }
27268 $this->_out('>>');
27269 $this->_out('endobj');
27270
27271 $this->_newobj();
27272 $this->patterns[$i]['n'] = $this->n;
27273 $this->_out('<< /Type /Pattern /PatternType 1 /PaintType 1 /TilingType 2');
27274 $this->_out('/Resources '. ($this->n-1) .' 0 R');
27275
27276 $this->_out(sprintf('/BBox [0 0 %.3F %.3F]',$orig_w,$orig_h));
27277 if ($x_repeat) { $this->_out(sprintf('/XStep %.3F',$orig_w)); }
27278 else { $this->_out(sprintf('/XStep %d',99999)); }
27279 if ($y_repeat) { $this->_out(sprintf('/YStep %.3F',$orig_h)); }
27280 else { $this->_out(sprintf('/YStep %d',99999)); }
27281
27282 if ($itype == 'svg' || $itype == 'wmf') {
27283 $this->_out(sprintf('/Matrix [1 0 0 -1 %.3F %.3F]', $adj_x, ($adj_y+$orig_h)));
27284 $s = sprintf("q %.3F 0 0 %.3F %.3F %.3F cm /FO%d Do Q",($orig_w/$fo_w), (-$orig_h/$fo_h), -($orig_w/$fo_w)*$wmf_x, ($orig_w/$fo_w)*$wmf_y, $image_id);
27285 }
27286 else {
27287 $this->_out(sprintf('/Matrix [1 0 0 1 %.3F %.3F]',$adj_x,$adj_y));
27288 $s = sprintf("q %.3F 0 0 %.3F 0 0 cm /I%d Do Q",$orig_w,$orig_h,$image_id);
27289 }
27290
27291 if ($this->compress) {
27292 $this->_out('/Filter /FlateDecode');
27293 $s = gzcompress($s);
27294 }
27295 $this->_out('/Length '.strlen($s).'>>');
27296 $this->_putstream($s);
27297 $this->_out('endobj');
27298 }
27299 }
27300
27301 /*-- BACKGROUNDS --*/
27302 function _putshaders() {
27303 $maxid = count($this->gradients); //index for transparency gradients
27304 foreach ($this->gradients as $id => $grad) {
27305 if (($grad['type'] == 2 || $grad['type'] == 3) && empty($grad['is_mask'])) {
27306 $this->_newobj();
27307 $this->_out('<<');
27308 $this->_out('/FunctionType 3');
27309 $this->_out('/Domain [0 1]');
27310 $fn = array();
27311 $bd = array();
27312 $en = array();
27313 for($i=0; $i<(count($grad['stops'])-1); $i++) {
27314 $fn[] = ($this->n+1+$i).' 0 R';
27315 $en[] = '0 1';
27316 if ($i>0) { $bd[] = sprintf('%.3F', $grad['stops'][$i]['offset']); }
27317 }
27318 $this->_out('/Functions ['.implode(' ',$fn).']');
27319 $this->_out('/Bounds ['.implode(' ',$bd).']');
27320 $this->_out('/Encode ['.implode(' ',$en).']');
27321 $this->_out('>>');
27322 $this->_out('endobj');
27323 $f1 = $this->n;
27324 for($i=0; $i<(count($grad['stops'])-1); $i++) {
27325 $this->_newobj();
27326 $this->_out('<<');
27327 $this->_out('/FunctionType 2');
27328 $this->_out('/Domain [0 1]');
27329 $this->_out('/C0 ['.$grad['stops'][$i]['col'].']');
27330 $this->_out('/C1 ['.$grad['stops'][$i+1]['col'].']');
27331 $this->_out('/N 1');
27332 $this->_out('>>');
27333 $this->_out('endobj');
27334 }
27335 }
27336 if ($grad['type'] == 2 || $grad['type'] == 3) {
27337 if (isset($grad['trans']) && $grad['trans']) {
27338 $this->_newobj();
27339 $this->_out('<<');
27340 $this->_out('/FunctionType 3');
27341 $this->_out('/Domain [0 1]');
27342 $fn = array();
27343 $bd = array();
27344 $en = array();
27345 for($i=0; $i<(count($grad['stops'])-1); $i++) {
27346 $fn[] = ($this->n+1+$i).' 0 R';
27347 $en[] = '0 1';
27348 if ($i>0) { $bd[] = sprintf('%.3F', $grad['stops'][$i]['offset']); }
27349 }
27350 $this->_out('/Functions ['.implode(' ',$fn).']');
27351 $this->_out('/Bounds ['.implode(' ',$bd).']');
27352 $this->_out('/Encode ['.implode(' ',$en).']');
27353 $this->_out('>>');
27354 $this->_out('endobj');
27355 $f2 = $this->n;
27356 for($i=0; $i<(count($grad['stops'])-1); $i++) {
27357 $this->_newobj();
27358 $this->_out('<<');
27359 $this->_out('/FunctionType 2');
27360 $this->_out('/Domain [0 1]');
27361 $this->_out(sprintf('/C0 [%.3F]', $grad['stops'][$i]['opacity']));
27362 $this->_out(sprintf('/C1 [%.3F]', $grad['stops'][$i+1]['opacity']));
27363 $this->_out('/N 1');
27364 $this->_out('>>');
27365 $this->_out('endobj');
27366 }
27367 }
27368 }
27369
27370 if (empty($grad['is_mask'])) {
27371 $this->_newobj();
27372 $this->_out('<<');
27373 $this->_out('/ShadingType '.$grad['type']);
27374 if (isset($grad['colorspace'])) {
27375 $this->_out('/ColorSpace /Device'.$grad['colorspace']); // Can use CMYK if all C0 and C1 above have 4 values
27376 } else {
27377 $this->_out('/ColorSpace /DeviceRGB');
27378 }
27379 if ($grad['type'] == 2) {
27380 $this->_out(sprintf('/Coords [%.3F %.3F %.3F %.3F]', $grad['coords'][0], $grad['coords'][1], $grad['coords'][2], $grad['coords'][3]));
27381 $this->_out('/Function '.$f1.' 0 R');
27382 $this->_out('/Extend ['.$grad['extend'][0].' '.$grad['extend'][1].'] ');
27383 $this->_out('>>');
27384 }
27385 else if ($grad['type'] == 3) {
27386 //x0, y0, r0, x1, y1, r1
27387 //at this this time radius of inner circle is 0
27388 $ir = 0;
27389 if (isset($grad['coords'][5]) && $grad['coords'][5]) { $ir = $grad['coords'][5]; }
27390 $this->_out(sprintf('/Coords [%.3F %.3F %.3F %.3F %.3F %.3F]', $grad['coords'][0], $grad['coords'][1], $ir, $grad['coords'][2], $grad['coords'][3], $grad['coords'][4]));
27391 $this->_out('/Function '.$f1.' 0 R');
27392 $this->_out('/Extend ['.$grad['extend'][0].' '.$grad['extend'][1].'] ');
27393 $this->_out('>>');
27394 }
27395 else if ($grad['type']==6) {
27396 $this->_out('/BitsPerCoordinate 16');
27397 $this->_out('/BitsPerComponent 8');
27398 if ($grad['colorspace'] == 'CMYK') { $this->_out('/Decode[0 1 0 1 0 1 0 1 0 1 0 1]'); }
27399 else if ($grad['colorspace'] == 'Gray') { $this->_out('/Decode[0 1 0 1 0 1]'); }
27400 else { $this->_out('/Decode[0 1 0 1 0 1 0 1 0 1]'); }
27401 $this->_out('/BitsPerFlag 8');
27402 $this->_out('/Length '.strlen($grad['stream']));
27403 $this->_out('>>');
27404 $this->_putstream($grad['stream']);
27405 }
27406 $this->_out('endobj');
27407 }
27408
27409 $this->gradients[$id]['id'] = $this->n;
27410
27411 // set pattern object
27412 $this->_newobj();
27413 $out = '<< /Type /Pattern /PatternType 2';
27414 $out .= ' /Shading '.$this->gradients[$id]['id'].' 0 R';
27415 $out .= ' >>';
27416 $out .= "\n".'endobj';
27417 $this->_out($out);
27418
27419
27420 $this->gradients[$id]['pattern'] = $this->n;
27421
27422 if (isset($grad['trans']) && $grad['trans']) {
27423 // luminosity pattern
27424 $transid = $id + $maxid;
27425 $this->_newobj();
27426 $this->_out('<<');
27427 $this->_out('/ShadingType '.$grad['type']);
27428 $this->_out('/ColorSpace /DeviceGray');
27429 if ($grad['type'] == 2) {
27430 $this->_out(sprintf('/Coords [%.3F %.3F %.3F %.3F]', $grad['coords'][0], $grad['coords'][1], $grad['coords'][2], $grad['coords'][3]));
27431 $this->_out('/Function '.$f2.' 0 R');
27432 $this->_out('/Extend ['.$grad['extend'][0].' '.$grad['extend'][1].'] ');
27433 $this->_out('>>');
27434 }
27435 else if ($grad['type'] == 3) {
27436 //x0, y0, r0, x1, y1, r1
27437 //at this this time radius of inner circle is 0
27438 $ir = 0;
27439 if (isset($grad['coords'][5]) && $grad['coords'][5]) { $ir = $grad['coords'][5]; }
27440 $this->_out(sprintf('/Coords [%.3F %.3F %.3F %.3F %.3F %.3F]', $grad['coords'][0], $grad['coords'][1], $ir, $grad['coords'][2], $grad['coords'][3], $grad['coords'][4]));
27441 $this->_out('/Function '.$f2.' 0 R');
27442 $this->_out('/Extend ['.$grad['extend'][0].' '.$grad['extend'][1].'] ');
27443 $this->_out('>>');
27444 }
27445 else if ($grad['type']==6) {
27446 $this->_out('/BitsPerCoordinate 16');
27447 $this->_out('/BitsPerComponent 8');
27448 $this->_out('/Decode[0 1 0 1 0 1]');
27449 $this->_out('/BitsPerFlag 8');
27450 $this->_out('/Length '.strlen($grad['stream_trans']));
27451 $this->_out('>>');
27452 $this->_putstream($grad['stream_trans']);
27453 }
27454 $this->_out('endobj');
27455
27456 $this->gradients[$transid]['id'] = $this->n;
27457 $this->_newobj();
27458 $this->_out('<< /Type /Pattern /PatternType 2');
27459 $this->_out('/Shading '.$this->gradients[$transid]['id'].' 0 R');
27460 $this->_out('>>');
27461 $this->_out('endobj');
27462 $this->gradients[$transid]['pattern'] = $this->n;
27463 $this->_newobj();
27464 // Need to extend size of viewing box in case of transformations
27465 $str = 'q /a0 gs /Pattern cs /p'.$transid.' scn -'.($this->wPt/2).' -'.($this->hPt/2).' '.(2*$this->wPt).' '.(2*$this->hPt).' re f Q';
27466 $filter=($this->compress) ? '/Filter /FlateDecode ' : '';
27467 $p=($this->compress) ? gzcompress($str) : $str;
27468 $this->_out('<< /Type /XObject /Subtype /Form /FormType 1 '.$filter);
27469 $this->_out('/Length '.strlen($p));
27470 $this->_out('/BBox [-'.($this->wPt/2).' -'.($this->hPt/2).' '.(2*$this->wPt).' '.(2*$this->hPt).']');
27471 $this->_out('/Group << /Type /Group /S /Transparency /CS /DeviceGray >>');
27472 $this->_out('/Resources <<');
27473 $this->_out('/ExtGState << /a0 << /ca 1 /CA 1 >> >>');
27474 $this->_out('/Pattern << /p'.$transid.' '.$this->gradients[$transid]['pattern'].' 0 R >>');
27475 $this->_out('>>');
27476 $this->_out('>>');
27477 $this->_putstream($p);
27478 $this->_out('endobj');
27479 $this->_newobj();
27480 $this->_out('<< /Type /Mask /S /Luminosity /G '.($this->n - 1).' 0 R >>'."\n".'endobj');
27481 $this->_newobj();
27482 $this->_out('<< /Type /ExtGState /SMask '.($this->n - 1).' 0 R /AIS false >>'."\n".'endobj');
27483 if ($grad['fo']) { $this->extgstates[] = array('n' => $this->n, 'trans' => 'TGS'.$id, 'fo'=>true); }
27484 else { $this->extgstates[] = array('n' => $this->n, 'trans' => 'TGS'.$id); }
27485 }
27486 }
27487 }
27488 /*-- END BACKGROUNDS --*/
27489
27490 function _putspotcolors() {
27491 foreach($this->spotColors as $name=>$color) {
27492 $this->_newobj();
27493 $this->_out('[/Separation /'.str_replace(' ','#20',$name));
27494 $this->_out('/DeviceCMYK <<');
27495 $this->_out('/Range [0 1 0 1 0 1 0 1] /C0 [0 0 0 0] ');
27496 $this->_out(sprintf('/C1 [%.3F %.3F %.3F %.3F] ',$color['c']/100,$color['m']/100,$color['y']/100,$color['k']/100));
27497 $this->_out('/FunctionType 2 /Domain [0 1] /N 1>>]');
27498 $this->_out('endobj');
27499 $this->spotColors[$name]['n']=$this->n;
27500 }
27501 }
27502
27503
27504 function _putresources() {
27505 if ($this->hasOC || count($this->layers)) // mPDF 5.6.01
27506 $this->_putocg();
27507 $this->_putextgstates();
27508 $this->_putspotcolors();
27509 if ($this->progressBar) { $this->UpdateProgressBar(2,'40','Compiling Fonts'); } // *PROGRESS-BAR*
27510 $this->_putfonts();
27511 if ($this->progressBar) { $this->UpdateProgressBar(2,'50','Compiling Images'); } // *PROGRESS-BAR*
27512 $this->_putimages();
27513 $this->_putformobjects(); // *IMAGES-CORE*
27514
27515 /*-- IMPORTS --*/
27516 if ($this->enableImports) {
27517 $this->_putformxobjects();
27518 $this->_putimportedobjects();
27519 }
27520 /*-- END IMPORTS --*/
27521
27522 /*-- BACKGROUNDS --*/
27523 $this->_putshaders();
27524 $this->_putpatterns();
27525 /*-- END BACKGROUNDS --*/
27526
27527
27528 //Resource dictionary
27529 $this->offsets[2]=strlen($this->buffer);
27530 $this->_out('2 0 obj');
27531 $this->_out('<</ProcSet [/PDF /Text /ImageB /ImageC /ImageI]');
27532
27533 $this->_out('/Font <<');
27534 foreach($this->fonts as $font) {
27535 if (!$font['used'] && $font['type']=='TTF') { continue; }
27536 if ($font['type']=='TTF' && ($font['sip'] || $font['smp'])) {
27537 foreach($font['n'] AS $k => $fid) {
27538 $this->_out('/F'.$font['subsetfontids'][$k].' '.$font['n'][$k].' 0 R');
27539 }
27540 }
27541 else {
27542 $this->_out('/F'.$font['i'].' '.$font['n'].' 0 R');
27543 }
27544 }
27545 $this->_out('>>');
27546
27547 if (count($this->spotColors)) {
27548 $this->_out('/ColorSpace <<');
27549 foreach($this->spotColors as $color)
27550 $this->_out('/CS'.$color['i'].' '.$color['n'].' 0 R');
27551 $this->_out('>>');
27552 }
27553
27554 if (count($this->extgstates)) {
27555 $this->_out('/ExtGState <<');
27556 foreach($this->extgstates as $k=>$extgstate)
27557 if (isset($extgstate['trans'])) $this->_out('/'.$extgstate['trans'].' '.$extgstate['n'].' 0 R');
27558 else $this->_out('/GS'.$k.' '.$extgstate['n'].' 0 R');
27559 $this->_out('>>');
27560 }
27561
27562 /*-- BACKGROUNDS --*/
27563 if (isset($this->gradients) AND (count($this->gradients) > 0)) {
27564 $this->_out('/Shading <<');
27565 foreach ($this->gradients as $id => $grad) {
27566 $this->_out('/Sh'.$id.' '.$grad['id'].' 0 R');
27567 }
27568 $this->_out('>>');
27569
27570 /*
27571 // ??? Not needed !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
27572 $this->_out('/Pattern <<');
27573 foreach ($this->gradients as $id => $grad) {
27574 $this->_out('/P'.$id.' '.$grad['pattern'].' 0 R');
27575 }
27576 $this->_out('>>');
27577 */
27578 }
27579 /*-- END BACKGROUNDS --*/
27580
27581 if(count($this->images) || count($this->formobjects) || ($this->enableImports && count($this->tpls))) {
27582 $this->_out('/XObject <<');
27583 foreach($this->images as $image)
27584 $this->_out('/I'.$image['i'].' '.$image['n'].' 0 R');
27585 foreach($this->formobjects as $formobject)
27586 $this->_out('/FO'.$formobject['i'].' '.$formobject['n'].' 0 R');
27587 /*-- IMPORTS --*/
27588 if ($this->enableImports && count($this->tpls)) {
27589 foreach($this->tpls as $tplidx => $tpl) {
27590 $this->_out($this->tplprefix.$tplidx.' '.$tpl['n'].' 0 R');
27591 }
27592 }
27593 /*-- END IMPORTS --*/
27594 $this->_out('>>');
27595 }
27596
27597 /*-- BACKGROUNDS --*/
27598
27599 if (count($this->patterns)) {
27600 $this->_out('/Pattern <<');
27601 foreach($this->patterns as $k=>$patterns)
27602 $this->_out('/P'.$k.' '.$patterns['n'].' 0 R');
27603 $this->_out('>>');
27604 }
27605 /*-- END BACKGROUNDS --*/
27606
27607 // mPDF 5.6.01
27608 if ($this->hasOC || count($this->layers)) {
27609 $this->_out('/Properties <<');
27610 if ($this->hasOC) {
27611 $this->_out('/OC1 '.$this->n_ocg_print.' 0 R /OC2 '.$this->n_ocg_view.' 0 R /OC3 '.$this->n_ocg_hidden.' 0 R ');
27612 }
27613 if (count($this->layers)) {
27614 foreach($this->layers as $id=>$layer)
27615 $this->_out('/ZI'.$id.' '.$layer['n'].' 0 R');
27616 }
27617 $this->_out('>>');
27618 }
27619
27620 $this->_out('>>');
27621 $this->_out('endobj'); // end resource dictionary
27622
27623 $this->_putbookmarks(); // *BOOKMARKS*
27624
27625 if (isset($this->js) && $this->js) {
27626 $this->_putjavascript();
27627 }
27628
27629 /*-- ENCRYPTION --*/
27630 if ($this->encrypted) {
27631 $this->_newobj();
27632 $this->enc_obj_id = $this->n;
27633 $this->_out('<<');
27634 $this->_putencryption();
27635 $this->_out('>>');
27636 $this->_out('endobj');
27637 }
27638 /*-- END ENCRYPTION --*/
27639 }
27640
27641
27642 function _putjavascript() {
27643 $this->_newobj();
27644 $this->n_js = $this->n;
27645 $this->_out('<<');
27646 $this->_out('/Names [(EmbeddedJS) '.(1 + $this->n).' 0 R ]');
27647 $this->_out('>>');
27648 $this->_out('endobj');
27649
27650 $this->_newobj();
27651 $this->_out('<<');
27652 $this->_out('/S /JavaScript');
27653 $this->_out('/JS '.$this->_textstring($this->js));
27654 $this->_out('>>');
27655 $this->_out('endobj');
27656 }
27657
27658
27659
27660
27661 /*-- ENCRYPTION --*/
27662 function _putencryption() {
27663 $this->_out('/Filter /Standard');
27664 if ($this->useRC128encryption) {
27665 $this->_out('/V 2');
27666 $this->_out('/R 3');
27667 $this->_out('/Length 128');
27668 }
27669 else {
27670 $this->_out('/V 1');
27671 $this->_out('/R 2');
27672 }
27673 $this->_out('/O ('.$this->_escape($this->Ovalue).')');
27674 $this->_out('/U ('.$this->_escape($this->Uvalue).')');
27675 $this->_out('/P '.$this->Pvalue);
27676 }
27677 /*-- END ENCRYPTION --*/
27678
27679 function _puttrailer() {
27680 $this->_out('/Size '.($this->n+1));
27681 $this->_out('/Root '.$this->n.' 0 R');
27682 $this->_out('/Info '.$this->InfoRoot.' 0 R');
27683 /*-- ENCRYPTION --*/
27684 if ($this->encrypted) {
27685 $this->_out('/Encrypt '.$this->enc_obj_id.' 0 R');
27686 $this->_out('/ID [<'.$this->uniqid.'> <'.$this->uniqid.'>]');
27687 }
27688 else {
27689 /*-- END ENCRYPTION --*/
27690 $uniqid = md5(time() . $this->buffer);
27691 $this->_out('/ID [<'.$uniqid.'> <'.$uniqid.'>]');
27692 /*-- ENCRYPTION --*/
27693 }
27694 /*-- END ENCRYPTION --*/
27695 }
27696
27697 /*-- ENCRYPTION --*/
27698 function SetProtection($permissions=array(),$user_pass='',$owner_pass=null, $length=40) {
27699 $this->encrypted=false;
27700 if (is_string($permissions) && strlen($permissions)>0) { $permissions = array($permissions); }
27701 else if (!is_array($permissions)) { return 0; }
27702 $this->last_rc4_key='';
27703 $this->padding="\x28\xBF\x4E\x5E\x4E\x75\x8A\x41\x64\x00\x4E\x56\xFF\xFA\x01\x08".
27704 "\x2E\x2E\x00\xB6\xD0\x68\x3E\x80\x2F\x0C\xA9\xFE\x64\x53\x69\x7A";
27705
27706 $options = array(
27707 'print' => 4, // bit 3
27708 'modify' => 8, // bit 4
27709 'copy' => 16, // bit 5
27710 'annot-forms' => 32, // bit 6
27711 'fill-forms' => 256, // bit 9
27712 'extract' => 512, // bit 10
27713 'assemble' => 1024,// bit 11
27714 'print-highres' => 2048 // bit 12
27715 );
27716 // bit 31 = 1073741824
27717 // bit 32 = 2147483648
27718 // bits 13-31 = 2147479552
27719 // bits 13-32 = 4294963200 + 192 = 4294963392
27720 $protection = 4294963392; // bits 7,8,13-32
27721 foreach ($permissions as $permission) {
27722 if (!isset($options[$permission]))
27723 $this->Error('Incorrect permission: '.$permission);
27724 if ($options[$permission] > 32) { $this->useRC128encryption = true; }
27725 if (isset($options[$permission])) $protection += $options[$permission];
27726 }
27727 if ($length==128) { $this->useRC128encryption = true; }
27728 if ($owner_pass === null)
27729 $owner_pass = uniqid(rand());
27730 $this->encrypted = true;
27731 $this->_generateencryptionkey($user_pass, $owner_pass, $protection);
27732 }
27733
27734
27735 // Compute key depending on object number where the encrypted data is stored
27736 function _objectkey($n) {
27737 if ($this->useRC128encryption)
27738 $len = 16;
27739 else
27740 $len = 10;
27741 return substr($this->_md5_16($this->encryption_key.pack('VXxx',$n)),0,$len);
27742 }
27743
27744 // RC4 is the standard encryption algorithm used in PDF format
27745 function _RC4($key, $text) {
27746 if ($this->last_rc4_key != $key) {
27747 $k = str_repeat($key, 256/strlen($key)+1);
27748 $rc4 = range(0,255);
27749 $j = 0;
27750 for ($i=0; $i<256; $i++){
27751 $t = $rc4[$i];
27752 $j = ($j + $t + ord($k[$i])) % 256;
27753 $rc4[$i] = $rc4[$j];
27754 $rc4[$j] = $t;
27755 }
27756 $this->last_rc4_key = $key;
27757 $this->last_rc4_key_c = $rc4;
27758 } else {
27759 $rc4 = $this->last_rc4_key_c;
27760 }
27761
27762 $len = strlen($text);
27763 $a = 0;
27764 $b = 0;
27765 $out = '';
27766 for ($i=0; $i<$len; $i++){
27767 $a = ($a+1)%256;
27768 $t= $rc4[$a];
27769 $b = ($b+$t)%256;
27770 $rc4[$a] = $rc4[$b];
27771 $rc4[$b] = $t;
27772 $k = $rc4[($rc4[$a]+$rc4[$b])%256];
27773 $out.= chr(ord($text[$i]) ^ $k);
27774 }
27775 return $out;
27776 }
27777
27778 // Get MD5 as binary string
27779 function _md5_16($string) {
27780 return pack('H*',md5($string));
27781 }
27782
27783 // Compute O value
27784 function _Ovalue($user_pass, $owner_pass) {
27785 $tmp = $this->_md5_16($owner_pass);
27786 if ($this->useRC128encryption) {
27787 for ($i = 0; $i < 50; ++$i) {
27788 $tmp = $this->_md5_16($tmp);
27789 }
27790 }
27791 if ($this->useRC128encryption)
27792 $keybytelen = (128 / 8);
27793 else
27794 $keybytelen = (40 / 8);
27795 $owner_RC4_key = substr($tmp,0,$keybytelen);
27796 $enc = $this->_RC4($owner_RC4_key, $user_pass);
27797 if ($this->useRC128encryption) {
27798 $len = strlen($owner_RC4_key);
27799 for ($i = 1; $i <= 19; ++$i) {
27800 $key = '';
27801 for ($j = 0; $j < $len; ++$j) {
27802 $key .= chr(ord($owner_RC4_key{$j}) ^ $i);
27803 }
27804 $enc = $this->_RC4($key, $enc);
27805 }
27806 }
27807 return $enc;
27808 }
27809
27810 // Compute U value
27811 function _Uvalue() {
27812 if ($this->useRC128encryption) {
27813 $tmp = $this->_md5_16($this->padding.$this->_hexToString($this->uniqid));
27814 $enc = $this->_RC4($this->encryption_key, $tmp);
27815 $len = strlen($tmp);
27816 for ($i=1; $i<=19; ++$i) {
27817 $key = '';
27818 for ($j=0; $j<$len; ++$j) {
27819 $key .= chr(ord($this->encryption_key{$j}) ^ $i);
27820 }
27821 $enc = $this->_RC4($key, $enc);
27822 }
27823 $enc .= str_repeat("\x00", 16);
27824 return substr($enc, 0, 32);
27825 }
27826 else {
27827 return $this->_RC4($this->encryption_key, $this->padding);
27828 }
27829 }
27830
27831 // Compute encryption key
27832 function _generateencryptionkey($user_pass, $owner_pass, $protection) {
27833 // Pad passwords
27834 $user_pass = substr($user_pass.$this->padding,0,32);
27835 $owner_pass = substr($owner_pass.$this->padding,0,32);
27836 $chars = 'ABCDEF1234567890';
27837 $id = '';
27838 for ($i=0; $i<32; $i++) { $id .= $chars{rand(0, 15)}; }
27839 $this->uniqid = md5($id);
27840 // Compute O value
27841 $this->Ovalue = $this->_Ovalue($user_pass,$owner_pass);
27842 // Compute encyption key
27843 if ($this->useRC128encryption)
27844 $keybytelen = (128/8);
27845 else
27846 $keybytelen = (40/8);
27847 $prot = sprintf('%032b', $protection);
27848 $perms = chr(bindec(substr($prot,24,8)));
27849 $perms .= chr(bindec(substr($prot,16,8)));
27850 $perms .= chr(bindec(substr($prot,8,8)));
27851 $perms .= chr(bindec(substr($prot,0,8)));
27852 $tmp = $this->_md5_16($user_pass.$this->Ovalue.$perms.$this->_hexToString($this->uniqid));
27853 if ($this->useRC128encryption) {
27854 for ($i=0; $i<50; ++$i) {
27855 $tmp = $this->_md5_16(substr($tmp, 0, $keybytelen));
27856 }
27857 }
27858 $this->encryption_key = substr($tmp,0,$keybytelen);
27859 // Compute U value
27860 $this->Uvalue = $this->_Uvalue();
27861 // Compute P value
27862 $this->Pvalue = $protection;
27863 }
27864
27865
27866 function _hexToString($hs) {
27867 $s = '';
27868 $len = strlen($hs);
27869 if (($len % 2) != 0) {
27870 $hs .= '0';
27871 ++$len;
27872 }
27873 for ($i = 0; $i < $len; $i += 2) {
27874 $s .= chr(hexdec($hs{$i}.$hs{($i + 1)}));
27875 }
27876 return $s;
27877 }
27878
27879 /*-- END ENCRYPTION --*/
27880
27881 //=========================================
27882 /*-- BOOKMARKS --*/
27883 // FROM class PDF_Bookmark
27884
27885 function Bookmark($txt,$level=0,$y=0) {
27886 $txt = $this->purify_utf8_text($txt);
27887 if ($this->text_input_as_HTML) {
27888 $txt = $this->all_entities_to_utf8($txt);
27889 }
27890 if($y==-1) {
27891 if (!$this->ColActive){ $y=$this->y; }
27892 else { $y = $this->y0; } // If columns are on - mark top of columns
27893 }
27894 // else y is used as set, or =0 i.e. top of page
27895 // DIRECTIONALITY RTL
27896 $bmo = array('t'=>$txt,'l'=>$level,'y'=>$y,'p'=>$this->page);
27897 if ($this->keep_block_together) {
27898 $this->ktBMoutlines[]= $bmo;
27899 }
27900 /*-- TABLES --*/
27901 else if ($this->table_rotate) {
27902 $this->tbrot_BMoutlines[]= $bmo;
27903 }
27904 else if ($this->kwt) {
27905 $this->kwt_BMoutlines[]= $bmo;
27906 }
27907 /*-- END TABLES --*/
27908 else if ($this->ColActive) { // *COLUMNS*
27909 $this->col_BMoutlines[]= $bmo; // *COLUMNS*
27910 } // *COLUMNS*
27911 else {
27912 $this->BMoutlines[]= $bmo;
27913 }
27914 }
27915
27916
27917 function _putbookmarks()
27918 {
27919 $nb=count($this->BMoutlines);
27920 if($nb==0)
27921 return;
27922
27923 // mPDF 5.6.36
27924 $bmo = $this->BMoutlines;
27925 $this->BMoutlines = array();
27926 $lastlevel = -1;
27927 for($i=0;$i<count($bmo);$i++) {
27928 if ($bmo[$i]['l']>0) {
27929 while($bmo[$i]['l']-$lastlevel > 1) { // If jump down more than one level, insert a new entry
27930 $new = $bmo[$i];
27931 $new['t']="[".$new['t']."]"; // Put [] around text/title to highlight
27932 $new['l']=$lastlevel+1;
27933 $lastlevel++;
27934 $this->BMoutlines[] = $new;
27935 }
27936 }
27937 $this->BMoutlines[] = $bmo[$i];
27938 $lastlevel = $bmo[$i]['l'];
27939 }
27940 $nb=count($this->BMoutlines);
27941
27942 $lru=array();
27943 $level=0;
27944 foreach($this->BMoutlines as $i=>$o) {
27945 if($o['l']>0) {
27946 $parent=$lru[$o['l']-1];
27947 //Set parent and last pointers
27948 $this->BMoutlines[$i]['parent']=$parent;
27949 $this->BMoutlines[$parent]['last']=$i;
27950 if($o['l']>$level) {
27951 //Level increasing: set first pointer
27952 $this->BMoutlines[$parent]['first']=$i;
27953 }
27954 }
27955 else {
27956 $this->BMoutlines[$i]['parent']=$nb;
27957 }
27958 if($o['l']<=$level and $i>0) {
27959 //Set prev and next pointers
27960 $prev=$lru[$o['l']];
27961 $this->BMoutlines[$prev]['next']=$i;
27962 $this->BMoutlines[$i]['prev']=$prev;
27963 }
27964 $lru[$o['l']]=$i;
27965 $level=$o['l'];
27966 }
27967
27968
27969 //Outline items
27970 $n=$this->n+1;
27971 foreach($this->BMoutlines as $i=>$o) {
27972 $this->_newobj();
27973 $this->_out('<</Title '.$this->_UTF16BEtextstring($o['t']));
27974 $this->_out('/Parent '.($n+$o['parent']).' 0 R');
27975 if(isset($o['prev']))
27976 $this->_out('/Prev '.($n+$o['prev']).' 0 R');
27977 if(isset($o['next']))
27978 $this->_out('/Next '.($n+$o['next']).' 0 R');
27979 if(isset($o['first']))
27980 $this->_out('/First '.($n+$o['first']).' 0 R');
27981 if(isset($o['last']))
27982 $this->_out('/Last '.($n+$o['last']).' 0 R');
27983
27984
27985 if (isset($this->pageDim[$o['p']]['h'])) { $h=$this->pageDim[$o['p']]['h']; }
27986 else { $h = 0; }
27987
27988 $this->_out(sprintf('/Dest [%d 0 R /XYZ 0 %.3F null]',1+2*($o['p']),($h-$o['y'])*_MPDFK));
27989 if (isset($this->bookmarkStyles) && isset($this->bookmarkStyles[$o['l']])) {
27990 // font style
27991 $bms = $this->bookmarkStyles[$o['l']]['style'];
27992 $style = 0;
27993 if (strpos($bms,'B') !== false) { $style += 2; }
27994 if (strpos($bms,'I') !== false) { $style += 1; }
27995 $this->_out(sprintf('/F %d', $style));
27996 // Colour
27997 $col = $this->bookmarkStyles[$o['l']]['color'];
27998 if (isset($col) && is_array($col) && count($col)==3) {
27999 $this->_out(sprintf('/C [%.3F %.3F %.3F]', ($col[0]/255), ($col[1]/255), ($col[2]/255)));
28000 }
28001 }
28002
28003 $this->_out('/Count 0>>');
28004 $this->_out('endobj');
28005 }
28006 //Outline root
28007 $this->_newobj();
28008 $this->OutlineRoot=$this->n;
28009 $this->_out('<</Type /BMoutlines /First '.$n.' 0 R');
28010 $this->_out('/Last '.($n+$lru[0]).' 0 R>>');
28011 $this->_out('endobj');
28012 }
28013 /*-- END BOOKMARKS --*/
28014
28015
28016
28017 //======================================================
28018
28019
28020 // DEPRACATED but included for backwards compatability
28021 function startPageNums() {
28022 }
28023
28024 //======================================================
28025 /*-- TOC --*/
28026 // ToC TABLE OF CONTENTS
28027
28028 // Initiate, and Mark a place for the Table of Contents to be inserted
28029 function TOC($tocfont='', $tocfontsize=0, $tocindent=0, $resetpagenum='', $pagenumstyle='', $suppress='', $toc_orientation='', $TOCusePaging=true, $TOCuseLinking=false, $toc_id=0, $tocoutdent='') { // mPDF 5.6.19
28030 if (!class_exists('tocontents', false)) { include(_MPDF_PATH.'classes/tocontents.php'); }
28031 if (empty($this->tocontents)) { $this->tocontents = new tocontents($this); }
28032 $this->tocontents->TOC($tocfont, $tocfontsize, $tocindent, $resetpagenum, $pagenumstyle, $suppress, $toc_orientation, $TOCusePaging, $TOCuseLinking, $toc_id, $tocoutdent); // mPDF 5.6.19
28033 }
28034
28035
28036 function TOCpagebreakByArray($a) {
28037 if (!is_array($a)) { $a = array(); }
28038 if (!class_exists('tocontents', false)) { include(_MPDF_PATH.'classes/tocontents.php'); }
28039 if (empty($this->tocontents)) { $this->tocontents = new tocontents($this); }
28040 $tocoutdent = (isset($a['tocoutdent']) ? $a['tocoutdent'] : (isset($a['outdent']) ? $a['outdent'] : ''));
28041 $TOCusePaging = (isset($a['TOCusePaging']) ? $a['TOCusePaging'] : (isset($a['paging']) ? $a['paging'] : true));
28042 $TOCuseLinking = (isset($a['TOCuseLinking']) ? $a['TOCuseLinking'] : (isset($a['links']) ? $a['links'] : ''));
28043 $toc_orientation = (isset($a['toc_orientation']) ? $a['toc_orientation'] : (isset($a['toc-orientation']) ? $a['toc-orientation'] : ''));
28044 $toc_mgl = (isset($a['toc_mgl']) ? $a['toc_mgl'] : (isset($a['toc-margin-left']) ? $a['toc-margin-left'] : ''));
28045 $toc_mgr = (isset($a['toc_mgr']) ? $a['toc_mgr'] : (isset($a['toc-margin-right']) ? $a['toc-margin-right'] : ''));
28046 $toc_mgt = (isset($a['toc_mgt']) ? $a['toc_mgt'] : (isset($a['toc-margin-top']) ? $a['toc-margin-top'] : ''));
28047 $toc_mgb = (isset($a['toc_mgb']) ? $a['toc_mgb'] : (isset($a['toc-margin-bottom']) ? $a['toc-margin-bottom'] : ''));
28048 $toc_mgh = (isset($a['toc_mgh']) ? $a['toc_mgh'] : (isset($a['toc-margin-header']) ? $a['toc-margin-header'] : ''));
28049 $toc_mgf = (isset($a['toc_mgf']) ? $a['toc_mgf'] : (isset($a['toc-margin-footer']) ? $a['toc-margin-footer'] : ''));
28050 $toc_ohname = (isset($a['toc_ohname']) ? $a['toc_ohname'] : (isset($a['toc-odd-header-name']) ? $a['toc-odd-header-name'] : ''));
28051 $toc_ehname = (isset($a['toc_ehname']) ? $a['toc_ehname'] : (isset($a['toc-even-header-name']) ? $a['toc-even-header-name'] : ''));
28052 $toc_ofname = (isset($a['toc_ofname']) ? $a['toc_ofname'] : (isset($a['toc-odd-footer-name']) ? $a['toc-odd-footer-name'] : ''));
28053 $toc_efname = (isset($a['toc_efname']) ? $a['toc_efname'] : (isset($a['toc-even-footer-name']) ? $a['toc-even-footer-name'] : ''));
28054 $toc_ohvalue = (isset($a['toc_ohvalue']) ? $a['toc_ohvalue'] : (isset($a['toc-odd-header-value']) ? $a['toc-odd-header-value'] : 0));
28055 $toc_ehvalue = (isset($a['toc_ehvalue']) ? $a['toc_ehvalue'] : (isset($a['toc-even-header-value']) ? $a['toc-even-header-value'] : 0));
28056 $toc_ofvalue = (isset($a['toc_ofvalue']) ? $a['toc_ofvalue'] : (isset($a['toc-odd-footer-value']) ? $a['toc-odd-footer-value'] : 0));
28057 $toc_efvalue = (isset($a['toc_efvalue']) ? $a['toc_efvalue'] : (isset($a['toc-even-footer-value']) ? $a['toc-even-footer-value'] : 0));
28058 $toc_preHTML = (isset($a['toc_preHTML']) ? $a['toc_preHTML'] : (isset($a['toc-preHTML']) ? $a['toc-preHTML'] : ''));
28059 $toc_postHTML = (isset($a['toc_postHTML']) ? $a['toc_postHTML'] : (isset($a['toc-postHTML']) ? $a['toc-postHTML'] : ''));
28060 $toc_bookmarkText = (isset($a['toc_bookmarkText']) ? $a['toc_bookmarkText'] : (isset($a['toc-bookmarkText']) ? $a['toc-bookmarkText'] : ''));
28061 $resetpagenum = (isset($a['resetpagenum']) ? $a['resetpagenum'] : '');
28062 $pagenumstyle = (isset($a['pagenumstyle']) ? $a['pagenumstyle'] : '');
28063 $suppress = (isset($a['suppress']) ? $a['suppress'] : '');
28064 $orientation = (isset($a['orientation']) ? $a['orientation'] : '');
28065 $mgl = (isset($a['mgl']) ? $a['mgl'] : (isset($a['margin-left']) ? $a['margin-left'] : ''));
28066 $mgr = (isset($a['mgr']) ? $a['mgr'] : (isset($a['margin-right']) ? $a['margin-right'] : ''));
28067 $mgt = (isset($a['mgt']) ? $a['mgt'] : (isset($a['margin-top']) ? $a['margin-top'] : ''));
28068 $mgb = (isset($a['mgb']) ? $a['mgb'] : (isset($a['margin-bottom']) ? $a['margin-bottom'] : ''));
28069 $mgh = (isset($a['mgh']) ? $a['mgh'] : (isset($a['margin-header']) ? $a['margin-header'] : ''));
28070 $mgf = (isset($a['mgf']) ? $a['mgf'] : (isset($a['margin-footer']) ? $a['margin-footer'] : ''));
28071 $ohname = (isset($a['ohname']) ? $a['ohname'] : (isset($a['odd-header-name']) ? $a['odd-header-name'] : ''));
28072 $ehname = (isset($a['ehname']) ? $a['ehname'] : (isset($a['even-header-name']) ? $a['even-header-name'] : ''));
28073 $ofname = (isset($a['ofname']) ? $a['ofname'] : (isset($a['odd-footer-name']) ? $a['odd-footer-name'] : ''));
28074 $efname = (isset($a['efname']) ? $a['efname'] : (isset($a['even-footer-name']) ? $a['even-footer-name'] : ''));
28075 $ohvalue = (isset($a['ohvalue']) ? $a['ohvalue'] : (isset($a['odd-header-value']) ? $a['odd-header-value'] : 0));
28076 $ehvalue = (isset($a['ehvalue']) ? $a['ehvalue'] : (isset($a['even-header-value']) ? $a['even-header-value'] : 0));
28077 $ofvalue = (isset($a['ofvalue']) ? $a['ofvalue'] : (isset($a['odd-footer-value']) ? $a['odd-footer-value'] : 0));
28078 $efvalue = (isset($a['efvalue']) ? $a['efvalue'] : (isset($a['even-footer-value']) ? $a['even-footer-value'] : 0));
28079 $toc_id = (isset($a['toc_id']) ? $a['toc_id'] : (isset($a['name']) ? $a['name'] : 0));
28080 $pagesel = (isset($a['pagesel']) ? $a['pagesel'] : (isset($a['pageselector']) ? $a['pageselector'] : ''));
28081 $toc_pagesel = (isset($a['toc_pagesel']) ? $a['toc_pagesel'] : (isset($a['toc-pageselector']) ? $a['toc-pageselector'] : ''));
28082 $sheetsize = (isset($a['sheetsize']) ? $a['sheetsize'] : (isset($a['sheet-size']) ? $a['sheet-size'] : ''));
28083 $toc_sheetsize = (isset($a['toc_sheetsize']) ? $a['toc_sheetsize'] : (isset($a['toc-sheet-size']) ? $a['toc-sheet-size'] : ''));
28084
28085 $this->TOCpagebreak($tocfont, $tocfontsize, $tocindent, $TOCusePaging, $TOCuseLinking, $toc_orientation, $toc_mgl, $toc_mgr, $toc_mgt, $toc_mgb, $toc_mgh, $toc_mgf, $toc_ohname, $toc_ehname, $toc_ofname, $toc_efname, $toc_ohvalue, $toc_ehvalue, $toc_ofvalue, $toc_efvalue, $toc_preHTML, $toc_postHTML, $toc_bookmarkText, $resetpagenum, $pagenumstyle, $suppress, $orientation, $mgl, $mgr, $mgt, $mgb, $mgh, $mgf, $ohname, $ehname, $ofname, $efname, $ohvalue, $ehvalue, $ofvalue, $efvalue, $toc_id, $pagesel, $toc_pagesel, $sheetsize, $toc_sheetsize, $tocoutdent); // mPDF 5.6.19
28086
28087 }
28088
28089 function TOCpagebreak($tocfont='', $tocfontsize='', $tocindent='', $TOCusePaging=true, $TOCuseLinking='', $toc_orientation='', $toc_mgl='',$toc_mgr='',$toc_mgt='',$toc_mgb='',$toc_mgh='',$toc_mgf='',$toc_ohname='',$toc_ehname='',$toc_ofname='',$toc_efname='',$toc_ohvalue=0,$toc_ehvalue=0,$toc_ofvalue=0, $toc_efvalue=0, $toc_preHTML='', $toc_postHTML='', $toc_bookmarkText='', $resetpagenum='', $pagenumstyle='', $suppress='', $orientation='', $mgl='',$mgr='',$mgt='',$mgb='',$mgh='',$mgf='',$ohname='',$ehname='',$ofname='',$efname='',$ohvalue=0,$ehvalue=0,$ofvalue=0,$efvalue=0, $toc_id=0, $pagesel='', $toc_pagesel='', $sheetsize='', $toc_sheetsize='', $tocoutdent='') { // mPDF 5.6.19) {
28090 if (!class_exists('tocontents', false)) { include(_MPDF_PATH.'classes/tocontents.php'); }
28091 if (empty($this->tocontents)) { $this->tocontents = new tocontents($this); }
28092 //Start a new page
28093 if($this->state==0) $this->AddPage();
28094 if ($this->y == $this->tMargin && (!$this->mirrorMargins ||($this->mirrorMargins && $this->page % 2==1))) {
28095 // Don't add a page
28096 if ($this->page==1 && count($this->PageNumSubstitutions)==0) {
28097 if (!$suppress) { $suppress = 'off'; }
28098 if (!$resetpagenum) { $resetpagenum= 1; }
28099 //$this->PageNumSubstitutions[] = array('from'=>1, 'reset'=> $resetpagenum, 'type'=>$pagenumstyle, 'suppress'=> $suppress);
28100 }
28101 $this->PageNumSubstitutions[] = array('from'=>$this->page, 'reset'=> $resetpagenum, 'type'=>$pagenumstyle, 'suppress'=> $suppress);
28102 }
28103 else {
28104 $this->AddPage($orientation,'NEXT-ODD', $resetpagenum, $pagenumstyle, $suppress,$mgl,$mgr,$mgt,$mgb,$mgh,$mgf,$ohname,$ehname,$ofname,$efname,$ohvalue,$ehvalue,$ofvalue,$efvalue,$pagesel,$sheetsize);
28105 }
28106
28107 $this->tocontents->TOCpagebreak($tocfont, $tocfontsize, $tocindent, $TOCusePaging, $TOCuseLinking, $toc_orientation, $toc_mgl, $toc_mgr, $toc_mgt, $toc_mgb, $toc_mgh, $toc_mgf, $toc_ohname, $toc_ehname, $toc_ofname, $toc_efname, $toc_ohvalue, $toc_ehvalue, $toc_ofvalue, $toc_efvalue, $toc_preHTML, $toc_postHTML, $toc_bookmarkText, $resetpagenum, $pagenumstyle, $suppress, $orientation, $mgl, $mgr, $mgt, $mgb, $mgh, $mgf, $ohname, $ehname, $ofname, $efname, $ohvalue, $ehvalue, $ofvalue, $efvalue, $toc_id, $pagesel, $toc_pagesel, $sheetsize, $toc_sheetsize, $tocoutdent); // mPDF 5.6.19
28108 }
28109
28110 function TOC_Entry($txt, $level=0, $toc_id=0) {
28111 $txt = $this->purify_utf8_text($txt);
28112 if ($this->text_input_as_HTML) {
28113 $txt = $this->all_entities_to_utf8($txt);
28114 }
28115 if ($this->usingCoreFont) { $txt = mb_convert_encoding($txt,$this->mb_enc,'UTF-8'); }
28116 if ($this->ColActive) { $ily = $this->y0; } else { $ily = $this->y; } // use top of columns
28117
28118 // mPDF 5.6.19 mPDF 5.6.25 mPDF 5.6.37
28119 if (!class_exists('tocontents', false)) { include(_MPDF_PATH.'classes/tocontents.php'); }
28120 if (empty($this->tocontents)) { $this->tocontents = new tocontents($this); }
28121 $linkn = $this->AddLink();
28122 $uid = '__mpdfinternallink_' . $linkn ;
28123 if ($this->keep_block_together) { $this->internallink[$uid] = array("Y"=>$ily,"PAGE"=>$this->page, "kt"=>true ); }
28124 else if ($this->table_rotate) { $this->internallink[$uid] = array("Y"=>$ily,"PAGE"=>$this->page, "tbrot"=>true ); }
28125 else if ($this->kwt) { $this->internallink[$uid] = array("Y"=>$ily,"PAGE"=>$this->page, "kwt"=>true ); }
28126 else if ($this->ColActive) { $this->internallink[$uid] = array("Y"=>$ily,"PAGE"=>$this->page, "col"=>$this->CurrCol ); }
28127 else $this->internallink[$uid] = array("Y"=>$ily,"PAGE"=>$this->page );
28128 $this->internallink['#'.$uid] = $linkn;
28129 $this->SetLink($linkn,$ily,$this->page);
28130
28131 /*-- RTL --*/
28132 if ($this->biDirectional) {
28133 $txt = preg_replace("/([".$this->pregRTLchars."]+)/ue", '$this->ArabJoin(stripslashes(\'\\1\'))', $txt );
28134 }
28135 /*-- END RTL --*/
28136 if (strtoupper($toc_id)=='ALL') { $toc_id = '_mpdf_all'; }
28137 else if (!$toc_id) { $toc_id = 0; }
28138 else { $toc_id = strtolower($toc_id); }
28139 $btoc = array('t'=>$txt,'l'=>$level,'p'=>$this->page, 'link'=>$linkn, 'toc_id'=>$toc_id);
28140 if ($this->keep_block_together) {
28141 $this->_kttoc[]= $btoc;
28142 }
28143 /*-- TABLES --*/
28144 else if ($this->table_rotate) {
28145 $this->tbrot_toc[]= $btoc;
28146 }
28147 else if ($this->kwt) {
28148 $this->kwt_toc[]= $btoc;
28149 }
28150 /*-- END TABLES --*/
28151 else if ($this->ColActive) { // *COLUMNS*
28152 $this->col_toc[]= $btoc; // *COLUMNS*
28153 } // *COLUMNS*
28154 else {
28155 $this->tocontents->_toc[]= $btoc;
28156 }
28157 }
28158
28159 /*-- END TOC --*/
28160
28161 //======================================================
28162 function MovePages($target_page, $start_page, $end_page=-1) {
28163 // move a page/pages EARLIER in the document
28164 if ($end_page<1) { $end_page = $start_page; }
28165 $n_toc = $end_page - $start_page + 1;
28166
28167 // Set/Update PageNumSubstitutions changes before moving anything
28168 if (count($this->PageNumSubstitutions)) {
28169 $tp_present = false;
28170 $sp_present = false;
28171 $ep_present = false;
28172 foreach($this->PageNumSubstitutions AS $k=>$v) {
28173 if ($this->PageNumSubstitutions[$k]['from']==$target_page) {
28174 $tp_present = true;
28175 if ($this->PageNumSubstitutions[$k]['suppress']!='on' && $this->PageNumSubstitutions[$k]['suppress']!=1) {
28176 $this->PageNumSubstitutions[$k]['suppress']='off';
28177 }
28178 }
28179 if ($this->PageNumSubstitutions[$k]['from']==$start_page) {
28180 $sp_present = true;
28181 if ($this->PageNumSubstitutions[$k]['suppress']!='on' && $this->PageNumSubstitutions[$k]['suppress']!=1) {
28182 $this->PageNumSubstitutions[$k]['suppress']='off';
28183 }
28184 }
28185 if ($this->PageNumSubstitutions[$k]['from']==($end_page+1)) {
28186 $ep_present = true;
28187 if ($this->PageNumSubstitutions[$k]['suppress']!='on' && $this->PageNumSubstitutions[$k]['suppress']!=1) {
28188 $this->PageNumSubstitutions[$k]['suppress']='off';
28189 }
28190 }
28191 }
28192
28193 if (!$tp_present) {
28194 list($tp_type, $tp_suppress, $tp_reset) = $this->docPageSettings($target_page);
28195 }
28196 if (!$sp_present) {
28197 list($sp_type, $sp_suppress, $sp_reset) = $this->docPageSettings($start_page);
28198 }
28199 if (!$ep_present) {
28200 list($ep_type, $ep_suppress, $ep_reset) = $this->docPageSettings($start_page-1);
28201 }
28202
28203 }
28204
28205 $last = array();
28206 //store pages
28207 for($i = $start_page;$i <= $end_page ;$i++)
28208 $last[]=$this->pages[$i];
28209 //move pages
28210 for($i=$start_page - 1;$i>=($target_page);$i--) {
28211 $this->pages[$i+$n_toc]=$this->pages[$i];
28212 }
28213 //Put toc pages at insert point
28214 for($i = 0;$i < $n_toc;$i++) {
28215 $this->pages[$target_page + $i]=$last[$i];
28216 }
28217
28218 /*-- BOOKMARKS --*/
28219 // Update Bookmarks
28220 foreach($this->BMoutlines as $i=>$o) {
28221 if($o['p']>=$target_page) {
28222 $this->BMoutlines[$i]['p'] += $n_toc;
28223 }
28224 }
28225 /*-- END BOOKMARKS --*/
28226
28227 // Update Page Links
28228 if (count($this->PageLinks)) {
28229 $newarr = array();
28230 foreach($this->PageLinks as $i=>$o) {
28231 foreach($this->PageLinks[$i] as $key => $pl) {
28232 if (strpos($pl[4],'@')===0) {
28233 $p=substr($pl[4],1);
28234 if($p>=$start_page && $p<=$end_page) {
28235 $this->PageLinks[$i][$key][4] = '@'.($p + ($target_page - $start_page));
28236 }
28237 else if($p>=$target_page && $p<$start_page) {
28238 $this->PageLinks[$i][$key][4] = '@'.($p+$n_toc);
28239 }
28240 }
28241 }
28242 if($i>=$start_page && $i<=$end_page) {
28243 $newarr[($i + ($target_page - $start_page))] = $this->PageLinks[$i];
28244 }
28245 else if($i>=$target_page && $i<$start_page) {
28246 $newarr[($i + $n_toc)] = $this->PageLinks[$i];
28247 }
28248 else {
28249 $newarr[$i] = $this->PageLinks[$i];
28250 }
28251 }
28252 $this->PageLinks = $newarr;
28253 }
28254
28255 // OrientationChanges
28256 if (count($this->OrientationChanges)) {
28257 $newarr = array();
28258 foreach($this->OrientationChanges AS $p=>$v) {
28259 if($p>=$start_page && $p<=$end_page) { $newarr[($p + ($target_page - $start_page))] = $this->OrientationChanges[$p]; }
28260 else if($p>=$target_page && $p<$start_page) { $newarr[$p+$n_toc] = $this->OrientationChanges[$p]; }
28261 else { $newarr[$p] = $this->OrientationChanges[$p]; }
28262 }
28263 ksort($newarr);
28264 $this->OrientationChanges = $newarr;
28265 }
28266
28267 // Page Dimensions
28268 if (count($this->pageDim)) {
28269 $newarr = array();
28270 foreach($this->pageDim AS $p=>$v) {
28271 if($p>=$start_page && $p<=$end_page) { $newarr[($p + ($target_page - $start_page))] = $this->pageDim[$p]; }
28272 else if($p>=$target_page && $p<$start_page) { $newarr[$p+$n_toc] = $this->pageDim[$p]; }
28273 else { $newarr[$p] = $this->pageDim[$p]; }
28274 }
28275 ksort($newarr);
28276 $this->pageDim = $newarr;
28277 }
28278
28279 // HTML Headers & Footers
28280 if (count($this->saveHTMLHeader)) {
28281 $newarr = array();
28282 foreach($this->saveHTMLHeader AS $p=>$v) {
28283 if($p>=$start_page && $p<=$end_page) { $newarr[($p + ($target_page - $start_page))] = $this->saveHTMLHeader[$p]; }
28284 else if($p>=$target_page && $p<$start_page) { $newarr[$p+$n_toc] = $this->saveHTMLHeader[$p]; }
28285 else { $newarr[$p] = $this->saveHTMLHeader[$p]; }
28286 }
28287 ksort($newarr);
28288 $this->saveHTMLHeader = $newarr;
28289 }
28290 if (count($this->saveHTMLFooter)) {
28291 $newarr = array();
28292 foreach($this->saveHTMLFooter AS $p=>$v) {
28293 if($p>=$start_page && $p<=$end_page) { $newarr[($p + ($target_page - $start_page))] = $this->saveHTMLFooter[$p]; }
28294 else if($p>=$target_page && $p<$start_page) { $newarr[$p+$n_toc] = $this->saveHTMLFooter[$p]; }
28295 else { $newarr[$p] = $this->saveHTMLFooter[$p]; }
28296 }
28297 ksort($newarr);
28298 $this->saveHTMLFooter = $newarr;
28299 }
28300
28301 // Update Internal Links
28302 if (count($this->internallink)) {
28303 foreach($this->internallink as $key=>$o) {
28304 if($o['PAGE']>=$start_page && $o['PAGE']<=$end_page) {
28305 $this->internallink[$key]['PAGE'] += ($target_page - $start_page);
28306 }
28307 else if($o['PAGE']>=$target_page && $o['PAGE']<$start_page) {
28308 $this->internallink[$key]['PAGE'] += $n_toc;
28309 }
28310 }
28311 }
28312
28313 // Update Links
28314 if (count($this->links)) {
28315 foreach($this->links as $key=>$o) {
28316 if($o[0]>=$start_page && $o[0]<=$end_page) {
28317 $this->links[$key][0] += ($target_page - $start_page);
28318 }
28319 if($o[0]>=$target_page && $o[0]<$start_page) {
28320 $this->links[$key][0] += $n_toc;
28321 }
28322 }
28323 }
28324
28325 // Update Form fields
28326 if (count($this->form->forms)) {
28327 foreach($this->form->forms as $key=>$f) {
28328 if($f['page']>=$start_page && $f['page']<=$end_page) {
28329 $this->form->forms[$key]['page'] += ($target_page - $start_page);
28330 }
28331 if($f['page']>=$target_page && $f['page']<$start_page) {
28332 $this->form->forms[$key]['page'] += $n_toc;
28333 }
28334 }
28335 }
28336
28337 /*-- ANNOTATIONS --*/
28338 // Update Annotations
28339 if (count($this->PageAnnots)) {
28340 $newarr = array();
28341 foreach($this->PageAnnots as $p=>$anno) {
28342 if($p>=$start_page && $p<=$end_page) {
28343 $np = $p + ($target_page - $start_page);
28344 foreach($anno as $o) {
28345 $newarr[$np][] = $o;
28346 }
28347 }
28348 else if($p>=$target_page && $p<$start_page) {
28349 $np = $p + $n_toc;
28350 foreach($anno as $o) {
28351 $newarr[$np][] = $o;
28352 }
28353 }
28354 else {
28355 $newarr[$p] = $this->PageAnnots[$p];
28356 }
28357 }
28358 $this->PageAnnots = $newarr;
28359 unset($newarr);
28360 }
28361 /*-- END ANNOTATIONS --*/
28362
28363 // Update PageNumSubstitutions
28364 if (count($this->PageNumSubstitutions)) {
28365 $newarr = array();
28366 foreach($this->PageNumSubstitutions AS $k=>$v) {
28367 if($this->PageNumSubstitutions[$k]['from']>=$start_page && $this->PageNumSubstitutions[$k]['from']<=$end_page) {
28368 $this->PageNumSubstitutions[$k]['from'] += ($target_page - $start_page);
28369 $newarr[$this->PageNumSubstitutions[$k]['from']] = $this->PageNumSubstitutions[$k];
28370 }
28371 else if($this->PageNumSubstitutions[$k]['from']>=$target_page && $this->PageNumSubstitutions[$k]['from']<$start_page) {
28372 $this->PageNumSubstitutions[$k]['from'] += $n_toc;
28373 $newarr[$this->PageNumSubstitutions[$k]['from']] = $this->PageNumSubstitutions[$k];
28374 }
28375 else {
28376 $newarr[$this->PageNumSubstitutions[$k]['from']] = $this->PageNumSubstitutions[$k];
28377 }
28378 }
28379
28380 if (!$sp_present) {
28381 $newarr[$target_page] = array('from'=>$target_page, 'suppress'=>$sp_suppress, 'reset'=>$sp_reset, 'type'=>$sp_type);
28382 }
28383 if (!$tp_present) {
28384 $newarr[($target_page + $n_toc)] = array('from'=>($target_page+$n_toc), 'suppress'=>$tp_suppress, 'reset'=>$tp_reset, 'type'=>$tp_type);
28385 }
28386 if (!$ep_present && $end_page>count($this->pages)) {
28387 $newarr[($end_page+1)] = array('from'=>($end_page+1), 'suppress'=>$ep_suppress, 'reset'=>$ep_reset, 'type'=>$ep_type);
28388 }
28389 ksort($newarr);
28390 $this->PageNumSubstitutions = array();
28391 foreach($newarr as $v) {
28392 $this->PageNumSubstitutions[] = $v;
28393 }
28394 }
28395 }
28396
28397 //======================================================
28398 function DeletePages($start_page, $end_page=-1) {
28399 // move a page/pages EARLIER in the document
28400 if ($end_page<1) { $end_page = $start_page; }
28401 $n_tod = $end_page - $start_page + 1;
28402 $last_page = count($this->pages);
28403 $n_atend = $last_page - $end_page + 1;
28404
28405 //move pages
28406 for($i=0;$i<$n_atend;$i++) {
28407 $this->pages[$start_page+$i]=$this->pages[$end_page+1+$i];
28408 }
28409 //delete pages
28410 for($i = 0;$i < $n_tod ;$i++)
28411 unset($this->pages[$last_page-$i]);
28412
28413
28414 /*-- BOOKMARKS --*/
28415 // Update Bookmarks
28416 foreach($this->BMoutlines as $i=>$o) {
28417 if($o['p']>=$end_page) { $this->BMoutlines[$i]['p'] -= $n_tod; }
28418 else if($p<$start_page) { unset($this->BMoutlines[$i]); }
28419 }
28420 /*-- END BOOKMARKS --*/
28421
28422 // Update Page Links
28423 if (count($this->PageLinks)) {
28424 $newarr = array();
28425 foreach($this->PageLinks as $i=>$o) {
28426 foreach($this->PageLinks[$i] as $key => $pl) {
28427 if (strpos($pl[4],'@')===0) {
28428 $p=substr($pl[4],1);
28429 if($p>$end_page) { $this->PageLinks[$i][$key][4] = '@'.($p - $n_tod); }
28430 else if($p<$start_page) { unset($this->PageLinks[$i][$key]); }
28431 }
28432 }
28433 if($i>$end_page) { $newarr[($i - $n_tod)] = $this->PageLinks[$i]; }
28434 else if($p<$start_page) { $newarr[$i] = $this->PageLinks[$i]; }
28435 }
28436 $this->PageLinks = $newarr;
28437 }
28438
28439 // OrientationChanges
28440 if (count($this->OrientationChanges)) {
28441 $newarr = array();
28442 foreach($this->OrientationChanges AS $p=>$v) {
28443 if($p>$end_page) { $newarr[($p - $t_tod)] = $this->OrientationChanges[$p]; }
28444 else if($p<$start_page) { $newarr[$p] = $this->OrientationChanges[$p]; }
28445 }
28446 ksort($newarr);
28447 $this->OrientationChanges = $newarr;
28448 }
28449
28450 // Page Dimensions
28451 if (count($this->pageDim)) {
28452 $newarr = array();
28453 foreach($this->pageDim AS $p=>$v) {
28454 if($p>$end_page) { $newarr[($p - $n_tod)] = $this->pageDim[$p]; }
28455 else if($p<$start_page) { $newarr[$p] = $this->pageDim[$p]; }
28456 }
28457 ksort($newarr);
28458 $this->pageDim = $newarr;
28459 }
28460
28461 // HTML Headers & Footers
28462 if (count($this->saveHTMLHeader)) {
28463 foreach($this->saveHTMLHeader AS $p=>$v) {
28464 if($p>end_page) { $newarr[($p - $n_tod)] = $this->saveHTMLHeader[$p]; }
28465 else if($p<$start_page) { $newarr[$p] = $this->saveHTMLHeader[$p]; }
28466 }
28467 ksort($newarr);
28468 $this->saveHTMLHeader = $newarr;
28469 }
28470 if (count($this->saveHTMLFooter)) {
28471 $newarr = array();
28472 foreach($this->saveHTMLFooter AS $p=>$v) {
28473 if($p>$end_page) { $newarr[($p - $n_tod)] = $this->saveHTMLFooter[$p]; }
28474 else if($p<$start_page) { $newarr[$p] = $this->saveHTMLFooter[$p]; }
28475 }
28476 ksort($newarr);
28477 $this->saveHTMLFooter = $newarr;
28478 }
28479
28480 // Update Internal Links
28481 foreach($this->internallink as $key=>$o) {
28482 if($o['PAGE']>$end_page) { $this->internallink[$key]['PAGE'] -= $n_tod; }
28483 else if($o['PAGE']<$start_page) { unset($this->internallink[$key]); }
28484 }
28485
28486 // Update Links
28487 foreach($this->links as $key=>$o) {
28488 if($o[0]>$end_page) { $this->links[$key][0] -= $n_tod; }
28489 else if($o[0]<$start_page) { unset($this->links[$key]); }
28490 }
28491
28492 // Update Form fields
28493 foreach($this->form->forms as $key=>$f) {
28494 if($f['page']>$end_page) { $this->form->forms[$key]['page'] -= $n_tod; }
28495 else if($f['page']<$start_page) { unset($this->form->forms[$key]); }
28496 }
28497
28498 /*-- ANNOTATIONS --*/
28499 // Update Annotations
28500 if (count($this->PageAnnots)) {
28501 $newarr = array();
28502 foreach($this->PageAnnots as $p=>$anno) {
28503 if($p>$end_page) { foreach($anno as $o) { $newarr[($p - $n_tod)][] = $o; } }
28504 else if($p<$start_page) { $newarr[$p] = $this->PageAnnots[$p]; }
28505 }
28506 ksort($newarr);
28507 $this->PageAnnots = $newarr;
28508 }
28509 /*-- END ANNOTATIONS --*/
28510
28511 // Update PageNumSubstitutions
28512 foreach($this->PageNumSubstitutions AS $k=>$v) {
28513 if($this->PageNumSubstitutions[$k]['from']>$end_page) { $this->PageNumSubstitutions[$k]['from'] -= $n_tod; }
28514 else if($this->PageNumSubstitutions[$k]['from']<$start_page) { unset($this->PageNumSubstitutions[$k]); }
28515 }
28516
28517 unset($newarr);
28518 $this->page = count($this->pages);
28519 }
28520
28521
28522 //======================================================
28523 /*-- INDEX --*/
28524 // FROM class PDF_Ref == INDEX
28525
28526 function Reference($txt) {
28527 $this->IndexEntry($txt);
28528 }
28529
28530
28531 function IndexEntry($txt, $xref='') {
28532 if ($xref) {
28533 $this->IndexEntrySee($txt,$xref);
28534 return;
28535 }
28536 $txt = strip_tags($txt);
28537 $txt = $this->purify_utf8_text($txt);
28538 if ($this->text_input_as_HTML) {
28539 $txt = $this->all_entities_to_utf8($txt);
28540 }
28541 if ($this->usingCoreFont) { $txt = mb_convert_encoding($txt,$this->mb_enc,'UTF-8'); }
28542
28543 $Present=0;
28544 $size=sizeof($this->Reference);
28545
28546 if ($this->directionality == 'rtl') { // *RTL*
28547 $txt = str_replace(':',' - ',$txt); // *RTL*
28548 } // *RTL*
28549 else { // *RTL*
28550 $txt = str_replace(':',', ',$txt);
28551 } // *RTL*
28552
28553
28554 //Search the reference (AND Ref/PageNo) in the array
28555 for ($i=0;$i<$size;$i++){
28556 if ($this->keep_block_together) {
28557 if (isset($this->ktReference[$i]['t']) && $this->ktReference[$i]['t']==$txt){
28558 $Present=1;
28559 if (!in_array($this->page,$this->ktReference[$i]['p'])) {
28560 $this->ktReference[$i]['op'] = $this->page;
28561 }
28562 }
28563 }
28564 /*-- TABLES --*/
28565 else if ($this->table_rotate) {
28566 if (isset($this->tbrot_Reference[$i]['t']) && $this->tbrot_Reference[$i]['t']==$txt){
28567 $Present=1;
28568 if (!in_array($this->page,$this->tbrot_Reference[$i]['p'])) {
28569 $this->tbrot_Reference[$i]['op'] = $this->page;
28570 }
28571 }
28572 }
28573 else if ($this->kwt) {
28574 if (isset($this->kwt_Reference[$i]['t']) && $this->kwt_Reference[$i]['t']==$txt){
28575 $Present=1;
28576 if (!in_array($this->page,$this->kwt_Reference[$i]['p'])) {
28577 $this->kwt_Reference[$i]['op'] = $this->page;
28578 }
28579 }
28580 }
28581 /*-- END TABLES --*/
28582 /*-- COLUMNS --*/
28583 else if ($this->ColActive) {
28584 if (isset($this->col_Reference[$i]['t']) && $this->col_Reference[$i]['t']==$txt){
28585 $Present=1;
28586 if (!in_array($this->page,$this->col_Reference[$i]['p'])) {
28587 $this->col_Reference[$i]['op'] = $this->page;
28588 }
28589 }
28590 }
28591 /*-- END COLUMNS --*/
28592 else {
28593 if (isset($this->Reference[$i]['t']) && $this->Reference[$i]['t']==$txt){
28594 $Present=1;
28595 if (!in_array($this->page,$this->Reference[$i]['p'])) {
28596 $this->Reference[$i]['p'][] = $this->page;
28597 }
28598 }
28599 }
28600 }
28601 //If not found, add it
28602 if ($Present==0) {
28603 $opr = array('t'=>$txt, 'op'=>$this->page);
28604 if ($this->keep_block_together) {
28605 $this->ktReference[]= $opr;
28606 }
28607 /*-- TABLES --*/
28608 else if ($this->table_rotate) {
28609 $this->tbrot_Reference[]= $opr;
28610 }
28611 else if ($this->kwt) {
28612 $this->kwt_Reference[]= $opr;
28613 }
28614 /*-- END TABLES --*/
28615 /*-- COLUMNS --*/
28616 else if ($this->ColActive) {
28617 $this->col_Reference[]= $opr;
28618 }
28619 /*-- END COLUMNS --*/
28620 else {
28621 $this->Reference[]=array('t'=>$txt,'p'=>array($this->page));
28622 }
28623 }
28624 }
28625
28626 // Added function to add a reference "Elephants. See Chickens"
28627 function ReferenceSee($txta,$txtb) {
28628 $this->IndexEntrySee($txta,$txtb);
28629 }
28630
28631 function IndexEntrySee($txta,$txtb) {
28632 $txta = strip_tags($txta);
28633 $txtb = strip_tags($txtb);
28634 $txta = $this->purify_utf8_text($txta);
28635 $txtb = $this->purify_utf8_text($txtb);
28636 if ($this->text_input_as_HTML) {
28637 $txta = $this->all_entities_to_utf8($txta);
28638 $txtb = $this->all_entities_to_utf8($txtb);
28639 }
28640 if ($this->usingCoreFont) {
28641 $txta = mb_convert_encoding($txta,$this->mb_enc,'UTF-8');
28642 $txtb = mb_convert_encoding($txtb,$this->mb_enc,'UTF-8');
28643 }
28644 if ($this->directionality == 'rtl') { // *RTL*
28645 $txta = str_replace(':',' - ',$txta); // *RTL*
28646 $txtb = str_replace(':',' - ',$txtb); // *RTL*
28647 } // *RTL*
28648 else { // *RTL*
28649 $txta = str_replace(':',', ',$txta);
28650 $txtb = str_replace(':',', ',$txtb);
28651 } // *RTL*
28652 $this->Reference[]=array('t'=>$txta.' - see '.$txtb,'p'=>array());
28653 }
28654
28655 function CreateReference($NbCol=1, $reffontsize='', $linespacing='', $offset=3, $usedivletters=1, $divlettfontsize='', $gap=5, $reffont='',$divlettfont='', $useLinking=false) {
28656 $this->CreateIndex($NbCol, $reffontsize, $linespacing, $offset, $usedivletters, $divlettfontsize, $gap, $reffont, $divlettfont, $useLinking);
28657 }
28658
28659 function CreateIndex($NbCol=1, $reffontsize='', $linespacing='', $offset=3, $usedivletters=1, $divlettfontsize='', $gap=5, $reffont='',$divlettfont='', $useLinking=false) {
28660 if (!$reffontsize) { $reffontsize = $this->default_font_size; }
28661 if (!$divlettfontsize) { $divlettfontsize = ($this->default_font_size * 1.8); }
28662 if (!$reffont) { $reffont = $this->default_font; }
28663 if (!$divlettfont) { $divlettfont = $reffont; }
28664 if (!$linespacing) { $linespacing= $this->default_lineheight_correction; }
28665 if ($this->ColActive) { $this->SetColumns(0); } // *COLUMNS*
28666 $size=sizeof($this->Reference);
28667 if ($size == 0) { return false; }
28668
28669
28670 if ($NbCol<2) {
28671 $NbCol = 1;
28672 $colWidth = $this->pgwidth;
28673 }
28674 else {
28675 $this->SetColumns($NbCol,'',$gap);
28676 $colWidth = $this->ColWidth;
28677 }
28678 if ($this->directionality == 'rtl') { $align = 'R'; }
28679 else { $align = 'L'; }
28680 $lett = '';
28681 if (!function_exists('cmp')) {
28682 function cmp ($a, $b) {
28683 return strnatcmp(strtolower($a['t']), strtolower($b['t']));
28684 }
28685 }
28686 //Alphabetic sort of the references
28687 usort($this->Reference, 'cmp');
28688 $size=sizeof($this->Reference);
28689 $this->breakpoints[$this->CurrCol][] = $this->y; // *COLUMNS*
28690
28691 $divlettjuststarted = false;
28692
28693 $this->OpenTag('DIV',array('STYLE'=>'line-height: '.$linespacing.'; font-family: '.$reffont.'; font-size: '.$reffontsize.'pt; '));
28694
28695 $last_lett = '';
28696 for ($i=0;$i<$size;$i++){
28697 if ($this->Reference[$i]['t']) {
28698 if ($usedivletters) {
28699
28700 $lett = mb_strtoupper(mb_substr($this->Reference[$i]['t'],0,1,$this->mb_enc ),$this->mb_enc );
28701 if ($lett != $last_lett) {
28702
28703 $save_bp = $this->breakpoints[$this->CurrCol]; // *COLUMNS*
28704 $divlettjuststarted = true;
28705
28706 if ($i>0) {
28707 $this->OpenTag('DIV',array('STYLE'=>'line-height: '.$linespacing.'; font-family: '.$divlettfont.'; font-size: '.$divlettfontsize.'pt; font-weight: bold; page-break-after: avoid; margin-top: 0.5em; margin-collapse: collapse; '));
28708 }
28709 else {
28710 $this->OpenTag('DIV',array('STYLE'=>'line-height: '.$linespacing.'; font-family: '.$divlettfont.'; font-size: '.$divlettfontsize.'pt; font-weight: bold; page-break-after: avoid; '));
28711 }
28712 $this->_saveTextBuffer($lett);
28713 $this->CloseTag('DIV');
28714 }
28715 }
28716
28717 $this->OpenTag('DIV',array('STYLE'=>'text-indent: -'.$offset.'mm; line-height: '.$linespacing.'; font-family: '.$reffont.'; font-size: '.$reffontsize.'pt; '));
28718
28719 /*-- RTL --*/
28720 // Change Arabic + Persian. to Presentation Forms
28721 if ($this->biDirectional) {
28722 $this->Reference[$i]['t'] = preg_replace("/([".$this->pregRTLchars."]+)/ue", '$this->ArabJoin(stripslashes(\'\\1\'))', $this->Reference[$i]['t'] );
28723 }
28724 /*-- END RTL --*/
28725
28726 // Font-specific ligature substitution for Indic fonts
28727 if (isset($this->CurrentFont['indic']) && $this->CurrentFont['indic']) $this->ConvertIndic($this->Reference[$i]['t']); // *INDIC*
28728
28729 $this->_saveTextBuffer($this->Reference[$i]['t']);
28730 $ppp = $this->Reference[$i]['p']; // = array of page numbers to point to
28731 if (count($ppp)) {
28732 sort($ppp);
28733 $newarr = array();
28734 $range_start = $ppp[0];
28735 $range_end = 0;
28736
28737 if (!$this->usingCoreFont) { $spacer = "\xc2\xa0 "; }
28738 else { $spacer = chr(160).' '; }
28739 $this->_saveTextBuffer($spacer);
28740 if ($this->directionality == 'rtl') { $sep = '.'; $joiner = '-'; }
28741 else { $sep = ', '; $joiner = '-'; }
28742 for ($zi=1;$zi<count($ppp);$zi++) {
28743 // RTL - Each number separately
28744 if ($this->directionality == 'rtl') {
28745 /*-- RTL --*/
28746 if ($zi<count($ppp)-1) {
28747 $txt = $sep . $this->docPageNum($ppp[$zi]);
28748 if ($useLinking) { $href = '@'.$ppp[$zi]; }
28749 else { $href = ''; }
28750 $this->_saveTextBuffer($txt, $href);
28751 }
28752 /*-- END RTL --*/
28753 }
28754
28755 else if ($ppp[$zi] == ($ppp[($zi-1)]+1)) {
28756 $range_end = $ppp[$zi];
28757 }
28758 else {
28759 if ($range_end) {
28760 if ($range_end == $range_start+1) {
28761 if ($useLinking) { $href = '@'.$range_start; }
28762 else { $href = ''; }
28763 $txt = $this->docPageNum($range_start) . $sep;
28764 $this->_saveTextBuffer($txt, $href);
28765 if ($useLinking) { $href = '@'.$ppp[$zi-1]; }
28766 else { $href = ''; }
28767 $txt = $this->docPageNum($ppp[$zi-1]) . $sep;
28768 $this->_saveTextBuffer($txt, $href);
28769 }
28770 else {
28771 if ($useLinking) { $href = '@'.$range_start; }
28772 else { $href = ''; }
28773 }
28774 }
28775 else {
28776 if ($useLinking) { $href = '@'.$ppp[$zi-1]; }
28777 else { $href = ''; }
28778 $txt = $this->docPageNum($ppp[$zi-1]) . $sep;
28779 $this->_saveTextBuffer($txt, $href);
28780 }
28781 $range_start = $ppp[$zi];
28782 $range_end = 0;
28783 }
28784 }
28785
28786 if ($range_end) {
28787 if ($range_end == $range_start+1) {
28788 if ($useLinking) { $href = '@'.$range_start; }
28789 else { $href = ''; }
28790 $txt = $this->docPageNum($range_start) . $sep;
28791 $this->_saveTextBuffer($txt, $href);
28792 if ($useLinking) { $href = '@'.$range_end; }
28793 else { $href = ''; }
28794 $txt = $this->docPageNum($range_end);
28795 $this->_saveTextBuffer($txt, $href);
28796 }
28797 else {
28798 if ($useLinking) { $href = '@'.$range_start; }
28799 else { $href = ''; }
28800 $txt = $this->docPageNum($range_start) . $joiner;
28801 $this->_saveTextBuffer($txt, $href);
28802 if ($useLinking) { $href = '@'.$range_end; }
28803 else { $href = ''; }
28804 $txt = $this->docPageNum($range_end);
28805 $this->_saveTextBuffer($txt, $href);
28806 }
28807 }
28808 else {
28809 if ($useLinking) { $href = '@'.$ppp[(count($ppp)-1)]; }
28810 else { $href = ''; }
28811 $txt = $this->docPageNum($ppp[(count($ppp)-1)]);
28812 $this->_saveTextBuffer($txt, $href);
28813 }
28814 }
28815 }
28816 $this->CloseTag('DIV');
28817
28818 if ($divlettjuststarted) { $this->breakpoints[$this->CurrCol] = $save_bp; } // *COLUMNS*
28819 $divlettjuststarted = false;
28820
28821 $this->breakpoints[$this->CurrCol][] = $this->y; // *COLUMNS*
28822 $last_lett = $lett;
28823 }
28824 $this->CloseTag('DIV');
28825 $this->breakpoints[$this->CurrCol][] = $this->y; // *COLUMNS*
28826 if ($this->ColActive) { $this->SetColumns(0); } // *COLUMNS*
28827 }
28828 /*-- END INDEX --*/
28829
28830
28831 function AcceptPageBreak() {
28832 if (count($this->cellBorderBuffer)) { $this->printcellbuffer(); } // *TABLES*
28833 /*-- COLUMNS --*/
28834 if ($this->ColActive==1) {
28835 if($this->CurrCol<$this->NbCol-1) {
28836 //Go to the next column
28837 $this->CurrCol++;
28838 $this->SetCol($this->CurrCol);
28839 $this->y=$this->y0;
28840 $this->ChangeColumn=1; // Number (and direction) of columns changed +1, +2, -2 etc.
28841 // DIRECTIONALITY RTL
28842 if ($this->directionality == 'rtl') { $this->ChangeColumn = -($this->ChangeColumn); } // *RTL*
28843
28844 //Stay on the page
28845 return false;
28846 }
28847 else {
28848 //Go back to the first column - NEW PAGE
28849 if (count($this->columnbuffer)) { $this->printcolumnbuffer(); }
28850 $this->SetCol(0);
28851 $this->y0 = $this->tMargin;
28852 $this->ChangeColumn= -($this->NbCol-1);
28853 // DIRECTIONALITY RTL
28854 if ($this->directionality == 'rtl') { $this->ChangeColumn = -($this->ChangeColumn); } // *RTL*
28855 //Page break
28856 return true;
28857 }
28858 }
28859 /*-- END COLUMNS --*/
28860 /*-- TABLES --*/
28861 else if ($this->table_rotate) {
28862 if ($this->tablebuffer) { $this->printtablebuffer(); }
28863 return true;
28864 }
28865 /*-- END TABLES --*/
28866 else { // *COLUMNS*
28867 $this->ChangeColumn=0;
28868 return $this->autoPageBreak;
28869 } // *COLUMNS*
28870 return $this->autoPageBreak;
28871 }
28872
28873
28874 //----------- COLUMNS ---------------------
28875 /*-- COLUMNS --*/
28876
28877 function SetColumns($NbCol,$vAlign='',$gap=5) {
28878 // NbCol = number of columns
28879 // CurrCol = Number of the current column starting at 0
28880 // Called externally to set columns on/off and number
28881 // Integer 2 upwards sets columns on to that number
28882 // Anything less than 2 turns columns off
28883 if ($NbCol<2) { // SET COLUMNS OFF
28884 if ($this->ColActive) {
28885 $this->ColActive=0;
28886 if (count($this->columnbuffer)) { $this->printcolumnbuffer(); }
28887 $this->NbCol=1;
28888 $this->ResetMargins();
28889 $this->pgwidth = $this->w - $this->lMargin - $this->rMargin;
28890 $this->divwidth = 0;
28891 $this->Ln();
28892 }
28893 $this->ColActive=0;
28894 $this->columnbuffer = array();
28895 $this->ColDetails = array();
28896 $this->columnLinks = array();
28897 $this->columnAnnots = array();
28898 $this->columnForms = array();
28899 $this->col_Reference = array();
28900 $this->col_BMoutlines = array();
28901 $this->col_toc = array();
28902 $this->breakpoints = array();
28903 }
28904 else { // SET COLUMNS ON
28905 if ($this->ColActive) {
28906 $this->ColActive=0;
28907 if (count($this->columnbuffer)) { $this->printcolumnbuffer(); }
28908 $this->ResetMargins();
28909 }
28910 if (isset($this->y) && $this->y>$this->tMargin) $this->Ln();
28911 $this->NbCol=$NbCol;
28912 $this->ColGap = $gap;
28913 $this->divwidth = 0;
28914 $this->ColActive=1;
28915 $this->ColumnAdjust = true; // enables column height adjustment for the page
28916 $this->columnbuffer = array();
28917 $this->ColDetails = array();
28918 $this->columnLinks = array();
28919 $this->columnAnnots = array();
28920 $this->columnForms = array();
28921 $this->col_Reference = array();
28922 $this->col_BMoutlines = array();
28923 $this->col_toc = array();
28924 $this->breakpoints = array();
28925 if ((strtoupper($vAlign) == 'J') || (strtoupper($vAlign) == 'JUSTIFY')) { $vAlign = 'J'; }
28926 else { $vAlign = ''; }
28927 $this->colvAlign = $vAlign;
28928 //Save the ordinate
28929 $absL = $this->DeflMargin-($gap/2);
28930 $absR = $this->DefrMargin-($gap/2);
28931 $PageWidth = $this->w-$absL-$absR; // virtual pagewidth for calculation only
28932 $ColWidth = (($PageWidth - ($gap * ($NbCol)))/$NbCol);
28933 $this->ColWidth = $ColWidth;
28934 /*-- RTL --*/
28935
28936 if ($this->directionality == 'rtl') {
28937 for ($i=0;$i<$this->NbCol;$i++) {
28938 $this->ColL[$i] = $absL + ($gap/2) + (($NbCol - ($i+1))*($PageWidth/$NbCol)) ;
28939 $this->ColR[$i] = $this->ColL[$i] + $ColWidth; // NB This is not R margin -> R pos
28940 }
28941 }
28942 else {
28943 /*-- END RTL --*/
28944 for ($i=0;$i<$this->NbCol;$i++) {
28945 $this->ColL[$i] = $absL + ($gap/2) + ($i* ($PageWidth/$NbCol) );
28946 $this->ColR[$i] = $this->ColL[$i] + $ColWidth; // NB This is not R margin -> R pos
28947 }
28948 } // *RTL*
28949 $this->pgwidth = $ColWidth;
28950 $this->SetCol(0);
28951 $this->y0=$this->y;
28952 }
28953 $this->x = $this->lMargin;
28954 }
28955
28956 function SetCol($CurrCol) {
28957 // Used internally to set column by number: 0 is 1st column
28958 //Set position on a column
28959 $this->CurrCol=$CurrCol;
28960 $x = $this->ColL[$CurrCol];
28961 $xR = $this->ColR[$CurrCol]; // NB This is not R margin -> R pos
28962 if (($this->mirrorMargins) && (($this->page)%2==0)) { // EVEN
28963 $x += $this->MarginCorrection ;
28964 $xR += $this->MarginCorrection ;
28965 }
28966 $this->SetMargins($x,($this->w - $xR),$this->tMargin);
28967 }
28968
28969 function AddColumn() {
28970 $this->NewColumn();
28971 $this->ColumnAdjust = false; // disables all column height adjustment for the page.
28972 }
28973 function NewColumn() {
28974 if ($this->ColActive==1) {
28975 if($this->CurrCol<$this->NbCol-1) {
28976 //Go to the next column
28977 $this->CurrCol++;
28978 $this->SetCol($this->CurrCol);
28979 $this->y = $this->y0;
28980 $this->ChangeColumn=1;
28981 // DIRECTIONALITY RTL
28982 if ($this->directionality == 'rtl') { $this->ChangeColumn = -($this->ChangeColumn); } // *RTL*
28983 //Stay on the page
28984 }
28985 else {
28986 //Go back to the first column
28987 //Page break
28988 if (count($this->columnbuffer)) { $this->printcolumnbuffer(); }
28989 $this->AddPage($this->CurOrientation);
28990 $this->SetCol(0);
28991 $this->y0 = $this->tMargin;
28992 $this->ChangeColumn= -($this->NbCol-1);
28993 // DIRECTIONALITY RTL
28994 if ($this->directionality == 'rtl') { $this->ChangeColumn = -($this->ChangeColumn); } // *RTL*
28995 }
28996 $this->x = $this->lMargin;
28997 }
28998 else {
28999 $this->AddPage($this->CurOrientation);
29000 }
29001 }
29002
29003 function printcolumnbuffer() {
29004 // Columns ended (but page not ended) -> try to match all columns - unless disabled by using a custom column-break
29005 if (!$this->ColActive && $this->ColumnAdjust && !$this->keepColumns) {
29006 // Calculate adjustment to add to each column to calculate rel_y value
29007 $this->ColDetails[0]['add_y'] = 0;
29008 $last_col = 0;
29009 // Recursively add previous column's height
29010 for($i=1;$i<$this->NbCol;$i++) {
29011 if (isset($this->ColDetails[$i]['bottom_margin']) && $this->ColDetails[$i]['bottom_margin']) { // If any entries in the column
29012 $this->ColDetails[$i]['add_y'] = ($this->ColDetails[$i-1]['bottom_margin'] - $this->y0) + $this->ColDetails[$i-1]['add_y'];
29013 $last_col = $i; // Last column actually printed
29014 }
29015 }
29016
29017 // Calculate value for each position sensitive entry as though for one column
29018 foreach($this->columnbuffer AS $key=>$s) {
29019 $t = $s['s'];
29020 if ($t == 'ACROFORM') {
29021 $this->columnbuffer[$key]['rel_y'] = $s['y'] + $this->ColDetails[$s['col']]['add_y'] - $this->y0;
29022 $this->columnbuffer[$key]['s'] = '';
29023 }
29024 else if (preg_match('/BT \d+\.\d\d+ (\d+\.\d\d+) Td/',$t)) {
29025 $this->columnbuffer[$key]['rel_y'] = $s['y'] + $this->ColDetails[$s['col']]['add_y'] - $this->y0;
29026 }
29027 else if (preg_match('/\d+\.\d\d+ (\d+\.\d\d+) \d+\.\d\d+ [\-]{0,1}\d+\.\d\d+ re/',$t)) {
29028 $this->columnbuffer[$key]['rel_y'] = $s['y'] + $this->ColDetails[$s['col']]['add_y'] - $this->y0;
29029 }
29030 else if (preg_match('/\d+\.\d\d+ (\d+\.\d\d+) m/',$t)) {
29031 $this->columnbuffer[$key]['rel_y'] = $s['y'] + $this->ColDetails[$s['col']]['add_y'] - $this->y0;
29032 }
29033 else if (preg_match('/\d+\.\d\d+ (\d+\.\d\d+) l/',$t)) {
29034 $this->columnbuffer[$key]['rel_y'] = $s['y'] + $this->ColDetails[$s['col']]['add_y'] - $this->y0;
29035 }
29036 else if (preg_match('/q \d+\.\d\d+ 0 0 \d+\.\d\d+ \d+\.\d\d+ (\d+\.\d\d+) cm \/(I|FO)\d+ Do Q/',$t)) {
29037 $this->columnbuffer[$key]['rel_y'] = $s['y'] + $this->ColDetails[$s['col']]['add_y'] - $this->y0;
29038 }
29039 else if (preg_match('/\d+\.\d\d+ (\d+\.\d\d+) \d+\.\d\d+ \d+\.\d\d+ \d+\.\d\d+ \d+\.\d\d+ c/',$t)) {
29040 $this->columnbuffer[$key]['rel_y'] = $s['y'] + $this->ColDetails[$s['col']]['add_y'] - $this->y0;
29041 }
29042 }
29043 foreach($this->internallink AS $key => $f) {
29044 if (is_array($f) && isset($f['col'])) {
29045 $this->internallink[$key]['rel_y'] = $f['Y'] + $this->ColDetails[$f['col']]['add_y'] - $this->y0;
29046 }
29047 }
29048
29049 $breaks = array();
29050 foreach($this->breakpoints AS $c => $bpa) {
29051 foreach($bpa AS $rely) {
29052 $breaks[] = $rely + $this->ColDetails[$c]['add_y'] - $this->y0;
29053 }
29054 }
29055
29056 if (isset($this->ColDetails[$last_col]['bottom_margin'])) { $lcbm = $this->ColDetails[$last_col]['bottom_margin']; }
29057 else { $lcbm = 0; }
29058 $sum_h = $this->ColDetails[$last_col]['add_y'] + $lcbm - $this->y0;
29059 //$sum_h = max($this->ColDetails[$last_col]['add_y'] + $this->ColDetails[$last_col]['bottom_margin'] - $this->y0, end($breaks));
29060 $target_h = ($sum_h / $this->NbCol);
29061
29062 $cbr = array();
29063 for($i=1;$i<$this->NbCol;$i++) {
29064 $th = ($sum_h * $i / $this->NbCol);
29065 foreach($breaks AS $bk=>$val) {
29066 if ($val > $th) {
29067 if (($val-$th) < ($th-$breaks[$bk-1])) { $cbr[$i-1] = $val; }
29068 else { $cbr[$i-1] = $breaks[$bk-1]; }
29069 break;
29070 }
29071 }
29072 }
29073 $cbr[($this->NbCol-1)] = $sum_h;
29074
29075 // Now update the columns - divide into columns of approximately equal value
29076 $last_new_col = 0;
29077 $yadj = 0; // mm
29078 $xadj = 0;
29079 $last_col_bottom = 0;
29080 $lowest_bottom_y = 0;
29081 $block_bottom = 0;
29082 $newcolumn = 0;
29083 foreach($this->columnbuffer AS $key=>$s) {
29084 if (isset($s['rel_y'])) { // only process position sensitive data
29085 if ($s['rel_y'] >= $cbr[$newcolumn]) {
29086 $newcolumn++;
29087 }
29088 else {
29089 $newcolumn = $last_new_col ;
29090 }
29091
29092
29093 $block_bottom = max($block_bottom,($s['rel_y']+$s['h']));
29094
29095 if ($this->directionality == 'rtl') { // *RTL*
29096 $xadj = -(($newcolumn - $s['col']) * ($this->ColWidth + $this->ColGap)); // *RTL*
29097 } // *RTL*
29098 else { // *RTL*
29099 $xadj = ($newcolumn - $s['col']) * ($this->ColWidth + $this->ColGap);
29100 } // *RTL*
29101
29102 if ($last_new_col != $newcolumn) { // Added new column
29103 $last_col_bottom = $this->columnbuffer[$key]['rel_y'];
29104 $block_bottom = 0;
29105 }
29106 $yadj = ($s['rel_y'] - $s['y']) - ($last_col_bottom)+$this->y0;
29107 // callback function
29108 $t = $s['s'];
29109 $t = preg_replace('/BT (\d+\.\d\d+) (\d+\.\d\d+) Td/e',"\$this->columnAdjustAdd('Td',_MPDFK,$xadj,$yadj,'\\1','\\2')",$t);
29110 $t = preg_replace('/(\d+\.\d\d+) (\d+\.\d\d+) (\d+\.\d\d+) ([\-]{0,1}\d+\.\d\d+) re/e',"\$this->columnAdjustAdd('re',_MPDFK,$xadj,$yadj,'\\1','\\2','\\3','\\4')",$t);
29111 $t = preg_replace('/(\d+\.\d\d+) (\d+\.\d\d+) l/e',"\$this->columnAdjustAdd('l',_MPDFK,$xadj,$yadj,'\\1','\\2')",$t);
29112 $t = preg_replace('/q (\d+\.\d\d+) 0 0 (\d+\.\d\d+) (\d+\.\d\d+) (\d+\.\d\d+) cm \/(I|FO)/e',"\$this->columnAdjustAdd('img',_MPDFK,$xadj,$yadj,'\\1','\\2','\\3','\\4','\\5')",$t);
29113 $t = preg_replace('/(\d+\.\d\d+) (\d+\.\d\d+) m/e',"\$this->columnAdjustAdd('draw',_MPDFK,$xadj,$yadj,'\\1','\\2')",$t);
29114 $t = preg_replace('/(\d+\.\d\d+) (\d+\.\d\d+) (\d+\.\d\d+) (\d+\.\d\d+) (\d+\.\d\d+) (\d+\.\d\d+) c/e',"\$this->columnAdjustAdd('bezier',_MPDFK,$xadj,$yadj,'\\1','\\2','\\3','\\4','\\5','\\6')",$t);
29115
29116 $this->columnbuffer[$key]['s'] = $t;
29117 $this->columnbuffer[$key]['newcol'] = $newcolumn;
29118 $this->columnbuffer[$key]['newy'] = $s['y'] + $yadj;
29119 $last_new_col = $newcolumn;
29120 $clb = $s['y'] + $yadj + $s['h'] ; // bottom_margin of current
29121 if ((isset($this->ColDetails[$newcolumn]['max_bottom']) && $clb > $this->ColDetails[$newcolumn]['max_bottom']) || (!isset($this->ColDetails[$newcolumn]['max_bottom']) && $clb)) { $this->ColDetails[$newcolumn]['max_bottom'] = $clb; }
29122 if ($clb > $lowest_bottom_y) { $lowest_bottom_y = $clb; }
29123 // Adjust LINKS
29124 if (isset($this->columnLinks[$s['col']][INTVAL($s['x'])][INTVAL($s['y'])])) {
29125 $ref = $this->columnLinks[$s['col']][INTVAL($s['x'])][INTVAL($s['y'])];
29126 $this->PageLinks[$this->page][$ref][0] += ($xadj*_MPDFK);
29127 $this->PageLinks[$this->page][$ref][1] -= ($yadj*_MPDFK);
29128 unset($this->columnLinks[$s['col']][INTVAL($s['x'])][INTVAL($s['y'])]);
29129 }
29130 // Adjust FORM FIELDS
29131 if (isset($this->columnForms[$s['col']][INTVAL($s['x'])][INTVAL($s['y'])])) {
29132 $ref = $this->columnForms[$s['col']][INTVAL($s['x'])][INTVAL($s['y'])];
29133 $this->form->forms[$ref]['x'] += ($xadj);
29134 $this->form->forms[$ref]['y'] += ($yadj);
29135 unset($this->columnForms[$s['col']][INTVAL($s['x'])][INTVAL($s['y'])]);
29136 }
29137 /*-- ANNOTATIONS --*/
29138 if (isset($this->columnAnnots[$s['col']][INTVAL($s['x'])][INTVAL($s['y'])])) {
29139 $ref = $this->columnAnnots[$s['col']][INTVAL($s['x'])][INTVAL($s['y'])];
29140 if ($this->PageAnnots[$this->page][$ref]['x'] < 0) {
29141 $this->PageAnnots[$this->page][$ref]['x'] -= ($xadj);
29142 }
29143 else {
29144 $this->PageAnnots[$this->page][$ref]['x'] += ($xadj);
29145 }
29146 $this->PageAnnots[$this->page][$ref]['y'] += ($yadj); // unlike PageLinks, Page annots has y values from top in mm
29147 unset($this->columnAnnots[$s['col']][INTVAL($s['x'])][INTVAL($s['y'])]);
29148 }
29149 /*-- END ANNOTATIONS --*/
29150 }
29151 }
29152
29153 /*-- BOOKMARKS --*/
29154 // Adjust Bookmarks
29155 foreach($this->col_BMoutlines AS $v) {
29156 $this->BMoutlines[]=array('t'=>$v['t'],'l'=>$v['l'],'y'=>$this->y0,'p'=>$v['p']);
29157 }
29158 /*-- END BOOKMARKS --*/
29159
29160 /*-- INDEX --*/
29161 // Adjust Reference (index)
29162 foreach($this->col_Reference AS $v) {
29163 $Present=0;
29164 //Search the reference (AND Ref/PageNo) in the array
29165 for ($i=0;$i<count($this->Reference);$i++){
29166 if ($this->Reference[$i]['t']==$v['t']){
29167 $Present=1;
29168 if (!in_array($v['op'],$this->Reference[$i]['p'])) {
29169 $this->Reference[$i]['p'][] = $v['op'];
29170 }
29171 }
29172 }
29173 if ($Present==0) {
29174 $this->Reference[]=array('t'=>$v['t'],'p'=>array($v['op']));
29175 }
29176 }
29177 /*-- END INDEX --*/
29178
29179 /*-- TOC --*/
29180
29181 // Adjust ToC
29182 foreach($this->col_toc AS $v) {
29183 $this->tocontents->_toc[]=array('t'=>$v['t'],'l'=>$v['l'],'p'=>$v['p'],'link'=>$v['link'],'toc_id'=>$v['toc_id']);
29184 $this->links[$v['link']][1] = $this->y0;
29185 }
29186 /*-- END TOC --*/
29187
29188 // Adjust column length to be equal
29189 if ($this->colvAlign == 'J') {
29190 foreach($this->columnbuffer AS $key=>$s) {
29191 if (isset($s['rel_y'])) { // only process position sensitive data
29192 // Set ratio to expand y values or heights
29193 if (isset($this->ColDetails[$s['newcol']]['max_bottom']) && $this->ColDetails[$s['newcol']]['max_bottom'] && $this->ColDetails[$s['newcol']]['max_bottom']!=$this->y0) {
29194 $ratio = ($lowest_bottom_y - ($this->y0)) / ($this->ColDetails[$s['newcol']]['max_bottom'] - ($this->y0));
29195 }
29196 else { $ratio = 1; }
29197 if (($ratio > 1) && ($ratio <= $this->max_colH_correction)) {
29198 $yadj = ($s['newy'] - $this->y0) * ($ratio - 1);
29199
29200 // Adjust LINKS
29201 if (isset($this->columnLinks[$s['col']][INTVAL($s['x'])][INTVAL($s['y'])])) {
29202 $ref = $this->columnLinks[$s['col']][INTVAL($s['x'])][INTVAL($s['y'])];
29203 $this->PageLinks[$this->page][$ref][1] -= ($yadj*_MPDFK); // y value
29204 $this->PageLinks[$this->page][$ref][3] *= $ratio; // height
29205 unset($this->columnLinks[$s['col']][INTVAL($s['x'])][INTVAL($s['y'])]);
29206 }
29207 // Adjust FORM FIELDS
29208 if (isset($this->columnForms[$s['col']][INTVAL($s['x'])][INTVAL($s['y'])])) {
29209 $ref = $this->columnForms[$s['col']][INTVAL($s['x'])][INTVAL($s['y'])];
29210 $this->form->forms[$ref]['x'] += ($xadj);
29211 $this->form->forms[$ref]['y'] += ($yadj);
29212 unset($this->columnForms[$s['col']][INTVAL($s['x'])][INTVAL($s['y'])]);
29213 }
29214 /*-- ANNOTATIONS --*/
29215 if (isset($this->columnAnnots[$s['col']][INTVAL($s['x'])][INTVAL($s['y'])])) {
29216 $ref = $this->columnAnnots[$s['col']][INTVAL($s['x'])][INTVAL($s['y'])];
29217 $this->PageAnnots[$this->page][$ref]['y'] += ($yadj);
29218 unset($this->columnAnnots[$s['col']][INTVAL($s['x'])][INTVAL($s['y'])]);
29219 }
29220 /*-- END ANNOTATIONS --*/
29221 }
29222 }
29223 }
29224 foreach($this->internallink AS $key => $f) {
29225 if (is_array($f) && isset($f['col'])) {
29226 $last_col_bottom = 0;
29227 for ($nbc=0; $nbc<$this->NbCol; $nbc++) {
29228 if ($f['rel_y'] >= $cbr[$nbc]) { $last_col_bottom = $cbr[$nbc]; }
29229 }
29230 $yadj = ($f['rel_y'] - $f['Y']) - $last_col_bottom + $this->y0;
29231 $f['Y'] += $yadj;
29232 unset($f['col']);
29233 unset($f['rel_y']);
29234 $this->internallink[$key] = $f;
29235 }
29236 }
29237
29238 $last_col = -1;
29239 $trans_on = false;
29240 foreach($this->columnbuffer AS $key=>$s) {
29241 if (isset($s['rel_y'])) { // only process position sensitive data
29242 // Set ratio to expand y values or heights
29243 if (isset($this->ColDetails[$s['newcol']]['max_bottom']) && $this->ColDetails[$s['newcol']]['max_bottom'] && $this->ColDetails[$s['newcol']]['max_bottom']!=$this->y0) {
29244 $ratio = ($lowest_bottom_y - ($this->y0)) / ($this->ColDetails[$s['newcol']]['max_bottom'] - ($this->y0));
29245 }
29246 else { $ratio = 1; }
29247 if (($ratio > 1) && ($ratio <= $this->max_colH_correction)) {
29248 //Start Transformation
29249 $this->pages[$this->page] .= $this->StartTransform(true)."\n";
29250 $this->pages[$this->page] .= $this->transformScale(100, $ratio*100, $x='', $this->y0, true)."\n";
29251 $trans_on = true;
29252 }
29253 }
29254 // Now output the adjusted values
29255 $this->pages[$this->page] .= $s['s']."\n";
29256 if (isset($s['rel_y']) && ($ratio > 1) && ($ratio <= $this->max_colH_correction)) { // only process position sensitive data
29257 //Stop Transformation
29258 $this->pages[$this->page] .= $this->StopTransform(true)."\n";
29259 $trans_on = false;
29260 }
29261 }
29262 if ($trans_on) { $this->pages[$this->page] .= $this->StopTransform(true)."\n"; }
29263 }
29264 else { // if NOT $this->colvAlign == 'J'
29265 // Now output the adjusted values
29266 foreach($this->columnbuffer AS $s) {
29267 $this->pages[$this->page] .= $s['s']."\n";
29268 }
29269 }
29270 if ($lowest_bottom_y > 0) { $this->y = $lowest_bottom_y ; }
29271 }
29272
29273 // Columns not ended but new page -> align columns (can leave the columns alone - just tidy up the height)
29274 else if ($this->colvAlign == 'J' && $this->ColumnAdjust && !$this->keepColumns) {
29275 // calculate the lowest bottom margin
29276 $lowest_bottom_y = 0;
29277 foreach($this->columnbuffer AS $key=>$s) {
29278 // Only process output data
29279 $t = $s['s'];
29280 if ($t == 'ACROFORM' || (preg_match('/BT \d+\.\d\d+ (\d+\.\d\d+) Td/',$t)) || (preg_match('/\d+\.\d\d+ (\d+\.\d\d+) \d+\.\d\d+ [\-]{0,1}\d+\.\d\d+ re/',$t)) ||
29281 (preg_match('/\d+\.\d\d+ (\d+\.\d\d+) l/',$t)) ||
29282 (preg_match('/q \d+\.\d\d+ 0 0 \d+\.\d\d+ \d+\.\d\d+ (\d+\.\d\d+) cm \/(I|FO)\d+ Do Q/',$t)) ||
29283 (preg_match('/\d+\.\d\d+ (\d+\.\d\d+) m/',$t)) ||
29284 (preg_match('/\d+\.\d\d+ (\d+\.\d\d+) \d+\.\d\d+ \d+\.\d\d+ \d+\.\d\d+ \d+\.\d\d+ c/',$t)) ) {
29285
29286 $clb = $s['y'] + $s['h'];
29287 if ((isset($this->ColDetails[$s['col']]['max_bottom']) && $clb > $this->ColDetails[$s['col']]['max_bottom']) || !isset($this->ColDetails[$s['col']]['max_bottom'])) { $this->ColDetails[$s['col']]['max_bottom'] = $clb; }
29288 if ($clb > $lowest_bottom_y) { $lowest_bottom_y = $clb; }
29289 $this->columnbuffer[$key]['rel_y'] = $s['y']; // Marks position sensitive data to process later
29290 if ($t == 'ACROFORM') { $this->columnbuffer[$key]['s'] = ''; }
29291 }
29292 }
29293 // Adjust column length equal
29294 foreach($this->columnbuffer AS $key=>$s) {
29295 // Set ratio to expand y values or heights
29296 if (isset($this->ColDetails[$s['col']]['max_bottom']) && $this->ColDetails[$s['col']]['max_bottom']) {
29297 $ratio = ($lowest_bottom_y - ($this->y0)) / ($this->ColDetails[$s['col']]['max_bottom'] - ($this->y0));
29298 }
29299 else { $ratio = 1; }
29300 if (($ratio > 1) && ($ratio <= $this->max_colH_correction)) {
29301 $yadj = ($s['y'] - $this->y0) * ($ratio - 1);
29302
29303 // Adjust LINKS
29304 if (isset($s['rel_y'])) { // only process position sensitive data
29305 // otherwise triggers for all entries in column buffer (.e.g. formatting) and makes below adjustments more than once
29306 if (isset($this->columnLinks[$s['col']][INTVAL($s['x'])][INTVAL($s['y'])])) {
29307 $ref = $this->columnLinks[$s['col']][INTVAL($s['x'])][INTVAL($s['y'])];
29308 $this->PageLinks[$this->page][$ref][1] -= ($yadj*_MPDFK); // y value
29309 $this->PageLinks[$this->page][$ref][3] *= $ratio; // height
29310 unset($this->columnLinks[$s['col']][INTVAL($s['x'])][INTVAL($s['y'])]);
29311 }
29312 // Adjust FORM FIELDS
29313 if (isset($this->columnForms[$s['col']][INTVAL($s['x'])][INTVAL($s['y'])])) {
29314 $ref = $this->columnForms[$s['col']][INTVAL($s['x'])][INTVAL($s['y'])];
29315 $this->form->forms[$ref]['x'] += ($xadj);
29316 $this->form->forms[$ref]['y'] += ($yadj);
29317 unset($this->columnForms[$s['col']][INTVAL($s['x'])][INTVAL($s['y'])]);
29318 }
29319 /*-- ANNOTATIONS --*/
29320 if (isset($this->columnAnnots[$s['col']][INTVAL($s['x'])][INTVAL($s['y'])])) {
29321 $ref = $this->columnAnnots[$s['col']][INTVAL($s['x'])][INTVAL($s['y'])];
29322 $this->PageAnnots[$this->page][$ref]['y'] += ($yadj);
29323 unset($this->columnAnnots[$s['col']][INTVAL($s['x'])][INTVAL($s['y'])]);
29324 }
29325 /*-- END ANNOTATIONS --*/
29326 }
29327 }
29328 }
29329
29330 /*-- BOOKMARKS --*/
29331
29332 // Adjust Bookmarks
29333 foreach($this->col_BMoutlines AS $v) {
29334 $this->BMoutlines[]=array('t'=>$v['t'],'l'=>$v['l'],'y'=>$this->y0,'p'=>$v['p']);
29335 }
29336 /*-- END BOOKMARKS --*/
29337
29338 /*-- INDEX --*/
29339
29340 // Adjust Reference (index)
29341 foreach($this->col_Reference AS $v) {
29342 $Present=0;
29343 //Search the reference (AND Ref/PageNo) in the array
29344 for ($i=0;$i<count($this->Reference);$i++){
29345 if ($this->Reference[$i]['t']==$v['t']){
29346 $Present=1;
29347 if (!in_array($v['op'],$this->Reference[$i]['p'])) {
29348 $this->Reference[$i]['p'][] = $v['op'];
29349 }
29350 }
29351 }
29352 if ($Present==0) {
29353 $this->Reference[]=array('t'=>$v['t'],'p'=>array($v['op']));
29354 }
29355 }
29356 /*-- END INDEX --*/
29357
29358 /*-- TOC --*/
29359
29360 // Adjust ToC
29361 foreach($this->col_toc AS $v) {
29362 $this->tocontents->_toc[]=array('t'=>$v['t'],'l'=>$v['l'],'p'=>$v['p'],'link'=>$v['link'],'toc_id'=>$v['toc_id']);
29363 $this->links[$v['link']][1] = $this->y0;
29364 }
29365 /*-- END TOC --*/
29366 $trans_on = false;
29367 foreach($this->columnbuffer AS $key=>$s) {
29368 if (isset($s['rel_y'])) { // only process position sensitive data
29369 // Set ratio to expand y values or heights
29370 if ($this->ColDetails[$s['col']]['max_bottom']) {
29371 $ratio = ($lowest_bottom_y - ($this->y0)) / ($this->ColDetails[$s['col']]['max_bottom'] - ($this->y0));
29372 }
29373 else { $ratio = 1; }
29374 if (($ratio > 1) && ($ratio <= $this->max_colH_correction)) {
29375 //Start Transformation
29376 $this->pages[$this->page] .= $this->StartTransform(true)."\n";
29377 $this->pages[$this->page] .= $this->transformScale(100, $ratio*100, $x='', $this->y0, true)."\n";
29378 $trans_on = true;
29379 }
29380 }
29381 // Now output the adjusted values
29382 $this->pages[$this->page] .= $s['s']."\n";
29383 if (isset($s['rel_y']) && ($ratio > 1) && ($ratio <= $this->max_colH_correction)) {
29384 //Stop Transformation
29385 $this->pages[$this->page] .= $this->StopTransform(true)."\n";
29386 $trans_on = false; // mPDF 5.1.001
29387 }
29388 }
29389 if ($trans_on) { $this->pages[$this->page] .= $this->StopTransform(true)."\n"; }
29390
29391 if ($lowest_bottom_y > 0) { $this->y = $lowest_bottom_y ; }
29392 }
29393
29394
29395 // Just reproduce the page as it was
29396 else {
29397 // If page has not ended but height adjustment was disabled by custom column-break - adjust y
29398 $lowest_bottom_y = 0;
29399 if (!$this->ColActive && (!$this->ColumnAdjust || $this->keepColumns)) {
29400 // calculate the lowest bottom margin
29401 foreach($this->columnbuffer AS $key=>$s) {
29402 // Only process output data
29403 $t = $s['s'];
29404 if ($t == 'ACROFORM' || (preg_match('/BT \d+\.\d\d+ (\d+\.\d\d+) Td/',$t)) || (preg_match('/\d+\.\d\d+ (\d+\.\d\d+) \d+\.\d\d+ [\-]{0,1}\d+\.\d\d+ re/',$t)) ||
29405 (preg_match('/\d+\.\d\d+ (\d+\.\d\d+) l/',$t)) ||
29406 (preg_match('/q \d+\.\d\d+ 0 0 \d+\.\d\d+ \d+\.\d\d+ (\d+\.\d\d+) cm \/(I|FO)\d+ Do Q/',$t)) ||
29407 (preg_match('/\d+\.\d\d+ (\d+\.\d\d+) m/',$t)) ||
29408 (preg_match('/\d+\.\d\d+ (\d+\.\d\d+) \d+\.\d\d+ \d+\.\d\d+ \d+\.\d\d+ \d+\.\d\d+ c/',$t)) ) {
29409
29410 $clb = $s['y'] + $s['h'];
29411 if ($clb > $this->ColDetails[$s['col']]['max_bottom']) { $this->ColDetails[$s['col']]['max_bottom'] = $clb; }
29412 if ($clb > $lowest_bottom_y) { $lowest_bottom_y = $clb; }
29413 }
29414 }
29415 }
29416 foreach($this->columnbuffer AS $key=>$s) {
29417 if ($s['s'] != 'ACROFORM')
29418 $this->pages[$this->page] .= $s['s']."\n";
29419 }
29420 if ($lowest_bottom_y > 0) { $this->y = $lowest_bottom_y ; }
29421 /*-- INDEX --*/
29422
29423 // Output Reference (index)
29424 foreach($this->col_Reference AS $v) {
29425 $Present=0;
29426 for ($i=0;$i<count($this->Reference);$i++){
29427 if ($this->Reference[$i]['t']==$v['t']){
29428 $Present=1;
29429 if (!in_array($v['op'],$this->Reference[$i]['p'])) {
29430 $this->Reference[$i]['p'][] = $v['op'];
29431 }
29432 }
29433 }
29434 if ($Present==0) {
29435 $this->Reference[]=array('t'=>$v['t'],'p'=>array($v['op']));
29436 }
29437 }
29438 /*-- END INDEX --*/
29439 /*-- BOOKMARKS --*/
29440 // Output Bookmarks
29441 foreach($this->col_BMoutlines AS $v) {
29442 $this->BMoutlines[]=array('t'=>$v['t'],'l'=>$v['l'],'y'=>$v['y'],'p'=>$v['p']);
29443 }
29444 /*-- END BOOKMARKS --*/
29445 /*-- TOC --*/
29446 // Output ToC
29447 foreach($this->col_toc AS $v) {
29448 $this->tocontents->_toc[]=array('t'=>$v['t'],'l'=>$v['l'],'p'=>$v['p'],'link'=>$v['link'],'toc_id'=>$v['toc_id']);
29449 }
29450 /*-- END TOC --*/
29451 }
29452 foreach($this->internallink AS $key => $f) {
29453 if (isset($this->internallink[$key]['col'])) unset($this->internallink[$key]['col']);
29454 if (isset($this->internallink[$key]['rel_y'])) unset($this->internallink[$key]['rel_y']);
29455 }
29456
29457 $this->columnbuffer = array();
29458 $this->ColDetails = array();
29459 $this->columnLinks = array();
29460 $this->columnAnnots = array();
29461 $this->columnForms = array();
29462
29463 $this->col_Reference = array();
29464 $this->col_BMoutlines = array();
29465 $this->col_toc = array();
29466 $this->breakpoints = array();
29467 }
29468
29469 /*-- END COLUMNS --*/
29470
29471
29472 //==================================================================
29473 /*-- TABLES --*/
29474 function printcellbuffer() {
29475 if (count($this->cellBorderBuffer )) {
29476 sort($this->cellBorderBuffer);
29477 foreach($this->cellBorderBuffer AS $cbb) {
29478 $cba = unpack("A16dom/nbord/A1side/ns/dbw/a6ca/A10style/dx/dy/dw/dh/dmbl/dmbr/dmrt/dmrb/dmtl/dmtr/dmlt/dmlb/dcpd/dover/", $cbb);
29479 $side = $cba['side'];
29480 $details = array();
29481 $details[$side]['dom'] = (float) $cba['dom'];
29482 $details[$side]['s'] = $cba['s'];
29483 $details[$side]['w'] = $cba['bw'];
29484 $details[$side]['c'] = $cba['ca'];
29485 $details[$side]['style'] = trim($cba['style']);
29486 $details['mbw']['BL'] = $cba['mbl'];
29487 $details['mbw']['BR'] = $cba['mbr'];
29488 $details['mbw']['RT'] = $cba['mrt'];
29489 $details['mbw']['RB'] = $cba['mrb'];
29490 $details['mbw']['TL'] = $cba['mtl'];
29491 $details['mbw']['TR'] = $cba['mtr'];
29492 $details['mbw']['LT'] = $cba['mlt'];
29493 $details['mbw']['LB'] = $cba['mlb'];
29494 $details['cellposdom'] = $cba['cpd'];
29495 $details['p'] = $side;
29496 if ($cba['over']==1) { $details[$side]['overlay'] = true; }
29497 else { $details[$side]['overlay'] = false; }
29498 $this->_tableRect($cba['x'],$cba['y'],$cba['w'],$cba['h'],$cba['bord'],$details, false, false);
29499
29500 }
29501 $this->cellBorderBuffer = array();
29502 }
29503 }
29504 //==================================================================
29505 function printtablebuffer() {
29506
29507 if (!$this->table_rotate) {
29508 $this->pages[$this->page] .= $this->tablebuffer;
29509 foreach($this->tbrot_Links AS $p => $l) {
29510 foreach($l AS $v) {
29511 $this->PageLinks[$p][] = $v;
29512 }
29513 }
29514 $this->tbrot_Links = array();
29515 /*-- ANNOTATIONS --*/
29516 foreach($this->tbrot_Annots AS $p => $l) {
29517 foreach($l AS $v) {
29518 $this->PageAnnots[$p][] = $v;
29519 }
29520 }
29521 $this->tbrot_Annots = array();
29522 /*-- END ANNOTATIONS --*/
29523
29524 /*-- INDEX --*/
29525 // Output Reference (index)
29526 foreach($this->tbrot_Reference AS $v) {
29527 $Present=0;
29528 for ($i=0;$i<count($this->Reference);$i++){
29529 if ($this->Reference[$i]['t']==$v['t']){
29530 $Present=1;
29531 if (!in_array($v['op'],$this->Reference[$i]['p'])) {
29532 $this->Reference[$i]['p'][] = $v['op'];
29533 }
29534 }
29535 }
29536 if ($Present==0) {
29537 $this->Reference[]=array('t'=>$v['t'],'p'=>array($v['op']));
29538 }
29539 }
29540 $this->tbrot_Reference = array();
29541 /*-- END INDEX --*/
29542
29543 /*-- BOOKMARKS --*/
29544 // Output Bookmarks
29545 foreach($this->tbrot_BMoutlines AS $v) {
29546 $this->BMoutlines[]=array('t'=>$v['t'],'l'=>$v['l'],'y'=>$v['y'],'p'=>$v['p']);
29547 }
29548 $this->tbrot_BMoutlines = array();
29549 /*-- END BOOKMARKS --*/
29550
29551 /*-- TOC --*/
29552 // Output ToC
29553 foreach($this->tbrot_toc AS $v) {
29554 $this->tocontents->_toc[]=array('t'=>$v['t'],'l'=>$v['l'],'p'=>$v['p'],'link'=>$v['link'],'toc_id'=>$v['toc_id']);
29555 }
29556 $this->tbrot_toc = array();
29557 /*-- END TOC --*/
29558
29559 return;
29560 }
29561 // else if rotated
29562 $lm = $this->lMargin + $this->blk[$this->blklvl]['outer_left_margin'] + $this->blk[$this->blklvl]['border_left']['w'] + $this->blk[$this->blklvl]['padding_left'];
29563 $pw = $this->blk[$this->blklvl]['inner_width'];
29564 //Start Transformation
29565 $this->pages[$this->page] .= $this->StartTransform(true)."\n";
29566
29567 if ($this->table_rotate > 1) { // clockwise
29568 if ($this->tbrot_align == 'L') {
29569 $xadj = $this->tbrot_h ; // align L (as is)
29570 }
29571 else if ($this->tbrot_align == 'R') {
29572 $xadj = $lm-$this->tbrot_x0+($pw) ; // align R
29573 }
29574 else {
29575 $xadj = $lm-$this->tbrot_x0+(($pw + $this->tbrot_h)/2) ; // align C
29576 }
29577 $yadj = 0;
29578 }
29579 else { // anti-clockwise
29580 if ($this->tbrot_align == 'L') {
29581 $xadj = 0 ; // align L (as is)
29582 }
29583 else if ($this->tbrot_align == 'R') {
29584 $xadj = $lm-$this->tbrot_x0+($pw - $this->tbrot_h) ; // align R
29585 }
29586 else {
29587 $xadj = $lm-$this->tbrot_x0+(($pw - $this->tbrot_h)/2) ; // align C
29588 }
29589 $yadj = $this->tbrot_w;
29590 }
29591
29592
29593 $this->pages[$this->page] .= $this->transformTranslate($xadj, $yadj , true)."\n";
29594 $this->pages[$this->page] .= $this->transformRotate($this->table_rotate, $this->tbrot_x0 , $this->tbrot_y0 , true)."\n";
29595
29596 // Now output the adjusted values
29597 $this->pages[$this->page] .= $this->tablebuffer;
29598
29599
29600 foreach($this->tbrot_Links AS $p => $l) {
29601 foreach($l AS $v) {
29602 $w = $v[2]/_MPDFK;
29603 $h = $v[3]/_MPDFK;
29604 $ax = ($v[0]/_MPDFK) - $this->tbrot_x0;
29605 $ay = (($this->hPt-$v[1])/_MPDFK) - $this->tbrot_y0;
29606 if ($this->table_rotate > 1) { // clockwise
29607 $bx = $this->tbrot_x0+$xadj-$ay-$h;
29608 $by = $this->tbrot_y0+$yadj+$ax;
29609 }
29610 else {
29611 $bx = $this->tbrot_x0+$xadj+$ay;
29612 $by = $this->tbrot_y0+$yadj-$ax-$w;
29613 }
29614 $v[0] = $bx*_MPDFK;
29615 $v[1] = ($this->h-$by)*_MPDFK;
29616 $v[2] = $h*_MPDFK; // swap width and height
29617 $v[3] = $w*_MPDFK;
29618 $this->PageLinks[$p][] = $v;
29619 }
29620 }
29621 $this->tbrot_Links = array();
29622 foreach($this->internallink AS $key => $f) {
29623 if (is_array($f) && isset($f['tbrot'])) {
29624 $f['Y'] = $this->tbrot_y0;
29625 $f['PAGE'] = $this->page;
29626 unset($f['tbrot']);
29627 $this->internallink[$key] = $f;
29628 }
29629 }
29630 /*-- ANNOTATIONS --*/
29631 foreach($this->tbrot_Annots AS $p => $l) {
29632 foreach($l AS $v) {
29633 $ax = abs($v['x']) - $this->tbrot_x0; // abs because -ve values are internally set and held for reference if annotMargin set
29634 $ay = $v['y'] - $this->tbrot_y0;
29635 if ($this->table_rotate > 1) { // clockwise
29636 $bx = $this->tbrot_x0+$xadj-$ay;
29637 $by = $this->tbrot_y0+$yadj+$ax;
29638 }
29639 else {
29640 $bx = $this->tbrot_x0+$xadj+$ay;
29641 $by = $this->tbrot_y0+$yadj-$ax;
29642 }
29643 if ($v['x'] < 0) {
29644 $v['x'] = -$bx;
29645 }
29646 else {
29647 $v['x'] = $bx;
29648 }
29649 $v['y'] = ($by);
29650 $this->PageAnnots[$p][] = $v;
29651 }
29652 }
29653 $this->tbrot_Annots = array();
29654 /*-- END ANNOTATIONS --*/
29655
29656
29657 /*-- BOOKMARKS --*/
29658
29659 // Adjust Bookmarks
29660 foreach($this->tbrot_BMoutlines AS $v) {
29661 $v['y'] = $this->tbrot_y0;
29662 $this->BMoutlines[]=array('t'=>$v['t'],'l'=>$v['l'],'y'=>$v['y'],'p'=>$this->page);
29663 }
29664 /*-- END BOOKMARKS --*/
29665
29666 /*-- INDEX --*/
29667
29668 // Adjust Reference (index)
29669 foreach($this->tbrot_Reference AS $v) {
29670 $Present=0;
29671 //Search the reference (AND Ref/PageNo) in the array
29672 for ($i=0;$i<count($this->Reference);$i++){
29673 if ($this->Reference[$i]['t']==$v['t']){
29674 $Present=1;
29675 if (!in_array($this->page,$this->Reference[$i]['p'])) {
29676 $this->Reference[$i]['p'][] = $this->page;
29677 }
29678 }
29679 }
29680 if ($Present==0) {
29681 $this->Reference[]=array('t'=>$v['t'],'p'=>array($this->page));
29682 }
29683 }
29684 /*-- END INDEX --*/
29685
29686 /*-- TOC --*/
29687
29688 // Adjust ToC - uses document page number
29689 foreach($this->tbrot_toc AS $v) {
29690 $this->tocontents->_toc[]=array('t'=>$v['t'],'l'=>$v['l'],'p'=>$this->page,'link'=>$v['link'],'toc_id'=>$v['toc_id']);
29691 $this->links[$v['link']][1] = $this->tbrot_y0;
29692 }
29693 /*-- END TOC --*/
29694
29695
29696
29697 $this->tbrot_Reference = array();
29698 $this->tbrot_BMoutlines = array();
29699 $this->tbrot_toc = array();
29700
29701 //Stop Transformation
29702 $this->pages[$this->page] .= $this->StopTransform(true)."\n";
29703
29704
29705 $this->y = $this->tbrot_y0 + $this->tbrot_w;
29706 $this->x = $this->lMargin;
29707
29708 $this->tablebuffer = '';
29709 }
29710
29711 //==================================================================
29712 // Keep-with-table This buffers contents of h1-6 to keep on page with table
29713 function printkwtbuffer() {
29714 if (!$this->kwt_moved) {
29715 foreach($this->kwt_buffer AS $s) { $this->pages[$this->page] .= $s['s']."\n"; }
29716 foreach($this->kwt_Links AS $p => $l) {
29717 foreach($l AS $v) {
29718 $this->PageLinks[$p][] = $v;
29719 }
29720 }
29721 $this->kwt_Links = array();
29722 /*-- ANNOTATIONS --*/
29723 foreach($this->kwt_Annots AS $p => $l) {
29724 foreach($l AS $v) {
29725 $this->PageAnnots[$p][] = $v;
29726 }
29727 }
29728 $this->kwt_Annots = array();
29729 /*-- END ANNOTATIONS --*/
29730
29731 /*-- INDEX --*/
29732 // Output Reference (index)
29733 foreach($this->kwt_Reference AS $v) {
29734 $Present=0;
29735 for ($i=0;$i<count($this->Reference);$i++){
29736 if ($this->Reference[$i]['t']==$v['t']){
29737 $Present=1;
29738 if (!in_array($v['op'],$this->Reference[$i]['p'])) {
29739 $this->Reference[$i]['p'][] = $v['op'];
29740 }
29741 }
29742 }
29743 if ($Present==0) {
29744 $this->Reference[]=array('t'=>$v['t'],'p'=>array($v['op']));
29745 }
29746 }
29747 $this->kwt_Reference = array();
29748 /*-- END INDEX --*/
29749
29750 /*-- BOOKMARKS --*/
29751 // Output Bookmarks
29752 foreach($this->kwt_BMoutlines AS $v) {
29753 $this->BMoutlines[]=array('t'=>$v['t'],'l'=>$v['l'],'y'=>$v['y'],'p'=>$v['p']);
29754 }
29755 $this->kwt_BMoutlines = array();
29756 /*-- END BOOKMARKS --*/
29757
29758 /*-- TOC --*/
29759 // Output ToC
29760 foreach($this->kwt_toc AS $v) {
29761 $this->tocontents->_toc[]=array('t'=>$v['t'],'l'=>$v['l'],'p'=>$v['p'],'link'=>$v['link'],'toc_id'=>$v['toc_id']);
29762 }
29763 $this->kwt_toc = array();
29764 /*-- END TOC --*/
29765
29766 return;
29767 }
29768
29769 //Start Transformation
29770 $this->pages[$this->page] .= $this->StartTransform(true)."\n";
29771 $xadj = $this->lMargin - $this->kwt_x0 ;
29772 //$yadj = $this->y - $this->kwt_y0 ;
29773 $yadj = $this->tMargin - $this->kwt_y0 ;
29774
29775 $this->pages[$this->page] .= $this->transformTranslate($xadj, $yadj , true)."\n";
29776
29777 // Now output the adjusted values
29778 foreach($this->kwt_buffer AS $s) { $this->pages[$this->page] .= $s['s']."\n"; }
29779
29780 // Adjust hyperLinks
29781 foreach($this->kwt_Links AS $p => $l) {
29782 foreach($l AS $v) {
29783 $bx = $this->kwt_x0+$xadj;
29784 $by = $this->kwt_y0+$yadj;
29785 $v[0] = $bx*_MPDFK;
29786 $v[1] = ($this->h-$by)*_MPDFK;
29787 $this->PageLinks[$p][] = $v;
29788 }
29789 }
29790 foreach($this->internallink AS $key => $f) {
29791 if (is_array($f) && isset($f['kwt'])) {
29792 $f['Y'] += $yadj;
29793 $f['PAGE'] = $this->page;
29794 unset($f['kwt']);
29795 $this->internallink[$key] = $f;
29796 }
29797 }
29798 /*-- ANNOTATIONS --*/
29799 foreach($this->kwt_Annots AS $p => $l) {
29800 foreach($l AS $v) {
29801 $bx = $this->kwt_x0+$xadj;
29802 $by = $this->kwt_y0+$yadj;
29803 if ($v['x'] < 0) {
29804 $v['x'] = -$bx;
29805 }
29806 else {
29807 $v['x'] = $bx;
29808 }
29809 $v['y'] = $by;
29810 $this->PageAnnots[$p][] = $v;
29811 }
29812 }
29813 /*-- END ANNOTATIONS --*/
29814
29815 /*-- BOOKMARKS --*/
29816
29817 // Adjust Bookmarks
29818 foreach($this->kwt_BMoutlines AS $v) {
29819 if ($v['y'] != 0) { $v['y'] += $yadj; }
29820 $this->BMoutlines[]=array('t'=>$v['t'],'l'=>$v['l'],'y'=>$v['y'],'p'=>$this->page);
29821 }
29822 /*-- END BOOKMARKS --*/
29823
29824 /*-- INDEX --*/
29825
29826 // Adjust Reference (index)
29827 foreach($this->kwt_Reference AS $v) {
29828 $Present=0;
29829 //Search the reference (AND Ref/PageNo) in the array
29830 for ($i=0;$i<count($this->Reference);$i++){
29831 if ($this->Reference[$i]['t']==$v['t']){
29832 $Present=1;
29833 if (!in_array($this->page,$this->Reference[$i]['p'])) {
29834 $this->Reference[$i]['p'][] = $this->page;
29835 }
29836 }
29837 }
29838 if ($Present==0) {
29839 $this->Reference[]=array('t'=>$v['t'],'p'=>array($this->page));
29840 }
29841 }
29842 /*-- END INDEX --*/
29843
29844 /*-- TOC --*/
29845
29846 // Adjust ToC
29847 foreach($this->kwt_toc AS $v) {
29848 $this->tocontents->_toc[]=array('t'=>$v['t'],'l'=>$v['l'],'p'=>$this->page,'link'=>$v['link'],'toc_id'=>$v['toc_id']);
29849 $this->links[$v['link']][0] = $this->page;
29850 $this->links[$v['link']][1] += $yadj;
29851 }
29852 /*-- END TOC --*/
29853
29854
29855 $this->kwt_Links = array();
29856 $this->kwt_Annots = array();
29857
29858 $this->kwt_Reference = array();
29859 $this->kwt_BMoutlines = array();
29860 $this->kwt_toc = array();
29861 //Stop Transformation
29862 $this->pages[$this->page] .= $this->StopTransform(true)."\n";
29863
29864 $this->kwt_buffer = array();
29865
29866 $this->y += $this->kwt_height;
29867 }
29868
29869 /*-- END TABLES --*/
29870
29871
29872 //==================================================================
29873
29874 function printfloatbuffer() {
29875 if (count($this->floatbuffer)) {
29876 $this->objectbuffer = $this->floatbuffer;
29877 $this->printobjectbuffer(false);
29878 $this->objectbuffer = array();
29879 $this->floatbuffer = array();
29880 $this->floatmargins = array();
29881 }
29882 }
29883 //==================================================================
29884
29885 function printdivbuffer() {
29886 $p1 = $this->blk[$this->blklvl]['startpage'];
29887 $p2 = $this->page;
29888 $bottom[$p1] = $this->ktBlock[$p1]['bottom_margin'];
29889 $bottom[$p2] = $this->y; // $this->ktBlock[$p2]['bottom_margin'];
29890 $top[$p1] = $this->kt_y00;
29891
29892 $top2 = $this->h;
29893 foreach($this->divbuffer AS $key=>$s) {
29894 if ($s['page'] == $p2) {
29895 $top2 = MIN($s['y'], $top2);
29896 }
29897 }
29898 $top[$p2] = $top2;
29899 $height[$p1] = ($bottom[$p1] - $top[$p1]);
29900 $height[$p2] = ($bottom[$p2] - $top[$p2]);
29901 $xadj[$p1] = $this->MarginCorrection;
29902 $yadj[$p1] = -($top[$p1] - $top[$p2]);
29903 $xadj[$p2] = 0;
29904 $yadj[$p2] = $height[$p1];
29905
29906 // Output without any transformation
29907 if ($this->ColActive || !$this->keep_block_together || $this->blk[$this->blklvl]['startpage'] == $this->page || ($this->page - $this->blk[$this->blklvl]['startpage']) > 1 || ($height[$p1]+$height[$p2]) > $this->h) {
29908 foreach($this->divbuffer AS $s) { $this->pages[$s['page']] .= $s['s']."\n"; }
29909 foreach($this->ktLinks AS $p => $l) {
29910 foreach($l AS $v) {
29911 $this->PageLinks[$p][] = $v;
29912 }
29913 }
29914 foreach($this->ktForms AS $key => $f) {
29915 $this->form->forms[$f['n']] = $f;
29916 }
29917 /*-- ANNOTATIONS --*/
29918 foreach($this->ktAnnots AS $p => $l) {
29919 foreach($l AS $v) {
29920 $this->PageAnnots[$p][] = $v;
29921 }
29922 }
29923 /*-- END ANNOTATIONS --*/
29924 /*-- INDEX --*/
29925 // Adjust Reference (index)
29926 foreach($this->ktReference AS $v) {
29927 $Present=0;
29928 //Search the reference (AND Ref/PageNo) in the array
29929 for ($i=0;$i<count($this->Reference);$i++){
29930 if ($this->Reference[$i]['t']==$v['t']){
29931 $Present=1;
29932 if (!in_array($p2,$this->Reference[$i]['p'])) {
29933 $this->Reference[$i]['p'][] = $p2;
29934 }
29935 }
29936 }
29937 //If not found, add it
29938 if ($Present==0) {
29939 $this->Reference[]=array('t'=>$v['t'],'p'=>array($p2));
29940 }
29941 }
29942 /*-- END INDEX --*/
29943
29944 /*-- BOOKMARKS --*/
29945 // Adjust Bookmarks
29946 foreach($this->ktBMoutlines AS $v) {
29947 $this->BMoutlines[]=array('t'=>$v['t'],'l'=>$v['l'],'y'=>$v['y'],'p'=>$v['p']);
29948 }
29949 /*-- END BOOKMARKS --*/
29950
29951 /*-- TOC --*/
29952 // Adjust ToC
29953 foreach($this->_kttoc AS $v) {
29954 $this->tocontents->_toc[]=array('t'=>$v['t'],'l'=>$v['l'],'p'=>$v['p'],'link'=>$v['link'],'toc_id'=>$v['toc_id']);
29955 }
29956 /*-- END TOC --*/
29957
29958 $this->divbuffer = array();
29959 $this->ktLinks = array();
29960 $this->ktAnnots = array();
29961 $this->ktForms = array();
29962 $this->ktBlock = array();
29963 $this->ktReference = array();
29964 $this->ktBMoutlines = array();
29965 $this->_kttoc = array();
29966 $this->keep_block_together = 0;
29967 return;
29968 }
29969 else {
29970 // Output with transformation
29971 // mPDF 5.6.17
29972 $np = '';
29973 $lastpage = -1;
29974 foreach($this->divbuffer AS $key=>$s) {
29975 // callback function
29976 $t = $s['s'];
29977 $p = $s['page'];
29978 if ($p != $lastpage) {
29979 $q = '';
29980 if ($lastpage != -1) { $q = ' Q'."\n"; }
29981 $t = $q . $this->StartTransform(true)."\n" . $this->transformTranslate($xadj[$p], $yadj[$p] , true)."\n" . $t;
29982 $lastpage = $p;
29983 }
29984 $np .= $t."\n";
29985 }
29986 if ($lastpage != -1) { $np .= ' Q'."\n"; }
29987
29988 $this->pages[$this->page] .= $np;
29989
29990 // Adjust hyperLinks
29991 foreach($this->ktLinks AS $p => $l) {
29992 foreach($l AS $v) {
29993 $v[0] += ($xadj[$p]*_MPDFK);
29994 $v[1] -= ($yadj[$p]*_MPDFK);
29995 $this->PageLinks[$p2][] = $v;
29996 }
29997 }
29998 foreach($this->ktForms AS $key => $f) {
29999 $p = $f['page'];
30000 $f['x'] += ($xadj[$p]);
30001 $f['y'] += ($yadj[$p]);
30002 $f['page'] = $p2;
30003 $this->form->forms[$f['n']] = $f;
30004 }
30005 foreach($this->internallink AS $key => $f) {
30006 if (is_array($f) && isset($f['kt'])) {
30007 $f['Y'] += ($yadj[$f['PAGE']]);
30008 $f['PAGE'] = $p2;
30009 unset($f['kt']);
30010 $this->internallink[$key] = $f;
30011 }
30012 }
30013 /*-- ANNOTATIONS --*/
30014 foreach($this->ktAnnots AS $p => $l) {
30015 foreach($l AS $v) {
30016 if ($v['x']>0) { $v['x'] += $xadj[$p]; }
30017 else if ($v['x']<0) { $v['x'] -= $xadj[$p]; }
30018 $v['y'] += $yadj[$p];
30019 $this->PageAnnots[$p2][] = $v;
30020 }
30021 }
30022 /*-- END ANNOTATIONS --*/
30023
30024 /*-- BOOKMARKS --*/
30025 // Adjust Bookmarks
30026 foreach($this->ktBMoutlines AS $v) {
30027 if ($v['y'] != 0) { $v['y'] += ($yadj[$v['p']]); }
30028 $this->BMoutlines[]=array('t'=>$v['t'],'l'=>$v['l'],'y'=>$v['y'],'p'=>$p2);
30029 }
30030 /*-- END BOOKMARKS --*/
30031
30032 /*-- INDEX --*/
30033 // Adjust Reference (index)
30034 foreach($this->ktReference AS $v) {
30035 $Present=0;
30036 //Search the reference (AND Ref/PageNo) in the array
30037 for ($i=0;$i<count($this->Reference);$i++){
30038 if ($this->Reference[$i]['t']==$v['t']){
30039 $Present=1;
30040 if (!in_array($p2,$this->Reference[$i]['p'])) {
30041 $this->Reference[$i]['p'][] = $p2;
30042 }
30043 }
30044 }
30045 //If not found, add it
30046 if ($Present==0) {
30047 $this->Reference[]=array('t'=>$v['t'],'p'=>array($p2));
30048 }
30049 }
30050 /*-- END INDEX --*/
30051
30052 /*-- TOC --*/
30053 // Adjust ToC
30054 foreach($this->_kttoc AS $v) {
30055 $this->tocontents->_toc[]=array('t'=>$v['t'],'l'=>$v['l'],'p'=>$p2,'link'=>$v['link'],'toc_id'=>$v['toc_id']);
30056 $this->links[$v['link']][0] = $p2;
30057 $this->links[$v['link']][1] += $yadj[$v['p']];
30058 }
30059 /*-- END TOC --*/
30060
30061 $this->y = $top[$p2] + $height[$p1] + $height[$p2];
30062 $this->x = $this->lMargin;
30063
30064 $this->divbuffer = array();
30065 $this->ktLinks = array();
30066 $this->ktAnnots = array();
30067 $this->ktForms = array();
30068 $this->ktBlock = array();
30069 $this->ktReference = array();
30070 $this->ktBMoutlines = array();
30071 $this->_kttoc = array();
30072 $this->keep_block_together = 0;
30073 }
30074 }
30075
30076
30077 //==================================================================
30078 // Added ELLIPSES and CIRCLES
30079 function Circle($x,$y,$r,$style='S') {
30080 $this->Ellipse($x,$y,$r,$r,$style);
30081 }
30082
30083 function Ellipse($x,$y,$rx,$ry,$style='S') {
30084 if($style=='F') { $op='f'; }
30085 elseif($style=='FD' or $style=='DF') { $op='B'; }
30086 else { $op='S'; }
30087 $lx=4/3*(M_SQRT2-1)*$rx;
30088 $ly=4/3*(M_SQRT2-1)*$ry;
30089 $h=$this->h;
30090 $this->_out(sprintf('%.3F %.3F m %.3F %.3F %.3F %.3F %.3F %.3F c', ($x+$rx)*_MPDFK,($h-$y)*_MPDFK, ($x+$rx)*_MPDFK,($h-($y-$ly))*_MPDFK, ($x+$lx)*_MPDFK,($h-($y-$ry))*_MPDFK, $x*_MPDFK,($h-($y-$ry))*_MPDFK));
30091 $this->_out(sprintf('%.3F %.3F %.3F %.3F %.3F %.3F c', ($x-$lx)*_MPDFK,($h-($y-$ry))*_MPDFK, ($x-$rx)*_MPDFK,($h-($y-$ly))*_MPDFK, ($x-$rx)*_MPDFK,($h-$y)*_MPDFK));
30092 $this->_out(sprintf('%.3F %.3F %.3F %.3F %.3F %.3F c', ($x-$rx)*_MPDFK,($h-($y+$ly))*_MPDFK, ($x-$lx)*_MPDFK,($h-($y+$ry))*_MPDFK, $x*_MPDFK,($h-($y+$ry))*_MPDFK));
30093 $this->_out(sprintf('%.3F %.3F %.3F %.3F %.3F %.3F c %s', ($x+$lx)*_MPDFK,($h-($y+$ry))*_MPDFK, ($x+$rx)*_MPDFK,($h-($y+$ly))*_MPDFK, ($x+$rx)*_MPDFK,($h-$y)*_MPDFK, $op));
30094 }
30095
30096 /*-- DIRECTW --*/
30097 // Added adaptation of shaded_box = AUTOSIZE-TEXT
30098 function AutosizeText($text,$w,$font,$style,$szfont=72) {
30099 $text = $this->purify_utf8_text($text);
30100 if ($this->text_input_as_HTML) {
30101 $text = $this->all_entities_to_utf8($text);
30102 }
30103 if ($this->usingCoreFont) { $text = mb_convert_encoding($text,$this->mb_enc,'UTF-8'); }
30104 $text = ' '.$text.' ';
30105 $width = $this->ConvertSize($w);
30106 $loop = 0;
30107 while ( $loop == 0 ) {
30108 $this->SetFont($font,$style,$szfont);
30109 $sz = $this->GetStringWidth( $text );
30110 if ( $sz > $w ) { $szfont --; }
30111 else { $loop ++; }
30112 }
30113 $this->SetFont($font,$style,$szfont);
30114 $this->Cell($w, 0, $text, 0, 0, "C");
30115 }
30116 /*-- END DIRECTW --*/
30117
30118
30119
30120
30121
30122 // ====================================================
30123 // ====================================================
30124 /*-- RTL --*/
30125 function reverse_letters($str) {
30126 $str = strtr($str, '{}[]()', '}{][)(');
30127 return $this->mb_strrev($str, $this->mb_enc);
30128 }
30129
30130 function magic_reverse_dir(&$chunk, $join=true, $dir) {
30131 if ($this->usingCoreFont) { return 0; }
30132 if ($this->biDirectional) {
30133 // mPDF 5.4.05 Include PUA for non-indexed Arabic glyphs
30134 $pregRTLchars = $this->pregRTLchars;
30135 if ($this->CurrentFont['unAGlyphs']) { $pregRTLchars .= "\x{F500}-\x{F7FF}"; }
30136
30137 // Change Arabic + Persian. to Presentation Forms
30138 if ($join) {
30139 $chunk = preg_replace("/([".$pregRTLchars."]+)/ue", '$this->ArabJoin(stripslashes(\'\\1\'))', $chunk );
30140 }
30141 $contains_rtl = false;
30142 $all_rtl = true;
30143 $initSpace = false;
30144 $endSpace = false;
30145 $nonDirchars = "\x{A0}\"\'\(\)\{\}\[\].,:\\/-="; // mPDF 5.6.32
30146 // mPDF 5.6.43
30147 $bdo=array();
30148 preg_match_all('/([\x{202A}\x{202B}])(.*?)([\x{202C}])/u',$chunk,$m);
30149 if (count($m[0])) {
30150 for($i=0;$i<count($m[0]);$i++) {
30151 if ($m[1][$i]=="\xe2\x80\xab") { // Right-to-Left Embedding [RLE] U+202B &#8235;
30152 $mark = code2utf(0xf800+$i);
30153 $bdo[$i] = $this->reverse_letters($m[2][$i]);
30154 }
30155 else if ($m[1][$i]=="\xe2\x80\xaa") { // Left-to-Right Embedding [LRE] U+202A &#8234;
30156 $mark = code2utf(0xf880+$i);
30157 $bdo[$i] = $m[2][$i];
30158 }
30159 $chunk = preg_replace('/'.preg_quote($m[0][$i],'/').'/u',$mark,$chunk);
30160 }
30161 $pregRTLchars .= "\x{F800}-\x{F87F}";
30162 }
30163 if (preg_match("/[".$pregRTLchars."]/u",$chunk)) { // Chunk contains RTL characters
30164 if (preg_match("/^[ ]/",$chunk)) { $initSpace = true; $chunk = preg_replace("/^[ ]/",'',$chunk); }
30165 if (preg_match("/[ ]$/",$chunk)) { $endSpace = true; $chunk = preg_replace("/[ ]$/",'',$chunk); }
30166
30167 if (preg_match("/[^".$pregRTLchars.$nonDirchars." ]/u",$chunk)) { // Chunk also contains LTR characters
30168 $all_rtl = false;
30169 if ($dir == 'rtl') {
30170 $chunk = preg_replace("/([^".$pregRTLchars.$nonDirchars."][".$nonDirchars."]*) ([".$nonDirchars."]*[^".$pregRTLchars.$nonDirchars."])/u","\\1\x07\\2",$chunk);
30171 }
30172 $chunk = preg_replace("/([".$pregRTLchars."][".$nonDirchars."]*) ([".$nonDirchars."]*[".$pregRTLchars."])/u","\\1\x07\\2",$chunk);
30173 $bits = explode(' ',$chunk);
30174 foreach($bits AS $bitkey=>$bit) {
30175 $bit = preg_replace("/\x07/"," ",$bit);
30176 if (preg_match("/^[".$pregRTLchars.$nonDirchars." ]*$/u",$bit)) {
30177 $bits[$bitkey] = $this->reverse_letters($bit);
30178 }
30179 else if (preg_match("/[".$pregRTLchars."]/u",$bit)) {
30180 if ($dir == 'rtl') {
30181 $bit = preg_replace("/([^".$pregRTLchars.$nonDirchars." ])([".$nonDirchars."]*[".$pregRTLchars."])/u","\\1\x07\\2",$bit );
30182 $bit = preg_replace("/([".$pregRTLchars."][".$nonDirchars."]*)([^".$pregRTLchars.$nonDirchars." ])/u","\\1\x07\\2",$bit );
30183 }
30184 else {
30185 $bit = preg_replace("/([^".$pregRTLchars." ][".$nonDirchars."]*)([".$pregRTLchars." ])/u","\\1\x07\\2",$bit );
30186 $bit = preg_replace("/([".$pregRTLchars." ])([".$nonDirchars."]*[^".$pregRTLchars." ])/u","\\1\x07\\2",$bit );
30187 }
30188 $sbits = explode("\x07",$bit );
30189 foreach($sbits AS $sbitkey=>$sbit) {
30190 $sbit = preg_replace("/\x07/","",$sbit);
30191 if (preg_match("/^[".$pregRTLchars.$nonDirchars." ]*$/u",$sbit)) {
30192 $sbits[$sbitkey] = $this->reverse_letters($sbit);
30193 }
30194 else if (preg_match("/[".$pregRTLchars."]/u",$sbit) && $dir=='rtl') {
30195 $sbits[$sbitkey] = $this->reverse_letters($sbit);
30196 }
30197 else {
30198 // Reverse numerals only to RTL
30199 $sbit = preg_replace("/([\x{0660}-\x{066C}0-9]+[\x{0660}-\x{066C}0-9\.,:\/]*[\x{0660}-\x{066C}0-9]+)/ue", '$this->reverse_letters(\'\\1\')', $sbit ); // mPDF 5.6.32 // mPDF 5.6.46
30200 $sbits[$sbitkey] = $sbit;
30201 }
30202 }
30203 if ($dir == 'rtl') { $sbits = array_reverse($sbits,false); }
30204 $bits[$bitkey] = implode('',$sbits);
30205 }
30206 else if (preg_match("/[".$pregRTLchars."]/u",$bit) && $dir=='rtl') {
30207 $bits[$bitkey] = $this->reverse_letters($bit);
30208 }
30209 else {
30210 // Reverse numerals only to RTL
30211 $bit = preg_replace("/([\x{0660}-\x{066C}0-9]+[\x{0660}-\x{066C}0-9\.,:\/]*[\x{0660}-\x{066C}0-9]+)/ue", '$this->reverse_letters(\'\\1\')', $bit ); // mPDF 5.6.32 // mPDF 5.6.46
30212 $bits[$bitkey] = $bit;
30213 }
30214 }
30215 if ($dir == 'rtl') { $bits = array_reverse($bits,false); }
30216 $chunk = implode(' ',$bits);
30217 }
30218 else { $chunk = $this->reverse_letters($chunk); }
30219 $contains_rtl = true;
30220
30221 // Un-Reverse numerals back to ltr
30222 $chunk = preg_replace("/([\x{0660}-\x{066C}0-9]+[\x{0660}-\x{066C}0-9\.,:\/]*[\x{0660}-\x{066C}0-9]+)/ue", '$this->reverse_letters(\'\\1\')', $chunk ); // mPDF 5.6.13 // mPDF 5.6.32 // mPDF 5.6.46
30223 if ($dir == 'rtl') {
30224 if ($endSpace) { $chunk = ' '.$chunk; }
30225 if ($initSpace) { $chunk .= ' '; }
30226 }
30227 else {
30228 if ($initSpace) { $chunk = ' '.$chunk; }
30229 if ($endSpace) { $chunk .= ' '; }
30230 }
30231 }
30232 else { $all_rtl = false; }
30233
30234 // mPDF 5.6.43
30235 if (count($bdo)) {
30236 for($i=0;$i<count($bdo);$i++) {
30237 $chunk = preg_replace('/[\x{'.dechex(intval(0xf800+$i)).'}\x{'.dechex(intval(0xf880+$i)).'}]/u',$bdo[$i],$chunk);
30238 }
30239 }
30240
30241 if ($all_rtl) { return 2; }
30242 else if ($contains_rtl) { return 1; }
30243 else { return 0; }
30244 }
30245 return 0;
30246 }
30247 /*-- END RTL --*/
30248
30249 //
30250 // ****************************
30251 // ****************************
30252
30253
30254 function SetSubstitutions() {
30255 $subsarray = array();
30256 @include(_MPDF_PATH.'includes/subs_win-1252.php');
30257 $this->substitute = array();
30258 foreach($subsarray AS $key => $val) {
30259 $this->substitute[code2utf($key)] = $val;
30260 }
30261 }
30262
30263
30264 function SubstituteChars($html) {
30265 // only substitute characters between tags
30266 if (count($this->substitute)) {
30267 $a=preg_split('/(<.*?>)/ms',$html,-1,PREG_SPLIT_DELIM_CAPTURE);
30268 $html = '';
30269 foreach($a as $i => $e) {
30270 if($i%2==0) {
30271 $e = strtr($e, $this->substitute);
30272 }
30273 $html .= $e;
30274 }
30275 }
30276 return $html;
30277 }
30278
30279
30280 function SubstituteCharsSIP(&$writehtml_a, &$writehtml_i, &$writehtml_e) {
30281 if (preg_match("/^(.*?)([\x{20000}-\x{2FFFF}]+)(.*)/u", $writehtml_e, $m)) {
30282 if (isset($this->CurrentFont['sipext']) && $this->CurrentFont['sipext']) {
30283 $font = $this->CurrentFont['sipext'];
30284 if (!in_array($font, $this->available_unifonts)) { return 0; }
30285 $writehtml_a[$writehtml_i] = $writehtml_e = $m[1];
30286 array_splice($writehtml_a, $writehtml_i+1, 0, array('span style="font-family: '.$font.'"', $m[2], '/span', $m[3]));
30287 $this->subPos = $writehtml_i;
30288 return 4;
30289 }
30290 }
30291 return 0;
30292 }
30293
30294 // If core font is selected in document which is not onlyCoreFonts - substitute with non-core font
30295 function SubstituteCharsNonCore(&$writehtml_a, &$writehtml_i, &$writehtml_e) {
30296 if (mb_convert_encoding(mb_convert_encoding($writehtml_e, $this->mb_enc, "UTF-8"), "UTF-8", $this->mb_enc) == $writehtml_e) {
30297 return 0;
30298 }
30299 $cw = &$this->CurrentFont['cw'];
30300 $unicode = $this->UTF8StringToArray($writehtml_e, false);
30301 $start = -1;
30302 $end = 0;
30303 $flag = 0;
30304 $ftype = '';
30305 $u = array();
30306 if (!$this->subArrMB) {
30307 include(_MPDF_PATH.'includes/subs_core.php');
30308 $this->subArrMB['a'] = $aarr;
30309 $this->subArrMB['s'] = $sarr;
30310 $this->subArrMB['z'] = $zarr;
30311 }
30312 foreach($unicode AS $c => $char) {
30313 if (($char> 127 || ($flag==1 && $char==32)) && $char != 173 && (!isset($this->subArrMB['a'][$char]) || ($flag==1 && $char==32)) && ($char<1536 || ($char>1791 && $char < 2304) || $char>3455)) {
30314 if ($flag==0) { $start=$c; }
30315 $flag=1;
30316 $u[] = $char;
30317 }
30318 else if ($flag>0) { $end=$c-1; break; }
30319 }
30320 if ($flag>0 && !$end) { $end=count($unicode)-1; }
30321 if ($start==-1) { return 0; }
30322 // TRY IN BACKUP SUBS FONT
30323 if (!is_array($this->backupSubsFont)) { $this->backupSubsFont = array("$this->backupSubsFont"); }
30324 foreach($this->backupSubsFont AS $bsfctr=>$bsf) {
30325 if ($this->fonttrans[$bsf] == 'chelvetica' || $this->fonttrans[$bsf] == 'ctimes' || $this->fonttrans[$bsf] == 'ccourier') { continue; }
30326 $font = $bsf;
30327 unset($cw);
30328 $cw = '';
30329 if (isset($this->fonts[$font])) { $cw = &$this->fonts[$font]['cw']; }
30330 else if (file_exists(_MPDF_TTFONTDATAPATH.$font.'.cw.dat')) { $cw = @file_get_contents(_MPDF_TTFONTDATAPATH.$font.'.cw.dat'); }
30331 else {
30332
30333 $prevFontFamily = $this->FontFamily;
30334 $prevFontStyle = $this->currentfontstyle;
30335 $prevFontSizePt = $this->FontSizePt;
30336 $this->SetFont($bsf, '', '', false);
30337 $cw = @file_get_contents(_MPDF_TTFONTDATAPATH.$font.'.cw.dat');
30338 $this->SetFont($prevFontFamily, $prevFontStyle, $prevFontSizePt, false);
30339 }
30340 if (!$cw) { continue; }
30341 $l = 0;
30342 foreach($u AS $char) {
30343 if ($char == 173 || $this->_charDefined($cw,$char) || ($char>1536 && $char<1791) || ($char>2304 && $char<3455 )) {
30344 $l++;
30345 }
30346 else {
30347 if ($l==0 && $bsfctr == (count($this->backupSubsFont)-1)) { // Not found even in last backup font
30348 $cont = mb_substr($writehtml_e, $start+1);
30349 $writehtml_e = mb_substr($writehtml_e, 0, $start+1, 'UTF-8');
30350 array_splice($writehtml_a, $writehtml_i+1, 0, array('', $cont));
30351 $this->subPos = $writehtml_i+1;
30352 return 2;
30353 }
30354 else { break; }
30355 }
30356 }
30357 if ($l > 0) {
30358 $patt = mb_substr($writehtml_e, $start, $l, 'UTF-8');
30359 if (preg_match("/(.*?)(".preg_quote($patt,'/').")(.*)/u", $writehtml_e, $m)) {
30360 $writehtml_e = $m[1];
30361 array_splice($writehtml_a, $writehtml_i+1, 0, array('span style="font-family: '.$font.'"', $m[2], '/span', $m[3]));
30362 $this->subPos = $writehtml_i+3;
30363 return 4;
30364 }
30365 }
30366 }
30367
30368 unset($cw);
30369 return 0;
30370 }
30371
30372
30373 function SubstituteCharsMB(&$writehtml_a, &$writehtml_i, &$writehtml_e) {
30374 $cw = &$this->CurrentFont['cw'];
30375 $unicode = $this->UTF8StringToArray($writehtml_e, false);
30376 $start = -1;
30377 $end = 0;
30378 $flag = 0;
30379 $ftype = '';
30380 $u = array();
30381 foreach($unicode AS $c => $char) {
30382 if (($flag == 0 || $flag==2) && (!$this->_charDefined($cw,$char) || ($flag==2 && $char==32)) && $this->checkSIP && $char > 131071) { // Unicode Plane 2 (SIP)
30383 if (in_array($this->FontFamily ,$this->available_CJK_fonts)) { return 0; }
30384 if ($flag==0) { $start=$c; }
30385 $flag=2;
30386 $u[] = $char;
30387 }
30388 //else if (($flag == 0 || $flag==1) && $char != 173 && !$this->_charDefined($cw,$char) && ($char<1423 || ($char>3583 && $char < 11263))) {
30389 else if (($flag == 0 || $flag==1) && $char != 173 && (!$this->_charDefined($cw,$char) || ($flag==1 && $char==32)) && ($char<1536 || ($char>1791 && $char < 2304) || $char>3455)) {
30390 if ($flag==0) { $start=$c; }
30391 $flag=1;
30392 $u[] = $char;
30393 }
30394 else if ($flag>0) { $end=$c-1; break; }
30395 }
30396 if ($flag>0 && !$end) { $end=count($unicode)-1; }
30397 if ($start==-1) { return 0; }
30398 if ($flag == 2) { // SIP
30399 // Check if current CJK font has a ext-B related font
30400 if (isset($this->CurrentFont['sipext']) && $this->CurrentFont['sipext']) {
30401 $font = $this->CurrentFont['sipext'];
30402 unset($cw);
30403 $cw = '';
30404 if (isset($this->fonts[$font])) { $cw = &$this->fonts[$font]['cw']; }
30405 else if (file_exists(_MPDF_TTFONTDATAPATH.$font.'.cw.dat')) { $cw = @file_get_contents(_MPDF_TTFONTDATAPATH.$font.'.cw.dat'); }
30406 else {
30407 $prevFontFamily = $this->FontFamily;
30408 $prevFontStyle = $this->currentfontstyle;
30409 $prevFontSizePt = $this->FontSizePt;
30410 $this->SetFont($font, '', '', false);
30411 $cw = @file_get_contents(_MPDF_TTFONTDATAPATH.$font.'.cw.dat');
30412 $this->SetFont($prevFontFamily, $prevFontStyle, $prevFontSizePt, false);
30413 }
30414 if (!$cw) { return 0; }
30415 $l = 0;
30416 foreach($u AS $char) {
30417 if ($this->_charDefined($cw,$char) || $char > 131071) {
30418 $l++;
30419 }
30420 else { break; }
30421 }
30422 if ($l > 0) {
30423 $patt = mb_substr($writehtml_e, $start, $l);
30424 if (preg_match("/(.*?)(".preg_quote($patt,'/').")(.*)/u", $writehtml_e, $m)) {
30425 $writehtml_e = $m[1];
30426 array_splice($writehtml_a, $writehtml_i+1, 0, array('span style="font-family: '.$font.'"', $m[2], '/span', $m[3]));
30427 $this->subPos = $writehtml_i+3;
30428 return 4;
30429 }
30430 }
30431 }
30432 // Check Backup SIP font (defined in config_fonts.php)
30433 if (isset($this->backupSIPFont) && $this->backupSIPFont) {
30434 if ($this->currentfontfamily != $this->backupSIPFont) { $font = $this->backupSIPFont; }
30435 else { unset($cw); return 0; }
30436 unset($cw);
30437 $cw = '';
30438 if (isset($this->fonts[$font])) { $cw = &$this->fonts[$font]['cw']; }
30439 else if (file_exists(_MPDF_TTFONTDATAPATH.$font.'.cw.dat')) { $cw = @file_get_contents(_MPDF_TTFONTDATAPATH.$font.'.cw.dat'); }
30440 else {
30441 $prevFontFamily = $this->FontFamily;
30442 $prevFontStyle = $this->currentfontstyle;
30443 $prevFontSizePt = $this->FontSizePt;
30444 $this->SetFont($this->backupSIPFont, '', '', false);
30445 $cw = @file_get_contents(_MPDF_TTFONTDATAPATH.$font.'.cw.dat');
30446 $this->SetFont($prevFontFamily, $prevFontStyle, $prevFontSizePt, false);
30447 }
30448 if (!$cw) { return 0; }
30449 $l = 0;
30450 foreach($u AS $char) {
30451 if ($this->_charDefined($cw,$char) || $char > 131071) {
30452 $l++;
30453 }
30454 else { break; }
30455 }
30456 if ($l > 0) {
30457 $patt = mb_substr($writehtml_e, $start, $l);
30458 if (preg_match("/(.*?)(".preg_quote($patt,'/').")(.*)/u", $writehtml_e, $m)) {
30459 $writehtml_e = $m[1];
30460 array_splice($writehtml_a, $writehtml_i+1, 0, array('span style="font-family: '.$font.'"', $m[2], '/span', $m[3]));
30461 $this->subPos = $writehtml_i+3;
30462 return 4;
30463 }
30464 }
30465 }
30466 return 0;
30467 }
30468
30469
30470 // FIRST TRY CORE FONTS
30471 if (!$this->PDFA && !$this->PDFX) {
30472 $repl = array();
30473 if (!$this->subArrMB) {
30474 include(_MPDF_PATH.'includes/subs_core.php');
30475 $this->subArrMB['a'] = $aarr;
30476 $this->subArrMB['s'] = $sarr;
30477 $this->subArrMB['z'] = $zarr;
30478 }
30479 if (isset($this->subArrMB['a'][$u[0]])) {
30480 $font = 'tta'; $ftype = 'C';
30481 foreach($u AS $char) {
30482 if ($this->subArrMB['a'][$char]) { $repl[] = $this->subArrMB['a'][$char]; }
30483 else { break; }
30484 }
30485 }
30486 else if (isset($this->subArrMB['z'][$u[0]])) {
30487 $font = 'ttz'; $ftype = 'C';
30488 foreach($u AS $char) {
30489 if ($this->subArrMB['z'][$char]) { $repl[] = $this->subArrMB['z'][$char]; }
30490 else { break; }
30491 }
30492 }
30493 else if (isset($this->subArrMB['s'][$u[0]])) {
30494 $font = 'tts'; $ftype = 'C';
30495 foreach($u AS $char) {
30496 if ($this->subArrMB['s'][$char]) { $repl[] = $this->subArrMB['s'][$char]; }
30497 else { break; }
30498 }
30499 }
30500 if ($ftype=='C') {
30501 $patt = mb_substr($writehtml_e, $start, count($repl));
30502 if (preg_match("/(.*?)(".preg_quote($patt,'/').")(.*)/u", $writehtml_e, $m)) {
30503 $writehtml_e = $m[1];
30504 array_splice($writehtml_a, $writehtml_i+1, 0, array($font, implode('|', $repl), '/'.$font, $m[3])); // e.g. <tts>
30505 $this->subPos = $writehtml_i+3;
30506 return 4;
30507 }
30508 return 0;
30509 }
30510 }
30511
30512 // FIND IN DEFAULT FONT - removed mPDF 5.0
30513
30514 // LASTLY TRY IN BACKUP SUBS FONT
30515 if (!is_array($this->backupSubsFont)) { $this->backupSubsFont = array("$this->backupSubsFont"); }
30516 foreach($this->backupSubsFont AS $bsfctr=>$bsf) {
30517 if ($this->currentfontfamily != $bsf) { $font = $bsf; }
30518 else { continue; }
30519 unset($cw);
30520 $cw = '';
30521 if (isset($this->fonts[$font])) { $cw = &$this->fonts[$font]['cw']; }
30522 else if (file_exists(_MPDF_TTFONTDATAPATH.$font.'.cw.dat')) { $cw = @file_get_contents(_MPDF_TTFONTDATAPATH.$font.'.cw.dat'); }
30523 else {
30524 $prevFontFamily = $this->FontFamily;
30525 $prevFontStyle = $this->currentfontstyle;
30526 $prevFontSizePt = $this->FontSizePt;
30527 $this->SetFont($bsf, '', '', false);
30528 $cw = @file_get_contents(_MPDF_TTFONTDATAPATH.$font.'.cw.dat');
30529 $this->SetFont($prevFontFamily, $prevFontStyle, $prevFontSizePt, false);
30530 }
30531 if (!$cw) { continue; }
30532 $l = 0;
30533 foreach($u AS $char) {
30534 if ($char == 173 || $this->_charDefined($cw,$char) || ($char>1536 && $char<1791) || ($char>2304 && $char<3455 )) { // Arabic and Indic
30535 $l++;
30536 }
30537 else {
30538 if ($l==0 && $bsfctr == (count($this->backupSubsFont)-1)) { // Not found even in last backup font
30539 $cont = mb_substr($writehtml_e, $start+1);
30540 $writehtml_e = mb_substr($writehtml_e, 0, $start+1);
30541 array_splice($writehtml_a, $writehtml_i+1, 0, array('', $cont));
30542 $this->subPos = $writehtml_i+1;
30543 return 2;
30544 }
30545 else { break; }
30546 }
30547 }
30548 if ($l > 0) {
30549 $patt = mb_substr($writehtml_e, $start, $l);
30550 if (preg_match("/(.*?)(".preg_quote($patt,'/').")(.*)/u", $writehtml_e, $m)) {
30551 $writehtml_e = $m[1];
30552 array_splice($writehtml_a, $writehtml_i+1, 0, array('span style="font-family: '.$font.'"', $m[2], '/span', $m[3]));
30553 $this->subPos = $writehtml_i+3;
30554 return 4;
30555 }
30556 }
30557 }
30558
30559 unset($cw);
30560 return 0;
30561 }
30562
30563
30564 function setHiEntitySubstitutions() {
30565 $entarr = array (
30566 'nbsp' => '160', 'iexcl' => '161', 'cent' => '162', 'pound' => '163', 'curren' => '164', 'yen' => '165', 'brvbar' => '166', 'sect' => '167',
30567 'uml' => '168', 'copy' => '169', 'ordf' => '170', 'laquo' => '171', 'not' => '172', 'shy' => '173', 'reg' => '174', 'macr' => '175',
30568 'deg' => '176', 'plusmn' => '177', 'sup2' => '178', 'sup3' => '179', 'acute' => '180', 'micro' => '181', 'para' => '182', 'middot' => '183',
30569 'cedil' => '184', 'sup1' => '185', 'ordm' => '186', 'raquo' => '187', 'frac14' => '188', 'frac12' => '189', 'frac34' => '190',
30570 'iquest' => '191', 'Agrave' => '192', 'Aacute' => '193', 'Acirc' => '194', 'Atilde' => '195', 'Auml' => '196', 'Aring' => '197',
30571 'AElig' => '198', 'Ccedil' => '199', 'Egrave' => '200', 'Eacute' => '201', 'Ecirc' => '202', 'Euml' => '203', 'Igrave' => '204',
30572 'Iacute' => '205', 'Icirc' => '206', 'Iuml' => '207', 'ETH' => '208', 'Ntilde' => '209', 'Ograve' => '210', 'Oacute' => '211',
30573 'Ocirc' => '212', 'Otilde' => '213', 'Ouml' => '214', 'times' => '215', 'Oslash' => '216', 'Ugrave' => '217', 'Uacute' => '218',
30574 'Ucirc' => '219', 'Uuml' => '220', 'Yacute' => '221', 'THORN' => '222', 'szlig' => '223', 'agrave' => '224', 'aacute' => '225',
30575 'acirc' => '226', 'atilde' => '227', 'auml' => '228', 'aring' => '229', 'aelig' => '230', 'ccedil' => '231', 'egrave' => '232',
30576 'eacute' => '233', 'ecirc' => '234', 'euml' => '235', 'igrave' => '236', 'iacute' => '237', 'icirc' => '238', 'iuml' => '239',
30577 'eth' => '240', 'ntilde' => '241', 'ograve' => '242', 'oacute' => '243', 'ocirc' => '244', 'otilde' => '245', 'ouml' => '246',
30578 'divide' => '247', 'oslash' => '248', 'ugrave' => '249', 'uacute' => '250', 'ucirc' => '251', 'uuml' => '252', 'yacute' => '253',
30579 'thorn' => '254', 'yuml' => '255', 'OElig' => '338', 'oelig' => '339', 'Scaron' => '352', 'scaron' => '353', 'Yuml' => '376',
30580 'fnof' => '402', 'circ' => '710', 'tilde' => '732', 'Alpha' => '913', 'Beta' => '914', 'Gamma' => '915', 'Delta' => '916',
30581 'Epsilon' => '917', 'Zeta' => '918', 'Eta' => '919', 'Theta' => '920', 'Iota' => '921', 'Kappa' => '922', 'Lambda' => '923',
30582 'Mu' => '924', 'Nu' => '925', 'Xi' => '926', 'Omicron' => '927', 'Pi' => '928', 'Rho' => '929', 'Sigma' => '931', 'Tau' => '932',
30583 'Upsilon' => '933', 'Phi' => '934', 'Chi' => '935', 'Psi' => '936', 'Omega' => '937', 'alpha' => '945', 'beta' => '946', 'gamma' => '947',
30584 'delta' => '948', 'epsilon' => '949', 'zeta' => '950', 'eta' => '951', 'theta' => '952', 'iota' => '953', 'kappa' => '954',
30585 'lambda' => '955', 'mu' => '956', 'nu' => '957', 'xi' => '958', 'omicron' => '959', 'pi' => '960', 'rho' => '961', 'sigmaf' => '962',
30586 'sigma' => '963', 'tau' => '964', 'upsilon' => '965', 'phi' => '966', 'chi' => '967', 'psi' => '968', 'omega' => '969',
30587 'thetasym' => '977', 'upsih' => '978', 'piv' => '982', 'ensp' => '8194', 'emsp' => '8195', 'thinsp' => '8201', 'zwnj' => '8204',
30588 'zwj' => '8205', 'lrm' => '8206', 'rlm' => '8207', 'ndash' => '8211', 'mdash' => '8212', 'lsquo' => '8216', 'rsquo' => '8217',
30589 'sbquo' => '8218', 'ldquo' => '8220', 'rdquo' => '8221', 'bdquo' => '8222', 'dagger' => '8224', 'Dagger' => '8225', 'bull' => '8226',
30590 'hellip' => '8230', 'permil' => '8240', 'prime' => '8242', 'Prime' => '8243', 'lsaquo' => '8249', 'rsaquo' => '8250', 'oline' => '8254',
30591 'frasl' => '8260', 'euro' => '8364', 'image' => '8465', 'weierp' => '8472', 'real' => '8476', 'trade' => '8482', 'alefsym' => '8501',
30592 'larr' => '8592', 'uarr' => '8593', 'rarr' => '8594', 'darr' => '8595', 'harr' => '8596', 'crarr' => '8629', 'lArr' => '8656',
30593 'uArr' => '8657', 'rArr' => '8658', 'dArr' => '8659', 'hArr' => '8660', 'forall' => '8704', 'part' => '8706', 'exist' => '8707',
30594 'empty' => '8709', 'nabla' => '8711', 'isin' => '8712', 'notin' => '8713', 'ni' => '8715', 'prod' => '8719', 'sum' => '8721',
30595 'minus' => '8722', 'lowast' => '8727', 'radic' => '8730', 'prop' => '8733', 'infin' => '8734', 'ang' => '8736', 'and' => '8743',
30596 'or' => '8744', 'cap' => '8745', 'cup' => '8746', 'int' => '8747', 'there4' => '8756', 'sim' => '8764', 'cong' => '8773',
30597 'asymp' => '8776', 'ne' => '8800', 'equiv' => '8801', 'le' => '8804', 'ge' => '8805', 'sub' => '8834', 'sup' => '8835', 'nsub' => '8836',
30598 'sube' => '8838', 'supe' => '8839', 'oplus' => '8853', 'otimes' => '8855', 'perp' => '8869', 'sdot' => '8901', 'lceil' => '8968',
30599 'rceil' => '8969', 'lfloor' => '8970', 'rfloor' => '8971', 'lang' => '9001', 'rang' => '9002', 'loz' => '9674', 'spades' => '9824',
30600 'clubs' => '9827', 'hearts' => '9829', 'diams' => '9830',
30601 );
30602 foreach($entarr AS $key => $val) {
30603 $this->entsearch[] = '&'.$key.';';
30604 $this->entsubstitute[] = code2utf($val);
30605 }
30606 }
30607
30608 function SubstituteHiEntities($html) {
30609 // converts html_entities > ASCII 127 to unicode
30610 // Leaves in particular &lt; to distinguish from tag marker
30611 if (count($this->entsearch)) {
30612 $html = str_replace($this->entsearch,$this->entsubstitute,$html);
30613 }
30614 return $html;
30615 }
30616
30617
30618 // Edited v1.2 Pass by reference; option to continue if invalid UTF-8 chars
30619 function is_utf8(&$string) {
30620 if ($string === mb_convert_encoding(mb_convert_encoding($string, "UTF-32", "UTF-8"), "UTF-8", "UTF-32")) {
30621 return true;
30622 }
30623 else {
30624 if ($this->ignore_invalid_utf8) {
30625 $string = mb_convert_encoding(mb_convert_encoding($string, "UTF-32", "UTF-8"), "UTF-8", "UTF-32") ;
30626 return true;
30627 }
30628 else {
30629 return false;
30630 }
30631 }
30632 }
30633
30634
30635 function purify_utf8($html,$lo=true) {
30636 // For HTML
30637 // Checks string is valid UTF-8 encoded
30638 // converts html_entities > ASCII 127 to UTF-8
30639 // Only exception - leaves low ASCII entities e.g. &lt; &amp; etc.
30640 // Leaves in particular &lt; to distinguish from tag marker
30641 if (!$this->is_utf8($html)) {
30642 echo "<p><b>HTML contains invalid UTF-8 character(s)</b></p>";
30643 while (mb_convert_encoding(mb_convert_encoding($html, "UTF-32", "UTF-8"), "UTF-8", "UTF-32") != $html) {
30644 $a = iconv('UTF-8', 'UTF-8', $html);
30645 echo ($a);
30646 $pos = $start = strlen($a);
30647 $err = '';
30648 while ( ord(substr($html,$pos,1)) > 128 ) {
30649 $err .= '[[#'.ord(substr($html,$pos,1)).']]';
30650 $pos++;
30651 }
30652 echo '<span style="color:red; font-weight:bold">'.$err.'</span>';
30653 $html = substr($html, $pos);
30654 }
30655 echo $html;
30656 $this->Error("");
30657 }
30658 $html = preg_replace("/\r/", "", $html );
30659
30660 // converts html_entities > ASCII 127 to UTF-8
30661 // Leaves in particular &lt; to distinguish from tag marker
30662 $html = $this->SubstituteHiEntities($html);
30663
30664 // converts all &#nnn; or &#xHHH; to UTF-8 multibyte
30665 // If $lo==true then includes ASCII < 128
30666 $html = strcode2utf($html,$lo);
30667 return ($html);
30668 }
30669
30670 function purify_utf8_text($txt) {
30671 // For TEXT
30672 // Make sure UTF-8 string of characters
30673 if (!$this->is_utf8($txt)) { $this->Error("Text contains invalid UTF-8 character(s)"); }
30674
30675 $txt = preg_replace("/\r/", "", $txt );
30676
30677 return ($txt);
30678 }
30679 function all_entities_to_utf8($txt) {
30680 // converts txt_entities > ASCII 127 to UTF-8
30681 // Leaves in particular &lt; to distinguish from tag marker
30682 $txt = $this->SubstituteHiEntities($txt);
30683
30684 // converts all &#nnn; or &#xHHH; to UTF-8 multibyte
30685 $txt = strcode2utf($txt);
30686
30687 $txt = $this->lesser_entity_decode($txt);
30688 return ($txt);
30689 }
30690
30691
30692 // ====================================================
30693 /*-- BARCODES --*/
30694 // UPC/EAN barcode
30695 // EAN13, EAN8, UPCA, UPCE, ISBN, ISSN
30696 // Accepts 12 or 13 digits with or without - hyphens
30697 function WriteBarcode($code, $showtext=1, $x='', $y='', $size=1, $border=0, $paddingL=1, $paddingR=1, $paddingT=2, $paddingB=2, $height=1, $bgcol=false, $col=false, $btype='ISBN', $supplement='0', $supplement_code='', $k=1) {
30698 if (empty($code)) {
30699 return;
30700 }
30701 $codestr = $code;
30702 $code = preg_replace('/\-/','',$code);
30703
30704 if (!class_exists('PDFBarcode', false)) {
30705 include(_MPDF_PATH.'classes/barcode.php');
30706 }
30707 $this->barcode = new PDFBarcode();
30708 if ($btype == 'ISSN' || $btype == 'ISBN') {
30709 $arrcode = $this->barcode->getBarcodeArray($code, 'EAN13');
30710 }
30711 else { $arrcode = $this->barcode->getBarcodeArray($code, $btype); }
30712
30713 if ($arrcode === false) { $this->Error('Error in barcode string: '.$codestr); }
30714 if((($btype=='EAN13' || $btype=='ISBN' || $btype=='ISSN') && strlen($code) == 12) || ($btype=='UPCA' && strlen($code) == 11)
30715 || ($btype=='UPCE' && strlen($code) == 11) || ($btype=='EAN8' && strlen($code) == 7)) {
30716 $code .= $arrcode['checkdigit'];
30717 if (stristr($codestr,'-')) { $codestr .= '-' . $arrcode['checkdigit']; }
30718 else { $codestr .= $arrcode['checkdigit']; }
30719 }
30720 if ($btype == 'ISBN') { $codestr = 'ISBN '.$codestr; }
30721 if ($btype == 'ISSN') { $codestr = 'ISSN '.$codestr; }
30722
30723 if (empty($x)) {
30724 $x = $this->x;
30725 }
30726 if (empty($y)) {
30727 $y = $this->y;
30728 }
30729 // set foreground color
30730 $prevDrawColor = $this->DrawColor;
30731 $prevTextColor = $this->TextColor;
30732 $prevFillColor = $this->FillColor;
30733 $lw = $this->LineWidth;
30734 $this->SetLineWidth(0.01);
30735
30736 $size /= $k; // in case resized in a table
30737
30738 $xres = $arrcode['nom-X'] * $size;
30739 $llm = $arrcode['lightmL'] * $arrcode['nom-X'] * $size; // Left Light margin
30740 $rlm = $arrcode['lightmR'] * $arrcode['nom-X'] * $size; // Right Light margin
30741
30742 $bcw = ($arrcode["maxw"] * $xres); // Barcode width = Should always be 31.35mm * $size
30743
30744 $fbw = $bcw + $llm + $rlm; // Full barcode width incl. light margins
30745 $ow = $fbw + $paddingL + $paddingR; // Full overall width incl. user-defined padding
30746
30747 $fbwi = $fbw - 2; // Full barcode width incl. light margins - 2mm - for isbn string
30748
30749 // cf. http://www.gs1uk.org/downloads/bar_code/Bar coding getting it right.pdf
30750 $num_height = 3 * $size; // Height of numerals
30751 $fbh = $arrcode['nom-H'] * $size * $height; // Full barcode height incl. numerals
30752 $bch = $fbh - (1.5 * $size); // Barcode height of bars (3mm for numerals)
30753
30754 if (($btype=='EAN13' && $showtext) || $btype == 'ISSN' || $btype == 'ISBN') { // Add height for ISBN string + margin from top of bars
30755 $tisbnm = 1.5 * $size; // Top margin between isbn (if shown) & bars
30756 $codestr_fontsize = 2.1 * $size;
30757 $paddingT += $codestr_fontsize + $tisbnm ;
30758 }
30759 $oh = $fbh + $paddingT + $paddingB; // Full overall height incl. user-defined padding
30760
30761 // PRINT border background color
30762 $xpos = $x;
30763 $ypos = $y;
30764 if ($col) {
30765 $this->SetDColor($col);
30766 $this->SetTColor($col);
30767 }
30768 else {
30769 $this->SetDColor($this->ConvertColor(0));
30770 $this->SetTColor($this->ConvertColor(0));
30771 }
30772 if ($bgcol) {
30773 $this->SetFColor($bgcol);
30774 }
30775 else { $this->SetFColor($this->ConvertColor(255)); }
30776 if (!$bgcol && !$col) { // fn. called directly - not via HTML
30777 if ($border) { $fillb = 'DF'; } else { $fillb = 'F'; }
30778 $this->Rect($xpos, $ypos, $ow, $oh, $fillb);
30779 }
30780
30781
30782 // PRINT BARS
30783 $xpos = $x + $paddingL + $llm ;
30784 $ypos = $y + $paddingT;
30785 if ($col) { $this->SetFColor($col); }
30786 else { $this->SetFColor($this->ConvertColor(0)); }
30787 if ($arrcode !== false) {
30788 foreach ($arrcode["bcode"] AS $v) {
30789 $bw = ($v["w"] * $xres);
30790 if ($v["t"]) {
30791 // draw a vertical bar
30792 $this->Rect($xpos, $ypos, $bw, $bch, 'F');
30793 }
30794 $xpos += $bw;
30795 }
30796 }
30797
30798
30799 // print text
30800 $prevFontFamily = $this->FontFamily;
30801 $prevFontStyle = $this->FontStyle;
30802 $prevFontSizePt = $this->FontSizePt;
30803
30804 // ISBN string
30805 if (($btype=='EAN13' && $showtext) || $btype=='ISBN' || $btype=='ISSN') {
30806 if ($this->onlyCoreFonts) {
30807 $this->SetFont('chelvetica');
30808 }
30809 else {
30810 $this->SetFont('sans');
30811 }
30812
30813 if ($bgcol) { $this->SetFColor($bgcol); }
30814 else { $this->SetFColor($this->ConvertColor(255)); }
30815 $this->x = $x + $paddingL + 1; // 1mm left margin (cf. $fbwi above)
30816 // max width is $fbwi
30817 $loop = 0;
30818 while ( $loop == 0 ) {
30819 $this->SetFontSize($codestr_fontsize*1.4*_MPDFK, false); // don't write
30820 $sz = $this->GetStringWidth( $codestr );
30821 if ($sz > $fbwi)
30822 $codestr_fontsize -= 0.1;
30823 else
30824 $loop ++;
30825 }
30826 $this->SetFont('','',$codestr_fontsize*1.4*_MPDFK, true, true); // * 1.4 because font height is only 7/10 of given mm
30827 // WORD SPACING
30828 if ($fbwi > $sz) {
30829 $xtra = $fbwi - $sz;
30830 $charspacing = $xtra / (strlen($codestr)-1);
30831 if ($charspacing) { $this->_out(sprintf('BT %.3F Tc ET',$charspacing*_MPDFK)); }
30832 }
30833 $this->y = $y + $paddingT - ($codestr_fontsize ) - $tisbnm ;
30834 $this->Cell($fbw , $codestr_fontsize, $codestr);
30835 if ($charspacing) { $this->_out('BT 0 Tc ET'); }
30836 }
30837
30838
30839 // Bottom NUMERALS
30840 if ($this->onlyCoreFonts) {
30841 $this->SetFont('mono');
30842 }
30843 else {
30844 if (in_array('ocrb',$this->available_unifonts)) { $this->SetFont('ocrb'); }
30845 else { $this->SetFont('mono'); }
30846 }
30847 if (isset($this->CurrentFont['desc']['CapHeight'])) { $fh = (1000/$this->CurrentFont['desc']['CapHeight']); }
30848 else if (isset($this->CurrentFont['desc']['Ascent'])) { $fh = (1000/$this->CurrentFont['desc']['Ascent']); }
30849 else { $fh = 1.2; }
30850
30851 $charRO = '';
30852 if ($btype=='EAN13' || $btype=='ISBN' || $btype=='ISSN') {
30853 $outerfontsize = 3; // Inner fontsize = 3
30854 $outerp = $xres * 4;
30855 $innerp = $xres * 2.5;
30856 $textw = ($bcw*0.5) - $outerp - $innerp;
30857 $chars = 6; // number of numerals in each half
30858 $charLO = substr($code,0,1); // Left Outer
30859 $charLI = substr($code,1,6); // Left Inner
30860 $charRI = substr($code,7,6); // Right Inner
30861 if (!$supplement) $charRO = '>'; // Right Outer
30862 }
30863 else if ($btype=='UPCA') {
30864 $outerfontsize = 2.3; // Inner fontsize = 3
30865 $outerp = $xres * 10;
30866 $innerp = $xres * 2.5;
30867 $textw = ($bcw*0.5) - $outerp - $innerp;
30868 $chars = 5;
30869 $charLO = substr($code,0,1); // Left Outer
30870 $charLI = substr($code,1,5); // Left Inner
30871 $charRI = substr($code,6,5); // Right Inner
30872 $charRO = substr($code,11,1); // Right Outer
30873 }
30874 else if ($btype=='UPCE') {
30875 $outerfontsize = 2.3; // Inner fontsize = 3
30876 $outerp = $xres * 4;
30877 $innerp = 0;
30878 $textw = ($bcw*0.5) - $outerp - $innerp;
30879 $chars = 3;
30880 $upce_code = $arrcode['code'];
30881 $charLO = substr($code,0,1); // Left Outer
30882 $charLI = substr($upce_code,0,3); // Left Inner
30883 $charRI = substr($upce_code,3,3); // Right Inner
30884 $charRO = substr($code,11,1); // Right Outer
30885 }
30886 else if ($btype=='EAN8') {
30887 $outerfontsize = 3; // Inner fontsize = 3
30888 $outerp = $xres * 4;
30889 $innerp = $xres * 2.5;
30890 $textw = ($bcw*0.5) - $outerp - $innerp;
30891 $chars = 4;
30892 $charLO = '<'; // Left Outer
30893 $charLI = substr($code,0,4); // Left Inner
30894 $charRI = substr($code,4,4); // Right Inner
30895 if (!$supplement) $charRO = '>'; // Right Outer
30896 }
30897
30898 $this->SetFontSize(($outerfontsize/3)*3*$fh*$size*_MPDFK); // 3mm numerals (FontSize is larger to account for space above/below characters)
30899
30900 if (!$this->usingCoreFont) { $cw = $this->_getCharWidth($this->CurrentFont['cw'],32)*3*$fh*$size/1000; } // character width at 3mm
30901 else { $cw = $this->_getCharWidth($this->CurrentFont['cw'],48)*3*$fh*$size/1000; } // 48 == char "0"
30902
30903 // Outer left character
30904 $y_text = $y + $paddingT + $bch - ($num_height/2);
30905 $y_text_outer = $y + $paddingT + $bch - ($num_height*($outerfontsize/3)/2);
30906
30907 $this->x = $x + $paddingL - ($cw*($outerfontsize/3)*0.1); // 0.1 is correction as char does not fill full width;
30908 $this->y = $y_text_outer;
30909 $this->Cell($cw, $num_height, $charLO );
30910
30911 // WORD SPACING for inner chars
30912 $xtra = $textw - ($cw*$chars);
30913 $charspacing = $xtra / ($chars-1);
30914 if ($charspacing) { $this->_out(sprintf('BT %.3F Tc ET',$charspacing*_MPDFK)); }
30915
30916 if ($bgcol) { $this->SetFColor($bgcol); }
30917 else { $this->SetFColor($this->ConvertColor(255)); }
30918
30919 $this->SetFontSize(3*$fh*$size*_MPDFK); // 3mm numerals (FontSize is larger to account for space above/below characters)
30920
30921 // Inner left half characters
30922 $this->x = $x + $paddingL + $llm + $outerp;
30923 $this->y = $y_text;
30924 $this->Cell($textw, $num_height, $charLI , 0, 0, '', 1);
30925
30926 // Inner right half characters
30927 $this->x = $x + $paddingL + $llm + ($bcw*0.5) + $innerp;
30928 $this->y = $y_text;
30929 $this->Cell($textw, $num_height, $charRI , 0, 0, '', 1);
30930
30931 if ($charspacing) { $this->_out('BT 0 Tc ET'); }
30932
30933 // Outer Right character
30934 $this->SetFontSize(($outerfontsize/3)*3*$fh*$size*_MPDFK); // 3mm numerals (FontSize is larger to account for space above/below characters)
30935
30936 $this->x = $x + $paddingL + $llm + $bcw + $rlm - ($cw*($outerfontsize/3)*0.9); // 0.9 is correction as char does not fill full width
30937 $this->y = $y_text_outer;
30938 $this->Cell($cw*($outerfontsize/3), $num_height, $charRO , 0, 0, 'R');
30939
30940 if ($supplement) { // EAN-2 or -5 Supplement
30941 // PRINT BARS
30942 $supparrcode = $this->barcode->getBarcodeArray($supplement_code, 'EAN'.$supplement);
30943 if ($supparrcode === false) { $this->Error('Error in barcode string (supplement): '.$codestr.' '.$supplement_code); }
30944 if(strlen($supplement_code) != $supplement) {
30945 $this->Error('Barcode supplement incorrect: '.$supplement_code);
30946 }
30947 $llm = $fbw - (($arrcode['lightmR'] - $supparrcode['sepM']) * $arrcode['nom-X'] * $size); // Left Light margin
30948 $rlm = $arrcode['lightmR'] * $arrcode['nom-X'] * $size; // Right Light margin
30949
30950 $bcw = ($supparrcode["maxw"] * $xres); // Barcode width = Should always be 31.35mm * $size
30951
30952 $fbw = $bcw + $llm + $rlm; // Full barcode width incl. light margins
30953 $ow = $fbw + $paddingL + $paddingR; // Full overall width incl. user-defined padding
30954 $bch = $fbh - (1.5 * $size) - ($num_height + 0.5); // Barcode height of bars (3mm for numerals)
30955
30956 $xpos = $x + $paddingL + $llm ;
30957 $ypos = $y + $paddingT + $num_height + 0.5;
30958 if ($col) { $this->SetFColor($col); }
30959 else { $this->SetFColor($this->ConvertColor(0)); }
30960 if ($supparrcode !== false) {
30961 foreach ($supparrcode["bcode"] AS $v) {
30962 $bw = ($v["w"] * $xres);
30963 if ($v["t"]) {
30964 // draw a vertical bar
30965 $this->Rect($xpos, $ypos, $bw, $bch, 'F');
30966 }
30967 $xpos += $bw;
30968 }
30969 }
30970
30971 // Characters
30972 if ($bgcol) { $this->SetFColor($bgcol); }
30973 else { $this->SetFColor($this->ConvertColor(255)); }
30974 $this->SetFontSize(3*$fh*$size*_MPDFK); // 3mm numerals (FontSize is larger to account for space above/below characters)
30975 $this->x = $x + $paddingL + $llm;
30976 $this->y = $y + $paddingT;
30977 $this->Cell($bcw, $num_height, $supplement_code, 0, 0, 'C');
30978
30979 // Outer Right character (light margin)
30980 $this->SetFontSize(($outerfontsize/3)*3*$fh*$size*_MPDFK); // 3mm numerals (FontSize is larger to account for space above/below characters)
30981 $this->x = $x + $paddingL + $llm + $bcw + $rlm - ($cw*0.9); // 0.9 is correction as char does not fill full width
30982 $this->y = $y + $paddingT;
30983 $this->Cell($cw*($outerfontsize/3), $num_height, '>', 0, 0, 'R');
30984 }
30985
30986
30987
30988 // Restore **************
30989 $this->SetFont($prevFontFamily, $prevFontStyle, $prevFontSizePt);
30990 $this->DrawColor = $prevDrawColor;
30991 $this->TextColor = $prevTextColor;
30992 $this->FillColor = $prevFillColor;
30993 $this->SetLineWidth($lw);
30994 $this->SetY($y);
30995 }
30996
30997
30998
30999 // ====================================================
31000 // POSTAL and OTHER barcodes
31001 function WriteBarcode2($code, $x='', $y='', $size=1, $height=1, $bgcol=false, $col=false, $btype='IMB', $print_ratio='', $k=1) {
31002 if (empty($code)) { return; }
31003 if (!class_exists('PDFBarcode', false)) {
31004 include(_MPDF_PATH.'classes/barcode.php');
31005 }
31006 $this->barcode = new PDFBarcode();
31007 $arrcode = $this->barcode->getBarcodeArray($code, $btype, $print_ratio);
31008
31009 if ($arrcode === false) { $this->Error('Error in barcode string: '.$code); }
31010 if (empty($x)) { $x = $this->x; }
31011 if (empty($y)) { $y = $this->y; }
31012 $prevDrawColor = $this->DrawColor;
31013 $prevTextColor = $this->TextColor;
31014 $prevFillColor = $this->FillColor;
31015 $lw = $this->LineWidth;
31016 $this->SetLineWidth(0.01);
31017 $size /= $k; // in case resized in a table
31018 $xres = $arrcode['nom-X'] * $size;
31019
31020 if ($btype == 'IMB' || $btype == 'RM4SCC' || $btype == 'KIX' || $btype == 'POSTNET' || $btype == 'PLANET') {
31021 $llm = $arrcode['quietL'] / $k; // Left Quiet margin
31022 $rlm = $arrcode['quietR'] / $k; // Right Quiet margin
31023 $tlm = $blm = $arrcode['quietTB'] / $k;
31024 $height=1; // Overrides
31025 }
31026 else if (in_array($btype, array('C128A','C128B','C128C','EAN128A','EAN128B','EAN128C','C39','C39+','C39E','C39E+','S25','S25+','I25','I25+','I25B','I25B+','C93','MSI','MSI+','CODABAR','CODE11'))) {
31027 $llm = $arrcode['lightmL'] * $xres; // Left Quiet margin
31028 $rlm = $arrcode['lightmR'] * $xres; // Right Quiet margin
31029 $tlm = $blm = $arrcode['lightTB'] * $xres * $height;
31030 }
31031
31032
31033 $bcw = ($arrcode["maxw"] * $xres);
31034 $fbw = $bcw + $llm + $rlm; // Full barcode width incl. light margins
31035
31036 $bch = ($arrcode["nom-H"] * $size * $height);
31037 $fbh = $bch + $tlm + $blm; // Full barcode height
31038
31039 // PRINT border background color
31040 $xpos = $x;
31041 $ypos = $y;
31042 if ($col) {
31043 $this->SetDColor($col);
31044 $this->SetTColor($col);
31045 }
31046 else {
31047 $this->SetDColor($this->ConvertColor(0));
31048 $this->SetTColor($this->ConvertColor(0));
31049 }
31050 if ($bgcol) {
31051 $this->SetFColor($bgcol);
31052 }
31053 else { $this->SetFColor($this->ConvertColor(255)); }
31054
31055 // PRINT BARS
31056 if ($col) { $this->SetFColor($col); }
31057 else { $this->SetFColor($this->ConvertColor(0)); }
31058 $xpos = $x + $llm ;
31059
31060 if ($arrcode !== false) {
31061 foreach ($arrcode["bcode"] AS $v) {
31062 $bw = ($v["w"] * $xres);
31063 if ($v["t"]) {
31064 $ypos = $y + $tlm + ($bch * $v['p'] / $arrcode['maxh']);
31065 $this->Rect($xpos, $ypos, $bw, ($v['h'] * $bch / $arrcode['maxh']), 'F');
31066 }
31067 $xpos += $bw;
31068 }
31069 }
31070
31071 // PRINT BEARER BARS
31072 if ($btype == 'I25B' || $btype == 'I25B+') {
31073 $this->Rect($x, $y, $fbw, ($arrcode['lightTB'] * $xres * $height), 'F');
31074 $this->Rect($x, $y+$tlm+$bch, $fbw, ($arrcode['lightTB'] * $xres * $height), 'F');
31075 }
31076
31077 // Restore **************
31078 $this->SetFont($prevFontFamily, $prevFontStyle, $prevFontSizePt);
31079 $this->DrawColor = $prevDrawColor;
31080 $this->TextColor = $prevTextColor;
31081 $this->FillColor = $prevFillColor;
31082 $this->SetLineWidth($lw);
31083 $this->SetY($y);
31084 }
31085
31086 /*-- END BARCODES --*/
31087
31088 // ====================================================
31089 // ====================================================
31090
31091 function StartTransform($returnstring=false) {
31092 if ($returnstring) { return('q'); }
31093 else { $this->_out('q'); }
31094 }
31095 function StopTransform($returnstring=false) {
31096 if ($returnstring) { return('Q'); }
31097 else { $this->_out('Q'); }
31098 }
31099 function transformScale($s_x, $s_y, $x='', $y='', $returnstring=false) {
31100 if ($x === '') {
31101 $x=$this->x;
31102 }
31103 if ($y === '') {
31104 $y=$this->y;
31105 }
31106 if (($s_x == 0) OR ($s_y == 0)) {
31107 $this->Error('Please do not use values equal to zero for scaling');
31108 }
31109 $y = ($this->h - $y) * _MPDFK;
31110 $x *= _MPDFK;
31111 //calculate elements of transformation matrix
31112 $s_x /= 100;
31113 $s_y /= 100;
31114 $tm[0] = $s_x;
31115 $tm[1] = 0;
31116 $tm[2] = 0;
31117 $tm[3] = $s_y;
31118 $tm[4] = $x * (1 - $s_x);
31119 $tm[5] = $y * (1 - $s_y);
31120 //scale the coordinate system
31121 if ($returnstring) { return($this->_transform($tm, true)); }
31122 else { $this->_transform($tm); }
31123 }
31124 function transformTranslate($t_x, $t_y, $returnstring=false) {
31125 //calculate elements of transformation matrix
31126 $tm[0] = 1;
31127 $tm[1] = 0;
31128 $tm[2] = 0;
31129 $tm[3] = 1;
31130 $tm[4] = $t_x * _MPDFK;
31131 $tm[5] = -$t_y * _MPDFK;
31132 //translate the coordinate system
31133 if ($returnstring) { return($this->_transform($tm, true)); }
31134 else { $this->_transform($tm); }
31135 }
31136 function transformRotate($angle, $x='', $y='', $returnstring=false) {
31137 if ($x === '') {
31138 $x=$this->x;
31139 }
31140 if ($y === '') {
31141 $y=$this->y;
31142 }
31143 $angle = -$angle;
31144 $y = ($this->h - $y) * _MPDFK;
31145 $x *= _MPDFK;
31146 //calculate elements of transformation matrix
31147 $tm[0] = cos(deg2rad($angle));
31148 $tm[1] = sin(deg2rad($angle));
31149 $tm[2] = -$tm[1];
31150 $tm[3] = $tm[0];
31151 $tm[4] = $x + $tm[1] * $y - $tm[0] * $x;
31152 $tm[5] = $y - $tm[0] * $y - $tm[1] * $x;
31153 //rotate the coordinate system around ($x,$y)
31154 if ($returnstring) { return($this->_transform($tm, true)); }
31155 else { $this->_transform($tm); }
31156 }
31157 function _transform($tm, $returnstring=false) {
31158 if ($returnstring) { return(sprintf('%.4F %.4F %.4F %.4F %.4F %.4F cm', $tm[0], $tm[1], $tm[2], $tm[3], $tm[4], $tm[5])); }
31159 else { $this->_out(sprintf('%.4F %.4F %.4F %.4F %.4F %.4F cm', $tm[0], $tm[1], $tm[2], $tm[3], $tm[4], $tm[5])); }
31160 }
31161
31162
31163
31164 /*-- INDIC --*/
31165 // INDIC ============================
31166 // This conversion can only be done when font is set
31167 function ConvertIndic(&$str) {
31168 if (preg_match('/^ind_([a-z]{2})_/',$this->currentfontfamily, $m)) {
31169 if (!class_exists('indic', false)) { include(_MPDF_PATH.'classes/indic.php'); }
31170 if (empty($this->indic)) { $this->indic = new indic($this); }
31171 $earr = $this->UTF8StringToArray($str, false);
31172 $str = $this->indic->substituteIndic($earr, $m[1], $this->currentfontfamily);
31173 }
31174 }
31175 /*-- END INDIC --*/
31176
31177 // AUTOFONT =========================
31178 function AutoFont($html) {
31179 if ($this->onlyCoreFonts) { return $html; }
31180 $this->useLang = true;
31181 if ($this->autoFontGroupSize == 1) { $extra = $this->pregASCIIchars1; }
31182 else if ($this->autoFontGroupSize == 3) { $extra = $this->pregASCIIchars3; }
31183 else { $extra = $this->pregASCIIchars2; }
31184 $n = '';
31185 $a=preg_split('/<(.*?)>/ms',$html,-1,PREG_SPLIT_DELIM_CAPTURE);
31186 foreach($a as $i => $e) {
31187 if($i%2==0) {
31188 $e = strcode2utf($e);
31189 $e = $this->lesser_entity_decode($e);
31190
31191 // Use U=FFF0 and U+FFF1 to mark start and end of span tags to prevent nesting occurring
31192 // "\xef\xbf\xb0" ##lthtmltag## "\xef\xbf\xb1" ##gthtmltag##
31193
31194 /*-- CJK-FONTS --*/
31195 if ($this->autoFontGroups & AUTOFONT_CJK) {
31196 $e = preg_replace("/([".$this->pregCJKchars.$extra."]*[".$this->pregCJKchars."][".$this->pregCJKchars.$extra."]*)/ue", '$this->replaceCJK(stripslashes(\'\\1\'))', $e);
31197 }
31198 /*-- END CJK-FONTS --*/
31199
31200 /*-- RTL --*/
31201 if ($this->autoFontGroups & AUTOFONT_RTL) {
31202 // HEBREW
31203 $e = preg_replace("/([".$this->pregHEBchars .$extra."]*[".$this->pregHEBchars ."][".$this->pregHEBchars .$extra."]*)/u", "\xef\xbf\xb0span lang=\"he\"\xef\xbf\xb1\\1\xef\xbf\xb0/span\xef\xbf\xb1", $e);
31204 // All Arabic
31205 $e = preg_replace("/([".$this->pregARABICchars .$extra."]*[".$this->pregARABICchars ."][".$this->pregARABICchars .$extra."]*)/ue", '$this->replaceArabic(stripslashes(\'\\1\'))', $e);
31206 }
31207 /*-- END RTL --*/
31208
31209 /*-- INDIC --*/
31210 // INDIC
31211 if ($this->autoFontGroups & AUTOFONT_INDIC) {
31212 // Bengali
31213 $e = preg_replace("/([".$this->pregBNchars .$this->pregINDextra."]*[".$this->pregBNchars ."][".$this->pregBNchars .$this->pregINDextra."]*)/u", "\xef\xbf\xb0span lang=\"bn\"\xef\xbf\xb1\\1\xef\xbf\xb0/span\xef\xbf\xb1", $e);
31214 // Devanagari (= script for Hindi, Nepali + Sindhi)
31215 $e = preg_replace("/([".$this->pregHIchars .$this->pregINDextra."]*[".$this->pregHIchars ."][".$this->pregHIchars .$this->pregINDextra."]*)/u", "\xef\xbf\xb0span lang=\"hi\"\xef\xbf\xb1\\1\xef\xbf\xb0/span\xef\xbf\xb1", $e);
31216 // Gujarati
31217 $e = preg_replace("/([".$this->pregGUchars .$this->pregINDextra."]*[".$this->pregGUchars ."][".$this->pregGUchars .$this->pregINDextra."]*)/u", "\xef\xbf\xb0span lang=\"gu\"\xef\xbf\xb1\\1\xef\xbf\xb0/span\xef\xbf\xb1", $e);
31218 // Malayalam
31219 $e = preg_replace("/([".$this->pregMLchars .$this->pregINDextra."]*[".$this->pregMLchars ."][".$this->pregMLchars .$this->pregINDextra."]*)/u", "\xef\xbf\xb0span lang=\"ml\"\xef\xbf\xb1\\1\xef\xbf\xb0/span\xef\xbf\xb1", $e);
31220 // Kannada
31221 $e = preg_replace("/([".$this->pregKNchars .$this->pregINDextra."]*[".$this->pregKNchars ."][".$this->pregKNchars .$this->pregINDextra."]*)/u", "\xef\xbf\xb0span lang=\"kn\"\xef\xbf\xb1\\1\xef\xbf\xb0/span\xef\xbf\xb1", $e);
31222 // Oriya
31223 $e = preg_replace("/([".$this->pregORchars .$this->pregINDextra."]*[".$this->pregORchars ."][".$this->pregORchars .$this->pregINDextra."]*)/u", "\xef\xbf\xb0span lang=\"or\"\xef\xbf\xb1\\1\xef\xbf\xb0/span\xef\xbf\xb1", $e);
31224 // Punjabi ?= Gurmuhki
31225 $e = preg_replace("/([".$this->pregPAchars .$this->pregINDextra."]*[".$this->pregPAchars ."][".$this->pregPAchars .$this->pregINDextra."]*)/u", "\xef\xbf\xb0span lang=\"pa\"\xef\xbf\xb1\\1\xef\xbf\xb0/span\xef\xbf\xb1", $e);
31226 // Tamil
31227 $e = preg_replace("/([".$this->pregTAchars .$this->pregINDextra."]*[".$this->pregTAchars ."][".$this->pregTAchars .$this->pregINDextra."]*)/u", "\xef\xbf\xb0span lang=\"ta\"\xef\xbf\xb1\\1\xef\xbf\xb0/span\xef\xbf\xb1", $e);
31228 // Telugu
31229 $e = preg_replace("/([".$this->pregTEchars .$this->pregINDextra."]*[".$this->pregTEchars ."][".$this->pregTEchars .$this->pregINDextra."]*)/u", "\xef\xbf\xb0span lang=\"te\"\xef\xbf\xb1\\1\xef\xbf\xb0/span\xef\xbf\xb1", $e);
31230 }
31231 /*-- END INDIC --*/
31232
31233
31234 if ($this->autoFontGroups & AUTOFONT_THAIVIET) {
31235 // THAI
31236 $e = preg_replace("/([\x{0E00}-\x{0E7F}".$extra."]*[\x{0E00}-\x{0E7F}][\x{0E00}-\x{0E7F}".$extra."]*)/u", "\xef\xbf\xb0span lang=\"th\"\xef\xbf\xb1\\1\xef\xbf\xb0/span\xef\xbf\xb1", $e);
31237 // Vietnamese
31238 $e = preg_replace("/([".$this->pregVIETchars .$this->pregVIETPluschars ."]*[".$this->pregVIETchars ."][".$this->pregVIETchars .$this->pregVIETPluschars ."]*)/u", "\xef\xbf\xb0span lang=\"vi\"\xef\xbf\xb1\\1\xef\xbf\xb0/span\xef\xbf\xb1", $e);
31239 }
31240
31241 $e = preg_replace('/[&]/','&amp;',$e);
31242 $e = preg_replace('/[<]/','&lt;',$e);
31243 $e = preg_replace('/[>]/','&gt;',$e);
31244 $e = preg_replace("/(\xef\xbf\xb0span lang=\"([a-z\-A-Z]{2,5})\"\xef\xbf\xb1)\s+/",' \\1',$e);
31245 $e = preg_replace("/[ ]+(\xef\xbf\xb0\/span\xef\xbf\xb1)/",'\\1 ',$e);
31246
31247 $e = preg_replace("/\xef\xbf\xb0span lang=\"([a-z\-A-Z]{2,5})\"\xef\xbf\xb1/","\xef\xbf\xb0span lang=\"\\1\" class=\"lang_\\1\"\xef\xbf\xb1",$e);
31248
31249 $e = preg_replace("/\xef\xbf\xb0/",'<',$e);
31250 $e = preg_replace("/\xef\xbf\xb1/",'>',$e);
31251
31252 $a[$i] = $e;
31253 }
31254 else {
31255 $a[$i] = '<'.$e.'>';
31256 }
31257 }
31258 $n = implode('',$a);
31259 return $n;
31260 }
31261
31262
31263 /*-- CJK-FONTS --*/
31264 function replaceCJK($str) {
31265 // Use U=FFF0 and U+FFF1 to mark start and end of span tags to prevent nesting occurring
31266 // "\xef\xbf\xb0" ##lthtmltag## "\xef\xbf\xb1" ##gthtmltag##
31267 if (preg_match("/[".$this->pregUHCchars."]/u", $str)) {
31268 return "\xef\xbf\xb0span lang=\"ko\"\xef\xbf\xb1" . $str ."\xef\xbf\xb0/span\xef\xbf\xb1";
31269 }
31270 else if (preg_match("/[".$this->pregSJISchars."]/u", $str)) {
31271 return "\xef\xbf\xb0span lang=\"ja\"\xef\xbf\xb1" . $str ."\xef\xbf\xb0/span\xef\xbf\xb1";
31272 }
31273 // if in Unicode Plane 2, probably HKCS (incl in BIG5) if not Japanese
31274 else if (preg_match("/[\x{20000}-\x{2FFFF}]/u", $str)) {
31275 return "\xef\xbf\xb0span lang=\"zh-HK\"\xef\xbf\xb1" . $str ."\xef\xbf\xb0/span\xef\xbf\xb1";
31276 }
31277 else{
31278 return "\xef\xbf\xb0span lang=\"zh-CN\"\xef\xbf\xb1" . $str ."\xef\xbf\xb0/span\xef\xbf\xb1";
31279 }
31280 return $str;
31281 }
31282 /*-- END CJK-FONTS --*/
31283
31284 /*-- RTL --*/
31285 function replaceArabic($str) {
31286 // PASHTO, SINDHI, URDU, ARABIC, PERSIAN
31287 $persian = "\x{067E}\x{0686}\x{0698}\x{06AF}";
31288
31289 $urdu = "\x{0679}\x{0688}\x{0691}\x{06BA}\x{06BE}\x{06C1}\x{06D2}";
31290 $pashto = "\x{067C}\x{0681}\x{0685}\x{0689}\x{0693}\x{0696}\x{069A}\x{06BC}\x{06D0}"; // ? and U+06AB, U+06CD
31291 $sindhi = "\x{067A}\x{067B}\x{067D}\x{067F}\x{0680}\x{0684}\x{068D}\x{068A}\x{068F}\x{068C}\x{0687}\x{0683}\x{0699}\x{06AA}\x{06A6}\x{06BB}\x{06B1}\x{06B3}";
31292 // Use U=FFF0 and U+FFF1 to mark start and end of span tags to prevent nesting occurring
31293 // "\xef\xbf\xb0" ##lthtmltag## "\xef\xbf\xb1" ##gthtmltag##
31294
31295 if (preg_match("/[".$this->pregNonARABICchars ."]/u", $str) ) {
31296 if (preg_match("/[".$sindhi ."]/u", $str) ) {
31297 return "\xef\xbf\xb0span lang=\"sd\"\xef\xbf\xb1".$str."\xef\xbf\xb0/span\xef\xbf\xb1";
31298 }
31299 else if (preg_match("/[".$urdu ."]/u", $str) ) {
31300 return "\xef\xbf\xb0span lang=\"ur\"\xef\xbf\xb1".$str."\xef\xbf\xb0/span\xef\xbf\xb1";
31301 }
31302 else if (preg_match("/[".$pashto ."]/u", $str) ) {
31303 return "\xef\xbf\xb0span lang=\"ps\"\xef\xbf\xb1".$str."\xef\xbf\xb0/span\xef\xbf\xb1";
31304 }
31305 else if (preg_match("/[".$persian ."]/u", $str) ) {
31306 return "\xef\xbf\xb0span lang=\"fa\"\xef\xbf\xb1".$str."\xef\xbf\xb0/span\xef\xbf\xb1";
31307 }
31308 else {
31309 return "\xef\xbf\xb0span lang=\"ar\"\xef\xbf\xb1".$str."\xef\xbf\xb0/span\xef\xbf\xb1";
31310 }
31311 }
31312 if (preg_match("/[".$persian ."]/u", $str) ) {
31313 return "\xef\xbf\xb0span lang=\"fa\"\xef\xbf\xb1".$str."\xef\xbf\xb0/span\xef\xbf\xb1";
31314 }
31315 else {
31316 return "\xef\xbf\xb0span lang=\"ar\"\xef\xbf\xb1".$str."\xef\xbf\xb0/span\xef\xbf\xb1";
31317 }
31318 return $str;
31319 }
31320
31321 // ARABIC ===========================
31322 // mPDF 5.4.08
31323 function InitArabic() {
31324
31325 // JOIN TO FOLLOWING LETTER IN LOGICAL ORDER (i.e. AS INITIAL)
31326 $this->arabPrevLink = "";
31327 // U+060c; U+061b; U+061f; U+0626; U+0628;
31328 $this->arabPrevLink .= "\xd8\x8c\xd8\x9b\xd8\x9f\xd8\xa6\xd8\xa8";
31329 // U+062a; U+062b; U+062c; U+062d; U+062e;
31330 $this->arabPrevLink .= "\xd8\xaa\xd8\xab\xd8\xac\xd8\xad\xd8\xae";
31331 // U+0633; U+0634; U+0635; U+0636; U+0637; U+0638; U+0639; U+063a;
31332 $this->arabPrevLink .= "\xd8\xb3\xd8\xb4\xd8\xb5\xd8\xb6\xd8\xb7\xd8\xb8\xd8\xb9\xd8\xba";
31333 // U+0640; U+0641; U+0642; U+0643; U+0644; U+0645; U+0646; U+0647; U+0649; U+064a;
31334 $this->arabPrevLink .= "\xd9\x80\xd9\x81\xd9\x82\xd9\x83\xd9\x84\xd9\x85\xd9\x86\xd9\x87\xd9\x89\xd9\x8a";
31335 // U+0678; U+0679; U+067a; U+067b; U+067c; U+067d; U+067e; U+067f;
31336 $this->arabPrevLink .= "\xd9\xb8\xd9\xb9\xd9\xba\xd9\xbb\xd9\xbc\xd9\xbd\xd9\xbe\xd9\xbf";
31337 // U+0680; U+0681; U+0682; U+0683; U+0684; U+0685; U+0686; U+0687;
31338 $this->arabPrevLink .= "\xda\x80\xda\x81\xda\x82\xda\x83\xda\x84\xda\x85\xda\x86\xda\x87";
31339 // U+069a; U+069b; U+069c; U+069d; U+069e; U+069f;
31340 $this->arabPrevLink .= "\xda\x9a\xda\x9b\xda\x9c\xda\x9d\xda\x9e\xda\x9f";
31341 // U+06a0; U+06a1; U+06a2; U+06a3; U+06a4; U+06a5; U+06a6; U+06A7; U+06A8;
31342 $this->arabPrevLink .= "\xda\xa0\xda\xa1\xda\xa2\xda\xa3\xda\xa4\xda\xa5\xda\xa6\xda\xa7\xda\xa8";
31343 // U+06a9; U+06aa; U+06ab; U+06ac; U+06ad; U+06ae; U+06af;
31344 $this->arabPrevLink .= "\xda\xa9\xda\xaa\xda\xab\xda\xac\xda\xad\xda\xae\xda\xaf";
31345 // U+06b0; U+06b1; U+06b2; U+06b3; U+06b4; U+06b5; U+06b6; U+06b7; U+06b8; U+06b9;
31346 $this->arabPrevLink .= "\xda\xb0\xda\xb1\xda\xb2\xda\xb3\xda\xb4\xda\xb5\xda\xb6\xda\xb7\xda\xb8\xda\xb9";
31347 // U+06ba; U+06bb; U+06bc; U+06be; U+06bf;
31348 $this->arabPrevLink .= "\xda\xba\xda\xbb\xda\xbc\xda\xbe\xda\xbf";
31349 // U+06c1; U+06cc; U+06ce; U+06d0; U+06d1;
31350 $this->arabPrevLink .= "\xdb\x81\xdb\x8c\xdb\x8e\xdb\x90\xdb\x91";
31351
31352
31353
31354
31355 // JOIN TO PREVIOUS LETTER IN LOGICAL ORDER (i.e. AS FINAL FORM)
31356 $this->arabNextLink = "";
31357 // U+0622; U+0623; U+0624; U+0625; U+0626; U+0627; U+0628; U+0629;
31358 $this->arabNextLink .= "\xd8\xa2\xd8\xa3\xd8\xa4\xd8\xa5\xd8\xa6\xd8\xa7\xd8\xa8\xd8\xa9";
31359 // U+062A; U+062B; U+062C; U+062D; U+062E; U+062F;
31360 $this->arabNextLink .= "\xd8\xaa\xd8\xab\xd8\xac\xd8\xad\xd8\xae\xd8\xaf";
31361 // U+0630; U+0631; U+0632; U+0633; U+0634; U+0635; U+0636; U+0637; U+0638; U+0639; U+063A;
31362 $this->arabNextLink .= "\xd8\xb0\xd8\xb1\xd8\xb2\xd8\xb3\xd8\xb4\xd8\xb5\xd8\xb6\xd8\xb7\xd8\xb8\xd8\xb9\xd8\xba";
31363 // U+0640; U+0641; U+0642; U+0643; U+0644; U+0645; U+0646; U+0647; U+0648; U+0649; U+064A;
31364 $this->arabNextLink .= "\xd9\x80\xd9\x81\xd9\x82\xd9\x83\xd9\x84\xd9\x85\xd9\x86\xd9\x87\xd9\x88\xd9\x89\xd9\x8a";
31365 // U+0671; U+0672; U+0675; U+0676; U+0677; U+0678; U+0679;
31366 $this->arabNextLink .= "\xd9\xb1\xd9\xb2\xd9\xb5\xd9\xb6\xd9\xb7\xd9\xb8\xd9\xb9";
31367 // U+067A; U+067B; U+067C; U+067D; U+067E; U+067F;
31368 $this->arabNextLink .= "\xd9\xba\xd9\xbb\xd9\xbc\xd9\xbd\xd9\xbe\xd9\xbf";
31369 // U+0680; U+0681; U+0682; U+0683; U+0684; U+0685; U+0686; U+0687; U+0688; U+0689;
31370 $this->arabNextLink .= "\xda\x80\xda\x81\xda\x82\xda\x83\xda\x84\xda\x85\xda\x86\xda\x87\xda\x88\xda\x89";
31371 // U+068A; U+068B; U+068C; U+068D; U+068F;U+068F;
31372 $this->arabNextLink .= "\xda\x8a\xda\x8b\xda\x8c\xda\x8d\xda\x8e\xda\x8f";
31373 // U+0690; U+0691; U+0692; U+0693; U+0694; U+0695; U+0696; U+0697; U+0698; U+0699;
31374 $this->arabNextLink .= "\xda\x90\xda\x91\xda\x92\xda\x93\xda\x94\xda\x95\xda\x96\xda\x97\xda\x98\xda\x99";
31375 // U+069A; U+069B; U+069C; U+069D; U+069E; U+069F;
31376 $this->arabNextLink .= "\xda\x9a\xda\x9b\xda\x9c\xda\x9d\xda\x9e\xda\x9f";
31377 // U+06A0; U+06A1; U+06A2; U+06A3; U+06A4; U+06A5; U+06A6; U+06A7; U+06A8; U+06A9;
31378 $this->arabNextLink .= "\xda\xa0\xda\xa1\xda\xa2\xda\xa3\xda\xa4\xda\xa5\xda\xa6\xda\xa7\xda\xa8\xda\xa9";
31379 // U+06AA; U+06AB; U+06AC; U+06AD; U+06AE; U+06AF;
31380 $this->arabNextLink .= "\xda\xaa\xda\xab\xda\xac\xda\xad\xda\xae\xda\xaf";
31381 // U+06B0; U+06B1; U+06B2; U+06B3; U+06B4; U+06B5; U+06B6; U+06B7; U+06B8; U+06B9;
31382 $this->arabNextLink .= "\xda\xb0\xda\xb1\xda\xb2\xda\xb3\xda\xb4\xda\xb5\xda\xb6\xda\xb7\xda\xb8\xda\xb9";
31383 // U+06BA; U+06BB; U+06BC; U+06BE; U+06BF;
31384 $this->arabNextLink .= "\xda\xba\xda\xbb\xda\xbc\xda\xbe\xda\xbf";
31385 // U+06C0; U+06C1; U+06C2; U+06C3; U+06C4; U+06C5; U+06C6; U+06C7; U+06C8; U+06C9;
31386 $this->arabNextLink .= "\xdb\x80\xdb\x81\xdb\x82\xdb\x83\xdb\x84\xdb\x85\xdb\x86\xdb\x87\xdb\x88\xdb\x89";
31387 // U+06CA; U+06CB; U+06CC; U+06CD; U+06CE; U+06CF;
31388 $this->arabNextLink .= "\xdb\x8a\xdb\x8b\xdb\x8c\xdb\x8d\xdb\x8e\xdb\x8f";
31389 // U+06D0; U+06d1; U+06D2; U+06D3;
31390 $this->arabNextLink .= "\xdb\x90\xdb\x91\xdb\x92\xdb\x93";
31391
31392
31393 // VOWELS ++
31394
31395 // U+064b U+064c; U+064d; U+064e; U+064f; U+0650; U+0651; U+0652;
31396 $this->arabVowels = "\xd9\x8b\xd9\x8c\xd9\x8d\xd9\x8e\xd9\x8f\xd9\x90\xd9\x91\xd9\x92";
31397
31398 // Added chars that may not be vowels but should not interrupt joining
31399 // U+0670; U+0653;
31400 $this->arabVowels .= "\xd9\xb0\xd9\x93";
31401 // ? should also add - U+615, 616, 617-61A, 653-65E, 6D6-6DC, 6DF-6E4, 6E7, 6E8, 6EA-6ED
31402
31403
31404
31405 // ISOLATED FORM :: FINAL :: INITIAL :: MEDIAL
31406 // FB** - FE** = Arabic presentation Forms
31407 // F5** F6** F7** = Private use area used by unAGlyphs in mPDF
31408 $this->arabGlyphs = array(
31409 "\xd8\x8c"=>array("\xd8\x8c", "\xd8\x8c", "\xd8\x8c", "\xd8\x8c"), /* 060C, 060C, 060C, 060C */
31410 "\xd8\x9b"=>array("\xd8\x9b", "\xd8\x9b", "\xd8\x9b", "\xd8\x9b"), /* 061B, 061B, 061B, 061B */
31411 "\xd8\x9f"=>array("\xd8\x9f", "\xd8\x9f", "\xd8\x9f", "\xd8\x9f"), /* 061F, 061F, 061F, 061F */
31412 "\xd8\xa1"=>array("\xd8\xa1", "\xd8\xa1", "\xd8\xa1", "\xd8\xa1"), /* 0621, 0621, 0621, 0621 */
31413 "\xd8\xa2"=>array("\xd8\xa2", "\xef\xba\x82", "\xd8\xa2", "\xef\xba\x82"), /* 0622, FE82, 0622, FE82 */
31414 "\xd8\xa3"=>array("\xd8\xa3", "\xef\xba\x84", "\xd8\xa3", "\xef\xba\x84"), /* 0623, FE84, 0623, FE84 */
31415 "\xd8\xa4"=>array("\xd8\xa4", "\xef\xba\x86", "\xd8\xa4", "\xef\xba\x86"), /* 0624, FE86, 0624, FE86 */
31416 "\xd8\xa5"=>array("\xd8\xa5", "\xef\xba\x88", "\xd8\xa5", "\xef\xba\x88"), /* 0625, FE88, 0625, FE88 */
31417 "\xd8\xa6"=>array("\xd8\xa6", "\xef\xba\x8a", "\xef\xba\x8b", "\xef\xba\x8c"), /* 0626, FE8A, FE8B, FE8C */
31418 "\xd8\xa7"=>array("\xd8\xa7", "\xef\xba\x8e", "\xd8\xa7", "\xef\xba\x8e"), /* 0627, FE8E, 0627, FE8E */
31419 "\xd8\xa8"=>array("\xd8\xa8", "\xef\xba\x90", "\xef\xba\x91", "\xef\xba\x92"), /* 0628, FE90, FE91, FE92 */
31420 "\xd8\xa9"=>array("\xd8\xa9", "\xef\xba\x94", "\xd8\xa9", "\xef\xba\x94"), /* 0629, FE94, 0629, FE94 */
31421 "\xd8\xaa"=>array("\xd8\xaa", "\xef\xba\x96", "\xef\xba\x97", "\xef\xba\x98"), /* 062A, FE96, FE97, FE98 */
31422 "\xd8\xab"=>array("\xd8\xab", "\xef\xba\x9a", "\xef\xba\x9b", "\xef\xba\x9c"), /* 062B, FE9A, FE9B, FE9C */
31423 "\xd8\xac"=>array("\xd8\xac", "\xef\xba\x9e", "\xef\xba\x9f", "\xef\xba\xa0"), /* 062C, FE9E, FE9F, FEA0 */
31424 "\xd8\xad"=>array("\xd8\xad", "\xef\xba\xa2", "\xef\xba\xa3", "\xef\xba\xa4"), /* 062D, FEA2, FEA3, FEA4 */
31425 "\xd8\xae"=>array("\xd8\xae", "\xef\xba\xa6", "\xef\xba\xa7", "\xef\xba\xa8"), /* 062E, FEA6, FEA7, FEA8 */
31426 "\xd8\xaf"=>array("\xd8\xaf", "\xef\xba\xaa", "\xd8\xaf", "\xef\xba\xaa"), /* 062F, FEAA, 062F, FEAA */
31427 "\xd8\xb0"=>array("\xd8\xb0", "\xef\xba\xac", "\xd8\xb0", "\xef\xba\xac"), /* 0630, FEAC, 0630, FEAC */
31428 "\xd8\xb1"=>array("\xd8\xb1", "\xef\xba\xae", "\xd8\xb1", "\xef\xba\xae"), /* 0631, FEAE, 0631, FEAE */
31429 "\xd8\xb2"=>array("\xd8\xb2", "\xef\xba\xb0", "\xd8\xb2", "\xef\xba\xb0"), /* 0632, FEB0, 0632, FEB0 */
31430 "\xd8\xb3"=>array("\xd8\xb3", "\xef\xba\xb2", "\xef\xba\xb3", "\xef\xba\xb4"), /* 0633, FEB2, FEB3, FEB4 */
31431 "\xd8\xb4"=>array("\xd8\xb4", "\xef\xba\xb6", "\xef\xba\xb7", "\xef\xba\xb8"), /* 0634, FEB6, FEB7, FEB8 */
31432 "\xd8\xb5"=>array("\xd8\xb5", "\xef\xba\xba", "\xef\xba\xbb", "\xef\xba\xbc"), /* 0635, FEBA, FEBB, FEBC */
31433 "\xd8\xb6"=>array("\xd8\xb6", "\xef\xba\xbe", "\xef\xba\xbf", "\xef\xbb\x80"), /* 0636, FEBE, FEBF, FEC0 */
31434 "\xd8\xb7"=>array("\xd8\xb7", "\xef\xbb\x82", "\xef\xbb\x83", "\xef\xbb\x84"), /* 0637, FEC2, FEC3, FEC4 */
31435 "\xd8\xb8"=>array("\xd8\xb8", "\xef\xbb\x86", "\xef\xbb\x87", "\xef\xbb\x88"), /* 0638, FEC6, FEC7, FEC8 */
31436 "\xd8\xb9"=>array("\xd8\xb9", "\xef\xbb\x8a", "\xef\xbb\x8b", "\xef\xbb\x8c"), /* 0639, FECA, FECB, FECC */
31437 "\xd8\xba"=>array("\xd8\xba", "\xef\xbb\x8e", "\xef\xbb\x8f", "\xef\xbb\x90"), /* 063A, FECE, FECF, FED0 */
31438 "\xd9\x80"=>array("\xd9\x80", "\xd9\x80", "\xd9\x80", "\xd9\x80"), /* 0640, 0640, 0640, 0640 */
31439 "\xd9\x81"=>array("\xd9\x81", "\xef\xbb\x92", "\xef\xbb\x93", "\xef\xbb\x94"), /* 0641, FED2, FED3, FED4 */
31440 "\xd9\x82"=>array("\xd9\x82", "\xef\xbb\x96", "\xef\xbb\x97", "\xef\xbb\x98"), /* 0642, FED6, FED7, FED8 */
31441 "\xd9\x83"=>array("\xd9\x83", "\xef\xbb\x9a", "\xef\xbb\x9b", "\xef\xbb\x9c"), /* 0643, FEDA, FEDB, FEDC */
31442 "\xd9\x84"=>array("\xd9\x84", "\xef\xbb\x9e", "\xef\xbb\x9f", "\xef\xbb\xa0"), /* 0644, FEDE, FEDF, FEE0 */
31443 "\xd9\x85"=>array("\xd9\x85", "\xef\xbb\xa2", "\xef\xbb\xa3", "\xef\xbb\xa4"), /* 0645, FEE2, FEE3, FEE4 */
31444 "\xd9\x86"=>array("\xd9\x86", "\xef\xbb\xa6", "\xef\xbb\xa7", "\xef\xbb\xa8"), /* 0646, FEE6, FEE7, FEE8 */
31445 "\xd9\x87"=>array("\xd9\x87", "\xef\xbb\xaa", "\xef\xbb\xab", "\xef\xbb\xac"), /* 0647, FEEA, FEEB, FEEC */
31446 "\xd9\x88"=>array("\xd9\x88", "\xef\xbb\xae", "\xd9\x88", "\xef\xbb\xae"), /* 0648, FEEE, 0648, FEEE */
31447
31448 /* 0649 Alef Maksura should only appear at end of word (in Arabic) So Initial and medial are shown as isolated/final */
31449 "\xd9\x89"=>array("\xd9\x89", "\xef\xbb\xb0", "\xd9\x89", "\xef\xbb\xb0"), /* 0649, FEF0, 0649, FEF0 */
31450
31451 /* 0649 Alef Maksura Initial and Medial forms as given in Unicode FBE8 and FBE9 for Uighur Kazakh (not in some fonts) */
31452 "\xd9\x89"=>array("\xd9\x89", "\xef\xbb\xb0", "\xef\xaf\xa8", "\xef\xaf\xa9"), /* 0649, FEF0, FBE8, FBE9 not in most fonts */
31453
31454 "\xd9\x8a"=>array("\xd9\x8a", "\xef\xbb\xb2", "\xef\xbb\xb3", "\xef\xbb\xb4"), /* 064A, FEF2, FEF3, FEF4 */
31455 "\xd9\x8b"=>array("\xd9\x8b", "\xd9\x8b", "\xd9\x8b", "\xd9\x8b"), /* 064B, 064B, 064B, 064B */
31456 "\xd9\x8c"=>array("\xd9\x8c", "\xd9\x8c", "\xd9\x8c", "\xd9\x8c"), /* 064C, 064C, 064C, 064C */
31457 "\xd9\x8d"=>array("\xd9\x8d", "\xd9\x8d", "\xd9\x8d", "\xd9\x8d"), /* 064D, 064D, 064D, 064D */
31458 "\xd9\x8e"=>array("\xd9\x8e", "\xd9\x8e", "\xd9\x8e", "\xd9\x8e"), /* 064E, 064E, 064E, 064E */
31459 "\xd9\x8f"=>array("\xd9\x8f", "\xd9\x8f", "\xd9\x8f", "\xd9\x8f"), /* 064F, 064F, 064F, 064F */
31460 "\xd9\x90"=>array("\xd9\x90", "\xd9\x90", "\xd9\x90", "\xd9\x90"), /* 0650, 0650, 0650, 0650 */
31461 "\xd9\x91"=>array("\xd9\x91", "\xd9\x91", "\xd9\x91", "\xd9\x91"), /* 0651, 0651, 0651, 0651 */
31462 "\xd9\x92"=>array("\xd9\x92", "\xd9\x92", "\xd9\x92", "\xd9\x92"), /* 0652, 0652, 0652, 0652 */
31463 "\xd9\xb1"=>array("\xd9\xb1", "\xef\xad\x91", "\xd9\xb1", "\xef\xad\x91"), /* 0671, FB51, 0671, FB51 */
31464 "\xd9\xb2"=>array("\xd9\xb2", "\xef\x95\xb2", "\xd9\xb2", "\xef\x95\xb2"), /* 0672, F572, 0672, F572 */
31465 "\xd9\xb5"=>array("\xd9\xb5", "\xef\x95\xb5", "\xd9\xb5", "\xef\x95\xb5"), /* 0675, F575, 0675, F575 */
31466 "\xd9\xb8"=>array("\xd9\xb8", "\xef\x95\xb8", "\xef\xba\x8b", "\xef\xba\x8c"), /* 0678, F578, FE8B, FE8C ( as 0626 ) */
31467 "\xd9\xb9"=>array("\xd9\xb9", "\xef\xad\xa7", "\xef\xad\xa8", "\xef\xad\xa9"), /* 0679, FB67, FB68, FB69 */
31468 "\xd9\xba"=>array("\xd9\xba", "\xef\xad\x9f", "\xef\xad\xa0", "\xef\xad\xa1"), /* 067A, FB5F, FB60, FB61 */
31469 "\xd9\xbb"=>array("\xd9\xbb", "\xef\xad\x93", "\xef\xad\x94", "\xef\xad\x95"), /* 067B, FB53, FB54, FB55 */
31470 "\xd9\xbc"=>array("\xd9\xbc", "\xef\x95\xbc", "\xef\x99\xbc", "\xef\x9d\xbc"), /* 067C, F57C, F67C, F77C */
31471 "\xd9\xbd"=>array("\xd9\xbd", "\xef\x95\xbd", "\xef\x99\xbd", "\xef\x9d\xbd"), /* 067D, F57D, F67D, F77D */
31472 "\xd9\xbe"=>array("\xd9\xbe", "\xef\xad\x97", "\xef\xad\x98", "\xef\xad\x99"), /* 067E, FB57, FB58, FB59 */
31473 "\xd9\xbf"=>array("\xd9\xbf", "\xef\xad\xa3", "\xef\xad\xa4", "\xef\xad\xa5"), /* 067F, FB63, FB64, FB65 */
31474 "\xda\x80"=>array("\xda\x80", "\xef\xad\x9b", "\xef\xad\x9c", "\xef\xad\x9d"), /* 0680, FB5B, FB5C, FB5D */
31475 "\xda\x81"=>array("\xda\x81", "\xef\x96\x81", "\xef\x9a\x81", "\xef\x9e\x81"), /* 0681, F581, F681, F781 */
31476 "\xda\x82"=>array("\xda\x82", "\xef\x96\x82", "\xef\x9a\x82", "\xef\x9e\x82"), /* 0682, F582, F682, F782 */
31477 "\xda\x83"=>array("\xda\x83", "\xef\xad\xb7", "\xef\xad\xb8", "\xef\xad\xb9"), /* 0683, FB77, FB78, FB79 */
31478 "\xda\x84"=>array("\xda\x84", "\xef\xad\xb3", "\xef\xad\xb4", "\xef\xad\xb5"), /* 0684, FB73, FB74, FB75 */
31479 "\xda\x85"=>array("\xda\x85", "\xef\x96\x85", "\xef\x9a\x85", "\xef\x9e\x85"), /* 0685, F585, F685, F785 */
31480 "\xda\x86"=>array("\xda\x86", "\xef\xad\xbb", "\xef\xad\xbc", "\xef\xad\xbd"), /* 0686, FB7B, FB7C, FB7D */
31481 "\xda\x87"=>array("\xda\x87", "\xef\xad\xbf", "\xef\xae\x80", "\xef\xae\x81"), /* 0687, FB7F, FB80, FB81 */
31482 "\xda\x88"=>array("\xda\x88", "\xef\xae\x89", "\xda\x88", "\xda\x88"), /* 0688, FB89, 0688, 0688 */
31483 "\xda\x89"=>array("\xda\x89", "\xef\x96\x89", "\xda\x89", "\xda\x89"), /* 0689, F589, 0689, 0689 */
31484 "\xda\x91"=>array("\xda\x91", "\xef\xae\x8d", "\xda\x91", "\xef\xae\x8d"), /* 0691, FB8D, 0691, FB8D */
31485 "\xda\x93"=>array("\xda\x93", "\xef\x96\x93", "\xda\x93", "\xda\x93"), /* 0693, F593, 0693, 0693 */
31486 "\xda\x96"=>array("\xda\x96", "\xef\x96\x96", "\xda\x96", "\xda\x96"), /* 0696, F596, 0696, 0696 */
31487 "\xda\x98"=>array("\xda\x98", "\xef\xae\x8b", "\xda\x98", "\xef\xae\x8b"), /* 0698, FB8B, 0698, FB8B */
31488 "\xda\x9a"=>array("\xda\x9a", "\xef\x96\x9a", "\xef\x9a\x9a", "\xef\x9e\x9a"), /* 069A, F59A, F69A, F79A */
31489 "\xda\x9b"=>array("\xda\x9b", "\xef\x96\x9b", "\xef\x9a\x9b", "\xef\x9e\x9b"), /* 069B, F59B, F69B, F79B */
31490 "\xda\x9c"=>array("\xda\x9c", "\xef\x96\x9c", "\xef\x9a\x9c", "\xef\x9e\x9c"), /* 069C, F59C, F69C, F79C */
31491 "\xda\x9d"=>array("\xda\x9d", "\xef\x96\x9d", "\xef\x9a\x9d", "\xef\x9e\x9d"), /* 069D, F59D, F69D, F79D */
31492 "\xda\x9e"=>array("\xda\x9e", "\xef\x96\x9e", "\xef\x9a\x9e", "\xef\x9e\x9e"), /* 069E, F59E, F69E, F79E */
31493 "\xda\xa0"=>array("\xda\xa0", "\xef\x96\xa0", "\xef\x9a\xa0", "\xef\x9e\xa0"), /* 06A0, F5A0, F6A0, F7A0 */
31494 "\xda\xa1"=>array("\xda\xa1", "\xef\x96\xa1", "\xef\x9a\xa1", "\xef\x9e\xa1"), /* 06A1, F5A1, F6A1, F7A1 */
31495 "\xda\xa2"=>array("\xda\xa2", "\xef\x96\xa2", "\xef\x9a\xa2", "\xef\x9e\xa2"), /* 06A2, F5A2, F6A2, F7A2 */
31496 "\xda\xa3"=>array("\xda\xa3", "\xef\x96\xa3", "\xef\x9a\xa3", "\xef\x9e\xa3"), /* 06A3, F5A3, F6A3, F7A3 */
31497 "\xda\xa4"=>array("\xda\xa4", "\xef\xad\xab", "\xef\xad\xac", "\xef\xad\xad"), /* 06A4, FB6B, FB6C, FB6D */
31498 "\xda\xa5"=>array("\xda\xa5", "\xef\x96\xa5", "\xef\x9a\xa5", "\xef\x9e\xa5"), /* 06A5, F5A5, F6A5, F7A5 */
31499 "\xda\xa6"=>array("\xda\xa6", "\xef\xad\xaf", "\xef\xad\xb0", "\xef\xad\xb1"), /* 06A6, FB6F, FB70, FB71 */
31500 "\xda\xa9"=>array("\xda\xa9", "\xef\xae\x8f", "\xef\xae\x90", "\xef\xae\x91"), /* 06A9, FB8F, FB90, FB91 */
31501 "\xda\xaa"=>array("\xda\xaa", "\xef\x96\xaa", "\xef\x9a\xaa", "\xef\x9e\xaa"), /* 06AA, F5AA, F6AA, F7AA */
31502 "\xda\xab"=>array("\xda\xab", "\xef\x96\xab", "\xef\x9a\xab", "\xef\x9e\xab"), /* 06AB, F5AB, F6AB, F7AB */
31503 "\xda\xac"=>array("\xda\xac", "\xef\x96\xac", "\xef\x9a\xac", "\xef\x9e\xac"), /* 06AC, F5AC, F6AC, F7AC */
31504 "\xda\xad"=>array("\xda\xad", "\xef\xaf\x94", "\xef\xaf\x95", "\xef\xaf\x96"), /* 06AD, FBD4, FBD5, FBD6 */
31505 "\xda\xae"=>array("\xda\xae", "\xef\x96\xae", "\xef\x9a\xae", "\xef\x9e\xae"), /* 06AE, F5AE, F6AE, F7AE */
31506 "\xda\xaf"=>array("\xda\xaf", "\xef\xae\x93", "\xef\xae\x94", "\xef\xae\x95"), /* 06Af, FB93, FB94, FB95 */
31507 "\xda\xb0"=>array("\xda\xb0", "\xef\x96\xb0", "\xef\x9a\xb0", "\xef\x9e\xb0"), /* 06B0, F5B0, F6B0, F7B0 */
31508 "\xda\xb1"=>array("\xda\xb1", "\xef\xae\x9b", "\xef\xae\x9c", "\xef\xae\x9d"), /* 06B1, FB9B, FB9C, FB9D */
31509 "\xda\xb2"=>array("\xda\xb2", "\xef\x96\xb2", "\xef\x9a\xb2", "\xef\x9e\xb2"), /* 06B2, F5B2, F6B2, F7B2 */
31510 "\xda\xb3"=>array("\xda\xb3", "\xef\xae\x97", "\xef\xae\x98", "\xef\xae\x99"), /* 06B3, FB97, FB98, FB99 */
31511 "\xda\xb4"=>array("\xda\xb4", "\xef\x96\xb4", "\xef\x9a\xb4", "\xef\x9e\xb4"), /* 06B4, F5B4, F6B4, F7B4 */
31512 "\xda\xb5"=>array("\xda\xb5", "\xef\x96\xb5", "\xef\x9a\xb5", "\xef\x9e\xb5"), /* 06B5, F5B5, F6B5, F7B5 */
31513 "\xda\xb6"=>array("\xda\xb6", "\xef\x96\xb6", "\xef\x9a\xb6", "\xef\x9e\xb6"), /* 06B6, F5B6, F6B6, F7B6 */
31514 "\xda\xb7"=>array("\xda\xb7", "\xef\x96\xb7", "\xef\x9a\xb7", "\xef\x9e\xb7"), /* 06B7, F5B7, F6B7, F7B7 */
31515 "\xda\xb8"=>array("\xda\xb8", "\xef\x96\xb8", "\xef\x9a\xb8", "\xef\x9e\xb8"), /* 06B8, F5B8, F6B8, F7B8 */
31516 "\xda\xb9"=>array("\xda\xb9", "\xef\x96\xb9", "\xef\x9a\xb9", "\xef\x9e\xb9"), /* 06B9, F5B9, F6B9, F7B9 */
31517 "\xda\xba"=>array("\xda\xba", "\xef\xae\x9f", "\xda\xba", "\xda\xba"), /* 06BA, FB9F, 06BA, 06BA */
31518 "\xda\xbb"=>array("\xda\xbb", "\xef\xae\xa1", "\xef\xae\xa2", "\xef\xae\xa3"), /* 06BB, FBA1, FBA2, FBA3 */
31519 "\xda\xbc"=>array("\xda\xbc", "\xef\x96\xbc", "\xef\x9a\xbc", "\xef\x9e\xbc"), /* 06BC, F5BC, F6BC, F7BC */
31520 "\xda\xbe"=>array("\xda\xbe", "\xef\xae\xab", "\xef\xae\xac", "\xef\xae\xad"), /* 06BE, FBAB, FBAC, FBAD */
31521 "\xda\xbf"=>array("\xda\xbf", "\xef\x96\xbf", "\xef\x9a\xbf", "\xef\x9e\xbf"), /* 06BF, F5BF, F6BF, F7BF */
31522 "\xdb\x80"=>array("\xdb\x80", "\xef\xae\xa5", "\xdb\x80", "\xef\xae\xa5"), /* 06C0, FBA5, 06C0, FBA5 */
31523 "\xdb\x81"=>array("\xdb\x81", "\xef\xae\xa7", "\xef\xae\xa8", "\xef\xae\xa9"), /* 06C1, FBA7, FBA8, FBA9 */
31524 "\xdb\x8c"=>array("\xdb\x8c", "\xef\xaf\xbd", "\xef\xaf\xbe", "\xef\xaf\xbf"), /* 06CC, FBFD, FBFE, FBFF */
31525 "\xdb\x8d"=>array("\xdb\x8d", "\xef\x97\x8d", "\xdb\x8d", "\xef\x97\x8d"), /* 06CD, F5CD, 06CD, F5CD */
31526 "\xdb\x8e"=>array("\xdb\x8e", "\xef\x97\x8e", "\xef\x9b\x8e", "\xef\x9f\x8e"), /* 06CE, F5CE, F6CE, F7CE */
31527 "\xdb\x90"=>array("\xdb\x90", "\xef\xaf\xa5", "\xef\xaf\xa6", "\xef\xaf\xa7"), /* 06D0, FBE5, FBE6, FBE7 */
31528 "\xdb\x91"=>array("\xdb\x91", "\xef\x97\x91", "\xef\xad\x98", "\xef\xad\x99"), /* 06D1, F5D1, FB58, FB59 Fudge borrows from 067E */
31529 "\xdb\x92"=>array("\xdb\x92", "\xef\xae\xaf", "\xdb\x92", "\xef\xae\xaf"), /* 06D2, FBAF, 06D2, FBAF */
31530 "\xdb\x93"=>array("\xdb\x93", "\xef\xae\xb1", "\xdb\x93", "\xef\xae\xb1"), /* 06D3, FBB1, 06D3, FBB1 */
31531 );
31532
31533
31534 // LAM with ALEF ligatures (Mandatory ligatures)
31535
31536 // U+0644; U+0622; U+0644; U+0623; U+0644; U+0625; U+0644; U+0627;
31537 $this->arabLigGlyphs = "\xd9\x84\xd8\xa2\xd9\x84\xd8\xa3\xd9\x84\xd8\xa5\xd9\x84\xd8\xa7";
31538 $this->arabLigHex = 'FEF5FEF6FEF5FEF6FEF7FEF8FEF7FEF8FEF9FEFAFEF9FEFAFEFBFEFCFEFBFEFC';
31539
31540 }
31541
31542 // mPDF 5.4.08
31543 function ArabJoin($str) {
31544 if (!$this->arabGlyphs) { $this->InitArabic(); }
31545 $crntChar = null;
31546 $prevChar = null;
31547 $nextChar = null;
31548 $output = array();
31549 $chars = preg_split('//u', $str);
31550 $max = count($chars);
31551 for ($i = $max - 1; $i >= 0; $i--) {
31552 $crntChar = $chars[$i];
31553 if ($i > 0){ $prevChar = $chars[$i - 1]; }
31554 else{ $prevChar = NULL; }
31555 if ($prevChar && mb_strpos($this->arabVowels, $prevChar, 0, 'utf-8') !== false) {
31556 $prevChar = $chars[$i - 2];
31557 if ($prevChar && mb_strpos($this->arabVowels, $prevChar, 0, 'utf-8') !== false) {
31558 $prevChar = $chars[$i - 3];
31559 }
31560 }
31561 if ($crntChar && mb_strpos($this->arabVowels, $crntChar, 0, 'utf-8') !== false) {
31562 // If next_char = nextLink && prev_char = prevLink:
31563 // Added && $prevchar (defined) else error on mb_strpos()
31564 if ($chars[$i + 1] && (mb_strpos($this->arabNextLink, $chars[$i + 1], 0, 'utf-8') !== false) && $prevChar && (mb_strpos($this->arabPrevLink, $prevChar, 0, 'utf-8') !== false)) {
31565 $output[] = $this->get_arab_glyphs($crntChar, 1); // <final> form
31566 }
31567 else {
31568 $output[] = $this->get_arab_glyphs($crntChar, 0); // <isolated> form
31569 }
31570 continue;
31571 }
31572 // NB = &#x622 &#x623; &#x625; &#x627; &#x644;
31573 if (isset($chars[$i + 1]) && in_array($chars[$i + 1], array("\xd8\xa2","\xd8\xa3","\xd8\xa5","\xd8\xa7")) && $crntChar == "\xd9\x84"){
31574 continue;
31575 }
31576 if (ord($crntChar) < 128) {
31577 $output[] = $crntChar;
31578 $nextChar = $crntChar;
31579 continue;
31580 }
31581 $form = 0;
31582 if ($prevChar == "\xd9\x84" && ($crntChar == "\xd8\xa2" || $crntChar == "\xd8\xa3" || $crntChar == "\xd8\xa5" || $crntChar == "\xd8\xa7")) {
31583 if ($chars[$i - 2] && mb_strpos($this->arabPrevLink, $chars[$i - 2], 0, 'utf-8') !== false) {
31584 $form++; // <final> form
31585 }
31586 $pos = mb_strpos($this->arabLigGlyphs, ($prevChar . $crntChar), 0, 'utf-8');
31587 $pos = $pos*8 + $form*4;
31588 $pres = (mb_substr($this->arabLigHex, $pos, 4, 'utf-8'));
31589 // If presentation forms for mandatory ligatures with diacritics not present (even if remapped from e.g. uni0644uni0625)
31590 // try replacing with mandatory ligature Alef/lam isolated/final FEFB/FEFC + diacritic glyph
31591 if (!$this->_charDefined($this->CurrentFont['cw'], hexdec($pres)) && $this->_charDefined($this->CurrentFont['cw'], hexdec('FEFB'))) {
31592 if ($pres=='FEF5') { $output[] = strcode2utf('&#xFEFB;&#x0653;'); }
31593 else if ($pres=='FEF6') { $output[] = strcode2utf('&#xFEFC;&#x0653;'); }
31594 else if ($pres=='FEF7') { $output[] = strcode2utf('&#xFEFB;&#x0654;'); }
31595 else if ($pres=='FEF8') { $output[] = strcode2utf('&#xFEFC;&#x0654;'); }
31596 else if ($pres=='FEF9') { $output[] = strcode2utf('&#xFEFB;&#x0655;'); }
31597 else if ($pres=='FEFA') { $output[] = strcode2utf('&#xFEFC;&#x0655;'); }
31598 }
31599 else {
31600 $output[] = strcode2utf('&#x' . $pres . ';');
31601 }
31602 $nextChar = $prevChar;
31603 continue;
31604 }
31605 if ($prevChar && mb_strpos($this->arabPrevLink, $prevChar, 0, 'utf-8') !== false) {
31606 $form++;
31607 }
31608 if ($nextChar && mb_strpos($this->arabNextLink, $nextChar, 0, 'utf-8') !== false) {
31609 $form += 2;
31610 }
31611 $output[] = $this->get_arab_glyphs($crntChar, $form) ;
31612 $nextChar = $crntChar;
31613 }
31614 $ra = array_reverse($output);
31615 $s = implode($ra);
31616 return $s;
31617 }
31618
31619 // mPDF 5.4.08
31620 function get_arab_glyphs($char, $type) {
31621 if ($type>0 && isset($this->arabGlyphs[$char])) {
31622 // If presentation form specified FB** - FE** = Arabic presentation Forms
31623 if (preg_match("/[\x{FB50}-\x{FEFF}]/u",$this->arabGlyphs[$char][$type])) {
31624 $unicode = $this->UTF8StringToArray($this->arabGlyphs[$char][$type], false);
31625 if ($this->_charDefined($this->CurrentFont['cw'],$unicode[0])) { return $this->arabGlyphs[$char][$type]; }
31626 else if (isset($this->CurrentFont['unAGlyphs'])) {
31627 $uni = $this->UTF8StringToArray($char, false);
31628 $pua = $uni[0] - 1536 + 62464 + 256*$type ;
31629 if ($this->_charDefined($this->CurrentFont['cw'], $pua)) { return strcode2utf('&#x' . dechex($pua) . ';'); }
31630 else return $char;
31631 }
31632 else return $char;
31633 }
31634 // If PUA form specified and unAGlphs font set F5** F6** F7** = Private use area used by unAGlyphs in mPDF
31635 if (preg_match("/[\x{F500}-\x{F7FF}]/u",$this->arabGlyphs[$char][$type]) && isset($this->CurrentFont['unAGlyphs'])) {
31636 $unicode = $this->UTF8StringToArray($this->arabGlyphs[$char][$type], false);
31637 if ($this->_charDefined($this->CurrentFont['cw'],$unicode[0])) { return $this->arabGlyphs[$char][$type]; }
31638 else return $char;
31639 }
31640 return $this->arabGlyphs[$char][$type];
31641 }
31642 else return $char;
31643 }
31644 /*-- END RTL --*/
31645
31646
31647
31648 //===========================
31649 // Functions originally in htmltoolkit - moved mPDF 4.0
31650
31651 // Call-back function Used for usort in fn _tableWrite
31652
31653 function _cmpdom($a, $b) {
31654 return ($a["dom"] < $b["dom"]) ? -1 : 1;
31655 }
31656
31657 function mb_strrev($str, $enc = 'utf-8'){
31658 $ch = array();
31659 $ch = preg_split('//u',$str);
31660 $revch = array_reverse($ch);
31661 return implode('',$revch);
31662 }
31663
31664 /*-- COLUMNS --*/
31665 // Callback function from function printcolumnbuffer in mpdf
31666 function columnAdjustAdd($type,$k,$xadj,$yadj,$a,$b,$c=0,$d=0,$e=0,$f=0) {
31667 if ($type == 'Td') { // xpos,ypos
31668 $a += ($xadj * $k);
31669 $b -= ($yadj * $k);
31670 return 'BT '.sprintf('%.3F %.3F',$a,$b).' Td';
31671 }
31672 else if ($type == 're') { // xpos,ypos,width,height
31673 $a += ($xadj * $k);
31674 $b -= ($yadj * $k);
31675 return sprintf('%.3F %.3F %.3F %.3F',$a,$b,$c,$d).' re';
31676 }
31677 else if ($type == 'l') { // xpos,ypos,x2pos,y2pos
31678 $a += ($xadj * $k);
31679 $b -= ($yadj * $k);
31680 return sprintf('%.3F %.3F l',$a,$b);
31681 }
31682 else if ($type == 'img') { // width,height,xpos,ypos
31683 $c += ($xadj * $k);
31684 $d -= ($yadj * $k);
31685 return sprintf('q %.3F 0 0 %.3F %.3F %.3F',$a,$b,$c,$d).' cm /'.$e;
31686 }
31687 else if ($type == 'draw') { // xpos,ypos
31688 $a += ($xadj * $k);
31689 $b -= ($yadj * $k);
31690 return sprintf('%.3F %.3F m',$a,$b);
31691 }
31692 else if ($type == 'bezier') { // xpos,ypos,x2pos,y2pos,x3pos,y3pos
31693 $a += ($xadj * $k);
31694 $b -= ($yadj * $k);
31695 $c += ($xadj * $k);
31696 $d -= ($yadj * $k);
31697 $e += ($xadj * $k);
31698 $f -= ($yadj * $k);
31699 return sprintf('%.3F %.3F %.3F %.3F %.3F %.3F',$a,$b,$c,$d,$e,$f).' c';
31700 }
31701 }
31702 /*-- END COLUMNS --*/
31703
31704
31705
31706 function ConvertColor($color="#000000"){
31707 $color = trim(strtolower($color));
31708 $c = false;
31709 if ($color=='transparent') { return false; }
31710 else if ($color=='inherit') { return false; }
31711 else if (isset($this->SVGcolors[$color])) $color = $this->SVGcolors[$color];
31712
31713 if (preg_match('/^[\d]+$/',$color)) { $c = (array(1,$color)); } // i.e. integer only
31714 else if ($color[0] == '#') { //case of #nnnnnn or #nnn
31715 $cor = preg_replace('/\s+.*/','',$color); // in case of Background: #CCC url() x-repeat etc.
31716 if (strlen($cor) == 4) { // Turn #RGB into #RRGGBB
31717 $cor = "#" . $cor[1] . $cor[1] . $cor[2] . $cor[2] . $cor[3] . $cor[3];
31718 }
31719 $r = hexdec(substr($cor, 1, 2));
31720 $g = hexdec(substr($cor, 3, 2));
31721 $b = hexdec(substr($cor, 5, 2));
31722 $c = array(3,$r,$g,$b);
31723 }
31724 else if (preg_match('/(rgba|rgb|device-cmyka|cmyka|device-cmyk|cmyk|hsla|hsl|spot)\((.*?)\)/',$color,$m)) { // mPDF 5.6.05
31725 $type= $m[1];
31726 $cores = explode(",", $m[2]);
31727 $ncores = count($cores);
31728 if (stristr($cores[0],'%') ) {
31729 $cores[0] += 0;
31730 if ($type=='rgb' || $type=='rgba') { $cores[0] = intval($cores[0]*255/100); }
31731 }
31732 if ($ncores>1 && stristr($cores[1],'%') ) {
31733 $cores[1] += 0;
31734 if ($type=='rgb' || $type=='rgba') { $cores[1] = intval($cores[1]*255/100); }
31735 if ($type=='hsl' || $type=='hsla') { $cores[1] = $cores[1]/100; }
31736 }
31737 if ($ncores>2 && stristr($cores[2],'%') ) {
31738 $cores[2] += 0;
31739 if ($type=='rgb' || $type=='rgba') { $cores[2] = intval($cores[2]*255/100); }
31740 if ($type=='hsl' || $type=='hsla') { $cores[2] = $cores[2]/100; }
31741 }
31742 if ($ncores>3 && stristr($cores[3],'%') ) {
31743 $cores[3] += 0;
31744 }
31745
31746 if ($type=='rgb') { $c = array(3,$cores[0],$cores[1],$cores[2]); }
31747 else if ($type=='rgba') { $c = array(5,$cores[0],$cores[1],$cores[2],$cores[3]*100); }
31748 else if ($type=='cmyk' || $type=='device-cmyk') { $c = array(4,$cores[0],$cores[1],$cores[2],$cores[3]); } // mPDF 5.6.05
31749 else if ($type=='cmyka' || $type=='device-cmyka') { $c = array(6,$cores[0],$cores[1],$cores[2],$cores[3],$cores[4]*100); } // mPDF 5.6.05
31750 else if ($type=='hsl' || $type=='hsla') {
31751 $conv = $this->hsl2rgb($cores[0]/360,$cores[1],$cores[2]);
31752 if ($type=='hsl') { $c = array(3,$conv[0],$conv[1],$conv[2]); }
31753 else if ($type=='hsla') { $c = array(5,$conv[0],$conv[1],$conv[2],$cores[3]*100); }
31754 }
31755 else if ($type=='spot') {
31756 $name = strtoupper(trim($cores[0]));
31757 // mPDF 5.6.59
31758 if(!isset($this->spotColors[$name])) {
31759 if (isset($cores[5])) { $this->AddSpotColor($cores[0],$cores[2],$cores[3],$cores[4],$cores[5]); }
31760 else { $this->Error('Undefined spot color: '.$name); }
31761 }
31762 $c = array(2,$this->spotColors[$name]['i'],$cores[1]);
31763 }
31764 }
31765
31766
31767 // $this->restrictColorSpace
31768 // 1 - allow GRAYSCALE only [convert CMYK/RGB->gray]
31769 // 2 - allow RGB / SPOT COLOR / Grayscale [convert CMYK->RGB]
31770 // 3 - allow CMYK / SPOT COLOR / Grayscale [convert RGB->CMYK]
31771 if ($this->PDFA || $this->PDFX || $this->restrictColorSpace) {
31772 if ($c[0]==1) { // GRAYSCALE
31773 }
31774 else if ($c[0]==2) { // SPOT COLOR
31775 if (!isset($this->spotColorIDs[$c[1]])) { die('Error: Spot colour has not been defined - '.$this->spotColorIDs[$c[1]]); }
31776 if ($this->PDFA) {
31777 if ($this->PDFA && !$this->PDFAauto) { $this->PDFAXwarnings[] = "Spot color specified '".$this->spotColorIDs[$c[1]]."' (converted to process color)"; }
31778 if ($this->restrictColorSpace!=3) {
31779 $sp = $this->spotColors[$this->spotColorIDs[$c[1]]];
31780 $c = $this->cmyk2rgb(array(4,$sp['c'],$sp['m'],$sp['y'],$sp['k']));
31781 }
31782 }
31783 else if ($this->restrictColorSpace==1) {
31784 $sp = $this->spotColors[$this->spotColorIDs[$c[1]]];
31785 $c = $this->cmyk2gray(array(4,$sp['c'],$sp['m'],$sp['y'],$sp['k']));
31786 }
31787 }
31788 else if ($c[0]==3) { // RGB
31789 if ($this->PDFX || ($this->PDFA && $this->restrictColorSpace==3)) {
31790 if (($this->PDFA && !$this->PDFAauto) || ($this->PDFX && !$this->PDFXauto)) { $this->PDFAXwarnings[] = "RGB color specified '".$color."' (converted to CMYK)"; }
31791 $c = $this->rgb2cmyk($c);
31792 }
31793 else if ($this->restrictColorSpace==1) { $c = $this->rgb2gray($c); }
31794 else if ($this->restrictColorSpace==3) { $c = $this->rgb2cmyk($c); }
31795 }
31796 else if ($c[0]==4) { // CMYK
31797 if ($this->PDFA && $this->restrictColorSpace!=3) {
31798 if ($this->PDFA && !$this->PDFAauto) { $this->PDFAXwarnings[] = "CMYK color specified '".$color."' (converted to RGB)"; }
31799 $c = $this->cmyk2rgb($c);
31800 }
31801 else if ($this->restrictColorSpace==1) { $c = $this->cmyk2gray($c); }
31802 else if ($this->restrictColorSpace==2) { $c = $this->cmyk2rgb($c); }
31803 }
31804 else if ($c[0]==5) { // RGBa
31805 if ($this->PDFX || ($this->PDFA && $this->restrictColorSpace==3)) {
31806 if (($this->PDFA && !$this->PDFAauto) || ($this->PDFX && !$this->PDFXauto)) { $this->PDFAXwarnings[] = "RGB color with transparency specified '".$color."' (converted to CMYK without transparency)"; }
31807 $c = $this->rgb2cmyk($c);
31808 $c = array(4, $c[1], $c[2], $c[3], $c[4]);
31809 }
31810 else if ($this->PDFA && $this->restrictColorSpace!=3) {
31811 if (!$this->PDFAauto) { $this->PDFAXwarnings[] = "RGB color with transparency specified '".$color."' (converted to RGB without transparency)"; }
31812 $c = $this->rgb2cmyk($c);
31813 $c = array(4, $c[1], $c[2], $c[3], $c[4]);
31814 }
31815 else if ($this->restrictColorSpace==1) { $c = $this->rgb2gray($c); }
31816 else if ($this->restrictColorSpace==3) { $c = $this->rgb2cmyk($c); }
31817 }
31818 else if ($c[0]==6) { // CMYKa
31819 if ($this->PDFA && $this->restrictColorSpace!=3) {
31820 if (($this->PDFA && !$this->PDFAauto) || ($this->PDFX && !$this->PDFXauto)) { $this->PDFAXwarnings[] = "CMYK color with transparency specified '".$color."' (converted to RGB without transparency)"; }
31821 $c = $this->cmyk2rgb($c);
31822 $c = array(3, $c[1], $c[2], $c[3]);
31823 }
31824 else if ($this->PDFX || ($this->PDFA && $this->restrictColorSpace==3)) {
31825 if (($this->PDFA && !$this->PDFAauto) || ($this->PDFX && !$this->PDFXauto)) { $this->PDFAXwarnings[] = "CMYK color with transparency specified '".$color."' (converted to CMYK without transparency)"; }
31826 $c = $this->cmyk2rgb($c);
31827 $c = array(3, $c[1], $c[2], $c[3]);
31828 }
31829 else if ($this->restrictColorSpace==1) { $c = $this->cmyk2gray($c); }
31830 else if ($this->restrictColorSpace==2) { $c = $this->cmyk2rgb($c); }
31831 }
31832 }
31833 if (is_array($c)) {
31834 $c = array_pad($c, 6, 0);
31835 $cstr = pack("a1ccccc", $c[0], ($c[1] & 0xFF), ($c[2] & 0xFF), ($c[3] & 0xFF), ($c[4] & 0xFF), ($c[5] & 0xFF) );
31836 }
31837 return $cstr;
31838 }
31839
31840 function rgb2gray($c) {
31841 if (isset($c[4])) { return array(1,(($c[1] * .21) + ($c[2] * .71) + ($c[3] * .07)), ord(1), $c[4]); }
31842 else { return array(1,(($c[1] * .21) + ($c[2] * .71) + ($c[3] * .07))); }
31843 }
31844
31845 function cmyk2gray($c) {
31846 $rgb = $this->cmyk2rgb($c);
31847 return $this->rgb2gray($rgb);
31848 }
31849
31850 function rgb2cmyk($c) {
31851 $cyan = 1 - ($c[1] / 255);
31852 $magenta = 1 - ($c[2] / 255);
31853 $yellow = 1 - ($c[3] / 255);
31854 $min = min($cyan, $magenta, $yellow);
31855
31856 if ($min == 1) {
31857 if ($c[0]==5) { return array (6,100,100,100,100, $c[4]); }
31858 else { return array (4,100,100,100,100); }
31859 // For K-Black
31860 //if ($c[0]==5) { return array (6,0,0,0,100, $c[4]); }
31861 //else { return array (4,0,0,0,100); }
31862 }
31863 $K = $min;
31864 $black = 1 - $K;
31865 if ($c[0]==5) { return array (6,($cyan-$K)*100/$black, ($magenta-$K)*100/$black, ($yellow-$K)*100/$black, $K*100, $c[4]); }
31866 else { return array (4,($cyan-$K)*100/$black, ($magenta-$K)*100/$black, ($yellow-$K)*100/$black, $K*100); }
31867 }
31868
31869
31870 function cmyk2rgb($c) {
31871 $rgb = array();
31872 $colors = 255 - ($c[4]*2.55);
31873 $rgb[0] = intval($colors * (255 - ($c[1]*2.55))/255);
31874 $rgb[1] = intval($colors * (255 - ($c[2]*2.55))/255);
31875 $rgb[2] = intval($colors * (255 - ($c[3]*2.55))/255);
31876 if ($c[0]==6) { return array (5,$rgb[0],$rgb[1],$rgb[2], $c[5]); }
31877 else { return array (3,$rgb[0],$rgb[1],$rgb[2]); }
31878 }
31879
31880 function rgb2hsl($var_r, $var_g, $var_b) {
31881 $var_min = min($var_r,$var_g,$var_b);
31882 $var_max = max($var_r,$var_g,$var_b);
31883 $del_max = $var_max - $var_min;
31884 $l = ($var_max + $var_min) / 2;
31885 if ($del_max == 0) {
31886 $h = 0;
31887 $s = 0;
31888 }
31889 else {
31890 if ($l < 0.5) { $s = $del_max / ($var_max + $var_min); }
31891 else { $s = $del_max / (2 - $var_max - $var_min); }
31892 $del_r = ((($var_max - $var_r) / 6) + ($del_max / 2)) / $del_max;
31893 $del_g = ((($var_max - $var_g) / 6) + ($del_max / 2)) / $del_max;
31894 $del_b = ((($var_max - $var_b) / 6) + ($del_max / 2)) / $del_max;
31895 if ($var_r == $var_max) { $h = $del_b - $del_g; }
31896 elseif ($var_g == $var_max) { $h = (1 / 3) + $del_r - $del_b; }
31897 elseif ($var_b == $var_max) { $h = (2 / 3) + $del_g - $del_r; };
31898 if ($h < 0) { $h += 1; }
31899 if ($h > 1) { $h -= 1; }
31900 }
31901 return array($h,$s,$l);
31902 }
31903
31904
31905 function hsl2rgb($h2,$s2,$l2) {
31906 // Input is HSL value of complementary colour, held in $h2, $s, $l as fractions of 1
31907 // Output is RGB in normal 255 255 255 format, held in $r, $g, $b
31908 // Hue is converted using function hue_2_rgb, shown at the end of this code
31909 if ($s2 == 0) {
31910 $r = $l2 * 255;
31911 $g = $l2 * 255;
31912 $b = $l2 * 255;
31913 }
31914 else {
31915 if ($l2 < 0.5) { $var_2 = $l2 * (1 + $s2); }
31916 else { $var_2 = ($l2 + $s2) - ($s2 * $l2); }
31917 $var_1 = 2 * $l2 - $var_2;
31918 $r = round(255 * $this->hue_2_rgb($var_1,$var_2,$h2 + (1 / 3)));
31919 $g = round(255 * $this->hue_2_rgb($var_1,$var_2,$h2));
31920 $b = round(255 * $this->hue_2_rgb($var_1,$var_2,$h2 - (1 / 3)));
31921 }
31922 return array($r,$g,$b);
31923 }
31924
31925 function hue_2_rgb($v1,$v2,$vh) {
31926 // Function to convert hue to RGB, called from above
31927 if ($vh < 0) { $vh += 1; };
31928 if ($vh > 1) { $vh -= 1; };
31929 if ((6 * $vh) < 1) { return ($v1 + ($v2 - $v1) * 6 * $vh); };
31930 if ((2 * $vh) < 1) { return ($v2); };
31931 if ((3 * $vh) < 2) { return ($v1 + ($v2 - $v1) * ((2 / 3 - $vh) * 6)); };
31932 return ($v1);
31933 }
31934
31935 function _invertColor($cor) {
31936 if ($cor[0]==3 || $cor[0]==5) { // RGB
31937 return array(3, (255-$cor[1]), (255-$cor[2]), (255-$cor[3]));
31938 }
31939 else if ($cor[0]==4 || $cor[0]==6) { // CMYK
31940 return array(4, (100-$cor[1]), (100-$cor[2]), (100-$cor[3]), (100-$cor[4]));
31941 }
31942 else if ($cor[0]==1) { // Grayscale
31943 return array(1, (255-$cor[1]));
31944 }
31945 // Cannot cope with non-RGB colors at present
31946 die('Error in _invertColor - trying to invert non-RGB color');
31947 }
31948
31949 function _colAtoString($cor) {
31950 $s = '';
31951 if ($cor{0}==1) $s = 'rgb('.ord($cor{1}).','.ord($cor{1}).','.ord($cor{1}).')';
31952 else if ($cor{0}==2) $s = 'spot('.ord($cor{1}).','.ord($cor{2}).')'; // SPOT COLOR
31953 else if ($cor{0}==3) $s = 'rgb('.ord($cor{1}).','.ord($cor{2}).','.ord($cor{3}).')';
31954 else if ($cor{0}==4) $s = 'cmyk('.ord($cor{1}).','.ord($cor{2}).','.ord($cor{3}).','.ord($cor{4}).')';
31955 else if ($cor{0}==5) $s = 'rgba('.ord($cor{1}).','.ord($cor{2}).','.ord($cor{3}).','.sprintf('%0.2F',ord($cor{4})/100).')';
31956 else if ($cor{0}==6) $s = 'cmyka('.ord($cor{1}).','.ord($cor{2}).','.ord($cor{3}).','.ord($cor{4}).','.sprintf('%0.2F',ord($cor{5})/100).')';
31957 return $s;
31958 }
31959
31960 function ConvertSize($size=5,$maxsize=0,$fontsize=false,$usefontsize=true){
31961 // usefontsize - setfalse for e.g. margins - will ignore fontsize for % values
31962 // Depends of maxsize value to make % work properly. Usually maxsize == pagewidth
31963 // For text $maxsize = Fontsize
31964 // Setting e.g. margin % will use maxsize (pagewidth) and em will use fontsize
31965 //Identify size (remember: we are using 'mm' units here)
31966 $size = trim(strtolower($size));
31967
31968 if ( $size == 'thin' ) $size = 1*(25.4/$this->dpi); //1 pixel width for table borders
31969 elseif ( stristr($size,'px') ) $size *= (25.4/$this->dpi); //pixels
31970 elseif ( stristr($size,'cm') ) $size *= 10; //centimeters
31971 elseif ( stristr($size,'mm') ) $size += 0; //millimeters
31972 elseif ( stristr($size,'pt') ) $size *= 25.4/72; //72 pts/inch
31973 elseif ( stristr($size,'rem') ) { // mPDF 5.6.12
31974 $size += 0; //make "0.83rem" become simply "0.83"
31975 $size *= ($this->default_font_size / _MPDFK);
31976 }
31977 elseif ( stristr($size,'em') ) {
31978 $size += 0; //make "0.83em" become simply "0.83"
31979 if ($fontsize) { $size *= $fontsize; }
31980 else { $size *= $maxsize; }
31981 }
31982 elseif ( stristr($size,'%') ) {
31983 $size += 0; //make "90%" become simply "90"
31984 if ($fontsize && $usefontsize) { $size *= $fontsize/100; }
31985 else { $size *= $maxsize/100; }
31986 }
31987 elseif ( stristr($size,'in') ) $size *= 25.4; //inches
31988 elseif ( stristr($size,'pc') ) $size *= 38.1/9; //PostScript picas
31989 elseif ( stristr($size,'ex') ) { // Approximates "ex" as half of font height
31990 $size += 0; //make "3.5ex" become simply "3.5"
31991 if ($fontsize) { $size *= $fontsize/2; }
31992 else { $size *= $maxsize/2; }
31993 }
31994 elseif ( $size == 'medium' ) $size = 3*(25.4/$this->dpi); //3 pixel width for table borders
31995 elseif ( $size == 'thick' ) $size = 5*(25.4/$this->dpi); //5 pixel width for table borders
31996 elseif ($size == 'xx-small') {
31997 if ($fontsize) { $size *= $fontsize*0.7; }
31998 else { $size *= $maxsize*0.7; }
31999 }
32000 elseif ($size == 'x-small') {
32001 if ($fontsize) { $size *= $fontsize*0.77; }
32002 else { $size *= $maxsize*0.77; }
32003 }
32004 elseif ($size == 'small') {
32005 if ($fontsize) { $size *= $fontsize*0.86; }
32006 else { $size *= $maxsize*0.86; }
32007 }
32008 elseif ($size == 'medium') {
32009 if ($fontsize) { $size *= $fontsize; }
32010 else { $size *= $maxsize; }
32011 }
32012 elseif ($size == 'large') {
32013 if ($fontsize) { $size *= $fontsize*1.2; }
32014 else { $size *= $maxsize*1.2; }
32015 }
32016 elseif ($size == 'x-large') {
32017 if ($fontsize) { $size *= $fontsize*1.5; }
32018 else { $size *= $maxsize*1.5; }
32019 }
32020 elseif ($size == 'xx-large') {
32021 if ($fontsize) { $size *= $fontsize*2; }
32022 else { $size *= $maxsize*2; }
32023 }
32024 else $size *= (25.4/$this->dpi); //nothing == px
32025
32026 return $size;
32027 }
32028
32029
32030 function lesser_entity_decode($html) {
32031 //supports the most used entity codes (only does ascii safe characters)
32032 //$html = str_replace("&nbsp;"," ",$html); // mPDF 5.3.59
32033 $html = str_replace("&lt;","<",$html);
32034 $html = str_replace("&gt;",">",$html);
32035
32036 $html = str_replace("&apos;","'",$html);
32037 $html = str_replace("&quot;",'"',$html);
32038 $html = str_replace("&amp;","&",$html);
32039 return $html;
32040 }
32041
32042 function AdjustHTML($html, $tabSpaces=8) {
32043 //Try to make the html text more manageable (turning it into XHTML)
32044 if (PHP_VERSION_ID < 50307) {
32045 if (strlen($html) > 100000) {
32046 if (PHP_VERSION_ID < 50200) $this->Error("The HTML code is more than 100,000 characters. You should use WriteHTML() with smaller string lengths.");
32047 else ini_set("pcre.backtrack_limit","1000000");
32048 }
32049 }
32050
32051 /*-- ANNOTATIONS --*/
32052 preg_match_all("/(<annotation.*?>)/si", $html, $m);
32053 if (count($m[1])) {
32054 for($i=0;$i<count($m[1]);$i++) {
32055 $sub = preg_replace("/\n/si", "\xbb\xa4\xac", $m[1][$i]);
32056 $html = preg_replace('/'.preg_quote($m[1][$i], '/').'/si', $sub, $html);
32057 }
32058 }
32059 /*-- END ANNOTATIONS --*/
32060
32061 preg_match_all("/(<svg.*?<\/svg>)/si", $html, $svgi);
32062 if (count($svgi[0])) {
32063 for($i=0;$i<count($svgi[0]);$i++) {
32064 $file = _MPDF_TEMP_PATH.'_tempSVG'.RAND(1,10000).'_'.$i.'.svg';
32065 //Save to local file
32066 file_put_contents($file, $svgi[0][$i]);
32067 $html = str_replace($svgi[0][$i], '<img src="'.$file.'" />', $html); // mPDF 5.5.18
32068 }
32069 }
32070
32071 //Remove javascript code from HTML (should not appear in the PDF file)
32072 $html = preg_replace('/<script.*?<\/script>/is','',$html);
32073
32074 //Remove special comments
32075 $html = preg_replace('/<!--mpdf/i','',$html);
32076 $html = preg_replace('/mpdf-->/i','',$html);
32077
32078 //Remove comments from HTML (should not appear in the PDF file)
32079 $html = preg_replace('/<!--.*?-->/s','',$html);
32080
32081 $html = preg_replace('/\f/','',$html); //replace formfeed by nothing
32082 $html = preg_replace('/\r/','',$html); //replace carriage return by nothing
32083
32084 // Well formed XHTML end tags
32085 $html = preg_replace('/<(br|hr)\/>/i',"<\\1 />",$html);
32086 // Get rid of empty <thead></thead>
32087 $html = preg_replace('/<thead>\s*<\/thead>/i','',$html);
32088 $html = preg_replace('/<tfoot>\s*<\/tfoot>/i','',$html);
32089 $html = preg_replace('/<table[^>]*>\s*<\/table>/i','',$html);
32090 $html = preg_replace('/<tr>\s*<\/tr>/i','',$html);
32091
32092 // Remove spaces at end of table cells
32093 $html = preg_replace("/[ \n\r]+<\/t(d|h)/",'</t\\1',$html); // mPDF 5.5.09
32094
32095 $html = preg_replace("/[ ]*<dottab\s*[\/]*>[ ]*/",'<dottab />',$html);
32096
32097 // Concatenates any Substitute characters from symbols/dingbats
32098 $html = str_replace('</tts><tts>','|',$html);
32099 $html = str_replace('</ttz><ttz>','|',$html);
32100 $html = str_replace('</tta><tta>','|',$html);
32101
32102 $html = preg_replace('/<br \/>\s*/is',"<br />",$html);
32103
32104 $html = preg_replace('/<wbr[ \/]*>\s*/is',"&#173;",$html); // mPDF 5.6.04
32105
32106 // Preserve '\n's in content between the tags <pre> and </pre>
32107 if (preg_match('/<pre/',$html)) {
32108 $html_a = preg_split('/(\<\/?pre[^\>]*\>)/', $html, -1, 2);
32109 $h = array();
32110 $c=0;
32111 foreach($html_a AS $s) {
32112 if ($c>1 && preg_match('/^<\/pre/i',$s)) { $c--; $s=preg_replace('/<\/pre/i','</innerpre',$s); }
32113 else if ($c>0 && preg_match('/^<pre/i',$s)) { $c++; $s=preg_replace('/<pre/i','<innerpre',$s); }
32114 else if (preg_match('/^<pre/i',$s)) { $c++; }
32115 else if (preg_match('/^<\/pre/i',$s)) { $c--; }
32116 array_push($h, $s);
32117 }
32118 $html = implode("", $h);
32119 }
32120 $thereispre = preg_match_all('#<pre(.*?)>(.*?)</pre>#si',$html,$temp);
32121 // Preserve '\n's in content between the tags <textarea> and </textarea>
32122 $thereistextarea = preg_match_all('#<textarea(.*?)>(.*?)</textarea>#si',$html,$temp2);
32123 $html = preg_replace('/[\n]/',' ',$html); //replace linefeed by spaces
32124 $html = preg_replace('/[\t]/',' ',$html); //replace tabs by spaces
32125
32126 // Converts < to &lt; when not a tag
32127 $html = preg_replace('/<([^!\/a-zA-Z])/i','&lt;\\1',$html);
32128 $html = preg_replace("/[ ]+/",' ',$html);
32129
32130 $html = preg_replace('/\/li>\s+<\/(u|o)l/i','/li></\\1l',$html);
32131 $html = preg_replace('/\/(u|o)l>\s+<\/li/i','/\\1l></li',$html);
32132 $html = preg_replace('/\/li>\s+<\/(u|o)l/i','/li></\\1l',$html);
32133 $html = preg_replace('/\/li>\s+<li/i','/li><li',$html);
32134 $html = preg_replace('/<(u|o)l([^>]*)>[ ]+/i','<\\1l\\2>',$html);
32135 $html = preg_replace('/[ ]+<(u|o)l/i','<\\1l',$html);
32136
32137 $iterator = 0;
32138 while($thereispre) //Recover <pre attributes>content</pre>
32139 {
32140 $temp[2][$iterator] = preg_replace("/^([^\n\t]*?)\t/me", "stripslashes('\\1') . str_repeat(' ', ( $tabSpaces - (mb_strlen(stripslashes('\\1')) % $tabSpaces)) )",$temp[2][$iterator]);
32141 $temp[2][$iterator] = preg_replace('/\t/',str_repeat(" ",$tabSpaces),$temp[2][$iterator]);
32142
32143 $temp[2][$iterator] = preg_replace('/\n/',"<br />",$temp[2][$iterator]);
32144 $temp[2][$iterator] = str_replace('\\',"\\\\",$temp[2][$iterator]);
32145 $html = preg_replace('#<pre(.*?)>(.*?)</pre>#si','<erp'.$temp[1][$iterator].'>'.$temp[2][$iterator].'</erp>',$html,1);
32146 $thereispre--;
32147 $iterator++;
32148 }
32149 $iterator = 0;
32150 while($thereistextarea) //Recover <textarea attributes>content</textarea>
32151 {
32152 $temp2[2][$iterator] = preg_replace('/\t/',str_repeat(" ",$tabSpaces),$temp2[2][$iterator]);
32153 $temp2[2][$iterator] = str_replace('\\',"\\\\",$temp2[2][$iterator]); // mPDF 5.3.88
32154 $html = preg_replace('#<textarea(.*?)>(.*?)</textarea>#si','<aeratxet'.$temp2[1][$iterator].'>'.trim($temp2[2][$iterator]) .'</aeratxet>',$html,1);
32155 $thereistextarea--;
32156 $iterator++;
32157 }
32158 //Restore original tag names
32159 $html = str_replace("<erp","<pre",$html);
32160 $html = str_replace("</erp>","</pre>",$html);
32161 $html = str_replace("<aeratxet","<textarea",$html);
32162 $html = str_replace("</aeratxet>","</textarea>",$html);
32163 $html = str_replace("</innerpre","</pre",$html);
32164 $html = str_replace("<innerpre","<pre",$html);
32165
32166 $html = preg_replace('/<textarea([^>]*)><\/textarea>/si','<textarea\\1> </textarea>',$html);
32167 $html = preg_replace('/(<table[^>]*>)\s*(<caption)(.*?<\/caption>)(.*?<\/table>)/si','\\2 position="top"\\3\\1\\4\\2 position="bottom"\\3',$html); // *TABLES*
32168 $html = preg_replace('/<(h[1-6])([^>]*)(>(?:(?!h[1-6]).)*?<\/\\1>\s*<table)/si','<\\1\\2 keep-with-table="1"\\3',$html); // *TABLES*
32169 $html = preg_replace("/\xbb\xa4\xac/", "\n", $html);
32170
32171 return $html;
32172 }
32173
32174 /*-- LISTS --*/
32175 function dec2other($num, $cp) {
32176 $nstr = (string) $num;
32177 $rnum = '';
32178 for ($i=0;$i<strlen($nstr);$i++) {
32179 if ($this->_charDefined($this->CurrentFont['cw'],$cp+intval($nstr[$i]))) { // contains arabic-indic numbers
32180 $rnum .= code2utf($cp+intval($nstr[$i]));
32181 }
32182 else { $rnum .= $nstr[$i]; }
32183 }
32184 return $rnum;
32185 }
32186
32187 function dec2alpha($valor,$toupper="true"){
32188 // returns a string from A-Z to AA-ZZ to AAA-ZZZ
32189 // OBS: A = 65 ASCII TABLE VALUE
32190 if (($valor < 1) || ($valor > 18278)) return "?"; //supports 'only' up to 18278
32191 $c1 = $c2 = $c3 = '';
32192 if ($valor > 702) // 3 letters (up to 18278)
32193 {
32194 $c1 = 65 + floor(($valor-703)/676);
32195 $c2 = 65 + floor((($valor-703)%676)/26);
32196 $c3 = 65 + floor((($valor-703)%676)%26);
32197 }
32198 elseif ($valor > 26) // 2 letters (up to 702)
32199 {
32200 $c1 = (64 + (int)(($valor-1) / 26));
32201 $c2 = (64 + (int)($valor % 26));
32202 if ($c2 == 64) $c2 += 26;
32203 }
32204 else // 1 letter (up to 26)
32205 {
32206 $c1 = (64 + $valor);
32207 }
32208 $alpha = chr($c1);
32209 if ($c2 != '') $alpha .= chr($c2);
32210 if ($c3 != '') $alpha .= chr($c3);
32211 if (!$toupper) $alpha = strtolower($alpha);
32212 return $alpha;
32213 }
32214
32215
32216 function dec2roman($valor,$toupper=true){
32217 //returns a string as a roman numeral
32218 $r1=$r2=$r3=$r4='';
32219 if (($valor >= 5000) || ($valor < 1)) return "?"; //supports 'only' up to 4999
32220 $aux = (int)($valor/1000);
32221 if ($aux!==0)
32222 {
32223 $valor %= 1000;
32224 while($aux!==0)
32225 {
32226 $r1 .= "M";
32227 $aux--;
32228 }
32229 }
32230 $aux = (int)($valor/100);
32231 if ($aux!==0)
32232 {
32233 $valor %= 100;
32234 switch($aux){
32235 case 3: $r2="C";
32236 case 2: $r2.="C";
32237 case 1: $r2.="C"; break;
32238 case 9: $r2="CM"; break;
32239 case 8: $r2="C";
32240 case 7: $r2.="C";
32241 case 6: $r2.="C";
32242 case 5: $r2="D".$r2; break;
32243 case 4: $r2="CD"; break;
32244 default: break;
32245 }
32246 }
32247 $aux = (int)($valor/10);
32248 if ($aux!==0)
32249 {
32250 $valor %= 10;
32251 switch($aux){
32252 case 3: $r3="X";
32253 case 2: $r3.="X";
32254 case 1: $r3.="X"; break;
32255 case 9: $r3="XC"; break;
32256 case 8: $r3="X";
32257 case 7: $r3.="X";
32258 case 6: $r3.="X";
32259 case 5: $r3="L".$r3; break;
32260 case 4: $r3="XL"; break;
32261 default: break;
32262 }
32263 }
32264 switch($valor){
32265 case 3: $r4="I";
32266 case 2: $r4.="I";
32267 case 1: $r4.="I"; break;
32268 case 9: $r4="IX"; break;
32269 case 8: $r4="I";
32270 case 7: $r4.="I";
32271 case 6: $r4.="I";
32272 case 5: $r4="V".$r4; break;
32273 case 4: $r4="IV"; break;
32274 default: break;
32275 }
32276 $roman = $r1.$r2.$r3.$r4;
32277 if (!$toupper) $roman = strtolower($roman);
32278 return $roman;
32279 }
32280 /*-- END LISTS --*/
32281
32282
32283 //===========================
32284 /*-- IMPORTS --*/
32285 function SetImportUse() {
32286 $this->enableImports = true;
32287 ini_set('auto_detect_line_endings',1);
32288 require_once(_MPDF_PATH."mpdfi/pdf_context.php");
32289 require_once(_MPDF_PATH."mpdfi/pdf_parser.php");
32290 require_once(_MPDF_PATH."mpdfi/fpdi_pdf_parser.php");
32291 }
32292
32293 // from mPDFI
32294 function hex2str($hex) {
32295 return pack("H*", str_replace(array("\r","\n"," "),"", $hex));
32296 }
32297
32298 function str2hex($str) {
32299 return current(unpack("H*",$str));
32300 }
32301
32302
32303 function pdf_write_value(&$value) {
32304 switch ($value[0]) {
32305 case PDF_TYPE_NUMERIC :
32306 case PDF_TYPE_TOKEN :
32307 // A numeric value or a token.
32308 // Simply output them
32309 $this->_out($value[1]." ", false);
32310 break;
32311
32312 case PDF_TYPE_ARRAY :
32313 // An array. Output the proper
32314 // structure and move on.
32315 $this->_out("[",false);
32316 for ($i = 0; $i < count($value[1]); $i++) {
32317 $this->pdf_write_value($value[1][$i]);
32318 }
32319 $this->_out("]");
32320 break;
32321
32322 case PDF_TYPE_DICTIONARY :
32323 // A dictionary.
32324 $this->_out("<<",false);
32325 reset ($value[1]);
32326 while (list($k, $v) = each($value[1])) {
32327 $this->_out($k . " ",false);
32328 $this->pdf_write_value($v);
32329 }
32330 $this->_out(">>");
32331 break;
32332
32333 case PDF_TYPE_OBJREF :
32334 // An indirect object reference
32335 // Fill the object stack if needed
32336 $cpfn =& $this->current_parser->filename;
32337 if (!isset($this->_don_obj_stack[$cpfn][$value[1]])) {
32338 $this->_newobj(false,true);
32339 $this->_obj_stack[$cpfn][$value[1]] = array($this->n, $value);
32340 $this->_don_obj_stack[$cpfn][$value[1]] = array($this->n, $value);
32341 }
32342 $objid = $this->_don_obj_stack[$cpfn][$value[1]][0];
32343 $this->_out("{$objid} 0 R"); //{$value[2]}
32344 break;
32345
32346 case PDF_TYPE_STRING :
32347 if ($this->encrypted) {
32348 $value[1] = $this->_RC4($this->_objectkey($this->_current_obj_id), $value[1]);
32349 $value[1] = $this->_escape($value[1]);
32350 }
32351 // A string.
32352 $this->_out('('.$value[1].')');
32353 break;
32354
32355 case PDF_TYPE_STREAM :
32356 // A stream. First, output the
32357 // stream dictionary, then the
32358 // stream data itself.
32359 $this->pdf_write_value($value[1]);
32360 if ($this->encrypted) {
32361 $value[2][1] = $this->_RC4($this->_objectkey($this->_current_obj_id), $value[2][1]);
32362 }
32363 $this->_out("stream");
32364 $this->_out($value[2][1]);
32365 $this->_out("endstream");
32366 break;
32367
32368 case PDF_TYPE_HEX :
32369 if ($this->encrypted) {
32370 $value[1] = $this->hex2str($value[1]);
32371 $value[1] = $this->_RC4($this->_objectkey($this->_current_obj_id), $value[1]);
32372 // remake hexstring of encrypted string
32373 $value[1] = $this->str2hex($value[1]);
32374 }
32375 $this->_out("<".$value[1].">");
32376 break;
32377
32378 case PDF_TYPE_NULL :
32379 // The null object.
32380 $this->_out("null");
32381 break;
32382 }
32383 }
32384
32385 // ========== OVERWRITE SEARCH STRING IN A PDF FILE ================
32386 function OverWrite($file_in, $search, $replacement, $dest="D", $file_out="mpdf" ) {
32387 $pdf = file_get_contents($file_in);
32388
32389 if (!is_array($search)) {
32390 $x = $search;
32391 $search = array($x);
32392 }
32393 if (!is_array($replacement)) {
32394 $x = $replacement;
32395 $search = array($x);
32396 }
32397
32398 if (!$this->onlyCoreFonts && !$this->usingCoreFont) {
32399 foreach($search AS $k=>$val) {
32400 $search[$k] = $this->UTF8ToUTF16BE($search[$k] , false);
32401 $search[$k] = $this->_escape($search[$k]);
32402 $replacement[$k] = $this->UTF8ToUTF16BE($replacement[$k], false);
32403 $replacement[$k] = $this->_escape($replacement[$k]);
32404 }
32405 }
32406 else {
32407 foreach($replacement AS $k=>$val) {
32408 $replacement[$k] = mb_convert_encoding($replacement[$k],$this->mb_enc,'utf-8');
32409 $replacement[$k] = $this->_escape($replacement[$k]);
32410 }
32411 }
32412
32413 // Get xref into array
32414 $xref = array();
32415 preg_match("/xref\n0 (\d+)\n(.*?)\ntrailer/s",$pdf,$m);
32416 $xref_objid = $m[1];
32417 preg_match_all('/(\d{10}) (\d{5}) (f|n)/',$m[2],$x);
32418 for($i=0; $i<count($x[0]); $i++) {
32419 $xref[] = array(intval($x[1][$i]), $x[2][$i], $x[3][$i]);
32420 }
32421
32422 $changes = array();
32423 preg_match("/<<\s*\/Type\s*\/Pages\s*\/Kids\s*\[(.*?)\]\s*\/Count/s",$pdf,$m);
32424 preg_match_all("/(\d+) 0 R /s",$m[1],$o);
32425 $objlist = $o[1];
32426 foreach($objlist AS $obj) {
32427 if ($this->compress) {
32428 preg_match("/".($obj+1)." 0 obj\n<<\s*\/Filter\s*\/FlateDecode\s*\/Length (\d+)>>\nstream\n(.*?)\nendstream\n/s",$pdf,$m);
32429 }
32430 else {
32431 preg_match("/".($obj+1)." 0 obj\n<<\s*\/Length (\d+)>>\nstream\n(.*?)\nendstream\n/s",$pdf,$m);
32432 }
32433 $s = $m[2];
32434 if (!$s) { continue; }
32435 $oldlen = $m[1];
32436 if ($this->encrypted) {
32437 $s = $this->_RC4($this->_objectkey($obj+1), $s);
32438 }
32439 if ($this->compress) {
32440 $s = gzuncompress($s);
32441 }
32442 foreach($search AS $k=>$val) {
32443 $s = str_replace($search[$k],$replacement[$k],$s);
32444 }
32445 if ($this->compress) {
32446 $s = gzcompress($s);
32447 }
32448 if ($this->encrypted) {
32449 $s = $this->_RC4($this->_objectkey($obj+1), $s);
32450 }
32451 $newlen = strlen($s);
32452 $changes[($xref[$obj+1][0])] = ($newlen - $oldlen) + (strlen($newlen) - strlen($oldlen ));
32453 if ($this->compress) {
32454 $newstr = ($obj+1) . " 0 obj\n<</Filter /FlateDecode /Length ".$newlen.">>\nstream\n".$s."\nendstream\n";
32455 }
32456 else {
32457 $newstr = ($obj+1) . " 0 obj\n<</Length ".$newlen.">>\nstream\n".$s."\nendstream\n";
32458 }
32459 $pdf = str_replace($m[0],$newstr,$pdf);
32460 }
32461
32462 // Update xref in PDF
32463 krsort($changes);
32464 $newxref = "xref\n0 ".$xref_objid."\n";
32465 foreach($xref AS $v) {
32466 foreach($changes AS $ck => $cv) {
32467 if ($v[0] > $ck) { $v[0] += $cv; }
32468 }
32469 $newxref .= sprintf('%010d',$v[0]) . ' ' . $v[1] . ' ' .$v[2] . " \n";
32470 }
32471 $newxref .= "trailer";
32472 $pdf = preg_replace("/xref\n0 \d+\n.*?\ntrailer/s",$newxref,$pdf);
32473
32474 // Update startxref in PDF
32475 preg_match("/startxref\n(\d+)\n%%EOF/s", $pdf, $m);
32476 $startxref = $m[1];
32477 $startxref += array_sum($changes);
32478 $pdf = preg_replace("/startxref\n(\d+)\n%%EOF/s","startxref\n".$startxref."\n%%EOF",$pdf);
32479
32480 // OUTPUT
32481 switch($dest) {
32482 case 'I':
32483 //Send to standard output
32484 if(isset($_SERVER['SERVER_NAME']))
32485 {
32486 //We send to a browser
32487 Header('Content-Type: application/pdf');
32488 Header('Content-Length: '.strlen($pdf));
32489 Header('Content-disposition: inline; filename='.$file_out);
32490 }
32491 echo $pdf;
32492 break;
32493 case 'F':
32494 //Save to local file
32495 if (!$file_out) { $file_out = 'mpdf.pdf'; }
32496 $f=fopen($file_out,'wb');
32497 if(!$f) die('Unable to create output file: '.$file_out);
32498 fwrite($f,$pdf,strlen($pdf));
32499 fclose($f);
32500 break;
32501 case 'S':
32502 //Return as a string
32503 return $pdf;
32504 case 'D':
32505 default:
32506 //Download file
32507 if(isset($_SERVER['HTTP_USER_AGENT']) and strpos($_SERVER['HTTP_USER_AGENT'],'MSIE'))
32508 Header('Content-Type: application/force-download');
32509 else
32510 Header('Content-Type: application/octet-stream');
32511 Header('Content-Length: '.strlen($pdf));
32512 Header('Content-disposition: attachment; filename='.$file_out);
32513 echo $pdf;
32514 break;
32515 }
32516 }
32517
32518
32519 function GetTemplateSize($tplidx, $_w=0, $_h=0) {
32520 if (!$this->tpls[$tplidx])
32521 return false;
32522 $w = $this->tpls[$tplidx]['box']['w'];
32523 $h = $this->tpls[$tplidx]['box']['h'];
32524 if ($_w == 0 and $_h == 0) {
32525 $_w = $w;
32526 $_h = $h;
32527 }
32528 if($_w==0)
32529 $_w=$_h*$w/$h;
32530 if($_h==0)
32531 $_h=$_w*$h/$w;
32532 return array("w" => $_w, "h" => $_h);
32533 }
32534
32535 // Thumbnails
32536 function Thumbnail($file, $npr=3, $spacing=10) { //$npr = number per row
32537 $w = (($this->pgwidth + $spacing)/$npr) - $spacing;
32538 $oldlinewidth = $this->LineWidth;
32539 $this->SetLineWidth(0.02);
32540 $this->SetDColor($this->ConvertColor(0));
32541 $h = 0;
32542 $maxh = 0;
32543 $x = $_x = $this->lMargin;
32544 $_y = $this->tMargin;
32545 if ($this->y==0) { $y = $_y; } else { $y = $this->y; }
32546 $pagecount = $this->SetSourceFile($file);
32547 for ($n = 1; $n <= $pagecount; $n++) {
32548 $tplidx = $this->ImportPage($n);
32549 $size = $this->useTemplate($tplidx, $x, $y, $w);
32550 $this->Rect($x, $y, $size['w'], $size['h']);
32551 $h = max($h, $size['h']);
32552 $maxh = max($h, $maxh);
32553 if ($n % $npr == 0) {
32554 if (($y + $h + $spacing + $maxh)>$this->PageBreakTrigger && $n != $pagecount) {
32555 $this->AddPage();
32556 $x = $_x;
32557 $y = $_y;
32558 }
32559 else {
32560 $y += $h+$spacing ;
32561 $x = $_x;
32562 $h = 0;
32563 }
32564 }
32565 else {
32566 $x += $w+$spacing ;
32567 }
32568 }
32569 $this->SetLineWidth($oldlinewidth);
32570 }
32571
32572 function SetSourceFile($filename) {
32573 $this->current_filename = $filename;
32574 $fn =& $this->current_filename;
32575 if (!isset($this->parsers[$fn]))
32576 // $this->parsers[$fn] =& new fpdi_pdf_parser($fn,$this);
32577 $this->parsers[$fn] = new fpdi_pdf_parser($fn,$this);
32578 if (!$this->parsers[$fn]->success) {
32579 $this->Error($this->parsers[$fn]->errormsg); // Delete this line to return false on fail
32580 return false;
32581 }
32582 $this->current_parser =& $this->parsers[$fn];
32583 return $this->parsers[$fn]->getPageCount();
32584 }
32585 function ImportPage($pageno=1, $crop_x=null, $crop_y=null, $crop_w=0, $crop_h=0, $boxName='/CropBox') {
32586 $fn =& $this->current_filename;
32587 $parser =& $this->parsers[$fn];
32588 $parser->setPageno($pageno);
32589
32590 $this->tpl++;
32591 $this->tpls[$this->tpl] = array();
32592 $tpl =& $this->tpls[$this->tpl];
32593 $tpl['parser'] =& $parser;
32594 $tpl['resources'] = $parser->getPageResources();
32595 $tpl['buffer'] = $parser->getContent();
32596 if (!in_array($boxName, $parser->availableBoxes))
32597 return $this->Error(sprintf("Unknown box: %s", $boxName));
32598 $pageboxes = $parser->getPageBoxes($pageno);
32599 /**
32600 * MediaBox
32601 * CropBox: Default -> MediaBox
32602 * BleedBox: Default -> CropBox
32603 * TrimBox: Default -> CropBox
32604 * ArtBox: Default -> CropBox
32605 */
32606 if (!isset($pageboxes[$boxName]) && ($boxName == "/BleedBox" || $boxName == "/TrimBox" || $boxName == "/ArtBox"))
32607 $boxName = "/CropBox";
32608 if (!isset($pageboxes[$boxName]) && $boxName == "/CropBox")
32609 $boxName = "/MediaBox";
32610 if (!isset($pageboxes[$boxName]))
32611 return false;
32612 $box = $pageboxes[$boxName];
32613
32614 $tpl['box'] = $box;
32615 // To build an array that can be used by useTemplate()
32616 $this->tpls[$this->tpl] = array_merge($this->tpls[$this->tpl],$box);
32617 // An imported page will start at 0,0 everytime. Translation will be set in _putformxobjects()
32618 $tpl['x'] = 0;
32619 $tpl['y'] = 0;
32620 $tpl['w'] = $tpl['box']['w'] ;
32621 $tpl['h'] = $tpl['box']['h'] ;
32622 if ($crop_w) { $tpl['box']['w'] = $crop_w; }
32623 if ($crop_h) { $tpl['box']['h'] = $crop_h; }
32624 if (isset($crop_x)) { $tpl['box']['x'] = $crop_x; }
32625 if (isset($crop_y)) {$tpl['box']['y'] = $tpl['h'] - $crop_y - $crop_h ; }
32626
32627 $page =& $parser->pages[$parser->pageno];
32628 // fix for rotated pages
32629 $rotation = $parser->getPageRotation($pageno);
32630
32631 if (isset($rotation[1]) && ($angle = $rotation[1] % 360) != 0 && $tpl['box']['w'] == $tpl['w']) {
32632 $steps = $angle / 90;
32633
32634 $_w = $tpl['w'];
32635 $_h = $tpl['h'];
32636 $tpl['w'] = $steps % 2 == 0 ? $_w : $_h;
32637 $tpl['h'] = $steps % 2 == 0 ? $_h : $_w;
32638 if ($steps % 2 != 0) {
32639 $x = $y = ($steps == 1 || $steps == -3) ? $tpl['h'] : $tpl['w'];
32640 } else {
32641 $x = $tpl['w'];
32642 $y = $tpl['h'];
32643 }
32644 $cx=($x/2+$tpl['box']['x'])*_MPDFK;
32645 $cy=($y/2+$tpl['box']['y'])*_MPDFK;
32646 $angle*=-1;
32647 $angle*=M_PI/180;
32648 $c=cos($angle);
32649 $s=sin($angle);
32650 $tpl['box']['w'] = $tpl['w'] ;
32651 $tpl['box']['h'] = $tpl['h'] ;
32652 $tpl['buffer'] = sprintf('q %.5F %.5F %.5F %.5F %.2F %.2F cm 1 0 0 1 %.2F %.2F cm %s Q',$c,$s,-$s,$c,$cx,$cy,-$cx,-$cy, $tpl['buffer']);
32653 }
32654 return $this->tpl;
32655 }
32656 function UseTemplate($tplidx, $_x=null, $_y=null, $_w=0, $_h=0) {
32657 if (!isset($this->tpls[$tplidx]))
32658 $this->Error("Template does not exist!");
32659 if($this->state==0) { $this->AddPage(); }
32660 $out = 'q 0 J 1 w 0 j 0 G'."\n"; // reset standard values
32661 $x = $this->tpls[$tplidx]['x'];
32662 $y = $this->tpls[$tplidx]['y'];
32663 $w = $this->tpls[$tplidx]['w'];
32664 $h = $this->tpls[$tplidx]['h'];
32665 if ($_x == null) { $_x = $x; }
32666 if ($_y == null) { $_y = $y; }
32667 if ($_x === -1) { $_x = $this->x; }
32668 if ($_y === -1) { $_y = $this->y; }
32669
32670 $wh = $this->getTemplateSize($tplidx,$_w,$_h);
32671 $_w = $wh['w'];
32672 $_h = $wh['h'];
32673 $out .= sprintf("q %.4F 0 0 %.4F %.2F %.2F cm", ($_w/$this->tpls[$tplidx]['box']['w']), ($_h/$this->tpls[$tplidx]['box']['h']), $_x*_MPDFK, ($this->h-($_y+$_h))*_MPDFK)."\n";
32674 $out .= $this->tplprefix.$tplidx." Do Q\n";
32675
32676 $s = array("w" => $_w, "h" => $_h);
32677 $out .= "Q\n";
32678 $this->pages[$this->page] = $out . $this->pages[$this->page];
32679 return $s;
32680 }
32681 function SetPageTemplate($tplidx='') {
32682 if (!isset($this->tpls[$tplidx])) {
32683 $this->pageTemplate = '';
32684 return false;
32685 }
32686 $this->pageTemplate = $tplidx;
32687 }
32688 function SetDocTemplate($file='', $continue=0) {
32689 $this->docTemplate = $file;
32690 $this->docTemplateContinue = $continue;
32691 }
32692 /*-- END IMPORTS --*/
32693
32694
32695 /* ---------------------------------------------- */
32696 /* ---------------------------------------------- */
32697 /* ---------------------------------------------- */
32698 /* ---------------------------------------------- */
32699 /* ---------------------------------------------- */
32700
32701 // JAVASCRIPT
32702 function _set_object_javascript ($string) {
32703 $this->_newobj();
32704 $this->_out('<<');
32705 $this->_out('/S /JavaScript ');
32706 $this->_out('/JS '.$this->_textstring($string));
32707 $this->_out('>>');
32708 $this->_out('endobj');
32709 }
32710
32711 function SetJS($script) {
32712 $this->js = $script;
32713 }
32714
32715
32716
32717
32718 }//end of Class
32719
32720
32721
32722
32723 ?>