aboutsummaryrefslogtreecommitdiffhomepage
path: root/inc/3rdparty/libraries/mpdf/mpdf.php
diff options
context:
space:
mode:
authortcit <tcit@tcit.fr>2014-09-27 19:34:17 +0200
committertcit <tcit@tcit.fr>2014-09-27 19:34:17 +0200
commit824f8c45edb20e27221e92805b0090f1768a2756 (patch)
tree8563a41cc27619347c851b3a06285bf2474b69dd /inc/3rdparty/libraries/mpdf/mpdf.php
parentd4690a8fa18c27c6d98c1c76ac1d1d2c35a1ebbb (diff)
downloadwallabag-824f8c45edb20e27221e92805b0090f1768a2756.tar.gz
wallabag-824f8c45edb20e27221e92805b0090f1768a2756.tar.zst
wallabag-824f8c45edb20e27221e92805b0090f1768a2756.zip
changed mpdf with tcpdf
Diffstat (limited to 'inc/3rdparty/libraries/mpdf/mpdf.php')
-rw-r--r--inc/3rdparty/libraries/mpdf/mpdf.php32805
1 files changed, 0 insertions, 32805 deletions
diff --git a/inc/3rdparty/libraries/mpdf/mpdf.php b/inc/3rdparty/libraries/mpdf/mpdf.php
deleted file mode 100644
index fd4f57b3..00000000
--- a/inc/3rdparty/libraries/mpdf/mpdf.php
+++ /dev/null
@@ -1,32805 +0,0 @@
1<?php
2
3// ******************************************************************************
4// Software: mPDF, Unicode-HTML Free PDF generator *
5// Version: 5.7.2 based on *
6// FPDF by Olivier PLATHEY *
7// HTML2FPDF by Renato Coelho *
8// Date: 2013-09-01 *
9// Author: Ian Back <ianb@bpm1.com> *
10// License: GPL *
11// *
12// Changes: See changelog.txt *
13// ******************************************************************************
14
15
16define('mPDF_VERSION','5.7.2');
17
18//Scale factor
19define('_MPDFK', (72/25.4));
20
21/*-- HTML-CSS --*/
22define('AUTOFONT_CJK',1);
23define('AUTOFONT_THAIVIET',2);
24define('AUTOFONT_RTL',4);
25define('AUTOFONT_INDIC',8);
26define('AUTOFONT_ALL',15);
27
28define('_BORDER_ALL',15);
29define('_BORDER_TOP',8);
30define('_BORDER_RIGHT',4);
31define('_BORDER_BOTTOM',2);
32define('_BORDER_LEFT',1);
33/*-- END HTML-CSS --*/
34
35if (!defined('_MPDF_PATH')) define('_MPDF_PATH', dirname(preg_replace('/\\\\/','/',__FILE__)) . '/');
36if (!defined('_MPDF_URI')) define('_MPDF_URI',_MPDF_PATH);
37
38require_once(_MPDF_PATH.'includes/functions.php');
39require_once(_MPDF_PATH.'config_cp.php');
40
41if (!defined('_JPGRAPH_PATH')) define("_JPGRAPH_PATH", _MPDF_PATH.'jpgraph/');
42
43if (!defined('_MPDF_TEMP_PATH')) define("_MPDF_TEMP_PATH", _MPDF_PATH.'tmp/');
44
45if (!defined('_MPDF_TTFONTPATH')) { define('_MPDF_TTFONTPATH',_MPDF_PATH.'ttfonts/'); }
46if (!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
53if(function_exists("date_default_timezone_set")) {
54 if (ini_get("date.timezone")=="") { date_default_timezone_set("Europe/London"); }
55}
56if (!function_exists("mb_strlen")) { die("Error - mPDF requires mb_string functions. Ensure that PHP is compiled with php_mbstring.dll enabled."); }
57
58if (!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);
64define("_DSIZE", strlen($test));
65
66class mPDF
67{
68
69///////////////////////////////
70// EXTERNAL (PUBLIC) VARIABLES
71// Define these in config.php
72///////////////////////////////
73var $CJKforceend; // mPDF 5.6.40
74// mPDF 5.6.34
75var $h2bookmarks;
76var $h2toc;
77var $decimal_align; // mPDF 5.6.13
78var $margBuffer; // mPDF 5.4.04
79var $splitTableBorderWidth; // mPDF 5.4.16
80
81var $cacheTables;
82var $bookmarkStyles;
83var $useActiveForms;
84
85var $repackageTTF;
86var $allowCJKorphans;
87var $allowCJKoverflow;
88
89var $useKerning;
90var $restrictColorSpace;
91var $bleedMargin;
92var $crossMarkMargin;
93var $cropMarkMargin;
94var $cropMarkLength;
95var $nonPrintMargin;
96
97var $PDFX;
98var $PDFXauto;
99
100var $PDFA;
101var $PDFAauto;
102var $ICCProfile;
103
104var $printers_info;
105var $iterationCounter;
106var $smCapsScale;
107var $smCapsStretch;
108
109var $backupSubsFont;
110var $backupSIPFont;
111var $debugfonts;
112var $useAdobeCJK;
113var $percentSubset;
114var $maxTTFFilesize;
115var $BMPonly;
116
117var $tableMinSizePriority;
118
119var $dpi;
120var $watermarkImgAlphaBlend;
121var $watermarkImgBehind;
122var $justifyB4br;
123var $packTableData;
124var $pgsIns;
125var $simpleTables;
126var $enableImports;
127
128var $debug;
129var $showStats;
130var $setAutoTopMargin;
131var $setAutoBottomMargin;
132var $autoMarginPadding;
133var $collapseBlockMargins;
134var $falseBoldWeight;
135var $normalLineheight;
136var $progressBar;
137var $incrementFPR1;
138var $incrementFPR2;
139var $incrementFPR3;
140var $incrementFPR4;
141
142var $SHYlang;
143var $SHYleftmin;
144var $SHYrightmin;
145var $SHYcharmin;
146var $SHYcharmax;
147var $SHYlanguages;
148// PageNumber Conditional Text
149var $pagenumPrefix;
150var $pagenumSuffix;
151var $nbpgPrefix;
152var $nbpgSuffix;
153var $showImageErrors;
154var $allow_output_buffering;
155var $autoPadding;
156var $useGraphs;
157var $autoFontGroupSize;
158var $tabSpaces;
159var $useLang;
160var $restoreBlockPagebreaks;
161var $watermarkTextAlpha;
162var $watermarkImageAlpha;
163var $watermark_size;
164var $watermark_pos;
165var $annotSize;
166var $annotMargin;
167var $annotOpacity;
168var $title2annots;
169var $keepColumns;
170var $keep_table_proportions;
171var $ignore_table_widths;
172var $ignore_table_percents;
173var $list_align_style;
174var $list_number_suffix;
175var $useSubstitutions;
176var $CSSselectMedia;
177
178var $forcePortraitHeaders;
179var $forcePortraitMargins;
180var $displayDefaultOrientation;
181var $ignore_invalid_utf8;
182var $allowedCSStags;
183var $onlyCoreFonts;
184var $allow_charset_conversion;
185
186var $jSWord;
187var $jSmaxChar;
188var $jSmaxCharLast;
189var $jSmaxWordLast;
190
191var $max_colH_correction;
192
193
194var $table_error_report;
195var $table_error_report_param;
196var $biDirectional;
197var $text_input_as_HTML;
198var $anchor2Bookmark;
199var $list_indent_first_level;
200var $shrink_tables_to_fit;
201
202var $allow_html_optional_endtags;
203
204var $img_dpi;
205
206var $defaultheaderfontsize;
207var $defaultheaderfontstyle;
208var $defaultheaderline;
209var $defaultfooterfontsize;
210var $defaultfooterfontstyle;
211var $defaultfooterline;
212var $header_line_spacing;
213var $footer_line_spacing;
214
215var $pregUHCchars;
216var $pregSJISchars;
217var $pregCJKchars;
218var $pregASCIIchars1;
219var $pregASCIIchars2;
220var $pregASCIIchars3;
221var $pregVIETchars;
222var $pregVIETPluschars;
223
224var $pregRTLchars;
225var $pregHEBchars;
226var $pregARABICchars;
227var $pregNonARABICchars;
228// INDIC
229var $pregHIchars;
230var $pregBNchars;
231var $pregPAchars;
232var $pregGUchars;
233var $pregORchars;
234var $pregTAchars;
235var $pregTEchars;
236var $pregKNchars;
237var $pregMLchars;
238var $pregSHchars;
239var $pregINDextra;
240
241var $mirrorMargins;
242var $default_lineheight_correction;
243var $watermarkText;
244var $watermarkImage;
245var $showWatermarkText;
246var $showWatermarkImage;
247
248var $fontsizes;
249
250// Aliases for backward compatability
251var $UnvalidatedText; // alias = $watermarkText
252var $TopicIsUnvalidated; // alias = $showWatermarkText
253var $useOddEven; // alias = $mirrorMargins
254var $useSubstitutionsMB; // alias = $useSubstitutions
255
256
257
258//////////////////////
259// CLASS OBJECTS
260//////////////////////
261var $cssmgr;
262var $grad;
263var $bmp;
264var $wmf;
265var $tocontents;
266var $form;
267var $directw;
268
269//////////////////////
270// INTERNAL VARIABLES
271//////////////////////
272var $uniqstr; // mPDF 5.7.2
273var $writingToC; // mPDF 5.6.38
274// mPDF 5.6.01
275var $layers;
276var $current_layer;
277var $open_layer_pane;
278var $decimal_offset; // mPDF 5.6.13
279var $inMeter; // mPDF 5.5.09
280
281var $CJKleading;
282var $CJKfollowing;
283var $CJKoverflow;
284
285var $textshadow;
286
287var $colsums;
288var $spanborder;
289var $spanborddet;
290
291var $visibility;
292
293var $useRC128encryption;
294var $uniqid;
295
296var $kerning;
297var $fixedlSpacing;
298var $minwSpacing;
299var $lSpacingCSS;
300var $wSpacingCSS;
301
302var $listDir;
303var $spotColorIDs;
304var $SVGcolors;
305var $spotColors;
306var $defTextColor;
307var $defDrawColor;
308var $defFillColor;
309
310var $tableBackgrounds;
311var $inlineDisplayOff;
312var $kt_y00;
313var $kt_p00;
314var $upperCase;
315var $checkSIP;
316var $checkSMP;
317var $checkCJK;
318var $tableCJK;
319
320var $watermarkImgAlpha;
321var $PDFAXwarnings;
322var $MetadataRoot;
323var $OutputIntentRoot;
324var $InfoRoot;
325var $current_filename;
326var $parsers;
327var $current_parser;
328var $_obj_stack;
329var $_don_obj_stack;
330var $_current_obj_id;
331var $tpls;
332var $tpl;
333var $tplprefix;
334var $_res;
335
336var $pdf_version;
337var $noImageFile;
338var $lastblockbottommargin;
339var $baselineC;
340var $subPos;
341var $subArrMB;
342var $ReqFontStyle;
343var $tableClipPath ;
344var $forceExactLineheight;
345var $listOcc;
346
347var $fullImageHeight;
348var $inFixedPosBlock; // Internal flag for position:fixed block
349var $fixedPosBlock; // Buffer string for position:fixed block
350var $fixedPosBlockDepth;
351var $fixedPosBlockBBox;
352var $fixedPosBlockSave;
353var $maxPosL;
354var $maxPosR;
355
356var $loaded;
357
358var $extraFontSubsets;
359var $docTemplateStart; // Internal flag for page (page no. -1) that docTemplate starts on
360var $time0;
361
362// Classes
363var $indic;
364var $barcode;
365
366var $SHYpatterns;
367var $loadedSHYpatterns;
368var $loadedSHYdictionary;
369var $SHYdictionary;
370var $SHYdictionaryWords;
371
372var $spanbgcolorarray;
373var $default_font;
374var $list_lineheight;
375var $headerbuffer;
376var $lastblocklevelchange;
377var $nestedtablejustfinished;
378var $linebreakjustfinished;
379var $cell_border_dominance_L;
380var $cell_border_dominance_R;
381var $cell_border_dominance_T;
382var $cell_border_dominance_B;
383var $table_keep_together;
384var $plainCell_properties;
385var $inherit_lineheight;
386var $listitemtype;
387var $shrin_k1;
388var $outerfilled;
389
390var $blockContext;
391var $floatDivs;
392
393
394var $patterns;
395var $pageBackgrounds;
396
397var $bodyBackgroundGradient;
398var $bodyBackgroundImage;
399var $bodyBackgroundColor;
400
401var $writingHTMLheader; // internal flag - used both for writing HTMLHeaders/Footers and FixedPos block
402var $writingHTMLfooter;
403var $autoFontGroups;
404var $angle;
405
406var $gradients;
407
408var $kwt_Reference;
409var $kwt_BMoutlines;
410var $kwt_toc;
411
412var $tbrot_Reference;
413var $tbrot_BMoutlines;
414var $tbrot_toc;
415
416var $col_Reference;
417var $col_BMoutlines;
418var $col_toc;
419
420var $currentGraphId;
421var $graphs;
422
423var $floatbuffer;
424var $floatmargins;
425
426var $bullet;
427var $bulletarray;
428
429var $rtlAsArabicFarsi; // DEPRACATED
430
431var $currentLang;
432var $default_lang;
433var $default_available_fonts;
434var $pageTemplate;
435var $docTemplate;
436var $docTemplateContinue;
437
438var $arabGlyphs;
439var $arabHex;
440var $persianGlyphs;
441var $persianHex;
442var $arabVowels;
443var $arabPrevLink;
444var $arabNextLink;
445
446
447var $formobjects; // array of Form Objects for WMF
448var $InlineProperties;
449var $InlineAnnots;
450var $ktAnnots;
451var $tbrot_Annots;
452var $kwt_Annots;
453var $columnAnnots;
454var $columnForms;
455
456var $PageAnnots;
457
458var $pageDim; // Keep track of page wxh for orientation changes - set in _beginpage, used in _putannots
459
460var $breakpoints;
461
462var $tableLevel;
463var $tbctr;
464var $innermostTableLevel;
465var $saveTableCounter;
466var $cellBorderBuffer;
467
468var $saveHTMLFooter_height;
469var $saveHTMLFooterE_height;
470
471var $firstPageBoxHeader;
472var $firstPageBoxHeaderEven;
473var $firstPageBoxFooter;
474var $firstPageBoxFooterEven;
475
476var $page_box;
477var $show_marks; // crop or cross marks
478
479var $basepathIsLocal;
480
481var $use_kwt;
482var $kwt;
483var $kwt_height;
484var $kwt_y0;
485var $kwt_x0;
486var $kwt_buffer;
487var $kwt_Links;
488var $kwt_moved;
489var $kwt_saved;
490
491var $PageNumSubstitutions;
492
493var $table_borders_separate;
494var $base_table_properties;
495var $borderstyles;
496
497var $listjustfinished;
498var $blockjustfinished;
499
500var $orig_bMargin;
501var $orig_tMargin;
502var $orig_lMargin;
503var $orig_rMargin;
504var $orig_hMargin;
505var $orig_fMargin;
506
507var $pageheaders;
508var $pagefooters;
509
510var $pageHTMLheaders;
511var $pageHTMLfooters;
512
513var $saveHTMLHeader;
514var $saveHTMLFooter;
515
516var $HTMLheaderPageLinks;
517var $HTMLheaderPageAnnots;
518var $HTMLheaderPageForms;
519
520// See config_fonts.php for these next 5 values
521var $available_unifonts;
522var $sans_fonts;
523var $serif_fonts;
524var $mono_fonts;
525var $defaultSubsFont;
526
527// List of ALL available CJK fonts (incl. styles) (Adobe add-ons) hw removed
528var $available_CJK_fonts;
529
530var $HTMLHeader;
531var $HTMLFooter;
532var $HTMLHeaderE;
533var $HTMLFooterE;
534var $bufferoutput;
535
536var $showdefaultpagenos; // DEPRACATED -left for backward compatability
537
538
539// CJK fonts
540var $Big5_widths;
541var $GB_widths;
542var $SJIS_widths;
543var $UHC_widths;
544
545// SetProtection
546var $encrypted; //whether document is protected
547var $Uvalue; //U entry in pdf document
548var $Ovalue; //O entry in pdf document
549var $Pvalue; //P entry in pdf document
550var $enc_obj_id; //encryption object id
551var $last_rc4_key; //last RC4 key encrypted (cached for optimisation)
552var $last_rc4_key_c; //last RC4 computed key
553var $encryption_key;
554var $padding; //used for encryption
555
556
557// Bookmark
558var $BMoutlines;
559var $OutlineRoot;
560// INDEX
561var $ColActive;
562var $Reference;
563var $CurrCol;
564var $NbCol;
565var $y0; //Top ordinate of columns
566var $ColL;
567var $ColWidth;
568var $ColGap;
569// COLUMNS
570var $ColR;
571var $ChangeColumn;
572var $columnbuffer;
573var $ColDetails;
574var $columnLinks;
575var $colvAlign;
576// Substitutions
577var $substitute; // Array of substitution strings e.g. <ttz>112</ttz>
578var $entsearch; // Array of HTML entities (>ASCII 127) to substitute
579var $entsubstitute; // Array of substitution decimal unicode for the Hi entities
580
581
582// Default values if no style sheet offered (cf. http://www.w3.org/TR/CSS21/sample.html)
583var $defaultCSS;
584
585var $linemaxfontsize;
586var $lineheight_correction;
587var $lastoptionaltag; // Save current block item which HTML specifies optionsl endtag
588var $pageoutput;
589var $charset_in;
590var $blk;
591var $blklvl;
592var $ColumnAdjust;
593var $ws; // Word spacing
594var $HREF;
595var $pgwidth;
596var $fontlist;
597var $oldx;
598var $oldy;
599var $B;
600var $U; //underlining flag
601var $S; // SmallCaps flag
602var $I;
603
604var $tdbegin;
605var $table;
606var $cell;
607var $col;
608var $row;
609
610var $divbegin;
611var $divalign;
612var $divwidth;
613var $divheight;
614var $divrevert;
615var $spanbgcolor;
616
617var $spanlvl;
618var $listlvl;
619var $listnum;
620var $listtype;
621var $listoccur;
622var $listlist;
623var $listitem;
624
625var $pjustfinished;
626var $ignorefollowingspaces;
627var $SUP;
628var $SUB;
629var $SMALL;
630var $BIG;
631var $toupper;
632var $tolower;
633var $capitalize;
634var $dash_on;
635var $dotted_on;
636var $strike;
637
638var $textbuffer;
639var $currentfontstyle;
640var $currentfontfamily;
641var $currentfontsize;
642var $colorarray;
643var $bgcolorarray;
644var $internallink;
645var $enabledtags;
646
647var $lineheight;
648var $basepath;
649var $textparam;
650
651var $specialcontent;
652var $selectoption;
653var $objectbuffer;
654
655// Table Rotation
656var $table_rotate;
657var $tbrot_maxw;
658var $tbrot_maxh;
659var $tablebuffer;
660var $tbrot_align;
661var $tbrot_Links;
662
663var $divbuffer; // Buffer used when keeping DIV on one page
664var $keep_block_together; // Keep a Block from page-break-inside: avoid
665var $ktLinks; // Keep-together Block links array
666var $ktBlock; // Keep-together Block array
667var $ktForms;
668var $ktReference;
669var $ktBMoutlines;
670var $_kttoc;
671
672var $tbrot_y0;
673var $tbrot_x0;
674var $tbrot_w;
675var $tbrot_h;
676
677var $mb_enc;
678var $directionality;
679
680var $extgstates; // Used for alpha channel - Transparency (Watermark)
681var $mgl;
682var $mgt;
683var $mgr;
684var $mgb;
685
686var $tts;
687var $ttz;
688var $tta;
689
690var $headerDetails;
691var $footerDetails;
692
693// Best to alter the below variables using default stylesheet above
694var $page_break_after_avoid;
695var $margin_bottom_collapse;
696var $list_indent;
697var $list_align;
698var $list_margin_bottom;
699var $default_font_size; // in pts
700var $original_default_font_size; // used to save default sizes when using table default
701var $original_default_font;
702var $watermark_font;
703var $defaultAlign;
704
705// TABLE
706var $defaultTableAlign;
707var $tablethead;
708var $thead_font_weight;
709var $thead_font_style;
710var $thead_font_smCaps;
711var $thead_valign_default;
712var $thead_textalign_default;
713var $tabletfoot;
714var $tfoot_font_weight;
715var $tfoot_font_style;
716var $tfoot_font_smCaps;
717var $tfoot_valign_default;
718var $tfoot_textalign_default;
719
720var $trow_text_rotate;
721
722var $cellPaddingL;
723var $cellPaddingR;
724var $cellPaddingT;
725var $cellPaddingB;
726var $table_lineheight;
727var $table_border_attr_set;
728var $table_border_css_set;
729
730var $shrin_k; // factor with which to shrink tables - used internally - do not change
731var $shrink_this_table_to_fit; // 0 or false to disable; value (if set) gives maximum factor to reduce fontsize
732var $MarginCorrection; // corrects for OddEven Margins
733var $margin_footer;
734var $margin_header;
735
736var $tabletheadjustfinished;
737var $usingCoreFont;
738var $charspacing;
739
740//Private properties FROM FPDF
741var $DisplayPreferences;
742var $flowingBlockAttr;
743var $page; //current page number
744var $n; //current object number
745var $offsets; //array of object offsets
746var $buffer; //buffer holding in-memory PDF
747var $pages; //array containing pages
748var $state; //current document state
749var $compress; //compression flag
750var $DefOrientation; //default orientation
751var $CurOrientation; //current orientation
752var $OrientationChanges; //array indicating orientation changes
753var $k; //scale factor (number of points in user unit)
754var $fwPt;
755var $fhPt; //dimensions of page format in points
756var $fw;
757var $fh; //dimensions of page format in user unit
758var $wPt;
759var $hPt; //current dimensions of page in points
760var $w;
761var $h; //current dimensions of page in user unit
762var $lMargin; //left margin
763var $tMargin; //top margin
764var $rMargin; //right margin
765var $bMargin; //page break margin
766var $cMarginL; //cell margin Left
767var $cMarginR; //cell margin Right
768var $cMarginT; //cell margin Left
769var $cMarginB; //cell margin Right
770var $DeflMargin; //Default left margin
771var $DefrMargin; //Default right margin
772var $x;
773var $y; //current position in user unit for cell positioning
774var $lasth; //height of last cell printed
775var $LineWidth; //line width in user unit
776var $CoreFonts; //array of standard font names
777var $fonts; //array of used fonts
778var $FontFiles; //array of font files
779var $images; //array of used images
780var $PageLinks; //array of links in pages
781var $links; //array of internal links
782var $FontFamily; //current font family
783var $FontStyle; //current font style
784var $CurrentFont; //current font info
785var $FontSizePt; //current font size in points
786var $FontSize; //current font size in user unit
787var $DrawColor; //commands for drawing color
788var $FillColor; //commands for filling color
789var $TextColor; //commands for text color
790var $ColorFlag; //indicates whether fill and text colors are different
791var $autoPageBreak; //automatic page breaking
792var $PageBreakTrigger; //threshold used to trigger page breaks
793var $InFooter; //flag set when processing footer
794var $InHTMLFooter;
795
796var $processingFooter; //flag set when processing footer - added for columns
797var $processingHeader; //flag set when processing header - added for columns
798var $ZoomMode; //zoom display mode
799var $LayoutMode; //layout display mode
800var $title; //title
801var $subject; //subject
802var $author; //author
803var $keywords; //keywords
804var $creator; //creator
805
806var $aliasNbPg; //alias for total number of pages
807var $aliasNbPgGp; //alias for total number of pages in page group
808var $aliasNbPgHex;
809var $aliasNbPgGpHex;
810
811var $ispre;
812
813var $outerblocktags;
814var $innerblocktags;
815
816
817// **********************************
818// **********************************
819// **********************************
820// **********************************
821// **********************************
822// **********************************
823// **********************************
824// **********************************
825// **********************************
826
827function mPDF($mode='',$format='A4',$default_font_size=0,$default_font='',$mgl=15,$mgr=15,$mgt=16,$mgb=16,$mgh=9,$mgf=9, $orientation='P') {
828
829/*-- BACKGROUNDS --*/
830 if (!class_exists('grad', false)) { include(_MPDF_PATH.'classes/grad.php'); }
831 if (empty($this->grad)) { $this->grad = new grad($this); }
832/*-- END BACKGROUNDS --*/
833/*-- FORMS --*/
834 if (!class_exists('form', false)) { include(_MPDF_PATH.'classes/form.php'); }
835 if (empty($this->form)) { $this->form = new form($this); }
836/*-- END FORMS --*/
837
838 $this->time0 = microtime(true);
839 //Some checks
840 $this->_dochecks();
841
842 // Set up Aliases for backwards compatability
843 $this->UnvalidatedText =& $this->watermarkText;
844 $this->TopicIsUnvalidated =& $this->showWatermarkText;
845 $this->AliasNbPg =& $this->aliasNbPg;
846 $this->AliasNbPgGp =& $this->aliasNbPgGp;
847 $this->BiDirectional =& $this->biDirectional;
848 $this->Anchor2Bookmark =& $this->anchor2Bookmark;
849 $this->KeepColumns =& $this->keepColumns;
850 $this->useOddEven =& $this->mirrorMargins;
851 $this->useSubstitutionsMB =& $this->useSubstitutions;
852
853 $this->writingToC = false; // mPDF 5.6.38
854 $this->uniqstr = '20110230'; // mPDF 5.7.2
855 // mPDF 5.6.01
856 $this->layers = array();
857 $this->current_layer = 0;
858 $this->open_layer_pane = false;
859
860 $this->visibility='visible';
861
862 //Initialization of properties
863 $this->spotColors=array();
864 $this->spotColorIDs = array();
865 $this->tableBackgrounds = array();
866
867 $this->kt_y00 = '';
868 $this->kt_p00 = '';
869 $this->iterationCounter = false;
870 $this->BMPonly = array();
871 $this->page=0;
872 $this->n=2;
873 $this->buffer='';
874 $this->objectbuffer = array();
875 $this->pages=array();
876 $this->OrientationChanges=array();
877 $this->state=0;
878 $this->fonts=array();
879 $this->FontFiles=array();
880 $this->images=array();
881 $this->links=array();
882 $this->InFooter=false;
883 $this->processingFooter=false;
884 $this->processingHeader=false;
885 $this->lasth=0;
886 $this->FontFamily='';
887 $this->FontStyle='';
888 $this->FontSizePt=9;
889 $this->U=false;
890 // Small Caps
891 $this->upperCase = array();
892 $this->S = false;
893 $this->smCapsScale = 1;
894 $this->smCapsStretch = 100;
895 $this->margBuffer = 0; // mPDF 5.4.04
896 $this->inMeter = false; // mPDF 5.5.09
897 $this->decimal_offset = 0;
898
899 $this->defTextColor = $this->TextColor = $this->SetTColor($this->ConvertColor(0),true);
900 $this->defDrawColor = $this->DrawColor = $this->SetDColor($this->ConvertColor(0),true);
901 $this->defFillColor = $this->FillColor = $this->SetFColor($this->ConvertColor(255),true);
902
903 //SVG color names array
904 //http://www.w3schools.com/css/css_colornames.asp
905 $this->SVGcolors = array('antiquewhite'=>'#FAEBD7','aqua'=>'#00FFFF','aquamarine'=>'#7FFFD4','beige'=>'#F5F5DC','black'=>'#000000',
906'blue'=>'#0000FF','brown'=>'#A52A2A','cadetblue'=>'#5F9EA0','chocolate'=>'#D2691E','cornflowerblue'=>'#6495ED','crimson'=>'#DC143C',
907'darkblue'=>'#00008B','darkgoldenrod'=>'#B8860B','darkgreen'=>'#006400','darkmagenta'=>'#8B008B','darkorange'=>'#FF8C00',
908'darkred'=>'#8B0000','darkseagreen'=>'#8FBC8F','darkslategray'=>'#2F4F4F','darkviolet'=>'#9400D3','deepskyblue'=>'#00BFFF',
909'dodgerblue'=>'#1E90FF','firebrick'=>'#B22222','forestgreen'=>'#228B22','fuchsia'=>'#FF00FF','gainsboro'=>'#DCDCDC','gold'=>'#FFD700',
910'gray'=>'#808080','green'=>'#008000','greenyellow'=>'#ADFF2F','hotpink'=>'#FF69B4','indigo'=>'#4B0082','khaki'=>'#F0E68C',
911'lavenderblush'=>'#FFF0F5','lemonchiffon'=>'#FFFACD','lightcoral'=>'#F08080','lightgoldenrodyellow'=>'#FAFAD2','lightgreen'=>'#90EE90',
912'lightsalmon'=>'#FFA07A','lightskyblue'=>'#87CEFA','lightslategray'=>'#778899','lightyellow'=>'#FFFFE0','lime'=>'#00FF00','limegreen'=>'#32CD32',
913'magenta'=>'#FF00FF','maroon'=>'#800000','mediumaquamarine'=>'#66CDAA','mediumorchid'=>'#BA55D3','mediumseagreen'=>'#3CB371',
914'mediumspringgreen'=>'#00FA9A','mediumvioletred'=>'#C71585','midnightblue'=>'#191970','mintcream'=>'#F5FFFA','moccasin'=>'#FFE4B5','navy'=>'#000080',
915'olive'=>'#808000','orange'=>'#FFA500','orchid'=>'#DA70D6','palegreen'=>'#98FB98',
916'palevioletred'=>'#D87093','peachpuff'=>'#FFDAB9','pink'=>'#FFC0CB','powderblue'=>'#B0E0E6','purple'=>'#800080',
917'red'=>'#FF0000','royalblue'=>'#4169E1','salmon'=>'#FA8072','seagreen'=>'#2E8B57','sienna'=>'#A0522D','silver'=>'#C0C0C0','skyblue'=>'#87CEEB',
918'slategray'=>'#708090','springgreen'=>'#00FF7F','steelblue'=>'#4682B4','tan'=>'#D2B48C','teal'=>'#008080','thistle'=>'#D8BFD8','turquoise'=>'#40E0D0',
919'violetred'=>'#D02090','white'=>'#FFFFFF','yellow'=>'#FFFF00',
920'aliceblue'=>'#f0f8ff', 'azure'=>'#f0ffff', 'bisque'=>'#ffe4c4', 'blanchedalmond'=>'#ffebcd', 'blueviolet'=>'#8a2be2', 'burlywood'=>'#deb887',
921'chartreuse'=>'#7fff00', 'coral'=>'#ff7f50', 'cornsilk'=>'#fff8dc', 'cyan'=>'#00ffff', 'darkcyan'=>'#008b8b', 'darkgray'=>'#a9a9a9',
922'darkgrey'=>'#a9a9a9', 'darkkhaki'=>'#bdb76b', 'darkolivegreen'=>'#556b2f', 'darkorchid'=>'#9932cc', 'darksalmon'=>'#e9967a',
923'darkslateblue'=>'#483d8b', 'darkslategrey'=>'#2f4f4f', 'darkturquoise'=>'#00ced1', 'deeppink'=>'#ff1493', 'dimgray'=>'#696969',
924'dimgrey'=>'#696969', 'floralwhite'=>'#fffaf0', 'ghostwhite'=>'#f8f8ff', 'goldenrod'=>'#daa520', 'grey'=>'#808080', 'honeydew'=>'#f0fff0',
925'indianred'=>'#cd5c5c', 'ivory'=>'#fffff0', 'lavender'=>'#e6e6fa', 'lawngreen'=>'#7cfc00', 'lightblue'=>'#add8e6', 'lightcyan'=>'#e0ffff',
926'lightgray'=>'#d3d3d3', 'lightgrey'=>'#d3d3d3', 'lightpink'=>'#ffb6c1', 'lightseagreen'=>'#20b2aa', 'lightslategrey'=>'#778899',
927'lightsteelblue'=>'#b0c4de', 'linen'=>'#faf0e6', 'mediumblue'=>'#0000cd', 'mediumpurple'=>'#9370db', 'mediumslateblue'=>'#7b68ee',
928'mediumturquoise'=>'#48d1cc', 'mistyrose'=>'#ffe4e1', 'navajowhite'=>'#ffdead', 'oldlace'=>'#fdf5e6', 'olivedrab'=>'#6b8e23', 'orangered'=>'#ff4500',
929'palegoldenrod'=>'#eee8aa', 'paleturquoise'=>'#afeeee', 'papayawhip'=>'#ffefd5', 'peru'=>'#cd853f', 'plum'=>'#dda0dd', 'rosybrown'=>'#bc8f8f',
930'saddlebrown'=>'#8b4513', 'sandybrown'=>'#f4a460', 'seashell'=>'#fff5ee', 'slateblue'=>'#6a5acd', 'slategrey'=>'#708090', 'snow'=>'#fffafa',
931'tomato'=>'#ff6347', 'violet'=>'#ee82ee', 'wheat'=>'#f5deb3', 'whitesmoke'=>'#f5f5f5', 'yellowgreen'=>'#9acd32');
932
933 $this->ColorFlag=false;
934 $this->extgstates = array();
935
936 $this->mb_enc='windows-1252';
937 $this->directionality='ltr';
938 $this->defaultAlign = 'L';
939 $this->defaultTableAlign = 'L';
940
941 $this->fixedPosBlockSave = array();
942 $this->extraFontSubsets = 0;
943
944 $this->SHYpatterns = array();
945 $this->loadedSHYdictionary = false;
946 $this->SHYdictionary = array();
947 $this->SHYdictionaryWords = array();
948 $this->blockContext = 1;
949 $this->floatDivs = array();
950 $this->DisplayPreferences='';
951
952 $this->patterns = array(); // Tiling patterns used for backgrounds
953 $this->pageBackgrounds = array();
954 $this->writingHTMLheader = false; // internal flag - used both for writing HTMLHeaders/Footers and FixedPos block
955 $this->writingHTMLfooter = false; // internal flag - used both for writing HTMLHeaders/Footers and FixedPos block
956 $this->gradients = array();
957
958 $this->kwt_Reference = array();
959 $this->kwt_BMoutlines = array();
960 $this->kwt_toc = array();
961
962 $this->tbrot_Reference = array();
963 $this->tbrot_BMoutlines = array();
964 $this->tbrot_toc = array();
965
966 $this->col_Reference = array();
967 $this->col_BMoutlines = array();
968 $this->col_toc = array();
969 $this->graphs = array();
970
971 $this->pgsIns = array();
972 $this->PDFAXwarnings = array();
973 $this->inlineDisplayOff = false;
974 $this->kerning = false;
975 $this->lSpacingCSS = '';
976 $this->wSpacingCSS = '';
977 $this->fixedlSpacing = false;
978 $this->minwSpacing = 0;
979
980
981 $this->baselineC = 0.35; // Baseline for text
982 $this->noImageFile = str_replace("\\","/",dirname(__FILE__)) . '/includes/no_image.jpg';
983 $this->subPos = 0;
984 $this->forceExactLineheight = false;
985 $this->listOcc = 0;
986 $this->normalLineheight = 1.3;
987 // These are intended as configuration variables, and should be set in config.php - which will override these values;
988 // set here as failsafe as will cause an error if not defined
989 $this->incrementFPR1 = 10;
990 $this->incrementFPR2 = 10;
991 $this->incrementFPR3 = 10;
992 $this->incrementFPR4 = 10;
993
994 $this->fullImageHeight = false;
995 $this->floatbuffer = array();
996 $this->floatmargins = array();
997 $this->autoFontGroups = 0;
998 $this->formobjects=array(); // array of Form Objects for WMF
999 $this->InlineProperties=array();
1000 $this->InlineAnnots=array();
1001 $this->ktAnnots=array();
1002 $this->tbrot_Annots=array();
1003 $this->kwt_Annots=array();
1004 $this->columnAnnots=array();
1005 $this->pageDim=array();
1006 $this->breakpoints = array(); // used in columnbuffer
1007 $this->tableLevel=0;
1008 $this->tbctr=array(); // counter for nested tables at each level
1009 $this->page_box = array();
1010 $this->show_marks = ''; // crop or cross marks
1011 $this->kwt = false;
1012 $this->kwt_height = 0;
1013 $this->kwt_y0 = 0;
1014 $this->kwt_x0 = 0;
1015 $this->kwt_buffer = array();
1016 $this->kwt_Links = array();
1017 $this->kwt_moved = false;
1018 $this->kwt_saved = false;
1019 $this->PageNumSubstitutions = array();
1020 $this->base_table_properties=array();
1021 $this->borderstyles = array('inset','groove','outset','ridge','dotted','dashed','solid','double');
1022 $this->tbrot_align = 'C';
1023 $this->pageheaders=array();
1024 $this->pagefooters=array();
1025
1026 $this->pageHTMLheaders=array();
1027 $this->pageHTMLfooters=array();
1028 $this->HTMLheaderPageLinks = array();
1029 $this->HTMLheaderPageAnnots = array();
1030
1031 $this->ktForms = array();
1032 $this->HTMLheaderPageForms = array();
1033 $this->columnForms = array();
1034 $this->tbrotForms = array();
1035 $this->useRC128encryption = false;
1036 $this->uniqid = '';
1037
1038 $this->bufferoutput = false;
1039 $this->encrypted=false; //whether document is protected
1040 $this->BMoutlines=array();
1041 $this->ColActive=0; //Flag indicating that columns are on (the index is being processed)
1042 $this->Reference=array(); //Array containing the references
1043 $this->CurrCol=0; //Current column number
1044 $this->ColL = array(0); // Array of Left pos of columns - absolute - needs Margin correction for Odd-Even
1045 $this->ColR = array(0); // Array of Right pos of columns - absolute pos - needs Margin correction for Odd-Even
1046 $this->ChangeColumn = 0;
1047 $this->columnbuffer = array();
1048 $this->ColDetails = array(); // Keeps track of some column details
1049 $this->columnLinks = array(); // Cross references PageLinks
1050 $this->substitute = array(); // Array of substitution strings e.g. <ttz>112</ttz>
1051 $this->entsearch = array(); // Array of HTML entities (>ASCII 127) to substitute
1052 $this->entsubstitute = array(); // Array of substitution decimal unicode for the Hi entities
1053 $this->lastoptionaltag = '';
1054 $this->charset_in = '';
1055 $this->blk = array();
1056 $this->blklvl = 0;
1057 $this->tts = false;
1058 $this->ttz = false;
1059 $this->tta = false;
1060 $this->ispre=false;
1061
1062 $this->checkSIP = false;
1063 $this->checkSMP = false;
1064 $this->checkCJK = false;
1065 $this->tableCJK = false;
1066
1067 $this->headerDetails=array();
1068 $this->footerDetails=array();
1069 $this->page_break_after_avoid = false;
1070 $this->margin_bottom_collapse = false;
1071 $this->tablethead = 0;
1072 $this->tabletfoot = 0;
1073 $this->table_border_attr_set = 0;
1074 $this->table_border_css_set = 0;
1075 $this->shrin_k = 1.0;
1076 $this->shrink_this_table_to_fit = 0;
1077 $this->MarginCorrection = 0;
1078
1079 $this->tabletheadjustfinished = false;
1080 $this->usingCoreFont = false;
1081 $this->charspacing=0;
1082
1083 $this->autoPageBreak = true;
1084
1085 require(_MPDF_PATH.'config.php'); // config data
1086
1087 $this->_setPageSize($format, $orientation);
1088 $this->DefOrientation=$orientation;
1089
1090 $this->margin_header=$mgh;
1091 $this->margin_footer=$mgf;
1092
1093 $bmargin=$mgb;
1094
1095 $this->DeflMargin = $mgl;
1096 $this->DefrMargin = $mgr;
1097
1098 $this->orig_tMargin = $mgt;
1099 $this->orig_bMargin = $bmargin;
1100 $this->orig_lMargin = $this->DeflMargin;
1101 $this->orig_rMargin = $this->DefrMargin;
1102 $this->orig_hMargin = $this->margin_header;
1103 $this->orig_fMargin = $this->margin_footer;
1104
1105 if ($this->setAutoTopMargin=='pad') { $mgt += $this->margin_header; }
1106 if ($this->setAutoBottomMargin=='pad') { $mgb += $this->margin_footer; }
1107 $this->SetMargins($this->DeflMargin,$this->DefrMargin,$mgt); // sets l r t margin
1108 //Automatic page break
1109 $this->SetAutoPageBreak($this->autoPageBreak,$bmargin); // sets $this->bMargin & PageBreakTrigger
1110
1111 $this->pgwidth = $this->w - $this->lMargin - $this->rMargin;
1112
1113 //Interior cell margin (1 mm) ? not used
1114 $this->cMarginL = 1;
1115 $this->cMarginR = 1;
1116 //Line width (0.2 mm)
1117 $this->LineWidth=.567/_MPDFK;
1118
1119 //To make the function Footer() work - replaces {nb} with page number
1120 $this->AliasNbPages();
1121 $this->AliasNbPageGroups();
1122
1123 $this->aliasNbPgHex = '{nbHEXmarker}';
1124 $this->aliasNbPgGpHex = '{nbpgHEXmarker}';
1125
1126 //Enable all tags as default
1127 $this->DisableTags();
1128 //Full width display mode
1129 $this->SetDisplayMode(100); // fullwidth? 'fullpage'
1130 //Compression
1131 $this->SetCompression(true);
1132 //Set default display preferences
1133 $this->SetDisplayPreferences('');
1134
1135 // Font data
1136 require(_MPDF_PATH.'config_fonts.php');
1137 // Available fonts
1138 $this->available_unifonts = array();
1139 foreach ($this->fontdata AS $f => $fs) {
1140 if (isset($fs['R']) && $fs['R']) { $this->available_unifonts[] = $f; }
1141 if (isset($fs['B']) && $fs['B']) { $this->available_unifonts[] = $f.'B'; }
1142 if (isset($fs['I']) && $fs['I']) { $this->available_unifonts[] = $f.'I'; }
1143 if (isset($fs['BI']) && $fs['BI']) { $this->available_unifonts[] = $f.'BI'; }
1144 }
1145
1146 $this->default_available_fonts = $this->available_unifonts;
1147
1148 $optcore = false;
1149 $onlyCoreFonts = false;
1150 if (preg_match('/([\-+])aCJK/i',$mode, $m)) {
1151 $mode = preg_replace('/([\-+])aCJK/i','',$mode);
1152 if ($m[1]=='+') { $this->useAdobeCJK = true; }
1153 else { $this->useAdobeCJK = false; }
1154 }
1155
1156 if (strlen($mode)==1) {
1157 if ($mode=='s') { $this->percentSubset = 100; $mode = ''; }
1158 else if ($mode=='c') { $onlyCoreFonts = true; $mode = ''; }
1159 }
1160 else if (substr($mode,-2)=='-s') {
1161 $this->percentSubset = 100;
1162 $mode = substr($mode,0,strlen($mode)-2);
1163 }
1164 else if (substr($mode,-2)=='-c') {
1165 $onlyCoreFonts = true;
1166 $mode = substr($mode,0,strlen($mode)-2);
1167 }
1168 else if (substr($mode,-2)=='-x') {
1169 $optcore = true;
1170 $mode = substr($mode,0,strlen($mode)-2);
1171 }
1172
1173 // Autodetect if mode is a language_country string (en-GB or en_GB or en)
1174 if ((strlen($mode) == 5 && $mode != 'UTF-8') || strlen($mode) == 2) {
1175 list ($coreSuitable,$mpdf_pdf_unifonts) = GetLangOpts($mode, $this->useAdobeCJK);
1176 if ($coreSuitable && $optcore) { $onlyCoreFonts = true; }
1177 if ($mpdf_pdf_unifonts) {
1178 $this->RestrictUnicodeFonts($mpdf_pdf_unifonts);
1179 $this->default_available_fonts = $mpdf_pdf_unifonts;
1180 }
1181 $this->currentLang = $mode;
1182 $this->default_lang = $mode;
1183 }
1184
1185 $this->onlyCoreFonts = $onlyCoreFonts;
1186
1187 if ($this->onlyCoreFonts) {
1188 $this->setMBencoding('windows-1252'); // sets $this->mb_enc
1189 }
1190 else {
1191 $this->setMBencoding('UTF-8'); // sets $this->mb_enc
1192 }
1193 @mb_regex_encoding('UTF-8'); // required only for mb_ereg... and mb_split functions
1194
1195
1196 // Adobe CJK fonts
1197 $this->available_CJK_fonts = array('gb','big5','sjis','uhc','gbB','big5B','sjisB','uhcB','gbI','big5I','sjisI','uhcI',
1198 'gbBI','big5BI','sjisBI','uhcBI');
1199
1200
1201 //Standard fonts
1202 $this->CoreFonts=array('ccourier'=>'Courier','ccourierB'=>'Courier-Bold','ccourierI'=>'Courier-Oblique','ccourierBI'=>'Courier-BoldOblique',
1203 'chelvetica'=>'Helvetica','chelveticaB'=>'Helvetica-Bold','chelveticaI'=>'Helvetica-Oblique','chelveticaBI'=>'Helvetica-BoldOblique',
1204 'ctimes'=>'Times-Roman','ctimesB'=>'Times-Bold','ctimesI'=>'Times-Italic','ctimesBI'=>'Times-BoldItalic',
1205 'csymbol'=>'Symbol','czapfdingbats'=>'ZapfDingbats');
1206 $this->fontlist=array("ctimes","ccourier","chelvetica","csymbol","czapfdingbats");
1207
1208 // Substitutions
1209 $this->setHiEntitySubstitutions();
1210
1211 if ($this->onlyCoreFonts) {
1212 $this->useSubstitutions = true;
1213 $this->SetSubstitutions();
1214 }
1215 else { $this->useSubstitutions = false; }
1216
1217/*-- HTML-CSS --*/
1218
1219 if (!class_exists('cssmgr', false)) { include(_MPDF_PATH .'classes/cssmgr.php'); }
1220 $this->cssmgr = new cssmgr($this);
1221 if (file_exists(_MPDF_PATH.'mpdf.css')) {
1222 $css = file_get_contents(_MPDF_PATH.'mpdf.css');
1223 $css2 = $this->cssmgr->ReadDefaultCSS($css);
1224 $this->defaultCSS = $this->cssmgr->array_merge_recursive_unique($this->defaultCSS,$css2);
1225 }
1226/*-- END HTML-CSS --*/
1227
1228 if ($default_font=='') {
1229 if ($this->onlyCoreFonts) {
1230 if (in_array(strtolower($this->defaultCSS['BODY']['FONT-FAMILY']),$this->mono_fonts)) { $default_font = 'ccourier'; }
1231 else if (in_array(strtolower($this->defaultCSS['BODY']['FONT-FAMILY']),$this->sans_fonts)) { $default_font = 'chelvetica'; }
1232 else { $default_font = 'ctimes'; }
1233 }
1234 else { $default_font = $this->defaultCSS['BODY']['FONT-FAMILY']; }
1235 }
1236 if (!$default_font_size) {
1237 $mmsize = $this->ConvertSize($this->defaultCSS['BODY']['FONT-SIZE']);
1238 $default_font_size = $mmsize*(_MPDFK);
1239 }
1240
1241 if ($default_font) { $this->SetDefaultFont($default_font); }
1242 if ($default_font_size) { $this->SetDefaultFontSize($default_font_size); }
1243
1244 $this->SetLineHeight(); // lineheight is in mm
1245
1246 $this->SetFColor($this->ConvertColor(255));
1247 $this->HREF='';
1248 $this->oldy=-1;
1249 $this->B=0;
1250 $this->U=false;
1251 $this->S=false;
1252 $this->I=0;
1253
1254 $this->listlvl=0;
1255 $this->listnum=0;
1256 $this->listtype='';
1257 $this->listoccur=array();
1258 $this->listlist=array();
1259 $this->listitem=array();
1260
1261 $this->tdbegin=false;
1262 $this->table=array();
1263 $this->cell=array();
1264 $this->col=-1;
1265 $this->row=-1;
1266 $this->cellBorderBuffer = array();
1267
1268 $this->divbegin=false;
1269 $this->divalign='';
1270 $this->divwidth=0;
1271 $this->divheight=0;
1272 $this->spanbgcolor=false;
1273 $this->divrevert=false;
1274 $this->spanborder=false;
1275 $this->spanborddet=array();
1276
1277 $this->blockjustfinished=false;
1278 $this->listjustfinished=false;
1279 $this->ignorefollowingspaces = true; //in order to eliminate exceeding left-side spaces
1280 $this->toupper=false;
1281 $this->tolower=false;
1282 $this->capitalize=false;
1283 $this->dash_on=false;
1284 $this->dotted_on=false;
1285 $this->SUP=false;
1286 $this->SUB=false;
1287 $this->strike=false;
1288 $this->textshadow='';
1289
1290 $this->currentfontfamily='';
1291 $this->currentfontsize='';
1292 $this->currentfontstyle='';
1293 $this->colorarray=array();
1294 $this->spanbgcolorarray=array();
1295 $this->textbuffer=array();
1296 $this->internallink=array();
1297 $this->basepath = "";
1298
1299 $this->SetBasePath('');
1300
1301 $this->textparam = array();
1302
1303 $this->specialcontent = '';
1304 $this->selectoption = array();
1305
1306/*-- IMPORTS --*/
1307
1308 $this->tpls = array();
1309 $this->tpl = 0;
1310 $this->tplprefix = "/TPL";
1311 $this->res = array();
1312 if ($this->enableImports) {
1313 $this->SetImportUse();
1314 }
1315/*-- END IMPORTS --*/
1316
1317 if ($this->progressBar) { $this->StartProgressBarOutput($this->progressBar) ; } // *PROGRESS-BAR*
1318}
1319
1320
1321function _setPageSize($format, &$orientation) {
1322 //Page format
1323 if(is_string($format))
1324 {
1325 if ($format=='') { $format = 'A4'; }
1326 $pfo = 'P';
1327 if(preg_match('/([0-9a-zA-Z]*)-L/i',$format,$m)) { // e.g. A4-L = A4 landscape
1328 $format=$m[1];
1329 $pfo='L';
1330 }
1331 $format = $this->_getPageFormat($format);
1332 if (!$format) { $this->Error('Unknown page format: '.$format); }
1333 else { $orientation = $pfo; }
1334
1335 $this->fwPt=$format[0];
1336 $this->fhPt=$format[1];
1337 }
1338 else
1339 {
1340 if (!$format[0] || !$format[1]) { $this->Error('Invalid page format: '.$format[0].' '.$format[1]); }
1341 $this->fwPt=$format[0]*_MPDFK;
1342 $this->fhPt=$format[1]*_MPDFK;
1343 }
1344 $this->fw=$this->fwPt/_MPDFK;
1345 $this->fh=$this->fhPt/_MPDFK;
1346 //Page orientation
1347 $orientation=strtolower($orientation);
1348 if($orientation=='p' or $orientation=='portrait')
1349 {
1350 $orientation='P';
1351 $this->wPt=$this->fwPt;
1352 $this->hPt=$this->fhPt;
1353 }
1354 elseif($orientation=='l' or $orientation=='landscape')
1355 {
1356 $orientation='L';
1357 $this->wPt=$this->fhPt;
1358 $this->hPt=$this->fwPt;
1359 }
1360 else $this->Error('Incorrect orientation: '.$orientation);
1361 $this->CurOrientation=$orientation;
1362
1363 $this->w=$this->wPt/_MPDFK;
1364 $this->h=$this->hPt/_MPDFK;
1365}
1366
1367function _getPageFormat($format) {
1368 switch (strtoupper($format)) {
1369 case '4A0': {$format = array(4767.87,6740.79); break;}
1370 case '2A0': {$format = array(3370.39,4767.87); break;}
1371 case 'A0': {$format = array(2383.94,3370.39); break;}
1372 case 'A1': {$format = array(1683.78,2383.94); break;}
1373 case 'A2': {$format = array(1190.55,1683.78); break;}
1374 case 'A3': {$format = array(841.89,1190.55); break;}
1375 case 'A4': default: {$format = array(595.28,841.89); break;}
1376 case 'A5': {$format = array(419.53,595.28); break;}
1377 case 'A6': {$format = array(297.64,419.53); break;}
1378 case 'A7': {$format = array(209.76,297.64); break;}
1379 case 'A8': {$format = array(147.40,209.76); break;}
1380 case 'A9': {$format = array(104.88,147.40); break;}
1381 case 'A10': {$format = array(73.70,104.88); break;}
1382 case 'B0': {$format = array(2834.65,4008.19); break;}
1383 case 'B1': {$format = array(2004.09,2834.65); break;}
1384 case 'B2': {$format = array(1417.32,2004.09); break;}
1385 case 'B3': {$format = array(1000.63,1417.32); break;}
1386 case 'B4': {$format = array(708.66,1000.63); break;}
1387 case 'B5': {$format = array(498.90,708.66); break;}
1388 case 'B6': {$format = array(354.33,498.90); break;}
1389 case 'B7': {$format = array(249.45,354.33); break;}
1390 case 'B8': {$format = array(175.75,249.45); break;}
1391 case 'B9': {$format = array(124.72,175.75); break;}
1392 case 'B10': {$format = array(87.87,124.72); break;}
1393 case 'C0': {$format = array(2599.37,3676.54); break;}
1394 case 'C1': {$format = array(1836.85,2599.37); break;}
1395 case 'C2': {$format = array(1298.27,1836.85); break;}
1396 case 'C3': {$format = array(918.43,1298.27); break;}
1397 case 'C4': {$format = array(649.13,918.43); break;}
1398 case 'C5': {$format = array(459.21,649.13); break;}
1399 case 'C6': {$format = array(323.15,459.21); break;}
1400 case 'C7': {$format = array(229.61,323.15); break;}
1401 case 'C8': {$format = array(161.57,229.61); break;}
1402 case 'C9': {$format = array(113.39,161.57); break;}
1403 case 'C10': {$format = array(79.37,113.39); break;}
1404 case 'RA0': {$format = array(2437.80,3458.27); break;}
1405 case 'RA1': {$format = array(1729.13,2437.80); break;}
1406 case 'RA2': {$format = array(1218.90,1729.13); break;}
1407 case 'RA3': {$format = array(864.57,1218.90); break;}
1408 case 'RA4': {$format = array(609.45,864.57); break;}
1409 case 'SRA0': {$format = array(2551.18,3628.35); break;}
1410 case 'SRA1': {$format = array(1814.17,2551.18); break;}
1411 case 'SRA2': {$format = array(1275.59,1814.17); break;}
1412 case 'SRA3': {$format = array(907.09,1275.59); break;}
1413 case 'SRA4': {$format = array(637.80,907.09); break;}
1414 case 'LETTER': {$format = array(612.00,792.00); break;}
1415 case 'LEGAL': {$format = array(612.00,1008.00); break;}
1416 case 'LEDGER': {$format = array(279.00,432.00); break;}
1417 case 'TABLOID': {$format = array(279.00,432.00); break;}
1418 case 'EXECUTIVE': {$format = array(521.86,756.00); break;}
1419 case 'FOLIO': {$format = array(612.00,936.00); break;}
1420 case 'B': {$format=array(362.83,561.26 ); break;} // 'B' format paperback size 128x198mm
1421 case 'A': {$format=array(314.65,504.57 ); break;} // 'A' format paperback size 111x178mm
1422 case 'DEMY': {$format=array(382.68,612.28 ); break;} // 'Demy' format paperback size 135x216mm
1423 case 'ROYAL': {$format=array(433.70,663.30 ); break;} // 'Royal' format paperback size 153x234mm
1424 default: $format = false;
1425 }
1426 return $format;
1427}
1428
1429
1430/*-- PROGRESS-BAR --*/
1431function StartProgressBarOutput($mode=1) {
1432 // must be relative path, or URI (not a file system path)
1433 if (!defined('_MPDF_URI')) {
1434 $this->progressBar = false;
1435 if ($this->debug) { $this->Error("You need to define _MPDF_URI to use the progress bar!"); }
1436 else return false;
1437 }
1438 $this->progressBar = $mode;
1439 if ($this->progbar_altHTML) {
1440 echo $this->progbar_altHTML;
1441 }
1442 else {
1443 echo '<html>
1444 <head>
1445 <title>mPDF File Progress</title>
1446 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
1447 <link rel="stylesheet" type="text/css" href="'._MPDF_URI.'progbar.css" />
1448 </head>
1449 <body>
1450 <div class="main">
1451 <div class="heading">'.$this->progbar_heading.'</div>
1452 <div class="demo">
1453 ';
1454 if ($this->progressBar==2) { echo ' <table width="100%"><tr><td style="width: 50%;">
1455 <span class="barheading">Writing HTML code</span> <br/>
1456
1457 <div class="progressBar">
1458 <div id="element1" class="innerBar">&nbsp;</div>
1459 </div>
1460 <span class="code" id="box1"></span>
1461 </td><td style="width: 50%;">
1462 <span class="barheading">Autosizing elements</span> <br/>
1463 <div class="progressBar">
1464 <div id="element4" class="innerBar">&nbsp;</div>
1465 </div>
1466 <span class="code" id="box4"></span>
1467 <br/><br/>
1468 <span class="barheading">Writing Tables</span> <br/>
1469 <div class="progressBar">
1470 <div id="element7" class="innerBar">&nbsp;</div>
1471 </div>
1472 <span class="code" id="box7"></span>
1473 </td></tr>
1474 <tr><td><br /><br /></td><td></td></tr>
1475 <tr><td style="width: 50%;">
1476 '; }
1477 echo ' <span class="barheading">Writing PDF file</span> <br/>
1478 <div class="progressBar">
1479 <div id="element2" class="innerBar">&nbsp;</div>
1480 </div>
1481 <span class="code" id="box2"></span>
1482 ';
1483 if ($this->progressBar==2) { echo '
1484 </td><td style="width: 50%;">
1485 <span class="barheading">Memory usage</span> <br/>
1486 <div class="progressBar">
1487 <div id="element5" class="innerBar">&nbsp;</div>
1488 </div>
1489 <span id="box5">0</span> '.ini_get("memory_limit").'<br />
1490 <br/><br/>
1491 <span class="barheading">Memory usage (peak)</span> <br/>
1492 <div class="progressBar">
1493 <div id="element6" class="innerBar">&nbsp;</div>
1494 </div>
1495 <span id="box6">0</span> '.ini_get("memory_limit").'<br />
1496 </td></tr>
1497 </table>
1498 '; }
1499 echo ' <br/><br/>
1500 <span id="box3"></span>
1501
1502 </div>
1503 ';
1504 }
1505 ob_flush();
1506 flush();
1507}
1508
1509function UpdateProgressBar($el,$val,$txt='') {
1510 // $val should be a string - 5 = actual value, +15 = increment
1511
1512 if ($this->progressBar<2) {
1513 if ($el>3) { return; }
1514 else if ($el ==1) { $el = 2; }
1515 }
1516 echo '<script type="text/javascript">';
1517 if ($val) { echo ' document.getElementById(\'element'.$el.'\').style.width=\''.$val.'%\'; '; }
1518 if ($txt) { echo ' document.getElementById(\'box'.$el.'\').innerHTML=\''.$txt.'\'; '; }
1519 if ($this->progressBar==2) {
1520 $m = round(memory_get_usage(true)/1048576);
1521 $m2 = round(memory_get_peak_usage(true)/1048576);
1522 $mem = $m * 100 / (ini_get("memory_limit")+0);
1523 $mem2 = $m2 * 100 / (ini_get("memory_limit")+0);
1524 echo ' document.getElementById(\'element5\').style.width=\''.$mem.'%\'; ';
1525 echo ' document.getElementById(\'element6\').style.width=\''.$mem2.'%\'; ';
1526 echo ' document.getElementById(\'box5\').innerHTML=\''.$m.'MB / \'; ';
1527 echo ' document.getElementById(\'box6\').innerHTML=\''.$m2.'MB / \'; ';
1528 }
1529 echo '</script>'."\n";
1530 ob_flush();
1531 flush();
1532}
1533/*-- END PROGRESS-BAR --*/
1534
1535
1536
1537function RestrictUnicodeFonts($res) {
1538 // $res = array of (Unicode) fonts to restrict to: e.g. norasi|norasiB - language specific
1539 if (count($res)) { // Leave full list of available fonts if passed blank array
1540 $this->available_unifonts = $res;
1541 }
1542 else { $this->available_unifonts = $this->default_available_fonts; }
1543 if (count($this->available_unifonts) == 0) { $this->available_unifonts[] = $this->default_available_fonts[0]; }
1544 $this->available_unifonts = array_values($this->available_unifonts);
1545}
1546
1547
1548function setMBencoding($enc) {
1549 if ($this->mb_enc != $enc) {
1550 $this->mb_enc = $enc;
1551 mb_internal_encoding($this->mb_enc);
1552 }
1553}
1554
1555
1556function SetMargins($left,$right,$top) {
1557 //Set left, top and right margins
1558 $this->lMargin=$left;
1559 $this->rMargin=$right;
1560 $this->tMargin=$top;
1561}
1562
1563function ResetMargins() {
1564 //ReSet left, top margins
1565 if (($this->forcePortraitHeaders || $this->forcePortraitMargins) && $this->DefOrientation=='P' && $this->CurOrientation=='L') {
1566 if (($this->mirrorMargins) && (($this->page)%2==0)) { // EVEN
1567 $this->tMargin=$this->orig_rMargin;
1568 $this->bMargin=$this->orig_lMargin;
1569 }
1570 else { // ODD // OR NOT MIRRORING MARGINS/FOOTERS
1571 $this->tMargin=$this->orig_lMargin;
1572 $this->bMargin=$this->orig_rMargin;
1573 }
1574 $this->lMargin=$this->DeflMargin;
1575 $this->rMargin=$this->DefrMargin;
1576 $this->MarginCorrection = 0;
1577 $this->PageBreakTrigger=$this->h-$this->bMargin;
1578 }
1579 else if (($this->mirrorMargins) && (($this->page)%2==0)) { // EVEN
1580 $this->lMargin=$this->DefrMargin;
1581 $this->rMargin=$this->DeflMargin;
1582 $this->MarginCorrection = $this->DefrMargin-$this->DeflMargin;
1583
1584 }
1585 else { // ODD // OR NOT MIRRORING MARGINS/FOOTERS
1586 $this->lMargin=$this->DeflMargin;
1587 $this->rMargin=$this->DefrMargin;
1588 if ($this->mirrorMargins) { $this->MarginCorrection = $this->DeflMargin-$this->DefrMargin; }
1589 }
1590 $this->x=$this->lMargin;
1591
1592}
1593
1594function SetLeftMargin($margin) {
1595 //Set left margin
1596 $this->lMargin=$margin;
1597 if($this->page>0 and $this->x<$margin) $this->x=$margin;
1598}
1599
1600function SetTopMargin($margin) {
1601 //Set top margin
1602 $this->tMargin=$margin;
1603}
1604
1605function SetRightMargin($margin) {
1606 //Set right margin
1607 $this->rMargin=$margin;
1608}
1609
1610function SetAutoPageBreak($auto,$margin=0) {
1611 //Set auto page break mode and triggering margin
1612 $this->autoPageBreak=$auto;
1613 $this->bMargin=$margin;
1614 $this->PageBreakTrigger=$this->h-$margin;
1615}
1616
1617function SetDisplayMode($zoom,$layout='continuous') {
1618 //Set display mode in viewer
1619 if($zoom=='fullpage' or $zoom=='fullwidth' or $zoom=='real' or $zoom=='default' or !is_string($zoom))
1620 $this->ZoomMode=$zoom;
1621 else
1622 $this->Error('Incorrect zoom display mode: '.$zoom);
1623 if($layout=='single' or $layout=='continuous' or $layout=='two' or $layout=='twoleft' or $layout=='tworight' or $layout=='default')
1624 $this->LayoutMode=$layout;
1625 else
1626 $this->Error('Incorrect layout display mode: '.$layout);
1627}
1628
1629function SetCompression($compress) {
1630 //Set page compression
1631 if(function_exists('gzcompress')) $this->compress=$compress;
1632 else $this->compress=false;
1633}
1634
1635function SetTitle($title) {
1636 //Title of document // Arrives as UTF-8
1637 $this->title = $title;
1638}
1639
1640function SetSubject($subject) {
1641 //Subject of document
1642 $this->subject= $subject;
1643}
1644
1645function SetAuthor($author) {
1646 //Author of document
1647 $this->author= $author;
1648}
1649
1650function SetKeywords($keywords) {
1651 //Keywords of document
1652 $this->keywords= $keywords;
1653}
1654
1655function SetCreator($creator) {
1656 //Creator of document
1657 $this->creator= $creator;
1658}
1659
1660
1661function SetAnchor2Bookmark($x) {
1662 $this->anchor2Bookmark = $x;
1663}
1664
1665function AliasNbPages($alias='{nb}') {
1666 //Define an alias for total number of pages
1667 $this->aliasNbPg=$alias;
1668}
1669
1670function AliasNbPageGroups($alias='{nbpg}') {
1671 //Define an alias for total number of pages in a group
1672 $this->aliasNbPgGp=$alias;
1673}
1674
1675function SetAlpha($alpha, $bm='Normal', $return=false, $mode='B') {
1676// alpha: real value from 0 (transparent) to 1 (opaque)
1677// bm: blend mode, one of the following:
1678// Normal, Multiply, Screen, Overlay, Darken, Lighten, ColorDodge, ColorBurn,
1679// HardLight, SoftLight, Difference, Exclusion, Hue, Saturation, Color, Luminosity
1680// set alpha for stroking (CA) and non-stroking (ca) operations
1681// mode determines F (fill) S (stroke) B (both)
1682 if (($this->PDFA || $this->PDFX) && $alpha!=1) {
1683 if (($this->PDFA && !$this->PDFAauto) || ($this->PDFX && !$this->PDFXauto)) { $this->PDFAXwarnings[] = "Image opacity must be 100% (Opacity changed to 100%)"; }
1684 $alpha = 1;
1685 }
1686 $a = array('BM'=>'/'.$bm);
1687 if ($mode=='F' || $mode=='B') $a['ca'] = $alpha; // mPDF 5.7.2
1688 if ($mode=='S' || $mode=='B') $a['CA'] = $alpha; // mPDF 5.7.2
1689 $gs = $this->AddExtGState($a);
1690 if ($return) { return sprintf('/GS%d gs', $gs); }
1691 else { $this->_out(sprintf('/GS%d gs', $gs)); }
1692}
1693
1694function AddExtGState($parms) {
1695 $n = count($this->extgstates);
1696 // check if graphics state already exists
1697 for ($i=1; $i<=$n; $i++) {
1698 if (count($this->extgstates[$i]['parms']) == count($parms)) {
1699 $same = true;
1700 foreach($this->extgstates[$i]['parms'] AS $k=>$v) {
1701 if (!isset($parms[$k]) || $parms[$k] != $v) { $same = false; break; }
1702 }
1703 if ($same) { return $i; }
1704 }
1705 }
1706 $n++;
1707 $this->extgstates[$n]['parms'] = $parms;
1708 return $n;
1709}
1710
1711function SetVisibility($v) {
1712 if (($this->PDFA || $this->PDFX) && $this->visibility!='visible') { $this->PDFAXwarnings[] = "Cannot set visibility to anything other than full when using PDFA or PDFX"; return ''; }
1713 else if (!$this->PDFA && !$this->PDFX)
1714 $this->pdf_version='1.5';
1715 if($this->visibility!='visible') {
1716 $this->_out('EMC');
1717 $this->hasOC=intval($this->hasOC ); // mPDF 5.6.01
1718 }
1719 if($v=='printonly') {
1720 $this->_out('/OC /OC1 BDC');
1721 $this->hasOC=($this->hasOC | 1); // mPDF 5.6.01
1722 }
1723 elseif($v=='screenonly') {
1724 $this->_out('/OC /OC2 BDC');
1725 $this->hasOC=($this->hasOC | 2); // mPDF 5.6.01
1726 }
1727 elseif($v=='hidden') {
1728 $this->_out('/OC /OC3 BDC');
1729 $this->hasOC=($this->hasOC | 4); // mPDF 5.6.01
1730 }
1731 elseif($v!='visible')
1732 $this->Error('Incorrect visibility: '.$v);
1733 $this->visibility=$v;
1734}
1735
1736function Error($msg) {
1737 //Fatal error
1738 header('Content-Type: text/html; charset=utf-8');
1739 die('<B>mPDF error: </B>'.$msg);
1740}
1741
1742function Open() {
1743 //Begin document
1744 if($this->state==0) $this->_begindoc();
1745}
1746
1747function Close() {
1748 if ($this->progressBar) { $this->UpdateProgressBar(2,'2','Closing last page'); } // *PROGRESS-BAR*
1749 //Terminate document
1750 if($this->state==3) return;
1751 if($this->page==0) $this->AddPage($this->CurOrientation);
1752 if (count($this->cellBorderBuffer)) { $this->printcellbuffer(); } // *TABLES*
1753 if ($this->tablebuffer) { $this->printtablebuffer(); } // *TABLES*
1754/*-- COLUMNS --*/
1755
1756 if ($this->ColActive) {
1757 $this->SetColumns(0);
1758 $this->ColActive = 0;
1759 if (count($this->columnbuffer)) { $this->printcolumnbuffer(); }
1760 }
1761/*-- END COLUMNS --*/
1762 if (count($this->divbuffer)) { $this->printdivbuffer(); }
1763
1764 // BODY Backgrounds
1765 $s = '';
1766
1767 $s .= $this->PrintBodyBackgrounds();
1768
1769 $s .= $this->PrintPageBackgrounds();
1770 $this->pages[$this->page] = preg_replace('/(___BACKGROUND___PATTERNS'.$this->uniqstr.')/', "\n".$s."\n".'\\1', $this->pages[$this->page]);
1771 $this->pageBackgrounds = array();
1772
1773 if($this->visibility!='visible')
1774 $this->SetVisibility('visible');
1775 // mPDF 5.6.01 - LAYERS
1776 $this->EndLayer();
1777
1778 if (!$this->tocontents || !$this->tocontents->TOCmark) { //Page footer
1779 $this->InFooter=true;
1780 $this->Footer();
1781 $this->InFooter=false;
1782 }
1783 if ($this->tocontents && ($this->tocontents->TOCmark || count($this->tocontents->m_TOC))) { $this->tocontents->insertTOC(); } // *TOC*
1784
1785 //Close page
1786 $this->_endpage();
1787
1788 //Close document
1789 $this->_enddoc();
1790}
1791
1792/*-- BACKGROUNDS --*/
1793function _resizeBackgroundImage($imw, $imh, $cw, $ch, $resize=0, $repx, $repy, $pba=array(), $size=array()) { // mPDF 5.6.10
1794 // pba is background positioning area (from CSS background-origin) may not always be set [x,y,w,h]
1795 // size is from CSS3 background-size - takes precendence over old resize
1796 // $w - absolute length or % or auto or cover | contain
1797 // $h - absolute length or % or auto or cover | contain
1798 // mPDF 5.6.10
1799 if (isset($pba['w'])) $cw = $pba['w'];
1800 if (isset($pba['h'])) $ch = $pba['h'];
1801
1802 $cw = $cw*_MPDFK;
1803 $ch = $ch*_MPDFK;
1804 if (empty($size) && !$resize) { return array($imw, $imh, $repx, $repy); }
1805
1806 // mPDF 5.6.10
1807 if (isset($size['w']) && $size['w']) {
1808 if ($size['w']=='contain') {
1809 // 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.
1810 // Same as resize==3
1811 $h = $imh * $cw/$imw;
1812 $w = $cw;
1813 if ($h > $ch) {
1814 $w = $w * $ch/$h;
1815 $h = $ch;
1816 }
1817 }
1818 else if ($size['w']=='cover') {
1819 // 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.
1820 $h = $imh * $cw/$imw;
1821 $w = $cw;
1822 if ($h < $ch) {
1823 $w = $w * $h/$ch;
1824 $h = $ch;
1825 }
1826 }
1827 else {
1828 if (stristr($size['w'] ,'%')) {
1829 $size['w'] += 0;
1830 $size['w'] /= 100;
1831 $size['w'] = ($cw * $size['w']);
1832 }
1833 if (stristr($size['h'] ,'%')) {
1834 $size['h'] += 0;
1835 $size['h'] /= 100;
1836 $size['h'] = ($ch * $size['h']);
1837 }
1838 if ($size['w']=='auto' && $size['h']=='auto') {
1839 $w = $imw;
1840 $h = $imh;
1841 }
1842 else if ($size['w']=='auto' && $size['h']!='auto') {
1843 $w = $imw * $size['h']/$imh;
1844 $h = $size['h'];
1845 }
1846 else if ($size['w']!='auto' && $size['h']=='auto') {
1847 $h = $imh * $size['w']/$imw;
1848 $w = $size['w'];
1849 }
1850 else {
1851 $w = $size['w'];
1852 $h = $size['h'];
1853 }
1854 }
1855 return array($w, $h, $repx, $repy);
1856 }
1857 else if ($resize==1 && $imw > $cw) {
1858 $h = $imh * $cw/$imw;
1859 return array($cw, $h, $repx, $repy);
1860 }
1861 else if ($resize==2 && $imh > $ch) {
1862 $w = $imw * $ch/$imh;
1863 return array($w, $ch, $repx, $repy);
1864 }
1865 else if ($resize==3) {
1866 $w = $imw;
1867 $h = $imh;
1868 if ($w > $cw) {
1869 $h = $h * $cw/$w;
1870 $w = $cw;
1871 }
1872 if ($h > $ch) {
1873 $w = $w * $ch/$h;
1874 $h = $ch;
1875 }
1876 return array($w, $h, $repx, $repy);
1877 }
1878 else if ($resize==4) {
1879 $h = $imh * $cw/$imw;
1880 return array($cw, $h, $repx, $repy);
1881 }
1882 else if ($resize==5) {
1883 $w = $imw * $ch/$imh;
1884 return array($w, $ch, $repx, $repy);
1885 }
1886 else if ($resize==6) {
1887 return array($cw, $ch, $repx, $repy);
1888 }
1889 return array($imw, $imh, $repx, $repy);
1890}
1891
1892
1893function SetBackground(&$properties, &$maxwidth) {
1894 // mPDF 5.6.10 5.6.11
1895 if (isset($properties['BACKGROUND-ORIGIN']) && ($properties['BACKGROUND-ORIGIN']=='border-box' || $properties['BACKGROUND-ORIGIN']== 'content-box')) { $origin = $properties['BACKGROUND-ORIGIN']; }
1896 else { $origin = 'padding-box'; }
1897 // mPDF 5.6.10
1898 if (isset($properties['BACKGROUND-SIZE'])) {
1899 if (stristr($properties['BACKGROUND-SIZE'] ,'contain') ) { $bsw = $bsh = 'contain'; }
1900 else if (stristr($properties['BACKGROUND-SIZE'] ,'cover') ) { $bsw = $bsh = 'cover'; }
1901 else {
1902 $bsw = $bsh = 'auto';
1903 $sz = preg_split('/\s+/',trim($properties['BACKGROUND-SIZE']));
1904 if (count($sz)==2) { $bsw = $sz[0]; $bsh = $sz[1]; }
1905 else { $bsw = $sz[0]; }
1906 if (!stristr($bsw ,'%') && !stristr($bsw ,'auto') ) { $bsw = $this->ConvertSize($bsw ,$maxwidth,$this->FontSize); }
1907 if (!stristr($bsh ,'%') && !stristr($bsh ,'auto') ) { $bsh = $this->ConvertSize($bsh ,$maxwidth,$this->FontSize); }
1908 }
1909 $size = array('w'=>$bsw, 'h'=>$bsh);
1910 }
1911 if (preg_match('/(-moz-)*(repeating-)*(linear|radial)-gradient/',$properties['BACKGROUND-IMAGE'])) {
1912 return array('gradient'=>$properties['BACKGROUND-IMAGE'], 'origin'=>$origin, 'size'=>$size ); // mPDF 5.6.10
1913 }
1914 else {
1915 $file = $properties['BACKGROUND-IMAGE'];
1916 $sizesarray = $this->Image($file,0,0,0,0,'','',false, false, false, false, true);
1917 if (isset($sizesarray['IMAGE_ID'])) {
1918 $image_id = $sizesarray['IMAGE_ID'];
1919 $orig_w = $sizesarray['WIDTH']*_MPDFK; // in user units i.e. mm
1920 $orig_h = $sizesarray['HEIGHT']*_MPDFK; // (using $this->img_dpi)
1921 if (isset($properties['BACKGROUND-IMAGE-RESOLUTION'])) {
1922 if (preg_match('/from-image/i', $properties['BACKGROUND-IMAGE-RESOLUTION']) && isset($sizesarray['set-dpi']) && $sizesarray['set-dpi']>0) {
1923 $orig_w *= $this->img_dpi / $sizesarray['set-dpi'];
1924 $orig_h *= $this->img_dpi / $sizesarray['set-dpi'];
1925 }
1926 else if (preg_match('/(\d+)dpi/i', $properties['BACKGROUND-IMAGE-RESOLUTION'], $m)) {
1927 $dpi = $m[1];
1928 if ($dpi > 0) {
1929 $orig_w *= $this->img_dpi / $dpi;
1930 $orig_h *= $this->img_dpi / $dpi;
1931 }
1932 }
1933 }
1934 $x_repeat = true;
1935 $y_repeat = true;
1936 if (isset($properties['BACKGROUND-REPEAT'])) {
1937 if ($properties['BACKGROUND-REPEAT']=='no-repeat' || $properties['BACKGROUND-REPEAT']=='repeat-x') { $y_repeat = false; }
1938 if ($properties['BACKGROUND-REPEAT']=='no-repeat' || $properties['BACKGROUND-REPEAT']=='repeat-y') { $x_repeat = false; }
1939 }
1940 $x_pos = 0;
1941 $y_pos = 0;
1942 if (isset($properties['BACKGROUND-POSITION'])) {
1943 $ppos = preg_split('/\s+/',$properties['BACKGROUND-POSITION']);
1944 $x_pos = $ppos[0];
1945 $y_pos = $ppos[1];
1946 if (!stristr($x_pos ,'%') ) { $x_pos = $this->ConvertSize($x_pos ,$maxwidth,$this->FontSize); }
1947 if (!stristr($y_pos ,'%') ) { $y_pos = $this->ConvertSize($y_pos ,$maxwidth,$this->FontSize); }
1948 }
1949 if (isset($properties['BACKGROUND-IMAGE-RESIZE'])) { $resize = $properties['BACKGROUND-IMAGE-RESIZE']; }
1950 else { $resize = 0; }
1951 if (isset($properties['BACKGROUND-IMAGE-OPACITY'])) { $opacity = $properties['BACKGROUND-IMAGE-OPACITY']; }
1952 else { $opacity = 1; }
1953 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 );
1954 }
1955 }
1956 return false;
1957}
1958/*-- END BACKGROUNDS --*/
1959
1960function PrintBodyBackgrounds() {
1961 $s = '';
1962 $clx = 0;
1963 $cly = 0;
1964 $clw = $this->w;
1965 $clh = $this->h;
1966 // If using bleed and trim margins in paged media
1967 if ($this->pageDim[$this->page]['outer_width_LR'] || $this->pageDim[$this->page]['outer_width_TB']) {
1968 $clx = $this->pageDim[$this->page]['outer_width_LR'] - $this->pageDim[$this->page]['bleedMargin'];
1969 $cly = $this->pageDim[$this->page]['outer_width_TB'] - $this->pageDim[$this->page]['bleedMargin'];
1970 $clw = $this->w - 2*$clx;
1971 $clh = $this->h - 2*$cly;
1972 }
1973
1974 if ($this->bodyBackgroundColor) {
1975 $s .= 'q ' .$this->SetFColor($this->bodyBackgroundColor, true)."\n";
1976 if ($this->bodyBackgroundColor{0}==5) { // RGBa
1977 $s .= $this->SetAlpha(ord($this->bodyBackgroundColor{4})/100, 'Normal', true, 'F')."\n";
1978 }
1979 else if ($this->bodyBackgroundColor{0}==6) { // CMYKa
1980 $s .= $this->SetAlpha(ord($this->bodyBackgroundColor{5})/100, 'Normal', true, 'F')."\n";
1981 }
1982 $s .= sprintf('%.3F %.3F %.3F %.3F re f Q', ($clx*_MPDFK), ($cly*_MPDFK),$clw*_MPDFK,$clh*_MPDFK)."\n";
1983 }
1984
1985/*-- BACKGROUNDS --*/
1986 if ($this->bodyBackgroundGradient) {
1987 $g = $this->grad->parseBackgroundGradient($this->bodyBackgroundGradient);
1988 if ($g) {
1989 $s .= $this->grad->Gradient($clx, $cly, $clw, $clh, (isset($g['gradtype']) ? $g['gradtype'] : null), $g['stops'], $g['colorspace'], $g['coords'], $g['extend'], true);
1990 }
1991 }
1992 if ($this->bodyBackgroundImage) {
1993 if ( $this->bodyBackgroundImage['gradient'] && preg_match('/(-moz-)*(repeating-)*(linear|radial)-gradient/', $this->bodyBackgroundImage['gradient'])) {
1994 $g = $this->grad->parseMozGradient( $this->bodyBackgroundImage['gradient']);
1995 if ($g) {
1996 $s .= $this->grad->Gradient($clx, $cly, $clw, $clh, $g['type'], $g['stops'], $g['colorspace'], $g['coords'], $g['extend'], true);
1997 }
1998 }
1999 else if ($this->bodyBackgroundImage['image_id']) { // Background pattern
2000 $n = count($this->patterns)+1;
2001 // If using resize, uses TrimBox (not including the bleed)
2002 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']);
2003
2004 $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']);
2005 if (($this->bodyBackgroundImage['opacity']>0 || $this->bodyBackgroundImage['opacity']==='0') && $this->bodyBackgroundImage['opacity']<1) { $opac = $this->SetAlpha($this->bodyBackgroundImage['opacity'],'Normal',true); }
2006 else { $opac = ''; }
2007 $s .= sprintf('q /Pattern cs /P%d scn %s %.3F %.3F %.3F %.3F re f Q', $n, $opac, ($clx*_MPDFK), ($cly*_MPDFK),$clw*_MPDFK, $clh*_MPDFK) ."\n";
2008 }
2009 }
2010/*-- END BACKGROUNDS --*/
2011 return $s;
2012}
2013
2014
2015function PrintPageBackgrounds($adjustmenty=0) {
2016 $s = '';
2017
2018 ksort($this->pageBackgrounds);
2019 foreach($this->pageBackgrounds AS $bl=>$pbs) {
2020 foreach ($pbs AS $pb) {
2021 if ((!isset($pb['image_id']) && !isset($pb['gradient'])) || isset($pb['shadowonly'])) { // Background colour or boxshadow
2022 // mPDF 5.6.01 - LAYERS
2023 if($pb['z-index']>0) {
2024 $this->current_layer = $pb['z-index'];
2025 $s .= "\n".'/OCBZ-index /ZI'.$pb['z-index'].' BDC'."\n";
2026 }
2027
2028 if($pb['visibility']!='visible') {
2029 if($pb['visibility']=='printonly')
2030 $s .= '/OC /OC1 BDC'."\n";
2031 else if($pb['visibility']=='screenonly')
2032 $s .= '/OC /OC2 BDC'."\n";
2033 else if($pb['visibility']=='hidden')
2034 $s .= '/OC /OC3 BDC'."\n";
2035 }
2036 // Box shadow
2037 if (isset($pb['shadow']) && $pb['shadow']) { $s .= $pb['shadow']."\n"; }
2038 if (isset($pb['clippath']) && $pb['clippath']) { $s .= $pb['clippath']."\n"; }
2039 $s .= 'q '.$this->SetFColor($pb['col'], true)."\n";
2040 if ($pb['col']{0}==5) { // RGBa
2041 $s .= $this->SetAlpha(ord($pb['col']{4})/100, 'Normal', true, 'F')."\n";
2042 }
2043 else if ($pb['col']{0}==6) { // CMYKa
2044 $s .= $this->SetAlpha(ord($pb['col']{5})/100, 'Normal', true, 'F')."\n";
2045 }
2046 $s .= sprintf('%.3F %.3F %.3F %.3F re f Q',$pb['x']*_MPDFK,($this->h-$pb['y'])*_MPDFK,$pb['w']*_MPDFK,-$pb['h']*_MPDFK)."\n";
2047 if (isset($pb['clippath']) && $pb['clippath']) { $s .= 'Q'."\n"; }
2048 if($pb['visibility']!='visible')
2049 $s .= 'EMC'."\n";
2050
2051 // mPDF 5.6.01 - LAYERS
2052 if($pb['z-index']>0) {
2053 $s .= "\n".'EMCBZ-index'."\n";
2054 $this->current_layer = 0;
2055 }
2056 }
2057 }
2058/*-- BACKGROUNDS --*/
2059 foreach ($pbs AS $pb) {
2060 // mPDF 5.6.01 - LAYERS
2061 if ((isset($pb['gradient']) && $pb['gradient']) || (isset($pb['image_id']) && $pb['image_id'])) {
2062 if($pb['z-index']>0) {
2063 $this->current_layer = $pb['z-index'];
2064 $s .= "\n".'/OCGZ-index /ZI'.$pb['z-index'].' BDC'."\n";
2065 }
2066 if($pb['visibility']!='visible') {
2067 if($pb['visibility']=='printonly')
2068 $s .= '/OC /OC1 BDC'."\n";
2069 else if($pb['visibility']=='screenonly')
2070 $s .= '/OC /OC2 BDC'."\n";
2071 else if($pb['visibility']=='hidden')
2072 $s .= '/OC /OC3 BDC'."\n";
2073 }
2074 }
2075 if (isset($pb['gradient']) && $pb['gradient']) {
2076 if (isset($pb['clippath']) && $pb['clippath']) { $s .= $pb['clippath']."\n"; }
2077 $s .= $this->grad->Gradient($pb['x'], $pb['y'], $pb['w'], $pb['h'], $pb['gradtype'], $pb['stops'], $pb['colorspace'], $pb['coords'], $pb['extend'], true);
2078 if (isset($pb['clippath']) && $pb['clippath']) { $s .= 'Q'."\n"; }
2079 }
2080 else if (isset($pb['image_id']) && $pb['image_id']) { // Background Image
2081 $pb['y'] -= $adjustmenty;
2082 $pb['h'] += $adjustmenty;
2083 $n = count($this->patterns)+1;
2084 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
2085 $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
2086 $x = $pb['x']*_MPDFK;
2087 $y = ($this->h - $pb['y'])*_MPDFK;
2088 $w = $pb['w']*_MPDFK;
2089 $h = -$pb['h']*_MPDFK;
2090 if (isset($pb['clippath']) && $pb['clippath']) { $s .= $pb['clippath']."\n"; }
2091 if ($this->writingHTMLfooter || $this->writingHTMLheader) { // Write each (tiles) image rather than use as a pattern
2092 $iw = $pb['orig_w']/_MPDFK;
2093 $ih = $pb['orig_h']/_MPDFK;
2094
2095 $w = $pb['w'];
2096 $h = $pb['h'];
2097 $x0 = $pb['x'];
2098 $y0 = $pb['y'];
2099
2100 // mPDF 5.6.11
2101 if (isset($pb['bpa']) && $pb['bpa']) {
2102 $w = $pb['bpa']['w'];
2103 $h = $pb['bpa']['h'];
2104 $x0 = $pb['bpa']['x'];
2105 $y0 = $pb['bpa']['y'];
2106 }
2107
2108 // mPDF 5.6.11
2109 if (isset($pb['size']['w']) && $pb['size']['w']) {
2110 $size = $pb['size'];
2111
2112 if ($size['w']=='contain') {
2113 // 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.
2114 // Same as resize==3
2115 $ih = $ih * $pb['bpa']['w']/$iw;
2116 $iw = $pb['bpa']['w'];
2117 if ($ih > $pb['bpa']['h']) {
2118 $iw = $iw * $pb['bpa']['h']/$ih;
2119 $ih = $pb['bpa']['h'];
2120 }
2121 }
2122 else if ($size['w']=='cover') {
2123 // 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.
2124 $ih = $ih * $pb['bpa']['w']/$iw;
2125 $iw = $pb['bpa']['w'];
2126 if ($ih < $pb['bpa']['h']) {
2127 $iw = $iw * $ih/$pb['bpa']['h'];
2128 $ih = $pb['bpa']['h'];
2129 }
2130 }
2131 else {
2132 if (stristr($size['w'] ,'%')) {
2133 $size['w'] += 0;
2134 $size['w'] /= 100;
2135 $size['w'] = ($pb['bpa']['w'] * $size['w']);
2136 }
2137 if (stristr($size['h'] ,'%')) {
2138 $size['h'] += 0;
2139 $size['h'] /= 100;
2140 $size['h'] = ($pb['bpa']['h'] * $size['h']);
2141 }
2142 if ($size['w']=='auto' && $size['h']=='auto') {
2143 $iw = $iw;
2144 $ih = $ih;
2145 }
2146 else if ($size['w']=='auto' && $size['h']!='auto') {
2147 $iw = $iw * $size['h']/$ih;
2148 $ih = $size['h'];
2149 }
2150 else if ($size['w']!='auto' && $size['h']=='auto') {
2151 $ih = $ih * $size['w']/$iw;
2152 $iw = $size['w'];
2153 }
2154 else {
2155 $iw = $size['w'];
2156 $ih = $size['h'];
2157 }
2158 }
2159 }
2160
2161 // Number to repeat
2162 if ($pb['x_repeat']) { $nx = ceil($pb['w']/$iw)+1; } // mPDF 5.6.11
2163 else { $nx = 1; }
2164 if ($pb['y_repeat']) { $ny = ceil($pb['h']/$ih)+1; } // mPDF 5.6.11
2165 else { $ny = 1; }
2166
2167 $x_pos = $pb['x_pos'];
2168 if (stristr($x_pos ,'%') ) {
2169 $x_pos += 0;
2170 $x_pos /= 100;
2171 $x_pos = ($pb['bpa']['w'] * $x_pos) - ($iw * $x_pos); // mPDF 5.6.11
2172 }
2173 $y_pos = $pb['y_pos'];
2174 if (stristr($y_pos ,'%') ) {
2175 $y_pos += 0;
2176 $y_pos /= 100;
2177 $y_pos = ($pb['bpa']['h'] * $y_pos) - ($ih * $y_pos); // mPDF 5.6.11
2178 }
2179 if ($nx>1) {
2180 while($x_pos>($pb['x']-$pb['bpa']['x'])) { $x_pos -= $iw; } // mPDF 5.6.11
2181 }
2182 if ($ny>1) {
2183 while($y_pos>($pb['y']-$pb['bpa']['y'])) { $y_pos -= $ih; } // mPDF 5.6.11
2184 }
2185 for($xi=0;$xi<$nx;$xi++) {
2186 for($yi=0;$yi<$ny;$yi++) {
2187 $x = $x0 + $x_pos + ($iw*$xi);
2188 $y = $y0 + $y_pos + ($ih*$yi);
2189 if ($pb['opacity']>0 && $pb['opacity']<1) { $opac = $this->SetAlpha($pb['opacity'],'Normal',true); }
2190 else { $opac = ''; }
2191 $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";
2192 }
2193 }
2194 }
2195 else {
2196 if (($pb['opacity']>0 || $pb['opacity']==='0') && $pb['opacity']<1) { $opac = $this->SetAlpha($pb['opacity'],'Normal',true); }
2197 else { $opac = ''; }
2198 $s .= sprintf('q /Pattern cs /P%d scn %s %.3F %.3F %.3F %.3F re f Q', $n, $opac, $x, $y, $w, $h) ."\n";
2199 }
2200 if (isset($pb['clippath']) && $pb['clippath']) { $s .= 'Q'."\n"; }
2201 }
2202 if ((isset($pb['gradient']) && $pb['gradient']) || (isset($pb['image_id']) && $pb['image_id'])) {
2203 if($pb['visibility']!='visible')
2204 $s .= 'EMC'."\n";
2205
2206 // mPDF 5.6.01 - LAYERS
2207 if($pb['z-index']>0) {
2208 $s .= "\n".'EMCGZ-index'."\n";
2209 $this->current_layer = 0;
2210 }
2211 }
2212
2213 }
2214/*-- END BACKGROUNDS --*/
2215 }
2216 return $s;
2217}
2218
2219function PrintTableBackgrounds($adjustmenty=0) {
2220 $s = '';
2221/*-- BACKGROUNDS --*/
2222 ksort($this->tableBackgrounds);
2223 foreach($this->tableBackgrounds AS $bl=>$pbs) {
2224 foreach ($pbs AS $pb) {
2225 if ((!isset($pb['gradient']) || !$pb['gradient']) && (!isset($pb['image_id']) || !$pb['image_id'])) {
2226 $s .= 'q '.$this->SetFColor($pb['col'], true)."\n";
2227 if ($pb['col']{0}==5) { // RGBa
2228 $s .= $this->SetAlpha(ord($pb['col']{4})/100, 'Normal', true, 'F')."\n";
2229 }
2230 else if ($pb['col']{0}==6) { // CMYKa
2231 $s .= $this->SetAlpha(ord($pb['col']{5})/100, 'Normal', true, 'F')."\n";
2232 }
2233 $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";
2234 }
2235 if (isset($pb['gradient']) && $pb['gradient']) {
2236 if (isset($pb['clippath']) && $pb['clippath']) { $s .= $pb['clippath']."\n"; }
2237 $s .= $this->grad->Gradient($pb['x'], $pb['y'], $pb['w'], $pb['h'], $pb['gradtype'], $pb['stops'], $pb['colorspace'], $pb['coords'], $pb['extend'], true);
2238 if (isset($pb['clippath']) && $pb['clippath']) { $s .= 'Q'."\n"; }
2239 }
2240 if (isset($pb['image_id']) && $pb['image_id']) { // Background pattern
2241 $pb['y'] -= $adjustmenty;
2242 $pb['h'] += $adjustmenty;
2243 $n = count($this->patterns)+1;
2244 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']);
2245 $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']);
2246 $x = $pb['x']*_MPDFK;
2247 $y = ($this->h - $pb['y'])*_MPDFK;
2248 $w = $pb['w']*_MPDFK;
2249 $h = -$pb['h']*_MPDFK;
2250 if (isset($pb['clippath']) && $pb['clippath']) { $s .= $pb['clippath']."\n"; }
2251 if ($pb['opacity']>0 && $pb['opacity']<1) { $opac = $this->SetAlpha($pb['opacity'],'Normal',true); }
2252 else { $opac = ''; }
2253 $s .= sprintf('q /Pattern cs /P%d scn %s %.3F %.3F %.3F %.3F re f Q', $n, $opac, $x, $y, $w, $h) ."\n";
2254 if (isset($pb['clippath']) && $pb['clippath']) { $s .= 'Q'."\n"; }
2255 }
2256 }
2257 }
2258/*-- END BACKGROUNDS --*/
2259 return $s;
2260}
2261
2262// mPDF 5.6.01 - LAYERS
2263function BeginLayer($id) {
2264 if($this->current_layer>0) $this->EndLayer();
2265 if ($id < 1) { return false; }
2266 if (!isset($this->layers[$id])) {
2267 $this->layers[$id] = array('name'=>'Layer '.($id) );
2268 if (($this->PDFA || $this->PDFX)) { $this->PDFAXwarnings[] = "Cannot use layers when using PDFA or PDFX"; return ''; }
2269 else if (!$this->PDFA && !$this->PDFX) { $this->pdf_version='1.5'; }
2270 }
2271 $this->current_layer = $id;
2272 $this->_out('/OCZ-index /ZI'.$id.' BDC');
2273
2274 $this->pageoutput[$this->page] = array();
2275}
2276
2277function EndLayer() {
2278 if($this->current_layer>0) {
2279 $this->_out('EMCZ-index');
2280 $this->current_layer = 0;
2281 }
2282}
2283
2284
2285
2286// Depracated - can use AddPage for all
2287function 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='')
2288{
2289 $this->AddPage($orientation,$condition,$resetpagenum, $pagenumstyle, $suppress,$mgl,$mgr,$mgt,$mgb,$mgh,$mgf, $ohname, $ehname, $ofname, $efname, $ohvalue, $ehvalue, $ofvalue, $efvalue,$pagesel,$newformat);
2290}
2291
2292
2293function AddPageByArray($a) {
2294 if (!is_array($a)) { $a = array(); }
2295 $orientation = (isset($a['orientation']) ? $a['orientation'] : '');
2296 $condition = (isset($a['condition']) ? $a['condition'] : (isset($a['type']) ? $a['type'] : ''));
2297 $resetpagenum = (isset($a['resetpagenum']) ? $a['resetpagenum'] : '');
2298 $pagenumstyle = (isset($a['pagenumstyle']) ? $a['pagenumstyle'] : '');
2299 $suppress = (isset($a['suppress']) ? $a['suppress'] : '');
2300 $mgl = (isset($a['mgl']) ? $a['mgl'] : (isset($a['margin-left']) ? $a['margin-left'] : ''));
2301 $mgr = (isset($a['mgr']) ? $a['mgr'] : (isset($a['margin-right']) ? $a['margin-right'] : ''));
2302 $mgt = (isset($a['mgt']) ? $a['mgt'] : (isset($a['margin-top']) ? $a['margin-top'] : ''));
2303 $mgb = (isset($a['mgb']) ? $a['mgb'] : (isset($a['margin-bottom']) ? $a['margin-bottom'] : ''));
2304 $mgh = (isset($a['mgh']) ? $a['mgh'] : (isset($a['margin-header']) ? $a['margin-header'] : ''));
2305 $mgf = (isset($a['mgf']) ? $a['mgf'] : (isset($a['margin-footer']) ? $a['margin-footer'] : ''));
2306 $ohname = (isset($a['ohname']) ? $a['ohname'] : (isset($a['odd-header-name']) ? $a['odd-header-name'] : ''));
2307 $ehname = (isset($a['ehname']) ? $a['ehname'] : (isset($a['even-header-name']) ? $a['even-header-name'] : ''));
2308 $ofname = (isset($a['ofname']) ? $a['ofname'] : (isset($a['odd-footer-name']) ? $a['odd-footer-name'] : ''));
2309 $efname = (isset($a['efname']) ? $a['efname'] : (isset($a['even-footer-name']) ? $a['even-footer-name'] : ''));
2310 $ohvalue = (isset($a['ohvalue']) ? $a['ohvalue'] : (isset($a['odd-header-value']) ? $a['odd-header-value'] : 0));
2311 $ehvalue = (isset($a['ehvalue']) ? $a['ehvalue'] : (isset($a['even-header-value']) ? $a['even-header-value'] : 0));
2312 $ofvalue = (isset($a['ofvalue']) ? $a['ofvalue'] : (isset($a['odd-footer-value']) ? $a['odd-footer-value'] : 0));
2313 $efvalue = (isset($a['efvalue']) ? $a['efvalue'] : (isset($a['even-footer-value']) ? $a['even-footer-value'] : 0));
2314 $pagesel = (isset($a['pagesel']) ? $a['pagesel'] : (isset($a['pageselector']) ? $a['pageselector'] : ''));
2315 $newformat = (isset($a['newformat']) ? $a['newformat'] : (isset($a['sheet-size']) ? $a['sheet-size'] : ''));
2316
2317 $this->AddPage($orientation,$condition,$resetpagenum, $pagenumstyle, $suppress,$mgl,$mgr,$mgt,$mgb,$mgh,$mgf, $ohname, $ehname, $ofname, $efname, $ohvalue, $ehvalue, $ofvalue, $efvalue,$pagesel,$newformat);
2318
2319}
2320
2321
2322function 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='')
2323{
2324/*-- CSS-FLOAT --*/
2325 // Float DIV
2326 // Cannot do with columns on, or if any change in page orientation/margins etc.
2327 // If next page already exists - i.e background /headers and footers already written
2328 if ($this->state > 0 && $this->page < count($this->pages)) {
2329 $bak_cml = $this->cMarginL;
2330 $bak_cmr = $this->cMarginR;
2331 $bak_dw = $this->divwidth;
2332 // Paint Div Border if necessary
2333 if ($this->blklvl > 0) {
2334 $save_tr = $this->table_rotate; // *TABLES*
2335 $this->table_rotate = 0; // *TABLES*
2336 if ($this->y == $this->blk[$this->blklvl]['y0']) { $this->blk[$this->blklvl]['startpage']++; }
2337 if (($this->y > $this->blk[$this->blklvl]['y0']) || $this->flowingBlockAttr['is_table'] ) { $toplvl = $this->blklvl; }
2338 else { $toplvl = $this->blklvl-1; }
2339 $sy = $this->y;
2340 for ($bl=1;$bl<=$toplvl;$bl++) {
2341 $this->PaintDivBB('pagebottom',0,$bl);
2342 }
2343 $this->y = $sy;
2344 $this->table_rotate = $save_tr; // *TABLES*
2345 }
2346 $s = $this->PrintPageBackgrounds();
2347
2348 // Writes after the marker so not overwritten later by page background etc.
2349 $this->pages[$this->page] = preg_replace('/(___BACKGROUND___PATTERNS'.$this->uniqstr.')/', '\\1'."\n".$s."\n", $this->pages[$this->page]);
2350 $this->pageBackgrounds = array();
2351 $family=$this->FontFamily;
2352 $style=$this->FontStyle.($this->U ? 'U' : '').($this->S ? 'S' : '');
2353 $size=$this->FontSizePt;
2354 $lw=$this->LineWidth;
2355 $dc=$this->DrawColor;
2356 $fc=$this->FillColor;
2357 $tc=$this->TextColor;
2358 $cf=$this->ColorFlag;
2359
2360 $this->printfloatbuffer();
2361
2362 //Move to next page
2363 $this->page++;
2364 $this->ResetMargins();
2365 $this->SetAutoPageBreak($this->autoPageBreak,$this->bMargin);
2366 $this->x=$this->lMargin;
2367 $this->y=$this->tMargin;
2368 $this->FontFamily='';
2369 $this->_out('2 J');
2370 $this->LineWidth=$lw;
2371 $this->_out(sprintf('%.3F w',$lw*_MPDFK));
2372 if($family) $this->SetFont($family,$style,$size,true,true);
2373 $this->DrawColor=$dc;
2374 if($dc!=$this->defDrawColor) $this->_out($dc);
2375 $this->FillColor=$fc;
2376 if($fc!=$this->defFillColor) $this->_out($fc);
2377 $this->TextColor=$tc;
2378 $this->ColorFlag=$cf;
2379 for($bl=1;$bl<=$this->blklvl;$bl++) {
2380 $this->blk[$bl]['y0'] = $this->y;
2381 // Don't correct more than once for background DIV containing a Float
2382 if (!isset($this->blk[$bl]['marginCorrected'][$this->page])) { $this->blk[$bl]['x0'] += $this->MarginCorrection; }
2383 $this->blk[$bl]['marginCorrected'][$this->page] = true;
2384 }
2385 $this->cMarginL = $bak_cml;
2386 $this->cMarginR = $bak_cmr;
2387 $this->divwidth = $bak_dw;
2388 return '';
2389 }
2390/*-- END CSS-FLOAT --*/
2391
2392 //Start a new page
2393 if($this->state==0) $this->Open();
2394
2395 $bak_cml = $this->cMarginL;
2396 $bak_cmr = $this->cMarginR;
2397 $bak_dw = $this->divwidth;
2398
2399
2400 $bak_lh = $this->lineheight;
2401
2402 $orientation = substr(strtoupper($orientation),0,1);
2403 $condition = strtoupper($condition);
2404
2405
2406 if ($condition == 'NEXT-EVEN') { // always adds at least one new page to create an Even page
2407 if (!$this->mirrorMargins) { $condition = ''; }
2408 else {
2409 if ($pagesel) { $pbch = $pagesel; $pagesel = ''; } // *CSS-PAGE*
2410 else { $pbch = false; } // *CSS-PAGE*
2411 $this->AddPage($this->CurOrientation,'O');
2412 if ($pbch ) { $pagesel = $pbch; } // *CSS-PAGE*
2413 $condition = '';
2414 }
2415 }
2416 if ($condition == 'NEXT-ODD') { // always adds at least one new page to create an Odd page
2417 if (!$this->mirrorMargins) { $condition = ''; }
2418 else {
2419 if ($pagesel) { $pbch = $pagesel; $pagesel = ''; } // *CSS-PAGE*
2420 else { $pbch = false; } // *CSS-PAGE*
2421 $this->AddPage($this->CurOrientation,'E');
2422 if ($pbch ) { $pagesel = $pbch; } // *CSS-PAGE*
2423 $condition = '';
2424 }
2425 }
2426
2427
2428 if ($condition == 'E') { // only adds new page if needed to create an Even page
2429 if (!$this->mirrorMargins || ($this->page)%2==0) { return false; }
2430 }
2431 if ($condition == 'O') { // only adds new page if needed to create an Odd page
2432 if (!$this->mirrorMargins || ($this->page)%2==1) { return false; }
2433 }
2434
2435 if ($resetpagenum || $pagenumstyle || $suppress) {
2436 $this->PageNumSubstitutions[] = array('from'=>($this->page+1), 'reset'=> $resetpagenum, 'type'=>$pagenumstyle, 'suppress'=>$suppress);
2437 }
2438
2439
2440 $save_tr = $this->table_rotate; // *TABLES*
2441 $this->table_rotate = 0; // *TABLES*
2442 $save_kwt = $this->kwt;
2443 $this->kwt = 0;
2444 // mPDF 5.6.01 - LAYERS
2445 $save_layer = $this->current_layer;
2446 $save_vis = $this->visibility;
2447
2448 if($this->visibility!='visible')
2449 $this->SetVisibility('visible');
2450 // mPDF 5.6.01 - LAYERS
2451 $this->EndLayer();
2452
2453 // Paint Div Border if necessary
2454 //PAINTS BACKGROUND COLOUR OR BORDERS for DIV - DISABLED FOR COLUMNS (cf. AcceptPageBreak) AT PRESENT in ->PaintDivBB
2455 if (!$this->ColActive && $this->blklvl > 0) {
2456 if (isset($this->blk[$this->blklvl]['y0']) && $this->y == $this->blk[$this->blklvl]['y0']) {
2457 if (isset($this->blk[$this->blklvl]['startpage'])) { $this->blk[$this->blklvl]['startpage']++; }
2458 else { $this->blk[$this->blklvl]['startpage'] = 1; }
2459 }
2460 if ((isset($this->blk[$this->blklvl]['y0']) && $this->y > $this->blk[$this->blklvl]['y0']) || $this->flowingBlockAttr['is_table'] ) { $toplvl = $this->blklvl; }
2461 else { $toplvl = $this->blklvl-1; }
2462 $sy = $this->y;
2463 for ($bl=1;$bl<=$toplvl;$bl++) {
2464
2465 // mPDF 5.6.01 - LAYERS
2466 if ($this->blk[$bl]['z-index']>0) {
2467 $this->BeginLayer($this->blk[$bl]['z-index']);
2468 }
2469 if (isset($this->blk[$bl]['visibility']) && $this->blk[$bl]['visibility'] && $this->blk[$bl]['visibility']!='visible') {
2470 $this->SetVisibility($this->blk[$bl]['visibility']);
2471 }
2472
2473 $this->PaintDivBB('pagebottom',0,$bl);
2474 }
2475 $this->y = $sy;
2476 // RESET block y0 and x0 - see below
2477 }
2478
2479 if($this->visibility!='visible')
2480 $this->SetVisibility('visible');
2481 // mPDF 5.6.01 - LAYERS
2482 $this->EndLayer();
2483
2484 // BODY Backgrounds
2485 if ($this->page > 0) {
2486 $s = '';
2487 $s .= $this->PrintBodyBackgrounds();
2488
2489 $s .= $this->PrintPageBackgrounds();
2490 $this->pages[$this->page] = preg_replace('/(___BACKGROUND___PATTERNS'.$this->uniqstr.')/', "\n".$s."\n".'\\1', $this->pages[$this->page]);
2491 $this->pageBackgrounds = array();
2492 }
2493
2494 $save_kt = $this->keep_block_together;
2495 $this->keep_block_together = 0;
2496
2497 $save_cols = false;
2498/*-- COLUMNS --*/
2499 if ($this->ColActive) {
2500 $save_cols = true;
2501 $save_nbcol = $this->NbCol; // other values of gap and vAlign will not change by setting Columns off
2502 $this->SetColumns(0);
2503 }
2504/*-- END COLUMNS --*/
2505
2506
2507 $family=$this->FontFamily;
2508 $style=$this->FontStyle.($this->U ? 'U' : '').($this->S ? 'S' : '');
2509 $size=$this->FontSizePt;
2510 $this->ColumnAdjust = true; // enables column height adjustment for the page
2511 $lw=$this->LineWidth;
2512 $dc=$this->DrawColor;
2513 $fc=$this->FillColor;
2514 $tc=$this->TextColor;
2515 $cf=$this->ColorFlag;
2516 if($this->page>0)
2517 {
2518 //Page footer
2519 $this->InFooter=true;
2520
2521 $this->Reset();
2522 $this->pageoutput[$this->page] = array();
2523
2524 $this->Footer();
2525 //Close page
2526 $this->_endpage();
2527 }
2528
2529
2530 //Start new page
2531 $this->_beginpage($orientation,$mgl,$mgr,$mgt,$mgb,$mgh,$mgf,$ohname,$ehname,$ofname,$efname,$ohvalue,$ehvalue,$ofvalue,$efvalue,$pagesel,$newformat);
2532 if ($this->docTemplate) {
2533 $pagecount = $this->SetSourceFile($this->docTemplate);
2534 if (($this->page - $this->docTemplateStart) > $pagecount) {
2535 if ($this->docTemplateContinue) {
2536 $tplIdx = $this->ImportPage($pagecount);
2537 $this->UseTemplate($tplIdx);
2538 }
2539 }
2540 else {
2541 $tplIdx = $this->ImportPage(($this->page - $this->docTemplateStart));
2542 $this->UseTemplate($tplIdx);
2543 }
2544 }
2545 if ($this->pageTemplate) {
2546 $this->UseTemplate($this->pageTemplate);
2547 }
2548
2549 // Tiling Patterns
2550 $this->_out('___PAGE___START'.$this->uniqstr);
2551 $this->_out('___BACKGROUND___PATTERNS'.$this->uniqstr);
2552 $this->_out('___HEADER___MARKER'.$this->uniqstr);
2553 $this->pageBackgrounds = array();
2554
2555 //Set line cap style to square
2556 $this->SetLineCap(2);
2557 //Set line width
2558 $this->LineWidth=$lw;
2559 $this->_out(sprintf('%.3F w',$lw*_MPDFK));
2560 //Set font
2561 if($family) $this->SetFont($family,$style,$size,true,true); // forces write
2562 //Set colors
2563 $this->DrawColor=$dc;
2564 if($dc!=$this->defDrawColor) $this->_out($dc);
2565 $this->FillColor=$fc;
2566 if($fc!=$this->defFillColor) $this->_out($fc);
2567 $this->TextColor=$tc;
2568 $this->ColorFlag=$cf;
2569
2570 //Page header
2571 $this->Header();
2572
2573 //Restore line width
2574 if($this->LineWidth!=$lw)
2575 {
2576 $this->LineWidth=$lw;
2577 $this->_out(sprintf('%.3F w',$lw*_MPDFK));
2578 }
2579 //Restore font
2580 if($family) $this->SetFont($family,$style,$size,true,true); // forces write
2581 //Restore colors
2582 if($this->DrawColor!=$dc)
2583 {
2584 $this->DrawColor=$dc;
2585 $this->_out($dc);
2586 }
2587 if($this->FillColor!=$fc)
2588 {
2589 $this->FillColor=$fc;
2590 $this->_out($fc);
2591 }
2592 $this->TextColor=$tc;
2593 $this->ColorFlag=$cf;
2594 $this->InFooter=false;
2595
2596 // mPDF 5.6.01 - LAYERS
2597 if ($save_layer>0)
2598 $this->BeginLayer($save_layer);
2599
2600 if($save_vis!='visible')
2601 $this->SetVisibility($save_vis);
2602
2603/*-- COLUMNS --*/
2604 if ($save_cols) {
2605 // Restore columns
2606 $this->SetColumns($save_nbcol,$this->colvAlign,$this->ColGap);
2607 }
2608 if ($this->ColActive) { $this->SetCol(0); }
2609/*-- END COLUMNS --*/
2610
2611
2612 //RESET BLOCK BORDER TOP
2613 if (!$this->ColActive) {
2614 for($bl=1;$bl<=$this->blklvl;$bl++) {
2615 $this->blk[$bl]['y0'] = $this->y;
2616 if (isset($this->blk[$bl]['x0'])) { $this->blk[$bl]['x0'] += $this->MarginCorrection; }
2617 else { $this->blk[$bl]['x0'] = $this->MarginCorrection; }
2618 // Added mPDF 3.0 Float DIV
2619 $this->blk[$bl]['marginCorrected'][$this->page] = true;
2620 }
2621 }
2622
2623
2624 $this->table_rotate = $save_tr; // *TABLES*
2625 $this->kwt = $save_kwt;
2626
2627 $this->keep_block_together = $save_kt ;
2628
2629 $this->cMarginL = $bak_cml;
2630 $this->cMarginR = $bak_cmr;
2631 $this->divwidth = $bak_dw;
2632
2633 $this->lineheight = $bak_lh;
2634}
2635
2636
2637function PageNo() {
2638 //Get current page number
2639 return $this->page;
2640}
2641
2642function AddSpotColorsFromFile($file) {
2643 $colors = @file($file) or die("Cannot load spot colors file - ".$file);
2644 foreach($colors AS $sc) {
2645 list($name, $c, $m, $y, $k) = preg_split("/\t/",$sc);
2646 $c = intval($c);
2647 $m = intval($m);
2648 $y = intval($y);
2649 $k = intval($k);
2650 $this->AddSpotColor($name, $c, $m, $y, $k);
2651 }
2652}
2653
2654function AddSpotColor($name, $c, $m, $y, $k) {
2655 $name = strtoupper(trim($name));
2656 if(!isset($this->spotColors[$name])) {
2657 $i=count($this->spotColors)+1;
2658 $this->spotColors[$name]=array('i'=>$i,'c'=>$c,'m'=>$m,'y'=>$y,'k'=>$k);
2659 $this->spotColorIDs[$i]=$name;
2660 }
2661}
2662
2663function SetColor($col, $type='') {
2664 $out = '';
2665 if ($col{0}==3 || $col{0}==5) { // RGB / RGBa
2666 $out = sprintf('%.3F %.3F %.3F rg',ord($col{1})/255,ord($col{2})/255,ord($col{3})/255);
2667 }
2668 else if ($col{0}==1) { // GRAYSCALE
2669 $out = sprintf('%.3F g',ord($col{1})/255);
2670 }
2671 else if ($col{0}==2) { // SPOT COLOR
2672 $out = sprintf('/CS%d cs %.3F scn',ord($col{1}),ord($col{2})/100);
2673 }
2674 else if ($col{0}==4 || $col{0}==6) { // CMYK / CMYKa
2675 $out = sprintf('%.3F %.3F %.3F %.3F k', ord($col{1})/100, ord($col{2})/100, ord($col{3})/100, ord($col{4})/100);
2676 }
2677 if ($type=='Draw') { $out = strtoupper($out); } // e.g. rg => RG
2678 else if ($type=='CodeOnly') { $out = preg_replace('/\s(rg|g|k)/','',$out); }
2679 return $out;
2680}
2681
2682
2683function SetDColor($col, $return=false) {
2684 $out = $this->SetColor($col, 'Draw');
2685 if ($return) { return $out; }
2686 if ($out=='') { return ''; }
2687 $this->DrawColor = $out;
2688 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); }
2689 $this->pageoutput[$this->page]['DrawColor'] = $this->DrawColor;
2690}
2691
2692function SetFColor($col, $return=false) {
2693 $out = $this->SetColor($col, 'Fill');
2694 if ($return) { return $out; }
2695 if ($out=='') { return ''; }
2696 $this->FillColor = $out;
2697 $this->ColorFlag = ($out != $this->TextColor);
2698 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); }
2699 $this->pageoutput[$this->page]['FillColor'] = $this->FillColor;
2700}
2701
2702function SetTColor($col, $return=false) {
2703 $out = $this->SetColor($col, 'Text');
2704 if ($return) { return $out; }
2705 if ($out=='') { return ''; }
2706 $this->TextColor = $out;
2707 $this->ColorFlag = ($this->FillColor != $out);
2708}
2709
2710
2711function SetDrawColor($r,$g=-1,$b=-1,$col4=-1, $return=false) {
2712 //Set color for all stroking operations
2713 $col = array();
2714 if(($r==0 and $g==0 and $b==0 && $col4 == -1) or $g==-1) { $col = $this->ConvertColor($r); }
2715 else if ($col4 == -1) { $col = $this->ConvertColor('rgb('.$r.','.$g.','.$b.')'); }
2716 else { $col = $this->ConvertColor('cmyk('.$r.','.$g.','.$b.','.$col4.')'); }
2717 $out = $this->SetDColor($col, $return);
2718 return $out;
2719}
2720
2721function SetFillColor($r,$g=-1,$b=-1,$col4=-1, $return=false) {
2722 //Set color for all filling operations
2723 $col = array();
2724 if(($r==0 and $g==0 and $b==0 && $col4 == -1) or $g==-1) { $col = $this->ConvertColor($r); }
2725 else if ($col4 == -1) { $col = $this->ConvertColor('rgb('.$r.','.$g.','.$b.')'); }
2726 else { $col = $this->ConvertColor('cmyk('.$r.','.$g.','.$b.','.$col4.')'); }
2727 $out = $this->SetFColor($col, $return);
2728 return $out;
2729}
2730
2731function SetTextColor($r,$g=-1,$b=-1,$col4=-1, $return=false) {
2732 //Set color for text
2733 $col = array();
2734 if(($r==0 and $g==0 and $b==0 && $col4 == -1) or $g==-1) { $col = $this->ConvertColor($r); }
2735 else if ($col4 == -1) { $col = $this->ConvertColor('rgb('.$r.','.$g.','.$b.')'); }
2736 else { $col = $this->ConvertColor('cmyk('.$r.','.$g.','.$b.','.$col4.')'); }
2737 $out = $this->SetTColor($col, $return);
2738 return $out;
2739}
2740
2741function _getCharWidth(&$cw, $u, $isdef=true) {
2742 if ($u==0) { $w = false; }
2743 else { $w = (ord($cw[$u*2]) << 8) + ord($cw[$u*2+1]); }
2744 if ($w == 65535) { return 0; }
2745 else if ($w) { return $w; }
2746 else if ($isdef) { return false; }
2747 else { return 0; }
2748}
2749
2750function _charDefined(&$cw, $u) {
2751 if ($u==0) { return false; }
2752 $w = (ord($cw[$u*2]) << 8) + ord($cw[$u*2+1]);
2753 if ($w) { return true; }
2754 else { return false; }
2755}
2756
2757function GetCharWidthCore($c) {
2758 //Get width of a single character in the current Core font
2759 $c = (string)$c;
2760 $w = 0;
2761 // Soft Hyphens chr(173)
2762 if ($c == chr(173) && $this->FontFamily!='csymbol' && $this->FontFamily!='czapfdingbats') {
2763 return 0;
2764 }
2765 else if ($this->S && isset($this->upperCase[ord($c)])) {
2766 $charw = $this->CurrentFont['cw'][chr($this->upperCase[ord($c)])];
2767 if ($charw!==false) {
2768 $charw = $charw*$this->smCapsScale * $this->smCapsStretch/100;
2769 $w+=$charw;
2770 }
2771 }
2772 else if (isset($this->CurrentFont['cw'][$c])) {
2773 $w += $this->CurrentFont['cw'][$c];
2774 }
2775 else if (isset($this->CurrentFont['cw'][ord($c)])) {
2776 $w += $this->CurrentFont['cw'][ord($c)];
2777 }
2778 $w *= ($this->FontSize/ 1000);
2779 if ($this->minwSpacing || $this->fixedlSpacing) {
2780 if ($c==' ') $nb_spaces = 1;
2781 else $nb_spaces = 0;
2782 $w += $this->fixedlSpacing + ($nb_spaces * $this->minwSpacing);
2783 }
2784 return ($w);
2785}
2786
2787function GetCharWidthNonCore($c, $addSubset=true) {
2788 //Get width of a single character in the current Non-Core font
2789 $c = (string)$c;
2790 $w = 0;
2791 $unicode = $this->UTF8StringToArray($c, $addSubset);
2792 $char = $unicode[0];
2793/*-- CJK-FONTS --*/
2794 if ($this->CurrentFont['type'] == 'Type0') { // CJK Adobe fonts
2795 if ($char == 173) { return 0; } // Soft Hyphens
2796 elseif (isset($this->CurrentFont['cw'][$char])) { $w+=$this->CurrentFont['cw'][$char]; }
2797 elseif(isset($this->CurrentFont['MissingWidth'])) { $w += $this->CurrentFont['MissingWidth']; }
2798 else { $w += 500; }
2799 }
2800 else {
2801/*-- END CJK-FONTS --*/
2802 if ($char == 173) { return 0; } // Soft Hyphens
2803 else if ($this->S && isset($this->upperCase[$char])) {
2804 $charw = $this->_getCharWidth($this->CurrentFont['cw'],$this->upperCase[$char]);
2805 if ($charw!==false) {
2806 $charw = $charw*$this->smCapsScale * $this->smCapsStretch/100;
2807 $w+=$charw;
2808 }
2809 elseif(isset($this->CurrentFont['desc']['MissingWidth'])) { $w += $this->CurrentFont['desc']['MissingWidth']; }
2810 elseif(isset($this->CurrentFont['MissingWidth'])) { $w += $this->CurrentFont['MissingWidth']; }
2811 else { $w += 500; }
2812 }
2813 else {
2814 $charw = $this->_getCharWidth($this->CurrentFont['cw'],$char);
2815 if ($charw!==false) { $w+=$charw; }
2816 elseif(isset($this->CurrentFont['desc']['MissingWidth'])) { $w += $this->CurrentFont['desc']['MissingWidth']; }
2817 elseif(isset($this->CurrentFont['MissingWidth'])) { $w += $this->CurrentFont['MissingWidth']; }
2818 else { $w += 500; }
2819 }
2820 } // *CJK-FONTS*
2821 $w *= ($this->FontSize/ 1000);
2822 if ($this->minwSpacing || $this->fixedlSpacing) {
2823 if ($c==' ') $nb_spaces = 1;
2824 else $nb_spaces = 0;
2825 $w += $this->fixedlSpacing + ($nb_spaces * $this->minwSpacing);
2826 }
2827 return ($w);
2828}
2829
2830
2831function GetCharWidth($c, $addSubset=true) {
2832 if (!$this->usingCoreFont) {
2833 return $this->GetCharWidthNonCore($c, $addSubset);
2834 }
2835 else {
2836 return $this->GetCharWidthCore($c);
2837 }
2838}
2839
2840function GetStringWidth($s, $addSubset=true) {
2841 //Get width of a string in the current font
2842 $s = (string)$s;
2843 $cw = &$this->CurrentFont['cw'];
2844 $w = 0;
2845 $kerning = 0;
2846 $lastchar = 0;
2847 $nb_carac = 0;
2848 $nb_spaces = 0;
2849 // mPDF ITERATION
2850 if ($this->iterationCounter) $s = preg_replace('/{iteration ([a-zA-Z0-9_]+)}/', '\\1', $s);
2851
2852 if (!$this->usingCoreFont) {
2853 $s = str_replace("\xc2\xad",'',$s );
2854 $unicode = $this->UTF8StringToArray($s, $addSubset);
2855 if ($this->minwSpacing || $this->fixedlSpacing) {
2856 $nb_carac = count($unicode);
2857 $nb_spaces = mb_substr_count($s,' ', $this->mb_enc);
2858 }
2859/*-- CJK-FONTS --*/
2860 if ($this->CurrentFont['type'] == 'Type0') { // CJK Adobe fonts
2861 foreach($unicode as $char) {
2862 if (isset($cw[$char])) { $w+=$cw[$char]; }
2863 elseif(isset($this->CurrentFont['MissingWidth'])) { $w += $this->CurrentFont['MissingWidth']; }
2864 else { $w += 500; }
2865 }
2866 }
2867 else {
2868/*-- END CJK-FONTS --*/
2869 foreach($unicode as $char) {
2870 if ($this->S && isset($this->upperCase[$char])) {
2871 $charw = $this->_getCharWidth($cw,$this->upperCase[$char]);
2872 if ($charw!==false) {
2873 $charw = $charw*$this->smCapsScale * $this->smCapsStretch/100;
2874 $w+=$charw;
2875 }
2876 elseif(isset($this->CurrentFont['desc']['MissingWidth'])) { $w += $this->CurrentFont['desc']['MissingWidth']; }
2877 elseif(isset($this->CurrentFont['MissingWidth'])) { $w += $this->CurrentFont['MissingWidth']; }
2878 else { $w += 500; }
2879 }
2880 else {
2881 $charw = $this->_getCharWidth($cw,$char);
2882 if ($charw!==false) { $w+=$charw; }
2883 elseif(isset($this->CurrentFont['desc']['MissingWidth'])) { $w += $this->CurrentFont['desc']['MissingWidth']; }
2884 elseif(isset($this->CurrentFont['MissingWidth'])) { $w += $this->CurrentFont['MissingWidth']; }
2885 else { $w += 500; }
2886 if ($this->kerning && $this->useKerning && $lastchar) {
2887 if (isset($this->CurrentFont['kerninfo'][$lastchar][$char])) {
2888 $kerning += $this->CurrentFont['kerninfo'][$lastchar][$char];
2889 }
2890 }
2891 $lastchar = $char;
2892 }
2893 }
2894 } // *CJK-FONTS*
2895
2896 }
2897 else {
2898 if ($this->FontFamily!='csymbol' && $this->FontFamily!='czapfdingbats') {
2899 $s = str_replace(chr(173),'',$s );
2900 }
2901 $nb_carac = $l = strlen($s);
2902 if ($this->minwSpacing || $this->fixedlSpacing) {
2903 $nb_spaces = substr_count($s,' ');
2904 }
2905 for($i=0; $i<$l; $i++) {
2906 if ($this->S && isset($this->upperCase[ord($s[$i])])) {
2907 $charw = $cw[chr($this->upperCase[ord($s[$i])])];
2908 if ($charw!==false) {
2909 $charw = $charw*$this->smCapsScale * $this->smCapsStretch/100;
2910 $w+=$charw;
2911 }
2912 }
2913 else if (isset($cw[$s[$i]])) {
2914 $w += $cw[$s[$i]];
2915 }
2916 else if (isset($cw[ord($s[$i])])) {
2917 $w += $cw[ord($s[$i])];
2918 }
2919 if ($this->kerning && $this->useKerning && $i>0) {
2920 if (isset($this->CurrentFont['kerninfo'][$s[($i-1)]][$s[$i]])) {
2921 $kerning += $this->CurrentFont['kerninfo'][$s[($i-1)]][$s[$i]];
2922 }
2923 }
2924 }
2925 }
2926 unset($cw);
2927 if ($this->kerning && $this->useKerning) { $w += $kerning; }
2928 $w *= ($this->FontSize/ 1000);
2929 $w += (($nb_carac + $nb_spaces) * $this->fixedlSpacing) + ($nb_spaces * $this->minwSpacing);
2930 return ($w);
2931}
2932
2933function SetLineWidth($width) {
2934 //Set line width
2935 $this->LineWidth=$width;
2936 $lwout = (sprintf('%.3F w',$width*_MPDFK));
2937 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)) {
2938 $this->_out($lwout);
2939 }
2940 $this->pageoutput[$this->page]['LineWidth'] = $lwout;
2941}
2942
2943function Line($x1,$y1,$x2,$y2) {
2944 //Draw a line
2945 $this->_out(sprintf('%.3F %.3F m %.3F %.3F l S',$x1*_MPDFK,($this->h-$y1)*_MPDFK,$x2*_MPDFK,($this->h-$y2)*_MPDFK));
2946}
2947
2948function Arrow($x1,$y1,$x2,$y2,$headsize=3,$fill='B',$angle=25) {
2949 //F == fill //S == stroke //B == stroke and fill
2950 // angle = splay of arrowhead - 1 - 89 degrees
2951 if($fill=='F') $fill='f';
2952 elseif($fill=='FD' or $fill=='DF' or $fill=='B') $fill='B';
2953 else $fill='S';
2954 $a = atan2(($y2-$y1),($x2-$x1));
2955 $b = $a + deg2rad($angle);
2956 $c = $a - deg2rad($angle);
2957 $x3 = $x2 - ($headsize* cos($b));
2958 $y3 = $this->h-($y2 - ($headsize* sin($b)));
2959 $x4 = $x2 - ($headsize* cos($c));
2960 $y4 = $this->h-($y2 - ($headsize* sin($c)));
2961
2962 $x5 = $x3-($x3-$x4)/2; // mid point of base of arrowhead - to join arrow line to
2963 $y5 = $y3-($y3-$y4)/2;
2964
2965 $s = '';
2966 $s.=sprintf('%.3F %.3F m %.3F %.3F l S',$x1*_MPDFK,($this->h-$y1)*_MPDFK,$x5*_MPDFK,$y5*_MPDFK);
2967 $this->_out($s);
2968
2969 $s = '';
2970 $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);
2971 $s.=$fill;
2972 $this->_out($s);
2973}
2974
2975
2976function Rect($x,$y,$w,$h,$style='') {
2977 //Draw a rectangle
2978 if($style=='F') $op='f';
2979 elseif($style=='FD' or $style=='DF') $op='B';
2980 else $op='S';
2981 $this->_out(sprintf('%.3F %.3F %.3F %.3F re %s',$x*_MPDFK,($this->h-$y)*_MPDFK,$w*_MPDFK,-$h*_MPDFK,$op));
2982}
2983
2984function AddFont($family,$style='') {
2985 if(empty($family)) { return; }
2986 $family = strtolower($family);
2987 $style=strtoupper($style);
2988 $style=str_replace('U','',$style);
2989 if($style=='IB') $style='BI';
2990 $fontkey = $family.$style;
2991 // check if the font has been already added
2992 if(isset($this->fonts[$fontkey])) {
2993 return;
2994 }
2995
2996/*-- CJK-FONTS --*/
2997 if (in_array($family,$this->available_CJK_fonts)) {
2998 if (empty($this->Big5_widths)) { require(_MPDF_PATH . 'includes/CJKdata.php'); }
2999 $this->AddCJKFont($family); // don't need to add style
3000 return;
3001 }
3002/*-- END CJK-FONTS --*/
3003
3004 if ($this->usingCoreFont) { die("mPDF Error - problem with Font management"); }
3005
3006 $stylekey = $style;
3007 if (!$style) { $stylekey = 'R'; }
3008
3009 if (!isset($this->fontdata[$family][$stylekey]) || !$this->fontdata[$family][$stylekey]) {
3010 die('mPDF Error - Font is not supported - '.$family.' '.$style);
3011 }
3012
3013 $name = '';
3014 $originalsize = 0;
3015 $sip = false;
3016 $smp = false;
3017 $unAGlyphs = false; // mPDF 5.4.05
3018 $haskerninfo = false;
3019 $BMPselected = false;
3020 @include(_MPDF_TTFONTDATAPATH.$fontkey.'.mtx.php');
3021
3022 $ttffile = '';
3023 if (defined('_MPDF_SYSTEM_TTFONTS')) {
3024 $ttffile = _MPDF_SYSTEM_TTFONTS.$this->fontdata[$family][$stylekey];
3025 if (!file_exists($ttffile)) { $ttffile = ''; }
3026 }
3027 if (!$ttffile) {
3028 $ttffile = _MPDF_TTFONTPATH.$this->fontdata[$family][$stylekey];
3029 if (!file_exists($ttffile)) { die("mPDF Error - cannot find TTF TrueType font file - ".$ttffile); }
3030 }
3031 $ttfstat = stat($ttffile);
3032
3033 if (isset($this->fontdata[$family]['TTCfontID'][$stylekey])) { $TTCfontID = $this->fontdata[$family]['TTCfontID'][$stylekey]; }
3034 else { $TTCfontID = 0; }
3035
3036
3037 $BMPonly = false;
3038 if (in_array($family,$this->BMPonly)) { $BMPonly = true; }
3039 $regenerate = false;
3040 if ($BMPonly && !$BMPselected) { $regenerate = true; }
3041 else if (!$BMPonly && $BMPselected) { $regenerate = true; }
3042 if ($this->useKerning && !$haskerninfo) { $regenerate = true; }
3043 // mPDF 5.4.05
3044 if (isset($this->fontdata[$family]['unAGlyphs']) && $this->fontdata[$family]['unAGlyphs'] && !$unAGlyphs) {
3045 $regenerate = true;
3046 $unAGlyphs = true;
3047 }
3048 else if ((!isset($this->fontdata[$family]['unAGlyphs']) || !$this->fontdata[$family]['unAGlyphs']) && $unAGlyphs) {
3049 $regenerate = true;
3050 $unAGlyphs = false;
3051 }
3052 if (!isset($name) || $originalsize != $ttfstat['size'] || $regenerate) {
3053 if (!class_exists('TTFontFile', false)) { include(_MPDF_PATH .'classes/ttfontsuni.php'); }
3054 $ttf = new TTFontFile();
3055 $ttf->getMetrics($ttffile, $TTCfontID, $this->debugfonts, $BMPonly, $this->useKerning, $unAGlyphs); // mPDF 5.4.05
3056 $cw = $ttf->charWidths;
3057 $kerninfo = $ttf->kerninfo;
3058 $haskerninfo = true;
3059 $name = preg_replace('/[ ()]/','',$ttf->fullName);
3060 $sip = $ttf->sipset;
3061 $smp = $ttf->smpset;
3062
3063 $desc= array('Ascent'=>round($ttf->ascent),
3064 'Descent'=>round($ttf->descent),
3065 'CapHeight'=>round($ttf->capHeight),
3066 'Flags'=>$ttf->flags,
3067 'FontBBox'=>'['.round($ttf->bbox[0])." ".round($ttf->bbox[1])." ".round($ttf->bbox[2])." ".round($ttf->bbox[3]).']',
3068 'ItalicAngle'=>$ttf->italicAngle,
3069 'StemV'=>round($ttf->stemV),
3070 'MissingWidth'=>round($ttf->defaultWidth));
3071 $panose = '';
3072 // mPDF 5.5.19
3073 if (count($ttf->panose)) {
3074 $panoseArray = array_merge(array($ttf->sFamilyClass, $ttf->sFamilySubClass), $ttf->panose);
3075 foreach($panoseArray as $value)
3076 $panose .= ' '.dechex($value);
3077 }
3078 $up = round($ttf->underlinePosition);
3079 $ut = round($ttf->underlineThickness);
3080 $originalsize = $ttfstat['size']+0;
3081 $type = 'TTF';
3082 //Generate metrics .php file
3083 $s='<?php'."\n";
3084 $s.='$name=\''.$name."';\n";
3085 $s.='$type=\''.$type."';\n";
3086 $s.='$desc='.var_export($desc,true).";\n";
3087 $s.='$up='.$up.";\n";
3088 $s.='$ut='.$ut.";\n";
3089 $s.='$ttffile=\''.$ttffile."';\n";
3090 $s.='$TTCfontID=\''.$TTCfontID."';\n";
3091 $s.='$originalsize='.$originalsize.";\n";
3092 if ($sip) $s.='$sip=true;'."\n";
3093 else $s.='$sip=false;'."\n";
3094 if ($smp) $s.='$smp=true;'."\n";
3095 else $s.='$smp=false;'."\n";
3096 if ($BMPonly) $s.='$BMPselected=true;'."\n";
3097 else $s.='$BMPselected=false;'."\n";
3098 $s.='$fontkey=\''.$fontkey."';\n";
3099 $s.='$panose=\''.$panose."';\n";
3100 if ($this->useKerning) {
3101 $s.='$kerninfo='.var_export($kerninfo,true).";\n";
3102 $s.='$haskerninfo=true;'."\n";
3103 }
3104 else $s.='$haskerninfo=false;'."\n";
3105 // mPDF 5.4.05
3106 if ($this->fontdata[$family]['unAGlyphs']) {
3107 $s.='$unAGlyphs=true;'."\n";
3108 }
3109 else $s.='$unAGlyphs=false;'."\n";
3110 $s.="?>";
3111 if (is_writable(dirname(_MPDF_TTFONTDATAPATH.'x'))) {
3112 $fh = fopen(_MPDF_TTFONTDATAPATH.$fontkey.'.mtx.php',"w");
3113 fwrite($fh,$s,strlen($s));
3114 fclose($fh);
3115 $fh = fopen(_MPDF_TTFONTDATAPATH.$fontkey.'.cw.dat',"wb");
3116 fwrite($fh,$cw,strlen($cw));
3117 fclose($fh);
3118 @unlink(_MPDF_TTFONTDATAPATH.$fontkey.'.cgm');
3119 @unlink(_MPDF_TTFONTDATAPATH.$fontkey.'.z');
3120 @unlink(_MPDF_TTFONTDATAPATH.$fontkey.'.cw127.php');
3121 @unlink(_MPDF_TTFONTDATAPATH.$fontkey.'.cw');
3122 }
3123 else if ($this->debugfonts) { $this->Error('Cannot write to the font caching directory - '._MPDF_TTFONTDATAPATH); }
3124 unset($ttf);
3125 }
3126 else {
3127 $cw = @file_get_contents(_MPDF_TTFONTDATAPATH.$fontkey.'.cw.dat');
3128 }
3129
3130 if (isset($this->fontdata[$family]['indic']) && $this->fontdata[$family]['indic']) { $indic = true; }
3131 else { $indic = false; }
3132 if (isset($this->fontdata[$family]['sip-ext']) && $this->fontdata[$family]['sip-ext']) { $sipext = $this->fontdata[$family]['sip-ext']; }
3133 else { $sipext = ''; }
3134
3135
3136 $i = count($this->fonts)+$this->extraFontSubsets+1;
3137 if ($sip || $smp) {
3138 $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
3139 }
3140 else {
3141 $ss = array();
3142 for ($s=32; $s<128; $s++) { $ss[$s] = $s; }
3143 $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
3144 }
3145 if ($this->useKerning && $haskerninfo) { $this->fonts[$fontkey]['kerninfo'] = $kerninfo; }
3146 $this->FontFiles[$fontkey]=array('length1'=>$originalsize, 'type'=>"TTF", 'ttffile'=>$ttffile, 'sip'=>$sip, 'smp'=>$smp);
3147 unset($cw);
3148}
3149
3150
3151
3152function SetFont($family,$style='',$size=0, $write=true, $forcewrite=false) {
3153 $family=strtolower($family);
3154 if (!$this->onlyCoreFonts) {
3155 if ($family == 'sans' || $family == 'sans-serif') { $family = $this->sans_fonts[0]; }
3156 if ($family == 'serif') { $family = $this->serif_fonts[0]; }
3157 if ($family == 'mono' || $family == 'monospace') { $family = $this->mono_fonts[0]; }
3158 }
3159 if (isset($this->fonttrans[$family]) && $this->fonttrans[$family]) { $family = $this->fonttrans[$family]; }
3160 if($family=='') {
3161 if ($this->FontFamily) { $family=$this->FontFamily; }
3162 else if ($this->default_font) { $family=$this->default_font; }
3163 else { $this->Error("No font or default font set!"); }
3164 }
3165 $this->ReqFontStyle = $style; // required or requested style - used later for artificial bold/italic
3166
3167 if (($family == 'csymbol') || ($family == 'czapfdingbats') || ($family == 'ctimes') || ($family == 'ccourier') || ($family == 'chelvetica')) {
3168 if ($this->PDFA || $this->PDFX) {
3169 if ($family == 'csymbol' || $family == 'czapfdingbats') {
3170 $this->Error("Symbol and Zapfdingbats cannot be embedded in mPDF (required for PDFA1-b or PDFX/1-a).");
3171 }
3172 if ($family == 'ctimes' || $family == 'ccourier' || $family == 'chelvetica') {
3173 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.)"; }
3174 if ($family == 'chelvetica') { $family = 'sans'; }
3175 if ($family == 'ctimes') { $family = 'serif'; }
3176 if ($family == 'ccourier') { $family = 'mono'; }
3177 }
3178 $this->usingCoreFont = false;
3179 }
3180 else { $this->usingCoreFont = true; }
3181 if($family=='csymbol' || $family=='czapfdingbats') { $style=''; }
3182 }
3183 else { $this->usingCoreFont = false; }
3184
3185 $this->U=false;
3186 $this->S=false;
3187 if ($style) {
3188 $style=strtoupper($style);
3189 if(strpos($style,'U')!==false) {
3190 $this->U=true;
3191 $style=str_replace('U','',$style);
3192 }
3193 if(strpos($style,'S')!==false) {
3194 $this->S=true;
3195 // Small Caps
3196 if (empty($this->upperCase)) { @include(_MPDF_PATH.'includes/upperCase.php'); }
3197 $style=str_replace('S','',$style);
3198 }
3199 if ($style=='IB') $style='BI';
3200 }
3201 if ($size==0) $size=$this->FontSizePt;
3202
3203 $fontkey=$family.$style;
3204
3205 $stylekey = $style;
3206 if (!$stylekey) { $stylekey = "R"; }
3207
3208 if (!$this->onlyCoreFonts && !$this->usingCoreFont) {
3209 if(!isset($this->fonts[$fontkey]) || count($this->default_available_fonts) != count($this->available_unifonts) ) { // not already added
3210/*-- CJK-FONTS --*/
3211 // CJK fonts
3212 if (in_array($fontkey,$this->available_CJK_fonts)) {
3213 if(!isset($this->fonts[$fontkey])) { // already added
3214 if (empty($this->Big5_widths)) { require(_MPDF_PATH . 'includes/CJKdata.php'); }
3215 $this->AddCJKFont($family); // don't need to add style
3216 }
3217 }
3218 // Test to see if requested font/style is available - or substitute
3219 else
3220/*-- END CJK-FONTS --*/
3221 if (!in_array($fontkey,$this->available_unifonts)) {
3222 // If font[nostyle] exists - set it
3223 if (in_array($family,$this->available_unifonts)) {
3224 $style = '';
3225 }
3226
3227 // Else if only one font available - set it (assumes if only one font available it will not have a style)
3228 else if (count($this->available_unifonts) == 1) {
3229 $family = $this->available_unifonts[0];
3230 $style = '';
3231 }
3232
3233 else {
3234 $found = 0;
3235 // else substitute font of similar type
3236 if (in_array($family,$this->sans_fonts)) {
3237 $i = array_intersect($this->sans_fonts,$this->available_unifonts);
3238 if (count($i)) {
3239 $i = array_values($i);
3240 // with requested style if possible
3241 if (!in_array(($i[0].$style),$this->available_unifonts)) {
3242 $style = '';
3243 }
3244 $family = $i[0];
3245 $found = 1;
3246 }
3247 }
3248 else if (in_array($family,$this->serif_fonts)) {
3249 $i = array_intersect($this->serif_fonts,$this->available_unifonts);
3250 if (count($i)) {
3251 $i = array_values($i);
3252 // with requested style if possible
3253 if (!in_array(($i[0].$style),$this->available_unifonts)) {
3254 $style = '';
3255 }
3256 $family = $i[0];
3257 $found = 1;
3258 }
3259 }
3260 else if (in_array($family,$this->mono_fonts)) {
3261 $i = array_intersect($this->mono_fonts,$this->available_unifonts);
3262 if (count($i)) {
3263 $i = array_values($i);
3264 // with requested style if possible
3265 if (!in_array(($i[0].$style),$this->available_unifonts)) {
3266 $style = '';
3267 }
3268 $family = $i[0];
3269 $found = 1;
3270 }
3271 }
3272
3273 if (!$found) {
3274 // set first available font
3275 $fs = $this->available_unifonts[0];
3276 preg_match('/^([a-z_0-9\-]+)([BI]{0,2})$/',$fs,$fas); // Allow "-"
3277 // with requested style if possible
3278 $ws = $fas[1].$style;
3279 if (in_array($ws,$this->available_unifonts)) {
3280 $family = $fas[1]; // leave $style as is
3281 }
3282 else if (in_array($fas[1],$this->available_unifonts)) {
3283 // or without style
3284 $family = $fas[1];
3285 $style = '';
3286 }
3287 else {
3288 // or with the style specified
3289 $family = $fas[1];
3290 $style = $fas[2];
3291 }
3292 }
3293 }
3294 $fontkey = $family.$style;
3295 }
3296 }
3297 // try to add font (if not already added)
3298 $this->AddFont($family, $style);
3299
3300 //Test if font is already selected
3301 if($this->FontFamily == $family && $this->FontFamily == $this->currentfontfamily && $this->FontStyle == $style && $this->FontStyle == $this->currentfontstyle && $this->FontSizePt == $size && $this->FontSizePt == $this->currentfontsize && !$forcewrite) {
3302 return $family;
3303 }
3304
3305 $fontkey = $family.$style;
3306
3307 //Select it
3308 $this->FontFamily = $family;
3309 $this->FontStyle = $style;
3310 $this->FontSizePt = $size;
3311 $this->FontSize = $size / _MPDFK;
3312 $this->CurrentFont = &$this->fonts[$fontkey];
3313 if ($write) {
3314 $fontout = (sprintf('BT /F%d %.3F Tf ET', $this->CurrentFont['i'], $this->FontSizePt));
3315 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); }
3316 $this->pageoutput[$this->page]['Font'] = $fontout;
3317 }
3318
3319
3320
3321 // Added - currentfont (lowercase) used in HTML2PDF
3322 $this->currentfontfamily=$family;
3323 $this->currentfontsize=$size;
3324 $this->currentfontstyle=$style.($this->U ? 'U' : '').($this->S ? 'S' : '');
3325 $this->setMBencoding('UTF-8');
3326 }
3327
3328 else { // if using core fonts
3329
3330
3331 if ($this->PDFA || $this->PDFX) {
3332 $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.');
3333 }
3334 $this->setMBencoding('windows-1252');
3335
3336 //Test if font is already selected
3337 if(($this->FontFamily == $family) AND ($this->FontStyle == $style) AND ($this->FontSizePt == $size) && !$forcewrite) {
3338 return $family;
3339 }
3340
3341 if (!isset($this->CoreFonts[$fontkey])) {
3342 if (in_array($family,$this->serif_fonts)) { $family = 'ctimes'; }
3343 else if (in_array($family,$this->mono_fonts)) { $family = 'ccourier'; }
3344 else { $family = 'chelvetica'; }
3345 $this->usingCoreFont = true;
3346 $fontkey = $family.$style;
3347 }
3348
3349 if(!isset($this->fonts[$fontkey])) {
3350 // STANDARD CORE FONTS
3351 if (isset($this->CoreFonts[$fontkey])) {
3352 //Load metric file
3353 $file=$family;
3354 if($family=='ctimes' || $family=='chelvetica' || $family=='ccourier') { $file.=strtolower($style); }
3355 $file.='.php';
3356 include(_MPDF_PATH.'font/'.$file);
3357 if(!isset($cw)) { $this->Error('Could not include font metric file'); }
3358 $i=count($this->fonts)+$this->extraFontSubsets+1;
3359 $this->fonts[$fontkey]=array('i'=>$i,'type'=>'core','name'=>$this->CoreFonts[$fontkey],'desc'=>$desc,'up'=>$up,'ut'=>$ut,'cw'=>$cw);
3360 if ($this->useKerning) { $this->fonts[$fontkey]['kerninfo'] = $kerninfo; }
3361 }
3362 else {
3363 die('mPDF error - Font not defined');
3364 }
3365 }
3366 //Test if font is already selected
3367 if(($this->FontFamily == $family) AND ($this->FontStyle == $style) AND ($this->FontSizePt == $size) && !$forcewrite) {
3368 return $family;
3369 }
3370 //Select it
3371 $this->FontFamily=$family;
3372 $this->FontStyle=$style;
3373 $this->FontSizePt=$size;
3374 $this->FontSize=$size/_MPDFK;
3375 $this->CurrentFont=&$this->fonts[$fontkey];
3376 if ($write) {
3377 $fontout = (sprintf('BT /F%d %.3F Tf ET', $this->CurrentFont['i'], $this->FontSizePt));
3378 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); }
3379 $this->pageoutput[$this->page]['Font'] = $fontout;
3380 }
3381 // Added - currentfont (lowercase) used in HTML2PDF
3382 $this->currentfontfamily=$family;
3383 $this->currentfontsize=$size;
3384 $this->currentfontstyle=$style.($this->U ? 'U' : '').($this->S ? 'S' : '');
3385
3386 }
3387
3388 return $family;
3389}
3390
3391function SetFontSize($size,$write=true) {
3392 //Set font size in points
3393 if($this->FontSizePt==$size) return;
3394 $this->FontSizePt=$size;
3395 $this->FontSize=$size/_MPDFK;
3396 $this->currentfontsize=$size;
3397 if ($write) {
3398 $fontout = (sprintf('BT /F%d %.3F Tf ET', $this->CurrentFont['i'], $this->FontSizePt));
3399 // Edited mPDF 3.0
3400 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); }
3401 $this->pageoutput[$this->page]['Font'] = $fontout;
3402 }
3403}
3404
3405function AddLink() {
3406 //Create a new internal link
3407 $n=count($this->links)+1;
3408 $this->links[$n]=array(0,0);
3409 return $n;
3410}
3411
3412function SetLink($link,$y=0,$page=-1) {
3413 //Set destination of internal link
3414 if($y==-1) $y=$this->y;
3415 if($page==-1) $page=$this->page;
3416 $this->links[$link]=array($page,$y);
3417}
3418
3419function Link($x,$y,$w,$h,$link) {
3420 $l = array($x*_MPDFK,$this->hPt-$y*_MPDFK,$w*_MPDFK,$h*_MPDFK,$link);
3421 if ($this->keep_block_together) { // Save to array - don't write yet
3422 $this->ktLinks[$this->page][]= $l;
3423 return;
3424 }
3425 else if ($this->table_rotate) { // *TABLES*
3426 $this->tbrot_Links[$this->page][]= $l; // *TABLES*
3427 return; // *TABLES*
3428 } // *TABLES*
3429 else if ($this->kwt) {
3430 $this->kwt_Links[$this->page][]= $l;
3431 return;
3432 }
3433
3434 if ($this->writingHTMLheader || $this->writingHTMLfooter) {
3435 $this->HTMLheaderPageLinks[]= $l;
3436 return;
3437 }
3438 //Put a link on the page
3439 $this->PageLinks[$this->page][]= $l;
3440 // Save cross-reference to Column buffer
3441 $ref = count($this->PageLinks[$this->page])-1; // *COLUMNS*
3442 $this->columnLinks[$this->CurrCol][INTVAL($this->x)][INTVAL($this->y)] = $ref; // *COLUMNS*
3443
3444}
3445
3446function Text($x,$y,$txt) {
3447 // Output a string
3448 // Called (internally) by Watermark and _tableWrite [rotated cells]
3449 // Expects input to be mb_encoded if necessary and RTL reversed
3450
3451 // ARTIFICIAL BOLD AND ITALIC
3452 $s = 'q ';
3453 if ($this->falseBoldWeight && strpos($this->ReqFontStyle,"B") !== false && strpos($this->FontStyle,"B") === false) {
3454 $s .= '2 Tr 1 J 1 j ';
3455 $s .= sprintf('%.3F w ',($this->FontSize/130)*_MPDFK*$this->falseBoldWeight);
3456 $tc = strtoupper($this->TextColor); // change 0 0 0 rg to 0 0 0 RG
3457 if($this->FillColor!=$tc) { $s .= $tc.' '; } // stroke (outline) = same colour as text(fill)
3458 }
3459 if (strpos($this->ReqFontStyle,"I") !== false && strpos($this->FontStyle,"I") === false) {
3460 $aix = '1 0 0.261799 1 %.3F %.3F Tm';
3461 }
3462 else { $aix = '%.3F %.3F Td'; }
3463
3464 if($this->ColorFlag) $s.=$this->TextColor.' ';
3465
3466 $this->CurrentFont['used']= true;
3467 if ($this->CurrentFont['type']=='TTF' && ($this->CurrentFont['sip'] || $this->CurrentFont['smp'])) {
3468 $txt2 = str_replace(chr(194).chr(160),chr(32),$txt);
3469 $txt2 = $this->UTF8toSubset($txt2);
3470 $s.=sprintf('BT '.$aix.' %s Tj ET ',$x*_MPDFK,($this->h-$y)*_MPDFK,$txt2);
3471 }
3472 else if (!$this->usingCoreFont) {
3473 $txt2 = str_replace(chr(194).chr(160),chr(32),$txt);
3474 $this->UTF8StringToArray($txt2); // this is just to add chars to subset list
3475 if ($this->kerning && $this->useKerning) { $s .= $this->_kern($txt2, '', $aix, $x, $y); }
3476 else {
3477 //Convert string to UTF-16BE without BOM
3478 $txt2= $this->UTF8ToUTF16BE($txt2, false);
3479 $s.=sprintf('BT '.$aix.' (%s) Tj ET ',$x*_MPDFK,($this->h-$y)*_MPDFK,$this->_escape($txt2));
3480 }
3481 }
3482 else {
3483 $txt2 = str_replace(chr(160),chr(32),$txt);
3484 if ($this->kerning && $this->useKerning) { $s .= $this->_kern($txt2, '', $aix, $x, $y); }
3485 else {
3486 $s.=sprintf('BT '.$aix.' (%s) Tj ET ',$x*_MPDFK,($this->h-$y)*_MPDFK,$this->_escape($txt2));
3487 }
3488 }
3489 if($this->U && $txt!='') {
3490 $c = strtoupper($this->TextColor); // change 0 0 0 rg to 0 0 0 RG
3491 if($this->FillColor!=$c) { $s.= ' '.$c.' '; }
3492 if (isset($this->CurrentFont['up'])) { $up=$this->CurrentFont['up']; }
3493 else { $up = -100; }
3494 $adjusty = (-$up/1000* $this->FontSize);
3495 if (isset($this->CurrentFont['ut'])) { $ut=$this->CurrentFont['ut']/1000* $this->FontSize; }
3496 else { $ut = 60/1000* $this->FontSize; }
3497 $olw = $this->LineWidth;
3498 $s.=' '.(sprintf(' %.3F w',$ut*_MPDFK));
3499 $s.=' '.$this->_dounderline($x,$y + $adjusty,$txt);
3500 $s.=' '.(sprintf(' %.3F w',$olw*_MPDFK));
3501 if($this->FillColor!=$c) { $s.= ' '.$this->FillColor.' '; }
3502 }
3503 // STRIKETHROUGH
3504 if($this->strike && $txt!='') {
3505 $c = strtoupper($this->TextColor); // change 0 0 0 rg to 0 0 0 RG
3506 if($this->FillColor!=$c) { $s.= ' '.$c.' '; }
3507 //Superscript and Subscript Y coordinate adjustment (now for striked-through texts)
3508 if (isset($this->CurrentFont['desc']['CapHeight'])) { $ch=$this->CurrentFont['desc']['CapHeight']; }
3509 else { $ch = 700; }
3510 $adjusty = (-$ch/1000* $this->FontSize) * 0.35;
3511 if (isset($this->CurrentFont['ut'])) { $ut=$this->CurrentFont['ut']/1000* $this->FontSize; }
3512 else { $ut = 60/1000* $this->FontSize; }
3513 $olw = $this->LineWidth;
3514 $s.=' '.(sprintf(' %.3F w',$ut*_MPDFK));
3515 $s.=' '.$this->_dounderline($x,$y+$adjusty,$txt);
3516 $s.=' '.(sprintf(' %.3F w',$olw*_MPDFK));
3517 if($this->FillColor!=$c) { $s.= ' '.$this->FillColor.' '; }
3518 }
3519 $s .= 'Q';
3520 $this->_out($s);
3521}
3522
3523/*-- DIRECTW --*/
3524function WriteText($x,$y,$txt) {
3525 // Output a string using Text() but does encoding and text reversing of RTL
3526 $txt = $this->purify_utf8_text($txt);
3527 if ($this->text_input_as_HTML) {
3528 $txt = $this->all_entities_to_utf8($txt);
3529 }
3530 if ($this->usingCoreFont) { $txt = mb_convert_encoding($txt,$this->mb_enc,'UTF-8'); }
3531 // DIRECTIONALITY
3532 if (preg_match("/([".$this->pregRTLchars."])/u", $txt)) { $this->biDirectional = true; } // *RTL*
3533 $this->magic_reverse_dir($txt, true, $this->directionality); // *RTL*
3534 // Font-specific ligature substitution for Indic fonts
3535 if (isset($this->CurrentFont['indic']) && $this->CurrentFont['indic']) $this->ConvertIndic($txt); // *INDIC*
3536 $this->Text($x,$y,$txt);
3537}
3538
3539function WriteCell($w,$h=0,$txt='',$border=0,$ln=0,$align='',$fill=0,$link='', $currentx=0) {
3540 //Output a cell using Cell() but does encoding and text reversing of RTL
3541 $txt = $this->purify_utf8_text($txt);
3542 if ($this->text_input_as_HTML) {
3543 $txt = $this->all_entities_to_utf8($txt);
3544 }
3545 if ($this->usingCoreFont) { $txt = mb_convert_encoding($txt,$this->mb_enc,'UTF-8'); }
3546 // DIRECTIONALITY
3547 if (preg_match("/([".$this->pregRTLchars."])/u", $txt)) { $this->biDirectional = true; } // *RTL*
3548 $this->magic_reverse_dir($txt, true, $this->directionality); // *RTL*
3549 // Font-specific ligature substitution for Indic fonts
3550 if (isset($this->CurrentFont['indic']) && $this->CurrentFont['indic']) $this->ConvertIndic($txt); // *INDIC*
3551 $this->Cell($w,$h,$txt,$border,$ln,$align,$fill,$link, $currentx);
3552}
3553/*-- END DIRECTW --*/
3554
3555
3556function ResetSpacing() {
3557 if ($this->ws != 0) { $this->_out('BT 0 Tw ET'); }
3558 $this->ws=0;
3559 if ($this->charspacing != 0) { $this->_out('BT 0 Tc ET'); }
3560 $this->charspacing=0;
3561}
3562
3563
3564function SetSpacing($cs,$ws) {
3565 if (intval($cs*1000)==0) { $cs = 0; }
3566 if ($cs) { $this->_out(sprintf('BT %.3F Tc ET',$cs)); }
3567 else if ($this->charspacing != 0) { $this->_out('BT 0 Tc ET'); }
3568 $this->charspacing=$cs;
3569 if (intval($ws*1000)==0) { $ws = 0; }
3570 if ($ws) { $this->_out(sprintf('BT %.3F Tw ET',$ws)); }
3571 else if ($this->ws != 0) { $this->_out('BT 0 Tw ET'); }
3572 $this->ws=$ws;
3573}
3574
3575// WORD SPACING
3576function GetJspacing($nc,$ns,$w,$inclCursive) {
3577 $ws = 0;
3578 $charspacing = 0;
3579 $ww = $this->jSWord;
3580 $ncx = $nc-1;
3581 if ($nc == 0) { return array(0,0); }
3582 else if ($nc==1) { $charspacing = $w; }
3583 // Only word spacing allowed / possible
3584 else if ($this->fixedlSpacing !== false || $inclCursive) {
3585 if ($ns) { $ws = $w / $ns; }
3586 }
3587 else if (!$ns) {
3588 $charspacing = $w / ($ncx );
3589 if (($this->jSmaxChar > 0) && ($charspacing > $this->jSmaxChar)) {
3590 $charspacing = $this->jSmaxChar;
3591 }
3592 }
3593 else if ($ns == ($ncx )) {
3594 $charspacing = $w / $ns;
3595 }
3596 else {
3597 if ($this->usingCoreFont) {
3598 $cs = ($w * (1 - $this->jSWord)) / ($ncx );
3599 if (($this->jSmaxChar > 0) && ($cs > $this->jSmaxChar)) {
3600 $cs = $this->jSmaxChar;
3601 $ww = 1 - (($cs * ($ncx ))/$w);
3602 }
3603 $charspacing = $cs;
3604 $ws = ($w * ($ww) ) / $ns;
3605 }
3606 else {
3607 $cs = ($w * (1 - $this->jSWord)) / ($ncx -$ns);
3608 if (($this->jSmaxChar > 0) && ($cs > $this->jSmaxChar)) {
3609 $cs = $this->jSmaxChar;
3610 $ww = 1 - (($cs * ($ncx -$ns))/$w);
3611 }
3612 $charspacing = $cs;
3613 $ws = (($w * ($ww) ) / $ns) - $charspacing;
3614 }
3615 }
3616 return array($charspacing,$ws);
3617}
3618
3619function 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) {
3620 //Output a cell
3621 // Expects input to be mb_encoded if necessary and RTL reversed
3622 // NON_BREAKING SPACE
3623 if ($this->usingCoreFont) {
3624 $txt = str_replace(chr(160),chr(32),$txt);
3625 }
3626 else {
3627 $txt = str_replace(chr(194).chr(160),chr(32),$txt);
3628 }
3629
3630 $oldcolumn = $this->CurrCol;
3631 // Automatic page break
3632 // Allows PAGE-BREAK-AFTER = avoid to work
3633 if (!$this->tableLevel && (($this->y+$this->divheight>$this->PageBreakTrigger) || ($this->y+$h>$this->PageBreakTrigger) ||
3634 ($this->y+($h*2)+$this->blk[$this->blklvl]['padding_bottom']+$this->blk[$this->blklvl]['margin_bottom']>$this->PageBreakTrigger && $this->blk[$this->blklvl]['page_break_after_avoid'])) and !$this->InFooter and $this->AcceptPageBreak()) { // mPDF 5.7.2
3635 $x=$this->x;//Current X position
3636
3637
3638 // WORD SPACING
3639 $ws=$this->ws;//Word Spacing
3640 $charspacing=$this->charspacing;//Character Spacing
3641 $this->ResetSpacing();
3642
3643 $this->AddPage($this->CurOrientation);
3644 // Added to correct for OddEven Margins
3645 $x += $this->MarginCorrection;
3646 if ($currentx) {
3647 $currentx += $this->MarginCorrection;
3648 }
3649 $this->x=$x;
3650 // WORD SPACING
3651 $this->SetSpacing($charspacing,$ws);
3652 }
3653
3654 // Test: to put line through centre of cell: $this->Line($this->x,$this->y+($h/2),$this->x+50,$this->y+($h/2));
3655
3656/*-- COLUMNS --*/
3657 // COLS
3658 // COLUMN CHANGE
3659 if ($this->CurrCol != $oldcolumn) {
3660 if ($currentx) {
3661 $currentx += $this->ChangeColumn * ($this->ColWidth+$this->ColGap);
3662 }
3663 $this->x += $this->ChangeColumn * ($this->ColWidth+$this->ColGap);
3664 }
3665
3666 // COLUMNS Update/overwrite the lowest bottom of printing y value for a column
3667 if ($this->ColActive) {
3668 if ($h) { $this->ColDetails[$this->CurrCol]['bottom_margin'] = $this->y+$h; }
3669 else { $this->ColDetails[$this->CurrCol]['bottom_margin'] = $this->y+$this->divheight; }
3670 }
3671/*-- END COLUMNS --*/
3672
3673 // KEEP BLOCK TOGETHER Update/overwrite the lowest bottom of printing y value on first page
3674 if ($this->keep_block_together) {
3675 if ($h) { $this->ktBlock[$this->page]['bottom_margin'] = $this->y+$h; }
3676// else { $this->ktBlock[$this->page]['bottom_margin'] = $this->y+$this->divheight; }
3677 }
3678
3679 if($w==0) $w = $this->w-$this->rMargin-$this->x;
3680 $s='';
3681 if($fill==1 && $this->FillColor) {
3682 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.' '; }
3683 $this->pageoutput[$this->page]['FillColor'] = $this->FillColor;
3684 }
3685
3686
3687 $boxtop = $this->y;
3688 $boxheight = $h;
3689 $boxbottom = $this->y+$h;
3690
3691 if($txt!='') {
3692 // FONT SIZE - this determines the baseline caculation
3693 if ($this->linemaxfontsize && !$this->processingHeader) { $bfs = $this->linemaxfontsize; }
3694 else { $bfs = $this->FontSize; }
3695 //Calculate baseline Superscript and Subscript Y coordinate adjustment
3696 $bfx = $this->baselineC;
3697 $baseline = $bfx*$bfs;
3698 if($this->SUP) { $baseline += ($bfx-1.05)*$this->FontSize; }
3699 else if($this->SUB) { $baseline += ($bfx + 0.04)*$this->FontSize; }
3700 else if($this->bullet) { $baseline += ($bfx-0.7)*$this->FontSize; }
3701
3702 // Vertical align (for Images)
3703 if ($abovefont || $belowfont) { // from flowing block - valign always M
3704 $va = $abovefont + (0.5*$bfs);
3705 }
3706 else if ($this->lineheight_correction) {
3707 if ($valign == 'T') { $va = (0.5 * $bfs * $this->lineheight_correction); }
3708 else if ($valign == 'B') { $va = $h-(0.5 * $bfs * $this->lineheight_correction); }
3709 else { $va = 0.5*$h; } // Middle
3710 }
3711 else {
3712 if ($valign == 'T') { $va = (0.5 * $bfs * $this->default_lineheight_correction); }
3713 else if ($valign == 'B') { $va = $h-(0.5 * $bfs * $this->default_lineheight_correction); }
3714 else { $va = 0.5*$h; } // Middle
3715 }
3716
3717 // ONLY SET THESE IF WANT TO CONFINE BORDER +/- FILL TO FIT FONTSIZE - NOT FULL CELL AS IS ORIGINAL FUNCTION
3718 // spanfill or spanborder are set in FlowingBlock functions
3719 if ($spanfill || !empty($this->spanborddet) || $link!='') {
3720 $exth = 0.2; // Add to fontsize to increase height of background / link / border
3721 $boxtop = $this->y+$baseline+$va-($this->FontSize*(1+$exth/2)*(0.5+$bfx));
3722 $boxheight = $this->FontSize * (1+$exth);
3723 $boxbottom = $boxtop + $boxheight;
3724 }
3725 }
3726
3727 $bbw = $tbw = $lbw = $rbw = 0; // Border widths
3728 if (!empty($this->spanborddet)) {
3729 if (!isset($this->spanborddet['B'])) { $this->spanborddet['B'] = array('s' => 0, 'style' => '', 'w' => 0); }
3730 if (!isset($this->spanborddet['T'])) { $this->spanborddet['T'] = array('s' => 0, 'style' => '', 'w' => 0); }
3731 if (!isset($this->spanborddet['L'])) { $this->spanborddet['L'] = array('s' => 0, 'style' => '', 'w' => 0); }
3732 if (!isset($this->spanborddet['R'])) { $this->spanborddet['R'] = array('s' => 0, 'style' => '', 'w' => 0); }
3733 $bbw = $this->spanborddet['B']['w'];
3734 $tbw = $this->spanborddet['T']['w'];
3735 $lbw = $this->spanborddet['L']['w'];
3736 $rbw = $this->spanborddet['R']['w'];
3737 }
3738 if($fill==1 || $border==1 || !empty($this->spanborddet)) {
3739 if (!empty($this->spanborddet)) {
3740 if ($fill==1) {
3741 $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);
3742 }
3743 $s.= ' q ';
3744 $dashon = 3;
3745 $dashoff = 3.5;
3746 $dot = 2.5;
3747 if($tbw) {
3748 $short = 0;
3749 if ($this->spanborddet['T']['style'] == 'dashed') {
3750 $s.=sprintf(' 0 j 0 J [%.3F %.3F] 0 d ',$tbw*$dashon*_MPDFK,$tbw*$dashoff*_MPDFK);
3751 }
3752 else if ($this->spanborddet['T']['style'] == 'dotted') {
3753 $s.=sprintf(' 1 j 1 J [%.3F %.3F] %.3F d ',0.001,$tbw*$dot*_MPDFK,-$tbw/2*_MPDFK);
3754 $short = $tbw/2;
3755 }
3756 else {
3757 $s.=' 0 j 0 J [] 0 d ';
3758 }
3759 $c = $this->SetDColor($this->spanborddet['T']['c'],true);
3760 if ($this->spanborddet['T']['style'] == 'double') {
3761 $s.=sprintf(' %s %.3F w ',$c,$tbw/3*_MPDFK);
3762 $xadj = $xadj2 = 0;
3763 if ($this->spanborddet['L']['style'] == 'double') { $xadj = $this->spanborddet['L']['w']*2/3; }
3764 if ($this->spanborddet['R']['style'] == 'double') { $xadj2 = $this->spanborddet['R']['w']*2/3; }
3765 $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);
3766 $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);
3767 }
3768 else {
3769 $s.=sprintf(' %s %.3F w ',$c,$tbw*_MPDFK);
3770 $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);
3771 }
3772 }
3773 if($bbw) {
3774 $short = 0;
3775 if ($this->spanborddet['B']['style'] == 'dashed') {
3776 $s.=sprintf(' 0 j 0 J [%.3F %.3F] 0 d ',$bbw*$dashon*_MPDFK,$bbw*$dashoff*_MPDFK);
3777 }
3778 else if ($this->spanborddet['B']['style'] == 'dotted') {
3779 $s.=sprintf(' 1 j 1 J [%.3F %.3F] %.3F d ',0.001,$bbw*$dot*_MPDFK,-$bbw/2*_MPDFK);
3780 $short = $bbw/2;
3781 }
3782 else {
3783 $s.=' 0 j 0 J [] 0 d ';
3784 }
3785 $c = $this->SetDColor($this->spanborddet['B']['c'],true);
3786 if ($this->spanborddet['B']['style'] == 'double') {
3787 $s.=sprintf(' %s %.3F w ',$c,$bbw/3*_MPDFK);
3788 $xadj = $xadj2 = 0;
3789 if ($this->spanborddet['L']['style'] == 'double') { $xadj = $this->spanborddet['L']['w']*2/3; }
3790 if ($this->spanborddet['R']['style'] == 'double') { $xadj2 = $this->spanborddet['R']['w']*2/3; }
3791 $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);
3792 $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);
3793 }
3794 else {
3795 $s.=sprintf(' %s %.3F w ',$c,$bbw*_MPDFK);
3796 $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);
3797 }
3798 }
3799 if($lbw) {
3800 $short = 0;
3801 if ($this->spanborddet['L']['style'] == 'dashed') {
3802 $s.=sprintf(' 0 j 0 J [%.3F %.3F] 0 d ',$lbw*$dashon*_MPDFK,$lbw*$dashoff*_MPDFK);
3803 }
3804 else if ($this->spanborddet['L']['style'] == 'dotted') {
3805 $s.=sprintf(' 1 j 1 J [%.3F %.3F] %.3F d ',0.001,$lbw*$dot*_MPDFK,-$lbw/2*_MPDFK);
3806 $short = $lbw/2;
3807 }
3808 else {
3809 $s.=' 0 j 0 J [] 0 d ';
3810 }
3811 $c = $this->SetDColor($this->spanborddet['L']['c'],true);
3812 if ($this->spanborddet['L']['style'] == 'double') {
3813 $s.=sprintf(' %s %.3F w ',$c,$lbw/3*_MPDFK);
3814 $yadj = $yadj2 = 0;
3815 if ($this->spanborddet['T']['style'] == 'double') { $yadj = $this->spanborddet['T']['w']*2/3; }
3816 if ($this->spanborddet['B']['style'] == 'double') { $yadj2 = $this->spanborddet['B']['w']*2/3; }
3817 $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);
3818 $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);
3819 }
3820 else {
3821 $s.=sprintf(' %s %.3F w ',$c,$lbw*_MPDFK);
3822 $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);
3823 }
3824 }
3825 if($rbw) {
3826 $short = 0;
3827 if ($this->spanborddet['R']['style'] == 'dashed') {
3828 $s.=sprintf(' 0 j 0 J [%.3F %.3F] 0 d ',$rbw*$dashon*_MPDFK,$rbw*$dashoff*_MPDFK);
3829 }
3830 else if ($this->spanborddet['R']['style'] == 'dotted') {
3831 $s.=sprintf(' 1 j 1 J [%.3F %.3F] %.3F d ',0.001,$rbw*$dot*_MPDFK,-$rbw/2*_MPDFK);
3832 $short = $rbw/2;
3833 }
3834 else {
3835 $s.=' 0 j 0 J [] 0 d ';
3836 }
3837 $c = $this->SetDColor($this->spanborddet['R']['c'],true);
3838 if ($this->spanborddet['R']['style'] == 'double') {
3839 $s.=sprintf(' %s %.3F w ',$c,$rbw/3*_MPDFK);
3840 $yadj = $yadj2 = 0;
3841 if ($this->spanborddet['T']['style'] == 'double') { $yadj = $this->spanborddet['T']['w']*2/3; }
3842 if ($this->spanborddet['B']['style'] == 'double') { $yadj2 = $this->spanborddet['B']['w']*2/3; }
3843 $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);
3844 $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);
3845 }
3846 else {
3847 $s.=sprintf(' %s %.3F w ',$c,$rbw*_MPDFK);
3848 $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);
3849 }
3850 }
3851 $s.= ' Q ';
3852 }
3853 else {
3854 if ($fill==1) $op=($border==1) ? 'B' : 'f';
3855 else $op='S';
3856 $s.=sprintf('%.3F %.3F %.3F %.3F re %s ',$this->x*_MPDFK,($this->h-$boxtop)*_MPDFK,$w*_MPDFK,-$boxheight*_MPDFK,$op);
3857 }
3858 }
3859
3860 if(is_string($border)) {
3861 $x=$this->x;
3862 $y=$this->y;
3863 if(is_int(strpos($border,'L')))
3864 $s.=sprintf('%.3F %.3F m %.3F %.3F l S ',$x*_MPDFK,($this->h-$boxtop)*_MPDFK,$x*_MPDFK,($this->h-($boxbottom))*_MPDFK);
3865 if(is_int(strpos($border,'T')))
3866 $s.=sprintf('%.3F %.3F m %.3F %.3F l S ',$x*_MPDFK,($this->h-$boxtop)*_MPDFK,($x+$w)*_MPDFK,($this->h-$boxtop)*_MPDFK);
3867 if(is_int(strpos($border,'R')))
3868 $s.=sprintf('%.3F %.3F m %.3F %.3F l S ',($x+$w)*_MPDFK,($this->h-$boxtop)*_MPDFK,($x+$w)*_MPDFK,($this->h-($boxbottom))*_MPDFK);
3869 if(is_int(strpos($border,'B')))
3870 $s.=sprintf('%.3F %.3F m %.3F %.3F l S ',$x*_MPDFK,($this->h-($boxbottom))*_MPDFK,($x+$w)*_MPDFK,($this->h-($boxbottom))*_MPDFK);
3871 }
3872
3873 if($txt!='') {
3874 if ($exactWidth)
3875 $stringWidth = $w;
3876 else
3877 $stringWidth = $this->GetStringWidth($txt) + ( $this->charspacing * mb_strlen( $txt, $this->mb_enc ) / _MPDFK )
3878 + ( $this->ws * mb_substr_count( $txt, ' ', $this->mb_enc ) / _MPDFK );
3879
3880 // Set x OFFSET FOR PRINTING
3881 if($align=='R') {
3882 $dx=$w-$this->cMarginR - $stringWidth - $lcpaddingR;
3883 }
3884 elseif($align=='C') {
3885 $dx=(($w - $stringWidth )/2);
3886 }
3887 elseif($align=='L' or $align=='J') $dx=$this->cMarginL + $lcpaddingL;
3888 else $dx = 0;
3889
3890 if($this->ColorFlag) $s .='q '.$this->TextColor.' ';
3891
3892 // OUTLINE
3893 if($this->textparam['outline-s'] && !$this->S) { // mPDF 5.6.07
3894 $s .=' '.sprintf('%.3F w',$this->LineWidth*_MPDFK).' ';
3895 $s .=" $this->DrawColor ";
3896 $s .=" 2 Tr ";
3897 }
3898 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
3899 $s .= ' 2 Tr 1 J 1 j ';
3900 $s .= ' '.sprintf('%.3F w',($this->FontSize/130)*_MPDFK*$this->falseBoldWeight).' ';
3901 $tc = strtoupper($this->TextColor); // change 0 0 0 rg to 0 0 0 RG
3902 if($this->FillColor!=$tc) { $s .= ' '.$tc.' '; } // stroke (outline) = same colour as text(fill)
3903 }
3904 else { $s .=" 0 Tr "; } // mPDF 5.6.07
3905
3906 if (strpos($this->ReqFontStyle,"I") !== false && strpos($this->FontStyle,"I") === false) { // Artificial italic
3907 $aix = '1 0 0.261799 1 %.3F %.3F Tm ';
3908 }
3909 else { $aix = '%.3F %.3F Td '; }
3910
3911 // THE TEXT
3912 $sub = '';
3913 $this->CurrentFont['used']= true;
3914
3915 // WORD SPACING
3916 // IF multibyte - Tw has no effect - need to use alternative method - do word spacing using an adjustment before each space
3917 if ($this->ws && !$this->usingCoreFont && !$this->CurrentFont['sip'] && !$this->CurrentFont['smp'] && !$this->S) {
3918 $sub .= ' BT 0 Tw ET ';
3919 if ($this->kerning && $this->useKerning) { $sub .= $this->_kern($txt, 'MBTw', $aix, ($this->x+$dx), ($this->y+$baseline+$va)); }
3920 else {
3921 $space = " ";
3922 //Convert string to UTF-16BE without BOM
3923 $space= $this->UTF8ToUTF16BE($space , false);
3924 $space=$this->_escape($space );
3925 $sub .=sprintf('BT '.$aix,($this->x+$dx)*_MPDFK,($this->h-($this->y+$baseline+$va))*_MPDFK);
3926 $t = explode(' ',$txt);
3927 $sub .=sprintf(' %.3F Tc [',$this->charspacing);
3928 $numt = count($t);
3929 for($i=0;$i<$numt;$i++) {
3930 $tx = $t[$i];
3931 //Convert string to UTF-16BE without BOM
3932 $tx = $this->UTF8ToUTF16BE($tx , false);
3933 $tx = $this->_escape($tx);
3934 $sub .=sprintf('(%s) ',$tx);
3935 if (($i+1)<$numt) {
3936 $adj = -($this->ws)*1000/$this->FontSizePt;
3937 $sub .=sprintf('%d(%s) ',$adj,$space);
3938 }
3939 }
3940 $sub .='] TJ ';
3941 $sub .=' ET';
3942 }
3943 }
3944 else {
3945 $txt2= $txt;
3946 if ($this->CurrentFont['type']=='TTF' && ($this->CurrentFont['sip'] || $this->CurrentFont['smp'])) {
3947 if ($this->S) { $sub .= $this->_smallCaps($txt2, 'SIPSMP', $aix, $dx, _MPDFK, $baseline, $va); }
3948 else {
3949 $txt2 = $this->UTF8toSubset($txt2);
3950 $sub .=sprintf('BT '.$aix.' %s Tj ET',($this->x+$dx)*_MPDFK,($this->h-($this->y+$baseline+$va))*_MPDFK,$txt2);
3951 }
3952 }
3953 else {
3954 if ($this->S) { $sub .= $this->_smallCaps($txt2, '', $aix, $dx, _MPDFK, $baseline, $va); }
3955 else if ($this->kerning && $this->useKerning) { $sub .= $this->_kern($txt2, '', $aix, ($this->x+$dx), ($this->y+$baseline+$va)); }
3956 else {
3957 if (!$this->usingCoreFont) {
3958 $txt2 = $this->UTF8ToUTF16BE($txt2, false);
3959 }
3960 $txt2=$this->_escape($txt2);
3961 $sub .=sprintf('BT '.$aix.' (%s) Tj ET',($this->x+$dx)*_MPDFK,($this->h-($this->y+$baseline+$va))*_MPDFK,$txt2);
3962 }
3963 }
3964 }
3965 // UNDERLINE
3966 if($this->U) {
3967 $c = strtoupper($this->TextColor); // change 0 0 0 rg to 0 0 0 RG
3968 if($this->FillColor!=$c) { $sub .= ' '.$c.' '; }
3969 if (isset($this->CurrentFont['up'])) { $up=$this->CurrentFont['up']; }
3970 else { $up = -100; }
3971 $adjusty = (-$up/1000* $this->FontSize);
3972 if (isset($this->CurrentFont['ut'])) { $ut=$this->CurrentFont['ut']/1000* $this->FontSize; }
3973 else { $ut = 60/1000* $this->FontSize; }
3974 $olw = $this->LineWidth;
3975 $sub .=' '.(sprintf(' %.3F w 0 j 0 J ',$ut*_MPDFK));
3976 $sub .=' '.$this->_dounderline($this->x+$dx,$this->y+$baseline+$va+$adjusty,$txt);
3977 $sub .=' '.(sprintf(' %.3F w 2 j 2 J ',$olw*_MPDFK));
3978 if($this->FillColor!=$c) { $sub .= ' '.$this->FillColor.' '; }
3979 }
3980
3981 // STRIKETHROUGH
3982 if($this->strike) {
3983 $c = strtoupper($this->TextColor); // change 0 0 0 rg to 0 0 0 RG
3984 if($this->FillColor!=$c) { $sub .= ' '.$c.' '; }
3985 //Superscript and Subscript Y coordinate adjustment (now for striked-through texts)
3986 if (isset($this->CurrentFont['desc']['CapHeight'])) { $ch=$this->CurrentFont['desc']['CapHeight']; }
3987 else { $ch = 700; }
3988 $adjusty = (-$ch/1000* $this->FontSize) * 0.35;
3989 if (isset($this->CurrentFont['ut'])) { $ut=$this->CurrentFont['ut']/1000* $this->FontSize; }
3990 else { $ut = 60/1000* $this->FontSize; }
3991 $olw = $this->LineWidth;
3992 $sub .=' '.(sprintf(' %.3F w 0 j 0 J ',$ut*_MPDFK));
3993 $sub .=' '.$this->_dounderline($this->x+$dx,$this->y+$baseline+$va+$adjusty,$txt);
3994 $sub .=' '.(sprintf(' %.3F w 2 j 2 J ',$olw*_MPDFK));
3995 if($this->FillColor!=$c) { $sub .= ' '.$this->FillColor.' '; }
3996 }
3997
3998 // TEXT SHADOW
3999 if ($this->textshadow) { // First to process is last in CSS comma separated shadows
4000 foreach($this->textshadow AS $ts) {
4001 $s .= ' q ';
4002 $s .= $this->SetTColor($ts['col'], true)."\n";
4003 if ($ts['col']{0}==5 && ord($ts['col']{4})<100) { // RGBa
4004 $s .= $this->SetAlpha(ord($ts['col']{4})/100, 'Normal', true, 'F')."\n";
4005 }
4006 else if ($ts['col']{0}==6 && ord($ts['col']{5})<100) { // CMYKa
4007 $s .= $this->SetAlpha(ord($ts['col']{5})/100, 'Normal', true, 'F')."\n";
4008 }
4009 else if ($ts['col']{0}==1 && $ts['col']{2}==1 && ord($ts['col']{3})<100) { // Gray
4010 $s .= $this->SetAlpha(ord($ts['col']{3})/100, 'Normal', true, 'F')."\n";
4011 }
4012 $s .= sprintf(' 1 0 0 1 %.4F %.4F cm', $ts['x']*_MPDFK, -$ts['y']*_MPDFK)."\n";
4013 $s .= $sub;
4014 $s .= ' Q ';
4015 }
4016 }
4017
4018 $s .= $sub;
4019
4020 // COLOR
4021 if($this->ColorFlag) $s .=' Q';
4022
4023 // LINK
4024 if($link!='') {
4025 $this->Link($this->x,$boxtop,$w,$boxheight,$link);
4026 }
4027 }
4028 if($s) $this->_out($s);
4029
4030 // WORD SPACING
4031 if ($this->ws && !$this->usingCoreFont) {
4032 $this->_out(sprintf('BT %.3F Tc ET',$this->charspacing));
4033 }
4034 $this->lasth=$h;
4035 if( strpos($txt,"\n") !== false) $ln=1; // cell recognizes \n from <BR> tag
4036 if($ln>0)
4037 {
4038 //Go to next line
4039 $this->y += $h;
4040 if($ln==1) {
4041 //Move to next line
4042 if ($currentx != 0) { $this->x=$currentx; }
4043 else { $this->x=$this->lMargin; }
4044 }
4045 }
4046 else $this->x+=$w;
4047
4048
4049}
4050
4051
4052function _kern($txt, $mode, $aix, $x, $y) {
4053 if ($mode == 'MBTw') { // Multibyte requiring word spacing
4054 $space = ' ';
4055 //Convert string to UTF-16BE without BOM
4056 $space= $this->UTF8ToUTF16BE($space , false);
4057 $space=$this->_escape($space );
4058 $s = sprintf(' BT '.$aix,$x*_MPDFK,($this->h-$y)*_MPDFK);
4059 $t = explode(' ',$txt);
4060 for($i=0;$i<count($t);$i++) {
4061 $tx = $t[$i];
4062
4063 $tj = '(';
4064 $unicode = $this->UTF8StringToArray($tx);
4065 for($ti=0;$ti<count($unicode);$ti++) {
4066 if ($ti > 0 && isset($this->CurrentFont['kerninfo'][$unicode[($ti-1)]][$unicode[$ti]])) {
4067 $kern = -$this->CurrentFont['kerninfo'][$unicode[($ti-1)]][$unicode[$ti]];
4068 $tj .= sprintf(')%d(',$kern);
4069 }
4070 $tc = code2utf($unicode[$ti]);
4071 $tc = $this->UTF8ToUTF16BE($tc, false);
4072 $tj .= $this->_escape($tc);
4073 }
4074 $tj .= ')';
4075 $s.=sprintf(' %.3F Tc [%s] TJ',$this->charspacing,$tj);
4076
4077
4078 if (($i+1)<count($t)) {
4079 $s.=sprintf(' %.3F Tc (%s) Tj',$this->ws+$this->charspacing,$space);
4080 }
4081 }
4082 $s.=' ET ';
4083 }
4084 else if (!$this->usingCoreFont) {
4085 $s = '';
4086 $tj = '(';
4087 $unicode = $this->UTF8StringToArray($txt);
4088 for($i=0;$i<count($unicode);$i++) {
4089 if ($i > 0 && isset($this->CurrentFont['kerninfo'][$unicode[($i-1)]][$unicode[$i]])) {
4090 $kern = -$this->CurrentFont['kerninfo'][$unicode[($i-1)]][$unicode[$i]];
4091 $tj .= sprintf(')%d(',$kern);
4092 }
4093 $tx = code2utf($unicode[$i]);
4094 $tx = $this->UTF8ToUTF16BE($tx, false);
4095 $tj .= $this->_escape($tx);
4096 }
4097 $tj .= ')';
4098 $s.=sprintf(' BT '.$aix.' [%s] TJ ET ',$x*_MPDFK,($this->h-$y)*_MPDFK,$tj);
4099 }
4100 else { // CORE Font
4101 $s = '';
4102 $tj = '(';
4103 $l = strlen($txt);
4104 for($i=0;$i<$l;$i++) {
4105 if ($i > 0 && isset($this->CurrentFont['kerninfo'][$txt[($i-1)]][$txt[$i]])) {
4106 $kern = -$this->CurrentFont['kerninfo'][$txt[($i-1)]][$txt[$i]];
4107 $tj .= sprintf(')%d(',$kern);
4108 }
4109 $tj .= $this->_escape($txt[$i]);
4110 }
4111 $tj .= ')';
4112 $s.=sprintf(' BT '.$aix.' [%s] TJ ET ',$x*_MPDFK,($this->h-$y)*_MPDFK,$tj);
4113 }
4114
4115 return $s;
4116}
4117
4118
4119function _smallCaps($txt, $mode, $aix, $dx, $k, $baseline, $va) {
4120 $upp = false;
4121 $str = array();
4122 $bits = array();
4123 if (!$this->usingCoreFont) {
4124 $unicode = $this->UTF8StringToArray($txt);
4125 foreach($unicode as $char) {
4126 if ($this->ws && $char == 32) { // space
4127 if (count($str)) { $bits[] = array($upp, $str, false); }
4128 $bits[] = array(false, array(32), true);
4129 $str = array();
4130 $upp = false;
4131 }
4132 else if (isset($this->upperCase[$char])) {
4133 if (!$upp) {
4134 if (count($str)) { $bits[] = array($upp, $str, false); }
4135 $str = array();
4136 }
4137 $str[] = $this->upperCase[$char];
4138 if ((!isset($this->CurrentFont['sip']) || !$this->CurrentFont['sip']) && (!isset($this->CurrentFont['smp']) || !$this->CurrentFont['smp'])) {
4139 $this->CurrentFont['subset'][$this->upperCase[$char]] = $this->upperCase[$char];
4140 }
4141 $upp = true;
4142 }
4143 else {
4144 if ($upp) {
4145 if (count($str)) { $bits[] = array($upp, $str, false); }
4146 $str = array();
4147 }
4148 $str[] = $char;
4149 $upp = false;
4150 }
4151 }
4152 }
4153 else {
4154 for($i=0;$i<strlen($txt);$i++) {
4155 if (isset($this->upperCase[ord($txt[$i])]) && $this->upperCase[ord($txt[$i])] < 256) {
4156 if (!$upp) {
4157 if (count($str)) { $bits[] = array($upp, $str, false); }
4158 $str = array();
4159 }
4160 $str[] = $this->upperCase[ord($txt[$i])];
4161 $upp = true;
4162 }
4163 else {
4164 if ($upp) {
4165 if (count($str)) { $bits[] = array($upp, $str, false); }
4166 $str = array();
4167 }
4168 $str[] = ord($txt[$i]);
4169 $upp = false;
4170 }
4171 }
4172 }
4173 if (count($str)) { $bits[] = array($upp, $str, false); }
4174
4175 $fid = $this->CurrentFont['i'];
4176
4177 $s=sprintf(' BT '.$aix,($this->x+$dx)*$k,($this->h-($this->y+$baseline+$va))*$k);
4178 foreach($bits AS $b) {
4179 if ($b[0]) { $upp = true; }
4180 else { $upp = false; }
4181
4182 $size = count ($b[1]);
4183 $txt = '';
4184 for ($i = 0; $i < $size; $i++) {
4185 $txt .= code2utf($b[1][$i]);
4186 }
4187 if ($this->usingCoreFont) {
4188 $txt = utf8_decode($txt);
4189 }
4190 if ($mode == 'SIPSMP') {
4191 $txt = $this->UTF8toSubset($txt);
4192 }
4193 else {
4194 if (!$this->usingCoreFont) {
4195 $txt = $this->UTF8ToUTF16BE($txt, false);
4196 }
4197 $txt=$this->_escape($txt);
4198 $txt = '('.$txt.')';
4199 }
4200 if ($b[2]) { // space
4201 $s.=sprintf(' /F%d %.3F Tf %d Tz', $fid, $this->FontSizePt, 100);
4202 $s.=sprintf(' %.3F Tc', ($this->charspacing+$this->ws));
4203 $s.=sprintf(' %s Tj', $txt);
4204 }
4205 else if ($upp) {
4206 $s.=sprintf(' /F%d %.3F Tf', $fid, $this->FontSizePt*$this->smCapsScale);
4207 $s.=sprintf(' %d Tz', $this->smCapsStretch);
4208 $s.=sprintf(' %.3F Tc', ($this->charspacing*100/$this->smCapsStretch));
4209 $s.=sprintf(' %s Tj', $txt);
4210 }
4211 else {
4212 $s.=sprintf(' /F%d %.3F Tf %d Tz', $fid, $this->FontSizePt, 100);
4213 $s.=sprintf(' %.3F Tc', ($this->charspacing));
4214 $s.=sprintf(' %s Tj', $txt);
4215 }
4216 }
4217 $s.=' ET ';
4218 return $s;
4219}
4220
4221
4222function MultiCell($w,$h,$txt,$border=0,$align='',$fill=0,$link='',$directionality='ltr',$encoded=false)
4223{
4224 // Parameter (pre-)encoded - When called internally from ToC or textarea: mb_encoding already done - but not reverse RTL/Indic
4225 if (!$encoded) {
4226 $txt = $this->purify_utf8_text($txt);
4227 if ($this->text_input_as_HTML) {
4228 $txt = $this->all_entities_to_utf8($txt);
4229 }
4230 if ($this->usingCoreFont) { $txt = mb_convert_encoding($txt,$this->mb_enc,'UTF-8'); }
4231 // Font-specific ligature substitution for Indic fonts
4232 else if (isset($this->CurrentFont['indic']) && $this->CurrentFont['indic']) { // *INDIC*
4233 $this->ConvertIndic($tmp); // *INDIC*
4234 } // *INDIC*
4235 if (preg_match("/([".$this->pregRTLchars."])/u", $txt)) { $this->biDirectional = true; } // *RTL*
4236 }
4237 if (!$align) { $align = $this->defaultAlign; }
4238
4239 //Output text with automatic or explicit line breaks
4240 $cw=&$this->CurrentFont['cw'];
4241 if($w==0) $w=$this->w-$this->rMargin-$this->x;
4242
4243 $wmax = ($w - ($this->cMarginL+$this->cMarginR));
4244 if ($this->usingCoreFont) {
4245 $s=str_replace("\r",'',$txt);
4246 $nb=strlen($s);
4247 while($nb>0 and $s[$nb-1]=="\n") $nb--;
4248 }
4249 else {
4250 $s=str_replace("\r",'',$txt);
4251 $nb=mb_strlen($s, $this->mb_enc );
4252 while($nb>0 and mb_substr($s,$nb-1,1,$this->mb_enc )=="\n") $nb--;
4253 }
4254 $b=0;
4255 if($border) {
4256 if($border==1) {
4257 $border='LTRB';
4258 $b='LRT';
4259 $b2='LR';
4260 }
4261 else {
4262 $b2='';
4263 if(is_int(strpos($border,'L'))) $b2.='L';
4264 if(is_int(strpos($border,'R'))) $b2.='R';
4265 $b=is_int(strpos($border,'T')) ? $b2.'T' : $b2;
4266 }
4267 }
4268 $sep=-1;
4269 $i=0;
4270 $j=0;
4271 $l=0;
4272 $ns=0;
4273 $nl=1;
4274
4275
4276
4277 if (!$this->usingCoreFont) {
4278 $checkCursive=false;
4279 if ($this->biDirectional) { $checkCursive=true; }
4280 else if (isset($this->CurrentFont['indic']) && $this->CurrentFont['indic']) { $checkCursive=true; } // *INDIC*
4281 while($i<$nb) {
4282 //Get next character
4283 $c = mb_substr($s,$i,1,$this->mb_enc );
4284 if($c == "\n") {
4285 //Explicit line break
4286 // WORD SPACING
4287 $this->ResetSpacing();
4288 $tmp = rtrim(mb_substr($s,$j,$i-$j,$this->mb_enc));
4289 // DIRECTIONALITY
4290 $this->magic_reverse_dir($tmp, true, $directionality); // *RTL*
4291
4292 $this->Cell($w,$h,$tmp,$b,2,$align,$fill,$link);
4293 $i++;
4294 $sep=-1;
4295 $j=$i;
4296 $l=0;
4297 $ns=0;
4298 $nl++;
4299 if($border and $nl==2) $b=$b2;
4300 continue;
4301 }
4302 if($c == " ") {
4303 $sep=$i;
4304 $ls=$l;
4305 $ns++;
4306 }
4307
4308 $l += $this->GetCharWidthNonCore($c);
4309
4310 if($l>$wmax) {
4311 //Automatic line break
4312 if($sep==-1) { // Only one word
4313 if($i==$j) $i++;
4314 // WORD SPACING
4315 $this->ResetSpacing();
4316 $tmp = rtrim(mb_substr($s,$j,$i-$j,$this->mb_enc));
4317 // DIRECTIONALITY
4318 $this->magic_reverse_dir($tmp, true, $directionality); // *RTL*
4319
4320 $this->Cell($w,$h,$tmp,$b,2,$align,$fill,$link);
4321 }
4322 else {
4323 $tmp = rtrim(mb_substr($s,$j,$sep-$j,$this->mb_enc));
4324 if($align=='J') {
4325 //////////////////////////////////////////
4326 // JUSTIFY J using Unicode fonts (Word spacing doesn't work)
4327 // WORD SPACING UNICODE
4328 // Change NON_BREAKING SPACE to spaces so they are 'spaced' properly
4329 $tmp = str_replace(chr(194).chr(160),chr(32),$tmp );
4330 $len_ligne = $this->GetStringWidth($tmp );
4331 $nb_carac = mb_strlen( $tmp , $this->mb_enc ) ;
4332 $nb_spaces = mb_substr_count( $tmp ,' ', $this->mb_enc ) ;
4333
4334 $inclCursive=false;
4335 if ($checkCursive) {
4336 if (preg_match("/([".$this->pregRTLchars."])/u", $tmp)) { $inclCursive = true; } // *RTL*
4337 if (preg_match("/([".$this->pregHIchars.$this->pregBNchars.$this->pregPAchars."])/u", $tmp)) { $inclCursive = true; } // *INDIC*
4338 }
4339 list($charspacing,$ws) = $this->GetJspacing($nb_carac,$nb_spaces,((($wmax) - $len_ligne) * _MPDFK),$inclCursive);
4340 $this->SetSpacing($charspacing,$ws);
4341 //////////////////////////////////////////
4342 }
4343
4344 // DIRECTIONALITY
4345 $this->magic_reverse_dir($tmp, true, $directionality); // *RTL*
4346
4347 $this->Cell($w,$h,$tmp,$b,2,$align,$fill,$link);
4348 $i=$sep+1;
4349 }
4350 $sep=-1;
4351 $j=$i;
4352 $l=0;
4353 $ns=0;
4354 $nl++;
4355 if($border and $nl==2) $b=$b2;
4356 }
4357 else $i++;
4358 }
4359 //Last chunk
4360 // WORD SPACING
4361
4362 $this->ResetSpacing();
4363
4364 }
4365
4366
4367 else {
4368
4369 while($i<$nb) {
4370 //Get next character
4371 $c=$s[$i];
4372 if($c == "\n") {
4373 //Explicit line break
4374 // WORD SPACING
4375 $this->ResetSpacing();
4376 $this->Cell($w,$h,substr($s,$j,$i-$j),$b,2,$align,$fill,$link);
4377 $i++;
4378 $sep=-1;
4379 $j=$i;
4380 $l=0;
4381 $ns=0;
4382 $nl++;
4383 if($border and $nl==2) $b=$b2;
4384 continue;
4385 }
4386 if($c == " ") {
4387 $sep=$i;
4388 $ls=$l;
4389 $ns++;
4390 }
4391
4392 $l += $this->GetCharWidthCore($c);
4393 if($l>$wmax) {
4394 //Automatic line break
4395 if($sep==-1) {
4396 if($i==$j) $i++;
4397 // WORD SPACING
4398 $this->ResetSpacing();
4399 $this->Cell($w,$h,substr($s,$j,$i-$j),$b,2,$align,$fill,$link);
4400 }
4401 else {
4402 if($align=='J') {
4403 $tmp = rtrim(substr($s,$j,$sep-$j));
4404 //////////////////////////////////////////
4405 // JUSTIFY J using Unicode fonts (Word spacing doesn't work)
4406 // WORD SPACING NON_UNICDOE/CJK
4407 // Change NON_BREAKING SPACE to spaces so they are 'spaced' properly
4408 $tmp = str_replace(chr(160),chr(32),$tmp);
4409 $len_ligne = $this->GetStringWidth($tmp );
4410 $nb_carac = strlen( $tmp ) ;
4411 $nb_spaces = substr_count( $tmp ,' ' ) ;
4412 list($charspacing,$ws) = $this->GetJspacing($nb_carac,$nb_spaces,((($wmax) - $len_ligne) * _MPDFK),false);
4413 $this->SetSpacing($charspacing,$ws);
4414 //////////////////////////////////////////
4415 }
4416 $this->Cell($w,$h,substr($s,$j,$sep-$j),$b,2,$align,$fill,$link);
4417 $i=$sep+1;
4418 }
4419 $sep=-1;
4420 $j=$i;
4421 $l=0;
4422 $ns=0;
4423 $nl++;
4424 if($border and $nl==2) $b=$b2;
4425 }
4426 else $i++;
4427 }
4428 //Last chunk
4429 // WORD SPACING
4430
4431 $this->ResetSpacing();
4432
4433 }
4434 //Last chunk
4435 if($border and is_int(strpos($border,'B'))) $b.='B';
4436 if (!$this->usingCoreFont) {
4437 $tmp = rtrim(mb_substr($s,$j,$i-$j,$this->mb_enc));
4438 // DIRECTIONALITY
4439 $this->magic_reverse_dir($tmp, true, $directionality); // *RTL*
4440 $this->Cell($w,$h,$tmp,$b,2,$align,$fill,$link);
4441 }
4442 else { $this->Cell($w,$h,substr($s,$j,$i-$j),$b,2,$align,$fill,$link); }
4443 $this->x=$this->lMargin;
4444}
4445
4446
4447/*-- DIRECTW --*/
4448function Write($h,$txt,$currentx=0,$link='',$directionality='ltr',$align='') {
4449 if (!class_exists('directw', false)) { include(_MPDF_PATH.'classes/directw.php'); }
4450 if (empty($this->directw)) { $this->directw = new directw($this); }
4451 $this->directw->Write($h,$txt,$currentx,$link,$directionality,$align);
4452}
4453/*-- END DIRECTW --*/
4454
4455
4456/*-- HTML-CSS --*/
4457function saveInlineProperties() {
4458 $saved = array();
4459 $saved[ 'family' ] = $this->FontFamily;
4460 $saved[ 'style' ] = $this->FontStyle;
4461 $saved[ 'sizePt' ] = $this->FontSizePt;
4462 $saved[ 'size' ] = $this->FontSize;
4463 $saved[ 'HREF' ] = $this->HREF;
4464 $saved[ 'underline' ] = $this->U;
4465 $saved[ 'smCaps' ] = $this->S;
4466 $saved[ 'strike' ] = $this->strike;
4467 $saved[ 'textshadow' ] = $this->textshadow;
4468 $saved[ 'SUP' ] = $this->SUP;
4469 $saved[ 'SUB' ] = $this->SUB;
4470 $saved[ 'linewidth' ] = $this->LineWidth;
4471 $saved[ 'drawcolor' ] = $this->DrawColor;
4472 $saved[ 'textparam' ] = $this->textparam;
4473 $saved[ 'toupper' ] = $this->toupper;
4474 $saved[ 'tolower' ] = $this->tolower;
4475 $saved[ 'capitalize' ] = $this->capitalize;
4476 $saved[ 'fontkerning' ] = $this->kerning;
4477 $saved[ 'lSpacingCSS' ] = $this->lSpacingCSS;
4478 $saved[ 'wSpacingCSS' ] = $this->wSpacingCSS;
4479 $saved[ 'I' ] = $this->I;
4480 $saved[ 'B' ] = $this->B;
4481 $saved[ 'colorarray' ] = $this->colorarray;
4482 $saved[ 'bgcolorarray' ] = $this->spanbgcolorarray;
4483 $saved[ 'border' ] = $this->spanborddet;
4484 $saved[ 'color' ] = $this->TextColor;
4485 $saved[ 'bgcolor' ] = $this->FillColor;
4486 $saved[ 'lang' ] = $this->currentLang;
4487 $saved[ 'display_off' ] = $this->inlineDisplayOff;
4488
4489 return $saved;
4490}
4491
4492function restoreInlineProperties( &$saved) {
4493 $FontFamily = $saved[ 'family' ];
4494 $this->FontStyle = $saved[ 'style' ];
4495 $this->FontSizePt = $saved[ 'sizePt' ];
4496 $this->FontSize = $saved[ 'size' ];
4497
4498 $this->currentLang = $saved['lang'];
4499 if ($this->useLang && !$this->usingCoreFont) {
4500 if ($this->currentLang != $this->default_lang && ((strlen($this->currentLang) == 5 && $this->currentLang != 'UTF-8') || strlen($this->currentLang ) == 2)) {
4501 list ($coreSuitable,$mpdf_pdf_unifonts) = GetLangOpts($this->currentLang, $this->useAdobeCJK);
4502 if ($mpdf_pdf_unifonts) { $this->RestrictUnicodeFonts($mpdf_pdf_unifonts); }
4503 else { $this->RestrictUnicodeFonts($this->default_available_fonts ); }
4504 }
4505 else {
4506 $this->RestrictUnicodeFonts($this->default_available_fonts );
4507 }
4508 }
4509
4510 $this->ColorFlag = ($this->FillColor != $this->TextColor); //Restore ColorFlag as well
4511
4512 $this->HREF = $saved[ 'HREF' ];
4513 $this->U = $saved[ 'underline' ];
4514 $this->S = $saved[ 'smCaps' ];
4515 $this->strike = $saved[ 'strike' ];
4516 $this->textshadow = $saved[ 'textshadow' ];
4517 $this->SUP = $saved[ 'SUP' ];
4518 $this->SUB = $saved[ 'SUB' ];
4519 $this->LineWidth = $saved[ 'linewidth' ];
4520 $this->DrawColor = $saved[ 'drawcolor' ];
4521 $this->textparam = $saved[ 'textparam' ];
4522 $this->inlineDisplayOff = $saved['display_off'];
4523
4524 $this->toupper = $saved[ 'toupper' ];
4525 $this->tolower = $saved[ 'tolower' ];
4526 $this->capitalize = $saved[ 'capitalize' ];
4527 $this->kerning = $saved[ 'fontkerning' ];
4528 $this->lSpacingCSS = $saved[ 'lSpacingCSS' ];
4529 if (($this->lSpacingCSS || $this->lSpacingCSS==='0') && strtoupper($this->lSpacingCSS) != 'NORMAL') {
4530 $this->fixedlSpacing = $this->ConvertSize($this->lSpacingCSS,$this->FontSize);
4531 }
4532 else { $this->fixedlSpacing = false; }
4533 $this->wSpacingCSS = $saved[ 'wSpacingCSS' ];
4534 if ($this->wSpacingCSS && strtoupper($this->wSpacingCSS) != 'NORMAL') {
4535 $this->minwSpacing = $this->ConvertSize($this->wSpacingCSS,$this->FontSize);
4536 }
4537 else { $this->minwSpacing = 0; }
4538
4539 $this->SetFont($FontFamily, $saved[ 'style' ].($this->U ? 'U' : '').($this->S ? 'S' : ''),$saved[ 'sizePt' ],false);
4540
4541 $this->currentfontstyle = $saved[ 'style' ].($this->U ? 'U' : '').($this->S ? 'S' : '');
4542 $this->currentfontsize = $saved[ 'sizePt' ];
4543 $this->SetStylesArray(array('S'=>$this->S, 'U'=>$this->U, 'B'=>$saved[ 'B' ], 'I'=>$saved[ 'I' ]));
4544
4545 $this->TextColor = $saved[ 'color' ];
4546 $this->FillColor = $saved[ 'bgcolor' ];
4547 $this->colorarray = $saved[ 'colorarray' ];
4548 $cor = $saved[ 'colorarray' ];
4549 if ($cor) $this->SetTColor($cor);
4550 $this->spanbgcolorarray = $saved[ 'bgcolorarray' ];
4551 $cor = $saved[ 'bgcolorarray' ];
4552 if ($cor) $this->SetFColor($cor);
4553 $this->spanborddet = $saved[ 'border' ];
4554}
4555
4556
4557
4558// Used when ColActive for tables - updated to return first block with background fill OR borders
4559function GetFirstBlockFill() {
4560 // Returns the first blocklevel that uses a bgcolor fill
4561 $startfill = 0;
4562 for ($i=1;$i<=$this->blklvl;$i++) {
4563 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'] ) {
4564 $startfill = $i;
4565 break;
4566 }
4567 }
4568 return $startfill;
4569}
4570
4571function SetBlockFill($blvl) {
4572 if ($this->blk[$blvl]['bgcolor']) {
4573 $this->SetFColor($this->blk[$blvl]['bgcolorarray']);
4574 return 1;
4575 }
4576 else {
4577 $this->SetFColor($this->ConvertColor(255));
4578 return 0;
4579 }
4580}
4581
4582
4583//-------------------------FLOWING BLOCK------------------------------------//
4584//The following functions were originally written by Damon Kohler //
4585//--------------------------------------------------------------------------//
4586
4587function saveFont() {
4588 $saved = array();
4589 $saved[ 'family' ] = $this->FontFamily;
4590 $saved[ 'style' ] = $this->FontStyle;
4591 $saved[ 'sizePt' ] = $this->FontSizePt;
4592 $saved[ 'size' ] = $this->FontSize;
4593 $saved[ 'curr' ] = &$this->CurrentFont;
4594 $saved[ 'color' ] = $this->TextColor;
4595 $saved[ 'spanbgcolor' ] = $this->spanbgcolor;
4596 $saved[ 'spanbgcolorarray' ] = $this->spanbgcolorarray;
4597 $saved[ 'bord' ] = $this->spanborder;
4598 $saved[ 'border' ] = $this->spanborddet;
4599 $saved[ 'HREF' ] = $this->HREF;
4600 $saved[ 'underline' ] = $this->U;
4601 $saved[ 'smCaps' ] = $this->S;
4602 $saved[ 'strike' ] = $this->strike;
4603 $saved[ 'textshadow' ] = $this->textshadow;
4604 $saved[ 'SUP' ] = $this->SUP;
4605 $saved[ 'SUB' ] = $this->SUB;
4606 $saved[ 'linewidth' ] = $this->LineWidth;
4607 $saved[ 'drawcolor' ] = $this->DrawColor;
4608 $saved[ 'textparam' ] = $this->textparam;
4609 $saved[ 'ReqFontStyle' ] = $this->ReqFontStyle;
4610 $saved[ 'fontkerning' ] = $this->kerning;
4611 $saved[ 'fixedlSpacing' ] = $this->fixedlSpacing;
4612 $saved[ 'minwSpacing' ] = $this->minwSpacing;
4613 return $saved;
4614}
4615
4616function restoreFont( &$saved, $write=true) {
4617 if (!isset($saved) || empty($saved)) return;
4618
4619 $this->FontFamily = $saved[ 'family' ];
4620 $this->FontStyle = $saved[ 'style' ];
4621 $this->FontSizePt = $saved[ 'sizePt' ];
4622 $this->FontSize = $saved[ 'size' ];
4623 $this->CurrentFont = &$saved[ 'curr' ];
4624 $this->TextColor = $saved[ 'color' ];
4625 $this->spanbgcolor = $saved[ 'spanbgcolor' ];
4626 $this->spanbgcolorarray = $saved[ 'spanbgcolorarray' ];
4627 $this->spanborder = $saved[ 'bord' ];
4628 $this->spanborddet = $saved[ 'border' ];
4629 $this->ColorFlag = ($this->FillColor != $this->TextColor); //Restore ColorFlag as well
4630 $this->HREF = $saved[ 'HREF' ];
4631 $this->U = $saved[ 'underline' ];
4632 $this->S = $saved[ 'smCaps' ];
4633 $this->kerning = $saved[ 'fontkerning' ];
4634 $this->fixedlSpacing = $saved[ 'fixedlSpacing' ];
4635 $this->minwSpacing = $saved[ 'minwSpacing' ];
4636 $this->strike = $saved[ 'strike' ];
4637 $this->textshadow = $saved[ 'textshadow' ];
4638 $this->SUP = $saved[ 'SUP' ];
4639 $this->SUB = $saved[ 'SUB' ];
4640 $this->LineWidth = $saved[ 'linewidth' ];
4641 $this->DrawColor = $saved[ 'drawcolor' ];
4642 $this->textparam = $saved[ 'textparam' ];
4643 if ($write) {
4644 $this->SetFont($saved[ 'family' ],$saved[ 'style' ].($this->U ? 'U' : '').($this->S ? 'S' : ''),$saved[ 'sizePt' ],true,true); // force output
4645 $fontout = (sprintf('BT /F%d %.3F Tf ET', $this->CurrentFont['i'], $this->FontSizePt));
4646 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); }
4647 $this->pageoutput[$this->page]['Font'] = $fontout;
4648 }
4649 else
4650 $this->SetFont($saved[ 'family' ],$saved[ 'style' ].($this->U ? 'U' : '').($this->S ? 'S' : ''),$saved[ 'sizePt' ]);
4651 $this->ReqFontStyle = $saved[ 'ReqFontStyle' ];
4652}
4653
4654function newFlowingBlock( $w, $h, $a = '', $is_table = false, $is_list = false, $blockstate = 0, $newblock=true, $blockdir='ltr')
4655{
4656 if (!$a) {
4657 if ($blockdir=='rtl') { $a = 'R'; }
4658 else { $a = 'L'; }
4659 }
4660 $this->flowingBlockAttr[ 'width' ] = ($w * _MPDFK);
4661 // line height in user units
4662 $this->flowingBlockAttr[ 'is_table' ] = $is_table;
4663 $this->flowingBlockAttr[ 'is_list' ] = $is_list;
4664 $this->flowingBlockAttr[ 'height' ] = $h;
4665 $this->flowingBlockAttr[ 'lineCount' ] = 0;
4666 $this->flowingBlockAttr[ 'align' ] = $a;
4667 $this->flowingBlockAttr[ 'font' ] = array();
4668 $this->flowingBlockAttr[ 'content' ] = array();
4669 $this->flowingBlockAttr[ 'contentB' ] = array();
4670 $this->flowingBlockAttr[ 'contentWidth' ] = 0;
4671 $this->flowingBlockAttr[ 'blockstate' ] = $blockstate;
4672
4673 $this->flowingBlockAttr[ 'newblock' ] = $newblock;
4674 $this->flowingBlockAttr[ 'valign' ] = 'M';
4675 $this->flowingBlockAttr['blockdir'] = $blockdir;
4676
4677}
4678
4679function finishFlowingBlock($endofblock=false, $next='') {
4680 $currentx = $this->x;
4681 //prints out the last chunk
4682 $is_table = $this->flowingBlockAttr[ 'is_table' ];
4683 $is_list = $this->flowingBlockAttr[ 'is_list' ];
4684 $maxWidth =& $this->flowingBlockAttr[ 'width' ];
4685 $lineHeight =& $this->flowingBlockAttr[ 'height' ];
4686 $align =& $this->flowingBlockAttr[ 'align' ];
4687 $content =& $this->flowingBlockAttr[ 'content' ];
4688 $contentB =& $this->flowingBlockAttr[ 'contentB' ];
4689 $font =& $this->flowingBlockAttr[ 'font' ];
4690 $contentWidth =& $this->flowingBlockAttr[ 'contentWidth' ];
4691 $lineCount =& $this->flowingBlockAttr[ 'lineCount' ];
4692 $valign =& $this->flowingBlockAttr[ 'valign' ];
4693 $blockstate = $this->flowingBlockAttr[ 'blockstate' ];
4694
4695 $newblock = $this->flowingBlockAttr[ 'newblock' ];
4696 $blockdir = $this->flowingBlockAttr['blockdir'];
4697
4698
4699 // *********** BLOCK BACKGROUND COLOR *****************//
4700 if ($this->blk[$this->blklvl]['bgcolor'] && !$is_table) {
4701 $fill = 0;
4702 }
4703 else {
4704 $this->SetFColor($this->ConvertColor(255));
4705 $fill = 0;
4706 }
4707
4708 $hanger = ''; // mPDF 5.6.40
4709
4710 // Always right trim!
4711 // Right trim content and adjust width if need to justify (later)
4712 if (isset($content[count($content)-1]) && preg_match('/[ ]+$/',$content[count($content)-1], $m)) {
4713 $strip = strlen($m[0]);
4714 $content[count($content)-1] = substr($content[count($content)-1],0,(strlen($content[count($content)-1])-$strip));
4715 $this->restoreFont( $font[ count($content)-1 ],false );
4716 $contentWidth -= $this->GetStringWidth($m[0]) * _MPDFK;
4717 }
4718
4719 // the amount of space taken up so far in user units
4720 $usedWidth = 0;
4721
4722 // COLS
4723 $oldcolumn = $this->CurrCol;
4724
4725 if ($this->ColActive && !$is_table) { $this->breakpoints[$this->CurrCol][] = $this->y; } // *COLUMNS*
4726
4727 // Print out each chunk
4728
4729/*-- TABLES --*/
4730 if ($is_table) {
4731 $ipaddingL = 0;
4732 $ipaddingR = 0;
4733 $paddingL = 0;
4734 $paddingR = 0;
4735 }
4736 else {
4737/*-- END TABLES --*/
4738 $ipaddingL = $this->blk[$this->blklvl]['padding_left'];
4739 $ipaddingR = $this->blk[$this->blklvl]['padding_right'];
4740 $paddingL = ($ipaddingL * _MPDFK);
4741 $paddingR = ($ipaddingR * _MPDFK);
4742 $this->cMarginL = $this->blk[$this->blklvl]['border_left']['w'];
4743 $this->cMarginR = $this->blk[$this->blklvl]['border_right']['w'];
4744
4745 // Added mPDF 3.0 Float DIV
4746 $fpaddingR = 0;
4747 $fpaddingL = 0;
4748/*-- CSS-FLOAT --*/
4749 if (count($this->floatDivs)) {
4750 list($l_exists, $r_exists, $l_max, $r_max, $l_width, $r_width) = $this->GetFloatDivInfo($this->blklvl);
4751 if ($r_exists) { $fpaddingR = $r_width; }
4752 if ($l_exists) { $fpaddingL = $l_width; }
4753 }
4754/*-- END CSS-FLOAT --*/
4755
4756 $usey = $this->y + 0.002;
4757 if (($newblock) && ($blockstate==1 || $blockstate==3) && ($lineCount == 0) ) {
4758 $usey += $this->blk[$this->blklvl]['margin_top'] + $this->blk[$this->blklvl]['padding_top'] + $this->blk[$this->blklvl]['border_top']['w'];
4759 }
4760/*-- CSS-IMAGE-FLOAT --*/
4761 // If float exists at this level
4762 if (isset($this->floatmargins['R']) && $usey <= $this->floatmargins['R']['y1'] && $usey >= $this->floatmargins['R']['y0'] && !$this->floatmargins['R']['skipline']) { $fpaddingR += $this->floatmargins['R']['w']; }
4763 if (isset($this->floatmargins['L']) && $usey <= $this->floatmargins['L']['y1'] && $usey >= $this->floatmargins['L']['y0'] && !$this->floatmargins['L']['skipline']) { $fpaddingL += $this->floatmargins['L']['w']; }
4764/*-- END CSS-IMAGE-FLOAT --*/
4765 } // *TABLES*
4766
4767 // Set Current lineheight (correction factor)
4768 $lhfixed = false;
4769/*-- LISTS --*/
4770 if ($is_list) {
4771 if (preg_match('/([0-9.,]+)mm/',$this->list_lineheight[$this->listlvl][$this->listOcc],$am)) {
4772 $lhfixed = true;
4773 $def_fontsize = $this->InlineProperties['LISTITEM'][$this->listlvl][$this->listOcc][$this->listnum]['size'];
4774 $this->lineheight_correction = $am[1] / $def_fontsize ;
4775 }
4776 else {
4777 $this->lineheight_correction = $this->list_lineheight[$this->listlvl][$this->listOcc];
4778 }
4779 }
4780 else
4781/*-- END LISTS --*/
4782/*-- TABLES --*/
4783 if ($is_table) {
4784 if (preg_match('/([0-9.,]+)mm/',$this->table_lineheight,$am)) {
4785 $lhfixed = true;
4786 $def_fontsize = $this->FontSize; // needs to be default font-size for block ****
4787 $this->lineheight_correction = $lineHeight / $def_fontsize ;
4788 }
4789 else {
4790 $this->lineheight_correction = $this->table_lineheight;
4791 }
4792 }
4793 else
4794/*-- END TABLES --*/
4795 if (isset($this->blk[$this->blklvl]['line_height']) && $this->blk[$this->blklvl]['line_height']) {
4796 if (preg_match('/([0-9.,]+)mm/',$this->blk[$this->blklvl]['line_height'],$am)) {
4797 $lhfixed = true;
4798 $def_fontsize = $this->blk[$this->blklvl]['InlineProperties']['size']; // needs to be default font-size for block ****
4799 $this->lineheight_correction = $am[1] / $def_fontsize ;
4800 }
4801 else {
4802 $this->lineheight_correction = $this->blk[$this->blklvl]['line_height'];
4803 }
4804 }
4805 else {
4806 $this->lineheight_correction = $this->normalLineheight;
4807 }
4808
4809 // correct lineheight to maximum fontsize
4810 if ($lhfixed) { $maxlineHeight = $this->lineheight; }
4811 else { $maxlineHeight = 0; }
4812 $this->forceExactLineheight = true;
4813 $maxfontsize = 0;
4814 // While we're at it, check if contains cursive text
4815 $checkCursive=false;
4816 if ($this->biDirectional) { $checkCursive=true; } // *RTL*
4817 foreach ( $content as $k => $chunk )
4818 {
4819 $this->restoreFont( $font[ $k ],false );
4820 if (!isset($this->objectbuffer[$k])) {
4821 // Soft Hyphens chr(173)
4822 if (!$this->usingCoreFont) {
4823 $content[$k] = $chunk = str_replace("\xc2\xad",'',$chunk );
4824 if (isset($this->CurrentFont['indic']) && $this->CurrentFont['indic']) { $checkCursive=true; } // *INDIC*
4825 }
4826 else if ($this->FontFamily!='csymbol' && $this->FontFamily!='czapfdingbats') {
4827 $content[$k] = $chunk = str_replace(chr(173),'',$chunk );
4828 }
4829 // Special case of sub/sup carried over on its own to last line
4830 if (($this->SUB || $this->SUP) && count($content)==1) { $actfs = $this->FontSize*100/55; } // 55% is font change for sub/sup
4831 else { $actfs = $this->FontSize; }
4832 if (!$lhfixed) { $maxlineHeight = max($maxlineHeight,$actfs * $this->lineheight_correction ); }
4833 if ($lhfixed && ($actfs > $def_fontsize || ($actfs > ($lineHeight * $this->lineheight_correction) && $is_list))) {
4834 $this->forceExactLineheight = false;
4835 }
4836 $maxfontsize = max($maxfontsize,$actfs);
4837 }
4838 }
4839
4840 if(isset($font[count($font)-1])) {
4841 $lastfontreqstyle = $font[count($font)-1]['ReqFontStyle'];
4842 $lastfontstyle = $font[count($font)-1]['style'];
4843 }
4844 else {
4845 $lastfontreqstyle=null;
4846 $lastfontstyle=null;
4847 }
4848 if ($blockdir == 'ltr' && strpos($lastfontreqstyle,"I") !== false && strpos($lastfontstyle,"I") === false) { // Artificial italic
4849 $lastitalic = $this->FontSize*0.15*_MPDFK;
4850 }
4851 else { $lastitalic = 0; }
4852
4853
4854/*-- LISTS --*/
4855 if ($is_list && is_array($this->bulletarray) && count($this->bulletarray)) {
4856 $actfs = $this->bulletarray['fontsize'];
4857 if (!$lhfixed) { $maxlineHeight = max($maxlineHeight,$actfs * $this->lineheight_correction ); }
4858 if ($lhfixed && $actfs > $def_fontsize) { $this->forceExactLineheight = false; }
4859 $maxfontsize = max($maxfontsize,$actfs);
4860 }
4861/*-- END LISTS --*/
4862
4863 // when every text item checked i.e. $maxfontsize is set properly
4864
4865 $af = 0; // Above font
4866 $bf = 0; // Below font
4867 $mta = 0; // Maximum top-aligned
4868 $mba = 0; // Maximum bottom-aligned
4869
4870 foreach ( $content as $k => $chunk )
4871 {
4872 if (isset($this->objectbuffer[$k])) {
4873 $oh = $this->objectbuffer[$k]['OUTER-HEIGHT'];
4874 $va = $this->objectbuffer[$k]['vertical-align']; // = $objattr['vertical-align'] = set as M,T,B,S
4875 if ($lhfixed && $oh > $def_fontsize) { $this->forceExactLineheight = false; }
4876
4877 if ($va == 'BS') { // (BASELINE default)
4878 $af = max($af, ($oh - ($maxfontsize * (0.5 + $this->baselineC))));
4879 }
4880 else if ($va == 'M') {
4881 $af = max($af, ($oh - $maxfontsize)/2);
4882 $bf = max($bf, ($oh - $maxfontsize)/2);
4883 }
4884 else if ($va == 'TT') {
4885 $bf = max($bf, ($oh - $maxfontsize));
4886 }
4887 else if ($va == 'TB') {
4888 $af = max($af, ($oh - $maxfontsize));
4889 }
4890 else if ($va == 'T') {
4891 $mta = max($mta, $oh);
4892 }
4893 else if ($va == 'B') {
4894 $mba = max($mba, $oh);
4895 }
4896 }
4897 }
4898 if ((!$lhfixed || !$this->forceExactLineheight) && ($af > (($maxlineHeight - $maxfontsize)/2) || $bf > (($maxlineHeight - $maxfontsize)/2))) {
4899 $maxlineHeight = $maxfontsize + $af + $bf;
4900 }
4901 else if (!$lhfixed) { $af = $bf = ($maxlineHeight - $maxfontsize)/2; }
4902 if ($mta > $maxlineHeight) {
4903 $bf += ($mta - $maxlineHeight);
4904 $maxlineHeight = $mta;
4905 }
4906 if ($mba > $maxlineHeight) {
4907 $af += ($mba - $maxlineHeight);
4908 $maxlineHeight = $mba;
4909 }
4910
4911 $lineHeight = $maxlineHeight;
4912 // If NOT images, and maxfontsize NOT > lineHeight - this value determines text baseline positioning
4913 if ($lhfixed && $af==0 && $bf==0 && $maxfontsize<=($def_fontsize * $this->lineheight_correction * 0.8 )) {
4914 $this->linemaxfontsize = $def_fontsize;
4915 }
4916 else { $this->linemaxfontsize = $maxfontsize; }
4917
4918 // Get PAGEBREAK TO TEST for height including the bottom border/padding
4919 $check_h = max($this->divheight,$lineHeight);
4920
4921 // This fixes a proven bug...
4922 if ($endofblock && $newblock && $blockstate==0 && !$content) { $check_h = 0; }
4923 // but ? needs to fix potentially more widespread...
4924 // if (!$content) { $check_h = 0; }
4925
4926 if ($this->blklvl > 0 && !$is_table) {
4927 if ($endofblock && $blockstate > 1) {
4928 if ($this->blk[$this->blklvl]['page_break_after_avoid']) { $check_h += $lineHeight; }
4929 $check_h += ($this->blk[$this->blklvl]['padding_bottom'] + $this->blk[$this->blklvl]['border_bottom']['w']);
4930 }
4931 // mPDF 5.4.03
4932 if (($newblock && ($blockstate==1 || $blockstate==3) && $lineCount == 0) || ($endofblock && $blockstate ==3 && $lineCount == 0)) {
4933 $check_h += ($this->blk[$this->blklvl]['padding_top'] + $this->blk[$this->blklvl]['margin_top'] + $this->blk[$this->blklvl]['border_top']['w']);
4934 }
4935 }
4936
4937 // Force PAGE break if column height cannot take check-height
4938 if ($this->ColActive && $check_h > ($this->PageBreakTrigger - $this->y0)) {
4939 $this->SetCol($this->NbCol-1);
4940 }
4941
4942 // mPDF 5.4.04
4943 // Avoid just border/background-color moved on to next page
4944 if ($endofblock && $blockstate > 1 && !$content) { $buff = $this->margBuffer; }
4945 else { $buff = 0; }
4946
4947
4948 // PAGEBREAK
4949 // mPDF 5.4.04
4950 if(!$is_table && ($this->y+$check_h) > ($this->PageBreakTrigger + $buff) and !$this->InFooter and $this->AcceptPageBreak()) {
4951 $bak_x=$this->x;//Current X position
4952 // WORD SPACING
4953 $ws=$this->ws;//Word Spacing
4954 $charspacing=$this->charspacing;//Character Spacing
4955 $this->ResetSpacing();
4956
4957 $this->AddPage($this->CurOrientation);
4958
4959 $this->x=$bak_x;
4960 // Added to correct for OddEven Margins
4961 $currentx += $this->MarginCorrection;
4962 $this->x += $this->MarginCorrection;
4963
4964 // WORD SPACING
4965 $this->SetSpacing($charspacing,$ws);
4966 }
4967
4968 if ($this->keep_block_together && !$is_table && $this->kt_p00 < $this->page && ($this->y+$check_h) > $this->kt_y00) {
4969 $this->printdivbuffer();
4970 $this->keep_block_together = 0;
4971 }
4972
4973/*-- COLUMNS --*/
4974 // COLS
4975 // COLUMN CHANGE
4976 if ($this->CurrCol != $oldcolumn) {
4977 $currentx += $this->ChangeColumn * ($this->ColWidth+$this->ColGap);
4978 $this->x += $this->ChangeColumn * ($this->ColWidth+$this->ColGap);
4979 $oldcolumn = $this->CurrCol;
4980 }
4981
4982
4983 if ($this->ColActive && !$is_table) { $this->breakpoints[$this->CurrCol][] = $this->y; }
4984/*-- END COLUMNS --*/
4985
4986 // TOP MARGIN
4987 if ($newblock && ($blockstate==1 || $blockstate==3) && ($this->blk[$this->blklvl]['margin_top']) && $lineCount == 0 && !$is_table && !$is_list) {
4988 $this->DivLn($this->blk[$this->blklvl]['margin_top'],$this->blklvl-1,true,$this->blk[$this->blklvl]['margin_collapse']);
4989 if ($this->ColActive) { $this->breakpoints[$this->CurrCol][] = $this->y; } // *COLUMNS*
4990 }
4991
4992 if ($newblock && ($blockstate==1 || $blockstate==3) && $lineCount == 0 && !$is_table && !$is_list) {
4993 $this->blk[$this->blklvl]['y0'] = $this->y;
4994 $this->blk[$this->blklvl]['startpage'] = $this->page;
4995 if ($this->blk[$this->blklvl]['float']) { $this->blk[$this->blklvl]['float_start_y'] = $this->y; } // mPDF 5.6.63
4996 if ($this->ColActive) { $this->breakpoints[$this->CurrCol][] = $this->y; } // *COLUMNS*
4997 }
4998
4999 // ADDED for Paragraph_indent
5000 $WidthCorrection = 0;
5001 if (($newblock) && ($blockstate==1 || $blockstate==3) && isset($this->blk[$this->blklvl]['text_indent']) && ($lineCount == 0) && (!$is_table) && (!$is_list) && ($align != 'C')) {
5002 $ti = $this->ConvertSize($this->blk[$this->blklvl]['text_indent'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
5003 $WidthCorrection = ($ti*_MPDFK);
5004 }
5005
5006
5007 // PADDING and BORDER spacing/fill
5008 if (($newblock) && ($blockstate==1 || $blockstate==3) && (($this->blk[$this->blklvl]['padding_top']) || ($this->blk[$this->blklvl]['border_top'])) && ($lineCount == 0) && (!$is_table) && (!$is_list)) {
5009 // $state = 0 normal; 1 top; 2 bottom; 3 top and bottom
5010 $this->DivLn($this->blk[$this->blklvl]['padding_top'] + $this->blk[$this->blklvl]['border_top']['w'],-3,true,false,1);
5011 if ($this->ColActive) { $this->breakpoints[$this->CurrCol][] = $this->y; } // *COLUMNS*
5012 $this->x = $currentx;
5013 }
5014
5015
5016 // Added mPDF 3.0 Float DIV
5017 $fpaddingR = 0;
5018 $fpaddingL = 0;
5019/*-- CSS-FLOAT --*/
5020 if (count($this->floatDivs)) {
5021 list($l_exists, $r_exists, $l_max, $r_max, $l_width, $r_width) = $this->GetFloatDivInfo($this->blklvl);
5022 if ($r_exists) { $fpaddingR = $r_width; }
5023 if ($l_exists) { $fpaddingL = $l_width; }
5024 }
5025/*-- END CSS-FLOAT --*/
5026
5027 $usey = $this->y + 0.002;
5028 if (($newblock) && ($blockstate==1 || $blockstate==3) && ($lineCount == 0) ) {
5029 $usey += $this->blk[$this->blklvl]['margin_top'] + $this->blk[$this->blklvl]['padding_top'] + $this->blk[$this->blklvl]['border_top']['w'];
5030 }
5031/*-- CSS-IMAGE-FLOAT --*/
5032 // If float exists at this level
5033 if (isset($this->floatmargins['R']) && $usey <= $this->floatmargins['R']['y1'] && $usey >= $this->floatmargins['R']['y0'] && !$this->floatmargins['R']['skipline']) { $fpaddingR += $this->floatmargins['R']['w']; }
5034 if (isset($this->floatmargins['L']) && $usey <= $this->floatmargins['L']['y1'] && $usey >= $this->floatmargins['L']['y0'] && !$this->floatmargins['L']['skipline']) { $fpaddingL += $this->floatmargins['L']['w']; }
5035/*-- END CSS-IMAGE-FLOAT --*/
5036
5037 if ($content) {
5038
5039 // In FinishFlowing Block no lines are justified as it is always last line
5040 // but if CJKorphan has allowed content width to go over max width, use J charspacing to compress line
5041 // JUSTIFICATION J - NOT!
5042 $nb_carac = 0;
5043 $nb_spaces = 0;
5044 $jcharspacing = 0;
5045 $jws = 0;
5046 $inclCursive=false;
5047 $dottab = false; // mPDF 5.6.19
5048 foreach ( $content as $k => $chunk ) {
5049 if (!isset($this->objectbuffer[$k]) || (isset($this->objectbuffer[$k]) && !$this->objectbuffer[$k])) {
5050 if ($this->usingCoreFont) {
5051 $chunk = str_replace(chr(160),chr(32),$chunk );
5052 }
5053 else {
5054 $chunk = str_replace(chr(194).chr(160),chr(32),$chunk );
5055 }
5056 $nb_carac += mb_strlen( $chunk, $this->mb_enc );
5057 $nb_spaces += mb_substr_count( $chunk,' ', $this->mb_enc );
5058 if ($checkCursive) {
5059 if (preg_match("/([".$this->pregRTLchars."])/u", $chunk)) { $inclCursive = true; } // *RTL*
5060 if (preg_match("/([".$this->pregHIchars.$this->pregBNchars.$this->pregPAchars."])/u", $chunk)) { $inclCursive = true; } // *INDIC*
5061 }
5062 }
5063 else if ($this->objectbuffer[$k]['type']=='dottab') { $dottab = $this->objectbuffer[$k]['outdent']; } // mPDF 5.6.19
5064 }
5065 // 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)
5066 // If "orphans" in fact is just a final space - ignore this
5067 // mPDF 5.6.40
5068 $lastchar = mb_substr($content[(count($content)-1)],mb_strlen($content[(count($content)-1)], $this->mb_enc)-1, 1, $this->mb_enc);
5069 if (preg_match("/[".$this->CJKoverflow."]/u", $lastchar)) { $CJKoverflow = true; }
5070 else {$CJKoverflow = false; }
5071 if ((((($contentWidth + $lastitalic) > $maxWidth) && ($content[count($content)-1] != ' ') ) ||
5072 (!$endofblock && $align=='J' && ($next=='image' || $next=='select' || $next=='input' || $next=='textarea' || ($next=='br' && $this->justifyB4br)))) && !($CJKoverflow && $this->allowCJKoverflow) ) { // mPDF 5.6.40
5073 // WORD SPACING
5074 list($jcharspacing,$jws) = $this->GetJspacing($nb_carac,$nb_spaces,($maxWidth-$lastitalic-$contentWidth-$WidthCorrection-(($this->cMarginL+$this->cMarginR)*_MPDFK)-($paddingL+$paddingR +(($fpaddingL + $fpaddingR) * _MPDFK) )),$inclCursive);
5075 }
5076/*-- CJK-FONTS --*/
5077 // mPDF 5.6.40
5078 else if ($this->checkCJK && $align=='J' && $CJKoverflow && $this->allowCJKoverflow && $this->CJKforceend) {
5079 // force-end overhang
5080 $hanger = mb_substr($content[count($content)-1],mb_strlen($content[count($content)-1],$this->mb_enc)-1,1,$this->mb_enc );
5081 if (preg_match("/[".$this->CJKoverflow."]/u", $hanger)) {
5082 $content[count($content)-1] = mb_substr($content[count($content)-1],0,mb_strlen($content[count($content)-1],$this->mb_enc)-1,$this->mb_enc );
5083 $this->restoreFont( $font[ count($content)-1 ],false );
5084 $contentWidth -= $this->GetStringWidth($hanger) * _MPDFK;
5085 $nb_carac -= 1;
5086 list($jcharspacing,$jws) = $this->GetJspacing($nb_carac,$nb_spaces,($maxWidth-$lastitalic-$contentWidth-$WidthCorrection-(($this->cMarginL+$this->cMarginR)*_MPDFK)-($paddingL+$paddingR +(($fpaddingL + $fpaddingR) * _MPDFK) )),$inclCursive);
5087 }
5088 }
5089/*-- END CJK-FONTS --*/
5090
5091 // Check if will fit at word/char spacing of previous line - if so continue it
5092 // but only allow a maximum of $this->jSmaxWordLast and $this->jSmaxCharLast
5093 else if ($contentWidth < ($maxWidth - $lastitalic-$WidthCorrection - (($this->cMarginL+$this->cMarginR)* _MPDFK) - ($paddingL+$paddingR +(($fpaddingL + $fpaddingR) * _MPDFK))) && !$this->fixedlSpacing) {
5094 if ($this->ws > $this->jSmaxWordLast) {
5095 $jws = $this->jSmaxWordLast;
5096 }
5097 if ($this->charspacing > $this->jSmaxCharLast) {
5098 $jcharspacing = $this->jSmaxCharLast;
5099 }
5100 $check = $maxWidth - $lastitalic-$WidthCorrection - $contentWidth - (($this->cMarginL+$this->cMarginR)* _MPDFK) - ($paddingL+$paddingR +(($fpaddingL + $fpaddingR) * _MPDFK) ) - ( $jcharspacing * $nb_carac) - ( $jws * $nb_spaces);
5101 if ($check <= 0) {
5102 $jcharspacing = 0;
5103 $jws = 0;
5104 }
5105 }
5106
5107 $empty = $maxWidth - $lastitalic-$WidthCorrection - $contentWidth - (($this->cMarginL+$this->cMarginR)* _MPDFK) - ($paddingL+$paddingR +(($fpaddingL + $fpaddingR) * _MPDFK) );
5108
5109 $empty -= ($jcharspacing * $nb_carac);
5110 $empty -= ($jws * $nb_spaces);
5111
5112 $empty /= _MPDFK;
5113
5114 if (!$is_table) {
5115 $this->maxPosR = max($this->maxPosR , ($this->w - $this->rMargin - $this->blk[$this->blklvl]['outer_right_margin'] - $empty));
5116 $this->maxPosL = min($this->maxPosL , ($this->lMargin + $this->blk[$this->blklvl]['outer_left_margin'] + $empty));
5117 }
5118
5119 $arraysize = count($content);
5120
5121 $margins = ($this->cMarginL+$this->cMarginR) + ($ipaddingL+$ipaddingR + $fpaddingR + $fpaddingR );
5122
5123 if (!$is_table) { $this->DivLn($lineHeight,$this->blklvl,false); } // false -> don't advance y
5124
5125 // DIRECTIONALITY RTL
5126 $all_rtl = false;
5127 $contains_rtl = false;
5128/*-- RTL --*/
5129 if ($blockdir == 'rtl' || $this->biDirectional) {
5130 $all_rtl = true;
5131 foreach ( $content as $k => $chunk ) {
5132 $reversed = $this->magic_reverse_dir($chunk, false, $blockdir);
5133 if ($reversed > 0) { $contains_rtl = true; }
5134 if ($reversed < 2) { $all_rtl = false; }
5135 $content[$k] = $chunk;
5136 }
5137 if (($blockdir =='rtl' && $contains_rtl) || $all_rtl) {
5138 $content = array_reverse($content,false);
5139 $contentB = array_reverse($contentB,false);
5140 }
5141 }
5142/*-- END RTL --*/
5143
5144 $this->x = $currentx + $this->cMarginL + $ipaddingL + $fpaddingL;
5145 if ($dottab !== false && $blockdir=='rtl') { $this->x -= $dottab; } // mPDF 5.6.19
5146 else if ($align == 'R') { $this->x += $empty; }
5147 else if ($align == 'J' && $blockdir == 'rtl') { $this->x += $empty; }
5148 else if ($align == 'C') { $this->x += ($empty / 2); }
5149
5150 // Paragraph INDENT
5151 $WidthCorrection = 0;
5152 if (($newblock) && ($blockstate==1 || $blockstate==3) && isset($this->blk[$this->blklvl]['text_indent']) && ($lineCount == 0) && (!$is_table) && (!$is_list) && ($align !='C')) {
5153 $ti = $this->ConvertSize($this->blk[$this->blklvl]['text_indent'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
5154 $this->x += $ti;
5155 }
5156
5157
5158 foreach ( $content as $k => $chunk )
5159 {
5160
5161 // FOR IMAGES
5162 if ((($blockdir == 'rtl') && ($contains_rtl )) || $all_rtl ) { $dirk = $arraysize-1 - $k; } else { $dirk = $k; }
5163
5164 $va = 'M'; // default for text
5165 if (isset($this->objectbuffer[$dirk]) && $this->objectbuffer[$dirk]) {
5166 $xadj = $this->x - $this->objectbuffer[$dirk]['OUTER-X'];
5167 $this->objectbuffer[$dirk]['OUTER-X'] += $xadj;
5168 $this->objectbuffer[$dirk]['BORDER-X'] += $xadj;
5169 $this->objectbuffer[$dirk]['INNER-X'] += $xadj;
5170 $va = $this->objectbuffer[$dirk]['vertical-align'];
5171 $yadj = $this->y - $this->objectbuffer[$dirk]['OUTER-Y'];
5172 if ($va == 'BS') {
5173 $yadj += $af + ($this->linemaxfontsize * (0.5 + $this->baselineC)) - $this->objectbuffer[$dirk]['OUTER-HEIGHT'];
5174 }
5175 else if ($va == 'M' || $va == '') {
5176 $yadj += $af + ($this->linemaxfontsize /2) - ($this->objectbuffer[$dirk]['OUTER-HEIGHT']/2);
5177 }
5178 else if ($va == 'TB') {
5179 $yadj += $af + $this->linemaxfontsize - $this->objectbuffer[$dirk]['OUTER-HEIGHT'];
5180 }
5181 else if ($va == 'TT') {
5182 $yadj += $af;
5183 }
5184 else if ($va == 'B') {
5185 $yadj += $af + $this->linemaxfontsize + $bf - $this->objectbuffer[$dirk]['OUTER-HEIGHT'];
5186 }
5187 else if ($va == 'T') {
5188 $yadj += 0;
5189 }
5190 $this->objectbuffer[$dirk]['OUTER-Y'] += $yadj;
5191 $this->objectbuffer[$dirk]['BORDER-Y'] += $yadj;
5192 $this->objectbuffer[$dirk]['INNER-Y'] += $yadj;
5193 }
5194
5195
5196 // DIRECTIONALITY RTL
5197 if ((($blockdir == 'rtl') && ($contains_rtl )) || $all_rtl ) { $this->restoreFont( $font[ $arraysize-1 - $k ] ); }
5198 else { $this->restoreFont( $font[ $k ] ); }
5199
5200 // mPDF 5.6.13 Decimal alignment - set in _tableWrite
5201 if ($is_table && substr($align,0,1)=='D' && $k==0 ) {
5202 $dp = $this->decimal_align[substr($align,0,2)];
5203 $s = preg_split('/'.preg_quote($dp,'/').'/', $content[0], 2); // ? needs to be /u if not core
5204 $s0 = $this->GetStringWidth($s[0], false);
5205 $this->x += ($this->decimal_offset - $s0);
5206 }
5207
5208 $this->SetSpacing(($this->fixedlSpacing*_MPDFK)+$jcharspacing,($this->fixedlSpacing+$this->minwSpacing)*_MPDFK+$jws);
5209 $this->fixedlSpacing = false;
5210 $this->minwSpacing = 0;
5211
5212 // mPDF 5.6.26
5213 $save_vis = $this->visibility;
5214 if (isset($this->textparam['visibility']) && $this->textparam['visibility'] && $this->textparam['visibility'] != $this->visibility) {
5215 $this->SetVisibility($this->textparam['visibility']);
5216 }
5217
5218 // *********** SPAN BACKGROUND COLOR ***************** //
5219 if (isset($this->spanbgcolor) && $this->spanbgcolor) {
5220 $cor = $this->spanbgcolorarray;
5221 $this->SetFColor($cor);
5222 $save_fill = $fill; $spanfill = 1; $fill = 1;
5223 }
5224 if (!empty($this->spanborddet)) {
5225 if (strpos($contentB[$k],'L')!==false && isset($this->spanborddet['L'])) $this->x += $this->spanborddet['L']['w'];
5226 if (strpos($contentB[$k],'L')===false) $this->spanborddet['L']['s'] = $this->spanborddet['L']['w'] = 0;
5227 if (strpos($contentB[$k],'R')===false) $this->spanborddet['R']['s'] = $this->spanborddet['R']['w'] = 0;
5228 }
5229 // WORD SPACING
5230 $stringWidth = $this->GetStringWidth($chunk ) + ( $this->charspacing * mb_strlen($chunk,$this->mb_enc ) / _MPDFK )
5231 + ( $this->ws * mb_substr_count($chunk,' ',$this->mb_enc ) / _MPDFK );
5232 if (isset($this->objectbuffer[$dirk])) {
5233 if ($this->objectbuffer[$dirk]['type']=='dottab') {
5234 $this->objectbuffer[$dirk]['OUTER-WIDTH'] +=$empty;
5235 $this->objectbuffer[$dirk]['OUTER-WIDTH'] +=$this->objectbuffer[$dirk]['outdent']; // mPDF 5.6.19
5236 }
5237 $stringWidth = $this->objectbuffer[$dirk]['OUTER-WIDTH'];
5238 }
5239
5240 if ($stringWidth==0) { $stringWidth = 0.000001; }
5241 if ($k == $arraysize-1) {
5242 // mPDF 5.6.40
5243 if ($this->checkCJK && $CJKoverflow && $align=='J' && $this->allowCJKoverflow && $hanger && $this->CJKforceend) {
5244 // force-end overhang
5245 $this->Cell( $stringWidth, $lineHeight, $chunk, '', 0, '', $fill, $this->HREF, $currentx,0,0,'M', $fill, $af, $bf, true );
5246 $this->Cell( $this->GetStringWidth($hanger), $lineHeight, $hanger, '', 1, '', $fill, $this->HREF, $currentx,0,0,'M', $fill, $af, $bf, true );
5247 }
5248 else {
5249 $this->Cell( $stringWidth, $lineHeight, $chunk, '', 1, '', $fill, $this->HREF, $currentx,0,0,'M', $fill, $af, $bf, true );
5250 }
5251 }
5252 else $this->Cell( $stringWidth, $lineHeight, $chunk, '', 0, '', $fill, $this->HREF, 0, 0,0,'M', $fill, $af, $bf, true );//first or middle part
5253
5254
5255 if (!empty($this->spanborddet)) {
5256 if (strpos($contentB[$k],'R')!==false && $k != $arraysize-1) $this->x += $this->spanborddet['R']['w'];
5257 }
5258 // *********** SPAN BACKGROUND COLOR OFF - RESET BLOCK BGCOLOR ***************** //
5259 if (isset($spanfill) && $spanfill) {
5260 $fill = $save_fill; $spanfill = 0;
5261 if ($fill) { $this->SetFColor($bcor); }
5262 }
5263 // mPDF 5.6.26
5264 if (isset($this->textparam['visibility']) && $this->textparam['visibility'] && $this->visibility != $save_vis) {
5265 $this->SetVisibility($save_vis);
5266 }
5267
5268 }
5269
5270 $this->printobjectbuffer($is_table, $blockdir);
5271
5272 $this->objectbuffer = array();
5273
5274 $this->ResetSpacing();
5275
5276/*-- LISTS --*/
5277 // LIST BULLETS/NUMBERS
5278 if ($is_list && is_array($this->bulletarray) && ($lineCount == 0) ) {
5279
5280 $savedFont = $this->saveFont();
5281
5282 $bull = $this->bulletarray;
5283 if (isset($bull['level']) && isset($bull['occur']) && isset($this->InlineProperties['LIST'][$bull['level']][$bull['occur']])) {
5284 $this->restoreInlineProperties($this->InlineProperties['LIST'][$bull['level']][$bull['occur']]);
5285 }
5286 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']]); }
5287 if (isset($bull['font']) && $bull['font'] == 'czapfdingbats') {
5288 $this->bullet = true;
5289 $this->SetFont('czapfdingbats','',$this->FontSizePt/2.5);
5290 }
5291 else { $this->SetFont($this->FontFamily,$this->FontStyle,$this->FontSizePt,true,true); } // force output
5292 //Output bullet
5293 $this->x = $currentx;
5294 if (isset($bull['x'])) { $this->x += $bull['x']; }
5295 $this->y -= $lineHeight;
5296 if (isset($bull['col']) && $bull['col']) { $this->SetTColor($bull['col']); } // mPDF 5.6.67
5297
5298 if (isset($bull['txt'])) { $this->Cell($bull['w'], $lineHeight,$bull['txt'],'','',$bull['align'],0,'',0,-$this->cMarginL, -$this->cMarginR ); }
5299 if (isset($bull['font']) && $bull['font'] == 'czapfdingbats') {
5300 $this->bullet = false;
5301 }
5302 $this->x = $currentx; // Reset
5303 $this->y += $lineHeight;
5304
5305 if ($this->ColActive && !$is_table) { $this->breakpoints[$this->CurrCol][] = $this->y; } // *COLUMNS*
5306
5307 $this->restoreFont( $savedFont );
5308 // $font = array( $savedFont );
5309
5310 $this->bulletarray = array(); // prevents repeat of bullet/number if <li>....<br />.....</li>
5311 }
5312/*-- END LISTS --*/
5313
5314
5315 } // END IF CONTENT
5316
5317/*-- CSS-IMAGE-FLOAT --*/
5318 // Update values if set to skipline
5319 if ($this->floatmargins) { $this->_advanceFloatMargins(); }
5320
5321
5322 if ($endofblock && $blockstate>1) {
5323 // If float exists at this level
5324 if (isset($this->floatmargins['R']['y1'])) { $fry1 = $this->floatmargins['R']['y1']; }
5325 else { $fry1 = 0; }
5326 if (isset($this->floatmargins['L']['y1'])) { $fly1 = $this->floatmargins['L']['y1']; }
5327 else { $fly1 = 0; }
5328 if ($this->y < $fry1 || $this->y < $fly1) {
5329 $drop = max($fry1,$fly1) - $this->y;
5330 $this->DivLn($drop);
5331 $this->x = $currentx;
5332 }
5333 }
5334/*-- END CSS-IMAGE-FLOAT --*/
5335
5336
5337 // PADDING and BORDER spacing/fill
5338 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)) {
5339 // If CSS height set, extend bottom - if on same page as block started, and CSS HEIGHT > actual height,
5340 // and does not force pagebreak
5341 $extra = 0;
5342 if ($this->blk[$this->blklvl]['css_set_height'] && $this->blk[$this->blklvl]['startpage']==$this->page) {
5343 // predicted height
5344 $h1 = ($this->y-$this->blk[$this->blklvl]['y0']) + $this->blk[$this->blklvl]['padding_bottom'] + $this->blk[$this->blklvl]['border_bottom']['w'];
5345 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; }
5346 if($this->y + $this->blk[$this->blklvl]['padding_bottom'] + $this->blk[$this->blklvl]['border_bottom']['w'] + $extra > $this->PageBreakTrigger) {
5347 $extra = $this->PageBreakTrigger - ($this->y + $this->blk[$this->blklvl]['padding_bottom'] + $this->blk[$this->blklvl]['border_bottom']['w']);
5348 }
5349 }
5350
5351 // $state = 0 normal; 1 top; 2 bottom; 3 top and bottom
5352 $this->DivLn($this->blk[$this->blklvl]['padding_bottom'] + $this->blk[$this->blklvl]['border_bottom']['w'] + $extra,-3,true,false,2);
5353 $this->x = $currentx;
5354
5355 if ($this->ColActive) { $this->breakpoints[$this->CurrCol][] = $this->y; } // *COLUMNS*
5356
5357 }
5358
5359 // SET Bottom y1 of block (used for painting borders)
5360 if (($endofblock) && ($blockstate > 1) && (!$is_table) && (!$is_list)) {
5361 $this->blk[$this->blklvl]['y1'] = $this->y;
5362 }
5363
5364 // BOTTOM MARGIN
5365 if (($endofblock) && ($blockstate > 1) && ($this->blk[$this->blklvl]['margin_bottom']) && (!$is_table) && (!$is_list)) {
5366 if($this->y+$this->blk[$this->blklvl]['margin_bottom'] < $this->PageBreakTrigger and !$this->InFooter) {
5367 $this->DivLn($this->blk[$this->blklvl]['margin_bottom'],$this->blklvl-1,true,$this->blk[$this->blklvl]['margin_collapse']);
5368 if ($this->ColActive) { $this->breakpoints[$this->CurrCol][] = $this->y; } // *COLUMNS*
5369 }
5370 }
5371
5372 // Reset lineheight
5373 $lineHeight = $this->divheight;
5374}
5375
5376
5377
5378
5379
5380function printobjectbuffer($is_table=false, $blockdir=false) {
5381 if (!$blockdir) { $blockdir = $this->directionality; }
5382 if ($is_table && $this->shrin_k > 1) { $k = $this->shrin_k; }
5383 else { $k = 1; }
5384 $save_y = $this->y;
5385 $save_x = $this->x;
5386 $save_currentfontfamily = $this->FontFamily;
5387 $save_currentfontsize = $this->FontSizePt;
5388 $save_currentfontstyle = $this->FontStyle.($this->U ? 'U' : '').($this->S ? 'S' : '');
5389 if ($blockdir == 'rtl') { $rtlalign = 'R'; } else { $rtlalign = 'L'; }
5390 foreach ($this->objectbuffer AS $ib => $objattr) {
5391 if ($objattr['type'] == 'bookmark' || $objattr['type'] == 'indexentry' || $objattr['type'] == 'toc') {
5392 $x = $objattr['OUTER-X'];
5393 $y = $objattr['OUTER-Y'];
5394 $this->y = $y - $this->FontSize/2;
5395 $this->x = $x;
5396 if ($objattr['type'] == 'bookmark' ) { $this->Bookmark($objattr['CONTENT'],$objattr['bklevel'] ,$y - $this->FontSize); } // *BOOKMARKS*
5397 if ($objattr['type'] == 'indexentry') { $this->IndexEntry($objattr['CONTENT']); } // *INDEX*
5398 if ($objattr['type'] == 'toc') { $this->TOC_Entry($objattr['CONTENT'], $objattr['toclevel'], $objattr['toc_id']); } // *TOC*
5399 }
5400/*-- ANNOTATIONS --*/
5401 else if ($objattr['type'] == 'annot') {
5402 if ($objattr['POS-X']) { $x = $objattr['POS-X']; }
5403 else if ($this->annotMargin<>0) { $x = -$objattr['OUTER-X']; }
5404 else { $x = $objattr['OUTER-X']; }
5405 if ($objattr['POS-Y']) { $y = $objattr['POS-Y']; }
5406 else { $y = $objattr['OUTER-Y'] - $this->FontSize/2; }
5407 // Create a dummy entry in the _out/columnBuffer with position sensitive data,
5408 // linking $y-1 in the Columnbuffer with entry in $this->columnAnnots
5409 // and when columns are split in length will not break annotation from current line
5410 $this->y = $y-1;
5411 $this->x = $x-1;
5412 $this->Line($x-1,$y-1,$x-1,$y-1);
5413 $this->Annotation($objattr['CONTENT'], $x , $y , $objattr['ICON'], $objattr['AUTHOR'], $objattr['SUBJECT'], $objattr['OPACITY'], $objattr['COLOR'], $objattr['POPUP'], $objattr['FILE']);
5414 }
5415/*-- END ANNOTATIONS --*/
5416 else {
5417 $y = $objattr['OUTER-Y'];
5418 $x = $objattr['OUTER-X'];
5419 $w = $objattr['OUTER-WIDTH'];
5420 $h = $objattr['OUTER-HEIGHT'];
5421 if (isset($objattr['text'])) { $texto = $objattr['text']; }
5422 $this->y = $y;
5423 $this->x = $x;
5424 if (isset($objattr['fontfamily'])) { $this->SetFont($objattr['fontfamily'],'',$objattr['fontsize'] ); }
5425 }
5426
5427 // HR
5428 if ($objattr['type'] == 'hr') {
5429 $this->SetDColor($objattr['color']);
5430 switch($objattr['align']) {
5431 case 'C':
5432 $empty = $objattr['OUTER-WIDTH'] - $objattr['INNER-WIDTH'];
5433 $empty /= 2;
5434 $x += $empty;
5435 break;
5436 case 'R':
5437 $empty = $objattr['OUTER-WIDTH'] - $objattr['INNER-WIDTH'];
5438 $x += $empty;
5439 break;
5440 }
5441 $oldlinewidth = $this->LineWidth;
5442 $this->SetLineWidth($objattr['linewidth']/$k );
5443 $this->y += ($objattr['linewidth']/2) + $objattr['margin_top']/$k;
5444 $this->Line($x,$this->y,$x+$objattr['INNER-WIDTH'],$this->y);
5445 $this->SetLineWidth($oldlinewidth);
5446 $this->SetDColor($this->ConvertColor(0));
5447 }
5448 // IMAGE
5449 if ($objattr['type'] == 'image') {
5450 // mPDF 5.6.01 - LAYERS
5451 if (isset($objattr['z-index']) && $objattr['z-index'] > 0 && $this->currentlayer==0) {
5452 $this->BeginLayer($objattr['z-index']);
5453 }
5454 if(isset($objattr['visibility']) && $objattr['visibility']!='visible' && $objattr['visibility']) {
5455 $this->SetVisibility($objattr['visibility']);
5456 }
5457 if (isset($objattr['opacity'])) { $this->SetAlpha($objattr['opacity']); }
5458 $rotate = 0;
5459 $obiw = $objattr['INNER-WIDTH'];
5460 $obih = $objattr['INNER-HEIGHT'];
5461 $sx = $objattr['INNER-WIDTH']*_MPDFK / $objattr['orig_w'];
5462 $sy = abs($objattr['INNER-HEIGHT'])*_MPDFK / abs($objattr['orig_h']);
5463 $sx = ($objattr['INNER-WIDTH']*_MPDFK / $objattr['orig_w']);
5464 $sy = ($objattr['INNER-HEIGHT']*_MPDFK / $objattr['orig_h']);
5465
5466 if (isset($objattr['ROTATE'])) { $rotate = $objattr['ROTATE']; }
5467 if ($rotate==90) {
5468 // Clockwise
5469 $obiw = $objattr['INNER-HEIGHT'];
5470 $obih = $objattr['INNER-WIDTH'];
5471 $tr = $this->transformTranslate(0, -$objattr['INNER-WIDTH'], true) ;
5472 $tr .= ' '. $this->transformRotate(90, $objattr['INNER-X'],($objattr['INNER-Y'] +$objattr['INNER-WIDTH'] ),true) ;
5473 $sx = $obiw*_MPDFK / $objattr['orig_h'];
5474 $sy = $obih*_MPDFK / $objattr['orig_w'];
5475 }
5476 else if ($rotate==-90 || $rotate==270) {
5477 // AntiClockwise
5478 $obiw = $objattr['INNER-HEIGHT'];
5479 $obih = $objattr['INNER-WIDTH'];
5480 $tr = $this->transformTranslate($objattr['INNER-WIDTH'], ($objattr['INNER-HEIGHT']-$objattr['INNER-WIDTH']), true) ;
5481 $tr .= ' '. $this->transformRotate(-90, $objattr['INNER-X'],($objattr['INNER-Y'] +$objattr['INNER-WIDTH'] ),true) ;
5482 $sx = $obiw*_MPDFK / $objattr['orig_h'];
5483 $sy = $obih*_MPDFK / $objattr['orig_w'];
5484 }
5485 else if ($rotate==180) {
5486 // Mirror
5487 $tr = $this->transformTranslate($objattr['INNER-WIDTH'], -$objattr['INNER-HEIGHT'], true) ;
5488 $tr .= ' '. $this->transformRotate(180, $objattr['INNER-X'],($objattr['INNER-Y'] +$objattr['INNER-HEIGHT'] ),true) ;
5489 }
5490 else { $tr = ''; }
5491 $tr = trim($tr);
5492 if ($tr) { $tr .= ' '; }
5493 $gradmask = '';
5494
5495
5496/*-- BACKGROUNDS --*/
5497 if (isset($objattr['GRADIENT-MASK'])) {
5498 $g = $this->grad->parseMozGradient( $objattr['GRADIENT-MASK'] );
5499 if ($g) {
5500 $dummy = $this->grad->Gradient($objattr['INNER-X'], $objattr['INNER-Y'], $obiw, $obih, $g['type'], $g['stops'], $g['colorspace'], $g['coords'], $g['extend'], true, true);
5501 $gradmask = '/TGS'.count($this->gradients).' gs ';
5502 // $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");
5503 }
5504 }
5505/*-- END BACKGROUNDS --*/
5506/*-- IMAGES-WMF --*/
5507 if (isset($objattr['itype']) && $objattr['itype']=='wmf') {
5508 $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']);
5509 }
5510 else
5511/*-- END IMAGES-WMF --*/
5512 if (isset($objattr['itype']) && $objattr['itype']=='svg') {
5513 $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']);
5514 }
5515 else {
5516 $outstring = sprintf("q ".$tr."%.3F 0 0 %.3F %.3F %.3F cm ".$gradmask."/I%d Do Q",$obiw*_MPDFK, $obih*_MPDFK, $objattr['INNER-X'] *_MPDFK, ($this->h-($objattr['INNER-Y'] +$obih ))*_MPDFK,$objattr['ID'] );
5517 }
5518 $this->_out($outstring);
5519 // LINK
5520 if (isset($objattr['link'])) $this->Link($objattr['INNER-X'],$objattr['INNER-Y'],$objattr['INNER-WIDTH'],$objattr['INNER-HEIGHT'],$objattr['link']);
5521 if (isset($objattr['opacity'])) { $this->SetAlpha(1); }
5522 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); }
5523 if(isset($objattr['visibility']) && $objattr['visibility']!='visible' && $objattr['visibility']) {
5524 $this->SetVisibility('visible');
5525 }
5526 // mPDF 5.6.01 - LAYERS
5527 if (isset($objattr['z-index']) && $objattr['z-index'] > 0 && $this->currentlayer==0) {
5528 $this->EndLayer();
5529 }
5530
5531 }
5532
5533/*-- BARCODES --*/
5534 // BARCODE
5535 if ($objattr['type'] == 'barcode') {
5536 $bgcol = $this->ConvertColor(255);
5537 if (isset($objattr['bgcolor']) && $objattr['bgcolor']) {
5538 $bgcol = $objattr['bgcolor'];
5539 }
5540 $col = $this->ConvertColor(0);
5541 if (isset($objattr['color']) && $objattr['color']) {
5542 $col = $objattr['color'];
5543 }
5544 $this->SetFColor($bgcol);
5545 $this->Rect($objattr['BORDER-X'], $objattr['BORDER-Y'], $objattr['BORDER-WIDTH'], $objattr['BORDER-HEIGHT'], 'F');
5546 $this->SetFColor($this->ConvertColor(255));
5547 if (isset($objattr['BORDER-WIDTH'])) { $this->PaintImgBorder($objattr,$is_table); }
5548 if ($objattr['btype'] == 'EAN13' || $objattr['btype'] == 'ISBN' || $objattr['btype'] == 'ISSN' || $objattr['btype'] == 'UPCA' || $objattr['btype'] == 'UPCE' || $objattr['btype'] == 'EAN8') {
5549 $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);
5550 }
5551 // QR-code
5552 else if ($objattr['btype']=='QR') {
5553 if (!class_exists('QRcode', false)) {
5554 include(_MPDF_PATH.'qrcode/qrcode.class.php');
5555 }
5556 $this->qrcode = new QRcode($objattr['code'], $objattr['errorlevel']);
5557 $this->qrcode->displayFPDF($this, $objattr['INNER-X'], $objattr['INNER-Y'], $objattr['bsize']*25, array(255,255,255), array(0,0,0));
5558 }
5559 else {
5560 $this->WriteBarcode2($objattr['code'], $objattr['INNER-X'], $objattr['INNER-Y'], $objattr['bsize'], $objattr['bheight'], $bgcol, $col, $objattr['btype'], $objattr['pr_ratio'], $k);
5561 }
5562 }
5563/*-- END BARCODES --*/
5564
5565 // TEXT CIRCLE
5566 if ($objattr['type'] == 'textcircle') {
5567 $bgcol = ''; // mPDF 5.5.14
5568 if (isset($objattr['bgcolor']) && $objattr['bgcolor']) {
5569 $bgcol = $objattr['bgcolor'];
5570 }
5571 $col = $this->ConvertColor(0);
5572 if (isset($objattr['color']) && $objattr['color']) {
5573 $col = $objattr['color'];
5574 }
5575 $this->SetTColor($col);
5576 $this->SetFColor($bgcol);
5577 if ($bgcol) $this->Rect($objattr['BORDER-X'], $objattr['BORDER-Y'], $objattr['BORDER-WIDTH'], $objattr['BORDER-HEIGHT'], 'F'); // mPDF 5.5.14
5578 $this->SetFColor($this->ConvertColor(255));
5579 if (isset($objattr['BORDER-WIDTH'])) { $this->PaintImgBorder($objattr,$is_table); }
5580 if (!class_exists('directw', false)) { include(_MPDF_PATH.'classes/directw.php'); }
5581 if (empty($this->directw)) { $this->directw = new directw($this); }
5582 $save_lmfs = $this->linemaxfontsize;
5583 $this->linemaxfontsize = 0;
5584 if (isset($objattr['top-text'])) {
5585 $this->directw->CircularText($objattr['INNER-X']+$objattr['INNER-WIDTH']/2, $objattr['INNER-Y']+$objattr['INNER-HEIGHT']/2, $objattr['r']/$k, $objattr['top-text'], 'top', $objattr['fontfamily'], $objattr['fontsize']/$k, $objattr['fontstyle'], $objattr['space-width'], $objattr['char-width'], $objattr['divider']); // mPDF 5.5.23
5586 }
5587 if (isset($objattr['bottom-text'])) {
5588 $this->directw->CircularText($objattr['INNER-X']+$objattr['INNER-WIDTH']/2, $objattr['INNER-Y']+$objattr['INNER-HEIGHT']/2, $objattr['r']/$k, $objattr['bottom-text'], 'bottom', $objattr['fontfamily'], $objattr['fontsize']/$k, $objattr['fontstyle'], $objattr['space-width'], $objattr['char-width'], $objattr['divider']); // mPDF 5.5.23
5589 }
5590 $this->linemaxfontsize = $save_lmfs;
5591 }
5592
5593 $this->ResetSpacing();
5594
5595 // DOT-TAB
5596 if ($objattr['type'] == 'dottab') {
5597 // mPDF 5.6.19
5598 if (isset($objattr['fontfamily'])) { $this->SetFont($objattr['fontfamily'],'',$objattr['fontsize'] ); }
5599 $sp = $this->GetStringWidth(' ');
5600 $nb=floor(($w-2*$sp)/$this->GetStringWidth('.'));
5601 if ($nb>0) { $dots=' '.str_repeat('.',$nb).' '; }
5602 else { $dots=' '; }
5603 $col = $this->ConvertColor(0);
5604 if (isset($objattr['colorarray']) && ($objattr['colorarray'])) { // mPDF 5.6.19
5605 $col = $objattr['colorarray'];
5606 }
5607 $this->SetTColor($col);
5608 $save_dh = $this->divheight; // mPDF 5.6.19
5609 $save_sbd = $this->spanborddet;
5610 $save_u = $this->U;
5611 $save_s = $this->strike;
5612 $this->spanborddet = '';
5613 $this->divheight = 0; // mPDF 5.6.19
5614 $this->U = false;
5615 $this->strike = false;
5616 $this->Cell($w,$h,$dots,0,0,'C');
5617 $this->spanborddet = $save_sbd;
5618 $this->U = $save_u;
5619 $this->strike = $save_s;
5620 $this->divheight = $save_dh; // mPDF 5.6.19
5621 // mPDF 5.0
5622 $this->SetTColor($this->ConvertColor(0));
5623 }
5624
5625/*-- FORMS --*/
5626 // TEXT/PASSWORD INPUT
5627 if ($objattr['type'] == 'input' && ($objattr['subtype'] == 'TEXT' || $objattr['subtype'] == 'PASSWORD')) {
5628 $this->form->print_ob_text($objattr,$w,$h,$texto,$rtlalign,$k,$blockdir);
5629 }
5630
5631 // TEXTAREA
5632 if ($objattr['type'] == 'textarea') {
5633 $this->form->print_ob_textarea($objattr,$w,$h,$texto,$rtlalign,$k,$blockdir);
5634 }
5635
5636 // SELECT
5637 if ($objattr['type'] == 'select') {
5638 $this->form->print_ob_select($objattr,$w,$h,$texto,$rtlalign,$k,$blockdir);
5639 }
5640
5641
5642 // INPUT/BUTTON as IMAGE
5643 if ($objattr['type'] == 'input' && $objattr['subtype'] == 'IMAGE') {
5644 $this->form->print_ob_imageinput($objattr,$w,$h,$texto,$rtlalign,$k,$blockdir);
5645 }
5646
5647 // BUTTON
5648 if ($objattr['type'] == 'input' && ($objattr['subtype'] == 'SUBMIT' || $objattr['subtype'] == 'RESET' || $objattr['subtype'] == 'BUTTON')) {
5649 $this->form->print_ob_button($objattr,$w,$h,$texto,$rtlalign,$k,$blockdir);
5650 }
5651
5652 // CHECKBOX
5653 if ($objattr['type'] == 'input' && ($objattr['subtype'] == 'CHECKBOX')) {
5654 $this->form->print_ob_checkbox($objattr,$w,$h,$texto,$rtlalign,$k,$blockdir,$x,$y);
5655 }
5656 // RADIO
5657 if ($objattr['type'] == 'input' && ($objattr['subtype'] == 'RADIO')) {
5658 $this->form->print_ob_radio($objattr,$w,$h,$texto,$rtlalign,$k,$blockdir,$x,$y);
5659 }
5660/*-- END FORMS --*/
5661 }
5662 $this->SetFont($save_currentfontfamily,$save_currentfontstyle,$save_currentfontsize);
5663 $this->y = $save_y;
5664 $this->x = $save_x;
5665 unset($content);
5666}
5667
5668
5669function WriteFlowingBlock( $s)
5670{
5671 $currentx = $this->x;
5672 $is_table = $this->flowingBlockAttr[ 'is_table' ];
5673 $is_list = $this->flowingBlockAttr[ 'is_list' ];
5674 // width of all the content so far in points
5675 $contentWidth =& $this->flowingBlockAttr[ 'contentWidth' ];
5676 // cell width in points
5677 $maxWidth =& $this->flowingBlockAttr[ 'width' ];
5678 $lineCount =& $this->flowingBlockAttr[ 'lineCount' ];
5679 // line height in user units
5680 $lineHeight =& $this->flowingBlockAttr[ 'height' ];
5681 $align =& $this->flowingBlockAttr[ 'align' ];
5682 $content =& $this->flowingBlockAttr[ 'content' ];
5683 $contentB =& $this->flowingBlockAttr[ 'contentB' ];
5684 $font =& $this->flowingBlockAttr[ 'font' ];
5685 $valign =& $this->flowingBlockAttr[ 'valign' ];
5686 $blockstate = $this->flowingBlockAttr[ 'blockstate' ];
5687
5688 $newblock = $this->flowingBlockAttr[ 'newblock' ];
5689 $blockdir = $this->flowingBlockAttr['blockdir'];
5690 // *********** BLOCK BACKGROUND COLOR ***************** //
5691 if ($this->blk[$this->blklvl]['bgcolor'] && !$is_table) {
5692 $fill = 0;
5693 }
5694 else {
5695 $this->SetFColor($this->ConvertColor(255));
5696 $fill = 0;
5697 }
5698 $font[] = $this->saveFont();
5699 $content[] = '';
5700 $contentB[] = '';
5701 $currContent =& $content[ count( $content ) - 1 ];
5702 // where the line should be cutoff if it is to be justified
5703 $cutoffWidth = $contentWidth;
5704
5705 $CJKoverflow = false;
5706 $hanger = ''; // mPDF 5.6.40
5707
5708 // COLS
5709 $oldcolumn = $this->CurrCol;
5710
5711 if ($this->ColActive && !$is_table) { $this->breakpoints[$this->CurrCol][] = $this->y; } // *COLUMNS*
5712
5713/*-- TABLES --*/
5714 if ($is_table) {
5715 $ipaddingL = 0;
5716 $ipaddingR = 0;
5717 $paddingL = 0;
5718 $paddingR = 0;
5719 $cpaddingadjustL = 0;
5720 $cpaddingadjustR = 0;
5721 // Added mPDF 3.0
5722 $fpaddingR = 0;
5723 $fpaddingL = 0;
5724 }
5725 else {
5726/*-- END TABLES --*/
5727 $ipaddingL = $this->blk[$this->blklvl]['padding_left'];
5728 $ipaddingR = $this->blk[$this->blklvl]['padding_right'];
5729 $paddingL = ($ipaddingL * _MPDFK);
5730 $paddingR = ($ipaddingR * _MPDFK);
5731 $this->cMarginL = $this->blk[$this->blklvl]['border_left']['w'];
5732 $cpaddingadjustL = -$this->cMarginL;
5733 $this->cMarginR = $this->blk[$this->blklvl]['border_right']['w'];
5734 $cpaddingadjustR = -$this->cMarginR;
5735 // Added mPDF 3.0 Float DIV
5736 $fpaddingR = 0;
5737 $fpaddingL = 0;
5738/*-- CSS-FLOAT --*/
5739 if (count($this->floatDivs)) {
5740 list($l_exists, $r_exists, $l_max, $r_max, $l_width, $r_width) = $this->GetFloatDivInfo($this->blklvl);
5741 if ($r_exists) { $fpaddingR = $r_width; }
5742 if ($l_exists) { $fpaddingL = $l_width; }
5743 }
5744/*-- END CSS-FLOAT --*/
5745
5746 $usey = $this->y + 0.002;
5747 if (($newblock) && ($blockstate==1 || $blockstate==3) && ($lineCount == 0) ) {
5748 $usey += $this->blk[$this->blklvl]['margin_top'] + $this->blk[$this->blklvl]['padding_top'] + $this->blk[$this->blklvl]['border_top']['w'];
5749 }
5750/*-- CSS-IMAGE-FLOAT --*/
5751 // If float exists at this level
5752 if (isset($this->floatmargins['R']) && $usey <= $this->floatmargins['R']['y1'] && $usey >= $this->floatmargins['R']['y0'] && !$this->floatmargins['R']['skipline']) { $fpaddingR += $this->floatmargins['R']['w']; }
5753 if (isset($this->floatmargins['L']) && $usey <= $this->floatmargins['L']['y1'] && $usey >= $this->floatmargins['L']['y0'] && !$this->floatmargins['L']['skipline']) { $fpaddingL += $this->floatmargins['L']['w']; }
5754/*-- END CSS-IMAGE-FLOAT --*/
5755 } // *TABLES*
5756
5757 //OBJECTS - IMAGES & FORM Elements (NB has already skipped line/page if required - in printbuffer)
5758 if (substr($s,0,3) == "\xbb\xa4\xac") { //identifier has been identified!
5759 $objattr = $this->_getObjAttr($s);
5760 $h_corr = 0;
5761 if ($is_table) { // *TABLES*
5762 $maximumW = ($maxWidth/_MPDFK) - ($this->cellPaddingL + $this->cMarginL + $this->cellPaddingR + $this->cMarginR); // *TABLES*
5763 } // *TABLES*
5764 else { // *TABLES*
5765 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']; }
5766 $maximumW = ($maxWidth/_MPDFK) - ($this->blk[$this->blklvl]['padding_left'] + $this->blk[$this->blklvl]['border_left']['w'] + $this->blk[$this->blklvl]['padding_right'] + $this->blk[$this->blklvl]['border_right']['w'] + $fpaddingL + $fpaddingR );
5767 } // *TABLES*
5768 $objattr = $this->inlineObject($objattr['type'],$this->lMargin + $fpaddingL + ($contentWidth/_MPDFK),($this->y + $h_corr), $objattr, $this->lMargin,($contentWidth/_MPDFK),$maximumW,$lineHeight,true,$is_table);
5769
5770 // SET LINEHEIGHT for this line ================ RESET AT END
5771 $lineHeight = MAX($lineHeight,$objattr['OUTER-HEIGHT']);
5772 $this->objectbuffer[count($content)-1] = $objattr;
5773 // if (isset($objattr['vertical-align'])) { $valign = $objattr['vertical-align']; }
5774 // else { $valign = ''; }
5775 $contentWidth += ($objattr['OUTER-WIDTH'] * _MPDFK);
5776 return;
5777 }
5778
5779 $lbw = $rbw = 0; // Border widths
5780 if (!empty($this->spanborddet)) {
5781 if (isset($this->spanborddet['L'])) $lbw = $this->spanborddet['L']['w'];
5782 if (isset($this->spanborddet['R'])) $rbw = $this->spanborddet['R']['w'];
5783 }
5784
5785 if ($this->usingCoreFont) {
5786 $tmp = strlen( $s );
5787 }
5788 else {
5789 $tmp = mb_strlen( $s, $this->mb_enc );
5790 }
5791
5792 // for every character in the string
5793 for ( $i = 0; $i < $tmp; $i++ ) {
5794 // extract the current character
5795 // get the width of the character in points
5796 if ($this->usingCoreFont) {
5797 $c = $s[$i];
5798 // Soft Hyphens chr(173)
5799 $cw = ($this->GetCharWidthCore($c) * _MPDFK);
5800 if ($this->kerning && $this->useKerning && $i > 0) {
5801 if (isset($this->CurrentFont['kerninfo'][$s[($i-1)]][$c])) {
5802 $cw += ($this->CurrentFont['kerninfo'][$s[($i-1)]][$c] * $this->FontSizePt / 1000 );
5803 }
5804 }
5805 }
5806 else {
5807 $c = mb_substr($s,$i,1,$this->mb_enc );
5808 $cw = ($this->GetCharWidthNonCore($c, false) * _MPDFK);
5809 if ($this->kerning && $this->useKerning && $i > 0) {
5810 $lastc = mb_substr($s,($i-1),1,$this->mb_enc );
5811 $ulastc = $this->UTF8StringToArray($lastc, false);
5812 $uc = $this->UTF8StringToArray($c, false);
5813 if (isset($this->CurrentFont['kerninfo'][$ulastc[0]][$uc[0]])) {
5814 $cw += ($this->CurrentFont['kerninfo'][$ulastc[0]][$uc[0]] * $this->FontSizePt / 1000 );
5815 }
5816 }
5817 }
5818
5819 if ($i==0) {
5820 $cw += $lbw*_MPDFK;
5821 $contentB[(count($contentB)-1)] .= 'L';
5822 }
5823 if ($i==($tmp-1)) {
5824 $cw += $rbw*_MPDFK;
5825 $contentB[(count($contentB)-1)] .= 'R';
5826 }
5827 // mPDF 5.6.45
5828 if ($c==' ') {
5829 $currContent .= $c;
5830 $cutoffWidth = $contentWidth;
5831 $contentWidth += $cw;
5832 continue;
5833 }
5834
5835 // ADDED for Paragraph_indent
5836 $WidthCorrection = 0;
5837 if (($newblock) && ($blockstate==1 || $blockstate==3) && isset($this->blk[$this->blklvl]['text_indent']) && ($lineCount == 0) && (!$is_table) && (!$is_list) && ($align != 'C')) {
5838 $ti = $this->ConvertSize($this->blk[$this->blklvl]['text_indent'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
5839 $WidthCorrection = ($ti*_MPDFK);
5840 }
5841
5842 // Added mPDF 3.0 Float DIV
5843 $fpaddingR = 0;
5844 $fpaddingL = 0;
5845/*-- CSS-FLOAT --*/
5846 if (count($this->floatDivs)) {
5847 list($l_exists, $r_exists, $l_max, $r_max, $l_width, $r_width) = $this->GetFloatDivInfo($this->blklvl);
5848 if ($r_exists) { $fpaddingR = $r_width; }
5849 if ($l_exists) { $fpaddingL = $l_width; }
5850 }
5851/*-- END CSS-FLOAT --*/
5852
5853 $usey = $this->y + 0.002;
5854 if (($newblock) && ($blockstate==1 || $blockstate==3) && ($lineCount == 0) ) {
5855 $usey += $this->blk[$this->blklvl]['margin_top'] + $this->blk[$this->blklvl]['padding_top'] + $this->blk[$this->blklvl]['border_top']['w'];
5856 }
5857
5858/*-- CSS-IMAGE-FLOAT --*/
5859 // If float exists at this level
5860 if (isset($this->floatmargins['R']) && $usey <= $this->floatmargins['R']['y1'] && $usey >= $this->floatmargins['R']['y0'] && !$this->floatmargins['R']['skipline']) { $fpaddingR += $this->floatmargins['R']['w']; }
5861 if (isset($this->floatmargins['L']) && $usey <= $this->floatmargins['L']['y1'] && $usey >= $this->floatmargins['L']['y0'] && !$this->floatmargins['L']['skipline']) { $fpaddingL += $this->floatmargins['L']['w']; }
5862/*-- END CSS-IMAGE-FLOAT --*/
5863
5864
5865
5866 // try adding another char
5867 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
5868 // it won't fit, output what we already have
5869 $lineCount++;
5870
5871 // contains any content that didn't make it into this print
5872 $savedContent = '';
5873 $savedContentB = '';
5874 $savedFont = array();
5875 $savedObj = array();
5876 // mPDF 5.6.20
5877 $savedPreContent = array();
5878 $savedPreContentB = array();
5879 $savedPreFont = array();
5880
5881 // cut off and save any partial words at the end of the string
5882 $words = explode( ' ', $currContent );
5883 ///////////////////
5884 // HYPHENATION
5885 $currWord = $words[count($words)-1] ;
5886 $success = false;
5887
5888 // mPDF 5.6.21 Hard Hyphens -
5889 $hardsuccess = false;
5890 if ($this->textparam['hyphens'] != 2 && preg_match("/\-/",$currWord)) {
5891 $rem = $maxWidth - $WidthCorrection - (($this->cMarginL+$this->cMarginR)*_MPDFK) - ($paddingL+$paddingR +(($fpaddingL + $fpaddingR) * _MPDFK) );
5892 list($hardsuccess,$pre,$post,$prelength) = $this->hardHyphenate($currWord, (($rem-$cutoffWidth)/_MPDFK -$this->GetCharWidth("-", false)) );
5893 if ($hardsuccess) {
5894 $already = array_pop( $words );
5895 $forward = mb_substr($already,$prelength+1,mb_strlen($already, $this->mb_enc), $this->mb_enc);
5896 $words[] = $pre.'-';
5897 $words[] = $forward;
5898 $currContent = mb_substr($currContent,0,mb_strlen($currContent, $this->mb_enc)+1-mb_strlen($post, $this->mb_enc), $this->mb_enc) . '-';
5899 }
5900 }
5901
5902/*-- HYPHENATION --*/
5903 // Soft Hyphens chr(173)
5904 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
5905 $rem = $maxWidth - $WidthCorrection - (($this->cMarginL+$this->cMarginR)*_MPDFK) - ($paddingL+$paddingR +(($fpaddingL + $fpaddingR) * _MPDFK) );
5906 list($success,$pre,$post,$prelength) = $this->softHyphenate($currWord, (($rem-$cutoffWidth)/_MPDFK -$this->GetCharWidth(" ", false)) );
5907 }
5908
5909 if (!$success && !$hardsuccess && $this->textparam['hyphens'] == 1 ) { // mPDF 5.6.06 // mPDF 5.6.21
5910 // Look ahead to get current word
5911 for($ac = $i; $ac<(mb_strlen($s)-1); $ac++) {
5912 $addc = mb_substr($s,$ac,1,$this->mb_enc );
5913 if ($addc == ' ') { break; }
5914 $currWord .= $addc;
5915 }
5916 $rem = $maxWidth - $WidthCorrection - (($this->cMarginL+$this->cMarginR)*_MPDFK) - ($paddingL+$paddingR +(($fpaddingL + $fpaddingR) * _MPDFK) );
5917 list($success,$pre,$post,$prelength) = $this->hyphenateWord($currWord, (($rem-$cutoffWidth)/_MPDFK -$this->GetCharWidth(" ", false)) );
5918 }
5919 if ($success) {
5920 $already = array_pop( $words );
5921 $forward = mb_substr($already,$prelength,mb_strlen($already, $this->mb_enc), $this->mb_enc);
5922 $words[] = $pre.'-';
5923 $words[] = $forward;
5924 $currContent = mb_substr($currContent,0,mb_strlen($currContent, $this->mb_enc)+1-mb_strlen($post, $this->mb_enc), $this->mb_enc) . '-';
5925 }
5926/*-- END HYPHENATION --*/
5927
5928 // mPDF 5.6.13 Decimal alignment (cancel if wraps to > 1 line)
5929 if ($is_table && substr($align,0,1)=='D' ) { $align=substr($align,2,1); }
5930
5931/*-- CJK-FONTS --*/
5932 // mPDF 5.6.42
5933 if ($this->checkCJK) {
5934 $lastchar = mb_substr($words[(count($words)-1)],mb_strlen($words[(count($words)-1)], $this->mb_enc)-1, 1, $this->mb_enc);
5935 }
5936 // Next character is suitable to add as overhanging or squeezed punctuation
5937 if ($this->checkCJK && preg_match("/[".$this->CJKoverflow."]/u", $c) && $this->allowCJKorphans && !$CJKoverflow) {
5938 // add character onto this line
5939 $currContent .= $c;
5940 $cutoffWidth = $contentWidth;
5941 $contentWidth += $cw;
5942 $CJKoverflow = true;
5943 continue;
5944 }
5945 // Last character that fits is not allowed to end a line - move lastchar(s) to start of next line
5946 else if ($this->checkCJK && preg_match("/[".$this->CJKleading."]/u", $lastchar)) {
5947 //move lastchar(s) to next line
5948 $m0 = $lastchar;
5949 $m1 = $c;
5950 while(preg_match("/[".$this->CJKleading."]/u", $m0) && mb_strlen($words[(count($words)-1)], $this->mb_enc)>2) {
5951 // trim last letter off word[0]
5952 $words[(count($words)-1)] = mb_substr($words[(count($words)-1)],0,mb_strlen($words[(count($words)-1)], $this->mb_enc)-1, $this->mb_enc);
5953 // and add it to savedContent for next line
5954 $savedContent = $m0.$savedContent;
5955 $m1 = $lastchar;
5956 $lastchar = mb_substr($words[(count($words)-1)],mb_strlen($words[(count($words)-1)], $this->mb_enc)-1, 1, $this->mb_enc);
5957 $m0 = $lastchar;
5958 }
5959 $lastContent = '';
5960 for ( $w = 0; $w < count( $words ) ; $w++) { $lastContent .= $words[ $w ]." "; }
5961 $savedFont = $this->saveFont();
5962 // replace the current content with the cropped version
5963 $currContent = rtrim( $lastContent );
5964 }
5965 // Next character is not allowed to start a new line
5966 else if ($this->checkCJK && preg_match("/[".$this->CJKfollowing."]/u", $c)) {
5967 // try squeezing another character(s) onto this line = Oikomi
5968 if ($this->allowCJKorphans && !$CJKoverflow) { // mPDF 5.6.40
5969 $lookahead = mb_substr($s,$i+1,1,$this->mb_enc );
5970 //if lookahead is not another following char
5971 if (!$lookahead || ($lookahead && !preg_match("/[".$this->CJKfollowing."]/u", $lookahead))) {
5972 $currContent .= $c;
5973 $cutoffWidth = $contentWidth;
5974 $contentWidth += $cw;
5975 if ($this->allowCJKoverflow && preg_match("/[".$this->CJKoverflow."]/u", $c)) { $CJKoverflow = true; }
5976 continue;
5977 }
5978 }
5979 // or move lastchar(s) to next line to keep $c company = Oidashi
5980 $m0 = $lastchar;
5981 $m1 = $c;
5982 while(preg_match("/[".$this->CJKfollowing."]/u", $m1) && mb_strlen($words[(count($words)-1)], $this->mb_enc)>2) {
5983 // trim last letter off word[0]
5984 $words[(count($words)-1)] = mb_substr($words[(count($words)-1)],0,mb_strlen($words[(count($words)-1)], $this->mb_enc)-1, $this->mb_enc);
5985 // and add it to savedContent for next line
5986 $savedContent = $m0.$savedContent;
5987 $m1 = $lastchar;
5988 $lastchar = mb_substr($words[(count($words)-1)],mb_strlen($words[(count($words)-1)], $this->mb_enc)-1, 1, $this->mb_enc);
5989 $m0 = $lastchar;
5990 }
5991 $lastContent = '';
5992 for ( $w = 0; $w < count( $words ) ; $w++) { $lastContent .= $words[ $w ]." "; }
5993 $savedFont = $this->saveFont();
5994 // replace the current content with the cropped version
5995 $currContent = rtrim( $lastContent );
5996 }
5997 // mPDF 5.6.42
5998 else if ($this->checkCJK && preg_match("/([".$this->pregCJKchars."]+[0-9\x{ff10}-\x{ff19}]+$)/u", $words[0])) {
5999 $lookahead = mb_substr($s,$i,16,$this->mb_enc );
6000 //and if lookahead starts with a few numerals
6001 if ($lookahead && (preg_match("/^([0-9\x{ff10}-\x{ff19}]+[".$this->pregCJKchars."]+)/u", $lookahead) || preg_match("/^([0-9\x{ff10}-\x{ff19}]+$)/u", $lookahead)) ) {
6002 // or move lastchar(s) to next line to keep numerals together
6003 $m0 = $lastchar;
6004 while(preg_match("/[0-9\x{ff10}-\x{ff19}]/u", $m0) && mb_strlen($words[(count($words)-1)], $this->mb_enc)>2) {
6005 // trim last letter off word[0]
6006 $words[(count($words)-1)] = mb_substr($words[(count($words)-1)],0,mb_strlen($words[(count($words)-1)], $this->mb_enc)-1, $this->mb_enc);
6007 // and add it to savedContent for next line
6008 $savedContent = $m0.$savedContent;
6009 $lastchar = mb_substr($words[(count($words)-1)],mb_strlen($words[(count($words)-1)], $this->mb_enc)-1, 1, $this->mb_enc);
6010 $m0 = $lastchar;
6011 }
6012 }
6013 $lastContent = '';
6014 for ( $w = 0; $w < count( $words ) ; $w++) { $lastContent .= $words[ $w ]." "; }
6015 $savedFont = $this->saveFont();
6016 // replace the current content with the cropped version
6017 $currContent = rtrim( $lastContent );
6018 }
6019 else
6020/*-- END CJK-FONTS --*/
6021 // if it looks like we didn't finish any words for this chunk
6022 if ( count( $words ) == 1 ) {
6023 // TO correct for error when word too wide for page - but only when one long word from left to right margin
6024 if (count($content) == 1 && $currContent != ' ') {
6025 $lastchar = mb_substr($words[0],mb_strlen($words[0], $this->mb_enc)-1, 1, $this->mb_enc);
6026 $lastContent = $words[0];
6027 $savedFont = $this->saveFont();
6028 // replace the current content with the cropped version
6029 $currContent = rtrim( $lastContent );
6030 }
6031 // mPDF 5.6.20
6032 else if ( count($content)>1
6033 && (!isset($this->objectbuffer[(count($content)-1)]) && !isset($this->objectbuffer[(count($content)-2)]))
6034 && substr($content[count($content)-2],-1,1) != ' '
6035 && substr($currContent,0,1) != ' '
6036 ) {
6037 // Go back to find a space in a previous chunk of content
6038 $found = false;
6039 for ($ix=count($content)-1;$ix>=0;$ix--) {
6040 // mPDF 5.6.29
6041 if ($this->usingCoreFont && preg_match('/[ '.chr(173).']/',$content[$ix],$m)) { $match = $m[0]; $found = $ix; break; }
6042 else if (!$this->usingCoreFont) {
6043 if (preg_match('/[ ]/',$content[$ix])) { $match = ' '; $found = $ix; break; }
6044 else if (preg_match('/[\x{00AD}]/u',$content[$ix])) {
6045 // even though it is UTF-8 replace it temporarily with chr(173)
6046 $content[$ix] = preg_replace('/[\x{00AD}]/u',chr(173),$content[$ix]);
6047 $match = chr(173); $found = $ix; break;
6048 }
6049 }
6050 }
6051 if ($found !== false) {
6052 $charpos = strrpos($content[$found],$match); // mPDF 5.6.29
6053 for ($ix=count($content)-1;$ix>$found;$ix--) {
6054 // save and crop off any subsequent chunks
6055 $savedPreContent[] = array_pop($content);
6056 $savedPreContentB[] = array_pop($contentB);
6057 $savedPreFont[] = array_pop($font);
6058 }
6059 if (substr($content[count($content)-1],$charpos+1,strlen($content[count($content)-1])-1) != '') {
6060 $savedPreContent[] = substr($content[count($content)-1],$charpos+1,strlen($content[count($content)-1])-1);
6061 $savedPreContentB[] = preg_replace('/L/','',$contentB[count($content)-1]); // ???
6062 $savedPreFont[] = $font[count($content)-1];
6063 }
6064 $savedContent = '';
6065 $savedContentB = '';
6066 $savedFont = array();
6067
6068 $currContent =& $content[ count( $content ) - 1 ];
6069 $currContent = substr($currContent,0,$charpos);
6070 if ($match == chr(173)) { $currContent .= '-'; } // mPDF 5.6.29
6071 if (strpos($contentB[(count($contentB)-1)],'R')!==false) { // ???
6072 $contentB[count($content)-1] = preg_replace('/R/','',$contentB[count($content)-1]); // ???
6073 }
6074
6075 $currContent = rtrim( $currContent );
6076 }
6077 else {
6078 $savedContent = array_pop( $content );
6079 $savedContentB = array_pop($contentB);
6080 $savedFont = array_pop( $font );
6081 $currContent =& $content[ count( $content ) - 1 ];
6082 $currContent = rtrim( $currContent );
6083 }
6084 }
6085 else {
6086 // save and crop off the content currently on the stack
6087 $savedContent = array_pop( $content );
6088 $savedContentB = array_pop($contentB); // mPDF 5.6.20
6089 $savedFont = array_pop( $font );
6090
6091 // mPDF 5.7.2
6092 // e.g: |first chunk |second chunk |[IndexEntry]|doesntfit
6093 if (isset($this->objectbuffer[(count($content)-1)]) && $this->objectbuffer[(count($content)-1)]['OUTER-WIDTH'] < 0.001) {
6094 $savedObj = $this->objectbuffer[(count($content)-1)];
6095 array_pop( $content );
6096 array_pop( $contentB );
6097 array_pop( $font );
6098 array_pop( $this->objectbuffer );
6099 }
6100
6101 // trim any trailing spaces off the last bit of content
6102 $currContent =& $content[ count( $content ) - 1 ];
6103 $currContent = rtrim( $currContent );
6104 }
6105 }
6106 else { // otherwise, we need to find which bit to cut off
6107 $lastContent = '';
6108 for ( $w = 0; $w < count( $words ) - 1; $w++) { $lastContent .= $words[ $w ]." "; }
6109 $savedContent = $words[ count( $words ) - 1 ];
6110 $savedFont = $this->saveFont();
6111 // replace the current content with the cropped version
6112 $currContent = rtrim( $lastContent );
6113 }
6114 // CJK - strip CJK space at end of line
6115 // &#x3000; = \xe3\x80\x80 = CJK space
6116 if ($this->checkCJK) { $currContent = preg_replace("/\xe3\x80\x80$/",'',$currContent) ; } // *CJK-FONTS*
6117
6118
6119 if (isset($this->objectbuffer[(count($content)-1)]) && $this->objectbuffer[(count($content)-1)]['type']=='dottab') {
6120 $savedObj = array_pop( $this->objectbuffer );
6121 $contentWidth -= ($this->objectbuffer[(count($content)-1)]['OUTER-WIDTH'] * _MPDFK);
6122 }
6123
6124 // Set Current lineheight (correction factor)
6125 $lhfixed = false;
6126/*-- LISTS --*/
6127 if ($is_list) {
6128 if (preg_match('/([0-9.,]+)mm/',$this->list_lineheight[$this->listlvl][$this->listOcc],$am)) {
6129 $lhfixed = true;
6130 $def_fontsize = $this->InlineProperties['LISTITEM'][$this->listlvl][$this->listOcc][$this->listnum]['size'];
6131 $this->lineheight_correction = $am[1] / $def_fontsize ;
6132 }
6133 else {
6134 $this->lineheight_correction = $this->list_lineheight[$this->listlvl][$this->listOcc];
6135 }
6136 }
6137 else
6138/*-- END LISTS --*/
6139/*-- TABLES --*/
6140 if ($is_table) {
6141 if (preg_match('/([0-9.,]+)mm/',$this->table_lineheight,$am)) {
6142 $lhfixed = true;
6143 $def_fontsize = $this->FontSize; // needs to be default font-size for block ****
6144 $this->lineheight_correction = $lineHeight / $def_fontsize ;
6145 }
6146 else {
6147 $this->lineheight_correction = $this->table_lineheight;
6148 }
6149 }
6150 else
6151/*-- END TABLES --*/
6152 if (isset($this->blk[$this->blklvl]['line_height']) && $this->blk[$this->blklvl]['line_height']) {
6153 if (preg_match('/([0-9.,]+)mm/',$this->blk[$this->blklvl]['line_height'],$am)) {
6154 $lhfixed = true;
6155 $def_fontsize = $this->blk[$this->blklvl]['InlineProperties']['size']; // needs to be default font-size for block ****
6156 $this->lineheight_correction = $am[1] / $def_fontsize ;
6157 }
6158 else {
6159 $this->lineheight_correction = $this->blk[$this->blklvl]['line_height'];
6160 }
6161 }
6162 else {
6163 $this->lineheight_correction = $this->normalLineheight;
6164 }
6165 // update $contentWidth and $cutoffWidth since they changed with cropping
6166 // Also correct lineheight to maximum fontsize (not for tables)
6167 $contentWidth = 0;
6168 // correct lineheight to maximum fontsize
6169 if ($lhfixed) { $maxlineHeight = $this->lineheight; }
6170 else { $maxlineHeight = 0; }
6171 $this->forceExactLineheight = true;
6172 $maxfontsize = 0;
6173 // While we're at it, check for cursive text
6174 $checkCursive=false;
6175 if ($this->biDirectional) { $checkCursive=true; } // *RTL*
6176 foreach ( $content as $k => $chunk )
6177 {
6178 $this->restoreFont( $font[ $k ]);
6179 if (!isset($this->objectbuffer[$k])) {
6180 // mPDF 5.6.40
6181 if ($this->checkCJK && $k == count($content)-1 && $CJKoverflow && $align=='J' && $this->allowCJKoverflow && $this->CJKforceend) {
6182 // force-end overhang
6183 $hanger = mb_substr($chunk,mb_strlen($chunk,$this->mb_enc)-1,1,$this->mb_enc );
6184 $content[$k] = $chunk = mb_substr($chunk,0,mb_strlen($chunk,$this->mb_enc)-1,$this->mb_enc );
6185 }
6186 if (!$this->usingCoreFont) {
6187 $content[$k] = $chunk = str_replace("\xc2\xad",'',$chunk );
6188 if (isset($this->CurrentFont['indic']) && $this->CurrentFont['indic']) { $checkCursive=true; } // *INDIC*
6189 }
6190 // Soft Hyphens chr(173)
6191 else if ($this->FontFamily!='csymbol' && $this->FontFamily!='czapfdingbats') {
6192 $content[$k] = $chunk = str_replace(chr(173),'',$chunk );
6193 }
6194 $contentWidth += $this->GetStringWidth( $chunk ) * _MPDFK;
6195 if (!empty($this->spanborddet)) {
6196 if (strpos($contentB[$k],'L')!==false) $contentWidth += $this->spanborddet['L']['w'] * _MPDFK;
6197 if (strpos($contentB[$k],'R')!==false) $contentWidth += $this->spanborddet['R']['w'] * _MPDFK;
6198 }
6199 if (!$lhfixed) { $maxlineHeight = max($maxlineHeight,$this->FontSize * $this->lineheight_correction ); }
6200 if ($lhfixed && ($this->FontSize > $def_fontsize || ($this->FontSize > ($lineHeight * $this->lineheight_correction) && $is_list))) {
6201 $this->forceExactLineheight = false;
6202 }
6203 $maxfontsize = max($maxfontsize,$this->FontSize);
6204 }
6205 }
6206
6207 $lastfontreqstyle = $font[count($font)-1]['ReqFontStyle'];
6208 $lastfontstyle = $font[count($font)-1]['style'];
6209 if ($blockdir == 'ltr' && strpos($lastfontreqstyle,"I") !== false && strpos($lastfontstyle,"I") === false) { // Artificial italic
6210 $lastitalic = $this->FontSize*0.15*_MPDFK;
6211 }
6212 else { $lastitalic = 0; }
6213
6214
6215/*-- LISTS --*/
6216 if ($is_list && is_array($this->bulletarray) && $this->bulletarray) {
6217 $actfs = $this->bulletarray['fontsize'];
6218 if (!$lhfixed) { $maxlineHeight = max($maxlineHeight,$actfs * $this->lineheight_correction ); }
6219 if ($lhfixed && $actfs > $def_fontsize) { $this->forceExactLineheight = false; }
6220 $maxfontsize = max($maxfontsize,$actfs);
6221 }
6222/*-- END LISTS --*/
6223
6224 // when every text item checked i.e. $maxfontsize is set properly
6225
6226 $af = 0; // Above font
6227 $bf = 0; // Below font
6228 $mta = 0; // Maximum top-aligned
6229 $mba = 0; // Maximum bottom-aligned
6230
6231 foreach ( $content as $k => $chunk ) {
6232 if (isset($this->objectbuffer[$k]) && $this->objectbuffer[$k]) {
6233 $contentWidth += $this->objectbuffer[$k]['OUTER-WIDTH'] * _MPDFK;
6234 $oh = $this->objectbuffer[$k]['OUTER-HEIGHT'];
6235 $va = $this->objectbuffer[$k]['vertical-align']; // = $objattr['vertical-align'] = set as M,T,B,S
6236 if ($lhfixed && $oh > $def_fontsize) { $this->forceExactLineheight = false; }
6237
6238 if ($va == 'BS') { // (BASELINE default)
6239 $af = max($af, ($oh - ($maxfontsize * (0.5 + $this->baselineC))));
6240 }
6241 else if ($va == 'M') {
6242 $af = max($af, ($oh - $maxfontsize)/2);
6243 $bf = max($bf, ($oh - $maxfontsize)/2);
6244 }
6245 else if ($va == 'TT') {
6246 $bf = max($bf, ($oh - $maxfontsize));
6247 }
6248 else if ($va == 'TB') {
6249 $af = max($af, ($oh - $maxfontsize));
6250 }
6251 else if ($va == 'T') {
6252 $mta = max($mta, $oh);
6253 }
6254 else if ($va == 'B') {
6255 $mba = max($mba, $oh);
6256 }
6257 }
6258 }
6259 if ((!$lhfixed || !$this->forceExactLineheight) && ($af > (($maxlineHeight - $maxfontsize)/2) || $bf > (($maxlineHeight - $maxfontsize)/2))) {
6260 $maxlineHeight = $maxfontsize + $af + $bf;
6261 }
6262 else if (!$lhfixed) { $af = $bf = ($maxlineHeight - $maxfontsize)/2; }
6263
6264 if ($mta > $maxlineHeight) {
6265 $bf += ($mta - $maxlineHeight);
6266 $maxlineHeight = $mta;
6267 }
6268 if ($mba > $maxlineHeight) {
6269 $af += ($mba - $maxlineHeight);
6270 $maxlineHeight = $mba;
6271 }
6272
6273
6274 $lineHeight = $maxlineHeight;
6275 $cutoffWidth = $contentWidth;
6276 // If NOT images, and maxfontsize NOT > lineHeight - this value determines text baseline positioning
6277 if ($lhfixed && $af==0 && $bf==0 && $maxfontsize<=($def_fontsize * $this->lineheight_correction * 0.8 )) {
6278 $this->linemaxfontsize = $def_fontsize;
6279 }
6280 else { $this->linemaxfontsize = $maxfontsize; }
6281
6282
6283 $inclCursive=false;
6284 foreach ( $content as $k => $chunk ) {
6285 if (!isset($this->objectbuffer[$k]) || (isset($this->objectbuffer[$k]) && !$this->objectbuffer[$k])) {
6286 if ($this->usingCoreFont) {
6287 $content[$k] = str_replace(chr(160),chr(32),$chunk );
6288 }
6289 else {
6290 $content[$k] = str_replace(chr(194).chr(160),chr(32),$chunk );
6291 if ($checkCursive) {
6292 if (preg_match("/([".$this->pregRTLchars."])/u", $chunk)) { $inclCursive = true; } // *RTL*
6293 if (preg_match("/([".$this->pregHIchars.$this->pregBNchars.$this->pregPAchars."])/u", $chunk)) { $inclCursive = true; } // *INDIC*
6294 }
6295 }
6296 }
6297 }
6298
6299 // JUSTIFICATION J
6300 $jcharspacing = 0;
6301 $jws = 0;
6302 $nb_carac = 0;
6303 $nb_spaces = 0;
6304 // 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)
6305 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
6306 // JUSTIFY J (Use character spacing)
6307 // WORD SPACING
6308 foreach ( $content as $k => $chunk ) {
6309 if (!isset($this->objectbuffer[$k]) || (isset($this->objectbuffer[$k]) && !$this->objectbuffer[$k])) {
6310 $nb_carac += mb_strlen( $chunk, $this->mb_enc ) ;
6311 $nb_spaces += mb_substr_count( $chunk,' ', $this->mb_enc ) ;
6312 }
6313 }
6314 list($jcharspacing,$jws) = $this->GetJspacing($nb_carac,$nb_spaces,($maxWidth-$lastitalic-$cutoffWidth-$WidthCorrection-(($this->cMarginL+$this->cMarginR)*_MPDFK)-($paddingL+$paddingR +(($fpaddingL + $fpaddingR) * _MPDFK) )),$inclCursive);
6315 }
6316
6317
6318 // WORD SPACING
6319 $empty = $maxWidth - $lastitalic-$WidthCorrection - $contentWidth - (($this->cMarginL+$this->cMarginR)* _MPDFK) - ($paddingL+$paddingR +(($fpaddingL + $fpaddingR) * _MPDFK) );
6320
6321 $empty -= ($jcharspacing * $nb_carac);
6322 $empty -= ($jws * $nb_spaces);
6323
6324 $empty /= _MPDFK;
6325 $b = ''; //do not use borders
6326 // Get PAGEBREAK TO TEST for height including the top border/padding
6327 $check_h = max($this->divheight,$lineHeight);
6328 if (($newblock) && ($blockstate==1 || $blockstate==3) && ($this->blklvl > 0) && ($lineCount == 1) && (!$is_table) && (!$is_list)) {
6329 $check_h += ($this->blk[$this->blklvl]['padding_top'] + $this->blk[$this->blklvl]['margin_top'] + $this->blk[$this->blklvl]['border_top']['w']);
6330 }
6331
6332 if ($this->ColActive && $check_h > ($this->PageBreakTrigger - $this->y0)) {
6333 $this->SetCol($this->NbCol-1);
6334 }
6335
6336 // PAGEBREAK
6337 // 'If' below used in order to fix "first-line of other page with justify on" bug
6338 if(!$is_table && ($this->y+$check_h) > $this->PageBreakTrigger and !$this->InFooter and $this->AcceptPageBreak()) {
6339 $bak_x=$this->x;//Current X position
6340
6341 // WORD SPACING
6342 $ws=$this->ws;//Word Spacing
6343 $charspacing=$this->charspacing;//Character Spacing
6344 $this->ResetSpacing();
6345
6346 $this->AddPage($this->CurOrientation);
6347
6348 $this->x = $bak_x;
6349 // Added to correct for OddEven Margins
6350 $currentx += $this->MarginCorrection;
6351 $this->x += $this->MarginCorrection;
6352
6353 // WORD SPACING
6354 $this->SetSpacing($charspacing,$ws);
6355 }
6356
6357 if ($this->keep_block_together && !$is_table && $this->kt_p00 < $this->page && ($this->y+$check_h) > $this->kt_y00) {
6358 $this->printdivbuffer();
6359 $this->keep_block_together = 0;
6360 }
6361
6362 if ($this->kwt && !$is_table) { // mPDF 5.7+
6363 $this->printkwtbuffer();
6364 $this->kwt = false;
6365 }
6366
6367/*-- COLUMNS --*/
6368 // COLS
6369 // COLUMN CHANGE
6370 if ($this->CurrCol != $oldcolumn) {
6371 $currentx += $this->ChangeColumn * ($this->ColWidth+$this->ColGap);
6372 $this->x += $this->ChangeColumn * ($this->ColWidth+$this->ColGap);
6373 $oldcolumn = $this->CurrCol;
6374 }
6375
6376 if ($this->ColActive && !$is_table) { $this->breakpoints[$this->CurrCol][] = $this->y; } // *COLUMNS*
6377/*-- END COLUMNS --*/
6378
6379 // TOP MARGIN
6380 if (($newblock) && ($blockstate==1 || $blockstate==3) && ($this->blk[$this->blklvl]['margin_top']) && ($lineCount == 1) && (!$is_table) && (!$is_list)) {
6381 $this->DivLn($this->blk[$this->blklvl]['margin_top'],$this->blklvl-1,true,$this->blk[$this->blklvl]['margin_collapse']);
6382 if ($this->ColActive) { $this->breakpoints[$this->CurrCol][] = $this->y; } // *COLUMNS*
6383 }
6384
6385
6386 // Update y0 for top of block (used to paint border)
6387 if (($newblock) && ($blockstate==1 || $blockstate==3) && ($lineCount == 1) && (!$is_table) && (!$is_list)) {
6388 $this->blk[$this->blklvl]['y0'] = $this->y;
6389 $this->blk[$this->blklvl]['startpage'] = $this->page;
6390 if ($this->blk[$this->blklvl]['float']) { $this->blk[$this->blklvl]['float_start_y'] = $this->y; } // mPDF 5.6.63
6391 }
6392
6393 // TOP PADDING and BORDER spacing/fill
6394 if (($newblock) && ($blockstate==1 || $blockstate==3) && (($this->blk[$this->blklvl]['padding_top']) || ($this->blk[$this->blklvl]['border_top'])) && ($lineCount == 1) && (!$is_table) && (!$is_list)) {
6395 // $state = 0 normal; 1 top; 2 bottom; 3 top and bottom
6396 $this->DivLn($this->blk[$this->blklvl]['padding_top'] + $this->blk[$this->blklvl]['border_top']['w'],-3,true,false,1);
6397 if ($this->ColActive) { $this->breakpoints[$this->CurrCol][] = $this->y; } // *COLUMNS*
6398 }
6399
6400 $arraysize = count($content);
6401
6402 $margins = ($this->cMarginL+$this->cMarginR) + ($ipaddingL+$ipaddingR + $fpaddingR + $fpaddingR );
6403
6404 // PAINT BACKGROUND FOR THIS LINE
6405 if (!$is_table) { $this->DivLn($lineHeight,$this->blklvl,false); } // false -> don't advance y
6406
6407 $this->x = $currentx + $this->cMarginL + $ipaddingL + $fpaddingL ;
6408 if ($align == 'R') { $this->x += $empty; }
6409 else if ($align == 'C') { $this->x += ($empty / 2); }
6410
6411 // Paragraph INDENT
6412 if (isset($this->blk[$this->blklvl]['text_indent']) && ($newblock) && ($blockstate==1 || $blockstate==3) && ($lineCount == 1) && (!$is_table) && ($blockdir !='rtl') && ($align !='C')) {
6413 $ti = $this->ConvertSize($this->blk[$this->blklvl]['text_indent'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
6414 $this->x += $ti;
6415 }
6416
6417 // DIRECTIONALITY RTL
6418 $all_rtl = false;
6419 $contains_rtl = false;
6420/*-- RTL --*/
6421 if ($blockdir == 'rtl' || $this->biDirectional) {
6422 $all_rtl = true;
6423 foreach ( $content as $k => $chunk ) {
6424 $reversed = $this->magic_reverse_dir($chunk, false, $blockdir);
6425
6426 if ($reversed > 0) { $contains_rtl = true; }
6427 if ($reversed < 2) { $all_rtl = false; }
6428 $content[$k] = $chunk;
6429 }
6430 if (($blockdir =='rtl' && $contains_rtl) || $all_rtl) {
6431 $content = array_reverse($content,false);
6432 $contentB = array_reverse($contentB,false);
6433 }
6434 }
6435/*-- END RTL --*/
6436
6437 foreach ( $content as $k => $chunk ) {
6438
6439 // FOR IMAGES - UPDATE POSITION
6440 if (($blockdir =='rtl' && $contains_rtl) || $all_rtl) { $dirk = $arraysize-1 - $k ; } else { $dirk = $k; }
6441
6442 $va = 'M'; // default for text
6443 if (isset($this->objectbuffer[$dirk]) && $this->objectbuffer[$dirk]) {
6444 $xadj = $this->x - $this->objectbuffer[$dirk]['OUTER-X'] ;
6445 $this->objectbuffer[$dirk]['OUTER-X'] += $xadj;
6446 $this->objectbuffer[$dirk]['BORDER-X'] += $xadj;
6447 $this->objectbuffer[$dirk]['INNER-X'] += $xadj;
6448 $va = $this->objectbuffer[$dirk]['vertical-align'];
6449 $yadj = $this->y - $this->objectbuffer[$dirk]['OUTER-Y'];
6450 if ($va == 'BS') {
6451 $yadj += $af + ($this->linemaxfontsize * (0.5 + $this->baselineC)) - $this->objectbuffer[$dirk]['OUTER-HEIGHT'];
6452 }
6453 else if ($va == 'M' || $va == '') {
6454 $yadj += $af + ($this->linemaxfontsize /2) - ($this->objectbuffer[$dirk]['OUTER-HEIGHT']/2);
6455 }
6456 else if ($va == 'TB') {
6457 $yadj += $af + $this->linemaxfontsize - $this->objectbuffer[$dirk]['OUTER-HEIGHT'];
6458 }
6459 else if ($va == 'TT') {
6460 $yadj += $af;
6461 }
6462 else if ($va == 'B') {
6463 $yadj += $af + $this->linemaxfontsize + $bf - $this->objectbuffer[$dirk]['OUTER-HEIGHT'];
6464 }
6465 else if ($va == 'T') {
6466 $yadj += 0;
6467 }
6468 $this->objectbuffer[$dirk]['OUTER-Y'] += $yadj;
6469 $this->objectbuffer[$dirk]['BORDER-Y'] += $yadj;
6470 $this->objectbuffer[$dirk]['INNER-Y'] += $yadj;
6471 }
6472
6473 // DIRECTIONALITY RTL
6474 if ((($blockdir == 'rtl') && ($contains_rtl )) || ($all_rtl )) { $this->restoreFont($font[$arraysize-1 - $k]); }
6475 else { $this->restoreFont( $font[ $k ] ); }
6476
6477 $this->SetSpacing(($this->fixedlSpacing*_MPDFK)+$jcharspacing,($this->fixedlSpacing+$this->minwSpacing)*_MPDFK+$jws);
6478 // Now unset these values so they don't influence GetStringwidth below or in fn. Cell
6479 $this->fixedlSpacing = false;
6480 $this->minwSpacing = 0;
6481
6482 // mPDF 5.6.26
6483 $save_vis = $this->visibility;
6484 if (isset($this->textparam['visibility']) && $this->textparam['visibility'] && $this->textparam['visibility'] != $this->visibility) {
6485 $this->SetVisibility($this->textparam['visibility']);
6486 }
6487 // *********** SPAN BACKGROUND COLOR ***************** //
6488 if ($this->spanbgcolor) {
6489 $cor = $this->spanbgcolorarray;
6490 $this->SetFColor($cor);
6491 $save_fill = $fill; $spanfill = 1; $fill = 1;
6492 }
6493 if (!empty($this->spanborddet)) {
6494 if (strpos($contentB[$k],'L')!==false) $this->x += $this->spanborddet['L']['w'];
6495 if (strpos($contentB[$k],'L')===false) $this->spanborddet['L']['s'] = $this->spanborddet['L']['w'] = 0;
6496 if (strpos($contentB[$k],'R')===false) $this->spanborddet['R']['s'] = $this->spanborddet['R']['w'] = 0;
6497 }
6498
6499 // WORD SPACING
6500 $stringWidth = $this->GetStringWidth($chunk );
6501 $stringWidth += ( $this->charspacing * mb_strlen($chunk,$this->mb_enc ) / _MPDFK );
6502 $stringWidth += ( $this->ws * mb_substr_count($chunk,' ',$this->mb_enc ) / _MPDFK );
6503 if (isset($this->objectbuffer[$dirk])) { $stringWidth = $this->objectbuffer[$dirk]['OUTER-WIDTH']; }
6504
6505 if ($stringWidth==0) { $stringWidth = 0.000001; }
6506 if ($k == $arraysize-1) {
6507 $stringWidth -= ( $this->charspacing / _MPDFK );
6508 // mPDF 5.6.40
6509 if ($this->checkCJK && $CJKoverflow && $align=='J' && $this->allowCJKoverflow && $hanger && $this->CJKforceend) {
6510 // force-end overhang
6511 $this->Cell( $stringWidth, $lineHeight, $chunk, '', 0, '', $fill, $this->HREF, $currentx,0,0,'M', $fill, $af, $bf, true );
6512 $this->Cell( $this->GetStringWidth($hanger), $lineHeight, $hanger, '', 1, '', $fill, $this->HREF, $currentx,0,0,'M', $fill, $af, $bf, true );
6513 }
6514 else {
6515 $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)
6516 }
6517
6518 }
6519 else $this->Cell( $stringWidth, $lineHeight, $chunk, '', 0, '', $fill, $this->HREF, 0, 0,0,'M', $fill, $af, $bf, true );//first or middle part
6520
6521 if (!empty($this->spanborddet)) {
6522 if (strpos($contentB[$k],'R')!==false && $k != $arraysize-1) $this->x += $this->spanborddet['R']['w'];
6523 }
6524 // *********** SPAN BACKGROUND COLOR OFF - RESET BLOCK BGCOLOR ***************** //
6525 if (isset($spanfill) && $spanfill) {
6526 $fill = $save_fill; $spanfill = 0;
6527 if ($fill) { $this->SetFColor($bcor); }
6528 }
6529 // mPDF 5.6.26
6530 if (isset($this->textparam['visibility']) && $this->textparam['visibility'] && $this->visibility != $save_vis) {
6531 $this->SetVisibility($save_vis);
6532 }
6533
6534 }
6535 if (!$is_table) {
6536 $this->maxPosR = max($this->maxPosR , ($this->w - $this->rMargin - $this->blk[$this->blklvl]['outer_right_margin']));
6537 $this->maxPosL = min($this->maxPosL , ($this->lMargin + $this->blk[$this->blklvl]['outer_left_margin']));
6538 }
6539
6540 // move on to the next line, reset variables, tack on saved content and current char
6541
6542 $this->printobjectbuffer($is_table, $blockdir);
6543 $this->objectbuffer = array();
6544
6545/*-- LISTS --*/
6546 // LIST BULLETS/NUMBERS
6547 if ($is_list && is_array($this->bulletarray) && ($lineCount == 1) ) {
6548
6549 $this->ResetSpacing();
6550
6551 $bull = $this->bulletarray;
6552 if (isset($bull['level']) && isset($bull['occur']) && isset($this->InlineProperties['LIST'][$bull['level']][$bull['occur']])) {
6553 $this->restoreInlineProperties($this->InlineProperties['LIST'][$bull['level']][$bull['occur']]);
6554 }
6555 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']]); }
6556 if (isset($bull['font']) && $bull['font'] == 'czapfdingbats') {
6557 $this->bullet = true;
6558 $this->SetFont('czapfdingbats','',$this->FontSizePt/2.5);
6559 }
6560 else { $this->SetFont($this->FontFamily,$this->FontStyle,$this->FontSizePt,true,true); } // force output
6561 //Output bullet
6562 $this->x = $currentx;
6563 if (isset($bull['x'])) { $this->x += $bull['x']; }
6564 $this->y -= $lineHeight;
6565 if (isset($bull['col']) && $bull['col']) { $this->SetTColor($bull['col']); } // mPDF 5.6.67
6566 if (isset($bull['txt'])) { $this->Cell($bull['w'], $lineHeight,$bull['txt'],'','',$bull['align'],0,'',0,-$this->cMarginL, -$this->cMarginR ); }
6567 if (isset($bull['font']) && $bull['font'] == 'czapfdingbats') {
6568 $this->bullet = false;
6569 }
6570 $this->x = $currentx; // Reset
6571 $this->y += $lineHeight;
6572
6573 if ($this->ColActive && !$is_table) { $this->breakpoints[$this->CurrCol][] = $this->y; } // *COLUMNS*
6574
6575 $this->bulletarray = array(); // prevents repeat of bullet/number if <li>....<br />.....</li>
6576 }
6577/*-- END LISTS --*/
6578
6579
6580/*-- CSS-IMAGE-FLOAT --*/
6581 // Update values if set to skipline
6582 if ($this->floatmargins) { $this->_advanceFloatMargins(); }
6583/*-- END CSS-IMAGE-FLOAT --*/
6584
6585 // Reset lineheight
6586 $lineHeight = $this->divheight;
6587 $valign = 'M';
6588
6589 $font = array();
6590 $content = array();
6591 $contentB = array();
6592 $contentWidth = 0;
6593 if (!empty($savedObj)) {
6594 $this->objectbuffer[] = $savedObj;
6595 $font[] = $savedFont;
6596 $content[] = '';
6597 $contentB[] = '';
6598 $contentWidth += $savedObj['OUTER-WIDTH'] * _MPDFK;
6599 }
6600 // mPDF 5.6.20
6601 if (count($savedPreContent) > 0) {
6602 for($ix=count($savedPreContent)-1;$ix>=0;$ix--) {
6603 $font[] = $savedPreFont[$ix];
6604 $content[] = $savedPreContent[$ix];
6605 $contentB[] = $savedPreContentB[$ix];
6606 $this->restoreFont( $savedPreFont[$ix] );
6607 $lbw = $rbw = 0; // Border widths
6608 if (!empty($this->spanborddet)) {
6609 $lbw = $this->spanborddet['L']['w'];
6610 $rbw = $this->spanborddet['R']['w'];
6611 }
6612 if ($ix>0) {
6613 $contentWidth += $this->GetStringWidth( $savedPreContent[$ix] ) * _MPDFK;
6614 if (strpos($savedPreContentB[$ix],'L')!==false) $contentWidth += $lbw;
6615 if (strpos($savedPreContentB[$ix],'R')!==false) $contentWidth += $rbw;
6616 }
6617 }
6618 $savedPreContent = array();
6619 $savedPreContentB = array();
6620 $savedPreFont = array();
6621 $content[ (count($content)-1) ] .= $c;
6622 }
6623 else {
6624 $font[] = $savedFont;
6625 $content[] = $savedContent . $c;
6626 $contentB[] = $savedContentB ;
6627 }
6628
6629 $currContent =& $content[ (count($content)-1) ];
6630
6631 // CJK - strip CJK space at end of line
6632 // &#x3000; = \xe3\x80\x80 = CJK space
6633 if ($this->checkCJK && $currContent == "\xe3\x80\x80") { $currContent = '' ; } // *CJK-FONTS*
6634
6635 $this->restoreFont( $savedFont );
6636 $lbw = $rbw = 0; // Border widths
6637 if (!empty($this->spanborddet)) {
6638 $lbw = $this->spanborddet['L']['w'];
6639 $rbw = $this->spanborddet['R']['w'];
6640 }
6641 $contentWidth += $this->GetStringWidth( $currContent ) * _MPDFK;
6642 if (strpos($savedContentB,'L')!==false) $contentWidth += $lbw;
6643 $cutoffWidth = $contentWidth;
6644 $CJKoverflow = false;
6645 $hanger = ''; // mPDF 5.6.40
6646 }
6647 // another character will fit, so add it on
6648 else {
6649 $contentWidth += $cw;
6650 $currContent .= $c;
6651 }
6652 }
6653 unset($content);
6654 unset($contentB);
6655}
6656//----------------------END OF FLOWING BLOCK------------------------------------//
6657
6658
6659/*-- CSS-IMAGE-FLOAT --*/
6660// Update values if set to skipline
6661function _advanceFloatMargins() {
6662 // Update floatmargins - L
6663 if (isset($this->floatmargins['L']) && $this->floatmargins['L']['skipline'] && $this->floatmargins['L']['y0'] != $this->y) {
6664 $yadj = $this->y - $this->floatmargins['L']['y0'];
6665 $this->floatmargins['L']['y0'] = $this->y;
6666 $this->floatmargins['L']['y1'] += $yadj;
6667
6668 // Update objattr in floatbuffer
6669 if ($this->floatbuffer[$this->floatmargins['L']['id']]['border_left']['w']) {
6670 $this->floatbuffer[$this->floatmargins['L']['id']]['BORDER-Y'] += $yadj;
6671 }
6672 $this->floatbuffer[$this->floatmargins['L']['id']]['INNER-Y'] += $yadj;
6673 $this->floatbuffer[$this->floatmargins['L']['id']]['OUTER-Y'] += $yadj;
6674
6675 // Unset values
6676 $this->floatbuffer[$this->floatmargins['L']['id']]['skipline'] = false;
6677 $this->floatmargins['L']['skipline'] = false;
6678 $this->floatmargins['L']['id'] = '';
6679 }
6680 // Update floatmargins - R
6681 if (isset($this->floatmargins['R']) && $this->floatmargins['R']['skipline'] && $this->floatmargins['R']['y0'] != $this->y) {
6682 $yadj = $this->y - $this->floatmargins['R']['y0'];
6683 $this->floatmargins['R']['y0'] = $this->y;
6684 $this->floatmargins['R']['y1'] += $yadj;
6685
6686 // Update objattr in floatbuffer
6687 if ($this->floatbuffer[$this->floatmargins['R']['id']]['border_left']['w']) {
6688 $this->floatbuffer[$this->floatmargins['R']['id']]['BORDER-Y'] += $yadj;
6689 }
6690 $this->floatbuffer[$this->floatmargins['R']['id']]['INNER-Y'] += $yadj;
6691 $this->floatbuffer[$this->floatmargins['R']['id']]['OUTER-Y'] += $yadj;
6692
6693 // Unset values
6694 $this->floatbuffer[$this->floatmargins['R']['id']]['skipline'] = false;
6695 $this->floatmargins['R']['skipline'] = false;
6696 $this->floatmargins['R']['id'] = '';
6697 }
6698}
6699/*-- END CSS-IMAGE-FLOAT --*/
6700
6701
6702
6703////////////////////////////////////////////////////////////////////////////////
6704// ADDED forcewrap - to call from inline OBJECT functions to breakwords if necessary in cell
6705////////////////////////////////////////////////////////////////////////////////
6706function WordWrap(&$text, $maxwidth, $forcewrap = 0) {
6707 $biggestword=0;
6708 $toonarrow=false;
6709
6710 $text = trim($text);
6711
6712 if ($text==='') return 0;
6713 $space = $this->GetCharWidth(' ',false);
6714 $lines = explode("\n", $text);
6715 $text = '';
6716 $count = 0;
6717 foreach ($lines as $line) {
6718 $words = explode(' ', $line);
6719 $width = 0;
6720 foreach ($words as $word) {
6721 $word = trim($word);
6722 $wordwidth = $this->GetStringWidth($word);
6723 //Warn user that maxwidth is insufficient
6724 if ($wordwidth > $maxwidth + 0.0001) {
6725 if ($wordwidth > $biggestword) { $biggestword = $wordwidth; }
6726 $toonarrow=true;
6727 // ADDED
6728 if ($forcewrap) {
6729 while($wordwidth > $maxwidth) {
6730 $chw = 0; // check width
6731 for ( $i = 0; $i < mb_strlen($word, $this->mb_enc ); $i++ ) {
6732 $chw = $this->GetStringWidth(mb_substr($word,0,$i+1,$this->mb_enc ));
6733 if ($chw > $maxwidth ) {
6734 if ($text) {
6735 $text = rtrim($text)."\n".mb_substr($word,0,$i,$this->mb_enc );
6736 $count++;
6737 }
6738 else {
6739 $text = mb_substr($word,0,$i,$this->mb_enc );
6740 }
6741 $word = mb_substr($word,$i,mb_strlen($word, $this->mb_enc )-$i,$this->mb_enc );
6742 $wordwidth = $this->GetStringWidth($word);
6743 $width = $maxwidth;
6744 break;
6745 }
6746 }
6747 }
6748 }
6749 }
6750
6751 if ($width + $wordwidth < $maxwidth - 0.0001) {
6752 $width += $wordwidth + $space;
6753 $text .= $word.' ';
6754 }
6755 else {
6756 $width = $wordwidth + $space;
6757 $text = rtrim($text)."\n".$word.' ';
6758 $count++;
6759 }
6760 }
6761 $text .= "\n";
6762 $count++;
6763 }
6764 $text = rtrim($text);
6765
6766 //Return -(wordsize) if word is bigger than maxwidth
6767
6768 // ADDED
6769 if ($forcewrap) { return $count; }
6770 if (($toonarrow) && ($this->table_error_report)) {
6771 $this->Error("Word is too long to fit in table - ".$this->table_error_report_param);
6772 }
6773 if ($toonarrow) return -$biggestword;
6774 else return $count;
6775}
6776
6777/*-- END HTML-CSS --*/
6778
6779function _SetTextRendering($mode) {
6780 if (!(($mode == 0) || ($mode == 1) || ($mode == 2)))
6781 $this->Error("Text rendering mode should be 0, 1 or 2 (value : $mode)");
6782 $tr = ($mode.' Tr');
6783 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); }
6784 $this->pageoutput[$this->page]['TextRendering'] = $tr;
6785
6786}
6787
6788function SetTextOutline($params=array()) { // mPDF 5.6.07
6789 if (isset($params['outline-s']) && $params['outline-s'])
6790 {
6791 $this->SetLineWidth($params['outline-WIDTH']);
6792 $this->SetDColor($params['outline-COLOR']);
6793 $tr = ('2 Tr');
6794 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); }
6795 $this->pageoutput[$this->page]['TextRendering'] = $tr;
6796 }
6797 else //Now resets all values
6798 {
6799 $this->SetLineWidth(0.2);
6800 $this->SetDColor($this->ConvertColor(0));
6801 $this->_SetTextRendering(0);
6802 $tr = ('0 Tr');
6803 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); }
6804 $this->pageoutput[$this->page]['TextRendering'] = $tr;
6805 }
6806}
6807
6808function Image($file,$x,$y,$w=0,$h=0,$type='',$link='',$paint=true, $constrain=true, $watermark=false, $shownoimg=true, $allowvector=true) {
6809 $orig_srcpath = $file;
6810 $this->GetFullPath($file);
6811
6812 $info=$this->_getImage($file, true, $allowvector, $orig_srcpath );
6813 if(!$info && $paint) {
6814 $info = $this->_getImage($this->noImageFile);
6815 if ($info) {
6816 $file = $this->noImageFile;
6817 $w = ($info['w'] * (25.4/$this->dpi)); // 14 x 16px
6818 $h = ($info['h'] * (25.4/$this->dpi)); // 14 x 16px
6819 }
6820 }
6821 if(!$info) return false;
6822 //Automatic width and height calculation if needed
6823 if($w==0 and $h==0) {
6824/*-- IMAGES-WMF --*/
6825 if ($info['type']=='wmf') {
6826 // WMF units are twips (1/20pt)
6827 // divide by 20 to get points
6828 // divide by k to get user units
6829 $w = abs($info['w'])/(20*_MPDFK);
6830 $h = abs($info['h']) / (20*_MPDFK);
6831 }
6832 else
6833/*-- END IMAGES-WMF --*/
6834 if ($info['type']=='svg') {
6835 // returned SVG units are pts
6836 // divide by k to get user units (mm)
6837 $w = abs($info['w'])/_MPDFK;
6838 $h = abs($info['h']) /_MPDFK;
6839 }
6840 else {
6841 //Put image at default image dpi
6842 $w=($info['w']/_MPDFK) * (72/$this->img_dpi);
6843 $h=($info['h']/_MPDFK) * (72/$this->img_dpi);
6844 }
6845 }
6846 if($w==0) $w=abs($h*$info['w']/$info['h']);
6847 if($h==0) $h=abs($w*$info['h']/$info['w']);
6848
6849/*-- WATERMARK --*/
6850 if ($watermark) {
6851 $maxw = $this->w;
6852 $maxh = $this->h;
6853 // Size = D PF or array
6854 if (is_array($this->watermark_size)) {
6855 $w = $this->watermark_size[0];
6856 $h = $this->watermark_size[1];
6857 }
6858 else if (!is_string($this->watermark_size)) {
6859 $maxw -= $this->watermark_size*2;
6860 $maxh -= $this->watermark_size*2;
6861 $w = $maxw;
6862 $h=abs($w*$info['h']/$info['w']);
6863 if ($h > $maxh ) {
6864 $h = $maxh ; $w=abs($h*$info['w']/$info['h']);
6865 }
6866 }
6867 else if ($this->watermark_size == 'F') {
6868 if ($this->ColActive) { $maxw = $this->w - ($this->DeflMargin + $this->DefrMargin); }
6869 else { $maxw = $this->pgwidth; }
6870 $maxh = $this->h - ($this->tMargin + $this->bMargin);
6871 $w = $maxw;
6872 $h=abs($w*$info['h']/$info['w']);
6873 if ($h > $maxh ) {
6874 $h = $maxh ; $w=abs($h*$info['w']/$info['h']);
6875 }
6876 }
6877 else if ($this->watermark_size == 'P') { // Default P
6878 $w = $maxw;
6879 $h=abs($w*$info['h']/$info['w']);
6880 if ($h > $maxh ) {
6881 $h = $maxh ; $w=abs($h*$info['w']/$info['h']);
6882 }
6883 }
6884 // Automatically resize to maximum dimensions of page if too large
6885 if ($w > $maxw) {
6886 $w = $maxw;
6887 $h=abs($w*$info['h']/$info['w']);
6888 }
6889 if ($h > $maxh ) {
6890 $h = $maxh ;
6891 $w=abs($h*$info['w']/$info['h']);
6892 }
6893 // Position
6894 if (is_array($this->watermark_pos)) {
6895 $x = $this->watermark_pos[0];
6896 $y = $this->watermark_pos[1];
6897 }
6898 else if ($this->watermark_pos == 'F') { // centred on printable area
6899 if ($this->ColActive) { // *COLUMNS*
6900 if (($this->mirrorMargins) && (($this->page)%2==0)) { $xadj = $this->DeflMargin-$this->DefrMargin; } // *COLUMNS*
6901 else { $xadj = 0; } // *COLUMNS*
6902 $x = ($this->DeflMargin - $xadj + ($this->w - ($this->DeflMargin + $this->DefrMargin))/2) - ($w/2); // *COLUMNS*
6903 } // *COLUMNS*
6904 else { // *COLUMNS*
6905 $x = ($this->lMargin + ($this->pgwidth)/2) - ($w/2);
6906 } // *COLUMNS*
6907 $y = ($this->tMargin + ($this->h - ($this->tMargin + $this->bMargin))/2) - ($h/2);
6908 }
6909 else { // default P - centred on whole page
6910 $x = ($this->w/2) - ($w/2);
6911 $y = ($this->h/2) - ($h/2);
6912 }
6913/*-- IMAGES-WMF --*/
6914 if ($info['type']=='wmf') {
6915 $sx = $w*_MPDFK / $info['w'];
6916 $sy = -$h*_MPDFK / $info['h'];
6917 $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']);
6918 }
6919 else
6920/*-- END IMAGES-WMF --*/
6921 if ($info['type']=='svg') {
6922 $sx = $w*_MPDFK / $info['w'];
6923 $sy = -$h*_MPDFK / $info['h'];
6924 $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']);
6925 }
6926 else {
6927 $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']);
6928 }
6929
6930 if ($this->watermarkImgBehind) {
6931 $outstring = $this->watermarkImgAlpha . "\n" . $outstring . "\n" . $this->SetAlpha(1, 'Normal', true) . "\n";
6932 $this->pages[$this->page] = preg_replace('/(___BACKGROUND___PATTERNS'.$this->uniqstr.')/', "\n".$outstring."\n".'\\1', $this->pages[$this->page]);
6933 }
6934 else { $this->_out($outstring); }
6935
6936 return 0;
6937 } // end of IF watermark
6938/*-- END WATERMARK --*/
6939
6940 if ($constrain) {
6941 // Automatically resize to maximum dimensions of page if too large
6942 if (isset($this->blk[$this->blklvl]['inner_width']) && $this->blk[$this->blklvl]['inner_width']) { $maxw = $this->blk[$this->blklvl]['inner_width']; }
6943 else { $maxw = $this->pgwidth; }
6944 if ($w > $maxw) {
6945 $w = $maxw;
6946 $h=abs($w*$info['h']/$info['w']);
6947 }
6948 if ($h > $this->h - ($this->tMargin + $this->bMargin + 1)) { // see below - +10 to avoid drawing too close to border of page
6949 $h = $this->h - ($this->tMargin + $this->bMargin + 1) ;
6950 if ($this->fullImageHeight) { $h = $this->fullImageHeight; }
6951 $w=abs($h*$info['w']/$info['h']);
6952 }
6953
6954
6955 //Avoid drawing out of the paper(exceeding width limits).
6956 //if ( ($x + $w) > $this->fw ) {
6957 if ( ($x + $w) > $this->w ) {
6958 $x = $this->lMargin;
6959 $y += 5;
6960 }
6961
6962 $changedpage = false;
6963 $oldcolumn = $this->CurrCol;
6964 //Avoid drawing out of the page.
6965 if($y+$h>$this->PageBreakTrigger and !$this->InFooter and $this->AcceptPageBreak()) {
6966 $this->AddPage($this->CurOrientation);
6967 // Added to correct for OddEven Margins
6968 $x=$x +$this->MarginCorrection;
6969 $y = $tMargin + $this->margin_header;
6970 $changedpage = true;
6971 }
6972/*-- COLUMNS --*/
6973 // COLS
6974 // COLUMN CHANGE
6975 if ($this->CurrCol != $oldcolumn) {
6976 $y = $this->y0;
6977 $x += $this->ChangeColumn * ($this->ColWidth+$this->ColGap);
6978 $this->x += $this->ChangeColumn * ($this->ColWidth+$this->ColGap);
6979 }
6980/*-- END COLUMNS --*/
6981 } // end of IF constrain
6982
6983/*-- IMAGES-WMF --*/
6984 if ($info['type']=='wmf') {
6985 $sx = $w*_MPDFK / $info['w'];
6986 $sy = -$h*_MPDFK / $info['h'];
6987 $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']);
6988 }
6989 else
6990/*-- END IMAGES-WMF --*/
6991 if ($info['type']=='svg') {
6992 $sx = $w*_MPDFK / $info['w'];
6993 $sy = -$h*_MPDFK / $info['h'];
6994 $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']);
6995 }
6996 else {
6997 $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']);
6998 }
6999
7000 if($paint) {
7001 $this->_out($outstring);
7002 if($link) $this->Link($x,$y,$w,$h,$link);
7003
7004 // Avoid writing text on top of the image. // THIS WAS OUTSIDE THE if ($paint) bit!!!!!!!!!!!!!!!!
7005 $this->y = $y + $h;
7006 }
7007
7008 //Return width-height array
7009 $sizesarray['WIDTH'] = $w;
7010 $sizesarray['HEIGHT'] = $h;
7011 $sizesarray['X'] = $x; //Position before painting image
7012 $sizesarray['Y'] = $y; //Position before painting image
7013 $sizesarray['OUTPUT'] = $outstring;
7014
7015 $sizesarray['IMAGE_ID'] = $info['i'];
7016 $sizesarray['itype'] = $info['type'];
7017 $sizesarray['set-dpi'] = $info['set-dpi'];
7018 return $sizesarray;
7019}
7020
7021
7022
7023//=============================================================
7024//=============================================================
7025//=============================================================
7026//=============================================================
7027//=============================================================
7028/*-- HTML-CSS --*/
7029
7030function _getObjAttr($t) {
7031 $c = explode("\xbb\xa4\xac",$t,2);
7032 $c = explode(",",$c[1],2);
7033 foreach($c as $v) {
7034 $v = explode("=",$v,2);
7035 $sp[$v[0]] = $v[1];
7036 }
7037 return (unserialize($sp['objattr']));
7038}
7039
7040
7041function inlineObject($type,$x,$y,$objattr,$Lmargin,$widthUsed,$maxWidth,$lineHeight,$paint=false,$is_table=false)
7042{
7043 if ($is_table) { $k = $this->shrin_k; } else { $k = 1; }
7044
7045 // NB $x is only used when paint=true
7046 // Lmargin not used
7047 $w = 0;
7048 if (isset($objattr['width'])) { $w = $objattr['width']/$k; }
7049 $h = 0;
7050 if (isset($objattr['height'])) { $h = abs($objattr['height']/$k); }
7051 $widthLeft = $maxWidth - $widthUsed;
7052 $maxHeight = $this->h - ($this->tMargin + $this->bMargin + 10) ;
7053 if ($this->fullImageHeight) { $maxHeight = $this->fullImageHeight; }
7054 // For Images
7055 if (isset($objattr['border_left'])) {
7056 $extraWidth = ($objattr['border_left']['w'] + $objattr['border_right']['w'] + $objattr['margin_left']+ $objattr['margin_right'])/$k;
7057 $extraHeight = ($objattr['border_top']['w'] + $objattr['border_bottom']['w'] + $objattr['margin_top']+ $objattr['margin_bottom'])/$k;
7058
7059 if ($type == 'image' || $type == 'barcode' || $type == 'textcircle') {
7060 $extraWidth += ($objattr['padding_left'] + $objattr['padding_right'])/$k;
7061 $extraHeight += ($objattr['padding_top'] + $objattr['padding_bottom'])/$k;
7062 }
7063 }
7064
7065 if (!isset($objattr['vertical-align'])) { $objattr['vertical-align'] = 'M'; }
7066
7067 if ($type == 'image' || (isset($objattr['subtype']) && $objattr['subtype'] == 'IMAGE')) {
7068 if (isset($objattr['itype']) && ($objattr['itype'] == 'wmf' || $objattr['itype'] == 'svg')) {
7069 $file = $objattr['file'];
7070 $info=$this->formobjects[$file];
7071 }
7072 else if (isset($objattr['file'])) {
7073 $file = $objattr['file'];
7074 $info=$this->images[$file];
7075 }
7076 }
7077 if ($type == 'annot' || $type == 'bookmark' || $type == 'indexentry' || $type == 'toc') {
7078 $w = 0.00001;
7079 $h = 0.00001;
7080 }
7081
7082 // TEST whether need to skipline
7083 if (!$paint) {
7084 if ($type == 'hr') { // always force new line
7085 if (($y + $h + $lineHeight > $this->PageBreakTrigger) && !$this->InFooter && !$is_table) { return array(-2, $w ,$h ); } // New page + new line
7086 else { return array(1, $w ,$h ); } // new line
7087 }
7088 else {
7089 if ($widthUsed > 0 && $w > $widthLeft && (!$is_table || $type != 'image')) { // New line needed
7090 if (($y + $h + $lineHeight > $this->PageBreakTrigger) && !$this->InFooter) { return array(-2,$w ,$h ); } // New page + new line
7091 return array(1,$w ,$h ); // new line
7092 }
7093 else if ($widthUsed > 0 && $w > $widthLeft && $is_table) { // New line needed in TABLE
7094 return array(1,$w ,$h ); // new line
7095 }
7096 // Will fit on line but NEW PAGE REQUIRED
7097 else if (($y + $h > $this->PageBreakTrigger) && !$this->InFooter && !$is_table) { return array(-1,$w ,$h ); }
7098 else { return array(0,$w ,$h ); }
7099 }
7100 }
7101
7102 if ($type == 'annot' || $type == 'bookmark' || $type == 'indexentry' || $type == 'toc') {
7103 $w = 0.00001;
7104 $h = 0.00001;
7105 $objattr['BORDER-WIDTH'] = 0;
7106 $objattr['BORDER-HEIGHT'] = 0;
7107 $objattr['BORDER-X'] = $x;
7108 $objattr['BORDER-Y'] = $y;
7109 $objattr['INNER-WIDTH'] = 0;
7110 $objattr['INNER-HEIGHT'] = 0;
7111 $objattr['INNER-X'] = $x;
7112 $objattr['INNER-Y'] = $y;
7113 }
7114
7115 if ($type == 'image') {
7116 // Automatically resize to width remaining
7117 if ($w > $widthLeft && !$is_table) {
7118 $w = $widthLeft ;
7119 $h=abs($w*$info['h']/$info['w']);
7120 }
7121 $img_w = $w - $extraWidth ;
7122 $img_h = $h - $extraHeight ;
7123
7124 $objattr['BORDER-WIDTH'] = $img_w + $objattr['padding_left']/$k + $objattr['padding_right']/$k + (($objattr['border_left']['w']/$k + $objattr['border_right']['w']/$k)/2) ;
7125 $objattr['BORDER-HEIGHT'] = $img_h + $objattr['padding_top']/$k + $objattr['padding_bottom']/$k + (($objattr['border_top']['w']/$k + $objattr['border_bottom']['w']/$k)/2) ;
7126 $objattr['BORDER-X'] = $x + $objattr['margin_left']/$k + (($objattr['border_left']['w']/$k)/2) ;
7127 $objattr['BORDER-Y'] = $y + $objattr['margin_top']/$k + (($objattr['border_top']['w']/$k)/2) ;
7128 $objattr['INNER-WIDTH'] = $img_w;
7129 $objattr['INNER-HEIGHT'] = $img_h;
7130 $objattr['INNER-X'] = $x + $objattr['padding_left']/$k + $objattr['margin_left']/$k + ($objattr['border_left']['w']/$k);
7131 $objattr['INNER-Y'] = $y + $objattr['padding_top']/$k + $objattr['margin_top']/$k + ($objattr['border_top']['w']/$k) ;
7132 $objattr['ID'] = $info['i'];
7133 }
7134
7135 if ($type == 'input' && $objattr['subtype'] == 'IMAGE') {
7136 $img_w = $w - $extraWidth ;
7137 $img_h = $h - $extraHeight ;
7138 $objattr['BORDER-WIDTH'] = $img_w + (($objattr['border_left']['w']/$k + $objattr['border_right']['w']/$k)/2) ;
7139 $objattr['BORDER-HEIGHT'] = $img_h + (($objattr['border_top']['w']/$k + $objattr['border_bottom']['w']/$k)/2) ;
7140 $objattr['BORDER-X'] = $x + $objattr['margin_left']/$k + (($objattr['border_left']['w']/$k)/2) ;
7141 $objattr['BORDER-Y'] = $y + $objattr['margin_top']/$k + (($objattr['border_top']['w']/$k)/2) ;
7142 $objattr['INNER-WIDTH'] = $img_w;
7143 $objattr['INNER-HEIGHT'] = $img_h;
7144 $objattr['INNER-X'] = $x + $objattr['margin_left']/$k + ($objattr['border_left']['w']/$k);
7145 $objattr['INNER-Y'] = $y + $objattr['margin_top']/$k + ($objattr['border_top']['w']/$k) ;
7146 $objattr['ID'] = $info['i'];
7147 }
7148
7149 if ($type == 'barcode' || $type == 'textcircle') {
7150 $b_w = $w - $extraWidth ;
7151 $b_h = $h - $extraHeight ;
7152 $objattr['BORDER-WIDTH'] = $b_w + $objattr['padding_left']/$k + $objattr['padding_right']/$k + (($objattr['border_left']['w']/$k + $objattr['border_right']['w']/$k)/2) ;
7153 $objattr['BORDER-HEIGHT'] = $b_h + $objattr['padding_top']/$k + $objattr['padding_bottom']/$k + (($objattr['border_top']['w']/$k + $objattr['border_bottom']['w']/$k)/2) ;
7154 $objattr['BORDER-X'] = $x + $objattr['margin_left']/$k + (($objattr['border_left']['w']/$k)/2) ;
7155 $objattr['BORDER-Y'] = $y + $objattr['margin_top']/$k + (($objattr['border_top']['w']/$k)/2) ;
7156 $objattr['INNER-X'] = $x + $objattr['padding_left']/$k + $objattr['margin_left']/$k + ($objattr['border_left']['w']/$k);
7157 $objattr['INNER-Y'] = $y + $objattr['padding_top']/$k + $objattr['margin_top']/$k + ($objattr['border_top']['w']/$k) ;
7158 $objattr['INNER-WIDTH'] = $b_w;
7159 $objattr['INNER-HEIGHT'] = $b_h;
7160 }
7161
7162
7163 if ($type == 'textarea') {
7164 // Automatically resize to width remaining
7165 if ($w > $widthLeft && !$is_table) {
7166 $w = $widthLeft ;
7167 }
7168 if (($y + $h > $this->PageBreakTrigger) && !$this->InFooter) {
7169 $h=$this->h - $y - $this->bMargin;
7170 }
7171 }
7172
7173 if ($type == 'hr') {
7174 if ($is_table) {
7175 $objattr['INNER-WIDTH'] = $maxWidth * $objattr['W-PERCENT']/100;
7176 $objattr['width'] = $objattr['INNER-WIDTH'];
7177 $w = $maxWidth;
7178 }
7179 else {
7180 if ($w>$maxWidth) { $w = $maxWidth; }
7181 $objattr['INNER-WIDTH'] = $w;
7182 $w = $maxWidth;
7183 }
7184 }
7185
7186
7187
7188 if (($type == 'select') || ($type == 'input' && ($objattr['subtype'] == 'TEXT' || $objattr['subtype'] == 'PASSWORD'))) {
7189 // Automatically resize to width remaining
7190 if ($w > $widthLeft && !$is_table) {
7191 $w = $widthLeft;
7192 }
7193 }
7194
7195 if ($type == 'textarea' || $type == 'select' || $type == 'input') {
7196 if (isset($objattr['fontsize'])) $objattr['fontsize'] /= $k;
7197 if (isset($objattr['linewidth'])) $objattr['linewidth'] /= $k;
7198 }
7199
7200 if (!isset($objattr['BORDER-Y'])) { $objattr['BORDER-Y'] = 0; }
7201 if (!isset($objattr['BORDER-X'])) { $objattr['BORDER-X'] = 0; }
7202 if (!isset($objattr['INNER-Y'])) { $objattr['INNER-Y'] = 0; }
7203 if (!isset($objattr['INNER-X'])) { $objattr['INNER-X'] = 0; }
7204
7205 //Return width-height array
7206 $objattr['OUTER-WIDTH'] = $w;
7207 $objattr['OUTER-HEIGHT'] = $h;
7208 $objattr['OUTER-X'] = $x;
7209 $objattr['OUTER-Y'] = $y;
7210 return $objattr;
7211}
7212
7213/*-- END HTML-CSS --*/
7214
7215//=============================================================
7216//=============================================================
7217//=============================================================
7218//=============================================================
7219//=============================================================
7220
7221function SetLineJoin($mode=0)
7222{
7223 $s=sprintf('%d j',$mode);
7224 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); }
7225 $this->pageoutput[$this->page]['LineJoin'] = $s;
7226
7227}
7228function SetLineCap($mode=2) {
7229 $s=sprintf('%d J',$mode);
7230 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); }
7231 $this->pageoutput[$this->page]['LineCap'] = $s;
7232
7233}
7234
7235function SetDash($black=false,$white=false)
7236{
7237 if($black and $white) $s=sprintf('[%.3F %.3F] 0 d',$black*_MPDFK,$white*_MPDFK);
7238 else $s='[] 0 d';
7239 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); }
7240 $this->pageoutput[$this->page]['Dash'] = $s;
7241
7242}
7243
7244function SetDisplayPreferences($preferences) {
7245 // String containing any or none of /HideMenubar/HideToolbar/HideWindowUI/DisplayDocTitle/CenterWindow/FitWindow
7246 $this->DisplayPreferences .= $preferences;
7247}
7248
7249
7250function Ln($h='',$collapsible=0)
7251{
7252// Added collapsible to allow collapsible top-margin on new page
7253 //Line feed; default value is last cell height
7254 $this->x = $this->lMargin + $this->blk[$this->blklvl]['outer_left_margin'];
7255 if ($collapsible && ($this->y==$this->tMargin) && (!$this->ColActive)) { $h = 0; }
7256 if(is_string($h)) $this->y+=$this->lasth;
7257 else $this->y+=$h;
7258}
7259
7260/*-- HTML-CSS --*/
7261// $state = 0 normal; 1 top; 2 bottom; 3 top and bottom
7262function DivLn($h,$level=-3,$move_y=true,$collapsible=false,$state=0) {
7263 // this->x is returned as it was
7264 // adds lines (y) where DIV bgcolors are filled in
7265 // allows .00001 as nominal height used for bookmarks/annotations etc.
7266 if ($collapsible && (sprintf("%0.4f", $this->y)==sprintf("%0.4f", $this->tMargin)) && (!$this->ColActive)) { return; }
7267 if ($collapsible && (sprintf("%0.4f", $this->y)==sprintf("%0.4f", $this->y0)) && ($this->ColActive) && $this->CurrCol == 0) { return; } // *COLUMNS*
7268
7269 // Still use this method if columns or page-break-inside: avoid, as it allows repositioning later
7270 // otherwise, now uses PaintDivBB()
7271 if (!$this->ColActive && !$this->keep_block_together && !$this->kwt) {
7272 if ($move_y && !$this->ColActive) { $this->y += $h; }
7273 return;
7274 }
7275
7276 if ($level == -3) { $level = $this->blklvl; }
7277 $firstblockfill = $this->GetFirstBlockFill();
7278 if ($firstblockfill && $this->blklvl > 0 && $this->blklvl >= $firstblockfill) {
7279 $last_x = 0;
7280 $last_w = 0;
7281 $last_fc = $this->FillColor;
7282 $bak_x = $this->x;
7283 $bak_h = $this->divheight;
7284 $this->divheight = 0; // Temporarily turn off divheight - as Cell() uses it to check for PageBreak
7285 for ($blvl=$firstblockfill;$blvl<=$level;$blvl++) {
7286 $this->SetBlockFill($blvl);
7287 $this->x = $this->lMargin + $this->blk[$blvl]['outer_left_margin'];
7288 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
7289 $x = $this->x;
7290 $this->Cell( ($this->blk[$blvl]['width']), $h, '', '', 0, '', 1);
7291 if (!$this->keep_block_together && !$this->writingHTMLheader && !$this->writingHTMLfooter) {
7292 $this->x = $x;
7293 // $state = 0 normal; 1 top; 2 bottom; 3 top and bottom
7294 if ($blvl == $this->blklvl) { $this->PaintDivLnBorder($state,$blvl,$h); }
7295 else { $this->PaintDivLnBorder(0,$blvl,$h); }
7296 }
7297 }
7298 $last_x = $this->lMargin + $this->blk[$blvl]['outer_left_margin'];
7299 $last_w = $this->blk[$blvl]['width'];
7300 $last_fc = $this->FillColor;
7301 }
7302 // Reset current block fill
7303 if (isset($this->blk[$this->blklvl]['bgcolorarray'])) {
7304 $bcor = $this->blk[$this->blklvl]['bgcolorarray'];
7305 $this->SetFColor($bcor);
7306 }
7307 $this->x = $bak_x;
7308 $this->divheight = $bak_h;
7309 }
7310 if ($move_y) { $this->y += $h; }
7311}
7312/*-- END HTML-CSS --*/
7313
7314
7315function SetX($x)
7316{
7317 //Set x position
7318 if($x >= 0) $this->x=$x;
7319 else $this->x = $this->w + $x;
7320}
7321
7322function SetY($y)
7323{
7324 //Set y position and reset x
7325 $this->x=$this->lMargin;
7326 if($y>=0)
7327 $this->y=$y;
7328 else
7329 $this->y=$this->h+$y;
7330}
7331
7332function SetXY($x,$y)
7333{
7334 //Set x and y positions
7335 $this->SetY($y);
7336 $this->SetX($x);
7337}
7338
7339
7340function Output($name='',$dest='')
7341{
7342 //Output PDF to some destination
7343 if ($this->showStats) {
7344 echo '<div>Generated in '.sprintf('%.2F',(microtime(true) - $this->time0)).' seconds</div>';
7345 }
7346 //Finish document if necessary
7347 if ($this->progressBar) { $this->UpdateProgressBar(1,'100','Finished'); } // *PROGRESS-BAR*
7348 if($this->state < 3) $this->Close();
7349 if ($this->progressBar) { $this->UpdateProgressBar(2,'100','Finished'); } // *PROGRESS-BAR*
7350 // fn. error_get_last is only in PHP>=5.2
7351 if ($this->debug && function_exists('error_get_last') && error_get_last()) {
7352 $e = error_get_last();
7353 if (($e['type'] < 2048 && $e['type'] != 8) || (intval($e['type']) & intval(ini_get("error_reporting")))) {
7354 echo "<p>Error message detected - PDF file generation aborted.</p>";
7355 echo $e['message'].'<br />';
7356 echo 'File: '.$e['file'].'<br />';
7357 echo 'Line: '.$e['line'].'<br />';
7358 exit;
7359 }
7360 }
7361
7362
7363 if (($this->PDFA || $this->PDFX) && $this->encrypted) { $this->Error("PDFA1-b or PDFX/1-a does not permit encryption of documents."); }
7364 if (count($this->PDFAXwarnings) && (($this->PDFA && !$this->PDFAauto) || ($this->PDFX && !$this->PDFXauto))) {
7365 if ($this->PDFA) {
7366 echo '<div>WARNING - This file could not be generated as it stands as a PDFA1-b compliant file.</div>';
7367 echo '<div>These issues can be automatically fixed by mPDF using <i>$mpdf-&gt;PDFAauto=true;</i></div>';
7368 echo '<div>Action that mPDF will take to automatically force PDFA1-b compliance are shown in brackets.</div>';
7369 }
7370 else {
7371 echo '<div>WARNING - This file could not be generated as it stands as a PDFX/1-a compliant file.</div>';
7372 echo '<div>These issues can be automatically fixed by mPDF using <i>$mpdf-&gt;PDFXauto=true;</i></div>';
7373 echo '<div>Action that mPDF will take to automatically force PDFX/1-a compliance are shown in brackets.</div>';
7374 }
7375 echo '<div>Warning(s) generated:</div><ul>';
7376 $this->PDFAXwarnings = array_unique($this->PDFAXwarnings);
7377 foreach($this->PDFAXwarnings AS $w) {
7378 echo '<li>'.$w.'</li>';
7379 }
7380 echo '</ul>';
7381 exit;
7382 }
7383
7384 if ($this->showStats) {
7385 echo '<div>Compiled in '.sprintf('%.2F',(microtime(true) - $this->time0)).' seconds (total)</div>';
7386 echo '<div>Peak Memory usage '.number_format((memory_get_peak_usage(true)/(1024*1024)),2).' MB</div>';
7387 echo '<div>PDF file size '.number_format((strlen($this->buffer)/1024)).' kB</div>';
7388 echo '<div>Number of fonts '.count($this->fonts).'</div>';
7389 exit;
7390 }
7391
7392
7393 if(is_bool($dest)) $dest=$dest ? 'D' : 'F';
7394 $dest=strtoupper($dest);
7395 if($dest=='') {
7396 if($name=='') {
7397 $name='mpdf.pdf';
7398 $dest='I';
7399 }
7400 else { $dest='F'; }
7401 }
7402
7403/*-- PROGRESS-BAR --*/
7404 if ($this->progressBar && ($dest=='D' || $dest=='I')) {
7405 if($name=='') { $name='mpdf.pdf'; }
7406 $tempfile = '_tempPDF'.uniqid(rand(1,100000),true);
7407 //Save to local file
7408 $f=fopen(_MPDF_TEMP_PATH.$tempfile.'.pdf','wb');
7409 if(!$f) $this->Error('Unable to create temporary output file: '.$tempfile.'.pdf');
7410 fwrite($f,$this->buffer,strlen($this->buffer));
7411 fclose($f);
7412 $this->UpdateProgressBar(3,'','Finished');
7413
7414 echo '<script type="text/javascript">
7415
7416 var form = document.createElement("form");
7417 form.setAttribute("method", "post");
7418 form.setAttribute("action", "'._MPDF_URI.'includes/out.php");
7419
7420 var hiddenField = document.createElement("input");
7421 hiddenField.setAttribute("type", "hidden");
7422 hiddenField.setAttribute("name", "filename");
7423 hiddenField.setAttribute("value", "'.$tempfile.'");
7424 form.appendChild(hiddenField);
7425
7426 var hiddenField = document.createElement("input");
7427 hiddenField.setAttribute("type", "hidden");
7428 hiddenField.setAttribute("name", "dest");
7429 hiddenField.setAttribute("value", "'.$dest.'");
7430 form.appendChild(hiddenField);
7431
7432 var hiddenField = document.createElement("input");
7433 hiddenField.setAttribute("type", "hidden");
7434 hiddenField.setAttribute("name", "opname");
7435 hiddenField.setAttribute("value", "'.$name.'");
7436 form.appendChild(hiddenField);
7437
7438 var hiddenField = document.createElement("input");
7439 hiddenField.setAttribute("type", "hidden");
7440 hiddenField.setAttribute("name", "path");
7441 hiddenField.setAttribute("value", "'.urlencode(_MPDF_TEMP_PATH).'");
7442 form.appendChild(hiddenField);
7443
7444 document.body.appendChild(form);
7445 form.submit();
7446
7447 </script>
7448 </div>
7449 </body>
7450 </html>';
7451 exit;
7452 }
7453 else {
7454 if ($this->progressBar) { $this->UpdateProgressBar(3,'','Finished'); }
7455/*-- END PROGRESS-BAR --*/
7456
7457 switch($dest) {
7458 case 'I':
7459 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; }
7460 //Send to standard output
7461 if(PHP_SAPI!='cli') {
7462 //We send to a browser
7463 header('Content-Type: application/pdf');
7464 if(headers_sent())
7465 $this->Error('Some data has already been output to browser, can\'t send PDF file');
7466 if (!isset($_SERVER['HTTP_ACCEPT_ENCODING']) OR empty($_SERVER['HTTP_ACCEPT_ENCODING'])) {
7467 // don't use length if server using compression
7468 header('Content-Length: '.strlen($this->buffer));
7469 }
7470 header('Content-disposition: inline; filename="'.$name.'"');
7471 header('Cache-Control: public, must-revalidate, max-age=0');
7472 header('Pragma: public');
7473 header('Expires: Sat, 26 Jul 1997 05:00:00 GMT');
7474 header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT');
7475 }
7476 echo $this->buffer;
7477 break;
7478 case 'D':
7479 //Download file
7480 header('Content-Description: File Transfer');
7481 if (headers_sent())
7482 $this->Error('Some data has already been output to browser, can\'t send PDF file');
7483 header('Content-Transfer-Encoding: binary');
7484 header('Cache-Control: public, must-revalidate, max-age=0');
7485 header('Pragma: public');
7486 header('Expires: Sat, 26 Jul 1997 05:00:00 GMT');
7487 header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT');
7488 header('Content-Type: application/force-download');
7489 header('Content-Type: application/octet-stream', false);
7490 header('Content-Type: application/download', false);
7491 header('Content-Type: application/pdf', false);
7492 if (!isset($_SERVER['HTTP_ACCEPT_ENCODING']) OR empty($_SERVER['HTTP_ACCEPT_ENCODING'])) {
7493 // don't use length if server using compression
7494 header('Content-Length: '.strlen($this->buffer));
7495 }
7496 header('Content-disposition: attachment; filename="'.$name.'"');
7497 echo $this->buffer;
7498 break;
7499 case 'F':
7500 //Save to local file
7501 $f=fopen($name,'wb');
7502 if(!$f) $this->Error('Unable to create output file: '.$name);
7503 fwrite($f,$this->buffer,strlen($this->buffer));
7504 fclose($f);
7505 break;
7506 case 'S':
7507 //Return as a string
7508 return $this->buffer;
7509 default:
7510 $this->Error('Incorrect output destination: '.$dest);
7511 }
7512
7513 } // *PROGRESS-BAR*
7514 //======================================================================================================
7515 // DELETE OLD TMP FILES - Housekeeping
7516 // Delete any files in tmp/ directory that are >1 hrs old
7517 $interval = 3600;
7518 if ($handle = opendir(preg_replace('/\/$/','',_MPDF_TEMP_PATH))) {
7519 while (false !== ($file = readdir($handle))) {
7520 if (!is_dir($file) && ((filemtime(_MPDF_TEMP_PATH.$file)+$interval) < time()) && ($file != "..") && ($file != ".") && (substr($file, 0, 1) !== '.') && ($file !='dummy.txt')) { // mPDF 5.7
7521 unlink(_MPDF_TEMP_PATH.$file);
7522 }
7523 }
7524 closedir($handle);
7525 }
7526 //==============================================================================================================
7527
7528 return '';
7529}
7530
7531
7532// *****************************************************************************
7533// *
7534// Protected methods *
7535// *
7536// *****************************************************************************
7537function _dochecks()
7538{
7539 //Check for locale-related bug
7540 if(1.1==1)
7541 $this->Error('Don\'t alter the locale before including mPDF');
7542 //Check for decimal separator
7543 if(sprintf('%.1f',1.0)!='1.0')
7544 setlocale(LC_NUMERIC,'C');
7545 // mPDF 5.4.11
7546 $mqr=ini_get("magic_quotes_runtime");
7547 if ($mqr) { $this->Error('mPDF requires magic_quotes_runtime to be turned off e.g. by using ini_set("magic_quotes_runtime", 0);'); }
7548}
7549
7550function _begindoc()
7551{
7552 //Start document
7553 $this->state=1;
7554 $this->_out('%PDF-'.$this->pdf_version);
7555 $this->_out('%'.chr(226).chr(227).chr(207).chr(211)); // 4 chars > 128 to show binary file
7556}
7557
7558
7559/*-- HTMLHEADERS-FOOTERS --*/
7560function _puthtmlheaders() {
7561 $this->state=2;
7562 $nb=$this->page;
7563 for($n=1;$n<=$nb;$n++) {
7564 if ($this->mirrorMargins && $n%2==0) { $OE = 'E'; } // EVEN
7565 else { $OE = 'O'; }
7566 $this->page = $n;
7567 if (isset($this->saveHTMLHeader[$n][$OE])) {
7568 $html = $this->saveHTMLHeader[$n][$OE]['html'];
7569 $this->lMargin = $this->saveHTMLHeader[$n][$OE]['ml'];
7570 $this->rMargin = $this->saveHTMLHeader[$n][$OE]['mr'];
7571 $this->tMargin = $this->saveHTMLHeader[$n][$OE]['mh'];
7572 $this->bMargin = $this->saveHTMLHeader[$n][$OE]['mf'];
7573 $this->margin_header = $this->saveHTMLHeader[$n][$OE]['mh'];
7574 $this->margin_footer = $this->saveHTMLHeader[$n][$OE]['mf'];
7575 $this->w = $this->saveHTMLHeader[$n][$OE]['pw'];
7576 $this->h = $this->saveHTMLHeader[$n][$OE]['ph'];
7577 $rotate = (isset($this->saveHTMLHeader[$n][$OE]['rotate']) ? $this->saveHTMLHeader[$n][$OE]['rotate'] : null);
7578 $this->Reset();
7579 $this->pageoutput[$n] = array();
7580 $this->pgwidth = $this->w - $this->lMargin - $this->rMargin;
7581 $this->x = $this->lMargin;
7582 $this->y = $this->margin_header;
7583 // mPDF 5.6.47
7584 $pn = $this->docPageNum($n);
7585 if ($pn)
7586 $pnstr = $this->pagenumPrefix.$pn.$this->pagenumSuffix;
7587 else { $pnstr = ''; }
7588 $html = str_replace('{PAGENO}',$pnstr,$html);
7589 $pnt = $this->docPageNumTotal($n);
7590 if ($pnt)
7591 $pntstr = $this->nbpgPrefix.$pnt.$this->nbpgSuffix;
7592 else { $pntstr = ''; }
7593 $html = str_replace($this->aliasNbPgGp,$pntstr,$html ); // {nbpg}
7594 $html = str_replace($this->aliasNbPg,$nb,$html ); // {nb}
7595 $html = preg_replace_callback('/\{DATE\s+(.*?)\}/', array($this, 'date_callback') ,$html ); // mPDF 5.7
7596
7597 $this->HTMLheaderPageLinks = array();
7598 $this->HTMLheaderPageAnnots = array();
7599 $this->HTMLheaderPageForms = array();
7600 $this->pageBackgrounds = array();
7601
7602 $this->writingHTMLheader = true;
7603 $this->WriteHTML($html , 4); // parameter 4 saves output to $this->headerbuffer
7604 $this->writingHTMLheader = false;
7605 $this->Reset();
7606 $this->pageoutput[$n] = array();
7607
7608 $s = $this->PrintPageBackgrounds();
7609 $this->headerbuffer = $s . $this->headerbuffer;
7610 $os = '';
7611 if ($rotate) {
7612 $os .= sprintf('q 0 -1 1 0 0 %.3F cm ',($this->w*_MPDFK));
7613 }
7614 $os .= $this->headerbuffer ;
7615 if ($rotate) {
7616 $os .= ' Q' . "\n";
7617 }
7618
7619 // Writes over the page background but behind any other output on page
7620 $os = preg_replace('/\\\\/','\\\\\\\\',$os);
7621 $this->pages[$n] = preg_replace('/(___HEADER___MARKER'.$this->uniqstr.')/', "\n".$os."\n".'\\1', $this->pages[$n]);
7622
7623 $lks = $this->HTMLheaderPageLinks;
7624 foreach($lks AS $lk) {
7625 if ($rotate) {
7626 $lw = $lk[2];
7627 $lh = $lk[3];
7628 $lk[2] = $lh;
7629 $lk[3] = $lw; // swap width and height
7630 $ax = $lk[0]/_MPDFK;
7631 $ay = $lk[1]/_MPDFK;
7632 $bx = $ay-($lh/_MPDFK);
7633 $by = $this->w-$ax;
7634 $lk[0] = $bx*_MPDFK;
7635 $lk[1] = ($this->h-$by)*_MPDFK - $lw;
7636 }
7637 $this->PageLinks[$n][]=$lk;
7638 }
7639/*-- FORMS --*/
7640 foreach($this->HTMLheaderPageForms AS $f) {
7641 $this->form->forms[$f['n']] = $f;
7642 }
7643/*-- END FORMS --*/
7644
7645
7646 }
7647 if (isset($this->saveHTMLFooter[$n][$OE])) {
7648 $html = $this->saveHTMLFooter[$this->page][$OE]['html'];
7649 $this->lMargin = $this->saveHTMLFooter[$n][$OE]['ml'];
7650 $this->rMargin = $this->saveHTMLFooter[$n][$OE]['mr'];
7651 $this->tMargin = $this->saveHTMLFooter[$n][$OE]['mh'];
7652 $this->bMargin = $this->saveHTMLFooter[$n][$OE]['mf'];
7653 $this->margin_header = $this->saveHTMLFooter[$n][$OE]['mh'];
7654 $this->margin_footer = $this->saveHTMLFooter[$n][$OE]['mf'];
7655 $this->w = $this->saveHTMLFooter[$n][$OE]['pw'];
7656 $this->h = $this->saveHTMLFooter[$n][$OE]['ph'];
7657 $rotate = (isset($this->saveHTMLFooter[$n][$OE]['rotate']) ? $this->saveHTMLFooter[$n][$OE]['rotate'] : null);
7658 $this->Reset();
7659 $this->pageoutput[$n] = array();
7660 $this->pgwidth = $this->w - $this->lMargin - $this->rMargin;
7661 $this->x = $this->lMargin;
7662 $top_y = $this->y = $this->h - $this->margin_footer;
7663
7664 // if bottom-margin==0, corrects to avoid division by zero
7665 if ($this->y == $this->h) { $top_y = $this->y = ($this->h - 0.1); }
7666 // mPDF 5.6.47
7667 $pn = $this->docPageNum($n);
7668 if ($pn)
7669 $pnstr = $this->pagenumPrefix.$pn.$this->pagenumSuffix;
7670 else { $pnstr = ''; }
7671 $html = str_replace('{PAGENO}',$pnstr,$html);
7672 $pnt = $this->docPageNumTotal($n);
7673 if ($pnt)
7674 $pntstr = $this->nbpgPrefix.$pnt.$this->nbpgSuffix;
7675 else { $pntstr = ''; }
7676 $html = str_replace($this->aliasNbPgGp,$pntstr,$html ); // {nbpg}
7677 $html = str_replace($this->aliasNbPg,$nb,$html ); // {nb}
7678 $html = preg_replace_callback('/\{DATE\s+(.*?)\}/', array($this, 'date_callback') ,$html ); // mPDF 5.7
7679
7680
7681 $this->HTMLheaderPageLinks = array();
7682 $this->HTMLheaderPageAnnots = array();
7683 $this->HTMLheaderPageForms = array();
7684 $this->pageBackgrounds = array();
7685
7686 $this->writingHTMLfooter = true;
7687 $this->InFooter = true;
7688 $this->WriteHTML($html , 4); // parameter 4 saves output to $this->headerbuffer
7689 $this->writingHTMLfooter = false;
7690 $this->InFooter = false;
7691 $this->Reset();
7692 $this->pageoutput[$n] = array();
7693
7694 $fheight = $this->y - $top_y;
7695 $adj = -$fheight;
7696
7697 $s = $this->PrintPageBackgrounds(-$adj);
7698 $this->headerbuffer = $s . $this->headerbuffer;
7699
7700 $os = '';
7701 $os .= $this->StartTransform(true)."\n";
7702 if ($rotate) {
7703 $os .= sprintf('q 0 -1 1 0 0 %.3F cm ',($this->w*_MPDFK));
7704 }
7705 $os .= $this->transformTranslate(0, $adj, true)."\n";
7706 $os .= $this->headerbuffer ;
7707 if ($rotate) {
7708 $os .= ' Q' . "\n";
7709 }
7710 $os .= $this->StopTransform(true)."\n";
7711 // Writes over the page background but behind any other output on page
7712 $os = preg_replace('/\\\\/','\\\\\\\\',$os);
7713 $this->pages[$n] = preg_replace('/(___HEADER___MARKER'.$this->uniqstr.')/', "\n".$os."\n".'\\1', $this->pages[$n]);
7714
7715 $lks = $this->HTMLheaderPageLinks;
7716 foreach($lks AS $lk) {
7717 $lk[1] -= $adj*_MPDFK;
7718 if ($rotate) {
7719 $lw = $lk[2];
7720 $lh = $lk[3];
7721 $lk[2] = $lh;
7722 $lk[3] = $lw; // swap width and height
7723
7724 $ax = $lk[0]/_MPDFK;
7725 $ay = $lk[1]/_MPDFK;
7726 $bx = $ay-($lh/_MPDFK);
7727 $by = $this->w-$ax;
7728 $lk[0] = $bx*_MPDFK;
7729 $lk[1] = ($this->h-$by)*_MPDFK - $lw;
7730 }
7731 $this->PageLinks[$n][]=$lk;
7732 }
7733/*-- FORMS --*/
7734 foreach($this->HTMLheaderPageForms AS $f) {
7735 $f['y'] += $adj;
7736 $this->form->forms[$f['n']] = $f;
7737 }
7738/*-- END FORMS --*/
7739 }
7740 }
7741 $this->page=$nb;
7742 $this->state=1;
7743}
7744/*-- END HTMLHEADERS-FOOTERS --*/
7745
7746
7747function _putpages()
7748{
7749 $nb=$this->page;
7750 $filter=($this->compress) ? '/Filter /FlateDecode ' : '';
7751
7752 if($this->DefOrientation=='P') {
7753 $defwPt=$this->fwPt;
7754 $defhPt=$this->fhPt;
7755 }
7756 else {
7757 $defwPt=$this->fhPt;
7758 $defhPt=$this->fwPt;
7759 }
7760 $annotid=(3+2*$nb);
7761
7762 // Active Forms
7763 $totaladdnum = 0;
7764 for($n=1;$n<=$nb;$n++) {
7765 if (isset($this->PageLinks[$n])) { $totaladdnum += count($this->PageLinks[$n]); }
7766/*-- ANNOTATIONS --*/
7767 if (isset($this->PageAnnots[$n])) {
7768 foreach ($this->PageAnnots[$n] as $k => $pl) {
7769 if (!empty($pl['opt']['popup']) || !empty($pl['opt']['file'])) { $totaladdnum += 2 ; }
7770 else { $totaladdnum++; }
7771 }
7772 }
7773/*-- END ANNOTATIONS --*/
7774
7775/*-- FORMS --*/
7776 if ( count($this->form->forms) > 0 ) {
7777 $this->form->countPageForms($n, $totaladdnum);
7778 }
7779/*-- END FORMS --*/
7780 }
7781/*-- FORMS --*/
7782 // Make a note in the radio button group of the obj_id it will have
7783 $ctr = 0;
7784 if (count($this->form->form_radio_groups)) {
7785 foreach($this->form->form_radio_groups AS $name=>$frg) {
7786 $this->form->form_radio_groups[$name]['obj_id'] = $annotid + $totaladdnum + $ctr;
7787 $ctr++;
7788 }
7789 }
7790/*-- END FORMS --*/
7791
7792 // Select unused fonts (usually default font)
7793 $unused = array();
7794 foreach($this->fonts as $fk=>$font) {
7795 if (!$font['used'] && ($font['type']=='TTF')) {
7796 $unused[] = $fk;
7797 }
7798 }
7799
7800
7801 for($n=1;$n<=$nb;$n++)
7802 {
7803 $thispage = $this->pages[$n];
7804// unset($this->pages[$n]); // mPDF 5.6.47
7805 if(isset($this->OrientationChanges[$n])) {
7806 $hPt=$this->pageDim[$n]['w']*_MPDFK;
7807 $wPt=$this->pageDim[$n]['h']*_MPDFK;
7808 $owidthPt_LR = $this->pageDim[$n]['outer_width_TB']*_MPDFK;
7809 $owidthPt_TB = $this->pageDim[$n]['outer_width_LR']*_MPDFK;
7810 }
7811 else {
7812 $wPt=$this->pageDim[$n]['w']*_MPDFK;
7813 $hPt=$this->pageDim[$n]['h']*_MPDFK;
7814 $owidthPt_LR = $this->pageDim[$n]['outer_width_LR']*_MPDFK;
7815 $owidthPt_TB = $this->pageDim[$n]['outer_width_TB']*_MPDFK;
7816 }
7817 // Remove references to unused fonts (usually default font)
7818 foreach($unused as $fk) {
7819 if ($this->fonts[$fk]['sip'] || $this->fonts[$fk]['smp']) {
7820 foreach($this->fonts[$fk]['subsetfontids'] AS $k => $fid) {
7821 $thispage = preg_replace('/\s\/F'.$fid.' \d[\d.]* Tf\s/is',' ',$thispage);
7822 }
7823 }
7824 else {
7825 $thispage = preg_replace('/\s\/F'.$this->fonts[$fk]['i'].' \d[\d.]* Tf\s/is',' ',$thispage);
7826 }
7827 }
7828 //Replace number of pages
7829 if(!empty($this->aliasNbPg)) {
7830 if (!$this->onlyCoreFonts) { $s1 = $this->UTF8ToUTF16BE($this->aliasNbPg, false); }
7831 $s2 = $this->aliasNbPg;
7832 if (!$this->onlyCoreFonts) { $r1 = $this->UTF8ToUTF16BE($nb, false); }
7833 $r2 = $nb;
7834 if (preg_match_all('/{mpdfheadernbpg (C|R) ff=(\S*) fs=(\S*) fz=(.*?)}/',$thispage,$m)) {
7835 for($hi=0;$hi<count($m[0]);$hi++) {
7836 $pos = $m[1][$hi];
7837 $hff = $m[2][$hi];
7838 $hfst = $m[3][$hi];
7839 $hfsz = $m[4][$hi];
7840 $this->SetFont($hff,$hfst,$hfsz, false);
7841 $x1 = $this->GetStringWidth($this->aliasNbPg);
7842 $x2 = $this->GetStringWidth($nb);
7843 $xadj = $x1 - $x2;
7844 if ($pos=='C') { $xadj /= 2; }
7845 $rep = sprintf(' q 1 0 0 1 %.3F 0 cm ', $xadj*_MPDFK);
7846 $thispage = str_replace($m[0][$hi], $rep, $thispage);
7847 }
7848 }
7849 if (!$this->onlyCoreFonts) { $thispage=str_replace($s1,$r1,$thispage); }
7850 $thispage=str_replace($s2,$r2,$thispage);
7851
7852 // And now for any SMP/SIP fonts subset using <HH> format
7853 $r = '';
7854 $nstr = "$nb";
7855 for($i=0;$i<strlen($nstr);$i++) {
7856 $r .= sprintf("%02s", strtoupper(dechex(intval($nstr[$i])+48)));
7857 }
7858 $thispage=str_replace($this->aliasNbPgHex,$r,$thispage);
7859
7860 }
7861 //Replace number of pages in group
7862 if(!empty($this->aliasNbPgGp)) {
7863 if (!$this->onlyCoreFonts) { $s1 = $this->UTF8ToUTF16BE($this->aliasNbPgGp, false); }
7864 $s2 = $this->aliasNbPgGp;
7865 $nbt = $this->docPageNumTotal($n);
7866 if (!$this->onlyCoreFonts) { $r1 = $this->UTF8ToUTF16BE($nbt, false); }
7867 $r2 = $nbt;
7868 if (preg_match_all('/{mpdfheadernbpggp (C|R) ff=(\S*) fs=(\S*) fz=(.*?)}/',$thispage,$m)) {
7869 for($hi=0;$hi<count($m[0]);$hi++) {
7870 $pos = $m[1][$hi];
7871 $hff = $m[2][$hi];
7872 $hfst = $m[3][$hi];
7873 $hfsz = $m[4][$hi];
7874 $this->SetFont($hff,$hfst,$hfsz, false);
7875 $x1 = $this->GetStringWidth($this->aliasNbPgGp);
7876 $x2 = $this->GetStringWidth($nbt);
7877 $xadj = $x1 - $x2;
7878 if ($pos=='C') { $xadj /= 2; }
7879 $rep = sprintf(' q 1 0 0 1 %.3F 0 cm ', $xadj*_MPDFK);
7880 $thispage = str_replace($m[0][$hi], $rep, $thispage);
7881 }
7882 }
7883 if (!$this->onlyCoreFonts) { $thispage=str_replace($s1,$r1,$thispage); }
7884 $thispage=str_replace($s2,$r2,$thispage);
7885
7886 // And now for any SMP/SIP fonts subset using <HH> format
7887 $r = '';
7888 $nstr = "$nbt";
7889 for($i=0;$i<strlen($nstr);$i++) {
7890 $r .= sprintf("%02s", strtoupper(dechex(intval($nstr[$i])+48)));
7891 }
7892 $thispage=str_replace($this->aliasNbPgGpHex,$r,$thispage);
7893
7894 }
7895 $thispage = preg_replace('/(\s*___BACKGROUND___PATTERNS'.$this->uniqstr.'\s*)/', " ", $thispage);
7896 $thispage = preg_replace('/(\s*___HEADER___MARKER'.$this->uniqstr.'\s*)/', " ", $thispage);
7897 $thispage = preg_replace('/(\s*___PAGE___START'.$this->uniqstr.'\s*)/', " ", $thispage);
7898 $thispage = preg_replace('/(\s*___TABLE___BACKGROUNDS'.$this->uniqstr.'\s*)/', " ", $thispage);
7899
7900 //Page
7901 $this->_newobj();
7902 $this->_out('<</Type /Page');
7903 $this->_out('/Parent 1 0 R');
7904 if(isset($this->OrientationChanges[$n])) {
7905 $this->_out(sprintf('/MediaBox [0 0 %.3F %.3F]',$hPt,$wPt));
7906 //If BleedBox is defined, it must be larger than the TrimBox, but smaller than the MediaBox
7907 $bleedMargin = $this->pageDim[$n]['bleedMargin']*_MPDFK;
7908 if ($bleedMargin && ($owidthPt_TB || $owidthPt_LR)) {
7909 $x0 = $owidthPt_TB-$bleedMargin;
7910 $y0 = $owidthPt_LR-$bleedMargin;
7911 $x1 = $hPt-$owidthPt_TB+$bleedMargin;
7912 $y1 = $wPt-$owidthPt_LR+$bleedMargin;
7913 $this->_out(sprintf('/BleedBox [%.3F %.3F %.3F %.3F]', $x0, $y0, $x1, $y1));
7914 }
7915 $this->_out(sprintf('/TrimBox [%.3F %.3F %.3F %.3F]', $owidthPt_TB, $owidthPt_LR, ($hPt-$owidthPt_TB), ($wPt-$owidthPt_LR)));
7916 if (isset($this->OrientationChanges[$n]) && $this->displayDefaultOrientation) {
7917 if ($this->DefOrientation=='P') { $this->_out('/Rotate 270'); }
7918 else { $this->_out('/Rotate 90'); }
7919 }
7920 }
7921 //else if($wPt != $defwPt || $hPt != $defhPt) {
7922 else {
7923 $this->_out(sprintf('/MediaBox [0 0 %.3F %.3F]',$wPt,$hPt));
7924 $bleedMargin = $this->pageDim[$n]['bleedMargin']*_MPDFK;
7925 if ($bleedMargin && ($owidthPt_TB || $owidthPt_LR)) {
7926 $x0 = $owidthPt_LR-$bleedMargin;
7927 $y0 = $owidthPt_TB-$bleedMargin;
7928 $x1 = $wPt-$owidthPt_LR+$bleedMargin;
7929 $y1 = $hPt-$owidthPt_TB+$bleedMargin;
7930 $this->_out(sprintf('/BleedBox [%.3F %.3F %.3F %.3F]', $x0, $y0, $x1, $y1));
7931 }
7932 $this->_out(sprintf('/TrimBox [%.3F %.3F %.3F %.3F]', $owidthPt_LR, $owidthPt_TB, ($wPt-$owidthPt_LR), ($hPt-$owidthPt_TB)));
7933 }
7934 $this->_out('/Resources 2 0 R');
7935
7936 // Important to keep in RGB colorSpace when using transparency
7937 if (!$this->PDFA && !$this->PDFX) {
7938 if ($this->restrictColorSpace == 3)
7939 $this->_out('/Group << /Type /Group /S /Transparency /CS /DeviceCMYK >> ');
7940 else if ($this->restrictColorSpace == 1)
7941 $this->_out('/Group << /Type /Group /S /Transparency /CS /DeviceGray >> ');
7942 else
7943 $this->_out('/Group << /Type /Group /S /Transparency /CS /DeviceRGB >> ');
7944 }
7945
7946 $annotsnum = 0;
7947 $embeddedfiles = array(); // mPDF 5.7.2 /EmbeddedFiles
7948
7949 if (isset($this->PageLinks[$n])) { $annotsnum += count($this->PageLinks[$n]); }
7950/*-- ANNOTATIONS --*/
7951 if (isset($this->PageAnnots[$n])) {
7952 foreach ($this->PageAnnots[$n] as $k => $pl) {
7953 if (!empty($pl['opt']['file'])) { $embeddedfiles[$annotsnum+1] = true ; } // mPDF 5.7.2 /EmbeddedFiles
7954 if (!empty($pl['opt']['popup']) || !empty($pl['opt']['file'])) { $annotsnum += 2 ; }
7955 else { $annotsnum++; }
7956 $this->PageAnnots[$n][$k]['pageobj'] = $this->n;
7957 }
7958 }
7959/*-- END ANNOTATIONS --*/
7960
7961/*-- FORMS --*/
7962 // Active Forms
7963 $formsnum = 0;
7964 if ( count($this->form->forms) > 0 ) {
7965 foreach( $this->form->forms as $val ) {
7966 if ( $val['page'] == $n )
7967 $formsnum++;
7968 }
7969 }
7970/*-- END FORMS --*/
7971 if ($annotsnum || $formsnum) {
7972 $s = '/Annots [ ';
7973 for($i=0;$i<$annotsnum;$i++) {
7974 if (!isset($embeddedfiles[$i])) { $s .= ($annotid + $i) . ' 0 R '; } // mPDF 5.7.2 /EmbeddedFiles
7975 }
7976 $annotid += $annotsnum;
7977/*-- FORMS --*/
7978 if ( count($this->form->forms) > 0 ) {
7979 $this->form->addFormIds($n, $s, $annotid);
7980 }
7981/*-- END FORMS --*/
7982 $s .= '] ';
7983 $this->_out($s);
7984 }
7985
7986 $this->_out('/Contents '.($this->n+1).' 0 R>>');
7987 $this->_out('endobj');
7988
7989 //Page content
7990 $this->_newobj();
7991 $p=($this->compress) ? gzcompress($thispage) : $thispage;
7992 $this->_out('<<'.$filter.'/Length '.strlen($p).'>>');
7993 $this->_putstream($p);
7994 $this->_out('endobj');
7995 }
7996 $this->_putannots(); // mPDF 5.7.2
7997
7998 //Pages root
7999 $this->offsets[1]=strlen($this->buffer);
8000 $this->_out('1 0 obj');
8001 $this->_out('<</Type /Pages');
8002 $kids='/Kids [';
8003 for($i=0;$i<$nb;$i++)
8004 $kids.=(3+2*$i).' 0 R ';
8005 $this->_out($kids.']');
8006 $this->_out('/Count '.$nb);
8007 $this->_out(sprintf('/MediaBox [0 0 %.3F %.3F]',$defwPt,$defhPt));
8008 $this->_out('>>');
8009 $this->_out('endobj');
8010}
8011
8012
8013function _putannots() { // mPDF 5.7.2
8014 $filter=($this->compress) ? '/Filter /FlateDecode ' : '';
8015 $nb=$this->page;
8016 for($n=1;$n<=$nb;$n++)
8017 {
8018 $annotobjs = array();
8019 if(isset($this->PageLinks[$n]) || isset($this->PageAnnots[$n]) || count($this->form->forms) > 0 ) {
8020 $wPt=$this->pageDim[$n]['w']*_MPDFK;
8021 $hPt=$this->pageDim[$n]['h']*_MPDFK;
8022
8023 //Links
8024 if(isset($this->PageLinks[$n])) {
8025 foreach($this->PageLinks[$n] as $key => $pl) {
8026 $this->_newobj();
8027 $annot='';
8028 $rect=sprintf('%.3F %.3F %.3F %.3F',$pl[0],$pl[1],$pl[0]+$pl[2],$pl[1]-$pl[3]);
8029 $annot .= '<</Type /Annot /Subtype /Link /Rect ['.$rect.']';
8030 $annot .= ' /Contents '.$this->_UTF16BEtextstring($pl[4]);
8031 $annot .= ' /NM '.$this->_textstring(sprintf('%04u-%04u', $n, $key));
8032 $annot .= ' /M '.$this->_textstring('D:'.date('YmdHis'));
8033 $annot .= ' /Border [0 0 0]';
8034 // Use this (instead of /Border) to specify border around link
8035 // $annot .= ' /BS <</W 1'; // Width on points; 0 = no line
8036 // $annot .= ' /S /D'; // style - [S]olid, [D]ashed, [B]eveled, [I]nset, [U]nderline
8037 // $annot .= ' /D [3 2]'; // Dash array - if dashed
8038 // $annot .= ' >>';
8039 // $annot .= ' /C [1 0 0]'; // Color RGB
8040
8041 if ($this->PDFA || $this->PDFX) { $annot .= ' /F 28'; }
8042 if (strpos($pl[4],'@')===0) {
8043 $p=substr($pl[4],1);
8044 // $h=isset($this->OrientationChanges[$p]) ? $wPt : $hPt;
8045 $htarg=$this->pageDim[$p]['h']*_MPDFK;
8046 $annot.=sprintf(' /Dest [%d 0 R /XYZ 0 %.3F null]>>',1+2*$p,$htarg);
8047 }
8048 else if(is_string($pl[4])) {
8049 $annot .= ' /A <</S /URI /URI '.$this->_textstring($pl[4]).'>> >>';
8050 }
8051 else {
8052 $l=$this->links[$pl[4]];
8053 // may not be set if #link points to non-existent target
8054 if (isset($this->pageDim[$l[0]]['h'])) { $htarg=$this->pageDim[$l[0]]['h']*_MPDFK; }
8055 else { $htarg=$this->h*_MPDFK; } // doesn't really matter
8056 $annot.=sprintf(' /Dest [%d 0 R /XYZ 0 %.3F null]>>',1+2*$l[0],$htarg-$l[1]*_MPDFK);
8057 }
8058 $this->_out($annot);
8059 $this->_out('endobj');
8060 }
8061 }
8062
8063
8064/*-- ANNOTATIONS --*/
8065 if(isset($this->PageAnnots[$n])) {
8066 foreach ($this->PageAnnots[$n] as $key => $pl) {
8067 if ($pl['opt']['file']) { $FileAttachment=true; }
8068 else { $FileAttachment=false; }
8069 $this->_newobj();
8070 $annot='';
8071 $pl['opt'] = array_change_key_case($pl['opt'], CASE_LOWER);
8072 $x = $pl['x'];
8073 if ($this->annotMargin <> 0 || $x==0 || $x<0) { // Odd page
8074 $x = ($wPt/_MPDFK) - $this->annotMargin;
8075 }
8076 $w = $h = 0;
8077 $a = $x * _MPDFK;
8078 $b = $hPt - ($pl['y'] * _MPDFK);
8079 $annot .= '<</Type /Annot ';
8080 if ($FileAttachment) {
8081 $annot .= '/Subtype /FileAttachment';
8082 // Need to set a size for FileAttachment icons
8083 if ($pl['opt']['icon']=='Paperclip') { $w=8.235; $h=20; } // 7,17
8084 else if ($pl['opt']['icon']=='Tag') { $w=20; $h=16; }
8085 else if ($pl['opt']['icon']=='Graph') { $w=20; $h=20; }
8086 else { $w=14; $h=20; } // PushPin
8087 $f = $pl['opt']['file'];
8088 $f = preg_replace('/^.*\//', '', $f);
8089 $f = preg_replace('/[^a-zA-Z0-9._]/', '', $f);
8090 $annot .= '/FS <</Type /Filespec /F ('.$f.')';
8091 $annot .= '/EF <</F '.($this->n+1).' 0 R>>';
8092 $annot .= '>>';
8093 }
8094 else {
8095 $annot .= '/Subtype /Text';
8096 }
8097 $rect = sprintf('%.3F %.3F %.3F %.3F', $a, $b-$h, $a+$w, $b);
8098 $annot .= '/Rect ['.$rect.']';
8099
8100 // contents = description of file in free text
8101 $annot .= ' /Contents '.$this->_UTF16BEtextstring($pl['txt']);
8102 $annot .= ' /NM '.$this->_textstring(sprintf('%04u-%04u', $n, (2000 + $key)));
8103 $annot .= ' /M '.$this->_textstring('D:'.date('YmdHis'));
8104 $annot .= ' /CreationDate '.$this->_textstring('D:'.date('YmdHis'));
8105 $annot .= ' /Border [0 0 0]';
8106 if ($this->PDFA || $this->PDFX) {
8107 $annot .= ' /F 28';
8108 $annot .= ' /CA 1';
8109 }
8110 else if ($pl['opt']['ca']>0) { $annot .= ' /CA '.$pl['opt']['ca']; }
8111
8112 $annotcolor = ' /C [';
8113 if (isset($pl['opt']['c']) AND $pl['opt']['c']) {
8114 $col = $pl['opt']['c'];
8115 if ($col{0}==3 || $col{0}==5) { $annotcolor .= sprintf("%.3F %.3F %.3F", ord($col{1})/255,ord($col{2})/255,ord($col{3})/255); }
8116 else if ($col{0}==1) { $annotcolor .= sprintf("%.3F", ord($col{1})/255); }
8117 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); }
8118 else { $annotcolor .= '1 1 0'; }
8119 }
8120 else { $annotcolor .= '1 1 0'; }
8121 $annotcolor .= ']';
8122 $annot .= $annotcolor;
8123 // Usually Author
8124 // Use as Title for fileattachment
8125 if (isset($pl['opt']['t']) AND is_string($pl['opt']['t'])) {
8126 $annot .= ' /T '.$this->_UTF16BEtextstring($pl['opt']['t']);
8127 }
8128 if ($FileAttachment) {
8129 $iconsapp = array('Paperclip', 'Graph', 'PushPin', 'Tag');
8130 }
8131 else { $iconsapp = array('Comment', 'Help', 'Insert', 'Key', 'NewParagraph', 'Note', 'Paragraph'); }
8132 if (isset($pl['opt']['icon']) AND in_array($pl['opt']['icon'], $iconsapp)) {
8133 $annot .= ' /Name /'.$pl['opt']['icon'];
8134 }
8135 else if ($FileAttachment) { $annot .= ' /Name /PushPin'; }
8136 else { $annot .= ' /Name /Note'; }
8137 if (!$FileAttachment) {
8138 // /Subj is PDF 1.5 spec.
8139 if (isset($pl['opt']['subj']) && !$this->PDFA && !$this->PDFX) {
8140 $annot .= ' /Subj '.$this->_UTF16BEtextstring($pl['opt']['subj']);
8141 }
8142 if (!empty($pl['opt']['popup'])) {
8143 $annot .= ' /Open true';
8144 $annot .= ' /Popup '.($this->n+1).' 0 R';
8145 }
8146 else { $annot .= ' /Open false'; }
8147 }
8148 $annot .= ' /P '.$pl['pageobj'].' 0 R';
8149 $annot .= '>>';
8150 $this->_out($annot);
8151 $this->_out('endobj');
8152
8153 if ($FileAttachment) {
8154 $file = @file_get_contents($pl['opt']['file']) or die('mPDF Error: Cannot access file attachment - '.$pl['opt']['file']);
8155 $filestream = gzcompress($file);
8156 $this->_newobj();
8157 $this->_out('<</Type /EmbeddedFile');
8158 $this->_out('/Length '.strlen($filestream));
8159 $this->_out('/Filter /FlateDecode');
8160 $this->_out('>>');
8161 $this->_putstream($filestream);
8162 $this->_out('endobj');
8163 }
8164 else if (!empty($pl['opt']['popup'])) {
8165 $this->_newobj();
8166 $annot='';
8167 if (is_array($pl['opt']['popup']) && isset($pl['opt']['popup'][0])) { $x = $pl['opt']['popup'][0] * _MPDFK; }
8168 else { $x = $pl['x'] * _MPDFK; }
8169 if (is_array($pl['opt']['popup']) && isset($pl['opt']['popup'][1])) { $y = $hPt - ($pl['opt']['popup'][1] * _MPDFK); }
8170 else { $y = $hPt - ($pl['y'] * _MPDFK); }
8171 if (is_array($pl['opt']['popup']) && isset($pl['opt']['popup'][2])) { $w = $pl['opt']['popup'][2] * _MPDFK; }
8172 else { $w = 180; }
8173 if (is_array($pl['opt']['popup']) && isset($pl['opt']['popup'][3])) { $h = $pl['opt']['popup'][3] * _MPDFK; }
8174 else { $h = 120; }
8175 $rect = sprintf('%.3F %.3F %.3F %.3F', $x, $y-$h, $x+$w, $y);
8176 $annot .= '<</Type /Annot /Subtype /Popup /Rect ['.$rect.']';
8177 $annot .= ' /M '.$this->_textstring('D:'.date('YmdHis'));
8178 if ($this->PDFA || $this->PDFX) { $annot .= ' /F 28'; }
8179 $annot .= ' /Parent '.($this->n-1).' 0 R';
8180 $annot .= '>>';
8181 $this->_out($annot);
8182 $this->_out('endobj');
8183 }
8184 }
8185 }
8186/*-- END ANNOTATIONS --*/
8187
8188/*-- FORMS --*/
8189 // Active Forms
8190 if ( count($this->form->forms) > 0 ) {
8191 $this->form->_putFormItems($n, $hPt);
8192 }
8193/*-- END FORMS --*/
8194 }
8195 }
8196/*-- FORMS --*/
8197 // Active Forms - Radio Button Group entries
8198 // Output Radio Button Group form entries (radio_on_obj_id already determined)
8199 if (count($this->form->form_radio_groups)) {
8200 $this->form->_putRadioItems($n);
8201 }
8202/*-- END FORMS --*/
8203}
8204
8205
8206/*-- ANNOTATIONS --*/
8207function Annotation($text, $x=0, $y=0, $icon='Note', $author='', $subject='', $opacity=0, $colarray=false, $popup='', $file='') {
8208 if (is_array($colarray) && count($colarray)==3) { $colarray = $this->ConvertColor('rgb('.$colarray[0].','.$colarray[1].','.$colarray[2].')'); }
8209 if ($colarray === false) { $colarray = $this->ConvertColor('yellow'); }
8210 if ($x==0) { $x = $this->x; }
8211 if ($y==0) { $y = $this->y; }
8212 $page = $this->page;
8213 if ($page < 1) { // Document has not been started - assume it's for first page
8214 $page = 1;
8215 if ($x==0) { $x = $this->lMargin; }
8216 if ($y==0) { $y = $this->tMargin; }
8217 }
8218
8219 if ($this->PDFA || $this->PDFX) {
8220 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)"; }
8221 $x = ($this->w) - $this->rMargin*0.66;
8222 }
8223 if (!$this->annotMargin) { $y -= $this->FontSize / 2; }
8224
8225 if (!$opacity && $this->annotMargin) { $opacity = 1; }
8226 else if (!$opacity) { $opacity = $this->annotOpacity; }
8227
8228 $an = array('txt' => $text, 'x' => $x, 'y' => $y, 'opt' => array('Icon'=>$icon, 'T'=>$author, 'Subj'=>$subject, 'C'=>$colarray, 'CA'=>$opacity, 'popup'=>$popup, 'file'=>$file));
8229
8230 if ($this->keep_block_together) { // Save to array - don't write yet
8231 $this->ktAnnots[$this->page][]= $an;
8232 return;
8233 }
8234 else if ($this->table_rotate) {
8235 $this->tbrot_Annots[$this->page][]= $an;
8236 return;
8237 }
8238 else if ($this->kwt) {
8239 $this->kwt_Annots[$this->page][]= $an;
8240 return;
8241 }
8242 // mPDF 5.0
8243 if ($this->writingHTMLheader || $this->writingHTMLfooter) {
8244 $this->HTMLheaderPageAnnots[]= $an;
8245 return;
8246 }
8247 //Put an Annotation on the page
8248 $this->PageAnnots[$page][] = $an;
8249/*-- COLUMNS --*/
8250 // Save cross-reference to Column buffer
8251 $ref = count($this->PageAnnots[$this->page])-1;
8252 $this->columnAnnots[$this->CurrCol][INTVAL($this->x)][INTVAL($this->y)] = $ref;
8253/*-- END COLUMNS --*/
8254}
8255/*-- END ANNOTATIONS --*/
8256
8257
8258function _putfonts() {
8259 $nf=$this->n;
8260 foreach($this->FontFiles as $fontkey=>$info) {
8261 // TrueType embedded
8262 if (isset($info['type']) && $info['type']=='TTF' && !$info['sip'] && !$info['smp']) {
8263 $used = true;
8264 $asSubset = false;
8265 foreach($this->fonts AS $k=>$f) {
8266 if ($f['fontkey'] == $fontkey && $f['type']=='TTF') {
8267 $used = $f['used'];
8268 if ($used) {
8269 $nChars = (ord($f['cw'][0]) << 8) + ord($f['cw'][1]);
8270 $usage = intval(count($f['subset'])*100 / $nChars);
8271 $fsize = $info['length1'];
8272 // Always subset the very large TTF files
8273 if ($fsize > ($this->maxTTFFilesize *1024)) { $asSubset = true; }
8274 else if ($usage < $this->percentSubset) { $asSubset = true; }
8275 }
8276 if ($f['unAGlyphs']) $aaSubset = true; // mPDF 5.4.05
8277 if ($this->PDFA || $this->PDFX) $asSubset = false;
8278 $this->fonts[$k]['asSubset'] = $asSubset;
8279 break;
8280 }
8281 }
8282 if ($used && !$asSubset) {
8283 //Font file embedding
8284 $this->_newobj();
8285 $this->FontFiles[$fontkey]['n']=$this->n;
8286 $font='';
8287 $originalsize = $info['length1'];
8288 if ($this->repackageTTF || $this->fonts[$fontkey]['TTCfontID']>0) {
8289 // First see if there is a cached compressed file
8290 if (file_exists(_MPDF_TTFONTDATAPATH.$fontkey.'.ps.z')) {
8291 $f=fopen(_MPDF_TTFONTDATAPATH.$fontkey.'.ps.z','rb');
8292 if(!$f) { $this->Error('Font file .ps.z not found'); }
8293 while(!feof($f)) { $font .= fread($f, 2048); }
8294 fclose($f);
8295 include(_MPDF_TTFONTDATAPATH.$fontkey.'.ps.php'); // sets $originalsize (of repackaged font)
8296 }
8297 else {
8298 if (!class_exists('TTFontFile', false)) { include(_MPDF_PATH .'classes/ttfontsuni.php'); }
8299 $ttf = new TTFontFile();
8300 $font = $ttf->repackageTTF($this->FontFiles[$fontkey]['ttffile'], $this->fonts[$fontkey]['TTCfontID'], $this->debugfonts, $this->fonts[$fontkey]['unAGlyphs']); // mPDF 5.4.05
8301
8302 $originalsize = strlen($font);
8303 $font = gzcompress($font);
8304 unset($ttf);
8305 if (is_writable(dirname(_MPDF_TTFONTDATAPATH.'x'))) {
8306 $fh = fopen(_MPDF_TTFONTDATAPATH.$fontkey.'.ps.z',"wb");
8307 fwrite($fh,$font,strlen($font));
8308 fclose($fh);
8309 $fh = fopen(_MPDF_TTFONTDATAPATH.$fontkey.'.ps.php',"wb");
8310 $len = "<?php \n";
8311 $len.='$originalsize='.$originalsize.";\n";
8312 $len.="?>";
8313 fwrite($fh,$len,strlen($len));
8314 fclose($fh);
8315 }
8316 }
8317 }
8318 else {
8319 // First see if there is a cached compressed file
8320 if (file_exists(_MPDF_TTFONTDATAPATH.$fontkey.'.z')) {
8321 $f=fopen(_MPDF_TTFONTDATAPATH.$fontkey.'.z','rb');
8322 if(!$f) { $this->Error('Font file not found'); }
8323 while(!feof($f)) { $font .= fread($f, 2048); }
8324 fclose($f);
8325 }
8326 else {
8327 $f=fopen($this->FontFiles[$fontkey]['ttffile'],'rb');
8328 if(!$f) { $this->Error('Font file not found'); }
8329 while(!feof($f)) { $font .= fread($f, 2048); }
8330 fclose($f);
8331 $font = gzcompress($font);
8332 if (is_writable(dirname(_MPDF_TTFONTDATAPATH.'x'))) {
8333 $fh = fopen(_MPDF_TTFONTDATAPATH.$fontkey.'.z',"wb");
8334 fwrite($fh,$font,strlen($font));
8335 fclose($fh);
8336 }
8337 }
8338 }
8339
8340 $this->_out('<</Length '.strlen($font));
8341 $this->_out('/Filter /FlateDecode');
8342 $this->_out('/Length1 '.$originalsize);
8343 $this->_out('>>');
8344 $this->_putstream($font);
8345 $this->_out('endobj');
8346 }
8347 }
8348 }
8349
8350 $nfonts = count($this->fonts);
8351 $fctr = 1;
8352 foreach($this->fonts as $k=>$font) {
8353 //Font objects
8354 $type=$font['type'];
8355 $name=$font['name'];
8356 if ((!isset($font['used']) || !$font['used']) && $type=='TTF') { continue; }
8357 if ($this->progressBar) { $this->UpdateProgressBar(2,intval($fctr*100/$nfonts),'Writing Fonts'); $fctr++; } // *PROGRESS-BAR*
8358 if (isset($font['asSubset'])) { $asSubset = $font['asSubset']; }
8359 else { $asSubset = ''; }
8360/*-- CJK-FONTS --*/
8361 if($type=='Type0') { // = Adobe CJK Fonts
8362 $this->fonts[$k]['n']=$this->n+1;
8363 $this->_newobj();
8364 $this->_out('<</Type /Font');
8365 $this->_putType0($font);
8366 }
8367 else
8368/*-- END CJK-FONTS --*/
8369 if($type=='core') {
8370 //Standard font
8371 $this->fonts[$k]['n']=$this->n+1;
8372 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.)'); }
8373 $this->_newobj();
8374 $this->_out('<</Type /Font');
8375 $this->_out('/BaseFont /'.$name);
8376 $this->_out('/Subtype /Type1');
8377 if($name!='Symbol' && $name!='ZapfDingbats') {
8378 $this->_out('/Encoding /WinAnsiEncoding');
8379 }
8380 $this->_out('>>');
8381 $this->_out('endobj');
8382 }
8383 // TrueType embedded SUBSETS for SIP (CJK extB containing Supplementary Ideographic Plane 2)
8384 // Or Unicode Plane 1 - Supplementary Multilingual Plane
8385 else if ($type=='TTF' && ($font['sip'] || $font['smp'])) {
8386 if (!$font['used']) { continue; }
8387 $ssfaid="AA";
8388 if (!class_exists('TTFontFile', false)) { include(_MPDF_PATH .'classes/ttfontsuni.php'); }
8389 $ttf = new TTFontFile();
8390 for($sfid=0;$sfid<count($font['subsetfontids']);$sfid++) {
8391 $this->fonts[$k]['n'][$sfid]=$this->n+1; // NB an array for subset
8392 $subsetname = 'MPDF'.$ssfaid.'+'.$font['name'];
8393 $ssfaid++;
8394 $subset = $font['subsets'][$sfid];
8395 unset($subset[0]);
8396 $ttfontstream = $ttf->makeSubsetSIP($font['ttffile'], $subset, $font['TTCfontID'], $this->debugfonts);
8397 $ttfontsize = strlen($ttfontstream);
8398 $fontstream = gzcompress($ttfontstream);
8399 $widthstring = '';
8400 $toUnistring = '';
8401 foreach($font['subsets'][$sfid] AS $cp=>$u) {
8402 $w = $this->_getCharWidth($font['cw'], $u);
8403 if ($w !== false) {
8404 $widthstring .= $w.' ';
8405 }
8406 else {
8407 $widthstring .= round($ttf->defaultWidth).' ';
8408 }
8409 if ($u > 65535) {
8410 $utf8 = chr(($u>>18)+240).chr((($u>>12)&63)+128).chr((($u>>6)&63)+128) .chr(($u&63)+128);
8411 $utf16 = mb_convert_encoding($utf8, 'UTF-16BE', 'UTF-8');
8412 $l1 = ord($utf16[0]);
8413 $h1 = ord($utf16[1]);
8414 $l2 = ord($utf16[2]);
8415 $h2 = ord($utf16[3]);
8416 $toUnistring .= sprintf("<%02s> <%02s%02s%02s%02s>\n", strtoupper(dechex($cp)), strtoupper(dechex($l1)), strtoupper(dechex($h1)), strtoupper(dechex($l2)), strtoupper(dechex($h2)));
8417 }
8418 else {
8419 $toUnistring .= sprintf("<%02s> <%04s>\n", strtoupper(dechex($cp)), strtoupper(dechex($u)));
8420 }
8421 }
8422
8423 //Additional Type1 or TrueType font
8424 $this->_newobj();
8425 $this->_out('<</Type /Font');
8426 $this->_out('/BaseFont /'.$subsetname);
8427 $this->_out('/Subtype /TrueType');
8428 $this->_out('/FirstChar 0 /LastChar '.(count($font['subsets'][$sfid])-1));
8429 $this->_out('/Widths '.($this->n+1).' 0 R');
8430 $this->_out('/FontDescriptor '.($this->n+2).' 0 R');
8431 $this->_out('/ToUnicode '.($this->n + 3).' 0 R');
8432 $this->_out('>>');
8433 $this->_out('endobj');
8434
8435 //Widths
8436 $this->_newobj();
8437 $this->_out('['.$widthstring.']');
8438 $this->_out('endobj');
8439
8440 //Descriptor
8441 $this->_newobj();
8442 $s='<</Type /FontDescriptor /FontName /'.$subsetname."\n";
8443 foreach($font['desc'] as $kd=>$v) {
8444 if ($kd == 'Flags') { $v = $v | 4; $v = $v & ~32; } // SYMBOLIC font flag
8445 $s.=' /'.$kd.' '.$v."\n";
8446 }
8447 $s.='/FontFile2 '.($this->n + 2).' 0 R';
8448 $this->_out($s.'>>');
8449 $this->_out('endobj');
8450
8451 // ToUnicode
8452 $this->_newobj();
8453 $toUni = "/CIDInit /ProcSet findresource begin\n";
8454 $toUni .= "12 dict begin\n";
8455 $toUni .= "begincmap\n";
8456 $toUni .= "/CIDSystemInfo\n";
8457 $toUni .= "<</Registry (Adobe)\n";
8458 $toUni .= "/Ordering (UCS)\n";
8459 $toUni .= "/Supplement 0\n";
8460 $toUni .= ">> def\n";
8461 $toUni .= "/CMapName /Adobe-Identity-UCS def\n";
8462 $toUni .= "/CMapType 2 def\n";
8463 $toUni .= "1 begincodespacerange\n";
8464 $toUni .= "<00> <FF>\n";
8465 $toUni .= "endcodespacerange\n";
8466 $toUni .= count($font['subsets'][$sfid])." beginbfchar\n";
8467 $toUni .= $toUnistring;
8468 $toUni .= "endbfchar\n";
8469 $toUni .= "endcmap\n";
8470 $toUni .= "CMapName currentdict /CMap defineresource pop\n";
8471 $toUni .= "end\n";
8472 $toUni .= "end\n";
8473
8474 $this->_out('<</Length '.(strlen($toUni)).'>>');
8475 $this->_putstream($toUni);
8476 $this->_out('endobj');
8477
8478 //Font file
8479 $this->_newobj();
8480 $this->_out('<</Length '.strlen($fontstream));
8481 $this->_out('/Filter /FlateDecode');
8482 $this->_out('/Length1 '.$ttfontsize);
8483 $this->_out('>>');
8484 $this->_putstream($fontstream);
8485 $this->_out('endobj');
8486 } // foreach subset
8487 unset($ttf);
8488 }
8489 // TrueType embedded SUBSETS or FULL
8490 else if ($type=='TTF') {
8491 $this->fonts[$k]['n']=$this->n+1;
8492 if ($asSubset ) {
8493 $ssfaid="A";
8494 if (!class_exists('TTFontFile', false)) { include(_MPDF_PATH .'classes/ttfontsuni.php'); }
8495 $ttf = new TTFontFile();
8496 $fontname = 'MPDFA'.$ssfaid.'+'.$font['name'];
8497 $subset = $font['subset'];
8498 unset($subset[0]);
8499 $ttfontstream = $ttf->makeSubset($font['ttffile'], $subset, $font['TTCfontID'], $this->debugfonts, $font['unAGlyphs']); // mPDF 5.4.05
8500 $ttfontsize = strlen($ttfontstream);
8501 $fontstream = gzcompress($ttfontstream);
8502 $codeToGlyph = $ttf->codeToGlyph;
8503 unset($codeToGlyph[0]);
8504 }
8505 else { $fontname = $font['name']; }
8506 // Type0 Font
8507 // A composite font - a font composed of other fonts, organized hierarchically
8508 $this->_newobj();
8509 $this->_out('<</Type /Font');
8510 $this->_out('/Subtype /Type0');
8511 $this->_out('/BaseFont /'.$fontname.'');
8512 $this->_out('/Encoding /Identity-H');
8513 $this->_out('/DescendantFonts ['.($this->n + 1).' 0 R]');
8514 $this->_out('/ToUnicode '.($this->n + 2).' 0 R');
8515 $this->_out('>>');
8516 $this->_out('endobj');
8517
8518 // CIDFontType2
8519 // A CIDFont whose glyph descriptions are based on TrueType font technology
8520 $this->_newobj();
8521 $this->_out('<</Type /Font');
8522 $this->_out('/Subtype /CIDFontType2');
8523 $this->_out('/BaseFont /'.$fontname.'');
8524 $this->_out('/CIDSystemInfo '.($this->n + 2).' 0 R');
8525 $this->_out('/FontDescriptor '.($this->n + 3).' 0 R');
8526 if (isset($font['desc']['MissingWidth'])){
8527 $this->_out('/DW '.$font['desc']['MissingWidth'].'');
8528 }
8529
8530 if (!$asSubset && file_exists(_MPDF_TTFONTDATAPATH.$font['fontkey'].'.cw')) {
8531 $w = '';
8532 $w=file_get_contents(_MPDF_TTFONTDATAPATH.$font['fontkey'].'.cw');
8533 $this->_out($w);
8534 }
8535 else {
8536 $this->_putTTfontwidths($font, $asSubset, $ttf->maxUni);
8537 }
8538
8539 $this->_out('/CIDToGIDMap '.($this->n + 4).' 0 R');
8540 $this->_out('>>');
8541 $this->_out('endobj');
8542
8543 // ToUnicode
8544 $this->_newobj();
8545 $toUni = "/CIDInit /ProcSet findresource begin\n";
8546 $toUni .= "12 dict begin\n";
8547 $toUni .= "begincmap\n";
8548 $toUni .= "/CIDSystemInfo\n";
8549 $toUni .= "<</Registry (Adobe)\n";
8550 $toUni .= "/Ordering (UCS)\n";
8551 $toUni .= "/Supplement 0\n";
8552 $toUni .= ">> def\n";
8553 $toUni .= "/CMapName /Adobe-Identity-UCS def\n";
8554 $toUni .= "/CMapType 2 def\n";
8555 $toUni .= "1 begincodespacerange\n";
8556 $toUni .= "<0000> <FFFF>\n";
8557 $toUni .= "endcodespacerange\n";
8558 $toUni .= "1 beginbfrange\n";
8559 $toUni .= "<0000> <FFFF> <0000>\n";
8560 $toUni .= "endbfrange\n";
8561 $toUni .= "endcmap\n";
8562 $toUni .= "CMapName currentdict /CMap defineresource pop\n";
8563 $toUni .= "end\n";
8564 $toUni .= "end\n";
8565 $this->_out('<</Length '.(strlen($toUni)).'>>');
8566 $this->_putstream($toUni);
8567 $this->_out('endobj');
8568
8569
8570 // CIDSystemInfo dictionary
8571 $this->_newobj();
8572 $this->_out('<</Registry (Adobe)');
8573 $this->_out('/Ordering (UCS)');
8574 $this->_out('/Supplement 0');
8575 $this->_out('>>');
8576 $this->_out('endobj');
8577
8578 // Font descriptor
8579 $this->_newobj();
8580 $this->_out('<</Type /FontDescriptor');
8581 $this->_out('/FontName /'.$fontname);
8582 foreach($font['desc'] as $kd=>$v) {
8583 if ($asSubset && $kd == 'Flags') { $v = $v | 4; $v = $v & ~32; } // SYMBOLIC font flag
8584 $this->_out(' /'.$kd.' '.$v);
8585 }
8586 if ($font['panose']) {
8587 $this->_out(' /Style << /Panose <'.$font['panose'].'> >>');
8588 }
8589 if ($asSubset ) {
8590 $this->_out('/FontFile2 '.($this->n + 2).' 0 R');
8591 }
8592 else if ($font['fontkey']) {
8593 // obj ID of a stream containing a TrueType font program
8594 $this->_out('/FontFile2 '.$this->FontFiles[$font['fontkey']]['n'].' 0 R');
8595 }
8596 $this->_out('>>');
8597 $this->_out('endobj');
8598
8599 // Embed CIDToGIDMap
8600 // A specification of the mapping from CIDs to glyph indices
8601 if ($asSubset ) {
8602 $cidtogidmap = '';
8603 $cidtogidmap = str_pad('', 256*256*2, "\x00");
8604 foreach($codeToGlyph as $cc=>$glyph) {
8605 $cidtogidmap[$cc*2] = chr($glyph >> 8);
8606 $cidtogidmap[$cc*2 + 1] = chr($glyph & 0xFF);
8607 }
8608 $cidtogidmap = gzcompress($cidtogidmap);
8609 }
8610 else {
8611 // First see if there is a cached CIDToGIDMapfile
8612 $cidtogidmap = '';
8613 if (file_exists(_MPDF_TTFONTDATAPATH.$font['fontkey'].'.cgm')) {
8614 $f=fopen(_MPDF_TTFONTDATAPATH.$font['fontkey'].'.cgm','rb');
8615 while(!feof($f)) { $cidtogidmap .= fread($f, 2048); }
8616 fclose($f);
8617 }
8618 else {
8619 if (!class_exists('TTFontFile', false)) { include(_MPDF_PATH .'classes/ttfontsuni.php'); }
8620 $ttf = new TTFontFile();
8621 $charToGlyph = $ttf->getCTG($font['ttffile'], $font['TTCfontID'], $this->debugfonts, $font['unAGlyphs']); // mPDF 5.4.05
8622 $cidtogidmap = str_pad('', 256*256*2, "\x00");
8623 foreach($charToGlyph as $cc=>$glyph) {
8624 $cidtogidmap[$cc*2] = chr($glyph >> 8);
8625 $cidtogidmap[$cc*2 + 1] = chr($glyph & 0xFF);
8626 }
8627 unset($ttf);
8628 $cidtogidmap = gzcompress($cidtogidmap);
8629 if (is_writable(dirname(_MPDF_TTFONTDATAPATH.'x'))) {
8630 $fh = fopen(_MPDF_TTFONTDATAPATH.$font['fontkey'].'.cgm',"wb");
8631 fwrite($fh,$cidtogidmap,strlen($cidtogidmap));
8632 fclose($fh);
8633 }
8634 }
8635 }
8636 $this->_newobj();
8637 $this->_out('<</Length '.strlen($cidtogidmap).'');
8638 $this->_out('/Filter /FlateDecode');
8639 $this->_out('>>');
8640 $this->_putstream($cidtogidmap);
8641 $this->_out('endobj');
8642
8643 //Font file
8644 if ($asSubset ) {
8645 $this->_newobj();
8646 $this->_out('<</Length '.strlen($fontstream));
8647 $this->_out('/Filter /FlateDecode');
8648 $this->_out('/Length1 '.$ttfontsize);
8649 $this->_out('>>');
8650 $this->_putstream($fontstream);
8651 $this->_out('endobj');
8652 unset($ttf);
8653 }
8654 }
8655 else { $this->Error('Unsupported font type: '.$type.' ('.$name.')'); }
8656 }
8657}
8658
8659
8660
8661function _putTTfontwidths(&$font, $asSubset, $maxUni) {
8662 if ($asSubset && file_exists(_MPDF_TTFONTDATAPATH.$font['fontkey'].'.cw127.php')) {
8663 include(_MPDF_TTFONTDATAPATH.$font['fontkey'].'.cw127.php') ;
8664 $startcid = 128;
8665 }
8666 else {
8667 $rangeid = 0;
8668 $range = array();
8669 $prevcid = -2;
8670 $prevwidth = -1;
8671 $interval = false;
8672 $startcid = 1;
8673 }
8674 if ($asSubset) { $cwlen = $maxUni + 1; }
8675 else { $cwlen = (strlen($font['cw'])/2); }
8676
8677 // for each character
8678 for ($cid=$startcid; $cid<$cwlen; $cid++) {
8679 if ($cid==128 && $asSubset && (!file_exists(_MPDF_TTFONTDATAPATH.$font['fontkey'].'.cw127.php'))) {
8680 if (is_writable(dirname(_MPDF_TTFONTDATAPATH.'x'))) {
8681 $fh = fopen(_MPDF_TTFONTDATAPATH.$font['fontkey'].'.cw127.php',"wb");
8682 $cw127='<?php'."\n";
8683 $cw127.='$rangeid='.$rangeid.";\n";
8684 $cw127.='$prevcid='.$prevcid.";\n";
8685 $cw127.='$prevwidth='.$prevwidth.";\n";
8686 if ($interval) { $cw127.='$interval=true'.";\n"; }
8687 else { $cw127.='$interval=false'.";\n"; }
8688 $cw127.='$range='.var_export($range,true).";\n";
8689 $cw127.="?>";
8690 fwrite($fh,$cw127,strlen($cw127));
8691 fclose($fh);
8692 }
8693 }
8694 if ($font['cw'][$cid*2] == "\00" && $font['cw'][$cid*2+1] == "\00") { continue; }
8695 $width = (ord($font['cw'][$cid*2]) << 8) + ord($font['cw'][$cid*2+1]);
8696 if ($width == 65535) { $width = 0; }
8697 if ($asSubset && $cid > 255 && (!isset($font['subset'][$cid]) || !$font['subset'][$cid])) {
8698 continue;
8699 }
8700 if (!isset($font['dw']) || (isset($font['dw']) && $width != $font['dw'])) {
8701 if ($cid == ($prevcid + 1)) {
8702 // consecutive CID
8703 if ($width == $prevwidth) {
8704 if ($width == $range[$rangeid][0]) {
8705 $range[$rangeid][] = $width;
8706 } else {
8707 array_pop($range[$rangeid]);
8708 // new range
8709 $rangeid = $prevcid;
8710 $range[$rangeid] = array();
8711 $range[$rangeid][] = $prevwidth;
8712 $range[$rangeid][] = $width;
8713 }
8714 $interval = true;
8715 $range[$rangeid]['interval'] = true;
8716 } else {
8717 if ($interval) {
8718 // new range
8719 $rangeid = $cid;
8720 $range[$rangeid] = array();
8721 $range[$rangeid][] = $width;
8722 } else {
8723 $range[$rangeid][] = $width;
8724 }
8725 $interval = false;
8726 }
8727 } else {
8728 // new range
8729 $rangeid = $cid;
8730 $range[$rangeid] = array();
8731 $range[$rangeid][] = $width;
8732 $interval = false;
8733 }
8734 $prevcid = $cid;
8735 $prevwidth = $width;
8736 }
8737 }
8738 $w = $this->_putfontranges($range);
8739 $this->_out($w);
8740 if (!$asSubset) {
8741 if (is_writable(dirname(_MPDF_TTFONTDATAPATH.'x'))) {
8742 $fh = fopen(_MPDF_TTFONTDATAPATH.$font['fontkey'].'.cw',"wb");
8743 fwrite($fh,$w,strlen($w));
8744 fclose($fh);
8745 }
8746 }
8747}
8748
8749function _putfontranges(&$range) {
8750 // optimize ranges
8751 $prevk = -1;
8752 $nextk = -1;
8753 $prevint = false;
8754 foreach ($range as $k => $ws) {
8755 $cws = count($ws);
8756 if (($k == $nextk) AND (!$prevint) AND ((!isset($ws['interval'])) OR ($cws < 4))) {
8757 if (isset($range[$k]['interval'])) {
8758 unset($range[$k]['interval']);
8759 }
8760 $range[$prevk] = array_merge($range[$prevk], $range[$k]);
8761 unset($range[$k]);
8762 } else {
8763 $prevk = $k;
8764 }
8765 $nextk = $k + $cws;
8766 if (isset($ws['interval'])) {
8767 if ($cws > 3) {
8768 $prevint = true;
8769 } else {
8770 $prevint = false;
8771 }
8772 unset($range[$k]['interval']);
8773 --$nextk;
8774 } else {
8775 $prevint = false;
8776 }
8777 }
8778 // output data
8779 $w = '';
8780 foreach ($range as $k => $ws) {
8781 if (count(array_count_values($ws)) == 1) {
8782 // interval mode is more compact
8783 $w .= ' '.$k.' '.($k + count($ws) - 1).' '.$ws[0];
8784 } else {
8785 // range mode
8786 $w .= ' '.$k.' [ '.implode(' ', $ws).' ]' . "\n";
8787 }
8788 }
8789 return '/W ['.$w.' ]';
8790}
8791
8792
8793function _putfontwidths(&$font, $cidoffset=0) {
8794 ksort($font['cw']);
8795 unset($font['cw'][65535]);
8796 $rangeid = 0;
8797 $range = array();
8798 $prevcid = -2;
8799 $prevwidth = -1;
8800 $interval = false;
8801 // for each character
8802 foreach ($font['cw'] as $cid => $width) {
8803 $cid -= $cidoffset;
8804 if (!isset($font['dw']) || (isset($font['dw']) && $width != $font['dw'])) {
8805 if ($cid == ($prevcid + 1)) {
8806 // consecutive CID
8807 if ($width == $prevwidth) {
8808 if ($width == $range[$rangeid][0]) {
8809 $range[$rangeid][] = $width;
8810 } else {
8811 array_pop($range[$rangeid]);
8812 // new range
8813 $rangeid = $prevcid;
8814 $range[$rangeid] = array();
8815 $range[$rangeid][] = $prevwidth;
8816 $range[$rangeid][] = $width;
8817 }
8818 $interval = true;
8819 $range[$rangeid]['interval'] = true;
8820 } else {
8821 if ($interval) {
8822 // new range
8823 $rangeid = $cid;
8824 $range[$rangeid] = array();
8825 $range[$rangeid][] = $width;
8826 } else {
8827 $range[$rangeid][] = $width;
8828 }
8829 $interval = false;
8830 }
8831 } else {
8832 // new range
8833 $rangeid = $cid;
8834 $range[$rangeid] = array();
8835 $range[$rangeid][] = $width;
8836 $interval = false;
8837 }
8838 $prevcid = $cid;
8839 $prevwidth = $width;
8840 }
8841 }
8842 $this->_out($this->_putfontranges($range));
8843}
8844
8845
8846/*-- CJK-FONTS --*/
8847
8848// from class PDF_Chinese CJK EXTENSIONS
8849function _putType0(&$font)
8850{
8851 //Type0
8852 $this->_out('/Subtype /Type0');
8853 $this->_out('/BaseFont /'.$font['name'].'-'.$font['CMap']);
8854 $this->_out('/Encoding /'.$font['CMap']);
8855 $this->_out('/DescendantFonts ['.($this->n+1).' 0 R]');
8856 $this->_out('>>');
8857 $this->_out('endobj');
8858 //CIDFont
8859 $this->_newobj();
8860 $this->_out('<</Type /Font');
8861 $this->_out('/Subtype /CIDFontType0');
8862 $this->_out('/BaseFont /'.$font['name']);
8863
8864 $cidinfo = '/Registry '.$this->_textstring('Adobe');
8865 $cidinfo .= ' /Ordering '.$this->_textstring($font['registry']['ordering']);
8866 $cidinfo .= ' /Supplement '.$font['registry']['supplement'];
8867 $this->_out('/CIDSystemInfo <<'.$cidinfo.'>>');
8868
8869 $this->_out('/FontDescriptor '.($this->n+1).' 0 R');
8870 if (isset($font['MissingWidth'])){
8871 $this->_out('/DW '.$font['MissingWidth'].'');
8872 }
8873 $this->_putfontwidths($font, 31);
8874 $this->_out('>>');
8875 $this->_out('endobj');
8876
8877 //Font descriptor
8878 $this->_newobj();
8879 $s = '<</Type /FontDescriptor /FontName /'.$font['name'];
8880 foreach ($font['desc'] as $k => $v) {
8881 if ($k != 'Style') {
8882 $s .= ' /'.$k.' '.$v.'';
8883 }
8884 }
8885 $this->_out($s.'>>');
8886 $this->_out('endobj');
8887}
8888/*-- END CJK-FONTS --*/
8889
8890
8891
8892function _putimages()
8893{
8894 $filter=($this->compress) ? '/Filter /FlateDecode ' : '';
8895 reset($this->images);
8896 while(list($file,$info)=each($this->images)) {
8897 $this->_newobj();
8898 $this->images[$file]['n']=$this->n;
8899 $this->_out('<</Type /XObject');
8900 $this->_out('/Subtype /Image');
8901 $this->_out('/Width '.$info['w']);
8902 $this->_out('/Height '.$info['h']);
8903 if (isset($info['masked'])) {
8904 $this->_out('/SMask '.($this->n - 1).' 0 R');
8905 }
8906 if($info['cs']=='Indexed') {
8907 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.")."); }
8908 $this->_out('/ColorSpace [/Indexed /DeviceRGB '.(strlen($info['pal'])/3-1).' '.($this->n+1).' 0 R]');
8909 }
8910 else {
8911 $this->_out('/ColorSpace /'.$info['cs']);
8912 if($info['cs']=='DeviceCMYK') {
8913 if ($this->PDFA && $this->restrictColorSpace!=3) { $this->Error("PDFA1-b does not permit Images using mixed colour space (".$file.")."); }
8914 if($info['type']=='jpg') { $this->_out('/Decode [1 0 1 0 1 0 1 0]'); }
8915 }
8916 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.")."); }
8917 }
8918 $this->_out('/BitsPerComponent '.$info['bpc']);
8919 if (isset($info['f']) && $info['f']) { $this->_out('/Filter /'.$info['f']); }
8920 if(isset($info['parms'])) { $this->_out($info['parms']); }
8921 if(isset($info['trns']) and is_array($info['trns'])) {
8922 $trns='';
8923 for($i=0;$i<count($info['trns']);$i++)
8924 $trns.=$info['trns'][$i].' '.$info['trns'][$i].' ';
8925 $this->_out('/Mask ['.$trns.']');
8926 }
8927 $this->_out('/Length '.strlen($info['data']).'>>');
8928 $this->_putstream($info['data']);
8929
8930 unset($this->images[$file]['data']);
8931 $this->_out('endobj');
8932 //Palette
8933 if($info['cs']=='Indexed') {
8934 $this->_newobj();
8935 $pal=($this->compress) ? gzcompress($info['pal']) : $info['pal'];
8936 $this->_out('<<'.$filter.'/Length '.strlen($pal).'>>');
8937 $this->_putstream($pal);
8938 $this->_out('endobj');
8939 }
8940 }
8941}
8942
8943function _putinfo()
8944{
8945 $this->_out('/Producer '.$this->_UTF16BEtextstring('mPDF '.mPDF_VERSION));
8946 if(!empty($this->title))
8947 $this->_out('/Title '.$this->_UTF16BEtextstring($this->title));
8948 if(!empty($this->subject))
8949 $this->_out('/Subject '.$this->_UTF16BEtextstring($this->subject));
8950 if(!empty($this->author))
8951 $this->_out('/Author '.$this->_UTF16BEtextstring($this->author));
8952 if(!empty($this->keywords))
8953 $this->_out('/Keywords '.$this->_UTF16BEtextstring($this->keywords));
8954 if(!empty($this->creator))
8955 $this->_out('/Creator '.$this->_UTF16BEtextstring($this->creator));
8956
8957 $z = date('O'); // +0200
8958 $offset = substr($z,0,3)."'".substr($z,3,2)."'";
8959 $this->_out('/CreationDate '.$this->_textstring(date('YmdHis').$offset));
8960 $this->_out('/ModDate '.$this->_textstring(date('YmdHis').$offset));
8961 if ($this->PDFX) {
8962 $this->_out('/Trapped/False');
8963 $this->_out('/GTS_PDFXVersion(PDF/X-1a:2003)');
8964 }
8965}
8966
8967function _putmetadata() {
8968 $this->_newobj();
8969 $this->MetadataRoot = $this->n;
8970 $Producer = 'mPDF '.mPDF_VERSION;
8971 $z = date('O'); // +0200
8972 $offset = substr($z,0,3).':'.substr($z,3,2);
8973 $CreationDate = date('Y-m-d\TH:i:s').$offset; // 2006-03-10T10:47:26-05:00 2006-06-19T09:05:17Z
8974 $uuid = sprintf('%04x%04x-%04x-%04x-%04x-%04x%04x%04x', mt_rand(0, 0xffff), mt_rand(0, 0xffff),
8975 mt_rand(0, 0xffff), mt_rand(0, 0x0fff) | 0x4000, mt_rand(0, 0x3fff) | 0x8000,
8976 mt_rand(0, 0xffff), mt_rand(0, 0xffff), mt_rand(0, 0xffff) );
8977
8978
8979 $m = '<?xpacket begin="'.chr(239).chr(187).chr(191).'" id="W5M0MpCehiHzreSzNTczkc9d"?>'."\n"; // begin = FEFF BOM
8980 $m .= ' <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="3.1-701">'."\n";
8981 $m .= ' <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">'."\n";
8982 $m .= ' <rdf:Description rdf:about="uuid:'.$uuid.'" xmlns:pdf="http://ns.adobe.com/pdf/1.3/">'."\n";
8983 $m .= ' <pdf:Producer>'.$Producer.'</pdf:Producer>'."\n";
8984 if(!empty($this->keywords)) { $m .= ' <pdf:Keywords>'.$this->keywords.'</pdf:Keywords>'."\n"; }
8985 $m .= ' </rdf:Description>'."\n";
8986
8987 $m .= ' <rdf:Description rdf:about="uuid:'.$uuid.'" xmlns:xmp="http://ns.adobe.com/xap/1.0/">'."\n";
8988 $m .= ' <xmp:CreateDate>'.$CreationDate.'</xmp:CreateDate>'."\n";
8989 $m .= ' <xmp:ModifyDate>'.$CreationDate.'</xmp:ModifyDate>'."\n";
8990 $m .= ' <xmp:MetadataDate>'.$CreationDate.'</xmp:MetadataDate>'."\n";
8991 if(!empty($this->creator)) { $m .= ' <xmp:CreatorTool>'.$this->creator.'</xmp:CreatorTool>'."\n"; }
8992 $m .= ' </rdf:Description>'."\n";
8993
8994 // DC elements
8995 $m .= ' <rdf:Description rdf:about="uuid:'.$uuid.'" xmlns:dc="http://purl.org/dc/elements/1.1/">'."\n";
8996 $m .= ' <dc:format>application/pdf</dc:format>'."\n";
8997 if(!empty($this->title)) {
8998 $m .= ' <dc:title>
8999 <rdf:Alt>
9000 <rdf:li xml:lang="x-default">'.$this->title.'</rdf:li>
9001 </rdf:Alt>
9002 </dc:title>'."\n";
9003 }
9004 if(!empty($this->keywords)) {
9005 $m .= ' <dc:subject>
9006 <rdf:Bag>
9007 <rdf:li>'.$this->keywords.'</rdf:li>
9008 </rdf:Bag>
9009 </dc:subject>'."\n";
9010 }
9011 if(!empty($this->subject)) {
9012 $m .= ' <dc:description>
9013 <rdf:Alt>
9014 <rdf:li xml:lang="x-default">'.$this->subject.'</rdf:li>
9015 </rdf:Alt>
9016 </dc:description>'."\n";
9017 }
9018 if(!empty($this->author)) {
9019 $m .= ' <dc:creator>
9020 <rdf:Seq>
9021 <rdf:li>'.$this->author.'</rdf:li>
9022 </rdf:Seq>
9023 </dc:creator>'."\n";
9024 }
9025 $m .= ' </rdf:Description>'."\n";
9026
9027
9028 // This bit is specific to PDFX-1a
9029 if ($this->PDFX) {
9030 $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";
9031 }
9032
9033 // This bit is specific to PDFA-1b
9034 else if ($this->PDFA) {
9035 $m .= ' <rdf:Description rdf:about="uuid:'.$uuid.'" xmlns:pdfaid="http://www.aiim.org/pdfa/ns/id/" >'."\n";
9036 $m .= ' <pdfaid:part>1</pdfaid:part>'."\n";
9037 $m .= ' <pdfaid:conformance>B</pdfaid:conformance>'."\n";
9038 $m .= ' <pdfaid:amd>2005</pdfaid:amd>'."\n";
9039 $m .= ' </rdf:Description>'."\n";
9040 }
9041
9042 $m .= ' <rdf:Description rdf:about="uuid:'.$uuid.'" xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/">'."\n";
9043 $m .= ' <xmpMM:DocumentID>uuid:'.$uuid.'</xmpMM:DocumentID>'."\n";
9044 $m .= ' </rdf:Description>'."\n";
9045 $m .= ' </rdf:RDF>'."\n";
9046 $m .= ' </x:xmpmeta>'."\n";
9047 $m .= str_repeat(str_repeat(' ',100)."\n",20); // 2-4kB whitespace padding required
9048 $m .= '<?xpacket end="w"?>'; // "r" read only
9049 $this->_out('<</Type/Metadata/Subtype/XML/Length '.strlen($m).'>>');
9050 $this->_putstream($m);
9051 $this->_out('endobj');
9052}
9053
9054function _putoutputintent() {
9055 $this->_newobj();
9056 $this->OutputIntentRoot = $this->n;
9057 $this->_out('<</Type /OutputIntent');
9058
9059 if ($this->PDFA) {
9060 $this->_out('/S /GTS_PDFA1');
9061 if ($this->ICCProfile) {
9062 $this->_out('/Info ('.preg_replace('/_/',' ',$this->ICCProfile).')');
9063 $this->_out('/OutputConditionIdentifier (Custom)');
9064 $this->_out('/OutputCondition ()');
9065 }
9066 else {
9067 $this->_out('/Info (sRGB IEC61966-2.1)');
9068 $this->_out('/OutputConditionIdentifier (sRGB IEC61966-2.1)');
9069 $this->_out('/OutputCondition ()');
9070 }
9071 $this->_out('/DestOutputProfile '.($this->n+1).' 0 R');
9072 }
9073 else if ($this->PDFX) { // always a CMYK profile
9074 $this->_out('/S /GTS_PDFX');
9075 if ($this->ICCProfile) {
9076 $this->_out('/Info ('.preg_replace('/_/',' ',$this->ICCProfile).')');
9077 $this->_out('/OutputConditionIdentifier (Custom)');
9078 $this->_out('/OutputCondition ()');
9079 $this->_out('/DestOutputProfile '.($this->n+1).' 0 R');
9080 }
9081 else {
9082 $this->_out('/Info (CGATS TR 001)');
9083 $this->_out('/OutputConditionIdentifier (CGATS TR 001)');
9084 $this->_out('/OutputCondition (CGATS TR 001 (SWOP))');
9085 $this->_out('/RegistryName (http://www.color.org)');
9086 }
9087 }
9088 $this->_out('>>');
9089 $this->_out('endobj');
9090
9091 if ($this->PDFX && !$this->ICCProfile) { return; } // no ICCProfile embedded
9092
9093 $this->_newobj();
9094 if ($this->ICCProfile)
9095 $s = file_get_contents(_MPDF_PATH.'iccprofiles/'.$this->ICCProfile.'.icc');
9096 else
9097 $s = file_get_contents(_MPDF_PATH.'iccprofiles/sRGB_IEC61966-2-1.icc');
9098 if ($this->compress) { $s = gzcompress($s); }
9099 $this->_out('<<');
9100 if ($this->PDFX || ($this->PDFA && $this->restrictColorSpace == 3)) { $this->_out('/N 4'); }
9101 else { $this->_out('/N 3'); }
9102 if ($this->compress)
9103 $this->_out('/Filter /FlateDecode ');
9104 $this->_out('/Length '.strlen($s).'>>');
9105 $this->_putstream($s);
9106 $this->_out('endobj');
9107}
9108
9109
9110function _putcatalog() {
9111 $this->_out('/Type /Catalog');
9112 $this->_out('/Pages 1 0 R');
9113 if($this->ZoomMode=='fullpage') $this->_out('/OpenAction [3 0 R /Fit]');
9114 elseif($this->ZoomMode=='fullwidth') $this->_out('/OpenAction [3 0 R /FitH null]');
9115 elseif($this->ZoomMode=='real') $this->_out('/OpenAction [3 0 R /XYZ null null 1]');
9116 elseif(!is_string($this->ZoomMode)) $this->_out('/OpenAction [3 0 R /XYZ null null '.($this->ZoomMode/100).']');
9117 else $this->_out('/OpenAction [3 0 R /XYZ null null null]');
9118 if($this->LayoutMode=='single') $this->_out('/PageLayout /SinglePage');
9119 elseif($this->LayoutMode=='continuous') $this->_out('/PageLayout /OneColumn');
9120 elseif($this->LayoutMode=='twoleft') $this->_out('/PageLayout /TwoColumnLeft');
9121 elseif($this->LayoutMode=='tworight') $this->_out('/PageLayout /TwoColumnRight');
9122 elseif($this->LayoutMode=='two') {
9123 if ($this->mirrorMargins) { $this->_out('/PageLayout /TwoColumnRight'); }
9124 else { $this->_out('/PageLayout /TwoColumnLeft'); }
9125 }
9126
9127/*-- BOOKMARKS --*/
9128 if(count($this->BMoutlines)>0) {
9129 $this->_out('/Outlines '.$this->OutlineRoot.' 0 R');
9130 $this->_out('/PageMode /UseOutlines');
9131 }
9132/*-- END BOOKMARKS --*/
9133 if(is_int(strpos($this->DisplayPreferences,'FullScreen'))) $this->_out('/PageMode /FullScreen');
9134
9135 // Metadata
9136 if ($this->PDFA || $this->PDFX) {
9137 $this->_out('/Metadata '.$this->MetadataRoot.' 0 R');
9138 }
9139 // OutputIntents
9140 if ($this->PDFA || $this->PDFX || $this->ICCProfile) {
9141 $this->_out('/OutputIntents ['.$this->OutputIntentRoot.' 0 R]');
9142 }
9143
9144/*-- FORMS --*/
9145 if (count($this->form->forms)>0) {
9146 $this->form->_putFormsCatalog();
9147 }
9148/*-- END FORMS --*/
9149 if ( isset($this->js) ) {
9150 $this->_out('/Names << /JavaScript '.($this->n_js).' 0 R >> ');
9151 }
9152
9153 if($this->DisplayPreferences || $this->directionality == 'rtl' || $this->mirrorMargins) {
9154 $this->_out('/ViewerPreferences<<');
9155 if(is_int(strpos($this->DisplayPreferences,'HideMenubar'))) $this->_out('/HideMenubar true');
9156 if(is_int(strpos($this->DisplayPreferences,'HideToolbar'))) $this->_out('/HideToolbar true');
9157 if(is_int(strpos($this->DisplayPreferences,'HideWindowUI'))) $this->_out('/HideWindowUI true');
9158 if(is_int(strpos($this->DisplayPreferences,'DisplayDocTitle'))) $this->_out('/DisplayDocTitle true');
9159 if(is_int(strpos($this->DisplayPreferences,'CenterWindow'))) $this->_out('/CenterWindow true');
9160 if(is_int(strpos($this->DisplayPreferences,'FitWindow'))) $this->_out('/FitWindow true');
9161 // /PrintScaling is PDF 1.6 spec.
9162 if(is_int(strpos($this->DisplayPreferences,'NoPrintScaling')) && !$this->PDFA && !$this->PDFX)
9163 $this->_out('/PrintScaling /None');
9164 if($this->directionality == 'rtl') $this->_out('/Direction /R2L');
9165 // /Duplex is PDF 1.7 spec.
9166 if($this->mirrorMargins && !$this->PDFA && !$this->PDFX) {
9167 // if ($this->DefOrientation=='P') $this->_out('/Duplex /DuplexFlipShortEdge');
9168 $this->_out('/Duplex /DuplexFlipLongEdge'); // PDF v1.7+
9169 }
9170 $this->_out('>>');
9171 }
9172 // mPDF 5.6.01
9173 if($this->open_layer_pane && ($this->hasOC || count($this->layers)))
9174 $this->_out('/PageMode /UseOC');
9175
9176 // mPDF 5.6.01
9177 if ($this->hasOC || count($this->layers)) {
9178 $p = $v = $h = $l = $loff = $lall = $as = ''; // mPDF 5.6.28
9179 if ($this->hasOC) {
9180 if (($this->hasOC & 1) == 1) $p=$this->n_ocg_print.' 0 R';
9181 if (($this->hasOC & 2) == 2) $v=$this->n_ocg_view.' 0 R';
9182 if (($this->hasOC & 4) == 4) $h=$this->n_ocg_hidden.' 0 R';
9183 $as="<</Event /Print /OCGs [$p $v $h] /Category [/Print]>> <</Event /View /OCGs [$p $v $h] /Category [/View]>>";
9184 }
9185
9186 if(count($this->layers)) {
9187 foreach($this->layers as $k=>$layer) { // mPDF 5.6.28
9188 if (strtolower($this->layerDetails[$k]['state'])=='hidden') { $loff .= $layer['n'].' 0 R '; }
9189 else { $l .= $layer['n'].' 0 R '; }
9190 $lall .= $layer['n'].' 0 R ';
9191 }
9192 }
9193 $this->_out("/OCProperties <</OCGs [$p $v $h $lall] /D <</ON [$p $l] /OFF [$v $h $loff] "); // mPDF 5.6.28
9194 $this->_out("/Order [$v $p $h $lall] "); // mPDF 5.6.28
9195 if ($as) $this->_out("/AS [$as] ");
9196 $this->_out(">>>>");
9197
9198 }
9199
9200}
9201
9202// Inactive function left for backwards compatability
9203function SetUserRights($enable=true, $annots="", $form="", $signature="") {
9204 // Does nothing
9205}
9206
9207function _enddoc() {
9208 if ($this->progressBar) { $this->UpdateProgressBar(2,'10','Writing Headers & Footers'); } // *PROGRESS-BAR*
9209 $this->_puthtmlheaders(); // *HTMLHEADERS-FOOTERS*
9210 if ($this->progressBar) { $this->UpdateProgressBar(2,'20','Writing Pages'); } // *PROGRESS-BAR*
9211 // Remove references to unused fonts (usually default font)
9212 foreach($this->fonts as $fk=>$font) {
9213 if (!$font['used'] && ($font['type']=='TTF')) {
9214 if ($font['sip'] || $font['smp']) {
9215 foreach($font['subsetfontids'] AS $k => $fid) {
9216 foreach($this->pages AS $pn=>$page) {
9217 $this->pages[$pn] = preg_replace('/\s\/F'.$fid.' \d[\d.]* Tf\s/is',' ',$this->pages[$pn]);
9218 }
9219 }
9220 }
9221 else {
9222 foreach($this->pages AS $pn=>$page) {
9223 $this->pages[$pn] = preg_replace('/\s\/F'.$font['i'].' \d[\d.]* Tf\s/is',' ',$this->pages[$pn]);
9224 }
9225 }
9226 }
9227 }
9228
9229 // mPDF 5.6.01 - LAYERS
9230 if (count($this->layers)) {
9231 foreach($this->pages AS $pn=>$page) {
9232 preg_match_all('/\/OCZ-index \/ZI(\d+) BDC(.*?)(EMCZ)-index/is',$this->pages[$pn],$m1);
9233 preg_match_all('/\/OCBZ-index \/ZI(\d+) BDC(.*?)(EMCBZ)-index/is',$this->pages[$pn],$m2);
9234 preg_match_all('/\/OCGZ-index \/ZI(\d+) BDC(.*?)(EMCGZ)-index/is',$this->pages[$pn],$m3);
9235 $m = array();
9236 for ($i=0;$i<4;$i++) {
9237 $m[$i] = array_merge($m1[$i],$m2[$i],$m3[$i]);
9238 }
9239 if (count($m[0])) {
9240 $sortarr = array();
9241 for($i=0;$i<count($m[0]);$i++) {
9242 $key = $m[1][$i]*2;
9243 if ($m[3][$i]=='EMCZ') $key +=2; // background first then gradient then normal
9244 else if ($m[3][$i]=='EMCGZ') $key +=1;
9245 $sortarr[$i] = $key;
9246 }
9247 asort($sortarr);
9248 foreach($sortarr AS $i=>$k) {
9249 $this->pages[$pn] = str_replace($m[0][$i],'',$this->pages[$pn] );
9250 $this->pages[$pn] .= "\n".$m[0][$i]."\n";
9251 }
9252 $this->pages[$pn] = preg_replace('/\/OC[BG]{0,1}Z-index \/ZI(\d+) BDC/is','/OC /ZI\\1 BDC ',$this->pages[$pn]);
9253 $this->pages[$pn] = preg_replace('/EMC[BG]{0,1}Z-index/is','EMC',$this->pages[$pn]);
9254 }
9255 }
9256 }
9257
9258 $this->_putpages();
9259 if ($this->progressBar) { $this->UpdateProgressBar(2,'30','Writing document resources'); } // *PROGRESS-BAR*
9260
9261 $this->_putresources();
9262 //Info
9263 $this->_newobj();
9264 $this->InfoRoot = $this->n;
9265 $this->_out('<<');
9266 if ($this->progressBar) { $this->UpdateProgressBar(2,'80','Writing document info'); } // *PROGRESS-BAR*
9267 $this->_putinfo();
9268 $this->_out('>>');
9269 $this->_out('endobj');
9270
9271 // METADATA
9272 if ($this->PDFA || $this->PDFX) { $this->_putmetadata(); }
9273 // OUTPUTINTENT
9274 if ($this->PDFA || $this->PDFX || $this->ICCProfile) { $this->_putoutputintent(); }
9275
9276 //Catalog
9277 $this->_newobj();
9278 $this->_out('<<');
9279 if ($this->progressBar) { $this->UpdateProgressBar(2,'90','Writing document catalog'); } // *PROGRESS-BAR*
9280 $this->_putcatalog();
9281 $this->_out('>>');
9282 $this->_out('endobj');
9283 //Cross-ref
9284 $o=strlen($this->buffer);
9285 $this->_out('xref');
9286 $this->_out('0 '.($this->n+1));
9287 $this->_out('0000000000 65535 f ');
9288 for($i=1; $i <= $this->n ; $i++)
9289 $this->_out(sprintf('%010d 00000 n ',$this->offsets[$i]));
9290 //Trailer
9291 $this->_out('trailer');
9292 $this->_out('<<');
9293 $this->_puttrailer();
9294 $this->_out('>>');
9295 $this->_out('startxref');
9296 $this->_out($o);
9297
9298 $this->buffer .= '%%EOF';
9299 $this->state=3;
9300/*-- IMPORTS --*/
9301
9302 if ($this->enableImports && count($this->parsers) > 0) {
9303 foreach ($this->parsers as $k => $_){
9304 $this->parsers[$k]->closeFile();
9305 $this->parsers[$k] = null;
9306 unset($this->parsers[$k]);
9307 }
9308 }
9309/*-- END IMPORTS --*/
9310}
9311
9312function _beginpage($orientation,$mgl='',$mgr='',$mgt='',$mgb='',$mgh='',$mgf='',$ohname='',$ehname='',$ofname='',$efname='',$ohvalue=0,$ehvalue=0,$ofvalue=0,$efvalue=0,$pagesel='',$newformat='') {
9313 if (!($pagesel && $this->page==1 && (sprintf("%0.4f", $this->y)==sprintf("%0.4f", $this->tMargin)))) {
9314 $this->page++;
9315 $this->pages[$this->page]='';
9316 }
9317 $this->state=2;
9318 $resetHTMLHeadersrequired = false;
9319
9320 if ($newformat) { $this->_setPageSize($newformat, $orientation); }
9321/*-- CSS-PAGE --*/
9322 // Paged media (page-box)
9323
9324 if ($pagesel || (isset($this->page_box['using']) && $this->page_box['using'])) {
9325 if ($pagesel || $this->page==1) { $first = true; }
9326 else { $first = false; }
9327 if ($this->mirrorMargins && ($this->page % 2==0)) { $oddEven = 'E'; }
9328 else { $oddEven = 'O'; }
9329 if ($pagesel) { $psel = $pagesel; }
9330 else if ($this->page_box['current']) { $psel = $this->page_box['current']; }
9331 else { $psel = ''; }
9332 list($orientation,$mgl,$mgr,$mgt,$mgb,$mgh,$mgf,$hname,$fname,$bg,$resetpagenum,$pagenumstyle,$suppress,$marks,$newformat) = $this->SetPagedMediaCSS($psel, $first, $oddEven);
9333 if ($this->mirrorMargins && ($this->page % 2==0)) {
9334 if ($hname) { $ehvalue = 1; $ehname = $hname; } else { $ehvalue = -1; }
9335 if ($fname) { $efvalue = 1; $efname = $fname; } else { $efvalue = -1; }
9336 }
9337 else {
9338 if ($hname) { $ohvalue = 1; $ohname = $hname; } else { $ohvalue = -1; }
9339 if ($fname) { $ofvalue = 1; $ofname = $fname; } else { $ofvalue = -1; }
9340 }
9341 if ($resetpagenum || $pagenumstyle || $suppress) {
9342 $this->PageNumSubstitutions[] = array('from'=>($this->page), 'reset'=> $resetpagenum, 'type'=>$pagenumstyle, 'suppress'=>$suppress);
9343 }
9344 // PAGED MEDIA - CROP / CROSS MARKS from @PAGE
9345 $this->show_marks = $marks;
9346
9347 // Background color
9348 if (isset($bg['BACKGROUND-COLOR'])) {
9349 $cor = $this->ConvertColor($bg['BACKGROUND-COLOR']);
9350 if ($cor) {
9351 $this->bodyBackgroundColor = $cor;
9352 }
9353 }
9354 else { $this->bodyBackgroundColor = false; }
9355
9356/*-- BACKGROUNDS --*/
9357 if (isset($bg['BACKGROUND-GRADIENT'])) {
9358 $this->bodyBackgroundGradient = $bg['BACKGROUND-GRADIENT'];
9359 }
9360 else { $this->bodyBackgroundGradient = false; }
9361
9362 // Tiling Patterns
9363 if (isset($bg['BACKGROUND-IMAGE']) && $bg['BACKGROUND-IMAGE']) {
9364 $ret = $this->SetBackground($bg, $this->pgwidth);
9365 if ($ret) { $this->bodyBackgroundImage = $ret; }
9366 }
9367 else { $this->bodyBackgroundImage = false; }
9368/*-- END BACKGROUNDS --*/
9369
9370 $this->page_box['current'] = $psel;
9371 $this->page_box['using'] = true;
9372 }
9373/*-- END CSS-PAGE --*/
9374
9375 //Page orientation
9376 if(!$orientation)
9377 $orientation=$this->DefOrientation;
9378 else {
9379 $orientation=strtoupper(substr($orientation,0,1));
9380 if($orientation!=$this->DefOrientation)
9381 $this->OrientationChanges[$this->page]=true;
9382 }
9383 if($orientation!=$this->CurOrientation || $newformat) {
9384
9385 //Change orientation
9386 if($orientation=='P') {
9387 $this->wPt=$this->fwPt;
9388 $this->hPt=$this->fhPt;
9389 $this->w=$this->fw;
9390 $this->h=$this->fh;
9391 if (($this->forcePortraitHeaders || $this->forcePortraitMargins) && $this->DefOrientation=='P') {
9392 $this->tMargin = $this->orig_tMargin;
9393 $this->bMargin = $this->orig_bMargin;
9394 $this->DeflMargin = $this->orig_lMargin;
9395 $this->DefrMargin = $this->orig_rMargin;
9396 $this->margin_header = $this->orig_hMargin;
9397 $this->margin_footer = $this->orig_fMargin;
9398 }
9399 else { $resetHTMLHeadersrequired = true; } // *HTMLHEADERS-FOOTERS*
9400 }
9401 else {
9402 $this->wPt=$this->fhPt;
9403 $this->hPt=$this->fwPt;
9404 $this->w=$this->fh;
9405 $this->h=$this->fw;
9406 if (($this->forcePortraitHeaders || $this->forcePortraitMargins) && $this->DefOrientation=='P') {
9407 $this->tMargin = $this->orig_lMargin;
9408 $this->bMargin = $this->orig_rMargin;
9409 $this->DeflMargin = $this->orig_bMargin;
9410 $this->DefrMargin = $this->orig_tMargin;
9411 $this->margin_header = $this->orig_hMargin;
9412 $this->margin_footer = $this->orig_fMargin;
9413 }
9414 else { $resetHTMLHeadersrequired = true; } // *HTMLHEADERS-FOOTERS*
9415
9416 }
9417 $this->CurOrientation=$orientation;
9418 $this->ResetMargins();
9419 $this->pgwidth = $this->w - $this->lMargin - $this->rMargin;
9420 $this->PageBreakTrigger=$this->h-$this->bMargin;
9421 }
9422
9423 $this->pageDim[$this->page]['w']=$this->w ;
9424 $this->pageDim[$this->page]['h']=$this->h ;
9425
9426 $this->pageDim[$this->page]['outer_width_LR'] = isset($this->page_box['outer_width_LR']) ? $this->page_box['outer_width_LR'] : 0;
9427 $this->pageDim[$this->page]['outer_width_TB'] = isset($this->page_box['outer_width_TB']) ? $this->page_box['outer_width_TB'] : 0;
9428 if (!isset($this->page_box['outer_width_LR']) && !isset($this->page_box['outer_width_TB'])) {
9429 $this->pageDim[$this->page]['bleedMargin'] = 0;
9430 }
9431 else if ($this->bleedMargin <= $this->page_box['outer_width_LR'] && $this->bleedMargin <= $this->page_box['outer_width_TB']) {
9432 $this->pageDim[$this->page]['bleedMargin'] = $this->bleedMargin;
9433 }
9434 else {
9435 $this->pageDim[$this->page]['bleedMargin'] = min($this->page_box['outer_width_LR'], $this->page_box['outer_width_TB'])-0.01;
9436 }
9437
9438 // If Page Margins are re-defined
9439 // strlen()>0 is used to pick up (integer) 0, (string) '0', or set value
9440 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)) {
9441 if (strlen($mgl)>0) $this->DeflMargin = $mgl;
9442 if (strlen($mgr)>0) $this->DefrMargin = $mgr;
9443 if (strlen($mgt)>0) $this->tMargin = $mgt;
9444 if (strlen($mgb)>0) $this->bMargin = $mgb;
9445 if (strlen($mgh)>0) $this->margin_header=$mgh;
9446 if (strlen($mgf)>0) $this->margin_footer=$mgf;
9447 $this->ResetMargins();
9448 $this->SetAutoPageBreak($this->autoPageBreak,$this->bMargin);
9449 $this->pgwidth = $this->w - $this->lMargin - $this->rMargin;
9450 $resetHTMLHeadersrequired = true; // *HTMLHEADERS-FOOTERS*
9451 }
9452
9453 $this->ResetMargins();
9454 $this->pgwidth = $this->w - $this->lMargin - $this->rMargin;
9455 $this->SetAutoPageBreak($this->autoPageBreak,$this->bMargin);
9456
9457 // Reset column top margin
9458 $this->y0 = $this->tMargin;
9459
9460 $this->x=$this->lMargin;
9461 $this->y=$this->tMargin;
9462 $this->FontFamily='';
9463
9464 // HEADERS AND FOOTERS
9465 if ($ohvalue<0 || strtoupper($ohvalue)=='OFF') {
9466 $this->HTMLHeader = '';
9467 $this->headerDetails['odd'] = array();
9468 $resetHTMLHeadersrequired = true; // *HTMLHEADERS-FOOTERS*
9469 }
9470 else if ($ohname && $ohvalue>0) {
9471/*-- HTMLHEADERS-FOOTERS --*/
9472 if (preg_match('/^html_(.*)$/i',$ohname,$n)) {
9473 if (isset($this->pageHTMLheaders[$n[1]])) { $this->HTMLHeader = $this->pageHTMLheaders[$n[1]]; }
9474 else { $this->HTMLHeader = ''; }
9475 $this->headerDetails['odd'] = array();
9476 $resetHTMLHeadersrequired = true;
9477 }
9478 else {
9479/*-- END HTMLHEADERS-FOOTERS --*/
9480 if (isset($this->pageheaders[$ohname])) { $this->headerDetails['odd'] = $this->pageheaders[$ohname]; }
9481 else if ($ohname!='_default') { $this->headerDetails['odd'] = array(); }
9482 $this->HTMLHeader = '';
9483/*-- HTMLHEADERS-FOOTERS --*/
9484 $resetHTMLHeadersrequired = false;
9485 }
9486/*-- END HTMLHEADERS-FOOTERS --*/
9487 }
9488
9489 if ($ehvalue<0 || strtoupper($ehvalue)=='OFF') {
9490 $this->HTMLHeaderE = '';
9491 $this->headerDetails['even'] = array();
9492 $resetHTMLHeadersrequired = true; // *HTMLHEADERS-FOOTERS*
9493 }
9494 else if ($ehname && $ehvalue>0) {
9495/*-- HTMLHEADERS-FOOTERS --*/
9496 if (preg_match('/^html_(.*)$/i',$ehname,$n)) {
9497 if (isset($this->pageHTMLheaders[$n[1]])) { $this->HTMLHeaderE = $this->pageHTMLheaders[$n[1]]; }
9498 else { $this->HTMLHeaderE = ''; }
9499 $this->headerDetails['even'] = array();
9500 $resetHTMLHeadersrequired = true;
9501 }
9502 else {
9503/*-- END HTMLHEADERS-FOOTERS --*/
9504 if (isset($this->pageheaders[$ehname])) { $this->headerDetails['even'] = $this->pageheaders[$ehname]; }
9505 else if ($ehname!='_default') { $this->headerDetails['even'] = array(); }
9506 $this->HTMLHeaderE = '';
9507/*-- HTMLHEADERS-FOOTERS --*/
9508 $resetHTMLHeadersrequired = false;
9509 }
9510/*-- END HTMLHEADERS-FOOTERS --*/
9511 }
9512
9513 if ($ofvalue<0 || strtoupper($ofvalue)=='OFF') {
9514 $this->HTMLFooter = '';
9515 $this->footerDetails['odd'] = array();
9516 $resetHTMLHeadersrequired = true; // *HTMLHEADERS-FOOTERS*
9517 }
9518 else if ($ofname && $ofvalue>0) {
9519/*-- HTMLHEADERS-FOOTERS --*/
9520 if (preg_match('/^html_(.*)$/i',$ofname,$n)) {
9521 if (isset($this->pageHTMLfooters[$n[1]])) { $this->HTMLFooter = $this->pageHTMLfooters[$n[1]]; }
9522 else { $this->HTMLFooter = ''; }
9523 $this->footerDetails['odd'] = array();
9524 $resetHTMLHeadersrequired = true;
9525 }
9526 else {
9527/*-- END HTMLHEADERS-FOOTERS --*/
9528 if (isset($this->pagefooters[$ofname])) { $this->footerDetails['odd'] = $this->pagefooters[$ofname]; }
9529 else if ($ofname!='_default') { $this->footerDetails['odd'] = array(); }
9530 $this->HTMLFooter = '';
9531/*-- HTMLHEADERS-FOOTERS --*/
9532 $resetHTMLHeadersrequired = true;
9533 }
9534/*-- END HTMLHEADERS-FOOTERS --*/
9535 }
9536
9537 if ($efvalue<0 || strtoupper($efvalue)=='OFF') {
9538 $this->HTMLFooterE = '';
9539 $this->footerDetails['even'] = array();
9540 $resetHTMLHeadersrequired = true; // *HTMLHEADERS-FOOTERS*
9541 }
9542 else if ($efname && $efvalue>0) {
9543/*-- HTMLHEADERS-FOOTERS --*/
9544 if (preg_match('/^html_(.*)$/i',$efname,$n)) {
9545 if (isset($this->pageHTMLfooters[$n[1]])) { $this->HTMLFooterE = $this->pageHTMLfooters[$n[1]]; }
9546 else { $this->HTMLFooterE = ''; }
9547 $this->footerDetails['even'] = array();
9548 $resetHTMLHeadersrequired = true;
9549 }
9550 else {
9551/*-- END HTMLHEADERS-FOOTERS --*/
9552 if (isset($this->pagefooters[$efname])) { $this->footerDetails['even'] = $this->pagefooters[$efname]; }
9553 else if ($efname!='_default') { $this->footerDetails['even'] = array(); }
9554 $this->HTMLFooterE = '';
9555/*-- HTMLHEADERS-FOOTERS --*/
9556 $resetHTMLHeadersrequired = true;
9557 }
9558/*-- END HTMLHEADERS-FOOTERS --*/
9559 }
9560/*-- HTMLHEADERS-FOOTERS --*/
9561 if ($resetHTMLHeadersrequired) {
9562 $this->SetHTMLHeader($this->HTMLHeader );
9563 $this->SetHTMLHeader($this->HTMLHeaderE ,'E');
9564 $this->SetHTMLFooter($this->HTMLFooter );
9565 $this->SetHTMLFooter($this->HTMLFooterE ,'E');
9566 }
9567/*-- END HTMLHEADERS-FOOTERS --*/
9568
9569
9570 if (($this->mirrorMargins) && (($this->page)%2==0)) { // EVEN
9571 $this->_setAutoHeaderHeight($this->headerDetails['even'], $this->HTMLHeaderE);
9572 $this->_setAutoFooterHeight($this->footerDetails['even'], $this->HTMLFooterE);
9573 }
9574 else { // ODD or DEFAULT
9575 $this->_setAutoHeaderHeight($this->headerDetails['odd'], $this->HTMLHeader);
9576 $this->_setAutoFooterHeight($this->footerDetails['odd'], $this->HTMLFooter);
9577 }
9578 // Reset column top margin
9579 $this->y0 = $this->tMargin;
9580
9581 $this->x=$this->lMargin;
9582 $this->y=$this->tMargin;
9583}
9584
9585
9586
9587function _setAutoHeaderHeight(&$det, &$htmlh) {
9588 if ($this->setAutoTopMargin=='pad') {
9589 if ($htmlh['h']) { $h = $htmlh['h']; }
9590 else if ($det) { $h = $this->_getHFHeight($det,'H'); }
9591 else { $h = 0; }
9592 $this->tMargin = $this->margin_header + $h + $this->orig_tMargin;
9593 }
9594 else if ($this->setAutoTopMargin=='stretch') {
9595 if ($htmlh['h']) { $h = $htmlh['h']; }
9596 else if ($det) { $h = $this->_getHFHeight($det,'H'); }
9597 else { $h = 0; }
9598 $this->tMargin = max($this->orig_tMargin, $this->margin_header + $h + $this->autoMarginPadding);
9599 }
9600}
9601
9602
9603function _setAutoFooterHeight(&$det, &$htmlf) {
9604 if ($this->setAutoBottomMargin=='pad') {
9605 if ($htmlf['h']) { $h = $htmlf['h']; }
9606 else if ($det) { $h = $this->_getHFHeight($det,'F'); }
9607 else { $h = 0; }
9608 $this->bMargin = $this->margin_footer + $h + $this->orig_bMargin;
9609 $this->PageBreakTrigger=$this->h-$this->bMargin ;
9610 }
9611 else if ($this->setAutoBottomMargin=='stretch') {
9612 if ($htmlf['h']) { $h = $htmlf['h']; }
9613 else if ($det) { $h = $this->_getHFHeight($det,'F'); }
9614 else { $h = 0; }
9615 $this->bMargin = max($this->orig_bMargin, $this->margin_footer + $h + $this->autoMarginPadding);
9616 $this->PageBreakTrigger=$this->h-$this->bMargin ;
9617 }
9618}
9619
9620function _getHFHeight(&$det,$end) {
9621 $h = 0;
9622 if(count($det)) {
9623 foreach(array('L','C','R') AS $pos) {
9624 if (isset($det[$pos]['content']) && $det[$pos]['content']) {
9625 if (isset($det[$pos]['font-size']) && $det[$pos]['font-size']) { $hfsz = $det[$pos]['font-size']; }
9626 else { $hfsz = $this->default_font_size; }
9627 $h = max($h,$hfsz/_MPDFK);
9628 }
9629 }
9630 if ($det['line'] && $end=='H') { $h += $h/_MPDFK*$this->header_line_spacing; }
9631 else if ($det['line'] && $end=='F') { $h += $h/_MPDFK*$this->footer_line_spacing; }
9632 }
9633 return $h;
9634}
9635
9636
9637function _endpage() {
9638/*-- CSS-IMAGE-FLOAT --*/
9639 $this->printfloatbuffer();
9640/*-- END CSS-IMAGE-FLOAT --*/
9641
9642 if($this->visibility!='visible')
9643 $this->SetVisibility('visible');
9644 $this->EndLayer(); // mPDF 5.6.01
9645 //End of page contents
9646 $this->state=1;
9647}
9648
9649function _newobj($obj_id=false,$onlynewobj=false) {
9650 if (!$obj_id) {
9651 $obj_id = ++$this->n;
9652 }
9653 //Begin a new object
9654 if (!$onlynewobj) {
9655 $this->offsets[$obj_id] = strlen($this->buffer);
9656 $this->_out($obj_id.' 0 obj');
9657 $this->_current_obj_id = $obj_id; // for later use with encryption
9658 }
9659}
9660
9661function _dounderline($x,$y,$txt) {
9662 // Now print line exactly where $y secifies - called from Text() and Cell() - adjust position there
9663 // WORD SPACING
9664 $w =($this->GetStringWidth($txt)*_MPDFK) + ($this->charspacing * mb_strlen( $txt, $this->mb_enc ))
9665 + ( $this->ws * mb_substr_count( $txt, ' ', $this->mb_enc ));
9666 //Draw a line
9667 return sprintf('%.3F %.3F m %.3F %.3F l S',$x*_MPDFK,($this->h-$y)*_MPDFK,($x*_MPDFK)+$w,($this->h-$y)*_MPDFK);
9668}
9669
9670
9671function _imageError($file, $firsttime, $msg) {
9672 // Save re-trying image URL's which have already failed
9673 $this->failedimages[$file] = true;
9674 if ($firsttime && ($this->showImageErrors || $this->debug)) {
9675 $this->Error("IMAGE Error (".$file."): ".$msg);
9676 }
9677 return false;
9678}
9679
9680
9681function _getImage(&$file, $firsttime=true, $allowvector=true, $orig_srcpath=false) {
9682 // firsttime i.e. whether to add to this->images - use false when calling iteratively
9683 // Image Data passed directly as var:varname
9684 if (preg_match('/var:\s*(.*)/',$file, $v)) {
9685 $data = $this->$v[1];
9686 $file = md5($data);
9687 }
9688 // mPDF 5.5.13
9689 if (preg_match('/data:image\/(gif|jpeg|png);base64,(.*)/',$file, $v)) {
9690 $type = $v[1];
9691 $data = base64_decode($v[2]);
9692 $file = md5($data);
9693 }
9694
9695 // mPDF 5.6.02
9696 if ($firsttime && $file && substr($file,0,5)!='data:') { $file = urlencode_part($file); }
9697 if ($firsttime && $orig_srcpath && substr($orig_srcpath,0,5)!='data:') { $orig_srcpath = urlencode_part($orig_srcpath); }
9698
9699 $ppUx = 0;
9700 if ($orig_srcpath && isset($this->images[$orig_srcpath])) { $file=$orig_srcpath; return $this->images[$orig_srcpath]; }
9701 if (isset($this->images[$file])) { return $this->images[$file]; }
9702 else if ($orig_srcpath && isset($this->formobjects[$orig_srcpath])) { $file=$orig_srcpath; return $this->formobjects[$file]; }
9703 else if (isset($this->formobjects[$file])) { return $this->formobjects[$file]; }
9704 // Save re-trying image URL's which have already failed
9705 else if ($firsttime && isset($this->failedimages[$file])) { return $this->_imageError($file, $firsttime, ''); }
9706 if (empty($data)) {
9707 $type = '';
9708 $data = '';
9709
9710 if ($orig_srcpath && $this->basepathIsLocal && $check = @fopen($orig_srcpath,"rb")) {
9711 fclose($check);
9712 $file=$orig_srcpath;
9713 $data = file_get_contents($file);
9714 $type = $this->_imageTypeFromString($data);
9715 }
9716 if (!$data && $check = @fopen($file,"rb")) {
9717 fclose($check);
9718 $data = file_get_contents($file);
9719 $type = $this->_imageTypeFromString($data);
9720 }
9721 if ((!$data || !$type) && !ini_get('allow_url_fopen') ) { // only worth trying if remote file and !ini_get('allow_url_fopen')
9722 $this->file_get_contents_by_socket($file, $data); // needs full url?? even on local (never needed for local)
9723 if ($data) { $type = $this->_imageTypeFromString($data); }
9724 }
9725 if ((!$data || !$type) && !ini_get('allow_url_fopen') && function_exists("curl_init")) {
9726 $this->file_get_contents_by_curl($file, $data); // needs full url?? even on local (never needed for local)
9727 if ($data) { $type = $this->_imageTypeFromString($data); }
9728 }
9729
9730 }
9731 if (!$data) { return $this->_imageError($file, $firsttime, 'Could not find image file'); }
9732 if (empty($type)) { $type = $this->_imageTypeFromString($data); }
9733 if (($type == 'wmf' || $type == 'svg') && !$allowvector) { return $this->_imageError($file, $firsttime, 'WMF or SVG image file not supported in this context'); }
9734
9735 // SVG
9736 if ($type == 'svg') {
9737 if (!class_exists('SVG', false)) { include(_MPDF_PATH .'classes/svg.php'); }
9738 $svg = new SVG($this);
9739 $family=$this->FontFamily;
9740 $style=$this->FontStyle;
9741 $size=$this->FontSizePt;
9742 $info = $svg->ImageSVG($data);
9743 //Restore font
9744 if($family) $this->SetFont($family,$style,$size,false);
9745 if (!$info) { return $this->_imageError($file, $firsttime, 'Error parsing SVG file'); }
9746 $info['type']='svg';
9747 $info['i']=count($this->formobjects)+1;
9748 $this->formobjects[$file]=$info;
9749 return $info;
9750 }
9751
9752 // JPEG
9753 if ($type == 'jpeg' || $type == 'jpg') {
9754 $hdr = $this->_jpgHeaderFromString($data);
9755 if (!$hdr) { return $this->_imageError($file, $firsttime, 'Error parsing JPG header'); }
9756 $a = $this->_jpgDataFromHeader($hdr);
9757 $j = strpos($data,'JFIF');
9758 if ($j) {
9759 //Read resolution
9760 $unitSp=ord(substr($data,($j+7),1));
9761 if ($unitSp > 0) {
9762 $ppUx=$this->_twobytes2int(substr($data,($j+8),2)); // horizontal pixels per meter, usually set to zero
9763 if ($unitSp == 2) { // = dots per cm (if == 1 set as dpi)
9764 $ppUx=round($ppUx/10 *25.4);
9765 }
9766 }
9767 }
9768 if ($a[2] == 'DeviceCMYK' && (($this->PDFA && $this->restrictColorSpace!=3) || $this->restrictColorSpace==2)) {
9769 // convert to RGB image
9770 if (!function_exists("gd_info")) { $this->Error("JPG image may not use CMYK color space (".$file.")."); }
9771 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.)"; }
9772 $im = @imagecreatefromstring($data);
9773 if ($im) {
9774 $tempfile = _MPDF_TEMP_PATH.'_tempImgPNG'.md5($file).RAND(1,10000).'.png';
9775 imageinterlace($im, false);
9776 $check = @imagepng($im, $tempfile);
9777 if (!$check) { return $this->_imageError($file, $firsttime, 'Error creating temporary file ('.$tempfile.') whilst using GD library to parse JPG(CMYK) image'); }
9778 $info = $this->_getImage($tempfile, false);
9779 if (!$info) { return $this->_imageError($file, $firsttime, 'Error parsing temporary file ('.$tempfile.') created with GD library to parse JPG(CMYK) image'); }
9780 imagedestroy($im);
9781 unlink($tempfile);
9782 $info['type']='jpg';
9783 if ($firsttime) {
9784 $info['i']=count($this->images)+1;
9785 $this->images[$file]=$info;
9786 }
9787 return $info;
9788 }
9789 else { return $this->_imageError($file, $firsttime, 'Error creating GD image file from JPG(CMYK) image'); }
9790 }
9791 else if ($a[2] == 'DeviceRGB' && ($this->PDFX || $this->restrictColorSpace==3)) {
9792 // Convert to CMYK image stream - nominally returned as type='png'
9793 $info = $this->_convImage($data, $a[2], 'DeviceCMYK', $a[0], $a[1], $ppUx, false);
9794 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.)"; }
9795 }
9796 else if (($a[2] == 'DeviceRGB' || $a[2] == 'DeviceCMYK') && $this->restrictColorSpace==1) {
9797 // Convert to Grayscale image stream - nominally returned as type='png'
9798 $info = $this->_convImage($data, $a[2], 'DeviceGray', $a[0], $a[1], $ppUx, false);
9799 }
9800 else {
9801 $info = array('w'=>$a[0],'h'=>$a[1],'cs'=>$a[2],'bpc'=>$a[3],'f'=>'DCTDecode','data'=>$data, 'type'=>'jpg');
9802 if ($ppUx) { $info['set-dpi'] = $ppUx; }
9803 }
9804 if (!$info) { return $this->_imageError($file, $firsttime, 'Error parsing or converting JPG image'); }
9805
9806 if ($firsttime) {
9807 $info['i']=count($this->images)+1;
9808 $this->images[$file]=$info;
9809 }
9810 return $info;
9811 }
9812
9813 // PNG
9814 else if ($type == 'png') {
9815 //Check signature
9816 if(substr($data,0,8)!=chr(137).'PNG'.chr(13).chr(10).chr(26).chr(10)) {
9817 return $this->_imageError($file, $firsttime, 'Error parsing PNG identifier');
9818 }
9819 //Read header chunk
9820 if(substr($data,12,4)!='IHDR') {
9821 return $this->_imageError($file, $firsttime, 'Incorrect PNG file (no IHDR block found)');
9822 }
9823
9824 $w=$this->_fourbytes2int(substr($data,16,4));
9825 $h=$this->_fourbytes2int(substr($data,20,4));
9826 $bpc=ord(substr($data,24,1));
9827 $errpng = false;
9828 $pngalpha = false;
9829 if($bpc>8) { $errpng = 'not 8-bit depth'; }
9830 $ct=ord(substr($data,25,1));
9831 if($ct==0) { $colspace='DeviceGray'; }
9832 elseif($ct==2) { $colspace='DeviceRGB'; }
9833 elseif($ct==3) { $colspace='Indexed'; }
9834 elseif($ct==4) { $colspace='DeviceGray'; $errpng = 'alpha channel'; $pngalpha = true; }
9835 else { $colspace='DeviceRGB'; $errpng = 'alpha channel'; $pngalpha = true; }
9836 if(ord(substr($data,26,1))!=0) { $errpng = 'compression method'; }
9837 if(ord(substr($data,27,1))!=0) { $errpng = 'filter method'; }
9838 if(ord(substr($data,28,1))!=0) { $errpng = 'interlaced file'; }
9839 $j = strpos($data,'pHYs');
9840 if ($j) {
9841 //Read resolution
9842 $unitSp=ord(substr($data,($j+12),1));
9843 if ($unitSp == 1) {
9844 $ppUx=$this->_fourbytes2int(substr($data,($j+4),4)); // horizontal pixels per meter, usually set to zero
9845 $ppUx=round($ppUx/1000 *25.4);
9846 }
9847 }
9848 if (($colspace == 'DeviceRGB' || $colspace == 'Indexed') && ($this->PDFX || $this->restrictColorSpace==3)) {
9849 // Convert to CMYK image stream - nominally returned as type='png'
9850 $info = $this->_convImage($data, $colspace, 'DeviceCMYK', $w, $h, $ppUx, $pngalpha);
9851 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.)"; }
9852 }
9853 else if (($colspace == 'DeviceRGB' || $colspace == 'Indexed') && $this->restrictColorSpace==1) {
9854 // Convert to Grayscale image stream - nominally returned as type='png'
9855 $info = $this->_convImage($data, $colspace, 'DeviceGray', $w, $h, $ppUx, $pngalpha);
9856 }
9857 else if (($this->PDFA || $this->PDFX) && $pngalpha) {
9858 // Remove alpha channel
9859 if ($this->restrictColorSpace==1) { // Grayscale
9860 $info = $this->_convImage($data, $colspace, 'DeviceGray', $w, $h, $ppUx, $pngalpha);
9861 }
9862 else if ($this->restrictColorSpace==3) { // CMYK
9863 $info = $this->_convImage($data, $colspace, 'DeviceCMYK', $w, $h, $ppUx, $pngalpha);
9864 }
9865 else if ($this->PDFA ) { // RGB
9866 $info = $this->_convImage($data, $colspace, 'DeviceRGB', $w, $h, $ppUx, $pngalpha);
9867 }
9868 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.)"; }
9869 }
9870 else if ($errpng || $pngalpha) {
9871 if (function_exists('gd_info')) { $gd = gd_info(); }
9872 else {$gd = array(); }
9873 if (!isset($gd['PNG Support'])) { return $this->_imageError($file, $firsttime, 'GD library required for PNG image ('.$errpng.')'); }
9874 $im = imagecreatefromstring($data);
9875 if (!$im) { return $this->_imageError($file, $firsttime, 'Error creating GD image from PNG file ('.$errpng.')'); }
9876 $w = imagesx($im);
9877 $h = imagesy($im);
9878 if ($im) {
9879 $tempfile = _MPDF_TEMP_PATH.'_tempImgPNG'.md5($file).RAND(1,10000).'.png';
9880 // Alpha channel set
9881 if ($pngalpha) {
9882 if ($this->PDFA) { $this->Error("PDFA1-b does not permit images with alpha channel transparency (".$file.")."); }
9883 $imgalpha = imagecreate($w, $h);
9884 // generate gray scale pallete
9885 for ($c = 0; $c < 256; ++$c) { ImageColorAllocate($imgalpha, $c, $c, $c); }
9886 // extract alpha channel
9887 for ($xpx = 0; $xpx < $w; ++$xpx) {
9888 for ($ypx = 0; $ypx < $h; ++$ypx) {
9889 $alpha = (imagecolorat($im, $xpx, $ypx) & 0x7F000000) >> 24;
9890 // mPDF 5.7.2
9891 if ($alpha < 127) {
9892 imagesetpixel($imgalpha, $xpx, $ypx, (255-($alpha * 2)));
9893 }
9894 }
9895 }
9896 // create temp alpha file
9897 $tempfile_alpha = _MPDF_TEMP_PATH.'_tempMskPNG'.md5($file).RAND(1,10000).'.png';
9898 if (!is_writable(_MPDF_TEMP_PATH)) { // mPDF 5.7.2
9899 ob_start();
9900 $check = @imagepng($imgalpha);
9901 if (!$check) { return $this->_imageError($file, $firsttime, 'Error creating temporary image object whilst using GD library to parse PNG image'); }
9902 imagedestroy($imgalpha);
9903 $this->_tempimg = ob_get_contents();
9904 $this->_tempimglnk = 'var:_tempimg';
9905 ob_end_clean();
9906 // extract image without alpha channel
9907 $imgplain = imagecreatetruecolor($w, $h);
9908 imagealphablending( $imgplain, false ); // mPDF 5.7.2
9909 imagecopy($imgplain, $im, 0, 0, 0, 0, $w, $h);
9910 // create temp image file
9911 $minfo = $this->_getImage($this->_tempimglnk, false);
9912 if (!$minfo) { return $this->_imageError($file, $firsttime, 'Error parsing temporary file image object created with GD library to parse PNG image'); }
9913 ob_start();
9914 $check = @imagepng($imgplain);
9915 if (!$check) { return $this->_imageError($file, $firsttime, 'Error creating temporary image object whilst using GD library to parse PNG image'); }
9916 $this->_tempimg = ob_get_contents();
9917 $this->_tempimglnk = 'var:_tempimg';
9918 ob_end_clean();
9919 $info = $this->_getImage($this->_tempimglnk, false);
9920 if (!$info) { return $this->_imageError($file, $firsttime, 'Error parsing temporary file image object created with GD library to parse PNG image'); }
9921 imagedestroy($imgplain);
9922 $imgmask = count($this->images)+1;
9923 $minfo['cs'] = 'DeviceGray';
9924 $minfo['i']=$imgmask ;
9925 $this->images[$tempfile_alpha] = $minfo;
9926
9927 }
9928 else {
9929 $check = @imagepng($imgalpha, $tempfile_alpha);
9930 if (!$check) { return $this->_imageError($file, $firsttime, 'Failed to create temporary image file ('.$tempfile_alpha.') parsing PNG image with alpha channel ('.$errpng.')'); }
9931 imagedestroy($imgalpha);
9932
9933 // extract image without alpha channel
9934 $imgplain = imagecreatetruecolor($w, $h);
9935 imagealphablending( $imgplain, false ); // mPDF 5.7.2
9936 imagecopy($imgplain, $im, 0, 0, 0, 0, $w, $h);
9937
9938 // create temp image file
9939 $check = @imagepng($imgplain, $tempfile);
9940 if (!$check) { return $this->_imageError($file, $firsttime, 'Failed to create temporary image file ('.$tempfile.') parsing PNG image with alpha channel ('.$errpng.')'); }
9941 imagedestroy($imgplain);
9942 // embed mask image
9943 $minfo = $this->_getImage($tempfile_alpha, false);
9944 unlink($tempfile_alpha);
9945 if (!$minfo) { return $this->_imageError($file, $firsttime, 'Error parsing temporary file ('.$tempfile_alpha.') created with GD library to parse PNG image'); }
9946 $imgmask = count($this->images)+1;
9947 $minfo['cs'] = 'DeviceGray';
9948 $minfo['i']=$imgmask ;
9949 $this->images[$tempfile_alpha] = $minfo;
9950 // embed image, masked with previously embedded mask
9951 $info = $this->_getImage($tempfile, false);
9952 unlink($tempfile);
9953 if (!$info) { return $this->_imageError($file, $firsttime, 'Error parsing temporary file ('.$tempfile.') created with GD library to parse PNG image'); }
9954
9955 }
9956 $info['masked'] = $imgmask;
9957 if ($ppUx) { $info['set-dpi'] = $ppUx; }
9958 $info['type']='png';
9959 if ($firsttime) {
9960 $info['i']=count($this->images)+1;
9961 $this->images[$file]=$info;
9962 }
9963 return $info;
9964 }
9965 else { // No alpha/transparency set
9966 imagealphablending($im, false);
9967 imagesavealpha($im, false);
9968 imageinterlace($im, false);
9969 if (!is_writable($tempfile)) {
9970 ob_start();
9971 $check = @imagepng($im);
9972 if (!$check) { return $this->_imageError($file, $firsttime, 'Error creating temporary image object whilst using GD library to parse PNG image'); }
9973 $this->_tempimg = ob_get_contents();
9974 $this->_tempimglnk = 'var:_tempimg';
9975 ob_end_clean();
9976 $info = $this->_getImage($this->_tempimglnk, false);
9977 if (!$info) { return $this->_imageError($file, $firsttime, 'Error parsing temporary file image object created with GD library to parse PNG image'); }
9978 imagedestroy($im);
9979 }
9980 else {
9981 $check = @imagepng($im, $tempfile );
9982 if (!$check) { return $this->_imageError($file, $firsttime, 'Failed to create temporary image file ('.$tempfile.') parsing PNG image ('.$errpng.')'); }
9983 imagedestroy($im);
9984 $info = $this->_getImage($tempfile, false) ;
9985 unlink($tempfile );
9986 if (!$info) { return $this->_imageError($file, $firsttime, 'Error parsing temporary file ('.$tempfile.') created with GD library to parse PNG image'); }
9987 }
9988 if ($ppUx) { $info['set-dpi'] = $ppUx; }
9989 $info['type']='png';
9990 if ($firsttime) {
9991 $info['i']=count($this->images)+1;
9992 $this->images[$file]=$info;
9993 }
9994 return $info;
9995 }
9996 }
9997 }
9998
9999 else {
10000 $parms='/DecodeParms <</Predictor 15 /Colors '.($ct==2 ? 3 : 1).' /BitsPerComponent '.$bpc.' /Columns '.$w.'>>';
10001 //Scan chunks looking for palette, transparency and image data
10002 $pal='';
10003 $trns='';
10004 $pngdata='';
10005 $p = 33;
10006 do {
10007 $n=$this->_fourbytes2int(substr($data,$p,4)); $p += 4;
10008 $type=substr($data,$p,4); $p += 4;
10009 if($type=='PLTE') {
10010 //Read palette
10011 $pal=substr($data,$p,$n); $p += $n;
10012 $p += 4;
10013 }
10014 elseif($type=='tRNS') {
10015 //Read transparency info
10016 $t=substr($data,$p,$n); $p += $n;
10017 if($ct==0) $trns=array(ord(substr($t,1,1)));
10018 elseif($ct==2) $trns=array(ord(substr($t,1,1)),ord(substr($t,3,1)),ord(substr($t,5,1)));
10019 else
10020 {
10021 $pos=strpos($t,chr(0));
10022 if(is_int($pos)) $trns=array($pos);
10023 }
10024 $p += 4;
10025 }
10026 elseif($type=='IDAT') {
10027 $pngdata.=substr($data,$p,$n); $p += $n;
10028 $p += 4;
10029 }
10030 elseif($type=='IEND') { break; }
10031 else if (preg_match('/[a-zA-Z]{4}/',$type)) { $p += $n+4; }
10032 else { return $this->_imageError($file, $firsttime, 'Error parsing PNG image data'); }
10033 }
10034 while($n);
10035 if (!$pngdata) { return $this->_imageError($file, $firsttime, 'Error parsing PNG image data - no IDAT data found'); }
10036 if($colspace=='Indexed' and empty($pal)) { return $this->_imageError($file, $firsttime, 'Error parsing PNG image data - missing colour palette'); }
10037 $info = array('w'=>$w,'h'=>$h,'cs'=>$colspace,'bpc'=>$bpc,'f'=>'FlateDecode','parms'=>$parms,'pal'=>$pal,'trns'=>$trns,'data'=>$pngdata);
10038 $info['type']='png';
10039 if ($ppUx) { $info['set-dpi'] = $ppUx; }
10040 }
10041
10042 if (!$info) { return $this->_imageError($file, $firsttime, 'Error parsing or converting PNG image'); }
10043
10044 if ($firsttime) {
10045 $info['i']=count($this->images)+1;
10046 $this->images[$file]=$info;
10047 }
10048 return $info;
10049 }
10050
10051 // GIF
10052 else if ($type == 'gif') {
10053 if (function_exists('gd_info')) { $gd = gd_info(); }
10054 else {$gd = array(); }
10055 if (isset($gd['GIF Read Support']) && $gd['GIF Read Support']) {
10056 $im = @imagecreatefromstring($data);
10057 if ($im) {
10058 $tempfile = _MPDF_TEMP_PATH.'_tempImgPNG'.md5($file).RAND(1,10000).'.png';
10059 imagealphablending($im, false);
10060 imagesavealpha($im, false);
10061 imageinterlace($im, false);
10062 if (!is_writable($tempfile)) {
10063 ob_start();
10064 $check = @imagepng($im);
10065 if (!$check) { return $this->_imageError($file, $firsttime, 'Error creating temporary image object whilst using GD library to parse GIF image'); }
10066 $this->_tempimg = ob_get_contents();
10067 $this->_tempimglnk = 'var:_tempimg';
10068 ob_end_clean();
10069 $info = $this->_getImage($this->_tempimglnk, false);
10070 if (!$info) { return $this->_imageError($file, $firsttime, 'Error parsing temporary file image object created with GD library to parse GIF image'); }
10071 imagedestroy($im);
10072 }
10073 else {
10074 $check = @imagepng($im, $tempfile);
10075 if (!$check) { return $this->_imageError($file, $firsttime, 'Error creating temporary file ('.$tempfile.') whilst using GD library to parse GIF image'); }
10076 $info = $this->_getImage($tempfile, false);
10077 if (!$info) { return $this->_imageError($file, $firsttime, 'Error parsing temporary file ('.$tempfile.') created with GD library to parse GIF image'); }
10078 imagedestroy($im);
10079 unlink($tempfile);
10080 }
10081 $info['type']='gif';
10082 if ($firsttime) {
10083 $info['i']=count($this->images)+1;
10084 $this->images[$file]=$info;
10085 }
10086 return $info;
10087 }
10088 else { return $this->_imageError($file, $firsttime, 'Error creating GD image file from GIF image'); }
10089 }
10090
10091 if (!class_exists('gif', false)) {
10092 include_once(_MPDF_PATH.'classes/gif.php');
10093 }
10094 $gif=new CGIF();
10095
10096 $h=0;
10097 $w=0;
10098 $gif->loadFile($data, 0);
10099
10100 if(isset($gif->m_img->m_gih->m_bLocalClr) && $gif->m_img->m_gih->m_bLocalClr) {
10101 $nColors = $gif->m_img->m_gih->m_nTableSize;
10102 $pal = $gif->m_img->m_gih->m_colorTable->toString();
10103 if($bgColor != -1) {
10104 $bgColor = $gif->m_img->m_gih->m_colorTable->colorIndex($bgColor);
10105 }
10106 $colspace='Indexed';
10107 } elseif(isset($gif->m_gfh->m_bGlobalClr) && $gif->m_gfh->m_bGlobalClr) {
10108 $nColors = $gif->m_gfh->m_nTableSize;
10109 $pal = $gif->m_gfh->m_colorTable->toString();
10110 if((isset($bgColor)) and $bgColor != -1) {
10111 $bgColor = $gif->m_gfh->m_colorTable->colorIndex($bgColor);
10112 }
10113 $colspace='Indexed';
10114 } else {
10115 $nColors = 0;
10116 $bgColor = -1;
10117 $colspace='DeviceGray';
10118 $pal='';
10119 }
10120
10121 $trns='';
10122 if(isset($gif->m_img->m_bTrans) && $gif->m_img->m_bTrans && ($nColors > 0)) {
10123 $trns=array($gif->m_img->m_nTrans);
10124 }
10125 $gifdata=$gif->m_img->m_data;
10126 $w=$gif->m_gfh->m_nWidth;
10127 $h=$gif->m_gfh->m_nHeight;
10128 $gif->ClearData();
10129
10130 if($colspace=='Indexed' and empty($pal)) {
10131 return $this->_imageError($file, $firsttime, 'Error parsing GIF image - missing colour palette');
10132 }
10133 if ($this->compress) {
10134 $gifdata=gzcompress($gifdata);
10135 $info = array( 'w'=>$w, 'h'=>$h, 'cs'=>$colspace, 'bpc'=>8, 'f'=>'FlateDecode', 'pal'=>$pal, 'trns'=>$trns, 'data'=>$gifdata);
10136 }
10137 else {
10138 $info = array( 'w'=>$w, 'h'=>$h, 'cs'=>$colspace, 'bpc'=>8, 'pal'=>$pal, 'trns'=>$trns, 'data'=>$gifdata);
10139 }
10140 $info['type']='gif';
10141 if ($firsttime) {
10142 $info['i']=count($this->images)+1;
10143 $this->images[$file]=$info;
10144 }
10145 return $info;
10146 }
10147
10148/*-- IMAGES-BMP --*/
10149 // BMP (Windows Bitmap)
10150 else if ($type == 'bmp') {
10151 if (!class_exists('bmp', false)) { include(_MPDF_PATH.'classes/bmp.php'); }
10152 if (empty($this->bmp)) { $this->bmp = new bmp($this); }
10153 $info = $this->bmp->_getBMPimage($data, $file);
10154 if (isset($info['error'])) {
10155 return $this->_imageError($file, $firsttime, $info['error']);
10156 }
10157 if ($firsttime) {
10158 $info['i']=count($this->images)+1;
10159 $this->images[$file]=$info;
10160 }
10161 return $info;
10162 }
10163/*-- END IMAGES-BMP --*/
10164/*-- IMAGES-WMF --*/
10165 // WMF
10166 else if ($type == 'wmf') {
10167 if (!class_exists('wmf', false)) { include(_MPDF_PATH.'classes/wmf.php'); }
10168 if (empty($this->wmf)) { $this->wmf = new wmf($this); }
10169 $wmfres = $this->wmf->_getWMFimage($data);
10170 if ($wmfres[0]==0) {
10171 if ($wmfres[1]) { return $this->_imageError($file, $firsttime, $wmfres[1]); }
10172 return $this->_imageError($file, $firsttime, 'Error parsing WMF image');
10173 }
10174 $info = array('x'=>$wmfres[2][0],'y'=>$wmfres[2][1],'w'=>$wmfres[3][0],'h'=>$wmfres[3][1],'data'=>$wmfres[1]);
10175 $info['i']=count($this->formobjects)+1;
10176 $info['type']='wmf';
10177 $this->formobjects[$file]=$info;
10178 return $info;
10179 }
10180/*-- END IMAGES-WMF --*/
10181
10182 // UNKNOWN TYPE - try GD imagecreatefromstring
10183 else {
10184 if (function_exists('gd_info')) { $gd = gd_info(); }
10185 else {$gd = array(); }
10186 if (isset($gd['PNG Support']) && $gd['PNG Support']) {
10187 $im = @imagecreatefromstring($data);
10188 if (!$im) { return $this->_imageError($file, $firsttime, 'Error parsing image file - image type not recognised, and not supported by GD imagecreate'); }
10189 $tempfile = _MPDF_TEMP_PATH.'_tempImgPNG'.md5($file).RAND(1,10000).'.png';
10190 imagealphablending($im, false);
10191 imagesavealpha($im, false);
10192 imageinterlace($im, false);
10193 $check = @imagepng($im, $tempfile);
10194 if (!$check) { return $this->_imageError($file, $firsttime, 'Error creating temporary file ('.$tempfile.') whilst using GD library to parse unknown image type'); }
10195 $info = $this->_getImage($tempfile, false);
10196 imagedestroy($im);
10197 unlink($tempfile);
10198 if (!$info) { return $this->_imageError($file, $firsttime, 'Error parsing temporary file ('.$tempfile.') created with GD library to parse unknown image type'); }
10199 $info['type']='png';
10200 if ($firsttime) {
10201 $info['i']=count($this->images)+1;
10202 $this->images[$file]=$info;
10203 }
10204 return $info;
10205 }
10206 }
10207
10208 return $this->_imageError($file, $firsttime, 'Error parsing image file - image type not recognised');
10209}
10210//==============================================================
10211function _convImage(&$data, $colspace, $targetcs, $w, $h, $dpi, $mask) {
10212 if ($this->PDFA || $this->PDFX) { $mask=false; }
10213 $im = @imagecreatefromstring($data);
10214 $info = array();
10215 if ($im) {
10216 $imgdata = '';
10217 $mimgdata = '';
10218 $minfo = array();
10219 //Read transparency info
10220 $trns=array();
10221 $trnsrgb = false;
10222 if (!$this->PDFA && !$this->PDFX) {
10223 $p = strpos($data,'tRNS');
10224 if ($p) {
10225 $n=$this->_fourbytes2int(substr($data,($p-4),4));
10226 $t = substr($data,($p+4),$n);
10227 if ($colspace=='DeviceGray') {
10228 $trns=array(ord(substr($t,1,1)));
10229 $trnsrgb = array($trns[0],$trns[0],$trns[0]);
10230 }
10231 else if ($colspace=='DeviceRGB') {
10232 $trns=array(ord(substr($t,1,1)),ord(substr($t,3,1)),ord(substr($t,5,1)));
10233 $trnsrgb = $trns;
10234 if ($targetcs=='DeviceCMYK') {
10235 $col = $this->rgb2cmyk(array(3,$trns[0],$trns[1],$trns[2]));
10236 $c1 = intval($col[1]*2.55);
10237 $c2 = intval($col[2]*2.55);
10238 $c3 = intval($col[3]*2.55);
10239 $c4 = intval($col[4]*2.55);
10240 $trns = array($c1,$c2,$c3,$c4);
10241 }
10242 else if ($targetcs=='DeviceGray') {
10243 $c = intval(($trns[0] * .21) + ($trns[1] * .71) + ($trns[2] * .07));
10244 $trns = array($c);
10245 }
10246 }
10247 else { // Indexed
10248 $pos = strpos($t,chr(0));
10249 if (is_int($pos)) {
10250 $pal = imagecolorsforindex($im, $pos);
10251 $r = $pal['red'];
10252 $g = $pal['green'];
10253 $b = $pal['blue'];
10254 $trns=array($r,$g,$b); // ****
10255 $trnsrgb = $trns;
10256 if ($targetcs=='DeviceCMYK') {
10257 $col = $this->rgb2cmyk(array(3,$r,$g,$b));
10258 $c1 = intval($col[1]*2.55);
10259 $c2 = intval($col[2]*2.55);
10260 $c3 = intval($col[3]*2.55);
10261 $c4 = intval($col[4]*2.55);
10262 $trns = array($c1,$c2,$c3,$c4);
10263 }
10264 else if ($targetcs=='DeviceGray') {
10265 $c = intval(($r * .21) + ($g * .71) + ($b * .07));
10266 $trns = array($c);
10267 }
10268 }
10269 }
10270 }
10271 }
10272 for ($i = 0; $i < $h; $i++) {
10273 for ($j = 0; $j < $w; $j++) {
10274 $rgb = imagecolorat($im, $j, $i);
10275 $r = ($rgb >> 16) & 0xFF;
10276 $g = ($rgb >> 8) & 0xFF;
10277 $b = $rgb & 0xFF;
10278 if ($colspace=='Indexed') {
10279 $pal = imagecolorsforindex($im, $rgb);
10280 $r = $pal['red'];
10281 $g = $pal['green'];
10282 $b = $pal['blue'];
10283 }
10284
10285 if ($targetcs=='DeviceCMYK') {
10286 $col = $this->rgb2cmyk(array(3,$r,$g,$b));
10287 $c1 = intval($col[1]*2.55);
10288 $c2 = intval($col[2]*2.55);
10289 $c3 = intval($col[3]*2.55);
10290 $c4 = intval($col[4]*2.55);
10291 if ($trnsrgb) {
10292 // original pixel was not set as transparent but processed color does match
10293 if ($trnsrgb!=array($r,$g,$b) && $trns==array($c1,$c2,$c3,$c4)) {
10294 if ($c4==0) { $c4=1; } else { $c4--; }
10295 }
10296 }
10297 $imgdata .= chr($c1).chr($c2).chr($c3).chr($c4);
10298 }
10299 else if ($targetcs=='DeviceGray') {
10300 $c = intval(($r * .21) + ($g * .71) + ($b * .07));
10301 if ($trnsrgb) {
10302 // original pixel was not set as transparent but processed color does match
10303 if ($trnsrgb!=array($r,$g,$b) && $trns==array($c)) {
10304 if ($c==0) { $c=1; } else { $c--; }
10305 }
10306 }
10307 $imgdata .= chr($c);
10308 }
10309 else if ($targetcs=='DeviceRGB') {
10310 $imgdata .= chr($r).chr($g).chr($b);
10311 }
10312 if ($mask) {
10313 // mPDF 5.7.2 Gamma correction
10314 $alpha = ($rgb & 0x7F000000) >> 24;
10315 if ($alpha < 127) { $mimgdata .= chr(255-($alpha * 2)); }
10316 else { $mimgdata .= chr(0); }
10317 }
10318 }
10319 }
10320
10321 if ($targetcs=='DeviceGray') { $ncols = 1; }
10322 else if ($targetcs=='DeviceRGB') { $ncols = 3; }
10323 else if ($targetcs=='DeviceCMYK') { $ncols = 4; }
10324
10325 $imgdata = gzcompress($imgdata);
10326 $info = array('w'=>$w,'h'=>$h,'cs'=>$targetcs,'bpc'=>8,'f'=>'FlateDecode','data'=>$imgdata, 'type'=>'png',
10327 'parms'=>'/DecodeParms <</Colors '.$ncols.' /BitsPerComponent 8 /Columns '.$w.'>>');
10328 if ($dpi) { $info['set-dpi'] = $dpi; }
10329 if ($mask) {
10330 $mimgdata = gzcompress($mimgdata);
10331 $minfo = array('w'=>$w,'h'=>$h,'cs'=>'DeviceGray','bpc'=>8,'f'=>'FlateDecode','data'=>$mimgdata, 'type'=>'png',
10332 'parms'=>'/DecodeParms <</Colors '.$ncols.' /BitsPerComponent 8 /Columns '.$w.'>>');
10333 if ($dpi) { $minfo['set-dpi'] = $dpi; }
10334 $tempfile = '_tempImgPNG'.md5($file).RAND(1,10000).'.png';
10335 $imgmask = count($this->images)+1;
10336 $minfo['i']=$imgmask ;
10337 $this->images[$tempfile] = $minfo;
10338 $info['masked'] = $imgmask;
10339 }
10340 else if ($trns) { $info['trns'] = $trns; }
10341 imagedestroy($im);
10342 }
10343 return $info;
10344}
10345
10346
10347
10348
10349function _fourbytes2int($s) {
10350 //Read a 4-byte integer from string
10351 return (ord($s[0])<<24) + (ord($s[1])<<16) + (ord($s[2])<<8) + ord($s[3]);
10352}
10353
10354function _twobytes2int($s) {
10355 //Read a 2-byte integer from string
10356 return (ord(substr($s, 0, 1))<<8) + ord(substr($s, 1, 1));
10357}
10358
10359function _jpgHeaderFromString(&$data) {
10360 $p = 4;
10361 $p += $this->_twobytes2int(substr($data, $p, 2)); // Length of initial marker block
10362 $marker = substr($data, $p, 2);
10363 while($marker != chr(255).chr(192) && $marker != chr(255).chr(194) && $p<strlen($data)) {
10364 // Start of frame marker (FFC0) or (FFC2) mPDF 4.4.004
10365 $p += ($this->_twobytes2int(substr($data, $p+2, 2))) + 2; // Length of marker block
10366 $marker = substr($data, $p, 2);
10367 }
10368 if ($marker != chr(255).chr(192) && $marker != chr(255).chr(194)) { return false; }
10369 return substr($data, $p+2, 10);
10370}
10371
10372function _jpgDataFromHeader($hdr) {
10373 $bpc = ord(substr($hdr, 2, 1));
10374 if (!$bpc) { $bpc = 8; }
10375 $h = $this->_twobytes2int(substr($hdr, 3, 2));
10376 $w = $this->_twobytes2int(substr($hdr, 5, 2));
10377 $channels = ord(substr($hdr, 7, 1));
10378 if ($channels==3) { $colspace='DeviceRGB'; }
10379 elseif($channels==4) { $colspace='DeviceCMYK'; }
10380 else { $colspace='DeviceGray'; }
10381 return array($w, $h, $colspace, $bpc);
10382}
10383
10384function file_get_contents_by_curl($url, &$data) {
10385 $timeout = 5;
10386 $ch = curl_init($url);
10387 curl_setopt($ch, CURLOPT_HEADER, 0);
10388 curl_setopt($ch, CURLOPT_NOBODY, 0);
10389 curl_setopt ( $ch , CURLOPT_RETURNTRANSFER , 1 );
10390 curl_setopt ( $ch , CURLOPT_CONNECTTIMEOUT , $timeout );
10391 $data = curl_exec($ch);
10392 curl_close($ch);
10393}
10394
10395
10396function file_get_contents_by_socket($url, &$data) {
10397 $timeout = 1;
10398 $p = parse_url($url);
10399 $file = $p['path'];
10400 if ($p['query']) { $file .= '?'.$p['query']; }
10401 if(!($fh = @fsockopen($p['host'], 80, $errno, $errstr, $timeout))) { return false; }
10402 $getstring =
10403 "GET ".$file." HTTP/1.0 \r\n" .
10404 "Host: ".$p['host']." \r\n" .
10405 "Connection: close\r\n\r\n";
10406 fwrite($fh, $getstring);
10407 // Get rid of HTTP header
10408 $s = fgets($fh, 1024);
10409 if (!$s) { return false; }
10410 $httpheader .= $s;
10411 while (!feof($fh)) {
10412 $s = fgets($fh, 1024);
10413 if ( $s == "\r\n" ) { break; }
10414 }
10415 $data = '';
10416 while (!feof($fh)) {
10417 $data .= fgets($fh, 1024);
10418 }
10419 fclose($fh);
10420}
10421
10422//==============================================================
10423
10424function _imageTypeFromString(&$data) {
10425 $type = '';
10426 if (substr($data, 6, 4)== 'JFIF' || substr($data, 6, 4)== 'Exif' || substr($data, 0, 2)== chr(255).chr(216)) { // 0xFF 0xD8 // mpDF 5.7.2
10427 $type = 'jpeg';
10428 }
10429 else if (substr($data, 0, 6)== "GIF87a" || substr($data, 0, 6)== "GIF89a") {
10430 $type = 'gif';
10431 }
10432 else if (substr($data, 0, 8)== chr(137).'PNG'.chr(13).chr(10).chr(26).chr(10)) {
10433 $type = 'png';
10434 }
10435/*-- IMAGES-WMF --*/
10436 else if (substr($data, 0, 4)== chr(215).chr(205).chr(198).chr(154)) {
10437 $type = 'wmf';
10438 }
10439/*-- END IMAGES-WMF --*/
10440 else if (preg_match('/<svg.*<\/svg>/is',$data)) {
10441 $type = 'svg';
10442 }
10443 // BMP images
10444 else if (substr($data, 0, 2)== "BM") {
10445 $type = 'bmp';
10446 }
10447 return $type;
10448}
10449//==============================================================
10450
10451// Moved outside WMF as also needed for SVG
10452function _putformobjects() {
10453 reset($this->formobjects);
10454 while(list($file,$info)=each($this->formobjects)) {
10455 $this->_newobj();
10456 $this->formobjects[$file]['n']=$this->n;
10457 $this->_out('<</Type /XObject');
10458 $this->_out('/Subtype /Form');
10459 $this->_out('/Group '.($this->n+1).' 0 R');
10460 $this->_out('/BBox ['.$info['x'].' '.$info['y'].' '.($info['w']+$info['x']).' '.($info['h']+$info['y']).']');
10461 if ($this->compress)
10462 $this->_out('/Filter /FlateDecode');
10463 $data=($this->compress) ? gzcompress($info['data']) : $info['data'];
10464 $this->_out('/Length '.strlen($data).'>>');
10465 $this->_putstream($data);
10466 unset($this->formobjects[$file]['data']);
10467 $this->_out('endobj');
10468 // Required for SVG transparency (opacity) to work
10469 $this->_newobj();
10470 $this->_out('<</Type /Group');
10471 $this->_out('/S /Transparency');
10472 $this->_out('>>');
10473 $this->_out('endobj');
10474 }
10475}
10476
10477function _freadint($f)
10478{
10479 //Read a 4-byte integer from file
10480 $i=ord(fread($f,1))<<24;
10481 $i+=ord(fread($f,1))<<16;
10482 $i+=ord(fread($f,1))<<8;
10483 $i+=ord(fread($f,1));
10484 return $i;
10485}
10486
10487function _UTF16BEtextstring($s) {
10488 $s = $this->UTF8ToUTF16BE($s, true);
10489/*-- ENCRYPTION --*/
10490 if ($this->encrypted) {
10491 $s = $this->_RC4($this->_objectkey($this->_current_obj_id), $s);
10492 }
10493/*-- END ENCRYPTION --*/
10494 return '('. $this->_escape($s).')';
10495}
10496
10497function _textstring($s) {
10498/*-- ENCRYPTION --*/
10499 if ($this->encrypted) {
10500 $s = $this->_RC4($this->_objectkey($this->_current_obj_id), $s);
10501 }
10502/*-- END ENCRYPTION --*/
10503 return '('. $this->_escape($s).')';
10504}
10505
10506
10507function _escape($s)
10508{
10509 // the chr(13) substitution fixes the Bugs item #1421290.
10510 return strtr($s, array(')' => '\\)', '(' => '\\(', '\\' => '\\\\', chr(13) => '\r'));
10511}
10512
10513function _putstream($s) {
10514/*-- ENCRYPTION --*/
10515 if ($this->encrypted) {
10516 $s = $this->_RC4($this->_objectkey($this->_current_obj_id), $s);
10517 }
10518/*-- END ENCRYPTION --*/
10519 $this->_out('stream');
10520 $this->_out($s);
10521 $this->_out('endstream');
10522}
10523
10524
10525function _out($s,$ln=true) {
10526 if($this->state==2) {
10527 if ($this->bufferoutput) {
10528 $this->headerbuffer.= $s."\n";
10529 }
10530/*-- COLUMNS --*/
10531 else if (($this->ColActive) && !$this->processingHeader && !$this->processingFooter) {
10532 // Captures everything in buffer for columns; Almost everything is sent from fn. Cell() except:
10533 // Images sent from Image() or
10534 // later sent as _out($textto) in printbuffer
10535 // Line()
10536 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
10537 $h = ($m[1]/_MPDFK);
10538 // Update/overwrite the lowest bottom of printing y value for a column
10539 $this->ColDetails[$this->CurrCol]['bottom_margin'] = $this->y+$h;
10540 }
10541/*-- TABLES --*/
10542 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
10543 $h = ($m[1]/_MPDFK);
10544 // Update/overwrite the lowest bottom of printing y value for a column
10545 $this->ColDetails[$this->CurrCol]['bottom_margin'] = max($this->ColDetails[$this->CurrCol]['bottom_margin'],($this->y+$h));
10546 }
10547/*-- END TABLES --*/
10548 else { // Td Text Set in Cell()
10549 if (isset($this->ColDetails[$this->CurrCol]['bottom_margin'])) { $h = $this->ColDetails[$this->CurrCol]['bottom_margin'] - $this->y; }
10550 else { $h = 0; }
10551 }
10552 if ($h < 0) { $h = -$h; }
10553 $this->columnbuffer[] = array(
10554 's' => $s, // Text string to output
10555 'col' => $this->CurrCol, // Column when printed
10556 'x' => $this->x, // x when printed
10557 'y' => $this->y, // this->y when printed (after column break)
10558 'h' => $h // actual y at bottom when printed = y+h
10559 );
10560 }
10561/*-- END COLUMNS --*/
10562/*-- TABLES --*/
10563 else if ($this->table_rotate && !$this->processingHeader && !$this->processingFooter) {
10564 // Captures eveything in buffer for rotated tables;
10565 $this->tablebuffer .= $s . "\n";
10566 }
10567/*-- END TABLES --*/
10568 else if ($this->kwt && !$this->processingHeader && !$this->processingFooter) {
10569 // Captures eveything in buffer for keep-with-table (h1-6);
10570 $this->kwt_buffer[] = array(
10571 's' => $s, // Text string to output
10572 'x' => $this->x, // x when printed
10573 'y' => $this->y, // y when printed
10574 );
10575 }
10576 else if (($this->keep_block_together) && !$this->processingHeader && !$this->processingFooter) {
10577 if (!isset($this->ktBlock[$this->page]['bottom_margin'])) {
10578 $this->ktBlock[$this->page]['bottom_margin'] = $this->y;
10579 }
10580
10581 // Captures eveything in buffer;
10582 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
10583 $h = ($m[1]/_MPDFK);
10584 // Update/overwrite the lowest bottom of printing y value for Keep together block
10585 $this->ktBlock[$this->page]['bottom_margin'] = $this->y+$h;
10586 }
10587 else { // Td Text Set in Cell()
10588 if (isset($this->ktBlock[$this->page]['bottom_margin'])) { $h = $this->ktBlock[$this->page]['bottom_margin'] - $this->y; }
10589 else { $h = 0; }
10590 }
10591 if ($h < 0) { $h = -$h; }
10592 $this->divbuffer[] = array(
10593 'page' => $this->page,
10594 's' => $s, // Text string to output
10595 'x' => $this->x, // x when printed
10596 'y' => $this->y, // y when printed (after column break)
10597 'h' => $h // actual y at bottom when printed = y+h
10598 );
10599 }
10600 else {
10601 $this->pages[$this->page] .= $s.($ln == true ? "\n" : '');
10602 }
10603
10604 }
10605 else {
10606 $this->buffer .= $s.($ln == true ? "\n" : '');
10607 }
10608}
10609
10610/*-- WATERMARK --*/
10611// add a watermark
10612function watermark( $texte, $angle=45, $fontsize=96, $alpha=0.2 ) {
10613 if ($this->PDFA || $this->PDFX) { $this->Error('PDFA and PDFX do not permit transparency, so mPDF does not allow Watermarks!'); }
10614 if (!$this->watermark_font) { $this->watermark_font = $this->default_font; }
10615 $this->SetFont( $this->watermark_font, "B", $fontsize, false ); // Don't output
10616 $texte= $this->purify_utf8_text($texte);
10617 if ($this->text_input_as_HTML) {
10618 $texte= $this->all_entities_to_utf8($texte);
10619 }
10620 if ($this->usingCoreFont) { $texte = mb_convert_encoding($texte,$this->mb_enc,'UTF-8'); }
10621 // DIRECTIONALITY
10622 $this->magic_reverse_dir($texte, true, $this->directionality); // *RTL*
10623 // Font-specific ligature substitution for Indic fonts
10624 if (isset($this->CurrentFont['indic']) && $this->CurrentFont['indic']) $this->ConvertIndic($texte); // *INDIC*
10625
10626 $this->SetAlpha($alpha);
10627
10628 $this->SetTColor($this->ConvertColor(0));
10629 $szfont = $fontsize;
10630 $loop = 0;
10631 $maxlen = (min($this->w,$this->h) ); // sets max length of text as 7/8 width/height of page
10632 while ( $loop == 0 )
10633 {
10634 $this->SetFont( $this->watermark_font, "B", $szfont, false ); // Don't output
10635 $offset = ((sin(deg2rad($angle))) * ($szfont/_MPDFK));
10636
10637 $strlen = $this->GetStringWidth($texte);
10638 if ( $strlen > $maxlen - $offset )
10639 $szfont --;
10640 else
10641 $loop ++;
10642 }
10643
10644 $this->SetFont( $this->watermark_font, "B", $szfont-0.1, true, true); // Output The -0.1 is because SetFont above is not written to PDF
10645 // Repeating it will not output anything as mPDF thinks it is set
10646 $adj = ((cos(deg2rad($angle))) * ($strlen/2));
10647 $opp = ((sin(deg2rad($angle))) * ($strlen/2));
10648 $wx = ($this->w/2) - $adj + $offset/3;
10649 $wy = ($this->h/2) + $opp;
10650 $this->Rotate($angle,$wx,$wy);
10651 $this->Text($wx,$wy,$texte);
10652 $this->Rotate(0);
10653 $this->SetTColor($this->ConvertColor(0));
10654
10655 $this->SetAlpha(1);
10656
10657}
10658
10659function watermarkImg( $src, $alpha=0.2 ) {
10660 if ($this->PDFA || $this->PDFX) { $this->Error('PDFA and PDFX do not permit transparency, so mPDF does not allow Watermarks!'); }
10661 if ($this->watermarkImgBehind) { $this->watermarkImgAlpha = $this->SetAlpha($alpha, 'Normal', true); }
10662 else { $this->SetAlpha($alpha, $this->watermarkImgAlphaBlend); }
10663 $this->Image($src,0,0,0,0,'','', true, true, true);
10664 if (!$this->watermarkImgBehind) { $this->SetAlpha(1); }
10665}
10666/*-- END WATERMARK --*/
10667
10668
10669function Rotate($angle,$x=-1,$y=-1)
10670{
10671 if($x==-1)
10672 $x=$this->x;
10673 if($y==-1)
10674 $y=$this->y;
10675 if($this->angle!=0)
10676 $this->_out('Q');
10677 $this->angle=$angle;
10678 if($angle!=0)
10679 {
10680 $angle*=M_PI/180;
10681 $c=cos($angle);
10682 $s=sin($angle);
10683 $cx=$x*_MPDFK;
10684 $cy=($this->h-$y)*_MPDFK;
10685 $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));
10686 }
10687}
10688
10689
10690
10691function CircularText($x, $y, $r, $text, $align='top', $fontfamily='', $fontsize=0, $fontstyle='', $kerning=120, $fontwidth=100, $divider) { // mPDF 5.5.23
10692 if (!class_exists('directw', false)) { include(_MPDF_PATH.'classes/directw.php'); }
10693 if (empty($this->directw)) { $this->directw = new directw($this); }
10694 $this->directw->CircularText($x, $y, $r, $text, $align, $fontfamily, $fontsize, $fontstyle, $kerning, $fontwidth, $divider); // mPDF 5.5.23
10695}
10696
10697
10698// From Invoice
10699function RoundedRect($x, $y, $w, $h, $r, $style = '')
10700{
10701 $hp = $this->h;
10702 if($style=='F')
10703 $op='f';
10704 elseif($style=='FD' or $style=='DF')
10705 $op='B';
10706 else
10707 $op='S';
10708 $MyArc = 4/3 * (sqrt(2) - 1);
10709 $this->_out(sprintf('%.3F %.3F m',($x+$r)*_MPDFK,($hp-$y)*_MPDFK ));
10710 $xc = $x+$w-$r ;
10711 $yc = $y+$r;
10712 $this->_out(sprintf('%.3F %.3F l', $xc*_MPDFK,($hp-$y)*_MPDFK ));
10713
10714 $this->_Arc($xc + $r*$MyArc, $yc - $r, $xc + $r, $yc - $r*$MyArc, $xc + $r, $yc);
10715 $xc = $x+$w-$r ;
10716 $yc = $y+$h-$r;
10717 $this->_out(sprintf('%.3F %.3F l',($x+$w)*_MPDFK,($hp-$yc)*_MPDFK));
10718 $this->_Arc($xc + $r, $yc + $r*$MyArc, $xc + $r*$MyArc, $yc + $r, $xc, $yc + $r);
10719 $xc = $x+$r ;
10720 $yc = $y+$h-$r;
10721 $this->_out(sprintf('%.3F %.3F l',$xc*_MPDFK,($hp-($y+$h))*_MPDFK));
10722 $this->_Arc($xc - $r*$MyArc, $yc + $r, $xc - $r, $yc + $r*$MyArc, $xc - $r, $yc);
10723 $xc = $x+$r ;
10724 $yc = $y+$r;
10725 $this->_out(sprintf('%.3F %.3F l',($x)*_MPDFK,($hp-$yc)*_MPDFK ));
10726 $this->_Arc($xc - $r, $yc - $r*$MyArc, $xc - $r*$MyArc, $yc - $r, $xc, $yc - $r);
10727 $this->_out($op);
10728}
10729
10730function _Arc($x1, $y1, $x2, $y2, $x3, $y3)
10731{
10732 $h = $this->h;
10733 $this->_out(sprintf('%.3F %.3F %.3F %.3F %.3F %.3F c ', $x1*_MPDFK, ($h-$y1)*_MPDFK,
10734 $x2*_MPDFK, ($h-$y2)*_MPDFK, $x3*_MPDFK, ($h-$y3)*_MPDFK));
10735}
10736
10737
10738
10739
10740//====================================================
10741
10742
10743
10744/*-- DIRECTW --*/
10745function Shaded_box( $text,$font='',$fontstyle='B',$szfont='',$width='70%',$style='DF',$radius=2.5,$fill='#FFFFFF',$color='#000000',$pad=2 ) {
10746 // F (shading - no line),S (line, no shading),DF (both)
10747 if (!class_exists('directw', false)) { include(_MPDF_PATH.'classes/directw.php'); }
10748 if (empty($this->directw)) { $this->directw = new directw($this); }
10749 $this->directw->Shaded_box( $text,$font,$fontstyle,$szfont,$width,$style,$radius,$fill,$color,$pad);
10750}
10751/*-- END DIRECTW --*/
10752
10753
10754function UTF8StringToArray($str, $addSubset=true) {
10755 $out = array();
10756 $len = strlen($str);
10757 for ($i = 0; $i < $len; $i++) {
10758 $uni = -1;
10759 $h = ord($str[$i]);
10760 if ( $h <= 0x7F )
10761 $uni = $h;
10762 elseif ( $h >= 0xC2 ) {
10763 if ( ($h <= 0xDF) && ($i < $len -1) )
10764 $uni = ($h & 0x1F) << 6 | (ord($str[++$i]) & 0x3F);
10765 elseif ( ($h <= 0xEF) && ($i < $len -2) )
10766 $uni = ($h & 0x0F) << 12 | (ord($str[++$i]) & 0x3F) << 6 | (ord($str[++$i]) & 0x3F);
10767 elseif ( ($h <= 0xF4) && ($i < $len -3) )
10768 $uni = ($h & 0x0F) << 18 | (ord($str[++$i]) & 0x3F) << 12 | (ord($str[++$i]) & 0x3F) << 6 | (ord($str[++$i]) & 0x3F);
10769 }
10770 if ($uni >= 0) {
10771 $out[] = $uni;
10772 if ($addSubset && isset($this->CurrentFont['subset'])) {
10773 $this->CurrentFont['subset'][$uni] = $uni;
10774 }
10775 }
10776 }
10777 return $out;
10778}
10779
10780
10781//Convert utf-8 string to <HHHHHH> for Font Subsets
10782function UTF8toSubset($str) {
10783 $ret = '<';
10784 $str = preg_replace('/'.preg_quote($this->aliasNbPg,'/').'/', chr(7), $str );
10785 $str = preg_replace('/'.preg_quote($this->aliasNbPgGp,'/').'/', chr(8), $str );
10786 $unicode = $this->UTF8StringToArray($str);
10787 $orig_fid = $this->CurrentFont['subsetfontids'][0];
10788 $last_fid = $this->CurrentFont['subsetfontids'][0];
10789 foreach($unicode as $c) {
10790 if ($c == 7 || $c == 8) {
10791 if ($orig_fid != $last_fid) {
10792 $ret .= '> Tj /F'.$orig_fid.' '.$this->FontSizePt.' Tf <';
10793 $last_fid = $orig_fid;
10794 }
10795 if ($c == 7) { $ret .= $this->aliasNbPgHex; }
10796 else { $ret .= $this->aliasNbPgGpHex; }
10797 continue;
10798 }
10799 for ($i=0; $i<99; $i++) {
10800 // return c as decimal char
10801 $init = array_search($c, $this->CurrentFont['subsets'][$i]);
10802 if ($init!==false) {
10803 if ($this->CurrentFont['subsetfontids'][$i] != $last_fid) {
10804 $ret .= '> Tj /F'.$this->CurrentFont['subsetfontids'][$i].' '.$this->FontSizePt.' Tf <';
10805 $last_fid = $this->CurrentFont['subsetfontids'][$i];
10806 }
10807 $ret .= sprintf("%02s", strtoupper(dechex($init)));
10808 break;
10809 }
10810 // TrueType embedded SUBSETS
10811 else if (count($this->CurrentFont['subsets'][$i]) < 255) {
10812 $n = count($this->CurrentFont['subsets'][$i]);
10813 $this->CurrentFont['subsets'][$i][$n] = $c;
10814 if ($this->CurrentFont['subsetfontids'][$i] != $last_fid) {
10815 $ret .= '> Tj /F'.$this->CurrentFont['subsetfontids'][$i].' '.$this->FontSizePt.' Tf <';
10816 $last_fid = $this->CurrentFont['subsetfontids'][$i];
10817 }
10818 $ret .= sprintf("%02s", strtoupper(dechex($n)));
10819 break;
10820 }
10821 else if (!isset($this->CurrentFont['subsets'][($i+1)])) {
10822 // TrueType embedded SUBSETS
10823 $this->CurrentFont['subsets'][($i+1)] = array(0=>0);
10824 $new_fid = count($this->fonts)+$this->extraFontSubsets+1;
10825 $this->CurrentFont['subsetfontids'][($i+1)] = $new_fid;
10826 $this->extraFontSubsets++;
10827 }
10828 }
10829 }
10830 $ret .= '>';
10831 if ($last_fid != $orig_fid) {
10832 $ret .= ' Tj /F'.$orig_fid.' '.$this->FontSizePt.' Tf <> ';
10833 }
10834 return $ret;
10835}
10836
10837
10838// Converts UTF-8 strings to UTF16-BE.
10839function UTF8ToUTF16BE($str, $setbom=true) {
10840 if ($this->checkSIP && preg_match("/([\x{20000}-\x{2FFFF}])/u", $str)) {
10841 if (!in_array($this->currentfontfamily, array('gb','big5','sjis','uhc','gbB','big5B','sjisB','uhcB','gbI','big5I','sjisI','uhcI',
10842 'gbBI','big5BI','sjisBI','uhcBI'))) {
10843 $str = preg_replace("/[\x{20000}-\x{2FFFF}]/u", chr(0), $str);
10844 }
10845 }
10846 if ($this->checkSMP && preg_match("/([\x{10000}-\x{1FFFF}])/u", $str )) {
10847 $str = preg_replace("/[\x{10000}-\x{1FFFF}]/u", chr(0), $str );
10848 }
10849 $outstr = ""; // string to be returned
10850 if ($setbom) {
10851 $outstr .= "\xFE\xFF"; // Byte Order Mark (BOM)
10852 }
10853 $outstr .= mb_convert_encoding($str, 'UTF-16BE', 'UTF-8');
10854 return $outstr;
10855}
10856
10857
10858
10859
10860
10861// ====================================================
10862// ====================================================
10863/*-- CJK-FONTS --*/
10864
10865// from class PDF_Chinese CJK EXTENSIONS
10866function AddCIDFont($family,$style,$name,&$cw,$CMap,$registry,$desc)
10867{
10868 $fontkey=strtolower($family).strtoupper($style);
10869 if(isset($this->fonts[$fontkey]))
10870 $this->Error("Font already added: $family $style");
10871 $i=count($this->fonts)+$this->extraFontSubsets+1;
10872 $name=str_replace(' ','',$name);
10873 if ($family == 'sjis') { $up = -120; } else { $up = -130; }
10874 // ? 'up' and 'ut' do not seem to be referenced anywhere
10875 $this->fonts[$fontkey]=array('i'=>$i,'type'=>'Type0','name'=>$name,'up'=>$up,'ut'=>40,'cw'=>$cw,'CMap'=>$CMap,'registry'=>$registry,'MissingWidth'=>1000,'desc'=>$desc);
10876}
10877
10878function AddCJKFont($family) {
10879
10880 if ($this->PDFA || $this->PDFX) {
10881 $this->Error("Adobe CJK fonts cannot be embedded in mPDF (required for PDFA1-b and PDFX/1-a).");
10882 }
10883 if ($family == 'big5') { $this->AddBig5Font(); }
10884 else if ($family == 'gb') { $this->AddGBFont(); }
10885 else if ($family == 'sjis') { $this->AddSJISFont(); }
10886 else if ($family == 'uhc') { $this->AddUHCFont(); }
10887}
10888
10889function AddBig5Font()
10890{
10891 //Add Big5 font with proportional Latin
10892 $family='big5';
10893 $name='MSungStd-Light-Acro';
10894 $cw=$this->Big5_widths;
10895 $CMap='UniCNS-UTF16-H';
10896 $registry=array('ordering'=>'CNS1','supplement'=>4);
10897 $desc = array(
10898 'Ascent' => 880,
10899 'Descent' => -120,
10900 'CapHeight' => 880,
10901 'Flags' => 6,
10902 'FontBBox' => '[-160 -249 1015 1071]',
10903 'ItalicAngle' => 0,
10904 'StemV' => 93,
10905 );
10906 $this->AddCIDFont($family,'',$name,$cw,$CMap,$registry,$desc);
10907 $this->AddCIDFont($family,'B',$name.',Bold',$cw,$CMap,$registry,$desc);
10908 $this->AddCIDFont($family,'I',$name.',Italic',$cw,$CMap,$registry,$desc);
10909 $this->AddCIDFont($family,'BI',$name.',BoldItalic',$cw,$CMap,$registry,$desc);
10910}
10911
10912
10913function AddGBFont()
10914{
10915 //Add GB font with proportional Latin
10916 $family='gb';
10917 $name='STSongStd-Light-Acro';
10918 $cw=$this->GB_widths;
10919 $CMap='UniGB-UTF16-H';
10920 $registry=array('ordering'=>'GB1','supplement'=>4);
10921 $desc = array(
10922 'Ascent' => 752,
10923 'Descent' => -271,
10924 'CapHeight' => 737,
10925 'Flags' => 6,
10926 'FontBBox' => '[-25 -254 1000 880]',
10927 'ItalicAngle' => 0,
10928 'StemV' => 58,
10929 'Style' => '<< /Panose <000000000400000000000000> >>',
10930 );
10931 $this->AddCIDFont($family,'',$name,$cw,$CMap,$registry,$desc);
10932 $this->AddCIDFont($family,'B',$name.',Bold',$cw,$CMap,$registry,$desc);
10933 $this->AddCIDFont($family,'I',$name.',Italic',$cw,$CMap,$registry,$desc);
10934 $this->AddCIDFont($family,'BI',$name.',BoldItalic',$cw,$CMap,$registry,$desc);
10935}
10936
10937
10938function AddSJISFont()
10939{
10940 //Add SJIS font with proportional Latin
10941 $family='sjis';
10942 $name='KozMinPro-Regular-Acro';
10943 $cw=$this->SJIS_widths;
10944 $CMap='UniJIS-UTF16-H';
10945 $registry=array('ordering'=>'Japan1','supplement'=>5);
10946 $desc = array(
10947 'Ascent' => 880,
10948 'Descent' => -120,
10949 'CapHeight' => 740,
10950 'Flags' => 6,
10951 'FontBBox' => '[-195 -272 1110 1075]',
10952 'ItalicAngle' => 0,
10953 'StemV' => 86,
10954 'XHeight' => 502,
10955 );
10956 $this->AddCIDFont($family,'',$name,$cw,$CMap,$registry,$desc);
10957 $this->AddCIDFont($family,'B',$name.',Bold',$cw,$CMap,$registry,$desc);
10958 $this->AddCIDFont($family,'I',$name.',Italic',$cw,$CMap,$registry,$desc);
10959 $this->AddCIDFont($family,'BI',$name.',BoldItalic',$cw,$CMap,$registry,$desc);
10960}
10961
10962function AddUHCFont()
10963{
10964 //Add UHC font with proportional Latin
10965 $family='uhc';
10966 $name='HYSMyeongJoStd-Medium-Acro';
10967 $cw=$this->UHC_widths;
10968 $CMap='UniKS-UTF16-H';
10969 $registry=array('ordering'=>'Korea1','supplement'=>2);
10970 $desc = array(
10971 'Ascent' => 880,
10972 'Descent' => -120,
10973 'CapHeight' => 720,
10974 'Flags' => 6,
10975 'FontBBox' => '[-28 -148 1001 880]',
10976 'ItalicAngle' => 0,
10977 'StemV' => 60,
10978 'Style' => '<< /Panose <000000000600000000000000> >>',
10979 );
10980 $this->AddCIDFont($family,'',$name,$cw,$CMap,$registry,$desc);
10981 $this->AddCIDFont($family,'B',$name.',Bold',$cw,$CMap,$registry,$desc);
10982 $this->AddCIDFont($family,'I',$name.',Italic',$cw,$CMap,$registry,$desc);
10983 $this->AddCIDFont($family,'BI',$name.',BoldItalic',$cw,$CMap,$registry,$desc);
10984}
10985
10986/*-- END CJK-FONTS --*/
10987
10988//////////////////////////////////////////////////////////////////////////////
10989//////////////////////////////////////////////////////////////////////////////
10990//////////////////////////////////////////////////////////////////////////////
10991//////////////////////////////////////////////////////////////////////////////
10992//////////////////////////////////////////////////////////////////////////////
10993//////////////////////////////////////////////////////////////////////////////
10994//////////////////////////////////////////////////////////////////////////////
10995function SetAutoFont($af = AUTOFONT_ALL) {
10996 if ($this->onlyCoreFonts) { return false; }
10997 if (!$af && $af !== 0) { $af = AUTOFONT_ALL; }
10998 $this->autoFontGroups = $af;
10999 if ($this->autoFontGroups ) {
11000 $this->useLang = true;
11001 }
11002}
11003
11004
11005function SetDefaultFont($font) {
11006 // Disallow embedded fonts to be used as defaults in PDFA
11007 if ($this->PDFA || $this->PDFX) {
11008 if (strtolower($font) == 'ctimes') { $font = 'serif'; }
11009 if (strtolower($font) == 'ccourier') { $font = 'monospace'; }
11010 if (strtolower($font) == 'chelvetica') { $font = 'sans-serif'; }
11011 }
11012 $font = $this->SetFont($font); // returns substituted font if necessary
11013 $this->default_font = $font;
11014 $this->original_default_font = $font;
11015 if (!$this->watermark_font ) { $this->watermark_font = $font; } // *WATERMARK*
11016 $this->defaultCSS['BODY']['FONT-FAMILY'] = $font;
11017 $this->cssmgr->CSS['BODY']['FONT-FAMILY'] = $font;
11018}
11019
11020function SetDefaultFontSize($fontsize) {
11021 $this->default_font_size = $fontsize;
11022 $this->original_default_font_size = $fontsize;
11023 $this->SetFontSize($fontsize);
11024 $this->defaultCSS['BODY']['FONT-SIZE'] = $fontsize . 'pt';
11025 $this->cssmgr->CSS['BODY']['FONT-SIZE'] = $fontsize . 'pt';
11026}
11027
11028function SetDefaultBodyCSS($prop, $val) {
11029 if ($prop) {
11030 $this->defaultCSS['BODY'][strtoupper($prop)] = $val;
11031 $this->cssmgr->CSS['BODY'][strtoupper($prop)] = $val;
11032 }
11033}
11034
11035
11036function SetDirectionality($dir='ltr') {
11037/*-- RTL --*/
11038 if (strtolower($dir) == 'rtl') {
11039 if ($this->directionality != 'rtl') {
11040 // Swop L/R Margins so page 1 RTL is an 'even' page
11041 $tmp = $this->DeflMargin;
11042 $this->DeflMargin = $this->DefrMargin;
11043 $this->DefrMargin = $tmp;
11044 $this->orig_lMargin = $this->DeflMargin;
11045 $this->orig_rMargin = $this->DefrMargin;
11046
11047 $this->SetMargins($this->DeflMargin,$this->DefrMargin,$this->tMargin);
11048 }
11049 $this->directionality = 'rtl';
11050 $this->defaultAlign = 'R';
11051 $this->defaultTableAlign = 'R';
11052 }
11053 else {
11054/*-- END RTL --*/
11055 $this->directionality = 'ltr';
11056 $this->defaultAlign = 'L';
11057 $this->defaultTableAlign = 'L';
11058 } // *RTL*
11059 $this->cssmgr->CSS['BODY']['DIRECTION'] = $this->directionality;
11060}
11061
11062
11063
11064// Added to set line-height-correction
11065function SetLineHeightCorrection($val) {
11066 if ($val > 0) { $this->default_lineheight_correction = $val; }
11067 else { $this->default_lineheight_correction = 1.2; }
11068}
11069
11070// Set a (fixed) lineheight to an actual value - either to named fontsize(pts) or default
11071function SetLineHeight($FontPt='',$spacing = '') {
11072 if ($this->shrin_k > 1) { $k = $this->shrin_k; }
11073 else { $k = 1; }
11074 if ($spacing > 0) {
11075 if (preg_match('/mm/',$spacing)) {
11076 $this->lineheight = ($spacing + 0.0) / $k; // convert to number
11077 }
11078 else {
11079 if ($FontPt) { $this->lineheight = (($FontPt/_MPDFK) *$spacing); }
11080 else { $this->lineheight = (($this->FontSizePt/_MPDFK) *$spacing); }
11081 }
11082 }
11083 else {
11084 if ($FontPt) { $this->lineheight = (($FontPt/_MPDFK) *$this->normalLineheight); }
11085 else { $this->lineheight = (($this->FontSizePt/_MPDFK) *$this->normalLineheight); }
11086 }
11087}
11088
11089function _computeLineheight($lh, $fs='') {
11090 if ($this->shrin_k > 1) { $k = $this->shrin_k; }
11091 else { $k = 1; }
11092 if (!$fs) { $fs = $this->FontSize; }
11093 if (preg_match('/mm/',$lh)) {
11094 return (($lh + 0.0) / $k); // convert to number
11095 }
11096 else if ($lh > 0) {
11097 return ($fs * $lh);
11098 }
11099 else if (isset($this->normalLineheight)) { return ($fs * $this->normalLineheight); }
11100 else return ($fs * $this->default_lineheight_correction);
11101}
11102
11103
11104function SetBasePath($str='') {
11105 if ( isset($_SERVER['HTTP_HOST']) ) { $host = $_SERVER['HTTP_HOST']; }
11106 else if ( isset($_SERVER['SERVER_NAME']) ) { $host = $_SERVER['SERVER_NAME']; }
11107 else { $host = ''; }
11108 if (!$str) {
11109 if ($_SERVER['SCRIPT_NAME']) { $currentPath = dirname($_SERVER['SCRIPT_NAME']); }
11110 else { $currentPath = dirname($_SERVER['PHP_SELF']); }
11111 $currentPath = str_replace("\\","/",$currentPath);
11112 if ($currentPath == '/') { $currentPath = ''; }
11113 if ($host) { $currpath = 'http://' . $host . $currentPath .'/'; }
11114 else { $currpath = ''; }
11115 $this->basepath = $currpath;
11116 $this->basepathIsLocal = true;
11117 return;
11118 }
11119 $str = preg_replace('/\?.*/','',$str);
11120 if (!preg_match('/(http|https|ftp):\/\/.*\//i',$str)) { $str .= '/'; }
11121 $str .= 'xxx'; // in case $str ends in / e.g. http://www.bbc.co.uk/
11122 $this->basepath = dirname($str) . "/"; // returns e.g. e.g. http://www.google.com/dir1/dir2/dir3/
11123 $this->basepath = str_replace("\\","/",$this->basepath); //If on Windows
11124 $tr = parse_url($this->basepath);
11125 if (isset($tr['host']) && ($tr['host'] == $host)) { $this->basepathIsLocal = true; }
11126 else { $this->basepathIsLocal = false; }
11127}
11128
11129
11130function GetFullPath(&$path,$basepath='') {
11131 // When parsing CSS need to pass temporary basepath - so links are relative to current stylesheet
11132 if (!$basepath) { $basepath = $this->basepath; }
11133 //Fix path value
11134 $path = str_replace("\\","/",$path); //If on Windows
11135 // mPDF 5.7.2
11136 if (substr($path,0,2) == "//") {
11137 $tr = parse_url($basepath);
11138 $path = $tr['scheme'].':'.$path;
11139 }
11140 $regexp = '|^./|'; // Inadvertently corrects "./path/etc" and "//www.domain.com/etc"
11141 $path = preg_replace($regexp,'',$path);
11142
11143
11144 if(substr($path,0,1) == '#') { return; }
11145 if (stristr($path,"mailto:") !== false) { return; }
11146 if (strpos($path,"../") !== false ) { //It is a Relative Link
11147 $backtrackamount = substr_count($path,"../");
11148 $maxbacktrack = substr_count($basepath,"/") - 3; // mPDF 5.6.18
11149 $filepath = str_replace("../",'',$path);
11150 $path = $basepath;
11151 //If it is an invalid relative link, then make it go to directory root
11152 if ($backtrackamount > $maxbacktrack) $backtrackamount = $maxbacktrack;
11153 //Backtrack some directories
11154 for( $i = 0 ; $i < $backtrackamount + 1 ; $i++ ) $path = substr( $path, 0 , strrpos($path,"/") );
11155 $path = $path . "/" . $filepath; //Make it an absolute path
11156 }
11157 else if( strpos($path,":/") === false || strpos($path,":/") > 10) { //It is a Local Link
11158 if (substr($path,0,1) == "/") {
11159 $tr = parse_url($basepath);
11160 // mPDF 5.7.2
11161 $root = '';
11162 if (!empty($tr['scheme'])) { $root .= $tr['scheme'].'://'; }
11163 $root .= $tr['host'];
11164 $path = $root . $path;
11165 }
11166 else { $path = $basepath . $path; }
11167 }
11168 //Do nothing if it is an Absolute Link
11169}
11170
11171
11172// Used for external CSS files
11173function _get_file($path) {
11174 // If local file try using local path (? quicker, but also allowed even if allow_url_fopen false)
11175 $contents = '';
11176 $contents = @file_get_contents($path);
11177 if ($contents) { return $contents; }
11178 if ($this->basepathIsLocal) {
11179 $tr = parse_url($path);
11180 $lp=getenv("SCRIPT_NAME");
11181 $ap=realpath($lp);
11182 $ap=str_replace("\\","/",$ap);
11183 $docroot=substr($ap,0,strpos($ap,$lp));
11184 // WriteHTML parses all paths to full URLs; may be local file name
11185 if ($tr['scheme'] && $tr['host'] && $_SERVER["DOCUMENT_ROOT"] ) {
11186 $localpath = $_SERVER["DOCUMENT_ROOT"] . $tr['path'];
11187 }
11188 // DOCUMENT_ROOT is not returned on IIS
11189 else if ($docroot) {
11190 $localpath = $docroot . $tr['path'];
11191 }
11192 else { $localpath = $path; }
11193 $contents = @file_get_contents($localpath);
11194 }
11195 // if not use full URL
11196 else if (!$contents && !ini_get('allow_url_fopen') && function_exists("curl_init")) {
11197 $ch = curl_init($path);
11198 curl_setopt($ch, CURLOPT_HEADER, 0);
11199 curl_setopt ( $ch , CURLOPT_RETURNTRANSFER , 1 );
11200 $contents = curl_exec($ch);
11201 curl_close($ch);
11202 }
11203 return $contents;
11204}
11205
11206
11207function docPageNum($num = 0, $extras = false) {
11208 if ($num < 1) { $num = $this->page; }
11209 $type = '1'; // set default decimal
11210 $ppgno = $num;
11211 $suppress = 0;
11212 $offset = 0;
11213 $lastreset = 0;
11214 foreach($this->PageNumSubstitutions AS $psarr) {
11215 if ($num >= $psarr['from']) {
11216 if ($psarr['reset']) {
11217 if ($psarr['reset']>1) { $offset = $psarr['reset']-1; }
11218 $ppgno = $num - $psarr['from'] + 1 + $offset;
11219 $lastreset = $psarr['from'];
11220 }
11221 if ($psarr['type']) { $type = $psarr['type']; }
11222 if (strtoupper($psarr['suppress'])=='ON' || $psarr['suppress']==1) { $suppress = 1; }
11223 else if (strtoupper($psarr['suppress'])=='OFF') { $suppress = 0; }
11224 }
11225 }
11226 if ($suppress) { return ''; }
11227
11228 foreach($this->pgsIns AS $k=>$v) {
11229 if ($k>$lastreset && $k<$num) {
11230 $ppgno -= $v;
11231 }
11232 }
11233 if ($type=='A') { $ppgno = $this->dec2alpha($ppgno,true); }
11234 else if ($type=='a') { $ppgno = $this->dec2alpha($ppgno,false);}
11235 else if ($type=='I') { $ppgno = $this->dec2roman($ppgno,true); }
11236 else if ($type=='i') { $ppgno = $this->dec2roman($ppgno,false); }
11237 if ($extras) { $ppgno = $this->pagenumPrefix . $ppgno . $this->pagenumSuffix; }
11238 return $ppgno;
11239}
11240
11241
11242function docPageSettings($num = 0) {
11243 // Returns current type (numberstyle), suppression state for this page number;
11244 // reset is only returned if set for this page number
11245 if ($num < 1) { $num = $this->page; }
11246 $type = '1'; // set default decimal
11247 $ppgno = $num;
11248 $suppress = 0;
11249 $offset = 0;
11250 $reset = '';
11251 foreach($this->PageNumSubstitutions AS $psarr) {
11252 if ($num >= $psarr['from']) {
11253 if ($psarr['reset']) {
11254 if ($psarr['reset']>1) { $offset = $psarr['reset']-1; }
11255 $ppgno = $num - $psarr['from'] + 1 + $offset;
11256 }
11257 if ($psarr['type']) { $type = $psarr['type']; }
11258 if (strtoupper($psarr['suppress'])=='ON' || $psarr['suppress']==1) { $suppress = 1; }
11259 else if (strtoupper($psarr['suppress'])=='OFF') { $suppress = 0; }
11260 }
11261 if ($num == $psarr['from']) { $reset = $psarr['reset']; }
11262 }
11263 if ($suppress) { $suppress = 'on'; }
11264 else { $suppress = 'off'; }
11265 return array($type, $suppress, $reset);
11266}
11267
11268function docPageNumTotal($num = 0, $extras = false) {
11269 if ($num < 1) { $num = $this->page; }
11270 $type = '1'; // set default decimal
11271 $ppgstart = 1;
11272 $ppgend = count($this->pages)+1;
11273 $suppress = 0;
11274 $offset = 0;
11275 foreach($this->PageNumSubstitutions AS $psarr) {
11276 if ($num >= $psarr['from']) {
11277 if ($psarr['reset']) {
11278 if ($psarr['reset']>1) { $offset = $psarr['reset']-1; }
11279 $ppgstart = $psarr['from'] + $offset;
11280 $ppgend = count($this->pages)+1 + $offset;
11281 }
11282 if ($psarr['type']) { $type = $psarr['type']; }
11283 if (strtoupper($psarr['suppress'])=='ON' || $psarr['suppress']==1) { $suppress = 1; }
11284 else if (strtoupper($psarr['suppress'])=='OFF') { $suppress = 0; }
11285 }
11286 if ($num < $psarr['from']) {
11287 if ($psarr['reset']) {
11288 $ppgend = $psarr['from'] + $offset;
11289 break;
11290 }
11291 }
11292 }
11293 if ($suppress) { return ''; }
11294 $ppgno = $ppgend-$ppgstart+$offset;
11295
11296 // mPDF 5.6.47
11297 foreach($this->pgsIns AS $k => $v) {
11298 if ($k>$ppgstart && $k<$ppgend) {
11299 $ppgno -= $v;
11300 }
11301 }
11302
11303 if ($extras) { $ppgno = $this->nbpgPrefix . $ppgno . $this->nbpgSuffix; }
11304 return $ppgno;
11305}
11306
11307function RestartDocTemplate() {
11308 $this->docTemplateStart = $this->page;
11309}
11310
11311
11312
11313//Page header
11314function Header($content='') {
11315
11316 $this->cMarginL = 0;
11317 $this->cMarginR = 0;
11318
11319
11320/*-- HTMLHEADERS-FOOTERS --*/
11321 if (($this->mirrorMargins && ($this->page%2==0) && $this->HTMLHeaderE) || ($this->mirrorMargins && ($this->page%2==1) && $this->HTMLHeader) || (!$this->mirrorMargins && $this->HTMLHeader)) {
11322 $this->writeHTMLHeaders();
11323 return;
11324 }
11325/*-- END HTMLHEADERS-FOOTERS --*/
11326 $this->processingHeader=true;
11327 $h = $this->headerDetails;
11328 if(count($h)) {
11329
11330 if ($this->forcePortraitHeaders && $this->CurOrientation=='L' && $this->CurOrientation!=$this->DefOrientation) {
11331 $this->_out(sprintf('q 0 -1 1 0 0 %.3F cm ',($this->h*_MPDFK)));
11332 $yadj = $this->w - $this->h;
11333 $headerpgwidth = $this->h - $this->orig_lMargin - $this->orig_rMargin;
11334 if (($this->mirrorMargins) && (($this->page)%2==0)) { // EVEN
11335 $headerlmargin = $this->orig_rMargin;
11336 }
11337 else {
11338 $headerlmargin = $this->orig_lMargin;
11339 }
11340 }
11341 else {
11342 $yadj = 0;
11343 $headerpgwidth = $this->pgwidth;
11344 $headerlmargin = $this->lMargin;
11345 }
11346
11347 $this->y = $this->margin_header - $yadj ;
11348 $this->SetTColor($this->ConvertColor(0));
11349 $this->SUP = false;
11350 $this->SUB = false;
11351 $this->bullet = false;
11352
11353 // only show pagenumber if numbering on
11354 $pgno = $this->docPageNum($this->page, true);
11355
11356 if (($this->mirrorMargins) && (($this->page)%2==0)) { // EVEN
11357 $side = 'even';
11358 }
11359 else { // ODD // OR NOT MIRRORING MARGINS/FOOTERS = DEFAULT
11360 $side = 'odd';
11361 }
11362 $maxfontheight = 0;
11363 foreach(array('L','C','R') AS $pos) {
11364 if (isset($h[$side][$pos]['content']) && $h[$side][$pos]['content']) {
11365 if (isset($h[$side][$pos]['font-size']) && $h[$side][$pos]['font-size']) { $hfsz = $h[$side][$pos]['font-size']; }
11366 else { $hfsz = $this->default_font_size; }
11367 $maxfontheight = max($maxfontheight,$hfsz);
11368 }
11369 }
11370 // LEFT-CENTER-RIGHT
11371 foreach(array('L','C','R') AS $pos) {
11372 if (isset($h[$side][$pos]['content']) && $h[$side][$pos]['content']) {
11373 $hd = str_replace('{PAGENO}',$pgno,$h[$side][$pos]['content']);
11374 $hd = str_replace($this->aliasNbPgGp,$this->nbpgPrefix.$this->aliasNbPgGp.$this->nbpgSuffix,$hd);
11375 $hd = preg_replace_callback('/\{DATE\s+(.*?)\}/', array($this, 'date_callback') ,$hd); // mPDF 5.7
11376 if (isset($h[$side][$pos]['font-family']) && $h[$side][$pos]['font-family']) { $hff = $h[$side][$pos]['font-family']; }
11377 else { $hff = $this->original_default_font; }
11378 if (isset($h[$side][$pos]['font-size']) && $h[$side][$pos]['font-size']) { $hfsz = $h[$side][$pos]['font-size']; }
11379 else { $hfsz = $this->original_default_font_size; } // pts
11380 $maxfontheight = max($maxfontheight,$hfsz);
11381 $hfst = '';
11382 if (isset($h[$side][$pos]['font-style']) && $h[$side][$pos]['font-style']) {
11383 $hfst = $h[$side][$pos]['font-style'];
11384 }
11385 if (isset($h[$side][$pos]['color']) && $h[$side][$pos]['color']) {
11386 $hfcol = $h[$side][$pos]['color'];
11387 $cor = $this->ConvertColor($hfcol);
11388 if ($cor) { $this->SetTColor($cor); }
11389 }
11390 else { $hfcol = ''; }
11391 $this->SetFont($hff,$hfst,$hfsz,true,true);
11392 $this->x = $headerlmargin ;
11393 $this->y = $this->margin_header - $yadj ;
11394
11395 $hd = $this->purify_utf8_text($hd);
11396 if ($this->text_input_as_HTML) {
11397 $hd = $this->all_entities_to_utf8($hd);
11398 }
11399 // CONVERT CODEPAGE
11400 if ($this->usingCoreFont) { $hd = mb_convert_encoding($hd,$this->mb_enc,'UTF-8'); }
11401 // DIRECTIONALITY RTL
11402 $this->magic_reverse_dir($hd, true, $this->directionality); // *RTL*
11403 // Font-specific ligature substitution for Indic fonts
11404 if (isset($this->CurrentFont['indic']) && $this->CurrentFont['indic']) $this->ConvertIndic($hd); // *INDIC*
11405 $align = $pos;
11406/*-- RTL --*/
11407 if ($this->directionality == 'rtl') {
11408 if ($pos == 'L') { $align = 'R'; }
11409 else if ($pos == 'R') { $align = 'L'; }
11410 }
11411/*-- END RTL --*/
11412 if ($pos!='L' && (strpos($hd,$this->aliasNbPg)!==false || strpos($hd,$this->aliasNbPgGp)!==false)) {
11413 if (strpos($hd,$this->aliasNbPgGp)!==false) { $type= 'nbpggp'; } else { $type= 'nbpg'; }
11414 $this->_out('{mpdfheader'.$type.' '.$pos.' ff='.$hff.' fs='.$hfst.' fz='.$hfsz.'}');
11415 $this->Cell($headerpgwidth ,$maxfontheight/_MPDFK ,$hd,0,0,$align,0,'',0,0,0,'M');
11416 $this->_out('Q');
11417 }
11418 else {
11419 $this->Cell($headerpgwidth ,$maxfontheight/_MPDFK ,$hd,0,0,$align,0,'',0,0,0,'M');
11420 }
11421 if ($hfcol) { $this->SetTColor($this->ConvertColor(0)); }
11422 }
11423 }
11424 //Return Font to normal
11425 $this->SetFont($this->default_font,'',$this->original_default_font_size);
11426 // LINE
11427 if (isset($h[$side]['line']) && $h[$side]['line']) {
11428 $this->SetLineWidth(0.1);
11429 $this->SetDColor($this->ConvertColor(0));
11430 $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 );
11431 }
11432 if ($this->forcePortraitHeaders && $this->CurOrientation=='L' && $this->CurOrientation!=$this->DefOrientation) {
11433 $this->_out('Q');
11434 }
11435 }
11436 $this->SetY($this->tMargin);
11437 if ($this->ColActive) { $this->pgwidth = $this->ColWidth; } // *COLUMNS*
11438
11439 $this->processingHeader=false;
11440}
11441
11442
11443
11444/*-- TABLES --*/
11445function TableHeaderFooter($content='',$tablestartpage='',$tablestartcolumn ='',$horf = 'H',$level, $firstSpread=true, $finalSpread=true) {
11446 if(($horf=='H' || $horf=='F') && !empty($content)) { // mPDF 5.7.2
11447 $table = &$this->table[1][1];
11448
11449 // mPDF 5.7.2
11450 if ($horf=='F') { // Table Footer
11451 $firstrow = count($table['cells']) - $table['footernrows'];
11452 $lastrow = count($table['cells']) - 1;
11453 }
11454 else { // Table Header
11455 $firstrow = 0;
11456 $lastrow = $table['headernrows'] - 1;
11457 }
11458 if(empty($content[$firstrow])) {
11459 if ($this->debug) { $this->Error("&lt;tfoot&gt; must precede &lt;tbody&gt; in a table"); }
11460 else { return; }
11461 }
11462
11463 // Advance down page by half width of top border
11464 if ($horf=='H') { // Only if header
11465 if ($table['borders_separate']) { $adv = $table['border_spacing_V']/2 + $table['border_details']['T']['w'] + $table['padding']['T']; }
11466 else { $adv = $table['max_cell_border_width']['T'] /2 ; }
11467 if ($adv) {
11468 if ($this->table_rotate) {
11469 $this->y += ($adv);
11470 }
11471 else {
11472 $this->DivLn($adv,$this->blklvl,true);
11473 }
11474 }
11475 }
11476
11477
11478 $topy = $content[$firstrow][0]['y']-$this->y;
11479
11480 for ($i=$firstrow ; $i<=$lastrow; $i++) {
11481
11482 $y = $this->y;
11483
11484/*-- COLUMNS --*/
11485 // If outside columns, this is done in PaintDivBB
11486 if ($this->ColActive) {
11487 //OUTER FILL BGCOLOR of DIVS
11488 if ($this->blklvl > 0) {
11489 $firstblockfill = $this->GetFirstBlockFill();
11490 if ($firstblockfill && $this->blklvl >= $firstblockfill) {
11491 $divh = $content[$i][0]['h'];
11492 $bak_x = $this->x;
11493 $this->DivLn($divh,-3,false);
11494 // Reset current block fill
11495 $bcor = $this->blk[$this->blklvl]['bgcolorarray'];
11496 $this->SetFColor($bcor);
11497 $this->x = $bak_x;
11498 }
11499 }
11500 }
11501/*-- END COLUMNS --*/
11502
11503 $colctr = 0;
11504 foreach($content[$i] as $tablehf) {
11505 $colctr++;
11506 $y = $tablehf['y'] - $topy;
11507 $this->y = $y;
11508 //Set some cell values
11509 $x = $tablehf['x'];
11510 if (($this->mirrorMargins) && ($tablestartpage == 'ODD') && (($this->page)%2==0)) { // EVEN
11511 $x = $x +$this->MarginCorrection;
11512 }
11513 else if (($this->mirrorMargins) && ($tablestartpage == 'EVEN') && (($this->page)%2==1)) { // ODD
11514 $x = $x +$this->MarginCorrection;
11515 }
11516/*-- COLUMNS --*/
11517 // Added to correct for Columns
11518 if ($this->ColActive) {
11519 if ($this->directionality == 'rtl') { // *RTL*
11520 $x -= ($this->CurrCol - $tablestartcolumn) * ($this->ColWidth+$this->ColGap); // *RTL*
11521 } // *RTL*
11522 else { // *RTL*
11523 $x += ($this->CurrCol - $tablestartcolumn) * ($this->ColWidth+$this->ColGap);
11524 } // *RTL*
11525 }
11526/*-- END COLUMNS --*/
11527
11528 if ($colctr==1) { $x0 = $x; }
11529
11530 // mPDF ITERATION
11531 if ($this->iterationCounter) {
11532 foreach($tablehf['textbuffer'] AS $k=>$t) {
11533 if (!is_array($t[0]) && preg_match('/{iteration ([a-zA-Z0-9_]+)}/',$t[0], $m)) { // mPDF 5.5.06
11534 $vname = '__'.$m[1].'_';
11535 if (!isset($this->$vname)) { $this->$vname = 1; }
11536 else { $this->$vname++; }
11537 $tablehf['textbuffer'][$k][0] = preg_replace('/{iteration '.$m[1].'}/', $this->$vname, $tablehf['textbuffer'][$k][0]);
11538 }
11539 }
11540 }
11541
11542
11543 $w = $tablehf['w'];
11544 $h = $tablehf['h'];
11545 $va = $tablehf['va'];
11546 $R = $tablehf['R'];
11547 $mih = $tablehf['mih'];
11548 $border = $tablehf['border'];
11549 $border_details = $tablehf['border_details'];
11550 $padding = $tablehf['padding'];
11551 $this->tabletheadjustfinished = true;
11552
11553 $textbuffer = $tablehf['textbuffer'];
11554
11555 $align = $tablehf['a'];
11556 //Align
11557 $this->divalign=$align;
11558 $this->x = $x;
11559
11560 if ($this->ColActive) {
11561 if ($table['borders_separate']) {
11562 $tablefill = isset($table['bgcolor'][-1]) ? $table['bgcolor'][-1] : 0;
11563 if ($tablefill) {
11564 $color = $this->ConvertColor($tablefill);
11565 if ($color) {
11566 $xadj = ($table['border_spacing_H']/2);
11567 $yadj = ($table['border_spacing_V']/2);
11568 $wadj = $table['border_spacing_H'];
11569 $hadj = $table['border_spacing_V'];
11570 if ($i == $firstrow && $horf=='H') { // Top
11571 $yadj += $table['padding']['T'] + $table['border_details']['T']['w'] ;
11572 $hadj += $table['padding']['T'] + $table['border_details']['T']['w'] ;
11573 }
11574 if (($i == ($lastrow) || (isset($tablehf['rowspan']) && ($i+$tablehf['rowspan']) == ($lastrow+1)) || (!isset($tablehf['rowspan']) && ($i+1) == ($lastrow+1))) && $horf=='F') { // Bottom
11575 $hadj += $table['padding']['B'] + $table['border_details']['B']['w'] ;
11576 }
11577 if ($colctr == 1) { // Left
11578 $xadj += $table['padding']['L'] + $table['border_details']['L']['w'] ;
11579 $wadj += $table['padding']['L'] + $table['border_details']['L']['w'] ;
11580 }
11581 if ($colctr == count($content[$i]) ) { // Right
11582 $wadj += $table['padding']['R'] + $table['border_details']['R']['w'] ;
11583 }
11584 $this->SetFColor($color);
11585 $this->Rect($x - $xadj, $y - $yadj, $w + $wadj, $h + $hadj, 'F');
11586 }
11587 }
11588 }
11589 }
11590
11591 if ($table['empty_cells']!='hide' || !empty($textbuffer) || !$table['borders_separate']) { $paintcell = true; }
11592 else { $paintcell = false; }
11593
11594 //Vertical align
11595 if ($R && INTVAL($R) > 0 && isset($va) && $va!='B') { $va='B';}
11596
11597 if (!isset($va) || empty($va) || $va=='M') $this->y += ($h-$mih)/2;
11598 elseif (isset($va) && $va=='B') $this->y += $h-$mih;
11599
11600
11601 //TABLE ROW OR CELL FILL BGCOLOR
11602 $fill = 0;
11603 if (isset($tablehf['bgcolor']) && $tablehf['bgcolor'] && $tablehf['bgcolor']!='transparent') {
11604 $fill = $tablehf['bgcolor'];
11605 $leveladj = 6;
11606 }
11607 else if (isset($content[$i][0]['trbgcolor']) && $content[$i][0]['trbgcolor'] && $content[$i][0]['trbgcolor']!='transparent') { // Row color
11608 $fill = $content[$i][0]['trbgcolor'];
11609 $leveladj = 3;
11610 }
11611 if ($fill && $paintcell) {
11612 $color = $this->ConvertColor($fill);
11613 if ($color) {
11614 if ($table['borders_separate']) {
11615 if ($this->ColActive) {
11616 $this->SetFColor($color);
11617 $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');
11618 }
11619 else {
11620 $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);
11621 }
11622 }
11623 else {
11624 if ($this->ColActive) {
11625 $this->SetFColor($color);
11626 $this->Rect($x, $y, $w, $h, 'F');
11627 }
11628 else {
11629 $this->tableBackgrounds[$level*9+$leveladj][] = array('gradient'=>false, 'x'=>$x, 'y'=>$y, 'w'=>$w, 'h'=>$h, 'col'=>$color);
11630 }
11631 }
11632 }
11633 }
11634
11635
11636/*-- BACKGROUNDS --*/
11637 if (isset($tablehf['gradient']) && $tablehf['gradient'] && $paintcell){
11638 $g = $this->grad->parseBackgroundGradient($tablehf['gradient']);
11639 if ($g) {
11640 if ($table['borders_separate']) {
11641 $px = $x+ ($table['border_spacing_H']/2);
11642 $py = $y+ ($table['border_spacing_V']/2);
11643 $pw = $w- $table['border_spacing_H'];
11644 $ph = $h- $table['border_spacing_V'];
11645 }
11646 else {
11647 $px = $x;
11648 $py = $y;
11649 $pw = $w;
11650 $ph = $h;
11651 }
11652 if ($this->ColActive) {
11653 $this->grad->Gradient($px, $py, $pw, $ph, $g['type'], $g['stops'], $g['colorspace'], $g['coords'], $g['extend']);
11654 }
11655 else {
11656 $this->tableBackgrounds[$level*9+7][] = array('gradient'=>true, 'x'=>$px, 'y'=>$py, 'w'=>$pw, 'h'=>$ph, 'gradtype'=>$g['type'], 'stops'=>$g['stops'], 'colorspace'=>$g['colorspace'], 'coords'=>$g['coords'], 'extend'=>$g['extend'], 'clippath'=>'');
11657 }
11658 }
11659 }
11660
11661 if (isset($tablehf['background-image']) && $paintcell){
11662 if ($tablehf['background-image']['gradient'] && preg_match('/(-moz-)*(repeating-)*(linear|radial)-gradient/', $tablehf['background-image']['gradient'] )) {
11663 $g = $this->grad->parseMozGradient( $tablehf['background-image']['gradient'] );
11664 if ($g) {
11665 if ($table['borders_separate']) {
11666 $px = $x+ ($table['border_spacing_H']/2);
11667 $py = $y+ ($table['border_spacing_V']/2);
11668 $pw = $w- $table['border_spacing_H'];
11669 $ph = $h- $table['border_spacing_V'];
11670 }
11671 else {
11672 $px = $x;
11673 $py = $y;
11674 $pw = $w;
11675 $ph = $h;
11676 }
11677 if ($this->ColActive) {
11678 $this->grad->Gradient($px, $py, $pw, $ph, $g['type'], $g['stops'], $g['colorspace'], $g['coords'], $g['extend']);
11679 }
11680 else {
11681 $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'=>'');
11682 }
11683 }
11684 }
11685 else if ($tablehf['background-image']['image_id']) { // Background pattern
11686 $n = count($this->patterns)+1;
11687 if ($table['borders_separate']) {
11688 $px = $x+ ($table['border_spacing_H']/2);
11689 $py = $y+ ($table['border_spacing_V']/2);
11690 $pw = $w- $table['border_spacing_H'];
11691 $ph = $h- $table['border_spacing_V'];
11692 }
11693 else {
11694 $px = $x;
11695 $py = $y;
11696 $pw = $w;
11697 $ph = $h;
11698 }
11699 if ($this->ColActive) {
11700 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']);
11701 $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']);
11702 if ($tablehf['background-image']['opacity']>0 && $tablehf['background-image']['opacity']<1) { $opac = $this->SetAlpha($tablehf['background-image']['opacity'],'Normal',true); }
11703 else { $opac = ''; }
11704 $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));
11705 }
11706 else {
11707 $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']);
11708 }
11709 }
11710 }
11711/*-- END BACKGROUNDS --*/
11712
11713 //Cell Border
11714 if ($table['borders_separate'] && $paintcell && $border) {
11715 $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']);
11716 }
11717 else if ($paintcell && $border) {
11718 $this->_tableRect($x, $y, $w, $h, $border, $border_details, true, $table['borders_separate']); // true causes buffer
11719 }
11720
11721 //Print cell content
11722 //$this->divheight = $this->table_lineheight*$this->lineheight;
11723 if (!empty($textbuffer)) {
11724 if ($horf=='F' && preg_match('/{colsum([0-9]*)[_]*}/', $textbuffer[0][0], $m)) {
11725 $rep = sprintf("%01.".intval($m[1])."f", $this->colsums[$colctr-1]);
11726 $textbuffer[0][0] = preg_replace('/{colsum[0-9_]*}/', $rep ,$textbuffer[0][0]);
11727 }
11728
11729 if ($R) {
11730 $cellPtSize = $textbuffer[0][11] / $this->shrin_k;
11731 if (!$cellPtSize) { $cellPtSize = $this->default_font_size; }
11732 $cellFontHeight = ($cellPtSize/_MPDFK);
11733 $opx = $this->x;
11734 $opy = $this->y;
11735 $angle = INTVAL($R);
11736 // Only allow 45 - 90 degrees (when bottom-aligned) or -90
11737 if ($angle > 90) { $angle = 90; }
11738 else if ($angle > 0 && (isset($va) && $va!='B')) { $angle = 90; }
11739 else if ($angle > 0 && $angle <45) { $angle = 45; }
11740 else if ($angle < 0) { $angle = -90; }
11741 $offset = ((sin(deg2rad($angle))) * 0.37 * $cellFontHeight);
11742 if (isset($align) && $align =='R') {
11743 $this->x += ($w) + ($offset) - ($cellFontHeight/3) - ($padding['R'] + $border_details['R']['w']);
11744 }
11745 else if (!isset($align ) || $align =='C') {
11746 $this->x += ($w/2) + ($offset);
11747 }
11748 else {
11749 $this->x += ($offset) + ($cellFontHeight/3)+($padding['L'] + $border_details['L']['w']);
11750 }
11751 $str = '';
11752 foreach($tablehf['textbuffer'] AS $t) { $str .= $t[0].' '; }
11753 $str = trim($str);
11754
11755 if (!isset($va) || $va=='M') {
11756 $this->y -= ($h-$mih)/2; //Undo what was added earlier VERTICAL ALIGN
11757 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'])); }
11758 else if ($angle < 0) { $this->y += (($h-$mih)/2)+($padding['T'] + $border_details['T']['w']); }
11759 }
11760 else if (isset($va) && $va=='B') {
11761 $this->y -= $h-$mih; //Undo what was added earlier VERTICAL ALIGN
11762 if ($angle > 0) { $this->y += $h-($border_details['B']['w']+$padding['B']); }
11763 else if ($angle < 0) { $this->y += $h-$mih+($padding['T'] + $border_details['T']['w']); }
11764 }
11765 else if (isset($va) && $va=='T') {
11766 if ($angle > 0) { $this->y += $mih-($border_details['B']['w']+$padding['B']); }
11767 else if ($angle < 0) { $this->y += ($padding['T'] + $border_details['T']['w']); }
11768 }
11769
11770 $this->Rotate($angle,$this->x,$this->y);
11771 $s_fs = $this->FontSizePt;
11772 $s_f = $this->FontFamily;
11773 $s_st = $this->FontStyle;
11774 if (!empty($textbuffer[0][3])) { //Font Color
11775 $cor = $textbuffer[0][3];
11776 $this->SetTColor($cor);
11777 }
11778 $s_str = $this->strike;
11779 $this->strike = $textbuffer[0][8]; //Strikethrough
11780 $this->SetFont($textbuffer[0][4],$textbuffer[0][2],$cellPtSize,true,true);
11781 $this->Text($this->x,$this->y,$str);
11782 $this->Rotate(0);
11783 $this->SetFont($s_f,$s_st,$s_fs,true,true);
11784 $this->SetTColor(0);
11785 $this->strike = $s_str;
11786 $this->x = $opx;
11787 $this->y = $opy;
11788 }
11789 else {
11790 if ($table['borders_separate']) { // NB twice border width
11791 $xadj = $border_details['L']['w'] + $padding['L'] +($table['border_spacing_H']/2);
11792 $wadj = $border_details['L']['w'] + $border_details['R']['w'] + $padding['L'] +$padding['R'] + $table['border_spacing_H'];
11793 $yadj = $border_details['T']['w'] + $padding['T'] + ($table['border_spacing_H']/2);
11794 }
11795 else {
11796 $xadj = $border_details['L']['w']/2 + $padding['L'];
11797 $wadj = ($border_details['L']['w'] + $border_details['R']['w'])/2 + $padding['L'] + $padding['R'];
11798 $yadj = $border_details['T']['w']/2 + $padding['T'];
11799 }
11800
11801 $this->divwidth=$w-($wadj);
11802 $this->x += $xadj;
11803 $this->y += $yadj;
11804 $this->printbuffer($textbuffer,'',true);
11805 }
11806
11807 }
11808 $textbuffer = array();
11809
11810/*-- BACKGROUNDS --*/
11811 if (!$this->ColActive) {
11812 if (isset($content[$i][0]['trgradients']) && ($colctr==1 || $table['borders_separate'])) {
11813 $g = $this->grad->parseBackgroundGradient($content[$i][0]['trgradients']);
11814 if ($g) {
11815 $gx = $x0;
11816 $gy = $y;
11817 $gh = $h;
11818 $gw = $table['w'] - ($table['max_cell_border_width']['L']/2) - ($table['max_cell_border_width']['R']/2) - $table['margin']['L'] - $table['margin']['R'];
11819 if ($table['borders_separate']) {
11820 $gw -= ($table['padding']['L'] + $table['border_details']['L']['w'] + $table['padding']['R'] + $table['border_details']['R']['w'] + $table['border_spacing_H']);
11821 $s = '';
11822 $clx = $x+ ($table['border_spacing_H']/2);
11823 $cly = $y+ ($table['border_spacing_V']/2);
11824 $clw = $w- $table['border_spacing_H'];
11825 $clh = $h- $table['border_spacing_V'];
11826 // Set clipping path
11827 $s = ' q 0 w '; // Line width=0
11828 $s .= sprintf('%.3F %.3F m ', ($clx)*_MPDFK, ($this->h-($cly))*_MPDFK); // start point TL before the arc
11829 $s .= sprintf('%.3F %.3F l ', ($clx)*_MPDFK, ($this->h-($cly+$clh))*_MPDFK); // line to BL
11830 $s .= sprintf('%.3F %.3F l ', ($clx+$clw)*_MPDFK, ($this->h-($cly+$clh))*_MPDFK); // line to BR
11831 $s .= sprintf('%.3F %.3F l ', ($clx+$clw)*_MPDFK, ($this->h-($cly))*_MPDFK); // line to TR
11832 $s .= sprintf('%.3F %.3F l ', ($clx)*_MPDFK, ($this->h-($cly))*_MPDFK); // line to TL
11833 $s .= ' W n '; // Ends path no-op & Sets the clipping path
11834 $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);
11835 }
11836 else {
11837 $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'=>'');
11838 }
11839 }
11840 }
11841
11842 if (isset($content[$i][0]['trbackground-images']) && ($colctr==1 || $table['borders_separate'])) {
11843 if ($content[$i][0]['trbackground-images']['gradient'] && preg_match('/(-moz-)*(repeating-)*(linear|radial)-gradient/', $content[$i][0]['trbackground-images']['gradient'] )) {
11844 $g = $this->grad->parseMozGradient( $content[$i][0]['trbackground-images']['gradient'] );
11845 if ($g) {
11846 $gx = $x0;
11847 $gy = $y;
11848 $gh = $h;
11849 $gw = $table['w'] - ($table['max_cell_border_width']['L']/2) - ($table['max_cell_border_width']['R']/2) - $table['margin']['L'] - $table['margin']['R'];
11850 if ($table['borders_separate']) {
11851 $gw -= ($table['padding']['L'] + $table['border_details']['L']['w'] + $table['padding']['R'] + $table['border_details']['R']['w'] + $table['border_spacing_H']);
11852 $s = '';
11853 $clx = $x+ ($table['border_spacing_H']/2);
11854 $cly = $y+ ($table['border_spacing_V']/2);
11855 $clw = $w- $table['border_spacing_H'];
11856 $clh = $h- $table['border_spacing_V'];
11857 // Set clipping path
11858 $s = ' q 0 w '; // Line width=0
11859 $s .= sprintf('%.3F %.3F m ', ($clx)*_MPDFK, ($this->h-($cly))*_MPDFK); // start point TL before the arc
11860 $s .= sprintf('%.3F %.3F l ', ($clx)*_MPDFK, ($this->h-($cly+$clh))*_MPDFK); // line to BL
11861 $s .= sprintf('%.3F %.3F l ', ($clx+$clw)*_MPDFK, ($this->h-($cly+$clh))*_MPDFK); // line to BR
11862 $s .= sprintf('%.3F %.3F l ', ($clx+$clw)*_MPDFK, ($this->h-($cly))*_MPDFK); // line to TR
11863 $s .= sprintf('%.3F %.3F l ', ($clx)*_MPDFK, ($this->h-($cly))*_MPDFK); // line to TL
11864 $s .= ' W n '; // Ends path no-op & Sets the clipping path
11865 $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);
11866 }
11867 else {
11868 $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'=>'');
11869 }
11870 }
11871 }
11872 else {
11873 $image_id = $content[$i][0]['trbackground-images']['image_id'];
11874 $orig_w = $content[$i][0]['trbackground-images']['orig_w'];
11875 $orig_h = $content[$i][0]['trbackground-images']['orig_h'];
11876 $x_pos = $content[$i][0]['trbackground-images']['x_pos'];
11877 $y_pos = $content[$i][0]['trbackground-images']['y_pos'];
11878 $x_repeat = $content[$i][0]['trbackground-images']['x_repeat'];
11879 $y_repeat = $content[$i][0]['trbackground-images']['y_repeat'];
11880 $resize = $content[$i][0]['trbackground-images']['resize'];
11881 $opacity = $content[$i][0]['trbackground-images']['opacity'];
11882 $itype = $content[$i][0]['trbackground-images']['itype'];
11883
11884 $clippath = '';
11885 $gx = $x0;
11886 $gy = $y;
11887 $gh = $h;
11888 $gw = $table['w'] - ($table['max_cell_border_width']['L']/2) - ($table['max_cell_border_width']['R']/2) - $table['margin']['L'] - $table['margin']['R'];
11889 if ($table['borders_separate']) {
11890 $gw -= ($table['padding']['L'] + $table['border_details']['L']['w'] + $table['padding']['R'] + $table['border_details']['R']['w'] + $table['border_spacing_H']);
11891 $s = '';
11892 $clx = $x+ ($table['border_spacing_H']/2);
11893 $cly = $y+ ($table['border_spacing_V']/2);
11894 $clw = $w- $table['border_spacing_H'];
11895 $clh = $h- $table['border_spacing_V'];
11896 // Set clipping path
11897 $s = ' q 0 w '; // Line width=0
11898 $s .= sprintf('%.3F %.3F m ', ($clx)*_MPDFK, ($this->h-($cly))*_MPDFK); // start point TL before the arc
11899 $s .= sprintf('%.3F %.3F l ', ($clx)*_MPDFK, ($this->h-($cly+$clh))*_MPDFK); // line to BL
11900 $s .= sprintf('%.3F %.3F l ', ($clx+$clw)*_MPDFK, ($this->h-($cly+$clh))*_MPDFK); // line to BR
11901 $s .= sprintf('%.3F %.3F l ', ($clx+$clw)*_MPDFK, ($this->h-($cly))*_MPDFK); // line to TR
11902 $s .= sprintf('%.3F %.3F l ', ($clx)*_MPDFK, ($this->h-($cly))*_MPDFK); // line to TL
11903 $s .= ' W n '; // Ends path no-op & Sets the clipping path
11904 $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);
11905 }
11906 else {
11907 $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);
11908 }
11909 }
11910 }
11911 }
11912/*-- END BACKGROUNDS --*/
11913
11914 // TABLE BORDER - if separate OR collapsed and only table border
11915 if (($table['borders_separate'] || ($this->simpleTables && !$table['simple']['border'])) && $table['border']) {
11916 $halfspaceL = $table['padding']['L'] + ($table['border_spacing_H']/2);
11917 $halfspaceR = $table['padding']['R'] + ($table['border_spacing_H']/2);
11918 $halfspaceT = $table['padding']['T'] + ($table['border_spacing_V']/2);
11919 $halfspaceB = $table['padding']['B'] + ($table['border_spacing_V']/2);
11920 $tbx = $x;
11921 $tby = $y;
11922 $tbw = $w;
11923 $tbh = $h;
11924 $tab_bord = 0;
11925 $corner = '';
11926 if ($i == $firstrow && $horf=='H') { // Top
11927 $tby -= $halfspaceT + ($table['border_details']['T']['w']/2);
11928 $tbh += $halfspaceT + ($table['border_details']['T']['w']/2);
11929 $this->setBorder($tab_bord , _BORDER_TOP);
11930 $corner .= 'T';
11931 }
11932 if (($i == ($lastrow) || (isset($tablehf['rowspan']) && ($i+$tablehf['rowspan']) == ($lastrow+1))) && $horf=='F') { // Bottom
11933 $tbh += $halfspaceB + ($table['border_details']['B']['w']/2);
11934 $this->setBorder($tab_bord , _BORDER_BOTTOM);
11935 $corner .= 'B';
11936 }
11937 if ($colctr == 1 && $firstSpread) { // Left
11938 $tbx -= $halfspaceL + ($table['border_details']['L']['w']/2);
11939 $tbw += $halfspaceL + ($table['border_details']['L']['w']/2);
11940 $this->setBorder($tab_bord , _BORDER_LEFT);
11941 $corner .= 'L';
11942 }
11943 if ($colctr == count($content[$i]) && $finalSpread) { // Right
11944 $tbw += $halfspaceR + ($table['border_details']['R']['w']/2);
11945 $this->setBorder($tab_bord , _BORDER_RIGHT);
11946 $corner .= 'R';
11947 }
11948 $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'] );
11949 }
11950
11951
11952 }// end column $content
11953 $this->y = $y + $h; //Update y coordinate
11954 }// end row $i
11955 unset($table );
11956 $this->colsums = array();
11957 }
11958}
11959/*-- END TABLES --*/
11960
11961/*-- HTMLHEADERS-FOOTERS --*/
11962function SetHTMLHeader($header='',$OE='',$write=false) {
11963
11964 $height = 0;
11965 if (is_array($header) && isset($header['html']) && $header['html']) {
11966 $Hhtml = $header['html'];
11967 if ($this->setAutoTopMargin) {
11968 if (isset($header['h'])) { $height = $header['h']; }
11969 else { $height = $this->_gethtmlheight($Hhtml); }
11970 }
11971 }
11972 else if (!is_array($header) && $header) {
11973 $Hhtml = $header;
11974 if ($this->setAutoTopMargin) { $height = $this->_gethtmlheight($Hhtml); }
11975 }
11976 else { $Hhtml = ''; }
11977
11978 if ($OE != 'E') { $OE = 'O'; }
11979 if ($OE == 'E') {
11980
11981 if ($Hhtml) {
11982 $this->HTMLHeaderE['html'] = $Hhtml;
11983 $this->HTMLHeaderE['h'] = $height;
11984 }
11985 else { $this->HTMLHeaderE = ''; }
11986 }
11987 else {
11988
11989 if ($Hhtml) {
11990 $this->HTMLHeader['html'] = $Hhtml;
11991 $this->HTMLHeader['h'] = $height;
11992 }
11993 else { $this->HTMLHeader = ''; }
11994 }
11995 if (!$this->mirrorMargins && $OE == 'E') { return; }
11996 if ($Hhtml=='') { return; }
11997 if ($OE == 'E') {
11998 $this->headerDetails['even'] = array(); // override and clear any other non-HTML header/footer
11999 }
12000 else {
12001 $this->headerDetails['odd'] = array(); // override and clear any non-HTML other header/footer
12002 }
12003
12004 if ($this->setAutoTopMargin=='pad') {
12005 $this->tMargin = $this->margin_header + $height + $this->orig_tMargin;
12006 if (isset($this->saveHTMLHeader[$this->page][$OE]['mt'])) { $this->saveHTMLHeader[$this->page][$OE]['mt'] = $this->tMargin; }
12007 }
12008 else if ($this->setAutoTopMargin=='stretch') {
12009 $this->tMargin = max($this->orig_tMargin, $this->margin_header + $height + $this->autoMarginPadding);
12010 if (isset($this->saveHTMLHeader[$this->page][$OE]['mt'])) { $this->saveHTMLHeader[$this->page][$OE]['mt'] = $this->tMargin; }
12011 }
12012 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(); }
12013}
12014
12015function SetHTMLFooter($footer='',$OE='') {
12016
12017 $height = 0;
12018 if (is_array($footer) && isset($footer['html']) && $footer['html']) {
12019 $Fhtml = $footer['html'];
12020 if ($this->setAutoBottomMargin) {
12021 if (isset($footer['h'])) { $height = $footer['h']; }
12022 else { $height = $this->_gethtmlheight($Fhtml); }
12023 }
12024 }
12025 else if (!is_array($footer) && $footer) {
12026 $Fhtml = $footer;
12027 if ($this->setAutoBottomMargin) { $height = $this->_gethtmlheight($Fhtml); }
12028 }
12029 else { $Fhtml = ''; }
12030
12031 if ($OE != 'E') { $OE = 'O'; }
12032 if ($OE == 'E') {
12033
12034 if ($Fhtml) {
12035 $this->HTMLFooterE['html'] = $Fhtml;
12036 $this->HTMLFooterE['h'] = $height;
12037 }
12038 else { $this->HTMLFooterE = ''; }
12039 }
12040 else {
12041
12042 if ($Fhtml) {
12043 $this->HTMLFooter['html'] = $Fhtml;
12044 $this->HTMLFooter['h'] = $height;
12045 }
12046 else { $this->HTMLFooter = ''; }
12047 }
12048 if (!$this->mirrorMargins && $OE == 'E') { return; }
12049 if ($Fhtml=='') { return false; }
12050 if ($OE == 'E') {
12051 $this->footerDetails['even'] = array(); // override and clear any other header/footer
12052 }
12053 else {
12054 $this->footerDetails['odd'] = array(); // override and clear any other header/footer
12055 }
12056
12057 if ($this->setAutoBottomMargin=='pad') {
12058 $this->bMargin = $this->margin_footer + $height + $this->orig_bMargin;
12059 $this->PageBreakTrigger=$this->h-$this->bMargin ;
12060 if (isset($this->saveHTMLHeader[$this->page][$OE]['mb'])) { $this->saveHTMLHeader[$this->page][$OE]['mb'] = $this->bMargin; }
12061 }
12062 else if ($this->setAutoBottomMargin=='stretch') {
12063 $this->bMargin = max($this->orig_bMargin, $this->margin_footer + $height + $this->autoMarginPadding);
12064 $this->PageBreakTrigger=$this->h-$this->bMargin ;
12065 if (isset($this->saveHTMLHeader[$this->page][$OE]['mb'])) { $this->saveHTMLHeader[$this->page][$OE]['mb'] = $this->bMargin; }
12066 }
12067}
12068
12069
12070function _getHtmlHeight($html) {
12071 $save_state = $this->state;
12072 if($this->state==0) {
12073 $this->AddPage($this->CurOrientation);
12074 }
12075 $this->state = 2;
12076 $this->Reset();
12077 $this->pageoutput[$this->page] = array();
12078 $save_x = $this->x;
12079 $save_y = $this->y;
12080 $this->x = $this->lMargin;
12081 $this->y = $this->margin_header;
12082 $html = str_replace('{PAGENO}',$this->pagenumPrefix.$this->docPageNum($this->page).$this->pagenumSuffix,$html);
12083 $html = str_replace($this->aliasNbPgGp,$this->nbpgPrefix.$this->docPageNumTotal($this->page).$this->nbpgSuffix,$html );
12084 $html = str_replace($this->aliasNbPg,$this->page,$html );
12085 $html = preg_replace_callback('/\{DATE\s+(.*?)\}/', array($this, 'date_callback') ,$html ); // mPDF 5.7
12086 $this->HTMLheaderPageLinks = array();
12087 $this->HTMLheaderPageAnnots = array();
12088 $this->HTMLheaderPageForms = array();
12089 $savepb = $this->pageBackgrounds;
12090 $this->writingHTMLheader = true;
12091 $this->WriteHTML($html , 4); // parameter 4 saves output to $this->headerbuffer
12092 $this->writingHTMLheader = false;
12093 $h = ($this->y - $this->margin_header);
12094 $this->Reset();
12095 // mPDF 5.7.2 - Clear in case Float used in Header/Footer
12096 $this->blk[0]['blockContext'] = 0;
12097 $this->blk[0]['float_endpos'] = 0;
12098
12099 $this->pageoutput[$this->page] = array();
12100 $this->headerbuffer = '';
12101 $this->pageBackgrounds = $savepb;
12102 $this->x = $save_x;
12103 $this->y = $save_y;
12104 $this->state = $save_state;
12105 if($save_state==0) {
12106 unset($this->pages[1]);
12107 $this->page = 0;
12108 }
12109 return $h;
12110}
12111
12112
12113// Called internally from Header
12114function writeHTMLHeaders() {
12115
12116 if ($this->mirrorMargins && ($this->page)%2==0) { $OE = 'E'; } // EVEN
12117 else { $OE = 'O'; }
12118 if ($OE == 'E') {
12119 $this->saveHTMLHeader[$this->page][$OE]['html'] = $this->HTMLHeaderE['html'] ;
12120 }
12121 else {
12122 $this->saveHTMLHeader[$this->page][$OE]['html'] = $this->HTMLHeader['html'] ;
12123 }
12124 if ($this->forcePortraitHeaders && $this->CurOrientation=='L' && $this->CurOrientation!=$this->DefOrientation) {
12125 $this->saveHTMLHeader[$this->page][$OE]['rotate'] = true;
12126 $this->saveHTMLHeader[$this->page][$OE]['ml'] = $this->tMargin;
12127 $this->saveHTMLHeader[$this->page][$OE]['mr'] = $this->bMargin;
12128 $this->saveHTMLHeader[$this->page][$OE]['mh'] = $this->margin_header;
12129 $this->saveHTMLHeader[$this->page][$OE]['mf'] = $this->margin_footer;
12130 $this->saveHTMLHeader[$this->page][$OE]['pw'] = $this->h;
12131 $this->saveHTMLHeader[$this->page][$OE]['ph'] = $this->w;
12132 }
12133 else {
12134 $this->saveHTMLHeader[$this->page][$OE]['ml'] = $this->lMargin;
12135 $this->saveHTMLHeader[$this->page][$OE]['mr'] = $this->rMargin;
12136 $this->saveHTMLHeader[$this->page][$OE]['mh'] = $this->margin_header;
12137 $this->saveHTMLHeader[$this->page][$OE]['mf'] = $this->margin_footer;
12138 $this->saveHTMLHeader[$this->page][$OE]['pw'] = $this->w;
12139 $this->saveHTMLHeader[$this->page][$OE]['ph'] = $this->h;
12140 }
12141}
12142
12143function writeHTMLFooters() {
12144
12145 if ($this->mirrorMargins && ($this->page)%2==0) { $OE = 'E'; } // EVEN
12146 else { $OE = 'O'; }
12147 if ($OE == 'E') {
12148 $this->saveHTMLFooter[$this->page][$OE]['html'] = $this->HTMLFooterE['html'] ;
12149 }
12150 else {
12151 $this->saveHTMLFooter[$this->page][$OE]['html'] = $this->HTMLFooter['html'] ;
12152 }
12153 if ($this->forcePortraitHeaders && $this->CurOrientation=='L' && $this->CurOrientation!=$this->DefOrientation) {
12154 $this->saveHTMLFooter[$this->page][$OE]['rotate'] = true;
12155 $this->saveHTMLFooter[$this->page][$OE]['ml'] = $this->tMargin;
12156 $this->saveHTMLFooter[$this->page][$OE]['mr'] = $this->bMargin;
12157 $this->saveHTMLFooter[$this->page][$OE]['mt'] = $this->rMargin;
12158 $this->saveHTMLFooter[$this->page][$OE]['mb'] = $this->lMargin;
12159 $this->saveHTMLFooter[$this->page][$OE]['mh'] = $this->margin_header;
12160 $this->saveHTMLFooter[$this->page][$OE]['mf'] = $this->margin_footer;
12161 $this->saveHTMLFooter[$this->page][$OE]['pw'] = $this->h;
12162 $this->saveHTMLFooter[$this->page][$OE]['ph'] = $this->w;
12163 }
12164 else {
12165 $this->saveHTMLFooter[$this->page][$OE]['ml'] = $this->lMargin;
12166 $this->saveHTMLFooter[$this->page][$OE]['mr'] = $this->rMargin;
12167 $this->saveHTMLFooter[$this->page][$OE]['mt'] = $this->tMargin;
12168 $this->saveHTMLFooter[$this->page][$OE]['mb'] = $this->bMargin;
12169 $this->saveHTMLFooter[$this->page][$OE]['mh'] = $this->margin_header;
12170 $this->saveHTMLFooter[$this->page][$OE]['mf'] = $this->margin_footer;
12171 $this->saveHTMLFooter[$this->page][$OE]['pw'] = $this->w;
12172 $this->saveHTMLFooter[$this->page][$OE]['ph'] = $this->h;
12173 }
12174}
12175/*-- END HTMLHEADERS-FOOTERS --*/
12176
12177function DefHeaderByName($name,$arr) {
12178 if (!$name) { $name = '_default'; }
12179 $this->pageheaders[$name] = $arr;
12180}
12181
12182function DefFooterByName($name,$arr) {
12183 if (!$name) { $name = '_default'; }
12184 $this->pagefooters[$name] = $arr;
12185}
12186
12187function SetHeaderByName($name,$side='O',$write=false) {
12188 if (!$name) { $name = '_default'; }
12189 if ($side=='E') { $this->headerDetails['even'] = $this->pageheaders[$name]; }
12190 else { $this->headerDetails['odd'] = $this->pageheaders[$name]; }
12191 if ($write) { $this->Header(); }
12192}
12193
12194function SetFooterByName($name,$side='O') {
12195 if (!$name) { $name = '_default'; }
12196 if ($side=='E') { $this->footerDetails['even'] = $this->pagefooters[$name]; }
12197 else { $this->footerDetails['odd'] = $this->pagefooters[$name]; }
12198}
12199
12200/*-- HTMLHEADERS-FOOTERS --*/
12201function DefHTMLHeaderByName($name,$html) {
12202 if (!$name) { $name = '_default'; }
12203
12204 $this->pageHTMLheaders[$name]['html'] = $html;
12205 $this->pageHTMLheaders[$name]['h'] = $this->_gethtmlheight($html);
12206}
12207
12208function DefHTMLFooterByName($name,$html) {
12209 if (!$name) { $name = '_default'; }
12210
12211 $this->pageHTMLfooters[$name]['html'] = $html;
12212 $this->pageHTMLfooters[$name]['h'] = $this->_gethtmlheight($html);
12213}
12214
12215function SetHTMLHeaderByName($name,$side='O',$write=false) {
12216 if (!$name) { $name = '_default'; }
12217 $this->SetHTMLHeader($this->pageHTMLheaders[$name],$side,$write);
12218}
12219
12220function SetHTMLFooterByName($name,$side='O') {
12221 if (!$name) { $name = '_default'; }
12222 $this->SetHTMLFooter($this->pageHTMLfooters[$name],$side,$write);
12223}
12224/*-- END HTMLHEADERS-FOOTERS --*/
12225
12226
12227function SetHeader($Harray=array(),$side='',$write=false) {
12228 if (is_string($Harray)) {
12229 if (strlen($Harray)==0) {
12230 if ($side=='O') { $this->headerDetails['odd'] = array(); }
12231 else if ($side=='E') { $this->headerDetails['even'] = array(); }
12232 else { $this->headerDetails = array(); }
12233 }
12234 else if (strpos($Harray,'|') || strpos($Harray,'|')===0) {
12235 $hdet = explode('|',$Harray);
12236 $this->headerDetails = array (
12237 'odd' => array (
12238 'L' => array ('content' => $hdet[0], 'font-size' => $this->defaultheaderfontsize, 'font-style' => $this->defaultheaderfontstyle),
12239 'C' => array ('content' => $hdet[1], 'font-size' => $this->defaultheaderfontsize, 'font-style' => $this->defaultheaderfontstyle),
12240 'R' => array ('content' => $hdet[2], 'font-size' => $this->defaultheaderfontsize, 'font-style' => $this->defaultheaderfontstyle),
12241 'line' => $this->defaultheaderline,
12242 ),
12243 'even' => array (
12244 'R' => array ('content' => $hdet[0], 'font-size' => $this->defaultheaderfontsize, 'font-style' => $this->defaultheaderfontstyle),
12245 'C' => array ('content' => $hdet[1], 'font-size' => $this->defaultheaderfontsize, 'font-style' => $this->defaultheaderfontstyle),
12246 'L' => array ('content' => $hdet[2], 'font-size' => $this->defaultheaderfontsize, 'font-style' => $this->defaultheaderfontstyle),
12247 'line' => $this->defaultheaderline,
12248 )
12249 );
12250 }
12251 else {
12252 $this->headerDetails = array (
12253 'odd' => array (
12254 'R' => array ('content' => $Harray, 'font-size' => $this->defaultheaderfontsize, 'font-style' => $this->defaultheaderfontstyle),
12255 'line' => $this->defaultheaderline,
12256 ),
12257 'even' => array (
12258 'L' => array ('content' => $Harray, 'font-size' => $this->defaultheaderfontsize, 'font-style' => $this->defaultheaderfontstyle),
12259 'line' => $this->defaultheaderline,
12260 )
12261 );
12262 }
12263 }
12264 else if (is_array($Harray)) {
12265 if ($side=='O') { $this->headerDetails['odd'] = $Harray; }
12266 else if ($side=='E') { $this->headerDetails['even'] = $Harray; }
12267 else { $this->headerDetails = $Harray; }
12268 }
12269/*-- HTMLHEADERS-FOOTERS --*/
12270 // Overwrite any HTML Header previously set
12271 if ($side=='E') { $this->SetHTMLHeader('','E'); }
12272 else if ($side=='O') { $this->SetHTMLHeader(''); }
12273 else {
12274 $this->SetHTMLHeader('');
12275 $this->SetHTMLHeader('','E');
12276 }
12277/*-- END HTMLHEADERS-FOOTERS --*/
12278
12279 if ($write) {
12280 $save_y = $this->y;
12281 $this->Header();
12282 $this->SetY($save_y) ;
12283 }
12284}
12285
12286
12287
12288
12289function SetFooter($Farray=array(),$side='') {
12290 if (is_string($Farray)) {
12291 if (strlen($Farray)==0) {
12292 if ($side=='O') { $this->footerDetails['odd'] = array(); }
12293 else if ($side=='E') { $this->footerDetails['even'] = array(); }
12294 else { $this->footerDetails = array(); }
12295 }
12296 else if (strpos($Farray,'|') || strpos($Farray,'|')===0) {
12297 $fdet = explode('|',$Farray);
12298 $this->footerDetails = array (
12299 'odd' => array (
12300 'L' => array ('content' => $fdet[0], 'font-size' => $this->defaultfooterfontsize, 'font-style' => $this->defaultfooterfontstyle),
12301 'C' => array ('content' => $fdet[1], 'font-size' => $this->defaultfooterfontsize, 'font-style' => $this->defaultfooterfontstyle),
12302 'R' => array ('content' => $fdet[2], 'font-size' => $this->defaultfooterfontsize, 'font-style' => $this->defaultfooterfontstyle),
12303 'line' => $this->defaultfooterline,
12304 ),
12305 'even' => array (
12306 'R' => array ('content' => $fdet[0], 'font-size' => $this->defaultfooterfontsize, 'font-style' => $this->defaultfooterfontstyle),
12307 'C' => array ('content' => $fdet[1], 'font-size' => $this->defaultfooterfontsize, 'font-style' => $this->defaultfooterfontstyle),
12308 'L' => array ('content' => $fdet[2], 'font-size' => $this->defaultfooterfontsize, 'font-style' => $this->defaultfooterfontstyle),
12309 'line' => $this->defaultfooterline,
12310 )
12311 );
12312 }
12313 else {
12314 $this->footerDetails = array (
12315 'odd' => array (
12316 'R' => array ('content' => $Farray, 'font-size' => $this->defaultfooterfontsize, 'font-style' => $this->defaultfooterfontstyle),
12317 'line' => $this->defaultfooterline,
12318 ),
12319 'even' => array (
12320 'L' => array ('content' => $Farray, 'font-size' => $this->defaultfooterfontsize, 'font-style' => $this->defaultfooterfontstyle),
12321 'line' => $this->defaultfooterline,
12322 )
12323 );
12324 }
12325 }
12326 else if (is_array($Farray)) {
12327 if ($side=='O') { $this->footerDetails['odd'] = $Farray; }
12328 else if ($side=='E') { $this->footerDetails['even'] = $Farray; }
12329 else { $this->footerDetails = $Farray; }
12330 }
12331/*-- HTMLHEADERS-FOOTERS --*/
12332 // Overwrite any HTML Footer previously set
12333 if ($side=='E') { $this->SetHTMLFooter('','E'); }
12334 else if ($side=='O') { $this->SetHTMLFooter(''); }
12335 else {
12336 $this->SetHTMLFooter('');
12337 $this->SetHTMLFooter('','E');
12338 }
12339/*-- END HTMLHEADERS-FOOTERS --*/
12340}
12341
12342/*-- WATERMARK --*/
12343function setUnvalidatedText($txt='', $alpha=-1) {
12344 if ($alpha>=0) $this->watermarkTextAlpha = $alpha;
12345 $this->watermarkText = $txt;
12346}
12347function SetWatermarkText($txt='', $alpha=-1) {
12348 if ($alpha>=0) $this->watermarkTextAlpha = $alpha;
12349 $this->watermarkText = $txt;
12350}
12351
12352function SetWatermarkImage($src, $alpha=-1, $size='D', $pos='F') {
12353 if ($alpha>=0) $this->watermarkImageAlpha = $alpha;
12354 $this->watermarkImage = $src;
12355 $this->watermark_size = $size;
12356 $this->watermark_pos = $pos;
12357}
12358/*-- END WATERMARK --*/
12359
12360
12361//Page footer
12362function Footer() {
12363/*-- CSS-PAGE --*/
12364 // PAGED MEDIA - CROP / CROSS MARKS from @PAGE
12365 if ($this->show_marks == 'CROP' || $this->show_marks == 'CROPCROSS') {
12366 // Show TICK MARKS
12367 $this->SetLineWidth(0.1); // = 0.1 mm
12368 $this->SetDColor($this->ConvertColor(0));
12369 $l = $this->cropMarkLength;
12370 $m = $this->cropMarkMargin; // Distance of crop mark from margin
12371 $b = $this->nonPrintMargin; // Non-printable border at edge of paper sheet
12372 $ax1 = $b;
12373 $bx = $this->page_box['outer_width_LR'] - $m;
12374 $ax = max($ax1, $bx-$l);
12375 $cx1 = $this->w - $b;
12376 $dx = $this->w - $this->page_box['outer_width_LR'] + $m;
12377 $cx = min($cx1, $dx+$l);
12378 $ay1 = $b;
12379 $by = $this->page_box['outer_width_TB'] - $m;
12380 $ay = max($ay1, $by-$l);
12381 $cy1 = $this->h - $b;
12382 $dy = $this->h - $this->page_box['outer_width_TB'] + $m;
12383 $cy = min($cy1, $dy+$l);
12384
12385 $this->Line($ax, $this->page_box['outer_width_TB'], $bx, $this->page_box['outer_width_TB']);
12386 $this->Line($cx, $this->page_box['outer_width_TB'], $dx, $this->page_box['outer_width_TB']);
12387 $this->Line($ax, $this->h - $this->page_box['outer_width_TB'], $bx, $this->h - $this->page_box['outer_width_TB']);
12388 $this->Line($cx, $this->h - $this->page_box['outer_width_TB'], $dx, $this->h - $this->page_box['outer_width_TB']);
12389 $this->Line($this->page_box['outer_width_LR'], $ay, $this->page_box['outer_width_LR'], $by);
12390 $this->Line($this->page_box['outer_width_LR'], $cy, $this->page_box['outer_width_LR'], $dy);
12391 $this->Line($this->w - $this->page_box['outer_width_LR'], $ay, $this->w - $this->page_box['outer_width_LR'], $by);
12392 $this->Line($this->w - $this->page_box['outer_width_LR'], $cy, $this->w - $this->page_box['outer_width_LR'], $dy);
12393
12394 if ($this->printers_info) {
12395 $hd = date('Y-m-d H:i').' Page '.$this->page.' of {nb}';
12396 $this->SetTColor($this->ConvertColor(0));
12397 $this->SetFont('arial','',7.5,true,true);
12398 $this->x = $this->page_box['outer_width_LR'] + 1.5;
12399 $this->y = 1;
12400 $this->Cell($headerpgwidth ,$this->FontSize,$hd,0,0,'L',0,'',0,0,0,'M');
12401 $this->SetFont($this->default_font,'',$this->original_default_font_size);
12402 }
12403
12404 }
12405 if ($this->show_marks == 'CROSS' || $this->show_marks == 'CROPCROSS') {
12406 $this->SetLineWidth(0.1); // = 0.1 mm
12407 $this->SetDColor($this->ConvertColor(0));
12408 $l = 14 /2; // longer length of the cross line (half)
12409 $w = 6 /2; // shorter width of the cross line (half)
12410 $r = 1.2; // radius of circle
12411 $m = $this->crossMarkMargin; // Distance of cross mark from margin
12412 $x1 = $this->page_box['outer_width_LR'] - $m;
12413 $x2 = $this->w - $this->page_box['outer_width_LR'] + $m;
12414 $y1 = $this->page_box['outer_width_TB'] - $m;
12415 $y2 = $this->h - $this->page_box['outer_width_TB'] + $m;
12416 // Left
12417 $this->Circle($x1, $this->h/2, $r, 'S') ;
12418 $this->Line($x1-$w, $this->h/2, $x1+$w, $this->h/2);
12419 $this->Line($x1, $this->h/2-$l, $x1, $this->h/2+$l);
12420 // Right
12421 $this->Circle($x2, $this->h/2, $r, 'S') ;
12422 $this->Line($x2-$w, $this->h/2, $x2+$w, $this->h/2);
12423 $this->Line($x2, $this->h/2-$l, $x2, $this->h/2+$l);
12424 // Top
12425 $this->Circle($this->w/2, $y1, $r, 'S') ;
12426 $this->Line($this->w/2, $y1-$w, $this->w/2, $y1+$w);
12427 $this->Line($this->w/2-$l, $y1, $this->w/2+$l, $y1);
12428 // Bottom
12429 $this->Circle($this->w/2, $y2, $r, 'S') ;
12430 $this->Line($this->w/2, $y2-$w, $this->w/2, $y2+$w);
12431 $this->Line($this->w/2-$l, $y2, $this->w/2+$l, $y2);
12432 }
12433
12434
12435 // If @page set non-HTML headers/footers named, they were not read until later in the HTML code - so now set them
12436 if ($this->page==1) {
12437 if ($this->firstPageBoxHeader) {
12438 $this->headerDetails['odd'] = $this->pageheaders[$this->firstPageBoxHeader];
12439 $this->Header();
12440 }
12441 if ($this->firstPageBoxFooter) {
12442 $this->footerDetails['odd'] = $this->pagefooters[$this->firstPageBoxFooter];
12443 }
12444 $this->firstPageBoxHeader='';
12445 $this->firstPageBoxFooter='';
12446 }
12447/*-- END CSS-PAGE --*/
12448
12449
12450
12451/*-- HTMLHEADERS-FOOTERS --*/
12452 if (($this->mirrorMargins && ($this->page%2==0) && $this->HTMLFooterE) || ($this->mirrorMargins && ($this->page%2==1) && $this->HTMLFooter) || (!$this->mirrorMargins && $this->HTMLFooter)) {
12453 $this->writeHTMLFooters();
12454/*-- WATERMARK --*/
12455 if (($this->watermarkText) && ($this->showWatermarkText)) {
12456 $this->watermark( $this->watermarkText, 45, 120, $this->watermarkTextAlpha); // Watermark text
12457 }
12458 if (($this->watermarkImage) && ($this->showWatermarkImage)) {
12459 $this->watermarkImg( $this->watermarkImage, $this->watermarkImageAlpha); // Watermark image
12460 }
12461/*-- END WATERMARK --*/
12462 return;
12463 }
12464/*-- END HTMLHEADERS-FOOTERS --*/
12465
12466 $this->processingHeader=true;
12467 $this->ResetMargins(); // necessary after columns
12468 $this->pgwidth = $this->w - $this->lMargin - $this->rMargin;
12469/*-- WATERMARK --*/
12470 if (($this->watermarkText) && ($this->showWatermarkText)) {
12471 $this->watermark( $this->watermarkText, 45, 120, $this->watermarkTextAlpha); // Watermark text
12472 }
12473 if (($this->watermarkImage) && ($this->showWatermarkImage)) {
12474 $this->watermarkImg( $this->watermarkImage, $this->watermarkImageAlpha); // Watermark image
12475 }
12476/*-- END WATERMARK --*/
12477 $h = $this->footerDetails;
12478 if(count($h)) {
12479
12480 if ($this->forcePortraitHeaders && $this->CurOrientation=='L' && $this->CurOrientation!=$this->DefOrientation) {
12481 $this->_out(sprintf('q 0 -1 1 0 0 %.3F cm ',($this->h*_MPDFK)));
12482 $headerpgwidth = $this->h - $this->orig_lMargin - $this->orig_rMargin;
12483 if (($this->mirrorMargins) && (($this->page)%2==0)) { // EVEN
12484 $headerlmargin = $this->orig_rMargin;
12485 }
12486 else {
12487 $headerlmargin = $this->orig_lMargin;
12488 }
12489 }
12490 else {
12491 $yadj = 0;
12492 $headerpgwidth = $this->pgwidth;
12493 $headerlmargin = $this->lMargin;
12494 }
12495 $this->SetY(-$this->margin_footer);
12496
12497 $this->SetTColor($this->ConvertColor(0));
12498 $this->SUP = false;
12499 $this->SUB = false;
12500 $this->bullet = false;
12501
12502 // only show pagenumber if numbering on
12503 $pgno = $this->docPageNum($this->page, true);
12504
12505 if (($this->mirrorMargins) && (($this->page)%2==0)) { // EVEN
12506 $side = 'even';
12507 }
12508 else { // ODD // OR NOT MIRRORING MARGINS/FOOTERS = DEFAULT
12509 $side = 'odd';
12510 }
12511 $maxfontheight = 0;
12512 foreach(array('L','C','R') AS $pos) {
12513 if (isset($h[$side][$pos]['content']) && $h[$side][$pos]['content']) {
12514 if (isset($h[$side][$pos]['font-size']) && $h[$side][$pos]['font-size']) { $hfsz = $h[$side][$pos]['font-size']; }
12515 else { $hfsz = $this->default_font_size; }
12516 $maxfontheight = max($maxfontheight,$hfsz);
12517 }
12518 }
12519 // LEFT-CENTER-RIGHT
12520 foreach(array('L','C','R') AS $pos) {
12521 if (isset($h[$side][$pos]['content']) && $h[$side][$pos]['content']) {
12522 $hd = str_replace('{PAGENO}',$pgno,$h[$side][$pos]['content']);
12523 $hd = str_replace($this->aliasNbPgGp,$this->nbpgPrefix.$this->aliasNbPgGp.$this->nbpgSuffix,$hd);
12524 $hd = preg_replace_callback('/\{DATE\s+(.*?)\}/', array($this, 'date_callback') ,$hd); // mPDF 5.7
12525 if (isset($h[$side][$pos]['font-family']) && $h[$side][$pos]['font-family']) { $hff = $h[$side][$pos]['font-family']; }
12526 else { $hff = $this->original_default_font; }
12527 if (isset($h[$side][$pos]['font-size']) && $h[$side][$pos]['font-size']) { $hfsz = $h[$side][$pos]['font-size']; }
12528 else { $hfsz = $this->original_default_font_size; }
12529 $maxfontheight = max($maxfontheight,$hfsz);
12530 if (isset($h[$side][$pos]['font-style']) && $h[$side][$pos]['font-style']) { $hfst = $h[$side][$pos]['font-style']; }
12531 else { $hfst = ''; }
12532 if (isset($h[$side][$pos]['color']) && $h[$side][$pos]['color']) {
12533 $hfcol = $h[$side][$pos]['color'];
12534 $cor = $this->ConvertColor($hfcol);
12535 if ($cor) { $this->SetTColor($cor); }
12536 }
12537 else { $hfcol = ''; }
12538 $this->SetFont($hff,$hfst,$hfsz,true,true);
12539 $this->x = $headerlmargin ;
12540 $this->y = $this->h - $this->margin_footer - ($maxfontheight/_MPDFK);
12541 $hd = $this->purify_utf8_text($hd);
12542 if ($this->text_input_as_HTML) {
12543 $hd = $this->all_entities_to_utf8($hd);
12544 }
12545 // CONVERT CODEPAGE
12546 if ($this->usingCoreFont) { $hd = mb_convert_encoding($hd,$this->mb_enc,'UTF-8'); }
12547 // DIRECTIONALITY RTL
12548 $this->magic_reverse_dir($hd, true, $this->directionality); // *RTL*
12549 // Font-specific ligature substitution for Indic fonts
12550 if (isset($this->CurrentFont['indic']) && $this->CurrentFont['indic']) $this->ConvertIndic($hd); // *INDIC*
12551 $align = $pos;
12552 if ($this->directionality == 'rtl') {
12553 if ($pos == 'L') { $align = 'R'; }
12554 else if ($pos == 'R') { $align = 'L'; }
12555 }
12556
12557 if ($pos!='L' && (strpos($hd,$this->aliasNbPg)!==false || strpos($hd,$this->aliasNbPgGp)!==false)) {
12558 if (strpos($hd,$this->aliasNbPgGp)!==false) { $type= 'nbpggp'; } else { $type= 'nbpg'; }
12559 $this->_out('{mpdfheader'.$type.' '.$pos.' ff='.$hff.' fs='.$hfst.' fz='.$hfsz.'}');
12560 $this->Cell($headerpgwidth ,$maxfontheight/_MPDFK ,$hd,0,0,$align,0,'',0,0,0,'M');
12561 $this->_out('Q');
12562 }
12563 else {
12564 $this->Cell($headerpgwidth ,$maxfontheight/_MPDFK ,$hd,0,0,$align,0,'',0,0,0,'M');
12565 }
12566 if ($hfcol) { $this->SetTColor($this->ConvertColor(0)); }
12567 }
12568 }
12569 // Return Font to normal
12570 $this->SetFont($this->default_font,'',$this->original_default_font_size);
12571
12572 // LINE
12573
12574 if (isset($h[$side]['line']) && $h[$side]['line']) {
12575 $this->SetLineWidth(0.1);
12576 $this->SetDColor($this->ConvertColor(0));
12577 $this->Line($headerlmargin , $this->y-($maxfontheight*($this->footer_line_spacing)/_MPDFK), $headerlmargin +$headerpgwidth, $this->y-($maxfontheight*($this->footer_line_spacing)/_MPDFK));
12578 }
12579 if ($this->forcePortraitHeaders && $this->CurOrientation=='L' && $this->CurOrientation!=$this->DefOrientation) {
12580 $this->_out('Q');
12581 }
12582 }
12583 $this->processingHeader=false;
12584
12585}
12586
12587///////////////////
12588// HYPHENATION
12589///////////////////
12590// mPDF 5.6.21
12591// Hard hyphens
12592function hardHyphenate($word, $maxWidth) {
12593 // Don't hyphenate web addresses
12594 if (preg_match('/^(http:|www\.)/',$word)) { return array(false,'','',''); }
12595
12596 // Get dictionary
12597 $poss = array();
12598 $softhyphens = array();
12599 $offset = 0;
12600 $p = true;
12601 if ($this->usingCoreFont) {
12602 $wl = strlen($word);
12603 }
12604 else {
12605 $wl = mb_strlen($word,'UTF-8');
12606 }
12607 while($offset < $wl) {
12608 if (!$this->usingCoreFont) {
12609 $p = mb_strpos($word, "-", $offset, 'UTF-8');
12610 }
12611 else if ($this->FontFamily!='csymbol' && $this->FontFamily!='czapfdingbats') {
12612 $p = strpos($word, "-", $offset);
12613 }
12614 if ($p !== false) { $poss[] = $p; } // mPDF 5.7.2
12615 else { break; }
12616 $offset = $p+1;
12617 }
12618 $success = false;
12619 foreach($poss AS $i) {
12620 if ($this->usingCoreFont) {
12621 $a = substr($word,0,$i);
12622 if ($this->GetStringWidth($a.'-') > $maxWidth) { break ; }
12623 $pre = $a;
12624 $post = substr($word,$i,strlen($word));
12625 $prelength = strlen($pre);
12626 }
12627 else {
12628 $a = mb_substr($word,0,$i,'UTF-8');
12629 if ($this->GetStringWidth($a.'-') > $maxWidth) { break ; }
12630 $pre = $a;
12631 $post = mb_substr($word,$i,mb_strlen($word,'UTF-8'),'UTF-8');
12632 $prelength = mb_strlen($pre, 'UTF-8');
12633 }
12634 $success = true;
12635 }
12636 return array($success,$pre,$post,$prelength);
12637}
12638
12639
12640/*-- HYPHENATION --*/
12641///////////////////
12642///////////////////
12643// HYPHENATION
12644///////////////////
12645// Soft hyphs
12646function softHyphenate($word, $maxWidth) {
12647 // Don't hyphenate web addresses
12648 if (preg_match('/^(http:|www\.)/',$word)) { return array(false,'','',''); }
12649
12650 // Get dictionary
12651 $poss = array();
12652 $softhyphens = array();
12653 $offset = 0;
12654 $p = true;
12655 if ($this->usingCoreFont) {
12656 $wl = strlen($word);
12657 }
12658 else {
12659 $wl = mb_strlen($word,'UTF-8');
12660 }
12661 while($offset < $wl) {
12662 // Soft Hyphens chr(173)
12663 if (!$this->usingCoreFont) {
12664 $p = mb_strpos($word, "\xc2\xad", $offset, 'UTF-8');
12665 }
12666 else if ($this->FontFamily!='csymbol' && $this->FontFamily!='czapfdingbats') {
12667 $p = strpos($word, chr(173), $offset);
12668 }
12669 // mPDF 5.7.2
12670 //if ($p !== false) { $poss[] = $p - count($poss); }
12671 if ($p !== false) { $poss[] = $p; }
12672 else { break; }
12673 $offset = $p+1;
12674 }
12675 $success = false;
12676 foreach($poss AS $i) {
12677 if ($this->usingCoreFont) {
12678 $a = substr($word,0,$i);
12679 if ($this->GetStringWidth($a.'-') > $maxWidth) { break ; }
12680 $pre = $a;
12681 $post = substr($word,$i,strlen($word));
12682 $prelength = strlen($pre);
12683 }
12684 else {
12685 $a = mb_substr($word,0,$i,'UTF-8');
12686 if ($this->GetStringWidth($a.'-') > $maxWidth) { break ; }
12687 $pre = $a;
12688 $post = mb_substr($word,$i,mb_strlen($word,'UTF-8'),'UTF-8');
12689 $prelength = mb_strlen($pre, 'UTF-8');
12690 }
12691 $success = true;
12692 }
12693 return array($success,$pre,$post,$prelength);
12694}
12695
12696///////////////////
12697// Word hyphenation
12698function hyphenateWord($word, $maxWidth) {
12699 // Do everything inside this function in utf-8
12700 // Don't hyphenate web addresses
12701 if (preg_match('/^(http:|www\.)/',$word)) { return array(false,'','',''); }
12702
12703
12704 // Get dictionary
12705 if (!$this->loadedSHYdictionary) {
12706 if (file_exists(_MPDF_PATH.'patterns/dictionary.txt')) {
12707 $this->SHYdictionary = file(_MPDF_PATH.'patterns/dictionary.txt',FILE_SKIP_EMPTY_LINES);
12708 foreach($this->SHYdictionary as $entry) {
12709 $entry = trim($entry);
12710 $poss = array();
12711 $offset = 0;
12712 $p = true;
12713 $wl = mb_strlen($entry ,'UTF-8');
12714 while($offset < $wl) {
12715 $p = mb_strpos($entry, '/', $offset, 'UTF-8');
12716 if ($p !== false) { $poss[] = $p - count($poss); }
12717 else { break; }
12718 $offset = $p+1;
12719 }
12720 if (count($poss)) { $this->SHYdictionaryWords[str_replace('/', '', mb_strtolower($entry))] = $poss; }
12721 }
12722 }
12723 $this->loadedSHYdictionary = true;
12724 }
12725
12726 if (!in_array($this->SHYlang,$this->SHYlanguages)) { return array(false,'','',''); }
12727 // If no pattern loaded or not the best one
12728 if (count($this->SHYpatterns) < 1 || ($this->loadedSHYpatterns && $this->loadedSHYpatterns != $this->SHYlang)) {
12729 include(_MPDF_PATH."patterns/" . $this->SHYlang . ".php");
12730 $patterns = explode(' ', $patterns);
12731 $new_patterns = array();
12732 for($i = 0; $i < count($patterns); $i++) {
12733 $value = $patterns[$i];
12734 $new_patterns[preg_replace('/[0-9]/', '', $value)] = $value;
12735 }
12736 $this->SHYpatterns = $new_patterns;
12737 $this->loadedSHYpatterns = $this->SHYlang;
12738 }
12739
12740 if ($this->usingCoreFont) { $word = mb_convert_encoding($word,'UTF-8',$this->mb_enc); }
12741
12742 $prepre = '';
12743 $postpost = '';
12744 $startpunctuation = "\xc2\xab\xc2\xbf\xe2\x80\x98\xe2\x80\x9b\xe2\x80\x9c\xe2\x80\x9f";
12745 $endpunctuation = "\xe2\x80\x9e\xe2\x80\x9d\xe2\x80\x9a\xe2\x80\x99\xc2\xbb";
12746 $pre = '';
12747 $post = '';
12748
12749
12750 if (preg_match('/^(["\''.$startpunctuation .'])+(.{'.$this->SHYcharmin.',})$/u',$word,$m)) {
12751 $prepre = $m[1];
12752 $word = $m[2];
12753 }
12754 if (preg_match('/^(.{'.$this->SHYcharmin.',})([\'\.,;:!?"'.$endpunctuation .']+)$/u',$word,$m)) {
12755 $word = $m[1];
12756 $postpost = $m[2];
12757 }
12758 if(mb_strlen($word,'UTF-8') < $this->SHYcharmin) {
12759 return array(false,'','','');
12760 }
12761 $success = false;
12762
12763 if(isset($this->SHYdictionaryWords[mb_strtolower($word)])) {
12764 foreach($this->SHYdictionaryWords[mb_strtolower($word)] AS $i) {
12765 $a = $prepre . mb_substr($word,0,$i,'UTF-8');
12766 if ($this->usingCoreFont) { $testa = mb_convert_encoding($a,$this->mb_enc,'UTF-8'); }
12767 else { $testa = $a; }
12768 if ($this->GetStringWidth($testa.'-') > $maxWidth) { break ; }
12769 $pre = $a;
12770 $post = mb_substr($word,$i,mb_strlen($word,'UTF-8'),'UTF-8') . $postpost;
12771 $success = true;
12772 }
12773 }
12774
12775 if (!$success) {
12776 $text_word = '_' . $word . '_';
12777 $word_length = mb_strlen($text_word,'UTF-8');
12778
12779 $single_character = preg_split('//u', $text_word);
12780
12781 $text_word = mb_strtolower($text_word,'UTF-8');
12782 $hyphenated_word = array();
12783 $numb3rs = array('0' => true, '1' => true, '2' => true, '3' => true, '4' => true, '5' => true, '6' => true, '7' => true, '8' => true, '9' => true);
12784 for($position = 0; $position <= ($word_length - $this->SHYcharmin); $position++) {
12785 $maxwins = min(($word_length - $position), $this->SHYcharmax);
12786 for($win = $this->SHYcharmin; $win <= $maxwins; $win++) {
12787 if(isset($this->SHYpatterns[mb_substr($text_word, $position, $win,'UTF-8')])) {
12788 $pattern = $this->SHYpatterns[mb_substr($text_word, $position, $win,'UTF-8')];
12789 $digits = 1;
12790 $pattern_length = mb_strlen($pattern,'UTF-8');
12791 for($i = 0; $i < $pattern_length; $i++) {
12792 $char = $pattern[$i];
12793 if(isset($numb3rs[$char])) {
12794 $zero = ($i == 0) ? $position - 1 : $position + $i - $digits;
12795 if(!isset($hyphenated_word[$zero]) || $hyphenated_word[$zero] != $char) $hyphenated_word[$zero] = $char;
12796 $digits++;
12797 }
12798 }
12799 }
12800 }
12801 }
12802
12803 for($i = $this->SHYleftmin; $i <= (mb_strlen($word,'UTF-8') - $this->SHYrightmin); $i++) {
12804 if(isset($hyphenated_word[$i]) && $hyphenated_word[$i] % 2 != 0) {
12805 $a = $prepre . mb_substr($word,0,$i,'UTF-8');
12806 if ($this->usingCoreFont) { $testa = mb_convert_encoding($a,$this->mb_enc,'UTF-8'); }
12807 else { $testa = $a; }
12808 if ($this->GetStringWidth($testa.'-') > $maxWidth + 0.0001) { break ; }
12809 $pre = $a;
12810 $post = mb_substr($word,$i,mb_strlen($word,'UTF-8'),'UTF-8') . $postpost;
12811 $success = true;
12812 }
12813 }
12814 }
12815 if ($this->usingCoreFont) {
12816 $pre = mb_convert_encoding($pre,$this->mb_enc,'UTF-8');
12817 $post = mb_convert_encoding($post,$this->mb_enc,'UTF-8');
12818 $prelength = strlen($pre);
12819 }
12820 else {
12821 $prelength = mb_strlen($pre);
12822 }
12823 return array($success,$pre,$post,$prelength);
12824
12825}
12826/*-- END HYPHENATION --*/
12827
12828
12829/*-- HTML-CSS --*/
12830///////////////////
12831/// HTML parser ///
12832///////////////////
12833function WriteHTML($html,$sub=0,$init=true,$close=true) {
12834 // $sub ADDED - 0 = default; 1=headerCSS only; 2=HTML body (parts) only; 3 - HTML parses only
12835 // 4 - writes HTML headers
12836 // $close Leaves buffers etc. in current state, so that it can continue a block etc.
12837 // $init - Clears and sets buffers to Top level block etc.
12838
12839 if (empty($html)) { $html = ''; }
12840 if ($this->progressBar) { $this->UpdateProgressBar(1,0,'Parsing CSS & Headers'); } // *PROGRESS-BAR*
12841
12842 if ($init) {
12843 $this->headerbuffer='';
12844 $this->textbuffer = array();
12845 $this->fixedPosBlockSave = array();
12846 }
12847 if ($sub == 1) { $html = '<style> '.$html.' </style>'; } // stylesheet only
12848
12849 if ($this->allow_charset_conversion) {
12850 if ($sub < 1) {
12851 $this->ReadCharset($html);
12852 }
12853 if ($this->charset_in && $sub!=4) { // mPDF 5.4.14
12854 $success = iconv($this->charset_in,'UTF-8//TRANSLIT',$html);
12855 if ($success) { $html = $success; }
12856 }
12857 }
12858 $html = $this->purify_utf8($html,false);
12859 if ($init) {
12860 $this->blklvl = 0;
12861 $this->lastblocklevelchange = 0;
12862 $this->blk = array();
12863 $this->initialiseBlock($this->blk[0]);
12864 $this->blk[0]['width'] =& $this->pgwidth;
12865 $this->blk[0]['inner_width'] =& $this->pgwidth;
12866 $this->blk[0]['blockContext'] = $this->blockContext;
12867 }
12868
12869 $zproperties = array();
12870 if ($sub < 2) {
12871 $this->ReadMetaTags($html);
12872
12873 // mPDF 5.6.18
12874 if (preg_match('/<base[^>]*href=["\']([^"\'>]*)["\']/i', $html, $m)) {
12875 $this->SetBasePath($m[1]);
12876 }
12877 // NB default stylesheet now in mPDF.css - read on initialising class
12878 $html = $this->cssmgr->ReadCSS($html);
12879
12880 if ($this->useLang && !$this->usingCoreFont && preg_match('/<html [^>]*lang=[\'\"](.*?)[\'\"]/ism',$html,$m)) {
12881 $html_lang = $m[1];
12882 }
12883
12884 if (preg_match('/<html [^>]*dir=[\'\"]\s*rtl\s*[\'\"]/ism',$html)) {
12885 $zproperties['DIRECTION'] = 'rtl';
12886 }
12887
12888 // allow in-line CSS for body tag to be parsed // Get <body> tag inline CSS
12889 if (preg_match('/<body([^>]*)>(.*?)<\/body>/ism',$html,$m) || preg_match('/<body([^>]*)>(.*)$/ism',$html,$m)) {
12890 $html = $m[2];
12891 // Changed to allow style="background: url('bg.jpg')"
12892 if (preg_match('/style=[\"](.*?)[\"]/ism',$m[1],$mm) || preg_match('/style=[\'](.*?)[\']/ism',$m[1],$mm)) {
12893 $zproperties = $this->cssmgr->readInlineCSS($mm[1]);
12894 }
12895 if (preg_match('/dir=[\'\"]\s*rtl\s*[\'\"]/ism',$m[1])) {
12896 $zproperties['DIRECTION'] = 'rtl';
12897 }
12898 if (isset($html_lang) && $html_lang) { $zproperties['LANG'] = $html_lang; }
12899 if ($this->useLang && !$this->onlyCoreFonts && preg_match('/lang=[\'\"](.*?)[\'\"]/ism',$m[1],$mm)) {
12900 $zproperties['LANG'] = $mm[1];
12901 }
12902
12903 }
12904 }
12905 $properties = $this->cssmgr->MergeCSS('BLOCK','BODY','');
12906 if ($zproperties) { $properties = $this->cssmgr->array_merge_recursive_unique($properties,$zproperties); }
12907
12908 if (isset($properties['DIRECTION']) && $properties['DIRECTION']) {
12909 $this->cssmgr->CSS['BODY']['DIRECTION'] = $properties['DIRECTION'];
12910 }
12911 if (!isset($this->cssmgr->CSS['BODY']['DIRECTION'])) {
12912 $this->cssmgr->CSS['BODY']['DIRECTION'] = $this->directionality;
12913 }
12914 else { $this->SetDirectionality($this->cssmgr->CSS['BODY']['DIRECTION']); }
12915
12916 $this->setCSS($properties,'','BODY');
12917 $this->blk[0]['InlineProperties'] = $this->saveInlineProperties();
12918
12919 if ($sub == 1) { return ''; }
12920 if (!isset($this->cssmgr->CSS['BODY'])) { $this->cssmgr->CSS['BODY'] = array(); }
12921
12922/*-- BACKGROUNDS --*/
12923 if (isset($properties['BACKGROUND-GRADIENT'])) {
12924 $this->bodyBackgroundGradient = $properties['BACKGROUND-GRADIENT'];
12925 }
12926
12927 if (isset($properties['BACKGROUND-IMAGE']) && $properties['BACKGROUND-IMAGE']) {
12928 $ret = $this->SetBackground($properties, $this->pgwidth);
12929 if ($ret) { $this->bodyBackgroundImage = $ret; }
12930 }
12931/*-- END BACKGROUNDS --*/
12932
12933/*-- CSS-PAGE --*/
12934 // If page-box is set
12935 if ($this->state==0 && isset($this->cssmgr->CSS['@PAGE']) && $this->cssmgr->CSS['@PAGE'] ) {
12936 $this->page_box['current'] = '';
12937 $this->page_box['using'] = true;
12938 list($pborientation,$pbmgl,$pbmgr,$pbmgt,$pbmgb,$pbmgh,$pbmgf,$hname,$fname,$bg,$resetpagenum,$pagenumstyle,$suppress,$marks,$newformat) = $this->SetPagedMediaCSS('', false, 'O');
12939 $this->DefOrientation = $this->CurOrientation = $pborientation;
12940 $this->orig_lMargin = $this->DeflMargin = $pbmgl;
12941 $this->orig_rMargin = $this->DefrMargin = $pbmgr;
12942 $this->orig_tMargin = $this->tMargin = $pbmgt;
12943 $this->orig_bMargin = $this->bMargin = $pbmgb;
12944 $this->orig_hMargin = $this->margin_header = $pbmgh;
12945 $this->orig_fMargin = $this->margin_footer = $pbmgf;
12946 list($pborientation,$pbmgl,$pbmgr,$pbmgt,$pbmgb,$pbmgh,$pbmgf,$hname,$fname,$bg,$resetpagenum,$pagenumstyle,$suppress,$marks,$newformat) = $this->SetPagedMediaCSS('', true, 'O'); // first page
12947 $this->show_marks = $marks;
12948 if ($hname && !preg_match('/^html_(.*)$/i',$hname)) $this->firstPageBoxHeader = $hname;
12949 if ($fname && !preg_match('/^html_(.*)$/i',$fname)) $this->firstPageBoxFooter = $fname;
12950 }
12951/*-- END CSS-PAGE --*/
12952
12953 $parseonly = false;
12954 $this->bufferoutput = false;
12955 if ($sub == 3) {
12956 $parseonly = true;
12957 // Close any open block tags
12958 for ($b= $this->blklvl;$b>0;$b--) { $this->CloseTag($this->blk[$b]['tag']); }
12959 // Output any text left in buffer
12960 if (count($this->textbuffer)) { $this->printbuffer($this->textbuffer); }
12961 $this->textbuffer=array();
12962 }
12963 else if ($sub == 4) {
12964 // Close any open block tags
12965 for ($b= $this->blklvl;$b>0;$b--) { $this->CloseTag($this->blk[$b]['tag']); }
12966 // Output any text left in buffer
12967 if (count($this->textbuffer)) { $this->printbuffer($this->textbuffer); }
12968 $this->bufferoutput = true;
12969 $this->textbuffer=array();
12970 $this->headerbuffer='';
12971 $properties = $this->cssmgr->MergeCSS('BLOCK','BODY','');
12972 $this->setCSS($properties,'','BODY');
12973 }
12974
12975 mb_internal_encoding('UTF-8');
12976
12977 $html = $this->AdjustHTML($html, $this->tabSpaces); //Try to make HTML look more like XHTML
12978
12979 if ($this->autoFontGroups) { $html = $this->AutoFont($html); }
12980
12981/*-- HTMLHEADERS-FOOTERS --*/
12982 preg_match_all('/<htmlpageheader([^>]*)>(.*?)<\/htmlpageheader>/si',$html,$h);
12983 for($i=0;$i<count($h[1]);$i++) {
12984 if (preg_match('/name=[\'|\"](.*?)[\'|\"]/',$h[1][$i],$n)) {
12985 $this->pageHTMLheaders[$n[1]]['html'] = $h[2][$i];
12986 $this->pageHTMLheaders[$n[1]]['h'] = $this->_gethtmlheight($h[2][$i]);
12987 }
12988 }
12989 preg_match_all('/<htmlpagefooter([^>]*)>(.*?)<\/htmlpagefooter>/si',$html,$f);
12990 for($i=0;$i<count($f[1]);$i++) {
12991 if (preg_match('/name=[\'|\"](.*?)[\'|\"]/',$f[1][$i],$n)) {
12992 $this->pageHTMLfooters[$n[1]]['html'] = $f[2][$i];
12993 $this->pageHTMLfooters[$n[1]]['h'] = $this->_gethtmlheight($f[2][$i]);
12994 }
12995 }
12996/*-- END HTMLHEADERS-FOOTERS --*/
12997 $html = preg_replace('/<htmlpageheader.*?<\/htmlpageheader>/si','',$html);
12998 $html = preg_replace('/<htmlpagefooter.*?<\/htmlpagefooter>/si','',$html);
12999
13000 if($this->state==0 && $sub!=1 && $sub!=3 && $sub!=4) {
13001 $this->AddPage($this->CurOrientation);
13002 }
13003
13004
13005/*-- HTMLHEADERS-FOOTERS --*/
13006
13007 if (isset($hname) && preg_match('/^html_(.*)$/i',$hname,$n)) $this->SetHTMLHeader($this->pageHTMLheaders[$n[1]],'O',true);
13008 if (isset($fname) && preg_match('/^html_(.*)$/i',$fname,$n)) $this->SetHTMLFooter($this->pageHTMLfooters[$n[1]],'O');
13009
13010/*-- END HTMLHEADERS-FOOTERS --*/
13011
13012 $html=str_replace('<?','< ',$html); //Fix '<?XML' bug from HTML code generated by MS Word
13013
13014 $this->checkSIP = false;
13015 $this->checkSMP = false;
13016 $this->checkCJK = false;
13017 if ($this->onlyCoreFonts) { $html = $this->SubstituteChars($html); }
13018 else {
13019 if (preg_match("/([".$this->pregRTLchars."])/u", $html)) { $this->biDirectional = true; } // *RTL*
13020 if (preg_match("/([\x{20000}-\x{2FFFF}])/u", $html)) { $this->checkSIP = true; }
13021 if (preg_match("/([\x{10000}-\x{1FFFF}])/u", $html)) { $this->checkSMP = true; }
13022/*-- CJK-FONTS --*/
13023 if (preg_match("/([".$this->pregCJKchars."])/u", $html)) { $this->checkCJK = true; }
13024/*-- END CJK-FONTS --*/
13025 }
13026
13027 // Don't allow non-breaking spaces that are converted to substituted chars or will break anyway and mess up table width calc.
13028 $html = str_replace('<tta>160</tta>',chr(32),$html);
13029 $html = str_replace('</tta><tta>','|',$html);
13030 $html = str_replace('</tts><tts>','|',$html);
13031 $html = str_replace('</ttz><ttz>','|',$html);
13032
13033 //Add new supported tags in the DisableTags function
13034 $html=strip_tags($html,$this->enabledtags); //remove all unsupported tags, but the ones inside the 'enabledtags' string
13035
13036 //Explode the string in order to parse the HTML code
13037 $a=preg_split('/<(.*?)>/ms',$html,-1,PREG_SPLIT_DELIM_CAPTURE);
13038 // ? more accurate regexp that allows e.g. <a name="Silly <name>">
13039 // if changing - also change in fn.SubstituteChars()
13040 // $a = preg_split ('/<((?:[^<>]+(?:"[^"]*"|\'[^\']*\')?)+)>/ms', $html, -1, PREG_SPLIT_DELIM_CAPTURE);
13041
13042 if ($this->mb_enc) {
13043 mb_internal_encoding($this->mb_enc);
13044 }
13045 $pbc = 0;
13046 if ($this->progressBar) { $this->UpdateProgressBar(1,0); } // *PROGRESS-BAR*
13047 $this->subPos = -1;
13048 $cnt = count($a);
13049 for($i=0;$i<$cnt; $i++) {
13050 $e = $a[$i];
13051 if($i%2==0) {
13052 //TEXT
13053 if ($this->blk[$this->blklvl]['hide']) { continue; }
13054 if ($this->inlineDisplayOff) { continue; }
13055 if ($this->inMeter) { continue; } // mPDF 5.5.09
13056
13057 if ($this->inFixedPosBlock) { $this->fixedPosBlock .= $e; continue; } // *CSS-POSITION*
13058 if (strlen($e) == 0) { continue; }
13059
13060 $e = strcode2utf($e);
13061 $e = $this->lesser_entity_decode($e);
13062
13063 if ($this->usingCoreFont) {
13064 // If core font is selected in document which is not onlyCoreFonts - substitute with non-core font
13065 if ($this->useSubstitutions && !$this->onlyCoreFonts && $this->subPos<$i && !$this->specialcontent) {
13066 $cnt += $this->SubstituteCharsNonCore($a, $i, $e);
13067 }
13068 // CONVERT ENCODING
13069 $e = mb_convert_encoding($e,$this->mb_enc,'UTF-8');
13070 // mPDF 5.6.41
13071 if ($this->toupper) { $e = mb_strtoupper($e,$this->mb_enc); }
13072 if ($this->tolower) { $e = mb_strtolower($e,$this->mb_enc); }
13073 if ($this->capitalize) { $e = mb_convert_case($e, MB_CASE_TITLE, "UTF-8"); }
13074 }
13075 else {
13076 if ($this->checkSIP && $this->CurrentFont['sipext'] && $this->subPos<$i && !$this->specialcontent) {
13077 $cnt += $this->SubstituteCharsSIP($a, $i, $e);
13078 }
13079
13080 if ($this->useSubstitutions && !$this->onlyCoreFonts && $this->CurrentFont['type']!='Type0' && $this->subPos<$i && !$this->specialcontent) {
13081 // mPDF 5.6.62 removes U+200E/U+200F LTR and RTL mark and U+200C/U+200D Zero-width Joiner and Non-joiner
13082 $e = preg_replace("/[\xe2\x80\x8c\xe2\x80\x8d\xe2\x80\x8e\xe2\x80\x8f]/u",'',$e);
13083 $cnt += $this->SubstituteCharsMB($a, $i, $e);
13084 }
13085 if ($this->biDirectional) { // *RTL*
13086 // mPDF 5.7+
13087 $e = preg_replace_callback("/([".$this->pregRTLchars."]+)/u", array($this, 'arabJoinPregCallback'), $e ); // *RTL*
13088 } // *RTL*
13089 // Font-specific ligature substitution for Indic fonts
13090 if (isset($this->CurrentFont['indic']) && $this->CurrentFont['indic']) $this->ConvertIndic($e); // *INDIC*
13091
13092 // mPDF 5.6.62 removes U+200E/U+200F LTR and RTL mark and U+200C/U+200D Zero-width Joiner and Non-joiner
13093 $e = preg_replace("/[\xe2\x80\x8c\xe2\x80\x8d\xe2\x80\x8e\xe2\x80\x8f]/u",'',$e);
13094
13095 if ($this->toupper) { $e = mb_strtoupper($e,$this->mb_enc); }
13096 if ($this->tolower) { $e = mb_strtolower($e,$this->mb_enc); }
13097 if ($this->capitalize) { $e = mb_convert_case($e, MB_CASE_TITLE, "UTF-8"); }
13098 }
13099 if (($this->tts) || ($this->ttz) || ($this->tta)) {
13100 $es = explode('|',$e);
13101 $e = '';
13102 foreach($es AS $val) {
13103 $e .= chr($val);
13104 }
13105 }
13106 //Adjust lineheight
13107
13108 // FORM ELEMENTS
13109 if ($this->specialcontent) {
13110/*-- FORMS --*/
13111 //SELECT tag (form element)
13112 if ($this->specialcontent == "type=select") {
13113 $e = ltrim($e);
13114 $stringwidth = $this->GetStringWidth($e);
13115 if (!isset($this->selectoption['MAXWIDTH']) || $stringwidth > $this->selectoption['MAXWIDTH']) { $this->selectoption['MAXWIDTH'] = $stringwidth; }
13116 if (!isset($this->selectoption['SELECTED']) || $this->selectoption['SELECTED'] == '') { $this->selectoption['SELECTED'] = $e; }
13117 // mPDD 1.4 Active Forms
13118 if (isset($this->selectoption['ACTIVE']) && $this->selectoption['ACTIVE']) {
13119 $this->selectoption['ITEMS'][]=array('exportValue'=>$this->selectoption['currentVAL'], 'content'=>$e, 'selected'=>$this->selectoption['currentSEL']);
13120 }
13121 }
13122 // TEXTAREA
13123 else {
13124 $objattr = unserialize($this->specialcontent);
13125 $objattr['text'] = $e;
13126 $te = "\xbb\xa4\xactype=textarea,objattr=".serialize($objattr)."\xbb\xa4\xac";
13127 if ($this->tdbegin) {
13128 $this->_saveCellTextBuffer($te, $this->HREF);
13129 }
13130 else {
13131 $this->_saveTextBuffer($te, $this->HREF);
13132 }
13133 }
13134/*-- END FORMS --*/
13135 }
13136
13137 // TABLE
13138 else if ($this->tableLevel) {
13139/*-- TABLES --*/
13140 if ($this->tdbegin) {
13141 if (($this->ignorefollowingspaces) && !$this->ispre) { $e = ltrim($e); }
13142 if ($e || $e==='0') {
13143 if (($this->blockjustfinished || $this->listjustfinished) && $this->cell[$this->row][$this->col]['s']>0) {
13144 $this->_saveCellTextBuffer("\n");
13145 if (!isset($this->cell[$this->row][$this->col]['maxs'])) {
13146 $this->cell[$this->row][$this->col]['maxs'] = $this->cell[$this->row][$this->col]['s'];
13147 }
13148 elseif($this->cell[$this->row][$this->col]['maxs'] < $this->cell[$this->row][$this->col]['s']) {
13149 $this->cell[$this->row][$this->col]['maxs'] = $this->cell[$this->row][$this->col]['s'];
13150 }
13151 $this->cell[$this->row][$this->col]['s'] = 0;// reset
13152 }
13153 $this->blockjustfinished=false;
13154 $this->listjustfinished=false;
13155
13156 $this->_saveCellTextBuffer($e, $this->HREF);
13157
13158 if (!isset($this->cell[$this->row][$this->col]['R']) || !$this->cell[$this->row][$this->col]['R']) {
13159 if (isset($this->cell[$this->row][$this->col]['s'])) {
13160 $this->cell[$this->row][$this->col]['s'] += $this->GetStringWidth($e, false);
13161 }
13162 else { $this->cell[$this->row][$this->col]['s'] = $this->GetStringWidth($e, false); }
13163 if (!empty($this->spanborddet)) {
13164 $this->cell[$this->row][$this->col]['s'] += $this->spanborddet['L']['w'] + $this->spanborddet['R']['w'];
13165 }
13166 }
13167
13168 if ($this->checkCJK && preg_match("/([".$this->pregCJKchars."])/u", $e)) { $this->tableCJK = true; } // *CJK-FONTS*
13169
13170 // mPDF 5.6.13 Decimal mark alignment
13171 if (substr($this->cell[$this->row][$this->col]['a'],0,1) == 'D') {
13172 $dp = $this->decimal_align[substr($this->cell[$this->row][$this->col]['a'],0,2)];
13173 $s = preg_split('/'.preg_quote($dp,'/').'/', $e, 2); // ? needs to be /u if not core
13174 $s0 = $this->GetStringWidth($s[0], false);
13175 if ($s[1]) { $s1 = $this->GetStringWidth(($s[1].$dp), false); }
13176 else $s1 = 0;
13177 if (!isset($this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['decimal_align'][$this->col]['maxs0'])) {
13178 $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['decimal_align'][$this->col]['maxs0'] = $s0;
13179 }
13180 else {
13181 $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']);
13182 }
13183 if (!isset($this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['decimal_align'][$this->col]['maxs1'])) {
13184 $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['decimal_align'][$this->col]['maxs1'] = $s1;
13185 }
13186 else {
13187 $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']);
13188 }
13189 }
13190
13191 if ($this->tableLevel==1 && $this->useGraphs) {
13192 $this->graphs[$this->currentGraphId]['data'][$this->row][$this->col] = $e;
13193 }
13194 $this->nestedtablejustfinished = false;
13195 $this->linebreakjustfinished=false;
13196 }
13197 }
13198/*-- END TABLES --*/
13199 }
13200 // ALL ELSE
13201 else {
13202 if ($this->ignorefollowingspaces and !$this->ispre) { $e = ltrim($e); }
13203 if ($e || $e==='0') $this->_saveTextBuffer($e, $this->HREF);
13204 }
13205 }
13206
13207
13208 else { // TAG **
13209
13210 if($e[0]=='/') {
13211/*-- PROGRESS-BAR --*/
13212 if ($this->progressBar) { // 10% increments
13213 if (intval($i*10/$cnt) != $pbc) { $pbc = intval($i*10/$cnt); $this->UpdateProgressBar(1,$pbc*10,$tag); }
13214 }
13215/*-- END PROGRESS-BAR --*/
13216
13217
13218 // Check for tags where HTML specifies optional end tags,
13219 // and/or does not allow nesting e.g. P inside P, or
13220 $endtag = trim(strtoupper(substr($e,1))); // mPDF 5.4.20
13221 if($this->blk[$this->blklvl]['hide']) {
13222 if (in_array($endtag, $this->outerblocktags) || in_array($endtag, $this->innerblocktags)) {
13223 unset($this->blk[$this->blklvl]);
13224 $this->blklvl--;
13225 }
13226 continue;
13227 }
13228
13229/*-- CSS-POSITION --*/
13230 if ($this->inFixedPosBlock) {
13231 if (in_array($endtag, $this->outerblocktags) || in_array($endtag, $this->innerblocktags)) { $this->fixedPosBlockDepth--; }
13232 if ($this->fixedPosBlockDepth == 0) {
13233 $this->fixedPosBlockSave[] = array($this->fixedPosBlock, $this->fixedPosBlockBBox, $this->page);
13234 $this->fixedPosBlock = '';
13235 $this->inFixedPosBlock = false;
13236 continue;
13237 }
13238 $this->fixedPosBlock .= '<'.$e.'>';
13239 continue;
13240 }
13241/*-- END CSS-POSITION --*/
13242 if ($this->allow_html_optional_endtags && !$parseonly) {
13243 if (($endtag == 'DIV' || $endtag =='FORM' || $endtag =='CENTER') && $this->lastoptionaltag == 'P') { $this->CloseTag($this->lastoptionaltag ); }
13244 if ($this->lastoptionaltag == 'LI' && $endtag == 'OL') { $this->CloseTag($this->lastoptionaltag ); }
13245 if ($this->lastoptionaltag == 'LI' && $endtag == 'UL') { $this->CloseTag($this->lastoptionaltag ); }
13246 if ($this->lastoptionaltag == 'DD' && $endtag == 'DL') { $this->CloseTag($this->lastoptionaltag ); }
13247 if ($this->lastoptionaltag == 'DT' && $endtag == 'DL') { $this->CloseTag($this->lastoptionaltag ); }
13248 if ($this->lastoptionaltag == 'OPTION' && $endtag == 'SELECT') { $this->CloseTag($this->lastoptionaltag ); }
13249/*-- TABLES --*/
13250 if ($endtag == 'TABLE') {
13251 if ($this->lastoptionaltag == 'THEAD' || $this->lastoptionaltag == 'TBODY' || $this->lastoptionaltag == 'TFOOT') {
13252 $this->CloseTag($this->lastoptionaltag);
13253 }
13254 if ($this->lastoptionaltag == 'TR') { $this->CloseTag('TR'); }
13255 if ($this->lastoptionaltag == 'TD' || $this->lastoptionaltag == 'TH') { $this->CloseTag($this->lastoptionaltag ); $this->CloseTag('TR'); }
13256 }
13257 if ($endtag == 'THEAD' || $endtag == 'TBODY' || $endtag == 'TFOOT') {
13258 if ($this->lastoptionaltag == 'TR') { $this->CloseTag('TR'); }
13259 if ($this->lastoptionaltag == 'TD' || $this->lastoptionaltag == 'TH') { $this->CloseTag($this->lastoptionaltag ); $this->CloseTag('TR'); }
13260 }
13261 if ($endtag == 'TR') {
13262 if ($this->lastoptionaltag == 'TD' || $this->lastoptionaltag == 'TH') { $this->CloseTag($this->lastoptionaltag ); }
13263 }
13264/*-- END TABLES --*/
13265 }
13266 $this->CloseTag($endtag);
13267 }
13268
13269 else { // OPENING TAG
13270 if($this->blk[$this->blklvl]['hide']) {
13271 if (strpos($e,' ')) { $te = strtoupper(substr($e,0,strpos($e,' '))); }
13272 else { $te = strtoupper($e); }
13273 if (in_array($te, $this->outerblocktags) || in_array($te, $this->innerblocktags)) {
13274 $this->blklvl++;
13275 $this->blk[$this->blklvl]['hide']=true;
13276 }
13277 continue;
13278 }
13279
13280/*-- CSS-POSITION --*/
13281 if ($this->inFixedPosBlock) {
13282 if (strpos($e,' ')) { $te = strtoupper(substr($e,0,strpos($e,' '))); }
13283 else { $te = strtoupper($e); }
13284 $this->fixedPosBlock .= '<'.$e.'>';
13285 if (in_array($te, $this->outerblocktags) || in_array($te, $this->innerblocktags)) { $this->fixedPosBlockDepth++; }
13286 continue;
13287 }
13288/*-- END CSS-POSITION --*/
13289 $regexp = '|=\'(.*?)\'|s'; // eliminate single quotes, if any
13290 $e = preg_replace($regexp,"=\"\$1\"",$e);
13291 // changes anykey=anyvalue to anykey="anyvalue" (only do this inside [some] tags)
13292 if (substr($e,0,10)!='pageheader' && substr($e,0,10)!='pagefooter' && substr($e,0,12)!='tocpagebreak') { // mPDF 5.6.69
13293 $regexp = '| (\\w+?)=([^\\s>"]+)|si';
13294 $e = preg_replace($regexp," \$1=\"\$2\"",$e);
13295 }
13296
13297 $e = preg_replace('/ (\\S+?)\s*=\s*"/i', " \\1=\"", $e);
13298
13299 //Fix path values, if needed
13300 $orig_srcpath = '';
13301 if ((stristr($e,"href=") !== false) or (stristr($e,"src=") !== false) ) {
13302 $regexp = '/ (href|src)\s*=\s*"(.*?)"/i';
13303 preg_match($regexp,$e,$auxiliararray);
13304 if (isset($auxiliararray[2])) { $path = $auxiliararray[2]; }
13305 else { $path = ''; }
13306 if (trim($path) != '' && !(stristr($e,"src=") !== false && substr($path,0,4)=='var:')) {
13307 $orig_srcpath = $path;
13308 $this->GetFullPath($path);
13309 $regexp = '/ (href|src)="(.*?)"/i';
13310 $e = preg_replace($regexp,' \\1="'.$path.'"',$e);
13311 }
13312 }//END of Fix path values
13313
13314
13315 //Extract attributes
13316 $contents=array();
13317 $contents1=array(); // mPDF 5.5.17
13318 $contents2=array();
13319 // Changed to allow style="background: url('bg.jpg')"
13320 // mPDF 5.5.17 Changed to improve performance; maximum length of \S (attribute) = 16
13321 // mPDF 5.6.30 Increase allowed attribute name to 32 - cutting off "toc-even-header-name" etc.
13322 preg_match_all('/\\S{1,32}=["][^"]*["]/',$e,$contents1);
13323 preg_match_all('/\\S{1,32}=[\'][^\']*[\']/i',$e,$contents2);
13324
13325 $contents = array_merge($contents1, $contents2);
13326 preg_match('/\\S+/',$e,$a2);
13327 $tag=strtoupper($a2[0]);
13328 $attr=array();
13329 if ($orig_srcpath) { $attr['ORIG_SRC'] = $orig_srcpath; }
13330 if (!empty($contents)) {
13331 foreach($contents[0] as $v) {
13332 // Changed to allow style="background: url('bg.jpg')"
13333 if(preg_match('/^([^=]*)=["]?([^"]*)["]?$/',$v,$a3) || preg_match('/^([^=]*)=[\']?([^\']*)[\']?$/',$v,$a3)) {
13334 if (strtoupper($a3[1])=='ID' || strtoupper($a3[1])=='CLASS') { // 4.2.013 Omits STYLE
13335 $attr[strtoupper($a3[1])]=trim(strtoupper($a3[2]));
13336 }
13337 // includes header-style-right etc. used for <pageheader>
13338 else if (preg_match('/^(HEADER|FOOTER)-STYLE/i',$a3[1])) {
13339 $attr[strtoupper($a3[1])]=trim(strtoupper($a3[2]));
13340 }
13341 else {
13342 $attr[strtoupper($a3[1])]=trim($a3[2]);
13343 }
13344 }
13345 }
13346 }
13347 $this->OpenTag($tag,$attr);
13348/*-- CSS-POSITION --*/
13349 if ($this->inFixedPosBlock) {
13350 $this->fixedPosBlockBBox = array($tag,$attr, $this->x, $this->y);
13351 $this->fixedPosBlock = '';
13352 $this->fixedPosBlockDepth = 1;
13353 }
13354/*-- END CSS-POSITION --*/
13355 // mPDF 5.5.09
13356 if (preg_match('/\/$/',$e)) { $this->closeTag($tag); }
13357
13358 }
13359
13360 } // end TAG
13361 } //end of foreach($a as $i=>$e)
13362
13363 if ($close) {
13364
13365 // Close any open block tags
13366 for ($b= $this->blklvl;$b>0;$b--) { $this->CloseTag($this->blk[$b]['tag']); }
13367
13368 // Output any text left in buffer
13369 if (count($this->textbuffer) && !$parseonly) { $this->printbuffer($this->textbuffer); }
13370 if (!$parseonly) $this->textbuffer=array();
13371
13372/*-- CSS-FLOAT --*/
13373 // If ended with a float, need to move to end page
13374 $currpos = $this->page*1000 + $this->y;
13375 if (isset($this->blk[$this->blklvl]['float_endpos']) && $this->blk[$this->blklvl]['float_endpos'] > $currpos) {
13376 $old_page = $this->page;
13377 $new_page = intval($this->blk[$this->blklvl]['float_endpos'] /1000);
13378 if ($old_page != $new_page) {
13379 $s = $this->PrintPageBackgrounds();
13380 // Writes after the marker so not overwritten later by page background etc.
13381 $this->pages[$this->page] = preg_replace('/(___BACKGROUND___PATTERNS'.$this->uniqstr.')/', '\\1'."\n".$s."\n", $this->pages[$this->page]);
13382 $this->pageBackgrounds = array();
13383 $this->page = $new_page;
13384 $this->ResetMargins();
13385 $this->Reset();
13386 $this->pageoutput[$this->page] = array();
13387 }
13388 $this->y = (($this->blk[$this->blklvl]['float_endpos'] *1000) % 1000000)/1000; // mod changes operands to integers before processing
13389 }
13390/*-- END CSS-FLOAT --*/
13391
13392/*-- CSS-IMAGE-FLOAT --*/
13393 $this->printfloatbuffer();
13394/*-- END CSS-IMAGE-FLOAT --*/
13395
13396 //Create Internal Links, if needed
13397 if (!empty($this->internallink) ) {
13398 foreach($this->internallink as $k=>$v) {
13399 if (strpos($k,"#") !== false ) { continue; } //ignore
13400 $ypos = $v['Y'];
13401 $pagenum = $v['PAGE'];
13402 $sharp = "#";
13403 while (array_key_exists($sharp.$k,$this->internallink)) {
13404 $internallink = $this->internallink[$sharp.$k];
13405 $this->SetLink($internallink,$ypos,$pagenum);
13406 $sharp .= "#";
13407 }
13408 }
13409 }
13410
13411 $this->linemaxfontsize = '';
13412 $this->lineheight_correction = $this->default_lineheight_correction;
13413
13414 $this->bufferoutput = false;
13415
13416/*-- CSS-POSITION --*/
13417 if (count($this->fixedPosBlockSave) && $sub != 4) {
13418 foreach($this->fixedPosBlockSave AS $fpbs) {
13419 $old_page = $this->page;
13420 $this->page = $fpbs[2];
13421 $this->WriteFixedPosHTML($fpbs[0], 0, 0, 100, 100,'auto', $fpbs[1]); // 0,0,10,10 are overwritten by bbox
13422 $this->page = $old_page;
13423 }
13424 }
13425/*-- END CSS-POSITION --*/
13426
13427 }
13428}
13429
13430/*-- CSS-POSITION --*/
13431
13432function WriteFixedPosHTML($html='',$x, $y, $w, $h, $overflow='visible', $bounding=array()) {
13433 // $overflow can be 'hidden', 'visible' or 'auto' - 'auto' causes autofit to size
13434 // Annotations disabled - enabled in mPDF 5.0
13435 // Links do work
13436 // Will always go on current page (or start Page 1 if required)
13437 // Probably INCOMPATIBLE WITH keep with table, columns etc.
13438 // Called externally or interally via <div style="position: [fixed|absolute]">
13439 // When used internally, $x $y $w $h and $overflow are all overridden by $bounding
13440
13441 $overflow = strtolower($overflow);
13442 if($this->state==0) {
13443 $this->AddPage($this->CurOrientation);
13444 }
13445 $save_y = $this->y;
13446 $save_x = $this->x;
13447 $this->fullImageHeight = $this->h;
13448 $save_cols = false;
13449/*-- COLUMNS --*/
13450 if ($this->ColActive) {
13451 $save_cols = true;
13452 $save_nbcol = $this->NbCol; // other values of gap and vAlign will not change by setting Columns off
13453 $this->SetColumns(0);
13454 }
13455/*-- END COLUMNS --*/
13456 $save_annots = $this->title2annots; // *ANNOTATIONS*
13457 $this->writingHTMLheader = true; // a FIX to stop pagebreaks etc.
13458 $this->writingHTMLfooter = true;
13459 $this->InFooter = true; // suppresses autopagebreaks
13460 $save_bgs = $this->pageBackgrounds;
13461 $checkinnerhtml = preg_replace('/\s/','',$html);
13462
13463 if ($w > $this->w) { $x = 0; $w = $this->w; }
13464 if ($h > $this->h) { $y = 0; $h = $this->h; }
13465 if ($x > $this->w) { $x = $this->w - $w; }
13466 if ($y > $this->h) { $y = $this->h - $h; }
13467
13468 if (!empty($bounding)) {
13469 // $cont_ containing block = full physical page (position: absolute) or page inside margins (position: fixed)
13470 // $bbox_ Bounding box is the <div> which is positioned absolutely/fixed
13471 // top/left/right/bottom/width/height/background*/border*/padding*/margin* are taken from bounding
13472 // font*[family/size/style/weight]/line-height/text*[align/decoration/transform/indent]/color are transferred to $inner
13473 // as an enclosing <div> (after having checked ID/CLASS)
13474 // $x, $y, $w, $h are inside of $bbox_ = containing box for $inner_
13475 // $inner_ InnerHTML is the contents of that block to be output
13476 $tag = $bounding[0];
13477 $attr = $bounding[1];
13478 $orig_x0 = $bounding[2];
13479 $orig_y0 = $bounding[3];
13480
13481 // As in WriteHTML() initialising
13482 $this->blklvl = 0;
13483 $this->lastblocklevelchange = 0;
13484 $this->blk = array();
13485 $this->initialiseBlock($this->blk[0]);
13486
13487 $this->blk[0]['width'] =& $this->pgwidth;
13488 $this->blk[0]['inner_width'] =& $this->pgwidth;
13489
13490 $this->blk[0]['blockContext'] = $this->blockContext;
13491
13492 $properties = $this->cssmgr->MergeCSS('BLOCK','BODY','');
13493 $this->setCSS($properties,'','BODY');
13494 $this->blklvl = 1;
13495 $this->initialiseBlock($this->blk[1]);
13496 $this->blk[1]['tag'] = $tag;
13497 $this->blk[1]['attr'] = $attr;
13498 $this->Reset();
13499 $p = $this->cssmgr->MergeCSS('BLOCK',$tag,$attr);
13500 if (isset($p['ROTATE']) && ($p['ROTATE']==90 || $p['ROTATE']==-90)) { $rotate = $p['ROTATE']; }
13501 else { $rotate = 0; }
13502 if (isset($p['OVERFLOW'])) { $overflow = strtolower($p['OVERFLOW']); }
13503 if (strtolower($p['POSITION']) == 'fixed') {
13504 $cont_w = $this->pgwidth; // $this->blk[0]['inner_width'];
13505 $cont_h = $this->h - $this->tMargin - $this->bMargin;
13506 $cont_x = $this->lMargin;
13507 $cont_y = $this->tMargin;
13508 }
13509 else {
13510 $cont_w = $this->w; // ABSOLUTE;
13511 $cont_h = $this->h;
13512 $cont_x = 0;
13513 $cont_y = 0;
13514 }
13515
13516 // Pass on in-line properties to the innerhtml
13517 $css = '';
13518 if (isset($p['TEXT-ALIGN'])) { $css .= 'text-align: '.strtolower($p['TEXT-ALIGN']).'; '; }
13519 if (isset($p['TEXT-TRANSFORM'])) { $css .= 'text-transform: '.strtolower($p['TEXT-TRANSFORM']).'; '; }
13520 if (isset($p['TEXT-INDENT'])) { $css .= 'text-indent: '.strtolower($p['TEXT-INDENT']).'; '; }
13521 if (isset($p['TEXT-DECORATION'])) { $css .= 'text-decoration: '.strtolower($p['TEXT-DECORATION']).'; '; }
13522 if (isset($p['FONT-FAMILY'])) { $css .= 'font-family: '.strtolower($p['FONT-FAMILY']).'; '; }
13523 if (isset($p['FONT-STYLE'])) { $css .= 'font-style: '.strtolower($p['FONT-STYLE']).'; '; }
13524 if (isset($p['FONT-WEIGHT'])) { $css .= 'font-weight: '.strtolower($p['FONT-WEIGHT']).'; '; }
13525 if (isset($p['FONT-SIZE'])) { $css .= 'font-size: '.strtolower($p['FONT-SIZE']).'; '; }
13526 if (isset($p['LINE-HEIGHT'])) { $css .= 'line-height: '.strtolower($p['LINE-HEIGHT']).'; '; }
13527 if (isset($p['TEXT-SHADOW'])) { $css .= 'text-shadow: '.strtolower($p['TEXT-SHADOW']).'; '; }
13528 if (isset($p['LETTER-SPACING'])) { $css .= 'letter-spacing: '.strtolower($p['LETTER-SPACING']).'; '; }
13529 if (isset($p['FONT-VARIANT'])) { $css .= 'font-variant: '.strtolower($p['FONT-VARIANT']).'; '; }
13530 if (isset($p['COLOR'])) { $css .= 'color: '.strtolower($p['COLOR']).'; '; }
13531 if (isset($p['Z-INDEX'])) { $css .= 'z-index: '.$p['Z-INDEX'].'; '; } // mPDF 5.6.01
13532 if ($css) {
13533 $html = '<div style="'.$css.'">'.$html.'</div>';
13534 }
13535 // Copy over (only) the properties to set for border and background
13536 $pb = array();
13537 $pb['MARGIN-TOP'] = $p['MARGIN-TOP'];
13538 $pb['MARGIN-RIGHT'] = $p['MARGIN-RIGHT'];
13539 $pb['MARGIN-BOTTOM'] = $p['MARGIN-BOTTOM'];
13540 $pb['MARGIN-LEFT'] = $p['MARGIN-LEFT'];
13541 $pb['PADDING-TOP'] = $p['PADDING-TOP'];
13542 $pb['PADDING-RIGHT'] = $p['PADDING-RIGHT'];
13543 $pb['PADDING-BOTTOM'] = $p['PADDING-BOTTOM'];
13544 $pb['PADDING-LEFT'] = $p['PADDING-LEFT'];
13545 $pb['BORDER-TOP'] = $p['BORDER-TOP'];
13546 $pb['BORDER-RIGHT'] = $p['BORDER-RIGHT'];
13547 $pb['BORDER-BOTTOM'] = $p['BORDER-BOTTOM'];
13548 $pb['BORDER-LEFT'] = $p['BORDER-LEFT'];
13549 $pb['BORDER-TOP-LEFT-RADIUS-H'] = $p['BORDER-TOP-LEFT-RADIUS-H'];
13550 $pb['BORDER-TOP-LEFT-RADIUS-V'] = $p['BORDER-TOP-LEFT-RADIUS-V'];
13551 $pb['BORDER-TOP-RIGHT-RADIUS-H'] = $p['BORDER-TOP-RIGHT-RADIUS-H'];
13552 $pb['BORDER-TOP-RIGHT-RADIUS-V'] = $p['BORDER-TOP-RIGHT-RADIUS-V'];
13553 $pb['BORDER-BOTTOM-LEFT-RADIUS-H'] = $p['BORDER-BOTTOM-LEFT-RADIUS-H'];
13554 $pb['BORDER-BOTTOM-LEFT-RADIUS-V'] = $p['BORDER-BOTTOM-LEFT-RADIUS-V'];
13555 $pb['BORDER-BOTTOM-RIGHT-RADIUS-H'] = $p['BORDER-BOTTOM-RIGHT-RADIUS-H'];
13556 $pb['BORDER-BOTTOM-RIGHT-RADIUS-V'] = $p['BORDER-BOTTOM-RIGHT-RADIUS-V'];
13557 if (isset($p['BACKGROUND-COLOR'])) { $pb['BACKGROUND-COLOR'] = $p['BACKGROUND-COLOR']; }
13558 if (isset($p['BOX-SHADOW'])) { $pb['BOX-SHADOW'] = $p['BOX-SHADOW']; }
13559/*-- BACKGROUNDS --*/
13560 if (isset($p['BACKGROUND-IMAGE'])) { $pb['BACKGROUND-IMAGE'] = $p['BACKGROUND-IMAGE']; }
13561 if (isset($p['BACKGROUND-IMAGE-RESIZE'])) { $pb['BACKGROUND-IMAGE-RESIZE'] = $p['BACKGROUND-IMAGE-RESIZE']; }
13562 if (isset($p['BACKGROUND-IMAGE-OPACITY'])) { $pb['BACKGROUND-IMAGE-OPACITY'] = $p['BACKGROUND-IMAGE-OPACITY']; }
13563 if (isset($p['BACKGROUND-REPEAT'])) { $pb['BACKGROUND-REPEAT'] = $p['BACKGROUND-REPEAT']; }
13564 if (isset($p['BACKGROUND-POSITION'])) { $pb['BACKGROUND-POSITION'] = $p['BACKGROUND-POSITION']; }
13565 if (isset($p['BACKGROUND-GRADIENT'])) { $pb['BACKGROUND-GRADIENT'] = $p['BACKGROUND-GRADIENT']; }
13566 if (isset($p['BACKGROUND-SIZE'])) { $pb['BACKGROUND-SIZE'] = $p['BACKGROUND-SIZE']; } // mPDF 5.6.12
13567 if (isset($p['BACKGROUND-ORIGIN'])) { $pb['BACKGROUND-ORIGIN'] = $p['BACKGROUND-ORIGIN']; } // mPDF 5.6.12
13568 if (isset($p['BACKGROUND-CLIP'])) { $pb['BACKGROUND-CLIP'] = $p['BACKGROUND-CLIP']; } // mPDF 5.6.12
13569
13570/*-- END BACKGROUNDS --*/
13571
13572 $this->setCSS($pb,'BLOCK',$tag);
13573
13574 //================================================================
13575 $bbox_br = $this->blk[1]['border_right']['w'];
13576 $bbox_bl = $this->blk[1]['border_left']['w'];
13577 $bbox_bt = $this->blk[1]['border_top']['w'];
13578 $bbox_bb = $this->blk[1]['border_bottom']['w'];
13579 $bbox_pr = $this->blk[1]['padding_right'];
13580 $bbox_pl = $this->blk[1]['padding_left'];
13581 $bbox_pt = $this->blk[1]['padding_top'];
13582 $bbox_pb = $this->blk[1]['padding_bottom'];
13583 $bbox_mr = $this->blk[1]['margin_right'];
13584 if (strtolower($p['MARGIN-RIGHT'])=='auto') { $bbox_mr = 'auto'; }
13585 $bbox_ml = $this->blk[1]['margin_left'];
13586 if (strtolower($p['MARGIN-LEFT'])=='auto') { $bbox_ml = 'auto'; }
13587 $bbox_mt = $this->blk[1]['margin_top'];
13588 if (strtolower($p['MARGIN-TOP'])=='auto') { $bbox_mt = 'auto'; }
13589 $bbox_mb = $this->blk[1]['margin_bottom'];
13590 if (strtolower($p['MARGIN-BOTTOM'])=='auto') { $bbox_mb = 'auto'; }
13591 if (isset($p['LEFT']) && strtolower($p['LEFT'])!='auto') { $bbox_left = $this->ConvertSize($p['LEFT'], $cont_w, $this->FontSize,false); }
13592 else { $bbox_left = 'auto'; }
13593 if (isset($p['TOP']) && strtolower($p['TOP'])!='auto') { $bbox_top = $this->ConvertSize($p['TOP'], $cont_h, $this->FontSize,false); }
13594 else { $bbox_top = 'auto'; }
13595 if (isset($p['RIGHT']) && strtolower($p['RIGHT'])!='auto') { $bbox_right = $this->ConvertSize($p['RIGHT'], $cont_w, $this->FontSize,false); }
13596 else { $bbox_right = 'auto'; }
13597 if (isset($p['BOTTOM']) && strtolower($p['BOTTOM'])!='auto') { $bbox_bottom = $this->ConvertSize($p['BOTTOM'], $cont_h, $this->FontSize,false); }
13598 else { $bbox_bottom = 'auto'; }
13599 if (isset($p['WIDTH']) && strtolower($p['WIDTH'])!='auto') { $inner_w = $this->ConvertSize($p['WIDTH'], $cont_w, $this->FontSize,false); }
13600 else { $inner_w = 'auto'; }
13601 if (isset($p['HEIGHT']) && strtolower($p['HEIGHT'])!='auto') { $inner_h = $this->ConvertSize($p['HEIGHT'], $cont_h, $this->FontSize,false); }
13602 else { $inner_h = 'auto'; }
13603
13604 // If bottom or right pos are set and not left / top - save this to adjust rotated block later
13605 if ($rotate) {
13606 if ($bbox_left === 'auto' && $bbox_right !== 'auto') { $rot_rpos = $bbox_right; }
13607 else { $rot_rpos = false; }
13608 if ($bbox_top === 'auto' && $bbox_bottom !== 'auto') { $rot_bpos = $bbox_bottom; }
13609 else { $rot_bpos = false; }
13610 }
13611
13612 //================================================================
13613 if ($checkinnerhtml=='' && $inner_h==='auto') { $inner_h = 0.0001; }
13614 if ($checkinnerhtml=='' && $inner_w==='auto') { $inner_w = 2*$this->GetCharWidth('W',false); }
13615 //================================================================
13616 // Algorithm from CSS2.1 See http://www.w3.org/TR/CSS21/visudet.html#abs-non-replaced-height
13617 // mPD 5.3.14
13618 // Special case (not CSS) if all not specified, centre vertically on page
13619 if ($bbox_top==='auto' && $inner_h==='auto' && $bbox_bottom==='auto' && $bbox_mt==='auto' && $bbox_mb==='auto') {
13620 $bbox_top_orig = $bbox_top;
13621 if ($bbox_mt==='auto') { $bbox_mt = 0; }
13622 if ($bbox_mb==='auto') { $bbox_mb = 0; }
13623 $bbox_top = $orig_y0 - $bbox_mt - $cont_y;
13624 // solve for $bbox_bottom when content_h known - $inner_h=='auto' && $bbox_bottom=='auto'
13625 }
13626 // mPD 5.3.14
13627 else if ($bbox_top==='auto' && $inner_h==='auto' && $bbox_bottom==='auto') {
13628 $bbox_top_orig = $bbox_top = $orig_y0 - $cont_y;
13629 if ($bbox_mt==='auto') { $bbox_mt = 0; }
13630 if ($bbox_mb==='auto') { $bbox_mb = 0; }
13631 // solve for $bbox_bottom when content_h known - $inner_h=='auto' && $bbox_bottom=='auto'
13632 }
13633 else if ($bbox_top!=='auto' && $inner_h!=='auto' && $bbox_bottom!=='auto') {
13634 if ($bbox_mt==='auto' && $bbox_mb==='auto') {
13635 $x = $cont_h - $bbox_top - $bbox_bt - $bbox_pt - $inner_h - $bbox_pb - $bbox_bb - $bbox_bottom;
13636 $bbox_mt = $bbox_mb = ($x/2);
13637 }
13638 else if ($bbox_mt==='auto') {
13639 $bbox_mt = $cont_h - $bbox_top - $bbox_bt - $bbox_pt - $inner_h - $bbox_pb - $bbox_bb - $bbox_mb - $bbox_bottom;
13640 }
13641 else if ($bbox_mb==='auto') {
13642 $bbox_mb = $cont_h - $bbox_top - $bbox_mt - $bbox_bt - $bbox_pt - $inner_h - $bbox_pb - $bbox_bb - $bbox_bottom;
13643 }
13644 else {
13645 $bbox_bottom = $cont_h - $bbox_top - $bbox_mt - $bbox_bt - $bbox_pt - $inner_h - $bbox_pb - $bbox_bb - $bbox_mt;
13646 }
13647 }
13648 else {
13649 if ($bbox_mt==='auto') { $bbox_mt = 0; }
13650 if ($bbox_mb==='auto') { $bbox_mb = 0; }
13651 if ($bbox_top==='auto' && $inner_h==='auto' && $bbox_bottom!=='auto') {
13652 // solve for $bbox_top when content_h known - $inner_h=='auto' && $bbox_top =='auto'
13653 }
13654 else if ($bbox_top==='auto' && $bbox_bottom==='auto' && $inner_h!=='auto') {
13655 $bbox_top = $orig_y0 - $bbox_mt - $cont_y;
13656 $bbox_bottom = $cont_h - $bbox_top - $bbox_mt - $bbox_bt - $bbox_pt - $inner_h - $bbox_pb - $bbox_bb - $bbox_mt;
13657 }
13658 else if ($inner_h==='auto' && $bbox_bottom==='auto' && $bbox_top!=='auto') {
13659 // solve for $bbox_bottom when content_h known - $inner_h=='auto' && $bbox_bottom=='auto'
13660 }
13661 else if ($bbox_top==='auto' && $inner_h!=='auto' && $bbox_bottom!=='auto') {
13662 $bbox_top = $cont_h - $bbox_mt - $bbox_bt - $bbox_pt - $inner_h - $bbox_pb - $bbox_bb - $bbox_mt - $bbox_bottom;
13663 }
13664 else if ($inner_h==='auto' && $bbox_top!=='auto' && $bbox_bottom!=='auto') {
13665 $inner_h = $cont_h - $bbox_top - $bbox_mt - $bbox_bt - $bbox_pt - $bbox_pb - $bbox_bb - $bbox_mt - $bbox_bottom;
13666 }
13667 else if ($bbox_bottom==='auto' && $bbox_top!=='auto' && $inner_h!=='auto') {
13668 $bbox_bottom = $cont_h - $bbox_top - $bbox_mt - $bbox_bt - $bbox_pt - $inner_h - $bbox_pb - $bbox_bb - $bbox_mt;
13669 }
13670 }
13671
13672 // THEN DO SAME FOR WIDTH
13673 // http://www.w3.org/TR/CSS21/visudet.html#abs-non-replaced-width
13674 if ($bbox_left==='auto' && $inner_w==='auto' && $bbox_right==='auto') {
13675 if ($bbox_ml==='auto') { $bbox_ml = 0; }
13676 if ($bbox_mr==='auto') { $bbox_mr = 0; }
13677 // IF containing element RTL, should set $bbox_right
13678 $bbox_left = $orig_x0 - $bbox_ml - $cont_x;
13679 // solve for $bbox_right when content_w known - $inner_w=='auto' && $bbox_right=='auto'
13680 }
13681 else if ($bbox_left!=='auto' && $inner_w!=='auto' && $bbox_right!=='auto') {
13682 if ($bbox_ml==='auto' && $bbox_mr==='auto') {
13683 $x = $cont_w - $bbox_left - $bbox_bl - $bbox_pl - $inner_w - $bbox_pr - $bbox_br - $bbox_right;
13684 $bbox_ml = $bbox_mr = ($x/2);
13685 }
13686 else if ($bbox_ml==='auto') {
13687 $bbox_ml = $cont_w - $bbox_left - $bbox_bl - $bbox_pl - $inner_w - $bbox_pr - $bbox_br - $bbox_mr - $bbox_right;
13688 }
13689 else if ($bbox_mr==='auto') {
13690 $bbox_mr = $cont_w - $bbox_left - $bbox_ml - $bbox_bl - $bbox_pl - $inner_w - $bbox_pr - $bbox_br - $bbox_right;
13691 }
13692 else {
13693 $bbox_right = $cont_w - $bbox_left - $bbox_ml - $bbox_bl - $bbox_pl - $inner_w - $bbox_pr - $bbox_br - $bbox_ml;
13694 }
13695 }
13696 else {
13697 if ($bbox_ml==='auto') { $bbox_ml = 0; }
13698 if ($bbox_mr==='auto') { $bbox_mr = 0; }
13699 if ($bbox_left==='auto' && $inner_w==='auto' && $bbox_right!=='auto') {
13700 // solve for $bbox_left when content_w known - $inner_w=='auto' && $bbox_left =='auto'
13701 }
13702 else if ($bbox_left==='auto' && $bbox_right==='auto' && $inner_w!=='auto') {
13703 // IF containing element RTL, should set $bbox_right
13704 $bbox_left = $orig_x0 - $bbox_ml - $cont_x;
13705 $bbox_right = $cont_w - $bbox_left - $bbox_ml - $bbox_bl - $bbox_pl - $inner_w - $bbox_pr - $bbox_br - $bbox_ml;
13706 }
13707 else if ($inner_w==='auto' && $bbox_right==='auto' && $bbox_left!=='auto') {
13708 // solve for $bbox_right when content_w known - $inner_w=='auto' && $bbox_right=='auto'
13709 }
13710 else if ($bbox_left==='auto' && $inner_w!=='auto' && $bbox_right!=='auto') {
13711 $bbox_left = $cont_w - $bbox_ml - $bbox_bl - $bbox_pl - $inner_w - $bbox_pr - $bbox_br - $bbox_ml - $bbox_right;
13712 }
13713 else if ($inner_w==='auto' && $bbox_left!=='auto' && $bbox_right!=='auto') {
13714 $inner_w = $cont_w - $bbox_left - $bbox_ml - $bbox_bl - $bbox_pl - $bbox_pr - $bbox_br - $bbox_ml - $bbox_right;
13715 }
13716 else if ($bbox_right==='auto' && $bbox_left!=='auto' && $inner_w!=='auto') {
13717 $bbox_right = $cont_w - $bbox_left - $bbox_ml - $bbox_bl - $bbox_pl - $inner_w - $bbox_pr - $bbox_br - $bbox_ml;
13718 }
13719 }
13720
13721 //================================================================
13722 //================================================================
13723/*-- BACKGROUNDS --*/
13724 if (isset($pb['BACKGROUND-IMAGE']) && $pb['BACKGROUND-IMAGE']) {
13725 $ret = $this->SetBackground($pb, $this->blk[1]['inner_width']);
13726 if ($ret) { $this->blk[1]['background-image'] = $ret; }
13727 }
13728/*-- END BACKGROUNDS --*/
13729
13730 //================================================================
13731 $y = $cont_y + $bbox_top + $bbox_mt + $bbox_bt + $bbox_pt;
13732 $h = $cont_h - $bbox_top - $bbox_mt - $bbox_bt - $bbox_pt - $bbox_pb - $bbox_bb - $bbox_mb - $bbox_bottom;
13733 $x = $cont_x + $bbox_left + $bbox_ml + $bbox_bl + $bbox_pl;
13734 $w = $cont_w - $bbox_left - $bbox_ml - $bbox_bl - $bbox_pl - $bbox_pr - $bbox_br - $bbox_mr - $bbox_right;
13735 // Set (temporary) values for x y w h to do first paint, if values are auto
13736 if ($inner_h==='auto' && $bbox_top==='auto') {
13737 $y = $cont_y + $bbox_mt + $bbox_bt + $bbox_pt;
13738 $h = $cont_h - ($bbox_bottom + $bbox_mt + $bbox_mb + $bbox_bt + $bbox_bb + $bbox_pt + $bbox_pb);
13739 }
13740 else if ($inner_h==='auto' && $bbox_bottom==='auto') {
13741 $y = $cont_y + $bbox_top + $bbox_mt + $bbox_bt + $bbox_pt;
13742 $h = $cont_h - ($bbox_top + $bbox_mt + $bbox_mb + $bbox_bt + $bbox_bb + $bbox_pt + $bbox_pb);
13743 }
13744 if ($inner_w==='auto' && $bbox_left==='auto') {
13745 $x = $cont_x + $bbox_ml + $bbox_bl + $bbox_pl;
13746 $w = $cont_w - ($bbox_right + $bbox_ml + $bbox_mr + $bbox_bl + $bbox_br + $bbox_pl + $bbox_pr);
13747 }
13748 else if ($inner_w==='auto' && $bbox_right==='auto') {
13749 $x = $cont_x + $bbox_left + $bbox_ml + $bbox_bl + $bbox_pl;
13750 $w = $cont_w - ($bbox_left + $bbox_ml + $bbox_mr + $bbox_bl + $bbox_br + $bbox_pl + $bbox_pr);
13751 }
13752 $bbox_y = $cont_y + $bbox_top + $bbox_mt;
13753 $bbox_x = $cont_x + $bbox_left + $bbox_ml;
13754 $saved_block1 = $this->blk[1];
13755 unset($p);
13756 unset($pb);
13757 //================================================================
13758 if ($inner_w==='auto') { // do a first write
13759 $this->lMargin=$x;
13760 $this->rMargin=$this->w - $w - $x;
13761 // SET POSITION & FONT VALUES
13762 $this->pgwidth = $this->w - $this->lMargin - $this->rMargin;
13763 $this->pageoutput[$this->page]=array();
13764 $this->x = $x;
13765 $this->y = $y;
13766 $this->HTMLheaderPageLinks = array();
13767 $this->HTMLheaderPageAnnots = array();
13768 $this->HTMLheaderPageForms = array();
13769 $this->pageBackgrounds = array();
13770 $this->maxPosR = 0;
13771 $this->maxPosL = $this->w; // For RTL
13772 $this->WriteHTML($html , 4);
13773 $inner_w = $this->maxPosR - $this->lMargin;
13774 if ($bbox_right==='auto') {
13775 $bbox_right = $cont_w - $bbox_left - $bbox_ml - $bbox_bl - $bbox_pl - $inner_w - $bbox_pr - $bbox_br - $bbox_ml;
13776 }
13777 else if ($bbox_left==='auto') {
13778 $bbox_left = $cont_w - $bbox_ml - $bbox_bl - $bbox_pl - $inner_w - $bbox_pr - $bbox_br - $bbox_ml - $bbox_right;
13779 $bbox_x = $cont_x + $bbox_left + $bbox_ml ;
13780 $inner_x = $bbox_x + $bbox_bl + $bbox_pl;
13781 $x = $inner_x;
13782 }
13783 $w = $inner_w;
13784 $bbox_y = $cont_y + $bbox_top + $bbox_mt;
13785 $bbox_x = $cont_x + $bbox_left + $bbox_ml;
13786 }
13787
13788 if ($inner_h==='auto') { // do a first write
13789 $this->lMargin=$x;
13790 $this->rMargin=$this->w - $w - $x;
13791 // SET POSITION & FONT VALUES
13792 $this->pgwidth = $this->w - $this->lMargin - $this->rMargin;
13793 $this->pageoutput[$this->page]=array();
13794 $this->x = $x;
13795 $this->y = $y;
13796 $this->HTMLheaderPageLinks = array();
13797 $this->HTMLheaderPageAnnots = array();
13798 $this->HTMLheaderPageForms = array();
13799 $this->pageBackgrounds = array();
13800 $this->WriteHTML($html , 4);
13801 $inner_h = $this->y - $y;
13802 if ($overflow!='hidden' && $overflow!='visible') { // constrained
13803 if (($this->y + $bbox_pb + $bbox_bb) > ($cont_y + $cont_h)) {
13804 $adj = ($this->y + $bbox_pb + $bbox_bb) - ($cont_y + $cont_h);
13805 $inner_h -= $adj;
13806 }
13807 }
13808 if ($bbox_bottom==='auto' && $bbox_top_orig==='auto') {
13809 $bbox_bottom = $bbox_top = ($cont_h - $bbox_mt - $bbox_bt - $bbox_pt - $inner_h - $bbox_pb - $bbox_bb - $bbox_mb)/2;
13810 if ($overflow!='hidden' && $overflow!='visible') { // constrained
13811 if ($bbox_top < 0) {
13812 $bbox_top = 0;
13813 $inner_h = $cont_h - $bbox_top - $bbox_mt - $bbox_bt - $bbox_pt - $bbox_pb - $bbox_bb - $bbox_mb - $bbox_bottom;
13814 }
13815 }
13816 $bbox_y = $cont_y + $bbox_top + $bbox_mt;
13817 $inner_y = $bbox_y + $bbox_bt + $bbox_pt;
13818 $y = $inner_y;
13819
13820 }
13821 else if ($bbox_bottom==='auto') {
13822 $bbox_bottom = $cont_h - $bbox_top - $bbox_mt - $bbox_bt - $bbox_pt - $inner_h - $bbox_pb - $bbox_bb - $bbox_mb;
13823 }
13824 else if ($bbox_top==='auto') {
13825 $bbox_top = $cont_h - $bbox_mt - $bbox_bt - $bbox_pt - $inner_h - $bbox_pb - $bbox_bb - $bbox_mb - $bbox_bottom;
13826 if ($overflow!='hidden' && $overflow!='visible') { // constrained
13827 if ($bbox_top < 0) {
13828 $bbox_top = 0;
13829 $inner_h = $cont_h - $bbox_top - $bbox_mt - $bbox_bt - $bbox_pt - $bbox_pb - $bbox_bb - $bbox_mb - $bbox_bottom;
13830 }
13831 }
13832 $bbox_y = $cont_y + $bbox_top + $bbox_mt;
13833 $inner_y = $bbox_y + $bbox_bt + $bbox_pt;
13834 $y = $inner_y;
13835 }
13836 $h = $inner_h;
13837 $bbox_y = $cont_y + $bbox_top + $bbox_mt;
13838 $bbox_x = $cont_x + $bbox_left + $bbox_ml;
13839 }
13840 $inner_w = $w;
13841 $inner_h = $h;
13842
13843 }
13844 $this->lMargin=$x;
13845 $this->rMargin=$this->w - $w - $x;
13846 // SET POSITION & FONT VALUES
13847 $this->pgwidth = $this->w - $this->lMargin - $this->rMargin;
13848 $this->pageoutput[$this->page]=array();
13849 $this->x = $x;
13850 $this->y = $y;
13851 $this->HTMLheaderPageLinks = array();
13852 $this->HTMLheaderPageAnnots = array();
13853 $this->HTMLheaderPageForms = array();
13854 $this->pageBackgrounds = array();
13855 $this->WriteHTML($html , 4); // parameter 4 saves output to $this->headerbuffer
13856 $actual_h = $this->y - $y;
13857 $use_w = $w;
13858 $use_h = $h;
13859 $ratio = $actual_h / $use_w;
13860
13861 if ($overflow!='hidden' && $overflow!='visible') {
13862 $target = $h/$w;
13863 if (($ratio / $target ) > 1) {
13864 $nl = CEIL($actual_h / $this->lineheight);
13865 $l = $use_w * $nl;
13866 $est_w = sqrt(($l * $this->lineheight) / $target) * 0.8;
13867 $use_w += ($est_w - $use_w) - ($w/100);
13868 }
13869 $bpcstart = ($ratio / $target);
13870 $bpcctr = 1;
13871 while(($ratio / $target ) > 1) {
13872
13873 if ($this->progressBar) { $this->UpdateProgressBar(4,intval(100/($ratio/$target)),('Auto-sizing fixed-position block: '.$bpcctr++)); } // *PROGRESS-BAR*
13874
13875 $this->x = $x;
13876 $this->y = $y;
13877
13878 if (($ratio / $target) > 1.5 || ($ratio / $target) < 0.6) {
13879 $use_w += ($w/$this->incrementFPR1);
13880 }
13881 else if (($ratio / $target) > 1.2 || ($ratio / $target) < 0.85) {
13882 $use_w += ($w/$this->incrementFPR2);
13883 }
13884 else if (($ratio / $target) > 1.1 || ($ratio / $target) < 0.91) {
13885 $use_w += ($w/$this->incrementFPR3);
13886 }
13887 else {
13888 $use_w += ($w/$this->incrementFPR4);
13889 }
13890
13891 $use_h = $use_w * $target ;
13892 $this->rMargin=$this->w - $use_w - $x;
13893 $this->pgwidth = $this->w - $this->lMargin - $this->rMargin;
13894 $this->HTMLheaderPageLinks = array();
13895 $this->HTMLheaderPageAnnots = array();
13896 $this->HTMLheaderPageForms = array();
13897 $this->pageBackgrounds = array();
13898 $this->WriteHTML($html , 4); // parameter 4 saves output to $this->headerbuffer
13899 $actual_h = $this->y - $y;
13900 $ratio = $actual_h / $use_w;
13901 }
13902 if ($this->progressBar) { $this->UpdateProgressBar(4,'100',' '); } // *PROGRESS-BAR*
13903 }
13904 $shrink_f = $w/$use_w;
13905
13906 //================================================================
13907
13908 $this->pages[$this->page] .= '___BEFORE_BORDERS___';
13909 $block_s = $this->PrintPageBackgrounds(); // Save to print later inside clipping path
13910 $this->pageBackgrounds = array();
13911
13912 //================================================================
13913
13914 if ($rotate) {
13915 $prerotw = $bbox_bl + $bbox_pl + $inner_w + $bbox_pr + $bbox_br;
13916 $preroth = $bbox_bt + $bbox_pt + $inner_h + $bbox_pb + $bbox_bb;
13917 $rot_start = " q\n";
13918 if ($rotate == 90) {
13919 if ($rot_rpos !== false) { $adjw = $prerotw; } // width before rotation
13920 else { $adjw = $preroth; } // height before rotation
13921 if ($rot_bpos !== false) { $adjh = -$prerotw + $preroth; }
13922 else { $adjh = 0; }
13923 }
13924 else {
13925 if ($rot_rpos !== false) { $adjw = $prerotw - $preroth; }
13926 else { $adjw = 0; }
13927 if ($rot_bpos !== false) { $adjh = $preroth; } // height before rotation
13928 else { $adjh = $prerotw; } // width before rotation
13929 }
13930 $rot_start .= $this->transformTranslate($adjw, $adjh, true)."\n";
13931 $rot_start .= $this->transformRotate($rotate, $bbox_x, $bbox_y, true)."\n";
13932 $rot_end = " Q\n";
13933 }
13934 else {
13935 $rot_start = '';
13936 $rot_end = '';
13937 }
13938
13939 //================================================================
13940 if (!empty($bounding)) {
13941 // WHEN HEIGHT // BOTTOM EDGE IS KNOWN and $this->y is set to the bottom
13942 // Re-instate saved $this->blk[1]
13943 $this->blk[1] = $saved_block1;
13944
13945 // These are only needed when painting border/background
13946 $this->blk[1]['width'] = $bbox_w = $cont_w - $bbox_left - $bbox_ml - $bbox_mr - $bbox_right;
13947 $this->blk[1]['x0'] = $bbox_x;
13948 $this->blk[1]['y0'] = $bbox_y;
13949 $this->blk[1]['startpage'] = $this->page;
13950 $this->blk[1]['y1'] = $bbox_y + $bbox_bt + $bbox_pt + $inner_h + $bbox_pb + $bbox_bb ;
13951 $this->_out($rot_start); // mPDF 5.0
13952 $this->PaintDivBB('',0,1); // Prints borders and sets backgrounds in $this->pageBackgrounds
13953 $this->_out($rot_end);
13954 }
13955
13956 $s = $this->PrintPageBackgrounds();
13957 $s = $rot_start.$s.$rot_end;
13958 $this->pages[$this->page] = preg_replace('/___BEFORE_BORDERS___/', "\n".$s."\n", $this->pages[$this->page]);
13959 $this->pageBackgrounds = array();
13960
13961 $this->_out($rot_start);
13962
13963 // Clipping Output
13964 if ($overflow=='hidden') {
13965 //Bounding rectangle to clip
13966 $clip_y1 = $this->y;
13967 if (!empty($bounding) && ($this->y + $bbox_pb + $bbox_bb) > ($bbox_y + $bbox_bt + $bbox_pt + $inner_h + $bbox_pb + $bbox_bb )) {
13968 $clip_y1 = ($bbox_y + $bbox_bt + $bbox_pt + $inner_h + $bbox_pb + $bbox_bb ) - ($bbox_pb + $bbox_bb);
13969 }
13970 //$op = 'W* n'; // Clipping
13971 $op = 'W n'; // Clipping alternative mode
13972 $this->_out("q");
13973 $ch = $clip_y1 - $y;
13974 $this->_out(sprintf('%.3F %.3F %.3F %.3F re %s',$x*_MPDFK,($this->h-$y)*_MPDFK,$w*_MPDFK,-$ch*_MPDFK,$op));
13975 if (!empty($block_s)) {
13976 $tmp = "q\n".sprintf('%.3F %.3F %.3F %.3F re %s',$x*_MPDFK,($this->h-$y)*_MPDFK,$w*_MPDFK,-$ch*_MPDFK,$op);
13977 $tmp .= "\n".$block_s."\nQ";
13978 $block_s = $tmp ;
13979 }
13980 }
13981
13982
13983 if (!empty($block_s)) {
13984 if ($shrink_f != 1) { // i.e. autofit has resized the box
13985 $tmp = "q\n".$this->transformScale(($shrink_f*100),($shrink_f*100), $x, $y, true);
13986 $tmp .= "\n".$block_s."\nQ";
13987 $block_s = $tmp ;
13988 }
13989 $this->_out($block_s);
13990 }
13991
13992
13993
13994 if ($shrink_f != 1) { // i.e. autofit has resized the box
13995 $this->StartTransform();
13996 $this->transformScale(($shrink_f*100),($shrink_f*100), $x, $y);
13997 }
13998
13999 $this->_out($this->headerbuffer);
14000
14001 if ($shrink_f != 1) { // i.e. autofit has resized the box
14002 $this->StopTransform();
14003 }
14004
14005 if ($overflow=='hidden') {
14006 //End clipping
14007 $this->_out("Q");
14008 }
14009
14010 $this->_out($rot_end);
14011
14012
14013 // Page Links
14014 foreach($this->HTMLheaderPageLinks AS $lk) {
14015 if ($rotate) {
14016 $tmp = $lk[2]; // Switch h - w
14017 $lk[2] = $lk[3];
14018 $lk[3] = $tmp;
14019
14020 $lx1 = (($lk[0]/_MPDFK));
14021 $ly1 = (($this->h-($lk[1]/_MPDFK)));
14022 if ($rotate == 90) {
14023 $adjx = -($lx1-$bbox_x) + ($preroth - ($ly1-$bbox_y));
14024 $adjy = -($ly1-$bbox_y) + ($lx1-$bbox_x);
14025 $lk[2] = -$lk[2];
14026 }
14027 else if ($rotate == -90) {
14028 $adjx = -($lx1-$bbox_x) + ($ly1-$bbox_y);
14029 $adjy = -($ly1-$bbox_y) - ($lx1-$bbox_x) + $prerotw;
14030 $lk[3] = -$lk[3];
14031 }
14032 if ($rot_rpos !== false) { $adjx += $prerotw - $preroth; }
14033 if ($rot_bpos !== false) { $adjy += $preroth - $prerotw; }
14034 $lx1 += $adjx;
14035 $ly1 += $adjy;
14036
14037 $lk[0] = $lx1*_MPDFK;
14038 $lk[1] = ($this->h-$ly1)*_MPDFK;
14039 }
14040 if ($shrink_f != 1) { // i.e. autofit has resized the box
14041 $lx1 = (($lk[0]/_MPDFK)-$x);
14042 $lx2 = $x + ($lx1 * $shrink_f);
14043 $lk[0] = $lx2*_MPDFK;
14044 $ly1 = (($this->h-($lk[1]/_MPDFK))-$y);
14045 $ly2 = $y + ($ly1 * $shrink_f);
14046 $lk[1] = ($this->h-$ly2)*_MPDFK;
14047 $lk[2] *= $shrink_f; // width
14048 $lk[3] *= $shrink_f; // height
14049 }
14050 $this->PageLinks[$this->page][]=$lk;
14051 }
14052
14053 foreach($this->HTMLheaderPageForms AS $n=>$f) {
14054 if ($shrink_f != 1) { // i.e. autofit has resized the box
14055 $f['x'] = $x + (($f['x'] -$x) * $shrink_f);
14056 $f['y'] = $y + (($f['y'] -$y) * $shrink_f);
14057 $f['w'] *= $shrink_f;
14058 $f['h'] *= $shrink_f;
14059 $f['style']['fontsize'] *= $shrink_f;
14060 }
14061 $this->form->forms[$f['n']] = $f;
14062 }
14063 // Page Annotations
14064 foreach($this->HTMLheaderPageAnnots AS $lk) {
14065 if ($rotate) {
14066 if ($rotate == 90) {
14067 $adjx = -($lk['x']-$bbox_x) + ($preroth - ($lk['y']-$bbox_y));
14068 $adjy = -($lk['y']-$bbox_y) + ($lk['x']-$bbox_x);
14069 }
14070 else if ($rotate == -90) {
14071 $adjx = -($lk['x']-$bbox_x) + ($lk['y']-$bbox_y);
14072 $adjy = -($lk['y']-$bbox_y) - ($lk['x']-$bbox_x) + $prerotw;
14073 }
14074 if ($rot_rpos !== false) { $adjx += $prerotw - $preroth; }
14075 if ($rot_bpos !== false) { $adjy += $preroth - $prerotw; }
14076 $lk['x'] += $adjx;
14077 $lk['y'] += $adjy;
14078 }
14079 if ($shrink_f != 1) { // i.e. autofit has resized the box
14080 $lk['x'] = $x + (($lk['x']-$x) * $shrink_f);
14081 $lk['y'] = $y + (($lk['y']-$y) * $shrink_f);
14082 }
14083 $this->PageAnnots[$this->page][]=$lk;
14084 }
14085
14086 // Restore
14087 $this->headerbuffer = '';
14088 $this->HTMLheaderPageLinks = array();
14089 $this->HTMLheaderPageAnnots = array();
14090 $this->HTMLheaderPageForms = array();
14091 $this->pageBackgrounds = $save_bgs;
14092 $this->writingHTMLheader = false;
14093
14094 $this->writingHTMLfooter = false;
14095 $this->fullImageHeight = false;
14096 $this->ResetMargins();
14097 $this->pgwidth = $this->w - $this->lMargin - $this->rMargin;
14098 $this->SetXY($save_x,$save_y) ;
14099 $this->title2annots = $save_annots; // *ANNOTATIONS*
14100 $this->InFooter = false; // turns back on autopagebreaks
14101 $this->pageoutput[$this->page]=array();
14102 $this->pageoutput[$this->page]['Font']='';
14103/*-- COLUMNS --*/
14104 if ($save_cols) {
14105 $this->SetColumns($save_nbcol,$this->colvAlign,$this->ColGap);
14106 }
14107/*-- END COLUMNS --*/
14108}
14109/*-- END CSS-POSITION --*/
14110
14111
14112
14113function initialiseBlock(&$blk) {
14114 $blk['margin_top'] = 0;
14115 $blk['margin_left'] = 0;
14116 $blk['margin_bottom'] = 0;
14117 $blk['margin_right'] = 0;
14118 $blk['padding_top'] = 0;
14119 $blk['padding_left'] = 0;
14120 $blk['padding_bottom'] = 0;
14121 $blk['padding_right'] = 0;
14122 $blk['border_top']['w'] = 0;
14123 $blk['border_left']['w'] = 0;
14124 $blk['border_bottom']['w'] = 0;
14125 $blk['border_right']['w'] = 0;
14126 $blk['hide'] = false;
14127 $blk['outer_left_margin'] = 0;
14128 $blk['outer_right_margin'] = 0;
14129 $blk['cascadeCSS'] = array();
14130 $blk['block-align'] = false;
14131 $blk['bgcolor'] = false;
14132 $blk['page_break_after_avoid'] = false;
14133 $blk['keep_block_together'] = false;
14134 $blk['float'] = false;
14135 $blk['line_height'] = '';
14136 $blk['margin_collapse'] = false;
14137}
14138
14139
14140function border_details($bd) {
14141 $prop = preg_split('/\s+/',trim($bd));
14142
14143 if (isset($this->blk[$this->blklvl]['inner_width'])) { $refw = $this->blk[$this->blklvl]['inner_width']; }
14144 else if (isset($this->blk[$this->blklvl-1]['inner_width'])) { $refw = $this->blk[$this->blklvl-1]['inner_width']; }
14145 else { $refw = $this->w; }
14146 if ( count($prop) == 1 ) {
14147 $bsize = $this->ConvertSize($prop[0],$refw,$this->FontSize,false);
14148 if ($bsize > 0) {
14149 return array('s' => 1, 'w' => $bsize, 'c' => $this->ConvertColor(0), 'style'=>'solid');
14150 }
14151 else { return array('w' => 0, 's' => 0); }
14152 }
14153
14154 else if (count($prop) == 2 ) {
14155 // 1px solid
14156 if (in_array($prop[1],$this->borderstyles) || $prop[1] == 'none' || $prop[1] == 'hidden' ) { $prop[2] = ''; }
14157 // solid #000000
14158 else if (in_array($prop[0],$this->borderstyles) || $prop[0] == 'none' || $prop[0] == 'hidden' ) { $prop[0] = ''; $prop[1] = $prop[0]; $prop[2] = $prop[1]; }
14159 // 1px #000000
14160 else { $prop[1] = ''; $prop[2] = $prop[1]; }
14161 }
14162 else if ( count($prop) == 3 ) {
14163 // Change #000000 1px solid to 1px solid #000000 (proper)
14164 if (substr($prop[0],0,1) == '#') { $tmp = $prop[0]; $prop[0] = $prop[1]; $prop[1] = $prop[2]; $prop[2] = $tmp; }
14165 // Change solid #000000 1px to 1px solid #000000 (proper)
14166 else if (substr($prop[0],1,1) == '#') { $tmp = $prop[1]; $prop[0] = $prop[2]; $prop[1] = $prop[0]; $prop[2] = $tmp; }
14167 // Change solid 1px #000000 to 1px solid #000000 (proper)
14168 else if (in_array($prop[0],$this->borderstyles) || $prop[0] == 'none' || $prop[0] == 'hidden' ) {
14169 $tmp = $prop[0]; $prop[0] = $prop[1]; $prop[1] = $tmp;
14170 }
14171 }
14172 else { return array(); }
14173 // Size
14174 $bsize = $this->ConvertSize($prop[0],$refw,$this->FontSize,false);
14175 //color
14176 $coul = $this->ConvertColor($prop[2]); // returns array
14177 // Style
14178 $prop[1] = strtolower($prop[1]);
14179 if (in_array($prop[1],$this->borderstyles) && $bsize > 0) { $on = 1; }
14180 else if ($prop[1] == 'hidden') { $on = 1; $bsize = 0; $coul = ''; }
14181 else if ($prop[1] == 'none') { $on = 0; $bsize = 0; $coul = ''; }
14182 else { $on = 0; $bsize = 0; $coul = ''; $prop[1] = ''; }
14183 return array('s' => $on, 'w' => $bsize, 'c' => $coul, 'style'=> $prop[1] );
14184}
14185
14186
14187
14188/*-- END HTML-CSS --*/
14189
14190
14191// Return either a number (factor) - based on current set fontsize (if % or em) - or exact lineheight (with 'mm' after it)
14192function fixLineheight($v) {
14193 $lh = false;
14194 if (preg_match('/^[0-9\.,]*$/',$v) && $v >= 0) { return ($v + 0); }
14195 else if (strtoupper($v) == 'NORMAL') {
14196 return $this->normalLineheight;
14197 }
14198 else {
14199 $tlh = $this->ConvertSize($v,$this->FontSize,$this->FontSize,true);
14200 if ($tlh) { return ($tlh.'mm'); }
14201 }
14202 return $this->normalLineheight;
14203}
14204
14205
14206/*-- BORDER-RADIUS --*/
14207function _borderPadding($a, $b, &$px, &$py) {
14208 // $px and py are padding long axis (x) and short axis (y)
14209 $added = 0; // extra padding
14210
14211 $x = $a-$px;
14212 $y = $b-$py;
14213 // Check if Falls within ellipse of border radius
14214 if ( ( (($x+$added)*($x+$added))/($a*$a) + (($y+$added)*($y+$added))/($b*$b) ) <=1 ) { return false; }
14215
14216 $t = atan2($y,$x);
14217
14218 $newx = $b / sqrt((($b*$b)/($a*$a)) + ( tan($t) * tan($t) ) );
14219 $newy = $a / sqrt((($a*$a)/($b*$b)) + ( (1/tan($t)) * (1/tan($t)) ) );
14220 $px = max($px, $a - $newx + $added);
14221 $py = max($py, $b - $newy + $added);
14222}
14223/*-- END BORDER-RADIUS --*/
14224
14225
14226
14227/*-- HTML-CSS --*/
14228
14229
14230/*-- CSS-PAGE --*/
14231function SetPagedMediaCSS($name='', $first, $oddEven) {
14232 if ($oddEven == 'E') {
14233 if ($this->directionality=='rtl') { $side = 'R'; }
14234 else { $side = 'L'; }
14235 }
14236 else {
14237 if ($this->directionality=='rtl') { $side = 'L'; }
14238 else { $side = 'R'; }
14239 }
14240 $name = strtoupper($name);
14241 $p = array();
14242 $p['SIZE'] = 'AUTO';
14243
14244 // Uses mPDF original margins as default
14245 $p['MARGIN-RIGHT'] = strval($this->orig_rMargin).'mm';
14246 $p['MARGIN-LEFT'] = strval($this->orig_lMargin).'mm';
14247 $p['MARGIN-TOP'] = strval($this->orig_tMargin).'mm';
14248 $p['MARGIN-BOTTOM'] = strval($this->orig_bMargin).'mm';
14249 $p['MARGIN-HEADER'] = strval($this->orig_hMargin).'mm';
14250 $p['MARGIN-FOOTER'] = strval($this->orig_fMargin).'mm';
14251
14252 // Basic page + selector
14253 if (isset($this->cssmgr->CSS['@PAGE'])) { $zp = $this->cssmgr->CSS['@PAGE']; }
14254 else { $zp = array(); }
14255 if (is_array($zp) && !empty($zp)) { $p = array_merge($p,$zp); }
14256
14257 if (isset($p['EVEN-HEADER-NAME']) && $oddEven=='E') {
14258 $p['HEADER'] = $p['EVEN-HEADER-NAME']; unset($p['EVEN-HEADER-NAME']);
14259 }
14260 if (isset($p['ODD-HEADER-NAME']) && $oddEven!='E') {
14261 $p['HEADER'] = $p['ODD-HEADER-NAME']; unset($p['ODD-HEADER-NAME']);
14262 }
14263 if (isset($p['EVEN-FOOTER-NAME']) && $oddEven=='E') {
14264 $p['FOOTER'] = $p['EVEN-FOOTER-NAME']; unset($p['EVEN-FOOTER-NAME']);
14265 }
14266 if (isset($p['ODD-FOOTER-NAME']) && $oddEven!='E') {
14267 $p['FOOTER'] = $p['ODD-FOOTER-NAME']; unset($p['ODD-FOOTER-NAME']);
14268 }
14269
14270 // If right/Odd page
14271 if (isset($this->cssmgr->CSS['@PAGE>>PSEUDO>>RIGHT']) && $side=='R') {
14272 $zp = $this->cssmgr->CSS['@PAGE>>PSEUDO>>RIGHT'];
14273 }
14274 else { $zp = array(); }
14275 if (isset($zp['SIZE'])) { unset($zp['SIZE']); }
14276 if (isset($zp['SHEET-SIZE'])) { unset($zp['SHEET-SIZE']); }
14277 // Disallow margin-left or -right on :LEFT or :RIGHT
14278 if (isset($zp['MARGIN-LEFT'])) { unset($zp['MARGIN-LEFT']); }
14279 if (isset($zp['MARGIN-RIGHT'])) { unset($zp['MARGIN-RIGHT']); }
14280 if (is_array($zp) && !empty($zp)) { $p = array_merge($p,$zp); }
14281
14282 // If left/Even page
14283 if (isset($this->cssmgr->CSS['@PAGE>>PSEUDO>>LEFT']) && $side=='L') {
14284 $zp = $this->cssmgr->CSS['@PAGE>>PSEUDO>>LEFT'];
14285 }
14286 else { $zp = array(); }
14287 if (isset($zp['SIZE'])) { unset($zp['SIZE']); }
14288 if (isset($zp['SHEET-SIZE'])) { unset($zp['SHEET-SIZE']); }
14289 // Disallow margin-left or -right on :LEFT or :RIGHT
14290 if (isset($zp['MARGIN-LEFT'])) { unset($zp['MARGIN-LEFT']); }
14291 if (isset($zp['MARGIN-RIGHT'])) { unset($zp['MARGIN-RIGHT']); }
14292 if (is_array($zp) && !empty($zp)) { $p = array_merge($p,$zp); }
14293
14294 // If first page
14295 if (isset($this->cssmgr->CSS['@PAGE>>PSEUDO>>FIRST']) && $first) { $zp = $this->cssmgr->CSS['@PAGE>>PSEUDO>>FIRST']; }
14296 else { $zp = array(); }
14297 if (isset($zp['SIZE'])) { unset($zp['SIZE']); }
14298 if (isset($zp['SHEET-SIZE'])) { unset($zp['SHEET-SIZE']); }
14299 if (is_array($zp) && !empty($zp)) { $p = array_merge($p,$zp); }
14300
14301 // If named page
14302 if ($name) {
14303 if (isset($this->cssmgr->CSS['@PAGE>>NAMED>>'.$name])) { $zp = $this->cssmgr->CSS['@PAGE>>NAMED>>'.$name]; }
14304 else { $zp = array(); }
14305 if (is_array($zp) && !empty($zp)) { $p = array_merge($p,$zp); }
14306
14307 if (isset($p['EVEN-HEADER-NAME']) && $oddEven=='E') {
14308 $p['HEADER'] = $p['EVEN-HEADER-NAME']; unset($p['EVEN-HEADER-NAME']);
14309 }
14310 if (isset($p['ODD-HEADER-NAME']) && $oddEven!='E') {
14311 $p['HEADER'] = $p['ODD-HEADER-NAME']; unset($p['ODD-HEADER-NAME']);
14312 }
14313 if (isset($p['EVEN-FOOTER-NAME']) && $oddEven=='E') {
14314 $p['FOOTER'] = $p['EVEN-FOOTER-NAME']; unset($p['EVEN-FOOTER-NAME']);
14315 }
14316 if (isset($p['ODD-FOOTER-NAME']) && $oddEven!='E') {
14317 $p['FOOTER'] = $p['ODD-FOOTER-NAME']; unset($p['ODD-FOOTER-NAME']);
14318 }
14319
14320 // If named right/Odd page
14321 if (isset($this->cssmgr->CSS['@PAGE>>NAMED>>'.$name.'>>PSEUDO>>RIGHT']) && $side=='R') { $zp = $this->cssmgr->CSS['@PAGE>>NAMED>>'.$name.'>>PSEUDO>>RIGHT']; }
14322 else { $zp = array(); }
14323 if (isset($zp['SIZE'])) { unset($zp['SIZE']); }
14324 if (isset($zp['SHEET-SIZE'])) { unset($zp['SHEET-SIZE']); }
14325 // Disallow margin-left or -right on :LEFT or :RIGHT
14326 if (isset($zp['MARGIN-LEFT'])) { unset($zp['MARGIN-LEFT']); }
14327 if (isset($zp['MARGIN-RIGHT'])) { unset($zp['MARGIN-RIGHT']); }
14328 if (is_array($zp) && !empty($zp)) { $p = array_merge($p,$zp); }
14329
14330 // If named left/Even page
14331 if (isset($this->cssmgr->CSS['@PAGE>>NAMED>>'.$name.'>>PSEUDO>>LEFT']) && $side=='L') { $zp = $this->cssmgr->CSS['@PAGE>>NAMED>>'.$name.'>>PSEUDO>>LEFT']; }
14332 else { $zp = array(); }
14333 if (isset($zp['SIZE'])) { unset($zp['SIZE']); }
14334 if (isset($zp['SHEET-SIZE'])) { unset($zp['SHEET-SIZE']); }
14335 // Disallow margin-left or -right on :LEFT or :RIGHT
14336 if (isset($zp['MARGIN-LEFT'])) { unset($zp['MARGIN-LEFT']); }
14337 if (isset($zp['MARGIN-RIGHT'])) { unset($zp['MARGIN-RIGHT']); }
14338 if (is_array($zp) && !empty($zp)) { $p = array_merge($p,$zp); }
14339
14340 // If named first page
14341 if (isset($this->cssmgr->CSS['@PAGE>>NAMED>>'.$name.'>>PSEUDO>>FIRST']) && $first) { $zp = $this->cssmgr->CSS['@PAGE>>NAMED>>'.$name.'>>PSEUDO>>FIRST']; }
14342 else { $zp = array(); }
14343 if (isset($zp['SIZE'])) { unset($zp['SIZE']); }
14344 if (isset($zp['SHEET-SIZE'])) { unset($zp['SHEET-SIZE']); }
14345 if (is_array($zp) && !empty($zp)) { $p = array_merge($p,$zp); }
14346 }
14347
14348 $orientation = $mgl = $mgr = $mgt = $mgb = $mgh = $mgf = '';
14349 $header = $footer = '';
14350 $resetpagenum = $pagenumstyle = $suppress = '';
14351 $marks = '';
14352 $bg = array();
14353
14354 $newformat = '';
14355
14356
14357 if (isset($p['SHEET-SIZE']) && is_array($p['SHEET-SIZE'])) {
14358 $newformat = $p['SHEET-SIZE'];
14359 if ($newformat[0] > $newformat[1]) { // landscape
14360 $newformat = array_reverse($newformat);
14361 $p['ORIENTATION'] = 'L';
14362 }
14363 else { $p['ORIENTATION'] = 'P'; }
14364 $this->_setPageSize($newformat, $p['ORIENTATION']);
14365 }
14366
14367 if (isset($p['SIZE']) && is_array($p['SIZE']) && !$newformat) {
14368 if ($p['SIZE']['W'] > $p['SIZE']['H']) { $p['ORIENTATION'] = 'L'; }
14369 else { $p['ORIENTATION'] = 'P'; }
14370 }
14371 if (is_array($p['SIZE'])) {
14372 if ($p['SIZE']['W'] > $this->fw) { $p['SIZE']['W'] = $this->fw; } // mPD 4.2 use fw not fPt
14373 if ($p['SIZE']['H'] > $this->fh) { $p['SIZE']['H'] = $this->fh; }
14374 if (($p['ORIENTATION']==$this->DefOrientation && !$newformat) || ($newformat && $p['ORIENTATION']=='P')) {
14375 $outer_width_LR = ($this->fw - $p['SIZE']['W'])/2;
14376 $outer_width_TB = ($this->fh - $p['SIZE']['H'])/2;
14377 }
14378 else {
14379 $outer_width_LR = ($this->fh - $p['SIZE']['W'])/2;
14380 $outer_width_TB = ($this->fw - $p['SIZE']['H'])/2;
14381 }
14382 $pgw = $p['SIZE']['W'];
14383 $pgh = $p['SIZE']['H'];
14384 }
14385 else { // AUTO LANDSCAPE PORTRAIT
14386 $outer_width_LR = 0;
14387 $outer_width_TB = 0;
14388 if (!$newformat) {
14389 if (strtoupper($p['SIZE']) == 'AUTO') { $p['ORIENTATION']=$this->DefOrientation; }
14390 else if (strtoupper($p['SIZE']) == 'LANDSCAPE') { $p['ORIENTATION']='L'; }
14391 else { $p['ORIENTATION']='P'; }
14392 }
14393 if (($p['ORIENTATION']==$this->DefOrientation && !$newformat) || ($newformat && $p['ORIENTATION']=='P')) {
14394 $pgw = $this->fw;
14395 $pgh = $this->fh;
14396 }
14397 else {
14398 $pgw = $this->fh;
14399 $pgh = $this->fw;
14400 }
14401 }
14402
14403 if (isset($p['HEADER']) && $p['HEADER']) { $header = $p['HEADER']; }
14404 if (isset($p['FOOTER']) && $p['FOOTER']) { $footer = $p['FOOTER']; }
14405 if (isset($p['RESETPAGENUM']) && $p['RESETPAGENUM']) { $resetpagenum = $p['RESETPAGENUM']; }
14406 if (isset($p['PAGENUMSTYLE']) && $p['PAGENUMSTYLE']) { $pagenumstyle = $p['PAGENUMSTYLE']; }
14407 if (isset($p['SUPPRESS']) && $p['SUPPRESS']) { $suppress = $p['SUPPRESS']; }
14408
14409 if (preg_match('/cross/i', $p['MARKS']) && preg_match('/crop/i', $p['MARKS'])) { $marks = 'CROPCROSS'; }
14410 else if (strtoupper($p['MARKS']) == 'CROP') { $marks = 'CROP'; }
14411 else if (strtoupper($p['MARKS']) == 'CROSS') { $marks = 'CROSS'; }
14412
14413
14414 if (isset($p['BACKGROUND-COLOR']) && $p['BACKGROUND-COLOR']) { $bg['BACKGROUND-COLOR'] = $p['BACKGROUND-COLOR']; }
14415/*-- BACKGROUNDS --*/
14416 if (isset($p['BACKGROUND-GRADIENT']) && $p['BACKGROUND-GRADIENT']) { $bg['BACKGROUND-GRADIENT'] = $p['BACKGROUND-GRADIENT']; }
14417 if (isset($p['BACKGROUND-IMAGE']) && $p['BACKGROUND-IMAGE']) { $bg['BACKGROUND-IMAGE'] = $p['BACKGROUND-IMAGE']; }
14418 if (isset($p['BACKGROUND-REPEAT']) && $p['BACKGROUND-REPEAT']) { $bg['BACKGROUND-REPEAT'] = $p['BACKGROUND-REPEAT']; }
14419 if (isset($p['BACKGROUND-POSITION']) && $p['BACKGROUND-POSITION']) { $bg['BACKGROUND-POSITION'] = $p['BACKGROUND-POSITION']; }
14420 if (isset($p['BACKGROUND-IMAGE-RESIZE']) && $p['BACKGROUND-IMAGE-RESIZE']) { $bg['BACKGROUND-IMAGE-RESIZE'] = $p['BACKGROUND-IMAGE-RESIZE']; }
14421 if (isset($p['BACKGROUND-IMAGE-OPACITY'])) { $bg['BACKGROUND-IMAGE-OPACITY'] = $p['BACKGROUND-IMAGE-OPACITY']; }
14422/*-- END BACKGROUNDS --*/
14423
14424 if (isset($p['MARGIN-LEFT'])) { $mgl = $this->ConvertSize($p['MARGIN-LEFT'],$pgw) + $outer_width_LR; }
14425 if (isset($p['MARGIN-RIGHT'])) { $mgr = $this->ConvertSize($p['MARGIN-RIGHT'],$pgw) + $outer_width_LR; }
14426 if (isset($p['MARGIN-BOTTOM'])) { $mgb = $this->ConvertSize($p['MARGIN-BOTTOM'],$pgh) + $outer_width_TB; }
14427 if (isset($p['MARGIN-TOP'])) { $mgt = $this->ConvertSize($p['MARGIN-TOP'],$pgh) + $outer_width_TB; }
14428 if (isset($p['MARGIN-HEADER'])) { $mgh = $this->ConvertSize($p['MARGIN-HEADER'],$pgh) + $outer_width_TB; }
14429 if (isset($p['MARGIN-FOOTER'])) { $mgf = $this->ConvertSize($p['MARGIN-FOOTER'],$pgh) + $outer_width_TB; }
14430
14431 if (isset($p['ORIENTATION']) && $p['ORIENTATION']) { $orientation = $p['ORIENTATION']; }
14432 $this->page_box['outer_width_LR'] = $outer_width_LR; // Used in MARKS:crop etc.
14433 $this->page_box['outer_width_TB'] = $outer_width_TB;
14434
14435 return array($orientation,$mgl,$mgr,$mgt,$mgb,$mgh,$mgf,$header,$footer,$bg,$resetpagenum,$pagenumstyle,$suppress,$marks,$newformat);
14436}
14437/*-- END CSS-PAGE --*/
14438
14439
14440
14441/*-- CSS-FLOAT --*/
14442// Added mPDF 3.0 Float DIV - CLEAR
14443function ClearFloats($clear, $blklvl=0) {
14444 list($l_exists, $r_exists, $l_max, $r_max, $l_width, $r_width) = $this->GetFloatDivInfo($blklvl,true);
14445 $end = $currpos = ($this->page*1000 + $this->y);
14446 if ($clear == 'BOTH' && ($l_exists || $r_exists)) {
14447 $this->pageoutput[$this->page] = array();
14448 $end = max($l_max, $r_max, $currpos);
14449 }
14450 else if ($clear == 'RIGHT' && $r_exists) {
14451 $this->pageoutput[$this->page] = array();
14452 $end = max($r_max, $currpos);
14453 }
14454 else if ($clear == 'LEFT' && $l_exists ) {
14455 $this->pageoutput[$this->page] = array();
14456 $end = max($l_max, $currpos);
14457 }
14458 else { return; }
14459 $old_page = $this->page;
14460 $new_page = intval($end/1000);
14461 if ($old_page != $new_page) {
14462 $s = $this->PrintPageBackgrounds();
14463 // Writes after the marker so not overwritten later by page background etc.
14464 $this->pages[$this->page] = preg_replace('/(___BACKGROUND___PATTERNS'.$this->uniqstr.')/', '\\1'."\n".$s."\n", $this->pages[$this->page]);
14465 $this->pageBackgrounds = array();
14466 $this->page = $new_page;
14467 }
14468 $this->ResetMargins();
14469 $this->pageoutput[$this->page] = array();
14470 $this->y = (($end*1000) % 1000000)/1000; // mod changes operands to integers before processing
14471}
14472
14473
14474// Added mPDF 3.0 Float DIV
14475function GetFloatDivInfo($blklvl=0,$clear=false) {
14476 // If blklvl specified, only returns floats at that level - for ClearFloats
14477 $l_exists = false;
14478 $r_exists = false;
14479 $l_max = 0;
14480 $r_max = 0;
14481 $l_width = 0;
14482 $r_width = 0;
14483 if (count($this->floatDivs)) {
14484 $currpos = ($this->page*1000 + $this->y);
14485 foreach($this->floatDivs AS $f) {
14486 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'])) {
14487 if ($f['side']=='L') {
14488 $l_exists= true;
14489 $l_max = max($l_max, $f['endpos']);
14490 $l_width = max($l_width , $f['w']);
14491 }
14492 if ($f['side']=='R') {
14493 $r_exists= true;
14494 $r_max = max($r_max, $f['endpos']);
14495 $r_width = max($r_width , $f['w']);
14496 }
14497 }
14498 }
14499 }
14500 return array($l_exists, $r_exists, $l_max, $r_max, $l_width, $r_width);
14501}
14502/*-- END CSS-FLOAT --*/
14503
14504
14505
14506
14507function OpenTag($tag,$attr)
14508{
14509
14510 // What this gets: < $tag $attr['WIDTH']="90px" > does not get content here </closeTag here>
14511 // Correct tags where HTML specifies optional end tags,
14512 // and/or does not allow nesting e.g. P inside P, or
14513 if ($this->allow_html_optional_endtags) {
14514 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 ); }
14515 if ($tag == 'DD' && $this->lastoptionaltag == 'DD') { $this->CloseTag($this->lastoptionaltag ); }
14516 if ($tag == 'DD' && $this->lastoptionaltag == 'DT') { $this->CloseTag($this->lastoptionaltag ); }
14517 if ($tag == 'DT' && $this->lastoptionaltag == 'DD') { $this->CloseTag($this->lastoptionaltag ); }
14518 if ($tag == 'DT' && $this->lastoptionaltag == 'DT') { $this->CloseTag($this->lastoptionaltag ); }
14519 if ($tag == 'LI' && $this->lastoptionaltag == 'LI') { $this->CloseTag($this->lastoptionaltag ); }
14520 if (($tag == 'TD' || $tag == 'TH') && $this->lastoptionaltag == 'TD') { $this->CloseTag($this->lastoptionaltag ); } // *TABLES*
14521 if (($tag == 'TD' || $tag == 'TH') && $this->lastoptionaltag == 'TH') { $this->CloseTag($this->lastoptionaltag ); } // *TABLES*
14522 if ($tag == 'TR' && $this->lastoptionaltag == 'TR') { $this->CloseTag($this->lastoptionaltag ); } // *TABLES*
14523 if ($tag == 'TR' && $this->lastoptionaltag == 'TD') { $this->CloseTag($this->lastoptionaltag ); $this->CloseTag('TR'); $this->CloseTag('THEAD'); } // *TABLES*
14524 if ($tag == 'TR' && $this->lastoptionaltag == 'TH') { $this->CloseTag($this->lastoptionaltag ); $this->CloseTag('TR'); $this->CloseTag('THEAD'); } // *TABLES*
14525 if ($tag == 'OPTION' && $this->lastoptionaltag == 'OPTION') { $this->CloseTag($this->lastoptionaltag ); }
14526 }
14527
14528 $align = array('left'=>'L','center'=>'C','right'=>'R','top'=>'T','text-top'=>'TT','middle'=>'M','baseline'=>'BS','bottom'=>'B','text-bottom'=>'TB','justify'=>'J');
14529
14530 $this->ignorefollowingspaces=false;
14531
14532 //Opening tag
14533 switch($tag){
14534
14535 case 'DOTTAB':
14536 $objattr = array();
14537 $objattr['type'] = 'dottab';
14538 $dots=str_repeat('.', 3)." "; // minimum number of dots
14539 $objattr['width'] = $this->GetStringWidth($dots);
14540 $objattr['margin_top'] = 0;
14541 $objattr['margin_bottom'] = 0;
14542 $objattr['margin_left'] = 0;
14543 $objattr['margin_right'] = 0;
14544 $objattr['height'] = 0;
14545 $objattr['colorarray'] = $this->colorarray;
14546 $objattr['border_top']['w'] = 0;
14547 $objattr['border_bottom']['w'] = 0;
14548 $objattr['border_left']['w'] = 0;
14549 $objattr['border_right']['w'] = 0;
14550
14551 // mPDF 5.6.19
14552 $properties = $this->cssmgr->MergeCSS('INLINE',$tag,$attr); // mPDF 5.6.33
14553 if (isset($properties['OUTDENT'])) { // mPDF 5.6.33
14554 $objattr['outdent'] = $this->ConvertSize($properties['OUTDENT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
14555 }
14556 else if (isset($attr['OUTDENT'])) {
14557 $objattr['outdent'] = $this->ConvertSize($attr['OUTDENT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
14558 }
14559 else { $objattr['outdent'] = 0; }
14560
14561 $objattr['fontfamily'] = $this->FontFamily;
14562 $objattr['fontsize'] = $this->FontSizePt;
14563
14564 $e = "\xbb\xa4\xactype=dottab,objattr=".serialize($objattr)."\xbb\xa4\xac";
14565/*-- TABLES --*/
14566 // Output it to buffers
14567 if ($this->tableLevel) {
14568 if (!isset($this->cell[$this->row][$this->col]['maxs'])) {
14569 $this->cell[$this->row][$this->col]['maxs'] = $this->cell[$this->row][$this->col]['s'];
14570 }
14571 elseif($this->cell[$this->row][$this->col]['maxs'] < $this->cell[$this->row][$this->col]['s']) {
14572 $this->cell[$this->row][$this->col]['maxs'] = $this->cell[$this->row][$this->col]['s'];
14573 }
14574 $this->cell[$this->row][$this->col]['s'] = 0 ;// reset
14575 $this->_saveCellTextBuffer($e);
14576 }
14577 else {
14578/*-- END TABLES --*/
14579 $this->_saveTextBuffer($e);
14580 } // *TABLES*
14581 break;
14582
14583 case 'PAGEHEADER':
14584 case 'PAGEFOOTER':
14585 $this->ignorefollowingspaces = true;
14586 if ($attr['NAME']) { $pname = $attr['NAME']; }
14587 else { $pname = '_default'; }
14588
14589 if ($tag=='PAGEHEADER') { $p = &$this->pageheaders[$pname]; }
14590 else { $p = &$this->pagefooters[$pname]; }
14591
14592 $p['L']=array();
14593 $p['C']=array();
14594 $p['R']=array();
14595 $p['L']['font-style'] = '';
14596 $p['C']['font-style'] = '';
14597 $p['R']['font-style'] = '';
14598
14599 if (isset($attr['CONTENT-LEFT'])) {
14600 $p['L']['content'] = $attr['CONTENT-LEFT'];
14601 }
14602 if (isset($attr['CONTENT-CENTER'])) {
14603 $p['C']['content'] = $attr['CONTENT-CENTER'];
14604 }
14605 if (isset($attr['CONTENT-RIGHT'])) {
14606 $p['R']['content'] = $attr['CONTENT-RIGHT'];
14607 }
14608
14609 if (isset($attr['HEADER-STYLE']) || isset($attr['FOOTER-STYLE'])) { // font-family,size,weight,style,color
14610 if ($tag=='PAGEHEADER') { $properties = $this->cssmgr->readInlineCSS($attr['HEADER-STYLE']); }
14611 else { $properties = $this->cssmgr->readInlineCSS($attr['FOOTER-STYLE']); }
14612 if (isset($properties['FONT-FAMILY'])) {
14613 $p['L']['font-family'] = $properties['FONT-FAMILY'];
14614 $p['C']['font-family'] = $properties['FONT-FAMILY'];
14615 $p['R']['font-family'] = $properties['FONT-FAMILY'];
14616 }
14617 if (isset($properties['FONT-SIZE'])) {
14618 $p['L']['font-size'] = $this->ConvertSize($properties['FONT-SIZE']) * _MPDFK;
14619 $p['C']['font-size'] = $this->ConvertSize($properties['FONT-SIZE']) * _MPDFK;
14620 $p['R']['font-size'] = $this->ConvertSize($properties['FONT-SIZE']) * _MPDFK;
14621 }
14622 if (isset($properties['FONT-WEIGHT']) && $properties['FONT-WEIGHT']=='bold') {
14623 $p['L']['font-style'] = 'B';
14624 $p['C']['font-style'] = 'B';
14625 $p['R']['font-style'] = 'B';
14626 }
14627 if (isset($properties['FONT-STYLE']) && $properties['FONT-STYLE']=='italic') {
14628 $p['L']['font-style'] .= 'I';
14629 $p['C']['font-style'] .= 'I';
14630 $p['R']['font-style'] .= 'I';
14631 }
14632 if (isset($properties['COLOR'])) {
14633 $p['L']['color'] = $properties['COLOR'];
14634 $p['C']['color'] = $properties['COLOR'];
14635 $p['R']['color'] = $properties['COLOR'];
14636 }
14637 }
14638 if (isset($attr['HEADER-STYLE-LEFT']) || isset($attr['FOOTER-STYLE-LEFT'])) {
14639 if ($tag=='PAGEHEADER') { $properties = $this->cssmgr->readInlineCSS($attr['HEADER-STYLE-LEFT']); }
14640 else { $properties = $this->cssmgr->readInlineCSS($attr['FOOTER-STYLE-LEFT']); }
14641 if (isset($properties['FONT-FAMILY'])) { $p['L']['font-family'] = $properties['FONT-FAMILY']; }
14642 if (isset($properties['FONT-SIZE'])) { $p['L']['font-size'] = $this->ConvertSize($properties['FONT-SIZE']) * _MPDFK; }
14643 if (isset($properties['FONT-WEIGHT']) && $properties['FONT-WEIGHT']=='bold') { $p['L']['font-style'] ='B'; }
14644 if (isset($properties['FONT-STYLE']) && $properties['FONT-STYLE']=='italic') { $p['L']['font-style'] .='I'; }
14645 if (isset($properties['COLOR'])) { $p['L']['color'] = $properties['COLOR']; }
14646 }
14647 if (isset($attr['HEADER-STYLE-CENTER']) || isset($attr['FOOTER-STYLE-CENTER'])) {
14648 if ($tag=='PAGEHEADER') { $properties = $this->cssmgr->readInlineCSS($attr['HEADER-STYLE-CENTER']); }
14649 else { $properties = $this->cssmgr->readInlineCSS($attr['FOOTER-STYLE-CENTER']); }
14650 if (isset($properties['FONT-FAMILY'])) { $p['C']['font-family'] = $properties['FONT-FAMILY']; }
14651 if (isset($properties['FONT-SIZE'])) { $p['C']['font-size'] = $this->ConvertSize($properties['FONT-SIZE']) * _MPDFK; }
14652 if (isset($properties['FONT-WEIGHT']) && $properties['FONT-WEIGHT']=='bold') { $p['C']['font-style'] = 'B'; }
14653 if (isset($properties['FONT-STYLE']) && $properties['FONT-STYLE']=='italic') { $p['C']['font-style'] .= 'I'; }
14654 if (isset($properties['COLOR'])) { $p['C']['color'] = $properties['COLOR']; }
14655 }
14656 if (isset($attr['HEADER-STYLE-RIGHT']) || isset($attr['FOOTER-STYLE-RIGHT'])) {
14657 if ($tag=='PAGEHEADER') { $properties = $this->cssmgr->readInlineCSS($attr['HEADER-STYLE-RIGHT']); }
14658 else { $properties = $this->cssmgr->readInlineCSS($attr['FOOTER-STYLE-RIGHT']); }
14659 if (isset($properties['FONT-FAMILY'])) { $p['R']['font-family'] = $properties['FONT-FAMILY']; }
14660 if (isset($properties['FONT-SIZE'])) { $p['R']['font-size'] = $this->ConvertSize($properties['FONT-SIZE']) * _MPDFK; }
14661 if (isset($properties['FONT-WEIGHT']) && $properties['FONT-WEIGHT']=='bold') { $p['R']['font-style'] = 'B'; }
14662 if (isset($properties['FONT-STYLE']) && $properties['FONT-STYLE']=='italic') { $p['R']['font-style'] .= 'I'; }
14663 if (isset($properties['COLOR'])) { $p['R']['color'] = $properties['COLOR']; }
14664 }
14665 if (isset($attr['LINE']) && $attr['LINE']) { // 0|1|on|off
14666 if ($attr['LINE']=='1' || strtoupper($attr['LINE'])=='ON') { $lineset=1; }
14667 else { $lineset=0; }
14668 $p['line'] = $lineset;
14669 }
14670 break;
14671
14672
14673/*-- HTMLHEADERS-FOOTERS --*/
14674 case 'SETHTMLPAGEHEADER':
14675 case 'SETHTMLPAGEFOOTER':
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 (isset($attr['SHOW-THIS-PAGE']) && $attr['SHOW-THIS-PAGE'] && $tag=='SETHTMLPAGEHEADER') { $write = 1; }
14693 else { $write = 0; }
14694 if ($side=='odd' || $side=='both') {
14695 if ($set && $tag=='SETHTMLPAGEHEADER') { $this->SetHTMLHeader($this->pageHTMLheaders[$pname],'O',$write); }
14696 else if ($set && $tag=='SETHTMLPAGEFOOTER') { $this->SetHTMLFooter($this->pageHTMLfooters[$pname],'O'); }
14697 else if ($tag=='SETHTMLPAGEHEADER') { $this->SetHTMLHeader('','O'); }
14698 else { $this->SetHTMLFooter('','O'); }
14699 }
14700 if ($side=='even' || $side=='both') {
14701 if ($set && $tag=='SETHTMLPAGEHEADER') { $this->SetHTMLHeader($this->pageHTMLheaders[$pname],'E',$write); }
14702 else if ($set && $tag=='SETHTMLPAGEFOOTER') { $this->SetHTMLFooter($this->pageHTMLfooters[$pname],'E'); }
14703 else if ($tag=='SETHTMLPAGEHEADER') { $this->SetHTMLHeader('','E'); }
14704 else { $this->SetHTMLFooter('','E'); }
14705 }
14706 break;
14707/*-- END HTMLHEADERS-FOOTERS --*/
14708
14709 case 'SETPAGEHEADER':
14710 case 'SETPAGEFOOTER':
14711 $this->ignorefollowingspaces = true;
14712 if (isset($attr['NAME']) && $attr['NAME']) { $pname = $attr['NAME']; }
14713 else { $pname = '_default'; }
14714 if (isset($attr['PAGE']) && $attr['PAGE']) { // O|odd|even|E|ALL|[blank]
14715 if (strtoupper($attr['PAGE'])=='O' || strtoupper($attr['PAGE'])=='ODD') { $side='odd'; }
14716 else if (strtoupper($attr['PAGE'])=='E' || strtoupper($attr['PAGE'])=='EVEN') { $side='even'; }
14717 else if (strtoupper($attr['PAGE'])=='ALL') { $side='both'; }
14718 else { $side='odd'; }
14719 }
14720 else { $side='odd'; }
14721 if (isset($attr['VALUE']) && $attr['VALUE']) { // -1|1|on|off
14722 if ($attr['VALUE']=='1' || strtoupper($attr['VALUE'])=='ON') { $set=1; }
14723 else if ($attr['VALUE']=='-1' || strtoupper($attr['VALUE'])=='OFF') { $set=0; }
14724 else { $set=1; }
14725 }
14726 else { $set=1; }
14727 if ($side=='odd' || $side=='both') {
14728 if ($set && $tag=='SETPAGEHEADER') { $this->headerDetails['odd'] = $this->pageheaders[$pname]; }
14729 else if ($set && $tag=='SETPAGEFOOTER') { $this->footerDetails['odd'] = $this->pagefooters[$pname]; }
14730 else if ($tag=='SETPAGEHEADER') { $this->headerDetails['odd'] = array(); }
14731 else { $this->footerDetails['odd'] = array(); }
14732 if (!$this->mirrorMargins || ($this->page)%2!=0) { // ODD
14733 if ($tag=='SETPAGEHEADER') { $this->_setAutoHeaderHeight($this->headerDetails['odd'],$this->HTMLHeader); }
14734 if ($tag=='SETPAGEFOOTER') { $this->_setAutoFooterHeight($this->footerDetails['odd'],$this->HTMLFooter); }
14735 }
14736 }
14737 if ($side=='even' || $side=='both') {
14738 if ($set && $tag=='SETPAGEHEADER') { $this->headerDetails['even'] = $this->pageheaders[$pname]; }
14739 else if ($set && $tag=='SETPAGEFOOTER') { $this->footerDetails['even'] = $this->pagefooters[$pname]; }
14740 else if ($tag=='SETPAGEHEADER') { $this->headerDetails['even'] = array(); }
14741 else { $this->footerDetails['even'] = array(); }
14742 if ($this->mirrorMargins && ($this->page)%2==0) { // EVEN
14743 if ($tag=='SETPAGEHEADER') { $this->_setAutoHeaderHeight($this->headerDetails['even'],$this->HTMLHeaderE); }
14744 if ($tag=='SETPAGEFOOTER') { $this->_setAutoFooterHeight($this->footerDetails['even'],$this->HTMLFooterE); }
14745 }
14746 }
14747 if (isset($attr['SHOW-THIS-PAGE']) && $attr['SHOW-THIS-PAGE'] && $tag=='SETPAGEHEADER') {
14748 $this->Header();
14749 }
14750 break;
14751
14752
14753/*-- TOC --*/
14754 case 'TOC': //added custom-tag - set Marker for insertion later of ToC
14755 if (!class_exists('tocontents', false)) { include(_MPDF_PATH.'classes/tocontents.php'); }
14756 if (empty($this->tocontents)) { $this->tocontents = new tocontents($this); }
14757 $this->tocontents->openTagTOC($attr);
14758 break;
14759
14760
14761
14762 case 'TOCPAGEBREAK': // custom-tag - set Marker for insertion later of ToC AND adds PAGEBREAK
14763 if (!class_exists('tocontents', false)) { include(_MPDF_PATH.'classes/tocontents.php'); }
14764 if (empty($this->tocontents)) { $this->tocontents = new tocontents($this); }
14765 list($isbreak,$toc_id) = $this->tocontents->openTagTOCPAGEBREAK($attr);
14766 if ($isbreak) break;
14767 // No break - continues as PAGEBREAK...
14768/*-- END TOC --*/
14769
14770
14771 case 'PAGE_BREAK': //custom-tag
14772 case 'PAGEBREAK': //custom-tag
14773 case 'NEWPAGE': //custom-tag
14774 case 'FORMFEED': //custom-tag
14775
14776 $save_blklvl = $this->blklvl;
14777 $save_blk = $this->blk;
14778 $save_silp = $this->saveInlineProperties();
14779 $save_spanlvl = $this->spanlvl;
14780 $save_ilp = $this->InlineProperties;
14781
14782 // Close any open block tags
14783 for ($b= $this->blklvl;$b>0;$b--) { $this->CloseTag($this->blk[$b]['tag']); }
14784 if(!empty($this->textbuffer)) { //Output previously buffered content
14785 $this->printbuffer($this->textbuffer);
14786 $this->textbuffer=array();
14787 }
14788 $this->ignorefollowingspaces = true;
14789 $save_cols = false;
14790/*-- COLUMNS --*/
14791 if ($this->ColActive) {
14792 $save_cols = true;
14793 $save_nbcol = $this->NbCol; // other values of gap and vAlign will not change by setting Columns off
14794 $this->SetColumns(0);
14795 }
14796/*-- END COLUMNS --*/
14797
14798
14799 if (isset($attr['SHEET-SIZE']) && $tag != 'FORMFEED' && !$this->restoreBlockPageBreaks) {
14800 // Convert to same types as accepted in initial mPDF() A4, A4-L, or array(w,h)
14801 $prop = preg_split('/\s+/',trim($attr['SHEET-SIZE']));
14802 if (count($prop) == 2 ) {
14803 $newformat = array($this->ConvertSize($prop[0]), $this->ConvertSize($prop[1]));
14804 }
14805 else { $newformat = $attr['SHEET-SIZE']; }
14806 }
14807 else { $newformat = ''; }
14808
14809 $mgr = $mgl = $mgt = $mgb = $mgh = $mgf = '';
14810 if (isset($attr['MARGIN-RIGHT'])) { $mgr = $this->ConvertSize($attr['MARGIN-RIGHT'],$this->w,$this->FontSize,false); }
14811 if (isset($attr['MARGIN-LEFT'])) { $mgl = $this->ConvertSize($attr['MARGIN-LEFT'],$this->w,$this->FontSize,false); }
14812 if (isset($attr['MARGIN-TOP'])) { $mgt = $this->ConvertSize($attr['MARGIN-TOP'],$this->w,$this->FontSize,false); }
14813 if (isset($attr['MARGIN-BOTTOM'])) { $mgb = $this->ConvertSize($attr['MARGIN-BOTTOM'],$this->w,$this->FontSize,false); }
14814 if (isset($attr['MARGIN-HEADER'])) { $mgh = $this->ConvertSize($attr['MARGIN-HEADER'],$this->w,$this->FontSize,false); }
14815 if (isset($attr['MARGIN-FOOTER'])) { $mgf = $this->ConvertSize($attr['MARGIN-FOOTER'],$this->w,$this->FontSize,false); }
14816 $ohname = $ehname = $ofname = $efname = '';
14817 if (isset($attr['ODD-HEADER-NAME'])) { $ohname = $attr['ODD-HEADER-NAME']; }
14818 if (isset($attr['EVEN-HEADER-NAME'])) { $ehname = $attr['EVEN-HEADER-NAME']; }
14819 if (isset($attr['ODD-FOOTER-NAME'])) { $ofname = $attr['ODD-FOOTER-NAME']; }
14820 if (isset($attr['EVEN-FOOTER-NAME'])) { $efname = $attr['EVEN-FOOTER-NAME']; }
14821 $ohvalue = $ehvalue = $ofvalue = $efvalue = 0;
14822 if (isset($attr['ODD-HEADER-VALUE']) && ($attr['ODD-HEADER-VALUE']=='1' || strtoupper($attr['ODD-HEADER-VALUE'])=='ON')) { $ohvalue = 1; }
14823 else if (isset($attr['ODD-HEADER-VALUE']) && ($attr['ODD-HEADER-VALUE']=='-1' || strtoupper($attr['ODD-HEADER-VALUE'])=='OFF')) { $ohvalue = -1; }
14824 if (isset($attr['EVEN-HEADER-VALUE']) && ($attr['EVEN-HEADER-VALUE']=='1' || strtoupper($attr['EVEN-HEADER-VALUE'])=='ON')) { $ehvalue = 1; }
14825 else if (isset($attr['EVEN-HEADER-VALUE']) && ($attr['EVEN-HEADER-VALUE']=='-1' || strtoupper($attr['EVEN-HEADER-VALUE'])=='OFF')) { $ehvalue = -1; }
14826 if (isset($attr['ODD-FOOTER-VALUE']) && ($attr['ODD-FOOTER-VALUE']=='1' || strtoupper($attr['ODD-FOOTER-VALUE'])=='ON')) { $ofvalue = 1; }
14827 else if (isset($attr['ODD-FOOTER-VALUE']) && ($attr['ODD-FOOTER-VALUE']=='-1' || strtoupper($attr['ODD-FOOTER-VALUE'])=='OFF')) { $ofvalue = -1; }
14828 if (isset($attr['EVEN-FOOTER-VALUE']) && ($attr['EVEN-FOOTER-VALUE']=='1' || strtoupper($attr['EVEN-FOOTER-VALUE'])=='ON')) { $efvalue = 1; }
14829 else if (isset($attr['EVEN-FOOTER-VALUE']) && ($attr['EVEN-FOOTER-VALUE']=='-1' || strtoupper($attr['EVEN-FOOTER-VALUE'])=='OFF')) { $efvalue = -1; }
14830
14831 if (isset($attr['ORIENTATION']) && (strtoupper($attr['ORIENTATION'])=='L' || strtoupper($attr['ORIENTATION'])=='LANDSCAPE')) { $orient = 'L'; }
14832 else if (isset($attr['ORIENTATION']) && (strtoupper($attr['ORIENTATION'])=='P' || strtoupper($attr['ORIENTATION'])=='PORTRAIT')) { $orient = 'P'; }
14833 else { $orient = $this->CurOrientation; }
14834
14835 if (isset($attr['PAGE-SELECTOR']) && $attr['PAGE-SELECTOR']) { $pagesel = $attr['PAGE-SELECTOR']; }
14836 else { $pagesel = ''; }
14837
14838 $resetpagenum = '';
14839 $pagenumstyle = '';
14840 $suppress = '';
14841 if (isset($attr['RESETPAGENUM'])) { $resetpagenum = $attr['RESETPAGENUM']; }
14842 if (isset($attr['PAGENUMSTYLE'])) { $pagenumstyle = $attr['PAGENUMSTYLE']; }
14843 if (isset($attr['SUPPRESS'])) { $suppress = $attr['SUPPRESS']; }
14844
14845 if ($tag == 'TOCPAGEBREAK') { $type = 'NEXT-ODD'; }
14846 else if(isset($attr['TYPE'])) { $type = strtoupper($attr['TYPE']); }
14847 else { $type = ''; }
14848
14849 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); }
14850 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); }
14851 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); }
14852 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); }
14853 else { $this->AddPage($orient,'', $resetpagenum, $pagenumstyle, $suppress,$mgl,$mgr,$mgt,$mgb,$mgh,$mgf,$ohname,$ehname,$ofname,$efname,$ohvalue,$ehvalue,$ofvalue,$efvalue,$pagesel,$newformat); }
14854
14855/*-- TOC --*/
14856 if ($tag == 'TOCPAGEBREAK') {
14857 if ($toc_id) { $this->tocontents->m_TOC[$toc_id]['TOCmark'] = $this->page; }
14858 else { $this->tocontents->TOCmark = $this->page; }
14859 }
14860/*-- END TOC --*/
14861
14862/*-- COLUMNS --*/
14863 if ($save_cols) {
14864 // Restore columns
14865 $this->SetColumns($save_nbcol,$this->colvAlign,$this->ColGap);
14866 }
14867/*-- END COLUMNS --*/
14868 if (($tag == 'FORMFEED' || $this->restoreBlockPagebreaks) && !$this->tableLevel && !$this->listlvl) {
14869 $this->blk = $save_blk;
14870 // Re-open block tags
14871 $t = $this->blk[0]['tag'];
14872 $a = $this->blk[0]['attr'];
14873 $this->blklvl = 0;
14874 for ($b=0; $b<=$save_blklvl;$b++) {
14875 $tc = $t;
14876 $ac = $a;
14877 $t = $this->blk[$b+1]['tag'];
14878 $a = $this->blk[$b+1]['attr'];
14879 unset($this->blk[$b+1]);
14880 $this->OpenTag($tc,$ac);
14881 }
14882 $this->spanlvl = $save_spanlvl;
14883 $this->InlineProperties = $save_ilp;
14884 $this->restoreInlineProperties($save_silp);
14885 }
14886
14887 break;
14888
14889
14890/*-- TOC --*/
14891 case 'TOCENTRY':
14892 if (isset($attr['CONTENT']) && $attr['CONTENT']) {
14893 $objattr = array();
14894 $objattr['CONTENT'] = htmlspecialchars_decode($attr['CONTENT'],ENT_QUOTES);
14895 $objattr['type'] = 'toc';
14896 if (isset($attr['LEVEL']) && $attr['LEVEL']) { $objattr['toclevel'] = $attr['LEVEL']; } else { $objattr['toclevel'] = 0; }
14897 if (isset($attr['NAME']) && $attr['NAME']) { $objattr['toc_id'] = $attr['NAME']; } else { $objattr['toc_id'] = 0; }
14898 $e = "\xbb\xa4\xactype=toc,objattr=".serialize($objattr)."\xbb\xa4\xac";
14899 if($this->tableLevel) { $this->cell[$this->row][$this->col]['textbuffer'][] = array($e); } // *TABLES*
14900 else { // *TABLES*
14901 $this->textbuffer[] = array($e);
14902 } // *TABLES*
14903 }
14904 break;
14905/*-- END TOC --*/
14906
14907/*-- INDEX --*/
14908 case 'INDEXENTRY':
14909 if (isset($attr['CONTENT']) && $attr['CONTENT']) {
14910 if (isset($attr['XREF']) && $attr['XREF']) {
14911 $this->IndexEntry(htmlspecialchars_decode($attr['CONTENT'],ENT_QUOTES),$attr['XREF']);
14912 break;
14913 }
14914 $objattr = array();
14915 $objattr['CONTENT'] = htmlspecialchars_decode($attr['CONTENT'],ENT_QUOTES);
14916 $objattr['type'] = 'indexentry';
14917 $e = "\xbb\xa4\xactype=indexentry,objattr=".serialize($objattr)."\xbb\xa4\xac";
14918 if($this->tableLevel) { $this->cell[$this->row][$this->col]['textbuffer'][] = array($e); } // *TABLES*
14919 else { // *TABLES*
14920 $this->textbuffer[] = array($e);
14921 } // *TABLES*
14922 }
14923 break;
14924
14925
14926 case 'INDEXINSERT':
14927 if (isset($attr['FONT-SIZE'])) { $reffontsize = $attr['FONT-SIZE']; } else { $reffontsize = ''; }
14928 if (isset($attr['LINE-SPACING']) && $attr['LINE-SPACING']) { $linespacing = $attr['LINE-SPACING']; } else { $linespacing = ''; }
14929 if (isset($attr['DIV-FONT-SIZE']) && $attr['DIV-FONT-SIZE']) { $divlettfontsize = $attr['DIV-FONT-SIZE']; } else { $divlettfontsize = ''; }
14930 if (isset($attr['FONT']) && $attr['FONT']) { $reffont = $attr['FONT']; } else { $reffont = ''; }
14931 if (isset($attr['DIV-FONT']) && $attr['DIV-FONT']) { $divlettfont = $attr['DIV-FONT']; } else { $divlettfont = ''; }
14932 if (isset($attr['COLS']) && $attr['COLS']) { $cols = $attr['COLS']; } else { $cols = 1; }
14933 if (isset($attr['OFFSET']) && $attr['OFFSET']) { $offset = $attr['OFFSET']; } else { $offset = 3; }
14934 if (isset($attr['GAP']) && $attr['GAP']) { $gap = $attr['GAP']; } else { $gap = 5; }
14935
14936 if (isset($attr['USEDIVLETTERS']) && (strtoupper($attr['USEDIVLETTERS'])=='OFF' || $attr['USEDIVLETTERS']==-1 || $attr['USEDIVLETTERS']==='0')) { $usedivletters = 0; }
14937 else { $usedivletters = 1; }
14938
14939 if (isset($attr['LINKS']) && (strtoupper($attr['LINKS'])=='ON' || $attr['LINKS']==1)) { $links = true; }
14940 else { $links = false; }
14941 $this->CreateIndex($cols, $reffontsize, $linespacing, $offset, $usedivletters, $divlettfontsize, $gap, $reffont,$divlettfont, $links);
14942 break;
14943/*-- END INDEX --*/
14944
14945/*-- WATERMARK --*/
14946
14947 case 'WATERMARKTEXT':
14948 if (isset($attr['CONTENT']) && $attr['CONTENT']) { $txt = htmlspecialchars_decode($attr['CONTENT'],ENT_QUOTES); } else { $txt = ''; }
14949 if (isset($attr['ALPHA']) && $attr['ALPHA']>0) { $alpha = $attr['ALPHA']; } else { $alpha = -1; }
14950 $this->SetWatermarkText($txt, $alpha);
14951 break;
14952
14953
14954 case 'WATERMARKIMAGE':
14955 if (isset($attr['SRC'])) { $src = $attr['SRC']; } else { $src = ''; }
14956 if (isset($attr['ALPHA']) && $attr['ALPHA']>0) { $alpha = $attr['ALPHA']; } else { $alpha = -1; }
14957 if (isset($attr['SIZE']) && $attr['SIZE']) {
14958 $size = $attr['SIZE'];
14959 if (strpos($size,',')) { $size = explode(',',$size); }
14960 }
14961 else { $size = 'D'; }
14962 if (isset($attr['POSITION']) && $attr['POSITION']) { // mPDF 5.7.2
14963 $pos = $attr['POSITION'];
14964 if (strpos($pos,',')) { $pos = explode(',',$pos); }
14965 }
14966 else { $pos = 'P'; }
14967 $this->SetWatermarkImage($src, $alpha, $size, $pos);
14968 break;
14969/*-- END WATERMARK --*/
14970
14971/*-- BOOKMARKS --*/
14972 case 'BOOKMARK':
14973 if (isset($attr['CONTENT'])) {
14974 $objattr = array();
14975 $objattr['CONTENT'] = htmlspecialchars_decode($attr['CONTENT'],ENT_QUOTES);
14976 $objattr['type'] = 'bookmark';
14977 if (isset($attr['LEVEL']) && $attr['LEVEL']) { $objattr['bklevel'] = $attr['LEVEL']; } else { $objattr['bklevel'] = 0; }
14978 $e = "\xbb\xa4\xactype=bookmark,objattr=".serialize($objattr)."\xbb\xa4\xac";
14979 if($this->tableLevel) { $this->cell[$this->row][$this->col]['textbuffer'][] = array($e); } // *TABLES*
14980 else { // *TABLES*
14981 $this->textbuffer[] = array($e);
14982 } // *TABLES*
14983 }
14984 break;
14985/*-- END BOOKMARKS --*/
14986
14987/*-- ANNOTATIONS --*/
14988 case 'ANNOTATION':
14989
14990 //if (isset($attr['CONTENT']) && !$this->writingHTMLheader && !$this->writingHTMLfooter) { // Stops annotations in FixedPos
14991 if (isset($attr['CONTENT'])) {
14992 $objattr = array();
14993 $objattr['margin_top'] = 0;
14994 $objattr['margin_bottom'] = 0;
14995 $objattr['margin_left'] = 0;
14996 $objattr['margin_right'] = 0;
14997 $objattr['width'] = 0;
14998 $objattr['height'] = 0;
14999 $objattr['border_top']['w'] = 0;
15000 $objattr['border_bottom']['w'] = 0;
15001 $objattr['border_left']['w'] = 0;
15002 $objattr['border_right']['w'] = 0;
15003 $objattr['CONTENT'] = htmlspecialchars_decode($attr['CONTENT'],ENT_QUOTES);
15004 $objattr['type'] = 'annot';
15005 $objattr['POPUP'] = '';
15006 }
15007 else { break; }
15008 if (isset($attr['POS-X'])) { $objattr['POS-X'] = $attr['POS-X']; } else { $objattr['POS-X'] = 0; }
15009 if (isset($attr['POS-Y'])) { $objattr['POS-Y'] = $attr['POS-Y']; } else { $objattr['POS-Y'] = 0; }
15010 if (isset($attr['ICON'])) { $objattr['ICON'] = $attr['ICON']; } else { $objattr['ICON'] = 'Note'; }
15011 if (isset($attr['AUTHOR'])) { $objattr['AUTHOR'] = $attr['AUTHOR']; }
15012 else if (isset($attr['TITLE'])) { $objattr['AUTHOR'] = $attr['TITLE']; } else { $objattr['AUTHOR'] = ''; }
15013 if (isset($attr['FILE'])) { $objattr['FILE'] = $attr['FILE']; } else { $objattr['FILE'] = ''; }
15014 if (isset($attr['SUBJECT'])) { $objattr['SUBJECT'] = $attr['SUBJECT']; } else { $objattr['SUBJECT'] = ''; }
15015 if (isset($attr['OPACITY']) && $attr['OPACITY']>0 && $attr['OPACITY']<=1) { $objattr['OPACITY'] = $attr['OPACITY']; }
15016 else if ($this->annotMargin) { $objattr['OPACITY'] = 1; }
15017 else { $objattr['OPACITY'] = $this->annotOpacity; }
15018 if (isset($attr['COLOR'])) {
15019 $cor = $this->ConvertColor($attr['COLOR']);
15020 if ($cor) { $objattr['COLOR'] = $cor; }
15021 else { $objattr['COLOR'] = $this->ConvertColor('yellow'); }
15022 }
15023 else { $objattr['COLOR'] = $this->ConvertColor('yellow'); }
15024
15025 if (isset($attr['POPUP']) && !empty($attr['POPUP'])) {
15026 $pop = preg_split('/\s+/',trim($attr['POPUP']));
15027 if (count($pop)>1) { $objattr['POPUP'] = $pop; }
15028 else { $objattr['POPUP'] = true; }
15029 }
15030 $e = "\xbb\xa4\xactype=annot,objattr=".serialize($objattr)."\xbb\xa4\xac";
15031 if($this->tableLevel) { $this->cell[$this->row][$this->col]['textbuffer'][] = array($e); } // *TABLES*
15032 else { // *TABLES*
15033 $this->textbuffer[] = array($e);
15034 } // *TABLES*
15035 break;
15036/*-- END ANNOTATIONS --*/
15037
15038
15039/*-- COLUMNS --*/
15040 case 'COLUMNS': //added custom-tag
15041 if (isset($attr['COLUMN-COUNT']) && ($attr['COLUMN-COUNT'] || $attr['COLUMN-COUNT']==='0')) {
15042 // Close any open block tags
15043 for ($b= $this->blklvl;$b>0;$b--) { $this->CloseTag($this->blk[$b]['tag']); }
15044 if(!empty($this->textbuffer)) { //Output previously buffered content
15045 $this->printbuffer($this->textbuffer);
15046 $this->textbuffer=array();
15047 }
15048
15049 if (isset($attr['VALIGN']) && $attr['VALIGN']) {
15050 if ($attr['VALIGN'] == 'J') { $valign = 'J'; }
15051 else { $valign = $align[$attr['VALIGN']]; }
15052 }
15053 else { $valign = ''; }
15054 if (isset($attr['COLUMN-GAP']) && $attr['COLUMN-GAP']) { $this->SetColumns($attr['COLUMN-COUNT'],$valign,$attr['COLUMN-GAP']); }
15055 else { $this->SetColumns($attr['COLUMN-COUNT'],$valign); }
15056 }
15057 $this->ignorefollowingspaces = true;
15058 break;
15059
15060 case 'COLUMN_BREAK': //custom-tag
15061 case 'COLUMNBREAK': //custom-tag
15062 case 'NEWCOLUMN': //custom-tag
15063 $this->ignorefollowingspaces = true;
15064 $this->NewColumn();
15065 $this->ColumnAdjust = false; // disables all column height adjustment for the page.
15066 break;
15067
15068/*-- END COLUMNS --*/
15069
15070
15071 case 'BDO':
15072 // $this->biDirectional = true;
15073 break;
15074
15075
15076 case 'TTZ':
15077 $this->ttz = true;
15078 $this->InlineProperties[$tag] = $this->saveInlineProperties();
15079 $this->setCSS(array('FONT-FAMILY'=>'czapfdingbats','FONT-WEIGHT'=>'normal','FONT-STYLE'=>'normal'),'INLINE');
15080 break;
15081
15082 case 'TTS':
15083 $this->tts = true;
15084 $this->InlineProperties[$tag] = $this->saveInlineProperties();
15085 $this->setCSS(array('FONT-FAMILY'=>'csymbol','FONT-WEIGHT'=>'normal','FONT-STYLE'=>'normal'),'INLINE');
15086 break;
15087
15088 case 'TTA':
15089 $this->tta = true;
15090 $this->InlineProperties[$tag] = $this->saveInlineProperties();
15091
15092 if (in_array($this->FontFamily,$this->mono_fonts)) {
15093 $this->setCSS(array('FONT-FAMILY'=>'ccourier'),'INLINE');
15094 }
15095 else if (in_array($this->FontFamily,$this->serif_fonts)) {
15096 $this->setCSS(array('FONT-FAMILY'=>'ctimes'),'INLINE');
15097 }
15098 else {
15099 $this->setCSS(array('FONT-FAMILY'=>'chelvetica'),'INLINE');
15100 }
15101 break;
15102
15103
15104
15105 // INLINE PHRASES OR STYLES
15106 case 'SUB':
15107 case 'SUP':
15108 case 'ACRONYM':
15109 case 'BIG':
15110 case 'SMALL':
15111 case 'INS':
15112 case 'S':
15113 case 'STRIKE':
15114 case 'DEL':
15115 case 'STRONG':
15116 case 'CITE':
15117 case 'Q':
15118 case 'EM':
15119 case 'B':
15120 case 'I':
15121 case 'U':
15122 case 'SAMP':
15123 case 'CODE':
15124 case 'KBD':
15125 case 'TT':
15126 case 'VAR':
15127 case 'FONT':
15128 case 'MARK': // mPDF 5.5.09
15129 case 'TIME':
15130
15131 case 'SPAN':
15132/*-- ANNOTATIONS --*/
15133 if ($this->title2annots && isset($attr['TITLE'])) {
15134 $objattr = array();
15135 $objattr['margin_top'] = 0;
15136 $objattr['margin_bottom'] = 0;
15137 $objattr['margin_left'] = 0;
15138 $objattr['margin_right'] = 0;
15139 $objattr['width'] = 0;
15140 $objattr['height'] = 0;
15141 $objattr['border_top']['w'] = 0;
15142 $objattr['border_bottom']['w'] = 0;
15143 $objattr['border_left']['w'] = 0;
15144 $objattr['border_right']['w'] = 0;
15145
15146 $objattr['CONTENT'] = $attr['TITLE'];
15147 $objattr['type'] = 'annot';
15148 $objattr['POS-X'] = 0;
15149 $objattr['POS-Y'] = 0;
15150 $objattr['ICON'] = 'Comment';
15151 $objattr['AUTHOR'] = '';
15152 $objattr['SUBJECT'] = '';
15153 $objattr['OPACITY'] = $this->annotOpacity;
15154 $objattr['COLOR'] = $this->ConvertColor('yellow');
15155 $annot = "\xbb\xa4\xactype=annot,objattr=".serialize($objattr)."\xbb\xa4\xac";
15156 }
15157/*-- END ANNOTATIONS --*/
15158
15159 if ($tag == 'SPAN') {
15160 $this->spanlvl++;
15161 $this->InlineProperties['SPAN'][$this->spanlvl] = $this->saveInlineProperties();
15162 if (isset($annot)) { $this->InlineAnnots[$tag][$this->spanlvl] = $annot; } // *ANNOTATIONS*
15163 }
15164 else {
15165 if (!isset($this->InlineProperties[$tag])) $this->InlineProperties[$tag] = $this->saveInlineProperties(); // mPDF 5.4.13
15166 if (isset($annot)) { $this->InlineAnnots[$tag] = $annot; } // *ANNOTATIONS*
15167 }
15168 $properties = $this->cssmgr->MergeCSS('INLINE',$tag,$attr);
15169 if (!empty($properties)) $this->setCSS($properties,'INLINE');
15170 break;
15171
15172
15173 case 'A':
15174 if (isset($attr['NAME']) and $attr['NAME'] != '') {
15175 $e = '';
15176/*-- BOOKMARKS --*/
15177 if ($this->anchor2Bookmark) {
15178 $objattr = array();
15179 $objattr['CONTENT'] = htmlspecialchars_decode($attr['NAME'],ENT_QUOTES);
15180 $objattr['type'] = 'bookmark';
15181 if (isset($attr['LEVEL']) && $attr['LEVEL']) { $objattr['bklevel'] = $attr['LEVEL']; } else { $objattr['bklevel'] = 0; }
15182 $e = "\xbb\xa4\xactype=bookmark,objattr=".serialize($objattr)."\xbb\xa4\xac";
15183 }
15184/*-- END BOOKMARKS --*/
15185 if($this->tableLevel) { // *TABLES*
15186 $this->_saveCellTextBuffer($e, '', $attr['NAME']); // *TABLES*
15187 } // *TABLES*
15188 else { // *TABLES*
15189 $this->_saveTextBuffer($e, '', $attr['NAME']); //an internal link (adds a space for recognition)
15190 } // *TABLES*
15191 }
15192 if (isset($attr['HREF'])) {
15193 $this->InlineProperties['A'] = $this->saveInlineProperties();
15194 $properties = $this->cssmgr->MergeCSS('',$tag,$attr);
15195 if (!empty($properties)) $this->setCSS($properties,'INLINE');
15196 $this->HREF=htmlspecialchars_decode(urldecode($attr['HREF']));
15197 }
15198 break;
15199
15200 case 'LEGEND': // mPDF 5.4.18
15201 $this->InlineProperties['LEGEND'] = $this->saveInlineProperties();
15202 $properties = $this->cssmgr->MergeCSS('',$tag,$attr);
15203 if (!empty($properties)) $this->setCSS($properties,'INLINE');
15204 break;
15205
15206
15207
15208 case 'PROGRESS': // mPDF 5.5.09
15209 case 'METER': // mPDF 5.5.09
15210 $this->inMeter = true; // mPDF 5.5.09
15211
15212 if (isset($attr['MAX']) && $attr['MAX']) { $max = $attr['MAX']; }
15213 else { $max = 1; }
15214 if (isset($attr['MIN']) && $attr['MIN'] && $tag=='METER') { $min = $attr['MIN']; }
15215 else { $min = 0; }
15216 if ($max < $min) { $max = $min; }
15217
15218 if (isset($attr['VALUE']) && ($attr['VALUE'] || $attr['VALUE']==='0')) {
15219 $value = $attr['VALUE'];
15220 if ($value < $min) { $value = $min; }
15221 else if ($value > $max) { $value = $max; }
15222 }
15223 else { $value = ''; }
15224
15225 if (isset($attr['LOW']) && $attr['LOW']) { $low = $attr['LOW']; }
15226 else { $low = $min; }
15227 if ($low < $min) { $low = $min; }
15228 else if ($low > $max) { $low = $max; }
15229 if (isset($attr['HIGH']) && $attr['HIGH']) { $high = $attr['HIGH']; }
15230 else { $high = $max; }
15231 if ($high < $low) { $high = $low; }
15232 else if ($high > $max) { $high = $max; }
15233 if (isset($attr['OPTIMUM']) && $attr['OPTIMUM']) { $optimum = $attr['OPTIMUM']; }
15234 else { $optimum = $min + (($max-$min)/2); }
15235 if ($optimum < $min) { $optimum = $min; }
15236 else if ($optimum > $max) { $optimum = $max; }
15237 if (isset($attr['TYPE']) && $attr['TYPE']) { $type = $attr['TYPE']; }
15238 else { $type = ''; }
15239 $objattr = array();
15240 $objattr['margin_top'] = 0;
15241 $objattr['margin_bottom'] = 0;
15242 $objattr['margin_left'] = 0;
15243 $objattr['margin_right'] = 0;
15244 $objattr['padding_top'] = 0;
15245 $objattr['padding_bottom'] = 0;
15246 $objattr['padding_left'] = 0;
15247 $objattr['padding_right'] = 0;
15248 $objattr['width'] = 0;
15249 $objattr['height'] = 0;
15250 $objattr['border_top']['w'] = 0;
15251 $objattr['border_bottom']['w'] = 0;
15252 $objattr['border_left']['w'] = 0;
15253 $objattr['border_right']['w'] = 0;
15254
15255 $properties = $this->cssmgr->MergeCSS('',$tag,$attr);
15256 if(isset($properties ['DISPLAY']) && strtolower($properties ['DISPLAY'])=='none') {
15257 return;
15258 }
15259 $objattr['visibility'] = 'visible';
15260 if (isset($properties['VISIBILITY'])) {
15261 $v = strtolower($properties['VISIBILITY']);
15262 if (($v == 'hidden' || $v == 'printonly' || $v == 'screenonly') && $this->visibility=='visible') {
15263 $objattr['visibility'] = $v;
15264 }
15265 }
15266
15267 if (isset($properties['MARGIN-TOP'])) { $objattr['margin_top']=$this->ConvertSize($properties['MARGIN-TOP'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
15268 if (isset($properties['MARGIN-BOTTOM'])) { $objattr['margin_bottom'] = $this->ConvertSize($properties['MARGIN-BOTTOM'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
15269 if (isset($properties['MARGIN-LEFT'])) { $objattr['margin_left'] = $this->ConvertSize($properties['MARGIN-LEFT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
15270 if (isset($properties['MARGIN-RIGHT'])) { $objattr['margin_right'] = $this->ConvertSize($properties['MARGIN-RIGHT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
15271
15272 if (isset($properties['PADDING-TOP'])) { $objattr['padding_top']=$this->ConvertSize($properties['PADDING-TOP'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
15273 if (isset($properties['PADDING-BOTTOM'])) { $objattr['padding_bottom'] = $this->ConvertSize($properties['PADDING-BOTTOM'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
15274 if (isset($properties['PADDING-LEFT'])) { $objattr['padding_left'] = $this->ConvertSize($properties['PADDING-LEFT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
15275 if (isset($properties['PADDING-RIGHT'])) { $objattr['padding_right'] = $this->ConvertSize($properties['PADDING-RIGHT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
15276
15277 if (isset($properties['BORDER-TOP'])) { $objattr['border_top'] = $this->border_details($properties['BORDER-TOP']); }
15278 if (isset($properties['BORDER-BOTTOM'])) { $objattr['border_bottom'] = $this->border_details($properties['BORDER-BOTTOM']); }
15279 if (isset($properties['BORDER-LEFT'])) { $objattr['border_left'] = $this->border_details($properties['BORDER-LEFT']); }
15280 if (isset($properties['BORDER-RIGHT'])) { $objattr['border_right'] = $this->border_details($properties['BORDER-RIGHT']); }
15281
15282 if (isset($properties['VERTICAL-ALIGN'])) { $objattr['vertical-align'] = $align[strtolower($properties['VERTICAL-ALIGN'])]; }
15283 $w = 0;
15284 $h = 0;
15285 if(isset($properties['WIDTH'])) $w = $this->ConvertSize($properties['WIDTH'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
15286 else if(isset($attr['WIDTH'])) $w = $this->ConvertSize($attr['WIDTH'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
15287
15288 if(isset($properties['HEIGHT'])) $h = $this->ConvertSize($properties['HEIGHT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
15289 else if(isset($attr['HEIGHT'])) $h = $this->ConvertSize($attr['HEIGHT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
15290
15291 if (isset($properties['OPACITY']) && $properties['OPACITY'] > 0 && $properties['OPACITY'] <= 1) { $objattr['opacity'] = $properties['OPACITY']; }
15292 if ($this->HREF) {
15293 if (strpos($this->HREF,".") === false && strpos($this->HREF,"@") !== 0) {
15294 $href = $this->HREF;
15295 while(array_key_exists($href,$this->internallink)) $href="#".$href;
15296 $this->internallink[$href] = $this->AddLink();
15297 $objattr['link'] = $this->internallink[$href];
15298 }
15299 else { $objattr['link'] = $this->HREF; }
15300 }
15301 $extraheight = $objattr['padding_top'] + $objattr['padding_bottom'] + $objattr['margin_top'] + $objattr['margin_bottom'] + $objattr['border_top']['w'] + $objattr['border_bottom']['w'];
15302 $extrawidth = $objattr['padding_left'] + $objattr['padding_right'] + $objattr['margin_left'] + $objattr['margin_right'] + $objattr['border_left']['w'] + $objattr['border_right']['w'];
15303
15304 // Image file
15305 if (!class_exists('meter', false)) {
15306 include(_MPDF_PATH.'classes/meter.php');
15307 }
15308 $this->meter = new meter();
15309 $svg = $this->meter->makeSVG(strtolower($tag), $type, $value, $max, $min, $optimum, $low, $high);
15310 //Save to local file
15311 $srcpath= _MPDF_TEMP_PATH.'_tempSVG'.uniqid(rand(1,100000),true).'_'.strtolower($tag).'.svg';
15312 file_put_contents($srcpath, $svg);
15313 $orig_srcpath = $srcpath;
15314 $this->GetFullPath($srcpath);
15315
15316 $info=$this->_getImage($srcpath, true, true, $orig_srcpath);
15317 if(!$info) {
15318 $info = $this->_getImage($this->noImageFile);
15319 if ($info) {
15320 $srcpath = $this->noImageFile;
15321 $w = ($info['w'] * (25.4/$this->dpi));
15322 $h = ($info['h'] * (25.4/$this->dpi));
15323 }
15324 }
15325 if(!$info) break;
15326
15327 $objattr['file'] = $srcpath;
15328 //Default width and height calculation if needed
15329 if($w==0 and $h==0) {
15330 // SVG units are pixels
15331 $w = $this->FontSize/(10/_MPDFK) * abs($info['w'])/_MPDFK; // mPDF 5.5.21
15332 $h = $this->FontSize/(10/_MPDFK) * abs($info['h'])/_MPDFK;
15333 }
15334 // IF WIDTH OR HEIGHT SPECIFIED
15335 if($w==0) $w=abs($h*$info['w']/$info['h']);
15336 if($h==0) $h=abs($w*$info['h']/$info['w']);
15337
15338 // Resize to maximum dimensions of page
15339 $maxWidth = $this->blk[$this->blklvl]['inner_width'];
15340 $maxHeight = $this->h - ($this->tMargin + $this->bMargin + 1) ;
15341 if ($this->fullImageHeight) { $maxHeight = $this->fullImageHeight; }
15342 if ($w + $extrawidth > $maxWidth ) {
15343 $w = $maxWidth - $extrawidth;
15344 $h=abs($w*$info['h']/$info['w']);
15345 }
15346
15347 if ($h + $extraheight > $maxHeight ) {
15348 $h = $maxHeight - $extraheight;
15349 $w=abs($h*$info['w']/$info['h']);
15350 }
15351 $objattr['type'] = 'image';
15352 $objattr['itype'] = $info['type'];
15353
15354 $objattr['orig_h'] = $info['h'];
15355 $objattr['orig_w'] = $info['w'];
15356 $objattr['wmf_x'] = $info['x'];
15357 $objattr['wmf_y'] = $info['y'];
15358 $objattr['height'] = $h + $extraheight;
15359 $objattr['width'] = $w + $extrawidth;
15360 $objattr['image_height'] = $h;
15361 $objattr['image_width'] = $w;
15362 $e = "\xbb\xa4\xactype=image,objattr=".serialize($objattr)."\xbb\xa4\xac";
15363 $properties = array();
15364 if ($this->tableLevel) {
15365 $this->_saveCellTextBuffer($e, $this->HREF);
15366 $this->cell[$this->row][$this->col]['s'] += $objattr['width'] ;
15367 }
15368 else {
15369 $this->_saveTextBuffer($e, $this->HREF);
15370 }
15371
15372 break;
15373
15374
15375 case 'BR':
15376 // Added mPDF 3.0 Float DIV - CLEAR
15377 if (isset($attr['STYLE'])) {
15378 $properties = $this->cssmgr->readInlineCSS($attr['STYLE']);
15379 if (isset($properties['CLEAR'])) { $this->ClearFloats(strtoupper($properties['CLEAR']),$this->blklvl); } // *CSS-FLOAT*
15380 }
15381
15382
15383/*-- TABLES --*/
15384 if($this->tableLevel) {
15385
15386 if ($this->blockjustfinished || $this->listjustfinished) {
15387 $this->_saveCellTextBuffer("\n");
15388 }
15389
15390 $this->_saveCellTextBuffer("\n");
15391 if (!isset($this->cell[$this->row][$this->col]['maxs'])) {
15392 $this->cell[$this->row][$this->col]['maxs'] = $this->cell[$this->row][$this->col]['s'];
15393 }
15394 elseif($this->cell[$this->row][$this->col]['maxs'] < $this->cell[$this->row][$this->col]['s']) {
15395 $this->cell[$this->row][$this->col]['maxs'] = $this->cell[$this->row][$this->col]['s'];
15396 }
15397 $this->cell[$this->row][$this->col]['s'] = 0 ;// reset
15398 }
15399 else {
15400/*-- END TABLES --*/
15401 if (count($this->textbuffer)) {
15402 $this->textbuffer[count($this->textbuffer)-1][0] = preg_replace('/ $/','',$this->textbuffer[count($this->textbuffer)-1][0]);
15403 }
15404 $this->_saveTextBuffer("\n");
15405 } // *TABLES*
15406 $this->ignorefollowingspaces = true;
15407 $this->blockjustfinished=false;
15408 $this->listjustfinished=false;
15409
15410 $this->linebreakjustfinished=true;
15411 break;
15412
15413
15414 // *********** BLOCKS ********************
15415
15416
15417 case 'PRE':
15418 $this->ispre=true; // ADDED - Prevents left trim of textbuffer in printbuffer()
15419
15420 case 'DIV':
15421 case 'FORM':
15422 case 'CENTER':
15423
15424 case 'BLOCKQUOTE':
15425 case 'ADDRESS':
15426
15427 case 'CAPTION':
15428 case 'P':
15429 case 'H1':
15430 case 'H2':
15431 case 'H3':
15432 case 'H4':
15433 case 'H5':
15434 case 'H6':
15435 case 'DL':
15436 case 'DT':
15437 case 'DD':
15438 case 'FIELDSET':
15439 // mPDF 5.5.22
15440 case 'DETAILS':
15441 case 'SUMMARY':
15442 // mPDF 5.5.09
15443 case 'ARTICLE':
15444 case 'ASIDE':
15445 case 'FIGURE':
15446 case 'FIGCAPTION':
15447 case 'FOOTER':
15448 case 'HEADER':
15449 case 'HGROUP':
15450 case 'NAV':
15451 case 'SECTION':
15452 $p = $this->cssmgr->PreviewBlockCSS($tag,$attr);
15453 if(isset($p['DISPLAY']) && strtolower($p['DISPLAY'])=='none') {
15454 $this->blklvl++;
15455 $this->blk[$this->blklvl]['hide'] = true;
15456 return;
15457 }
15458 if($tag == 'CAPTION') {
15459 // position is written in AdjstHTML
15460 if (isset($attr['POSITION']) && strtolower($attr['POSITION'])=='bottom') { $divpos = 'B'; }
15461 else { $divpos = 'T'; }
15462 if (isset($attr['ALIGN']) && strtolower($attr['ALIGN'])=='bottom') { $cappos = 'B'; }
15463 else if (isset($p['CAPTION-SIDE']) && strtolower($p['CAPTION-SIDE'])=='bottom') { $cappos = 'B'; }
15464 else { $cappos = 'T'; }
15465 if (isset($attr['ALIGN'])) { unset($attr['ALIGN']); }
15466 if ($cappos != $divpos) {
15467 $this->blklvl++;
15468 $this->blk[$this->blklvl]['hide'] = true;
15469 return;
15470 }
15471 }
15472
15473/*-- FORMS --*/
15474 if($tag == 'FORM') {
15475 if (isset($attr['METHOD']) && strtolower($attr['METHOD'])=='get') { $this->form->formMethod = 'GET'; }
15476 else { $this->form->formMethod = 'POST'; }
15477 if (isset($attr['ACTION'])) { $this->form->formAction = $attr['ACTION']; }
15478 else { $this->form->formAction = ''; }
15479 }
15480/*-- END FORMS --*/
15481
15482
15483/*-- CSS-POSITION --*/
15484 if ((isset($p['POSITION']) && (strtolower($p['POSITION'])=='fixed' || strtolower($p['POSITION'])=='absolute')) && $this->blklvl==0) {
15485 if ($this->inFixedPosBlock) {
15486 $this->Error("Cannot nest block with position:fixed or position:absolute");
15487 }
15488 $this->inFixedPosBlock = true;
15489 return;
15490 }
15491/*-- END CSS-POSITION --*/
15492 // Start Block
15493 $this->ignorefollowingspaces = true;
15494
15495 if ($this->blockjustfinished && !count($this->textbuffer) && $this->y != $this->tMargin && $this->collapseBlockMargins) { $lastbottommargin = $this->lastblockbottommargin; }
15496 else { $lastbottommargin = 0; }
15497 $this->lastblockbottommargin = 0;
15498 $this->blockjustfinished=false;
15499
15500/*-- LISTS --*/
15501 if ($this->listlvl>0) { return; }
15502/*-- END LISTS --*/
15503
15504 $this->InlineProperties = array();
15505 $this->spanlvl = 0;
15506 $this->listjustfinished=false;
15507 $this->divbegin=true;
15508
15509 $this->linebreakjustfinished=false;
15510
15511/*-- TABLES --*/
15512 if ($this->tableLevel) {
15513
15514 // If already something on the line
15515 if ($this->cell[$this->row][$this->col]['s'] > 0 && !$this->nestedtablejustfinished ) {
15516 $this->_saveCellTextBuffer("\n");
15517 if (!isset($this->cell[$this->row][$this->col]['maxs'])) {
15518 $this->cell[$this->row][$this->col]['maxs'] = $this->cell[$this->row][$this->col]['s'];
15519 }
15520 elseif($this->cell[$this->row][$this->col]['maxs'] < $this->cell[$this->row][$this->col]['s']) {
15521 $this->cell[$this->row][$this->col]['maxs'] = $this->cell[$this->row][$this->col]['s'];
15522 }
15523 $this->cell[$this->row][$this->col]['s'] = 0 ;// reset
15524 }
15525 // Cannot set block properties inside table - use Bold to indicate h1-h6
15526 if ($tag == 'CENTER' && $this->tdbegin) { $this->cell[$this->row][$this->col]['a'] = $align['center']; }
15527
15528 $this->InlineProperties['BLOCKINTABLE'] = $this->saveInlineProperties();
15529 $properties = $this->cssmgr->MergeCSS('',$tag,$attr);
15530 if (!empty($properties)) $this->setCSS($properties,'INLINE');
15531
15532
15533 break;
15534 }
15535/*-- END TABLES --*/
15536
15537 if ($tag == 'P' || $tag == 'DT' || $tag == 'DD') { $this->lastoptionaltag = $tag; } // Save current HTML specified optional endtag
15538 else { $this->lastoptionaltag = ''; }
15539
15540 if ($this->lastblocklevelchange == 1) { $blockstate = 1; } // Top margins/padding only
15541 else if ($this->lastblocklevelchange < 1) { $blockstate = 0; } // NO margins/padding
15542 $this->printbuffer($this->textbuffer,$blockstate);
15543 $this->textbuffer=array();
15544
15545 $save_blklvl = $this->blklvl;
15546 $save_blk = $this->blk;
15547 $save_silp = $this->saveInlineProperties();
15548 $save_spanlvl = $this->spanlvl;
15549 $save_ilp = $this->InlineProperties;
15550
15551 $this->blklvl++;
15552
15553 $currblk =& $this->blk[$this->blklvl];
15554 $this->initialiseBlock($currblk);
15555 $prevblk =& $this->blk[$this->blklvl-1];
15556
15557 $currblk['tag'] = $tag;
15558 $currblk['attr'] = $attr;
15559
15560 $this->Reset();
15561 $properties = $this->cssmgr->MergeCSS('BLOCK',$tag,$attr);
15562 $pagesel = '';
15563/*-- CSS-PAGE --*/
15564
15565 if (isset($properties['PAGE'])) { $pagesel = $properties['PAGE']; }
15566/*-- END CSS-PAGE --*/
15567
15568 // If page-box has changed AND/OR PAGE-BREAK-BEFORE
15569 $save_cols = false;
15570 if (($pagesel && $pagesel != $this->page_box['current']) || (isset($properties['PAGE-BREAK-BEFORE']) && $properties['PAGE-BREAK-BEFORE'])) {
15571 if ($this->blklvl>1) {
15572 // Close any open block tags
15573 for ($b= $this->blklvl;$b>0;$b--) { $this->CloseTag($this->blk[$b]['tag']); }
15574 // Output any text left in buffer
15575 if (count($this->textbuffer)) { $this->printbuffer($this->textbuffer); $this->textbuffer=array(); }
15576 }
15577/*-- COLUMNS --*/
15578 if ($this->ColActive) {
15579 $save_cols = true;
15580 $save_nbcol = $this->NbCol; // other values of gap and vAlign will not change by setting Columns off
15581 $this->SetColumns(0);
15582 }
15583/*-- END COLUMNS --*/
15584
15585
15586 // Must Add new page if changed page properties
15587 if (isset($properties['PAGE-BREAK-BEFORE'])) {
15588 if (strtoupper($properties['PAGE-BREAK-BEFORE']) == 'RIGHT') { $this->AddPage($this->CurOrientation,'NEXT-ODD','','','','','', '','', '','','','','','',0,0,0,0,$pagesel); }
15589 else if (strtoupper($properties['PAGE-BREAK-BEFORE']) == 'LEFT') { $this->AddPage($this->CurOrientation,'NEXT-EVEN','','','','','', '','', '','','','','','',0,0,0,0,$pagesel); }
15590 else if (strtoupper($properties['PAGE-BREAK-BEFORE']) == 'ALWAYS') { $this->AddPage($this->CurOrientation,'','','','','','', '','', '','','','','','',0,0,0,0,$pagesel); }
15591 else if ($this->page_box['current'] != $pagesel) { $this->AddPage($this->CurOrientation,'','','','','','', '','', '','','','','','',0,0,0,0,$pagesel); } // *CSS-PAGE*
15592 }
15593/*-- CSS-PAGE --*/
15594 else if ($pagesel != $this->page_box['current']) { $this->AddPage($this->CurOrientation,'','','','','','', '','', '','','','','','',0,0,0,0,$pagesel); }
15595/*-- END CSS-PAGE --*/
15596
15597 // if using htmlheaders, the headers need to be rewritten when new page
15598 // done by calling WriteHTML() within resethtmlheaders
15599 // so block is reset to 0 - now we need to resurrect it
15600 // As in WriteHTML() initialising
15601 if (!($this->restoreBlockPagebreaks && isset($properties['PAGE-BREAK-BEFORE']) && $properties['PAGE-BREAK-BEFORE'])) {
15602 $this->blklvl = 0;
15603 $this->lastblocklevelchange = 0;
15604 $this->blk = array();
15605 $this->initialiseBlock($this->blk[0]);
15606 $this->blk[0]['width'] =& $this->pgwidth;
15607 $this->blk[0]['inner_width'] =& $this->pgwidth;
15608 $this->blk[0]['blockContext'] = $this->blockContext;
15609 $properties = $this->cssmgr->MergeCSS('BLOCK','BODY','');
15610 $this->setCSS($properties,'','BODY');
15611 $this->blklvl++;
15612 $currblk =& $this->blk[$this->blklvl];
15613 $prevblk =& $this->blk[$this->blklvl-1];
15614
15615 $this->initialiseBlock($currblk);
15616 $currblk['tag'] = $tag;
15617 $currblk['attr'] = $attr;
15618
15619 $this->Reset();
15620 $properties = $this->cssmgr->MergeCSS('BLOCK',$tag,$attr);
15621 }
15622/*-- COLUMNS --*/
15623 if ($save_cols) {
15624 // Restore columns
15625 $this->SetColumns($save_nbcol,$this->colvAlign,$this->ColGap);
15626 }
15627/*-- END COLUMNS --*/
15628 if ($this->restoreBlockPagebreaks && isset($properties['PAGE-BREAK-BEFORE']) && $properties['PAGE-BREAK-BEFORE']) {
15629 $this->blk = $save_blk;
15630 // Re-open block tags
15631 $t = $this->blk[0]['tag'];
15632 $a = $this->blk[0]['attr'];
15633 $this->blklvl = 0;
15634 for ($b=0; $b<=$save_blklvl;$b++) {
15635 $tc = $t;
15636 $ac = $a;
15637 $t = $this->blk[$b+1]['tag'];
15638 $a = $this->blk[$b+1]['attr'];
15639 unset($this->blk[$b+1]);
15640 $this->OpenTag($tc,$ac);
15641 }
15642 $this->spanlvl = $save_spanlvl;
15643 $this->InlineProperties = $save_ilp;
15644 $this->restoreInlineProperties($save_silp);
15645 }
15646 }
15647
15648 if (isset($properties['PAGE-BREAK-INSIDE']) && strtoupper($properties['PAGE-BREAK-INSIDE']) == 'AVOID' && !$this->ColActive && !$this->keep_block_together) {
15649 $currblk['keep_block_together'] = 1;
15650 $this->kt_y00 = $this->y;
15651 $this->kt_p00 = $this->page;
15652 $this->keep_block_together = 1;
15653 $this->divbuffer = array();
15654 $this->ktLinks = array();
15655 $this->ktAnnots = array();
15656 $this->ktForms = array();
15657 $this->ktBlock = array();
15658 $this->ktReference = array();
15659 $this->ktBMoutlines = array();
15660 $this->_kttoc = array();
15661 }
15662 if ($lastbottommargin && isset($properties['MARGIN-TOP']) && $properties['MARGIN-TOP'] && empty($properties['FLOAT'])) { $currblk['lastbottommargin'] = $lastbottommargin; }
15663
15664 // mPDF 5.6.01 - LAYERS
15665 if (isset($properties['Z-INDEX']) && $this->currentlayer==0) {
15666 $v = intval($properties['Z-INDEX']);
15667 if ($v > 0) {
15668 $currblk['z-index'] = $v;
15669 $this->BeginLayer($v);
15670 }
15671 }
15672
15673 $this->setCSS($properties,'BLOCK',$tag); //name(id/class/style) found in the CSS array!
15674 $currblk['InlineProperties'] = $this->saveInlineProperties();
15675
15676 if (isset($properties['VISIBILITY'])) {
15677 $v = strtolower($properties['VISIBILITY']);
15678 if (($v == 'hidden' || $v == 'printonly' || $v == 'screenonly') && $this->visibility=='visible' && !$this->tableLevel) {
15679 $currblk['visibility'] = $v;
15680 $this->SetVisibility($v);
15681 }
15682 }
15683
15684 if(isset($attr['DIR']) && $attr['DIR']) { $currblk['direction'] = strtolower($attr['DIR']); }
15685 if(isset($attr['ALIGN']) && $attr['ALIGN']) { $currblk['block-align'] = $align[strtolower($attr['ALIGN'])]; }
15686
15687 if (isset($properties['HEIGHT'])) {
15688 $currblk['css_set_height'] = $this->ConvertSize($properties['HEIGHT'],($this->h - $this->tMargin - $this->bMargin),$this->FontSize,false);
15689 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); }
15690 }
15691 else { $currblk['css_set_height'] = false; }
15692
15693
15694 // Added mPDF 3.0 Float DIV
15695 if (isset($prevblk['blockContext'])) { $currblk['blockContext'] = $prevblk['blockContext'] ; } // *CSS-FLOAT*
15696
15697 if (isset($properties['CLEAR'])) { $this->ClearFloats(strtoupper($properties['CLEAR']), $this->blklvl-1); } // *CSS-FLOAT*
15698
15699 $container_w = $prevblk['inner_width'];
15700 $bdr = $currblk['border_right']['w'];
15701 $bdl = $currblk['border_left']['w'];
15702 $pdr = $currblk['padding_right'];
15703 $pdl = $currblk['padding_left'];
15704
15705 if (isset($currblk['css_set_width'])) { $setwidth = $currblk['css_set_width']; }
15706 else { $setwidth = 0; }
15707
15708/*-- CSS-FLOAT --*/
15709 if (isset($properties['FLOAT']) && strtoupper($properties['FLOAT']) == 'RIGHT' && !$this->ColActive) {
15710 // Cancel Keep-Block-together
15711 $currblk['keep_block_together'] = false;
15712 $this->kt_y00 = '';
15713 $this->keep_block_together = 0;
15714
15715 $this->blockContext++;
15716 $currblk['blockContext'] = $this->blockContext;
15717
15718 list($l_exists, $r_exists, $l_max, $r_max, $l_width, $r_width) = $this->GetFloatDivInfo($this->blklvl-1);
15719
15720 // DIV is too narrow for text to fit!
15721 $maxw = $container_w - $l_width - $r_width;
15722 if (($setwidth + $currblk['margin_right'] + $bdl + $pdl + $bdr + $pdr) > $maxw || ($maxw - ($currblk['margin_right'] + $bdl + $pdl + $bdr + $pdr)) < (2*$this->GetCharWidth('W',false))) {
15723 // Too narrow to fit - try to move down past L or R float
15724 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))) {
15725 $this->ClearFloats('LEFT', $this->blklvl-1);
15726 }
15727 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))) {
15728 $this->ClearFloats('RIGHT', $this->blklvl-1);
15729 }
15730 else { $this->ClearFloats('BOTH', $this->blklvl-1); }
15731 list($l_exists, $r_exists, $l_max, $r_max, $l_width, $r_width) = $this->GetFloatDivInfo($this->blklvl-1);
15732 }
15733
15734 if ($r_exists) { $currblk['margin_right'] += $r_width; }
15735
15736 $currblk['float'] = 'R';
15737 $currblk['float_start_y'] = $this->y;
15738 if ($currblk['css_set_width']) {
15739 $currblk['margin_left'] = $container_w - ($setwidth + $bdl + $pdl + $bdr + $pdr + $currblk['margin_right']);
15740 $currblk['float_width'] = ($setwidth + $bdl + $pdl + $bdr + $pdr + $currblk['margin_right']);
15741 }
15742 else {
15743 // *** If no width set - would need to buffer and keep track of max width, then Right-align if not full width
15744 // and do borders and backgrounds - For now - just set to maximum width left
15745
15746 if ($l_exists) { $currblk['margin_left'] += $l_width; }
15747 $currblk['css_set_width'] = $container_w - ($currblk['margin_left'] + $currblk['margin_right'] + $bdl + $pdl + $bdr + $pdr);
15748
15749 $currblk['float_width'] = ($currblk['css_set_width'] + $bdl + $pdl + $bdr + $pdr + $currblk['margin_right']);
15750 }
15751 }
15752 else if (isset($properties['FLOAT']) && strtoupper($properties['FLOAT']) == 'LEFT' && !$this->ColActive) {
15753 // Cancel Keep-Block-together
15754 $currblk['keep_block_together'] = false;
15755 $this->kt_y00 = '';
15756 $this->keep_block_together = 0;
15757
15758 $this->blockContext++;
15759 $currblk['blockContext'] = $this->blockContext;
15760
15761 list($l_exists, $r_exists, $l_max, $r_max, $l_width, $r_width) = $this->GetFloatDivInfo($this->blklvl-1);
15762
15763 // DIV is too narrow for text to fit!
15764 $maxw = $container_w - $l_width - $r_width;
15765 if (($setwidth + $currblk['margin_left'] + $bdl + $pdl + $bdr + $pdr) > $maxw || ($maxw - ($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_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))) {
15768 $this->ClearFloats('LEFT', $this->blklvl-1);
15769 }
15770 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))) {
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
15777 if ($l_exists) { $currblk['margin_left'] += $l_width; }
15778
15779 $currblk['float'] = 'L';
15780 $currblk['float_start_y'] = $this->y;
15781 if ($setwidth) {
15782 $currblk['margin_right'] = $container_w - ($setwidth + $bdl + $pdl + $bdr + $pdr + $currblk['margin_left']);
15783 $currblk['float_width'] = ($setwidth + $bdl + $pdl + $bdr + $pdr + $currblk['margin_left']);
15784 }
15785 else {
15786 // *** If no width set - would need to buffer and keep track of max width, then Right-align if not full width
15787 // and do borders and backgrounds - For now - just set to maximum width left
15788
15789 if ($r_exists) { $currblk['margin_right'] += $r_width; }
15790 $currblk['css_set_width'] = $container_w - ($currblk['margin_left'] + $currblk['margin_right'] + $bdl + $pdl + $bdr + $pdr);
15791
15792 $currblk['float_width'] = ($currblk['css_set_width'] + $bdl + $pdl + $bdr + $pdr + $currblk['margin_left']);
15793 }
15794 }
15795
15796 else {
15797 // Don't allow overlap - if floats present - adjust padding to avoid overlap with Floats
15798 list($l_exists, $r_exists, $l_max, $r_max, $l_width, $r_width) = $this->GetFloatDivInfo($this->blklvl-1);
15799 $maxw = $container_w - $l_width - $r_width;
15800 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))) {
15801 // Too narrow to fit - try to move down past L or R float
15802 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))) {
15803 $this->ClearFloats('LEFT', $this->blklvl-1);
15804 }
15805 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))) {
15806 $this->ClearFloats('RIGHT', $this->blklvl-1);
15807 }
15808 else { $this->ClearFloats('BOTH', $this->blklvl-1); }
15809 list($l_exists, $r_exists, $l_max, $r_max, $l_width, $r_width) = $this->GetFloatDivInfo($this->blklvl-1);
15810 }
15811 if ($r_exists) { $currblk['padding_right'] = max(($r_width-$currblk['margin_right']-$bdr), $pdr); }
15812 if ($l_exists) { $currblk['padding_left'] = max(($l_width-$currblk['margin_left']-$bdl), $pdl); }
15813 }
15814/*-- END CSS-FLOAT --*/
15815
15816
15817/*-- BORDER-RADIUS --*/
15818 // Automatically increase padding if required for border-radius
15819 if ($this->autoPadding && !$this->ColActive && !$this->keep_block_together) {
15820 if ($currblk['border_radius_TL_H']>$currblk['padding_left'] && $currblk['border_radius_TL_V']>$currblk['padding_top']) {
15821 if ($currblk['border_radius_TL_H']>$currblk['border_radius_TL_V']) {
15822 $this->_borderPadding($currblk['border_radius_TL_H'],$currblk['border_radius_TL_V'], $currblk['padding_left'], $currblk['padding_top']);
15823 }
15824 else {
15825 $this->_borderPadding($currblk['border_radius_TL_V'],$currblk['border_radius_TL_H'], $currblk['padding_top'], $currblk['padding_left']);
15826 }
15827 }
15828 if ($currblk['border_radius_TR_H']>$currblk['padding_right'] && $currblk['border_radius_TR_V']>$currblk['padding_top']) {
15829 if ($currblk['border_radius_TR_H']>$currblk['border_radius_TR_V']) {
15830 $this->_borderPadding($currblk['border_radius_TR_H'],$currblk['border_radius_TR_V'], $currblk['padding_right'], $currblk['padding_top']);
15831 }
15832 else {
15833 $this->_borderPadding($currblk['border_radius_TR_V'],$currblk['border_radius_TR_H'], $currblk['padding_top'], $currblk['padding_right']);
15834 }
15835 }
15836 if ($currblk['border_radius_BL_H']>$currblk['padding_left'] && $currblk['border_radius_BL_V']>$currblk['padding_bottom']) {
15837 if ($currblk['border_radius_BL_H']>$currblk['border_radius_BL_V']) {
15838 $this->_borderPadding($currblk['border_radius_BL_H'],$currblk['border_radius_BL_V'], $currblk['padding_left'], $currblk['padding_bottom']);
15839 }
15840 else {
15841 $this->_borderPadding($currblk['border_radius_BL_V'],$currblk['border_radius_BL_H'], $currblk['padding_bottom'], $currblk['padding_left']);
15842 }
15843 }
15844 if ($currblk['border_radius_BR_H']>$currblk['padding_right'] && $currblk['border_radius_BR_V']>$currblk['padding_bottom']) {
15845 if ($currblk['border_radius_BR_H']>$currblk['border_radius_BR_V']) {
15846 $this->_borderPadding($currblk['border_radius_BR_H'],$currblk['border_radius_BR_V'], $currblk['padding_right'], $currblk['padding_bottom']);
15847 }
15848 else {
15849 $this->_borderPadding($currblk['border_radius_BR_V'],$currblk['border_radius_BR_H'], $currblk['padding_bottom'], $currblk['padding_right']);
15850 }
15851 }
15852 }
15853/*-- END BORDER-RADIUS --*/
15854
15855
15856 // Hanging indent - if negative indent: ensure padding is >= indent
15857 if(!isset($currblk['text_indent'])) { $currblk['text_indent'] = null; }
15858 if(!isset($currblk['inner_width'])) { $currblk['inner_width'] = null; }
15859 $cbti = $this->ConvertSize($currblk['text_indent'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
15860 if ($cbti < 0) {
15861 $hangind = -($cbti);
15862 if ($currblk['direction'] == 'rtl') { // *RTL*
15863 $currblk['padding_right'] = max($currblk['padding_right'],$hangind); // *RTL*
15864 } // *RTL*
15865 else { // *RTL*
15866 $currblk['padding_left'] = max($currblk['padding_left'],$hangind);
15867 } // *RTL*
15868 }
15869
15870 if (isset($currblk['css_set_width'])) {
15871 if (isset($properties['MARGIN-LEFT']) && isset($properties['MARGIN-RIGHT']) && strtolower($properties['MARGIN-LEFT'])=='auto' && strtolower($properties['MARGIN-RIGHT'])=='auto') {
15872 // Try to reduce margins to accomodate - if still too wide, set margin-right/left=0 (reduces width)
15873 $anyextra = $prevblk['inner_width'] - ($currblk['css_set_width'] + $currblk['border_left']['w'] + $currblk['padding_left'] + $currblk['border_right']['w'] + $currblk['padding_right']);
15874 if ($anyextra>0) {
15875 $currblk['margin_left'] = $currblk['margin_right'] = $anyextra /2;
15876 }
15877 else {
15878 $currblk['margin_left'] = $currblk['margin_right'] = 0;
15879 }
15880 }
15881 else if (isset($properties['MARGIN-LEFT']) && strtolower($properties['MARGIN-LEFT'])=='auto') {
15882 // Try to reduce margin-left to accomodate - if still too wide, set margin-left=0 (reduces width)
15883 $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']);
15884 if ($currblk['margin_left'] < 0) {
15885 $currblk['margin_left'] = 0;
15886 }
15887 }
15888 else if (isset($properties['MARGIN-RIGHT']) && strtolower($properties['MARGIN-RIGHT'])=='auto') {
15889 // Try to reduce margin-right to accomodate - if still too wide, set margin-right=0 (reduces width)
15890 $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']);
15891 if ($currblk['margin_right'] < 0) {
15892 $currblk['margin_right'] = 0;
15893 }
15894 }
15895 else {
15896 if ($currblk['direction'] == 'rtl') { // *RTL*
15897 // Try to reduce margin-left to accomodate - if still too wide, set margin-left=0 (reduces width)
15898 $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*
15899 if ($currblk['margin_left'] < 0) { // *RTL*
15900 $currblk['margin_left'] = 0; // *RTL*
15901 } // *RTL*
15902 } // *RTL*
15903 else { // *RTL*
15904 // Try to reduce margin-right to accomodate - if still too wide, set margin-right=0 (reduces width)
15905 $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']);
15906 if ($currblk['margin_right'] < 0) {
15907 $currblk['margin_right'] = 0;
15908 }
15909 } // *RTL*
15910 }
15911 }
15912
15913 $currblk['outer_left_margin'] = $prevblk['outer_left_margin'] + $currblk['margin_left'] + $prevblk['border_left']['w'] + $prevblk['padding_left'];
15914 $currblk['outer_right_margin'] = $prevblk['outer_right_margin'] + $currblk['margin_right'] + $prevblk['border_right']['w'] + $prevblk['padding_right'];
15915
15916 $currblk['width'] = $this->pgwidth - ($currblk['outer_right_margin'] + $currblk['outer_left_margin']);
15917 $currblk['inner_width'] = $currblk['width'] - ($currblk['border_left']['w'] + $currblk['padding_left'] + $currblk['border_right']['w'] + $currblk['padding_right']);
15918
15919 // Check DIV is not now too narrow to fit text
15920 $mw = 2*$this->GetCharWidth('W',false);
15921 if ($currblk['inner_width'] < $mw) {
15922 $currblk['padding_left'] = 0;
15923 $currblk['padding_right'] = 0;
15924 $currblk['border_left']['w'] = 0.2;
15925 $currblk['border_right']['w'] = 0.2;
15926 $currblk['margin_left'] = 0;
15927 $currblk['margin_right'] = 0;
15928 $currblk['outer_left_margin'] = $prevblk['outer_left_margin'] + $currblk['margin_left'] + $prevblk['border_left']['w'] + $prevblk['padding_left'];
15929 $currblk['outer_right_margin'] = $prevblk['outer_right_margin'] + $currblk['margin_right'] + $prevblk['border_right']['w'] + $prevblk['padding_right'];
15930 $currblk['width'] = $this->pgwidth - ($currblk['outer_right_margin'] + $currblk['outer_left_margin']);
15931 $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']);
15932// if ($currblk['inner_width'] < $mw) { $this->Error("DIV is too narrow for text to fit!"); }
15933 }
15934
15935 $this->x = $this->lMargin + $currblk['outer_left_margin'];
15936
15937/*-- BACKGROUNDS --*/
15938 if (isset($properties['BACKGROUND-IMAGE']) && $properties['BACKGROUND-IMAGE'] && !$this->kwt && !$this->ColActive && !$this->keep_block_together) {
15939 $ret = $this->SetBackground($properties, $currblk['inner_width']);
15940 if ($ret) { $currblk['background-image'] = $ret; }
15941 }
15942/*-- END BACKGROUNDS --*/
15943
15944/*-- TABLES --*/
15945 if ($this->use_kwt && isset($attr['KEEP-WITH-TABLE']) && !$this->ColActive && !$this->keep_block_together) {
15946 $this->kwt = true;
15947 $this->kwt_y0 = $this->y;
15948 $this->kwt_x0 = $this->x;
15949 $this->kwt_height = 0;
15950 $this->kwt_buffer = array();
15951 $this->kwt_Links = array();
15952 $this->kwt_Annots = array();
15953 $this->kwt_moved = false;
15954 $this->kwt_saved = false;
15955 $this->kwt_Reference = array();
15956 $this->kwt_BMoutlines = array();
15957 $this->kwt_toc = array();
15958 }
15959 else {
15960/*-- END TABLES --*/
15961 $this->kwt = false;
15962 } // *TABLES*
15963
15964 //Save x,y coords in case we need to print borders...
15965 $currblk['y0'] = $this->y;
15966 $currblk['x0'] = $this->x;
15967 $currblk['startpage'] = $this->page;
15968 $this->oldy = $this->y;
15969
15970 $this->lastblocklevelchange = 1 ;
15971
15972 break;
15973
15974 case 'HR':
15975 // Added mPDF 3.0 Float DIV - CLEAR
15976 if (isset($attr['STYLE'])) {
15977 $properties = $this->cssmgr->readInlineCSS($attr['STYLE']);
15978 if (isset($properties['CLEAR'])) { $this->ClearFloats(strtoupper($properties['CLEAR']),$this->blklvl); } // *CSS-FLOAT*
15979 }
15980
15981 $this->ignorefollowingspaces = true;
15982
15983 $objattr = array();
15984 $objattr['margin_top'] = 0;
15985 $objattr['margin_bottom'] = 0;
15986 $objattr['margin_left'] = 0;
15987 $objattr['margin_right'] = 0;
15988 $objattr['width'] = 0;
15989 $objattr['height'] = 0;
15990 $objattr['border_top']['w'] = 0;
15991 $objattr['border_bottom']['w'] = 0;
15992 $objattr['border_left']['w'] = 0;
15993 $objattr['border_right']['w'] = 0;
15994 $properties = $this->cssmgr->MergeCSS('',$tag,$attr);
15995 if (isset($properties['MARGIN-TOP'])) { $objattr['margin_top'] = $this->ConvertSize($properties['MARGIN-TOP'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
15996 if (isset($properties['MARGIN-BOTTOM'])) { $objattr['margin_bottom'] = $this->ConvertSize($properties['MARGIN-BOTTOM'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
15997 if (isset($properties['WIDTH'])) { $objattr['width'] = $this->ConvertSize($properties['WIDTH'],$this->blk[$this->blklvl]['inner_width']); }
15998 else if(isset($attr['WIDTH']) && $attr['WIDTH'] != '') $objattr['width'] = $this->ConvertSize($attr['WIDTH'],$this->blk[$this->blklvl]['inner_width']);
15999 if (isset($properties['TEXT-ALIGN'])) { $objattr['align'] = $align[strtolower($properties['TEXT-ALIGN'])]; }
16000 else if(isset($attr['ALIGN']) && $attr['ALIGN'] != '') $objattr['align'] = $align[strtolower($attr['ALIGN'])];
16001
16002 if (isset($properties['MARGIN-LEFT']) && strtolower($properties['MARGIN-LEFT'])=='auto') {
16003 $objattr['align'] = 'R';
16004 }
16005 if (isset($properties['MARGIN-RIGHT']) && strtolower($properties['MARGIN-RIGHT'])=='auto') {
16006 $objattr['align'] = 'L';
16007 if (isset($properties['MARGIN-RIGHT']) && strtolower($properties['MARGIN-RIGHT'])=='auto' && isset($properties['MARGIN-LEFT']) && strtolower($properties['MARGIN-LEFT'])=='auto') {
16008 $objattr['align'] = 'C';
16009 }
16010 }
16011 if (isset($properties['COLOR'])) { $objattr['color'] = $this->ConvertColor($properties['COLOR']); }
16012 else if(isset($attr['COLOR']) && $attr['COLOR'] != '') $objattr['color'] = $this->ConvertColor($attr['COLOR']);
16013 if (isset($properties['HEIGHT'])) { $objattr['linewidth'] = $this->ConvertSize($properties['HEIGHT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
16014
16015
16016/*-- TABLES --*/
16017 if ($this->tableLevel) {
16018 $objattr['W-PERCENT'] = 100;
16019 if (isset($properties['WIDTH']) && stristr($properties['WIDTH'],'%')) {
16020 $properties['WIDTH'] += 0; //make "90%" become simply "90"
16021 $objattr['W-PERCENT'] = $properties['WIDTH'];
16022 }
16023 if (isset($attr['WIDTH']) && stristr($attr['WIDTH'],'%')) {
16024 $attr['WIDTH'] += 0; //make "90%" become simply "90"
16025 $objattr['W-PERCENT'] = $attr['WIDTH'];
16026 }
16027 }
16028/*-- END TABLES --*/
16029
16030 $objattr['type'] = 'hr';
16031 $objattr['height'] = $objattr['linewidth'] + $objattr['margin_top'] + $objattr['margin_bottom'];
16032 $e = "\xbb\xa4\xactype=image,objattr=".serialize($objattr)."\xbb\xa4\xac";
16033
16034 // Clear properties - tidy up
16035 $properties = array();
16036
16037/*-- TABLES --*/
16038 // Output it to buffers
16039 if ($this->tableLevel) {
16040 if (!isset($this->cell[$this->row][$this->col]['maxs'])) {
16041 $this->cell[$this->row][$this->col]['maxs'] = $this->cell[$this->row][$this->col]['s'];
16042 }
16043 elseif($this->cell[$this->row][$this->col]['maxs'] < $this->cell[$this->row][$this->col]['s']) {
16044 $this->cell[$this->row][$this->col]['maxs'] = $this->cell[$this->row][$this->col]['s'];
16045 }
16046 $this->cell[$this->row][$this->col]['s'] = 0 ;// reset
16047 $this->_saveCellTextBuffer($e, $this->HREF);
16048 }
16049 else {
16050/*-- END TABLES --*/
16051 $this->_saveTextBuffer($e, $this->HREF);
16052 } // *TABLES*
16053
16054 break;
16055
16056
16057/*-- BARCODES --*/
16058
16059 case 'BARCODE':
16060 if(isset($attr['CODE']) && $attr['CODE']) {
16061 $objattr = array();
16062 $objattr['margin_top'] = 0;
16063 $objattr['margin_bottom'] = 0;
16064 $objattr['margin_left'] = 0;
16065 $objattr['margin_right'] = 0;
16066 $objattr['padding_top'] = 0;
16067 $objattr['padding_bottom'] = 0;
16068 $objattr['padding_left'] = 0;
16069 $objattr['padding_right'] = 0;
16070 $objattr['width'] = 0;
16071 $objattr['height'] = 0;
16072 $objattr['border_top']['w'] = 0;
16073 $objattr['border_bottom']['w'] = 0;
16074 $objattr['border_left']['w'] = 0;
16075 $objattr['border_right']['w'] = 0;
16076 $objattr['code'] = $attr['CODE'];
16077
16078 if(isset($attr['TYPE'])) {
16079 $objattr['btype'] = trim(strtoupper($attr['TYPE']));
16080 }
16081 else { $objattr['btype'] = 'EAN13'; } // default
16082 if (preg_match('/^(EAN13|ISBN|ISSN|EAN8|UPCA|UPCE)P([25])$/',$objattr['btype'],$m)) {
16083 $objattr['btype'] = $m[1];
16084 $objattr['bsupp'] = $m[2];
16085 if (preg_match('/^(\S+)\s+(.*)$/',$objattr['code'],$mm)) {
16086 $objattr['code'] = $mm[1];
16087 $objattr['bsupp_code'] = $mm[2];
16088 }
16089 }
16090 else { $objattr['bsupp'] = 0; }
16091
16092 if(isset($attr['TEXT']) && $attr['TEXT']==1) { $objattr['showtext'] = 1; }
16093 else { $objattr['showtext'] = 0; }
16094 if(isset($attr['SIZE']) && $attr['SIZE']>0) { $objattr['bsize'] = $attr['SIZE']; }
16095 else { $objattr['bsize'] = 1; }
16096 if(isset($attr['HEIGHT']) && $attr['HEIGHT']>0) { $objattr['bheight'] = $attr['HEIGHT']; }
16097 else { $objattr['bheight'] = 1; }
16098 if(isset($attr['PR']) && $attr['PR']>0) { $objattr['pr_ratio'] = $attr['PR']; }
16099 else { $objattr['pr_ratio'] = ''; }
16100 $properties = $this->cssmgr->MergeCSS('',$tag,$attr);
16101 if(isset($properties ['DISPLAY']) && strtolower($properties ['DISPLAY'])=='none') {
16102 return;
16103 }
16104 if (isset($properties['MARGIN-TOP'])) { $objattr['margin_top']=$this->ConvertSize($properties['MARGIN-TOP'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
16105 if (isset($properties['MARGIN-BOTTOM'])) { $objattr['margin_bottom'] = $this->ConvertSize($properties['MARGIN-BOTTOM'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
16106 if (isset($properties['MARGIN-LEFT'])) { $objattr['margin_left'] = $this->ConvertSize($properties['MARGIN-LEFT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
16107 if (isset($properties['MARGIN-RIGHT'])) { $objattr['margin_right'] = $this->ConvertSize($properties['MARGIN-RIGHT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
16108
16109 if (isset($properties['PADDING-TOP'])) { $objattr['padding_top']=$this->ConvertSize($properties['PADDING-TOP'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
16110 if (isset($properties['PADDING-BOTTOM'])) { $objattr['padding_bottom'] = $this->ConvertSize($properties['PADDING-BOTTOM'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
16111 if (isset($properties['PADDING-LEFT'])) { $objattr['padding_left'] = $this->ConvertSize($properties['PADDING-LEFT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
16112 if (isset($properties['PADDING-RIGHT'])) { $objattr['padding_right'] = $this->ConvertSize($properties['PADDING-RIGHT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
16113
16114 if (isset($properties['BORDER-TOP'])) { $objattr['border_top'] = $this->border_details($properties['BORDER-TOP']); }
16115 if (isset($properties['BORDER-BOTTOM'])) { $objattr['border_bottom'] = $this->border_details($properties['BORDER-BOTTOM']); }
16116 if (isset($properties['BORDER-LEFT'])) { $objattr['border_left'] = $this->border_details($properties['BORDER-LEFT']); }
16117 if (isset($properties['BORDER-RIGHT'])) { $objattr['border_right'] = $this->border_details($properties['BORDER-RIGHT']); }
16118
16119 if (isset($properties['VERTICAL-ALIGN'])) { $objattr['vertical-align'] = $align[strtolower($properties['VERTICAL-ALIGN'])]; }
16120 if (isset($properties['COLOR']) && $properties['COLOR'] != '') { $objattr['color'] = $this->ConvertColor($properties['COLOR']); }
16121 else { $objattr['color'] = false; }
16122 if (isset($properties['BACKGROUND-COLOR']) && $properties['BACKGROUND-COLOR'] != '') { $objattr['bgcolor'] = $this->ConvertColor($properties['BACKGROUND-COLOR']); }
16123 else { $objattr['bgcolor'] = false; }
16124
16125 if (!class_exists('PDFBarcode', false)) {
16126 include(_MPDF_PATH.'classes/barcode.php');
16127 }
16128 $this->barcode = new PDFBarcode();
16129
16130 if ($objattr['btype'] == 'EAN13' || $objattr['btype'] == 'ISBN' || $objattr['btype'] == 'ISSN' || $objattr['btype'] == 'UPCA' || $objattr['btype'] == 'UPCE' || $objattr['btype'] == 'EAN8') {
16131 $code = preg_replace('/\-/','',$objattr['code']);
16132 if ($objattr['btype'] == 'ISSN' || $objattr['btype'] == 'ISBN') {
16133 $arrcode = $this->barcode->getBarcodeArray($code, 'EAN13');
16134 }
16135 else { $arrcode = $this->barcode->getBarcodeArray($code, $objattr['btype'] ); }
16136 if ($arrcode === false) { $this->Error('Error in barcode string.'); }
16137
16138 if ($objattr['bsupp'] == 2 || $objattr['bsupp'] == 5) { // EAN-2 or -5 Supplement
16139 $supparrcode = $this->barcode->getBarcodeArray($objattr['bsupp_code'], 'EAN'.$objattr['bsupp'] );
16140 $w = ($arrcode["maxw"] + $arrcode['lightmL'] + $arrcode['lightmR'] + $supparrcode["maxw"] + $supparrcode['sepM']) * $arrcode['nom-X'] * $objattr['bsize'];
16141 }
16142 else {
16143 $w = ($arrcode["maxw"] + $arrcode['lightmL'] + $arrcode['lightmR']) * $arrcode['nom-X'] * $objattr['bsize'];
16144 }
16145 $h = $arrcode['nom-H'] * $objattr['bsize'] * $objattr['bheight'];
16146 // Add height for ISBN string + margin from top of bars
16147 if (($objattr['showtext'] && $objattr['btype'] == 'EAN13') || $objattr['btype'] == 'ISBN' || $objattr['btype'] == 'ISSN') {
16148 $tisbnm = 1.5 * $objattr['bsize']; // Top margin between TOP TEXT (isbn - if shown) & bars
16149 $isbn_fontsize = 2.1 * $objattr['bsize'];
16150 $h += $isbn_fontsize + $tisbnm ;
16151 }
16152 }
16153 // QR-code
16154 else if ($objattr['btype'] == 'QR') {
16155 $w = $h = $objattr['bsize']*25; // Factor of 25mm (default)
16156 $objattr['errorlevel'] = 'L';
16157 if (isset($attr['ERROR'])) { $objattr['errorlevel'] = $attr['ERROR']; }
16158 }
16159 else if ($objattr['btype'] == 'IMB' || $objattr['btype'] == 'RM4SCC' || $objattr['btype'] == 'KIX' || $objattr['btype'] == 'POSTNET' || $objattr['btype'] == 'PLANET') {
16160 $arrcode = $this->barcode->getBarcodeArray($objattr['code'], $objattr['btype'] );
16161 if ($arrcode === false) { $this->Error('Error in barcode string.'); }
16162 $w = ($arrcode["maxw"] * $arrcode['nom-X'] * $objattr['bsize']) + $arrcode['quietL'] + $arrcode['quietR'];
16163 $h = ($arrcode['nom-H'] * $objattr['bsize']) + (2*$arrcode['quietTB']);
16164 }
16165 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'))) {
16166 $arrcode = $this->barcode->getBarcodeArray($objattr['code'], $objattr['btype'], $objattr['pr_ratio'] );
16167 if ($arrcode === false) { $this->Error('Error in barcode string.'); }
16168 $w = ($arrcode["maxw"] + $arrcode['lightmL'] + $arrcode['lightmR']) * $arrcode['nom-X'] * $objattr['bsize'];
16169 $h = ((2*$arrcode['lightTB'] * $arrcode['nom-X']) + $arrcode['nom-H']) * $objattr['bsize'] * $objattr['bheight'];
16170 }
16171 else { break; }
16172
16173 $extraheight = $objattr['padding_top'] + $objattr['padding_bottom'] + $objattr['margin_top'] + $objattr['margin_bottom'] + $objattr['border_top']['w'] + $objattr['border_bottom']['w'];
16174 $extrawidth = $objattr['padding_left'] + $objattr['padding_right'] + $objattr['margin_left'] + $objattr['margin_right'] + $objattr['border_left']['w'] + $objattr['border_right']['w'];
16175
16176 $objattr['type'] = 'barcode';
16177 $objattr['height'] = $h + $extraheight;
16178 $objattr['width'] = $w + $extrawidth;
16179 $objattr['barcode_height'] = $h;
16180 $objattr['barcode_width'] = $w;
16181/*-- CSS-IMAGE-FLOAT --*/
16182 if (!$this->ColActive && !$this->tableLevel && !$this->listlvl && !$this->kwt && !$this->keep_block_together) {
16183 if (isset($properties['FLOAT']) && (strtoupper($properties['FLOAT']) == 'RIGHT' || strtoupper($properties['FLOAT']) == 'LEFT')) {
16184 $objattr['float'] = substr(strtoupper($properties['FLOAT']),0,1);
16185 }
16186 }
16187/*-- END CSS-IMAGE-FLOAT --*/
16188
16189 $e = "\xbb\xa4\xactype=barcode,objattr=".serialize($objattr)."\xbb\xa4\xac";
16190
16191 // Clear properties - tidy up
16192 $properties = array();
16193
16194/*-- TABLES --*/
16195 // Output it to buffers
16196 if ($this->tableLevel) {
16197 $this->_saveCellTextBuffer($e, $this->HREF);
16198 $this->cell[$this->row][$this->col]['s'] += $objattr['width'] ;
16199 }
16200 else {
16201/*-- END TABLES --*/
16202 $this->_saveTextBuffer($e, $this->HREF);
16203
16204 } // *TABLES*
16205 }
16206 break;
16207/*-- END BARCODES --*/
16208
16209
16210 // *********** FORM ELEMENTS ********************
16211
16212/*-- FORMS --*/
16213 case 'SELECT':
16214 $this->lastoptionaltag = ''; // Save current HTML specified optional endtag
16215 $this->InlineProperties[$tag] = $this->saveInlineProperties();
16216 $properties = $this->cssmgr->MergeCSS('',$tag,$attr);
16217 if (isset($properties['FONT-FAMILY'])) {
16218 $this->SetFont($properties['FONT-FAMILY'],$this->FontStyle,0,false);
16219 }
16220 if (isset($properties['FONT-SIZE'])) {
16221 $mmsize = $this->ConvertSize($properties['FONT-SIZE'],$this->default_font_size/_MPDFK);
16222 $this->SetFontSize($mmsize*_MPDFK,false);
16223 }
16224 if (isset($attr['SPELLCHECK']) && strtolower($attr['SPELLCHECK'])=='true') {
16225 $this->selectoption['SPELLCHECK'] = true;
16226 }
16227
16228 if (isset($properties['COLOR'])) { $this->selectoption['COLOR'] = $this->ConvertColor($properties['COLOR']); }
16229 $this->specialcontent = "type=select";
16230 if(isset($attr['DISABLED'])) { $this->selectoption['DISABLED'] = $attr['DISABLED']; }
16231 if(isset($attr['READONLY'])) { $this->selectoption['READONLY'] = $attr['READONLY']; }
16232 if(isset($attr['REQUIRED'])) { $this->selectoption['REQUIRED'] = $attr['REQUIRED']; }
16233 if(isset($attr['EDITABLE'])) { $this->selectoption['EDITABLE'] = $attr['EDITABLE']; }
16234 if(isset($attr['TITLE'])) { $this->selectoption['TITLE'] = $attr['TITLE']; }
16235 if(isset($attr['MULTIPLE'])) { $this->selectoption['MULTIPLE'] = $attr['MULTIPLE']; }
16236 if(isset($attr['SIZE']) && $attr['SIZE']>1) { $this->selectoption['SIZE'] = $attr['SIZE']; }
16237 if ($this->useActiveForms) {
16238 if(isset($attr['NAME'])) { $this->selectoption['NAME'] = $attr['NAME']; }
16239 if (isset($attr['ONCHANGE'])) { $this->selectoption['ONCHANGE'] = $attr['ONCHANGE']; }
16240 }
16241
16242 $properties = array();
16243 break;
16244
16245 case 'OPTION':
16246 $this->lastoptionaltag = 'OPTION'; // Save current HTML specified optional endtag
16247 $this->selectoption['ACTIVE'] = true;
16248 $this->selectoption['currentSEL'] = false;
16249 if (empty($this->selectoption)) {
16250 $this->selectoption['MAXWIDTH'] = '';
16251 $this->selectoption['SELECTED'] = '';
16252 }
16253 if (isset($attr['SELECTED'])) {
16254 $this->selectoption['SELECTED'] = '';
16255 $this->selectoption['currentSEL'] = true;
16256 }
16257 if(isset($attr['VALUE'])) {
16258 $attr['VALUE'] = strcode2utf($attr['VALUE']);
16259 $attr['VALUE'] = $this->lesser_entity_decode($attr['VALUE']);
16260 if ($this->onlyCoreFonts)
16261 $attr['VALUE'] = mb_convert_encoding($attr['VALUE'], $this->mb_enc,'UTF-8');
16262 }
16263 $this->selectoption['currentVAL'] = $attr['VALUE'];
16264 break;
16265
16266 case 'TEXTAREA':
16267 $objattr = array();
16268 $objattr['margin_top'] = 0;
16269 $objattr['margin_bottom'] = 0;
16270 $objattr['margin_left'] = 0;
16271 $objattr['margin_right'] = 0;
16272 $objattr['width'] = 0;
16273 $objattr['height'] = 0;
16274 $objattr['border_top']['w'] = 0;
16275 $objattr['border_bottom']['w'] = 0;
16276 $objattr['border_left']['w'] = 0;
16277 $objattr['border_right']['w'] = 0;
16278 if(isset($attr['DISABLED'])) { $objattr['disabled'] = true; }
16279 if(isset($attr['READONLY'])) { $objattr['readonly'] = true; }
16280 if(isset($attr['REQUIRED'])) { $objattr['required'] = true; }
16281 if(isset($attr['SPELLCHECK']) && strtolower($attr['SPELLCHECK'])=='true') { $objattr['spellcheck'] = true; }
16282 if(isset($attr['TITLE'])) { $objattr['title'] = $attr['TITLE']; }
16283 if ($this->onlyCoreFonts)
16284 $objattr['title'] = mb_convert_encoding($objattr['title'], $this->mb_enc,'UTF-8');
16285 if ($this->useActiveForms) {
16286 if(isset($attr['NAME'])) { $objattr['fieldname'] = $attr['NAME']; }
16287 $this->form->form_element_spacing['textarea']['outer']['v'] = 0;
16288 $this->form->form_element_spacing['textarea']['inner']['v'] = 0;
16289 if (isset($attr['ONCALCULATE'])) { $objattr['onCalculate'] = $attr['ONCALCULATE']; }
16290 else if (isset($attr['ONCHANGE'])) { $objattr['onCalculate'] = $attr['ONCHANGE']; }
16291 if (isset($attr['ONVALIDATE'])) { $objattr['onValidate'] = $attr['ONVALIDATE']; }
16292 if (isset($attr['ONKEYSTROKE'])) { $objattr['onKeystroke'] = $attr['ONKEYSTROKE']; }
16293 if (isset($attr['ONFORMAT'])) { $objattr['onFormat'] = $attr['ONFORMAT']; }
16294 }
16295 $this->InlineProperties[$tag] = $this->saveInlineProperties();
16296 $properties = $this->cssmgr->MergeCSS('',$tag,$attr);
16297 if (isset($properties['FONT-FAMILY'])) {
16298 $this->SetFont($properties['FONT-FAMILY'],'',0,false);
16299 }
16300 if (isset($properties['FONT-SIZE'])) {
16301 $mmsize = $this->ConvertSize($properties['FONT-SIZE'],$this->default_font_size/_MPDFK);
16302 $this->SetFontSize($mmsize*_MPDFK,false);
16303 }
16304 if (isset($properties['COLOR'])) { $objattr['color'] = $this->ConvertColor($properties['COLOR']); }
16305 $objattr['fontfamily'] = $this->FontFamily;
16306 $objattr['fontsize'] = $this->FontSizePt;
16307 if ($this->useActiveForms) {
16308 if(isset($properties['TEXT-ALIGN'])) { $objattr['text_align'] = $align[strtolower($properties['TEXT-ALIGN'])]; }
16309 else if(isset($attr['ALIGN'])) { $objattr['text_align'] = $align[strtolower($attr['ALIGN'])]; }
16310 if (isset($properties['OVERFLOW']) && strtolower($properties['OVERFLOW'])=='hidden') { $objattr['donotscroll'] = true; }
16311 if (isset($properties['BORDER-TOP-COLOR'])) { $objattr['border-col'] = $this->ConvertColor($properties['BORDER-TOP-COLOR']); }
16312 if (isset($properties['BACKGROUND-COLOR'])) { $objattr['background-col'] = $this->ConvertColor($properties['BACKGROUND-COLOR']); }
16313 }
16314 $this->SetLineHeight('',$this->form->textarea_lineheight);
16315 $formLineHeight = $this->lineheight;
16316
16317 $w = 0;
16318 $h = 0;
16319 if(isset($properties['WIDTH'])) $w = $this->ConvertSize($properties['WIDTH'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
16320 if(isset($properties['HEIGHT'])) $h = $this->ConvertSize($properties['HEIGHT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
16321 if ($properties['VERTICAL-ALIGN']) { $objattr['vertical-align'] = $align[strtolower($properties['VERTICAL-ALIGN'])]; }
16322
16323 $colsize = 20; //HTML default value
16324 $rowsize = 2; //HTML default value
16325 if (isset($attr['COLS'])) $colsize = intval($attr['COLS']);
16326 if (isset($attr['ROWS'])) $rowsize = intval($attr['ROWS']);
16327
16328 $charsize = $this->GetCharWidth('w',false);
16329 if ($w) { $colsize = round(($w-($this->form->form_element_spacing['textarea']['outer']['h']*2)-($this->form->form_element_spacing['textarea']['inner']['h']*2))/$charsize); }
16330 if ($h) { $rowsize = round(($h-($this->form->form_element_spacing['textarea']['outer']['v']*2)-($this->form->form_element_spacing['textarea']['inner']['v']*2))/$formLineHeight); }
16331
16332 $objattr['type'] = 'textarea';
16333 $objattr['width'] = ($colsize * $charsize) + ($this->form->form_element_spacing['textarea']['outer']['h']*2)+($this->form->form_element_spacing['textarea']['inner']['h']*2);
16334 $objattr['height'] = ($rowsize * $formLineHeight) + ($this->form->form_element_spacing['textarea']['outer']['v']*2)+($this->form->form_element_spacing['textarea']['inner']['v']*2);
16335 $objattr['rows'] = $rowsize;
16336 $objattr['cols'] = $colsize;
16337
16338 $this->specialcontent = serialize($objattr);
16339
16340 if ($this->tableLevel) { // *TABLES*
16341 $this->cell[$this->row][$this->col]['s'] += $objattr['width'] ; // *TABLES*
16342 } // *TABLES*
16343
16344 // Clear properties - tidy up
16345 $properties = array();
16346 break;
16347
16348
16349
16350 // *********** FORM - INPUT ********************
16351
16352 case 'INPUT':
16353 if (!isset($attr['TYPE'])) $attr['TYPE'] == 'TEXT';
16354 $objattr = array();
16355 $objattr['margin_top'] = 0;
16356 $objattr['margin_bottom'] = 0;
16357 $objattr['margin_left'] = 0;
16358 $objattr['margin_right'] = 0;
16359 $objattr['width'] = 0;
16360 $objattr['height'] = 0;
16361 $objattr['border_top']['w'] = 0;
16362 $objattr['border_bottom']['w'] = 0;
16363 $objattr['border_left']['w'] = 0;
16364 $objattr['border_right']['w'] = 0;
16365 $objattr['type'] = 'input';
16366 if(isset($attr['DISABLED'])) { $objattr['disabled'] = true; }
16367 if(isset($attr['READONLY'])) { $objattr['readonly'] = true; }
16368 if(isset($attr['REQUIRED'])) { $objattr['required'] = true; }
16369 if(isset($attr['SPELLCHECK']) && strtolower($attr['SPELLCHECK'])=='true') { $objattr['spellcheck'] = true; }
16370 if(isset($attr['TITLE'])) { $objattr['title'] = $attr['TITLE']; }
16371 else if(isset($attr['ALT'])) { $objattr['title'] = $attr['ALT']; }
16372 else $objattr['title'] = '';
16373 $objattr['title'] = strcode2utf($objattr['title']);
16374 $objattr['title'] = $this->lesser_entity_decode($objattr['title']);
16375 if ($this->onlyCoreFonts)
16376 $objattr['title'] = mb_convert_encoding($objattr['title'], $this->mb_enc,'UTF-8');
16377 if ($this->useActiveForms) {
16378 if(isset($attr['NAME'])) { $objattr['fieldname'] = $attr['NAME']; }
16379 }
16380 if(isset($attr['VALUE'])) {
16381 $attr['VALUE'] = strcode2utf($attr['VALUE']);
16382 $attr['VALUE'] = $this->lesser_entity_decode($attr['VALUE']);
16383 if ($this->onlyCoreFonts)
16384 $attr['VALUE'] = mb_convert_encoding($attr['VALUE'], $this->mb_enc,'UTF-8');
16385 $objattr['value'] = $attr['VALUE'];
16386 }
16387
16388 $this->InlineProperties[$tag] = $this->saveInlineProperties();
16389 $properties = $this->cssmgr->MergeCSS('',$tag,$attr);
16390 $objattr['vertical-align'] = '';
16391
16392 if (isset($properties['FONT-FAMILY'])) {
16393 $this->SetFont($properties['FONT-FAMILY'],$this->FontStyle,0,false);
16394 }
16395 if (isset($properties['FONT-SIZE'])) {
16396 $mmsize = $this->ConvertSize($properties['FONT-SIZE'],($this->default_font_size/_MPDFK));
16397 $this->SetFontSize($mmsize*_MPDFK,false);
16398 }
16399 if (isset($properties['COLOR'])) { $objattr['color'] = $this->ConvertColor($properties['COLOR']); }
16400 $objattr['fontfamily'] = $this->FontFamily;
16401 $objattr['fontsize'] = $this->FontSizePt;
16402 if ($this->useActiveForms) {
16403 if(isset($attr['ALIGN'])) { $objattr['text_align'] = $align[strtolower($attr['ALIGN'])]; }
16404 else if(isset($properties['TEXT-ALIGN'])) { $objattr['text_align'] = $align[strtolower($properties['TEXT-ALIGN'])]; }
16405 if (isset($properties['BORDER-TOP-COLOR'])) { $objattr['border-col'] = $this->ConvertColor($properties['BORDER-TOP-COLOR']); }
16406 if (isset($properties['BACKGROUND-COLOR'])) { $objattr['background-col'] = $this->ConvertColor($properties['BACKGROUND-COLOR']); }
16407 }
16408
16409 $type = '';
16410 $texto='';
16411 $height = $this->FontSize;
16412 $width = 0;
16413 $spacesize = $this->GetCharWidth(' ',false);
16414
16415 $w = 0;
16416 if(isset($properties['WIDTH'])) $w = $this->ConvertSize($properties['WIDTH'],$this->blk[$this->blklvl]['inner_width']);
16417
16418 if ($properties['VERTICAL-ALIGN']) { $objattr['vertical-align'] = $align[strtolower($properties['VERTICAL-ALIGN'])]; }
16419
16420 switch(strtoupper($attr['TYPE'])){
16421 case 'HIDDEN':
16422 $this->ignorefollowingspaces = true; //Eliminate exceeding left-side spaces
16423 if ($this->useActiveForms) {
16424 $this->form->SetFormText( 0, 0, $objattr['fieldname'], $objattr['value'], $objattr['value'], '', 0, '', true );
16425 }
16426 if ($this->InlineProperties[$tag]) { $this->restoreInlineProperties($this->InlineProperties[$tag]); }
16427 unset($this->InlineProperties[$tag]);
16428 break 2;
16429 case 'CHECKBOX': //Draw Checkbox
16430 $type = 'CHECKBOX';
16431 if (isset($attr['CHECKED'])) { $objattr['checked'] = true; }
16432 else { $objattr['checked'] = false; }
16433 $width = $this->FontSize;
16434 $height = $this->FontSize;
16435 break;
16436
16437 case 'RADIO': //Draw Radio button
16438 $type = 'RADIO';
16439 if (isset($attr['CHECKED'])) $objattr['checked'] = true;
16440 $width = $this->FontSize;
16441 $height = $this->FontSize;
16442 break;
16443
16444/*-- IMAGES-CORE --*/
16445 case 'IMAGE': // Draw an Image button
16446 if(isset($attr['SRC'])) {
16447 $type = 'IMAGE';
16448 $srcpath = $attr['SRC'];
16449 $orig_srcpath = $attr['ORIG_SRC'];
16450 // VSPACE and HSPACE converted to margins in MergeCSS
16451 if (isset($properties['MARGIN-TOP'])) { $objattr['margin_top']=$this->ConvertSize($properties['MARGIN-TOP'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
16452 if (isset($properties['MARGIN-BOTTOM'])) { $objattr['margin_bottom'] = $this->ConvertSize($properties['MARGIN-BOTTOM'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
16453 if (isset($properties['MARGIN-LEFT'])) { $objattr['margin_left'] = $this->ConvertSize($properties['MARGIN-LEFT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
16454 if (isset($properties['MARGIN-RIGHT'])) { $objattr['margin_right'] = $this->ConvertSize($properties['MARGIN-RIGHT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
16455
16456
16457 if (isset($properties['BORDER-TOP'])) { $objattr['border_top'] = $this->border_details($properties['BORDER-TOP']); }
16458 if (isset($properties['BORDER-BOTTOM'])) { $objattr['border_bottom'] = $this->border_details($properties['BORDER-BOTTOM']); }
16459 if (isset($properties['BORDER-LEFT'])) { $objattr['border_left'] = $this->border_details($properties['BORDER-LEFT']); }
16460 if (isset($properties['BORDER-RIGHT'])) { $objattr['border_right'] = $this->border_details($properties['BORDER-RIGHT']); }
16461
16462 $objattr['padding_top'] = 0;
16463 $objattr['padding_bottom'] = 0;
16464 $objattr['padding_left'] = 0;
16465 $objattr['padding_right'] = 0;
16466
16467 if (isset($properties['VERTICAL-ALIGN'])) { $objattr['vertical-align'] = $align[strtolower($properties['VERTICAL-ALIGN'])]; }
16468
16469 $w = 0;
16470 $h = 0;
16471 if(isset($properties['WIDTH'])) $w = $this->ConvertSize($properties['WIDTH'],$this->blk[$this->blklvl]['inner_width']);
16472 if(isset($properties['HEIGHT'])) $h = $this->ConvertSize($properties['HEIGHT'],$this->blk[$this->blklvl]['inner_width']);
16473
16474 $extraheight = $objattr['margin_top'] + $objattr['margin_bottom'] + $objattr['border_top']['w'] + $objattr['border_bottom']['w'];
16475 $extrawidth = $objattr['margin_left'] + $objattr['margin_right'] + $objattr['border_left']['w'] + $objattr['border_right']['w'];
16476
16477 // Image file
16478 $info=$this->_getImage($srcpath, true, true, $orig_srcpath);
16479 if(!$info) {
16480 $info = $this->_getImage($this->noImageFile);
16481 if ($info) {
16482 $srcpath = $this->noImageFile;
16483 $w = ($info['w'] * (25.4/$this->dpi));
16484 $h = ($info['h'] * (25.4/$this->dpi));
16485 }
16486 }
16487 if(!$info) break;
16488 if ($info['cs']=='Indexed') { $objattr['Indexed'] = true; }
16489 $objattr['file'] = $srcpath;
16490 //Default width and height calculation if needed
16491 if($w==0 and $h==0) {
16492/*-- IMAGES-WMF --*/
16493 if ($info['type']=='wmf') {
16494 // WMF units are twips (1/20pt)
16495 // divide by 20 to get points
16496 // divide by k to get user units
16497 $w = abs($info['w'])/(20*_MPDFK);
16498 $h = abs($info['h']) / (20*_MPDFK);
16499 }
16500 else
16501/*-- END IMAGES-WMF --*/
16502 if ($info['type']=='svg') {
16503 // SVG units are pixels
16504 $w = abs($info['w'])/_MPDFK;
16505 $h = abs($info['h'])/_MPDFK;
16506 }
16507 else {
16508 //Put image at default image dpi
16509 $w=($info['w']/_MPDFK) * (72/$this->img_dpi);
16510 $h=($info['h']/_MPDFK) * (72/$this->img_dpi);
16511 }
16512 if (isset($properties['IMAGE-RESOLUTION'])) {
16513 if (preg_match('/from-image/i', $properties['IMAGE-RESOLUTION']) && isset($info['set-dpi']) && $info['set-dpi']>0) {
16514 $w *= $this->img_dpi / $info['set-dpi'];
16515 $h *= $this->img_dpi / $info['set-dpi'];
16516 }
16517 else if (preg_match('/(\d+)dpi/i', $properties['IMAGE-RESOLUTION'], $m)) {
16518 $dpi = $m[1];
16519 if ($dpi > 0) {
16520 $w *= $this->img_dpi / $dpi;
16521 $h *= $this->img_dpi / $dpi;
16522 }
16523 }
16524 }
16525 }
16526 // IF WIDTH OR HEIGHT SPECIFIED
16527 if($w==0) $w=$h*$info['w']/$info['h'];
16528 if($h==0) $h=$w*$info['h']/$info['w'];
16529 // Resize to maximum dimensions of page
16530 $maxWidth = $this->blk[$this->blklvl]['inner_width'];
16531 $maxHeight = $this->h - ($this->tMargin + $this->bMargin + 10) ;
16532 if ($this->fullImageHeight) { $maxHeight = $this->fullImageHeight; }
16533 if ($w + $extrawidth > $maxWidth ) {
16534 $w = $maxWidth - $extrawidth;
16535 $h=$w*$info['h']/$info['w'];
16536 }
16537 if ($h + $extraheight > $maxHeight ) {
16538 $h = $maxHeight - $extraheight;
16539 $w=$h*$info['w']/$info['h'];
16540 }
16541 $height = $h + $extraheight;
16542 $width = $w + $extrawidth;
16543 $objattr['type'] = 'image';
16544 $objattr['itype'] = $info['type'];
16545 $objattr['orig_h'] = $info['h'];
16546 $objattr['orig_w'] = $info['w'];
16547/*-- IMAGES-WMF --*/
16548 if ($info['type']=='wmf') {
16549 $objattr['wmf_x'] = $info['x'];
16550 $objattr['wmf_y'] = $info['y'];
16551 }
16552 else
16553/*-- END IMAGES-WMF --*/
16554 if ($info['type']=='svg') {
16555 $objattr['wmf_x'] = $info['x'];
16556 $objattr['wmf_y'] = $info['y'];
16557 }
16558 $objattr['height'] = $h + $extraheight;
16559 $objattr['width'] = $w + $extrawidth;
16560
16561 $objattr['image_height'] = $h;
16562 $objattr['image_width'] = $w;
16563 $objattr['ID'] = $info['i'];
16564 $texto = 'X';
16565 if ($this->useActiveForms) {
16566 if (isset($attr['ONCLICK'])) { $objattr['onClick'] = $attr['ONCLICK']; }
16567 $objattr['type'] = 'input';
16568 $type = 'IMAGE';
16569 }
16570 break;
16571 }
16572/*-- END IMAGES-CORE --*/
16573
16574 case 'BUTTON': // Draw a button
16575 case 'SUBMIT':
16576 case 'RESET':
16577 $type = strtoupper($attr['TYPE']);
16578 if ($type=='IMAGE') { $type = 'BUTTON'; } // src path not found
16579 if(isset($attr['NOPRINT'])) { $objattr['noprint'] = true; }
16580 if (!isset($attr['VALUE'])) {
16581 $objattr['value'] = ucfirst(strtolower($type));
16582 }
16583
16584 $texto = " " . $objattr['value'] . " ";
16585 $width = $this->GetStringWidth($texto) + ($this->form->form_element_spacing['button']['outer']['h']*2)+($this->form->form_element_spacing['button']['inner']['h']*2);
16586 $height = $this->FontSize + ($this->form->form_element_spacing['button']['outer']['v']*2)+($this->form->form_element_spacing['button']['inner']['v']*2);
16587 if ($this->useActiveForms) {
16588 if (isset($attr['ONCLICK'])) { $objattr['onClick'] = $attr['ONCLICK']; }
16589 }
16590 break;
16591
16592 case 'PASSWORD':
16593 case 'TEXT':
16594 default:
16595 if ($type == '') { $type = 'TEXT'; }
16596 if(strtoupper($attr['TYPE'])=='PASSWORD') { $type = 'PASSWORD'; }
16597 if (isset($attr['VALUE'])) {
16598 if ($type == 'PASSWORD') {
16599 $num_stars = mb_strlen($attr['VALUE'],$this->mb_enc );
16600 $texto = str_repeat('*',$num_stars);
16601 }
16602 else { $texto = $attr['VALUE']; }
16603 }
16604 $xw = ($this->form->form_element_spacing['input']['outer']['h']*2)+($this->form->form_element_spacing['input']['inner']['h']*2);
16605 $xh = ($this->form->form_element_spacing['input']['outer']['v']*2)+($this->form->form_element_spacing['input']['inner']['v']*2);
16606 if ($w) { $width = $w + $xw; }
16607 else { $width = (20 * $spacesize) + $xw; } // Default width in chars
16608 if (isset($attr['SIZE']) and ctype_digit($attr['SIZE']) ) $width = ($attr['SIZE'] * $spacesize) + $xw;
16609 $height = $this->FontSize + $xh;
16610 if (isset($attr['MAXLENGTH']) and ctype_digit($attr['MAXLENGTH']) ) $objattr['maxlength'] = $attr['MAXLENGTH'];
16611 if ($this->useActiveForms) {
16612 if (isset($attr['ONCALCULATE'])) { $objattr['onCalculate'] = $attr['ONCALCULATE']; }
16613 else if (isset($attr['ONCHANGE'])) { $objattr['onCalculate'] = $attr['ONCHANGE']; }
16614 if (isset($attr['ONVALIDATE'])) { $objattr['onValidate'] = $attr['ONVALIDATE']; }
16615 if (isset($attr['ONKEYSTROKE'])) { $objattr['onKeystroke'] = $attr['ONKEYSTROKE']; }
16616 if (isset($attr['ONFORMAT'])) { $objattr['onFormat'] = $attr['ONFORMAT']; }
16617 }
16618 break;
16619 }
16620
16621 $objattr['subtype'] = $type;
16622 $objattr['text'] = $texto;
16623 $objattr['width'] = $width;
16624 $objattr['height'] = $height;
16625 $e = "\xbb\xa4\xactype=input,objattr=".serialize($objattr)."\xbb\xa4\xac";
16626
16627 // Clear properties - tidy up
16628 $properties = array();
16629
16630/*-- TABLES --*/
16631 // Output it to buffers
16632 if ($this->tableLevel) {
16633 $this->_saveCellTextBuffer($e, $this->HREF);
16634 $this->cell[$this->row][$this->col]['s'] += $objattr['width'] ;
16635
16636 }
16637 else {
16638/*-- END TABLES --*/
16639 $this->_saveTextBuffer($e, $this->HREF);
16640 } // *TABLES*
16641
16642 if ($this->InlineProperties[$tag]) { $this->restoreInlineProperties($this->InlineProperties[$tag]); }
16643 unset($this->InlineProperties[$tag]);
16644
16645 break; // END of INPUT
16646/*-- END FORMS --*/
16647
16648
16649 // *********** GRAPH ********************
16650 case 'JPGRAPH':
16651 if (!$this->useGraphs) { break; }
16652 if ($attr['TABLE']) { $gid = strtoupper($attr['TABLE']); }
16653 else { $gid = '0'; }
16654 if (!is_array($this->graphs[$gid]) || count($this->graphs[$gid])==0 ) { break; }
16655 include_once(_MPDF_PATH.'graph.php');
16656 $this->graphs[$gid]['attr'] = $attr;
16657
16658
16659 if (isset($this->graphs[$gid]['attr']['WIDTH']) && $this->graphs[$gid]['attr']['WIDTH']) {
16660 $this->graphs[$gid]['attr']['cWIDTH']=$this->ConvertSize($this->graphs[$gid]['attr']['WIDTH'],$pgwidth);
16661 } // mm
16662 if (isset($this->graphs[$gid]['attr']['HEIGHT']) && $this->graphs[$gid]['attr']['HEIGHT']) {
16663 $this->graphs[$gid]['attr']['cHEIGHT']=$this->ConvertSize($this->graphs[$gid]['attr']['HEIGHT'],$pgwidth);
16664 }
16665
16666 $graph_img = print_graph($this->graphs[$gid],$this->blk[$this->blklvl]['inner_width']);
16667 if ($graph_img) {
16668 if(isset($attr['ROTATE'])) {
16669 if ($attr['ROTATE']==90 || $attr['ROTATE']==-90) {
16670 $tmpw = $graph_img['w'];
16671 $graph_img['w']= $graph_img['h'];
16672 $graph_img['h']= $tmpw;
16673 }
16674 }
16675 $attr['SRC'] = $graph_img['file'];
16676 $attr['WIDTH'] = $graph_img['w'];
16677 $attr['HEIGHT'] = $graph_img['h'];
16678 }
16679 else { break; }
16680
16681 // *********** IMAGE ********************
16682/*-- IMAGES-CORE --*/
16683 case 'IMG':
16684 if ($this->progressBar) { $this->UpdateProgressBar(1,'','IMG'); } // *PROGRESS-BAR*
16685 $objattr = array();
16686 $objattr['margin_top'] = 0;
16687 $objattr['margin_bottom'] = 0;
16688 $objattr['margin_left'] = 0;
16689 $objattr['margin_right'] = 0;
16690 $objattr['padding_top'] = 0;
16691 $objattr['padding_bottom'] = 0;
16692 $objattr['padding_left'] = 0;
16693 $objattr['padding_right'] = 0;
16694 $objattr['width'] = 0;
16695 $objattr['height'] = 0;
16696 $objattr['border_top']['w'] = 0;
16697 $objattr['border_bottom']['w'] = 0;
16698 $objattr['border_left']['w'] = 0;
16699 $objattr['border_right']['w'] = 0;
16700 if(isset($attr['SRC'])) {
16701 $srcpath = $attr['SRC'];
16702 $orig_srcpath = $attr['ORIG_SRC'];
16703 $properties = $this->cssmgr->MergeCSS('',$tag,$attr);
16704 if(isset($properties ['DISPLAY']) && strtolower($properties ['DISPLAY'])=='none') {
16705 return;
16706 }
16707 // mPDF 5.6.01 - LAYERS
16708 if (isset($properties['Z-INDEX']) && $this->currentlayer==0) {
16709 $v = intval($properties['Z-INDEX']);
16710 if ($v > 0) {
16711 $objattr['z-index'] = $v;
16712 }
16713 }
16714
16715 $objattr['visibility'] = 'visible';
16716 if (isset($properties['VISIBILITY'])) {
16717 $v = strtolower($properties['VISIBILITY']);
16718 if (($v == 'hidden' || $v == 'printonly' || $v == 'screenonly') && $this->visibility=='visible') {
16719 $objattr['visibility'] = $v;
16720 }
16721 }
16722
16723 // VSPACE and HSPACE converted to margins in MergeCSS
16724 if (isset($properties['MARGIN-TOP'])) { $objattr['margin_top']=$this->ConvertSize($properties['MARGIN-TOP'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
16725 if (isset($properties['MARGIN-BOTTOM'])) { $objattr['margin_bottom'] = $this->ConvertSize($properties['MARGIN-BOTTOM'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
16726 if (isset($properties['MARGIN-LEFT'])) { $objattr['margin_left'] = $this->ConvertSize($properties['MARGIN-LEFT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
16727 if (isset($properties['MARGIN-RIGHT'])) { $objattr['margin_right'] = $this->ConvertSize($properties['MARGIN-RIGHT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
16728
16729 if (isset($properties['PADDING-TOP'])) { $objattr['padding_top']=$this->ConvertSize($properties['PADDING-TOP'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
16730 if (isset($properties['PADDING-BOTTOM'])) { $objattr['padding_bottom'] = $this->ConvertSize($properties['PADDING-BOTTOM'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
16731 if (isset($properties['PADDING-LEFT'])) { $objattr['padding_left'] = $this->ConvertSize($properties['PADDING-LEFT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
16732 if (isset($properties['PADDING-RIGHT'])) { $objattr['padding_right'] = $this->ConvertSize($properties['PADDING-RIGHT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
16733
16734 if (isset($properties['BORDER-TOP'])) { $objattr['border_top'] = $this->border_details($properties['BORDER-TOP']); }
16735 if (isset($properties['BORDER-BOTTOM'])) { $objattr['border_bottom'] = $this->border_details($properties['BORDER-BOTTOM']); }
16736 if (isset($properties['BORDER-LEFT'])) { $objattr['border_left'] = $this->border_details($properties['BORDER-LEFT']); }
16737 if (isset($properties['BORDER-RIGHT'])) { $objattr['border_right'] = $this->border_details($properties['BORDER-RIGHT']); }
16738
16739 if (isset($properties['VERTICAL-ALIGN'])) { $objattr['vertical-align'] = $align[strtolower($properties['VERTICAL-ALIGN'])]; }
16740 $w = 0;
16741 $h = 0;
16742 if(isset($properties['WIDTH'])) $w = $this->ConvertSize($properties['WIDTH'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
16743 else if(isset($attr['WIDTH'])) $w = $this->ConvertSize($attr['WIDTH'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
16744 if(isset($properties['HEIGHT'])) $h = $this->ConvertSize($properties['HEIGHT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
16745 else if(isset($attr['HEIGHT'])) $h = $this->ConvertSize($attr['HEIGHT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
16746 // mPDF 5.5.15 // mPDF 5.6.60
16747 $maxw=$maxh=$minw=$minh=false;
16748 if(isset($properties['MAX-WIDTH'])) $maxw = $this->ConvertSize($properties['MAX-WIDTH'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
16749 else if(isset($attr['MAX-WIDTH'])) $maxw = $this->ConvertSize($attr['MAX-WIDTH'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
16750 if(isset($properties['MAX-HEIGHT'])) $maxh = $this->ConvertSize($properties['MAX-HEIGHT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
16751 else if(isset($attr['MAX-HEIGHT'])) $maxh = $this->ConvertSize($attr['MAX-HEIGHT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
16752 if(isset($properties['MIN-WIDTH'])) $minw = $this->ConvertSize($properties['MIN-WIDTH'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
16753 else if(isset($attr['MIN-WIDTH'])) $minw = $this->ConvertSize($attr['MIN-WIDTH'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
16754 if(isset($properties['MIN-HEIGHT'])) $minh = $this->ConvertSize($properties['MIN-HEIGHT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
16755 else if(isset($attr['MIN-HEIGHT'])) $minh = $this->ConvertSize($attr['MIN-HEIGHT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
16756
16757 if (isset($properties['OPACITY']) && $properties['OPACITY'] > 0 && $properties['OPACITY'] <= 1) { $objattr['opacity'] = $properties['OPACITY']; }
16758 if ($this->HREF) {
16759 if (strpos($this->HREF,".") === false && strpos($this->HREF,"@") !== 0) {
16760 $href = $this->HREF;
16761 while(array_key_exists($href,$this->internallink)) $href="#".$href;
16762 $this->internallink[$href] = $this->AddLink();
16763 $objattr['link'] = $this->internallink[$href];
16764 }
16765 else { $objattr['link'] = $this->HREF; }
16766 }
16767 $extraheight = $objattr['padding_top'] + $objattr['padding_bottom'] + $objattr['margin_top'] + $objattr['margin_bottom'] + $objattr['border_top']['w'] + $objattr['border_bottom']['w'];
16768 $extrawidth = $objattr['padding_left'] + $objattr['padding_right'] + $objattr['margin_left'] + $objattr['margin_right'] + $objattr['border_left']['w'] + $objattr['border_right']['w'];
16769
16770/*-- BACKGROUNDS --*/
16771 if(isset($properties['GRADIENT-MASK']) && preg_match('/(-moz-)*(repeating-)*(linear|radial)-gradient/',$properties['GRADIENT-MASK'])) {
16772 $objattr['GRADIENT-MASK'] = $properties['GRADIENT-MASK'];
16773 }
16774/*-- END BACKGROUNDS --*/
16775
16776 // Image file
16777 $info=$this->_getImage($srcpath, true, true, $orig_srcpath);
16778 if(!$info) {
16779 $info = $this->_getImage($this->noImageFile);
16780 if ($info) {
16781 $srcpath = $this->noImageFile;
16782 $w = ($info['w'] * (25.4/$this->dpi));
16783 $h = ($info['h'] * (25.4/$this->dpi));
16784 }
16785 }
16786 if(!$info) break;
16787
16788 if(isset($attr['ROTATE'])) { $image_orientation = $attr['ROTATE']; }
16789 else if(isset($properties['IMAGE-ORIENTATION'])) { $image_orientation = $properties['IMAGE-ORIENTATION']; }
16790 else { $image_orientation = 0; }
16791 if($image_orientation) {
16792 if ($image_orientation==90 || $image_orientation==-90 || $image_orientation==270) {
16793 $tmpw = $info['w'];
16794 $info['w'] = $info['h'];
16795 $info['h'] = $tmpw;
16796 }
16797 $objattr['ROTATE'] = $image_orientation;
16798 }
16799
16800 $objattr['file'] = $srcpath;
16801 //Default width and height calculation if needed
16802 if($w==0 and $h==0) {
16803/*-- IMAGES-WMF --*/
16804 if ($info['type']=='wmf') {
16805 // WMF units are twips (1/20pt)
16806 // divide by 20 to get points
16807 // divide by k to get user units
16808 $w = abs($info['w'])/(20*_MPDFK);
16809 $h = abs($info['h']) / (20*_MPDFK);
16810 }
16811 else
16812/*-- END IMAGES-WMF --*/
16813 if ($info['type']=='svg') {
16814 // SVG units are pixels
16815 $w = abs($info['w'])/_MPDFK;
16816 $h = abs($info['h'])/_MPDFK;
16817 }
16818 else {
16819 //Put image at default image dpi
16820 $w=($info['w']/_MPDFK) * (72/$this->img_dpi);
16821 $h=($info['h']/_MPDFK) * (72/$this->img_dpi);
16822 }
16823 if (isset($properties['IMAGE-RESOLUTION'])) {
16824 if (preg_match('/from-image/i', $properties['IMAGE-RESOLUTION']) && isset($info['set-dpi']) && $info['set-dpi']>0) {
16825 $w *= $this->img_dpi / $info['set-dpi'];
16826 $h *= $this->img_dpi / $info['set-dpi'];
16827 }
16828 else if (preg_match('/(\d+)dpi/i', $properties['IMAGE-RESOLUTION'], $m)) {
16829 $dpi = $m[1];
16830 if ($dpi > 0) {
16831 $w *= $this->img_dpi / $dpi;
16832 $h *= $this->img_dpi / $dpi;
16833 }
16834 }
16835 }
16836 }
16837 // IF WIDTH OR HEIGHT SPECIFIED
16838 if($w==0) $w=abs($h*$info['w']/$info['h']);
16839 if($h==0) $h=abs($w*$info['h']/$info['w']);
16840
16841 // mPDF 5.5.15
16842 if ($minw && $w<$minw) { $w = $minw; $h=abs($w*$info['h']/$info['w']); }
16843 if ($maxw && $w>$maxw) { $w = $maxw; $h=abs($w*$info['h']/$info['w']); }
16844 if ($minh && $h<$minh) { $h = $minh; $w=abs($h*$info['w']/$info['h']); }
16845 if ($maxh && $h>$maxh) { $h = $maxh; $w=abs($h*$info['w']/$info['h']); }
16846
16847 // Resize to maximum dimensions of page
16848 $maxWidth = $this->blk[$this->blklvl]['inner_width'];
16849 $maxHeight = $this->h - ($this->tMargin + $this->bMargin + 1) ;
16850 if ($this->fullImageHeight) { $maxHeight = $this->fullImageHeight; }
16851 if ($w + $extrawidth > $maxWidth ) {
16852 $w = $maxWidth - $extrawidth;
16853 $h=abs($w*$info['h']/$info['w']);
16854 }
16855
16856 if ($h + $extraheight > $maxHeight ) {
16857 $h = $maxHeight - $extraheight;
16858 $w=abs($h*$info['w']/$info['h']);
16859 }
16860 $objattr['type'] = 'image';
16861 $objattr['itype'] = $info['type'];
16862
16863 $objattr['orig_h'] = $info['h'];
16864 $objattr['orig_w'] = $info['w'];
16865/*-- IMAGES-WMF --*/
16866 if ($info['type']=='wmf') {
16867 $objattr['wmf_x'] = $info['x'];
16868 $objattr['wmf_y'] = $info['y'];
16869 }
16870 else
16871/*-- END IMAGES-WMF --*/
16872 if ($info['type']=='svg') {
16873 $objattr['wmf_x'] = $info['x'];
16874 $objattr['wmf_y'] = $info['y'];
16875 }
16876 $objattr['height'] = $h + $extraheight;
16877 $objattr['width'] = $w + $extrawidth;
16878 $objattr['image_height'] = $h;
16879 $objattr['image_width'] = $w;
16880/*-- CSS-IMAGE-FLOAT --*/
16881 if (!$this->ColActive && !$this->tableLevel && !$this->listlvl && !$this->kwt && !$this->keep_block_together) {
16882 if (isset($properties['FLOAT']) && (strtoupper($properties['FLOAT']) == 'RIGHT' || strtoupper($properties['FLOAT']) == 'LEFT')) {
16883 $objattr['float'] = substr(strtoupper($properties['FLOAT']),0,1);
16884 }
16885 }
16886/*-- END CSS-IMAGE-FLOAT --*/
16887
16888 $e = "\xbb\xa4\xactype=image,objattr=".serialize($objattr)."\xbb\xa4\xac";
16889
16890 // Clear properties - tidy up
16891 $properties = array();
16892
16893/*-- TABLES --*/
16894 // Output it to buffers
16895 if ($this->tableLevel) {
16896 $this->_saveCellTextBuffer($e, $this->HREF);
16897 $this->cell[$this->row][$this->col]['s'] += $objattr['width'] ;
16898 }
16899 else {
16900/*-- END TABLES --*/
16901 $this->_saveTextBuffer($e, $this->HREF);
16902 } // *TABLES*
16903/*-- ANNOTATIONS --*/
16904 if ($this->title2annots && isset($attr['TITLE'])) {
16905 $objattr = array();
16906 $objattr['margin_top'] = 0;
16907 $objattr['margin_bottom'] = 0;
16908 $objattr['margin_left'] = 0;
16909 $objattr['margin_right'] = 0;
16910 $objattr['width'] = 0;
16911 $objattr['height'] = 0;
16912 $objattr['border_top']['w'] = 0;
16913 $objattr['border_bottom']['w'] = 0;
16914 $objattr['border_left']['w'] = 0;
16915 $objattr['border_right']['w'] = 0;
16916 $objattr['CONTENT'] = $attr['TITLE'];
16917 $objattr['type'] = 'annot';
16918 $objattr['POS-X'] = 0;
16919 $objattr['POS-Y'] = 0;
16920 $objattr['ICON'] = 'Comment';
16921 $objattr['AUTHOR'] = '';
16922 $objattr['SUBJECT'] = '';
16923 $objattr['OPACITY'] = $this->annotOpacity;
16924 $objattr['COLOR'] = $this->ConvertColor('yellow');
16925 $e = "\xbb\xa4\xactype=annot,objattr=".serialize($objattr)."\xbb\xa4\xac";
16926 if($this->tableLevel) { // *TABLES*
16927 $this->cell[$this->row][$this->col]['textbuffer'][] = array($e); // *TABLES*
16928 } // *TABLES*
16929 else { // *TABLES*
16930 $this->textbuffer[] = array($e);
16931 } // *TABLES*
16932 }
16933/*-- END ANNOTATIONS --*/
16934 }
16935 break;
16936/*-- END IMAGES-CORE --*/
16937
16938
16939 // *********** CIRCULAR TEXT = TEXTCIRCLE ********************
16940 case 'TEXTCIRCLE':
16941 $objattr = array();
16942 $objattr['margin_top'] = 0;
16943 $objattr['margin_bottom'] = 0;
16944 $objattr['margin_left'] = 0;
16945 $objattr['margin_right'] = 0;
16946 $objattr['padding_top'] = 0;
16947 $objattr['padding_bottom'] = 0;
16948 $objattr['padding_left'] = 0;
16949 $objattr['padding_right'] = 0;
16950 $objattr['width'] = 0;
16951 $objattr['height'] = 0;
16952 $objattr['border_top']['w'] = 0;
16953 $objattr['border_bottom']['w'] = 0;
16954 $objattr['border_left']['w'] = 0;
16955 $objattr['border_right']['w'] = 0;
16956 $objattr['top-text'] = '';
16957 $objattr['bottom-text'] = '';
16958 $objattr['r'] = 20; // radius (default value here for safety)
16959 $objattr['space-width'] = 120;
16960 $objattr['char-width'] = 100;
16961
16962 $this->InlineProperties[$tag] = $this->saveInlineProperties();
16963 $properties = $this->cssmgr->MergeCSS('INLINE',$tag,$attr);
16964
16965 if(isset($properties ['DISPLAY']) && strtolower($properties ['DISPLAY'])=='none') {
16966 return;
16967 }
16968 if (isset($attr['R'])) { $objattr['r']=$this->ConvertSize($attr['R'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
16969 if(isset($attr['TOP-TEXT'])) {
16970 $objattr['top-text'] = strcode2utf($attr['TOP-TEXT']);
16971 $objattr['top-text'] = $this->lesser_entity_decode($objattr['top-text']);
16972 if ($this->onlyCoreFonts)
16973 $objattr['top-text'] = mb_convert_encoding($objattr['top-text'], $this->mb_enc,'UTF-8');
16974 }
16975 if(isset($attr['BOTTOM-TEXT'])) {
16976 $objattr['bottom-text'] = strcode2utf($attr['BOTTOM-TEXT']);
16977 $objattr['bottom-text'] = $this->lesser_entity_decode($objattr['bottom-text']);
16978 if ($this->onlyCoreFonts)
16979 $objattr['bottom-text'] = mb_convert_encoding($objattr['bottom-text'], $this->mb_enc,'UTF-8');
16980 }
16981 if(isset($attr['SPACE-WIDTH']) && $attr['SPACE-WIDTH']) { $objattr['space-width'] = $attr['SPACE-WIDTH']; }
16982 if(isset($attr['CHAR-WIDTH']) && $attr['CHAR-WIDTH']) { $objattr['char-width'] = $attr['CHAR-WIDTH']; }
16983
16984 // VISIBILITY
16985 $objattr['visibility'] = 'visible';
16986 if (isset($properties['VISIBILITY'])) {
16987 $v = strtolower($properties['VISIBILITY']);
16988 if (($v == 'hidden' || $v == 'printonly' || $v == 'screenonly') && $this->visibility=='visible') {
16989 $objattr['visibility'] = $v;
16990 }
16991 }
16992 // mPDF 5.5.23
16993 if (isset($properties['FONT-SIZE'])) {
16994 if (strtolower($properties['FONT-SIZE'])=='auto') {
16995 if ($objattr['top-text'] && $objattr['bottom-text']) {
16996 $objattr['fontsize'] = -2;
16997 }
16998 else {
16999 $objattr['fontsize'] = -1;
17000 }
17001 }
17002 else {
17003 $mmsize = $this->ConvertSize($properties['FONT-SIZE'],($this->default_font_size/_MPDFK));
17004 $this->SetFontSize($mmsize*_MPDFK,false);
17005 $objattr['fontsize'] = $this->FontSizePt;
17006 }
17007 }
17008 // mPDF 5.5.23
17009 if(isset($attr['DIVIDER'])) {
17010 $objattr['divider'] = strcode2utf($attr['DIVIDER']);
17011 $objattr['divider'] = $this->lesser_entity_decode($objattr['divider']);
17012 if ($this->onlyCoreFonts)
17013 $objattr['divider'] = mb_convert_encoding($objattr['divider'], $this->mb_enc,'UTF-8');
17014
17015 }
17016
17017 if (isset($properties['COLOR'])) { $objattr['color'] = $this->ConvertColor($properties['COLOR']); }
17018
17019 $objattr['fontstyle'] = '';
17020 if (isset($properties['FONT-WEIGHT'])) {
17021 if (strtoupper($properties['FONT-WEIGHT']) == 'BOLD') { $objattr['fontstyle'] .= 'B'; }
17022 }
17023 if (isset($properties['FONT-STYLE'])) {
17024 if (strtoupper($properties['FONT-STYLE']) == 'ITALIC') { $objattr['fontstyle'] .= 'I'; }
17025 }
17026
17027 if (isset($properties['FONT-FAMILY'])) {
17028 $this->SetFont($properties['FONT-FAMILY'],$this->FontStyle,0,false);
17029 }
17030 $objattr['fontfamily'] = $this->FontFamily;
17031
17032 // VSPACE and HSPACE converted to margins in MergeCSS
17033 if (isset($properties['MARGIN-TOP'])) { $objattr['margin_top']=$this->ConvertSize($properties['MARGIN-TOP'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
17034 if (isset($properties['MARGIN-BOTTOM'])) { $objattr['margin_bottom'] = $this->ConvertSize($properties['MARGIN-BOTTOM'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
17035 if (isset($properties['MARGIN-LEFT'])) { $objattr['margin_left'] = $this->ConvertSize($properties['MARGIN-LEFT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
17036 if (isset($properties['MARGIN-RIGHT'])) { $objattr['margin_right'] = $this->ConvertSize($properties['MARGIN-RIGHT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
17037
17038 if (isset($properties['PADDING-TOP'])) { $objattr['padding_top']=$this->ConvertSize($properties['PADDING-TOP'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
17039 if (isset($properties['PADDING-BOTTOM'])) { $objattr['padding_bottom'] = $this->ConvertSize($properties['PADDING-BOTTOM'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
17040 if (isset($properties['PADDING-LEFT'])) { $objattr['padding_left'] = $this->ConvertSize($properties['PADDING-LEFT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
17041 if (isset($properties['PADDING-RIGHT'])) { $objattr['padding_right'] = $this->ConvertSize($properties['PADDING-RIGHT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
17042
17043 if (isset($properties['BORDER-TOP'])) { $objattr['border_top'] = $this->border_details($properties['BORDER-TOP']); }
17044 if (isset($properties['BORDER-BOTTOM'])) { $objattr['border_bottom'] = $this->border_details($properties['BORDER-BOTTOM']); }
17045 if (isset($properties['BORDER-LEFT'])) { $objattr['border_left'] = $this->border_details($properties['BORDER-LEFT']); }
17046 if (isset($properties['BORDER-RIGHT'])) { $objattr['border_right'] = $this->border_details($properties['BORDER-RIGHT']); }
17047
17048 if (isset($properties['OPACITY']) && $properties['OPACITY'] > 0 && $properties['OPACITY'] <= 1) { $objattr['opacity'] = $properties['OPACITY']; }
17049 if (isset($properties['BACKGROUND-COLOR']) && $properties['BACKGROUND-COLOR'] != '') { $objattr['bgcolor'] = $this->ConvertColor($properties['BACKGROUND-COLOR']); }
17050 else { $objattr['bgcolor'] = false; }
17051 if ($this->HREF) {
17052 if (strpos($this->HREF,".") === false && strpos($this->HREF,"@") !== 0) {
17053 $href = $this->HREF;
17054 while(array_key_exists($href,$this->internallink)) $href="#".$href;
17055 $this->internallink[$href] = $this->AddLink();
17056 $objattr['link'] = $this->internallink[$href];
17057 }
17058 else { $objattr['link'] = $this->HREF; }
17059 }
17060 $extraheight = $objattr['padding_top'] + $objattr['padding_bottom'] + $objattr['margin_top'] + $objattr['margin_bottom'] + $objattr['border_top']['w'] + $objattr['border_bottom']['w'];
17061 $extrawidth = $objattr['padding_left'] + $objattr['padding_right'] + $objattr['margin_left'] + $objattr['margin_right'] + $objattr['border_left']['w'] + $objattr['border_right']['w'];
17062
17063
17064 $w = $objattr['r']*2;
17065 $h = $w;
17066 $objattr['height'] = $h + $extraheight;
17067 $objattr['width'] = $w + $extrawidth;
17068 $objattr['type'] = 'textcircle';
17069
17070 $e = "\xbb\xa4\xactype=image,objattr=".serialize($objattr)."\xbb\xa4\xac";
17071
17072 // Clear properties - tidy up
17073 $properties = array();
17074
17075/*-- TABLES --*/
17076 // Output it to buffers
17077 if ($this->tableLevel) {
17078 $this->_saveCellTextBuffer($e, $this->HREF);
17079 $this->cell[$this->row][$this->col]['s'] += $objattr['width'] ;
17080 }
17081 else {
17082/*-- END TABLES --*/
17083 $this->_saveTextBuffer($e, $this->HREF);
17084 } // *TABLES*
17085
17086 if ($this->InlineProperties[$tag]) { $this->restoreInlineProperties($this->InlineProperties[$tag]); }
17087 unset($this->InlineProperties[$tag]);
17088
17089 break;
17090
17091
17092/*-- TABLES --*/
17093
17094 case 'TABLE': // TABLE-BEGIN
17095 $this->tdbegin = false;
17096 $this->lastoptionaltag = '';
17097 // Disable vertical justification in columns
17098 if ($this->ColActive) { $this->colvAlign = ''; } // *COLUMNS*
17099 if ($this->lastblocklevelchange == 1) { $blockstate = 1; } // Top margins/padding only
17100 else if ($this->lastblocklevelchange < 1) { $blockstate = 0; } // NO margins/padding
17101 // called from block after new div e.g. <div> ... <table> ... Outputs block top margin/border and padding
17102 if (count($this->textbuffer) == 0 && $this->lastblocklevelchange == 1 && !$this->tableLevel && !$this->kwt) {
17103 $this->newFlowingBlock( $this->blk[$this->blklvl]['width'],$this->lineheight,'',false,false,1,true, $this->blk[$this->blklvl]['direction']);
17104 $this->finishFlowingBlock(true); // true = END of flowing block
17105 }
17106 else if (!$this->tableLevel && count($this->textbuffer)) { $this->printbuffer($this->textbuffer,$blockstate); }
17107
17108 $this->textbuffer=array();
17109 $this->lastblocklevelchange = -1;
17110 if ($this->tableLevel) { // i.e. now a nested table coming...
17111 // Save current level table
17112 // mPDF 5.4.10
17113 $this->cell['PARENTCELL'] = $this->saveInlineProperties();
17114 $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['baseProperties']= $this->base_table_properties;
17115 $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['cells'] = $this->cell;
17116 $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['currrow'] = $this->row;
17117 $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['currcol'] = $this->col;
17118 }
17119 $this->tableLevel++;
17120 $this->cssmgr->tbCSSlvl++;
17121
17122 if ($this->tableLevel>1) { // inherit table properties from cell in which nested
17123 $this->base_table_properties['FONT-KERNING'] = $this->kerning ;
17124 $this->base_table_properties['LETTER-SPACING'] = $this->lSpacingCSS ;
17125 $this->base_table_properties['WORD-SPACING'] = $this->wSpacingCSS ;
17126 }
17127
17128 if (isset($this->tbctr[$this->tableLevel])) { $this->tbctr[$this->tableLevel]++; }
17129 else { $this->tbctr[$this->tableLevel] = 1; }
17130
17131 $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['level'] = $this->tableLevel;
17132 $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['levelid'] = $this->tbctr[$this->tableLevel];
17133
17134 if ($this->tableLevel > $this->innermostTableLevel) { $this->innermostTableLevel = $this->tableLevel; }
17135 if ($this->tableLevel > 1) {
17136 $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['nestedpos'] = array($this->row,$this->col,$this->tbctr[($this->tableLevel-1)]);
17137 }
17138 //++++++++++++++++++++++++++++
17139
17140 $this->cell = array();
17141 $this->col=-1; //int
17142 $this->row=-1; //int
17143 $table = &$this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]];
17144
17145 // New table - any level
17146 if ($this->cacheTables) {
17147 $this->packTableData = true; // required for cacheTables
17148 $this->simpleTables = false; // Cannot co-exist with cacheTables
17149 $table['cache'] = _MPDF_TEMP_PATH.'_tempTblCache'.uniqid(rand(1,100000),true).'.dat';
17150 $fh = fopen($table['cache'] , "wb") or $this->Error("When using cacheTables, you must have read/write access to cache files (".$table['cache'] .")");
17151 fwrite($fh, "\x00");
17152 fclose($fh);
17153 $table['ptr'] = 1 ; // Must not be 0
17154 }
17155
17156 $table['direction'] = $this->directionality;
17157 $table['bgcolor'] = false;
17158 $table['va'] = false;
17159 $table['txta'] = false;
17160 $table['topntail'] = false;
17161 $table['thead-underline'] = false;
17162 $table['border'] = false;
17163 $table['border_details']['R']['w'] = 0;
17164 $table['border_details']['L']['w'] = 0;
17165 $table['border_details']['T']['w'] = 0;
17166 $table['border_details']['B']['w'] = 0;
17167 $table['border_details']['R']['style'] = '';
17168 $table['border_details']['L']['style'] = '';
17169 $table['border_details']['T']['style'] = '';
17170 $table['border_details']['B']['style'] = '';
17171 $table['max_cell_border_width']['R'] = 0;
17172 $table['max_cell_border_width']['L'] = 0;
17173 $table['max_cell_border_width']['T'] = 0;
17174 $table['max_cell_border_width']['B'] = 0;
17175 $table['padding']['L'] = false;
17176 $table['padding']['R'] = false;
17177 $table['padding']['T'] = false;
17178 $table['padding']['B'] = false;
17179 $table['margin']['L'] = false;
17180 $table['margin']['R'] = false;
17181 $table['margin']['T'] = false;
17182 $table['margin']['B'] = false;
17183 $table['a'] = false;
17184 $table['border_spacing_H'] = false;
17185 $table['border_spacing_V'] = false;
17186 $table['decimal_align'] = false; // mPDF 5.6.13
17187 $this->Reset();
17188 $this->InlineProperties = array();
17189 $this->spanlvl = 0;
17190 $table['nc'] = $table['nr'] = 0;
17191 $this->tablethead = 0;
17192 $this->tabletfoot = 0;
17193 $this->tabletheadjustfinished = false;
17194
17195
17196 if ($this->blockjustfinished && !count($this->textbuffer) && $this->y != $this->tMargin && $this->collapseBlockMargins && $this->tableLevel==1) { $lastbottommargin = $this->lastblockbottommargin; }
17197 else { $lastbottommargin = 0; }
17198 $this->lastblockbottommargin = 0;
17199 $this->blockjustfinished=false;
17200
17201 if ($this->tableLevel==1) {
17202 $this->tableCJK = false;
17203 $this->table_lineheight = $this->normalLineheight;
17204 $table['headernrows'] = 0;
17205 $table['footernrows'] = 0;
17206 $this->base_table_properties = array();
17207 }
17208
17209 // ADDED CSS FUNCIONS FOR TABLE
17210 if ($this->cssmgr->tbCSSlvl==1) {
17211 $properties = $this->cssmgr->MergeCSS('TOPTABLE',$tag,$attr);
17212 }
17213 else {
17214 $properties = $this->cssmgr->MergeCSS('TABLE',$tag,$attr);
17215 }
17216 $w = '';
17217 if (isset($properties['WIDTH'])) { $w = $properties['WIDTH']; }
17218 else if (isset($attr['WIDTH']) && $attr['WIDTH']) { $w = $attr['WIDTH']; }
17219
17220
17221 if(isset($properties['DIRECTION']) && $properties['DIRECTION']) { $table['direction'] = strtolower($properties['DIRECTION']); }
17222 else if(isset($attr['DIR']) && $attr['DIR']) { $table['direction'] = strtolower($attr['DIR']); }
17223 else if (!isset($table['direction'])){ $table['direction'] = $this->blk[$this->blklvl]['direction']; }
17224
17225 if (isset($properties['BACKGROUND-COLOR'])) { $table['bgcolor'][-1] = $properties['BACKGROUND-COLOR']; }
17226 else if (isset($properties['BACKGROUND'])) { $table['bgcolor'][-1] = $properties['BACKGROUND']; }
17227 else if (isset($attr['BGCOLOR'])) { $table['bgcolor'][-1] = $attr['BGCOLOR']; }
17228 if (isset($properties['VERTICAL-ALIGN'])) { $table['va'] = $align[strtolower($properties['VERTICAL-ALIGN'])]; }
17229 if (isset($properties['TEXT-ALIGN'])) { $table['txta'] = $align[strtolower($properties['TEXT-ALIGN'])]; }
17230 if (isset($attr['ALIGN'])) { $table['a'] = $align[strtolower($attr['ALIGN'])]; }
17231 if (!$table['a']) {
17232 if ($table['direction'] == 'rtl' ) { $table['a'] = 'R'; }
17233 else { $table['a'] = 'L'; }
17234 }
17235
17236 if (isset($properties['AUTOSIZE']) && $properties['AUTOSIZE'] && $this->tableLevel ==1) {
17237 $this->shrink_this_table_to_fit = $properties['AUTOSIZE'];
17238 if ($this->shrink_this_table_to_fit < 1) { $this->shrink_this_table_to_fit = 0; }
17239 }
17240 if (isset($properties['ROTATE']) && $properties['ROTATE'] && $this->tableLevel ==1) {
17241 $this->table_rotate = $properties['ROTATE'];
17242 }
17243 if (isset($properties['TOPNTAIL'])) { $table['topntail'] = $properties['TOPNTAIL']; }
17244 if (isset($properties['THEAD-UNDERLINE'])) { $table['thead-underline'] = $properties['THEAD-UNDERLINE']; }
17245
17246 if (isset($properties['BORDER'])) {
17247 $bord = $this->border_details($properties['BORDER']);
17248 if ($bord['s']) {
17249 $table['border'] = _BORDER_ALL;
17250 $table['border_details']['R'] = $bord;
17251 $table['border_details']['L'] = $bord;
17252 $table['border_details']['T'] = $bord;
17253 $table['border_details']['B'] = $bord;
17254 }
17255 }
17256 if (isset($properties['BORDER-RIGHT'])) {
17257 if ($table['direction'] == 'rtl') { // *RTL*
17258 $table['border_details']['R'] = $this->border_details($properties['BORDER-LEFT']); // *RTL*
17259 } // *RTL*
17260 else { // *RTL*
17261 $table['border_details']['R'] = $this->border_details($properties['BORDER-RIGHT']);
17262 } // *RTL*
17263 $this->setBorder($table['border'], _BORDER_RIGHT, $table['border_details']['R']['s']);
17264 }
17265 if (isset($properties['BORDER-LEFT'])) {
17266 if ($table['direction'] == 'rtl') { // *RTL*
17267 $table['border_details']['L'] = $this->border_details($properties['BORDER-RIGHT']); // *RTL*
17268 } // *RTL*
17269 else { // *RTL*
17270 $table['border_details']['L'] = $this->border_details($properties['BORDER-LEFT']);
17271 } // *RTL*
17272 $this->setBorder($table['border'], _BORDER_LEFT, $table['border_details']['L']['s']);
17273 }
17274 if (isset($properties['BORDER-BOTTOM'])) {
17275 $table['border_details']['B'] = $this->border_details($properties['BORDER-BOTTOM']);
17276 $this->setBorder($table['border'], _BORDER_BOTTOM, $table['border_details']['B']['s']);
17277 }
17278 if (isset($properties['BORDER-TOP'])) {
17279 $table['border_details']['T'] = $this->border_details($properties['BORDER-TOP']);
17280 $this->setBorder($table['border'], _BORDER_TOP, $table['border_details']['T']['s']);
17281 }
17282 if ($table['border']){
17283 $this->table_border_css_set = 1;
17284 }
17285 else {
17286 $this->table_border_css_set = 0;
17287 }
17288
17289 if (isset($properties['FONT-FAMILY'])) {
17290 $this->default_font = $properties['FONT-FAMILY'];
17291 $this->SetFont($this->default_font,'',0,false);
17292 }
17293 $this->base_table_properties['FONT-FAMILY'] = $this->FontFamily; // mPDF 5.4.10
17294
17295 if (isset($properties['FONT-SIZE'])) {
17296 // mPDF 5.4.10
17297 if ($this->tableLevel>1) { $mmsize = $this->ConvertSize($properties['FONT-SIZE'], $this->base_table_properties['FONT-SIZE']); }
17298 else { $mmsize = $this->ConvertSize($properties['FONT-SIZE'],$this->default_font_size/_MPDFK); }
17299 if ($mmsize) {
17300 $this->default_font_size = $mmsize*(_MPDFK);
17301 $this->SetFontSize($this->default_font_size,false);
17302 }
17303 }
17304 $this->base_table_properties['FONT-SIZE'] = $this->FontSize.'mm'; // mPDF 5.4.10
17305
17306 if (isset($properties['FONT-WEIGHT'])) {
17307 if (strtoupper($properties['FONT-WEIGHT']) == 'BOLD') { $this->base_table_properties['FONT-WEIGHT'] = 'BOLD'; }
17308 }
17309 if (isset($properties['FONT-STYLE'])) {
17310 if (strtoupper($properties['FONT-STYLE']) == 'ITALIC') { $this->base_table_properties['FONT-STYLE'] = 'ITALIC'; }
17311 }
17312 if (isset($properties['COLOR'])) {
17313 $this->base_table_properties['COLOR'] = $properties['COLOR'];
17314 }
17315 if (isset($properties['FONT-KERNING'])) {
17316 $this->base_table_properties['FONT-KERNING'] = $properties['FONT-KERNING'];
17317 }
17318 if (isset($properties['LETTER-SPACING'])) {
17319 $this->base_table_properties['LETTER-SPACING'] = $properties['LETTER-SPACING'];
17320 }
17321 if (isset($properties['WORD-SPACING'])) {
17322 $this->base_table_properties['WORD-SPACING'] = $properties['WORD-SPACING'];
17323 }
17324
17325 if (isset($properties['PADDING-LEFT'])) {
17326 $table['padding']['L'] = $this->ConvertSize($properties['PADDING-LEFT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
17327 }
17328 if (isset($properties['PADDING-RIGHT'])) {
17329 $table['padding']['R'] = $this->ConvertSize($properties['PADDING-RIGHT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
17330 }
17331 if (isset($properties['PADDING-TOP'])) {
17332 $table['padding']['T'] = $this->ConvertSize($properties['PADDING-TOP'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
17333 }
17334 if (isset($properties['PADDING-BOTTOM'])) {
17335 $table['padding']['B'] = $this->ConvertSize($properties['PADDING-BOTTOM'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
17336 }
17337
17338 if (isset($properties['MARGIN-TOP'])) {
17339 if ($lastbottommargin) {
17340 $tmp = $this->ConvertSize($properties['MARGIN-TOP'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
17341 if ($tmp > $lastbottommargin) { $properties['MARGIN-TOP'] -= $lastbottommargin; }
17342 else { $properties['MARGIN-TOP'] = 0; }
17343 }
17344 $table['margin']['T'] = $this->ConvertSize($properties['MARGIN-TOP'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
17345 }
17346
17347 if (isset($properties['MARGIN-BOTTOM'])) {
17348 $table['margin']['B'] = $this->ConvertSize($properties['MARGIN-BOTTOM'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
17349 }
17350 if (isset($properties['MARGIN-LEFT'])) {
17351 $table['margin']['L'] = $this->ConvertSize($properties['MARGIN-LEFT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
17352 }
17353
17354 if (isset($properties['MARGIN-RIGHT'])) {
17355 $table['margin']['R'] = $this->ConvertSize($properties['MARGIN-RIGHT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
17356 }
17357 if (isset($properties['MARGIN-LEFT']) && isset($properties['MARGIN-RIGHT']) && strtolower($properties['MARGIN-LEFT'])=='auto' && strtolower($properties['MARGIN-RIGHT'])=='auto') {
17358 $table['a'] = 'C';
17359 }
17360 else if (isset($properties['MARGIN-LEFT']) && strtolower($properties['MARGIN-LEFT'])=='auto') {
17361 $table['a'] = 'R';
17362 }
17363 else if (isset($properties['MARGIN-RIGHT']) && strtolower($properties['MARGIN-RIGHT'])=='auto') {
17364 $table['a'] = 'L';
17365 }
17366
17367 if (isset($properties['LINE-HEIGHT']) && $this->tableLevel==1) {
17368 $this->table_lineheight = $this->fixLineheight($properties['LINE-HEIGHT']);
17369 if (!$this->table_lineheight) { $this->table_lineheight = $this->normalLineheight; }
17370 }
17371
17372 if (isset($properties['BORDER-COLLAPSE']) && strtoupper($properties['BORDER-COLLAPSE'])=='SEPARATE') {
17373 $table['borders_separate'] = true;
17374 }
17375 else {
17376 $table['borders_separate'] = false;
17377 }
17378
17379 if (!$table['borders_separate']) { $table['border_spacing_H'] = $table['border_spacing_V'] = 0; }
17380 else if (isset($attr['CELLSPACING'])) {
17381 $table['border_spacing_H'] = $table['border_spacing_V'] = $this->ConvertSize($attr['CELLSPACING'],$this->blk[$this->blklvl]['inner_width']);
17382 }
17383 if (isset($properties['BORDER-SPACING-H'])) {
17384 $table['border_spacing_H'] = $this->ConvertSize($properties['BORDER-SPACING-H'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
17385 }
17386 if (isset($properties['BORDER-SPACING-V'])) {
17387 $table['border_spacing_V'] = $this->ConvertSize($properties['BORDER-SPACING-V'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
17388 }
17389
17390 if (isset($properties['EMPTY-CELLS'])) {
17391 $table['empty_cells'] = strtolower($properties['EMPTY-CELLS']); // 'hide' or 'show'
17392 }
17393 else { $table['empty_cells'] = ''; }
17394
17395 if (isset($properties['PAGE-BREAK-INSIDE']) && strtoupper($properties['PAGE-BREAK-INSIDE'])=='AVOID' && $this->tableLevel==1 && !$this->writingHTMLfooter) {
17396 $this->table_keep_together = true;
17397 }
17398 else if ($this->tableLevel==1) {
17399 $this->table_keep_together = false;
17400 }
17401 if (isset($properties['PAGE-BREAK-AFTER']) && $this->tableLevel==1) {
17402 $table['page_break_after'] = strtoupper($properties['PAGE-BREAK-AFTER']);
17403 }
17404
17405/*-- BACKGROUNDS --*/
17406 if (isset($properties['BACKGROUND-GRADIENT']) && !$this->kwt && !$this->ColActive) { $table['gradient'] = $properties['BACKGROUND-GRADIENT']; }
17407
17408 if (isset($properties['BACKGROUND-IMAGE']) && $properties['BACKGROUND-IMAGE'] && !$this->kwt && !$this->ColActive) {
17409 $ret = $this->SetBackground($properties, $currblk['inner_width']);
17410 if ($ret) { $table['background-image'] = $ret; }
17411 }
17412/*-- END BACKGROUNDS --*/
17413
17414 if (isset($properties['OVERFLOW'])) {
17415 $table['overflow'] = strtolower($properties['OVERFLOW']); // 'hidden' 'wrap' or 'visible' or 'auto'
17416 if (($this->ColActive || $this->tableLevel>1) && $table['overflow']=='visible') { unset($table['overflow']); }
17417 }
17418
17419 $properties = array();
17420
17421
17422
17423 if (isset($attr['CELLPADDING'])) {
17424 $table['cell_padding'] = $attr['CELLPADDING'];
17425 }
17426 else {
17427 $table['cell_padding'] = false;
17428 }
17429
17430 if (isset($attr['BORDER']) && $attr['BORDER']=='1') { // mPDF 5.5.08
17431 $this->table_border_attr_set = 1; // mPDF 5.5.08
17432 $bord = $this->border_details('#000000 1px solid');
17433 if ($bord['s']) {
17434 $table['border'] = _BORDER_ALL;
17435 $table['border_details']['R'] = $bord;
17436 $table['border_details']['L'] = $bord;
17437 $table['border_details']['T'] = $bord;
17438 $table['border_details']['B'] = $bord;
17439 }
17440 }
17441 else {
17442 $this->table_border_attr_set = 0;
17443 }
17444
17445 if ($w) {
17446 $maxwidth = $this->blk[$this->blklvl]['inner_width'];
17447 if ($table['borders_separate']) {
17448 $tblblw = $table['margin']['L'] + $table['margin']['R'] + $table['border_details']['L']['w']/2 + $table['border_details']['R']['w']/2;
17449 }
17450 else {
17451 $tblblw = $table['margin']['L'] + $table['margin']['R'] + $table['max_cell_border_width']['L']/2 + $table['max_cell_border_width']['R']/2;
17452 }
17453 if (strpos($w,'%') && $this->tableLevel == 1 && !$this->ignore_table_percents ) {
17454 // % needs to be of inner box without table margins etc.
17455 $maxwidth -= $tblblw ;
17456 $wmm = $this->ConvertSize($w,$maxwidth,$this->FontSize,false);
17457 $table['w'] = $wmm + $tblblw ;
17458 }
17459 if (strpos($w,'%') && $this->tableLevel > 1 && !$this->ignore_table_percents && $this->keep_table_proportions) {
17460 $table['wpercent'] = $w + 0; // makes 80% -> 80
17461 }
17462 if (!strpos($w,'%') && !$this->ignore_table_widths ) {
17463 $wmm = $this->ConvertSize($w,$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
17464 $table['w'] = $wmm + $tblblw ;
17465 }
17466 if (!$this->keep_table_proportions) {
17467 if (isset($table['w']) && $table['w'] > $this->blk[$this->blklvl]['inner_width']) { $table['w'] = $this->blk[$this->blklvl]['inner_width']; }
17468 }
17469 }
17470
17471 if (isset($attr['AUTOSIZE']) && $this->tableLevel==1) {
17472 $this->shrink_this_table_to_fit = $attr['AUTOSIZE'];
17473 if ($this->shrink_this_table_to_fit < 1) { $this->shrink_this_table_to_fit = 1; }
17474 }
17475 if (isset($attr['ROTATE']) && $this->tableLevel==1) {
17476 $this->table_rotate = $attr['ROTATE'];
17477 }
17478
17479 //++++++++++++++++++++++++++++
17480 // keeping block together on one page
17481 // Autosize is now forced therefore keep block together disabled
17482 if ($this->keep_block_together) {
17483 $this->keep_block_together = 0;
17484 $this->printdivbuffer();
17485 $this->blk[$this->blklvl]['keep_block_together'] = 0;
17486 }
17487 if ($this->table_rotate) {
17488 $this->tbrot_Links = array();
17489 $this->tbrot_Annots = array();
17490 $this->tbrotForms = array();
17491 $this->tbrot_Reference = array();
17492 $this->tbrot_BMoutlines = array();
17493 $this->tbrot_toc = array();
17494 }
17495
17496 if ($this->kwt) {
17497 if ($this->table_rotate) { $this->table_keep_together = true; }
17498 $this->kwt = false;
17499 $this->kwt_saved = true;
17500 }
17501
17502 if ($this->tableLevel==1 && $this->useGraphs) {
17503 if (isset($attr['ID']) && $attr['ID']) { $this->currentGraphId = strtoupper($attr['ID']); }
17504 else { $this->currentGraphId = '0'; }
17505 $this->graphs[$this->currentGraphId] = array();
17506 }
17507 //++++++++++++++++++++++++++++
17508 $this->plainCell_properties = array();
17509 unset($table);
17510 break;
17511
17512 case 'THEAD':
17513 $this->lastoptionaltag = $tag; // Save current HTML specified optional endtag
17514 $this->cssmgr->tbCSSlvl++;
17515 $this->tablethead = 1;
17516 $this->tabletfoot = 0;
17517 $properties = $this->cssmgr->MergeCSS('TABLE',$tag,$attr);
17518 if (isset($properties['FONT-WEIGHT'])) {
17519 if (strtoupper($properties['FONT-WEIGHT']) == 'BOLD') { $this->thead_font_weight = 'B'; }
17520 else { $this->thead_font_weight = ''; }
17521 }
17522
17523 if (isset($properties['FONT-STYLE'])) {
17524 if (strtoupper($properties['FONT-STYLE']) == 'ITALIC') { $this->thead_font_style = 'I'; }
17525 else { $this->thead_font_style = ''; }
17526 }
17527 if (isset($properties['FONT-VARIANT'])) {
17528 if (strtoupper($properties['FONT-VARIANT']) == 'SMALL-CAPS') { $this->thead_font_smCaps = 'S'; }
17529 else { $this->thead_font_smCaps = ''; }
17530 }
17531
17532 if (isset($properties['VERTICAL-ALIGN'])) {
17533 $this->thead_valign_default = $properties['VERTICAL-ALIGN'];
17534 }
17535 if (isset($properties['TEXT-ALIGN'])) {
17536 $this->thead_textalign_default = $properties['TEXT-ALIGN'];
17537 }
17538 $properties = array();
17539 break;
17540
17541 case 'TFOOT':
17542 $this->lastoptionaltag = $tag; // Save current HTML specified optional endtag
17543 $this->cssmgr->tbCSSlvl++;
17544 $this->tabletfoot = 1;
17545 $this->tablethead = 0;
17546 $properties = $this->cssmgr->MergeCSS('TABLE',$tag,$attr);
17547 if (isset($properties['FONT-WEIGHT'])) {
17548 if (strtoupper($properties['FONT-WEIGHT']) == 'BOLD') { $this->tfoot_font_weight = 'B'; }
17549 else { $this->tfoot_font_weight = ''; }
17550 }
17551
17552 if (isset($properties['FONT-STYLE'])) {
17553 if (strtoupper($properties['FONT-STYLE']) == 'ITALIC') { $this->tfoot_font_style = 'I'; }
17554 else { $this->tfoot_font_style = ''; }
17555 }
17556 if (isset($properties['FONT-VARIANT'])) {
17557 if (strtoupper($properties['FONT-VARIANT']) == 'SMALL-CAPS') { $this->tfoot_font_smCaps = 'S'; }
17558 else { $this->tfoot_font_smCaps = ''; }
17559 }
17560
17561 if (isset($properties['VERTICAL-ALIGN'])) {
17562 $this->tfoot_valign_default = $properties['VERTICAL-ALIGN'];
17563 }
17564 if (isset($properties['TEXT-ALIGN'])) {
17565 $this->tfoot_textalign_default = $properties['TEXT-ALIGN'];
17566 }
17567 $properties = array();
17568 break;
17569
17570
17571 case 'TBODY':
17572 $this->tablethead = 0;
17573 $this->tabletfoot = 0;
17574 $this->lastoptionaltag = $tag; // Save current HTML specified optional endtag
17575 $this->cssmgr->tbCSSlvl++;
17576 $this->cssmgr->MergeCSS('TABLE',$tag,$attr);
17577 break;
17578
17579
17580 case 'TR':
17581 $this->lastoptionaltag = $tag; // Save current HTML specified optional endtag
17582 $this->cssmgr->tbCSSlvl++;
17583 $this->row++;
17584 $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['nr']++;
17585 $this->col = -1;
17586 $properties = $this->cssmgr->MergeCSS('TABLE',$tag,$attr);
17587
17588 if (!$this->simpleTables && (!isset($this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['borders_separate']) || !$this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['borders_separate'])) {
17589 if (isset($properties['BORDER-LEFT']) && $properties['BORDER-LEFT']) { $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['trborder-left'][$this->row] = $properties['BORDER-LEFT']; }
17590 if (isset($properties['BORDER-RIGHT']) && $properties['BORDER-RIGHT']) { $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['trborder-right'][$this->row] = $properties['BORDER-RIGHT']; }
17591 if (isset($properties['BORDER-TOP']) && $properties['BORDER-TOP']) { $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['trborder-top'][$this->row] = $properties['BORDER-TOP']; }
17592 if (isset($properties['BORDER-BOTTOM']) && $properties['BORDER-BOTTOM']) { $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['trborder-bottom'][$this->row] = $properties['BORDER-BOTTOM']; }
17593 }
17594
17595 if (isset($properties['BACKGROUND-COLOR'])) { $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['bgcolor'][$this->row] = $properties['BACKGROUND-COLOR']; }
17596 else if (isset($attr['BGCOLOR'])) $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['bgcolor'][$this->row] = $attr['BGCOLOR'];
17597
17598/*-- BACKGROUNDS --*/
17599 if (isset($properties['BACKGROUND-GRADIENT']) && !$this->kwt && !$this->ColActive) { $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['trgradients'][$this->row] = $properties['BACKGROUND-GRADIENT']; }
17600
17601 if (isset($properties['BACKGROUND-IMAGE']) && $properties['BACKGROUND-IMAGE'] && !$this->kwt && !$this->ColActive) {
17602 $ret = $this->SetBackground($properties, $currblk['inner_width']);
17603 if ($ret) { $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['trbackground-images'][$this->row] = $ret; }
17604 }
17605/*-- END BACKGROUNDS --*/
17606
17607
17608 if (isset($properties['TEXT-ROTATE'])) {
17609 $this->trow_text_rotate = $properties['TEXT-ROTATE'];
17610 }
17611 if (isset($attr['TEXT-ROTATE'])) $this->trow_text_rotate = $attr['TEXT-ROTATE'];
17612
17613 if ($this->tablethead) { $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['is_thead'][$this->row] = true; }
17614 if ($this->tabletfoot) { $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['is_tfoot'][$this->row] = true; }
17615 $properties = array();
17616 break;
17617
17618
17619 case 'TH':
17620 case 'TD':
17621 $this->ignorefollowingspaces = true;
17622 $this->lastoptionaltag = $tag; // Save current HTML specified optional endtag
17623 $this->cssmgr->tbCSSlvl++;
17624 $this->InlineProperties = array();
17625 $this->spanlvl = 0;
17626 $this->tdbegin = true;
17627 $this->col++;
17628 while (isset($this->cell[$this->row][$this->col])) { $this->col++; }
17629
17630 //Update number column
17631 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; }
17632
17633 $table = &$this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]];
17634
17635 $c = array('a' => false,
17636 'R' => false,
17637 'nowrap' => false,
17638 'bgcolor' => false,
17639 'padding' => array('L' => false,
17640 'R' => false,
17641 'T' => false,
17642 'B' => false
17643 )
17644 );
17645
17646 if ($this->simpleTables && $this->row==0 && $this->col==0){
17647 $table['simple']['border'] = false;
17648 $table['simple']['border_details']['R']['w'] = 0;
17649 $table['simple']['border_details']['L']['w'] = 0;
17650 $table['simple']['border_details']['T']['w'] = 0;
17651 $table['simple']['border_details']['B']['w'] = 0;
17652 $table['simple']['border_details']['R']['style'] = '';
17653 $table['simple']['border_details']['L']['style'] = '';
17654 $table['simple']['border_details']['T']['style'] = '';
17655 $table['simple']['border_details']['B']['style'] = '';
17656 }
17657 else if (!$this->simpleTables) {
17658 $c['border'] = false;
17659 $c['border_details']['R']['w'] = 0;
17660 $c['border_details']['L']['w'] = 0;
17661 $c['border_details']['T']['w'] = 0;
17662 $c['border_details']['B']['w'] = 0;
17663 $c['border_details']['mbw']['BL'] = 0;
17664 $c['border_details']['mbw']['BR'] = 0;
17665 $c['border_details']['mbw']['RT'] = 0;
17666 $c['border_details']['mbw']['RB'] = 0;
17667 $c['border_details']['mbw']['TL'] = 0;
17668 $c['border_details']['mbw']['TR'] = 0;
17669 $c['border_details']['mbw']['LT'] = 0;
17670 $c['border_details']['mbw']['LB'] = 0;
17671 $c['border_details']['R']['style'] = '';
17672 $c['border_details']['L']['style'] = '';
17673 $c['border_details']['T']['style'] = '';
17674 $c['border_details']['B']['style'] = '';
17675 $c['border_details']['R']['s'] = 0;
17676 $c['border_details']['L']['s'] = 0;
17677 $c['border_details']['T']['s'] = 0;
17678 $c['border_details']['B']['s'] = 0;
17679 $c['border_details']['R']['c'] = $this->ConvertColor(0);
17680 $c['border_details']['L']['c'] = $this->ConvertColor(0);
17681 $c['border_details']['T']['c'] = $this->ConvertColor(0);
17682 $c['border_details']['B']['c'] = $this->ConvertColor(0);
17683 $c['border_details']['R']['dom'] = 0;
17684 $c['border_details']['L']['dom'] = 0;
17685 $c['border_details']['T']['dom'] = 0;
17686 $c['border_details']['B']['dom'] = 0;
17687 }
17688
17689
17690 if ($table['va']) { $c['va'] = $table['va']; }
17691 if ($table['txta']) { $c['a'] = $table['txta']; }
17692 if ($this->table_border_attr_set) {
17693 if ($table['border_details']) {
17694 if (!$this->simpleTables){
17695 $c['border_details']['R'] = $table['border_details']['R'];
17696 $c['border_details']['L'] = $table['border_details']['L'];
17697 $c['border_details']['T'] = $table['border_details']['T'];
17698 $c['border_details']['B'] = $table['border_details']['B'];
17699 $c['border'] = $table['border'];
17700 $c['border_details']['L']['dom'] = 1;
17701 $c['border_details']['R']['dom'] = 1;
17702 $c['border_details']['T']['dom'] = 1;
17703 $c['border_details']['B']['dom'] = 1;
17704 }
17705 else if ($this->simpleTables && $this->row==0 && $this->col==0){
17706 $table['simple']['border_details']['R'] = $table['border_details']['R'];
17707 $table['simple']['border_details']['L'] = $table['border_details']['L'];
17708 $table['simple']['border_details']['T'] = $table['border_details']['T'];
17709 $table['simple']['border_details']['B'] = $table['border_details']['B'];
17710 $table['simple']['border'] = $table['border'];
17711 }
17712 }
17713 }
17714 // INHERITED THEAD CSS Properties
17715 if ($this->tablethead) {
17716 if ($this->thead_valign_default) $c['va'] = $align[strtolower($this->thead_valign_default)];
17717 if ($this->thead_textalign_default) $c['a'] = $align[strtolower($this->thead_textalign_default)];
17718 if ($this->thead_font_weight == 'B') { $this->SetStyle('B',true); }
17719 if ($this->thead_font_style == 'I') { $this->SetStyle('I',true); }
17720 if ($this->thead_font_smCaps == 'S') { $this->SetStyle('S',true); }
17721 }
17722
17723 // INHERITED TFOOT CSS Properties
17724 if ($this->tabletfoot) {
17725 if ($this->tfoot_valign_default) $c['va'] = $align[strtolower($this->tfoot_valign_default)];
17726 if ($this->tfoot_textalign_default) $c['a'] = $align[strtolower($this->tfoot_textalign_default)];
17727 if ($this->tfoot_font_weight == 'B') { $this->SetStyle('B',true); }
17728 if ($this->tfoot_font_style == 'I') { $this->SetStyle('I',true); }
17729 if ($this->tfoot_font_style == 'S') { $this->SetStyle('S',true); }
17730 }
17731
17732
17733 if ($this->trow_text_rotate){
17734 $c['R'] = $this->trow_text_rotate;
17735 }
17736
17737 $this->cell_border_dominance_L = 0;
17738 $this->cell_border_dominance_R = 0;
17739 $this->cell_border_dominance_T = 0;
17740 $this->cell_border_dominance_B = 0;
17741
17742 $properties = $this->cssmgr->MergeCSS('TABLE',$tag,$attr);
17743 $properties = $this->cssmgr->array_merge_recursive_unique($this->base_table_properties, $properties);
17744
17745 if (isset($properties['FONT-KERNING']) && (strtoupper($properties['FONT-KERNING'])=='NORMAL' || strtoupper($properties['FONT-KERNING'])=='AUTO')) {
17746 $this->kerning = true;
17747 }
17748 else { $this->kerning = false; }
17749
17750 if (isset($properties['LETTER-SPACING']) && ($properties['LETTER-SPACING'] || $properties['LETTER-SPACING']==='0') && strtoupper($properties['LETTER-SPACING']) != 'NORMAL') {
17751 $this->lSpacingCSS = strtoupper($properties['LETTER-SPACING']);
17752 $this->fixedlSpacing = $this->ConvertSize($this->lSpacingCSS,$this->FontSize);
17753 }
17754 else {
17755 $this->lSpacingCSS = '';
17756 $this->fixedlSpacing = false;
17757 }
17758 if (isset($properties['WORD-SPACING']) && strtoupper($properties['WORD-SPACING']) != 'NORMAL') {
17759 $this->wSpacingCSS = strtoupper($properties['WORD-SPACING']);
17760 $this->minwSpacing = $this->ConvertSize($this->wSpacingCSS,$this->FontSize);
17761 }
17762 else {
17763 $this->minwSpacing = 0;
17764 $this->wSpacingCSS = '';
17765 }
17766 // mPDF 5.6.08
17767 if (isset($properties['HYPHENS']) && $properties['HYPHENS']) {
17768 if (strtoupper($properties['HYPHENS']) == 'NONE') { $this->textparam['hyphens'] = 2; }
17769 else if (strtoupper($properties['HYPHENS']) == 'AUTO') { $this->textparam['hyphens'] = 1; }
17770 else if (strtoupper($properties['HYPHENS']) == 'MANUAL') { $this->textparam['hyphens'] = 0; }
17771 }
17772
17773 if (isset($properties['BACKGROUND-COLOR'])) { $c['bgcolor'] = $properties['BACKGROUND-COLOR']; }
17774 else if (isset($properties['BACKGROUND'])) { $c['bgcolor'] = $properties['BACKGROUND']; }
17775 else if (isset($attr['BGCOLOR'])) $c['bgcolor'] = $attr['BGCOLOR'];
17776
17777
17778
17779/*-- BACKGROUNDS --*/
17780 if (isset($properties['BACKGROUND-GRADIENT'])) { $c['gradient'] = $properties['BACKGROUND-GRADIENT']; }
17781 else { $c['gradient'] = false; }
17782
17783 if (isset($properties['BACKGROUND-IMAGE']) && $properties['BACKGROUND-IMAGE'] && !$this->keep_block_together) {
17784 $ret = $this->SetBackground($properties, $this->blk[$this->blklvl]['inner_width']);
17785 if ($ret) { $c['background-image'] = $ret; }
17786 }
17787/*-- END BACKGROUNDS --*/
17788 if (isset($properties['VERTICAL-ALIGN'])) { $c['va']=$align[strtolower($properties['VERTICAL-ALIGN'])]; }
17789 else if (isset($attr['VALIGN'])) $c['va'] = $align[strtolower($attr['VALIGN'])];
17790
17791
17792 // mPDF 5.6.13
17793 if (isset($properties['TEXT-ALIGN']) && $properties['TEXT-ALIGN']) {
17794 if (substr($properties['TEXT-ALIGN'],0,1)=='D') { $c['a'] = $properties['TEXT-ALIGN']; }
17795 else { $c['a'] = $align[strtolower($properties['TEXT-ALIGN'])]; }
17796 }
17797 // mPDF 5.6.13
17798 if (isset($attr['ALIGN']) && $attr['ALIGN']) {
17799 if (strtolower($attr['ALIGN']) == 'char') {
17800 if (isset($attr['CHAR']) && $attr['CHAR']) {
17801 $char = html_entity_decode($attr['CHAR']);
17802 $char = strcode2utf($char);
17803 $d = array_search($char,$this->decimal_align);
17804 if ($d !== false) { $c['a'] = $d.'R'; }
17805 }
17806 else { $c['a'] = 'DPR'; }
17807 }
17808 else { $c['a'] = $align[strtolower($attr['ALIGN'])]; }
17809 }
17810
17811 if (!$c['a']) {
17812 if (isset($table['direction']) && $table['direction'] == 'rtl' ) { $c['a'] = 'R'; }
17813 else { $c['a'] = 'L'; }
17814 }
17815
17816
17817 if (isset($properties['TEXT-ROTATE']) && ($properties['TEXT-ROTATE'] || $properties['TEXT-ROTATE']==="0")){
17818 $c['R'] = $properties['TEXT-ROTATE'];
17819 }
17820 if (isset($properties['BORDER'])) {
17821 $bord = $this->border_details($properties['BORDER']);
17822 if ($bord['s']) {
17823 if (!$this->simpleTables){
17824 $c['border'] = _BORDER_ALL;
17825 $c['border_details']['R'] = $bord;
17826 $c['border_details']['L'] = $bord;
17827 $c['border_details']['T'] = $bord;
17828 $c['border_details']['B'] = $bord;
17829 $c['border_details']['L']['dom'] = $this->cell_border_dominance_L;
17830 $c['border_details']['R']['dom'] = $this->cell_border_dominance_R;
17831 $c['border_details']['T']['dom'] = $this->cell_border_dominance_T;
17832 $c['border_details']['B']['dom'] = $this->cell_border_dominance_B;
17833 }
17834 else if ($this->simpleTables && $this->row==0 && $this->col==0){
17835 $table['simple']['border'] = _BORDER_ALL;
17836 $table['simple']['border_details']['R'] = $bord;
17837 $table['simple']['border_details']['L'] = $bord;
17838 $table['simple']['border_details']['T'] = $bord;
17839 $table['simple']['border_details']['B'] = $bord;
17840 }
17841 }
17842 }
17843 if (!$this->simpleTables){
17844 if (isset($properties['BORDER-RIGHT']) && $properties['BORDER-RIGHT']) {
17845 $c['border_details']['R'] = $this->border_details($properties['BORDER-RIGHT']);
17846 $this->setBorder($c['border'], _BORDER_RIGHT, $c['border_details']['R']['s']);
17847 $c['border_details']['R']['dom'] = $this->cell_border_dominance_R;
17848 }
17849 if (isset($properties['BORDER-LEFT']) && $properties['BORDER-LEFT']) {
17850 $c['border_details']['L'] = $this->border_details($properties['BORDER-LEFT']);
17851 $this->setBorder($c['border'], _BORDER_LEFT, $c['border_details']['L']['s']);
17852 $c['border_details']['L']['dom'] = $this->cell_border_dominance_L;
17853 }
17854 if (isset($properties['BORDER-BOTTOM']) && $properties['BORDER-BOTTOM']) {
17855 $c['border_details']['B'] = $this->border_details($properties['BORDER-BOTTOM']);
17856 $this->setBorder($c['border'], _BORDER_BOTTOM, $c['border_details']['B']['s']);
17857 $c['border_details']['B']['dom'] = $this->cell_border_dominance_B;
17858 }
17859 if (isset($properties['BORDER-TOP']) && $properties['BORDER-TOP']) {
17860 $c['border_details']['T'] = $this->border_details($properties['BORDER-TOP']);
17861 $this->setBorder($c['border'], _BORDER_TOP, $c['border_details']['T']['s']);
17862 $c['border_details']['T']['dom'] = $this->cell_border_dominance_T;
17863 }
17864 }
17865 else if ($this->simpleTables && $this->row==0 && $this->col==0){
17866 if (isset($properties['BORDER-LEFT']) && $properties['BORDER-LEFT']) {
17867 $bord = $this->border_details($properties['BORDER-LEFT']);
17868 if ($bord['s']) { $table['simple']['border'] = _BORDER_ALL; }
17869 else { $table['simple']['border'] = 0; }
17870 $table['simple']['border_details']['R'] = $bord;
17871 $table['simple']['border_details']['L'] = $bord;
17872 $table['simple']['border_details']['T'] = $bord;
17873 $table['simple']['border_details']['B'] = $bord;
17874 }
17875 }
17876
17877 if ($this->simpleTables && $this->row==0 && $this->col==0 && !$table['borders_separate'] && $table['simple']['border'] ){
17878 $table['border_details'] = $table['simple']['border_details'];
17879 $table['border'] = $table['simple']['border'];
17880 }
17881
17882 // Border set on TR (if collapsed only)
17883 if (!$table['borders_separate'] && !$this->simpleTables && isset($table['trborder-left'][$this->row])) {
17884 if ($this->col==0) {
17885 $left = $this->border_details($table['trborder-left'][$this->row]);
17886 $c['border_details']['L'] = $left;
17887 $this->setBorder($c['border'], _BORDER_LEFT, $c['border_details']['L']['s']);
17888 }
17889 $c['border_details']['B'] = $this->border_details($table['trborder-bottom'][$this->row]);
17890 $this->setBorder($c['border'], _BORDER_BOTTOM, $c['border_details']['B']['s']);
17891 $c['border_details']['T'] = $this->border_details($table['trborder-top'][$this->row]);
17892 $this->setBorder($c['border'], _BORDER_TOP, $c['border_details']['T']['s']);
17893 }
17894
17895 if ($this->packTableData && !$this->simpleTables) {
17896 $c['borderbin'] = $this->_packCellBorder($c);
17897 unset($c['border']);
17898 unset($c['border_details']);
17899 }
17900
17901 if (isset($properties['PADDING-LEFT'])) {
17902 $c['padding']['L'] = $this->ConvertSize($properties['PADDING-LEFT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
17903 }
17904 if (isset($properties['PADDING-RIGHT'])) {
17905 $c['padding']['R'] = $this->ConvertSize($properties['PADDING-RIGHT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
17906 }
17907 if (isset($properties['PADDING-BOTTOM'])) {
17908 $c['padding']['B'] = $this->ConvertSize($properties['PADDING-BOTTOM'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
17909 }
17910 if (isset($properties['PADDING-TOP'])) {
17911 $c['padding']['T'] = $this->ConvertSize($properties['PADDING-TOP'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
17912 }
17913
17914 $w = '';
17915 if (isset($properties['WIDTH'])) { $w = $properties['WIDTH']; }
17916 else if (isset($attr['WIDTH'])) { $w = $attr['WIDTH']; }
17917 if ($w) {
17918 if (strpos($w,'%') && !$this->ignore_table_percents ) { $c['wpercent'] = $w + 0; } // makes 80% -> 80
17919 else if (!strpos($w,'%') && !$this->ignore_table_widths ) { $c['w'] = $this->ConvertSize($w,$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
17920 }
17921
17922 if (isset($properties['HEIGHT']) && !strpos($properties['HEIGHT'],'%')) { $c['h'] = $this->ConvertSize($properties['HEIGHT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
17923 else if (isset($attr['HEIGHT']) && !strpos($attr['HEIGHT'],'%')) $c['h'] = $this->ConvertSize($attr['HEIGHT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
17924
17925
17926 if (isset($properties['COLOR'])) {
17927 $cor = $this->ConvertColor($properties['COLOR']);
17928 if ($cor) {
17929 $this->colorarray = $cor;
17930 $this->SetTColor($cor);
17931 }
17932 }
17933 if (isset($properties['FONT-FAMILY'])) {
17934 $this->SetFont($properties['FONT-FAMILY'],'',0,false);
17935 }
17936 if (isset($properties['FONT-SIZE'])) {
17937 $mmsize = $this->ConvertSize($properties['FONT-SIZE'],$this->default_font_size/_MPDFK);
17938 if ($mmsize) {
17939 $this->SetFontSize($mmsize*(_MPDFK),false);
17940 }
17941 }
17942 $c['dfs'] = $this->FontSize; // Default Font size
17943 if (isset($properties['FONT-WEIGHT'])) {
17944 if (strtoupper($properties['FONT-WEIGHT']) == 'BOLD') { $this->SetStyle('B',true); }
17945 }
17946 if (isset($properties['FONT-STYLE'])) {
17947 if (strtoupper($properties['FONT-STYLE']) == 'ITALIC') { $this->SetStyle('I',true); }
17948 }
17949 if (isset($properties['FONT-VARIANT'])) {
17950 if (strtoupper($properties['FONT-VARIANT']) == 'SMALL-CAPS') { $this->SetStyle('S',true); }
17951 }
17952 if (isset($properties['TEXT-DECORATION'])) {
17953 if (strtoupper($properties['TEXT-DECORATION']) == 'LINE-THROUGH') { $this->strike = true; }
17954 else if (strtoupper($properties['TEXT-DECORATION']) == 'UNDERLINE') { $this->SetStyle('U',true); }
17955 }
17956 if (isset($properties['TEXT-SHADOW'])) {
17957 $ts = $this->cssmgr->setCSStextshadow($properties['TEXT-SHADOW']);
17958 if ($ts) { $this->textshadow = $ts; }
17959 }
17960 if (isset($properties['TEXT-TRANSFORM'])) {
17961 if (strtoupper($properties['TEXT-TRANSFORM']) == 'CAPITALIZE') { $this->capitalize = true; }
17962 else if (strtoupper($properties['TEXT-TRANSFORM']) == 'UPPERCASE') { $this->toupper = true; }
17963 else if (strtoupper($properties['TEXT-TRANSFORM']) == 'LOWERCASE') { $this->tolower = true; }
17964 }
17965 if (isset($properties['WHITE-SPACE'])) {
17966 if (strtoupper($properties['WHITE-SPACE']) == 'NOWRAP') { $c['nowrap']= 1; }
17967 }
17968 $properties = array();
17969
17970 if (isset($attr['TEXT-ROTATE'])) {
17971 $c['R'] = $attr['TEXT-ROTATE'];
17972 }
17973 if (isset($attr['NOWRAP']) && $attr['NOWRAP']) $c['nowrap']= 1;
17974
17975 $this->cell[$this->row][$this->col] = $c;
17976 unset($c);
17977 $this->cell[$this->row][$this->col]['s'] = 0 ;
17978
17979 $cs = $rs = 1;
17980 if (isset($attr['COLSPAN']) && $attr['COLSPAN']>1) $cs = $this->cell[$this->row][$this->col]['colspan'] = $attr['COLSPAN'];
17981 if ($this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['nc'] < $this->col+$cs) {
17982 $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['nc'] = $this->col+$cs;
17983 } // following code moved outside if...
17984 for($l=$this->col; $l < $this->col+$cs ;$l++) {
17985 if ($l-$this->col) $this->cell[$this->row][$l] = 0;
17986 }
17987 if (isset($attr['ROWSPAN']) && $attr['ROWSPAN']>1) $rs = $this->cell[$this->row][$this->col]['rowspan'] = $attr['ROWSPAN'];
17988 for ($k=$this->row ; $k < $this->row+$rs ;$k++) {
17989 for($l=$this->col; $l < $this->col+$cs ;$l++) {
17990 if ($k-$this->row || $l-$this->col) $this->cell[$k][$l] = 0;
17991 }
17992 }
17993 unset($table);
17994 break;
17995/*-- END TABLES --*/
17996
17997
17998/*-- LISTS --*/
17999 // *********** LISTS ********************
18000 case 'OL':
18001 case 'UL':
18002 $this->listjustfinished = false;
18003
18004 if ($this->blockjustfinished && !count($this->textbuffer) && $this->y != $this->tMargin && $this->collapseBlockMargins) { $lastbottommargin = $this->lastblockbottommargin; }
18005 else { $lastbottommargin = 0; }
18006 $this->lastblockbottommargin = 0;
18007 $this->blockjustfinished=false;
18008
18009 $this->linebreakjustfinished=false;
18010 $this->lastoptionaltag = ''; // Save current HTML specified optional endtag
18011 $this->cssmgr->listCSSlvl++;
18012 if((!$this->tableLevel) && ($this->listlvl == 0)) {
18013 $blockstate = 0;
18014 //if ($this->lastblocklevelchange == 1) { $blockstate = -1; } // Top margins/padding only
18015 //else if ($this->lastblocklevelchange < 1) { $blockstate = 0; } // NO margins/padding
18016 // called from block after new div e.g. <div> ... <ol> ... Outputs block top margin/border and padding
18017 if (count($this->textbuffer) == 0 && $this->lastblocklevelchange == 1 && !$this->tableLevel && !$this->kwt) {
18018 $this->newFlowingBlock( $this->blk[$this->blklvl]['width'],$this->lineheight,'',false,false,1,true, $this->blk[$this->blklvl]['direction']);
18019 $this->finishFlowingBlock(true); // true = END of flowing block
18020 }
18021 else if (count($this->textbuffer)) { $this->printbuffer($this->textbuffer,$blockstate); }
18022 $this->textbuffer=array();
18023 $this->lastblocklevelchange = -1;
18024 }
18025 // ol and ul types are mixed here
18026 if ($this->listlvl == 0) {
18027 $this->list_indent = array();
18028 $this->list_align = array();
18029 $this->list_lineheight = array();
18030 $this->InlineProperties['LIST'] = array();
18031 $this->InlineProperties['LISTITEM'] = array();
18032 }
18033
18034/*-- TABLES --*/
18035 // A simple list for inside a table
18036 if($this->tableLevel) {
18037 $this->list_indent[$this->listlvl] = 0; // mm default indent for each level
18038 if ($tag == 'OL') $this->listtype = '1';
18039 else if ($tag == 'UL') $this->listtype = 'disc';
18040 if ($this->listlvl > 0) {
18041 $this->listlist[$this->listlvl]['MAXNUM'] = $this->listnum; //save previous lvl's maxnum
18042 }
18043 $this->listlvl++;
18044 // mPDF 5.6.15
18045 if (isset($attr['START'])) { $this->listnum = intval($attr['START']); }
18046 else { $this->listnum = 0; }
18047 $this->listlist[$this->listlvl] = array('TYPE'=>$this->listtype,'MAXNUM'=>$this->listnum);
18048 break;
18049 }
18050/*-- END TABLES --*/
18051
18052
18053 if (($this->PDFA || $this->PDFX) && $tag == 'UL') {
18054 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 '-')"; }
18055 }
18056
18057 if ($this->cssmgr->listCSSlvl==1) {
18058 $properties = $this->cssmgr->MergeCSS('TOPLIST',$tag,$attr);
18059 }
18060 else {
18061 $properties = $this->cssmgr->MergeCSS('LIST',$tag,$attr);
18062 }
18063 if (!empty($properties)) $this->setCSS($properties,'LIST');
18064 // List-type
18065
18066 $this->listtype = '';
18067 if (isset($properties['LIST-STYLE-TYPE'])) {
18068 $this->listtype = $this->_getListStyle($properties['LIST-STYLE-TYPE']);
18069 }
18070 else if (isset($properties['LIST-STYLE'])) {
18071 $this->listtype = $this->_getListStyle($properties['LIST-STYLE']);
18072 }
18073 else if (isset($attr['TYPE']) && $attr['TYPE']) { $this->listtype = $attr['TYPE']; }
18074 if (!$this->listtype) {
18075 if ($tag == 'OL') $this->listtype = '1';
18076 if ($tag == 'UL') {
18077 if ($this->listlvl % 3 == 0) $this->listtype = 'disc';
18078 elseif ($this->listlvl % 3 == 1) $this->listtype = 'circle';
18079 else $this->listtype = 'square';
18080 }
18081 }
18082 if ($this->listlvl == 0) {
18083 $this->inherit_lineheight = 0;
18084 $this->listlvl++; // first depth level
18085 // mPDF 5.6.15
18086 if (isset($attr['START'])) { $this->listnum = intval($attr['START']); }
18087 else { $this->listnum = 0; }
18088 $this->listDir = (isset($this->blk[$this->blklvl]['direction']) ? $this->blk[$this->blklvl]['direction'] : null);
18089 $occur = $this->listoccur[$this->listlvl] = 1;
18090 $this->listlist[$this->listlvl][1] = array('TYPE'=>$this->listtype,'MAXNUM'=>$this->listnum);
18091 }
18092 else {
18093 if (!empty($this->textbuffer))
18094 {
18095 $this->listitem[] = array($this->listlvl,$this->listnum,$this->textbuffer,$this->listoccur[$this->listlvl],$this->listitemtype);
18096 $this->listnum++;
18097 }
18098 // Save current lineheight to inherit
18099 $this->textbuffer = array();
18100 $occur = $this->listoccur[$this->listlvl];
18101 $this->listlist[$this->listlvl][$occur]['MAXNUM'] = $this->listnum; //save previous lvl's maxnum
18102 $this->listlvl++;
18103 // mPDF 5.6.15
18104 if (isset($attr['START'])) { $this->listnum = intval($attr['START']); }
18105 else { $this->listnum = 0; }
18106
18107
18108 if (!isset($this->listoccur[$this->listlvl]) || $this->listoccur[$this->listlvl] == 0) $this->listoccur[$this->listlvl] = 1;
18109 else $this->listoccur[$this->listlvl]++;
18110 $occur = $this->listoccur[$this->listlvl];
18111 $this->listlist[$this->listlvl][$occur] = array('TYPE'=>$this->listtype,'MAXNUM'=>$this->listnum);
18112 }
18113
18114
18115 // TOP LEVEL ONLY
18116 if ($this->listlvl == 1) {
18117 if (isset($properties['MARGIN-TOP'])) {
18118 if ($lastbottommargin) {
18119 $tmp = $this->ConvertSize($properties['MARGIN-TOP'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
18120 if ($tmp > $lastbottommargin) { $properties['MARGIN-TOP'] -= $lastbottommargin; }
18121 else { $properties['MARGIN-TOP'] = 0; }
18122 }
18123 $this->DivLn($this->ConvertSize($properties['MARGIN-TOP'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false),$this->blklvl,true,1); // collapsible
18124 }
18125 if (isset($properties['MARGIN-BOTTOM'])) {
18126 $this->list_margin_bottom = $this->ConvertSize($properties['MARGIN-BOTTOM'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
18127 }
18128
18129 if (isset($this->blk[$this->blklvl]['line_height'])) {
18130 $this->list_lineheight[$this->listlvl][$occur] = $this->blk[$this->blklvl]['line_height'];
18131 }
18132
18133 if (isset($properties['DIRECTION']) && $properties['DIRECTION']) { $this->listDir = strtolower($properties['DIRECTION']); }
18134 else if (isset($attr['DIR']) && $attr['DIR']) { $this->listDir = strtolower($attr['DIR']); }
18135
18136 }
18137 $this->list_indent[$this->listlvl][$occur] = 5; // mm default indent for each level
18138 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); }
18139
18140 if (isset($properties['TEXT-ALIGN'])) {
18141 $this->list_align[$this->listlvl][$occur] = $align[strtolower($properties['TEXT-ALIGN'])];
18142 }
18143
18144
18145 if (isset($properties['LINE-HEIGHT'])) {
18146 $this->list_lineheight[$this->listlvl][$occur] = $this->fixLineheight($properties['LINE-HEIGHT']);
18147 }
18148 else if ($this->listlvl>1 && isset($this->list_lineheight[($this->listlvl - 1)][1])) {
18149 $this->list_lineheight[$this->listlvl][$occur] = end($this->list_lineheight[($this->listlvl - 1)]);
18150 }
18151 if (!isset($this->list_lineheight[$this->listlvl][$occur]) || !$this->list_lineheight[$this->listlvl][$occur]) {
18152 $this->list_lineheight[$this->listlvl][$occur] = $this->normalLineheight;
18153 }
18154
18155 $this->InlineProperties['LIST'][$this->listlvl][$occur] = $this->saveInlineProperties();
18156 $properties = array();
18157 break;
18158
18159
18160
18161 case 'LI':
18162 // Start Block
18163 $this->lastoptionaltag = $tag; // Save current HTML specified optional endtag
18164 $this->ignorefollowingspaces = true; //Eliminate exceeding left-side spaces
18165/*-- TABLES --*/
18166 // A simple list for inside a table
18167 if($this->tableLevel) {
18168 $this->blockjustfinished=false;
18169
18170 // If already something in the Cell
18171 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 ) {
18172 $this->_saveCellTextBuffer("\n");
18173 if (!isset($this->cell[$this->row][$this->col]['maxs'])) {
18174 $this->cell[$this->row][$this->col]['maxs'] = $this->cell[$this->row][$this->col]['s'];
18175 }
18176 elseif($this->cell[$this->row][$this->col]['maxs'] < $this->cell[$this->row][$this->col]['s']) {
18177 $this->cell[$this->row][$this->col]['maxs'] = $this->cell[$this->row][$this->col]['s'];
18178 }
18179 $this->cell[$this->row][$this->col]['s'] = 0 ;
18180 }
18181 if ($this->listlvl == 0) { //in case of malformed HTML code. Example:(...)</p><li>Content</li><p>Paragraph1</p>(...)
18182 $this->listlvl++; // first depth level
18183 $this->listnum = 0; // reset
18184 $this->listlist[$this->listlvl] = array('TYPE'=>'disc','MAXNUM'=>$this->listnum);
18185 }
18186
18187 $this->listnum++;
18188 switch($this->listlist[$this->listlvl]['TYPE']) {
18189 case 'A':
18190 $blt = $this->dec2alpha($this->listnum,true).$this->list_number_suffix;
18191 break;
18192 case 'a':
18193 $blt = $this->dec2alpha($this->listnum,false).$this->list_number_suffix;
18194 break;
18195 case 'I':
18196 $blt = $this->dec2roman($this->listnum,true).$this->list_number_suffix;
18197 break;
18198 case 'i':
18199 $blt = $this->dec2roman($this->listnum,false).$this->list_number_suffix;
18200 break;
18201 case '1':
18202 $blt = $this->listnum.$this->list_number_suffix;
18203 break;
18204 default:
18205 if ($this->listlvl % 3 == 1 && $this->_charDefined($this->CurrentFont['cw'],8226)) { $blt = "\xe2\x80\xa2"; } // &#8226;
18206 else if ($this->listlvl % 3 == 2 && $this->_charDefined($this->CurrentFont['cw'],9900)) { $blt = "\xe2\x9a\xac"; } // &#9900;
18207 else if ($this->listlvl % 3 == 0 && $this->_charDefined($this->CurrentFont['cw'],9642)) { $blt = "\xe2\x96\xaa"; } // &#9642;
18208 else { $blt = '-'; }
18209 break;
18210 }
18211
18212 // change to &nbsp; spaces
18213 if ($this->usingCoreFont) {
18214 $ls = str_repeat(chr(160).chr(160),($this->listlvl-1)*2) . $blt . ' ';
18215 }
18216 else {
18217 $ls = str_repeat("\xc2\xa0\xc2\xa0",($this->listlvl-1)*2) . $blt . ' ';
18218 }
18219
18220 $this->_saveCellTextBuffer($ls, $this->HREF);
18221 $this->cell[$this->row][$this->col]['s'] += $this->GetStringWidth($ls);
18222 break;
18223 }
18224/*-- END TABLES --*/
18225 //Observation: </LI> is ignored
18226 if ($this->listlvl == 0) { //in case of malformed HTML code. Example:(...)</p><li>Content</li><p>Paragraph1</p>(...)
18227 //First of all, skip a line
18228 $this->listlvl++; // first depth level
18229 $this->listnum = 0; // reset
18230 $this->listoccur[$this->listlvl] = 1;
18231 $this->listlist[$this->listlvl][1] = array('TYPE'=>'disc','MAXNUM'=>$this->listnum);
18232 }
18233 if ($this->listnum == 0) {
18234 $this->listnum++;
18235 $this->textbuffer = array();
18236 }
18237 else {
18238 if (!empty($this->textbuffer)) {
18239 if (!$this->listjustfinished) {
18240 $this->listitem[] = array($this->listlvl,$this->listnum,$this->textbuffer,$this->listoccur[$this->listlvl],$this->listitemtype);
18241 $this->listnum++;
18242 }
18243 else {
18244 $this->listitem[] = array($this->listlvl,$this->listnum,$this->textbuffer,$this->listoccur[$this->listlvl],$this->listitemtype, true);
18245 }
18246 }
18247 $this->textbuffer = array();
18248 }
18249 $this->listjustfinished = false;
18250
18251 $this->cssmgr->listCSSlvl++;
18252 $properties = $this->cssmgr->MergeCSS('LIST',$tag,$attr);
18253 if (!empty($properties)) $this->setCSS($properties,'LIST');
18254 $this->InlineProperties['LISTITEM'][$this->listlvl][$this->listoccur[$this->listlvl]][$this->listnum] = $this->saveInlineProperties();
18255
18256 // List-type
18257 if (isset($properties['LIST-STYLE-TYPE'])) {
18258 $this->listitemtype = $this->_getListStyle($properties['LIST-STYLE-TYPE']);
18259 }
18260 else if (isset($properties['LIST-STYLE'])) {
18261 $this->listitemtype = $this->_getListStyle($properties['LIST-STYLE']);
18262 }
18263 else if (isset($attr['TYPE']) && $attr['TYPE']) { $this->listitemtype = $attr['TYPE']; }
18264 else $this->listitemtype = '';
18265 break;
18266/*-- END LISTS --*/
18267
18268 }//end of switch
18269}
18270
18271/*-- LISTS --*/
18272
18273function _getListStyle($ls) {
18274 if (stristr($ls,'decimal')) { return '1'; }
18275 else if (preg_match('/(disc|circle|square|arabic-indic|bengali|devanagari|gujarati|gurmukhi|kannada|malayalam|oriya|persian|tamil|telugu|thai|urdu|cambodian|khmer|lao)/i',$ls,$m)) {
18276 return strtolower(trim($m[1]));
18277 }
18278 else if (stristr($ls,'lower-roman')) { return 'i'; }
18279 else if (stristr($ls,'upper-roman')) { return 'I'; }
18280 else if (stristr($ls,'lower-latin')|| stristr($ls,'lower-alpha')) { return 'a'; }
18281 else if (stristr($ls,'upper-latin') || stristr($ls,'upper-alpha')) { return 'A'; }
18282 else if (stristr($ls,'none')) { return 'none'; }
18283 else if (preg_match('/U\+([a-fA-F0-9]+)/i',$ls)) { return $ls; }
18284 else { return ''; }
18285}
18286/*-- END LISTS --*/
18287
18288
18289
18290function CloseTag($tag)
18291{
18292 $this->ignorefollowingspaces = false; //Eliminate exceeding left-side spaces
18293 //Closing tag
18294 if($tag=='OPTION') { $this->selectoption['ACTIVE'] = false; $this->lastoptionaltag = ''; }
18295
18296 if($tag=='TTS' or $tag=='TTA' or $tag=='TTZ') {
18297 if ($this->InlineProperties[$tag]) { $this->restoreInlineProperties($this->InlineProperties[$tag]); }
18298 unset($this->InlineProperties[$tag]);
18299 $ltag = strtolower($tag);
18300 $this->$ltag = false;
18301 }
18302
18303
18304 if($tag=='FONT' || $tag=='SPAN' || $tag=='CODE' || $tag=='KBD' || $tag=='SAMP' || $tag=='TT' || $tag=='VAR'
18305 || $tag=='INS' || $tag=='STRONG' || $tag=='CITE' || $tag=='SUB' || $tag=='SUP' || $tag=='S' || $tag=='STRIKE' || $tag=='DEL'
18306 || $tag=='Q' || $tag=='EM' || $tag=='B' || $tag=='I' || $tag=='U' | $tag=='SMALL' || $tag=='BIG' || $tag=='ACRONYM'
18307 || $tag=='MARK' || $tag=='TIME' || $tag=='PROGRESS' || $tag=='METER'
18308 ) { // mPDF 5.5.09
18309
18310 if ($tag == 'SPAN') {
18311 if (isset($this->InlineProperties['SPAN'][$this->spanlvl]) && $this->InlineProperties['SPAN'][$this->spanlvl]) { $this->restoreInlineProperties($this->InlineProperties['SPAN'][$this->spanlvl]); }
18312 unset($this->InlineProperties['SPAN'][$this->spanlvl]);
18313 if (isset($this->InlineAnnots['SPAN'][$this->spanlvl]) && $this->InlineAnnots['SPAN'][$this->spanlvl]) { $annot = $this->InlineAnnots['SPAN'][$this->spanlvl]; } // *ANNOTATIONS*
18314 unset($this->InlineAnnots['SPAN'][$this->spanlvl]); // *ANNOTATIONS*
18315 $this->spanlvl--;
18316 }
18317 else {
18318 if (isset($this->InlineProperties[$tag]) && $this->InlineProperties[$tag]) { $this->restoreInlineProperties($this->InlineProperties[$tag]); }
18319 unset($this->InlineProperties[$tag]);
18320 if (isset($this->InlineAnnots[$tag]) && $this->InlineAnnots[$tag]) { $annot = $this->InlineAnnots[$tag]; } // *ANNOTATIONS*
18321 unset($this->InlineAnnots[$tag]); // *ANNOTATIONS*
18322 }
18323
18324/*-- ANNOTATIONS --*/
18325 if (isset($annot)) {
18326 if($this->tableLevel) { // *TABLES*
18327 $this->cell[$this->row][$this->col]['textbuffer'][] = array($annot); // *TABLES*
18328 } // *TABLES*
18329 else { // *TABLES*
18330 $this->textbuffer[] = array($annot);
18331 } // *TABLES*
18332 }
18333/*-- END ANNOTATIONS --*/
18334 }
18335
18336 if($tag=='METER' || $tag=='PROGRESS') {
18337 $this->inMeter = false; // mPDF 5.5.09
18338 }
18339
18340
18341 if($tag=='A') {
18342 $this->HREF='';
18343 if (isset($this->InlineProperties['A'])) { $this->restoreInlineProperties($this->InlineProperties['A']); }
18344 unset($this->InlineProperties['A']);
18345 }
18346
18347 if($tag=='LEGEND') { // mPDF 5.4.18
18348 if (count($this->textbuffer) && !$this->tableLevel) {
18349 $leg = $this->textbuffer[(count($this->textbuffer)-1)];
18350 unset($this->textbuffer[(count($this->textbuffer)-1)]);
18351 $this->textbuffer = array_values($this->textbuffer);
18352 $this->blk[$this->blklvl]['border_legend'] = $leg;
18353 $this->blk[$this->blklvl]['margin_top'] += ($leg[11]/2)/_MPDFK;
18354 $this->blk[$this->blklvl]['padding_top'] += ($leg[11]/2)/_MPDFK;
18355 }
18356 if (isset($this->InlineProperties['LEGEND'])) { $this->restoreInlineProperties($this->InlineProperties['LEGEND']); }
18357 unset($this->InlineProperties['LEGEND']);
18358 $this->ignorefollowingspaces = true; //Eliminate exceeding left-side spaces
18359 }
18360
18361
18362
18363/*-- FORMS --*/
18364 // *********** FORM ELEMENTS ********************
18365
18366 if($tag=='TEXTAREA') {
18367 $this->specialcontent = '';
18368 if ($this->InlineProperties[$tag]) { $this->restoreInlineProperties($this->InlineProperties[$tag]); }
18369 unset($this->InlineProperties[$tag]);
18370 }
18371
18372
18373 if($tag=='SELECT') {
18374 $this->lastoptionaltag = '';
18375 $texto = '';
18376 if (isset($this->selectoption['SELECTED'])) { $texto = $this->selectoption['SELECTED']; }
18377
18378 if ($this->useActiveForms) { $w = $this->selectoption['MAXWIDTH']; }
18379 else { $w = $this->GetStringWidth($texto); }
18380 if ($w == 0) { $w = 5; }
18381 $objattr['type'] = 'select';
18382 $objattr['text'] = $texto;
18383 if (isset($this->selectoption['NAME'])) { $objattr['fieldname'] = $this->selectoption['NAME']; }
18384 if (isset($this->selectoption['READONLY'])) { $objattr['readonly'] = true; }
18385 if (isset($this->selectoption['REQUIRED'])) { $objattr['required'] = true; }
18386 if (isset($this->selectoption['SPELLCHECK'])) { $objattr['spellcheck'] = true; }
18387 if (isset($this->selectoption['EDITABLE'])) { $objattr['editable'] = true; }
18388 if (isset($this->selectoption['ONCHANGE'])) { $objattr['onChange'] = $this->selectoption['ONCHANGE']; }
18389 if (isset($this->selectoption['ITEMS'])) { $objattr['items'] = $this->selectoption['ITEMS']; }
18390 if (isset($this->selectoption['MULTIPLE'])) { $objattr['multiple'] = $this->selectoption['MULTIPLE']; }
18391 if (isset($this->selectoption['DISABLED'])) { $objattr['disabled'] = $this->selectoption['DISABLED']; }
18392 if (isset($this->selectoption['TITLE'])) { $objattr['title'] = $this->selectoption['TITLE']; }
18393 if (isset($this->selectoption['COLOR'])) { $objattr['color'] = $this->selectoption['COLOR']; }
18394 if (isset($this->selectoption['SIZE'])) { $objattr['size'] = $this->selectoption['SIZE']; }
18395 if (isset($objattr['size']) && $objattr['size']>1) { $rows=$objattr['size']; } else { $rows = 1; }
18396
18397 $objattr['fontfamily'] = $this->FontFamily;
18398 $objattr['fontsize'] = $this->FontSizePt;
18399
18400 $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);
18401 $objattr['height'] = ($this->FontSize*$rows) + ($this->form->form_element_spacing['select']['outer']['v']*2)+($this->form->form_element_spacing['select']['inner']['v']*2);
18402 $e = "\xbb\xa4\xactype=select,objattr=".serialize($objattr)."\xbb\xa4\xac";
18403
18404 // Clear properties - tidy up
18405 $properties = array();
18406
18407 // Output it to buffers
18408 if ($this->tableLevel) { // *TABLES*
18409 $this->_saveCellTextBuffer($e, $this->HREF);
18410 $this->cell[$this->row][$this->col]['s'] += $objattr['width'] ; // *TABLES*
18411 } // *TABLES*
18412 else { // *TABLES*
18413 $this->_saveTextBuffer($e, $this->HREF);
18414 } // *TABLES*
18415
18416 $this->selectoption = array();
18417 $this->specialcontent = '';
18418
18419 if ($this->InlineProperties[$tag]) { $this->restoreInlineProperties($this->InlineProperties[$tag]); }
18420 unset($this->InlineProperties[$tag]);
18421
18422 }
18423/*-- END FORMS --*/
18424
18425
18426 // *********** BLOCKS ********************
18427 // mPDF 5.4.18
18428 if($tag=='P' || $tag=='DIV' || $tag=='H1' || $tag=='H2' || $tag=='H3' || $tag=='H4' || $tag=='H5' || $tag=='H6' || $tag=='PRE'
18429 || $tag=='FORM' || $tag=='ADDRESS' || $tag=='BLOCKQUOTE' || $tag=='CENTER' || $tag=='DT' || $tag=='DD' || $tag=='DL'
18430 || $tag=='CAPTION' || $tag=='FIELDSET'
18431 || $tag=='ARTICLE' || $tag=='ASIDE' || $tag=='FIGURE' || $tag=='FIGCAPTION' || $tag=='FOOTER' || $tag=='HEADER' || $tag=='HGROUP'
18432 || $tag=='NAV' || $tag=='SECTION' || $tag=='DETAILS' || $tag=='SUMMARY'
18433 ) { // mPDF 5.5.09 // mPDF 5.5.22
18434
18435 $this->ignorefollowingspaces = true; //Eliminate exceeding left-side spaces
18436 $this->blockjustfinished=true;
18437
18438 $this->lastblockbottommargin = $this->blk[$this->blklvl]['margin_bottom'];
18439/*-- LISTS --*/
18440 if ($this->listlvl>0) { return; }
18441/*-- END LISTS --*/
18442
18443 // mPDF 5.6.34
18444 if (preg_match('/^H\d/',$tag) && !$this->tableLevel && !$this->writingToC) { // mPDF 5.6.38
18445 if (isset($this->h2toc[$tag]) || isset($this->h2bookmarks[$tag])) {
18446 $content = '';
18447 if (count($this->textbuffer)==1) { $content = $this->textbuffer[0][0]; }
18448 else {
18449 for ($i=0;$i<count($this->textbuffer);$i++) {
18450 if (substr($this->textbuffer[$i][0],0,3) != "\xbb\xa4\xac") { //inline object
18451 $content .= $this->textbuffer[$i][0];
18452 }
18453 }
18454 }
18455/*-- TOC --*/
18456 if (isset($this->h2toc[$tag])) {
18457 $objattr = array();
18458 $objattr['type'] = 'toc';
18459 $objattr['toclevel'] = $this->h2toc[$tag];
18460 $objattr['CONTENT'] = htmlspecialchars($content); // mPDF 5.6.37
18461 $e = "\xbb\xa4\xactype=toc,objattr=".serialize($objattr)."\xbb\xa4\xac";
18462 array_unshift($this->textbuffer,array($e));
18463 }
18464/*-- END TOC --*/
18465/*-- BOOKMARKS --*/
18466 if (isset($this->h2bookmarks[$tag])) {
18467 $objattr = array();
18468 $objattr['type'] = 'bookmark';
18469 $objattr['bklevel'] = $this->h2bookmarks[$tag];
18470 $objattr['CONTENT'] = $content;
18471 $e = "\xbb\xa4\xactype=toc,objattr=".serialize($objattr)."\xbb\xa4\xac";
18472 array_unshift($this->textbuffer,array($e));
18473 }
18474/*-- END BOOKMARKS --*/
18475 }
18476 }
18477
18478/*-- TABLES --*/
18479 if($this->tableLevel) {
18480 if ($this->linebreakjustfinished) { $this->blockjustfinished=false; }
18481 if (isset($this->InlineProperties['BLOCKINTABLE'])) {
18482 if ($this->InlineProperties['BLOCKINTABLE']) { $this->restoreInlineProperties($this->InlineProperties['BLOCKINTABLE']); }
18483 unset($this->InlineProperties['BLOCKINTABLE']);
18484 }
18485 if($tag=='PRE') { $this->ispre=false; }
18486 return;
18487 }
18488/*-- END TABLES --*/
18489 $this->lastoptionaltag = '';
18490 $this->divbegin=false;
18491
18492 $this->linebreakjustfinished=false;
18493
18494 $this->x = $this->lMargin + $this->blk[$this->blklvl]['outer_left_margin'];
18495
18496/*-- CSS-FLOAT --*/
18497 // If float contained in a float, need to extend bottom to allow for it
18498 $currpos = $this->page*1000 + $this->y;
18499 if (isset($this->blk[$this->blklvl]['float_endpos']) && $this->blk[$this->blklvl]['float_endpos'] > $currpos) {
18500 $old_page = $this->page;
18501 $new_page = intval($this->blk[$this->blklvl]['float_endpos'] /1000);
18502 if ($old_page != $new_page) {
18503 $s = $this->PrintPageBackgrounds();
18504 // Writes after the marker so not overwritten later by page background etc.
18505 $this->pages[$this->page] = preg_replace('/(___BACKGROUND___PATTERNS'.$this->uniqstr.')/', '\\1'."\n".$s."\n", $this->pages[$this->page]);
18506 $this->pageBackgrounds = array();
18507 $this->page = $new_page;
18508 $this->ResetMargins();
18509 $this->Reset();
18510 $this->pageoutput[$this->page] = array();
18511 }
18512 $this->y = (($this->blk[$this->blklvl]['float_endpos'] *1000) % 1000000)/1000; // mod changes operands to integers before processing
18513 }
18514/*-- END CSS-FLOAT --*/
18515
18516
18517 //Print content
18518 if ($this->lastblocklevelchange == 1) { $blockstate = 3; } // Top & bottom margins/padding
18519 else if ($this->lastblocklevelchange == -1) { $blockstate = 2; } // Bottom margins/padding only
18520 else { $blockstate = 0; }
18521 // called from after e.g. </table> </div> </div> ... Outputs block margin/border and padding
18522 if (count($this->textbuffer) && $this->textbuffer[count($this->textbuffer)-1]) {
18523 if (substr($this->textbuffer[count($this->textbuffer)-1][0],0,3) != "\xbb\xa4\xac") { // not special content
18524 if ($this->usingCoreFont) {
18525 $this->textbuffer[count($this->textbuffer)-1][0] = preg_replace('/[ ]+$/', '', $this->textbuffer[count($this->textbuffer)-1][0]);
18526 }
18527 else {
18528 $this->textbuffer[count($this->textbuffer)-1][0] = preg_replace('/[ ]+$/u', '', $this->textbuffer[count($this->textbuffer)-1][0]); }
18529 }
18530 }
18531
18532 if (count($this->textbuffer) == 0 && $this->lastblocklevelchange != 0) {
18533 //$this->newFlowingBlock( $this->blk[$this->blklvl]['width'],$this->lineheight,'',false,false,2,true, $this->blk[$this->blklvl]['direction']);
18534 $this->newFlowingBlock( $this->blk[$this->blklvl]['width'],$this->lineheight,'',false,false,$blockstate,true, $this->blk[$this->blklvl]['direction']);
18535 $this->finishFlowingBlock(true); // true = END of flowing block
18536 $this->PaintDivBB('',$blockstate);
18537 }
18538 else {
18539 $this->printbuffer($this->textbuffer,$blockstate);
18540 }
18541
18542
18543 $this->textbuffer=array();
18544
18545 if ($this->blk[$this->blklvl]['keep_block_together']) {
18546 $this->printdivbuffer();
18547 }
18548
18549 if ($this->kwt) {
18550 $this->kwt_height = $this->y - $this->kwt_y0;
18551 }
18552
18553/*-- CSS-IMAGE-FLOAT --*/
18554 $this->printfloatbuffer();
18555/*-- END CSS-IMAGE-FLOAT --*/
18556
18557 if($tag=='PRE') { $this->ispre=false; }
18558
18559/*-- CSS-FLOAT --*/
18560 if ($this->blk[$this->blklvl]['float'] == 'R') {
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'.$this->uniqstr.')/', '\\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'=>'R',
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 if ($this->blk[$this->blklvl]['float'] == 'L') {
18593 // If width not set, here would need to adjust and output buffer
18594 $s = $this->PrintPageBackgrounds();
18595 // Writes after the marker so not overwritten later by page background etc.
18596 $this->pages[$this->page] = preg_replace('/(___BACKGROUND___PATTERNS'.$this->uniqstr.')/', '\\1'."\n".$s."\n", $this->pages[$this->page]);
18597 $this->pageBackgrounds = array();
18598 $this->Reset();
18599 $this->pageoutput[$this->page] = array();
18600
18601 for($i=($this->blklvl-1); $i >= 0; $i--) {
18602 if (isset($this->blk[$i]['float_endpos'])) { $this->blk[$i]['float_endpos'] = max($this->blk[$i]['float_endpos'], ($this->page*1000 + $this->y)); }
18603 else { $this->blk[$i]['float_endpos'] = $this->page*1000 + $this->y; }
18604 }
18605
18606 $this->floatDivs[] = array(
18607 'side'=>'L',
18608 'startpage'=>$this->blk[$this->blklvl]['startpage'] ,
18609 'y0'=>$this->blk[$this->blklvl]['float_start_y'] ,
18610 'startpos'=> ($this->blk[$this->blklvl]['startpage']*1000 + $this->blk[$this->blklvl]['float_start_y']),
18611 'endpage'=>$this->page ,
18612 'y1'=>$this->y ,
18613 'endpos'=> ($this->page*1000 + $this->y),
18614 'w'=> $this->blk[$this->blklvl]['float_width'],
18615 'blklvl'=>$this->blklvl,
18616 'blockContext' => $this->blk[$this->blklvl-1]['blockContext']
18617 );
18618
18619 $this->y = $this->blk[$this->blklvl]['float_start_y'] ;
18620 $this->page = $this->blk[$this->blklvl]['startpage'] ;
18621 $this->ResetMargins();
18622 $this->pageoutput[$this->page] = array();
18623 }
18624/*-- END CSS-FLOAT --*/
18625
18626 if (isset($this->blk[$this->blklvl]['visibility']) && $this->blk[$this->blklvl]['visibility']!='visible') {
18627 $this->SetVisibility('visible');
18628 }
18629
18630 if (isset($this->blk[$this->blklvl]['page_break_after'])) { $page_break_after = $this->blk[$this->blklvl]['page_break_after']; }
18631 else { $page_break_after = ''; }
18632
18633 //Reset values
18634 $this->Reset();
18635
18636 // mPDF 5.6.01 - LAYERS
18637 if (isset($this->blk[$this->blklvl]['z-index']) && $this->blk[$this->blklvl]['z-index'] > 0) {
18638 $this->EndLayer();
18639 }
18640
18641 if ($this->blklvl > 0) { // ==0 SHOULDN'T HAPPEN - NOT XHTML
18642 if ($this->blk[$this->blklvl]['tag'] == $tag) {
18643 unset($this->blk[$this->blklvl]);
18644 $this->blklvl--;
18645 }
18646 //else { echo $tag; exit; } // debug - forces error if incorrectly nested html tags
18647 }
18648
18649 $this->lastblocklevelchange = -1 ;
18650 // Reset Inline-type properties
18651 if (isset($this->blk[$this->blklvl]['InlineProperties'])) { $this->restoreInlineProperties($this->blk[$this->blklvl]['InlineProperties']); }
18652
18653 $this->x = $this->lMargin + $this->blk[$this->blklvl]['outer_left_margin'];
18654
18655 if ($page_break_after) {
18656 $save_blklvl = $this->blklvl;
18657 $save_blk = $this->blk;
18658 $save_silp = $this->saveInlineProperties();
18659 $save_spanlvl = $this->spanlvl;
18660 $save_ilp = $this->InlineProperties;
18661 if ($this->blklvl>1) {
18662 // Close any open block tags
18663 for ($b= $this->blklvl;$b>0;$b--) { $this->CloseTag($this->blk[$b]['tag']); }
18664 // Output any text left in buffer
18665 if (count($this->textbuffer)) { $this->printbuffer($this->textbuffer); $this->textbuffer=array(); }
18666 }
18667/*-- COLUMNS --*/
18668 $save_cols = false;
18669 if ($this->ColActive) {
18670 $save_cols = true;
18671 $save_nbcol = $this->NbCol; // other values of gap and vAlign will not change by setting Columns off
18672 $this->SetColumns(0);
18673 }
18674/*-- END COLUMNS --*/
18675 if ($page_break_after == 'RIGHT') { $this->AddPage($this->CurOrientation,'NEXT-ODD','','','','','', '','', '','','','','','',0,0,0,0,$pagesel); }
18676 else if ($page_break_after == 'LEFT') { $this->AddPage($this->CurOrientation,'NEXT-EVEN','','','','','', '','', '','','','','','',0,0,0,0,$pagesel); }
18677 else { $this->AddPage($this->CurOrientation,'','','','','','', '','', '','','','','','',0,0,0,0,$pagesel); }
18678 if (!$this->restoreBlockPagebreaks) {
18679 $this->blklvl = 0;
18680 $this->lastblocklevelchange = 0;
18681 $this->blk = array();
18682 $this->initialiseBlock($this->blk[0]);
18683 $this->blk[0]['width'] =& $this->pgwidth;
18684 $this->blk[0]['inner_width'] =& $this->pgwidth;
18685 $this->blk[0]['blockContext'] = $this->blockContext;
18686 $properties = $this->cssmgr->MergeCSS('BLOCK','BODY','');
18687 $this->setCSS($properties,'','BODY');
18688 $this->blklvl++;
18689 $currblk =& $this->blk[$this->blklvl];
18690 $prevblk =& $this->blk[$this->blklvl-1];
18691
18692 $this->initialiseBlock($currblk);
18693 $currblk['tag'] = $tag;
18694 $currblk['attr'] = $attr;
18695
18696 $this->Reset();
18697 $properties = $this->cssmgr->MergeCSS('BLOCK',$tag,$attr);
18698 }
18699/*-- COLUMNS --*/
18700 if ($save_cols) {
18701 // Restore columns
18702 $this->SetColumns($save_nbcol,$this->colvAlign,$this->ColGap);
18703 }
18704/*-- END COLUMNS --*/
18705 if ($this->restoreBlockPagebreaks && !$this->tableLevel && !$this->listlvl) {
18706 $this->blk = $save_blk;
18707 // Re-open block tags
18708 $t = $this->blk[0]['tag'];
18709 $a = $this->blk[0]['attr'];
18710 $this->blklvl = 0;
18711 for ($b=0; $b<=$save_blklvl;$b++) {
18712 $tc = $t;
18713 $ac = $a;
18714 $t = $this->blk[$b+1]['tag'];
18715 $a = $this->blk[$b+1]['attr'];
18716 unset($this->blk[$b+1]);
18717 $this->OpenTag($tc,$ac);
18718 }
18719 $this->spanlvl = $save_spanlvl;
18720 $this->InlineProperties = $save_ilp;
18721 $this->restoreInlineProperties($save_silp);
18722 }
18723 }
18724
18725 }
18726
18727
18728/*-- TABLES --*/
18729
18730 if($tag=='TH') $this->SetStyle('B',false);
18731
18732 if(($tag=='TH' or $tag=='TD') && $this->tableLevel) {
18733 $this->lastoptionaltag = 'TR';
18734 unset($this->cssmgr->tablecascadeCSS[$this->cssmgr->tbCSSlvl]);
18735 $this->cssmgr->tbCSSlvl--;
18736 if (!$this->tdbegin) { return; }
18737 $this->tdbegin = false;
18738 // Added for correct calculation of cell column width - otherwise misses the last line if not end </p> etc.
18739 if (!isset($this->cell[$this->row][$this->col]['maxs'])) {
18740 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;"); }
18741 $this->cell[$this->row][$this->col]['maxs'] = $this->cell[$this->row][$this->col]['s'];
18742 }
18743 elseif($this->cell[$this->row][$this->col]['maxs'] < $this->cell[$this->row][$this->col]['s']) {
18744 $this->cell[$this->row][$this->col]['maxs'] = $this->cell[$this->row][$this->col]['s'];
18745 }
18746
18747 // Remove last <br> if at end of cell
18748 if (isset($this->cell[$this->row][$this->col]['textbuffer'])) { $ntb = count($this->cell[$this->row][$this->col]['textbuffer']); }
18749 else { $ntb = 0; }
18750 if ($ntb>1 && $this->cell[$this->row][$this->col]['textbuffer'][$ntb-1][0] == "\n") {
18751 unset($this->cell[$this->row][$this->col]['textbuffer'][$ntb-1]);
18752 }
18753
18754 if ($this->cacheTables) {
18755 $clen = $this->_cacheCell($this->cell[$this->row][$this->col], $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['cache']);
18756 $this->cell[$this->row][$this->col] = $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['ptr'];
18757 $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['ptr'] += $clen;
18758 }
18759
18760 if ($this->tablethead) {
18761 $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['is_thead'][$this->row] = true;
18762 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)); }
18763 }
18764 if ($this->tabletfoot) {
18765 $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['is_tfoot'][$this->row] = true;
18766 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'] )); }
18767 }
18768 $this->Reset();
18769 }
18770
18771 if($tag=='TR' && $this->tableLevel) {
18772 // If Border set on TR - Update right border
18773 if (isset($this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['trborder-left'][$this->row])) {
18774 if ($this->cacheTables) {
18775 $c = $this->_uncacheCell($this->cell[$this->row][$this->col], $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['cache'], null);
18776 }
18777 else { $c =& $this->cell[$this->row][$this->col]; }
18778 if ($c) {
18779 if ($this->packTableData) {
18780 $cell = $this->_unpackCellBorder($c['borderbin'] );
18781 }
18782 else { $cell = $c; }
18783 $cell['border_details']['R'] = $this->border_details($this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['trborder-right'][$this->row]);
18784 $this->setBorder($cell['border'], _BORDER_RIGHT, $cell['border_details']['R']['s']);
18785 if ($this->packTableData) {
18786 $c['borderbin'] = $this->_packCellBorder($cell);
18787 unset($c['border']);
18788 unset($c['border_details']);
18789 }
18790 else { $c = $cell; }
18791 }
18792 if ($this->cacheTables) {
18793 $fh = fopen($this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['cache'], "r+b");
18794 $this->_cacheUpdateBorder($c, $fh, $this->cell[$this->row][$this->col]);
18795 fclose($fh);
18796 }
18797 }
18798 $this->lastoptionaltag = '';
18799 unset($this->cssmgr->tablecascadeCSS[$this->cssmgr->tbCSSlvl]);
18800 $this->cssmgr->tbCSSlvl--;
18801 $this->trow_text_rotate = '';
18802 $this->tabletheadjustfinished = false;
18803 }
18804
18805 if($tag=='TBODY') {
18806 $this->lastoptionaltag = '';
18807 unset($this->cssmgr->tablecascadeCSS[$this->cssmgr->tbCSSlvl]);
18808 $this->cssmgr->tbCSSlvl--;
18809 }
18810
18811 if($tag=='THEAD') {
18812 $this->lastoptionaltag = '';
18813 unset($this->cssmgr->tablecascadeCSS[$this->cssmgr->tbCSSlvl]);
18814 $this->cssmgr->tbCSSlvl--;
18815 $this->tablethead = 0;
18816 $this->tabletheadjustfinished = true;
18817 $this->ResetStyles();
18818 $this->thead_font_weight = '';
18819 $this->thead_font_style = '';
18820 $this->thead_font_smCaps = '';
18821
18822 $this->thead_valign_default = '';
18823 $this->thead_textalign_default = '';
18824 }
18825
18826 if($tag=='TFOOT') {
18827 $this->lastoptionaltag = '';
18828 unset($this->cssmgr->tablecascadeCSS[$this->cssmgr->tbCSSlvl]);
18829 $this->cssmgr->tbCSSlvl--;
18830 $this->tabletfoot = 0;
18831 $this->ResetStyles();
18832 $this->tfoot_font_weight = '';
18833 $this->tfoot_font_style = '';
18834 $this->tfoot_font_smCaps = '';
18835
18836 $this->tfoot_valign_default = '';
18837 $this->tfoot_textalign_default = '';
18838 }
18839
18840 if($tag=='TABLE') { // TABLE-END (
18841 if ($this->progressBar) { $this->UpdateProgressBar(1,'','TABLE'); } // *PROGRESS-BAR*
18842 if ($this->progressBar) { $this->UpdateProgressBar(7,0,''); } // *PROGRESS-BAR*
18843 $this->lastoptionaltag = '';
18844 unset($this->cssmgr->tablecascadeCSS[$this->cssmgr->tbCSSlvl]);
18845 $this->cssmgr->tbCSSlvl--;
18846 $this->ignorefollowingspaces = true; //Eliminate exceeding left-side spaces
18847 $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['cells'] = $this->cell;
18848 $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));
18849 $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['hr'] = array_pad(array(),$this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['nr'],0);
18850
18851 // Move table footer <tfoot> row to end of table
18852 if (isset($this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['is_tfoot']) && count($this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['is_tfoot'])) {
18853 $tfrows = array();
18854 foreach($this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['is_tfoot'] AS $r=>$val) {
18855 if ($val) { $tfrows[] = $r; }
18856 }
18857 $temp = array();
18858 $temptf = array();
18859 foreach($this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['cells'] AS $k=>$row) {
18860 if (in_array($k,$tfrows)) {
18861 $temptf[] = $row;
18862 }
18863 else {
18864 $temp[] = $row;
18865 }
18866 }
18867 $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['is_tfoot'] = array();
18868 for($i=count($temp) ; $i<(count($temp)+count($temptf)); $i++) {
18869 $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['is_tfoot'][$i] = true;
18870 }
18871 // Update nestedpos row references
18872 if (count($this->table[($this->tableLevel+1)])) {
18873 foreach($this->table[($this->tableLevel+1)] AS $nid=>$nested) {
18874 $this->table[($this->tableLevel+1)][$nid]['nestedpos'][0] -= count($temptf);
18875 }
18876 }
18877 $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['cells'] = array_merge($temp, $temptf);
18878
18879 // Update other arays set on row number
18880 // [trbackground-images] [trgradients]
18881 $temptrbgi = array();
18882 $temptrbgg = array();
18883 $temptrbgc = array();
18884 $temptrbgc[-1] = $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['bgcolor'][-1];
18885 for($k=0; $k<$this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['nr']; $k++) {
18886 if (!in_array($k,$tfrows)) {
18887 $temptrbgi[] = $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['trbackground-images'][$k];
18888 $temptrbgg[] = $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['trgradients'][$k];
18889 $temptrbgc[] = $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['bgcolor'][$k];
18890 }
18891 }
18892 for($k=0; $k<$this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['nr']; $k++) {
18893 if (in_array($k,$tfrows)) {
18894 $temptrbgi[] = $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['trbackground-images'][$k];
18895 $temptrbgg[] = $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['trgradients'][$k];
18896 $temptrbgc[] = $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['bgcolor'][$k];
18897 }
18898 }
18899 $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['trbackground-images'] = $temptrbgi;
18900 $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['trgradients'] = $temptrbgg;
18901 $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['bgcolor'] = $temptrbgc ;
18902 // Should Update all other arays set on row number, but cell properties have been set so not needed
18903 // [bgcolor] [trborder-left] [trborder-right] [trborder-top] [trborder-bottom]
18904 }
18905
18906 if ($this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['direction']=='rtl') {
18907 $this->_reverseTableDir($this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]);
18908 }
18909
18910 // Fix Borders *********************************************
18911 $this->_fixTableBorders($this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]);
18912
18913 if ($this->progressBar) { $this->UpdateProgressBar(7,10,' '); } // *PROGRESS-BAR*
18914
18915 if ($this->ColActive) { $this->table_rotate = 0; } // *COLUMNS*
18916 if ($this->table_rotate <> 0) {
18917 $this->tablebuffer = '';
18918 // Max width for rotated table
18919 $this->tbrot_maxw = $this->h - ($this->y + $this->bMargin + 1);
18920 $this->tbrot_maxh = $this->blk[$this->blklvl]['inner_width'] ; // Max width for rotated table
18921 $this->tbrot_align = $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['a'] ;
18922 }
18923 $this->shrin_k = 1;
18924
18925 if ($this->shrink_tables_to_fit < 1) { $this->shrink_tables_to_fit = 1; }
18926 if (!$this->shrink_this_table_to_fit) { $this->shrink_this_table_to_fit = $this->shrink_tables_to_fit; }
18927
18928 if ($this->tableLevel>1) {
18929 // deal with nested table
18930
18931 $this->_tableColumnWidth($this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]],true);
18932
18933 $tmiw = $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['miw'];
18934 $tmaw = $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['maw'];
18935 $tl = $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['tl'];
18936
18937 // Go down to lower table level
18938 $this->tableLevel--;
18939
18940 // Reset lower level table
18941 $this->base_table_properties = $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['baseProperties'];
18942 $this->cell = $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['cells'];
18943 // mPDF 5.4.10
18944 if (isset($this->cell['PARENTCELL'])) {
18945 if ($this->cell['PARENTCELL']) { $this->restoreInlineProperties($this->cell['PARENTCELL']); }
18946 unset($this->cell['PARENTCELL']);
18947 }
18948 $this->row = $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['currrow'];
18949 $this->col = $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['currcol'];
18950 $objattr = array();
18951 $objattr['type'] = 'nestedtable';
18952 $objattr['nestedcontent'] = $this->tbctr[($this->tableLevel+1)];
18953 $objattr['table'] = $this->tbctr[$this->tableLevel];
18954 $objattr['row'] = $this->row;
18955 $objattr['col'] = $this->col;
18956 $objattr['level'] = $this->tableLevel;
18957 $e = "\xbb\xa4\xactype=nestedtable,objattr=".serialize($objattr)."\xbb\xa4\xac";
18958 $this->_saveCellTextBuffer($e);
18959 $this->cell[$this->row][$this->col]['s'] += $tl ;
18960 if (!isset($this->cell[$this->row][$this->col]['maxs'])) {
18961 $this->cell[$this->row][$this->col]['maxs'] = $this->cell[$this->row][$this->col]['s'];
18962 }
18963 elseif($this->cell[$this->row][$this->col]['maxs'] < $this->cell[$this->row][$this->col]['s']) {
18964 $this->cell[$this->row][$this->col]['maxs'] = $this->cell[$this->row][$this->col]['s'];
18965 }
18966 $this->cell[$this->row][$this->col]['s'] = 0;// reset
18967 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 ; }
18968 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 ; }
18969 $this->tdbegin = true;
18970 $this->nestedtablejustfinished = true;
18971 $this->ignorefollowingspaces = true;
18972 return;
18973 }
18974 $this->cMarginL = 0;
18975 $this->cMarginR = 0;
18976 $this->cMarginT = 0;
18977 $this->cMarginB = 0;
18978 $this->cellPaddingL = 0;
18979 $this->cellPaddingR = 0;
18980 $this->cellPaddingT = 0;
18981 $this->cellPaddingB = 0;
18982
18983 if (isset($this->table[1][1]['overflow']) && $this->table[1][1]['overflow']=='visible') {
18984 if ($this->kwt || $this->table_rotate || $this->table_keep_together || $this->ColActive) {
18985 $this->kwt = false;
18986 $this->table_rotate = 0;
18987 $this->table_keep_together = false;
18988 //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");
18989 }
18990 $this->_tableColumnWidth($this->table[1][1],true);
18991 $this->_tableWidth($this->table[1][1]);
18992 }
18993 else {
18994 if (!$this->kwt_saved) { $this->kwt_height = 0; }
18995
18996 list($check,$tablemiw) = $this->_tableColumnWidth($this->table[1][1],true);
18997 $save_table = $this->table;
18998 if ($this->cacheTables) { $this->_backupCacheFiles(); }
18999 $reset_to_minimum_width = false;
19000 $added_page = false;
19001
19002 if ($check > 1) {
19003 if ($check > $this->shrink_this_table_to_fit && $this->table_rotate) {
19004 if ($this->y != $this->tMargin) {
19005 $this->AddPage($this->CurOrientation);
19006 $this->kwt_moved = true;
19007 }
19008 $added_page = true;
19009 $this->tbrot_maxw = $this->h - ($this->y + $this->bMargin + 5) - $this->kwt_height;
19010 //$check = $tablemiw/$this->tbrot_maxw; // undo any shrink
19011 $check = 1; // undo any shrink
19012 }
19013 $reset_to_minimum_width = true;
19014 }
19015
19016 if ($reset_to_minimum_width) {
19017
19018 $this->shrin_k = $check;
19019
19020 $this->default_font_size /= $this->shrin_k;
19021 $this->SetFontSize($this->default_font_size, false );
19022
19023 $this->shrinkTable($this->table[1][1],$this->shrin_k);
19024
19025 $this->_tableColumnWidth($this->table[1][1],false); // repeat
19026
19027 // Starting at $this->innermostTableLevel
19028 // Shrink table values - and redo columnWidth
19029 for($lvl=2;$lvl<=$this->innermostTableLevel;$lvl++) {
19030 for ($nid=1; $nid<=$this->tbctr[$lvl]; $nid++) {
19031 $this->shrinkTable($this->table[$lvl][$nid],$this->shrin_k);
19032 $this->_tableColumnWidth($this->table[$lvl][$nid],false);
19033 }
19034 }
19035 }
19036
19037 // Set table cell widths for top level table
19038 // Use $shrin_k to resize but don't change again
19039 $this->SetLineHeight('',$this->table_lineheight);
19040
19041 // Top level table
19042 $this->_tableWidth($this->table[1][1]);
19043
19044 }
19045
19046
19047 // Now work through any nested tables setting child table[w'] = parent cell['w']
19048 // Now do nested tables _tableWidth
19049 for($lvl=2;$lvl<=$this->innermostTableLevel;$lvl++) {
19050 for ($nid=1; $nid<=$this->tbctr[$lvl]; $nid++) {
19051 // HERE set child table width = cell width
19052
19053 list($parentrow, $parentcol, $parentnid) = $this->table[$lvl][$nid]['nestedpos'];
19054
19055 if ($this->cacheTables) {
19056 $c = $this->_uncacheCell($this->table[($lvl-1)][$parentnid]['cells'][$parentrow][$parentcol], $this->table[($lvl-1)][$parentnid]['cache'], null);
19057 }
19058 else
19059 $c =& $this->table[($lvl-1)][$parentnid]['cells'][$parentrow][$parentcol];
19060
19061 if (isset($c['colspan']) && $c['colspan']> 1) {
19062 $parentwidth = 0;
19063 for($cs=0;$cs<$c['colspan'] ; $cs++) {
19064 $parentwidth += $this->table[($lvl-1)][$parentnid]['wc'][$parentcol+$cs];
19065 }
19066 }
19067 else { $parentwidth = $this->table[($lvl-1)][$parentnid]['wc'][$parentcol]; }
19068
19069
19070 //$parentwidth -= ALLOW FOR PADDING ETC.in parent cell
19071 if (!$this->simpleTables){
19072 if ($this->packTableData) {
19073 list($bt,$br,$bb,$bl) = $this->_getBorderWidths($c['borderbin']);
19074 }
19075 else {
19076 $br = $c['border_details']['R']['w'];
19077 $bl = $c['border_details']['L']['w'];
19078 }
19079 if ($this->table[$lvl-1][$parentnid]['borders_separate']) {
19080 $parentwidth -= $br + $bl
19081 + $c['padding']['L']
19082 + $c['padding']['R']
19083 + $this->table[($lvl-1)][$parentnid]['border_spacing_H'];
19084 }
19085 else {
19086 $parentwidth -= $br/2 + $bl/2
19087 + $c['padding']['L']
19088 + $c['padding']['R'];
19089 }
19090 }
19091 else if ($this->simpleTables){
19092 if ($this->table[$lvl-1][$parentnid]['borders_separate']) {
19093 $parentwidth -= $this->table[($lvl-1)][$parentnid]['simple']['border_details']['L']['w']
19094 + $this->table[($lvl-1)][$parentnid]['simple']['border_details']['R']['w']
19095 + $c['padding']['L']
19096 + $c['padding']['R']
19097 + $this->table[($lvl-1)][$parentnid]['border_spacing_H'];
19098 }
19099 else {
19100 $parentwidth -= $this->table[($lvl-1)][$parentnid]['simple']['border_details']['L']['w']/2
19101 + $this->table[($lvl-1)][$parentnid]['simple']['border_details']['R']['w']/2
19102 + $c['padding']['L']
19103 + $c['padding']['R'];
19104 }
19105 }
19106 if (isset($this->table[$lvl][$nid]['wpercent']) && $this->table[$lvl][$nid]['wpercent'] && $lvl>1) {
19107 $this->table[$lvl][$nid]['w'] = $parentwidth;
19108 }
19109 else if ($parentwidth > $this->table[$lvl][$nid]['maw']) {
19110 $this->table[$lvl][$nid]['w'] = $this->table[$lvl][$nid]['maw'];
19111 }
19112 else {
19113 $this->table[$lvl][$nid]['w'] = $parentwidth;
19114 }
19115 unset($c);
19116 $this->_tableWidth($this->table[$lvl][$nid]);
19117 }
19118 }
19119
19120 // Starting at $this->innermostTableLevel
19121 // Cascade back up nested tables: setting heights back up the tree
19122 for($lvl=$this->innermostTableLevel;$lvl>0;$lvl--) {
19123 for ($nid=1; $nid<=$this->tbctr[$lvl]; $nid++) {
19124 list($tableheight,$maxrowheight,$fullpage,$remainingpage, $maxfirstrowheight) = $this->_tableHeight($this->table[$lvl][$nid]); }
19125 }
19126 if ($this->progressBar) { $this->UpdateProgressBar(7,20,' '); } // *PROGRESS-BAR*
19127 if ($this->table[1][1]['overflow']=='visible') {
19128 if ($maxrowheight > $fullpage) { die("mPDF Warning: A Table row is greater than available height. You cannot use CSS overflow:visible"); }
19129 if ($maxfirstrowheight > $remainingpage) { $this->AddPage($this->CurOrientation); }
19130 $r = 0; $c = 0; $p = 0; $y = 0;
19131 while (!$finished) {
19132 list($finished,$r,$c,$p,$y,$y0) = $this->_tableWrite($this->table[1][1],true,$r,$c,$p,$y);
19133 if (!$finished) {
19134 $this->AddPage($this->CurOrientation);
19135 // If printed something on first spread, set same y
19136 if ($r==0 && $y0 > -1) { $this->y = $y0; }
19137 }
19138 }
19139 }
19140 else {
19141 $recalculate = 1;
19142 $forcerecalc = false;
19143 // RESIZING ALGORITHM
19144 if ($maxrowheight > $fullpage) {
19145 $recalculate = $this->tbsqrt($maxrowheight / $fullpage, 1);
19146 $forcerecalc = true;
19147 }
19148 else if ($this->table_rotate) { // NB $remainingpage == $fullpage == the width of the page
19149 if ($tableheight > $remainingpage) {
19150 // If can fit on remainder of page whilst respecting autsize value..
19151 if (($this->shrin_k * $this->tbsqrt($tableheight / $remainingpage, 1)) <= $this->shrink_this_table_to_fit) {
19152 $recalculate = $this->tbsqrt($tableheight / $remainingpage, 1);
19153 }
19154 else if (!$added_page) {
19155 if ($this->y != $this->tMargin) {
19156 $this->AddPage($this->CurOrientation);
19157 $this->kwt_moved = true;
19158 }
19159 $added_page = true;
19160 $this->tbrot_maxw = $this->h - ($this->y + $this->bMargin + 5) - $this->kwt_height;
19161 // 0.001 to force it to recalculate
19162 $recalculate = (1 / $this->shrin_k) + 0.001; // undo any shrink
19163 }
19164 }
19165 else { $recalculate = 1; }
19166 }
19167 else if ($this->table_keep_together || ($this->table[1][1]['nr']==1 && !$this->writingHTMLfooter)) {
19168 if ($tableheight > $fullpage) {
19169 if (($this->shrin_k * $this->tbsqrt($tableheight / $fullpage, 1)) <= $this->shrink_this_table_to_fit) {
19170 $recalculate = $this->tbsqrt($tableheight / $fullpage, 1);
19171 }
19172 else if ($this->tableMinSizePriority) {
19173 $this->table_keep_together = false;
19174 $recalculate = 1.001;
19175 }
19176 else {
19177 if ($this->y != $this->tMargin) { // mPDF 5.1
19178 $this->AddPage($this->CurOrientation);
19179 $this->kwt_moved = true;
19180 }
19181 $added_page = true;
19182 $this->tbrot_maxw = $this->h - ($this->y + $this->bMargin + 5) - $this->kwt_height;
19183 $recalculate = $this->tbsqrt($tableheight / $fullpage, 1);
19184 }
19185 }
19186 else if ($tableheight > $remainingpage) {
19187 // If can fit on remainder of page whilst respecting autsize value..
19188 if (($this->shrin_k * $this->tbsqrt($tableheight / $remainingpage, 1)) <= $this->shrink_this_table_to_fit) {
19189 $recalculate = $this->tbsqrt($tableheight / $remainingpage, 1);
19190 }
19191 else {
19192 if ($this->y != $this->tMargin) {
19193 $this->AddPage($this->CurOrientation);
19194 $this->kwt_moved = true;
19195 }
19196 $added_page = true;
19197 $this->tbrot_maxw = $this->h - ($this->y + $this->bMargin + 5) - $this->kwt_height;
19198 $recalculate = 1.001;
19199 }
19200 }
19201 else { $recalculate = 1; }
19202 }
19203 else { $recalculate = 1; }
19204
19205 if ($recalculate > $this->shrink_this_table_to_fit && !$forcerecalc) { $recalculate = $this->shrink_this_table_to_fit; }
19206
19207 $iteration = 1;
19208
19209 // RECALCULATE
19210 while($recalculate <> 1) {
19211 $this->shrin_k1 = $recalculate ;
19212 $this->shrin_k *= $recalculate ;
19213 $this->default_font_size /= ($this->shrin_k1) ;
19214 $this->SetFontSize($this->default_font_size, false );
19215 $this->SetLineHeight('',$this->table_lineheight);
19216 $this->table = $save_table;
19217 if ($this->cacheTables) { $this->_restoreCacheFiles(); }
19218 if ($this->shrin_k <> 1) { $this->shrinkTable($this->table[1][1],$this->shrin_k); }
19219 $this->_tableColumnWidth($this->table[1][1],false); // repeat
19220
19221 // Starting at $this->innermostTableLevel
19222 // Shrink table values - and redo columnWidth
19223 for($lvl=2;$lvl<=$this->innermostTableLevel;$lvl++) {
19224 for ($nid=1; $nid<=$this->tbctr[$lvl]; $nid++) {
19225 if ($this->shrin_k <> 1) { $this->shrinkTable($this->table[$lvl][$nid],$this->shrin_k); }
19226 $this->_tableColumnWidth($this->table[$lvl][$nid],false);
19227 }
19228 }
19229 // Set table cell widths for top level table
19230
19231 // Top level table
19232 $this->_tableWidth($this->table[1][1]);
19233
19234 // Now work through any nested tables setting child table[w'] = parent cell['w']
19235 // Now do nested tables _tableWidth
19236 for($lvl=2;$lvl<=$this->innermostTableLevel;$lvl++) {
19237 for ($nid=1; $nid<=$this->tbctr[$lvl]; $nid++) {
19238 // HERE set child table width = cell width
19239
19240 list($parentrow, $parentcol, $parentnid) = $this->table[$lvl][$nid]['nestedpos'];
19241 if ($this->cacheTables) {
19242 $c = $this->_uncacheCell($this->table[($lvl-1)][$parentnid]['cells'][$parentrow][$parentcol], $this->table[($lvl-1)][$parentnid]['cache'], null);
19243 }
19244 else
19245 $c =& $this->table[($lvl-1)][$parentnid]['cells'][$parentrow][$parentcol];
19246
19247 if (isset($c['colspan']) && $c['colspan']> 1) {
19248 $parentwidth = 0;
19249 for($cs=0;$cs<$c['colspan'] ; $cs++) {
19250 $parentwidth += $this->table[($lvl-1)][$parentnid]['wc'][$parentcol+$cs];
19251 }
19252 }
19253 else { $parentwidth = $this->table[($lvl-1)][$parentnid]['wc'][$parentcol]; }
19254
19255 //$parentwidth -= ALLOW FOR PADDING ETC.in parent cell
19256 if (!$this->simpleTables){
19257 if ($this->packTableData) {
19258 list($bt,$br,$bb,$bl) = $this->_getBorderWidths($c['borderbin']);
19259 }
19260 else {
19261 $br = $c['border_details']['R']['w'];
19262 $bl = $c['border_details']['L']['w'];
19263 }
19264 if ($this->table[$lvl-1][$parentnid]['borders_separate']) {
19265 $parentwidth -= $br + $bl
19266 + $c['padding']['L']
19267 + $c['padding']['R']
19268 + $this->table[($lvl-1)][$parentnid]['border_spacing_H'];
19269 }
19270 else {
19271 $parentwidth -= $br/2 + $bl/2
19272 + $c['padding']['L']
19273 + $c['padding']['R'];
19274 }
19275 }
19276 else if ($this->simpleTables){
19277 if ($this->table[$lvl-1][$parentnid]['borders_separate']) {
19278 $parentwidth -= $this->table[($lvl-1)][$parentnid]['simple']['border_details']['L']['w']
19279 + $this->table[($lvl-1)][$parentnid]['simple']['border_details']['R']['w']
19280 + $c['padding']['L']
19281 + $c['padding']['R']
19282 + $this->table[($lvl-1)][$parentnid]['border_spacing_H'];
19283 }
19284 else {
19285 $parentwidth -= ($this->table[($lvl-1)][$parentnid]['simple']['border_details']['L']['w']
19286 + $this->table[($lvl-1)][$parentnid]['simple']['border_details']['R']['w']) /2
19287 + $c['padding']['L']
19288 + $c['padding']['R'];
19289 }
19290 }
19291 if (isset($this->table[$lvl][$nid]['wpercent']) && $this->table[$lvl][$nid]['wpercent'] && $lvl>1) {
19292 $this->table[$lvl][$nid]['w'] = $parentwidth;
19293 }
19294 else if ($parentwidth > $this->table[$lvl][$nid]['maw']) {
19295 $this->table[$lvl][$nid]['w'] = $this->table[$lvl][$nid]['maw'] ;
19296 }
19297 else {
19298 $this->table[$lvl][$nid]['w'] = $parentwidth;
19299 }
19300 unset($c);
19301 $this->_tableWidth($this->table[$lvl][$nid]);
19302 }
19303 }
19304
19305 // Starting at $this->innermostTableLevel
19306 // Cascade back up nested tables: setting heights back up the tree
19307 for($lvl=$this->innermostTableLevel;$lvl>0;$lvl--) {
19308 for ($nid=1; $nid<=$this->tbctr[$lvl]; $nid++) {
19309 list($tableheight,$maxrowheight,$fullpage,$remainingpage, $maxfirstrowheight) = $this->_tableHeight($this->table[$lvl][$nid]); }
19310 }
19311
19312 // RESIZING ALGORITHM
19313
19314 if ($maxrowheight > $fullpage) { $recalculate = $this->tbsqrt($maxrowheight / $fullpage, $iteration); $iteration++; }
19315 else if ($this->table_rotate && $tableheight > $remainingpage && !$added_page) {
19316 // If can fit on remainder of page whilst respecting autosize value..
19317 if (($this->shrin_k * $this->tbsqrt($tableheight / $remainingpage, $iteration)) <= $this->shrink_this_table_to_fit) {
19318 $recalculate = $this->tbsqrt($tableheight / $remainingpage, $iteration); $iteration++;
19319 }
19320 else {
19321 if (!$added_page) {
19322 $this->AddPage($this->CurOrientation);
19323 $added_page = true;
19324 $this->kwt_moved = true;
19325 $this->tbrot_maxw = $this->h - ($this->y + $this->bMargin + 5) - $this->kwt_height;
19326 }
19327 // 0.001 to force it to recalculate
19328 $recalculate = (1 / $this->shrin_k) + 0.001; // undo any shrink
19329 }
19330 }
19331 else if ($this->table_keep_together || ($this->table[1][1]['nr']==1 && !$this->writingHTMLfooter)) {
19332 if ($tableheight > $fullpage) {
19333 if (($this->shrin_k * $this->tbsqrt($tableheight / $fullpage, $iteration)) <= $this->shrink_this_table_to_fit) {
19334 $recalculate = $this->tbsqrt($tableheight / $fullpage, $iteration); $iteration++;
19335 }
19336 else if ($this->tableMinSizePriority) {
19337 $this->table_keep_together = false;
19338 $recalculate = (1 / $this->shrin_k) + 0.001;
19339 }
19340 else {
19341 if (!$added_page && $this->y != $this->tMargin) {
19342 $this->AddPage($this->CurOrientation);
19343 $added_page = true;
19344 $this->kwt_moved = true;
19345 $this->tbrot_maxw = $this->h - ($this->y + $this->bMargin + 5) - $this->kwt_height;
19346 }
19347 $recalculate = $this->tbsqrt($tableheight / $fullpage, $iteration); $iteration++;
19348 }
19349 }
19350 else if ($tableheight > $remainingpage) {
19351 // If can fit on remainder of page whilst respecting autosize value..
19352 if (($this->shrin_k * $this->tbsqrt($tableheight / $remainingpage, $iteration)) <= $this->shrink_this_table_to_fit) {
19353 $recalculate = $this->tbsqrt($tableheight / $remainingpage, $iteration); $iteration++;
19354 }
19355 else {
19356 if (!$added_page) {
19357 $this->AddPage($this->CurOrientation);
19358 $added_page = true;
19359 $this->kwt_moved = true;
19360 $this->tbrot_maxw = $this->h - ($this->y + $this->bMargin + 5) - $this->kwt_height;
19361 }
19362
19363 //$recalculate = $this->tbsqrt($tableheight / $fullpage, $iteration); $iteration++;
19364 $recalculate = (1 / $this->shrin_k) + 0.001; // undo any shrink
19365 }
19366 }
19367 else { $recalculate = 1; }
19368 }
19369 else { $recalculate = 1; }
19370 }
19371
19372
19373 if ($maxfirstrowheight > $remainingpage && !$added_page && !$this->table_rotate && !$this->ColActive && !$this->table_keep_together && !$this->writingHTMLheader && !$this->writingHTMLfooter) {
19374 $this->AddPage($this->CurOrientation);
19375 $this->kwt_moved = true;
19376 }
19377
19378 // keep-with-table: if page has advanced, print out buffer now, else done in fn. _Tablewrite()
19379 if ($this->kwt_saved && $this->kwt_moved) {
19380 $this->printkwtbuffer();
19381 $this->kwt_moved = false;
19382 $this->kwt_saved = false;
19383 }
19384
19385 if ($this->progressBar) { $this->UpdateProgressBar(7,30,' '); } // *PROGRESS-BAR*
19386 // Recursively writes all tables starting at top level
19387 $this->_tableWrite($this->table[1][1]);
19388
19389 if ($this->table_rotate && $this->tablebuffer) {
19390 $this->PageBreakTrigger=$this->h-$this->bMargin;
19391 $save_tr = $this->table_rotate;
19392 $save_y = $this->y;
19393 $this->table_rotate = 0;
19394 $this->y = $this->tbrot_y0;
19395 $h = $this->tbrot_w;
19396 $this->DivLn($h,$this->blklvl,true);
19397
19398 $this->table_rotate = $save_tr;
19399 $this->y = $save_y;
19400
19401 $this->printtablebuffer();
19402 }
19403 $this->table_rotate = 0;
19404 }
19405
19406
19407 $this->x = $this->lMargin + $this->blk[$this->blklvl]['outer_left_margin'];
19408
19409 $this->maxPosR = max($this->maxPosR , ($this->x + $this->table[1][1]['w']));
19410
19411 $this->blockjustfinished=true;
19412 $this->lastblockbottommargin = $this->table[1][1]['margin']['B'];
19413 //Reset values
19414
19415 if (isset($this->table[1][1]['page_break_after'])) { $page_break_after = $this->table[1][1]['page_break_after']; }
19416 else { $page_break_after = ''; }
19417
19418 // Keep-with-table
19419 $this->kwt = false;
19420 $this->kwt_y0 = 0;
19421 $this->kwt_x0 = 0;
19422 $this->kwt_height = 0;
19423 $this->kwt_buffer = array();
19424 $this->kwt_Links = array();
19425 $this->kwt_Annots = array();
19426 $this->kwt_moved = false;
19427 $this->kwt_saved = false;
19428
19429 $this->kwt_Reference = array();
19430 $this->kwt_BMoutlines = array();
19431 $this->kwt_toc = array();
19432
19433 $this->shrin_k = 1;
19434 $this->shrink_this_table_to_fit = 0;
19435
19436 unset($this->table);
19437 $this->table=array(); //array
19438 $this->tableLevel=0;
19439 $this->tbctr=array();
19440 $this->innermostTableLevel=0;
19441 $this->cssmgr->tbCSSlvl = 0;
19442 $this->cssmgr->tablecascadeCSS = array();
19443
19444 unset($this->cell);
19445 $this->cell=array(); //array
19446
19447 $this->col=-1; //int
19448 $this->row=-1; //int
19449 $this->Reset();
19450
19451 $this->cellPaddingL = 0;
19452 $this->cellPaddingT = 0;
19453 $this->cellPaddingR = 0;
19454 $this->cellPaddingB = 0;
19455 $this->cMarginL = 0;
19456 $this->cMarginT = 0;
19457 $this->cMarginR = 0;
19458 $this->cMarginB = 0;
19459 $this->default_font_size = $this->original_default_font_size;
19460 $this->default_font = $this->original_default_font;
19461 $this->SetFontSize($this->default_font_size, false);
19462 $this->SetFont($this->default_font,'',0,false);
19463 $this->SetLineHeight();
19464 if (isset($this->blk[$this->blklvl]['InlineProperties'])) { $this->restoreInlineProperties($this->blk[$this->blklvl]['InlineProperties']);}
19465 if ($this->progressBar) { $this->UpdateProgressBar(7,100,' '); } // *PROGRESS-BAR*
19466
19467 if ($page_break_after) {
19468 $save_blklvl = $this->blklvl;
19469 $save_blk = $this->blk;
19470 $save_silp = $this->saveInlineProperties();
19471 $save_spanlvl = $this->spanlvl;
19472 $save_ilp = $this->InlineProperties;
19473 if ($this->blklvl>1) {
19474 // Close any open block tags
19475 for ($b= $this->blklvl;$b>0;$b--) { $this->CloseTag($this->blk[$b]['tag']); }
19476 // Output any text left in buffer
19477 if (count($this->textbuffer)) { $this->printbuffer($this->textbuffer); $this->textbuffer=array(); }
19478 }
19479/*-- COLUMNS --*/
19480 $save_cols = false;
19481 if ($this->ColActive) {
19482 $save_cols = true;
19483 $save_nbcol = $this->NbCol; // other values of gap and vAlign will not change by setting Columns off
19484 $this->SetColumns(0);
19485 }
19486/*-- END COLUMNS --*/
19487 if ($page_break_after == 'RIGHT') { $this->AddPage($this->CurOrientation,'NEXT-ODD','','','','','', '','', '','','','','','',0,0,0,0,$pagesel); }
19488 else if ($page_break_after == 'LEFT') { $this->AddPage($this->CurOrientation,'NEXT-EVEN','','','','','', '','', '','','','','','',0,0,0,0,$pagesel); }
19489 else { $this->AddPage($this->CurOrientation,'','','','','','', '','', '','','','','','',0,0,0,0,$pagesel); }
19490 if (!$this->restoreBlockPagebreaks) {
19491 $this->blklvl = 0;
19492 $this->lastblocklevelchange = 0;
19493 $this->blk = array();
19494 $this->initialiseBlock($this->blk[0]);
19495 $this->blk[0]['width'] =& $this->pgwidth;
19496 $this->blk[0]['inner_width'] =& $this->pgwidth;
19497 $this->blk[0]['blockContext'] = $this->blockContext;
19498 $properties = $this->cssmgr->MergeCSS('BLOCK','BODY','');
19499 $this->setCSS($properties,'','BODY');
19500 }
19501
19502/*-- COLUMNS --*/
19503 if ($save_cols) {
19504 // Restore columns
19505 $this->SetColumns($save_nbcol,$this->colvAlign,$this->ColGap);
19506 }
19507/*-- END COLUMNS --*/
19508 if ($this->restoreBlockPagebreaks) {
19509 $this->blk = $save_blk;
19510 // Re-open block tags
19511 $t = $this->blk[0]['tag'];
19512 $a = $this->blk[0]['attr'];
19513 $this->blklvl = 0;
19514 for ($b=0; $b<=$save_blklvl;$b++) {
19515 $tc = $t;
19516 $ac = $a;
19517 $t = $this->blk[$b+1]['tag'];
19518 $a = $this->blk[$b+1]['attr'];
19519 unset($this->blk[$b+1]);
19520 $this->OpenTag($tc,$ac);
19521 }
19522 $this->spanlvl = $save_spanlvl;
19523 $this->InlineProperties = $save_ilp;
19524 $this->restoreInlineProperties($save_silp);
19525 }
19526 }
19527
19528 }
19529/*-- END TABLES --*/
19530
19531/*-- LISTS --*/
19532 // *********** LISTS ********************
19533
19534 if($tag=='LI') {
19535 $this->lastoptionaltag = '';
19536 unset($this->cssmgr->listcascadeCSS[$this->cssmgr->listCSSlvl]);
19537 $this->cssmgr->listCSSlvl--;
19538 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]]); }
19539 }
19540
19541
19542 if(($tag=='UL') or ($tag=='OL')) {
19543 $this->ignorefollowingspaces = true; //Eliminate exceeding left-side spaces
19544 unset($this->cssmgr->listcascadeCSS[$this->cssmgr->listCSSlvl]);
19545 $this->cssmgr->listCSSlvl--;
19546
19547 $this->lastoptionaltag = '';
19548/*-- TABLES --*/
19549 // A simple list for inside a table
19550 if($this->tableLevel) {
19551 $this->listlist[$this->listlvl]['MAXNUM'] = $this->listnum; //save previous lvl's maxnum
19552 unset($this->listlist[$this->listlvl]);
19553 $this->listlvl--;
19554 if (isset($this->listlist[$this->listlvl]['MAXNUM'])) { $this->listnum = $this->listlist[$this->listlvl]['MAXNUM']; } // restore previous levels
19555 if ($this->listlvl == 0) { $this->listjustfinished = true; }
19556 return;
19557 }
19558/*-- END TABLES --*/
19559
19560 if ($this->listlvl > 1) { // returning one level
19561 $this->listjustfinished=true;
19562 if (!empty($this->textbuffer)) {
19563 $this->listitem[] = array($this->listlvl,$this->listnum,$this->textbuffer,$this->listoccur[$this->listlvl],$this->listitemtype);
19564 }
19565 else {
19566 $this->listnum--;
19567 }
19568
19569 $this->textbuffer = array();
19570 $occur = $this->listoccur[$this->listlvl];
19571 $this->listlist[$this->listlvl][$occur]['MAXNUM'] = $this->listnum; //save previous lvl's maxnum
19572 $this->listlvl--;
19573 $occur = $this->listoccur[$this->listlvl];
19574 $this->listnum = $this->listlist[$this->listlvl][$occur]['MAXNUM']; // recover previous level's number
19575 $this->listtype = $this->listlist[$this->listlvl][$occur]['TYPE']; // recover previous level's type
19576 if ($this->InlineProperties['LIST'][$this->listlvl][$occur]) { $this->restoreInlineProperties($this->InlineProperties['LIST'][$this->listlvl][$occur]); }
19577
19578 }
19579 else { // We are closing the last OL/UL tag
19580 if (!empty($this->textbuffer)) {
19581 $this->listitem[] = array($this->listlvl,$this->listnum,$this->textbuffer,$this->listoccur[$this->listlvl],$this->listitemtype);
19582 }
19583 else {
19584 $this->listnum--;
19585 }
19586
19587 $occur = $this->listoccur[$this->listlvl];
19588 $this->listlist[$this->listlvl][$occur]['MAXNUM'] = $this->listnum;
19589 $this->textbuffer = array();
19590 $this->listlvl--;
19591
19592 $this->printlistbuffer();
19593 unset($this->InlineProperties['LIST']);
19594 // SPACING AFTER LIST (Top level only)
19595 $this->Ln(0);
19596 if ($this->list_margin_bottom) {
19597 $this->DivLn($this->list_margin_bottom,$this->blklvl,true,1); // collapsible
19598 }
19599 if (isset($this->blk[$this->blklvl]['InlineProperties'])) { $this->restoreInlineProperties($this->blk[$this->blklvl]['InlineProperties']);}
19600 $this->listjustfinished = true;
19601 $this->cssmgr->listCSSlvl = 0;
19602 $this->cssmgr->listcascadeCSS = array();
19603 $this->blockjustfinished=true;
19604 $this->lastblockbottommargin = $this->list_margin_bottom;
19605 }
19606 }
19607/*-- END LISTS --*/
19608
19609
19610}
19611
19612
19613/*-- TABLES --*/
19614// This function determines the shrink factor when resizing tables
19615// val is the table_height / page_height_available
19616// returns a scaling factor used as $shrin_k to resize the table
19617// Overcompensating will be quicker but may unnecessarily shrink table too much
19618// Undercompensating means it will reiterate more times (taking more processing time)
19619function tbsqrt($val, $iteration=3) {
19620 $k = 4; // Alters number of iterations until it returns $val itself - Must be > 2
19621 // Probably best guess and most accurate
19622 if ($iteration==1) return sqrt($val);
19623 // Faster than using sqrt (because it won't undercompensate), and gives reasonable results
19624 //return 1+(($val-1)/2);
19625 $x = 2-(($iteration-2)/($k-2));
19626 if ($x == 0) { $ret = $val+0.00001; }
19627 else if ($x < 0) { $ret = 1 + ( pow(2, ($iteration-2-$k))/1000 ); }
19628 else { $ret = 1+(($val-1)/$x); }
19629 return $ret;
19630}
19631/*-- END TABLES --*/
19632
19633
19634/*-- LISTS --*/
19635function printlistbuffer() {
19636 //Save x coordinate
19637 $x = $this->lMargin + $this->blk[$this->blklvl]['outer_left_margin'];
19638 $this->cMarginL = 0;
19639 $this->cMarginR = 0;
19640 $currIndentLvl = -1;
19641 $lastIndent = array();
19642 $bak_page = $this->page;
19643 $indent = 0;
19644 foreach($this->listitem as $item)
19645 {
19646 // COLS
19647 $oldcolumn = $this->CurrCol;
19648
19649 $this->bulletarray = array();
19650 //Get list's buffered data
19651 $this->listlvl = $lvl = $item[0];
19652 $num = $item[1];
19653 $this->textbuffer = $item[2];
19654 $occur = $item[3];
19655 if ($item[4]) { $type = $item[4]; } // listitemtype
19656 else { $type = $this->listlist[$lvl][$occur]['TYPE']; }
19657 $maxnum = $this->listlist[$lvl][$occur]['MAXNUM'];
19658 $this->restoreInlineProperties($this->InlineProperties['LIST'][$lvl][$occur]);
19659 $this->SetFont($this->FontFamily,$this->FontStyle,$this->FontSizePt,true,true); // force to write
19660 $clh = $this->FontSize;
19661
19662 $this->SetLineHeight($this->FontSizePt,$this->list_lineheight[$lvl][$occur]);
19663 $this->listOcc = $occur;
19664 $this->listnum = $num;
19665
19666 if (isset($this->list_align[$this->listlvl][$occur])) { $this->divalign = $this->list_align[$this->listlvl][$occur]; }
19667 else {
19668 if (isset($this->blk[$this->blklvl]['direction']) && $this->blk[$this->blklvl]['direction']=='rtl') { $this->divalign = 'R'; }
19669 else { $this->divalign = 'L'; }
19670 }
19671
19672 // Set the bullet fontsize
19673 $bullfs = $this->InlineProperties['LISTITEM'][$lvl][$occur][$num]['size'];
19674
19675 $space_width = $this->GetCharWidth(' ',false) * 1.5;
19676
19677 //Set default width & height values
19678 $this->divwidth = $this->blk[$this->blklvl]['inner_width'];
19679 $this->divheight = $this->lineheight;
19680 $typefont = $this->FontFamily;
19681 if (preg_match('/U\+([a-fA-F0-9]+)/i',$type,$m)) {
19682 if ($this->_charDefined($this->CurrentFont['cw'],hexdec($m[1]))) { $list_item_marker = codeHex2utf($m[1]); }
19683 else { $list_item_marker = '-'; }
19684 $blt_width = $this->GetStringWidth($list_item_marker);
19685 $typefont = '';
19686 if (preg_match('/rgb\(.*?\)/',$type,$m)) {
19687 $list_item_color = $this->ConvertColor($m[0]);
19688 }
19689 }
19690 else {
19691 $list_item_color = false;
19692
19693 switch($type) //Format type
19694 {
19695 case '1':
19696 if ($this->listDir == 'rtl') { $list_item_marker = $this->list_number_suffix . $num; }
19697 else { $list_item_marker = $num . $this->list_number_suffix; }
19698 $blt_width = $this->GetStringWidth(str_repeat('5',strlen($maxnum)).$this->list_number_suffix);
19699 break;
19700 case 'none':
19701 $list_item_marker = '';
19702 $blt_width = 0;
19703 break;
19704 case 'A':
19705 $anum = $this->dec2alpha($num,true);
19706 $maxnum = $this->dec2alpha($maxnum,true);
19707 if ($this->listDir == 'rtl') { $list_item_marker = $this->list_number_suffix . $anum; }
19708 else { $list_item_marker = $anum . $this->list_number_suffix; }
19709 $blt_width = $this->GetStringWidth(str_repeat('W',strlen($maxnum)).$this->list_number_suffix);
19710 break;
19711 case 'a':
19712 $anum = $this->dec2alpha($num,false);
19713 $maxnum = $this->dec2alpha($maxnum,false);
19714 if ($this->listDir == 'rtl') { $list_item_marker = $this->list_number_suffix . $anum; }
19715 else { $list_item_marker = $anum . $this->list_number_suffix; }
19716 $blt_width = $this->GetStringWidth(str_repeat('m',strlen($maxnum)).$this->list_number_suffix);
19717 break;
19718 case 'I':
19719 $anum = $this->dec2roman($num,true);
19720 if ($this->listDir == 'rtl') { $list_item_marker = $this->list_number_suffix . $anum; }
19721 else { $list_item_marker = $anum . $this->list_number_suffix; }
19722
19723 if ($maxnum>87) { $bbit = 87; }
19724 else if ($maxnum>86) { $bbit = 86; }
19725 else if ($maxnum>37) { $bbit = 38; }
19726 else if ($maxnum>36) { $bbit = 37; }
19727 else if ($maxnum>27) { $bbit = 28; }
19728 else if ($maxnum>26) { $bbit = 27; }
19729 else if ($maxnum>17) { $bbit = 18; }
19730 else if ($maxnum>16) { $bbit = 17; }
19731 else if ($maxnum>7) { $bbit = 8; }
19732 else if ($maxnum>6) { $bbit = 7; }
19733 else if ($maxnum>3) { $bbit = 4; }
19734 else { $bbit = $maxnum; }
19735 $maxlnum = $this->dec2roman($bbit,true);
19736 $blt_width = $this->GetStringWidth($maxlnum.$this->list_number_suffix);
19737 break;
19738 case 'i':
19739 $anum = $this->dec2roman($num,false);
19740 if ($this->listDir == 'rtl') { $list_item_marker = $this->list_number_suffix . $anum; }
19741 else { $list_item_marker = $anum . $this->list_number_suffix; }
19742
19743 if ($maxnum>87) { $bbit = 87; }
19744 else if ($maxnum>86) { $bbit = 86; }
19745 else if ($maxnum>37) { $bbit = 38; }
19746 else if ($maxnum>36) { $bbit = 37; }
19747 else if ($maxnum>27) { $bbit = 28; }
19748 else if ($maxnum>26) { $bbit = 27; }
19749 else if ($maxnum>17) { $bbit = 18; }
19750 else if ($maxnum>16) { $bbit = 17; }
19751 else if ($maxnum>7) { $bbit = 8; }
19752 else if ($maxnum>6) { $bbit = 7; }
19753 else if ($maxnum>3) { $bbit = 4; }
19754 else { $bbit = $maxnum; }
19755 $maxlnum = $this->dec2roman($bbit,false);
19756
19757 $blt_width = $this->GetStringWidth($maxlnum.$this->list_number_suffix);
19758 break;
19759 case 'disc':
19760 if ($this->PDFA || $this->PDFX) {
19761 if ($this->_charDefined($this->CurrentFont['cw'],8226)) { $list_item_marker = "\xe2\x80\xa2"; } // &#8226;
19762 else { $list_item_marker = '-'; }
19763 $blt_width = $this->GetCharWidth($list_item_marker);
19764 break;
19765 }
19766 $list_item_marker = chr(108); // bullet disc in Zapfdingbats 'l'
19767 $typefont = 'czapfdingbats';
19768 $blt_width = (0.791 * $this->FontSize/2.5);
19769 break;
19770 case 'circle':
19771 if ($this->PDFA || $this->PDFX) {
19772 if ($this->_charDefined($this->CurrentFont['cw'],9900)) { $list_item_marker = "\xe2\x9a\xac"; } // &#9900;
19773 else { $list_item_marker = '-'; }
19774 $blt_width = $this->GetCharWidth($list_item_marker);
19775 break;
19776 }
19777 $list_item_marker = chr(109); // circle in Zapfdingbats 'm'
19778 $typefont = 'czapfdingbats';
19779 $blt_width = (0.873 * $this->FontSize/2.5);
19780 break;
19781 case 'square':
19782 if ($this->PDFA || $this->PDFX) {
19783 if ($this->_charDefined($this->CurrentFont['cw'],9642)) { $list_item_marker = "\xe2\x96\xaa"; } // &#9642;
19784 else { $list_item_marker = '-'; }
19785 $blt_width = $this->GetCharWidth($list_item_marker);
19786 break;
19787 }
19788 $list_item_marker = chr(110); //black square in Zapfdingbats font 'n'
19789 $typefont = 'czapfdingbats';
19790 $blt_width = (0.761 * $this->FontSize/2.5);
19791 break;
19792
19793/* CSS3 list-styles numeric + I added tamil
19794arabic-indic | bengali | cambodian | devanagari | gujarati | gurmukhi | kannada | khmer | lao | malayalam | mongolian | myanmar | oriya | persian | telugu | tibetan | thai | urdu
19795*/
19796 case 'arabic-indic':
19797 $cp = 0x0660;
19798 $rnum = $this->dec2other($num, $cp);
19799 $list_item_marker = $this->list_number_suffix . $rnum; // RTL
19800 $blt_width = $this->GetStringWidth(str_repeat($this->dec2other(3, $cp),strlen($maxnum)).$this->list_number_suffix);
19801 break;
19802 case 'persian':
19803 case 'urdu':
19804 $cp = 0x06F0;
19805 $rnum = $this->dec2other($num, $cp);
19806 $list_item_marker = $this->list_number_suffix . $rnum; // RTL
19807 $blt_width = $this->GetStringWidth(str_repeat($this->dec2other(3, $cp),strlen($maxnum)).$this->list_number_suffix);
19808 break;
19809 case 'bengali':
19810 $cp = 0x09E6;
19811 $rnum = $this->dec2other($num, $cp);
19812 $list_item_marker = $rnum . $this->list_number_suffix;
19813 $blt_width = $this->GetStringWidth(str_repeat($this->dec2other(3, $cp),strlen($maxnum)).$this->list_number_suffix);
19814 break;
19815 case 'devanagari':
19816 $cp = 0x0966;
19817 $rnum = $this->dec2other($num, $cp);
19818 $list_item_marker = $rnum . $this->list_number_suffix;
19819 $blt_width = $this->GetStringWidth(str_repeat($this->dec2other(3, $cp),strlen($maxnum)).$this->list_number_suffix);
19820 break;
19821 case 'gujarati':
19822 $cp = 0x0AE6;
19823 $rnum = $this->dec2other($num, $cp);
19824 $list_item_marker = $rnum . $this->list_number_suffix;
19825 $blt_width = $this->GetStringWidth(str_repeat($this->dec2other(3, $cp),strlen($maxnum)).$this->list_number_suffix);
19826 break;
19827 case 'gurmukhi':
19828 $cp = 0x0A66;
19829 $rnum = $this->dec2other($num, $cp);
19830 $list_item_marker = $rnum . $this->list_number_suffix;
19831 $blt_width = $this->GetStringWidth(str_repeat($this->dec2other(3, $cp),strlen($maxnum)).$this->list_number_suffix);
19832 break;
19833 case 'kannada':
19834 $cp = 0x0CE6;
19835 $rnum = $this->dec2other($num, $cp);
19836 $list_item_marker = $rnum . $this->list_number_suffix;
19837 $blt_width = $this->GetStringWidth(str_repeat($this->dec2other(3, $cp),strlen($maxnum)).$this->list_number_suffix);
19838 break;
19839 case 'malayalam':
19840 $cp = 0x0D66;
19841 $rnum = $this->dec2other($num, $cp);
19842 $list_item_marker = $rnum . $this->list_number_suffix;
19843 $blt_width = $this->GetStringWidth(str_repeat($this->dec2other(6, $cp),strlen($maxnum)).$this->list_number_suffix);
19844 break;
19845 case 'oriya':
19846 $cp = 0x0B66;
19847 $rnum = $this->dec2other($num, $cp);
19848 $list_item_marker = $rnum . $this->list_number_suffix;
19849 $blt_width = $this->GetStringWidth(str_repeat($this->dec2other(3, $cp),strlen($maxnum)).$this->list_number_suffix);
19850 break;
19851 case 'telugu':
19852 $cp = 0x0C66;
19853 $rnum = $this->dec2other($num, $cp);
19854 $list_item_marker = $rnum . $this->list_number_suffix;
19855 $blt_width = $this->GetStringWidth(str_repeat($this->dec2other(3, $cp),strlen($maxnum)).$this->list_number_suffix);
19856 break;
19857 case 'tamil':
19858 $cp = 0x0BE6;
19859 $rnum = $this->dec2other($num, $cp);
19860 $list_item_marker = $rnum . $this->list_number_suffix;
19861 $blt_width = $this->GetStringWidth(str_repeat($this->dec2other(9, $cp),strlen($maxnum)).$this->list_number_suffix);
19862 break;
19863 case 'thai':
19864 $cp = 0x0E50;
19865 $rnum = $this->dec2other($num, $cp);
19866 $list_item_marker = $rnum . $this->list_number_suffix;
19867 $blt_width = $this->GetStringWidth(str_repeat($this->dec2other(5, $cp),strlen($maxnum)).$this->list_number_suffix);
19868 break;
19869 case 'khmer':
19870 case 'cambodian':
19871 $cp = 0x17E0;
19872 $rnum = $this->dec2other($num, $cp);
19873 $list_item_marker = $rnum . $this->list_number_suffix;
19874 $blt_width = $this->GetStringWidth(str_repeat($this->dec2other(3, $cp),strlen($maxnum)).$this->list_number_suffix);
19875 break;
19876 case 'lao':
19877 $cp = 0x0ED0;
19878 $rnum = $this->dec2other($num, $cp);
19879 $list_item_marker = $rnum . $this->list_number_suffix;
19880 $blt_width = $this->GetStringWidth(str_repeat($this->dec2other(6, $cp),strlen($maxnum)).$this->list_number_suffix);
19881 break;
19882 default:
19883 if ($this->listDir == 'rtl') { $list_item_marker = $this->list_number_suffix . $num; }
19884 else { $list_item_marker = $num . $this->list_number_suffix; }
19885 $blt_width = $this->GetStringWidth(str_repeat('5',strlen($maxnum)).$this->list_number_suffix);
19886 break;
19887 }
19888 }
19889
19890 if (isset($item[5]) && $item[5]) { $list_item_marker = ''; }
19891
19892 if ($currIndentLvl < $lvl) {
19893 if ($lvl > 1 || $this->list_indent_first_level) {
19894 $indent += $this->list_indent[$lvl][$occur];
19895 $lastIndent[$lvl] = $this->list_indent[$lvl][$occur];
19896 }
19897 }
19898 else if ($currIndentLvl > $lvl) {
19899 while ($currIndentLvl > $lvl) {
19900 $indent -= $lastIndent[$currIndentLvl];
19901 $currIndentLvl--;
19902 }
19903 }
19904 $currIndentLvl = $lvl;
19905
19906
19907/*-- RTL --*/
19908
19909 if ($this->listDir == 'rtl') {
19910 // list_align_style Determines alignment of numbers in numbered lists
19911 if ($this->list_align_style == 'L') { $lalign = 'R'; }
19912 else { $lalign = 'L'; }
19913 $this->divwidth = $this->blk[$this->blklvl]['width'] - ($indent + $blt_width + $space_width) ;
19914 $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)
19915 //Output bullet
19916 $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 );
19917 $this->x = $x;
19918 }
19919 else {
19920/*-- END RTL --*/
19921
19922 if ($this->list_align_style == 'L') { $lalign = 'L'; }
19923 else { $lalign = 'R'; }
19924 $this->divwidth = $this->blk[$this->blklvl]['width'] - ($indent + $blt_width + $space_width) ;
19925 $xb = $this->blk[$this->blklvl]['padding_left'] + $this->blk[$this->blklvl]['border_left']['w'] - $blt_width - $space_width;
19926 //Output bullet
19927 $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 );
19928 $this->x = $x + $indent + $blt_width + $space_width;
19929 } // *RTL*
19930
19931 //Print content
19932 $this->printbuffer($this->textbuffer,'',false,true);
19933 $this->textbuffer=array();
19934
19935 // Added to correct for OddEven Margins
19936 if ($this->page != $bak_page) {
19937 if (($this->page-$bak_page) % 2 == 1) {
19938 $x += $this->MarginCorrection;
19939 }
19940 $bak_page = $this->page;
19941 }
19942/*-- COLUMNS --*/
19943 // OR COLUMN CHANGE
19944 if ($this->CurrCol != $oldcolumn) {
19945 if ($this->directionality == 'rtl') { // *RTL*
19946 $x -= ($this->CurrCol - $oldcolumn) * ($this->ColWidth+$this->ColGap); // *RTL*
19947 } // *RTL*
19948 else { // *RTL*
19949 $x += ($this->CurrCol - $oldcolumn) * ($this->ColWidth+$this->ColGap);
19950 } // *RTL*
19951 $oldcolumn = $this->CurrCol;
19952 }
19953/*-- END COLUMNS --*/
19954
19955 }
19956
19957 //Reset all used values
19958 $this->listoccur = array();
19959 $this->listitem = array();
19960 $this->listlist = array();
19961 $this->listlvl = 0;
19962 $this->listnum = 0;
19963 $this->listtype = '';
19964 $this->textbuffer = array();
19965 $this->divwidth = 0;
19966 $this->divheight = 0;
19967 $this->x = $this->lMargin + $this->blk[$this->blklvl]['outer_left_margin'];
19968}
19969/*-- END LISTS --*/
19970
19971function _saveTextBuffer($t, $link = '', $intlink = '') {
19972// $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);
19973 // mPDF 5.6.14
19974 $arr = array();
19975 $arr[0] = $t;
19976 if (isset($link) && $link) $arr[1] = $link;
19977 $arr[2] = $this->currentfontstyle;
19978 if (isset($this->colorarray) && $this->colorarray) $arr[3] = $this->colorarray;
19979 $arr[4] = $this->currentfontfamily;
19980 if (isset($this->SUP) && $this->SUP) $arr[5] = $this->SUP;
19981 if (isset($this->SUB) && $this->SUB) $arr[6] = $this->SUB;
19982 if (isset($intlink) && $intlink) $arr[7] = $intlink;
19983 if (isset($this->strike) && $this->strike) $arr[8] = $this->strike;
19984 if (isset($this->textparam) && $this->textparam) $arr[9] = $this->textparam;
19985 if (isset($this->spanbgcolorarray) && $this->spanbgcolorarray) $arr[10] = $this->spanbgcolorarray;
19986 $arr[11] = $this->currentfontsize;
19987 if (isset($this->ReqFontStyle) && $this->ReqFontStyle) $arr[12] = $this->ReqFontStyle;
19988 if (isset($this->kerning) && $this->kerning) $arr[13] = $this->kerning;
19989 if (isset($this->lSpacingCSS) && $this->lSpacingCSS) $arr[14] = $this->lSpacingCSS;
19990 if (isset($this->wSpacingCSS) && $this->wSpacingCSS) $arr[15] = $this->wSpacingCSS;
19991 if (isset($this->spanborddet) && $this->spanborddet) $arr[16] = $this->spanborddet;
19992 if (isset($this->textshadow) && $this->textshadow) $arr[17] = $this->textshadow;
19993 $this->textbuffer[] = $arr;
19994}
19995
19996function _saveCellTextBuffer($t, $link = '', $intlink = '') {
19997// $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);
19998 // mPDF 5.6.14
19999 $arr = array();
20000 $arr[0] = $t;
20001 if (isset($link) && $link) $arr[1] = $link;
20002 $arr[2] = $this->currentfontstyle;
20003 if (isset($this->colorarray) && $this->colorarray) $arr[3] = $this->colorarray;
20004 $arr[4] = $this->currentfontfamily;
20005 if (isset($this->SUP) && $this->SUP) $arr[5] = $this->SUP;
20006 if (isset($this->SUB) && $this->SUB) $arr[6] = $this->SUB;
20007 if (isset($intlink) && $intlink) $arr[7] = $intlink;
20008 if (isset($this->strike) && $this->strike) $arr[8] = $this->strike;
20009 if (isset($this->textparam) && $this->textparam) $arr[9] = $this->textparam;
20010 if (isset($this->spanbgcolorarray) && $this->spanbgcolorarray) $arr[10] = $this->spanbgcolorarray;
20011 $arr[11] = $this->currentfontsize;
20012 if (isset($this->ReqFontStyle) && $this->ReqFontStyle) $arr[12] = $this->ReqFontStyle;
20013 if (isset($this->kerning) && $this->kerning) $arr[13] = $this->kerning;
20014 if (isset($this->lSpacingCSS) && $this->lSpacingCSS) $arr[14] = $this->lSpacingCSS;
20015 if (isset($this->wSpacingCSS) && $this->wSpacingCSS) $arr[15] = $this->wSpacingCSS;
20016 if (isset($this->spanborddet) && $this->spanborddet) $arr[16] = $this->spanborddet;
20017 if (isset($this->textshadow) && $this->textshadow) $arr[17] = $this->textshadow;
20018 $this->cell[$this->row][$this->col]['textbuffer'][] = $arr;
20019}
20020
20021
20022function printbuffer($arrayaux,$blockstate=0,$is_table=false,$is_list=false)
20023{
20024// $blockstate = 0; // NO margins/padding
20025// $blockstate = 1; // Top margins/padding only
20026// $blockstate = 2; // Bottom margins/padding only
20027// $blockstate = 3; // Top & bottom margins/padding
20028 $this->spanbgcolorarray = '';
20029 $this->spanbgcolor = false;
20030 $this->spanborder = false;
20031 $this->spanborddet = array();
20032 $paint_ht_corr = 0;
20033
20034/*-- CSS-FLOAT --*/
20035 if (count($this->floatDivs)) {
20036 list($l_exists, $r_exists, $l_max, $r_max, $l_width, $r_width) = $this->GetFloatDivInfo($this->blklvl);
20037 if (($this->blk[$this->blklvl]['inner_width']-$l_width-$r_width) < (2*$this->GetCharWidth('W',false))) {
20038 // Too narrow to fit - try to move down past L or R float
20039 if ($l_max < $r_max && ($this->blk[$this->blklvl]['inner_width']-$r_width) > (2*$this->GetCharWidth('W',false))) {
20040 $this->ClearFloats('LEFT', $this->blklvl);
20041 }
20042 else if ($r_max < $l_max && ($this->blk[$this->blklvl]['inner_width']-$l_width) > (2*$this->GetCharWidth('W',false))) {
20043 $this->ClearFloats('RIGHT', $this->blklvl);
20044 }
20045 else { $this->ClearFloats('BOTH', $this->blklvl); }
20046 }
20047 }
20048/*-- END CSS-FLOAT --*/
20049 $bak_y = $this->y;
20050 $bak_x = $this->x;
20051 $align = '';
20052 if (!$is_table && !$is_list) {
20053 if (isset($this->blk[$this->blklvl]['align']) && $this->blk[$this->blklvl]['align']) { $align = $this->blk[$this->blklvl]['align']; }
20054 // Block-align is set by e.g. <.. align="center"> Takes priority for this block but not inherited
20055 if (isset($this->blk[$this->blklvl]['block-align']) && $this->blk[$this->blklvl]['block-align']) { $align = $this->blk[$this->blklvl]['block-align']; }
20056 if (isset($this->blk[$this->blklvl]['direction'])) $blockdir = $this->blk[$this->blklvl]['direction'];
20057 else $blockdir = "";
20058 $this->divwidth = $this->blk[$this->blklvl]['width'];
20059 }
20060 else {
20061 $align = $this->divalign;
20062 if ($is_table) { $blockdir = $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['direction']; }
20063 else { $blockdir = $this->listDir; }
20064 }
20065 $oldpage = $this->page;
20066
20067 // ADDED for Out of Block now done as Flowing Block
20068 if ($this->divwidth == 0) {
20069 $this->divwidth = $this->pgwidth;
20070 }
20071
20072 if (!$is_table && !$is_list) { $this->SetLineHeight($this->FontSizePt,$this->blk[$this->blklvl]['line_height']); }
20073 $this->divheight = $this->lineheight;
20074 $old_height = $this->divheight;
20075
20076 // As a failsafe - if font has been set but not output to page
20077 $this->SetFont($this->default_font,'',$this->default_font_size,true,true); // force output to page
20078
20079 $array_size = count($arrayaux);
20080 $this->newFlowingBlock( $this->divwidth,$this->divheight,$align,$is_table,$is_list,$blockstate,true,$blockdir);
20081
20082 // Added - Otherwise <div><div><p> did not output top margins/padding for 1st/2nd div
20083 if ($array_size == 0) { $this->finishFlowingBlock(true); } // true = END of flowing block
20084
20085 for($i=0;$i < $array_size; $i++)
20086 {
20087 // COLS
20088 $oldcolumn = $this->CurrCol;
20089
20090 $vetor = $arrayaux[$i];
20091 if ($i == 0 and $vetor[0] != "\n" and !$this->ispre) {
20092 $vetor[0] = ltrim($vetor[0]);
20093 }
20094
20095 // FIXED TO ALLOW IT TO SHOW '0'
20096 if (empty($vetor[0]) && !($vetor[0]==='0') && empty($vetor[7])) { //Ignore empty text and not carrying an internal link
20097 //Check if it is the last element. If so then finish printing the block
20098 if ($i == ($array_size-1)) { $this->finishFlowingBlock(true); } // true = END of flowing block
20099 continue;
20100 }
20101
20102
20103 //Activating buffer properties
20104 if(isset($vetor[11]) and $vetor[11] != '') { // Font Size
20105 if ($is_table && $this->shrin_k) {
20106 $this->SetFontSize($vetor[11]/$this->shrin_k,false);
20107 }
20108 else {
20109 $this->SetFontSize($vetor[11],false);
20110 }
20111 }
20112
20113 if(isset($vetor[17]) && !empty($vetor[17])) { //TextShadow
20114 $this->textshadow = $vetor[17];
20115 }
20116 if(isset($vetor[16]) && !empty($vetor[16])) { //Border
20117 $this->spanborddet = $vetor[16];
20118 $this->spanborder = true;
20119 }
20120
20121 if(isset($vetor[15])) { // Word spacing
20122 $this->wSpacingCSS = $vetor[15];
20123 if ($this->wSpacingCSS && strtoupper($this->wSpacingCSS) != 'NORMAL') {
20124 $this->minwSpacing = $this->ConvertSize($this->wSpacingCSS,$this->FontSize);
20125 }
20126 }
20127 if(isset($vetor[14])) { // Letter spacing
20128 $this->lSpacingCSS = $vetor[14];
20129 if (($this->lSpacingCSS || $this->lSpacingCSS==='0') && strtoupper($this->lSpacingCSS) != 'NORMAL') {
20130 $this->fixedlSpacing = $this->ConvertSize($this->lSpacingCSS,$this->FontSize);
20131 }
20132 }
20133 if(isset($vetor[13])) { // Font Kerning
20134 $this->kerning = $vetor[13];
20135 }
20136
20137
20138 if(isset($vetor[10]) and !empty($vetor[10])) //Background color
20139 {
20140 $this->spanbgcolorarray = $vetor[10];
20141 $this->spanbgcolor = true;
20142 }
20143 if(isset($vetor[9]) and !empty($vetor[9])) // Text parameters - Outline + hyphens
20144 {
20145 $this->textparam = $vetor[9] ; // mPDF 5.6.14
20146 $this->SetTextOutline($this->textparam); // mPDF 5.6.07
20147 }
20148 if(isset($vetor[8]) and $vetor[8] === true) // strike-through the text
20149 {
20150 $this->strike = true;
20151 }
20152 if(isset($vetor[7]) and $vetor[7] != '') // internal target: <a name="anyvalue">
20153 {
20154 $ily = $this->y;
20155 if ($this->keep_block_together) { $this->internallink[$vetor[7]] = array("Y"=>$ily,"PAGE"=>$this->page, "kt"=>true ); }
20156 else if ($this->table_rotate) { $this->internallink[$vetor[7]] = array("Y"=>$ily,"PAGE"=>$this->page, "tbrot"=>true ); }
20157 else if ($this->kwt) { $this->internallink[$vetor[7]] = array("Y"=>$ily,"PAGE"=>$this->page, "kwt"=>true ); }
20158 else if ($this->ColActive) { $this->internallink[$vetor[7]] = array("Y"=>$ily,"PAGE"=>$this->page, "col"=>$this->CurrCol ); }
20159 else
20160 $this->internallink[$vetor[7]] = array("Y"=>$ily,"PAGE"=>$this->page );
20161 if (empty($vetor[0])) { //Ignore empty text
20162 //Check if it is the last element. If so then finish printing the block
20163 if ($i == ($array_size-1)) { $this->finishFlowingBlock(true); } // true = END of flowing block
20164 continue;
20165 }
20166 }
20167 if(isset($vetor[6]) and $vetor[6] === true) // Subscript
20168 {
20169 $this->SUB = true;
20170 }
20171 if(isset($vetor[5]) and $vetor[5] === true) // Superscript
20172 {
20173 $this->SUP = true;
20174 }
20175 if(isset($vetor[4]) and $vetor[4] != '') { // Font Family
20176 $font = $this->SetFont($vetor[4],$this->FontStyle,0,false);
20177 }
20178 if (!empty($vetor[3])) //Font Color
20179 {
20180 $cor = $vetor[3];
20181 $this->SetTColor($cor);
20182 }
20183 if(isset($vetor[2]) and $vetor[2] != '') //Bold,Italic,Underline styles
20184 {
20185 $this->SetStyles($vetor[2]);
20186 }
20187
20188 if(isset($vetor[12]) and $vetor[12] != '') { //Requested Bold,Italic,Underline
20189 $this->ReqFontStyle = $vetor[12];
20190 }
20191 if(isset($vetor[1]) and $vetor[1] != '') //LINK
20192 {
20193 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.)
20194 {
20195 //Repeated reference to same anchor?
20196 while(array_key_exists($vetor[1],$this->internallink)) $vetor[1]="#".$vetor[1];
20197 $this->internallink[$vetor[1]] = $this->AddLink();
20198 $vetor[1] = $this->internallink[$vetor[1]];
20199 }
20200 $this->HREF = $vetor[1]; // HREF link style set here ******
20201 }
20202
20203 // SPECIAL CONTENT - IMAGES & FORM OBJECTS
20204 //Print-out special content
20205
20206 if (substr($vetor[0],0,3) == "\xbb\xa4\xac") { //identifier has been identified!
20207
20208 $objattr = $this->_getObjAttr($vetor[0]);
20209
20210/*-- TABLES --*/
20211 if ($objattr['type'] == 'nestedtable') {
20212 if ($objattr['nestedcontent']) {
20213 $level = $objattr['level'];
20214 $table = &$this->table[$level][$objattr['table']];
20215 if ($this->cacheTables) {
20216 $fh = fopen($table['cache'], "r+b");
20217 $cell = $this->_uncacheCell($table['cells'][$objattr['row']][$objattr['col']], '', $fh);
20218 }
20219 else {
20220 $fh = null;
20221 $cell = &$table['cells'][$objattr['row']][$objattr['col']];
20222 }
20223 $this->finishFlowingBlock(false,'nestedtable');
20224 $save_dw = $this->divwidth ;
20225 $save_buffer = $this->cellBorderBuffer;
20226 $this->cellBorderBuffer = array();
20227 $ncx = $this->x;
20228 list($dummyx,$w) = $this->_tableGetWidth($table, $objattr['row'], $objattr['col'], $fh);
20229 $ntw = $this->table[($level+1)][$objattr['nestedcontent']]['w']; // nested table width
20230 if (!$this->simpleTables){
20231 if ($this->packTableData) {
20232 list($bt,$br,$bb,$bl) = $this->_getBorderWidths($cell['borderbin']);
20233 }
20234 else {
20235 $br = $cell['border_details']['R']['w'];
20236 $bl = $cell['border_details']['L']['w'];
20237 }
20238 if ($table['borders_separate']) {
20239 $innerw = $w - $bl - $br - $cell['padding']['L'] - $cell['padding']['R'] - $table['border_spacing_H'];
20240 }
20241 else {
20242 $innerw = $w - $bl/2 - $br/2 - $cell['padding']['L'] - $cell['padding']['R'];
20243 }
20244 }
20245 else if ($this->simpleTables){
20246 if ($table['borders_separate']) {
20247 $innerw = $w - $table['simple']['border_details']['L']['w'] - $table['simple']['border_details']['R']['w'] - $cell['padding']['L'] - $cell['padding']['R'] - $table['border_spacing_H'];
20248 }
20249 else {
20250 $innerw = $w - $table['simple']['border_details']['L']['w']/2 - $table['simple']['border_details']['R']['w']/2 - $cell['padding']['L'] - $cell['padding']['R'];
20251 }
20252 }
20253 if ($cell['a']=='C' || $this->table[($level+1)][$objattr['nestedcontent']]['a']=='C') {
20254 $ncx += ($innerw-$ntw)/2;
20255 }
20256 elseif ($cell['a']=='R' || $this->table[($level+1)][$objattr['nestedcontent']]['a']=='R') {
20257 $ncx += $innerw- $ntw;
20258 }
20259 $this->x = $ncx ;
20260 if ($this->cacheTables) { fclose($fh); }
20261
20262 $this->_tableWrite($this->table[($level+1)][$objattr['nestedcontent']]);
20263 $this->cellBorderBuffer = $save_buffer;
20264 $this->x = $bak_x ;
20265 $this->divwidth = $save_dw;
20266 $this->newFlowingBlock( $this->divwidth,$this->divheight,$align,$is_table,$is_list,$blockstate,false,$blockdir);
20267 }
20268 }
20269 else {
20270/*-- END TABLES --*/
20271 if ($is_table) { // *TABLES*
20272 $maxWidth = $this->divwidth; // *TABLES*
20273 } // *TABLES*
20274 else { // *TABLES*
20275 $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']);
20276 } // *TABLES*
20277
20278/*-- CSS-IMAGE-FLOAT --*/
20279 // If float (already) exists at this level
20280 if (isset($this->floatmargins['R']) && $this->y <= $this->floatmargins['R']['y1'] && $this->y >= $this->floatmargins['R']['y0']) { $maxWidth -= $this->floatmargins['R']['w']; }
20281 if (isset($this->floatmargins['L']) && $this->y <= $this->floatmargins['L']['y1'] && $this->y >= $this->floatmargins['L']['y0']) { $maxWidth -= $this->floatmargins['L']['w']; }
20282/*-- END CSS-IMAGE-FLOAT --*/
20283
20284 list($skipln) = $this->inlineObject($objattr['type'], '', $this->y, $objattr,$this->lMargin, ($this->flowingBlockAttr['contentWidth']/_MPDFK), $maxWidth, $this->flowingBlockAttr['height'], false, $is_table);
20285 // 1 -> New line needed because of width
20286 // -1 -> Will fit width on line but NEW PAGE REQUIRED because of height
20287 // -2 -> Will not fit on line therefore needs new line but thus NEW PAGE REQUIRED
20288 $iby = $this->y;
20289 $oldpage = $this->page;
20290 $oldcol = $this->CurrCol;
20291 if (($skipln == 1 || $skipln == -2) && !isset($objattr['float'])) {
20292 $this->finishFlowingBlock(false,$objattr['type']);
20293 $this->newFlowingBlock( $this->divwidth,$this->divheight,$align,$is_table,$is_list,$blockstate,false,$blockdir);
20294 }
20295 $thispage = $this->page;
20296 if ($this->CurrCol!=$oldcol) { $changedcol = true; }
20297 else { $changedcol=false; }
20298
20299 // the previous lines can already have triggered page break or column change
20300 if (!$changedcol && $skipln <0 && $this->AcceptPageBreak() && $thispage==$oldpage) {
20301
20302 $this->AddPage($this->CurOrientation);
20303
20304 // Added to correct Images already set on line before page advanced
20305 // i.e. if second inline image on line is higher than first and forces new page
20306 if (count($this->objectbuffer)) {
20307 $yadj = $iby - $this->y;
20308 foreach($this->objectbuffer AS $ib=>$val) {
20309 if ($this->objectbuffer[$ib]['OUTER-Y'] ) $this->objectbuffer[$ib]['OUTER-Y'] -= $yadj;
20310 if ($this->objectbuffer[$ib]['BORDER-Y']) $this->objectbuffer[$ib]['BORDER-Y'] -= $yadj;
20311 if ($this->objectbuffer[$ib]['INNER-Y']) $this->objectbuffer[$ib]['INNER-Y'] -= $yadj;
20312 }
20313 }
20314 }
20315
20316 // Added to correct for OddEven Margins
20317 if ($this->page != $oldpage) {
20318 if (($this->page-$oldpage) % 2 == 1) {
20319 $bak_x += $this->MarginCorrection;
20320 }
20321 $oldpage = $this->page;
20322 $y = $this->tMargin - $paint_ht_corr ;
20323 $this->oldy = $this->tMargin - $paint_ht_corr ;
20324 $old_height = 0;
20325 }
20326 $this->x = $bak_x;
20327/*-- COLUMNS --*/
20328 // COLS
20329 // OR COLUMN CHANGE
20330 if ($this->CurrCol != $oldcolumn) {
20331 if ($this->directionality == 'rtl') { // *RTL*
20332 $bak_x -= ($this->CurrCol - $oldcolumn) * ($this->ColWidth+$this->ColGap); // *RTL*
20333 } // *RTL*
20334 else { // *RTL*
20335 $bak_x += ($this->CurrCol - $oldcolumn) * ($this->ColWidth+$this->ColGap);
20336 } // *RTL*
20337 $this->x = $bak_x;
20338 $oldcolumn = $this->CurrCol;
20339 $y = $this->y0 - $paint_ht_corr ;
20340 $this->oldy = $this->y0 - $paint_ht_corr ;
20341 $old_height = 0;
20342 }
20343/*-- END COLUMNS --*/
20344
20345/*-- CSS-IMAGE-FLOAT --*/
20346 if ($objattr['type'] == 'image' && isset($objattr['float'])) {
20347 $fy = $this->y;
20348
20349 // DIV TOP MARGIN/BORDER/PADDING
20350 if ($this->flowingBlockAttr['newblock'] && ($this->flowingBlockAttr['blockstate']==1 || $this->flowingBlockAttr['blockstate']==3) && $this->flowingBlockAttr['lineCount']== 0) {
20351 $fy += $this->blk[$this->blklvl]['margin_top'] + $this->blk[$this->blklvl]['padding_top'] + $this->blk[$this->blklvl]['border_top']['w'];
20352 }
20353
20354 if ($objattr['float']=='R') {
20355 $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']);
20356
20357
20358 }
20359 else if ($objattr['float']=='L') {
20360 $fx = $this->lMargin + ($this->blk[$this->blklvl]['outer_left_margin'] + $this->blk[$this->blklvl]['border_left']['w'] + $this->blk[$this->blklvl]['padding_left']);
20361 }
20362 $w = $objattr['width'];
20363 $h = abs($objattr['height']);
20364
20365 $widthLeft = $maxWidth - ($this->flowingBlockAttr['contentWidth']/_MPDFK);
20366 $maxHeight = $this->h - ($this->tMargin + $this->margin_header + $this->bMargin + 10) ;
20367 // For Images
20368 $extraWidth = ($objattr['border_left']['w'] + $objattr['border_right']['w'] + $objattr['margin_left']+ $objattr['margin_right']);
20369 $extraHeight = ($objattr['border_top']['w'] + $objattr['border_bottom']['w'] + $objattr['margin_top']+ $objattr['margin_bottom']);
20370
20371 if ($objattr['itype'] == 'wmf' || $objattr['itype'] == 'svg') {
20372 $file = $objattr['file'];
20373 $info=$this->formobjects[$file];
20374 }
20375 else {
20376 $file = $objattr['file'];
20377 $info=$this->images[$file];
20378 }
20379 $img_w = $w - $extraWidth ;
20380 $img_h = $h - $extraHeight ;
20381 if ($objattr['border_left']['w']) {
20382 $objattr['BORDER-WIDTH'] = $img_w + (($objattr['border_left']['w'] + $objattr['border_right']['w'])/2) ;
20383 $objattr['BORDER-HEIGHT'] = $img_h + (($objattr['border_top']['w'] + $objattr['border_bottom']['w'])/2) ;
20384 $objattr['BORDER-X'] = $fx + $objattr['margin_left'] + (($objattr['border_left']['w'])/2) ;
20385 $objattr['BORDER-Y'] = $fy + $objattr['margin_top'] + (($objattr['border_top']['w'])/2) ;
20386 }
20387 $objattr['INNER-WIDTH'] = $img_w;
20388 $objattr['INNER-HEIGHT'] = $img_h;
20389 $objattr['INNER-X'] = $fx + $objattr['margin_left'] + ($objattr['border_left']['w']);
20390 $objattr['INNER-Y'] = $fy + $objattr['margin_top'] + ($objattr['border_top']['w']) ;
20391 $objattr['ID'] = $info['i'];
20392 $objattr['OUTER-WIDTH'] = $w;
20393 $objattr['OUTER-HEIGHT'] = $h;
20394 $objattr['OUTER-X'] = $fx;
20395 $objattr['OUTER-Y'] = $fy;
20396 if ($objattr['float']=='R') {
20397 // If R float already exists at this level
20398 $this->floatmargins['R']['skipline'] = false;
20399 if (isset($this->floatmargins['R']['y1']) && $this->floatmargins['R']['y1'] > 0 && $fy < $this->floatmargins['R']['y1']) {
20400 $this->WriteFlowingBlock($vetor[0]);
20401 }
20402 // If L float already exists at this level
20403 else if (isset($this->floatmargins['L']['y1']) && $this->floatmargins['L']['y1'] > 0 && $fy < $this->floatmargins['L']['y1']) {
20404 // Final check distance between floats is not now too narrow to fit text
20405 $mw = 2*$this->GetCharWidth('W',false);
20406 if (($this->blk[$this->blklvl]['inner_width'] - $w - $this->floatmargins['L']['w']) < $mw) {
20407 $this->WriteFlowingBlock($vetor[0]);
20408 }
20409 else {
20410 $this->floatmargins['R']['x'] = $fx;
20411 $this->floatmargins['R']['w'] = $w;
20412 $this->floatmargins['R']['y0'] = $fy;
20413 $this->floatmargins['R']['y1'] = $fy + $h;
20414 if ($skipln == 1) {
20415 $this->floatmargins['R']['skipline'] = true;
20416 $this->floatmargins['R']['id'] = count($this->floatbuffer)+0;
20417 $objattr['skipline'] = true;
20418 }
20419 $this->floatbuffer[] = $objattr;
20420 }
20421 }
20422 else {
20423 $this->floatmargins['R']['x'] = $fx;
20424 $this->floatmargins['R']['w'] = $w;
20425 $this->floatmargins['R']['y0'] = $fy;
20426 $this->floatmargins['R']['y1'] = $fy + $h;
20427 if ($skipln == 1) {
20428 $this->floatmargins['R']['skipline'] = true;
20429 $this->floatmargins['R']['id'] = count($this->floatbuffer)+0;
20430 $objattr['skipline'] = true;
20431 }
20432 $this->floatbuffer[] = $objattr;
20433 }
20434 }
20435 else if ($objattr['float']=='L') {
20436 // If L float already exists at this level
20437 $this->floatmargins['L']['skipline'] = false;
20438 if (isset($this->floatmargins['L']['y1']) && $this->floatmargins['L']['y1'] > 0 && $fy < $this->floatmargins['L']['y1']) {
20439 $this->floatmargins['L']['skipline'] = false;
20440 $this->WriteFlowingBlock($vetor[0]);
20441 }
20442 // If R float already exists at this level
20443 else if (isset($this->floatmargins['R']['y1']) && $this->floatmargins['R']['y1'] > 0 && $fy < $this->floatmargins['R']['y1']) {
20444 // Final check distance between floats is not now too narrow to fit text
20445 $mw = 2*$this->GetCharWidth('W',false);
20446 if (($this->blk[$this->blklvl]['inner_width'] - $w - $this->floatmargins['R']['w']) < $mw) {
20447 $this->WriteFlowingBlock($vetor[0]);
20448 }
20449 else {
20450 $this->floatmargins['L']['x'] = $fx + $w;
20451 $this->floatmargins['L']['w'] = $w;
20452 $this->floatmargins['L']['y0'] = $fy;
20453 $this->floatmargins['L']['y1'] = $fy + $h;
20454 if ($skipln == 1) {
20455 $this->floatmargins['L']['skipline'] = true;
20456 $this->floatmargins['L']['id'] = count($this->floatbuffer)+0;
20457 $objattr['skipline'] = true;
20458 }
20459 $this->floatbuffer[] = $objattr;
20460 }
20461 }
20462 else {
20463 $this->floatmargins['L']['x'] = $fx + $w;
20464 $this->floatmargins['L']['w'] = $w;
20465 $this->floatmargins['L']['y0'] = $fy;
20466 $this->floatmargins['L']['y1'] = $fy + $h;
20467 if ($skipln == 1) {
20468 $this->floatmargins['L']['skipline'] = true;
20469 $this->floatmargins['L']['id'] = count($this->floatbuffer)+0;
20470 $objattr['skipline'] = true;
20471 }
20472 $this->floatbuffer[] = $objattr;
20473 }
20474 }
20475 }
20476 else {
20477/*-- END CSS-IMAGE-FLOAT --*/
20478 $this->WriteFlowingBlock($vetor[0]);
20479/*-- CSS-IMAGE-FLOAT --*/
20480 }
20481/*-- END CSS-IMAGE-FLOAT --*/
20482 } // *TABLES*
20483
20484 } // END If special content
20485 else { //THE text
20486 if ($this->tableLevel) { $paint_ht_corr = 0; } // To move the y up when new column/page started if div border needed
20487 else { $paint_ht_corr = $this->blk[$this->blklvl]['border_top']['w']; }
20488
20489 if ($vetor[0] == "\n") { //We are reading a <BR> now turned into newline ("\n")
20490 if ($this->flowingBlockAttr['content']) {
20491 $this->finishFlowingBlock(false,'br');
20492 }
20493 else if ($is_table) {
20494 $this->y+= $this->_computeLineheight($this->table_lineheight);
20495 }
20496 else if (!$is_table) {
20497 $this->DivLn($this->lineheight);
20498 if ($this->ColActive) { $this->breakpoints[$this->CurrCol][] = $this->y; } // *COLUMNS*
20499 }
20500 // Added to correct for OddEven Margins
20501 if ($this->page != $oldpage) {
20502 if (($this->page-$oldpage) % 2 == 1) {
20503 $bak_x += $this->MarginCorrection;
20504 }
20505 $oldpage = $this->page;
20506 $y = $this->tMargin - $paint_ht_corr ;
20507 $this->oldy = $this->tMargin - $paint_ht_corr ;
20508 $old_height = 0;
20509 }
20510 $this->x = $bak_x;
20511/*-- COLUMNS --*/
20512 // COLS
20513 // OR COLUMN CHANGE
20514 if ($this->CurrCol != $oldcolumn) {
20515 if ($this->directionality == 'rtl') { // *RTL*
20516 $bak_x -= ($this->CurrCol - $oldcolumn) * ($this->ColWidth+$this->ColGap); // *RTL*
20517 } // *RTL*
20518 else { // *RTL*
20519 $bak_x += ($this->CurrCol - $oldcolumn) * ($this->ColWidth+$this->ColGap);
20520 } // *RTL*
20521 $this->x = $bak_x;
20522 $oldcolumn = $this->CurrCol;
20523 $y = $this->y0 - $paint_ht_corr ;
20524 $this->oldy = $this->y0 - $paint_ht_corr ;
20525 $old_height = 0;
20526 }
20527/*-- END COLUMNS --*/
20528 $this->newFlowingBlock( $this->divwidth,$this->divheight,$align,$is_table,$is_list,$blockstate,false,$blockdir);
20529 }
20530 else {
20531 $this->WriteFlowingBlock( $vetor[0]);
20532
20533 // Added to correct for OddEven Margins
20534 if ($this->page != $oldpage) {
20535 if (($this->page-$oldpage) % 2 == 1) {
20536 $bak_x += $this->MarginCorrection;
20537 $this->x = $bak_x;
20538 }
20539 $oldpage = $this->page;
20540 $y = $this->tMargin - $paint_ht_corr ;
20541 $this->oldy = $this->tMargin - $paint_ht_corr ;
20542 $old_height = 0;
20543 }
20544/*-- COLUMNS --*/
20545 // COLS
20546 // OR COLUMN CHANGE
20547 if ($this->CurrCol != $oldcolumn) {
20548 if ($this->directionality == 'rtl') { // *RTL*
20549 $bak_x -= ($this->CurrCol - $oldcolumn) * ($this->ColWidth+$this->ColGap); // *RTL*
20550 } // *RTL*
20551 else { // *RTL*
20552 $bak_x += ($this->CurrCol - $oldcolumn) * ($this->ColWidth+$this->ColGap);
20553 } // *RTL*
20554 $this->x = $bak_x;
20555 $oldcolumn = $this->CurrCol;
20556 $y = $this->y0 - $paint_ht_corr ;
20557 $this->oldy = $this->y0 - $paint_ht_corr ;
20558 $old_height = 0;
20559 }
20560/*-- END COLUMNS --*/
20561 }
20562
20563
20564 }
20565
20566 //Check if it is the last element. If so then finish printing the block
20567 if ($i == ($array_size-1)) {
20568 $this->finishFlowingBlock(true); // true = END of flowing block
20569 // Added to correct for OddEven Margins
20570 if ($this->page != $oldpage) {
20571 if (($this->page-$oldpage) % 2 == 1) {
20572 $bak_x += $this->MarginCorrection;
20573 $this->x = $bak_x;
20574 }
20575 $oldpage = $this->page;
20576 $y = $this->tMargin - $paint_ht_corr ;
20577 $this->oldy = $this->tMargin - $paint_ht_corr ;
20578 $old_height = 0;
20579 }
20580
20581/*-- COLUMNS --*/
20582 // COLS
20583 // OR COLUMN CHANGE
20584 if ($this->CurrCol != $oldcolumn) {
20585 if ($this->directionality == 'rtl') { // *RTL*
20586 $bak_x -= ($this->CurrCol - $oldcolumn) * ($this->ColWidth+$this->ColGap); // *RTL*
20587 } // *RTL*
20588 else { // *RTL*
20589 $bak_x += ($this->CurrCol - $oldcolumn) * ($this->ColWidth+$this->ColGap);
20590 } // *RTL*
20591 $this->x = $bak_x;
20592 $oldcolumn = $this->CurrCol;
20593 $y = $this->y0 - $paint_ht_corr ;
20594 $this->oldy = $this->y0 - $paint_ht_corr ;
20595 $old_height = 0;
20596 }
20597/*-- END COLUMNS --*/
20598
20599 }
20600
20601 // RESETTING VALUES
20602 $this->SetTColor($this->ConvertColor(0));
20603 $this->SetDColor($this->ConvertColor(0));
20604 $this->SetFColor($this->ConvertColor(255));
20605 $this->colorarray = '';
20606 $this->spanbgcolorarray = '';
20607 $this->spanbgcolor = false;
20608 $this->spanborder = false;
20609 $this->spanborddet = array();
20610 $this->HREF = '';
20611 $this->textparam = array();
20612 $this->SetTextOutline();
20613 $this->SUP = false;
20614 $this->SUB = false;
20615
20616 $this->strike = false;
20617 $this->textshadow = '';
20618
20619 $this->currentfontfamily = '';
20620 $this->currentfontsize = '';
20621 $this->currentfontstyle = '';
20622/*-- TABLES --*/
20623 if ($this->tableLevel) {
20624 $this->SetLineHeight('',$this->table_lineheight); // *TABLES*
20625 }
20626 else
20627/*-- END TABLES --*/
20628/*-- LISTS --*/
20629 if ($is_list && $this->list_lineheight[$this->listlvl][$this->listOcc]) {
20630 $this->SetLineHeight('',$this->list_lineheight[$this->listlvl][$this->listOcc]); // sets default line height
20631 }
20632 else
20633/*-- END LISTS --*/
20634 if (isset($this->blk[$this->blklvl]['line_height']) && $this->blk[$this->blklvl]['line_height']) {
20635 $this->SetLineHeight('',$this->blk[$this->blklvl]['line_height']); // sets default line height
20636 }
20637 $this->ResetStyles();
20638 $this->toupper = false;
20639 $this->tolower = false;
20640 $this->capitalize = false;
20641 $this->kerning = false;
20642 $this->lSpacingCSS = '';
20643 $this->wSpacingCSS = '';
20644 $this->fixedlSpacing = false;
20645 $this->minwSpacing = 0;
20646 $this->SetDash();
20647 $this->dash_on = false;
20648 $this->dotted_on = false;
20649
20650 }//end of for(i=0;i<arraysize;i++)
20651
20652
20653 // PAINT DIV BORDER // DISABLED IN COLUMNS AS DOESN'T WORK WHEN BROKEN ACROSS COLS??
20654 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)) {
20655 $bottom_y = $this->y; // Does not include Bottom Margin
20656 if (isset($this->blk[$this->blklvl]['startpage']) && $this->blk[$this->blklvl]['startpage'] != $this->page && $blockstate != 1) {
20657 $this->PaintDivBB('pagetop',$blockstate);
20658 }
20659
20660 else if ($blockstate != 1) {
20661 $this->PaintDivBB('',$blockstate);
20662 }
20663 $this->y = $bottom_y;
20664 $this->x = $bak_x;
20665 }
20666
20667 // Reset Font
20668 $this->SetFontSize($this->default_font_size,false);
20669
20670
20671}
20672
20673function _setDashBorder($style, $div, $cp, $side) {
20674 if ($style == 'dashed' && (($side=='L' || $side=='R') || ($side=='T' && $div != 'pagetop' && !$cp) || ($side=='B' && $div!='pagebottom') )) {
20675 $dashsize = 2; // final dash will be this + 1*linewidth
20676 $dashsizek = 1.5; // ratio of Dash/Blank
20677 $this->SetDash($dashsize,($dashsize/$dashsizek)+($this->LineWidth*2));
20678 }
20679 else if ($style == 'dotted' || ($side=='T' && ($div == 'pagetop' || $cp)) || ($side=='B' && $div == 'pagebottom')) {
20680 //Round join and cap
20681 $this->SetLineJoin(1);
20682 $this->SetLineCap(1);
20683 $this->SetDash(0.001,($this->LineWidth*3));
20684 }
20685}
20686
20687function _setBorderLine($b, $k=1) {
20688 $this->SetLineWidth($b['w']/$k);
20689 $this->SetDColor($b['c']);
20690 if ($b['c'][0]==5) { // RGBa
20691 $this->SetAlpha(ord($b['c'][4])/100, 'Normal', false, 'S')."\n"; // mPDF 5.7.2
20692 }
20693 else if ($b['c'][0]==6) { // CMYKa
20694 $this->SetAlpha(ord($b['c'][5])/100, 'Normal', false, 'S')."\n"; // mPDF 5.7.2
20695 }
20696}
20697
20698// mPDF 5.6.52
20699function PaintDivBB($divider='',$blockstate=0,$blvl=0) {
20700 // Borders & backgrounds are done elsewhere for columns - messes up the repositioning in printcolumnbuffer
20701 if ($this->ColActive) { return ; } // *COLUMNS*
20702 $save_y = $this->y;
20703 if (!$blvl) { $blvl = $this->blklvl; }
20704 $x0 = $x1 = $y0 = $y1 = 0;
20705
20706 // Added mPDF 3.0 Float DIV
20707 if (isset($this->blk[$blvl]['bb_painted'][$this->page]) && $this->blk[$blvl]['bb_painted'][$this->page]) { return; } // *CSS-FLOAT*
20708
20709 if (isset($this->blk[$blvl]['x0'])) { $x0 = $this->blk[$blvl]['x0']; } // left
20710 if (isset($this->blk[$blvl]['y1'])) { $y1 = $this->blk[$blvl]['y1']; } // bottom
20711
20712 // Added mPDF 3.0 Float DIV - ensures backgrounds/borders are drawn to bottom of page
20713 if ($y1==0) {
20714 if ($divider=='pagebottom') { $y1 = $this->h-$this->bMargin; }
20715 else { $y1 = $this->y; }
20716 }
20717
20718 if (isset($this->blk[$blvl]['startpage']) && $this->blk[$blvl]['startpage'] != $this->page) { $continuingpage = true; } else { $continuingpage = false; }
20719
20720 if (isset($this->blk[$blvl]['y0'])) { $y0 = $this->blk[$blvl]['y0']; }
20721 $h = $y1 - $y0;
20722 $w = $this->blk[$blvl]['width'];
20723 $x1 = $x0 + $w;
20724
20725 // Set border-widths as used here
20726 $border_top = $this->blk[$blvl]['border_top']['w'];
20727 $border_bottom = $this->blk[$blvl]['border_bottom']['w'];
20728 $border_left = $this->blk[$blvl]['border_left']['w'];
20729 $border_right = $this->blk[$blvl]['border_right']['w'];
20730 if (!$this->blk[$blvl]['border_top'] || $divider == 'pagetop' || $continuingpage) {
20731 $border_top = 0;
20732 }
20733 if (!$this->blk[$blvl]['border_bottom'] || $blockstate == 1 || $divider == 'pagebottom') {
20734 $border_bottom = 0;
20735 }
20736
20737 $brTL_H = 0;
20738 $brTL_V = 0;
20739 $brTR_H = 0;
20740 $brTR_V = 0;
20741 $brBL_H = 0;
20742 $brBL_V = 0;
20743 $brBR_H = 0;
20744 $brBR_V = 0;
20745
20746 $brset = false;
20747/*-- BORDER-RADIUS --*/
20748 if (isset($this->blk[$blvl]['border_radius_TL_H'])) { $brTL_H = $this->blk[$blvl]['border_radius_TL_H']; $brset = true; }
20749 if (isset($this->blk[$blvl]['border_radius_TL_V'])) { $brTL_V = $this->blk[$blvl]['border_radius_TL_V']; $brset = true; }
20750 if (isset($this->blk[$blvl]['border_radius_TR_H'])) { $brTR_H = $this->blk[$blvl]['border_radius_TR_H']; $brset = true; }
20751 if (isset($this->blk[$blvl]['border_radius_TR_V'])) { $brTR_V = $this->blk[$blvl]['border_radius_TR_V']; $brset = true; }
20752 if (isset($this->blk[$blvl]['border_radius_BR_H'])) { $brBR_H = $this->blk[$blvl]['border_radius_BR_H']; $brset = true; }
20753 if (isset($this->blk[$blvl]['border_radius_BR_V'])) { $brBR_V = $this->blk[$blvl]['border_radius_BR_V']; $brset = true; }
20754 if (isset($this->blk[$blvl]['border_radius_BL_H'])) { $brBL_H = $this->blk[$blvl]['border_radius_BL_H']; $brset = true; }
20755 if (isset($this->blk[$blvl]['border_radius_BL_V'])) { $brBL_V = $this->blk[$blvl]['border_radius_BL_V']; $brset = true; }
20756
20757 // mPDF 5.4.17
20758 //if (!$this->blk[$blvl]['border_top'] || $divider == 'pagetop' || $continuingpage || $this->keep_block_together) {
20759 if (!$this->blk[$blvl]['border_top'] || $divider == 'pagetop' || $continuingpage) {
20760 $brTL_H = 0;
20761 $brTL_V = 0;
20762 $brTR_H = 0;
20763 $brTR_V = 0;
20764 }
20765 // mPDF 5.4.17
20766 //if (!$this->blk[$blvl]['border_bottom'] || $blockstate == 1 || $divider == 'pagebottom' || $this->keep_block_together) {
20767 if (!$this->blk[$blvl]['border_bottom'] || $blockstate == 1 || $divider == 'pagebottom') {
20768 $brBL_H = 0;
20769 $brBL_V = 0;
20770 $brBR_H = 0;
20771 $brBR_V = 0;
20772 }
20773
20774 // Disallow border-radius if it is smaller than the border width.
20775 if ($brTL_H < min($border_left, $border_top)) { $brTL_H = $brTL_V = 0; }
20776 if ($brTL_V < min($border_left, $border_top)) { $brTL_V = $brTL_H = 0; }
20777 if ($brTR_H < min($border_right, $border_top)) { $brTR_H = $brTR_V = 0; }
20778 if ($brTR_V < min($border_right, $border_top)) { $brTR_V = $brTR_H = 0; }
20779 if ($brBL_H < min($border_left, $border_bottom)) { $brBL_H = $brBL_V = 0; }
20780 if ($brBL_V < min($border_left, $border_bottom)) { $brBL_V = $brBL_H = 0; }
20781 if ($brBR_H < min($border_right, $border_bottom)) { $brBR_H = $brBR_V = 0; }
20782 if ($brBR_V < min($border_right, $border_bottom)) { $brBR_V = $brBR_H = 0; }
20783
20784 // CHECK FOR radii that sum to > width or height of div ********
20785 $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));
20786 if ($f < 1) {
20787 $brTL_H *= $f;
20788 $brTL_V *= $f;
20789 $brTR_H *= $f;
20790 $brTR_V *= $f;
20791 $brBL_H *= $f;
20792 $brBL_V *= $f;
20793 $brBR_H *= $f;
20794 $brBR_V *= $f;
20795 }
20796/*-- END BORDER-RADIUS --*/
20797
20798 $tbcol = $this->ConvertColor(255);
20799 for($l=0; $l <= $blvl; $l++) {
20800 if ($this->blk[$l]['bgcolor']) {
20801 $tbcol = $this->blk[$l]['bgcolorarray'];
20802 }
20803 }
20804
20805 // BORDERS
20806 if (isset($this->blk[$blvl]['y0']) && $this->blk[$blvl]['y0']) { $y0 = $this->blk[$blvl]['y0']; }
20807 $h = $y1 - $y0;
20808 $w = $this->blk[$blvl]['width'];
20809
20810 //if ($this->blk[$blvl]['border_top']) {
20811 // Reinstate line above for dotted line divider when block border crosses a page
20812 if ($this->blk[$blvl]['border_top'] && $divider != 'pagetop' && !$continuingpage) {
20813 $tbd = $this->blk[$blvl]['border_top'];
20814
20815 // mPDF 5.4.18
20816 $legend = '';
20817 if (isset($this->blk[$blvl]['border_legend']) && $this->blk[$blvl]['border_legend']) {
20818 $legend = $this->blk[$blvl]['border_legend']; // Same structure array as textbuffer
20819 $txt = ltrim($legend[0]);
20820
20821 //Set font, size, style, color
20822 $this->SetFont($legend[4],$legend[2],$legend[11]);
20823 if ($legend[3]) {
20824 $cor = $legend[3];
20825 $this->SetTColor($cor);
20826 }
20827 $stringWidth = $this->GetStringWidth($txt );
20828 $save_x = $this->x;
20829 $save_y = $this->y;
20830 $save_currentfontfamily = $this->FontFamily;
20831 $save_currentfontsize = $this->FontSizePt;
20832 $save_currentfontstyle = $this->FontStyle.($this->U ? 'U' : '').($this->S ? 'S' : '');
20833 $this->y = $y0 - $this->FontSize/2 + $this->blk[$blvl]['border_top']['w']/2;
20834 $this->x = $x0 + $this->blk[$blvl]['padding_left'] + $this->blk[$blvl]['border_left']['w'];
20835
20836 // Set the distance from the border line to the text ? make configurable variable
20837 $gap = 0.2 * $this->FontSize;
20838
20839 $legbreakL = $this->x - $gap;
20840 $legbreakR = $this->x + $stringWidth + $gap;
20841
20842 $this->Cell( $stringWidth, $this->FontSize, $txt , '', 0, 'C', $fill, '', 0, 0,0,'M', $fill);
20843 // Reset
20844 $this->x = $save_x;
20845 $this->y = $save_y;
20846 $this->SetFont($save_currentfontfamily,$save_currentfontstyle,$save_currentfontsize);
20847 $this->SetTColor($this->ConvertColor(0));
20848 }
20849
20850 if (isset($tbd['s']) && $tbd['s']) {
20851 if (!$brset && $tbd['style']!='dotted' && $tbd['style']!='dashed') {
20852 $this->_out('q');
20853 $this->SetLineWidth(0);
20854 $this->_out(sprintf('%.3F %.3F m ',($x0)*_MPDFK, ($this->h-($y0))*_MPDFK));
20855 $this->_out(sprintf('%.3F %.3F l ',($x0 + $border_left)*_MPDFK, ($this->h-($y0 + $border_top))*_MPDFK));
20856 $this->_out(sprintf('%.3F %.3F l ',($x0 + $w - $border_right)*_MPDFK, ($this->h-($y0 + $border_top))*_MPDFK));
20857 $this->_out(sprintf('%.3F %.3F l ',($x0 + $w)*_MPDFK, ($this->h-($y0))*_MPDFK));
20858 $this->_out(' h W n '); // Ends path no-op & Sets the clipping path
20859 }
20860
20861 $this->_setBorderLine($tbd);
20862 if ($tbd['style']=='dotted' || $tbd['style']=='dashed') {
20863 $legbreakL -= $border_top/2; // because line cap different
20864 $legbreakR += $border_top/2;
20865 $this->_setDashBorder($tbd['style'],$divider,$continuingpage,'T');
20866 }
20867/*-- BORDER-RADIUS --*/
20868 else if (($brTL_V && $brTL_H) || ($brTR_V && $brTR_H) || $tbd['style']=='solid' || $tbd['style']=='double' ) { // mPDF 5.6.58
20869 $this->SetLineJoin(0);
20870 $this->SetLineCap(0);
20871 }
20872 $s = '';
20873 if ($brTR_H && $brTR_V) {
20874 $s .= ($this->_EllipseArc($x0 + $w - $brTR_H, $y0 + $brTR_V, $brTR_H - $border_top/2 , $brTR_V - $border_top/2 , 1, 2, true))."\n";
20875 }
20876 else
20877/*-- END BORDER-RADIUS --*/
20878 if ($tbd['style']=='solid' || $tbd['style']=='double') {
20879 $s .= (sprintf('%.3F %.3F m ',($x0 + $w)*_MPDFK, ($this->h-($y0 + ($border_top/2)))*_MPDFK))."\n";
20880 }
20881 else {
20882 $s .= (sprintf('%.3F %.3F m ',($x0 + $w - ($border_top/2))*_MPDFK, ($this->h-($y0 + ($border_top/2)))*_MPDFK))."\n";
20883 }
20884/*-- BORDER-RADIUS --*/
20885 if ($brTL_H && $brTL_V ) {
20886 // mPDF 5.4.18
20887 if ($legend) {
20888 if ($legbreakR < ($x0 + $w - $brTR_H)) {
20889 $s .= (sprintf('%.3F %.3F l ', $legbreakR*_MPDFK, ($this->h-($y0 + ($border_top/2)))*_MPDFK))."\n";
20890 }
20891 if ($legbreakL > ($x0 + $brTL_H )) {
20892 $s .= (sprintf('%.3F %.3F m ',$legbreakL*_MPDFK, ($this->h-($y0 + ($border_top/2)))*_MPDFK))."\n";
20893 $s .= (sprintf('%.3F %.3F l ',($x0 + $brTL_H )*_MPDFK, ($this->h-($y0 + ($border_top/2)))*_MPDFK)."\n");
20894 }
20895 else {
20896 $s .= (sprintf('%.3F %.3F m ',($x0 + $brTL_H )*_MPDFK, ($this->h-($y0 + ($border_top/2)))*_MPDFK))."\n";
20897 }
20898 }
20899 else {
20900 $s .= (sprintf('%.3F %.3F l ',($x0 + $brTL_H )*_MPDFK, ($this->h-($y0 + ($border_top/2)))*_MPDFK))."\n";
20901 }
20902 $s .= ($this->_EllipseArc($x0 + $brTL_H, $y0 + $brTL_V, $brTL_H - $border_top/2 , $brTL_V - $border_top/2 , 2, 1))."\n";
20903 }
20904 else {
20905/*-- END BORDER-RADIUS --*/
20906 // mPDF 5.4.18
20907 if ($legend) {
20908 if ($legbreakR < ($x0 + $w)) {
20909 $s .= (sprintf('%.3F %.3F l ',$legbreakR*_MPDFK, ($this->h-($y0 + ($border_top/2)))*_MPDFK))."\n";
20910 }
20911 if ($legbreakL > ($x0)) {
20912 $s .= (sprintf('%.3F %.3F m ',$legbreakL*_MPDFK, ($this->h-($y0 + ($border_top/2)))*_MPDFK))."\n";
20913 if ($tbd['style']=='solid' || $tbd['style']=='double') {
20914 $s .= (sprintf('%.3F %.3F l ',($x0)*_MPDFK, ($this->h-($y0 + ($border_top/2)))*_MPDFK))."\n";
20915 }
20916 else {
20917 $s .= (sprintf('%.3F %.3F l ',($x0 + ($border_top/2))*_MPDFK, ($this->h-($y0 + ($border_top/2)))*_MPDFK))."\n";
20918 }
20919 }
20920 else if ($tbd['style']=='solid' || $tbd['style']=='double') {
20921 $s .= (sprintf('%.3F %.3F m ', ($x0)*_MPDFK, ($this->h-($y0 + ($border_top/2)))*_MPDFK))."\n";
20922 }
20923 else {
20924 $s .= (sprintf('%.3F %.3F m ', ($x0 + $border_top/2)*_MPDFK, ($this->h-($y0 + ($border_top/2)))*_MPDFK))."\n";
20925 }
20926 }
20927 else if ($tbd['style']=='solid' || $tbd['style']=='double') {
20928 $s .= (sprintf('%.3F %.3F l ',($x0)*_MPDFK, ($this->h-($y0 + ($border_top/2)))*_MPDFK))."\n";
20929 }
20930 else {
20931 $s .= (sprintf('%.3F %.3F l ',($x0 + ($border_top/2))*_MPDFK, ($this->h-($y0 + ($border_top/2)))*_MPDFK))."\n";
20932 }
20933/*-- BORDER-RADIUS --*/
20934 }
20935/*-- END BORDER-RADIUS --*/
20936 $s .= 'S'."\n";
20937 $this->_out($s);
20938
20939 if ($tbd['style']=='double') {
20940 $this->SetLineWidth($tbd['w']/3);
20941 $this->SetDColor($tbcol);
20942 $this->_out($s);
20943 }
20944 if (!$brset && $tbd['style']!='dotted' && $tbd['style']!='dashed') { $this->_out('Q'); }
20945
20946 // Reset Corners and Dash off
20947 $this->SetLineWidth(0.1); // mPDF 5.6.57
20948 $this->SetDColor($this->ConvertColor(0));
20949 $this->SetLineJoin(2);
20950 $this->SetLineCap(2);
20951 $this->SetDash();
20952 }
20953 }
20954 //if ($this->blk[$blvl]['border_bottom'] && $blockstate != 1) {
20955 // Reinstate line above for dotted line divider when block border crosses a page
20956 if ($this->blk[$blvl]['border_bottom'] && $blockstate != 1 && $divider != 'pagebottom') {
20957 $tbd = $this->blk[$blvl]['border_bottom'];
20958 if (isset($tbd['s']) && $tbd['s']) {
20959 if (!$brset && $tbd['style']!='dotted' && $tbd['style']!='dashed') {
20960 $this->_out('q');
20961 $this->SetLineWidth(0);
20962 $this->_out(sprintf('%.3F %.3F m ',($x0)*_MPDFK, ($this->h-($y0 + $h))*_MPDFK));
20963 $this->_out(sprintf('%.3F %.3F l ',($x0 + $border_left)*_MPDFK, ($this->h-($y0 + $h - $border_bottom))*_MPDFK));
20964 $this->_out(sprintf('%.3F %.3F l ',($x0 + $w - $border_right)*_MPDFK, ($this->h-($y0 + $h - $border_bottom))*_MPDFK));
20965 $this->_out(sprintf('%.3F %.3F l ',($x0 + $w)*_MPDFK, ($this->h-($y0 + $h))*_MPDFK));
20966 $this->_out(' h W n '); // Ends path no-op & Sets the clipping path
20967 }
20968
20969 $this->_setBorderLine($tbd);
20970 if ($tbd['style']=='dotted' || $tbd['style']=='dashed') { $this->_setDashBorder($tbd['style'],$divider,$continuingpage,'B'); }
20971/*-- BORDER-RADIUS --*/
20972 else if (($brBL_V && $brBL_H) || ($brBR_V && $brBR_H) || $tbd['style']=='solid' || $tbd['style']=='double' ) { // mPDF 5.6.58
20973 $this->SetLineJoin(0);
20974 $this->SetLineCap(0);
20975 }
20976 $s = '';
20977 if ($brBL_H && $brBL_V) {
20978 $s .= ($this->_EllipseArc($x0 + $brBL_H, $y0 + $h - $brBL_V, $brBL_H - $border_bottom/2 , $brBL_V - $border_bottom/2 , 3, 2, true))."\n";
20979 }
20980 else
20981/*-- END BORDER-RADIUS --*/
20982 if ($tbd['style']=='solid' || $tbd['style']=='double') {
20983 $s .= (sprintf('%.3F %.3F m ',($x0)*_MPDFK, ($this->h-($y0 + $h - ($border_bottom/2)))*_MPDFK))."\n";
20984 }
20985 else {
20986 $s .= (sprintf('%.3F %.3F m ',($x0 + ($border_bottom/2))*_MPDFK, ($this->h-($y0 + $h - ($border_bottom/2)))*_MPDFK))."\n";
20987 }
20988/*-- BORDER-RADIUS --*/
20989 if ($brBR_H && $brBR_V ) {
20990 $s .= (sprintf('%.3F %.3F l ',($x0 + $w - ($border_bottom/2) - $brBR_H )*_MPDFK, ($this->h-($y0 + $h - ($border_bottom/2)))*_MPDFK))."\n";
20991 $s .= ($this->_EllipseArc($x0 + $w - $brBR_H, $y0 + $h - $brBR_V, $brBR_H - $border_bottom/2 , $brBR_V - $border_bottom/2 , 4, 1))."\n";
20992 }
20993 else
20994/*-- END BORDER-RADIUS --*/
20995 if ($tbd['style']=='solid' || $tbd['style']=='double') {
20996 $s .= (sprintf('%.3F %.3F l ',($x0 + $w)*_MPDFK, ($this->h-($y0 + $h - ($border_bottom/2)))*_MPDFK))."\n";
20997 }
20998 else {
20999 $s .= (sprintf('%.3F %.3F l ',($x0 + $w - ($border_bottom/2))*_MPDFK, ($this->h-($y0 + $h - ($border_bottom/2)))*_MPDFK))."\n";
21000 }
21001 $s .= 'S'."\n";
21002 $this->_out($s);
21003
21004 if ($tbd['style']=='double') {
21005 $this->SetLineWidth($tbd['w']/3);
21006 $this->SetDColor($tbcol);
21007 $this->_out($s);
21008 }
21009 if (!$brset && $tbd['style']!='dotted' && $tbd['style']!='dashed') { $this->_out('Q'); }
21010
21011
21012 // Reset Corners and Dash off
21013 $this->SetLineWidth(0.1); // mPDF 5.6.57
21014 $this->SetDColor($this->ConvertColor(0));
21015 $this->SetLineJoin(2);
21016 $this->SetLineCap(2);
21017 $this->SetDash();
21018 }
21019 }
21020 if ($this->blk[$blvl]['border_left']) {
21021 $tbd = $this->blk[$blvl]['border_left'];
21022 if (isset($tbd['s']) && $tbd['s']) {
21023 if (!$brset && $tbd['style']!='dotted' && $tbd['style']!='dashed') {
21024 $this->_out('q');
21025 $this->SetLineWidth(0);
21026 $this->_out(sprintf('%.3F %.3F m ',($x0)*_MPDFK, ($this->h-($y0))*_MPDFK));
21027 $this->_out(sprintf('%.3F %.3F l ',($x0 + $border_left)*_MPDFK, ($this->h-($y0+$border_top))*_MPDFK));
21028 $this->_out(sprintf('%.3F %.3F l ',($x0 + $border_left)*_MPDFK, ($this->h-($y0 + $h - $border_bottom))*_MPDFK));
21029 $this->_out(sprintf('%.3F %.3F l ',($x0)*_MPDFK, ($this->h-($y0 + $h))*_MPDFK));
21030 $this->_out(' h W n '); // Ends path no-op & Sets the clipping path
21031 }
21032
21033 $this->_setBorderLine($tbd);
21034 if ($tbd['style']=='dotted' || $tbd['style']=='dashed') { $this->_setDashBorder($tbd['style'],$divider,$continuingpage,'L'); }
21035/*-- BORDER-RADIUS --*/
21036 else if (($brTL_V && $brTL_H) || ($brBL_V && $brBL_H) || $tbd['style']=='solid' || $tbd['style']=='double' ) { // mPDF 5.6.58
21037 $this->SetLineJoin(0);
21038 $this->SetLineCap(0);
21039 }
21040 $s = '';
21041 if ($brTL_V && $brTL_H) {
21042 $s .= ($this->_EllipseArc($x0 + $brTL_H, $y0 + $brTL_V, $brTL_H - $border_left/2 , $brTL_V - $border_left/2, 2, 2, true))."\n";
21043 }
21044 else
21045/*-- END BORDER-RADIUS --*/
21046 if ($tbd['style']=='solid' || $tbd['style']=='double') {
21047 $s .= (sprintf('%.3F %.3F m ',($x0 + ($border_left/2))*_MPDFK, ($this->h-($y0))*_MPDFK))."\n";
21048 }
21049 else {
21050 $s .= (sprintf('%.3F %.3F m ',($x0 + ($border_left/2))*_MPDFK, ($this->h-($y0 + ($border_left/2)))*_MPDFK))."\n";
21051 }
21052/*-- BORDER-RADIUS --*/
21053 if ($brBL_V && $brBL_H ) {
21054 $s .= (sprintf('%.3F %.3F l ',($x0 + ($border_left/2))*_MPDFK, ($this->h-($y0 + $h - ($border_left/2)- $brBL_V) )*_MPDFK))."\n";
21055 $s .= ($this->_EllipseArc($x0 + $brBL_H, $y0 + $h - $brBL_V, $brBL_H - $border_left/2 , $brBL_V - $border_left/2, 3, 1))."\n";
21056 }
21057 else
21058/*-- END BORDER-RADIUS --*/
21059 if ($tbd['style']=='solid' || $tbd['style']=='double') {
21060 $s .= (sprintf('%.3F %.3F l ',($x0 + ($border_left/2))*_MPDFK, ($this->h-($y0 + $h) )*_MPDFK))."\n";
21061 }
21062 else {
21063 $s .= (sprintf('%.3F %.3F l ',($x0 + ($border_left/2))*_MPDFK, ($this->h-($y0 + $h - ($border_left/2)) )*_MPDFK))."\n";
21064 }
21065 $s .= 'S'."\n";
21066 $this->_out($s);
21067
21068 if ($tbd['style']=='double') {
21069 $this->SetLineWidth($tbd['w']/3);
21070 $this->SetDColor($tbcol);
21071 $this->_out($s);
21072 }
21073 if (!$brset && $tbd['style']!='dotted' && $tbd['style']!='dashed') { $this->_out('Q'); }
21074
21075 // Reset Corners and Dash off
21076 $this->SetLineWidth(0.1); // mPDF 5.6.57
21077 $this->SetDColor($this->ConvertColor(0));
21078 $this->SetLineJoin(2);
21079 $this->SetLineCap(2);
21080 $this->SetDash();
21081 }
21082 }
21083 if ($this->blk[$blvl]['border_right']) {
21084 $tbd = $this->blk[$blvl]['border_right'];
21085 if (isset($tbd['s']) && $tbd['s']) {
21086 if (!$brset && $tbd['style']!='dotted' && $tbd['style']!='dashed') {
21087 $this->_out('q');
21088 $this->SetLineWidth(0);
21089 $this->_out(sprintf('%.3F %.3F m ',($x0 + $w)*_MPDFK, ($this->h-($y0))*_MPDFK));
21090 $this->_out(sprintf('%.3F %.3F l ',($x0 + $w - $border_right)*_MPDFK, ($this->h-($y0+$border_top))*_MPDFK));
21091 $this->_out(sprintf('%.3F %.3F l ',($x0 + $w - $border_right)*_MPDFK, ($this->h-($y0 + $h - $border_bottom))*_MPDFK));
21092 $this->_out(sprintf('%.3F %.3F l ',($x0 + $w)*_MPDFK, ($this->h-($y0 + $h))*_MPDFK));
21093 $this->_out(' h W n '); // Ends path no-op & Sets the clipping path
21094 }
21095
21096 $this->_setBorderLine($tbd);
21097 if ($tbd['style']=='dotted' || $tbd['style']=='dashed') { $this->_setDashBorder($tbd['style'],$divider,$continuingpage,'R'); }
21098/*-- BORDER-RADIUS --*/
21099 else if (($brTR_V && $brTR_H) || ($brBR_V && $brBR_H) || $tbd['style']=='solid' || $tbd['style']=='double' ) { // mPDF 5.6.58
21100 $this->SetLineJoin(0);
21101 $this->SetLineCap(0);
21102 }
21103 $s = '';
21104 if ($brBR_V && $brBR_H) {
21105 $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";
21106 }
21107 else
21108/*-- END BORDER-RADIUS --*/
21109 if ($tbd['style']=='solid' || $tbd['style']=='double') {
21110 $s .= (sprintf('%.3F %.3F m ',($x0 + $w - ($border_right/2))*_MPDFK, ($this->h-($y0 + $h))*_MPDFK))."\n";
21111 }
21112 else {
21113 $s .= (sprintf('%.3F %.3F m ',($x0 + $w - ($border_right/2))*_MPDFK, ($this->h-($y0 + $h - ($border_right/2)))*_MPDFK))."\n";
21114 }
21115/*-- BORDER-RADIUS --*/
21116 if ($brTR_V && $brTR_H ) {
21117 $s .= (sprintf('%.3F %.3F l ',($x0 + $w - ($border_right/2))*_MPDFK, ($this->h-($y0 + ($border_right/2) + $brTR_V) )*_MPDFK))."\n";
21118 $s .= ($this->_EllipseArc($x0 + $w - $brTR_H, $y0 + $brTR_V, $brTR_H - $border_right/2 , $brTR_V - $border_right/2, 1, 1))."\n";
21119 }
21120 else
21121/*-- END BORDER-RADIUS --*/
21122 if ($tbd['style']=='solid' || $tbd['style']=='double') {
21123 $s .= (sprintf('%.3F %.3F l ',($x0 + $w - ($border_right/2))*_MPDFK, ($this->h-($y0) )*_MPDFK))."\n";
21124 }
21125 else {
21126 $s .= (sprintf('%.3F %.3F l ',($x0 + $w - ($border_right/2))*_MPDFK, ($this->h-($y0 + ($border_right/2)) )*_MPDFK))."\n";
21127 }
21128 $s .= 'S'."\n";
21129 $this->_out($s);
21130
21131 if ($tbd['style']=='double') {
21132 $this->SetLineWidth($tbd['w']/3);
21133 $this->SetDColor($tbcol);
21134 $this->_out($s);
21135 }
21136 if (!$brset && $tbd['style']!='dotted' && $tbd['style']!='dashed') { $this->_out('Q'); }
21137
21138 // Reset Corners and Dash off
21139 $this->SetLineWidth(0.1); // mPDF 5.6.57
21140 $this->SetDColor($this->ConvertColor(0));
21141 $this->SetLineJoin(2);
21142 $this->SetLineCap(2);
21143 $this->SetDash();
21144 }
21145 }
21146
21147
21148 $this->SetDash();
21149 $this->y = $save_y;
21150
21151
21152 // BACKGROUNDS are disabled in columns/kbt/headers - messes up the repositioning in printcolumnbuffer
21153 if ($this->ColActive || $this->kwt || $this->keep_block_together) { return ; }
21154
21155
21156 $bgx0 = $x0;
21157 $bgx1 = $x1;
21158 $bgy0 = $y0;
21159 $bgy1 = $y1;
21160
21161 // Defined br values represent the radius of the outer curve - need to take border-width/2 from each radius for drawing the borders
21162 if (isset($this->blk[$blvl]['background_clip']) && $this->blk[$blvl]['background_clip'] == 'padding-box') {
21163 $brbgTL_H = max(0, $brTL_H - $this->blk[$blvl]['border_left']['w']);
21164 $brbgTL_V = max(0, $brTL_V - $this->blk[$blvl]['border_top']['w']);
21165 $brbgTR_H = max(0, $brTR_H - $this->blk[$blvl]['border_right']['w']);
21166 $brbgTR_V = max(0, $brTR_V - $this->blk[$blvl]['border_top']['w']);
21167 $brbgBL_H = max(0, $brBL_H - $this->blk[$blvl]['border_left']['w']);
21168 $brbgBL_V = max(0, $brBL_V - $this->blk[$blvl]['border_bottom']['w']);
21169 $brbgBR_H = max(0, $brBR_H - $this->blk[$blvl]['border_right']['w']);
21170 $brbgBR_V = max(0, $brBR_V - $this->blk[$blvl]['border_bottom']['w']);
21171 $bgx0 += $this->blk[$blvl]['border_left']['w'];
21172 $bgx1 -= $this->blk[$blvl]['border_right']['w'];
21173 if ($this->blk[$blvl]['border_top'] && $divider != 'pagetop' && !$continuingpage) {
21174 $bgy0 += $this->blk[$blvl]['border_top']['w'];
21175 }
21176 if ($this->blk[$blvl]['border_bottom'] && $blockstate != 1 && $divider != 'pagebottom') {
21177 $bgy1 -= $this->blk[$blvl]['border_bottom']['w'];
21178 }
21179 }
21180 // mPDF 5.6.09
21181 else if (isset($this->blk[$blvl]['background_clip']) && $this->blk[$blvl]['background_clip'] == 'content-box') {
21182 $brbgTL_H = max(0, $brTL_H - $this->blk[$blvl]['border_left']['w'] - $this->blk[$blvl]['padding_left']);
21183 $brbgTL_V = max(0, $brTL_V - $this->blk[$blvl]['border_top']['w'] - $this->blk[$blvl]['padding_top']);
21184 $brbgTR_H = max(0, $brTR_H - $this->blk[$blvl]['border_right']['w'] - $this->blk[$blvl]['padding_right']);
21185 $brbgTR_V = max(0, $brTR_V - $this->blk[$blvl]['border_top']['w'] - $this->blk[$blvl]['padding_top']);
21186 $brbgBL_H = max(0, $brBL_H - $this->blk[$blvl]['border_left']['w'] - $this->blk[$blvl]['padding_left']);
21187 $brbgBL_V = max(0, $brBL_V - $this->blk[$blvl]['border_bottom']['w'] - $this->blk[$blvl]['padding_bottom']);
21188 $brbgBR_H = max(0, $brBR_H - $this->blk[$blvl]['border_right']['w'] - $this->blk[$blvl]['padding_right']);
21189 $brbgBR_V = max(0, $brBR_V - $this->blk[$blvl]['border_bottom']['w'] - $this->blk[$blvl]['padding_bottom']);
21190 $bgx0 += $this->blk[$blvl]['border_left']['w'] + $this->blk[$blvl]['padding_left'];
21191 $bgx1 -= $this->blk[$blvl]['border_right']['w'] + $this->blk[$blvl]['padding_right'];
21192 if (($this->blk[$blvl]['border_top']['w'] || $this->blk[$blvl]['padding_top']) && $divider != 'pagetop' && !$continuingpage) {
21193 $bgy0 += $this->blk[$blvl]['border_top']['w'] + $this->blk[$blvl]['padding_top'];
21194 }
21195 if (($this->blk[$blvl]['border_bottom']['w'] || $this->blk[$blvl]['padding_bottom']) && $blockstate != 1 && $divider != 'pagebottom') {
21196 $bgy1 -= $this->blk[$blvl]['border_bottom']['w'] + $this->blk[$blvl]['padding_bottom'];
21197 }
21198 }
21199 else {
21200 $brbgTL_H = $brTL_H;
21201 $brbgTL_V = $brTL_V;
21202 $brbgTR_H = $brTR_H;
21203 $brbgTR_V = $brTR_V;
21204 $brbgBL_H = $brBL_H;
21205 $brbgBL_V = $brBL_V;
21206 $brbgBR_H = $brBR_H;
21207 $brbgBR_V = $brBR_V;
21208 }
21209
21210 // Set clipping path
21211 $s = ' q 0 w '; // Line width=0
21212 $s .= sprintf('%.3F %.3F m ', ($bgx0+$brbgTL_H )*_MPDFK, ($this->h-$bgy0)*_MPDFK); // start point TL before the arc
21213/*-- BORDER-RADIUS --*/
21214 if ($brbgTL_H || $brbgTL_V) {
21215 $s .= $this->_EllipseArc($bgx0+$brbgTL_H, $bgy0+$brbgTL_V, $brbgTL_H , $brbgTL_V , 2); // segment 2 TL
21216 }
21217/*-- END BORDER-RADIUS --*/
21218 $s .= sprintf('%.3F %.3F l ', ($bgx0)*_MPDFK, ($this->h-($bgy1-$brbgBL_V ))*_MPDFK); // line to BL
21219/*-- BORDER-RADIUS --*/
21220 if ($brbgBL_H || $brbgBL_V) {
21221 $s .= $this->_EllipseArc($bgx0+$brbgBL_H, $bgy1-$brbgBL_V, $brbgBL_H , $brbgBL_V , 3); // segment 3 BL
21222 }
21223/*-- END BORDER-RADIUS --*/
21224 $s .= sprintf('%.3F %.3F l ', ($bgx1-$brbgBR_H )*_MPDFK, ($this->h-($bgy1))*_MPDFK); // line to BR
21225/*-- BORDER-RADIUS --*/
21226 if ($brbgBR_H || $brbgBR_V) {
21227 $s .= $this->_EllipseArc($bgx1-$brbgBR_H, $bgy1-$brbgBR_V, $brbgBR_H , $brbgBR_V , 4); // segment 4 BR
21228 }
21229/*-- END BORDER-RADIUS --*/
21230 $s .= sprintf('%.3F %.3F l ', ($bgx1)*_MPDFK, ($this->h-($bgy0+$brbgTR_V))*_MPDFK); // line to TR
21231/*-- BORDER-RADIUS --*/
21232 if ($brbgTR_H || $brbgTR_V) {
21233 $s .= $this->_EllipseArc($bgx1-$brbgTR_H, $bgy0+$brbgTR_V, $brbgTR_H , $brbgTR_V , 1); // segment 1 TR
21234 }
21235/*-- END BORDER-RADIUS --*/
21236 $s .= sprintf('%.3F %.3F l ', ($bgx0+$brbgTL_H )*_MPDFK, ($this->h-$bgy0)*_MPDFK); // line to TL
21237
21238
21239 // Box Shadow
21240 $shadow = '';
21241 if (isset($this->blk[$blvl]['box_shadow']) && $this->blk[$blvl]['box_shadow'] && $h > 0) {
21242 foreach($this->blk[$blvl]['box_shadow'] AS $sh) {
21243 // Colors
21244 if ($sh['col']{0}==1) {
21245 $colspace = 'Gray';
21246 if ($sh['col']{2}==1) { $col1 = '1'.$sh['col'][1].'1'.$sh['col'][3]; }
21247 else { $col1 = '1'.$sh['col'][1].'1'.chr(100); }
21248 $col2 = '1'.$sh['col'][1].'1'.chr(0);
21249 }
21250 else if ($sh['col']{0}==4) { // CMYK
21251 $colspace = 'CMYK';
21252 $col1 = '6'.$sh['col'][1].$sh['col'][2].$sh['col'][3].$sh['col'][4].chr(100);
21253 $col2 = '6'.$sh['col'][1].$sh['col'][2].$sh['col'][3].$sh['col'][4].chr(0);
21254 }
21255 else if ($sh['col']{0}==5) { // RGBa
21256 $colspace = 'RGB';
21257 $col1 = '5'.$sh['col'][1].$sh['col'][2].$sh['col'][3].$sh['col'][4];
21258 $col2 = '5'.$sh['col'][1].$sh['col'][2].$sh['col'][3].chr(0);
21259 }
21260 else if ($sh['col']{0}==6) { // CMYKa
21261 $colspace = 'CMYK';
21262 $col1 = '6'.$sh['col'][1].$sh['col'][2].$sh['col'][3].$sh['col'][4].$sh['col'][5];
21263 $col2 = '6'.$sh['col'][1].$sh['col'][2].$sh['col'][3].$sh['col'][4].chr(0);
21264 }
21265 else {
21266 $colspace = 'RGB';
21267 $col1 = '5'.$sh['col'][1].$sh['col'][2].$sh['col'][3].chr(100);
21268 $col2 = '5'.$sh['col'][1].$sh['col'][2].$sh['col'][3].chr(0);
21269 }
21270
21271 // Use clipping path as set above (and rectangle around page) to clip area outside box
21272 $shadow .= $s; // Use the clipping path with W*
21273 $shadow .= sprintf('0 %.3F m %.3F %.3F l ', $this->h*_MPDFK, $this->w*_MPDFK, $this->h*_MPDFK);
21274 $shadow .= sprintf('%.3F 0 l 0 0 l 0 %.3F l ', $this->w*_MPDFK, $this->h*_MPDFK);
21275 $shadow .= 'W n'."\n";
21276
21277 $sh['blur'] = abs($sh['blur']); // cannot have negative blur value
21278 // Ensure spread/blur do not make effective shadow width/height < 0
21279 // Could do more complex things but this just adjusts spread value
21280 if (-$sh['spread'] + $sh['blur']/2 > min($w/2, $h/2)) {
21281 $sh['spread'] = $sh['blur']/2 - min($w/2, $h/2) + 0.01;
21282 }
21283 // Shadow Offset
21284 if ($sh['x'] || $sh['y']) $shadow .= sprintf(' q 1 0 0 1 %.4F %.4F cm', $sh['x']*_MPDFK, -$sh['y']*_MPDFK)."\n";
21285
21286 // Set path for INNER shadow
21287 $shadow .= ' q 0 w ';
21288 $shadow .= $this->SetFColor($col1, true)."\n";
21289 if ($col1{0}==5 && ord($col1{4})<100) { // RGBa
21290 $shadow .= $this->SetAlpha(ord($col1{4})/100, 'Normal', true, 'F')."\n";
21291 }
21292 else if ($col1{0}==6 && ord($col1{5})<100) { // CMYKa
21293 $shadow .= $this->SetAlpha(ord($col1{5})/100, 'Normal', true, 'F')."\n";
21294 }
21295 else if ($col1{0}==1 && $col1{2}==1 && ord($col1{3})<100) { // Gray
21296 $shadow .= $this->SetAlpha(ord($col1{3})/100, 'Normal', true, 'F')."\n";
21297 }
21298
21299 // Blur edges
21300 $mag = 0.551784; // Bezier Control magic number for 4-part spline for circle/ellipse
21301 $mag2 = 0.551784; // Bezier Control magic number to fill in edge of blurred rectangle
21302 $d1 = $sh['spread']+$sh['blur']/2;
21303 $d2 = $sh['spread']-$sh['blur']/2;
21304 $bl = $sh['blur'];
21305 $x00 = $x0 - $d1;
21306 $y00 = $y0 - $d1;
21307 $w00 = $w + $d1*2;
21308 $h00 = $h + $d1*2;
21309
21310 // If any border-radius is greater width-negative spread(inner edge), ignore radii for shadow or screws up
21311 $flatten = false;
21312 if (max($brbgTR_H, $brbgTL_H, $brbgBR_H, $brbgBL_H) >= $w+$d2) { $flatten = true; }
21313 if (max($brbgTR_V, $brbgTL_V, $brbgBR_V, $brbgBL_V) >= $h+$d2) { $flatten = true; }
21314
21315
21316 // TOP RIGHT corner
21317 $p1x = $x00+$w00-$d1-$brbgTR_H; $p1c2x = $p1x +($d2+$brbgTR_H)*$mag;
21318 $p1y = $y00+$bl;
21319 $p2x = $x00+$w00-$d1-$brbgTR_H; $p2c2x = $p2x + ($d1+$brbgTR_H)*$mag;
21320 $p2y = $y00; $p2c1y = $p2y + $bl/2;
21321 $p3x = $x00+$w00; $p3c2x = $p3x - $bl/2;
21322 $p3y = $y00+$d1+$brbgTR_V; $p3c1y = $p3y - ($d1+$brbgTR_V)*$mag;
21323 $p4x = $x00+$w00-$bl;
21324 $p4y = $y00+$d1+$brbgTR_V; $p4c2y = $p4y - ($d2+$brbgTR_V)*$mag;
21325 if (-$d2 > min($brbgTR_H, $brbgTR_V) || $flatten) {
21326 $p1x = $x00+$w00-$bl; $p1c2x = $p1x;
21327 $p2x = $x00+$w00-$bl; $p2c2x = $p2x + $bl*$mag2;
21328 $p3y = $y00+$bl; $p3c1y = $p3y - $bl*$mag2;
21329 $p4y = $y00+$bl; $p4c2y = $p4y ;
21330 }
21331
21332 $shadow .= sprintf('%.3F %.3F m ', ($p1x )*_MPDFK, ($this->h-($p1y ))*_MPDFK);
21333 $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);
21334 $patch_array[0]['f']=0;
21335 $patch_array[0]['points']=array($p1x,$p1y, $p1x,$p1y,
21336 $p2x,$p2c1y, $p2x,$p2y, $p2c2x,$p2y,
21337 $p3x,$p3c1y, $p3x,$p3y, $p3c2x,$p3y,
21338 $p4x,$p4y, $p4x,$p4y, $p4x,$p4c2y,
21339 $p1c2x,$p1y);
21340 $patch_array[0]['colors'] = array($col1,$col2,$col2,$col1);
21341
21342
21343 // RIGHT
21344 $p1x = $x00+$w00; // control point only matches p3 preceding
21345 $p1y = $y00+$d1+$brbgTR_V;
21346 $p2x = $x00+$w00-$bl; // control point only matches p4 preceding
21347 $p2y = $y00+$d1+$brbgTR_V;
21348 $p3x = $x00+$w00-$bl;
21349 $p3y = $y00+$h00-$d1-$brbgBR_V;
21350 $p4x = $x00+$w00; $p4c1x = $p4x-$bl/2;
21351 $p4y = $y00+$h00-$d1-$brbgBR_V;
21352 if (-$d2 > min($brbgTR_H, $brbgTR_V) || $flatten) {
21353 $p1y = $y00+$bl;
21354 $p2y = $y00+$bl;
21355 }
21356 if (-$d2 > min($brbgBR_H, $brbgBR_V) || $flatten) {
21357 $p3y = $y00+$h00-$bl;
21358 $p4y = $y00+$h00-$bl;
21359 }
21360
21361 $shadow .= sprintf('%.3F %.3F l ', ($p3x )*_MPDFK, ($this->h-($p3y ))*_MPDFK);
21362 $patch_array[1]['f']=2;
21363 $patch_array[1]['points']=array($p2x,$p2y,
21364 $p3x,$p3y, $p3x,$p3y, $p3x,$p3y,
21365 $p4c1x,$p4y, $p4x,$p4y, $p4x,$p4y,
21366 $p1x,$p1y);
21367 $patch_array[1]['colors'] = array($col1,$col2);
21368
21369
21370 // BOTTOM RIGHT corner
21371 $p1x = $x00+$w00-$bl; // control points only matches p3 preceding
21372 $p1y = $y00+$h00-$d1-$brbgBR_V; $p1c2y = $p1y + ($d2+$brbgBR_V)*$mag;
21373 $p2x = $x00+$w00; // control point only matches p4 preceding
21374 $p2y = $y00+$h00-$d1-$brbgBR_V; $p2c2y = $p2y + ($d1+$brbgBR_V)*$mag;
21375 $p3x = $x00+$w00-$d1-$brbgBR_H; $p3c1x = $p3x + ($d1+$brbgBR_H)*$mag;
21376 $p3y = $y00+$h00; $p3c2y = $p3y - $bl/2;
21377 $p4x = $x00+$w00-$d1-$brbgBR_H; $p4c2x = $p4x + ($d2+$brbgBR_H)*$mag;
21378 $p4y = $y00+$h00-$bl;
21379
21380 if (-$d2 > min($brbgBR_H, $brbgBR_V) || $flatten) {
21381 $p1y = $y00+$h00-$bl; $p1c2y = $p1y;
21382 $p2y = $y00+$h00-$bl; $p2c2y = $p2y + $bl*$mag2;
21383 $p3x = $x00+$w00-$bl; $p3c1x = $p3x + $bl*$mag2;
21384 $p4x = $x00+$w00-$bl; $p4c2x = $p4x;
21385 }
21386
21387 $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);
21388 $patch_array[2]['f']=2;
21389 $patch_array[2]['points']=array($p2x,$p2c2y,
21390 $p3c1x,$p3y, $p3x,$p3y, $p3x,$p3c2y,
21391 $p4x,$p4y, $p4x,$p4y, $p4c2x,$p4y,
21392 $p1x,$p1c2y);
21393 $patch_array[2]['colors'] = array($col2,$col1);
21394
21395
21396
21397 // BOTTOM
21398 $p1x = $x00+$w00-$d1-$brbgBR_H; // control point only matches p3 preceding
21399 $p1y = $y00+$h00;
21400 $p2x = $x00+$w00-$d1-$brbgBR_H; // control point only matches p4 preceding
21401 $p2y = $y00+$h00-$bl;
21402 $p3x = $x00+$d1+$brbgBL_H;
21403 $p3y = $y00+$h00-$bl;
21404 $p4x = $x00+$d1+$brbgBL_H;
21405 $p4y = $y00+$h00; $p4c1y = $p4y - $bl/2;
21406
21407 if (-$d2 > min($brbgBR_H, $brbgBR_V) || $flatten) {
21408 $p1x = $x00+$w00-$bl;
21409 $p2x = $x00+$w00-$bl;
21410 }
21411 if (-$d2 > min($brbgBL_H, $brbgBL_V) || $flatten) {
21412 $p3x = $x00+$bl;
21413 $p4x = $x00+$bl;
21414 }
21415
21416 $shadow .= sprintf('%.3F %.3F l ', ($p3x )*_MPDFK, ($this->h-($p3y ))*_MPDFK);
21417 $patch_array[3]['f']=2;
21418 $patch_array[3]['points']=array($p2x,$p2y,
21419 $p3x,$p3y, $p3x,$p3y, $p3x,$p3y,
21420 $p4x,$p4c1y, $p4x,$p4y, $p4x,$p4y,
21421 $p1x,$p1y);
21422 $patch_array[3]['colors'] = array($col1,$col2);
21423
21424 // BOTTOM LEFT corner
21425 $p1x = $x00+$d1+$brbgBL_H; $p1c2x = $p1x - ($d2+$brbgBL_H)*$mag; // control points only matches p3 preceding
21426 $p1y = $y00+$h00-$bl;
21427 $p2x = $x00+$d1+$brbgBL_H; $p2c2x = $p2x - ($d1+$brbgBL_H)*$mag; // control point only matches p4 preceding
21428 $p2y = $y00+$h00;
21429 $p3x = $x00; $p3c2x = $p3x + $bl/2;
21430 $p3y = $y00+$h00-$d1-$brbgBL_V; $p3c1y = $p3y + ($d1+$brbgBL_V)*$mag;
21431 $p4x = $x00+$bl;
21432 $p4y = $y00+$h00-$d1-$brbgBL_V; $p4c2y = $p4y + ($d2+$brbgBL_V)*$mag;
21433 if (-$d2 > min($brbgBL_H, $brbgBL_V) || $flatten) {
21434 $p1x = $x00+$bl; $p1c2x = $p1x;
21435 $p2x = $x00+$bl; $p2c2x = $p2x - $bl*$mag2;
21436 $p3y = $y00+$h00-$bl; $p3c1y = $p3y + $bl*$mag2;
21437 $p4y = $y00+$h00-$bl; $p4c2y = $p4y;
21438 }
21439
21440 $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);
21441 $patch_array[4]['f']=2;
21442 $patch_array[4]['points']=array($p2c2x,$p2y,
21443 $p3x,$p3c1y, $p3x,$p3y, $p3c2x,$p3y,
21444 $p4x,$p4y, $p4x,$p4y, $p4x,$p4c2y,
21445 $p1c2x,$p1y);
21446 $patch_array[4]['colors'] = array($col2,$col1);
21447
21448
21449 // LEFT - joins on the right (C3-C4 of previous): f = 2
21450 $p1x = $x00; // control point only matches p3 preceding
21451 $p1y = $y00+$h00-$d1-$brbgBL_V;
21452 $p2x = $x00+$bl; // control point only matches p4 preceding
21453 $p2y = $y00+$h00-$d1-$brbgBL_V;
21454 $p3x = $x00+$bl;
21455 $p3y = $y00+$d1+$brbgTL_V;
21456 $p4x = $x00; $p4c1x = $p4x + $bl/2;
21457 $p4y = $y00+$d1+$brbgTL_V;
21458 if (-$d2 > min($brbgBL_H, $brbgBL_V) || $flatten) {
21459 $p1y = $y00+$h00-$bl;
21460 $p2y = $y00+$h00-$bl;
21461 }
21462 if (-$d2 > min($brbgTL_H, $brbgTL_V) || $flatten) {
21463 $p3y = $y00+$bl;
21464 $p4y = $y00+$bl;
21465 }
21466
21467 $shadow .= sprintf('%.3F %.3F l ', ($p3x )*_MPDFK, ($this->h-($p3y ))*_MPDFK);
21468 $patch_array[5]['f']=2;
21469 $patch_array[5]['points']=array($p2x,$p2y,
21470 $p3x,$p3y, $p3x,$p3y, $p3x,$p3y,
21471 $p4c1x,$p4y, $p4x,$p4y, $p4x,$p4y,
21472 $p1x,$p1y);
21473 $patch_array[5]['colors'] = array($col1,$col2);
21474
21475 // TOP LEFT corner
21476 $p1x = $x00+$bl; // control points only matches p3 preceding
21477 $p1y = $y00+$d1+$brbgTL_V; $p1c2y = $p1y - ($d2+$brbgTL_V)*$mag;
21478 $p2x = $x00; // control point only matches p4 preceding
21479 $p2y = $y00+$d1+$brbgTL_V; $p2c2y = $p2y - ($d1+$brbgTL_V)*$mag;
21480 $p3x = $x00+$d1+$brbgTL_H; $p3c1x = $p3x - ($d1+$brbgTL_H)*$mag;
21481 $p3y = $y00; $p3c2y = $p3y + $bl/2;
21482 $p4x = $x00+$d1+$brbgTL_H; $p4c2x = $p4x - ($d2+$brbgTL_H)*$mag;
21483 $p4y = $y00+$bl;
21484
21485 if (-$d2 > min($brbgTL_H, $brbgTL_V) || $flatten) {
21486 $p1y = $y00+$bl; $p1c2y = $p1y;
21487 $p2y = $y00+$bl; $p2c2y = $p2y - $bl*$mag2;
21488 $p3x = $x00+$bl; $p3c1x = $p3x - $bl*$mag2;
21489 $p4x = $x00+$bl; $p4c2x = $p4x ;
21490 }
21491
21492 $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);
21493 $patch_array[6]['f']=2;
21494 $patch_array[6]['points']=array($p2x,$p2c2y,
21495 $p3c1x,$p3y, $p3x,$p3y, $p3x,$p3c2y,
21496 $p4x,$p4y, $p4x,$p4y, $p4c2x,$p4y,
21497 $p1x,$p1c2y);
21498 $patch_array[6]['colors'] = array($col2,$col1);
21499
21500
21501 // TOP - joins on the right (C3-C4 of previous): f = 2
21502 $p1x = $x00+$d1+$brbgTL_H; // control point only matches p3 preceding
21503 $p1y = $y00;
21504 $p2x = $x00+$d1+$brbgTL_H; // control point only matches p4 preceding
21505 $p2y = $y00+$bl;
21506 $p3x = $x00+$w00-$d1-$brbgTR_H;
21507 $p3y = $y00+$bl;
21508 $p4x = $x00+$w00-$d1-$brbgTR_H;
21509 $p4y = $y00; $p4c1y = $p4y + $bl/2;
21510 if (-$d2 > min($brbgTL_H, $brbgTL_V) || $flatten) {
21511 $p1x = $x00+$bl;
21512 $p2x = $x00+$bl;
21513 }
21514 if (-$d2 > min($brbgTR_H, $brbgTR_V) || $flatten) {
21515 $p3x = $x00+$w00-$bl;
21516 $p4x = $x00+$w00-$bl;
21517 }
21518
21519 $shadow .= sprintf('%.3F %.3F l ', ($p3x )*_MPDFK, ($this->h-($p3y ))*_MPDFK);
21520 $patch_array[7]['f']=2;
21521 $patch_array[7]['points']=array($p2x,$p2y,
21522 $p3x,$p3y, $p3x,$p3y, $p3x,$p3y,
21523 $p4x,$p4c1y, $p4x,$p4y, $p4x,$p4y,
21524 $p1x,$p1y);
21525 $patch_array[7]['colors'] = array($col1,$col2);
21526
21527 $shadow .= ' h f Q '."\n"; // Close path and Fill the inner solid shadow
21528
21529 if ($bl) $shadow .= $this->grad->CoonsPatchMesh($x00,$y00,$w00,$h00,$patch_array,$x00,$x00+$w00,$y00,$y00+$h00, $colspace, true);
21530
21531 if ($sh['x'] || $sh['y']) $shadow .= ' Q'."\n"; // Shadow Offset
21532 $shadow .= ' Q'."\n"; // Ends path no-op & Sets the clipping path
21533
21534 }
21535 }
21536
21537 $s .= ' W n '; // Ends path no-op & Sets the clipping path
21538
21539 if ($this->blk[$blvl]['bgcolor']) {
21540 $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
21541 }
21542 else if ($shadow) {
21543 $this->pageBackgrounds[$blvl][] = array('shadowonly'=>true, 'col'=>'', 'clippath'=>'', 'visibility'=>$this->visibility, 'shadow'=>$shadow, 'z-index'=>$this->current_layer); // mPDF 5.6.01
21544 }
21545
21546/*-- BACKGROUNDS --*/
21547 if (isset($this->blk[$blvl]['gradient'])) {
21548 $g = $this->grad->parseBackgroundGradient($this->blk[$blvl]['gradient']);
21549 if ($g) {
21550 $gx = $x0;
21551 $gy = $y0;
21552 $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
21553 }
21554 }
21555 if (isset($this->blk[$blvl]['background-image'])) {
21556 if ($this->blk[$blvl]['background-image']['gradient'] && preg_match('/(-moz-)*(repeating-)*(linear|radial)-gradient/', $this->blk[$blvl]['background-image']['gradient'] )) {
21557 $g = $this->grad->parseMozGradient( $this->blk[$blvl]['background-image']['gradient'] );
21558 if ($g) {
21559 $gx = $x0;
21560 $gy = $y0;
21561 // mPDF 5.6.11
21562 // origin specifies the background-positioning-area (bpa)
21563 if ($this->blk[$blvl]['background-image']['origin'] == 'padding-box') {
21564 $gx += $this->blk[$blvl]['border_left']['w'];
21565 $w -= ($this->blk[$blvl]['border_left']['w'] + $this->blk[$blvl]['border_right']['w']);
21566 if ($this->blk[$blvl]['border_top'] && $divider != 'pagetop' && !$continuingpage) {
21567 $gy += $this->blk[$blvl]['border_top']['w'];
21568 }
21569 if ($this->blk[$blvl]['border_bottom'] && $blockstate != 1 && $divider != 'pagebottom') {
21570 $gy1 = $y1 - $this->blk[$blvl]['border_bottom']['w'];
21571 }
21572 else { $gy1 = $y1; }
21573 $h = $gy1 - $gy;
21574 }
21575 else if ($this->blk[$blvl]['background-image']['origin'] == 'content-box') {
21576 $gx += $this->blk[$blvl]['border_left']['w'] + $this->blk[$blvl]['padding_left'];
21577 $w -= ($this->blk[$blvl]['border_left']['w'] + $this->blk[$blvl]['padding_left'] + $this->blk[$blvl]['border_right']['w'] + $this->blk[$blvl]['padding_right']);
21578 if ($this->blk[$blvl]['border_top'] && $divider != 'pagetop' && !$continuingpage) {
21579 $gy += $this->blk[$blvl]['border_top']['w'] + $this->blk[$blvl]['padding_top'];
21580 }
21581 if ($this->blk[$blvl]['border_bottom'] && $blockstate != 1 && $divider != 'pagebottom') {
21582 $gy1 = $y1 - ($this->blk[$blvl]['border_bottom']['w'] + $this->blk[$blvl]['padding_bottom']);
21583 }
21584 else { $gy1 = $y1 - $this->blk[$blvl]['padding_bottom']; }
21585 $h = $gy1 - $gy;
21586 }
21587
21588 if (isset($this->blk[$blvl]['background-image']['size']['w']) && $this->blk[$blvl]['background-image']['size']['w']) {
21589 $size = $this->blk[$blvl]['background-image']['size'];
21590 if ($size['w']!='contain' && $size['w']!='cover') {
21591 if (stristr($size['w'] ,'%')) {
21592 $size['w'] += 0;
21593 $size['w'] /= 100;
21594 $w *= $size['w'];
21595 }
21596 else if ($size['w']!='auto') {
21597 $w = $size['w'];
21598 }
21599 if (stristr($size['h'] ,'%')) {
21600 $size['h'] += 0;
21601 $size['h'] /= 100;
21602 $h *= $size['h'];
21603 }
21604 else if ($size['h']!='auto') {
21605 $h = $size['h'];
21606 }
21607 }
21608 }
21609 $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
21610 }
21611 }
21612 else {
21613 $image_id = $this->blk[$blvl]['background-image']['image_id'];
21614 $orig_w = $this->blk[$blvl]['background-image']['orig_w'];
21615 $orig_h = $this->blk[$blvl]['background-image']['orig_h'];
21616 $x_pos = $this->blk[$blvl]['background-image']['x_pos'];
21617 $y_pos = $this->blk[$blvl]['background-image']['y_pos'];
21618 $x_repeat = $this->blk[$blvl]['background-image']['x_repeat'];
21619 $y_repeat = $this->blk[$blvl]['background-image']['y_repeat'];
21620 $resize = $this->blk[$blvl]['background-image']['resize'];
21621 $opacity = $this->blk[$blvl]['background-image']['opacity'];
21622 $itype = $this->blk[$blvl]['background-image']['itype'];
21623 $size = $this->blk[$blvl]['background-image']['size']; // mPDF 5.6.10
21624 // mPDF 5.6.10
21625 // origin specifies the background-positioning-area (bpa)
21626 $bpa = array('x'=>$x0, 'y'=>$y0, 'w'=>$w, 'h'=>$h);
21627 if ($this->blk[$blvl]['background-image']['origin'] == 'padding-box') {
21628 $bpa['x'] = $x0 + $this->blk[$blvl]['border_left']['w'];
21629 $bpa['w'] = $w - ($this->blk[$blvl]['border_left']['w'] + $this->blk[$blvl]['border_right']['w']);
21630 if ($this->blk[$blvl]['border_top'] && $divider != 'pagetop' && !$continuingpage) {
21631 $bpa['y'] = $y0 + $this->blk[$blvl]['border_top']['w'];
21632 }
21633 else { $bpa['y'] = $y0; }
21634 if ($this->blk[$blvl]['border_bottom'] && $blockstate != 1 && $divider != 'pagebottom') {
21635 $bpay = $y1 - $this->blk[$blvl]['border_bottom']['w'];
21636 }
21637 else { $bpay = $y1; }
21638 $bpa['h'] = $bpay - $bpa['y'];
21639 }
21640 // mPDF 5.6.09
21641 else if ($this->blk[$blvl]['background-image']['origin'] == 'content-box') {
21642 $bpa['x'] = $x0 + $this->blk[$blvl]['border_left']['w'] + $this->blk[$blvl]['padding_left'];
21643 $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']);
21644 if ($this->blk[$blvl]['border_top'] && $divider != 'pagetop' && !$continuingpage) {
21645 $bpa['y'] = $y0 + $this->blk[$blvl]['border_top']['w'] + $this->blk[$blvl]['padding_top'];
21646 }
21647 else { $bpa['y'] = $y0 + $this->blk[$blvl]['padding_top']; }
21648 if ($this->blk[$blvl]['border_bottom'] && $blockstate != 1 && $divider != 'pagebottom') {
21649 $bpay = $y1 - ($this->blk[$blvl]['border_bottom']['w'] + $this->blk[$blvl]['padding_bottom']);
21650 }
21651 else { $bpay = $y1 - $this->blk[$blvl]['padding_bottom']; }
21652 $bpa['h'] = $bpay - $bpa['y'];
21653 }
21654 $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
21655 }
21656 }
21657/*-- END BACKGROUNDS --*/
21658
21659 // Float DIV
21660 $this->blk[$blvl]['bb_painted'][$this->page] = true;
21661
21662}
21663
21664/*-- BORDER-RADIUS --*/
21665
21666function _EllipseArc($x0, $y0, $rx, $ry, $seg = 1, $part=false, $start=false) { // Anticlockwise segment 1-4 TR-TL-BL-BR (part=1 or 2)
21667 $s = '';
21668 if ($rx<0) { $rx = 0; }
21669 if ($ry<0) { $ry = 0; }
21670 $rx *= _MPDFK;
21671 $ry *= _MPDFK;
21672 $astart = 0;
21673 if ($seg == 1) { // Top Right
21674 $afinish = 90;
21675 $nSeg = 4;
21676 }
21677 else if ($seg == 2) { // Top Left
21678 $afinish = 180;
21679 $nSeg = 8;
21680 }
21681 else if ($seg == 3) { // Bottom Left
21682 $afinish = 270;
21683 $nSeg = 12;
21684 }
21685 else { // Bottom Right
21686 $afinish = 360;
21687 $nSeg = 16;
21688 }
21689 $astart = deg2rad((float) $astart);
21690 $afinish = deg2rad((float) $afinish);
21691 $totalAngle = $afinish - $astart;
21692 $dt = $totalAngle / $nSeg; // segment angle
21693 $dtm = $dt/3;
21694 $x0 *= _MPDFK;
21695 $y0 = ($this->h - $y0) * _MPDFK;
21696 $t1 = $astart;
21697 $a0 = $x0 + ($rx * cos($t1));
21698 $b0 = $y0 + ($ry * sin($t1));
21699 $c0 = -$rx * sin($t1);
21700 $d0 = $ry * cos($t1);
21701 $op = false;
21702 for ($i = 1; $i <= $nSeg; $i++) {
21703 // Draw this bit of the total curve
21704 $t1 = ($i * $dt) + $astart;
21705 $a1 = $x0 + ($rx * cos($t1));
21706 $b1 = $y0 + ($ry * sin($t1));
21707 $c1 = -$rx * sin($t1);
21708 $d1 = $ry * cos($t1);
21709 if ($i>($nSeg-4) && (!$part || ($part == 1 && $i<=$nSeg-2) || ($part == 2 && $i>$nSeg-2))) {
21710 if ($start && !$op) {
21711 $s .= sprintf('%.3F %.3F m ', $a0, $b0);
21712 }
21713 $s .= sprintf('%.3F %.3F %.3F %.3F %.3F %.3F c ', ($a0 + ($c0 * $dtm)), ($b0 + ($d0 * $dtm)), ($a1 - ($c1 * $dtm)) , ($b1 - ($d1 * $dtm)), $a1 , $b1 );
21714 $op = true;
21715 }
21716 $a0 = $a1;
21717 $b0 = $b1;
21718 $c0 = $c1;
21719 $d0 = $d1;
21720 }
21721 return $s;
21722}
21723/*-- END BORDER-RADIUS --*/
21724
21725
21726
21727function PaintDivLnBorder($state=0,$blvl=0,$h) {
21728 // $state = 0 normal; 1 top; 2 bottom; 3 top and bottom
21729 $this->ColDetails[$this->CurrCol]['bottom_margin'] = $this->y + $h;
21730
21731 $save_y = $this->y;
21732
21733 $w = $this->blk[$blvl]['width'];
21734 $x0 = $this->x; // left
21735 $y0 = $this->y; // top
21736 $x1 = $this->x + $w; // bottom
21737 $y1 = $this->y + $h; // bottom
21738
21739 if ($this->blk[$blvl]['border_top'] && ($state==1 || $state==3)) {
21740 $tbd = $this->blk[$blvl]['border_top'];
21741 if (isset($tbd['s']) && $tbd['s']) {
21742 $this->_setBorderLine($tbd);
21743 $this->y = $y0 + ($tbd['w']/2);
21744 // mPDF 5.6.56
21745 if ($tbd['style']=='dotted' || $tbd['style']=='dashed') {
21746 $this->_setDashBorder($tbd['style'],'',$continuingpage,'T');
21747 $this->Line($x0 + ($tbd['w']/2) , $this->y , $x0 + $w - ($tbd['w']/2), $this->y);
21748 }
21749 else {
21750 $this->SetLineJoin(0);
21751 $this->SetLineCap(0);
21752 $this->Line($x0, $this->y , $x0 + $w, $this->y);
21753 }
21754 $this->y += $tbd['w'];
21755 // Reset Corners and Dash off
21756 $this->SetLineJoin(2);
21757 $this->SetLineCap(2);
21758 $this->SetDash();
21759 }
21760 }
21761 if ($this->blk[$blvl]['border_left']) {
21762 $tbd = $this->blk[$blvl]['border_left'];
21763 if (isset($tbd['s']) && $tbd['s']) {
21764 $this->_setBorderLine($tbd);
21765 // mPDF 5.6.56
21766 if ($tbd['style']=='dotted' || $tbd['style']=='dashed') {
21767 $this->y = $y0 + ($tbd['w']/2);
21768 $this->_setDashBorder($tbd['style'],'',$continuingpage,'L');
21769 $this->Line($x0 + ($tbd['w']/2), $this->y, $x0 + ($tbd['w']/2), $y0 + $h -($tbd['w']/2));
21770 }
21771 else {
21772 $this->y = $y0;
21773 $this->SetLineJoin(0);
21774 $this->SetLineCap(0);
21775 $this->Line($x0 + ($tbd['w']/2), $this->y, $x0 + ($tbd['w']/2), $y0 + $h);
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 if ($this->blk[$blvl]['border_right']) {
21785 $tbd = $this->blk[$blvl]['border_right'];
21786 if (isset($tbd['s']) && $tbd['s']) {
21787 $this->_setBorderLine($tbd);
21788 // mPDF 5.6.56
21789 if ($tbd['style']=='dotted' || $tbd['style']=='dashed') {
21790 $this->y = $y0 + ($tbd['w']/2);
21791 $this->_setDashBorder($tbd['style'],'',$continuingpage,'R');
21792 $this->Line($x0 + $w - ($tbd['w']/2), $this->y, $x0 + $w - ($tbd['w']/2), $y0 + $h - ($tbd['w']/2));
21793 }
21794 else {
21795 $this->y = $y0;
21796 $this->SetLineJoin(0);
21797 $this->SetLineCap(0);
21798 $this->Line($x0 + $w - ($tbd['w']/2), $this->y, $x0 + $w - ($tbd['w']/2), $y0 + $h);
21799 }
21800 $this->y += $tbd['w'];
21801 // Reset Corners and Dash off
21802 $this->SetLineJoin(2);
21803 $this->SetLineCap(2);
21804 $this->SetDash();
21805 }
21806 }
21807 if ($this->blk[$blvl]['border_bottom'] && $state > 1) {
21808 $tbd = $this->blk[$blvl]['border_bottom'];
21809 if (isset($tbd['s']) && $tbd['s']) {
21810 $this->_setBorderLine($tbd);
21811 $this->y = $y0 + $h - ($tbd['w']/2);
21812 // mPDF 5.6.56
21813 if ($tbd['style']=='dotted' || $tbd['style']=='dashed') {
21814 $this->_setDashBorder($tbd['style'],'',$continuingpage,'B');
21815 $this->Line($x0 + ($tbd['w']/2) , $this->y, $x0 + $w - ($tbd['w']/2), $this->y);
21816 }
21817 else {
21818 $this->SetLineJoin(0);
21819 $this->SetLineCap(0);
21820 $this->Line($x0, $this->y, $x0 + $w, $this->y);
21821 }
21822 $this->y += $tbd['w'];
21823 // Reset Corners and Dash off
21824 $this->SetLineJoin(2);
21825 $this->SetLineCap(2);
21826 $this->SetDash();
21827 }
21828 }
21829 $this->SetDash();
21830 $this->y = $save_y;
21831}
21832
21833
21834function PaintImgBorder($objattr,$is_table) {
21835 // Borders are disabled in columns - messes up the repositioning in printcolumnbuffer
21836 if ($this->ColActive) { return ; } // *COLUMNS*
21837 if ($is_table) { $k = $this->shrin_k; } else { $k = 1; }
21838 $h = (isset($objattr['BORDER-HEIGHT']) ? $objattr['BORDER-HEIGHT'] : 0);
21839 $w = (isset($objattr['BORDER-WIDTH']) ? $objattr['BORDER-WIDTH'] : 0);
21840 $x0 = (isset($objattr['BORDER-X']) ? $objattr['BORDER-X'] : 0);
21841 $y0 = (isset($objattr['BORDER-Y']) ? $objattr['BORDER-Y'] : 0);
21842
21843 // BORDERS
21844 if ($objattr['border_top']) {
21845 $tbd = $objattr['border_top'];
21846 if (!empty($tbd['s'])) {
21847 $this->_setBorderLine($tbd,$k);
21848 if ($tbd['style']=='dotted' || $tbd['style']=='dashed') { $this->_setDashBorder($tbd['style'],'','','T'); }
21849 $this->Line($x0, $y0, $x0 + $w, $y0);
21850 // Reset Corners and Dash off
21851 $this->SetLineJoin(2);
21852 $this->SetLineCap(2);
21853 $this->SetDash();
21854 }
21855 }
21856 if ($objattr['border_left']) {
21857 $tbd = $objattr['border_left'];
21858 if (!empty($tbd['s'])) {
21859 $this->_setBorderLine($tbd,$k);
21860 if ($tbd['style']=='dotted' || $tbd['style']=='dashed') { $this->_setDashBorder($tbd['style'],'','','L'); }
21861 $this->Line($x0, $y0, $x0, $y0 + $h);
21862 // Reset Corners and Dash off
21863 $this->SetLineJoin(2);
21864 $this->SetLineCap(2);
21865 $this->SetDash();
21866 }
21867 }
21868 if ($objattr['border_right']) {
21869 $tbd = $objattr['border_right'];
21870 if (!empty($tbd['s'])) {
21871 $this->_setBorderLine($tbd,$k);
21872 if ($tbd['style']=='dotted' || $tbd['style']=='dashed') { $this->_setDashBorder($tbd['style'],'','','R'); }
21873 $this->Line($x0 + $w, $y0, $x0 + $w, $y0 + $h);
21874 // Reset Corners and Dash off
21875 $this->SetLineJoin(2);
21876 $this->SetLineCap(2);
21877 $this->SetDash();
21878 }
21879 }
21880 if ($objattr['border_bottom']) {
21881 $tbd = $objattr['border_bottom'];
21882 if (!empty($tbd['s'])) {
21883 $this->_setBorderLine($tbd,$k);
21884 if ($tbd['style']=='dotted' || $tbd['style']=='dashed') { $this->_setDashBorder($tbd['style'],'','','B'); }
21885 $this->Line($x0, $y0 + $h, $x0 + $w, $y0 + $h);
21886 // Reset Corners and Dash off
21887 $this->SetLineJoin(2);
21888 $this->SetLineCap(2);
21889 $this->SetDash();
21890 }
21891 }
21892 $this->SetDash();
21893 $this->SetAlpha(1);
21894}
21895
21896/*-- END HTML-CSS --*/
21897
21898
21899
21900
21901function Reset() {
21902 $this->SetTColor($this->ConvertColor(0));
21903 $this->SetDColor($this->ConvertColor(0));
21904 $this->SetFColor($this->ConvertColor(255));
21905 $this->SetAlpha(1);
21906 $this->colorarray = '';
21907
21908 $this->spanbgcolorarray = '';
21909 $this->spanbgcolor = false;
21910 $this->spanborder = false;
21911 $this->spanborddet = array();
21912
21913 $this->ResetStyles();
21914
21915 $this->HREF = '';
21916 $this->textparam = array();
21917 $this->SetTextOutline();
21918
21919 $this->SUP = false;
21920 $this->SUB = false;
21921 $this->strike = false;
21922 $this->textshadow = '';
21923
21924 $this->SetFont($this->default_font,'',0,false);
21925 $this->SetFontSize($this->default_font_size,false);
21926
21927 $this->currentfontfamily = '';
21928 $this->currentfontsize = '';
21929
21930/*-- TABLES --*/
21931 if ($this->tableLevel) {
21932 $this->SetLineHeight('',$this->table_lineheight); // *TABLES*
21933 }
21934 else
21935/*-- END TABLES --*/
21936/*-- LISTS --*/
21937
21938 if ($this->listlvl && $this->list_lineheight[$this->listlvl][$this->bulletarray['occur']]) {
21939 $this->SetLineHeight('',$this->list_lineheight[$this->listlvl][$this->bulletarray['occur']]); // sets default line height
21940 }
21941 else
21942/*-- END LISTS --*/
21943 if (isset($this->blk[$this->blklvl]['line_height']) && $this->blk[$this->blklvl]['line_height']) {
21944 $this->SetLineHeight('',$this->blk[$this->blklvl]['line_height']); // sets default line height
21945 }
21946
21947 $this->toupper = false;
21948 $this->tolower = false;
21949 $this->kerning = false;
21950 $this->lSpacingCSS = '';
21951 $this->wSpacingCSS = '';
21952 $this->fixedlSpacing = false;
21953 $this->minwSpacing = 0;
21954 $this->capitalize = false;
21955 $this->SetDash(); //restore to no dash
21956 $this->dash_on = false;
21957 $this->dotted_on = false;
21958 $this->divwidth = 0;
21959 $this->divheight = 0;
21960 $this->divalign = '';
21961 $this->divrevert = false;
21962 $this->oldy = -1;
21963
21964 $bodystyle = array();
21965 if (isset($this->cssmgr->CSS['BODY']['FONT-STYLE'])) { $bodystyle['FONT-STYLE'] = $this->cssmgr->CSS['BODY']['FONT-STYLE']; }
21966 if (isset($this->cssmgr->CSS['BODY']['FONT-WEIGHT'])) { $bodystyle['FONT-WEIGHT'] = $this->cssmgr->CSS['BODY']['FONT-WEIGHT']; }
21967 if (isset($this->cssmgr->CSS['BODY']['COLOR'])) { $bodystyle['COLOR'] = $this->cssmgr->CSS['BODY']['COLOR']; }
21968 if (isset($bodystyle)) { $this->setCSS($bodystyle,'BLOCK','BODY'); }
21969
21970}
21971
21972/*-- HTML-CSS --*/
21973function ReadMetaTags($html) {
21974 // changes anykey=anyvalue to anykey="anyvalue" (only do this when this happens inside tags)
21975 $regexp = '/ (\\w+?)=([^\\s>"]+)/si';
21976 $html = preg_replace($regexp," \$1=\"\$2\"",$html);
21977 if (preg_match('/<title>(.*?)<\/title>/si',$html,$m)) {
21978 $this->SetTitle($m[1]);
21979 }
21980 preg_match_all('/<meta [^>]*?(name|content)="([^>]*?)" [^>]*?(name|content)="([^>]*?)".*?>/si',$html,$aux);
21981 $firstattr = $aux[1];
21982 $secondattr = $aux[3];
21983 for( $i = 0 ; $i < count($aux[0]) ; $i++) {
21984
21985 $name = ( strtoupper($firstattr[$i]) == "NAME" )? strtoupper($aux[2][$i]) : strtoupper($aux[4][$i]);
21986 $content = ( strtoupper($firstattr[$i]) == "CONTENT" )? $aux[2][$i] : $aux[4][$i];
21987 switch($name) {
21988 case "KEYWORDS": $this->SetKeywords($content); break;
21989 case "AUTHOR": $this->SetAuthor($content); break;
21990 case "DESCRIPTION": $this->SetSubject($content); break;
21991 }
21992 }
21993}
21994
21995
21996function ReadCharset($html) {
21997 // Charset conversion
21998 if ($this->allow_charset_conversion) {
21999 if (preg_match('/<head.*charset=([^\'\"\s]*).*<\/head>/si',$html,$m)) {
22000 if (strtoupper($m[1]) != 'UTF-8') {
22001 $this->charset_in = strtoupper($m[1]);
22002 }
22003 }
22004 }
22005}
22006
22007function setCSS($arrayaux,$type='',$tag='') { // type= INLINE | BLOCK | LIST // tag= BODY
22008 if (!is_array($arrayaux)) return; //Removes PHP Warning
22009 // Set font size first so that e.g. MARGIN 0.83em works on font size for this element
22010 if (isset($arrayaux['FONT-SIZE'])) {
22011 $v = $arrayaux['FONT-SIZE'];
22012 if(is_numeric($v[0])) {
22013 if ($type == 'BLOCK' && $this->blklvl>0 && isset($this->blk[$this->blklvl-1]['InlineProperties']) && isset($this->blk[$this->blklvl-1]['InlineProperties']['size'])) {
22014 $mmsize = $this->ConvertSize($v,$this->blk[$this->blklvl-1]['InlineProperties']['size']);
22015 }
22016 else {
22017 $mmsize = $this->ConvertSize($v,$this->FontSize);
22018 }
22019 $this->SetFontSize( $mmsize*(_MPDFK),false ); //Get size in points (pt)
22020 }
22021 else{
22022 $v = strtoupper($v);
22023 if (isset($this->fontsizes[$v])) {
22024 $this->SetFontSize( $this->fontsizes[$v]* $this->default_font_size,false);
22025 }
22026 }
22027 if ($tag == 'BODY') { $this->SetDefaultFontSize($this->FontSizePt); }
22028 }
22029
22030
22031 if ($this->useLang && !$this->usingCoreFont) {
22032 if (isset($arrayaux['LANG']) && $arrayaux['LANG'] && $arrayaux['LANG'] != $this->default_lang && ((strlen($arrayaux['LANG']) == 5 && $arrayaux['LANG'] != 'UTF-8') || strlen($arrayaux['LANG']) == 2)) {
22033 list ($coreSuitable,$mpdf_pdf_unifonts) = GetLangOpts($arrayaux['LANG'], $this->useAdobeCJK);
22034 if ($mpdf_pdf_unifonts) { $this->RestrictUnicodeFonts($mpdf_pdf_unifonts); }
22035 else { $this->RestrictUnicodeFonts($this->default_available_fonts ); }
22036 if ($tag == 'BODY') {
22037 $this->currentLang = $arrayaux['LANG'];
22038 $this->default_lang = $arrayaux['LANG'];
22039 if ($mpdf_pdf_unifonts) { $this->default_available_fonts = $mpdf_pdf_unifonts; }
22040 }
22041 }
22042 else {
22043 $this->RestrictUnicodeFonts($this->default_available_fonts );
22044 }
22045 }
22046
22047 // FOR INLINE and BLOCK OR 'BODY'
22048 if (isset($arrayaux['FONT-FAMILY'])) {
22049 $v = $arrayaux['FONT-FAMILY'];
22050 //If it is a font list, get all font types
22051 $aux_fontlist = explode(",",$v);
22052 $found = 0;
22053 foreach($aux_fontlist AS $f) {
22054 $fonttype = trim($f);
22055 $fonttype = preg_replace('/["\']*(.*?)["\']*/','\\1',$fonttype);
22056 $fonttype = preg_replace('/ /','',$fonttype);
22057 $v = strtolower(trim($fonttype));
22058 if (isset($this->fonttrans[$v]) && $this->fonttrans[$v]) { $v = $this->fonttrans[$v]; }
22059 if ((!$this->onlyCoreFonts && in_array($v,$this->available_unifonts)) ||
22060 in_array($v,array('ccourier','ctimes','chelvetica')) ||
22061 ($this->onlyCoreFonts && in_array($v,array('courier','times','helvetica','arial'))) ||
22062 in_array($v, array('sjis','uhc','big5','gb'))) {
22063 $fonttype = $v;
22064 $found = 1;
22065 break;
22066 }
22067 }
22068 if (!$found) {
22069 foreach($aux_fontlist AS $f) {
22070 $fonttype = trim($f);
22071 $fonttype = preg_replace('/["\']*(.*?)["\']*/','\\1',$fonttype);
22072 $fonttype = preg_replace('/ /','',$fonttype);
22073 $v = strtolower(trim($fonttype));
22074 if (isset($this->fonttrans[$v]) && $this->fonttrans[$v]) { $v = $this->fonttrans[$v]; }
22075 if (in_array($v,$this->sans_fonts) || in_array($v,$this->serif_fonts) || in_array($v,$this->mono_fonts) ) {
22076 $fonttype = $v;
22077 break;
22078 }
22079 }
22080 }
22081
22082 if ($tag == 'BODY') {
22083 $this->SetDefaultFont($fonttype);
22084 }
22085 $this->SetFont($fonttype,$this->currentfontstyle,0,false);
22086 }
22087 else {
22088 $this->SetFont($this->currentfontfamily,$this->currentfontstyle,0,false);
22089 }
22090
22091 foreach($arrayaux as $k => $v) {
22092 if ($type != 'INLINE' && $tag != 'BODY' && $type != 'LIST') {
22093 switch($k){
22094 // BORDERS
22095 case 'BORDER-TOP':
22096 $this->blk[$this->blklvl]['border_top'] = $this->border_details($v);
22097 if ($this->blk[$this->blklvl]['border_top']['s']) { $this->blk[$this->blklvl]['border'] = 1; }
22098 break;
22099 case 'BORDER-BOTTOM':
22100 $this->blk[$this->blklvl]['border_bottom'] = $this->border_details($v);
22101 if ($this->blk[$this->blklvl]['border_bottom']['s']) { $this->blk[$this->blklvl]['border'] = 1; }
22102 break;
22103 case 'BORDER-LEFT':
22104 $this->blk[$this->blklvl]['border_left'] = $this->border_details($v);
22105 if ($this->blk[$this->blklvl]['border_left']['s']) { $this->blk[$this->blklvl]['border'] = 1; }
22106 break;
22107 case 'BORDER-RIGHT':
22108 $this->blk[$this->blklvl]['border_right'] = $this->border_details($v);
22109 if ($this->blk[$this->blklvl]['border_right']['s']) { $this->blk[$this->blklvl]['border'] = 1; }
22110 break;
22111
22112 // PADDING
22113 case 'PADDING-TOP':
22114 $this->blk[$this->blklvl]['padding_top'] = $this->ConvertSize($v,$this->blk[$this->blklvl-1]['inner_width'],$this->FontSize,false);
22115 break;
22116 case 'PADDING-BOTTOM':
22117 $this->blk[$this->blklvl]['padding_bottom'] = $this->ConvertSize($v,$this->blk[$this->blklvl-1]['inner_width'],$this->FontSize,false);
22118 break;
22119 case 'PADDING-LEFT':
22120 $this->blk[$this->blklvl]['padding_left'] = $this->ConvertSize($v,$this->blk[$this->blklvl-1]['inner_width'],$this->FontSize,false);
22121 break;
22122 case 'PADDING-RIGHT':
22123 $this->blk[$this->blklvl]['padding_right'] = $this->ConvertSize($v,$this->blk[$this->blklvl-1]['inner_width'],$this->FontSize,false);
22124 break;
22125
22126 // MARGINS
22127 case 'MARGIN-TOP':
22128 $tmp = $this->ConvertSize($v,$this->blk[$this->blklvl-1]['inner_width'],$this->FontSize,false);
22129 if (isset($this->blk[$this->blklvl]['lastbottommargin'])) {
22130 if ($tmp > $this->blk[$this->blklvl]['lastbottommargin']) {
22131 $tmp -= $this->blk[$this->blklvl]['lastbottommargin'];
22132 }
22133 else {
22134 $tmp = 0;
22135 }
22136 }
22137 $this->blk[$this->blklvl]['margin_top'] = $tmp;
22138 break;
22139 case 'MARGIN-BOTTOM':
22140 $this->blk[$this->blklvl]['margin_bottom'] = $this->ConvertSize($v,$this->blk[$this->blklvl-1]['inner_width'],$this->FontSize,false);
22141 break;
22142 case 'MARGIN-LEFT':
22143 $this->blk[$this->blklvl]['margin_left'] = $this->ConvertSize($v,$this->blk[$this->blklvl-1]['inner_width'],$this->FontSize,false);
22144 break;
22145 case 'MARGIN-RIGHT':
22146 $this->blk[$this->blklvl]['margin_right'] = $this->ConvertSize($v,$this->blk[$this->blklvl-1]['inner_width'],$this->FontSize,false);
22147 break;
22148
22149/*-- BORDER-RADIUS --*/
22150 case 'BORDER-TOP-LEFT-RADIUS-H':
22151 $this->blk[$this->blklvl]['border_radius_TL_H'] = $this->ConvertSize($v,$this->blk[$this->blklvl-1]['inner_width'],$this->FontSize,false);
22152 break;
22153 case 'BORDER-TOP-LEFT-RADIUS-V':
22154 $this->blk[$this->blklvl]['border_radius_TL_V'] = $this->ConvertSize($v,$this->blk[$this->blklvl-1]['inner_width'],$this->FontSize,false);
22155 break;
22156 case 'BORDER-TOP-RIGHT-RADIUS-H':
22157 $this->blk[$this->blklvl]['border_radius_TR_H'] = $this->ConvertSize($v,$this->blk[$this->blklvl-1]['inner_width'],$this->FontSize,false);
22158 break;
22159 case 'BORDER-TOP-RIGHT-RADIUS-V':
22160 $this->blk[$this->blklvl]['border_radius_TR_V'] = $this->ConvertSize($v,$this->blk[$this->blklvl-1]['inner_width'],$this->FontSize,false);
22161 break;
22162 case 'BORDER-BOTTOM-LEFT-RADIUS-H':
22163 $this->blk[$this->blklvl]['border_radius_BL_H'] = $this->ConvertSize($v,$this->blk[$this->blklvl-1]['inner_width'],$this->FontSize,false);
22164 break;
22165 case 'BORDER-BOTTOM-LEFT-RADIUS-V':
22166 $this->blk[$this->blklvl]['border_radius_BL_V'] = $this->ConvertSize($v,$this->blk[$this->blklvl-1]['inner_width'],$this->FontSize,false);
22167 break;
22168 case 'BORDER-BOTTOM-RIGHT-RADIUS-H':
22169 $this->blk[$this->blklvl]['border_radius_BR_H'] = $this->ConvertSize($v,$this->blk[$this->blklvl-1]['inner_width'],$this->FontSize,false);
22170 break;
22171 case 'BORDER-BOTTOM-RIGHT-RADIUS-V':
22172 $this->blk[$this->blklvl]['border_radius_BR_V'] = $this->ConvertSize($v,$this->blk[$this->blklvl-1]['inner_width'],$this->FontSize,false);
22173 break;
22174/*-- END BORDER-RADIUS --*/
22175
22176 case 'BOX-SHADOW':
22177 $bs = $this->cssmgr->setCSSboxshadow($v);
22178 if ($bs) { $this->blk[$this->blklvl]['box_shadow'] = $bs; }
22179 break;
22180
22181 case 'BACKGROUND-CLIP':
22182 if (strtoupper($v) == 'PADDING-BOX') { $this->blk[$this->blklvl]['background_clip'] = 'padding-box'; }
22183 else if (strtoupper($v) == 'CONTENT-BOX') { $this->blk[$this->blklvl]['background_clip'] = 'content-box'; } // mPDF 5.6.09
22184 break;
22185
22186 case 'PAGE-BREAK-AFTER':
22187 if (strtoupper($v) == 'AVOID') { $this->blk[$this->blklvl]['page_break_after_avoid'] = true; }
22188 else if (strtoupper($v) == 'ALWAYS' || strtoupper($v) == 'LEFT' || strtoupper($v) == 'RIGHT') { $this->blk[$this->blklvl]['page_break_after'] = strtoupper($v) ; }
22189 break;
22190
22191 case 'WIDTH':
22192 if (strtoupper($v) != 'AUTO') {
22193 $this->blk[$this->blklvl]['css_set_width'] = $this->ConvertSize($v,$this->blk[$this->blklvl-1]['inner_width'],$this->FontSize,false);
22194 }
22195 break;
22196
22197 case 'TEXT-INDENT':
22198 // Left as raw value (may include 1% or 2em)
22199 $this->blk[$this->blklvl]['text_indent'] = $v;
22200 break;
22201
22202 }//end of switch($k)
22203 }
22204
22205
22206 if ($type != 'INLINE' && $type != 'LIST') { // includes BODY tag
22207 switch($k){
22208
22209 case 'MARGIN-COLLAPSE': // Custom tag to collapse margins at top and bottom of page
22210 if (strtoupper($v) == 'COLLAPSE') { $this->blk[$this->blklvl]['margin_collapse'] = true; }
22211 break;
22212
22213 case 'LINE-HEIGHT':
22214 $this->blk[$this->blklvl]['line_height'] = $this->fixLineheight($v);
22215 if (!$this->blk[$this->blklvl]['line_height'] ) { $this->blk[$this->blklvl]['line_height'] = $this->normalLineheight; }
22216 break;
22217
22218 case 'TEXT-ALIGN': //left right center justify
22219 switch (strtoupper($v)) {
22220 case 'LEFT':
22221 $this->blk[$this->blklvl]['align']="L";
22222 break;
22223 case 'CENTER':
22224 $this->blk[$this->blklvl]['align']="C";
22225 break;
22226 case 'RIGHT':
22227 $this->blk[$this->blklvl]['align']="R";
22228 break;
22229 case 'JUSTIFY':
22230 $this->blk[$this->blklvl]['align']="J";
22231 break;
22232 }
22233 break;
22234
22235/*-- BACKGROUNDS --*/
22236 case 'BACKGROUND-GRADIENT':
22237 if ($type == 'BLOCK') {
22238 $this->blk[$this->blklvl]['gradient'] = $v;
22239 }
22240 break;
22241/*-- END BACKGROUNDS --*/
22242
22243 case 'DIRECTION':
22244 if ($v) { $this->blk[$this->blklvl]['direction'] = strtolower($v); }
22245 break;
22246
22247 }//end of switch($k)
22248 }
22249
22250 // FOR INLINE ONLY
22251 if ($type == 'INLINE' || $type == 'LIST') {
22252 switch($k){
22253 case 'DISPLAY': // Custom tag to collapse margins at top and bottom of page
22254 if (strtoupper($v) == 'NONE') { $this->inlineDisplayOff = true; }
22255 break;
22256 case 'DIRECTION':
22257 break;
22258 }//end of switch($k)
22259 }
22260 // FOR INLINE ONLY
22261 if ($type == 'INLINE') {
22262 switch($k){
22263 // BORDERS
22264 case 'BORDER-TOP':
22265 $this->spanborddet['T'] = $this->border_details($v);
22266 $this->spanborder = true;
22267 break;
22268 case 'BORDER-BOTTOM':
22269 $this->spanborddet['B'] = $this->border_details($v);
22270 $this->spanborder = true;
22271 break;
22272 case 'BORDER-LEFT':
22273 $this->spanborddet['L'] = $this->border_details($v);
22274 $this->spanborder = true;
22275 break;
22276 case 'BORDER-RIGHT':
22277 $this->spanborddet['R'] = $this->border_details($v);
22278 $this->spanborder = true;
22279 break;
22280 // mPDF 5.6.26
22281 case 'VISIBILITY': // block is set in OpenTag
22282 $v = strtolower($v);
22283 if ($v == 'visible' || $v == 'hidden' || $v == 'printonly' || $v == 'screenonly') {
22284 $this->textparam['visibility'] = $v;
22285 }
22286 break;
22287 }//end of switch($k)
22288 }
22289
22290
22291 // FOR INLINE and BLOCK
22292 switch($k){
22293 case 'TEXT-ALIGN': //left right center justify
22294 if (strtoupper($v) == 'NOJUSTIFY' && $this->blk[$this->blklvl]['align']=="J") {
22295 $this->blk[$this->blklvl]['align']="";
22296 }
22297 break;
22298 // bgcolor only - to stay consistent with original html2fpdf
22299 case 'BACKGROUND':
22300 case 'BACKGROUND-COLOR':
22301 $cor = $this->ConvertColor($v);
22302 if ($cor) {
22303 if ($tag == 'BODY') {
22304 $this->bodyBackgroundColor = $cor;
22305 }
22306 else if ($type == 'INLINE' || $type == 'LIST') {
22307 $this->spanbgcolorarray = $cor;
22308 $this->spanbgcolor = true;
22309 }
22310 else {
22311 $this->blk[$this->blklvl]['bgcolorarray'] = $cor;
22312 $this->blk[$this->blklvl]['bgcolor'] = true;
22313 }
22314 }
22315 else if ($type != 'INLINE' && $type != 'LIST') {
22316 if ($this->ColActive || $this->keep_block_together) {
22317 $this->blk[$this->blklvl]['bgcolorarray'] = $this->blk[$this->blklvl-1]['bgcolorarray'] ;
22318 $this->blk[$this->blklvl]['bgcolor'] = $this->blk[$this->blklvl-1]['bgcolor'] ;
22319 }
22320 }
22321 break;
22322
22323 // auto | normal | none
22324 case 'FONT-KERNING':
22325 if ((strtoupper($v) == 'NORMAL' || strtoupper($v) == 'AUTO') && $this->useKerning) { $this->kerning = true; }
22326 else if (strtoupper($v) == 'NONE') { $this->kerning = false; }
22327 break;
22328
22329
22330 // normal | <length>
22331 case 'LETTER-SPACING':
22332 $this->lSpacingCSS = $v;
22333 if (($this->lSpacingCSS || $this->lSpacingCSS==='0') && strtoupper($this->lSpacingCSS) != 'NORMAL') {
22334 $this->fixedlSpacing = $this->ConvertSize($this->lSpacingCSS,$this->FontSize);
22335 }
22336 break;
22337
22338 // normal | <length>
22339 case 'WORD-SPACING':
22340 $this->wSpacingCSS = $v;
22341 if ($this->wSpacingCSS && strtoupper($this->wSpacingCSS) != 'NORMAL') {
22342 $this->minwSpacing = $this->ConvertSize($this->wSpacingCSS,$this->FontSize);
22343 }
22344 break;
22345
22346 case 'FONT-STYLE': // italic normal oblique
22347 switch (strtoupper($v)) {
22348 case 'ITALIC':
22349 case 'OBLIQUE':
22350 $this->SetStyle('I',true);
22351 break;
22352 case 'NORMAL':
22353 $this->SetStyle('I',false);
22354 break;
22355 }
22356 break;
22357
22358 case 'FONT-WEIGHT': // normal bold //Does not support: bolder, lighter, 100..900(step value=100)
22359 switch (strtoupper($v)) {
22360 case 'BOLD':
22361 $this->SetStyle('B',true);
22362 break;
22363 case 'NORMAL':
22364 $this->SetStyle('B',false);
22365 break;
22366 }
22367 break;
22368
22369 case 'VERTICAL-ALIGN': //super and sub only dealt with here e.g. <SUB> and <SUP>
22370 switch (strtoupper($v)) {
22371 case 'SUPER':
22372 $this->SUP=true;
22373 $this->SUB=false; // mPDF 5.6.07
22374 break;
22375 case 'SUB':
22376 $this->SUB=true;
22377 $this->SUP=false; // mPDF 5.6.07
22378 break;
22379 case 'BASELINE': // mPDF 5.6.07
22380 $this->SUB=false;
22381 $this->SUP=false;
22382 break;
22383 }
22384 break;
22385
22386 case 'TEXT-DECORATION': // none underline line-through (strikeout) //Does not support: overline, blink
22387 if (stristr($v,'LINE-THROUGH')) {
22388 $this->strike = true;
22389 }
22390 else if (stristr($v,'UNDERLINE')) {
22391 $this->SetStyle('U',true);
22392 }
22393 else if (stristr($v,'NONE')) {
22394 $this->SetStyle('U',false);
22395 $this->strike = false; // mPDF 5.6.07
22396 }
22397 break;
22398
22399 case 'FONT-VARIANT':
22400 switch (strtoupper($v)) {
22401 case 'SMALL-CAPS':
22402 $this->SetStyle('S',true);
22403 break;
22404 case 'NORMAL':
22405 $this->SetStyle('S',false);
22406 break;
22407 }
22408 break;
22409
22410 case 'TEXT-TRANSFORM': // none uppercase lowercase //Does support: capitalize
22411 switch (strtoupper($v)) { //Not working 100%
22412 case 'CAPITALIZE':
22413 $this->capitalize=true;
22414 break;
22415 case 'UPPERCASE':
22416 $this->toupper=true;
22417 break;
22418 case 'LOWERCASE':
22419 $this->tolower=true;
22420 break;
22421 case 'NONE': break;
22422 }
22423 break;
22424
22425 case 'TEXT-SHADOW':
22426 $ts = $this->cssmgr->setCSStextshadow($v);
22427 if ($ts) { $this->textshadow = $ts; }
22428 break;
22429
22430 case 'HYPHENS': // mPDF 5.6.08
22431 if (strtoupper($v)=='NONE') {
22432 $this->textparam['hyphens'] = 2;
22433 }
22434 else if (strtoupper($v)=='AUTO') {
22435 $this->textparam['hyphens'] = 1;
22436 }
22437 else if (strtoupper($v)=='MANUAL') {
22438 $this->textparam['hyphens'] = 0;
22439 }
22440 break;
22441
22442 case 'TEXT-OUTLINE': // mPDF 5.6.07
22443 if (strtoupper($v)=='NONE') {
22444 $this->textparam['outline-s'] = false;
22445 }
22446 break;
22447
22448 case 'TEXT-OUTLINE-WIDTH': // mPDF 5.6.07
22449 case 'OUTLINE-WIDTH':
22450 switch(strtoupper($v)) {
22451 case 'THIN': $v = '0.03em'; break;
22452 case 'MEDIUM': $v = '0.05em'; break;
22453 case 'THICK': $v = '0.07em'; break;
22454 }
22455 $w = $this->ConvertSize($v,$this->blk[$this->blklvl]['inner_width'],$this->FontSize);
22456 if ($w) {
22457 $this->textparam['outline-WIDTH'] = $w;
22458 $this->textparam['outline-s'] = true;
22459 }
22460 else { $this->textparam['outline-s'] = false; }
22461 break;
22462
22463 case 'TEXT-OUTLINE-COLOR': // mPDF 5.6.07
22464 case 'OUTLINE-COLOR':
22465 if (strtoupper($v) == 'INVERT') {
22466 if ($this->colorarray) {
22467 $cor = $this->colorarray;
22468 $this->textparam['outline-COLOR'] = $this->_invertColor($cor);
22469 }
22470 else {
22471 $this->textparam['outline-COLOR'] = $this->ConvertColor(255);
22472 }
22473 }
22474 else {
22475 $cor = $this->ConvertColor($v);
22476 if ($cor) { $this->textparam['outline-COLOR'] = $cor ; }
22477 }
22478 break;
22479
22480 case 'COLOR': // font color
22481 $cor = $this->ConvertColor($v);
22482 if ($cor) {
22483 $this->colorarray = $cor;
22484 $this->SetTColor($cor);
22485 }
22486 break;
22487
22488
22489 }//end of switch($k)
22490
22491
22492 }//end of foreach
22493}
22494
22495/*-- END HTML-CSS --*/
22496
22497
22498function SetStyle($tag,$enable) {
22499 $this->$tag=$enable;
22500 $style='';
22501 foreach(array('B','I','U','S') as $s) {
22502 if($this->$s) {
22503 $style.=$s;
22504 }
22505 }
22506 if ($this->S && empty($this->upperCase)) { @include(_MPDF_PATH.'includes/upperCase.php'); }
22507 $this->currentfontstyle=$style;
22508 $this->SetFont('',$style,0,false);
22509}
22510
22511// Set multiple styles at one $str e.g. "BIS"
22512function SetStylesArray($arr) {
22513 $style='';
22514 foreach(array('B','I','U','S') as $s) {
22515 if (isset($arr[$s])) {
22516 if ($arr[$s]) {
22517 $this->$s = true;
22518 $style.=$s;
22519 }
22520 else { $this->$s = false; }
22521 }
22522 else if ($this->$s) { $style.=$s; }
22523 }
22524 $this->currentfontstyle=$style;
22525 $this->SetFont('',$style,0,false);
22526}
22527
22528// Set multiple styles at one $str e.g. "BIS"
22529function SetStyles($str) {
22530 $style='';
22531 foreach(array('B','I','U','S') as $s) {
22532 if (strpos($str,$s) !== false) {
22533 $this->$s = true;
22534 $style.=$s;
22535 }
22536 else { $this->$s = false; }
22537 }
22538 $this->currentfontstyle=$style;
22539 $this->SetFont('',$style,0,false);
22540}
22541
22542function ResetStyles() {
22543 foreach(array('B','I','U','S') as $s) {
22544 $this->$s = false;
22545 }
22546 $this->currentfontstyle='';
22547 $this->SetFont('','',0,false);
22548}
22549
22550
22551function DisableTags($str='')
22552{
22553 if ($str == '') //enable all tags
22554 {
22555 //Insert new supported tags in the long string below.
22556 $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
22557 }
22558 else
22559 {
22560 $str = explode(",",$str);
22561 foreach($str as $v) $this->enabledtags = str_replace(trim($v),'',$this->enabledtags);
22562 }
22563}
22564
22565
22566/*-- TABLES --*/
22567
22568function finaliseCellLineHeight($lhxt, $maxfontsize, $maxlineHeight, $lhfixed, $forceExactLineheight) {
22569 $af = 0; // Above font
22570 $bf = 0; // Below font
22571 $mta = 0; // Maximum top-aligned
22572 $mba = 0; // Maximum bottom-aligned
22573 if ($lhxt['BS']) {
22574 $af = max($af, ($lhxt['BS'] - ($maxfontsize * (0.5 + $this->baselineC))));
22575 }
22576 if ($lhxt['M']) {
22577 $af = max($af, ($lhxt['M'] - $maxfontsize)/2);
22578 $bf = max($bf, ($lhxt['M'] - $maxfontsize)/2);
22579 }
22580 if ($lhxt['TT']) {
22581 $bf = max($bf, ($lhxt['TT'] - $maxfontsize));
22582 }
22583 if ($lhxt['TB']) {
22584 $af = max($af, ($lhxt['TB'] - $maxfontsize));
22585 }
22586 if ($lhxt['T']) {
22587 $mta = max($mta, $lhxt['T']);
22588 }
22589 if ($lhxt['B']) {
22590 $mba = max($mba, $lhxt['B']);
22591 }
22592 if ((!$lhfixed || !$forceExactLineheight) && ($af > (($maxlineHeight - $maxfontsize)/2) || $bf > (($maxlineHeight - $maxfontsize)/2))) {
22593 $maxlineHeight = $maxfontsize + $af + $bf;
22594 }
22595 else if (!$lhfixed) { $af = $bf = ($maxlineHeight - $maxfontsize)/2; }
22596 if ($mta > $maxlineHeight) {
22597 $bf += ($mta - $maxlineHeight);
22598 $maxlineHeight = $mta;
22599 }
22600 if ($mba > $maxlineHeight) {
22601 $af += ($mba - $maxlineHeight);
22602 $maxlineHeight = $mba;
22603 }
22604 return $maxlineHeight;
22605}
22606
22607function TableWordWrap($maxwidth, $forcewrap = 0, $textbuffer = '', $def_fontsize, $returnarray=false) { // NB ** returnarray used in flowchart
22608 $biggestword=0;
22609 $toonarrow=false;
22610
22611 $textbuffer[0][0] = preg_replace('/^[ ]*/','',$textbuffer[0][0]);
22612 if ((count($textbuffer) == 0) or ((count($textbuffer) == 1) && ($textbuffer[0][0] == ''))) { return 0; }
22613
22614 $text = '';
22615 $lhfixed = false;
22616 if (preg_match('/([0-9.,]+)mm/',$this->table_lineheight)) { $lhfixed = true; }
22617 if ($lhfixed) { $def_lineheight = $this->_computeLineheight($this->table_lineheight, $def_fontsize);}
22618 else { $def_lineheight = 0; }
22619 // START OF NEW LINE
22620 // Initialise lineheight variables
22621 $maxfontsize = 0;
22622 $forceExactLineheight = true;
22623 $lhxt = array('BS'=>0, 'M'=>0, 'TT'=>0, 'TB'=>0, 'T'=>0, 'B'=>0);
22624 $maxlineHeight = $def_lineheight ;
22625 $ch = 0;
22626 $width = 0;
22627 $ln = 1; // Counts line number
22628 $mxw = $this->GetCharWidth('W',false);
22629 for($cctr=0;$cctr<count($textbuffer);$cctr++) { // mPDF 5.6.22
22630 $chunk = $textbuffer[$cctr]; // mPDF 5.6.22
22631 $line = $chunk[0];
22632 //IMAGE
22633 if (substr($line,0,3) == "\xbb\xa4\xac") { //identifier has been identified!
22634 $objattr = $this->_getObjAttr($line);
22635 if ($objattr['type'] == 'nestedtable') {
22636 // END OF LINE
22637 // Finalise & add lineheight
22638 $ch += $this->finaliseCellLineHeight($lhxt, $maxfontsize, $maxlineHeight, $lhfixed, $forceExactLineheight);
22639 $level = $objattr['level'];
22640 $ih = $this->table[($level+1)][$objattr['nestedcontent']]['h']; // nested table width
22641 $ch += $ih;
22642 // START OF NEW LINE
22643 // Initialise lineheight variables
22644 $ln++;
22645 $maxfontsize = 0;
22646 $forceExactLineheight = true;
22647 $lhxt = array('BS'=>0, 'M'=>0, 'TT'=>0, 'TB'=>0, 'T'=>0, 'B'=>0);
22648 $maxlineHeight = $def_lineheight ;
22649 $width = 0;
22650 $text = "";
22651 continue;
22652 }
22653
22654 list($skipln,$iw,$ih) = $this->inlineObject((isset($specialcontent['type']) ? $specialcontent['type'] : null),0,0, $objattr, $this->lMargin,$width,$maxwidth,$maxlineHeight,false,true);
22655 if ($objattr['type'] == 'hr') {
22656 // END OF LINE
22657 // Finalise & add lineheight
22658 $ch += $this->finaliseCellLineHeight($lhxt, $maxfontsize, $maxlineHeight, $lhfixed, $forceExactLineheight);
22659 // Add HR height
22660 $ch += $ih;
22661 // START OF NEW LINE
22662 // Initialise lineheight variables
22663 $ln++;
22664 $maxfontsize = 0;
22665 $forceExactLineheight = true;
22666 $lhxt = array('BS'=>0, 'M'=>0, 'TT'=>0, 'TB'=>0, 'T'=>0, 'B'=>0);
22667 $maxlineHeight = $def_lineheight ;
22668 $width = 0;
22669 $text = "";
22670 continue;
22671 }
22672
22673 if ($skipln==1 || $skipln==-2) {
22674 // Finish last line
22675 // END OF LINE
22676 // Finalise & add lineheight
22677 $ch += $this->finaliseCellLineHeight($lhxt, $maxfontsize, $maxlineHeight, $lhfixed, $forceExactLineheight);
22678 // START OF NEW LINE
22679 // Initialise lineheight variables
22680 $maxfontsize = 0;
22681 $forceExactLineheight = true;
22682 $lhxt = array('BS'=>0, 'M'=>0, 'TT'=>0, 'TB'=>0, 'T'=>0, 'B'=>0);
22683 $maxlineHeight = $def_lineheight ;
22684 $ln++;
22685 $width = 0;
22686 $text = "";
22687 }
22688 $va = (isset($objattr['vertical-align']) ? $objattr['vertical-align'] : null);
22689 if ($va) {
22690 $lhxt[$va] = max($lhxt[$va], $ih);
22691 }
22692 if ($lhfixed && $ih > $def_fontsize) { $forceExactLineheight = false; }
22693 $maxlineHeight = max($maxlineHeight ,$ih);
22694 $width += $iw;
22695 continue;
22696 }
22697
22698 // SET FONT SIZE/STYLE from $chunk[n]
22699 // FONTSIZE
22700 if(isset($chunk[11]) and $chunk[11] != '') {
22701 if ($this->shrin_k) {
22702 $this->SetFontSize($chunk[11]/$this->shrin_k,false);
22703 }
22704 else {
22705 $this->SetFontSize($chunk[11],false);
22706 }
22707 }
22708 if ($line == "\n") {
22709 // END OF LINE
22710 $maxfontsize = max($maxfontsize,$this->FontSize);
22711 $fh = $this->_computeLineheight($this->table_lineheight);
22712 if ($lhfixed && $this->FontSize > $def_fontsize) {
22713 $fh = $this->FontSize;
22714 $forceExactLineheight = false;
22715 }
22716 $maxlineHeight = max($maxlineHeight,$fh);
22717
22718 // Finalise & add lineheight
22719 $ch += $this->finaliseCellLineHeight($lhxt, $maxfontsize, $maxlineHeight, $lhfixed, $forceExactLineheight);
22720 // START OF NEW LINE
22721 // Initialise lineheight variables
22722 $maxfontsize = 0;
22723 $forceExactLineheight = true;
22724 $lhxt = array('BS'=>0, 'M'=>0, 'TT'=>0, 'TB'=>0, 'T'=>0, 'B'=>0);
22725 $maxlineHeight = $this->_computeLineheight($this->table_lineheight);
22726 $ln++;
22727 $text = "";
22728 $width = 0;
22729 if(isset($chunk[11]) and $chunk[11] != '') {
22730 $this->SetFontSize($this->default_font_size,false);
22731 }
22732 continue;
22733 }
22734
22735 $lbw = $rbw = 0; // Border widths
22736 if(isset($chunk[16]) && !empty($chunk[16])) { //Border
22737 $this->spanborddet = $chunk[16];
22738 if (isset($this->spanborddet['L'])) $lbw = $this->spanborddet['L']['w'];
22739 if (isset($this->spanborddet['R'])) $rbw = $this->spanborddet['R']['w'];
22740 }
22741 if(isset($chunk[15])) { // Word spacing
22742 $this->wSpacingCSS = $chunk[15];
22743 if ($this->wSpacingCSS && strtoupper($this->wSpacingCSS) != 'NORMAL') {
22744 $this->minwSpacing = $this->ConvertSize($this->wSpacingCSS,$this->FontSize);
22745 }
22746 }
22747 if(isset($chunk[14])) { // Letter spacing
22748 $this->lSpacingCSS = $chunk[14];
22749 if (($this->lSpacingCSS || $this->lSpacingCSS==='0') && strtoupper($this->lSpacingCSS) != 'NORMAL') {
22750 $this->fixedlSpacing = $this->ConvertSize($this->lSpacingCSS,$this->FontSize);
22751 }
22752 }
22753 if(isset($chunk[13])) { // Font Kerning
22754 $this->kerning = $chunk[13];
22755 }
22756 if(isset($chunk[9])) { // Text params - Outline, hyphens // mPDF 5.6.08
22757 $this->textparam = $chunk[9];
22758 }
22759 // FONTFAMILY
22760 if(isset($chunk[4]) and $chunk[4] != '') { $font = $this->SetFont($chunk[4],$this->FontStyle,0,false); }
22761
22762 // FONT STYLE B I U
22763 if(isset($chunk[2]) and $chunk[2] != '') {
22764 $this->SetStyles($chunk[2]);
22765 }
22766
22767 $space = $this->GetCharWidth(' ',false);
22768
22769 if (mb_substr($line,0,1,$this->mb_enc ) == ' ') { // line (chunk) starts with a space
22770 $width += $space;
22771 $text .= ' ';
22772 }
22773
22774 if (mb_substr($line,(mb_strlen($line,$this->mb_enc )-1),1,$this->mb_enc ) == ' ') { $lsend = true; } // line (chunk) ends with a space
22775 else { $lsend = false; }
22776 $line= trim($line);
22777 if ($line == '') { continue; }
22778
22779 // mPDF ITERATION
22780 if ($this->iterationCounter) $line = preg_replace('/{iteration ([a-zA-Z0-9_]+)}/','\\1', $line);
22781
22782 $words = explode(' ', $line);
22783
22784 foreach ($words as $k=>$word) {
22785 $word = trim($word);
22786 $wordwidth = $this->GetStringWidth($word);
22787 if ($k==0) { $wordwidth += $lbw; }
22788 if ($k==(count($words)-1)) { $wordwidth += $rbw; }
22789 //maxwidth is insufficient for one word
22790 if ($wordwidth > $maxwidth + 0.0001) {
22791 $firstchunk=true;
22792 while($wordwidth > $maxwidth + 0.0001) {
22793 $chw = 0; // check width
22794 $oneCJKorphan = false;
22795 $mlen = mb_strlen($word, $this->mb_enc );
22796 for ( $i = 0; $i < $mlen; $i++ ) {
22797 $chw = $this->GetStringWidth(mb_substr($word,0,$i+1,$this->mb_enc ));
22798 if ($k==0) { $chw += $lbw; }
22799 if ($k==(count($words)-1)) { $chw += $rbw; }
22800 if ($chw > $maxwidth) {
22801 if ($i==0 && $firstchunk) {
22802 // If first letter of line does not fit
22803 $wordwidth = $maxwidth - 0.0001;
22804 if ($this->debug) { $this->Error("Table cell width calculated less than that needed for one character!"); }
22805 break;
22806 }
22807/*-- CJK-FONTS --*/
22808 // mPDF 5.6.40 mPDF 5.6.44
22809 if ($this->checkCJK && !$this->usingCoreFont && preg_match("/[".$this->pregCJKchars."]/u", $word)) { // mPDF 5.6.44
22810 if (!$oneCJKorphan && preg_match('/['.$this->CJKoverflow.']$/u',mb_substr($word,0,$i+1,$this->mb_enc )) && $this->allowCJKorphans) {
22811 $wordwidth = $maxwidth - 0.0001;
22812 $oneCJKorphan = true;
22813 continue;
22814 }
22815 $cjkfix = 0;
22816 // Last character that fits is not allowed to end a line - move lastchar(s) to start of next line
22817 if ($i>0 && preg_match("/[".$this->CJKleading."$]/u", mb_substr($word,0,$i,$this->mb_enc ))) {
22818 $cjkfix = 1;
22819 }
22820 // Next character is not allowed to start a new line
22821 else if (preg_match("/[".$this->CJKfollowing."]/u", mb_substr($word,$i,1,$this->mb_enc ))) {
22822 // try squeezing another character(s) onto this line = Oikomi
22823 if ($this->allowCJKorphans && !$oneCJKorphan) {
22824 //if lookahead is not another following char
22825 if ($i==($mlen-1) || ($i<($mlen-1) && !preg_match("/[".$this->CJKfollowing."]/u", mb_substr($word,$i+1,1,$this->mb_enc )))) {
22826 $wordwidth = $maxwidth - 0.0001;
22827 $oneCJKorphan = true;
22828 continue;
22829 }
22830 }
22831 // or move lastchar(s) to next line
22832 $cjkfix = 2;
22833 }
22834 // mPDF 5.6.42
22835 // CJK numerals kept together
22836 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 ))) {
22837 $cjkfix = 3;
22838 }
22839 if ($cjkfix) {
22840 //move lastchar(s) to next line
22841 $m0 = mb_substr($word,$i-1,1,$this->mb_enc ); // chars to move
22842 $m1 = mb_substr($word,0,$i-1,$this->mb_enc ); // str after stripped chars to move
22843 $mi = $i - 1;
22844 if ($cjkfix == 3) { $match = "0-9\x{ff10}-\x{ff19}"; }
22845 else { $match = $this->CJKleading; }
22846 while(preg_match("/[".$match."$]/u", $m1) && mb_strlen($m1, $this->mb_enc)>2) {
22847 $m0 = mb_substr($m1,$mi-1,1,$this->mb_enc ).$m0; // chars to move
22848 $m1 = mb_substr($m1,0,$mi-1,$this->mb_enc ); // str after stripped chars to move
22849 $mi--;
22850 }
22851 // Insert $m0 into $word at $i
22852 $word = mb_substr($word,0,$i,$this->mb_enc ) . $m0 . mb_substr($word,$i,mb_strlen($word, $this->mb_enc )-$i,$this->mb_enc );
22853 $mlen = mb_strlen($word, $this->mb_enc ); // increment max for loop counter
22854 }
22855
22856
22857
22858 }
22859/*-- END CJK-FONTS --*/
22860
22861 if ($text && $firstchunk) {
22862 // END OF LINE
22863 // Finalise & add lineheight
22864 $maxfontsize = max($maxfontsize,$this->FontSize);
22865 $fh = $this->_computeLineheight($this->table_lineheight);
22866 if ($lhfixed && $this->FontSize > $def_fontsize) {
22867 $fh = $this->FontSize;
22868 $forceExactLineheight = false;
22869 }
22870 $maxlineHeight = max($maxlineHeight,$fh);
22871 $ch += $this->finaliseCellLineHeight($lhxt, $maxfontsize, $maxlineHeight, $lhfixed, $forceExactLineheight);
22872 // START OF NEW LINE
22873 // Initialise lineheight variables
22874 $maxfontsize = $this->FontSize;
22875 $forceExactLineheight = true;
22876 $lhxt = array('BS'=>0, 'M'=>0, 'TT'=>0, 'TB'=>0, 'T'=>0, 'B'=>0);
22877 $maxlineHeight = $this->_computeLineheight($this->table_lineheight);
22878 $ln++;
22879 }
22880 // END OF LINE
22881 // Finalise & add lineheight
22882 $maxfontsize = max($maxfontsize,$this->FontSize);
22883 $fh = $this->_computeLineheight($this->table_lineheight);
22884 if ($lhfixed && $this->FontSize > $def_fontsize) {
22885 $fh = $this->FontSize;
22886 $forceExactLineheight = false;
22887 }
22888 $maxlineHeight = max($maxlineHeight,$fh);
22889 $ch += $this->finaliseCellLineHeight($lhxt, $maxfontsize, $maxlineHeight, $lhfixed, $forceExactLineheight);
22890 // START OF NEW LINE
22891 // Initialise lineheight variables
22892 $maxfontsize = $this->FontSize;
22893 $forceExactLineheight = true;
22894 $lhxt = array('BS'=>0, 'M'=>0, 'TT'=>0, 'TB'=>0, 'T'=>0, 'B'=>0);
22895 $maxlineHeight = $this->_computeLineheight($this->table_lineheight);
22896 $ln++;
22897 $mxw = $maxwidth;
22898 $text = mb_substr($word,0,$i,$this->mb_enc );
22899 $word = mb_substr($word,$i,mb_strlen($word, $this->mb_enc )-$i,$this->mb_enc );
22900 $wordwidth = $this->GetStringWidth($word);
22901 $width = 0;
22902 $firstchunk=false;
22903 break;
22904 }
22905 }
22906 if (mb_strlen($word, $this->mb_enc )<2 && $wordwidth > $maxwidth + 0.0001) {
22907 $wordwidth = $maxwidth - 0.0001;
22908 if ($this->debug) { $this->Error("Table cell width calculated less than that needed for single character!"); }
22909 }
22910 $firstchunk=false;
22911 }
22912 }
22913 // Word fits on line...
22914 if ($width + $wordwidth < $maxwidth + 0.0001) {
22915 $mxw = max($mxw, ($width+$wordwidth));
22916 $width += $wordwidth + $space;
22917 $text .= $word.' ';
22918 }
22919 // Word does not fit on line...
22920 else {
22921 // mPDF 5.6.21 hard hyphens
22922 if ($this->textparam['hyphens'] != 2 && preg_match('/\-/',$word)) {
22923 list($hardsuccess,$pre,$post,$prelength) = $this->hardHyphenate($word, ($maxwidth - $width)-$this->GetCharWidth("-", false));
22924 if ($hardsuccess) {
22925 $text .= $pre.'-';
22926 $word = $post;
22927 $wordwidth = $this->GetStringWidth($word);
22928 if ($k==(count($words)-1)) { $wordwidth += $rbw; }
22929 }
22930 }
22931/*-- HYPHENATION --*/
22932 // Soft Hyphens chr(173)
22933 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
22934 list($success,$pre,$post,$prelength) = $this->softHyphenate($word, ($maxwidth - $width));
22935 if ($success) {
22936 $text .= $pre.'-';
22937 $word = $post;
22938 $wordwidth = $this->GetStringWidth($word);
22939 if ($k==(count($words)-1)) { $wordwidth += $rbw; }
22940 }
22941 }
22942 else if ($this->textparam['hyphens'] == 1) { // mPDF 5.6.06 5.6.08
22943 list($success,$pre,$post,$prelength) = $this->hyphenateWord($word, ($maxwidth - $width));
22944 if ($success) {
22945 $text .= $pre.'-';
22946 $word = $post;
22947 $wordwidth = $this->GetStringWidth($word);
22948 if ($k==(count($words)-1)) { $wordwidth += $rbw; }
22949 }
22950 }
22951/*-- END HYPHENATION --*/
22952
22953
22954 // mPDF 5.6.22
22955 if ( count($textbuffer)>1 && $cctr > 0 && $k==0
22956 && (substr($textbuffer[$cctr][0],0,3) != "\xbb\xa4\xac")
22957 && (substr($textbuffer[$cctr-1][0],0,3) != "\xbb\xa4\xac")
22958 && substr($textbuffer[$cctr-1][0],-1,1) != ' '
22959 && substr($textbuffer[$cctr][0],0,1) != ' '
22960 ) {
22961 // Go back to find a space in a previous chunk of content
22962 $found = false;
22963 for ($ix=$cctr-1;$ix>=0;$ix--) {
22964 if (preg_match('/[ ]/',$textbuffer[$ix][0])) { $found = $ix; break; }
22965 }
22966 if ($found !== false) {
22967 $charpos = strrpos($textbuffer[$found][0],' ');
22968 // mPDF 5.6.24
22969 $a1 = $a2 = $textbuffer[$found];
22970 $a1[0] = "\n";
22971 $a2[0] = substr($textbuffer[$found][0], $charpos+1, strlen($textbuffer[$found][0])-$charpos);
22972 $textbuffer[$found][0] = substr($textbuffer[$found][0], 0, $charpos);
22973 array_insert($textbuffer, $a1, $found+1);
22974 array_insert($textbuffer, $a2, $found+2);
22975 // Initialise all variables
22976 $biggestword=0;
22977 $toonarrow=false;
22978 $lhfixed = false;
22979 if (preg_match('/([0-9.,]+)mm/',$this->table_lineheight)) { $lhfixed = true; }
22980 if ($lhfixed) { $def_lineheight = $this->_computeLineheight($this->table_lineheight, $def_fontsize);}
22981 else { $def_lineheight = 0; }
22982 $maxfontsize = 0;
22983 $forceExactLineheight = true;
22984 $lhxt = array('BS'=>0, 'M'=>0, 'TT'=>0, 'TB'=>0, 'T'=>0, 'B'=>0);
22985 $maxlineHeight = $def_lineheight ;
22986 $ch = 0;
22987 $width = 0;
22988 $ln = 1; // Counts line number
22989 $mxw = $this->GetCharWidth('W',false);
22990 $text = '';
22991
22992 $cctr = -1;
22993 break;
22994 }
22995 }
22996
22997 // END OF LINE
22998 // Finalise & add lineheight
22999 $maxfontsize = max($maxfontsize,$this->FontSize);
23000 $fh = $this->_computeLineheight($this->table_lineheight);
23001 if ($lhfixed && $this->FontSize > $def_fontsize) {
23002 $fh = $this->FontSize;
23003 $forceExactLineheight = false;
23004 }
23005 $maxlineHeight = max($maxlineHeight,$fh);
23006 $ch += $this->finaliseCellLineHeight($lhxt, $maxfontsize, $maxlineHeight, $lhfixed, $forceExactLineheight);
23007 $mxw = $maxwidth;
23008 // START OF NEW LINE
23009 // Initialise lineheight variables
23010 $maxfontsize = $this->FontSize;
23011 $forceExactLineheight = true;
23012 $lhxt = array('BS'=>0, 'M'=>0, 'TT'=>0, 'TB'=>0, 'T'=>0, 'B'=>0);
23013 $maxlineHeight = $this->_computeLineheight($this->table_lineheight);
23014 $ln++;
23015 $width = $wordwidth + $space;
23016 $text = $word.' ';
23017 }
23018 $maxfontsize = max($maxfontsize,$this->FontSize);
23019 $fh = $this->_computeLineheight($this->table_lineheight);
23020 if ($lhfixed && $this->FontSize > $def_fontsize) {
23021 $fh = $this->FontSize;
23022 $forceExactLineheight = false;
23023 }
23024 $maxlineHeight = max($maxlineHeight,$fh);
23025 }
23026
23027 // End of textbuffer chunk
23028 if (!$lsend) {
23029 $width -= $space;
23030 $text = rtrim($text);
23031 }
23032
23033 // RESET FONT SIZE/STYLE
23034 // RESETTING VALUES
23035 //Now we must deactivate what we have used
23036 if(isset($chunk[2]) and $chunk[2] != '') {
23037 $this->ResetStyles();
23038 }
23039 if(isset($chunk[4]) and $chunk[4] != '') {
23040 $this->SetFont($this->default_font,$this->FontStyle,0,false);
23041 }
23042 if(isset($chunk[11]) and $chunk[11] != '') {
23043 $this->SetFontSize($this->default_font_size,false);
23044 }
23045 $this->spanborddet = array();
23046 $this->kerning = false;
23047 $this->lSpacingCSS = '';
23048 $this->wSpacingCSS = '';
23049 $this->fixedlSpacing = false;
23050 $this->minwSpacing = 0;
23051 }
23052 // Finalise lineheight if something output on line and add
23053 if ($width) {
23054 $ch += $this->finaliseCellLineHeight($lhxt, $maxfontsize, $maxlineHeight, $lhfixed, $forceExactLineheight);
23055 }
23056 if ($returnarray) { return array($ch,$ln,$mxw); }
23057 else { return $ch; }
23058
23059}
23060
23061
23062function TableCheckMinWidth($maxwidth, $forcewrap = 0, $textbuffer) {
23063 $biggestword=0;
23064 $toonarrow=false;
23065 if ((count($textbuffer) == 0) or ((count($textbuffer) == 1) && ($textbuffer[0][0] == ''))) { return 0; }
23066
23067 foreach ($textbuffer as $chunk) {
23068
23069 $line = $chunk[0];
23070 // mPDF ITERATION
23071 if ($this->iterationCounter) $line = preg_replace('/{iteration ([a-zA-Z0-9_]+)}/','\\1', $line);
23072
23073 // IMAGES & FORM ELEMENTS
23074 if (substr($line,0,3) == "\xbb\xa4\xac") { //inline object - FORM element or IMAGE!
23075 $objattr = $this->_getObjAttr($line);
23076 if ($objattr['type']!='hr' && isset($objattr['width']) && ($objattr['width']/$this->shrin_k) > ($maxwidth + 0.0001) ) {
23077 if (($objattr['width']/$this->shrin_k) > $biggestword) { $biggestword = ($objattr['width']/$this->shrin_k); }
23078 $toonarrow=true;
23079 }
23080 continue;
23081 }
23082
23083 if ($line == "\n") {
23084 continue;
23085 }
23086 $line = trim($line );
23087 // SET FONT SIZE/STYLE from $chunk[n]
23088
23089 // FONTSIZE
23090 if(isset($chunk[11]) and $chunk[11] != '') {
23091 if ($this->shrin_k) {
23092 $this->SetFontSize($chunk[11]/$this->shrin_k,false);
23093 }
23094 else {
23095 $this->SetFontSize($chunk[11],false);
23096 }
23097 }
23098 // FONTFAMILY
23099 if(isset($chunk[4]) and $chunk[4] != '') { $font = $this->SetFont($chunk[4],$this->FontStyle,0,false); }
23100 // B I U
23101 if(isset($chunk[2]) and $chunk[2] != '') {
23102 $this->SetStyles($chunk[2]);
23103 }
23104
23105 $lbw = $rbw = 0; // Border widths
23106 if(isset($chunk[16]) && !empty($chunk[16])) { //Border
23107 $this->spanborddet = $chunk[16];
23108 $lbw = $this->spanborddet['L']['w'];
23109 $rbw = $this->spanborddet['R']['w'];
23110 }
23111 if(isset($chunk[15])) { // Word spacing
23112 $this->wSpacingCSS = $chunk[15];
23113 if ($this->wSpacingCSS && strtoupper($this->wSpacingCSS) != 'NORMAL') {
23114 $this->minwSpacing = $this->ConvertSize($this->wSpacingCSS,$this->FontSize);
23115 }
23116 }
23117 if(isset($chunk[14])) { // Letter spacing
23118 $this->lSpacingCSS = $chunk[14];
23119 if (($this->lSpacingCSS || $this->lSpacingCSS==='0') && strtoupper($this->lSpacingCSS) != 'NORMAL') {
23120 $this->fixedlSpacing = $this->ConvertSize($this->lSpacingCSS,$this->FontSize);
23121 }
23122 }
23123 if(isset($chunk[13])) { // Font Kerning
23124 $this->kerning = $chunk[13];
23125 }
23126
23127 $words = explode(' ', $line);
23128 foreach ($words as $k=>$word) {
23129 $word = trim($word);
23130 $wordwidth = $this->GetStringWidth($word);
23131 if ($k==0) { $wordwidth += $lbw; }
23132 if ($k==(count($words)-1)) { $wordwidth += $rbw; }
23133
23134 //Warn user that maxwidth is insufficient
23135 if ($wordwidth > $maxwidth + 0.0001) {
23136 if ($wordwidth > $biggestword) { $biggestword = $wordwidth; }
23137 $toonarrow=true;
23138 }
23139 }
23140
23141 // RESET FONT SIZE/STYLE
23142 // RESETTING VALUES
23143 //Now we must deactivate what we have used
23144 if(isset($chunk[2]) and $chunk[2] != '') {
23145 $this->ResetStyles();
23146 }
23147 if(isset($chunk[4]) and $chunk[4] != '') {
23148 $this->SetFont($this->default_font,$this->FontStyle,0,false);
23149 }
23150 if(isset($chunk[11]) and $chunk[11] != '') {
23151 $this->SetFontSize($this->default_font_size,false);
23152 }
23153 $this->spanborddet = array();
23154 $this->kerning = false;
23155 $this->lSpacingCSS = '';
23156 $this->wSpacingCSS = '';
23157 $this->fixedlSpacing = false;
23158 $this->minwSpacing = 0;
23159 }
23160
23161 //Return -(wordsize) if word is bigger than maxwidth
23162 // ADDED
23163 if (($toonarrow) && ($this->table_error_report)) {
23164 $this->Error("Word is too long to fit in table - ".$this->table_error_report_param);
23165 }
23166 if ($toonarrow) return -$biggestword;
23167 else return 1;
23168}
23169
23170function shrinkTable(&$table,$k) {
23171 $table['border_spacing_H'] /= $k;
23172 $table['border_spacing_V'] /= $k;
23173
23174 $table['padding']['T'] /= $k;
23175 $table['padding']['R'] /= $k;
23176 $table['padding']['B'] /= $k;
23177 $table['padding']['L'] /= $k;
23178
23179 $table['margin']['T'] /= $k;
23180 $table['margin']['R'] /= $k;
23181 $table['margin']['B'] /= $k;
23182 $table['margin']['L'] /= $k;
23183
23184 $table['border_details']['T']['w'] /= $k;
23185 $table['border_details']['R']['w'] /= $k;
23186 $table['border_details']['B']['w'] /= $k;
23187 $table['border_details']['L']['w'] /= $k;
23188
23189 if (isset($table['max_cell_border_width']['T'])) $table['max_cell_border_width']['T'] /= $k;
23190 if (isset($table['max_cell_border_width']['R'])) $table['max_cell_border_width']['R'] /= $k;
23191 if (isset($table['max_cell_border_width']['B'])) $table['max_cell_border_width']['B'] /= $k;
23192 if (isset($table['max_cell_border_width']['L'])) $table['max_cell_border_width']['L'] /= $k;
23193
23194 if ($this->simpleTables){
23195 $table['simple']['border_details']['T']['w'] /= $k;
23196 $table['simple']['border_details']['R']['w'] /= $k;
23197 $table['simple']['border_details']['B']['w'] /= $k;
23198 $table['simple']['border_details']['L']['w'] /= $k;
23199 }
23200
23201 $table['miw'] /= $k;
23202 $table['maw'] /= $k;
23203
23204 if ($this->cacheTables) { $fh = fopen($table['cache'], "r+b"); }
23205
23206 for($j = 0 ; $j < $table['nc'] ; $j++ ) { //columns
23207
23208 $table['wc'][$j]['miw'] /= $k;
23209 $table['wc'][$j]['maw'] /= $k;
23210
23211 // mPDF 5.6.13
23212 if (isset($table['decimal_align'][$j]['maxs0']) && $table['decimal_align'][$j]['maxs0']) { $table['decimal_align'][$j]['maxs0'] /= $k; }
23213 if (isset($table['decimal_align'][$j]['maxs1']) && $table['decimal_align'][$j]['maxs1']) { $table['decimal_align'][$j]['maxs1'] /= $k; }
23214
23215 if (isset($table['wc'][$j]['absmiw']) && $table['wc'][$j]['absmiw'] ) $table['wc'][$j]['absmiw'] /= $k;
23216
23217 for($i = 0 ; $i < $table['nr']; $i++ ) { //rows
23218 if ($this->cacheTables) {
23219 $c = $this->_uncacheCell($table['cells'][$i][$j], '', $fh);
23220 }
23221 else
23222 $c = &$table['cells'][$i][$j];
23223 if (isset($c) && $c) {
23224 if (!$this->simpleTables){
23225 if ($this->packTableData) {
23226 $cell = $this->_unpackCellBorder($c['borderbin'] );
23227 $cell['border_details']['T']['w'] /= $k;
23228 $cell['border_details']['R']['w'] /= $k;
23229 $cell['border_details']['B']['w'] /= $k;
23230 $cell['border_details']['L']['w'] /= $k;
23231 $cell['border_details']['mbw']['TL'] /= $k;
23232 $cell['border_details']['mbw']['TR'] /= $k;
23233 $cell['border_details']['mbw']['BL'] /= $k;
23234 $cell['border_details']['mbw']['BR'] /= $k;
23235 $cell['border_details']['mbw']['LT'] /= $k;
23236 $cell['border_details']['mbw']['LB'] /= $k;
23237 $cell['border_details']['mbw']['RT'] /= $k;
23238 $cell['border_details']['mbw']['RB'] /= $k;
23239 $c['borderbin'] = $this->_packCellBorder($cell);
23240 }
23241 else {
23242 $c['border_details']['T']['w'] /= $k;
23243 $c['border_details']['R']['w'] /= $k;
23244 $c['border_details']['B']['w'] /= $k;
23245 $c['border_details']['L']['w'] /= $k;
23246 $c['border_details']['mbw']['TL'] /= $k;
23247 $c['border_details']['mbw']['TR'] /= $k;
23248 $c['border_details']['mbw']['BL'] /= $k;
23249 $c['border_details']['mbw']['BR'] /= $k;
23250 $c['border_details']['mbw']['LT'] /= $k;
23251 $c['border_details']['mbw']['LB'] /= $k;
23252 $c['border_details']['mbw']['RT'] /= $k;
23253 $c['border_details']['mbw']['RB'] /= $k;
23254 }
23255 }
23256 $c['padding']['T'] /= $k;
23257 $c['padding']['R'] /= $k;
23258 $c['padding']['B'] /= $k;
23259 $c['padding']['L'] /= $k;
23260 $c['maxs'] /= $k;
23261 if (isset($c['w'])) { $c['w'] /= $k; }
23262 $c['s'] /= $k;
23263 $c['maw'] /= $k;
23264 $c['miw'] /= $k;
23265 if (isset($c['absmiw'])) $c['absmiw'] /= $k;
23266 if (isset($c['nestedmaw'])) $c['nestedmaw'] /= $k;
23267 if (isset($c['nestedmiw'])) $c['nestedmiw'] /= $k;
23268 if (isset($c['textbuffer'])) {
23269 foreach($c['textbuffer'] AS $n=>$tb) {
23270 if (!empty($tb[16])) {
23271 $c['textbuffer'][$n][16]['T']['w'] /= $k;
23272 $c['textbuffer'][$n][16]['B']['w'] /= $k;
23273 $c['textbuffer'][$n][16]['L']['w'] /= $k;
23274 $c['textbuffer'][$n][16]['R']['w'] /= $k;
23275 }
23276 }
23277 }
23278 if ($this->cacheTables) {
23279 $this->_cacheCell($c, '', "W", $fh, $table['cells'][$i][$j]);
23280 }
23281 unset($c);
23282 }
23283 }//rows
23284 }//columns
23285 if ($this->cacheTables) { fclose($fh); }
23286}
23287
23288function _cacheCell($c, $file, $mode="A", $fh=null, $offset=0) { // mode = Append or (over)Write (needs offset and fh)
23289 // Requires either $file OR $fh (file_handle)
23290 if (!is_array($c) || !isset($c)) { return ''; }
23291
23292 if(isset($c['w'])) { $cw = $c['w']; } else { $cw = -1; }
23293 if(isset($c['w0'])) { $cw0 = $c['w0']; } else { $cw0 = -1; }
23294 if(isset($c['h0'])) { $ch0 = $c['h0']; } else { $ch0 = -1; }
23295
23296 $data = pack("n2d19A1A1n2sA32A128",
23297 $c['colspan'], /* n (16 bit; 2 bytes) [pos 0] */
23298 $c['rowspan'], /* n (16 bit; 2 bytes) [pos 2] */
23299 $c['s'], /* d NB machine-dependent size (64 bit; 8 bytes on test winOS) [pos 4] */
23300 $c['maxs'], /* d NB machine-dependent size [pos 4 + 1*D] */
23301 $c['nestedmaw'], /* d NB machine-dependent size [pos 4 + 2*D] */
23302 $c['nestedmiw'], /* d NB machine-dependent size [pos 4 + 3*D] */
23303 $c['padding']['L'], /* d NB machine-dependent size [pos 4 + 4*D] */
23304 $c['padding']['R'], /* d NB machine-dependent size [pos 4 + 5*D] */
23305 $c['padding']['T'], /* d NB machine-dependent size [pos 4 + 6*D] */
23306 $c['padding']['B'], /* d NB machine-dependent size [pos 4 + 7*D] */
23307 $c['dfs'], /* d NB machine-dependent size [pos 4 + 8*D] */
23308 $cw, /* d NB machine-dependent size [pos 4 + 9*D] */
23309 $c['h'], /* d NB machine-dependent size [pos 4 + 10*D] */
23310 $c['absmiw'], /* d NB machine-dependent size [pos 4 + 11*D] */
23311 $c['maw'], /* d NB machine-dependent size [pos 4 + 12*D] */
23312 $c['miw'], /* d NB machine-dependent size [pos 4 + 13*D] */
23313 $c['mih'], /* d NB machine-dependent size [pos 4 + 14*D] */
23314 $c['x0'], /* d NB machine-dependent size [pos 4 + 15*D] */
23315 $cw0, /* d NB machine-dependent size [pos 4 + 16*D] */
23316 $c['y0'], /* d NB machine-dependent size [pos 4 + 17*D] */
23317 $ch0, /* d NB machine-dependent size [pos 4 + 18*D] */
23318 $c['a'], /* A1 (1 byte) [pos 4 + 19*D] */
23319 $c['va'], /* A1 (1 byte) [pos 5 + 19*D] */
23320 $c['nowrap'], /* 1 or blank n (16 bit; 2 bytes) [pos 6 + 19*D] */
23321 $c['wpercent'], /* 0 - 100 n (16 bit; 2 bytes) [pos 8 + 19*D] */
23322 $c['R'], /* 90 or -90 s (16 bit; 2 bytes) [pos 10 + 19*D] */
23323 $c['bgcolor'], /* A32 (32 bytes) [pos 12 + 19*D] */
23324 $c['gradient'] /* A128 (128 bytes) [pos 44 + 19*D] */
23325 );
23326
23327 if ($c['background-image']) {
23328 $data .= pack("n2d2A6A6n3dA4A128",
23329 strlen($data), /* offset in main data to start of bgimage data */
23330 $c['background-image']['image_id'], /* n */
23331 $c['background-image']['orig_w'], /* d NB machine-dependent size */
23332 $c['background-image']['orig_h'], /* d NB machine-dependent size */
23333 $c['background-image']['x_pos'], /* A6 calc size or "50%" */
23334 $c['background-image']['y_pos'], /* A6 calc size or "50%" */
23335 $c['background-image']['x_repeat'], /* n true or false*/
23336 $c['background-image']['y_repeat'], /* n true or false */
23337 $c['background-image']['resize'], /* n 0 - 6 */
23338 $c['background-image']['opacity'], /* d 0-1 */
23339 $c['background-image']['itype'], /* A4 jpg etc */
23340 $c['background-image']['gradient'] /* A128 CSS string */
23341 );
23342 }
23343 else $data .= pack("n",0);
23344 $tb_offset = 2 + 186 + 2 + strlen($data);
23345 $stb = serialize($c['textbuffer']).' '; // buffer to allow updating in reverseTableDir
23346 $lentb = strlen($stb);
23347 $data2 = pack("nA".$lentb, $lentb, $stb);
23348
23349 $tempfh = true;
23350 if ($mode=="W" && $offset) {
23351 if (!$fh) { $fh = fopen($file, "r+b"); } // Overwrite (but not truncate)
23352 else $tempfh = false;
23353 fseek($fh, $offset);
23354 }
23355 else {
23356 $fh = fopen($file, "ab"); // APPEND
23357 }
23358 fwrite($fh, pack("n",$tb_offset)); // Offset to Text buffer 2 bytes
23359 fwrite($fh, $c['borderbin']); // border details 186 bytes
23360 fwrite($fh, pack("n",strlen($data))); // Length of Main data
23361 fwrite($fh, $data); // Main data
23362 fwrite($fh, $data2); // Text buffer (starts with "n" length of text buffer)
23363 if ($tempfh) fclose($fh);
23364 return ($tb_offset + 2 + $lentb);
23365}
23366
23367function _cacheUpdateTxB($c, $fh, $offset) {
23368 fseek($fh, $offset);
23369 $tb_offset = $this->read_short($fh); // First entry = Offset to Text buffer 2 bytes
23370 fseek($fh, ($tb_offset-2), SEEK_CUR);
23371 $lentb = $this->read_short($fh); // First entry in textbuffer = Length of serialized textbuffer - do not update
23372 $stb = serialize($c['textbuffer']);
23373 fwrite($fh, pack("A".$lentb, $stb));
23374}
23375
23376function _cacheUpdateBorder($c, $fh, $offset) {
23377 $offset += 2;
23378 fseek($fh, $offset);
23379 fwrite($fh, $c['borderbin']);
23380}
23381
23382function _cacheUpdateMtx($c, $fh, $offset, $var) {
23383 if ($var=='mih') { $offset += (2 + 186 + 2 + 4 + 14*_DSIZE); }
23384 else if ($var=='x0') { $offset += (2 + 186 + 2 + 4 + 15*_DSIZE); } // x0 and w0
23385 else if ($var=='y0') { $offset += (2 + 186 + 2 + 4 + 17*_DSIZE); } // y0 and h0
23386 fseek($fh, $offset);
23387 if ($var=='mih') { fwrite($fh, pack("d",$c['mih'])); }
23388 else if ($var=='x0') { fwrite($fh, pack("d2",$c['x0'],$c['w0'])); }
23389 else if ($var=='y0') { fwrite($fh, pack("d2",$c['y0'],$c['h0'])); }
23390}
23391
23392function _uncacheCell($ptr, $file, $fh) {
23393 // Requires either $file or $fh (file_handle)
23394 if ($ptr==0) { return null; }
23395 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 "); }
23396 $tempfh = true;
23397 if (!$fh) { $fh = fopen($file, "rb"); }
23398 else $tempfh = false;
23399 fseek($fh, $ptr);
23400 $c = array();
23401 $tb_offset = $this->read_short($fh); // First entry = Offset to Text buffer 2 bytes
23402 $c['borderbin'] = fread($fh,186); // border details 186 bytes
23403 $maindatalen = $this->read_short($fh); // Length of Main data (2 bytes)
23404 $str = fread($fh,$maindatalen ); // Main data
23405 $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);
23406
23407 if ($data['colspan']>0) $c['colspan'] = $data['colspan']; /* n */
23408 if ($data['rowspan']>0) $c['rowspan'] = $data['rowspan']; /* n */
23409 $c['s'] = $data['s']; /* d NB machine-dependent size */
23410 $c['maxs'] = $data['maxs']; /* d NB machine-dependent size */
23411 if ($data['nmaw']>0) $c['nestedmaw'] = $data['nmaw']; /* d NB machine-dependent size */
23412 if ($data['nmiw']>0) $c['nestedmiw'] = $data['nmiw']; /* d NB machine-dependent size */
23413 $c['padding']['L'] = $data['pl']; /* d NB machine-dependent size */
23414 $c['padding']['R'] = $data['pr']; /* d NB machine-dependent size */
23415 $c['padding']['T'] = $data['pt']; /* d NB machine-dependent size */
23416 $c['padding']['B'] = $data['pb']; /* d NB machine-dependent size */
23417 $c['dfs'] = $data['dfs']; /* d NB machine-dependent size */
23418 if ($data['w']>=0) $c['w'] = $data['w']; /* d NB machine-dependent size */
23419 if ($data['h']>0) $c['h'] = $data['h']; /* d NB machine-dependent size */
23420 if ($data['absmiw']>0) $c['absmiw'] = $data['absmiw']; /* d NB machine-dependent size */
23421 if ($data['maw']>0) $c['maw'] = $data['maw']; /* d NB machine-dependent size */
23422 if ($data['miw']>0) $c['miw'] = $data['miw']; /* d NB machine-dependent size */
23423 if ($data['mih']>0) $c['mih'] = $data['mih']; /* d NB machine-dependent size */
23424 if ($data['w0']>=0) { $c['w0'] = $data['w0']; /* d NB machine-dependent size */
23425 $c['x0'] = $data['x0']; } /* d NB machine-dependent size */
23426 if ($data['h0']>=0) { $c['h0'] = $data['h0']; /* d NB machine-dependent size */
23427 $c['y0'] = $data['y0']; } /* d NB machine-dependent size */
23428 $c['a'] = trim($data['a']); /* A1 */
23429 $c['va'] = trim($data['va']); /* A1 */
23430 if ($data['nowrap']) $c['nowrap'] = $data['nowrap']; /* 1 or blank n */
23431 else $c['nowrap'] = false;
23432 if ($data['wpercent']>0) $c['wpercent'] = $data['wpercent']; /* 0 - 100 n */
23433 if ($data['R']<>0) $c['R'] = $data['R']; /* 90 or -90 s */
23434 else $c['R'] = false;
23435 $c['bgcolor'] = trim($data['bgcol']); /* A32 */
23436 if (trim($data['grad']))
23437 $c['gradient'] = trim($data['grad']); /* A128 */
23438 else $c['gradient'] = false;
23439 if ($data['bgimage']>0) {
23440 $bgidata = substr($str, ($data['bgimage']+2));
23441 $c['background-image'] = unpack("nimage_id/dorig_w/dorig_h/A6x_pos/A6y_pos/nx_repeat/ny_repeat/nresize/dopacity/A4itype/A128gradient", $bgidata);
23442 }
23443
23444 $tblen = $this->read_short($fh); // Length of Textbuffer
23445 $tbsp = fread($fh,$tblen); // Textbuffer (serialised and packed)
23446 $tbs = unpack("A".$tblen."textbuffer",$tbsp); // Textbuffer unpacked
23447 $c['textbuffer'] = unserialize(trim($tbs['textbuffer'])); // Textbuffer unserialized
23448
23449 if ($tempfh) { fclose($fh); }
23450 return ($c);
23451}
23452function read_short(&$fh) {
23453 $s = fread($fh,2);
23454 $a = (ord($s[0])<<8) + ord($s[1]);
23455 if ($a & (1 << 15) ) {
23456 $a = ($a - (1 << 16));
23457 }
23458 return $a;
23459}
23460function _backupCacheFiles() {
23461 foreach($this->table AS $lvl=>$t) {
23462 foreach($this->table[$lvl] AS $c=>$t2) {
23463///////////////////////////if (!file_exists($t2['cache'])) { echo $lvl; echo $c; print_r($this->table); exit; }
23464 copy( $t2['cache'], $t2['cache'].'.bak');
23465 }
23466 }
23467}
23468function _restoreCacheFiles() {
23469 foreach($this->table AS $lvl=>$t) {
23470 foreach($this->table[$lvl] AS $c=>$t2) {
23471 copy( $t2['cache'].'.bak', $t2['cache']);
23472 }
23473 }
23474}
23475
23476
23477function _packCellBorder($cell) {
23478 if (!is_array($cell) || !isset($cell)) { return ''; }
23479
23480 if (!$this->packTableData) { return $cell; }
23481 // = 186 bytes
23482 $bindata = pack("nnda6A10nnda6A10nnda6A10nnda6A10nd9",
23483 $cell['border'],
23484 $cell['border_details']['R']['s'],
23485 $cell['border_details']['R']['w'],
23486 $cell['border_details']['R']['c'],
23487 $cell['border_details']['R']['style'],
23488 $cell['border_details']['R']['dom'],
23489
23490 $cell['border_details']['L']['s'],
23491 $cell['border_details']['L']['w'],
23492 $cell['border_details']['L']['c'],
23493 $cell['border_details']['L']['style'],
23494 $cell['border_details']['L']['dom'],
23495
23496 $cell['border_details']['T']['s'],
23497 $cell['border_details']['T']['w'],
23498 $cell['border_details']['T']['c'],
23499 $cell['border_details']['T']['style'],
23500 $cell['border_details']['T']['dom'],
23501
23502 $cell['border_details']['B']['s'],
23503 $cell['border_details']['B']['w'],
23504 $cell['border_details']['B']['c'],
23505 $cell['border_details']['B']['style'],
23506 $cell['border_details']['B']['dom'],
23507
23508 $cell['border_details']['mbw']['BL'],
23509 $cell['border_details']['mbw']['BR'],
23510 $cell['border_details']['mbw']['RT'],
23511 $cell['border_details']['mbw']['RB'],
23512 $cell['border_details']['mbw']['TL'],
23513 $cell['border_details']['mbw']['TR'],
23514 $cell['border_details']['mbw']['LT'],
23515 $cell['border_details']['mbw']['LB'],
23516
23517 $cell['border_details']['cellposdom']
23518 );
23519 return $bindata;
23520}
23521
23522
23523
23524function _getBorderWidths($bindata) {
23525 if (!$bindata) { return array(0,0,0,0); }
23526 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']); }
23527
23528 $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);
23529 $cell['border_details']['R']['w'] = $bd['rw'];
23530 $cell['border_details']['L']['w'] = $bd['lw'];
23531 $cell['border_details']['T']['w'] = $bd['tw'];
23532 $cell['border_details']['B']['w'] = $bd['bw'];
23533 return array($bd['tw'], $bd['rw'], $bd['bw'], $bd['lw']);
23534}
23535
23536
23537function _unpackCellBorder($bindata) {
23538 if (!$bindata) { return array(); }
23539 if (!$this->packTableData) { return $bindata; }
23540
23541 $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);
23542
23543 $cell['border'] = $bd['bord'];
23544 $cell['border_details']['R']['s'] = $bd['rs'];
23545 $cell['border_details']['R']['w'] = $bd['rw'];
23546 $cell['border_details']['R']['c'] = $bd['rca'];
23547 $cell['border_details']['R']['style'] = trim($bd['rst']);
23548 $cell['border_details']['R']['dom'] = $bd['rd'];
23549
23550 $cell['border_details']['L']['s'] = $bd['ls'];
23551 $cell['border_details']['L']['w'] = $bd['lw'];
23552 $cell['border_details']['L']['c'] = $bd['lca'];
23553 $cell['border_details']['L']['style'] = trim($bd['lst']);
23554 $cell['border_details']['L']['dom'] = $bd['ld'];
23555
23556 $cell['border_details']['T']['s'] = $bd['ts'];
23557 $cell['border_details']['T']['w'] = $bd['tw'];
23558 $cell['border_details']['T']['c'] = $bd['tca'];
23559 $cell['border_details']['T']['style'] = trim($bd['tst']);
23560 $cell['border_details']['T']['dom'] = $bd['td'];
23561
23562 $cell['border_details']['B']['s'] = $bd['bs'];
23563 $cell['border_details']['B']['w'] = $bd['bw'];
23564 $cell['border_details']['B']['c'] = $bd['bca'];
23565 $cell['border_details']['B']['style'] = trim($bd['bst']);
23566 $cell['border_details']['B']['dom'] = $bd['bd'];
23567
23568 $cell['border_details']['mbw']['BL'] = $bd['mbl'];
23569 $cell['border_details']['mbw']['BR'] = $bd['mbr'];
23570 $cell['border_details']['mbw']['RT'] = $bd['mrt'];
23571 $cell['border_details']['mbw']['RB'] = $bd['mrb'];
23572 $cell['border_details']['mbw']['TL'] = $bd['mtl'];
23573 $cell['border_details']['mbw']['TR'] = $bd['mtr'];
23574 $cell['border_details']['mbw']['LT'] = $bd['mlt'];
23575 $cell['border_details']['mbw']['LB'] = $bd['mlb'];
23576 $cell['border_details']['cellposdom'] = $bd['cpd'];
23577
23578 return($cell);
23579}
23580
23581
23582////////////////////////TABLE CODE (from PDFTable)/////////////////////////////////////
23583////////////////////////TABLE CODE (from PDFTable)/////////////////////////////////////
23584////////////////////////TABLE CODE (from PDFTable)/////////////////////////////////////
23585//table Array of (w, h, bc, nr, wc, hr, cells)
23586//w Width of table
23587//h Height of table
23588//nc Number column
23589//nr Number row
23590//hr List of height of each row
23591//wc List of width of each column
23592//cells List of cells of each rows, cells[i][j] is a cell in the table
23593function _tableColumnWidth(&$table,$firstpass=false){
23594 $cs = &$table['cells'];
23595
23596 $nc = $table['nc'];
23597 $nr = $table['nr'];
23598 $listspan = array();
23599
23600 if ($table['borders_separate']) {
23601 $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'];
23602 }
23603 else { $tblbw = $table['max_cell_border_width']['L']/2 + $table['max_cell_border_width']['R']/2 + $table['margin']['L'] + $table['margin']['R']; }
23604
23605 if ($this->cacheTables) { $fh = fopen($table['cache'], "r+b"); }
23606 else { $fh = null; }
23607
23608 // ADDED table['l'][colno]
23609 // = total length of text approx (using $c['s']) in that column - used to approximately distribute col widths in _tableWidth
23610 //
23611 for($j = 0 ; $j < $nc ; $j++ ) { //columns
23612 $wc = &$table['wc'][$j];
23613 for($i = 0 ; $i < $nr ; $i++ ) { //rows
23614 if (isset($cs[$i][$j]) && $cs[$i][$j]) {
23615 if ($this->cacheTables) {
23616 $c = $this->_uncacheCell($table['cells'][$i][$j], '', $fh);
23617 }
23618 else
23619 $c = &$cs[$i][$j];
23620
23621 if ($this->simpleTables){
23622 if ($table['borders_separate']) { // NB twice border width
23623 $extrcw = $table['simple']['border_details']['L']['w'] + $table['simple']['border_details']['R']['w'] + $c['padding']['L'] + $c['padding']['R'] + $table['border_spacing_H'];
23624 }
23625 else {
23626 $extrcw = $table['simple']['border_details']['L']['w']/2 + $table['simple']['border_details']['R']['w']/2 + $c['padding']['L'] + $c['padding']['R'];
23627 }
23628 }
23629 else {
23630 if ($this->packTableData) {
23631 list($bt,$br,$bb,$bl) = $this->_getBorderWidths($c['borderbin']);
23632 }
23633 else {
23634 $br = $c['border_details']['R']['w'];
23635 $bl = $c['border_details']['L']['w'];
23636 }
23637 if ($table['borders_separate']) { // NB twice border width
23638 $extrcw = $bl + $br + $c['padding']['L'] + $c['padding']['R'] + $table['border_spacing_H'];
23639 }
23640 else {
23641 $extrcw = $bl/2 + $br/2 + $c['padding']['L'] + $c['padding']['R'];
23642 }
23643 }
23644
23645 //$mw = $this->GetStringWidth('W') + $extrcw ;
23646 $mw = 0;
23647 // mPDF 5.6.13 Decimal point alignment
23648 if(substr($c['a'],0,1) == 'D') {
23649 $mw = $table['decimal_align'][$j]['maxs0'] + $table['decimal_align'][$j]['maxs1'] + $extrcw ;
23650 }
23651
23652 $c['absmiw'] = $mw;
23653
23654 if (isset($c['R']) && $c['R']) {
23655 $c['maw'] = $c['miw'] = $this->FontSize + $extrcw ;
23656 if (isset($c['w'])) { // If cell width is specified
23657 if ($c['miw'] <$c['w']) { $c['miw'] = $c['w']; }
23658 }
23659 if (!isset($c['colspan'])) {
23660 if ($wc['miw'] < $c['miw']) { $wc['miw'] = $c['miw']; }
23661 if ($wc['maw'] < $c['maw']) { $wc['maw'] = $c['maw']; }
23662
23663 if ($firstpass) {
23664 if (isset($table['l'][$j]) ) {
23665 $table['l'][$j] += $c['miw'] ;
23666 }
23667 else {
23668 $table['l'][$j] = $c['miw'] ;
23669 }
23670 }
23671 }
23672 if ($c['miw'] > $wc['miw']) { $wc['miw'] = $c['miw']; }
23673 if ($wc['miw'] > $wc['maw']) { $wc['maw'] = $wc['miw']; }
23674 continue;
23675 }
23676
23677 if ($firstpass) {
23678 if (isset($c['s'])) { $c['s'] += $extrcw; }
23679 if (isset($c['maxs'])) { $c['maxs'] += $extrcw; }
23680 if (isset($c['nestedmiw'])) { $c['nestedmiw'] += $extrcw; }
23681 if (isset($c['nestedmaw'])) { $c['nestedmaw'] += $extrcw; }
23682 }
23683
23684
23685 // If minimum width has already been set by a nested table or inline object (image/form), use it
23686 if (isset($c['nestedmiw']) && $this->table[1][1]['overflow']!='visible') { $miw = $c['nestedmiw']; }
23687 else { $miw = $mw; }
23688
23689 if (isset($c['maxs']) && $c['maxs'] != '') { $c['s'] = $c['maxs']; }
23690
23691 // If maximum width has already been set by a nested table, use it
23692 if (isset($c['nestedmaw'])) { $c['maw'] = $c['nestedmaw']; }
23693 else $c['maw'] = $c['s'];
23694
23695 if (isset($table['overflow']) && $table['overflow']=='visible' && $table['level']==1) {
23696 if (($c['maw'] + $tblbw) > $this->blk[$this->blklvl]['inner_width']) {
23697 $c['maw'] = $this->blk[$this->blklvl]['inner_width'] - $tblbw;
23698 }
23699 }
23700
23701 if (isset($c['nowrap']) && $c['nowrap']) { $miw = $c['maw']; }
23702
23703 if (isset($c['wpercent']) && $firstpass) {
23704 if (isset($c['colspan'])) { // Not perfect - but % set on colspan is shared equally on cols.
23705 for($k=0;$k<$c['colspan'];$k++) {
23706 $table['wc'][($j+$k)]['wpercent'] = $c['wpercent'] / $c['colspan'];
23707 }
23708 }
23709 else {
23710 if (isset($table['w']) && $table['w']) { $c['w'] = $c['wpercent']/100 * ($table['w'] - $tblbw ); }
23711 $wc['wpercent'] = $c['wpercent'];
23712 }
23713 }
23714
23715 if (isset($table['overflow']) && $table['overflow']=='visible' && $table['level']==1) {
23716 if (($c['w'] + $tblbw) > $this->blk[$this->blklvl]['inner_width']) {
23717 $c['w'] = $this->blk[$this->blklvl]['inner_width'] - $tblbw;
23718 }
23719 }
23720
23721
23722 if (isset($c['w'])) { // If cell width is specified
23723 if ($miw<$c['w']) { $c['miw'] = $c['w']; } // Cell min width = that specified
23724 if ($miw>$c['w']) { $c['miw'] = $c['w'] = $miw; } // If width specified is less than minimum allowed (W) increase it
23725 if (!isset($wc['w'])) { $wc['w'] = 1; } // If the Col width is not specified = set it to 1
23726
23727 }
23728 else { $c['miw'] = $miw; } // If cell width not specified -> set Cell min width it to minimum allowed (W)
23729
23730 if ($c['maw'] < $c['miw']) { $c['maw'] = $c['miw']; } // If Cell max width < Minwidth - increase it to =
23731 if (!isset($c['colspan'])) {
23732 if ($wc['miw'] < $c['miw']) { $wc['miw'] = $c['miw']; } // Update Col Minimum and maximum widths
23733 if ($wc['maw'] < $c['maw']) { $wc['maw'] = $c['maw']; }
23734 if ((isset($wc['absmiw']) && $wc['absmiw'] < $c['absmiw']) || !isset($wc['absmiw'])) { $wc['absmiw'] = $c['absmiw']; } // Update Col Minimum and maximum widths
23735
23736 if (isset($table['l'][$j]) ) {
23737 $table['l'][$j] += $c['s'];
23738 }
23739 else {
23740 $table['l'][$j] = $c['s'];
23741 }
23742
23743 }
23744 else {
23745 $listspan[] = array($i,$j);
23746 }
23747
23748 //Check if minimum width of the whole column is big enough for largest word to fit
23749 if (isset($c['textbuffer']) && (!isset($table['overflow']) || $table['overflow']!='wrap')) { // mPDF 5.5.11
23750 $minwidth = $this->TableCheckMinWidth($wc['miw']- $extrcw ,0,$c['textbuffer']);
23751 }
23752 else { $minwidth = 0; }
23753 if ($minwidth < 0) {
23754 //increase minimum width
23755 if (!isset($c['colspan'])) {
23756 $wc['miw'] = max($wc['miw'],((-$minwidth) + $extrcw) );
23757 }
23758 else {
23759 $c['miw'] = max($c['miw'],((-$minwidth) + $extrcw) );
23760 }
23761 }
23762 if (!isset($c['colspan'])) {
23763 if ($wc['miw'] > $wc['maw']) { $wc['maw'] = $wc['miw']; } //update maximum width, if needed
23764 }
23765 if ($this->cacheTables) {
23766 $this->_cacheCell($c, '', "W", $fh, $table['cells'][$i][$j]);
23767 }
23768 }
23769 unset($c);
23770 }//rows
23771 }//columns
23772
23773
23774 // COLUMN SPANS
23775 $wc = &$table['wc'];
23776 foreach ($listspan as $span) {
23777 list($i,$j) = $span;
23778 if ($this->cacheTables) {
23779 $c = $this->_uncacheCell($cs[$i][$j], '', $fh);
23780 }
23781 else
23782 $c = &$cs[$i][$j];
23783 $lc = $j + $c['colspan'];
23784 if ($lc > $nc) { $lc = $nc; }
23785 $wis = $wisa = 0;
23786 $was = $wasa = 0;
23787 $list = array();
23788 for($k=$j;$k<$lc;$k++) {
23789 if (isset($table['l'][$k]) ) {
23790 if ($c['R']) { $table['l'][$k] += $c['miw']/$c['colspan'] ; }
23791 else { $table['l'][$k] += $c['s']/$c['colspan']; }
23792 }
23793 else {
23794 if ($c['R']) { $table['l'][$k] = $c['miw']/$c['colspan'] ; }
23795 else { $table['l'][$k] = $c['s']/$c['colspan']; }
23796 }
23797 $wis += $wc[$k]['miw'];
23798 $was += $wc[$k]['maw'];
23799 if (!isset($c['w'])) {
23800 $list[] = $k;
23801 $wisa += $wc[$k]['miw'];
23802 $wasa += $wc[$k]['maw'];
23803 }
23804 }
23805 if ($c['miw'] > $wis) {
23806 if (!$wis) {
23807 for($k=$j;$k<$lc;$k++) { $wc[$k]['miw'] = $c['miw']/$c['colspan']; }
23808 }
23809 else if (!count($list)) {
23810 $wi = $c['miw'] - $wis;
23811 for($k=$j;$k<$lc;$k++) { $wc[$k]['miw'] += ($wc[$k]['miw']/$wis)*$wi; }
23812 }
23813 else {
23814 $wi = $c['miw'] - $wis;
23815 foreach ($list as $k) { if (!isset($wc[$k]['w']) || !$wc[$k]['w']) $wc[$k]['miw'] += ($wc[$k]['miw']/$wisa)*$wi; } // mPDF 5.7.2
23816 }
23817 }
23818 if ($c['maw'] > $was) {
23819 if (!$wis) {
23820 for($k=$j;$k<$lc;$k++) { $wc[$k]['maw'] = $c['maw']/$c['colspan']; }
23821 }
23822 else if (!count($list)) {
23823 $wi = $c['maw'] - $was;
23824 for($k=$j;$k<$lc;$k++) { $wc[$k]['maw'] += ($wc[$k]['maw']/$was)*$wi; }
23825 }
23826 else {
23827 $wi = $c['maw'] - $was;
23828 foreach ($list as $k) { $wc[$k]['maw'] += ($wc[$k]['maw']/$wasa)*$wi; }
23829 }
23830 }
23831 unset($c);
23832 }
23833
23834 if ($this->cacheTables) { fclose($fh); }
23835
23836 $checkminwidth = 0;
23837 $checkmaxwidth = 0;
23838 $totallength = 0;
23839
23840 for( $i = 0 ; $i < $nc ; $i++ ) {
23841 $checkminwidth += $table['wc'][$i]['miw'];
23842 $checkmaxwidth += $table['wc'][$i]['maw'];
23843 $totallength += $table['l'][$i];
23844 }
23845
23846 if (!isset($table['w']) && $firstpass) {
23847 $sumpc = 0;
23848 $notset = 0;
23849 for( $i = 0 ; $i < $nc ; $i++ ) {
23850 if (isset($table['wc'][$i]['wpercent']) && $table['wc'][$i]['wpercent']) {
23851 $sumpc += $table['wc'][$i]['wpercent'];
23852 }
23853 else { $notset++; }
23854 }
23855
23856 // If sum of widths as % >= 100% and not all columns are set
23857 // Set a nominal width of 1% for unset columns
23858 if ($sumpc >= 100 && $notset) {
23859 for( $i = 0 ; $i < $nc ; $i++ ) {
23860 if ((!isset($table['wc'][$i]['wpercent']) || !$table['wc'][$i]['wpercent']) &&
23861 (!isset($table['wc'][$i]['w']) || !$table['wc'][$i]['w'])) {
23862 $table['wc'][$i]['wpercent'] = 1;
23863 }
23864 }
23865 }
23866
23867
23868 if ($sumpc) { // if any percents are set
23869 $sumnonpc = (100 - $sumpc);
23870 $sumpc = max($sumpc,100);
23871 $miwleft = 0;
23872 $miwleftcount = 0;
23873 $miwsurplusnonpc = 0;
23874 $maxcalcmiw = 0;
23875 $mawleft = 0;
23876 $mawleftcount = 0;
23877 $mawsurplusnonpc = 0;
23878 $maxcalcmaw = 0;
23879 for( $i = 0 ; $i < $nc ; $i++ ) {
23880 if (isset($table['wc'][$i]['wpercent'])) {
23881 $maxcalcmiw = max($maxcalcmiw, ($table['wc'][$i]['miw'] * $sumpc /$table['wc'][$i]['wpercent']) );
23882 $maxcalcmaw = max($maxcalcmaw, ($table['wc'][$i]['maw'] * $sumpc /$table['wc'][$i]['wpercent']) );
23883 }
23884 else {
23885 $miwleft += $table['wc'][$i]['miw'];
23886 $mawleft += $table['wc'][$i]['maw'];
23887 if (!isset($table['wc'][$i]['w'])) { $miwleftcount++; $mawleftcount++; }
23888 }
23889 }
23890 if ($miwleft && $sumnonpc > 0) { $miwnon = $miwleft * 100 / $sumnonpc; }
23891 if ($mawleft && $sumnonpc > 0) { $mawnon = $mawleft * 100 / $sumnonpc; }
23892 if (($miwnon > $checkminwidth || $maxcalcmiw > $checkminwidth) && $this->keep_table_proportions) {
23893 if ($miwnon > $maxcalcmiw) {
23894 $miwsurplusnonpc = round((($miwnon * $sumnonpc / 100) - $miwleft),3);
23895 $checkminwidth = $miwnon;
23896 }
23897 else { $checkminwidth = $maxcalcmiw; }
23898 for( $i = 0 ; $i < $nc ; $i++ ) {
23899 if (isset($table['wc'][$i]['wpercent'])) {
23900 $newmiw = $checkminwidth * $table['wc'][$i]['wpercent']/100;
23901 if ($table['wc'][$i]['miw'] < $newmiw) {
23902 $table['wc'][$i]['miw'] = $newmiw;
23903 }
23904 $table['wc'][$i]['w'] = 1;
23905 }
23906 else if ($miwsurplusnonpc && !$table['wc'][$i]['w']) {
23907 $table['wc'][$i]['miw'] += $miwsurplusnonpc / $miwleftcount;
23908 }
23909 }
23910 }
23911 if (($mawnon > $checkmaxwidth || $maxcalcmaw > $checkmaxwidth )) {
23912 if ($mawnon > $maxcalcmaw) {
23913 $mawsurplusnonpc = round((($mawnon * $sumnonpc / 100) - $mawleft),3);
23914 $checkmaxwidth = $mawnon;
23915 }
23916 else { $checkmaxwidth = $maxcalcmaw; }
23917 for( $i = 0 ; $i < $nc ; $i++ ) {
23918 if (isset($table['wc'][$i]['wpercent'])) {
23919 $newmaw = $checkmaxwidth * $table['wc'][$i]['wpercent']/100;
23920 if ($table['wc'][$i]['maw'] < $newmaw) {
23921 $table['wc'][$i]['maw'] = $newmaw;
23922 }
23923 $table['wc'][$i]['w'] = 1;
23924 }
23925 else if ($mawsurplusnonpc && !$table['wc'][$i]['w']) {
23926 $table['wc'][$i]['maw'] += $mawsurplusnonpc / $mawleftcount;
23927 }
23928 if ($table['wc'][$i]['maw'] < $table['wc'][$i]['miw']) { $table['wc'][$i]['maw'] = $table['wc'][$i]['miw']; }
23929 }
23930 }
23931 if ($checkminwidth > $checkmaxwidth) { $checkmaxwidth = $checkminwidth; }
23932 }
23933 }
23934
23935 if (isset($table['wpercent']) && $table['wpercent']) {
23936 $checkminwidth *= (100 / $table['wpercent']);
23937 $checkmaxwidth *= (100 / $table['wpercent']);
23938 }
23939
23940
23941 $checkminwidth += $tblbw ;
23942 $checkmaxwidth += $tblbw ;
23943
23944 // Table['miw'] set by percent in first pass may be larger than sum of column miw
23945 if ((isset($table['miw']) && $checkminwidth > $table['miw']) || !isset($table['miw'])) { $table['miw'] = $checkminwidth; }
23946 if ((isset($table['maw']) && $checkmaxwidth > $table['maw']) || !isset($table['maw'])) { $table['maw'] = $checkmaxwidth; }
23947 $table['tl'] = $totallength ;
23948
23949
23950 if (!$this->tableCJK) {
23951 if ($this->table_rotate) {
23952 $mxw = $this->tbrot_maxw;
23953 }
23954 else {
23955 $mxw = $this->blk[$this->blklvl]['inner_width'];
23956 }
23957 if(!isset($table['overflow'])) { $table['overflow'] = null; }
23958 if ($table['overflow']=='visible') {
23959 return array(0,0);
23960 }
23961 else if ($table['overflow']=='hidden' && !$this->table_rotate && !$this->ColActive && $checkminwidth > $mxw) {
23962 $table['w'] = $table['miw'];
23963 return array(0,0);
23964 }
23965 else if ($table['overflow']=='wrap') { return array(0,0); }
23966
23967 if (isset($table['w']) && $table['w'] ) {
23968 if ($table['w'] >= $checkminwidth && $table['w'] <= $mxw) { $table['maw'] = $mxw = $table['w']; }
23969 else if ($table['w'] >= $checkminwidth && $table['w'] > $mxw && $this->keep_table_proportions) { $checkminwidth = $table['w']; }
23970 else {
23971 unset($table['w']);
23972 }
23973 }
23974 $ratio = $checkminwidth/$mxw;
23975 if ($checkminwidth > $mxw) { return array(($ratio +0.001),$checkminwidth); } // 0.001 to allow for rounded numbers when resizing
23976 }
23977 unset($cs);
23978 return array(0,0);
23979}
23980
23981
23982
23983function _tableWidth(&$table){
23984 $widthcols = &$table['wc'];
23985 $numcols = $table['nc'];
23986 $tablewidth = 0;
23987 if ($table['borders_separate']) {
23988 $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'];
23989 }
23990 else { $tblbw = $table['max_cell_border_width']['L']/2 + $table['max_cell_border_width']['R']/2 + $table['margin']['L'] + $table['margin']['R']; }
23991
23992 if ($table['level']>1 && isset($table['w'])) {
23993 if (isset($table['wpercent']) && $table['wpercent']) {
23994 $table['w'] = $temppgwidth = (($table['w']-$tblbw) * $table['wpercent'] / 100) + $tblbw ;
23995 }
23996 else {
23997 $temppgwidth = $table['w'] ;
23998 }
23999 }
24000 else if ($this->table_rotate) {
24001 $temppgwidth = $this->tbrot_maxw;
24002 // If it is less than 1/20th of the remaining page height to finish the DIV (i.e. DIV padding + table bottom margin)
24003 // then allow for this
24004 $enddiv = $this->blk[$this->blklvl]['padding_bottom'] + $this->blk[$this->blklvl]['border_bottom']['w'];
24005 if ($enddiv/$temppgwidth <0.05) { $temppgwidth -= $enddiv; }
24006 }
24007 else {
24008 if (isset($table['w']) && $table['w']< $this->blk[$this->blklvl]['inner_width']) {
24009 $notfullwidth = 1;
24010 $temppgwidth = $table['w'] ;
24011 }
24012 else if ($table['overflow']=='visible' && $table['level'] ==1) {
24013 $temppgwidth = null;
24014 }
24015 else if ($table['overflow']=='hidden' && !$this->ColActive && isset($table['w']) && $table['w'] > $this->blk[$this->blklvl]['inner_width'] && $table['w']==$table['miw']) {
24016 //$temppgwidth = $this->blk[$this->blklvl]['inner_width'];
24017 $temppgwidth = $table['w'] ;
24018 }
24019 else { $temppgwidth = $this->blk[$this->blklvl]['inner_width']; }
24020 }
24021
24022
24023 $totaltextlength = 0; // Added - to sum $table['l'][colno]
24024 $totalatextlength = 0; // Added - to sum $table['l'][colno] for those columns where width not set
24025 $percentages_set = 0;
24026 for ( $i = 0 ; $i < $numcols ; $i++ ) {
24027 if (isset($widthcols[$i]['wpercent'])) { $tablewidth += $widthcols[$i]['maw']; $percentages_set = 1; }
24028 else if (isset($widthcols[$i]['w'])) { $tablewidth += $widthcols[$i]['miw']; }
24029 else { $tablewidth += $widthcols[$i]['maw']; }
24030 $totaltextlength += $table['l'][$i];
24031 }
24032 if (!$totaltextlength) { $totaltextlength =1; }
24033 $tablewidth += $tblbw; // Outer half of table borders
24034
24035 if ($tablewidth > $temppgwidth) {
24036 $table['w'] = $temppgwidth;
24037 }
24038 // if any widths set as percentages and max width fits < page width
24039 else if ($tablewidth < $temppgwidth && !isset($table['w']) && $percentages_set) {
24040 $table['w'] = $table['maw'];
24041 }
24042 // if table width is set and is > allowed width
24043 if (isset($table['w']) && $table['w'] > $temppgwidth) { $table['w'] = $temppgwidth; }
24044 // IF the table width is now set - Need to distribute columns widths
24045 if (isset($table['w'])) {
24046 $wis = $wisa = 0;
24047 $list = array();
24048 $notsetlist = array();
24049 for( $i = 0 ; $i < $numcols ; $i++ ) {
24050 $wis += $widthcols[$i]['miw'];
24051 if (!isset($widthcols[$i]['w']) || ($widthcols[$i]['w'] && $table['w'] > $temppgwidth && !$this->keep_table_proportions && !$notfullwidth )){
24052 $list[] = $i;
24053 $wisa += $widthcols[$i]['miw'];
24054 $totalatextlength += $table['l'][$i];
24055 }
24056 }
24057 if (!$totalatextlength) { $totalatextlength =1; }
24058
24059 // Allocate spare (more than col's minimum width) across the cols according to their approx total text length
24060 // Do it by setting minimum width here
24061 if ($table['w'] > $wis + $tblbw) {
24062 // First set any cell widths set as percentages
24063 if ($table['w'] < $temppgwidth || $this->keep_table_proportions) {
24064 for($k=0;$k<$numcols;$k++) {
24065 if (isset($widthcols[$k]['wpercent'])) {
24066 $curr = $widthcols[$k]['miw'];
24067 $widthcols[$k]['miw'] = ($table['w']-$tblbw) * $widthcols[$k]['wpercent']/100;
24068 $wis += $widthcols[$k]['miw'] - $curr;
24069 $wisa += $widthcols[$k]['miw'] - $curr;
24070 }
24071 }
24072 }
24073 // Now allocate surplus up to maximum width of each column
24074 $surplus = 0; $ttl = 0; // number of surplus columns
24075 if (!count($list)) {
24076 $wi = ($table['w']-($wis + $tblbw)); // i.e. extra space to distribute
24077 for($k=0;$k<$numcols;$k++) {
24078 $spareratio = ($table['l'][$k] / $totaltextlength); // gives ratio to divide up free space
24079 // Don't allocate more than Maximum required width - save rest in surplus
24080 if ($widthcols[$k]['miw'] + ($wi * $spareratio) > $widthcols[$k]['maw']) {
24081 $surplus += ($wi * $spareratio) - ($widthcols[$k]['maw']-$widthcols[$k]['miw']);
24082 $widthcols[$k]['miw'] = $widthcols[$k]['maw'];
24083 }
24084 else {
24085 $notsetlist[] = $k;
24086 $ttl += $table['l'][$k];
24087 $widthcols[$k]['miw'] += ($wi * $spareratio);
24088 }
24089
24090 }
24091 }
24092 else {
24093 $wi = ($table['w'] - ($wis + $tblbw)); // i.e. extra space to distribute
24094 foreach ($list as $k) {
24095 $spareratio = ($table['l'][$k] / $totalatextlength); // gives ratio to divide up free space
24096 // Don't allocate more than Maximum required width - save rest in surplus
24097 if ($widthcols[$k]['miw'] + ($wi * $spareratio) > $widthcols[$k]['maw']) {
24098 $surplus += ($wi * $spareratio) - ($widthcols[$k]['maw']-$widthcols[$k]['miw']);
24099 $widthcols[$k]['miw'] = $widthcols[$k]['maw'];
24100 }
24101 else {
24102 $notsetlist[] = $k;
24103 $ttl += $table['l'][$k];
24104 $widthcols[$k]['miw'] += ($wi * $spareratio);
24105 }
24106 }
24107 }
24108 // If surplus still left over apportion it across columns
24109 if ($surplus) {
24110 // if some are set only add to remaining - otherwise add to all of them
24111 if (count($notsetlist) && count($notsetlist) < $numcols) {
24112 foreach ($notsetlist AS $i) {
24113 if ($ttl) $widthcols[$i]['miw'] += $surplus * $table['l'][$i] / $ttl ;
24114 }
24115 }
24116 // If some widths are defined, and others have been added up to their maxmum
24117 else if (count($list) && count($list) < $numcols) {
24118 foreach ($list AS $i) {
24119 $widthcols[$i]['miw'] += $surplus / count($list) ;
24120 }
24121 }
24122 else if ($numcols) { // If all columns
24123 $ttl = array_sum($table['l']);
24124 for ($i=0;$i<$numcols;$i++) {
24125 $widthcols[$i]['miw'] += $surplus * $table['l'][$i] / $ttl;
24126 }
24127 }
24128 }
24129
24130 }
24131
24132 // This sets the columns all to minimum width (which has been increased above if appropriate)
24133 for ($i=0;$i<$numcols;$i++) {
24134 $widthcols[$i] = $widthcols[$i]['miw'];
24135 }
24136
24137 // TABLE NOT WIDE ENOUGH EVEN FOR MINIMUM CONTENT WIDTH
24138 // If sum of column widths set are too wide for table
24139 $checktablewidth = 0;
24140 for ( $i = 0 ; $i < $numcols ; $i++ ) {
24141 $checktablewidth += $widthcols[$i];
24142 }
24143 if ($checktablewidth > ($temppgwidth + 0.001 - $tblbw)) {
24144 $usedup = 0; $numleft = 0;
24145 for ($i=0;$i<$numcols;$i++) {
24146 if ((isset($widthcols[$i]) && $widthcols[$i] > (($temppgwidth - $tblbw) / $numcols)) && (!isset($widthcols[$i]['w']))) {
24147 $numleft++;
24148 unset($widthcols[$i]);
24149 }
24150 else { $usedup += $widthcols[$i]; }
24151 }
24152 for ($i=0;$i<$numcols;$i++) {
24153 if (!isset($widthcols[$i]) || !$widthcols[$i]) {
24154 $widthcols[$i] = ((($temppgwidth - $tblbw) - $usedup)/ ($numleft));
24155 }
24156 }
24157 }
24158
24159 }
24160 else { //table has no width defined
24161 $table['w'] = $tablewidth;
24162 for ( $i = 0 ; $i < $numcols ; $i++) {
24163 if (isset($widthcols[$i]['wpercent']) && $this->keep_table_proportions) { $colwidth = $widthcols[$i]['maw']; }
24164 else if (isset($widthcols[$i]['w'])) { $colwidth = $widthcols[$i]['miw']; }
24165 else { $colwidth = $widthcols[$i]['maw']; }
24166 unset($widthcols[$i]);
24167 $widthcols[$i] = $colwidth;
24168 }
24169 }
24170
24171 if ($table['overflow']=='visible' && $table['level'] ==1) {
24172 if ($tablewidth > $this->blk[$this->blklvl]['inner_width']) {
24173 if ($this->cacheTables) { $fh = fopen($table['cache'], "r+b"); }
24174 else { $fh = null; }
24175 for ($j = 0 ; $j < $numcols; $j++) { //columns
24176 for ($i = 0 ; $i < $table['nr']; $i++) { //rows
24177 if (isset($table['cells'][$i][$j]) && $table['cells'][$i][$j]) {
24178 if ($this->cacheTables) {
24179 $cc = $this->_uncacheCell($table['cells'][$i][$j], '', $fh);
24180 $colspan = $cc['colspan'];
24181 }
24182 else
24183 $colspan = $table['cells'][$i][$j]['colspan'];
24184 if ($colspan > 1) {
24185 $w = 0;
24186 for ($c = $j; $c < ($j + $colspan); $c++) {
24187 $w += $widthcols[$c];
24188 }
24189 if ($w > $this->blk[$this->blklvl]['inner_width']) {
24190 $diff = $w - ($this->blk[$this->blklvl]['inner_width'] - $tblbw);
24191 for ($c = $j; $c < ($j + $colspan); $c++) {
24192 $widthcols[$c] -= $diff * ($widthcols[$c]/$w);
24193 }
24194 $table['w'] -= $diff;
24195 $table['csp'][$j] = $w - $diff;
24196 }
24197 }
24198 }
24199
24200 }
24201 }
24202 if ($this->cacheTables) { fclose($fh); }
24203 }
24204 $pgNo = 0;
24205 $currWc = 0;
24206 for ($i = 0 ; $i < $numcols; $i++) { //columns
24207 if (isset($table['csp'][$i])) {
24208 $w = $table['csp'][$i];
24209 unset($table['csp'][$i]);
24210 }
24211 else { $w = $widthcols[$i]; }
24212 if (($currWc + $w + $tblbw) > $this->blk[$this->blklvl]['inner_width']) {
24213 $pgNo++;
24214 $currWc = $widthcols[$i] ;
24215 }
24216 else { $currWc += $widthcols[$i] ; }
24217 $table['colPg'][$i] = $pgNo;
24218 }
24219 }
24220}
24221
24222
24223
24224function _tableHeight(&$table){
24225 $level = $table['level'];
24226 $levelid = $table['levelid'];
24227 $cells = &$table['cells'];
24228 $numcols = $table['nc'];
24229 $numrows = $table['nr'];
24230 $listspan = array();
24231 $checkmaxheight = 0;
24232 $headerrowheight = 0;
24233 $checkmaxheightplus = 0;
24234 $headerrowheightplus = 0;
24235 $firstrowheight = 0;
24236
24237 $footerrowheight = 0;
24238 $footerrowheightplus = 0;
24239 if ($this->table_rotate) {
24240 $temppgheight = $this->tbrot_maxh;
24241 $remainingpage = $this->tbrot_maxh;
24242 }
24243 else {
24244 $temppgheight = ($this->h - $this->bMargin - $this->tMargin) - $this->kwt_height;
24245 $remainingpage = ($this->h - $this->bMargin - $this->y) - $this->kwt_height;
24246
24247 // If it is less than 1/20th of the remaining page height to finish the DIV (i.e. DIV padding + table bottom margin)
24248 // then allow for this
24249 $enddiv = $this->blk[$this->blklvl]['padding_bottom'] + $this->blk[$this->blklvl]['border_bottom']['w'] + $table['margin']['B'];
24250 if ($remainingpage > $enddiv && $enddiv/$remainingpage <0.05) { $remainingpage -= $enddiv; }
24251 else if ($remainingpage == 0) { $remainingpage = 0.001; }
24252 if ($temppgheight > $enddiv && $enddiv/$temppgheight <0.05) { $temppgheight -= $enddiv; }
24253 else if ($temppgheight == 0) { $temppgheight = 0.001; }
24254 }
24255 if ($remainingpage < 0) { $remainingpage = 0.001; } // mPDF 5.6.64
24256 if ($temppgheight < 0) { $temppgheight = 0.001; } // mPDF 5.6.64
24257
24258 if ($this->cacheTables) { $fh = fopen($table['cache'], "r+b"); }
24259 else { $fh = null; }
24260
24261 for( $i = 0 ; $i < $numrows ; $i++ ) { //rows
24262 $heightrow = &$table['hr'][$i];
24263 for( $j = 0 ; $j < $numcols ; $j++ ) { //columns
24264 if (isset($cells[$i][$j]) && $cells[$i][$j]) {
24265 if ($this->cacheTables) {
24266 $c = $this->_uncacheCell($table['cells'][$i][$j], '', $fh);
24267 }
24268 else
24269 $c = &$cells[$i][$j];
24270
24271 if ($this->simpleTables){
24272 if ($table['borders_separate']) { // NB twice border width
24273 $extraWLR = ($table['simple']['border_details']['L']['w']+$table['simple']['border_details']['R']['w']) + ($c['padding']['L']+$c['padding']['R'])+$table['border_spacing_H'];
24274 $extrh = ($table['simple']['border_details']['T']['w']+$table['simple']['border_details']['B']['w']) + ($c['padding']['T']+$c['padding']['B'])+$table['border_spacing_V'];
24275 }
24276 else {
24277 $extraWLR = ($table['simple']['border_details']['L']['w']+$table['simple']['border_details']['R']['w'])/2 + ($c['padding']['L']+$c['padding']['R']);
24278 $extrh = ($table['simple']['border_details']['T']['w']+$table['simple']['border_details']['B']['w'])/2 + ($c['padding']['T']+$c['padding']['B']);
24279 }
24280 }
24281 else {
24282 if ($this->packTableData) {
24283 list($bt,$br,$bb,$bl) = $this->_getBorderWidths($c['borderbin']);
24284 }
24285 else {
24286 $bt = $c['border_details']['T']['w'];
24287 $bb = $c['border_details']['B']['w'];
24288 $br = $c['border_details']['R']['w'];
24289 $bl = $c['border_details']['L']['w'];
24290 }
24291 if ($table['borders_separate']) { // NB twice border width
24292 $extraWLR = $bl + $br + $c['padding']['L'] + $c['padding']['R'] + $table['border_spacing_H'];
24293 $extrh = $bt + $bb + $c['padding']['T'] + $c['padding']['B'] + $table['border_spacing_V'];
24294 }
24295 else {
24296 $extraWLR = $bl/2 + $br/2 + $c['padding']['L'] + $c['padding']['R'];
24297 $extrh = $bt/2 + $bb/2 + $c['padding']['T']+$c['padding']['B'];
24298 }
24299 }
24300
24301 if ($table['overflow']=='visible' && $level==1)
24302 list($x,$cw) = $this->_splitTableGetWidth($table, $i,$j, $fh);
24303 else
24304 list($x,$cw) = $this->_tableGetWidth($table, $i,$j, $fh);
24305
24306 // Get CELL HEIGHT
24307 // ++ extra parameter forces wrap to break word
24308 if ($c['R'] && isset($c['textbuffer'])) { // mPDF 5.4.01
24309 $str = '';
24310 foreach($c['textbuffer'] AS $t) { $str .= $t[0].' '; }
24311 $str = trim($str);
24312 $s_fs = $this->FontSizePt;
24313 $s_f = $this->FontFamily;
24314 $s_st = $this->FontStyle;
24315 $this->SetFont($c['textbuffer'][0][4],$c['textbuffer'][0][2],$c['textbuffer'][0][11] / $this->shrin_k,true,true);
24316 $tempch = $this->GetStringWidth($str);
24317 if ($c['R'] >= 45 && $c['R'] < 90) {
24318 $tempch = ((sin(deg2rad($c['R']))) * $tempch ) + ((sin(deg2rad($c['R']))) * (($c['textbuffer'][0][11]/_MPDFK) / $this->shrin_k));
24319 }
24320 $this->SetFont($s_f,$s_st,$s_fs,true,true);
24321 $ch = ($tempch ) + $extrh ;
24322 }
24323 else {
24324 if (isset($c['textbuffer'])) {
24325 $tempch = $this->TableWordWrap(($cw-$extraWLR),1,$c['textbuffer'], $c['dfs']);
24326 }
24327 else { $tempch = 0; }
24328
24329 // Added cellpadding top and bottom. (Lineheight already adjusted to table_lineheight)
24330 $ch = $tempch + $extrh ;
24331 }
24332 //If height is defined and it is bigger than calculated $ch then update values
24333 if (isset($c['h']) && $c['h'] > $ch) {
24334 $c['mih'] = $ch; //in order to keep valign working
24335 $ch = $c['h'];
24336 }
24337 else $c['mih'] = $ch;
24338 if ($this->cacheTables) {
24339 $this->_cacheUpdateMtx($c, $fh, $table['cells'][$i][$j], 'mih');
24340 }
24341 if (isset($c['rowspan'])) $listspan[] = array($i,$j);
24342 elseif ($heightrow < $ch) $heightrow = $ch;
24343
24344 // this is the extra used in _tableWrite to determine whether to trigger a page change
24345 if ($table['borders_separate']) {
24346 if ($i == ($numrows-1) || (isset($c['rowspan']) && ($i+$c['rowspan']) == ($numrows)) ) {
24347 $extra = $table['margin']['B'] + $table['padding']['B'] + $table['border_details']['B']['w'] + $table['border_spacing_V']/2;
24348 }
24349 else {
24350 $extra = $table['border_spacing_V']/2;
24351 }
24352 }
24353 else {
24354 if (!$this->simpleTables){
24355 $extra = $bb/2;
24356 }
24357 else if ($this->simpleTables){
24358 $extra = $table['simple']['border_details']['B']['w'] /2;
24359 }
24360 }
24361 if (isset($table['is_thead'][$i]) && $table['is_thead'][$i]) {
24362 if ($j==0) {
24363 $headerrowheight += $ch;
24364 $headerrowheightplus += $ch+$extra;
24365 }
24366 }
24367 else if (isset($table['is_tfoot'][$i]) && $table['is_tfoot'][$i]) {
24368 if ($j==0) {
24369 $footerrowheight += $ch;
24370 $footerrowheightplus += $ch+$extra;
24371 }
24372 }
24373 else {
24374 $checkmaxheight = max($checkmaxheight,$ch);
24375 $checkmaxheightplus = max($checkmaxheightplus,$ch+$extra);
24376 }
24377 if ($this->tableLevel==1 && $i == $table['headernrows']) { $firstrowheight = max($ch,$firstrowheight); }
24378 unset($c);
24379 }
24380 }//end of columns
24381 }//end of rows
24382
24383 $heightrow = &$table['hr'];
24384 foreach ($listspan as $span) {
24385 list($i,$j) = $span;
24386 if ($this->cacheTables) {
24387 $c = $this->_uncacheCell($table['cells'][$i][$j], '', $fh);
24388 }
24389 else
24390 $c = &$cells[$i][$j];
24391 $lr = $i + $c['rowspan'];
24392 if ($lr > $numrows) $lr = $numrows;
24393 $hs = $hsa = 0;
24394 $list = array();
24395 for($k=$i;$k<$lr;$k++) {
24396 $hs += $heightrow[$k];
24397 if (!isset($c['h'])) {
24398 $list[] = $k;
24399 $hsa += $heightrow[$k];
24400 }
24401 }
24402
24403 if ($table['borders_separate']) {
24404 if ($i == ($numrows-1) || ($i+$c['rowspan']) == ($numrows) ) {
24405 $extra = $table['margin']['B'] + $table['padding']['B'] + $table['border_details']['B']['w'] + $table['border_spacing_V']/2;
24406 }
24407 else {
24408 $extra = $table['border_spacing_V']/2;
24409 }
24410 }
24411 else {
24412 if (!$this->simpleTables){
24413 if ($this->packTableData) {
24414 list($bt,$br,$bb,$bl) = $this->_getBorderWidths($c['borderbin']);
24415 }
24416 else {
24417 $bb = $c['border_details']['B']['w'];
24418 }
24419 $extra = $bb/2;
24420 }
24421 else if ($this->simpleTables){
24422 $extra = $table['simple']['border_details']['B']['w'] /2;
24423 }
24424 }
24425 if (!empty($table['is_thead'][$i])) {
24426 $headerrowheight = max($headerrowheight,$hs);
24427 $headerrowheightplus = max($headerrowheightplus,$hs+$extra);
24428 }
24429 else if (!empty($table['is_tfoot'][$i])) {
24430 $footerrowheight = max($footerrowheight,$hs);
24431 $footerrowheightplus = max($footerrowheightplus,$hs+$extra);
24432 }
24433 else {
24434 $checkmaxheight = max($checkmaxheight,$hs);
24435 $checkmaxheightplus = max($checkmaxheightplus,$hs+$extra);
24436 }
24437 if ($this->tableLevel==1 && $i == $table['headernrows']) { $firstrowheight = max($hs,$firstrowheight); }
24438
24439 if ($c['mih'] > $hs) {
24440 if (!$hs) {
24441 for($k=$i;$k<$lr;$k++) $heightrow[$k] = $c['mih']/$c['rowspan'];
24442 }
24443 elseif (!count($list)) {
24444 $hi = $c['mih'] - $hs;
24445 for($k=$i;$k<$lr;$k++) $heightrow[$k] += ($heightrow[$k]/$hs)*$hi;
24446 }
24447 else {
24448 $hi = $c['mih'] - $hsa;
24449 foreach ($list as $k) $heightrow[$k] += ($heightrow[$k]/$hsa)*$hi;
24450 }
24451 }
24452 unset($c);
24453
24454 // If rowspans overlap so that one or more rows do not have a height set...
24455 // i.e. for one or more rows, the only cells (explicit) in that row have rowspan>1
24456 // so heightrow is still == 0
24457 if ($heightrow[$i]==0) {
24458 // Get row extent to analyse above and below
24459 $top = $i;
24460 foreach ($listspan as $checkspan) {
24461 list($cki,$ckj) = $checkspan;
24462 if ($this->cacheTables) {
24463 $c = $this->_uncacheCell($table['cells'][$cki][$ckj], '', $fh);
24464 }
24465 else
24466 $c = &$cells[$cki][$ckj];
24467 if (isset($c['rowspan']) && $c['rowspan']>1) {
24468 if (($cki + $c['rowspan']-1) >= $i) { $top = min($top, $cki); }
24469 }
24470 }
24471 $bottom = $i + $c['rowspan']-1;
24472 // Check for overconstrained conditions
24473 for ($k=$top; $k<=$bottom; $k++) {
24474 // if ['hr'] for any of the others is also 0, then abort (too complicated)
24475 if ($k != $i && $heightrow[$k]==0) { break(1); }
24476 // check again that top and bottom are not crossed by rowspans - or abort (too complicated)
24477 if ($k==$top) {
24478 // ???? take account of colspan as well???
24479 for( $m = 0 ; $m < $numcols ; $m++ ) { //columns
24480 if (!isset($cells[$k][$m]) || $cells[$k][$m]==0) {
24481 break(2);
24482 }
24483 }
24484 }
24485 else if ($k==$bottom) {
24486 // ???? take account of colspan as well???
24487 for( $m = 0 ; $m < $numcols ; $m++ ) { //columns
24488 if ($this->cacheTables) {
24489 $c = $this->_uncacheCell($table['cells'][$k][$m], '', $fh);
24490 }
24491 else
24492 $c = &$cells[$k][$m];
24493 if (isset($c['rowspan']) && $c['rowspan']>1) {
24494 break(2);
24495 }
24496 }
24497 }
24498 }
24499 // By columns add up col height using ['h'] if set or ['mih'] if not
24500 // Intentionally do not substract border-spacing
24501 $colH = array();
24502 $extH = 0;
24503 $newhr = array();
24504 for( $m = 0 ; $m < $numcols ; $m++ ) { //columns
24505 for ($k=$top; $k<=$bottom; $k++) {
24506 if (isset($cells[$k][$m]) && $cells[$k][$m]!=0) {
24507 if ($this->cacheTables) {
24508 $c = $this->_uncacheCell($table['cells'][$k][$m], '', $fh);
24509 }
24510 else
24511 $c = &$cells[$k][$m];
24512 if (isset($c['h']) && $c['h']) {
24513 $useh = $c['h'];
24514 }
24515 // ???? take account of colspan as well???
24516 else {
24517 $useh = $c['mih'];
24518 }
24519 $colH[$m] += $useh;
24520 if (!isset($c['rowspan']) || $c['rowspan']<2) { $newhr[$k] = max($newhr[$k], $useh); }
24521 }
24522 }
24523 $extH = max($tabH, $colH[$m]);
24524 }
24525 $newhr[$i] = $extH - array_sum($newhr);
24526 for ($k=$top; $k<=$bottom; $k++) { $heightrow[$k] = $newhr[$k]; }
24527 }
24528
24529
24530 unset($c);
24531 }
24532
24533 $table['h'] = array_sum($heightrow);
24534 unset($heightrow);
24535
24536 if ($this->cacheTables) { fclose($fh); }
24537
24538 if ($table['borders_separate']) {
24539 $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'];
24540 }
24541 else {
24542 $table['h'] += $table['margin']['T'] + $table['margin']['B'] + $table['max_cell_border_width']['T']/2 + $table['max_cell_border_width']['B']/2;
24543 }
24544
24545 $maxrowheight = $checkmaxheightplus + $headerrowheightplus + $footerrowheightplus;
24546 $maxfirstrowheight = $firstrowheight + $headerrowheightplus + $footerrowheightplus; // includes thead, 1st row and tfoot
24547 return array($table['h'],$maxrowheight,$temppgheight,$remainingpage,$maxfirstrowheight);
24548}
24549
24550function _tableGetWidth(&$table, $i,$j, $fh){
24551 if ($this->cacheTables) {
24552 $cell = $this->_uncacheCell($table['cells'][$i][$j], '', $fh);
24553 }
24554 else
24555 $cell = &$table['cells'][$i][$j];
24556 if ($cell) {
24557 if (isset($cell['x0'])) { return array($cell['x0'], $cell['w0']); }
24558 $x = 0;
24559 $widthcols = &$table['wc'];
24560 for( $k = 0 ; $k < $j ; $k++ ) $x += $widthcols[$k];
24561 $w = $widthcols[$j];
24562 if (isset($cell['colspan'])) {
24563 for ( $k = $j+$cell['colspan']-1 ; $k > $j ; $k-- ) $w += $widthcols[$k];
24564 }
24565 $cell['x0'] = $x;
24566 $cell['w0'] = $w;
24567 if ($this->cacheTables) {
24568 $this->_cacheUpdateMtx($cell, $fh, $table['cells'][$i][$j], 'x0');
24569 }
24570 return array($x, $w);
24571 }
24572 return array(0,0);
24573}
24574
24575function _splitTableGetWidth(&$table, $i,$j, $fh){
24576 if ($this->cacheTables) {
24577 $cell = $this->_uncacheCell($table['cells'][$i][$j], '', $fh);
24578 }
24579 else
24580 $cell = &$table['cells'][$i][$j];
24581 if ($cell) {
24582 if (isset($cell['x0'])) return array($cell['x0'], $cell['w0']);
24583 $x = 0;
24584 $widthcols = &$table['wc'];
24585 $pg = $table['colPg'][$j];
24586 for( $k = 0 ; $k < $j ; $k++ ) {
24587 if ($table['colPg'][$k]==$pg) $x += $widthcols[$k];
24588 }
24589 $w = $widthcols[$j];
24590 if (isset($cell['colspan'])) {
24591 for ( $k = $j+$cell['colspan']-1 ; $k > $j ; $k-- ) if ($table['colPg'][$k]==$pg) $w += $widthcols[$k];
24592 }
24593 $cell['x0'] = $x;
24594 $cell['w0'] = $w;
24595 if ($this->cacheTables) {
24596 $this->_cacheUpdateMtx($cell, $fh, $table['cells'][$i][$j], 'x0');
24597 }
24598 return array($x, $w);
24599 }
24600 return array(0,0);
24601}
24602
24603
24604function _tableGetHeight(&$table, $i,$j, $fh){
24605 if ($this->cacheTables) {
24606 $cell = $this->_uncacheCell($table['cells'][$i][$j], '', $fh);
24607 }
24608 else
24609 $cell = &$table['cells'][$i][$j];
24610 if ($cell){
24611 if (isset($cell['y0'])) return array($cell['y0'], $cell['h0']);
24612 $y = 0;
24613 $heightrow = &$table['hr'];
24614 for ($k=0;$k<$i;$k++) $y += $heightrow[$k];
24615 $h = $heightrow[$i];
24616 if (isset($cell['rowspan'])){
24617 for ($k=$i+$cell['rowspan']-1;$k>$i;$k--)
24618 $h += $heightrow[$k];
24619 }
24620 $cell['y0'] = $y;
24621 $cell['h0'] = $h;
24622 if ($this->cacheTables) {
24623 $this->_cacheUpdateMtx($cell, $fh, $table['cells'][$i][$j], 'y0');
24624 }
24625 return array($y, $h);
24626 }
24627 return array(0,0);
24628}
24629
24630function _tableGetMaxRowHeight($table, $row, $fh) {
24631 if ($row==$table['nc']-1) { return $table['hr'][$row]; }
24632 $maxrowheight = $table['hr'][$row];
24633 for ($i=$row+1;$i<$table['nr'];$i++) {
24634 $cellsset = 0;
24635 for ($j=0;$j<$table['nc'];$j++) {
24636 if ($this->cacheTables) {
24637 $cell = $this->_uncacheCell($table['cells'][$i][$j], '', $fh);
24638 if ($cell) {
24639 if (isset($cell['colspan'])) { $cellsset += $cell['colspan']; }
24640 else $cellsset += 1;
24641 }
24642 }
24643 else {
24644 if ($table['cells'][$i][$j]) {
24645 if (isset($table['cells'][$i][$j]['colspan'])) { $cellsset += $table['cells'][$i][$j]['colspan']; }
24646 else $cellsset += 1;
24647 }
24648 }
24649 }
24650 if ($cellsset == $table['nc']) { return $maxrowheight; }
24651 else { $maxrowheight += $table['hr'][$i]; }
24652 }
24653 return $maxrowheight;
24654}
24655
24656
24657// CHANGED TO ALLOW TABLE BORDER TO BE SPECIFIED CORRECTLY - added border_details
24658function _tableRect($x, $y, $w, $h, $bord=-1, $details=array(), $buffer=false, $bSeparate=false, $cort='cell', $tablecorner='', $bsv=0, $bsh=0) {
24659 $cellBorderOverlay = array();
24660
24661 if ($bord==-1) { $this->Rect($x, $y, $w, $h); }
24662 else if ($this->simpleTables && ($cort=='cell')) {
24663 $this->SetLineWidth($details['L']['w']);
24664 if ($details['L']['c']) {
24665 $this->SetDColor($details['L']['c']);
24666 }
24667 else { $this->SetDColor($this->ConvertColor(0)); }
24668 $this->SetLineJoin(0);
24669 $this->Rect($x, $y, $w, $h);
24670 }
24671 else if ($bord){
24672 if (!$bSeparate && $buffer) {
24673 $priority = 'LRTB';
24674 for($p=0;$p<strlen($priority);$p++) {
24675 $side = $priority[$p];
24676 $details['p'] = $side ;
24677
24678 $dom = 0;
24679 if (isset($details[$side]['w'])) { $dom += ($details[$side]['w'] * 100000); }
24680 if (isset($details[$side]['style'])) { $dom += (array_search($details[$side]['style'],$this->borderstyles)*100) ; }
24681 if (isset($details[$side]['dom'])) { $dom += ($details[$side]['dom']*10); }
24682
24683 // Precedence to darker colours at joins
24684 $coldom = 0;
24685 if (isset($details[$side]['c']) && is_array($details[$side]['c'])) {
24686 if ($details[$side]['c']{0}==3) { // RGB
24687 $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);
24688 }
24689 } // 10 black - 0 white
24690 if ($coldom) { $dom += $coldom; }
24691 // Lastly precedence to RIGHT and BOTTOM cells at joins
24692 if (isset($details['cellposdom'])) { $dom += $details['cellposdom']; }
24693
24694 $save = false;
24695 if ($side == 'T' && $this->issetBorder($bord, _BORDER_TOP)) { $cbord = _BORDER_TOP; $save = true; }
24696 else if ($side == 'L' && $this->issetBorder($bord, _BORDER_LEFT)) { $cbord = _BORDER_LEFT; $save = true; }
24697 else if ($side == 'R' && $this->issetBorder($bord, _BORDER_RIGHT)) { $cbord = _BORDER_RIGHT; $save = true; }
24698 else if ($side == 'B' && $this->issetBorder($bord, _BORDER_BOTTOM)) { $cbord = _BORDER_BOTTOM; $save = true; }
24699
24700 if ($save) {
24701 $this->cellBorderBuffer[] = pack("A16nCnda6A10d14",
24702 str_pad(sprintf("%08.7f", $dom),16,"0",STR_PAD_LEFT),
24703 $cbord,
24704 ord($side),
24705 $details[$side]['s'],
24706 $details[$side]['w'],
24707 $details[$side]['c'],
24708 $details[$side]['style'],
24709 $x, $y, $w, $h,
24710 $details['mbw']['BL'],
24711 $details['mbw']['BR'],
24712 $details['mbw']['RT'],
24713 $details['mbw']['RB'],
24714 $details['mbw']['TL'],
24715 $details['mbw']['TR'],
24716 $details['mbw']['LT'],
24717 $details['mbw']['LB'],
24718 $details['cellposdom'],
24719 0
24720 );
24721 if ($details[$side]['style'] == 'ridge' || $details[$side]['style'] == 'groove' || $details[$side]['style'] == 'inset' || $details[$side]['style'] == 'outset' || $details[$side]['style'] == 'double' ) {
24722 $details[$side]['overlay'] = true;
24723 $this->cellBorderBuffer[] = pack("A16nCnda6A10d14",
24724 str_pad(sprintf("%08.7f", ($dom+4)),16,"0",STR_PAD_LEFT),
24725 $cbord,
24726 ord($side),
24727 $details[$side]['s'],
24728 $details[$side]['w'],
24729 $details[$side]['c'],
24730 $details[$side]['style'],
24731 $x, $y, $w, $h,
24732 $details['mbw']['BL'],
24733 $details['mbw']['BR'],
24734 $details['mbw']['RT'],
24735 $details['mbw']['RB'],
24736 $details['mbw']['TL'],
24737 $details['mbw']['TR'],
24738 $details['mbw']['LT'],
24739 $details['mbw']['LB'],
24740 $details['cellposdom'],
24741 1
24742 );
24743 }
24744 }
24745 }
24746 return;
24747 }
24748
24749 if (isset($details['p']) && strlen($details['p'])>1) { $priority = $details['p']; }
24750 else { $priority='LTRB'; }
24751 $Tw = 0;
24752 $Rw = 0;
24753 $Bw = 0;
24754 $Lw = 0;
24755 if (isset($details['T']['w'])) { $Tw = $details['T']['w']; }
24756 if (isset($details['R']['w'])) { $Rw = $details['R']['w']; }
24757 if (isset($details['B']['w'])) { $Bw = $details['B']['w']; }
24758 if (isset($details['L']['w'])) { $Lw = $details['L']['w']; }
24759
24760 $x2 = $x + $w; $y2 = $y + $h;
24761 $oldlinewidth = $this->LineWidth;
24762
24763 for($p=0;$p<strlen($priority);$p++) {
24764 $side = $priority[$p];
24765 $xadj = 0;
24766 $xadj2 = 0;
24767 $yadj = 0;
24768 $yadj2 = 0;
24769 $print = false;
24770 if ($Tw && $side=='T' && $this->issetBorder($bord, _BORDER_TOP)) { // TOP
24771 $ly1 = $y;
24772 $ly2 = $y;
24773 $lx1 = $x;
24774 $lx2 = $x2;
24775 $this->SetLineWidth($Tw);
24776 if ($cort == 'cell' || strpos($tablecorner,'L')!==false) {
24777 if ($Tw > $Lw) $xadj = ($Tw - $Lw)/2;
24778 if ($Tw < $Lw) $xadj = ($Tw + $Lw)/2;
24779 }
24780 else { $xadj = $Tw/2 - $bsh/2; }
24781 if ($cort == 'cell' || strpos($tablecorner,'R')!==false) {
24782 if ($Tw > $Rw) $xadj2 = ($Tw - $Rw)/2;
24783 if ($Tw < $Rw) $xadj2 = ($Tw + $Rw)/2;
24784 }
24785 else { $xadj2 = $Tw/2 - $bsh/2; }
24786 if (!$bSeparate && $details['mbw']['TL']) {
24787 $xadj = ($Tw - $details['mbw']['TL'])/2 ;
24788 }
24789 if (!$bSeparate && $details['mbw']['TR']) {
24790 $xadj2 = ($Tw - $details['mbw']['TR'])/2;
24791 }
24792 $print = true;
24793 }
24794 if ($Lw && $side=='L' && $this->issetBorder($bord, _BORDER_LEFT)) { // LEFT
24795 $ly1 = $y;
24796 $ly2 = $y2;
24797 $lx1 = $x;
24798 $lx2 = $x;
24799 $this->SetLineWidth($Lw);
24800 if ($cort == 'cell' || strpos($tablecorner,'T')!==false) {
24801 if ($Lw > $Tw) $yadj = ($Lw - $Tw)/2;
24802 if ($Lw < $Tw) $yadj = ($Lw + $Tw)/2;
24803 }
24804 else { $yadj = $Lw/2 - $bsv/2; }
24805 if ($cort == 'cell' || strpos($tablecorner,'B')!==false) {
24806 if ($Lw > $Bw) $yadj2 = ($Lw - $Bw)/2;
24807 if ($Lw < $Bw) $yadj2 = ($Lw + $Bw)/2;
24808 }
24809 else { $yadj2 = $Lw/2 - $bsv/2; }
24810 if (!$bSeparate && $details['mbw']['LT']) {
24811 $yadj = ($Lw - $details['mbw']['LT'])/2;
24812 }
24813 if (!$bSeparate && $details['mbw']['LB']) {
24814 $yadj2 = ($Lw - $details['mbw']['LB'])/2;
24815 }
24816 $print = true;
24817 }
24818 if ($Rw && $side=='R' && $this->issetBorder($bord, _BORDER_RIGHT)) { // RIGHT
24819 $ly1 = $y;
24820 $ly2 = $y2;
24821 $lx1 = $x2;
24822 $lx2 = $x2;
24823 $this->SetLineWidth($Rw);
24824 if ($cort == 'cell' || strpos($tablecorner,'T')!==false) {
24825 if ($Rw < $Tw) $yadj = ($Rw + $Tw)/2;
24826 if ($Rw > $Tw) $yadj = ($Rw - $Tw)/2;
24827 }
24828 else { $yadj = $Rw/2 - $bsv/2; }
24829
24830 if ($cort == 'cell' || strpos($tablecorner,'B')!==false) {
24831 if ($Rw > $Bw) $yadj2 = ($Rw - $Bw)/2;
24832 if ($Rw < $Bw) $yadj2 = ($Rw + $Bw)/2;
24833 }
24834 else { $yadj2 = $Rw/2 - $bsv/2; }
24835
24836 if (!$bSeparate && $details['mbw']['RT']) {
24837 $yadj = ($Rw - $details['mbw']['RT'])/2;
24838 }
24839 if (!$bSeparate && $details['mbw']['RB']) {
24840 $yadj2 = ($Rw - $details['mbw']['RB'])/2;
24841 }
24842 $print = true;
24843 }
24844 if ($Bw && $side=='B' && $this->issetBorder($bord, _BORDER_BOTTOM)) { // BOTTOM
24845 $ly1 = $y2;
24846 $ly2 = $y2;
24847 $lx1 = $x;
24848 $lx2 = $x2;
24849 $this->SetLineWidth($Bw);
24850 if ($cort == 'cell' || strpos($tablecorner,'L')!==false) {
24851 if ($Bw > $Lw) $xadj = ($Bw - $Lw)/2;
24852 if ($Bw < $Lw) $xadj = ($Bw + $Lw)/2;
24853 }
24854 else { $xadj = $Bw/2 - $bsh/2; }
24855 if ($cort == 'cell' || strpos($tablecorner,'R')!==false) {
24856 if ($Bw > $Rw) $xadj2 = ($Bw - $Rw)/2;
24857 if ($Bw < $Rw) $xadj2 = ($Bw + $Rw)/2;
24858 }
24859 else { $xadj2 = $Bw/2 - $bsh/2; }
24860 if (!$bSeparate && $details['mbw']['BL']) {
24861 $xadj = ($Bw - $details['mbw']['BL'])/2;
24862 }
24863 if (!$bSeparate && $details['mbw']['BR']) {
24864 $xadj2 = ($Bw - $details['mbw']['BR'])/2;
24865 }
24866 $print = true;
24867 }
24868
24869 // Now draw line
24870 if ($print) {
24871/*-- TABLES-ADVANCED-BORDERS --*/
24872 if ($details[$side]['style'] == 'double') {
24873 if (!isset($details[$side]['overlay']) || !$details[$side]['overlay'] || $bSeparate) {
24874 if ($details[$side]['c']) {
24875 $this->SetDColor($details[$side]['c']);
24876 }
24877 else { $this->SetDColor($this->ConvertColor(0)); }
24878 $this->Line($lx1 + $xadj, $ly1 + $yadj, $lx2 - $xadj2, $ly2 - $yadj2);
24879 }
24880 if ((isset($details[$side]['overlay']) && $details[$side]['overlay']) || $bSeparate) {
24881 if ($bSeparate && $cort=='table') {
24882 if ($side=='T') {
24883 $xadj -= $this->LineWidth/2;
24884 $xadj2 -= $this->LineWidth;
24885 if ($this->issetBorder($bord, _BORDER_LEFT)) {
24886 $xadj += $this->LineWidth/2;
24887 }
24888 if ($this->issetBorder($bord, _BORDER_RIGHT)) {
24889 $xadj2 += $this->LineWidth;
24890 }
24891 }
24892 if ($side=='L') {
24893 $yadj -= $this->LineWidth/2;
24894 $yadj2 -= $this->LineWidth;
24895 if ($this->issetBorder($bord, _BORDER_TOP)) {
24896 $yadj += $this->LineWidth/2;
24897 }
24898 if ($this->issetBorder($bord, _BORDER_BOTTOM)) {
24899 $yadj2 += $this->LineWidth;
24900 }
24901 }
24902 if ($side=='B') {
24903 $xadj -= $this->LineWidth/2;
24904 $xadj2 -= $this->LineWidth;
24905 if ($this->issetBorder($bord, _BORDER_LEFT)) {
24906 $xadj += $this->LineWidth/2;
24907 }
24908 if ($this->issetBorder($bord, _BORDER_RIGHT)) {
24909 $xadj2 += $this->LineWidth;
24910 }
24911 }
24912 if ($side=='R') {
24913 $yadj -= $this->LineWidth/2;
24914 $yadj2 -= $this->LineWidth;
24915 if ($this->issetBorder($bord, _BORDER_TOP)) {
24916 $yadj += $this->LineWidth/2;
24917 }
24918 if ($this->issetBorder($bord, _BORDER_BOTTOM)) {
24919 $yadj2 += $this->LineWidth;
24920 }
24921 }
24922 }
24923
24924 $this->SetLineWidth($this->LineWidth/3);
24925
24926 $tbcol = $this->ConvertColor(255);
24927 for($l=0; $l <= $this->blklvl; $l++) {
24928 if ($this->blk[$l]['bgcolor']) {
24929 $tbcol = ($this->blk[$l]['bgcolorarray']); // mPDF 5.6.53
24930 }
24931 }
24932
24933 if ($bSeparate) {
24934 $cellBorderOverlay[] = array(
24935 'x' => $lx1 + $xadj,
24936 'y' => $ly1 + $yadj,
24937 'x2' => $lx2 - $xadj2,
24938 'y2' => $ly2 - $yadj2,
24939 'col' => $tbcol,
24940 'lw' => $this->LineWidth,
24941 );
24942 }
24943 else {
24944 $this->SetDColor($tbcol);
24945 $this->Line($lx1 + $xadj, $ly1 + $yadj, $lx2 - $xadj2, $ly2 - $yadj2);
24946 }
24947 }
24948 }
24949
24950
24951 else if (isset($details[$side]['style']) && ($details[$side]['style'] == 'ridge' || $details[$side]['style'] == 'groove' || $details[$side]['style'] == 'inset' || $details[$side]['style'] == 'outset')) {
24952 if (!isset($details[$side]['overlay']) || !$details[$side]['overlay'] || $bSeparate) {
24953 if ($details[$side]['c']) {
24954 $this->SetDColor($details[$side]['c']);
24955 }
24956 else { $this->SetDColor($this->ConvertColor(0)); }
24957 if ($details[$side]['style'] == 'outset' || $details[$side]['style'] == 'groove') {
24958 $nc = $this->_darkenColor($details[$side]['c']);
24959 $this->SetDColor($nc);
24960 }
24961 else if ($details[$side]['style'] == 'ridge' || $details[$side]['style'] == 'inset') {
24962 $nc = $this->_lightenColor($details[$side]['c']);
24963 $this->SetDColor($nc);
24964 }
24965 $this->Line($lx1 + $xadj, $ly1 + $yadj, $lx2 - $xadj2, $ly2 - $yadj2);
24966 }
24967 if ((isset($details[$side]['overlay']) && $details[$side]['overlay']) || $bSeparate) {
24968 if ($details[$side]['c']) {
24969 $this->SetDColor($details[$side]['c']);
24970 }
24971 else { $this->SetDColor($this->ConvertColor(0)); }
24972 $doubleadj = ($this->LineWidth)/3;
24973 $this->SetLineWidth($this->LineWidth/2);
24974 $xadj3 = $yadj3 = $wadj3 = $hadj3 = 0;
24975
24976 if ($details[$side]['style'] == 'ridge' || $details[$side]['style'] == 'inset') {
24977 $nc = $this->_darkenColor($details[$side]['c']);
24978
24979 if ($bSeparate && $cort=='table') {
24980 if ($side=='T') {
24981 $yadj3 = $this->LineWidth/2;
24982 $xadj3 = -$this->LineWidth/2;
24983 $wadj3 = $this->LineWidth;
24984 if ($this->issetBorder($bord, _BORDER_LEFT)) {
24985 $xadj3 += $this->LineWidth; $wadj3 -= $this->LineWidth;
24986 }
24987 if ($this->issetBorder($bord, _BORDER_RIGHT)) {
24988 $wadj3 -= $this->LineWidth*2;
24989 }
24990 }
24991 if ($side=='L') {
24992 $xadj3 = $this->LineWidth/2;
24993 $yadj3 = -$this->LineWidth/2;
24994 $hadj3 = $this->LineWidth;
24995 if ($this->issetBorder($bord, _BORDER_TOP)) {
24996 $yadj3 += $this->LineWidth; $hadj3 -= $this->LineWidth;
24997 }
24998 if ($this->issetBorder($bord, _BORDER_BOTTOM)) {
24999 $hadj3 -= $this->LineWidth*2;
25000 }
25001 }
25002 if ($side=='B') {
25003 $yadj3 = $this->LineWidth/2;
25004 $xadj3 = -$this->LineWidth/2;
25005 $wadj3 = $this->LineWidth;
25006 }
25007 if ($side=='R') {
25008 $xadj3 = $this->LineWidth/2;
25009 $yadj3 = -$this->LineWidth/2;
25010 $hadj3 = $this->LineWidth;
25011 }
25012 }
25013
25014 else if ($side=='T') { $yadj3 = $this->LineWidth/2; $xadj3 = $this->LineWidth/2; $wadj3 = -$this->LineWidth*2; }
25015 else if ($side=='L') { $xadj3 = $this->LineWidth/2; $yadj3 = $this->LineWidth/2; $hadj3 = -$this->LineWidth*2; }
25016
25017 else if ($side=='B' && $bSeparate) { $yadj3 = $this->LineWidth/2; $wadj3 = $this->LineWidth/2; }
25018 else if ($side=='R' && $bSeparate) { $xadj3 = $this->LineWidth/2; $hadj3 = $this->LineWidth/2; }
25019
25020 else if ($side=='B') { $yadj3 = $this->LineWidth/2; $xadj3 = $this->LineWidth/2; }
25021 else if ($side=='R') { $xadj3 = $this->LineWidth/2; $yadj3 = $this->LineWidth/2; }
25022 }
25023 else {
25024 $nc = $this->_lightenColor($details[$side]['c']);
25025
25026 if ($bSeparate && $cort=='table') {
25027 if ($side=='T') {
25028 $yadj3 = $this->LineWidth/2;
25029 $xadj3 = -$this->LineWidth/2;
25030 $wadj3 = $this->LineWidth;
25031 if ($this->issetBorder($bord, _BORDER_LEFT)) {
25032 $xadj3 += $this->LineWidth; $wadj3 -= $this->LineWidth;
25033 }
25034 }
25035 if ($side=='L') {
25036 $xadj3 = $this->LineWidth/2;
25037 $yadj3 = -$this->LineWidth/2;
25038 $hadj3 = $this->LineWidth;
25039 if ($this->issetBorder($bord, _BORDER_TOP)) {
25040 $yadj3 += $this->LineWidth; $hadj3 -= $this->LineWidth;
25041 }
25042 }
25043 if ($side=='B') {
25044 $yadj3 = $this->LineWidth/2;
25045 $xadj3 = -$this->LineWidth/2;
25046 $wadj3 = $this->LineWidth;
25047 if ($this->issetBorder($bord, _BORDER_LEFT)) {
25048 $xadj3 += $this->LineWidth; $wadj3 -= $this->LineWidth;
25049 }
25050 }
25051 if ($side=='R') {
25052 $xadj3 = $this->LineWidth/2;
25053 $yadj3 = -$this->LineWidth/2;
25054 $hadj3 = $this->LineWidth;
25055 if ($this->issetBorder($bord, _BORDER_TOP)) {
25056 $yadj3 += $this->LineWidth; $hadj3 -= $this->LineWidth;
25057 }
25058 }
25059 }
25060
25061 else if ($side=='T') { $yadj3 = $this->LineWidth/2; $xadj3 = $this->LineWidth/2; }
25062 else if ($side=='L') { $xadj3 = $this->LineWidth/2; $yadj3 = $this->LineWidth/2; }
25063
25064 else if ($side=='B' && $bSeparate) { $yadj3 = $this->LineWidth/2; $xadj3 = $this->LineWidth/2; }
25065 else if ($side=='R' && $bSeparate) { $xadj3 = $this->LineWidth/2; $yadj3 = $this->LineWidth/2; }
25066
25067 else if ($side=='B') { $yadj3 = $this->LineWidth/2; $xadj3 = -$this->LineWidth/2; $wadj3 = $this->LineWidth; }
25068 else if ($side=='R') { $xadj3 = $this->LineWidth/2; $yadj3 = -$this->LineWidth/2; $hadj3 = $this->LineWidth; }
25069
25070 }
25071
25072 if ($bSeparate) {
25073 $cellBorderOverlay[] = array(
25074 'x' => $lx1 + $xadj + $xadj3,
25075 'y' => $ly1 + $yadj + $yadj3,
25076 'x2' => $lx2 - $xadj2 + $xadj3 + $wadj3,
25077 'y2' => $ly2 - $yadj2 + $yadj3 + $hadj3,
25078 'col' => $nc,
25079 'lw' => $this->LineWidth,
25080 );
25081 }
25082 else {
25083 $this->SetDColor($nc);
25084 $this->Line($lx1 + $xadj + $xadj3, $ly1 + $yadj + $yadj3, $lx2 - $xadj2 + $xadj3 + $wadj3, $ly2 - $yadj2 + $yadj3 + $hadj3);
25085 }
25086 }
25087 }
25088
25089
25090 else {
25091/*-- END TABLES-ADVANCED-BORDERS --*/
25092 if ($details[$side]['style'] == 'dashed') {
25093 $dashsize = 2; // final dash will be this + 1*linewidth
25094 $dashsizek = 1.5; // ratio of Dash/Blank
25095 $this->SetDash($dashsize,($dashsize/$dashsizek)+($this->LineWidth*2));
25096 }
25097 else if ($details[$side]['style'] == 'dotted') {
25098 $this->SetLineJoin(1);
25099 $this->SetLineCap(1);
25100 $this->SetDash(0.001,($this->LineWidth*2));
25101 }
25102 if ($details[$side]['c']) {
25103 $this->SetDColor($details[$side]['c']);
25104 }
25105 else { $this->SetDColor($this->ConvertColor(0)); }
25106 $this->Line($lx1 + $xadj, $ly1 + $yadj, $lx2 - $xadj2, $ly2 - $yadj2);
25107/*-- TABLES-ADVANCED-BORDERS --*/
25108 }
25109/*-- END TABLES-ADVANCED-BORDERS --*/
25110
25111 // Reset Corners
25112 $this->SetDash();
25113 //BUTT style line cap
25114 $this->SetLineCap(2);
25115 }
25116 }
25117
25118 if ($bSeparate && count($cellBorderOverlay)) {
25119 foreach($cellBorderOverlay AS $cbo) {
25120 $this->SetLineWidth($cbo['lw']);
25121 $this->SetDColor($cbo['col']);
25122 $this->Line($cbo['x'], $cbo['y'], $cbo['x2'], $cbo['y2']);
25123 }
25124 }
25125
25126 // $this->SetLineWidth($oldlinewidth);
25127 // $this->SetDColor($this->ConvertColor(0));
25128 }
25129}
25130
25131
25132/*-- TABLES --*/
25133/*-- TABLES-ADVANCED-BORDERS --*/
25134function _lightenColor($c) {
25135 if (is_array($c)) { die('Color error in _lightencolor'); }
25136 if ($c{0}==3 || $c{0}==5) { // RGB
25137 list($h,$s,$l) = $this->rgb2hsl(ord($c{1})/255,ord($c{2})/255,ord($c{3})/255);
25138 $l += ((1 - $l)*0.8);
25139 list($r,$g,$b) = $this->hsl2rgb($h,$s,$l);
25140 $ret = array(3,$r,$g,$b);
25141 }
25142 else if ($c{0}==4 || $c{0}==6) { // CMYK
25143 $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)) );
25144 }
25145 else if ($c{0}==1) { // Grayscale
25146 $ret = array(1,min(255,(ord($c{1})+32)));
25147 }
25148 $c = array_pad($ret, 6, 0);
25149 $cstr = pack("a1ccccc", $c[0], ($c[1] & 0xFF), ($c[2] & 0xFF), ($c[3] & 0xFF), ($c[4] & 0xFF), ($c[5] & 0xFF) );
25150 return $cstr;
25151}
25152
25153
25154function _darkenColor($c) {
25155 if (is_array($c)) { die('Color error in _darkenColor'); }
25156 if ($c{0}==3 || $c{0}==5) { // RGB
25157 list($h,$s,$l) = $this->rgb2hsl(ord($c{1})/255,ord($c{2})/255,ord($c{3})/255);
25158 $s *= 0.25;
25159 $l *= 0.75;
25160 list($r,$g,$b) = $this->hsl2rgb($h,$s,$l);
25161 $ret = array(3,$r,$g,$b);
25162 }
25163 else if ($c{0}==4 || $c{0}==6) { // CMYK
25164 $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)) );
25165 }
25166 else if ($c{0}==1) { // Grayscale
25167 $ret = array(1,max(0,(ord($c{1})-32)));
25168 }
25169 $c = array_pad($ret, 6, 0);
25170 $cstr = pack("a1ccccc", $c[0], ($c[1] & 0xFF), ($c[2] & 0xFF), ($c[3] & 0xFF), ($c[4] & 0xFF), ($c[5] & 0xFF) );
25171 return $cstr;
25172}
25173
25174/*-- END TABLES-ADVANCED-BORDERS --*/
25175
25176
25177
25178function setBorder(&$var, $flag, $set = true) {
25179 $flag = intval($flag);
25180 if ($set) { $set = true; }
25181 $var = intval($var);
25182 $var = $set ? ($var | $flag) : ($var & ~$flag);
25183}
25184function issetBorder($var, $flag) {
25185 $flag = intval($flag);
25186 $var = intval($var);
25187 return (($var & $flag) == $flag);
25188}
25189
25190
25191function _table2cellBorder(&$tableb, &$cbdb, &$cellb, $bval) {
25192 if ($tableb && $tableb['w'] > $cbdb['w']) {
25193 $cbdb = $tableb;
25194 $this->setBorder($cellb, $bval);
25195 }
25196 else if ($tableb && $tableb['w'] == $cbdb['w']
25197 && array_search($tableb['style'],$this->borderstyles) > array_search($cbdb['style'],$this->borderstyles)) {
25198 $cbdb = $tableb;
25199 $this->setBorder($cellb, $bval);
25200 }
25201}
25202
25203// FIX BORDERS ********************************************
25204function _fixTableBorders(&$table){
25205 if ($this->cacheTables) { $fh = fopen($table['cache'], "r+b"); }
25206 else { $fh = null; }
25207
25208 if (!$table['borders_separate'] && $table['border_details']['L']['w']) {
25209 $table['max_cell_border_width']['L'] = $table['border_details']['L']['w'];
25210 }
25211 if (!$table['borders_separate'] && $table['border_details']['R']['w']) {
25212 $table['max_cell_border_width']['R'] = $table['border_details']['R']['w'];
25213 }
25214 if (!$table['borders_separate'] && $table['border_details']['T']['w']) {
25215 $table['max_cell_border_width']['T'] = $table['border_details']['T']['w'];
25216 }
25217 if (!$table['borders_separate'] && $table['border_details']['B']['w']) {
25218 $table['max_cell_border_width']['B'] = $table['border_details']['B']['w'];
25219 }
25220 if ($this->simpleTables) { return; }
25221 $cells = &$table['cells'];
25222 $numcols = $table['nc'];
25223 $numrows = $table['nr'];
25224/*-- TABLES-ADVANCED-BORDERS --*/
25225 if (isset($table['topntail']) && $table['topntail']) { $tntborddet = $this->border_details($table['topntail']); }
25226 if (isset($table['thead-underline']) && $table['thead-underline']) { $thuborddet = $this->border_details($table['thead-underline']); }
25227/*-- END TABLES-ADVANCED-BORDERS --*/
25228
25229 for( $i = 0 ; $i < $numrows ; $i++ ) { //Rows
25230 for( $j = 0 ; $j < $numcols ; $j++ ) { //Columns
25231 if (isset($cells[$i][$j]) && $cells[$i][$j]) {
25232 if ($this->cacheTables) {
25233 $cell = $this->_uncacheCell($table['cells'][$i][$j], '', $fh);
25234 }
25235 else
25236 $cell = &$cells[$i][$j];
25237 if ($this->packTableData) { // includes $this->cacheTables
25238 $cbord = $this->_unpackCellBorder($cell['borderbin']);
25239 }
25240 else {
25241 $cbord = &$cells[$i][$j];
25242 }
25243
25244 if (!$cbord['border'] && isset($table['border']) && $table['border'] && $this->table_border_attr_set) {
25245 $cbord['border'] = $table['border'];
25246 $cbord['border_details'] = $table['border_details'];
25247 }
25248
25249 if (isset($cell['colspan']) && $cell['colspan']>1) { $ccolsp = $cell['colspan']; }
25250 else { $ccolsp = 1; }
25251 if (isset($cell['rowspan']) && $cell['rowspan']>1) { $crowsp = $cell['rowspan']; }
25252 else { $crowsp = 1; }
25253
25254 $cbord['border_details']['cellposdom'] = ((($i+1)/$numrows) / 10000 ) + ((($j+1)/$numcols) / 10 );
25255 // Inherit Cell border from Table border
25256 if ($this->table_border_css_set && !$table['borders_separate']) {
25257 if ($i == 0) {
25258 $this->_table2cellBorder($table['border_details']['T'], $cbord['border_details']['T'], $cbord['border'], _BORDER_TOP);
25259 }
25260 if ($i == ($numrows-1) || ($i+$crowsp) == ($numrows) ) {
25261 $this->_table2cellBorder($table['border_details']['B'], $cbord['border_details']['B'], $cbord['border'], _BORDER_BOTTOM);
25262 }
25263 if ($j == 0) {
25264 $this->_table2cellBorder($table['border_details']['L'], $cbord['border_details']['L'], $cbord['border'], _BORDER_LEFT);
25265 }
25266 if ($j == ($numcols-1) || ($j+$ccolsp) == ($numcols) ) {
25267 $this->_table2cellBorder($table['border_details']['R'], $cbord['border_details']['R'], $cbord['border'], _BORDER_RIGHT);
25268 }
25269 }
25270
25271/*-- TABLES-ADVANCED-BORDERS --*/
25272 $fixbottom = true;
25273 if (isset($table['topntail']) && $table['topntail']) {
25274 if ($i == 0) {
25275 $cbord['border_details']['T'] = $tntborddet;
25276 $this->setBorder($cbord['border'], _BORDER_TOP);
25277 }
25278 if ($this->tableLevel==1 && $table['headernrows']>0 && $i == $table['headernrows']-1) {
25279 $cbord['border_details']['B'] = $tntborddet;
25280 $this->setBorder($cbord['border'], _BORDER_BOTTOM);
25281 $fixbottom = false;
25282 }
25283 else if ($this->tableLevel==1 && $table['headernrows']>0 && $i == $table['headernrows']) {
25284 if (!$table['borders_separate']) {
25285 $cbord['border_details']['T'] = $tntborddet;
25286 $this->setBorder($cbord['border'], _BORDER_TOP);
25287 }
25288 }
25289 if ($this->tableLevel==1 && $table['footernrows']>0 && $i == ($numrows-$table['footernrows']-1)) {
25290 if (!$table['borders_separate']) {
25291 $cbord['border_details']['B'] = $tntborddet;
25292 $this->setBorder($cbord['border'], _BORDER_BOTTOM);
25293 $fixbottom = false;
25294 }
25295 }
25296 else if ($this->tableLevel==1 && $table['footernrows']>0 && $i == ($numrows-$table['footernrows'])) {
25297 $cbord['border_details']['T'] = $tntborddet;
25298 $this->setBorder($cbord['border'], _BORDER_TOP);
25299 }
25300 if ($this->tabletheadjustfinished) { // $this->tabletheadjustfinished called from tableheader
25301 if (!$table['borders_separate']) {
25302 $cbord['border_details']['T'] = $tntborddet;
25303 $this->setBorder($cbord['border'], _BORDER_TOP);
25304 }
25305 }
25306 if ($i == ($numrows-1) || ($i+$crowsp) == ($numrows) ) {
25307 $cbord['border_details']['B'] = $tntborddet;
25308 $this->setBorder($cbord['border'], _BORDER_BOTTOM);
25309 }
25310 }
25311 if (isset($table['thead-underline']) && $table['thead-underline']) {
25312 if ($table['borders_separate']) {
25313 if ($i == 0) {
25314 $cbord['border_details']['B'] = $thuborddet;
25315 $this->setBorder($cbord['border'], _BORDER_BOTTOM);
25316 $fixbottom = false;
25317 }
25318 }
25319 else {
25320 if ($this->tableLevel==1 && $table['headernrows']>0 && $i == $table['headernrows']-1) {
25321 $cbord['border_details']['T'] = $thuborddet;
25322 $this->setBorder($cbord['border'], _BORDER_TOP);
25323 }
25324 else if ($this->tabletheadjustfinished) { // $this->tabletheadjustfinished called from tableheader
25325 $cbord['border_details']['T'] = $thuborddet;
25326 $this->setBorder($cbord['border'], _BORDER_TOP);
25327 }
25328 }
25329 }
25330
25331 // Collapse Border - Algorithm for conflicting borders
25332 // Hidden >> Width >> double>solid>dashed>dotted... >> style set on cell>table >> top/left>bottom/right
25333 // Do not turn off border which is overridden
25334 // Needed for page break for TOP/BOTTOM both to be defined in Collapsed borders
25335 // Means it is painted twice. (Left/Right can still disable overridden border)
25336 if (!$table['borders_separate']) {
25337 if (($i < ($numrows-1) || ($i+$crowsp) < $numrows ) && $fixbottom ) { // Bottom
25338 for ($cspi = 0; $cspi<$ccolsp; $cspi++) {
25339 // already defined Top for adjacent cell below
25340 if (isset($cells[($i+$crowsp)][$j+$cspi])) {
25341 if ($this->packTableData) {
25342 if ($this->cacheTables) {
25343 $adjc = $this->_uncacheCell($table['cells'][$i+$crowsp][$j+$cspi], '', $fh);
25344 }
25345 else { $adjc = $cells[($i+$crowsp)][$j+$cspi]; }
25346 $celladj = $this->_unpackCellBorder($adjc['borderbin']);
25347 }
25348 else { $celladj =& $cells[($i+$crowsp)][$j+$cspi]; }
25349 }
25350 else { $celladj = false; }
25351 if ($celladj && $celladj['border_details']['T']['s'] == 1) {
25352 $csadj = $celladj['border_details']['T']['w'];
25353 $csthis = $cbord['border_details']['B']['w'];
25354 // Hidden
25355 if ($cbord['border_details']['B']['style']=='hidden') {
25356 $celladj['border_details']['T'] = $cbord['border_details']['B'];
25357 $this->setBorder($celladj['border'] , _BORDER_TOP, false);
25358 $this->setBorder($cbord['border'] , _BORDER_BOTTOM , false);
25359 }
25360 else if ($celladj['border_details']['T']['style']=='hidden') {
25361 $cbord['border_details']['B'] = $celladj['border_details']['T'];
25362 $this->setBorder($cbord['border'] , _BORDER_BOTTOM , false);
25363 $this->setBorder($celladj['border'] , _BORDER_TOP, false);
25364 }
25365 // Width
25366 else if ($csthis > $csadj) {
25367 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
25368 $celladj['border_details']['T'] = $cbord['border_details']['B'];
25369 $this->setBorder($cbord['border'] , _BORDER_BOTTOM);
25370 }
25371 }
25372 else if ($csadj > $csthis) {
25373 if ($ccolsp < 2) { // don't overwrite this cell if it spans
25374 $cbord['border_details']['B'] = $celladj['border_details']['T'];
25375 $this->setBorder($celladj['border'] , _BORDER_TOP);
25376 }
25377 }
25378
25379 // double>solid>dashed>dotted...
25380 else if (array_search($cbord['border_details']['B']['style'],$this->borderstyles) > array_search($celladj['border_details']['T']['style'],$this->borderstyles)) {
25381 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
25382 $celladj['border_details']['T'] = $cbord['border_details']['B'];
25383 $this->setBorder($cbord['border'] , _BORDER_BOTTOM );
25384 }
25385 }
25386 else if (array_search($celladj['border_details']['T']['style'],$this->borderstyles) > array_search($cbord['border_details']['B']['style'],$this->borderstyles)) {
25387 if ($ccolsp < 2) { // don't overwrite this cell if it spans
25388 $cbord['border_details']['B'] = $celladj['border_details']['T'];
25389 $this->setBorder($celladj['border'] , _BORDER_TOP);
25390 }
25391 }
25392
25393
25394
25395 // Style set on cell vs. table
25396 else if ($celladj['border_details']['T']['dom'] > $cbord['border_details']['B']['dom']) {
25397 if ($ccolsp < 2) { // don't overwrite this cell if it spans
25398 $cbord['border_details']['B'] = $celladj['border_details']['T'];
25399 $this->setBorder($celladj['border'] , _BORDER_TOP);
25400 }
25401 }
25402 // Style set on cell vs. table - OR - LEFT/TOP (cell) in preference to BOTTOM/RIGHT
25403 else {
25404 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
25405 $celladj['border_details']['T'] = $cbord['border_details']['B'];
25406 $this->setBorder($cbord['border'] , _BORDER_BOTTOM );
25407 }
25408 }
25409 }
25410 else if ($celladj) {
25411 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
25412 $celladj['border_details']['T'] = $cbord['border_details']['B'];
25413 }
25414 }
25415 if ($celladj && $this->packTableData) {
25416 $celladj['borderbin'] = $this->_packCellBorder($celladj);
25417 unset($celladj['border']);
25418 unset($celladj['border_details']);
25419 }
25420 if ($this->cacheTables) {
25421 $this->_cacheUpdateBorder($celladj, $fh, $table['cells'][$i+$crowsp][$j+$cspi]);
25422 }
25423 unset($celladj);
25424 }
25425 }
25426
25427 if ($j < ($numcols-1) || ($j+$ccolsp) < $numcols ) { // Right-Left
25428 for ($cspi = 0; $cspi<$crowsp; $cspi++) {
25429 // already defined Left for adjacent cell to R
25430 if (isset($cells[($i+$cspi)][$j+$ccolsp])) {
25431 if ($this->packTableData) {
25432 if ($this->cacheTables) {
25433 $adjc = $this->_uncacheCell($table['cells'][$i+$cspi][$j+$ccolsp], '', $fh);
25434 }
25435 else { $adjc = $cells[($i+$cspi)][$j+$ccolsp]; }
25436 $celladj = $this->_unpackCellBorder($adjc['borderbin']);
25437 }
25438 else { $celladj =& $cells[$i+$cspi][$j+$ccolsp]; }
25439 }
25440 else { $celladj = false; }
25441 if ($celladj && $celladj['border_details']['L']['s'] == 1) {
25442 $csadj = $celladj['border_details']['L']['w'];
25443 $csthis = $cbord['border_details']['R']['w'];
25444 // Hidden
25445 if ($cbord['border_details']['R']['style']=='hidden') {
25446 $celladj['border_details']['L'] = $cbord['border_details']['R'];
25447 $this->setBorder($celladj['border'] , _BORDER_LEFT, false);
25448 $this->setBorder($cbord['border'] , _BORDER_RIGHT , false);
25449 }
25450 else if ($celladj['border_details']['L']['style']=='hidden') {
25451 $cbord['border_details']['R'] = $celladj['border_details']['L'];
25452 $this->setBorder($cbord['border'] , _BORDER_RIGHT , false);
25453 $this->setBorder($celladj['border'] , _BORDER_LEFT, false);
25454 }
25455 // Width
25456 else if ($csthis > $csadj) {
25457 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
25458 $celladj['border_details']['L'] = $cbord['border_details']['R'];
25459 $this->setBorder($cbord['border'] , _BORDER_RIGHT);
25460 $this->setBorder($celladj['border'] , _BORDER_LEFT, false);
25461 }
25462 }
25463 else if ($csadj > $csthis) {
25464 if ($crowsp < 2) { // don't overwrite this cell if it spans
25465 $cbord['border_details']['R'] = $celladj['border_details']['L'];
25466 $this->setBorder($cbord['border'] , _BORDER_RIGHT, false);
25467 $this->setBorder($celladj['border'] , _BORDER_LEFT);
25468 }
25469 }
25470
25471 // double>solid>dashed>dotted...
25472 else if (array_search($cbord['border_details']['R']['style'],$this->borderstyles) > array_search($celladj['border_details']['L']['style'],$this->borderstyles)) {
25473 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
25474 $celladj['border_details']['L'] = $cbord['border_details']['R'];
25475 $this->setBorder($celladj['border'] , _BORDER_LEFT, false);
25476 $this->setBorder($cbord['border'] , _BORDER_RIGHT);
25477 }
25478 }
25479 else if (array_search($celladj['border_details']['L']['style'],$this->borderstyles) > array_search($cbord['border_details']['R']['style'],$this->borderstyles)) {
25480 if ($crowsp < 2) { // don't overwrite this cell if it spans
25481 $cbord['border_details']['R'] = $celladj['border_details']['L'];
25482 $this->setBorder($cbord['border'] , _BORDER_RIGHT , false);
25483 $this->setBorder($celladj['border'] , _BORDER_LEFT);
25484 }
25485 }
25486
25487
25488 // Style set on cell vs. table
25489 else if ($celladj['border_details']['L']['dom'] > $cbord['border_details']['R']['dom']) {
25490 if ($crowsp < 2) { // don't overwrite this cell if it spans
25491 $cbord['border_details']['R'] = $celladj['border_details']['L'];
25492 $this->setBorder($celladj['border'] , _BORDER_LEFT);
25493 }
25494 }
25495 // Style set on cell vs. table - OR - LEFT/TOP (cell) in preference to BOTTOM/RIGHT
25496 else {
25497 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
25498 $celladj['border_details']['L'] = $cbord['border_details']['R'];
25499 $this->setBorder($cbord['border'] , _BORDER_RIGHT);
25500 }
25501 }
25502 }
25503 else if ($celladj) {
25504 // if right-cell border is not set
25505 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
25506 $celladj['border_details']['L'] = $cbord['border_details']['R'];
25507 }
25508 }
25509 if ($celladj && $this->packTableData) {
25510 $celladj['borderbin'] = $this->_packCellBorder($celladj);
25511 unset($celladj['border']);
25512 unset($celladj['border_details']);
25513 }
25514 if ($this->cacheTables) {
25515 $this->_cacheUpdateBorder($celladj, $fh, $table['cells'][$i+$cspi][$j+$ccolsp]);
25516 }
25517 unset($celladj);
25518 }
25519 }
25520 }
25521
25522
25523 // Set maximum cell border width meeting at LRTB edges of cell - used for extended cell border
25524 // ['border_details']['mbw']['LT'] = meeting border width - Left border - Top end
25525 if (!$table['borders_separate']) {
25526 $cbord['border_details']['mbw']['BL'] = max($cbord['border_details']['mbw']['BL'], $cbord['border_details']['L']['w']);
25527 $cbord['border_details']['mbw']['BR'] = max($cbord['border_details']['mbw']['BR'], $cbord['border_details']['R']['w']);
25528 $cbord['border_details']['mbw']['RT'] = max($cbord['border_details']['mbw']['RT'], $cbord['border_details']['T']['w']);
25529 $cbord['border_details']['mbw']['RB'] = max($cbord['border_details']['mbw']['RB'], $cbord['border_details']['B']['w']);
25530 $cbord['border_details']['mbw']['TL'] = max($cbord['border_details']['mbw']['TL'], $cbord['border_details']['L']['w']);
25531 $cbord['border_details']['mbw']['TR'] = max($cbord['border_details']['mbw']['TR'], $cbord['border_details']['R']['w']);
25532 $cbord['border_details']['mbw']['LT'] = max($cbord['border_details']['mbw']['LT'], $cbord['border_details']['T']['w']);
25533 $cbord['border_details']['mbw']['LB'] = max($cbord['border_details']['mbw']['LB'], $cbord['border_details']['B']['w']);
25534 if (($i+$crowsp) < $numrows && isset($cells[$i+$crowsp][$j])) { // Has Bottom adjoining cell
25535 if ($this->packTableData) {
25536 if ($this->cacheTables) {
25537 $adjc = $this->_uncacheCell($table['cells'][$i+$crowsp][$j], '', $fh);
25538 }
25539 else { $adjc = $cells[$i+$crowsp][$j]; }
25540 $celladj = $this->_unpackCellBorder($adjc['borderbin']);
25541 }
25542 else { $celladj =& $cells[$i+$crowsp][$j]; }
25543 $cbord['border_details']['mbw']['BL'] = max($cbord['border_details']['mbw']['BL'], $celladj['border_details']['L']['w'], $celladj['border_details']['mbw']['TL']);
25544 $cbord['border_details']['mbw']['BR'] = max($cbord['border_details']['mbw']['BR'], $celladj['border_details']['R']['w'], $celladj['border_details']['mbw']['TR']);
25545 $cbord['border_details']['mbw']['LB'] = max($cbord['border_details']['mbw']['LB'], $celladj['border_details']['mbw']['LT']);
25546 $cbord['border_details']['mbw']['RB'] = max($cbord['border_details']['mbw']['RB'], $celladj['border_details']['mbw']['RT']);
25547 unset($celladj);
25548 }
25549 if (($j+$ccolsp) < $numcols && isset($cells[$i][$j+$ccolsp])) { // Has Right adjoining cell
25550 if ($this->packTableData) {
25551 if ($this->cacheTables) {
25552 $adjc = $this->_uncacheCell($table['cells'][$i][$j+$ccolsp], '', $fh);
25553 }
25554 else { $adjc = $cells[$i][$j+$ccolsp]; }
25555 $celladj = $this->_unpackCellBorder($adjc['borderbin']);
25556 }
25557 else { $celladj =& $cells[$i][$j+$ccolsp]; }
25558 $cbord['border_details']['mbw']['RT'] = max($cbord['border_details']['mbw']['RT'], $celladj['border_details']['T']['w'], $celladj['border_details']['mbw']['LT']);
25559 $cbord['border_details']['mbw']['RB'] = max($cbord['border_details']['mbw']['RB'], $celladj['border_details']['B']['w'], $celladj['border_details']['mbw']['LB']);
25560 $cbord['border_details']['mbw']['TR'] = max($cbord['border_details']['mbw']['TR'], $celladj['border_details']['mbw']['TL']);
25561 $cbord['border_details']['mbw']['BR'] = max($cbord['border_details']['mbw']['BR'], $celladj['border_details']['mbw']['BL']);
25562 unset($celladj);
25563 }
25564
25565 if ($i > 0 && isset($cells[$i-1][$j]) && (($this->packTableData && $cells[$i-1][$j]['borderbin']) || $cells[$i-1][$j]['border'])) { // Has Top adjoining cell
25566 if ($this->packTableData) {
25567 if ($this->cacheTables) {
25568 $adjc = $this->_uncacheCell($table['cells'][$i-1][$j], '', $fh);
25569 }
25570 else { $adjc = $cells[$i-1][$j]; }
25571 $celladj = $this->_unpackCellBorder($adjc['borderbin']);
25572 }
25573 else { $celladj =& $cells[$i-1][$j]; }
25574 $cbord['border_details']['mbw']['TL'] = max($cbord['border_details']['mbw']['TL'], $celladj['border_details']['L']['w'], $celladj['border_details']['mbw']['BL']);
25575 $cbord['border_details']['mbw']['TR'] = max($cbord['border_details']['mbw']['TR'], $celladj['border_details']['R']['w'], $celladj['border_details']['mbw']['BR']);
25576 $cbord['border_details']['mbw']['LT'] = max($cbord['border_details']['mbw']['LT'], $celladj['border_details']['mbw']['LB']);
25577 $cbord['border_details']['mbw']['RT'] = max($cbord['border_details']['mbw']['RT'], $celladj['border_details']['mbw']['RB']);
25578
25579 if ($celladj['border_details']['mbw']['BL']) {
25580 $celladj['border_details']['mbw']['BL'] = max($cbord['border_details']['mbw']['TL'], $celladj['border_details']['mbw']['BL']);
25581 }
25582 if ($celladj['border_details']['mbw']['BR'] ) {
25583 $celladj['border_details']['mbw']['BR'] = max($celladj['border_details']['mbw']['BR'], $cbord['border_details']['mbw']['TR']);
25584 }
25585 if ($this->packTableData) { $cells[$i-1][$j]['borderbin'] = $this->_packCellBorder($celladj); }
25586 unset($celladj);
25587 }
25588 if ($j > 0 && isset($cells[$i][$j-1]) && (($this->packTableData && $cells[$i][$j-1]['borderbin']) || $cells[$i][$j-1]['border'])) { // Has Left adjoining cell
25589 if ($this->packTableData) {
25590 if ($this->cacheTables) {
25591 $adjc = $this->_uncacheCell($table['cells'][$i][$j-1], '', $fh);
25592 }
25593 else { $adjc = $cells[$i][$j-1]; }
25594 $celladj = $this->_unpackCellBorder($adjc['borderbin']);
25595 }
25596 else { $celladj =& $cells[$i][$j-1]; }
25597 $cbord['border_details']['mbw']['LT'] = max($cbord['border_details']['mbw']['LT'], $celladj['border_details']['T']['w'], $celladj['border_details']['mbw']['RT']);
25598 $cbord['border_details']['mbw']['LB'] = max($cbord['border_details']['mbw']['LB'], $celladj['border_details']['B']['w'], $celladj['border_details']['mbw']['RB']);
25599 $cbord['border_details']['mbw']['BL'] = max($cbord['border_details']['mbw']['BL'], $celladj['border_details']['mbw']['BR']);
25600 $cbord['border_details']['mbw']['TL'] = max($cbord['border_details']['mbw']['TL'], $celladj['border_details']['mbw']['TR']);
25601
25602 if ($celladj['border_details']['mbw']['RT']) {
25603 $celladj['border_details']['mbw']['RT'] = max($celladj['border_details']['mbw']['RT'], $cbord['border_details']['mbw']['LT']);
25604 }
25605 if ($celladj['border_details']['mbw']['RB']) {
25606 $celladj['border_details']['mbw']['RB'] = max($celladj['border_details']['mbw']['RB'], $cbord['border_details']['mbw']['LB']);
25607 }
25608 if ($this->packTableData) { $cells[$i][$j-1]['borderbin'] = $this->_packCellBorder($celladj); }
25609 unset($celladj);
25610 }
25611
25612
25613 // Update maximum cell border width at LRTB edges of table - used for overall table width
25614 if ($j == 0 && $cbord['border_details']['L']['w']) {
25615 $table['max_cell_border_width']['L'] = max($table['max_cell_border_width']['L'],$cbord['border_details']['L']['w']);
25616 }
25617 if (($j == ($numcols-1) || ($j+$ccolsp) == $numcols ) && $cbord['border_details']['R']['w']) {
25618 $table['max_cell_border_width']['R'] = max($table['max_cell_border_width']['R'],$cbord['border_details']['R']['w']);
25619 }
25620 if ($i == 0 && $cbord['border_details']['T']['w']) {
25621 $table['max_cell_border_width']['T'] = max($table['max_cell_border_width']['T'],$cbord['border_details']['T']['w']);
25622 }
25623 if (($i == ($numrows-1) || ($i+$crowsp) == $numrows ) && $cbord['border_details']['B']['w']) {
25624 $table['max_cell_border_width']['B'] = max($table['max_cell_border_width']['B'],$cbord['border_details']['B']['w']);
25625 }
25626 }
25627/*-- END TABLES-ADVANCED-BORDERS --*/
25628
25629 if ($this->packTableData) { $cell['borderbin'] = $this->_packCellBorder($cbord); }
25630
25631 if ($this->cacheTables) {
25632 $this->_cacheUpdateBorder($cell, $fh, $table['cells'][$i][$j]);
25633 }
25634 unset($cbord );
25635 unset($cell );
25636 }
25637 }
25638 }
25639 if ($this->cacheTables) { fclose($fh); }
25640 unset($cell );
25641}
25642// END FIX BORDERS ************************************************************************************
25643
25644
25645function _reverseTableDir(&$table) {
25646 if ($this->cacheTables) { $fh = fopen($table['cache'], "r+b"); }
25647 $cells = &$table['cells'];
25648 $numcols = $table['nc'];
25649 $numrows = $table['nr'];
25650 for( $i = 0 ; $i < $numrows ; $i++ ) { //Rows
25651 $row = array();
25652 for( $j = ($numcols-1) ; $j >= 0 ; $j-- ) { //Columns
25653 if (isset($cells[$i][$j]) && $cells[$i][$j]) {
25654 if ($this->cacheTables) {
25655 $cell = $this->_uncacheCell($table['cells'][$i][$j], '', $fh);
25656 }
25657 else
25658 $cell = &$cells[$i][$j];
25659 $col = $numcols - $j - 1;
25660 if (isset($cell['colspan']) && $cell['colspan'] > 1) { $col -= ($cell['colspan']-1); }
25661 // Nested content
25662 for ($n=0; $n < count($cell['textbuffer']); $n++) {
25663 $t = $cell['textbuffer'][$n][0];
25664 if (substr($t,0,19) == "\xbb\xa4\xactype=nestedtable") {
25665 $objattr = $this->_getObjAttr($t);
25666 $objattr['col'] = $col;
25667 $cell['textbuffer'][$n][0] = "\xbb\xa4\xactype=nestedtable,objattr=".serialize($objattr)."\xbb\xa4\xac";
25668 $this->table[($this->tableLevel+1)][$objattr['nestedcontent']]['nestedpos'][1] = $col;
25669 if ($this->cacheTables) {
25670 $this->_cacheUpdateTxB($cell, $fh, $table['cells'][$i][$j]);
25671 }
25672 }
25673 }
25674 $row[$col] = $cells[$i][$j];
25675 unset($cell);
25676 }
25677 }
25678 for($f=0; $f < $numcols; $f++) {
25679 if (!isset($row[$f])) { $row[$f] = 0; }
25680 }
25681 $table['cells'][$i] = $row;
25682 }
25683 if ($this->cacheTables) { fclose($fh); }
25684}
25685
25686
25687function _tableWrite(&$table, $split=false, $startrow=0, $startcol=0, $splitpg=0, $rety = 0){
25688 $level = $table['level'];
25689 $levelid = $table['levelid'];
25690
25691 $cells = &$table['cells'];
25692 $numcols = $table['nc'];
25693 $numrows = $table['nr'];
25694
25695 if ($this->ColActive && $level==1) { $this->breakpoints[$this->CurrCol][] = $this->y; } // *COLUMNS*
25696
25697 if (!$split || ($startrow==0 && $splitpg==0) || $startrow>0){
25698 // TABLE TOP MARGIN
25699 if ($table['margin']['T']) {
25700 if (!$this->table_rotate && $level==1) {
25701 $this->DivLn($table['margin']['T'],$this->blklvl,true,1); // collapsible
25702 }
25703 else {
25704 $this->y += ($table['margin']['T']);
25705 }
25706 }
25707 // Advance down page by half width of top border
25708 if ($table['borders_separate']) {
25709 if ($startrow>0 && (!isset($table['is_thead']) || count($table['is_thead'])==0))
25710 $adv = $table['border_spacing_V']/2;
25711 else
25712 $adv = $table['padding']['T'] + $table['border_details']['T']['w'] + $table['border_spacing_V']/2;
25713 }
25714 else {
25715 $adv = $table['max_cell_border_width']['T']/2;
25716 }
25717 if (!$this->table_rotate && $level==1) { $this->DivLn($adv); }
25718 else { $this->y += $adv; }
25719 }
25720
25721 if ($level==1) {
25722 $this->x = $this->lMargin + $this->blk[$this->blklvl]['outer_left_margin'] + $this->blk[$this->blklvl]['padding_left'] + $this->blk[$this->blklvl]['border_left']['w'];
25723 $x0 = $this->x;
25724 $y0 = $this->y;
25725 $right = $x0 + $this->blk[$this->blklvl]['inner_width'];
25726 $outerfilled = $this->y; // Keep track of how far down the outer DIV bgcolor is painted (NB rowspans)
25727 $this->outerfilled = $this->y;
25728 $this->colsums = array();
25729 }
25730 else {
25731 $x0 = $this->x;
25732 $y0 = $this->y;
25733 $right = $x0 + $table['w'];
25734 }
25735
25736 if ($this->table_rotate) {
25737 $temppgwidth = $this->tbrot_maxw;
25738 $this->PageBreakTrigger = $pagetrigger = $y0 + ($this->blk[$this->blklvl]['inner_width']);
25739 if ($level==1) {
25740 $this->tbrot_y0 = $this->y - $adv - $table['margin']['T'] ;
25741 $this->tbrot_x0 = $this->x;
25742 $this->tbrot_w = $table['w'];
25743 if ($table['borders_separate']) { $this->tbrot_h = $table['margin']['T'] + $table['padding']['T'] + $table['border_details']['T']['w'] + $table['border_spacing_V']/2; }
25744 else { $this->tbrot_h = $table['margin']['T'] + $table['padding']['T'] + $table['max_cell_border_width']['T']; }
25745 }
25746 }
25747 else {
25748 $this->PageBreakTrigger = $pagetrigger = ($this->h - $this->bMargin);
25749 if ($level==1) {
25750 $temppgwidth = $this->blk[$this->blklvl]['inner_width'];
25751 if (isset($table['a']) and ($table['w'] < $this->blk[$this->blklvl]['inner_width'])) {
25752 if ($table['a']=='C') { $x0 += ((($right-$x0) - $table['w'])/2); }
25753 else if ($table['a']=='R') { $x0 = $right - $table['w']; }
25754 }
25755 }
25756 else {
25757 $temppgwidth = $table['w'];
25758 }
25759 }
25760 if(!isset($table['overflow'])) { $table['overflow'] = null; }
25761 if ($table['overflow']=='hidden' && $level==1 && !$this->table_rotate && !$this->ColActive) {
25762 //Bounding rectangle to clip
25763 $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);
25764 $this->_out($this->tableClipPath);
25765 }
25766 else { $this->tableClipPath = ''; }
25767
25768
25769 if ($table['borders_separate']) { $indent = $table['margin']['L'] + $table['border_details']['L']['w'] + $table['padding']['L'] + $table['border_spacing_H']/2; }
25770 else { $indent = $table['margin']['L'] + $table['max_cell_border_width']['L']/2; }
25771 $x0 += $indent;
25772
25773 $returny = 0;
25774 $lastCol = 0;
25775 $tableheader = array();
25776 $tablefooter = array();
25777 $tableheaderrowheight = 0;
25778 $tablefooterrowheight = 0;
25779 $footery = 0;
25780
25781 // mPD 3.0 Set the Page & Column where table starts
25782 if (($this->mirrorMargins) && (($this->page)%2==0)) { // EVEN
25783 $tablestartpage = 'EVEN';
25784 }
25785 else if (($this->mirrorMargins) && (($this->page)%2==1)) { // ODD
25786 $tablestartpage = 'ODD';
25787 }
25788 else { $tablestartpage = ''; }
25789 if ($this->ColActive) { $tablestartcolumn = $this->CurrCol; }
25790 else { $tablestartcolumn = ''; }
25791
25792 if ($this->cacheTables) { $fh = fopen($table['cache'], "r+b"); }
25793 else { $fh = null; }
25794
25795 $y = $h = 0;
25796 for( $i = 0; $i < $numrows ; $i++ ) { //Rows
25797 if ($this->progressBar) { $this->UpdateProgressBar(7,intval(30 + ($i*40/$numrows)),' '); } // *PROGRESS-BAR*
25798 if (isset($table['is_tfoot'][$i]) && $table['is_tfoot'][$i] && $level==1) {
25799 $tablefooterrowheight += $table['hr'][$i];
25800 $tablefooter[$i][0]['trbackground-images'] = $table['trbackground-images'][$i];
25801 $tablefooter[$i][0]['trgradients'] = $table['trgradients'][$i];
25802 $tablefooter[$i][0]['trbgcolor'] = $table['bgcolor'][$i];
25803 for( $j = $startcol ; $j < $numcols ; $j++ ) { //Columns
25804 if (isset($cells[$i][$j]) && $cells[$i][$j]) {
25805 if ($this->cacheTables) {
25806 $cell = $this->_uncacheCell($table['cells'][$i][$j], '', $fh);
25807 }
25808 else
25809 $cell = &$cells[$i][$j];
25810 if ($split) {
25811 if ($table['colPg'][$j] != $splitpg) { continue; }
25812 list($x,$w) = $this->_splitTableGetWidth($table, $i, $j, $fh);
25813 $js = $j - $startcol;
25814 }
25815 else {
25816 list($x,$w) = $this->_tableGetWidth($table, $i, $j, $fh);
25817 $js = $j;
25818 }
25819
25820 list($y,$h) = $this->_tableGetHeight($table, $i, $j, $fh);
25821 $x += $x0;
25822 $y += $y0;
25823 //Get info of tfoot ==>> table footer
25824 $tablefooter[$i][$js]['x'] = $x;
25825 $tablefooter[$i][$js]['y'] = $y;
25826 $tablefooter[$i][$js]['h'] = $h;
25827 $tablefooter[$i][$js]['w'] = $w;
25828 if (isset($cell['textbuffer'])) { $tablefooter[$i][$js]['textbuffer'] = $cell['textbuffer']; }
25829 else { $tablefooter[$i][$js]['textbuffer'] = ''; }
25830 $tablefooter[$i][$js]['a'] = $cell['a'];
25831 $tablefooter[$i][$js]['R'] = $cell['R'];
25832 $tablefooter[$i][$js]['va'] = $cell['va'];
25833 $tablefooter[$i][$js]['mih'] = $cell['mih'];
25834 $tablefooter[$i][$js]['gradient'] = $cell['gradient']; // *BACKGROUNDS*
25835 $tablefooter[$i][$js]['background-image'] = $cell['background-image']; // *BACKGROUNDS*
25836 //CELL FILL BGCOLOR
25837 if (!$this->simpleTables){
25838 if ($this->packTableData) {
25839 $c = $this->_unpackCellBorder($cell['borderbin']);
25840 $tablefooter[$i][$js]['border'] = $c['border'];
25841 $tablefooter[$i][$js]['border_details'] = $c['border_details'];
25842 }
25843 else {
25844 $tablefooter[$i][$js]['border'] = $cell['border'];
25845 $tablefooter[$i][$js]['border_details'] = $cell['border_details'];
25846 }
25847 }
25848 else if ($this->simpleTables){
25849 $tablefooter[$i][$js]['border'] = $table['simple']['border'];
25850 $tablefooter[$i][$js]['border_details'] = $table['simple']['border_details'];
25851 }
25852 $tablefooter[$i][$js]['bgcolor'] = $cell['bgcolor'];
25853 $tablefooter[$i][$js]['padding'] = $cell['padding'];
25854 $tablefooter[$i][$js]['rowspan'] = $cell['rowspan'];
25855 $tablefooter[$i][$js]['colspan'] = $cell['colspan'];
25856 }
25857 }
25858 }
25859 }
25860
25861 if ($level==1) { $this->_out('___TABLE___BACKGROUNDS'.$this->uniqstr); }
25862 $tableheaderadj = 0;
25863 $tablefooteradj = 0;
25864
25865 $tablestartpageno = $this->page;
25866
25867 //Draw Table Contents and Borders
25868 for( $i = 0; $i < $numrows ; $i++ ) { //Rows
25869 if ($split && $startrow > 0) {
25870 $thnr = (isset($table['is_thead']) ? count($table['is_thead']) : 0);
25871 if ($i >= $thnr && $i < $startrow) { continue; }
25872 if ($i == $startrow){ $returny = $rety - $tableheaderrowheight; }
25873 }
25874
25875 // Get Maximum row/cell height in row - including rowspan>1 + 1 overlapping
25876 $maxrowheight = $this->_tableGetMaxRowHeight($table, $i, $fh);
25877
25878 $skippage = false;
25879 $newpagestarted = false;
25880 for( $j = $startcol ; $j < $numcols ; $j++ ) { //Columns
25881 if ($split) {
25882 if ($table['colPg'][$j] > $splitpg) { break; }
25883 $lastCol = $j;
25884 }
25885 if (isset($cells[$i][$j]) && $cells[$i][$j]) {
25886 if ($this->cacheTables) {
25887 $cell = $this->_uncacheCell($table['cells'][$i][$j], '', $fh);
25888 }
25889 else
25890 $cell = &$cells[$i][$j];
25891 if ($split) {
25892 $lastCol = $j + (isset($cell['colspan']) ? ($cell['colspan']-1) : 0) ;
25893 list($x,$w) = $this->_splitTableGetWidth($table, $i, $j, $fh);
25894 }
25895 else { list($x,$w) = $this->_tableGetWidth($table, $i, $j, $fh); }
25896
25897 list($y,$h) = $this->_tableGetHeight($table, $i, $j, $fh);
25898 $x += $x0;
25899 $y += $y0;
25900 $y -= $returny;
25901
25902 if ($table['borders_separate']) {
25903 if (!empty($tablefooter) || $i == ($numrows-1) || (isset($cell['rowspan']) && ($i+$cell['rowspan']) == $numrows) || (!isset($cell['rowspan']) && ($i+1) == $numrows) ) {
25904 $extra = $table['padding']['B'] + $table['border_details']['B']['w'] + $table['border_spacing_V']/2;
25905 //$extra = $table['margin']['B'] + $table['padding']['B'] + $table['border_details']['B']['w'] + $table['border_spacing_V']/2;
25906 }
25907 else {
25908 $extra = $table['border_spacing_V']/2;
25909 }
25910 }
25911 else { $extra = $table['max_cell_border_width']['B']/2; }
25912
25913 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 ) {
25914
25915 if (!$skippage) {
25916 $finalSpread = true;
25917 $firstSpread = true;
25918 if ($split) {
25919 for($t=$startcol; $t<$numcols; $t++) {
25920 // Are there more columns to print on a next page?
25921 if ($table['colPg'][$t] > $splitpg) {
25922 $finalSpread = false;
25923 break;
25924 }
25925 }
25926 if ($startcol>0) { $firstSpread = false; }
25927 }
25928
25929 if (($this->keepColumns || !$this->ColActive) && !empty($tablefooter) && $i > 0 ) {
25930 $this->y = $y;
25931 $ya = $this->y;
25932 $this->TableHeaderFooter($tablefooter,$tablestartpage,$tablestartcolumn,'F',$level, $firstSpread, $finalSpread);
25933 if ($this->table_rotate) {
25934 $this->tbrot_h += $this->y - $ya ;
25935 }
25936 $tablefooteradj = $this->y - $ya ;
25937 }
25938 $y -= $y0;
25939 $returny += $y;
25940
25941 $oldcolumn = $this->CurrCol;
25942 if ($this->AcceptPageBreak()) {
25943 $newpagestarted = true;
25944 $this->y = $y + $y0;
25945
25946 // Move down to account for border-spacing or
25947 // extra half border width in case page breaks in middle
25948 if($i>0 && !$this->table_rotate && $level==1 && !$this->ColActive) {
25949 if ($table['borders_separate']) {
25950 $adv = $table['border_spacing_V']/2;
25951 // If table footer
25952 if (($this->keepColumns || !$this->ColActive) && !empty($tablefooter) && $i > 0 ) {
25953 $adv += ($table['padding']['B'] + $table['border_details']['B']['w']);
25954 }
25955 }
25956 else {
25957 $maxbwtop = 0;
25958 $maxbwbottom = 0;
25959 if (!$this->simpleTables){
25960 if (!empty($tablefooter)) { $maxbwbottom = $table['max_cell_border_width']['B']; }
25961 else {
25962 $brow = $i-1;
25963 for( $ctj = 0 ; $ctj < $numcols ; $ctj++ ) {
25964 if (isset($cells[$brow][$ctj]) && $cells[$brow][$ctj]) {
25965 if ($this->cacheTables) {
25966 $cadj = $this->_uncacheCell($table['cells'][$brow][$ctj], '', $fh);
25967 list($bt,$br,$bb,$bl) = $this->_getBorderWidths($cadj['borderbin']);
25968 }
25969 else if ($this->packTableData) {
25970 list($bt,$br,$bb,$bl) = $this->_getBorderWidths($cells[$brow][$ctj]['borderbin']);
25971 }
25972 else {
25973 $bb = $cells[$brow][$ctj]['border_details']['B']['w'];
25974 }
25975 $maxbwbottom = max($maxbwbottom , $bb);
25976 }
25977 }
25978 }
25979 if (!empty($tableheader)) { $maxbwtop = $table['max_cell_border_width']['T']; }
25980 else {
25981 $trow = $i-1;
25982 for( $ctj = 0 ; $ctj < $numcols ; $ctj++ ) {
25983 if (isset($cells[$trow][$ctj]) && $cells[$trow][$ctj]) {
25984 if ($this->cacheTables) {
25985 $cadj = $this->_uncacheCell($table['cells'][$trow][$ctj], '', $fh);
25986 list($bt,$br,$bb,$bl) = $this->_getBorderWidths($cadj['borderbin']);
25987 }
25988 else if ($this->packTableData) {
25989 list($bt,$br,$bb,$bl) = $this->_getBorderWidths($cells[$trow][$ctj]['borderbin']);
25990 }
25991 else {
25992 $bt = $cells[$trow][$ctj]['border_details']['T']['w'];
25993 }
25994 $maxbwtop = max($maxbwtop , $bt);
25995 }
25996 }
25997 }
25998 }
25999 else if ($this->simpleTables){
26000 $maxbwtop = $table['simple']['border_details']['T']['w'];
26001 $maxbwbottom = $table['simple']['border_details']['B']['w'];
26002 }
26003 $adv = $maxbwbottom /2;
26004 }
26005 $this->y += $adv;
26006 }
26007
26008 // Rotated table split over pages - needs this->y for borders/backgrounds
26009 if($i>0 && $this->table_rotate && $level==1) {
26010 // $this->y = $y0 + $this->tbrot_w;
26011 }
26012
26013 if ($this->tableClipPath ) { $this->_out("Q"); }
26014
26015 $bx = $x0;
26016 $by = $y0;
26017
26018 if ($table['borders_separate']) {
26019 $bx -= ($table['padding']['L'] + $table['border_details']['L']['w'] + $table['border_spacing_H']/2);
26020 if ($tablestartpageno != $this->page) { // IF already broken across a previous pagebreak
26021 $by += $table['max_cell_border_width']['T']/2;
26022 if (empty($tableheader)) { $by -= ($table['border_spacing_V']/2); }
26023 }
26024 else {
26025 $by -= ($table['padding']['T'] + $table['border_details']['T']['w'] + $table['border_spacing_V']/2);
26026 }
26027 }
26028
26029 else if ($tablestartpageno != $this->page && !empty($tableheader)) { $by += $maxbwtop /2; }
26030
26031 $by -= $tableheaderadj;
26032 $bh = $this->y - $by + $tablefooteradj;
26033 if (!$table['borders_separate']) { $bh -= $adv ; }
26034 if ($split) {
26035 $bw = 0;
26036 for($t=$startcol; $t<$numcols; $t++) {
26037 if ($table['colPg'][$t] == $splitpg) { $bw += $table['wc'][$t]; }
26038 if ($table['colPg'][$t] > $splitpg) { break; }
26039 }
26040 if ($table['borders_separate']) {
26041 if ($firstSpread) {
26042 $bw += $table['padding']['L'] + $table['border_details']['L']['w'] + $table['border_spacing_H'];
26043 }
26044 else {
26045 $bx += ($table['padding']['L'] + $table['border_details']['L']['w']);
26046 $bw += $table['border_spacing_H'];
26047 }
26048 if ($finalSpread) {
26049 $bw += $table['padding']['R'] + $table['border_details']['R']['w']/2 + $table['border_spacing_H'];
26050 }
26051 }
26052 }
26053 else {
26054 $bw = $table['w'] - ($table['max_cell_border_width']['L']/2) - ($table['max_cell_border_width']['R']/2) - $table['margin']['L'] - $table['margin']['R'];
26055 }
26056
26057 // mPDF 5.4.16
26058 if ($this->splitTableBorderWidth && ($this->keepColumns || !$this->ColActive) && empty($tablefooter) && $i > 0 && $table['border_details']['B']['w']) {
26059 $prevDrawColor = $this->DrawColor;
26060 $lw = $this->LineWidth;
26061 $this->SetLineWidth($this->splitTableBorderWidth);
26062 $this->SetDColor($table['border_details']['B']['c']);
26063 $this->SetLineJoin(0);
26064 $this->SetLineCap(0);
26065 $blx = $bx;
26066 $blw = $bw;
26067 if (!$table['borders_separate']) {
26068 $blx -= ($table['max_cell_border_width']['L']/2);
26069 $blw += ($table['max_cell_border_width']['L']/2 + $table['max_cell_border_width']['R']/2);
26070 }
26071 $this->Line($blx,$this->y+($this->splitTableBorderWidth/2),$blx+$blw,$this->y+($this->splitTableBorderWidth/2));
26072 $this->DrawColor = $prevDrawColor;
26073 $this->_out($this->DrawColor);
26074 $this->SetLineWidth($lw);
26075 $this->SetLineJoin(2);
26076 $this->SetLineCap(2);
26077 }
26078
26079 if (!$this->ColActive && ($i > 0 || $j > 0)) {
26080 if (isset($table['bgcolor'][-1])) {
26081 $color = $this->ConvertColor($table['bgcolor'][-1]);
26082 if ($color) {
26083 if (!$table['borders_separate']) { $bh -= $table['max_cell_border_width']['B']/2; }
26084 $this->tableBackgrounds[$level*9][] = array('gradient'=>false, 'x'=>$bx, 'y'=>$by, 'w'=>$bw, 'h'=>$bh, 'col'=>$color);
26085 }
26086 }
26087
26088/*-- BACKGROUNDS --*/
26089 if (isset($table['gradient'])) {
26090 $g = $this->grad->parseBackgroundGradient($table['gradient']);
26091 if ($g) {
26092 $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'=>'');
26093 }
26094 }
26095
26096 if (isset($table['background-image'])) {
26097 if ($table['background-image']['gradient'] && preg_match('/(-moz-)*(repeating-)*(linear|radial)-gradient/', $table['background-image']['gradient'] )) {
26098 $g = $this->grad->parseMozGradient( $table['background-image']['gradient'] );
26099 if ($g) {
26100 $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'=>'');
26101 }
26102 }
26103 else {
26104 $image_id = $table['background-image']['image_id'];
26105 $orig_w = $table['background-image']['orig_w'];
26106 $orig_h = $table['background-image']['orig_h'];
26107 $x_pos = $table['background-image']['x_pos'];
26108 $y_pos = $table['background-image']['y_pos'];
26109 $x_repeat = $table['background-image']['x_repeat'];
26110 $y_repeat = $table['background-image']['y_repeat'];
26111 $resize = $table['background-image']['resize'];
26112 $opacity = $table['background-image']['opacity'];
26113 $itype = $table['background-image']['itype'];
26114 $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);
26115 }
26116 }
26117/*-- END BACKGROUNDS --*/
26118 }
26119
26120 // $this->AcceptPageBreak() has moved tablebuffer to $this->pages content
26121 if ($this->tableBackgrounds) {
26122 $s = $this->PrintTableBackgrounds();
26123 if ($this->bufferoutput) {
26124 $this->headerbuffer = preg_replace('/(___TABLE___BACKGROUNDS'.$this->uniqstr.')/', '\\1'."\n".$s."\n", $this->headerbuffer);
26125 $this->headerbuffer = preg_replace('/(___TABLE___BACKGROUNDS'.$this->uniqstr.')/', " ", $this->headerbuffer );
26126 }
26127 else {
26128 $this->pages[$this->page] = preg_replace('/(___TABLE___BACKGROUNDS'.$this->uniqstr.')/', '\\1'."\n".$s."\n", $this->pages[$this->page]);
26129 $this->pages[$this->page] = preg_replace('/(___TABLE___BACKGROUNDS'.$this->uniqstr.')/', " ", $this->pages[$this->page]);
26130 }
26131 $this->tableBackgrounds = array();
26132 }
26133
26134 if ($split) {
26135 if ($i == 0 && $j == 0) { $y0 = -1; }
26136 else if ($finalSpread) {
26137 $splitpg = 0;
26138 $startcol = 0;
26139 $startrow = $i;
26140 }
26141 else {
26142 $splitpg++;
26143 $startcol = $t;
26144 $returny -= $y;
26145 }
26146 return array(false, $startrow, $startcol, $splitpg, $returny, $y0);
26147 }
26148
26149 $this->AddPage($this->CurOrientation);
26150
26151 $this->_out('___TABLE___BACKGROUNDS'.$this->uniqstr);
26152
26153
26154 if ($this->tableClipPath ) { $this->_out($this->tableClipPath); }
26155
26156 // Added to correct for OddEven Margins
26157 $x= $x + $this->MarginCorrection;
26158 $x0= $x0 + $this->MarginCorrection;
26159
26160 // mPDF 5.4.16
26161 if ($this->splitTableBorderWidth && ($this->keepColumns || !$this->ColActive) && empty($tableheader) && $i > 0 && $table['border_details']['T']['w'] ) {
26162 $prevDrawColor = $this->DrawColor;
26163 $lw = $this->LineWidth;
26164 $this->SetLineWidth($this->splitTableBorderWidth);
26165 $this->SetDColor($table['border_details']['T']['c']);
26166 $this->SetLineJoin(0);
26167 $this->SetLineCap(0);
26168 $blx += $this->MarginCorrection;
26169 $this->Line($blx,$this->y-($this->splitTableBorderWidth/2),$blx+$blw,$this->y-($this->splitTableBorderWidth/2));
26170 $this->DrawColor = $prevDrawColor;
26171 $this->_out($this->DrawColor);
26172 $this->SetLineWidth($lw);
26173 $this->SetLineJoin(2);
26174 $this->SetLineCap(2);
26175 }
26176
26177 // Move down to account for half of top border-spacing or
26178 // extra half border width in case page was broken in middle
26179 if($i>0 && !$this->table_rotate && $level==1 && $table['headernrows']==0) {
26180 if ($table['borders_separate']) { $adv = $table['border_spacing_V']/2; }
26181 else {
26182 $maxbwtop = 0;
26183 for( $ctj = 0 ; $ctj < $numcols ; $ctj++ ) {
26184 if (isset($cells[$i][$ctj]) && $cells[$i][$ctj]) {
26185 if (!$this->simpleTables){
26186 if ($this->cacheTables) {
26187 $celltj = $this->_uncacheCell($table['cells'][$i][$ctj], '', $fh);
26188 list($bt,$br,$bb,$bl) = $this->_getBorderWidths($celltj['borderbin']);
26189 }
26190 else if ($this->packTableData) {
26191 list($bt,$br,$bb,$bl) = $this->_getBorderWidths($cells[$i][$ctj]['borderbin']);
26192 }
26193 else {
26194 $bt = $cells[$i][$ctj]['border_details']['T']['w'];
26195 }
26196 $maxbwtop = max($maxbwtop, $bt);
26197 }
26198 else if ($this->simpleTables){
26199 $maxbwtop = max($maxbwtop, $table['simple']['border_details']['T']['w']);
26200 }
26201 }
26202 }
26203 $adv = $maxbwtop /2;
26204 }
26205 $this->y += $adv;
26206 }
26207
26208
26209 if ($this->table_rotate) {
26210 $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'];
26211 if ($table['borders_separate']) { $this->tbrot_h = $table['margin']['T'] + $table['padding']['T'] + $table['border_details']['T']['w'] + $table['border_spacing_V']/2; }
26212 else { $this->tbrot_h = $table['margin']['T'] + $table['max_cell_border_width']['T'] ; }
26213 $this->tbrot_y0 = $this->y;
26214 $pagetrigger = $y0 - $tableheaderadj + ($this->blk[$this->blklvl]['inner_width']);
26215 }
26216 else {
26217 $pagetrigger = $this->PageBreakTrigger;
26218 }
26219
26220 if ($this->kwt_saved && $level==1) {
26221 $this->kwt_moved = true;
26222 }
26223
26224
26225 // Disable Table header repeat if Keep Block together
26226 if (!$this->keep_block_together && !empty($tableheader)) {
26227 $ya = $this->y;
26228 $this->TableHeaderFooter($tableheader,$tablestartpage,$tablestartcolumn,'H',$level);
26229 if ($this->table_rotate) {
26230 $this->tbrot_h = $this->y - $ya ;
26231 }
26232 $tableheaderadj = $this->y - $ya ;
26233 }
26234
26235 else if ($i==0 && !$this->keep_block_together && !$this->table_rotate && $level==1 && !$this->ColActive) {
26236 // Advance down page
26237 if ($table['borders_separate']) { $adv = $table['border_spacing_V']/2 + $table['border_details']['T']['w'] + $table['padding']['T']; }
26238 else { $adv = $table['max_cell_border_width']['T'] /2 ; }
26239 if ($adv) {
26240 if ($this->table_rotate) {
26241 $this->y += ($adv);
26242 }
26243 else {
26244 $this->DivLn($adv,$this->blklvl,true);
26245 }
26246 }
26247 }
26248
26249 $outerfilled = 0;
26250 $y = $y0 = $this->y;
26251 }
26252
26253/*-- COLUMNS --*/
26254 // COLS
26255 // COLUMN CHANGE
26256 if ($this->CurrCol != $oldcolumn) {
26257 // Added to correct for Columns
26258 $x += $this->ChangeColumn * ($this->ColWidth+$this->ColGap);
26259 $x0 += $this->ChangeColumn * ($this->ColWidth+$this->ColGap);
26260 if ($this->CurrCol == 0) { // just added a page - possibly with tableheader
26261 $y0 = $this->y; // this->y0 is global used by Columns - $y0 is internal to tablewrite
26262 }
26263 else {
26264 $y0 = $this->y0; // this->y0 is global used by Columns - $y0 is internal to tablewrite
26265 }
26266 $y = $y0;
26267 $outerfilled = 0;
26268 if ($this->CurrCol != 0 && ($this->keepColumns && $this->ColActive) && !empty($tableheader) && $i > 0 ) {
26269 $this->x = $x;
26270 $this->y = $y;
26271 $this->TableHeaderFooter($tableheader,$tablestartpage,$tablestartcolumn,'H',$level);
26272 $y0 = $y=$this->y;
26273 }
26274 }
26275/*-- END COLUMNS --*/
26276 }
26277 $skippage = true;
26278 }
26279
26280 $this->x = $x;
26281 $this->y = $y;
26282
26283 if ($this->kwt_saved && $level==1) {
26284 $this->printkwtbuffer();
26285 $x0 = $x = $this->x;
26286 $y0 = $y = $this->y;
26287 $this->kwt_moved = false;
26288 $this->kwt_saved = false;
26289 }
26290
26291
26292 // Set the Page & Column where table actually starts
26293 if ($i==0 && $j==0 && $level==1) {
26294 if (($this->mirrorMargins) && (($this->page)%2==0)) { // EVEN
26295 $tablestartpage = 'EVEN';
26296 }
26297 else if (($this->mirrorMargins) && (($this->page)%2==1)) { // ODD
26298 $tablestartpage = 'ODD';
26299 }
26300 else { $tablestartpage = ''; }
26301 $tablestartpageno = $this->page;
26302 if ($this->ColActive) { $tablestartcolumn = $this->CurrCol; } // *COLUMNS*
26303 }
26304
26305
26306 //ALIGN
26307 $align = $cell['a'];
26308
26309
26310/*-- COLUMNS --*/
26311 // If outside columns, this is done in PaintDivBB
26312 if ($this->ColActive) {
26313 //OUTER FILL BGCOLOR of DIVS
26314 if ($this->blklvl > 0 && ($j==0) && !$this->table_rotate && $level==1) {
26315 $firstblockfill = $this->GetFirstBlockFill();
26316 if ($firstblockfill && $this->blklvl >= $firstblockfill) {
26317 $divh = $maxrowheight;
26318 // Last row
26319 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
26320 if ($table['borders_separate']) {
26321 $adv = $table['margin']['B'] + $table['padding']['B'] + $table['border_details']['B']['w'] + $table['border_spacing_V']/2;
26322 }
26323 else {
26324 $adv = $table['margin']['B'] + $table['max_cell_border_width']['B']/2;
26325 }
26326 $divh += $adv; //last row: fill bottom half of bottom border (y advanced at end)
26327 }
26328
26329 if (($this->y + $divh) > $outerfilled ) { // if not already painted by previous rowspan
26330 $bak_x = $this->x;
26331 $bak_y = $this->y;
26332 if ($outerfilled > $this->y) {
26333 $divh = ($this->y + $divh) - $outerfilled;
26334 $this->y = $outerfilled;
26335 }
26336
26337 $this->DivLn($divh,-3,false);
26338 $outerfilled = $this->y + $divh;
26339 // Reset current block fill
26340 $bcor = $this->blk[$this->blklvl]['bgcolorarray'];
26341 if ($bcor ) $this->SetFColor($bcor);
26342 $this->x = $bak_x;
26343 $this->y = $bak_y;
26344 }
26345 }
26346 }
26347 }
26348
26349
26350 //TABLE BACKGROUND FILL BGCOLOR - for cellSpacing
26351 if ($this->ColActive) {
26352 if ($table['borders_separate']) {
26353 $fill = isset($table['bgcolor'][-1]) ? $table['bgcolor'][-1] : 0;
26354 if ($fill) {
26355 $color = $this->ConvertColor($fill);
26356 if ($color) {
26357 $xadj = ($table['border_spacing_H']/2);
26358 $yadj = ($table['border_spacing_V']/2);
26359 $wadj = $table['border_spacing_H'];
26360 $hadj = $table['border_spacing_V'];
26361 if ($i == 0) { // Top
26362 $yadj += $table['padding']['T'] + $table['border_details']['T']['w'] ;
26363 $hadj += $table['padding']['T'] + $table['border_details']['T']['w'] ;
26364 }
26365 if ($j == 0) { // Left
26366 $xadj += $table['padding']['L'] + $table['border_details']['L']['w'] ;
26367 $wadj += $table['padding']['L'] + $table['border_details']['L']['w'] ;
26368 }
26369 if ($i == ($numrows-1) || (isset($cell['rowspan']) && ($i+$cell['rowspan']) == $numrows) || (!isset($cell['rowspan']) && ($i+1) == $numrows)) { // Bottom
26370 $hadj += $table['padding']['B'] + $table['border_details']['B']['w'] ;
26371 }
26372 if ($j == ($numcols-1) || (isset($cell['colspan']) && ($j+$cell['colspan']) == $numcols) || (!isset($cell['colspan']) && ($j+1) == $numcols)) { // Right
26373 $wadj += $table['padding']['R'] + $table['border_details']['R']['w'] ;
26374 }
26375 $this->SetFColor($color);
26376 $this->Rect($x - $xadj, $y - $yadj, $w + $wadj, $h + $hadj, 'F');
26377 }
26378 }
26379 }
26380 }
26381/*-- END COLUMNS --*/
26382
26383 if ($table['empty_cells']!='hide' || !empty($cell['textbuffer']) || (isset($cell['nestedcontent']) && $cell['nestedcontent']) || !$table['borders_separate'] ) { $paintcell = true; }
26384 else { $paintcell = false; }
26385
26386 //Set Borders
26387 $bord = 0;
26388 $bord_det = array();
26389
26390 if (!$this->simpleTables){
26391 if ($this->packTableData) {
26392 if ($cell['borderbin']) {
26393 $c = $this->_unpackCellBorder($cell['borderbin']);
26394 $bord = $c['border'];
26395 $bord_det = $c['border_details'];
26396 }
26397 }
26398 else if ($cell['border']) {
26399 $bord = $cell['border'];
26400 $bord_det = $cell['border_details'];
26401 }
26402 }
26403 else if ($this->simpleTables){
26404 if ($table['simple']['border']) {
26405 $bord = $table['simple']['border'];
26406 $bord_det = $table['simple']['border_details'];
26407 }
26408 }
26409
26410 //TABLE ROW OR CELL FILL BGCOLOR
26411 $fill = 0;
26412 if (isset($cell['bgcolor']) && $cell['bgcolor'] && $cell['bgcolor']!='transparent') {
26413 $fill = $cell['bgcolor'];
26414 $leveladj = 6;
26415 }
26416 else if (isset($table['bgcolor'][$i]) && $table['bgcolor'][$i] && $table['bgcolor'][$i]!='transparent') { // Row color
26417 $fill = $table['bgcolor'][$i];
26418 $leveladj = 3;
26419 }
26420 if ($fill && $paintcell) {
26421 $color = $this->ConvertColor($fill);
26422 if ($color) {
26423 if ($table['borders_separate']) {
26424 if ($this->ColActive) {
26425 $this->SetFColor($color);
26426 $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');
26427 }
26428 else {
26429 $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);
26430 }
26431 }
26432 else {
26433 if ($this->ColActive) {
26434 $this->SetFColor($color);
26435 $this->Rect($x, $y, $w, $h, 'F');
26436 }
26437 else {
26438 $this->tableBackgrounds[$level*9+$leveladj][] = array('gradient'=>false, 'x'=>$x, 'y'=>$y, 'w'=>$w, 'h'=>$h, 'col'=>$color);
26439 }
26440 }
26441 }
26442 }
26443
26444/*-- BACKGROUNDS --*/
26445 if (isset($cell['gradient']) && $cell['gradient'] && $paintcell){
26446 $g = $this->grad->parseBackgroundGradient($cell['gradient']);
26447 if ($g) {
26448 if ($table['borders_separate']) {
26449 $px = $x+ ($table['border_spacing_H']/2);
26450 $py = $y+ ($table['border_spacing_V']/2);
26451 $pw = $w- $table['border_spacing_H'];
26452 $ph = $h- $table['border_spacing_V'];
26453 }
26454 else {
26455 $px = $x;
26456 $py = $y;
26457 $pw = $w;
26458 $ph = $h;
26459 }
26460 if ($this->ColActive) {
26461 $this->grad->Gradient($px, $py, $pw, $ph, $g['type'], $g['stops'], $g['colorspace'], $g['coords'], $g['extend']);
26462 }
26463 else {
26464 $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'=>'');
26465 }
26466 }
26467 }
26468
26469 if (isset($cell['background-image']) && $paintcell) {
26470 if ($cell['background-image']['gradient'] && preg_match('/(-moz-)*(repeating-)*(linear|radial)-gradient/', $cell['background-image']['gradient'] )) {
26471 $g = $this->grad->parseMozGradient( $cell['background-image']['gradient'] );
26472 if ($g) {
26473 if ($table['borders_separate']) {
26474 $px = $x+ ($table['border_spacing_H']/2);
26475 $py = $y+ ($table['border_spacing_V']/2);
26476 $pw = $w- $table['border_spacing_H'];
26477 $ph = $h- $table['border_spacing_V'];
26478 }
26479 else {
26480 $px = $x;
26481 $py = $y;
26482 $pw = $w;
26483 $ph = $h;
26484 }
26485 if ($this->ColActive) {
26486 $this->grad->Gradient($px, $py, $pw, $ph, $g['type'], $g['stops'], $g['colorspace'], $g['coords'], $g['extend']);
26487 }
26488 else {
26489 $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'=>'');
26490 }
26491 }
26492 }
26493 else if ($cell['background-image']['image_id']) { // Background pattern
26494 $n = count($this->patterns)+1;
26495 if ($table['borders_separate']) {
26496 $px = $x+ ($table['border_spacing_H']/2);
26497 $py = $y+ ($table['border_spacing_V']/2);
26498 $pw = $w- $table['border_spacing_H'];
26499 $ph = $h- $table['border_spacing_V'];
26500 }
26501 else {
26502 $px = $x;
26503 $py = $y;
26504 $pw = $w;
26505 $ph = $h;
26506 }
26507 if ($this->ColActive) {
26508 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']);
26509 $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);
26510 if ($cell['background-image']['opacity']>0 && $cell['background-image']['opacity']<1) { $opac = $this->SetAlpha($cell['background-image']['opacity'],'Normal',true); }
26511 else { $opac = ''; }
26512 $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));
26513 }
26514 else {
26515 $image_id = $cell['background-image']['image_id'];
26516 $orig_w = $cell['background-image']['orig_w'];
26517 $orig_h = $cell['background-image']['orig_h'];
26518 $x_pos = $cell['background-image']['x_pos'];
26519 $y_pos = $cell['background-image']['y_pos'];
26520 $x_repeat = $cell['background-image']['x_repeat'];
26521 $y_repeat = $cell['background-image']['y_repeat'];
26522 $resize = $cell['background-image']['resize'];
26523 $opacity = $cell['background-image']['opacity'];
26524 $itype = $cell['background-image']['itype'];
26525 $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);
26526 }
26527 }
26528 }
26529/*-- END BACKGROUNDS --*/
26530
26531 if (isset($cell['colspan']) && $cell['colspan']>1) { $ccolsp = $cell['colspan']; }
26532 else { $ccolsp = 1; }
26533 if (isset($cell['rowspan']) && $cell['rowspan']>1) { $crowsp = $cell['rowspan']; }
26534 else { $crowsp = 1; }
26535
26536
26537 // but still need to do this for repeated headers...
26538 if (!$table['borders_separate'] && $this->tabletheadjustfinished && !$this->simpleTables){
26539 if (isset($table['topntail']) && $table['topntail']) {
26540 $bord_det['T'] = $this->border_details($table['topntail']);
26541 $bord_det['T']['w'] /= $this->shrin_k;
26542 $this->setBorder($bord, _BORDER_TOP);
26543 }
26544 if (isset($table['thead-underline']) && $table['thead-underline']) {
26545 $bord_det['T'] = $this->border_details($table['thead-underline']);
26546 $bord_det['T']['w'] /= $this->shrin_k;
26547 $this->setBorder($bord, _BORDER_TOP);
26548 }
26549 }
26550
26551
26552 //Get info of first row ==>> table header
26553 //Use > 1 row if THEAD
26554 if (isset($table['is_thead'][$i]) && $table['is_thead'][$i] && $level==1) {
26555 if ($j==0) $tableheaderrowheight += $table['hr'][$i];
26556 $tableheader[$i][0]['trbackground-images'] = (isset($table['trbackground-images'][$i]) ? $table['trbackground-images'][$i] : null);
26557 $tableheader[$i][0]['trgradients'] = (isset($table['trgradients'][$i]) ? $table['trgradients'][$i] : null);
26558 $tableheader[$i][0]['trbgcolor'] = (isset($table['bgcolor'][$i]) ? $table['bgcolor'][$i] : null);
26559 $tableheader[$i][$j]['x'] = $x;
26560 $tableheader[$i][$j]['y'] = $y;
26561 $tableheader[$i][$j]['h'] = $h;
26562 $tableheader[$i][$j]['w'] = $w;
26563 if (isset($cell['textbuffer'])) { $tableheader[$i][$j]['textbuffer'] = $cell['textbuffer']; }
26564 else { $tableheader[$i][$j]['textbuffer'] = ''; }
26565 $tableheader[$i][$j]['a'] = $cell['a'];
26566 $tableheader[$i][$j]['R'] = $cell['R'];
26567
26568 $tableheader[$i][$j]['va'] = $cell['va'];
26569 $tableheader[$i][$j]['mih'] = $cell['mih'];
26570 $tableheader[$i][$j]['gradient'] = (isset($cell['gradient']) ? $cell['gradient'] : null); // *BACKGROUNDS*
26571 $tableheader[$i][$j]['background-image'] = (isset($cell['background-image']) ? $cell['background-image'] : null); // *BACKGROUNDS*
26572 $tableheader[$i][$j]['rowspan'] = (isset($cell['rowspan']) ? $cell['rowspan'] : null);
26573 $tableheader[$i][$j]['colspan'] = (isset($cell['colspan']) ? $cell['colspan'] : null);
26574 $tableheader[$i][$j]['bgcolor'] = $cell['bgcolor'];
26575
26576 if (!$this->simpleTables){
26577 $tableheader[$i][$j]['border'] = $bord;
26578 $tableheader[$i][$j]['border_details'] = $bord_det;
26579 }
26580 else if ($this->simpleTables){
26581 $tableheader[$i][$j]['border'] = $table['simple']['border'];
26582 $tableheader[$i][$j]['border_details'] = $table['simple']['border_details'];
26583 }
26584 $tableheader[$i][$j]['padding'] = $cell['padding'];
26585 }
26586
26587 // CELL BORDER
26588 if ($bord || $bord_det) {
26589 if ($table['borders_separate'] && $paintcell) {
26590 $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']);
26591 }
26592 else if (!$table['borders_separate']) {
26593 $this->_tableRect($x, $y, $w, $h, $bord, $bord_det, true, $table['borders_separate']); // true causes buffer
26594 }
26595
26596 }
26597
26598 //VERTICAL ALIGN
26599 if ($cell['R'] && INTVAL($cell['R']) > 0 && INTVAL($cell['R']) < 90 && isset($cell['va']) && $cell['va']!='B') { $cell['va']='B';}
26600 if (!isset($cell['va']) || $cell['va']=='M') $this->y += ($h-$cell['mih'])/2;
26601 elseif (isset($cell['va']) && $cell['va']=='B') $this->y += $h-$cell['mih'];
26602
26603 // NESTED CONTENT
26604
26605 // TEXT (and nested tables)
26606 $this->divalign=$align;
26607
26608 $this->divwidth=$w;
26609 if (!empty($cell['textbuffer'])) {
26610 if ($level==1) {
26611 if (isset($table['is_tfoot'][$i]) && $table['is_tfoot'][$i]) {
26612 if (preg_match('/{colsum([0-9]*)[_]*}/', $cell['textbuffer'][0][0], $m)) {
26613 $rep = sprintf("%01.".intval($m[1])."f", $this->colsums[$j]);
26614 $cell['textbuffer'][0][0] = preg_replace('/{colsum[0-9_]*}/', $rep ,$cell['textbuffer'][0][0]);
26615 }
26616 }
26617 else if (!isset($table['is_thead'][$i])) { $this->colsums[$j] += floatval(preg_replace('/^[^0-9\.\,]*/','',$cell['textbuffer'][0][0])); } // mPDF 5.6.66
26618 }
26619 $opy = $this->y;
26620 // mPDF ITERATION
26621 if ($this->iterationCounter) {
26622 foreach($cell['textbuffer'] AS $k=>$t) {
26623 if (preg_match('/{iteration ([a-zA-Z0-9_]+)}/',$t[0], $m)) {
26624 $vname = '__'.$m[1].'_';
26625 if (!isset($this->$vname)) { $this->$vname = 1; }
26626 else { $this->$vname++; }
26627 $cell['textbuffer'][$k][0] = preg_replace('/{iteration '.$m[1].'}/', $this->$vname, $cell['textbuffer'][$k][0]);
26628 }
26629 }
26630 }
26631
26632
26633 if ($cell['R']) {
26634 $cellPtSize = $cell['textbuffer'][0][11] / $this->shrin_k;
26635 if (!$cellPtSize) { $cellPtSize = $this->default_font_size; }
26636 $cellFontHeight = ($cellPtSize/_MPDFK);
26637 $opx = $this->x;
26638 $angle = INTVAL($cell['R']);
26639 // Only allow 45 to 89 degrees (when bottom-aligned) or exactly 90 or -90
26640 if ($angle > 90) { $angle = 90; }
26641 else if ($angle > 0 && $angle <45) { $angle = 45; }
26642 else if ($angle < 0) { $angle = -90; }
26643 $offset = ((sin(deg2rad($angle))) * 0.37 * $cellFontHeight);
26644 if (isset($cell['a']) && $cell['a']=='R') {
26645 $this->x += ($w) + ($offset) - ($cellFontHeight/3) - ($cell['padding']['R'] + ($table['border_spacing_H']/2));
26646 }
26647 else if (!isset($cell['a']) || $cell['a']=='C') {
26648 $this->x += ($w/2) + ($offset);
26649 }
26650 else {
26651 $this->x += ($offset) + ($cellFontHeight/3)+($cell['padding']['L'] +($table['border_spacing_H']/2));
26652 }
26653 $str = '';
26654 foreach($cell['textbuffer'] AS $t) { $str .= $t[0].' '; }
26655 $str = trim($str);
26656 if (!isset($cell['va']) || $cell['va']=='M') {
26657 $this->y -= ($h-$cell['mih'])/2; //Undo what was added earlier VERTICAL ALIGN
26658 if ($angle > 0) { $this->y += (($h-$cell['mih'])/2) + $cell['padding']['T'] + ($cell['mih']-($cell['padding']['T'] + $cell['padding']['B'])); }
26659 else if ($angle < 0) { $this->y += (($h-$cell['mih'])/2)+ ($cell['padding']['T'] + ($table['border_spacing_V']/2)); }
26660 }
26661 elseif (isset($cell['va']) && $cell['va']=='B') {
26662 $this->y -= $h-$cell['mih']; //Undo what was added earlier VERTICAL ALIGN
26663 if ($angle > 0) { $this->y += $h-($cell['padding']['B'] + ($table['border_spacing_V']/2)); }
26664 else if ($angle < 0) { $this->y += $h-$cell['mih'] + ($cell['padding']['T'] + ($table['border_spacing_V']/2)); }
26665 }
26666 elseif (isset($cell['va']) && $cell['va']=='T') {
26667 if ($angle > 0) { $this->y += $cell['mih']-($cell['padding']['B'] + ($table['border_spacing_V']/2)); }
26668 else if ($angle < 0) { $this->y += ($cell['padding']['T'] + ($table['border_spacing_V']/2)); }
26669 }
26670 $this->Rotate($angle,$this->x,$this->y);
26671 $s_fs = $this->FontSizePt;
26672 $s_f = $this->FontFamily;
26673 $s_st = $this->FontStyle;
26674 if (!empty($cell['textbuffer'][0][3])) { //Font Color
26675 $cor = $cell['textbuffer'][0][3];
26676 $this->SetTColor($cor);
26677 }
26678 $s_str = $this->strike;
26679 $this->strike = $cell['textbuffer'][0][8]; //Strikethrough
26680 $this->SetFont($cell['textbuffer'][0][4],$cell['textbuffer'][0][2],$cellPtSize,true,true);
26681 $this->Text($this->x,$this->y,$str);
26682 $this->Rotate(0);
26683 $this->SetFont($s_f,$s_st,$s_fs,true,true);
26684 $this->SetTColor(0);
26685 $this->strike = $s_str;
26686 $this->x = $opx;
26687 }
26688 else {
26689
26690 if (!$this->simpleTables){
26691 if ($bord_det) {
26692 $btlw = $bord_det['L']['w'];
26693 $btrw = $bord_det['R']['w'];
26694 $bttw = $bord_det['T']['w'];
26695 }
26696 else {
26697 $btlw = 0;
26698 $btrw = 0;
26699 $bttw = 0;
26700 }
26701 if ($table['borders_separate']) {
26702 $xadj = $btlw + $cell['padding']['L'] +($table['border_spacing_H']/2);
26703 $wadj = $btlw + $btrw + $cell['padding']['L'] +$cell['padding']['R'] + $table['border_spacing_H'];
26704 $yadj = $bttw + $cell['padding']['T'] + ($table['border_spacing_H']/2);
26705 }
26706 else {
26707 $xadj = $btlw/2 + $cell['padding']['L'];
26708 $wadj = ($btlw + $btrw)/2 + $cell['padding']['L'] + $cell['padding']['R'];
26709 $yadj = $bttw/2 + $cell['padding']['T'];
26710 }
26711 }
26712 else if ($this->simpleTables){
26713 if ($table['borders_separate']) { // NB twice border width
26714 $xadj = $table['simple']['border_details']['L']['w'] + $cell['padding']['L'] +($table['border_spacing_H']/2);
26715 $wadj = $table['simple']['border_details']['L']['w'] + $table['simple']['border_details']['R']['w'] + $cell['padding']['L'] +$cell['padding']['R'] + $table['border_spacing_H'];
26716 $yadj = $table['simple']['border_details']['T']['w'] + $cell['padding']['T'] + ($table['border_spacing_H']/2);
26717 }
26718 else {
26719 $xadj = $table['simple']['border_details']['L']['w']/2 + $cell['padding']['L'];
26720 $wadj = ($table['simple']['border_details']['L']['w'] + $table['simple']['border_details']['R']['w'])/2 + $cell['padding']['L'] + $cell['padding']['R'];
26721 $yadj = $table['simple']['border_details']['T']['w']/2 + $cell['padding']['T'];
26722 }
26723 }
26724 // mPDF 5.6.13
26725 $this->decimal_offset = 0;
26726 if(substr($cell['a'],0,1) == 'D') {
26727 if ($cell['colspan'] > 1) { $this->divalign = $c['a'] = substr($cell['a'],2,1); }
26728 else {
26729 $smax = $table['decimal_align'][$j]['maxs0'];
26730 $d_content = $table['decimal_align'][$j]['maxs0'] + $table['decimal_align'][$j]['maxs1'];
26731 $this->decimal_offset = $smax;
26732 $extra = ($w - $d_content - $wadj);
26733 if ($extra > 0) {
26734 if(substr($cell['a'],2,1) == 'R') { $this->decimal_offset += $extra; }
26735 else if(substr($cell['a'],2,1) == 'C') { $this->decimal_offset += ($extra)/2; }
26736 }
26737 }
26738 }
26739 $this->divwidth=$w-$wadj;
26740 if ($this->divwidth == 0) { $this->divwidth = 0.0001; }
26741 $this->x += $xadj;
26742 $this->y += $yadj;
26743 $this->printbuffer($cell['textbuffer'],'',true);
26744 }
26745 $this->y = $opy;
26746 }
26747
26748/*-- BACKGROUNDS --*/
26749 if (!$this->ColActive) {
26750 if (isset($table['trgradients'][$i]) && ($j==0 || $table['borders_separate'])) {
26751 $g = $this->grad->parseBackgroundGradient($table['trgradients'][$i]);
26752 if ($g) {
26753 $gx = $x0;
26754 $gy = $y;
26755 $gh = $h;
26756 $gw = $table['w'] - ($table['max_cell_border_width']['L']/2) - ($table['max_cell_border_width']['R']/2) - $table['margin']['L'] - $table['margin']['R'];
26757 if ($table['borders_separate']) {
26758 $gw -= ($table['padding']['L'] + $table['border_details']['L']['w'] + $table['padding']['R'] + $table['border_details']['R']['w'] + $table['border_spacing_H']);
26759 $s = '';
26760 $clx = $x+ ($table['border_spacing_H']/2);
26761 $cly = $y+ ($table['border_spacing_V']/2);
26762 $clw = $w- $table['border_spacing_H'];
26763 $clh = $h- $table['border_spacing_V'];
26764 // Set clipping path
26765 $s = ' q 0 w '; // Line width=0
26766 $s .= sprintf('%.3F %.3F m ', ($clx)*_MPDFK, ($this->h-($cly))*_MPDFK); // start point TL before the arc
26767 $s .= sprintf('%.3F %.3F l ', ($clx)*_MPDFK, ($this->h-($cly+$clh))*_MPDFK); // line to BL
26768 $s .= sprintf('%.3F %.3F l ', ($clx+$clw)*_MPDFK, ($this->h-($cly+$clh))*_MPDFK); // line to BR
26769 $s .= sprintf('%.3F %.3F l ', ($clx+$clw)*_MPDFK, ($this->h-($cly))*_MPDFK); // line to TR
26770 $s .= sprintf('%.3F %.3F l ', ($clx)*_MPDFK, ($this->h-($cly))*_MPDFK); // line to TL
26771 $s .= ' W n '; // Ends path no-op & Sets the clipping path
26772 $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);
26773 }
26774 else {
26775 $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'=>'');
26776 }
26777 }
26778 }
26779 if (isset($table['trbackground-images'][$i]) && ($j==0 || $table['borders_separate'])) {
26780 if ($table['trbackground-images'][$i]['gradient'] && preg_match('/(-moz-)*(repeating-)*(linear|radial)-gradient/', $table['trbackground-images'][$i]['gradient'] )) {
26781 $g = $this->grad->parseMozGradient( $table['trbackground-images'][$i]['gradient'] );
26782 if ($g) {
26783 $gx = $x0;
26784 $gy = $y;
26785 $gh = $h;
26786 $gw = $table['w'] - ($table['max_cell_border_width']['L']/2) - ($table['max_cell_border_width']['R']/2) - $table['margin']['L'] - $table['margin']['R'];
26787 if ($table['borders_separate']) {
26788 $gw -= ($table['padding']['L'] + $table['border_details']['L']['w'] + $table['padding']['R'] + $table['border_details']['R']['w'] + $table['border_spacing_H']);
26789 $s = '';
26790 $clx = $x+ ($table['border_spacing_H']/2);
26791 $cly = $y+ ($table['border_spacing_V']/2);
26792 $clw = $w- $table['border_spacing_H'];
26793 $clh = $h- $table['border_spacing_V'];
26794 // Set clipping path
26795 $s = ' q 0 w '; // Line width=0
26796 $s .= sprintf('%.3F %.3F m ', ($clx)*_MPDFK, ($this->h-($cly))*_MPDFK); // start point TL before the arc
26797 $s .= sprintf('%.3F %.3F l ', ($clx)*_MPDFK, ($this->h-($cly+$clh))*_MPDFK); // line to BL
26798 $s .= sprintf('%.3F %.3F l ', ($clx+$clw)*_MPDFK, ($this->h-($cly+$clh))*_MPDFK); // line to BR
26799 $s .= sprintf('%.3F %.3F l ', ($clx+$clw)*_MPDFK, ($this->h-($cly))*_MPDFK); // line to TR
26800 $s .= sprintf('%.3F %.3F l ', ($clx)*_MPDFK, ($this->h-($cly))*_MPDFK); // line to TL
26801 $s .= ' W n '; // Ends path no-op & Sets the clipping path
26802 $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);
26803 }
26804 else {
26805 $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'=>'');
26806 }
26807 }
26808 }
26809 else {
26810 $image_id = $table['trbackground-images'][$i]['image_id'];
26811 $orig_w = $table['trbackground-images'][$i]['orig_w'];
26812 $orig_h = $table['trbackground-images'][$i]['orig_h'];
26813 $x_pos = $table['trbackground-images'][$i]['x_pos'];
26814 $y_pos = $table['trbackground-images'][$i]['y_pos'];
26815 $x_repeat = $table['trbackground-images'][$i]['x_repeat'];
26816 $y_repeat = $table['trbackground-images'][$i]['y_repeat'];
26817 $resize = $table['trbackground-images'][$i]['resize'];
26818 $opacity = $table['trbackground-images'][$i]['opacity'];
26819 $itype = $table['trbackground-images'][$i]['itype'];
26820 $clippath = '';
26821 $gx = $x0;
26822 $gy = $y;
26823 $gh = $h;
26824 $gw = $table['w'] - ($table['max_cell_border_width']['L']/2) - ($table['max_cell_border_width']['R']/2) - $table['margin']['L'] - $table['margin']['R'];
26825 if ($table['borders_separate']) {
26826 $gw -= ($table['padding']['L'] + $table['border_details']['L']['w'] + $table['padding']['R'] + $table['border_details']['R']['w'] + $table['border_spacing_H']);
26827 $s = '';
26828 $clx = $x + ($table['border_spacing_H']/2);
26829 $cly = $y + ($table['border_spacing_V']/2);
26830 $clw = $w - $table['border_spacing_H'];
26831 $clh = $h - $table['border_spacing_V'];
26832 // Set clipping path
26833 $s = ' q 0 w '; // Line width=0
26834 $s .= sprintf('%.3F %.3F m ', ($clx)*_MPDFK, ($this->h-($cly))*_MPDFK); // start point TL
26835 $s .= sprintf('%.3F %.3F l ', ($clx)*_MPDFK, ($this->h-($cly+$clh))*_MPDFK); // line to BL
26836 $s .= sprintf('%.3F %.3F l ', ($clx+$clw)*_MPDFK, ($this->h-($cly+$clh))*_MPDFK); // line to BR
26837 $s .= sprintf('%.3F %.3F l ', ($clx+$clw)*_MPDFK, ($this->h-($cly))*_MPDFK); // line to TR
26838 $s .= sprintf('%.3F %.3F l ', ($clx)*_MPDFK, ($this->h-($cly))*_MPDFK); // line to TL
26839 $s .= ' W n '; // Ends path no-op & Sets the clipping path
26840 $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);
26841 }
26842 else {
26843 $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);
26844 }
26845 }
26846 }
26847 }
26848
26849/*-- END BACKGROUNDS --*/
26850
26851 // TABLE BORDER - if separate
26852 if (($table['borders_separate'] || ($this->simpleTables && !$table['simple']['border'])) && $table['border']) {
26853 $halfspaceL = $table['padding']['L'] + ($table['border_spacing_H']/2);
26854 $halfspaceR = $table['padding']['R'] + ($table['border_spacing_H']/2);
26855 $halfspaceT = $table['padding']['T'] + ($table['border_spacing_V']/2);
26856 $halfspaceB = $table['padding']['B'] + ($table['border_spacing_V']/2);
26857 $tbx = $x;
26858 $tby = $y;
26859 $tbw = $w;
26860 $tbh = $h;
26861 $tab_bord = 0;
26862
26863 $corner = '';
26864 if ($i == 0) { // Top
26865 $tby -= $halfspaceT + ($table['border_details']['T']['w']/2);
26866 $tbh += $halfspaceT + ($table['border_details']['T']['w']/2);
26867 $this->setBorder($tab_bord , _BORDER_TOP);
26868 $corner .= 'T';
26869 }
26870 if ($i == ($numrows-1) || (isset($cell['rowspan']) && ($i+$cell['rowspan']) == $numrows)) { // Bottom
26871 $tbh += $halfspaceB + ($table['border_details']['B']['w']/2);
26872 $this->setBorder($tab_bord , _BORDER_BOTTOM);
26873 $corner .= 'B';
26874 }
26875 if ($j == 0) { // Left
26876 $tbx -= $halfspaceL + ($table['border_details']['L']['w']/2);
26877 $tbw += $halfspaceL + ($table['border_details']['L']['w']/2);
26878 $this->setBorder($tab_bord , _BORDER_LEFT);
26879 $corner .= 'L';
26880 }
26881 if ($j == ($numcols-1) || (isset($cell['colspan']) && ($j+$cell['colspan']) == $numcols)) { // Right
26882 $tbw += $halfspaceR + ($table['border_details']['R']['w']/2);
26883 $this->setBorder($tab_bord , _BORDER_RIGHT);
26884 $corner .= 'R';
26885 }
26886 $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'] );
26887 }
26888
26889 unset($cell );
26890 //Reset values
26891 $this->Reset();
26892
26893 }//end of (if isset(cells)...)
26894 }// end of columns
26895
26896 $newpagestarted = false;
26897 $this->tabletheadjustfinished = false;
26898
26899 if ($this->ColActive && $i < $numrows-1 && $level==1) { $this->breakpoints[$this->CurrCol][] = $y + $h; } // *COLUMNS*
26900
26901/*-- COLUMNS --*/
26902 if ($this->ColActive) {
26903 if (count($this->cellBorderBuffer)) { $this->printcellbuffer(); }
26904 }
26905/*-- END COLUMNS --*/
26906
26907 if ($i == $numrows-1) { $this->y = $y + $h; } //last row jump (update this->y position)
26908 if ($this->table_rotate && $level==1) {
26909 $this->tbrot_h += $h;
26910 }
26911
26912
26913
26914 }// end of rows
26915
26916 if ($this->progressBar) { $this->UpdateProgressBar(7,70,' '); } // *PROGRESS-BAR*
26917
26918 if (count($this->cellBorderBuffer)) { $this->printcellbuffer(); }
26919
26920
26921 if ($this->tableClipPath ) { $this->_out("Q"); }
26922 $this->tableClipPath = '';
26923
26924 // Advance down page by half width of bottom border
26925 if ($table['borders_separate']) { $this->y += $table['padding']['B'] + $table['border_details']['B']['w'] + $table['border_spacing_V']/2; }
26926 else { $this->y += $table['max_cell_border_width']['B']/2; }
26927
26928 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; }
26929 else if ($level==1) { $this->tbrot_h += $table['margin']['B'] + $table['max_cell_border_width']['B']/2; }
26930
26931 $bx = $x0;
26932 $by = $y0;
26933 if ($table['borders_separate']) {
26934 $bx -= ($table['padding']['L'] + $table['border_details']['L']['w'] + $table['border_spacing_H']/2);
26935 if ($tablestartpageno != $this->page) { // IF broken across page
26936 $by += $table['max_cell_border_width']['T']/2;
26937 if (empty($tableheader)) { $by -= ($table['border_spacing_V']/2); }
26938 }
26939 else if ($split && $startrow > 0 && empty($tableheader)) {
26940 $by -= ($table['border_spacing_V']/2);
26941 }
26942 else {
26943 $by -= ($table['padding']['T'] + $table['border_details']['T']['w'] + $table['border_spacing_V']/2);
26944 }
26945 }
26946 else if ($tablestartpageno != $this->page && !empty($tableheader)) { $by += $maxbwtop /2; }
26947 $by -= $tableheaderadj;
26948 $bh = $this->y - $by;
26949 if (!$table['borders_separate']) { $bh -= $table['max_cell_border_width']['B']/2; }
26950
26951 if ($split) {
26952 $bw = 0;
26953 $finalSpread = true;
26954 for($t=$startcol; $t<$numcols; $t++) {
26955 if ($table['colPg'][$t] == $splitpg) { $bw += $table['wc'][$t]; }
26956 if ($table['colPg'][$t] > $splitpg) { $finalSpread = false; break; }
26957 }
26958 if ($startcol==0) { $firstSpread = true; }
26959 else { $firstSpread = false; }
26960 if ($table['borders_separate']) {
26961 $bw += $table['border_spacing_H'];
26962 if ($firstSpread) {
26963 $bw += $table['padding']['L'] + $table['border_details']['L']['w'];
26964 }
26965 else {
26966 $bx += ($table['padding']['L'] + $table['border_details']['L']['w']);
26967 }
26968 if ($finalSpread) {
26969 $bw += $table['padding']['R'] + $table['border_details']['R']['w'];
26970 }
26971 }
26972 }
26973 else {
26974 $bw = $table['w'] - ($table['max_cell_border_width']['L']/2) - ($table['max_cell_border_width']['R']/2) - $table['margin']['L'] - $table['margin']['R'];
26975 }
26976
26977 if (!$this->ColActive) {
26978 if (isset($table['bgcolor'][-1])) {
26979 $color = $this->ConvertColor($table['bgcolor'][-1]);
26980 if ($color) {
26981 $this->tableBackgrounds[$level*9][] = array('gradient'=>false, 'x'=>$bx, 'y'=>$by, 'w'=>$bw, 'h'=>$bh, 'col'=>$color);
26982 }
26983 }
26984
26985/*-- BACKGROUNDS --*/
26986 if (isset($table['gradient'])) {
26987 $g = $this->grad->parseBackgroundGradient($table['gradient']);
26988 if ($g) {
26989 $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'=>'');
26990 }
26991 }
26992
26993 if (isset($table['background-image'])) {
26994 if ($table['background-image']['gradient'] && preg_match('/(-moz-)*(repeating-)*(linear|radial)-gradient/', $table['background-image']['gradient'] )) {
26995 $g = $this->grad->parseMozGradient( $table['background-image']['gradient'] );
26996 if ($g) {
26997 $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'=>'');
26998 }
26999 }
27000 else {
27001 $image_id = $table['background-image']['image_id'];
27002 $orig_w = $table['background-image']['orig_w'];
27003 $orig_h = $table['background-image']['orig_h'];
27004 $x_pos = $table['background-image']['x_pos'];
27005 $y_pos = $table['background-image']['y_pos'];
27006 $x_repeat = $table['background-image']['x_repeat'];
27007 $y_repeat = $table['background-image']['y_repeat'];
27008 $resize = $table['background-image']['resize'];
27009 $opacity = $table['background-image']['opacity'];
27010 $itype = $table['background-image']['itype'];
27011 $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);
27012 }
27013 }
27014/*-- END BACKGROUNDS --*/
27015 }
27016
27017 if ($this->tableBackgrounds && $level == 1) {
27018 $s = $this->PrintTableBackgrounds();
27019 if ($this->table_rotate && !$this->processingHeader && !$this->processingFooter) {
27020 $this->tablebuffer = preg_replace('/(___TABLE___BACKGROUNDS'.$this->uniqstr.')/', '\\1'."\n".$s."\n", $this->tablebuffer);
27021 if ($level == 1) { $this->tablebuffer = preg_replace('/(___TABLE___BACKGROUNDS'.$this->uniqstr.')/', " ", $this->tablebuffer); }
27022 }
27023 else if ($this->bufferoutput) {
27024 $this->headerbuffer = preg_replace('/(___TABLE___BACKGROUNDS'.$this->uniqstr.')/', '\\1'."\n".$s."\n", $this->headerbuffer);
27025 if ($level == 1) { $this->headerbuffer = preg_replace('/(___TABLE___BACKGROUNDS'.$this->uniqstr.')/', " ", $this->headerbuffer ); }
27026 }
27027 else {
27028 $this->pages[$this->page] = preg_replace('/(___TABLE___BACKGROUNDS'.$this->uniqstr.')/', '\\1'."\n".$s."\n", $this->pages[$this->page]);
27029 if ($level == 1) { $this->pages[$this->page] = preg_replace('/(___TABLE___BACKGROUNDS'.$this->uniqstr.')/', " ", $this->pages[$this->page]); }
27030 }
27031 $this->tableBackgrounds = array();
27032 }
27033
27034
27035 // TABLE BOTTOM MARGIN
27036 if ($table['margin']['B']) {
27037 if (!$this->table_rotate && $level==1) {
27038 $this->DivLn($table['margin']['B'],$this->blklvl,true); // collapsible
27039 }
27040 else {
27041 $this->y += ($table['margin']['B']);
27042 }
27043 }
27044
27045 if ($this->ColActive && $level==1) { $this->breakpoints[$this->CurrCol][] = $this->y; } // *COLUMNS*
27046
27047 if ($this->cacheTables) { fclose($fh); }
27048
27049 if ($split) {
27050 // Are there more columns to print on a next page?
27051 if ($lastCol < $numcols-1) {
27052 $splitpg++;
27053 $startcol = $lastCol + 1;
27054 return array(false, $startrow, $startcol, $splitpg, $returny, $y0);
27055 }
27056 else {
27057 if ($this->cacheTables) {
27058 unlink($table['cache']);
27059 @unlink($table['cache'].'.bak');
27060 }
27061 return array(true,0,0,0);
27062 }
27063 }
27064 if ($this->cacheTables) {
27065 unlink($table['cache']);
27066 @unlink($table['cache'].'.bak');
27067 }
27068
27069}//END OF FUNCTION _tableWrite()
27070
27071
27072/////////////////////////END OF TABLE CODE//////////////////////////////////
27073/*-- END TABLES --*/
27074
27075function _putextgstates() {
27076 for ($i = 1; $i <= count($this->extgstates); $i++) {
27077 $this->_newobj();
27078 $this->extgstates[$i]['n'] = $this->n;
27079 $this->_out('<</Type /ExtGState');
27080 foreach ($this->extgstates[$i]['parms'] as $k=>$v)
27081 $this->_out('/'.$k.' '.$v);
27082 $this->_out('>>');
27083 $this->_out('endobj');
27084 }
27085}
27086
27087function _putocg() {
27088 if ($this->hasOC) { // mPDF 5.6.01
27089 $this->_newobj();
27090 $this->n_ocg_print=$this->n;
27091 $this->_out('<</Type /OCG /Name '.$this->_textstring('Print only'));
27092 $this->_out('/Usage <</Print <</PrintState /ON>> /View <</ViewState /OFF>>>>>>');
27093 $this->_out('endobj');
27094 $this->_newobj();
27095 $this->n_ocg_view=$this->n;
27096 $this->_out('<</Type /OCG /Name '.$this->_textstring('Screen only'));
27097 $this->_out('/Usage <</Print <</PrintState /OFF>> /View <</ViewState /ON>>>>>>');
27098 $this->_out('endobj');
27099 $this->_newobj();
27100 $this->n_ocg_hidden=$this->n;
27101 $this->_out('<</Type /OCG /Name '.$this->_textstring('Hidden'));
27102 $this->_out('/Usage <</Print <</PrintState /OFF>> /View <</ViewState /OFF>>>>>>');
27103 $this->_out('endobj');
27104 }
27105 // mPDF 5.6.01 Add Layers
27106 if (count($this->layers)) {
27107 ksort($this->layers);
27108 foreach($this->layers as $id=>$layer) {
27109 $this->_newobj();
27110 $this->layers[$id]['n'] = $this->n;
27111 // mPDF 5.6.28
27112 if (isset($this->layerDetails[$id]['name']) && $this->layerDetails[$id]['name']) {
27113 $name = $this->layerDetails[$id]['name'];
27114 }
27115 else { $name = $layer['name']; }
27116 $this->_out('<</Type /OCG /Name '.$this->_UTF16BEtextstring($name).'>>');
27117 $this->_out('endobj');
27118 }
27119 }
27120}
27121
27122
27123/*-- IMPORTS --*/
27124
27125 // from mPDFI
27126 function _putimportedobjects() {
27127 if (is_array($this->parsers) && count($this->parsers) > 0) {
27128 foreach($this->parsers AS $filename => $p) {
27129 $this->current_parser =& $this->parsers[$filename];
27130 if (is_array($this->_obj_stack[$filename])) {
27131 while($n = key($this->_obj_stack[$filename])) {
27132 $nObj = $this->current_parser->pdf_resolve_object($this->current_parser->c,$this->_obj_stack[$filename][$n][1]);
27133 $this->_newobj($this->_obj_stack[$filename][$n][0]);
27134 if ($nObj[0] == PDF_TYPE_STREAM) {
27135 $this->pdf_write_value($nObj);
27136 }
27137 else {
27138 $this->pdf_write_value($nObj[1]);
27139 }
27140 $this->_out('endobj');
27141 $this->_obj_stack[$filename][$n] = null; // free memory
27142 unset($this->_obj_stack[$filename][$n]);
27143 reset($this->_obj_stack[$filename]);
27144 }
27145 }
27146 }
27147 }
27148 }
27149
27150
27151 function _putformxobjects() {
27152 $filter=($this->compress) ? '/Filter /FlateDecode ' : '';
27153 reset($this->tpls);
27154 foreach($this->tpls AS $tplidx => $tpl) {
27155 $p=($this->compress) ? gzcompress($tpl['buffer']) : $tpl['buffer'];
27156 $this->_newobj();
27157 $this->tpls[$tplidx]['n'] = $this->n;
27158 $this->_out('<<'.$filter.'/Type /XObject');
27159 $this->_out('/Subtype /Form');
27160 $this->_out('/FormType 1');
27161 // Left/Bottom/Right/Top
27162 $this->_out(sprintf('/BBox [%.2F %.2F %.2F %.2F]',
27163 $tpl['box']['x']*_MPDFK,
27164 $tpl['box']['y']*_MPDFK,
27165 ($tpl['box']['x'] + $tpl['box']['w'])*_MPDFK,
27166 ($tpl['box']['y'] + $tpl['box']['h'])*_MPDFK )
27167 );
27168
27169
27170 if (isset($tpl['box']))
27171 $this->_out(sprintf('/Matrix [1 0 0 1 %.5F %.5F]',-$tpl['box']['x']*_MPDFK, -$tpl['box']['y']*_MPDFK));
27172 $this->_out('/Resources ');
27173
27174 if (isset($tpl['resources'])) {
27175 $this->current_parser =& $tpl['parser'];
27176 $this->pdf_write_value($tpl['resources']);
27177 } else {
27178 $this->_out('<</ProcSet [/PDF /Text /ImageB /ImageC /ImageI]');
27179 if (isset($this->_res['tpl'][$tplidx]['fonts']) && count($this->_res['tpl'][$tplidx]['fonts'])) {
27180 $this->_out('/Font <<');
27181 foreach($this->_res['tpl'][$tplidx]['fonts'] as $font)
27182 $this->_out('/F'.$font['i'].' '.$font['n'].' 0 R');
27183 $this->_out('>>');
27184 }
27185 if(isset($this->_res['tpl'][$tplidx]['images']) && count($this->_res['tpl'][$tplidx]['images']) ||
27186 isset($this->_res['tpl'][$tplidx]['tpls']) && count($this->_res['tpl'][$tplidx]['tpls']))
27187 {
27188 $this->_out('/XObject <<');
27189 if (isset($this->_res['tpl'][$tplidx]['images']) && count($this->_res['tpl'][$tplidx]['images'])) {
27190 foreach($this->_res['tpl'][$tplidx]['images'] as $image)
27191 $this->_out('/I'.$image['i'].' '.$image['n'].' 0 R');
27192 }
27193 if (isset($this->_res['tpl'][$tplidx]['tpls']) && count($this->_res['tpl'][$tplidx]['tpls'])) {
27194 foreach($this->_res['tpl'][$tplidx]['tpls'] as $i => $itpl)
27195 $this->_out($this->tplprefix.$i.' '.$itpl['n'].' 0 R');
27196 }
27197 $this->_out('>>');
27198 }
27199 $this->_out('>>');
27200 }
27201
27202 $this->_out('/Length '.strlen($p).' >>');
27203 $this->_putstream($p);
27204 $this->_out('endobj');
27205 }
27206 }
27207
27208/*-- END IMPORTS --*/
27209
27210
27211function _putpatterns() {
27212 for ($i = 1; $i <= count($this->patterns); $i++) {
27213 $x = $this->patterns[$i]['x'];
27214 $y = $this->patterns[$i]['y'];
27215 $w = $this->patterns[$i]['w'];
27216 $h = $this->patterns[$i]['h'];
27217 $pgh = $this->patterns[$i]['pgh'];
27218 $orig_w = $this->patterns[$i]['orig_w'];
27219 $orig_h = $this->patterns[$i]['orig_h'];
27220 $image_id = $this->patterns[$i]['image_id'];
27221 $itype = $this->patterns[$i]['itype'];
27222 $bpa = $this->patterns[$i]['bpa']; // mPDF 5.6.10 background positioning area
27223
27224 if ($this->patterns[$i]['x_repeat']) { $x_repeat = true; }
27225 else { $x_repeat = false; }
27226 if ($this->patterns[$i]['y_repeat']) { $y_repeat = true; }
27227 else { $y_repeat = false; }
27228 $x_pos = $this->patterns[$i]['x_pos'];
27229 if (stristr($x_pos ,'%') ) {
27230 $x_pos += 0;
27231 $x_pos /= 100;
27232 if (isset($bpa['w']) && $bpa['w']) $x_pos = ($bpa['w'] * $x_pos) - ($orig_w/_MPDFK * $x_pos); // mPDF 5.6.10
27233 else $x_pos = ($w * $x_pos) - ($orig_w/_MPDFK * $x_pos);
27234 }
27235 $y_pos = $this->patterns[$i]['y_pos'];
27236 if (stristr($y_pos ,'%') ) {
27237 $y_pos += 0;
27238 $y_pos /= 100;
27239 if (isset($bpa['h']) && $bpa['h']) $y_pos = ($bpa['h'] * $y_pos) - ($orig_h/_MPDFK * $y_pos); // mPDF 5.6.10
27240 else $y_pos = ($h * $y_pos) - ($orig_h/_MPDFK * $y_pos);
27241 }
27242 if (isset($bpa['x']) && $bpa['x']) $adj_x = ($x_pos + $bpa['x']) *_MPDFK; // mPDF 5.6.10
27243 else $adj_x = ($x_pos + $x) *_MPDFK;
27244 if (isset($bpa['y']) && $bpa['y']) $adj_y = (($pgh - $y_pos - $bpa['y'])*_MPDFK) - $orig_h ; // mPDF 5.6.10
27245 else $adj_y = (($pgh - $y_pos - $y)*_MPDFK) - $orig_h ;
27246 $img_obj = false;
27247 if ($itype == 'svg' || $itype == 'wmf') {
27248 foreach($this->formobjects AS $fo) {
27249 if ($fo['i'] == $image_id) {
27250 $img_obj = $fo['n'];
27251 $fo_w = $fo['w'];
27252 $fo_h = -$fo['h'];
27253 $wmf_x = $fo['x'];
27254 $wmf_y = $fo['y'];
27255 break;
27256 }
27257 }
27258 }
27259 else {
27260 foreach($this->images AS $img) {
27261 if ($img['i'] == $image_id) { $img_obj = $img['n']; break; }
27262 }
27263 }
27264 if (!$img_obj ) { echo "Problem: Image object not found for background pattern ".$img['i']; exit; }
27265
27266 $this->_newobj();
27267 $this->_out('<</ProcSet [/PDF /Text /ImageB /ImageC /ImageI]');
27268 if ($itype == 'svg' || $itype == 'wmf') {
27269 $this->_out('/XObject <</FO'.$image_id.' '.$img_obj.' 0 R >>');
27270 // ******* ADD ANY ExtGStates, Shading AND Fonts needed for the FormObject
27271 // Set in classes/svg array['fo'] = true
27272 // Required that _putshaders comes before _putpatterns in _putresources
27273 // This adds any resources associated with any FormObject to every Formobject - overkill but works!
27274 if (count($this->extgstates)) {
27275 $this->_out('/ExtGState <<');
27276 foreach($this->extgstates as $k=>$extgstate)
27277 if (isset($extgstate['fo']) && $extgstate['fo']) {
27278 if (isset($extgstate['trans'])) $this->_out('/'.$extgstate['trans'].' '.$extgstate['n'].' 0 R');
27279 else $this->_out('/GS'.$k.' '.$extgstate['n'].' 0 R');
27280 }
27281 $this->_out('>>');
27282 }
27283/*-- BACKGROUNDS --*/
27284 if (isset($this->gradients) AND (count($this->gradients) > 0)) {
27285 $this->_out('/Shading <<');
27286 foreach ($this->gradients as $id => $grad) {
27287 if (isset($grad['fo']) && $grad['fo']) {
27288 $this->_out('/Sh'.$id.' '.$grad['id'].' 0 R');
27289 }
27290 }
27291 $this->_out('>>');
27292 }
27293/*-- END BACKGROUNDS --*/
27294 $this->_out('/Font <<');
27295 foreach($this->fonts as $font) {
27296 if (!$font['used'] && $font['type']=='TTF') { continue; }
27297 if (isset($font['fo']) && $font['fo']) {
27298 if ($font['type']=='TTF' && ($font['sip'] || $font['smp'])) {
27299 foreach($font['n'] AS $k => $fid) {
27300 $this->_out('/F'.$font['subsetfontids'][$k].' '.$font['n'][$k].' 0 R');
27301 }
27302 }
27303 else {
27304 $this->_out('/F'.$font['i'].' '.$font['n'].' 0 R');
27305 }
27306 }
27307 }
27308 $this->_out('>>');
27309 }
27310 else {
27311 $this->_out('/XObject <</I'.$image_id.' '.$img_obj.' 0 R >>');
27312 }
27313 $this->_out('>>');
27314 $this->_out('endobj');
27315
27316 $this->_newobj();
27317 $this->patterns[$i]['n'] = $this->n;
27318 $this->_out('<< /Type /Pattern /PatternType 1 /PaintType 1 /TilingType 2');
27319 $this->_out('/Resources '. ($this->n-1) .' 0 R');
27320
27321 $this->_out(sprintf('/BBox [0 0 %.3F %.3F]',$orig_w,$orig_h));
27322 if ($x_repeat) { $this->_out(sprintf('/XStep %.3F',$orig_w)); }
27323 else { $this->_out(sprintf('/XStep %d',99999)); }
27324 if ($y_repeat) { $this->_out(sprintf('/YStep %.3F',$orig_h)); }
27325 else { $this->_out(sprintf('/YStep %d',99999)); }
27326
27327 if ($itype == 'svg' || $itype == 'wmf') {
27328 $this->_out(sprintf('/Matrix [1 0 0 -1 %.3F %.3F]', $adj_x, ($adj_y+$orig_h)));
27329 $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);
27330 }
27331 else {
27332 $this->_out(sprintf('/Matrix [1 0 0 1 %.3F %.3F]',$adj_x,$adj_y));
27333 $s = sprintf("q %.3F 0 0 %.3F 0 0 cm /I%d Do Q",$orig_w,$orig_h,$image_id);
27334 }
27335
27336 if ($this->compress) {
27337 $this->_out('/Filter /FlateDecode');
27338 $s = gzcompress($s);
27339 }
27340 $this->_out('/Length '.strlen($s).'>>');
27341 $this->_putstream($s);
27342 $this->_out('endobj');
27343 }
27344}
27345
27346/*-- BACKGROUNDS --*/
27347function _putshaders() {
27348 $maxid = count($this->gradients); //index for transparency gradients
27349 foreach ($this->gradients as $id => $grad) {
27350 if (($grad['type'] == 2 || $grad['type'] == 3) && empty($grad['is_mask'])) {
27351 $this->_newobj();
27352 $this->_out('<<');
27353 $this->_out('/FunctionType 3');
27354 $this->_out('/Domain [0 1]');
27355 $fn = array();
27356 $bd = array();
27357 $en = array();
27358 for($i=0; $i<(count($grad['stops'])-1); $i++) {
27359 $fn[] = ($this->n+1+$i).' 0 R';
27360 $en[] = '0 1';
27361 if ($i>0) { $bd[] = sprintf('%.3F', $grad['stops'][$i]['offset']); }
27362 }
27363 $this->_out('/Functions ['.implode(' ',$fn).']');
27364 $this->_out('/Bounds ['.implode(' ',$bd).']');
27365 $this->_out('/Encode ['.implode(' ',$en).']');
27366 $this->_out('>>');
27367 $this->_out('endobj');
27368 $f1 = $this->n;
27369 for($i=0; $i<(count($grad['stops'])-1); $i++) {
27370 $this->_newobj();
27371 $this->_out('<<');
27372 $this->_out('/FunctionType 2');
27373 $this->_out('/Domain [0 1]');
27374 $this->_out('/C0 ['.$grad['stops'][$i]['col'].']');
27375 $this->_out('/C1 ['.$grad['stops'][$i+1]['col'].']');
27376 $this->_out('/N 1');
27377 $this->_out('>>');
27378 $this->_out('endobj');
27379 }
27380 }
27381 if ($grad['type'] == 2 || $grad['type'] == 3) {
27382 if (isset($grad['trans']) && $grad['trans']) {
27383 $this->_newobj();
27384 $this->_out('<<');
27385 $this->_out('/FunctionType 3');
27386 $this->_out('/Domain [0 1]');
27387 $fn = array();
27388 $bd = array();
27389 $en = array();
27390 for($i=0; $i<(count($grad['stops'])-1); $i++) {
27391 $fn[] = ($this->n+1+$i).' 0 R';
27392 $en[] = '0 1';
27393 if ($i>0) { $bd[] = sprintf('%.3F', $grad['stops'][$i]['offset']); }
27394 }
27395 $this->_out('/Functions ['.implode(' ',$fn).']');
27396 $this->_out('/Bounds ['.implode(' ',$bd).']');
27397 $this->_out('/Encode ['.implode(' ',$en).']');
27398 $this->_out('>>');
27399 $this->_out('endobj');
27400 $f2 = $this->n;
27401 for($i=0; $i<(count($grad['stops'])-1); $i++) {
27402 $this->_newobj();
27403 $this->_out('<<');
27404 $this->_out('/FunctionType 2');
27405 $this->_out('/Domain [0 1]');
27406 $this->_out(sprintf('/C0 [%.3F]', $grad['stops'][$i]['opacity']));
27407 $this->_out(sprintf('/C1 [%.3F]', $grad['stops'][$i+1]['opacity']));
27408 $this->_out('/N 1');
27409 $this->_out('>>');
27410 $this->_out('endobj');
27411 }
27412 }
27413 }
27414
27415 if (empty($grad['is_mask'])) {
27416 $this->_newobj();
27417 $this->_out('<<');
27418 $this->_out('/ShadingType '.$grad['type']);
27419 if (isset($grad['colorspace'])) {
27420 $this->_out('/ColorSpace /Device'.$grad['colorspace']); // Can use CMYK if all C0 and C1 above have 4 values
27421 } else {
27422 $this->_out('/ColorSpace /DeviceRGB');
27423 }
27424 if ($grad['type'] == 2) {
27425 $this->_out(sprintf('/Coords [%.3F %.3F %.3F %.3F]', $grad['coords'][0], $grad['coords'][1], $grad['coords'][2], $grad['coords'][3]));
27426 $this->_out('/Function '.$f1.' 0 R');
27427 $this->_out('/Extend ['.$grad['extend'][0].' '.$grad['extend'][1].'] ');
27428 $this->_out('>>');
27429 }
27430 else if ($grad['type'] == 3) {
27431 //x0, y0, r0, x1, y1, r1
27432 //at this this time radius of inner circle is 0
27433 $ir = 0;
27434 if (isset($grad['coords'][5]) && $grad['coords'][5]) { $ir = $grad['coords'][5]; }
27435 $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]));
27436 $this->_out('/Function '.$f1.' 0 R');
27437 $this->_out('/Extend ['.$grad['extend'][0].' '.$grad['extend'][1].'] ');
27438 $this->_out('>>');
27439 }
27440 else if ($grad['type']==6) {
27441 $this->_out('/BitsPerCoordinate 16');
27442 $this->_out('/BitsPerComponent 8');
27443 if ($grad['colorspace'] == 'CMYK') { $this->_out('/Decode[0 1 0 1 0 1 0 1 0 1 0 1]'); }
27444 else if ($grad['colorspace'] == 'Gray') { $this->_out('/Decode[0 1 0 1 0 1]'); }
27445 else { $this->_out('/Decode[0 1 0 1 0 1 0 1 0 1]'); }
27446 $this->_out('/BitsPerFlag 8');
27447 $this->_out('/Length '.strlen($grad['stream']));
27448 $this->_out('>>');
27449 $this->_putstream($grad['stream']);
27450 }
27451 $this->_out('endobj');
27452 }
27453
27454 $this->gradients[$id]['id'] = $this->n;
27455
27456 // set pattern object
27457 $this->_newobj();
27458 $out = '<< /Type /Pattern /PatternType 2';
27459 $out .= ' /Shading '.$this->gradients[$id]['id'].' 0 R';
27460 $out .= ' >>';
27461 $out .= "\n".'endobj';
27462 $this->_out($out);
27463
27464
27465 $this->gradients[$id]['pattern'] = $this->n;
27466
27467 if (isset($grad['trans']) && $grad['trans']) {
27468 // luminosity pattern
27469 $transid = $id + $maxid;
27470 $this->_newobj();
27471 $this->_out('<<');
27472 $this->_out('/ShadingType '.$grad['type']);
27473 $this->_out('/ColorSpace /DeviceGray');
27474 if ($grad['type'] == 2) {
27475 $this->_out(sprintf('/Coords [%.3F %.3F %.3F %.3F]', $grad['coords'][0], $grad['coords'][1], $grad['coords'][2], $grad['coords'][3]));
27476 $this->_out('/Function '.$f2.' 0 R');
27477 $this->_out('/Extend ['.$grad['extend'][0].' '.$grad['extend'][1].'] ');
27478 $this->_out('>>');
27479 }
27480 else if ($grad['type'] == 3) {
27481 //x0, y0, r0, x1, y1, r1
27482 //at this this time radius of inner circle is 0
27483 $ir = 0;
27484 if (isset($grad['coords'][5]) && $grad['coords'][5]) { $ir = $grad['coords'][5]; }
27485 $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]));
27486 $this->_out('/Function '.$f2.' 0 R');
27487 $this->_out('/Extend ['.$grad['extend'][0].' '.$grad['extend'][1].'] ');
27488 $this->_out('>>');
27489 }
27490 else if ($grad['type']==6) {
27491 $this->_out('/BitsPerCoordinate 16');
27492 $this->_out('/BitsPerComponent 8');
27493 $this->_out('/Decode[0 1 0 1 0 1]');
27494 $this->_out('/BitsPerFlag 8');
27495 $this->_out('/Length '.strlen($grad['stream_trans']));
27496 $this->_out('>>');
27497 $this->_putstream($grad['stream_trans']);
27498 }
27499 $this->_out('endobj');
27500
27501 $this->gradients[$transid]['id'] = $this->n;
27502 $this->_newobj();
27503 $this->_out('<< /Type /Pattern /PatternType 2');
27504 $this->_out('/Shading '.$this->gradients[$transid]['id'].' 0 R');
27505 $this->_out('>>');
27506 $this->_out('endobj');
27507 $this->gradients[$transid]['pattern'] = $this->n;
27508 $this->_newobj();
27509 // Need to extend size of viewing box in case of transformations
27510 $str = 'q /a0 gs /Pattern cs /p'.$transid.' scn -'.($this->wPt/2).' -'.($this->hPt/2).' '.(2*$this->wPt).' '.(2*$this->hPt).' re f Q';
27511 $filter=($this->compress) ? '/Filter /FlateDecode ' : '';
27512 $p=($this->compress) ? gzcompress($str) : $str;
27513 $this->_out('<< /Type /XObject /Subtype /Form /FormType 1 '.$filter);
27514 $this->_out('/Length '.strlen($p));
27515 $this->_out('/BBox [-'.($this->wPt/2).' -'.($this->hPt/2).' '.(2*$this->wPt).' '.(2*$this->hPt).']');
27516 $this->_out('/Group << /Type /Group /S /Transparency /CS /DeviceGray >>');
27517 $this->_out('/Resources <<');
27518 $this->_out('/ExtGState << /a0 << /ca 1 /CA 1 >> >>');
27519 $this->_out('/Pattern << /p'.$transid.' '.$this->gradients[$transid]['pattern'].' 0 R >>');
27520 $this->_out('>>');
27521 $this->_out('>>');
27522 $this->_putstream($p);
27523 $this->_out('endobj');
27524 $this->_newobj();
27525 $this->_out('<< /Type /Mask /S /Luminosity /G '.($this->n - 1).' 0 R >>'."\n".'endobj');
27526 $this->_newobj();
27527 $this->_out('<< /Type /ExtGState /SMask '.($this->n - 1).' 0 R /AIS false >>'."\n".'endobj');
27528 if ($grad['fo']) { $this->extgstates[] = array('n' => $this->n, 'trans' => 'TGS'.$id, 'fo'=>true); }
27529 else { $this->extgstates[] = array('n' => $this->n, 'trans' => 'TGS'.$id); }
27530 }
27531 }
27532}
27533/*-- END BACKGROUNDS --*/
27534
27535function _putspotcolors() {
27536 foreach($this->spotColors as $name=>$color) {
27537 $this->_newobj();
27538 $this->_out('[/Separation /'.str_replace(' ','#20',$name));
27539 $this->_out('/DeviceCMYK <<');
27540 $this->_out('/Range [0 1 0 1 0 1 0 1] /C0 [0 0 0 0] ');
27541 $this->_out(sprintf('/C1 [%.3F %.3F %.3F %.3F] ',$color['c']/100,$color['m']/100,$color['y']/100,$color['k']/100));
27542 $this->_out('/FunctionType 2 /Domain [0 1] /N 1>>]');
27543 $this->_out('endobj');
27544 $this->spotColors[$name]['n']=$this->n;
27545 }
27546}
27547
27548
27549function _putresources() {
27550 if ($this->hasOC || count($this->layers)) // mPDF 5.6.01
27551 $this->_putocg();
27552 $this->_putextgstates();
27553 $this->_putspotcolors();
27554 if ($this->progressBar) { $this->UpdateProgressBar(2,'40','Compiling Fonts'); } // *PROGRESS-BAR*
27555 $this->_putfonts();
27556 if ($this->progressBar) { $this->UpdateProgressBar(2,'50','Compiling Images'); } // *PROGRESS-BAR*
27557 $this->_putimages();
27558 $this->_putformobjects(); // *IMAGES-CORE*
27559
27560/*-- IMPORTS --*/
27561 if ($this->enableImports) {
27562 $this->_putformxobjects();
27563 $this->_putimportedobjects();
27564 }
27565/*-- END IMPORTS --*/
27566
27567/*-- BACKGROUNDS --*/
27568 $this->_putshaders();
27569 $this->_putpatterns();
27570/*-- END BACKGROUNDS --*/
27571
27572
27573 //Resource dictionary
27574 $this->offsets[2]=strlen($this->buffer);
27575 $this->_out('2 0 obj');
27576 $this->_out('<</ProcSet [/PDF /Text /ImageB /ImageC /ImageI]');
27577
27578 $this->_out('/Font <<');
27579 foreach($this->fonts as $font) {
27580 if (!$font['used'] && $font['type']=='TTF') { continue; }
27581 if ($font['type']=='TTF' && ($font['sip'] || $font['smp'])) {
27582 foreach($font['n'] AS $k => $fid) {
27583 $this->_out('/F'.$font['subsetfontids'][$k].' '.$font['n'][$k].' 0 R');
27584 }
27585 }
27586 else {
27587 $this->_out('/F'.$font['i'].' '.$font['n'].' 0 R');
27588 }
27589 }
27590 $this->_out('>>');
27591
27592 if (count($this->spotColors)) {
27593 $this->_out('/ColorSpace <<');
27594 foreach($this->spotColors as $color)
27595 $this->_out('/CS'.$color['i'].' '.$color['n'].' 0 R');
27596 $this->_out('>>');
27597 }
27598
27599 if (count($this->extgstates)) {
27600 $this->_out('/ExtGState <<');
27601 foreach($this->extgstates as $k=>$extgstate)
27602 if (isset($extgstate['trans'])) $this->_out('/'.$extgstate['trans'].' '.$extgstate['n'].' 0 R');
27603 else $this->_out('/GS'.$k.' '.$extgstate['n'].' 0 R');
27604 $this->_out('>>');
27605 }
27606
27607/*-- BACKGROUNDS --*/
27608 if (isset($this->gradients) AND (count($this->gradients) > 0)) {
27609 $this->_out('/Shading <<');
27610 foreach ($this->gradients as $id => $grad) {
27611 $this->_out('/Sh'.$id.' '.$grad['id'].' 0 R');
27612 }
27613 $this->_out('>>');
27614
27615/*
27616 // ??? Not needed !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
27617 $this->_out('/Pattern <<');
27618 foreach ($this->gradients as $id => $grad) {
27619 $this->_out('/P'.$id.' '.$grad['pattern'].' 0 R');
27620 }
27621 $this->_out('>>');
27622*/
27623 }
27624/*-- END BACKGROUNDS --*/
27625
27626 if(count($this->images) || count($this->formobjects) || ($this->enableImports && count($this->tpls))) {
27627 $this->_out('/XObject <<');
27628 foreach($this->images as $image)
27629 $this->_out('/I'.$image['i'].' '.$image['n'].' 0 R');
27630 foreach($this->formobjects as $formobject)
27631 $this->_out('/FO'.$formobject['i'].' '.$formobject['n'].' 0 R');
27632/*-- IMPORTS --*/
27633 if ($this->enableImports && count($this->tpls)) {
27634 foreach($this->tpls as $tplidx => $tpl) {
27635 $this->_out($this->tplprefix.$tplidx.' '.$tpl['n'].' 0 R');
27636 }
27637 }
27638/*-- END IMPORTS --*/
27639 $this->_out('>>');
27640 }
27641
27642/*-- BACKGROUNDS --*/
27643
27644 if (count($this->patterns)) {
27645 $this->_out('/Pattern <<');
27646 foreach($this->patterns as $k=>$patterns)
27647 $this->_out('/P'.$k.' '.$patterns['n'].' 0 R');
27648 $this->_out('>>');
27649 }
27650/*-- END BACKGROUNDS --*/
27651
27652 // mPDF 5.6.01
27653 if ($this->hasOC || count($this->layers)) {
27654 $this->_out('/Properties <<');
27655 if ($this->hasOC) {
27656 $this->_out('/OC1 '.$this->n_ocg_print.' 0 R /OC2 '.$this->n_ocg_view.' 0 R /OC3 '.$this->n_ocg_hidden.' 0 R ');
27657 }
27658 if (count($this->layers)) {
27659 foreach($this->layers as $id=>$layer)
27660 $this->_out('/ZI'.$id.' '.$layer['n'].' 0 R');
27661 }
27662 $this->_out('>>');
27663 }
27664
27665 $this->_out('>>');
27666 $this->_out('endobj'); // end resource dictionary
27667
27668 $this->_putbookmarks(); // *BOOKMARKS*
27669
27670 if (isset($this->js) && $this->js) {
27671 $this->_putjavascript();
27672 }
27673
27674/*-- ENCRYPTION --*/
27675 if ($this->encrypted) {
27676 $this->_newobj();
27677 $this->enc_obj_id = $this->n;
27678 $this->_out('<<');
27679 $this->_putencryption();
27680 $this->_out('>>');
27681 $this->_out('endobj');
27682 }
27683/*-- END ENCRYPTION --*/
27684}
27685
27686
27687function _putjavascript() {
27688 $this->_newobj();
27689 $this->n_js = $this->n;
27690 $this->_out('<<');
27691 $this->_out('/Names [(EmbeddedJS) '.(1 + $this->n).' 0 R ]');
27692 $this->_out('>>');
27693 $this->_out('endobj');
27694
27695 $this->_newobj();
27696 $this->_out('<<');
27697 $this->_out('/S /JavaScript');
27698 $this->_out('/JS '.$this->_textstring($this->js));
27699 $this->_out('>>');
27700 $this->_out('endobj');
27701}
27702
27703
27704
27705
27706/*-- ENCRYPTION --*/
27707function _putencryption() {
27708 $this->_out('/Filter /Standard');
27709 if ($this->useRC128encryption) {
27710 $this->_out('/V 2');
27711 $this->_out('/R 3');
27712 $this->_out('/Length 128');
27713 }
27714 else {
27715 $this->_out('/V 1');
27716 $this->_out('/R 2');
27717 }
27718 $this->_out('/O ('.$this->_escape($this->Ovalue).')');
27719 $this->_out('/U ('.$this->_escape($this->Uvalue).')');
27720 $this->_out('/P '.$this->Pvalue);
27721}
27722/*-- END ENCRYPTION --*/
27723
27724function _puttrailer() {
27725 $this->_out('/Size '.($this->n+1));
27726 $this->_out('/Root '.$this->n.' 0 R');
27727 $this->_out('/Info '.$this->InfoRoot.' 0 R');
27728/*-- ENCRYPTION --*/
27729 if ($this->encrypted) {
27730 $this->_out('/Encrypt '.$this->enc_obj_id.' 0 R');
27731 $this->_out('/ID [<'.$this->uniqid.'> <'.$this->uniqid.'>]');
27732 }
27733 else {
27734/*-- END ENCRYPTION --*/
27735 $uniqid = md5(time() . $this->buffer);
27736 $this->_out('/ID [<'.$uniqid.'> <'.$uniqid.'>]');
27737/*-- ENCRYPTION --*/
27738 }
27739/*-- END ENCRYPTION --*/
27740}
27741
27742/*-- ENCRYPTION --*/
27743function SetProtection($permissions=array(),$user_pass='',$owner_pass=null, $length=40) {
27744 $this->encrypted=false;
27745 if (is_string($permissions) && strlen($permissions)>0) { $permissions = array($permissions); }
27746 else if (!is_array($permissions)) { return 0; }
27747 $this->last_rc4_key='';
27748 $this->padding="\x28\xBF\x4E\x5E\x4E\x75\x8A\x41\x64\x00\x4E\x56\xFF\xFA\x01\x08".
27749 "\x2E\x2E\x00\xB6\xD0\x68\x3E\x80\x2F\x0C\xA9\xFE\x64\x53\x69\x7A";
27750
27751 $options = array(
27752 'print' => 4, // bit 3
27753 'modify' => 8, // bit 4
27754 'copy' => 16, // bit 5
27755 'annot-forms' => 32, // bit 6
27756 'fill-forms' => 256, // bit 9
27757 'extract' => 512, // bit 10
27758 'assemble' => 1024,// bit 11
27759 'print-highres' => 2048 // bit 12
27760 );
27761 // bit 31 = 1073741824
27762 // bit 32 = 2147483648
27763 // bits 13-31 = 2147479552
27764 // bits 13-32 = 4294963200 + 192 = 4294963392
27765 $protection = 4294963392; // bits 7,8,13-32
27766 foreach ($permissions as $permission) {
27767 if (!isset($options[$permission]))
27768 $this->Error('Incorrect permission: '.$permission);
27769 if ($options[$permission] > 32) { $this->useRC128encryption = true; }
27770 if (isset($options[$permission])) $protection += $options[$permission];
27771 }
27772 if ($length==128) { $this->useRC128encryption = true; }
27773 if ($owner_pass === null)
27774 $owner_pass = uniqid(rand());
27775 $this->encrypted = true;
27776 $this->_generateencryptionkey($user_pass, $owner_pass, $protection);
27777}
27778
27779
27780// Compute key depending on object number where the encrypted data is stored
27781function _objectkey($n) {
27782 if ($this->useRC128encryption)
27783 $len = 16;
27784 else
27785 $len = 10;
27786 return substr($this->_md5_16($this->encryption_key.pack('VXxx',$n)),0,$len);
27787}
27788
27789// RC4 is the standard encryption algorithm used in PDF format
27790function _RC4($key, $text) {
27791 if ($this->last_rc4_key != $key) {
27792 $k = str_repeat($key, 256/strlen($key)+1);
27793 $rc4 = range(0,255);
27794 $j = 0;
27795 for ($i=0; $i<256; $i++){
27796 $t = $rc4[$i];
27797 $j = ($j + $t + ord($k[$i])) % 256;
27798 $rc4[$i] = $rc4[$j];
27799 $rc4[$j] = $t;
27800 }
27801 $this->last_rc4_key = $key;
27802 $this->last_rc4_key_c = $rc4;
27803 } else {
27804 $rc4 = $this->last_rc4_key_c;
27805 }
27806
27807 $len = strlen($text);
27808 $a = 0;
27809 $b = 0;
27810 $out = '';
27811 for ($i=0; $i<$len; $i++){
27812 $a = ($a+1)%256;
27813 $t= $rc4[$a];
27814 $b = ($b+$t)%256;
27815 $rc4[$a] = $rc4[$b];
27816 $rc4[$b] = $t;
27817 $k = $rc4[($rc4[$a]+$rc4[$b])%256];
27818 $out.= chr(ord($text[$i]) ^ $k);
27819 }
27820 return $out;
27821}
27822
27823// Get MD5 as binary string
27824function _md5_16($string) {
27825 return pack('H*',md5($string));
27826}
27827
27828// Compute O value
27829function _Ovalue($user_pass, $owner_pass) {
27830 $tmp = $this->_md5_16($owner_pass);
27831 if ($this->useRC128encryption) {
27832 for ($i = 0; $i < 50; ++$i) {
27833 $tmp = $this->_md5_16($tmp);
27834 }
27835 }
27836 if ($this->useRC128encryption)
27837 $keybytelen = (128 / 8);
27838 else
27839 $keybytelen = (40 / 8);
27840 $owner_RC4_key = substr($tmp,0,$keybytelen);
27841 $enc = $this->_RC4($owner_RC4_key, $user_pass);
27842 if ($this->useRC128encryption) {
27843 $len = strlen($owner_RC4_key);
27844 for ($i = 1; $i <= 19; ++$i) {
27845 $key = '';
27846 for ($j = 0; $j < $len; ++$j) {
27847 $key .= chr(ord($owner_RC4_key{$j}) ^ $i);
27848 }
27849 $enc = $this->_RC4($key, $enc);
27850 }
27851 }
27852 return $enc;
27853}
27854
27855// Compute U value
27856function _Uvalue() {
27857 if ($this->useRC128encryption) {
27858 $tmp = $this->_md5_16($this->padding.$this->_hexToString($this->uniqid));
27859 $enc = $this->_RC4($this->encryption_key, $tmp);
27860 $len = strlen($tmp);
27861 for ($i=1; $i<=19; ++$i) {
27862 $key = '';
27863 for ($j=0; $j<$len; ++$j) {
27864 $key .= chr(ord($this->encryption_key{$j}) ^ $i);
27865 }
27866 $enc = $this->_RC4($key, $enc);
27867 }
27868 $enc .= str_repeat("\x00", 16);
27869 return substr($enc, 0, 32);
27870 }
27871 else {
27872 return $this->_RC4($this->encryption_key, $this->padding);
27873 }
27874}
27875
27876// Compute encryption key
27877function _generateencryptionkey($user_pass, $owner_pass, $protection) {
27878 // Pad passwords
27879 $user_pass = substr($user_pass.$this->padding,0,32);
27880 $owner_pass = substr($owner_pass.$this->padding,0,32);
27881 $chars = 'ABCDEF1234567890';
27882 $id = '';
27883 for ($i=0; $i<32; $i++) { $id .= $chars{rand(0, 15)}; }
27884 $this->uniqid = md5($id);
27885 // Compute O value
27886 $this->Ovalue = $this->_Ovalue($user_pass,$owner_pass);
27887 // Compute encyption key
27888 if ($this->useRC128encryption)
27889 $keybytelen = (128/8);
27890 else
27891 $keybytelen = (40/8);
27892 $prot = sprintf('%032b', $protection);
27893 $perms = chr(bindec(substr($prot,24,8)));
27894 $perms .= chr(bindec(substr($prot,16,8)));
27895 $perms .= chr(bindec(substr($prot,8,8)));
27896 $perms .= chr(bindec(substr($prot,0,8)));
27897 $tmp = $this->_md5_16($user_pass.$this->Ovalue.$perms.$this->_hexToString($this->uniqid));
27898 if ($this->useRC128encryption) {
27899 for ($i=0; $i<50; ++$i) {
27900 $tmp = $this->_md5_16(substr($tmp, 0, $keybytelen));
27901 }
27902 }
27903 $this->encryption_key = substr($tmp,0,$keybytelen);
27904 // Compute U value
27905 $this->Uvalue = $this->_Uvalue();
27906 // Compute P value
27907 $this->Pvalue = $protection;
27908}
27909
27910
27911function _hexToString($hs) {
27912 $s = '';
27913 $len = strlen($hs);
27914 if (($len % 2) != 0) {
27915 $hs .= '0';
27916 ++$len;
27917 }
27918 for ($i = 0; $i < $len; $i += 2) {
27919 $s .= chr(hexdec($hs{$i}.$hs{($i + 1)}));
27920 }
27921 return $s;
27922}
27923
27924/*-- END ENCRYPTION --*/
27925
27926//=========================================
27927/*-- BOOKMARKS --*/
27928// FROM class PDF_Bookmark
27929
27930function Bookmark($txt,$level=0,$y=0) {
27931 $txt = $this->purify_utf8_text($txt);
27932 if ($this->text_input_as_HTML) {
27933 $txt = $this->all_entities_to_utf8($txt);
27934 }
27935 if($y==-1) {
27936 if (!$this->ColActive){ $y=$this->y; }
27937 else { $y = $this->y0; } // If columns are on - mark top of columns
27938 }
27939 // else y is used as set, or =0 i.e. top of page
27940 // DIRECTIONALITY RTL
27941 $bmo = array('t'=>$txt,'l'=>$level,'y'=>$y,'p'=>$this->page);
27942 if ($this->keep_block_together) {
27943 $this->ktBMoutlines[]= $bmo;
27944 }
27945/*-- TABLES --*/
27946 else if ($this->table_rotate) {
27947 $this->tbrot_BMoutlines[]= $bmo;
27948 }
27949 else if ($this->kwt) {
27950 $this->kwt_BMoutlines[]= $bmo;
27951 }
27952/*-- END TABLES --*/
27953 else if ($this->ColActive) { // *COLUMNS*
27954 $this->col_BMoutlines[]= $bmo; // *COLUMNS*
27955 } // *COLUMNS*
27956 else {
27957 $this->BMoutlines[]= $bmo;
27958 }
27959}
27960
27961
27962function _putbookmarks()
27963{
27964 $nb=count($this->BMoutlines);
27965 if($nb==0)
27966 return;
27967
27968 // mPDF 5.6.36
27969 $bmo = $this->BMoutlines;
27970 $this->BMoutlines = array();
27971 $lastlevel = -1;
27972 for($i=0;$i<count($bmo);$i++) {
27973 if ($bmo[$i]['l']>0) {
27974 while($bmo[$i]['l']-$lastlevel > 1) { // If jump down more than one level, insert a new entry
27975 $new = $bmo[$i];
27976 $new['t']="[".$new['t']."]"; // Put [] around text/title to highlight
27977 $new['l']=$lastlevel+1;
27978 $lastlevel++;
27979 $this->BMoutlines[] = $new;
27980 }
27981 }
27982 $this->BMoutlines[] = $bmo[$i];
27983 $lastlevel = $bmo[$i]['l'];
27984 }
27985 $nb=count($this->BMoutlines);
27986
27987 $lru=array();
27988 $level=0;
27989 foreach($this->BMoutlines as $i=>$o) {
27990 if($o['l']>0) {
27991 $parent=$lru[$o['l']-1];
27992 //Set parent and last pointers
27993 $this->BMoutlines[$i]['parent']=$parent;
27994 $this->BMoutlines[$parent]['last']=$i;
27995 if($o['l']>$level) {
27996 //Level increasing: set first pointer
27997 $this->BMoutlines[$parent]['first']=$i;
27998 }
27999 }
28000 else {
28001 $this->BMoutlines[$i]['parent']=$nb;
28002 }
28003 if($o['l']<=$level and $i>0) {
28004 //Set prev and next pointers
28005 $prev=$lru[$o['l']];
28006 $this->BMoutlines[$prev]['next']=$i;
28007 $this->BMoutlines[$i]['prev']=$prev;
28008 }
28009 $lru[$o['l']]=$i;
28010 $level=$o['l'];
28011 }
28012
28013
28014 //Outline items
28015 $n=$this->n+1;
28016 foreach($this->BMoutlines as $i=>$o) {
28017 $this->_newobj();
28018 $this->_out('<</Title '.$this->_UTF16BEtextstring($o['t']));
28019 $this->_out('/Parent '.($n+$o['parent']).' 0 R');
28020 if(isset($o['prev']))
28021 $this->_out('/Prev '.($n+$o['prev']).' 0 R');
28022 if(isset($o['next']))
28023 $this->_out('/Next '.($n+$o['next']).' 0 R');
28024 if(isset($o['first']))
28025 $this->_out('/First '.($n+$o['first']).' 0 R');
28026 if(isset($o['last']))
28027 $this->_out('/Last '.($n+$o['last']).' 0 R');
28028
28029
28030 if (isset($this->pageDim[$o['p']]['h'])) { $h=$this->pageDim[$o['p']]['h']; }
28031 else { $h = 0; }
28032
28033 $this->_out(sprintf('/Dest [%d 0 R /XYZ 0 %.3F null]',1+2*($o['p']),($h-$o['y'])*_MPDFK));
28034 if (isset($this->bookmarkStyles) && isset($this->bookmarkStyles[$o['l']])) {
28035 // font style
28036 $bms = $this->bookmarkStyles[$o['l']]['style'];
28037 $style = 0;
28038 if (strpos($bms,'B') !== false) { $style += 2; }
28039 if (strpos($bms,'I') !== false) { $style += 1; }
28040 $this->_out(sprintf('/F %d', $style));
28041 // Colour
28042 $col = $this->bookmarkStyles[$o['l']]['color'];
28043 if (isset($col) && is_array($col) && count($col)==3) {
28044 $this->_out(sprintf('/C [%.3F %.3F %.3F]', ($col[0]/255), ($col[1]/255), ($col[2]/255)));
28045 }
28046 }
28047
28048 $this->_out('/Count 0>>');
28049 $this->_out('endobj');
28050 }
28051 //Outline root
28052 $this->_newobj();
28053 $this->OutlineRoot=$this->n;
28054 $this->_out('<</Type /BMoutlines /First '.$n.' 0 R');
28055 $this->_out('/Last '.($n+$lru[0]).' 0 R>>');
28056 $this->_out('endobj');
28057}
28058/*-- END BOOKMARKS --*/
28059
28060
28061
28062//======================================================
28063
28064
28065// DEPRACATED but included for backwards compatability
28066function startPageNums() {
28067}
28068
28069//======================================================
28070/*-- TOC --*/
28071// ToC TABLE OF CONTENTS
28072
28073// Initiate, and Mark a place for the Table of Contents to be inserted
28074function TOC($tocfont='', $tocfontsize=0, $tocindent=0, $resetpagenum='', $pagenumstyle='', $suppress='', $toc_orientation='', $TOCusePaging=true, $TOCuseLinking=false, $toc_id=0, $tocoutdent='') { // mPDF 5.6.19
28075 if (!class_exists('tocontents', false)) { include(_MPDF_PATH.'classes/tocontents.php'); }
28076 if (empty($this->tocontents)) { $this->tocontents = new tocontents($this); }
28077 $this->tocontents->TOC($tocfont, $tocfontsize, $tocindent, $resetpagenum, $pagenumstyle, $suppress, $toc_orientation, $TOCusePaging, $TOCuseLinking, $toc_id, $tocoutdent); // mPDF 5.6.19
28078}
28079
28080
28081function TOCpagebreakByArray($a) {
28082 if (!is_array($a)) { $a = array(); }
28083 if (!class_exists('tocontents', false)) { include(_MPDF_PATH.'classes/tocontents.php'); }
28084 if (empty($this->tocontents)) { $this->tocontents = new tocontents($this); }
28085 $tocoutdent = (isset($a['tocoutdent']) ? $a['tocoutdent'] : (isset($a['outdent']) ? $a['outdent'] : ''));
28086 $TOCusePaging = (isset($a['TOCusePaging']) ? $a['TOCusePaging'] : (isset($a['paging']) ? $a['paging'] : true));
28087 $TOCuseLinking = (isset($a['TOCuseLinking']) ? $a['TOCuseLinking'] : (isset($a['links']) ? $a['links'] : ''));
28088 $toc_orientation = (isset($a['toc_orientation']) ? $a['toc_orientation'] : (isset($a['toc-orientation']) ? $a['toc-orientation'] : ''));
28089 $toc_mgl = (isset($a['toc_mgl']) ? $a['toc_mgl'] : (isset($a['toc-margin-left']) ? $a['toc-margin-left'] : ''));
28090 $toc_mgr = (isset($a['toc_mgr']) ? $a['toc_mgr'] : (isset($a['toc-margin-right']) ? $a['toc-margin-right'] : ''));
28091 $toc_mgt = (isset($a['toc_mgt']) ? $a['toc_mgt'] : (isset($a['toc-margin-top']) ? $a['toc-margin-top'] : ''));
28092 $toc_mgb = (isset($a['toc_mgb']) ? $a['toc_mgb'] : (isset($a['toc-margin-bottom']) ? $a['toc-margin-bottom'] : ''));
28093 $toc_mgh = (isset($a['toc_mgh']) ? $a['toc_mgh'] : (isset($a['toc-margin-header']) ? $a['toc-margin-header'] : ''));
28094 $toc_mgf = (isset($a['toc_mgf']) ? $a['toc_mgf'] : (isset($a['toc-margin-footer']) ? $a['toc-margin-footer'] : ''));
28095 $toc_ohname = (isset($a['toc_ohname']) ? $a['toc_ohname'] : (isset($a['toc-odd-header-name']) ? $a['toc-odd-header-name'] : ''));
28096 $toc_ehname = (isset($a['toc_ehname']) ? $a['toc_ehname'] : (isset($a['toc-even-header-name']) ? $a['toc-even-header-name'] : ''));
28097 $toc_ofname = (isset($a['toc_ofname']) ? $a['toc_ofname'] : (isset($a['toc-odd-footer-name']) ? $a['toc-odd-footer-name'] : ''));
28098 $toc_efname = (isset($a['toc_efname']) ? $a['toc_efname'] : (isset($a['toc-even-footer-name']) ? $a['toc-even-footer-name'] : ''));
28099 $toc_ohvalue = (isset($a['toc_ohvalue']) ? $a['toc_ohvalue'] : (isset($a['toc-odd-header-value']) ? $a['toc-odd-header-value'] : 0));
28100 $toc_ehvalue = (isset($a['toc_ehvalue']) ? $a['toc_ehvalue'] : (isset($a['toc-even-header-value']) ? $a['toc-even-header-value'] : 0));
28101 $toc_ofvalue = (isset($a['toc_ofvalue']) ? $a['toc_ofvalue'] : (isset($a['toc-odd-footer-value']) ? $a['toc-odd-footer-value'] : 0));
28102 $toc_efvalue = (isset($a['toc_efvalue']) ? $a['toc_efvalue'] : (isset($a['toc-even-footer-value']) ? $a['toc-even-footer-value'] : 0));
28103 $toc_preHTML = (isset($a['toc_preHTML']) ? $a['toc_preHTML'] : (isset($a['toc-preHTML']) ? $a['toc-preHTML'] : ''));
28104 $toc_postHTML = (isset($a['toc_postHTML']) ? $a['toc_postHTML'] : (isset($a['toc-postHTML']) ? $a['toc-postHTML'] : ''));
28105 $toc_bookmarkText = (isset($a['toc_bookmarkText']) ? $a['toc_bookmarkText'] : (isset($a['toc-bookmarkText']) ? $a['toc-bookmarkText'] : ''));
28106 $resetpagenum = (isset($a['resetpagenum']) ? $a['resetpagenum'] : '');
28107 $pagenumstyle = (isset($a['pagenumstyle']) ? $a['pagenumstyle'] : '');
28108 $suppress = (isset($a['suppress']) ? $a['suppress'] : '');
28109 $orientation = (isset($a['orientation']) ? $a['orientation'] : '');
28110 $mgl = (isset($a['mgl']) ? $a['mgl'] : (isset($a['margin-left']) ? $a['margin-left'] : ''));
28111 $mgr = (isset($a['mgr']) ? $a['mgr'] : (isset($a['margin-right']) ? $a['margin-right'] : ''));
28112 $mgt = (isset($a['mgt']) ? $a['mgt'] : (isset($a['margin-top']) ? $a['margin-top'] : ''));
28113 $mgb = (isset($a['mgb']) ? $a['mgb'] : (isset($a['margin-bottom']) ? $a['margin-bottom'] : ''));
28114 $mgh = (isset($a['mgh']) ? $a['mgh'] : (isset($a['margin-header']) ? $a['margin-header'] : ''));
28115 $mgf = (isset($a['mgf']) ? $a['mgf'] : (isset($a['margin-footer']) ? $a['margin-footer'] : ''));
28116 $ohname = (isset($a['ohname']) ? $a['ohname'] : (isset($a['odd-header-name']) ? $a['odd-header-name'] : ''));
28117 $ehname = (isset($a['ehname']) ? $a['ehname'] : (isset($a['even-header-name']) ? $a['even-header-name'] : ''));
28118 $ofname = (isset($a['ofname']) ? $a['ofname'] : (isset($a['odd-footer-name']) ? $a['odd-footer-name'] : ''));
28119 $efname = (isset($a['efname']) ? $a['efname'] : (isset($a['even-footer-name']) ? $a['even-footer-name'] : ''));
28120 $ohvalue = (isset($a['ohvalue']) ? $a['ohvalue'] : (isset($a['odd-header-value']) ? $a['odd-header-value'] : 0));
28121 $ehvalue = (isset($a['ehvalue']) ? $a['ehvalue'] : (isset($a['even-header-value']) ? $a['even-header-value'] : 0));
28122 $ofvalue = (isset($a['ofvalue']) ? $a['ofvalue'] : (isset($a['odd-footer-value']) ? $a['odd-footer-value'] : 0));
28123 $efvalue = (isset($a['efvalue']) ? $a['efvalue'] : (isset($a['even-footer-value']) ? $a['even-footer-value'] : 0));
28124 $toc_id = (isset($a['toc_id']) ? $a['toc_id'] : (isset($a['name']) ? $a['name'] : 0));
28125 $pagesel = (isset($a['pagesel']) ? $a['pagesel'] : (isset($a['pageselector']) ? $a['pageselector'] : ''));
28126 $toc_pagesel = (isset($a['toc_pagesel']) ? $a['toc_pagesel'] : (isset($a['toc-pageselector']) ? $a['toc-pageselector'] : ''));
28127 $sheetsize = (isset($a['sheetsize']) ? $a['sheetsize'] : (isset($a['sheet-size']) ? $a['sheet-size'] : ''));
28128 $toc_sheetsize = (isset($a['toc_sheetsize']) ? $a['toc_sheetsize'] : (isset($a['toc-sheet-size']) ? $a['toc-sheet-size'] : ''));
28129
28130 $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
28131
28132}
28133
28134function 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) {
28135 if (!class_exists('tocontents', false)) { include(_MPDF_PATH.'classes/tocontents.php'); }
28136 if (empty($this->tocontents)) { $this->tocontents = new tocontents($this); }
28137 //Start a new page
28138 if($this->state==0) $this->AddPage();
28139 if ($this->y == $this->tMargin && (!$this->mirrorMargins ||($this->mirrorMargins && $this->page % 2==1))) {
28140 // Don't add a page
28141 if ($this->page==1 && count($this->PageNumSubstitutions)==0) {
28142 if (!$suppress) { $suppress = 'off'; }
28143 if (!$resetpagenum) { $resetpagenum= 1; }
28144 //$this->PageNumSubstitutions[] = array('from'=>1, 'reset'=> $resetpagenum, 'type'=>$pagenumstyle, 'suppress'=> $suppress);
28145 }
28146 $this->PageNumSubstitutions[] = array('from'=>$this->page, 'reset'=> $resetpagenum, 'type'=>$pagenumstyle, 'suppress'=> $suppress);
28147 }
28148 else {
28149 $this->AddPage($orientation,'NEXT-ODD', $resetpagenum, $pagenumstyle, $suppress,$mgl,$mgr,$mgt,$mgb,$mgh,$mgf,$ohname,$ehname,$ofname,$efname,$ohvalue,$ehvalue,$ofvalue,$efvalue,$pagesel,$sheetsize);
28150 }
28151
28152 $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
28153}
28154
28155function TOC_Entry($txt, $level=0, $toc_id=0) {
28156 // mPDF 5.7.2
28157 if ($this->ColActive) { $ily = $this->y0; } else { $ily = $this->y; } // use top of columns
28158
28159 if (!class_exists('tocontents', false)) { include(_MPDF_PATH.'classes/tocontents.php'); }
28160 if (empty($this->tocontents)) { $this->tocontents = new tocontents($this); }
28161 $linkn = $this->AddLink();
28162 $uid = '__mpdfinternallink_' . $linkn ;
28163 if ($this->keep_block_together) { $this->internallink[$uid] = array("Y"=>$ily,"PAGE"=>$this->page, "kt"=>true ); }
28164 else if ($this->table_rotate) { $this->internallink[$uid] = array("Y"=>$ily,"PAGE"=>$this->page, "tbrot"=>true ); }
28165 else if ($this->kwt) { $this->internallink[$uid] = array("Y"=>$ily,"PAGE"=>$this->page, "kwt"=>true ); }
28166 else if ($this->ColActive) { $this->internallink[$uid] = array("Y"=>$ily,"PAGE"=>$this->page, "col"=>$this->CurrCol ); }
28167 else $this->internallink[$uid] = array("Y"=>$ily,"PAGE"=>$this->page );
28168 $this->internallink['#'.$uid] = $linkn;
28169 $this->SetLink($linkn,$ily,$this->page);
28170
28171/*-- RTL --*/
28172 if ($this->biDirectional) {
28173 $txt = preg_replace_callback("/([".$this->pregRTLchars."]+)/u", array($this, 'arabJoinPregCallback'), $txt ); // mPDF 5.7+
28174 }
28175/*-- END RTL --*/
28176 if (strtoupper($toc_id)=='ALL') { $toc_id = '_mpdf_all'; }
28177 else if (!$toc_id) { $toc_id = 0; }
28178 else { $toc_id = strtolower($toc_id); }
28179 $btoc = array('t'=>$txt,'l'=>$level,'p'=>$this->page, 'link'=>$linkn, 'toc_id'=>$toc_id);
28180 if ($this->keep_block_together) {
28181 $this->_kttoc[]= $btoc;
28182 }
28183/*-- TABLES --*/
28184 else if ($this->table_rotate) {
28185 $this->tbrot_toc[]= $btoc;
28186 }
28187 else if ($this->kwt) {
28188 $this->kwt_toc[]= $btoc;
28189 }
28190/*-- END TABLES --*/
28191 else if ($this->ColActive) { // *COLUMNS*
28192 $this->col_toc[]= $btoc; // *COLUMNS*
28193 } // *COLUMNS*
28194 else {
28195 $this->tocontents->_toc[]= $btoc;
28196 }
28197}
28198
28199/*-- END TOC --*/
28200
28201//======================================================
28202function MovePages($target_page, $start_page, $end_page=-1) {
28203 // move a page/pages EARLIER in the document
28204 if ($end_page<1) { $end_page = $start_page; }
28205 $n_toc = $end_page - $start_page + 1;
28206
28207 // Set/Update PageNumSubstitutions changes before moving anything
28208 if (count($this->PageNumSubstitutions)) {
28209 $tp_present = false;
28210 $sp_present = false;
28211 $ep_present = false;
28212 foreach($this->PageNumSubstitutions AS $k=>$v) {
28213 if ($this->PageNumSubstitutions[$k]['from']==$target_page) {
28214 $tp_present = true;
28215 if ($this->PageNumSubstitutions[$k]['suppress']!='on' && $this->PageNumSubstitutions[$k]['suppress']!=1) {
28216 $this->PageNumSubstitutions[$k]['suppress']='off';
28217 }
28218 }
28219 if ($this->PageNumSubstitutions[$k]['from']==$start_page) {
28220 $sp_present = true;
28221 if ($this->PageNumSubstitutions[$k]['suppress']!='on' && $this->PageNumSubstitutions[$k]['suppress']!=1) {
28222 $this->PageNumSubstitutions[$k]['suppress']='off';
28223 }
28224 }
28225 if ($this->PageNumSubstitutions[$k]['from']==($end_page+1)) {
28226 $ep_present = true;
28227 if ($this->PageNumSubstitutions[$k]['suppress']!='on' && $this->PageNumSubstitutions[$k]['suppress']!=1) {
28228 $this->PageNumSubstitutions[$k]['suppress']='off';
28229 }
28230 }
28231 }
28232
28233 if (!$tp_present) {
28234 list($tp_type, $tp_suppress, $tp_reset) = $this->docPageSettings($target_page);
28235 }
28236 if (!$sp_present) {
28237 list($sp_type, $sp_suppress, $sp_reset) = $this->docPageSettings($start_page);
28238 }
28239 if (!$ep_present) {
28240 list($ep_type, $ep_suppress, $ep_reset) = $this->docPageSettings($start_page-1);
28241 }
28242
28243 }
28244
28245 $last = array();
28246 //store pages
28247 for($i = $start_page;$i <= $end_page ;$i++)
28248 $last[]=$this->pages[$i];
28249 //move pages
28250 for($i=$start_page - 1;$i>=($target_page);$i--) {
28251 $this->pages[$i+$n_toc]=$this->pages[$i];
28252 }
28253 //Put toc pages at insert point
28254 for($i = 0;$i < $n_toc;$i++) {
28255 $this->pages[$target_page + $i]=$last[$i];
28256 }
28257
28258/*-- BOOKMARKS --*/
28259 // Update Bookmarks
28260 foreach($this->BMoutlines as $i=>$o) {
28261 if($o['p']>=$target_page) {
28262 $this->BMoutlines[$i]['p'] += $n_toc;
28263 }
28264 }
28265/*-- END BOOKMARKS --*/
28266
28267 // Update Page Links
28268 if (count($this->PageLinks)) {
28269 $newarr = array();
28270 foreach($this->PageLinks as $i=>$o) {
28271 foreach($this->PageLinks[$i] as $key => $pl) {
28272 if (strpos($pl[4],'@')===0) {
28273 $p=substr($pl[4],1);
28274 if($p>=$start_page && $p<=$end_page) {
28275 $this->PageLinks[$i][$key][4] = '@'.($p + ($target_page - $start_page));
28276 }
28277 else if($p>=$target_page && $p<$start_page) {
28278 $this->PageLinks[$i][$key][4] = '@'.($p+$n_toc);
28279 }
28280 }
28281 }
28282 if($i>=$start_page && $i<=$end_page) {
28283 $newarr[($i + ($target_page - $start_page))] = $this->PageLinks[$i];
28284 }
28285 else if($i>=$target_page && $i<$start_page) {
28286 $newarr[($i + $n_toc)] = $this->PageLinks[$i];
28287 }
28288 else {
28289 $newarr[$i] = $this->PageLinks[$i];
28290 }
28291 }
28292 $this->PageLinks = $newarr;
28293 }
28294
28295 // OrientationChanges
28296 if (count($this->OrientationChanges)) {
28297 $newarr = array();
28298 foreach($this->OrientationChanges AS $p=>$v) {
28299 if($p>=$start_page && $p<=$end_page) { $newarr[($p + ($target_page - $start_page))] = $this->OrientationChanges[$p]; }
28300 else if($p>=$target_page && $p<$start_page) { $newarr[$p+$n_toc] = $this->OrientationChanges[$p]; }
28301 else { $newarr[$p] = $this->OrientationChanges[$p]; }
28302 }
28303 ksort($newarr);
28304 $this->OrientationChanges = $newarr;
28305 }
28306
28307 // Page Dimensions
28308 if (count($this->pageDim)) {
28309 $newarr = array();
28310 foreach($this->pageDim AS $p=>$v) {
28311 if($p>=$start_page && $p<=$end_page) { $newarr[($p + ($target_page - $start_page))] = $this->pageDim[$p]; }
28312 else if($p>=$target_page && $p<$start_page) { $newarr[$p+$n_toc] = $this->pageDim[$p]; }
28313 else { $newarr[$p] = $this->pageDim[$p]; }
28314 }
28315 ksort($newarr);
28316 $this->pageDim = $newarr;
28317 }
28318
28319 // HTML Headers & Footers
28320 if (count($this->saveHTMLHeader)) {
28321 $newarr = array();
28322 foreach($this->saveHTMLHeader AS $p=>$v) {
28323 if($p>=$start_page && $p<=$end_page) { $newarr[($p + ($target_page - $start_page))] = $this->saveHTMLHeader[$p]; }
28324 else if($p>=$target_page && $p<$start_page) { $newarr[$p+$n_toc] = $this->saveHTMLHeader[$p]; }
28325 else { $newarr[$p] = $this->saveHTMLHeader[$p]; }
28326 }
28327 ksort($newarr);
28328 $this->saveHTMLHeader = $newarr;
28329 }
28330 if (count($this->saveHTMLFooter)) {
28331 $newarr = array();
28332 foreach($this->saveHTMLFooter AS $p=>$v) {
28333 if($p>=$start_page && $p<=$end_page) { $newarr[($p + ($target_page - $start_page))] = $this->saveHTMLFooter[$p]; }
28334 else if($p>=$target_page && $p<$start_page) { $newarr[$p+$n_toc] = $this->saveHTMLFooter[$p]; }
28335 else { $newarr[$p] = $this->saveHTMLFooter[$p]; }
28336 }
28337 ksort($newarr);
28338 $this->saveHTMLFooter = $newarr;
28339 }
28340
28341 // Update Internal Links
28342 if (count($this->internallink)) {
28343 foreach($this->internallink as $key=>$o) {
28344 if($o['PAGE']>=$start_page && $o['PAGE']<=$end_page) {
28345 $this->internallink[$key]['PAGE'] += ($target_page - $start_page);
28346 }
28347 else if($o['PAGE']>=$target_page && $o['PAGE']<$start_page) {
28348 $this->internallink[$key]['PAGE'] += $n_toc;
28349 }
28350 }
28351 }
28352
28353 // Update Links
28354 if (count($this->links)) {
28355 foreach($this->links as $key=>$o) {
28356 if($o[0]>=$start_page && $o[0]<=$end_page) {
28357 $this->links[$key][0] += ($target_page - $start_page);
28358 }
28359 if($o[0]>=$target_page && $o[0]<$start_page) {
28360 $this->links[$key][0] += $n_toc;
28361 }
28362 }
28363 }
28364
28365 // Update Form fields
28366 if (count($this->form->forms)) {
28367 foreach($this->form->forms as $key=>$f) {
28368 if($f['page']>=$start_page && $f['page']<=$end_page) {
28369 $this->form->forms[$key]['page'] += ($target_page - $start_page);
28370 }
28371 if($f['page']>=$target_page && $f['page']<$start_page) {
28372 $this->form->forms[$key]['page'] += $n_toc;
28373 }
28374 }
28375 }
28376
28377/*-- ANNOTATIONS --*/
28378 // Update Annotations
28379 if (count($this->PageAnnots)) {
28380 $newarr = array();
28381 foreach($this->PageAnnots as $p=>$anno) {
28382 if($p>=$start_page && $p<=$end_page) {
28383 $np = $p + ($target_page - $start_page);
28384 foreach($anno as $o) {
28385 $newarr[$np][] = $o;
28386 }
28387 }
28388 else if($p>=$target_page && $p<$start_page) {
28389 $np = $p + $n_toc;
28390 foreach($anno as $o) {
28391 $newarr[$np][] = $o;
28392 }
28393 }
28394 else {
28395 $newarr[$p] = $this->PageAnnots[$p];
28396 }
28397 }
28398 $this->PageAnnots = $newarr;
28399 unset($newarr);
28400 }
28401/*-- END ANNOTATIONS --*/
28402
28403 // Update PageNumSubstitutions
28404 if (count($this->PageNumSubstitutions)) {
28405 $newarr = array();
28406 foreach($this->PageNumSubstitutions AS $k=>$v) {
28407 if($this->PageNumSubstitutions[$k]['from']>=$start_page && $this->PageNumSubstitutions[$k]['from']<=$end_page) {
28408 $this->PageNumSubstitutions[$k]['from'] += ($target_page - $start_page);
28409 $newarr[$this->PageNumSubstitutions[$k]['from']] = $this->PageNumSubstitutions[$k];
28410 }
28411 else if($this->PageNumSubstitutions[$k]['from']>=$target_page && $this->PageNumSubstitutions[$k]['from']<$start_page) {
28412 $this->PageNumSubstitutions[$k]['from'] += $n_toc;
28413 $newarr[$this->PageNumSubstitutions[$k]['from']] = $this->PageNumSubstitutions[$k];
28414 }
28415 else {
28416 $newarr[$this->PageNumSubstitutions[$k]['from']] = $this->PageNumSubstitutions[$k];
28417 }
28418 }
28419
28420 if (!$sp_present) {
28421 $newarr[$target_page] = array('from'=>$target_page, 'suppress'=>$sp_suppress, 'reset'=>$sp_reset, 'type'=>$sp_type);
28422 }
28423 if (!$tp_present) {
28424 $newarr[($target_page + $n_toc)] = array('from'=>($target_page+$n_toc), 'suppress'=>$tp_suppress, 'reset'=>$tp_reset, 'type'=>$tp_type);
28425 }
28426 if (!$ep_present && $end_page>count($this->pages)) {
28427 $newarr[($end_page+1)] = array('from'=>($end_page+1), 'suppress'=>$ep_suppress, 'reset'=>$ep_reset, 'type'=>$ep_type);
28428 }
28429 ksort($newarr);
28430 $this->PageNumSubstitutions = array();
28431 foreach($newarr as $v) {
28432 $this->PageNumSubstitutions[] = $v;
28433 }
28434 }
28435}
28436
28437//======================================================
28438function DeletePages($start_page, $end_page=-1) {
28439 // move a page/pages EARLIER in the document
28440 if ($end_page<1) { $end_page = $start_page; }
28441 $n_tod = $end_page - $start_page + 1;
28442 $last_page = count($this->pages);
28443 $n_atend = $last_page - $end_page + 1;
28444
28445 //move pages
28446 for($i=0;$i<$n_atend;$i++) {
28447 $this->pages[$start_page+$i]=$this->pages[$end_page+1+$i];
28448 }
28449 //delete pages
28450 for($i = 0;$i < $n_tod ;$i++)
28451 unset($this->pages[$last_page-$i]);
28452
28453
28454/*-- BOOKMARKS --*/
28455 // Update Bookmarks
28456 foreach($this->BMoutlines as $i=>$o) {
28457 if($o['p']>=$end_page) { $this->BMoutlines[$i]['p'] -= $n_tod; }
28458 else if($p<$start_page) { unset($this->BMoutlines[$i]); }
28459 }
28460/*-- END BOOKMARKS --*/
28461
28462 // Update Page Links
28463 if (count($this->PageLinks)) {
28464 $newarr = array();
28465 foreach($this->PageLinks as $i=>$o) {
28466 foreach($this->PageLinks[$i] as $key => $pl) {
28467 if (strpos($pl[4],'@')===0) {
28468 $p=substr($pl[4],1);
28469 if($p>$end_page) { $this->PageLinks[$i][$key][4] = '@'.($p - $n_tod); }
28470 else if($p<$start_page) { unset($this->PageLinks[$i][$key]); }
28471 }
28472 }
28473 if($i>$end_page) { $newarr[($i - $n_tod)] = $this->PageLinks[$i]; }
28474 else if($p<$start_page) { $newarr[$i] = $this->PageLinks[$i]; }
28475 }
28476 $this->PageLinks = $newarr;
28477 }
28478
28479 // OrientationChanges
28480 if (count($this->OrientationChanges)) {
28481 $newarr = array();
28482 foreach($this->OrientationChanges AS $p=>$v) {
28483 if($p>$end_page) { $newarr[($p - $t_tod)] = $this->OrientationChanges[$p]; }
28484 else if($p<$start_page) { $newarr[$p] = $this->OrientationChanges[$p]; }
28485 }
28486 ksort($newarr);
28487 $this->OrientationChanges = $newarr;
28488 }
28489
28490 // Page Dimensions
28491 if (count($this->pageDim)) {
28492 $newarr = array();
28493 foreach($this->pageDim AS $p=>$v) {
28494 if($p>$end_page) { $newarr[($p - $n_tod)] = $this->pageDim[$p]; }
28495 else if($p<$start_page) { $newarr[$p] = $this->pageDim[$p]; }
28496 }
28497 ksort($newarr);
28498 $this->pageDim = $newarr;
28499 }
28500
28501 // HTML Headers & Footers
28502 if (count($this->saveHTMLHeader)) {
28503 foreach($this->saveHTMLHeader AS $p=>$v) {
28504 if($p>end_page) { $newarr[($p - $n_tod)] = $this->saveHTMLHeader[$p]; }
28505 else if($p<$start_page) { $newarr[$p] = $this->saveHTMLHeader[$p]; }
28506 }
28507 ksort($newarr);
28508 $this->saveHTMLHeader = $newarr;
28509 }
28510 if (count($this->saveHTMLFooter)) {
28511 $newarr = array();
28512 foreach($this->saveHTMLFooter AS $p=>$v) {
28513 if($p>$end_page) { $newarr[($p - $n_tod)] = $this->saveHTMLFooter[$p]; }
28514 else if($p<$start_page) { $newarr[$p] = $this->saveHTMLFooter[$p]; }
28515 }
28516 ksort($newarr);
28517 $this->saveHTMLFooter = $newarr;
28518 }
28519
28520 // Update Internal Links
28521 foreach($this->internallink as $key=>$o) {
28522 if($o['PAGE']>$end_page) { $this->internallink[$key]['PAGE'] -= $n_tod; }
28523 else if($o['PAGE']<$start_page) { unset($this->internallink[$key]); }
28524 }
28525
28526 // Update Links
28527 foreach($this->links as $key=>$o) {
28528 if($o[0]>$end_page) { $this->links[$key][0] -= $n_tod; }
28529 else if($o[0]<$start_page) { unset($this->links[$key]); }
28530 }
28531
28532 // Update Form fields
28533 foreach($this->form->forms as $key=>$f) {
28534 if($f['page']>$end_page) { $this->form->forms[$key]['page'] -= $n_tod; }
28535 else if($f['page']<$start_page) { unset($this->form->forms[$key]); }
28536 }
28537
28538/*-- ANNOTATIONS --*/
28539 // Update Annotations
28540 if (count($this->PageAnnots)) {
28541 $newarr = array();
28542 foreach($this->PageAnnots as $p=>$anno) {
28543 if($p>$end_page) { foreach($anno as $o) { $newarr[($p - $n_tod)][] = $o; } }
28544 else if($p<$start_page) { $newarr[$p] = $this->PageAnnots[$p]; }
28545 }
28546 ksort($newarr);
28547 $this->PageAnnots = $newarr;
28548 }
28549/*-- END ANNOTATIONS --*/
28550
28551 // Update PageNumSubstitutions
28552 foreach($this->PageNumSubstitutions AS $k=>$v) {
28553 if($this->PageNumSubstitutions[$k]['from']>$end_page) { $this->PageNumSubstitutions[$k]['from'] -= $n_tod; }
28554 else if($this->PageNumSubstitutions[$k]['from']<$start_page) { unset($this->PageNumSubstitutions[$k]); }
28555 }
28556
28557 unset($newarr);
28558 $this->page = count($this->pages);
28559}
28560
28561
28562//======================================================
28563/*-- INDEX --*/
28564// FROM class PDF_Ref == INDEX
28565
28566function Reference($txt) {
28567 $this->IndexEntry($txt);
28568}
28569
28570
28571function IndexEntry($txt, $xref='') {
28572 if ($xref) {
28573 $this->IndexEntrySee($txt,$xref);
28574 return;
28575 }
28576 $txt = strip_tags($txt);
28577 $txt = $this->purify_utf8_text($txt);
28578 if ($this->text_input_as_HTML) {
28579 $txt = $this->all_entities_to_utf8($txt);
28580 }
28581 if ($this->usingCoreFont) { $txt = mb_convert_encoding($txt,$this->mb_enc,'UTF-8'); }
28582
28583 $Present=0;
28584 $size=sizeof($this->Reference);
28585
28586 if ($this->directionality == 'rtl') { // *RTL*
28587 $txt = str_replace(':',' - ',$txt); // *RTL*
28588 } // *RTL*
28589 else { // *RTL*
28590 $txt = str_replace(':',', ',$txt);
28591 } // *RTL*
28592
28593
28594 //Search the reference (AND Ref/PageNo) in the array
28595 for ($i=0;$i<$size;$i++){
28596 if ($this->keep_block_together) {
28597 if (isset($this->ktReference[$i]['t']) && $this->ktReference[$i]['t']==$txt){
28598 $Present=1;
28599 if ($this->page != $this->ktReference[$i]['op']) { // mPDF 5.7.2
28600 $this->ktReference[$i]['op'] = $this->page;
28601 }
28602 }
28603 }
28604/*-- TABLES --*/
28605 else if ($this->table_rotate) {
28606 if (isset($this->tbrot_Reference[$i]['t']) && $this->tbrot_Reference[$i]['t']==$txt){
28607 $Present=1;
28608 if ($this->page != $this->tbrot_Reference[$i]['op']) { // mPDF 5.7.2
28609 $this->tbrot_Reference[$i]['op'] = $this->page;
28610 }
28611 }
28612 }
28613 else if ($this->kwt) {
28614 if (isset($this->kwt_Reference[$i]['t']) && $this->kwt_Reference[$i]['t']==$txt){
28615 $Present=1;
28616 if ($this->page != $this->kwt_Reference[$i]['op']) { // mPDF 5.7.2
28617 $this->kwt_Reference[$i]['op'] = $this->page;
28618 }
28619 }
28620 }
28621/*-- END TABLES --*/
28622/*-- COLUMNS --*/
28623 else if ($this->ColActive) {
28624 if (isset($this->col_Reference[$i]['t']) && $this->col_Reference[$i]['t']==$txt){
28625 $Present=1;
28626 if ($this->page != $this->col_Reference[$i]['op']) { // mPDF 5.7.2
28627 $this->col_Reference[$i]['op'] = $this->page;
28628 }
28629 }
28630 }
28631/*-- END COLUMNS --*/
28632 else {
28633 if (isset($this->Reference[$i]['t']) && $this->Reference[$i]['t']==$txt){
28634 $Present=1;
28635 if (!in_array($this->page,$this->Reference[$i]['p'])) {
28636 $this->Reference[$i]['p'][] = $this->page;
28637 }
28638 }
28639 }
28640 }
28641 //If not found, add it
28642 if ($Present==0) {
28643 $opr = array('t'=>$txt, 'op'=>$this->page);
28644 if ($this->keep_block_together) {
28645 $this->ktReference[]= $opr;
28646 }
28647/*-- TABLES --*/
28648 else if ($this->table_rotate) {
28649 $this->tbrot_Reference[]= $opr;
28650 }
28651 else if ($this->kwt) {
28652 $this->kwt_Reference[]= $opr;
28653 }
28654/*-- END TABLES --*/
28655/*-- COLUMNS --*/
28656 else if ($this->ColActive) {
28657 $this->col_Reference[]= $opr;
28658 }
28659/*-- END COLUMNS --*/
28660 else {
28661 $this->Reference[]=array('t'=>$txt,'p'=>array($this->page));
28662 }
28663 }
28664}
28665
28666// Added function to add a reference "Elephants. See Chickens"
28667function ReferenceSee($txta,$txtb) {
28668 $this->IndexEntrySee($txta,$txtb);
28669}
28670
28671function IndexEntrySee($txta,$txtb) {
28672 $txta = strip_tags($txta);
28673 $txtb = strip_tags($txtb);
28674 $txta = $this->purify_utf8_text($txta);
28675 $txtb = $this->purify_utf8_text($txtb);
28676 if ($this->text_input_as_HTML) {
28677 $txta = $this->all_entities_to_utf8($txta);
28678 $txtb = $this->all_entities_to_utf8($txtb);
28679 }
28680 if ($this->usingCoreFont) {
28681 $txta = mb_convert_encoding($txta,$this->mb_enc,'UTF-8');
28682 $txtb = mb_convert_encoding($txtb,$this->mb_enc,'UTF-8');
28683 }
28684 if ($this->directionality == 'rtl') { // *RTL*
28685 $txta = str_replace(':',' - ',$txta); // *RTL*
28686 $txtb = str_replace(':',' - ',$txtb); // *RTL*
28687 } // *RTL*
28688 else { // *RTL*
28689 $txta = str_replace(':',', ',$txta);
28690 $txtb = str_replace(':',', ',$txtb);
28691 } // *RTL*
28692 $this->Reference[]=array('t'=>$txta.' - see '.$txtb,'p'=>array());
28693}
28694
28695function CreateReference($NbCol=1, $reffontsize='', $linespacing='', $offset=3, $usedivletters=1, $divlettfontsize='', $gap=5, $reffont='',$divlettfont='', $useLinking=false) {
28696 $this->CreateIndex($NbCol, $reffontsize, $linespacing, $offset, $usedivletters, $divlettfontsize, $gap, $reffont, $divlettfont, $useLinking);
28697}
28698
28699function CreateIndex($NbCol=1, $reffontsize='', $linespacing='', $offset=3, $usedivletters=1, $divlettfontsize='', $gap=5, $reffont='',$divlettfont='', $useLinking=false) {
28700 if (!$reffontsize) { $reffontsize = $this->default_font_size; }
28701 if (!$divlettfontsize) { $divlettfontsize = ($this->default_font_size * 1.8); }
28702 if (!$reffont) { $reffont = $this->default_font; }
28703 if (!$divlettfont) { $divlettfont = $reffont; }
28704 if (!$linespacing) { $linespacing= $this->default_lineheight_correction; }
28705 if ($this->ColActive) { $this->SetColumns(0); } // *COLUMNS*
28706 $size=sizeof($this->Reference);
28707 if ($size == 0) { return false; }
28708
28709
28710 if ($NbCol<2) {
28711 $NbCol = 1;
28712 $colWidth = $this->pgwidth;
28713 }
28714 else {
28715 $this->SetColumns($NbCol,'',$gap);
28716 $colWidth = $this->ColWidth;
28717 }
28718 if ($this->directionality == 'rtl') { $align = 'R'; }
28719 else { $align = 'L'; }
28720 $lett = '';
28721 if (!function_exists('cmp')) {
28722 function cmp ($a, $b) {
28723 return strnatcmp(strtolower($a['t']), strtolower($b['t']));
28724 }
28725 }
28726 //Alphabetic sort of the references
28727 usort($this->Reference, 'cmp');
28728 $size=sizeof($this->Reference);
28729 $this->breakpoints[$this->CurrCol][] = $this->y; // *COLUMNS*
28730
28731 $divlettjuststarted = false;
28732
28733 $this->OpenTag('DIV',array('STYLE'=>'line-height: '.$linespacing.'; font-family: '.$reffont.'; font-size: '.$reffontsize.'pt; '));
28734
28735 $last_lett = '';
28736 for ($i=0;$i<$size;$i++){
28737 if ($this->Reference[$i]['t']) {
28738 if ($usedivletters) {
28739
28740 $lett = mb_strtoupper(mb_substr($this->Reference[$i]['t'],0,1,$this->mb_enc ),$this->mb_enc );
28741 if ($lett != $last_lett) {
28742
28743 $save_bp = $this->breakpoints[$this->CurrCol]; // *COLUMNS*
28744 $divlettjuststarted = true;
28745
28746 if ($i>0) {
28747 $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; '));
28748 }
28749 else {
28750 $this->OpenTag('DIV',array('STYLE'=>'line-height: '.$linespacing.'; font-family: '.$divlettfont.'; font-size: '.$divlettfontsize.'pt; font-weight: bold; page-break-after: avoid; '));
28751 }
28752 $this->_saveTextBuffer($lett);
28753 $this->CloseTag('DIV');
28754 }
28755 }
28756
28757 $this->OpenTag('DIV',array('STYLE'=>'text-indent: -'.$offset.'mm; line-height: '.$linespacing.'; font-family: '.$reffont.'; font-size: '.$reffontsize.'pt; '));
28758
28759/*-- RTL --*/
28760 // Change Arabic + Persian. to Presentation Forms
28761 if ($this->biDirectional) {
28762 $this->Reference[$i]['t'] = preg_replace_callback("/([".$this->pregRTLchars."]+)/u", array($this, 'arabJoinPregCallback'), $this->Reference[$i]['t'] ); // mPDF 5.7+
28763 }
28764/*-- END RTL --*/
28765
28766 // Font-specific ligature substitution for Indic fonts
28767 if (isset($this->CurrentFont['indic']) && $this->CurrentFont['indic']) $this->ConvertIndic($this->Reference[$i]['t']); // *INDIC*
28768
28769 $this->_saveTextBuffer($this->Reference[$i]['t']);
28770 $ppp = $this->Reference[$i]['p']; // = array of page numbers to point to
28771 if (count($ppp)) {
28772 sort($ppp);
28773 $newarr = array();
28774 $range_start = $ppp[0];
28775 $range_end = 0;
28776
28777 if (!$this->usingCoreFont) { $spacer = "\xc2\xa0 "; }
28778 else { $spacer = chr(160).' '; }
28779 $this->_saveTextBuffer($spacer);
28780 if ($this->directionality == 'rtl') { $sep = '.'; $joiner = '-'; }
28781 else { $sep = ', '; $joiner = '-'; }
28782 for ($zi=1;$zi<count($ppp);$zi++) {
28783 // RTL - Each number separately
28784 if ($this->directionality == 'rtl') {
28785/*-- RTL --*/
28786 if ($zi<count($ppp)-1) {
28787 $txt = $sep . $this->docPageNum($ppp[$zi]);
28788 if ($useLinking) { $href = '@'.$ppp[$zi]; }
28789 else { $href = ''; }
28790 $this->_saveTextBuffer($txt, $href);
28791 }
28792/*-- END RTL --*/
28793 }
28794
28795 else if ($ppp[$zi] == ($ppp[($zi-1)]+1)) {
28796 $range_end = $ppp[$zi];
28797 }
28798 else {
28799 if ($range_end) {
28800 if ($range_end == $range_start+1) {
28801 if ($useLinking) { $href = '@'.$range_start; }
28802 else { $href = ''; }
28803 $txt = $this->docPageNum($range_start) . $sep;
28804 $this->_saveTextBuffer($txt, $href);
28805 if ($useLinking) { $href = '@'.$ppp[$zi-1]; }
28806 else { $href = ''; }
28807 $txt = $this->docPageNum($ppp[$zi-1]) . $sep;
28808 $this->_saveTextBuffer($txt, $href);
28809 }
28810 else {
28811 if ($useLinking) { $href = '@'.$range_start; }
28812 else { $href = ''; }
28813 }
28814 }
28815 else {
28816 if ($useLinking) { $href = '@'.$ppp[$zi-1]; }
28817 else { $href = ''; }
28818 $txt = $this->docPageNum($ppp[$zi-1]) . $sep;
28819 $this->_saveTextBuffer($txt, $href);
28820 }
28821 $range_start = $ppp[$zi];
28822 $range_end = 0;
28823 }
28824 }
28825
28826 if ($range_end) {
28827 if ($range_end == $range_start+1) {
28828 if ($useLinking) { $href = '@'.$range_start; }
28829 else { $href = ''; }
28830 $txt = $this->docPageNum($range_start) . $sep;
28831 $this->_saveTextBuffer($txt, $href);
28832 if ($useLinking) { $href = '@'.$range_end; }
28833 else { $href = ''; }
28834 $txt = $this->docPageNum($range_end);
28835 $this->_saveTextBuffer($txt, $href);
28836 }
28837 else {
28838 if ($useLinking) { $href = '@'.$range_start; }
28839 else { $href = ''; }
28840 $txt = $this->docPageNum($range_start) . $joiner;
28841 $this->_saveTextBuffer($txt, $href);
28842 if ($useLinking) { $href = '@'.$range_end; }
28843 else { $href = ''; }
28844 $txt = $this->docPageNum($range_end);
28845 $this->_saveTextBuffer($txt, $href);
28846 }
28847 }
28848 else {
28849 if ($useLinking) { $href = '@'.$ppp[(count($ppp)-1)]; }
28850 else { $href = ''; }
28851 $txt = $this->docPageNum($ppp[(count($ppp)-1)]);
28852 $this->_saveTextBuffer($txt, $href);
28853 }
28854 }
28855 }
28856 $this->CloseTag('DIV');
28857
28858 if ($divlettjuststarted) { $this->breakpoints[$this->CurrCol] = $save_bp; } // *COLUMNS*
28859 $divlettjuststarted = false;
28860
28861 $this->breakpoints[$this->CurrCol][] = $this->y; // *COLUMNS*
28862 $last_lett = $lett;
28863 }
28864 $this->CloseTag('DIV');
28865 $this->breakpoints[$this->CurrCol][] = $this->y; // *COLUMNS*
28866 if ($this->ColActive) { $this->SetColumns(0); } // *COLUMNS*
28867}
28868/*-- END INDEX --*/
28869
28870
28871function AcceptPageBreak() {
28872 if (count($this->cellBorderBuffer)) { $this->printcellbuffer(); } // *TABLES*
28873/*-- COLUMNS --*/
28874 if ($this->ColActive==1) {
28875 if($this->CurrCol<$this->NbCol-1) {
28876 //Go to the next column
28877 $this->CurrCol++;
28878 $this->SetCol($this->CurrCol);
28879 $this->y=$this->y0;
28880 $this->ChangeColumn=1; // Number (and direction) of columns changed +1, +2, -2 etc.
28881 // DIRECTIONALITY RTL
28882 if ($this->directionality == 'rtl') { $this->ChangeColumn = -($this->ChangeColumn); } // *RTL*
28883
28884 //Stay on the page
28885 return false;
28886 }
28887 else {
28888 //Go back to the first column - NEW PAGE
28889 if (count($this->columnbuffer)) { $this->printcolumnbuffer(); }
28890 $this->SetCol(0);
28891 $this->y0 = $this->tMargin;
28892 $this->ChangeColumn= -($this->NbCol-1);
28893 // DIRECTIONALITY RTL
28894 if ($this->directionality == 'rtl') { $this->ChangeColumn = -($this->ChangeColumn); } // *RTL*
28895 //Page break
28896 return true;
28897 }
28898 }
28899/*-- END COLUMNS --*/
28900/*-- TABLES --*/
28901 else if ($this->table_rotate) {
28902 if ($this->tablebuffer) { $this->printtablebuffer(); }
28903 return true;
28904 }
28905/*-- END TABLES --*/
28906 else { // *COLUMNS*
28907 $this->ChangeColumn=0;
28908 return $this->autoPageBreak;
28909 } // *COLUMNS*
28910 return $this->autoPageBreak;
28911}
28912
28913
28914//----------- COLUMNS ---------------------
28915/*-- COLUMNS --*/
28916
28917function SetColumns($NbCol,$vAlign='',$gap=5) {
28918// NbCol = number of columns
28919// CurrCol = Number of the current column starting at 0
28920// Called externally to set columns on/off and number
28921// Integer 2 upwards sets columns on to that number
28922// Anything less than 2 turns columns off
28923 if ($NbCol<2) { // SET COLUMNS OFF
28924 if ($this->ColActive) {
28925 $this->ColActive=0;
28926 if (count($this->columnbuffer)) { $this->printcolumnbuffer(); }
28927 $this->NbCol=1;
28928 $this->ResetMargins();
28929 $this->pgwidth = $this->w - $this->lMargin - $this->rMargin;
28930 $this->divwidth = 0;
28931 $this->Ln();
28932 }
28933 $this->ColActive=0;
28934 $this->columnbuffer = array();
28935 $this->ColDetails = array();
28936 $this->columnLinks = array();
28937 $this->columnAnnots = array();
28938 $this->columnForms = array();
28939 $this->col_Reference = array();
28940 $this->col_BMoutlines = array();
28941 $this->col_toc = array();
28942 $this->breakpoints = array();
28943 }
28944 else { // SET COLUMNS ON
28945 if ($this->ColActive) {
28946 $this->ColActive=0;
28947 if (count($this->columnbuffer)) { $this->printcolumnbuffer(); }
28948 $this->ResetMargins();
28949 }
28950 if (isset($this->y) && $this->y>$this->tMargin) $this->Ln();
28951 $this->NbCol=$NbCol;
28952 $this->ColGap = $gap;
28953 $this->divwidth = 0;
28954 $this->ColActive=1;
28955 $this->ColumnAdjust = true; // enables column height adjustment for the page
28956 $this->columnbuffer = array();
28957 $this->ColDetails = array();
28958 $this->columnLinks = array();
28959 $this->columnAnnots = array();
28960 $this->columnForms = array();
28961 $this->col_Reference = array();
28962 $this->col_BMoutlines = array();
28963 $this->col_toc = array();
28964 $this->breakpoints = array();
28965 if ((strtoupper($vAlign) == 'J') || (strtoupper($vAlign) == 'JUSTIFY')) { $vAlign = 'J'; }
28966 else { $vAlign = ''; }
28967 $this->colvAlign = $vAlign;
28968 //Save the ordinate
28969 $absL = $this->DeflMargin-($gap/2);
28970 $absR = $this->DefrMargin-($gap/2);
28971 $PageWidth = $this->w-$absL-$absR; // virtual pagewidth for calculation only
28972 $ColWidth = (($PageWidth - ($gap * ($NbCol)))/$NbCol);
28973 $this->ColWidth = $ColWidth;
28974/*-- RTL --*/
28975
28976 if ($this->directionality == 'rtl') {
28977 for ($i=0;$i<$this->NbCol;$i++) {
28978 $this->ColL[$i] = $absL + ($gap/2) + (($NbCol - ($i+1))*($PageWidth/$NbCol)) ;
28979 $this->ColR[$i] = $this->ColL[$i] + $ColWidth; // NB This is not R margin -> R pos
28980 }
28981 }
28982 else {
28983/*-- END RTL --*/
28984 for ($i=0;$i<$this->NbCol;$i++) {
28985 $this->ColL[$i] = $absL + ($gap/2) + ($i* ($PageWidth/$NbCol) );
28986 $this->ColR[$i] = $this->ColL[$i] + $ColWidth; // NB This is not R margin -> R pos
28987 }
28988 } // *RTL*
28989 $this->pgwidth = $ColWidth;
28990 $this->SetCol(0);
28991 $this->y0=$this->y;
28992 }
28993 $this->x = $this->lMargin;
28994}
28995
28996function SetCol($CurrCol) {
28997// Used internally to set column by number: 0 is 1st column
28998 //Set position on a column
28999 $this->CurrCol=$CurrCol;
29000 $x = $this->ColL[$CurrCol];
29001 $xR = $this->ColR[$CurrCol]; // NB This is not R margin -> R pos
29002 if (($this->mirrorMargins) && (($this->page)%2==0)) { // EVEN
29003 $x += $this->MarginCorrection ;
29004 $xR += $this->MarginCorrection ;
29005 }
29006 $this->SetMargins($x,($this->w - $xR),$this->tMargin);
29007}
29008
29009function AddColumn() {
29010 $this->NewColumn();
29011 $this->ColumnAdjust = false; // disables all column height adjustment for the page.
29012}
29013function NewColumn() {
29014 if ($this->ColActive==1) {
29015 if($this->CurrCol<$this->NbCol-1) {
29016 //Go to the next column
29017 $this->CurrCol++;
29018 $this->SetCol($this->CurrCol);
29019 $this->y = $this->y0;
29020 $this->ChangeColumn=1;
29021 // DIRECTIONALITY RTL
29022 if ($this->directionality == 'rtl') { $this->ChangeColumn = -($this->ChangeColumn); } // *RTL*
29023 //Stay on the page
29024 }
29025 else {
29026 //Go back to the first column
29027 //Page break
29028 if (count($this->columnbuffer)) { $this->printcolumnbuffer(); }
29029 $this->AddPage($this->CurOrientation);
29030 $this->SetCol(0);
29031 $this->y0 = $this->tMargin;
29032 $this->ChangeColumn= -($this->NbCol-1);
29033 // DIRECTIONALITY RTL
29034 if ($this->directionality == 'rtl') { $this->ChangeColumn = -($this->ChangeColumn); } // *RTL*
29035 }
29036 $this->x = $this->lMargin;
29037 }
29038 else {
29039 $this->AddPage($this->CurOrientation);
29040 }
29041}
29042
29043function printcolumnbuffer() {
29044 // Columns ended (but page not ended) -> try to match all columns - unless disabled by using a custom column-break
29045 if (!$this->ColActive && $this->ColumnAdjust && !$this->keepColumns) { // mPDF 5.7.2
29046 // Calculate adjustment to add to each column to calculate rel_y value
29047 $this->ColDetails[0]['add_y'] = 0;
29048 $last_col = 0;
29049 // Recursively add previous column's height
29050 for($i=1;$i<$this->NbCol;$i++) {
29051 if (isset($this->ColDetails[$i]['bottom_margin']) && $this->ColDetails[$i]['bottom_margin']) { // If any entries in the column
29052 $this->ColDetails[$i]['add_y'] = ($this->ColDetails[$i-1]['bottom_margin'] - $this->y0) + $this->ColDetails[$i-1]['add_y'];
29053 $last_col = $i; // Last column actually printed
29054 }
29055 }
29056
29057 // Calculate value for each position sensitive entry as though for one column
29058 foreach($this->columnbuffer AS $key=>$s) {
29059 $t = $s['s'];
29060 if ($t == 'ACROFORM') {
29061 $this->columnbuffer[$key]['rel_y'] = $s['y'] + $this->ColDetails[$s['col']]['add_y'] - $this->y0;
29062 $this->columnbuffer[$key]['s'] = '';
29063 }
29064 else if (preg_match('/BT \d+\.\d\d+ (\d+\.\d\d+) Td/',$t)) {
29065 $this->columnbuffer[$key]['rel_y'] = $s['y'] + $this->ColDetails[$s['col']]['add_y'] - $this->y0;
29066 }
29067 else if (preg_match('/\d+\.\d\d+ (\d+\.\d\d+) \d+\.\d\d+ [\-]{0,1}\d+\.\d\d+ re/',$t)) {
29068 $this->columnbuffer[$key]['rel_y'] = $s['y'] + $this->ColDetails[$s['col']]['add_y'] - $this->y0;
29069 }
29070 else if (preg_match('/\d+\.\d\d+ (\d+\.\d\d+) m/',$t)) {
29071 $this->columnbuffer[$key]['rel_y'] = $s['y'] + $this->ColDetails[$s['col']]['add_y'] - $this->y0;
29072 }
29073 else if (preg_match('/\d+\.\d\d+ (\d+\.\d\d+) l/',$t)) {
29074 $this->columnbuffer[$key]['rel_y'] = $s['y'] + $this->ColDetails[$s['col']]['add_y'] - $this->y0;
29075 }
29076 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)) {
29077 $this->columnbuffer[$key]['rel_y'] = $s['y'] + $this->ColDetails[$s['col']]['add_y'] - $this->y0;
29078 }
29079 else if (preg_match('/\d+\.\d\d+ (\d+\.\d\d+) \d+\.\d\d+ \d+\.\d\d+ \d+\.\d\d+ \d+\.\d\d+ c/',$t)) {
29080 $this->columnbuffer[$key]['rel_y'] = $s['y'] + $this->ColDetails[$s['col']]['add_y'] - $this->y0;
29081 }
29082 }
29083 foreach($this->internallink AS $key => $f) {
29084 if (is_array($f) && isset($f['col'])) {
29085 $this->internallink[$key]['rel_y'] = $f['Y'] + $this->ColDetails[$f['col']]['add_y'] - $this->y0;
29086 }
29087 }
29088
29089 $breaks = array();
29090 foreach($this->breakpoints AS $c => $bpa) {
29091 foreach($bpa AS $rely) {
29092 $breaks[] = $rely + $this->ColDetails[$c]['add_y'] - $this->y0;
29093 }
29094 }
29095
29096 if (isset($this->ColDetails[$last_col]['bottom_margin'])) { $lcbm = $this->ColDetails[$last_col]['bottom_margin']; }
29097 else { $lcbm = 0; }
29098 $sum_h = $this->ColDetails[$last_col]['add_y'] + $lcbm - $this->y0;
29099 //$sum_h = max($this->ColDetails[$last_col]['add_y'] + $this->ColDetails[$last_col]['bottom_margin'] - $this->y0, end($breaks));
29100 $target_h = ($sum_h / $this->NbCol);
29101
29102 $cbr = array();
29103 for($i=1;$i<$this->NbCol;$i++) {
29104 $th = ($sum_h * $i / $this->NbCol);
29105 foreach($breaks AS $bk=>$val) {
29106 if ($val > $th) {
29107 if (($val-$th) < ($th-$breaks[$bk-1])) { $cbr[$i-1] = $val; }
29108 else { $cbr[$i-1] = $breaks[$bk-1]; }
29109 break;
29110 }
29111 }
29112 }
29113 $cbr[($this->NbCol-1)] = $sum_h;
29114
29115 // Now update the columns - divide into columns of approximately equal value
29116 $last_new_col = 0;
29117 $yadj = 0; // mm
29118 $xadj = 0;
29119 $last_col_bottom = 0;
29120 $lowest_bottom_y = 0;
29121 $block_bottom = 0;
29122 $newcolumn = 0;
29123 foreach($this->columnbuffer AS $key=>$s) {
29124 if (isset($s['rel_y'])) { // only process position sensitive data
29125 if ($s['rel_y'] >= $cbr[$newcolumn]) {
29126 $newcolumn++;
29127 }
29128 else {
29129 $newcolumn = $last_new_col ;
29130 }
29131
29132
29133 $block_bottom = max($block_bottom,($s['rel_y']+$s['h']));
29134
29135 if ($this->directionality == 'rtl') { // *RTL*
29136 $xadj = -(($newcolumn - $s['col']) * ($this->ColWidth + $this->ColGap)); // *RTL*
29137 } // *RTL*
29138 else { // *RTL*
29139 $xadj = ($newcolumn - $s['col']) * ($this->ColWidth + $this->ColGap);
29140 } // *RTL*
29141
29142 if ($last_new_col != $newcolumn) { // Added new column
29143 $last_col_bottom = $this->columnbuffer[$key]['rel_y'];
29144 $block_bottom = 0;
29145 }
29146 $yadj = ($s['rel_y'] - $s['y']) - ($last_col_bottom)+$this->y0;
29147 // callback function
29148 $t = $s['s'];
29149
29150 // mPDF 5.7+
29151 $t = $this->columnAdjustPregReplace('Td', $xadj, $yadj, '/BT (\d+\.\d\d+) (\d+\.\d\d+) Td/', $t);
29152 $t = $this->columnAdjustPregReplace('re', $xadj, $yadj, '/(\d+\.\d\d+) (\d+\.\d\d+) (\d+\.\d\d+) ([\-]{0,1}\d+\.\d\d+) re/', $t);
29153 $t = $this->columnAdjustPregReplace('l', $xadj, $yadj, '/(\d+\.\d\d+) (\d+\.\d\d+) l/', $t);
29154 $t = $this->columnAdjustPregReplace('img', $xadj, $yadj, '/q (\d+\.\d\d+) 0 0 (\d+\.\d\d+) (\d+\.\d\d+) (\d+\.\d\d+) cm \/(I|FO)/', $t);
29155 $t = $this->columnAdjustPregReplace('draw', $xadj, $yadj, '/(\d+\.\d\d+) (\d+\.\d\d+) m/', $t);
29156 $t = $this->columnAdjustPregReplace('bezier',$xadj, $yadj, '/(\d+\.\d\d+) (\d+\.\d\d+) (\d+\.\d\d+) (\d+\.\d\d+) (\d+\.\d\d+) (\d+\.\d\d+) c/', $t);
29157
29158 $this->columnbuffer[$key]['s'] = $t;
29159 $this->columnbuffer[$key]['newcol'] = $newcolumn;
29160 $this->columnbuffer[$key]['newy'] = $s['y'] + $yadj;
29161 $last_new_col = $newcolumn;
29162 $clb = $s['y'] + $yadj + $s['h'] ; // bottom_margin of current
29163 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; }
29164 if ($clb > $lowest_bottom_y) { $lowest_bottom_y = $clb; }
29165 // Adjust LINKS
29166 if (isset($this->columnLinks[$s['col']][INTVAL($s['x'])][INTVAL($s['y'])])) {
29167 $ref = $this->columnLinks[$s['col']][INTVAL($s['x'])][INTVAL($s['y'])];
29168 $this->PageLinks[$this->page][$ref][0] += ($xadj*_MPDFK);
29169 $this->PageLinks[$this->page][$ref][1] -= ($yadj*_MPDFK);
29170 unset($this->columnLinks[$s['col']][INTVAL($s['x'])][INTVAL($s['y'])]);
29171 }
29172 // Adjust FORM FIELDS
29173 if (isset($this->columnForms[$s['col']][INTVAL($s['x'])][INTVAL($s['y'])])) {
29174 $ref = $this->columnForms[$s['col']][INTVAL($s['x'])][INTVAL($s['y'])];
29175 $this->form->forms[$ref]['x'] += ($xadj);
29176 $this->form->forms[$ref]['y'] += ($yadj);
29177 unset($this->columnForms[$s['col']][INTVAL($s['x'])][INTVAL($s['y'])]);
29178 }
29179/*-- ANNOTATIONS --*/
29180 if (isset($this->columnAnnots[$s['col']][INTVAL($s['x'])][INTVAL($s['y'])])) {
29181 $ref = $this->columnAnnots[$s['col']][INTVAL($s['x'])][INTVAL($s['y'])];
29182 if ($this->PageAnnots[$this->page][$ref]['x'] < 0) {
29183 $this->PageAnnots[$this->page][$ref]['x'] -= ($xadj);
29184 }
29185 else {
29186 $this->PageAnnots[$this->page][$ref]['x'] += ($xadj);
29187 }
29188 $this->PageAnnots[$this->page][$ref]['y'] += ($yadj); // unlike PageLinks, Page annots has y values from top in mm
29189 unset($this->columnAnnots[$s['col']][INTVAL($s['x'])][INTVAL($s['y'])]);
29190 }
29191/*-- END ANNOTATIONS --*/
29192 }
29193 }
29194
29195/*-- BOOKMARKS --*/
29196 // Adjust Bookmarks
29197 foreach($this->col_BMoutlines AS $v) {
29198 $this->BMoutlines[]=array('t'=>$v['t'],'l'=>$v['l'],'y'=>$this->y0,'p'=>$v['p']);
29199 }
29200/*-- END BOOKMARKS --*/
29201
29202/*-- INDEX --*/
29203 // Adjust Reference (index)
29204 foreach($this->col_Reference AS $v) {
29205 $Present=0;
29206 //Search the reference (AND Ref/PageNo) in the array
29207 for ($i=0;$i<count($this->Reference);$i++){
29208 if ($this->Reference[$i]['t']==$v['t']){
29209 $Present=1;
29210 if (!in_array($v['op'],$this->Reference[$i]['p'])) {
29211 $this->Reference[$i]['p'][] = $v['op'];
29212 }
29213 }
29214 }
29215 if ($Present==0) {
29216 $this->Reference[]=array('t'=>$v['t'],'p'=>array($v['op']));
29217 }
29218 }
29219/*-- END INDEX --*/
29220
29221/*-- TOC --*/
29222
29223 // Adjust ToC
29224 foreach($this->col_toc AS $v) {
29225 $this->tocontents->_toc[]=array('t'=>$v['t'],'l'=>$v['l'],'p'=>$v['p'],'link'=>$v['link'],'toc_id'=>$v['toc_id']);
29226 $this->links[$v['link']][1] = $this->y0;
29227 }
29228/*-- END TOC --*/
29229
29230 // Adjust column length to be equal
29231 if ($this->colvAlign == 'J') {
29232 foreach($this->columnbuffer AS $key=>$s) {
29233 if (isset($s['rel_y'])) { // only process position sensitive data
29234 // Set ratio to expand y values or heights
29235 if (isset($this->ColDetails[$s['newcol']]['max_bottom']) && $this->ColDetails[$s['newcol']]['max_bottom'] && $this->ColDetails[$s['newcol']]['max_bottom']!=$this->y0) {
29236 $ratio = ($lowest_bottom_y - ($this->y0)) / ($this->ColDetails[$s['newcol']]['max_bottom'] - ($this->y0));
29237 }
29238 else { $ratio = 1; }
29239 if (($ratio > 1) && ($ratio <= $this->max_colH_correction)) {
29240 $yadj = ($s['newy'] - $this->y0) * ($ratio - 1);
29241
29242 // Adjust LINKS
29243 if (isset($this->columnLinks[$s['col']][INTVAL($s['x'])][INTVAL($s['y'])])) {
29244 $ref = $this->columnLinks[$s['col']][INTVAL($s['x'])][INTVAL($s['y'])];
29245 $this->PageLinks[$this->page][$ref][1] -= ($yadj*_MPDFK); // y value
29246 $this->PageLinks[$this->page][$ref][3] *= $ratio; // height
29247 unset($this->columnLinks[$s['col']][INTVAL($s['x'])][INTVAL($s['y'])]);
29248 }
29249 // Adjust FORM FIELDS
29250 if (isset($this->columnForms[$s['col']][INTVAL($s['x'])][INTVAL($s['y'])])) {
29251 $ref = $this->columnForms[$s['col']][INTVAL($s['x'])][INTVAL($s['y'])];
29252 $this->form->forms[$ref]['x'] += ($xadj);
29253 $this->form->forms[$ref]['y'] += ($yadj);
29254 unset($this->columnForms[$s['col']][INTVAL($s['x'])][INTVAL($s['y'])]);
29255 }
29256/*-- ANNOTATIONS --*/
29257 if (isset($this->columnAnnots[$s['col']][INTVAL($s['x'])][INTVAL($s['y'])])) {
29258 $ref = $this->columnAnnots[$s['col']][INTVAL($s['x'])][INTVAL($s['y'])];
29259 $this->PageAnnots[$this->page][$ref]['y'] += ($yadj);
29260 unset($this->columnAnnots[$s['col']][INTVAL($s['x'])][INTVAL($s['y'])]);
29261 }
29262/*-- END ANNOTATIONS --*/
29263 }
29264 }
29265 }
29266 foreach($this->internallink AS $key => $f) {
29267 if (is_array($f) && isset($f['col'])) {
29268 $last_col_bottom = 0;
29269 for ($nbc=0; $nbc<$this->NbCol; $nbc++) {
29270 if ($f['rel_y'] >= $cbr[$nbc]) { $last_col_bottom = $cbr[$nbc]; }
29271 }
29272 $yadj = ($f['rel_y'] - $f['Y']) - $last_col_bottom + $this->y0;
29273 $f['Y'] += $yadj;
29274 unset($f['col']);
29275 unset($f['rel_y']);
29276 $this->internallink[$key] = $f;
29277 }
29278 }
29279
29280 $last_col = -1;
29281 $trans_on = false;
29282 foreach($this->columnbuffer AS $key=>$s) {
29283 if (isset($s['rel_y'])) { // only process position sensitive data
29284 // Set ratio to expand y values or heights
29285 if (isset($this->ColDetails[$s['newcol']]['max_bottom']) && $this->ColDetails[$s['newcol']]['max_bottom'] && $this->ColDetails[$s['newcol']]['max_bottom']!=$this->y0) {
29286 $ratio = ($lowest_bottom_y - ($this->y0)) / ($this->ColDetails[$s['newcol']]['max_bottom'] - ($this->y0));
29287 }
29288 else { $ratio = 1; }
29289 if (($ratio > 1) && ($ratio <= $this->max_colH_correction)) {
29290 //Start Transformation
29291 $this->pages[$this->page] .= $this->StartTransform(true)."\n";
29292 $this->pages[$this->page] .= $this->transformScale(100, $ratio*100, $x='', $this->y0, true)."\n";
29293 $trans_on = true;
29294 }
29295 }
29296 // Now output the adjusted values
29297 $this->pages[$this->page] .= $s['s']."\n";
29298 if (isset($s['rel_y']) && ($ratio > 1) && ($ratio <= $this->max_colH_correction)) { // only process position sensitive data
29299 //Stop Transformation
29300 $this->pages[$this->page] .= $this->StopTransform(true)."\n";
29301 $trans_on = false;
29302 }
29303 }
29304 if ($trans_on) { $this->pages[$this->page] .= $this->StopTransform(true)."\n"; }
29305 }
29306 else { // if NOT $this->colvAlign == 'J'
29307 // Now output the adjusted values
29308 foreach($this->columnbuffer AS $s) {
29309 $this->pages[$this->page] .= $s['s']."\n";
29310 }
29311 }
29312 if ($lowest_bottom_y > 0) { $this->y = $lowest_bottom_y ; }
29313 }
29314
29315 // Columns not ended but new page -> align columns (can leave the columns alone - just tidy up the height)
29316 else if ($this->colvAlign == 'J' && $this->ColumnAdjust && !$this->keepColumns) {
29317 // calculate the lowest bottom margin
29318 $lowest_bottom_y = 0;
29319 foreach($this->columnbuffer AS $key=>$s) {
29320 // Only process output data
29321 $t = $s['s'];
29322 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)) ||
29323 (preg_match('/\d+\.\d\d+ (\d+\.\d\d+) l/',$t)) ||
29324 (preg_match('/q \d+\.\d\d+ 0 0 \d+\.\d\d+ \d+\.\d\d+ (\d+\.\d\d+) cm \/(I|FO)\d+ Do Q/',$t)) ||
29325 (preg_match('/\d+\.\d\d+ (\d+\.\d\d+) m/',$t)) ||
29326 (preg_match('/\d+\.\d\d+ (\d+\.\d\d+) \d+\.\d\d+ \d+\.\d\d+ \d+\.\d\d+ \d+\.\d\d+ c/',$t)) ) {
29327
29328 $clb = $s['y'] + $s['h'];
29329 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; }
29330 if ($clb > $lowest_bottom_y) { $lowest_bottom_y = $clb; }
29331 $this->columnbuffer[$key]['rel_y'] = $s['y']; // Marks position sensitive data to process later
29332 if ($t == 'ACROFORM') { $this->columnbuffer[$key]['s'] = ''; }
29333 }
29334 }
29335 // Adjust column length equal
29336 foreach($this->columnbuffer AS $key=>$s) {
29337 // Set ratio to expand y values or heights
29338 if (isset($this->ColDetails[$s['col']]['max_bottom']) && $this->ColDetails[$s['col']]['max_bottom']) {
29339 $ratio = ($lowest_bottom_y - ($this->y0)) / ($this->ColDetails[$s['col']]['max_bottom'] - ($this->y0));
29340 }
29341 else { $ratio = 1; }
29342 if (($ratio > 1) && ($ratio <= $this->max_colH_correction)) {
29343 $yadj = ($s['y'] - $this->y0) * ($ratio - 1);
29344
29345 // Adjust LINKS
29346 if (isset($s['rel_y'])) { // only process position sensitive data
29347 // otherwise triggers for all entries in column buffer (.e.g. formatting) and makes below adjustments more than once
29348 if (isset($this->columnLinks[$s['col']][INTVAL($s['x'])][INTVAL($s['y'])])) {
29349 $ref = $this->columnLinks[$s['col']][INTVAL($s['x'])][INTVAL($s['y'])];
29350 $this->PageLinks[$this->page][$ref][1] -= ($yadj*_MPDFK); // y value
29351 $this->PageLinks[$this->page][$ref][3] *= $ratio; // height
29352 unset($this->columnLinks[$s['col']][INTVAL($s['x'])][INTVAL($s['y'])]);
29353 }
29354 // Adjust FORM FIELDS
29355 if (isset($this->columnForms[$s['col']][INTVAL($s['x'])][INTVAL($s['y'])])) {
29356 $ref = $this->columnForms[$s['col']][INTVAL($s['x'])][INTVAL($s['y'])];
29357 $this->form->forms[$ref]['x'] += ($xadj);
29358 $this->form->forms[$ref]['y'] += ($yadj);
29359 unset($this->columnForms[$s['col']][INTVAL($s['x'])][INTVAL($s['y'])]);
29360 }
29361/*-- ANNOTATIONS --*/
29362 if (isset($this->columnAnnots[$s['col']][INTVAL($s['x'])][INTVAL($s['y'])])) {
29363 $ref = $this->columnAnnots[$s['col']][INTVAL($s['x'])][INTVAL($s['y'])];
29364 $this->PageAnnots[$this->page][$ref]['y'] += ($yadj);
29365 unset($this->columnAnnots[$s['col']][INTVAL($s['x'])][INTVAL($s['y'])]);
29366 }
29367/*-- END ANNOTATIONS --*/
29368 }
29369 }
29370 }
29371
29372/*-- BOOKMARKS --*/
29373
29374 // Adjust Bookmarks
29375 foreach($this->col_BMoutlines AS $v) {
29376 $this->BMoutlines[]=array('t'=>$v['t'],'l'=>$v['l'],'y'=>$this->y0,'p'=>$v['p']);
29377 }
29378/*-- END BOOKMARKS --*/
29379
29380/*-- INDEX --*/
29381
29382 // Adjust Reference (index)
29383 foreach($this->col_Reference AS $v) {
29384 $Present=0;
29385 //Search the reference (AND Ref/PageNo) in the array
29386 for ($i=0;$i<count($this->Reference);$i++){
29387 if ($this->Reference[$i]['t']==$v['t']){
29388 $Present=1;
29389 if (!in_array($v['op'],$this->Reference[$i]['p'])) {
29390 $this->Reference[$i]['p'][] = $v['op'];
29391 }
29392 }
29393 }
29394 if ($Present==0) {
29395 $this->Reference[]=array('t'=>$v['t'],'p'=>array($v['op']));
29396 }
29397 }
29398/*-- END INDEX --*/
29399
29400/*-- TOC --*/
29401
29402 // Adjust ToC
29403 foreach($this->col_toc AS $v) {
29404 $this->tocontents->_toc[]=array('t'=>$v['t'],'l'=>$v['l'],'p'=>$v['p'],'link'=>$v['link'],'toc_id'=>$v['toc_id']);
29405 $this->links[$v['link']][1] = $this->y0;
29406 }
29407/*-- END TOC --*/
29408 $trans_on = false;
29409 foreach($this->columnbuffer AS $key=>$s) {
29410 if (isset($s['rel_y'])) { // only process position sensitive data
29411 // Set ratio to expand y values or heights
29412 if ($this->ColDetails[$s['col']]['max_bottom']) {
29413 $ratio = ($lowest_bottom_y - ($this->y0)) / ($this->ColDetails[$s['col']]['max_bottom'] - ($this->y0));
29414 }
29415 else { $ratio = 1; }
29416 if (($ratio > 1) && ($ratio <= $this->max_colH_correction)) {
29417 //Start Transformation
29418 $this->pages[$this->page] .= $this->StartTransform(true)."\n";
29419 $this->pages[$this->page] .= $this->transformScale(100, $ratio*100, $x='', $this->y0, true)."\n";
29420 $trans_on = true;
29421 }
29422 }
29423 // Now output the adjusted values
29424 $this->pages[$this->page] .= $s['s']."\n";
29425 if (isset($s['rel_y']) && ($ratio > 1) && ($ratio <= $this->max_colH_correction)) {
29426 //Stop Transformation
29427 $this->pages[$this->page] .= $this->StopTransform(true)."\n";
29428 $trans_on = false; // mPDF 5.1.001
29429 }
29430 }
29431 if ($trans_on) { $this->pages[$this->page] .= $this->StopTransform(true)."\n"; }
29432
29433 if ($lowest_bottom_y > 0) { $this->y = $lowest_bottom_y ; }
29434 }
29435
29436
29437 // Just reproduce the page as it was
29438 else {
29439 // If page has not ended but height adjustment was disabled by custom column-break - adjust y
29440 $lowest_bottom_y = 0;
29441 if (!$this->ColActive && (!$this->ColumnAdjust || $this->keepColumns)) {
29442 // calculate the lowest bottom margin
29443 foreach($this->columnbuffer AS $key=>$s) {
29444 // Only process output data
29445 $t = $s['s'];
29446 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)) ||
29447 (preg_match('/\d+\.\d\d+ (\d+\.\d\d+) l/',$t)) ||
29448 (preg_match('/q \d+\.\d\d+ 0 0 \d+\.\d\d+ \d+\.\d\d+ (\d+\.\d\d+) cm \/(I|FO)\d+ Do Q/',$t)) ||
29449 (preg_match('/\d+\.\d\d+ (\d+\.\d\d+) m/',$t)) ||
29450 (preg_match('/\d+\.\d\d+ (\d+\.\d\d+) \d+\.\d\d+ \d+\.\d\d+ \d+\.\d\d+ \d+\.\d\d+ c/',$t)) ) {
29451
29452 $clb = $s['y'] + $s['h'];
29453 if ($clb > $this->ColDetails[$s['col']]['max_bottom']) { $this->ColDetails[$s['col']]['max_bottom'] = $clb; }
29454 if ($clb > $lowest_bottom_y) { $lowest_bottom_y = $clb; }
29455 }
29456 }
29457 }
29458 foreach($this->columnbuffer AS $key=>$s) {
29459 if ($s['s'] != 'ACROFORM')
29460 $this->pages[$this->page] .= $s['s']."\n";
29461 }
29462 if ($lowest_bottom_y > 0) { $this->y = $lowest_bottom_y ; }
29463/*-- INDEX --*/
29464
29465 // Output Reference (index)
29466 foreach($this->col_Reference AS $v) {
29467 $Present=0;
29468 for ($i=0;$i<count($this->Reference);$i++){
29469 if ($this->Reference[$i]['t']==$v['t']){
29470 $Present=1;
29471 if (!in_array($v['op'],$this->Reference[$i]['p'])) {
29472 $this->Reference[$i]['p'][] = $v['op'];
29473 }
29474 }
29475 }
29476 if ($Present==0) {
29477 $this->Reference[]=array('t'=>$v['t'],'p'=>array($v['op']));
29478 }
29479 }
29480/*-- END INDEX --*/
29481/*-- BOOKMARKS --*/
29482 // Output Bookmarks
29483 foreach($this->col_BMoutlines AS $v) {
29484 $this->BMoutlines[]=array('t'=>$v['t'],'l'=>$v['l'],'y'=>$v['y'],'p'=>$v['p']);
29485 }
29486/*-- END BOOKMARKS --*/
29487/*-- TOC --*/
29488 // Output ToC
29489 foreach($this->col_toc AS $v) {
29490 $this->tocontents->_toc[]=array('t'=>$v['t'],'l'=>$v['l'],'p'=>$v['p'],'link'=>$v['link'],'toc_id'=>$v['toc_id']);
29491 }
29492/*-- END TOC --*/
29493 }
29494 foreach($this->internallink AS $key => $f) {
29495 if (isset($this->internallink[$key]['col'])) unset($this->internallink[$key]['col']);
29496 if (isset($this->internallink[$key]['rel_y'])) unset($this->internallink[$key]['rel_y']);
29497 }
29498
29499 $this->columnbuffer = array();
29500 $this->ColDetails = array();
29501 $this->columnLinks = array();
29502 $this->columnAnnots = array();
29503 $this->columnForms = array();
29504
29505 $this->col_Reference = array();
29506 $this->col_BMoutlines = array();
29507 $this->col_toc = array();
29508 $this->breakpoints = array();
29509}
29510
29511// mPDF 5.7+
29512function columnAdjustPregReplace($type, $xadj, $yadj, $pattern, $subject) {
29513 preg_match($pattern, $subject, $matches);
29514 if (!isset($matches[3])) { $matches[3] = 0; }
29515 if (!isset($matches[4])) { $matches[4] = 0; }
29516 if (!isset($matches[5])) { $matches[5] = 0; }
29517 if (!isset($matches[6])) { $matches[6] = 0; }
29518 return str_replace($matches[0], $this->columnAdjustAdd($type, _MPDFK, $xadj, $yadj, $matches[1], $matches[2], $matches[3], $matches[4], $matches[5], $matches[6]), $subject);
29519}
29520
29521/*-- END COLUMNS --*/
29522
29523
29524//==================================================================
29525/*-- TABLES --*/
29526function printcellbuffer() {
29527 if (count($this->cellBorderBuffer )) {
29528 sort($this->cellBorderBuffer);
29529 foreach($this->cellBorderBuffer AS $cbb) {
29530 $cba = unpack("A16dom/nbord/A1side/ns/dbw/a6ca/A10style/dx/dy/dw/dh/dmbl/dmbr/dmrt/dmrb/dmtl/dmtr/dmlt/dmlb/dcpd/dover/", $cbb);
29531 $side = $cba['side'];
29532 $details = array();
29533 $details[$side]['dom'] = (float) $cba['dom'];
29534 $details[$side]['s'] = $cba['s'];
29535 $details[$side]['w'] = $cba['bw'];
29536 $details[$side]['c'] = $cba['ca'];
29537 $details[$side]['style'] = trim($cba['style']);
29538 $details['mbw']['BL'] = $cba['mbl'];
29539 $details['mbw']['BR'] = $cba['mbr'];
29540 $details['mbw']['RT'] = $cba['mrt'];
29541 $details['mbw']['RB'] = $cba['mrb'];
29542 $details['mbw']['TL'] = $cba['mtl'];
29543 $details['mbw']['TR'] = $cba['mtr'];
29544 $details['mbw']['LT'] = $cba['mlt'];
29545 $details['mbw']['LB'] = $cba['mlb'];
29546 $details['cellposdom'] = $cba['cpd'];
29547 $details['p'] = $side;
29548 if ($cba['over']==1) { $details[$side]['overlay'] = true; }
29549 else { $details[$side]['overlay'] = false; }
29550 $this->_tableRect($cba['x'],$cba['y'],$cba['w'],$cba['h'],$cba['bord'],$details, false, false);
29551
29552 }
29553 $this->cellBorderBuffer = array();
29554 }
29555}
29556//==================================================================
29557function printtablebuffer() {
29558
29559 if (!$this->table_rotate) {
29560 $this->pages[$this->page] .= $this->tablebuffer;
29561 foreach($this->tbrot_Links AS $p => $l) {
29562 foreach($l AS $v) {
29563 $this->PageLinks[$p][] = $v;
29564 }
29565 }
29566 $this->tbrot_Links = array();
29567/*-- ANNOTATIONS --*/
29568 foreach($this->tbrot_Annots AS $p => $l) {
29569 foreach($l AS $v) {
29570 $this->PageAnnots[$p][] = $v;
29571 }
29572 }
29573 $this->tbrot_Annots = array();
29574/*-- END ANNOTATIONS --*/
29575
29576/*-- INDEX --*/
29577 // Output Reference (index)
29578 foreach($this->tbrot_Reference AS $v) {
29579 $Present=0;
29580 for ($i=0;$i<count($this->Reference);$i++){
29581 if ($this->Reference[$i]['t']==$v['t']){
29582 $Present=1;
29583 if (!in_array($v['op'],$this->Reference[$i]['p'])) {
29584 $this->Reference[$i]['p'][] = $v['op'];
29585 }
29586 }
29587 }
29588 if ($Present==0) {
29589 $this->Reference[]=array('t'=>$v['t'],'p'=>array($v['op']));
29590 }
29591 }
29592 $this->tbrot_Reference = array();
29593/*-- END INDEX --*/
29594
29595/*-- BOOKMARKS --*/
29596 // Output Bookmarks
29597 foreach($this->tbrot_BMoutlines AS $v) {
29598 $this->BMoutlines[]=array('t'=>$v['t'],'l'=>$v['l'],'y'=>$v['y'],'p'=>$v['p']);
29599 }
29600 $this->tbrot_BMoutlines = array();
29601/*-- END BOOKMARKS --*/
29602
29603/*-- TOC --*/
29604 // Output ToC
29605 foreach($this->tbrot_toc AS $v) {
29606 $this->tocontents->_toc[]=array('t'=>$v['t'],'l'=>$v['l'],'p'=>$v['p'],'link'=>$v['link'],'toc_id'=>$v['toc_id']);
29607 }
29608 $this->tbrot_toc = array();
29609/*-- END TOC --*/
29610
29611 return;
29612 }
29613 // else if rotated
29614 $lm = $this->lMargin + $this->blk[$this->blklvl]['outer_left_margin'] + $this->blk[$this->blklvl]['border_left']['w'] + $this->blk[$this->blklvl]['padding_left'];
29615 $pw = $this->blk[$this->blklvl]['inner_width'];
29616 //Start Transformation
29617 $this->pages[$this->page] .= $this->StartTransform(true)."\n";
29618
29619 if ($this->table_rotate > 1) { // clockwise
29620 if ($this->tbrot_align == 'L') {
29621 $xadj = $this->tbrot_h ; // align L (as is)
29622 }
29623 else if ($this->tbrot_align == 'R') {
29624 $xadj = $lm-$this->tbrot_x0+($pw) ; // align R
29625 }
29626 else {
29627 $xadj = $lm-$this->tbrot_x0+(($pw + $this->tbrot_h)/2) ; // align C
29628 }
29629 $yadj = 0;
29630 }
29631 else { // anti-clockwise
29632 if ($this->tbrot_align == 'L') {
29633 $xadj = 0 ; // align L (as is)
29634 }
29635 else if ($this->tbrot_align == 'R') {
29636 $xadj = $lm-$this->tbrot_x0+($pw - $this->tbrot_h) ; // align R
29637 }
29638 else {
29639 $xadj = $lm-$this->tbrot_x0+(($pw - $this->tbrot_h)/2) ; // align C
29640 }
29641 $yadj = $this->tbrot_w;
29642 }
29643
29644
29645 $this->pages[$this->page] .= $this->transformTranslate($xadj, $yadj , true)."\n";
29646 $this->pages[$this->page] .= $this->transformRotate($this->table_rotate, $this->tbrot_x0 , $this->tbrot_y0 , true)."\n";
29647
29648 // Now output the adjusted values
29649 $this->pages[$this->page] .= $this->tablebuffer;
29650
29651
29652 foreach($this->tbrot_Links AS $p => $l) {
29653 foreach($l AS $v) {
29654 $w = $v[2]/_MPDFK;
29655 $h = $v[3]/_MPDFK;
29656 $ax = ($v[0]/_MPDFK) - $this->tbrot_x0;
29657 $ay = (($this->hPt-$v[1])/_MPDFK) - $this->tbrot_y0;
29658 if ($this->table_rotate > 1) { // clockwise
29659 $bx = $this->tbrot_x0+$xadj-$ay-$h;
29660 $by = $this->tbrot_y0+$yadj+$ax;
29661 }
29662 else {
29663 $bx = $this->tbrot_x0+$xadj+$ay;
29664 $by = $this->tbrot_y0+$yadj-$ax-$w;
29665 }
29666 $v[0] = $bx*_MPDFK;
29667 $v[1] = ($this->h-$by)*_MPDFK;
29668 $v[2] = $h*_MPDFK; // swap width and height
29669 $v[3] = $w*_MPDFK;
29670 $this->PageLinks[$p][] = $v;
29671 }
29672 }
29673 $this->tbrot_Links = array();
29674 foreach($this->internallink AS $key => $f) {
29675 if (is_array($f) && isset($f['tbrot'])) {
29676 $f['Y'] = $this->tbrot_y0;
29677 $f['PAGE'] = $this->page;
29678 unset($f['tbrot']);
29679 $this->internallink[$key] = $f;
29680 }
29681 }
29682/*-- ANNOTATIONS --*/
29683 foreach($this->tbrot_Annots AS $p => $l) {
29684 foreach($l AS $v) {
29685 $ax = abs($v['x']) - $this->tbrot_x0; // abs because -ve values are internally set and held for reference if annotMargin set
29686 $ay = $v['y'] - $this->tbrot_y0;
29687 if ($this->table_rotate > 1) { // clockwise
29688 $bx = $this->tbrot_x0+$xadj-$ay;
29689 $by = $this->tbrot_y0+$yadj+$ax;
29690 }
29691 else {
29692 $bx = $this->tbrot_x0+$xadj+$ay;
29693 $by = $this->tbrot_y0+$yadj-$ax;
29694 }
29695 if ($v['x'] < 0) {
29696 $v['x'] = -$bx;
29697 }
29698 else {
29699 $v['x'] = $bx;
29700 }
29701 $v['y'] = ($by);
29702 $this->PageAnnots[$p][] = $v;
29703 }
29704 }
29705 $this->tbrot_Annots = array();
29706/*-- END ANNOTATIONS --*/
29707
29708
29709/*-- BOOKMARKS --*/
29710
29711 // Adjust Bookmarks
29712 foreach($this->tbrot_BMoutlines AS $v) {
29713 $v['y'] = $this->tbrot_y0;
29714 $this->BMoutlines[]=array('t'=>$v['t'],'l'=>$v['l'],'y'=>$v['y'],'p'=>$this->page);
29715 }
29716/*-- END BOOKMARKS --*/
29717
29718/*-- INDEX --*/
29719
29720 // Adjust Reference (index)
29721 foreach($this->tbrot_Reference AS $v) {
29722 $Present=0;
29723 //Search the reference (AND Ref/PageNo) in the array
29724 for ($i=0;$i<count($this->Reference);$i++){
29725 if ($this->Reference[$i]['t']==$v['t']){
29726 $Present=1;
29727 if (!in_array($this->page,$this->Reference[$i]['p'])) {
29728 $this->Reference[$i]['p'][] = $this->page;
29729 }
29730 }
29731 }
29732 if ($Present==0) {
29733 $this->Reference[]=array('t'=>$v['t'],'p'=>array($this->page));
29734 }
29735 }
29736/*-- END INDEX --*/
29737
29738/*-- TOC --*/
29739
29740 // Adjust ToC - uses document page number
29741 foreach($this->tbrot_toc AS $v) {
29742 $this->tocontents->_toc[]=array('t'=>$v['t'],'l'=>$v['l'],'p'=>$this->page,'link'=>$v['link'],'toc_id'=>$v['toc_id']);
29743 $this->links[$v['link']][1] = $this->tbrot_y0;
29744 }
29745/*-- END TOC --*/
29746
29747
29748
29749 $this->tbrot_Reference = array();
29750 $this->tbrot_BMoutlines = array();
29751 $this->tbrot_toc = array();
29752
29753 //Stop Transformation
29754 $this->pages[$this->page] .= $this->StopTransform(true)."\n";
29755
29756
29757 $this->y = $this->tbrot_y0 + $this->tbrot_w;
29758 $this->x = $this->lMargin;
29759
29760 $this->tablebuffer = '';
29761}
29762
29763//==================================================================
29764// Keep-with-table This buffers contents of h1-6 to keep on page with table
29765function printkwtbuffer() {
29766 if (!$this->kwt_moved) {
29767 foreach($this->kwt_buffer AS $s) { $this->pages[$this->page] .= $s['s']."\n"; }
29768 foreach($this->kwt_Links AS $p => $l) {
29769 foreach($l AS $v) {
29770 $this->PageLinks[$p][] = $v;
29771 }
29772 }
29773 $this->kwt_Links = array();
29774/*-- ANNOTATIONS --*/
29775 foreach($this->kwt_Annots AS $p => $l) {
29776 foreach($l AS $v) {
29777 $this->PageAnnots[$p][] = $v;
29778 }
29779 }
29780 $this->kwt_Annots = array();
29781/*-- END ANNOTATIONS --*/
29782
29783/*-- INDEX --*/
29784 // Output Reference (index)
29785 foreach($this->kwt_Reference AS $v) {
29786 $Present=0;
29787 for ($i=0;$i<count($this->Reference);$i++){
29788 if ($this->Reference[$i]['t']==$v['t']){
29789 $Present=1;
29790 if (!in_array($v['op'],$this->Reference[$i]['p'])) {
29791 $this->Reference[$i]['p'][] = $v['op'];
29792 }
29793 }
29794 }
29795 if ($Present==0) {
29796 $this->Reference[]=array('t'=>$v['t'],'p'=>array($v['op']));
29797 }
29798 }
29799 $this->kwt_Reference = array();
29800/*-- END INDEX --*/
29801
29802/*-- BOOKMARKS --*/
29803 // Output Bookmarks
29804 foreach($this->kwt_BMoutlines AS $v) {
29805 $this->BMoutlines[]=array('t'=>$v['t'],'l'=>$v['l'],'y'=>$v['y'],'p'=>$v['p']);
29806 }
29807 $this->kwt_BMoutlines = array();
29808/*-- END BOOKMARKS --*/
29809
29810/*-- TOC --*/
29811 // Output ToC
29812 foreach($this->kwt_toc AS $v) {
29813 $this->tocontents->_toc[]=array('t'=>$v['t'],'l'=>$v['l'],'p'=>$v['p'],'link'=>$v['link'],'toc_id'=>$v['toc_id']);
29814 }
29815 $this->kwt_toc = array();
29816/*-- END TOC --*/
29817
29818 return;
29819 }
29820
29821 //Start Transformation
29822 $this->pages[$this->page] .= $this->StartTransform(true)."\n";
29823 $xadj = $this->lMargin - $this->kwt_x0 ;
29824 //$yadj = $this->y - $this->kwt_y0 ;
29825 $yadj = $this->tMargin - $this->kwt_y0 ;
29826
29827 $this->pages[$this->page] .= $this->transformTranslate($xadj, $yadj , true)."\n";
29828
29829 // Now output the adjusted values
29830 foreach($this->kwt_buffer AS $s) { $this->pages[$this->page] .= $s['s']."\n"; }
29831
29832 // Adjust hyperLinks
29833 foreach($this->kwt_Links AS $p => $l) {
29834 foreach($l AS $v) {
29835 $bx = $this->kwt_x0+$xadj;
29836 $by = $this->kwt_y0+$yadj;
29837 $v[0] = $bx*_MPDFK;
29838 $v[1] = ($this->h-$by)*_MPDFK;
29839 $this->PageLinks[$p][] = $v;
29840 }
29841 }
29842 foreach($this->internallink AS $key => $f) {
29843 if (is_array($f) && isset($f['kwt'])) {
29844 $f['Y'] += $yadj;
29845 $f['PAGE'] = $this->page;
29846 unset($f['kwt']);
29847 $this->internallink[$key] = $f;
29848 }
29849 }
29850/*-- ANNOTATIONS --*/
29851 foreach($this->kwt_Annots AS $p => $l) {
29852 foreach($l AS $v) {
29853 $bx = $this->kwt_x0+$xadj;
29854 $by = $this->kwt_y0+$yadj;
29855 if ($v['x'] < 0) {
29856 $v['x'] = -$bx;
29857 }
29858 else {
29859 $v['x'] = $bx;
29860 }
29861 $v['y'] = $by;
29862 $this->PageAnnots[$p][] = $v;
29863 }
29864 }
29865/*-- END ANNOTATIONS --*/
29866
29867/*-- BOOKMARKS --*/
29868
29869 // Adjust Bookmarks
29870 foreach($this->kwt_BMoutlines AS $v) {
29871 if ($v['y'] != 0) { $v['y'] += $yadj; }
29872 $this->BMoutlines[]=array('t'=>$v['t'],'l'=>$v['l'],'y'=>$v['y'],'p'=>$this->page);
29873 }
29874/*-- END BOOKMARKS --*/
29875
29876/*-- INDEX --*/
29877
29878 // Adjust Reference (index)
29879 foreach($this->kwt_Reference AS $v) {
29880 $Present=0;
29881 //Search the reference (AND Ref/PageNo) in the array
29882 for ($i=0;$i<count($this->Reference);$i++){
29883 if ($this->Reference[$i]['t']==$v['t']){
29884 $Present=1;
29885 if (!in_array($this->page,$this->Reference[$i]['p'])) {
29886 $this->Reference[$i]['p'][] = $this->page;
29887 }
29888 }
29889 }
29890 if ($Present==0) {
29891 $this->Reference[]=array('t'=>$v['t'],'p'=>array($this->page));
29892 }
29893 }
29894/*-- END INDEX --*/
29895
29896/*-- TOC --*/
29897
29898 // Adjust ToC
29899 foreach($this->kwt_toc AS $v) {
29900 $this->tocontents->_toc[]=array('t'=>$v['t'],'l'=>$v['l'],'p'=>$this->page,'link'=>$v['link'],'toc_id'=>$v['toc_id']);
29901 $this->links[$v['link']][0] = $this->page;
29902 $this->links[$v['link']][1] += $yadj;
29903 }
29904/*-- END TOC --*/
29905
29906
29907 $this->kwt_Links = array();
29908 $this->kwt_Annots = array();
29909
29910 $this->kwt_Reference = array();
29911 $this->kwt_BMoutlines = array();
29912 $this->kwt_toc = array();
29913 //Stop Transformation
29914 $this->pages[$this->page] .= $this->StopTransform(true)."\n";
29915
29916 $this->kwt_buffer = array();
29917
29918 $this->y += $this->kwt_height;
29919}
29920
29921/*-- END TABLES --*/
29922
29923
29924//==================================================================
29925
29926function printfloatbuffer() {
29927 if (count($this->floatbuffer)) {
29928 $this->objectbuffer = $this->floatbuffer;
29929 $this->printobjectbuffer(false);
29930 $this->objectbuffer = array();
29931 $this->floatbuffer = array();
29932 $this->floatmargins = array();
29933 }
29934}
29935//==================================================================
29936
29937function printdivbuffer() {
29938 $p1 = $this->blk[$this->blklvl]['startpage'];
29939 $p2 = $this->page;
29940 $bottom[$p1] = $this->ktBlock[$p1]['bottom_margin'];
29941 $bottom[$p2] = $this->y; // $this->ktBlock[$p2]['bottom_margin'];
29942 $top[$p1] = $this->kt_y00;
29943
29944 $top2 = $this->h;
29945 foreach($this->divbuffer AS $key=>$s) {
29946 if ($s['page'] == $p2) {
29947 $top2 = MIN($s['y'], $top2);
29948 }
29949 }
29950 $top[$p2] = $top2;
29951 $height[$p1] = ($bottom[$p1] - $top[$p1]);
29952 $height[$p2] = ($bottom[$p2] - $top[$p2]);
29953 $xadj[$p1] = $this->MarginCorrection;
29954 $yadj[$p1] = -($top[$p1] - $top[$p2]);
29955 $xadj[$p2] = 0;
29956 $yadj[$p2] = $height[$p1];
29957
29958 // Output without any transformation
29959 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) {
29960 foreach($this->divbuffer AS $s) { $this->pages[$s['page']] .= $s['s']."\n"; }
29961 foreach($this->ktLinks AS $p => $l) {
29962 foreach($l AS $v) {
29963 $this->PageLinks[$p][] = $v;
29964 }
29965 }
29966 foreach($this->ktForms AS $key => $f) {
29967 $this->form->forms[$f['n']] = $f;
29968 }
29969/*-- ANNOTATIONS --*/
29970 foreach($this->ktAnnots AS $p => $l) {
29971 foreach($l AS $v) {
29972 $this->PageAnnots[$p][] = $v;
29973 }
29974 }
29975/*-- END ANNOTATIONS --*/
29976/*-- INDEX --*/
29977 // Adjust Reference (index)
29978 foreach($this->ktReference AS $v) {
29979 $Present=0;
29980 //Search the reference (AND Ref/PageNo) in the array
29981 for ($i=0;$i<count($this->Reference);$i++){
29982 if ($this->Reference[$i]['t']==$v['t']){
29983 $Present=1;
29984 if (!in_array($p2,$this->Reference[$i]['p'])) {
29985 $this->Reference[$i]['p'][] = $p2;
29986 }
29987 }
29988 }
29989 //If not found, add it
29990 if ($Present==0) {
29991 $this->Reference[]=array('t'=>$v['t'],'p'=>array($p2));
29992 }
29993 }
29994/*-- END INDEX --*/
29995
29996/*-- BOOKMARKS --*/
29997 // Adjust Bookmarks
29998 foreach($this->ktBMoutlines AS $v) {
29999 $this->BMoutlines[]=array('t'=>$v['t'],'l'=>$v['l'],'y'=>$v['y'],'p'=>$v['p']);
30000 }
30001/*-- END BOOKMARKS --*/
30002
30003/*-- TOC --*/
30004 // Adjust ToC
30005 foreach($this->_kttoc AS $v) {
30006 $this->tocontents->_toc[]=array('t'=>$v['t'],'l'=>$v['l'],'p'=>$v['p'],'link'=>$v['link'],'toc_id'=>$v['toc_id']);
30007 }
30008/*-- END TOC --*/
30009
30010 $this->divbuffer = array();
30011 $this->ktLinks = array();
30012 $this->ktAnnots = array();
30013 $this->ktForms = array();
30014 $this->ktBlock = array();
30015 $this->ktReference = array();
30016 $this->ktBMoutlines = array();
30017 $this->_kttoc = array();
30018 $this->keep_block_together = 0;
30019 return;
30020 }
30021 else {
30022 // Output with transformation
30023 // mPDF 5.6.17
30024 $np = '';
30025 $lastpage = -1;
30026 foreach($this->divbuffer AS $key=>$s) {
30027 // callback function
30028 $t = $s['s'];
30029 $p = $s['page'];
30030 if ($p != $lastpage) {
30031 $q = '';
30032 if ($lastpage != -1) { $q = ' Q'."\n"; }
30033 $t = $q . $this->StartTransform(true)."\n" . $this->transformTranslate($xadj[$p], $yadj[$p] , true)."\n" . $t;
30034 $lastpage = $p;
30035 }
30036 $np .= $t."\n";
30037 }
30038 if ($lastpage != -1) { $np .= ' Q'."\n"; }
30039
30040 $this->pages[$this->page] .= $np;
30041
30042 // Adjust hyperLinks
30043 foreach($this->ktLinks AS $p => $l) {
30044 foreach($l AS $v) {
30045 $v[0] += ($xadj[$p]*_MPDFK);
30046 $v[1] -= ($yadj[$p]*_MPDFK);
30047 $this->PageLinks[$p2][] = $v;
30048 }
30049 }
30050 foreach($this->ktForms AS $key => $f) {
30051 $p = $f['page'];
30052 $f['x'] += ($xadj[$p]);
30053 $f['y'] += ($yadj[$p]);
30054 $f['page'] = $p2;
30055 $this->form->forms[$f['n']] = $f;
30056 }
30057 foreach($this->internallink AS $key => $f) {
30058 if (is_array($f) && isset($f['kt'])) {
30059 $f['Y'] += ($yadj[$f['PAGE']]);
30060 $f['PAGE'] = $p2;
30061 unset($f['kt']);
30062 $this->internallink[$key] = $f;
30063 }
30064 }
30065/*-- ANNOTATIONS --*/
30066 foreach($this->ktAnnots AS $p => $l) {
30067 foreach($l AS $v) {
30068 if ($v['x']>0) { $v['x'] += $xadj[$p]; }
30069 else if ($v['x']<0) { $v['x'] -= $xadj[$p]; }
30070 $v['y'] += $yadj[$p];
30071 $this->PageAnnots[$p2][] = $v;
30072 }
30073 }
30074/*-- END ANNOTATIONS --*/
30075
30076/*-- BOOKMARKS --*/
30077 // Adjust Bookmarks
30078 foreach($this->ktBMoutlines AS $v) {
30079 if ($v['y'] != 0) { $v['y'] += ($yadj[$v['p']]); }
30080 $this->BMoutlines[]=array('t'=>$v['t'],'l'=>$v['l'],'y'=>$v['y'],'p'=>$p2);
30081 }
30082/*-- END BOOKMARKS --*/
30083
30084/*-- INDEX --*/
30085 // Adjust Reference (index)
30086 foreach($this->ktReference AS $v) {
30087 $Present=0;
30088 //Search the reference (AND Ref/PageNo) in the array
30089 for ($i=0;$i<count($this->Reference);$i++){
30090 if ($this->Reference[$i]['t']==$v['t']){
30091 $Present=1;
30092 if (!in_array($p2,$this->Reference[$i]['p'])) {
30093 $this->Reference[$i]['p'][] = $p2;
30094 }
30095 }
30096 }
30097 //If not found, add it
30098 if ($Present==0) {
30099 $this->Reference[]=array('t'=>$v['t'],'p'=>array($p2));
30100 }
30101 }
30102/*-- END INDEX --*/
30103
30104/*-- TOC --*/
30105 // Adjust ToC
30106 foreach($this->_kttoc AS $v) {
30107 $this->tocontents->_toc[]=array('t'=>$v['t'],'l'=>$v['l'],'p'=>$p2,'link'=>$v['link'],'toc_id'=>$v['toc_id']);
30108 $this->links[$v['link']][0] = $p2;
30109 $this->links[$v['link']][1] += $yadj[$v['p']];
30110 }
30111/*-- END TOC --*/
30112
30113 $this->y = $top[$p2] + $height[$p1] + $height[$p2];
30114 $this->x = $this->lMargin;
30115
30116 $this->divbuffer = array();
30117 $this->ktLinks = array();
30118 $this->ktAnnots = array();
30119 $this->ktForms = array();
30120 $this->ktBlock = array();
30121 $this->ktReference = array();
30122 $this->ktBMoutlines = array();
30123 $this->_kttoc = array();
30124 $this->keep_block_together = 0;
30125 }
30126}
30127
30128
30129//==================================================================
30130// Added ELLIPSES and CIRCLES
30131function Circle($x,$y,$r,$style='S') {
30132 $this->Ellipse($x,$y,$r,$r,$style);
30133}
30134
30135function Ellipse($x,$y,$rx,$ry,$style='S') {
30136 if($style=='F') { $op='f'; }
30137 elseif($style=='FD' or $style=='DF') { $op='B'; }
30138 else { $op='S'; }
30139 $lx=4/3*(M_SQRT2-1)*$rx;
30140 $ly=4/3*(M_SQRT2-1)*$ry;
30141 $h=$this->h;
30142 $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));
30143 $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));
30144 $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));
30145 $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));
30146}
30147
30148/*-- DIRECTW --*/
30149// Added adaptation of shaded_box = AUTOSIZE-TEXT
30150function AutosizeText($text,$w,$font,$style,$szfont=72) {
30151 $text = $this->purify_utf8_text($text);
30152 if ($this->text_input_as_HTML) {
30153 $text = $this->all_entities_to_utf8($text);
30154 }
30155 if ($this->usingCoreFont) { $text = mb_convert_encoding($text,$this->mb_enc,'UTF-8'); }
30156 $text = ' '.$text.' ';
30157 $width = $this->ConvertSize($w);
30158 $loop = 0;
30159 while ( $loop == 0 ) {
30160 $this->SetFont($font,$style,$szfont);
30161 $sz = $this->GetStringWidth( $text );
30162 if ( $sz > $w ) { $szfont --; }
30163 else { $loop ++; }
30164 }
30165 $this->SetFont($font,$style,$szfont);
30166 $this->Cell($w, 0, $text, 0, 0, "C");
30167}
30168/*-- END DIRECTW --*/
30169
30170
30171
30172
30173
30174// ====================================================
30175// ====================================================
30176/*-- RTL --*/
30177function reverse_letters($str) {
30178 $str = strtr($str, '{}[]()', '}{][)(');
30179 return $this->mb_strrev($str, $this->mb_enc);
30180}
30181
30182// mPDF 5.7+
30183function reverse_letters_preg_callback($matches) {
30184 return $this->reverse_letters($matches[1]);
30185}
30186
30187function magic_reverse_dir(&$chunk, $join=true, $dir) {
30188 if ($this->usingCoreFont) { return 0; }
30189 if ($this->biDirectional) {
30190 // mPDF 5.4.05 Include PUA for non-indexed Arabic glyphs
30191 $pregRTLchars = $this->pregRTLchars;
30192 if ($this->CurrentFont['unAGlyphs']) { $pregRTLchars .= "\x{F500}-\x{F7FF}"; }
30193
30194 // Change Arabic + Persian. to Presentation Forms
30195 if ($join) {
30196 $chunk = preg_replace_callback("/([".$pregRTLchars."]+)/u", array($this, 'arabJoinPregCallback'), $chunk ); // mPDF 5.7+
30197 }
30198 $contains_rtl = false;
30199 $all_rtl = true;
30200 $initSpace = false;
30201 $endSpace = false;
30202 $nonDirchars = "\x{A0}\"\'\(\)\{\}\[\].,:\\/-="; // mPDF 5.6.32
30203 // mPDF 5.6.43
30204 $bdo=array();
30205 preg_match_all('/([\x{202A}\x{202B}])(.*?)([\x{202C}])/u',$chunk,$m);
30206 if (count($m[0])) {
30207 for($i=0;$i<count($m[0]);$i++) {
30208 if ($m[1][$i]=="\xe2\x80\xab") { // Right-to-Left Embedding [RLE] U+202B &#8235;
30209 $mark = code2utf(0xf800+$i);
30210 $bdo[$i] = $this->reverse_letters($m[2][$i]);
30211 }
30212 else if ($m[1][$i]=="\xe2\x80\xaa") { // Left-to-Right Embedding [LRE] U+202A &#8234;
30213 $mark = code2utf(0xf880+$i);
30214 $bdo[$i] = $m[2][$i];
30215 }
30216 $chunk = preg_replace('/'.preg_quote($m[0][$i],'/').'/u',$mark,$chunk);
30217 }
30218 $pregRTLchars .= "\x{F800}-\x{F87F}";
30219 }
30220 if (preg_match("/[".$pregRTLchars."]/u",$chunk)) { // Chunk contains RTL characters
30221 if (preg_match("/^[ ]/",$chunk)) { $initSpace = true; $chunk = preg_replace("/^[ ]/",'',$chunk); }
30222 if (preg_match("/[ ]$/",$chunk)) { $endSpace = true; $chunk = preg_replace("/[ ]$/",'',$chunk); }
30223
30224 if (preg_match("/[^".$pregRTLchars.$nonDirchars." ]/u",$chunk)) { // Chunk also contains LTR characters
30225 $all_rtl = false;
30226 if ($dir == 'rtl') {
30227 $chunk = preg_replace("/([^".$pregRTLchars.$nonDirchars."][".$nonDirchars."]*) ([".$nonDirchars."]*[^".$pregRTLchars.$nonDirchars."])/u","\\1\x07\\2",$chunk);
30228 }
30229 $chunk = preg_replace("/([".$pregRTLchars."][".$nonDirchars."]*) ([".$nonDirchars."]*[".$pregRTLchars."])/u","\\1\x07\\2",$chunk);
30230 $bits = explode(' ',$chunk);
30231 foreach($bits AS $bitkey=>$bit) {
30232 $bit = preg_replace("/\x07/"," ",$bit);
30233 if (preg_match("/^[".$pregRTLchars.$nonDirchars." ]*$/u",$bit)) {
30234 $bits[$bitkey] = $this->reverse_letters($bit);
30235 }
30236 else if (preg_match("/[".$pregRTLchars."]/u",$bit)) {
30237 if ($dir == 'rtl') {
30238 $bit = preg_replace("/([^".$pregRTLchars.$nonDirchars." ])([".$nonDirchars."]*[".$pregRTLchars."])/u","\\1\x07\\2",$bit );
30239 $bit = preg_replace("/([".$pregRTLchars."][".$nonDirchars."]*)([^".$pregRTLchars.$nonDirchars." ])/u","\\1\x07\\2",$bit );
30240 }
30241 else {
30242 $bit = preg_replace("/([^".$pregRTLchars." ][".$nonDirchars."]*)([".$pregRTLchars." ])/u","\\1\x07\\2",$bit );
30243 $bit = preg_replace("/([".$pregRTLchars." ])([".$nonDirchars."]*[^".$pregRTLchars." ])/u","\\1\x07\\2",$bit );
30244 }
30245 $sbits = explode("\x07",$bit );
30246 foreach($sbits AS $sbitkey=>$sbit) {
30247 $sbit = preg_replace("/\x07/","",$sbit);
30248 if (preg_match("/^[".$pregRTLchars.$nonDirchars." ]*$/u",$sbit)) {
30249 $sbits[$sbitkey] = $this->reverse_letters($sbit);
30250 }
30251 else if (preg_match("/[".$pregRTLchars."]/u",$sbit) && $dir=='rtl') {
30252 $sbits[$sbitkey] = $this->reverse_letters($sbit);
30253 }
30254 else {
30255 // Reverse numerals only to RTL
30256 $sbit = preg_replace_callback("/([\x{0660}-\x{066C}0-9]+[\x{0660}-\x{066C}0-9\.,:\/]*[\x{0660}-\x{066C}0-9]+)/u", array($this, 'reverse_letters_preg_callback'), $sbit ); // mPDF 5.7+
30257 $sbits[$sbitkey] = $sbit;
30258 }
30259 }
30260 if ($dir == 'rtl') { $sbits = array_reverse($sbits,false); }
30261 $bits[$bitkey] = implode('',$sbits);
30262 }
30263 else if (preg_match("/[".$pregRTLchars."]/u",$bit) && $dir=='rtl') {
30264 $bits[$bitkey] = $this->reverse_letters($bit);
30265 }
30266 else {
30267 // Reverse numerals only to RTL
30268 $bit = preg_replace_callback("/([\x{0660}-\x{066C}0-9]+[\x{0660}-\x{066C}0-9\.,:\/]*[\x{0660}-\x{066C}0-9]+)/u", array($this, 'reverse_letters_preg_callback'), $bit ); // mPDF 5.7+
30269 $bits[$bitkey] = $bit;
30270 }
30271 }
30272 if ($dir == 'rtl') { $bits = array_reverse($bits,false); }
30273 $chunk = implode(' ',$bits);
30274 }
30275 else { $chunk = $this->reverse_letters($chunk); }
30276 $contains_rtl = true;
30277
30278 // Un-Reverse numerals back to ltr
30279 $chunk = preg_replace_callback("/([\x{0660}-\x{066C}0-9]+[\x{0660}-\x{066C}0-9\.,:\/]*[\x{0660}-\x{066C}0-9]+)/u", array($this, 'reverse_letters_preg_callback'), $chunk ); // mPDF 5.7+
30280 if ($dir == 'rtl') {
30281 if ($endSpace) { $chunk = ' '.$chunk; }
30282 if ($initSpace) { $chunk .= ' '; }
30283 }
30284 else {
30285 if ($initSpace) { $chunk = ' '.$chunk; }
30286 if ($endSpace) { $chunk .= ' '; }
30287 }
30288 }
30289 else { $all_rtl = false; }
30290
30291 // mPDF 5.6.43
30292 if (count($bdo)) {
30293 for($i=0;$i<count($bdo);$i++) {
30294 $chunk = preg_replace('/[\x{'.dechex(intval(0xf800+$i)).'}\x{'.dechex(intval(0xf880+$i)).'}]/u',$bdo[$i],$chunk);
30295 }
30296 }
30297
30298 if ($all_rtl) { return 2; }
30299 else if ($contains_rtl) { return 1; }
30300 else { return 0; }
30301 }
30302 return 0;
30303}
30304/*-- END RTL --*/
30305
30306//
30307// ****************************
30308// ****************************
30309
30310
30311function SetSubstitutions() {
30312 $subsarray = array();
30313 @include(_MPDF_PATH.'includes/subs_win-1252.php');
30314 $this->substitute = array();
30315 foreach($subsarray AS $key => $val) {
30316 $this->substitute[code2utf($key)] = $val;
30317 }
30318}
30319
30320
30321function SubstituteChars($html) {
30322 // only substitute characters between tags
30323 if (count($this->substitute)) {
30324 $a=preg_split('/(<.*?>)/ms',$html,-1,PREG_SPLIT_DELIM_CAPTURE);
30325 $html = '';
30326 foreach($a as $i => $e) {
30327 if($i%2==0) {
30328 $e = strtr($e, $this->substitute);
30329 }
30330 $html .= $e;
30331 }
30332 }
30333 return $html;
30334}
30335
30336
30337function SubstituteCharsSIP(&$writehtml_a, &$writehtml_i, &$writehtml_e) {
30338 if (preg_match("/^(.*?)([\x{20000}-\x{2FFFF}]+)(.*)/u", $writehtml_e, $m)) {
30339 if (isset($this->CurrentFont['sipext']) && $this->CurrentFont['sipext']) {
30340 $font = $this->CurrentFont['sipext'];
30341 if (!in_array($font, $this->available_unifonts)) { return 0; }
30342 $writehtml_a[$writehtml_i] = $writehtml_e = $m[1];
30343 array_splice($writehtml_a, $writehtml_i+1, 0, array('span style="font-family: '.$font.'"', $m[2], '/span', $m[3]));
30344 $this->subPos = $writehtml_i;
30345 return 4;
30346 }
30347 }
30348 return 0;
30349}
30350
30351// If core font is selected in document which is not onlyCoreFonts - substitute with non-core font
30352function SubstituteCharsNonCore(&$writehtml_a, &$writehtml_i, &$writehtml_e) {
30353 if (mb_convert_encoding(mb_convert_encoding($writehtml_e, $this->mb_enc, "UTF-8"), "UTF-8", $this->mb_enc) == $writehtml_e) {
30354 return 0;
30355 }
30356 $cw = &$this->CurrentFont['cw'];
30357 $unicode = $this->UTF8StringToArray($writehtml_e, false);
30358 $start = -1;
30359 $end = 0;
30360 $flag = 0;
30361 $ftype = '';
30362 $u = array();
30363 if (!$this->subArrMB) {
30364 include(_MPDF_PATH.'includes/subs_core.php');
30365 $this->subArrMB['a'] = $aarr;
30366 $this->subArrMB['s'] = $sarr;
30367 $this->subArrMB['z'] = $zarr;
30368 }
30369 foreach($unicode AS $c => $char) {
30370 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)) {
30371 if ($flag==0) { $start=$c; }
30372 $flag=1;
30373 $u[] = $char;
30374 }
30375 else if ($flag>0) { $end=$c-1; break; }
30376 }
30377 if ($flag>0 && !$end) { $end=count($unicode)-1; }
30378 if ($start==-1) { return 0; }
30379 // TRY IN BACKUP SUBS FONT
30380 if (!is_array($this->backupSubsFont)) { $this->backupSubsFont = array("$this->backupSubsFont"); }
30381 foreach($this->backupSubsFont AS $bsfctr=>$bsf) {
30382 if ($this->fonttrans[$bsf] == 'chelvetica' || $this->fonttrans[$bsf] == 'ctimes' || $this->fonttrans[$bsf] == 'ccourier') { continue; }
30383 $font = $bsf;
30384 unset($cw);
30385 $cw = '';
30386 if (isset($this->fonts[$font])) { $cw = &$this->fonts[$font]['cw']; }
30387 else if (file_exists(_MPDF_TTFONTDATAPATH.$font.'.cw.dat')) { $cw = @file_get_contents(_MPDF_TTFONTDATAPATH.$font.'.cw.dat'); }
30388 else {
30389
30390 $prevFontFamily = $this->FontFamily;
30391 $prevFontStyle = $this->currentfontstyle;
30392 $prevFontSizePt = $this->FontSizePt;
30393 $this->SetFont($bsf, '', '', false);
30394 $cw = @file_get_contents(_MPDF_TTFONTDATAPATH.$font.'.cw.dat');
30395 $this->SetFont($prevFontFamily, $prevFontStyle, $prevFontSizePt, false);
30396 }
30397 if (!$cw) { continue; }
30398 $l = 0;
30399 foreach($u AS $char) {
30400 if ($char == 173 || $this->_charDefined($cw,$char) || ($char>1536 && $char<1791) || ($char>2304 && $char<3455 )) {
30401 $l++;
30402 }
30403 else {
30404 if ($l==0 && $bsfctr == (count($this->backupSubsFont)-1)) { // Not found even in last backup font
30405 $cont = mb_substr($writehtml_e, $start+1);
30406 $writehtml_e = mb_substr($writehtml_e, 0, $start+1, 'UTF-8');
30407 array_splice($writehtml_a, $writehtml_i+1, 0, array('', $cont));
30408 $this->subPos = $writehtml_i+1;
30409 return 2;
30410 }
30411 else { break; }
30412 }
30413 }
30414 if ($l > 0) {
30415 $patt = mb_substr($writehtml_e, $start, $l, 'UTF-8');
30416 if (preg_match("/(.*?)(".preg_quote($patt,'/').")(.*)/u", $writehtml_e, $m)) {
30417 $writehtml_e = $m[1];
30418 array_splice($writehtml_a, $writehtml_i+1, 0, array('span style="font-family: '.$font.'"', $m[2], '/span', $m[3]));
30419 $this->subPos = $writehtml_i+3;
30420 return 4;
30421 }
30422 }
30423 }
30424
30425 unset($cw);
30426 return 0;
30427}
30428
30429
30430function SubstituteCharsMB(&$writehtml_a, &$writehtml_i, &$writehtml_e) {
30431 $cw = &$this->CurrentFont['cw'];
30432 $unicode = $this->UTF8StringToArray($writehtml_e, false);
30433 $start = -1;
30434 $end = 0;
30435 $flag = 0;
30436 $ftype = '';
30437 $u = array();
30438 foreach($unicode AS $c => $char) {
30439 if (($flag == 0 || $flag==2) && (!$this->_charDefined($cw,$char) || ($flag==2 && $char==32)) && $this->checkSIP && $char > 131071) { // Unicode Plane 2 (SIP)
30440 if (in_array($this->FontFamily ,$this->available_CJK_fonts)) { return 0; }
30441 if ($flag==0) { $start=$c; }
30442 $flag=2;
30443 $u[] = $char;
30444 }
30445 //else if (($flag == 0 || $flag==1) && $char != 173 && !$this->_charDefined($cw,$char) && ($char<1423 || ($char>3583 && $char < 11263))) {
30446 else if (($flag == 0 || $flag==1) && $char != 173 && (!$this->_charDefined($cw,$char) || ($flag==1 && $char==32)) && ($char<1536 || ($char>1791 && $char < 2304) || $char>3455)) {
30447 if ($flag==0) { $start=$c; }
30448 $flag=1;
30449 $u[] = $char;
30450 }
30451 else if ($flag>0) { $end=$c-1; break; }
30452 }
30453 if ($flag>0 && !$end) { $end=count($unicode)-1; }
30454 if ($start==-1) { return 0; }
30455 if ($flag == 2) { // SIP
30456 // Check if current CJK font has a ext-B related font
30457 if (isset($this->CurrentFont['sipext']) && $this->CurrentFont['sipext']) {
30458 $font = $this->CurrentFont['sipext'];
30459 unset($cw);
30460 $cw = '';
30461 if (isset($this->fonts[$font])) { $cw = &$this->fonts[$font]['cw']; }
30462 else if (file_exists(_MPDF_TTFONTDATAPATH.$font.'.cw.dat')) { $cw = @file_get_contents(_MPDF_TTFONTDATAPATH.$font.'.cw.dat'); }
30463 else {
30464 $prevFontFamily = $this->FontFamily;
30465 $prevFontStyle = $this->currentfontstyle;
30466 $prevFontSizePt = $this->FontSizePt;
30467 $this->SetFont($font, '', '', false);
30468 $cw = @file_get_contents(_MPDF_TTFONTDATAPATH.$font.'.cw.dat');
30469 $this->SetFont($prevFontFamily, $prevFontStyle, $prevFontSizePt, false);
30470 }
30471 if (!$cw) { return 0; }
30472 $l = 0;
30473 foreach($u AS $char) {
30474 if ($this->_charDefined($cw,$char) || $char > 131071) {
30475 $l++;
30476 }
30477 else { break; }
30478 }
30479 if ($l > 0) {
30480 $patt = mb_substr($writehtml_e, $start, $l);
30481 if (preg_match("/(.*?)(".preg_quote($patt,'/').")(.*)/u", $writehtml_e, $m)) {
30482 $writehtml_e = $m[1];
30483 array_splice($writehtml_a, $writehtml_i+1, 0, array('span style="font-family: '.$font.'"', $m[2], '/span', $m[3]));
30484 $this->subPos = $writehtml_i+3;
30485 return 4;
30486 }
30487 }
30488 }
30489 // Check Backup SIP font (defined in config_fonts.php)
30490 if (isset($this->backupSIPFont) && $this->backupSIPFont) {
30491 if ($this->currentfontfamily != $this->backupSIPFont) { $font = $this->backupSIPFont; }
30492 else { unset($cw); return 0; }
30493 unset($cw);
30494 $cw = '';
30495 if (isset($this->fonts[$font])) { $cw = &$this->fonts[$font]['cw']; }
30496 else if (file_exists(_MPDF_TTFONTDATAPATH.$font.'.cw.dat')) { $cw = @file_get_contents(_MPDF_TTFONTDATAPATH.$font.'.cw.dat'); }
30497 else {
30498 $prevFontFamily = $this->FontFamily;
30499 $prevFontStyle = $this->currentfontstyle;
30500 $prevFontSizePt = $this->FontSizePt;
30501 $this->SetFont($this->backupSIPFont, '', '', false);
30502 $cw = @file_get_contents(_MPDF_TTFONTDATAPATH.$font.'.cw.dat');
30503 $this->SetFont($prevFontFamily, $prevFontStyle, $prevFontSizePt, false);
30504 }
30505 if (!$cw) { return 0; }
30506 $l = 0;
30507 foreach($u AS $char) {
30508 if ($this->_charDefined($cw,$char) || $char > 131071) {
30509 $l++;
30510 }
30511 else { break; }
30512 }
30513 if ($l > 0) {
30514 $patt = mb_substr($writehtml_e, $start, $l);
30515 if (preg_match("/(.*?)(".preg_quote($patt,'/').")(.*)/u", $writehtml_e, $m)) {
30516 $writehtml_e = $m[1];
30517 array_splice($writehtml_a, $writehtml_i+1, 0, array('span style="font-family: '.$font.'"', $m[2], '/span', $m[3]));
30518 $this->subPos = $writehtml_i+3;
30519 return 4;
30520 }
30521 }
30522 }
30523 return 0;
30524 }
30525
30526
30527 // FIRST TRY CORE FONTS
30528 if (!$this->PDFA && !$this->PDFX) {
30529 $repl = array();
30530 if (!$this->subArrMB) {
30531 include(_MPDF_PATH.'includes/subs_core.php');
30532 $this->subArrMB['a'] = $aarr;
30533 $this->subArrMB['s'] = $sarr;
30534 $this->subArrMB['z'] = $zarr;
30535 }
30536 if (isset($this->subArrMB['a'][$u[0]])) {
30537 $font = 'tta'; $ftype = 'C';
30538 foreach($u AS $char) {
30539 if ($this->subArrMB['a'][$char]) { $repl[] = $this->subArrMB['a'][$char]; }
30540 else { break; }
30541 }
30542 }
30543 else if (isset($this->subArrMB['z'][$u[0]])) {
30544 $font = 'ttz'; $ftype = 'C';
30545 foreach($u AS $char) {
30546 if ($this->subArrMB['z'][$char]) { $repl[] = $this->subArrMB['z'][$char]; }
30547 else { break; }
30548 }
30549 }
30550 else if (isset($this->subArrMB['s'][$u[0]])) {
30551 $font = 'tts'; $ftype = 'C';
30552 foreach($u AS $char) {
30553 if ($this->subArrMB['s'][$char]) { $repl[] = $this->subArrMB['s'][$char]; }
30554 else { break; }
30555 }
30556 }
30557 if ($ftype=='C') {
30558 $patt = mb_substr($writehtml_e, $start, count($repl));
30559 if (preg_match("/(.*?)(".preg_quote($patt,'/').")(.*)/u", $writehtml_e, $m)) {
30560 $writehtml_e = $m[1];
30561 array_splice($writehtml_a, $writehtml_i+1, 0, array($font, implode('|', $repl), '/'.$font, $m[3])); // e.g. <tts>
30562 $this->subPos = $writehtml_i+3;
30563 return 4;
30564 }
30565 return 0;
30566 }
30567 }
30568
30569 // FIND IN DEFAULT FONT - removed mPDF 5.0
30570
30571 // LASTLY TRY IN BACKUP SUBS FONT
30572 if (!is_array($this->backupSubsFont)) { $this->backupSubsFont = array("$this->backupSubsFont"); }
30573 foreach($this->backupSubsFont AS $bsfctr=>$bsf) {
30574 if ($this->currentfontfamily != $bsf) { $font = $bsf; }
30575 else { continue; }
30576 unset($cw);
30577 $cw = '';
30578 if (isset($this->fonts[$font])) { $cw = &$this->fonts[$font]['cw']; }
30579 else if (file_exists(_MPDF_TTFONTDATAPATH.$font.'.cw.dat')) { $cw = @file_get_contents(_MPDF_TTFONTDATAPATH.$font.'.cw.dat'); }
30580 else {
30581 $prevFontFamily = $this->FontFamily;
30582 $prevFontStyle = $this->currentfontstyle;
30583 $prevFontSizePt = $this->FontSizePt;
30584 $this->SetFont($bsf, '', '', false);
30585 $cw = @file_get_contents(_MPDF_TTFONTDATAPATH.$font.'.cw.dat');
30586 $this->SetFont($prevFontFamily, $prevFontStyle, $prevFontSizePt, false);
30587 }
30588 if (!$cw) { continue; }
30589 $l = 0;
30590 foreach($u AS $char) {
30591 if ($char == 173 || $this->_charDefined($cw,$char) || ($char>1536 && $char<1791) || ($char>2304 && $char<3455 )) { // Arabic and Indic
30592 $l++;
30593 }
30594 else {
30595 if ($l==0 && $bsfctr == (count($this->backupSubsFont)-1)) { // Not found even in last backup font
30596 $cont = mb_substr($writehtml_e, $start+1);
30597 $writehtml_e = mb_substr($writehtml_e, 0, $start+1);
30598 array_splice($writehtml_a, $writehtml_i+1, 0, array('', $cont));
30599 $this->subPos = $writehtml_i+1;
30600 return 2;
30601 }
30602 else { break; }
30603 }
30604 }
30605 if ($l > 0) {
30606 $patt = mb_substr($writehtml_e, $start, $l);
30607 if (preg_match("/(.*?)(".preg_quote($patt,'/').")(.*)/u", $writehtml_e, $m)) {
30608 $writehtml_e = $m[1];
30609 array_splice($writehtml_a, $writehtml_i+1, 0, array('span style="font-family: '.$font.'"', $m[2], '/span', $m[3]));
30610 $this->subPos = $writehtml_i+3;
30611 return 4;
30612 }
30613 }
30614 }
30615
30616 unset($cw);
30617 return 0;
30618}
30619
30620
30621function setHiEntitySubstitutions() {
30622 $entarr = array (
30623 'nbsp' => '160', 'iexcl' => '161', 'cent' => '162', 'pound' => '163', 'curren' => '164', 'yen' => '165', 'brvbar' => '166', 'sect' => '167',
30624 'uml' => '168', 'copy' => '169', 'ordf' => '170', 'laquo' => '171', 'not' => '172', 'shy' => '173', 'reg' => '174', 'macr' => '175',
30625 'deg' => '176', 'plusmn' => '177', 'sup2' => '178', 'sup3' => '179', 'acute' => '180', 'micro' => '181', 'para' => '182', 'middot' => '183',
30626 'cedil' => '184', 'sup1' => '185', 'ordm' => '186', 'raquo' => '187', 'frac14' => '188', 'frac12' => '189', 'frac34' => '190',
30627 'iquest' => '191', 'Agrave' => '192', 'Aacute' => '193', 'Acirc' => '194', 'Atilde' => '195', 'Auml' => '196', 'Aring' => '197',
30628 'AElig' => '198', 'Ccedil' => '199', 'Egrave' => '200', 'Eacute' => '201', 'Ecirc' => '202', 'Euml' => '203', 'Igrave' => '204',
30629 'Iacute' => '205', 'Icirc' => '206', 'Iuml' => '207', 'ETH' => '208', 'Ntilde' => '209', 'Ograve' => '210', 'Oacute' => '211',
30630 'Ocirc' => '212', 'Otilde' => '213', 'Ouml' => '214', 'times' => '215', 'Oslash' => '216', 'Ugrave' => '217', 'Uacute' => '218',
30631 'Ucirc' => '219', 'Uuml' => '220', 'Yacute' => '221', 'THORN' => '222', 'szlig' => '223', 'agrave' => '224', 'aacute' => '225',
30632 'acirc' => '226', 'atilde' => '227', 'auml' => '228', 'aring' => '229', 'aelig' => '230', 'ccedil' => '231', 'egrave' => '232',
30633 'eacute' => '233', 'ecirc' => '234', 'euml' => '235', 'igrave' => '236', 'iacute' => '237', 'icirc' => '238', 'iuml' => '239',
30634 'eth' => '240', 'ntilde' => '241', 'ograve' => '242', 'oacute' => '243', 'ocirc' => '244', 'otilde' => '245', 'ouml' => '246',
30635 'divide' => '247', 'oslash' => '248', 'ugrave' => '249', 'uacute' => '250', 'ucirc' => '251', 'uuml' => '252', 'yacute' => '253',
30636 'thorn' => '254', 'yuml' => '255', 'OElig' => '338', 'oelig' => '339', 'Scaron' => '352', 'scaron' => '353', 'Yuml' => '376',
30637 'fnof' => '402', 'circ' => '710', 'tilde' => '732', 'Alpha' => '913', 'Beta' => '914', 'Gamma' => '915', 'Delta' => '916',
30638 'Epsilon' => '917', 'Zeta' => '918', 'Eta' => '919', 'Theta' => '920', 'Iota' => '921', 'Kappa' => '922', 'Lambda' => '923',
30639 'Mu' => '924', 'Nu' => '925', 'Xi' => '926', 'Omicron' => '927', 'Pi' => '928', 'Rho' => '929', 'Sigma' => '931', 'Tau' => '932',
30640 'Upsilon' => '933', 'Phi' => '934', 'Chi' => '935', 'Psi' => '936', 'Omega' => '937', 'alpha' => '945', 'beta' => '946', 'gamma' => '947',
30641 'delta' => '948', 'epsilon' => '949', 'zeta' => '950', 'eta' => '951', 'theta' => '952', 'iota' => '953', 'kappa' => '954',
30642 'lambda' => '955', 'mu' => '956', 'nu' => '957', 'xi' => '958', 'omicron' => '959', 'pi' => '960', 'rho' => '961', 'sigmaf' => '962',
30643 'sigma' => '963', 'tau' => '964', 'upsilon' => '965', 'phi' => '966', 'chi' => '967', 'psi' => '968', 'omega' => '969',
30644 'thetasym' => '977', 'upsih' => '978', 'piv' => '982', 'ensp' => '8194', 'emsp' => '8195', 'thinsp' => '8201', 'zwnj' => '8204',
30645 'zwj' => '8205', 'lrm' => '8206', 'rlm' => '8207', 'ndash' => '8211', 'mdash' => '8212', 'lsquo' => '8216', 'rsquo' => '8217',
30646 'sbquo' => '8218', 'ldquo' => '8220', 'rdquo' => '8221', 'bdquo' => '8222', 'dagger' => '8224', 'Dagger' => '8225', 'bull' => '8226',
30647 'hellip' => '8230', 'permil' => '8240', 'prime' => '8242', 'Prime' => '8243', 'lsaquo' => '8249', 'rsaquo' => '8250', 'oline' => '8254',
30648 'frasl' => '8260', 'euro' => '8364', 'image' => '8465', 'weierp' => '8472', 'real' => '8476', 'trade' => '8482', 'alefsym' => '8501',
30649 'larr' => '8592', 'uarr' => '8593', 'rarr' => '8594', 'darr' => '8595', 'harr' => '8596', 'crarr' => '8629', 'lArr' => '8656',
30650 'uArr' => '8657', 'rArr' => '8658', 'dArr' => '8659', 'hArr' => '8660', 'forall' => '8704', 'part' => '8706', 'exist' => '8707',
30651 'empty' => '8709', 'nabla' => '8711', 'isin' => '8712', 'notin' => '8713', 'ni' => '8715', 'prod' => '8719', 'sum' => '8721',
30652 'minus' => '8722', 'lowast' => '8727', 'radic' => '8730', 'prop' => '8733', 'infin' => '8734', 'ang' => '8736', 'and' => '8743',
30653 'or' => '8744', 'cap' => '8745', 'cup' => '8746', 'int' => '8747', 'there4' => '8756', 'sim' => '8764', 'cong' => '8773',
30654 'asymp' => '8776', 'ne' => '8800', 'equiv' => '8801', 'le' => '8804', 'ge' => '8805', 'sub' => '8834', 'sup' => '8835', 'nsub' => '8836',
30655 'sube' => '8838', 'supe' => '8839', 'oplus' => '8853', 'otimes' => '8855', 'perp' => '8869', 'sdot' => '8901', 'lceil' => '8968',
30656 'rceil' => '8969', 'lfloor' => '8970', 'rfloor' => '8971', 'lang' => '9001', 'rang' => '9002', 'loz' => '9674', 'spades' => '9824',
30657 'clubs' => '9827', 'hearts' => '9829', 'diams' => '9830',
30658 );
30659 foreach($entarr AS $key => $val) {
30660 $this->entsearch[] = '&'.$key.';';
30661 $this->entsubstitute[] = code2utf($val);
30662 }
30663}
30664
30665function SubstituteHiEntities($html) {
30666 // converts html_entities > ASCII 127 to unicode
30667 // Leaves in particular &lt; to distinguish from tag marker
30668 if (count($this->entsearch)) {
30669 $html = str_replace($this->entsearch,$this->entsubstitute,$html);
30670 }
30671 return $html;
30672}
30673
30674
30675// Edited v1.2 Pass by reference; option to continue if invalid UTF-8 chars
30676function is_utf8(&$string) {
30677 if ($string === mb_convert_encoding(mb_convert_encoding($string, "UTF-32", "UTF-8"), "UTF-8", "UTF-32")) {
30678 return true;
30679 }
30680 else {
30681 if ($this->ignore_invalid_utf8) {
30682 $string = mb_convert_encoding(mb_convert_encoding($string, "UTF-32", "UTF-8"), "UTF-8", "UTF-32") ;
30683 return true;
30684 }
30685 else {
30686 return false;
30687 }
30688 }
30689}
30690
30691
30692function purify_utf8($html,$lo=true) {
30693 // For HTML
30694 // Checks string is valid UTF-8 encoded
30695 // converts html_entities > ASCII 127 to UTF-8
30696 // Only exception - leaves low ASCII entities e.g. &lt; &amp; etc.
30697 // Leaves in particular &lt; to distinguish from tag marker
30698 if (!$this->is_utf8($html)) {
30699 echo "<p><b>HTML contains invalid UTF-8 character(s)</b></p>";
30700 while (mb_convert_encoding(mb_convert_encoding($html, "UTF-32", "UTF-8"), "UTF-8", "UTF-32") != $html) {
30701 $a = iconv('UTF-8', 'UTF-8', $html);
30702 echo ($a);
30703 $pos = $start = strlen($a);
30704 $err = '';
30705 while ( ord(substr($html,$pos,1)) > 128 ) {
30706 $err .= '[[#'.ord(substr($html,$pos,1)).']]';
30707 $pos++;
30708 }
30709 echo '<span style="color:red; font-weight:bold">'.$err.'</span>';
30710 $html = substr($html, $pos);
30711 }
30712 echo $html;
30713 $this->Error("");
30714 }
30715 $html = preg_replace("/\r/", "", $html );
30716
30717 // converts html_entities > ASCII 127 to UTF-8
30718 // Leaves in particular &lt; to distinguish from tag marker
30719 $html = $this->SubstituteHiEntities($html);
30720
30721 // converts all &#nnn; or &#xHHH; to UTF-8 multibyte
30722 // If $lo==true then includes ASCII < 128
30723 $html = strcode2utf($html,$lo);
30724 return ($html);
30725}
30726
30727function purify_utf8_text($txt) {
30728 // For TEXT
30729 // Make sure UTF-8 string of characters
30730 if (!$this->is_utf8($txt)) { $this->Error("Text contains invalid UTF-8 character(s)"); }
30731
30732 $txt = preg_replace("/\r/", "", $txt );
30733
30734 return ($txt);
30735}
30736function all_entities_to_utf8($txt) {
30737 // converts txt_entities > ASCII 127 to UTF-8
30738 // Leaves in particular &lt; to distinguish from tag marker
30739 $txt = $this->SubstituteHiEntities($txt);
30740
30741 // converts all &#nnn; or &#xHHH; to UTF-8 multibyte
30742 $txt = strcode2utf($txt);
30743
30744 $txt = $this->lesser_entity_decode($txt);
30745 return ($txt);
30746}
30747
30748
30749// ====================================================
30750/*-- BARCODES --*/
30751// UPC/EAN barcode
30752// EAN13, EAN8, UPCA, UPCE, ISBN, ISSN
30753// Accepts 12 or 13 digits with or without - hyphens
30754function 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) {
30755 if (empty($code)) {
30756 return;
30757 }
30758 $codestr = $code;
30759 $code = preg_replace('/\-/','',$code);
30760
30761 if (!class_exists('PDFBarcode', false)) {
30762 include(_MPDF_PATH.'classes/barcode.php');
30763 }
30764 $this->barcode = new PDFBarcode();
30765 if ($btype == 'ISSN' || $btype == 'ISBN') {
30766 $arrcode = $this->barcode->getBarcodeArray($code, 'EAN13');
30767 }
30768 else { $arrcode = $this->barcode->getBarcodeArray($code, $btype); }
30769
30770 if ($arrcode === false) { $this->Error('Error in barcode string: '.$codestr); }
30771 if((($btype=='EAN13' || $btype=='ISBN' || $btype=='ISSN') && strlen($code) == 12) || ($btype=='UPCA' && strlen($code) == 11)
30772 || ($btype=='UPCE' && strlen($code) == 11) || ($btype=='EAN8' && strlen($code) == 7)) {
30773 $code .= $arrcode['checkdigit'];
30774 if (stristr($codestr,'-')) { $codestr .= '-' . $arrcode['checkdigit']; }
30775 else { $codestr .= $arrcode['checkdigit']; }
30776 }
30777 if ($btype == 'ISBN') { $codestr = 'ISBN '.$codestr; }
30778 if ($btype == 'ISSN') { $codestr = 'ISSN '.$codestr; }
30779
30780 if (empty($x)) {
30781 $x = $this->x;
30782 }
30783 if (empty($y)) {
30784 $y = $this->y;
30785 }
30786 // set foreground color
30787 $prevDrawColor = $this->DrawColor;
30788 $prevTextColor = $this->TextColor;
30789 $prevFillColor = $this->FillColor;
30790 $lw = $this->LineWidth;
30791 $this->SetLineWidth(0.01);
30792
30793 $size /= $k; // in case resized in a table
30794
30795 $xres = $arrcode['nom-X'] * $size;
30796 $llm = $arrcode['lightmL'] * $arrcode['nom-X'] * $size; // Left Light margin
30797 $rlm = $arrcode['lightmR'] * $arrcode['nom-X'] * $size; // Right Light margin
30798
30799 $bcw = ($arrcode["maxw"] * $xres); // Barcode width = Should always be 31.35mm * $size
30800
30801 $fbw = $bcw + $llm + $rlm; // Full barcode width incl. light margins
30802 $ow = $fbw + $paddingL + $paddingR; // Full overall width incl. user-defined padding
30803
30804 $fbwi = $fbw - 2; // Full barcode width incl. light margins - 2mm - for isbn string
30805
30806 // cf. http://www.gs1uk.org/downloads/bar_code/Bar coding getting it right.pdf
30807 $num_height = 3 * $size; // Height of numerals
30808 $fbh = $arrcode['nom-H'] * $size * $height; // Full barcode height incl. numerals
30809 $bch = $fbh - (1.5 * $size); // Barcode height of bars (3mm for numerals)
30810
30811 if (($btype=='EAN13' && $showtext) || $btype == 'ISSN' || $btype == 'ISBN') { // Add height for ISBN string + margin from top of bars
30812 $tisbnm = 1.5 * $size; // Top margin between isbn (if shown) & bars
30813 $codestr_fontsize = 2.1 * $size;
30814 $paddingT += $codestr_fontsize + $tisbnm ;
30815 }
30816 $oh = $fbh + $paddingT + $paddingB; // Full overall height incl. user-defined padding
30817
30818 // PRINT border background color
30819 $xpos = $x;
30820 $ypos = $y;
30821 if ($col) {
30822 $this->SetDColor($col);
30823 $this->SetTColor($col);
30824 }
30825 else {
30826 $this->SetDColor($this->ConvertColor(0));
30827 $this->SetTColor($this->ConvertColor(0));
30828 }
30829 if ($bgcol) {
30830 $this->SetFColor($bgcol);
30831 }
30832 else { $this->SetFColor($this->ConvertColor(255)); }
30833 if (!$bgcol && !$col) { // fn. called directly - not via HTML
30834 if ($border) { $fillb = 'DF'; } else { $fillb = 'F'; }
30835 $this->Rect($xpos, $ypos, $ow, $oh, $fillb);
30836 }
30837
30838
30839 // PRINT BARS
30840 $xpos = $x + $paddingL + $llm ;
30841 $ypos = $y + $paddingT;
30842 if ($col) { $this->SetFColor($col); }
30843 else { $this->SetFColor($this->ConvertColor(0)); }
30844 if ($arrcode !== false) {
30845 foreach ($arrcode["bcode"] AS $v) {
30846 $bw = ($v["w"] * $xres);
30847 if ($v["t"]) {
30848 // draw a vertical bar
30849 $this->Rect($xpos, $ypos, $bw, $bch, 'F');
30850 }
30851 $xpos += $bw;
30852 }
30853 }
30854
30855
30856 // print text
30857 $prevFontFamily = $this->FontFamily;
30858 $prevFontStyle = $this->FontStyle;
30859 $prevFontSizePt = $this->FontSizePt;
30860
30861 // ISBN string
30862 if (($btype=='EAN13' && $showtext) || $btype=='ISBN' || $btype=='ISSN') {
30863 if ($this->onlyCoreFonts) {
30864 $this->SetFont('chelvetica');
30865 }
30866 else {
30867 $this->SetFont('sans');
30868 }
30869
30870 if ($bgcol) { $this->SetFColor($bgcol); }
30871 else { $this->SetFColor($this->ConvertColor(255)); }
30872 $this->x = $x + $paddingL + 1; // 1mm left margin (cf. $fbwi above)
30873 // max width is $fbwi
30874 $loop = 0;
30875 while ( $loop == 0 ) {
30876 $this->SetFontSize($codestr_fontsize*1.4*_MPDFK, false); // don't write
30877 $sz = $this->GetStringWidth( $codestr );
30878 if ($sz > $fbwi)
30879 $codestr_fontsize -= 0.1;
30880 else
30881 $loop ++;
30882 }
30883 $this->SetFont('','',$codestr_fontsize*1.4*_MPDFK, true, true); // * 1.4 because font height is only 7/10 of given mm
30884 // WORD SPACING
30885 if ($fbwi > $sz) {
30886 $xtra = $fbwi - $sz;
30887 $charspacing = $xtra / (strlen($codestr)-1);
30888 if ($charspacing) { $this->_out(sprintf('BT %.3F Tc ET',$charspacing*_MPDFK)); }
30889 }
30890 $this->y = $y + $paddingT - ($codestr_fontsize ) - $tisbnm ;
30891 $this->Cell($fbw , $codestr_fontsize, $codestr);
30892 if ($charspacing) { $this->_out('BT 0 Tc ET'); }
30893 }
30894
30895
30896 // Bottom NUMERALS
30897 if ($this->onlyCoreFonts) {
30898 $this->SetFont('mono');
30899 }
30900 else {
30901 if (in_array('ocrb',$this->available_unifonts)) { $this->SetFont('ocrb'); }
30902 else { $this->SetFont('mono'); }
30903 }
30904 if (isset($this->CurrentFont['desc']['CapHeight'])) { $fh = (1000/$this->CurrentFont['desc']['CapHeight']); }
30905 else if (isset($this->CurrentFont['desc']['Ascent'])) { $fh = (1000/$this->CurrentFont['desc']['Ascent']); }
30906 else { $fh = 1.2; }
30907
30908 $charRO = '';
30909 if ($btype=='EAN13' || $btype=='ISBN' || $btype=='ISSN') {
30910 $outerfontsize = 3; // Inner fontsize = 3
30911 $outerp = $xres * 4;
30912 $innerp = $xres * 2.5;
30913 $textw = ($bcw*0.5) - $outerp - $innerp;
30914 $chars = 6; // number of numerals in each half
30915 $charLO = substr($code,0,1); // Left Outer
30916 $charLI = substr($code,1,6); // Left Inner
30917 $charRI = substr($code,7,6); // Right Inner
30918 if (!$supplement) $charRO = '>'; // Right Outer
30919 }
30920 else if ($btype=='UPCA') {
30921 $outerfontsize = 2.3; // Inner fontsize = 3
30922 $outerp = $xres * 10;
30923 $innerp = $xres * 2.5;
30924 $textw = ($bcw*0.5) - $outerp - $innerp;
30925 $chars = 5;
30926 $charLO = substr($code,0,1); // Left Outer
30927 $charLI = substr($code,1,5); // Left Inner
30928 $charRI = substr($code,6,5); // Right Inner
30929 $charRO = substr($code,11,1); // Right Outer
30930 }
30931 else if ($btype=='UPCE') {
30932 $outerfontsize = 2.3; // Inner fontsize = 3
30933 $outerp = $xres * 4;
30934 $innerp = 0;
30935 $textw = ($bcw*0.5) - $outerp - $innerp;
30936 $chars = 3;
30937 $upce_code = $arrcode['code'];
30938 $charLO = substr($code,0,1); // Left Outer
30939 $charLI = substr($upce_code,0,3); // Left Inner
30940 $charRI = substr($upce_code,3,3); // Right Inner
30941 $charRO = substr($code,11,1); // Right Outer
30942 }
30943 else if ($btype=='EAN8') {
30944 $outerfontsize = 3; // Inner fontsize = 3
30945 $outerp = $xres * 4;
30946 $innerp = $xres * 2.5;
30947 $textw = ($bcw*0.5) - $outerp - $innerp;
30948 $chars = 4;
30949 $charLO = '<'; // Left Outer
30950 $charLI = substr($code,0,4); // Left Inner
30951 $charRI = substr($code,4,4); // Right Inner
30952 if (!$supplement) $charRO = '>'; // Right Outer
30953 }
30954
30955 $this->SetFontSize(($outerfontsize/3)*3*$fh*$size*_MPDFK); // 3mm numerals (FontSize is larger to account for space above/below characters)
30956
30957 if (!$this->usingCoreFont) { $cw = $this->_getCharWidth($this->CurrentFont['cw'],32)*3*$fh*$size/1000; } // character width at 3mm
30958 else { $cw = $this->_getCharWidth($this->CurrentFont['cw'],48)*3*$fh*$size/1000; } // 48 == char "0"
30959
30960 // Outer left character
30961 $y_text = $y + $paddingT + $bch - ($num_height/2);
30962 $y_text_outer = $y + $paddingT + $bch - ($num_height*($outerfontsize/3)/2);
30963
30964 $this->x = $x + $paddingL - ($cw*($outerfontsize/3)*0.1); // 0.1 is correction as char does not fill full width;
30965 $this->y = $y_text_outer;
30966 $this->Cell($cw, $num_height, $charLO );
30967
30968 // WORD SPACING for inner chars
30969 $xtra = $textw - ($cw*$chars);
30970 $charspacing = $xtra / ($chars-1);
30971 if ($charspacing) { $this->_out(sprintf('BT %.3F Tc ET',$charspacing*_MPDFK)); }
30972
30973 if ($bgcol) { $this->SetFColor($bgcol); }
30974 else { $this->SetFColor($this->ConvertColor(255)); }
30975
30976 $this->SetFontSize(3*$fh*$size*_MPDFK); // 3mm numerals (FontSize is larger to account for space above/below characters)
30977
30978 // Inner left half characters
30979 $this->x = $x + $paddingL + $llm + $outerp;
30980 $this->y = $y_text;
30981 $this->Cell($textw, $num_height, $charLI , 0, 0, '', 1);
30982
30983 // Inner right half characters
30984 $this->x = $x + $paddingL + $llm + ($bcw*0.5) + $innerp;
30985 $this->y = $y_text;
30986 $this->Cell($textw, $num_height, $charRI , 0, 0, '', 1);
30987
30988 if ($charspacing) { $this->_out('BT 0 Tc ET'); }
30989
30990 // Outer Right character
30991 $this->SetFontSize(($outerfontsize/3)*3*$fh*$size*_MPDFK); // 3mm numerals (FontSize is larger to account for space above/below characters)
30992
30993 $this->x = $x + $paddingL + $llm + $bcw + $rlm - ($cw*($outerfontsize/3)*0.9); // 0.9 is correction as char does not fill full width
30994 $this->y = $y_text_outer;
30995 $this->Cell($cw*($outerfontsize/3), $num_height, $charRO , 0, 0, 'R');
30996
30997 if ($supplement) { // EAN-2 or -5 Supplement
30998 // PRINT BARS
30999 $supparrcode = $this->barcode->getBarcodeArray($supplement_code, 'EAN'.$supplement);
31000 if ($supparrcode === false) { $this->Error('Error in barcode string (supplement): '.$codestr.' '.$supplement_code); }
31001 if(strlen($supplement_code) != $supplement) {
31002 $this->Error('Barcode supplement incorrect: '.$supplement_code);
31003 }
31004 $llm = $fbw - (($arrcode['lightmR'] - $supparrcode['sepM']) * $arrcode['nom-X'] * $size); // Left Light margin
31005 $rlm = $arrcode['lightmR'] * $arrcode['nom-X'] * $size; // Right Light margin
31006
31007 $bcw = ($supparrcode["maxw"] * $xres); // Barcode width = Should always be 31.35mm * $size
31008
31009 $fbw = $bcw + $llm + $rlm; // Full barcode width incl. light margins
31010 $ow = $fbw + $paddingL + $paddingR; // Full overall width incl. user-defined padding
31011 $bch = $fbh - (1.5 * $size) - ($num_height + 0.5); // Barcode height of bars (3mm for numerals)
31012
31013 $xpos = $x + $paddingL + $llm ;
31014 $ypos = $y + $paddingT + $num_height + 0.5;
31015 if ($col) { $this->SetFColor($col); }
31016 else { $this->SetFColor($this->ConvertColor(0)); }
31017 if ($supparrcode !== false) {
31018 foreach ($supparrcode["bcode"] AS $v) {
31019 $bw = ($v["w"] * $xres);
31020 if ($v["t"]) {
31021 // draw a vertical bar
31022 $this->Rect($xpos, $ypos, $bw, $bch, 'F');
31023 }
31024 $xpos += $bw;
31025 }
31026 }
31027
31028 // Characters
31029 if ($bgcol) { $this->SetFColor($bgcol); }
31030 else { $this->SetFColor($this->ConvertColor(255)); }
31031 $this->SetFontSize(3*$fh*$size*_MPDFK); // 3mm numerals (FontSize is larger to account for space above/below characters)
31032 $this->x = $x + $paddingL + $llm;
31033 $this->y = $y + $paddingT;
31034 $this->Cell($bcw, $num_height, $supplement_code, 0, 0, 'C');
31035
31036 // Outer Right character (light margin)
31037 $this->SetFontSize(($outerfontsize/3)*3*$fh*$size*_MPDFK); // 3mm numerals (FontSize is larger to account for space above/below characters)
31038 $this->x = $x + $paddingL + $llm + $bcw + $rlm - ($cw*0.9); // 0.9 is correction as char does not fill full width
31039 $this->y = $y + $paddingT;
31040 $this->Cell($cw*($outerfontsize/3), $num_height, '>', 0, 0, 'R');
31041 }
31042
31043
31044
31045 // Restore **************
31046 $this->SetFont($prevFontFamily, $prevFontStyle, $prevFontSizePt);
31047 $this->DrawColor = $prevDrawColor;
31048 $this->TextColor = $prevTextColor;
31049 $this->FillColor = $prevFillColor;
31050 $this->SetLineWidth($lw);
31051 $this->SetY($y);
31052}
31053
31054
31055
31056// ====================================================
31057// POSTAL and OTHER barcodes
31058function WriteBarcode2($code, $x='', $y='', $size=1, $height=1, $bgcol=false, $col=false, $btype='IMB', $print_ratio='', $k=1) {
31059 if (empty($code)) { return; }
31060 if (!class_exists('PDFBarcode', false)) {
31061 include(_MPDF_PATH.'classes/barcode.php');
31062 }
31063 $this->barcode = new PDFBarcode();
31064 $arrcode = $this->barcode->getBarcodeArray($code, $btype, $print_ratio);
31065
31066 if ($arrcode === false) { $this->Error('Error in barcode string: '.$code); }
31067 if (empty($x)) { $x = $this->x; }
31068 if (empty($y)) { $y = $this->y; }
31069 $prevDrawColor = $this->DrawColor;
31070 $prevTextColor = $this->TextColor;
31071 $prevFillColor = $this->FillColor;
31072 $lw = $this->LineWidth;
31073 $this->SetLineWidth(0.01);
31074 $size /= $k; // in case resized in a table
31075 $xres = $arrcode['nom-X'] * $size;
31076
31077 if ($btype == 'IMB' || $btype == 'RM4SCC' || $btype == 'KIX' || $btype == 'POSTNET' || $btype == 'PLANET') {
31078 $llm = $arrcode['quietL'] / $k; // Left Quiet margin
31079 $rlm = $arrcode['quietR'] / $k; // Right Quiet margin
31080 $tlm = $blm = $arrcode['quietTB'] / $k;
31081 $height=1; // Overrides
31082 }
31083 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'))) {
31084 $llm = $arrcode['lightmL'] * $xres; // Left Quiet margin
31085 $rlm = $arrcode['lightmR'] * $xres; // Right Quiet margin
31086 $tlm = $blm = $arrcode['lightTB'] * $xres * $height;
31087 }
31088
31089
31090 $bcw = ($arrcode["maxw"] * $xres);
31091 $fbw = $bcw + $llm + $rlm; // Full barcode width incl. light margins
31092
31093 $bch = ($arrcode["nom-H"] * $size * $height);
31094 $fbh = $bch + $tlm + $blm; // Full barcode height
31095
31096 // PRINT border background color
31097 $xpos = $x;
31098 $ypos = $y;
31099 if ($col) {
31100 $this->SetDColor($col);
31101 $this->SetTColor($col);
31102 }
31103 else {
31104 $this->SetDColor($this->ConvertColor(0));
31105 $this->SetTColor($this->ConvertColor(0));
31106 }
31107 if ($bgcol) {
31108 $this->SetFColor($bgcol);
31109 }
31110 else { $this->SetFColor($this->ConvertColor(255)); }
31111
31112 // PRINT BARS
31113 if ($col) { $this->SetFColor($col); }
31114 else { $this->SetFColor($this->ConvertColor(0)); }
31115 $xpos = $x + $llm ;
31116
31117 if ($arrcode !== false) {
31118 foreach ($arrcode["bcode"] AS $v) {
31119 $bw = ($v["w"] * $xres);
31120 if ($v["t"]) {
31121 $ypos = $y + $tlm + ($bch * $v['p'] / $arrcode['maxh']);
31122 $this->Rect($xpos, $ypos, $bw, ($v['h'] * $bch / $arrcode['maxh']), 'F');
31123 }
31124 $xpos += $bw;
31125 }
31126 }
31127
31128 // PRINT BEARER BARS
31129 if ($btype == 'I25B' || $btype == 'I25B+') {
31130 $this->Rect($x, $y, $fbw, ($arrcode['lightTB'] * $xres * $height), 'F');
31131 $this->Rect($x, $y+$tlm+$bch, $fbw, ($arrcode['lightTB'] * $xres * $height), 'F');
31132 }
31133
31134 // Restore **************
31135 $this->SetFont($prevFontFamily, $prevFontStyle, $prevFontSizePt);
31136 $this->DrawColor = $prevDrawColor;
31137 $this->TextColor = $prevTextColor;
31138 $this->FillColor = $prevFillColor;
31139 $this->SetLineWidth($lw);
31140 $this->SetY($y);
31141}
31142
31143/*-- END BARCODES --*/
31144
31145// ====================================================
31146// ====================================================
31147
31148function StartTransform($returnstring=false) {
31149 if ($returnstring) { return('q'); }
31150 else { $this->_out('q'); }
31151}
31152function StopTransform($returnstring=false) {
31153 if ($returnstring) { return('Q'); }
31154 else { $this->_out('Q'); }
31155}
31156function transformScale($s_x, $s_y, $x='', $y='', $returnstring=false) {
31157 if ($x === '') {
31158 $x=$this->x;
31159 }
31160 if ($y === '') {
31161 $y=$this->y;
31162 }
31163 if (($s_x == 0) OR ($s_y == 0)) {
31164 $this->Error('Please do not use values equal to zero for scaling');
31165 }
31166 $y = ($this->h - $y) * _MPDFK;
31167 $x *= _MPDFK;
31168 //calculate elements of transformation matrix
31169 $s_x /= 100;
31170 $s_y /= 100;
31171 $tm[0] = $s_x;
31172 $tm[1] = 0;
31173 $tm[2] = 0;
31174 $tm[3] = $s_y;
31175 $tm[4] = $x * (1 - $s_x);
31176 $tm[5] = $y * (1 - $s_y);
31177 //scale the coordinate system
31178 if ($returnstring) { return($this->_transform($tm, true)); }
31179 else { $this->_transform($tm); }
31180}
31181function transformTranslate($t_x, $t_y, $returnstring=false) {
31182 //calculate elements of transformation matrix
31183 $tm[0] = 1;
31184 $tm[1] = 0;
31185 $tm[2] = 0;
31186 $tm[3] = 1;
31187 $tm[4] = $t_x * _MPDFK;
31188 $tm[5] = -$t_y * _MPDFK;
31189 //translate the coordinate system
31190 if ($returnstring) { return($this->_transform($tm, true)); }
31191 else { $this->_transform($tm); }
31192}
31193function transformRotate($angle, $x='', $y='', $returnstring=false) {
31194 if ($x === '') {
31195 $x=$this->x;
31196 }
31197 if ($y === '') {
31198 $y=$this->y;
31199 }
31200 $angle = -$angle;
31201 $y = ($this->h - $y) * _MPDFK;
31202 $x *= _MPDFK;
31203 //calculate elements of transformation matrix
31204 $tm[0] = cos(deg2rad($angle));
31205 $tm[1] = sin(deg2rad($angle));
31206 $tm[2] = -$tm[1];
31207 $tm[3] = $tm[0];
31208 $tm[4] = $x + $tm[1] * $y - $tm[0] * $x;
31209 $tm[5] = $y - $tm[0] * $y - $tm[1] * $x;
31210 //rotate the coordinate system around ($x,$y)
31211 if ($returnstring) { return($this->_transform($tm, true)); }
31212 else { $this->_transform($tm); }
31213}
31214function _transform($tm, $returnstring=false) {
31215 if ($returnstring) { return(sprintf('%.4F %.4F %.4F %.4F %.4F %.4F cm', $tm[0], $tm[1], $tm[2], $tm[3], $tm[4], $tm[5])); }
31216 else { $this->_out(sprintf('%.4F %.4F %.4F %.4F %.4F %.4F cm', $tm[0], $tm[1], $tm[2], $tm[3], $tm[4], $tm[5])); }
31217}
31218
31219
31220
31221/*-- INDIC --*/
31222// INDIC ============================
31223// This conversion can only be done when font is set
31224function ConvertIndic(&$str) {
31225 if (preg_match('/^ind_([a-z]{2})_/',$this->currentfontfamily, $m)) {
31226 if (!class_exists('indic', false)) { include(_MPDF_PATH.'classes/indic.php'); }
31227 if (empty($this->indic)) { $this->indic = new indic($this); }
31228 $earr = $this->UTF8StringToArray($str, false);
31229 $str = $this->indic->substituteIndic($earr, $m[1], $this->currentfontfamily);
31230 }
31231}
31232/*-- END INDIC --*/
31233
31234// AUTOFONT =========================
31235function AutoFont($html) {
31236 if ($this->onlyCoreFonts) { return $html; }
31237 $this->useLang = true;
31238 if ($this->autoFontGroupSize == 1) { $extra = $this->pregASCIIchars1; }
31239 else if ($this->autoFontGroupSize == 3) { $extra = $this->pregASCIIchars3; }
31240 else { $extra = $this->pregASCIIchars2; }
31241 $n = '';
31242 $a=preg_split('/<(.*?)>/ms',$html,-1,PREG_SPLIT_DELIM_CAPTURE);
31243 foreach($a as $i => $e) {
31244 if($i%2==0) {
31245 $e = strcode2utf($e);
31246 $e = $this->lesser_entity_decode($e);
31247
31248 // Use U=FFF0 and U+FFF1 to mark start and end of span tags to prevent nesting occurring
31249 // "\xef\xbf\xb0" ##lthtmltag## "\xef\xbf\xb1" ##gthtmltag##
31250
31251/*-- CJK-FONTS --*/
31252 if ($this->autoFontGroups & AUTOFONT_CJK) {
31253 $e = preg_replace_callback("/([".$this->pregCJKchars .$extra."]*[".$this->pregCJKchars ."][".$this->pregCJKchars .$extra."]*)/u", array($this, 'replaceCJKPregCallback'), $e ); // mPDF 5.7+
31254 }
31255/*-- END CJK-FONTS --*/
31256
31257/*-- RTL --*/
31258 if ($this->autoFontGroups & AUTOFONT_RTL) {
31259 // HEBREW
31260 $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);
31261 // All Arabic
31262 $e = preg_replace_callback("/([".$this->pregARABICchars .$extra."]*[".$this->pregARABICchars ."][".$this->pregARABICchars .$extra."]*)/u", array($this, 'replaceArabicPregCallback'), $e ); // mPDF 5.7+
31263 }
31264/*-- END RTL --*/
31265
31266/*-- INDIC --*/
31267 // INDIC
31268 if ($this->autoFontGroups & AUTOFONT_INDIC) {
31269 // Bengali
31270 $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);
31271 // Devanagari (= script for Hindi, Nepali + Sindhi)
31272 $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);
31273 // Gujarati
31274 $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);
31275 // Malayalam
31276 $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);
31277 // Kannada
31278 $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);
31279 // Oriya
31280 $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);
31281 // Punjabi ?= Gurmuhki
31282 $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);
31283 // Tamil
31284 $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);
31285 // Telugu
31286 $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);
31287 }
31288/*-- END INDIC --*/
31289
31290
31291 if ($this->autoFontGroups & AUTOFONT_THAIVIET) {
31292 // THAI
31293 $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);
31294 // Vietnamese
31295 $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);
31296 }
31297
31298 $e = preg_replace('/[&]/','&amp;',$e);
31299 $e = preg_replace('/[<]/','&lt;',$e);
31300 $e = preg_replace('/[>]/','&gt;',$e);
31301 $e = preg_replace("/(\xef\xbf\xb0span lang=\"([a-z\-A-Z]{2,5})\"\xef\xbf\xb1)\s+/",' \\1',$e);
31302 $e = preg_replace("/[ ]+(\xef\xbf\xb0\/span\xef\xbf\xb1)/",'\\1 ',$e);
31303
31304 $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);
31305
31306 $e = preg_replace("/\xef\xbf\xb0/",'<',$e);
31307 $e = preg_replace("/\xef\xbf\xb1/",'>',$e);
31308
31309 $a[$i] = $e;
31310 }
31311 else {
31312 $a[$i] = '<'.$e.'>';
31313 }
31314 }
31315 $n = implode('',$a);
31316 return $n;
31317}
31318
31319
31320/*-- CJK-FONTS --*/
31321function replaceCJK($str) {
31322 // Use U=FFF0 and U+FFF1 to mark start and end of span tags to prevent nesting occurring
31323 // "\xef\xbf\xb0" ##lthtmltag## "\xef\xbf\xb1" ##gthtmltag##
31324 if (preg_match("/[".$this->pregUHCchars."]/u", $str)) {
31325 return "\xef\xbf\xb0span lang=\"ko\"\xef\xbf\xb1" . $str ."\xef\xbf\xb0/span\xef\xbf\xb1";
31326 }
31327 else if (preg_match("/[".$this->pregSJISchars."]/u", $str)) {
31328 return "\xef\xbf\xb0span lang=\"ja\"\xef\xbf\xb1" . $str ."\xef\xbf\xb0/span\xef\xbf\xb1";
31329 }
31330 // if in Unicode Plane 2, probably HKCS (incl in BIG5) if not Japanese
31331 else if (preg_match("/[\x{20000}-\x{2FFFF}]/u", $str)) {
31332 return "\xef\xbf\xb0span lang=\"zh-HK\"\xef\xbf\xb1" . $str ."\xef\xbf\xb0/span\xef\xbf\xb1";
31333 }
31334 else{
31335 return "\xef\xbf\xb0span lang=\"zh-CN\"\xef\xbf\xb1" . $str ."\xef\xbf\xb0/span\xef\xbf\xb1";
31336 }
31337 return $str;
31338}
31339
31340// mPDF 5.7+
31341function replaceCJKPregCallback($matches) {
31342 return $this->replaceCJK(stripslashes($matches[1]));
31343}
31344/*-- END CJK-FONTS --*/
31345
31346/*-- RTL --*/
31347function replaceArabic($str) {
31348 // PASHTO, SINDHI, URDU, ARABIC, PERSIAN
31349 $persian = "\x{067E}\x{0686}\x{0698}\x{06AF}";
31350
31351 $urdu = "\x{0679}\x{0688}\x{0691}\x{06BA}\x{06BE}\x{06C1}\x{06D2}";
31352 $pashto = "\x{067C}\x{0681}\x{0685}\x{0689}\x{0693}\x{0696}\x{069A}\x{06BC}\x{06D0}"; // ? and U+06AB, U+06CD
31353 $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}";
31354 // Use U=FFF0 and U+FFF1 to mark start and end of span tags to prevent nesting occurring
31355 // "\xef\xbf\xb0" ##lthtmltag## "\xef\xbf\xb1" ##gthtmltag##
31356
31357 if (preg_match("/[".$this->pregNonARABICchars ."]/u", $str) ) {
31358 if (preg_match("/[".$sindhi ."]/u", $str) ) {
31359 return "\xef\xbf\xb0span lang=\"sd\"\xef\xbf\xb1".$str."\xef\xbf\xb0/span\xef\xbf\xb1";
31360 }
31361 else if (preg_match("/[".$urdu ."]/u", $str) ) {
31362 return "\xef\xbf\xb0span lang=\"ur\"\xef\xbf\xb1".$str."\xef\xbf\xb0/span\xef\xbf\xb1";
31363 }
31364 else if (preg_match("/[".$pashto ."]/u", $str) ) {
31365 return "\xef\xbf\xb0span lang=\"ps\"\xef\xbf\xb1".$str."\xef\xbf\xb0/span\xef\xbf\xb1";
31366 }
31367 else if (preg_match("/[".$persian ."]/u", $str) ) {
31368 return "\xef\xbf\xb0span lang=\"fa\"\xef\xbf\xb1".$str."\xef\xbf\xb0/span\xef\xbf\xb1";
31369 }
31370 else {
31371 return "\xef\xbf\xb0span lang=\"ar\"\xef\xbf\xb1".$str."\xef\xbf\xb0/span\xef\xbf\xb1";
31372 }
31373 }
31374 if (preg_match("/[".$persian ."]/u", $str) ) {
31375 return "\xef\xbf\xb0span lang=\"fa\"\xef\xbf\xb1".$str."\xef\xbf\xb0/span\xef\xbf\xb1";
31376 }
31377 else {
31378 return "\xef\xbf\xb0span lang=\"ar\"\xef\xbf\xb1".$str."\xef\xbf\xb0/span\xef\xbf\xb1";
31379 }
31380 return $str;
31381}
31382
31383// mPDF 5.7+
31384function replaceArabicPregCallback($matches) {
31385 return $this->replaceArabic(stripslashes($matches[1]));
31386}
31387
31388// ARABIC ===========================
31389// mPDF 5.4.08
31390function InitArabic() {
31391
31392 // JOIN TO FOLLOWING LETTER IN LOGICAL ORDER (i.e. AS INITIAL)
31393 $this->arabPrevLink = "";
31394 // U+060c; U+061b; U+061f; U+0626; U+0628;
31395 $this->arabPrevLink .= "\xd8\x8c\xd8\x9b\xd8\x9f\xd8\xa6\xd8\xa8";
31396 // U+062a; U+062b; U+062c; U+062d; U+062e;
31397 $this->arabPrevLink .= "\xd8\xaa\xd8\xab\xd8\xac\xd8\xad\xd8\xae";
31398 // U+0633; U+0634; U+0635; U+0636; U+0637; U+0638; U+0639; U+063a;
31399 $this->arabPrevLink .= "\xd8\xb3\xd8\xb4\xd8\xb5\xd8\xb6\xd8\xb7\xd8\xb8\xd8\xb9\xd8\xba";
31400 // U+0640; U+0641; U+0642; U+0643; U+0644; U+0645; U+0646; U+0647; U+0649; U+064a;
31401 $this->arabPrevLink .= "\xd9\x80\xd9\x81\xd9\x82\xd9\x83\xd9\x84\xd9\x85\xd9\x86\xd9\x87\xd9\x89\xd9\x8a";
31402 // U+0678; U+0679; U+067a; U+067b; U+067c; U+067d; U+067e; U+067f;
31403 $this->arabPrevLink .= "\xd9\xb8\xd9\xb9\xd9\xba\xd9\xbb\xd9\xbc\xd9\xbd\xd9\xbe\xd9\xbf";
31404 // U+0680; U+0681; U+0682; U+0683; U+0684; U+0685; U+0686; U+0687;
31405 $this->arabPrevLink .= "\xda\x80\xda\x81\xda\x82\xda\x83\xda\x84\xda\x85\xda\x86\xda\x87";
31406 // U+069a; U+069b; U+069c; U+069d; U+069e; U+069f;
31407 $this->arabPrevLink .= "\xda\x9a\xda\x9b\xda\x9c\xda\x9d\xda\x9e\xda\x9f";
31408 // U+06a0; U+06a1; U+06a2; U+06a3; U+06a4; U+06a5; U+06a6; U+06A7; U+06A8;
31409 $this->arabPrevLink .= "\xda\xa0\xda\xa1\xda\xa2\xda\xa3\xda\xa4\xda\xa5\xda\xa6\xda\xa7\xda\xa8";
31410 // U+06a9; U+06aa; U+06ab; U+06ac; U+06ad; U+06ae; U+06af;
31411 $this->arabPrevLink .= "\xda\xa9\xda\xaa\xda\xab\xda\xac\xda\xad\xda\xae\xda\xaf";
31412 // U+06b0; U+06b1; U+06b2; U+06b3; U+06b4; U+06b5; U+06b6; U+06b7; U+06b8; U+06b9;
31413 $this->arabPrevLink .= "\xda\xb0\xda\xb1\xda\xb2\xda\xb3\xda\xb4\xda\xb5\xda\xb6\xda\xb7\xda\xb8\xda\xb9";
31414 // U+06ba; U+06bb; U+06bc; U+06be; U+06bf;
31415 $this->arabPrevLink .= "\xda\xba\xda\xbb\xda\xbc\xda\xbe\xda\xbf";
31416 // U+06c1; U+06cc; U+06ce; U+06d0; U+06d1;
31417 $this->arabPrevLink .= "\xdb\x81\xdb\x8c\xdb\x8e\xdb\x90\xdb\x91";
31418
31419
31420
31421
31422 // JOIN TO PREVIOUS LETTER IN LOGICAL ORDER (i.e. AS FINAL FORM)
31423 $this->arabNextLink = "";
31424 // U+0622; U+0623; U+0624; U+0625; U+0626; U+0627; U+0628; U+0629;
31425 $this->arabNextLink .= "\xd8\xa2\xd8\xa3\xd8\xa4\xd8\xa5\xd8\xa6\xd8\xa7\xd8\xa8\xd8\xa9";
31426 // U+062A; U+062B; U+062C; U+062D; U+062E; U+062F;
31427 $this->arabNextLink .= "\xd8\xaa\xd8\xab\xd8\xac\xd8\xad\xd8\xae\xd8\xaf";
31428 // U+0630; U+0631; U+0632; U+0633; U+0634; U+0635; U+0636; U+0637; U+0638; U+0639; U+063A;
31429 $this->arabNextLink .= "\xd8\xb0\xd8\xb1\xd8\xb2\xd8\xb3\xd8\xb4\xd8\xb5\xd8\xb6\xd8\xb7\xd8\xb8\xd8\xb9\xd8\xba";
31430 // U+0640; U+0641; U+0642; U+0643; U+0644; U+0645; U+0646; U+0647; U+0648; U+0649; U+064A;
31431 $this->arabNextLink .= "\xd9\x80\xd9\x81\xd9\x82\xd9\x83\xd9\x84\xd9\x85\xd9\x86\xd9\x87\xd9\x88\xd9\x89\xd9\x8a";
31432 // U+0671; U+0672; U+0675; U+0676; U+0677; U+0678; U+0679;
31433 $this->arabNextLink .= "\xd9\xb1\xd9\xb2\xd9\xb5\xd9\xb6\xd9\xb7\xd9\xb8\xd9\xb9";
31434 // U+067A; U+067B; U+067C; U+067D; U+067E; U+067F;
31435 $this->arabNextLink .= "\xd9\xba\xd9\xbb\xd9\xbc\xd9\xbd\xd9\xbe\xd9\xbf";
31436 // U+0680; U+0681; U+0682; U+0683; U+0684; U+0685; U+0686; U+0687; U+0688; U+0689;
31437 $this->arabNextLink .= "\xda\x80\xda\x81\xda\x82\xda\x83\xda\x84\xda\x85\xda\x86\xda\x87\xda\x88\xda\x89";
31438 // U+068A; U+068B; U+068C; U+068D; U+068F;U+068F;
31439 $this->arabNextLink .= "\xda\x8a\xda\x8b\xda\x8c\xda\x8d\xda\x8e\xda\x8f";
31440 // U+0690; U+0691; U+0692; U+0693; U+0694; U+0695; U+0696; U+0697; U+0698; U+0699;
31441 $this->arabNextLink .= "\xda\x90\xda\x91\xda\x92\xda\x93\xda\x94\xda\x95\xda\x96\xda\x97\xda\x98\xda\x99";
31442 // U+069A; U+069B; U+069C; U+069D; U+069E; U+069F;
31443 $this->arabNextLink .= "\xda\x9a\xda\x9b\xda\x9c\xda\x9d\xda\x9e\xda\x9f";
31444 // U+06A0; U+06A1; U+06A2; U+06A3; U+06A4; U+06A5; U+06A6; U+06A7; U+06A8; U+06A9;
31445 $this->arabNextLink .= "\xda\xa0\xda\xa1\xda\xa2\xda\xa3\xda\xa4\xda\xa5\xda\xa6\xda\xa7\xda\xa8\xda\xa9";
31446 // U+06AA; U+06AB; U+06AC; U+06AD; U+06AE; U+06AF;
31447 $this->arabNextLink .= "\xda\xaa\xda\xab\xda\xac\xda\xad\xda\xae\xda\xaf";
31448 // U+06B0; U+06B1; U+06B2; U+06B3; U+06B4; U+06B5; U+06B6; U+06B7; U+06B8; U+06B9;
31449 $this->arabNextLink .= "\xda\xb0\xda\xb1\xda\xb2\xda\xb3\xda\xb4\xda\xb5\xda\xb6\xda\xb7\xda\xb8\xda\xb9";
31450 // U+06BA; U+06BB; U+06BC; U+06BE; U+06BF;
31451 $this->arabNextLink .= "\xda\xba\xda\xbb\xda\xbc\xda\xbe\xda\xbf";
31452 // U+06C0; U+06C1; U+06C2; U+06C3; U+06C4; U+06C5; U+06C6; U+06C7; U+06C8; U+06C9;
31453 $this->arabNextLink .= "\xdb\x80\xdb\x81\xdb\x82\xdb\x83\xdb\x84\xdb\x85\xdb\x86\xdb\x87\xdb\x88\xdb\x89";
31454 // U+06CA; U+06CB; U+06CC; U+06CD; U+06CE; U+06CF;
31455 $this->arabNextLink .= "\xdb\x8a\xdb\x8b\xdb\x8c\xdb\x8d\xdb\x8e\xdb\x8f";
31456 // U+06D0; U+06d1; U+06D2; U+06D3;
31457 $this->arabNextLink .= "\xdb\x90\xdb\x91\xdb\x92\xdb\x93";
31458
31459
31460 // VOWELS ++
31461
31462 // U+064b U+064c; U+064d; U+064e; U+064f; U+0650; U+0651; U+0652;
31463 $this->arabVowels = "\xd9\x8b\xd9\x8c\xd9\x8d\xd9\x8e\xd9\x8f\xd9\x90\xd9\x91\xd9\x92";
31464
31465 // Added chars that may not be vowels but should not interrupt joining
31466 // U+0670; U+0653;
31467 $this->arabVowels .= "\xd9\xb0\xd9\x93";
31468 // ? should also add - U+615, 616, 617-61A, 653-65E, 6D6-6DC, 6DF-6E4, 6E7, 6E8, 6EA-6ED
31469
31470
31471
31472 // ISOLATED FORM :: FINAL :: INITIAL :: MEDIAL
31473 // FB** - FE** = Arabic presentation Forms
31474 // F5** F6** F7** = Private use area used by unAGlyphs in mPDF
31475 $this->arabGlyphs = array(
31476 "\xd8\x8c"=>array("\xd8\x8c", "\xd8\x8c", "\xd8\x8c", "\xd8\x8c"), /* 060C, 060C, 060C, 060C */
31477 "\xd8\x9b"=>array("\xd8\x9b", "\xd8\x9b", "\xd8\x9b", "\xd8\x9b"), /* 061B, 061B, 061B, 061B */
31478 "\xd8\x9f"=>array("\xd8\x9f", "\xd8\x9f", "\xd8\x9f", "\xd8\x9f"), /* 061F, 061F, 061F, 061F */
31479 "\xd8\xa1"=>array("\xd8\xa1", "\xd8\xa1", "\xd8\xa1", "\xd8\xa1"), /* 0621, 0621, 0621, 0621 */
31480 "\xd8\xa2"=>array("\xd8\xa2", "\xef\xba\x82", "\xd8\xa2", "\xef\xba\x82"), /* 0622, FE82, 0622, FE82 */
31481 "\xd8\xa3"=>array("\xd8\xa3", "\xef\xba\x84", "\xd8\xa3", "\xef\xba\x84"), /* 0623, FE84, 0623, FE84 */
31482 "\xd8\xa4"=>array("\xd8\xa4", "\xef\xba\x86", "\xd8\xa4", "\xef\xba\x86"), /* 0624, FE86, 0624, FE86 */
31483 "\xd8\xa5"=>array("\xd8\xa5", "\xef\xba\x88", "\xd8\xa5", "\xef\xba\x88"), /* 0625, FE88, 0625, FE88 */
31484 "\xd8\xa6"=>array("\xd8\xa6", "\xef\xba\x8a", "\xef\xba\x8b", "\xef\xba\x8c"), /* 0626, FE8A, FE8B, FE8C */
31485 "\xd8\xa7"=>array("\xd8\xa7", "\xef\xba\x8e", "\xd8\xa7", "\xef\xba\x8e"), /* 0627, FE8E, 0627, FE8E */
31486 "\xd8\xa8"=>array("\xd8\xa8", "\xef\xba\x90", "\xef\xba\x91", "\xef\xba\x92"), /* 0628, FE90, FE91, FE92 */
31487 "\xd8\xa9"=>array("\xd8\xa9", "\xef\xba\x94", "\xd8\xa9", "\xef\xba\x94"), /* 0629, FE94, 0629, FE94 */
31488 "\xd8\xaa"=>array("\xd8\xaa", "\xef\xba\x96", "\xef\xba\x97", "\xef\xba\x98"), /* 062A, FE96, FE97, FE98 */
31489 "\xd8\xab"=>array("\xd8\xab", "\xef\xba\x9a", "\xef\xba\x9b", "\xef\xba\x9c"), /* 062B, FE9A, FE9B, FE9C */
31490 "\xd8\xac"=>array("\xd8\xac", "\xef\xba\x9e", "\xef\xba\x9f", "\xef\xba\xa0"), /* 062C, FE9E, FE9F, FEA0 */
31491 "\xd8\xad"=>array("\xd8\xad", "\xef\xba\xa2", "\xef\xba\xa3", "\xef\xba\xa4"), /* 062D, FEA2, FEA3, FEA4 */
31492 "\xd8\xae"=>array("\xd8\xae", "\xef\xba\xa6", "\xef\xba\xa7", "\xef\xba\xa8"), /* 062E, FEA6, FEA7, FEA8 */
31493 "\xd8\xaf"=>array("\xd8\xaf", "\xef\xba\xaa", "\xd8\xaf", "\xef\xba\xaa"), /* 062F, FEAA, 062F, FEAA */
31494 "\xd8\xb0"=>array("\xd8\xb0", "\xef\xba\xac", "\xd8\xb0", "\xef\xba\xac"), /* 0630, FEAC, 0630, FEAC */
31495 "\xd8\xb1"=>array("\xd8\xb1", "\xef\xba\xae", "\xd8\xb1", "\xef\xba\xae"), /* 0631, FEAE, 0631, FEAE */
31496 "\xd8\xb2"=>array("\xd8\xb2", "\xef\xba\xb0", "\xd8\xb2", "\xef\xba\xb0"), /* 0632, FEB0, 0632, FEB0 */
31497 "\xd8\xb3"=>array("\xd8\xb3", "\xef\xba\xb2", "\xef\xba\xb3", "\xef\xba\xb4"), /* 0633, FEB2, FEB3, FEB4 */
31498 "\xd8\xb4"=>array("\xd8\xb4", "\xef\xba\xb6", "\xef\xba\xb7", "\xef\xba\xb8"), /* 0634, FEB6, FEB7, FEB8 */
31499 "\xd8\xb5"=>array("\xd8\xb5", "\xef\xba\xba", "\xef\xba\xbb", "\xef\xba\xbc"), /* 0635, FEBA, FEBB, FEBC */
31500 "\xd8\xb6"=>array("\xd8\xb6", "\xef\xba\xbe", "\xef\xba\xbf", "\xef\xbb\x80"), /* 0636, FEBE, FEBF, FEC0 */
31501 "\xd8\xb7"=>array("\xd8\xb7", "\xef\xbb\x82", "\xef\xbb\x83", "\xef\xbb\x84"), /* 0637, FEC2, FEC3, FEC4 */
31502 "\xd8\xb8"=>array("\xd8\xb8", "\xef\xbb\x86", "\xef\xbb\x87", "\xef\xbb\x88"), /* 0638, FEC6, FEC7, FEC8 */
31503 "\xd8\xb9"=>array("\xd8\xb9", "\xef\xbb\x8a", "\xef\xbb\x8b", "\xef\xbb\x8c"), /* 0639, FECA, FECB, FECC */
31504 "\xd8\xba"=>array("\xd8\xba", "\xef\xbb\x8e", "\xef\xbb\x8f", "\xef\xbb\x90"), /* 063A, FECE, FECF, FED0 */
31505 "\xd9\x80"=>array("\xd9\x80", "\xd9\x80", "\xd9\x80", "\xd9\x80"), /* 0640, 0640, 0640, 0640 */
31506 "\xd9\x81"=>array("\xd9\x81", "\xef\xbb\x92", "\xef\xbb\x93", "\xef\xbb\x94"), /* 0641, FED2, FED3, FED4 */
31507 "\xd9\x82"=>array("\xd9\x82", "\xef\xbb\x96", "\xef\xbb\x97", "\xef\xbb\x98"), /* 0642, FED6, FED7, FED8 */
31508 "\xd9\x83"=>array("\xd9\x83", "\xef\xbb\x9a", "\xef\xbb\x9b", "\xef\xbb\x9c"), /* 0643, FEDA, FEDB, FEDC */
31509 "\xd9\x84"=>array("\xd9\x84", "\xef\xbb\x9e", "\xef\xbb\x9f", "\xef\xbb\xa0"), /* 0644, FEDE, FEDF, FEE0 */
31510 "\xd9\x85"=>array("\xd9\x85", "\xef\xbb\xa2", "\xef\xbb\xa3", "\xef\xbb\xa4"), /* 0645, FEE2, FEE3, FEE4 */
31511 "\xd9\x86"=>array("\xd9\x86", "\xef\xbb\xa6", "\xef\xbb\xa7", "\xef\xbb\xa8"), /* 0646, FEE6, FEE7, FEE8 */
31512 "\xd9\x87"=>array("\xd9\x87", "\xef\xbb\xaa", "\xef\xbb\xab", "\xef\xbb\xac"), /* 0647, FEEA, FEEB, FEEC */
31513 "\xd9\x88"=>array("\xd9\x88", "\xef\xbb\xae", "\xd9\x88", "\xef\xbb\xae"), /* 0648, FEEE, 0648, FEEE */
31514
31515/* 0649 Alef Maksura should only appear at end of word (in Arabic) So Initial and medial are shown as isolated/final */
31516 "\xd9\x89"=>array("\xd9\x89", "\xef\xbb\xb0", "\xd9\x89", "\xef\xbb\xb0"), /* 0649, FEF0, 0649, FEF0 */
31517
31518/* 0649 Alef Maksura Initial and Medial forms as given in Unicode FBE8 and FBE9 for Uighur Kazakh (not in some fonts) */
31519 "\xd9\x89"=>array("\xd9\x89", "\xef\xbb\xb0", "\xef\xaf\xa8", "\xef\xaf\xa9"), /* 0649, FEF0, FBE8, FBE9 not in most fonts */
31520
31521 "\xd9\x8a"=>array("\xd9\x8a", "\xef\xbb\xb2", "\xef\xbb\xb3", "\xef\xbb\xb4"), /* 064A, FEF2, FEF3, FEF4 */
31522 "\xd9\x8b"=>array("\xd9\x8b", "\xd9\x8b", "\xd9\x8b", "\xd9\x8b"), /* 064B, 064B, 064B, 064B */
31523 "\xd9\x8c"=>array("\xd9\x8c", "\xd9\x8c", "\xd9\x8c", "\xd9\x8c"), /* 064C, 064C, 064C, 064C */
31524 "\xd9\x8d"=>array("\xd9\x8d", "\xd9\x8d", "\xd9\x8d", "\xd9\x8d"), /* 064D, 064D, 064D, 064D */
31525 "\xd9\x8e"=>array("\xd9\x8e", "\xd9\x8e", "\xd9\x8e", "\xd9\x8e"), /* 064E, 064E, 064E, 064E */
31526 "\xd9\x8f"=>array("\xd9\x8f", "\xd9\x8f", "\xd9\x8f", "\xd9\x8f"), /* 064F, 064F, 064F, 064F */
31527 "\xd9\x90"=>array("\xd9\x90", "\xd9\x90", "\xd9\x90", "\xd9\x90"), /* 0650, 0650, 0650, 0650 */
31528 "\xd9\x91"=>array("\xd9\x91", "\xd9\x91", "\xd9\x91", "\xd9\x91"), /* 0651, 0651, 0651, 0651 */
31529 "\xd9\x92"=>array("\xd9\x92", "\xd9\x92", "\xd9\x92", "\xd9\x92"), /* 0652, 0652, 0652, 0652 */
31530 "\xd9\xb1"=>array("\xd9\xb1", "\xef\xad\x91", "\xd9\xb1", "\xef\xad\x91"), /* 0671, FB51, 0671, FB51 */
31531 "\xd9\xb2"=>array("\xd9\xb2", "\xef\x95\xb2", "\xd9\xb2", "\xef\x95\xb2"), /* 0672, F572, 0672, F572 */
31532 "\xd9\xb5"=>array("\xd9\xb5", "\xef\x95\xb5", "\xd9\xb5", "\xef\x95\xb5"), /* 0675, F575, 0675, F575 */
31533 "\xd9\xb8"=>array("\xd9\xb8", "\xef\x95\xb8", "\xef\xba\x8b", "\xef\xba\x8c"), /* 0678, F578, FE8B, FE8C ( as 0626 ) */
31534 "\xd9\xb9"=>array("\xd9\xb9", "\xef\xad\xa7", "\xef\xad\xa8", "\xef\xad\xa9"), /* 0679, FB67, FB68, FB69 */
31535 "\xd9\xba"=>array("\xd9\xba", "\xef\xad\x9f", "\xef\xad\xa0", "\xef\xad\xa1"), /* 067A, FB5F, FB60, FB61 */
31536 "\xd9\xbb"=>array("\xd9\xbb", "\xef\xad\x93", "\xef\xad\x94", "\xef\xad\x95"), /* 067B, FB53, FB54, FB55 */
31537 "\xd9\xbc"=>array("\xd9\xbc", "\xef\x95\xbc", "\xef\x99\xbc", "\xef\x9d\xbc"), /* 067C, F57C, F67C, F77C */
31538 "\xd9\xbd"=>array("\xd9\xbd", "\xef\x95\xbd", "\xef\x99\xbd", "\xef\x9d\xbd"), /* 067D, F57D, F67D, F77D */
31539 "\xd9\xbe"=>array("\xd9\xbe", "\xef\xad\x97", "\xef\xad\x98", "\xef\xad\x99"), /* 067E, FB57, FB58, FB59 */
31540 "\xd9\xbf"=>array("\xd9\xbf", "\xef\xad\xa3", "\xef\xad\xa4", "\xef\xad\xa5"), /* 067F, FB63, FB64, FB65 */
31541 "\xda\x80"=>array("\xda\x80", "\xef\xad\x9b", "\xef\xad\x9c", "\xef\xad\x9d"), /* 0680, FB5B, FB5C, FB5D */
31542 "\xda\x81"=>array("\xda\x81", "\xef\x96\x81", "\xef\x9a\x81", "\xef\x9e\x81"), /* 0681, F581, F681, F781 */
31543 "\xda\x82"=>array("\xda\x82", "\xef\x96\x82", "\xef\x9a\x82", "\xef\x9e\x82"), /* 0682, F582, F682, F782 */
31544 "\xda\x83"=>array("\xda\x83", "\xef\xad\xb7", "\xef\xad\xb8", "\xef\xad\xb9"), /* 0683, FB77, FB78, FB79 */
31545 "\xda\x84"=>array("\xda\x84", "\xef\xad\xb3", "\xef\xad\xb4", "\xef\xad\xb5"), /* 0684, FB73, FB74, FB75 */
31546 "\xda\x85"=>array("\xda\x85", "\xef\x96\x85", "\xef\x9a\x85", "\xef\x9e\x85"), /* 0685, F585, F685, F785 */
31547 "\xda\x86"=>array("\xda\x86", "\xef\xad\xbb", "\xef\xad\xbc", "\xef\xad\xbd"), /* 0686, FB7B, FB7C, FB7D */
31548 "\xda\x87"=>array("\xda\x87", "\xef\xad\xbf", "\xef\xae\x80", "\xef\xae\x81"), /* 0687, FB7F, FB80, FB81 */
31549 "\xda\x88"=>array("\xda\x88", "\xef\xae\x89", "\xda\x88", "\xda\x88"), /* 0688, FB89, 0688, 0688 */
31550 "\xda\x89"=>array("\xda\x89", "\xef\x96\x89", "\xda\x89", "\xda\x89"), /* 0689, F589, 0689, 0689 */
31551 "\xda\x91"=>array("\xda\x91", "\xef\xae\x8d", "\xda\x91", "\xef\xae\x8d"), /* 0691, FB8D, 0691, FB8D */
31552 "\xda\x93"=>array("\xda\x93", "\xef\x96\x93", "\xda\x93", "\xda\x93"), /* 0693, F593, 0693, 0693 */
31553 "\xda\x96"=>array("\xda\x96", "\xef\x96\x96", "\xda\x96", "\xda\x96"), /* 0696, F596, 0696, 0696 */
31554 "\xda\x98"=>array("\xda\x98", "\xef\xae\x8b", "\xda\x98", "\xef\xae\x8b"), /* 0698, FB8B, 0698, FB8B */
31555 "\xda\x9a"=>array("\xda\x9a", "\xef\x96\x9a", "\xef\x9a\x9a", "\xef\x9e\x9a"), /* 069A, F59A, F69A, F79A */
31556 "\xda\x9b"=>array("\xda\x9b", "\xef\x96\x9b", "\xef\x9a\x9b", "\xef\x9e\x9b"), /* 069B, F59B, F69B, F79B */
31557 "\xda\x9c"=>array("\xda\x9c", "\xef\x96\x9c", "\xef\x9a\x9c", "\xef\x9e\x9c"), /* 069C, F59C, F69C, F79C */
31558 "\xda\x9d"=>array("\xda\x9d", "\xef\x96\x9d", "\xef\x9a\x9d", "\xef\x9e\x9d"), /* 069D, F59D, F69D, F79D */
31559 "\xda\x9e"=>array("\xda\x9e", "\xef\x96\x9e", "\xef\x9a\x9e", "\xef\x9e\x9e"), /* 069E, F59E, F69E, F79E */
31560 "\xda\xa0"=>array("\xda\xa0", "\xef\x96\xa0", "\xef\x9a\xa0", "\xef\x9e\xa0"), /* 06A0, F5A0, F6A0, F7A0 */
31561 "\xda\xa1"=>array("\xda\xa1", "\xef\x96\xa1", "\xef\x9a\xa1", "\xef\x9e\xa1"), /* 06A1, F5A1, F6A1, F7A1 */
31562 "\xda\xa2"=>array("\xda\xa2", "\xef\x96\xa2", "\xef\x9a\xa2", "\xef\x9e\xa2"), /* 06A2, F5A2, F6A2, F7A2 */
31563 "\xda\xa3"=>array("\xda\xa3", "\xef\x96\xa3", "\xef\x9a\xa3", "\xef\x9e\xa3"), /* 06A3, F5A3, F6A3, F7A3 */
31564 "\xda\xa4"=>array("\xda\xa4", "\xef\xad\xab", "\xef\xad\xac", "\xef\xad\xad"), /* 06A4, FB6B, FB6C, FB6D */
31565 "\xda\xa5"=>array("\xda\xa5", "\xef\x96\xa5", "\xef\x9a\xa5", "\xef\x9e\xa5"), /* 06A5, F5A5, F6A5, F7A5 */
31566 "\xda\xa6"=>array("\xda\xa6", "\xef\xad\xaf", "\xef\xad\xb0", "\xef\xad\xb1"), /* 06A6, FB6F, FB70, FB71 */
31567 "\xda\xa9"=>array("\xda\xa9", "\xef\xae\x8f", "\xef\xae\x90", "\xef\xae\x91"), /* 06A9, FB8F, FB90, FB91 */
31568 "\xda\xaa"=>array("\xda\xaa", "\xef\x96\xaa", "\xef\x9a\xaa", "\xef\x9e\xaa"), /* 06AA, F5AA, F6AA, F7AA */
31569 "\xda\xab"=>array("\xda\xab", "\xef\x96\xab", "\xef\x9a\xab", "\xef\x9e\xab"), /* 06AB, F5AB, F6AB, F7AB */
31570 "\xda\xac"=>array("\xda\xac", "\xef\x96\xac", "\xef\x9a\xac", "\xef\x9e\xac"), /* 06AC, F5AC, F6AC, F7AC */
31571 "\xda\xad"=>array("\xda\xad", "\xef\xaf\x94", "\xef\xaf\x95", "\xef\xaf\x96"), /* 06AD, FBD4, FBD5, FBD6 */
31572 "\xda\xae"=>array("\xda\xae", "\xef\x96\xae", "\xef\x9a\xae", "\xef\x9e\xae"), /* 06AE, F5AE, F6AE, F7AE */
31573 "\xda\xaf"=>array("\xda\xaf", "\xef\xae\x93", "\xef\xae\x94", "\xef\xae\x95"), /* 06Af, FB93, FB94, FB95 */
31574 "\xda\xb0"=>array("\xda\xb0", "\xef\x96\xb0", "\xef\x9a\xb0", "\xef\x9e\xb0"), /* 06B0, F5B0, F6B0, F7B0 */
31575 "\xda\xb1"=>array("\xda\xb1", "\xef\xae\x9b", "\xef\xae\x9c", "\xef\xae\x9d"), /* 06B1, FB9B, FB9C, FB9D */
31576 "\xda\xb2"=>array("\xda\xb2", "\xef\x96\xb2", "\xef\x9a\xb2", "\xef\x9e\xb2"), /* 06B2, F5B2, F6B2, F7B2 */
31577 "\xda\xb3"=>array("\xda\xb3", "\xef\xae\x97", "\xef\xae\x98", "\xef\xae\x99"), /* 06B3, FB97, FB98, FB99 */
31578 "\xda\xb4"=>array("\xda\xb4", "\xef\x96\xb4", "\xef\x9a\xb4", "\xef\x9e\xb4"), /* 06B4, F5B4, F6B4, F7B4 */
31579 "\xda\xb5"=>array("\xda\xb5", "\xef\x96\xb5", "\xef\x9a\xb5", "\xef\x9e\xb5"), /* 06B5, F5B5, F6B5, F7B5 */
31580 "\xda\xb6"=>array("\xda\xb6", "\xef\x96\xb6", "\xef\x9a\xb6", "\xef\x9e\xb6"), /* 06B6, F5B6, F6B6, F7B6 */
31581 "\xda\xb7"=>array("\xda\xb7", "\xef\x96\xb7", "\xef\x9a\xb7", "\xef\x9e\xb7"), /* 06B7, F5B7, F6B7, F7B7 */
31582 "\xda\xb8"=>array("\xda\xb8", "\xef\x96\xb8", "\xef\x9a\xb8", "\xef\x9e\xb8"), /* 06B8, F5B8, F6B8, F7B8 */
31583 "\xda\xb9"=>array("\xda\xb9", "\xef\x96\xb9", "\xef\x9a\xb9", "\xef\x9e\xb9"), /* 06B9, F5B9, F6B9, F7B9 */
31584 "\xda\xba"=>array("\xda\xba", "\xef\xae\x9f", "\xda\xba", "\xda\xba"), /* 06BA, FB9F, 06BA, 06BA */
31585 "\xda\xbb"=>array("\xda\xbb", "\xef\xae\xa1", "\xef\xae\xa2", "\xef\xae\xa3"), /* 06BB, FBA1, FBA2, FBA3 */
31586 "\xda\xbc"=>array("\xda\xbc", "\xef\x96\xbc", "\xef\x9a\xbc", "\xef\x9e\xbc"), /* 06BC, F5BC, F6BC, F7BC */
31587 "\xda\xbe"=>array("\xda\xbe", "\xef\xae\xab", "\xef\xae\xac", "\xef\xae\xad"), /* 06BE, FBAB, FBAC, FBAD */
31588 "\xda\xbf"=>array("\xda\xbf", "\xef\x96\xbf", "\xef\x9a\xbf", "\xef\x9e\xbf"), /* 06BF, F5BF, F6BF, F7BF */
31589 "\xdb\x80"=>array("\xdb\x80", "\xef\xae\xa5", "\xdb\x80", "\xef\xae\xa5"), /* 06C0, FBA5, 06C0, FBA5 */
31590 "\xdb\x81"=>array("\xdb\x81", "\xef\xae\xa7", "\xef\xae\xa8", "\xef\xae\xa9"), /* 06C1, FBA7, FBA8, FBA9 */
31591 "\xdb\x8c"=>array("\xdb\x8c", "\xef\xaf\xbd", "\xef\xaf\xbe", "\xef\xaf\xbf"), /* 06CC, FBFD, FBFE, FBFF */
31592 "\xdb\x8d"=>array("\xdb\x8d", "\xef\x97\x8d", "\xdb\x8d", "\xef\x97\x8d"), /* 06CD, F5CD, 06CD, F5CD */
31593 "\xdb\x8e"=>array("\xdb\x8e", "\xef\x97\x8e", "\xef\x9b\x8e", "\xef\x9f\x8e"), /* 06CE, F5CE, F6CE, F7CE */
31594 "\xdb\x90"=>array("\xdb\x90", "\xef\xaf\xa5", "\xef\xaf\xa6", "\xef\xaf\xa7"), /* 06D0, FBE5, FBE6, FBE7 */
31595 "\xdb\x91"=>array("\xdb\x91", "\xef\x97\x91", "\xef\xad\x98", "\xef\xad\x99"), /* 06D1, F5D1, FB58, FB59 Fudge borrows from 067E */
31596 "\xdb\x92"=>array("\xdb\x92", "\xef\xae\xaf", "\xdb\x92", "\xef\xae\xaf"), /* 06D2, FBAF, 06D2, FBAF */
31597 "\xdb\x93"=>array("\xdb\x93", "\xef\xae\xb1", "\xdb\x93", "\xef\xae\xb1"), /* 06D3, FBB1, 06D3, FBB1 */
31598 );
31599
31600
31601 // LAM with ALEF ligatures (Mandatory ligatures)
31602
31603 // U+0644; U+0622; U+0644; U+0623; U+0644; U+0625; U+0644; U+0627;
31604 $this->arabLigGlyphs = "\xd9\x84\xd8\xa2\xd9\x84\xd8\xa3\xd9\x84\xd8\xa5\xd9\x84\xd8\xa7";
31605 $this->arabLigHex = 'FEF5FEF6FEF5FEF6FEF7FEF8FEF7FEF8FEF9FEFAFEF9FEFAFEFBFEFCFEFBFEFC';
31606
31607}
31608
31609// mPDF 5.4.08
31610function ArabJoin($str) {
31611 if (!$this->arabGlyphs) { $this->InitArabic(); }
31612 $crntChar = null;
31613 $prevChar = null;
31614 $nextChar = null;
31615 $output = array();
31616 $chars = preg_split('//u', $str);
31617 $max = count($chars);
31618 for ($i = $max - 1; $i >= 0; $i--) {
31619 $crntChar = $chars[$i];
31620 if ($i > 0){ $prevChar = $chars[$i - 1]; }
31621 else{ $prevChar = NULL; }
31622 if ($prevChar && mb_strpos($this->arabVowels, $prevChar, 0, 'utf-8') !== false) {
31623 $prevChar = $chars[$i - 2];
31624 if ($prevChar && mb_strpos($this->arabVowels, $prevChar, 0, 'utf-8') !== false) {
31625 $prevChar = $chars[$i - 3];
31626 }
31627 }
31628 if ($crntChar && mb_strpos($this->arabVowels, $crntChar, 0, 'utf-8') !== false) {
31629 // If next_char = nextLink && prev_char = prevLink:
31630 // Added && $prevchar (defined) else error on mb_strpos()
31631 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)) {
31632 $output[] = $this->get_arab_glyphs($crntChar, 1); // <final> form
31633 }
31634 else {
31635 $output[] = $this->get_arab_glyphs($crntChar, 0); // <isolated> form
31636 }
31637 continue;
31638 }
31639 // NB = &#x622 &#x623; &#x625; &#x627; &#x644;
31640 if (isset($chars[$i + 1]) && in_array($chars[$i + 1], array("\xd8\xa2","\xd8\xa3","\xd8\xa5","\xd8\xa7")) && $crntChar == "\xd9\x84"){
31641 continue;
31642 }
31643 if (ord($crntChar) < 128) {
31644 $output[] = $crntChar;
31645 $nextChar = $crntChar;
31646 continue;
31647 }
31648 $form = 0;
31649 if ($prevChar == "\xd9\x84" && ($crntChar == "\xd8\xa2" || $crntChar == "\xd8\xa3" || $crntChar == "\xd8\xa5" || $crntChar == "\xd8\xa7")) {
31650 if ($chars[$i - 2] && mb_strpos($this->arabPrevLink, $chars[$i - 2], 0, 'utf-8') !== false) {
31651 $form++; // <final> form
31652 }
31653 $pos = mb_strpos($this->arabLigGlyphs, ($prevChar . $crntChar), 0, 'utf-8');
31654 $pos = $pos*8 + $form*4;
31655 $pres = (mb_substr($this->arabLigHex, $pos, 4, 'utf-8'));
31656 // If presentation forms for mandatory ligatures with diacritics not present (even if remapped from e.g. uni0644uni0625)
31657 // try replacing with mandatory ligature Alef/lam isolated/final FEFB/FEFC + diacritic glyph
31658 if (!$this->_charDefined($this->CurrentFont['cw'], hexdec($pres)) && $this->_charDefined($this->CurrentFont['cw'], hexdec('FEFB'))) {
31659 if ($pres=='FEF5') { $output[] = strcode2utf('&#xFEFB;&#x0653;'); }
31660 else if ($pres=='FEF6') { $output[] = strcode2utf('&#xFEFC;&#x0653;'); }
31661 else if ($pres=='FEF7') { $output[] = strcode2utf('&#xFEFB;&#x0654;'); }
31662 else if ($pres=='FEF8') { $output[] = strcode2utf('&#xFEFC;&#x0654;'); }
31663 else if ($pres=='FEF9') { $output[] = strcode2utf('&#xFEFB;&#x0655;'); }
31664 else if ($pres=='FEFA') { $output[] = strcode2utf('&#xFEFC;&#x0655;'); }
31665 }
31666 else {
31667 $output[] = strcode2utf('&#x' . $pres . ';');
31668 }
31669 $nextChar = $prevChar;
31670 continue;
31671 }
31672 if ($prevChar && mb_strpos($this->arabPrevLink, $prevChar, 0, 'utf-8') !== false) {
31673 $form++;
31674 }
31675 if ($nextChar && mb_strpos($this->arabNextLink, $nextChar, 0, 'utf-8') !== false) {
31676 $form += 2;
31677 }
31678 $output[] = $this->get_arab_glyphs($crntChar, $form) ;
31679 $nextChar = $crntChar;
31680 }
31681 $ra = array_reverse($output);
31682 $s = implode($ra);
31683 return $s;
31684}
31685
31686// mPDF 5.7+
31687function arabJoinPregCallback($matches) {
31688 return $this->ArabJoin(stripslashes($matches[1]));
31689}
31690
31691// mPDF 5.4.08
31692function get_arab_glyphs($char, $type) {
31693 if ($type>0 && isset($this->arabGlyphs[$char])) {
31694 // If presentation form specified FB** - FE** = Arabic presentation Forms
31695 if (preg_match("/[\x{FB50}-\x{FEFF}]/u",$this->arabGlyphs[$char][$type])) {
31696 $unicode = $this->UTF8StringToArray($this->arabGlyphs[$char][$type], false);
31697 if ($this->_charDefined($this->CurrentFont['cw'],$unicode[0])) { return $this->arabGlyphs[$char][$type]; }
31698 else if (isset($this->CurrentFont['unAGlyphs'])) {
31699 $uni = $this->UTF8StringToArray($char, false);
31700 $pua = $uni[0] - 1536 + 62464 + 256*$type ;
31701 if ($this->_charDefined($this->CurrentFont['cw'], $pua)) { return strcode2utf('&#x' . dechex($pua) . ';'); }
31702 else return $char;
31703 }
31704 else return $char;
31705 }
31706 // If PUA form specified and unAGlphs font set F5** F6** F7** = Private use area used by unAGlyphs in mPDF
31707 if (preg_match("/[\x{F500}-\x{F7FF}]/u",$this->arabGlyphs[$char][$type]) && isset($this->CurrentFont['unAGlyphs'])) {
31708 $unicode = $this->UTF8StringToArray($this->arabGlyphs[$char][$type], false);
31709 if ($this->_charDefined($this->CurrentFont['cw'],$unicode[0])) { return $this->arabGlyphs[$char][$type]; }
31710 else return $char;
31711 }
31712 return $this->arabGlyphs[$char][$type];
31713 }
31714 else return $char;
31715}
31716/*-- END RTL --*/
31717
31718
31719
31720//===========================
31721// Functions originally in htmltoolkit - moved mPDF 4.0
31722
31723// Call-back function Used for usort in fn _tableWrite
31724
31725function _cmpdom($a, $b) {
31726 return ($a["dom"] < $b["dom"]) ? -1 : 1;
31727}
31728
31729function mb_strrev($str, $enc = 'utf-8'){
31730 $ch = array();
31731 $ch = preg_split('//u',$str);
31732 $revch = array_reverse($ch);
31733 return implode('',$revch);
31734}
31735
31736/*-- COLUMNS --*/
31737// Callback function from function printcolumnbuffer in mpdf
31738function columnAdjustAdd($type,$k,$xadj,$yadj,$a,$b,$c=0,$d=0,$e=0,$f=0) {
31739 if ($type == 'Td') { // xpos,ypos
31740 $a += ($xadj * $k);
31741 $b -= ($yadj * $k);
31742 return 'BT '.sprintf('%.3F %.3F',$a,$b).' Td';
31743 }
31744 else if ($type == 're') { // xpos,ypos,width,height
31745 $a += ($xadj * $k);
31746 $b -= ($yadj * $k);
31747 return sprintf('%.3F %.3F %.3F %.3F',$a,$b,$c,$d).' re';
31748 }
31749 else if ($type == 'l') { // xpos,ypos,x2pos,y2pos
31750 $a += ($xadj * $k);
31751 $b -= ($yadj * $k);
31752 return sprintf('%.3F %.3F l',$a,$b);
31753 }
31754 else if ($type == 'img') { // width,height,xpos,ypos
31755 $c += ($xadj * $k);
31756 $d -= ($yadj * $k);
31757 return sprintf('q %.3F 0 0 %.3F %.3F %.3F',$a,$b,$c,$d).' cm /'.$e;
31758 }
31759 else if ($type == 'draw') { // xpos,ypos
31760 $a += ($xadj * $k);
31761 $b -= ($yadj * $k);
31762 return sprintf('%.3F %.3F m',$a,$b);
31763 }
31764 else if ($type == 'bezier') { // xpos,ypos,x2pos,y2pos,x3pos,y3pos
31765 $a += ($xadj * $k);
31766 $b -= ($yadj * $k);
31767 $c += ($xadj * $k);
31768 $d -= ($yadj * $k);
31769 $e += ($xadj * $k);
31770 $f -= ($yadj * $k);
31771 return sprintf('%.3F %.3F %.3F %.3F %.3F %.3F',$a,$b,$c,$d,$e,$f).' c';
31772 }
31773}
31774/*-- END COLUMNS --*/
31775
31776
31777
31778function ConvertColor($color="#000000"){
31779 $color = trim(strtolower($color));
31780 $c = false;
31781 if ($color=='transparent') { return false; }
31782 else if ($color=='inherit') { return false; }
31783 else if (isset($this->SVGcolors[$color])) $color = $this->SVGcolors[$color];
31784
31785 if (preg_match('/^[\d]+$/',$color)) { $c = (array(1,$color)); } // i.e. integer only
31786 else if ($color[0] == '#') { //case of #nnnnnn or #nnn
31787 $cor = preg_replace('/\s+.*/','',$color); // in case of Background: #CCC url() x-repeat etc.
31788 if (strlen($cor) == 4) { // Turn #RGB into #RRGGBB
31789 $cor = "#" . $cor[1] . $cor[1] . $cor[2] . $cor[2] . $cor[3] . $cor[3];
31790 }
31791 $r = hexdec(substr($cor, 1, 2));
31792 $g = hexdec(substr($cor, 3, 2));
31793 $b = hexdec(substr($cor, 5, 2));
31794 $c = array(3,$r,$g,$b);
31795 }
31796 else if (preg_match('/(rgba|rgb|device-cmyka|cmyka|device-cmyk|cmyk|hsla|hsl|spot)\((.*?)\)/',$color,$m)) { // mPDF 5.6.05
31797 $type= $m[1];
31798 $cores = explode(",", $m[2]);
31799 $ncores = count($cores);
31800 if (stristr($cores[0],'%') ) {
31801 $cores[0] += 0;
31802 if ($type=='rgb' || $type=='rgba') { $cores[0] = intval($cores[0]*255/100); }
31803 }
31804 if ($ncores>1 && stristr($cores[1],'%') ) {
31805 $cores[1] += 0;
31806 if ($type=='rgb' || $type=='rgba') { $cores[1] = intval($cores[1]*255/100); }
31807 if ($type=='hsl' || $type=='hsla') { $cores[1] = $cores[1]/100; }
31808 }
31809 if ($ncores>2 && stristr($cores[2],'%') ) {
31810 $cores[2] += 0;
31811 if ($type=='rgb' || $type=='rgba') { $cores[2] = intval($cores[2]*255/100); }
31812 if ($type=='hsl' || $type=='hsla') { $cores[2] = $cores[2]/100; }
31813 }
31814 if ($ncores>3 && stristr($cores[3],'%') ) {
31815 $cores[3] += 0;
31816 }
31817
31818 if ($type=='rgb') { $c = array(3,$cores[0],$cores[1],$cores[2]); }
31819 else if ($type=='rgba') { $c = array(5,$cores[0],$cores[1],$cores[2],$cores[3]*100); }
31820 else if ($type=='cmyk' || $type=='device-cmyk') { $c = array(4,$cores[0],$cores[1],$cores[2],$cores[3]); } // mPDF 5.6.05
31821 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
31822 else if ($type=='hsl' || $type=='hsla') {
31823 $conv = $this->hsl2rgb($cores[0]/360,$cores[1],$cores[2]);
31824 if ($type=='hsl') { $c = array(3,$conv[0],$conv[1],$conv[2]); }
31825 else if ($type=='hsla') { $c = array(5,$conv[0],$conv[1],$conv[2],$cores[3]*100); }
31826 }
31827 else if ($type=='spot') {
31828 $name = strtoupper(trim($cores[0]));
31829 // mPDF 5.6.59
31830 if(!isset($this->spotColors[$name])) {
31831 if (isset($cores[5])) { $this->AddSpotColor($cores[0],$cores[2],$cores[3],$cores[4],$cores[5]); }
31832 else { $this->Error('Undefined spot color: '.$name); }
31833 }
31834 $c = array(2,$this->spotColors[$name]['i'],$cores[1]);
31835 }
31836 }
31837
31838
31839 // $this->restrictColorSpace
31840 // 1 - allow GRAYSCALE only [convert CMYK/RGB->gray]
31841 // 2 - allow RGB / SPOT COLOR / Grayscale [convert CMYK->RGB]
31842 // 3 - allow CMYK / SPOT COLOR / Grayscale [convert RGB->CMYK]
31843 if ($this->PDFA || $this->PDFX || $this->restrictColorSpace) {
31844 if ($c[0]==1) { // GRAYSCALE
31845 }
31846 else if ($c[0]==2) { // SPOT COLOR
31847 if (!isset($this->spotColorIDs[$c[1]])) { die('Error: Spot colour has not been defined - '.$this->spotColorIDs[$c[1]]); }
31848 if ($this->PDFA) {
31849 if ($this->PDFA && !$this->PDFAauto) { $this->PDFAXwarnings[] = "Spot color specified '".$this->spotColorIDs[$c[1]]."' (converted to process color)"; }
31850 if ($this->restrictColorSpace!=3) {
31851 $sp = $this->spotColors[$this->spotColorIDs[$c[1]]];
31852 $c = $this->cmyk2rgb(array(4,$sp['c'],$sp['m'],$sp['y'],$sp['k']));
31853 }
31854 }
31855 else if ($this->restrictColorSpace==1) {
31856 $sp = $this->spotColors[$this->spotColorIDs[$c[1]]];
31857 $c = $this->cmyk2gray(array(4,$sp['c'],$sp['m'],$sp['y'],$sp['k']));
31858 }
31859 }
31860 else if ($c[0]==3) { // RGB
31861 if ($this->PDFX || ($this->PDFA && $this->restrictColorSpace==3)) {
31862 if (($this->PDFA && !$this->PDFAauto) || ($this->PDFX && !$this->PDFXauto)) { $this->PDFAXwarnings[] = "RGB color specified '".$color."' (converted to CMYK)"; }
31863 $c = $this->rgb2cmyk($c);
31864 }
31865 else if ($this->restrictColorSpace==1) { $c = $this->rgb2gray($c); }
31866 else if ($this->restrictColorSpace==3) { $c = $this->rgb2cmyk($c); }
31867 }
31868 else if ($c[0]==4) { // CMYK
31869 if ($this->PDFA && $this->restrictColorSpace!=3) {
31870 if ($this->PDFA && !$this->PDFAauto) { $this->PDFAXwarnings[] = "CMYK color specified '".$color."' (converted to RGB)"; }
31871 $c = $this->cmyk2rgb($c);
31872 }
31873 else if ($this->restrictColorSpace==1) { $c = $this->cmyk2gray($c); }
31874 else if ($this->restrictColorSpace==2) { $c = $this->cmyk2rgb($c); }
31875 }
31876 else if ($c[0]==5) { // RGBa
31877 if ($this->PDFX || ($this->PDFA && $this->restrictColorSpace==3)) {
31878 if (($this->PDFA && !$this->PDFAauto) || ($this->PDFX && !$this->PDFXauto)) { $this->PDFAXwarnings[] = "RGB color with transparency specified '".$color."' (converted to CMYK without transparency)"; }
31879 $c = $this->rgb2cmyk($c);
31880 $c = array(4, $c[1], $c[2], $c[3], $c[4]);
31881 }
31882 else if ($this->PDFA && $this->restrictColorSpace!=3) {
31883 if (!$this->PDFAauto) { $this->PDFAXwarnings[] = "RGB color with transparency specified '".$color."' (converted to RGB without transparency)"; }
31884 $c = $this->rgb2cmyk($c);
31885 $c = array(4, $c[1], $c[2], $c[3], $c[4]);
31886 }
31887 else if ($this->restrictColorSpace==1) { $c = $this->rgb2gray($c); }
31888 else if ($this->restrictColorSpace==3) { $c = $this->rgb2cmyk($c); }
31889 }
31890 else if ($c[0]==6) { // CMYKa
31891 if ($this->PDFA && $this->restrictColorSpace!=3) {
31892 if (($this->PDFA && !$this->PDFAauto) || ($this->PDFX && !$this->PDFXauto)) { $this->PDFAXwarnings[] = "CMYK color with transparency specified '".$color."' (converted to RGB without transparency)"; }
31893 $c = $this->cmyk2rgb($c);
31894 $c = array(3, $c[1], $c[2], $c[3]);
31895 }
31896 else if ($this->PDFX || ($this->PDFA && $this->restrictColorSpace==3)) {
31897 if (($this->PDFA && !$this->PDFAauto) || ($this->PDFX && !$this->PDFXauto)) { $this->PDFAXwarnings[] = "CMYK color with transparency specified '".$color."' (converted to CMYK without transparency)"; }
31898 $c = $this->cmyk2rgb($c);
31899 $c = array(3, $c[1], $c[2], $c[3]);
31900 }
31901 else if ($this->restrictColorSpace==1) { $c = $this->cmyk2gray($c); }
31902 else if ($this->restrictColorSpace==2) { $c = $this->cmyk2rgb($c); }
31903 }
31904 }
31905 if (is_array($c)) {
31906 $c = array_pad($c, 6, 0);
31907 $cstr = pack("a1ccccc", $c[0], ($c[1] & 0xFF), ($c[2] & 0xFF), ($c[3] & 0xFF), ($c[4] & 0xFF), ($c[5] & 0xFF) );
31908 }
31909 return $cstr;
31910}
31911
31912function rgb2gray($c) {
31913 if (isset($c[4])) { return array(1,(($c[1] * .21) + ($c[2] * .71) + ($c[3] * .07)), ord(1), $c[4]); }
31914 else { return array(1,(($c[1] * .21) + ($c[2] * .71) + ($c[3] * .07))); }
31915}
31916
31917function cmyk2gray($c) {
31918 $rgb = $this->cmyk2rgb($c);
31919 return $this->rgb2gray($rgb);
31920}
31921
31922function rgb2cmyk($c) {
31923 $cyan = 1 - ($c[1] / 255);
31924 $magenta = 1 - ($c[2] / 255);
31925 $yellow = 1 - ($c[3] / 255);
31926 $min = min($cyan, $magenta, $yellow);
31927
31928 if ($min == 1) {
31929 if ($c[0]==5) { return array (6,100,100,100,100, $c[4]); }
31930 else { return array (4,100,100,100,100); }
31931 // For K-Black
31932 //if ($c[0]==5) { return array (6,0,0,0,100, $c[4]); }
31933 //else { return array (4,0,0,0,100); }
31934 }
31935 $K = $min;
31936 $black = 1 - $K;
31937 if ($c[0]==5) { return array (6,($cyan-$K)*100/$black, ($magenta-$K)*100/$black, ($yellow-$K)*100/$black, $K*100, $c[4]); }
31938 else { return array (4,($cyan-$K)*100/$black, ($magenta-$K)*100/$black, ($yellow-$K)*100/$black, $K*100); }
31939}
31940
31941
31942function cmyk2rgb($c) {
31943 $rgb = array();
31944 $colors = 255 - ($c[4]*2.55);
31945 $rgb[0] = intval($colors * (255 - ($c[1]*2.55))/255);
31946 $rgb[1] = intval($colors * (255 - ($c[2]*2.55))/255);
31947 $rgb[2] = intval($colors * (255 - ($c[3]*2.55))/255);
31948 if ($c[0]==6) { return array (5,$rgb[0],$rgb[1],$rgb[2], $c[5]); }
31949 else { return array (3,$rgb[0],$rgb[1],$rgb[2]); }
31950}
31951
31952function rgb2hsl($var_r, $var_g, $var_b) {
31953 $var_min = min($var_r,$var_g,$var_b);
31954 $var_max = max($var_r,$var_g,$var_b);
31955 $del_max = $var_max - $var_min;
31956 $l = ($var_max + $var_min) / 2;
31957 if ($del_max == 0) {
31958 $h = 0;
31959 $s = 0;
31960 }
31961 else {
31962 if ($l < 0.5) { $s = $del_max / ($var_max + $var_min); }
31963 else { $s = $del_max / (2 - $var_max - $var_min); }
31964 $del_r = ((($var_max - $var_r) / 6) + ($del_max / 2)) / $del_max;
31965 $del_g = ((($var_max - $var_g) / 6) + ($del_max / 2)) / $del_max;
31966 $del_b = ((($var_max - $var_b) / 6) + ($del_max / 2)) / $del_max;
31967 if ($var_r == $var_max) { $h = $del_b - $del_g; }
31968 elseif ($var_g == $var_max) { $h = (1 / 3) + $del_r - $del_b; }
31969 elseif ($var_b == $var_max) { $h = (2 / 3) + $del_g - $del_r; };
31970 if ($h < 0) { $h += 1; }
31971 if ($h > 1) { $h -= 1; }
31972 }
31973 return array($h,$s,$l);
31974}
31975
31976
31977function hsl2rgb($h2,$s2,$l2) {
31978 // Input is HSL value of complementary colour, held in $h2, $s, $l as fractions of 1
31979 // Output is RGB in normal 255 255 255 format, held in $r, $g, $b
31980 // Hue is converted using function hue_2_rgb, shown at the end of this code
31981 if ($s2 == 0) {
31982 $r = $l2 * 255;
31983 $g = $l2 * 255;
31984 $b = $l2 * 255;
31985 }
31986 else {
31987 if ($l2 < 0.5) { $var_2 = $l2 * (1 + $s2); }
31988 else { $var_2 = ($l2 + $s2) - ($s2 * $l2); }
31989 $var_1 = 2 * $l2 - $var_2;
31990 $r = round(255 * $this->hue_2_rgb($var_1,$var_2,$h2 + (1 / 3)));
31991 $g = round(255 * $this->hue_2_rgb($var_1,$var_2,$h2));
31992 $b = round(255 * $this->hue_2_rgb($var_1,$var_2,$h2 - (1 / 3)));
31993 }
31994 return array($r,$g,$b);
31995}
31996
31997function hue_2_rgb($v1,$v2,$vh) {
31998 // Function to convert hue to RGB, called from above
31999 if ($vh < 0) { $vh += 1; };
32000 if ($vh > 1) { $vh -= 1; };
32001 if ((6 * $vh) < 1) { return ($v1 + ($v2 - $v1) * 6 * $vh); };
32002 if ((2 * $vh) < 1) { return ($v2); };
32003 if ((3 * $vh) < 2) { return ($v1 + ($v2 - $v1) * ((2 / 3 - $vh) * 6)); };
32004 return ($v1);
32005}
32006
32007function _invertColor($cor) {
32008 if ($cor[0]==3 || $cor[0]==5) { // RGB
32009 return array(3, (255-$cor[1]), (255-$cor[2]), (255-$cor[3]));
32010 }
32011 else if ($cor[0]==4 || $cor[0]==6) { // CMYK
32012 return array(4, (100-$cor[1]), (100-$cor[2]), (100-$cor[3]), (100-$cor[4]));
32013 }
32014 else if ($cor[0]==1) { // Grayscale
32015 return array(1, (255-$cor[1]));
32016 }
32017 // Cannot cope with non-RGB colors at present
32018 die('Error in _invertColor - trying to invert non-RGB color');
32019}
32020
32021function _colAtoString($cor) {
32022 $s = '';
32023 if ($cor{0}==1) $s = 'rgb('.ord($cor{1}).','.ord($cor{1}).','.ord($cor{1}).')';
32024 else if ($cor{0}==2) $s = 'spot('.ord($cor{1}).','.ord($cor{2}).')'; // SPOT COLOR
32025 else if ($cor{0}==3) $s = 'rgb('.ord($cor{1}).','.ord($cor{2}).','.ord($cor{3}).')';
32026 else if ($cor{0}==4) $s = 'cmyk('.ord($cor{1}).','.ord($cor{2}).','.ord($cor{3}).','.ord($cor{4}).')';
32027 else if ($cor{0}==5) $s = 'rgba('.ord($cor{1}).','.ord($cor{2}).','.ord($cor{3}).','.sprintf('%0.2F',ord($cor{4})/100).')';
32028 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).')';
32029 return $s;
32030}
32031
32032function ConvertSize($size=5,$maxsize=0,$fontsize=false,$usefontsize=true){
32033// usefontsize - setfalse for e.g. margins - will ignore fontsize for % values
32034// Depends of maxsize value to make % work properly. Usually maxsize == pagewidth
32035// For text $maxsize = Fontsize
32036// Setting e.g. margin % will use maxsize (pagewidth) and em will use fontsize
32037 //Identify size (remember: we are using 'mm' units here)
32038 $size = trim(strtolower($size));
32039
32040 if ( $size == 'thin' ) $size = 1*(25.4/$this->dpi); //1 pixel width for table borders
32041 elseif ( stristr($size,'px') ) $size *= (25.4/$this->dpi); //pixels
32042 elseif ( stristr($size,'cm') ) $size *= 10; //centimeters
32043 elseif ( stristr($size,'mm') ) $size += 0; //millimeters
32044 elseif ( stristr($size,'pt') ) $size *= 25.4/72; //72 pts/inch
32045 elseif ( stristr($size,'rem') ) { // mPDF 5.6.12
32046 $size += 0; //make "0.83rem" become simply "0.83"
32047 $size *= ($this->default_font_size / _MPDFK);
32048 }
32049 elseif ( stristr($size,'em') ) {
32050 $size += 0; //make "0.83em" become simply "0.83"
32051 if ($fontsize) { $size *= $fontsize; }
32052 else { $size *= $maxsize; }
32053 }
32054 elseif ( stristr($size,'%') ) {
32055 $size += 0; //make "90%" become simply "90"
32056 if ($fontsize && $usefontsize) { $size *= $fontsize/100; }
32057 else { $size *= $maxsize/100; }
32058 }
32059 elseif ( stristr($size,'in') ) $size *= 25.4; //inches
32060 elseif ( stristr($size,'pc') ) $size *= 38.1/9; //PostScript picas
32061 elseif ( stristr($size,'ex') ) { // Approximates "ex" as half of font height
32062 $size += 0; //make "3.5ex" become simply "3.5"
32063 if ($fontsize) { $size *= $fontsize/2; }
32064 else { $size *= $maxsize/2; }
32065 }
32066 elseif ( $size == 'medium' ) $size = 3*(25.4/$this->dpi); //3 pixel width for table borders
32067 elseif ( $size == 'thick' ) $size = 5*(25.4/$this->dpi); //5 pixel width for table borders
32068 elseif ($size == 'xx-small') {
32069 if ($fontsize) { $size *= $fontsize*0.7; }
32070 else { $size *= $maxsize*0.7; }
32071 }
32072 elseif ($size == 'x-small') {
32073 if ($fontsize) { $size *= $fontsize*0.77; }
32074 else { $size *= $maxsize*0.77; }
32075 }
32076 elseif ($size == 'small') {
32077 if ($fontsize) { $size *= $fontsize*0.86; }
32078 else { $size *= $maxsize*0.86; }
32079 }
32080 elseif ($size == 'medium') {
32081 if ($fontsize) { $size *= $fontsize; }
32082 else { $size *= $maxsize; }
32083 }
32084 elseif ($size == 'large') {
32085 if ($fontsize) { $size *= $fontsize*1.2; }
32086 else { $size *= $maxsize*1.2; }
32087 }
32088 elseif ($size == 'x-large') {
32089 if ($fontsize) { $size *= $fontsize*1.5; }
32090 else { $size *= $maxsize*1.5; }
32091 }
32092 elseif ($size == 'xx-large') {
32093 if ($fontsize) { $size *= $fontsize*2; }
32094 else { $size *= $maxsize*2; }
32095 }
32096 else $size *= (25.4/$this->dpi); //nothing == px
32097
32098 return $size;
32099}
32100
32101
32102function lesser_entity_decode($html) {
32103 //supports the most used entity codes (only does ascii safe characters)
32104 //$html = str_replace("&nbsp;"," ",$html); // mPDF 5.3.59
32105 $html = str_replace("&lt;","<",$html);
32106 $html = str_replace("&gt;",">",$html);
32107
32108 $html = str_replace("&apos;","'",$html);
32109 $html = str_replace("&quot;",'"',$html);
32110 $html = str_replace("&amp;","&",$html);
32111 return $html;
32112}
32113
32114function AdjustHTML($html, $tabSpaces=8) {
32115 //Try to make the html text more manageable (turning it into XHTML)
32116 if (PHP_VERSION_ID < 50307) {
32117 if (strlen($html) > 100000) {
32118 if (PHP_VERSION_ID < 50200) $this->Error("The HTML code is more than 100,000 characters. You should use WriteHTML() with smaller string lengths.");
32119 else ini_set("pcre.backtrack_limit","1000000");
32120 }
32121 }
32122
32123/*-- ANNOTATIONS --*/
32124 preg_match_all("/(<annotation.*?>)/si", $html, $m);
32125 if (count($m[1])) {
32126 for($i=0;$i<count($m[1]);$i++) {
32127 $sub = preg_replace("/\n/si", "\xbb\xa4\xac", $m[1][$i]);
32128 $html = preg_replace('/'.preg_quote($m[1][$i], '/').'/si', $sub, $html);
32129 }
32130 }
32131/*-- END ANNOTATIONS --*/
32132
32133 preg_match_all("/(<svg.*?<\/svg>)/si", $html, $svgi);
32134 if (count($svgi[0])) {
32135 for($i=0;$i<count($svgi[0]);$i++) {
32136 $file = _MPDF_TEMP_PATH.'_tempSVG'.uniqid(rand(1,100000),true).'_'.$i.'.svg';
32137 //Save to local file
32138 file_put_contents($file, $svgi[0][$i]);
32139 $html = str_replace($svgi[0][$i], '<img src="'.$file.'" />', $html); // mPDF 5.5.18
32140 }
32141 }
32142
32143 //Remove javascript code from HTML (should not appear in the PDF file)
32144 $html = preg_replace('/<script.*?<\/script>/is','',$html);
32145
32146 //Remove special comments
32147 $html = preg_replace('/<!--mpdf/i','',$html);
32148 $html = preg_replace('/mpdf-->/i','',$html);
32149
32150 //Remove comments from HTML (should not appear in the PDF file)
32151 $html = preg_replace('/<!--.*?-->/s','',$html);
32152
32153 $html = preg_replace('/\f/','',$html); //replace formfeed by nothing
32154 $html = preg_replace('/\r/','',$html); //replace carriage return by nothing
32155
32156 // Well formed XHTML end tags
32157 $html = preg_replace('/<(br|hr)\/>/i',"<\\1 />",$html);
32158 // Get rid of empty <thead></thead>
32159 $html = preg_replace('/<thead>\s*<\/thead>/i','',$html);
32160 $html = preg_replace('/<tfoot>\s*<\/tfoot>/i','',$html);
32161 $html = preg_replace('/<table[^>]*>\s*<\/table>/i','',$html);
32162 $html = preg_replace('/<tr>\s*<\/tr>/i','',$html);
32163
32164 // Remove spaces at end of table cells
32165 $html = preg_replace("/[ \n\r]+<\/t(d|h)/",'</t\\1',$html); // mPDF 5.5.09
32166
32167 $html = preg_replace("/[ ]*<dottab\s*[\/]*>[ ]*/",'<dottab />',$html);
32168
32169 // Concatenates any Substitute characters from symbols/dingbats
32170 $html = str_replace('</tts><tts>','|',$html);
32171 $html = str_replace('</ttz><ttz>','|',$html);
32172 $html = str_replace('</tta><tta>','|',$html);
32173
32174 $html = preg_replace('/<br \/>\s*/is',"<br />",$html);
32175
32176 $html = preg_replace('/<wbr[ \/]*>\s*/is',"&#173;",$html); // mPDF 5.6.04
32177
32178 // Preserve '\n's in content between the tags <pre> and </pre>
32179 if (preg_match('/<pre/',$html)) {
32180 $html_a = preg_split('/(\<\/?pre[^\>]*\>)/', $html, -1, 2);
32181 $h = array();
32182 $c=0;
32183 foreach($html_a AS $s) {
32184 if ($c>1 && preg_match('/^<\/pre/i',$s)) { $c--; $s=preg_replace('/<\/pre/i','</innerpre',$s); }
32185 else if ($c>0 && preg_match('/^<pre/i',$s)) { $c++; $s=preg_replace('/<pre/i','<innerpre',$s); }
32186 else if (preg_match('/^<pre/i',$s)) { $c++; }
32187 else if (preg_match('/^<\/pre/i',$s)) { $c--; }
32188 array_push($h, $s);
32189 }
32190 $html = implode("", $h);
32191 }
32192 $thereispre = preg_match_all('#<pre(.*?)>(.*?)</pre>#si',$html,$temp);
32193 // Preserve '\n's in content between the tags <textarea> and </textarea>
32194 $thereistextarea = preg_match_all('#<textarea(.*?)>(.*?)</textarea>#si',$html,$temp2);
32195 $html = preg_replace('/[\n]/',' ',$html); //replace linefeed by spaces
32196 $html = preg_replace('/[\t]/',' ',$html); //replace tabs by spaces
32197
32198 // Converts < to &lt; when not a tag
32199 $html = preg_replace('/<([^!\/a-zA-Z])/i','&lt;\\1',$html);
32200 $html = preg_replace("/[ ]+/",' ',$html);
32201
32202 $html = preg_replace('/\/li>\s+<\/(u|o)l/i','/li></\\1l',$html);
32203 $html = preg_replace('/\/(u|o)l>\s+<\/li/i','/\\1l></li',$html);
32204 $html = preg_replace('/\/li>\s+<\/(u|o)l/i','/li></\\1l',$html);
32205 $html = preg_replace('/\/li>\s+<li/i','/li><li',$html);
32206 $html = preg_replace('/<(u|o)l([^>]*)>[ ]+/i','<\\1l\\2>',$html);
32207 $html = preg_replace('/[ ]+<(u|o)l/i','<\\1l',$html);
32208
32209 $iterator = 0;
32210 while($thereispre) //Recover <pre attributes>content</pre>
32211 {
32212 $temp[2][$iterator] = preg_replace('/<([^a-zA-Z_:])/','&lt;\\1',$temp[2][$iterator]); // mPDF 5.7.2
32213 $temp[2][$iterator] = preg_replace_callback("/^([^\n\t]*?)\t/m", array($this, 'tabs2spaces_callback'), $temp[2][$iterator]); // mPDF 5.7+
32214 $temp[2][$iterator] = preg_replace('/\t/',str_repeat(" ",$tabSpaces),$temp[2][$iterator]);
32215
32216 $temp[2][$iterator] = preg_replace('/\n/',"<br />",$temp[2][$iterator]);
32217 $temp[2][$iterator] = str_replace('\\',"\\\\",$temp[2][$iterator]);
32218 //$html = preg_replace('#<pre(.*?)>(.*?)</pre>#si','<erp'.$temp[1][$iterator].'>'.$temp[2][$iterator].'</erp>',$html,1);
32219 $html = preg_replace('#<pre(.*?)>(.*?)</pre>#si','<erp'.$temp[1][$iterator].'>'.str_replace('$','\$',$temp[2][$iterator]).'</erp>',$html,1); // mPDF 5.7+
32220 $thereispre--;
32221 $iterator++;
32222 }
32223 $iterator = 0;
32224 while($thereistextarea) //Recover <textarea attributes>content</textarea>
32225 {
32226 $temp2[2][$iterator] = preg_replace('/\t/',str_repeat(" ",$tabSpaces),$temp2[2][$iterator]);
32227 $temp2[2][$iterator] = str_replace('\\',"\\\\",$temp2[2][$iterator]); // mPDF 5.3.88
32228 $html = preg_replace('#<textarea(.*?)>(.*?)</textarea>#si','<aeratxet'.$temp2[1][$iterator].'>'.trim($temp2[2][$iterator]) .'</aeratxet>',$html,1);
32229 $thereistextarea--;
32230 $iterator++;
32231 }
32232 //Restore original tag names
32233 $html = str_replace("<erp","<pre",$html);
32234 $html = str_replace("</erp>","</pre>",$html);
32235 $html = str_replace("<aeratxet","<textarea",$html);
32236 $html = str_replace("</aeratxet>","</textarea>",$html);
32237 $html = str_replace("</innerpre","</pre",$html);
32238 $html = str_replace("<innerpre","<pre",$html);
32239
32240 $html = preg_replace('/<textarea([^>]*)><\/textarea>/si','<textarea\\1> </textarea>',$html);
32241 $html = preg_replace('/(<table[^>]*>)\s*(<caption)(.*?<\/caption>)(.*?<\/table>)/si','\\2 position="top"\\3\\1\\4\\2 position="bottom"\\3',$html); // *TABLES*
32242 $html = preg_replace('/<(h[1-6])([^>]*)(>(?:(?!h[1-6]).)*?<\/\\1>\s*<table)/si','<\\1\\2 keep-with-table="1"\\3',$html); // *TABLES*
32243 $html = preg_replace("/\xbb\xa4\xac/", "\n", $html);
32244
32245 return $html;
32246}
32247// mPDF 5.7+
32248function tabs2spaces_callback($matches) {
32249 return (stripslashes($matches[1]) . str_repeat(' ', $this->tabSpaces - (mb_strlen(stripslashes($matches[1])) % $this->tabSpaces)));
32250}
32251// mPDF 5.7+
32252function date_callback($matches) {
32253 return date($matches[1]);
32254}
32255
32256/*-- LISTS --*/
32257function dec2other($num, $cp) {
32258 $nstr = (string) $num;
32259 $rnum = '';
32260 for ($i=0;$i<strlen($nstr);$i++) {
32261 if ($this->_charDefined($this->CurrentFont['cw'],$cp+intval($nstr[$i]))) { // contains arabic-indic numbers
32262 $rnum .= code2utf($cp+intval($nstr[$i]));
32263 }
32264 else { $rnum .= $nstr[$i]; }
32265 }
32266 return $rnum;
32267}
32268
32269function dec2alpha($valor,$toupper="true"){
32270// returns a string from A-Z to AA-ZZ to AAA-ZZZ
32271// OBS: A = 65 ASCII TABLE VALUE
32272 if (($valor < 1) || ($valor > 18278)) return "?"; //supports 'only' up to 18278
32273 $c1 = $c2 = $c3 = '';
32274 if ($valor > 702) // 3 letters (up to 18278)
32275 {
32276 $c1 = 65 + floor(($valor-703)/676);
32277 $c2 = 65 + floor((($valor-703)%676)/26);
32278 $c3 = 65 + floor((($valor-703)%676)%26);
32279 }
32280 elseif ($valor > 26) // 2 letters (up to 702)
32281 {
32282 $c1 = (64 + (int)(($valor-1) / 26));
32283 $c2 = (64 + (int)($valor % 26));
32284 if ($c2 == 64) $c2 += 26;
32285 }
32286 else // 1 letter (up to 26)
32287 {
32288 $c1 = (64 + $valor);
32289 }
32290 $alpha = chr($c1);
32291 if ($c2 != '') $alpha .= chr($c2);
32292 if ($c3 != '') $alpha .= chr($c3);
32293 if (!$toupper) $alpha = strtolower($alpha);
32294 return $alpha;
32295}
32296
32297
32298function dec2roman($valor,$toupper=true){
32299 //returns a string as a roman numeral
32300 $r1=$r2=$r3=$r4='';
32301 if (($valor >= 5000) || ($valor < 1)) return "?"; //supports 'only' up to 4999
32302 $aux = (int)($valor/1000);
32303 if ($aux!==0)
32304 {
32305 $valor %= 1000;
32306 while($aux!==0)
32307 {
32308 $r1 .= "M";
32309 $aux--;
32310 }
32311 }
32312 $aux = (int)($valor/100);
32313 if ($aux!==0)
32314 {
32315 $valor %= 100;
32316 switch($aux){
32317 case 3: $r2="C";
32318 case 2: $r2.="C";
32319 case 1: $r2.="C"; break;
32320 case 9: $r2="CM"; break;
32321 case 8: $r2="C";
32322 case 7: $r2.="C";
32323 case 6: $r2.="C";
32324 case 5: $r2="D".$r2; break;
32325 case 4: $r2="CD"; break;
32326 default: break;
32327 }
32328 }
32329 $aux = (int)($valor/10);
32330 if ($aux!==0)
32331 {
32332 $valor %= 10;
32333 switch($aux){
32334 case 3: $r3="X";
32335 case 2: $r3.="X";
32336 case 1: $r3.="X"; break;
32337 case 9: $r3="XC"; break;
32338 case 8: $r3="X";
32339 case 7: $r3.="X";
32340 case 6: $r3.="X";
32341 case 5: $r3="L".$r3; break;
32342 case 4: $r3="XL"; break;
32343 default: break;
32344 }
32345 }
32346 switch($valor){
32347 case 3: $r4="I";
32348 case 2: $r4.="I";
32349 case 1: $r4.="I"; break;
32350 case 9: $r4="IX"; break;
32351 case 8: $r4="I";
32352 case 7: $r4.="I";
32353 case 6: $r4.="I";
32354 case 5: $r4="V".$r4; break;
32355 case 4: $r4="IV"; break;
32356 default: break;
32357 }
32358 $roman = $r1.$r2.$r3.$r4;
32359 if (!$toupper) $roman = strtolower($roman);
32360 return $roman;
32361}
32362/*-- END LISTS --*/
32363
32364
32365//===========================
32366/*-- IMPORTS --*/
32367function SetImportUse() {
32368 $this->enableImports = true;
32369 ini_set('auto_detect_line_endings',1);
32370 require_once(_MPDF_PATH."mpdfi/pdf_context.php");
32371 require_once(_MPDF_PATH."mpdfi/pdf_parser.php");
32372 require_once(_MPDF_PATH."mpdfi/fpdi_pdf_parser.php");
32373}
32374
32375// from mPDFI
32376function hex2str($hex) {
32377 return pack("H*", str_replace(array("\r","\n"," "),"", $hex));
32378}
32379
32380function str2hex($str) {
32381 return current(unpack("H*",$str));
32382}
32383
32384
32385function pdf_write_value(&$value) {
32386 switch ($value[0]) {
32387 case PDF_TYPE_NUMERIC :
32388 case PDF_TYPE_TOKEN :
32389 // A numeric value or a token.
32390 // Simply output them
32391 $this->_out($value[1]." ", false);
32392 break;
32393
32394 case PDF_TYPE_ARRAY :
32395 // An array. Output the proper
32396 // structure and move on.
32397 $this->_out("[",false);
32398 for ($i = 0; $i < count($value[1]); $i++) {
32399 $this->pdf_write_value($value[1][$i]);
32400 }
32401 $this->_out("]");
32402 break;
32403
32404 case PDF_TYPE_DICTIONARY :
32405 // A dictionary.
32406 $this->_out("<<",false);
32407 reset ($value[1]);
32408 while (list($k, $v) = each($value[1])) {
32409 $this->_out($k . " ",false);
32410 $this->pdf_write_value($v);
32411 }
32412 $this->_out(">>");
32413 break;
32414
32415 case PDF_TYPE_OBJREF :
32416 // An indirect object reference
32417 // Fill the object stack if needed
32418 $cpfn =& $this->current_parser->filename;
32419 if (!isset($this->_don_obj_stack[$cpfn][$value[1]])) {
32420 $this->_newobj(false,true);
32421 $this->_obj_stack[$cpfn][$value[1]] = array($this->n, $value);
32422 $this->_don_obj_stack[$cpfn][$value[1]] = array($this->n, $value);
32423 }
32424 $objid = $this->_don_obj_stack[$cpfn][$value[1]][0];
32425 $this->_out("{$objid} 0 R"); //{$value[2]}
32426 break;
32427
32428 case PDF_TYPE_STRING :
32429 if ($this->encrypted) {
32430 $value[1] = $this->_RC4($this->_objectkey($this->_current_obj_id), $value[1]);
32431 $value[1] = $this->_escape($value[1]);
32432 }
32433 // A string.
32434 $this->_out('('.$value[1].')');
32435 break;
32436
32437 case PDF_TYPE_STREAM :
32438 // A stream. First, output the
32439 // stream dictionary, then the
32440 // stream data itself.
32441 $this->pdf_write_value($value[1]);
32442 if ($this->encrypted) {
32443 $value[2][1] = $this->_RC4($this->_objectkey($this->_current_obj_id), $value[2][1]);
32444 }
32445 $this->_out("stream");
32446 $this->_out($value[2][1]);
32447 $this->_out("endstream");
32448 break;
32449
32450 case PDF_TYPE_HEX :
32451 if ($this->encrypted) {
32452 $value[1] = $this->hex2str($value[1]);
32453 $value[1] = $this->_RC4($this->_objectkey($this->_current_obj_id), $value[1]);
32454 // remake hexstring of encrypted string
32455 $value[1] = $this->str2hex($value[1]);
32456 }
32457 $this->_out("<".$value[1].">");
32458 break;
32459
32460 case PDF_TYPE_NULL :
32461 // The null object.
32462 $this->_out("null");
32463 break;
32464 }
32465}
32466
32467// ========== OVERWRITE SEARCH STRING IN A PDF FILE ================
32468function OverWrite($file_in, $search, $replacement, $dest="D", $file_out="mpdf" ) {
32469 $pdf = file_get_contents($file_in);
32470
32471 if (!is_array($search)) {
32472 $x = $search;
32473 $search = array($x);
32474 }
32475 if (!is_array($replacement)) {
32476 $x = $replacement;
32477 $search = array($x);
32478 }
32479
32480 if (!$this->onlyCoreFonts && !$this->usingCoreFont) {
32481 foreach($search AS $k=>$val) {
32482 $search[$k] = $this->UTF8ToUTF16BE($search[$k] , false);
32483 $search[$k] = $this->_escape($search[$k]);
32484 $replacement[$k] = $this->UTF8ToUTF16BE($replacement[$k], false);
32485 $replacement[$k] = $this->_escape($replacement[$k]);
32486 }
32487 }
32488 else {
32489 foreach($replacement AS $k=>$val) {
32490 $replacement[$k] = mb_convert_encoding($replacement[$k],$this->mb_enc,'utf-8');
32491 $replacement[$k] = $this->_escape($replacement[$k]);
32492 }
32493 }
32494
32495 // Get xref into array
32496 $xref = array();
32497 preg_match("/xref\n0 (\d+)\n(.*?)\ntrailer/s",$pdf,$m);
32498 $xref_objid = $m[1];
32499 preg_match_all('/(\d{10}) (\d{5}) (f|n)/',$m[2],$x);
32500 for($i=0; $i<count($x[0]); $i++) {
32501 $xref[] = array(intval($x[1][$i]), $x[2][$i], $x[3][$i]);
32502 }
32503
32504 $changes = array();
32505 preg_match("/<<\s*\/Type\s*\/Pages\s*\/Kids\s*\[(.*?)\]\s*\/Count/s",$pdf,$m);
32506 preg_match_all("/(\d+) 0 R /s",$m[1],$o);
32507 $objlist = $o[1];
32508 foreach($objlist AS $obj) {
32509 if ($this->compress) {
32510 preg_match("/".($obj+1)." 0 obj\n<<\s*\/Filter\s*\/FlateDecode\s*\/Length (\d+)>>\nstream\n(.*?)\nendstream\n/s",$pdf,$m);
32511 }
32512 else {
32513 preg_match("/".($obj+1)." 0 obj\n<<\s*\/Length (\d+)>>\nstream\n(.*?)\nendstream\n/s",$pdf,$m);
32514 }
32515 $s = $m[2];
32516 if (!$s) { continue; }
32517 $oldlen = $m[1];
32518 if ($this->encrypted) {
32519 $s = $this->_RC4($this->_objectkey($obj+1), $s);
32520 }
32521 if ($this->compress) {
32522 $s = gzuncompress($s);
32523 }
32524 foreach($search AS $k=>$val) {
32525 $s = str_replace($search[$k],$replacement[$k],$s);
32526 }
32527 if ($this->compress) {
32528 $s = gzcompress($s);
32529 }
32530 if ($this->encrypted) {
32531 $s = $this->_RC4($this->_objectkey($obj+1), $s);
32532 }
32533 $newlen = strlen($s);
32534 $changes[($xref[$obj+1][0])] = ($newlen - $oldlen) + (strlen($newlen) - strlen($oldlen ));
32535 if ($this->compress) {
32536 $newstr = ($obj+1) . " 0 obj\n<</Filter /FlateDecode /Length ".$newlen.">>\nstream\n".$s."\nendstream\n";
32537 }
32538 else {
32539 $newstr = ($obj+1) . " 0 obj\n<</Length ".$newlen.">>\nstream\n".$s."\nendstream\n";
32540 }
32541 $pdf = str_replace($m[0],$newstr,$pdf);
32542 }
32543
32544 // Update xref in PDF
32545 krsort($changes);
32546 $newxref = "xref\n0 ".$xref_objid."\n";
32547 foreach($xref AS $v) {
32548 foreach($changes AS $ck => $cv) {
32549 if ($v[0] > $ck) { $v[0] += $cv; }
32550 }
32551 $newxref .= sprintf('%010d',$v[0]) . ' ' . $v[1] . ' ' .$v[2] . " \n";
32552 }
32553 $newxref .= "trailer";
32554 $pdf = preg_replace("/xref\n0 \d+\n.*?\ntrailer/s",$newxref,$pdf);
32555
32556 // Update startxref in PDF
32557 preg_match("/startxref\n(\d+)\n%%EOF/s", $pdf, $m);
32558 $startxref = $m[1];
32559 $startxref += array_sum($changes);
32560 $pdf = preg_replace("/startxref\n(\d+)\n%%EOF/s","startxref\n".$startxref."\n%%EOF",$pdf);
32561
32562 // OUTPUT
32563 switch($dest) {
32564 case 'I':
32565 //Send to standard output
32566 if(isset($_SERVER['SERVER_NAME']))
32567 {
32568 //We send to a browser
32569 Header('Content-Type: application/pdf');
32570 Header('Content-Length: '.strlen($pdf));
32571 Header('Content-disposition: inline; filename='.$file_out);
32572 }
32573 echo $pdf;
32574 break;
32575 case 'F':
32576 //Save to local file
32577 if (!$file_out) { $file_out = 'mpdf.pdf'; }
32578 $f=fopen($file_out,'wb');
32579 if(!$f) die('Unable to create output file: '.$file_out);
32580 fwrite($f,$pdf,strlen($pdf));
32581 fclose($f);
32582 break;
32583 case 'S':
32584 //Return as a string
32585 return $pdf;
32586 case 'D':
32587 default:
32588 //Download file
32589 if(isset($_SERVER['HTTP_USER_AGENT']) and strpos($_SERVER['HTTP_USER_AGENT'],'MSIE'))
32590 Header('Content-Type: application/force-download');
32591 else
32592 Header('Content-Type: application/octet-stream');
32593 Header('Content-Length: '.strlen($pdf));
32594 Header('Content-disposition: attachment; filename='.$file_out);
32595 echo $pdf;
32596 break;
32597 }
32598}
32599
32600
32601function GetTemplateSize($tplidx, $_w=0, $_h=0) {
32602 if (!$this->tpls[$tplidx])
32603 return false;
32604 $w = $this->tpls[$tplidx]['box']['w'];
32605 $h = $this->tpls[$tplidx]['box']['h'];
32606 if ($_w == 0 and $_h == 0) {
32607 $_w = $w;
32608 $_h = $h;
32609 }
32610 if($_w==0)
32611 $_w=$_h*$w/$h;
32612 if($_h==0)
32613 $_h=$_w*$h/$w;
32614 return array("w" => $_w, "h" => $_h);
32615}
32616
32617// Thumbnails
32618function Thumbnail($file, $npr=3, $spacing=10) { //$npr = number per row
32619 $w = (($this->pgwidth + $spacing)/$npr) - $spacing;
32620 $oldlinewidth = $this->LineWidth;
32621 $this->SetLineWidth(0.02);
32622 $this->SetDColor($this->ConvertColor(0));
32623 $h = 0;
32624 $maxh = 0;
32625 $x = $_x = $this->lMargin;
32626 $_y = $this->tMargin;
32627 if ($this->y==0) { $y = $_y; } else { $y = $this->y; }
32628 $pagecount = $this->SetSourceFile($file);
32629 for ($n = 1; $n <= $pagecount; $n++) {
32630 $tplidx = $this->ImportPage($n);
32631 $size = $this->useTemplate($tplidx, $x, $y, $w);
32632 $this->Rect($x, $y, $size['w'], $size['h']);
32633 $h = max($h, $size['h']);
32634 $maxh = max($h, $maxh);
32635 if ($n % $npr == 0) {
32636 if (($y + $h + $spacing + $maxh)>$this->PageBreakTrigger && $n != $pagecount) {
32637 $this->AddPage();
32638 $x = $_x;
32639 $y = $_y;
32640 }
32641 else {
32642 $y += $h+$spacing ;
32643 $x = $_x;
32644 $h = 0;
32645 }
32646 }
32647 else {
32648 $x += $w+$spacing ;
32649 }
32650 }
32651 $this->SetLineWidth($oldlinewidth);
32652}
32653
32654function SetSourceFile($filename) {
32655 $this->current_filename = $filename;
32656 $fn =& $this->current_filename;
32657 if (!isset($this->parsers[$fn]))
32658 // $this->parsers[$fn] =& new fpdi_pdf_parser($fn,$this);
32659 $this->parsers[$fn] = new fpdi_pdf_parser($fn,$this);
32660 if (!$this->parsers[$fn]->success) {
32661 $this->Error($this->parsers[$fn]->errormsg); // Delete this line to return false on fail
32662 return false;
32663 }
32664 $this->current_parser =& $this->parsers[$fn];
32665 return $this->parsers[$fn]->getPageCount();
32666}
32667function ImportPage($pageno=1, $crop_x=null, $crop_y=null, $crop_w=0, $crop_h=0, $boxName='/CropBox') {
32668 $fn =& $this->current_filename;
32669 $parser =& $this->parsers[$fn];
32670 $parser->setPageno($pageno);
32671
32672 $this->tpl++;
32673 $this->tpls[$this->tpl] = array();
32674 $tpl =& $this->tpls[$this->tpl];
32675 $tpl['parser'] =& $parser;
32676 $tpl['resources'] = $parser->getPageResources();
32677 $tpl['buffer'] = $parser->getContent();
32678 if (!in_array($boxName, $parser->availableBoxes))
32679 return $this->Error(sprintf("Unknown box: %s", $boxName));
32680 $pageboxes = $parser->getPageBoxes($pageno);
32681 /**
32682 * MediaBox
32683 * CropBox: Default -> MediaBox
32684 * BleedBox: Default -> CropBox
32685 * TrimBox: Default -> CropBox
32686 * ArtBox: Default -> CropBox
32687 */
32688 if (!isset($pageboxes[$boxName]) && ($boxName == "/BleedBox" || $boxName == "/TrimBox" || $boxName == "/ArtBox"))
32689 $boxName = "/CropBox";
32690 if (!isset($pageboxes[$boxName]) && $boxName == "/CropBox")
32691 $boxName = "/MediaBox";
32692 if (!isset($pageboxes[$boxName]))
32693 return false;
32694 $box = $pageboxes[$boxName];
32695
32696 $tpl['box'] = $box;
32697 // To build an array that can be used by useTemplate()
32698 $this->tpls[$this->tpl] = array_merge($this->tpls[$this->tpl],$box);
32699 // An imported page will start at 0,0 everytime. Translation will be set in _putformxobjects()
32700 $tpl['x'] = 0;
32701 $tpl['y'] = 0;
32702 $tpl['w'] = $tpl['box']['w'] ;
32703 $tpl['h'] = $tpl['box']['h'] ;
32704 if ($crop_w) { $tpl['box']['w'] = $crop_w; }
32705 if ($crop_h) { $tpl['box']['h'] = $crop_h; }
32706 if (isset($crop_x)) { $tpl['box']['x'] = $crop_x; }
32707 if (isset($crop_y)) {$tpl['box']['y'] = $tpl['h'] - $crop_y - $crop_h ; }
32708
32709 $page =& $parser->pages[$parser->pageno];
32710 // fix for rotated pages
32711 $rotation = $parser->getPageRotation($pageno);
32712
32713 if (isset($rotation[1]) && ($angle = $rotation[1] % 360) != 0 && $tpl['box']['w'] == $tpl['w']) {
32714 $steps = $angle / 90;
32715
32716 $_w = $tpl['w'];
32717 $_h = $tpl['h'];
32718 $tpl['w'] = $steps % 2 == 0 ? $_w : $_h;
32719 $tpl['h'] = $steps % 2 == 0 ? $_h : $_w;
32720 if ($steps % 2 != 0) {
32721 $x = $y = ($steps == 1 || $steps == -3) ? $tpl['h'] : $tpl['w'];
32722 } else {
32723 $x = $tpl['w'];
32724 $y = $tpl['h'];
32725 }
32726 $cx=($x/2+$tpl['box']['x'])*_MPDFK;
32727 $cy=($y/2+$tpl['box']['y'])*_MPDFK;
32728 $angle*=-1;
32729 $angle*=M_PI/180;
32730 $c=cos($angle);
32731 $s=sin($angle);
32732 $tpl['box']['w'] = $tpl['w'] ;
32733 $tpl['box']['h'] = $tpl['h'] ;
32734 $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']);
32735 }
32736 return $this->tpl;
32737}
32738function UseTemplate($tplidx, $_x=null, $_y=null, $_w=0, $_h=0) {
32739 if (!isset($this->tpls[$tplidx]))
32740 $this->Error("Template does not exist!");
32741 if($this->state==0) { $this->AddPage(); }
32742 $out = 'q 0 J 1 w 0 j 0 G'."\n"; // reset standard values
32743 $x = $this->tpls[$tplidx]['x'];
32744 $y = $this->tpls[$tplidx]['y'];
32745 $w = $this->tpls[$tplidx]['w'];
32746 $h = $this->tpls[$tplidx]['h'];
32747 if ($_x == null) { $_x = $x; }
32748 if ($_y == null) { $_y = $y; }
32749 if ($_x === -1) { $_x = $this->x; }
32750 if ($_y === -1) { $_y = $this->y; }
32751
32752 $wh = $this->getTemplateSize($tplidx,$_w,$_h);
32753 $_w = $wh['w'];
32754 $_h = $wh['h'];
32755 $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";
32756 $out .= $this->tplprefix.$tplidx." Do Q\n";
32757
32758 $s = array("w" => $_w, "h" => $_h);
32759 $out .= "Q\n";
32760 $this->pages[$this->page] = $out . $this->pages[$this->page];
32761 return $s;
32762}
32763function SetPageTemplate($tplidx='') {
32764 if (!isset($this->tpls[$tplidx])) {
32765 $this->pageTemplate = '';
32766 return false;
32767 }
32768 $this->pageTemplate = $tplidx;
32769}
32770function SetDocTemplate($file='', $continue=0) {
32771 $this->docTemplate = $file;
32772 $this->docTemplateContinue = $continue;
32773}
32774/*-- END IMPORTS --*/
32775
32776
32777/* ---------------------------------------------- */
32778/* ---------------------------------------------- */
32779/* ---------------------------------------------- */
32780/* ---------------------------------------------- */
32781/* ---------------------------------------------- */
32782
32783// JAVASCRIPT
32784function _set_object_javascript ($string) {
32785 $this->_newobj();
32786 $this->_out('<<');
32787 $this->_out('/S /JavaScript ');
32788 $this->_out('/JS '.$this->_textstring($string));
32789 $this->_out('>>');
32790 $this->_out('endobj');
32791}
32792
32793function SetJS($script) {
32794 $this->js = $script;
32795}
32796
32797
32798
32799
32800}//end of Class
32801
32802
32803
32804
32805?> \ No newline at end of file