vendor/mpdf/mpdf/src/Mpdf.php line 1049

Open in your IDE?
  1. <?php
  2. namespace Mpdf;
  3. use Mpdf\Config\ConfigVariables;
  4. use Mpdf\Config\FontVariables;
  5. use Mpdf\Conversion;
  6. use Mpdf\Css\Border;
  7. use Mpdf\Css\TextVars;
  8. use Mpdf\Log\Context as LogContext;
  9. use Mpdf\Fonts\MetricsGenerator;
  10. use Mpdf\Output\Destination;
  11. use Mpdf\PsrLogAwareTrait\MpdfPsrLogAwareTrait;
  12. use Mpdf\QrCode;
  13. use Mpdf\Utils\Arrays;
  14. use Mpdf\Utils\NumericString;
  15. use Mpdf\Utils\UtfString;
  16. use Psr\Log\NullLogger;
  17. /**
  18.  * mPDF, PHP library generating PDF files from UTF-8 encoded HTML
  19.  *
  20.  * based on FPDF by Olivier Plathey
  21.  *      and HTML2FPDF by Renato Coelho
  22.  *
  23.  * @license GPL-2.0
  24.  */
  25. class Mpdf implements \Psr\Log\LoggerAwareInterface
  26. {
  27.     use Strict;
  28.     use FpdiTrait;
  29.     use MpdfPsrLogAwareTrait;
  30.     const VERSION '8.2.4';
  31.     const SCALE 72 25.4;
  32.     const OBJECT_IDENTIFIER "\xbb\xa4\xac";
  33.     var $useFixedNormalLineHeight// mPDF 6
  34.     var $useFixedTextBaseline// mPDF 6
  35.     var $adjustFontDescLineheight// mPDF 6
  36.     var $interpolateImages// mPDF 6
  37.     var $defaultPagebreakType// mPDF 6 pagebreaktype
  38.     var $indexUseSubentries// mPDF 6
  39.     var $autoScriptToLang// mPDF 6
  40.     var $baseScript// mPDF 6
  41.     var $autoVietnamese// mPDF 6
  42.     var $autoArabic// mPDF 6
  43.     var $CJKforceend;
  44.     var $h2bookmarks;
  45.     var $h2toc;
  46.     var $decimal_align;
  47.     var $margBuffer;
  48.     var $splitTableBorderWidth;
  49.     var $bookmarkStyles;
  50.     var $useActiveForms;
  51.     var $repackageTTF;
  52.     var $allowCJKorphans;
  53.     var $allowCJKoverflow;
  54.     var $useKerning;
  55.     var $restrictColorSpace;
  56.     var $bleedMargin;
  57.     var $crossMarkMargin;
  58.     var $cropMarkMargin;
  59.     var $cropMarkLength;
  60.     var $nonPrintMargin;
  61.     var $PDFX;
  62.     var $PDFXauto;
  63.     var $PDFA;
  64.     var $PDFAversion '1-B';
  65.     var $PDFAauto;
  66.     var $ICCProfile;
  67.     var $printers_info;
  68.     var $iterationCounter;
  69.     var $smCapsScale;
  70.     var $smCapsStretch;
  71.     var $backupSubsFont;
  72.     var $backupSIPFont;
  73.     var $fonttrans;
  74.     var $debugfonts;
  75.     var $useAdobeCJK;
  76.     var $percentSubset;
  77.     var $maxTTFFilesize;
  78.     var $BMPonly;
  79.     var $tableMinSizePriority;
  80.     var $dpi;
  81.     var $watermarkImgAlphaBlend;
  82.     var $watermarkImgBehind;
  83.     var $justifyB4br;
  84.     var $packTableData;
  85.     var $pgsIns;
  86.     var $simpleTables;
  87.     var $enableImports;
  88.     var $debug;
  89.     var $setAutoTopMargin;
  90.     var $setAutoBottomMargin;
  91.     var $autoMarginPadding;
  92.     var $collapseBlockMargins;
  93.     var $falseBoldWeight;
  94.     var $normalLineheight;
  95.     var $incrementFPR1;
  96.     var $incrementFPR2;
  97.     var $incrementFPR3;
  98.     var $incrementFPR4;
  99.     var $SHYlang;
  100.     var $SHYleftmin;
  101.     var $SHYrightmin;
  102.     var $SHYcharmin;
  103.     var $SHYcharmax;
  104.     var $SHYlanguages;
  105.     // PageNumber Conditional Text
  106.     var $pagenumPrefix;
  107.     var $pagenumSuffix;
  108.     var $nbpgPrefix;
  109.     var $nbpgSuffix;
  110.     var $showImageErrors;
  111.     var $allow_output_buffering;
  112.     var $autoPadding;
  113.     var $tabSpaces;
  114.     var $autoLangToFont;
  115.     var $watermarkTextAlpha;
  116.     var $watermarkImageAlpha;
  117.     var $watermark_size;
  118.     var $watermark_pos;
  119.     var $annotSize;
  120.     var $annotMargin;
  121.     var $annotOpacity;
  122.     var $title2annots;
  123.     var $keepColumns;
  124.     var $keep_table_proportions;
  125.     var $ignore_table_widths;
  126.     var $ignore_table_percents;
  127.     var $list_number_suffix;
  128.     var $list_auto_mode// mPDF 6
  129.     var $list_indent_first_level// mPDF 6
  130.     var $list_indent_default// mPDF 6
  131.     var $list_indent_default_mpdf;
  132.     var $list_marker_offset// mPDF 6
  133.     var $list_symbol_size;
  134.     var $useSubstitutions;
  135.     var $CSSselectMedia;
  136.     var $forcePortraitHeaders;
  137.     var $forcePortraitMargins;
  138.     var $displayDefaultOrientation;
  139.     var $ignore_invalid_utf8;
  140.     var $allowedCSStags;
  141.     var $onlyCoreFonts;
  142.     var $allow_charset_conversion;
  143.     var $jSWord;
  144.     var $jSmaxChar;
  145.     var $jSmaxCharLast;
  146.     var $jSmaxWordLast;
  147.     var $max_colH_correction;
  148.     var $table_error_report;
  149.     var $table_error_report_param;
  150.     var $biDirectional;
  151.     var $text_input_as_HTML;
  152.     var $anchor2Bookmark;
  153.     var $shrink_tables_to_fit;
  154.     var $allow_html_optional_endtags;
  155.     var $img_dpi;
  156.     var $whitelistStreamWrappers;
  157.     var $defaultheaderfontsize;
  158.     var $defaultheaderfontstyle;
  159.     var $defaultheaderline;
  160.     var $defaultfooterfontsize;
  161.     var $defaultfooterfontstyle;
  162.     var $defaultfooterline;
  163.     var $header_line_spacing;
  164.     var $footer_line_spacing;
  165.     var $pregCJKchars;
  166.     var $pregRTLchars;
  167.     var $pregCURSchars// mPDF 6
  168.     var $mirrorMargins;
  169.     var $watermarkText;
  170.     var $watermarkAngle;
  171.     var $watermarkImage;
  172.     var $showWatermarkText;
  173.     var $showWatermarkImage;
  174.     var $svgAutoFont;
  175.     var $svgClasses;
  176.     var $fontsizes;
  177.     var $defaultPageNumStyle// mPDF 6
  178.     //////////////////////
  179.     // INTERNAL VARIABLES
  180.     //////////////////////
  181.     var $extrapagebreak// mPDF 6 pagebreaktype
  182.     var $uniqstr// mPDF 5.7.2
  183.     var $hasOC;
  184.     var $textvar// mPDF 5.7.1
  185.     var $fontLanguageOverride// mPDF 5.7.1
  186.     var $OTLtags// mPDF 5.7.1
  187.     var $OTLdata;  // mPDF 5.7.1
  188.     var $useDictionaryLBR;
  189.     var $useTibetanLBR;
  190.     var $writingToC;
  191.     var $layers;
  192.     var $layerDetails;
  193.     var $current_layer;
  194.     var $open_layer_pane;
  195.     var $decimal_offset;
  196.     var $inMeter;
  197.     var $CJKleading;
  198.     var $CJKfollowing;
  199.     var $CJKoverflow;
  200.     var $textshadow;
  201.     var $colsums;
  202.     var $spanborder;
  203.     var $spanborddet;
  204.     var $visibility;
  205.     var $kerning;
  206.     var $fixedlSpacing;
  207.     var $minwSpacing;
  208.     var $lSpacingCSS;
  209.     var $wSpacingCSS;
  210.     var $spotColorIDs;
  211.     var $SVGcolors;
  212.     var $spotColors;
  213.     var $defTextColor;
  214.     var $defDrawColor;
  215.     var $defFillColor;
  216.     var $tableBackgrounds;
  217.     var $inlineDisplayOff;
  218.     var $kt_y00;
  219.     var $kt_p00;
  220.     var $upperCase;
  221.     var $checkSIP;
  222.     var $checkSMP;
  223.     var $checkCJK;
  224.     var $watermarkImgAlpha;
  225.     var $PDFAXwarnings;
  226.     var $MetadataRoot;
  227.     var $OutputIntentRoot;
  228.     var $InfoRoot;
  229.     var $associatedFilesRoot;
  230.     var $pdf_version;
  231.     private $fontDir;
  232.     var $tempDir;
  233.     var $cacheCleanupInterval;
  234.     var $allowAnnotationFiles;
  235.     var $fontdata;
  236.     var $noImageFile;
  237.     var $lastblockbottommargin;
  238.     var $baselineC;
  239.     // mPDF 5.7.3  inline text-decoration parameters
  240.     var $baselineSup;
  241.     var $baselineSub;
  242.     var $baselineS;
  243.     var $baselineO;
  244.     var $subPos;
  245.     var $subArrMB;
  246.     var $ReqFontStyle;
  247.     var $tableClipPath;
  248.     var $fullImageHeight;
  249.     var $inFixedPosBlock;  // Internal flag for position:fixed block
  250.     var $fixedPosBlock;  // Buffer string for position:fixed block
  251.     var $fixedPosBlockDepth;
  252.     var $fixedPosBlockBBox;
  253.     var $fixedPosBlockSave;
  254.     var $maxPosL;
  255.     var $maxPosR;
  256.     var $loaded;
  257.     var $extraFontSubsets;
  258.     var $docTemplateStart;  // Internal flag for page (page no. -1) that docTemplate starts on
  259.     var $time0;
  260.     var $hyphenationDictionaryFile;
  261.     var $spanbgcolorarray;
  262.     var $default_font;
  263.     var $headerbuffer;
  264.     var $lastblocklevelchange;
  265.     var $nestedtablejustfinished;
  266.     var $linebreakjustfinished;
  267.     var $cell_border_dominance_L;
  268.     var $cell_border_dominance_R;
  269.     var $cell_border_dominance_T;
  270.     var $cell_border_dominance_B;
  271.     var $table_keep_together;
  272.     var $plainCell_properties;
  273.     var $shrin_k1;
  274.     var $outerfilled;
  275.     var $blockContext;
  276.     var $floatDivs;
  277.     var $patterns;
  278.     var $pageBackgrounds;
  279.     var $bodyBackgroundGradient;
  280.     var $bodyBackgroundImage;
  281.     var $bodyBackgroundColor;
  282.     var $writingHTMLheader// internal flag - used both for writing HTMLHeaders/Footers and FixedPos block
  283.     var $writingHTMLfooter;
  284.     var $angle;
  285.     var $gradients;
  286.     var $kwt_Reference;
  287.     var $kwt_BMoutlines;
  288.     var $kwt_toc;
  289.     var $tbrot_BMoutlines;
  290.     var $tbrot_toc;
  291.     var $col_BMoutlines;
  292.     var $col_toc;
  293.     var $floatbuffer;
  294.     var $floatmargins;
  295.     var $bullet;
  296.     var $bulletarray;
  297.     var $currentLang;
  298.     var $default_lang;
  299.     var $default_available_fonts;
  300.     var $pageTemplate;
  301.     var $docTemplate;
  302.     var $docTemplateContinue;
  303.     var $docTemplateContinue2pages;
  304.     var $arabGlyphs;
  305.     var $arabHex;
  306.     var $persianGlyphs;
  307.     var $persianHex;
  308.     var $arabVowels;
  309.     var $arabPrevLink;
  310.     var $arabNextLink;
  311.     var $formobjects// array of Form Objects for WMF
  312.     var $InlineProperties;
  313.     var $InlineAnnots;
  314.     var $InlineBDF// mPDF 6 Bidirectional formatting
  315.     var $InlineBDFctr// mPDF 6
  316.     var $ktAnnots;
  317.     var $tbrot_Annots;
  318.     var $kwt_Annots;
  319.     var $columnAnnots;
  320.     var $columnForms;
  321.     var $tbrotForms;
  322.     var $PageAnnots;
  323.     var $pageDim// Keep track of page wxh for orientation changes - set in _beginpage, used in _putannots
  324.     var $breakpoints;
  325.     var $tableLevel;
  326.     var $tbctr;
  327.     var $innermostTableLevel;
  328.     var $saveTableCounter;
  329.     var $cellBorderBuffer;
  330.     var $saveHTMLFooter_height;
  331.     var $saveHTMLFooterE_height;
  332.     var $firstPageBoxHeader;
  333.     var $firstPageBoxHeaderEven;
  334.     var $firstPageBoxFooter;
  335.     var $firstPageBoxFooterEven;
  336.     var $page_box;
  337.     var $show_marks// crop or cross marks
  338.     var $basepathIsLocal;
  339.     var $use_kwt;
  340.     var $kwt;
  341.     var $kwt_height;
  342.     var $kwt_y0;
  343.     var $kwt_x0;
  344.     var $kwt_buffer;
  345.     var $kwt_Links;
  346.     var $kwt_moved;
  347.     var $kwt_saved;
  348.     var $PageNumSubstitutions;
  349.     var $table_borders_separate;
  350.     var $base_table_properties;
  351.     var $borderstyles;
  352.     var $blockjustfinished;
  353.     var $orig_bMargin;
  354.     var $orig_tMargin;
  355.     var $orig_lMargin;
  356.     var $orig_rMargin;
  357.     var $orig_hMargin;
  358.     var $orig_fMargin;
  359.     var $pageHTMLheaders;
  360.     var $pageHTMLfooters;
  361.     var $saveHTMLHeader;
  362.     var $saveHTMLFooter;
  363.     var $HTMLheaderPageLinks;
  364.     var $HTMLheaderPageAnnots;
  365.     var $HTMLheaderPageForms;
  366.     // See Config\FontVariables for these next 5 values
  367.     var $available_unifonts;
  368.     var $sans_fonts;
  369.     var $serif_fonts;
  370.     var $mono_fonts;
  371.     var $defaultSubsFont;
  372.     // List of ALL available CJK fonts (incl. styles) (Adobe add-ons)  hw removed
  373.     var $available_CJK_fonts;
  374.     var $HTMLHeader;
  375.     var $HTMLFooter;
  376.     var $HTMLHeaderE;
  377.     var $HTMLFooterE;
  378.     var $bufferoutput;
  379.     // CJK fonts
  380.     var $Big5_widths;
  381.     var $GB_widths;
  382.     var $SJIS_widths;
  383.     var $UHC_widths;
  384.     // SetProtection
  385.     var $encrypted;
  386.     var $enc_obj_id// encryption object id
  387.     // Bookmark
  388.     var $BMoutlines;
  389.     var $OutlineRoot;
  390.     // INDEX
  391.     var $ColActive;
  392.     var $Reference;
  393.     var $CurrCol;
  394.     var $NbCol;
  395.     var $y0;   // Top ordinate of columns
  396.     var $ColL;
  397.     var $ColWidth;
  398.     var $ColGap;
  399.     // COLUMNS
  400.     var $ColR;
  401.     var $ChangeColumn;
  402.     var $columnbuffer;
  403.     var $ColDetails;
  404.     var $columnLinks;
  405.     var $colvAlign;
  406.     // Substitutions
  407.     var $substitute;  // Array of substitution strings e.g. <ttz>112</ttz>
  408.     var $entsearch;  // Array of HTML entities (>ASCII 127) to substitute
  409.     var $entsubstitute// Array of substitution decimal unicode for the Hi entities
  410.     // Default values if no style sheet offered    (cf. http://www.w3.org/TR/CSS21/sample.html)
  411.     var $defaultCSS;
  412.     var $defaultCssFile;
  413.     var $lastoptionaltag// Save current block item which HTML specifies optionsl endtag
  414.     var $pageoutput;
  415.     var $charset_in;
  416.     var $blk;
  417.     var $blklvl;
  418.     var $ColumnAdjust;
  419.     var $ws// Word spacing
  420.     var $HREF;
  421.     var $pgwidth;
  422.     var $fontlist;
  423.     var $oldx;
  424.     var $oldy;
  425.     var $B;
  426.     var $I;
  427.     var $tdbegin;
  428.     var $table;
  429.     var $cell;
  430.     var $col;
  431.     var $row;
  432.     var $divbegin;
  433.     var $divwidth;
  434.     var $divheight;
  435.     var $spanbgcolor;
  436.     // mPDF 6 Used for table cell (block-type) properties
  437.     var $cellTextAlign;
  438.     var $cellLineHeight;
  439.     var $cellLineStackingStrategy;
  440.     var $cellLineStackingShift;
  441.     // mPDF 6  Lists
  442.     var $listcounter;
  443.     var $listlvl;
  444.     var $listtype;
  445.     var $listitem;
  446.     var $pjustfinished;
  447.     var $ignorefollowingspaces;
  448.     var $SMALL;
  449.     var $BIG;
  450.     var $dash_on;
  451.     var $dotted_on;
  452.     var $textbuffer;
  453.     var $currentfontstyle;
  454.     var $currentfontfamily;
  455.     var $currentfontsize;
  456.     var $colorarray;
  457.     var $bgcolorarray;
  458.     var $internallink;
  459.     var $enabledtags;
  460.     var $lineheight;
  461.     var $default_lineheight_correction;
  462.     var $basepath;
  463.     var $textparam;
  464.     var $specialcontent;
  465.     var $selectoption;
  466.     var $objectbuffer;
  467.     // Table Rotation
  468.     var $table_rotate;
  469.     var $tbrot_maxw;
  470.     var $tbrot_maxh;
  471.     var $tablebuffer;
  472.     var $tbrot_align;
  473.     var $tbrot_Links;
  474.     var $keep_block_together// Keep a Block from page-break-inside: avoid
  475.     var $tbrot_y0;
  476.     var $tbrot_x0;
  477.     var $tbrot_w;
  478.     var $tbrot_h;
  479.     var $mb_enc;
  480.     var $originalMbEnc;
  481.     var $originalMbRegexEnc;
  482.     var $directionality;
  483.     var $extgstates// Used for alpha channel - Transparency (Watermark)
  484.     var $mgl;
  485.     var $mgt;
  486.     var $mgr;
  487.     var $mgb;
  488.     var $tts;
  489.     var $ttz;
  490.     var $tta;
  491.     // Best to alter the below variables using default stylesheet above
  492.     var $page_break_after_avoid;
  493.     var $margin_bottom_collapse;
  494.     var $default_font_size// in pts
  495.     var $original_default_font_size// used to save default sizes when using table default
  496.     var $original_default_font;
  497.     var $watermark_font;
  498.     var $defaultAlign;
  499.     // TABLE
  500.     var $defaultTableAlign;
  501.     var $tablethead;
  502.     var $thead_font_weight;
  503.     var $thead_font_style;
  504.     var $thead_font_smCaps;
  505.     var $thead_valign_default;
  506.     var $thead_textalign_default;
  507.     var $tabletfoot;
  508.     var $tfoot_font_weight;
  509.     var $tfoot_font_style;
  510.     var $tfoot_font_smCaps;
  511.     var $tfoot_valign_default;
  512.     var $tfoot_textalign_default;
  513.     var $trow_text_rotate;
  514.     var $cellPaddingL;
  515.     var $cellPaddingR;
  516.     var $cellPaddingT;
  517.     var $cellPaddingB;
  518.     var $table_border_attr_set;
  519.     var $table_border_css_set;
  520.     var $shrin_k// factor with which to shrink tables - used internally - do not change
  521.     var $shrink_this_table_to_fit// 0 or false to disable; value (if set) gives maximum factor to reduce fontsize
  522.     var $MarginCorrection// corrects for OddEven Margins
  523.     var $margin_footer;
  524.     var $margin_header;
  525.     var $tabletheadjustfinished;
  526.     var $usingCoreFont;
  527.     var $charspacing;
  528.     var $js;
  529.     /**
  530.      * Set timeout for cURL
  531.      *
  532.      * @var int
  533.      */
  534.     var $curlTimeout;
  535.     /**
  536.      * Set execution timeout for cURL
  537.      *
  538.      * @var int
  539.      */
  540.     var $curlExecutionTimeout;
  541.     /**
  542.      * Set to true to follow redirects with cURL.
  543.      *
  544.      * @var bool
  545.      */
  546.     var $curlFollowLocation;
  547.     /**
  548.      * Set your own CA certificate store for SSL Certificate verification when using cURL
  549.      *
  550.      * Useful setting to use on hosts with outdated CA certificates.
  551.      *
  552.      * Download the latest CA certificate from https://curl.haxx.se/docs/caextract.html
  553.      *
  554.      * @var string The absolute path to the pem file
  555.      */
  556.     var $curlCaCertificate;
  557.     /**
  558.      * Set to true to allow unsafe SSL HTTPS requests.
  559.      *
  560.      * Can be useful when using CDN with HTTPS and if you don't want to configure settings with SSL certificates.
  561.      *
  562.      * @var bool
  563.      */
  564.     var $curlAllowUnsafeSslRequests;
  565.     /**
  566.      * Set the proxy for cURL.
  567.      *
  568.      * @see https://curl.haxx.se/libcurl/c/CURLOPT_PROXY.html
  569.      *
  570.      * @var string
  571.      */
  572.     var $curlProxy;
  573.     /**
  574.      * Set the proxy auth for cURL.
  575.      *
  576.      * @see https://curl.haxx.se/libcurl/c/CURLOPT_PROXYUSERPWD.html
  577.      *
  578.      * @var string
  579.      */
  580.     var $curlProxyAuth;
  581.     /**
  582.      * Set the User-Agent header in the HTTP requests sent by cURL.
  583.      *
  584.      * @see https://curl.haxx.se/libcurl/c/CURLOPT_USERAGENT.html
  585.      *
  586.      * @var string User Agent header
  587.      */
  588.     var $curlUserAgent;
  589.     // Private properties FROM FPDF
  590.     var $DisplayPreferences;
  591.     var $flowingBlockAttr;
  592.     var $page// current page number
  593.     var $n// current object number
  594.     var $n_js// current object number
  595.     var $n_ocg_hidden;
  596.     var $n_ocg_print;
  597.     var $n_ocg_view;
  598.     var $offsets// array of object offsets
  599.     var $buffer// buffer holding in-memory PDF
  600.     var $pages// array containing pages
  601.     var $state// current document state
  602.     var $compress// compression flag
  603.     var $DefOrientation// default orientation
  604.     var $CurOrientation// current orientation
  605.     var $OrientationChanges// array indicating orientation changes
  606.     var $fwPt;
  607.     var $fhPt// dimensions of page format in points
  608.     var $fw;
  609.     var $fh// dimensions of page format in user unit
  610.     var $wPt;
  611.     var $hPt// current dimensions of page in points
  612.     var $w;
  613.     var $h// current dimensions of page in user unit
  614.     var $lMargin// left margin
  615.     var $tMargin// top margin
  616.     var $rMargin// right margin
  617.     var $bMargin// page break margin
  618.     var $cMarginL// cell margin Left
  619.     var $cMarginR// cell margin Right
  620.     var $cMarginT// cell margin Left
  621.     var $cMarginB// cell margin Right
  622.     var $DeflMargin// Default left margin
  623.     var $DefrMargin// Default right margin
  624.     var $x;
  625.     var $y// current position in user unit for cell positioning
  626.     var $lasth// height of last cell printed
  627.     var $LineWidth// line width in user unit
  628.     var $CoreFonts// array of standard font names
  629.     var $fonts// array of used fonts
  630.     var $FontFiles// array of font files
  631.     var $images// array of used images
  632.     var $imageVars = []; // array of image vars
  633.     var $PageLinks// array of links in pages
  634.     var $links// array of internal links
  635.     var $FontFamily// current font family
  636.     var $FontStyle// current font style
  637.     var $CurrentFont// current font info
  638.     var $FontSizePt// current font size in points
  639.     var $FontSize// current font size in user unit
  640.     var $DrawColor// commands for drawing color
  641.     var $FillColor// commands for filling color
  642.     var $TextColor// commands for text color
  643.     var $ColorFlag// indicates whether fill and text colors are different
  644.     var $autoPageBreak// automatic page breaking
  645.     var $PageBreakTrigger// threshold used to trigger page breaks
  646.     var $InFooter// flag set when processing footer
  647.     var $InHTMLFooter;
  648.     var $processingFooter// flag set when processing footer - added for columns
  649.     var $processingHeader// flag set when processing header - added for columns
  650.     var $ZoomMode// zoom display mode
  651.     var $LayoutMode// layout display mode
  652.     var $title// title
  653.     var $subject// subject
  654.     var $author// author
  655.     var $keywords// keywords
  656.     var $creator// creator
  657.     var $customProperties// array of custom document properties
  658.     var $associatedFiles// associated files (see SetAssociatedFiles below)
  659.     var $additionalXmpRdf// additional rdf added in xmp
  660.     var $aliasNbPg// alias for total number of pages
  661.     var $aliasNbPgGp// alias for total number of pages in page group
  662.     var $ispre;
  663.     var $outerblocktags;
  664.     var $innerblocktags;
  665.     public $exposeVersion;
  666.     private $preambleWritten false;
  667.     private $watermarkTextObject;
  668.     private $watermarkImageObject;
  669.     /**
  670.      * @var string
  671.      */
  672.     private $fontDescriptor;
  673.     /**
  674.      * @var \Mpdf\Otl
  675.      */
  676.     private $otl;
  677.     /**
  678.      * @var \Mpdf\CssManager
  679.      */
  680.     private $cssManager;
  681.     /**
  682.      * @var \Mpdf\Gradient
  683.      */
  684.     private $gradient;
  685.     /**
  686.      * @var \Mpdf\Image\Bmp
  687.      */
  688.     private $bmp;
  689.     /**
  690.      * @var \Mpdf\Image\Wmf
  691.      */
  692.     private $wmf;
  693.     /**
  694.      * @var \Mpdf\TableOfContents
  695.      */
  696.     private $tableOfContents;
  697.     /**
  698.      * @var \Mpdf\Form
  699.      */
  700.     private $form;
  701.     /**
  702.      * @var \Mpdf\DirectWrite
  703.      */
  704.     private $directWrite;
  705.     /**
  706.      * @var \Mpdf\Cache
  707.      */
  708.     private $cache;
  709.     /**
  710.      * @var \Mpdf\Fonts\FontCache
  711.      */
  712.     private $fontCache;
  713.     /**
  714.      * @var \Mpdf\Fonts\FontFileFinder
  715.      */
  716.     private $fontFileFinder;
  717.     /**
  718.      * @var \Mpdf\Tag
  719.      */
  720.     private $tag;
  721.     /**
  722.      * @var \Mpdf\Barcode
  723.      * @todo solve Tag dependency and make private
  724.      */
  725.     public $barcode;
  726.     /**
  727.      * @var \Mpdf\QrCode\QrCode
  728.      */
  729.     private $qrcode;
  730.     /**
  731.      * @var \Mpdf\SizeConverter
  732.      */
  733.     private $sizeConverter;
  734.     /**
  735.      * @var \Mpdf\Color\ColorConverter
  736.      */
  737.     private $colorConverter;
  738.     /**
  739.      * @var \Mpdf\Color\ColorModeConverter
  740.      */
  741.     private $colorModeConverter;
  742.     /**
  743.      * @var \Mpdf\Color\ColorSpaceRestrictor
  744.      */
  745.     private $colorSpaceRestrictor;
  746.     /**
  747.      * @var \Mpdf\Hyphenator
  748.      */
  749.     private $hyphenator;
  750.     /**
  751.      * @var \Mpdf\Pdf\Protection
  752.      */
  753.     private $protection;
  754.     /**
  755.      * @var \Mpdf\Http\ClientInterface
  756.      */
  757.     private $httpClient;
  758.     /**
  759.      * @var \Mpdf\File\LocalContentLoaderInterface
  760.      */
  761.     private $localContentLoader;
  762.     /**
  763.      * @var \Mpdf\AssetFetcher
  764.      */
  765.     private $assetFetcher;
  766.     /**
  767.      * @var \Mpdf\Image\ImageProcessor
  768.      */
  769.     private $imageProcessor;
  770.     /**
  771.      * @var \Mpdf\Language\LanguageToFontInterface
  772.      */
  773.     private $languageToFont;
  774.     /**
  775.      * @var \Mpdf\Language\ScriptToLanguageInterface
  776.      */
  777.     private $scriptToLanguage;
  778.     /**
  779.      * @var \Mpdf\Writer\BaseWriter
  780.      */
  781.     private $writer;
  782.     /**
  783.      * @var \Mpdf\Writer\FontWriter
  784.      */
  785.     private $fontWriter;
  786.     /**
  787.      * @var \Mpdf\Writer\MetadataWriter
  788.      */
  789.     private $metadataWriter;
  790.     /**
  791.      * @var \Mpdf\Writer\ImageWriter
  792.      */
  793.     private $imageWriter;
  794.     /**
  795.      * @var \Mpdf\Writer\FormWriter
  796.      */
  797.     private $formWriter;
  798.     /**
  799.      * @var \Mpdf\Writer\PageWriter
  800.      */
  801.     private $pageWriter;
  802.     /**
  803.      * @var \Mpdf\Writer\BookmarkWriter
  804.      */
  805.     private $bookmarkWriter;
  806.     /**
  807.      * @var \Mpdf\Writer\OptionalContentWriter
  808.      */
  809.     private $optionalContentWriter;
  810.     /**
  811.      * @var \Mpdf\Writer\ColorWriter
  812.      */
  813.     private $colorWriter;
  814.     /**
  815.      * @var \Mpdf\Writer\BackgroundWriter
  816.      */
  817.     private $backgroundWriter;
  818.     /**
  819.      * @var \Mpdf\Writer\JavaScriptWriter
  820.      */
  821.     private $javaScriptWriter;
  822.     /**
  823.      * @var \Mpdf\Writer\ResourceWriter
  824.      */
  825.     private $resourceWriter;
  826.     /**
  827.      * @var string[]
  828.      */
  829.     private $services;
  830.     /**
  831.      * @var \Mpdf\Container\ContainerInterface
  832.      */
  833.     private $container;
  834.     /**
  835.      * @param mixed[] $config
  836.      * @param \Mpdf\Container\ContainerInterface|null $container Experimental container to override internal services
  837.      */
  838.     public function __construct(array $config = [], $container null)
  839.     {
  840.         $this->_dochecks();
  841.         assert(!$container || $container instanceof \Mpdf\Container\ContainerInterface);
  842.         list(
  843.             $mode,
  844.             $format,
  845.             $default_font_size,
  846.             $default_font,
  847.             $mgl,
  848.             $mgr,
  849.             $mgt,
  850.             $mgb,
  851.             $mgh,
  852.             $mgf,
  853.             $orientation
  854.         ) = $this->initConstructorParams($config);
  855.         $this->logger = new NullLogger();
  856.         $originalConfig $config;
  857.         $config $this->initConfig($originalConfig);
  858.         $serviceFactory = new ServiceFactory($container);
  859.         $services $serviceFactory->getServices(
  860.             $this,
  861.             $this->logger,
  862.             $config,
  863.             $this->languageToFont,
  864.             $this->scriptToLanguage,
  865.             $this->fontDescriptor,
  866.             $this->bmp,
  867.             $this->directWrite,
  868.             $this->wmf
  869.         );
  870.         $this->container $container;
  871.         $this->services = [];
  872.         foreach ($services as $key => $service) {
  873.             $this->{$key} = $service;
  874.             $this->services[] = $key;
  875.         }
  876.         $this->time0 microtime(true);
  877.         $this->writingToC false;
  878.         $this->layers = [];
  879.         $this->current_layer 0;
  880.         $this->open_layer_pane false;
  881.         $this->visibility 'visible';
  882.         $this->tableBackgrounds = [];
  883.         $this->uniqstr '20110230'// mPDF 5.7.2
  884.         $this->kt_y00 0;
  885.         $this->kt_p00 0;
  886.         $this->BMPonly = [];
  887.         $this->page 0;
  888.         $this->2;
  889.         $this->buffer '';
  890.         $this->objectbuffer = [];
  891.         $this->pages = [];
  892.         $this->OrientationChanges = [];
  893.         $this->state 0;
  894.         $this->fonts = [];
  895.         $this->FontFiles = [];
  896.         $this->images = [];
  897.         $this->links = [];
  898.         $this->InFooter false;
  899.         $this->processingFooter false;
  900.         $this->processingHeader false;
  901.         $this->lasth 0;
  902.         $this->FontFamily '';
  903.         $this->FontStyle '';
  904.         $this->FontSizePt 9;
  905.         // Small Caps
  906.         $this->inMeter false;
  907.         $this->decimal_offset 0;
  908.         $this->PDFAXwarnings = [];
  909.         $this->defTextColor $this->TextColor $this->SetTColor($this->colorConverter->convert(0$this->PDFAXwarnings), true);
  910.         $this->defDrawColor $this->DrawColor $this->SetDColor($this->colorConverter->convert(0$this->PDFAXwarnings), true);
  911.         $this->defFillColor $this->FillColor $this->SetFColor($this->colorConverter->convert(255$this->PDFAXwarnings), true);
  912.         $this->upperCase = require __DIR__ '/../data/upperCase.php';
  913.         $this->extrapagebreak true// mPDF 6 pagebreaktype
  914.         $this->ColorFlag false;
  915.         $this->extgstates = [];
  916.         $this->mb_enc 'windows-1252';
  917.         $this->originalMbEnc mb_internal_encoding();
  918.         $this->originalMbRegexEnc mb_regex_encoding();
  919.         $this->directionality 'ltr';
  920.         $this->defaultAlign 'L';
  921.         $this->defaultTableAlign 'L';
  922.         $this->fixedPosBlockSave = [];
  923.         $this->extraFontSubsets 0;
  924.         $this->blockContext 1;
  925.         $this->floatDivs = [];
  926.         $this->DisplayPreferences '';
  927.         // Tiling patterns used for backgrounds
  928.         $this->patterns = [];
  929.         $this->pageBackgrounds = [];
  930.         $this->gradients = [];
  931.         // internal flag - used both for writing HTMLHeaders/Footers and FixedPos block
  932.         $this->writingHTMLheader false;
  933.         // internal flag - used both for writing HTMLHeaders/Footers and FixedPos block
  934.         $this->writingHTMLfooter false;
  935.         $this->kwt_Reference = [];
  936.         $this->kwt_BMoutlines = [];
  937.         $this->kwt_toc = [];
  938.         $this->tbrot_BMoutlines = [];
  939.         $this->tbrot_toc = [];
  940.         $this->col_BMoutlines = [];
  941.         $this->col_toc = [];
  942.         $this->pgsIns = [];
  943.         $this->PDFAXwarnings = [];
  944.         $this->inlineDisplayOff false;
  945.         $this->lSpacingCSS '';
  946.         $this->wSpacingCSS '';
  947.         $this->fixedlSpacing false;
  948.         $this->minwSpacing 0;
  949.         // Baseline for text
  950.         $this->baselineC 0.35;
  951.         // mPDF 5.7.3  inline text-decoration parameters
  952.         // Sets default change in baseline for <sup> text as factor of preceeding fontsize
  953.         // 0.35 has been recommended; 0.5 matches applications like MS Word
  954.         $this->baselineSup 0.5;
  955.         // Sets default change in baseline for <sub> text as factor of preceeding fontsize
  956.         $this->baselineSub = -0.2;
  957.         // Sets default height for <strike> text as factor of fontsize
  958.         $this->baselineS 0.3;
  959.         // Sets default height for overline text as factor of fontsize
  960.         $this->baselineO 1.1;
  961.         $this->noImageFile __DIR__ '/../data/no_image.jpg';
  962.         $this->subPos 0;
  963.         $this->fullImageHeight false;
  964.         $this->floatbuffer = [];
  965.         $this->floatmargins = [];
  966.         $this->formobjects = []; // array of Form Objects for WMF
  967.         $this->InlineProperties = [];
  968.         $this->InlineAnnots = [];
  969.         $this->InlineBDF = []; // mPDF 6
  970.         $this->InlineBDFctr 0// mPDF 6
  971.         $this->tbrot_Annots = [];
  972.         $this->kwt_Annots = [];
  973.         $this->columnAnnots = [];
  974.         $this->PageLinks = [];
  975.         $this->OrientationChanges = [];
  976.         $this->pageDim = [];
  977.         $this->saveHTMLHeader = [];
  978.         $this->saveHTMLFooter = [];
  979.         $this->PageAnnots = [];
  980.         $this->PageNumSubstitutions = [];
  981.         $this->breakpoints = []; // used in columnbuffer
  982.         $this->tableLevel 0;
  983.         $this->tbctr = []; // counter for nested tables at each level
  984.         $this->page_box = new PageBox();
  985.         $this->show_marks ''// crop or cross marks
  986.         $this->kwt false;
  987.         $this->kwt_height 0;
  988.         $this->kwt_y0 0;
  989.         $this->kwt_x0 0;
  990.         $this->kwt_buffer = [];
  991.         $this->kwt_Links = [];
  992.         $this->kwt_moved false;
  993.         $this->kwt_saved false;
  994.         $this->PageNumSubstitutions = [];
  995.         $this->base_table_properties = [];
  996.         $this->borderstyles = ['inset''groove''outset''ridge''dotted''dashed''solid''double'];
  997.         $this->tbrot_align 'C';
  998.         $this->pageHTMLheaders = [];
  999.         $this->pageHTMLfooters = [];
  1000.         $this->HTMLheaderPageLinks = [];
  1001.         $this->HTMLheaderPageAnnots = [];
  1002.         $this->HTMLheaderPageForms = [];
  1003.         $this->columnForms = [];
  1004.         $this->tbrotForms = [];
  1005.         $this->pageoutput = [];
  1006.         $this->bufferoutput false;
  1007.         $this->encrypted false;
  1008.         $this->BMoutlines = [];
  1009.         $this->ColActive 0;          // Flag indicating that columns are on (the index is being processed)
  1010.         $this->Reference = [];    // Array containing the references
  1011.         $this->CurrCol 0;               // Current column number
  1012.         $this->ColL = [0];   // Array of Left pos of columns - absolute - needs Margin correction for Odd-Even
  1013.         $this->ColR = [0];   // Array of Right pos of columns - absolute pos - needs Margin correction for Odd-Even
  1014.         $this->ChangeColumn 0;
  1015.         $this->columnbuffer = [];
  1016.         $this->ColDetails = [];  // Keeps track of some column details
  1017.         $this->columnLinks = [];  // Cross references PageLinks
  1018.         $this->substitute = [];  // Array of substitution strings e.g. <ttz>112</ttz>
  1019.         $this->entsearch = [];  // Array of HTML entities (>ASCII 127) to substitute
  1020.         $this->entsubstitute = []; // Array of substitution decimal unicode for the Hi entities
  1021.         $this->lastoptionaltag '';
  1022.         $this->charset_in '';
  1023.         $this->blk = [];
  1024.         $this->blklvl 0;
  1025.         $this->tts false;
  1026.         $this->ttz false;
  1027.         $this->tta false;
  1028.         $this->ispre false;
  1029.         $this->checkSIP false;
  1030.         $this->checkSMP false;
  1031.         $this->checkCJK false;
  1032.         $this->page_break_after_avoid false;
  1033.         $this->margin_bottom_collapse false;
  1034.         $this->tablethead 0;
  1035.         $this->tabletfoot 0;
  1036.         $this->table_border_attr_set 0;
  1037.         $this->table_border_css_set 0;
  1038.         $this->shrin_k 1.0;
  1039.         $this->shrink_this_table_to_fit 0;
  1040.         $this->MarginCorrection 0;
  1041.         $this->tabletheadjustfinished false;
  1042.         $this->usingCoreFont false;
  1043.         $this->charspacing 0;
  1044.         $this->autoPageBreak true;
  1045.         $this->_setPageSize($format$orientation);
  1046.         $this->DefOrientation $orientation;
  1047.         $this->margin_header $mgh;
  1048.         $this->margin_footer $mgf;
  1049.         $bmargin $mgb;
  1050.         $this->DeflMargin $mgl;
  1051.         $this->DefrMargin $mgr;
  1052.         $this->orig_tMargin $mgt;
  1053.         $this->orig_bMargin $bmargin;
  1054.         $this->orig_lMargin $this->DeflMargin;
  1055.         $this->orig_rMargin $this->DefrMargin;
  1056.         $this->orig_hMargin $this->margin_header;
  1057.         $this->orig_fMargin $this->margin_footer;
  1058.         if ($this->setAutoTopMargin == 'pad') {
  1059.             $mgt += $this->margin_header;
  1060.         }
  1061.         if ($this->setAutoBottomMargin == 'pad') {
  1062.             $mgb += $this->margin_footer;
  1063.         }
  1064.         // sets l r t margin
  1065.         $this->SetMargins($this->DeflMargin$this->DefrMargin$mgt);
  1066.         // Automatic page break
  1067.         // sets $this->bMargin & PageBreakTrigger
  1068.         $this->SetAutoPageBreak($this->autoPageBreak$bmargin);
  1069.         $this->pgwidth $this->$this->lMargin $this->rMargin;
  1070.         // Interior cell margin (1 mm) ? not used
  1071.         $this->cMarginL 1;
  1072.         $this->cMarginR 1;
  1073.         // Line width (0.2 mm)
  1074.         $this->LineWidth .567 Mpdf::SCALE;
  1075.         // Enable all tags as default
  1076.         $this->DisableTags();
  1077.         // Full width display mode
  1078.         $this->SetDisplayMode(100); // fullwidth? 'fullpage'
  1079.         // Compression
  1080.         $this->SetCompression(true);
  1081.         // Set default display preferences
  1082.         $this->SetDisplayPreferences('');
  1083.         $this->initFontConfig($originalConfig);
  1084.         // Available fonts
  1085.         $this->available_unifonts = [];
  1086.         foreach ($this->fontdata as $f => $fs) {
  1087.             if (isset($fs['R']) && $fs['R']) {
  1088.                 $this->available_unifonts[] = $f;
  1089.             }
  1090.             if (isset($fs['B']) && $fs['B']) {
  1091.                 $this->available_unifonts[] = $f 'B';
  1092.             }
  1093.             if (isset($fs['I']) && $fs['I']) {
  1094.                 $this->available_unifonts[] = $f 'I';
  1095.             }
  1096.             if (isset($fs['BI']) && $fs['BI']) {
  1097.                 $this->available_unifonts[] = $f 'BI';
  1098.             }
  1099.         }
  1100.         $this->default_available_fonts $this->available_unifonts;
  1101.         $optcore false;
  1102.         $onlyCoreFonts false;
  1103.         if (preg_match('/([\-+])aCJK/i'$mode$m)) {
  1104.             $mode preg_replace('/([\-+])aCJK/i'''$mode); // mPDF 6
  1105.             if ($m[1] == '+') {
  1106.                 $this->useAdobeCJK true;
  1107.             } else {
  1108.                 $this->useAdobeCJK false;
  1109.             }
  1110.         }
  1111.         if (strlen($mode) == 1) {
  1112.             if ($mode == 's') {
  1113.                 $this->percentSubset 100;
  1114.                 $mode '';
  1115.             } elseif ($mode == 'c') {
  1116.                 $onlyCoreFonts true;
  1117.                 $mode '';
  1118.             }
  1119.         } elseif (substr($mode, -2) == '-s') {
  1120.             $this->percentSubset 100;
  1121.             $mode substr($mode0strlen($mode) - 2);
  1122.         } elseif (substr($mode, -2) == '-c') {
  1123.             $onlyCoreFonts true;
  1124.             $mode substr($mode0strlen($mode) - 2);
  1125.         } elseif (substr($mode, -2) == '-x') {
  1126.             $optcore true;
  1127.             $mode substr($mode0strlen($mode) - 2);
  1128.         }
  1129.         // Autodetect if mode is a language_country string (en-GB or en_GB or en)
  1130.         if ($mode && $mode != 'UTF-8') { // mPDF 6
  1131.             list ($coreSuitable$mpdf_pdf_unifont) = $this->languageToFont->getLanguageOptions($mode$this->useAdobeCJK);
  1132.             if ($coreSuitable && $optcore) {
  1133.                 $onlyCoreFonts true;
  1134.             }
  1135.             if ($mpdf_pdf_unifont) {  // mPDF 6
  1136.                 $default_font $mpdf_pdf_unifont;
  1137.             }
  1138.             $this->currentLang $mode;
  1139.             $this->default_lang $mode;
  1140.         }
  1141.         $this->onlyCoreFonts $onlyCoreFonts;
  1142.         if ($this->onlyCoreFonts) {
  1143.             $this->setMBencoding('windows-1252'); // sets $this->mb_enc
  1144.         } else {
  1145.             $this->setMBencoding('UTF-8'); // sets $this->mb_enc
  1146.         }
  1147.         @mb_regex_encoding('UTF-8'); // required only for mb_ereg... and mb_split functions
  1148.         // Adobe CJK fonts
  1149.         $this->available_CJK_fonts = [
  1150.             'gb',
  1151.             'big5',
  1152.             'sjis',
  1153.             'uhc',
  1154.             'gbB',
  1155.             'big5B',
  1156.             'sjisB',
  1157.             'uhcB',
  1158.             'gbI',
  1159.             'big5I',
  1160.             'sjisI',
  1161.             'uhcI',
  1162.             'gbBI',
  1163.             'big5BI',
  1164.             'sjisBI',
  1165.             'uhcBI',
  1166.         ];
  1167.         // Standard fonts
  1168.         $this->CoreFonts = [
  1169.             'ccourier' => 'Courier',
  1170.             'ccourierB' => 'Courier-Bold',
  1171.             'ccourierI' => 'Courier-Oblique',
  1172.             'ccourierBI' => 'Courier-BoldOblique',
  1173.             'chelvetica' => 'Helvetica',
  1174.             'chelveticaB' => 'Helvetica-Bold',
  1175.             'chelveticaI' => 'Helvetica-Oblique',
  1176.             'chelveticaBI' => 'Helvetica-BoldOblique',
  1177.             'ctimes' => 'Times-Roman',
  1178.             'ctimesB' => 'Times-Bold',
  1179.             'ctimesI' => 'Times-Italic',
  1180.             'ctimesBI' => 'Times-BoldItalic',
  1181.             'csymbol' => 'Symbol',
  1182.             'czapfdingbats' => 'ZapfDingbats'
  1183.         ];
  1184.         $this->fontlist = [
  1185.             "ctimes",
  1186.             "ccourier",
  1187.             "chelvetica",
  1188.             "csymbol",
  1189.             "czapfdingbats"
  1190.         ];
  1191.         // Substitutions
  1192.         $this->setHiEntitySubstitutions();
  1193.         if ($this->onlyCoreFonts) {
  1194.             $this->useSubstitutions true;
  1195.             $this->SetSubstitutions();
  1196.         } else {
  1197.             $this->useSubstitutions $config['useSubstitutions'];
  1198.         }
  1199.         if (file_exists($this->defaultCssFile)) {
  1200.             $css file_get_contents($this->defaultCssFile);
  1201.             $this->cssManager->ReadCSS('<style> ' $css ' </style>');
  1202.         } else {
  1203.             throw new \Mpdf\MpdfException(sprintf('Unable to read default CSS file "%s"'$this->defaultCssFile));
  1204.         }
  1205.         if ($default_font == '') {
  1206.             if ($this->onlyCoreFonts) {
  1207.                 if (in_array(strtolower($this->defaultCSS['BODY']['FONT-FAMILY']), $this->mono_fonts)) {
  1208.                     $default_font 'ccourier';
  1209.                 } elseif (in_array(strtolower($this->defaultCSS['BODY']['FONT-FAMILY']), $this->sans_fonts)) {
  1210.                     $default_font 'chelvetica';
  1211.                 } else {
  1212.                     $default_font 'ctimes';
  1213.                 }
  1214.             } else {
  1215.                 $default_font $this->defaultCSS['BODY']['FONT-FAMILY'];
  1216.             }
  1217.         }
  1218.         if (!$default_font_size) {
  1219.             $mmsize $this->sizeConverter->convert($this->defaultCSS['BODY']['FONT-SIZE']);
  1220.             $default_font_size $mmsize * (Mpdf::SCALE);
  1221.         }
  1222.         if ($default_font) {
  1223.             $this->SetDefaultFont($default_font);
  1224.         }
  1225.         if ($default_font_size) {
  1226.             $this->SetDefaultFontSize($default_font_size);
  1227.         }
  1228.         $this->SetLineHeight(); // lineheight is in mm
  1229.         $this->SetFColor($this->colorConverter->convert(255$this->PDFAXwarnings));
  1230.         $this->HREF '';
  1231.         $this->oldy = -1;
  1232.         $this->0;
  1233.         $this->0;
  1234.         // mPDF 6  Lists
  1235.         $this->listlvl 0;
  1236.         $this->listtype = [];
  1237.         $this->listitem = [];
  1238.         $this->listcounter = [];
  1239.         $this->tdbegin false;
  1240.         $this->table = [];
  1241.         $this->cell = [];
  1242.         $this->col = -1;
  1243.         $this->row = -1;
  1244.         $this->cellBorderBuffer = [];
  1245.         $this->divbegin false;
  1246.         // mPDF 6
  1247.         $this->cellTextAlign '';
  1248.         $this->cellLineHeight '';
  1249.         $this->cellLineStackingStrategy '';
  1250.         $this->cellLineStackingShift '';
  1251.         $this->divwidth 0;
  1252.         $this->divheight 0;
  1253.         $this->spanbgcolor false;
  1254.         $this->spanborder false;
  1255.         $this->spanborddet = [];
  1256.         $this->blockjustfinished false;
  1257.         $this->ignorefollowingspaces true// in order to eliminate exceeding left-side spaces
  1258.         $this->dash_on false;
  1259.         $this->dotted_on false;
  1260.         $this->textshadow '';
  1261.         $this->currentfontfamily '';
  1262.         $this->currentfontsize '';
  1263.         $this->currentfontstyle '';
  1264.         $this->colorarray ''// mPDF 6
  1265.         $this->spanbgcolorarray ''// mPDF 6
  1266.         $this->textbuffer = [];
  1267.         $this->internallink = [];
  1268.         $this->basepath "";
  1269.         $this->SetBasePath('');
  1270.         $this->textparam = [];
  1271.         $this->specialcontent '';
  1272.         $this->selectoption = [];
  1273.     }
  1274.     public function cleanup()
  1275.     {
  1276.         mb_internal_encoding($this->originalMbEnc);
  1277.         @mb_regex_encoding($this->originalMbRegexEnc);
  1278.         // this will free up the readers, based on code from Setasign's FpdiTrait::cleanUp()
  1279.         foreach ($this->createdReaders as $id) {
  1280.             $this->readers[$id]->getParser()->getStreamReader()->cleanUp();
  1281.             unset($this->readers[$id]);
  1282.         }
  1283.         $this->createdReaders = [];
  1284.     }
  1285.     private function initConfig(array $config)
  1286.     {
  1287.         $configObject = new ConfigVariables();
  1288.         $defaults $configObject->getDefaults();
  1289.         $config array_intersect_key($config $defaults$defaults);
  1290.         foreach ($config as $var => $val) {
  1291.             $this->{$var} = $val;
  1292.         }
  1293.         return $config;
  1294.     }
  1295.     private function initConstructorParams(array $config)
  1296.     {
  1297.         $constructor = [
  1298.             'mode' => '',
  1299.             'format' => 'A4',
  1300.             'default_font_size' => 0,
  1301.             'default_font' => '',
  1302.             'margin_left' => 15,
  1303.             'margin_right' => 15,
  1304.             'margin_top' => 16,
  1305.             'margin_bottom' => 16,
  1306.             'margin_header' => 9,
  1307.             'margin_footer' => 9,
  1308.             'orientation' => 'P',
  1309.         ];
  1310.         foreach ($constructor as $key => $val) {
  1311.             if (isset($config[$key])) {
  1312.                 $constructor[$key] = $config[$key];
  1313.             }
  1314.         }
  1315.         return array_values($constructor);
  1316.     }
  1317.     private function initFontConfig(array $config)
  1318.     {
  1319.         $configObject = new FontVariables();
  1320.         $defaults $configObject->getDefaults();
  1321.         $config array_intersect_key($config $defaults$defaults);
  1322.         foreach ($config as $var => $val) {
  1323.             $this->{$var} = $val;
  1324.         }
  1325.         return $config;
  1326.     }
  1327.     function _setPageSize($format, &$orientation)
  1328.     {
  1329.         if (is_string($format)) {
  1330.             if (empty($format)) {
  1331.                 $format 'A4';
  1332.             }
  1333.             // e.g. A4-L = A4 landscape, A4-P = A4 portrait
  1334.             $orientation $orientation ?: 'P';
  1335.             if (preg_match('/([0-9a-zA-Z]*)-([P,L])/i'$format$m)) {
  1336.                 list(, $format$orientation) = $m;
  1337.             }
  1338.             $format PageFormat::getSizeFromName($format);
  1339.             $this->fwPt $format[0];
  1340.             $this->fhPt $format[1];
  1341.         } else {
  1342.             if (!$format[0] || !$format[1]) {
  1343.                 throw new \Mpdf\MpdfException('Invalid page format: ' $format[0] . ' ' $format[1]);
  1344.             }
  1345.             $this->fwPt $format[0] * Mpdf::SCALE;
  1346.             $this->fhPt $format[1] * Mpdf::SCALE;
  1347.         }
  1348.         $this->fw $this->fwPt Mpdf::SCALE;
  1349.         $this->fh $this->fhPt Mpdf::SCALE;
  1350.         // Page orientation
  1351.         $orientation strtolower($orientation);
  1352.         if ($orientation === 'p' || $orientation === 'portrait') {
  1353.             $orientation 'P';
  1354.             $this->wPt $this->fwPt;
  1355.             $this->hPt $this->fhPt;
  1356.         } elseif ($orientation === 'l' || $orientation === 'landscape') {
  1357.             $orientation 'L';
  1358.             $this->wPt $this->fhPt;
  1359.             $this->hPt $this->fwPt;
  1360.         } else {
  1361.             throw new \Mpdf\MpdfException('Incorrect orientation: ' $orientation);
  1362.         }
  1363.         $this->CurOrientation $orientation;
  1364.         $this->$this->wPt Mpdf::SCALE;
  1365.         $this->$this->hPt Mpdf::SCALE;
  1366.     }
  1367.     function RestrictUnicodeFonts($res)
  1368.     {
  1369.         // $res = array of (Unicode) fonts to restrict to: e.g. norasi|norasiB - language specific
  1370.         if (count($res)) { // Leave full list of available fonts if passed blank array
  1371.             $this->available_unifonts $res;
  1372.         } else {
  1373.             $this->available_unifonts $this->default_available_fonts;
  1374.         }
  1375.         if (count($this->available_unifonts) == 0) {
  1376.             $this->available_unifonts[] = $this->default_available_fonts[0];
  1377.         }
  1378.         $this->available_unifonts array_values($this->available_unifonts);
  1379.     }
  1380.     function setMBencoding($enc)
  1381.     {
  1382.         if ($this->mb_enc != $enc) {
  1383.             $this->mb_enc $enc;
  1384.             mb_internal_encoding($this->mb_enc);
  1385.         }
  1386.     }
  1387.     function SetMargins($left$right$top)
  1388.     {
  1389.         // Set left, top and right margins
  1390.         $this->lMargin $left;
  1391.         $this->rMargin $right;
  1392.         $this->tMargin $top;
  1393.     }
  1394.     function ResetMargins()
  1395.     {
  1396.         // ReSet left, top margins
  1397.         if (($this->forcePortraitHeaders || $this->forcePortraitMargins) && $this->DefOrientation == 'P' && $this->CurOrientation == 'L') {
  1398.             if (($this->mirrorMargins) && (($this->page) % == 0)) { // EVEN
  1399.                 $this->tMargin $this->orig_rMargin;
  1400.                 $this->bMargin $this->orig_lMargin;
  1401.             } else { // ODD    // OR NOT MIRRORING MARGINS/FOOTERS
  1402.                 $this->tMargin $this->orig_lMargin;
  1403.                 $this->bMargin $this->orig_rMargin;
  1404.             }
  1405.             $this->lMargin $this->DeflMargin;
  1406.             $this->rMargin $this->DefrMargin;
  1407.             $this->MarginCorrection 0;
  1408.             $this->PageBreakTrigger $this->$this->bMargin;
  1409.         } elseif (($this->mirrorMargins) && (($this->page) % == 0)) { // EVEN
  1410.             $this->lMargin $this->DefrMargin;
  1411.             $this->rMargin $this->DeflMargin;
  1412.             $this->MarginCorrection $this->DefrMargin $this->DeflMargin;
  1413.         } else { // ODD    // OR NOT MIRRORING MARGINS/FOOTERS
  1414.             $this->lMargin $this->DeflMargin;
  1415.             $this->rMargin $this->DefrMargin;
  1416.             if ($this->mirrorMargins) {
  1417.                 $this->MarginCorrection $this->DeflMargin $this->DefrMargin;
  1418.             }
  1419.         }
  1420.         $this->$this->lMargin;
  1421.     }
  1422.     function SetLeftMargin($margin)
  1423.     {
  1424.         // Set left margin
  1425.         $this->lMargin $margin;
  1426.         if ($this->page and $this->$margin) {
  1427.             $this->$margin;
  1428.         }
  1429.     }
  1430.     function SetTopMargin($margin)
  1431.     {
  1432.         // Set top margin
  1433.         $this->tMargin $margin;
  1434.     }
  1435.     function SetRightMargin($margin)
  1436.     {
  1437.         // Set right margin
  1438.         $this->rMargin $margin;
  1439.     }
  1440.     function SetAutoPageBreak($auto$margin 0)
  1441.     {
  1442.         // Set auto page break mode and triggering margin
  1443.         $this->autoPageBreak $auto;
  1444.         $this->bMargin $margin;
  1445.         $this->PageBreakTrigger $this->$margin;
  1446.     }
  1447.     function SetDisplayMode($zoom$layout 'continuous')
  1448.     {
  1449.         $allowedZoomModes = ['fullpage''fullwidth''real''default''none'];
  1450.         if (in_array($zoom$allowedZoomModestrue) || is_numeric($zoom)) {
  1451.             $this->ZoomMode $zoom;
  1452.         } else {
  1453.             throw new \Mpdf\MpdfException('Incorrect zoom display mode: ' $zoom);
  1454.         }
  1455.         $allowedLayoutModes = ['single''continuous''two''twoleft''tworight''default'];
  1456.         if (in_array($layout$allowedLayoutModestrue)) {
  1457.             $this->LayoutMode $layout;
  1458.         } else {
  1459.             throw new \Mpdf\MpdfException('Incorrect layout display mode: ' $layout);
  1460.         }
  1461.     }
  1462.     function SetCompression($compress)
  1463.     {
  1464.         // Set page compression
  1465.         if (function_exists('gzcompress')) {
  1466.             $this->compress $compress;
  1467.         } else {
  1468.             $this->compress false;
  1469.         }
  1470.     }
  1471.     function SetTitle($title)
  1472.     {
  1473.         // Title of document // Arrives as UTF-8
  1474.         $this->title $title;
  1475.     }
  1476.     function SetSubject($subject)
  1477.     {
  1478.         // Subject of document
  1479.         $this->subject $subject;
  1480.     }
  1481.     function SetAuthor($author)
  1482.     {
  1483.         // Author of document
  1484.         $this->author $author;
  1485.     }
  1486.     function SetKeywords($keywords)
  1487.     {
  1488.         // Keywords of document
  1489.         $this->keywords $keywords;
  1490.     }
  1491.     function SetCreator($creator)
  1492.     {
  1493.         // Creator of document
  1494.         $this->creator $creator;
  1495.     }
  1496.     function AddCustomProperty($key$value)
  1497.     {
  1498.         $this->customProperties[$key] = $value;
  1499.     }
  1500.     /**
  1501.      * Set one or multiple associated file ("/AF" as required by PDF/A-3)
  1502.      *
  1503.      * param $files is an array of hash containing:
  1504.      *   path: file path on FS
  1505.      *   content: file content
  1506.      *   name: file name (not necessarily the same as the file on FS)
  1507.      *   mime (optional): file mime type (will show up as /Subtype in the PDF)
  1508.      *   description (optional): file description
  1509.      *   AFRelationship (optional): PDF/A-3 AFRelationship (e.g. "Alternative")
  1510.      *
  1511.      * e.g. to associate 1 file:
  1512.      *     [[
  1513.      *         'path' => 'tmp/1234.xml',
  1514.      *         'content' => 'file content',
  1515.      *         'name' => 'public_name.xml',
  1516.      *         'mime' => 'text/xml',
  1517.      *         'description' => 'foo',
  1518.      *         'AFRelationship' => 'Alternative',
  1519.      *     ]]
  1520.      *
  1521.      * @param mixed[] $files Array of arrays of associated files. See above
  1522.      */
  1523.     function SetAssociatedFiles(array $files)
  1524.     {
  1525.         $this->associatedFiles $files;
  1526.     }
  1527.     function SetAdditionalXmpRdf($s)
  1528.     {
  1529.         $this->additionalXmpRdf $s;
  1530.     }
  1531.     function SetAnchor2Bookmark($x)
  1532.     {
  1533.         $this->anchor2Bookmark $x;
  1534.     }
  1535.     public function AliasNbPages($alias '{nb}')
  1536.     {
  1537.         // Define an alias for total number of pages
  1538.         $this->aliasNbPg $alias;
  1539.     }
  1540.     public function AliasNbPageGroups($alias '{nbpg}')
  1541.     {
  1542.         // Define an alias for total number of pages in a group
  1543.         $this->aliasNbPgGp $alias;
  1544.     }
  1545.     function SetAlpha($alpha$bm 'Normal'$return false$mode 'B')
  1546.     {
  1547.         // alpha: real value from 0 (transparent) to 1 (opaque)
  1548.         // bm:    blend mode, one of the following:
  1549.         //          Normal, Multiply, Screen, Overlay, Darken, Lighten, ColorDodge, ColorBurn,
  1550.         //          HardLight, SoftLight, Difference, Exclusion, Hue, Saturation, Color, Luminosity
  1551.         // set alpha for stroking (CA) and non-stroking (ca) operations
  1552.         // mode determines F (fill) S (stroke) B (both)
  1553.         if (($this->PDFA || $this->PDFX) && $alpha != 1) {
  1554.             if (($this->PDFA && !$this->PDFAauto) || ($this->PDFX && !$this->PDFXauto)) {
  1555.                 $this->PDFAXwarnings[] = "Image opacity must be 100% (Opacity changed to 100%)";
  1556.             }
  1557.             $alpha 1;
  1558.         }
  1559.         $a = ['BM' => '/' $bm];
  1560.         if ($mode == 'F' || $mode == 'B') {
  1561.             $a['ca'] = $alpha// mPDF 5.7.2
  1562.         }
  1563.         if ($mode == 'S' || $mode == 'B') {
  1564.             $a['CA'] = $alpha// mPDF 5.7.2
  1565.         }
  1566.         $gs $this->AddExtGState($a);
  1567.         if ($return) {
  1568.             return sprintf('/GS%d gs'$gs);
  1569.         } else {
  1570.             $this->writer->write(sprintf('/GS%d gs'$gs));
  1571.         }
  1572.     }
  1573.     function AddExtGState($parms)
  1574.     {
  1575.         $n count($this->extgstates);
  1576.         // check if graphics state already exists
  1577.         for ($i 1$i <= $n$i++) {
  1578.             if (count($this->extgstates[$i]['parms']) == count($parms)) {
  1579.                 $same true;
  1580.                 foreach ($this->extgstates[$i]['parms'] as $k => $v) {
  1581.                     if (!isset($parms[$k]) || $parms[$k] != $v) {
  1582.                         $same false;
  1583.                         break;
  1584.                     }
  1585.                 }
  1586.                 if ($same) {
  1587.                     return $i;
  1588.                 }
  1589.             }
  1590.         }
  1591.         $n++;
  1592.         $this->extgstates[$n]['parms'] = $parms;
  1593.         return $n;
  1594.     }
  1595.     function SetVisibility($v)
  1596.     {
  1597.         if (($this->PDFA || $this->PDFX) && $this->visibility != 'visible') {
  1598.             $this->PDFAXwarnings[] = "Cannot set visibility to anything other than full when using PDFA or PDFX";
  1599.             return '';
  1600.         } elseif (!$this->PDFA && !$this->PDFX) {
  1601.             $this->pdf_version '1.5';
  1602.         }
  1603.         if ($this->visibility != 'visible') {
  1604.             $this->writer->write('EMC');
  1605.             $this->hasOC intval($this->hasOC);
  1606.         }
  1607.         if ($v == 'printonly') {
  1608.             $this->writer->write('/OC /OC1 BDC');
  1609.             $this->hasOC = ($this->hasOC 1);
  1610.         } elseif ($v == 'screenonly') {
  1611.             $this->writer->write('/OC /OC2 BDC');
  1612.             $this->hasOC = ($this->hasOC 2);
  1613.         } elseif ($v == 'hidden') {
  1614.             $this->writer->write('/OC /OC3 BDC');
  1615.             $this->hasOC = ($this->hasOC 4);
  1616.         } elseif ($v != 'visible') {
  1617.             throw new \Mpdf\MpdfException('Incorrect visibility: ' $v);
  1618.         }
  1619.         $this->visibility $v;
  1620.     }
  1621.     function Open()
  1622.     {
  1623.         // Begin document
  1624.         if ($this->state == 0) {
  1625.             $this->state 1;
  1626.             if (false === $this->preambleWritten) {
  1627.                 $this->writer->write('%PDF-' $this->pdf_version);
  1628.                 $this->writer->write('%' chr(226) . chr(227) . chr(207) . chr(211)); // 4 chars > 128 to show binary file
  1629.                 $this->preambleWritten true;
  1630.             }
  1631.         }
  1632.     }
  1633.     function Close()
  1634.     {
  1635.         // @log Closing last page
  1636.         // Terminate document
  1637.         if ($this->state == 3) {
  1638.             return;
  1639.         }
  1640.         if ($this->page == 0) {
  1641.             $this->AddPage($this->CurOrientation);
  1642.         }
  1643.         if (count($this->cellBorderBuffer)) {
  1644.             $this->printcellbuffer();
  1645.         }
  1646.         // *TABLES*
  1647.         if ($this->tablebuffer) {
  1648.             $this->printtablebuffer();
  1649.         }
  1650.         /* -- COLUMNS -- */
  1651.         if ($this->ColActive) {
  1652.             $this->SetColumns(0);
  1653.             $this->ColActive 0;
  1654.             if (count($this->columnbuffer)) {
  1655.                 $this->printcolumnbuffer();
  1656.             }
  1657.         }
  1658.         /* -- END COLUMNS -- */
  1659.         // BODY Backgrounds
  1660.         $s '';
  1661.         $s .= $this->PrintBodyBackgrounds();
  1662.         $s .= $this->PrintPageBackgrounds();
  1663.         $this->pages[$this->page] = preg_replace(
  1664.             '/(___BACKGROUND___PATTERNS' $this->uniqstr ')/',
  1665.             "\n" $s "\n" '\\1',
  1666.             $this->pages[$this->page]
  1667.         );
  1668.         $this->pageBackgrounds = [];
  1669.         if ($this->visibility != 'visible') {
  1670.             $this->SetVisibility('visible');
  1671.         }
  1672.         $this->EndLayer();
  1673.         if (!$this->tableOfContents->TOCmark) { // Page footer
  1674.             $this->InFooter true;
  1675.             $this->Footer();
  1676.             $this->InFooter false;
  1677.         }
  1678.         if ($this->tableOfContents->TOCmark || count($this->tableOfContents->m_TOC)) {
  1679.             $this->tableOfContents->insertTOC();
  1680.         }
  1681.         // Close page
  1682.         $this->_endpage();
  1683.         // Close document
  1684.         $this->_enddoc();
  1685.     }
  1686.     /* -- BACKGROUNDS -- */
  1687.     function _resizeBackgroundImage($imw$imh$cw$ch$resize$repx$repy$pba = [], $size = [])
  1688.     {
  1689.         // pba is background positioning area (from CSS background-origin) may not always be set [x,y,w,h]
  1690.         // size is from CSS3 background-size - takes precendence over old resize
  1691.         // $w - absolute length or % or auto or cover | contain
  1692.         // $h - absolute length or % or auto or cover | contain
  1693.         if (isset($pba['w'])) {
  1694.             $cw $pba['w'];
  1695.         }
  1696.         if (isset($pba['h'])) {
  1697.             $ch $pba['h'];
  1698.         }
  1699.         $cw $cw Mpdf::SCALE;
  1700.         $ch $ch Mpdf::SCALE;
  1701.         if (empty($size) && !$resize) {
  1702.             return [$imw$imh$repx$repy];
  1703.         }
  1704.         if (isset($size['w']) && $size['w']) {
  1705.             if ($size['w'] == 'contain') {
  1706.                 // Scale the image, while preserving its intrinsic aspect ratio (if any),
  1707.                 // to the largest size such that both its width and its height can fit inside the background positioning area.
  1708.                 // Same as resize==3
  1709.                 $h $imh $cw $imw;
  1710.                 $w $cw;
  1711.                 if ($h $ch) {
  1712.                     $w $w $ch $h;
  1713.                     $h $ch;
  1714.                 }
  1715.             } elseif ($size['w'] == 'cover') {
  1716.                 // Scale the image, while preserving its intrinsic aspect ratio (if any),
  1717.                 // to the smallest size such that both its width and its height can completely cover the background positioning area.
  1718.                 $h $imh $cw $imw;
  1719.                 $w $cw;
  1720.                 if ($h $ch) {
  1721.                     $w $w $h $ch;
  1722.                     $h $ch;
  1723.                 }
  1724.             } else {
  1725.                 if (stristr($size['w'], '%')) {
  1726.                     $size['w'] = (float) $size['w'];
  1727.                     $size['w'] /= 100;
  1728.                     $size['w'] = ($cw $size['w']);
  1729.                 }
  1730.                 if (stristr($size['h'], '%')) {
  1731.                     $size['h'] = (float) $size['h'];
  1732.                     $size['h'] /= 100;
  1733.                     $size['h'] = ($ch $size['h']);
  1734.                 }
  1735.                 if ($size['w'] == 'auto' && $size['h'] == 'auto') {
  1736.                     $w $imw;
  1737.                     $h $imh;
  1738.                 } elseif ($size['w'] == 'auto' && $size['h'] != 'auto') {
  1739.                     $w $imw $size['h'] / $imh;
  1740.                     $h $size['h'];
  1741.                 } elseif ($size['w'] != 'auto' && $size['h'] == 'auto') {
  1742.                     $h $imh $size['w'] / $imw;
  1743.                     $w $size['w'];
  1744.                 } else {
  1745.                     $w $size['w'];
  1746.                     $h $size['h'];
  1747.                 }
  1748.             }
  1749.             return [$w$h$repx$repy];
  1750.         } elseif ($resize == && $imw $cw) {
  1751.             $h $imh $cw $imw;
  1752.             return [$cw$h$repx$repy];
  1753.         } elseif ($resize == && $imh $ch) {
  1754.             $w $imw $ch $imh;
  1755.             return [$w$ch$repx$repy];
  1756.         } elseif ($resize == 3) {
  1757.             $w $imw;
  1758.             $h $imh;
  1759.             if ($w $cw) {
  1760.                 $h $h $cw $w;
  1761.                 $w $cw;
  1762.             }
  1763.             if ($h $ch) {
  1764.                 $w $w $ch $h;
  1765.                 $h $ch;
  1766.             }
  1767.             return [$w$h$repx$repy];
  1768.         } elseif ($resize == 4) {
  1769.             $h $imh $cw $imw;
  1770.             return [$cw$h$repx$repy];
  1771.         } elseif ($resize == 5) {
  1772.             $w $imw $ch $imh;
  1773.             return [$w$ch$repx$repy];
  1774.         } elseif ($resize == 6) {
  1775.             return [$cw$ch$repx$repy];
  1776.         }
  1777.         return [$imw$imh$repx$repy];
  1778.     }
  1779.     function SetBackground(&$properties, &$maxwidth)
  1780.     {
  1781.         if (isset($properties['BACKGROUND-ORIGIN']) && ($properties['BACKGROUND-ORIGIN'] == 'border-box' || $properties['BACKGROUND-ORIGIN'] == 'content-box')) {
  1782.             $origin $properties['BACKGROUND-ORIGIN'];
  1783.         } else {
  1784.             $origin 'padding-box';
  1785.         }
  1786.         if (isset($properties['BACKGROUND-SIZE'])) {
  1787.             if (stristr($properties['BACKGROUND-SIZE'], 'contain')) {
  1788.                 $bsw $bsh 'contain';
  1789.             } elseif (stristr($properties['BACKGROUND-SIZE'], 'cover')) {
  1790.                 $bsw $bsh 'cover';
  1791.             } else {
  1792.                 $bsw $bsh 'auto';
  1793.                 $sz preg_split('/\s+/'trim($properties['BACKGROUND-SIZE']));
  1794.                 if (count($sz) == 2) {
  1795.                     $bsw $sz[0];
  1796.                     $bsh $sz[1];
  1797.                 } else {
  1798.                     $bsw $sz[0];
  1799.                 }
  1800.                 if (!stristr($bsw'%') && !stristr($bsw'auto')) {
  1801.                     $bsw $this->sizeConverter->convert($bsw$maxwidth$this->FontSize);
  1802.                 }
  1803.                 if (!stristr($bsh'%') && !stristr($bsh'auto')) {
  1804.                     $bsh $this->sizeConverter->convert($bsh$maxwidth$this->FontSize);
  1805.                 }
  1806.             }
  1807.             $size = ['w' => $bsw'h' => $bsh];
  1808.         } else {
  1809.             $size false;
  1810.         } // mPDF 6
  1811.         if (preg_match('/(-moz-)*(repeating-)*(linear|radial)-gradient/'$properties['BACKGROUND-IMAGE'])) {
  1812.             return ['gradient' => $properties['BACKGROUND-IMAGE'], 'origin' => $origin'size' => $size];
  1813.         } else {
  1814.             $file $properties['BACKGROUND-IMAGE'];
  1815.             $sizesarray $this->Image($file0000''''falsefalsefalsefalsetrue);
  1816.             if (isset($sizesarray['IMAGE_ID'])) {
  1817.                 $image_id $sizesarray['IMAGE_ID'];
  1818.                 $orig_w $sizesarray['WIDTH'] * Mpdf::SCALE;  // in user units i.e. mm
  1819.                 $orig_h $sizesarray['HEIGHT'] * Mpdf::SCALE;  // (using $this->img_dpi)
  1820.                 if (isset($properties['BACKGROUND-IMAGE-RESOLUTION'])) {
  1821.                     if (preg_match('/from-image/i'$properties['BACKGROUND-IMAGE-RESOLUTION']) && isset($sizesarray['set-dpi']) && $sizesarray['set-dpi'] > 0) {
  1822.                         $orig_w *= $this->img_dpi $sizesarray['set-dpi'];
  1823.                         $orig_h *= $this->img_dpi $sizesarray['set-dpi'];
  1824.                     } elseif (preg_match('/(\d+)dpi/i'$properties['BACKGROUND-IMAGE-RESOLUTION'], $m)) {
  1825.                         $dpi $m[1];
  1826.                         if ($dpi 0) {
  1827.                             $orig_w *= $this->img_dpi $dpi;
  1828.                             $orig_h *= $this->img_dpi $dpi;
  1829.                         }
  1830.                     }
  1831.                 }
  1832.                 $x_repeat true;
  1833.                 $y_repeat true;
  1834.                 if (isset($properties['BACKGROUND-REPEAT'])) {
  1835.                     if ($properties['BACKGROUND-REPEAT'] == 'no-repeat' || $properties['BACKGROUND-REPEAT'] == 'repeat-x') {
  1836.                         $y_repeat false;
  1837.                     }
  1838.                     if ($properties['BACKGROUND-REPEAT'] == 'no-repeat' || $properties['BACKGROUND-REPEAT'] == 'repeat-y') {
  1839.                         $x_repeat false;
  1840.                     }
  1841.                 }
  1842.                 $x_pos 0;
  1843.                 $y_pos 0;
  1844.                 if (isset($properties['BACKGROUND-POSITION'])) {
  1845.                     $ppos preg_split('/\s+/'$properties['BACKGROUND-POSITION']);
  1846.                     $x_pos $ppos[0];
  1847.                     $y_pos $ppos[1];
  1848.                     if (!stristr($x_pos'%')) {
  1849.                         $x_pos $this->sizeConverter->convert($x_pos$maxwidth$this->FontSize);
  1850.                     }
  1851.                     if (!stristr($y_pos'%')) {
  1852.                         $y_pos $this->sizeConverter->convert($y_pos$maxwidth$this->FontSize);
  1853.                     }
  1854.                 }
  1855.                 if (isset($properties['BACKGROUND-IMAGE-RESIZE'])) {
  1856.                     $resize $properties['BACKGROUND-IMAGE-RESIZE'];
  1857.                 } else {
  1858.                     $resize 0;
  1859.                 }
  1860.                 if (isset($properties['BACKGROUND-IMAGE-OPACITY'])) {
  1861.                     $opacity $properties['BACKGROUND-IMAGE-OPACITY'];
  1862.                 } else {
  1863.                     $opacity 1;
  1864.                 }
  1865.                 return ['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];
  1866.             }
  1867.         }
  1868.         return false;
  1869.     }
  1870.     /* -- END BACKGROUNDS -- */
  1871.     function PrintBodyBackgrounds()
  1872.     {
  1873.         $s '';
  1874.         $clx 0;
  1875.         $cly 0;
  1876.         $clw $this->w;
  1877.         $clh $this->h;
  1878.         // If using bleed and trim margins in paged media
  1879.         if ($this->pageDim[$this->page]['outer_width_LR'] || $this->pageDim[$this->page]['outer_width_TB']) {
  1880.             $clx $this->pageDim[$this->page]['outer_width_LR'] - $this->pageDim[$this->page]['bleedMargin'];
  1881.             $cly $this->pageDim[$this->page]['outer_width_TB'] - $this->pageDim[$this->page]['bleedMargin'];
  1882.             $clw $this->$clx;
  1883.             $clh $this->$cly;
  1884.         }
  1885.         if ($this->bodyBackgroundColor) {
  1886.             $s .= 'q ' $this->SetFColor($this->bodyBackgroundColortrue) . "\n";
  1887.             if ($this->bodyBackgroundColor[0] == 5) { // RGBa
  1888.                 $s .= $this->SetAlpha(ord($this->bodyBackgroundColor[4]) / 100'Normal'true'F') . "\n";
  1889.             } elseif ($this->bodyBackgroundColor[0] == 6) { // CMYKa
  1890.                 $s .= $this->SetAlpha(ord($this->bodyBackgroundColor[5]) / 100'Normal'true'F') . "\n";
  1891.             }
  1892.             $s .= sprintf('%.3F %.3F %.3F %.3F re f Q', ($clx Mpdf::SCALE), ($cly Mpdf::SCALE), $clw Mpdf::SCALE$clh Mpdf::SCALE) . "\n";
  1893.         }
  1894.         /* -- BACKGROUNDS -- */
  1895.         if ($this->bodyBackgroundGradient) {
  1896.             $g $this->gradient->parseBackgroundGradient($this->bodyBackgroundGradient);
  1897.             if ($g) {
  1898.                 $s .= $this->gradient->Gradient($clx$cly$clw$clh, (isset($g['gradtype']) ? $g['gradtype'] : null), $g['stops'], $g['colorspace'], $g['coords'], $g['extend'], true);
  1899.             }
  1900.         }
  1901.         if ($this->bodyBackgroundImage) {
  1902.             if (isset($this->bodyBackgroundImage['gradient']) && $this->bodyBackgroundImage['gradient'] && preg_match('/(-moz-)*(repeating-)*(linear|radial)-gradient/'$this->bodyBackgroundImage['gradient'])) {
  1903.                 $g $this->gradient->parseMozGradient($this->bodyBackgroundImage['gradient']);
  1904.                 if ($g) {
  1905.                     $s .= $this->gradient->Gradient($clx$cly$clw$clh$g['type'], $g['stops'], $g['colorspace'], $g['coords'], $g['extend'], true);
  1906.                 }
  1907.             } elseif ($this->bodyBackgroundImage['image_id']) { // Background pattern
  1908.                 $n count($this->patterns) + 1;
  1909.                 // If using resize, uses TrimBox (not including the bleed)
  1910.                 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']);
  1911.                 $this->patterns[$n] = ['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']];
  1912.                 if (($this->bodyBackgroundImage['opacity'] > || $this->bodyBackgroundImage['opacity'] === '0') && $this->bodyBackgroundImage['opacity'] < 1) {
  1913.                     $opac $this->SetAlpha($this->bodyBackgroundImage['opacity'], 'Normal'true);
  1914.                 } else {
  1915.                     $opac '';
  1916.                 }
  1917.                 $s .= sprintf('q /Pattern cs /P%d scn %s %.3F %.3F %.3F %.3F re f Q'$n$opac, ($clx Mpdf::SCALE), ($cly Mpdf::SCALE), $clw Mpdf::SCALE$clh Mpdf::SCALE) . "\n";
  1918.             }
  1919.         }
  1920.         /* -- END BACKGROUNDS -- */
  1921.         return $s;
  1922.     }
  1923.     function _setClippingPath($clx$cly$clw$clh)
  1924.     {
  1925.         $s ' q 0 w '// Line width=0
  1926.         $s .= sprintf('%.3F %.3F m ', ($clx) * Mpdf::SCALE, ($this->- ($cly)) * Mpdf::SCALE); // start point TL before the arc
  1927.         $s .= sprintf('%.3F %.3F l ', ($clx) * Mpdf::SCALE, ($this->- ($cly $clh)) * Mpdf::SCALE); // line to BL
  1928.         $s .= sprintf('%.3F %.3F l ', ($clx $clw) * Mpdf::SCALE, ($this->- ($cly $clh)) * Mpdf::SCALE); // line to BR
  1929.         $s .= sprintf('%.3F %.3F l ', ($clx $clw) * Mpdf::SCALE, ($this->- ($cly)) * Mpdf::SCALE); // line to TR
  1930.         $s .= sprintf('%.3F %.3F l ', ($clx) * Mpdf::SCALE, ($this->- ($cly)) * Mpdf::SCALE); // line to TL
  1931.         $s .= ' W n '// Ends path no-op & Sets the clipping path
  1932.         return $s;
  1933.     }
  1934.     function PrintPageBackgrounds($adjustmenty 0)
  1935.     {
  1936.         $s '';
  1937.         ksort($this->pageBackgrounds);
  1938.         foreach ($this->pageBackgrounds as $bl => $pbs) {
  1939.             foreach ($pbs as $pb) {
  1940.                 if ((!isset($pb['image_id']) && !isset($pb['gradient'])) || isset($pb['shadowonly'])) { // Background colour or boxshadow
  1941.                     if ($pb['z-index'] > 0) {
  1942.                         $this->current_layer $pb['z-index'];
  1943.                         $s .= "\n" '/OCBZ-index /ZI' $pb['z-index'] . ' BDC' "\n";
  1944.                     }
  1945.                     if ($pb['visibility'] != 'visible') {
  1946.                         if ($pb['visibility'] == 'printonly') {
  1947.                             $s .= '/OC /OC1 BDC' "\n";
  1948.                         } elseif ($pb['visibility'] == 'screenonly') {
  1949.                             $s .= '/OC /OC2 BDC' "\n";
  1950.                         } elseif ($pb['visibility'] == 'hidden') {
  1951.                             $s .= '/OC /OC3 BDC' "\n";
  1952.                         }
  1953.                     }
  1954.                     // Box shadow
  1955.                     if (isset($pb['shadow']) && $pb['shadow']) {
  1956.                         $s .= $pb['shadow'] . "\n";
  1957.                     }
  1958.                     if (isset($pb['clippath']) && $pb['clippath']) {
  1959.                         $s .= $pb['clippath'] . "\n";
  1960.                     }
  1961.                     $s .= 'q ' $this->SetFColor($pb['col'], true) . "\n";
  1962.                     if ($pb['col'] && $pb['col'][0] === '5') { // RGBa
  1963.                         $s .= $this->SetAlpha(ord($pb['col'][4]) / 100'Normal'true'F') . "\n";
  1964.                     } elseif ($pb['col'] && $pb['col'][0] === '6') { // CMYKa
  1965.                         $s .= $this->SetAlpha(ord($pb['col'][5]) / 100'Normal'true'F') . "\n";
  1966.                     }
  1967.                     $s .= sprintf('%.3F %.3F %.3F %.3F re f Q'$pb['x'] * Mpdf::SCALE, ($this->$pb['y']) * Mpdf::SCALE$pb['w'] * Mpdf::SCALE, -$pb['h'] * Mpdf::SCALE) . "\n";
  1968.                     if (isset($pb['clippath']) && $pb['clippath']) {
  1969.                         $s .= 'Q' "\n";
  1970.                     }
  1971.                     if ($pb['visibility'] != 'visible') {
  1972.                         $s .= 'EMC' "\n";
  1973.                     }
  1974.                     if ($pb['z-index'] > 0) {
  1975.                         $s .= "\n" 'EMCBZ-index' "\n";
  1976.                         $this->current_layer 0;
  1977.                     }
  1978.                 }
  1979.             }
  1980.             /* -- BACKGROUNDS -- */
  1981.             foreach ($pbs as $pb) {
  1982.                 if ((isset($pb['gradient']) && $pb['gradient']) || (isset($pb['image_id']) && $pb['image_id'])) {
  1983.                     if ($pb['z-index'] > 0) {
  1984.                         $this->current_layer $pb['z-index'];
  1985.                         $s .= "\n" '/OCGZ-index /ZI' $pb['z-index'] . ' BDC' "\n";
  1986.                     }
  1987.                     if ($pb['visibility'] != 'visible') {
  1988.                         if ($pb['visibility'] == 'printonly') {
  1989.                             $s .= '/OC /OC1 BDC' "\n";
  1990.                         } elseif ($pb['visibility'] == 'screenonly') {
  1991.                             $s .= '/OC /OC2 BDC' "\n";
  1992.                         } elseif ($pb['visibility'] == 'hidden') {
  1993.                             $s .= '/OC /OC3 BDC' "\n";
  1994.                         }
  1995.                     }
  1996.                 }
  1997.                 if (isset($pb['gradient']) && $pb['gradient']) {
  1998.                     if (isset($pb['clippath']) && $pb['clippath']) {
  1999.                         $s .= $pb['clippath'] . "\n";
  2000.                     }
  2001.                     $s .= $this->gradient->Gradient($pb['x'], $pb['y'], $pb['w'], $pb['h'], $pb['gradtype'], $pb['stops'], $pb['colorspace'], $pb['coords'], $pb['extend'], true);
  2002.                     if (isset($pb['clippath']) && $pb['clippath']) {
  2003.                         $s .= 'Q' "\n";
  2004.                     }
  2005.                 } elseif (isset($pb['image_id']) && $pb['image_id']) { // Background Image
  2006.                     $pb['y'] -= $adjustmenty;
  2007.                     $pb['h'] += $adjustmenty;
  2008.                     $n count($this->patterns) + 1;
  2009.                     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']);
  2010.                     $this->patterns[$n] = ['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']];
  2011.                     $x $pb['x'] * Mpdf::SCALE;
  2012.                     $y = ($this->$pb['y']) * Mpdf::SCALE;
  2013.                     $w $pb['w'] * Mpdf::SCALE;
  2014.                     $h = -$pb['h'] * Mpdf::SCALE;
  2015.                     if (isset($pb['clippath']) && $pb['clippath']) {
  2016.                         $s .= $pb['clippath'] . "\n";
  2017.                     }
  2018.                     if ($this->writingHTMLfooter || $this->writingHTMLheader) { // Write each (tiles) image rather than use as a pattern
  2019.                         $iw $pb['orig_w'] / Mpdf::SCALE;
  2020.                         $ih $pb['orig_h'] / Mpdf::SCALE;
  2021.                         $w $pb['w'];
  2022.                         $h $pb['h'];
  2023.                         $x0 $pb['x'];
  2024.                         $y0 $pb['y'];
  2025.                         if (isset($pb['bpa']) && $pb['bpa']) {
  2026.                             $w $pb['bpa']['w'];
  2027.                             $h $pb['bpa']['h'];
  2028.                             $x0 $pb['bpa']['x'];
  2029.                             $y0 $pb['bpa']['y'];
  2030.                         }
  2031.                         if (isset($pb['size']['w']) && $pb['size']['w']) {
  2032.                             $size $pb['size'];
  2033.                             if ($size['w'] == 'contain') {
  2034.                                 // Scale the image, while preserving its intrinsic aspect ratio (if any), to the largest
  2035.                                 // size such that both its width and its height can fit inside the background positioning area.
  2036.                                 // Same as resize==3
  2037.                                 $ih $ih $pb['bpa']['w'] / $iw;
  2038.                                 $iw $pb['bpa']['w'];
  2039.                                 if ($ih $pb['bpa']['h']) {
  2040.                                     $iw $iw $pb['bpa']['h'] / $ih;
  2041.                                     $ih $pb['bpa']['h'];
  2042.                                 }
  2043.                             } elseif ($size['w'] == 'cover') {
  2044.                                 // Scale the image, while preserving its intrinsic aspect ratio (if any), to the smallest
  2045.                                 // size such that both its width and its height can completely cover the background positioning area.
  2046.                                 $ih $ih $pb['bpa']['w'] / $iw;
  2047.                                 $iw $pb['bpa']['w'];
  2048.                                 if ($ih $pb['bpa']['h']) {
  2049.                                     $iw $iw $ih $pb['bpa']['h'];
  2050.                                     $ih $pb['bpa']['h'];
  2051.                                 }
  2052.                             } else {
  2053.                                 if (NumericString::containsPercentChar($size['w'])) {
  2054.                                     $size['w'] = NumericString::removePercentChar($size['w']);
  2055.                                     $size['w'] /= 100;
  2056.                                     $size['w'] = ($pb['bpa']['w'] * $size['w']);
  2057.                                 }
  2058.                                 if (NumericString::containsPercentChar($size['h'])) {
  2059.                                     $size['h'] = NumericString::removePercentChar($size['h']);
  2060.                                     $size['h'] /= 100;
  2061.                                     $size['h'] = ($pb['bpa']['h'] * $size['h']);
  2062.                                 }
  2063.                                 if ($size['w'] == 'auto' && $size['h'] == 'auto') {
  2064.                                     $iw $iw;
  2065.                                     $ih $ih;
  2066.                                 } elseif ($size['w'] == 'auto' && $size['h'] != 'auto') {
  2067.                                     $iw $iw $size['h'] / $ih;
  2068.                                     $ih $size['h'];
  2069.                                 } elseif ($size['w'] != 'auto' && $size['h'] == 'auto') {
  2070.                                     $ih $ih $size['w'] / $iw;
  2071.                                     $iw $size['w'];
  2072.                                 } else {
  2073.                                     $iw $size['w'];
  2074.                                     $ih $size['h'];
  2075.                                 }
  2076.                             }
  2077.                         }
  2078.                         // Number to repeat
  2079.                         if ($pb['x_repeat']) {
  2080.                             $nx ceil($pb['w'] / $iw) + 1;
  2081.                         } else {
  2082.                             $nx 1;
  2083.                         }
  2084.                         if ($pb['y_repeat']) {
  2085.                             $ny ceil($pb['h'] / $ih) + 1;
  2086.                         } else {
  2087.                             $ny 1;
  2088.                         }
  2089.                         $x_pos $pb['x_pos'];
  2090.                         if (stristr($x_pos'%')) {
  2091.                             $x_pos = (float) $x_pos;
  2092.                             $x_pos /= 100;
  2093.                             $x_pos = ($pb['bpa']['w'] * $x_pos) - ($iw $x_pos);
  2094.                         }
  2095.                         $y_pos $pb['y_pos'];
  2096.                         if (stristr($y_pos'%')) {
  2097.                             $y_pos = (float) $y_pos;
  2098.                             $y_pos /= 100;
  2099.                             $y_pos = ($pb['bpa']['h'] * $y_pos) - ($ih $y_pos);
  2100.                         }
  2101.                         if ($nx 1) {
  2102.                             while ($x_pos > ($pb['x'] - $pb['bpa']['x'])) {
  2103.                                 $x_pos -= $iw;
  2104.                             }
  2105.                         }
  2106.                         if ($ny 1) {
  2107.                             while ($y_pos > ($pb['y'] - $pb['bpa']['y'])) {
  2108.                                 $y_pos -= $ih;
  2109.                             }
  2110.                         }
  2111.                         for ($xi 0$xi $nx$xi++) {
  2112.                             for ($yi 0$yi $ny$yi++) {
  2113.                                 $x $x0 $x_pos + ($iw $xi);
  2114.                                 $y $y0 $y_pos + ($ih $yi);
  2115.                                 if ($pb['opacity'] > && $pb['opacity'] < 1) {
  2116.                                     $opac $this->SetAlpha($pb['opacity'], 'Normal'true);
  2117.                                 } else {
  2118.                                     $opac '';
  2119.                                 }
  2120.                                 $s .= sprintf("q %s %.3F 0 0 %.3F %.3F %.3F cm /I%d Do Q"$opac$iw Mpdf::SCALE$ih Mpdf::SCALE$x Mpdf::SCALE, ($this->- ($y $ih)) * Mpdf::SCALE$pb['image_id']) . "\n";
  2121.                             }
  2122.                         }
  2123.                     } else {
  2124.                         if (($pb['opacity'] > || $pb['opacity'] === '0') && $pb['opacity'] < 1) {
  2125.                             $opac $this->SetAlpha($pb['opacity'], 'Normal'true);
  2126.                         } else {
  2127.                             $opac '';
  2128.                         }
  2129.                         $s .= sprintf('q /Pattern cs /P%d scn %s %.3F %.3F %.3F %.3F re f Q'$n$opac$x$y$w$h) . "\n";
  2130.                     }
  2131.                     if (isset($pb['clippath']) && $pb['clippath']) {
  2132.                         $s .= 'Q' "\n";
  2133.                     }
  2134.                 }
  2135.                 if ((isset($pb['gradient']) && $pb['gradient']) || (isset($pb['image_id']) && $pb['image_id'])) {
  2136.                     if ($pb['visibility'] != 'visible') {
  2137.                         $s .= 'EMC' "\n";
  2138.                     }
  2139.                     if ($pb['z-index'] > 0) {
  2140.                         $s .= "\n" 'EMCGZ-index' "\n";
  2141.                         $this->current_layer 0;
  2142.                     }
  2143.                 }
  2144.             }
  2145.             /* -- END BACKGROUNDS -- */
  2146.         }
  2147.         return $s;
  2148.     }
  2149.     function PrintTableBackgrounds($adjustmenty 0)
  2150.     {
  2151.         $s '';
  2152.         /* -- BACKGROUNDS -- */
  2153.         ksort($this->tableBackgrounds);
  2154.         foreach ($this->tableBackgrounds as $bl => $pbs) {
  2155.             foreach ($pbs as $pb) {
  2156.                 if ((!isset($pb['gradient']) || !$pb['gradient']) && (!isset($pb['image_id']) || !$pb['image_id'])) {
  2157.                     $s .= 'q ' $this->SetFColor($pb['col'], true) . "\n";
  2158.                     if ($pb['col'][0] == 5) { // RGBa
  2159.                         $s .= $this->SetAlpha(ord($pb['col'][4]) / 100'Normal'true'F') . "\n";
  2160.                     } elseif ($pb['col'][0] == 6) { // CMYKa
  2161.                         $s .= $this->SetAlpha(ord($pb['col'][5]) / 100'Normal'true'F') . "\n";
  2162.                     }
  2163.                     $s .= sprintf('%.3F %.3F %.3F %.3F re %s Q'$pb['x'] * Mpdf::SCALE, ($this->$pb['y']) * Mpdf::SCALE$pb['w'] * Mpdf::SCALE, -$pb['h'] * Mpdf::SCALE'f') . "\n";
  2164.                 }
  2165.                 if (isset($pb['gradient']) && $pb['gradient']) {
  2166.                     if (isset($pb['clippath']) && $pb['clippath']) {
  2167.                         $s .= $pb['clippath'] . "\n";
  2168.                     }
  2169.                     $s .= $this->gradient->Gradient($pb['x'], $pb['y'], $pb['w'], $pb['h'], $pb['gradtype'], $pb['stops'], $pb['colorspace'], $pb['coords'], $pb['extend'], true);
  2170.                     if (isset($pb['clippath']) && $pb['clippath']) {
  2171.                         $s .= 'Q' "\n";
  2172.                     }
  2173.                 }
  2174.                 if (isset($pb['image_id']) && $pb['image_id']) { // Background pattern
  2175.                     $pb['y'] -= $adjustmenty;
  2176.                     $pb['h'] += $adjustmenty;
  2177.                     $n count($this->patterns) + 1;
  2178.                     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']);
  2179.                     $this->patterns[$n] = ['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']];
  2180.                     $x $pb['x'] * Mpdf::SCALE;
  2181.                     $y = ($this->$pb['y']) * Mpdf::SCALE;
  2182.                     $w $pb['w'] * Mpdf::SCALE;
  2183.                     $h = -$pb['h'] * Mpdf::SCALE;
  2184.                     // mPDF 5.7.3
  2185.                     if (($this->writingHTMLfooter || $this->writingHTMLheader) && (!isset($pb['clippath']) || $pb['clippath'] == '')) {
  2186.                         // Set clipping path
  2187.                         $pb['clippath'] = sprintf(' q 0 w %.3F %.3F m %.3F %.3F l %.3F %.3F l %.3F %.3F l %.3F %.3F l W n '$x$y$x$y $h$x $w$y $h$x $w$y$x$y);
  2188.                     }
  2189.                     if (isset($pb['clippath']) && $pb['clippath']) {
  2190.                         $s .= $pb['clippath'] . "\n";
  2191.                     }
  2192.                     // mPDF 5.7.3
  2193.                     if ($this->writingHTMLfooter || $this->writingHTMLheader) { // Write each (tiles) image rather than use as a pattern
  2194.                         $iw $pb['orig_w'] / Mpdf::SCALE;
  2195.                         $ih $pb['orig_h'] / Mpdf::SCALE;
  2196.                         $w $pb['w'];
  2197.                         $h $pb['h'];
  2198.                         $x0 $pb['x'];
  2199.                         $y0 $pb['y'];
  2200.                         if (isset($pb['bpa']) && $pb['bpa']) {
  2201.                             $w $pb['bpa']['w'];
  2202.                             $h $pb['bpa']['h'];
  2203.                             $x0 $pb['bpa']['x'];
  2204.                             $y0 $pb['bpa']['y'];
  2205.                         } // At present 'bpa' (background page area) is not set for tablebackgrounds - only pagebackgrounds
  2206.                         // For now, just set it as:
  2207.                         else {
  2208.                             $pb['bpa'] = ['x' => $x0'y' => $y0'w' => $w'h' => $h];
  2209.                         }
  2210.                         if (isset($pb['size']['w']) && $pb['size']['w']) {
  2211.                             $size $pb['size'];
  2212.                             if ($size['w'] == 'contain') {
  2213.                                 // 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.
  2214.                                 // Same as resize==3
  2215.                                 $ih $ih $pb['bpa']['w'] / $iw;
  2216.                                 $iw $pb['bpa']['w'];
  2217.                                 if ($ih $pb['bpa']['h']) {
  2218.                                     $iw $iw $pb['bpa']['h'] / $ih;
  2219.                                     $ih $pb['bpa']['h'];
  2220.                                 }
  2221.                             } elseif ($size['w'] == 'cover') {
  2222.                                 // 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.
  2223.                                 $ih $ih $pb['bpa']['w'] / $iw;
  2224.                                 $iw $pb['bpa']['w'];
  2225.                                 if ($ih $pb['bpa']['h']) {
  2226.                                     $iw $iw $ih $pb['bpa']['h'];
  2227.                                     $ih $pb['bpa']['h'];
  2228.                                 }
  2229.                             } else {
  2230.                                 if (NumericString::containsPercentChar($size['w'])) {
  2231.                                     $size['w'] = NumericString::removePercentChar($size['w']);
  2232.                                     $size['w'] /= 100;
  2233.                                     $size['w'] = ($pb['bpa']['w'] * $size['w']);
  2234.                                 }
  2235.                                 if (NumericString::containsPercentChar($size['h'])) {
  2236.                                     $size['h'] = NumericString::removePercentChar($size['h']);
  2237.                                     $size['h'] /= 100;
  2238.                                     $size['h'] = ($pb['bpa']['h'] * $size['h']);
  2239.                                 }
  2240.                                 if ($size['w'] == 'auto' && $size['h'] == 'auto') {
  2241.                                     $iw $iw;
  2242.                                     $ih $ih;
  2243.                                 } elseif ($size['w'] == 'auto' && $size['h'] != 'auto') {
  2244.                                     $iw $iw $size['h'] / $ih;
  2245.                                     $ih $size['h'];
  2246.                                 } elseif ($size['w'] != 'auto' && $size['h'] == 'auto') {
  2247.                                     $ih $ih $size['w'] / $iw;
  2248.                                     $iw $size['w'];
  2249.                                 } else {
  2250.                                     $iw $size['w'];
  2251.                                     $ih $size['h'];
  2252.                                 }
  2253.                             }
  2254.                         }
  2255.                         // Number to repeat
  2256.                         if (isset($pb['x_repeat']) && $pb['x_repeat']) {
  2257.                             $nx ceil($pb['w'] / $iw) + 1;
  2258.                         } else {
  2259.                             $nx 1;
  2260.                         }
  2261.                         if (isset($pb['y_repeat']) && $pb['y_repeat']) {
  2262.                             $ny ceil($pb['h'] / $ih) + 1;
  2263.                         } else {
  2264.                             $ny 1;
  2265.                         }
  2266.                         $x_pos $pb['x_pos'];
  2267.                         if (NumericString::containsPercentChar($x_pos)) {
  2268.                             $x_pos NumericString::removePercentChar($x_pos);
  2269.                             $x_pos /= 100;
  2270.                             $x_pos = ($pb['bpa']['w'] * $x_pos) - ($iw $x_pos);
  2271.                         }
  2272.                         $y_pos $pb['y_pos'];
  2273.                         if (NumericString::containsPercentChar($y_pos)) {
  2274.                             $y_pos NumericString::removePercentChar($y_pos);
  2275.                             $y_pos /= 100;
  2276.                             $y_pos = ($pb['bpa']['h'] * $y_pos) - ($ih $y_pos);
  2277.                         }
  2278.                         if ($nx 1) {
  2279.                             while ($x_pos > ($pb['x'] - $pb['bpa']['x'])) {
  2280.                                 $x_pos -= $iw;
  2281.                             }
  2282.                         }
  2283.                         if ($ny 1) {
  2284.                             while ($y_pos > ($pb['y'] - $pb['bpa']['y'])) {
  2285.                                 $y_pos -= $ih;
  2286.                             }
  2287.                         }
  2288.                         for ($xi 0$xi $nx$xi++) {
  2289.                             for ($yi 0$yi $ny$yi++) {
  2290.                                 $x $x0 $x_pos + ($iw $xi);
  2291.                                 $y $y0 $y_pos + ($ih $yi);
  2292.                                 if ($pb['opacity'] > && $pb['opacity'] < 1) {
  2293.                                     $opac $this->SetAlpha($pb['opacity'], 'Normal'true);
  2294.                                 } else {
  2295.                                     $opac '';
  2296.                                 }
  2297.                                 $s .= sprintf("q %s %.3F 0 0 %.3F %.3F %.3F cm /I%d Do Q"$opac$iw Mpdf::SCALE$ih Mpdf::SCALE$x Mpdf::SCALE, ($this->- ($y $ih)) * Mpdf::SCALE$pb['image_id']) . "\n";
  2298.                             }
  2299.                         }
  2300.                     } else {
  2301.                         if (($pb['opacity'] > || $pb['opacity'] === '0') && $pb['opacity'] < 1) {
  2302.                             $opac $this->SetAlpha($pb['opacity'], 'Normal'true);
  2303.                         } else {
  2304.                             $opac '';
  2305.                         }
  2306.                         $s .= sprintf('q /Pattern cs /P%d scn %s %.3F %.3F %.3F %.3F re f Q'$n$opac$x$y$w$h) . "\n";
  2307.                     }
  2308.                     if (isset($pb['clippath']) && $pb['clippath']) {
  2309.                         $s .= 'Q' "\n";
  2310.                     }
  2311.                 }
  2312.             }
  2313.         }
  2314.         /* -- END BACKGROUNDS -- */
  2315.         return $s;
  2316.     }
  2317.     function BeginLayer($id)
  2318.     {
  2319.         if ($this->current_layer 0) {
  2320.             $this->EndLayer();
  2321.         }
  2322.         if ($id 1) {
  2323.             return false;
  2324.         }
  2325.         if (!isset($this->layers[$id])) {
  2326.             $this->layers[$id] = ['name' => 'Layer ' . ($id)];
  2327.             if (($this->PDFA || $this->PDFX)) {
  2328.                 $this->PDFAXwarnings[] = "Cannot use layers when using PDFA or PDFX";
  2329.                 return '';
  2330.             } elseif (!$this->PDFA && !$this->PDFX) {
  2331.                 $this->pdf_version '1.5';
  2332.             }
  2333.         }
  2334.         $this->current_layer $id;
  2335.         $this->writer->write('/OCZ-index /ZI' $id ' BDC');
  2336.         $this->pageoutput[$this->page] = [];
  2337.     }
  2338.     function EndLayer()
  2339.     {
  2340.         if ($this->current_layer 0) {
  2341.             $this->writer->write('EMCZ-index');
  2342.             $this->current_layer 0;
  2343.         }
  2344.     }
  2345.     function AddPageByArray($a)
  2346.     {
  2347.         if (!is_array($a)) {
  2348.             $a = [];
  2349.         }
  2350.         $orientation = (isset($a['orientation']) ? $a['orientation'] : '');
  2351.         $condition = (isset($a['condition']) ? $a['condition'] : (isset($a['type']) ? $a['type'] : ''));
  2352.         $resetpagenum = (isset($a['resetpagenum']) ? $a['resetpagenum'] : '');
  2353.         $pagenumstyle = (isset($a['pagenumstyle']) ? $a['pagenumstyle'] : '');
  2354.         $suppress = (isset($a['suppress']) ? $a['suppress'] : '');
  2355.         $mgl = (isset($a['mgl']) ? $a['mgl'] : (isset($a['margin-left']) ? $a['margin-left'] : ''));
  2356.         $mgr = (isset($a['mgr']) ? $a['mgr'] : (isset($a['margin-right']) ? $a['margin-right'] : ''));
  2357.         $mgt = (isset($a['mgt']) ? $a['mgt'] : (isset($a['margin-top']) ? $a['margin-top'] : ''));
  2358.         $mgb = (isset($a['mgb']) ? $a['mgb'] : (isset($a['margin-bottom']) ? $a['margin-bottom'] : ''));
  2359.         $mgh = (isset($a['mgh']) ? $a['mgh'] : (isset($a['margin-header']) ? $a['margin-header'] : ''));
  2360.         $mgf = (isset($a['mgf']) ? $a['mgf'] : (isset($a['margin-footer']) ? $a['margin-footer'] : ''));
  2361.         $ohname = (isset($a['ohname']) ? $a['ohname'] : (isset($a['odd-header-name']) ? $a['odd-header-name'] : ''));
  2362.         $ehname = (isset($a['ehname']) ? $a['ehname'] : (isset($a['even-header-name']) ? $a['even-header-name'] : ''));
  2363.         $ofname = (isset($a['ofname']) ? $a['ofname'] : (isset($a['odd-footer-name']) ? $a['odd-footer-name'] : ''));
  2364.         $efname = (isset($a['efname']) ? $a['efname'] : (isset($a['even-footer-name']) ? $a['even-footer-name'] : ''));
  2365.         $ohvalue = (isset($a['ohvalue']) ? $a['ohvalue'] : (isset($a['odd-header-value']) ? $a['odd-header-value'] : 0));
  2366.         $ehvalue = (isset($a['ehvalue']) ? $a['ehvalue'] : (isset($a['even-header-value']) ? $a['even-header-value'] : 0));
  2367.         $ofvalue = (isset($a['ofvalue']) ? $a['ofvalue'] : (isset($a['odd-footer-value']) ? $a['odd-footer-value'] : 0));
  2368.         $efvalue = (isset($a['efvalue']) ? $a['efvalue'] : (isset($a['even-footer-value']) ? $a['even-footer-value'] : 0));
  2369.         $pagesel = (isset($a['pagesel']) ? $a['pagesel'] : (isset($a['pageselector']) ? $a['pageselector'] : ''));
  2370.         $newformat = (isset($a['newformat']) ? $a['newformat'] : (isset($a['sheet-size']) ? $a['sheet-size'] : ''));
  2371.         $this->AddPage($orientation$condition$resetpagenum$pagenumstyle$suppress$mgl$mgr$mgt$mgb$mgh$mgf$ohname$ehname$ofname$efname$ohvalue$ehvalue$ofvalue$efvalue$pagesel$newformat);
  2372.     }
  2373.     // mPDF 6 pagebreaktype
  2374.     function _preForcedPagebreak($pagebreaktype)
  2375.     {
  2376.         if ($pagebreaktype == 'cloneall') {
  2377.             // Close any open block tags
  2378.             $arr = [];
  2379.             $ai 0;
  2380.             for ($b $this->blklvl$b 0$b--) {
  2381.                 $this->tag->CloseTag($this->blk[$b]['tag'], $arr$ai);
  2382.             }
  2383.             if ($this->blklvl == && !empty($this->textbuffer)) { // Output previously buffered content
  2384.                 $this->printbuffer($this->textbuffer1);
  2385.                 $this->textbuffer = [];
  2386.             }
  2387.         } elseif ($pagebreaktype == 'clonebycss') {
  2388.             // Close open block tags whilst box-decoration-break==clone
  2389.             $arr = [];
  2390.             $ai 0;
  2391.             for ($b $this->blklvl$b 0$b--) {
  2392.                 if (isset($this->blk[$b]['box_decoration_break']) && $this->blk[$b]['box_decoration_break'] == 'clone') {
  2393.                     $this->tag->CloseTag($this->blk[$b]['tag'], $arr$ai);
  2394.                 } else {
  2395.                     if ($b == $this->blklvl && !empty($this->textbuffer)) { // Output previously buffered content
  2396.                         $this->printbuffer($this->textbuffer1);
  2397.                         $this->textbuffer = [];
  2398.                     }
  2399.                     break;
  2400.                 }
  2401.             }
  2402.         } elseif (!empty($this->textbuffer)) { // Output previously buffered content
  2403.             $this->printbuffer($this->textbuffer1);
  2404.             $this->textbuffer = [];
  2405.         }
  2406.     }
  2407.     // mPDF 6 pagebreaktype
  2408.     function _postForcedPagebreak($pagebreaktype$startpage$save_blk$save_blklvl)
  2409.     {
  2410.         if ($pagebreaktype == 'cloneall') {
  2411.             $this->blk = [];
  2412.             $this->blk[0] = $save_blk[0];
  2413.             // Re-open block tags
  2414.             $this->blklvl 0;
  2415.             $arr = [];
  2416.             $i 0;
  2417.             for ($b 1$b <= $save_blklvl$b++) {
  2418.                 $this->tag->OpenTag($save_blk[$b]['tag'], $save_blk[$b]['attr'], $arr$i);
  2419.             }
  2420.         } elseif ($pagebreaktype == 'clonebycss') {
  2421.             $this->blk = [];
  2422.             $this->blk[0] = $save_blk[0];
  2423.             // Don't re-open tags for lowest level elements - so need to do some adjustments
  2424.             for ($b 1$b <= $this->blklvl$b++) {
  2425.                 $this->blk[$b] = $save_blk[$b];
  2426.                 $this->blk[$b]['startpage'] = 0;
  2427.                 $this->blk[$b]['y0'] = $this->y// ?? $this->tMargin
  2428.                 if (($this->page $startpage) % 2) {
  2429.                     if (isset($this->blk[$b]['x0'])) {
  2430.                         $this->blk[$b]['x0'] += $this->MarginCorrection;
  2431.                     } else {
  2432.                         $this->blk[$b]['x0'] = $this->MarginCorrection;
  2433.                     }
  2434.                 }
  2435.                 // for Float DIV
  2436.                 $this->blk[$b]['marginCorrected'][$this->page] = true;
  2437.             }
  2438.             // Re-open block tags for any that have box_decoration_break==clone
  2439.             $arr = [];
  2440.             $i 0;
  2441.             for ($b $this->blklvl 1$b <= $save_blklvl$b++) {
  2442.                 if ($b $this->blklvl) {
  2443.                     $this->lastblocklevelchange = -1;
  2444.                 }
  2445.                 $this->tag->OpenTag($save_blk[$b]['tag'], $save_blk[$b]['attr'], $arr$i);
  2446.             }
  2447.             if ($this->blk[$this->blklvl]['box_decoration_break'] != 'clone') {
  2448.                 $this->lastblocklevelchange = -1;
  2449.             }
  2450.         } else {
  2451.             $this->lastblocklevelchange = -1;
  2452.         }
  2453.     }
  2454.     function AddPage(
  2455.         $orientation '',
  2456.         $condition '',
  2457.         $resetpagenum '',
  2458.         $pagenumstyle '',
  2459.         $suppress '',
  2460.         $mgl '',
  2461.         $mgr '',
  2462.         $mgt '',
  2463.         $mgb '',
  2464.         $mgh '',
  2465.         $mgf '',
  2466.         $ohname '',
  2467.         $ehname '',
  2468.         $ofname '',
  2469.         $efname '',
  2470.         $ohvalue 0,
  2471.         $ehvalue 0,
  2472.         $ofvalue 0,
  2473.         $efvalue 0,
  2474.         $pagesel '',
  2475.         $newformat ''
  2476.     ) {
  2477.         /* -- CSS-FLOAT -- */
  2478.         // Float DIV
  2479.         // Cannot do with columns on, or if any change in page orientation/margins etc.
  2480.         // If next page already exists - i.e background /headers and footers already written
  2481.         if ($this->state && $this->page count($this->pages)) {
  2482.             $bak_cml $this->cMarginL;
  2483.             $bak_cmr $this->cMarginR;
  2484.             $bak_dw $this->divwidth;
  2485.             // Paint Div Border if necessary
  2486.             if ($this->blklvl 0) {
  2487.                 $save_tr $this->table_rotate// *TABLES*
  2488.                 $this->table_rotate 0// *TABLES*
  2489.                 if (isset($this->blk[$this->blklvl]['y0']) && $this->== $this->blk[$this->blklvl]['y0']) {
  2490.                     $this->blk[$this->blklvl]['startpage'] ++;
  2491.                 }
  2492.                 if ((isset($this->blk[$this->blklvl]['y0']) && $this->$this->blk[$this->blklvl]['y0']) || $this->flowingBlockAttr['is_table']) {
  2493.                     $toplvl $this->blklvl;
  2494.                 } else {
  2495.                     $toplvl $this->blklvl 1;
  2496.                 }
  2497.                 $sy $this->y;
  2498.                 for ($bl 1$bl <= $toplvl$bl++) {
  2499.                     $this->PaintDivBB('pagebottom'0$bl);
  2500.                 }
  2501.                 $this->$sy;
  2502.                 $this->table_rotate $save_tr// *TABLES*
  2503.             }
  2504.             $s $this->PrintPageBackgrounds();
  2505.             // Writes after the marker so not overwritten later by page background etc.
  2506.             $this->pages[$this->page] = preg_replace(
  2507.                 '/(___BACKGROUND___PATTERNS' $this->uniqstr ')/',
  2508.                 '\\1' "\n" $s "\n",
  2509.                 $this->pages[$this->page]
  2510.             );
  2511.             $this->pageBackgrounds = [];
  2512.             $family $this->FontFamily;
  2513.             $style $this->FontStyle;
  2514.             $size $this->FontSizePt;
  2515.             $lw $this->LineWidth;
  2516.             $dc $this->DrawColor;
  2517.             $fc $this->FillColor;
  2518.             $tc $this->TextColor;
  2519.             $cf $this->ColorFlag;
  2520.             $this->printfloatbuffer();
  2521.             // Move to next page
  2522.             $this->page++;
  2523.             $this->ResetMargins();
  2524.             $this->SetAutoPageBreak($this->autoPageBreak$this->bMargin);
  2525.             $this->$this->lMargin;
  2526.             $this->$this->tMargin;
  2527.             $this->FontFamily '';
  2528.             $this->writer->write('2 J');
  2529.             $this->LineWidth $lw;
  2530.             $this->writer->write(sprintf('%.3F w'$lw Mpdf::SCALE));
  2531.             if ($family) {
  2532.                 $this->SetFont($family$style$sizetruetrue);
  2533.             }
  2534.             $this->DrawColor $dc;
  2535.             if ($dc != $this->defDrawColor) {
  2536.                 $this->writer->write($dc);
  2537.             }
  2538.             $this->FillColor $fc;
  2539.             if ($fc != $this->defFillColor) {
  2540.                 $this->writer->write($fc);
  2541.             }
  2542.             $this->TextColor $tc;
  2543.             $this->ColorFlag $cf;
  2544.             for ($bl 1$bl <= $this->blklvl$bl++) {
  2545.                 $this->blk[$bl]['y0'] = $this->y;
  2546.                 // Don't correct more than once for background DIV containing a Float
  2547.                 if (!isset($this->blk[$bl]['marginCorrected'][$this->page])) {
  2548.                     if (isset($this->blk[$bl]['x0'])) {
  2549.                         $this->blk[$bl]['x0'] += $this->MarginCorrection;
  2550.                     } else {
  2551.                         $this->blk[$bl]['x0'] = $this->MarginCorrection;
  2552.                     }
  2553.                 }
  2554.                 $this->blk[$bl]['marginCorrected'][$this->page] = true;
  2555.             }
  2556.             $this->cMarginL $bak_cml;
  2557.             $this->cMarginR $bak_cmr;
  2558.             $this->divwidth $bak_dw;
  2559.             return '';
  2560.         }
  2561.         /* -- END CSS-FLOAT -- */
  2562.         // Start a new page
  2563.         if ($this->state == 0) {
  2564.             $this->Open();
  2565.         }
  2566.         $bak_cml $this->cMarginL;
  2567.         $bak_cmr $this->cMarginR;
  2568.         $bak_dw $this->divwidth;
  2569.         $bak_lh $this->lineheight;
  2570.         $orientation substr(strtoupper($orientation), 01);
  2571.         $condition strtoupper($condition);
  2572.         if ($condition == 'E') { // only adds new page if needed to create an Even page
  2573.             if (!$this->mirrorMargins || ($this->page) % == 0) {
  2574.                 return false;
  2575.             }
  2576.         } elseif ($condition == 'O') { // only adds new page if needed to create an Odd page
  2577.             if (!$this->mirrorMargins || ($this->page) % == 1) {
  2578.                 return false;
  2579.             }
  2580.         } elseif ($condition == 'NEXT-EVEN') { // always adds at least one new page to create an Even page
  2581.             if (!$this->mirrorMargins) {
  2582.                 $condition '';
  2583.             } else {
  2584.                 if ($pagesel) {
  2585.                     $pbch $pagesel;
  2586.                     $pagesel '';
  2587.                 } // *CSS-PAGE*
  2588.                 else {
  2589.                     $pbch false;
  2590.                 } // *CSS-PAGE*
  2591.                 $this->AddPage($this->CurOrientation'O');
  2592.                 $this->extrapagebreak true// mPDF 6 pagebreaktype
  2593.                 if ($pbch) {
  2594.                     $pagesel $pbch;
  2595.                 } // *CSS-PAGE*
  2596.                 $condition '';
  2597.             }
  2598.         } elseif ($condition == 'NEXT-ODD') { // always adds at least one new page to create an Odd page
  2599.             if (!$this->mirrorMargins) {
  2600.                 $condition '';
  2601.             } else {
  2602.                 if ($pagesel) {
  2603.                     $pbch $pagesel;
  2604.                     $pagesel '';
  2605.                 } // *CSS-PAGE*
  2606.                 else {
  2607.                     $pbch false;
  2608.                 } // *CSS-PAGE*
  2609.                 $this->AddPage($this->CurOrientation'E');
  2610.                 $this->extrapagebreak true// mPDF 6 pagebreaktype
  2611.                 if ($pbch) {
  2612.                     $pagesel $pbch;
  2613.                 } // *CSS-PAGE*
  2614.                 $condition '';
  2615.             }
  2616.         }
  2617.         if ($resetpagenum || $pagenumstyle || $suppress) {
  2618.             $this->PageNumSubstitutions[] = ['from' => ($this->page 1), 'reset' => $resetpagenum'type' => $pagenumstyle'suppress' => $suppress];
  2619.         }
  2620.         $save_tr $this->table_rotate// *TABLES*
  2621.         $this->table_rotate 0// *TABLES*
  2622.         $save_kwt $this->kwt;
  2623.         $this->kwt 0;
  2624.         $save_layer $this->current_layer;
  2625.         $save_vis $this->visibility;
  2626.         if ($this->visibility != 'visible') {
  2627.             $this->SetVisibility('visible');
  2628.         }
  2629.         $this->EndLayer();
  2630.         // Paint Div Border if necessary
  2631.         // PAINTS BACKGROUND COLOUR OR BORDERS for DIV - DISABLED FOR COLUMNS (cf. AcceptPageBreak) AT PRESENT in ->PaintDivBB
  2632.         if (!$this->ColActive && $this->blklvl 0) {
  2633.             if (isset($this->blk[$this->blklvl]['y0']) && $this->== $this->blk[$this->blklvl]['y0'] && !$this->extrapagebreak) { // mPDF 6 pagebreaktype
  2634.                 if (isset($this->blk[$this->blklvl]['startpage'])) {
  2635.                     $this->blk[$this->blklvl]['startpage'] ++;
  2636.                 } else {
  2637.                     $this->blk[$this->blklvl]['startpage'] = 1;
  2638.                 }
  2639.             }
  2640.             if ((isset($this->blk[$this->blklvl]['y0']) && $this->$this->blk[$this->blklvl]['y0']) || $this->flowingBlockAttr['is_table'] || $this->extrapagebreak) {
  2641.                 $toplvl $this->blklvl;
  2642.             } // mPDF 6 pagebreaktype
  2643.             else {
  2644.                 $toplvl $this->blklvl 1;
  2645.             }
  2646.             $sy $this->y;
  2647.             for ($bl 1$bl <= $toplvl$bl++) {
  2648.                 if (isset($this->blk[$bl]['z-index']) && $this->blk[$bl]['z-index'] > 0) {
  2649.                     $this->BeginLayer($this->blk[$bl]['z-index']);
  2650.                 }
  2651.                 if (isset($this->blk[$bl]['visibility']) && $this->blk[$bl]['visibility'] && $this->blk[$bl]['visibility'] != 'visible') {
  2652.                     $this->SetVisibility($this->blk[$bl]['visibility']);
  2653.                 }
  2654.                 $this->PaintDivBB('pagebottom'0$bl);
  2655.             }
  2656.             $this->$sy;
  2657.             // RESET block y0 and x0 - see below
  2658.         }
  2659.         $this->extrapagebreak false// mPDF 6 pagebreaktype
  2660.         if ($this->visibility != 'visible') {
  2661.             $this->SetVisibility('visible');
  2662.         }
  2663.         $this->EndLayer();
  2664.         // BODY Backgrounds
  2665.         if ($this->page 0) {
  2666.             $s '';
  2667.             $s .= $this->PrintBodyBackgrounds();
  2668.             $s .= $this->PrintPageBackgrounds();
  2669.             $this->pages[$this->page] = preg_replace('/(___BACKGROUND___PATTERNS' $this->uniqstr ')/'"\n" $s "\n" '\\1'$this->pages[$this->page]);
  2670.             $this->pageBackgrounds = [];
  2671.         }
  2672.         $save_kt $this->keep_block_together;
  2673.         $this->keep_block_together 0;
  2674.         $save_cols false;
  2675.         /* -- COLUMNS -- */
  2676.         if ($this->ColActive) {
  2677.             $save_cols true;
  2678.             $save_nbcol $this->NbCol// other values of gap and vAlign will not change by setting Columns off
  2679.             $this->SetColumns(0);
  2680.         }
  2681.         /* -- END COLUMNS -- */
  2682.         $family $this->FontFamily;
  2683.         $style $this->FontStyle;
  2684.         $size $this->FontSizePt;
  2685.         $this->ColumnAdjust true// enables column height adjustment for the page
  2686.         $lw $this->LineWidth;
  2687.         $dc $this->DrawColor;
  2688.         $fc $this->FillColor;
  2689.         $tc $this->TextColor;
  2690.         $cf $this->ColorFlag;
  2691.         if ($this->page 0) {
  2692.             // Page footer
  2693.             $this->InFooter true;
  2694.             $this->Reset();
  2695.             $this->pageoutput[$this->page] = [];
  2696.             $this->Footer();
  2697.             // Close page
  2698.             $this->_endpage();
  2699.         }
  2700.         // Start new page
  2701.         $pageBeforeNewPage $this->page;
  2702.         $this->_beginpage($orientation$mgl$mgr$mgt$mgb$mgh$mgf$ohname$ehname$ofname$efname$ohvalue$ehvalue$ofvalue$efvalue$pagesel$newformat);
  2703.         $isNewPage $pageBeforeNewPage !== $this->page;
  2704.         if ($this->docTemplate) {
  2705.             $currentReaderId $this->currentReaderId;
  2706.             $pagecount $this->setSourceFile($this->docTemplate);
  2707.             if (($this->page $this->docTemplateStart) > $pagecount) {
  2708.                 if ($this->docTemplateContinue) {
  2709.                     if ($this->docTemplateContinue2pages && $pagecount >= && (=== $this->page 2)) {
  2710.                         $tplIdx $this->importPage(($pagecount 1));
  2711.                         $this->useTemplate($tplIdx);
  2712.                     } else {
  2713.                         $tplIdx $this->importPage($pagecount);
  2714.                         $this->useTemplate($tplIdx);
  2715.                     }
  2716.                 }
  2717.             } else {
  2718.                 $tplIdx $this->importPage(($this->page $this->docTemplateStart));
  2719.                 $this->useTemplate($tplIdx);
  2720.             }
  2721.             $this->currentReaderId $currentReaderId;
  2722.         }
  2723.         if ($this->pageTemplate) {
  2724.             $this->useTemplate($this->pageTemplate);
  2725.         }
  2726.         // Only add the headers if it's a new page
  2727.         if ($isNewPage) {
  2728.             // Tiling Patterns
  2729.             $this->writer->write('___PAGE___START' $this->uniqstr);
  2730.             $this->writer->write('___BACKGROUND___PATTERNS' $this->uniqstr);
  2731.             $this->writer->write('___HEADER___MARKER' $this->uniqstr);
  2732.         }
  2733.         $this->pageBackgrounds = [];
  2734.         // Set line cap style to square
  2735.         $this->SetLineCap(2);
  2736.         // Set line width
  2737.         $this->LineWidth $lw;
  2738.         $this->writer->write(sprintf('%.3F w'$lw Mpdf::SCALE));
  2739.         // Set font
  2740.         if ($family) {
  2741.             $this->SetFont($family$style$sizetruetrue); // forces write
  2742.         }
  2743.         // Set colors
  2744.         $this->DrawColor $dc;
  2745.         if ($dc != $this->defDrawColor) {
  2746.             $this->writer->write($dc);
  2747.         }
  2748.         $this->FillColor $fc;
  2749.         if ($fc != $this->defFillColor) {
  2750.             $this->writer->write($fc);
  2751.         }
  2752.         $this->TextColor $tc;
  2753.         $this->ColorFlag $cf;
  2754.         // Page header
  2755.         $this->Header();
  2756.         // Restore line width
  2757.         if ($this->LineWidth != $lw) {
  2758.             $this->LineWidth $lw;
  2759.             $this->writer->write(sprintf('%.3F w'$lw Mpdf::SCALE));
  2760.         }
  2761.         // Restore font
  2762.         if ($family) {
  2763.             $this->SetFont($family$style$sizetruetrue); // forces write
  2764.         }
  2765.         // Restore colors
  2766.         if ($this->DrawColor != $dc) {
  2767.             $this->DrawColor $dc;
  2768.             $this->writer->write($dc);
  2769.         }
  2770.         if ($this->FillColor != $fc) {
  2771.             $this->FillColor $fc;
  2772.             $this->writer->write($fc);
  2773.         }
  2774.         $this->TextColor $tc;
  2775.         $this->ColorFlag $cf;
  2776.         $this->InFooter false;
  2777.         if ($save_layer 0) {
  2778.             $this->BeginLayer($save_layer);
  2779.         }
  2780.         if ($save_vis != 'visible') {
  2781.             $this->SetVisibility($save_vis);
  2782.         }
  2783.         /* -- COLUMNS -- */
  2784.         if ($save_cols) {
  2785.             // Restore columns
  2786.             $this->SetColumns($save_nbcol$this->colvAlign$this->ColGap);
  2787.         }
  2788.         if ($this->ColActive) {
  2789.             $this->SetCol(0);
  2790.         }
  2791.         /* -- END COLUMNS -- */
  2792.         // RESET BLOCK BORDER TOP
  2793.         if (!$this->ColActive) {
  2794.             for ($bl 1$bl <= $this->blklvl$bl++) {
  2795.                 $this->blk[$bl]['y0'] = $this->y;
  2796.                 if (isset($this->blk[$bl]['x0'])) {
  2797.                     $this->blk[$bl]['x0'] += $this->MarginCorrection;
  2798.                 } else {
  2799.                     $this->blk[$bl]['x0'] = $this->MarginCorrection;
  2800.                 }
  2801.                 // Added mPDF 3.0 Float DIV
  2802.                 $this->blk[$bl]['marginCorrected'][$this->page] = true;
  2803.             }
  2804.         }
  2805.         $this->table_rotate $save_tr// *TABLES*
  2806.         $this->kwt $save_kwt;
  2807.         $this->keep_block_together $save_kt;
  2808.         $this->cMarginL $bak_cml;
  2809.         $this->cMarginR $bak_cmr;
  2810.         $this->divwidth $bak_dw;
  2811.         $this->lineheight $bak_lh;
  2812.     }
  2813.     /**
  2814.      * Get current page number
  2815.      *
  2816.      * @return int
  2817.      */
  2818.     function PageNo()
  2819.     {
  2820.         return $this->page;
  2821.     }
  2822.     function AddSpotColorsFromFile($file)
  2823.     {
  2824.         $colors = @file($file);
  2825.         if (!$colors) {
  2826.             throw new \Mpdf\MpdfException("Cannot load spot colors file - " $file);
  2827.         }
  2828.         foreach ($colors as $sc) {
  2829.             list($name$c$m$y$k) = preg_split("/\t/"$sc);
  2830.             $c intval($c);
  2831.             $m intval($m);
  2832.             $y intval($y);
  2833.             $k intval($k);
  2834.             $this->AddSpotColor($name$c$m$y$k);
  2835.         }
  2836.     }
  2837.     function AddSpotColor($name$c$m$y$k)
  2838.     {
  2839.         $name strtoupper(trim($name));
  2840.         if (!isset($this->spotColors[$name])) {
  2841.             $i count($this->spotColors) + 1;
  2842.             $this->spotColors[$name] = ['i' => $i'c' => $c'm' => $m'y' => $y'k' => $k];
  2843.             $this->spotColorIDs[$i] = $name;
  2844.         }
  2845.     }
  2846.     function SetColor($col$type '')
  2847.     {
  2848.         $out '';
  2849.         if (!$col) {
  2850.             return '';
  2851.         } // mPDF 6
  2852.         if ($col[0] == || $col[0] == 5) { // RGB / RGBa
  2853.             $out sprintf('%.3F %.3F %.3F rg'ord($col[1]) / 255ord($col[2]) / 255ord($col[3]) / 255);
  2854.         } elseif ($col[0] == 1) { // GRAYSCALE
  2855.             $out sprintf('%.3F g'ord($col[1]) / 255);
  2856.         } elseif ($col[0] == 2) { // SPOT COLOR
  2857.             $out sprintf('/CS%d cs %.3F scn'ord($col[1]), ord($col[2]) / 100);
  2858.         } elseif ($col[0] == || $col[0] == 6) { // CMYK / CMYKa
  2859.             $out sprintf('%.3F %.3F %.3F %.3F k'ord($col[1]) / 100ord($col[2]) / 100ord($col[3]) / 100ord($col[4]) / 100);
  2860.         }
  2861.         if ($type == 'Draw') {
  2862.             $out strtoupper($out);
  2863.         } // e.g. rg => RG
  2864.         elseif ($type == 'CodeOnly') {
  2865.             $out preg_replace('/\s(rg|g|k)/'''$out);
  2866.         }
  2867.         return $out;
  2868.     }
  2869.     function SetDColor($col$return false)
  2870.     {
  2871.         $out $this->SetColor($col'Draw');
  2872.         if ($return) {
  2873.             return $out;
  2874.         }
  2875.         if ($out == '') {
  2876.             return '';
  2877.         }
  2878.         $this->DrawColor $out;
  2879.         if ($this->page && ((isset($this->pageoutput[$this->page]['DrawColor']) && $this->pageoutput[$this->page]['DrawColor'] != $this->DrawColor) || !isset($this->pageoutput[$this->page]['DrawColor']))) {
  2880.             $this->writer->write($this->DrawColor);
  2881.         }
  2882.         $this->pageoutput[$this->page]['DrawColor'] = $this->DrawColor;
  2883.     }
  2884.     function SetFColor($col$return false)
  2885.     {
  2886.         $out $this->SetColor($col'Fill');
  2887.         if ($return) {
  2888.             return $out;
  2889.         }
  2890.         if ($out == '') {
  2891.             return '';
  2892.         }
  2893.         $this->FillColor $out;
  2894.         $this->ColorFlag = ($out != $this->TextColor);
  2895.         if ($this->page && ((isset($this->pageoutput[$this->page]['FillColor']) && $this->pageoutput[$this->page]['FillColor'] != $this->FillColor) || !isset($this->pageoutput[$this->page]['FillColor']))) {
  2896.             $this->writer->write($this->FillColor);
  2897.         }
  2898.         $this->pageoutput[$this->page]['FillColor'] = $this->FillColor;
  2899.     }
  2900.     function SetTColor($col$return false)
  2901.     {
  2902.         $out $this->SetColor($col'Text');
  2903.         if ($return) {
  2904.             return $out;
  2905.         }
  2906.         if ($out == '') {
  2907.             return '';
  2908.         }
  2909.         $this->TextColor $out;
  2910.         $this->ColorFlag = ($this->FillColor != $out);
  2911.     }
  2912.     function SetDrawColor($r$g = -1$b = -1$col4 = -1$return false)
  2913.     {
  2914.         // Set color for all stroking operations
  2915.         $col = [];
  2916.         if (($r == and $g == and $b == && $col4 == -1) or $g == -1) {
  2917.             $col $this->colorConverter->convert($r$this->PDFAXwarnings);
  2918.         } elseif ($col4 == -1) {
  2919.             $col $this->colorConverter->convert('rgb(' $r ',' $g ',' $b ')'$this->PDFAXwarnings);
  2920.         } else {
  2921.             $col $this->colorConverter->convert('cmyk(' $r ',' $g ',' $b ',' $col4 ')'$this->PDFAXwarnings);
  2922.         }
  2923.         $out $this->SetDColor($col$return);
  2924.         return $out;
  2925.     }
  2926.     function SetFillColor($r$g = -1$b = -1$col4 = -1$return false)
  2927.     {
  2928.         // Set color for all filling operations
  2929.         $col = [];
  2930.         if (($r == and $g == and $b == && $col4 == -1) or $g == -1) {
  2931.             $col $this->colorConverter->convert($r$this->PDFAXwarnings);
  2932.         } elseif ($col4 == -1) {
  2933.             $col $this->colorConverter->convert('rgb(' $r ',' $g ',' $b ')'$this->PDFAXwarnings);
  2934.         } else {
  2935.             $col $this->colorConverter->convert('cmyk(' $r ',' $g ',' $b ',' $col4 ')'$this->PDFAXwarnings);
  2936.         }
  2937.         $out $this->SetFColor($col$return);
  2938.         return $out;
  2939.     }
  2940.     function SetTextColor($r$g = -1$b = -1$col4 = -1$return false)
  2941.     {
  2942.         // Set color for text
  2943.         $col = [];
  2944.         if (($r == and $g == and $b == && $col4 == -1) or $g == -1) {
  2945.             $col $this->colorConverter->convert($r$this->PDFAXwarnings);
  2946.         } elseif ($col4 == -1) {
  2947.             $col $this->colorConverter->convert('rgb(' $r ',' $g ',' $b ')'$this->PDFAXwarnings);
  2948.         } else {
  2949.             $col $this->colorConverter->convert('cmyk(' $r ',' $g ',' $b ',' $col4 ')'$this->PDFAXwarnings);
  2950.         }
  2951.         $out $this->SetTColor($col$return);
  2952.         return $out;
  2953.     }
  2954.     function _getCharWidth(&$cw$u$isdef true)
  2955.     {
  2956.         $w 0;
  2957.         if ($u == 0) {
  2958.             $w false;
  2959.         } elseif (isset($cw[$u 1])) {
  2960.             $w = (ord($cw[$u 2]) << 8) + ord($cw[$u 1]);
  2961.         }
  2962.         if ($w == 65535) {
  2963.             return 0;
  2964.         } elseif ($w) {
  2965.             return $w;
  2966.         } elseif ($isdef) {
  2967.             return false;
  2968.         } else {
  2969.             return 0;
  2970.         }
  2971.     }
  2972.     function _charDefined(&$cw$u)
  2973.     {
  2974.         $w 0;
  2975.         if ($u == 0) {
  2976.             return false;
  2977.         }
  2978.         if (isset($cw[$u 1])) {
  2979.             $w = (ord($cw[$u 2]) << 8) + ord($cw[$u 1]);
  2980.         }
  2981.         return (bool) $w;
  2982.     }
  2983.     function GetCharWidthCore($c)
  2984.     {
  2985.         // Get width of a single character in the current Core font
  2986.         $c = (string) $c;
  2987.         $w 0;
  2988.         // Soft Hyphens chr(173)
  2989.         if ($c == chr(173) && $this->FontFamily != 'csymbol' && $this->FontFamily != 'czapfdingbats') {
  2990.             return 0;
  2991.         } elseif (($this->textvar TextVars::FC_SMALLCAPS) && isset($this->upperCase[ord($c)])) {  // mPDF 5.7.1
  2992.             $charw $this->CurrentFont['cw'][chr($this->upperCase[ord($c)])];
  2993.             if ($charw !== false) {
  2994.                 $charw $charw $this->smCapsScale $this->smCapsStretch 100;
  2995.                 $w+=$charw;
  2996.             }
  2997.         } elseif (isset($this->CurrentFont['cw'][$c])) {
  2998.             $w += $this->CurrentFont['cw'][$c];
  2999.         } elseif (isset($this->CurrentFont['cw'][ord($c)])) {
  3000.             $w += $this->CurrentFont['cw'][ord($c)];
  3001.         }
  3002.         $w *= ($this->FontSize 1000);
  3003.         if ($this->minwSpacing || $this->fixedlSpacing) {
  3004.             if ($c == ' ') {
  3005.                 $nb_spaces 1;
  3006.             } else {
  3007.                 $nb_spaces 0;
  3008.             }
  3009.             $w += $this->fixedlSpacing + ($nb_spaces $this->minwSpacing);
  3010.         }
  3011.         return ($w);
  3012.     }
  3013.     function GetCharWidthNonCore($c$addSubset true)
  3014.     {
  3015.         // Get width of a single character in the current Non-Core font
  3016.         $c = (string) $c;
  3017.         $w 0;
  3018.         $unicode $this->UTF8StringToArray($c$addSubset);
  3019.         $char $unicode[0];
  3020.         /* -- CJK-FONTS -- */
  3021.         if ($this->CurrentFont['type'] == 'Type0') { // CJK Adobe fonts
  3022.             if ($char == 173) {
  3023.                 return 0;
  3024.             } // Soft Hyphens
  3025.             elseif (isset($this->CurrentFont['cw'][$char])) {
  3026.                 $w+=$this->CurrentFont['cw'][$char];
  3027.             } elseif (isset($this->CurrentFont['MissingWidth'])) {
  3028.                 $w += $this->CurrentFont['MissingWidth'];
  3029.             } else {
  3030.                 $w += 500;
  3031.             }
  3032.         } else {
  3033.             /* -- END CJK-FONTS -- */
  3034.             if ($char == 173) {
  3035.                 return 0;
  3036.             } // Soft Hyphens
  3037.             elseif (($this->textvar TextVars::FC_SMALLCAPS) && isset($this->upperCase[$char])) { // mPDF 5.7.1
  3038.                 $charw $this->_getCharWidth($this->CurrentFont['cw'], $this->upperCase[$char]);
  3039.                 if ($charw !== false) {
  3040.                     $charw $charw $this->smCapsScale $this->smCapsStretch 100;
  3041.                     $w+=$charw;
  3042.                 } elseif (isset($this->CurrentFont['desc']['MissingWidth'])) {
  3043.                     $w += $this->CurrentFont['desc']['MissingWidth'];
  3044.                 } elseif (isset($this->CurrentFont['MissingWidth'])) {
  3045.                     $w += $this->CurrentFont['MissingWidth'];
  3046.                 } else {
  3047.                     $w += 500;
  3048.                 }
  3049.             } else {
  3050.                 $charw $this->_getCharWidth($this->CurrentFont['cw'], $char);
  3051.                 if ($charw !== false) {
  3052.                     $w+=$charw;
  3053.                 } elseif (isset($this->CurrentFont['desc']['MissingWidth'])) {
  3054.                     $w += $this->CurrentFont['desc']['MissingWidth'];
  3055.                 } elseif (isset($this->CurrentFont['MissingWidth'])) {
  3056.                     $w += $this->CurrentFont['MissingWidth'];
  3057.                 } else {
  3058.                     $w += 500;
  3059.                 }
  3060.             }
  3061.         } // *CJK-FONTS*
  3062.         $w *= ($this->FontSize 1000);
  3063.         if ($this->minwSpacing || $this->fixedlSpacing) {
  3064.             if ($c == ' ') {
  3065.                 $nb_spaces 1;
  3066.             } else {
  3067.                 $nb_spaces 0;
  3068.             }
  3069.             $w += $this->fixedlSpacing + ($nb_spaces $this->minwSpacing);
  3070.         }
  3071.         return ($w);
  3072.     }
  3073.     function GetCharWidth($c$addSubset true)
  3074.     {
  3075.         if (!$this->usingCoreFont) {
  3076.             return $this->GetCharWidthNonCore($c$addSubset);
  3077.         } else {
  3078.             return $this->GetCharWidthCore($c);
  3079.         }
  3080.     }
  3081.     function GetStringWidth($s$addSubset true$OTLdata false$textvar 0$includeKashida false)
  3082.     {
  3083.     // mPDF 5.7.1
  3084.         // Get width of a string in the current font
  3085.         $s = (string) $s;
  3086.         $cw = &$this->CurrentFont['cw'];
  3087.         $w 0;
  3088.         $kerning 0;
  3089.         $lastchar 0;
  3090.         $nb_carac 0;
  3091.         $nb_spaces 0;
  3092.         $kashida 0;
  3093.         // mPDF ITERATION
  3094.         if ($this->iterationCounter) {
  3095.             $s preg_replace('/{iteration ([a-zA-Z0-9_]+)}/''\\1'$s);
  3096.         }
  3097.         if (!$this->usingCoreFont) {
  3098.             $discards substr_count($s"\xc2\xad"); // mPDF 6 soft hyphens [U+00AD]
  3099.             $unicode $this->UTF8StringToArray($s$addSubset);
  3100.             if ($this->minwSpacing || $this->fixedlSpacing) {
  3101.                 $nb_spaces mb_substr_count($s' '$this->mb_enc);
  3102.                 $nb_carac count($unicode) - $discards// mPDF 6
  3103.                 // mPDF 5.7.1
  3104.                 // Use GPOS OTL
  3105.                 if (isset($this->CurrentFont['useOTL']) && $this->CurrentFont['useOTL']) {
  3106.                     if (isset($OTLdata['group']) && $OTLdata['group']) {
  3107.                         $nb_carac -= substr_count($OTLdata['group'], 'M');
  3108.                     }
  3109.                 }
  3110.             }
  3111.             /* -- CJK-FONTS -- */
  3112.             if ($this->CurrentFont['type'] == 'Type0') { // CJK Adobe fonts
  3113.                 foreach ($unicode as $char) {
  3114.                     if ($char == 0x00AD) {
  3115.                         continue;
  3116.                     } // mPDF 6 soft hyphens [U+00AD]
  3117.                     if (isset($cw[$char])) {
  3118.                         $w+=$cw[$char];
  3119.                     } elseif (isset($this->CurrentFont['MissingWidth'])) {
  3120.                         $w += $this->CurrentFont['MissingWidth'];
  3121.                     } else {
  3122.                         $w += 500;
  3123.                     }
  3124.                 }
  3125.             } else {
  3126.                 /* -- END CJK-FONTS -- */
  3127.                 foreach ($unicode as $i => $char) {
  3128.                     if ($char == 0x00AD) {
  3129.                         continue;
  3130.                     } // mPDF 6 soft hyphens [U+00AD]
  3131.                     if (($textvar TextVars::FC_SMALLCAPS) && isset($this->upperCase[$char])) {
  3132.                         $charw $this->_getCharWidth($cw$this->upperCase[$char]);
  3133.                         if ($charw !== false) {
  3134.                             $charw $charw $this->smCapsScale $this->smCapsStretch 100;
  3135.                             $w+=$charw;
  3136.                         } elseif (isset($this->CurrentFont['desc']['MissingWidth'])) {
  3137.                             $w += $this->CurrentFont['desc']['MissingWidth'];
  3138.                         } elseif (isset($this->CurrentFont['MissingWidth'])) {
  3139.                             $w += $this->CurrentFont['MissingWidth'];
  3140.                         } else {
  3141.                             $w += 500;
  3142.                         }
  3143.                     } else {
  3144.                         $charw $this->_getCharWidth($cw$char);
  3145.                         if ($charw !== false) {
  3146.                             $w+=$charw;
  3147.                         } elseif (isset($this->CurrentFont['desc']['MissingWidth'])) {
  3148.                             $w += $this->CurrentFont['desc']['MissingWidth'];
  3149.                         } elseif (isset($this->CurrentFont['MissingWidth'])) {
  3150.                             $w += $this->CurrentFont['MissingWidth'];
  3151.                         } else {
  3152.                             $w += 500;
  3153.                         }
  3154.                         // mPDF 5.7.1
  3155.                         // Use GPOS OTL
  3156.                         // ...GetStringWidth...
  3157.                         if (isset($this->CurrentFont['useOTL']) && ($this->CurrentFont['useOTL'] & 0xFF) && !empty($OTLdata)) {
  3158.                             if (isset($OTLdata['GPOSinfo'][$i]['wDir']) && $OTLdata['GPOSinfo'][$i]['wDir'] == 'RTL') {
  3159.                                 if (isset($OTLdata['GPOSinfo'][$i]['XAdvanceR']) && $OTLdata['GPOSinfo'][$i]['XAdvanceR']) {
  3160.                                     $w += $OTLdata['GPOSinfo'][$i]['XAdvanceR'] * 1000 $this->CurrentFont['unitsPerEm'];
  3161.                                 }
  3162.                             } else {
  3163.                                 if (isset($OTLdata['GPOSinfo'][$i]['XAdvanceL']) && $OTLdata['GPOSinfo'][$i]['XAdvanceL']) {
  3164.                                     $w += $OTLdata['GPOSinfo'][$i]['XAdvanceL'] * 1000 $this->CurrentFont['unitsPerEm'];
  3165.                                 }
  3166.                             }
  3167.                             // Kashida from GPOS
  3168.                             // Kashida is set as an absolute length value (already set as a proportion based on useKashida %)
  3169.                             if ($includeKashida && isset($OTLdata['GPOSinfo'][$i]['kashida_space']) && $OTLdata['GPOSinfo'][$i]['kashida_space']) {
  3170.                                 $kashida += $OTLdata['GPOSinfo'][$i]['kashida_space'];
  3171.                             }
  3172.                         }
  3173.                         if (($textvar TextVars::FC_KERNING) && $lastchar) {
  3174.                             if (isset($this->CurrentFont['kerninfo'][$lastchar][$char])) {
  3175.                                 $kerning += $this->CurrentFont['kerninfo'][$lastchar][$char];
  3176.                             }
  3177.                         }
  3178.                         $lastchar $char;
  3179.                     }
  3180.                 }
  3181.             } // *CJK-FONTS*
  3182.         } else {
  3183.             if ($this->FontFamily != 'csymbol' && $this->FontFamily != 'czapfdingbats') {
  3184.                 $s str_replace(chr(173), ''$s);
  3185.             }
  3186.             $nb_carac $l strlen($s);
  3187.             if ($this->minwSpacing || $this->fixedlSpacing) {
  3188.                 $nb_spaces substr_count($s' ');
  3189.             }
  3190.             for ($i 0$i $l$i++) {
  3191.                 if (($textvar TextVars::FC_SMALLCAPS) && isset($this->upperCase[ord($s[$i])])) {  // mPDF 5.7.1
  3192.                     $charw $cw[chr($this->upperCase[ord($s[$i])])];
  3193.                     if ($charw !== false) {
  3194.                         $charw $charw $this->smCapsScale $this->smCapsStretch 100;
  3195.                         $w+=$charw;
  3196.                     }
  3197.                 } elseif (isset($cw[$s[$i]])) {
  3198.                     $w += $cw[$s[$i]];
  3199.                 } elseif (isset($cw[ord($s[$i])])) {
  3200.                     $w += $cw[ord($s[$i])];
  3201.                 }
  3202.                 if (($textvar TextVars::FC_KERNING) && $i 0) { // mPDF 5.7.1
  3203.                     if (isset($this->CurrentFont['kerninfo'][$s[($i 1)]][$s[$i]])) {
  3204.                         $kerning += $this->CurrentFont['kerninfo'][$s[($i 1)]][$s[$i]];
  3205.                     }
  3206.                 }
  3207.             }
  3208.         }
  3209.         unset($cw);
  3210.         if ($textvar TextVars::FC_KERNING) {
  3211.             $w += $kerning;
  3212.         } // mPDF 5.7.1
  3213.         $w *= ($this->FontSize 1000);
  3214.         $w += (($nb_carac $nb_spaces) * $this->fixedlSpacing) + ($nb_spaces $this->minwSpacing);
  3215.         $w += $kashida Mpdf::SCALE;
  3216.         return ($w);
  3217.     }
  3218.     function SetLineWidth($width)
  3219.     {
  3220.         // Set line width
  3221.         $this->LineWidth $width;
  3222.         $lwout = (sprintf('%.3F w'$width Mpdf::SCALE));
  3223.         if ($this->page && ((isset($this->pageoutput[$this->page]['LineWidth']) && $this->pageoutput[$this->page]['LineWidth'] != $lwout) || !isset($this->pageoutput[$this->page]['LineWidth']))) {
  3224.             $this->writer->write($lwout);
  3225.         }
  3226.         $this->pageoutput[$this->page]['LineWidth'] = $lwout;
  3227.     }
  3228.     function Line($x1$y1$x2$y2)
  3229.     {
  3230.         // Draw a line
  3231.         $this->writer->write(sprintf('%.3F %.3F m %.3F %.3F l S'$x1 Mpdf::SCALE, ($this->$y1) * Mpdf::SCALE$x2 Mpdf::SCALE, ($this->$y2) * Mpdf::SCALE));
  3232.     }
  3233.     function Arrow($x1$y1$x2$y2$headsize 3$fill 'B'$angle 25)
  3234.     {
  3235.         // F == fill // S == stroke // B == stroke and fill
  3236.         // angle = splay of arrowhead - 1 - 89 degrees
  3237.         if ($fill == 'F') {
  3238.             $fill 'f';
  3239.         } elseif ($fill == 'FD' or $fill == 'DF' or $fill == 'B') {
  3240.             $fill 'B';
  3241.         } else {
  3242.             $fill 'S';
  3243.         }
  3244.         $a atan2(($y2 $y1), ($x2 $x1));
  3245.         $b $a deg2rad($angle);
  3246.         $c $a deg2rad($angle);
  3247.         $x3 $x2 - ($headsize cos($b));
  3248.         $y3 $this->- ($y2 - ($headsize sin($b)));
  3249.         $x4 $x2 - ($headsize cos($c));
  3250.         $y4 $this->- ($y2 - ($headsize sin($c)));
  3251.         $x5 $x3 - ($x3 $x4) / 2// mid point of base of arrowhead - to join arrow line to
  3252.         $y5 $y3 - ($y3 $y4) / 2;
  3253.         $s '';
  3254.         $s .= sprintf('%.3F %.3F m %.3F %.3F l S'$x1 Mpdf::SCALE, ($this->$y1) * Mpdf::SCALE$x5 Mpdf::SCALE$y5 Mpdf::SCALE);
  3255.         $this->writer->write($s);
  3256.         $s '';
  3257.         $s .= sprintf('%.3F %.3F m %.3F %.3F l %.3F %.3F l %.3F %.3F l %.3F %.3F l '$x5 Mpdf::SCALE$y5 Mpdf::SCALE$x3 Mpdf::SCALE$y3 Mpdf::SCALE$x2 Mpdf::SCALE, ($this->$y2) * Mpdf::SCALE$x4 Mpdf::SCALE$y4 Mpdf::SCALE$x5 Mpdf::SCALE$y5 Mpdf::SCALE);
  3258.         $s .= $fill;
  3259.         $this->writer->write($s);
  3260.     }
  3261.     function Rect($x$y$w$h$style '')
  3262.     {
  3263.         // Draw a rectangle
  3264.         if ($style == 'F') {
  3265.             $op 'f';
  3266.         } elseif ($style == 'FD' or $style == 'DF') {
  3267.             $op 'B';
  3268.         } else {
  3269.             $op 'S';
  3270.         }
  3271.         $this->writer->write(sprintf('%.3F %.3F %.3F %.3F re %s'$x Mpdf::SCALE, ($this->$y) * Mpdf::SCALE$w Mpdf::SCALE, -$h Mpdf::SCALE$op));
  3272.     }
  3273.     function AddFontDirectory($directory)
  3274.     {
  3275.         $this->fontDir[] = $directory;
  3276.         $this->fontFileFinder->setDirectories($this->fontDir);
  3277.     }
  3278.     function AddFont($family$style '')
  3279.     {
  3280.         if (empty($family)) {
  3281.             return;
  3282.         }
  3283.         $family strtolower($family);
  3284.         $style strtoupper($style);
  3285.         $style str_replace('U'''$style);
  3286.         if ($style == 'IB') {
  3287.             $style 'BI';
  3288.         }
  3289.         $fontkey $family $style;
  3290.         // check if the font has been already added
  3291.         if (isset($this->fonts[$fontkey])) {
  3292.             return;
  3293.         }
  3294.         /* -- CJK-FONTS -- */
  3295.         if (in_array($family$this->available_CJK_fonts)) {
  3296.             if (empty($this->Big5_widths)) {
  3297.                 require __DIR__ '/../data/CJKdata.php';
  3298.             }
  3299.             $this->AddCJKFont($family); // don't need to add style
  3300.             return;
  3301.         }
  3302.         /* -- END CJK-FONTS -- */
  3303.         if ($this->usingCoreFont) {
  3304.             throw new \Mpdf\MpdfException("mPDF Error - problem with Font management");
  3305.         }
  3306.         $stylekey $style;
  3307.         if (!$style) {
  3308.             $stylekey 'R';
  3309.         }
  3310.         if (!isset($this->fontdata[$family][$stylekey]) || !$this->fontdata[$family][$stylekey]) {
  3311.             throw new \Mpdf\MpdfException(sprintf('Font "%s%s%s" is not supported'$family$style ' - ' ''$style));
  3312.         }
  3313.         /* Setup defaults */
  3314.         $font = [
  3315.             'name' => '',
  3316.             'type' => '',
  3317.             'desc' => '',
  3318.             'panose' => '',
  3319.             'unitsPerEm' => '',
  3320.             'up' => '',
  3321.             'ut' => '',
  3322.             'strs' => '',
  3323.             'strp' => '',
  3324.             'sip' => false,
  3325.             'smp' => false,
  3326.             'useOTL' => 0,
  3327.             'fontmetrics' => '',
  3328.             'haskerninfo' => false,
  3329.             'haskernGPOS' => false,
  3330.             'hassmallcapsGSUB' => false,
  3331.             'BMPselected' => false,
  3332.             'GSUBScriptLang' => [],
  3333.             'GSUBFeatures' => [],
  3334.             'GSUBLookups' => [],
  3335.             'GPOSScriptLang' => [],
  3336.             'GPOSFeatures' => [],
  3337.             'GPOSLookups' => [],
  3338.             'rtlPUAstr' => '',
  3339.         ];
  3340.         $fontCacheFilename $fontkey '.mtx.json';
  3341.         if ($this->fontCache->jsonHas($fontCacheFilename)) {
  3342.             $font $this->fontCache->jsonLoad($fontCacheFilename);
  3343.         }
  3344.         $ttffile $this->fontFileFinder->findFontFile($this->fontdata[$family][$stylekey]);
  3345.         $ttfstat stat($ttffile);
  3346.         $TTCfontID = isset($this->fontdata[$family]['TTCfontID'][$stylekey]) ? isset($this->fontdata[$family]['TTCfontID'][$stylekey]) : 0;
  3347.         $fontUseOTL = isset($this->fontdata[$family]['useOTL']) ? $this->fontdata[$family]['useOTL'] : false;
  3348.         $BMPonly in_array($family$this->BMPonly) ? true false;
  3349.         $regenerate false;
  3350.         if ($BMPonly && !$font['BMPselected']) {
  3351.             $regenerate true;
  3352.         } elseif (!$BMPonly && $font['BMPselected']) {
  3353.             $regenerate true;
  3354.         }
  3355.         if ($fontUseOTL && $font['useOTL'] != $fontUseOTL) {
  3356.             $regenerate true;
  3357.             $font['useOTL'] = $fontUseOTL;
  3358.         } elseif (!$fontUseOTL && $font['useOTL']) {
  3359.             $regenerate true;
  3360.             $font['useOTL'] = 0;
  3361.         }
  3362.         if ($this->fontDescriptor != $font['fontmetrics']) {
  3363.             $regenerate true;
  3364.         } // mPDF 6
  3365.         if (empty($font['name']) || $font['originalsize'] != $ttfstat['size'] || $regenerate) {
  3366.             $generator = new MetricsGenerator($this->fontCache$this->fontDescriptor);
  3367.             $generator->generateMetrics(
  3368.                 $ttffile,
  3369.                 $ttfstat,
  3370.                 $fontkey,
  3371.                 $TTCfontID,
  3372.                 $this->debugfonts,
  3373.                 $BMPonly,
  3374.                 $font['useOTL'],
  3375.                 $fontUseOTL
  3376.             );
  3377.             $font $this->fontCache->jsonLoad($fontCacheFilename);
  3378.             $cw $this->fontCache->load($fontkey '.cw.dat');
  3379.             $glyphIDtoUni $this->fontCache->load($fontkey '.gid.dat');
  3380.         } else {
  3381.             if ($this->fontCache->has($fontkey '.cw.dat')) {
  3382.                 $cw $this->fontCache->load($fontkey '.cw.dat');
  3383.             }
  3384.             if ($this->fontCache->has($fontkey '.gid.dat')) {
  3385.                 $glyphIDtoUni $this->fontCache->load($fontkey '.gid.dat');
  3386.             }
  3387.         }
  3388.         if (isset($this->fontdata[$family]['sip-ext']) && $this->fontdata[$family]['sip-ext']) {
  3389.             $sipext $this->fontdata[$family]['sip-ext'];
  3390.         } else {
  3391.             $sipext '';
  3392.         }
  3393.         // Override with values from config_font.php
  3394.         if (isset($this->fontdata[$family]['Ascent']) && $this->fontdata[$family]['Ascent']) {
  3395.             $desc['Ascent'] = $this->fontdata[$family]['Ascent'];
  3396.         }
  3397.         if (isset($this->fontdata[$family]['Descent']) && $this->fontdata[$family]['Descent']) {
  3398.             $desc['Descent'] = $this->fontdata[$family]['Descent'];
  3399.         }
  3400.         if (isset($this->fontdata[$family]['Leading']) && $this->fontdata[$family]['Leading']) {
  3401.             $desc['Leading'] = $this->fontdata[$family]['Leading'];
  3402.         }
  3403.         $i count($this->fonts) + $this->extraFontSubsets 1;
  3404.         $this->fonts[$fontkey] = [
  3405.             'i' => $i,
  3406.             'name' => $font['name'],
  3407.             'type' => $font['type'],
  3408.             'desc' => $font['desc'],
  3409.             'panose' => $font['panose'],
  3410.             'unitsPerEm' => $font['unitsPerEm'],
  3411.             'up' => $font['up'],
  3412.             'ut' => $font['ut'],
  3413.             'strs' => $font['strs'],
  3414.             'strp' => $font['strp'],
  3415.             'cw' => $cw,
  3416.             'ttffile' => $ttffile,
  3417.             'fontkey' => $fontkey,
  3418.             'used' => false,
  3419.             'sip' => $font['sip'],
  3420.             'sipext' => $sipext,
  3421.             'smp' => $font['smp'],
  3422.             'TTCfontID' => $TTCfontID,
  3423.             'useOTL' => $fontUseOTL,
  3424.             'useKashida' => (isset($this->fontdata[$family]['useKashida']) ? $this->fontdata[$family]['useKashida'] : false),
  3425.             'GSUBScriptLang' => $font['GSUBScriptLang'],
  3426.             'GSUBFeatures' => $font['GSUBFeatures'],
  3427.             'GSUBLookups' => $font['GSUBLookups'],
  3428.             'GPOSScriptLang' => $font['GPOSScriptLang'],
  3429.             'GPOSFeatures' => $font['GPOSFeatures'],
  3430.             'GPOSLookups' => $font['GPOSLookups'],
  3431.             'rtlPUAstr' => $font['rtlPUAstr'],
  3432.             'glyphIDtoUni' => $glyphIDtoUni,
  3433.             'haskerninfo' => $font['haskerninfo'],
  3434.             'haskernGPOS' => $font['haskernGPOS'],
  3435.             'hassmallcapsGSUB' => $font['hassmallcapsGSUB'],
  3436.         ];
  3437.         if (!$font['sip'] && !$font['smp']) {
  3438.             $subsetRange range(32127);
  3439.             $this->fonts[$fontkey]['subset'] = array_combine($subsetRange$subsetRange);
  3440.         } else {
  3441.             $this->fonts[$fontkey]['subsets'] = [=> range(0127)];
  3442.             $this->fonts[$fontkey]['subsetfontids'] = [$i];
  3443.         }
  3444.         if ($font['haskerninfo']) {
  3445.             $this->fonts[$fontkey]['kerninfo'] = $font['kerninfo'];
  3446.         }
  3447.         $this->FontFiles[$fontkey] = [
  3448.             'length1' => $font['originalsize'],
  3449.             'type' => 'TTF',
  3450.             'ttffile' => $ttffile,
  3451.             'sip' => $font['sip'],
  3452.             'smp' => $font['smp'],
  3453.         ];
  3454.         unset($cw);
  3455.     }
  3456.     function SetFont($family$style ''$size 0$write true$forcewrite false)
  3457.     {
  3458.         $family strtolower($family);
  3459.         if (!$this->onlyCoreFonts) {
  3460.             if ($family == 'sans' || $family == 'sans-serif') {
  3461.                 $family $this->sans_fonts[0];
  3462.             }
  3463.             if ($family == 'serif') {
  3464.                 $family $this->serif_fonts[0];
  3465.             }
  3466.             if ($family == 'mono' || $family == 'monospace') {
  3467.                 $family $this->mono_fonts[0];
  3468.             }
  3469.         }
  3470.         if (isset($this->fonttrans[$family]) && $this->fonttrans[$family]) {
  3471.             $family $this->fonttrans[$family];
  3472.         }
  3473.         if ($family == '') {
  3474.             if ($this->FontFamily) {
  3475.                 $family $this->FontFamily;
  3476.             } elseif ($this->default_font) {
  3477.                 $family $this->default_font;
  3478.             } else {
  3479.                 throw new \Mpdf\MpdfException("No font or default font set!");
  3480.             }
  3481.         }
  3482.         $this->ReqFontStyle $style// required or requested style - used later for artificial bold/italic
  3483.         if (($family == 'csymbol') || ($family == 'czapfdingbats') || ($family == 'ctimes') || ($family == 'ccourier') || ($family == 'chelvetica')) {
  3484.             if ($this->PDFA || $this->PDFX) {
  3485.                 if ($family == 'csymbol' || $family == 'czapfdingbats') {
  3486.                     throw new \Mpdf\MpdfException("Symbol and Zapfdingbats cannot be embedded in mPDF (required for PDFA1-b or PDFX/1-a).");
  3487.                 }
  3488.                 if ($family == 'ctimes' || $family == 'ccourier' || $family == 'chelvetica') {
  3489.                     if (($this->PDFA && !$this->PDFAauto) || ($this->PDFX && !$this->PDFXauto)) {
  3490.                         $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.)";
  3491.                     }
  3492.                     if ($family == 'chelvetica') {
  3493.                         $family 'sans';
  3494.                     }
  3495.                     if ($family == 'ctimes') {
  3496.                         $family 'serif';
  3497.                     }
  3498.                     if ($family == 'ccourier') {
  3499.                         $family 'mono';
  3500.                     }
  3501.                 }
  3502.                 $this->usingCoreFont false;
  3503.             } else {
  3504.                 $this->usingCoreFont true;
  3505.             }
  3506.             if ($family == 'csymbol' || $family == 'czapfdingbats') {
  3507.                 $style '';
  3508.             }
  3509.         } else {
  3510.             $this->usingCoreFont false;
  3511.         }
  3512.         // mPDF 5.7.1
  3513.         if ($style) {
  3514.             $style strtoupper($style);
  3515.             if ($style == 'IB') {
  3516.                 $style 'BI';
  3517.             }
  3518.         }
  3519.         if (!$size) {
  3520.             $size $this->FontSizePt;
  3521.         }
  3522.         $fontkey $family $style;
  3523.         $stylekey $style;
  3524.         if (!$stylekey) {
  3525.             $stylekey "R";
  3526.         }
  3527.         if (!$this->onlyCoreFonts && !$this->usingCoreFont) {
  3528.             if (!isset($this->fonts[$fontkey]) || count($this->default_available_fonts) != count($this->available_unifonts)) { // not already added
  3529.                 /* -- CJK-FONTS -- */
  3530.                 if (in_array($fontkey$this->available_CJK_fonts)) {
  3531.                     if (!isset($this->fonts[$fontkey])) { // already added
  3532.                         if (empty($this->Big5_widths)) {
  3533.                             require __DIR__ '/../data/CJKdata.php';
  3534.                         }
  3535.                         $this->AddCJKFont($family); // don't need to add style
  3536.                     }
  3537.                 } else { // Test to see if requested font/style is available - or substitute /* -- END CJK-FONTS -- */
  3538.                     if (!in_array($fontkey$this->available_unifonts)) {
  3539.                         // If font[nostyle] exists - set it
  3540.                         if (in_array($family$this->available_unifonts)) {
  3541.                             $style '';
  3542.                         } // elseif only one font available - set it (assumes if only one font available it will not have a style)
  3543.                         elseif (count($this->available_unifonts) == 1) {
  3544.                             $family $this->available_unifonts[0];
  3545.                             $style '';
  3546.                         } else {
  3547.                             $found 0;
  3548.                             // else substitute font of similar type
  3549.                             if (in_array($family$this->sans_fonts)) {
  3550.                                 $i array_intersect($this->sans_fonts$this->available_unifonts);
  3551.                                 if (count($i)) {
  3552.                                     $i array_values($i);
  3553.                                     // with requested style if possible
  3554.                                     if (!in_array(($i[0] . $style), $this->available_unifonts)) {
  3555.                                         $style '';
  3556.                                     }
  3557.                                     $family $i[0];
  3558.                                     $found 1;
  3559.                                 }
  3560.                             } elseif (in_array($family$this->serif_fonts)) {
  3561.                                 $i array_intersect($this->serif_fonts$this->available_unifonts);
  3562.                                 if (count($i)) {
  3563.                                     $i array_values($i);
  3564.                                     // with requested style if possible
  3565.                                     if (!in_array(($i[0] . $style), $this->available_unifonts)) {
  3566.                                         $style '';
  3567.                                     }
  3568.                                     $family $i[0];
  3569.                                     $found 1;
  3570.                                 }
  3571.                             } elseif (in_array($family$this->mono_fonts)) {
  3572.                                 $i array_intersect($this->mono_fonts$this->available_unifonts);
  3573.                                 if (count($i)) {
  3574.                                     $i array_values($i);
  3575.                                     // with requested style if possible
  3576.                                     if (!in_array(($i[0] . $style), $this->available_unifonts)) {
  3577.                                         $style '';
  3578.                                     }
  3579.                                     $family $i[0];
  3580.                                     $found 1;
  3581.                                 }
  3582.                             }
  3583.                             if (!$found) {
  3584.                                 // set first available font
  3585.                                 $fs $this->available_unifonts[0];
  3586.                                 preg_match('/^([a-z_0-9\-]+)([BI]{0,2})$/'$fs$fas); // Allow "-"
  3587.                                 // with requested style if possible
  3588.                                 $ws $fas[1] . $style;
  3589.                                 if (in_array($ws$this->available_unifonts)) {
  3590.                                     $family $fas[1]; // leave $style as is
  3591.                                 } elseif (in_array($fas[1], $this->available_unifonts)) {
  3592.                                     // or without style
  3593.                                     $family $fas[1];
  3594.                                     $style '';
  3595.                                 } else {
  3596.                                     // or with the style specified
  3597.                                     $family $fas[1];
  3598.                                     $style $fas[2];
  3599.                                 }
  3600.                             }
  3601.                         }
  3602.                         $fontkey $family $style;
  3603.                     }
  3604.                 }
  3605.             }
  3606.             // try to add font (if not already added)
  3607.             $this->AddFont($family$style);
  3608.             // Test if font is already selected
  3609.             if ($this->FontFamily == $family && $this->FontFamily == $this->currentfontfamily && $this->FontStyle == $style && $this->FontStyle == $this->currentfontstyle && $this->FontSizePt == $size && $this->FontSizePt == $this->currentfontsize && !$forcewrite) {
  3610.                 return $family;
  3611.             }
  3612.             $fontkey $family $style;
  3613.             // Select it
  3614.             $this->FontFamily $family;
  3615.             $this->FontStyle $style;
  3616.             $this->FontSizePt $size;
  3617.             $this->FontSize $size Mpdf::SCALE;
  3618.             $this->CurrentFont = &$this->fonts[$fontkey];
  3619.             if ($write) {
  3620.                 $fontout = (sprintf('BT /F%d %.3F Tf ET'$this->CurrentFont['i'], $this->FontSizePt));
  3621.                 if ($this->page && ((isset($this->pageoutput[$this->page]['Font']) && $this->pageoutput[$this->page]['Font'] != $fontout) || !isset($this->pageoutput[$this->page]['Font']))) {
  3622.                     $this->writer->write($fontout);
  3623.                 }
  3624.                 $this->pageoutput[$this->page]['Font'] = $fontout;
  3625.             }
  3626.             // Added - currentfont (lowercase) used in HTML2PDF
  3627.             $this->currentfontfamily $family;
  3628.             $this->currentfontsize $size;
  3629.             $this->currentfontstyle $style;
  3630.             $this->setMBencoding('UTF-8');
  3631.         } else {  // if using core fonts
  3632.             if ($this->PDFA || $this->PDFX) {
  3633.                 throw new \Mpdf\MpdfException('Core Adobe fonts cannot be embedded in mPDF (required for PDFA1-b or PDFX/1-a) - cannot use option to use core fonts.');
  3634.             }
  3635.             $this->setMBencoding('windows-1252');
  3636.             // Test if font is already selected
  3637.             if (($this->FontFamily == $family) and ( $this->FontStyle == $style) and ( $this->FontSizePt == $size) && !$forcewrite) {
  3638.                 return $family;
  3639.             }
  3640.             if (!isset($this->CoreFonts[$fontkey])) {
  3641.                 if (in_array($family$this->serif_fonts)) {
  3642.                     $family 'ctimes';
  3643.                 } elseif (in_array($family$this->mono_fonts)) {
  3644.                     $family 'ccourier';
  3645.                 } else {
  3646.                     $family 'chelvetica';
  3647.                 }
  3648.                 $this->usingCoreFont true;
  3649.                 $fontkey $family $style;
  3650.             }
  3651.             if (!isset($this->fonts[$fontkey])) {
  3652.                 // STANDARD CORE FONTS
  3653.                 if (isset($this->CoreFonts[$fontkey])) {
  3654.                     // Load metric file
  3655.                     $file $family;
  3656.                     if ($family == 'ctimes' || $family == 'chelvetica' || $family == 'ccourier') {
  3657.                         $file .= strtolower($style);
  3658.                     }
  3659.                     require __DIR__ '/../data/font/' $file '.php';
  3660.                     if (!isset($cw)) {
  3661.                         throw new \Mpdf\MpdfException(sprintf('Could not include font metric file "%s"'$file));
  3662.                     }
  3663.                     $i count($this->fonts) + $this->extraFontSubsets 1;
  3664.                     $this->fonts[$fontkey] = ['i' => $i'type' => 'core''name' => $this->CoreFonts[$fontkey], 'desc' => $desc'up' => $up'ut' => $ut'cw' => $cw];
  3665.                     if ($this->useKerning && isset($kerninfo)) {
  3666.                         $this->fonts[$fontkey]['kerninfo'] = $kerninfo;
  3667.                     }
  3668.                 } else {
  3669.                     throw new \Mpdf\MpdfException(sprintf('Font %s not defined'$fontkey));
  3670.                 }
  3671.             }
  3672.             // Test if font is already selected
  3673.             if (($this->FontFamily == $family) and ( $this->FontStyle == $style) and ( $this->FontSizePt == $size) && !$forcewrite) {
  3674.                 return $family;
  3675.             }
  3676.             // Select it
  3677.             $this->FontFamily $family;
  3678.             $this->FontStyle $style;
  3679.             $this->FontSizePt $size;
  3680.             $this->FontSize $size Mpdf::SCALE;
  3681.             $this->CurrentFont = &$this->fonts[$fontkey];
  3682.             if ($write) {
  3683.                 $fontout = (sprintf('BT /F%d %.3F Tf ET'$this->CurrentFont['i'], $this->FontSizePt));
  3684.                 if ($this->page && ((isset($this->pageoutput[$this->page]['Font']) && $this->pageoutput[$this->page]['Font'] != $fontout) || !isset($this->pageoutput[$this->page]['Font']))) {
  3685.                     $this->writer->write($fontout);
  3686.                 }
  3687.                 $this->pageoutput[$this->page]['Font'] = $fontout;
  3688.             }
  3689.             // Added - currentfont (lowercase) used in HTML2PDF
  3690.             $this->currentfontfamily $family;
  3691.             $this->currentfontsize $size;
  3692.             $this->currentfontstyle $style;
  3693.         }
  3694.         return $family;
  3695.     }
  3696.     function SetFontSize($size$write true)
  3697.     {
  3698.         // Set font size in points
  3699.         if ($this->FontSizePt == $size) {
  3700.             return;
  3701.         }
  3702.         $this->FontSizePt $size;
  3703.         $this->FontSize $size Mpdf::SCALE;
  3704.         $this->currentfontsize $size;
  3705.         if ($write) {
  3706.             $fontout = (sprintf('BT /F%d %.3F Tf ET'$this->CurrentFont['i'], $this->FontSizePt));
  3707.             // Edited mPDF 3.0
  3708.             if ($this->page && ((isset($this->pageoutput[$this->page]['Font']) && $this->pageoutput[$this->page]['Font'] != $fontout) || !isset($this->pageoutput[$this->page]['Font']))) {
  3709.                 $this->writer->write($fontout);
  3710.             }
  3711.             $this->pageoutput[$this->page]['Font'] = $fontout;
  3712.         }
  3713.     }
  3714.     function AddLink()
  3715.     {
  3716.         // Create a new internal link
  3717.         $n count($this->links) + 1;
  3718.         $this->links[$n] = [00];
  3719.         return $n;
  3720.     }
  3721.     function SetLink($link$y 0$page = -1)
  3722.     {
  3723.         // Set destination of internal link
  3724.         if ($y == -1) {
  3725.             $y $this->y;
  3726.         }
  3727.         if ($page == -1) {
  3728.             $page $this->page;
  3729.         }
  3730.         $this->links[$link] = [$page$y];
  3731.     }
  3732.     function Link($x$y$w$h$link)
  3733.     {
  3734.         $l = [$x Mpdf::SCALE$this->hPt $y Mpdf::SCALE$w Mpdf::SCALE$h Mpdf::SCALE$link];
  3735.         if ($this->keep_block_together) { // don't write yet
  3736.             return;
  3737.         } elseif ($this->table_rotate) { // *TABLES*
  3738.             $this->tbrot_Links[$this->page][] = $l// *TABLES*
  3739.             return; // *TABLES*
  3740.         // *TABLES*
  3741.         elseif ($this->kwt) {
  3742.             $this->kwt_Links[$this->page][] = $l;
  3743.             return;
  3744.         }
  3745.         if ($this->writingHTMLheader || $this->writingHTMLfooter) {
  3746.             $this->HTMLheaderPageLinks[] = $l;
  3747.             return;
  3748.         }
  3749.         // Put a link on the page
  3750.         $this->PageLinks[$this->page][] = $l;
  3751.         // Save cross-reference to Column buffer
  3752.         $ref count($this->PageLinks[$this->page]) - 1// *COLUMNS*
  3753.         $this->columnLinks[$this->CurrCol][(int) $this->x][(int) $this->y] = $ref// *COLUMNS*
  3754.     }
  3755.     function Text($x$y$txt$OTLdata = [], $textvar 0$aixextra ''$coordsys ''$return false)
  3756.     {
  3757.         // Output (or return) a string
  3758.         // Called (internally) by Watermark() & _tableWrite() [rotated cells] & TableHeaderFooter() & WriteText()
  3759.         // Called also from classes/svg.php
  3760.         // Expects Font to be set
  3761.         // Expects input to be mb_encoded if necessary and RTL reversed & OTL processed
  3762.         // ARTIFICIAL BOLD AND ITALIC
  3763.         $s 'q ';
  3764.         if ($this->falseBoldWeight && strpos($this->ReqFontStyle"B") !== false && strpos($this->FontStyle"B") === false) {
  3765.             $s .= '2 Tr 1 J 1 j ';
  3766.             $s .= sprintf('%.3F w ', ($this->FontSize 130) * Mpdf::SCALE $this->falseBoldWeight);
  3767.             $tc strtoupper($this->TextColor); // change 0 0 0 rg to 0 0 0 RG
  3768.             if ($this->FillColor != $tc) {
  3769.                 $s .= $tc ' ';
  3770.             }  // stroke (outline) = same colour as text(fill)
  3771.         }
  3772.         if (strpos($this->ReqFontStyle"I") !== false && strpos($this->FontStyle"I") === false) {
  3773.             $aix '1 0 0.261799 1 %.3F %.3F Tm';
  3774.         } else {
  3775.             $aix '%.3F %.3F Td';
  3776.         }
  3777.         $aix $aixextra $aix;
  3778.         if ($this->ColorFlag) {
  3779.             $s .= $this->TextColor ' ';
  3780.         }
  3781.         $this->CurrentFont['used'] = true;
  3782.         if ($this->usingCoreFont) {
  3783.             $txt2 str_replace(chr(160), chr(32), $txt);
  3784.         } else {
  3785.             $txt2 str_replace(chr(194) . chr(160), chr(32), $txt);
  3786.         }
  3787.         $px $x;
  3788.         $py $y;
  3789.         if ($coordsys != 'SVG') {
  3790.             $px $x Mpdf::SCALE;
  3791.             $py = ($this->$y) * Mpdf::SCALE;
  3792.         }
  3793.         /** ************** SIMILAR TO Cell() ************************ */
  3794.         // IF corefonts AND NOT SmCaps AND NOT Kerning
  3795.         // Just output text
  3796.         if ($this->usingCoreFont && !($textvar TextVars::FC_SMALLCAPS) && !($textvar TextVars::FC_KERNING)) {
  3797.             $txt2 $this->writer->escape($txt2);
  3798.             $s .= sprintf('BT ' $aix ' (%s) Tj ET'$px$py$txt2);
  3799.         } // IF NOT corefonts [AND NO wordspacing] AND NOT SIP/SMP AND NOT SmCaps AND NOT Kerning AND NOT OTL
  3800.         // Just output text
  3801.         elseif (!$this->usingCoreFont && !($textvar TextVars::FC_SMALLCAPS) && !($textvar TextVars::FC_KERNING) && !(isset($this->CurrentFont['useOTL']) && ($this->CurrentFont['useOTL'] & 0xFF) && !empty($OTLdata['GPOSinfo']))) {
  3802.             // IF SIP/SMP
  3803.             if ($this->CurrentFont['sip'] || $this->CurrentFont['smp']) {
  3804.                 $txt2 $this->UTF8toSubset($txt2);
  3805.                 $s .=sprintf('BT ' $aix ' %s Tj ET'$px$py$txt2);
  3806.             } // NOT SIP/SMP
  3807.             else {
  3808.                 $txt2 $this->writer->utf8ToUtf16BigEndian($txt2false);
  3809.                 $txt2 $this->writer->escape($txt2);
  3810.                 $s .=sprintf('BT ' $aix ' (%s) Tj ET'$px$py$txt2);
  3811.             }
  3812.         } // IF NOT corefonts [AND IS wordspacing] AND NOT SIP AND NOT SmCaps AND NOT Kerning AND NOT OTL
  3813.         // Not required here (cf. Cell() )
  3814.         // ELSE (IF SmCaps || Kerning || OTL) [corefonts or not corefonts; SIP or SMP or BMP]
  3815.         else {
  3816.             $s .= $this->applyGPOSpdf($txt2$aix$px$py$OTLdata$textvar);
  3817.         }
  3818.         /*         * ************** END ************************ */
  3819.         $s .= ' ';
  3820.         if (($textvar TextVars::FD_UNDERLINE) && $txt != '') { // mPDF 5.7.1
  3821.             $c strtoupper($this->TextColor); // change 0 0 0 rg to 0 0 0 RG
  3822.             if ($this->FillColor != $c) {
  3823.                 $s.= ' ' $c ' ';
  3824.             }
  3825.             if (isset($this->CurrentFont['up']) && $this->CurrentFont['up']) {
  3826.                 $up $this->CurrentFont['up'];
  3827.             } else {
  3828.                 $up = -100;
  3829.             }
  3830.             $adjusty = (-$up 1000 $this->FontSize);
  3831.             if (isset($this->CurrentFont['ut']) && $this->CurrentFont['ut']) {
  3832.                 $ut $this->CurrentFont['ut'] / 1000 $this->FontSize;
  3833.             } else {
  3834.                 $ut 60 1000 $this->FontSize;
  3835.             }
  3836.             $olw $this->LineWidth;
  3837.             $s .= ' ' . (sprintf(' %.3F w'$ut Mpdf::SCALE));
  3838.             $s .= ' ' $this->_dounderline($x$y $adjusty$txt$OTLdata$textvar);
  3839.             $s .= ' ' . (sprintf(' %.3F w'$olw Mpdf::SCALE));
  3840.             if ($this->FillColor != $c) {
  3841.                 $s.= ' ' $this->FillColor ' ';
  3842.             }
  3843.         }
  3844.         // STRIKETHROUGH
  3845.         if (($textvar TextVars::FD_LINETHROUGH) && $txt != '') { // mPDF 5.7.1
  3846.             $c strtoupper($this->TextColor); // change 0 0 0 rg to 0 0 0 RG
  3847.             if ($this->FillColor != $c) {
  3848.                 $s.= ' ' $c ' ';
  3849.             }
  3850.             // Superscript and Subscript Y coordinate adjustment (now for striked-through texts)
  3851.             if (isset($this->CurrentFont['desc']['CapHeight']) && $this->CurrentFont['desc']['CapHeight']) {
  3852.                 $ch $this->CurrentFont['desc']['CapHeight'];
  3853.             } else {
  3854.                 $ch 700;
  3855.             }
  3856.             $adjusty = (-$ch 1000 $this->FontSize) * 0.35;
  3857.             if (isset($this->CurrentFont['ut']) && $this->CurrentFont['ut']) {
  3858.                 $ut $this->CurrentFont['ut'] / 1000 $this->FontSize;
  3859.             } else {
  3860.                 $ut 60 1000 $this->FontSize;
  3861.             }
  3862.             $olw $this->LineWidth;
  3863.             $s .= ' ' . (sprintf(' %.3F w'$ut Mpdf::SCALE));
  3864.             $s .= ' ' $this->_dounderline($x$y $adjusty$txt$OTLdata$textvar);
  3865.             $s .= ' ' . (sprintf(' %.3F w'$olw Mpdf::SCALE));
  3866.             if ($this->FillColor != $c) {
  3867.                 $s.= ' ' $this->FillColor ' ';
  3868.             }
  3869.         }
  3870.         $s .= 'Q';
  3871.         if ($return) {
  3872.             return $s " \n";
  3873.         }
  3874.         $this->writer->write($s);
  3875.     }
  3876.     /* -- DIRECTW -- */
  3877.     function WriteText($x$y$txt)
  3878.     {
  3879.         // Output a string using Text() but does encoding and text reversing of RTL
  3880.         $txt $this->purify_utf8_text($txt);
  3881.         if ($this->text_input_as_HTML) {
  3882.             $txt $this->all_entities_to_utf8($txt);
  3883.         }
  3884.         if ($this->usingCoreFont) {
  3885.             $txt mb_convert_encoding($txt$this->mb_enc'UTF-8');
  3886.         }
  3887.         // DIRECTIONALITY
  3888.         if (preg_match("/([" $this->pregRTLchars "])/u"$txt)) {
  3889.             $this->biDirectional true;
  3890.         } // *OTL*
  3891.         $textvar 0;
  3892.         $save_OTLtags $this->OTLtags;
  3893.         $this->OTLtags = [];
  3894.         if ($this->useKerning) {
  3895.             if ($this->CurrentFont['haskernGPOS']) {
  3896.                 $this->OTLtags['Plus'] .= ' kern';
  3897.             } else {
  3898.                 $textvar = ($textvar TextVars::FC_KERNING);
  3899.             }
  3900.         }
  3901.         /* -- OTL -- */
  3902.         // Use OTL OpenType Table Layout - GSUB & GPOS
  3903.         if (isset($this->CurrentFont['useOTL']) && $this->CurrentFont['useOTL']) {
  3904.             $txt $this->otl->applyOTL($txt$this->CurrentFont['useOTL']);
  3905.             $OTLdata $this->otl->OTLdata;
  3906.         }
  3907.         /* -- END OTL -- */
  3908.         $this->OTLtags $save_OTLtags;
  3909.         $this->magic_reverse_dir($txt$this->directionality$OTLdata);
  3910.         $this->Text($x$y$txt$OTLdata$textvar);
  3911.     }
  3912.     function WriteCell($w$h 0$txt ''$border 0$ln 0$align ''$fill 0$link ''$currentx 0)
  3913.     {
  3914.         // Output a cell using Cell() but does encoding and text reversing of RTL
  3915.         $txt $this->purify_utf8_text($txt);
  3916.         if ($this->text_input_as_HTML) {
  3917.             $txt $this->all_entities_to_utf8($txt);
  3918.         }
  3919.         if ($this->usingCoreFont) {
  3920.             $txt mb_convert_encoding($txt$this->mb_enc'UTF-8');
  3921.         }
  3922.         // DIRECTIONALITY
  3923.         if (preg_match("/([" $this->pregRTLchars "])/u"$txt)) {
  3924.             $this->biDirectional true;
  3925.         } // *OTL*
  3926.         $textvar 0;
  3927.         $save_OTLtags $this->OTLtags;
  3928.         $this->OTLtags = [];
  3929.         if ($this->useKerning) {
  3930.             if ($this->CurrentFont['haskernGPOS']) {
  3931.                 $this->OTLtags['Plus'] .= ' kern';
  3932.             } else {
  3933.                 $textvar = ($textvar TextVars::FC_KERNING);
  3934.             }
  3935.         }
  3936.         /* -- OTL -- */
  3937.         // Use OTL OpenType Table Layout - GSUB & GPOS
  3938.         if (isset($this->CurrentFont['useOTL']) && $this->CurrentFont['useOTL']) {
  3939.             $txt $this->otl->applyOTL($txt$this->CurrentFont['useOTL']);
  3940.             $OTLdata $this->otl->OTLdata;
  3941.         }
  3942.         /* -- END OTL -- */
  3943.         $this->OTLtags $save_OTLtags;
  3944.         $this->magic_reverse_dir($txt$this->directionality$OTLdata);
  3945.         $this->Cell($w$h$txt$border$ln$align$fill$link$currentx00'M'0false$OTLdata$textvar);
  3946.     }
  3947.     /* -- END DIRECTW -- */
  3948.     function ResetSpacing()
  3949.     {
  3950.         if ($this->ws != 0) {
  3951.             $this->writer->write('BT 0 Tw ET');
  3952.         }
  3953.         $this->ws 0;
  3954.         if ($this->charspacing != 0) {
  3955.             $this->writer->write('BT 0 Tc ET');
  3956.         }
  3957.         $this->charspacing 0;
  3958.     }
  3959.     function SetSpacing($cs$ws)
  3960.     {
  3961.         if (intval($cs 1000) == 0) {
  3962.             $cs 0;
  3963.         }
  3964.         if ($cs) {
  3965.             $this->writer->write(sprintf('BT %.3F Tc ET'$cs));
  3966.         } elseif ($this->charspacing != 0) {
  3967.             $this->writer->write('BT 0 Tc ET');
  3968.         }
  3969.         $this->charspacing $cs;
  3970.         if (intval($ws 1000) == 0) {
  3971.             $ws 0;
  3972.         }
  3973.         if ($ws) {
  3974.             $this->writer->write(sprintf('BT %.3F Tw ET'$ws));
  3975.         } elseif ($this->ws != 0) {
  3976.             $this->writer->write('BT 0 Tw ET');
  3977.         }
  3978.         $this->ws $ws;
  3979.     }
  3980.     // WORD SPACING
  3981.     function GetJspacing($nc$ns$w$inclCursive, &$cOTLdata)
  3982.     {
  3983.         $kashida_present false;
  3984.         $kashida_space 0;
  3985.         if ($w && $inclCursive && isset($this->CurrentFont['useKashida']) && $this->CurrentFont['useKashida'] && !empty($cOTLdata)) {
  3986.             for ($c 0$c count($cOTLdata); $c++) {
  3987.                 for ($i 0$i strlen($cOTLdata[$c]['group']); $i++) {
  3988.                     if (isset($cOTLdata[$c]['GPOSinfo'][$i]['kashida']) && $cOTLdata[$c]['GPOSinfo'][$i]['kashida'] > 0) {
  3989.                         $kashida_present true;
  3990.                         break 2;
  3991.                     }
  3992.                 }
  3993.             }
  3994.         }
  3995.         if ($kashida_present) {
  3996.             $k_ctr 0;  // Number of kashida points
  3997.             $k_total 0;  // Total of kashida values (priority)
  3998.             // Reset word
  3999.             $max_kashida_in_word 0;
  4000.             $last_kashida_in_word = -1;
  4001.             for ($c 0$c count($cOTLdata); $c++) {
  4002.                 for ($i 0$i strlen($cOTLdata[$c]['group']); $i++) {
  4003.                     if ($cOTLdata[$c]['group'][$i] == 'S') {
  4004.                         // Save from last word
  4005.                         if ($max_kashida_in_word) {
  4006.                             $k_ctr++;
  4007.                             $k_total $max_kashida_in_word;
  4008.                         }
  4009.                         // Reset word
  4010.                         $max_kashida_in_word 0;
  4011.                         $last_kashida_in_word = -1;
  4012.                     }
  4013.                     if (isset($cOTLdata[$c]['GPOSinfo'][$i]['kashida']) && $cOTLdata[$c]['GPOSinfo'][$i]['kashida'] > 0) {
  4014.                         if ($max_kashida_in_word) {
  4015.                             if ($cOTLdata[$c]['GPOSinfo'][$i]['kashida'] > $max_kashida_in_word) {
  4016.                                 $max_kashida_in_word $cOTLdata[$c]['GPOSinfo'][$i]['kashida'];
  4017.                                 $cOTLdata[$c]['GPOSinfo'][$last_kashida_in_word]['kashida'] = 0;
  4018.                                 $last_kashida_in_word $i;
  4019.                             } else {
  4020.                                 $cOTLdata[$c]['GPOSinfo'][$i]['kashida'] = 0;
  4021.                             }
  4022.                         } else {
  4023.                             $max_kashida_in_word $cOTLdata[$c]['GPOSinfo'][$i]['kashida'];
  4024.                             $last_kashida_in_word $i;
  4025.                         }
  4026.                     }
  4027.                 }
  4028.             }
  4029.             // Save from last word
  4030.             if ($max_kashida_in_word) {
  4031.                 $k_ctr++;
  4032.                 $k_total $max_kashida_in_word;
  4033.             }
  4034.             // Number of kashida points = $k_ctr
  4035.             // $useKashida is a % value from CurrentFont/config_fonts.php
  4036.             // % ratio divided between word-spacing and kashida-spacing
  4037.             $kashida_space_ratio intval($this->CurrentFont['useKashida']) / 100;
  4038.             $kashida_space $w $kashida_space_ratio;
  4039.             $tatw $this->_getCharWidth($this->CurrentFont['cw'], 0x0640);
  4040.             // Only use kashida if each allocated kashida width is > 0.01 x width of a tatweel
  4041.             // Otherwise fontstretch is too small and errors
  4042.             // If not just leave to adjust word-spacing
  4043.             if ($tatw && (($kashida_space $k_ctr) / $tatw) > 0.01) {
  4044.                 for ($c 0$c count($cOTLdata); $c++) {
  4045.                     for ($i 0$i strlen($cOTLdata[$c]['group']); $i++) {
  4046.                         if (isset($cOTLdata[$c]['GPOSinfo'][$i]['kashida']) && $cOTLdata[$c]['GPOSinfo'][$i]['kashida'] > 0) {
  4047.                             // At this point kashida is a number representing priority (higher number - higher priority)
  4048.                             // We are now going to set it as an actual length
  4049.                             // This shares it equally amongst words:
  4050.                             $cOTLdata[$c]['GPOSinfo'][$i]['kashida_space'] = ($k_ctr) * $kashida_space;
  4051.                         }
  4052.                     }
  4053.                 }
  4054.                 $w -= $kashida_space;
  4055.             }
  4056.         }
  4057.         $ws 0;
  4058.         $charspacing 0;
  4059.         $ww $this->jSWord;
  4060.         $ncx $nc 1;
  4061.         if ($nc == 0) {
  4062.             return [000];
  4063.         } // Only word spacing allowed / possible
  4064.         elseif ($this->fixedlSpacing !== false || $inclCursive) {
  4065.             if ($ns) {
  4066.                 $ws $w $ns;
  4067.             }
  4068.         } elseif ($nc == 1) {
  4069.             $charspacing $w;
  4070.         } elseif (!$ns) {
  4071.             $charspacing $w / ($ncx );
  4072.             if (($this->jSmaxChar 0) && ($charspacing $this->jSmaxChar)) {
  4073.                 $charspacing $this->jSmaxChar;
  4074.             }
  4075.         } elseif ($ns == ($ncx )) {
  4076.             $charspacing $w $ns;
  4077.         } else {
  4078.             if ($this->usingCoreFont) {
  4079.                 $cs = ($w * ($this->jSWord)) / ($ncx );
  4080.                 if (($this->jSmaxChar 0) && ($cs $this->jSmaxChar)) {
  4081.                     $cs $this->jSmaxChar;
  4082.                     $ww - (($cs * ($ncx )) / $w);
  4083.                 }
  4084.                 $charspacing $cs;
  4085.                 $ws = ($w * ($ww) ) / $ns;
  4086.             } else {
  4087.                 $cs = ($w * ($this->jSWord)) / ($ncx $ns);
  4088.                 if (($this->jSmaxChar 0) && ($cs $this->jSmaxChar)) {
  4089.                     $cs $this->jSmaxChar;
  4090.                     $ww - (($cs * ($ncx $ns)) / $w);
  4091.                 }
  4092.                 $charspacing $cs;
  4093.                 $ws = (($w * ($ww) ) / $ns) - $charspacing;
  4094.             }
  4095.         }
  4096.         return [$charspacing$ws$kashida_space];
  4097.     }
  4098.     /**
  4099.      * Output a cell
  4100.      *
  4101.      * Expects input to be mb_encoded if necessary and RTL reversed
  4102.      *
  4103.      * @since mPDF 5.7.1
  4104.      */
  4105.     function Cell($w$h 0$txt ''$border 0$ln 0$align ''$fill 0$link ''$currentx 0$lcpaddingL 0$lcpaddingR 0$valign 'M'$spanfill 0$exactWidth false$OTLdata false$textvar 0$lineBox false)
  4106.     {
  4107.         // NON_BREAKING SPACE
  4108.         if ($this->usingCoreFont) {
  4109.             $txt str_replace(chr(160), chr(32), $txt);
  4110.         } else {
  4111.             $txt str_replace(chr(194) . chr(160), chr(32), $txt);
  4112.         }
  4113.         $oldcolumn $this->CurrCol;
  4114.         // Automatic page break
  4115.         // Allows PAGE-BREAK-AFTER = avoid to work
  4116.         if (isset($this->blk[$this->blklvl])) {
  4117.             $bottom $this->blk[$this->blklvl]['padding_bottom'] + $this->blk[$this->blklvl]['margin_bottom'];
  4118.         } else {
  4119.             $bottom 0;
  4120.         }
  4121.         if (!$this->tableLevel
  4122.             && (
  4123.                 ($this->$this->divheight $this->PageBreakTrigger)
  4124.                 || ($this->$h $this->PageBreakTrigger)
  4125.                 || (
  4126.                     $this->+ ($h 2) + $bottom $this->PageBreakTrigger
  4127.                         && (isset($this->blk[$this->blklvl]['page_break_after_avoid']) && $this->blk[$this->blklvl]['page_break_after_avoid'])
  4128.                 )
  4129.             )
  4130.             && !$this->InFooter
  4131.             && $this->AcceptPageBreak()
  4132.         ) { // mPDF 5.7.2
  4133.             $x $this->x// Current X position
  4134.             // WORD SPACING
  4135.             $ws $this->ws// Word Spacing
  4136.             $charspacing $this->charspacing// Character Spacing
  4137.             $this->ResetSpacing();
  4138.             $this->AddPage($this->CurOrientation);
  4139.             // Added to correct for OddEven Margins
  4140.             $x += $this->MarginCorrection;
  4141.             if ($currentx) {
  4142.                 $currentx += $this->MarginCorrection;
  4143.             }
  4144.             $this->$x;
  4145.             // WORD SPACING
  4146.             $this->SetSpacing($charspacing$ws);
  4147.         }
  4148.         // Test: to put line through centre of cell: $this->Line($this->x,$this->y+($h/2),$this->x+50,$this->y+($h/2));
  4149.         // Test: to put border around cell as it is specified: $border='LRTB';
  4150.         /* -- COLUMNS -- */
  4151.         // COLS
  4152.         // COLUMN CHANGE
  4153.         if ($this->CurrCol != $oldcolumn) {
  4154.             if ($currentx) {
  4155.                 $currentx += $this->ChangeColumn * ($this->ColWidth $this->ColGap);
  4156.             }
  4157.             $this->+= $this->ChangeColumn * ($this->ColWidth $this->ColGap);
  4158.         }
  4159.         // COLUMNS Update/overwrite the lowest bottom of printing y value for a column
  4160.         if ($this->ColActive) {
  4161.             if ($h) {
  4162.                 $this->ColDetails[$this->CurrCol]['bottom_margin'] = $this->$h;
  4163.             } else {
  4164.                 $this->ColDetails[$this->CurrCol]['bottom_margin'] = $this->$this->divheight;
  4165.             }
  4166.         }
  4167.         /* -- END COLUMNS -- */
  4168.         if ($w == 0) {
  4169.             $w $this->$this->rMargin $this->x;
  4170.         }
  4171.         $s '';
  4172.         if ($fill == && $this->FillColor) {
  4173.             if ((isset($this->pageoutput[$this->page]['FillColor']) && $this->pageoutput[$this->page]['FillColor'] != $this->FillColor) || !isset($this->pageoutput[$this->page]['FillColor'])) {
  4174.                 $s .= $this->FillColor ' ';
  4175.             }
  4176.             $this->pageoutput[$this->page]['FillColor'] = $this->FillColor;
  4177.         }
  4178.         if ($lineBox && isset($lineBox['boxtop']) && $txt) { // i.e. always from WriteFlowingBlock/finishFlowingBlock (but not objects -
  4179.             // which only have $lineBox['top'] set)
  4180.             $boxtop $this->$lineBox['boxtop'];
  4181.             $boxbottom $this->$lineBox['boxbottom'];
  4182.             $glyphYorigin $lineBox['glyphYorigin'];
  4183.             $baseline_shift $lineBox['baseline-shift'];
  4184.             $bord_boxtop $bg_boxtop $boxtop $boxtop $baseline_shift;
  4185.             $bord_boxbottom $bg_boxbottom $boxbottom $boxbottom $baseline_shift;
  4186.             $bord_boxheight $bg_boxheight $boxheight $boxbottom $boxtop;
  4187.             // If inline element BACKGROUND has bounding box set by parent element:
  4188.             if (isset($lineBox['background-boxtop'])) {
  4189.                 $bg_boxtop $this->$lineBox['background-boxtop'] - $lineBox['background-baseline-shift'];
  4190.                 $bg_boxbottom $this->$lineBox['background-boxbottom'] - $lineBox['background-baseline-shift'];
  4191.                 $bg_boxheight $bg_boxbottom $bg_boxtop;
  4192.             }
  4193.             // If inline element BORDER has bounding box set by parent element:
  4194.             if (isset($lineBox['border-boxtop'])) {
  4195.                 $bord_boxtop $this->$lineBox['border-boxtop'] - $lineBox['border-baseline-shift'];
  4196.                 $bord_boxbottom $this->$lineBox['border-boxbottom'] - $lineBox['border-baseline-shift'];
  4197.                 $bord_boxheight $bord_boxbottom $bord_boxtop;
  4198.             }
  4199.         } else {
  4200.             $boxtop $this->y;
  4201.             $boxheight $h;
  4202.             $boxbottom $this->$h;
  4203.             $baseline_shift 0;
  4204.             if ($txt != '') {
  4205.                 // FONT SIZE - this determines the baseline caculation
  4206.                 $bfs $this->FontSize;
  4207.                 // Calculate baseline Superscript and Subscript Y coordinate adjustment
  4208.                 $bfx $this->baselineC;
  4209.                 $baseline $bfx $bfs;
  4210.                 if ($textvar TextVars::FA_SUPERSCRIPT) {
  4211.                     $baseline_shift $this->textparam['text-baseline'];
  4212.                 } elseif ($textvar TextVars::FA_SUBSCRIPT) {
  4213.                     $baseline_shift $this->textparam['text-baseline'];
  4214.                 } elseif ($this->bullet) {
  4215.                     $baseline += ($bfx 0.7) * $this->FontSize;
  4216.                 }
  4217.                 // Vertical align (for Images)
  4218.                 if ($valign == 'T') {
  4219.                     $va = (0.5 $bfs $this->normalLineheight);
  4220.                 } elseif ($valign == 'B') {
  4221.                     $va $h - (0.5 $bfs $this->normalLineheight);
  4222.                 } else {
  4223.                     $va 0.5 $h;
  4224.                 } // Middle
  4225.                 // ONLY SET THESE IF WANT TO CONFINE BORDER +/- FILL TO FIT FONTSIZE - NOT FULL CELL AS IS ORIGINAL FUNCTION
  4226.                 // spanfill or spanborder are set in FlowingBlock functions
  4227.                 if ($spanfill || !empty($this->spanborddet) || $link != '') {
  4228.                     $exth 0.2// Add to fontsize to increase height of background / link / border
  4229.                     $boxtop $this->$baseline $va - ($this->FontSize * ($exth 2) * (0.5 $bfx));
  4230.                     $boxheight $this->FontSize * ($exth);
  4231.                     $boxbottom $boxtop $boxheight;
  4232.                 }
  4233.                 $glyphYorigin $baseline $va;
  4234.             }
  4235.             $boxtop -= $baseline_shift;
  4236.             $boxbottom -= $baseline_shift;
  4237.             $bord_boxtop $bg_boxtop $boxtop;
  4238.             $bord_boxbottom $bg_boxbottom $boxbottom;
  4239.             $bord_boxheight $bg_boxheight $boxheight $boxbottom $boxtop;
  4240.         }
  4241.         $bbw $tbw $lbw $rbw 0// Border widths
  4242.         if (!empty($this->spanborddet)) {
  4243.             if (!isset($this->spanborddet['B'])) {
  4244.                 $this->spanborddet['B'] = ['s' => 0'style' => '''w' => 0];
  4245.             }
  4246.             if (!isset($this->spanborddet['T'])) {
  4247.                 $this->spanborddet['T'] = ['s' => 0'style' => '''w' => 0];
  4248.             }
  4249.             if (!isset($this->spanborddet['L'])) {
  4250.                 $this->spanborddet['L'] = ['s' => 0'style' => '''w' => 0];
  4251.             }
  4252.             if (!isset($this->spanborddet['R'])) {
  4253.                 $this->spanborddet['R'] = ['s' => 0'style' => '''w' => 0];
  4254.             }
  4255.             $bbw $this->spanborddet['B']['w'];
  4256.             $tbw $this->spanborddet['T']['w'];
  4257.             $lbw $this->spanborddet['L']['w'];
  4258.             $rbw $this->spanborddet['R']['w'];
  4259.         }
  4260.         if ($fill == || $border == || !empty($this->spanborddet)) {
  4261.             if (!empty($this->spanborddet)) {
  4262.                 if ($fill == 1) {
  4263.                     $s .= sprintf('%.3F %.3F %.3F %.3F re f ', ($this->$lbw) * Mpdf::SCALE, ($this->$bg_boxtop $tbw) * Mpdf::SCALE, ($w $lbw $rbw) * Mpdf::SCALE, (-$bg_boxheight $tbw $bbw) * Mpdf::SCALE);
  4264.                 }
  4265.                 $s.= ' q ';
  4266.                 $dashon 3;
  4267.                 $dashoff 3.5;
  4268.                 $dot 2.5;
  4269.                 if ($tbw) {
  4270.                     $short 0;
  4271.                     if ($this->spanborddet['T']['style'] == 'dashed') {
  4272.                         $s .= sprintf(' 0 j 0 J [%.3F %.3F] 0 d '$tbw $dashon Mpdf::SCALE$tbw $dashoff Mpdf::SCALE);
  4273.                     } elseif ($this->spanborddet['T']['style'] == 'dotted') {
  4274.                         $s .= sprintf(' 1 j 1 J [%.3F %.3F] %.3F d '0.001$tbw $dot Mpdf::SCALE, -$tbw Mpdf::SCALE);
  4275.                         $short $tbw 2;
  4276.                     } else {
  4277.                         $s .= ' 0 j 0 J [] 0 d ';
  4278.                     }
  4279.                     if ($this->spanborddet['T']['style'] != 'dotted') {
  4280.                         $s .= 'q ';
  4281.                         $s .= sprintf('%.3F %.3F m ', ($this->$lbw) * Mpdf::SCALE, ($this->$bord_boxtop $tbw) * Mpdf::SCALE);
  4282.                         $s .= sprintf('%.3F %.3F l ', ($this->$w $rbw) * Mpdf::SCALE, ($this->$bord_boxtop $tbw) * Mpdf::SCALE);
  4283.                         $s .= sprintf('%.3F %.3F l ', ($this->$w) * Mpdf::SCALE, ($this->$bord_boxtop) * Mpdf::SCALE);
  4284.                         $s .= sprintf('%.3F %.3F l ', ($this->x) * Mpdf::SCALE, ($this->$bord_boxtop) * Mpdf::SCALE);
  4285.                         $s .= ' h W n '// Ends path no-op & Sets the clipping path
  4286.                     }
  4287.                     $c $this->SetDColor($this->spanborddet['T']['c'], true);
  4288.                     if ($this->spanborddet['T']['style'] == 'double') {
  4289.                         $s .= sprintf(' %s %.3F w '$c$tbw Mpdf::SCALE);
  4290.                         $s .= sprintf('%.3F %.3F m %.3F %.3F l S ', ($this->$lbw) * Mpdf::SCALE, ($this->$bord_boxtop $tbw 6) * Mpdf::SCALE, ($this->$w $rbw) * Mpdf::SCALE, ($this->$bord_boxtop $tbw 6) * Mpdf::SCALE);
  4291.                         $s .= sprintf('%.3F %.3F m %.3F %.3F l S ', ($this->$lbw) * Mpdf::SCALE, ($this->$bord_boxtop $tbw 6) * Mpdf::SCALE, ($this->$w $rbw) * Mpdf::SCALE, ($this->$bord_boxtop $tbw 6) * Mpdf::SCALE);
  4292.                     } elseif ($this->spanborddet['T']['style'] == 'dotted') {
  4293.                         $s .= sprintf(' %s %.3F w '$c$tbw Mpdf::SCALE);
  4294.                         $s .= sprintf('%.3F %.3F m %.3F %.3F l S ', ($this->$lbw) * Mpdf::SCALE, ($this->$bord_boxtop $tbw 2) * Mpdf::SCALE, ($this->$w $rbw $short) * Mpdf::SCALE, ($this->$bord_boxtop $tbw 2) * Mpdf::SCALE);
  4295.                     } else {
  4296.                         $s .= sprintf(' %s %.3F w '$c$tbw Mpdf::SCALE);
  4297.                         $s .= sprintf('%.3F %.3F m %.3F %.3F l S ', ($this->$lbw) * Mpdf::SCALE, ($this->$bord_boxtop $tbw 2) * Mpdf::SCALE, ($this->$w $rbw $short) * Mpdf::SCALE, ($this->$bord_boxtop $tbw 2) * Mpdf::SCALE);
  4298.                     }
  4299.                     if ($this->spanborddet['T']['style'] != 'dotted') {
  4300.                         $s .= ' Q ';
  4301.                     }
  4302.                 }
  4303.                 if ($bbw) {
  4304.                     $short 0;
  4305.                     if ($this->spanborddet['B']['style'] == 'dashed') {
  4306.                         $s .= sprintf(' 0 j 0 J [%.3F %.3F] 0 d '$bbw $dashon Mpdf::SCALE$bbw $dashoff Mpdf::SCALE);
  4307.                     } elseif ($this->spanborddet['B']['style'] == 'dotted') {
  4308.                         $s .= sprintf(' 1 j 1 J [%.3F %.3F] %.3F d '0.001$bbw $dot Mpdf::SCALE, -$bbw Mpdf::SCALE);
  4309.                         $short $bbw 2;
  4310.                     } else {
  4311.                         $s .= ' 0 j 0 J [] 0 d ';
  4312.                     }
  4313.                     if ($this->spanborddet['B']['style'] != 'dotted') {
  4314.                         $s .= 'q ';
  4315.                         $s .= sprintf('%.3F %.3F m ', ($this->$lbw) * Mpdf::SCALE, ($this->$bord_boxbottom $bbw) * Mpdf::SCALE);
  4316.                         $s .= sprintf('%.3F %.3F l ', ($this->$w $rbw) * Mpdf::SCALE, ($this->$bord_boxbottom $bbw) * Mpdf::SCALE);
  4317.                         $s .= sprintf('%.3F %.3F l ', ($this->$w) * Mpdf::SCALE, ($this->$bord_boxbottom) * Mpdf::SCALE);
  4318.                         $s .= sprintf('%.3F %.3F l ', ($this->x) * Mpdf::SCALE, ($this->$bord_boxbottom) * Mpdf::SCALE);
  4319.                         $s .= ' h W n '// Ends path no-op & Sets the clipping path
  4320.                     }
  4321.                     $c $this->SetDColor($this->spanborddet['B']['c'], true);
  4322.                     if ($this->spanborddet['B']['style'] == 'double') {
  4323.                         $s .= sprintf(' %s %.3F w '$c$bbw Mpdf::SCALE);
  4324.                         $s .= sprintf('%.3F %.3F m %.3F %.3F l S ', ($this->$lbw) * Mpdf::SCALE, ($this->$bord_boxbottom $bbw 6) * Mpdf::SCALE, ($this->$w $rbw $short) * Mpdf::SCALE, ($this->$bord_boxbottom $bbw 6) * Mpdf::SCALE);
  4325.                         $s .= sprintf('%.3F %.3F m %.3F %.3F l S ', ($this->$lbw) * Mpdf::SCALE, ($this->$bord_boxbottom $bbw 6) * Mpdf::SCALE, ($this->$w $rbw $short) * Mpdf::SCALE, ($this->$bord_boxbottom $bbw 6) * Mpdf::SCALE);
  4326.                     } elseif ($this->spanborddet['B']['style'] == 'dotted') {
  4327.                         $s .= sprintf(' %s %.3F w '$c$bbw Mpdf::SCALE);
  4328.                         $s .= sprintf('%.3F %.3F m %.3F %.3F l S ', ($this->$lbw) * Mpdf::SCALE, ($this->$bord_boxbottom $bbw 2) * Mpdf::SCALE, ($this->$w $rbw $short) * Mpdf::SCALE, ($this->$bord_boxbottom $bbw 2) * Mpdf::SCALE);
  4329.                     } else {
  4330.                         $s .= sprintf(' %s %.3F w '$c$bbw Mpdf::SCALE);
  4331.                         $s .= sprintf('%.3F %.3F m %.3F %.3F l S ', ($this->$lbw) * Mpdf::SCALE, ($this->$bord_boxbottom $bbw 2) * Mpdf::SCALE, ($this->$w $rbw $short) * Mpdf::SCALE, ($this->$bord_boxbottom $bbw 2) * Mpdf::SCALE);
  4332.                     }
  4333.                     if ($this->spanborddet['B']['style'] != 'dotted') {
  4334.                         $s .= ' Q ';
  4335.                     }
  4336.                 }
  4337.                 if ($lbw) {
  4338.                     $short 0;
  4339.                     if ($this->spanborddet['L']['style'] == 'dashed') {
  4340.                         $s .= sprintf(' 0 j 0 J [%.3F %.3F] 0 d '$lbw $dashon Mpdf::SCALE$lbw $dashoff Mpdf::SCALE);
  4341.                     } elseif ($this->spanborddet['L']['style'] == 'dotted') {
  4342.                         $s .= sprintf(' 1 j 1 J [%.3F %.3F] %.3F d '0.001$lbw $dot Mpdf::SCALE, -$lbw Mpdf::SCALE);
  4343.                         $short $lbw 2;
  4344.                     } else {
  4345.                         $s .= ' 0 j 0 J [] 0 d ';
  4346.                     }
  4347.                     if ($this->spanborddet['L']['style'] != 'dotted') {
  4348.                         $s .= 'q ';
  4349.                         $s .= sprintf('%.3F %.3F m ', ($this->$lbw) * Mpdf::SCALE, ($this->$bord_boxbottom $bbw) * Mpdf::SCALE);
  4350.                         $s .= sprintf('%.3F %.3F l ', ($this->x) * Mpdf::SCALE, ($this->$bord_boxbottom) * Mpdf::SCALE);
  4351.                         $s .= sprintf('%.3F %.3F l ', ($this->x) * Mpdf::SCALE, ($this->$bord_boxtop) * Mpdf::SCALE);
  4352.                         $s .= sprintf('%.3F %.3F l ', ($this->$lbw) * Mpdf::SCALE, ($this->$bord_boxtop $tbw) * Mpdf::SCALE);
  4353.                         $s .= ' h W n '// Ends path no-op & Sets the clipping path
  4354.                     }
  4355.                     $c $this->SetDColor($this->spanborddet['L']['c'], true);
  4356.                     if ($this->spanborddet['L']['style'] == 'double') {
  4357.                         $s .= sprintf(' %s %.3F w '$c$lbw Mpdf::SCALE);
  4358.                         $s .= sprintf('%.3F %.3F m %.3F %.3F l S ', ($this->$lbw 6) * Mpdf::SCALE, ($this->$bord_boxtop $tbw) * Mpdf::SCALE, ($this->$lbw 6) * Mpdf::SCALE, ($this->$bord_boxbottom $bbw $short) * Mpdf::SCALE);
  4359.                         $s .= sprintf('%.3F %.3F m %.3F %.3F l S ', ($this->$lbw 6) * Mpdf::SCALE, ($this->$bord_boxtop $tbw) * Mpdf::SCALE, ($this->$lbw 6) * Mpdf::SCALE, ($this->$bord_boxbottom $bbw $short) * Mpdf::SCALE);
  4360.                     } elseif ($this->spanborddet['L']['style'] == 'dotted') {
  4361.                         $s .= sprintf(' %s %.3F w '$c$lbw Mpdf::SCALE);
  4362.                         $s .= sprintf('%.3F %.3F m %.3F %.3F l S ', ($this->$lbw 2) * Mpdf::SCALE, ($this->$bord_boxtop $tbw) * Mpdf::SCALE, ($this->$lbw 2) * Mpdf::SCALE, ($this->$bord_boxbottom $bbw $short) * Mpdf::SCALE);
  4363.                     } else {
  4364.                         $s .= sprintf(' %s %.3F w '$c$lbw Mpdf::SCALE);
  4365.                         $s .= sprintf('%.3F %.3F m %.3F %.3F l S ', ($this->$lbw 2) * Mpdf::SCALE, ($this->$bord_boxtop $tbw) * Mpdf::SCALE, ($this->$lbw 2) * Mpdf::SCALE, ($this->$bord_boxbottom $bbw $short) * Mpdf::SCALE);
  4366.                     }
  4367.                     if ($this->spanborddet['L']['style'] != 'dotted') {
  4368.                         $s .= ' Q ';
  4369.                     }
  4370.                 }
  4371.                 if ($rbw) {
  4372.                     $short 0;
  4373.                     if ($this->spanborddet['R']['style'] == 'dashed') {
  4374.                         $s .= sprintf(' 0 j 0 J [%.3F %.3F] 0 d '$rbw $dashon Mpdf::SCALE$rbw $dashoff Mpdf::SCALE);
  4375.                     } elseif ($this->spanborddet['R']['style'] == 'dotted') {
  4376.                         $s .= sprintf(' 1 j 1 J [%.3F %.3F] %.3F d '0.001$rbw $dot Mpdf::SCALE, -$rbw Mpdf::SCALE);
  4377.                         $short $rbw 2;
  4378.                     } else {
  4379.                         $s .= ' 0 j 0 J [] 0 d ';
  4380.                     }
  4381.                     if ($this->spanborddet['R']['style'] != 'dotted') {
  4382.                         $s .= 'q ';
  4383.                         $s .= sprintf('%.3F %.3F m ', ($this->$w $rbw) * Mpdf::SCALE, ($this->$bord_boxbottom $bbw) * Mpdf::SCALE);
  4384.                         $s .= sprintf('%.3F %.3F l ', ($this->$w) * Mpdf::SCALE, ($this->$bord_boxbottom) * Mpdf::SCALE);
  4385.                         $s .= sprintf('%.3F %.3F l ', ($this->$w) * Mpdf::SCALE, ($this->$bord_boxtop) * Mpdf::SCALE);
  4386.                         $s .= sprintf('%.3F %.3F l ', ($this->$w $rbw) * Mpdf::SCALE, ($this->$bord_boxtop $tbw) * Mpdf::SCALE);
  4387.                         $s .= ' h W n '// Ends path no-op & Sets the clipping path
  4388.                     }
  4389.                     $c $this->SetDColor($this->spanborddet['R']['c'], true);
  4390.                     if ($this->spanborddet['R']['style'] == 'double') {
  4391.                         $s .= sprintf(' %s %.3F w '$c$rbw Mpdf::SCALE);
  4392.                         $s .= sprintf('%.3F %.3F m %.3F %.3F l S ', ($this->$w $rbw 6) * Mpdf::SCALE, ($this->$bord_boxtop $tbw) * Mpdf::SCALE, ($this->$w $rbw 6) * Mpdf::SCALE, ($this->$bord_boxbottom $bbw $short) * Mpdf::SCALE);
  4393.                         $s .= sprintf('%.3F %.3F m %.3F %.3F l S ', ($this->$w $rbw 6) * Mpdf::SCALE, ($this->$bord_boxtop $tbw) * Mpdf::SCALE, ($this->$w $rbw 6) * Mpdf::SCALE, ($this->$bord_boxbottom $bbw $short) * Mpdf::SCALE);
  4394.                     } elseif ($this->spanborddet['R']['style'] == 'dotted') {
  4395.                         $s .= sprintf(' %s %.3F w '$c$rbw Mpdf::SCALE);
  4396.                         $s .= sprintf('%.3F %.3F m %.3F %.3F l S ', ($this->$w $rbw 2) * Mpdf::SCALE, ($this->$bord_boxtop $tbw) * Mpdf::SCALE, ($this->$w $rbw 2) * Mpdf::SCALE, ($this->$bord_boxbottom $bbw $short) * Mpdf::SCALE);
  4397.                     } else {
  4398.                         $s .= sprintf(' %s %.3F w '$c$rbw Mpdf::SCALE);
  4399.                         $s .= sprintf('%.3F %.3F m %.3F %.3F l S ', ($this->$w $rbw 2) * Mpdf::SCALE, ($this->$bord_boxtop $tbw) * Mpdf::SCALE, ($this->$w $rbw 2) * Mpdf::SCALE, ($this->$bord_boxbottom $bbw $short) * Mpdf::SCALE);
  4400.                     }
  4401.                     if ($this->spanborddet['R']['style'] != 'dotted') {
  4402.                         $s .= ' Q ';
  4403.                     }
  4404.                 }
  4405.                 $s.= ' Q ';
  4406.             } else { // If "border", does not come from WriteFlowingBlock or FinishFlowingBlock
  4407.                 if ($fill == 1) {
  4408.                     $op = ($border == 1) ? 'B' 'f';
  4409.                 } else {
  4410.                     $op 'S';
  4411.                 }
  4412.                 $s .= sprintf('%.3F %.3F %.3F %.3F re %s '$this->Mpdf::SCALE, ($this->$bg_boxtop) * Mpdf::SCALE$w Mpdf::SCALE, -$bg_boxheight Mpdf::SCALE$op);
  4413.             }
  4414.         }
  4415.         if (is_string($border)) { // If "border", does not come from WriteFlowingBlock or FinishFlowingBlock
  4416.             $x $this->x;
  4417.             $y $this->y;
  4418.             if (is_int(strpos($border'L'))) {
  4419.                 $s .= sprintf('%.3F %.3F m %.3F %.3F l S '$x Mpdf::SCALE, ($this->$bord_boxtop) * Mpdf::SCALE$x Mpdf::SCALE, ($this->- ($bord_boxbottom)) * Mpdf::SCALE);
  4420.             }
  4421.             if (is_int(strpos($border'T'))) {
  4422.                 $s .= sprintf('%.3F %.3F m %.3F %.3F l S '$x Mpdf::SCALE, ($this->$bord_boxtop) * Mpdf::SCALE, ($x $w) * Mpdf::SCALE, ($this->$bord_boxtop) * Mpdf::SCALE);
  4423.             }
  4424.             if (is_int(strpos($border'R'))) {
  4425.                 $s .= sprintf('%.3F %.3F m %.3F %.3F l S ', ($x $w) * Mpdf::SCALE, ($this->$bord_boxtop) * Mpdf::SCALE, ($x $w) * Mpdf::SCALE, ($this->- ($bord_boxbottom)) * Mpdf::SCALE);
  4426.             }
  4427.             if (is_int(strpos($border'B'))) {
  4428.                 $s .= sprintf('%.3F %.3F m %.3F %.3F l S '$x Mpdf::SCALE, ($this->- ($bord_boxbottom)) * Mpdf::SCALE, ($x $w) * Mpdf::SCALE, ($this->- ($bord_boxbottom)) * Mpdf::SCALE);
  4429.             }
  4430.         }
  4431.         if ($txt != '') {
  4432.             if ($exactWidth) {
  4433.                 $stringWidth $w;
  4434.             } else {
  4435.                 $stringWidth $this->GetStringWidth($txttrue$OTLdata$textvar) + ( $this->charspacing mb_strlen($txt$this->mb_enc) / Mpdf::SCALE ) + ( $this->ws mb_substr_count($txt' '$this->mb_enc) / Mpdf::SCALE );
  4436.             }
  4437.             // Set x OFFSET FOR PRINTING
  4438.             if ($align == 'R') {
  4439.                 $dx $w $this->cMarginR $stringWidth $lcpaddingR;
  4440.             } elseif ($align == 'C') {
  4441.                 $dx = (($w $stringWidth ) / 2);
  4442.             } elseif ($align == 'L' or $align == 'J') {
  4443.                 $dx $this->cMarginL $lcpaddingL;
  4444.             } else {
  4445.                 $dx 0;
  4446.             }
  4447.             if ($this->ColorFlag) {
  4448.                 $s .='q ' $this->TextColor ' ';
  4449.             }
  4450.             // OUTLINE
  4451.             if (isset($this->textparam['outline-s']) && $this->textparam['outline-s'] && !($textvar TextVars::FC_SMALLCAPS)) { // mPDF 5.7.1
  4452.                 $s .=' ' sprintf('%.3F w'$this->LineWidth Mpdf::SCALE) . ' ';
  4453.                 $s .=$this->DrawColor ";
  4454.                 $s .=" 2 Tr ";
  4455.             } elseif ($this->falseBoldWeight && strpos($this->ReqFontStyle"B") !== false && strpos($this->FontStyle"B") === false && !($textvar TextVars::FC_SMALLCAPS)) { // can't use together with OUTLINE or Small Caps    // mPDF 5.7.1    ??? why not with SmallCaps ???
  4456.                 $s .= ' 2 Tr 1 J 1 j ';
  4457.                 $s .= ' ' sprintf('%.3F w', ($this->FontSize 130) * Mpdf::SCALE $this->falseBoldWeight) . ' ';
  4458.                 $tc strtoupper($this->TextColor); // change 0 0 0 rg to 0 0 0 RG
  4459.                 if ($this->FillColor != $tc) {
  4460.                     $s .= ' ' $tc ' ';
  4461.                 }  // stroke (outline) = same colour as text(fill)
  4462.             } else {
  4463.                 $s .=" 0 Tr ";
  4464.             }
  4465.             if (strpos($this->ReqFontStyle"I") !== false && strpos($this->FontStyle"I") === false) { // Artificial italic
  4466.                 $aix '1 0 0.261799 1 %.3F %.3F Tm ';
  4467.             } else {
  4468.                 $aix '%.3F %.3F Td ';
  4469.             }
  4470.             $px = ($this->$dx) * Mpdf::SCALE;
  4471.             $py = ($this->- ($this->$glyphYorigin $baseline_shift)) * Mpdf::SCALE;
  4472.             // THE TEXT
  4473.             $txt2 $txt;
  4474.             $sub '';
  4475.             $this->CurrentFont['used'] = true;
  4476.             /*             * ************** SIMILAR TO Text() ************************ */
  4477.             // IF corefonts AND NOT SmCaps AND NOT Kerning
  4478.             // Just output text; charspacing and wordspacing already set by charspacing (Tc) and ws (Tw)
  4479.             if ($this->usingCoreFont && !($textvar TextVars::FC_SMALLCAPS) && !($textvar TextVars::FC_KERNING)) {
  4480.                 $txt2 $this->writer->escape($txt2);
  4481.                 $sub .= sprintf('BT ' $aix ' (%s) Tj ET'$px$py$txt2);
  4482.             } // IF NOT corefonts AND NO wordspacing AND NOT SIP/SMP AND NOT SmCaps AND NOT Kerning AND NOT OTL
  4483.             // Just output text
  4484.             elseif (!$this->usingCoreFont && !$this->ws && !($textvar TextVars::FC_SMALLCAPS) && !($textvar TextVars::FC_KERNING) && !(isset($this->CurrentFont['useOTL']) && ($this->CurrentFont['useOTL'] & 0xFF) && !empty($OTLdata['GPOSinfo']))) {
  4485.                 // IF SIP/SMP
  4486.                 if ((isset($this->CurrentFont['sip']) && $this->CurrentFont['sip']) || (isset($this->CurrentFont['smp']) && $this->CurrentFont['smp'])) {
  4487.                     $txt2 $this->UTF8toSubset($txt2);
  4488.                     $sub .=sprintf('BT ' $aix ' %s Tj ET'$px$py$txt2);
  4489.                 } // NOT SIP/SMP
  4490.                 else {
  4491.                     $txt2 $this->writer->utf8ToUtf16BigEndian($txt2false);
  4492.                     $txt2 $this->writer->escape($txt2);
  4493.                     $sub .=sprintf('BT ' $aix ' (%s) Tj ET'$px$py$txt2);
  4494.                 }
  4495.             } // IF NOT corefonts AND IS wordspacing AND NOT SIP AND NOT SmCaps AND NOT Kerning AND NOT OTL
  4496.             // Output text word by word with an adjustment to the intercharacter spacing for SPACEs to form word spacing
  4497.             // IF multibyte - Tw has no effect - need to do word spacing using an adjustment before each space
  4498.             elseif (!$this->usingCoreFont && $this->ws && !((isset($this->CurrentFont['sip']) && $this->CurrentFont['sip']) || (isset($this->CurrentFont['smp']) && $this->CurrentFont['smp'])) && !($textvar TextVars::FC_SMALLCAPS) && !($textvar TextVars::FC_KERNING) && !(isset($this->CurrentFont['useOTL']) && ($this->CurrentFont['useOTL'] & 0xFF) && (!empty($OTLdata['GPOSinfo']) || (strpos($OTLdata['group'], 'M') !== false && $this->charspacing)) )) {
  4499.                 $space " ";
  4500.                 $space $this->writer->utf8ToUtf16BigEndian($spacefalse);
  4501.                 $space $this->writer->escape($space);
  4502.                 $sub .=sprintf('BT ' $aix ' %.3F Tc ['$px$py$this->charspacing);
  4503.                 $t explode(' '$txt2);
  4504.                 $numt count($t);
  4505.                 for ($i 0$i $numt$i++) {
  4506.                     $tx $t[$i];
  4507.                     $tx $this->writer->utf8ToUtf16BigEndian($txfalse);
  4508.                     $tx $this->writer->escape($tx);
  4509.                     $sub .=sprintf('(%s) '$tx);
  4510.                     if (($i 1) < $numt) {
  4511.                         $adj = -($this->ws) * 1000 $this->FontSizePt;
  4512.                         $sub .=sprintf('%d(%s) '$adj$space);
  4513.                     }
  4514.                 }
  4515.                 $sub .='] TJ ';
  4516.                 $sub .=' ET';
  4517.             } // ELSE (IF SmCaps || Kerning || OTL) [corefonts or not corefonts; SIP or SMP or BMP]
  4518.             else {
  4519.                 $sub $this->applyGPOSpdf($txt$aix$px$py$OTLdata$textvar);
  4520.             }
  4521.             /** ************** END SIMILAR TO Text() ************************ */
  4522.             if ($this->shrin_k 1) {
  4523.                 $shrin_k $this->shrin_k;
  4524.             } else {
  4525.                 $shrin_k 1;
  4526.             }
  4527.             // UNDERLINE
  4528.             if ($textvar TextVars::FD_UNDERLINE) { // mPDF 5.7.1    // mPDF 6
  4529.                 // mPDF 5.7.3  inline text-decoration parameters
  4530.                 $c = isset($this->textparam['u-decoration']['color']) ? $this->textparam['u-decoration']['color'] : '';
  4531.                 if ($this->FillColor != $c) {
  4532.                     $sub .= ' ' $c ' ';
  4533.                 }
  4534.                 // mPDF 5.7.3  inline text-decoration parameters
  4535.                 $decorationfontkey = isset($this->textparam['u-decoration']['fontkey']) ? $this->textparam['u-decoration']['fontkey'] : '';
  4536.                 $decorationfontsize = isset($this->textparam['u-decoration']['fontsize']) ? $this->textparam['u-decoration']['fontsize'] / $shrin_k 0;
  4537.                 if (isset($this->fonts[$decorationfontkey]['ut']) && $this->fonts[$decorationfontkey]['ut']) {
  4538.                     $ut $this->fonts[$decorationfontkey]['ut'] / 1000 $decorationfontsize;
  4539.                 } else {
  4540.                     $ut 60 1000 $decorationfontsize;
  4541.                 }
  4542.                 if (isset($this->fonts[$decorationfontkey]['up']) && $this->fonts[$decorationfontkey]['up']) {
  4543.                     $up $this->fonts[$decorationfontkey]['up'];
  4544.                 } else {
  4545.                     $up = -100;
  4546.                 }
  4547.                 $adjusty = (-$up 1000 $decorationfontsize) + $ut 2;
  4548.                 $ubaseline = isset($this->textparam['u-decoration']['baseline'])
  4549.                     ? $glyphYorigin $this->textparam['u-decoration']['baseline'] / $shrin_k
  4550.                     $glyphYorigin;
  4551.                 $olw $this->LineWidth;
  4552.                 $sub .= ' ' . (sprintf(' %.3F w 0 j 0 J '$ut Mpdf::SCALE));
  4553.                 $sub .= ' ' $this->_dounderline($this->$dx$this->$ubaseline $adjusty$txt$OTLdata$textvar);
  4554.                 $sub .= ' ' . (sprintf(' %.3F w 2 j 2 J '$olw Mpdf::SCALE));
  4555.                 if ($this->FillColor != $c) {
  4556.                     $sub .= ' ' $this->FillColor ' ';
  4557.                 }
  4558.             }
  4559.             // STRIKETHROUGH
  4560.             if ($textvar TextVars::FD_LINETHROUGH) { // mPDF 5.7.1    // mPDF 6
  4561.                 // mPDF 5.7.3  inline text-decoration parameters
  4562.                 $c $this->textparam['s-decoration']['color'];
  4563.                 if ($this->FillColor != $c) {
  4564.                     $sub .= ' ' $c ' ';
  4565.                 }
  4566.                 // mPDF 5.7.3  inline text-decoration parameters
  4567.                 $decorationfontkey $this->textparam['s-decoration']['fontkey'];
  4568.                 $decorationfontsize $this->textparam['s-decoration']['fontsize'] / $shrin_k;
  4569.                 // Use yStrikeoutSize from OS/2 if available
  4570.                 if (isset($this->fonts[$decorationfontkey]['strs']) && $this->fonts[$decorationfontkey]['strs']) {
  4571.                     $ut $this->fonts[$decorationfontkey]['strs'] / 1000 $decorationfontsize;
  4572.                 } // else use underlineThickness from post if available
  4573.                 elseif (isset($this->fonts[$decorationfontkey]['ut']) && $this->fonts[$decorationfontkey]['ut']) {
  4574.                     $ut $this->fonts[$decorationfontkey]['ut'] / 1000 $decorationfontsize;
  4575.                 } else {
  4576.                     $ut 50 1000 $decorationfontsize;
  4577.                 }
  4578.                 // Use yStrikeoutPosition from OS/2 if available
  4579.                 if (isset($this->fonts[$decorationfontkey]['strp']) && $this->fonts[$decorationfontkey]['strp']) {
  4580.                     $up $this->fonts[$decorationfontkey]['strp'];
  4581.                     $adjusty = (-$up 1000 $decorationfontsize);
  4582.                 } // else use a fraction ($this->baselineS) of CapHeight
  4583.                 else {
  4584.                     if (isset($this->fonts[$decorationfontkey]['desc']['CapHeight']) && $this->fonts[$decorationfontkey]['desc']['CapHeight']) {
  4585.                         $ch $this->fonts[$decorationfontkey]['desc']['CapHeight'];
  4586.                     } else {
  4587.                         $ch 700;
  4588.                     }
  4589.                     $adjusty = (-$ch 1000 $decorationfontsize) * $this->baselineS;
  4590.                 }
  4591.                 $sbaseline $glyphYorigin $this->textparam['s-decoration']['baseline'] / $shrin_k;
  4592.                 $olw $this->LineWidth;
  4593.                 $sub .=' ' . (sprintf(' %.3F w 0 j 0 J '$ut Mpdf::SCALE));
  4594.                 $sub .=' ' $this->_dounderline($this->$dx$this->$sbaseline $adjusty$txt$OTLdata$textvar);
  4595.                 $sub .=' ' . (sprintf(' %.3F w 2 j 2 J '$olw Mpdf::SCALE));
  4596.                 if ($this->FillColor != $c) {
  4597.                     $sub .= ' ' $this->FillColor ' ';
  4598.                 }
  4599.             }
  4600.             // mPDF 5.7.3  inline text-decoration parameters
  4601.             // OVERLINE
  4602.             if ($textvar TextVars::FD_OVERLINE) { // mPDF 5.7.1    // mPDF 6
  4603.                 // mPDF 5.7.3  inline text-decoration parameters
  4604.                 $c $this->textparam['o-decoration']['color'];
  4605.                 if ($this->FillColor != $c) {
  4606.                     $sub .= ' ' $c ' ';
  4607.                 }
  4608.                 // mPDF 5.7.3  inline text-decoration parameters
  4609.                 $decorationfontkey = (int) (((float) $this->textparam['o-decoration']['fontkey']) / $shrin_k);
  4610.                 $decorationfontsize $this->textparam['o-decoration']['fontsize'];
  4611.                 if (isset($this->fonts[$decorationfontkey]['ut']) && $this->fonts[$decorationfontkey]['ut']) {
  4612.                     $ut $this->fonts[$decorationfontkey]['ut'] / 1000 $decorationfontsize;
  4613.                 } else {
  4614.                     $ut 60 1000 $decorationfontsize;
  4615.                 }
  4616.                 if (isset($this->fonts[$decorationfontkey]['desc']['CapHeight']) && $this->fonts[$decorationfontkey]['desc']['CapHeight']) {
  4617.                     $ch $this->fonts[$decorationfontkey]['desc']['CapHeight'];
  4618.                 } else {
  4619.                     $ch 700;
  4620.                 }
  4621.                 $adjusty = (-$ch 1000 $decorationfontsize) * $this->baselineO;
  4622.                 $obaseline $glyphYorigin $this->textparam['o-decoration']['baseline'] / $shrin_k;
  4623.                 $olw $this->LineWidth;
  4624.                 $sub .=' ' . (sprintf(' %.3F w 0 j 0 J '$ut Mpdf::SCALE));
  4625.                 $sub .=' ' $this->_dounderline($this->$dx$this->$obaseline $adjusty$txt$OTLdata$textvar);
  4626.                 $sub .=' ' . (sprintf(' %.3F w 2 j 2 J '$olw Mpdf::SCALE));
  4627.                 if ($this->FillColor != $c) {
  4628.                     $sub .= ' ' $this->FillColor ' ';
  4629.                 }
  4630.             }
  4631.             // TEXT SHADOW
  4632.             if ($this->textshadow) {  // First to process is last in CSS comma separated shadows
  4633.                 foreach ($this->textshadow as $ts) {
  4634.                     $s .= ' q ';
  4635.                     $s .= $this->SetTColor($ts['col'], true) . "\n";
  4636.                     if ($ts['col'][0] == && ord($ts['col'][4]) < 100) { // RGBa
  4637.                         $s .= $this->SetAlpha(ord($ts['col'][4]) / 100'Normal'true'F') . "\n";
  4638.                     } elseif ($ts['col'][0] == && ord($ts['col'][5]) < 100) { // CMYKa
  4639.                         $s .= $this->SetAlpha(ord($ts['col'][5]) / 100'Normal'true'F') . "\n";
  4640.                     } elseif ($ts['col'][0] == && $ts['col'][2] == && ord($ts['col'][3]) < 100) { // Gray
  4641.                         $s .= $this->SetAlpha(ord($ts['col'][3]) / 100'Normal'true'F') . "\n";
  4642.                     }
  4643.                     $s .= sprintf(' 1 0 0 1 %.4F %.4F cm'$ts['x'] * Mpdf::SCALE, -$ts['y'] * Mpdf::SCALE) . "\n";
  4644.                     $s .= $sub;
  4645.                     $s .= ' Q ';
  4646.                 }
  4647.             }
  4648.             $s .= $sub;
  4649.             // COLOR
  4650.             if ($this->ColorFlag) {
  4651.                 $s .=' Q';
  4652.             }
  4653.             // LINK
  4654.             if ($link != '') {
  4655.                 $this->Link($this->x$boxtop$w$boxheight$link);
  4656.             }
  4657.         }
  4658.         if ($s) {
  4659.             $this->writer->write($s);
  4660.         }
  4661.         // WORD SPACING
  4662.         if ($this->ws && !$this->usingCoreFont) {
  4663.             $this->writer->write(sprintf('BT %.3F Tc ET'$this->charspacing));
  4664.         }
  4665.         $this->lasth $h;
  4666.         if (strpos($txt"\n") !== false) {
  4667.             $ln 1// cell recognizes \n from <BR> tag
  4668.         }
  4669.         if ($ln 0) {
  4670.             // Go to next line
  4671.             $this->+= $h;
  4672.             if ($ln == 1) {
  4673.                 // Move to next line
  4674.                 if ($currentx != 0) {
  4675.                     $this->$currentx;
  4676.                 } else {
  4677.                     $this->$this->lMargin;
  4678.                 }
  4679.             }
  4680.         } else {
  4681.             $this->x+=$w;
  4682.         }
  4683.     }
  4684.     function applyGPOSpdf($txt$aix$x$y$OTLdata$textvar 0)
  4685.     {
  4686.         $sipset = (isset($this->CurrentFont['sip']) && $this->CurrentFont['sip'])
  4687.             || (isset($this->CurrentFont['smp']) && $this->CurrentFont['smp']);
  4688.         $smcaps = ($textvar TextVars::FC_SMALLCAPS);
  4689.         $fontid $sipset
  4690.             $last_fontid $original_fontid $this->CurrentFont['subsetfontids'][0]
  4691.             : $last_fontid $original_fontid $this->CurrentFont['i'];
  4692.         $SmallCapsON false;  // state: uppercase/not
  4693.         $lastSmallCapsON false// state: uppercase/not
  4694.         $last_fontsize $fontsize $this->FontSizePt;
  4695.         $last_fontstretch $fontstretch 100;
  4696.         $groupBreak false;
  4697.         $unicode $this->UTF8StringToArray($txt);
  4698.         $GPOSinfo = (isset($OTLdata['GPOSinfo']) ? $OTLdata['GPOSinfo'] : []);
  4699.         $charspacing = ($this->charspacing 1000 $this->FontSizePt);
  4700.         $wordspacing = ($this->ws 1000 $this->FontSizePt);
  4701.         $XshiftBefore 0;
  4702.         $XshiftAfter 0;
  4703.         $lastYPlacement 0;
  4704.         $tj $sipset
  4705.             '<'
  4706.             '(';
  4707.         for ($i 0$i count($unicode); $i++) {
  4708.             $c $unicode[$i];
  4709.             $tx '';
  4710.             $XshiftBefore $XshiftAfter;
  4711.             $XshiftAfter 0;
  4712.             $YPlacement 0;
  4713.             $groupBreak false;
  4714.             $kashida 0;
  4715.             if (!empty($OTLdata)) {
  4716.                 // YPlacement from GPOS
  4717.                 if (isset($GPOSinfo[$i]['YPlacement']) && $GPOSinfo[$i]['YPlacement']) {
  4718.                     $YPlacement $GPOSinfo[$i]['YPlacement'] * $this->FontSizePt $this->CurrentFont['unitsPerEm'];
  4719.                     $groupBreak true;
  4720.                 }
  4721.                 // XPlacement from GPOS
  4722.                 if (isset($GPOSinfo[$i]['XPlacement']) && $GPOSinfo[$i]['XPlacement']) {
  4723.                     if (!isset($GPOSinfo[$i]['wDir']) || $GPOSinfo[$i]['wDir'] !== 'RTL') {
  4724.                         if (isset($GPOSinfo[$i]['BaseWidth'])) {
  4725.                             $GPOSinfo[$i]['XPlacement'] -= $GPOSinfo[$i]['BaseWidth'];
  4726.                         }
  4727.                     }
  4728.                     // Convert to PDF Text space (thousandths of a unit );
  4729.                     $XshiftBefore += $GPOSinfo[$i]['XPlacement'] * 1000 $this->CurrentFont['unitsPerEm'];
  4730.                     $XshiftAfter += -$GPOSinfo[$i]['XPlacement'] * 1000 $this->CurrentFont['unitsPerEm'];
  4731.                 }
  4732.                 // Kashida from GPOS
  4733.                 // Kashida is set as an absolute length value, but to adjust text needs to be converted to
  4734.                 // font-related size
  4735.                 if (isset($GPOSinfo[$i]['kashida_space']) && $GPOSinfo[$i]['kashida_space']) {
  4736.                     $kashida $GPOSinfo[$i]['kashida_space'];
  4737.                 }
  4738.                 if ($c == 32) { // word spacing
  4739.                     $XshiftAfter += $wordspacing;
  4740.                 }
  4741.                 if (substr($OTLdata['group'], ($i 1), 1) !== 'M') { // Don't add inter-character spacing before Marks
  4742.                     $XshiftAfter += $charspacing;
  4743.                 }
  4744.                 // ...applyGPOSpdf...
  4745.                 // XAdvance from GPOS - Convert to PDF Text space (thousandths of a unit );
  4746.                 if (((isset($GPOSinfo[$i]['wDir']) && $GPOSinfo[$i]['wDir'] !== 'RTL') || !isset($GPOSinfo[$i]['wDir'])) && isset($GPOSinfo[$i]['XAdvanceL']) && $GPOSinfo[$i]['XAdvanceL']) {
  4747.                     $XshiftAfter += $GPOSinfo[$i]['XAdvanceL'] * 1000 $this->CurrentFont['unitsPerEm'];
  4748.                 } elseif (isset($GPOSinfo[$i]['wDir']) && $GPOSinfo[$i]['wDir'] === 'RTL' && isset($GPOSinfo[$i]['XAdvanceR']) && $GPOSinfo[$i]['XAdvanceR']) {
  4749.                     $XshiftAfter += $GPOSinfo[$i]['XAdvanceR'] * 1000 $this->CurrentFont['unitsPerEm'];
  4750.                 }
  4751.             } else { // Character & Word spacing - if NOT OTL
  4752.                 $XshiftAfter += $charspacing;
  4753.                 if ($c == 32) {
  4754.                     $XshiftAfter += $wordspacing;
  4755.                 }
  4756.             }
  4757.             // IF Kerning done using pairs rather than OTL
  4758.             if ($textvar TextVars::FC_KERNING) {
  4759.                 if ($i && isset($this->CurrentFont['kerninfo'][$unicode[($i 1)]][$unicode[$i]])) {
  4760.                     $XshiftBefore += $this->CurrentFont['kerninfo'][$unicode[($i 1)]][$unicode[$i]];
  4761.                 }
  4762.             }
  4763.             if ($YPlacement !== $lastYPlacement) {
  4764.                 $groupBreak true;
  4765.             }
  4766.             if ($XshiftBefore) {  // +ve value in PDF moves to the left
  4767.                 // If Fontstretch is ongoing, need to adjust X adjustments because these will be stretched out.
  4768.                 $XshiftBefore *= 100 $last_fontstretch;
  4769.                 if ($sipset) {
  4770.                     $tj .= sprintf('>%d<', (-$XshiftBefore));
  4771.                 } else {
  4772.                     $tj .= sprintf(')%d(', (-$XshiftBefore));
  4773.                 }
  4774.             }
  4775.             // Small-Caps
  4776.             if ($smcaps) {
  4777.                 if (isset($this->upperCase[$c])) {
  4778.                     $c $this->upperCase[$c];
  4779.                     // $this->CurrentFont['subset'][$this->upperCase[$c]] = $this->upperCase[$c];    // add the CAP to subset
  4780.                     $SmallCapsON true;
  4781.                     // For $sipset
  4782.                     if (!$lastSmallCapsON) { // Turn ON SmallCaps
  4783.                         $groupBreak true;
  4784.                         $fontstretch $this->smCapsStretch;
  4785.                         $fontsize $this->FontSizePt $this->smCapsScale;
  4786.                     }
  4787.                 } else {
  4788.                     $SmallCapsON false;
  4789.                     if ($lastSmallCapsON) {  // Turn OFF SmallCaps
  4790.                         $groupBreak true;
  4791.                         $fontstretch 100;
  4792.                         $fontsize $this->FontSizePt;
  4793.                     }
  4794.                 }
  4795.             }
  4796.             // Prepare Text and Select Font ID
  4797.             if ($sipset) {
  4798.                 for ($j 0$j 99$j++) {
  4799.                     $init array_search($c$this->CurrentFont['subsets'][$j]);
  4800.                     if ($init !== false) {
  4801.                         if ($this->CurrentFont['subsetfontids'][$j] != $last_fontid) {
  4802.                             $groupBreak true;
  4803.                             $fontid $this->CurrentFont['subsetfontids'][$j];
  4804.                         }
  4805.                         $tx sprintf("%02s"strtoupper(dechex($init)));
  4806.                         break;
  4807.                     }
  4808.                     if (count($this->CurrentFont['subsets'][$j]) < 255) {
  4809.                         $n count($this->CurrentFont['subsets'][$j]);
  4810.                         $this->CurrentFont['subsets'][$j][$n] = $c;
  4811.                         if ($this->CurrentFont['subsetfontids'][$j] != $last_fontid) {
  4812.                             $groupBreak true;
  4813.                             $fontid $this->CurrentFont['subsetfontids'][$j];
  4814.                         }
  4815.                         $tx sprintf("%02s"strtoupper(dechex($n)));
  4816.                         break;
  4817.                     }
  4818.                     if (!isset($this->CurrentFont['subsets'][($j 1)])) {
  4819.                         $this->CurrentFont['subsets'][($j 1)] = [=> 0];
  4820.                         $this->CurrentFont['subsetfontids'][($j 1)] = count($this->fonts) + $this->extraFontSubsets 1;
  4821.                         $this->extraFontSubsets++;
  4822.                     }
  4823.                 }
  4824.             } else {
  4825.                 $tx UtfString::code2utf($c);
  4826.                 if ($this->usingCoreFont) {
  4827.                     $tx iconv('UTF-8''ISO-8859-1//TRANSLIT'$tx);
  4828.                 } else {
  4829.                     $tx $this->writer->utf8ToUtf16BigEndian($txfalse);
  4830.                 }
  4831.                 $tx $this->writer->escape($tx);
  4832.             }
  4833.             // If any settings require a new Text Group
  4834.             if ($groupBreak || $fontstretch != $last_fontstretch) {
  4835.                 $tj .= $sipset
  4836.                     '>] TJ '
  4837.                     ')] TJ ';
  4838.                 if ($fontid != $last_fontid || $fontsize != $last_fontsize) {
  4839.                     $tj .= sprintf(' /F%d %.3F Tf '$fontid$fontsize);
  4840.                 }
  4841.                 if ($fontstretch != $last_fontstretch) {
  4842.                     $tj .= sprintf('%d Tz '$fontstretch);
  4843.                 }
  4844.                 if ($YPlacement != $lastYPlacement) {
  4845.                     $tj .= sprintf('%.3F Ts '$YPlacement);
  4846.                 }
  4847.                 $tj .= $sipset
  4848.                     '[<'
  4849.                     '[(';
  4850.             }
  4851.             // Output the code for the txt character
  4852.             $tj .= $tx;
  4853.             $lastSmallCapsON $SmallCapsON;
  4854.             $last_fontid $fontid;
  4855.             $last_fontsize $fontsize;
  4856.             $last_fontstretch $fontstretch;
  4857.             // Kashida
  4858.             if ($kashida) {
  4859.                 $c 0x0640// add the Tatweel U+0640
  4860.                 if (isset($this->CurrentFont['subset'])) {
  4861.                     $this->CurrentFont['subset'][$c] = $c;
  4862.                 }
  4863.                 $kashida *= 1000 $this->FontSizePt;
  4864.                 $tatw $this->_getCharWidth($this->CurrentFont['cw'], 0x0640);
  4865.                 // Get YPlacement from next Base character
  4866.                 $nextbase $i 1;
  4867.                 while ($OTLdata['group'][$nextbase] !== 'C') {
  4868.                     $nextbase++;
  4869.                 }
  4870.                 if (isset($GPOSinfo[$nextbase]) && isset($GPOSinfo[$nextbase]['YPlacement']) && $GPOSinfo[$nextbase]['YPlacement']) {
  4871.                     $YPlacement $GPOSinfo[$nextbase]['YPlacement'] * $this->FontSizePt $this->CurrentFont['unitsPerEm'];
  4872.                 }
  4873.                 // Prepare Text and Select Font ID
  4874.                 if ($sipset) {
  4875.                     for ($j 0$j 99$j++) {
  4876.                         $init array_search($c$this->CurrentFont['subsets'][$j]);
  4877.                         if ($init !== false) {
  4878.                             if ($this->CurrentFont['subsetfontids'][$j] != $last_fontid) {
  4879.                                 $fontid $this->CurrentFont['subsetfontids'][$j];
  4880.                             }
  4881.                             $tx sprintf("%02s"strtoupper(dechex($init)));
  4882.                             break;
  4883.                         }
  4884.                         if (count($this->CurrentFont['subsets'][$j]) < 255) {
  4885.                             $n count($this->CurrentFont['subsets'][$j]);
  4886.                             $this->CurrentFont['subsets'][$j][$n] = $c;
  4887.                             if ($this->CurrentFont['subsetfontids'][$j] != $last_fontid) {
  4888.                                 $fontid $this->CurrentFont['subsetfontids'][$j];
  4889.                             }
  4890.                             $tx sprintf("%02s"strtoupper(dechex($n)));
  4891.                             break;
  4892.                         }
  4893.                         if (!isset($this->CurrentFont['subsets'][($j 1)])) {
  4894.                             $this->CurrentFont['subsets'][($j 1)] = [=> 0];
  4895.                             $this->CurrentFont['subsetfontids'][($j 1)] = count($this->fonts) + $this->extraFontSubsets 1;
  4896.                             $this->extraFontSubsets++;
  4897.                         }
  4898.                     }
  4899.                 } else {
  4900.                     $tx UtfString::code2utf($c);
  4901.                     $tx $this->writer->utf8ToUtf16BigEndian($txfalse);
  4902.                     $tx $this->writer->escape($tx);
  4903.                 }
  4904.                 if ($kashida $tatw) {
  4905.                     // Insert multiple tatweel characters, repositioning the last one to give correct total length
  4906.                     $fontstretch 100;
  4907.                     $nt = (int) ($kashida $tatw);
  4908.                     $nudgeback = (($nt 1) * $tatw) - $kashida;
  4909.                     $optx str_repeat($tx$nt);
  4910.                     if ($sipset) {
  4911.                         $optx .= sprintf('>%d<', ($nudgeback));
  4912.                     } else {
  4913.                         $optx .= sprintf(')%d(', ($nudgeback));
  4914.                     }
  4915.                     $optx .= $tx// #last
  4916.                 } else {
  4917.                     // Insert single tatweel character and use fontstretch to get correct length
  4918.                     $fontstretch = ($kashida $tatw) * 100;
  4919.                     $optx $tx;
  4920.                 }
  4921.                 $tj .= $sipset
  4922.                     '>] TJ '
  4923.                     ')] TJ ';
  4924.                 if ($fontid != $last_fontid || $fontsize != $last_fontsize) {
  4925.                     $tj .= sprintf(' /F%d %.3F Tf '$fontid$fontsize);
  4926.                 }
  4927.                 if ($fontstretch != $last_fontstretch) {
  4928.                     $tj .= sprintf('%d Tz '$fontstretch);
  4929.                 }
  4930.                 $tj .= sprintf('%.3F Ts '$YPlacement);
  4931.                 $tj .= $sipset
  4932.                     '[<'
  4933.                     '[(';
  4934.                 // Output the code for the txt character(s)
  4935.                 $tj .= $optx;
  4936.                 $last_fontid $fontid;
  4937.                 $last_fontstretch $fontstretch;
  4938.                 $fontstretch 100;
  4939.             }
  4940.             $lastYPlacement $YPlacement;
  4941.         }
  4942.         $tj .= $sipset
  4943.             '>'
  4944.             ')';
  4945.         if ($XshiftAfter) {
  4946.             $tj .= sprintf('%d', (-$XshiftAfter));
  4947.         }
  4948.         if ($last_fontid != $original_fontid) {
  4949.             $tj .= '] TJ ';
  4950.             $tj .= sprintf(' /F%d %.3F Tf '$original_fontid$fontsize);
  4951.             $tj .= '[';
  4952.         }
  4953.         $tj $sipset
  4954.             preg_replace('/([^\\\])<>/''\\1 '$tj)
  4955.             : preg_replace('/([^\\\])\(\)/''\\1 '$tj);
  4956.         return sprintf(' BT ' $aix ' 0 Tc 0 Tw [%s] TJ ET '$x$y$tj);
  4957.     }
  4958.     function _kern($txt$mode$aix$x$y)
  4959.     {
  4960.         if ($mode === 'MBTw') { // Multibyte requiring word spacing
  4961.             $space ' ';
  4962.             // Convert string to UTF-16BE without BOM
  4963.             $space $this->writer->utf8ToUtf16BigEndian($spacefalse);
  4964.             $space $this->writer->escape($space);
  4965.             $s sprintf(' BT ' $aix$x Mpdf::SCALE, ($this->$y) * Mpdf::SCALE);
  4966.             $t explode(' '$txt);
  4967.             foreach ($t as $i => $iValue) {
  4968.                 $tx $iValue;
  4969.                 $tj '(';
  4970.                 $unicode $this->UTF8StringToArray($tx);
  4971.                 foreach ($unicode as $ti => $tiValue) {
  4972.                     if ($ti && isset($this->CurrentFont['kerninfo'][$unicode[($ti 1)]][$tiValue])) {
  4973.                         $kern = -$this->CurrentFont['kerninfo'][$unicode[($ti 1)]][$tiValue];
  4974.                         $tj .= sprintf(')%d('$kern);
  4975.                     }
  4976.                     $tc UtfString::code2utf($tiValue);
  4977.                     $tc $this->writer->utf8ToUtf16BigEndian($tcfalse);
  4978.                     $tj .= $this->writer->escape($tc);
  4979.                 }
  4980.                 $tj .= ')';
  4981.                 $s .= sprintf(' %.3F Tc [%s] TJ'$this->charspacing$tj);
  4982.                 if (($i 1) < count($t)) {
  4983.                     $s .= sprintf(' %.3F Tc (%s) Tj'$this->ws $this->charspacing$space);
  4984.                 }
  4985.             }
  4986.             $s .= ' ET ';
  4987.             return $s;
  4988.         }
  4989.         if (!$this->usingCoreFont) {
  4990.             $s '';
  4991.             $tj '(';
  4992.             $unicode $this->UTF8StringToArray($txt);
  4993.             foreach ($unicode as $i => $iValue) {
  4994.                 if ($i && isset($this->CurrentFont['kerninfo'][$unicode[($i 1)]][$iValue])) {
  4995.                     $kern = -$this->CurrentFont['kerninfo'][$unicode[($i 1)]][$iValue];
  4996.                     $tj .= sprintf(')%d('$kern);
  4997.                 }
  4998.                 $tx UtfString::code2utf($iValue);
  4999.                 $tx $this->writer->utf8ToUtf16BigEndian($txfalse);
  5000.                 $tj .= $this->writer->escape($tx);
  5001.             }
  5002.             $tj .= ')';
  5003.             $s .= sprintf(' BT ' $aix ' [%s] TJ ET '$x Mpdf::SCALE, ($this->$y) * Mpdf::SCALE$tj);
  5004.             return $s;
  5005.         }
  5006.         $s '';
  5007.         $tj '(';
  5008.         $l strlen($txt);
  5009.         for ($i 0$i $l$i++) {
  5010.             if ($i && isset($this->CurrentFont['kerninfo'][$txt[($i 1)]][$txt[$i]])) {
  5011.                 $kern = -$this->CurrentFont['kerninfo'][$txt[($i 1)]][$txt[$i]];
  5012.                 $tj .= sprintf(')%d('$kern);
  5013.             }
  5014.             $tj .= $this->writer->escape($txt[$i]);
  5015.         }
  5016.         $tj .= ')';
  5017.         $s .= sprintf(' BT ' $aix ' [%s] TJ ET '$x Mpdf::SCALE, ($this->$y) * Mpdf::SCALE$tj);
  5018.         return $s;
  5019.     }
  5020.     function MultiCell(
  5021.         $w,
  5022.         $h,
  5023.         $txt,
  5024.         $border 0,
  5025.         $align '',
  5026.         $fill 0,
  5027.         $link '',
  5028.         $directionality 'ltr',
  5029.         $encoded false,
  5030.         $OTLdata false,
  5031.         $maxrows false
  5032.     ) {
  5033.         // maxrows is called from mpdfform->TEXTAREA
  5034.         // Parameter (pre-)encoded - When called internally from form::textarea -
  5035.         // mb_encoding already done and OTL - but not reverse RTL
  5036.         if (!$encoded) {
  5037.             $txt $this->purify_utf8_text($txt);
  5038.             if ($this->text_input_as_HTML) {
  5039.                 $txt $this->all_entities_to_utf8($txt);
  5040.             }
  5041.             if ($this->usingCoreFont) {
  5042.                 $txt mb_convert_encoding($txt$this->mb_enc'UTF-8');
  5043.             }
  5044.             if (preg_match("/([" $this->pregRTLchars "])/u"$txt)) {
  5045.                 $this->biDirectional true;
  5046.             }
  5047.             /* -- OTL -- */
  5048.             if (!is_array($OTLdata)) {
  5049.                 unset($OTLdata);
  5050.             }
  5051.             // Use OTL OpenType Table Layout - GSUB & GPOS
  5052.             if (isset($this->CurrentFont['useOTL']) && $this->CurrentFont['useOTL']) {
  5053.                 $txt $this->otl->applyOTL($txt$this->CurrentFont['useOTL']);
  5054.                 $OTLdata $this->otl->OTLdata;
  5055.             }
  5056.             if ($directionality == 'rtl' || $this->biDirectional) {
  5057.                 if (!isset($OTLdata)) {
  5058.                     $unicode $this->UTF8StringToArray($txtfalse);
  5059.                     $is_strong false;
  5060.                     $this->getBasicOTLdata($OTLdata$unicode$is_strong);
  5061.                 }
  5062.             }
  5063.             /* -- END OTL -- */
  5064.         }
  5065.         if (!$align) {
  5066.             $align $this->defaultAlign;
  5067.         }
  5068.         // Output text with automatic or explicit line breaks
  5069.         $cw = &$this->CurrentFont['cw'];
  5070.         if ($w == 0) {
  5071.             $w $this->$this->rMargin $this->x;
  5072.         }
  5073.         $wmax = ($w - ($this->cMarginL $this->cMarginR));
  5074.         if ($this->usingCoreFont) {
  5075.             $s str_replace("\r"''$txt);
  5076.             $nb strlen($s);
  5077.             while ($nb and $s[$nb 1] == "\n") {
  5078.                 $nb--;
  5079.             }
  5080.         } else {
  5081.             $s str_replace("\r"''$txt);
  5082.             $nb mb_strlen($s$this->mb_enc);
  5083.             while ($nb and mb_substr($s$nb 11$this->mb_enc) == "\n") {
  5084.                 $nb--;
  5085.             }
  5086.         }
  5087.         $b 0;
  5088.         if ($border) {
  5089.             if ($border == 1) {
  5090.                 $border 'LTRB';
  5091.                 $b 'LRT';
  5092.                 $b2 'LR';
  5093.             } else {
  5094.                 $b2 '';
  5095.                 if (is_int(strpos($border'L'))) {
  5096.                     $b2 .= 'L';
  5097.                 }
  5098.                 if (is_int(strpos($border'R'))) {
  5099.                     $b2 .= 'R';
  5100.                 }
  5101.                 $b is_int(strpos($border'T')) ? $b2 'T' $b2;
  5102.             }
  5103.         }
  5104.         $sep = -1;
  5105.         $i 0;
  5106.         $j 0;
  5107.         $l 0;
  5108.         $ns 0;
  5109.         $nl 1;
  5110.         $rows 0;
  5111.         $start_y $this->y;
  5112.         if (!$this->usingCoreFont) {
  5113.             $inclCursive false;
  5114.             if (preg_match("/([" $this->pregCURSchars "])/u"$s)) {
  5115.                 $inclCursive true;
  5116.             }
  5117.             while ($i $nb) {
  5118.                 // Get next character
  5119.                 $c mb_substr($s$i1$this->mb_enc);
  5120.                 if ($c === "\n") { // Explicit line break
  5121.                     // WORD SPACING
  5122.                     $this->ResetSpacing();
  5123.                     $tmp rtrim(mb_substr($s$j$i $j$this->mb_enc));
  5124.                     $tmpOTLdata false;
  5125.                     /* -- OTL -- */
  5126.                     if (isset($OTLdata)) {
  5127.                         $tmpOTLdata $this->otl->sliceOTLdata($OTLdata$j$i $j);
  5128.                         $this->otl->trimOTLdata($tmpOTLdatafalsetrue);
  5129.                         $this->magic_reverse_dir($tmp$directionality$tmpOTLdata);
  5130.                     }
  5131.                     /* -- END OTL -- */
  5132.                     $this->Cell($w$h$tmp$b2$align$fill$link000'M'0false$tmpOTLdata);
  5133.                     if ($maxrows != false && isset($this->form) && ($this->$start_y) / $h $maxrows) {
  5134.                         return false;
  5135.                     }
  5136.                     $i++;
  5137.                     $sep = -1;
  5138.                     $j $i;
  5139.                     $l 0;
  5140.                     $ns 0;
  5141.                     $nl++;
  5142.                     if ($border and $nl == 2) {
  5143.                         $b $b2;
  5144.                     }
  5145.                     continue;
  5146.                 }
  5147.                 if ($c == " ") {
  5148.                     $sep $i;
  5149.                     $ls $l;
  5150.                     $ns++;
  5151.                 }
  5152.                 $l += $this->GetCharWidthNonCore($c);
  5153.                 if ($l $wmax) {
  5154.                     // Automatic line break
  5155.                     if ($sep == -1) { // Only one word
  5156.                         if ($i == $j) {
  5157.                             $i++;
  5158.                         }
  5159.                         // WORD SPACING
  5160.                         $this->ResetSpacing();
  5161.                         $tmp rtrim(mb_substr($s$j$i $j$this->mb_enc));
  5162.                         $tmpOTLdata false;
  5163.                         /* -- OTL -- */
  5164.                         if (isset($OTLdata)) {
  5165.                             $tmpOTLdata $this->otl->sliceOTLdata($OTLdata$j$i $j);
  5166.                             $this->otl->trimOTLdata($tmpOTLdatafalsetrue);
  5167.                             $this->magic_reverse_dir($tmp$directionality$tmpOTLdata);
  5168.                         }
  5169.                         /* -- END OTL -- */
  5170.                         $this->Cell($w$h$tmp$b2$align$fill$link000'M'0false$tmpOTLdata);
  5171.                     } else {
  5172.                         $tmp rtrim(mb_substr($s$j$sep $j$this->mb_enc));
  5173.                         $tmpOTLdata false;
  5174.                         /* -- OTL -- */
  5175.                         if (isset($OTLdata)) {
  5176.                             $tmpOTLdata $this->otl->sliceOTLdata($OTLdata$j$sep $j);
  5177.                             $this->otl->trimOTLdata($tmpOTLdatafalsetrue);
  5178.                         }
  5179.                         /* -- END OTL -- */
  5180.                         if ($align === 'J') {
  5181.                             // JUSTIFY J using Unicode fonts (Word spacing doesn't work)
  5182.                             // WORD SPACING UNICODE
  5183.                             // Change NON_BREAKING SPACE to spaces so they are 'spaced' properly
  5184.                             $tmp str_replace(chr(194) . chr(160), chr(32), $tmp);
  5185.                             $len_ligne $this->GetStringWidth($tmpfalse$tmpOTLdata);
  5186.                             $nb_carac mb_strlen($tmp$this->mb_enc);
  5187.                             $nb_spaces mb_substr_count($tmp' '$this->mb_enc);
  5188.                             // Take off number of Marks
  5189.                             // Use GPOS OTL
  5190.                             if (isset($this->CurrentFont['useOTL']) && ($this->CurrentFont['useOTL'])) {
  5191.                                 if (isset($tmpOTLdata['group']) && $tmpOTLdata['group']) {
  5192.                                     $nb_carac -= substr_count($tmpOTLdata['group'], 'M');
  5193.                                 }
  5194.                             }
  5195.                             list($charspacing$ws$kashida) = $this->GetJspacing($nb_carac$nb_spaces, ((($wmax) - $len_ligne) * Mpdf::SCALE), $inclCursive$tmpOTLdata);
  5196.                             $this->SetSpacing($charspacing$ws);
  5197.                         }
  5198.                         if (isset($OTLdata)) {
  5199.                             $this->magic_reverse_dir($tmp$directionality$tmpOTLdata);
  5200.                         }
  5201.                         $this->Cell($w$h$tmp$b2$align$fill$link000'M'0false$tmpOTLdata);
  5202.                         $i $sep 1;
  5203.                     }
  5204.                     if ($maxrows != false && isset($this->form) && ($this->$start_y) / $h $maxrows) {
  5205.                         return false;
  5206.                     }
  5207.                     $sep = -1;
  5208.                     $j $i;
  5209.                     $l 0;
  5210.                     $ns 0;
  5211.                     $nl++;
  5212.                     if ($border and $nl == 2) {
  5213.                         $b $b2;
  5214.                     }
  5215.                 } else {
  5216.                     $i++;
  5217.                 }
  5218.             }
  5219.             // Last chunk
  5220.             // WORD SPACING
  5221.             $this->ResetSpacing();
  5222.         } else {
  5223.             while ($i $nb) {
  5224.                 // Get next character
  5225.                 $c $s[$i];
  5226.                 if ($c === "\n") {
  5227.                     // Explicit line break
  5228.                     // WORD SPACING
  5229.                     $this->ResetSpacing();
  5230.                     $this->Cell($w$hsubstr($s$j$i $j), $b2$align$fill$link);
  5231.                     if ($maxrows != false && isset($this->form) && ($this->$start_y) / $h $maxrows) {
  5232.                         return false;
  5233.                     }
  5234.                     $i++;
  5235.                     $sep = -1;
  5236.                     $j $i;
  5237.                     $l 0;
  5238.                     $ns 0;
  5239.                     $nl++;
  5240.                     if ($border and $nl == 2) {
  5241.                         $b $b2;
  5242.                     }
  5243.                     continue;
  5244.                 }
  5245.                 if ($c === ' ') {
  5246.                     $sep $i;
  5247.                     $ls $l;
  5248.                     $ns++;
  5249.                 }
  5250.                 $l += $this->GetCharWidthCore($c);
  5251.                 if ($l $wmax) {
  5252.                     // Automatic line break
  5253.                     if ($sep == -1) {
  5254.                         if ($i == $j) {
  5255.                             $i++;
  5256.                         }
  5257.                         // WORD SPACING
  5258.                         $this->ResetSpacing();
  5259.                         $this->Cell($w$hsubstr($s$j$i $j), $b2$align$fill$link);
  5260.                     } else {
  5261.                         if ($align === 'J') {
  5262.                             $tmp rtrim(substr($s$j$sep $j));
  5263.                             // JUSTIFY J using Unicode fonts (Word spacing doesn't work)
  5264.                             // WORD SPACING NON_UNICODE/CJK
  5265.                             // Change NON_BREAKING SPACE to spaces so they are 'spaced' properly
  5266.                             $tmp str_replace(chr(160), chr(32), $tmp);
  5267.                             $len_ligne $this->GetStringWidth($tmp);
  5268.                             $nb_carac strlen($tmp);
  5269.                             $nb_spaces substr_count($tmp' ');
  5270.                             $tmpOTLdata = [];
  5271.                             list($charspacing$ws$kashida) = $this->GetJspacing($nb_carac$nb_spaces, ((($wmax) - $len_ligne) * Mpdf::SCALE), false$tmpOTLdata);
  5272.                             $this->SetSpacing($charspacing$ws);
  5273.                         }
  5274.                         $this->Cell($w$hsubstr($s$j$sep $j), $b2$align$fill$link);
  5275.                         $i $sep 1;
  5276.                     }
  5277.                     if ($maxrows != false && isset($this->form) && ($this->$start_y) / $h $maxrows) {
  5278.                         return false;
  5279.                     }
  5280.                     $sep = -1;
  5281.                     $j $i;
  5282.                     $l 0;
  5283.                     $ns 0;
  5284.                     $nl++;
  5285.                     if ($border and $nl == 2) {
  5286.                         $b $b2;
  5287.                     }
  5288.                 } else {
  5289.                     $i++;
  5290.                 }
  5291.             }
  5292.             // Last chunk
  5293.             // WORD SPACING
  5294.             $this->ResetSpacing();
  5295.         }
  5296.         // Last chunk
  5297.         if ($border and is_int(strpos($border'B'))) {
  5298.             $b .= 'B';
  5299.         }
  5300.         if (!$this->usingCoreFont) {
  5301.             $tmp rtrim(mb_substr($s$j$i $j$this->mb_enc));
  5302.             $tmpOTLdata false;
  5303.             /* -- OTL -- */
  5304.             if (isset($OTLdata)) {
  5305.                 $tmpOTLdata $this->otl->sliceOTLdata($OTLdata$j$i $j);
  5306.                 $this->otl->trimOTLdata($tmpOTLdatafalsetrue);
  5307.                 $this->magic_reverse_dir($tmp$directionality$tmpOTLdata);
  5308.             }
  5309.             /* -- END OTL -- */
  5310.             $this->Cell($w$h$tmp$b2$align$fill$link000'M'0false$tmpOTLdata);
  5311.         } else {
  5312.             $this->Cell($w$hsubstr($s$j$i $j), $b2$align$fill$link);
  5313.         }
  5314.         $this->$this->lMargin;
  5315.     }
  5316.     /* -- DIRECTW -- */
  5317.     function Write($h$txt$currentx 0$link ''$directionality 'ltr'$align ''$fill 0)
  5318.     {
  5319.         if (empty($this->directWrite)) {
  5320.             $this->directWrite = new DirectWrite($this$this->otl$this->sizeConverter$this->colorConverter);
  5321.         }
  5322.         $this->directWrite->Write($h$txt$currentx$link$directionality$align$fill);
  5323.     }
  5324.     /* -- END DIRECTW -- */
  5325.     /* -- HTML-CSS -- */
  5326.     function saveInlineProperties()
  5327.     {
  5328.         $saved = [];
  5329.         $saved['family'] = $this->FontFamily;
  5330.         $saved['style'] = $this->FontStyle;
  5331.         $saved['sizePt'] = $this->FontSizePt;
  5332.         $saved['size'] = $this->FontSize;
  5333.         $saved['HREF'] = $this->HREF;
  5334.         $saved['textvar'] = $this->textvar// mPDF 5.7.1
  5335.         $saved['OTLtags'] = $this->OTLtags// mPDF 5.7.1
  5336.         $saved['textshadow'] = $this->textshadow;
  5337.         $saved['linewidth'] = $this->LineWidth;
  5338.         $saved['drawcolor'] = $this->DrawColor;
  5339.         $saved['textparam'] = $this->textparam;
  5340.         $saved['lSpacingCSS'] = $this->lSpacingCSS;
  5341.         $saved['wSpacingCSS'] = $this->wSpacingCSS;
  5342.         $saved['I'] = $this->I;
  5343.         $saved['B'] = $this->B;
  5344.         $saved['colorarray'] = $this->colorarray;
  5345.         $saved['bgcolorarray'] = $this->spanbgcolorarray;
  5346.         $saved['border'] = $this->spanborddet;
  5347.         $saved['color'] = $this->TextColor;
  5348.         $saved['bgcolor'] = $this->FillColor;
  5349.         $saved['lang'] = $this->currentLang;
  5350.         $saved['fontLanguageOverride'] = $this->fontLanguageOverride// mPDF 5.7.1
  5351.         $saved['display_off'] = $this->inlineDisplayOff;
  5352.         return $saved;
  5353.     }
  5354.     function restoreInlineProperties(&$saved)
  5355.     {
  5356.         $FontFamily $saved['family'];
  5357.         $this->FontStyle $saved['style'];
  5358.         $this->FontSizePt $saved['sizePt'];
  5359.         $this->FontSize $saved['size'];
  5360.         $this->currentLang $saved['lang'];
  5361.         $this->fontLanguageOverride $saved['fontLanguageOverride']; // mPDF 5.7.1
  5362.         $this->ColorFlag = ($this->FillColor != $this->TextColor); // Restore ColorFlag as well
  5363.         $this->HREF $saved['HREF'];
  5364.         $this->textvar $saved['textvar']; // mPDF 5.7.1
  5365.         $this->OTLtags $saved['OTLtags']; // mPDF 5.7.1
  5366.         $this->textshadow $saved['textshadow'];
  5367.         $this->LineWidth $saved['linewidth'];
  5368.         $this->DrawColor $saved['drawcolor'];
  5369.         $this->textparam $saved['textparam'];
  5370.         $this->inlineDisplayOff $saved['display_off'];
  5371.         $this->lSpacingCSS $saved['lSpacingCSS'];
  5372.         if (($this->lSpacingCSS || $this->lSpacingCSS === '0') && strtoupper($this->lSpacingCSS) != 'NORMAL') {
  5373.             $this->fixedlSpacing $this->sizeConverter->convert($this->lSpacingCSS$this->FontSize);
  5374.         } else {
  5375.             $this->fixedlSpacing false;
  5376.         }
  5377.         $this->wSpacingCSS $saved['wSpacingCSS'];
  5378.         if ($this->wSpacingCSS && strtoupper($this->wSpacingCSS) != 'NORMAL') {
  5379.             $this->minwSpacing $this->sizeConverter->convert($this->wSpacingCSS$this->FontSize);
  5380.         } else {
  5381.             $this->minwSpacing 0;
  5382.         }
  5383.         $this->SetFont($FontFamily$saved['style'], $saved['sizePt'], false);
  5384.         $this->currentfontstyle $saved['style'];
  5385.         $this->currentfontsize $saved['sizePt'];
  5386.         $this->SetStylesArray(['B' => $saved['B'], 'I' => $saved['I']]); // mPDF 5.7.1
  5387.         $this->TextColor $saved['color'];
  5388.         $this->FillColor $saved['bgcolor'];
  5389.         $this->colorarray $saved['colorarray'];
  5390.         $cor $saved['colorarray'];
  5391.         if ($cor) {
  5392.             $this->SetTColor($cor);
  5393.         }
  5394.         $this->spanbgcolorarray $saved['bgcolorarray'];
  5395.         $cor $saved['bgcolorarray'];
  5396.         if ($cor) {
  5397.             $this->SetFColor($cor);
  5398.         }
  5399.         $this->spanborddet $saved['border'];
  5400.     }
  5401.     // Used when ColActive for tables - updated to return first block with background fill OR borders
  5402.     function GetFirstBlockFill()
  5403.     {
  5404.         // Returns the first blocklevel that uses a bgcolor fill
  5405.         $startfill 0;
  5406.         for ($i 1$i <= $this->blklvl$i++) {
  5407.             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']) {
  5408.                 $startfill $i;
  5409.                 break;
  5410.             }
  5411.         }
  5412.         return $startfill;
  5413.     }
  5414.     // -------------------------FLOWING BLOCK------------------------------------//
  5415.     // The following functions were originally written by Damon Kohler           //
  5416.     // --------------------------------------------------------------------------//
  5417.     function saveFont()
  5418.     {
  5419.         $saved = [];
  5420.         $saved['family'] = $this->FontFamily;
  5421.         $saved['style'] = $this->FontStyle;
  5422.         $saved['sizePt'] = $this->FontSizePt;
  5423.         $saved['size'] = $this->FontSize;
  5424.         $saved['curr'] = &$this->CurrentFont;
  5425.         $saved['lang'] = $this->currentLang// mPDF 6
  5426.         $saved['color'] = $this->TextColor;
  5427.         $saved['spanbgcolor'] = $this->spanbgcolor;
  5428.         $saved['spanbgcolorarray'] = $this->spanbgcolorarray;
  5429.         $saved['bord'] = $this->spanborder;
  5430.         $saved['border'] = $this->spanborddet;
  5431.         $saved['HREF'] = $this->HREF;
  5432.         $saved['textvar'] = $this->textvar// mPDF 5.7.1
  5433.         $saved['textshadow'] = $this->textshadow;
  5434.         $saved['linewidth'] = $this->LineWidth;
  5435.         $saved['drawcolor'] = $this->DrawColor;
  5436.         $saved['textparam'] = $this->textparam;
  5437.         $saved['ReqFontStyle'] = $this->ReqFontStyle;
  5438.         $saved['fixedlSpacing'] = $this->fixedlSpacing;
  5439.         $saved['minwSpacing'] = $this->minwSpacing;
  5440.         return $saved;
  5441.     }
  5442.     function restoreFont(&$saved$write true)
  5443.     {
  5444.         if (!isset($saved) || empty($saved)) {
  5445.             return;
  5446.         }
  5447.         $this->FontFamily $saved['family'];
  5448.         $this->FontStyle $saved['style'];
  5449.         $this->FontSizePt $saved['sizePt'];
  5450.         $this->FontSize $saved['size'];
  5451.         $this->CurrentFont = &$saved['curr'];
  5452.         $this->currentLang $saved['lang']; // mPDF 6
  5453.         $this->TextColor $saved['color'];
  5454.         $this->spanbgcolor $saved['spanbgcolor'];
  5455.         $this->spanbgcolorarray $saved['spanbgcolorarray'];
  5456.         $this->spanborder $saved['bord'];
  5457.         $this->spanborddet $saved['border'];
  5458.         $this->ColorFlag = ($this->FillColor != $this->TextColor); // Restore ColorFlag as well
  5459.         $this->HREF $saved['HREF'];
  5460.         $this->fixedlSpacing $saved['fixedlSpacing'];
  5461.         $this->minwSpacing $saved['minwSpacing'];
  5462.         $this->textvar $saved['textvar'];  // mPDF 5.7.1
  5463.         $this->textshadow $saved['textshadow'];
  5464.         $this->LineWidth $saved['linewidth'];
  5465.         $this->DrawColor $saved['drawcolor'];
  5466.         $this->textparam $saved['textparam'];
  5467.         if ($write) {
  5468.             $this->SetFont($saved['family'], $saved['style'], $saved['sizePt'], truetrue); // force output
  5469.             $fontout = (sprintf('BT /F%d %.3F Tf ET'$this->CurrentFont['i'], $this->FontSizePt));
  5470.             if ($this->page && ((isset($this->pageoutput[$this->page]['Font']) && $this->pageoutput[$this->page]['Font'] != $fontout) || !isset($this->pageoutput[$this->page]['Font']))) {
  5471.                 $this->writer->write($fontout);
  5472.             }
  5473.             $this->pageoutput[$this->page]['Font'] = $fontout;
  5474.         } else {
  5475.             $this->SetFont($saved['family'], $saved['style'], $saved['sizePt'], false);
  5476.         }
  5477.         $this->ReqFontStyle $saved['ReqFontStyle'];
  5478.     }
  5479.     function newFlowingBlock($w$h$a ''$is_table false$blockstate 0$newblock true$blockdir 'ltr'$table_draft false)
  5480.     {
  5481.         if (!$a) {
  5482.             if ($blockdir == 'rtl') {
  5483.                 $a 'R';
  5484.             } else {
  5485.                 $a 'L';
  5486.             }
  5487.         }
  5488.         $this->flowingBlockAttr['width'] = ($w Mpdf::SCALE);
  5489.         // line height in user units
  5490.         $this->flowingBlockAttr['is_table'] = $is_table;
  5491.         $this->flowingBlockAttr['table_draft'] = $table_draft;
  5492.         $this->flowingBlockAttr['height'] = $h;
  5493.         $this->flowingBlockAttr['lineCount'] = 0;
  5494.         $this->flowingBlockAttr['align'] = $a;
  5495.         $this->flowingBlockAttr['font'] = [];
  5496.         $this->flowingBlockAttr['content'] = [];
  5497.         $this->flowingBlockAttr['contentB'] = [];
  5498.         $this->flowingBlockAttr['contentWidth'] = 0;
  5499.         $this->flowingBlockAttr['blockstate'] = $blockstate;
  5500.         $this->flowingBlockAttr['newblock'] = $newblock;
  5501.         $this->flowingBlockAttr['valign'] = 'M';
  5502.         $this->flowingBlockAttr['blockdir'] = $blockdir;
  5503.         $this->flowingBlockAttr['cOTLdata'] = []; // mPDF 5.7.1
  5504.         $this->flowingBlockAttr['lastBidiText'] = ''// mPDF 5.7.1
  5505.         if (!empty($this->otl)) {
  5506.             $this->otl->lastBidiStrongType '';
  5507.         } // *OTL*
  5508.     }
  5509.     function finishFlowingBlock($endofblock false$next '')
  5510.     {
  5511.         $currentx $this->x;
  5512.         // prints out the last chunk
  5513.         $is_table $this->flowingBlockAttr['is_table'];
  5514.         $table_draft $this->flowingBlockAttr['table_draft'];
  5515.         $maxWidth = & $this->flowingBlockAttr['width'];
  5516.         $stackHeight = & $this->flowingBlockAttr['height'];
  5517.         $align = & $this->flowingBlockAttr['align'];
  5518.         $content = & $this->flowingBlockAttr['content'];
  5519.         $contentB = & $this->flowingBlockAttr['contentB'];
  5520.         $font = & $this->flowingBlockAttr['font'];
  5521.         $contentWidth = & $this->flowingBlockAttr['contentWidth'];
  5522.         $lineCount = & $this->flowingBlockAttr['lineCount'];
  5523.         $valign = & $this->flowingBlockAttr['valign'];
  5524.         $blockstate $this->flowingBlockAttr['blockstate'];
  5525.         $cOTLdata = & $this->flowingBlockAttr['cOTLdata']; // mPDF 5.7.1
  5526.         $newblock $this->flowingBlockAttr['newblock'];
  5527.         $blockdir $this->flowingBlockAttr['blockdir'];
  5528.         // *********** BLOCK BACKGROUND COLOR *****************//
  5529.         if ($this->blk[$this->blklvl]['bgcolor'] && !$is_table) {
  5530.             $fill 0;
  5531.         } else {
  5532.             $this->SetFColor($this->colorConverter->convert(255$this->PDFAXwarnings));
  5533.             $fill 0;
  5534.         }
  5535.         $hanger '';
  5536.         // Always right trim!
  5537.         // Right trim last content and adjust width if needed to justify (later)
  5538.         if (isset($content[count($content) - 1]) && preg_match('/[ ]+$/'$content[count($content) - 1], $m)) {
  5539.             $strip strlen($m[0]);
  5540.             $content[count($content) - 1] = substr($content[count($content) - 1], 0, (strlen($content[count($content) - 1]) - $strip));
  5541.             /* -- OTL -- */
  5542.             if (isset($this->CurrentFont['useOTL']) && $this->CurrentFont['useOTL']) {
  5543.                 $this->otl->trimOTLdata($cOTLdata[count($cOTLdata) - 1], falsetrue);
  5544.             }
  5545.             /* -- END OTL -- */
  5546.         }
  5547.         // the amount of space taken up so far in user units
  5548.         $usedWidth 0;
  5549.         // COLS
  5550.         $oldcolumn $this->CurrCol;
  5551.         if ($this->ColActive && !$is_table) {
  5552.             $this->breakpoints[$this->CurrCol][] = $this->y;
  5553.         } // *COLUMNS*
  5554.         // Print out each chunk
  5555.         /* -- TABLES -- */
  5556.         if ($is_table) {
  5557.             $ipaddingL 0;
  5558.             $ipaddingR 0;
  5559.             $paddingL 0;
  5560.             $paddingR 0;
  5561.         } else {
  5562.             /* -- END TABLES -- */
  5563.             $ipaddingL $this->blk[$this->blklvl]['padding_left'];
  5564.             $ipaddingR $this->blk[$this->blklvl]['padding_right'];
  5565.             $paddingL = ($ipaddingL Mpdf::SCALE);
  5566.             $paddingR = ($ipaddingR Mpdf::SCALE);
  5567.             $this->cMarginL $this->blk[$this->blklvl]['border_left']['w'];
  5568.             $this->cMarginR $this->blk[$this->blklvl]['border_right']['w'];
  5569.             // Added mPDF 3.0 Float DIV
  5570.             $fpaddingR 0;
  5571.             $fpaddingL 0;
  5572.             /* -- CSS-FLOAT -- */
  5573.             if (count($this->floatDivs)) {
  5574.                 list($l_exists$r_exists$l_max$r_max$l_width$r_width) = $this->GetFloatDivInfo($this->blklvl);
  5575.                 if ($r_exists) {
  5576.                     $fpaddingR $r_width;
  5577.                 }
  5578.                 if ($l_exists) {
  5579.                     $fpaddingL $l_width;
  5580.                 }
  5581.             }
  5582.             /* -- END CSS-FLOAT -- */
  5583.             $usey $this->0.002;
  5584.             if (($newblock) && ($blockstate == || $blockstate == 3) && ($lineCount == 0)) {
  5585.                 $usey += $this->blk[$this->blklvl]['margin_top'] + $this->blk[$this->blklvl]['padding_top'] + $this->blk[$this->blklvl]['border_top']['w'];
  5586.             }
  5587.             /* -- CSS-IMAGE-FLOAT -- */
  5588.             // If float exists at this level
  5589.             if (isset($this->floatmargins['R']) && $usey <= $this->floatmargins['R']['y1'] && $usey >= $this->floatmargins['R']['y0'] && !$this->floatmargins['R']['skipline']) {
  5590.                 $fpaddingR += $this->floatmargins['R']['w'];
  5591.             }
  5592.             if (isset($this->floatmargins['L']) && $usey <= $this->floatmargins['L']['y1'] && $usey >= $this->floatmargins['L']['y0'] && !$this->floatmargins['L']['skipline']) {
  5593.                 $fpaddingL += $this->floatmargins['L']['w'];
  5594.             }
  5595.             /* -- END CSS-IMAGE-FLOAT -- */
  5596.         // *TABLES*
  5597.         $lineBox = [];
  5598.         $this->_setInlineBlockHeights($lineBox$stackHeight$content$font$is_table);
  5599.         if ($is_table && count($content) == 0) {
  5600.             $stackHeight 0;
  5601.         }
  5602.         if ($table_draft) {
  5603.             $this->+= $stackHeight;
  5604.             $this->objectbuffer = [];
  5605.             return 0;
  5606.         }
  5607.         // While we're at it, check if contains cursive text
  5608.         // Change NBSP to SPACE.
  5609.         // Re-calculate contentWidth
  5610.         $contentWidth 0;
  5611.         foreach ($content as $k => $chunk) {
  5612.             $this->restoreFont($font[$k], false);
  5613.             if (!isset($this->objectbuffer[$k]) || (isset($this->objectbuffer[$k]) && !$this->objectbuffer[$k])) {
  5614.                 // Soft Hyphens chr(173)
  5615.                 if (!$this->usingCoreFont) {
  5616.                     /* -- OTL -- */
  5617.                     // mPDF 5.7.1
  5618.                     if (isset($this->CurrentFont['useOTL']) && $this->CurrentFont['useOTL']) {
  5619.                         $this->otl->removeChar($chunk$cOTLdata[$k], "\xc2\xad");
  5620.                         $this->otl->replaceSpace($chunk$cOTLdata[$k]);
  5621.                         $content[$k] = $chunk;
  5622.                     } /* -- END OTL -- */ else {  // *OTL*
  5623.                         $content[$k] = $chunk str_replace("\xc2\xad"''$chunk);
  5624.                         $content[$k] = $chunk str_replace(chr(194) . chr(160), chr(32), $chunk);
  5625.                     } // *OTL*
  5626.                 } elseif ($this->FontFamily != 'csymbol' && $this->FontFamily != 'czapfdingbats') {
  5627.                     $content[$k] = $chunk str_replace(chr(173), ''$chunk);
  5628.                     $content[$k] = $chunk str_replace(chr(160), chr(32), $chunk);
  5629.                 }
  5630.                 $contentWidth += $this->GetStringWidth($chunktrue, (isset($cOTLdata[$k]) ? $cOTLdata[$k] : false), $this->textvar) * Mpdf::SCALE;
  5631.             } elseif (isset($this->objectbuffer[$k]) && $this->objectbuffer[$k]) {
  5632.                 // LIST MARKERS    // mPDF 6  Lists
  5633.                 if ($this->objectbuffer[$k]['type'] == 'image' && isset($this->objectbuffer[$k]['listmarker']) && $this->objectbuffer[$k]['listmarker'] && $this->objectbuffer[$k]['listmarkerposition'] == 'outside') {
  5634.                     // do nothing
  5635.                 } else {
  5636.                     $contentWidth += $this->objectbuffer[$k]['OUTER-WIDTH'] * Mpdf::SCALE;
  5637.                 }
  5638.             }
  5639.         }
  5640.         if (isset($font[count($font) - 1])) {
  5641.             $lastfontreqstyle = (isset($font[count($font) - 1]['ReqFontStyle']) ? $font[count($font) - 1]['ReqFontStyle'] : '');
  5642.             $lastfontstyle = (isset($font[count($font) - 1]['style']) ? $font[count($font) - 1]['style'] : '');
  5643.         } else {
  5644.             $lastfontreqstyle null;
  5645.             $lastfontstyle null;
  5646.         }
  5647.         if ($blockdir == 'ltr' && $lastfontreqstyle && strpos($lastfontreqstyle"I") !== false && strpos($lastfontstyle"I") === false) { // Artificial italic
  5648.             $lastitalic $this->FontSize 0.15 Mpdf::SCALE;
  5649.         } else {
  5650.             $lastitalic 0;
  5651.         }
  5652.         // Get PAGEBREAK TO TEST for height including the bottom border/padding
  5653.         $check_h max($this->divheight$stackHeight);
  5654.         // This fixes a proven bug...
  5655.         if ($endofblock && $newblock && $blockstate == && !$content) {
  5656.             $check_h 0;
  5657.         }
  5658.         // but ? needs to fix potentially more widespread...
  5659.         // if (!$content) {  $check_h = 0; }
  5660.         if ($this->blklvl && !$is_table) {
  5661.             if ($endofblock && $blockstate 1) {
  5662.                 if ($this->blk[$this->blklvl]['page_break_after_avoid']) {
  5663.                     $check_h += $stackHeight;
  5664.                 }
  5665.                 $check_h += ($this->blk[$this->blklvl]['padding_bottom'] + $this->blk[$this->blklvl]['border_bottom']['w']);
  5666.             }
  5667.             if (($newblock && ($blockstate == || $blockstate == 3) && $lineCount == 0) || ($endofblock && $blockstate == && $lineCount == 0)) {
  5668.                 $check_h += ($this->blk[$this->blklvl]['padding_top'] + $this->blk[$this->blklvl]['margin_top'] + $this->blk[$this->blklvl]['border_top']['w']);
  5669.             }
  5670.         }
  5671.         // Force PAGE break if column height cannot take check-height
  5672.         if ($this->ColActive && $check_h > ($this->PageBreakTrigger $this->y0)) {
  5673.             $this->SetCol($this->NbCol 1);
  5674.         }
  5675.         // Avoid just border/background-color moved on to next page
  5676.         if ($endofblock && $blockstate && !$content) {
  5677.             $buff $this->margBuffer;
  5678.         } else {
  5679.             $buff 0;
  5680.         }
  5681.         // PAGEBREAK
  5682.         if (!$is_table && ($this->$check_h) > ($this->PageBreakTrigger $buff) and ! $this->InFooter and $this->AcceptPageBreak()) {
  5683.             $bak_x $this->x// Current X position
  5684.             // WORD SPACING
  5685.             $ws $this->ws// Word Spacing
  5686.             $charspacing $this->charspacing// Character Spacing
  5687.             $this->ResetSpacing();
  5688.             $this->AddPage($this->CurOrientation);
  5689.             $this->$bak_x;
  5690.             // Added to correct for OddEven Margins
  5691.             $currentx += $this->MarginCorrection;
  5692.             $this->+= $this->MarginCorrection;
  5693.             // WORD SPACING
  5694.             $this->SetSpacing($charspacing$ws);
  5695.         }
  5696.         /* -- COLUMNS -- */
  5697.         // COLS
  5698.         // COLUMN CHANGE
  5699.         if ($this->CurrCol != $oldcolumn) {
  5700.             $currentx += $this->ChangeColumn * ($this->ColWidth $this->ColGap);
  5701.             $this->+= $this->ChangeColumn * ($this->ColWidth $this->ColGap);
  5702.             $oldcolumn $this->CurrCol;
  5703.         }
  5704.         if ($this->ColActive && !$is_table) {
  5705.             $this->breakpoints[$this->CurrCol][] = $this->y;
  5706.         }
  5707.         /* -- END COLUMNS -- */
  5708.         // TOP MARGIN
  5709.         if ($newblock && ($blockstate == || $blockstate == 3) && ($this->blk[$this->blklvl]['margin_top']) && $lineCount == && !$is_table) {
  5710.             $this->DivLn($this->blk[$this->blklvl]['margin_top'], $this->blklvl 1true$this->blk[$this->blklvl]['margin_collapse']);
  5711.             if ($this->ColActive) {
  5712.                 $this->breakpoints[$this->CurrCol][] = $this->y;
  5713.             } // *COLUMNS*
  5714.         }
  5715.         if ($newblock && ($blockstate == || $blockstate == 3) && $lineCount == && !$is_table) {
  5716.             $this->blk[$this->blklvl]['y0'] = $this->y;
  5717.             $this->blk[$this->blklvl]['startpage'] = $this->page;
  5718.             if ($this->blk[$this->blklvl]['float']) {
  5719.                 $this->blk[$this->blklvl]['float_start_y'] = $this->y;
  5720.             }
  5721.             if ($this->ColActive) {
  5722.                 $this->breakpoints[$this->CurrCol][] = $this->y;
  5723.             } // *COLUMNS*
  5724.         }
  5725.         // Paragraph INDENT
  5726.         $WidthCorrection 0;
  5727.         if (($newblock) && ($blockstate == || $blockstate == 3) && isset($this->blk[$this->blklvl]['text_indent']) && ($lineCount == 0) && (!$is_table) && ($align != 'C')) {
  5728.             $ti $this->sizeConverter->convert($this->blk[$this->blklvl]['text_indent'], $this->blk[$this->blklvl]['inner_width'], $this->blk[$this->blklvl]['InlineProperties']['size'], false);  // mPDF 5.7.4
  5729.             $WidthCorrection = ($ti Mpdf::SCALE);
  5730.         }
  5731.         // PADDING and BORDER spacing/fill
  5732.         if (($newblock) && ($blockstate == || $blockstate == 3) && (($this->blk[$this->blklvl]['padding_top']) || ($this->blk[$this->blklvl]['border_top'])) && ($lineCount == 0) && (!$is_table)) {
  5733.             // $state = 0 normal; 1 top; 2 bottom; 3 top and bottom
  5734.             $this->DivLn($this->blk[$this->blklvl]['padding_top'] + $this->blk[$this->blklvl]['border_top']['w'], -3truefalse1);
  5735.             if ($this->ColActive) {
  5736.                 $this->breakpoints[$this->CurrCol][] = $this->y;
  5737.             } // *COLUMNS*
  5738.             $this->$currentx;
  5739.         }
  5740.         // Added mPDF 3.0 Float DIV
  5741.         $fpaddingR 0;
  5742.         $fpaddingL 0;
  5743.         /* -- CSS-FLOAT -- */
  5744.         if (count($this->floatDivs)) {
  5745.             list($l_exists$r_exists$l_max$r_max$l_width$r_width) = $this->GetFloatDivInfo($this->blklvl);
  5746.             if ($r_exists) {
  5747.                 $fpaddingR $r_width;
  5748.             }
  5749.             if ($l_exists) {
  5750.                 $fpaddingL $l_width;
  5751.             }
  5752.         }
  5753.         /* -- END CSS-FLOAT -- */
  5754.         $usey $this->0.002;
  5755.         if (($newblock) && ($blockstate == || $blockstate == 3) && ($lineCount == 0)) {
  5756.             $usey += $this->blk[$this->blklvl]['margin_top'] + $this->blk[$this->blklvl]['padding_top'] + $this->blk[$this->blklvl]['border_top']['w'];
  5757.         }
  5758.         /* -- CSS-IMAGE-FLOAT -- */
  5759.         // If float exists at this level
  5760.         if (isset($this->floatmargins['R']) && $usey <= $this->floatmargins['R']['y1'] && $usey >= $this->floatmargins['R']['y0'] && !$this->floatmargins['R']['skipline']) {
  5761.             $fpaddingR += $this->floatmargins['R']['w'];
  5762.         }
  5763.         if (isset($this->floatmargins['L']) && $usey <= $this->floatmargins['L']['y1'] && $usey >= $this->floatmargins['L']['y0'] && !$this->floatmargins['L']['skipline']) {
  5764.             $fpaddingL += $this->floatmargins['L']['w'];
  5765.         }
  5766.         /* -- END CSS-IMAGE-FLOAT -- */
  5767.         if ($content) {
  5768.             // In FinishFlowing Block no lines are justified as it is always last line
  5769.             // but if CJKorphan has allowed content width to go over max width, use J charspacing to compress line
  5770.             // JUSTIFICATION J - NOT!
  5771.             $nb_carac 0;
  5772.             $nb_spaces 0;
  5773.             $jcharspacing 0;
  5774.             $jkashida 0;
  5775.             $jws 0;
  5776.             $inclCursive false;
  5777.             $dottab false;
  5778.             foreach ($content as $k => $chunk) {
  5779.                 if (!isset($this->objectbuffer[$k]) || (isset($this->objectbuffer[$k]) && !$this->objectbuffer[$k])) {
  5780.                     $nb_carac += mb_strlen($chunk$this->mb_enc);
  5781.                     $nb_spaces += mb_substr_count($chunk' '$this->mb_enc);
  5782.                     // mPDF 6
  5783.                     // Use GPOS OTL
  5784.                     $this->restoreFont($font[$k], false);
  5785.                     if (isset($this->CurrentFont['useOTL']) && $this->CurrentFont['useOTL']) {
  5786.                         if (isset($cOTLdata[$k]['group']) && $cOTLdata[$k]['group']) {
  5787.                             $nb_marks substr_count($cOTLdata[$k]['group'], 'M');
  5788.                             $nb_carac -= $nb_marks;
  5789.                         }
  5790.                         if (preg_match("/([" $this->pregCURSchars "])/u"$chunk)) {
  5791.                             $inclCursive true;
  5792.                         }
  5793.                     }
  5794.                 } else {
  5795.                     $nb_carac ++;  // mPDF 6 allow spacing for inline object
  5796.                     if ($this->objectbuffer[$k]['type'] == 'dottab') {
  5797.                         $dottab $this->objectbuffer[$k]['outdent'];
  5798.                     }
  5799.                 }
  5800.             }
  5801.             // DIRECTIONALITY RTL
  5802.             $chunkorder range(0count($content) - 1); // mPDF 6
  5803.             /* -- OTL -- */
  5804.             // mPDF 6
  5805.             if ($blockdir == 'rtl' || $this->biDirectional) {
  5806.                 $this->otl->bidiReorder($chunkorder$content$cOTLdata$blockdir);
  5807.                 // From this point on, $content and $cOTLdata may contain more elements (and re-ordered) compared to
  5808.                 // $this->objectbuffer and $font ($chunkorder contains the mapping)
  5809.             }
  5810.             /* -- END OTL -- */
  5811.             // Remove any XAdvance from OTL data at end of line
  5812.             // And correct for XPlacement on last character
  5813.             // BIDI is applied
  5814.             foreach ($chunkorder as $aord => $k) {
  5815.                 if (count($cOTLdata)) {
  5816.                     $this->restoreFont($font[$k], false);
  5817.                     // ...FinishFlowingBlock...
  5818.                     if ($aord == count($chunkorder) - && isset($cOTLdata[$aord]['group'])) { // Last chunk on line
  5819.                         $nGPOS strlen($cOTLdata[$aord]['group']) - 1// Last character
  5820.                         if (isset($cOTLdata[$aord]['GPOSinfo'][$nGPOS]['XAdvanceL']) || isset($cOTLdata[$aord]['GPOSinfo'][$nGPOS]['XAdvanceR'])) {
  5821.                             if (isset($cOTLdata[$aord]['GPOSinfo'][$nGPOS]['XAdvanceL'])) {
  5822.                                 $w $cOTLdata[$aord]['GPOSinfo'][$nGPOS]['XAdvanceL'] * 1000 $this->CurrentFont['unitsPerEm'];
  5823.                             } else {
  5824.                                 $w $cOTLdata[$aord]['GPOSinfo'][$nGPOS]['XAdvanceR'] * 1000 $this->CurrentFont['unitsPerEm'];
  5825.                             }
  5826.                             $w *= ($this->FontSize 1000);
  5827.                             $contentWidth -= $w Mpdf::SCALE;
  5828.                             $cOTLdata[$aord]['GPOSinfo'][$nGPOS]['XAdvanceL'] = 0;
  5829.                             $cOTLdata[$aord]['GPOSinfo'][$nGPOS]['XAdvanceR'] = 0;
  5830.                         }
  5831.                         // If last character has an XPlacement set, adjust width calculation, and add to XAdvance to account for it
  5832.                         if (isset($cOTLdata[$aord]['GPOSinfo'][$nGPOS]['XPlacement'])) {
  5833.                             $w = -$cOTLdata[$aord]['GPOSinfo'][$nGPOS]['XPlacement'] * 1000 $this->CurrentFont['unitsPerEm'];
  5834.                             $w *= ($this->FontSize 1000);
  5835.                             $contentWidth -= $w Mpdf::SCALE;
  5836.                             $cOTLdata[$aord]['GPOSinfo'][$nGPOS]['XAdvanceL'] = $cOTLdata[$aord]['GPOSinfo'][$nGPOS]['XPlacement'];
  5837.                             $cOTLdata[$aord]['GPOSinfo'][$nGPOS]['XAdvanceR'] = $cOTLdata[$aord]['GPOSinfo'][$nGPOS]['XPlacement'];
  5838.                         }
  5839.                     }
  5840.                 }
  5841.             }
  5842.             // 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)
  5843.             // If "orphans" in fact is just a final space - ignore this
  5844.             $lastchar mb_substr($content[(count($chunkorder) - 1)], mb_strlen($content[(count($chunkorder) - 1)], $this->mb_enc) - 11$this->mb_enc);
  5845.             if (preg_match("/[" $this->CJKoverflow "]/u"$lastchar)) {
  5846.                 $CJKoverflow true;
  5847.             } else {
  5848.                 $CJKoverflow false;
  5849.             }
  5850.             if ((((($contentWidth $lastitalic) > $maxWidth) && ($content[(count($chunkorder) - 1)] != ' ') ) ||
  5851.                 (!$endofblock && $align == 'J' && ($next == 'image' || $next == 'select' || $next == 'input' || $next == 'textarea' || ($next == 'br' && $this->justifyB4br)))) && !($CJKoverflow && $this->allowCJKoverflow)) {
  5852.                 // WORD SPACING
  5853.                 list($jcharspacing$jws$jkashida) = $this->GetJspacing($nb_carac$nb_spaces, ($maxWidth $lastitalic $contentWidth $WidthCorrection - (($this->cMarginL $this->cMarginR) * Mpdf::SCALE) - ($paddingL $paddingR + (($fpaddingL $fpaddingR) * Mpdf::SCALE) )), $inclCursive$cOTLdata);
  5854.             } /* -- CJK-FONTS -- */ elseif ($this->checkCJK && $align == 'J' && $CJKoverflow && $this->allowCJKoverflow && $this->CJKforceend) {
  5855.                 // force-end overhang
  5856.                 $hanger mb_substr($content[(count($chunkorder) - 1)], mb_strlen($content[(count($chunkorder) - 1)], $this->mb_enc) - 11$this->mb_enc);
  5857.                 if (preg_match("/[" $this->CJKoverflow "]/u"$hanger)) {
  5858.                     $content[(count($chunkorder) - 1)] = mb_substr($content[(count($chunkorder) - 1)], 0mb_strlen($content[(count($chunkorder) - 1)], $this->mb_enc) - 1$this->mb_enc);
  5859.                     $this->restoreFont($font[$chunkorder[count($chunkorder) - 1]], false);
  5860.                     $contentWidth -= $this->GetStringWidth($hanger) * Mpdf::SCALE;
  5861.                     $nb_carac -= 1;
  5862.                     list($jcharspacing$jws$jkashida) = $this->GetJspacing($nb_carac$nb_spaces, ($maxWidth $lastitalic $contentWidth $WidthCorrection - (($this->cMarginL $this->cMarginR) * Mpdf::SCALE) - ($paddingL $paddingR + (($fpaddingL $fpaddingR) * Mpdf::SCALE) )), $inclCursive$cOTLdata);
  5863.                 }
  5864.             } /* -- END CJK-FONTS -- */
  5865.             // Check if will fit at word/char spacing of previous line - if so continue it
  5866.             // but only allow a maximum of $this->jSmaxWordLast and $this->jSmaxCharLast
  5867.             elseif ($contentWidth < ($maxWidth $lastitalic $WidthCorrection - (($this->cMarginL $this->cMarginR) * Mpdf::SCALE) - ($paddingL $paddingR + (($fpaddingL $fpaddingR) * Mpdf::SCALE))) && !$this->fixedlSpacing) {
  5868.                 if ($this->ws $this->jSmaxWordLast) {
  5869.                     $jws $this->jSmaxWordLast;
  5870.                 }
  5871.                 if ($this->charspacing $this->jSmaxCharLast) {
  5872.                     $jcharspacing $this->jSmaxCharLast;
  5873.                 }
  5874.                 $check $maxWidth $lastitalic $WidthCorrection $contentWidth - (($this->cMarginL $this->cMarginR) * Mpdf::SCALE) - ($paddingL $paddingR + (($fpaddingL $fpaddingR) * Mpdf::SCALE) ) - ( $jcharspacing $nb_carac) - ( $jws $nb_spaces);
  5875.                 if ($check <= 0) {
  5876.                     $jcharspacing 0;
  5877.                     $jws 0;
  5878.                 }
  5879.             }
  5880.             $empty $maxWidth $lastitalic $WidthCorrection $contentWidth - (($this->cMarginL $this->cMarginR) * Mpdf::SCALE) - ($paddingL $paddingR + (($fpaddingL $fpaddingR) * Mpdf::SCALE) );
  5881.             $empty -= ($jcharspacing * ($nb_carac 1)); // mPDF 6 nb_carac MINUS 1
  5882.             $empty -= ($jws $nb_spaces);
  5883.             $empty -= ($jkashida);
  5884.             $empty /= Mpdf::SCALE;
  5885.             if (!$is_table) {
  5886.                 $this->maxPosR max($this->maxPosR, ($this->$this->rMargin $this->blk[$this->blklvl]['outer_right_margin'] - $empty));
  5887.                 $this->maxPosL min($this->maxPosL, ($this->lMargin $this->blk[$this->blklvl]['outer_left_margin'] + $empty));
  5888.             }
  5889.             $arraysize count($chunkorder);
  5890.             $margins = ($this->cMarginL $this->cMarginR) + ($ipaddingL $ipaddingR $fpaddingR $fpaddingR );
  5891.             if (!$is_table) {
  5892.                 $this->DivLn($stackHeight$this->blklvlfalse);
  5893.             } // false -> don't advance y
  5894.             $this->$currentx $this->cMarginL $ipaddingL $fpaddingL;
  5895.             if ($dottab !== false && $blockdir == 'rtl') {
  5896.                 $this->-= $dottab;
  5897.             } elseif ($align == 'R') {
  5898.                 $this->+= $empty;
  5899.             } elseif ($align == 'J' && $blockdir == 'rtl') {
  5900.                 $this->+= $empty;
  5901.             } elseif ($align == 'C') {
  5902.                 $this->+= ($empty 2);
  5903.             }
  5904.             // Paragraph INDENT
  5905.             $WidthCorrection 0;
  5906.             if (($newblock) && ($blockstate == || $blockstate == 3) && isset($this->blk[$this->blklvl]['text_indent']) && ($lineCount == 0) && (!$is_table) && ($align != 'C')) {
  5907.                 $ti $this->sizeConverter->convert($this->blk[$this->blklvl]['text_indent'], $this->blk[$this->blklvl]['inner_width'], $this->blk[$this->blklvl]['InlineProperties']['size'], false);  // mPDF 5.7.4
  5908.                 if ($blockdir != 'rtl') {
  5909.                     $this->+= $ti;
  5910.                 } // mPDF 6
  5911.             }
  5912.             foreach ($chunkorder as $aord => $k) { // mPDF 5.7
  5913.                 $chunk $content[$aord];
  5914.                 if (isset($this->objectbuffer[$k]) && $this->objectbuffer[$k]) {
  5915.                     $xadj $this->$this->objectbuffer[$k]['OUTER-X'];
  5916.                     $this->objectbuffer[$k]['OUTER-X'] += $xadj;
  5917.                     $this->objectbuffer[$k]['BORDER-X'] += $xadj;
  5918.                     $this->objectbuffer[$k]['INNER-X'] += $xadj;
  5919.                     if ($this->objectbuffer[$k]['type'] == 'listmarker') {
  5920.                         $this->objectbuffer[$k]['lineBox'] = $lineBox[-1]; // Block element details for glyph-origin
  5921.                     }
  5922.                     $yadj $this->$this->objectbuffer[$k]['OUTER-Y'];
  5923.                     if ($this->objectbuffer[$k]['type'] == 'dottab') { // mPDF 6 DOTTAB
  5924.                         $this->objectbuffer[$k]['lineBox'] = $lineBox[$k]; // element details for glyph-origin
  5925.                     }
  5926.                     if ($this->objectbuffer[$k]['type'] != 'dottab') { // mPDF 6 DOTTAB
  5927.                         $yadj += $lineBox[$k]['top'];
  5928.                     }
  5929.                     $this->objectbuffer[$k]['OUTER-Y'] += $yadj;
  5930.                     $this->objectbuffer[$k]['BORDER-Y'] += $yadj;
  5931.                     $this->objectbuffer[$k]['INNER-Y'] += $yadj;
  5932.                 }
  5933.                 $this->restoreFont($font[$k]);  // mPDF 5.7
  5934.                 if ($is_table && substr($align01) == 'D' && $aord == 0) {
  5935.                     $dp $this->decimal_align[substr($align02)];
  5936.                     $s preg_split('/' preg_quote($dp'/') . '/'$content[0], 2);  // ? needs to be /u if not core
  5937.                     $s0 $this->GetStringWidth($s[0], false);
  5938.                     $this->+= ($this->decimal_offset $s0);
  5939.                 }
  5940.                 $this->SetSpacing(($this->fixedlSpacing Mpdf::SCALE) + $jcharspacing, ($this->fixedlSpacing $this->minwSpacing) * Mpdf::SCALE $jws);
  5941.                 $this->fixedlSpacing false;
  5942.                 $this->minwSpacing 0;
  5943.                 $save_vis $this->visibility;
  5944.                 if (isset($this->textparam['visibility']) && $this->textparam['visibility'] && $this->textparam['visibility'] != $this->visibility) {
  5945.                     $this->SetVisibility($this->textparam['visibility']);
  5946.                 }
  5947.                 // *********** SPAN BACKGROUND COLOR ***************** //
  5948.                 if (isset($this->spanbgcolor) && $this->spanbgcolor) {
  5949.                     $cor $this->spanbgcolorarray;
  5950.                     $this->SetFColor($cor);
  5951.                     $save_fill $fill;
  5952.                     $spanfill 1;
  5953.                     $fill 1;
  5954.                 }
  5955.                 if (!empty($this->spanborddet)) {
  5956.                     if (strpos($contentB[$k], 'L') !== false && isset($this->spanborddet['L'])) {
  5957.                         $this->+= $this->spanborddet['L']['w'];
  5958.                     }
  5959.                     if (strpos($contentB[$k], 'L') === false) {
  5960.                         $this->spanborddet['L']['s'] = $this->spanborddet['L']['w'] = 0;
  5961.                     }
  5962.                     if (strpos($contentB[$k], 'R') === false) {
  5963.                         $this->spanborddet['R']['s'] = $this->spanborddet['R']['w'] = 0;
  5964.                     }
  5965.                 }
  5966.                 // WORD SPACING
  5967.                 // mPDF 5.7.1
  5968.                 $stringWidth $this->GetStringWidth($chunktrue, (isset($cOTLdata[$aord]) ? $cOTLdata[$aord] : false), $this->textvar);
  5969.                 $nch mb_strlen($chunk$this->mb_enc);
  5970.                 // Use GPOS OTL
  5971.                 if (isset($this->CurrentFont['useOTL']) && $this->CurrentFont['useOTL']) {
  5972.                     if (isset($cOTLdata[$aord]['group']) && $cOTLdata[$aord]['group']) {
  5973.                         $nch -= substr_count($cOTLdata[$aord]['group'], 'M');
  5974.                     }
  5975.                 }
  5976.                 $stringWidth += ( $this->charspacing $nch Mpdf::SCALE );
  5977.                 $stringWidth += ( $this->ws mb_substr_count($chunk' '$this->mb_enc) / Mpdf::SCALE );
  5978.                 if (isset($this->objectbuffer[$k])) {
  5979.                     if ($this->objectbuffer[$k]['type'] == 'dottab') {
  5980.                         $this->objectbuffer[$k]['OUTER-WIDTH'] +=$empty;
  5981.                         $this->objectbuffer[$k]['OUTER-WIDTH'] +=$this->objectbuffer[$k]['outdent'];
  5982.                     }
  5983.                     // LIST MARKERS    // mPDF 6  Lists
  5984.                     if ($this->objectbuffer[$k]['type'] == 'image' && isset($this->objectbuffer[$k]['listmarker']) && $this->objectbuffer[$k]['listmarker'] && $this->objectbuffer[$k]['listmarkerposition'] == 'outside') {
  5985.                         // do nothing
  5986.                     } else {
  5987.                         $stringWidth $this->objectbuffer[$k]['OUTER-WIDTH'];
  5988.                     }
  5989.                 }
  5990.                 if ($stringWidth == 0) {
  5991.                     $stringWidth 0.000001;
  5992.                 }
  5993.                 if ($aord == $arraysize 1) { // mPDF 5.7
  5994.                     // mPDF 5.7.1
  5995.                     if ($this->checkCJK && $CJKoverflow && $align == 'J' && $this->allowCJKoverflow && $hanger && $this->CJKforceend) {
  5996.                         // force-end overhang
  5997.                         $this->Cell($stringWidth$stackHeight$chunk''0''$fill$this->HREF$currentx00'M'$filltrue, (isset($cOTLdata[$aord]) ? $cOTLdata[$aord] : false), $this->textvar, (isset($lineBox[$k]) ? $lineBox[$k] : false));  // mPDF 5.7.1
  5998.                         $this->Cell($this->GetStringWidth($hanger), $stackHeight$hanger''1''$fill$this->HREF$currentx00'M'$filltrue, (isset($cOTLdata[$aord]) ? $cOTLdata[$aord] : false), $this->textvar, (isset($lineBox[$k]) ? $lineBox[$k] : false)); // mPDF 5.7.1
  5999.                     } else {
  6000.                         $this->Cell($stringWidth$stackHeight$chunk''1''$fill$this->HREF$currentx00'M'$filltrue, (isset($cOTLdata[$aord]) ? $cOTLdata[$aord] : false), $this->textvar, (isset($lineBox[$k]) ? $lineBox[$k] : false)); // mPDF 5.7.1
  6001.                     }
  6002.                 } else {
  6003.                     $this->Cell($stringWidth$stackHeight$chunk''0''$fill$this->HREF000'M'$filltrue, (isset($cOTLdata[$aord]) ? $cOTLdata[$aord] : false), $this->textvar, (isset($lineBox[$k]) ? $lineBox[$k] : false)); // first or middle part    // mPDF 5.7.1
  6004.                 }
  6005.                 if (!empty($this->spanborddet)) {
  6006.                     if (strpos($contentB[$k], 'R') !== false && $aord != $arraysize 1) {
  6007.                         $this->+= $this->spanborddet['R']['w'];
  6008.                     }
  6009.                 }
  6010.                 // *********** SPAN BACKGROUND COLOR OFF - RESET BLOCK BGCOLOR ***************** //
  6011.                 if (isset($spanfill) && $spanfill) {
  6012.                     $fill $save_fill;
  6013.                     $spanfill 0;
  6014.                     if ($fill) {
  6015.                         $this->SetFColor($bcor);
  6016.                     }
  6017.                 }
  6018.                 if (isset($this->textparam['visibility']) && $this->textparam['visibility'] && $this->visibility != $save_vis) {
  6019.                     $this->SetVisibility($save_vis);
  6020.                 }
  6021.             }
  6022.             $this->printobjectbuffer($is_table$blockdir);
  6023.             $this->objectbuffer = [];
  6024.             $this->ResetSpacing();
  6025.         } // END IF CONTENT
  6026.         /* -- CSS-IMAGE-FLOAT -- */
  6027.         // Update values if set to skipline
  6028.         if ($this->floatmargins) {
  6029.             $this->_advanceFloatMargins();
  6030.         }
  6031.         if ($endofblock && $blockstate 1) {
  6032.             // If float exists at this level
  6033.             if (isset($this->floatmargins['R']['y1'])) {
  6034.                 $fry1 $this->floatmargins['R']['y1'];
  6035.             } else {
  6036.                 $fry1 0;
  6037.             }
  6038.             if (isset($this->floatmargins['L']['y1'])) {
  6039.                 $fly1 $this->floatmargins['L']['y1'];
  6040.             } else {
  6041.                 $fly1 0;
  6042.             }
  6043.             if ($this->$fry1 || $this->$fly1) {
  6044.                 $drop max($fry1$fly1) - $this->y;
  6045.                 $this->DivLn($drop);
  6046.                 $this->$currentx;
  6047.             }
  6048.         }
  6049.         /* -- END CSS-IMAGE-FLOAT -- */
  6050.         // PADDING and BORDER spacing/fill
  6051.         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)) {
  6052.             // If CSS height set, extend bottom - if on same page as block started, and CSS HEIGHT > actual height,
  6053.             // and does not force pagebreak
  6054.             $extra 0;
  6055.             if (isset($this->blk[$this->blklvl]['css_set_height']) && $this->blk[$this->blklvl]['css_set_height'] && $this->blk[$this->blklvl]['startpage'] == $this->page) {
  6056.                 // predicted height
  6057.                 $h1 = ($this->$this->blk[$this->blklvl]['y0']) + $this->blk[$this->blklvl]['padding_bottom'] + $this->blk[$this->blklvl]['border_bottom']['w'];
  6058.                 if ($h1 < ($this->blk[$this->blklvl]['css_set_height'] + $this->blk[$this->blklvl]['padding_bottom'] + $this->blk[$this->blklvl]['padding_top'])) {
  6059.                     $extra = ($this->blk[$this->blklvl]['css_set_height'] + $this->blk[$this->blklvl]['padding_bottom'] + $this->blk[$this->blklvl]['padding_top']) - $h1;
  6060.                 }
  6061.                 if ($this->$this->blk[$this->blklvl]['padding_bottom'] + $this->blk[$this->blklvl]['border_bottom']['w'] + $extra $this->PageBreakTrigger) {
  6062.                     $extra $this->PageBreakTrigger - ($this->$this->blk[$this->blklvl]['padding_bottom'] + $this->blk[$this->blklvl]['border_bottom']['w']);
  6063.                 }
  6064.             }
  6065.             // $state = 0 normal; 1 top; 2 bottom; 3 top and bottom
  6066.             $this->DivLn($this->blk[$this->blklvl]['padding_bottom'] + $this->blk[$this->blklvl]['border_bottom']['w'] + $extra, -3truefalse2);
  6067.             $this->$currentx;
  6068.             if ($this->ColActive) {
  6069.                 $this->breakpoints[$this->CurrCol][] = $this->y;
  6070.             } // *COLUMNS*
  6071.         }
  6072.         // SET Bottom y1 of block (used for painting borders)
  6073.         if (($endofblock) && ($blockstate 1) && (!$is_table)) {
  6074.             $this->blk[$this->blklvl]['y1'] = $this->y;
  6075.         }
  6076.         // BOTTOM MARGIN
  6077.         if (($endofblock) && ($blockstate 1) && ($this->blk[$this->blklvl]['margin_bottom']) && (!$is_table)) {
  6078.             if ($this->$this->blk[$this->blklvl]['margin_bottom'] < $this->PageBreakTrigger and ! $this->InFooter) {
  6079.                 $this->DivLn($this->blk[$this->blklvl]['margin_bottom'], $this->blklvl 1true$this->blk[$this->blklvl]['margin_collapse']);
  6080.                 if ($this->ColActive) {
  6081.                     $this->breakpoints[$this->CurrCol][] = $this->y;
  6082.                 } // *COLUMNS*
  6083.             }
  6084.         }
  6085.         // Reset lineheight
  6086.         $stackHeight $this->divheight;
  6087.     }
  6088.     function printobjectbuffer($is_table false$blockdir false)
  6089.     {
  6090.         if (!$blockdir) {
  6091.             $blockdir $this->directionality;
  6092.         }
  6093.         if ($is_table && $this->shrin_k 1) {
  6094.             $k $this->shrin_k;
  6095.         } else {
  6096.             $k 1;
  6097.         }
  6098.         $save_y $this->y;
  6099.         $save_x $this->x;
  6100.         $save_currentfontfamily $this->FontFamily;
  6101.         $save_currentfontsize $this->FontSizePt;
  6102.         $save_currentfontstyle $this->FontStyle;
  6103.         if ($blockdir == 'rtl') {
  6104.             $rtlalign 'R';
  6105.         } else {
  6106.             $rtlalign 'L';
  6107.         }
  6108.         foreach ($this->objectbuffer as $ib => $objattr) {
  6109.             if ($objattr['type'] == 'bookmark' || $objattr['type'] == 'indexentry' || $objattr['type'] == 'toc') {
  6110.                 $x $objattr['OUTER-X'];
  6111.                 $y $objattr['OUTER-Y'];
  6112.                 $this->$y $this->FontSize 2;
  6113.                 $this->$x;
  6114.                 if ($objattr['type'] == 'bookmark') {
  6115.                     $this->Bookmark($objattr['CONTENT'], $objattr['bklevel'], $y $this->FontSize);
  6116.                 } // *BOOKMARKS*
  6117.                 if ($objattr['type'] == 'indexentry') {
  6118.                     $this->IndexEntry($objattr['CONTENT']);
  6119.                 } // *INDEX*
  6120.                 if ($objattr['type'] == 'toc') {
  6121.                     $this->TOC_Entry($objattr['CONTENT'], $objattr['toclevel'], (isset($objattr['toc_id']) ? $objattr['toc_id'] : ''));
  6122.                 } // *TOC*
  6123.             /* -- ANNOTATIONS -- */ elseif ($objattr['type'] == 'annot') {
  6124.                 if ($objattr['POS-X']) {
  6125.                     $x $objattr['POS-X'];
  6126.                 } elseif ($this->annotMargin <> 0) {
  6127.                     $x = -$objattr['OUTER-X'];
  6128.                 } else {
  6129.                     $x $objattr['OUTER-X'];
  6130.                 }
  6131.                 if ($objattr['POS-Y']) {
  6132.                     $y $objattr['POS-Y'];
  6133.                 } else {
  6134.                     $y $objattr['OUTER-Y'] - $this->FontSize 2;
  6135.                 }
  6136.                 // Create a dummy entry in the _out/columnBuffer with position sensitive data,
  6137.                 // linking $y-1 in the Columnbuffer with entry in $this->columnAnnots
  6138.                 // and when columns are split in length will not break annotation from current line
  6139.                 $this->$y 1;
  6140.                 $this->$x 1;
  6141.                 $this->Line($x 1$y 1$x 1$y 1);
  6142.                 $this->Annotation($objattr['CONTENT'], $x$y$objattr['ICON'], $objattr['AUTHOR'], $objattr['SUBJECT'], $objattr['OPACITY'], $objattr['COLOR'], (isset($objattr['POPUP']) ? $objattr['POPUP'] : ''), (isset($objattr['FILE']) ? $objattr['FILE'] : ''));
  6143.             } /* -- END ANNOTATIONS -- */ else {
  6144.                 $y $objattr['OUTER-Y'];
  6145.                 $x $objattr['OUTER-X'];
  6146.                 $w $objattr['OUTER-WIDTH'];
  6147.                 $h $objattr['OUTER-HEIGHT'];
  6148.                 if (isset($objattr['text'])) {
  6149.                     $texto $objattr['text'];
  6150.                 }
  6151.                 $this->$y;
  6152.                 $this->$x;
  6153.                 if (isset($objattr['fontfamily'])) {
  6154.                     $this->SetFont($objattr['fontfamily'], ''$objattr['fontsize']);
  6155.                 }
  6156.             }
  6157.             // HR
  6158.             if ($objattr['type'] == 'hr') {
  6159.                 $this->SetDColor($objattr['color']);
  6160.                 switch ($objattr['align']) {
  6161.                     case 'C':
  6162.                         $empty $objattr['OUTER-WIDTH'] - $objattr['INNER-WIDTH'];
  6163.                         $empty /= 2;
  6164.                         $x += $empty;
  6165.                         break;
  6166.                     case 'R':
  6167.                         $empty $objattr['OUTER-WIDTH'] - $objattr['INNER-WIDTH'];
  6168.                         $x += $empty;
  6169.                         break;
  6170.                 }
  6171.                 $oldlinewidth $this->LineWidth;
  6172.                 $this->SetLineWidth($objattr['linewidth'] / $k);
  6173.                 $this->+= ($objattr['linewidth'] / 2) + $objattr['margin_top'] / $k;
  6174.                 $this->Line($x$this->y$x $objattr['INNER-WIDTH'], $this->y);
  6175.                 $this->SetLineWidth($oldlinewidth);
  6176.                 $this->SetDColor($this->colorConverter->convert(0$this->PDFAXwarnings));
  6177.             }
  6178.             // IMAGE
  6179.             if ($objattr['type'] == 'image') {
  6180.                 // mPDF 5.7.3 TRANSFORMS
  6181.                 if (isset($objattr['transform'])) {
  6182.                     $this->writer->write("\n" '% BTR'); // Begin Transform
  6183.                 }
  6184.                 if (isset($objattr['z-index']) && $objattr['z-index'] > && $this->current_layer == 0) {
  6185.                     $this->BeginLayer($objattr['z-index']);
  6186.                 }
  6187.                 if (isset($objattr['visibility']) && $objattr['visibility'] != 'visible' && $objattr['visibility']) {
  6188.                     $this->SetVisibility($objattr['visibility']);
  6189.                 }
  6190.                 if (isset($objattr['opacity'])) {
  6191.                     $this->SetAlpha($objattr['opacity']);
  6192.                 }
  6193.                 $obiw $objattr['INNER-WIDTH'];
  6194.                 $obih $objattr['INNER-HEIGHT'];
  6195.                 $sx $objattr['orig_w'] ? ($objattr['INNER-WIDTH'] * Mpdf::SCALE $objattr['orig_w']) : INF;
  6196.                 $sy $objattr['orig_h'] ? ($objattr['INNER-HEIGHT'] * Mpdf::SCALE $objattr['orig_h']) : INF;
  6197.                 $rotate 0;
  6198.                 if (isset($objattr['ROTATE'])) {
  6199.                     $rotate $objattr['ROTATE'];
  6200.                 }
  6201.                 if ($rotate == 90) {
  6202.                     // Clockwise
  6203.                     $obiw $objattr['INNER-HEIGHT'];
  6204.                     $obih $objattr['INNER-WIDTH'];
  6205.                     $tr $this->transformTranslate(0, -$objattr['INNER-WIDTH'], true);
  6206.                     $tr .= ' ' $this->transformRotate(90$objattr['INNER-X'], ($objattr['INNER-Y'] + $objattr['INNER-WIDTH']), true);
  6207.                     $sx $obiw Mpdf::SCALE $objattr['orig_h'];
  6208.                     $sy $obih Mpdf::SCALE $objattr['orig_w'];
  6209.                 } elseif ($rotate == -90 || $rotate == 270) {
  6210.                     // AntiClockwise
  6211.                     $obiw $objattr['INNER-HEIGHT'];
  6212.                     $obih $objattr['INNER-WIDTH'];
  6213.                     $tr $this->transformTranslate($objattr['INNER-WIDTH'], ($objattr['INNER-HEIGHT'] - $objattr['INNER-WIDTH']), true);
  6214.                     $tr .= ' ' $this->transformRotate(-90$objattr['INNER-X'], ($objattr['INNER-Y'] + $objattr['INNER-WIDTH']), true);
  6215.                     $sx $obiw Mpdf::SCALE $objattr['orig_h'];
  6216.                     $sy $obih Mpdf::SCALE $objattr['orig_w'];
  6217.                 } elseif ($rotate == 180) {
  6218.                     // Mirror
  6219.                     $tr $this->transformTranslate($objattr['INNER-WIDTH'], -$objattr['INNER-HEIGHT'], true);
  6220.                     $tr .= ' ' $this->transformRotate(180$objattr['INNER-X'], ($objattr['INNER-Y'] + $objattr['INNER-HEIGHT']), true);
  6221.                 } else {
  6222.                     $tr '';
  6223.                 }
  6224.                 $tr trim($tr);
  6225.                 if ($tr) {
  6226.                     $tr .= ' ';
  6227.                 }
  6228.                 $gradmask '';
  6229.                 // mPDF 5.7.3 TRANSFORMS
  6230.                 $tr2 '';
  6231.                 if (isset($objattr['transform'])) {
  6232.                     $maxsize_x $w;
  6233.                     $maxsize_y $h;
  6234.                     $cx $x $w 2;
  6235.                     $cy $y $h 2;
  6236.                     preg_match_all('/(translatex|translatey|translate|scalex|scaley|scale|rotate|skewX|skewY|skew)\((.*?)\)/is'$objattr['transform'], $m);
  6237.                     if (count($m[0])) {
  6238.                         for ($i 0$i count($m[0]); $i++) {
  6239.                             $c strtolower($m[1][$i]);
  6240.                             $v trim($m[2][$i]);
  6241.                             $vv preg_split('/[ ,]+/'$v);
  6242.                             if ($c == 'translate' && count($vv)) {
  6243.                                 $translate_x $this->sizeConverter->convert($vv[0], $maxsize_xfalsefalse);
  6244.                                 if (count($vv) == 2) {
  6245.                                     $translate_y $this->sizeConverter->convert($vv[1], $maxsize_yfalsefalse);
  6246.                                 } else {
  6247.                                     $translate_y 0;
  6248.                                 }
  6249.                                 $tr2 .= $this->transformTranslate($translate_x$translate_ytrue) . ' ';
  6250.                             } elseif ($c == 'translatex' && count($vv)) {
  6251.                                 $translate_x $this->sizeConverter->convert($vv[0], $maxsize_xfalsefalse);
  6252.                                 $tr2 .= $this->transformTranslate($translate_x0true) . ' ';
  6253.                             } elseif ($c == 'translatey' && count($vv)) {
  6254.                                 $translate_y $this->sizeConverter->convert($vv[0], $maxsize_yfalsefalse);
  6255.                                 $tr2 .= $this->transformTranslate(0$translate_ytrue) . ' ';
  6256.                             } elseif ($c == 'scale' && count($vv)) {
  6257.                                 $scale_x $vv[0] * 100;
  6258.                                 if (count($vv) == 2) {
  6259.                                     $scale_y $vv[1] * 100;
  6260.                                 } else {
  6261.                                     $scale_y $scale_x;
  6262.                                 }
  6263.                                 $tr2 .= $this->transformScale($scale_x$scale_y$cx$cytrue) . ' ';
  6264.                             } elseif ($c == 'scalex' && count($vv)) {
  6265.                                 $scale_x $vv[0] * 100;
  6266.                                 $tr2 .= $this->transformScale($scale_x0$cx$cytrue) . ' ';
  6267.                             } elseif ($c == 'scaley' && count($vv)) {
  6268.                                 $scale_y $vv[0] * 100;
  6269.                                 $tr2 .= $this->transformScale(0$scale_y$cx$cytrue) . ' ';
  6270.                             } elseif ($c == 'skew' && count($vv)) {
  6271.                                 $angle_x $this->ConvertAngle($vv[0], false);
  6272.                                 if (count($vv) == 2) {
  6273.                                     $angle_y $this->ConvertAngle($vv[1], false);
  6274.                                 } else {
  6275.                                     $angle_y 0;
  6276.                                 }
  6277.                                 $tr2 .= $this->transformSkew($angle_x$angle_y$cx$cytrue) . ' ';
  6278.                             } elseif ($c == 'skewx' && count($vv)) {
  6279.                                 $angle $this->ConvertAngle($vv[0], false);
  6280.                                 $tr2 .= $this->transformSkew($angle0$cx$cytrue) . ' ';
  6281.                             } elseif ($c == 'skewy' && count($vv)) {
  6282.                                 $angle $this->ConvertAngle($vv[0], false);
  6283.                                 $tr2 .= $this->transformSkew(0$angle$cx$cytrue) . ' ';
  6284.                             } elseif ($c == 'rotate' && count($vv)) {
  6285.                                 $angle $this->ConvertAngle($vv[0]);
  6286.                                 $tr2 .= $this->transformRotate($angle$cx$cytrue) . ' ';
  6287.                             }
  6288.                         }
  6289.                     }
  6290.                 }
  6291.                 // LIST MARKERS (Images)    // mPDF 6  Lists
  6292.                 if (isset($objattr['listmarker']) && $objattr['listmarker'] && $objattr['listmarkerposition'] == 'outside') {
  6293.                     $mw $objattr['OUTER-WIDTH'];
  6294.                     // NB If change marker-offset, also need to alter in function _getListMarkerWidth
  6295.                     $adjx $this->sizeConverter->convert($this->list_marker_offset$this->FontSize);
  6296.                     if ($objattr['dir'] == 'rtl') {
  6297.                         $objattr['INNER-X'] += $adjx;
  6298.                     } else {
  6299.                         $objattr['INNER-X'] -= $adjx;
  6300.                         $objattr['INNER-X'] -= $mw;
  6301.                     }
  6302.                 }
  6303.                 // mPDF 5.7.3 TRANSFORMS / BACKGROUND COLOR
  6304.                 // Transform also affects image background
  6305.                 if ($tr2) {
  6306.                     $this->writer->write('q ' $tr2 ' ');
  6307.                 }
  6308.                 if (isset($objattr['bgcolor']) && $objattr['bgcolor']) {
  6309.                     $bgcol $objattr['bgcolor'];
  6310.                     $this->SetFColor($bgcol);
  6311.                     $this->Rect($x$y$w$h'F');
  6312.                     $this->SetFColor($this->colorConverter->convert(255$this->PDFAXwarnings));
  6313.                 }
  6314.                 if ($tr2) {
  6315.                     $this->writer->write('Q');
  6316.                 }
  6317.                 /* -- BACKGROUNDS -- */
  6318.                 if (isset($objattr['GRADIENT-MASK'])) {
  6319.                     $g $this->gradient->parseMozGradient($objattr['GRADIENT-MASK']);
  6320.                     if ($g) {
  6321.                         $dummy $this->gradient->Gradient($objattr['INNER-X'], $objattr['INNER-Y'], $obiw$obih$g['type'], $g['stops'], $g['colorspace'], $g['coords'], $g['extend'], truetrue);
  6322.                         $gradmask '/TGS' count($this->gradients) . ' gs ';
  6323.                     }
  6324.                 }
  6325.                 /* -- END BACKGROUNDS -- */
  6326.                 /* -- IMAGES-WMF -- */
  6327.                 if (isset($objattr['itype']) && $objattr['itype'] == 'wmf') {
  6328.                     $outstring sprintf('q ' $tr $tr2 '%.3F 0 0 %.3F %.3F %.3F cm /FO%d Do Q'$sx, -$sy$objattr['INNER-X'] * Mpdf::SCALE $sx $objattr['wmf_x'], (($this->$objattr['INNER-Y']) * Mpdf::SCALE) + $sy $objattr['wmf_y'], $objattr['ID']); // mPDF 5.7.3 TRANSFORMS
  6329.                 } else {                 /* -- END IMAGES-WMF -- */
  6330.                     if (isset($objattr['itype']) && $objattr['itype'] == 'svg') {
  6331.                         $outstring sprintf('q ' $tr $tr2 '%.3F 0 0 %.3F %.3F %.3F cm /FO%d Do Q'$sx, -$sy$objattr['INNER-X'] * Mpdf::SCALE $sx $objattr['wmf_x'], (($this->$objattr['INNER-Y']) * Mpdf::SCALE) + $sy $objattr['wmf_y'], $objattr['ID']); // mPDF 5.7.3 TRANSFORMS
  6332.                     } else {
  6333.                         $outstring sprintf("q " $tr $tr2 "%.3F 0 0 %.3F %.3F %.3F cm " $gradmask "/I%d Do Q"$obiw Mpdf::SCALE$obih Mpdf::SCALE$objattr['INNER-X'] * Mpdf::SCALE, ($this->- ($objattr['INNER-Y'] + $obih )) * Mpdf::SCALE$objattr['ID']); // mPDF 5.7.3 TRANSFORMS
  6334.                     }
  6335.                 }
  6336.                 $this->writer->write($outstring);
  6337.                 // LINK
  6338.                 if (isset($objattr['link'])) {
  6339.                     $this->Link($objattr['INNER-X'], $objattr['INNER-Y'], $objattr['INNER-WIDTH'], $objattr['INNER-HEIGHT'], $objattr['link']);
  6340.                 }
  6341.                 if (isset($objattr['opacity'])) {
  6342.                     $this->SetAlpha(1);
  6343.                 }
  6344.                 // mPDF 5.7.3 TRANSFORMS
  6345.                 // Transform also affects image borders
  6346.                 if ($tr2) {
  6347.                     $this->writer->write('q ' $tr2 ' ');
  6348.                 }
  6349.                 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)) {
  6350.                     $this->PaintImgBorder($objattr$is_table);
  6351.                 }
  6352.                 if ($tr2) {
  6353.                     $this->writer->write('Q');
  6354.                 }
  6355.                 if (isset($objattr['visibility']) && $objattr['visibility'] != 'visible' && $objattr['visibility']) {
  6356.                     $this->SetVisibility('visible');
  6357.                 }
  6358.                 if (isset($objattr['z-index']) && $objattr['z-index'] > && $this->current_layer == 0) {
  6359.                     $this->EndLayer();
  6360.                 }
  6361.                 // mPDF 5.7.3 TRANSFORMS
  6362.                 if (isset($objattr['transform'])) {
  6363.                     $this->writer->write("\n" '% ETR'); // End Transform
  6364.                 }
  6365.             }
  6366.             if ($objattr['type'] === 'barcode') {
  6367.                 $bgcol $this->colorConverter->convert(255$this->PDFAXwarnings);
  6368.                 if (isset($objattr['bgcolor']) && $objattr['bgcolor']) {
  6369.                     $bgcol $objattr['bgcolor'];
  6370.                 }
  6371.                 $col $this->colorConverter->convert(0$this->PDFAXwarnings);
  6372.                 if (isset($objattr['color']) && $objattr['color']) {
  6373.                     $col $objattr['color'];
  6374.                 }
  6375.                 $this->SetFColor($bgcol);
  6376.                 $this->Rect($objattr['BORDER-X'], $objattr['BORDER-Y'], $objattr['BORDER-WIDTH'], $objattr['BORDER-HEIGHT'], 'F');
  6377.                 $this->SetFColor($this->colorConverter->convert(255$this->PDFAXwarnings));
  6378.                 if (isset($objattr['BORDER-WIDTH'])) {
  6379.                     $this->PaintImgBorder($objattr$is_table);
  6380.                 }
  6381.                 $barcodeTypes = ['EAN13''ISBN''ISSN''UPCA''UPCE''EAN8'];
  6382.                 if (in_array($objattr['btype'], $barcodeTypestrue)) {
  6383.                     $this->WriteBarcode(
  6384.                         $objattr['code'],
  6385.                         $objattr['showtext'],
  6386.                         $objattr['INNER-X'],
  6387.                         $objattr['INNER-Y'],
  6388.                         $objattr['bsize'],
  6389.                         0,
  6390.                         0,
  6391.                         0,
  6392.                         0,
  6393.                         0,
  6394.                         $objattr['bheight'],
  6395.                         $bgcol,
  6396.                         $col,
  6397.                         $objattr['btype'],
  6398.                         $objattr['bsupp'],
  6399.                         (isset($objattr['bsupp_code']) ? $objattr['bsupp_code'] : ''),
  6400.                         $k
  6401.                     );
  6402.                 } elseif ($objattr['btype'] === 'QR') {
  6403.                     if (!class_exists('Mpdf\QrCode\QrCode') || !class_exists('Mpdf\QrCode\Output\Mpdf')) {
  6404.                         throw new \Mpdf\MpdfException('Mpdf\QrCode package was not found. Install the package from Packagist with "composer require mpdf/qrcode"');
  6405.                     }
  6406.                     $barcodeContent str_replace('\r\n'"\r\n"$objattr['code']);
  6407.                     $barcodeContent str_replace('\n'"\n"$barcodeContent);
  6408.                     $qrcode = new QrCode\QrCode($barcodeContent$objattr['errorlevel']);
  6409.                     if ($objattr['disableborder']) {
  6410.                         $qrcode->disableBorder();
  6411.                     }
  6412.                     $bgColor = [255255255];
  6413.                     if ($objattr['bgcolor']) {
  6414.                         $bgColor array_map(
  6415.                             function ($col) {
  6416.                                 return intval(255 floatval($col));
  6417.                             },
  6418.                             explode(" "$this->SetColor($objattr['bgcolor'], 'CodeOnly'))
  6419.                         );
  6420.                     }
  6421.                     $color = [000];
  6422.                     if ($objattr['color']) {
  6423.                         $color array_map(
  6424.                             function ($col) {
  6425.                                 return intval(255 floatval($col));
  6426.                             },
  6427.                             explode(" "$this->SetColor($objattr['color'], 'CodeOnly'))
  6428.                         );
  6429.                     }
  6430.                     $out = new QrCode\Output\Mpdf();
  6431.                     $out->output(
  6432.                         $qrcode,
  6433.                         $this,
  6434.                         $objattr['INNER-X'],
  6435.                         $objattr['INNER-Y'],
  6436.                         $objattr['bsize'] * 25,
  6437.                         $bgColor,
  6438.                         $color
  6439.                     );
  6440.                     unset($qrcode);
  6441.                 } else {
  6442.                     $this->WriteBarcode2(
  6443.                         $objattr['code'],
  6444.                         $objattr['INNER-X'],
  6445.                         $objattr['INNER-Y'],
  6446.                         $objattr['bsize'],
  6447.                         $objattr['bheight'],
  6448.                         $bgcol,
  6449.                         $col,
  6450.                         $objattr['btype'],
  6451.                         $objattr['pr_ratio'],
  6452.                         $k,
  6453.                         $objattr['quiet_zone_left'],
  6454.                         $objattr['quiet_zone_right']
  6455.                     );
  6456.                 }
  6457.             }
  6458.             // TEXT CIRCLE
  6459.             if ($objattr['type'] == 'textcircle') {
  6460.                 $bgcol '';
  6461.                 if (isset($objattr['bgcolor']) && $objattr['bgcolor']) {
  6462.                     $bgcol $objattr['bgcolor'];
  6463.                 }
  6464.                 $col $this->colorConverter->convert(0$this->PDFAXwarnings);
  6465.                 if (isset($objattr['color']) && $objattr['color']) {
  6466.                     $col $objattr['color'];
  6467.                 }
  6468.                 $this->SetTColor($col);
  6469.                 $this->SetFColor($bgcol);
  6470.                 if ($bgcol) {
  6471.                     $this->Rect($objattr['BORDER-X'], $objattr['BORDER-Y'], $objattr['BORDER-WIDTH'], $objattr['BORDER-HEIGHT'], 'F');
  6472.                 }
  6473.                 $this->SetFColor($this->colorConverter->convert(255$this->PDFAXwarnings));
  6474.                 if (isset($objattr['BORDER-WIDTH'])) {
  6475.                     $this->PaintImgBorder($objattr$is_table);
  6476.                 }
  6477.                 if (empty($this->directWrite)) {
  6478.                     $this->directWrite = new DirectWrite($this$this->otl$this->sizeConverter$this->colorConverter);
  6479.                 }
  6480.                 if (isset($objattr['top-text'])) {
  6481.                     $this->directWrite->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'], (isset($objattr['divider']) ? $objattr['divider'] : ''));
  6482.                 }
  6483.                 if (isset($objattr['bottom-text'])) {
  6484.                     $this->directWrite->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'], (isset($objattr['divider']) ? $objattr['divider'] : ''));
  6485.                 }
  6486.             }
  6487.             $this->ResetSpacing();
  6488.             // LIST MARKERS (Text or bullets)    // mPDF 6  Lists
  6489.             if ($objattr['type'] == 'listmarker') {
  6490.                 if (isset($objattr['fontfamily'])) {
  6491.                     $this->SetFont($objattr['fontfamily'], $objattr['fontstyle'], $objattr['fontsizept']);
  6492.                 }
  6493.                 $col $this->colorConverter->convert(0$this->PDFAXwarnings);
  6494.                 if (isset($objattr['colorarray']) && ($objattr['colorarray'])) {
  6495.                     $col $objattr['colorarray'];
  6496.                 }
  6497.                 if (isset($objattr['bullet']) && $objattr['bullet']) { // Used for position "outside" only
  6498.                     $type $objattr['bullet'];
  6499.                     $size $objattr['size'];
  6500.                     if ($objattr['listmarkerposition'] == 'inside') {
  6501.                         $adjx $size 2;
  6502.                         if ($objattr['dir'] == 'rtl') {
  6503.                             $adjx += $objattr['offset'];
  6504.                         }
  6505.                         $this->+= $adjx;
  6506.                     } else {
  6507.                         $adjx $objattr['offset'];
  6508.                         $adjx += $size 2;
  6509.                         if ($objattr['dir'] == 'rtl') {
  6510.                             $this->+= $adjx;
  6511.                         } else {
  6512.                             $this->-= $adjx;
  6513.                         }
  6514.                     }
  6515.                     $yadj $objattr['lineBox']['glyphYorigin'];
  6516.                     if (isset($this->CurrentFont['desc']['XHeight']) && $this->CurrentFont['desc']['XHeight']) {
  6517.                         $xh $this->CurrentFont['desc']['XHeight'];
  6518.                     } else {
  6519.                         $xh 500;
  6520.                     }
  6521.                     $yadj -= ($this->FontSize $xh 1000) * 0.625// Vertical height of bullet (centre) from baseline= XHeight * 0.625
  6522.                     $this->+= $yadj;
  6523.                     $this->_printListBullet($this->x$this->y$size$type$col);
  6524.                 } else {
  6525.                     $this->SetTColor($col);
  6526.                     $w $this->GetStringWidth($texto);
  6527.                     // NB If change marker-offset, also need to alter in function _getListMarkerWidth
  6528.                     $adjx $this->sizeConverter->convert($this->list_marker_offset$this->FontSize);
  6529.                     if ($objattr['dir'] == 'rtl') {
  6530.                         $align 'L';
  6531.                         $this->+= $adjx;
  6532.                     } else {
  6533.                         // Use these lines to set as marker-offset, right-aligned - default
  6534.                         $align 'R';
  6535.                         $this->-= $adjx;
  6536.                         $this->-= $w;
  6537.                     }
  6538.                     $this->Cell($w$this->FontSize$texto00$align0''000'T'0falsefalse0$objattr['lineBox']);
  6539.                     $this->SetTColor($this->colorConverter->convert(0$this->PDFAXwarnings));
  6540.                 }
  6541.             }
  6542.             // DOT-TAB
  6543.             if ($objattr['type'] == 'dottab') {
  6544.                 if (isset($objattr['fontfamily'])) {
  6545.                     $this->SetFont($objattr['fontfamily'], ''$objattr['fontsize']);
  6546.                 }
  6547.                 $sp $this->GetStringWidth(' ');
  6548.                 $nb floor(($w $sp) / $this->GetStringWidth('.'));
  6549.                 if ($nb 0) {
  6550.                     $dots ' ' str_repeat('.'$nb) . ' ';
  6551.                 } else {
  6552.                     $dots ' ';
  6553.                 }
  6554.                 $col $this->colorConverter->convert(0$this->PDFAXwarnings);
  6555.                 if (isset($objattr['colorarray']) && ($objattr['colorarray'])) {
  6556.                     $col $objattr['colorarray'];
  6557.                 }
  6558.                 $this->SetTColor($col);
  6559.                 $save_dh $this->divheight;
  6560.                 $save_sbd $this->spanborddet;
  6561.                 $save_textvar $this->textvar// mPDF 5.7.1
  6562.                 $this->spanborddet '';
  6563.                 $this->divheight 0;
  6564.                 $this->textvar 0x00// mPDF 5.7.1
  6565.                 $this->Cell($w$h$dots00'C'0''000'T'0falsefalse0$objattr['lineBox']); // mPDF 6 DOTTAB
  6566.                 $this->spanborddet $save_sbd;
  6567.                 $this->textvar $save_textvar// mPDF 5.7.1
  6568.                 $this->divheight $save_dh;
  6569.                 $this->SetTColor($this->colorConverter->convert(0$this->PDFAXwarnings));
  6570.             }
  6571.             /* -- FORMS -- */
  6572.             // TEXT/PASSWORD INPUT
  6573.             if ($objattr['type'] == 'input' && ($objattr['subtype'] == 'TEXT' || $objattr['subtype'] == 'PASSWORD')) {
  6574.                 $this->form->print_ob_text($objattr$w$h$texto$rtlalign$k$blockdir);
  6575.             }
  6576.             // TEXTAREA
  6577.             if ($objattr['type'] == 'textarea') {
  6578.                 $this->form->print_ob_textarea($objattr$w$h$texto$rtlalign$k$blockdir);
  6579.             }
  6580.             // SELECT
  6581.             if ($objattr['type'] == 'select') {
  6582.                 $this->form->print_ob_select($objattr$w$h$texto$rtlalign$k$blockdir);
  6583.             }
  6584.             // INPUT/BUTTON as IMAGE
  6585.             if ($objattr['type'] == 'input' && $objattr['subtype'] == 'IMAGE') {
  6586.                 $this->form->print_ob_imageinput($objattr$w$h$texto$rtlalign$k$blockdir$is_table);
  6587.             }
  6588.             // BUTTON
  6589.             if ($objattr['type'] == 'input' && ($objattr['subtype'] == 'SUBMIT' || $objattr['subtype'] == 'RESET' || $objattr['subtype'] == 'BUTTON')) {
  6590.                 $this->form->print_ob_button($objattr$w$h$texto$rtlalign$k$blockdir);
  6591.             }
  6592.             // CHECKBOX
  6593.             if ($objattr['type'] == 'input' && ($objattr['subtype'] == 'CHECKBOX')) {
  6594.                 $this->form->print_ob_checkbox($objattr$w$h$texto$rtlalign$k$blockdir$x$y);
  6595.             }
  6596.             // RADIO
  6597.             if ($objattr['type'] == 'input' && ($objattr['subtype'] == 'RADIO')) {
  6598.                 $this->form->print_ob_radio($objattr$w$h$texto$rtlalign$k$blockdir$x$y);
  6599.             }
  6600.             /* -- END FORMS -- */
  6601.         }
  6602.         $this->SetFont($save_currentfontfamily$save_currentfontstyle$save_currentfontsize);
  6603.         $this->$save_y;
  6604.         $this->$save_x;
  6605.         unset($content);
  6606.     }
  6607.     function _printListBullet($x$y$size$type$color)
  6608.     {
  6609.         // x and y are the centre of the bullet; size is the width and/or height in mm
  6610.         $fcol $this->SetTColor($colortrue);
  6611.         $lcol strtoupper($fcol); // change 0 0 0 rg to 0 0 0 RG
  6612.         $this->writer->write(sprintf('q %s %s'$lcol$fcol));
  6613.         $this->writer->write('0 j 0 J [] 0 d');
  6614.         if ($type == 'square') {
  6615.             $size *= 0.85// Smaller to appear the same size as circle/disc
  6616.             $this->writer->write(sprintf('%.3F %.3F %.3F %.3F re f', ($x $size 2) * Mpdf::SCALE, ($this->$y $size 2) * Mpdf::SCALE, ($size) * Mpdf::SCALE, (-$size) * Mpdf::SCALE));
  6617.         } elseif ($type == 'disc') {
  6618.             $this->Circle($x$y$size 2'F'); // Fill
  6619.         } elseif ($type == 'circle') {
  6620.             $lw $size 12// Line width
  6621.             $this->writer->write(sprintf('%.3F w '$lw Mpdf::SCALE));
  6622.             $this->Circle($x$y$size $lw 2'S'); // Stroke
  6623.         }
  6624.         $this->writer->write('Q');
  6625.     }
  6626.     // mPDF 6
  6627.     // Get previous character and move pointers
  6628.     function _moveToPrevChar(&$contentctr, &$charctr$content)
  6629.     {
  6630.         $lastchar false;
  6631.         $charctr--;
  6632.         while ($charctr 0) { // go back to previous $content[]
  6633.             $contentctr--;
  6634.             if ($contentctr 0) {
  6635.                 return false;
  6636.             }
  6637.             if ($this->usingCoreFont) {
  6638.                 $charctr strlen($content[$contentctr]) - 1;
  6639.             } else {
  6640.                 $charctr mb_strlen($content[$contentctr], $this->mb_enc) - 1;
  6641.             }
  6642.         }
  6643.         if ($this->usingCoreFont) {
  6644.             $lastchar $content[$contentctr][$charctr];
  6645.         } else {
  6646.             $lastchar mb_substr($content[$contentctr], $charctr1$this->mb_enc);
  6647.         }
  6648.         return $lastchar;
  6649.     }
  6650.     // Get previous character
  6651.     function _getPrevChar($contentctr$charctr$content)
  6652.     {
  6653.         $lastchar false;
  6654.         $charctr--;
  6655.         while ($charctr 0) { // go back to previous $content[]
  6656.             $contentctr--;
  6657.             if ($contentctr 0) {
  6658.                 return false;
  6659.             }
  6660.             if ($this->usingCoreFont) {
  6661.                 $charctr strlen($content[$contentctr]) - 1;
  6662.             } else {
  6663.                 $charctr mb_strlen($content[$contentctr], $this->mb_enc) - 1;
  6664.             }
  6665.         }
  6666.         if ($this->usingCoreFont) {
  6667.             $lastchar $content[$contentctr][$charctr];
  6668.         } else {
  6669.             $lastchar mb_substr($content[$contentctr], $charctr1$this->mb_enc);
  6670.         }
  6671.         return $lastchar;
  6672.     }
  6673.     function WriteFlowingBlock($s$sOTLdata)
  6674.     {
  6675.     // mPDF 5.7.1
  6676.         $currentx $this->x;
  6677.         $is_table $this->flowingBlockAttr['is_table'];
  6678.         $table_draft $this->flowingBlockAttr['table_draft'];
  6679.         // width of all the content so far in points
  6680.         $contentWidth = & $this->flowingBlockAttr['contentWidth'];
  6681.         // cell width in points
  6682.         $maxWidth = & $this->flowingBlockAttr['width'];
  6683.         $lineCount = & $this->flowingBlockAttr['lineCount'];
  6684.         // line height in user units
  6685.         $stackHeight = & $this->flowingBlockAttr['height'];
  6686.         $align = & $this->flowingBlockAttr['align'];
  6687.         $content = & $this->flowingBlockAttr['content'];
  6688.         $contentB = & $this->flowingBlockAttr['contentB'];
  6689.         $font = & $this->flowingBlockAttr['font'];
  6690.         $valign = & $this->flowingBlockAttr['valign'];
  6691.         $blockstate $this->flowingBlockAttr['blockstate'];
  6692.         $cOTLdata = & $this->flowingBlockAttr['cOTLdata']; // mPDF 5.7.1
  6693.         $newblock $this->flowingBlockAttr['newblock'];
  6694.         $blockdir $this->flowingBlockAttr['blockdir'];
  6695.         // *********** BLOCK BACKGROUND COLOR ***************** //
  6696.         if ($this->blk[$this->blklvl]['bgcolor'] && !$is_table) {
  6697.             $fill 0;
  6698.         } else {
  6699.             $this->SetFColor($this->colorConverter->convert(255$this->PDFAXwarnings));
  6700.             $fill 0;
  6701.         }
  6702.         $font[] = $this->saveFont();
  6703.         $content[] = '';
  6704.         $contentB[] = '';
  6705.         $cOTLdata[] = $sOTLdata// mPDF 5.7.1
  6706.         $currContent = & $content[count($content) - 1];
  6707.         $CJKoverflow false;
  6708.         $Oikomi false// mPDF 6
  6709.         $hanger '';
  6710.         // COLS
  6711.         $oldcolumn $this->CurrCol;
  6712.         if ($this->ColActive && !$is_table) {
  6713.             $this->breakpoints[$this->CurrCol][] = $this->y;
  6714.         } // *COLUMNS*
  6715.         /* -- TABLES -- */
  6716.         if ($is_table) {
  6717.             $ipaddingL 0;
  6718.             $ipaddingR 0;
  6719.             $paddingL 0;
  6720.             $paddingR 0;
  6721.             $cpaddingadjustL 0;
  6722.             $cpaddingadjustR 0;
  6723.             // Added mPDF 3.0
  6724.             $fpaddingR 0;
  6725.             $fpaddingL 0;
  6726.         } else {
  6727.             /* -- END TABLES -- */
  6728.             $ipaddingL $this->blk[$this->blklvl]['padding_left'];
  6729.             $ipaddingR $this->blk[$this->blklvl]['padding_right'];
  6730.             $paddingL = ($ipaddingL Mpdf::SCALE);
  6731.             $paddingR = ($ipaddingR Mpdf::SCALE);
  6732.             $this->cMarginL $this->blk[$this->blklvl]['border_left']['w'];
  6733.             $cpaddingadjustL = -$this->cMarginL;
  6734.             $this->cMarginR $this->blk[$this->blklvl]['border_right']['w'];
  6735.             $cpaddingadjustR = -$this->cMarginR;
  6736.             // Added mPDF 3.0 Float DIV
  6737.             $fpaddingR 0;
  6738.             $fpaddingL 0;
  6739.             /* -- CSS-FLOAT -- */
  6740.             if (count($this->floatDivs)) {
  6741.                 list($l_exists$r_exists$l_max$r_max$l_width$r_width) = $this->GetFloatDivInfo($this->blklvl);
  6742.                 if ($r_exists) {
  6743.                     $fpaddingR $r_width;
  6744.                 }
  6745.                 if ($l_exists) {
  6746.                     $fpaddingL $l_width;
  6747.                 }
  6748.             }
  6749.             /* -- END CSS-FLOAT -- */
  6750.             $usey $this->0.002;
  6751.             if (($newblock) && ($blockstate == || $blockstate == 3) && ($lineCount == 0)) {
  6752.                 $usey += $this->blk[$this->blklvl]['margin_top'] + $this->blk[$this->blklvl]['padding_top'] + $this->blk[$this->blklvl]['border_top']['w'];
  6753.             }
  6754.             /* -- CSS-IMAGE-FLOAT -- */
  6755.             // If float exists at this level
  6756.             if (isset($this->floatmargins['R']) && $usey <= $this->floatmargins['R']['y1'] && $usey >= $this->floatmargins['R']['y0'] && !$this->floatmargins['R']['skipline']) {
  6757.                 $fpaddingR += $this->floatmargins['R']['w'];
  6758.             }
  6759.             if (isset($this->floatmargins['L']) && $usey <= $this->floatmargins['L']['y1'] && $usey >= $this->floatmargins['L']['y0'] && !$this->floatmargins['L']['skipline']) {
  6760.                 $fpaddingL += $this->floatmargins['L']['w'];
  6761.             }
  6762.             /* -- END CSS-IMAGE-FLOAT -- */
  6763.         // *TABLES*
  6764.         // OBJECTS - IMAGES & FORM Elements (NB has already skipped line/page if required - in printbuffer)
  6765.         if (substr($s03) == Mpdf::OBJECT_IDENTIFIER) { // identifier has been identified!
  6766.             $objattr $this->_getObjAttr($s);
  6767.             $h_corr 0;
  6768.             if ($is_table) { // *TABLES*
  6769.                 $maximumW = ($maxWidth Mpdf::SCALE) - ($this->cellPaddingL $this->cMarginL $this->cellPaddingR $this->cMarginR);  // *TABLES*
  6770.             // *TABLES*
  6771.             else { // *TABLES*
  6772.                 if (($newblock) && ($blockstate == || $blockstate == 3) && ($lineCount == 0) && (!$is_table)) {
  6773.                     $h_corr $this->blk[$this->blklvl]['padding_top'] + $this->blk[$this->blklvl]['border_top']['w'];
  6774.                 }
  6775.                 $maximumW = ($maxWidth Mpdf::SCALE) - ($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 );
  6776.             } // *TABLES*
  6777.             $objattr $this->inlineObject($objattr['type'], $this->lMargin $fpaddingL + ($contentWidth Mpdf::SCALE), ($this->$h_corr), $objattr$this->lMargin, ($contentWidth Mpdf::SCALE), $maximumW$stackHeighttrue$is_table);
  6778.             // SET LINEHEIGHT for this line ================ RESET AT END
  6779.             $stackHeight max($stackHeight$objattr['OUTER-HEIGHT']);
  6780.             $this->objectbuffer[count($content) - 1] = $objattr;
  6781.             // if (isset($objattr['vertical-align'])) { $valign = $objattr['vertical-align']; }
  6782.             // else { $valign = ''; }
  6783.             // LIST MARKERS    // mPDF 6  Lists
  6784.             if ($objattr['type'] == 'image' && isset($objattr['listmarker']) && $objattr['listmarker'] && $objattr['listmarkerposition'] == 'outside') {
  6785.                 // do nothing
  6786.             } else {
  6787.                 $contentWidth += ($objattr['OUTER-WIDTH'] * Mpdf::SCALE);
  6788.             }
  6789.             return;
  6790.         }
  6791.         $lbw $rbw 0// Border widths
  6792.         if (!empty($this->spanborddet)) {
  6793.             if (isset($this->spanborddet['L'])) {
  6794.                 $lbw $this->spanborddet['L']['w'];
  6795.             }
  6796.             if (isset($this->spanborddet['R'])) {
  6797.                 $rbw $this->spanborddet['R']['w'];
  6798.             }
  6799.         }
  6800.         if ($this->usingCoreFont) {
  6801.             $clen strlen($s);
  6802.         } else {
  6803.             $clen mb_strlen($s$this->mb_enc);
  6804.         }
  6805.         // for every character in the string
  6806.         for ($i 0$i $clen$i++) {
  6807.             // extract the current character
  6808.             // get the width of the character in points
  6809.             if ($this->usingCoreFont) {
  6810.                 $c $s[$i];
  6811.                 // Soft Hyphens chr(173)
  6812.                 $cw = ($this->GetCharWidthCore($c) * Mpdf::SCALE);
  6813.                 if (($this->textvar TextVars::FC_KERNING) && $i 0) { // mPDF 5.7.1
  6814.                     if (isset($this->CurrentFont['kerninfo'][$s[($i 1)]][$c])) {
  6815.                         $cw += ($this->CurrentFont['kerninfo'][$s[($i 1)]][$c] * $this->FontSizePt 1000 );
  6816.                     }
  6817.                 }
  6818.             } else {
  6819.                 $c mb_substr($s$i1$this->mb_enc);
  6820.                 $cw = ($this->GetCharWidthNonCore($cfalse) * Mpdf::SCALE);
  6821.                 // mPDF 5.7.1
  6822.                 // Use OTL GPOS
  6823.                 if (isset($this->CurrentFont['useOTL']) && ($this->CurrentFont['useOTL'] & 0xFF)) {
  6824.                     // ...WriteFlowingBlock...
  6825.                     // Only  add XAdvanceL (not sure at present whether RTL or LTR writing direction)
  6826.                     // At this point, XAdvanceL and XAdvanceR will balance
  6827.                     if (isset($sOTLdata['GPOSinfo'][$i]['XAdvanceL'])) {
  6828.                         $cw += $sOTLdata['GPOSinfo'][$i]['XAdvanceL'] * (1000 $this->CurrentFont['unitsPerEm']) * ($this->FontSize 1000) * Mpdf::SCALE;
  6829.                     }
  6830.                 }
  6831.                 if (($this->textvar TextVars::FC_KERNING) && $i 0) { // mPDF 5.7.1
  6832.                     $lastc mb_substr($s, ($i 1), 1$this->mb_enc);
  6833.                     $ulastc $this->UTF8StringToArray($lastcfalse);
  6834.                     $uc $this->UTF8StringToArray($cfalse);
  6835.                     if (isset($this->CurrentFont['kerninfo'][$ulastc[0]][$uc[0]])) {
  6836.                         $cw += ($this->CurrentFont['kerninfo'][$ulastc[0]][$uc[0]] * $this->FontSizePt 1000 );
  6837.                     }
  6838.                 }
  6839.             }
  6840.             if ($i == 0) {
  6841.                 $cw += $lbw Mpdf::SCALE;
  6842.                 $contentB[(count($contentB) - 1)] .= 'L';
  6843.             }
  6844.             if ($i == ($clen 1)) {
  6845.                 $cw += $rbw Mpdf::SCALE;
  6846.                 $contentB[(count($contentB) - 1)] .= 'R';
  6847.             }
  6848.             if ($c == ' ') {
  6849.                 $currContent .= $c;
  6850.                 $contentWidth += $cw;
  6851.                 continue;
  6852.             }
  6853.             // Paragraph INDENT
  6854.             $WidthCorrection 0;
  6855.             if (($newblock) && ($blockstate == || $blockstate == 3) && isset($this->blk[$this->blklvl]['text_indent']) && ($lineCount == 0) && (!$is_table) && ($align != 'C')) {
  6856.                 $ti $this->sizeConverter->convert($this->blk[$this->blklvl]['text_indent'], $this->blk[$this->blklvl]['inner_width'], $this->blk[$this->blklvl]['InlineProperties']['size'], false);  // mPDF 5.7.4
  6857.                 $WidthCorrection = ($ti Mpdf::SCALE);
  6858.             }
  6859.             // OUTDENT
  6860.             foreach ($this->objectbuffer as $k => $objattr) {   // mPDF 6 DOTTAB
  6861.                 if ($objattr['type'] == 'dottab') {
  6862.                     $WidthCorrection -= ($objattr['outdent'] * Mpdf::SCALE);
  6863.                     break;
  6864.                 }
  6865.             }
  6866.             // Added mPDF 3.0 Float DIV
  6867.             $fpaddingR 0;
  6868.             $fpaddingL 0;
  6869.             /* -- CSS-FLOAT -- */
  6870.             if (count($this->floatDivs)) {
  6871.                 list($l_exists$r_exists$l_max$r_max$l_width$r_width) = $this->GetFloatDivInfo($this->blklvl);
  6872.                 if ($r_exists) {
  6873.                     $fpaddingR $r_width;
  6874.                 }
  6875.                 if ($l_exists) {
  6876.                     $fpaddingL $l_width;
  6877.                 }
  6878.             }
  6879.             /* -- END CSS-FLOAT -- */
  6880.             $usey $this->0.002;
  6881.             if (($newblock) && ($blockstate == || $blockstate == 3) && ($lineCount == 0)) {
  6882.                 $usey += $this->blk[$this->blklvl]['margin_top'] + $this->blk[$this->blklvl]['padding_top'] + $this->blk[$this->blklvl]['border_top']['w'];
  6883.             }
  6884.             /* -- CSS-IMAGE-FLOAT -- */
  6885.             // If float exists at this level
  6886.             if (isset($this->floatmargins['R']) && $usey <= $this->floatmargins['R']['y1'] && $usey >= $this->floatmargins['R']['y0'] && !$this->floatmargins['R']['skipline']) {
  6887.                 $fpaddingR += $this->floatmargins['R']['w'];
  6888.             }
  6889.             if (isset($this->floatmargins['L']) && $usey <= $this->floatmargins['L']['y1'] && $usey >= $this->floatmargins['L']['y0'] && !$this->floatmargins['L']['skipline']) {
  6890.                 $fpaddingL += $this->floatmargins['L']['w'];
  6891.             }
  6892.             /* -- END CSS-IMAGE-FLOAT -- */
  6893.             // try adding another char
  6894.             if (( $contentWidth $cw $maxWidth $WidthCorrection - (($this->cMarginL $this->cMarginR) * Mpdf::SCALE) - ($paddingL $paddingR + (($fpaddingL $fpaddingR) * Mpdf::SCALE) ) + 0.001)) {// 0.001 is to correct for deviations converting mm=>pts
  6895.                 // it won't fit, output what we already have
  6896.                 $lineCount++;
  6897.                 // contains any content that didn't make it into this print
  6898.                 $savedContent '';
  6899.                 $savedContentB '';
  6900.                 $savedOTLdata = []; // mPDF 5.7.1
  6901.                 $savedFont = [];
  6902.                 $savedObj = [];
  6903.                 $savedPreOTLdata = []; // mPDF 5.7.1
  6904.                 $savedPreContent = [];
  6905.                 $savedPreContentB = [];
  6906.                 $savedPreFont = [];
  6907.                 // mPDF 6
  6908.                 // New line-breaking algorithm
  6909.                 /////////////////////
  6910.                 // LINE BREAKING
  6911.                 /////////////////////
  6912.                 $breakfound false;
  6913.                 $contentctr count($content) - 1;
  6914.                 if ($this->usingCoreFont) {
  6915.                     $charctr strlen($currContent);
  6916.                 } else {
  6917.                     $charctr mb_strlen($currContent$this->mb_enc);
  6918.                 }
  6919.                 $checkchar $c;
  6920.                 $prevchar $this->_getPrevChar($contentctr$charctr$content);
  6921.                 /* -- CJK-FONTS -- */
  6922.                 // 1) CJK Overflowing a) punctuation or b) Oikomi
  6923.                 // Next character ($c) is suitable to add as overhanging or squeezed punctuation, or Oikomi
  6924.                 if ($CJKoverflow || $Oikomi) { // If flag already set
  6925.                     $CJKoverflow false;
  6926.                     $Oikomi false;
  6927.                     $breakfound true;
  6928.                 }
  6929.                 if (!$this->usingCoreFont && !$breakfound && $this->checkCJK) {
  6930.                     // Get next/following character (in this chunk)
  6931.                     $followingchar '';
  6932.                     if ($i < ($clen 1)) {
  6933.                         if ($this->usingCoreFont) {
  6934.                             $followingchar $s[$i 1];
  6935.                         } else {
  6936.                             $followingchar mb_substr($s$i 11$this->mb_enc);
  6937.                         }
  6938.                     }
  6939.                     // 1a) Overflow punctuation
  6940.                     if (preg_match("/[" $this->pregCJKchars "]/u"$prevchar) && preg_match("/[" $this->CJKoverflow "]/u"$checkchar) && $this->allowCJKorphans) {
  6941.                         // add character onto this line
  6942.                         $currContent .= $c;
  6943.                         $contentWidth += $cw;
  6944.                         $CJKoverflow true// Set flag
  6945.                         continue;
  6946.                     } elseif (preg_match("/[" $this->pregCJKchars "]/u"$checkchar) && $this->allowCJKorphans &&
  6947.                             (preg_match("/[" $this->CJKleading "]/u"$followingchar) || preg_match("/[" $this->CJKfollowing "]/u"$checkchar)) &&
  6948.                             !preg_match("/[" $this->CJKleading "]/u"$checkchar) && !preg_match("/[" $this->CJKfollowing "]/u"$followingchar) &&
  6949.                             !(preg_match("/[0-9\x{ff10}-\x{ff19}]/u"$followingchar) && preg_match("/[0-9\x{ff10}-\x{ff19}]/u"$checkchar))) {
  6950.                         // 1b) Try squeezing another character(s) onto this line = Oikomi, if character cannot end line
  6951.                         // or next character cannot start line (and not splitting CJK numerals)
  6952.                         // NB otherwise it move lastchar(s) to next line to keep $c company = Oidashi, which is done below in standard way
  6953.                         // add character onto this line
  6954.                         $currContent .= $c;
  6955.                         $contentWidth += $cw;
  6956.                         $Oikomi true// Set flag
  6957.                         continue;
  6958.                     }
  6959.                 }
  6960.                 /* -- END CJK-FONTS -- */
  6961.                 /* -- HYPHENATION -- */
  6962.                 // AUTOMATIC HYPHENATION
  6963.                 // 2) Automatic hyphen in current word (does not cross tags)
  6964.                 if (isset($this->textparam['hyphens']) && $this->textparam['hyphens'] == 1) {
  6965.                     $currWord '';
  6966.                     // Look back and ahead to get current word
  6967.                     for ($ac $charctr 1$ac >= 0$ac--) {
  6968.                         if ($this->usingCoreFont) {
  6969.                             $addc substr($currContent$ac1);
  6970.                         } else {
  6971.                             $addc mb_substr($currContent$ac1$this->mb_enc);
  6972.                         }
  6973.                         if ($addc == ' ') {
  6974.                             break;
  6975.                         }
  6976.                         $currWord $addc $currWord;
  6977.                     }
  6978.                     $start $ac 1;
  6979.                     for ($ac $i$ac < ($clen 1); $ac++) {
  6980.                         if ($this->usingCoreFont) {
  6981.                             $addc substr($s$ac1);
  6982.                         } else {
  6983.                             $addc mb_substr($s$ac1$this->mb_enc);
  6984.                         }
  6985.                         if ($addc == ' ') {
  6986.                             break;
  6987.                         }
  6988.                         $currWord .= $addc;
  6989.                     }
  6990.                     $ptr $this->hyphenator->hyphenateWord($currWord$charctr $start);
  6991.                     if ($ptr > -1) {
  6992.                         $breakfound = [$contentctr$start $ptr$contentctr$start $ptr'hyphen'];
  6993.                     }
  6994.                 }
  6995.                 /* -- END HYPHENATION -- */
  6996.                 // Search backwards to find first line-break opportunity
  6997.                 while ($breakfound == false && $prevchar !== false) {
  6998.                     $cutcontentctr $contentctr;
  6999.                     $cutcharctr $charctr;
  7000.                     $prevchar $this->_moveToPrevChar($contentctr$charctr$content);
  7001.                     /////////////////////
  7002.                     // 3) Break at SPACE
  7003.                     /////////////////////
  7004.                     if ($prevchar == ' ') {
  7005.                         $breakfound = [$contentctr$charctr$cutcontentctr$cutcharctr'discard'];
  7006.                     } /////////////////////
  7007.                     // 4) Break at U+200B in current word (Khmer, Lao & Thai Invisible word boundary, and Tibetan)
  7008.                     /////////////////////
  7009.                     elseif ($prevchar == "\xe2\x80\x8b") { // U+200B Zero-width Word Break
  7010.                         $breakfound = [$contentctr$charctr$cutcontentctr$cutcharctr'discard'];
  7011.                     } /////////////////////
  7012.                     // 5) Break at Hard HYPHEN '-' or U+2010
  7013.                     /////////////////////
  7014.                     elseif (isset($this->textparam['hyphens']) && $this->textparam['hyphens'] != && ($prevchar == '-' || $prevchar == "\xe2\x80\x90")) {
  7015.                         // Don't break a URL
  7016.                         // Look back to get first part of current word
  7017.                         $checkw '';
  7018.                         for ($ac $charctr 1$ac >= 0$ac--) {
  7019.                             if ($this->usingCoreFont) {
  7020.                                 $addc substr($currContent$ac1);
  7021.                             } else {
  7022.                                 $addc mb_substr($currContent$ac1$this->mb_enc);
  7023.                             }
  7024.                             if ($addc == ' ') {
  7025.                                 break;
  7026.                             }
  7027.                             $checkw $addc $checkw;
  7028.                         }
  7029.                         // Don't break if HyphenMinus AND (a URL or before a numeral or before a >)
  7030.                         if ((!preg_match('/(http:|ftp:|https:|www\.)/'$checkw) && $checkchar != '>' && !preg_match('/[0-9]/'$checkchar)) || $prevchar == "\xe2\x80\x90") {
  7031.                             $breakfound = [$cutcontentctr$cutcharctr$cutcontentctr$cutcharctr'cut'];
  7032.                         }
  7033.                     } /////////////////////
  7034.                     // 6) Break at Soft HYPHEN (replace with hard hyphen)
  7035.                     /////////////////////
  7036.                     elseif (isset($this->textparam['hyphens']) && $this->textparam['hyphens'] != && !$this->usingCoreFont && $prevchar == "\xc2\xad") {
  7037.                         $breakfound = [$cutcontentctr$cutcharctr$cutcontentctr$cutcharctr'cut'];
  7038.                         $content[$contentctr] = mb_substr($content[$contentctr], 0$charctr$this->mb_enc) . '-' mb_substr($content[$contentctr], $charctr 1mb_strlen($content[$contentctr]), $this->mb_enc);
  7039.                         if (!empty($cOTLdata[$contentctr])) {
  7040.                             $cOTLdata[$contentctr]['char_data'][$charctr] = ['bidi_class' => 9'uni' => 45];
  7041.                             $cOTLdata[$contentctr]['group'][$charctr] = 'C';
  7042.                         }
  7043.                     } elseif (isset($this->textparam['hyphens']) && $this->textparam['hyphens'] != && $this->FontFamily != 'csymbol' && $this->FontFamily != 'czapfdingbats' && $prevchar == chr(173)) {
  7044.                         $breakfound = [$cutcontentctr$cutcharctr$cutcontentctr$cutcharctr'cut'];
  7045.                         $content[$contentctr] = substr($content[$contentctr], 0$charctr) . '-' substr($content[$contentctr], $charctr 1);
  7046.                     } /* -- CJK-FONTS -- */
  7047.                     /////////////////////
  7048.                     // 7) Break at CJK characters (unless forbidden characters to end or start line)
  7049.                     // CJK Avoiding line break in the middle of numerals
  7050.                     /////////////////////
  7051.                     elseif (!$this->usingCoreFont && $this->checkCJK && preg_match("/[" $this->pregCJKchars "]/u"$checkchar) &&
  7052.                         !preg_match("/[" $this->CJKfollowing "]/u"$checkchar) && !preg_match("/[" $this->CJKleading "]/u"$prevchar) &&
  7053.                         !(preg_match("/[0-9\x{ff10}-\x{ff19}]/u"$prevchar) && preg_match("/[0-9\x{ff10}-\x{ff19}]/u"$checkchar))) {
  7054.                         $breakfound = [$cutcontentctr$cutcharctr$cutcontentctr$cutcharctr'cut'];
  7055.                     }
  7056.                     /* -- END CJK-FONTS -- */
  7057.                     /////////////////////
  7058.                     // 8) Break at OBJECT (Break before all objects here - selected objects are moved forward to next line below e.g. dottab)
  7059.                     /////////////////////
  7060.                     if (isset($this->objectbuffer[$contentctr])) {
  7061.                         $breakfound = [$cutcontentctr$cutcharctr$cutcontentctr$cutcharctr'cut'];
  7062.                     }
  7063.                     $checkchar $prevchar;
  7064.                 }
  7065.                 // If a line-break opportunity found:
  7066.                 if (is_array($breakfound)) {
  7067.                     $contentctr $breakfound[0];
  7068.                     $charctr $breakfound[1];
  7069.                     $cutcontentctr $breakfound[2];
  7070.                     $cutcharctr $breakfound[3];
  7071.                     $type $breakfound[4];
  7072.                     // Cache chunks which are already processed, but now need to be passed on to the new line
  7073.                     for ($ix count($content) - 1$ix $cutcontentctr$ix--) {
  7074.                         // save and crop off any subsequent chunks
  7075.                         /* -- OTL -- */
  7076.                         if (!empty($sOTLdata)) {
  7077.                             $tmpOTL array_pop($cOTLdata);
  7078.                             $savedPreOTLdata[] = $tmpOTL;
  7079.                         }
  7080.                         /* -- END OTL -- */
  7081.                         $savedPreContent[] = array_pop($content);
  7082.                         $savedPreContentB[] = array_pop($contentB);
  7083.                         $savedPreFont[] = array_pop($font);
  7084.                     }
  7085.                     // Next cache the part which will start the next line
  7086.                     if ($this->usingCoreFont) {
  7087.                         $savedPreContent[] = substr($content[$cutcontentctr], $cutcharctr);
  7088.                     } else {
  7089.                         $savedPreContent[] = mb_substr($content[$cutcontentctr], $cutcharctrmb_strlen($content[$cutcontentctr]), $this->mb_enc);
  7090.                     }
  7091.                     $savedPreContentB[] = preg_replace('/L/'''$contentB[$cutcontentctr]);
  7092.                     $savedPreFont[] = $font[$cutcontentctr];
  7093.                     /* -- OTL -- */
  7094.                     if (!empty($sOTLdata)) {
  7095.                         $savedPreOTLdata[] = $this->otl->splitOTLdata($cOTLdata[$cutcontentctr], $cutcharctr$cutcharctr);
  7096.                     }
  7097.                     /* -- END OTL -- */
  7098.                     // Finally adjust the Current content which ends this line
  7099.                     if ($cutcharctr == && $type == 'discard') {
  7100.                         array_pop($content);
  7101.                         array_pop($contentB);
  7102.                         array_pop($font);
  7103.                         array_pop($cOTLdata);
  7104.                     }
  7105.                     $currContent = & $content[count($content) - 1];
  7106.                     if ($this->usingCoreFont) {
  7107.                         $currContent substr($currContent0$charctr);
  7108.                     } else {
  7109.                         $currContent mb_substr($currContent0$charctr$this->mb_enc);
  7110.                     }
  7111.                     if (!empty($sOTLdata)) {
  7112.                         $savedPreOTLdata[] = $this->otl->splitOTLdata($cOTLdata[(count($cOTLdata) - 1)], mb_strlen($currContent$this->mb_enc));
  7113.                     }
  7114.                     if (strpos($contentB[(count($contentB) - 1)], 'R') !== false) {   // ???
  7115.                         $contentB[count($content) - 1] = preg_replace('/R/'''$contentB[count($content) - 1]); // ???
  7116.                     }
  7117.                     if ($type === 'hyphen') {
  7118.                         $hyphen in_array(mb_substr($currContent, -1), ['-''–''—'], true);
  7119.                         if (!$hyphen) {
  7120.                             $currContent .= '-';
  7121.                         } else {
  7122.                             $savedPreContent[count($savedPreContent) - 1] = '-' $savedPreContent[count($savedPreContent) - 1];
  7123.                         }
  7124.                         if (!empty($cOTLdata[(count($cOTLdata) - 1)])) {
  7125.                             $cOTLdata[(count($cOTLdata) - 1)]['char_data'][] = ['bidi_class' => 9'uni' => 45];
  7126.                             $cOTLdata[(count($cOTLdata) - 1)]['group'] .= 'C';
  7127.                         }
  7128.                     }
  7129.                     $savedContent '';
  7130.                     $savedContentB '';
  7131.                     $savedFont = [];
  7132.                     $savedOTLdata = [];
  7133.                 }
  7134.                 // If no line-break opportunity found - split at current position
  7135.                 // or - Next character ($c) is suitable to add as overhanging or squeezed punctuation, or Oikomi, as set above by:
  7136.                 // 1) CJK Overflowing a) punctuation or b) Oikomi
  7137.                 // in which case $breakfound==1 and NOT array
  7138.                 if (!is_array($breakfound)) {
  7139.                     $savedFont $this->saveFont();
  7140.                     if (!empty($sOTLdata)) {
  7141.                         $savedOTLdata $this->otl->splitOTLdata($cOTLdata[(count($cOTLdata) - 1)], mb_strlen($currContent$this->mb_enc));
  7142.                     }
  7143.                 }
  7144.                 if ($content[count($content) - 1] == '' && !isset($this->objectbuffer[count($content) - 1])) {
  7145.                     array_pop($content);
  7146.                     array_pop($contentB);
  7147.                     array_pop($font);
  7148.                     array_pop($cOTLdata);
  7149.                     $currContent = & $content[count($content) - 1];
  7150.                 }
  7151.                 // Right Trim current content - including CJK space, and for OTLdata
  7152.                 // incl. CJK - strip CJK space at end of line &#x3000; = \xe3\x80\x80 = CJK space
  7153.                 $currContent $currContent rtrim($currContent) : '';
  7154.                 if ($this->checkCJK) {
  7155.                     $currContent preg_replace("/\xe3\x80\x80$/"''$currContent);
  7156.                 } // *CJK-FONTS*
  7157.                 /* -- OTL -- */
  7158.                 if (isset($this->CurrentFont['useOTL']) && $this->CurrentFont['useOTL']) {
  7159.                     $this->otl->trimOTLdata($cOTLdata[count($cOTLdata) - 1], falsetrue); // NB also does U+3000
  7160.                 }
  7161.                 /* -- END OTL -- */
  7162.                 // Selected OBJECTS are moved forward to next line, unless they come before a space or U+200B (type='discard')
  7163.                 if (isset($this->objectbuffer[(count($content) - 1)]) && (!isset($type) || $type != 'discard')) {
  7164.                     $objtype $this->objectbuffer[(count($content) - 1)]['type'];
  7165.                     if ($objtype == 'dottab' || $objtype == 'bookmark' || $objtype == 'indexentry' || $objtype == 'toc' || $objtype == 'annot') {
  7166.                         $savedObj array_pop($this->objectbuffer);
  7167.                     }
  7168.                 }
  7169.                 // Decimal alignment (cancel if wraps to > 1 line)
  7170.                 if ($is_table && substr($align01) == 'D') {
  7171.                     $align substr($align21);
  7172.                 }
  7173.                 $lineBox = [];
  7174.                 $this->_setInlineBlockHeights($lineBox$stackHeight$content$font$is_table);
  7175.                 // update $contentWidth since it has changed with cropping
  7176.                 $contentWidth 0;
  7177.                 $inclCursive false;
  7178.                 foreach ($content as $k => $chunk) {
  7179.                     if (isset($this->objectbuffer[$k]) && $this->objectbuffer[$k]) {
  7180.                         // LIST MARKERS
  7181.                         if ($this->objectbuffer[$k]['type'] == 'image' && isset($this->objectbuffer[$k]['listmarker']) && $this->objectbuffer[$k]['listmarker']) {
  7182.                             if ($this->objectbuffer[$k]['listmarkerposition'] != 'outside') {
  7183.                                 $contentWidth += $this->objectbuffer[$k]['OUTER-WIDTH'] * Mpdf::SCALE;
  7184.                             }
  7185.                         } else {
  7186.                             $contentWidth += $this->objectbuffer[$k]['OUTER-WIDTH'] * Mpdf::SCALE;
  7187.                         }
  7188.                     } elseif (!isset($this->objectbuffer[$k]) || (isset($this->objectbuffer[$k]) && !$this->objectbuffer[$k])) {
  7189.                         $this->restoreFont($font[$k], false);
  7190.                         if ($this->checkCJK && $k == count($content) - && $CJKoverflow && $align == 'J' && $this->allowCJKoverflow && $this->CJKforceend) {
  7191.                             // force-end overhang
  7192.                             $hanger mb_substr($chunkmb_strlen($chunk$this->mb_enc) - 11$this->mb_enc);
  7193.                             // Probably ought to do something with char_data and GPOS in cOTLdata...
  7194.                             $content[$k] = $chunk mb_substr($chunk0mb_strlen($chunk$this->mb_enc) - 1$this->mb_enc);
  7195.                         }
  7196.                         // Soft Hyphens chr(173) + Replace NBSP with SPACE + Set inclcursive if includes CURSIVE TEXT
  7197.                         if (!$this->usingCoreFont) {
  7198.                             /* -- OTL -- */
  7199.                             if ((isset($this->CurrentFont['useOTL']) && $this->CurrentFont['useOTL']) || !empty($sOTLdata)) {
  7200.                                 $this->otl->removeChar($chunk$cOTLdata[$k], "\xc2\xad");
  7201.                                 $this->otl->replaceSpace($chunk$cOTLdata[$k]); // NBSP -> space
  7202.                                 if (preg_match("/([" $this->pregCURSchars "])/u"$chunk)) {
  7203.                                     $inclCursive true;
  7204.                                 }
  7205.                                 $content[$k] = $chunk;
  7206.                             } /* -- END OTL -- */ else {  // *OTL*
  7207.                                 $content[$k] = $chunk str_replace("\xc2\xad"''$chunk);
  7208.                                 $content[$k] = $chunk str_replace(chr(194) . chr(160), chr(32), $chunk);
  7209.                             } // *OTL*
  7210.                         } elseif ($this->FontFamily != 'csymbol' && $this->FontFamily != 'czapfdingbats') {
  7211.                             $content[$k] = $chunk str_replace(chr(173), ''$chunk);
  7212.                             $content[$k] = $chunk str_replace(chr(160), chr(32), $chunk);
  7213.                         }
  7214.                         $contentWidth += $this->GetStringWidth($chunktrue, (isset($cOTLdata[$k]) ? $cOTLdata[$k] : false), $this->textvar) * Mpdf::SCALE;  // mPDF 5.7.1
  7215.                         if (!empty($this->spanborddet)) {
  7216.                             if (isset($this->spanborddet['L']['w']) && strpos($contentB[$k], 'L') !== false) {
  7217.                                 $contentWidth += $this->spanborddet['L']['w'] * Mpdf::SCALE;
  7218.                             }
  7219.                             if (isset($this->spanborddet['R']['w']) && strpos($contentB[$k], 'R') !== false) {
  7220.                                 $contentWidth += $this->spanborddet['R']['w'] * Mpdf::SCALE;
  7221.                             }
  7222.                         }
  7223.                     }
  7224.                 }
  7225.                 $lastfontreqstyle = (isset($font[count($font) - 1]['ReqFontStyle']) ? $font[count($font) - 1]['ReqFontStyle'] : '');
  7226.                 $lastfontstyle = (isset($font[count($font) - 1]['style']) ? $font[count($font) - 1]['style'] : '');
  7227.                 if ($blockdir == 'ltr' && strpos($lastfontreqstyle"I") !== false && strpos($lastfontstyle"I") === false) { // Artificial italic
  7228.                     $lastitalic $this->FontSize 0.15 Mpdf::SCALE;
  7229.                 } else {
  7230.                     $lastitalic 0;
  7231.                 }
  7232.                 // NOW FORMAT THE LINE TO OUTPUT
  7233.                 if (!$table_draft) {
  7234.                     // DIRECTIONALITY RTL
  7235.                     $chunkorder range(0count($content) - 1); // mPDF 5.7
  7236.                     /* -- OTL -- */
  7237.                     // mPDF 6
  7238.                     if ($blockdir == 'rtl' || $this->biDirectional) {
  7239.                         $this->otl->bidiReorder($chunkorder$content$cOTLdata$blockdir);
  7240.                         // From this point on, $content and $cOTLdata may contain more elements (and re-ordered) compared to
  7241.                         // $this->objectbuffer and $font ($chunkorder contains the mapping)
  7242.                     }
  7243.                     /* -- END OTL -- */
  7244.                     // Remove any XAdvance from OTL data at end of line
  7245.                     foreach ($chunkorder as $aord => $k) {
  7246.                         if (count($cOTLdata)) {
  7247.                             $this->restoreFont($font[$k], false);
  7248.                             // ...WriteFlowingBlock...
  7249.                             if ($aord == count($chunkorder) - && isset($cOTLdata[$aord]['group'])) { // Last chunk on line
  7250.                                 $nGPOS strlen($cOTLdata[$aord]['group']) - 1// Last character
  7251.                                 if (isset($cOTLdata[$aord]['GPOSinfo'][$nGPOS]['XAdvanceL']) || isset($cOTLdata[$aord]['GPOSinfo'][$nGPOS]['XAdvanceR'])) {
  7252.                                     if (isset($cOTLdata[$aord]['GPOSinfo'][$nGPOS]['XAdvanceL'])) {
  7253.                                         $w $cOTLdata[$aord]['GPOSinfo'][$nGPOS]['XAdvanceL'] * 1000 $this->CurrentFont['unitsPerEm'];
  7254.                                     } else {
  7255.                                         $w $cOTLdata[$aord]['GPOSinfo'][$nGPOS]['XAdvanceR'] * 1000 $this->CurrentFont['unitsPerEm'];
  7256.                                     }
  7257.                                     $w *= ($this->FontSize 1000);
  7258.                                     $contentWidth -= $w Mpdf::SCALE;
  7259.                                     $cOTLdata[$aord]['GPOSinfo'][$nGPOS]['XAdvanceL'] = 0;
  7260.                                     $cOTLdata[$aord]['GPOSinfo'][$nGPOS]['XAdvanceR'] = 0;
  7261.                                 }
  7262.                                 // If last character has an XPlacement set, adjust width calculation, and add to XAdvance to account for it
  7263.                                 if (isset($cOTLdata[$aord]['GPOSinfo'][$nGPOS]['XPlacement'])) {
  7264.                                     $w = -$cOTLdata[$aord]['GPOSinfo'][$nGPOS]['XPlacement'] * 1000 $this->CurrentFont['unitsPerEm'];
  7265.                                     $w *= ($this->FontSize 1000);
  7266.                                     $contentWidth -= $w Mpdf::SCALE;
  7267.                                     $cOTLdata[$aord]['GPOSinfo'][$nGPOS]['XAdvanceL'] = $cOTLdata[$aord]['GPOSinfo'][$nGPOS]['XPlacement'];
  7268.                                     $cOTLdata[$aord]['GPOSinfo'][$nGPOS]['XAdvanceR'] = $cOTLdata[$aord]['GPOSinfo'][$nGPOS]['XPlacement'];
  7269.                                 }
  7270.                             }
  7271.                         }
  7272.                     }
  7273.                     // JUSTIFICATION J
  7274.                     $jcharspacing 0;
  7275.                     $jws 0;
  7276.                     $nb_carac 0;
  7277.                     $nb_spaces 0;
  7278.                     $jkashida 0;
  7279.                     // if it's justified, we need to find the char/word spacing (or if hanger $this->CJKforceend)
  7280.                     if (($align == 'J' && !$CJKoverflow) || (($contentWidth $lastitalic $maxWidth $WidthCorrection - (($this->cMarginL $this->cMarginR) * Mpdf::SCALE) - ($paddingL $paddingR + (($fpaddingL $fpaddingR) * Mpdf::SCALE) ) + 0.001) && (!$CJKoverflow || ($CJKoverflow && !$this->allowCJKoverflow))) || $CJKoverflow && $align == 'J' && $this->allowCJKoverflow && $hanger && $this->CJKforceend) {   // 0.001 is to correct for deviations converting mm=>pts
  7281.                         // JUSTIFY J (Use character spacing)
  7282.                         // WORD SPACING
  7283.                         // mPDF 5.7
  7284.                         foreach ($chunkorder as $aord => $k) {
  7285.                             $chunk = isset($content[$aord]) ? $content[$aord] : '';
  7286.                             if (!isset($this->objectbuffer[$k]) || (isset($this->objectbuffer[$k]) && !$this->objectbuffer[$k])) {
  7287.                                 $nb_carac += mb_strlen($chunk$this->mb_enc);
  7288.                                 $nb_spaces += mb_substr_count($chunk' '$this->mb_enc);
  7289.                                 // Use GPOS OTL
  7290.                                 if (isset($this->CurrentFont['useOTL']) && ($this->CurrentFont['useOTL'] & 0xFF)) {
  7291.                                     if (isset($cOTLdata[$aord]['group']) && $cOTLdata[$aord]['group']) {
  7292.                                         $nb_carac -= substr_count($cOTLdata[$aord]['group'], 'M');
  7293.                                     }
  7294.                                 }
  7295.                             } else {
  7296.                                 $nb_carac ++;
  7297.                             } // mPDF 6 allow spacing for inline object
  7298.                         }
  7299.                         // GetJSpacing adds kashida spacing to GPOSinfo if appropriate for Font
  7300.                         list($jcharspacing$jws$jkashida) = $this->GetJspacing($nb_carac$nb_spaces, ($maxWidth $lastitalic $contentWidth $WidthCorrection - (($this->cMarginL $this->cMarginR) * Mpdf::SCALE) - ($paddingL $paddingR + (($fpaddingL $fpaddingR) * Mpdf::SCALE) )), $inclCursive$cOTLdata);
  7301.                     }
  7302.                     // WORD SPACING
  7303.                     $empty $maxWidth $lastitalic $WidthCorrection $contentWidth - (($this->cMarginL $this->cMarginR) * Mpdf::SCALE) - ($paddingL $paddingR + (($fpaddingL $fpaddingR) * Mpdf::SCALE) );
  7304.                     $empty -= ($jcharspacing * ($nb_carac 1)); // mPDF 6 nb_carac MINUS 1
  7305.                     $empty -= ($jws $nb_spaces);
  7306.                     $empty -= ($jkashida);
  7307.                     $empty /= Mpdf::SCALE;
  7308.                     $b ''// do not use borders
  7309.                     // Get PAGEBREAK TO TEST for height including the top border/padding
  7310.                     $check_h max($this->divheight$stackHeight);
  7311.                     if (($newblock) && ($blockstate == || $blockstate == 3) && ($this->blklvl 0) && ($lineCount == 1) && (!$is_table)) {
  7312.                         $check_h += ($this->blk[$this->blklvl]['padding_top'] + $this->blk[$this->blklvl]['margin_top'] + $this->blk[$this->blklvl]['border_top']['w']);
  7313.                     }
  7314.                     if ($this->ColActive && $check_h > ($this->PageBreakTrigger $this->y0)) {
  7315.                         $this->SetCol($this->NbCol 1);
  7316.                     }
  7317.                     // PAGEBREAK
  7318.                     // 'If' below used in order to fix "first-line of other page with justify on" bug
  7319.                     if (!$is_table && ($this->$check_h) > $this->PageBreakTrigger and ! $this->InFooter and $this->AcceptPageBreak()) {
  7320.                         $bak_x $this->x// Current X position
  7321.                         // WORD SPACING
  7322.                         $ws $this->ws// Word Spacing
  7323.                         $charspacing $this->charspacing// Character Spacing
  7324.                         $this->ResetSpacing();
  7325.                         $this->AddPage($this->CurOrientation);
  7326.                         $this->$bak_x;
  7327.                         // Added to correct for OddEven Margins
  7328.                         $currentx += $this->MarginCorrection;
  7329.                         $this->+= $this->MarginCorrection;
  7330.                         // WORD SPACING
  7331.                         $this->SetSpacing($charspacing$ws);
  7332.                     }
  7333.                     if ($this->kwt && !$is_table) { // mPDF 5.7+
  7334.                         $this->printkwtbuffer();
  7335.                         $this->kwt false;
  7336.                     }
  7337.                     /* -- COLUMNS -- */
  7338.                     // COLS
  7339.                     // COLUMN CHANGE
  7340.                     if ($this->CurrCol != $oldcolumn) {
  7341.                         $currentx += $this->ChangeColumn * ($this->ColWidth $this->ColGap);
  7342.                         $this->+= $this->ChangeColumn * ($this->ColWidth $this->ColGap);
  7343.                         $oldcolumn $this->CurrCol;
  7344.                     }
  7345.                     if ($this->ColActive && !$is_table) {
  7346.                         $this->breakpoints[$this->CurrCol][] = $this->y;
  7347.                     } // *COLUMNS*
  7348.                     /* -- END COLUMNS -- */
  7349.                     // TOP MARGIN
  7350.                     if (($newblock) && ($blockstate == || $blockstate == 3) && ($this->blk[$this->blklvl]['margin_top']) && ($lineCount == 1) && (!$is_table)) {
  7351.                         $this->DivLn($this->blk[$this->blklvl]['margin_top'], $this->blklvl 1true$this->blk[$this->blklvl]['margin_collapse']);
  7352.                         if ($this->ColActive) {
  7353.                             $this->breakpoints[$this->CurrCol][] = $this->y;
  7354.                         } // *COLUMNS*
  7355.                     }
  7356.                     // Update y0 for top of block (used to paint border)
  7357.                     if (($newblock) && ($blockstate == || $blockstate == 3) && ($lineCount == 1) && (!$is_table)) {
  7358.                         $this->blk[$this->blklvl]['y0'] = $this->y;
  7359.                         $this->blk[$this->blklvl]['startpage'] = $this->page;
  7360.                         if ($this->blk[$this->blklvl]['float']) {
  7361.                             $this->blk[$this->blklvl]['float_start_y'] = $this->y;
  7362.                         }
  7363.                     }
  7364.                     // TOP PADDING and BORDER spacing/fill
  7365.                     if (($newblock) && ($blockstate == || $blockstate == 3) && (($this->blk[$this->blklvl]['padding_top']) || ($this->blk[$this->blklvl]['border_top'])) && ($lineCount == 1) && (!$is_table)) {
  7366.                         // $state = 0 normal; 1 top; 2 bottom; 3 top and bottom
  7367.                         $this->DivLn($this->blk[$this->blklvl]['padding_top'] + $this->blk[$this->blklvl]['border_top']['w'], -3truefalse1);
  7368.                         if ($this->ColActive) {
  7369.                             $this->breakpoints[$this->CurrCol][] = $this->y;
  7370.                         } // *COLUMNS*
  7371.                     }
  7372.                     $arraysize count($chunkorder);
  7373.                     $margins = ($this->cMarginL $this->cMarginR) + ($ipaddingL $ipaddingR $fpaddingR $fpaddingR );
  7374.                     // PAINT BACKGROUND FOR THIS LINE
  7375.                     if (!$is_table) {
  7376.                         $this->DivLn($stackHeight$this->blklvlfalse);
  7377.                     } // false -> don't advance y
  7378.                     $this->$currentx $this->cMarginL $ipaddingL $fpaddingL;
  7379.                     if ($align == 'R') {
  7380.                         $this->+= $empty;
  7381.                     } elseif ($align == 'C') {
  7382.                         $this->+= ($empty 2);
  7383.                     }
  7384.                     // Paragraph INDENT
  7385.                     if (isset($this->blk[$this->blklvl]['text_indent']) && ($newblock) && ($blockstate == || $blockstate == 3) && ($lineCount == 1) && (!$is_table) && ($blockdir != 'rtl') && ($align != 'C')) {
  7386.                         $ti $this->sizeConverter->convert($this->blk[$this->blklvl]['text_indent'], $this->blk[$this->blklvl]['inner_width'], $this->blk[$this->blklvl]['InlineProperties']['size'], false);  // mPDF 5.7.4
  7387.                         $this->+= $ti;
  7388.                     }
  7389.                     // BIDI magic_reverse moved upwards from here
  7390.                     foreach ($chunkorder as $aord => $k) { // mPDF 5.7
  7391.                         $chunk = isset($content[$aord]) ? $content[$aord] : '';
  7392.                         if (isset($this->objectbuffer[$k]) && $this->objectbuffer[$k]) {
  7393.                             $xadj $this->$this->objectbuffer[$k]['OUTER-X'];
  7394.                             $this->objectbuffer[$k]['OUTER-X'] += $xadj;
  7395.                             $this->objectbuffer[$k]['BORDER-X'] += $xadj;
  7396.                             $this->objectbuffer[$k]['INNER-X'] += $xadj;
  7397.                             if ($this->objectbuffer[$k]['type'] == 'listmarker') {
  7398.                                 $this->objectbuffer[$k]['lineBox'] = $lineBox[-1]; // Block element details for glyph-origin
  7399.                             }
  7400.                             $yadj $this->$this->objectbuffer[$k]['OUTER-Y'];
  7401.                             if ($this->objectbuffer[$k]['type'] == 'dottab') { // mPDF 6 DOTTAB
  7402.                                 $this->objectbuffer[$k]['lineBox'] = $lineBox[$k]; // element details for glyph-origin
  7403.                             }
  7404.                             if ($this->objectbuffer[$k]['type'] != 'dottab') { // mPDF 6 DOTTAB
  7405.                                 $yadj += $lineBox[$k]['top'];
  7406.                             }
  7407.                             $this->objectbuffer[$k]['OUTER-Y'] += $yadj;
  7408.                             $this->objectbuffer[$k]['BORDER-Y'] += $yadj;
  7409.                             $this->objectbuffer[$k]['INNER-Y'] += $yadj;
  7410.                         }
  7411.                         $this->restoreFont($font[$k]);  // mPDF 5.7
  7412.                         $this->SetSpacing(($this->fixedlSpacing Mpdf::SCALE) + $jcharspacing, ($this->fixedlSpacing $this->minwSpacing) * Mpdf::SCALE $jws);
  7413.                         // Now unset these values so they don't influence GetStringwidth below or in fn. Cell
  7414.                         $this->fixedlSpacing false;
  7415.                         $this->minwSpacing 0;
  7416.                         $save_vis $this->visibility;
  7417.                         if (isset($this->textparam['visibility']) && $this->textparam['visibility'] && $this->textparam['visibility'] != $this->visibility) {
  7418.                             $this->SetVisibility($this->textparam['visibility']);
  7419.                         }
  7420.                         // *********** SPAN BACKGROUND COLOR ***************** //
  7421.                         if ($this->spanbgcolor) {
  7422.                             $cor $this->spanbgcolorarray;
  7423.                             $this->SetFColor($cor);
  7424.                             $save_fill $fill;
  7425.                             $spanfill 1;
  7426.                             $fill 1;
  7427.                         }
  7428.                         if (!empty($this->spanborddet)) {
  7429.                             if (strpos($contentB[$k], 'L') !== false) {
  7430.                                 $this->+= (isset($this->spanborddet['L']['w']) ? $this->spanborddet['L']['w'] : 0);
  7431.                             }
  7432.                             if (strpos($contentB[$k], 'L') === false) {
  7433.                                 $this->spanborddet['L']['s'] = $this->spanborddet['L']['w'] = 0;
  7434.                             }
  7435.                             if (strpos($contentB[$k], 'R') === false) {
  7436.                                 $this->spanborddet['R']['s'] = $this->spanborddet['R']['w'] = 0;
  7437.                             }
  7438.                         }
  7439.                         // WORD SPACING
  7440.                         // StringWidth this time includes any kashida spacing
  7441.                         $stringWidth $this->GetStringWidth($chunktrue, (isset($cOTLdata[$aord]) ? $cOTLdata[$aord] : false), $this->textvartrue);
  7442.                         $nch mb_strlen($chunk$this->mb_enc);
  7443.                         // Use GPOS OTL
  7444.                         if (isset($this->CurrentFont['useOTL']) && ($this->CurrentFont['useOTL'] & 0xFF)) {
  7445.                             if (isset($cOTLdata[$aord]['group']) && $cOTLdata[$aord]['group']) {
  7446.                                 $nch -= substr_count($cOTLdata[$aord]['group'], 'M');
  7447.                             }
  7448.                         }
  7449.                         $stringWidth += ( $this->charspacing $nch Mpdf::SCALE );
  7450.                         $stringWidth += ( $this->ws mb_substr_count($chunk' '$this->mb_enc) / Mpdf::SCALE );
  7451.                         if (isset($this->objectbuffer[$k])) {
  7452.                             // LIST MARKERS    // mPDF 6  Lists
  7453.                             if ($this->objectbuffer[$k]['type'] == 'image' && isset($this->objectbuffer[$k]['listmarker']) && $this->objectbuffer[$k]['listmarker'] && $this->objectbuffer[$k]['listmarkerposition'] == 'outside') {
  7454.                                 $stringWidth 0;
  7455.                             } else {
  7456.                                 $stringWidth $this->objectbuffer[$k]['OUTER-WIDTH'];
  7457.                             }
  7458.                         }
  7459.                         if ($stringWidth == 0) {
  7460.                             $stringWidth 0.000001;
  7461.                         }
  7462.                         if ($aord == $arraysize 1) {
  7463.                             $stringWidth -= ( $this->charspacing Mpdf::SCALE );
  7464.                             if ($this->checkCJK && $CJKoverflow && $align == 'J' && $this->allowCJKoverflow && $hanger && $this->CJKforceend) {
  7465.                                 // force-end overhang
  7466.                                 $this->Cell($stringWidth$stackHeight$chunk''0''$fill$this->HREF$currentx00'M'$filltrue, (isset($cOTLdata[$aord]) ? $cOTLdata[$aord] : false), $this->textvar, (isset($lineBox[$k]) ? $lineBox[$k] : false));
  7467.                                 $this->Cell($this->GetStringWidth($hanger), $stackHeight$hanger''1''$fill$this->HREF$currentx00'M'$filltrue, (isset($cOTLdata[$aord]) ? $cOTLdata[$aord] : false), $this->textvar, (isset($lineBox[$k]) ? $lineBox[$k] : false));
  7468.                             } else {
  7469.                                 $this->Cell($stringWidth$stackHeight$chunk''1''$fill$this->HREF$currentx00'M'$filltrue, (isset($cOTLdata[$aord]) ? $cOTLdata[$aord] : false), $this->textvar, (isset($lineBox[$k]) ? $lineBox[$k] : false)); // mono-style line or last part (skips line)
  7470.                             }
  7471.                         } else {
  7472.                             $this->Cell($stringWidth$stackHeight$chunk''0''$fill$this->HREF000'M'$filltrue, (isset($cOTLdata[$aord]) ? $cOTLdata[$aord] : false), $this->textvar, (isset($lineBox[$k]) ? $lineBox[$k] : false)); // first or middle part
  7473.                         }
  7474.                         if (!empty($this->spanborddet)) {
  7475.                             if (strpos($contentB[$k], 'R') !== false && $aord != $arraysize 1) {
  7476.                                 $this->+= $this->spanborddet['R']['w'];
  7477.                             }
  7478.                         }
  7479.                         // *********** SPAN BACKGROUND COLOR OFF - RESET BLOCK BGCOLOR ***************** //
  7480.                         if (isset($spanfill) && $spanfill) {
  7481.                             $fill $save_fill;
  7482.                             $spanfill 0;
  7483.                             if ($fill) {
  7484.                                 $this->SetFColor($bcor);
  7485.                             }
  7486.                         }
  7487.                         if (isset($this->textparam['visibility']) && $this->textparam['visibility'] && $this->visibility != $save_vis) {
  7488.                             $this->SetVisibility($save_vis);
  7489.                         }
  7490.                     }
  7491.                 } elseif ($table_draft) {
  7492.                     $this->+= $stackHeight;
  7493.                 }
  7494.                 if (!$is_table) {
  7495.                     $this->maxPosR max($this->maxPosR, ($this->$this->rMargin $this->blk[$this->blklvl]['outer_right_margin']));
  7496.                     $this->maxPosL min($this->maxPosL, ($this->lMargin $this->blk[$this->blklvl]['outer_left_margin']));
  7497.                 }
  7498.                 // move on to the next line, reset variables, tack on saved content and current char
  7499.                 if (!$table_draft) {
  7500.                     $this->printobjectbuffer($is_table$blockdir);
  7501.                 }
  7502.                 $this->objectbuffer = [];
  7503.                 /* -- CSS-IMAGE-FLOAT -- */
  7504.                 // Update values if set to skipline
  7505.                 if ($this->floatmargins) {
  7506.                     $this->_advanceFloatMargins();
  7507.                 }
  7508.                 /* -- END CSS-IMAGE-FLOAT -- */
  7509.                 // Reset lineheight
  7510.                 $stackHeight $this->divheight;
  7511.                 $valign 'M';
  7512.                 $font = [];
  7513.                 $content = [];
  7514.                 $contentB = [];
  7515.                 $cOTLdata = []; // mPDF 5.7.1
  7516.                 $contentWidth 0;
  7517.                 if (!empty($savedObj)) {
  7518.                     $this->objectbuffer[] = $savedObj;
  7519.                     $font[] = $savedFont;
  7520.                     $content[] = '';
  7521.                     $contentB[] = '';
  7522.                     $cOTLdata[] = []; // mPDF 5.7.1
  7523.                     $contentWidth += $savedObj['OUTER-WIDTH'] * Mpdf::SCALE;
  7524.                 }
  7525.                 if (count($savedPreContent) > 0) {
  7526.                     for ($ix count($savedPreContent) - 1$ix >= 0$ix--) {
  7527.                         $font[] = $savedPreFont[$ix];
  7528.                         $content[] = $savedPreContent[$ix];
  7529.                         $contentB[] = $savedPreContentB[$ix];
  7530.                         if (!empty($sOTLdata)) {
  7531.                             $cOTLdata[] = $savedPreOTLdata[$ix];
  7532.                         }
  7533.                         $this->restoreFont($savedPreFont[$ix]);
  7534.                         $lbw $rbw 0// Border widths
  7535.                         if (!empty($this->spanborddet)) {
  7536.                             $lbw = (isset($this->spanborddet['L']['w']) ? $this->spanborddet['L']['w'] : 0);
  7537.                             $rbw = (isset($this->spanborddet['R']['w']) ? $this->spanborddet['R']['w'] : 0);
  7538.                         }
  7539.                         if ($ix 0) {
  7540.                             $contentWidth += $this->GetStringWidth($savedPreContent[$ix], true, (isset($savedPreOTLdata[$ix]) ? $savedPreOTLdata[$ix] : false), $this->textvar) * Mpdf::SCALE// mPDF 5.7.1
  7541.                             if (strpos($savedPreContentB[$ix], 'L') !== false) {
  7542.                                 $contentWidth += $lbw;
  7543.                             }
  7544.                             if (strpos($savedPreContentB[$ix], 'R') !== false) {
  7545.                                 $contentWidth += $rbw;
  7546.                             }
  7547.                         }
  7548.                     }
  7549.                     $savedPreContent = [];
  7550.                     $savedPreContentB = [];
  7551.                     $savedPreOTLdata = []; // mPDF 5.7.1
  7552.                     $savedPreFont = [];
  7553.                     $content[(count($content) - 1)] .= $c;
  7554.                 } else {
  7555.                     $font[] = $savedFont;
  7556.                     $content[] = $savedContent $c;
  7557.                     $contentB[] = $savedContentB;
  7558.                     $cOTLdata[] = $savedOTLdata// mPDF 5.7.1
  7559.                 }
  7560.                 $currContent = & $content[(count($content) - 1)];
  7561.                 $this->restoreFont($font[(count($font) - 1)]); // mPDF 6.0
  7562.                 /* -- CJK-FONTS -- */
  7563.                 // CJK - strip CJK space at start of line
  7564.                 // &#x3000; = \xe3\x80\x80 = CJK space
  7565.                 if ($this->checkCJK && $currContent == "\xe3\x80\x80") {
  7566.                     $currContent '';
  7567.                     if (isset($this->CurrentFont['useOTL']) && $this->CurrentFont['useOTL']) {
  7568.                         $this->otl->trimOTLdata($cOTLdata[count($cOTLdata) - 1], truefalse); // left trim U+3000
  7569.                     }
  7570.                 }
  7571.                 /* -- END CJK-FONTS -- */
  7572.                 $lbw $rbw 0// Border widths
  7573.                 if (!empty($this->spanborddet)) {
  7574.                     $lbw = (isset($this->spanborddet['L']['w']) ? $this->spanborddet['L']['w'] : 0);
  7575.                     $rbw = (isset($this->spanborddet['R']['w']) ? $this->spanborddet['R']['w'] : 0);
  7576.                 }
  7577.                 $contentWidth += $this->GetStringWidth($currContentfalse, (isset($cOTLdata[(count($cOTLdata) - 1)]) ? $cOTLdata[(count($cOTLdata) - 1)] : false), $this->textvar) * Mpdf::SCALE// mPDF 5.7.1
  7578.                 if (strpos($savedContentB'L') !== false) {
  7579.                     $contentWidth += $lbw;
  7580.                 }
  7581.                 $CJKoverflow false;
  7582.                 $hanger '';
  7583.             } // another character will fit, so add it on
  7584.             else {
  7585.                 $contentWidth += $cw;
  7586.                 $currContent .= $c;
  7587.             }
  7588.         }
  7589.         unset($content);
  7590.         unset($contentB);
  7591.     }
  7592.     // ----------------------END OF FLOWING BLOCK------------------------------------//
  7593.     /* -- CSS-IMAGE-FLOAT -- */
  7594.     // Update values if set to skipline
  7595.     function _advanceFloatMargins()
  7596.     {
  7597.         // Update floatmargins - L
  7598.         if (isset($this->floatmargins['L']) && $this->floatmargins['L']['skipline'] && $this->floatmargins['L']['y0'] != $this->y) {
  7599.             $yadj $this->$this->floatmargins['L']['y0'];
  7600.             $this->floatmargins['L']['y0'] = $this->y;
  7601.             $this->floatmargins['L']['y1'] += $yadj;
  7602.             // Update objattr in floatbuffer
  7603.             if ($this->floatbuffer[$this->floatmargins['L']['id']]['border_left']['w']) {
  7604.                 $this->floatbuffer[$this->floatmargins['L']['id']]['BORDER-Y'] += $yadj;
  7605.             }
  7606.             $this->floatbuffer[$this->floatmargins['L']['id']]['INNER-Y'] += $yadj;
  7607.             $this->floatbuffer[$this->floatmargins['L']['id']]['OUTER-Y'] += $yadj;
  7608.             // Unset values
  7609.             $this->floatbuffer[$this->floatmargins['L']['id']]['skipline'] = false;
  7610.             $this->floatmargins['L']['skipline'] = false;
  7611.             $this->floatmargins['L']['id'] = '';
  7612.         }
  7613.         // Update floatmargins - R
  7614.         if (isset($this->floatmargins['R']) && $this->floatmargins['R']['skipline'] && $this->floatmargins['R']['y0'] != $this->y) {
  7615.             $yadj $this->$this->floatmargins['R']['y0'];
  7616.             $this->floatmargins['R']['y0'] = $this->y;
  7617.             $this->floatmargins['R']['y1'] += $yadj;
  7618.             // Update objattr in floatbuffer
  7619.             if ($this->floatbuffer[$this->floatmargins['R']['id']]['border_left']['w']) {
  7620.                 $this->floatbuffer[$this->floatmargins['R']['id']]['BORDER-Y'] += $yadj;
  7621.             }
  7622.             $this->floatbuffer[$this->floatmargins['R']['id']]['INNER-Y'] += $yadj;
  7623.             $this->floatbuffer[$this->floatmargins['R']['id']]['OUTER-Y'] += $yadj;
  7624.             // Unset values
  7625.             $this->floatbuffer[$this->floatmargins['R']['id']]['skipline'] = false;
  7626.             $this->floatmargins['R']['skipline'] = false;
  7627.             $this->floatmargins['R']['id'] = '';
  7628.         }
  7629.     }
  7630.     /* -- END CSS-IMAGE-FLOAT -- */
  7631.     /* -- END HTML-CSS -- */
  7632.     function _SetTextRendering($mode)
  7633.     {
  7634.         if (!(($mode == 0) || ($mode == 1) || ($mode == 2))) {
  7635.             throw new \Mpdf\MpdfException("Text rendering mode should be 0, 1 or 2 (value : $mode)");
  7636.         }
  7637.         $tr = ($mode ' Tr');
  7638.         if ($this->page && ((isset($this->pageoutput[$this->page]['TextRendering']) && $this->pageoutput[$this->page]['TextRendering'] != $tr) || !isset($this->pageoutput[$this->page]['TextRendering']))) {
  7639.             $this->writer->write($tr);
  7640.         }
  7641.         $this->pageoutput[$this->page]['TextRendering'] = $tr;
  7642.     }
  7643.     function SetTextOutline($params = [])
  7644.     {
  7645.         if (isset($params['outline-s']) && $params['outline-s']) {
  7646.             $this->SetLineWidth($params['outline-WIDTH']);
  7647.             $this->SetDColor($params['outline-COLOR']);
  7648.             $tr = ('2 Tr');
  7649.             if ($this->page && ((isset($this->pageoutput[$this->page]['TextRendering']) && $this->pageoutput[$this->page]['TextRendering'] != $tr) || !isset($this->pageoutput[$this->page]['TextRendering']))) {
  7650.                 $this->writer->write($tr);
  7651.             }
  7652.             $this->pageoutput[$this->page]['TextRendering'] = $tr;
  7653.         } else { // Now resets all values
  7654.             $this->SetLineWidth(0.2);
  7655.             $this->SetDColor($this->colorConverter->convert(0$this->PDFAXwarnings));
  7656.             $this->_SetTextRendering(0);
  7657.             $tr = ('0 Tr');
  7658.             if ($this->page && ((isset($this->pageoutput[$this->page]['TextRendering']) && $this->pageoutput[$this->page]['TextRendering'] != $tr) || !isset($this->pageoutput[$this->page]['TextRendering']))) {
  7659.                 $this->writer->write($tr);
  7660.             }
  7661.             $this->pageoutput[$this->page]['TextRendering'] = $tr;
  7662.         }
  7663.     }
  7664.     function Image($file$x$y$w 0$h 0$type ''$link ''$paint true$constrain true$watermark false$shownoimg true$allowvector true)
  7665.     {
  7666.         $orig_srcpath $file;
  7667.         $this->GetFullPath($file);
  7668.         $info $this->imageProcessor->getImage($filetrue$allowvector$orig_srcpath);
  7669.         if (!$info && $paint) {
  7670.             $info $this->imageProcessor->getImage($this->noImageFile);
  7671.             if ($info) {
  7672.                 $file $this->noImageFile;
  7673.                 $w = ($info['w'] * (25.4 $this->img_dpi));  // 14 x 16px
  7674.                 $h = ($info['h'] * (25.4 $this->img_dpi));  // 14 x 16px
  7675.             }
  7676.         }
  7677.         if (!$info) {
  7678.             return false;
  7679.         }
  7680.         // Automatic width and height calculation if needed
  7681.         if ($w == and $h == 0) {
  7682.             /* -- IMAGES-WMF -- */
  7683.             if ($info['type'] === 'wmf') {
  7684.                 // WMF units are twips (1/20pt)
  7685.                 // divide by 20 to get points
  7686.                 // divide by k to get user units
  7687.                 $w abs($info['w']) / (20 Mpdf::SCALE);
  7688.                 $h abs($info['h']) / (20 Mpdf::SCALE);
  7689.             } else {             /* -- END IMAGES-WMF -- */
  7690.                 if ($info['type'] === 'svg') {
  7691.                     // returned SVG units are pts
  7692.                     // divide by k to get user units (mm)
  7693.                     $w abs($info['w']) / Mpdf::SCALE;
  7694.                     $h abs($info['h']) / Mpdf::SCALE;
  7695.                 } else {
  7696.                     // Put image at default image dpi
  7697.                     $w = ($info['w'] / Mpdf::SCALE) * (72 $this->img_dpi);
  7698.                     $h = ($info['h'] / Mpdf::SCALE) * (72 $this->img_dpi);
  7699.                 }
  7700.             }
  7701.         }
  7702.         if ($w == 0) {
  7703.             $w abs($h $info['w'] / $info['h']);
  7704.         }
  7705.         if ($h == 0) {
  7706.             $h abs($w $info['h'] / $info['w']);
  7707.         }
  7708.         /* -- WATERMARK -- */
  7709.         if ($watermark) {
  7710.             $maxw $this->w;
  7711.             $maxh $this->h;
  7712.             // Size = D PF or array
  7713.             if (is_array($this->watermark_size)) {
  7714.                 $w $this->watermark_size[0];
  7715.                 $h $this->watermark_size[1];
  7716.             } elseif (!is_string($this->watermark_size)) {
  7717.                 $maxw -= $this->watermark_size 2;
  7718.                 $maxh -= $this->watermark_size 2;
  7719.                 $w $maxw;
  7720.                 $h abs($w $info['h'] / $info['w']);
  7721.                 if ($h $maxh) {
  7722.                     $h $maxh;
  7723.                     $w abs($h $info['w'] / $info['h']);
  7724.                 }
  7725.             } elseif ($this->watermark_size == 'F') {
  7726.                 if ($this->ColActive) {
  7727.                     $maxw $this->- ($this->DeflMargin $this->DefrMargin);
  7728.                 } else {
  7729.                     $maxw $this->pgwidth;
  7730.                 }
  7731.                 $maxh $this->- ($this->tMargin $this->bMargin);
  7732.                 $w $maxw;
  7733.                 $h abs($w $info['h'] / $info['w']);
  7734.                 if ($h $maxh) {
  7735.                     $h $maxh;
  7736.                     $w abs($h $info['w'] / $info['h']);
  7737.                 }
  7738.             } elseif ($this->watermark_size == 'P') { // Default P
  7739.                 $w $maxw;
  7740.                 $h abs($w $info['h'] / $info['w']);
  7741.                 if ($h $maxh) {
  7742.                     $h $maxh;
  7743.                     $w abs($h $info['w'] / $info['h']);
  7744.                 }
  7745.             }
  7746.             // Automatically resize to maximum dimensions of page if too large
  7747.             if ($w $maxw) {
  7748.                 $w $maxw;
  7749.                 $h abs($w $info['h'] / $info['w']);
  7750.             }
  7751.             if ($h $maxh) {
  7752.                 $h $maxh;
  7753.                 $w abs($h $info['w'] / $info['h']);
  7754.             }
  7755.             // Position
  7756.             if (is_array($this->watermark_pos)) {
  7757.                 $x $this->watermark_pos[0];
  7758.                 $y $this->watermark_pos[1];
  7759.             } elseif ($this->watermark_pos == 'F') { // centred on printable area
  7760.                 if ($this->ColActive) { // *COLUMNS*
  7761.                     if (($this->mirrorMargins) && (($this->page) % == 0)) {
  7762.                         $xadj $this->DeflMargin $this->DefrMargin;
  7763.                     } // *COLUMNS*
  7764.                     else {
  7765.                         $xadj 0;
  7766.                     } // *COLUMNS*
  7767.                     $x = ($this->DeflMargin $xadj + ($this->- ($this->DeflMargin $this->DefrMargin)) / 2) - ($w 2); // *COLUMNS*
  7768.                 // *COLUMNS*
  7769.                 else {  // *COLUMNS*
  7770.                     $x = ($this->lMargin + ($this->pgwidth) / 2) - ($w 2);
  7771.                 } // *COLUMNS*
  7772.                 $y = ($this->tMargin + ($this->- ($this->tMargin $this->bMargin)) / 2) - ($h 2);
  7773.             } else { // default P - centred on whole page
  7774.                 $x = ($this->2) - ($w 2);
  7775.                 $y = ($this->2) - ($h 2);
  7776.             }
  7777.             /* -- IMAGES-WMF -- */
  7778.             if ($info['type'] == 'wmf') {
  7779.                 $sx $w Mpdf::SCALE $info['w'];
  7780.                 $sy = -$h Mpdf::SCALE $info['h'];
  7781.                 $outstring sprintf('q %.3F 0 0 %.3F %.3F %.3F cm /FO%d Do Q'$sx$sy$x Mpdf::SCALE $sx $info['x'], (($this->$y) * Mpdf::SCALE) - $sy $info['y'], $info['i']);
  7782.             } else {             /* -- END IMAGES-WMF -- */
  7783.                 if ($info['type'] == 'svg') {
  7784.                     $sx $w Mpdf::SCALE $info['w'];
  7785.                     $sy = -$h Mpdf::SCALE $info['h'];
  7786.                     $outstring sprintf('q %.3F 0 0 %.3F %.3F %.3F cm /FO%d Do Q'$sx$sy$x Mpdf::SCALE $sx $info['x'], (($this->$y) * Mpdf::SCALE) - $sy $info['y'], $info['i']);
  7787.                 } else {
  7788.                     $outstring sprintf("q %.3F 0 0 %.3F %.3F %.3F cm /I%d Do Q"$w Mpdf::SCALE$h Mpdf::SCALE$x Mpdf::SCALE, ($this->- ($y $h)) * Mpdf::SCALE$info['i']);
  7789.                 }
  7790.             }
  7791.             if ($this->watermarkImgBehind) {
  7792.                 $outstring $this->watermarkImgAlpha "\n" $outstring "\n" $this->SetAlpha(1'Normal'true) . "\n";
  7793.                 $this->pages[$this->page] = preg_replace('/(___BACKGROUND___PATTERNS' $this->uniqstr ')/'"\n" $outstring "\n" '\\1'$this->pages[$this->page]);
  7794.             } else {
  7795.                 $this->writer->write($outstring);
  7796.             }
  7797.             return 0;
  7798.         } // end of IF watermark
  7799.         /* -- END WATERMARK -- */
  7800.         if ($constrain) {
  7801.             // Automatically resize to maximum dimensions of page if too large
  7802.             if (isset($this->blk[$this->blklvl]['inner_width']) && $this->blk[$this->blklvl]['inner_width']) {
  7803.                 $maxw $this->blk[$this->blklvl]['inner_width'];
  7804.             } else {
  7805.                 $maxw $this->pgwidth;
  7806.             }
  7807.             if ($w $maxw) {
  7808.                 $w $maxw;
  7809.                 $h abs($w $info['h'] / $info['w']);
  7810.             }
  7811.             if ($h $this->- ($this->tMargin $this->bMargin 1)) {  // see below - +10 to avoid drawing too close to border of page
  7812.                 $h $this->- ($this->tMargin $this->bMargin 1);
  7813.                 if ($this->fullImageHeight) {
  7814.                     $h $this->fullImageHeight;
  7815.                 }
  7816.                 $w abs($h $info['w'] / $info['h']);
  7817.             }
  7818.             // Avoid drawing out of the paper(exceeding width limits).
  7819.             // if ( ($x + $w) > $this->fw ) {
  7820.             if (($x $w) > $this->w) {
  7821.                 $x $this->lMargin;
  7822.                 $y += 5;
  7823.             }
  7824.             $changedpage false;
  7825.             $oldcolumn $this->CurrCol;
  7826.             // Avoid drawing out of the page.
  7827.             if ($y $h $this->PageBreakTrigger and ! $this->InFooter and $this->AcceptPageBreak()) {
  7828.                 $this->AddPage($this->CurOrientation);
  7829.                 // Added to correct for OddEven Margins
  7830.                 $x $x $this->MarginCorrection;
  7831.                 $y $this->tMargin// mPDF 5.7.3
  7832.                 $changedpage true;
  7833.             }
  7834.             /* -- COLUMNS -- */
  7835.             // COLS
  7836.             // COLUMN CHANGE
  7837.             if ($this->CurrCol != $oldcolumn) {
  7838.                 $y $this->y0;
  7839.                 $x += $this->ChangeColumn * ($this->ColWidth $this->ColGap);
  7840.                 $this->+= $this->ChangeColumn * ($this->ColWidth $this->ColGap);
  7841.             }
  7842.             /* -- END COLUMNS -- */
  7843.         // end of IF constrain
  7844.         /* -- IMAGES-WMF -- */
  7845.         if ($info['type'] == 'wmf') {
  7846.             $sx $w Mpdf::SCALE $info['w'];
  7847.             $sy = -$h Mpdf::SCALE $info['h'];
  7848.             $outstring sprintf('q %.3F 0 0 %.3F %.3F %.3F cm /FO%d Do Q'$sx$sy$x Mpdf::SCALE $sx $info['x'], (($this->$y) * Mpdf::SCALE) - $sy $info['y'], $info['i']);
  7849.         } else {         /* -- END IMAGES-WMF -- */
  7850.             if ($info['type'] == 'svg') {
  7851.                 $sx $w Mpdf::SCALE $info['w'];
  7852.                 $sy = -$h Mpdf::SCALE $info['h'];
  7853.                 $outstring sprintf('q %.3F 0 0 %.3F %.3F %.3F cm /FO%d Do Q'$sx$sy$x Mpdf::SCALE $sx $info['x'], (($this->$y) * Mpdf::SCALE) - $sy $info['y'], $info['i']);
  7854.             } else {
  7855.                 $outstring sprintf("q %.3F 0 0 %.3F %.3F %.3F cm /I%d Do Q"$w Mpdf::SCALE$h Mpdf::SCALE$x Mpdf::SCALE, ($this->- ($y $h)) * Mpdf::SCALE$info['i']);
  7856.             }
  7857.         }
  7858.         if ($paint) {
  7859.             $this->writer->write($outstring);
  7860.             if ($link) {
  7861.                 $this->Link($x$y$w$h$link);
  7862.             }
  7863.             // Avoid writing text on top of the image. // THIS WAS OUTSIDE THE if ($paint) bit!!!!!!!!!!!!!!!!
  7864.             $this->$y $h;
  7865.         }
  7866.         // Return width-height array
  7867.         $sizesarray['WIDTH'] = $w;
  7868.         $sizesarray['HEIGHT'] = $h;
  7869.         $sizesarray['X'] = $x// Position before painting image
  7870.         $sizesarray['Y'] = $y// Position before painting image
  7871.         $sizesarray['OUTPUT'] = $outstring;
  7872.         $sizesarray['IMAGE_ID'] = $info['i'];
  7873.         $sizesarray['itype'] = $info['type'];
  7874.         $sizesarray['set-dpi'] = (isset($info['set-dpi']) ? $info['set-dpi'] : 0);
  7875.         return $sizesarray;
  7876.     }
  7877.     // =============================================================
  7878.     // =============================================================
  7879.     // =============================================================
  7880.     // =============================================================
  7881.     // =============================================================
  7882.     /* -- HTML-CSS -- */
  7883.     function _getObjAttr($t)
  7884.     {
  7885.         $c explode(Mpdf::OBJECT_IDENTIFIER$t2);
  7886.         $c explode(','$c[1], 2);
  7887.         foreach ($c as $v) {
  7888.             $v explode('='$v2);
  7889.             $sp[$v[0]] = trim($v[1], Mpdf::OBJECT_IDENTIFIER);
  7890.         }
  7891.         return (unserialize($sp['objattr']));
  7892.     }
  7893.     function inlineObject($type$x$y$objattr$Lmargin$widthUsed$maxWidth$lineHeight$paint false$is_table false)
  7894.     {
  7895.         if ($is_table) {
  7896.             $k $this->shrin_k;
  7897.         } else {
  7898.             $k 1;
  7899.         }
  7900.         // NB $x is only used when paint=true
  7901.         // Lmargin not used
  7902.         $w 0;
  7903.         if (isset($objattr['width'])) {
  7904.             $w $objattr['width'] / $k;
  7905.         }
  7906.         $h 0;
  7907.         if (isset($objattr['height'])) {
  7908.             $h abs($objattr['height'] / $k);
  7909.         }
  7910.         $widthLeft $maxWidth $widthUsed;
  7911.         $maxHeight $this->- ($this->tMargin $this->bMargin 10);
  7912.         if ($this->fullImageHeight) {
  7913.             $maxHeight $this->fullImageHeight;
  7914.         }
  7915.         // For Images
  7916.         if (isset($objattr['border_left'])) {
  7917.             $extraWidth = ($objattr['border_left']['w'] + $objattr['border_right']['w'] + $objattr['margin_left'] + $objattr['margin_right']) / $k;
  7918.             $extraHeight = ($objattr['border_top']['w'] + $objattr['border_bottom']['w'] + $objattr['margin_top'] + $objattr['margin_bottom']) / $k;
  7919.             if ($type == 'image' || $type == 'barcode' || $type == 'textcircle') {
  7920.                 $extraWidth += ($objattr['padding_left'] + $objattr['padding_right']) / $k;
  7921.                 $extraHeight += ($objattr['padding_top'] + $objattr['padding_bottom']) / $k;
  7922.             }
  7923.         }
  7924.         if (!isset($objattr['vertical-align'])) {
  7925.             if ($objattr['type'] == 'select') {
  7926.                 $objattr['vertical-align'] = 'M';
  7927.             } else {
  7928.                 $objattr['vertical-align'] = 'BS';
  7929.             }
  7930.         } // mPDF 6
  7931.         if ($type == 'image' || (isset($objattr['subtype']) && $objattr['subtype'] == 'IMAGE')) {
  7932.             if (isset($objattr['itype']) && ($objattr['itype'] == 'wmf' || $objattr['itype'] == 'svg')) {
  7933.                 $file $objattr['file'];
  7934.                 $info $this->formobjects[$file];
  7935.             } elseif (isset($objattr['file'])) {
  7936.                 $file $objattr['file'];
  7937.                 $info $this->images[$file];
  7938.             }
  7939.         }
  7940.         if ($type == 'annot' || $type == 'bookmark' || $type == 'indexentry' || $type == 'toc') {
  7941.             $w 0.00001;
  7942.             $h 0.00001;
  7943.         }
  7944.         // TEST whether need to skipline
  7945.         if (!$paint) {
  7946.             if ($type == 'hr') { // always force new line
  7947.                 if (($y $h $lineHeight $this->PageBreakTrigger) && !$this->InFooter && !$is_table) {
  7948.                     return [-2$w$h];
  7949.                 } // New page + new line
  7950.                 else {
  7951.                     return [1$w$h];
  7952.                 } // new line
  7953.             } else {
  7954.                 // LIST MARKERS    // mPDF 6  Lists
  7955.                 $displayheight $h;
  7956.                 $displaywidth $w;
  7957.                 if ($objattr['type'] == 'image' && isset($objattr['listmarker']) && $objattr['listmarker']) {
  7958.                     $displayheight 0;
  7959.                     if ($objattr['listmarkerposition'] == 'outside') {
  7960.                         $displaywidth 0;
  7961.                     }
  7962.                 }
  7963.                 if ($widthUsed && $displaywidth $widthLeft && (!$is_table || $type != 'image')) {  // New line needed
  7964.                     // mPDF 6  Lists
  7965.                     if (($y $displayheight $lineHeight $this->PageBreakTrigger) && !$this->InFooter) {
  7966.                         return [-2$w$h];
  7967.                     } // New page + new line
  7968.                     return [1$w$h]; // new line
  7969.                 } elseif ($widthUsed && $displaywidth $widthLeft && $is_table) {  // New line needed in TABLE
  7970.                     return [1$w$h]; // new line
  7971.                 // Will fit on line but NEW PAGE REQUIRED
  7972.                 elseif (($y $displayheight $this->PageBreakTrigger) && !$this->InFooter && !$is_table) {
  7973.                     return [-1$w$h];
  7974.                 } // mPDF 6  Lists
  7975.                 else {
  7976.                     return [0$w$h];
  7977.                 }
  7978.             }
  7979.         }
  7980.         if ($type == 'annot' || $type == 'bookmark' || $type == 'indexentry' || $type == 'toc') {
  7981.             $w 0.00001;
  7982.             $h 0.00001;
  7983.             $objattr['BORDER-WIDTH'] = 0;
  7984.             $objattr['BORDER-HEIGHT'] = 0;
  7985.             $objattr['BORDER-X'] = $x;
  7986.             $objattr['BORDER-Y'] = $y;
  7987.             $objattr['INNER-WIDTH'] = 0;
  7988.             $objattr['INNER-HEIGHT'] = 0;
  7989.             $objattr['INNER-X'] = $x;
  7990.             $objattr['INNER-Y'] = $y;
  7991.         }
  7992.         if ($type == 'image') {
  7993.             // Automatically resize to width remaining
  7994.             if ($w > ($widthLeft 0.0001) && !$is_table) { // mPDF 5.7.4  0.0001 to allow for rounding errors when w==maxWidth
  7995.                 $w $widthLeft;
  7996.                 $h abs($w $info['h'] / $info['w']);
  7997.             }
  7998.             $img_w $w $extraWidth;
  7999.             $img_h $h $extraHeight;
  8000.             $objattr['BORDER-WIDTH'] = $img_w $objattr['padding_left'] / $k $objattr['padding_right'] / $k + (($objattr['border_left']['w'] / $k $objattr['border_right']['w'] / $k) / 2);
  8001.             $objattr['BORDER-HEIGHT'] = $img_h $objattr['padding_top'] / $k $objattr['padding_bottom'] / $k + (($objattr['border_top']['w'] / $k $objattr['border_bottom']['w'] / $k) / 2);
  8002.             $objattr['BORDER-X'] = $x $objattr['margin_left'] / $k + (($objattr['border_left']['w'] / $k) / 2);
  8003.             $objattr['BORDER-Y'] = $y $objattr['margin_top'] / $k + (($objattr['border_top']['w'] / $k) / 2);
  8004.             $objattr['INNER-WIDTH'] = $img_w;
  8005.             $objattr['INNER-HEIGHT'] = $img_h;
  8006.             $objattr['INNER-X'] = $x $objattr['padding_left'] / $k $objattr['margin_left'] / $k + ($objattr['border_left']['w'] / $k);
  8007.             $objattr['INNER-Y'] = $y $objattr['padding_top'] / $k $objattr['margin_top'] / $k + ($objattr['border_top']['w'] / $k);
  8008.             $objattr['ID'] = $info['i'];
  8009.         }
  8010.         if ($type == 'input' && $objattr['subtype'] == 'IMAGE') {
  8011.             $img_w $w $extraWidth;
  8012.             $img_h $h $extraHeight;
  8013.             $objattr['BORDER-WIDTH'] = $img_w + (($objattr['border_left']['w'] / $k $objattr['border_right']['w'] / $k) / 2);
  8014.             $objattr['BORDER-HEIGHT'] = $img_h + (($objattr['border_top']['w'] / $k $objattr['border_bottom']['w'] / $k) / 2);
  8015.             $objattr['BORDER-X'] = $x $objattr['margin_left'] / $k + (($objattr['border_left']['w'] / $k) / 2);
  8016.             $objattr['BORDER-Y'] = $y $objattr['margin_top'] / $k + (($objattr['border_top']['w'] / $k) / 2);
  8017.             $objattr['INNER-WIDTH'] = $img_w;
  8018.             $objattr['INNER-HEIGHT'] = $img_h;
  8019.             $objattr['INNER-X'] = $x $objattr['margin_left'] / $k + ($objattr['border_left']['w'] / $k);
  8020.             $objattr['INNER-Y'] = $y $objattr['margin_top'] / $k + ($objattr['border_top']['w'] / $k);
  8021.             $objattr['ID'] = $info['i'];
  8022.         }
  8023.         if ($type == 'barcode' || $type == 'textcircle') {
  8024.             $b_w $w $extraWidth;
  8025.             $b_h $h $extraHeight;
  8026.             $objattr['BORDER-WIDTH'] = $b_w $objattr['padding_left'] / $k $objattr['padding_right'] / $k + (($objattr['border_left']['w'] / $k $objattr['border_right']['w'] / $k) / 2);
  8027.             $objattr['BORDER-HEIGHT'] = $b_h $objattr['padding_top'] / $k $objattr['padding_bottom'] / $k + (($objattr['border_top']['w'] / $k $objattr['border_bottom']['w'] / $k) / 2);
  8028.             $objattr['BORDER-X'] = $x $objattr['margin_left'] / $k + (($objattr['border_left']['w'] / $k) / 2);
  8029.             $objattr['BORDER-Y'] = $y $objattr['margin_top'] / $k + (($objattr['border_top']['w'] / $k) / 2);
  8030.             $objattr['INNER-X'] = $x $objattr['padding_left'] / $k $objattr['margin_left'] / $k + ($objattr['border_left']['w'] / $k);
  8031.             $objattr['INNER-Y'] = $y $objattr['padding_top'] / $k $objattr['margin_top'] / $k + ($objattr['border_top']['w'] / $k);
  8032.             $objattr['INNER-WIDTH'] = $b_w;
  8033.             $objattr['INNER-HEIGHT'] = $b_h;
  8034.         }
  8035.         if ($type == 'textarea') {
  8036.             // Automatically resize to width remaining
  8037.             if ($w $widthLeft && !$is_table) {
  8038.                 $w $widthLeft;
  8039.             }
  8040.             // This used to resize height to maximum remaining on page ? why. Causes problems when in table and causing a new column
  8041.             // if (($y + $h > $this->PageBreakTrigger) && !$this->InFooter) {
  8042.             //     $h=$this->h - $y - $this->bMargin;
  8043.             // }
  8044.         }
  8045.         if ($type == 'hr') {
  8046.             if ($is_table) {
  8047.                 $objattr['INNER-WIDTH'] = $maxWidth $objattr['W-PERCENT'] / 100;
  8048.                 $objattr['width'] = $objattr['INNER-WIDTH'];
  8049.                 $w $maxWidth;
  8050.             } else {
  8051.                 if ($w $maxWidth) {
  8052.                     $w $maxWidth;
  8053.                 }
  8054.                 $objattr['INNER-WIDTH'] = $w;
  8055.                 $w $maxWidth;
  8056.             }
  8057.         }
  8058.         if (($type == 'select') || ($type == 'input' && ($objattr['subtype'] == 'TEXT' || $objattr['subtype'] == 'PASSWORD'))) {
  8059.             // Automatically resize to width remaining
  8060.             if ($w $widthLeft && !$is_table) {
  8061.                 $w $widthLeft;
  8062.             }
  8063.         }
  8064.         if ($type == 'textarea' || $type == 'select' || $type == 'input') {
  8065.             if (isset($objattr['fontsize'])) {
  8066.                 $objattr['fontsize'] /= $k;
  8067.             }
  8068.             if (isset($objattr['linewidth'])) {
  8069.                 $objattr['linewidth'] /= $k;
  8070.             }
  8071.         }
  8072.         if (!isset($objattr['BORDER-Y'])) {
  8073.             $objattr['BORDER-Y'] = 0;
  8074.         }
  8075.         if (!isset($objattr['BORDER-X'])) {
  8076.             $objattr['BORDER-X'] = 0;
  8077.         }
  8078.         if (!isset($objattr['INNER-Y'])) {
  8079.             $objattr['INNER-Y'] = 0;
  8080.         }
  8081.         if (!isset($objattr['INNER-X'])) {
  8082.             $objattr['INNER-X'] = 0;
  8083.         }
  8084.         // Return width-height array
  8085.         $objattr['OUTER-WIDTH'] = $w;
  8086.         $objattr['OUTER-HEIGHT'] = $h;
  8087.         $objattr['OUTER-X'] = $x;
  8088.         $objattr['OUTER-Y'] = $y;
  8089.         return $objattr;
  8090.     }
  8091.     /* -- END HTML-CSS -- */
  8092.     // =============================================================
  8093.     // =============================================================
  8094.     // =============================================================
  8095.     // =============================================================
  8096.     // =============================================================
  8097.     function SetLineJoin($mode 0)
  8098.     {
  8099.         $s sprintf('%d j'$mode);
  8100.         if ($this->page && ((isset($this->pageoutput[$this->page]['LineJoin']) && $this->pageoutput[$this->page]['LineJoin'] != $s) || !isset($this->pageoutput[$this->page]['LineJoin']))) {
  8101.             $this->writer->write($s);
  8102.         }
  8103.         $this->pageoutput[$this->page]['LineJoin'] = $s;
  8104.     }
  8105.     function SetLineCap($mode 2)
  8106.     {
  8107.         $s sprintf('%d J'$mode);
  8108.         if ($this->page && ((isset($this->pageoutput[$this->page]['LineCap']) && $this->pageoutput[$this->page]['LineCap'] != $s) || !isset($this->pageoutput[$this->page]['LineCap']))) {
  8109.             $this->writer->write($s);
  8110.         }
  8111.         $this->pageoutput[$this->page]['LineCap'] = $s;
  8112.     }
  8113.     function SetDash($black false$white false)
  8114.     {
  8115.         if ($black and $white) {
  8116.             $s sprintf('[%.3F %.3F] 0 d'$black Mpdf::SCALE$white Mpdf::SCALE);
  8117.         } else {
  8118.             $s '[] 0 d';
  8119.         }
  8120.         if ($this->page && ((isset($this->pageoutput[$this->page]['Dash']) && $this->pageoutput[$this->page]['Dash'] != $s) || !isset($this->pageoutput[$this->page]['Dash']))) {
  8121.             $this->writer->write($s);
  8122.         }
  8123.         $this->pageoutput[$this->page]['Dash'] = $s;
  8124.     }
  8125.     function SetDisplayPreferences($preferences)
  8126.     {
  8127.         // String containing any or none of /HideMenubar/HideToolbar/HideWindowUI/DisplayDocTitle/CenterWindow/FitWindow
  8128.         $this->DisplayPreferences .= $preferences;
  8129.     }
  8130.     function Ln($h ''$collapsible 0)
  8131.     {
  8132.         // Added collapsible to allow collapsible top-margin on new page
  8133.         // Line feed; default value is last cell height
  8134.         $margin = isset($this->blk[$this->blklvl]['outer_left_margin']) ? $this->blk[$this->blklvl]['outer_left_margin'] : 0;
  8135.         $this->$this->lMargin $margin;
  8136.         if ($collapsible && ($this->== $this->tMargin) && (!$this->ColActive)) {
  8137.             $h 0;
  8138.         }
  8139.         if (is_string($h)) {
  8140.             $this->+= $this->lasth;
  8141.         } else {
  8142.             $this->+= $h;
  8143.         }
  8144.     }
  8145.     /* -- HTML-CSS -- */
  8146.     function DivLn($h$level = -3$move_y true$collapsible false$state 0)
  8147.     {
  8148.         // $state = 0 normal; 1 top; 2 bottom; 3 top and bottom
  8149.         // Used in Columns and keep-with-table i.e. "kwt"
  8150.         // writes background block by block so it can be repositioned
  8151.         // and also used in writingFlowingBlock at top and bottom of blocks to move y (not to draw/paint anything)
  8152.         // adds lines (y) where DIV bgcolors are filled in
  8153.         // this->x is returned as it was
  8154.         // allows .00001 as nominal height used for bookmarks/annotations etc.
  8155.         if ($collapsible && (sprintf("%0.4f"$this->y) == sprintf("%0.4f"$this->tMargin)) && (!$this->ColActive)) {
  8156.             return;
  8157.         }
  8158.         // mPDF 6 Columns
  8159.         //   if ($collapsible && (sprintf("%0.4f", $this->y)==sprintf("%0.4f", $this->y0)) && ($this->ColActive) && $this->CurrCol == 0) { return; }    // *COLUMNS*
  8160.         if ($collapsible && (sprintf("%0.4f"$this->y) == sprintf("%0.4f"$this->y0)) && ($this->ColActive)) {
  8161.             return;
  8162.         } // *COLUMNS*
  8163.         // Still use this method if columns or keep-with-table, as it allows repositioning later
  8164.         // otherwise, now uses PaintDivBB()
  8165.         if (!$this->ColActive && !$this->kwt) {
  8166.             if ($move_y && !$this->ColActive) {
  8167.                 $this->+= $h;
  8168.             }
  8169.             return;
  8170.         }
  8171.         if ($level == -3) {
  8172.             $level $this->blklvl;
  8173.         }
  8174.         $firstblockfill $this->GetFirstBlockFill();
  8175.         if ($firstblockfill && $this->blklvl && $this->blklvl >= $firstblockfill) {
  8176.             $last_x 0;
  8177.             $last_w 0;
  8178.             $last_fc $this->FillColor;
  8179.             $bak_x $this->x;
  8180.             $bak_h $this->divheight;
  8181.             $this->divheight 0// Temporarily turn off divheight - as Cell() uses it to check for PageBreak
  8182.             for ($blvl $firstblockfill$blvl <= $level$blvl++) {
  8183.                 $this->$this->lMargin $this->blk[$blvl]['outer_left_margin'];
  8184.                 // mPDF 6
  8185.                 if ($this->blk[$blvl]['bgcolor']) {
  8186.                     $this->SetFColor($this->blk[$blvl]['bgcolorarray']);
  8187.                 }
  8188.                 if ($last_x != ($this->lMargin $this->blk[$blvl]['outer_left_margin']) || ($last_w != $this->blk[$blvl]['width']) || $last_fc != $this->FillColor || (isset($this->blk[$blvl]['border_top']['s']) && $this->blk[$blvl]['border_top']['s']) || (isset($this->blk[$blvl]['border_bottom']['s']) && $this->blk[$blvl]['border_bottom']['s']) || (isset($this->blk[$blvl]['border_left']['s']) && $this->blk[$blvl]['border_left']['s']) || (isset($this->blk[$blvl]['border_right']['s']) && $this->blk[$blvl]['border_right']['s'])) {
  8189.                     $x $this->x;
  8190.                     $this->Cell(($this->blk[$blvl]['width']), $h''''0''1);
  8191.                     $this->$x;
  8192.                     if (!$this->keep_block_together && !$this->writingHTMLheader && !$this->writingHTMLfooter) {
  8193.                         // $state = 0 normal; 1 top; 2 bottom; 3 top and bottom
  8194.                         if ($blvl == $this->blklvl) {
  8195.                             $this->PaintDivLnBorder($state$blvl$h);
  8196.                         } else {
  8197.                             $this->PaintDivLnBorder(0$blvl$h);
  8198.                         }
  8199.                     }
  8200.                 }
  8201.                 $last_x $this->lMargin $this->blk[$blvl]['outer_left_margin'];
  8202.                 $last_w $this->blk[$blvl]['width'];
  8203.                 $last_fc $this->FillColor;
  8204.             }
  8205.             // Reset current block fill
  8206.             if (isset($this->blk[$this->blklvl]['bgcolorarray'])) {
  8207.                 $bcor $this->blk[$this->blklvl]['bgcolorarray'];
  8208.                 $this->SetFColor($bcor);
  8209.             }
  8210.             $this->$bak_x;
  8211.             $this->divheight $bak_h;
  8212.         }
  8213.         if ($move_y) {
  8214.             $this->+= $h;
  8215.         }
  8216.     }
  8217.     /* -- END HTML-CSS -- */
  8218.     function SetX($x)
  8219.     {
  8220.         // Set x position
  8221.         if ($x >= 0) {
  8222.             $this->$x;
  8223.         } else {
  8224.             $this->$this->$x;
  8225.         }
  8226.     }
  8227.     function SetY($y)
  8228.     {
  8229.         // Set y position and reset x
  8230.         $this->$this->lMargin;
  8231.         if ($y >= 0) {
  8232.             $this->$y;
  8233.         } else {
  8234.             $this->$this->$y;
  8235.         }
  8236.     }
  8237.     function SetXY($x$y)
  8238.     {
  8239.         // Set x and y positions
  8240.         $this->SetY($y);
  8241.         $this->SetX($x);
  8242.     }
  8243.     function Output($name ''$dest '')
  8244.     {
  8245.         $this->logger->debug(sprintf('PDF generated in %.6F seconds'microtime(true) - $this->time0), ['context' => LogContext::STATISTICS]);
  8246.         // Finish document if necessary
  8247.         if ($this->state 3) {
  8248.             $this->Close();
  8249.         }
  8250.         if ($this->debug && error_get_last()) {
  8251.             $e error_get_last();
  8252.             if (($e['type'] < 2048 && $e['type'] != 8) || (intval($e['type']) & intval(ini_get("error_reporting")))) {
  8253.                 throw new \Mpdf\MpdfException(
  8254.                     sprintf('Error detected. PDF file generation aborted: %s'$e['message']),
  8255.                     $e['type'],
  8256.                     1,
  8257.                     $e['file'],
  8258.                     $e['line']
  8259.                 );
  8260.             }
  8261.         }
  8262.         if (($this->PDFA || $this->PDFX) && $this->encrypted) {
  8263.             throw new \Mpdf\MpdfException('PDF/A1-b or PDF/X1-a does not permit encryption of documents.');
  8264.         }
  8265.         if (count($this->PDFAXwarnings) && (($this->PDFA && !$this->PDFAauto) || ($this->PDFX && !$this->PDFXauto))) {
  8266.             if ($this->PDFA) {
  8267.                 $standard 'PDFA/1-b';
  8268.                 $option '$mpdf->PDFAauto';
  8269.             } else {
  8270.                 $standard 'PDFX/1-a ';
  8271.                 $option '$mpdf->PDFXauto';
  8272.             }
  8273.             $this->logger->warning(sprintf('PDF could not be generated as it stands as a %s compliant file.'$standard), ['context' => LogContext::PDFA_PDFX]);
  8274.             $this->logger->warning(sprintf('These issues can be automatically fixed by mPDF using %s = true;'$option), ['context' => LogContext::PDFA_PDFX]);
  8275.             $this->logger->warning(sprintf('Action that mPDF will take to automatically force %s compliance are shown further in the log.'$standard), ['context' => LogContext::PDFA_PDFX]);
  8276.             $this->PDFAXwarnings array_unique($this->PDFAXwarnings);
  8277.             foreach ($this->PDFAXwarnings as $w) {
  8278.                 $this->logger->warning($w, ['context' => LogContext::PDFA_PDFX]);
  8279.             }
  8280.             throw new \Mpdf\MpdfException('PDFA/PDFX warnings generated. See log for further details');
  8281.         }
  8282.         $this->logger->debug(sprintf('Compiled in %.6F seconds'microtime(true) - $this->time0), ['context' => LogContext::STATISTICS]);
  8283.         $this->logger->debug(sprintf('Peak Memory usage %s MB'number_format(memory_get_peak_usage(true) / (1024 1024), 2)), ['context' => LogContext::STATISTICS]);
  8284.         $this->logger->debug(sprintf('PDF file size %s kB'number_format(strlen($this->buffer) / 1024)), ['context' => LogContext::STATISTICS]);
  8285.         $this->logger->debug(sprintf('%d fonts used'count($this->fonts)), ['context' => LogContext::STATISTICS]);
  8286.         if (is_bool($dest)) {
  8287.             $dest $dest Destination::DOWNLOAD Destination::FILE;
  8288.         }
  8289.         $dest strtoupper($dest);
  8290.         if (empty($dest)) {
  8291.             if (empty($name)) {
  8292.                 $name 'mpdf.pdf';
  8293.                 $dest Destination::INLINE;
  8294.             } else {
  8295.                 $dest Destination::FILE;
  8296.             }
  8297.         }
  8298.         switch ($dest) {
  8299.             case Destination::INLINE:
  8300.                 if (headers_sent($filename$line)) {
  8301.                     throw new \Mpdf\MpdfException(
  8302.                         sprintf('Data has already been sent to output (%s at line %s), unable to output PDF file'$filename$line)
  8303.                     );
  8304.                 }
  8305.                 if ($this->debug && !$this->allow_output_buffering && ob_get_contents()) {
  8306.                     throw new \Mpdf\MpdfException('Output has already been sent from the script - PDF file generation aborted.');
  8307.                 }
  8308.                 // We send to a browser
  8309.                 if (PHP_SAPI !== 'cli') {
  8310.                     header('Content-Type: application/pdf');
  8311.                     if (!isset($_SERVER['HTTP_ACCEPT_ENCODING']) || empty($_SERVER['HTTP_ACCEPT_ENCODING'])) {
  8312.                         // don't use length if server using compression
  8313.                         header('Content-Length: ' strlen($this->buffer));
  8314.                     }
  8315.                     header('Content-disposition: inline; filename="' $name '"');
  8316.                     header('Cache-Control: public, must-revalidate, max-age=0');
  8317.                     header('Pragma: public');
  8318.                     header('X-Generator: mPDF' . ($this->exposeVersion ? (' ' . static::VERSION) : ''));
  8319.                     header('Expires: Sat, 26 Jul 1997 05:00:00 GMT');
  8320.                     header('Last-Modified: ' gmdate('D, d M Y H:i:s') . ' GMT');
  8321.                 }
  8322.                 echo $this->buffer;
  8323.                 break;
  8324.             case Destination::DOWNLOAD:
  8325.                 if (headers_sent()) {
  8326.                     throw new \Mpdf\MpdfException('Data has already been sent to output, unable to output PDF file');
  8327.                 }
  8328.                 header('Content-Description: File Transfer');
  8329.                 header('Content-Transfer-Encoding: binary');
  8330.                 header('Cache-Control: public, must-revalidate, max-age=0');
  8331.                 header('Pragma: public');
  8332.                 header('X-Generator: mPDF' . ($this->exposeVersion ? (' ' . static::VERSION) : ''));
  8333.                 header('Expires: Sat, 26 Jul 1997 05:00:00 GMT');
  8334.                 header('Last-Modified: ' gmdate('D, d M Y H:i:s') . ' GMT');
  8335.                 header('Content-Type: application/pdf');
  8336.                 if (!isset($_SERVER['HTTP_ACCEPT_ENCODING']) || empty($_SERVER['HTTP_ACCEPT_ENCODING'])) {
  8337.                     // don't use length if server using compression
  8338.                     header('Content-Length: ' strlen($this->buffer));
  8339.                 }
  8340.                 header('Content-Disposition: attachment; filename="' $name '"');
  8341.                 echo $this->buffer;
  8342.                 break;
  8343.             case Destination::FILE:
  8344.                 $f fopen($name'wb');
  8345.                 if (!$f) {
  8346.                     throw new \Mpdf\MpdfException(sprintf('Unable to create output file %s'$name));
  8347.                 }
  8348.                 fwrite($f$this->bufferstrlen($this->buffer));
  8349.                 fclose($f);
  8350.                 break;
  8351.             case Destination::STRING_RETURN:
  8352.                 $this->cache->clearOld();
  8353.                 return $this->buffer;
  8354.             default:
  8355.                 throw new \Mpdf\MpdfException(sprintf('Incorrect output destination %s'$dest));
  8356.         }
  8357.         $this->cache->clearOld();
  8358.     }
  8359.     public function OutputBinaryData()
  8360.     {
  8361.         return $this->Output(nullDestination::STRING_RETURN);
  8362.     }
  8363.     public function OutputHttpInline()
  8364.     {
  8365.         return $this->Output(nullDestination::INLINE);
  8366.     }
  8367.     /**
  8368.      * @param string $fileName
  8369.      */
  8370.     public function OutputHttpDownload($fileName)
  8371.     {
  8372.         return $this->Output($fileNameDestination::DOWNLOAD);
  8373.     }
  8374.     /**
  8375.      * @param string $fileName
  8376.      */
  8377.     public function OutputFile($fileName)
  8378.     {
  8379.         return $this->Output($fileNameDestination::FILE);
  8380.     }
  8381.     // *****************************************************************************
  8382.     //                                                                             *
  8383.     //                             Protected methods                               *
  8384.     //                                                                             *
  8385.     // *****************************************************************************
  8386.     function _dochecks()
  8387.     {
  8388.         // Check for locale-related bug
  8389.         if (1.1 == 1) {
  8390.             throw new \Mpdf\MpdfException('Do not alter the locale before including mPDF');
  8391.         }
  8392.         // Check for decimal separator
  8393.         if (sprintf('%.1f'1.0) != '1.0') {
  8394.             setlocale(LC_NUMERIC'C');
  8395.         }
  8396.         if (ini_get('mbstring.func_overload')) {
  8397.             throw new \Mpdf\MpdfException('Mpdf cannot function properly with mbstring.func_overload enabled');
  8398.         }
  8399.         if (!function_exists('mb_substr')) {
  8400.             throw new \Mpdf\MpdfException('mbstring extension must be loaded in order to run mPDF');
  8401.         }
  8402.         if (!function_exists('mb_regex_encoding')) {
  8403.             $mamp '';
  8404.             if (strtoupper(substr(PHP_OS03)) === 'WIN') {
  8405.                 $mamp ' If using MAMP, there is a bug in its PHP build causing this.';
  8406.             }
  8407.             throw new \Mpdf\MpdfException('mbstring extension with mbregex support must be loaded in order to run mPDF.' $mamp);
  8408.         }
  8409.     }
  8410.     function _puthtmlheaders()
  8411.     {
  8412.         $this->state 2;
  8413.         $nb $this->page;
  8414.         for ($n 1$n <= $nb$n++) {
  8415.             if ($this->mirrorMargins && $n == 0) {
  8416.                 $OE 'E';
  8417.             } // EVEN
  8418.             else {
  8419.                 $OE 'O';
  8420.             }
  8421.             $this->page $n;
  8422.             $pn $this->docPageNum($n);
  8423.             if ($pn) {
  8424.                 $pnstr $this->pagenumPrefix $pn $this->pagenumSuffix;
  8425.             } else {
  8426.                 $pnstr '';
  8427.             }
  8428.             $pnt $this->docPageNumTotal($n);
  8429.             if ($pnt) {
  8430.                 $pntstr $this->nbpgPrefix $pnt $this->nbpgSuffix;
  8431.             } else {
  8432.                 $pntstr '';
  8433.             }
  8434.             if (isset($this->saveHTMLHeader[$n][$OE])) {
  8435.                 $html = isset($this->saveHTMLHeader[$n][$OE]['html']) ? $this->saveHTMLHeader[$n][$OE]['html'] : '';
  8436.                 $this->lMargin $this->saveHTMLHeader[$n][$OE]['ml'];
  8437.                 $this->rMargin $this->saveHTMLHeader[$n][$OE]['mr'];
  8438.                 $this->tMargin $this->saveHTMLHeader[$n][$OE]['mh'];
  8439.                 $this->bMargin $this->saveHTMLHeader[$n][$OE]['mf'];
  8440.                 $this->margin_header $this->saveHTMLHeader[$n][$OE]['mh'];
  8441.                 $this->margin_footer $this->saveHTMLHeader[$n][$OE]['mf'];
  8442.                 $this->$this->saveHTMLHeader[$n][$OE]['pw'];
  8443.                 $this->$this->saveHTMLHeader[$n][$OE]['ph'];
  8444.                 if ($this->$this->h) {
  8445.                     $this->hPt $this->fwPt;
  8446.                     $this->wPt $this->fhPt;
  8447.                 } else {
  8448.                     $this->hPt $this->fhPt;
  8449.                     $this->wPt $this->fwPt;
  8450.                 }
  8451.                 $rotate = (isset($this->saveHTMLHeader[$n][$OE]['rotate']) ? $this->saveHTMLHeader[$n][$OE]['rotate'] : null);
  8452.                 $this->Reset();
  8453.                 $this->pageoutput[$n] = [];
  8454.                 $this->pgwidth $this->$this->lMargin $this->rMargin;
  8455.                 $this->$this->lMargin;
  8456.                 $this->$this->margin_header;
  8457.                 // Replace of page number aliases and date format
  8458.                 $html $this->aliasReplace($html$pnstr$pntstr$nb);
  8459.                 $this->HTMLheaderPageLinks = [];
  8460.                 $this->HTMLheaderPageAnnots = [];
  8461.                 $this->HTMLheaderPageForms = [];
  8462.                 $this->pageBackgrounds = [];
  8463.                 $this->writingHTMLheader true;
  8464.                 $this->WriteHTML($htmlHTMLParserMode::HTML_HEADER_BUFFER);
  8465.                 $this->writingHTMLheader false;
  8466.                 $this->Reset();
  8467.                 $this->pageoutput[$n] = [];
  8468.                 $s $this->PrintPageBackgrounds();
  8469.                 $this->headerbuffer $s $this->headerbuffer;
  8470.                 $os '';
  8471.                 if ($rotate) {
  8472.                     $os .= sprintf('q 0 -1 1 0 0 %.3F cm ', ($this->Mpdf::SCALE));
  8473.                     // To rotate the other way i.e. Header to left of page:
  8474.                     // $os .= sprintf('q 0 1 -1 0 %.3F %.3F cm ',($this->h*Mpdf::SCALE), (($this->rMargin - $this->lMargin )*Mpdf::SCALE));
  8475.                 }
  8476.                 $os .= $this->headerbuffer;
  8477.                 if ($rotate) {
  8478.                     $os .= ' Q' "\n";
  8479.                 }
  8480.                 // Writes over the page background but behind any other output on page
  8481.                 $os preg_replace(['/\\\\/''/\$/'], ['\\\\\\\\''\\\\$'], $os);
  8482.                 $this->pages[$n] = preg_replace('/(___HEADER___MARKER' $this->uniqstr ')/'"\n" $os "\n" '\\1'$this->pages[$n]);
  8483.                 $lks $this->HTMLheaderPageLinks;
  8484.                 foreach ($lks as $lk) {
  8485.                     if ($rotate) {
  8486.                         $lw $lk[2];
  8487.                         $lh $lk[3];
  8488.                         $lk[2] = $lh;
  8489.                         $lk[3] = $lw// swap width and height
  8490.                         $ax $lk[0] / Mpdf::SCALE;
  8491.                         $ay $lk[1] / Mpdf::SCALE;
  8492.                         $bx $ay - ($lh Mpdf::SCALE);
  8493.                         $by $this->$ax;
  8494.                         $lk[0] = $bx Mpdf::SCALE;
  8495.                         $lk[1] = ($this->$by) * Mpdf::SCALE $lw;
  8496.                     }
  8497.                     $this->PageLinks[$n][] = $lk;
  8498.                 }
  8499.                 /* -- FORMS -- */
  8500.                 foreach ($this->HTMLheaderPageForms as $f) {
  8501.                     $this->form->forms[$f['n']] = $f;
  8502.                 }
  8503.                 /* -- END FORMS -- */
  8504.             }
  8505.             if (isset($this->saveHTMLFooter[$n][$OE])) {
  8506.                 $html $this->saveHTMLFooter[$this->page][$OE]['html'];
  8507.                 $this->lMargin $this->saveHTMLFooter[$n][$OE]['ml'];
  8508.                 $this->rMargin $this->saveHTMLFooter[$n][$OE]['mr'];
  8509.                 $this->tMargin $this->saveHTMLFooter[$n][$OE]['mh'];
  8510.                 $this->bMargin $this->saveHTMLFooter[$n][$OE]['mf'];
  8511.                 $this->margin_header $this->saveHTMLFooter[$n][$OE]['mh'];
  8512.                 $this->margin_footer $this->saveHTMLFooter[$n][$OE]['mf'];
  8513.                 $this->$this->saveHTMLFooter[$n][$OE]['pw'];
  8514.                 $this->$this->saveHTMLFooter[$n][$OE]['ph'];
  8515.                 if ($this->$this->h) {
  8516.                     $this->hPt $this->fwPt;
  8517.                     $this->wPt $this->fhPt;
  8518.                 } else {
  8519.                     $this->hPt $this->fhPt;
  8520.                     $this->wPt $this->fwPt;
  8521.                 }
  8522.                 $rotate = (isset($this->saveHTMLFooter[$n][$OE]['rotate']) ? $this->saveHTMLFooter[$n][$OE]['rotate'] : null);
  8523.                 $this->Reset();
  8524.                 $this->pageoutput[$n] = [];
  8525.                 $this->pgwidth $this->$this->lMargin $this->rMargin;
  8526.                 $this->$this->lMargin;
  8527.                 $top_y $this->$this->$this->margin_footer;
  8528.                 // if bottom-margin==0, corrects to avoid division by zero
  8529.                 if ($this->== $this->h) {
  8530.                     $top_y $this->= ($this->0.01);
  8531.                 }
  8532.                 // Replace of page number aliases and date format
  8533.                 $html $this->aliasReplace($html$pnstr$pntstr$nb);
  8534.                 $this->HTMLheaderPageLinks = [];
  8535.                 $this->HTMLheaderPageAnnots = [];
  8536.                 $this->HTMLheaderPageForms = [];
  8537.                 $this->pageBackgrounds = [];
  8538.                 $this->writingHTMLfooter true;
  8539.                 $this->InFooter true;
  8540.                 $this->WriteHTML($htmlHTMLParserMode::HTML_HEADER_BUFFER);
  8541.                 $this->InFooter false;
  8542.                 $this->Reset();
  8543.                 $this->pageoutput[$n] = [];
  8544.                 $fheight $this->$top_y;
  8545.                 $adj = -$fheight;
  8546.                 $s $this->PrintPageBackgrounds(-$adj);
  8547.                 $this->headerbuffer $s $this->headerbuffer;
  8548.                 $this->writingHTMLfooter false// mPDF 5.7.3  (moved after PrintPageBackgrounds so can adjust position of images in footer)
  8549.                 $os '';
  8550.                 $os .= $this->StartTransform(true) . "\n";
  8551.                 if ($rotate) {
  8552.                     $os .= sprintf('q 0 -1 1 0 0 %.3F cm ', ($this->Mpdf::SCALE));
  8553.                     // To rotate the other way i.e. Header to left of page:
  8554.                     // $os .= sprintf('q 0 1 -1 0 %.3F %.3F cm ',($this->h*Mpdf::SCALE), (($this->rMargin - $this->lMargin )*Mpdf::SCALE));
  8555.                 }
  8556.                 $os .= $this->transformTranslate(0$adjtrue) . "\n";
  8557.                 $os .= $this->headerbuffer;
  8558.                 if ($rotate) {
  8559.                     $os .= ' Q' "\n";
  8560.                 }
  8561.                 $os .= $this->StopTransform(true) . "\n";
  8562.                 // Writes over the page background but behind any other output on page
  8563.                 $os preg_replace(['/\\\\/''/\$/'], ['\\\\\\\\''\\\\$'], $os);
  8564.                 $this->pages[$n] = preg_replace('/(___HEADER___MARKER' $this->uniqstr ')/'"\n" $os "\n" '\\1'$this->pages[$n]);
  8565.                 $lks $this->HTMLheaderPageLinks;
  8566.                 foreach ($lks as $lk) {
  8567.                     $lk[1] -= $adj Mpdf::SCALE;
  8568.                     if ($rotate) {
  8569.                         $lw $lk[2];
  8570.                         $lh $lk[3];
  8571.                         $lk[2] = $lh;
  8572.                         $lk[3] = $lw// swap width and height
  8573.                         $ax $lk[0] / Mpdf::SCALE;
  8574.                         $ay $lk[1] / Mpdf::SCALE;
  8575.                         $bx $ay - ($lh Mpdf::SCALE);
  8576.                         $by $this->$ax;
  8577.                         $lk[0] = $bx Mpdf::SCALE;
  8578.                         $lk[1] = ($this->$by) * Mpdf::SCALE $lw;
  8579.                     }
  8580.                     $this->PageLinks[$n][] = $lk;
  8581.                 }
  8582.                 /* -- FORMS -- */
  8583.                 foreach ($this->HTMLheaderPageForms as $f) {
  8584.                     $f['y'] += $adj;
  8585.                     $this->form->forms[$f['n']] = $f;
  8586.                 }
  8587.                 /* -- END FORMS -- */
  8588.             }
  8589.             // Customization for https://github.com/mpdf/mpdf/issues/172
  8590.             // Replace of page number aliases and date format
  8591.             $this->pages[$n] = $this->aliasReplace($this->pages[$n], $pnstr$pntstr$nb);
  8592.         }
  8593.         $this->page $nb;
  8594.         $this->state 1;
  8595.     }
  8596.     /* -- ANNOTATIONS -- */
  8597.     function Annotation($text$x 0$y 0$icon 'Note'$author ''$subject ''$opacity 0$colarray false$popup ''$file '')
  8598.     {
  8599.         if (is_array($colarray) && count($colarray) == 3) {
  8600.             $colarray $this->colorConverter->convert('rgb(' $colarray[0] . ',' $colarray[1] . ',' $colarray[2] . ')'$this->PDFAXwarnings);
  8601.         }
  8602.         if ($colarray === false) {
  8603.             $colarray $this->colorConverter->convert('yellow'$this->PDFAXwarnings);
  8604.         }
  8605.         if ($x == 0) {
  8606.             $x $this->x;
  8607.         }
  8608.         if ($y == 0) {
  8609.             $y $this->y;
  8610.         }
  8611.         $page $this->page;
  8612.         if ($page 1) { // Document has not been started - assume it's for first page
  8613.             $page 1;
  8614.             if ($x == 0) {
  8615.                 $x $this->lMargin;
  8616.             }
  8617.             if ($y == 0) {
  8618.                 $y $this->tMargin;
  8619.             }
  8620.         }
  8621.         if ($this->PDFA || $this->PDFX) {
  8622.             if (($this->PDFA && !$this->PDFAauto) || ($this->PDFX && !$this->PDFXauto)) {
  8623.                 $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)";
  8624.             }
  8625.             $x = ($this->w) - $this->rMargin 0.66;
  8626.         }
  8627.         if (!$this->annotMargin) {
  8628.             $y -= $this->FontSize 2;
  8629.         }
  8630.         if (!$opacity && $this->annotMargin) {
  8631.             $opacity 1;
  8632.         } elseif (!$opacity) {
  8633.             $opacity $this->annotOpacity;
  8634.         }
  8635.         $an = ['txt' => $text'x' => $x'y' => $y'opt' => ['Icon' => $icon'T' => $author'Subj' => $subject'C' => $colarray'CA' => $opacity'popup' => $popup'file' => $file]];
  8636.         if ($this->keep_block_together) { // don't write yet
  8637.             return;
  8638.         } elseif ($this->table_rotate) {
  8639.             $this->tbrot_Annots[$this->page][] = $an;
  8640.             return;
  8641.         } elseif ($this->kwt) {
  8642.             $this->kwt_Annots[$this->page][] = $an;
  8643.             return;
  8644.         }
  8645.         if ($this->writingHTMLheader || $this->writingHTMLfooter) {
  8646.             $this->HTMLheaderPageAnnots[] = $an;
  8647.             return;
  8648.         }
  8649.         // Put an Annotation on the page
  8650.         $this->PageAnnots[$page][] = $an;
  8651.         /* -- COLUMNS -- */
  8652.         // Save cross-reference to Column buffer
  8653.         $ref = isset($this->PageAnnots[$this->page]) ? (count($this->PageAnnots[$this->page]) - 1) : -1;
  8654.         $this->columnAnnots[$this->CurrCol][intval($this->x)][intval($this->y)] = $ref;
  8655.         /* -- END COLUMNS -- */
  8656.     }
  8657.     /* -- END ANNOTATIONS -- */
  8658.     function _enddoc()
  8659.     {
  8660.         // @log Writing Headers & Footers
  8661.         $this->_puthtmlheaders();
  8662.         // @log Writing Pages
  8663.         // Remove references to unused fonts (usually default font)
  8664.         foreach ($this->fonts as $fk => $font) {
  8665.             if (isset($font['type']) && $font['type'] == 'TTF' && !$font['used']) {
  8666.                 if ($font['sip'] || $font['smp']) {
  8667.                     foreach ($font['subsetfontids'] as $k => $fid) {
  8668.                         foreach ($this->pages as $pn => $page) {
  8669.                             $this->pages[$pn] = preg_replace('/\s\/F' $fid ' \d[\d.]* Tf\s/is'' '$this->pages[$pn]);
  8670.                         }
  8671.                     }
  8672.                 } else {
  8673.                     foreach ($this->pages as $pn => $page) {
  8674.                         $this->pages[$pn] = preg_replace('/\s\/F' $font['i'] . ' \d[\d.]* Tf\s/is'' '$this->pages[$pn]);
  8675.                     }
  8676.                 }
  8677.             }
  8678.         }
  8679.         if (count($this->layers)) {
  8680.             foreach ($this->pages as $pn => $page) {
  8681.                 preg_match_all('/\/OCZ-index \/ZI(\d+) BDC(.*?)(EMCZ)-index/is'$this->pages[$pn], $m1);
  8682.                 preg_match_all('/\/OCBZ-index \/ZI(\d+) BDC(.*?)(EMCBZ)-index/is'$this->pages[$pn], $m2);
  8683.                 preg_match_all('/\/OCGZ-index \/ZI(\d+) BDC(.*?)(EMCGZ)-index/is'$this->pages[$pn], $m3);
  8684.                 $m = [];
  8685.                 for ($i 0$i 4$i++) {
  8686.                     $m[$i] = array_merge($m1[$i], $m2[$i], $m3[$i]);
  8687.                 }
  8688.                 if (count($m[0])) {
  8689.                     $sortarr = [];
  8690.                     for ($i 0$i count($m[0]); $i++) {
  8691.                         $key $m[1][$i] * 2;
  8692.                         if ($m[3][$i] == 'EMCZ') {
  8693.                             $key +=2// background first then gradient then normal
  8694.                         } elseif ($m[3][$i] == 'EMCGZ') {
  8695.                             $key +=1;
  8696.                         }
  8697.                         $sortarr[$i] = $key;
  8698.                     }
  8699.                     asort($sortarr);
  8700.                     foreach ($sortarr as $i => $k) {
  8701.                         $this->pages[$pn] = str_replace($m[0][$i], ''$this->pages[$pn]);
  8702.                         $this->pages[$pn] .= "\n" $m[0][$i] . "\n";
  8703.                     }
  8704.                     $this->pages[$pn] = preg_replace('/\/OC[BG]{0,1}Z-index \/ZI(\d+) BDC/is''/OC /ZI\\1 BDC '$this->pages[$pn]);
  8705.                     $this->pages[$pn] = preg_replace('/EMC[BG]{0,1}Z-index/is''EMC'$this->pages[$pn]);
  8706.                 }
  8707.             }
  8708.         }
  8709.         $this->pageWriter->writePages();
  8710.         // @log Writing document resources
  8711.         $this->resourceWriter->writeResources();
  8712.         // Info
  8713.         $this->writer->object();
  8714.         $this->InfoRoot $this->n;
  8715.         $this->writer->write('<<');
  8716.         // @log Writing document info
  8717.         $this->metadataWriter->writeInfo();
  8718.         $this->writer->write('>>');
  8719.         $this->writer->write('endobj');
  8720.         // METADATA
  8721.         if ($this->PDFA || $this->PDFX) {
  8722.             $this->metadataWriter->writeMetadata();
  8723.         }
  8724.         // OUTPUTINTENT
  8725.         if ($this->PDFA || $this->PDFX || $this->ICCProfile) {
  8726.             $this->metadataWriter->writeOutputIntent();
  8727.         }
  8728.         // Associated files
  8729.         if ($this->associatedFiles) {
  8730.             $this->metadataWriter->writeAssociatedFiles();
  8731.         }
  8732.         // Catalog
  8733.         $this->writer->object();
  8734.         $this->writer->write('<<');
  8735.         // @log Writing document catalog
  8736.         $this->metadataWriter->writeCatalog();
  8737.         $this->writer->write('>>');
  8738.         $this->writer->write('endobj');
  8739.         // Cross-ref
  8740.         $o strlen($this->buffer);
  8741.         $this->writer->write('xref');
  8742.         $this->writer->write('0 ' . ($this->1));
  8743.         $this->writer->write('0000000000 65535 f ');
  8744.         for ($i 1$i <= $this->n$i++) {
  8745.             $this->writer->write(sprintf('%010d 00000 n '$this->offsets[$i]));
  8746.         }
  8747.         // Trailer
  8748.         $this->writer->write('trailer');
  8749.         $this->writer->write('<<');
  8750.         $this->metadataWriter->writeTrailer();
  8751.         $this->writer->write('>>');
  8752.         $this->writer->write('startxref');
  8753.         $this->writer->write($o);
  8754.         $this->buffer .= '%%EOF';
  8755.         $this->state 3;
  8756.     }
  8757.     function _beginpage(
  8758.         $orientation,
  8759.         $mgl '',
  8760.         $mgr '',
  8761.         $mgt '',
  8762.         $mgb '',
  8763.         $mgh '',
  8764.         $mgf '',
  8765.         $ohname '',
  8766.         $ehname '',
  8767.         $ofname '',
  8768.         $efname '',
  8769.         $ohvalue 0,
  8770.         $ehvalue 0,
  8771.         $ofvalue 0,
  8772.         $efvalue 0,
  8773.         $pagesel '',
  8774.         $newformat ''
  8775.     ) {
  8776.         if (!($pagesel && $this->page == && (sprintf("%0.4f"$this->y) == sprintf("%0.4f"$this->tMargin)))) {
  8777.             $this->page++;
  8778.             $this->pages[$this->page] = '';
  8779.         }
  8780.         $this->state 2;
  8781.         $resetHTMLHeadersrequired false;
  8782.         if ($newformat) {
  8783.             $this->_setPageSize($newformat$orientation);
  8784.         }
  8785.         /* -- CSS-PAGE -- */
  8786.         // Paged media (page-box)
  8787.         if ($pagesel || $this->page_box['using']) {
  8788.             if ($pagesel || $this->page === 1) {
  8789.                 $first true;
  8790.             } else {
  8791.                 $first false;
  8792.             }
  8793.             if ($this->mirrorMargins && ($this->page === 0)) {
  8794.                 $oddEven 'E';
  8795.             } else {
  8796.                 $oddEven 'O';
  8797.             }
  8798.             if ($pagesel) {
  8799.                 $psel $pagesel;
  8800.             } elseif ($this->page_box['current']) {
  8801.                 $psel $this->page_box['current'];
  8802.             } else {
  8803.                 $psel '';
  8804.             }
  8805.             list($orientation$mgl$mgr$mgt$mgb$mgh$mgf$hname$fname$bg$resetpagenum$pagenumstyle$suppress$marks$newformat) = $this->SetPagedMediaCSS($psel$first$oddEven);
  8806.             if ($this->mirrorMargins && ($this->page === 0)) {
  8807.                 if ($hname) {
  8808.                     $ehvalue 1;
  8809.                     $ehname $hname;
  8810.                 } else {
  8811.                     $ehvalue = -1;
  8812.                 }
  8813.                 if ($fname) {
  8814.                     $efvalue 1;
  8815.                     $efname $fname;
  8816.                 } else {
  8817.                     $efvalue = -1;
  8818.                 }
  8819.             } else {
  8820.                 if ($hname) {
  8821.                     $ohvalue 1;
  8822.                     $ohname $hname;
  8823.                 } else {
  8824.                     $ohvalue = -1;
  8825.                 }
  8826.                 if ($fname) {
  8827.                     $ofvalue 1;
  8828.                     $ofname $fname;
  8829.                 } else {
  8830.                     $ofvalue = -1;
  8831.                 }
  8832.             }
  8833.             if ($resetpagenum || $pagenumstyle || $suppress) {
  8834.                 $this->PageNumSubstitutions[] = ['from' => ($this->page), 'reset' => $resetpagenum'type' => $pagenumstyle'suppress' => $suppress];
  8835.             }
  8836.             // PAGED MEDIA - CROP / CROSS MARKS from @PAGE
  8837.             $this->show_marks $marks;
  8838.             // Background color
  8839.             if (isset($bg['BACKGROUND-COLOR'])) {
  8840.                 $cor $this->colorConverter->convert($bg['BACKGROUND-COLOR'], $this->PDFAXwarnings);
  8841.                 if ($cor) {
  8842.                     $this->bodyBackgroundColor $cor;
  8843.                 }
  8844.             } else {
  8845.                 $this->bodyBackgroundColor false;
  8846.             }
  8847.             /* -- BACKGROUNDS -- */
  8848.             if (isset($bg['BACKGROUND-GRADIENT'])) {
  8849.                 $this->bodyBackgroundGradient $bg['BACKGROUND-GRADIENT'];
  8850.             } else {
  8851.                 $this->bodyBackgroundGradient false;
  8852.             }
  8853.             // Tiling Patterns
  8854.             if (isset($bg['BACKGROUND-IMAGE']) && $bg['BACKGROUND-IMAGE']) {
  8855.                 $ret $this->SetBackground($bg$this->pgwidth);
  8856.                 if ($ret) {
  8857.                     $this->bodyBackgroundImage $ret;
  8858.                 }
  8859.             } else {
  8860.                 $this->bodyBackgroundImage false;
  8861.             }
  8862.             /* -- END BACKGROUNDS -- */
  8863.             $this->page_box['current'] = $psel;
  8864.             $this->page_box['using'] = true;
  8865.         }
  8866.         /* -- END CSS-PAGE -- */
  8867.         // Page orientation
  8868.         if (!$orientation) {
  8869.             $orientation $this->DefOrientation;
  8870.         } else {
  8871.             $orientation strtoupper(substr($orientation01));
  8872.             if ($orientation != $this->DefOrientation) {
  8873.                 $this->OrientationChanges[$this->page] = true;
  8874.             }
  8875.         }
  8876.         if ($orientation !== $this->CurOrientation || $newformat) {
  8877.             // Change orientation
  8878.             if ($orientation === 'P') {
  8879.                 $this->wPt $this->fwPt;
  8880.                 $this->hPt $this->fhPt;
  8881.                 $this->$this->fw;
  8882.                 $this->$this->fh;
  8883.                 if (($this->forcePortraitHeaders || $this->forcePortraitMargins) && $this->DefOrientation === 'P') {
  8884.                     $this->tMargin $this->orig_tMargin;
  8885.                     $this->bMargin $this->orig_bMargin;
  8886.                     $this->DeflMargin $this->orig_lMargin;
  8887.                     $this->DefrMargin $this->orig_rMargin;
  8888.                     $this->margin_header $this->orig_hMargin;
  8889.                     $this->margin_footer $this->orig_fMargin;
  8890.                 } else {
  8891.                     $resetHTMLHeadersrequired true;
  8892.                 }
  8893.             } else {
  8894.                 $this->wPt $this->fhPt;
  8895.                 $this->hPt $this->fwPt;
  8896.                 $this->$this->fh;
  8897.                 $this->$this->fw;
  8898.                 if (($this->forcePortraitHeaders || $this->forcePortraitMargins) && $this->DefOrientation === 'P') {
  8899.                     $this->tMargin $this->orig_lMargin;
  8900.                     $this->bMargin $this->orig_rMargin;
  8901.                     $this->DeflMargin $this->orig_bMargin;
  8902.                     $this->DefrMargin $this->orig_tMargin;
  8903.                     $this->margin_header $this->orig_hMargin;
  8904.                     $this->margin_footer $this->orig_fMargin;
  8905.                 } else {
  8906.                     $resetHTMLHeadersrequired true;
  8907.                 }
  8908.             }
  8909.             $this->CurOrientation $orientation;
  8910.             $this->ResetMargins();
  8911.             $this->pgwidth $this->$this->lMargin $this->rMargin;
  8912.             $this->PageBreakTrigger $this->$this->bMargin;
  8913.         }
  8914.         $this->pageDim[$this->page]['w'] = $this->w;
  8915.         $this->pageDim[$this->page]['h'] = $this->h;
  8916.         $this->pageDim[$this->page]['outer_width_LR'] = $this->page_box['outer_width_LR'] ?: 0;
  8917.         $this->pageDim[$this->page]['outer_width_TB'] = $this->page_box['outer_width_TB'] ?: 0;
  8918.         if (!$this->page_box['outer_width_LR'] && !$this->page_box['outer_width_TB']) {
  8919.             $this->pageDim[$this->page]['bleedMargin'] = 0;
  8920.         } elseif ($this->bleedMargin <= $this->page_box['outer_width_LR'] && $this->bleedMargin <= $this->page_box['outer_width_TB']) {
  8921.             $this->pageDim[$this->page]['bleedMargin'] = $this->bleedMargin;
  8922.         } else {
  8923.             $this->pageDim[$this->page]['bleedMargin'] = min($this->page_box['outer_width_LR'], $this->page_box['outer_width_TB']) - 0.01;
  8924.         }
  8925.         // If Page Margins are re-defined
  8926.         // strlen()>0 is used to pick up (integer) 0, (string) '0', or set value
  8927.         if ((strlen($mgl) > && $this->DeflMargin != $mgl) || (strlen($mgr) > && $this->DefrMargin != $mgr) || (strlen($mgt) > && $this->tMargin != $mgt) || (strlen($mgb) > && $this->bMargin != $mgb) || (strlen($mgh) > && $this->margin_header != $mgh) || (strlen($mgf) > && $this->margin_footer != $mgf)) {
  8928.             if (strlen($mgl) > 0) {
  8929.                 $this->DeflMargin $mgl;
  8930.             }
  8931.             if (strlen($mgr) > 0) {
  8932.                 $this->DefrMargin $mgr;
  8933.             }
  8934.             if (strlen($mgt) > 0) {
  8935.                 $this->tMargin $mgt;
  8936.             }
  8937.             if (strlen($mgb) > 0) {
  8938.                 $this->bMargin $mgb;
  8939.             }
  8940.             if (strlen($mgh) > 0) {
  8941.                 $this->margin_header $mgh;
  8942.             }
  8943.             if (strlen($mgf) > 0) {
  8944.                 $this->margin_footer $mgf;
  8945.             }
  8946.             $this->ResetMargins();
  8947.             $this->SetAutoPageBreak($this->autoPageBreak$this->bMargin);
  8948.             $this->pgwidth $this->$this->lMargin $this->rMargin;
  8949.             $resetHTMLHeadersrequired true;
  8950.         }
  8951.         $this->ResetMargins();
  8952.         $this->pgwidth $this->$this->lMargin $this->rMargin;
  8953.         $this->SetAutoPageBreak($this->autoPageBreak$this->bMargin);
  8954.         // Reset column top margin
  8955.         $this->y0 $this->tMargin;
  8956.         $this->$this->lMargin;
  8957.         $this->$this->tMargin;
  8958.         $this->FontFamily '';
  8959.         // HEADERS AND FOOTERS    // mPDF 6
  8960.         if ($ohvalue || strtoupper($ohvalue) == 'OFF') {
  8961.             $this->HTMLHeader '';
  8962.             $resetHTMLHeadersrequired true;
  8963.         } elseif ($ohname && $ohvalue 0) {
  8964.             if (preg_match('/^html_(.*)$/i'$ohname$n)) {
  8965.                 $name $n[1];
  8966.             } else {
  8967.                 $name $ohname;
  8968.             }
  8969.             if (isset($this->pageHTMLheaders[$name])) {
  8970.                 $this->HTMLHeader $this->pageHTMLheaders[$name];
  8971.             } else {
  8972.                 $this->HTMLHeader '';
  8973.             }
  8974.             $resetHTMLHeadersrequired true;
  8975.         }
  8976.         if ($ehvalue || strtoupper($ehvalue) == 'OFF') {
  8977.             $this->HTMLHeaderE '';
  8978.             $resetHTMLHeadersrequired true;
  8979.         } elseif ($ehname && $ehvalue 0) {
  8980.             if (preg_match('/^html_(.*)$/i'$ehname$n)) {
  8981.                 $name $n[1];
  8982.             } else {
  8983.                 $name $ehname;
  8984.             }
  8985.             if (isset($this->pageHTMLheaders[$name])) {
  8986.                 $this->HTMLHeaderE $this->pageHTMLheaders[$name];
  8987.             } else {
  8988.                 $this->HTMLHeaderE '';
  8989.             }
  8990.             $resetHTMLHeadersrequired true;
  8991.         }
  8992.         if ($ofvalue || strtoupper($ofvalue) == 'OFF') {
  8993.             $this->HTMLFooter '';
  8994.             $resetHTMLHeadersrequired true;
  8995.         } elseif ($ofname && $ofvalue 0) {
  8996.             if (preg_match('/^html_(.*)$/i'$ofname$n)) {
  8997.                 $name $n[1];
  8998.             } else {
  8999.                 $name $ofname;
  9000.             }
  9001.             if (isset($this->pageHTMLfooters[$name])) {
  9002.                 $this->HTMLFooter $this->pageHTMLfooters[$name];
  9003.             } else {
  9004.                 $this->HTMLFooter '';
  9005.             }
  9006.             $resetHTMLHeadersrequired true;
  9007.         }
  9008.         if ($efvalue || strtoupper($efvalue) == 'OFF') {
  9009.             $this->HTMLFooterE '';
  9010.             $resetHTMLHeadersrequired true;
  9011.         } elseif ($efname && $efvalue 0) {
  9012.             if (preg_match('/^html_(.*)$/i'$efname$n)) {
  9013.                 $name $n[1];
  9014.             } else {
  9015.                 $name $efname;
  9016.             }
  9017.             if (isset($this->pageHTMLfooters[$name])) {
  9018.                 $this->HTMLFooterE $this->pageHTMLfooters[$name];
  9019.             } else {
  9020.                 $this->HTMLFooterE '';
  9021.             }
  9022.             $resetHTMLHeadersrequired true;
  9023.         }
  9024.         if ($resetHTMLHeadersrequired) {
  9025.             $this->SetHTMLHeader($this->HTMLHeader);
  9026.             $this->SetHTMLHeader($this->HTMLHeaderE'E');
  9027.             $this->SetHTMLFooter($this->HTMLFooter);
  9028.             $this->SetHTMLFooter($this->HTMLFooterE'E');
  9029.         }
  9030.         if (($this->mirrorMargins) && (($this->page) % == 0)) { // EVEN
  9031.             $this->_setAutoHeaderHeight($this->HTMLHeaderE);
  9032.             $this->_setAutoFooterHeight($this->HTMLFooterE);
  9033.         } else { // ODD or DEFAULT
  9034.             $this->_setAutoHeaderHeight($this->HTMLHeader);
  9035.             $this->_setAutoFooterHeight($this->HTMLFooter);
  9036.         }
  9037.         // Reset column top margin
  9038.         $this->y0 $this->tMargin;
  9039.         $this->$this->lMargin;
  9040.         $this->$this->tMargin;
  9041.     }
  9042.     // mPDF 6
  9043.     function _setAutoHeaderHeight(&$htmlh)
  9044.     {
  9045.         /* When the setAutoTopMargin option is set to pad/stretch, only apply auto header height when a header exists */
  9046.         if ($this->HTMLHeader === '' && $this->HTMLHeaderE === '') {
  9047.             return;
  9048.         }
  9049.         if ($this->setAutoTopMargin == 'pad') {
  9050.             if (isset($htmlh['h']) && $htmlh['h']) {
  9051.                 $h $htmlh['h'];
  9052.             } // 5.7.3
  9053.             else {
  9054.                 $h 0;
  9055.             }
  9056.             $this->tMargin $this->margin_header $h $this->orig_tMargin;
  9057.         } elseif ($this->setAutoTopMargin == 'stretch') {
  9058.             if (isset($htmlh['h']) && $htmlh['h']) {
  9059.                 $h $htmlh['h'];
  9060.             } // 5.7.3
  9061.             else {
  9062.                 $h 0;
  9063.             }
  9064.             $this->tMargin max($this->orig_tMargin$this->margin_header $h $this->autoMarginPadding);
  9065.         }
  9066.     }
  9067.     // mPDF 6
  9068.     function _setAutoFooterHeight(&$htmlf)
  9069.     {
  9070.         /* When the setAutoTopMargin option is set to pad/stretch, only apply auto footer height when a footer exists */
  9071.         if ($this->HTMLFooter === '' && $this->HTMLFooterE === '') {
  9072.             return;
  9073.         }
  9074.         if ($this->setAutoBottomMargin == 'pad') {
  9075.             if (isset($htmlf['h']) && $htmlf['h']) {
  9076.                 $h $htmlf['h'];
  9077.             } // 5.7.3
  9078.             else {
  9079.                 $h 0;
  9080.             }
  9081.             $this->bMargin $this->margin_footer $h $this->orig_bMargin;
  9082.             $this->PageBreakTrigger $this->$this->bMargin;
  9083.         } elseif ($this->setAutoBottomMargin == 'stretch') {
  9084.             if (isset($htmlf['h']) && $htmlf['h']) {
  9085.                 $h $htmlf['h'];
  9086.             } // 5.7.3
  9087.             else {
  9088.                 $h 0;
  9089.             }
  9090.             $this->bMargin max($this->orig_bMargin$this->margin_footer $h $this->autoMarginPadding);
  9091.             $this->PageBreakTrigger $this->$this->bMargin;
  9092.         }
  9093.     }
  9094.     function _endpage()
  9095.     {
  9096.         /* -- CSS-IMAGE-FLOAT -- */
  9097.         $this->printfloatbuffer();
  9098.         /* -- END CSS-IMAGE-FLOAT -- */
  9099.         if ($this->visibility != 'visible') {
  9100.             $this->SetVisibility('visible');
  9101.         }
  9102.         $this->EndLayer();
  9103.         // End of page contents
  9104.         $this->state 1;
  9105.     }
  9106.     function _dounderline($x$y$txt$OTLdata false$textvar 0)
  9107.     {
  9108.         // Now print line exactly where $y secifies - called from Text() and Cell() - adjust  position there
  9109.         // WORD SPACING
  9110.         $w = ($this->GetStringWidth($txtfalse$OTLdata$textvar) * Mpdf::SCALE) + ($this->charspacing mb_strlen($txt$this->mb_enc)) + ( $this->ws mb_substr_count($txt' '$this->mb_enc));
  9111.         // Draw a line
  9112.         return sprintf('%.3F %.3F m %.3F %.3F l S'$x Mpdf::SCALE, ($this->$y) * Mpdf::SCALE, ($x Mpdf::SCALE) + $w, ($this->$y) * Mpdf::SCALE);
  9113.     }
  9114.     /* -- WATERMARK -- */
  9115.     // add a watermark
  9116.     function watermark($texte$angle 45$fontsize 96$alpha 0.2)
  9117.     {
  9118.         if ($this->PDFA || $this->PDFX) {
  9119.             throw new \Mpdf\MpdfException('PDFA and PDFX do not permit transparency, so mPDF does not allow Watermarks!');
  9120.         }
  9121.         if (!$this->watermark_font) {
  9122.             $this->watermark_font $this->default_font;
  9123.         }
  9124.         $this->SetFont($this->watermark_font"B"$fontsizefalse); // Don't output
  9125.         $texte $this->purify_utf8_text($texte);
  9126.         if ($this->text_input_as_HTML) {
  9127.             $texte $this->all_entities_to_utf8($texte);
  9128.         }
  9129.         if ($this->usingCoreFont) {
  9130.             $texte mb_convert_encoding($texte$this->mb_enc'UTF-8');
  9131.         }
  9132.         // DIRECTIONALITY
  9133.         if (preg_match("/([" $this->pregRTLchars "])/u"$texte)) {
  9134.             $this->biDirectional true;
  9135.         } // *OTL*
  9136.         $textvar 0;
  9137.         $save_OTLtags $this->OTLtags;
  9138.         $this->OTLtags = [];
  9139.         if ($this->useKerning) {
  9140.             if ($this->CurrentFont['haskernGPOS']) {
  9141.                 $this->OTLtags['Plus'] .= ' kern';
  9142.             } else {
  9143.                 $textvar = ($textvar TextVars::FC_KERNING);
  9144.             }
  9145.         }
  9146.         /* -- OTL -- */
  9147.         // Use OTL OpenType Table Layout - GSUB & GPOS
  9148.         if (isset($this->CurrentFont['useOTL']) && $this->CurrentFont['useOTL']) {
  9149.             $texte $this->otl->applyOTL($texte$this->CurrentFont['useOTL']);
  9150.             $OTLdata $this->otl->OTLdata;
  9151.         }
  9152.         /* -- END OTL -- */
  9153.         $this->OTLtags $save_OTLtags;
  9154.         $this->magic_reverse_dir($texte$this->directionality$OTLdata);
  9155.         $this->SetAlpha($alpha);
  9156.         $color $this->watermarkTextObject $this->watermarkTextObject->getColor() : 0;
  9157.         $this->SetTColor($this->colorConverter->convert($color$this->PDFAXwarnings));
  9158.         $szfont $fontsize;
  9159.         $loop 0;
  9160.         $maxlen = (min($this->w$this->h) ); // sets max length of text as 7/8 width/height of page
  9161.         while ($loop == 0) {
  9162.             $this->SetFont($this->watermark_font"B"$szfontfalse); // Don't output
  9163.             $offset = ((sin(deg2rad($angle))) * ($szfont Mpdf::SCALE));
  9164.             $strlen $this->GetStringWidth($textetrue$OTLdata$textvar);
  9165.             if ($strlen $maxlen $offset) {
  9166.                 $szfont --;
  9167.             } else {
  9168.                 $loop ++;
  9169.             }
  9170.         }
  9171.         $this->SetFont($this->watermark_font"B"$szfont 0.1truetrue); // Output The -0.1 is because SetFont above is not written to PDF
  9172.         // Repeating it will not output anything as mPDF thinks it is set
  9173.         $adj = ((cos(deg2rad($angle))) * ($strlen 2));
  9174.         $opp = ((sin(deg2rad($angle))) * ($strlen 2));
  9175.         $wx = ($this->2) - $adj $offset 3;
  9176.         $wy = ($this->2) + $opp;
  9177.         $this->Rotate($angle$wx$wy);
  9178.         $this->Text($wx$wy$texte$OTLdata$textvar);
  9179.         $this->Rotate(0);
  9180.         $this->SetTColor($this->colorConverter->convert(0$this->PDFAXwarnings));
  9181.         $this->SetAlpha(1);
  9182.     }
  9183.     function watermarkImg($src$alpha 0.2)
  9184.     {
  9185.         if ($this->PDFA || $this->PDFX) {
  9186.             throw new \Mpdf\MpdfException('PDFA and PDFX do not permit transparency, so mPDF does not allow Watermarks!');
  9187.         }
  9188.         if ($this->watermarkImgBehind) {
  9189.             $this->watermarkImgAlpha $this->SetAlpha($alpha'Normal'true);
  9190.         } else {
  9191.             $this->SetAlpha($alpha$this->watermarkImgAlphaBlend);
  9192.         }
  9193.         $this->Image($src0000''''truetruetrue);
  9194.         if (!$this->watermarkImgBehind) {
  9195.             $this->SetAlpha(1);
  9196.         }
  9197.     }
  9198.     /* -- END WATERMARK -- */
  9199.     function Rotate($angle$x = -1$y = -1)
  9200.     {
  9201.         if ($x == -1) {
  9202.             $x $this->x;
  9203.         }
  9204.         if ($y == -1) {
  9205.             $y $this->y;
  9206.         }
  9207.         if ($this->angle != 0) {
  9208.             $this->writer->write('Q');
  9209.         }
  9210.         $this->angle $angle;
  9211.         if ($angle != 0) {
  9212.             $angle*=M_PI 180;
  9213.             $c cos($angle);
  9214.             $s sin($angle);
  9215.             $cx $x Mpdf::SCALE;
  9216.             $cy = ($this->$y) * Mpdf::SCALE;
  9217.             $this->writer->write(sprintf('q %.5F %.5F %.5F %.5F %.3F %.3F cm 1 0 0 1 %.3F %.3F cm'$c$s, -$s$c$cx$cy, -$cx, -$cy));
  9218.         }
  9219.     }
  9220.     function CircularText($x$y$r$text$align 'top'$fontfamily ''$fontsize 0$fontstyle ''$kerning 120$fontwidth 100$divider '')
  9221.     {
  9222.         if (empty($this->directWrite)) {
  9223.             $this->directWrite = new DirectWrite($this$this->otl$this->sizeConverter$this->colorConverter);
  9224.         }
  9225.         $this->directWrite->CircularText($x$y$r$text$align$fontfamily$fontsize$fontstyle$kerning$fontwidth$divider);
  9226.     }
  9227.     // From Invoice
  9228.     function RoundedRect($x$y$w$h$r$style '')
  9229.     {
  9230.         $hp $this->h;
  9231.         if ($style == 'F') {
  9232.             $op 'f';
  9233.         } elseif ($style == 'FD' or $style == 'DF') {
  9234.             $op 'B';
  9235.         } else {
  9236.             $op 'S';
  9237.         }
  9238.         $MyArc * (sqrt(2) - 1);
  9239.         $this->writer->write(sprintf('%.3F %.3F m', ($x $r) * Mpdf::SCALE, ($hp $y) * Mpdf::SCALE));
  9240.         $xc $x $w $r;
  9241.         $yc $y $r;
  9242.         $this->writer->write(sprintf('%.3F %.3F l'$xc Mpdf::SCALE, ($hp $y) * Mpdf::SCALE));
  9243.         $this->_Arc($xc $r $MyArc$yc $r$xc $r$yc $r $MyArc$xc $r$yc);
  9244.         $xc $x $w $r;
  9245.         $yc $y $h $r;
  9246.         $this->writer->write(sprintf('%.3F %.3F l', ($x $w) * Mpdf::SCALE, ($hp $yc) * Mpdf::SCALE));
  9247.         $this->_Arc($xc $r$yc $r $MyArc$xc $r $MyArc$yc $r$xc$yc $r);
  9248.         $xc $x $r;
  9249.         $yc $y $h $r;
  9250.         $this->writer->write(sprintf('%.3F %.3F l'$xc Mpdf::SCALE, ($hp - ($y $h)) * Mpdf::SCALE));
  9251.         $this->_Arc($xc $r $MyArc$yc $r$xc $r$yc $r $MyArc$xc $r$yc);
  9252.         $xc $x $r;
  9253.         $yc $y $r;
  9254.         $this->writer->write(sprintf('%.3F %.3F l', ($x) * Mpdf::SCALE, ($hp $yc) * Mpdf::SCALE));
  9255.         $this->_Arc($xc $r$yc $r $MyArc$xc $r $MyArc$yc $r$xc$yc $r);
  9256.         $this->writer->write($op);
  9257.     }
  9258.     function _Arc($x1$y1$x2$y2$x3$y3)
  9259.     {
  9260.         $h $this->h;
  9261.         $this->writer->write(sprintf('%.3F %.3F %.3F %.3F %.3F %.3F c '$x1 Mpdf::SCALE, ($h $y1) * Mpdf::SCALE$x2 Mpdf::SCALE, ($h $y2) * Mpdf::SCALE$x3 Mpdf::SCALE, ($h $y3) * Mpdf::SCALE));
  9262.     }
  9263.     // ====================================================
  9264.     /* -- DIRECTW -- */
  9265.     function Shaded_box($text$font ''$fontstyle 'B'$szfont ''$width '70%'$style 'DF'$radius 2.5$fill '#FFFFFF'$color '#000000'$pad 2)
  9266.     {
  9267.         // F (shading - no line),S (line, no shading),DF (both)
  9268.         if (empty($this->directWrite)) {
  9269.             $this->directWrite = new DirectWrite($this$this->otl$this->sizeConverter$this->colorConverter);
  9270.         }
  9271.         $this->directWrite->Shaded_box($text$font$fontstyle$szfont$width$style$radius$fill$color$pad);
  9272.     }
  9273.     /* -- END DIRECTW -- */
  9274.     function UTF8StringToArray($str$addSubset true)
  9275.     {
  9276.         $out = [];
  9277.         $len strlen($str);
  9278.         for ($i 0$i $len$i++) {
  9279.             $uni = -1;
  9280.             $h ord($str[$i]);
  9281.             if ($h <= 0x7F) {
  9282.                 $uni $h;
  9283.             } elseif ($h >= 0xC2) {
  9284.                 if (($h <= 0xDF) && ($i $len 1)) {
  9285.                     $uni = ($h 0x1F) << | (ord($str[++$i]) & 0x3F);
  9286.                 } elseif (($h <= 0xEF) && ($i $len 2)) {
  9287.                     $uni = ($h 0x0F) << 12 | (ord($str[++$i]) & 0x3F) << | (ord($str[++$i]) & 0x3F);
  9288.                 } elseif (($h <= 0xF4) && ($i $len 3)) {
  9289.                     $uni = ($h 0x0F) << 18 | (ord($str[++$i]) & 0x3F) << 12 | (ord($str[++$i]) & 0x3F) << | (ord($str[++$i]) & 0x3F);
  9290.                 }
  9291.             }
  9292.             if ($uni >= 0) {
  9293.                 $out[] = $uni;
  9294.                 if ($addSubset && isset($this->CurrentFont['subset'])) {
  9295.                     $this->CurrentFont['subset'][$uni] = $uni;
  9296.                 }
  9297.             }
  9298.         }
  9299.         return $out;
  9300.     }
  9301.     // Convert utf-8 string to <HHHHHH> for Font Subsets
  9302.     function UTF8toSubset($str)
  9303.     {
  9304.         $ret '<';
  9305.         // $str = preg_replace('/'.preg_quote($this->aliasNbPg,'/').'/', chr(7), $str );    // mPDF 6 deleted
  9306.         // $str = preg_replace('/'.preg_quote($this->aliasNbPgGp,'/').'/', chr(8), $str );    // mPDF 6 deleted
  9307.         $unicode $this->UTF8StringToArray($str);
  9308.         $orig_fid $this->CurrentFont['subsetfontids'][0];
  9309.         $last_fid $this->CurrentFont['subsetfontids'][0];
  9310.         foreach ($unicode as $c) {
  9311.             /*     // mPDF 6 deleted
  9312.               if ($c == 7 || $c == 8) {
  9313.               if ($orig_fid != $last_fid) {
  9314.               $ret .= '> Tj /F'.$orig_fid.' '.$this->FontSizePt.' Tf <';
  9315.               $last_fid = $orig_fid;
  9316.               }
  9317.               if ($c == 7) { $ret .= $this->aliasNbPgHex; }
  9318.               else { $ret .= $this->aliasNbPgGpHex; }
  9319.               continue;
  9320.               }
  9321.              */
  9322.             if (!$this->_charDefined($this->CurrentFont['cw'], $c)) {
  9323.                 $c 0;
  9324.             } // mPDF 6
  9325.             for ($i 0$i 99$i++) {
  9326.                 // return c as decimal char
  9327.                 $init array_search($c$this->CurrentFont['subsets'][$i]);
  9328.                 if ($init !== false) {
  9329.                     if ($this->CurrentFont['subsetfontids'][$i] != $last_fid) {
  9330.                         $ret .= '> Tj /F' $this->CurrentFont['subsetfontids'][$i] . ' ' $this->FontSizePt ' Tf <';
  9331.                         $last_fid $this->CurrentFont['subsetfontids'][$i];
  9332.                     }
  9333.                     $ret .= sprintf("%02s"strtoupper(dechex($init)));
  9334.                     break;
  9335.                 } // TrueType embedded SUBSETS
  9336.                 elseif (count($this->CurrentFont['subsets'][$i]) < 255) {
  9337.                     $n count($this->CurrentFont['subsets'][$i]);
  9338.                     $this->CurrentFont['subsets'][$i][$n] = $c;
  9339.                     if ($this->CurrentFont['subsetfontids'][$i] != $last_fid) {
  9340.                         $ret .= '> Tj /F' $this->CurrentFont['subsetfontids'][$i] . ' ' $this->FontSizePt ' Tf <';
  9341.                         $last_fid $this->CurrentFont['subsetfontids'][$i];
  9342.                     }
  9343.                     $ret .= sprintf("%02s"strtoupper(dechex($n)));
  9344.                     break;
  9345.                 } elseif (!isset($this->CurrentFont['subsets'][($i 1)])) {
  9346.                     // TrueType embedded SUBSETS
  9347.                     $this->CurrentFont['subsets'][($i 1)] = [=> 0];
  9348.                     $new_fid count($this->fonts) + $this->extraFontSubsets 1;
  9349.                     $this->CurrentFont['subsetfontids'][($i 1)] = $new_fid;
  9350.                     $this->extraFontSubsets++;
  9351.                 }
  9352.             }
  9353.         }
  9354.         $ret .= '>';
  9355.         if ($last_fid != $orig_fid) {
  9356.             $ret .= ' Tj /F' $orig_fid ' ' $this->FontSizePt ' Tf <> ';
  9357.         }
  9358.         return $ret;
  9359.     }
  9360.     /* -- CJK-FONTS -- */
  9361.     // from class PDF_Chinese CJK EXTENSIONS
  9362.     function AddCIDFont($family$style$name, &$cw$CMap$registry$desc)
  9363.     {
  9364.         $fontkey strtolower($family) . strtoupper($style);
  9365.         if (isset($this->fonts[$fontkey])) {
  9366.             throw new \Mpdf\MpdfException("Font already added: $family $style");
  9367.         }
  9368.         $i count($this->fonts) + $this->extraFontSubsets 1;
  9369.         $name str_replace(' '''$name);
  9370.         if ($family == 'sjis') {
  9371.             $up = -120;
  9372.         } else {
  9373.             $up = -130;
  9374.         }
  9375.         // ? 'up' and 'ut' do not seem to be referenced anywhere
  9376.         $this->fonts[$fontkey] = ['i' => $i'type' => 'Type0''name' => $name'up' => $up'ut' => 40'cw' => $cw'CMap' => $CMap'registry' => $registry'MissingWidth' => 1000'desc' => $desc];
  9377.     }
  9378.     function AddCJKFont($family)
  9379.     {
  9380.         if ($this->PDFA || $this->PDFX) {
  9381.             throw new \Mpdf\MpdfException("Adobe CJK fonts cannot be embedded in mPDF (required for PDFA1-b and PDFX/1-a).");
  9382.         }
  9383.         if ($family == 'big5') {
  9384.             $this->AddBig5Font();
  9385.         } elseif ($family == 'gb') {
  9386.             $this->AddGBFont();
  9387.         } elseif ($family == 'sjis') {
  9388.             $this->AddSJISFont();
  9389.         } elseif ($family == 'uhc') {
  9390.             $this->AddUHCFont();
  9391.         }
  9392.     }
  9393.     function AddBig5Font()
  9394.     {
  9395.         // Add Big5 font with proportional Latin
  9396.         $family 'big5';
  9397.         $name 'MSungStd-Light-Acro';
  9398.         $cw $this->Big5_widths;
  9399.         $CMap 'UniCNS-UTF16-H';
  9400.         $registry = ['ordering' => 'CNS1''supplement' => 4];
  9401.         $desc = [
  9402.             'Ascent' => 880,
  9403.             'Descent' => -120,
  9404.             'CapHeight' => 880,
  9405.             'Flags' => 6,
  9406.             'FontBBox' => '[-160 -249 1015 1071]',
  9407.             'ItalicAngle' => 0,
  9408.             'StemV' => 93,
  9409.         ];
  9410.         $this->AddCIDFont($family''$name$cw$CMap$registry$desc);
  9411.         $this->AddCIDFont($family'B'$name ',Bold'$cw$CMap$registry$desc);
  9412.         $this->AddCIDFont($family'I'$name ',Italic'$cw$CMap$registry$desc);
  9413.         $this->AddCIDFont($family'BI'$name ',BoldItalic'$cw$CMap$registry$desc);
  9414.     }
  9415.     function AddGBFont()
  9416.     {
  9417.         // Add GB font with proportional Latin
  9418.         $family 'gb';
  9419.         $name 'STSongStd-Light-Acro';
  9420.         $cw $this->GB_widths;
  9421.         $CMap 'UniGB-UTF16-H';
  9422.         $registry = ['ordering' => 'GB1''supplement' => 4];
  9423.         $desc = [
  9424.             'Ascent' => 880,
  9425.             'Descent' => -120,
  9426.             'CapHeight' => 737,
  9427.             'Flags' => 6,
  9428.             'FontBBox' => '[-25 -254 1000 880]',
  9429.             'ItalicAngle' => 0,
  9430.             'StemV' => 58,
  9431.             'Style' => '<< /Panose <000000000400000000000000> >>',
  9432.         ];
  9433.         $this->AddCIDFont($family''$name$cw$CMap$registry$desc);
  9434.         $this->AddCIDFont($family'B'$name ',Bold'$cw$CMap$registry$desc);
  9435.         $this->AddCIDFont($family'I'$name ',Italic'$cw$CMap$registry$desc);
  9436.         $this->AddCIDFont($family'BI'$name ',BoldItalic'$cw$CMap$registry$desc);
  9437.     }
  9438.     function AddSJISFont()
  9439.     {
  9440.         // Add SJIS font with proportional Latin
  9441.         $family 'sjis';
  9442.         $name 'KozMinPro-Regular-Acro';
  9443.         $cw $this->SJIS_widths;
  9444.         $CMap 'UniJIS-UTF16-H';
  9445.         $registry = ['ordering' => 'Japan1''supplement' => 5];
  9446.         $desc = [
  9447.             'Ascent' => 880,
  9448.             'Descent' => -120,
  9449.             'CapHeight' => 740,
  9450.             'Flags' => 6,
  9451.             'FontBBox' => '[-195 -272 1110 1075]',
  9452.             'ItalicAngle' => 0,
  9453.             'StemV' => 86,
  9454.             'XHeight' => 502,
  9455.         ];
  9456.         $this->AddCIDFont($family''$name$cw$CMap$registry$desc);
  9457.         $this->AddCIDFont($family'B'$name ',Bold'$cw$CMap$registry$desc);
  9458.         $this->AddCIDFont($family'I'$name ',Italic'$cw$CMap$registry$desc);
  9459.         $this->AddCIDFont($family'BI'$name ',BoldItalic'$cw$CMap$registry$desc);
  9460.     }
  9461.     function AddUHCFont()
  9462.     {
  9463.         // Add UHC font with proportional Latin
  9464.         $family 'uhc';
  9465.         $name 'HYSMyeongJoStd-Medium-Acro';
  9466.         $cw $this->UHC_widths;
  9467.         $CMap 'UniKS-UTF16-H';
  9468.         $registry = ['ordering' => 'Korea1''supplement' => 2];
  9469.         $desc = [
  9470.             'Ascent' => 880,
  9471.             'Descent' => -120,
  9472.             'CapHeight' => 720,
  9473.             'Flags' => 6,
  9474.             'FontBBox' => '[-28 -148 1001 880]',
  9475.             'ItalicAngle' => 0,
  9476.             'StemV' => 60,
  9477.             'Style' => '<< /Panose <000000000600000000000000> >>',
  9478.         ];
  9479.         $this->AddCIDFont($family''$name$cw$CMap$registry$desc);
  9480.         $this->AddCIDFont($family'B'$name ',Bold'$cw$CMap$registry$desc);
  9481.         $this->AddCIDFont($family'I'$name ',Italic'$cw$CMap$registry$desc);
  9482.         $this->AddCIDFont($family'BI'$name ',BoldItalic'$cw$CMap$registry$desc);
  9483.     }
  9484.     /* -- END CJK-FONTS -- */
  9485.     //////////////////////////////////////////////////////////////////////////////
  9486.     //////////////////////////////////////////////////////////////////////////////
  9487.     //////////////////////////////////////////////////////////////////////////////
  9488.     //////////////////////////////////////////////////////////////////////////////
  9489.     //////////////////////////////////////////////////////////////////////////////
  9490.     //////////////////////////////////////////////////////////////////////////////
  9491.     //////////////////////////////////////////////////////////////////////////////
  9492.     function SetDefaultFont($font)
  9493.     {
  9494.         // Disallow embedded fonts to be used as defaults in PDFA
  9495.         if ($this->PDFA || $this->PDFX) {
  9496.             if (strtolower($font) == 'ctimes') {
  9497.                 $font 'serif';
  9498.             }
  9499.             if (strtolower($font) == 'ccourier') {
  9500.                 $font 'monospace';
  9501.             }
  9502.             if (strtolower($font) == 'chelvetica') {
  9503.                 $font 'sans-serif';
  9504.             }
  9505.         }
  9506.         $font $this->SetFont($font); // returns substituted font if necessary
  9507.         $this->default_font $font;
  9508.         $this->original_default_font $font;
  9509.         if (!$this->watermark_font) {
  9510.             $this->watermark_font $font;
  9511.         } // *WATERMARK*
  9512.         $this->defaultCSS['BODY']['FONT-FAMILY'] = $font;
  9513.         $this->cssManager->CSS['BODY']['FONT-FAMILY'] = $font;
  9514.     }
  9515.     function SetDefaultFontSize($fontsize)
  9516.     {
  9517.         $this->default_font_size $fontsize;
  9518.         $this->original_default_font_size $fontsize;
  9519.         $this->SetFontSize($fontsize);
  9520.         $this->defaultCSS['BODY']['FONT-SIZE'] = $fontsize 'pt';
  9521.         $this->cssManager->CSS['BODY']['FONT-SIZE'] = $fontsize 'pt';
  9522.     }
  9523.     function SetDefaultBodyCSS($prop$val)
  9524.     {
  9525.         if ($prop) {
  9526.             $this->defaultCSS['BODY'][strtoupper($prop)] = $val;
  9527.             $this->cssManager->CSS['BODY'][strtoupper($prop)] = $val;
  9528.         }
  9529.     }
  9530.     function SetDirectionality($dir 'ltr')
  9531.     {
  9532.         /* -- OTL -- */
  9533.         if (strtolower($dir) == 'rtl') {
  9534.             if ($this->directionality != 'rtl') {
  9535.                 // Swop L/R Margins so page 1 RTL is an 'even' page
  9536.                 $tmp $this->DeflMargin;
  9537.                 $this->DeflMargin $this->DefrMargin;
  9538.                 $this->DefrMargin $tmp;
  9539.                 $this->orig_lMargin $this->DeflMargin;
  9540.                 $this->orig_rMargin $this->DefrMargin;
  9541.                 $this->SetMargins($this->DeflMargin$this->DefrMargin$this->tMargin);
  9542.             }
  9543.             $this->directionality 'rtl';
  9544.             $this->defaultAlign 'R';
  9545.             $this->defaultTableAlign 'R';
  9546.         } else {
  9547.             /* -- END OTL -- */
  9548.             $this->directionality 'ltr';
  9549.             $this->defaultAlign 'L';
  9550.             $this->defaultTableAlign 'L';
  9551.         } // *OTL*
  9552.         $this->cssManager->CSS['BODY']['DIRECTION'] = $this->directionality;
  9553.     }
  9554.     // Return either a number (factor) - based on current set fontsize (if % or em) - or exact lineheight (with 'mm' after it)
  9555.     function fixLineheight($v)
  9556.     {
  9557.         $lh false;
  9558.         if (preg_match('/^[0-9\.,]*$/'$v) && $v >= 0) {
  9559.             return ($v 0);
  9560.         } elseif (strtoupper($v) == 'NORMAL' || $v == 'N') {
  9561.             return 'N';  // mPDF 6
  9562.         } else {
  9563.             $tlh $this->sizeConverter->convert($v$this->FontSize$this->FontSizetrue);
  9564.             if ($tlh) {
  9565.                 return ($tlh 'mm');
  9566.             }
  9567.         }
  9568.         return $this->normalLineheight;
  9569.     }
  9570.     function _getNormalLineheight($desc false)
  9571.     {
  9572.         if (!$desc) {
  9573.             $desc $this->CurrentFont['desc'];
  9574.         }
  9575.         if (!isset($desc['Leading'])) {
  9576.             $desc['Leading'] = 0;
  9577.         }
  9578.         if ($this->useFixedNormalLineHeight) {
  9579.             $lh $this->normalLineheight;
  9580.         } elseif (isset($desc['Ascent']) && $desc['Ascent']) {
  9581.             $lh = ($this->adjustFontDescLineheight * ($desc['Ascent'] - $desc['Descent'] + $desc['Leading']) / 1000);
  9582.         } else {
  9583.             $lh $this->normalLineheight;
  9584.         }
  9585.         return $lh;
  9586.     }
  9587.     // Set a (fixed) lineheight to an actual value - either to named fontsize(pts) or default
  9588.     function SetLineHeight($FontPt ''$lh '')
  9589.     {
  9590.         if (!$FontPt) {
  9591.             $FontPt $this->FontSizePt;
  9592.         }
  9593.         $fs $FontPt Mpdf::SCALE;
  9594.         $this->lineheight $this->_computeLineheight($lh$fs);
  9595.     }
  9596.     function _computeLineheight($lh$fs '')
  9597.     {
  9598.         if ($this->shrin_k 1) {
  9599.             $k $this->shrin_k;
  9600.         } else {
  9601.             $k 1;
  9602.         }
  9603.         if (!$fs) {
  9604.             $fs $this->FontSize;
  9605.         }
  9606.         if ($lh == 'N') {
  9607.             $lh $this->_getNormalLineheight();
  9608.         }
  9609.         if (preg_match('/mm/'$lh)) {
  9610.             return (((float) $lh) / $k); // convert to number
  9611.         } elseif ($lh 0) {
  9612.             return ($fs $lh);
  9613.         }
  9614.         return ($fs $this->normalLineheight);
  9615.     }
  9616.     function _setLineYpos(&$fontsize, &$fontdesc, &$CSSlineheight$blockYpos false)
  9617.     {
  9618.         $ypos['glyphYorigin'] = 0;
  9619.         $ypos['baseline-shift'] = 0;
  9620.         $linegap 0;
  9621.         $leading 0;
  9622.         if (isset($fontdesc['Ascent']) && $fontdesc['Ascent'] && !$this->useFixedTextBaseline) {
  9623.             // Fontsize uses font metrics - this method seems to produce results compatible with browsers (except IE9)
  9624.             $ypos['boxtop'] = $fontdesc['Ascent'] / 1000 $fontsize;
  9625.             $ypos['boxbottom'] = $fontdesc['Descent'] / 1000 $fontsize;
  9626.             if (isset($fontdesc['Leading'])) {
  9627.                 $linegap $fontdesc['Leading'] / 1000 $fontsize;
  9628.             }
  9629.         } // Default if not set - uses baselineC
  9630.         else {
  9631.             $ypos['boxtop'] = (0.5 $this->baselineC) * $fontsize;
  9632.             $ypos['boxbottom'] = -(0.5 $this->baselineC) * $fontsize;
  9633.         }
  9634.         $fontheight $ypos['boxtop'] - $ypos['boxbottom'];
  9635.         if ($this->shrin_k 1) {
  9636.             $shrin_k $this->shrin_k;
  9637.         } else {
  9638.             $shrin_k 1;
  9639.         }
  9640.         $leading 0;
  9641.         if ($CSSlineheight == 'N') {
  9642.             $lh $this->_getNormalLineheight($fontdesc);
  9643.             $lineheight = ($fontsize $lh);
  9644.             $leading += $linegap// specified in hhea or sTypo in OpenType tables
  9645.         } elseif (preg_match('/mm/'$CSSlineheight)) {
  9646.             $lineheight = (((float) $CSSlineheight) / $shrin_k); // convert to number
  9647.         // ??? If lineheight is a factor e.g. 1.3  ?? use factor x 1em or ? use 'normal' lineheight * factor
  9648.         // Could depend on value for $text_height - a draft CSS value as set above for now
  9649.         elseif ($CSSlineheight 0) {
  9650.             $lineheight = ($fontsize $CSSlineheight);
  9651.         } else {
  9652.             $lineheight = ($fontsize $this->normalLineheight);
  9653.         }
  9654.         // In general, calculate the "leading" - the difference between the fontheight and the lineheight
  9655.         // and add half to the top and half to the bottom. BUT
  9656.         // If an inline element has a font-size less than the block element, and the line-height is set as an em or % value
  9657.         // it will add too much leading below the font and expand the height of the line - so just use the block element exttop/extbottom:
  9658.         if (preg_match('/mm/'$CSSlineheight)
  9659.                 && ($blockYpos && $ypos['boxtop'] < $blockYpos['boxtop'])
  9660.                 && ($blockYpos && $ypos['boxbottom'] > $blockYpos['boxbottom'])) {
  9661.             $ypos['exttop'] = $blockYpos['exttop'];
  9662.             $ypos['extbottom'] = $blockYpos['extbottom'];
  9663.         } else {
  9664.             $leading += ($lineheight $fontheight);
  9665.             $ypos['exttop'] = $ypos['boxtop'] + $leading 2;
  9666.             $ypos['extbottom'] = $ypos['boxbottom'] - $leading 2;
  9667.         }
  9668.         // TEMP ONLY FOR DEBUGGING *********************************
  9669.         // $ypos['lineheight'] = $lineheight;
  9670.         // $ypos['fontheight'] = $fontheight;
  9671.         // $ypos['leading'] = $leading;
  9672.         return $ypos;
  9673.     }
  9674.     /* Called from WriteFlowingBlock() and finishFlowingBlock()
  9675.       Determines the line hieght and glyph/writing position
  9676.       for each element in the line to be written */
  9677.     function _setInlineBlockHeights(&$lineBox, &$stackHeight, &$content, &$font$is_table)
  9678.     {
  9679.         if ($this->shrin_k 1) {
  9680.             $shrin_k $this->shrin_k;
  9681.         } else {
  9682.             $shrin_k 1;
  9683.         }
  9684.         $ypos = [];
  9685.         $bordypos = [];
  9686.         $bgypos = [];
  9687.         if ($is_table) {
  9688.             // FOR TABLE
  9689.             $fontsize $this->FontSize;
  9690.             $fontkey $this->FontFamily $this->FontStyle;
  9691.             $fontdesc $this->fonts[$fontkey]['desc'];
  9692.             $CSSlineheight $this->cellLineHeight;
  9693.             $line_stacking_strategy $this->cellLineStackingStrategy// inline-line-height [default] | block-line-height | max-height | grid-height
  9694.             $line_stacking_shift $this->cellLineStackingShift;  // consider-shifts [default] | disregard-shifts
  9695.         } else {
  9696.             // FOR BLOCK FONT
  9697.             $fontsize $this->blk[$this->blklvl]['InlineProperties']['size'];
  9698.             $fontkey $this->blk[$this->blklvl]['InlineProperties']['family'] . $this->blk[$this->blklvl]['InlineProperties']['style'];
  9699.             $fontdesc $this->fonts[$fontkey]['desc'];
  9700.             $CSSlineheight $this->blk[$this->blklvl]['line_height'];
  9701.             // inline-line-height | block-line-height | max-height | grid-height
  9702.             $line_stacking_strategy = (isset($this->blk[$this->blklvl]['line_stacking_strategy']) ? $this->blk[$this->blklvl]['line_stacking_strategy'] : 'inline-line-height');
  9703.             // consider-shifts | disregard-shifts
  9704.             $line_stacking_shift = (isset($this->blk[$this->blklvl]['line_stacking_shift']) ? $this->blk[$this->blklvl]['line_stacking_shift'] : 'consider-shifts');
  9705.         }
  9706.         $boxLineHeight $this->_computeLineheight($CSSlineheight$fontsize);
  9707.         // First, set a "strut" using block font at index $lineBox[-1]
  9708.         $ypos[-1] = $this->_setLineYpos($fontsize$fontdesc$CSSlineheight);
  9709.         // for the block element - always taking the block EXTENDED progression including leading - which may be negative
  9710.         if ($line_stacking_strategy == 'block-line-height') {
  9711.             $topy $ypos[-1]['exttop'];
  9712.             $bottomy $ypos[-1]['extbottom'];
  9713.         } else {
  9714.             $topy 0;
  9715.             $bottomy 0;
  9716.         }
  9717.         // Get text-middle for aligning images/objects
  9718.         $midpoint $ypos[-1]['boxtop'] - (($ypos[-1]['boxtop'] - $ypos[-1]['boxbottom']) / 2);
  9719.         // for images / inline objects / replaced elements
  9720.         $mta 0// Maximum top-aligned
  9721.         $mba 0// Maximum bottom-aligned
  9722.         foreach ($content as $k => $chunk) {
  9723.             if (isset($this->objectbuffer[$k]) && $this->objectbuffer[$k]['type'] == 'listmarker') {
  9724.                 $ypos[$k] = $ypos[-1];
  9725.                 // UPDATE Maximums
  9726.                 if ($line_stacking_strategy == 'block-line-height' || $line_stacking_strategy == 'grid-height' || $line_stacking_strategy == 'max-height') { // don't include extended block progression of all inline elements
  9727.                     if ($ypos[$k]['boxtop'] > $topy) {
  9728.                         $topy $ypos[$k]['boxtop'];
  9729.                     }
  9730.                     if ($ypos[$k]['boxbottom'] < $bottomy) {
  9731.                         $bottomy $ypos[$k]['boxbottom'];
  9732.                     }
  9733.                 } else {
  9734.                     if ($ypos[$k]['exttop'] > $topy) {
  9735.                         $topy $ypos[$k]['exttop'];
  9736.                     }
  9737.                     if ($ypos[$k]['extbottom'] < $bottomy) {
  9738.                         $bottomy $ypos[$k]['extbottom'];
  9739.                     }
  9740.                 }
  9741.             } elseif (isset($this->objectbuffer[$k]) && $this->objectbuffer[$k]['type'] == 'dottab') { // mPDF 6 DOTTAB
  9742.                 $fontsize $font[$k]['size'];
  9743.                 $fontdesc $font[$k]['curr']['desc'];
  9744.                 $lh 1;
  9745.                 $ypos[$k] = $this->_setLineYpos($fontsize$fontdesc$lh$ypos[-1]); // Lineheight=1 fixed
  9746.             } elseif (isset($this->objectbuffer[$k])) {
  9747.                 $oh $this->objectbuffer[$k]['OUTER-HEIGHT'];
  9748.                 $va $this->objectbuffer[$k]['vertical-align'];
  9749.                 if ($va == 'BS') { //  (BASELINE default)
  9750.                     if ($oh $topy) {
  9751.                         $topy $oh;
  9752.                     }
  9753.                 } elseif ($va == 'M') {
  9754.                     if (($midpoint $oh 2) > $topy) {
  9755.                         $topy $midpoint $oh 2;
  9756.                     }
  9757.                     if (($midpoint $oh 2) < $bottomy) {
  9758.                         $bottomy $midpoint $oh 2;
  9759.                     }
  9760.                 } elseif ($va == 'TT') {
  9761.                     if (($ypos[-1]['boxtop'] - $oh) < $bottomy) {
  9762.                         $bottomy $ypos[-1]['boxtop'] - $oh;
  9763.                         $topy max($topy$ypos[-1]['boxtop']);
  9764.                     }
  9765.                 } elseif ($va == 'TB') {
  9766.                     if (($ypos[-1]['boxbottom'] + $oh) > $topy) {
  9767.                         $topy $ypos[-1]['boxbottom'] + $oh;
  9768.                         $bottomy min($bottomy$ypos[-1]['boxbottom']);
  9769.                     }
  9770.                 } elseif ($va == 'T') {
  9771.                     if ($oh $mta) {
  9772.                         $mta $oh;
  9773.                     }
  9774.                 } elseif ($va == 'B') {
  9775.                     if ($oh $mba) {
  9776.                         $mba $oh;
  9777.                     }
  9778.                 }
  9779.             } elseif ($content[$k] || $content[$k] === '0') {
  9780.                 // FOR FLOWING BLOCK
  9781.                 $fontsize $font[$k]['size'];
  9782.                 $fontdesc $font[$k]['curr']['desc'];
  9783.                 // In future could set CSS line-height from inline elements; for now, use block level:
  9784.                 $ypos[$k] = $this->_setLineYpos($fontsize$fontdesc$CSSlineheight$ypos[-1]);
  9785.                 if (isset($font[$k]['textparam']['text-baseline']) && $font[$k]['textparam']['text-baseline'] != 0) {
  9786.                     $ypos[$k]['baseline-shift'] = $font[$k]['textparam']['text-baseline'];
  9787.                 }
  9788.                 // DO ALIGNMENT FOR BASELINES *******************
  9789.                 // Until most fonts have OpenType BASE tables, this won't work
  9790.                 // $ypos[$k] compared to $ypos[-1] or $ypos[$k-1] using $dominant_baseline and $baseline_table
  9791.                 // UPDATE Maximums
  9792.                 if ($line_stacking_strategy == 'block-line-height' || $line_stacking_strategy == 'grid-height' || $line_stacking_strategy == 'max-height') { // don't include extended block progression of all inline elements
  9793.                     if ($line_stacking_shift == 'disregard-shifts') {
  9794.                         if ($ypos[$k]['boxtop'] > $topy) {
  9795.                             $topy $ypos[$k]['boxtop'];
  9796.                         }
  9797.                         if ($ypos[$k]['boxbottom'] < $bottomy) {
  9798.                             $bottomy $ypos[$k]['boxbottom'];
  9799.                         }
  9800.                     } else {
  9801.                         if (($ypos[$k]['boxtop'] + $ypos[$k]['baseline-shift']) > $topy) {
  9802.                             $topy $ypos[$k]['boxtop'] + $ypos[$k]['baseline-shift'];
  9803.                         }
  9804.                         if (($ypos[$k]['boxbottom'] + $ypos[$k]['baseline-shift']) < $bottomy) {
  9805.                             $bottomy $ypos[$k]['boxbottom'] + $ypos[$k]['baseline-shift'];
  9806.                         }
  9807.                     }
  9808.                 } else {
  9809.                     if ($line_stacking_shift == 'disregard-shifts') {
  9810.                         if ($ypos[$k]['exttop'] > $topy) {
  9811.                             $topy $ypos[$k]['exttop'];
  9812.                         }
  9813.                         if ($ypos[$k]['extbottom'] < $bottomy) {
  9814.                             $bottomy $ypos[$k]['extbottom'];
  9815.                         }
  9816.                     } else {
  9817.                         if (($ypos[$k]['exttop'] + $ypos[$k]['baseline-shift']) > $topy) {
  9818.                             $topy $ypos[$k]['exttop'] + $ypos[$k]['baseline-shift'];
  9819.                         }
  9820.                         if (($ypos[$k]['extbottom'] + $ypos[$k]['baseline-shift']) < $bottomy) {
  9821.                             $bottomy $ypos[$k]['extbottom'] + $ypos[$k]['baseline-shift'];
  9822.                         }
  9823.                     }
  9824.                 }
  9825.                 // If BORDER set on inline element
  9826.                 if (isset($font[$k]['bord']) && $font[$k]['bord']) {
  9827.                     $bordfontsize $font[$k]['textparam']['bord-decoration']['fontsize'] / $shrin_k;
  9828.                     $bordfontkey $font[$k]['textparam']['bord-decoration']['fontkey'];
  9829.                     if ($bordfontkey != $fontkey || $bordfontsize != $fontsize || isset($font[$k]['textparam']['bord-decoration']['baseline'])) {
  9830.                         $bordfontdesc $this->fonts[$bordfontkey]['desc'];
  9831.                         $bordypos[$k] = $this->_setLineYpos($bordfontsize$bordfontdesc$CSSlineheight$ypos[-1]);
  9832.                         if (isset($font[$k]['textparam']['bord-decoration']['baseline']) && $font[$k]['textparam']['bord-decoration']['baseline'] != 0) {
  9833.                             $bordypos[$k]['baseline-shift'] = $font[$k]['textparam']['bord-decoration']['baseline'] / $shrin_k;
  9834.                         }
  9835.                     }
  9836.                 }
  9837.                 // If BACKGROUND set on inline element
  9838.                 if (isset($font[$k]['spanbgcolor']) && $font[$k]['spanbgcolor']) {
  9839.                     $bgfontsize $font[$k]['textparam']['bg-decoration']['fontsize'] / $shrin_k;
  9840.                     $bgfontkey $font[$k]['textparam']['bg-decoration']['fontkey'];
  9841.                     if ($bgfontkey != $fontkey || $bgfontsize != $fontsize || isset($font[$k]['textparam']['bg-decoration']['baseline'])) {
  9842.                         $bgfontdesc $this->fonts[$bgfontkey]['desc'];
  9843.                         $bgypos[$k] = $this->_setLineYpos($bgfontsize$bgfontdesc$CSSlineheight$ypos[-1]);
  9844.                         if (isset($font[$k]['textparam']['bg-decoration']['baseline']) && $font[$k]['textparam']['bg-decoration']['baseline'] != 0) {
  9845.                             $bgypos[$k]['baseline-shift'] = $font[$k]['textparam']['bg-decoration']['baseline'] / $shrin_k;
  9846.                         }
  9847.                     }
  9848.                 }
  9849.             }
  9850.         }
  9851.         // TOP or BOTTOM aligned images
  9852.         if ($mta > ($topy $bottomy)) {
  9853.             if (($topy $mta) < $bottomy) {
  9854.                 $bottomy $topy $mta;
  9855.             }
  9856.         }
  9857.         if ($mba > ($topy $bottomy)) {
  9858.             if (($bottomy $mba) > $topy) {
  9859.                 $topy $bottomy $mba;
  9860.             }
  9861.         }
  9862.         if ($line_stacking_strategy == 'block-line-height') { // fixed height set by block element (whether present or not)
  9863.             $topy $ypos[-1]['exttop'];
  9864.             $bottomy $ypos[-1]['extbottom'];
  9865.         }
  9866.         $inclusiveHeight $topy $bottomy;
  9867.         // SET $stackHeight taking note of line_stacking_strategy
  9868.         // NB inclusive height already takes account of need to consider block progression height (excludes leading set by lineheight)
  9869.         // or extended block progression height (includes leading set by lineheight)
  9870.         if ($line_stacking_strategy == 'block-line-height') { // fixed = extended block progression height of block element
  9871.             $stackHeight $boxLineHeight;
  9872.         } elseif ($line_stacking_strategy == 'max-height') { // smallest height which includes extended block progression height of block element
  9873.             // and block progression heights of inline elements (NOT extended)
  9874.             $stackHeight $inclusiveHeight;
  9875.         } elseif ($line_stacking_strategy == 'grid-height') { // smallest multiple of block element lineheight to include
  9876.             // block progression heights of inline elements (NOT extended)
  9877.             $stackHeight $boxLineHeight;
  9878.             while ($stackHeight $inclusiveHeight) {
  9879.                 $stackHeight += $boxLineHeight;
  9880.             }
  9881.         } else { // 'inline-line-height' = default        // smallest height which includes extended block progression height of block element
  9882.             // AND extended block progression heights of inline elements
  9883.             $stackHeight $inclusiveHeight;
  9884.         }
  9885.         $diff $stackHeight $inclusiveHeight;
  9886.         $topy += $diff 2;
  9887.         $bottomy -= $diff 2;
  9888.         // ADJUST $ypos => lineBox using $stackHeight; lineBox are all offsets from the top of stackHeight in mm
  9889.         // and SET IMAGE OFFSETS
  9890.         $lineBox[-1]['boxtop'] = $topy $ypos[-1]['boxtop'];
  9891.         $lineBox[-1]['boxbottom'] = $topy $ypos[-1]['boxbottom'];
  9892.         // $lineBox[-1]['exttop'] = $topy - $ypos[-1]['exttop'];
  9893.         // $lineBox[-1]['extbottom'] = $topy - $ypos[-1]['extbottom'];
  9894.         $lineBox[-1]['glyphYorigin'] = $topy $ypos[-1]['glyphYorigin'];
  9895.         $lineBox[-1]['baseline-shift'] = $ypos[-1]['baseline-shift'];
  9896.         $midpoint $lineBox[-1]['boxbottom'] - (($lineBox[-1]['boxbottom'] - $lineBox[-1]['boxtop']) / 2);
  9897.         foreach ($content as $k => $chunk) {
  9898.             if (isset($this->objectbuffer[$k])) {
  9899.                 $oh $this->objectbuffer[$k]['OUTER-HEIGHT'];
  9900.                 // LIST MARKERS
  9901.                 if ($this->objectbuffer[$k]['type'] == 'listmarker') {
  9902.                     $oh $fontsize;
  9903.                 } elseif ($this->objectbuffer[$k]['type'] == 'dottab') { // mPDF 6 DOTTAB
  9904.                     $oh $font[$k]['size']; // == $this->objectbuffer[$k]['fontsize']/Mpdf::SCALE;
  9905.                     $lineBox[$k]['boxtop'] = $topy $ypos[$k]['boxtop'];
  9906.                     $lineBox[$k]['boxbottom'] = $topy $ypos[$k]['boxbottom'];
  9907.                     $lineBox[$k]['glyphYorigin'] = $topy $ypos[$k]['glyphYorigin'];
  9908.                     $lineBox[$k]['baseline-shift'] = 0;
  9909.                     // continue;
  9910.                 }
  9911.                 $va $this->objectbuffer[$k]['vertical-align']; // = $objattr['vertical-align'] = set as M,T,B,S
  9912.                 if ($va == 'BS') { //  (BASELINE default)
  9913.                     $lineBox[$k]['top'] = $lineBox[-1]['glyphYorigin'] - $oh;
  9914.                 } elseif ($va == 'M') {
  9915.                     $lineBox[$k]['top'] = $midpoint $oh 2;
  9916.                 } elseif ($va == 'TT') {
  9917.                     $lineBox[$k]['top'] = $lineBox[-1]['boxtop'];
  9918.                 } elseif ($va == 'TB') {
  9919.                     $lineBox[$k]['top'] = $lineBox[-1]['boxbottom'] - $oh;
  9920.                 } elseif ($va == 'T') {
  9921.                     $lineBox[$k]['top'] = 0;
  9922.                 } elseif ($va == 'B') {
  9923.                     $lineBox[$k]['top'] = $stackHeight $oh;
  9924.                 }
  9925.             } elseif ($content[$k] || $content[$k] === '0') {
  9926.                 $lineBox[$k]['boxtop'] = $topy $ypos[$k]['boxtop'];
  9927.                 $lineBox[$k]['boxbottom'] = $topy $ypos[$k]['boxbottom'];
  9928.                 // $lineBox[$k]['exttop'] = $topy - $ypos[$k]['exttop'];
  9929.                 // $lineBox[$k]['extbottom'] = $topy - $ypos[$k]['extbottom'];
  9930.                 $lineBox[$k]['glyphYorigin'] = $topy $ypos[$k]['glyphYorigin'];
  9931.                 $lineBox[$k]['baseline-shift'] = $ypos[$k]['baseline-shift'];
  9932.                 if (isset($bordypos[$k]['boxtop'])) {
  9933.                     $lineBox[$k]['border-boxtop'] = $topy $bordypos[$k]['boxtop'];
  9934.                     $lineBox[$k]['border-boxbottom'] = $topy $bordypos[$k]['boxbottom'];
  9935.                     $lineBox[$k]['border-baseline-shift'] = $bordypos[$k]['baseline-shift'];
  9936.                 }
  9937.                 if (isset($bgypos[$k]['boxtop'])) {
  9938.                     $lineBox[$k]['background-boxtop'] = $topy $bgypos[$k]['boxtop'];
  9939.                     $lineBox[$k]['background-boxbottom'] = $topy $bgypos[$k]['boxbottom'];
  9940.                     $lineBox[$k]['background-baseline-shift'] = $bgypos[$k]['baseline-shift'];
  9941.                 }
  9942.             }
  9943.         }
  9944.     }
  9945.     function SetBasePath($str '')
  9946.     {
  9947.         if (isset($_SERVER['HTTP_HOST'])) {
  9948.             $host $_SERVER['HTTP_HOST'];
  9949.         } elseif (isset($_SERVER['SERVER_NAME'])) {
  9950.             $host $_SERVER['SERVER_NAME'];
  9951.         } else {
  9952.             $host '';
  9953.         }
  9954.         if (!$str) {
  9955.             if (isset($_SERVER['SCRIPT_NAME'])) {
  9956.                 $currentPath dirname($_SERVER['SCRIPT_NAME']);
  9957.             } else {
  9958.                 $currentPath dirname($_SERVER['PHP_SELF']);
  9959.             }
  9960.             $currentPath str_replace("\\""/"$currentPath);
  9961.             if ($currentPath == '/') {
  9962.                 $currentPath '';
  9963.             }
  9964.             if ($host) {  // mPDF 6
  9965.                 if (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] && $_SERVER['HTTPS'] !== 'off') {
  9966.                     $currpath 'https://' $host $currentPath '/';
  9967.                 } else {
  9968.                     $currpath 'http://' $host $currentPath '/';
  9969.                 }
  9970.             } else {
  9971.                 $currpath '';
  9972.             }
  9973.             $this->basepath $currpath;
  9974.             $this->basepathIsLocal true;
  9975.             return;
  9976.         }
  9977.         $str preg_replace('/\?.*/'''$str);
  9978.         if (!preg_match('/(http|https|ftp):\/\/.*\//i'$str)) {
  9979.             $str .= '/';
  9980.         }
  9981.         $str .= 'xxx'// in case $str ends in / e.g. http://www.bbc.co.uk/
  9982.         $this->basepath dirname($str) . "/"// returns e.g. e.g. http://www.google.com/dir1/dir2/dir3/
  9983.         $this->basepath str_replace("\\""/"$this->basepath); // If on Windows
  9984.         $tr parse_url($this->basepath);
  9985.         $this->basepathIsLocal = (isset($tr['host']) && ($tr['host'] == $host));
  9986.     }
  9987.     public function GetFullPath(&$path$basepath '')
  9988.     {
  9989.         // @todo make return, remove reference
  9990.         // When parsing CSS need to pass temporary basepath - so links are relative to current stylesheet
  9991.         if (!$basepath) {
  9992.             $basepath $this->basepath;
  9993.         }
  9994.         // Fix path value
  9995.         $path str_replace("\\"'/'$path); // If on Windows
  9996.         // mPDF 5.7.2
  9997.         if (strpos($path'//') === 0) {
  9998.             $scheme parse_url($basepathPHP_URL_SCHEME);
  9999.             $scheme $scheme ?: 'http';
  10000.             $path $scheme ':' $path;
  10001.         }
  10002.         $path preg_replace('|^./|'''$path); // Inadvertently corrects "./path/etc" and "//www.domain.com/etc"
  10003.         if (strpos($path'#') === 0) {
  10004.             return;
  10005.         }
  10006.         // Skip schemes not supported by installed stream wrappers
  10007.         $wrappers stream_get_wrappers();
  10008.         $pattern sprintf('@^(?!%s)[a-z0-9\.\-+]+:.*@i'implode('|'$wrappers));
  10009.         if (preg_match($pattern$path)) {
  10010.             return;
  10011.         }
  10012.         if (strpos($path'../') === 0) { // It is a relative link
  10013.             $backtrackamount substr_count($path'../');
  10014.             $maxbacktrack substr_count($basepath'/') - 3;
  10015.             $filepath str_replace('../'''$path);
  10016.             $path $basepath;
  10017.             // If it is an invalid relative link, then make it go to directory root
  10018.             if ($backtrackamount $maxbacktrack) {
  10019.                 $backtrackamount $maxbacktrack;
  10020.             }
  10021.             // Backtrack some directories
  10022.             for ($i 0$i $backtrackamount 1$i++) {
  10023.                 $path substr($path0strrpos($path"/"));
  10024.             }
  10025.             $path .= '/' $filepath// Make it an absolute path
  10026.             return;
  10027.         }
  10028.         if ((strpos($path":/") === false || strpos($path":/") > 10) && !@is_file($path)) { // It is a local link. Ignore potential file errors
  10029.             if (strpos($path'/') === 0) {
  10030.                 $tr parse_url($basepath);
  10031.                 // mPDF 5.7.2
  10032.                 $root '';
  10033.                 if (!empty($tr['scheme'])) {
  10034.                     $root .= $tr['scheme'] . '://';
  10035.                 }
  10036.                 $root .= isset($tr['host']) ? $tr['host'] : '';
  10037.                 $root .= ((isset($tr['port']) && $tr['port']) ? (':' $tr['port']) : ''); // mPDF 5.7.3
  10038.                 $path $root $path;
  10039.                 return;
  10040.             }
  10041.             $path $basepath $path;
  10042.         }
  10043.         // Do nothing if it is an Absolute Link
  10044.     }
  10045.     function docPageNum($num 0$extras false)
  10046.     {
  10047.         if ($num 1) {
  10048.             $num $this->page;
  10049.         }
  10050.         $type $this->defaultPageNumStyle// set default Page Number Style
  10051.         $ppgno $num;
  10052.         $suppress 0;
  10053.         $offset 0;
  10054.         $lastreset 0;
  10055.         foreach ($this->PageNumSubstitutions as $psarr) {
  10056.             if ($num >= $psarr['from']) {
  10057.                 if ($psarr['reset']) {
  10058.                     if ($psarr['reset'] > 1) {
  10059.                         $offset $psarr['reset'] - 1;
  10060.                     }
  10061.                     $ppgno $num $psarr['from'] + $offset;
  10062.                     $lastreset $psarr['from'];
  10063.                 }
  10064.                 if ($psarr['type']) {
  10065.                     $type $psarr['type'];
  10066.                 }
  10067.                 if (strtoupper($psarr['suppress']) == 'ON' || $psarr['suppress'] == 1) {
  10068.                     $suppress 1;
  10069.                 } elseif (strtoupper($psarr['suppress']) == 'OFF') {
  10070.                     $suppress 0;
  10071.                 }
  10072.             }
  10073.         }
  10074.         if ($suppress) {
  10075.             return '';
  10076.         }
  10077.         $ppgno $this->_getStyledNumber($ppgno$type);
  10078.         if ($extras) {
  10079.             $ppgno $this->pagenumPrefix $ppgno $this->pagenumSuffix;
  10080.         }
  10081.         return $ppgno;
  10082.     }
  10083.     function docPageNumTotal($num 0$extras false)
  10084.     {
  10085.         if ($num 1) {
  10086.             $num $this->page;
  10087.         }
  10088.         $type $this->defaultPageNumStyle// set default Page Number Style
  10089.         $ppgstart 1;
  10090.         $ppgend count($this->pages) + 1;
  10091.         $suppress 0;
  10092.         $offset 0;
  10093.         foreach ($this->PageNumSubstitutions as $psarr) {
  10094.             if ($num >= $psarr['from']) {
  10095.                 if ($psarr['reset']) {
  10096.                     if ($psarr['reset'] > 1) {
  10097.                         $offset $psarr['reset'] - 1;
  10098.                     }
  10099.                     $ppgstart $psarr['from'] + $offset;
  10100.                     $ppgend count($this->pages) + $offset;
  10101.                 }
  10102.                 if ($psarr['type']) {
  10103.                     $type $psarr['type'];
  10104.                 }
  10105.                 if (strtoupper($psarr['suppress']) == 'ON' || $psarr['suppress'] == 1) {
  10106.                     $suppress 1;
  10107.                 } elseif (strtoupper($psarr['suppress']) == 'OFF') {
  10108.                     $suppress 0;
  10109.                 }
  10110.             }
  10111.             if ($num $psarr['from']) {
  10112.                 if ($psarr['reset']) {
  10113.                     $ppgend $psarr['from'] + $offset;
  10114.                     break;
  10115.                 }
  10116.             }
  10117.         }
  10118.         if ($suppress) {
  10119.             return '';
  10120.         }
  10121.         $ppgno $ppgend $ppgstart $offset;
  10122.         $ppgno $this->_getStyledNumber($ppgno$type);
  10123.         if ($extras) {
  10124.             $ppgno $this->pagenumPrefix $ppgno $this->pagenumSuffix;
  10125.         }
  10126.         return $ppgno;
  10127.     }
  10128.     // mPDF 6
  10129.     function _getStyledNumber($ppgno$type$listmarker false)
  10130.     {
  10131.         if ($listmarker) {
  10132.             $reverse true// Reverse RTL numerals (Hebrew) when using for list
  10133.             $checkfont true// Using list - font is set, so check if character is available
  10134.         } else {
  10135.             $reverse false// For pagenumbers, RTL numerals (Hebrew) will get reversed later by bidi
  10136.             $checkfont false// For pagenumbers - font is not set, so no check
  10137.         }
  10138.         $decToAlpha = new Conversion\DecToAlpha();
  10139.         $decToCjk = new Conversion\DecToCjk();
  10140.         $decToHebrew = new Conversion\DecToHebrew();
  10141.         $decToRoman = new Conversion\DecToRoman();
  10142.         $decToOther = new Conversion\DecToOther($this);
  10143.         $lowertype strtolower($type);
  10144.         if ($lowertype == 'upper-latin' || $lowertype == 'upper-alpha' || $type == 'A') {
  10145.             $ppgno $decToAlpha->convert($ppgnotrue);
  10146.         } elseif ($lowertype == 'lower-latin' || $lowertype == 'lower-alpha' || $type == 'a') {
  10147.             $ppgno $decToAlpha->convert($ppgnofalse);
  10148.         } elseif ($lowertype == 'upper-roman' || $type == 'I') {
  10149.             $ppgno $decToRoman->convert($ppgnotrue);
  10150.         } elseif ($lowertype == 'lower-roman' || $type == 'i') {
  10151.             $ppgno $decToRoman->convert($ppgnofalse);
  10152.         } elseif ($lowertype == 'hebrew') {
  10153.             $ppgno $decToHebrew->convert($ppgno$reverse);
  10154.         } elseif (preg_match('/(arabic-indic|bengali|devanagari|gujarati|gurmukhi|kannada|malayalam|oriya|persian|tamil|telugu|thai|urdu|cambodian|khmer|lao|myanmar)/i'$lowertype$m)) {
  10155.             $cp $decToOther->getCodePage($m[1]);
  10156.             $ppgno $decToOther->convert($ppgno$cp$checkfont);
  10157.         } elseif ($lowertype == 'cjk-decimal') {
  10158.             $ppgno $decToCjk->convert($ppgno);
  10159.         }
  10160.         return $ppgno;
  10161.     }
  10162.     function docPageSettings($num 0)
  10163.     {
  10164.         // Returns current type (numberstyle), suppression state for this page number;
  10165.         // reset is only returned if set for this page number
  10166.         if ($num 1) {
  10167.             $num $this->page;
  10168.         }
  10169.         $type $this->defaultPageNumStyle// set default Page Number Style
  10170.         $ppgno $num;
  10171.         $suppress 0;
  10172.         $offset 0;
  10173.         $reset '';
  10174.         foreach ($this->PageNumSubstitutions as $psarr) {
  10175.             if ($num >= $psarr['from']) {
  10176.                 if ($psarr['reset']) {
  10177.                     if ($psarr['reset'] > 1) {
  10178.                         $offset $psarr['reset'] - 1;
  10179.                     }
  10180.                     $ppgno $num $psarr['from'] + $offset;
  10181.                 }
  10182.                 if ($psarr['type']) {
  10183.                     $type $psarr['type'];
  10184.                 }
  10185.                 if (strtoupper($psarr['suppress']) == 'ON' || $psarr['suppress'] == 1) {
  10186.                     $suppress 1;
  10187.                 } elseif (strtoupper($psarr['suppress']) == 'OFF') {
  10188.                     $suppress 0;
  10189.                 }
  10190.             }
  10191.             if ($num == $psarr['from']) {
  10192.                 $reset $psarr['reset'];
  10193.             }
  10194.         }
  10195.         if ($suppress) {
  10196.             $suppress 'on';
  10197.         } else {
  10198.             $suppress 'off';
  10199.         }
  10200.         return [$type$suppress$reset];
  10201.     }
  10202.     function RestartDocTemplate()
  10203.     {
  10204.         $this->docTemplateStart $this->page;
  10205.     }
  10206.     // Page header
  10207.     function Header($content '')
  10208.     {
  10209.         $this->cMarginL 0;
  10210.         $this->cMarginR 0;
  10211.         if (($this->mirrorMargins && ($this->page == 0) && $this->HTMLHeaderE) || ($this->mirrorMargins && ($this->page == 1) && $this->HTMLHeader) || (!$this->mirrorMargins && $this->HTMLHeader)) {
  10212.             $this->writeHTMLHeaders();
  10213.             return;
  10214.         }
  10215.     }
  10216.     /* -- TABLES -- */
  10217.     function TableHeaderFooter($content ''$tablestartpage ''$tablestartcolumn ''$horf 'H'$level 0$firstSpread true$finalSpread true)
  10218.     {
  10219.         if (($horf == 'H' || $horf == 'F') && !empty($content)) { // mPDF 5.7.2
  10220.             $table = &$this->table[1][1];
  10221.             // mPDF 5.7.2
  10222.             if ($horf == 'F') { // Table Footer
  10223.                 $firstrow count($table['cells']) - $table['footernrows'];
  10224.                 $lastrow count($table['cells']) - 1;
  10225.             } else {  // Table Header
  10226.                 $firstrow 0;
  10227.                 $lastrow $table['headernrows'] - 1;
  10228.             }
  10229.             if (empty($content[$firstrow])) {
  10230.                 if ($this->debug) {
  10231.                     throw new \Mpdf\MpdfException("<tfoot> must precede <tbody> in a table");
  10232.                 } else {
  10233.                     return;
  10234.                 }
  10235.             }
  10236.             // Advance down page by half width of top border
  10237.             if ($horf == 'H') { // Only if header
  10238.                 if ($table['borders_separate']) {
  10239.                     $adv $table['border_spacing_V'] / $table['border_details']['T']['w'] + $table['padding']['T'];
  10240.                 } else {
  10241.                     $adv $table['max_cell_border_width']['T'] / 2;
  10242.                 }
  10243.                 if ($adv) {
  10244.                     if ($this->table_rotate) {
  10245.                         $this->+= ($adv);
  10246.                     } else {
  10247.                         $this->DivLn($adv$this->blklvltrue);
  10248.                     }
  10249.                 }
  10250.             }
  10251.             $topy $content[$firstrow][0]['y'] - $this->y;
  10252.             for ($i $firstrow$i <= $lastrow$i++) {
  10253.                 $y $this->y;
  10254.                 /* -- COLUMNS -- */
  10255.                 // If outside columns, this is done in PaintDivBB
  10256.                 if ($this->ColActive) {
  10257.                     // OUTER FILL BGCOLOR of DIVS
  10258.                     if ($this->blklvl 0) {
  10259.                         $firstblockfill $this->GetFirstBlockFill();
  10260.                         if ($firstblockfill && $this->blklvl >= $firstblockfill) {
  10261.                             $divh $content[$i][0]['h'];
  10262.                             $bak_x $this->x;
  10263.                             $this->DivLn($divh, -3false);
  10264.                             // Reset current block fill
  10265.                             $bcor $this->blk[$this->blklvl]['bgcolorarray'];
  10266.                             $this->SetFColor($bcor);
  10267.                             $this->$bak_x;
  10268.                         }
  10269.                     }
  10270.                 }
  10271.                 /* -- END COLUMNS -- */
  10272.                 $colctr 0;
  10273.                 foreach ($content[$i] as $tablehf) {
  10274.                     $colctr++;
  10275.                     $y Arrays::get($tablehf'y'null) - $topy;
  10276.                     $this->$y;
  10277.                     // Set some cell values
  10278.                     $x Arrays::get($tablehf'x'null);
  10279.                     if (($this->mirrorMargins) && ($tablestartpage == 'ODD') && (($this->page) % == 0)) { // EVEN
  10280.                         $x $x $this->MarginCorrection;
  10281.                     } elseif (($this->mirrorMargins) && ($tablestartpage == 'EVEN') && (($this->page) % == 1)) { // ODD
  10282.                         $x $x $this->MarginCorrection;
  10283.                     }
  10284.                     /* -- COLUMNS -- */
  10285.                     // Added to correct for Columns
  10286.                     if ($this->ColActive) {
  10287.                         if ($this->directionality == 'rtl') { // *OTL*
  10288.                             $x -= ($this->CurrCol $tablestartcolumn) * ($this->ColWidth $this->ColGap); // *OTL*
  10289.                         // *OTL*
  10290.                         else { // *OTL*
  10291.                             $x += ($this->CurrCol $tablestartcolumn) * ($this->ColWidth $this->ColGap);
  10292.                         } // *OTL*
  10293.                     }
  10294.                     /* -- END COLUMNS -- */
  10295.                     if ($colctr == 1) {
  10296.                         $x0 $x;
  10297.                     }
  10298.                     // mPDF ITERATION
  10299.                     if ($this->iterationCounter) {
  10300.                         foreach ($tablehf['textbuffer'] as $k => $t) {
  10301.                             if (!is_array($t[0]) && preg_match('/{iteration ([a-zA-Z0-9_]+)}/'$t[0], $m)) {
  10302.                                 $vname '__' $m[1] . '_';
  10303.                                 if (!isset($this->$vname)) {
  10304.                                     $this->$vname 1;
  10305.                                 } else {
  10306.                                     $this->$vname++;
  10307.                                 }
  10308.                                 $tablehf['textbuffer'][$k][0] = preg_replace('/{iteration ' $m[1] . '}/'$this->$vname$tablehf['textbuffer'][$k][0]);
  10309.                             }
  10310.                         }
  10311.                     }
  10312.                     $w Arrays::get($tablehf'w'null);
  10313.                     $h Arrays::get($tablehf'h'null);
  10314.                     $va Arrays::get($tablehf'va'null);
  10315.                     $R Arrays::get($tablehf'R'null);
  10316.                     $direction Arrays::get($tablehf'direction'null);
  10317.                     $mih Arrays::get($tablehf'mih'null);
  10318.                     $border Arrays::get($tablehf'border'null);
  10319.                     $border_details Arrays::get($tablehf'border_details'null);
  10320.                     $padding Arrays::get($tablehf'padding'null);
  10321.                     $this->tabletheadjustfinished true;
  10322.                     $textbuffer Arrays::get($tablehf'textbuffer'null);
  10323.                     // Align
  10324.                     $align Arrays::get($tablehf'a'null);
  10325.                     $this->cellTextAlign $align;
  10326.                     $this->cellLineHeight Arrays::get($tablehf'cellLineHeight'null);
  10327.                     $this->cellLineStackingStrategy Arrays::get($tablehf'cellLineStackingStrategy'null);
  10328.                     $this->cellLineStackingShift Arrays::get($tablehf'cellLineStackingShift'null);
  10329.                     $this->$x;
  10330.                     if ($this->ColActive) {
  10331.                         if ($table['borders_separate']) {
  10332.                             $tablefill = isset($table['bgcolor'][-1]) ? $table['bgcolor'][-1] : 0;
  10333.                             if ($tablefill) {
  10334.                                 $color $this->colorConverter->convert($tablefill$this->PDFAXwarnings);
  10335.                                 if ($color) {
  10336.                                     $xadj = ($table['border_spacing_H'] / 2);
  10337.                                     $yadj = ($table['border_spacing_V'] / 2);
  10338.                                     $wadj $table['border_spacing_H'];
  10339.                                     $hadj $table['border_spacing_V'];
  10340.                                     if ($i == $firstrow && $horf == 'H') {  // Top
  10341.                                         $yadj += $table['padding']['T'] + $table['border_details']['T']['w'];
  10342.                                         $hadj += $table['padding']['T'] + $table['border_details']['T']['w'];
  10343.                                     }
  10344.                                     if (($i == ($lastrow) || (isset($tablehf['rowspan']) && ($i $tablehf['rowspan']) == ($lastrow 1)) || (!isset($tablehf['rowspan']) && ($i 1) == ($lastrow 1))) && $horf == 'F') { // Bottom
  10345.                                         $hadj += $table['padding']['B'] + $table['border_details']['B']['w'];
  10346.                                     }
  10347.                                     if ($colctr == 1) {  // Left
  10348.                                         $xadj += $table['padding']['L'] + $table['border_details']['L']['w'];
  10349.                                         $wadj += $table['padding']['L'] + $table['border_details']['L']['w'];
  10350.                                     }
  10351.                                     if ($colctr == count($content[$i])) { // Right
  10352.                                         $wadj += $table['padding']['R'] + $table['border_details']['R']['w'];
  10353.                                     }
  10354.                                     $this->SetFColor($color);
  10355.                                     $this->Rect($x $xadj$y $yadj$w $wadj$h $hadj'F');
  10356.                                 }
  10357.                             }
  10358.                         }
  10359.                     }
  10360.                     if ($table['empty_cells'] != 'hide' || !empty($textbuffer) || !$table['borders_separate']) {
  10361.                         $paintcell true;
  10362.                     } else {
  10363.                         $paintcell false;
  10364.                     }
  10365.                     // Vertical align
  10366.                     if ($R && intval($R) > && isset($va) && $va != 'B') {
  10367.                         $va 'B';
  10368.                     }
  10369.                     if (!isset($va) || empty($va) || $va == 'M') {
  10370.                         $this->+= ($h $mih) / 2;
  10371.                     } elseif (isset($va) && $va == 'B') {
  10372.                         $this->+= $h $mih;
  10373.                     }
  10374.                     // TABLE ROW OR CELL FILL BGCOLOR
  10375.                     $fill 0;
  10376.                     if (isset($tablehf['bgcolor']) && $tablehf['bgcolor'] && $tablehf['bgcolor'] != 'transparent') {
  10377.                         $fill $tablehf['bgcolor'];
  10378.                         $leveladj 6;
  10379.                     } elseif (isset($content[$i][0]['trbgcolor']) && $content[$i][0]['trbgcolor'] && $content[$i][0]['trbgcolor'] != 'transparent') { // Row color
  10380.                         $fill $content[$i][0]['trbgcolor'];
  10381.                         $leveladj 3;
  10382.                     }
  10383.                     if ($fill && $paintcell) {
  10384.                         $color $this->colorConverter->convert($fill$this->PDFAXwarnings);
  10385.                         if ($color) {
  10386.                             if ($table['borders_separate']) {
  10387.                                 if ($this->ColActive) {
  10388.                                     $this->SetFColor($color);
  10389.                                     $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');
  10390.                                 } else {
  10391.                                     $this->tableBackgrounds[$level $leveladj][] = ['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];
  10392.                                 }
  10393.                             } else {
  10394.                                 if ($this->ColActive) {
  10395.                                     $this->SetFColor($color);
  10396.                                     $this->Rect($x$y$w$h'F');
  10397.                                 } else {
  10398.                                     $this->tableBackgrounds[$level $leveladj][] = ['gradient' => false'x' => $x'y' => $y'w' => $w'h' => $h'col' => $color];
  10399.                                 }
  10400.                             }
  10401.                         }
  10402.                     }
  10403.                     /* -- BACKGROUNDS -- */
  10404.                     if (isset($tablehf['gradient']) && $tablehf['gradient'] && $paintcell) {
  10405.                         $g $this->gradient->parseBackgroundGradient($tablehf['gradient']);
  10406.                         if ($g) {
  10407.                             if ($table['borders_separate']) {
  10408.                                 $px $x + ($table['border_spacing_H'] / 2);
  10409.                                 $py $y + ($table['border_spacing_V'] / 2);
  10410.                                 $pw $w $table['border_spacing_H'];
  10411.                                 $ph $h $table['border_spacing_V'];
  10412.                             } else {
  10413.                                 $px $x;
  10414.                                 $py $y;
  10415.                                 $pw $w;
  10416.                                 $ph $h;
  10417.                             }
  10418.                             if ($this->ColActive) {
  10419.                                 $this->gradient->Gradient($px$py$pw$ph$g['type'], $g['stops'], $g['colorspace'], $g['coords'], $g['extend']);
  10420.                             } else {
  10421.                                 $this->tableBackgrounds[$level 7][] = ['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' => ''];
  10422.                             }
  10423.                         }
  10424.                     }
  10425.                     if (isset($tablehf['background-image']) && $paintcell) {
  10426.                         if ($tablehf['background-image']['gradient'] && preg_match('/(-moz-)*(repeating-)*(linear|radial)-gradient/'$tablehf['background-image']['gradient'])) {
  10427.                             $g $this->gradient->parseMozGradient($tablehf['background-image']['gradient']);
  10428.                             if ($g) {
  10429.                                 if ($table['borders_separate']) {
  10430.                                     $px $x + ($table['border_spacing_H'] / 2);
  10431.                                     $py $y + ($table['border_spacing_V'] / 2);
  10432.                                     $pw $w $table['border_spacing_H'];
  10433.                                     $ph $h $table['border_spacing_V'];
  10434.                                 } else {
  10435.                                     $px $x;
  10436.                                     $py $y;
  10437.                                     $pw $w;
  10438.                                     $ph $h;
  10439.                                 }
  10440.                                 if ($this->ColActive) {
  10441.                                     $this->gradient->Gradient($px$py$pw$ph$g['type'], $g['stops'], $g['colorspace'], $g['coords'], $g['extend']);
  10442.                                 } else {
  10443.                                     $this->tableBackgrounds[$level 7][] = ['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' => ''];
  10444.                                 }
  10445.                             }
  10446.                         } elseif ($tablehf['background-image']['image_id']) { // Background pattern
  10447.                             $n count($this->patterns) + 1;
  10448.                             if ($table['borders_separate']) {
  10449.                                 $px $x + ($table['border_spacing_H'] / 2);
  10450.                                 $py $y + ($table['border_spacing_V'] / 2);
  10451.                                 $pw $w $table['border_spacing_H'];
  10452.                                 $ph $h $table['border_spacing_V'];
  10453.                             } else {
  10454.                                 $px $x;
  10455.                                 $py $y;
  10456.                                 $pw $w;
  10457.                                 $ph $h;
  10458.                             }
  10459.                             if ($this->ColActive) {
  10460.                                 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']);
  10461.                                 $this->patterns[$n] = ['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']];
  10462.                                 if ($tablehf['background-image']['opacity'] > && $tablehf['background-image']['opacity'] < 1) {
  10463.                                     $opac $this->SetAlpha($tablehf['background-image']['opacity'], 'Normal'true);
  10464.                                 } else {
  10465.                                     $opac '';
  10466.                                 }
  10467.                                 $this->writer->write(sprintf('q /Pattern cs /P%d scn %s %.3F %.3F %.3F %.3F re f Q'$n$opac$px Mpdf::SCALE, ($this->$py) * Mpdf::SCALE$pw Mpdf::SCALE, -$ph Mpdf::SCALE));
  10468.                             } else {
  10469.                                 $this->tableBackgrounds[$level 8][] = ['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']];
  10470.                             }
  10471.                         }
  10472.                     }
  10473.                     /* -- END BACKGROUNDS -- */
  10474.                     // Cell Border
  10475.                     if ($table['borders_separate'] && $paintcell && $border) {
  10476.                         $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_detailsfalse$table['borders_separate']);
  10477.                     } elseif ($paintcell && $border) {
  10478.                         $this->_tableRect($x$y$w$h$border$border_detailstrue$table['borders_separate']);   // true causes buffer
  10479.                     }
  10480.                     // Print cell content
  10481.                     if (!empty($textbuffer)) {
  10482.                         if ($horf == 'F' && preg_match('/{colsum([0-9]*)[_]*}/'$textbuffer[0][0], $m)) {
  10483.                             $rep sprintf("%01." intval($m[1]) . "f"$this->colsums[$colctr 1]);
  10484.                             $textbuffer[0][0] = preg_replace('/{colsum[0-9_]*}/'$rep$textbuffer[0][0]);
  10485.                         }
  10486.                         if ($R) {
  10487.                             $cellPtSize $textbuffer[0][11] / $this->shrin_k;
  10488.                             if (!$cellPtSize) {
  10489.                                 $cellPtSize $this->default_font_size;
  10490.                             }
  10491.                             $cellFontHeight = ($cellPtSize Mpdf::SCALE);
  10492.                             $opx $this->x;
  10493.                             $opy $this->y;
  10494.                             $angle intval($R);
  10495.                             // Only allow 45 - 90 degrees (when bottom-aligned) or -90
  10496.                             if ($angle 90) {
  10497.                                 $angle 90;
  10498.                             } elseif ($angle && (isset($va) && $va != 'B')) {
  10499.                                 $angle 90;
  10500.                             } elseif ($angle && $angle 45) {
  10501.                                 $angle 45;
  10502.                             } elseif ($angle 0) {
  10503.                                 $angle = -90;
  10504.                             }
  10505.                             $offset = ((sin(deg2rad($angle))) * 0.37 $cellFontHeight);
  10506.                             if (isset($align) && $align == 'R') {
  10507.                                 $this->+= ($w) + ($offset) - ($cellFontHeight 3) - ($padding['R'] + $border_details['R']['w']);
  10508.                             } elseif (!isset($align) || $align == 'C') {
  10509.                                 $this->+= ($w 2) + ($offset);
  10510.                             } else {
  10511.                                 $this->+= ($offset) + ($cellFontHeight 3) + ($padding['L'] + $border_details['L']['w']);
  10512.                             }
  10513.                             $str '';
  10514.                             foreach ($tablehf['textbuffer'] as $t) {
  10515.                                 $str .= $t[0] . ' ';
  10516.                             }
  10517.                             $str rtrim($str);
  10518.                             if (!isset($va) || $va == 'M') {
  10519.                                 $this->-= ($h $mih) / 2// Undo what was added earlier VERTICAL ALIGN
  10520.                                 if ($angle 0) {
  10521.                                     $this->+= (($h $mih) / 2) + ($padding['T'] + $border_details['T']['w']) + ($mih - ($padding['T'] + $border_details['T']['w'] + $border_details['B']['w'] + $padding['B']));
  10522.                                 } elseif ($angle 0) {
  10523.                                     $this->+= (($h $mih) / 2) + ($padding['T'] + $border_details['T']['w']);
  10524.                                 }
  10525.                             } elseif (isset($va) && $va == 'B') {
  10526.                                 $this->-= $h $mih// Undo what was added earlier VERTICAL ALIGN
  10527.                                 if ($angle 0) {
  10528.                                     $this->+= $h - ($border_details['B']['w'] + $padding['B']);
  10529.                                 } elseif ($angle 0) {
  10530.                                     $this->+= $h $mih + ($padding['T'] + $border_details['T']['w']);
  10531.                                 }
  10532.                             } elseif (isset($va) && $va == 'T') {
  10533.                                 if ($angle 0) {
  10534.                                     $this->+= $mih - ($border_details['B']['w'] + $padding['B']);
  10535.                                 } elseif ($angle 0) {
  10536.                                     $this->+= ($padding['T'] + $border_details['T']['w']);
  10537.                                 }
  10538.                             }
  10539.                             $this->Rotate($angle$this->x$this->y);
  10540.                             $s_fs $this->FontSizePt;
  10541.                             $s_f $this->FontFamily;
  10542.                             $s_st $this->FontStyle;
  10543.                             if (!empty($textbuffer[0][3])) { // Font Color
  10544.                                 $cor $textbuffer[0][3];
  10545.                                 $this->SetTColor($cor);
  10546.                             }
  10547.                             $this->SetFont($textbuffer[0][4], $textbuffer[0][2], $cellPtSizetruetrue);
  10548.                             $this->magic_reverse_dir($str$this->directionality$textbuffer[0][18]);
  10549.                             $this->Text($this->x$this->y$str$textbuffer[0][18], $textbuffer[0][8]); // textvar
  10550.                             $this->Rotate(0);
  10551.                             $this->SetFont($s_f$s_st$s_fstruetrue);
  10552.                             $this->SetTColor(0);
  10553.                             $this->$opx;
  10554.                             $this->$opy;
  10555.                         } else {
  10556.                             if ($table['borders_separate']) { // NB twice border width
  10557.                                 $xadj $border_details['L']['w'] + $padding['L'] + ($table['border_spacing_H'] / 2);
  10558.                                 $wadj $border_details['L']['w'] + $border_details['R']['w'] + $padding['L'] + $padding['R'] + $table['border_spacing_H'];
  10559.                                 $yadj $border_details['T']['w'] + $padding['T'] + ($table['border_spacing_H'] / 2);
  10560.                             } else {
  10561.                                 $xadj $border_details['L']['w'] / $padding['L'];
  10562.                                 $wadj = ($border_details['L']['w'] + $border_details['R']['w']) / $padding['L'] + $padding['R'];
  10563.                                 $yadj $border_details['T']['w'] / $padding['T'];
  10564.                             }
  10565.                             $this->divwidth $w - ($wadj);
  10566.                             $this->+= $xadj;
  10567.                             $this->+= $yadj;
  10568.                             $this->printbuffer($textbuffer''truefalse$direction);
  10569.                         }
  10570.                     }
  10571.                     $textbuffer = [];
  10572.                     /* -- BACKGROUNDS -- */
  10573.                     if (!$this->ColActive) {
  10574.                         if (isset($content[$i][0]['trgradients']) && ($colctr == || $table['borders_separate'])) {
  10575.                             $g $this->gradient->parseBackgroundGradient($content[$i][0]['trgradients']);
  10576.                             if ($g) {
  10577.                                 $gx $x0;
  10578.                                 $gy $y;
  10579.                                 $gh $h;
  10580.                                 $gw $table['w'] - ($table['max_cell_border_width']['L'] / 2) - ($table['max_cell_border_width']['R'] / 2) - $table['margin']['L'] - $table['margin']['R'];
  10581.                                 if ($table['borders_separate']) {
  10582.                                     $gw -= ($table['padding']['L'] + $table['border_details']['L']['w'] + $table['padding']['R'] + $table['border_details']['R']['w'] + $table['border_spacing_H']);
  10583.                                     $clx $x + ($table['border_spacing_H'] / 2);
  10584.                                     $cly $y + ($table['border_spacing_V'] / 2);
  10585.                                     $clw $w $table['border_spacing_H'];
  10586.                                     $clh $h $table['border_spacing_V'];
  10587.                                     // Set clipping path
  10588.                                     $s $this->_setClippingPath($clx$cly$clw$clh); // mPDF 6
  10589.                                     $this->tableBackgrounds[$level 4][] = ['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];
  10590.                                 } else {
  10591.                                     $this->tableBackgrounds[$level 4][] = ['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' => ''];
  10592.                                 }
  10593.                             }
  10594.                         }
  10595.                         if (isset($content[$i][0]['trbackground-images']) && ($colctr == || $table['borders_separate'])) {
  10596.                             if ($content[$i][0]['trbackground-images']['gradient'] && preg_match('/(-moz-)*(repeating-)*(linear|radial)-gradient/'$content[$i][0]['trbackground-images']['gradient'])) {
  10597.                                 $g $this->gradient->parseMozGradient($content[$i][0]['trbackground-images']['gradient']);
  10598.                                 if ($g) {
  10599.                                     $gx $x0;
  10600.                                     $gy $y;
  10601.                                     $gh $h;
  10602.                                     $gw $table['w'] - ($table['max_cell_border_width']['L'] / 2) - ($table['max_cell_border_width']['R'] / 2) - $table['margin']['L'] - $table['margin']['R'];
  10603.                                     if ($table['borders_separate']) {
  10604.                                         $gw -= ($table['padding']['L'] + $table['border_details']['L']['w'] + $table['padding']['R'] + $table['border_details']['R']['w'] + $table['border_spacing_H']);
  10605.                                         $clx $x + ($table['border_spacing_H'] / 2);
  10606.                                         $cly $y + ($table['border_spacing_V'] / 2);
  10607.                                         $clw $w $table['border_spacing_H'];
  10608.                                         $clh $h $table['border_spacing_V'];
  10609.                                         // Set clipping path
  10610.                                         $s $this->_setClippingPath($clx$cly$clw$clh); // mPDF 6
  10611.                                         $this->tableBackgrounds[$level 4][] = ['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];
  10612.                                     } else {
  10613.                                         $this->tableBackgrounds[$level 4][] = ['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' => ''];
  10614.                                     }
  10615.                                 }
  10616.                             } else {
  10617.                                 $image_id $content[$i][0]['trbackground-images']['image_id'];
  10618.                                 $orig_w $content[$i][0]['trbackground-images']['orig_w'];
  10619.                                 $orig_h $content[$i][0]['trbackground-images']['orig_h'];
  10620.                                 $x_pos $content[$i][0]['trbackground-images']['x_pos'];
  10621.                                 $y_pos $content[$i][0]['trbackground-images']['y_pos'];
  10622.                                 $x_repeat $content[$i][0]['trbackground-images']['x_repeat'];
  10623.                                 $y_repeat $content[$i][0]['trbackground-images']['y_repeat'];
  10624.                                 $resize $content[$i][0]['trbackground-images']['resize'];
  10625.                                 $opacity $content[$i][0]['trbackground-images']['opacity'];
  10626.                                 $itype $content[$i][0]['trbackground-images']['itype'];
  10627.                                 $clippath '';
  10628.                                 $gx $x0;
  10629.                                 $gy $y;
  10630.                                 $gh $h;
  10631.                                 $gw $table['w'] - ($table['max_cell_border_width']['L'] / 2) - ($table['max_cell_border_width']['R'] / 2) - $table['margin']['L'] - $table['margin']['R'];
  10632.                                 if ($table['borders_separate']) {
  10633.                                     $gw -= ($table['padding']['L'] + $table['border_details']['L']['w'] + $table['padding']['R'] + $table['border_details']['R']['w'] + $table['border_spacing_H']);
  10634.                                     $clx $x + ($table['border_spacing_H'] / 2);
  10635.                                     $cly $y + ($table['border_spacing_V'] / 2);
  10636.                                     $clw $w $table['border_spacing_H'];
  10637.                                     $clh $h $table['border_spacing_V'];
  10638.                                     // Set clipping path
  10639.                                     $s $this->_setClippingPath($clx$cly$clw$clh); // mPDF 6
  10640.                                     $this->tableBackgrounds[$level 5][] = ['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];
  10641.                                 } else {
  10642.                                     $this->tableBackgrounds[$level 5][] = ['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];
  10643.                                 }
  10644.                             }
  10645.                         }
  10646.                     }
  10647.                     /* -- END BACKGROUNDS -- */
  10648.                     // TABLE BORDER - if separate OR collapsed and only table border
  10649.                     if (($table['borders_separate'] || ($this->simpleTables && !$table['simple']['border'])) && $table['border']) {
  10650.                         $halfspaceL $table['padding']['L'] + ($table['border_spacing_H'] / 2);
  10651.                         $halfspaceR $table['padding']['R'] + ($table['border_spacing_H'] / 2);
  10652.                         $halfspaceT $table['padding']['T'] + ($table['border_spacing_V'] / 2);
  10653.                         $halfspaceB $table['padding']['B'] + ($table['border_spacing_V'] / 2);
  10654.                         $tbx $x;
  10655.                         $tby $y;
  10656.                         $tbw $w;
  10657.                         $tbh $h;
  10658.                         $tab_bord 0;
  10659.                         $corner '';
  10660.                         if ($i == $firstrow && $horf == 'H') {  // Top
  10661.                             $tby -= $halfspaceT + ($table['border_details']['T']['w'] / 2);
  10662.                             $tbh += $halfspaceT + ($table['border_details']['T']['w'] / 2);
  10663.                             $this->setBorder($tab_bordBorder::TOP);
  10664.                             $corner .= 'T';
  10665.                         }
  10666.                         if (($i == ($lastrow) || (isset($tablehf['rowspan']) && ($i $tablehf['rowspan']) == ($lastrow 1))) && $horf == 'F') { // Bottom
  10667.                             $tbh += $halfspaceB + ($table['border_details']['B']['w'] / 2);
  10668.                             $this->setBorder($tab_bordBorder::BOTTOM);
  10669.                             $corner .= 'B';
  10670.                         }
  10671.                         if ($colctr == && $firstSpread) { // Left
  10672.                             $tbx -= $halfspaceL + ($table['border_details']['L']['w'] / 2);
  10673.                             $tbw += $halfspaceL + ($table['border_details']['L']['w'] / 2);
  10674.                             $this->setBorder($tab_bordBorder::LEFT);
  10675.                             $corner .= 'L';
  10676.                         }
  10677.                         if ($colctr == count($content[$i]) && $finalSpread) { // Right
  10678.                             $tbw += $halfspaceR + ($table['border_details']['R']['w'] / 2);
  10679.                             $this->setBorder($tab_bordBorder::RIGHT);
  10680.                             $corner .= 'R';
  10681.                         }
  10682.                         $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']);
  10683.                     }
  10684.                 }// end column $content
  10685.                 $this->$y $h// Update y coordinate
  10686.             }// end row $i
  10687.             unset($table);
  10688.             $this->colsums = [];
  10689.         }
  10690.     }
  10691.     /* -- END TABLES -- */
  10692.     function SetHTMLHeader($header ''$OE ''$write false)
  10693.     {
  10694.         $height 0;
  10695.         if (is_array($header) && isset($header['html']) && $header['html']) {
  10696.             $Hhtml $header['html'];
  10697.             if ($this->setAutoTopMargin) {
  10698.                 if (isset($header['h'])) {
  10699.                     $height $header['h'];
  10700.                 } else {
  10701.                     $height $this->_getHtmlHeight($Hhtml);
  10702.                 }
  10703.             }
  10704.         } elseif (!is_array($header) && $header) {
  10705.             $Hhtml $header;
  10706.             if ($this->setAutoTopMargin) {
  10707.                 $height $this->_getHtmlHeight($Hhtml);
  10708.             }
  10709.         } else {
  10710.             $Hhtml '';
  10711.         }
  10712.         if ($OE !== 'E') {
  10713.             $OE 'O';
  10714.         }
  10715.         if ($OE === 'E') {
  10716.             if ($Hhtml) {
  10717.                 $this->HTMLHeaderE = [];
  10718.                 $this->HTMLHeaderE['html'] = $Hhtml;
  10719.                 $this->HTMLHeaderE['h'] = $height;
  10720.             } else {
  10721.                 $this->HTMLHeaderE '';
  10722.             }
  10723.         } else {
  10724.             if ($Hhtml) {
  10725.                 $this->HTMLHeader = [];
  10726.                 $this->HTMLHeader['html'] = $Hhtml;
  10727.                 $this->HTMLHeader['h'] = $height;
  10728.             } else {
  10729.                 $this->HTMLHeader '';
  10730.             }
  10731.         }
  10732.         if (!$this->mirrorMargins && $OE == 'E') {
  10733.             return;
  10734.         }
  10735.         if ($Hhtml == '') {
  10736.             return;
  10737.         }
  10738.         if ($this->setAutoTopMargin == 'pad') {
  10739.             $this->tMargin $this->margin_header $height $this->orig_tMargin;
  10740.             if (isset($this->saveHTMLHeader[$this->page][$OE]['mt'])) {
  10741.                 $this->saveHTMLHeader[$this->page][$OE]['mt'] = $this->tMargin;
  10742.             }
  10743.         } elseif ($this->setAutoTopMargin == 'stretch') {
  10744.             $this->tMargin max($this->orig_tMargin$this->margin_header $height $this->autoMarginPadding);
  10745.             if (isset($this->saveHTMLHeader[$this->page][$OE]['mt'])) {
  10746.                 $this->saveHTMLHeader[$this->page][$OE]['mt'] = $this->tMargin;
  10747.             }
  10748.         }
  10749.         if ($write && $this->state != && (($this->mirrorMargins && $OE == 'E' && ($this->page) % == 0) || ($this->mirrorMargins && $OE != 'E' && ($this->page) % == 1) || !$this->mirrorMargins)) {
  10750.             $this->writeHTMLHeaders();
  10751.         }
  10752.     }
  10753.     function SetHTMLFooter($footer ''$OE '')
  10754.     {
  10755.         $height 0;
  10756.         if (is_array($footer) && isset($footer['html']) && $footer['html']) {
  10757.             $Fhtml $footer['html'];
  10758.             if ($this->setAutoBottomMargin) {
  10759.                 if (isset($footer['h'])) {
  10760.                     $height $footer['h'];
  10761.                 } else {
  10762.                     $height $this->_getHtmlHeight($Fhtml);
  10763.                 }
  10764.             }
  10765.         } elseif (!is_array($footer) && $footer) {
  10766.             $Fhtml $footer;
  10767.             if ($this->setAutoBottomMargin) {
  10768.                 $height $this->_getHtmlHeight($Fhtml);
  10769.             }
  10770.         } else {
  10771.             $Fhtml '';
  10772.         }
  10773.         if ($OE !== 'E') {
  10774.             $OE 'O';
  10775.         }
  10776.         if ($OE === 'E') {
  10777.             if ($Fhtml) {
  10778.                 $this->HTMLFooterE = [];
  10779.                 $this->HTMLFooterE['html'] = $Fhtml;
  10780.                 $this->HTMLFooterE['h'] = $height;
  10781.             } else {
  10782.                 $this->HTMLFooterE '';
  10783.             }
  10784.         } else {
  10785.             if ($Fhtml) {
  10786.                 $this->HTMLFooter = [];
  10787.                 $this->HTMLFooter['html'] = $Fhtml;
  10788.                 $this->HTMLFooter['h'] = $height;
  10789.             } else {
  10790.                 $this->HTMLFooter '';
  10791.             }
  10792.         }
  10793.         if (!$this->mirrorMargins && $OE == 'E') {
  10794.             return;
  10795.         }
  10796.         if ($Fhtml == '') {
  10797.             return false;
  10798.         }
  10799.         if ($this->setAutoBottomMargin == 'pad') {
  10800.             $this->bMargin $this->margin_footer $height $this->orig_bMargin;
  10801.             $this->PageBreakTrigger $this->$this->bMargin;
  10802.             if (isset($this->saveHTMLHeader[$this->page][$OE]['mb'])) {
  10803.                 $this->saveHTMLHeader[$this->page][$OE]['mb'] = $this->bMargin;
  10804.             }
  10805.         } elseif ($this->setAutoBottomMargin == 'stretch') {
  10806.             $this->bMargin max($this->orig_bMargin$this->margin_footer $height $this->autoMarginPadding);
  10807.             $this->PageBreakTrigger $this->$this->bMargin;
  10808.             if (isset($this->saveHTMLHeader[$this->page][$OE]['mb'])) {
  10809.                 $this->saveHTMLHeader[$this->page][$OE]['mb'] = $this->bMargin;
  10810.             }
  10811.         }
  10812.     }
  10813.     function _getHtmlHeight($html)
  10814.     {
  10815.         $save_state $this->state;
  10816.         if ($this->state == 0) {
  10817.             $this->AddPage($this->CurOrientation);
  10818.         }
  10819.         $this->state 2;
  10820.         $this->Reset();
  10821.         $this->pageoutput[$this->page] = [];
  10822.         $save_x $this->x;
  10823.         $save_y $this->y;
  10824.         $this->$this->lMargin;
  10825.         $this->$this->margin_header;
  10826.         // Replace of page number aliases and date format
  10827.         $pnstr $this->pagenumPrefix $this->docPageNum($this->page) . $this->pagenumSuffix;
  10828.         $pntstr $this->nbpgPrefix $this->docPageNumTotal($this->page) . $this->nbpgSuffix;
  10829.         $nb $this->page;
  10830.         $html $this->aliasReplace($html$pnstr$pntstr$nb);
  10831.         $this->HTMLheaderPageLinks = [];
  10832.         $this->HTMLheaderPageAnnots = [];
  10833.         $this->HTMLheaderPageForms = [];
  10834.         $savepb $this->pageBackgrounds;
  10835.         $this->writingHTMLheader true;
  10836.         $this->WriteHTML($htmlHTMLParserMode::HTML_HEADER_BUFFER);
  10837.         $this->writingHTMLheader false;
  10838.         $h = ($this->$this->margin_header);
  10839.         $this->Reset();
  10840.         // mPDF 5.7.2 - Clear in case Float used in Header/Footer
  10841.         $this->blk[0]['blockContext'] = 0;
  10842.         $this->blk[0]['float_endpos'] = 0;
  10843.         $this->pageoutput[$this->page] = [];
  10844.         $this->headerbuffer '';
  10845.         $this->pageBackgrounds $savepb;
  10846.         $this->$save_x;
  10847.         $this->$save_y;
  10848.         $this->state $save_state;
  10849.         if ($save_state == 0) {
  10850.             unset($this->pages[1]);
  10851.             $this->page 0;
  10852.         }
  10853.         return $h;
  10854.     }
  10855.     // Called internally from Header
  10856.     function writeHTMLHeaders()
  10857.     {
  10858.         if ($this->mirrorMargins && ($this->page) % == 0) {
  10859.             $OE 'E';
  10860.         } else {
  10861.             $OE 'O';
  10862.         }
  10863.         if ($OE === 'E') {
  10864.             $this->saveHTMLHeader[$this->page][$OE]['html'] = $this->HTMLHeaderE['html'];
  10865.         } else {
  10866.             $this->saveHTMLHeader[$this->page][$OE]['html'] = $this->HTMLHeader['html'];
  10867.         }
  10868.         if ($this->forcePortraitHeaders && $this->CurOrientation == 'L' && $this->CurOrientation != $this->DefOrientation) {
  10869.             $this->saveHTMLHeader[$this->page][$OE]['rotate'] = true;
  10870.             $this->saveHTMLHeader[$this->page][$OE]['ml'] = $this->tMargin;
  10871.             $this->saveHTMLHeader[$this->page][$OE]['mr'] = $this->bMargin;
  10872.             $this->saveHTMLHeader[$this->page][$OE]['mh'] = $this->margin_header;
  10873.             $this->saveHTMLHeader[$this->page][$OE]['mf'] = $this->margin_footer;
  10874.             $this->saveHTMLHeader[$this->page][$OE]['pw'] = $this->h;
  10875.             $this->saveHTMLHeader[$this->page][$OE]['ph'] = $this->w;
  10876.         } else {
  10877.             $this->saveHTMLHeader[$this->page][$OE]['ml'] = $this->lMargin;
  10878.             $this->saveHTMLHeader[$this->page][$OE]['mr'] = $this->rMargin;
  10879.             $this->saveHTMLHeader[$this->page][$OE]['mh'] = $this->margin_header;
  10880.             $this->saveHTMLHeader[$this->page][$OE]['mf'] = $this->margin_footer;
  10881.             $this->saveHTMLHeader[$this->page][$OE]['pw'] = $this->w;
  10882.             $this->saveHTMLHeader[$this->page][$OE]['ph'] = $this->h;
  10883.         }
  10884.     }
  10885.     function writeHTMLFooters()
  10886.     {
  10887.         if ($this->mirrorMargins && ($this->page) % == 0) {
  10888.             $OE 'E';
  10889.         } else {
  10890.             $OE 'O';
  10891.         }
  10892.         if ($OE === 'E') {
  10893.             $this->saveHTMLFooter[$this->page][$OE]['html'] = $this->HTMLFooterE['html'];
  10894.         } else {
  10895.             $this->saveHTMLFooter[$this->page][$OE]['html'] = $this->HTMLFooter['html'];
  10896.         }
  10897.         if ($this->forcePortraitHeaders && $this->CurOrientation == 'L' && $this->CurOrientation != $this->DefOrientation) {
  10898.             $this->saveHTMLFooter[$this->page][$OE]['rotate'] = true;
  10899.             $this->saveHTMLFooter[$this->page][$OE]['ml'] = $this->tMargin;
  10900.             $this->saveHTMLFooter[$this->page][$OE]['mr'] = $this->bMargin;
  10901.             $this->saveHTMLFooter[$this->page][$OE]['mt'] = $this->rMargin;
  10902.             $this->saveHTMLFooter[$this->page][$OE]['mb'] = $this->lMargin;
  10903.             $this->saveHTMLFooter[$this->page][$OE]['mh'] = $this->margin_header;
  10904.             $this->saveHTMLFooter[$this->page][$OE]['mf'] = $this->margin_footer;
  10905.             $this->saveHTMLFooter[$this->page][$OE]['pw'] = $this->h;
  10906.             $this->saveHTMLFooter[$this->page][$OE]['ph'] = $this->w;
  10907.         } else {
  10908.             $this->saveHTMLFooter[$this->page][$OE]['ml'] = $this->lMargin;
  10909.             $this->saveHTMLFooter[$this->page][$OE]['mr'] = $this->rMargin;
  10910.             $this->saveHTMLFooter[$this->page][$OE]['mt'] = $this->tMargin;
  10911.             $this->saveHTMLFooter[$this->page][$OE]['mb'] = $this->bMargin;
  10912.             $this->saveHTMLFooter[$this->page][$OE]['mh'] = $this->margin_header;
  10913.             $this->saveHTMLFooter[$this->page][$OE]['mf'] = $this->margin_footer;
  10914.             $this->saveHTMLFooter[$this->page][$OE]['pw'] = $this->w;
  10915.             $this->saveHTMLFooter[$this->page][$OE]['ph'] = $this->h;
  10916.         }
  10917.     }
  10918.     // mPDF 6
  10919.     function _shareHeaderFooterWidth($cl$cc$cr)
  10920.     {
  10921.     // mPDF 6
  10922.         $l mb_strlen($cl'UTF-8');
  10923.         $c mb_strlen($cc'UTF-8');
  10924.         $r mb_strlen($cr'UTF-8');
  10925.         $s max($l$r);
  10926.         $tw $c $s;
  10927.         if ($tw 0) {
  10928.             return [intval($s 100 $tw), intval($c 100 $tw), intval($s 100 $tw)];
  10929.         } else {
  10930.             return [333333];
  10931.         }
  10932.     }
  10933.     // mPDF 6
  10934.     // Create an HTML header/footer from array (non-HTML header/footer)
  10935.     function _createHTMLheaderFooter($arr$hf)
  10936.     {
  10937.         $lContent = (isset($arr['L']['content']) ? $arr['L']['content'] : '');
  10938.         $cContent = (isset($arr['C']['content']) ? $arr['C']['content'] : '');
  10939.         $rContent = (isset($arr['R']['content']) ? $arr['R']['content'] : '');
  10940.         list($lw$cw$rw) = $this->_shareHeaderFooterWidth($lContent$cContent$rContent);
  10941.         if ($hf == 'H') {
  10942.             $valign 'bottom';
  10943.             $vpadding '0 0 ' $this->header_line_spacing 'em 0';
  10944.         } else {
  10945.             $valign 'top';
  10946.             $vpadding '' $this->footer_line_spacing 'em 0 0 0';
  10947.         }
  10948.         if ($this->directionality == 'rtl') { // table columns get reversed so need different text-alignment
  10949.             $talignL 'right';
  10950.             $talignR 'left';
  10951.         } else {
  10952.             $talignL 'left';
  10953.             $talignR 'right';
  10954.         }
  10955.         $html '<table width="100%" style="border-collapse: collapse; margin: 0; vertical-align: ' $valign '; color: #000000; ';
  10956.         if (isset($arr['line']) && $arr['line']) {
  10957.             $html .= ' border-' $valign ': 0.1mm solid #000000;';
  10958.         }
  10959.         $html .= '">';
  10960.         $html .= '<tr>';
  10961.         $html .= '<td width="' $lw '%" style="padding: ' $vpadding '; text-align: ' $talignL '; ';
  10962.         if (isset($arr['L']['font-family'])) {
  10963.             $html .= ' font-family: ' $arr['L']['font-family'] . ';';
  10964.         }
  10965.         if (isset($arr['L']['color'])) {
  10966.             $html .= ' color: ' $arr['L']['color'] . ';';
  10967.         }
  10968.         if (isset($arr['L']['font-size'])) {
  10969.             $html .= ' font-size: ' $arr['L']['font-size'] . 'pt;';
  10970.         }
  10971.         if (isset($arr['L']['font-style'])) {
  10972.             if ($arr['L']['font-style'] == 'B' || $arr['L']['font-style'] == 'BI') {
  10973.                 $html .= ' font-weight: bold;';
  10974.             }
  10975.             if ($arr['L']['font-style'] == 'I' || $arr['L']['font-style'] == 'BI') {
  10976.                 $html .= ' font-style: italic;';
  10977.             }
  10978.         }
  10979.         $html .= '">' $lContent '</td>';
  10980.         $html .= '<td width="' $cw '%" style="padding: ' $vpadding '; text-align: center; ';
  10981.         if (isset($arr['C']['font-family'])) {
  10982.             $html .= ' font-family: ' $arr['C']['font-family'] . ';';
  10983.         }
  10984.         if (isset($arr['C']['color'])) {
  10985.             $html .= ' color: ' $arr['C']['color'] . ';';
  10986.         }
  10987.         if (isset($arr['C']['font-size'])) {
  10988.             $html .= ' font-size: ' $arr['C']['font-size'] . 'pt;';
  10989.         }
  10990.         if (isset($arr['C']['font-style'])) {
  10991.             if ($arr['C']['font-style'] == 'B' || $arr['C']['font-style'] == 'BI') {
  10992.                 $html .= ' font-weight: bold;';
  10993.             }
  10994.             if ($arr['C']['font-style'] == 'I' || $arr['C']['font-style'] == 'BI') {
  10995.                 $html .= ' font-style: italic;';
  10996.             }
  10997.         }
  10998.         $html .= '">' $cContent '</td>';
  10999.         $html .= '<td width="' $rw '%" style="padding: ' $vpadding '; text-align: ' $talignR '; ';
  11000.         if (isset($arr['R']['font-family'])) {
  11001.             $html .= ' font-family: ' $arr['R']['font-family'] . ';';
  11002.         }
  11003.         if (isset($arr['R']['color'])) {
  11004.             $html .= ' color: ' $arr['R']['color'] . ';';
  11005.         }
  11006.         if (isset($arr['R']['font-size'])) {
  11007.             $html .= ' font-size: ' $arr['R']['font-size'] . 'pt;';
  11008.         }
  11009.         if (isset($arr['R']['font-style'])) {
  11010.             if ($arr['R']['font-style'] == 'B' || $arr['R']['font-style'] == 'BI') {
  11011.                 $html .= ' font-weight: bold;';
  11012.             }
  11013.             if ($arr['R']['font-style'] == 'I' || $arr['R']['font-style'] == 'BI') {
  11014.                 $html .= ' font-style: italic;';
  11015.             }
  11016.         }
  11017.         $html .= '">' $rContent '</td>';
  11018.         $html .= '</tr></table>';
  11019.         return $html;
  11020.     }
  11021.     function DefHeaderByName($name$arr)
  11022.     {
  11023.         if (!$name) {
  11024.             $name '_nonhtmldefault';
  11025.         }
  11026.         $html $this->_createHTMLheaderFooter($arr'H');
  11027.         $this->pageHTMLheaders[$name]['html'] = $html;
  11028.         $this->pageHTMLheaders[$name]['h'] = $this->_getHtmlHeight($html);
  11029.     }
  11030.     function DefFooterByName($name$arr)
  11031.     {
  11032.         if (!$name) {
  11033.             $name '_nonhtmldefault';
  11034.         }
  11035.         $html $this->_createHTMLheaderFooter($arr'F');
  11036.         $this->pageHTMLfooters[$name]['html'] = $html;
  11037.         $this->pageHTMLfooters[$name]['h'] = $this->_getHtmlHeight($html);
  11038.     }
  11039.     function SetHeaderByName($name$side 'O'$write false)
  11040.     {
  11041.         if (!$name) {
  11042.             $name '_nonhtmldefault';
  11043.         }
  11044.         $this->SetHTMLHeader($this->pageHTMLheaders[$name], $side$write);
  11045.     }
  11046.     function SetFooterByName($name$side 'O')
  11047.     {
  11048.         if (!$name) {
  11049.             $name '_nonhtmldefault';
  11050.         }
  11051.         $this->SetHTMLFooter($this->pageHTMLfooters[$name], $side);
  11052.     }
  11053.     function DefHTMLHeaderByName($name$html)
  11054.     {
  11055.         if (!$name) {
  11056.             $name '_default';
  11057.         }
  11058.         $this->pageHTMLheaders[$name]['html'] = $html;
  11059.         $this->pageHTMLheaders[$name]['h'] = $this->_getHtmlHeight($html);
  11060.     }
  11061.     function DefHTMLFooterByName($name$html)
  11062.     {
  11063.         if (!$name) {
  11064.             $name '_default';
  11065.         }
  11066.         $this->pageHTMLfooters[$name]['html'] = $html;
  11067.         $this->pageHTMLfooters[$name]['h'] = $this->_getHtmlHeight($html);
  11068.     }
  11069.     function SetHTMLHeaderByName($name$side 'O'$write false)
  11070.     {
  11071.         if (!$name) {
  11072.             $name '_default';
  11073.         }
  11074.         $this->SetHTMLHeader($this->pageHTMLheaders[$name], $side$write);
  11075.     }
  11076.     function SetHTMLFooterByName($name$side 'O')
  11077.     {
  11078.         if (!$name) {
  11079.             $name '_default';
  11080.         }
  11081.         $this->SetHTMLFooter($this->pageHTMLfooters[$name], $side);
  11082.     }
  11083.     function SetHeader($Harray = [], $side ''$write false)
  11084.     {
  11085.         $oddhtml '';
  11086.         $evenhtml '';
  11087.         if (is_string($Harray)) {
  11088.             if (strlen($Harray) === 0) {
  11089.                 $oddhtml '';
  11090.                 $evenhtml '';
  11091.             } elseif (strpos($Harray'|') !== false) {
  11092.                 $hdet explode('|'$Harray);
  11093.                 list($lw$cw$rw) = $this->_shareHeaderFooterWidth($hdet[0], $hdet[1], $hdet[2]);
  11094.                 $oddhtml '<table width="100%" style="border-collapse: collapse; margin: 0; vertical-align: bottom; color: #000000; ';
  11095.                 if ($this->defaultheaderfontsize) {
  11096.                     $oddhtml .= ' font-size: ' $this->defaultheaderfontsize 'pt;';
  11097.                 }
  11098.                 if ($this->defaultheaderfontstyle) {
  11099.                     if ($this->defaultheaderfontstyle == 'B' || $this->defaultheaderfontstyle == 'BI') {
  11100.                         $oddhtml .= ' font-weight: bold;';
  11101.                     }
  11102.                     if ($this->defaultheaderfontstyle == 'I' || $this->defaultheaderfontstyle == 'BI') {
  11103.                         $oddhtml .= ' font-style: italic;';
  11104.                     }
  11105.                 }
  11106.                 if ($this->defaultheaderline) {
  11107.                     $oddhtml .= ' border-bottom: 0.1mm solid #000000;';
  11108.                 }
  11109.                 $oddhtml .= '">';
  11110.                 $oddhtml .= '<tr>';
  11111.                 $oddhtml .= '<td width="' $lw '%" style="padding: 0 0 ' $this->header_line_spacing 'em 0; text-align: left; ">' $hdet[0] . '</td>';
  11112.                 $oddhtml .= '<td width="' $cw '%" style="padding: 0 0 ' $this->header_line_spacing 'em 0; text-align: center; ">' $hdet[1] . '</td>';
  11113.                 $oddhtml .= '<td width="' $rw '%" style="padding: 0 0 ' $this->header_line_spacing 'em 0; text-align: right; ">' $hdet[2] . '</td>';
  11114.                 $oddhtml .= '</tr></table>';
  11115.                 $evenhtml '<table width="100%" style="border-collapse: collapse; margin: 0; vertical-align: bottom; color: #000000; ';
  11116.                 if ($this->defaultheaderfontsize) {
  11117.                     $evenhtml .= ' font-size: ' $this->defaultheaderfontsize 'pt;';
  11118.                 }
  11119.                 if ($this->defaultheaderfontstyle) {
  11120.                     if ($this->defaultheaderfontstyle == 'B' || $this->defaultheaderfontstyle == 'BI') {
  11121.                         $evenhtml .= ' font-weight: bold;';
  11122.                     }
  11123.                     if ($this->defaultheaderfontstyle == 'I' || $this->defaultheaderfontstyle == 'BI') {
  11124.                         $evenhtml .= ' font-style: italic;';
  11125.                     }
  11126.                 }
  11127.                 if ($this->defaultheaderline) {
  11128.                     $evenhtml .= ' border-bottom: 0.1mm solid #000000;';
  11129.                 }
  11130.                 $evenhtml .= '">';
  11131.                 $evenhtml .= '<tr>';
  11132.                 $evenhtml .= '<td width="' $rw '%" style="padding: 0 0 ' $this->header_line_spacing 'em 0; text-align: left; ">' $hdet[2] . '</td>';
  11133.                 $evenhtml .= '<td width="' $cw '%" style="padding: 0 0 ' $this->header_line_spacing 'em 0; text-align: center; ">' $hdet[1] . '</td>';
  11134.                 $evenhtml .= '<td width="' $lw '%" style="padding: 0 0 ' $this->header_line_spacing 'em 0; text-align: right; ">' $hdet[0] . '</td>';
  11135.                 $evenhtml .= '</tr></table>';
  11136.             } else {
  11137.                 $oddhtml '<div style="margin: 0; color: #000000; ';
  11138.                 if ($this->defaultheaderfontsize) {
  11139.                     $oddhtml .= ' font-size: ' $this->defaultheaderfontsize 'pt;';
  11140.                 }
  11141.                 if ($this->defaultheaderfontstyle) {
  11142.                     if ($this->defaultheaderfontstyle == 'B' || $this->defaultheaderfontstyle == 'BI') {
  11143.                         $oddhtml .= ' font-weight: bold;';
  11144.                     }
  11145.                     if ($this->defaultheaderfontstyle == 'I' || $this->defaultheaderfontstyle == 'BI') {
  11146.                         $oddhtml .= ' font-style: italic;';
  11147.                     }
  11148.                 }
  11149.                 if ($this->defaultheaderline) {
  11150.                     $oddhtml .= ' border-bottom: 0.1mm solid #000000;';
  11151.                 }
  11152.                 $oddhtml .= 'text-align: right; ">' $Harray '</div>';
  11153.                 $evenhtml '<div style="margin: 0; color: #000000; ';
  11154.                 if ($this->defaultheaderfontsize) {
  11155.                     $evenhtml .= ' font-size: ' $this->defaultheaderfontsize 'pt;';
  11156.                 }
  11157.                 if ($this->defaultheaderfontstyle) {
  11158.                     if ($this->defaultheaderfontstyle == 'B' || $this->defaultheaderfontstyle == 'BI') {
  11159.                         $evenhtml .= ' font-weight: bold;';
  11160.                     }
  11161.                     if ($this->defaultheaderfontstyle == 'I' || $this->defaultheaderfontstyle == 'BI') {
  11162.                         $evenhtml .= ' font-style: italic;';
  11163.                     }
  11164.                 }
  11165.                 if ($this->defaultheaderline) {
  11166.                     $evenhtml .= ' border-bottom: 0.1mm solid #000000;';
  11167.                 }
  11168.                 $evenhtml .= 'text-align: left; ">' $Harray '</div>';
  11169.             }
  11170.         } elseif (is_array($Harray) && !empty($Harray)) {
  11171.             $odd null;
  11172.             $even null;
  11173.             if ($side === 'O') {
  11174.                 $odd $Harray;
  11175.             } elseif ($side === 'E') {
  11176.                 $even $Harray;
  11177.             } else {
  11178.                 $odd Arrays::get($Harray'odd'null);
  11179.                 $even Arrays::get($Harray'even'null);
  11180.             }
  11181.             $oddhtml $this->_createHTMLheaderFooter($odd'H');
  11182.             $evenhtml $this->_createHTMLheaderFooter($even'H');
  11183.         }
  11184.         if ($side === 'E') {
  11185.             $this->SetHTMLHeader($evenhtml'E'$write);
  11186.         } elseif ($side === 'O') {
  11187.             $this->SetHTMLHeader($oddhtml'O'$write);
  11188.         } else {
  11189.             $this->SetHTMLHeader($oddhtml'O'$write);
  11190.             $this->SetHTMLHeader($evenhtml'E'$write);
  11191.         }
  11192.     }
  11193.     function SetFooter($Farray = [], $side '')
  11194.     {
  11195.         $oddhtml '';
  11196.         $evenhtml '';
  11197.         if (is_string($Farray)) {
  11198.             if (strlen($Farray) == 0) {
  11199.                 $oddhtml '';
  11200.                 $evenhtml '';
  11201.             } elseif (strpos($Farray'|') !== false) {
  11202.                 $hdet explode('|'$Farray);
  11203.                 $oddhtml '<table width="100%" style="border-collapse: collapse; margin: 0; vertical-align: top; color: #000000; ';
  11204.                 if ($this->defaultfooterfontsize) {
  11205.                     $oddhtml .= ' font-size: ' $this->defaultfooterfontsize 'pt;';
  11206.                 }
  11207.                 if ($this->defaultfooterfontstyle) {
  11208.                     if ($this->defaultfooterfontstyle == 'B' || $this->defaultfooterfontstyle == 'BI') {
  11209.                         $oddhtml .= ' font-weight: bold;';
  11210.                     }
  11211.                     if ($this->defaultfooterfontstyle == 'I' || $this->defaultfooterfontstyle == 'BI') {
  11212.                         $oddhtml .= ' font-style: italic;';
  11213.                     }
  11214.                 }
  11215.                 if ($this->defaultfooterline) {
  11216.                     $oddhtml .= ' border-top: 0.1mm solid #000000;';
  11217.                 }
  11218.                 $oddhtml .= '">';
  11219.                 $oddhtml .= '<tr>';
  11220.                 $oddhtml .= '<td width="33%" style="padding: ' $this->footer_line_spacing 'em 0 0 0; text-align: left; ">' $hdet[0] . '</td>';
  11221.                 $oddhtml .= '<td width="33%" style="padding: ' $this->footer_line_spacing 'em 0 0 0; text-align: center; ">' $hdet[1] . '</td>';
  11222.                 $oddhtml .= '<td width="33%" style="padding: ' $this->footer_line_spacing 'em 0 0 0; text-align: right; ">' $hdet[2] . '</td>';
  11223.                 $oddhtml .= '</tr></table>';
  11224.                 $evenhtml '<table width="100%" style="border-collapse: collapse; margin: 0; vertical-align: top; color: #000000; ';
  11225.                 if ($this->defaultfooterfontsize) {
  11226.                     $evenhtml .= ' font-size: ' $this->defaultfooterfontsize 'pt;';
  11227.                 }
  11228.                 if ($this->defaultfooterfontstyle) {
  11229.                     if ($this->defaultfooterfontstyle == 'B' || $this->defaultfooterfontstyle == 'BI') {
  11230.                         $evenhtml .= ' font-weight: bold;';
  11231.                     }
  11232.                     if ($this->defaultfooterfontstyle == 'I' || $this->defaultfooterfontstyle == 'BI') {
  11233.                         $evenhtml .= ' font-style: italic;';
  11234.                     }
  11235.                 }
  11236.                 if ($this->defaultfooterline) {
  11237.                     $evenhtml .= ' border-top: 0.1mm solid #000000;';
  11238.                 }
  11239.                 $evenhtml .= '">';
  11240.                 $evenhtml .= '<tr>';
  11241.                 $evenhtml .= '<td width="33%" style="padding: ' $this->footer_line_spacing 'em 0 0 0; text-align: left; ">' $hdet[2] . '</td>';
  11242.                 $evenhtml .= '<td width="33%" style="padding: ' $this->footer_line_spacing 'em 0 0 0; text-align: center; ">' $hdet[1] . '</td>';
  11243.                 $evenhtml .= '<td width="33%" style="padding: ' $this->footer_line_spacing 'em 0 0 0; text-align: right; ">' $hdet[0] . '</td>';
  11244.                 $evenhtml .= '</tr></table>';
  11245.             } else {
  11246.                 $oddhtml '<div style="margin: 0; color: #000000; ';
  11247.                 if ($this->defaultfooterfontsize) {
  11248.                     $oddhtml .= ' font-size: ' $this->defaultfooterfontsize 'pt;';
  11249.                 }
  11250.                 if ($this->defaultfooterfontstyle) {
  11251.                     if ($this->defaultfooterfontstyle == 'B' || $this->defaultfooterfontstyle == 'BI') {
  11252.                         $oddhtml .= ' font-weight: bold;';
  11253.                     }
  11254.                     if ($this->defaultfooterfontstyle == 'I' || $this->defaultfooterfontstyle == 'BI') {
  11255.                         $oddhtml .= ' font-style: italic;';
  11256.                     }
  11257.                 }
  11258.                 if ($this->defaultfooterline) {
  11259.                     $oddhtml .= ' border-top: 0.1mm solid #000000;';
  11260.                 }
  11261.                 $oddhtml .= 'text-align: right; ">' $Farray '</div>';
  11262.                 $evenhtml '<div style="margin: 0; color: #000000; ';
  11263.                 if ($this->defaultfooterfontsize) {
  11264.                     $evenhtml .= ' font-size: ' $this->defaultfooterfontsize 'pt;';
  11265.                 }
  11266.                 if ($this->defaultfooterfontstyle) {
  11267.                     if ($this->defaultfooterfontstyle == 'B' || $this->defaultfooterfontstyle == 'BI') {
  11268.                         $evenhtml .= ' font-weight: bold;';
  11269.                     }
  11270.                     if ($this->defaultfooterfontstyle == 'I' || $this->defaultfooterfontstyle == 'BI') {
  11271.                         $evenhtml .= ' font-style: italic;';
  11272.                     }
  11273.                 }
  11274.                 if ($this->defaultfooterline) {
  11275.                     $evenhtml .= ' border-top: 0.1mm solid #000000;';
  11276.                 }
  11277.                 $evenhtml .= 'text-align: left; ">' $Farray '</div>';
  11278.             }
  11279.         } elseif (is_array($Farray)) {
  11280.             $odd null;
  11281.             $even null;
  11282.             if ($side === 'O') {
  11283.                 $odd $Farray;
  11284.             } elseif ($side == 'E') {
  11285.                 $even $Farray;
  11286.             } else {
  11287.                 $odd Arrays::get($Farray'odd'null);
  11288.                 $even Arrays::get($Farray'even'null);
  11289.             }
  11290.             $oddhtml $this->_createHTMLheaderFooter($odd'F');
  11291.             $evenhtml $this->_createHTMLheaderFooter($even'F');
  11292.         }
  11293.         if ($side === 'E') {
  11294.             $this->SetHTMLFooter($evenhtml'E');
  11295.         } elseif ($side === 'O') {
  11296.             $this->SetHTMLFooter($oddhtml'O');
  11297.         } else {
  11298.             $this->SetHTMLFooter($oddhtml'O');
  11299.             $this->SetHTMLFooter($evenhtml'E');
  11300.         }
  11301.     }
  11302.     /* -- WATERMARK -- */
  11303.     function SetWatermarkText($txt ''$alpha = -1)
  11304.     {
  11305.         if ($txt instanceof \Mpdf\WatermarkText) {
  11306.             $this->watermarkTextObject $txt;
  11307.             $this->watermarkText $txt->getText();
  11308.             $this->watermarkTextAlpha $txt->getAlpha();
  11309.             $this->watermarkAngle $txt->getAngle();
  11310.             $this->watermark_font $txt->getFont() === null $txt->getFont() : $this->watermark_font;
  11311.             $this->watermark_size $txt->getSize();
  11312.             return;
  11313.         }
  11314.         if ($alpha >= 0) {
  11315.             $this->watermarkTextAlpha $alpha;
  11316.         }
  11317.         $this->watermarkText $txt;
  11318.     }
  11319.     function SetWatermarkImage($src$alpha = -1$size 'D'$pos 'F')
  11320.     {
  11321.         if ($src instanceof \Mpdf\WatermarkImage) {
  11322.             $this->watermarkImage $src->getPath();
  11323.             $this->watermark_size $src->getSize();
  11324.             $this->watermark_pos $src->getPosition();
  11325.             $this->watermarkImageAlpha $src->getAlpha();
  11326.             $this->watermarkImgBehind $src->isBehindContent();
  11327.             $this->watermarkImgAlphaBlend $src->getAlphaBlend();
  11328.             return;
  11329.         }
  11330.         if ($alpha >= 0) {
  11331.             $this->watermarkImageAlpha $alpha;
  11332.         }
  11333.         $this->watermarkImage $src;
  11334.         $this->watermark_size $size;
  11335.         $this->watermark_pos $pos;
  11336.     }
  11337.     /* -- END WATERMARK -- */
  11338.     // Page footer
  11339.     function Footer()
  11340.     {
  11341.         /* -- CSS-PAGE -- */
  11342.         // PAGED MEDIA - CROP / CROSS MARKS from @PAGE
  11343.         if ($this->show_marks == 'CROP' || $this->show_marks == 'CROPCROSS') {
  11344.             // Show TICK MARKS
  11345.             $this->SetLineWidth(0.1); // = 0.1 mm
  11346.             $this->SetDColor($this->colorConverter->convert(0$this->PDFAXwarnings));
  11347.             $l $this->cropMarkLength;
  11348.             $m $this->cropMarkMargin// Distance of crop mark from margin
  11349.             $b $this->nonPrintMargin// Non-printable border at edge of paper sheet
  11350.             $ax1 $b;
  11351.             $bx $this->page_box['outer_width_LR'] - $m;
  11352.             $ax max($ax1$bx $l);
  11353.             $cx1 $this->$b;
  11354.             $dx $this->$this->page_box['outer_width_LR'] + $m;
  11355.             $cx min($cx1$dx $l);
  11356.             $ay1 $b;
  11357.             $by $this->page_box['outer_width_TB'] - $m;
  11358.             $ay max($ay1$by $l);
  11359.             $cy1 $this->$b;
  11360.             $dy $this->$this->page_box['outer_width_TB'] + $m;
  11361.             $cy min($cy1$dy $l);
  11362.             $this->Line($ax$this->page_box['outer_width_TB'], $bx$this->page_box['outer_width_TB']);
  11363.             $this->Line($cx$this->page_box['outer_width_TB'], $dx$this->page_box['outer_width_TB']);
  11364.             $this->Line($ax$this->$this->page_box['outer_width_TB'], $bx$this->$this->page_box['outer_width_TB']);
  11365.             $this->Line($cx$this->$this->page_box['outer_width_TB'], $dx$this->$this->page_box['outer_width_TB']);
  11366.             $this->Line($this->page_box['outer_width_LR'], $ay$this->page_box['outer_width_LR'], $by);
  11367.             $this->Line($this->page_box['outer_width_LR'], $cy$this->page_box['outer_width_LR'], $dy);
  11368.             $this->Line($this->$this->page_box['outer_width_LR'], $ay$this->$this->page_box['outer_width_LR'], $by);
  11369.             $this->Line($this->$this->page_box['outer_width_LR'], $cy$this->$this->page_box['outer_width_LR'], $dy);
  11370.             if ($this->printers_info) {
  11371.                 $hd date('Y-m-d H:i') . '  Page ' $this->page ' of {nb}';
  11372.                 $this->SetTColor($this->colorConverter->convert(0$this->PDFAXwarnings));
  11373.                 $this->SetFont('arial'''7.5truetrue);
  11374.                 $this->$this->page_box['outer_width_LR'] + 1.5;
  11375.                 $this->1;
  11376.                 $this->Cell(0$this->FontSize$hd00'L'0''000'M');
  11377.                 $this->SetFont($this->default_font''$this->original_default_font_size);
  11378.             }
  11379.         }
  11380.         if ($this->show_marks == 'CROSS' || $this->show_marks == 'CROPCROSS') {
  11381.             $this->SetLineWidth(0.1); // = 0.1 mm
  11382.             $this->SetDColor($this->colorConverter->convert(0$this->PDFAXwarnings));
  11383.             $l 14 2// longer length of the cross line (half)
  11384.             $w 2// shorter width of the cross line (half)
  11385.             $r 1.2// radius of circle
  11386.             $m $this->crossMarkMargin// Distance of cross mark from margin
  11387.             $x1 $this->page_box['outer_width_LR'] - $m;
  11388.             $x2 $this->$this->page_box['outer_width_LR'] + $m;
  11389.             $y1 $this->page_box['outer_width_TB'] - $m;
  11390.             $y2 $this->$this->page_box['outer_width_TB'] + $m;
  11391.             // Left
  11392.             $this->Circle($x1$this->2$r'S');
  11393.             $this->Line($x1 $w$this->2$x1 $w$this->2);
  11394.             $this->Line($x1$this->$l$x1$this->$l);
  11395.             // Right
  11396.             $this->Circle($x2$this->2$r'S');
  11397.             $this->Line($x2 $w$this->2$x2 $w$this->2);
  11398.             $this->Line($x2$this->$l$x2$this->$l);
  11399.             // Top
  11400.             $this->Circle($this->2$y1$r'S');
  11401.             $this->Line($this->2$y1 $w$this->2$y1 $w);
  11402.             $this->Line($this->$l$y1$this->$l$y1);
  11403.             // Bottom
  11404.             $this->Circle($this->2$y2$r'S');
  11405.             $this->Line($this->2$y2 $w$this->2$y2 $w);
  11406.             $this->Line($this->$l$y2$this->$l$y2);
  11407.         }
  11408.         /* -- END CSS-PAGE -- */
  11409.         // mPDF 6
  11410.         // If @page set non-HTML headers/footers named, they were not read until later in the HTML code - so now set them
  11411.         if ($this->page == 1) {
  11412.             if ($this->firstPageBoxHeader) {
  11413.                 if (isset($this->pageHTMLheaders[$this->firstPageBoxHeader])) {
  11414.                     $this->HTMLHeader $this->pageHTMLheaders[$this->firstPageBoxHeader];
  11415.                 }
  11416.                 $this->Header();
  11417.             }
  11418.             if ($this->firstPageBoxFooter) {
  11419.                 if (isset($this->pageHTMLfooters[$this->firstPageBoxFooter])) {
  11420.                     $this->HTMLFooter $this->pageHTMLfooters[$this->firstPageBoxFooter];
  11421.                 }
  11422.             }
  11423.             $this->firstPageBoxHeader '';
  11424.             $this->firstPageBoxFooter '';
  11425.         }
  11426.         if (($this->mirrorMargins && ($this->page == 0) && $this->HTMLFooterE) || ($this->mirrorMargins && ($this->page == 1) && $this->HTMLFooter) || (!$this->mirrorMargins && $this->HTMLFooter)) {
  11427.             $this->writeHTMLFooters();
  11428.         }
  11429.         /* -- WATERMARK -- */
  11430.         if (($this->watermarkText) && ($this->showWatermarkText)) {
  11431.             $this->watermark($this->watermarkText$this->watermarkAngleis_int($this->watermark_size) ? $this->watermark_size 120$this->watermarkTextAlpha); // Watermark text
  11432.         }
  11433.         if (($this->watermarkImage) && ($this->showWatermarkImage)) {
  11434.             $this->watermarkImg($this->watermarkImage$this->watermarkImageAlpha); // Watermark image
  11435.         }
  11436.         /* -- END WATERMARK -- */
  11437.     }
  11438.     /* -- HTML-CSS -- */
  11439.     /**
  11440.      * Write HTML code to the document
  11441.      *
  11442.      * Also used internally to parse HTML into buffers
  11443.      *
  11444.      * @param string $html
  11445.      * @param int    $mode  Use HTMLParserMode constants. Controls what parts of the $html code is parsed.
  11446.      * @param bool   $init  Clears and sets buffers to Top level block etc.
  11447.      * @param bool   $close If false leaves buffers etc. in current state, so that it can continue a block etc.
  11448.      */
  11449.     function WriteHTML($html$mode HTMLParserMode::DEFAULT_MODE$init true$close true)
  11450.     {
  11451.         /* Check $html is an integer, float, string, boolean or class with __toString(), otherwise throw exception */
  11452.         if (is_scalar($html) === false) {
  11453.             if (!is_object($html) || ! method_exists($html'__toString')) {
  11454.                 throw new \Mpdf\MpdfException('WriteHTML() requires $html be an integer, float, string, boolean or an object with the __toString() magic method.');
  11455.             }
  11456.         }
  11457.         // Check the mode is valid
  11458.         if (in_array($modeHTMLParserMode::getAllModes(), true) === false) {
  11459.             throw new \Mpdf\MpdfException('WriteHTML() requires $mode to be one of the modes defined in HTMLParserMode');
  11460.         }
  11461.         /* Cast $html as a string */
  11462.         $html = (string) $html;
  11463.         // @log Parsing CSS & Headers
  11464.         if ($init) {
  11465.             $this->headerbuffer '';
  11466.             $this->textbuffer = [];
  11467.             $this->fixedPosBlockSave = [];
  11468.         }
  11469.         if ($mode === HTMLParserMode::HEADER_CSS) {
  11470.             $html '<style> ' $html ' </style>';
  11471.         } // stylesheet only
  11472.         if ($this->allow_charset_conversion) {
  11473.             if ($mode === HTMLParserMode::DEFAULT_MODE) {
  11474.                 $this->ReadCharset($html);
  11475.             }
  11476.             if ($this->charset_in && $mode !== HTMLParserMode::HTML_HEADER_BUFFER) {
  11477.                 $success iconv($this->charset_in'UTF-8//TRANSLIT'$html);
  11478.                 if ($success) {
  11479.                     $html $success;
  11480.                 }
  11481.             }
  11482.         }
  11483.         $html $this->purify_utf8($htmlfalse);
  11484.         if ($init) {
  11485.             $this->blklvl 0;
  11486.             $this->lastblocklevelchange 0;
  11487.             $this->blk = [];
  11488.             $this->initialiseBlock($this->blk[0]);
  11489.             $this->blk[0]['width'] = & $this->pgwidth;
  11490.             $this->blk[0]['inner_width'] = & $this->pgwidth;
  11491.             $this->blk[0]['blockContext'] = $this->blockContext;
  11492.         }
  11493.         $zproperties = [];
  11494.         if ($mode === HTMLParserMode::DEFAULT_MODE || $mode === HTMLParserMode::HEADER_CSS) {
  11495.             $this->ReadMetaTags($html);
  11496.             if (preg_match('/<base[^>]*href=["\']([^"\'>]*)["\']/i'$html$m)) {
  11497.                 $this->SetBasePath($m[1]);
  11498.             }
  11499.             $html $this->cssManager->ReadCSS($html);
  11500.             if ($this->autoLangToFont && !$this->usingCoreFont && preg_match('/<html [^>]*lang=[\'\"](.*?)[\'\"]/ism'$html$m)) {
  11501.                 $html_lang $m[1];
  11502.             }
  11503.             if (preg_match('/<html [^>]*dir=[\'\"]\s*rtl\s*[\'\"]/ism'$html)) {
  11504.                 $zproperties['DIRECTION'] = 'rtl';
  11505.             }
  11506.             // allow in-line CSS for body tag to be parsed // Get <body> tag inline CSS
  11507.             if (preg_match('/<body([^>]*)>(.*?)<\/body>/ism'$html$m) || preg_match('/<body([^>]*)>(.*)$/ism'$html$m)) {
  11508.                 $html $m[2];
  11509.                 // Changed to allow style="background: url('bg.jpg')"
  11510.                 if (preg_match('/style=[\"](.*?)[\"]/ism'$m[1], $mm) || preg_match('/style=[\'](.*?)[\']/ism'$m[1], $mm)) {
  11511.                     $zproperties $this->cssManager->readInlineCSS($mm[1]);
  11512.                 }
  11513.                 if (preg_match('/dir=[\'\"]\s*rtl\s*[\'\"]/ism'$m[1])) {
  11514.                     $zproperties['DIRECTION'] = 'rtl';
  11515.                 }
  11516.                 if (isset($html_lang) && $html_lang) {
  11517.                     $zproperties['LANG'] = $html_lang;
  11518.                 }
  11519.                 if ($this->autoLangToFont && !$this->onlyCoreFonts && preg_match('/lang=[\'\"](.*?)[\'\"]/ism'$m[1], $mm)) {
  11520.                     $zproperties['LANG'] = $mm[1];
  11521.                 }
  11522.             }
  11523.         }
  11524.         $properties $this->cssManager->MergeCSS('BLOCK''BODY''');
  11525.         if ($zproperties) {
  11526.             $properties $this->cssManager->array_merge_recursive_unique($properties$zproperties);
  11527.         }
  11528.         if (isset($properties['DIRECTION']) && $properties['DIRECTION']) {
  11529.             $this->cssManager->CSS['BODY']['DIRECTION'] = $properties['DIRECTION'];
  11530.         }
  11531.         if (!isset($this->cssManager->CSS['BODY']['DIRECTION'])) {
  11532.             $this->cssManager->CSS['BODY']['DIRECTION'] = $this->directionality;
  11533.         } else {
  11534.             $this->SetDirectionality($this->cssManager->CSS['BODY']['DIRECTION']);
  11535.         }
  11536.         $this->setCSS($properties'''BODY');
  11537.         $this->blk[0]['InlineProperties'] = $this->saveInlineProperties();
  11538.         if ($mode === HTMLParserMode::HEADER_CSS) {
  11539.             return '';
  11540.         }
  11541.         if (!isset($this->cssManager->CSS['BODY'])) {
  11542.             $this->cssManager->CSS['BODY'] = [];
  11543.         }
  11544.         /* -- BACKGROUNDS -- */
  11545.         if (isset($properties['BACKGROUND-GRADIENT'])) {
  11546.             $this->bodyBackgroundGradient $properties['BACKGROUND-GRADIENT'];
  11547.         }
  11548.         if (isset($properties['BACKGROUND-IMAGE']) && $properties['BACKGROUND-IMAGE']) {
  11549.             $ret $this->SetBackground($properties$this->pgwidth);
  11550.             if ($ret) {
  11551.                 $this->bodyBackgroundImage $ret;
  11552.             }
  11553.         }
  11554.         /* -- END BACKGROUNDS -- */
  11555.         /* -- CSS-PAGE -- */
  11556.         // If page-box is set
  11557.         if ($this->state == && ((isset($this->cssManager->CSS['@PAGE']) && $this->cssManager->CSS['@PAGE']) || (isset($this->cssManager->CSS['@PAGE>>PSEUDO>>FIRST']) && $this->cssManager->CSS['@PAGE>>PSEUDO>>FIRST']))) { // mPDF 5.7.3
  11558.             $this->page_box['current'] = '';
  11559.             $this->page_box['using'] = true;
  11560.             list($pborientation$pbmgl$pbmgr$pbmgt$pbmgb$pbmgh$pbmgf$hname$fname$bg$resetpagenum$pagenumstyle$suppress$marks$newformat) = $this->SetPagedMediaCSS(''false'O');
  11561.             $this->DefOrientation $this->CurOrientation $pborientation;
  11562.             $this->orig_lMargin $this->DeflMargin $pbmgl;
  11563.             $this->orig_rMargin $this->DefrMargin $pbmgr;
  11564.             $this->orig_tMargin $this->tMargin $pbmgt;
  11565.             $this->orig_bMargin $this->bMargin $pbmgb;
  11566.             $this->orig_hMargin $this->margin_header $pbmgh;
  11567.             $this->orig_fMargin $this->margin_footer $pbmgf;
  11568.             list($pborientation$pbmgl$pbmgr$pbmgt$pbmgb$pbmgh$pbmgf$hname$fname$bg$resetpagenum$pagenumstyle$suppress$marks$newformat) = $this->SetPagedMediaCSS(''true'O'); // first page
  11569.             $this->show_marks $marks;
  11570.             if ($hname) {
  11571.                 $this->firstPageBoxHeader $hname;
  11572.             }
  11573.             if ($fname) {
  11574.                 $this->firstPageBoxFooter $fname;
  11575.             }
  11576.         }
  11577.         /* -- END CSS-PAGE -- */
  11578.         $parseonly false;
  11579.         $this->bufferoutput false;
  11580.         if ($mode == HTMLParserMode::HTML_PARSE_NO_WRITE) {
  11581.             $parseonly true;
  11582.             // Close any open block tags
  11583.             $arr = [];
  11584.             $ai 0;
  11585.             for ($b $this->blklvl$b 0$b--) {
  11586.                 $this->tag->CloseTag($this->blk[$b]['tag'], $arr$ai);
  11587.             }
  11588.             // Output any text left in buffer
  11589.             if (count($this->textbuffer)) {
  11590.                 $this->printbuffer($this->textbuffer);
  11591.             }
  11592.             $this->textbuffer = [];
  11593.         } elseif ($mode === HTMLParserMode::HTML_HEADER_BUFFER) {
  11594.             // Close any open block tags
  11595.             $arr = [];
  11596.             $ai 0;
  11597.             for ($b $this->blklvl$b 0$b--) {
  11598.                 $this->tag->CloseTag($this->blk[$b]['tag'], $arr$ai);
  11599.             }
  11600.             // Output any text left in buffer
  11601.             if (count($this->textbuffer)) {
  11602.                 $this->printbuffer($this->textbuffer);
  11603.             }
  11604.             $this->bufferoutput true;
  11605.             $this->textbuffer = [];
  11606.             $this->headerbuffer '';
  11607.             $properties $this->cssManager->MergeCSS('BLOCK''BODY''');
  11608.             $this->setCSS($properties'''BODY');
  11609.         }
  11610.         mb_internal_encoding('UTF-8');
  11611.         $html $this->AdjustHTML($html$this->tabSpaces); // Try to make HTML look more like XHTML
  11612.         if ($this->autoScriptToLang) {
  11613.             $html $this->markScriptToLang($html);
  11614.         }
  11615.         preg_match_all('/<htmlpageheader([^>]*)>(.*?)<\/htmlpageheader>/si'$html$h);
  11616.         for ($i 0$i count($h[1]); $i++) {
  11617.             if (preg_match('/name=[\'|\"](.*?)[\'|\"]/'$h[1][$i], $n)) {
  11618.                 $this->pageHTMLheaders[$n[1]]['html'] = $h[2][$i];
  11619.                 $this->pageHTMLheaders[$n[1]]['h'] = $this->_getHtmlHeight($h[2][$i]);
  11620.             }
  11621.         }
  11622.         preg_match_all('/<htmlpagefooter([^>]*)>(.*?)<\/htmlpagefooter>/si'$html$f);
  11623.         for ($i 0$i count($f[1]); $i++) {
  11624.             if (preg_match('/name=[\'|\"](.*?)[\'|\"]/'$f[1][$i], $n)) {
  11625.                 $this->pageHTMLfooters[$n[1]]['html'] = $f[2][$i];
  11626.                 $this->pageHTMLfooters[$n[1]]['h'] = $this->_getHtmlHeight($f[2][$i]);
  11627.             }
  11628.         }
  11629.         $html preg_replace('/<htmlpageheader.*?<\/htmlpageheader>/si'''$html);
  11630.         $html preg_replace('/<htmlpagefooter.*?<\/htmlpagefooter>/si'''$html);
  11631.         if ($this->state == && ($mode === HTMLParserMode::DEFAULT_MODE || $mode === HTMLParserMode::HTML_BODY)) {
  11632.             $this->AddPage($this->CurOrientation);
  11633.         }
  11634.         if (isset($hname) && preg_match('/^html_(.*)$/i'$hname$n)) {
  11635.             $this->SetHTMLHeader($this->pageHTMLheaders[$n[1]], 'O'true);
  11636.         }
  11637.         if (isset($fname) && preg_match('/^html_(.*)$/i'$fname$n)) {
  11638.             $this->SetHTMLFooter($this->pageHTMLfooters[$n[1]], 'O');
  11639.         }
  11640.         $html str_replace('<?''< '$html); // Fix '<?XML' bug from HTML code generated by MS Word
  11641.         $this->checkSIP false;
  11642.         $this->checkSMP false;
  11643.         $this->checkCJK false;
  11644.         if ($this->onlyCoreFonts) {
  11645.             $html $this->SubstituteChars($html);
  11646.         } else {
  11647.             if (preg_match("/([" $this->pregRTLchars "])/u"$html)) {
  11648.                 $this->biDirectional true;
  11649.             } // *OTL*
  11650.             if (preg_match("/([\x{20000}-\x{2FFFF}])/u"$html)) {
  11651.                 $this->checkSIP true;
  11652.             }
  11653.             if (preg_match("/([\x{10000}-\x{1FFFF}])/u"$html)) {
  11654.                 $this->checkSMP true;
  11655.             }
  11656.             /* -- CJK-FONTS -- */
  11657.             if (preg_match("/([" $this->pregCJKchars "])/u"$html)) {
  11658.                 $this->checkCJK true;
  11659.             }
  11660.             /* -- END CJK-FONTS -- */
  11661.         }
  11662.         // Don't allow non-breaking spaces that are converted to substituted chars or will break anyway and mess up table width calc.
  11663.         $html str_replace('<tta>160</tta>'chr(32), $html);
  11664.         $html str_replace('</tta><tta>''|'$html);
  11665.         $html str_replace('</tts><tts>''|'$html);
  11666.         $html str_replace('</ttz><ttz>''|'$html);
  11667.         // Add new supported tags in the DisableTags function
  11668.         $html strip_tags($html$this->enabledtags); // remove all unsupported tags, but the ones inside the 'enabledtags' string
  11669.         // Explode the string in order to parse the HTML code
  11670.         $a preg_split('/<(.*?)>/ms'$html, -1PREG_SPLIT_DELIM_CAPTURE);
  11671.         // ? more accurate regexp that allows e.g. <a name="Silly <name>">
  11672.         // if changing - also change in fn.SubstituteChars()
  11673.         // $a = preg_split ('/<((?:[^<>]+(?:"[^"]*"|\'[^\']*\')?)+)>/ms', $html, -1, PREG_SPLIT_DELIM_CAPTURE);
  11674.         if ($this->mb_enc) {
  11675.             mb_internal_encoding($this->mb_enc);
  11676.         }
  11677.         $pbc 0;
  11678.         $this->subPos = -1;
  11679.         $cnt count($a);
  11680.         for ($i 0$i $cnt$i++) {
  11681.             $e $a[$i];
  11682.             if ($i == 0) {
  11683.                 // TEXT
  11684.                 if ($this->blk[$this->blklvl]['hide']) {
  11685.                     continue;
  11686.                 }
  11687.                 if ($this->inlineDisplayOff) {
  11688.                     continue;
  11689.                 }
  11690.                 if ($this->inMeter) {
  11691.                     continue;
  11692.                 }
  11693.                 if ($this->inFixedPosBlock) {
  11694.                     $this->fixedPosBlock .= $e;
  11695.                     continue;
  11696.                 } // *CSS-POSITION*
  11697.                 if (strlen($e) == 0) {
  11698.                     continue;
  11699.                 }
  11700.                 if ($this->ignorefollowingspaces && !$this->ispre) {
  11701.                     if (strlen(ltrim($e)) == 0) {
  11702.                         continue;
  11703.                     }
  11704.                     if ($this->FontFamily != 'csymbol' && $this->FontFamily != 'czapfdingbats' && substr($e01) == ' ') {
  11705.                         $this->ignorefollowingspaces false;
  11706.                         $e ltrim($e);
  11707.                     }
  11708.                 }
  11709.                 $this->OTLdata null;  // mPDF 5.7.1
  11710.                 $e UtfString::strcode2utf($e);
  11711.                 $e $this->lesser_entity_decode($e);
  11712.                 if ($this->usingCoreFont) {
  11713.                     // If core font is selected in document which is not onlyCoreFonts - substitute with non-core font
  11714.                     if ($this->useSubstitutions && !$this->onlyCoreFonts && $this->subPos $i && !$this->specialcontent) {
  11715.                         $cnt += $this->SubstituteCharsNonCore($a$i$e);
  11716.                     }
  11717.                     // CONVERT ENCODING
  11718.                     $e mb_convert_encoding($e$this->mb_enc'UTF-8');
  11719.                     if ($this->textvar TextVars::FT_UPPERCASE) {
  11720.                         $e mb_strtoupper($e$this->mb_enc);
  11721.                     } // mPDF 5.7.1
  11722.                     elseif ($this->textvar TextVars::FT_LOWERCASE) {
  11723.                         $e mb_strtolower($e$this->mb_enc);
  11724.                     } // mPDF 5.7.1
  11725.                     elseif ($this->textvar TextVars::FT_CAPITALIZE) {
  11726.                         $e mb_convert_case($eMB_CASE_TITLE"UTF-8");
  11727.                     } // mPDF 5.7.1
  11728.                 } else {
  11729.                     if ($this->checkSIP && $this->CurrentFont['sipext'] && $this->subPos $i && (!$this->specialcontent || !$this->useActiveForms)) {
  11730.                         $cnt += $this->SubstituteCharsSIP($a$i$e);
  11731.                     }
  11732.                     if ($this->useSubstitutions && !$this->onlyCoreFonts && $this->CurrentFont['type'] != 'Type0' && $this->subPos $i && (!$this->specialcontent || !$this->useActiveForms)) {
  11733.                         $cnt += $this->SubstituteCharsMB($a$i$e);
  11734.                     }
  11735.                     if ($this->textvar TextVars::FT_UPPERCASE) {
  11736.                         $e mb_strtoupper($e$this->mb_enc);
  11737.                     } elseif ($this->textvar TextVars::FT_LOWERCASE) {
  11738.                         $e mb_strtolower($e$this->mb_enc);
  11739.                     } elseif ($this->textvar TextVars::FT_CAPITALIZE) {
  11740.                         $e mb_convert_case($eMB_CASE_TITLE"UTF-8");
  11741.                     }
  11742.                     /* -- OTL -- */
  11743.                     // Use OTL OpenType Table Layout - GSUB & GPOS
  11744.                     if (isset($this->CurrentFont['useOTL']) && $this->CurrentFont['useOTL'] && (!$this->specialcontent || !$this->useActiveForms)) {
  11745.                         if (!$this->otl) {
  11746.                             $this->otl = new Otl($this$this->fontCache);
  11747.                         }
  11748.                         $e $this->otl->applyOTL($e$this->CurrentFont['useOTL']);
  11749.                         $this->OTLdata $this->otl->OTLdata;
  11750.                         $this->otl->removeChar($e$this->OTLdata"\xef\xbb\xbf"); // Remove ZWNBSP (also Byte order mark FEFF)
  11751.                     /* -- END OTL -- */
  11752.                     else {
  11753.                         // removes U+200E/U+200F LTR and RTL mark and U+200C/U+200D Zero-width Joiner and Non-joiner
  11754.                         $e preg_replace("/[\xe2\x80\x8c\xe2\x80\x8d\xe2\x80\x8e\xe2\x80\x8f]/u"''$e);
  11755.                         $e preg_replace("/[\xef\xbb\xbf]/u"''$e); // Remove ZWNBSP (also Byte order mark FEFF)
  11756.                     }
  11757.                 }
  11758.                 if (($this->tts) || ($this->ttz) || ($this->tta)) {
  11759.                     $es explode('|'$e);
  11760.                     $e '';
  11761.                     foreach ($es as $val) {
  11762.                         $e .= chr($val);
  11763.                     }
  11764.                 }
  11765.                 //  FORM ELEMENTS
  11766.                 if ($this->specialcontent) {
  11767.                     /* -- FORMS -- */
  11768.                     // SELECT tag (form element)
  11769.                     if ($this->specialcontent == "type=select") {
  11770.                         $e ltrim($e);
  11771.                         if (!empty($this->OTLdata)) {
  11772.                             $this->otl->trimOTLdata($this->OTLdatatruefalse);
  11773.                         } // *OTL*
  11774.                         $stringwidth $this->GetStringWidth($e);
  11775.                         if (!isset($this->selectoption['MAXWIDTH']) || $stringwidth $this->selectoption['MAXWIDTH']) {
  11776.                             $this->selectoption['MAXWIDTH'] = $stringwidth;
  11777.                         }
  11778.                         if (!isset($this->selectoption['SELECTED']) || $this->selectoption['SELECTED'] == '') {
  11779.                             $this->selectoption['SELECTED'] = $e;
  11780.                             if (!empty($this->OTLdata)) {
  11781.                                 $this->selectoption['SELECTED-OTLDATA'] = $this->OTLdata;
  11782.                             } // *OTL*
  11783.                         }
  11784.                         // Active Forms
  11785.                         if (isset($this->selectoption['ACTIVE']) && $this->selectoption['ACTIVE']) {
  11786.                             $this->selectoption['ITEMS'][] = ['exportValue' => $this->selectoption['currentVAL'], 'content' => $e'selected' => $this->selectoption['currentSEL']];
  11787.                         }
  11788.                         $this->OTLdata = [];
  11789.                     } // TEXTAREA
  11790.                     else {
  11791.                         $objattr unserialize($this->specialcontent);
  11792.                         $objattr['text'] = $e;
  11793.                         $objattr['OTLdata'] = $this->OTLdata;
  11794.                         $this->OTLdata = [];
  11795.                         $te Mpdf::OBJECT_IDENTIFIER "type=textarea,objattr=" serialize($objattr) . Mpdf::OBJECT_IDENTIFIER;
  11796.                         if ($this->tdbegin) {
  11797.                             $this->_saveCellTextBuffer($te$this->HREF);
  11798.                         } else {
  11799.                             $this->_saveTextBuffer($te$this->HREF);
  11800.                         }
  11801.                     }
  11802.                     /* -- END FORMS -- */
  11803.                 // TABLE
  11804.                 elseif ($this->tableLevel) {
  11805.                     /* -- TABLES -- */
  11806.                     if ($this->tdbegin) {
  11807.                         if (($this->ignorefollowingspaces) && !$this->ispre) {
  11808.                             $e ltrim($e);
  11809.                             if (!empty($this->OTLdata)) {
  11810.                                 $this->otl->trimOTLdata($this->OTLdatatruefalse);
  11811.                             } // *OTL*
  11812.                         }
  11813.                         if ($e || $e === '0') {
  11814.                             if ($this->blockjustfinished && $this->cell[$this->row][$this->col]['s'] > 0) {
  11815.                                 $this->_saveCellTextBuffer("\n");
  11816.                                 if (!isset($this->cell[$this->row][$this->col]['maxs'])) {
  11817.                                     $this->cell[$this->row][$this->col]['maxs'] = $this->cell[$this->row][$this->col]['s'];
  11818.                                 } elseif ($this->cell[$this->row][$this->col]['maxs'] < $this->cell[$this->row][$this->col]['s']) {
  11819.                                     $this->cell[$this->row][$this->col]['maxs'] = $this->cell[$this->row][$this->col]['s'];
  11820.                                 }
  11821.                                 $this->cell[$this->row][$this->col]['s'] = 0// reset
  11822.                             }
  11823.                             $this->blockjustfinished false;
  11824.                             if (!isset($this->cell[$this->row][$this->col]['R']) || !$this->cell[$this->row][$this->col]['R']) {
  11825.                                 if (isset($this->cell[$this->row][$this->col]['s'])) {
  11826.                                     $this->cell[$this->row][$this->col]['s'] += $this->GetStringWidth($efalse$this->OTLdata$this->textvar);
  11827.                                 } else {
  11828.                                     $this->cell[$this->row][$this->col]['s'] = $this->GetStringWidth($efalse$this->OTLdata$this->textvar);
  11829.                                 }
  11830.                                 if (!empty($this->spanborddet)) {
  11831.                                     $this->cell[$this->row][$this->col]['s'] += (isset($this->spanborddet['L']['w']) ? $this->spanborddet['L']['w'] : 0) + (isset($this->spanborddet['R']['w']) ? $this->spanborddet['R']['w'] : 0);
  11832.                                 }
  11833.                             }
  11834.                             $this->_saveCellTextBuffer($e$this->HREF);
  11835.                             if (substr($this->cell[$this->row][$this->col]['a'], 01) == 'D') {
  11836.                                 $dp $this->decimal_align[substr($this->cell[$this->row][$this->col]['a'], 02)];
  11837.                                 $s preg_split('/' preg_quote($dp'/') . '/'$e2);  // ? needs to be /u if not core
  11838.                                 $s0 $this->GetStringWidth($s[0], false);
  11839.                                 if (isset($s[1]) && $s[1]) {
  11840.                                     $s1 $this->GetStringWidth(($s[1] . $dp), false);
  11841.                                 } else {
  11842.                                     $s1 0;
  11843.                                 }
  11844.                                 if (!isset($this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['decimal_align'][$this->col]['maxs0'])) {
  11845.                                     if ($this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['decimal_align'] === false) {
  11846.                                         $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['decimal_align'] = [];
  11847.                                     }
  11848.                                     $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['decimal_align'][$this->col]['maxs0'] = $s0;
  11849.                                 } else {
  11850.                                     $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']);
  11851.                                 }
  11852.                                 if (!isset($this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['decimal_align'][$this->col]['maxs1'])) {
  11853.                                     $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['decimal_align'][$this->col]['maxs1'] = $s1;
  11854.                                 } else {
  11855.                                     $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']);
  11856.                                 }
  11857.                             }
  11858.                             $this->nestedtablejustfinished false;
  11859.                             $this->linebreakjustfinished false;
  11860.                         }
  11861.                     }
  11862.                     /* -- END TABLES -- */
  11863.                 // ALL ELSE
  11864.                 else {
  11865.                     if ($this->ignorefollowingspaces && !$this->ispre) {
  11866.                         $e ltrim($e);
  11867.                         if (!empty($this->OTLdata)) {
  11868.                             $this->otl->trimOTLdata($this->OTLdatatruefalse);
  11869.                         } // *OTL*
  11870.                     }
  11871.                     if ($e || $e === '0') {
  11872.                         $this->_saveTextBuffer($e$this->HREF);
  11873.                     }
  11874.                 }
  11875.                 if ($e || $e === '0') {
  11876.                     $this->ignorefollowingspaces false// mPDF 6
  11877.                 }
  11878.                 if (substr($e, -11) == ' ' && !$this->ispre && $this->FontFamily != 'csymbol' && $this->FontFamily != 'czapfdingbats') {
  11879.                     $this->ignorefollowingspaces true;
  11880.                 }
  11881.             } else { // TAG **
  11882.                 if (isset($e[0]) && $e[0] == '/') {
  11883.                     $endtag trim(strtoupper(substr($e1)));
  11884.                     /* -- CSS-POSITION -- */
  11885.                     // mPDF 6
  11886.                     if ($this->inFixedPosBlock) {
  11887.                         if (in_array($endtag$this->outerblocktags) || in_array($endtag$this->innerblocktags)) {
  11888.                             $this->fixedPosBlockDepth--;
  11889.                         }
  11890.                         if ($this->fixedPosBlockDepth == 0) {
  11891.                             $this->fixedPosBlockSave[] = [$this->fixedPosBlock$this->fixedPosBlockBBox$this->page];
  11892.                             $this->fixedPosBlock '';
  11893.                             $this->inFixedPosBlock false;
  11894.                             continue;
  11895.                         }
  11896.                         $this->fixedPosBlock .= '<' $e '>';
  11897.                         continue;
  11898.                     }
  11899.                     /* -- END CSS-POSITION -- */
  11900.                     // mPDF 6
  11901.                     // Correct for tags where HTML5 specifies optional end tags (see also OpenTag() )
  11902.                     if ($this->allow_html_optional_endtags && !$parseonly) {
  11903.                         if (isset($this->blk[$this->blklvl]['tag'])) {
  11904.                             $closed false;
  11905.                             // li end tag may be omitted if there is no more content in the parent element
  11906.                             if (!$closed && $this->blk[$this->blklvl]['tag'] == 'LI' && $endtag != 'LI' && (in_array($endtag$this->outerblocktags) || in_array($endtag$this->innerblocktags))) {
  11907.                                 $this->tag->CloseTag('LI'$a$i);
  11908.                                 $closed true;
  11909.                             }
  11910.                             // dd end tag may be omitted if there is no more content in the parent element
  11911.                             if (!$closed && $this->blk[$this->blklvl]['tag'] == 'DD' && $endtag != 'DD' && (in_array($endtag$this->outerblocktags) || in_array($endtag$this->innerblocktags))) {
  11912.                                 $this->tag->CloseTag('DD'$a$i);
  11913.                                 $closed true;
  11914.                             }
  11915.                             // p end tag may be omitted if there is no more content in the parent element and the parent element is not an A element [??????]
  11916.                             if (!$closed && $this->blk[$this->blklvl]['tag'] == 'P' && $endtag != 'P' && (in_array($endtag$this->outerblocktags) || in_array($endtag$this->innerblocktags))) {
  11917.                                 $this->tag->CloseTag('P'$a$i);
  11918.                                 $closed true;
  11919.                             }
  11920.                             // option end tag may be omitted if there is no more content in the parent element
  11921.                             if (!$closed && $this->blk[$this->blklvl]['tag'] == 'OPTION' && $endtag != 'OPTION' && (in_array($endtag$this->outerblocktags) || in_array($endtag$this->innerblocktags))) {
  11922.                                 $this->tag->CloseTag('OPTION'$a$i);
  11923.                                 $closed true;
  11924.                             }
  11925.                         }
  11926.                         /* -- TABLES -- */
  11927.                         // Check for Table tags where HTML specifies optional end tags,
  11928.                         if ($endtag == 'TABLE') {
  11929.                             if ($this->lastoptionaltag == 'THEAD' || $this->lastoptionaltag == 'TBODY' || $this->lastoptionaltag == 'TFOOT') {
  11930.                                 $this->tag->CloseTag($this->lastoptionaltag$a$i);
  11931.                             }
  11932.                             if ($this->lastoptionaltag == 'TR') {
  11933.                                 $this->tag->CloseTag('TR'$a$i);
  11934.                             }
  11935.                             if ($this->lastoptionaltag == 'TD' || $this->lastoptionaltag == 'TH') {
  11936.                                 $this->tag->CloseTag($this->lastoptionaltag$a$i);
  11937.                                 $this->tag->CloseTag('TR'$a$i);
  11938.                             }
  11939.                         }
  11940.                         if ($endtag == 'THEAD' || $endtag == 'TBODY' || $endtag == 'TFOOT') {
  11941.                             if ($this->lastoptionaltag == 'TR') {
  11942.                                 $this->tag->CloseTag('TR'$a$i);
  11943.                             }
  11944.                             if ($this->lastoptionaltag == 'TD' || $this->lastoptionaltag == 'TH') {
  11945.                                 $this->tag->CloseTag($this->lastoptionaltag$a$i);
  11946.                                 $this->tag->CloseTag('TR'$a$i);
  11947.                             }
  11948.                         }
  11949.                         if ($endtag == 'TR') {
  11950.                             if ($this->lastoptionaltag == 'TD' || $this->lastoptionaltag == 'TH') {
  11951.                                 $this->tag->CloseTag($this->lastoptionaltag$a$i);
  11952.                             }
  11953.                         }
  11954.                         /* -- END TABLES -- */
  11955.                     }
  11956.                     // mPDF 6
  11957.                     if ($this->blk[$this->blklvl]['hide']) {
  11958.                         if (in_array($endtag$this->outerblocktags) || in_array($endtag$this->innerblocktags)) {
  11959.                             unset($this->blk[$this->blklvl]);
  11960.                             $this->blklvl--;
  11961.                         }
  11962.                         continue;
  11963.                     }
  11964.                     // mPDF 6
  11965.                     $this->tag->CloseTag($endtag$a$i); // mPDF 6
  11966.                 } else { // OPENING TAG
  11967.                     if ($this->blk[$this->blklvl]['hide']) {
  11968.                         if (strpos($e' ')) {
  11969.                             $te strtoupper(substr($e0strpos($e' ')));
  11970.                         } else {
  11971.                             $te strtoupper($e);
  11972.                         }
  11973.                         // mPDF 6
  11974.                         if ($te == 'THEAD' || $te == 'TBODY' || $te == 'TFOOT' || $te == 'TR' || $te == 'TD' || $te == 'TH') {
  11975.                             $this->lastoptionaltag $te;
  11976.                         }
  11977.                         if (in_array($te$this->outerblocktags) || in_array($te$this->innerblocktags)) {
  11978.                             $this->blklvl++;
  11979.                             $this->blk[$this->blklvl]['hide'] = true;
  11980.                             $this->blk[$this->blklvl]['tag'] = $te// mPDF 6
  11981.                         }
  11982.                         continue;
  11983.                     }
  11984.                     /* -- CSS-POSITION -- */
  11985.                     if ($this->inFixedPosBlock) {
  11986.                         if (strpos($e' ')) {
  11987.                             $te strtoupper(substr($e0strpos($e' ')));
  11988.                         } else {
  11989.                             $te strtoupper($e);
  11990.                         }
  11991.                         $this->fixedPosBlock .= '<' $e '>';
  11992.                         if (in_array($te$this->outerblocktags) || in_array($te$this->innerblocktags)) {
  11993.                             $this->fixedPosBlockDepth++;
  11994.                         }
  11995.                         continue;
  11996.                     }
  11997.                     /* -- END CSS-POSITION -- */
  11998.                     $regexp '|=\'(.*?)\'|s'// eliminate single quotes, if any
  11999.                     $e preg_replace($regexp"=\"\$1\""$e);
  12000.                     // changes anykey=anyvalue to anykey="anyvalue" (only do this inside [some] tags)
  12001.                     if (substr($e010) != 'pageheader' && substr($e010) != 'pagefooter' && substr($e012) != 'tocpagebreak' && substr($e010) != 'indexentry' && substr($e08) != 'tocentry') { // mPDF 6  (ZZZ99H)
  12002.                         $regexp '| (\\w+?)=([^\\s>"]+)|si';
  12003.                         $e preg_replace($regexp" \$1=\"\$2\""$e);
  12004.                     }
  12005.                     $e preg_replace('/ (\\S+?)\s*=\s*"/i'" \\1=\""$e);
  12006.                     // Fix path values, if needed
  12007.                     $orig_srcpath '';
  12008.                     if ((stristr($e"href=") !== false) or ( stristr($e"src=") !== false)) {
  12009.                         $regexp '/ (href|src)\s*=\s*"(.*?)"/i';
  12010.                         preg_match($regexp$e$auxiliararray);
  12011.                         if (isset($auxiliararray[2])) {
  12012.                             $path $auxiliararray[2];
  12013.                         } else {
  12014.                             $path '';
  12015.                         }
  12016.                         if (trim($path) != '' && !(stristr($e"src=") !== false && substr($path04) == 'var:') && substr($path01) != '@') {
  12017.                             $path htmlspecialchars_decode($path); // mPDF 5.7.4 URLs
  12018.                             $orig_srcpath $path;
  12019.                             $this->GetFullPath($path);
  12020.                             $regexp '/ (href|src)="(.*?)"/i';
  12021.                             $e preg_replace($regexp' \\1="' $path '"'$e);
  12022.                         }
  12023.                     }//END of Fix path values
  12024.                     // Extract attributes
  12025.                     $contents = [];
  12026.                     $contents1 = [];
  12027.                     $contents2 = [];
  12028.                     // Changed to allow style="background: url('bg.jpg')"
  12029.                     // Changed to improve performance; maximum length of \S (attribute) = 16
  12030.                     // Increase allowed attribute name to 32 - cutting off "toc-even-header-name" etc.
  12031.                     preg_match_all('/\\S{1,32}=["][^"]*["]/'$e$contents1);
  12032.                     preg_match_all('/\\S{1,32}=[\'][^\']*[\']/i'$e$contents2);
  12033.                     $contents array_merge($contents1$contents2);
  12034.                     preg_match('/\\S+/'$e$a2);
  12035.                     $tag = (isset($a2[0]) ? strtoupper($a2[0]) : '');
  12036.                     $attr = [];
  12037.                     if ($orig_srcpath) {
  12038.                         $attr['ORIG_SRC'] = $orig_srcpath;
  12039.                     }
  12040.                     if (!empty($contents)) {
  12041.                         foreach ($contents[0] as $v) {
  12042.                             // Changed to allow style="background: url('bg.jpg')"
  12043.                             if (preg_match('/^([^=]*)=["]?([^"]*)["]?$/'$v$a3) || preg_match('/^([^=]*)=[\']?([^\']*)[\']?$/'$v$a3)) {
  12044.                                 if (strtoupper($a3[1]) == 'ID' || strtoupper($a3[1]) == 'CLASS') { // 4.2.013 Omits STYLE
  12045.                                     $attr[strtoupper($a3[1])] = trim(strtoupper($a3[2]));
  12046.                                 } // includes header-style-right etc. used for <pageheader>
  12047.                                 elseif (preg_match('/^(HEADER|FOOTER)-STYLE/i'$a3[1])) {
  12048.                                     $attr[strtoupper($a3[1])] = trim(strtoupper($a3[2]));
  12049.                                 } else {
  12050.                                     $attr[strtoupper($a3[1])] = trim($a3[2]);
  12051.                                 }
  12052.                             }
  12053.                         }
  12054.                     }
  12055.                     $this->tag->OpenTag($tag$attr$a$i); // mPDF 6
  12056.                     /* -- CSS-POSITION -- */
  12057.                     if ($this->inFixedPosBlock) {
  12058.                         $this->fixedPosBlockBBox = [$tag$attr$this->x$this->y];
  12059.                         $this->fixedPosBlock '';
  12060.                         $this->fixedPosBlockDepth 1;
  12061.                     }
  12062.                     /* -- END CSS-POSITION -- */
  12063.                     if (preg_match('/\/$/'$e)) {
  12064.                         $this->tag->CloseTag($tag$a$i);
  12065.                     }
  12066.                 }
  12067.             } // end TAG
  12068.         // end of    foreach($a as $i=>$e)
  12069.         if ($close) {
  12070.             // Close any open block tags
  12071.             for ($b $this->blklvl$b 0$b--) {
  12072.                 $this->tag->CloseTag($this->blk[$b]['tag'], $a$i);
  12073.             }
  12074.             // Output any text left in buffer
  12075.             if (count($this->textbuffer) && !$parseonly) {
  12076.                 $this->printbuffer($this->textbuffer);
  12077.             }
  12078.             if (!$parseonly) {
  12079.                 $this->textbuffer = [];
  12080.             }
  12081.             /* -- CSS-FLOAT -- */
  12082.             // If ended with a float, need to move to end page
  12083.             $currpos $this->page 1000 $this->y;
  12084.             if (isset($this->blk[$this->blklvl]['float_endpos']) && $this->blk[$this->blklvl]['float_endpos'] > $currpos) {
  12085.                 $old_page $this->page;
  12086.                 $new_page intval($this->blk[$this->blklvl]['float_endpos'] / 1000);
  12087.                 if ($old_page != $new_page) {
  12088.                     $s $this->PrintPageBackgrounds();
  12089.                     // Writes after the marker so not overwritten later by page background etc.
  12090.                     $this->pages[$this->page] = preg_replace('/(___BACKGROUND___PATTERNS' $this->uniqstr ')/''\\1' "\n" $s "\n"$this->pages[$this->page]);
  12091.                     $this->pageBackgrounds = [];
  12092.                     $this->page $new_page;
  12093.                     $this->ResetMargins();
  12094.                     $this->Reset();
  12095.                     $this->pageoutput[$this->page] = [];
  12096.                 }
  12097.                 $this->= (round($this->blk[$this->blklvl]['float_endpos'] * 1000) % 1000000) / 1000// mod changes operands to integers before processing
  12098.             }
  12099.             /* -- END CSS-FLOAT -- */
  12100.             /* -- CSS-IMAGE-FLOAT -- */
  12101.             $this->printfloatbuffer();
  12102.             /* -- END CSS-IMAGE-FLOAT -- */
  12103.             // Create Internal Links, if needed
  12104.             if (!empty($this->internallink)) {
  12105.                 foreach ($this->internallink as $k => $v) {
  12106.                     if (strpos($k"#") !== false) {
  12107.                         continue;
  12108.                     }
  12109.                     if (!is_array($v)) {
  12110.                         continue;
  12111.                     }
  12112.                     $ypos $v['Y'];
  12113.                     $pagenum $v['PAGE'];
  12114.                     $sharp "#";
  12115.                     while (array_key_exists($sharp $k$this->internallink)) {
  12116.                         $internallink $this->internallink[$sharp $k];
  12117.                         $this->SetLink($internallink$ypos$pagenum);
  12118.                         $sharp .= "#";
  12119.                     }
  12120.                 }
  12121.             }
  12122.             $this->bufferoutput false;
  12123.             /* -- CSS-POSITION -- */
  12124.             if (count($this->fixedPosBlockSave)) {
  12125.                 foreach ($this->fixedPosBlockSave as $fpbs) {
  12126.                     $old_page $this->page;
  12127.                     $this->page $fpbs[2];
  12128.                     $this->WriteFixedPosHTML($fpbs[0], 00100100'auto'$fpbs[1]);  // 0,0,10,10 are overwritten by bbox
  12129.                     $this->page $old_page;
  12130.                 }
  12131.                 $this->fixedPosBlockSave = [];
  12132.             }
  12133.             /* -- END CSS-POSITION -- */
  12134.         }
  12135.     }
  12136.     /* -- CSS-POSITION -- */
  12137.     function WriteFixedPosHTML($html$x$y$w$h$overflow 'visible'$bounding = [])
  12138.     {
  12139.         // $overflow can be 'hidden', 'visible' or 'auto' - 'auto' causes autofit to size
  12140.         // Annotations disabled - enabled in mPDF 5.0
  12141.         // Links do work
  12142.         // Will always go on current page (or start Page 1 if required)
  12143.         // Probably INCOMPATIBLE WITH keep with table, columns etc.
  12144.         // Called externally or interally via <div style="position: [fixed|absolute]">
  12145.         // When used internally, $x $y $w $h and $overflow are all overridden by $bounding
  12146.         $overflow strtolower($overflow);
  12147.         if ($this->state == 0) {
  12148.             $this->AddPage($this->CurOrientation);
  12149.         }
  12150.         $save_y $this->y;
  12151.         $save_x $this->x;
  12152.         $this->fullImageHeight $this->h;
  12153.         $save_cols false;
  12154.         /* -- COLUMNS -- */
  12155.         if ($this->ColActive) {
  12156.             $save_cols true;
  12157.             $save_nbcol $this->NbCol// other values of gap and vAlign will not change by setting Columns off
  12158.             $this->SetColumns(0);
  12159.         }
  12160.         /* -- END COLUMNS -- */
  12161.         $save_annots $this->title2annots// *ANNOTATIONS*
  12162.         $this->writingHTMLheader true// a FIX to stop pagebreaks etc.
  12163.         $this->writingHTMLfooter true;
  12164.         $this->InFooter true// suppresses autopagebreaks
  12165.         $save_bgs $this->pageBackgrounds;
  12166.         $checkinnerhtml preg_replace('/\s/'''$html);
  12167.         $rotate 0;
  12168.         if ($w $this->w) {
  12169.             $x 0;
  12170.             $w $this->w;
  12171.         }
  12172.         if ($h $this->h) {
  12173.             $y 0;
  12174.             $h $this->h;
  12175.         }
  12176.         if ($x $this->w) {
  12177.             $x $this->$w;
  12178.         }
  12179.         if ($y $this->h) {
  12180.             $y $this->$h;
  12181.         }
  12182.         if (!empty($bounding)) {
  12183.             // $cont_ containing block = full physical page (position: absolute) or page inside margins (position: fixed)
  12184.             // $bbox_ Bounding box is the <div> which is positioned absolutely/fixed
  12185.             // top/left/right/bottom/width/height/background*/border*/padding*/margin* are taken from bounding
  12186.             // font*[family/size/style/weight]/line-height/text*[align/decoration/transform/indent]/color are transferred to $inner
  12187.             // as an enclosing <div> (after having checked ID/CLASS)
  12188.             // $x, $y, $w, $h are inside of $bbox_ = containing box for $inner_
  12189.             // $inner_ InnerHTML is the contents of that block to be output
  12190.             $tag $bounding[0];
  12191.             $attr $bounding[1];
  12192.             $orig_x0 $bounding[2];
  12193.             $orig_y0 $bounding[3];
  12194.             // As in WriteHTML() initialising
  12195.             $this->blklvl 0;
  12196.             $this->lastblocklevelchange 0;
  12197.             $this->blk = [];
  12198.             $this->initialiseBlock($this->blk[0]);
  12199.             $this->blk[0]['width'] = & $this->pgwidth;
  12200.             $this->blk[0]['inner_width'] = & $this->pgwidth;
  12201.             $this->blk[0]['blockContext'] = $this->blockContext;
  12202.             $properties $this->cssManager->MergeCSS('BLOCK''BODY''');
  12203.             $this->setCSS($properties'''BODY');
  12204.             $this->blklvl 1;
  12205.             $this->initialiseBlock($this->blk[1]);
  12206.             $this->blk[1]['tag'] = $tag;
  12207.             $this->blk[1]['attr'] = $attr;
  12208.             $this->Reset();
  12209.             $p $this->cssManager->MergeCSS('BLOCK'$tag$attr);
  12210.             if (isset($p['ROTATE']) && ($p['ROTATE'] == 90 || $p['ROTATE'] == -90 || $p['ROTATE'] == 180)) {
  12211.                 $rotate $p['ROTATE'];
  12212.             } // mPDF 6
  12213.             if (isset($p['OVERFLOW'])) {
  12214.                 $overflow strtolower($p['OVERFLOW']);
  12215.             }
  12216.             if (strtolower($p['POSITION']) == 'fixed') {
  12217.                 $cont_w $this->pgwidth// $this->blk[0]['inner_width'];
  12218.                 $cont_h $this->$this->tMargin $this->bMargin;
  12219.                 $cont_x $this->lMargin;
  12220.                 $cont_y $this->tMargin;
  12221.             } else {
  12222.                 $cont_w $this->w// ABSOLUTE;
  12223.                 $cont_h $this->h;
  12224.                 $cont_x 0;
  12225.                 $cont_y 0;
  12226.             }
  12227.             // Pass on in-line properties to the innerhtml
  12228.             $css '';
  12229.             if (isset($p['TEXT-ALIGN'])) {
  12230.                 $css .= 'text-align: ' strtolower($p['TEXT-ALIGN']) . '; ';
  12231.             }
  12232.             if (isset($p['TEXT-TRANSFORM'])) {
  12233.                 $css .= 'text-transform: ' strtolower($p['TEXT-TRANSFORM']) . '; ';
  12234.             }
  12235.             if (isset($p['TEXT-INDENT'])) {
  12236.                 $css .= 'text-indent: ' strtolower($p['TEXT-INDENT']) . '; ';
  12237.             }
  12238.             if (isset($p['TEXT-DECORATION'])) {
  12239.                 $css .= 'text-decoration: ' strtolower($p['TEXT-DECORATION']) . '; ';
  12240.             }
  12241.             if (isset($p['FONT-FAMILY'])) {
  12242.                 $css .= 'font-family: ' strtolower($p['FONT-FAMILY']) . '; ';
  12243.             }
  12244.             if (isset($p['FONT-STYLE'])) {
  12245.                 $css .= 'font-style: ' strtolower($p['FONT-STYLE']) . '; ';
  12246.             }
  12247.             if (isset($p['FONT-WEIGHT'])) {
  12248.                 $css .= 'font-weight: ' strtolower($p['FONT-WEIGHT']) . '; ';
  12249.             }
  12250.             if (isset($p['FONT-SIZE'])) {
  12251.                 $css .= 'font-size: ' strtolower($p['FONT-SIZE']) . '; ';
  12252.             }
  12253.             if (isset($p['LINE-HEIGHT'])) {
  12254.                 $css .= 'line-height: ' strtolower($p['LINE-HEIGHT']) . '; ';
  12255.             }
  12256.             if (isset($p['TEXT-SHADOW'])) {
  12257.                 $css .= 'text-shadow: ' strtolower($p['TEXT-SHADOW']) . '; ';
  12258.             }
  12259.             if (isset($p['LETTER-SPACING'])) {
  12260.                 $css .= 'letter-spacing: ' strtolower($p['LETTER-SPACING']) . '; ';
  12261.             }
  12262.             // mPDF 6
  12263.             if (isset($p['FONT-VARIANT-POSITION'])) {
  12264.                 $css .= 'font-variant-position: ' strtolower($p['FONT-VARIANT-POSITION']) . '; ';
  12265.             }
  12266.             if (isset($p['FONT-VARIANT-CAPS'])) {
  12267.                 $css .= 'font-variant-caps: ' strtolower($p['FONT-VARIANT-CAPS']) . '; ';
  12268.             }
  12269.             if (isset($p['FONT-VARIANT-LIGATURES'])) {
  12270.                 $css .= 'font-variant-ligatures: ' strtolower($p['FONT-VARIANT-LIGATURES']) . '; ';
  12271.             }
  12272.             if (isset($p['FONT-VARIANT-NUMERIC'])) {
  12273.                 $css .= 'font-variant-numeric: ' strtolower($p['FONT-VARIANT-NUMERIC']) . '; ';
  12274.             }
  12275.             if (isset($p['FONT-VARIANT-ALTERNATES'])) {
  12276.                 $css .= 'font-variant-alternates: ' strtolower($p['FONT-VARIANT-ALTERNATES']) . '; ';
  12277.             }
  12278.             if (isset($p['FONT-FEATURE-SETTINGS'])) {
  12279.                 $css .= 'font-feature-settings: ' strtolower($p['FONT-FEATURE-SETTINGS']) . '; ';
  12280.             }
  12281.             if (isset($p['FONT-LANGUAGE-OVERRIDE'])) {
  12282.                 $css .= 'font-language-override: ' strtolower($p['FONT-LANGUAGE-OVERRIDE']) . '; ';
  12283.             }
  12284.             if (isset($p['FONT-KERNING'])) {
  12285.                 $css .= 'font-kerning: ' strtolower($p['FONT-KERNING']) . '; ';
  12286.             }
  12287.             if (isset($p['COLOR'])) {
  12288.                 $css .= 'color: ' strtolower($p['COLOR']) . '; ';
  12289.             }
  12290.             if (isset($p['Z-INDEX'])) {
  12291.                 $css .= 'z-index: ' $p['Z-INDEX'] . '; ';
  12292.             }
  12293.             if ($css) {
  12294.                 $html '<div style="' $css '">' $html '</div>';
  12295.             }
  12296.             // Copy over (only) the properties to set for border and background
  12297.             $pb = [];
  12298.             $pb['MARGIN-TOP'] = (isset($p['MARGIN-TOP']) ? $p['MARGIN-TOP'] : '');
  12299.             $pb['MARGIN-RIGHT'] = (isset($p['MARGIN-RIGHT']) ? $p['MARGIN-RIGHT'] : '');
  12300.             $pb['MARGIN-BOTTOM'] = (isset($p['MARGIN-BOTTOM']) ? $p['MARGIN-BOTTOM'] : '');
  12301.             $pb['MARGIN-LEFT'] = (isset($p['MARGIN-LEFT']) ? $p['MARGIN-LEFT'] : '');
  12302.             $pb['PADDING-TOP'] = (isset($p['PADDING-TOP']) ? $p['PADDING-TOP'] : '');
  12303.             $pb['PADDING-RIGHT'] = (isset($p['PADDING-RIGHT']) ? $p['PADDING-RIGHT'] : '');
  12304.             $pb['PADDING-BOTTOM'] = (isset($p['PADDING-BOTTOM']) ? $p['PADDING-BOTTOM'] : '');
  12305.             $pb['PADDING-LEFT'] = (isset($p['PADDING-LEFT']) ? $p['PADDING-LEFT'] : '');
  12306.             $pb['BORDER-TOP'] = (isset($p['BORDER-TOP']) ? $p['BORDER-TOP'] : '');
  12307.             $pb['BORDER-RIGHT'] = (isset($p['BORDER-RIGHT']) ? $p['BORDER-RIGHT'] : '');
  12308.             $pb['BORDER-BOTTOM'] = (isset($p['BORDER-BOTTOM']) ? $p['BORDER-BOTTOM'] : '');
  12309.             $pb['BORDER-LEFT'] = (isset($p['BORDER-LEFT']) ? $p['BORDER-LEFT'] : '');
  12310.             if (isset($p['BORDER-TOP-LEFT-RADIUS-H'])) {
  12311.                 $pb['BORDER-TOP-LEFT-RADIUS-H'] = $p['BORDER-TOP-LEFT-RADIUS-H'];
  12312.             }
  12313.             if (isset($p['BORDER-TOP-LEFT-RADIUS-V'])) {
  12314.                 $pb['BORDER-TOP-LEFT-RADIUS-V'] = $p['BORDER-TOP-LEFT-RADIUS-V'];
  12315.             }
  12316.             if (isset($p['BORDER-TOP-RIGHT-RADIUS-H'])) {
  12317.                 $pb['BORDER-TOP-RIGHT-RADIUS-H'] = $p['BORDER-TOP-RIGHT-RADIUS-H'];
  12318.             }
  12319.             if (isset($p['BORDER-TOP-RIGHT-RADIUS-V'])) {
  12320.                 $pb['BORDER-TOP-RIGHT-RADIUS-V'] = $p['BORDER-TOP-RIGHT-RADIUS-V'];
  12321.             }
  12322.             if (isset($p['BORDER-BOTTOM-LEFT-RADIUS-H'])) {
  12323.                 $pb['BORDER-BOTTOM-LEFT-RADIUS-H'] = $p['BORDER-BOTTOM-LEFT-RADIUS-H'];
  12324.             }
  12325.             if (isset($p['BORDER-BOTTOM-LEFT-RADIUS-V'])) {
  12326.                 $pb['BORDER-BOTTOM-LEFT-RADIUS-V'] = $p['BORDER-BOTTOM-LEFT-RADIUS-V'];
  12327.             }
  12328.             if (isset($p['BORDER-BOTTOM-RIGHT-RADIUS-H'])) {
  12329.                 $pb['BORDER-BOTTOM-RIGHT-RADIUS-H'] = $p['BORDER-BOTTOM-RIGHT-RADIUS-H'];
  12330.             }
  12331.             if (isset($p['BORDER-BOTTOM-RIGHT-RADIUS-V'])) {
  12332.                 $pb['BORDER-BOTTOM-RIGHT-RADIUS-V'] = $p['BORDER-BOTTOM-RIGHT-RADIUS-V'];
  12333.             }
  12334.             if (isset($p['BACKGROUND-COLOR'])) {
  12335.                 $pb['BACKGROUND-COLOR'] = $p['BACKGROUND-COLOR'];
  12336.             }
  12337.             if (isset($p['BOX-SHADOW'])) {
  12338.                 $pb['BOX-SHADOW'] = $p['BOX-SHADOW'];
  12339.             }
  12340.             /* -- BACKGROUNDS -- */
  12341.             if (isset($p['BACKGROUND-IMAGE'])) {
  12342.                 $pb['BACKGROUND-IMAGE'] = $p['BACKGROUND-IMAGE'];
  12343.             }
  12344.             if (isset($p['BACKGROUND-IMAGE-RESIZE'])) {
  12345.                 $pb['BACKGROUND-IMAGE-RESIZE'] = $p['BACKGROUND-IMAGE-RESIZE'];
  12346.             }
  12347.             if (isset($p['BACKGROUND-IMAGE-OPACITY'])) {
  12348.                 $pb['BACKGROUND-IMAGE-OPACITY'] = $p['BACKGROUND-IMAGE-OPACITY'];
  12349.             }
  12350.             if (isset($p['BACKGROUND-REPEAT'])) {
  12351.                 $pb['BACKGROUND-REPEAT'] = $p['BACKGROUND-REPEAT'];
  12352.             }
  12353.             if (isset($p['BACKGROUND-POSITION'])) {
  12354.                 $pb['BACKGROUND-POSITION'] = $p['BACKGROUND-POSITION'];
  12355.             }
  12356.             if (isset($p['BACKGROUND-GRADIENT'])) {
  12357.                 $pb['BACKGROUND-GRADIENT'] = $p['BACKGROUND-GRADIENT'];
  12358.             }
  12359.             if (isset($p['BACKGROUND-SIZE'])) {
  12360.                 $pb['BACKGROUND-SIZE'] = $p['BACKGROUND-SIZE'];
  12361.             }
  12362.             if (isset($p['BACKGROUND-ORIGIN'])) {
  12363.                 $pb['BACKGROUND-ORIGIN'] = $p['BACKGROUND-ORIGIN'];
  12364.             }
  12365.             if (isset($p['BACKGROUND-CLIP'])) {
  12366.                 $pb['BACKGROUND-CLIP'] = $p['BACKGROUND-CLIP'];
  12367.             }
  12368.             /* -- END BACKGROUNDS -- */
  12369.             $this->setCSS($pb'BLOCK'$tag);
  12370.             // ================================================================
  12371.             $bbox_br $this->blk[1]['border_right']['w'];
  12372.             $bbox_bl $this->blk[1]['border_left']['w'];
  12373.             $bbox_bt $this->blk[1]['border_top']['w'];
  12374.             $bbox_bb $this->blk[1]['border_bottom']['w'];
  12375.             $bbox_pr $this->blk[1]['padding_right'];
  12376.             $bbox_pl $this->blk[1]['padding_left'];
  12377.             $bbox_pt $this->blk[1]['padding_top'];
  12378.             $bbox_pb $this->blk[1]['padding_bottom'];
  12379.             $bbox_mr $this->blk[1]['margin_right'];
  12380.             if (isset($p['MARGIN-RIGHT']) && strtolower($p['MARGIN-RIGHT']) == 'auto') {
  12381.                 $bbox_mr 'auto';
  12382.             }
  12383.             $bbox_ml $this->blk[1]['margin_left'];
  12384.             if (isset($p['MARGIN-LEFT']) && strtolower($p['MARGIN-LEFT']) == 'auto') {
  12385.                 $bbox_ml 'auto';
  12386.             }
  12387.             $bbox_mt $this->blk[1]['margin_top'];
  12388.             if (isset($p['MARGIN-TOP']) && strtolower($p['MARGIN-TOP']) == 'auto') {
  12389.                 $bbox_mt 'auto';
  12390.             }
  12391.             $bbox_mb $this->blk[1]['margin_bottom'];
  12392.             if (isset($p['MARGIN-BOTTOM']) && strtolower($p['MARGIN-BOTTOM']) == 'auto') {
  12393.                 $bbox_mb 'auto';
  12394.             }
  12395.             if (isset($p['LEFT']) && strtolower($p['LEFT']) != 'auto') {
  12396.                 $bbox_left $this->sizeConverter->convert($p['LEFT'], $cont_w$this->FontSizefalse);
  12397.             } else {
  12398.                 $bbox_left 'auto';
  12399.             }
  12400.             if (isset($p['TOP']) && strtolower($p['TOP']) != 'auto') {
  12401.                 $bbox_top $this->sizeConverter->convert($p['TOP'], $cont_h$this->FontSizefalse);
  12402.             } else {
  12403.                 $bbox_top 'auto';
  12404.             }
  12405.             if (isset($p['RIGHT']) && strtolower($p['RIGHT']) != 'auto') {
  12406.                 $bbox_right $this->sizeConverter->convert($p['RIGHT'], $cont_w$this->FontSizefalse);
  12407.             } else {
  12408.                 $bbox_right 'auto';
  12409.             }
  12410.             if (isset($p['BOTTOM']) && strtolower($p['BOTTOM']) != 'auto') {
  12411.                 $bbox_bottom $this->sizeConverter->convert($p['BOTTOM'], $cont_h$this->FontSizefalse);
  12412.             } else {
  12413.                 $bbox_bottom 'auto';
  12414.             }
  12415.             if (isset($p['WIDTH']) && strtolower($p['WIDTH']) != 'auto') {
  12416.                 $inner_w $this->sizeConverter->convert($p['WIDTH'], $cont_w$this->FontSizefalse);
  12417.             } else {
  12418.                 $inner_w 'auto';
  12419.             }
  12420.             if (isset($p['HEIGHT']) && strtolower($p['HEIGHT']) != 'auto') {
  12421.                 $inner_h $this->sizeConverter->convert($p['HEIGHT'], $cont_h$this->FontSizefalse);
  12422.             } else {
  12423.                 $inner_h 'auto';
  12424.             }
  12425.             // If bottom or right pos are set and not left / top - save this to adjust rotated block later
  12426.             if ($rotate == 90 || $rotate == -90) { // mPDF 6
  12427.                 if ($bbox_left === 'auto' && $bbox_right !== 'auto') {
  12428.                     $rot_rpos $bbox_right;
  12429.                 } else {
  12430.                     $rot_rpos false;
  12431.                 }
  12432.                 if ($bbox_top === 'auto' && $bbox_bottom !== 'auto') {
  12433.                     $rot_bpos $bbox_bottom;
  12434.                 } else {
  12435.                     $rot_bpos false;
  12436.                 }
  12437.             }
  12438.             // ================================================================
  12439.             if ($checkinnerhtml == '' && $inner_h === 'auto') {
  12440.                 $inner_h 0.0001;
  12441.             }
  12442.             if ($checkinnerhtml == '' && $inner_w === 'auto') {
  12443.                 $inner_w $this->GetCharWidth('W'false);
  12444.             }
  12445.             // ================================================================
  12446.             // Algorithm from CSS2.1  See http://www.w3.org/TR/CSS21/visudet.html#abs-non-replaced-height
  12447.             // mPD 5.3.14
  12448.             // Special case (not CSS) if all not specified, centre vertically on page
  12449.             $bbox_top_orig '';
  12450.             if ($bbox_top === 'auto' && $inner_h === 'auto' && $bbox_bottom === 'auto' && $bbox_mt === 'auto' && $bbox_mb === 'auto') {
  12451.                 $bbox_top_orig $bbox_top;
  12452.                 if ($bbox_mt === 'auto') {
  12453.                     $bbox_mt 0;
  12454.                 }
  12455.                 if ($bbox_mb === 'auto') {
  12456.                     $bbox_mb 0;
  12457.                 }
  12458.                 $bbox_top $orig_y0 $bbox_mt $cont_y;
  12459.                 // solve for $bbox_bottom when content_h known - $inner_h=='auto' && $bbox_bottom=='auto'
  12460.             // mPD 5.3.14
  12461.             elseif ($bbox_top === 'auto' && $inner_h === 'auto' && $bbox_bottom === 'auto') {
  12462.                 $bbox_top_orig $bbox_top $orig_y0 $cont_y;
  12463.                 if ($bbox_mt === 'auto') {
  12464.                     $bbox_mt 0;
  12465.                 }
  12466.                 if ($bbox_mb === 'auto') {
  12467.                     $bbox_mb 0;
  12468.                 }
  12469.                 // solve for $bbox_bottom when content_h known - $inner_h=='auto' && $bbox_bottom=='auto'
  12470.             } elseif ($bbox_top !== 'auto' && $inner_h !== 'auto' && $bbox_bottom !== 'auto') {
  12471.                 if ($bbox_mt === 'auto' && $bbox_mb === 'auto') {
  12472.                     $x $cont_h $bbox_top $bbox_bt $bbox_pt $inner_h $bbox_pb $bbox_bb $bbox_bottom;
  12473.                     $bbox_mt $bbox_mb = ($x 2);
  12474.                 } elseif ($bbox_mt === 'auto') {
  12475.                     $bbox_mt $cont_h $bbox_top $bbox_bt $bbox_pt $inner_h $bbox_pb $bbox_bb $bbox_mb $bbox_bottom;
  12476.                 } elseif ($bbox_mb === 'auto') {
  12477.                     $bbox_mb $cont_h $bbox_top $bbox_mt $bbox_bt $bbox_pt $inner_h $bbox_pb $bbox_bb $bbox_bottom;
  12478.                 } else {
  12479.                     $bbox_bottom $cont_h $bbox_top $bbox_mt $bbox_bt $bbox_pt $inner_h $bbox_pb $bbox_bb $bbox_mt;
  12480.                 }
  12481.             } else {
  12482.                 if ($bbox_mt === 'auto') {
  12483.                     $bbox_mt 0;
  12484.                 }
  12485.                 if ($bbox_mb === 'auto') {
  12486.                     $bbox_mb 0;
  12487.                 }
  12488.                 if ($bbox_top === 'auto' && $inner_h === 'auto' && $bbox_bottom !== 'auto') {
  12489.                     // solve for $bbox_top when content_h known - $inner_h=='auto' && $bbox_top =='auto'
  12490.                 } elseif ($bbox_top === 'auto' && $bbox_bottom === 'auto' && $inner_h !== 'auto') {
  12491.                     $bbox_top $orig_y0 $bbox_mt $cont_y;
  12492.                     $bbox_bottom $cont_h $bbox_top $bbox_mt $bbox_bt $bbox_pt $inner_h $bbox_pb $bbox_bb $bbox_mt;
  12493.                 } elseif ($inner_h === 'auto' && $bbox_bottom === 'auto' && $bbox_top !== 'auto') {
  12494.                     // solve for $bbox_bottom when content_h known - $inner_h=='auto' && $bbox_bottom=='auto'
  12495.                 } elseif ($bbox_top === 'auto' && $inner_h !== 'auto' && $bbox_bottom !== 'auto') {
  12496.                     $bbox_top $cont_h $bbox_mt $bbox_bt $bbox_pt $inner_h $bbox_pb $bbox_bb $bbox_mt $bbox_bottom;
  12497.                 } elseif ($inner_h === 'auto' && $bbox_top !== 'auto' && $bbox_bottom !== 'auto') {
  12498.                     $inner_h $cont_h $bbox_top $bbox_mt $bbox_bt $bbox_pt $bbox_pb $bbox_bb $bbox_mt $bbox_bottom;
  12499.                 } elseif ($bbox_bottom === 'auto' && $bbox_top !== 'auto' && $inner_h !== 'auto') {
  12500.                     $bbox_bottom $cont_h $bbox_top $bbox_mt $bbox_bt $bbox_pt $inner_h $bbox_pb $bbox_bb $bbox_mt;
  12501.                 }
  12502.             }
  12503.             // THEN DO SAME FOR WIDTH
  12504.             // http://www.w3.org/TR/CSS21/visudet.html#abs-non-replaced-width
  12505.             if ($bbox_left === 'auto' && $inner_w === 'auto' && $bbox_right === 'auto') {
  12506.                 if ($bbox_ml === 'auto') {
  12507.                     $bbox_ml 0;
  12508.                 }
  12509.                 if ($bbox_mr === 'auto') {
  12510.                     $bbox_mr 0;
  12511.                 }
  12512.                 // IF containing element RTL, should set $bbox_right
  12513.                 $bbox_left $orig_x0 $bbox_ml $cont_x;
  12514.                 // solve for $bbox_right when content_w known - $inner_w=='auto' && $bbox_right=='auto'
  12515.             } elseif ($bbox_left !== 'auto' && $inner_w !== 'auto' && $bbox_right !== 'auto') {
  12516.                 if ($bbox_ml === 'auto' && $bbox_mr === 'auto') {
  12517.                     $x $cont_w $bbox_left $bbox_bl $bbox_pl $inner_w $bbox_pr $bbox_br $bbox_right;
  12518.                     $bbox_ml $bbox_mr = ($x 2);
  12519.                 } elseif ($bbox_ml === 'auto') {
  12520.                     $bbox_ml $cont_w $bbox_left $bbox_bl $bbox_pl $inner_w $bbox_pr $bbox_br $bbox_mr $bbox_right;
  12521.                 } elseif ($bbox_mr === 'auto') {
  12522.                     $bbox_mr $cont_w $bbox_left $bbox_ml $bbox_bl $bbox_pl $inner_w $bbox_pr $bbox_br $bbox_right;
  12523.                 } else {
  12524.                     $bbox_right $cont_w $bbox_left $bbox_ml $bbox_bl $bbox_pl $inner_w $bbox_pr $bbox_br $bbox_ml;
  12525.                 }
  12526.             } else {
  12527.                 if ($bbox_ml === 'auto') {
  12528.                     $bbox_ml 0;
  12529.                 }
  12530.                 if ($bbox_mr === 'auto') {
  12531.                     $bbox_mr 0;
  12532.                 }
  12533.                 if ($bbox_left === 'auto' && $inner_w === 'auto' && $bbox_right !== 'auto') {
  12534.                     // solve for $bbox_left when content_w known - $inner_w=='auto' && $bbox_left =='auto'
  12535.                 } elseif ($bbox_left === 'auto' && $bbox_right === 'auto' && $inner_w !== 'auto') {
  12536.                     // IF containing element RTL, should set $bbox_right
  12537.                     $bbox_left $orig_x0 $bbox_ml $cont_x;
  12538.                     $bbox_right $cont_w $bbox_left $bbox_ml $bbox_bl $bbox_pl $inner_w $bbox_pr $bbox_br $bbox_ml;
  12539.                 } elseif ($inner_w === 'auto' && $bbox_right === 'auto' && $bbox_left !== 'auto') {
  12540.                     // solve for $bbox_right when content_w known - $inner_w=='auto' && $bbox_right=='auto'
  12541.                 } elseif ($bbox_left === 'auto' && $inner_w !== 'auto' && $bbox_right !== 'auto') {
  12542.                     $bbox_left $cont_w $bbox_ml $bbox_bl $bbox_pl $inner_w $bbox_pr $bbox_br $bbox_ml $bbox_right;
  12543.                 } elseif ($inner_w === 'auto' && $bbox_left !== 'auto' && $bbox_right !== 'auto') {
  12544.                     $inner_w $cont_w $bbox_left $bbox_ml $bbox_bl $bbox_pl $bbox_pr $bbox_br $bbox_ml $bbox_right;
  12545.                 } elseif ($bbox_right === 'auto' && $bbox_left !== 'auto' && $inner_w !== 'auto') {
  12546.                     $bbox_right $cont_w $bbox_left $bbox_ml $bbox_bl $bbox_pl $inner_w $bbox_pr $bbox_br $bbox_ml;
  12547.                 }
  12548.             }
  12549.             // ================================================================
  12550.             // ================================================================
  12551.             /* -- BACKGROUNDS -- */
  12552.             if (isset($pb['BACKGROUND-IMAGE']) && $pb['BACKGROUND-IMAGE']) {
  12553.                 $ret $this->SetBackground($pb$this->blk[1]['inner_width']);
  12554.                 if ($ret) {
  12555.                     $this->blk[1]['background-image'] = $ret;
  12556.                 }
  12557.             }
  12558.             /* -- END BACKGROUNDS -- */
  12559.             $bbox_top_auto $bbox_top === 'auto';
  12560.             $bbox_left_auto $bbox_left === 'auto';
  12561.             $bbox_right_auto $bbox_right === 'auto';
  12562.             $bbox_bottom_auto $bbox_bottom === 'auto';
  12563.             $bbox_top is_numeric($bbox_top) ? $bbox_top 0;
  12564.             $bbox_left is_numeric($bbox_left) ? $bbox_left 0;
  12565.             $bbox_right is_numeric($bbox_right) ? $bbox_right 0;
  12566.             $bbox_bottom is_numeric($bbox_bottom) ? $bbox_bottom 0;
  12567.             $y $cont_y $bbox_top $bbox_mt $bbox_bt $bbox_pt;
  12568.             $h $cont_h $bbox_top $bbox_mt $bbox_bt $bbox_pt $bbox_pb $bbox_bb $bbox_mb $bbox_bottom;
  12569.             $x $cont_x $bbox_left $bbox_ml $bbox_bl $bbox_pl;
  12570.             $w $cont_w $bbox_left $bbox_ml $bbox_bl $bbox_pl $bbox_pr $bbox_br $bbox_mr $bbox_right;
  12571.             // Set (temporary) values for x y w h to do first paint, if values are auto
  12572.             if ($inner_h === 'auto' && $bbox_top_auto) {
  12573.                 $y $cont_y $bbox_mt $bbox_bt $bbox_pt;
  12574.                 $h $cont_h - ($bbox_bottom $bbox_mt $bbox_mb $bbox_bt $bbox_bb $bbox_pt $bbox_pb);
  12575.             } elseif ($inner_h === 'auto' && $bbox_bottom_auto) {
  12576.                 $y $cont_y $bbox_top $bbox_mt $bbox_bt $bbox_pt;
  12577.                 $h $cont_h - ($bbox_top $bbox_mt $bbox_mb $bbox_bt $bbox_bb $bbox_pt $bbox_pb);
  12578.             }
  12579.             if ($inner_w === 'auto' && $bbox_left_auto) {
  12580.                 $x $cont_x $bbox_ml $bbox_bl $bbox_pl;
  12581.                 $w $cont_w - ($bbox_right $bbox_ml $bbox_mr $bbox_bl $bbox_br $bbox_pl $bbox_pr);
  12582.             } elseif ($inner_w === 'auto' && $bbox_right_auto) {
  12583.                 $x $cont_x $bbox_left $bbox_ml $bbox_bl $bbox_pl;
  12584.                 $w $cont_w - ($bbox_left $bbox_ml $bbox_mr $bbox_bl $bbox_br $bbox_pl $bbox_pr);
  12585.             }
  12586.             $bbox_y $cont_y $bbox_top $bbox_mt;
  12587.             $bbox_x $cont_x $bbox_left $bbox_ml;
  12588.             $saved_block1 $this->blk[1];
  12589.             unset($p);
  12590.             unset($pb);
  12591.             // ================================================================
  12592.             if ($inner_w === 'auto') { // do a first write
  12593.                 $this->lMargin $x;
  12594.                 $this->rMargin $this->$w $x;
  12595.                 // SET POSITION & FONT VALUES
  12596.                 $this->pgwidth $this->$this->lMargin $this->rMargin;
  12597.                 $this->pageoutput[$this->page] = [];
  12598.                 $this->$x;
  12599.                 $this->$y;
  12600.                 $this->HTMLheaderPageLinks = [];
  12601.                 $this->HTMLheaderPageAnnots = [];
  12602.                 $this->HTMLheaderPageForms = [];
  12603.                 $this->pageBackgrounds = [];
  12604.                 $this->maxPosR 0;
  12605.                 $this->maxPosL $this->w// For RTL
  12606.                 $this->WriteHTML($htmlHTMLParserMode::HTML_HEADER_BUFFER);
  12607.                 $inner_w $this->maxPosR $this->lMargin;
  12608.                 if ($bbox_right_auto) {
  12609.                     $bbox_right $cont_w $bbox_left $bbox_ml $bbox_bl $bbox_pl $inner_w $bbox_pr $bbox_br $bbox_ml;
  12610.                 } elseif ($bbox_left_auto) {
  12611.                     $bbox_left $cont_w $bbox_ml $bbox_bl $bbox_pl $inner_w $bbox_pr $bbox_br $bbox_ml $bbox_right;
  12612.                     $bbox_x $cont_x $bbox_left $bbox_ml;
  12613.                     $inner_x $bbox_x $bbox_bl $bbox_pl;
  12614.                     $x $inner_x;
  12615.                 }
  12616.                 $w $inner_w;
  12617.                 $bbox_y $cont_y $bbox_top $bbox_mt;
  12618.                 $bbox_x $cont_x $bbox_left $bbox_ml;
  12619.             }
  12620.             if ($inner_h === 'auto') { // do a first write
  12621.                 $this->lMargin $x;
  12622.                 $this->rMargin $this->$w $x;
  12623.                 // SET POSITION & FONT VALUES
  12624.                 $this->pgwidth $this->$this->lMargin $this->rMargin;
  12625.                 $this->pageoutput[$this->page] = [];
  12626.                 $this->$x;
  12627.                 $this->$y;
  12628.                 $this->HTMLheaderPageLinks = [];
  12629.                 $this->HTMLheaderPageAnnots = [];
  12630.                 $this->HTMLheaderPageForms = [];
  12631.                 $this->pageBackgrounds = [];
  12632.                 $this->WriteHTML($htmlHTMLParserMode::HTML_HEADER_BUFFER);
  12633.                 $inner_h $this->$y;
  12634.                 if ($overflow != 'hidden' && $overflow != 'visible') { // constrained
  12635.                     if (($this->$bbox_pb $bbox_bb) > ($cont_y $cont_h)) {
  12636.                         $adj = ($this->$bbox_pb $bbox_bb) - ($cont_y $cont_h);
  12637.                         $inner_h -= $adj;
  12638.                     }
  12639.                 }
  12640.                 if ($bbox_bottom_auto && $bbox_top_orig === 'auto') {
  12641.                     $bbox_bottom $bbox_top = ($cont_h $bbox_mt $bbox_bt $bbox_pt $inner_h $bbox_pb $bbox_bb $bbox_mb) / 2;
  12642.                     if ($overflow != 'hidden' && $overflow != 'visible') { // constrained
  12643.                         if ($bbox_top 0) {
  12644.                             $bbox_top 0;
  12645.                             $inner_h $cont_h $bbox_top $bbox_mt $bbox_bt $bbox_pt $bbox_pb $bbox_bb $bbox_mb $bbox_bottom;
  12646.                         }
  12647.                     }
  12648.                     $bbox_y $cont_y $bbox_top $bbox_mt;
  12649.                     $inner_y $bbox_y $bbox_bt $bbox_pt;
  12650.                     $y $inner_y;
  12651.                 } elseif ($bbox_bottom_auto) {
  12652.                     $bbox_bottom $cont_h $bbox_top $bbox_mt $bbox_bt $bbox_pt $inner_h $bbox_pb $bbox_bb $bbox_mb;
  12653.                 } elseif ($bbox_top_auto) {
  12654.                     $bbox_top $cont_h $bbox_mt $bbox_bt $bbox_pt $inner_h $bbox_pb $bbox_bb $bbox_mb $bbox_bottom;
  12655.                     if ($overflow != 'hidden' && $overflow != 'visible') { // constrained
  12656.                         if ($bbox_top 0) {
  12657.                             $bbox_top 0;
  12658.                             $inner_h $cont_h $bbox_top $bbox_mt $bbox_bt $bbox_pt $bbox_pb $bbox_bb $bbox_mb $bbox_bottom;
  12659.                         }
  12660.                     }
  12661.                     $bbox_y $cont_y $bbox_top $bbox_mt;
  12662.                     $inner_y $bbox_y $bbox_bt $bbox_pt;
  12663.                     $y $inner_y;
  12664.                 }
  12665.                 $h $inner_h;
  12666.                 $bbox_y $cont_y $bbox_top $bbox_mt;
  12667.                 $bbox_x $cont_x $bbox_left $bbox_ml;
  12668.             }
  12669.             $inner_w $w;
  12670.             $inner_h $h;
  12671.         }
  12672.         $this->lMargin $x;
  12673.         $this->rMargin $this->$w $x;
  12674.         // SET POSITION & FONT VALUES
  12675.         $this->pgwidth $this->$this->lMargin $this->rMargin;
  12676.         $this->pageoutput[$this->page] = [];
  12677.         $this->$x;
  12678.         $this->$y;
  12679.         $this->HTMLheaderPageLinks = [];
  12680.         $this->HTMLheaderPageAnnots = [];
  12681.         $this->HTMLheaderPageForms = [];
  12682.         $this->pageBackgrounds = [];
  12683.         $this->WriteHTML($htmlHTMLParserMode::HTML_HEADER_BUFFER);
  12684.         $actual_h $this->$y;
  12685.         $use_w $w;
  12686.         $use_h $h;
  12687.         $ratio $actual_h $use_w;
  12688.         if ($overflow != 'hidden' && $overflow != 'visible') {
  12689.             $target $h $w;
  12690.             if ($target 0) {
  12691.                 if (($ratio $target) > 1) {
  12692.                     $nl ceil($actual_h $this->lineheight);
  12693.                     $l $use_w $nl;
  12694.                     $est_w sqrt(($l $this->lineheight) / $target) * 0.8;
  12695.                     $use_w += ($est_w $use_w) - ($w 100);
  12696.                 }
  12697.                 $bpcstart = ($ratio $target);
  12698.                 $bpcctr 1;
  12699.                 while (($ratio $target) > 1) {
  12700.                     // @log 'Auto-sizing fixed-position block $bpcctr++
  12701.                     $this->$x;
  12702.                     $this->$y;
  12703.                     if (($ratio $target) > 1.5 || ($ratio $target) < 0.6) {
  12704.                         $use_w += ($w $this->incrementFPR1);
  12705.                     } elseif (($ratio $target) > 1.2 || ($ratio $target) < 0.85) {
  12706.                         $use_w += ($w $this->incrementFPR2);
  12707.                     } elseif (($ratio $target) > 1.1 || ($ratio $target) < 0.91) {
  12708.                         $use_w += ($w $this->incrementFPR3);
  12709.                     } else {
  12710.                         $use_w += ($w $this->incrementFPR4);
  12711.                     }
  12712.                     $use_h $use_w $target;
  12713.                     $this->rMargin $this->$use_w $x;
  12714.                     $this->pgwidth $this->$this->lMargin $this->rMargin;
  12715.                     $this->HTMLheaderPageLinks = [];
  12716.                     $this->HTMLheaderPageAnnots = [];
  12717.                     $this->HTMLheaderPageForms = [];
  12718.                     $this->pageBackgrounds = [];
  12719.                     $this->WriteHTML($htmlHTMLParserMode::HTML_HEADER_BUFFER);
  12720.                     $actual_h $this->$y;
  12721.                     $ratio $actual_h $use_w;
  12722.                 }
  12723.             }
  12724.         }
  12725.         $shrink_f $w $use_w;
  12726.         // ================================================================
  12727.         $this->pages[$this->page] .= '___BEFORE_BORDERS___';
  12728.         $block_s $this->PrintPageBackgrounds(); // Save to print later inside clipping path
  12729.         $this->pageBackgrounds = [];
  12730.         // ================================================================
  12731.         if ($rotate == 90 || $rotate == -90) { // mPDF 6
  12732.             $prerotw $bbox_bl $bbox_pl $inner_w $bbox_pr $bbox_br;
  12733.             $preroth $bbox_bt $bbox_pt $inner_h $bbox_pb $bbox_bb;
  12734.             $rot_start " q\n";
  12735.             if ($rotate == 90) {
  12736.                 if ($rot_rpos !== false) {
  12737.                     $adjw $prerotw;
  12738.                 } // width before rotation
  12739.                 else {
  12740.                     $adjw $preroth;
  12741.                 } // height before rotation
  12742.                 if ($rot_bpos !== false) {
  12743.                     $adjh = -$prerotw $preroth;
  12744.                 } else {
  12745.                     $adjh 0;
  12746.                 }
  12747.             } else {
  12748.                 if ($rot_rpos !== false) {
  12749.                     $adjw $prerotw $preroth;
  12750.                 } else {
  12751.                     $adjw 0;
  12752.                 }
  12753.                 if ($rot_bpos !== false) {
  12754.                     $adjh $preroth;
  12755.                 } // height before rotation
  12756.                 else {
  12757.                     $adjh $prerotw;
  12758.                 } // width before rotation
  12759.             }
  12760.             $rot_start .= $this->transformTranslate($adjw$adjhtrue) . "\n";
  12761.             $rot_start .= $this->transformRotate($rotate$bbox_x$bbox_ytrue) . "\n";
  12762.             $rot_end " Q\n";
  12763.         } elseif ($rotate == 180) { // mPDF 6
  12764.             $rot_start " q\n";
  12765.             $rot_start .= $this->transformTranslate($bbox_bl $bbox_pl $inner_w $bbox_pr $bbox_br$bbox_bt $bbox_pt $inner_h $bbox_pb $bbox_bbtrue) . "\n";
  12766.             $rot_start .= $this->transformRotate(180$bbox_x$bbox_ytrue) . "\n";
  12767.             $rot_end " Q\n";
  12768.         } else {
  12769.             $rot_start '';
  12770.             $rot_end '';
  12771.         }
  12772.         // ================================================================
  12773.         if (!empty($bounding)) {
  12774.             // WHEN HEIGHT // BOTTOM EDGE IS KNOWN and $this->y is set to the bottom
  12775.             // Re-instate saved $this->blk[1]
  12776.             $this->blk[1] = $saved_block1;
  12777.             // These are only needed when painting border/background
  12778.             $this->blk[1]['width'] = $bbox_w $cont_w $bbox_left $bbox_ml $bbox_mr $bbox_right;
  12779.             $this->blk[1]['x0'] = $bbox_x;
  12780.             $this->blk[1]['y0'] = $bbox_y;
  12781.             $this->blk[1]['startpage'] = $this->page;
  12782.             $this->blk[1]['y1'] = $bbox_y $bbox_bt $bbox_pt $inner_h $bbox_pb $bbox_bb;
  12783.             $this->writer->write($rot_start);
  12784.             $this->PaintDivBB(''01); // Prints borders and sets backgrounds in $this->pageBackgrounds
  12785.             $this->writer->write($rot_end);
  12786.         }
  12787.         $s $this->PrintPageBackgrounds();
  12788.         $s $rot_start $s $rot_end;
  12789.         $this->pages[$this->page] = preg_replace('/___BEFORE_BORDERS___/'"\n" $s "\n"$this->pages[$this->page]);
  12790.         $this->pageBackgrounds = [];
  12791.         $this->writer->write($rot_start);
  12792.         // Clipping Output
  12793.         if ($overflow == 'hidden') {
  12794.             // Bounding rectangle to clip
  12795.             $clip_y1 $this->y;
  12796.             if (!empty($bounding) && ($this->$bbox_pb $bbox_bb) > ($bbox_y $bbox_bt $bbox_pt $inner_h $bbox_pb $bbox_bb )) {
  12797.                 $clip_y1 = ($bbox_y $bbox_bt $bbox_pt $inner_h $bbox_pb $bbox_bb ) - ($bbox_pb $bbox_bb);
  12798.             }
  12799.             // $op = 'W* n';    // Clipping
  12800.             $op 'W n'// Clipping alternative mode
  12801.             $this->writer->write("q");
  12802.             $ch $clip_y1 $y;
  12803.             $this->writer->write(sprintf('%.3F %.3F %.3F %.3F re %s'$x Mpdf::SCALE, ($this->$y) * Mpdf::SCALE$w Mpdf::SCALE, -$ch Mpdf::SCALE$op));
  12804.             if (!empty($block_s)) {
  12805.                 $tmp "q\n" sprintf('%.3F %.3F %.3F %.3F re %s'$x Mpdf::SCALE, ($this->$y) * Mpdf::SCALE$w Mpdf::SCALE, -$ch Mpdf::SCALE$op);
  12806.                 $tmp .= "\n" $block_s "\nQ";
  12807.                 $block_s $tmp;
  12808.             }
  12809.         }
  12810.         if (!empty($block_s)) {
  12811.             if ($shrink_f != 1) { // i.e. autofit has resized the box
  12812.                 $tmp "q\n" $this->transformScale(($shrink_f 100), ($shrink_f 100), $x$ytrue);
  12813.                 $tmp .= "\n" $block_s "\nQ";
  12814.                 $block_s $tmp;
  12815.             }
  12816.             $this->writer->write($block_s);
  12817.         }
  12818.         if ($shrink_f != 1) { // i.e. autofit has resized the box
  12819.             $this->StartTransform();
  12820.             $this->transformScale(($shrink_f 100), ($shrink_f 100), $x$y);
  12821.         }
  12822.         $this->writer->write($this->headerbuffer);
  12823.         if ($shrink_f != 1) { // i.e. autofit has resized the box
  12824.             $this->StopTransform();
  12825.         }
  12826.         if ($overflow == 'hidden') {
  12827.             // End clipping
  12828.             $this->writer->write("Q");
  12829.         }
  12830.         $this->writer->write($rot_end);
  12831.         // Page Links
  12832.         foreach ($this->HTMLheaderPageLinks as $lk) {
  12833.             if ($rotate) {
  12834.                 $tmp $lk[2]; // Switch h - w
  12835.                 $lk[2] = $lk[3];
  12836.                 $lk[3] = $tmp;
  12837.                 $lx1 = (($lk[0] / Mpdf::SCALE));
  12838.                 $ly1 = (($this->- ($lk[1] / Mpdf::SCALE)));
  12839.                 if ($rotate == 90) {
  12840.                     $adjx = -($lx1 $bbox_x) + ($preroth - ($ly1 $bbox_y));
  12841.                     $adjy = -($ly1 $bbox_y) + ($lx1 $bbox_x);
  12842.                     $lk[2] = -$lk[2];
  12843.                 } elseif ($rotate == -90) {
  12844.                     $adjx = -($lx1 $bbox_x) + ($ly1 $bbox_y);
  12845.                     $adjy = -($ly1 $bbox_y) - ($lx1 $bbox_x) + $prerotw;
  12846.                     $lk[3] = -$lk[3];
  12847.                 }
  12848.                 if ($rot_rpos !== false) {
  12849.                     $adjx += $prerotw $preroth;
  12850.                 }
  12851.                 if ($rot_bpos !== false) {
  12852.                     $adjy += $preroth $prerotw;
  12853.                 }
  12854.                 $lx1 += $adjx;
  12855.                 $ly1 += $adjy;
  12856.                 $lk[0] = $lx1 Mpdf::SCALE;
  12857.                 $lk[1] = ($this->$ly1) * Mpdf::SCALE;
  12858.             }
  12859.             if ($shrink_f != 1) {  // i.e. autofit has resized the box
  12860.                 $lx1 = (($lk[0] / Mpdf::SCALE) - $x);
  12861.                 $lx2 $x + ($lx1 $shrink_f);
  12862.                 $lk[0] = $lx2 Mpdf::SCALE;
  12863.                 $ly1 = (($this->- ($lk[1] / Mpdf::SCALE)) - $y);
  12864.                 $ly2 $y + ($ly1 $shrink_f);
  12865.                 $lk[1] = ($this->$ly2) * Mpdf::SCALE;
  12866.                 $lk[2] *= $shrink_f// width
  12867.                 $lk[3] *= $shrink_f// height
  12868.             }
  12869.             $this->PageLinks[$this->page][] = $lk;
  12870.         }
  12871.         foreach ($this->HTMLheaderPageForms as $n => $f) {
  12872.             if ($shrink_f != 1) {  // i.e. autofit has resized the box
  12873.                 $f['x'] = $x + (($f['x'] - $x) * $shrink_f);
  12874.                 $f['y'] = $y + (($f['y'] - $y) * $shrink_f);
  12875.                 $f['w'] *= $shrink_f;
  12876.                 $f['h'] *= $shrink_f;
  12877.                 $f['style']['fontsize'] *= $shrink_f;
  12878.             }
  12879.             $this->form->forms[$f['n']] = $f;
  12880.         }
  12881.         // Page Annotations
  12882.         foreach ($this->HTMLheaderPageAnnots as $lk) {
  12883.             if ($rotate) {
  12884.                 if ($rotate == 90) {
  12885.                     $adjx = -($lk['x'] - $bbox_x) + ($preroth - ($lk['y'] - $bbox_y));
  12886.                     $adjy = -($lk['y'] - $bbox_y) + ($lk['x'] - $bbox_x);
  12887.                 } elseif ($rotate == -90) {
  12888.                     $adjx = -($lk['x'] - $bbox_x) + ($lk['y'] - $bbox_y);
  12889.                     $adjy = -($lk['y'] - $bbox_y) - ($lk['x'] - $bbox_x) + $prerotw;
  12890.                 }
  12891.                 if ($rot_rpos !== false) {
  12892.                     $adjx += $prerotw $preroth;
  12893.                 }
  12894.                 if ($rot_bpos !== false) {
  12895.                     $adjy += $preroth $prerotw;
  12896.                 }
  12897.                 $lk['x'] += $adjx;
  12898.                 $lk['y'] += $adjy;
  12899.             }
  12900.             if ($shrink_f != 1) {  // i.e. autofit has resized the box
  12901.                 $lk['x'] = $x + (($lk['x'] - $x) * $shrink_f);
  12902.                 $lk['y'] = $y + (($lk['y'] - $y) * $shrink_f);
  12903.             }
  12904.             $this->PageAnnots[$this->page][] = $lk;
  12905.         }
  12906.         // Restore
  12907.         $this->headerbuffer '';
  12908.         $this->HTMLheaderPageLinks = [];
  12909.         $this->HTMLheaderPageAnnots = [];
  12910.         $this->HTMLheaderPageForms = [];
  12911.         $this->pageBackgrounds $save_bgs;
  12912.         $this->writingHTMLheader false;
  12913.         $this->writingHTMLfooter false;
  12914.         $this->fullImageHeight false;
  12915.         $this->ResetMargins();
  12916.         $this->pgwidth $this->$this->lMargin $this->rMargin;
  12917.         $this->SetXY($save_x$save_y);
  12918.         $this->title2annots $save_annots// *ANNOTATIONS*
  12919.         $this->InFooter false// turns back on autopagebreaks
  12920.         $this->pageoutput[$this->page] = [];
  12921.         $this->pageoutput[$this->page]['Font'] = '';
  12922.         /* -- COLUMNS -- */
  12923.         if ($save_cols) {
  12924.             $this->SetColumns($save_nbcol$this->colvAlign$this->ColGap);
  12925.         }
  12926.         /* -- END COLUMNS -- */
  12927.     }
  12928.     /* -- END CSS-POSITION -- */
  12929.     function initialiseBlock(&$blk)
  12930.     {
  12931.         $blk['margin_top'] = 0;
  12932.         $blk['margin_left'] = 0;
  12933.         $blk['margin_bottom'] = 0;
  12934.         $blk['margin_right'] = 0;
  12935.         $blk['padding_top'] = 0;
  12936.         $blk['padding_left'] = 0;
  12937.         $blk['padding_bottom'] = 0;
  12938.         $blk['padding_right'] = 0;
  12939.         $blk['border_top']['w'] = 0;
  12940.         $blk['border_left']['w'] = 0;
  12941.         $blk['border_bottom']['w'] = 0;
  12942.         $blk['border_right']['w'] = 0;
  12943.         $blk['direction'] = 'ltr';
  12944.         $blk['hide'] = false;
  12945.         $blk['outer_left_margin'] = 0;
  12946.         $blk['outer_right_margin'] = 0;
  12947.         $blk['cascadeCSS'] = [];
  12948.         $blk['block-align'] = false;
  12949.         $blk['bgcolor'] = false;
  12950.         $blk['page_break_after_avoid'] = false;
  12951.         $blk['keep_block_together'] = false;
  12952.         $blk['float'] = false;
  12953.         $blk['line_height'] = '';
  12954.         $blk['margin_collapse'] = false;
  12955.     }
  12956.     function border_details($bd)
  12957.     {
  12958.         $prop preg_split('/\s+/'trim($bd));
  12959.         if (isset($this->blk[$this->blklvl]['inner_width'])) {
  12960.             $refw $this->blk[$this->blklvl]['inner_width'];
  12961.         } elseif (isset($this->blk[$this->blklvl 1]['inner_width'])) {
  12962.             $refw $this->blk[$this->blklvl 1]['inner_width'];
  12963.         } else {
  12964.             $refw $this->w;
  12965.         }
  12966.         if (count($prop) == 1) {
  12967.             $bsize $this->sizeConverter->convert($prop[0], $refw$this->FontSizefalse);
  12968.             if ($bsize 0) {
  12969.                 return ['s' => 1'w' => $bsize'c' => $this->colorConverter->convert(0$this->PDFAXwarnings), 'style' => 'solid'];
  12970.             } else {
  12971.                 return ['w' => 0's' => 0];
  12972.             }
  12973.         } elseif (count($prop) == 2) {
  12974.             // 1px solid
  12975.             if (in_array($prop[1], $this->borderstyles) || $prop[1] == 'none' || $prop[1] == 'hidden') {
  12976.                 $prop[2] = '';
  12977.             } // solid #000000
  12978.             elseif (in_array($prop[0], $this->borderstyles) || $prop[0] == 'none' || $prop[0] == 'hidden') {
  12979.                 $prop[0] = '';
  12980.                 $prop[1] = $prop[0];
  12981.                 $prop[2] = $prop[1];
  12982.             } // 1px #000000
  12983.             else {
  12984.                 $prop[1] = '';
  12985.                 $prop[2] = $prop[1];
  12986.             }
  12987.         } elseif (count($prop) == 3) {
  12988.             // Change #000000 1px solid to 1px solid #000000 (proper)
  12989.             if (substr($prop[0], 01) == '#') {
  12990.                 $tmp $prop[0];
  12991.                 $prop[0] = $prop[1];
  12992.                 $prop[1] = $prop[2];
  12993.                 $prop[2] = $tmp;
  12994.             } // Change solid #000000 1px to 1px solid #000000 (proper)
  12995.             elseif (substr($prop[0], 11) == '#') {
  12996.                 $tmp $prop[1];
  12997.                 $prop[0] = $prop[2];
  12998.                 $prop[1] = $prop[0];
  12999.                 $prop[2] = $tmp;
  13000.             } // Change solid 1px #000000 to 1px solid #000000 (proper)
  13001.             elseif (in_array($prop[0], $this->borderstyles) || $prop[0] == 'none' || $prop[0] == 'hidden') {
  13002.                 $tmp $prop[0];
  13003.                 $prop[0] = $prop[1];
  13004.                 $prop[1] = $tmp;
  13005.             }
  13006.         } else {
  13007.             return ['w' => 0's' => 0];
  13008.         }
  13009.         // Size
  13010.         $bsize $this->sizeConverter->convert($prop[0], $refw$this->FontSizefalse);
  13011.         // color
  13012.         $coul $this->colorConverter->convert($prop[2], $this->PDFAXwarnings); // returns array
  13013.         // Style
  13014.         $prop[1] = strtolower($prop[1]);
  13015.         if (in_array($prop[1], $this->borderstyles) && $bsize 0) {
  13016.             $on 1;
  13017.         } elseif ($prop[1] == 'hidden') {
  13018.             $on 1;
  13019.             $bsize 0;
  13020.             $coul '';
  13021.         } elseif ($prop[1] == 'none') {
  13022.             $on 0;
  13023.             $bsize 0;
  13024.             $coul '';
  13025.         } else {
  13026.             $on 0;
  13027.             $bsize 0;
  13028.             $coul '';
  13029.             $prop[1] = '';
  13030.         }
  13031.         return ['s' => $on'w' => $bsize'c' => $coul'style' => $prop[1], 'dom' => 0];
  13032.     }
  13033.     /* -- END HTML-CSS -- */
  13034.     /* -- BORDER-RADIUS -- */
  13035.     function _borderPadding($a$b, &$px, &$py)
  13036.     {
  13037.         // $px and py are padding long axis (x) and short axis (y)
  13038.         $added 0// extra padding
  13039.         $x $a $px;
  13040.         $y $b $py;
  13041.         // Check if Falls within ellipse of border radius
  13042.         if (( (($x $added) * ($x $added)) / ($a $a) + (($y $added) * ($y $added)) / ($b $b) ) <= 1) {
  13043.             return false;
  13044.         }
  13045.         $t atan2($y$x);
  13046.         $newx $b sqrt((($b $b) / ($a $a)) + ( tan($t) * tan($t) ));
  13047.         $newy $a sqrt((($a $a) / ($b $b)) + ( (tan($t)) * (tan($t)) ));
  13048.         $px max($px$a $newx $added);
  13049.         $py max($py$b $newy $added);
  13050.     }
  13051.     /* -- END BORDER-RADIUS -- */
  13052.     /* -- HTML-CSS -- */
  13053.     /* -- CSS-PAGE -- */
  13054.     function SetPagedMediaCSS($name$first$oddEven)
  13055.     {
  13056.         if ($oddEven == 'E') {
  13057.             if ($this->directionality == 'rtl') {
  13058.                 $side 'R';
  13059.             } else {
  13060.                 $side 'L';
  13061.             }
  13062.         } else {
  13063.             if ($this->directionality == 'rtl') {
  13064.                 $side 'L';
  13065.             } else {
  13066.                 $side 'R';
  13067.             }
  13068.         }
  13069.         $name strtoupper($name);
  13070.         $p = [];
  13071.         $p['SIZE'] = 'AUTO';
  13072.         // Uses mPDF original margins as default
  13073.         $p['MARGIN-RIGHT'] = strval($this->orig_rMargin) . 'mm';
  13074.         $p['MARGIN-LEFT'] = strval($this->orig_lMargin) . 'mm';
  13075.         $p['MARGIN-TOP'] = strval($this->orig_tMargin) . 'mm';
  13076.         $p['MARGIN-BOTTOM'] = strval($this->orig_bMargin) . 'mm';
  13077.         $p['MARGIN-HEADER'] = strval($this->orig_hMargin) . 'mm';
  13078.         $p['MARGIN-FOOTER'] = strval($this->orig_fMargin) . 'mm';
  13079.         // Basic page + selector
  13080.         if (isset($this->cssManager->CSS['@PAGE'])) {
  13081.             $zp $this->cssManager->CSS['@PAGE'];
  13082.         } else {
  13083.             $zp = [];
  13084.         }
  13085.         if (is_array($zp) && !empty($zp)) {
  13086.             $p array_merge($p$zp);
  13087.         }
  13088.         if (isset($p['EVEN-HEADER-NAME']) && $oddEven == 'E') {
  13089.             $p['HEADER'] = $p['EVEN-HEADER-NAME'];
  13090.             unset($p['EVEN-HEADER-NAME']);
  13091.         }
  13092.         if (isset($p['ODD-HEADER-NAME']) && $oddEven != 'E') {
  13093.             $p['HEADER'] = $p['ODD-HEADER-NAME'];
  13094.             unset($p['ODD-HEADER-NAME']);
  13095.         }
  13096.         if (isset($p['EVEN-FOOTER-NAME']) && $oddEven == 'E') {
  13097.             $p['FOOTER'] = $p['EVEN-FOOTER-NAME'];
  13098.             unset($p['EVEN-FOOTER-NAME']);
  13099.         }
  13100.         if (isset($p['ODD-FOOTER-NAME']) && $oddEven != 'E') {
  13101.             $p['FOOTER'] = $p['ODD-FOOTER-NAME'];
  13102.             unset($p['ODD-FOOTER-NAME']);
  13103.         }
  13104.         // If right/Odd page
  13105.         if (isset($this->cssManager->CSS['@PAGE>>PSEUDO>>RIGHT']) && $side == 'R') {
  13106.             $zp $this->cssManager->CSS['@PAGE>>PSEUDO>>RIGHT'];
  13107.         } else {
  13108.             $zp = [];
  13109.         }
  13110.         if (isset($zp['SIZE'])) {
  13111.             unset($zp['SIZE']);
  13112.         }
  13113.         if (isset($zp['SHEET-SIZE'])) {
  13114.             unset($zp['SHEET-SIZE']);
  13115.         }
  13116.         // Disallow margin-left or -right on :LEFT or :RIGHT
  13117.         if (isset($zp['MARGIN-LEFT'])) {
  13118.             unset($zp['MARGIN-LEFT']);
  13119.         }
  13120.         if (isset($zp['MARGIN-RIGHT'])) {
  13121.             unset($zp['MARGIN-RIGHT']);
  13122.         }
  13123.         if (is_array($zp) && !empty($zp)) {
  13124.             $p array_merge($p$zp);
  13125.         }
  13126.         // If left/Even page
  13127.         if (isset($this->cssManager->CSS['@PAGE>>PSEUDO>>LEFT']) && $side == 'L') {
  13128.             $zp $this->cssManager->CSS['@PAGE>>PSEUDO>>LEFT'];
  13129.         } else {
  13130.             $zp = [];
  13131.         }
  13132.         if (isset($zp['SIZE'])) {
  13133.             unset($zp['SIZE']);
  13134.         }
  13135.         if (isset($zp['SHEET-SIZE'])) {
  13136.             unset($zp['SHEET-SIZE']);
  13137.         }
  13138.         // Disallow margin-left or -right on :LEFT or :RIGHT
  13139.         if (isset($zp['MARGIN-LEFT'])) {
  13140.             unset($zp['MARGIN-LEFT']);
  13141.         }
  13142.         if (isset($zp['MARGIN-RIGHT'])) {
  13143.             unset($zp['MARGIN-RIGHT']);
  13144.         }
  13145.         if (is_array($zp) && !empty($zp)) {
  13146.             $p array_merge($p$zp);
  13147.         }
  13148.         // If first page
  13149.         if (isset($this->cssManager->CSS['@PAGE>>PSEUDO>>FIRST']) && $first) {
  13150.             $zp $this->cssManager->CSS['@PAGE>>PSEUDO>>FIRST'];
  13151.         } else {
  13152.             $zp = [];
  13153.         }
  13154.         if (isset($zp['SIZE'])) {
  13155.             unset($zp['SIZE']);
  13156.         }
  13157.         if (isset($zp['SHEET-SIZE'])) {
  13158.             unset($zp['SHEET-SIZE']);
  13159.         }
  13160.         // Disallow margin-left or -right on :FIRST    // mPDF 5.7.3
  13161.         if (isset($zp['MARGIN-LEFT'])) {
  13162.             unset($zp['MARGIN-LEFT']);
  13163.         }
  13164.         if (isset($zp['MARGIN-RIGHT'])) {
  13165.             unset($zp['MARGIN-RIGHT']);
  13166.         }
  13167.         if (is_array($zp) && !empty($zp)) {
  13168.             $p array_merge($p$zp);
  13169.         }
  13170.         // If named page
  13171.         if ($name) {
  13172.             if (isset($this->cssManager->CSS['@PAGE>>NAMED>>' $name])) {
  13173.                 $zp $this->cssManager->CSS['@PAGE>>NAMED>>' $name];
  13174.             } else {
  13175.                 $zp = [];
  13176.             }
  13177.             if (is_array($zp) && !empty($zp)) {
  13178.                 $p array_merge($p$zp);
  13179.             }
  13180.             if (isset($p['EVEN-HEADER-NAME']) && $oddEven == 'E') {
  13181.                 $p['HEADER'] = $p['EVEN-HEADER-NAME'];
  13182.                 unset($p['EVEN-HEADER-NAME']);
  13183.             }
  13184.             if (isset($p['ODD-HEADER-NAME']) && $oddEven != 'E') {
  13185.                 $p['HEADER'] = $p['ODD-HEADER-NAME'];
  13186.                 unset($p['ODD-HEADER-NAME']);
  13187.             }
  13188.             if (isset($p['EVEN-FOOTER-NAME']) && $oddEven == 'E') {
  13189.                 $p['FOOTER'] = $p['EVEN-FOOTER-NAME'];
  13190.                 unset($p['EVEN-FOOTER-NAME']);
  13191.             }
  13192.             if (isset($p['ODD-FOOTER-NAME']) && $oddEven != 'E') {
  13193.                 $p['FOOTER'] = $p['ODD-FOOTER-NAME'];
  13194.                 unset($p['ODD-FOOTER-NAME']);
  13195.             }
  13196.             // If named right/Odd page
  13197.             if (isset($this->cssManager->CSS['@PAGE>>NAMED>>' $name '>>PSEUDO>>RIGHT']) && $side == 'R') {
  13198.                 $zp $this->cssManager->CSS['@PAGE>>NAMED>>' $name '>>PSEUDO>>RIGHT'];
  13199.             } else {
  13200.                 $zp = [];
  13201.             }
  13202.             if (isset($zp['SIZE'])) {
  13203.                 unset($zp['SIZE']);
  13204.             }
  13205.             if (isset($zp['SHEET-SIZE'])) {
  13206.                 unset($zp['SHEET-SIZE']);
  13207.             }
  13208.             // Disallow margin-left or -right on :LEFT or :RIGHT
  13209.             if (isset($zp['MARGIN-LEFT'])) {
  13210.                 unset($zp['MARGIN-LEFT']);
  13211.             }
  13212.             if (isset($zp['MARGIN-RIGHT'])) {
  13213.                 unset($zp['MARGIN-RIGHT']);
  13214.             }
  13215.             if (is_array($zp) && !empty($zp)) {
  13216.                 $p array_merge($p$zp);
  13217.             }
  13218.             // If named left/Even page
  13219.             if (isset($this->cssManager->CSS['@PAGE>>NAMED>>' $name '>>PSEUDO>>LEFT']) && $side == 'L') {
  13220.                 $zp $this->cssManager->CSS['@PAGE>>NAMED>>' $name '>>PSEUDO>>LEFT'];
  13221.             } else {
  13222.                 $zp = [];
  13223.             }
  13224.             if (isset($zp['SIZE'])) {
  13225.                 unset($zp['SIZE']);
  13226.             }
  13227.             if (isset($zp['SHEET-SIZE'])) {
  13228.                 unset($zp['SHEET-SIZE']);
  13229.             }
  13230.             // Disallow margin-left or -right on :LEFT or :RIGHT
  13231.             if (isset($zp['MARGIN-LEFT'])) {
  13232.                 unset($zp['MARGIN-LEFT']);
  13233.             }
  13234.             if (isset($zp['MARGIN-RIGHT'])) {
  13235.                 unset($zp['MARGIN-RIGHT']);
  13236.             }
  13237.             if (is_array($zp) && !empty($zp)) {
  13238.                 $p array_merge($p$zp);
  13239.             }
  13240.             // If named first page
  13241.             if (isset($this->cssManager->CSS['@PAGE>>NAMED>>' $name '>>PSEUDO>>FIRST']) && $first) {
  13242.                 $zp $this->cssManager->CSS['@PAGE>>NAMED>>' $name '>>PSEUDO>>FIRST'];
  13243.             } else {
  13244.                 $zp = [];
  13245.             }
  13246.             if (isset($zp['SIZE'])) {
  13247.                 unset($zp['SIZE']);
  13248.             }
  13249.             if (isset($zp['SHEET-SIZE'])) {
  13250.                 unset($zp['SHEET-SIZE']);
  13251.             }
  13252.             // Disallow margin-left or -right on :FIRST    // mPDF 5.7.3
  13253.             if (isset($zp['MARGIN-LEFT'])) {
  13254.                 unset($zp['MARGIN-LEFT']);
  13255.             }
  13256.             if (isset($zp['MARGIN-RIGHT'])) {
  13257.                 unset($zp['MARGIN-RIGHT']);
  13258.             }
  13259.             if (is_array($zp) && !empty($zp)) {
  13260.                 $p array_merge($p$zp);
  13261.             }
  13262.         }
  13263.         $orientation $mgl $mgr $mgt $mgb $mgh $mgf '';
  13264.         $header $footer '';
  13265.         $resetpagenum $pagenumstyle $suppress '';
  13266.         $marks '';
  13267.         $bg = [];
  13268.         $newformat '';
  13269.         if (isset($p['SHEET-SIZE']) && is_array($p['SHEET-SIZE'])) {
  13270.             $newformat $p['SHEET-SIZE'];
  13271.             if ($newformat[0] > $newformat[1]) { // landscape
  13272.                 $newformat array_reverse($newformat);
  13273.                 $p['ORIENTATION'] = 'L';
  13274.             } else {
  13275.                 $p['ORIENTATION'] = 'P';
  13276.             }
  13277.             $this->_setPageSize($newformat$p['ORIENTATION']);
  13278.         }
  13279.         if (isset($p['SIZE']) && is_array($p['SIZE']) && !$newformat) {
  13280.             if ($p['SIZE']['W'] > $p['SIZE']['H']) {
  13281.                 $p['ORIENTATION'] = 'L';
  13282.             } else {
  13283.                 $p['ORIENTATION'] = 'P';
  13284.             }
  13285.         }
  13286.         if (is_array($p['SIZE'])) {
  13287.             if ($p['SIZE']['W'] > $this->fw) {
  13288.                 $p['SIZE']['W'] = $this->fw;
  13289.             } // mPD 4.2 use fw not fPt
  13290.             if ($p['SIZE']['H'] > $this->fh) {
  13291.                 $p['SIZE']['H'] = $this->fh;
  13292.             }
  13293.             if (($p['ORIENTATION'] == $this->DefOrientation && !$newformat) || ($newformat && $p['ORIENTATION'] == 'P')) {
  13294.                 $outer_width_LR = ($this->fw $p['SIZE']['W']) / 2;
  13295.                 $outer_width_TB = ($this->fh $p['SIZE']['H']) / 2;
  13296.             } else {
  13297.                 $outer_width_LR = ($this->fh $p['SIZE']['W']) / 2;
  13298.                 $outer_width_TB = ($this->fw $p['SIZE']['H']) / 2;
  13299.             }
  13300.             $pgw $p['SIZE']['W'];
  13301.             $pgh $p['SIZE']['H'];
  13302.         } else { // AUTO LANDSCAPE PORTRAIT
  13303.             $outer_width_LR 0;
  13304.             $outer_width_TB 0;
  13305.             if (!$newformat) {
  13306.                 if (strtoupper($p['SIZE']) == 'AUTO') {
  13307.                     $p['ORIENTATION'] = $this->DefOrientation;
  13308.                 } elseif (strtoupper($p['SIZE']) == 'LANDSCAPE') {
  13309.                     $p['ORIENTATION'] = 'L';
  13310.                 } else {
  13311.                     $p['ORIENTATION'] = 'P';
  13312.                 }
  13313.             }
  13314.             if (($p['ORIENTATION'] == $this->DefOrientation && !$newformat) || ($newformat && $p['ORIENTATION'] == 'P')) {
  13315.                 $pgw $this->fw;
  13316.                 $pgh $this->fh;
  13317.             } else {
  13318.                 $pgw $this->fh;
  13319.                 $pgh $this->fw;
  13320.             }
  13321.         }
  13322.         if (isset($p['HEADER']) && $p['HEADER']) {
  13323.             $header $p['HEADER'];
  13324.         }
  13325.         if (isset($p['FOOTER']) && $p['FOOTER']) {
  13326.             $footer $p['FOOTER'];
  13327.         }
  13328.         if (isset($p['RESETPAGENUM']) && $p['RESETPAGENUM']) {
  13329.             $resetpagenum $p['RESETPAGENUM'];
  13330.         }
  13331.         if (isset($p['PAGENUMSTYLE']) && $p['PAGENUMSTYLE']) {
  13332.             $pagenumstyle $p['PAGENUMSTYLE'];
  13333.         }
  13334.         if (isset($p['SUPPRESS']) && $p['SUPPRESS']) {
  13335.             $suppress $p['SUPPRESS'];
  13336.         }
  13337.         if (isset($p['MARKS'])) {
  13338.             if (preg_match('/cross/i'$p['MARKS']) && preg_match('/crop/i'$p['MARKS'])) {
  13339.                 $marks 'CROPCROSS';
  13340.             } elseif (strtoupper($p['MARKS']) == 'CROP') {
  13341.                 $marks 'CROP';
  13342.             } elseif (strtoupper($p['MARKS']) == 'CROSS') {
  13343.                 $marks 'CROSS';
  13344.             }
  13345.         }
  13346.         if (isset($p['BACKGROUND-COLOR']) && $p['BACKGROUND-COLOR']) {
  13347.             $bg['BACKGROUND-COLOR'] = $p['BACKGROUND-COLOR'];
  13348.         }
  13349.         /* -- BACKGROUNDS -- */
  13350.         if (isset($p['BACKGROUND-GRADIENT']) && $p['BACKGROUND-GRADIENT']) {
  13351.             $bg['BACKGROUND-GRADIENT'] = $p['BACKGROUND-GRADIENT'];
  13352.         }
  13353.         if (isset($p['BACKGROUND-IMAGE']) && $p['BACKGROUND-IMAGE']) {
  13354.             $bg['BACKGROUND-IMAGE'] = $p['BACKGROUND-IMAGE'];
  13355.         }
  13356.         if (isset($p['BACKGROUND-REPEAT']) && $p['BACKGROUND-REPEAT']) {
  13357.             $bg['BACKGROUND-REPEAT'] = $p['BACKGROUND-REPEAT'];
  13358.         }
  13359.         if (isset($p['BACKGROUND-POSITION']) && $p['BACKGROUND-POSITION']) {
  13360.             $bg['BACKGROUND-POSITION'] = $p['BACKGROUND-POSITION'];
  13361.         }
  13362.         if (isset($p['BACKGROUND-IMAGE-RESIZE']) && $p['BACKGROUND-IMAGE-RESIZE']) {
  13363.             $bg['BACKGROUND-IMAGE-RESIZE'] = $p['BACKGROUND-IMAGE-RESIZE'];
  13364.         }
  13365.         if (isset($p['BACKGROUND-IMAGE-OPACITY'])) {
  13366.             $bg['BACKGROUND-IMAGE-OPACITY'] = $p['BACKGROUND-IMAGE-OPACITY'];
  13367.         }
  13368.         /* -- END BACKGROUNDS -- */
  13369.         if (isset($p['MARGIN-LEFT'])) {
  13370.             $mgl $this->sizeConverter->convert($p['MARGIN-LEFT'], $pgw) + $outer_width_LR;
  13371.         }
  13372.         if (isset($p['MARGIN-RIGHT'])) {
  13373.             $mgr $this->sizeConverter->convert($p['MARGIN-RIGHT'], $pgw) + $outer_width_LR;
  13374.         }
  13375.         if (isset($p['MARGIN-BOTTOM'])) {
  13376.             $mgb $this->sizeConverter->convert($p['MARGIN-BOTTOM'], $pgh) + $outer_width_TB;
  13377.         }
  13378.         if (isset($p['MARGIN-TOP'])) {
  13379.             $mgt $this->sizeConverter->convert($p['MARGIN-TOP'], $pgh) + $outer_width_TB;
  13380.         }
  13381.         if (isset($p['MARGIN-HEADER'])) {
  13382.             $mgh $this->sizeConverter->convert($p['MARGIN-HEADER'], $pgh) + $outer_width_TB;
  13383.         }
  13384.         if (isset($p['MARGIN-FOOTER'])) {
  13385.             $mgf $this->sizeConverter->convert($p['MARGIN-FOOTER'], $pgh) + $outer_width_TB;
  13386.         }
  13387.         if (isset($p['ORIENTATION']) && $p['ORIENTATION']) {
  13388.             $orientation $p['ORIENTATION'];
  13389.         }
  13390.         $this->page_box['outer_width_LR'] = $outer_width_LR// Used in MARKS:crop etc.
  13391.         $this->page_box['outer_width_TB'] = $outer_width_TB;
  13392.         return [$orientation$mgl$mgr$mgt$mgb$mgh$mgf$header$footer$bg$resetpagenum$pagenumstyle$suppress$marks$newformat];
  13393.     }
  13394.     /* -- END CSS-PAGE -- */
  13395.     /* -- CSS-FLOAT -- */
  13396.     // Added mPDF 3.0 Float DIV - CLEAR
  13397.     function ClearFloats($clear$blklvl 0)
  13398.     {
  13399.         list($l_exists$r_exists$l_max$r_max$l_width$r_width) = $this->GetFloatDivInfo($blklvltrue);
  13400.         $end $currpos = ($this->page 1000 $this->y);
  13401.         if ($clear == 'BOTH' && ($l_exists || $r_exists)) {
  13402.             $this->pageoutput[$this->page] = [];
  13403.             $end max($l_max$r_max$currpos);
  13404.         } elseif ($clear == 'RIGHT' && $r_exists) {
  13405.             $this->pageoutput[$this->page] = [];
  13406.             $end max($r_max$currpos);
  13407.         } elseif ($clear == 'LEFT' && $l_exists) {
  13408.             $this->pageoutput[$this->page] = [];
  13409.             $end max($l_max$currpos);
  13410.         } else {
  13411.             return;
  13412.         }
  13413.         $old_page $this->page;
  13414.         $new_page intval($end 1000);
  13415.         if ($old_page != $new_page) {
  13416.             $s $this->PrintPageBackgrounds();
  13417.             // Writes after the marker so not overwritten later by page background etc.
  13418.             $this->pages[$this->page] = preg_replace('/(___BACKGROUND___PATTERNS' $this->uniqstr ')/''\\1' "\n" $s "\n"$this->pages[$this->page]);
  13419.             $this->pageBackgrounds = [];
  13420.             $this->page $new_page;
  13421.         }
  13422.         $this->ResetMargins();
  13423.         $this->pageoutput[$this->page] = [];
  13424.         $this->= (round($end 1000) % 1000000) / 1000// mod changes operands to integers before processing
  13425.     }
  13426.     // Added mPDF 3.0 Float DIV
  13427.     function GetFloatDivInfo($blklvl 0$clear false)
  13428.     {
  13429.         // If blklvl specified, only returns floats at that level - for ClearFloats
  13430.         $l_exists false;
  13431.         $r_exists false;
  13432.         $l_max 0;
  13433.         $r_max 0;
  13434.         $l_width 0;
  13435.         $r_width 0;
  13436.         if (count($this->floatDivs)) {
  13437.             $currpos = ($this->page 1000 $this->y);
  13438.             foreach ($this->floatDivs as $f) {
  13439.                 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'])) {
  13440.                     if ($f['side'] == 'L') {
  13441.                         $l_exists true;
  13442.                         $l_max max($l_max$f['endpos']);
  13443.                         $l_width max($l_width$f['w']);
  13444.                     }
  13445.                     if ($f['side'] == 'R') {
  13446.                         $r_exists true;
  13447.                         $r_max max($r_max$f['endpos']);
  13448.                         $r_width max($r_width$f['w']);
  13449.                     }
  13450.                 }
  13451.             }
  13452.         }
  13453.         return [$l_exists$r_exists$l_max$r_max$l_width$r_width];
  13454.     }
  13455.     /* -- END CSS-FLOAT -- */
  13456.     // LIST MARKERS    // mPDF 6  Lists
  13457.     function _setListMarker($listitemtype$listitemimage$listitemposition)
  13458.     {
  13459.         // if position:inside (and NOT table) - output now as a textbuffer; (so if next is block, will move to new line)
  13460.         // elseif position:outside (and NOT table) - output in front of first textbuffer output by setting listitem (cf. _saveTextBuffer)
  13461.         $e '';
  13462.         $this->listitem '';
  13463.         $spacer ' ';
  13464.         // IMAGE
  13465.         if ($listitemimage && $listitemimage != 'none') {
  13466.             $listitemimage trim(preg_replace('/url\(["\']*(.*?)["\']*\)/''\\1'$listitemimage));
  13467.             // ? Restrict maximum height/width of list marker??
  13468.             $maxWidth 100;
  13469.             $maxHeight 100;
  13470.             $objattr = [];
  13471.             $objattr['margin_top'] = 0;
  13472.             $objattr['margin_bottom'] = 0;
  13473.             $objattr['margin_left'] = 0;
  13474.             $objattr['margin_right'] = 0;
  13475.             $objattr['padding_top'] = 0;
  13476.             $objattr['padding_bottom'] = 0;
  13477.             $objattr['padding_left'] = 0;
  13478.             $objattr['padding_right'] = 0;
  13479.             $objattr['width'] = 0;
  13480.             $objattr['height'] = 0;
  13481.             $objattr['border_top']['w'] = 0;
  13482.             $objattr['border_bottom']['w'] = 0;
  13483.             $objattr['border_left']['w'] = 0;
  13484.             $objattr['border_right']['w'] = 0;
  13485.             $objattr['visibility'] = 'visible';
  13486.             $srcpath $listitemimage;
  13487.             $orig_srcpath $listitemimage;
  13488.             $objattr['vertical-align'] = 'BS'// vertical alignment of marker (baseline)
  13489.             $w 0;
  13490.             $h 0;
  13491.             // Image file
  13492.             $info $this->imageProcessor->getImage($srcpathtruetrue$orig_srcpath);
  13493.             if (!$info) {
  13494.                 return;
  13495.             }
  13496.             if ($info['w'] == && $info['h'] == 0) {
  13497.                 $info['h'] = $this->sizeConverter->convert('1em'$this->blk[$this->blklvl]['inner_width'], $this->FontSizefalse);
  13498.             }
  13499.             $objattr['file'] = $srcpath;
  13500.             // Default width and height calculation if needed
  13501.             if ($w == and $h == 0) {
  13502.                 /* -- IMAGES-WMF -- */
  13503.                 if ($info['type'] == 'wmf') {
  13504.                     // WMF units are twips (1/20pt)
  13505.                     // divide by 20 to get points
  13506.                     // divide by k to get user units
  13507.                     $w abs($info['w']) / (20 Mpdf::SCALE);
  13508.                     $h abs($info['h']) / (20 Mpdf::SCALE);
  13509.                 } else {                 /* -- END IMAGES-WMF -- */
  13510.                     if ($info['type'] == 'svg') {
  13511.                         // SVG units are pixels
  13512.                         $w abs($info['w']) / Mpdf::SCALE;
  13513.                         $h abs($info['h']) / Mpdf::SCALE;
  13514.                     } else {
  13515.                         // Put image at default image dpi
  13516.                         $w = ($info['w'] / Mpdf::SCALE) * (72 $this->img_dpi);
  13517.                         $h = ($info['h'] / Mpdf::SCALE) * (72 $this->img_dpi);
  13518.                     }
  13519.                 }
  13520.             }
  13521.             // IF WIDTH OR HEIGHT SPECIFIED
  13522.             if ($w == 0) {
  13523.                 $w abs($h $info['w'] / $info['h']);
  13524.             }
  13525.             if ($h == 0) {
  13526.                 $h abs($w $info['h'] / $info['w']);
  13527.             }
  13528.             if ($w $maxWidth) {
  13529.                 $w $maxWidth;
  13530.                 $h abs($w $info['h'] / $info['w']);
  13531.             }
  13532.             if ($h $maxHeight) {
  13533.                 $h $maxHeight;
  13534.                 $w abs($h $info['w'] / $info['h']);
  13535.             }
  13536.             $objattr['type'] = 'image';
  13537.             $objattr['itype'] = $info['type'];
  13538.             $objattr['orig_h'] = $info['h'];
  13539.             $objattr['orig_w'] = $info['w'];
  13540.             /* -- IMAGES-WMF -- */
  13541.             if ($info['type'] == 'wmf') {
  13542.                 $objattr['wmf_x'] = $info['x'];
  13543.                 $objattr['wmf_y'] = $info['y'];
  13544.             } else {             /* -- END IMAGES-WMF -- */
  13545.                 if ($info['type'] == 'svg') {
  13546.                     $objattr['wmf_x'] = $info['x'];
  13547.                     $objattr['wmf_y'] = $info['y'];
  13548.                 }
  13549.             }
  13550.             $objattr['height'] = $h;
  13551.             $objattr['width'] = $w;
  13552.             $objattr['image_height'] = $h;
  13553.             $objattr['image_width'] = $w;
  13554.             $objattr['dir'] = (isset($this->blk[$this->blklvl]['direction']) ? $this->blk[$this->blklvl]['direction'] : 'ltr');
  13555.             $objattr['listmarker'] = true;
  13556.             $objattr['listmarkerposition'] = $listitemposition;
  13557.             $e Mpdf::OBJECT_IDENTIFIER "type=image,objattr=" serialize($objattr) . Mpdf::OBJECT_IDENTIFIER;
  13558.             $this->_saveTextBuffer($e);
  13559.             if ($listitemposition == 'inside') {
  13560.                 $e $spacer;
  13561.                 $this->_saveTextBuffer($e);
  13562.             }
  13563.         } elseif ($listitemtype == 'disc' || $listitemtype == 'circle' || $listitemtype == 'square') { // SYMBOL (needs new font)
  13564.             $objattr = [];
  13565.             $objattr['type'] = 'listmarker';
  13566.             $objattr['listmarkerposition'] = $listitemposition;
  13567.             $objattr['width'] = 0;
  13568.             $size $this->sizeConverter->convert($this->list_symbol_size$this->FontSize);
  13569.             $objattr['size'] = $size;
  13570.             $objattr['offset'] = $this->sizeConverter->convert($this->list_marker_offset$this->FontSize);
  13571.             if ($listitemposition == 'inside') {
  13572.                 $objattr['width'] = $size $objattr['offset'];
  13573.             }
  13574.             $objattr['height'] = $this->FontSize;
  13575.             $objattr['vertical-align'] = 'T';
  13576.             $objattr['text'] = '';
  13577.             $objattr['dir'] = (isset($this->blk[$this->blklvl]['direction']) ? $this->blk[$this->blklvl]['direction'] : 'ltr');
  13578.             $objattr['bullet'] = $listitemtype;
  13579.             $objattr['colorarray'] = $this->colorarray;
  13580.             $objattr['fontfamily'] = $this->FontFamily;
  13581.             $objattr['fontsize'] = $this->FontSize;
  13582.             $objattr['fontsizept'] = $this->FontSizePt;
  13583.             $objattr['fontstyle'] = $this->FontStyle;
  13584.             $e Mpdf::OBJECT_IDENTIFIER "type=listmarker,objattr=" serialize($objattr) . Mpdf::OBJECT_IDENTIFIER;
  13585.             $this->listitem $this->_saveTextBuffer($e''''true); // true returns array
  13586.         } elseif (preg_match('/U\+([a-fA-F0-9]+)/i'$listitemtype$m)) { // SYMBOL 2 (needs new font)
  13587.             if ($this->_charDefined($this->CurrentFont['cw'], hexdec($m[1]))) {
  13588.                 $list_item_marker UtfString::codeHex2utf($m[1]);
  13589.             } else {
  13590.                 $list_item_marker '-';
  13591.             }
  13592.             if (preg_match('/rgb\(.*?\)/'$listitemtype$m)) {
  13593.                 $list_item_color $this->colorConverter->convert($m[0], $this->PDFAXwarnings);
  13594.             } else {
  13595.                 $list_item_color '';
  13596.             }
  13597.             // SAVE then SET COLR
  13598.             $save_colorarray $this->colorarray;
  13599.             if ($list_item_color) {
  13600.                 $this->colorarray $list_item_color;
  13601.             }
  13602.             if ($listitemposition == 'inside') {
  13603.                 $e $list_item_marker $spacer;
  13604.                 $this->_saveTextBuffer($e);
  13605.             } else {
  13606.                 $objattr = [];
  13607.                 $objattr['type'] = 'listmarker';
  13608.                 $objattr['width'] = 0;
  13609.                 $objattr['height'] = $this->FontSize;
  13610.                 $objattr['vertical-align'] = 'T';
  13611.                 $objattr['text'] = $list_item_marker;
  13612.                 $objattr['dir'] = (isset($this->blk[$this->blklvl]['direction']) ? $this->blk[$this->blklvl]['direction'] : 'ltr');
  13613.                 $objattr['colorarray'] = $this->colorarray;
  13614.                 $objattr['fontfamily'] = $this->FontFamily;
  13615.                 $objattr['fontsize'] = $this->FontSize;
  13616.                 $objattr['fontsizept'] = $this->FontSizePt;
  13617.                 $objattr['fontstyle'] = $this->FontStyle;
  13618.                 $e Mpdf::OBJECT_IDENTIFIER "type=listmarker,objattr=" serialize($objattr) . Mpdf::OBJECT_IDENTIFIER;
  13619.                 $this->listitem $this->_saveTextBuffer($e''''true); // true returns array
  13620.             }
  13621.             // RESET COLOR
  13622.             $this->colorarray $save_colorarray;
  13623.         } else { // TEXT
  13624.             $counter $this->listcounter[$this->listlvl];
  13625.             if ($listitemtype == 'none') {
  13626.                 return;
  13627.             }
  13628.             $num $this->_getStyledNumber($counter$listitemtypetrue);
  13629.             if ($listitemposition == 'inside') {
  13630.                 $e $num $this->list_number_suffix $spacer;
  13631.                 $this->_saveTextBuffer($e);
  13632.             } else {
  13633.                 if (isset($this->blk[$this->blklvl]['direction']) && $this->blk[$this->blklvl]['direction'] == 'rtl') {
  13634.                     // REPLACE MIRRORED RTL $this->list_number_suffix  e.g. ) -> (  (NB could use Ucdn::$mirror_pairs)
  13635.                     $m strtr($this->list_number_suffix")]}""([{") . $num;
  13636.                 } else {
  13637.                     $m $num $this->list_number_suffix;
  13638.                 }
  13639.                 $objattr = [];
  13640.                 $objattr['type'] = 'listmarker';
  13641.                 $objattr['width'] = 0;
  13642.                 $objattr['height'] = $this->FontSize;
  13643.                 $objattr['vertical-align'] = 'T';
  13644.                 $objattr['text'] = $m;
  13645.                 $objattr['dir'] = (isset($this->blk[$this->blklvl]['direction']) ? $this->blk[$this->blklvl]['direction'] : 'ltr');
  13646.                 $objattr['colorarray'] = $this->colorarray;
  13647.                 $objattr['fontfamily'] = $this->FontFamily;
  13648.                 $objattr['fontsize'] = $this->FontSize;
  13649.                 $objattr['fontsizept'] = $this->FontSizePt;
  13650.                 $objattr['fontstyle'] = $this->FontStyle;
  13651.                 $e Mpdf::OBJECT_IDENTIFIER "type=listmarker,objattr=" serialize($objattr) . Mpdf::OBJECT_IDENTIFIER;
  13652.                 $this->listitem $this->_saveTextBuffer($e''''true); // true returns array
  13653.             }
  13654.         }
  13655.     }
  13656.     // mPDF Lists
  13657.     function _getListMarkerWidth(&$currblk, &$a, &$i)
  13658.     {
  13659.         $blt_width 0;
  13660.         $markeroffset $this->sizeConverter->convert($this->list_marker_offset$this->FontSize);
  13661.         // Get Maximum number in the list
  13662.         $maxnum $this->listcounter[$this->listlvl];
  13663.         if ($currblk['list_style_type'] != 'disc' && $currblk['list_style_type'] != 'circle' && $currblk['list_style_type'] != 'square') {
  13664.             $lvl 1;
  13665.             for ($j $i 2$j count($a); $j+=2) {
  13666.                 $e $a[$j];
  13667.                 if (!$e) {
  13668.                     continue;
  13669.                 }
  13670.                 if ($e[0] == '/') { // end tag
  13671.                     $e strtoupper(substr($e1));
  13672.                     if ($e == 'OL' || $e == 'UL') {
  13673.                         if ($lvl == 1) {
  13674.                             break;
  13675.                         }
  13676.                         $lvl--;
  13677.                     }
  13678.                 } else { // opening tag
  13679.                     if (strpos($e' ')) {
  13680.                         $e substr($e0strpos($e' '));
  13681.                     }
  13682.                     $e strtoupper($e);
  13683.                     if ($e == 'LI') {
  13684.                         if ($lvl == 1) {
  13685.                             $maxnum++;
  13686.                         }
  13687.                     } elseif ($e == 'OL' || $e == 'UL') {
  13688.                         $lvl++;
  13689.                     }
  13690.                 }
  13691.             }
  13692.         }
  13693.         $decToAlpha = new Conversion\DecToAlpha();
  13694.         $decToRoman = new Conversion\DecToRoman();
  13695.         $decToOther = new Conversion\DecToOther($this);
  13696.         switch ($currblk['list_style_type']) {
  13697.             case 'decimal':
  13698.             case '1':
  13699.                 $blt_width $this->GetStringWidth(str_repeat('5'strlen($maxnum)) . $this->list_number_suffix);
  13700.                 break;
  13701.             case 'none':
  13702.                 $blt_width 0;
  13703.                 break;
  13704.             case 'upper-alpha':
  13705.             case 'upper-latin':
  13706.             case 'A':
  13707.                 $maxnumA $decToAlpha->convert($maxnumtrue);
  13708.                 if ($maxnum 13) {
  13709.                     $blt_width $this->GetStringWidth('D' $this->list_number_suffix);
  13710.                 } else {
  13711.                     $blt_width $this->GetStringWidth(str_repeat('W'strlen($maxnumA)) . $this->list_number_suffix);
  13712.                 }
  13713.                 break;
  13714.             case 'lower-alpha':
  13715.             case 'lower-latin':
  13716.             case 'a':
  13717.                 $maxnuma $decToAlpha->convert($maxnumfalse);
  13718.                 if ($maxnum 13) {
  13719.                     $blt_width $this->GetStringWidth('b' $this->list_number_suffix);
  13720.                 } else {
  13721.                     $blt_width $this->GetStringWidth(str_repeat('m'strlen($maxnuma)) . $this->list_number_suffix);
  13722.                 }
  13723.                 break;
  13724.             case 'upper-roman':
  13725.             case 'I':
  13726.                 if ($maxnum 87) {
  13727.                     $bbit 87;
  13728.                 } elseif ($maxnum 86) {
  13729.                     $bbit 86;
  13730.                 } elseif ($maxnum 37) {
  13731.                     $bbit 38;
  13732.                 } elseif ($maxnum 36) {
  13733.                     $bbit 37;
  13734.                 } elseif ($maxnum 27) {
  13735.                     $bbit 28;
  13736.                 } elseif ($maxnum 26) {
  13737.                     $bbit 27;
  13738.                 } elseif ($maxnum 17) {
  13739.                     $bbit 18;
  13740.                 } elseif ($maxnum 16) {
  13741.                     $bbit 17;
  13742.                 } elseif ($maxnum 7) {
  13743.                     $bbit 8;
  13744.                 } elseif ($maxnum 6) {
  13745.                     $bbit 7;
  13746.                 } elseif ($maxnum 3) {
  13747.                     $bbit 4;
  13748.                 } else {
  13749.                     $bbit $maxnum;
  13750.                 }
  13751.                 $maxlnum $decToRoman->convert($bbittrue);
  13752.                 $blt_width $this->GetStringWidth($maxlnum $this->list_number_suffix);
  13753.                 break;
  13754.             case 'lower-roman':
  13755.             case 'i':
  13756.                 if ($maxnum 87) {
  13757.                     $bbit 87;
  13758.                 } elseif ($maxnum 86) {
  13759.                     $bbit 86;
  13760.                 } elseif ($maxnum 37) {
  13761.                     $bbit 38;
  13762.                 } elseif ($maxnum 36) {
  13763.                     $bbit 37;
  13764.                 } elseif ($maxnum 27) {
  13765.                     $bbit 28;
  13766.                 } elseif ($maxnum 26) {
  13767.                     $bbit 27;
  13768.                 } elseif ($maxnum 17) {
  13769.                     $bbit 18;
  13770.                 } elseif ($maxnum 16) {
  13771.                     $bbit 17;
  13772.                 } elseif ($maxnum 7) {
  13773.                     $bbit 8;
  13774.                 } elseif ($maxnum 6) {
  13775.                     $bbit 7;
  13776.                 } elseif ($maxnum 3) {
  13777.                     $bbit 4;
  13778.                 } else {
  13779.                     $bbit $maxnum;
  13780.                 }
  13781.                 $maxlnum $decToRoman->convert($bbitfalse);
  13782.                 $blt_width $this->GetStringWidth($maxlnum $this->list_number_suffix);
  13783.                 break;
  13784.             case 'disc':
  13785.             case 'circle':
  13786.             case 'square':
  13787.                 $size $this->sizeConverter->convert($this->list_symbol_size$this->FontSize);
  13788.                 $offset $this->sizeConverter->convert($this->list_marker_offset$this->FontSize);
  13789.                 $blt_width $size $offset;
  13790.                 break;
  13791.             case 'arabic-indic':
  13792.                 $blt_width $this->GetStringWidth(str_repeat($decToOther->convert(30x0660), strlen($maxnum)) . $this->list_number_suffix);
  13793.                 break;
  13794.             case 'persian':
  13795.             case 'urdu':
  13796.                 $blt_width $this->GetStringWidth(str_repeat($decToOther->convert(30x06F0), strlen($maxnum)) . $this->list_number_suffix);
  13797.                 break;
  13798.             case 'bengali':
  13799.                 $blt_width $this->GetStringWidth(str_repeat($decToOther->convert(30x09E6), strlen($maxnum)) . $this->list_number_suffix);
  13800.                 break;
  13801.             case 'devanagari':
  13802.                 $blt_width $this->GetStringWidth(str_repeat($decToOther->convert(30x0966), strlen($maxnum)) . $this->list_number_suffix);
  13803.                 break;
  13804.             case 'gujarati':
  13805.                 $blt_width $this->GetStringWidth(str_repeat($decToOther->convert(30x0AE6), strlen($maxnum)) . $this->list_number_suffix);
  13806.                 break;
  13807.             case 'gurmukhi':
  13808.                 $blt_width $this->GetStringWidth(str_repeat($decToOther->convert(30x0A66), strlen($maxnum)) . $this->list_number_suffix);
  13809.                 break;
  13810.             case 'kannada':
  13811.                 $blt_width $this->GetStringWidth(str_repeat($decToOther->convert(30x0CE6), strlen($maxnum)) . $this->list_number_suffix);
  13812.                 break;
  13813.             case 'malayalam':
  13814.                 $blt_width $this->GetStringWidth(str_repeat($decToOther->convert(60x0D66), strlen($maxnum)) . $this->list_number_suffix);
  13815.                 break;
  13816.             case 'oriya':
  13817.                 $blt_width $this->GetStringWidth(str_repeat($decToOther->convert(30x0B66), strlen($maxnum)) . $this->list_number_suffix);
  13818.                 break;
  13819.             case 'telugu':
  13820.                 $blt_width $this->GetStringWidth(str_repeat($decToOther->convert(30x0C66), strlen($maxnum)) . $this->list_number_suffix);
  13821.                 break;
  13822.             case 'tamil':
  13823.                 $blt_width $this->GetStringWidth(str_repeat($decToOther->convert(90x0BE6), strlen($maxnum)) . $this->list_number_suffix);
  13824.                 break;
  13825.             case 'thai':
  13826.                 $blt_width $this->GetStringWidth(str_repeat($decToOther->convert(50x0E50), strlen($maxnum)) . $this->list_number_suffix);
  13827.                 break;
  13828.             default:
  13829.                 $blt_width $this->GetStringWidth(str_repeat('5'strlen($maxnum)) . $this->list_number_suffix);
  13830.                 break;
  13831.         }
  13832.         return ($blt_width $markeroffset);
  13833.     }
  13834.     function _saveTextBuffer($t$link ''$intlink ''$return false)
  13835.     {
  13836.     // mPDF 6  Lists
  13837.         $arr = [];
  13838.         $arr[0] = $t;
  13839.         if (isset($link) && $link) {
  13840.             $arr[1] = $link;
  13841.         }
  13842.         $arr[2] = $this->currentfontstyle;
  13843.         if (isset($this->colorarray) && $this->colorarray) {
  13844.             $arr[3] = $this->colorarray;
  13845.         }
  13846.         $arr[4] = $this->currentfontfamily;
  13847.         $arr[5] = $this->currentLang// mPDF 6
  13848.         if (isset($intlink) && $intlink) {
  13849.             $arr[7] = $intlink;
  13850.         }
  13851.         // mPDF 6
  13852.         // If Kerning set for OTL, and useOTL has positive value, but has not set for this particular script,
  13853.         // set for kerning via kern table
  13854.         // e.g. Latin script when useOTL set as 0x80
  13855.         if (isset($this->OTLtags['Plus']) && strpos($this->OTLtags['Plus'], 'kern') !== false && empty($this->OTLdata['GPOSinfo'])) {
  13856.             $this->textvar = ($this->textvar TextVars::FC_KERNING);
  13857.         }
  13858.         $arr[8] = $this->textvar// mPDF 5.7.1
  13859.         if (isset($this->textparam) && $this->textparam) {
  13860.             $arr[9] = $this->textparam;
  13861.         }
  13862.         if (isset($this->spanbgcolorarray) && $this->spanbgcolorarray) {
  13863.             $arr[10] = $this->spanbgcolorarray;
  13864.         }
  13865.         $arr[11] = $this->currentfontsize;
  13866.         if (isset($this->ReqFontStyle) && $this->ReqFontStyle) {
  13867.             $arr[12] = $this->ReqFontStyle;
  13868.         }
  13869.         if (isset($this->lSpacingCSS) && $this->lSpacingCSS) {
  13870.             $arr[14] = $this->lSpacingCSS;
  13871.         }
  13872.         if (isset($this->wSpacingCSS) && $this->wSpacingCSS) {
  13873.             $arr[15] = $this->wSpacingCSS;
  13874.         }
  13875.         if (isset($this->spanborddet) && $this->spanborddet) {
  13876.             $arr[16] = $this->spanborddet;
  13877.         }
  13878.         if (isset($this->textshadow) && $this->textshadow) {
  13879.             $arr[17] = $this->textshadow;
  13880.         }
  13881.         if (isset($this->OTLdata) && $this->OTLdata) {
  13882.             $arr[18] = $this->OTLdata;
  13883.             $this->OTLdata = [];
  13884.         } // mPDF 5.7.1
  13885.         else {
  13886.             $arr[18] = null;
  13887.         }
  13888.         // mPDF 6  Lists
  13889.         if ($return) {
  13890.             return ($arr);
  13891.         }
  13892.         if ($this->listitem) {
  13893.             $this->textbuffer[] = $this->listitem;
  13894.             $this->listitem = [];
  13895.         }
  13896.         $this->textbuffer[] = $arr;
  13897.     }
  13898.     function _saveCellTextBuffer($t$link ''$intlink '')
  13899.     {
  13900.         $arr = [];
  13901.         $arr[0] = $t;
  13902.         if (isset($link) && $link) {
  13903.             $arr[1] = $link;
  13904.         }
  13905.         $arr[2] = $this->currentfontstyle;
  13906.         if (isset($this->colorarray) && $this->colorarray) {
  13907.             $arr[3] = $this->colorarray;
  13908.         }
  13909.         $arr[4] = $this->currentfontfamily;
  13910.         if (isset($intlink) && $intlink) {
  13911.             $arr[7] = $intlink;
  13912.         }
  13913.         // mPDF 6
  13914.         // If Kerning set for OTL, and useOTL has positive value, but has not set for this particular script,
  13915.         // set for kerning via kern table
  13916.         // e.g. Latin script when useOTL set as 0x80
  13917.         if (isset($this->OTLtags['Plus']) && strpos($this->OTLtags['Plus'], 'kern') !== false && empty($this->OTLdata['GPOSinfo'])) {
  13918.             $this->textvar = ($this->textvar TextVars::FC_KERNING);
  13919.         }
  13920.         $arr[8] = $this->textvar// mPDF 5.7.1
  13921.         if (isset($this->textparam) && $this->textparam) {
  13922.             $arr[9] = $this->textparam;
  13923.         }
  13924.         if (isset($this->spanbgcolorarray) && $this->spanbgcolorarray) {
  13925.             $arr[10] = $this->spanbgcolorarray;
  13926.         }
  13927.         $arr[11] = $this->currentfontsize;
  13928.         if (isset($this->ReqFontStyle) && $this->ReqFontStyle) {
  13929.             $arr[12] = $this->ReqFontStyle;
  13930.         }
  13931.         if (isset($this->lSpacingCSS) && $this->lSpacingCSS) {
  13932.             $arr[14] = $this->lSpacingCSS;
  13933.         }
  13934.         if (isset($this->wSpacingCSS) && $this->wSpacingCSS) {
  13935.             $arr[15] = $this->wSpacingCSS;
  13936.         }
  13937.         if (isset($this->spanborddet) && $this->spanborddet) {
  13938.             $arr[16] = $this->spanborddet;
  13939.         }
  13940.         if (isset($this->textshadow) && $this->textshadow) {
  13941.             $arr[17] = $this->textshadow;
  13942.         }
  13943.         if (isset($this->OTLdata) && $this->OTLdata) {
  13944.             $arr[18] = $this->OTLdata;
  13945.             $this->OTLdata = [];
  13946.         } // mPDF 5.7.1
  13947.         else {
  13948.             $arr[18] = null;
  13949.         }
  13950.         $this->cell[$this->row][$this->col]['textbuffer'][] = $arr;
  13951.     }
  13952.     function printbuffer($arrayaux$blockstate 0$is_table false$table_draft false$cell_dir '')
  13953.     {
  13954.         // $blockstate = 0;    // NO margins/padding
  13955.         // $blockstate = 1;    // Top margins/padding only
  13956.         // $blockstate = 2;    // Bottom margins/padding only
  13957.         // $blockstate = 3;    // Top & bottom margins/padding
  13958.         $this->spanbgcolorarray '';
  13959.         $this->spanbgcolor false;
  13960.         $this->spanborder false;
  13961.         $this->spanborddet = [];
  13962.         $paint_ht_corr 0;
  13963.         /* -- CSS-FLOAT -- */
  13964.         if (count($this->floatDivs)) {
  13965.             list($l_exists$r_exists$l_max$r_max$l_width$r_width) = $this->GetFloatDivInfo($this->blklvl);
  13966.             if (($this->blk[$this->blklvl]['inner_width'] - $l_width $r_width) < ($this->GetCharWidth('W'false))) {
  13967.                 // Too narrow to fit - try to move down past L or R float
  13968.                 if ($l_max $r_max && ($this->blk[$this->blklvl]['inner_width'] - $r_width) > ($this->GetCharWidth('W'false))) {
  13969.                     $this->ClearFloats('LEFT'$this->blklvl);
  13970.                 } elseif ($r_max $l_max && ($this->blk[$this->blklvl]['inner_width'] - $l_width) > ($this->GetCharWidth('W'false))) {
  13971.                     $this->ClearFloats('RIGHT'$this->blklvl);
  13972.                 } else {
  13973.                     $this->ClearFloats('BOTH'$this->blklvl);
  13974.                 }
  13975.             }
  13976.         }
  13977.         /* -- END CSS-FLOAT -- */
  13978.         $bak_y $this->y;
  13979.         $bak_x $this->x;
  13980.         $align '';
  13981.         if (!$is_table) {
  13982.             if (isset($this->blk[$this->blklvl]['align']) && $this->blk[$this->blklvl]['align']) {
  13983.                 $align $this->blk[$this->blklvl]['align'];
  13984.             }
  13985.             // Block-align is set by e.g. <.. align="center"> Takes priority for this block but not inherited
  13986.             if (isset($this->blk[$this->blklvl]['block-align']) && $this->blk[$this->blklvl]['block-align']) {
  13987.                 $align $this->blk[$this->blklvl]['block-align'];
  13988.             }
  13989.             if (isset($this->blk[$this->blklvl]['direction'])) {
  13990.                 $blockdir $this->blk[$this->blklvl]['direction'];
  13991.             } else {
  13992.                 $blockdir "";
  13993.             }
  13994.             $this->divwidth $this->blk[$this->blklvl]['width'];
  13995.         } else {
  13996.             $align $this->cellTextAlign;
  13997.             $blockdir $cell_dir;
  13998.         }
  13999.         $oldpage $this->page;
  14000.         // ADDED for Out of Block now done as Flowing Block
  14001.         if ($this->divwidth == 0) {
  14002.             $this->divwidth $this->pgwidth;
  14003.         }
  14004.         if (!$is_table) {
  14005.             $this->SetLineHeight($this->FontSizePt$this->blk[$this->blklvl]['line_height']);
  14006.         }
  14007.         $this->divheight $this->lineheight;
  14008.         $old_height $this->divheight;
  14009.         // As a failsafe - if font has been set but not output to page
  14010.         if (!$table_draft) {
  14011.             $this->SetFont($this->default_font''$this->default_font_sizetruetrue); // force output to page
  14012.         }
  14013.         $this->newFlowingBlock($this->divwidth$this->divheight$align$is_table$blockstatetrue$blockdir$table_draft);
  14014.         $array_size count($arrayaux);
  14015.         // Added - Otherwise <div><div><p> did not output top margins/padding for 1st/2nd div
  14016.         if ($array_size == 0) {
  14017.             $this->finishFlowingBlock(true);
  14018.         } // true = END of flowing block
  14019.         // mPDF 6
  14020.         // ALL the chunks of textbuffer need to have at least basic OTLdata set
  14021.         // First make sure each element/chunk has the OTLdata for Bidi set.
  14022.         for ($i 0$i $array_size$i++) {
  14023.             if (empty($arrayaux[$i][18])) {
  14024.                 if (substr($arrayaux[$i][0], 03) == Mpdf::OBJECT_IDENTIFIER) { // object identifier has been identified!
  14025.                     $unicode = [0xFFFC]; // Object replacement character
  14026.                 } else {
  14027.                     $unicode $this->UTF8StringToArray($arrayaux[$i][0], false);
  14028.                 }
  14029.                 $is_strong false;
  14030.                 $this->getBasicOTLdata($arrayaux[$i][18], $unicode$is_strong);
  14031.             }
  14032.             // Gets messed up if try and use core fonts inside a paragraph of text which needs to be BiDi re-ordered or OTLdata set
  14033.             if (($blockdir == 'rtl' || $this->biDirectional) && isset($arrayaux[$i][4]) && in_array($arrayaux[$i][4], ['ccourier''ctimes''chelvetica''csymbol''czapfdingbats'])) {
  14034.                 throw new \Mpdf\MpdfException("You cannot use core fonts in a document which contains RTL text.");
  14035.             }
  14036.         }
  14037.         // mPDF 6
  14038.         // Process bidirectional text ready for bidi-re-ordering (which is done after line-breaks are established in WriteFlowingBlock etc.)
  14039.         if (($blockdir == 'rtl' || $this->biDirectional) && !$table_draft) {
  14040.             if (empty($this->otl)) {
  14041.                 $this->otl = new Otl($this$this->fontCache);
  14042.             }
  14043.             $this->otl->bidiPrepare($arrayaux$blockdir);
  14044.             $array_size count($arrayaux);
  14045.         }
  14046.         // Remove empty items // mPDF 6
  14047.         for ($i $array_size 1$i 0$i--) {
  14048.             if ('' === $arrayaux[$i][0] && (isset($arrayaux[$i][16]) && $arrayaux[$i][16] !== '0') && empty($arrayaux[$i][7])) {
  14049.                 unset($arrayaux[$i]);
  14050.             }
  14051.         }
  14052.         // Correct adjoining borders for inline elements
  14053.         if (isset($arrayaux[0][16])) {
  14054.             $lastspanborder $arrayaux[0][16];
  14055.         } else {
  14056.             $lastspanborder false;
  14057.         }
  14058.         for ($i 1$i $array_size$i++) {
  14059.             if (isset($arrayaux[$i][16]) && $arrayaux[$i][16] == $lastspanborder &&
  14060.                 ((!isset($arrayaux[$i][9]['bord-decoration']) && !isset($arrayaux[$i 1][9]['bord-decoration'])) ||
  14061.                 (isset($arrayaux[$i][9]['bord-decoration']) && isset($arrayaux[$i 1][9]['bord-decoration']) && $arrayaux[$i][9]['bord-decoration'] == $arrayaux[$i 1][9]['bord-decoration'])
  14062.                 )
  14063.             ) {
  14064.                 if (isset($arrayaux[$i][16]['R'])) {
  14065.                     $lastspanborder $arrayaux[$i][16];
  14066.                 } else {
  14067.                     $lastspanborder false;
  14068.                 }
  14069.                 $arrayaux[$i][16]['L']['s'] = 0;
  14070.                 $arrayaux[$i][16]['L']['w'] = 0;
  14071.                 $arrayaux[$i 1][16]['R']['s'] = 0;
  14072.                 $arrayaux[$i 1][16]['R']['w'] = 0;
  14073.             } else {
  14074.                 if (isset($arrayaux[$i][16]['R'])) {
  14075.                     $lastspanborder $arrayaux[$i][16];
  14076.                 } else {
  14077.                     $lastspanborder false;
  14078.                 }
  14079.             }
  14080.         }
  14081.         for ($i 0$i $array_size$i++) {
  14082.             // COLS
  14083.             $oldcolumn $this->CurrCol;
  14084.             $vetor = isset($arrayaux[$i]) ? $arrayaux[$i] : null;
  14085.             if ($i == && $vetor[0] != "\n" && ! $this->ispre) {
  14086.                 $vetor[0] = ltrim($vetor[0]);
  14087.                 if (!empty($vetor[18])) {
  14088.                     $this->otl->trimOTLdata($vetor[18], truefalse);
  14089.                 } // *OTL*
  14090.             }
  14091.             // FIXED TO ALLOW IT TO SHOW '0'
  14092.             if (empty($vetor[0]) && !($vetor[0] === '0') && empty($vetor[7])) {
  14093.                 // Ignore empty text and not carrying an internal link
  14094.                 // Check if it is the last element. If so then finish printing the block
  14095.                 if ($i == ($array_size 1)) {
  14096.                     $this->finishFlowingBlock(true);
  14097.                 } // true = END of flowing block
  14098.                 continue;
  14099.             }
  14100.             // Activating buffer properties
  14101.             if (isset($vetor[11]) && $vetor[11] != '') {   // Font Size
  14102.                 if ($is_table && $this->shrin_k) {
  14103.                     $this->SetFontSize($vetor[11] / $this->shrin_kfalse);
  14104.                 } else {
  14105.                     $this->SetFontSize($vetor[11], false);
  14106.                 }
  14107.             }
  14108.             if (isset($vetor[17]) && !empty($vetor[17])) { // TextShadow
  14109.                 $this->textshadow $vetor[17];
  14110.             }
  14111.             if (isset($vetor[16]) && !empty($vetor[16])) { // Border
  14112.                 $this->spanborddet $vetor[16];
  14113.                 $this->spanborder true;
  14114.             }
  14115.             if (isset($vetor[15])) {   // Word spacing
  14116.                 $this->wSpacingCSS $vetor[15];
  14117.                 if ($this->wSpacingCSS && strtoupper($this->wSpacingCSS) != 'NORMAL') {
  14118.                     $this->minwSpacing $this->sizeConverter->convert($this->wSpacingCSS$this->FontSize) / $this->shrin_k// mPDF 5.7.3
  14119.                 }
  14120.             }
  14121.             if (isset($vetor[14])) {   // Letter spacing
  14122.                 $this->lSpacingCSS $vetor[14];
  14123.                 if (($this->lSpacingCSS || $this->lSpacingCSS === '0') && strtoupper($this->lSpacingCSS) != 'NORMAL') {
  14124.                     $this->fixedlSpacing $this->sizeConverter->convert($this->lSpacingCSS$this->FontSize) / $this->shrin_k// mPDF 5.7.3
  14125.                 }
  14126.             }
  14127.             if (isset($vetor[10]) and ! empty($vetor[10])) { // Background color
  14128.                 $this->spanbgcolorarray $vetor[10];
  14129.                 $this->spanbgcolor true;
  14130.             }
  14131.             if (isset($vetor[9]) and ! empty($vetor[9])) { // Text parameters - Outline + hyphens
  14132.                 $this->textparam $vetor[9];
  14133.                 $this->SetTextOutline($this->textparam);
  14134.                 // mPDF 5.7.3  inline text-decoration parameters
  14135.                 if ($is_table && $this->shrin_k) {
  14136.                     if (isset($this->textparam['text-baseline'])) {
  14137.                         $this->textparam['text-baseline'] /= $this->shrin_k;
  14138.                     }
  14139.                     if (isset($this->textparam['decoration-baseline'])) {
  14140.                         $this->textparam['decoration-baseline'] /= $this->shrin_k;
  14141.                     }
  14142.                     if (isset($this->textparam['decoration-fontsize'])) {
  14143.                         $this->textparam['decoration-fontsize'] /= $this->shrin_k;
  14144.                     }
  14145.                 }
  14146.             }
  14147.             if (isset($vetor[8])) {  // mPDF 5.7.1
  14148.                 $this->textvar $vetor[8];
  14149.             }
  14150.             if (isset($vetor[7]) and $vetor[7] != '') { // internal target: <a name="anyvalue">
  14151.                 $ily $this->y;
  14152.                 if ($this->table_rotate) {
  14153.                     $this->internallink[$vetor[7]] = ["Y" => $ily"PAGE" => $this->page"tbrot" => true];
  14154.                 } elseif ($this->kwt) {
  14155.                     $this->internallink[$vetor[7]] = ["Y" => $ily"PAGE" => $this->page"kwt" => true];
  14156.                 } elseif ($this->ColActive) {
  14157.                     $this->internallink[$vetor[7]] = ["Y" => $ily"PAGE" => $this->page"col" => $this->CurrCol];
  14158.                 } elseif (!$this->keep_block_together) {
  14159.                     $this->internallink[$vetor[7]] = ["Y" => $ily"PAGE" => $this->page];
  14160.                 }
  14161.                 if (empty($vetor[0])) { // Ignore empty text
  14162.                     // Check if it is the last element. If so then finish printing the block
  14163.                     if ($i == ($array_size 1)) {
  14164.                         $this->finishFlowingBlock(true);
  14165.                     } // true = END of flowing block
  14166.                     continue;
  14167.                 }
  14168.             }
  14169.             if (isset($vetor[5]) and $vetor[5] != '') {  // Language    // mPDF 6
  14170.                 $this->currentLang $vetor[5];
  14171.             }
  14172.             if (isset($vetor[4]) and $vetor[4] != '') {  // Font Family
  14173.                 $font $this->SetFont($vetor[4], $this->FontStyle0false);
  14174.             }
  14175.             if (!empty($vetor[3])) { // Font Color
  14176.                 $cor $vetor[3];
  14177.                 $this->SetTColor($cor);
  14178.             }
  14179.             if (isset($vetor[2]) and $vetor[2] != '') { // Bold,Italic styles
  14180.                 $this->SetStyles($vetor[2]);
  14181.             }
  14182.             if (isset($vetor[12]) and $vetor[12] != '') { // Requested Bold,Italic
  14183.                 $this->ReqFontStyle $vetor[12];
  14184.             }
  14185.             if (isset($vetor[1]) and $vetor[1] != '') { // LINK
  14186.                 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.)
  14187.                     // Repeated reference to same anchor?
  14188.                     while (array_key_exists($vetor[1], $this->internallink)) {
  14189.                         $vetor[1] = "#" $vetor[1];
  14190.                     }
  14191.                     $this->internallink[$vetor[1]] = $this->AddLink();
  14192.                     $vetor[1] = $this->internallink[$vetor[1]];
  14193.                 }
  14194.                 $this->HREF $vetor[1];     // HREF link style set here ******
  14195.             }
  14196.             // SPECIAL CONTENT - IMAGES & FORM OBJECTS
  14197.             // Print-out special content
  14198.             if (substr($vetor[0], 03) == Mpdf::OBJECT_IDENTIFIER) { // identifier has been identified!
  14199.                 $objattr $this->_getObjAttr($vetor[0]);
  14200.                 /* -- TABLES -- */
  14201.                 if ($objattr['type'] == 'nestedtable') {
  14202.                     if ($objattr['nestedcontent']) {
  14203.                         $level $objattr['level'];
  14204.                         $table = &$this->table[$level][$objattr['table']];
  14205.                         if ($table_draft) {
  14206.                             $this->+= $this->table[($level 1)][$objattr['nestedcontent']]['h']; // nested table height
  14207.                             $this->finishFlowingBlock(false'nestedtable');
  14208.                         } else {
  14209.                             $cell = &$table['cells'][$objattr['row']][$objattr['col']];
  14210.                             $this->finishFlowingBlock(false'nestedtable');
  14211.                             $save_dw $this->divwidth;
  14212.                             $save_buffer $this->cellBorderBuffer;
  14213.                             $this->cellBorderBuffer = [];
  14214.                             $ncx $this->x;
  14215.                             list($dummyx$w) = $this->_tableGetWidth($table$objattr['row'], $objattr['col']);
  14216.                             $ntw $this->table[($level 1)][$objattr['nestedcontent']]['w']; // nested table width
  14217.                             if (!$this->simpleTables) {
  14218.                                 if ($this->packTableData) {
  14219.                                     list($bt$br$bb$bl) = $this->_getBorderWidths($cell['borderbin']);
  14220.                                 } else {
  14221.                                     $br $cell['border_details']['R']['w'];
  14222.                                     $bl $cell['border_details']['L']['w'];
  14223.                                 }
  14224.                                 if ($table['borders_separate']) {
  14225.                                     $innerw $w $bl $br $cell['padding']['L'] - $cell['padding']['R'] - $table['border_spacing_H'];
  14226.                                 } else {
  14227.                                     $innerw $w $bl $br $cell['padding']['L'] - $cell['padding']['R'];
  14228.                                 }
  14229.                             } elseif ($this->simpleTables) {
  14230.                                 if ($table['borders_separate']) {
  14231.                                     $innerw $w $table['simple']['border_details']['L']['w'] - $table['simple']['border_details']['R']['w'] - $cell['padding']['L'] - $cell['padding']['R'] - $table['border_spacing_H'];
  14232.                                 } else {
  14233.                                     $innerw $w $table['simple']['border_details']['L']['w'] / $table['simple']['border_details']['R']['w'] / $cell['padding']['L'] - $cell['padding']['R'];
  14234.                                 }
  14235.                             }
  14236.                             if ($cell['a'] == 'C' || $this->table[($level 1)][$objattr['nestedcontent']]['a'] == 'C') {
  14237.                                 $ncx += ($innerw $ntw) / 2;
  14238.                             } elseif ($cell['a'] == 'R' || $this->table[($level 1)][$objattr['nestedcontent']]['a'] == 'R') {
  14239.                                 $ncx += $innerw $ntw;
  14240.                             }
  14241.                             $this->$ncx;
  14242.                             $this->_tableWrite($this->table[($level 1)][$objattr['nestedcontent']]);
  14243.                             $this->cellBorderBuffer $save_buffer;
  14244.                             $this->$bak_x;
  14245.                             $this->divwidth $save_dw;
  14246.                         }
  14247.                         $this->newFlowingBlock($this->divwidth$this->divheight$align$is_table$blockstatefalse$blockdir$table_draft);
  14248.                     }
  14249.                 } else {
  14250.                     /* -- END TABLES -- */
  14251.                     if ($is_table) { // *TABLES*
  14252.                         $maxWidth $this->divwidth;  // *TABLES*
  14253.                     // *TABLES*
  14254.                     else { // *TABLES*
  14255.                         $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']);
  14256.                     } // *TABLES*
  14257.                     /* -- CSS-IMAGE-FLOAT -- */
  14258.                     // If float (already) exists at this level
  14259.                     if (isset($this->floatmargins['R']) && $this-><= $this->floatmargins['R']['y1'] && $this->>= $this->floatmargins['R']['y0']) {
  14260.                         $maxWidth -= $this->floatmargins['R']['w'];
  14261.                     }
  14262.                     if (isset($this->floatmargins['L']) && $this-><= $this->floatmargins['L']['y1'] && $this->>= $this->floatmargins['L']['y0']) {
  14263.                         $maxWidth -= $this->floatmargins['L']['w'];
  14264.                     }
  14265.                     /* -- END CSS-IMAGE-FLOAT -- */
  14266.                     list($skipln) = $this->inlineObject($objattr['type'], ''$this->y$objattr$this->lMargin, ($this->flowingBlockAttr['contentWidth'] / Mpdf::SCALE), $maxWidth$this->flowingBlockAttr['height'], false$is_table);
  14267.                     //  1 -> New line needed because of width
  14268.                     // -1 -> Will fit width on line but NEW PAGE REQUIRED because of height
  14269.                     // -2 -> Will not fit on line therefore needs new line but thus NEW PAGE REQUIRED
  14270.                     $iby $this->y;
  14271.                     $oldpage $this->page;
  14272.                     $oldcol $this->CurrCol;
  14273.                     if (($skipln == || $skipln == -2) && !isset($objattr['float'])) {
  14274.                         $this->finishFlowingBlock(false$objattr['type']);
  14275.                         $this->newFlowingBlock($this->divwidth$this->divheight$align$is_table$blockstatefalse$blockdir$table_draft);
  14276.                     }
  14277.                     if (!$table_draft) {
  14278.                         $thispage $this->page;
  14279.                         if ($this->CurrCol != $oldcol) {
  14280.                             $changedcol true;
  14281.                         } else {
  14282.                             $changedcol false;
  14283.                         }
  14284.                         // the previous lines can already have triggered page break or column change
  14285.                         if (!$changedcol && $skipln && $this->AcceptPageBreak() && $thispage == $oldpage) {
  14286.                             $this->AddPage($this->CurOrientation);
  14287.                             // Added to correct Images already set on line before page advanced
  14288.                             // i.e. if second inline image on line is higher than first and forces new page
  14289.                             if (count($this->objectbuffer)) {
  14290.                                 $yadj $iby $this->y;
  14291.                                 foreach ($this->objectbuffer as $ib => $val) {
  14292.                                     if ($this->objectbuffer[$ib]['OUTER-Y']) {
  14293.                                         $this->objectbuffer[$ib]['OUTER-Y'] -= $yadj;
  14294.                                     }
  14295.                                     if ($this->objectbuffer[$ib]['BORDER-Y']) {
  14296.                                         $this->objectbuffer[$ib]['BORDER-Y'] -= $yadj;
  14297.                                     }
  14298.                                     if ($this->objectbuffer[$ib]['INNER-Y']) {
  14299.                                         $this->objectbuffer[$ib]['INNER-Y'] -= $yadj;
  14300.                                     }
  14301.                                 }
  14302.                             }
  14303.                         }
  14304.                         // Added to correct for OddEven Margins
  14305.                         if ($this->page != $oldpage) {
  14306.                             if (($this->page $oldpage) % == 1) {
  14307.                                 $bak_x += $this->MarginCorrection;
  14308.                             }
  14309.                             $oldpage $this->page;
  14310.                             $y $this->tMargin $paint_ht_corr;
  14311.                             $this->oldy $this->tMargin $paint_ht_corr;
  14312.                             $old_height 0;
  14313.                         }
  14314.                         $this->$bak_x;
  14315.                         /* -- COLUMNS -- */
  14316.                         // COLS
  14317.                         // OR COLUMN CHANGE
  14318.                         if ($this->CurrCol != $oldcolumn) {
  14319.                             if ($this->directionality == 'rtl') { // *OTL*
  14320.                                 $bak_x -= ($this->CurrCol $oldcolumn) * ($this->ColWidth $this->ColGap); // *OTL*
  14321.                             // *OTL*
  14322.                             else { // *OTL*
  14323.                                 $bak_x += ($this->CurrCol $oldcolumn) * ($this->ColWidth $this->ColGap);
  14324.                             } // *OTL*
  14325.                             $this->$bak_x;
  14326.                             $oldcolumn $this->CurrCol;
  14327.                             $y $this->y0 $paint_ht_corr;
  14328.                             $this->oldy $this->y0 $paint_ht_corr;
  14329.                             $old_height 0;
  14330.                         }
  14331.                         /* -- END COLUMNS -- */
  14332.                     }
  14333.                     /* -- CSS-IMAGE-FLOAT -- */
  14334.                     if ($objattr['type'] == 'image' && isset($objattr['float'])) {
  14335.                         $fy $this->y;
  14336.                         // DIV TOP MARGIN/BORDER/PADDING
  14337.                         if ($this->flowingBlockAttr['newblock'] && ($this->flowingBlockAttr['blockstate'] == || $this->flowingBlockAttr['blockstate'] == 3) && $this->flowingBlockAttr['lineCount'] == 0) {
  14338.                             $fy += $this->blk[$this->blklvl]['margin_top'] + $this->blk[$this->blklvl]['padding_top'] + $this->blk[$this->blklvl]['border_top']['w'];
  14339.                         }
  14340.                         if ($objattr['float'] == 'R') {
  14341.                             $fx $this->$this->rMargin $objattr['width'] - ($this->blk[$this->blklvl]['outer_right_margin'] + $this->blk[$this->blklvl]['border_right']['w'] + $this->blk[$this->blklvl]['padding_right']);
  14342.                         } elseif ($objattr['float'] == 'L') {
  14343.                             $fx $this->lMargin + ($this->blk[$this->blklvl]['outer_left_margin'] + $this->blk[$this->blklvl]['border_left']['w'] + $this->blk[$this->blklvl]['padding_left']);
  14344.                         }
  14345.                         $w $objattr['width'];
  14346.                         $h abs($objattr['height']);
  14347.                         $widthLeft $maxWidth - ($this->flowingBlockAttr['contentWidth'] / Mpdf::SCALE);
  14348.                         $maxHeight $this->- ($this->tMargin $this->margin_header $this->bMargin 10);
  14349.                         // For Images
  14350.                         $extraWidth = ($objattr['border_left']['w'] + $objattr['border_right']['w'] + $objattr['margin_left'] + $objattr['margin_right']);
  14351.                         $extraHeight = ($objattr['border_top']['w'] + $objattr['border_bottom']['w'] + $objattr['margin_top'] + $objattr['margin_bottom']);
  14352.                         if ($objattr['itype'] == 'wmf' || $objattr['itype'] == 'svg') {
  14353.                             $file $objattr['file'];
  14354.                             $info $this->formobjects[$file];
  14355.                         } else {
  14356.                             $file $objattr['file'];
  14357.                             $info $this->images[$file];
  14358.                         }
  14359.                         $img_w $w $extraWidth;
  14360.                         $img_h $h $extraHeight;
  14361.                         if ($objattr['border_left']['w']) {
  14362.                             $objattr['BORDER-WIDTH'] = $img_w + (($objattr['border_left']['w'] + $objattr['border_right']['w']) / 2);
  14363.                             $objattr['BORDER-HEIGHT'] = $img_h + (($objattr['border_top']['w'] + $objattr['border_bottom']['w']) / 2);
  14364.                             $objattr['BORDER-X'] = $fx $objattr['margin_left'] + (($objattr['border_left']['w']) / 2);
  14365.                             $objattr['BORDER-Y'] = $fy $objattr['margin_top'] + (($objattr['border_top']['w']) / 2);
  14366.                         }
  14367.                         $objattr['INNER-WIDTH'] = $img_w;
  14368.                         $objattr['INNER-HEIGHT'] = $img_h;
  14369.                         $objattr['INNER-X'] = $fx $objattr['margin_left'] + ($objattr['border_left']['w']);
  14370.                         $objattr['INNER-Y'] = $fy $objattr['margin_top'] + ($objattr['border_top']['w']);
  14371.                         $objattr['ID'] = $info['i'];
  14372.                         $objattr['OUTER-WIDTH'] = $w;
  14373.                         $objattr['OUTER-HEIGHT'] = $h;
  14374.                         $objattr['OUTER-X'] = $fx;
  14375.                         $objattr['OUTER-Y'] = $fy;
  14376.                         if ($objattr['float'] == 'R') {
  14377.                             // If R float already exists at this level
  14378.                             $this->floatmargins['R']['skipline'] = false;
  14379.                             if (isset($this->floatmargins['R']['y1']) && $this->floatmargins['R']['y1'] > && $fy $this->floatmargins['R']['y1']) {
  14380.                                 $this->WriteFlowingBlock($vetor[0], $vetor[18]);  // mPDF 5.7.1
  14381.                             // If L float already exists at this level
  14382.                             elseif (isset($this->floatmargins['L']['y1']) && $this->floatmargins['L']['y1'] > && $fy $this->floatmargins['L']['y1']) {
  14383.                                 // Final check distance between floats is not now too narrow to fit text
  14384.                                 $mw $this->GetCharWidth('W'false);
  14385.                                 if (($this->blk[$this->blklvl]['inner_width'] - $w $this->floatmargins['L']['w']) < $mw) {
  14386.                                     $this->WriteFlowingBlock($vetor[0], $vetor[18]);  // mPDF 5.7.1
  14387.                                 } else {
  14388.                                     $this->floatmargins['R']['x'] = $fx;
  14389.                                     $this->floatmargins['R']['w'] = $w;
  14390.                                     $this->floatmargins['R']['y0'] = $fy;
  14391.                                     $this->floatmargins['R']['y1'] = $fy $h;
  14392.                                     if ($skipln == 1) {
  14393.                                         $this->floatmargins['R']['skipline'] = true;
  14394.                                         $this->floatmargins['R']['id'] = count($this->floatbuffer) + 0;
  14395.                                         $objattr['skipline'] = true;
  14396.                                     }
  14397.                                     $this->floatbuffer[] = $objattr;
  14398.                                 }
  14399.                             } else {
  14400.                                 $this->floatmargins['R']['x'] = $fx;
  14401.                                 $this->floatmargins['R']['w'] = $w;
  14402.                                 $this->floatmargins['R']['y0'] = $fy;
  14403.                                 $this->floatmargins['R']['y1'] = $fy $h;
  14404.                                 if ($skipln == 1) {
  14405.                                     $this->floatmargins['R']['skipline'] = true;
  14406.                                     $this->floatmargins['R']['id'] = count($this->floatbuffer) + 0;
  14407.                                     $objattr['skipline'] = true;
  14408.                                 }
  14409.                                 $this->floatbuffer[] = $objattr;
  14410.                             }
  14411.                         } elseif ($objattr['float'] == 'L') {
  14412.                             // If L float already exists at this level
  14413.                             $this->floatmargins['L']['skipline'] = false;
  14414.                             if (isset($this->floatmargins['L']['y1']) && $this->floatmargins['L']['y1'] > && $fy $this->floatmargins['L']['y1']) {
  14415.                                 $this->floatmargins['L']['skipline'] = false;
  14416.                                 $this->WriteFlowingBlock($vetor[0], $vetor[18]);  // mPDF 5.7.1
  14417.                             // If R float already exists at this level
  14418.                             elseif (isset($this->floatmargins['R']['y1']) && $this->floatmargins['R']['y1'] > && $fy $this->floatmargins['R']['y1']) {
  14419.                                 // Final check distance between floats is not now too narrow to fit text
  14420.                                 $mw $this->GetCharWidth('W'false);
  14421.                                 if (($this->blk[$this->blklvl]['inner_width'] - $w $this->floatmargins['R']['w']) < $mw) {
  14422.                                     $this->WriteFlowingBlock($vetor[0], $vetor[18]);  // mPDF 5.7.1
  14423.                                 } else {
  14424.                                     $this->floatmargins['L']['x'] = $fx $w;
  14425.                                     $this->floatmargins['L']['w'] = $w;
  14426.                                     $this->floatmargins['L']['y0'] = $fy;
  14427.                                     $this->floatmargins['L']['y1'] = $fy $h;
  14428.                                     if ($skipln == 1) {
  14429.                                         $this->floatmargins['L']['skipline'] = true;
  14430.                                         $this->floatmargins['L']['id'] = count($this->floatbuffer) + 0;
  14431.                                         $objattr['skipline'] = true;
  14432.                                     }
  14433.                                     $this->floatbuffer[] = $objattr;
  14434.                                 }
  14435.                             } else {
  14436.                                 $this->floatmargins['L']['x'] = $fx $w;
  14437.                                 $this->floatmargins['L']['w'] = $w;
  14438.                                 $this->floatmargins['L']['y0'] = $fy;
  14439.                                 $this->floatmargins['L']['y1'] = $fy $h;
  14440.                                 if ($skipln == 1) {
  14441.                                     $this->floatmargins['L']['skipline'] = true;
  14442.                                     $this->floatmargins['L']['id'] = count($this->floatbuffer) + 0;
  14443.                                     $objattr['skipline'] = true;
  14444.                                 }
  14445.                                 $this->floatbuffer[] = $objattr;
  14446.                             }
  14447.                         }
  14448.                     } else {
  14449.                         /* -- END CSS-IMAGE-FLOAT -- */
  14450.                         $this->WriteFlowingBlock($vetor[0], (isset($vetor[18]) ? $vetor[18] : null));  // mPDF 5.7.1
  14451.                         /* -- CSS-IMAGE-FLOAT -- */
  14452.                     }
  14453.                     /* -- END CSS-IMAGE-FLOAT -- */
  14454.                 // *TABLES*
  14455.             // END If special content
  14456.             else { // THE text
  14457.                 if ($this->tableLevel) {
  14458.                     $paint_ht_corr 0;
  14459.                 } // To move the y up when new column/page started if div border needed
  14460.                 else {
  14461.                     $paint_ht_corr $this->blk[$this->blklvl]['border_top']['w'];
  14462.                 }
  14463.                 if ($vetor[0] == "\n") { // We are reading a <BR> now turned into newline ("\n")
  14464.                     if ($this->flowingBlockAttr['content']) {
  14465.                         $this->finishFlowingBlock(false'br');
  14466.                     } elseif ($is_table) {
  14467.                         $this->y+= $this->_computeLineheight($this->cellLineHeight);
  14468.                     } elseif (!$is_table) {
  14469.                         $this->DivLn($this->lineheight);
  14470.                         if ($this->ColActive) {
  14471.                             $this->breakpoints[$this->CurrCol][] = $this->y;
  14472.                         } // *COLUMNS*
  14473.                     }
  14474.                     // Added to correct for OddEven Margins
  14475.                     if ($this->page != $oldpage) {
  14476.                         if (($this->page $oldpage) % == 1) {
  14477.                             $bak_x += $this->MarginCorrection;
  14478.                         }
  14479.                         $oldpage $this->page;
  14480.                         $y $this->tMargin $paint_ht_corr;
  14481.                         $this->oldy $this->tMargin $paint_ht_corr;
  14482.                         $old_height 0;
  14483.                     }
  14484.                     $this->$bak_x;
  14485.                     /* -- COLUMNS -- */
  14486.                     // COLS
  14487.                     // OR COLUMN CHANGE
  14488.                     if ($this->CurrCol != $oldcolumn) {
  14489.                         if ($this->directionality == 'rtl') { // *OTL*
  14490.                             $bak_x -= ($this->CurrCol $oldcolumn) * ($this->ColWidth $this->ColGap); // *OTL*
  14491.                         // *OTL*
  14492.                         else { // *OTL*
  14493.                             $bak_x += ($this->CurrCol $oldcolumn) * ($this->ColWidth $this->ColGap);
  14494.                         } // *OTL*
  14495.                         $this->$bak_x;
  14496.                         $oldcolumn $this->CurrCol;
  14497.                         $y $this->y0 $paint_ht_corr;
  14498.                         $this->oldy $this->y0 $paint_ht_corr;
  14499.                         $old_height 0;
  14500.                     }
  14501.                     /* -- END COLUMNS -- */
  14502.                     $this->newFlowingBlock($this->divwidth$this->divheight$align$is_table$blockstatefalse$blockdir$table_draft);
  14503.                 } else {
  14504.                     $this->WriteFlowingBlock($vetor[0], $vetor[18]);  // mPDF 5.7.1
  14505.                     // Added to correct for OddEven Margins
  14506.                     if ($this->page != $oldpage) {
  14507.                         if (($this->page $oldpage) % == 1) {
  14508.                             $bak_x += $this->MarginCorrection;
  14509.                             $this->$bak_x;
  14510.                         }
  14511.                         $oldpage $this->page;
  14512.                         $y $this->tMargin $paint_ht_corr;
  14513.                         $this->oldy $this->tMargin $paint_ht_corr;
  14514.                         $old_height 0;
  14515.                     }
  14516.                     /* -- COLUMNS -- */
  14517.                     // COLS
  14518.                     // OR COLUMN CHANGE
  14519.                     if ($this->CurrCol != $oldcolumn) {
  14520.                         if ($this->directionality == 'rtl') { // *OTL*
  14521.                             $bak_x -= ($this->CurrCol $oldcolumn) * ($this->ColWidth $this->ColGap); // *OTL*
  14522.                         // *OTL*
  14523.                         else { // *OTL*
  14524.                             $bak_x += ($this->CurrCol $oldcolumn) * ($this->ColWidth $this->ColGap);
  14525.                         } // *OTL*
  14526.                         $this->$bak_x;
  14527.                         $oldcolumn $this->CurrCol;
  14528.                         $y $this->y0 $paint_ht_corr;
  14529.                         $this->oldy $this->y0 $paint_ht_corr;
  14530.                         $old_height 0;
  14531.                     }
  14532.                     /* -- END COLUMNS -- */
  14533.                 }
  14534.             }
  14535.             // Check if it is the last element. If so then finish printing the block
  14536.             if ($i == ($array_size 1)) {
  14537.                 $this->finishFlowingBlock(true); // true = END of flowing block
  14538.                 // Added to correct for OddEven Margins
  14539.                 if ($this->page != $oldpage) {
  14540.                     if (($this->page $oldpage) % == 1) {
  14541.                         $bak_x += $this->MarginCorrection;
  14542.                         $this->$bak_x;
  14543.                     }
  14544.                     $oldpage $this->page;
  14545.                     $y $this->tMargin $paint_ht_corr;
  14546.                     $this->oldy $this->tMargin $paint_ht_corr;
  14547.                     $old_height 0;
  14548.                 }
  14549.                 /* -- COLUMNS -- */
  14550.                 // COLS
  14551.                 // OR COLUMN CHANGE
  14552.                 if ($this->CurrCol != $oldcolumn) {
  14553.                     if ($this->directionality == 'rtl') { // *OTL*
  14554.                         $bak_x -= ($this->CurrCol $oldcolumn) * ($this->ColWidth $this->ColGap); // *OTL*
  14555.                     // *OTL*
  14556.                     else { // *OTL*
  14557.                         $bak_x += ($this->CurrCol $oldcolumn) * ($this->ColWidth $this->ColGap);
  14558.                     } // *OTL*
  14559.                     $this->$bak_x;
  14560.                     $oldcolumn $this->CurrCol;
  14561.                     $y $this->y0 $paint_ht_corr;
  14562.                     $this->oldy $this->y0 $paint_ht_corr;
  14563.                     $old_height 0;
  14564.                 }
  14565.                 /* -- END COLUMNS -- */
  14566.             }
  14567.             // RESETTING VALUES
  14568.             $this->SetTColor($this->colorConverter->convert(0$this->PDFAXwarnings));
  14569.             $this->SetDColor($this->colorConverter->convert(0$this->PDFAXwarnings));
  14570.             $this->SetFColor($this->colorConverter->convert(255$this->PDFAXwarnings));
  14571.             $this->colorarray '';
  14572.             $this->spanbgcolorarray '';
  14573.             $this->spanbgcolor false;
  14574.             $this->spanborder false;
  14575.             $this->spanborddet = [];
  14576.             $this->HREF '';
  14577.             $this->textparam = [];
  14578.             $this->SetTextOutline();
  14579.             $this->textvar 0x00// mPDF 5.7.1
  14580.             $this->OTLtags = [];
  14581.             $this->textshadow '';
  14582.             $this->currentfontfamily '';
  14583.             $this->currentfontsize '';
  14584.             $this->currentfontstyle '';
  14585.             $this->currentLang $this->default_lang;  // mPDF 6
  14586.             $this->RestrictUnicodeFonts($this->default_available_fonts); // mPDF 6
  14587.             /* -- TABLES -- */
  14588.             if ($this->tableLevel) {
  14589.                 $this->SetLineHeight(''$this->table[1][1]['cellLineHeight']); // *TABLES*
  14590.             } else {             /* -- END TABLES -- */
  14591.                 if (isset($this->blk[$this->blklvl]['line_height']) && $this->blk[$this->blklvl]['line_height']) {
  14592.                     $this->SetLineHeight(''$this->blk[$this->blklvl]['line_height']); // sets default line height
  14593.                 }
  14594.             }
  14595.             $this->ResetStyles();
  14596.             $this->lSpacingCSS '';
  14597.             $this->wSpacingCSS '';
  14598.             $this->fixedlSpacing false;
  14599.             $this->minwSpacing 0;
  14600.             $this->SetDash();
  14601.             $this->dash_on false;
  14602.             $this->dotted_on false;
  14603.         }//end of for(i=0;i<arraysize;i++)
  14604.         $this->Reset(); // mPDF 6
  14605.         // PAINT DIV BORDER    // DISABLED IN COLUMNS AS DOESN'T WORK WHEN BROKEN ACROSS COLS??
  14606.         if ((isset($this->blk[$this->blklvl]['border']) || isset($this->blk[$this->blklvl]['bgcolor']) || isset($this->blk[$this->blklvl]['box_shadow'])) && $blockstate && ($this->!= $this->oldy)) {
  14607.             $bottom_y $this->y// Does not include Bottom Margin
  14608.             if (isset($this->blk[$this->blklvl]['startpage']) && $this->blk[$this->blklvl]['startpage'] != $this->page && $blockstate != 1) {
  14609.                 $this->PaintDivBB('pagetop'$blockstate);
  14610.             } elseif ($blockstate != 1) {
  14611.                 $this->PaintDivBB(''$blockstate);
  14612.             }
  14613.             $this->$bottom_y;
  14614.             $this->$bak_x;
  14615.         }
  14616.         // Reset Font
  14617.         $this->SetFontSize($this->default_font_sizefalse);
  14618.         if ($table_draft) {
  14619.             $ch $this->$bak_y;
  14620.             $this->$bak_y;
  14621.             $this->$bak_x;
  14622.             return $ch;
  14623.         }
  14624.     }
  14625.     function _setDashBorder($style$div$cp$side)
  14626.     {
  14627.         if ($style == 'dashed' && (($side == 'L' || $side == 'R') || ($side == 'T' && $div != 'pagetop' && !$cp) || ($side == 'B' && $div != 'pagebottom') )) {
  14628.             $dashsize 2// final dash will be this + 1*linewidth
  14629.             $dashsizek 1.5// ratio of Dash/Blank
  14630.             $this->SetDash($dashsize, ($dashsize $dashsizek) + ($this->LineWidth 2));
  14631.         } elseif ($style == 'dotted' || ($side == 'T' && ($div == 'pagetop' || $cp)) || ($side == 'B' && $div == 'pagebottom')) {
  14632.             // Round join and cap
  14633.             $this->SetLineJoin(1);
  14634.             $this->SetLineCap(1);
  14635.             $this->SetDash(0.001, ($this->LineWidth 3));
  14636.         }
  14637.     }
  14638.     function _setBorderLine($b$k 1)
  14639.     {
  14640.         $this->SetLineWidth($b['w'] / $k);
  14641.         $this->SetDColor($b['c']);
  14642.         if ($b['c'][0] == 5) { // RGBa
  14643.             $this->SetAlpha(ord($b['c'][4]) / 100'Normal'false'S'); // mPDF 5.7.2
  14644.         } elseif ($b['c'][0] == 6) { // CMYKa
  14645.             $this->SetAlpha(ord($b['c'][5]) / 100'Normal'false'S'); // mPDF 5.7.2
  14646.         }
  14647.     }
  14648.     function PaintDivBB($divider ''$blockstate 0$blvl 0)
  14649.     {
  14650.         // Borders & backgrounds are done elsewhere for columns - messes up the repositioning in printcolumnbuffer
  14651.         if ($this->ColActive) {
  14652.             return;
  14653.         } // *COLUMNS*
  14654.         if ($this->keep_block_together) {
  14655.             return;
  14656.         } // mPDF 6
  14657.         $save_y $this->y;
  14658.         if (!$blvl) {
  14659.             $blvl $this->blklvl;
  14660.         }
  14661.         $x0 $x1 $y0 $y1 0;
  14662.         // Added mPDF 3.0 Float DIV
  14663.         if (isset($this->blk[$blvl]['bb_painted'][$this->page]) && $this->blk[$blvl]['bb_painted'][$this->page]) {
  14664.             return;
  14665.         } // *CSS-FLOAT*
  14666.         if (isset($this->blk[$blvl]['x0'])) {
  14667.             $x0 $this->blk[$blvl]['x0'];
  14668.         } // left
  14669.         if (isset($this->blk[$blvl]['y1'])) {
  14670.             $y1 $this->blk[$blvl]['y1'];
  14671.         } // bottom
  14672.         // Added mPDF 3.0 Float DIV - ensures backgrounds/borders are drawn to bottom of page
  14673.         if ($y1 == 0) {
  14674.             if ($divider == 'pagebottom') {
  14675.                 $y1 $this->$this->bMargin;
  14676.             } else {
  14677.                 $y1 $this->y;
  14678.             }
  14679.         }
  14680.         $continuingpage = (isset($this->blk[$blvl]['startpage']) && $this->blk[$blvl]['startpage'] != $this->page);
  14681.         if (isset($this->blk[$blvl]['y0'])) {
  14682.             $y0 $this->blk[$blvl]['y0'];
  14683.         }
  14684.         $h $y1 $y0;
  14685.         $w $this->blk[$blvl]['width'];
  14686.         $x1 $x0 $w;
  14687.         // Set border-widths as used here
  14688.         $border_top $this->blk[$blvl]['border_top']['w'];
  14689.         $border_bottom $this->blk[$blvl]['border_bottom']['w'];
  14690.         $border_left $this->blk[$blvl]['border_left']['w'];
  14691.         $border_right $this->blk[$blvl]['border_right']['w'];
  14692.         if (!$this->blk[$blvl]['border_top'] || $divider == 'pagetop' || $continuingpage) {
  14693.             $border_top 0;
  14694.         }
  14695.         if (!$this->blk[$blvl]['border_bottom'] || $blockstate == || $divider == 'pagebottom') {
  14696.             $border_bottom 0;
  14697.         }
  14698.         $brTL_H 0;
  14699.         $brTL_V 0;
  14700.         $brTR_H 0;
  14701.         $brTR_V 0;
  14702.         $brBL_H 0;
  14703.         $brBL_V 0;
  14704.         $brBR_H 0;
  14705.         $brBR_V 0;
  14706.         $brset false;
  14707.         /* -- BORDER-RADIUS -- */
  14708.         if (isset($this->blk[$blvl]['border_radius_TL_H'])) {
  14709.             $brTL_H $this->blk[$blvl]['border_radius_TL_H'];
  14710.             $brset true;
  14711.         }
  14712.         if (isset($this->blk[$blvl]['border_radius_TL_V'])) {
  14713.             $brTL_V $this->blk[$blvl]['border_radius_TL_V'];
  14714.             $brset true;
  14715.         }
  14716.         if (isset($this->blk[$blvl]['border_radius_TR_H'])) {
  14717.             $brTR_H $this->blk[$blvl]['border_radius_TR_H'];
  14718.             $brset true;
  14719.         }
  14720.         if (isset($this->blk[$blvl]['border_radius_TR_V'])) {
  14721.             $brTR_V $this->blk[$blvl]['border_radius_TR_V'];
  14722.             $brset true;
  14723.         }
  14724.         if (isset($this->blk[$blvl]['border_radius_BR_H'])) {
  14725.             $brBR_H $this->blk[$blvl]['border_radius_BR_H'];
  14726.             $brset true;
  14727.         }
  14728.         if (isset($this->blk[$blvl]['border_radius_BR_V'])) {
  14729.             $brBR_V $this->blk[$blvl]['border_radius_BR_V'];
  14730.             $brset true;
  14731.         }
  14732.         if (isset($this->blk[$blvl]['border_radius_BL_H'])) {
  14733.             $brBL_H $this->blk[$blvl]['border_radius_BL_H'];
  14734.             $brset true;
  14735.         }
  14736.         if (isset($this->blk[$blvl]['border_radius_BL_V'])) {
  14737.             $brBL_V $this->blk[$blvl]['border_radius_BL_V'];
  14738.             $brset true;
  14739.         }
  14740.         if (!$this->blk[$blvl]['border_top'] || $divider == 'pagetop' || $continuingpage) {
  14741.             $brTL_H 0;
  14742.             $brTL_V 0;
  14743.             $brTR_H 0;
  14744.             $brTR_V 0;
  14745.         }
  14746.         if (!$this->blk[$blvl]['border_bottom'] || $blockstate == || $divider == 'pagebottom') {
  14747.             $brBL_H 0;
  14748.             $brBL_V 0;
  14749.             $brBR_H 0;
  14750.             $brBR_V 0;
  14751.         }
  14752.         // Disallow border-radius if it is smaller than the border width.
  14753.         if ($brTL_H min($border_left$border_top)) {
  14754.             $brTL_H $brTL_V 0;
  14755.         }
  14756.         if ($brTL_V min($border_left$border_top)) {
  14757.             $brTL_V $brTL_H 0;
  14758.         }
  14759.         if ($brTR_H min($border_right$border_top)) {
  14760.             $brTR_H $brTR_V 0;
  14761.         }
  14762.         if ($brTR_V min($border_right$border_top)) {
  14763.             $brTR_V $brTR_H 0;
  14764.         }
  14765.         if ($brBL_H min($border_left$border_bottom)) {
  14766.             $brBL_H $brBL_V 0;
  14767.         }
  14768.         if ($brBL_V min($border_left$border_bottom)) {
  14769.             $brBL_V $brBL_H 0;
  14770.         }
  14771.         if ($brBR_H min($border_right$border_bottom)) {
  14772.             $brBR_H $brBR_V 0;
  14773.         }
  14774.         if ($brBR_V min($border_right$border_bottom)) {
  14775.             $brBR_V $brBR_H 0;
  14776.         }
  14777.         // CHECK FOR radii that sum to > width or height of div ********
  14778.         $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));
  14779.         if ($f 1) {
  14780.             $brTL_H *= $f;
  14781.             $brTL_V *= $f;
  14782.             $brTR_H *= $f;
  14783.             $brTR_V *= $f;
  14784.             $brBL_H *= $f;
  14785.             $brBL_V *= $f;
  14786.             $brBR_H *= $f;
  14787.             $brBR_V *= $f;
  14788.         }
  14789.         /* -- END BORDER-RADIUS -- */
  14790.         $tbcol $this->colorConverter->convert(255$this->PDFAXwarnings);
  14791.         for ($l 0$l <= $blvl$l++) {
  14792.             if ($this->blk[$l]['bgcolor']) {
  14793.                 $tbcol $this->blk[$l]['bgcolorarray'];
  14794.             }
  14795.         }
  14796.         // BORDERS
  14797.         if (isset($this->blk[$blvl]['y0']) && $this->blk[$blvl]['y0']) {
  14798.             $y0 $this->blk[$blvl]['y0'];
  14799.         }
  14800.         $h $y1 $y0;
  14801.         $w $this->blk[$blvl]['width'];
  14802.         if ($this->blk[$blvl]['border_top'] && $divider != 'pagetop' && !$continuingpage) {
  14803.             $tbd $this->blk[$blvl]['border_top'];
  14804.             $legend '';
  14805.             $legbreakL 0;
  14806.             $legbreakR 0;
  14807.             // BORDER LEGEND
  14808.             if (isset($this->blk[$blvl]['border_legend']) && $this->blk[$blvl]['border_legend']) {
  14809.                 $legend $this->blk[$blvl]['border_legend']; // Same structure array as textbuffer
  14810.                 $txt $legend[0] = ltrim($legend[0]);
  14811.                 if (!empty($legend[18])) {
  14812.                     $this->otl->trimOTLdata($legend[18], truefalse);
  14813.                 } // *OTL*
  14814.                 // Set font, size, style, color
  14815.                 $this->SetFont($legend[4], $legend[2], $legend[11]);
  14816.                 if (isset($legend[3]) && $legend[3]) {
  14817.                     $cor $legend[3];
  14818.                     $this->SetTColor($cor);
  14819.                 }
  14820.                 $stringWidth $this->GetStringWidth($txttrue$legend[18], $legend[8]);
  14821.                 $save_x $this->x;
  14822.                 $save_y $this->y;
  14823.                 $save_currentfontfamily $this->FontFamily;
  14824.                 $save_currentfontsize $this->FontSizePt;
  14825.                 $save_currentfontstyle $this->FontStyle;
  14826.                 $this->$y0 $this->FontSize $this->blk[$blvl]['border_top']['w'] / 2;
  14827.                 $this->$x0 $this->blk[$blvl]['padding_left'] + $this->blk[$blvl]['border_left']['w'];
  14828.                 // Set the distance from the border line to the text ? make configurable variable
  14829.                 $gap 0.2 $this->FontSize;
  14830.                 $legbreakL $this->$gap;
  14831.                 $legbreakR $this->$stringWidth $gap;
  14832.                 $this->magic_reverse_dir($txt$this->blk[$blvl]['direction'], $legend[18]);
  14833.                 $fill '';
  14834.                 $this->Cell($stringWidth$this->FontSize$txt''0'C'$fill''000'M'$fillfalse$legend[18], $legend[8]);
  14835.                 // Reset
  14836.                 $this->$save_x;
  14837.                 $this->$save_y;
  14838.                 $this->SetFont($save_currentfontfamily$save_currentfontstyle$save_currentfontsize);
  14839.                 $this->SetTColor($this->colorConverter->convert(0$this->PDFAXwarnings));
  14840.             }
  14841.             if (isset($tbd['s']) && $tbd['s']) {
  14842.                 if (!$brset && $tbd['style'] != 'dotted' && $tbd['style'] != 'dashed') {
  14843.                     $this->writer->write('q');
  14844.                     $this->SetLineWidth(0);
  14845.                     $this->writer->write(sprintf('%.3F %.3F m ', ($x0) * Mpdf::SCALE, ($this->- ($y0)) * Mpdf::SCALE));
  14846.                     $this->writer->write(sprintf('%.3F %.3F l ', ($x0 $border_left) * Mpdf::SCALE, ($this->- ($y0 $border_top)) * Mpdf::SCALE));
  14847.                     $this->writer->write(sprintf('%.3F %.3F l ', ($x0 $w $border_right) * Mpdf::SCALE, ($this->- ($y0 $border_top)) * Mpdf::SCALE));
  14848.                     $this->writer->write(sprintf('%.3F %.3F l ', ($x0 $w) * Mpdf::SCALE, ($this->- ($y0)) * Mpdf::SCALE));
  14849.                     $this->writer->write(' h W n '); // Ends path no-op & Sets the clipping path
  14850.                 }
  14851.                 $this->_setBorderLine($tbd);
  14852.                 if ($tbd['style'] == 'dotted' || $tbd['style'] == 'dashed') {
  14853.                     $legbreakL -= $border_top 2// because line cap different
  14854.                     $legbreakR += $border_top 2;
  14855.                     $this->_setDashBorder($tbd['style'], $divider$continuingpage'T');
  14856.                 } /* -- BORDER-RADIUS -- */ elseif (($brTL_V && $brTL_H) || ($brTR_V && $brTR_H) || $tbd['style'] == 'solid' || $tbd['style'] == 'double') {
  14857.                     $this->SetLineJoin(0);
  14858.                     $this->SetLineCap(0);
  14859.                 }
  14860.                 $s '';
  14861.                 if ($brTR_H && $brTR_V) {
  14862.                     $s .= ($this->_EllipseArc($x0 $w $brTR_H$y0 $brTR_V$brTR_H $border_top 2$brTR_V $border_top 212true)) . "\n";
  14863.                 } else {                 /* -- END BORDER-RADIUS -- */
  14864.                     if ($tbd['style'] == 'solid' || $tbd['style'] == 'double') {
  14865.                         $s .= (sprintf('%.3F %.3F m ', ($x0 $w) * Mpdf::SCALE, ($this->- ($y0 + ($border_top 2))) * Mpdf::SCALE)) . "\n";
  14866.                     } else {
  14867.                         $s .= (sprintf('%.3F %.3F m ', ($x0 $w - ($border_top 2)) * Mpdf::SCALE, ($this->- ($y0 + ($border_top 2))) * Mpdf::SCALE)) . "\n";
  14868.                     }
  14869.                 }
  14870.                 /* -- BORDER-RADIUS -- */
  14871.                 if ($brTL_H && $brTL_V) {
  14872.                     if ($legend) {
  14873.                         if ($legbreakR < ($x0 $w $brTR_H)) {
  14874.                             $s .= (sprintf('%.3F %.3F l '$legbreakR Mpdf::SCALE, ($this->- ($y0 + ($border_top 2))) * Mpdf::SCALE)) . "\n";
  14875.                         }
  14876.                         if ($legbreakL > ($x0 $brTL_H )) {
  14877.                             $s .= (sprintf('%.3F %.3F m '$legbreakL Mpdf::SCALE, ($this->- ($y0 + ($border_top 2))) * Mpdf::SCALE)) . "\n";
  14878.                             $s .= (sprintf('%.3F %.3F l ', ($x0 $brTL_H ) * Mpdf::SCALE, ($this->- ($y0 + ($border_top 2))) * Mpdf::SCALE) . "\n");
  14879.                         } else {
  14880.                             $s .= (sprintf('%.3F %.3F m ', ($x0 $brTL_H ) * Mpdf::SCALE, ($this->- ($y0 + ($border_top 2))) * Mpdf::SCALE)) . "\n";
  14881.                         }
  14882.                     } else {
  14883.                         $s .= (sprintf('%.3F %.3F l ', ($x0 $brTL_H ) * Mpdf::SCALE, ($this->- ($y0 + ($border_top 2))) * Mpdf::SCALE)) . "\n";
  14884.                     }
  14885.                     $s .= ($this->_EllipseArc($x0 $brTL_H$y0 $brTL_V$brTL_H $border_top 2$brTL_V $border_top 221)) . "\n";
  14886.                 } else {
  14887.                     /* -- END BORDER-RADIUS -- */
  14888.                     if ($legend) {
  14889.                         if ($legbreakR < ($x0 $w)) {
  14890.                             $s .= (sprintf('%.3F %.3F l '$legbreakR Mpdf::SCALE, ($this->- ($y0 + ($border_top 2))) * Mpdf::SCALE)) . "\n";
  14891.                         }
  14892.                         if ($legbreakL > ($x0)) {
  14893.                             $s .= (sprintf('%.3F %.3F m '$legbreakL Mpdf::SCALE, ($this->- ($y0 + ($border_top 2))) * Mpdf::SCALE)) . "\n";
  14894.                             if ($tbd['style'] == 'solid' || $tbd['style'] == 'double') {
  14895.                                 $s .= (sprintf('%.3F %.3F l ', ($x0) * Mpdf::SCALE, ($this->- ($y0 + ($border_top 2))) * Mpdf::SCALE)) . "\n";
  14896.                             } else {
  14897.                                 $s .= (sprintf('%.3F %.3F l ', ($x0 + ($border_top 2)) * Mpdf::SCALE, ($this->- ($y0 + ($border_top 2))) * Mpdf::SCALE)) . "\n";
  14898.                             }
  14899.                         } elseif ($tbd['style'] == 'solid' || $tbd['style'] == 'double') {
  14900.                             $s .= (sprintf('%.3F %.3F m ', ($x0) * Mpdf::SCALE, ($this->- ($y0 + ($border_top 2))) * Mpdf::SCALE)) . "\n";
  14901.                         } else {
  14902.                             $s .= (sprintf('%.3F %.3F m ', ($x0 $border_top 2) * Mpdf::SCALE, ($this->- ($y0 + ($border_top 2))) * Mpdf::SCALE)) . "\n";
  14903.                         }
  14904.                     } elseif ($tbd['style'] == 'solid' || $tbd['style'] == 'double') {
  14905.                         $s .= (sprintf('%.3F %.3F l ', ($x0) * Mpdf::SCALE, ($this->- ($y0 + ($border_top 2))) * Mpdf::SCALE)) . "\n";
  14906.                     } else {
  14907.                         $s .= (sprintf('%.3F %.3F l ', ($x0 + ($border_top 2)) * Mpdf::SCALE, ($this->- ($y0 + ($border_top 2))) * Mpdf::SCALE)) . "\n";
  14908.                     }
  14909.                     /* -- BORDER-RADIUS -- */
  14910.                 }
  14911.                 /* -- END BORDER-RADIUS -- */
  14912.                 $s .= 'S' "\n";
  14913.                 $this->writer->write($s);
  14914.                 if ($tbd['style'] == 'double') {
  14915.                     $this->SetLineWidth($tbd['w'] / 3);
  14916.                     $this->SetDColor($tbcol);
  14917.                     $this->writer->write($s);
  14918.                 }
  14919.                 if (!$brset && $tbd['style'] != 'dotted' && $tbd['style'] != 'dashed') {
  14920.                     $this->writer->write('Q');
  14921.                 }
  14922.                 // Reset Corners and Dash off
  14923.                 $this->SetLineWidth(0.1);
  14924.                 $this->SetDColor($this->colorConverter->convert(0$this->PDFAXwarnings));
  14925.                 $this->SetLineJoin(2);
  14926.                 $this->SetLineCap(2);
  14927.                 $this->SetDash();
  14928.             }
  14929.         }
  14930.         // Reinstate line above for dotted line divider when block border crosses a page
  14931.         // elseif ($divider == 'pagetop' || $continuingpage) {
  14932.         if ($this->blk[$blvl]['border_bottom'] && $blockstate != && $divider != 'pagebottom') {
  14933.             $tbd $this->blk[$blvl]['border_bottom'];
  14934.             if (isset($tbd['s']) && $tbd['s']) {
  14935.                 if (!$brset && $tbd['style'] != 'dotted' && $tbd['style'] != 'dashed') {
  14936.                     $this->writer->write('q');
  14937.                     $this->SetLineWidth(0);
  14938.                     $this->writer->write(sprintf('%.3F %.3F m ', ($x0) * Mpdf::SCALE, ($this->- ($y0 $h)) * Mpdf::SCALE));
  14939.                     $this->writer->write(sprintf('%.3F %.3F l ', ($x0 $border_left) * Mpdf::SCALE, ($this->- ($y0 $h $border_bottom)) * Mpdf::SCALE));
  14940.                     $this->writer->write(sprintf('%.3F %.3F l ', ($x0 $w $border_right) * Mpdf::SCALE, ($this->- ($y0 $h $border_bottom)) * Mpdf::SCALE));
  14941.                     $this->writer->write(sprintf('%.3F %.3F l ', ($x0 $w) * Mpdf::SCALE, ($this->- ($y0 $h)) * Mpdf::SCALE));
  14942.                     $this->writer->write(' h W n '); // Ends path no-op & Sets the clipping path
  14943.                 }
  14944.                 $this->_setBorderLine($tbd);
  14945.                 if ($tbd['style'] == 'dotted' || $tbd['style'] == 'dashed') {
  14946.                     $this->_setDashBorder($tbd['style'], $divider$continuingpage'B');
  14947.                 } /* -- BORDER-RADIUS -- */ elseif (($brBL_V && $brBL_H) || ($brBR_V && $brBR_H) || $tbd['style'] == 'solid' || $tbd['style'] == 'double') {
  14948.                     $this->SetLineJoin(0);
  14949.                     $this->SetLineCap(0);
  14950.                 }
  14951.                 $s '';
  14952.                 if ($brBL_H && $brBL_V) {
  14953.                     $s .= ($this->_EllipseArc($x0 $brBL_H$y0 $h $brBL_V$brBL_H $border_bottom 2$brBL_V $border_bottom 232true)) . "\n";
  14954.                 } else {                 /* -- END BORDER-RADIUS -- */
  14955.                     if ($tbd['style'] == 'solid' || $tbd['style'] == 'double') {
  14956.                         $s .= (sprintf('%.3F %.3F m ', ($x0) * Mpdf::SCALE, ($this->- ($y0 $h - ($border_bottom 2))) * Mpdf::SCALE)) . "\n";
  14957.                     } else {
  14958.                         $s .= (sprintf('%.3F %.3F m ', ($x0 + ($border_bottom 2)) * Mpdf::SCALE, ($this->- ($y0 $h - ($border_bottom 2))) * Mpdf::SCALE)) . "\n";
  14959.                     }
  14960.                 }
  14961.                 /* -- BORDER-RADIUS -- */
  14962.                 if ($brBR_H && $brBR_V) {
  14963.                     $s .= (sprintf('%.3F %.3F l ', ($x0 $w - ($border_bottom 2) - $brBR_H ) * Mpdf::SCALE, ($this->- ($y0 $h - ($border_bottom 2))) * Mpdf::SCALE)) . "\n";
  14964.                     $s .= ($this->_EllipseArc($x0 $w $brBR_H$y0 $h $brBR_V$brBR_H $border_bottom 2$brBR_V $border_bottom 241)) . "\n";
  14965.                 } else {                 /* -- END BORDER-RADIUS -- */
  14966.                     if ($tbd['style'] == 'solid' || $tbd['style'] == 'double') {
  14967.                         $s .= (sprintf('%.3F %.3F l ', ($x0 $w) * Mpdf::SCALE, ($this->- ($y0 $h - ($border_bottom 2))) * Mpdf::SCALE)) . "\n";
  14968.                     } else {
  14969.                         $s .= (sprintf('%.3F %.3F l ', ($x0 $w - ($border_bottom 2)) * Mpdf::SCALE, ($this->- ($y0 $h - ($border_bottom 2))) * Mpdf::SCALE)) . "\n";
  14970.                     }
  14971.                 }
  14972.                 $s .= 'S' "\n";
  14973.                 $this->writer->write($s);
  14974.                 if ($tbd['style'] == 'double') {
  14975.                     $this->SetLineWidth($tbd['w'] / 3);
  14976.                     $this->SetDColor($tbcol);
  14977.                     $this->writer->write($s);
  14978.                 }
  14979.                 if (!$brset && $tbd['style'] != 'dotted' && $tbd['style'] != 'dashed') {
  14980.                     $this->writer->write('Q');
  14981.                 }
  14982.                 // Reset Corners and Dash off
  14983.                 $this->SetLineWidth(0.1);
  14984.                 $this->SetDColor($this->colorConverter->convert(0$this->PDFAXwarnings));
  14985.                 $this->SetLineJoin(2);
  14986.                 $this->SetLineCap(2);
  14987.                 $this->SetDash();
  14988.             }
  14989.         }
  14990.         // Reinstate line below for dotted line divider when block border crosses a page
  14991.         // elseif ($blockstate == 1 || $divider == 'pagebottom') {
  14992.         if ($this->blk[$blvl]['border_left']) {
  14993.             $tbd $this->blk[$blvl]['border_left'];
  14994.             if (isset($tbd['s']) && $tbd['s']) {
  14995.                 if (!$brset && $tbd['style'] != 'dotted' && $tbd['style'] != 'dashed') {
  14996.                     $this->writer->write('q');
  14997.                     $this->SetLineWidth(0);
  14998.                     $this->writer->write(sprintf('%.3F %.3F m ', ($x0) * Mpdf::SCALE, ($this->- ($y0)) * Mpdf::SCALE));
  14999.                     $this->writer->write(sprintf('%.3F %.3F l ', ($x0 $border_left) * Mpdf::SCALE, ($this->- ($y0 $border_top)) * Mpdf::SCALE));
  15000.                     $this->writer->write(sprintf('%.3F %.3F l ', ($x0 $border_left) * Mpdf::SCALE, ($this->- ($y0 $h $border_bottom)) * Mpdf::SCALE));
  15001.                     $this->writer->write(sprintf('%.3F %.3F l ', ($x0) * Mpdf::SCALE, ($this->- ($y0 $h)) * Mpdf::SCALE));
  15002.                     $this->writer->write(' h W n '); // Ends path no-op & Sets the clipping path
  15003.                 }
  15004.                 $this->_setBorderLine($tbd);
  15005.                 if ($tbd['style'] == 'dotted' || $tbd['style'] == 'dashed') {
  15006.                     $this->_setDashBorder($tbd['style'], $divider$continuingpage'L');
  15007.                 } /* -- BORDER-RADIUS -- */ elseif (($brTL_V && $brTL_H) || ($brBL_V && $brBL_H) || $tbd['style'] == 'solid' || $tbd['style'] == 'double') {
  15008.                     $this->SetLineJoin(0);
  15009.                     $this->SetLineCap(0);
  15010.                 }
  15011.                 $s '';
  15012.                 if ($brTL_V && $brTL_H) {
  15013.                     $s .= ($this->_EllipseArc($x0 $brTL_H$y0 $brTL_V$brTL_H $border_left 2$brTL_V $border_left 222true)) . "\n";
  15014.                 } else {                 /* -- END BORDER-RADIUS -- */
  15015.                     if ($tbd['style'] == 'solid' || $tbd['style'] == 'double') {
  15016.                         $s .= (sprintf('%.3F %.3F m ', ($x0 + ($border_left 2)) * Mpdf::SCALE, ($this->- ($y0)) * Mpdf::SCALE)) . "\n";
  15017.                     } else {
  15018.                         $s .= (sprintf('%.3F %.3F m ', ($x0 + ($border_left 2)) * Mpdf::SCALE, ($this->- ($y0 + ($border_left 2))) * Mpdf::SCALE)) . "\n";
  15019.                     }
  15020.                 }
  15021.                 /* -- BORDER-RADIUS -- */
  15022.                 if ($brBL_V && $brBL_H) {
  15023.                     $s .= (sprintf('%.3F %.3F l ', ($x0 + ($border_left 2)) * Mpdf::SCALE, ($this->- ($y0 $h - ($border_left 2) - $brBL_V) ) * Mpdf::SCALE)) . "\n";
  15024.                     $s .= ($this->_EllipseArc($x0 $brBL_H$y0 $h $brBL_V$brBL_H $border_left 2$brBL_V $border_left 231)) . "\n";
  15025.                 } else {                 /* -- END BORDER-RADIUS -- */
  15026.                     if ($tbd['style'] == 'solid' || $tbd['style'] == 'double') {
  15027.                         $s .= (sprintf('%.3F %.3F l ', ($x0 + ($border_left 2)) * Mpdf::SCALE, ($this->- ($y0 $h) ) * Mpdf::SCALE)) . "\n";
  15028.                     } else {
  15029.                         $s .= (sprintf('%.3F %.3F l ', ($x0 + ($border_left 2)) * Mpdf::SCALE, ($this->- ($y0 $h - ($border_left 2)) ) * Mpdf::SCALE)) . "\n";
  15030.                     }
  15031.                 }
  15032.                 $s .= 'S' "\n";
  15033.                 $this->writer->write($s);
  15034.                 if ($tbd['style'] == 'double') {
  15035.                     $this->SetLineWidth($tbd['w'] / 3);
  15036.                     $this->SetDColor($tbcol);
  15037.                     $this->writer->write($s);
  15038.                 }
  15039.                 if (!$brset && $tbd['style'] != 'dotted' && $tbd['style'] != 'dashed') {
  15040.                     $this->writer->write('Q');
  15041.                 }
  15042.                 // Reset Corners and Dash off
  15043.                 $this->SetLineWidth(0.1);
  15044.                 $this->SetDColor($this->colorConverter->convert(0$this->PDFAXwarnings));
  15045.                 $this->SetLineJoin(2);
  15046.                 $this->SetLineCap(2);
  15047.                 $this->SetDash();
  15048.             }
  15049.         }
  15050.         if ($this->blk[$blvl]['border_right']) {
  15051.             $tbd $this->blk[$blvl]['border_right'];
  15052.             if (isset($tbd['s']) && $tbd['s']) {
  15053.                 if (!$brset && $tbd['style'] != 'dotted' && $tbd['style'] != 'dashed') {
  15054.                     $this->writer->write('q');
  15055.                     $this->SetLineWidth(0);
  15056.                     $this->writer->write(sprintf('%.3F %.3F m ', ($x0 $w) * Mpdf::SCALE, ($this->- ($y0)) * Mpdf::SCALE));
  15057.                     $this->writer->write(sprintf('%.3F %.3F l ', ($x0 $w $border_right) * Mpdf::SCALE, ($this->- ($y0 $border_top)) * Mpdf::SCALE));
  15058.                     $this->writer->write(sprintf('%.3F %.3F l ', ($x0 $w $border_right) * Mpdf::SCALE, ($this->- ($y0 $h $border_bottom)) * Mpdf::SCALE));
  15059.                     $this->writer->write(sprintf('%.3F %.3F l ', ($x0 $w) * Mpdf::SCALE, ($this->- ($y0 $h)) * Mpdf::SCALE));
  15060.                     $this->writer->write(' h W n '); // Ends path no-op & Sets the clipping path
  15061.                 }
  15062.                 $this->_setBorderLine($tbd);
  15063.                 if ($tbd['style'] == 'dotted' || $tbd['style'] == 'dashed') {
  15064.                     $this->_setDashBorder($tbd['style'], $divider$continuingpage'R');
  15065.                 } /* -- BORDER-RADIUS -- */ elseif (($brTR_V && $brTR_H) || ($brBR_V && $brBR_H) || $tbd['style'] == 'solid' || $tbd['style'] == 'double') {
  15066.                     $this->SetLineJoin(0);
  15067.                     $this->SetLineCap(0);
  15068.                 }
  15069.                 $s '';
  15070.                 if ($brBR_V && $brBR_H) {
  15071.                     $s .= ($this->_EllipseArc($x0 $w $brBR_H$y0 $h $brBR_V$brBR_H $border_right 2$brBR_V $border_right 242true)) . "\n";
  15072.                 } else {                 /* -- END BORDER-RADIUS -- */
  15073.                     if ($tbd['style'] == 'solid' || $tbd['style'] == 'double') {
  15074.                         $s .= (sprintf('%.3F %.3F m ', ($x0 $w - ($border_right 2)) * Mpdf::SCALE, ($this->- ($y0 $h)) * Mpdf::SCALE)) . "\n";
  15075.                     } else {
  15076.                         $s .= (sprintf('%.3F %.3F m ', ($x0 $w - ($border_right 2)) * Mpdf::SCALE, ($this->- ($y0 $h - ($border_right 2))) * Mpdf::SCALE)) . "\n";
  15077.                     }
  15078.                 }
  15079.                 /* -- BORDER-RADIUS -- */
  15080.                 if ($brTR_V && $brTR_H) {
  15081.                     $s .= (sprintf('%.3F %.3F l ', ($x0 $w - ($border_right 2)) * Mpdf::SCALE, ($this->- ($y0 + ($border_right 2) + $brTR_V) ) * Mpdf::SCALE)) . "\n";
  15082.                     $s .= ($this->_EllipseArc($x0 $w $brTR_H$y0 $brTR_V$brTR_H $border_right 2$brTR_V $border_right 211)) . "\n";
  15083.                 } else {                 /* -- END BORDER-RADIUS -- */
  15084.                     if ($tbd['style'] == 'solid' || $tbd['style'] == 'double') {
  15085.                         $s .= (sprintf('%.3F %.3F l ', ($x0 $w - ($border_right 2)) * Mpdf::SCALE, ($this->- ($y0) ) * Mpdf::SCALE)) . "\n";
  15086.                     } else {
  15087.                         $s .= (sprintf('%.3F %.3F l ', ($x0 $w - ($border_right 2)) * Mpdf::SCALE, ($this->- ($y0 + ($border_right 2)) ) * Mpdf::SCALE)) . "\n";
  15088.                     }
  15089.                 }
  15090.                 $s .= 'S' "\n";
  15091.                 $this->writer->write($s);
  15092.                 if ($tbd['style'] == 'double') {
  15093.                     $this->SetLineWidth($tbd['w'] / 3);
  15094.                     $this->SetDColor($tbcol);
  15095.                     $this->writer->write($s);
  15096.                 }
  15097.                 if (!$brset && $tbd['style'] != 'dotted' && $tbd['style'] != 'dashed') {
  15098.                     $this->writer->write('Q');
  15099.                 }
  15100.                 // Reset Corners and Dash off
  15101.                 $this->SetLineWidth(0.1);
  15102.                 $this->SetDColor($this->colorConverter->convert(0$this->PDFAXwarnings));
  15103.                 $this->SetLineJoin(2);
  15104.                 $this->SetLineCap(2);
  15105.                 $this->SetDash();
  15106.             }
  15107.         }
  15108.         $this->SetDash();
  15109.         $this->$save_y;
  15110.         // BACKGROUNDS are disabled in columns/kbt/headers - messes up the repositioning in printcolumnbuffer
  15111.         if ($this->ColActive || $this->kwt || $this->keep_block_together) {
  15112.             return;
  15113.         }
  15114.         $bgx0 $x0;
  15115.         $bgx1 $x1;
  15116.         $bgy0 $y0;
  15117.         $bgy1 $y1;
  15118.         // Defined br values represent the radius of the outer curve - need to take border-width/2 from each radius for drawing the borders
  15119.         if (isset($this->blk[$blvl]['background_clip']) && $this->blk[$blvl]['background_clip'] == 'padding-box') {
  15120.             $brbgTL_H max(0$brTL_H $this->blk[$blvl]['border_left']['w']);
  15121.             $brbgTL_V max(0$brTL_V $this->blk[$blvl]['border_top']['w']);
  15122.             $brbgTR_H max(0$brTR_H $this->blk[$blvl]['border_right']['w']);
  15123.             $brbgTR_V max(0$brTR_V $this->blk[$blvl]['border_top']['w']);
  15124.             $brbgBL_H max(0$brBL_H $this->blk[$blvl]['border_left']['w']);
  15125.             $brbgBL_V max(0$brBL_V $this->blk[$blvl]['border_bottom']['w']);
  15126.             $brbgBR_H max(0$brBR_H $this->blk[$blvl]['border_right']['w']);
  15127.             $brbgBR_V max(0$brBR_V $this->blk[$blvl]['border_bottom']['w']);
  15128.             $bgx0 += $this->blk[$blvl]['border_left']['w'];
  15129.             $bgx1 -= $this->blk[$blvl]['border_right']['w'];
  15130.             if ($this->blk[$blvl]['border_top'] && $divider != 'pagetop' && !$continuingpage) {
  15131.                 $bgy0 += $this->blk[$blvl]['border_top']['w'];
  15132.             }
  15133.             if ($this->blk[$blvl]['border_bottom'] && $blockstate != && $divider != 'pagebottom') {
  15134.                 $bgy1 -= $this->blk[$blvl]['border_bottom']['w'];
  15135.             }
  15136.         } elseif (isset($this->blk[$blvl]['background_clip']) && $this->blk[$blvl]['background_clip'] == 'content-box') {
  15137.             $brbgTL_H max(0$brTL_H $this->blk[$blvl]['border_left']['w'] - $this->blk[$blvl]['padding_left']);
  15138.             $brbgTL_V max(0$brTL_V $this->blk[$blvl]['border_top']['w'] - $this->blk[$blvl]['padding_top']);
  15139.             $brbgTR_H max(0$brTR_H $this->blk[$blvl]['border_right']['w'] - $this->blk[$blvl]['padding_right']);
  15140.             $brbgTR_V max(0$brTR_V $this->blk[$blvl]['border_top']['w'] - $this->blk[$blvl]['padding_top']);
  15141.             $brbgBL_H max(0$brBL_H $this->blk[$blvl]['border_left']['w'] - $this->blk[$blvl]['padding_left']);
  15142.             $brbgBL_V max(0$brBL_V $this->blk[$blvl]['border_bottom']['w'] - $this->blk[$blvl]['padding_bottom']);
  15143.             $brbgBR_H max(0$brBR_H $this->blk[$blvl]['border_right']['w'] - $this->blk[$blvl]['padding_right']);
  15144.             $brbgBR_V max(0$brBR_V $this->blk[$blvl]['border_bottom']['w'] - $this->blk[$blvl]['padding_bottom']);
  15145.             $bgx0 += $this->blk[$blvl]['border_left']['w'] + $this->blk[$blvl]['padding_left'];
  15146.             $bgx1 -= $this->blk[$blvl]['border_right']['w'] + $this->blk[$blvl]['padding_right'];
  15147.             if (($this->blk[$blvl]['border_top']['w'] || $this->blk[$blvl]['padding_top']) && $divider != 'pagetop' && !$continuingpage) {
  15148.                 $bgy0 += $this->blk[$blvl]['border_top']['w'] + $this->blk[$blvl]['padding_top'];
  15149.             }
  15150.             if (($this->blk[$blvl]['border_bottom']['w'] || $this->blk[$blvl]['padding_bottom']) && $blockstate != && $divider != 'pagebottom') {
  15151.                 $bgy1 -= $this->blk[$blvl]['border_bottom']['w'] + $this->blk[$blvl]['padding_bottom'];
  15152.             }
  15153.         } else {
  15154.             $brbgTL_H $brTL_H;
  15155.             $brbgTL_V $brTL_V;
  15156.             $brbgTR_H $brTR_H;
  15157.             $brbgTR_V $brTR_V;
  15158.             $brbgBL_H $brBL_H;
  15159.             $brbgBL_V $brBL_V;
  15160.             $brbgBR_H $brBR_H;
  15161.             $brbgBR_V $brBR_V;
  15162.         }
  15163.         // Set clipping path
  15164.         $s ' q 0 w '// Line width=0
  15165.         $s .= sprintf('%.3F %.3F m ', ($bgx0 $brbgTL_H ) * Mpdf::SCALE, ($this->$bgy0) * Mpdf::SCALE); // start point TL before the arc
  15166.         /* -- BORDER-RADIUS -- */
  15167.         if ($brbgTL_H || $brbgTL_V) {
  15168.             $s .= $this->_EllipseArc($bgx0 $brbgTL_H$bgy0 $brbgTL_V$brbgTL_H$brbgTL_V2); // segment 2 TL
  15169.         }
  15170.         /* -- END BORDER-RADIUS -- */
  15171.         $s .= sprintf('%.3F %.3F l ', ($bgx0) * Mpdf::SCALE, ($this->- ($bgy1 $brbgBL_V )) * Mpdf::SCALE); // line to BL
  15172.         /* -- BORDER-RADIUS -- */
  15173.         if ($brbgBL_H || $brbgBL_V) {
  15174.             $s .= $this->_EllipseArc($bgx0 $brbgBL_H$bgy1 $brbgBL_V$brbgBL_H$brbgBL_V3); // segment 3 BL
  15175.         }
  15176.         /* -- END BORDER-RADIUS -- */
  15177.         $s .= sprintf('%.3F %.3F l ', ($bgx1 $brbgBR_H ) * Mpdf::SCALE, ($this->- ($bgy1)) * Mpdf::SCALE); // line to BR
  15178.         /* -- BORDER-RADIUS -- */
  15179.         if ($brbgBR_H || $brbgBR_V) {
  15180.             $s .= $this->_EllipseArc($bgx1 $brbgBR_H$bgy1 $brbgBR_V$brbgBR_H$brbgBR_V4); // segment 4 BR
  15181.         }
  15182.         /* -- END BORDER-RADIUS -- */
  15183.         $s .= sprintf('%.3F %.3F l ', ($bgx1) * Mpdf::SCALE, ($this->- ($bgy0 $brbgTR_V)) * Mpdf::SCALE); // line to TR
  15184.         /* -- BORDER-RADIUS -- */
  15185.         if ($brbgTR_H || $brbgTR_V) {
  15186.             $s .= $this->_EllipseArc($bgx1 $brbgTR_H$bgy0 $brbgTR_V$brbgTR_H$brbgTR_V1); // segment 1 TR
  15187.         }
  15188.         /* -- END BORDER-RADIUS -- */
  15189.         $s .= sprintf('%.3F %.3F l ', ($bgx0 $brbgTL_H ) * Mpdf::SCALE, ($this->$bgy0) * Mpdf::SCALE); // line to TL
  15190.         // Box Shadow
  15191.         $shadow '';
  15192.         if (isset($this->blk[$blvl]['box_shadow']) && $this->blk[$blvl]['box_shadow'] && $h 0) {
  15193.             foreach ($this->blk[$blvl]['box_shadow'] as $sh) {
  15194.                 // Colors
  15195.                 if ($sh['col'][0] == 1) {
  15196.                     $colspace 'Gray';
  15197.                     if ($sh['col'][2] == 1) {
  15198.                         $col1 '1' $sh['col'][1] . '1' $sh['col'][3];
  15199.                     } else {
  15200.                         $col1 '1' $sh['col'][1] . '1' chr(100);
  15201.                     }
  15202.                     $col2 '1' $sh['col'][1] . '1' chr(0);
  15203.                 } elseif ($sh['col'][0] == 4) { // CMYK
  15204.                     $colspace 'CMYK';
  15205.                     $col1 '6' $sh['col'][1] . $sh['col'][2] . $sh['col'][3] . $sh['col'][4] . chr(100);
  15206.                     $col2 '6' $sh['col'][1] . $sh['col'][2] . $sh['col'][3] . $sh['col'][4] . chr(0);
  15207.                 } elseif ($sh['col'][0] == 5) { // RGBa
  15208.                     $colspace 'RGB';
  15209.                     $col1 '5' $sh['col'][1] . $sh['col'][2] . $sh['col'][3] . $sh['col'][4];
  15210.                     $col2 '5' $sh['col'][1] . $sh['col'][2] . $sh['col'][3] . chr(0);
  15211.                 } elseif ($sh['col'][0] == 6) { // CMYKa
  15212.                     $colspace 'CMYK';
  15213.                     $col1 '6' $sh['col'][1] . $sh['col'][2] . $sh['col'][3] . $sh['col'][4] . $sh['col'][5];
  15214.                     $col2 '6' $sh['col'][1] . $sh['col'][2] . $sh['col'][3] . $sh['col'][4] . chr(0);
  15215.                 } else {
  15216.                     $colspace 'RGB';
  15217.                     $col1 '5' $sh['col'][1] . $sh['col'][2] . $sh['col'][3] . chr(100);
  15218.                     $col2 '5' $sh['col'][1] . $sh['col'][2] . $sh['col'][3] . chr(0);
  15219.                 }
  15220.                 // Use clipping path as set above (and rectangle around page) to clip area outside box
  15221.                 $shadow .= $s// Use the clipping path with W*
  15222.                 $shadow .= sprintf('0 %.3F m %.3F %.3F l '$this->Mpdf::SCALE$this->Mpdf::SCALE$this->Mpdf::SCALE);
  15223.                 $shadow .= sprintf('%.3F 0 l 0 0 l 0 %.3F l '$this->Mpdf::SCALE$this->Mpdf::SCALE);
  15224.                 $shadow .= 'W n' "\n";
  15225.                 $sh['blur'] = abs($sh['blur']); // cannot have negative blur value
  15226.                 // Ensure spread/blur do not make effective shadow width/height < 0
  15227.                 // Could do more complex things but this just adjusts spread value
  15228.                 if (-$sh['spread'] + $sh['blur'] / min($w 2$h 2)) {
  15229.                     $sh['spread'] = $sh['blur'] / min($w 2$h 2) + 0.01;
  15230.                 }
  15231.                 // Shadow Offset
  15232.                 if ($sh['x'] || $sh['y']) {
  15233.                     $shadow .= sprintf(' q 1 0 0 1 %.4F %.4F cm'$sh['x'] * Mpdf::SCALE, -$sh['y'] * Mpdf::SCALE) . "\n";
  15234.                 }
  15235.                 // Set path for INNER shadow
  15236.                 $shadow .= ' q 0 w ';
  15237.                 $shadow .= $this->SetFColor($col1true) . "\n";
  15238.                 if ($col1[0] == && ord($col1[4]) < 100) { // RGBa
  15239.                     $shadow .= $this->SetAlpha(ord($col1[4]) / 100'Normal'true'F') . "\n";
  15240.                 } elseif ($col1[0] == && ord($col1[5]) < 100) { // CMYKa
  15241.                     $shadow .= $this->SetAlpha(ord($col1[5]) / 100'Normal'true'F') . "\n";
  15242.                 } elseif ($col1[0] == && $col1[2] == && ord($col1[3]) < 100) { // Gray
  15243.                     $shadow .= $this->SetAlpha(ord($col1[3]) / 100'Normal'true'F') . "\n";
  15244.                 }
  15245.                 // Blur edges
  15246.                 $mag 0.551784// Bezier Control magic number for 4-part spline for circle/ellipse
  15247.                 $mag2 0.551784// Bezier Control magic number to fill in edge of blurred rectangle
  15248.                 $d1 $sh['spread'] + $sh['blur'] / 2;
  15249.                 $d2 $sh['spread'] - $sh['blur'] / 2;
  15250.                 $bl $sh['blur'];
  15251.                 $x00 $x0 $d1;
  15252.                 $y00 $y0 $d1;
  15253.                 $w00 $w $d1 2;
  15254.                 $h00 $h $d1 2;
  15255.                 // If any border-radius is greater width-negative spread(inner edge), ignore radii for shadow or screws up
  15256.                 $flatten false;
  15257.                 if (max($brbgTR_H$brbgTL_H$brbgBR_H$brbgBL_H) >= $w $d2) {
  15258.                     $flatten true;
  15259.                 }
  15260.                 if (max($brbgTR_V$brbgTL_V$brbgBR_V$brbgBL_V) >= $h $d2) {
  15261.                     $flatten true;
  15262.                 }
  15263.                 // TOP RIGHT corner
  15264.                 $p1x $x00 $w00 $d1 $brbgTR_H;
  15265.                 $p1c2x $p1x + ($d2 $brbgTR_H) * $mag;
  15266.                 $p1y $y00 $bl;
  15267.                 $p2x $x00 $w00 $d1 $brbgTR_H;
  15268.                 $p2c2x $p2x + ($d1 $brbgTR_H) * $mag;
  15269.                 $p2y $y00;
  15270.                 $p2c1y $p2y $bl 2;
  15271.                 $p3x $x00 $w00;
  15272.                 $p3c2x $p3x $bl 2;
  15273.                 $p3y $y00 $d1 $brbgTR_V;
  15274.                 $p3c1y $p3y - ($d1 $brbgTR_V) * $mag;
  15275.                 $p4x $x00 $w00 $bl;
  15276.                 $p4y $y00 $d1 $brbgTR_V;
  15277.                 $p4c2y $p4y - ($d2 $brbgTR_V) * $mag;
  15278.                 if (-$d2 min($brbgTR_H$brbgTR_V) || $flatten) {
  15279.                     $p1x $x00 $w00 $bl;
  15280.                     $p1c2x $p1x;
  15281.                     $p2x $x00 $w00 $bl;
  15282.                     $p2c2x $p2x $bl $mag2;
  15283.                     $p3y $y00 $bl;
  15284.                     $p3c1y $p3y $bl $mag2;
  15285.                     $p4y $y00 $bl;
  15286.                     $p4c2y $p4y;
  15287.                 }
  15288.                 $shadow .= sprintf('%.3F %.3F m ', ($p1x ) * Mpdf::SCALE, ($this->- ($p1y )) * Mpdf::SCALE);
  15289.                 $shadow .= sprintf('%.3F %.3F %.3F %.3F %.3F %.3F c ', ($p1c2x) * Mpdf::SCALE, ($this->- ($p1y)) * Mpdf::SCALE, ($p4x) * Mpdf::SCALE, ($this->- ($p4c2y)) * Mpdf::SCALE, ($p4x) * Mpdf::SCALE, ($this->- ($p4y)) * Mpdf::SCALE);
  15290.                 $patch_array[0]['f'] = 0;
  15291.                 $patch_array[0]['points'] = [$p1x$p1y$p1x$p1y,
  15292.                     $p2x$p2c1y$p2x$p2y$p2c2x$p2y,
  15293.                     $p3x$p3c1y$p3x$p3y$p3c2x$p3y,
  15294.                     $p4x$p4y$p4x$p4y$p4x$p4c2y,
  15295.                     $p1c2x$p1y];
  15296.                 $patch_array[0]['colors'] = [$col1$col2$col2$col1];
  15297.                 // RIGHT
  15298.                 $p1x $x00 $w00// control point only matches p3 preceding
  15299.                 $p1y $y00 $d1 $brbgTR_V;
  15300.                 $p2x $x00 $w00 $bl// control point only matches p4 preceding
  15301.                 $p2y $y00 $d1 $brbgTR_V;
  15302.                 $p3x $x00 $w00 $bl;
  15303.                 $p3y $y00 $h00 $d1 $brbgBR_V;
  15304.                 $p4x $x00 $w00;
  15305.                 $p4c1x $p4x $bl 2;
  15306.                 $p4y $y00 $h00 $d1 $brbgBR_V;
  15307.                 if (-$d2 min($brbgTR_H$brbgTR_V) || $flatten) {
  15308.                     $p1y $y00 $bl;
  15309.                     $p2y $y00 $bl;
  15310.                 }
  15311.                 if (-$d2 min($brbgBR_H$brbgBR_V) || $flatten) {
  15312.                     $p3y $y00 $h00 $bl;
  15313.                     $p4y $y00 $h00 $bl;
  15314.                 }
  15315.                 $shadow .= sprintf('%.3F %.3F l ', ($p3x ) * Mpdf::SCALE, ($this->- ($p3y )) * Mpdf::SCALE);
  15316.                 $patch_array[1]['f'] = 2;
  15317.                 $patch_array[1]['points'] = [$p2x$p2y,
  15318.                     $p3x$p3y$p3x$p3y$p3x$p3y,
  15319.                     $p4c1x$p4y$p4x$p4y$p4x$p4y,
  15320.                     $p1x$p1y];
  15321.                 $patch_array[1]['colors'] = [$col1$col2];
  15322.                 // BOTTOM RIGHT corner
  15323.                 $p1x $x00 $w00 $bl;  // control points only matches p3 preceding
  15324.                 $p1y $y00 $h00 $d1 $brbgBR_V;
  15325.                 $p1c2y $p1y + ($d2 $brbgBR_V) * $mag;
  15326.                 $p2x $x00 $w00;     // control point only matches p4 preceding
  15327.                 $p2y $y00 $h00 $d1 $brbgBR_V;
  15328.                 $p2c2y $p2y + ($d1 $brbgBR_V) * $mag;
  15329.                 $p3x $x00 $w00 $d1 $brbgBR_H;
  15330.                 $p3c1x $p3x + ($d1 $brbgBR_H) * $mag;
  15331.                 $p3y $y00 $h00;
  15332.                 $p3c2y $p3y $bl 2;
  15333.                 $p4x $x00 $w00 $d1 $brbgBR_H;
  15334.                 $p4c2x $p4x + ($d2 $brbgBR_H) * $mag;
  15335.                 $p4y $y00 $h00 $bl;
  15336.                 if (-$d2 min($brbgBR_H$brbgBR_V) || $flatten) {
  15337.                     $p1y $y00 $h00 $bl;
  15338.                     $p1c2y $p1y;
  15339.                     $p2y $y00 $h00 $bl;
  15340.                     $p2c2y $p2y $bl $mag2;
  15341.                     $p3x $x00 $w00 $bl;
  15342.                     $p3c1x $p3x $bl $mag2;
  15343.                     $p4x $x00 $w00 $bl;
  15344.                     $p4c2x $p4x;
  15345.                 }
  15346.                 $shadow .= sprintf('%.3F %.3F %.3F %.3F %.3F %.3F c ', ($p1x) * Mpdf::SCALE, ($this->- ($p1c2y)) * Mpdf::SCALE, ($p4c2x) * Mpdf::SCALE, ($this->- ($p4y)) * Mpdf::SCALE, ($p4x) * Mpdf::SCALE, ($this->- ($p4y)) * Mpdf::SCALE);
  15347.                 $patch_array[2]['f'] = 2;
  15348.                 $patch_array[2]['points'] = [$p2x$p2c2y,
  15349.                     $p3c1x$p3y$p3x$p3y$p3x$p3c2y,
  15350.                     $p4x$p4y$p4x$p4y$p4c2x$p4y,
  15351.                     $p1x$p1c2y];
  15352.                 $patch_array[2]['colors'] = [$col2$col1];
  15353.                 // BOTTOM
  15354.                 $p1x $x00 $w00 $d1 $brbgBR_H// control point only matches p3 preceding
  15355.                 $p1y $y00 $h00;
  15356.                 $p2x $x00 $w00 $d1 $brbgBR_H// control point only matches p4 preceding
  15357.                 $p2y $y00 $h00 $bl;
  15358.                 $p3x $x00 $d1 $brbgBL_H;
  15359.                 $p3y $y00 $h00 $bl;
  15360.                 $p4x $x00 $d1 $brbgBL_H;
  15361.                 $p4y $y00 $h00;
  15362.                 $p4c1y $p4y $bl 2;
  15363.                 if (-$d2 min($brbgBR_H$brbgBR_V) || $flatten) {
  15364.                     $p1x $x00 $w00 $bl;
  15365.                     $p2x $x00 $w00 $bl;
  15366.                 }
  15367.                 if (-$d2 min($brbgBL_H$brbgBL_V) || $flatten) {
  15368.                     $p3x $x00 $bl;
  15369.                     $p4x $x00 $bl;
  15370.                 }
  15371.                 $shadow .= sprintf('%.3F %.3F l ', ($p3x ) * Mpdf::SCALE, ($this->- ($p3y )) * Mpdf::SCALE);
  15372.                 $patch_array[3]['f'] = 2;
  15373.                 $patch_array[3]['points'] = [$p2x$p2y,
  15374.                     $p3x$p3y$p3x$p3y$p3x$p3y,
  15375.                     $p4x$p4c1y$p4x$p4y$p4x$p4y,
  15376.                     $p1x$p1y];
  15377.                 $patch_array[3]['colors'] = [$col1$col2];
  15378.                 // BOTTOM LEFT corner
  15379.                 $p1x $x00 $d1 $brbgBL_H;
  15380.                 $p1c2x $p1x - ($d2 $brbgBL_H) * $mag// control points only matches p3 preceding
  15381.                 $p1y $y00 $h00 $bl;
  15382.                 $p2x $x00 $d1 $brbgBL_H;
  15383.                 $p2c2x $p2x - ($d1 $brbgBL_H) * $mag// control point only matches p4 preceding
  15384.                 $p2y $y00 $h00;
  15385.                 $p3x $x00;
  15386.                 $p3c2x $p3x $bl 2;
  15387.                 $p3y $y00 $h00 $d1 $brbgBL_V;
  15388.                 $p3c1y $p3y + ($d1 $brbgBL_V) * $mag;
  15389.                 $p4x $x00 $bl;
  15390.                 $p4y $y00 $h00 $d1 $brbgBL_V;
  15391.                 $p4c2y $p4y + ($d2 $brbgBL_V) * $mag;
  15392.                 if (-$d2 min($brbgBL_H$brbgBL_V) || $flatten) {
  15393.                     $p1x $x00 $bl;
  15394.                     $p1c2x $p1x;
  15395.                     $p2x $x00 $bl;
  15396.                     $p2c2x $p2x $bl $mag2;
  15397.                     $p3y $y00 $h00 $bl;
  15398.                     $p3c1y $p3y $bl $mag2;
  15399.                     $p4y $y00 $h00 $bl;
  15400.                     $p4c2y $p4y;
  15401.                 }
  15402.                 $shadow .= sprintf('%.3F %.3F %.3F %.3F %.3F %.3F c ', ($p1c2x) * Mpdf::SCALE, ($this->- ($p1y)) * Mpdf::SCALE, ($p4x) * Mpdf::SCALE, ($this->- ($p4c2y)) * Mpdf::SCALE, ($p4x) * Mpdf::SCALE, ($this->- ($p4y)) * Mpdf::SCALE);
  15403.                 $patch_array[4]['f'] = 2;
  15404.                 $patch_array[4]['points'] = [$p2c2x$p2y,
  15405.                     $p3x$p3c1y$p3x$p3y$p3c2x$p3y,
  15406.                     $p4x$p4y$p4x$p4y$p4x$p4c2y,
  15407.                     $p1c2x$p1y];
  15408.                 $patch_array[4]['colors'] = [$col2$col1];
  15409.                 // LEFT - joins on the right (C3-C4 of previous): f = 2
  15410.                 $p1x $x00// control point only matches p3 preceding
  15411.                 $p1y $y00 $h00 $d1 $brbgBL_V;
  15412.                 $p2x $x00 $bl// control point only matches p4 preceding
  15413.                 $p2y $y00 $h00 $d1 $brbgBL_V;
  15414.                 $p3x $x00 $bl;
  15415.                 $p3y $y00 $d1 $brbgTL_V;
  15416.                 $p4x $x00;
  15417.                 $p4c1x $p4x $bl 2;
  15418.                 $p4y $y00 $d1 $brbgTL_V;
  15419.                 if (-$d2 min($brbgBL_H$brbgBL_V) || $flatten) {
  15420.                     $p1y $y00 $h00 $bl;
  15421.                     $p2y $y00 $h00 $bl;
  15422.                 }
  15423.                 if (-$d2 min($brbgTL_H$brbgTL_V) || $flatten) {
  15424.                     $p3y $y00 $bl;
  15425.                     $p4y $y00 $bl;
  15426.                 }
  15427.                 $shadow .= sprintf('%.3F %.3F l ', ($p3x ) * Mpdf::SCALE, ($this->- ($p3y )) * Mpdf::SCALE);
  15428.                 $patch_array[5]['f'] = 2;
  15429.                 $patch_array[5]['points'] = [$p2x$p2y,
  15430.                     $p3x$p3y$p3x$p3y$p3x$p3y,
  15431.                     $p4c1x$p4y$p4x$p4y$p4x$p4y,
  15432.                     $p1x$p1y];
  15433.                 $patch_array[5]['colors'] = [$col1$col2];
  15434.                 // TOP LEFT corner
  15435.                 $p1x $x00 $bl;  // control points only matches p3 preceding
  15436.                 $p1y $y00 $d1 $brbgTL_V;
  15437.                 $p1c2y $p1y - ($d2 $brbgTL_V) * $mag;
  15438.                 $p2x $x00;   // control point only matches p4 preceding
  15439.                 $p2y $y00 $d1 $brbgTL_V;
  15440.                 $p2c2y $p2y - ($d1 $brbgTL_V) * $mag;
  15441.                 $p3x $x00 $d1 $brbgTL_H;
  15442.                 $p3c1x $p3x - ($d1 $brbgTL_H) * $mag;
  15443.                 $p3y $y00;
  15444.                 $p3c2y $p3y $bl 2;
  15445.                 $p4x $x00 $d1 $brbgTL_H;
  15446.                 $p4c2x $p4x - ($d2 $brbgTL_H) * $mag;
  15447.                 $p4y $y00 $bl;
  15448.                 if (-$d2 min($brbgTL_H$brbgTL_V) || $flatten) {
  15449.                     $p1y $y00 $bl;
  15450.                     $p1c2y $p1y;
  15451.                     $p2y $y00 $bl;
  15452.                     $p2c2y $p2y $bl $mag2;
  15453.                     $p3x $x00 $bl;
  15454.                     $p3c1x $p3x $bl $mag2;
  15455.                     $p4x $x00 $bl;
  15456.                     $p4c2x $p4x;
  15457.                 }
  15458.                 $shadow .= sprintf('%.3F %.3F %.3F %.3F %.3F %.3F c ', ($p1x) * Mpdf::SCALE, ($this->- ($p1c2y)) * Mpdf::SCALE, ($p4c2x) * Mpdf::SCALE, ($this->- ($p4y)) * Mpdf::SCALE, ($p4x) * Mpdf::SCALE, ($this->- ($p4y)) * Mpdf::SCALE);
  15459.                 $patch_array[6]['f'] = 2;
  15460.                 $patch_array[6]['points'] = [$p2x$p2c2y,
  15461.                     $p3c1x$p3y$p3x$p3y$p3x$p3c2y,
  15462.                     $p4x$p4y$p4x$p4y$p4c2x$p4y,
  15463.                     $p1x$p1c2y];
  15464.                 $patch_array[6]['colors'] = [$col2$col1];
  15465.                 // TOP - joins on the right (C3-C4 of previous): f = 2
  15466.                 $p1x $x00 $d1 $brbgTL_H// control point only matches p3 preceding
  15467.                 $p1y $y00;
  15468.                 $p2x $x00 $d1 $brbgTL_H// control point only matches p4 preceding
  15469.                 $p2y $y00 $bl;
  15470.                 $p3x $x00 $w00 $d1 $brbgTR_H;
  15471.                 $p3y $y00 $bl;
  15472.                 $p4x $x00 $w00 $d1 $brbgTR_H;
  15473.                 $p4y $y00;
  15474.                 $p4c1y $p4y $bl 2;
  15475.                 if (-$d2 min($brbgTL_H$brbgTL_V) || $flatten) {
  15476.                     $p1x $x00 $bl;
  15477.                     $p2x $x00 $bl;
  15478.                 }
  15479.                 if (-$d2 min($brbgTR_H$brbgTR_V) || $flatten) {
  15480.                     $p3x $x00 $w00 $bl;
  15481.                     $p4x $x00 $w00 $bl;
  15482.                 }
  15483.                 $shadow .= sprintf('%.3F %.3F l ', ($p3x ) * Mpdf::SCALE, ($this->- ($p3y )) * Mpdf::SCALE);
  15484.                 $patch_array[7]['f'] = 2;
  15485.                 $patch_array[7]['points'] = [$p2x$p2y,
  15486.                     $p3x$p3y$p3x$p3y$p3x$p3y,
  15487.                     $p4x$p4c1y$p4x$p4y$p4x$p4y,
  15488.                     $p1x$p1y];
  15489.                 $patch_array[7]['colors'] = [$col1$col2];
  15490.                 $shadow .= ' h f Q ' "\n"// Close path and Fill the inner solid shadow
  15491.                 if ($bl) {
  15492.                     $shadow .= $this->gradient->CoonsPatchMesh($x00$y00$w00$h00$patch_array$x00$x00 $w00$y00$y00 $h00$colspacetrue);
  15493.                 }
  15494.                 if ($sh['x'] || $sh['y']) {
  15495.                     $shadow .= ' Q' "\n";  // Shadow Offset
  15496.                 }
  15497.                 $shadow .= ' Q' "\n"// Ends path no-op & Sets the clipping path
  15498.             }
  15499.         }
  15500.         $s .= ' W n '// Ends path no-op & Sets the clipping path
  15501.         if ($this->blk[$blvl]['bgcolor']) {
  15502.             $this->pageBackgrounds[$blvl][] = [
  15503.                 'x' => $x0,
  15504.                 'y' => $y0,
  15505.                 'w' => $w,
  15506.                 'h' => $h,
  15507.                 'col' => $this->blk[$blvl]['bgcolorarray'],
  15508.                 'clippath' => $s,
  15509.                 'visibility' => $this->visibility,
  15510.                 'shadow' => $shadow,
  15511.                 'z-index' => $this->current_layer,
  15512.             ];
  15513.         } elseif ($shadow) {
  15514.             $this->pageBackgrounds[$blvl][] = [
  15515.                 'x' => 0,
  15516.                 'y' => 0,
  15517.                 'w' => 0,
  15518.                 'h' => 0,
  15519.                 'shadowonly' => true,
  15520.                 'col' => '',
  15521.                 'clippath' => '',
  15522.                 'visibility' => $this->visibility,
  15523.                 'shadow' => $shadow,
  15524.                 'z-index' => $this->current_layer,
  15525.             ];
  15526.         }
  15527.         /* -- BACKGROUNDS -- */
  15528.         if (isset($this->blk[$blvl]['gradient'])) {
  15529.             $g $this->gradient->parseBackgroundGradient($this->blk[$blvl]['gradient']);
  15530.             if ($g) {
  15531.                 $gx $x0;
  15532.                 $gy $y0;
  15533.                 $this->pageBackgrounds[$blvl][] = [
  15534.                     'gradient' => true,
  15535.                     'x' => $gx,
  15536.                     'y' => $gy,
  15537.                     'w' => $w,
  15538.                     'h' => $h,
  15539.                     'gradtype' => $g['type'],
  15540.                     'stops' => $g['stops'],
  15541.                     'colorspace' => $g['colorspace'],
  15542.                     'coords' => $g['coords'],
  15543.                     'extend' => $g['extend'],
  15544.                     'clippath' => $s,
  15545.                     'visibility' => $this->visibility,
  15546.                     'z-index' => $this->current_layer
  15547.                 ];
  15548.             }
  15549.         }
  15550.         if (isset($this->blk[$blvl]['background-image'])) {
  15551.             if (isset($this->blk[$blvl]['background-image']['gradient']) && $this->blk[$blvl]['background-image']['gradient'] && preg_match('/(-moz-)*(repeating-)*(linear|radial)-gradient/'$this->blk[$blvl]['background-image']['gradient'])) {
  15552.                 $g $this->gradient->parseMozGradient($this->blk[$blvl]['background-image']['gradient']);
  15553.                 if ($g) {
  15554.                     $gx $x0;
  15555.                     $gy $y0;
  15556.                     // origin specifies the background-positioning-area (bpa)
  15557.                     if ($this->blk[$blvl]['background-image']['origin'] == 'padding-box') {
  15558.                         $gx += $this->blk[$blvl]['border_left']['w'];
  15559.                         $w -= ($this->blk[$blvl]['border_left']['w'] + $this->blk[$blvl]['border_right']['w']);
  15560.                         if ($this->blk[$blvl]['border_top'] && $divider != 'pagetop' && !$continuingpage) {
  15561.                             $gy += $this->blk[$blvl]['border_top']['w'];
  15562.                         }
  15563.                         if ($this->blk[$blvl]['border_bottom'] && $blockstate != && $divider != 'pagebottom') {
  15564.                             $gy1 $y1 $this->blk[$blvl]['border_bottom']['w'];
  15565.                         } else {
  15566.                             $gy1 $y1;
  15567.                         }
  15568.                         $h $gy1 $gy;
  15569.                     } elseif ($this->blk[$blvl]['background-image']['origin'] == 'content-box') {
  15570.                         $gx += $this->blk[$blvl]['border_left']['w'] + $this->blk[$blvl]['padding_left'];
  15571.                         $w -= ($this->blk[$blvl]['border_left']['w'] + $this->blk[$blvl]['padding_left'] + $this->blk[$blvl]['border_right']['w'] + $this->blk[$blvl]['padding_right']);
  15572.                         if ($this->blk[$blvl]['border_top'] && $divider != 'pagetop' && !$continuingpage) {
  15573.                             $gy += $this->blk[$blvl]['border_top']['w'] + $this->blk[$blvl]['padding_top'];
  15574.                         }
  15575.                         if ($this->blk[$blvl]['border_bottom'] && $blockstate != && $divider != 'pagebottom') {
  15576.                             $gy1 $y1 - ($this->blk[$blvl]['border_bottom']['w'] + $this->blk[$blvl]['padding_bottom']);
  15577.                         } else {
  15578.                             $gy1 $y1 $this->blk[$blvl]['padding_bottom'];
  15579.                         }
  15580.                         $h $gy1 $gy;
  15581.                     }
  15582.                     if (isset($this->blk[$blvl]['background-image']['size']['w']) && $this->blk[$blvl]['background-image']['size']['w']) {
  15583.                         $size $this->blk[$blvl]['background-image']['size'];
  15584.                         if ($size['w'] != 'contain' && $size['w'] != 'cover') {
  15585.                             if (stristr($size['w'], '%')) {
  15586.                                 $size['w'] = (float) $size['w'];
  15587.                                 $size['w'] /= 100;
  15588.                                 $w *= $size['w'];
  15589.                             } elseif ($size['w'] != 'auto') {
  15590.                                 $w $size['w'];
  15591.                             }
  15592.                             if (stristr($size['h'], '%')) {
  15593.                                 $size['h'] = (float) $size['h'];
  15594.                                 $size['h'] /= 100;
  15595.                                 $h *= $size['h'];
  15596.                             } elseif ($size['h'] != 'auto') {
  15597.                                 $h $size['h'];
  15598.                             }
  15599.                         }
  15600.                     }
  15601.                     $this->pageBackgrounds[$blvl][] = [
  15602.                         'gradient' => true,
  15603.                         'x' => $gx,
  15604.                         'y' => $gy,
  15605.                         'w' => $w,
  15606.                         'h' => $h,
  15607.                         'gradtype' => $g['type'],
  15608.                         'stops' => $g['stops'],
  15609.                         'colorspace' => $g['colorspace'],
  15610.                         'coords' => $g['coords'],
  15611.                         'extend' => $g['extend'],
  15612.                         'clippath' => $s,
  15613.                         'visibility' => $this->visibility,
  15614.                         'z-index' => $this->current_layer
  15615.                     ];
  15616.                 }
  15617.             } else {
  15618.                 $image_id $this->blk[$blvl]['background-image']['image_id'];
  15619.                 $orig_w $this->blk[$blvl]['background-image']['orig_w'];
  15620.                 $orig_h $this->blk[$blvl]['background-image']['orig_h'];
  15621.                 $x_pos $this->blk[$blvl]['background-image']['x_pos'];
  15622.                 $y_pos $this->blk[$blvl]['background-image']['y_pos'];
  15623.                 $x_repeat $this->blk[$blvl]['background-image']['x_repeat'];
  15624.                 $y_repeat $this->blk[$blvl]['background-image']['y_repeat'];
  15625.                 $resize $this->blk[$blvl]['background-image']['resize'];
  15626.                 $opacity $this->blk[$blvl]['background-image']['opacity'];
  15627.                 $itype $this->blk[$blvl]['background-image']['itype'];
  15628.                 $size $this->blk[$blvl]['background-image']['size'];
  15629.                 // origin specifies the background-positioning-area (bpa)
  15630.                 $bpa = ['x' => $x0'y' => $y0'w' => $w'h' => $h];
  15631.                 if ($this->blk[$blvl]['background-image']['origin'] == 'padding-box') {
  15632.                     $bpa['x'] = $x0 $this->blk[$blvl]['border_left']['w'];
  15633.                     $bpa['w'] = $w - ($this->blk[$blvl]['border_left']['w'] + $this->blk[$blvl]['border_right']['w']);
  15634.                     if ($this->blk[$blvl]['border_top'] && $divider != 'pagetop' && !$continuingpage) {
  15635.                         $bpa['y'] = $y0 $this->blk[$blvl]['border_top']['w'];
  15636.                     } else {
  15637.                         $bpa['y'] = $y0;
  15638.                     }
  15639.                     if ($this->blk[$blvl]['border_bottom'] && $blockstate != && $divider != 'pagebottom') {
  15640.                         $bpay $y1 $this->blk[$blvl]['border_bottom']['w'];
  15641.                     } else {
  15642.                         $bpay $y1;
  15643.                     }
  15644.                     $bpa['h'] = $bpay $bpa['y'];
  15645.                 } elseif ($this->blk[$blvl]['background-image']['origin'] == 'content-box') {
  15646.                     $bpa['x'] = $x0 $this->blk[$blvl]['border_left']['w'] + $this->blk[$blvl]['padding_left'];
  15647.                     $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']);
  15648.                     if ($this->blk[$blvl]['border_top'] && $divider != 'pagetop' && !$continuingpage) {
  15649.                         $bpa['y'] = $y0 $this->blk[$blvl]['border_top']['w'] + $this->blk[$blvl]['padding_top'];
  15650.                     } else {
  15651.                         $bpa['y'] = $y0 $this->blk[$blvl]['padding_top'];
  15652.                     }
  15653.                     if ($this->blk[$blvl]['border_bottom'] && $blockstate != && $divider != 'pagebottom') {
  15654.                         $bpay $y1 - ($this->blk[$blvl]['border_bottom']['w'] + $this->blk[$blvl]['padding_bottom']);
  15655.                     } else {
  15656.                         $bpay $y1 $this->blk[$blvl]['padding_bottom'];
  15657.                     }
  15658.                     $bpa['h'] = $bpay $bpa['y'];
  15659.                 }
  15660.                 $this->pageBackgrounds[$blvl][] = [
  15661.                     'x' => $x0,
  15662.                     'y' => $y0,
  15663.                     'w' => $w,
  15664.                     'h' => $h,
  15665.                     'image_id' => $image_id,
  15666.                     'orig_w' => $orig_w,
  15667.                     'orig_h' => $orig_h,
  15668.                     'x_pos' => $x_pos,
  15669.                     'y_pos' => $y_pos,
  15670.                     'x_repeat' => $x_repeat,
  15671.                     'y_repeat' => $y_repeat,
  15672.                     'clippath' => $s,
  15673.                     'resize' => $resize,
  15674.                     'opacity' => $opacity,
  15675.                     'itype' => $itype,
  15676.                     'visibility' => $this->visibility,
  15677.                     'z-index' => $this->current_layer,
  15678.                     'size' => $size,
  15679.                     'bpa' => $bpa
  15680.                 ];
  15681.             }
  15682.         }
  15683.         /* -- END BACKGROUNDS -- */
  15684.         // Float DIV
  15685.         $this->blk[$blvl]['bb_painted'][$this->page] = true;
  15686.     }
  15687.     /* -- BORDER-RADIUS -- */
  15688.     function _EllipseArc($x0$y0$rx$ry$seg 1$part false$start false)
  15689.     {
  15690.         // Anticlockwise segment 1-4 TR-TL-BL-BR (part=1 or 2)
  15691.         $s '';
  15692.         if ($rx 0) {
  15693.             $rx 0;
  15694.         }
  15695.         if ($ry 0) {
  15696.             $ry 0;
  15697.         }
  15698.         $rx *= Mpdf::SCALE;
  15699.         $ry *= Mpdf::SCALE;
  15700.         $astart 0;
  15701.         if ($seg == 1) { // Top Right
  15702.             $afinish 90;
  15703.             $nSeg 4;
  15704.         } elseif ($seg == 2) { // Top Left
  15705.             $afinish 180;
  15706.             $nSeg 8;
  15707.         } elseif ($seg == 3) { // Bottom Left
  15708.             $afinish 270;
  15709.             $nSeg 12;
  15710.         } else {   // Bottom Right
  15711.             $afinish 360;
  15712.             $nSeg 16;
  15713.         }
  15714.         $astart deg2rad((float) $astart);
  15715.         $afinish deg2rad((float) $afinish);
  15716.         $totalAngle $afinish $astart;
  15717.         $dt $totalAngle $nSeg// segment angle
  15718.         $dtm $dt 3;
  15719.         $x0 *= Mpdf::SCALE;
  15720.         $y0 = ($this->$y0) * Mpdf::SCALE;
  15721.         $t1 $astart;
  15722.         $a0 $x0 + ($rx cos($t1));
  15723.         $b0 $y0 + ($ry sin($t1));
  15724.         $c0 = -$rx sin($t1);
  15725.         $d0 $ry cos($t1);
  15726.         $op false;
  15727.         for ($i 1$i <= $nSeg$i++) {
  15728.             // Draw this bit of the total curve
  15729.             $t1 = ($i $dt) + $astart;
  15730.             $a1 $x0 + ($rx cos($t1));
  15731.             $b1 $y0 + ($ry sin($t1));
  15732.             $c1 = -$rx sin($t1);
  15733.             $d1 $ry cos($t1);
  15734.             if ($i > ($nSeg 4) && (!$part || ($part == && $i <= $nSeg 2) || ($part == && $i $nSeg 2))) {
  15735.                 if ($start && !$op) {
  15736.                     $s .= sprintf('%.3F %.3F m '$a0$b0);
  15737.                 }
  15738.                 $s .= sprintf('%.3F %.3F %.3F %.3F %.3F %.3F c ', ($a0 + ($c0 $dtm)), ($b0 + ($d0 $dtm)), ($a1 - ($c1 $dtm)), ($b1 - ($d1 $dtm)), $a1$b1);
  15739.                 $op true;
  15740.             }
  15741.             $a0 $a1;
  15742.             $b0 $b1;
  15743.             $c0 $c1;
  15744.             $d0 $d1;
  15745.         }
  15746.         return $s;
  15747.     }
  15748.     /* -- END BORDER-RADIUS -- */
  15749.     function PaintDivLnBorder($state 0$blvl 0$h 0)
  15750.     {
  15751.         // $state = 0 normal; 1 top; 2 bottom; 3 top and bottom
  15752.         $this->ColDetails[$this->CurrCol]['bottom_margin'] = $this->$h;
  15753.         $save_y $this->y;
  15754.         $w $this->blk[$blvl]['width'];
  15755.         $x0 $this->x;    // left
  15756.         $y0 $this->y;    // top
  15757.         $x1 $this->$w;   // bottom
  15758.         $y1 $this->$h;   // bottom
  15759.         $continuingpage = (isset($this->blk[$blvl]['startpage']) && $this->blk[$blvl]['startpage'] != $this->page);
  15760.         if ($this->blk[$blvl]['border_top'] && ($state == || $state == 3)) {
  15761.             $tbd $this->blk[$blvl]['border_top'];
  15762.             if (isset($tbd['s']) && $tbd['s']) {
  15763.                 $this->_setBorderLine($tbd);
  15764.                 $this->$y0 + ($tbd['w'] / 2);
  15765.                 if ($tbd['style'] == 'dotted' || $tbd['style'] == 'dashed') {
  15766.                     $this->_setDashBorder($tbd['style'], ''$continuingpage'T');
  15767.                     $this->Line($x0 + ($tbd['w'] / 2), $this->y$x0 $w - ($tbd['w'] / 2), $this->y);
  15768.                 } else {
  15769.                     $this->SetLineJoin(0);
  15770.                     $this->SetLineCap(0);
  15771.                     $this->Line($x0$this->y$x0 $w$this->y);
  15772.                 }
  15773.                 $this->+= $tbd['w'];
  15774.                 // Reset Corners and Dash off
  15775.                 $this->SetLineJoin(2);
  15776.                 $this->SetLineCap(2);
  15777.                 $this->SetDash();
  15778.             }
  15779.         }
  15780.         if ($this->blk[$blvl]['border_left']) {
  15781.             $tbd $this->blk[$blvl]['border_left'];
  15782.             if (isset($tbd['s']) && $tbd['s']) {
  15783.                 $this->_setBorderLine($tbd);
  15784.                 if ($tbd['style'] == 'dotted' || $tbd['style'] == 'dashed') {
  15785.                     $this->$y0 + ($tbd['w'] / 2);
  15786.                     $this->_setDashBorder($tbd['style'], ''$continuingpage'L');
  15787.                     $this->Line($x0 + ($tbd['w'] / 2), $this->y$x0 + ($tbd['w'] / 2), $y0 $h - ($tbd['w'] / 2));
  15788.                 } else {
  15789.                     $this->$y0;
  15790.                     $this->SetLineJoin(0);
  15791.                     $this->SetLineCap(0);
  15792.                     $this->Line($x0 + ($tbd['w'] / 2), $this->y$x0 + ($tbd['w'] / 2), $y0 $h);
  15793.                 }
  15794.                 $this->+= $tbd['w'];
  15795.                 // Reset Corners and Dash off
  15796.                 $this->SetLineJoin(2);
  15797.                 $this->SetLineCap(2);
  15798.                 $this->SetDash();
  15799.             }
  15800.         }
  15801.         if ($this->blk[$blvl]['border_right']) {
  15802.             $tbd $this->blk[$blvl]['border_right'];
  15803.             if (isset($tbd['s']) && $tbd['s']) {
  15804.                 $this->_setBorderLine($tbd);
  15805.                 if ($tbd['style'] == 'dotted' || $tbd['style'] == 'dashed') {
  15806.                     $this->$y0 + ($tbd['w'] / 2);
  15807.                     $this->_setDashBorder($tbd['style'], ''$continuingpage'R');
  15808.                     $this->Line($x0 $w - ($tbd['w'] / 2), $this->y$x0 $w - ($tbd['w'] / 2), $y0 $h - ($tbd['w'] / 2));
  15809.                 } else {
  15810.                     $this->$y0;
  15811.                     $this->SetLineJoin(0);
  15812.                     $this->SetLineCap(0);
  15813.                     $this->Line($x0 $w - ($tbd['w'] / 2), $this->y$x0 $w - ($tbd['w'] / 2), $y0 $h);
  15814.                 }
  15815.                 $this->+= $tbd['w'];
  15816.                 // Reset Corners and Dash off
  15817.                 $this->SetLineJoin(2);
  15818.                 $this->SetLineCap(2);
  15819.                 $this->SetDash();
  15820.             }
  15821.         }
  15822.         if ($this->blk[$blvl]['border_bottom'] && $state 1) {
  15823.             $tbd $this->blk[$blvl]['border_bottom'];
  15824.             if (isset($tbd['s']) && $tbd['s']) {
  15825.                 $this->_setBorderLine($tbd);
  15826.                 $this->$y0 $h - ($tbd['w'] / 2);
  15827.                 if ($tbd['style'] == 'dotted' || $tbd['style'] == 'dashed') {
  15828.                     $this->_setDashBorder($tbd['style'], ''$continuingpage'B');
  15829.                     $this->Line($x0 + ($tbd['w'] / 2), $this->y$x0 $w - ($tbd['w'] / 2), $this->y);
  15830.                 } else {
  15831.                     $this->SetLineJoin(0);
  15832.                     $this->SetLineCap(0);
  15833.                     $this->Line($x0$this->y$x0 $w$this->y);
  15834.                 }
  15835.                 $this->+= $tbd['w'];
  15836.                 // Reset Corners and Dash off
  15837.                 $this->SetLineJoin(2);
  15838.                 $this->SetLineCap(2);
  15839.                 $this->SetDash();
  15840.             }
  15841.         }
  15842.         $this->SetDash();
  15843.         $this->$save_y;
  15844.     }
  15845.     function PaintImgBorder($objattr$is_table)
  15846.     {
  15847.         // Borders are disabled in columns - messes up the repositioning in printcolumnbuffer
  15848.         if ($this->ColActive) {
  15849.             return;
  15850.         } // *COLUMNS*
  15851.         if ($is_table) {
  15852.             $k $this->shrin_k;
  15853.         } else {
  15854.             $k 1;
  15855.         }
  15856.         $h = (isset($objattr['BORDER-HEIGHT']) ? $objattr['BORDER-HEIGHT'] : 0);
  15857.         $w = (isset($objattr['BORDER-WIDTH']) ? $objattr['BORDER-WIDTH'] : 0);
  15858.         $x0 = (isset($objattr['BORDER-X']) ? $objattr['BORDER-X'] : 0);
  15859.         $y0 = (isset($objattr['BORDER-Y']) ? $objattr['BORDER-Y'] : 0);
  15860.         // BORDERS
  15861.         if ($objattr['border_top']) {
  15862.             $tbd $objattr['border_top'];
  15863.             if (!empty($tbd['s'])) {
  15864.                 $this->_setBorderLine($tbd$k);
  15865.                 if ($tbd['style'] == 'dotted' || $tbd['style'] == 'dashed') {
  15866.                     $this->_setDashBorder($tbd['style'], '''''T');
  15867.                 }
  15868.                 $this->Line($x0$y0$x0 $w$y0);
  15869.                 // Reset Corners and Dash off
  15870.                 $this->SetLineJoin(2);
  15871.                 $this->SetLineCap(2);
  15872.                 $this->SetDash();
  15873.             }
  15874.         }
  15875.         if ($objattr['border_left']) {
  15876.             $tbd $objattr['border_left'];
  15877.             if (!empty($tbd['s'])) {
  15878.                 $this->_setBorderLine($tbd$k);
  15879.                 if ($tbd['style'] == 'dotted' || $tbd['style'] == 'dashed') {
  15880.                     $this->_setDashBorder($tbd['style'], '''''L');
  15881.                 }
  15882.                 $this->Line($x0$y0$x0$y0 $h);
  15883.                 // Reset Corners and Dash off
  15884.                 $this->SetLineJoin(2);
  15885.                 $this->SetLineCap(2);
  15886.                 $this->SetDash();
  15887.             }
  15888.         }
  15889.         if ($objattr['border_right']) {
  15890.             $tbd $objattr['border_right'];
  15891.             if (!empty($tbd['s'])) {
  15892.                 $this->_setBorderLine($tbd$k);
  15893.                 if ($tbd['style'] == 'dotted' || $tbd['style'] == 'dashed') {
  15894.                     $this->_setDashBorder($tbd['style'], '''''R');
  15895.                 }
  15896.                 $this->Line($x0 $w$y0$x0 $w$y0 $h);
  15897.                 // Reset Corners and Dash off
  15898.                 $this->SetLineJoin(2);
  15899.                 $this->SetLineCap(2);
  15900.                 $this->SetDash();
  15901.             }
  15902.         }
  15903.         if ($objattr['border_bottom']) {
  15904.             $tbd $objattr['border_bottom'];
  15905.             if (!empty($tbd['s'])) {
  15906.                 $this->_setBorderLine($tbd$k);
  15907.                 if ($tbd['style'] == 'dotted' || $tbd['style'] == 'dashed') {
  15908.                     $this->_setDashBorder($tbd['style'], '''''B');
  15909.                 }
  15910.                 $this->Line($x0$y0 $h$x0 $w$y0 $h);
  15911.                 // Reset Corners and Dash off
  15912.                 $this->SetLineJoin(2);
  15913.                 $this->SetLineCap(2);
  15914.                 $this->SetDash();
  15915.             }
  15916.         }
  15917.         $this->SetDash();
  15918.         $this->SetAlpha(1);
  15919.     }
  15920.     /* -- END HTML-CSS -- */
  15921.     function Reset()
  15922.     {
  15923.         $this->SetTColor($this->colorConverter->convert(0$this->PDFAXwarnings));
  15924.         $this->SetDColor($this->colorConverter->convert(0$this->PDFAXwarnings));
  15925.         $this->SetFColor($this->colorConverter->convert(255$this->PDFAXwarnings));
  15926.         $this->SetAlpha(1);
  15927.         $this->colorarray '';
  15928.         $this->spanbgcolorarray '';
  15929.         $this->spanbgcolor false;
  15930.         $this->spanborder false;
  15931.         $this->spanborddet = [];
  15932.         $this->ResetStyles();
  15933.         $this->HREF '';
  15934.         $this->textparam = [];
  15935.         $this->SetTextOutline();
  15936.         $this->textvar 0x00// mPDF 5.7.1
  15937.         $this->OTLtags = [];
  15938.         $this->textshadow '';
  15939.         $this->currentLang $this->default_lang;  // mPDF 6
  15940.         $this->RestrictUnicodeFonts($this->default_available_fonts); // mPDF 6
  15941.         $this->SetFont($this->default_font''0false);
  15942.         $this->SetFontSize($this->default_font_sizefalse);
  15943.         $this->currentfontfamily '';
  15944.         $this->currentfontsize '';
  15945.         $this->currentfontstyle '';
  15946.         if ($this->tableLevel && isset($this->table[1][1]['cellLineHeight'])) {
  15947.             $this->SetLineHeight(''$this->table[1][1]['cellLineHeight']);
  15948.         } else {
  15949.             if (isset($this->blk[$this->blklvl]['line_height']) && $this->blk[$this->blklvl]['line_height']) {
  15950.                 $this->SetLineHeight(''$this->blk[$this->blklvl]['line_height']); // sets default line height
  15951.             }
  15952.         }
  15953.         $this->lSpacingCSS '';
  15954.         $this->wSpacingCSS '';
  15955.         $this->fixedlSpacing false;
  15956.         $this->minwSpacing 0;
  15957.         $this->SetDash(); // restore to no dash
  15958.         $this->dash_on false;
  15959.         $this->dotted_on false;
  15960.         $this->divwidth 0;
  15961.         $this->divheight 0;
  15962.         $this->cellTextAlign '';
  15963.         $this->cellLineHeight '';
  15964.         $this->cellLineStackingStrategy '';
  15965.         $this->cellLineStackingShift '';
  15966.         $this->oldy = -1;
  15967.         $bodystyle = [];
  15968.         if (isset($this->cssManager->CSS['BODY']['FONT-STYLE'])) {
  15969.             $bodystyle['FONT-STYLE'] = $this->cssManager->CSS['BODY']['FONT-STYLE'];
  15970.         }
  15971.         if (isset($this->cssManager->CSS['BODY']['FONT-WEIGHT'])) {
  15972.             $bodystyle['FONT-WEIGHT'] = $this->cssManager->CSS['BODY']['FONT-WEIGHT'];
  15973.         }
  15974.         if (isset($this->cssManager->CSS['BODY']['COLOR'])) {
  15975.             $bodystyle['COLOR'] = $this->cssManager->CSS['BODY']['COLOR'];
  15976.         }
  15977.         if (isset($bodystyle)) {
  15978.             $this->setCSS($bodystyle'BLOCK''BODY');
  15979.         }
  15980.     }
  15981.     /* -- HTML-CSS -- */
  15982.     function ReadMetaTags($html)
  15983.     {
  15984.         // changes anykey=anyvalue to anykey="anyvalue" (only do this when this happens inside tags)
  15985.         $regexp '/ (\\w+?)=([^\\s>"]+)/si';
  15986.         $html preg_replace($regexp" \$1=\"\$2\""$html);
  15987.         if (preg_match('/<title>(.*?)<\/title>/si'$html$m)) {
  15988.             $this->SetTitle($m[1]);
  15989.         }
  15990.         preg_match_all('/<meta [^>]*?(name|content)="([^>]*?)" [^>]*?(name|content)="([^>]*?)".*?>/si'$html$aux);
  15991.         $firstattr $aux[1];
  15992.         $secondattr $aux[3];
  15993.         for ($i 0$i count($aux[0]); $i++) {
  15994.             $name = ( strtoupper($firstattr[$i]) == "NAME" ) ? strtoupper($aux[2][$i]) : strtoupper($aux[4][$i]);
  15995.             $content = ( strtoupper($firstattr[$i]) == "CONTENT" ) ? $aux[2][$i] : $aux[4][$i];
  15996.             switch ($name) {
  15997.                 case "KEYWORDS":
  15998.                     $this->SetKeywords($content);
  15999.                     break;
  16000.                 case "AUTHOR":
  16001.                     $this->SetAuthor($content);
  16002.                     break;
  16003.                 case "DESCRIPTION":
  16004.                     $this->SetSubject($content);
  16005.                     break;
  16006.             }
  16007.         }
  16008.     }
  16009.     function ReadCharset($html)
  16010.     {
  16011.         // Charset conversion
  16012.         if ($this->allow_charset_conversion) {
  16013.             if (preg_match('/<head.*charset=([^\'\"\s]*).*<\/head>/si'$html$m)) {
  16014.                 if (strtoupper($m[1]) != 'UTF-8') {
  16015.                     $this->charset_in strtoupper($m[1]);
  16016.                 }
  16017.             }
  16018.         }
  16019.     }
  16020.     function setCSS($arrayaux$type ''$tag '')
  16021.     {
  16022.     // type= INLINE | BLOCK | TABLECELL // tag= BODY
  16023.         if (!is_array($arrayaux)) {
  16024.             return; // Removes PHP Warning
  16025.         }
  16026.         // mPDF 5.7.3  inline text-decoration parameters
  16027.         $preceeding_fontkey $this->FontFamily $this->FontStyle;
  16028.         $preceeding_fontsize $this->FontSize;
  16029.         $spanbordset false;
  16030.         $spanbgset false;
  16031.         // mPDF 6
  16032.         $prevlevel = (($this->blklvl == 0) ? $this->blklvl 1);
  16033.         // Set font size first so that e.g. MARGIN 0.83em works on font size for this element
  16034.         if (isset($arrayaux['FONT-SIZE'])) {
  16035.             $v $arrayaux['FONT-SIZE'];
  16036.             $firstLetter substr($v01);
  16037.             if (is_numeric($firstLetter) || ($firstLetter === '.')) {
  16038.                 if ($type == 'BLOCK' && $this->blklvl && isset($this->blk[$this->blklvl 1]['InlineProperties']) && isset($this->blk[$this->blklvl 1]['InlineProperties']['size'])) {
  16039.                     $mmsize $this->sizeConverter->convert($v$this->blk[$this->blklvl 1]['InlineProperties']['size']);
  16040.                 } elseif ($type == 'TABLECELL') {
  16041.                     $mmsize $this->sizeConverter->convert($v$this->default_font_size Mpdf::SCALE);
  16042.                 } else {
  16043.                     $mmsize $this->sizeConverter->convert($v$this->FontSize);
  16044.                 }
  16045.                 $this->SetFontSize($mmsize * (Mpdf::SCALE), false); // Get size in points (pt)
  16046.             } else {
  16047.                 $v strtoupper($v);
  16048.                 if (isset($this->fontsizes[$v])) {
  16049.                     $this->SetFontSize($this->fontsizes[$v] * $this->default_font_sizefalse);
  16050.                 }
  16051.             }
  16052.             if ($tag == 'BODY') {
  16053.                 $this->SetDefaultFontSize($this->FontSizePt);
  16054.             }
  16055.         }
  16056.         // mPDF 6
  16057.         if (isset($arrayaux['LANG']) && $arrayaux['LANG']) {
  16058.             if ($this->autoLangToFont && !$this->usingCoreFont) {
  16059.                 if ($arrayaux['LANG'] != $this->default_lang && $arrayaux['LANG'] != 'UTF-8') {
  16060.                     list ($coreSuitable$mpdf_pdf_unifont) = $this->languageToFont->getLanguageOptions($arrayaux['LANG'], $this->useAdobeCJK);
  16061.                     if ($mpdf_pdf_unifont) {
  16062.                         $arrayaux['FONT-FAMILY'] = $mpdf_pdf_unifont;
  16063.                     }
  16064.                     if ($tag == 'BODY') {
  16065.                         $this->default_lang $arrayaux['LANG'];
  16066.                     }
  16067.                 }
  16068.             }
  16069.             $this->currentLang $arrayaux['LANG'];
  16070.         }
  16071.         // FOR INLINE and BLOCK OR 'BODY'
  16072.         if (isset($arrayaux['FONT-FAMILY'])) {
  16073.             $v $arrayaux['FONT-FAMILY'];
  16074.             // If it is a font list, get all font types
  16075.             $aux_fontlist explode(","$v);
  16076.             $found 0;
  16077.             foreach ($aux_fontlist as $f) {
  16078.                 $fonttype trim($f);
  16079.                 $fonttype preg_replace('/["\']*(.*?)["\']*/''\\1'$fonttype);
  16080.                 $fonttype preg_replace('/ /'''$fonttype);
  16081.                 $v strtolower(trim($fonttype));
  16082.                 if (isset($this->fonttrans[$v]) && $this->fonttrans[$v]) {
  16083.                     $v $this->fonttrans[$v];
  16084.                 }
  16085.                 if ((!$this->onlyCoreFonts && in_array($v$this->available_unifonts)) ||
  16086.                     in_array($v, ['ccourier''ctimes''chelvetica']) ||
  16087.                     ($this->onlyCoreFonts && in_array($v, ['courier''times''helvetica''arial'])) ||
  16088.                     in_array($v, ['sjis''uhc''big5''gb'])) {
  16089.                     $fonttype $v;
  16090.                     $found 1;
  16091.                     break;
  16092.                 }
  16093.             }
  16094.             if (!$found) {
  16095.                 foreach ($aux_fontlist as $f) {
  16096.                     $fonttype trim($f);
  16097.                     $fonttype preg_replace('/["\']*(.*?)["\']*/''\\1'$fonttype);
  16098.                     $fonttype preg_replace('/ /'''$fonttype);
  16099.                     $v strtolower(trim($fonttype));
  16100.                     if (isset($this->fonttrans[$v]) && $this->fonttrans[$v]) {
  16101.                         $v $this->fonttrans[$v];
  16102.                     }
  16103.                     if (in_array($v$this->sans_fonts) || in_array($v$this->serif_fonts) || in_array($v$this->mono_fonts)) {
  16104.                         $fonttype $v;
  16105.                         break;
  16106.                     }
  16107.                 }
  16108.             }
  16109.             if ($tag == 'BODY') {
  16110.                 $this->SetDefaultFont($fonttype);
  16111.             }
  16112.             $this->SetFont($fonttype$this->currentfontstyle0false);
  16113.         } else {
  16114.             $this->SetFont($this->currentfontfamily$this->currentfontstyle0false);
  16115.         }
  16116.         foreach ($arrayaux as $k => $v) {
  16117.             if ($type != 'INLINE' && $tag != 'BODY' && $type != 'TABLECELL') {
  16118.                 switch ($k) {
  16119.                     // BORDERS
  16120.                     case 'BORDER-TOP':
  16121.                         $this->blk[$this->blklvl]['border_top'] = $this->border_details($v);
  16122.                         if ($this->blk[$this->blklvl]['border_top']['s']) {
  16123.                             $this->blk[$this->blklvl]['border'] = 1;
  16124.                         }
  16125.                         break;
  16126.                     case 'BORDER-BOTTOM':
  16127.                         $this->blk[$this->blklvl]['border_bottom'] = $this->border_details($v);
  16128.                         if ($this->blk[$this->blklvl]['border_bottom']['s']) {
  16129.                             $this->blk[$this->blklvl]['border'] = 1;
  16130.                         }
  16131.                         break;
  16132.                     case 'BORDER-LEFT':
  16133.                         $this->blk[$this->blklvl]['border_left'] = $this->border_details($v);
  16134.                         if ($this->blk[$this->blklvl]['border_left']['s']) {
  16135.                             $this->blk[$this->blklvl]['border'] = 1;
  16136.                         }
  16137.                         break;
  16138.                     case 'BORDER-RIGHT':
  16139.                         $this->blk[$this->blklvl]['border_right'] = $this->border_details($v);
  16140.                         if ($this->blk[$this->blklvl]['border_right']['s']) {
  16141.                             $this->blk[$this->blklvl]['border'] = 1;
  16142.                         }
  16143.                         break;
  16144.                     // PADDING
  16145.                     case 'PADDING-TOP':
  16146.                         $this->blk[$this->blklvl]['padding_top'] = $this->sizeConverter->convert($v$this->blk[$prevlevel]['inner_width'], $this->FontSizefalse);
  16147.                         break;
  16148.                     case 'PADDING-BOTTOM':
  16149.                         $this->blk[$this->blklvl]['padding_bottom'] = $this->sizeConverter->convert($v$this->blk[$prevlevel]['inner_width'], $this->FontSizefalse);
  16150.                         break;
  16151.                     case 'PADDING-LEFT':
  16152.                         if (($tag == 'UL' || $tag == 'OL') && $v == 'auto') {
  16153.                             $this->blk[$this->blklvl]['padding_left'] = 'auto';
  16154.                             break;
  16155.                         }
  16156.                         $this->blk[$this->blklvl]['padding_left'] = $this->sizeConverter->convert($v$this->blk[$prevlevel]['inner_width'], $this->FontSizefalse);
  16157.                         break;
  16158.                     case 'PADDING-RIGHT':
  16159.                         if (($tag == 'UL' || $tag == 'OL') && $v == 'auto') {
  16160.                             $this->blk[$this->blklvl]['padding_right'] = 'auto';
  16161.                             break;
  16162.                         }
  16163.                         $this->blk[$this->blklvl]['padding_right'] = $this->sizeConverter->convert($v$this->blk[$prevlevel]['inner_width'], $this->FontSizefalse);
  16164.                         break;
  16165.                     // MARGINS
  16166.                     case 'MARGIN-TOP':
  16167.                         $tmp $this->sizeConverter->convert($v$this->blk[$prevlevel]['inner_width'], $this->FontSizefalse);
  16168.                         if (isset($this->blk[$this->blklvl]['lastbottommargin'])) {
  16169.                             if ($tmp $this->blk[$this->blklvl]['lastbottommargin']) {
  16170.                                 $tmp -= $this->blk[$this->blklvl]['lastbottommargin'];
  16171.                             } else {
  16172.                                 $tmp 0;
  16173.                             }
  16174.                         }
  16175.                         $this->blk[$this->blklvl]['margin_top'] = $tmp;
  16176.                         break;
  16177.                     case 'MARGIN-BOTTOM':
  16178.                         $this->blk[$this->blklvl]['margin_bottom'] = $this->sizeConverter->convert($v$this->blk[$prevlevel]['inner_width'], $this->FontSizefalse);
  16179.                         break;
  16180.                     case 'MARGIN-LEFT':
  16181.                         $this->blk[$this->blklvl]['margin_left'] = $this->sizeConverter->convert($v$this->blk[$prevlevel]['inner_width'], $this->FontSizefalse);
  16182.                         break;
  16183.                     case 'MARGIN-RIGHT':
  16184.                         $this->blk[$this->blklvl]['margin_right'] = $this->sizeConverter->convert($v$this->blk[$prevlevel]['inner_width'], $this->FontSizefalse);
  16185.                         break;
  16186.                     /* -- BORDER-RADIUS -- */
  16187.                     case 'BORDER-TOP-LEFT-RADIUS-H':
  16188.                         $this->blk[$this->blklvl]['border_radius_TL_H'] = $this->sizeConverter->convert($v$this->blk[$prevlevel]['inner_width'], $this->FontSizefalse);
  16189.                         break;
  16190.                     case 'BORDER-TOP-LEFT-RADIUS-V':
  16191.                         $this->blk[$this->blklvl]['border_radius_TL_V'] = $this->sizeConverter->convert($v$this->blk[$prevlevel]['inner_width'], $this->FontSizefalse);
  16192.                         break;
  16193.                     case 'BORDER-TOP-RIGHT-RADIUS-H':
  16194.                         $this->blk[$this->blklvl]['border_radius_TR_H'] = $this->sizeConverter->convert($v$this->blk[$prevlevel]['inner_width'], $this->FontSizefalse);
  16195.                         break;
  16196.                     case 'BORDER-TOP-RIGHT-RADIUS-V':
  16197.                         $this->blk[$this->blklvl]['border_radius_TR_V'] = $this->sizeConverter->convert($v$this->blk[$prevlevel]['inner_width'], $this->FontSizefalse);
  16198.                         break;
  16199.                     case 'BORDER-BOTTOM-LEFT-RADIUS-H':
  16200.                         $this->blk[$this->blklvl]['border_radius_BL_H'] = $this->sizeConverter->convert($v$this->blk[$prevlevel]['inner_width'], $this->FontSizefalse);
  16201.                         break;
  16202.                     case 'BORDER-BOTTOM-LEFT-RADIUS-V':
  16203.                         $this->blk[$this->blklvl]['border_radius_BL_V'] = $this->sizeConverter->convert($v$this->blk[$prevlevel]['inner_width'], $this->FontSizefalse);
  16204.                         break;
  16205.                     case 'BORDER-BOTTOM-RIGHT-RADIUS-H':
  16206.                         $this->blk[$this->blklvl]['border_radius_BR_H'] = $this->sizeConverter->convert($v$this->blk[$prevlevel]['inner_width'], $this->FontSizefalse);
  16207.                         break;
  16208.                     case 'BORDER-BOTTOM-RIGHT-RADIUS-V':
  16209.                         $this->blk[$this->blklvl]['border_radius_BR_V'] = $this->sizeConverter->convert($v$this->blk[$prevlevel]['inner_width'], $this->FontSizefalse);
  16210.                         break;
  16211.                     /* -- END BORDER-RADIUS -- */
  16212.                     case 'BOX-SHADOW':
  16213.                         $bs $this->cssManager->setCSSboxshadow($v);
  16214.                         if ($bs) {
  16215.                             $this->blk[$this->blklvl]['box_shadow'] = $bs;
  16216.                         }
  16217.                         break;
  16218.                     case 'BACKGROUND-CLIP':
  16219.                         if (strtoupper($v) == 'PADDING-BOX') {
  16220.                             $this->blk[$this->blklvl]['background_clip'] = 'padding-box';
  16221.                         } elseif (strtoupper($v) == 'CONTENT-BOX') {
  16222.                             $this->blk[$this->blklvl]['background_clip'] = 'content-box';
  16223.                         }
  16224.                         break;
  16225.                     case 'PAGE-BREAK-AFTER':
  16226.                         if (strtoupper($v) == 'AVOID') {
  16227.                             $this->blk[$this->blklvl]['page_break_after_avoid'] = true;
  16228.                         } elseif (strtoupper($v) == 'ALWAYS' || strtoupper($v) == 'LEFT' || strtoupper($v) == 'RIGHT') {
  16229.                             $this->blk[$this->blklvl]['page_break_after'] = strtoupper($v);
  16230.                         }
  16231.                         break;
  16232.                     // mPDF 6 pagebreaktype
  16233.                     case 'BOX-DECORATION-BREAK':
  16234.                         if (strtoupper($v) == 'CLONE') {
  16235.                             $this->blk[$this->blklvl]['box_decoration_break'] = 'clone';
  16236.                         } elseif (strtoupper($v) == 'SLICE') {
  16237.                             $this->blk[$this->blklvl]['box_decoration_break'] = 'slice';
  16238.                         }
  16239.                         break;
  16240.                     case 'WIDTH':
  16241.                         if (strtoupper($v) != 'AUTO') {
  16242.                             $this->blk[$this->blklvl]['css_set_width'] = $this->sizeConverter->convert($v$this->blk[$prevlevel]['inner_width'], $this->FontSizefalse);
  16243.                         }
  16244.                         break;
  16245.                     // mPDF 6  Lists
  16246.                     // LISTS
  16247.                     case 'LIST-STYLE-TYPE':
  16248.                         $this->blk[$this->blklvl]['list_style_type'] = strtolower($v);
  16249.                         break;
  16250.                     case 'LIST-STYLE-IMAGE':
  16251.                         $this->blk[$this->blklvl]['list_style_image'] = strtolower($v);
  16252.                         break;
  16253.                     case 'LIST-STYLE-POSITION':
  16254.                         $this->blk[$this->blklvl]['list_style_position'] = strtolower($v);
  16255.                         break;
  16256.                 }//end of switch($k)
  16257.             }
  16258.             if ($type != 'INLINE' && $type != 'TABLECELL') { // All block-level, including BODY tag
  16259.                 switch ($k) {
  16260.                     case 'TEXT-INDENT':
  16261.                         // Computed value - to inherit
  16262.                         $this->blk[$this->blklvl]['text_indent'] = $this->sizeConverter->convert($v$this->blk[$prevlevel]['inner_width'], $this->FontSizefalse) . 'mm';
  16263.                         break;
  16264.                     case 'MARGIN-COLLAPSE'// Custom tag to collapse margins at top and bottom of page
  16265.                         if (strtoupper($v) == 'COLLAPSE') {
  16266.                             $this->blk[$this->blklvl]['margin_collapse'] = true;
  16267.                         }
  16268.                         break;
  16269.                     case 'LINE-HEIGHT':
  16270.                         $this->blk[$this->blklvl]['line_height'] = $this->fixLineheight($v);
  16271.                         if (!$this->blk[$this->blklvl]['line_height']) {
  16272.                             $this->blk[$this->blklvl]['line_height'] = 'N';
  16273.                         } // mPDF 6
  16274.                         break;
  16275.                     // mPDF 6
  16276.                     case 'LINE-STACKING-STRATEGY':
  16277.                         $this->blk[$this->blklvl]['line_stacking_strategy'] = strtolower($v);
  16278.                         break;
  16279.                     case 'LINE-STACKING-SHIFT':
  16280.                         $this->blk[$this->blklvl]['line_stacking_shift'] = strtolower($v);
  16281.                         break;
  16282.                     case 'TEXT-ALIGN'// left right center justify
  16283.                         switch (strtoupper($v)) {
  16284.                             case 'LEFT':
  16285.                                 $this->blk[$this->blklvl]['align'] = "L";
  16286.                                 break;
  16287.                             case 'CENTER':
  16288.                                 $this->blk[$this->blklvl]['align'] = "C";
  16289.                                 break;
  16290.                             case 'RIGHT':
  16291.                                 $this->blk[$this->blklvl]['align'] = "R";
  16292.                                 break;
  16293.                             case 'JUSTIFY':
  16294.                                 $this->blk[$this->blklvl]['align'] = "J";
  16295.                                 break;
  16296.                         }
  16297.                         break;
  16298.                     /* -- BACKGROUNDS -- */
  16299.                     case 'BACKGROUND-GRADIENT':
  16300.                         if ($type == 'BLOCK') {
  16301.                             $this->blk[$this->blklvl]['gradient'] = $v;
  16302.                         }
  16303.                         break;
  16304.                     /* -- END BACKGROUNDS -- */
  16305.                     case 'DIRECTION':
  16306.                         if ($v) {
  16307.                             $this->blk[$this->blklvl]['direction'] = strtolower($v);
  16308.                         }
  16309.                         break;
  16310.                 }
  16311.             }
  16312.             // FOR INLINE ONLY
  16313.             if ($type == 'INLINE') {
  16314.                 switch ($k) {
  16315.                     case 'DISPLAY':
  16316.                         if (strtoupper($v) == 'NONE') {
  16317.                             $this->inlineDisplayOff true;
  16318.                         }
  16319.                         break;
  16320.                     case 'DIRECTION':
  16321.                         break;
  16322.                 }
  16323.             }
  16324.             // FOR INLINE ONLY
  16325.             if ($type == 'INLINE') {
  16326.                 switch ($k) {
  16327.                     // BORDERS
  16328.                     case 'BORDER-TOP':
  16329.                         $this->spanborddet['T'] = $this->border_details($v);
  16330.                         $this->spanborder true;
  16331.                         $spanbordset true;
  16332.                         break;
  16333.                     case 'BORDER-BOTTOM':
  16334.                         $this->spanborddet['B'] = $this->border_details($v);
  16335.                         $this->spanborder true;
  16336.                         $spanbordset true;
  16337.                         break;
  16338.                     case 'BORDER-LEFT':
  16339.                         $this->spanborddet['L'] = $this->border_details($v);
  16340.                         $this->spanborder true;
  16341.                         $spanbordset true;
  16342.                         break;
  16343.                     case 'BORDER-RIGHT':
  16344.                         $this->spanborddet['R'] = $this->border_details($v);
  16345.                         $this->spanborder true;
  16346.                         $spanbordset true;
  16347.                         break;
  16348.                     case 'VISIBILITY'// block is set in OpenTag
  16349.                         $v strtolower($v);
  16350.                         if ($v == 'visible' || $v == 'hidden' || $v == 'printonly' || $v == 'screenonly') {
  16351.                             $this->textparam['visibility'] = $v;
  16352.                         }
  16353.                         break;
  16354.                 }//end of switch($k)
  16355.             }
  16356.             if ($type != 'TABLECELL') {
  16357.                 // FOR INLINE and BLOCK
  16358.                 switch ($k) {
  16359.                     case 'TEXT-ALIGN'// left right center justify
  16360.                         if (strtoupper($v) == 'NOJUSTIFY' && $this->blk[$this->blklvl]['align'] == "J") {
  16361.                             $this->blk[$this->blklvl]['align'] = "";
  16362.                         }
  16363.                         break;
  16364.                     // bgcolor only - to stay consistent with original html2fpdf
  16365.                     case 'BACKGROUND':
  16366.                     case 'BACKGROUND-COLOR':
  16367.                         $cor $this->colorConverter->convert($v$this->PDFAXwarnings);
  16368.                         if ($cor) {
  16369.                             if ($tag == 'BODY') {
  16370.                                 $this->bodyBackgroundColor $cor;
  16371.                             } elseif ($type == 'INLINE') {
  16372.                                 $this->spanbgcolorarray $cor;
  16373.                                 $this->spanbgcolor true;
  16374.                                 $spanbgset true;
  16375.                             } else {
  16376.                                 $this->blk[$this->blklvl]['bgcolorarray'] = $cor;
  16377.                                 $this->blk[$this->blklvl]['bgcolor'] = true;
  16378.                             }
  16379.                         } elseif ($type != 'INLINE') {
  16380.                             if ($this->ColActive) {
  16381.                                 $this->blk[$this->blklvl]['bgcolorarray'] = $this->blk[$prevlevel]['bgcolorarray'];
  16382.                                 $this->blk[$this->blklvl]['bgcolor'] = $this->blk[$prevlevel]['bgcolor'];
  16383.                             }
  16384.                         }
  16385.                         break;
  16386.                     case 'VERTICAL-ALIGN'// super and sub only dealt with here e.g. <SUB> and <SUP>
  16387.                         switch (strtoupper($v)) {
  16388.                             case 'SUPER':
  16389.                                 $this->textvar = ($this->textvar TextVars::FA_SUPERSCRIPT); // mPDF 5.7.1
  16390.                                 $this->textvar = ($this->textvar & ~TextVars::FA_SUBSCRIPT);
  16391.                                 // mPDF 5.7.3  inline text-decoration parameters
  16392.                                 if (isset($this->textparam['text-baseline'])) {
  16393.                                     $this->textparam['text-baseline'] += ($this->baselineSup) * $preceeding_fontsize;
  16394.                                 } else {
  16395.                                     $this->textparam['text-baseline'] = ($this->baselineSup) * $preceeding_fontsize;
  16396.                                 }
  16397.                                 break;
  16398.                             case 'SUB':
  16399.                                 $this->textvar = ($this->textvar TextVars::FA_SUBSCRIPT);
  16400.                                 $this->textvar = ($this->textvar & ~TextVars::FA_SUPERSCRIPT);
  16401.                                 // mPDF 5.7.3  inline text-decoration parameters
  16402.                                 if (isset($this->textparam['text-baseline'])) {
  16403.                                     $this->textparam['text-baseline'] += ($this->baselineSub) * $preceeding_fontsize;
  16404.                                 } else {
  16405.                                     $this->textparam['text-baseline'] = ($this->baselineSub) * $preceeding_fontsize;
  16406.                                 }
  16407.                                 break;
  16408.                             case 'BASELINE':
  16409.                                 $this->textvar = ($this->textvar & ~TextVars::FA_SUBSCRIPT);
  16410.                                 $this->textvar = ($this->textvar & ~TextVars::FA_SUPERSCRIPT);
  16411.                                 // mPDF 5.7.3  inline text-decoration parameters
  16412.                                 if (isset($this->textparam['text-baseline'])) {
  16413.                                     unset($this->textparam['text-baseline']);
  16414.                                 }
  16415.                                 break;
  16416.                             // mPDF 5.7.3  inline text-decoration parameters
  16417.                             default:
  16418.                                 $lh $this->_computeLineheight($this->blk[$this->blklvl]['line_height']);
  16419.                                 $sz $this->sizeConverter->convert($v$lh$this->FontSizefalse);
  16420.                                 $this->textvar = ($this->textvar & ~TextVars::FA_SUBSCRIPT);
  16421.                                 $this->textvar = ($this->textvar & ~TextVars::FA_SUPERSCRIPT);
  16422.                                 if ($sz) {
  16423.                                     if ($sz 0) {
  16424.                                         $this->textvar = ($this->textvar TextVars::FA_SUPERSCRIPT);
  16425.                                     } else {
  16426.                                         $this->textvar = ($this->textvar TextVars::FA_SUBSCRIPT);
  16427.                                     }
  16428.                                     if (isset($this->textparam['text-baseline'])) {
  16429.                                         $this->textparam['text-baseline'] += $sz;
  16430.                                     } else {
  16431.                                         $this->textparam['text-baseline'] = $sz;
  16432.                                     }
  16433.                                 }
  16434.                         }
  16435.                         break;
  16436.                 }//end of switch($k)
  16437.             }
  16438.             // FOR ALL
  16439.             switch ($k) {
  16440.                 case 'LETTER-SPACING':
  16441.                     $this->lSpacingCSS $v;
  16442.                     if (($this->lSpacingCSS || $this->lSpacingCSS === '0') && strtoupper($this->lSpacingCSS) != 'NORMAL') {
  16443.                         $this->fixedlSpacing $this->sizeConverter->convert($this->lSpacingCSS$this->FontSize);
  16444.                     }
  16445.                     break;
  16446.                 case 'WORD-SPACING':
  16447.                     $this->wSpacingCSS $v;
  16448.                     if ($this->wSpacingCSS && strtoupper($this->wSpacingCSS) != 'NORMAL') {
  16449.                         $this->minwSpacing $this->sizeConverter->convert($this->wSpacingCSS$this->FontSize);
  16450.                     }
  16451.                     break;
  16452.                 case 'FONT-STYLE'// italic normal oblique
  16453.                     switch (strtoupper($v)) {
  16454.                         case 'ITALIC':
  16455.                         case 'OBLIQUE':
  16456.                             $this->SetStyle('I'true);
  16457.                             break;
  16458.                         case 'NORMAL':
  16459.                             $this->SetStyle('I'false);
  16460.                             break;
  16461.                     }
  16462.                     break;
  16463.                 case 'FONT-WEIGHT'// normal bold // Does not support: bolder, lighter, 100..900(step value=100)
  16464.                     switch (strtoupper($v)) {
  16465.                         case 'BOLD':
  16466.                             $this->SetStyle('B'true);
  16467.                             break;
  16468.                         case 'NORMAL':
  16469.                             $this->SetStyle('B'false);
  16470.                             break;
  16471.                     }
  16472.                     break;
  16473.                 case 'FONT-KERNING':
  16474.                     if (strtoupper($v) == 'NORMAL' || (strtoupper($v) == 'AUTO' && $this->useKerning)) {
  16475.                         /* -- OTL -- */
  16476.                         if ($this->CurrentFont['haskernGPOS']) {
  16477.                             if (isset($this->OTLtags['Plus'])) {
  16478.                                 $this->OTLtags['Plus'] .= ' kern';
  16479.                             } else {
  16480.                                 $this->OTLtags['Plus'] = ' kern';
  16481.                             }
  16482.                         } /* -- END OTL -- */ else {  // *OTL*
  16483.                             $this->textvar = ($this->textvar TextVars::FC_KERNING);
  16484.                         } // *OTL*
  16485.                     } elseif (strtoupper($v) == 'NONE' || (strtoupper($v) == 'AUTO' && !$this->useKerning)) {
  16486.                         if (isset($this->OTLtags['Plus'])) {
  16487.                             $this->OTLtags['Plus'] = str_replace('kern'''$this->OTLtags['Plus']); // *OTL*
  16488.                         }
  16489.                         if (isset($this->OTLtags['FFPlus'])) {
  16490.                             $this->OTLtags['FFPlus'] = preg_replace('/kern[\d]*/'''$this->OTLtags['FFPlus']);
  16491.                         }
  16492.                         $this->textvar = ($this->textvar & ~TextVars::FC_KERNING);
  16493.                     }
  16494.                     break;
  16495.                 /* -- OTL -- */
  16496.                 case 'FONT-LANGUAGE-OVERRIDE':
  16497.                     $v strtoupper($v);
  16498.                     if (strpos($v'NORMAL') !== false) {
  16499.                         $this->fontLanguageOverride '';
  16500.                     } else {
  16501.                         $this->fontLanguageOverride trim($v);
  16502.                     }
  16503.                     break;
  16504.                 case 'FONT-VARIANT-POSITION':
  16505.                     if (isset($this->OTLtags['Plus'])) {
  16506.                         $this->OTLtags['Plus'] = str_replace(['sups''subs'], ''$this->OTLtags['Plus']);
  16507.                     }
  16508.                     switch (strtoupper($v)) {
  16509.                         case 'SUPER':
  16510.                             $this->OTLtags['Plus'] .= ' sups';
  16511.                             break;
  16512.                         case 'SUB':
  16513.                             $this->OTLtags['Plus'] .= ' subs';
  16514.                             break;
  16515.                         case 'NORMAL':
  16516.                             break;
  16517.                     }
  16518.                     break;
  16519.                 case 'FONT-VARIANT-CAPS':
  16520.                     $v strtoupper($v);
  16521.                     if (!isset($this->OTLtags['Plus'])) {
  16522.                         $this->OTLtags['Plus'] = '';
  16523.                     }
  16524.                     $this->OTLtags['Plus'] = str_replace(['c2sc''smcp''c2pc''pcap''unic''titl'], ''$this->OTLtags['Plus']);
  16525.                     $this->textvar = ($this->textvar & ~TextVars::FC_SMALLCAPS);   // ?????????????? <small-caps>
  16526.                     if (strpos($v'ALL-SMALL-CAPS') !== false) {
  16527.                         $this->OTLtags['Plus'] .= ' c2sc smcp';
  16528.                     } elseif (strpos($v'SMALL-CAPS') !== false) {
  16529.                         if (isset($this->CurrentFont['hassmallcapsGSUB']) && $this->CurrentFont['hassmallcapsGSUB']) {
  16530.                             $this->OTLtags['Plus'] .= ' smcp';
  16531.                         } else {
  16532.                             $this->textvar = ($this->textvar TextVars::FC_SMALLCAPS);
  16533.                         }
  16534.                     } elseif (strpos($v'ALL-PETITE-CAPS') !== false) {
  16535.                         $this->OTLtags['Plus'] .= ' c2pc pcap';
  16536.                     } elseif (strpos($v'PETITE-CAPS') !== false) {
  16537.                         $this->OTLtags['Plus'] .= ' pcap';
  16538.                     } elseif (strpos($v'UNICASE') !== false) {
  16539.                         $this->OTLtags['Plus'] .= ' unic';
  16540.                     } elseif (strpos($v'TITLING-CAPS') !== false) {
  16541.                         $this->OTLtags['Plus'] .= ' titl';
  16542.                     }
  16543.                     break;
  16544.                 case 'FONT-VARIANT-LIGATURES':
  16545.                     $v strtoupper($v);
  16546.                     if (!isset($this->OTLtags['Plus'])) {
  16547.                         $this->OTLtags['Plus'] = '';
  16548.                     }
  16549.                     if (!isset($this->OTLtags['Minus'])) {
  16550.                         $this->OTLtags['Minus'] = '';
  16551.                     }
  16552.                     if (strpos($v'NORMAL') !== false) {
  16553.                         $this->OTLtags['Minus'] = str_replace(['liga''clig''calt'], ''$this->OTLtags['Minus']);
  16554.                         $this->OTLtags['Plus'] = str_replace(['dlig''hlig'], ''$this->OTLtags['Plus']);
  16555.                     } elseif (strpos($v'NONE') !== false) {
  16556.                         $this->OTLtags['Minus'] .= ' liga clig calt';
  16557.                         $this->OTLtags['Plus'] = str_replace(['dlig''hlig'], ''$this->OTLtags['Plus']);
  16558.                     }
  16559.                     if (strpos($v'NO-COMMON-LIGATURES') !== false) {
  16560.                         $this->OTLtags['Minus'] .= ' liga clig';
  16561.                     } elseif (strpos($v'COMMON-LIGATURES') !== false) {
  16562.                         $this->OTLtags['Minus'] = str_replace(['liga''clig'], ''$this->OTLtags['Minus']);
  16563.                     }
  16564.                     if (strpos($v'NO-CONTEXTUAL') !== false) {
  16565.                         $this->OTLtags['Minus'] .= ' calt';
  16566.                     } elseif (strpos($v'CONTEXTUAL') !== false) {
  16567.                         $this->OTLtags['Minus'] = str_replace('calt'''$this->OTLtags['Minus']);
  16568.                     }
  16569.                     if (strpos($v'NO-DISCRETIONARY-LIGATURES') !== false) {
  16570.                         $this->OTLtags['Plus'] = str_replace('dlig'''$this->OTLtags['Plus']);
  16571.                     } elseif (strpos($v'DISCRETIONARY-LIGATURES') !== false) {
  16572.                         $this->OTLtags['Plus'] .= ' dlig';
  16573.                     }
  16574.                     if (strpos($v'NO-HISTORICAL-LIGATURES') !== false) {
  16575.                         $this->OTLtags['Plus'] = str_replace('hlig'''$this->OTLtags['Plus']);
  16576.                     } elseif (strpos($v'HISTORICAL-LIGATURES') !== false) {
  16577.                         $this->OTLtags['Plus'] .= ' hlig';
  16578.                     }
  16579.                     break;
  16580.                 case 'FONT-VARIANT-NUMERIC':
  16581.                     $v strtoupper($v);
  16582.                     if (!isset($this->OTLtags['Plus'])) {
  16583.                         $this->OTLtags['Plus'] = '';
  16584.                     }
  16585.                     if (strpos($v'NORMAL') !== false) {
  16586.                         $this->OTLtags['Plus'] = str_replace(['ordn''zero''lnum''onum''pnum''tnum''frac''afrc'], ''$this->OTLtags['Plus']);
  16587.                     }
  16588.                     if (strpos($v'ORDINAL') !== false) {
  16589.                         $this->OTLtags['Plus'] .= ' ordn';
  16590.                     }
  16591.                     if (strpos($v'SLASHED-ZERO') !== false) {
  16592.                         $this->OTLtags['Plus'] .= ' zero';
  16593.                     }
  16594.                     if (strpos($v'LINING-NUMS') !== false) {
  16595.                         $this->OTLtags['Plus'] .= ' lnum';
  16596.                         $this->OTLtags['Plus'] = str_replace('onum'''$this->OTLtags['Plus']);
  16597.                     } elseif (strpos($v'OLDSTYLE-NUMS') !== false) {
  16598.                         $this->OTLtags['Plus'] .= ' onum';
  16599.                         $this->OTLtags['Plus'] = str_replace('lnum'''$this->OTLtags['Plus']);
  16600.                     }
  16601.                     if (strpos($v'PROPORTIONAL-NUMS') !== false) {
  16602.                         $this->OTLtags['Plus'] .= ' pnum';
  16603.                         $this->OTLtags['Plus'] = str_replace('tnum'''$this->OTLtags['Plus']);
  16604.                     } elseif (strpos($v'TABULAR-NUMS') !== false) {
  16605.                         $this->OTLtags['Plus'] .= ' tnum';
  16606.                         $this->OTLtags['Plus'] = str_replace('pnum'''$this->OTLtags['Plus']);
  16607.                     }
  16608.                     if (strpos($v'DIAGONAL-FRACTIONS') !== false) {
  16609.                         $this->OTLtags['Plus'] .= ' frac';
  16610.                         $this->OTLtags['Plus'] = str_replace('afrc'''$this->OTLtags['Plus']);
  16611.                     } elseif (strpos($v'STACKED-FRACTIONS') !== false) {
  16612.                         $this->OTLtags['Plus'] .= ' afrc';
  16613.                         $this->OTLtags['Plus'] = str_replace('frac'''$this->OTLtags['Plus']);
  16614.                     }
  16615.                     break;
  16616.                 case 'FONT-VARIANT-ALTERNATES':  // Only supports historical-forms
  16617.                     $v strtoupper($v);
  16618.                     if (!isset($this->OTLtags['Plus'])) {
  16619.                         $this->OTLtags['Plus'] = '';
  16620.                     }
  16621.                     if (strpos($v'NORMAL') !== false) {
  16622.                         $this->OTLtags['Plus'] = str_replace('hist'''$this->OTLtags['Plus']);
  16623.                     }
  16624.                     if (strpos($v'HISTORICAL-FORMS') !== false) {
  16625.                         $this->OTLtags['Plus'] .= ' hist';
  16626.                     }
  16627.                     break;
  16628.                 case 'FONT-FEATURE-SETTINGS':
  16629.                     $v strtolower($v);
  16630.                     if (strpos($v'normal') !== false) {
  16631.                         $this->OTLtags['FFMinus'] = '';
  16632.                         $this->OTLtags['FFPlus'] = '';
  16633.                     } else {
  16634.                         if (!isset($this->OTLtags['FFPlus'])) {
  16635.                             $this->OTLtags['FFPlus'] = '';
  16636.                         }
  16637.                         if (!isset($this->OTLtags['FFMinus'])) {
  16638.                             $this->OTLtags['FFMinus'] = '';
  16639.                         }
  16640.                         $tags preg_split('/[,]/'$v);
  16641.                         foreach ($tags as $t) {
  16642.                             if (preg_match('/[\"\']([a-zA-Z0-9]{4})[\"\']\s*(on|off|\d*){0,1}/'$t$m)) {
  16643.                                 if ($m[2] == 'off' || $m[2] === '0') {
  16644.                                     if (strpos($this->OTLtags['FFMinus'], $m[1]) === false) {
  16645.                                         $this->OTLtags['FFMinus'] .= ' ' $m[1];
  16646.                                     }
  16647.                                     $this->OTLtags['FFPlus'] = preg_replace('/' $m[1] . '[\d]*/'''$this->OTLtags['FFPlus']);
  16648.                                 } else {
  16649.                                     if ($m[2] == 'on') {
  16650.                                         $m[2] = '1';
  16651.                                     }
  16652.                                     if (strpos($this->OTLtags['FFPlus'], $m[1]) === false) {
  16653.                                         $this->OTLtags['FFPlus'] .= ' ' $m[1] . $m[2];
  16654.                                     }
  16655.                                     $this->OTLtags['FFMinus'] = str_replace($m[1], ''$this->OTLtags['FFMinus']);
  16656.                                 }
  16657.                             }
  16658.                         }
  16659.                     }
  16660.                     break;
  16661.                 /* -- END OTL -- */
  16662.                 case 'TEXT-TRANSFORM'// none uppercase lowercase // Does support: capitalize
  16663.                     switch (strtoupper($v)) { // Not working 100%
  16664.                         case 'CAPITALIZE':
  16665.                             $this->textvar = ($this->textvar TextVars::FT_CAPITALIZE); // mPDF 5.7.1
  16666.                             $this->textvar = ($this->textvar & ~TextVars::FT_UPPERCASE); // mPDF 5.7.1
  16667.                             $this->textvar = ($this->textvar & ~TextVars::FT_LOWERCASE); // mPDF 5.7.1
  16668.                             break;
  16669.                         case 'UPPERCASE':
  16670.                             $this->textvar = ($this->textvar TextVars::FT_UPPERCASE); // mPDF 5.7.1
  16671.                             $this->textvar = ($this->textvar & ~TextVars::FT_LOWERCASE); // mPDF 5.7.1
  16672.                             $this->textvar = ($this->textvar & ~TextVars::FT_CAPITALIZE); // mPDF 5.7.1
  16673.                             break;
  16674.                         case 'LOWERCASE':
  16675.                             $this->textvar = ($this->textvar TextVars::FT_LOWERCASE); // mPDF 5.7.1
  16676.                             $this->textvar = ($this->textvar & ~TextVars::FT_UPPERCASE); // mPDF 5.7.1
  16677.                             $this->textvar = ($this->textvar & ~TextVars::FT_CAPITALIZE); // mPDF 5.7.1
  16678.                             break;
  16679.                         case 'NONE':
  16680.                             break;
  16681.                             $this->textvar = ($this->textvar & ~TextVars::FT_UPPERCASE); // mPDF 5.7.1
  16682.                             $this->textvar = ($this->textvar & ~TextVars::FT_LOWERCASE); // mPDF 5.7.1
  16683.                             $this->textvar = ($this->textvar & ~TextVars::FT_CAPITALIZE); // mPDF 5.7.1
  16684.                     }
  16685.                     break;
  16686.                 case 'TEXT-SHADOW':
  16687.                     $ts $this->cssManager->setCSStextshadow($v);
  16688.                     if ($ts) {
  16689.                         $this->textshadow $ts;
  16690.                     }
  16691.                     break;
  16692.                 case 'HYPHENS':
  16693.                     if (strtoupper($v) == 'NONE') {
  16694.                         $this->textparam['hyphens'] = 2;
  16695.                     } elseif (strtoupper($v) == 'AUTO') {
  16696.                         $this->textparam['hyphens'] = 1;
  16697.                     } elseif (strtoupper($v) == 'MANUAL') {
  16698.                         $this->textparam['hyphens'] = 0;
  16699.                     }
  16700.                     break;
  16701.                 case 'TEXT-OUTLINE':
  16702.                     if (strtoupper($v) == 'NONE') {
  16703.                         $this->textparam['outline-s'] = false;
  16704.                     }
  16705.                     break;
  16706.                 case 'TEXT-OUTLINE-WIDTH':
  16707.                 case 'OUTLINE-WIDTH':
  16708.                     switch (strtoupper($v)) {
  16709.                         case 'THIN':
  16710.                             $v '0.03em';
  16711.                             break;
  16712.                         case 'MEDIUM':
  16713.                             $v '0.05em';
  16714.                             break;
  16715.                         case 'THICK':
  16716.                             $v '0.07em';
  16717.                             break;
  16718.                     }
  16719.                     $w $this->sizeConverter->convert($v$this->FontSize$this->FontSize);
  16720.                     if ($w) {
  16721.                         $this->textparam['outline-WIDTH'] = $w;
  16722.                         $this->textparam['outline-s'] = true;
  16723.                     } else {
  16724.                         $this->textparam['outline-s'] = false;
  16725.                     }
  16726.                     break;
  16727.                 case 'TEXT-OUTLINE-COLOR':
  16728.                 case 'OUTLINE-COLOR':
  16729.                     if (strtoupper($v) == 'INVERT') {
  16730.                         if ($this->colorarray) {
  16731.                             $cor $this->colorarray;
  16732.                             $this->textparam['outline-COLOR'] = $this->colorConverter->invert($cor);
  16733.                         } else {
  16734.                             $this->textparam['outline-COLOR'] = $this->colorConverter->convert(255$this->PDFAXwarnings);
  16735.                         }
  16736.                     } else {
  16737.                         $cor $this->colorConverter->convert($v$this->PDFAXwarnings);
  16738.                         if ($cor) {
  16739.                             $this->textparam['outline-COLOR'] = $cor;
  16740.                         }
  16741.                     }
  16742.                     break;
  16743.                 case 'COLOR'// font color
  16744.                     $cor $this->colorConverter->convert($v$this->PDFAXwarnings);
  16745.                     if ($cor) {
  16746.                         $this->colorarray $cor;
  16747.                         $this->SetTColor($cor);
  16748.                     }
  16749.                     break;
  16750.             }//end of switch($k)
  16751.         }//end of foreach
  16752.         // mPDF 5.7.3  inline text-decoration parameters
  16753.         // Needs to be set at the end - after vertical-align = super/sub, so that textparam['text-baseline'] is set
  16754.         if (isset($arrayaux['TEXT-DECORATION'])) {
  16755.             $v $arrayaux['TEXT-DECORATION']; // none underline line-through (strikeout) // Does not support: blink
  16756.             if (stristr($v'LINE-THROUGH')) {
  16757.                 $this->textvar = ($this->textvar TextVars::FD_LINETHROUGH);
  16758.                 // mPDF 5.7.3  inline text-decoration parameters
  16759.                 if (isset($this->textparam['text-baseline'])) {
  16760.                     $this->textparam['s-decoration']['baseline'] = $this->textparam['text-baseline'];
  16761.                 } else {
  16762.                     $this->textparam['s-decoration']['baseline'] = 0;
  16763.                 }
  16764.                 $this->textparam['s-decoration']['fontkey'] = $this->FontFamily $this->FontStyle;
  16765.                 $this->textparam['s-decoration']['fontsize'] = $this->FontSize;
  16766.                 $this->textparam['s-decoration']['color'] = strtoupper($this->TextColor); // change 0 0 0 rg to 0 0 0 RG
  16767.             }
  16768.             if (stristr($v'UNDERLINE')) {
  16769.                 $this->textvar = ($this->textvar TextVars::FD_UNDERLINE);
  16770.                 // mPDF 5.7.3  inline text-decoration parameters
  16771.                 if (isset($this->textparam['text-baseline'])) {
  16772.                     $this->textparam['u-decoration']['baseline'] = $this->textparam['text-baseline'];
  16773.                 } else {
  16774.                     $this->textparam['u-decoration']['baseline'] = 0;
  16775.                 }
  16776.                 $this->textparam['u-decoration']['fontkey'] = $this->FontFamily $this->FontStyle;
  16777.                 $this->textparam['u-decoration']['fontsize'] = $this->FontSize;
  16778.                 $this->textparam['u-decoration']['color'] = strtoupper($this->TextColor); // change 0 0 0 rg to 0 0 0 RG
  16779.             }
  16780.             if (stristr($v'OVERLINE')) {
  16781.                 $this->textvar = ($this->textvar TextVars::FD_OVERLINE);
  16782.                 // mPDF 5.7.3  inline text-decoration parameters
  16783.                 if (isset($this->textparam['text-baseline'])) {
  16784.                     $this->textparam['o-decoration']['baseline'] = $this->textparam['text-baseline'];
  16785.                 } else {
  16786.                     $this->textparam['o-decoration']['baseline'] = 0;
  16787.                 }
  16788.                 $this->textparam['o-decoration']['fontkey'] = $this->FontFamily $this->FontStyle;
  16789.                 $this->textparam['o-decoration']['fontsize'] = $this->FontSize;
  16790.                 $this->textparam['o-decoration']['color'] = strtoupper($this->TextColor); // change 0 0 0 rg to 0 0 0 RG
  16791.             }
  16792.             if (stristr($v'NONE')) {
  16793.                 $this->textvar = ($this->textvar & ~TextVars::FD_UNDERLINE);
  16794.                 $this->textvar = ($this->textvar & ~TextVars::FD_LINETHROUGH);
  16795.                 $this->textvar = ($this->textvar & ~TextVars::FD_OVERLINE);
  16796.                 // mPDF 5.7.3  inline text-decoration parameters
  16797.                 if (isset($this->textparam['u-decoration'])) {
  16798.                     unset($this->textparam['u-decoration']);
  16799.                 }
  16800.                 if (isset($this->textparam['s-decoration'])) {
  16801.                     unset($this->textparam['s-decoration']);
  16802.                 }
  16803.                 if (isset($this->textparam['o-decoration'])) {
  16804.                     unset($this->textparam['o-decoration']);
  16805.                 }
  16806.             }
  16807.         }
  16808.         // mPDF 6
  16809.         if ($spanbordset) { // BORDER has been set on this INLINE element
  16810.             if (isset($this->textparam['text-baseline'])) {
  16811.                 $this->textparam['bord-decoration']['baseline'] = $this->textparam['text-baseline'];
  16812.             } else {
  16813.                 $this->textparam['bord-decoration']['baseline'] = 0;
  16814.             }
  16815.             $this->textparam['bord-decoration']['fontkey'] = $this->FontFamily $this->FontStyle;
  16816.             $this->textparam['bord-decoration']['fontsize'] = $this->FontSize;
  16817.         }
  16818.         if ($spanbgset) { // BACKGROUND[-COLOR] has been set on this INLINE element
  16819.             if (isset($this->textparam['text-baseline'])) {
  16820.                 $this->textparam['bg-decoration']['baseline'] = $this->textparam['text-baseline'];
  16821.             } else {
  16822.                 $this->textparam['bg-decoration']['baseline'] = 0;
  16823.             }
  16824.             $this->textparam['bg-decoration']['fontkey'] = $this->FontFamily $this->FontStyle;
  16825.             $this->textparam['bg-decoration']['fontsize'] = $this->FontSize;
  16826.         }
  16827.     }
  16828.     /* -- END HTML-CSS -- */
  16829.     function SetStyle($tag$enable)
  16830.     {
  16831.         $this->$tag $enable;
  16832.         $style '';
  16833.         foreach (['B''I'] as $s) {
  16834.             if ($this->$s) {
  16835.                 $style .= $s;
  16836.             }
  16837.         }
  16838.         $this->currentfontstyle $style;
  16839.         $this->SetFont(''$style0false);
  16840.     }
  16841.     // Set multiple styles at one time
  16842.     function SetStylesArray($arr)
  16843.     {
  16844.         $style '';
  16845.         foreach (['B''I'] as $s) {
  16846.             if (isset($arr[$s])) {
  16847.                 if ($arr[$s]) {
  16848.                     $this->$s true;
  16849.                     $style .= $s;
  16850.                 } else {
  16851.                     $this->$s false;
  16852.                 }
  16853.             } elseif ($this->$s) {
  16854.                 $style .= $s;
  16855.             }
  16856.         }
  16857.         $this->currentfontstyle $style;
  16858.         $this->SetFont(''$style0false);
  16859.     }
  16860.     // Set multiple styles at one $str e.g. "BI"
  16861.     function SetStyles($str)
  16862.     {
  16863.         $style '';
  16864.         foreach (['B''I'] as $s) {
  16865.             if (strpos($str$s) !== false) {
  16866.                 $this->$s true;
  16867.                 $style .= $s;
  16868.             } else {
  16869.                 $this->$s false;
  16870.             }
  16871.         }
  16872.         $this->currentfontstyle $style;
  16873.         $this->SetFont(''$style0false);
  16874.     }
  16875.     function ResetStyles()
  16876.     {
  16877.         foreach (['B''I'] as $s) {
  16878.             $this->$s false;
  16879.         }
  16880.         $this->currentfontstyle '';
  16881.         $this->SetFont(''''0false);
  16882.     }
  16883.     function DisableTags($str '')
  16884.     {
  16885.         if ($str == '') { // enable all tags
  16886.             // Insert new supported tags in the long string below.
  16887.             $this->enabledtags "<a><acronym><address><article><aside><b><bdi><bdo><big><blockquote><br><caption><center><cite><code><del><details><dd><div><dl><dt><em><fieldset><figcaption><figure><font><form><h1><h2><h3><h4><h5><h6><hgroup><hr><i><img><input><ins><kbd><legend><li><main><mark><meter><nav><ol><option><p><pre><progress><q><s><samp><section><select><small><span><strike><strong><sub><summary><sup><table><tbody><td><template><textarea><tfoot><th><thead><time><tr><tt><u><ul><var><footer><header><annotation><bookmark><textcircle><barcode><dottab><indexentry><indexinsert><watermarktext><watermarkimage><tts><ttz><tta><column_break><columnbreak><newcolumn><newpage><page_break><pagebreak><formfeed><columns><toc><tocentry><tocpagebreak><pageheader><pagefooter><setpageheader><setpagefooter><sethtmlpageheader><sethtmlpagefooter>";
  16888.         } else {
  16889.             $str explode(","$str);
  16890.             foreach ($str as $v) {
  16891.                 $this->enabledtags str_replace(trim($v), ''$this->enabledtags);
  16892.             }
  16893.         }
  16894.     }
  16895.     /* -- TABLES -- */
  16896.     function TableCheckMinWidth($maxwidth$forcewrap 0$textbuffer = [], $checkletter false)
  16897.     {
  16898.     // mPDF 6
  16899.         $acclength 0// mPDF 6 (accumulated length across > 1 chunk)
  16900.         $acclongest 0// mPDF 6 (accumulated length max across > 1 chunk)
  16901.         $biggestword 0;
  16902.         $toonarrow false;
  16903.         if ((count($textbuffer) == 0) or ( (count($textbuffer) == 1) && ($textbuffer[0][0] == ''))) {
  16904.             return 0;
  16905.         }
  16906.         foreach ($textbuffer as $chunk) {
  16907.             $line $chunk[0];
  16908.             $OTLdata = (isset($chunk[18]) ? $chunk[18] : null);
  16909.             // mPDF ITERATION
  16910.             if ($this->iterationCounter) {
  16911.                 $line preg_replace('/{iteration ([a-zA-Z0-9_]+)}/''\\1'$line);
  16912.             }
  16913.             // IMAGES & FORM ELEMENTS
  16914.             if (substr($line03) == Mpdf::OBJECT_IDENTIFIER) { // inline object - FORM element or IMAGE!
  16915.                 $objattr $this->_getObjAttr($line);
  16916.                 if ($objattr['type'] != 'hr' && isset($objattr['width']) && ($objattr['width'] / $this->shrin_k) > ($maxwidth 0.0001)) {
  16917.                     if (($objattr['width'] / $this->shrin_k) > $biggestword) {
  16918.                         $biggestword = ($objattr['width'] / $this->shrin_k);
  16919.                     }
  16920.                     $toonarrow true;
  16921.                 }
  16922.                 continue;
  16923.             }
  16924.             if ($line == "\n") {
  16925.                 $acclength 0// mPDF 6 (accumulated length across > 1 chunk)
  16926.                 continue;
  16927.             }
  16928.             $line trim($line);
  16929.             if (!empty($OTLdata)) {
  16930.                 $this->otl->trimOTLdata($OTLdatatruetrue);
  16931.             } // *OTL*
  16932.             // SET FONT SIZE/STYLE from $chunk[n]
  16933.             // FONTSIZE
  16934.             if (isset($chunk[11]) and $chunk[11] != '') {
  16935.                 if ($this->shrin_k) {
  16936.                     $this->SetFontSize($chunk[11] / $this->shrin_kfalse);
  16937.                 } else {
  16938.                     $this->SetFontSize($chunk[11], false);
  16939.                 }
  16940.             }
  16941.             // FONTFAMILY
  16942.             if (isset($chunk[4]) and $chunk[4] != '') {
  16943.                 $font $this->SetFont($chunk[4], $this->FontStyle0false);
  16944.             }
  16945.             // B I
  16946.             if (isset($chunk[2]) and $chunk[2] != '') {
  16947.                 $this->SetStyles($chunk[2]);
  16948.             }
  16949.             $lbw $rbw 0// Border widths
  16950.             if (isset($chunk[16]) && !empty($chunk[16])) { // Border
  16951.                 $this->spanborddet $chunk[16];
  16952.                 $lbw = (isset($this->spanborddet['L']['w']) ? $this->spanborddet['L']['w'] : 0);
  16953.                 $rbw = (isset($this->spanborddet['R']['w']) ? $this->spanborddet['R']['w'] : 0);
  16954.             }
  16955.             if (isset($chunk[15])) {   // Word spacing
  16956.                 $this->wSpacingCSS $chunk[15];
  16957.                 if ($this->wSpacingCSS && strtoupper($this->wSpacingCSS) != 'NORMAL') {
  16958.                     $this->minwSpacing $this->sizeConverter->convert($this->wSpacingCSS$this->FontSize) / $this->shrin_k// mPDF 5.7.3
  16959.                 }
  16960.             }
  16961.             if (isset($chunk[14])) {   // Letter spacing
  16962.                 $this->lSpacingCSS $chunk[14];
  16963.                 if (($this->lSpacingCSS || $this->lSpacingCSS === '0') && strtoupper($this->lSpacingCSS) != 'NORMAL') {
  16964.                     $this->fixedlSpacing $this->sizeConverter->convert($this->lSpacingCSS$this->FontSize) / $this->shrin_k// mPDF 5.7.3
  16965.                 }
  16966.             }
  16967.             if (isset($chunk[8])) { // mPDF 5.7.1
  16968.                 $this->textvar $chunk[8];
  16969.             }
  16970.             // mPDF 6
  16971.             // If overflow==wrap ($checkletter) OR (No word breaks and contains CJK)
  16972.             if ($checkletter || (!preg_match('/(\xe2\x80\x8b| )/'trim($line)) && preg_match("/([" $this->pregCJKchars "])/u"$line) )) {
  16973.                 if (preg_match("/([" $this->pregCJKchars "])/u"$line)) {
  16974.                     $checkCJK true;
  16975.                 } else {
  16976.                     $checkCJK false;
  16977.                 }
  16978.                 $letters preg_split('//u'$line);
  16979.                 foreach ($letters as $k => $letter) {
  16980.                     // mPDF 6
  16981.                     if ($checkCJK) {
  16982.                         if (preg_match("/[" $this->CJKleading "]/u"$letter) && $k 0) {
  16983.                             $letter $letters[$k 1] . $letter;
  16984.                         }
  16985.                         if (preg_match("/[" $this->CJKfollowing "]/u"$letter) && $k < (count($letters) - 1)) {
  16986.                             $letter $letter $letters[$k 1];
  16987.                         }
  16988.                     }
  16989.                     $letterwidth $this->GetStringWidth($letterfalsefalse$chunk[8]); // Pass $textvar ($chunk[8]), but do OTLdata here
  16990.                     // so don't have to split OTLdata for each word
  16991.                     if ($k == 0) {
  16992.                         $letterwidth += $lbw;
  16993.                     }
  16994.                     if ($k == (count($letters) - 1)) {
  16995.                         $letterwidth += $rbw;
  16996.                     }
  16997.                     // Warn user that maxwidth is insufficient
  16998.                     if ($letterwidth $maxwidth 0.0001) {
  16999.                         if ($letterwidth $biggestword) {
  17000.                             $biggestword $letterwidth;
  17001.                         }
  17002.                         $toonarrow true;
  17003.                     }
  17004.                 }
  17005.             } else {
  17006.                 // mPDF 6
  17007.                 // Need to account for any XAdvance in GPOSinfo (OTLdata = $chunk[18])
  17008.                 $wordXAdvance = [];
  17009.                 if (isset($chunk[18]) && $chunk[18]) {
  17010.                     preg_match_all('/(\xe2\x80\x8b| )/'$line$spacesPREG_OFFSET_CAPTURE); // U+200B Zero Width word boundary, or space
  17011.                     $lastoffset 0;
  17012.                     $k = -1// Added so that if no spaces found, "last word" later is calculated for the one and only word
  17013.                     foreach ($spaces[0] as $k => $m) {
  17014.                         $offset $m[1];
  17015.                         // ...TableCheckMinWidth...
  17016.                         // At this point, BIDI not applied, Writing direction is not set, and XAdvanceL balances XAdvanceR
  17017.                         for ($n $lastoffset$n $offset$n++) {
  17018.                             if (isset($chunk[18]['GPOSinfo'][$n]['XAdvanceL'])) {
  17019.                                 if (isset($wordXAdvance[$k])) {
  17020.                                     $wordXAdvance[$k] += $chunk[18]['GPOSinfo'][$n]['XAdvanceL'];
  17021.                                 } else {
  17022.                                     $wordXAdvance[$k] = $chunk[18]['GPOSinfo'][$n]['XAdvanceL'];
  17023.                                 }
  17024.                             }
  17025.                         }
  17026.                         $lastoffset $offset 1;
  17027.                     }
  17028.                     $k++;  // last word
  17029.                     foreach ($chunk[18]['GPOSinfo'] as $n => $gpos) {
  17030.                         if ($n >= $lastoffset && isset($chunk[18]['GPOSinfo'][$n]['XAdvanceL'])) {
  17031.                             if (isset($wordXAdvance[$k])) {
  17032.                                 $wordXAdvance[$k] += $chunk[18]['GPOSinfo'][$n]['XAdvanceL'];
  17033.                             } else {
  17034.                                 $wordXAdvance[$k] = $chunk[18]['GPOSinfo'][$n]['XAdvanceL'];
  17035.                             }
  17036.                         }
  17037.                     }
  17038.                 }
  17039.                 $words preg_split('/(\xe2\x80\x8b| )/'$line); // U+200B Zero Width word boundary, or space
  17040.                 foreach ($words as $k => $word) {
  17041.                     $word trim($word);
  17042.                     $wordwidth $this->GetStringWidth($wordfalsefalse$chunk[8]); // Pass $textvar ($chunk[8]), but do OTLdata here
  17043.                     // so don't have to split OTLdata for each word
  17044.                     if (isset($wordXAdvance[$k])) {
  17045.                         $wordwidth += ($wordXAdvance[$k] * 1000 $this->CurrentFont['unitsPerEm']) * ($this->FontSize 1000);
  17046.                     }
  17047.                     if ($k == 0) {
  17048.                         $wordwidth += $lbw;
  17049.                     }
  17050.                     if ($k == (count($words) - 1)) {
  17051.                         $wordwidth += $rbw;
  17052.                     }
  17053.                     // mPDF 6
  17054.                     if (count($words) == && substr($chunk[0], 01) != ' ') {
  17055.                         $acclength += $wordwidth;
  17056.                     } elseif (count($words) > && $k == && substr($chunk[0], 01) != ' ') {
  17057.                         $acclength += $wordwidth;
  17058.                     } else {
  17059.                         $acclength $wordwidth;
  17060.                     }
  17061.                     $acclongest max($acclongest$acclength);
  17062.                     if (count($words) == && substr($chunk[0], -11) == ' ') {
  17063.                         $acclength 0;
  17064.                     } elseif (count($words) > && ($k != (count($words) - 1) || substr($chunk[0], -11) == ' ')) {
  17065.                         $acclength 0;
  17066.                     }
  17067.                     // Warn user that maxwidth is insufficient
  17068.                     if ($wordwidth $maxwidth 0.0001) {
  17069.                         if ($wordwidth $biggestword) {
  17070.                             $biggestword $wordwidth;
  17071.                         }
  17072.                         $toonarrow true;
  17073.                     }
  17074.                 }
  17075.             }
  17076.             // mPDF 6  Accumulated length of biggest word - across multiple chunks
  17077.             if ($acclongest $maxwidth 0.0001) {
  17078.                 if ($acclongest $biggestword) {
  17079.                     $biggestword $acclongest;
  17080.                 }
  17081.                 $toonarrow true;
  17082.             }
  17083.             // RESET FONT SIZE/STYLE
  17084.             // RESETTING VALUES
  17085.             // Now we must deactivate what we have used
  17086.             if (isset($chunk[2]) and $chunk[2] != '') {
  17087.                 $this->ResetStyles();
  17088.             }
  17089.             if (isset($chunk[4]) and $chunk[4] != '') {
  17090.                 $this->SetFont($this->default_font$this->FontStyle0false);
  17091.             }
  17092.             if (isset($chunk[11]) and $chunk[11] != '') {
  17093.                 $this->SetFontSize($this->default_font_sizefalse);
  17094.             }
  17095.             $this->spanborddet = [];
  17096.             $this->textvar 0x00// mPDF 5.7.1
  17097.             $this->OTLtags = [];
  17098.             $this->lSpacingCSS '';
  17099.             $this->wSpacingCSS '';
  17100.             $this->fixedlSpacing false;
  17101.             $this->minwSpacing 0;
  17102.         }
  17103.         // Return -(wordsize) if word is bigger than maxwidth
  17104.         // ADDED
  17105.         if (($toonarrow) && ($this->table_error_report)) {
  17106.             throw new \Mpdf\MpdfException("Word is too long to fit in table - " $this->table_error_report_param);
  17107.         }
  17108.         if ($toonarrow) {
  17109.             return -$biggestword;
  17110.         } else {
  17111.             return 1;
  17112.         }
  17113.     }
  17114.     function shrinkTable(&$table$k)
  17115.     {
  17116.         $table['border_spacing_H'] /= $k;
  17117.         $table['border_spacing_V'] /= $k;
  17118.         $table['padding']['T'] /= $k;
  17119.         $table['padding']['R'] /= $k;
  17120.         $table['padding']['B'] /= $k;
  17121.         $table['padding']['L'] /= $k;
  17122.         $table['margin']['T'] /= $k;
  17123.         $table['margin']['R'] /= $k;
  17124.         $table['margin']['B'] /= $k;
  17125.         $table['margin']['L'] /= $k;
  17126.         $table['border_details']['T']['w'] /= $k;
  17127.         $table['border_details']['R']['w'] /= $k;
  17128.         $table['border_details']['B']['w'] /= $k;
  17129.         $table['border_details']['L']['w'] /= $k;
  17130.         if (isset($table['max_cell_border_width']['T'])) {
  17131.             $table['max_cell_border_width']['T'] /= $k;
  17132.         }
  17133.         if (isset($table['max_cell_border_width']['R'])) {
  17134.             $table['max_cell_border_width']['R'] /= $k;
  17135.         }
  17136.         if (isset($table['max_cell_border_width']['B'])) {
  17137.             $table['max_cell_border_width']['B'] /= $k;
  17138.         }
  17139.         if (isset($table['max_cell_border_width']['L'])) {
  17140.             $table['max_cell_border_width']['L'] /= $k;
  17141.         }
  17142.         if ($this->simpleTables) {
  17143.             $table['simple']['border_details']['T']['w'] /= $k;
  17144.             $table['simple']['border_details']['R']['w'] /= $k;
  17145.             $table['simple']['border_details']['B']['w'] /= $k;
  17146.             $table['simple']['border_details']['L']['w'] /= $k;
  17147.         }
  17148.         $table['miw'] /= $k;
  17149.         $table['maw'] /= $k;
  17150.         for ($j 0$j $table['nc']; $j++) { // columns
  17151.             $table['wc'][$j]['miw'] = isset($table['wc'][$j]['miw']) ? $table['wc'][$j]['miw'] : 0;
  17152.             $table['wc'][$j]['maw'] = isset($table['wc'][$j]['maw']) ? $table['wc'][$j]['maw'] : 0;
  17153.             $table['wc'][$j]['miw'] /= $k;
  17154.             $table['wc'][$j]['maw'] /= $k;
  17155.             if (isset($table['decimal_align'][$j]['maxs0']) && $table['decimal_align'][$j]['maxs0']) {
  17156.                 $table['decimal_align'][$j]['maxs0'] /= $k;
  17157.             }
  17158.             if (isset($table['decimal_align'][$j]['maxs1']) && $table['decimal_align'][$j]['maxs1']) {
  17159.                 $table['decimal_align'][$j]['maxs1'] /= $k;
  17160.             }
  17161.             if (isset($table['wc'][$j]['absmiw']) && $table['wc'][$j]['absmiw']) {
  17162.                 $table['wc'][$j]['absmiw'] /= $k;
  17163.             }
  17164.             for ($i 0$i $table['nr']; $i++) { // rows
  17165.                 $c = &$table['cells'][$i][$j];
  17166.                 if (isset($c) && $c) {
  17167.                     if (!$this->simpleTables) {
  17168.                         if ($this->packTableData) {
  17169.                             $cell $this->_unpackCellBorder($c['borderbin']);
  17170.                             $cell['border_details']['T']['w'] /= $k;
  17171.                             $cell['border_details']['R']['w'] /= $k;
  17172.                             $cell['border_details']['B']['w'] /= $k;
  17173.                             $cell['border_details']['L']['w'] /= $k;
  17174.                             $cell['border_details']['mbw']['TL'] /= $k;
  17175.                             $cell['border_details']['mbw']['TR'] /= $k;
  17176.                             $cell['border_details']['mbw']['BL'] /= $k;
  17177.                             $cell['border_details']['mbw']['BR'] /= $k;
  17178.                             $cell['border_details']['mbw']['LT'] /= $k;
  17179.                             $cell['border_details']['mbw']['LB'] /= $k;
  17180.                             $cell['border_details']['mbw']['RT'] /= $k;
  17181.                             $cell['border_details']['mbw']['RB'] /= $k;
  17182.                             $c['borderbin'] = $this->_packCellBorder($cell);
  17183.                         } else {
  17184.                             $c['border_details']['T']['w'] /= $k;
  17185.                             $c['border_details']['R']['w'] /= $k;
  17186.                             $c['border_details']['B']['w'] /= $k;
  17187.                             $c['border_details']['L']['w'] /= $k;
  17188.                             $c['border_details']['mbw']['TL'] /= $k;
  17189.                             $c['border_details']['mbw']['TR'] /= $k;
  17190.                             $c['border_details']['mbw']['BL'] /= $k;
  17191.                             $c['border_details']['mbw']['BR'] /= $k;
  17192.                             $c['border_details']['mbw']['LT'] /= $k;
  17193.                             $c['border_details']['mbw']['LB'] /= $k;
  17194.                             $c['border_details']['mbw']['RT'] /= $k;
  17195.                             $c['border_details']['mbw']['RB'] /= $k;
  17196.                         }
  17197.                     }
  17198.                     $c['padding']['T'] /= $k;
  17199.                     $c['padding']['R'] /= $k;
  17200.                     $c['padding']['B'] /= $k;
  17201.                     $c['padding']['L'] /= $k;
  17202.                     $c['maxs'] = isset($c['maxs']) ? $c['maxs'] /= $k null;
  17203.                     $c['w'] = isset($c['w']) ? $c['w'] /= $k null;
  17204.                     $c['s'] = isset($c['s']) ? $c['s'] /= $k 0;
  17205.                     $c['h'] = isset($c['h']) ? $c['h'] /= $k null;
  17206.                     $c['miw'] = isset($c['miw']) ? $c['miw'] /= $k 0;
  17207.                     $c['maw'] = isset($c['maw']) ? $c['maw'] /= $k 0;
  17208.                     $c['absmiw'] = isset($c['absmiw']) ? $c['absmiw'] /= $k null;
  17209.                     $c['nestedmaw'] = isset($c['nestedmaw']) ? $c['nestedmaw'] /= $k null;
  17210.                     $c['nestedmiw'] = isset($c['nestedmiw']) ? $c['nestedmiw'] /= $k null;
  17211.                     if (isset($c['textbuffer'])) {
  17212.                         foreach ($c['textbuffer'] as $n => $tb) {
  17213.                             if (!empty($tb[16])) {
  17214.                                 !isset($c['textbuffer'][$n][16]['T']) || $c['textbuffer'][$n][16]['T']['w'] /= $k;
  17215.                                 !isset($c['textbuffer'][$n][16]['B']) || $c['textbuffer'][$n][16]['B']['w'] /= $k;
  17216.                                 !isset($c['textbuffer'][$n][16]['L']) || $c['textbuffer'][$n][16]['L']['w'] /= $k;
  17217.                                 !isset($c['textbuffer'][$n][16]['R']) || $c['textbuffer'][$n][16]['R']['w'] /= $k;
  17218.                             }
  17219.                         }
  17220.                     }
  17221.                     unset($c);
  17222.                 }
  17223.             } // rows
  17224.         // columns
  17225.     }
  17226.     function read_short(&$fh)
  17227.     {
  17228.         $s fread($fh2);
  17229.         $a = (ord($s[0]) << 8) + ord($s[1]);
  17230.         if ($a & (<< 15)) {
  17231.             $a = ($a - (<< 16));
  17232.         }
  17233.         return $a;
  17234.     }
  17235.     function _packCellBorder($cell)
  17236.     {
  17237.         if (!is_array($cell) || !isset($cell)) {
  17238.             return '';
  17239.         }
  17240.         if (!$this->packTableData) {
  17241.             return $cell;
  17242.         }
  17243.         // = 186 bytes
  17244.         $bindata pack("nnda6A10nnda6A10nnda6A10nnda6A10nd9"$cell['border'], $cell['border_details']['R']['s'], $cell['border_details']['R']['w'], $cell['border_details']['R']['c'], $cell['border_details']['R']['style'], $cell['border_details']['R']['dom'], $cell['border_details']['L']['s'], $cell['border_details']['L']['w'], $cell['border_details']['L']['c'], $cell['border_details']['L']['style'], $cell['border_details']['L']['dom'], $cell['border_details']['T']['s'], $cell['border_details']['T']['w'], $cell['border_details']['T']['c'], $cell['border_details']['T']['style'], $cell['border_details']['T']['dom'], $cell['border_details']['B']['s'], $cell['border_details']['B']['w'], $cell['border_details']['B']['c'], $cell['border_details']['B']['style'], $cell['border_details']['B']['dom'], $cell['border_details']['mbw']['BL'], $cell['border_details']['mbw']['BR'], $cell['border_details']['mbw']['RT'], $cell['border_details']['mbw']['RB'], $cell['border_details']['mbw']['TL'], $cell['border_details']['mbw']['TR'], $cell['border_details']['mbw']['LT'], $cell['border_details']['mbw']['LB'], (isset($cell['border_details']['cellposdom']) ? $cell['border_details']['cellposdom'] : 0));
  17245.         return $bindata;
  17246.     }
  17247.     function _getBorderWidths($bindata)
  17248.     {
  17249.         if (!$bindata) {
  17250.             return [0000];
  17251.         }
  17252.         if (!$this->packTableData) {
  17253.             return [$bindata['border_details']['T']['w'], $bindata['border_details']['R']['w'], $bindata['border_details']['B']['w'], $bindata['border_details']['L']['w']];
  17254.         }
  17255.         $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);
  17256.         $cell['border_details']['R']['w'] = $bd['rw'];
  17257.         $cell['border_details']['L']['w'] = $bd['lw'];
  17258.         $cell['border_details']['T']['w'] = $bd['tw'];
  17259.         $cell['border_details']['B']['w'] = $bd['bw'];
  17260.         return [$bd['tw'], $bd['rw'], $bd['bw'], $bd['lw']];
  17261.     }
  17262.     function _unpackCellBorder($bindata)
  17263.     {
  17264.         if (!$bindata) {
  17265.             return [];
  17266.         }
  17267.         if (!$this->packTableData) {
  17268.             return $bindata;
  17269.         }
  17270.         $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);
  17271.         $cell['border'] = $bd['bord'];
  17272.         $cell['border_details']['R']['s'] = $bd['rs'];
  17273.         $cell['border_details']['R']['w'] = $bd['rw'];
  17274.         $cell['border_details']['R']['c'] = str_pad($bd['rca'], 6"\x00");
  17275.         $cell['border_details']['R']['style'] = trim($bd['rst']);
  17276.         $cell['border_details']['R']['dom'] = $bd['rd'];
  17277.         $cell['border_details']['L']['s'] = $bd['ls'];
  17278.         $cell['border_details']['L']['w'] = $bd['lw'];
  17279.         $cell['border_details']['L']['c'] = str_pad($bd['lca'], 6"\x00");
  17280.         $cell['border_details']['L']['style'] = trim($bd['lst']);
  17281.         $cell['border_details']['L']['dom'] = $bd['ld'];
  17282.         $cell['border_details']['T']['s'] = $bd['ts'];
  17283.         $cell['border_details']['T']['w'] = $bd['tw'];
  17284.         $cell['border_details']['T']['c'] = str_pad($bd['tca'], 6"\x00");
  17285.         $cell['border_details']['T']['style'] = trim($bd['tst']);
  17286.         $cell['border_details']['T']['dom'] = $bd['td'];
  17287.         $cell['border_details']['B']['s'] = $bd['bs'];
  17288.         $cell['border_details']['B']['w'] = $bd['bw'];
  17289.         $cell['border_details']['B']['c'] = str_pad($bd['bca'], 6"\x00");
  17290.         $cell['border_details']['B']['style'] = trim($bd['bst']);
  17291.         $cell['border_details']['B']['dom'] = $bd['bd'];
  17292.         $cell['border_details']['mbw']['BL'] = $bd['mbl'];
  17293.         $cell['border_details']['mbw']['BR'] = $bd['mbr'];
  17294.         $cell['border_details']['mbw']['RT'] = $bd['mrt'];
  17295.         $cell['border_details']['mbw']['RB'] = $bd['mrb'];
  17296.         $cell['border_details']['mbw']['TL'] = $bd['mtl'];
  17297.         $cell['border_details']['mbw']['TR'] = $bd['mtr'];
  17298.         $cell['border_details']['mbw']['LT'] = $bd['mlt'];
  17299.         $cell['border_details']['mbw']['LB'] = $bd['mlb'];
  17300.         $cell['border_details']['cellposdom'] = $bd['cpd'];
  17301.         return($cell);
  17302.     }
  17303.     ////////////////////////TABLE CODE (from PDFTable)/////////////////////////////////////
  17304.     ////////////////////////TABLE CODE (from PDFTable)/////////////////////////////////////
  17305.     ////////////////////////TABLE CODE (from PDFTable)/////////////////////////////////////
  17306.     // table        Array of (w, h, bc, nr, wc, hr, cells)
  17307.     // w            Width of table
  17308.     // h            Height of table
  17309.     // nc            Number column
  17310.     // nr            Number row
  17311.     // hr            List of height of each row
  17312.     // wc            List of width of each column
  17313.     // cells        List of cells of each rows, cells[i][j] is a cell in the table
  17314.     function _tableColumnWidth(&$table$firstpass false)
  17315.     {
  17316.         $cs = &$table['cells'];
  17317.         $nc $table['nc'];
  17318.         $nr $table['nr'];
  17319.         $listspan = [];
  17320.         if ($table['borders_separate']) {
  17321.             $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'];
  17322.         } else {
  17323.             $tblbw $table['max_cell_border_width']['L'] / $table['max_cell_border_width']['R'] / $table['margin']['L'] + $table['margin']['R'];
  17324.         }
  17325.         // ADDED table['l'][colno]
  17326.         // = total length of text approx (using $c['s']) in that column - used to approximately distribute col widths in _tableWidth
  17327.         //
  17328.         for ($j 0$j $nc$j++) { // columns
  17329.             $wc = &$table['wc'][$j];
  17330.             for ($i 0$i $nr$i++) { // rows
  17331.                 if (isset($cs[$i][$j]) && $cs[$i][$j]) {
  17332.                     $c = &$cs[$i][$j];
  17333.                     if ($this->simpleTables) {
  17334.                         if ($table['borders_separate']) { // NB twice border width
  17335.                             $extrcw $table['simple']['border_details']['L']['w'] + $table['simple']['border_details']['R']['w'] + $c['padding']['L'] + $c['padding']['R'] + $table['border_spacing_H'];
  17336.                         } else {
  17337.                             $extrcw $table['simple']['border_details']['L']['w'] / $table['simple']['border_details']['R']['w'] / $c['padding']['L'] + $c['padding']['R'];
  17338.                         }
  17339.                     } else {
  17340.                         if ($this->packTableData) {
  17341.                             list($bt$br$bb$bl) = $this->_getBorderWidths($c['borderbin']);
  17342.                         } else {
  17343.                             $br $c['border_details']['R']['w'];
  17344.                             $bl $c['border_details']['L']['w'];
  17345.                         }
  17346.                         if ($table['borders_separate']) { // NB twice border width
  17347.                             $extrcw $bl $br $c['padding']['L'] + $c['padding']['R'] + $table['border_spacing_H'];
  17348.                         } else {
  17349.                             $extrcw $bl $br $c['padding']['L'] + $c['padding']['R'];
  17350.                         }
  17351.                     }
  17352.                     // $mw = $this->GetStringWidth('W') + $extrcw ;
  17353.                     $mw $extrcw// mPDF 6
  17354.                     if (substr($c['a'], 01) == 'D') {
  17355.                         $mw $table['decimal_align'][$j]['maxs0'] + $table['decimal_align'][$j]['maxs1'] + $extrcw;
  17356.                     }
  17357.                     $c['absmiw'] = $mw;
  17358.                     if (isset($c['R']) && $c['R']) {
  17359.                         $c['maw'] = $c['miw'] = $this->FontSize $extrcw;
  17360.                         if (isset($c['w'])) { // If cell width is specified
  17361.                             if ($c['miw'] < $c['w']) {
  17362.                                 $c['miw'] = $c['w'];
  17363.                             }
  17364.                         }
  17365.                         if (!isset($c['colspan'])) {
  17366.                             if ($wc['miw'] < $c['miw']) {
  17367.                                 $wc['miw'] = $c['miw'];
  17368.                             }
  17369.                             if ($wc['maw'] < $c['maw']) {
  17370.                                 $wc['maw'] = $c['maw'];
  17371.                             }
  17372.                             if ($firstpass) {
  17373.                                 if (isset($table['l'][$j])) {
  17374.                                     $table['l'][$j] += $c['miw'];
  17375.                                 } else {
  17376.                                     $table['l'][$j] = $c['miw'];
  17377.                                 }
  17378.                             }
  17379.                         }
  17380.                         if ($c['miw'] > $wc['miw']) {
  17381.                             $wc['miw'] = $c['miw'];
  17382.                         }
  17383.                         if ($wc['miw'] > $wc['maw']) {
  17384.                             $wc['maw'] = $wc['miw'];
  17385.                         }
  17386.                         continue;
  17387.                     }
  17388.                     if ($firstpass) {
  17389.                         if (isset($c['s'])) {
  17390.                             $c['s'] += $extrcw;
  17391.                         }
  17392.                         if (isset($c['maxs'])) {
  17393.                             $c['maxs'] += $extrcw;
  17394.                         }
  17395.                         if (isset($c['nestedmiw'])) {
  17396.                             $c['nestedmiw'] += $extrcw;
  17397.                         }
  17398.                         if (isset($c['nestedmaw'])) {
  17399.                             $c['nestedmaw'] += $extrcw;
  17400.                         }
  17401.                     }
  17402.                     // If minimum width has already been set by a nested table or inline object (image/form), use it
  17403.                     if (isset($c['nestedmiw']) && (!isset($this->table[1][1]['overflow']) || $this->table[1][1]['overflow'] != 'visible')) {
  17404.                         $miw $c['nestedmiw'];
  17405.                     } else {
  17406.                         $miw $mw;
  17407.                     }
  17408.                     if (isset($c['maxs']) && $c['maxs'] != '') {
  17409.                         $c['s'] = $c['maxs'];
  17410.                     }
  17411.                     // If maximum width has already been set by a nested table, use it
  17412.                     if (isset($c['nestedmaw'])) {
  17413.                         $c['maw'] = $c['nestedmaw'];
  17414.                     } else {
  17415.                         $c['maw'] = $c['s'];
  17416.                     }
  17417.                     if (isset($table['overflow']) && $table['overflow'] == 'visible' && $table['level'] == 1) {
  17418.                         if (($c['maw'] + $tblbw) > $this->blk[$this->blklvl]['inner_width']) {
  17419.                             $c['maw'] = $this->blk[$this->blklvl]['inner_width'] - $tblbw;
  17420.                         }
  17421.                     }
  17422.                     if (isset($c['nowrap']) && $c['nowrap']) {
  17423.                         $miw $c['maw'];
  17424.                     }
  17425.                     if (isset($c['wpercent']) && $firstpass) {
  17426.                         if (isset($c['colspan'])) { // Not perfect - but % set on colspan is shared equally on cols.
  17427.                             for ($k 0$k $c['colspan']; $k++) {
  17428.                                 $table['wc'][($j $k)]['wpercent'] = $c['wpercent'] / $c['colspan'];
  17429.                             }
  17430.                         } else {
  17431.                             if (isset($table['w']) && $table['w']) {
  17432.                                 $c['w'] = $c['wpercent'] / 100 * ($table['w'] - $tblbw );
  17433.                             }
  17434.                             $wc['wpercent'] = $c['wpercent'];
  17435.                         }
  17436.                     }
  17437.                     if (isset($table['overflow']) && $table['overflow'] == 'visible' && $table['level'] == 1) {
  17438.                         if (isset($c['w']) && ($c['w'] + $tblbw) > $this->blk[$this->blklvl]['inner_width']) {
  17439.                             $c['w'] = $this->blk[$this->blklvl]['inner_width'] - $tblbw;
  17440.                         }
  17441.                     }
  17442.                     if (isset($c['w'])) { // If cell width is specified
  17443.                         if ($miw $c['w']) {
  17444.                             $c['miw'] = $c['w'];
  17445.                         } // Cell min width = that specified
  17446.                         if ($miw $c['w']) {
  17447.                             $c['miw'] = $c['w'] = $miw;
  17448.                         } // If width specified is less than minimum allowed (W) increase it
  17449.                         // mPDF 5.7.4  Do not set column width in colspan
  17450.                         // cf. http://www.mpdf1.com/forum/discussion/2221/colspan-bug
  17451.                         if (!isset($c['colspan'])) {
  17452.                             if (!isset($wc['w'])) {
  17453.                                 $wc['w'] = 1;
  17454.                             }  // If the Col width is not specified = set it to 1
  17455.                         }
  17456.                         // mPDF 5.7.3  cf. http://www.mpdf1.com/forum/discussion/1648/nested-table-bug-
  17457.                         $c['maw'] = $c['w'];
  17458.                     } else {
  17459.                         $c['miw'] = $miw;
  17460.                     } // If cell width not specified -> set Cell min width it to minimum allowed (W)
  17461.                     if (isset($c['miw']) && $c['maw'] < $c['miw']) {
  17462.                         $c['maw'] = $c['miw'];
  17463.                     } // If Cell max width < Minwidth - increase it to =
  17464.                     if (!isset($c['colspan'])) {
  17465.                         if (isset($c['miw']) && $wc['miw'] < $c['miw']) {
  17466.                             $wc['miw'] = $c['miw'];
  17467.                         } // Update Col Minimum and maximum widths
  17468.                         if ($wc['maw'] < $c['maw']) {
  17469.                             $wc['maw'] = $c['maw'];
  17470.                         }
  17471.                         if ((isset($wc['absmiw']) && $wc['absmiw'] < $c['absmiw']) || !isset($wc['absmiw'])) {
  17472.                             $wc['absmiw'] = $c['absmiw'];
  17473.                         } // Update Col Minimum and maximum widths
  17474.                         if (isset($table['l'][$j])) {
  17475.                             $table['l'][$j] += $c['s'];
  17476.                         } else {
  17477.                             $table['l'][$j] = $c['s'];
  17478.                         }
  17479.                     } else {
  17480.                         $listspan[] = [$i$j];
  17481.                     }
  17482.                     // Check if minimum width of the whole column is big enough for largest word to fit
  17483.                     // mPDF 6
  17484.                     if (isset($c['textbuffer'])) {
  17485.                         if (isset($table['overflow']) && $table['overflow'] == 'wrap') {
  17486.                             $letter true;
  17487.                         } // check for maximum width of letters
  17488.                         else {
  17489.                             $letter false;
  17490.                         }
  17491.                         $minwidth $this->TableCheckMinWidth($wc['miw'] - $extrcw0$c['textbuffer'], $letter);
  17492.                     } else {
  17493.                         $minwidth 0;
  17494.                     }
  17495.                     if ($minwidth 0) {
  17496.                         // increase minimum width
  17497.                         if (!isset($c['colspan'])) {
  17498.                             $wc['miw'] = max((isset($wc['miw']) ? $wc['miw'] : 0), ((-$minwidth) + $extrcw));
  17499.                         } else {
  17500.                             $c['miw'] = max((isset($c['miw']) ? $c['miw'] : 0), ((-$minwidth) + $extrcw));
  17501.                         }
  17502.                     }
  17503.                     if (!isset($c['colspan'])) {
  17504.                         if ($wc['miw'] > $wc['maw']) {
  17505.                             $wc['maw'] = $wc['miw'];
  17506.                         } // update maximum width, if needed
  17507.                     }
  17508.                 }
  17509.                 unset($c);
  17510.             }//rows
  17511.         }//columns
  17512.         // COLUMN SPANS
  17513.         $wc = &$table['wc'];
  17514.         foreach ($listspan as $span) {
  17515.             list($i$j) = $span;
  17516.             $c = &$cs[$i][$j];
  17517.             $lc $j $c['colspan'];
  17518.             if ($lc $nc) {
  17519.                 $lc $nc;
  17520.             }
  17521.             $wis $wisa 0;
  17522.             $was $wasa 0;
  17523.             $list = [];
  17524.             for ($k $j$k $lc$k++) {
  17525.                 if (isset($table['l'][$k])) {
  17526.                     if ($c['R']) {
  17527.                         $table['l'][$k] += $c['miw'] / $c['colspan'];
  17528.                     } else {
  17529.                         $table['l'][$k] += $c['s'] / $c['colspan'];
  17530.                     }
  17531.                 } else {
  17532.                     if ($c['R']) {
  17533.                         $table['l'][$k] = $c['miw'] / $c['colspan'];
  17534.                     } else {
  17535.                         $table['l'][$k] = $c['s'] / $c['colspan'];
  17536.                     }
  17537.                 }
  17538.                 $wis += $wc[$k]['miw'];   // $wis is the sum of the column miw in the colspan
  17539.                 $was += $wc[$k]['maw'];   // $was is the sum of the column maw in the colspan
  17540.                 if (!isset($c['w'])) {
  17541.                     $list[] = $k;
  17542.                     $wisa += $wc[$k]['miw']; // $wisa is the sum of the column miw in cells with no width specified in the colspan
  17543.                     $wasa += $wc[$k]['maw']; // $wasa is the sum of the column maw in cells with no width specified in the colspan
  17544.                 }
  17545.             }
  17546.             if ($c['miw'] > $wis) {
  17547.                 if (!$wis) {
  17548.                     for ($k $j$k $lc$k++) {
  17549.                         $wc[$k]['miw'] = $c['miw'] / $c['colspan'];
  17550.                     }
  17551.                 } elseif (!count($list) && $wis != 0) {
  17552.                     $wi $c['miw'] - $wis;
  17553.                     for ($k $j$k $lc$k++) {
  17554.                         $wc[$k]['miw'] += ($wc[$k]['miw'] / $wis) * $wi;
  17555.                     }
  17556.                 } else {
  17557.                     $wi $c['miw'] - $wis;
  17558.                     // mPDF 5.7.2   Extra min width distributed proportionately to all cells in colspan without a specified width
  17559.                     // cf. http://www.mpdf1.com/forum/discussion/1607#Item_4
  17560.                     foreach ($list as $k) {
  17561.                         if (!isset($wc[$k]['w']) || !$wc[$k]['w']) {
  17562.                             $wc[$k]['miw'] += ($wc[$k]['miw'] / $wisa) * $wi;
  17563.                         }
  17564.                     } // mPDF 5.7.2
  17565.                 }
  17566.             }
  17567.             if ($c['maw'] > $was) {
  17568.                 if (!$wis) {
  17569.                     for ($k $j$k $lc$k++) {
  17570.                         $wc[$k]['maw'] = $c['maw'] / $c['colspan'];
  17571.                     }
  17572.                 } elseif (!count($list) && $was != 0) {
  17573.                     $wi $c['maw'] - $was;
  17574.                     for ($k $j$k $lc$k++) {
  17575.                         $wc[$k]['maw'] += ($wc[$k]['maw'] / $was) * $wi;
  17576.                     }
  17577.                 } else {
  17578.                     $wi $c['maw'] - $was;
  17579.                     // mPDF 5.7.4  Extra max width distributed evenly to all cells in colspan without a specified width
  17580.                     // cf. http://www.mpdf1.com/forum/discussion/2221/colspan-bug
  17581.                     foreach ($list as $k) {
  17582.                         $wc[$k]['maw'] += $wi count($list);
  17583.                     }
  17584.                 }
  17585.             }
  17586.             unset($c);
  17587.         }
  17588.         $checkminwidth 0;
  17589.         $checkmaxwidth 0;
  17590.         $totallength 0;
  17591.         for ($i 0$i $nc$i++) {
  17592.             $checkminwidth += $table['wc'][$i]['miw'];
  17593.             $checkmaxwidth += $table['wc'][$i]['maw'];
  17594.             $totallength += isset($table['l']) ? $table['l'][$i] : 0;
  17595.         }
  17596.         if (!isset($table['w']) && $firstpass) {
  17597.             $sumpc 0;
  17598.             $notset 0;
  17599.             for ($i 0$i $nc$i++) {
  17600.                 if (isset($table['wc'][$i]['wpercent']) && $table['wc'][$i]['wpercent']) {
  17601.                     $sumpc += $table['wc'][$i]['wpercent'];
  17602.                 } else {
  17603.                     $notset++;
  17604.                 }
  17605.             }
  17606.             // If sum of widths as %  >= 100% and not all columns are set
  17607.             // Set a nominal width of 1% for unset columns
  17608.             if ($sumpc >= 100 && $notset) {
  17609.                 for ($i 0$i $nc$i++) {
  17610.                     if ((!isset($table['wc'][$i]['wpercent']) || !$table['wc'][$i]['wpercent']) &&
  17611.                         (!isset($table['wc'][$i]['w']) || !$table['wc'][$i]['w'])) {
  17612.                         $table['wc'][$i]['wpercent'] = 1;
  17613.                     }
  17614.                 }
  17615.             }
  17616.             if ($sumpc) { // if any percents are set
  17617.                 $sumnonpc = (100 $sumpc);
  17618.                 $sumpc max($sumpc100);
  17619.                 $miwleft 0;
  17620.                 $miwleftcount 0;
  17621.                 $miwsurplusnonpc 0;
  17622.                 $maxcalcmiw 0;
  17623.                 $mawleft 0;
  17624.                 $mawleftcount 0;
  17625.                 $mawsurplusnonpc 0;
  17626.                 $maxcalcmaw 0;
  17627.                 $mawnon 0;
  17628.                 $miwnon 0;
  17629.                 for ($i 0$i $nc$i++) {
  17630.                     if (isset($table['wc'][$i]['wpercent'])) {
  17631.                         $maxcalcmiw max($maxcalcmiw, ($table['wc'][$i]['miw'] * $sumpc $table['wc'][$i]['wpercent']));
  17632.                         $maxcalcmaw max($maxcalcmaw, ($table['wc'][$i]['maw'] * $sumpc $table['wc'][$i]['wpercent']));
  17633.                     } else {
  17634.                         $miwleft += $table['wc'][$i]['miw'];
  17635.                         $mawleft += $table['wc'][$i]['maw'];
  17636.                         if (!isset($table['wc'][$i]['w'])) {
  17637.                             $miwleftcount++;
  17638.                             $mawleftcount++;
  17639.                         }
  17640.                     }
  17641.                 }
  17642.                 if ($miwleft && $sumnonpc 0) {
  17643.                     $miwnon $miwleft 100 $sumnonpc;
  17644.                 }
  17645.                 if ($mawleft && $sumnonpc 0) {
  17646.                     $mawnon $mawleft 100 $sumnonpc;
  17647.                 }
  17648.                 if (($miwnon $checkminwidth || $maxcalcmiw $checkminwidth) && $this->keep_table_proportions) {
  17649.                     if ($miwnon $maxcalcmiw) {
  17650.                         $miwsurplusnonpc round((($miwnon $sumnonpc 100) - $miwleft), 3);
  17651.                         $checkminwidth $miwnon;
  17652.                     } else {
  17653.                         $checkminwidth $maxcalcmiw;
  17654.                     }
  17655.                     for ($i 0$i $nc$i++) {
  17656.                         if (isset($table['wc'][$i]['wpercent'])) {
  17657.                             $newmiw $checkminwidth $table['wc'][$i]['wpercent'] / 100;
  17658.                             if ($table['wc'][$i]['miw'] < $newmiw) {
  17659.                                 $table['wc'][$i]['miw'] = $newmiw;
  17660.                             }
  17661.                             $table['wc'][$i]['w'] = 1;
  17662.                         } elseif ($miwsurplusnonpc && !$table['wc'][$i]['w']) {
  17663.                             $table['wc'][$i]['miw'] += $miwsurplusnonpc $miwleftcount;
  17664.                         }
  17665.                     }
  17666.                 }
  17667.                 if (($mawnon $checkmaxwidth || $maxcalcmaw $checkmaxwidth)) {
  17668.                     if ($mawnon $maxcalcmaw) {
  17669.                         $mawsurplusnonpc round((($mawnon $sumnonpc 100) - $mawleft), 3);
  17670.                         $checkmaxwidth $mawnon;
  17671.                     } else {
  17672.                         $checkmaxwidth $maxcalcmaw;
  17673.                     }
  17674.                     for ($i 0$i $nc$i++) {
  17675.                         if (isset($table['wc'][$i]['wpercent'])) {
  17676.                             $newmaw $checkmaxwidth $table['wc'][$i]['wpercent'] / 100;
  17677.                             if ($table['wc'][$i]['maw'] < $newmaw) {
  17678.                                 $table['wc'][$i]['maw'] = $newmaw;
  17679.                             }
  17680.                             $table['wc'][$i]['w'] = 1;
  17681.                         } elseif ($mawsurplusnonpc && !$table['wc'][$i]['w']) {
  17682.                             $table['wc'][$i]['maw'] += $mawsurplusnonpc $mawleftcount;
  17683.                         }
  17684.                         if ($table['wc'][$i]['maw'] < $table['wc'][$i]['miw']) {
  17685.                             $table['wc'][$i]['maw'] = $table['wc'][$i]['miw'];
  17686.                         }
  17687.                     }
  17688.                 }
  17689.                 if ($checkminwidth $checkmaxwidth) {
  17690.                     $checkmaxwidth $checkminwidth;
  17691.                 }
  17692.             }
  17693.         }
  17694.         if (isset($table['wpercent']) && $table['wpercent']) {
  17695.             $checkminwidth *= (100 $table['wpercent']);
  17696.             $checkmaxwidth *= (100 $table['wpercent']);
  17697.         }
  17698.         $checkminwidth += $tblbw;
  17699.         $checkmaxwidth += $tblbw;
  17700.         // Table['miw'] set by percent in first pass may be larger than sum of column miw
  17701.         if ((isset($table['miw']) && $checkminwidth $table['miw']) || !isset($table['miw'])) {
  17702.             $table['miw'] = $checkminwidth;
  17703.         }
  17704.         if ((isset($table['maw']) && $checkmaxwidth $table['maw']) || !isset($table['maw'])) {
  17705.             $table['maw'] = $checkmaxwidth;
  17706.         }
  17707.         $table['tl'] = $totallength;
  17708.         // mPDF 6
  17709.         if ($this->table_rotate) {
  17710.             $mxw $this->tbrot_maxw;
  17711.         } else {
  17712.             $mxw $this->blk[$this->blklvl]['inner_width'];
  17713.         }
  17714.         if (!isset($table['overflow'])) {
  17715.             $table['overflow'] = null;
  17716.         }
  17717.         if ($table['overflow'] == 'visible') {
  17718.             return [00];
  17719.         } elseif ($table['overflow'] == 'hidden' && !$this->table_rotate && !$this->ColActive && $checkminwidth $mxw) {
  17720.             $table['w'] = $table['miw'];
  17721.             return [00];
  17722.         }
  17723.         // elseif ($table['overflow']=='wrap') { return array(0,0); }    // mPDF 6
  17724.         if (isset($table['w']) && $table['w']) {
  17725.             if ($table['w'] >= $checkminwidth && $table['w'] <= $mxw) {
  17726.                 $table['maw'] = $mxw $table['w'];
  17727.             } elseif ($table['w'] >= $checkminwidth && $table['w'] > $mxw && $this->keep_table_proportions) {
  17728.                 $checkminwidth $table['w'];
  17729.             } elseif ($table['w'] < $checkminwidth && $checkminwidth $mxw && $this->keep_table_proportions) {
  17730.                 $table['maw'] = $table['w'] = $checkminwidth;
  17731.             } else {
  17732.                 unset($table['w']);
  17733.             }
  17734.         }
  17735.         $ratio $checkminwidth $mxw;
  17736.         if ($checkminwidth $mxw) {
  17737.             return [($ratio 0.001), $checkminwidth]; // 0.001 to allow for rounded numbers when resizing
  17738.         }
  17739.         unset($cs);
  17740.         return [00];
  17741.     }
  17742.     function _tableWidth(&$table)
  17743.     {
  17744.         $widthcols = &$table['wc'];
  17745.         $numcols $table['nc'];
  17746.         $tablewidth 0;
  17747.         if ($table['borders_separate']) {
  17748.             $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'];
  17749.         } else {
  17750.             $tblbw $table['max_cell_border_width']['L'] / $table['max_cell_border_width']['R'] / $table['margin']['L'] + $table['margin']['R'];
  17751.         }
  17752.         if ($table['level'] > && isset($table['w'])) {
  17753.             if (isset($table['wpercent']) && $table['wpercent']) {
  17754.                 $table['w'] = $temppgwidth = (($table['w'] - $tblbw) * $table['wpercent'] / 100) + $tblbw;
  17755.             } else {
  17756.                 $temppgwidth $table['w'];
  17757.             }
  17758.         } elseif ($this->table_rotate) {
  17759.             $temppgwidth $this->tbrot_maxw;
  17760.             // If it is less than 1/20th of the remaining page height to finish the DIV (i.e. DIV padding + table bottom margin) then allow for this
  17761.             $enddiv $this->blk[$this->blklvl]['padding_bottom'] + $this->blk[$this->blklvl]['border_bottom']['w'];
  17762.             if ($enddiv $temppgwidth 0.05) {
  17763.                 $temppgwidth -= $enddiv;
  17764.             }
  17765.         } else {
  17766.             if (isset($table['w']) && $table['w'] < $this->blk[$this->blklvl]['inner_width']) {
  17767.                 $notfullwidth 1;
  17768.                 $temppgwidth $table['w'];
  17769.             } elseif ($table['overflow'] == 'visible' && $table['level'] == 1) {
  17770.                 $temppgwidth null;
  17771.             } elseif ($table['overflow'] == 'hidden' && !$this->ColActive && isset($table['w']) && $table['w'] > $this->blk[$this->blklvl]['inner_width'] && $table['w'] == $table) {
  17772.                 // $temppgwidth = $this->blk[$this->blklvl]['inner_width'];
  17773.                 $temppgwidth $table['w'];
  17774.             } else {
  17775.                 $temppgwidth $this->blk[$this->blklvl]['inner_width'];
  17776.             }
  17777.         }
  17778.         $totaltextlength 0// Added - to sum $table['l'][colno]
  17779.         $totalatextlength 0// Added - to sum $table['l'][colno] for those columns where width not set
  17780.         $percentages_set 0;
  17781.         for ($i 0$i $numcols$i++) {
  17782.             if (isset($widthcols[$i]['wpercent'])) {
  17783.                 $tablewidth += $widthcols[$i]['maw'];
  17784.                 $percentages_set 1;
  17785.             } elseif (isset($widthcols[$i]['w'])) {
  17786.                 $tablewidth += $widthcols[$i]['miw'];
  17787.             } else {
  17788.                 $tablewidth += $widthcols[$i]['maw'];
  17789.             }
  17790.             $totaltextlength += isset($table['l']) ? $table['l'][$i] : 0;
  17791.         }
  17792.         if (!$totaltextlength) {
  17793.             $totaltextlength 1;
  17794.         }
  17795.         $tablewidth += $tblbw// Outer half of table borders
  17796.         if ($tablewidth $temppgwidth) {
  17797.             $table['w'] = $temppgwidth;
  17798.         } elseif ($tablewidth $temppgwidth && !isset($table['w']) && $percentages_set) { // if any widths set as percentages and max width fits < page width
  17799.             $table['w'] = $table['maw'];
  17800.         }
  17801.         // if table width is set and is > allowed width
  17802.         if (isset($table['w']) && $table['w'] > $temppgwidth) {
  17803.             $table['w'] = $temppgwidth;
  17804.         }
  17805.         // IF the table width is now set - Need to distribute columns widths
  17806.         // mPDF 5.7.3
  17807.         // If the table width is already set to the maximum width (e.g. nested table), then use maximum column widths exactly
  17808.         if (isset($table['w']) && ($table['w'] == $tablewidth) && !$percentages_set) {
  17809.             // This sets the columns all to maximum width
  17810.             for ($i 0$i $numcols$i++) {
  17811.                 $widthcols[$i] = $widthcols[$i]['maw'];
  17812.             }
  17813.         } elseif (isset($table['w'])) { // elseif the table width is set distribute width using algorithm
  17814.             $wis $wisa 0;
  17815.             $list = [];
  17816.             $notsetlist = [];
  17817.             for ($i 0$i $numcols$i++) {
  17818.                 $wis += $widthcols[$i]['miw'];
  17819.                 if (!isset($widthcols[$i]['w']) || ($widthcols[$i]['w'] && $table['w'] > $temppgwidth && !$this->keep_table_proportions && !$notfullwidth )) {
  17820.                     $list[] = $i;
  17821.                     $wisa += $widthcols[$i]['miw'];
  17822.                     $totalatextlength += $table['l'][$i];
  17823.                 }
  17824.             }
  17825.             if (!$totalatextlength) {
  17826.                 $totalatextlength 1;
  17827.             }
  17828.             // Allocate spare (more than col's minimum width) across the cols according to their approx total text length
  17829.             // Do it by setting minimum width here
  17830.             if ($table['w'] > $wis $tblbw) {
  17831.                 // First set any cell widths set as percentages
  17832.                 if ($table['w'] < $temppgwidth || $this->keep_table_proportions) {
  17833.                     for ($k 0$k $numcols$k++) {
  17834.                         if (isset($widthcols[$k]['wpercent'])) {
  17835.                             $curr $widthcols[$k]['miw'];
  17836.                             $widthcols[$k]['miw'] = ($table['w'] - $tblbw) * $widthcols[$k]['wpercent'] / 100;
  17837.                             $wis += $widthcols[$k]['miw'] - $curr;
  17838.                             $wisa += $widthcols[$k]['miw'] - $curr;
  17839.                         }
  17840.                     }
  17841.                 }
  17842.                 // Now allocate surplus up to maximum width of each column
  17843.                 $surplus 0;
  17844.                 $ttl 0// number of surplus columns
  17845.                 if (!count($list)) {
  17846.                     $wi = ($table['w'] - ($wis $tblbw)); // i.e. extra space to distribute
  17847.                     for ($k 0$k $numcols$k++) {
  17848.                         $spareratio = ($table['l'][$k] / $totaltextlength); //  gives ratio to divide up free space
  17849.                         // Don't allocate more than Maximum required width - save rest in surplus
  17850.                         if ($widthcols[$k]['miw'] + ($wi $spareratio) >= $widthcols[$k]['maw']) { // mPDF 5.7.3
  17851.                             $surplus += ($wi $spareratio) - ($widthcols[$k]['maw'] - $widthcols[$k]['miw']);
  17852.                             $widthcols[$k]['miw'] = $widthcols[$k]['maw'];
  17853.                         } else {
  17854.                             $notsetlist[] = $k;
  17855.                             $ttl += $table['l'][$k];
  17856.                             $widthcols[$k]['miw'] += ($wi $spareratio);
  17857.                         }
  17858.                     }
  17859.                 } else {
  17860.                     $wi = ($table['w'] - ($wis $tblbw)); // i.e. extra space to distribute
  17861.                     foreach ($list as $k) {
  17862.                         $spareratio = ($table['l'][$k] / $totalatextlength); //  gives ratio to divide up free space
  17863.                         // Don't allocate more than Maximum required width - save rest in surplus
  17864.                         if ($widthcols[$k]['miw'] + ($wi $spareratio) >= $widthcols[$k]['maw']) { // mPDF 5.7.3
  17865.                             $surplus += ($wi $spareratio) - ($widthcols[$k]['maw'] - $widthcols[$k]['miw']);
  17866.                             $widthcols[$k]['miw'] = $widthcols[$k]['maw'];
  17867.                         } else {
  17868.                             $notsetlist[] = $k;
  17869.                             $ttl += $table['l'][$k];
  17870.                             $widthcols[$k]['miw'] += ($wi $spareratio);
  17871.                         }
  17872.                     }
  17873.                 }
  17874.                 // If surplus still left over apportion it across columns
  17875.                 if ($surplus) {
  17876.                     if (count($notsetlist) && count($notsetlist) < $numcols) { // if some are set only add to remaining - otherwise add to all of them
  17877.                         foreach ($notsetlist as $i) {
  17878.                             if ($ttl) {
  17879.                                 $widthcols[$i]['miw'] += $surplus $table['l'][$i] / $ttl;
  17880.                             }
  17881.                         }
  17882.                     } elseif (count($list) && count($list) < $numcols) { // If some widths are defined, and others have been added up to their maxmum
  17883.                         foreach ($list as $i) {
  17884.                             $widthcols[$i]['miw'] += $surplus count($list);
  17885.                         }
  17886.                     } elseif ($numcols) { // If all columns
  17887.                         $ttl array_sum($table['l']);
  17888.                         if ($ttl) {
  17889.                             for ($i 0$i $numcols$i++) {
  17890.                                 $widthcols[$i]['miw'] += $surplus $table['l'][$i] / $ttl;
  17891.                             }
  17892.                         }
  17893.                     }
  17894.                 }
  17895.             }
  17896.             // This sets the columns all to minimum width (which has been increased above if appropriate)
  17897.             for ($i 0$i $numcols$i++) {
  17898.                 $widthcols[$i] = $widthcols[$i]['miw'];
  17899.             }
  17900.             // TABLE NOT WIDE ENOUGH EVEN FOR MINIMUM CONTENT WIDTH
  17901.             // If sum of column widths set are too wide for table
  17902.             $checktablewidth 0;
  17903.             for ($i 0$i $numcols$i++) {
  17904.                 $checktablewidth += $widthcols[$i];
  17905.             }
  17906.             if ($checktablewidth > ($temppgwidth 0.001 $tblbw)) {
  17907.                 $usedup 0;
  17908.                 $numleft 0;
  17909.                 for ($i 0$i $numcols$i++) {
  17910.                     if ((isset($widthcols[$i]) && $widthcols[$i] > (($temppgwidth $tblbw) / $numcols)) && (!isset($widthcols[$i]['w']))) {
  17911.                         $numleft++;
  17912.                         unset($widthcols[$i]);
  17913.                     } else {
  17914.                         $usedup += $widthcols[$i];
  17915.                     }
  17916.                 }
  17917.                 for ($i 0$i $numcols$i++) {
  17918.                     if (!isset($widthcols[$i]) || !$widthcols[$i]) {
  17919.                         $widthcols[$i] = ((($temppgwidth $tblbw) - $usedup) / ($numleft));
  17920.                     }
  17921.                 }
  17922.             }
  17923.         } else { // table has no width defined
  17924.             $table['w'] = $tablewidth;
  17925.             for ($i 0$i $numcols$i++) {
  17926.                 if (isset($widthcols[$i]['wpercent']) && $this->keep_table_proportions) {
  17927.                     $colwidth $widthcols[$i]['maw'];
  17928.                 } elseif (isset($widthcols[$i]['w'])) {
  17929.                     $colwidth $widthcols[$i]['miw'];
  17930.                 } else {
  17931.                     $colwidth $widthcols[$i]['maw'];
  17932.                 }
  17933.                 unset($widthcols[$i]);
  17934.                 $widthcols[$i] = $colwidth;
  17935.             }
  17936.         }
  17937.         if ($table['overflow'] === 'visible' && $table['level'] == 1) {
  17938.             if ($tablewidth $this->blk[$this->blklvl]['inner_width']) {
  17939.                 for ($j 0$j $numcols$j++) { // columns
  17940.                     for ($i 0$i $table['nr']; $i++) { // rows
  17941.                         if (isset($table['cells'][$i][$j]) && $table['cells'][$i][$j]) {
  17942.                             $colspan = (isset($table['cells'][$i][$j]['colspan']) ? $table['cells'][$i][$j]['colspan'] : 1);
  17943.                             if ($colspan 1) {
  17944.                                 $w 0;
  17945.                                 for ($c $j$c < ($j $colspan); $c++) {
  17946.                                     $w += $widthcols[$c];
  17947.                                 }
  17948.                                 if ($w $this->blk[$this->blklvl]['inner_width']) {
  17949.                                     $diff $w - ($this->blk[$this->blklvl]['inner_width'] - $tblbw);
  17950.                                     for ($c $j$c < ($j $colspan); $c++) {
  17951.                                         $widthcols[$c] -= $diff * ($widthcols[$c] / $w);
  17952.                                     }
  17953.                                     $table['w'] -= $diff;
  17954.                                     $table['csp'][$j] = $w $diff;
  17955.                                 }
  17956.                             }
  17957.                         }
  17958.                     }
  17959.                 }
  17960.             }
  17961.             $pgNo 0;
  17962.             $currWc 0;
  17963.             for ($i 0$i $numcols$i++) { // columns
  17964.                 if (isset($table['csp'][$i])) {
  17965.                     $w $table['csp'][$i];
  17966.                     unset($table['csp'][$i]);
  17967.                 } else {
  17968.                     $w $widthcols[$i];
  17969.                 }
  17970.                 if (($currWc $w $tblbw) > $this->blk[$this->blklvl]['inner_width']) {
  17971.                     $pgNo++;
  17972.                     $currWc $widthcols[$i];
  17973.                 } else {
  17974.                     $currWc += $widthcols[$i];
  17975.                 }
  17976.                 $table['colPg'][$i] = $pgNo;
  17977.             }
  17978.         }
  17979.     }
  17980.     function _tableHeight(&$table)
  17981.     {
  17982.         $level $table['level'];
  17983.         $levelid $table['levelid'];
  17984.         $cells = &$table['cells'];
  17985.         $numcols $table['nc'];
  17986.         $numrows $table['nr'];
  17987.         $listspan = [];
  17988.         $checkmaxheight 0;
  17989.         $headerrowheight 0;
  17990.         $checkmaxheightplus 0;
  17991.         $headerrowheightplus 0;
  17992.         $firstrowheight 0;
  17993.         $footerrowheight 0;
  17994.         $footerrowheightplus 0;
  17995.         if ($this->table_rotate) {
  17996.             $temppgheight $this->tbrot_maxh;
  17997.             $remainingpage $this->tbrot_maxh;
  17998.         } else {
  17999.             $temppgheight = ($this->$this->bMargin $this->tMargin) - $this->kwt_height;
  18000.             $remainingpage = ($this->$this->bMargin $this->y) - $this->kwt_height;
  18001.             // If it is less than 1/20th of the remaining page height to finish the DIV (i.e. DIV padding + table bottom margin)
  18002.             // then allow for this
  18003.             $enddiv $this->blk[$this->blklvl]['padding_bottom'] + $this->blk[$this->blklvl]['border_bottom']['w'] + $table['margin']['B'];
  18004.             if ($remainingpage $enddiv && $enddiv $remainingpage 0.05) {
  18005.                 $remainingpage -= $enddiv;
  18006.             } elseif ($remainingpage == 0) {
  18007.                 $remainingpage 0.001;
  18008.             }
  18009.             if ($temppgheight $enddiv && $enddiv $temppgheight 0.05) {
  18010.                 $temppgheight -= $enddiv;
  18011.             } elseif ($temppgheight == 0) {
  18012.                 $temppgheight 0.001;
  18013.             }
  18014.         }
  18015.         if ($remainingpage 0) {
  18016.             $remainingpage 0.001;
  18017.         }
  18018.         if ($temppgheight 0) {
  18019.             $temppgheight 0.001;
  18020.         }
  18021.         for ($i 0$i $numrows$i++) { // rows
  18022.             $heightrow = &$table['hr'][$i];
  18023.             for ($j 0$j $numcols$j++) { // columns
  18024.                 if (isset($cells[$i][$j]) && $cells[$i][$j]) {
  18025.                     $c = &$cells[$i][$j];
  18026.                     if ($this->simpleTables) {
  18027.                         if ($table['borders_separate']) { // NB twice border width
  18028.                             $extraWLR = ($table['simple']['border_details']['L']['w'] + $table['simple']['border_details']['R']['w']) + ($c['padding']['L'] + $c['padding']['R']) + $table['border_spacing_H'];
  18029.                             $extrh = ($table['simple']['border_details']['T']['w'] + $table['simple']['border_details']['B']['w']) + ($c['padding']['T'] + $c['padding']['B']) + $table['border_spacing_V'];
  18030.                         } else {
  18031.                             $extraWLR = ($table['simple']['border_details']['L']['w'] + $table['simple']['border_details']['R']['w']) / + ($c['padding']['L'] + $c['padding']['R']);
  18032.                             $extrh = ($table['simple']['border_details']['T']['w'] + $table['simple']['border_details']['B']['w']) / + ($c['padding']['T'] + $c['padding']['B']);
  18033.                         }
  18034.                     } else {
  18035.                         if ($this->packTableData) {
  18036.                             list($bt$br$bb$bl) = $this->_getBorderWidths($c['borderbin']);
  18037.                         } else {
  18038.                             $bt $c['border_details']['T']['w'];
  18039.                             $bb $c['border_details']['B']['w'];
  18040.                             $br $c['border_details']['R']['w'];
  18041.                             $bl $c['border_details']['L']['w'];
  18042.                         }
  18043.                         if ($table['borders_separate']) { // NB twice border width
  18044.                             $extraWLR $bl $br $c['padding']['L'] + $c['padding']['R'] + $table['border_spacing_H'];
  18045.                             $extrh $bt $bb $c['padding']['T'] + $c['padding']['B'] + $table['border_spacing_V'];
  18046.                         } else {
  18047.                             $extraWLR $bl $br $c['padding']['L'] + $c['padding']['R'];
  18048.                             $extrh $bt $bb $c['padding']['T'] + $c['padding']['B'];
  18049.                         }
  18050.                     }
  18051.                     if ($table['overflow'] == 'visible' && $level == 1) {
  18052.                         list($x$cw) = $this->_splitTableGetWidth($table$i$j);
  18053.                     } else {
  18054.                         list($x$cw) = $this->_tableGetWidth($table$i$j);
  18055.                     }
  18056.                     // Get CELL HEIGHT
  18057.                     // ++ extra parameter forces wrap to break word
  18058.                     if ($c['R'] && isset($c['textbuffer'])) {
  18059.                         $str '';
  18060.                         foreach ($c['textbuffer'] as $t) {
  18061.                             $str .= $t[0] . ' ';
  18062.                         }
  18063.                         $str rtrim($str);
  18064.                         $s_fs $this->FontSizePt;
  18065.                         $s_f $this->FontFamily;
  18066.                         $s_st $this->FontStyle;
  18067.                         $this->SetFont($c['textbuffer'][0][4], $c['textbuffer'][0][2], $c['textbuffer'][0][11] / $this->shrin_ktruetrue);
  18068.                         $tempch $this->GetStringWidth($strtrue$c['textbuffer'][0][18], $c['textbuffer'][0][8]);
  18069.                         if ($c['R'] >= 45 && $c['R'] < 90) {
  18070.                             $tempch = ((sin(deg2rad($c['R']))) * $tempch ) + ((sin(deg2rad($c['R']))) * (($c['textbuffer'][0][11] / Mpdf::SCALE) / $this->shrin_k));
  18071.                         }
  18072.                         $this->SetFont($s_f$s_st$s_fstruetrue);
  18073.                         $ch = ($tempch ) + $extrh;
  18074.                     } else {
  18075.                         if (isset($c['textbuffer']) && !empty($c['textbuffer'])) {
  18076.                             $this->cellLineHeight $c['cellLineHeight'];
  18077.                             $this->cellLineStackingStrategy $c['cellLineStackingStrategy'];
  18078.                             $this->cellLineStackingShift $c['cellLineStackingShift'];
  18079.                             $this->divwidth $cw $extraWLR;
  18080.                             $tempch $this->printbuffer($c['textbuffer'], ''truetrue);
  18081.                         } else {
  18082.                             $tempch 0;
  18083.                         }
  18084.                         // Added cellpadding top and bottom. (Lineheight already adjusted)
  18085.                         $ch $tempch $extrh;
  18086.                     }
  18087.                     // If height is defined and it is bigger than calculated $ch then update values
  18088.                     if (isset($c['h']) && $c['h'] > $ch) {
  18089.                         $c['mih'] = $ch// in order to keep valign working
  18090.                         $ch $c['h'];
  18091.                     } else {
  18092.                         $c['mih'] = $ch;
  18093.                     }
  18094.                     if (isset($c['rowspan'])) {
  18095.                         $listspan[] = [$i$j];
  18096.                     } elseif ($heightrow $ch) {
  18097.                         $heightrow $ch;
  18098.                     }
  18099.                     // this is the extra used in _tableWrite to determine whether to trigger a page change
  18100.                     if ($table['borders_separate']) {
  18101.                         if ($i == ($numrows 1) || (isset($c['rowspan']) && ($i $c['rowspan']) == ($numrows))) {
  18102.                             $extra $table['margin']['B'] + $table['padding']['B'] + $table['border_details']['B']['w'] + $table['border_spacing_V'] / 2;
  18103.                         } else {
  18104.                             $extra $table['border_spacing_V'] / 2;
  18105.                         }
  18106.                     } else {
  18107.                         if (!$this->simpleTables) {
  18108.                             $extra $bb 2;
  18109.                         } elseif ($this->simpleTables) {
  18110.                             $extra $table['simple']['border_details']['B']['w'] / 2;
  18111.                         }
  18112.                     }
  18113.                     if (isset($table['is_thead'][$i]) && $table['is_thead'][$i]) {
  18114.                         if ($j == 0) {
  18115.                             $headerrowheight += $ch;
  18116.                             $headerrowheightplus += $ch $extra;
  18117.                         }
  18118.                     } elseif (isset($table['is_tfoot'][$i]) && $table['is_tfoot'][$i]) {
  18119.                         if ($j == 0) {
  18120.                             $footerrowheight += $ch;
  18121.                             $footerrowheightplus += $ch $extra;
  18122.                         }
  18123.                     } else {
  18124.                         $checkmaxheight max($checkmaxheight$ch);
  18125.                         $checkmaxheightplus max($checkmaxheightplus$ch $extra);
  18126.                     }
  18127.                     if ($this->tableLevel == && $i == (isset($table['headernrows']) ? $table['headernrows'] : 0)) {
  18128.                         $firstrowheight max($ch$firstrowheight);
  18129.                     }
  18130.                     unset($c);
  18131.                 }
  18132.             }//end of columns
  18133.         }//end of rows
  18134.         $heightrow = &$table['hr'];
  18135.         foreach ($listspan as $span) {
  18136.             list($i$j) = $span;
  18137.             $c = &$cells[$i][$j];
  18138.             $lr $i $c['rowspan'];
  18139.             if ($lr $numrows) {
  18140.                 $lr $numrows;
  18141.             }
  18142.             $hs $hsa 0;
  18143.             $list = [];
  18144.             for ($k $i$k $lr$k++) {
  18145.                 $hs += $heightrow[$k];
  18146.                 // mPDF 6
  18147.                 $sh false// specified height
  18148.                 for ($m 0$m $numcols$m++) { // columns
  18149.                     $tc = &$cells[$k][$m];
  18150.                     if (isset($tc['rowspan'])) {
  18151.                         continue;
  18152.                     }
  18153.                     if (isset($tc['h'])) {
  18154.                         $sh true;
  18155.                         break;
  18156.                     }
  18157.                 }
  18158.                 if (!$sh) {
  18159.                     $list[] = $k;
  18160.                 }
  18161.             }
  18162.             if ($table['borders_separate']) {
  18163.                 if ($i == ($numrows 1) || ($i $c['rowspan']) == ($numrows)) {
  18164.                     $extra $table['margin']['B'] + $table['padding']['B'] + $table['border_details']['B']['w'] + $table['border_spacing_V'] / 2;
  18165.                 } else {
  18166.                     $extra $table['border_spacing_V'] / 2;
  18167.                 }
  18168.             } else {
  18169.                 if (!$this->simpleTables) {
  18170.                     if ($this->packTableData) {
  18171.                         list($bt$br$bb$bl) = $this->_getBorderWidths($c['borderbin']);
  18172.                     } else {
  18173.                         $bb $c['border_details']['B']['w'];
  18174.                     }
  18175.                     $extra $bb 2;
  18176.                 } elseif ($this->simpleTables) {
  18177.                     $extra $table['simple']['border_details']['B']['w'] / 2;
  18178.                 }
  18179.             }
  18180.             if (!empty($table['is_thead'][$i])) {
  18181.                 $headerrowheight max($headerrowheight$hs);
  18182.                 $headerrowheightplus max($headerrowheightplus$hs $extra);
  18183.             } elseif (!empty($table['is_tfoot'][$i])) {
  18184.                 $footerrowheight max($footerrowheight$hs);
  18185.                 $footerrowheightplus max($footerrowheightplus$hs $extra);
  18186.             } else {
  18187.                 $checkmaxheight max($checkmaxheight$hs);
  18188.                 $checkmaxheightplus max($checkmaxheightplus$hs $extra);
  18189.             }
  18190.             if ($this->tableLevel == && $i == (isset($table['headernrows']) ? $table['headernrows'] : 0)) {
  18191.                 $firstrowheight max($hs$firstrowheight);
  18192.             }
  18193.             if ($c['mih'] > $hs) {
  18194.                 if (!$hs) {
  18195.                     for ($k $i$k $lr$k++) {
  18196.                         $heightrow[$k] = $c['mih'] / $c['rowspan'];
  18197.                     }
  18198.                 } elseif (!count($list)) { // no rows in the rowspan have a height specified, so share amongst all rows equally
  18199.                     $hi $c['mih'] - $hs;
  18200.                     for ($k $i$k $lr$k++) {
  18201.                         $heightrow[$k] += ($heightrow[$k] / $hs) * $hi;
  18202.                     }
  18203.                 } else {
  18204.                     $hi $c['mih'] - $hs// mPDF 6
  18205.                     foreach ($list as $k) {
  18206.                         $heightrow[$k] += $hi / (count($list)); // mPDF 6
  18207.                     }
  18208.                 }
  18209.             }
  18210.             unset($c);
  18211.             // If rowspans overlap so that one or more rows do not have a height set...
  18212.             // i.e. for one or more rows, the only cells (explicit) in that row have rowspan>1
  18213.             // so heightrow is still == 0
  18214.             if ($heightrow[$i] == 0) {
  18215.                 // Get row extent to analyse above and below
  18216.                 $top $i;
  18217.                 foreach ($listspan as $checkspan) {
  18218.                     list($cki$ckj) = $checkspan;
  18219.                     $c = &$cells[$cki][$ckj];
  18220.                     if (isset($c['rowspan']) && $c['rowspan'] > 1) {
  18221.                         if (($cki $c['rowspan'] - 1) >= $i) {
  18222.                             $top min($top$cki);
  18223.                         }
  18224.                     }
  18225.                 }
  18226.                 $bottom $i $c['rowspan'] - 1;
  18227.                 // Check for overconstrained conditions
  18228.                 for ($k $top$k <= $bottom$k++) {
  18229.                     // if ['hr'] for any of the others is also 0, then abort (too complicated)
  18230.                     if ($k != $i && $heightrow[$k] == 0) {
  18231.                         break(1);
  18232.                     }
  18233.                     // check again that top and bottom are not crossed by rowspans - or abort (too complicated)
  18234.                     if ($k == $top) {
  18235.                         // ???? take account of colspan as well???
  18236.                         for ($m 0$m $numcols$m++) { // columns
  18237.                             if (!isset($cells[$k][$m]) || $cells[$k][$m] == 0) {
  18238.                                 break(2);
  18239.                             }
  18240.                         }
  18241.                     } elseif ($k == $bottom) {
  18242.                         // ???? take account of colspan as well???
  18243.                         for ($m 0$m $numcols$m++) { // columns
  18244.                             $c = &$cells[$k][$m];
  18245.                             if (isset($c['rowspan']) && $c['rowspan'] > 1) {
  18246.                                 break(2);
  18247.                             }
  18248.                         }
  18249.                     }
  18250.                 }
  18251.                 // By columns add up col height using ['h'] if set or ['mih'] if not
  18252.                 // Intentionally do not substract border-spacing
  18253.                 $colH = [];
  18254.                 $extH 0;
  18255.                 $newhr = [];
  18256.                 for ($m 0$m $numcols$m++) { // columns
  18257.                     for ($k $top$k <= $bottom$k++) {
  18258.                         if (isset($cells[$k][$m]) && $cells[$k][$m] != 0) {
  18259.                             $c = &$cells[$k][$m];
  18260.                             if (isset($c['h']) && $c['h']) {
  18261.                                 $useh $c['h'];
  18262.                             } // ???? take account of colspan as well???
  18263.                             else {
  18264.                                 $useh $c['mih'];
  18265.                             }
  18266.                             if (isset($colH[$m])) {
  18267.                                 $colH[$m] += $useh;
  18268.                             } else {
  18269.                                 $colH[$m] = $useh;
  18270.                             }
  18271.                             if (!isset($c['rowspan']) || $c['rowspan'] < 2) {
  18272.                                 $newhr[$k] = max((isset($newhr[$k]) ? $newhr[$k] : 0), $useh);
  18273.                             }
  18274.                         }
  18275.                     }
  18276.                     $extH max($extH$colH[$m]); // mPDF 6
  18277.                 }
  18278.                 $newhr[$i] = $extH array_sum($newhr);
  18279.                 for ($k $top$k <= $bottom$k++) {
  18280.                     $heightrow[$k] = $newhr[$k];
  18281.                 }
  18282.             }
  18283.             unset($c);
  18284.         }
  18285.         $table['h'] = array_sum($heightrow);
  18286.         unset($heightrow);
  18287.         if ($table['borders_separate']) {
  18288.             $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'];
  18289.         } else {
  18290.             $table['h'] += $table['margin']['T'] + $table['margin']['B'] + $table['max_cell_border_width']['T'] / $table['max_cell_border_width']['B'] / 2;
  18291.         }
  18292.         $maxrowheight $checkmaxheightplus $headerrowheightplus $footerrowheightplus;
  18293.         $maxfirstrowheight $firstrowheight $headerrowheightplus $footerrowheightplus// includes thead, 1st row and tfoot
  18294.         return [$table['h'], $maxrowheight$temppgheight$remainingpage$maxfirstrowheight];
  18295.     }
  18296.     function _tableGetWidth(&$table$i$j)
  18297.     {
  18298.         $cell = &$table['cells'][$i][$j];
  18299.         if ($cell) {
  18300.             if (isset($cell['x0'])) {
  18301.                 return [$cell['x0'], $cell['w0']];
  18302.             }
  18303.             $x 0;
  18304.             $widthcols = &$table['wc'];
  18305.             for ($k 0$k $j$k++) {
  18306.                 $x += $widthcols[$k];
  18307.             }
  18308.             $w $widthcols[$j];
  18309.             if (isset($cell['colspan'])) {
  18310.                 for ($k $j $cell['colspan'] - 1$k $j$k--) {
  18311.                     $w += $widthcols[$k];
  18312.                 }
  18313.             }
  18314.             $cell['x0'] = $x;
  18315.             $cell['w0'] = $w;
  18316.             return [$x$w];
  18317.         }
  18318.         return [00];
  18319.     }
  18320.     function _splitTableGetWidth(&$table$i$j)
  18321.     {
  18322.         $cell = &$table['cells'][$i][$j];
  18323.         if ($cell) {
  18324.             if (isset($cell['x0'])) {
  18325.                 return [$cell['x0'], $cell['w0']];
  18326.             }
  18327.             $x 0;
  18328.             $widthcols = &$table['wc'];
  18329.             $pg $table['colPg'][$j];
  18330.             for ($k 0$k $j$k++) {
  18331.                 if ($table['colPg'][$k] == $pg) {
  18332.                     $x += $widthcols[$k];
  18333.                 }
  18334.             }
  18335.             $w $widthcols[$j];
  18336.             if (isset($cell['colspan'])) {
  18337.                 for ($k $j $cell['colspan'] - 1$k $j$k--) {
  18338.                     if ($table['colPg'][$k] == $pg) {
  18339.                         $w += $widthcols[$k];
  18340.                     }
  18341.                 }
  18342.             }
  18343.             $cell['x0'] = $x;
  18344.             $cell['w0'] = $w;
  18345.             return [$x$w];
  18346.         }
  18347.         return [00];
  18348.     }
  18349.     function _tableGetHeight(&$table$i$j)
  18350.     {
  18351.         $cell = &$table['cells'][$i][$j];
  18352.         if ($cell) {
  18353.             if (isset($cell['y0'])) {
  18354.                 return [$cell['y0'], $cell['h0']];
  18355.             }
  18356.             $y 0;
  18357.             $heightrow = &$table['hr'];
  18358.             for ($k 0$k $i$k++) {
  18359.                 $y += $heightrow[$k];
  18360.             }
  18361.             $h $heightrow[$i];
  18362.             if (isset($cell['rowspan'])) {
  18363.                 for ($k $i $cell['rowspan'] - 1$k $i$k--) {
  18364.                     if (array_key_exists($k$heightrow)) {
  18365.                         $h += $heightrow[$k];
  18366.                     } else {
  18367.                         $this->logger->debug('Possible non-wellformed HTML markup in a table', ['context' => LogContext::HTML_MARKUP]);
  18368.                     }
  18369.                 }
  18370.             }
  18371.             $cell['y0'] = $y;
  18372.             $cell['h0'] = $h;
  18373.             return [$y$h];
  18374.         }
  18375.         return [00];
  18376.     }
  18377.     function _tableGetMaxRowHeight($table$row)
  18378.     {
  18379.         if ($row == $table['nc'] - 1) {
  18380.             return $table['hr'][$row];
  18381.         }
  18382.         $maxrowheight $table['hr'][$row];
  18383.         for ($i $row 1$i $table['nr']; $i++) {
  18384.             $cellsset 0;
  18385.             for ($j 0$j $table['nc']; $j++) {
  18386.                 if (!empty($table['cells'][$i][$j])) {
  18387.                     if (isset($table['cells'][$i][$j]['colspan'])) {
  18388.                         $cellsset += $table['cells'][$i][$j]['colspan'];
  18389.                     } else {
  18390.                         $cellsset += 1;
  18391.                     }
  18392.                 }
  18393.             }
  18394.             if ($cellsset == $table['nc']) {
  18395.                 return $maxrowheight;
  18396.             } else {
  18397.                 $maxrowheight += $table['hr'][$i];
  18398.             }
  18399.         }
  18400.         return $maxrowheight;
  18401.     }
  18402.     // CHANGED TO ALLOW TABLE BORDER TO BE SPECIFIED CORRECTLY - added border_details
  18403.     function _tableRect($x$y$w$h$bord = -1$details = [], $buffer false$bSeparate false$cort 'cell'$tablecorner ''$bsv 0$bsh 0)
  18404.     {
  18405.         $cellBorderOverlay = [];
  18406.         if ($bord == -1) {
  18407.             $this->Rect($x$y$w$h);
  18408.         } elseif ($this->simpleTables && ($cort == 'cell')) {
  18409.             $this->SetLineWidth($details['L']['w']);
  18410.             if ($details['L']['c']) {
  18411.                 $this->SetDColor($details['L']['c']);
  18412.             } else {
  18413.                 $this->SetDColor($this->colorConverter->convert(0$this->PDFAXwarnings));
  18414.             }
  18415.             $this->SetLineJoin(0);
  18416.             $this->Rect($x$y$w$h);
  18417.         } elseif ($bord) {
  18418.             if (!$bSeparate && $buffer) {
  18419.                 $priority 'LRTB';
  18420.                 for ($p 0$p strlen($priority); $p++) {
  18421.                     $side $priority[$p];
  18422.                     $details['p'] = $side;
  18423.                     $dom 0;
  18424.                     if (isset($details[$side]['w'])) {
  18425.                         $dom += ($details[$side]['w'] * 100000);
  18426.                     }
  18427.                     if (isset($details[$side]['style'])) {
  18428.                         $dom += (array_search($details[$side]['style'], $this->borderstyles) * 100);
  18429.                     }
  18430.                     if (isset($details[$side]['dom'])) {
  18431.                         $dom += ($details[$side]['dom'] * 10);
  18432.                     }
  18433.                     // Precedence to darker colours at joins
  18434.                     $coldom 0;
  18435.                     if (isset($details[$side]['c']) && is_array($details[$side]['c'])) {
  18436.                         if ($details[$side]['c'][0] == 3) {  // RGB
  18437.                             $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);
  18438.                         }
  18439.                     } // 10 black - 0 white
  18440.                     if ($coldom) {
  18441.                         $dom += $coldom;
  18442.                     }
  18443.                     // Lastly precedence to RIGHT and BOTTOM cells at joins
  18444.                     if (isset($details['cellposdom'])) {
  18445.                         $dom += $details['cellposdom'];
  18446.                     }
  18447.                     $save false;
  18448.                     if ($side == 'T' && $this->issetBorder($bordBorder::TOP)) {
  18449.                         $cbord Border::TOP;
  18450.                         $save true;
  18451.                     } elseif ($side == 'L' && $this->issetBorder($bordBorder::LEFT)) {
  18452.                         $cbord Border::LEFT;
  18453.                         $save true;
  18454.                     } elseif ($side == 'R' && $this->issetBorder($bordBorder::RIGHT)) {
  18455.                         $cbord Border::RIGHT;
  18456.                         $save true;
  18457.                     } elseif ($side == 'B' && $this->issetBorder($bordBorder::BOTTOM)) {
  18458.                         $cbord Border::BOTTOM;
  18459.                         $save true;
  18460.                     }
  18461.                     if ($save) {
  18462.                         $this->cellBorderBuffer[] = pack("A16nCnda6A10d14"str_pad(sprintf("%08.7f"$dom), 16"0"STR_PAD_LEFT), $cbordord($side), $details[$side]['s'], $details[$side]['w'], $details[$side]['c'], $details[$side]['style'], $x$y$w$h$details['mbw']['BL'], $details['mbw']['BR'], $details['mbw']['RT'], $details['mbw']['RB'], $details['mbw']['TL'], $details['mbw']['TR'], $details['mbw']['LT'], $details['mbw']['LB'], $details['cellposdom'], 0);
  18463.                         if ($details[$side]['style'] == 'ridge' || $details[$side]['style'] == 'groove' || $details[$side]['style'] == 'inset' || $details[$side]['style'] == 'outset' || $details[$side]['style'] == 'double') {
  18464.                             $details[$side]['overlay'] = true;
  18465.                             $this->cellBorderBuffer[] = pack("A16nCnda6A10d14"str_pad(sprintf("%08.7f", ($dom 4)), 16"0"STR_PAD_LEFT), $cbordord($side), $details[$side]['s'], $details[$side]['w'], $details[$side]['c'], $details[$side]['style'], $x$y$w$h$details['mbw']['BL'], $details['mbw']['BR'], $details['mbw']['RT'], $details['mbw']['RB'], $details['mbw']['TL'], $details['mbw']['TR'], $details['mbw']['LT'], $details['mbw']['LB'], $details['cellposdom'], 1);
  18466.                         }
  18467.                     }
  18468.                 }
  18469.                 return;
  18470.             }
  18471.             if (isset($details['p']) && strlen($details['p']) > 1) {
  18472.                 $priority $details['p'];
  18473.             } else {
  18474.                 $priority 'LTRB';
  18475.             }
  18476.             $Tw 0;
  18477.             $Rw 0;
  18478.             $Bw 0;
  18479.             $Lw 0;
  18480.             if (isset($details['T']['w'])) {
  18481.                 $Tw $details['T']['w'];
  18482.             }
  18483.             if (isset($details['R']['w'])) {
  18484.                 $Rw $details['R']['w'];
  18485.             }
  18486.             if (isset($details['B']['w'])) {
  18487.                 $Bw $details['B']['w'];
  18488.             }
  18489.             if (isset($details['L']['w'])) {
  18490.                 $Lw $details['L']['w'];
  18491.             }
  18492.             $x2 $x $w;
  18493.             $y2 $y $h;
  18494.             $oldlinewidth $this->LineWidth;
  18495.             for ($p 0$p strlen($priority); $p++) {
  18496.                 $side $priority[$p];
  18497.                 $xadj 0;
  18498.                 $xadj2 0;
  18499.                 $yadj 0;
  18500.                 $yadj2 0;
  18501.                 $print false;
  18502.                 if ($Tw && $side == 'T' && $this->issetBorder($bordBorder::TOP)) { // TOP
  18503.                     $ly1 $y;
  18504.                     $ly2 $y;
  18505.                     $lx1 $x;
  18506.                     $lx2 $x2;
  18507.                     $this->SetLineWidth($Tw);
  18508.                     if ($cort == 'cell' || strpos($tablecorner'L') !== false) {
  18509.                         if ($Tw $Lw) {
  18510.                             $xadj = ($Tw $Lw) / 2;
  18511.                         }
  18512.                         if ($Tw $Lw) {
  18513.                             $xadj = ($Tw $Lw) / 2;
  18514.                         }
  18515.                     } else {
  18516.                         $xadj $Tw $bsh 2;
  18517.                     }
  18518.                     if ($cort == 'cell' || strpos($tablecorner'R') !== false) {
  18519.                         if ($Tw $Rw) {
  18520.                             $xadj2 = ($Tw $Rw) / 2;
  18521.                         }
  18522.                         if ($Tw $Rw) {
  18523.                             $xadj2 = ($Tw $Rw) / 2;
  18524.                         }
  18525.                     } else {
  18526.                         $xadj2 $Tw $bsh 2;
  18527.                     }
  18528.                     if (!$bSeparate && !empty($details['mbw']) && !empty($details['mbw']['TL'])) {
  18529.                         $xadj = ($Tw $details['mbw']['TL']) / 2;
  18530.                     }
  18531.                     if (!$bSeparate && !empty($details['mbw']) && !empty($details['mbw']['TR'])) {
  18532.                         $xadj2 = ($Tw $details['mbw']['TR']) / 2;
  18533.                     }
  18534.                     $print true;
  18535.                 }
  18536.                 if ($Lw && $side == 'L' && $this->issetBorder($bordBorder::LEFT)) { // LEFT
  18537.                     $ly1 $y;
  18538.                     $ly2 $y2;
  18539.                     $lx1 $x;
  18540.                     $lx2 $x;
  18541.                     $this->SetLineWidth($Lw);
  18542.                     if ($cort == 'cell' || strpos($tablecorner'T') !== false) {
  18543.                         if ($Lw $Tw) {
  18544.                             $yadj = ($Lw $Tw) / 2;
  18545.                         }
  18546.                         if ($Lw $Tw) {
  18547.                             $yadj = ($Lw $Tw) / 2;
  18548.                         }
  18549.                     } else {
  18550.                         $yadj $Lw $bsv 2;
  18551.                     }
  18552.                     if ($cort == 'cell' || strpos($tablecorner'B') !== false) {
  18553.                         if ($Lw $Bw) {
  18554.                             $yadj2 = ($Lw $Bw) / 2;
  18555.                         }
  18556.                         if ($Lw $Bw) {
  18557.                             $yadj2 = ($Lw $Bw) / 2;
  18558.                         }
  18559.                     } else {
  18560.                         $yadj2 $Lw $bsv 2;
  18561.                     }
  18562.                     if (!$bSeparate && $details['mbw']['LT']) {
  18563.                         $yadj = ($Lw $details['mbw']['LT']) / 2;
  18564.                     }
  18565.                     if (!$bSeparate && $details['mbw']['LB']) {
  18566.                         $yadj2 = ($Lw $details['mbw']['LB']) / 2;
  18567.                     }
  18568.                     $print true;
  18569.                 }
  18570.                 if ($Rw && $side == 'R' && $this->issetBorder($bordBorder::RIGHT)) { // RIGHT
  18571.                     $ly1 $y;
  18572.                     $ly2 $y2;
  18573.                     $lx1 $x2;
  18574.                     $lx2 $x2;
  18575.                     $this->SetLineWidth($Rw);
  18576.                     if ($cort == 'cell' || strpos($tablecorner'T') !== false) {
  18577.                         if ($Rw $Tw) {
  18578.                             $yadj = ($Rw $Tw) / 2;
  18579.                         }
  18580.                         if ($Rw $Tw) {
  18581.                             $yadj = ($Rw $Tw) / 2;
  18582.                         }
  18583.                     } else {
  18584.                         $yadj $Rw $bsv 2;
  18585.                     }
  18586.                     if ($cort == 'cell' || strpos($tablecorner'B') !== false) {
  18587.                         if ($Rw $Bw) {
  18588.                             $yadj2 = ($Rw $Bw) / 2;
  18589.                         }
  18590.                         if ($Rw $Bw) {
  18591.                             $yadj2 = ($Rw $Bw) / 2;
  18592.                         }
  18593.                     } else {
  18594.                         $yadj2 $Rw $bsv 2;
  18595.                     }
  18596.                     if (!$bSeparate && !empty($details['mbw']) && !empty($details['mbw']['RT'])) {
  18597.                         $yadj = ($Rw $details['mbw']['RT']) / 2;
  18598.                     }
  18599.                     if (!$bSeparate && !empty($details['mbw']) && !empty($details['mbw']['RB'])) {
  18600.                         $yadj2 = ($Rw $details['mbw']['RB']) / 2;
  18601.                     }
  18602.                     $print true;
  18603.                 }
  18604.                 if ($Bw && $side == 'B' && $this->issetBorder($bordBorder::BOTTOM)) { // BOTTOM
  18605.                     $ly1 $y2;
  18606.                     $ly2 $y2;
  18607.                     $lx1 $x;
  18608.                     $lx2 $x2;
  18609.                     $this->SetLineWidth($Bw);
  18610.                     if ($cort == 'cell' || strpos($tablecorner'L') !== false) {
  18611.                         if ($Bw $Lw) {
  18612.                             $xadj = ($Bw $Lw) / 2;
  18613.                         }
  18614.                         if ($Bw $Lw) {
  18615.                             $xadj = ($Bw $Lw) / 2;
  18616.                         }
  18617.                     } else {
  18618.                         $xadj $Bw $bsh 2;
  18619.                     }
  18620.                     if ($cort == 'cell' || strpos($tablecorner'R') !== false) {
  18621.                         if ($Bw $Rw) {
  18622.                             $xadj2 = ($Bw $Rw) / 2;
  18623.                         }
  18624.                         if ($Bw $Rw) {
  18625.                             $xadj2 = ($Bw $Rw) / 2;
  18626.                         }
  18627.                     } else {
  18628.                         $xadj2 $Bw $bsh 2;
  18629.                     }
  18630.                     if (!$bSeparate && isset($details['mbw']) && isset($details['mbw']['BL'])) {
  18631.                         $xadj = ($Bw $details['mbw']['BL']) / 2;
  18632.                     }
  18633.                     if (!$bSeparate && isset($details['mbw']) && isset($details['mbw']['BR'])) {
  18634.                         $xadj2 = ($Bw $details['mbw']['BR']) / 2;
  18635.                     }
  18636.                     $print true;
  18637.                 }
  18638.                 // Now draw line
  18639.                 if ($print) {
  18640.                     /* -- TABLES-ADVANCED-BORDERS -- */
  18641.                     if ($details[$side]['style'] == 'double') {
  18642.                         if (!isset($details[$side]['overlay']) || !$details[$side]['overlay'] || $bSeparate) {
  18643.                             if ($details[$side]['c']) {
  18644.                                 $this->SetDColor($details[$side]['c']);
  18645.                             } else {
  18646.                                 $this->SetDColor($this->colorConverter->convert(0$this->PDFAXwarnings));
  18647.                             }
  18648.                             $this->Line($lx1 $xadj$ly1 $yadj$lx2 $xadj2$ly2 $yadj2);
  18649.                         }
  18650.                         if ((isset($details[$side]['overlay']) && $details[$side]['overlay']) || $bSeparate) {
  18651.                             if ($bSeparate && $cort == 'table') {
  18652.                                 if ($side == 'T') {
  18653.                                     $xadj -= $this->LineWidth 2;
  18654.                                     $xadj2 -= $this->LineWidth;
  18655.                                     if ($this->issetBorder($bordBorder::LEFT)) {
  18656.                                         $xadj += $this->LineWidth 2;
  18657.                                     }
  18658.                                     if ($this->issetBorder($bordBorder::RIGHT)) {
  18659.                                         $xadj2 += $this->LineWidth;
  18660.                                     }
  18661.                                 }
  18662.                                 if ($side == 'L') {
  18663.                                     $yadj -= $this->LineWidth 2;
  18664.                                     $yadj2 -= $this->LineWidth;
  18665.                                     if ($this->issetBorder($bordBorder::TOP)) {
  18666.                                         $yadj += $this->LineWidth 2;
  18667.                                     }
  18668.                                     if ($this->issetBorder($bordBorder::BOTTOM)) {
  18669.                                         $yadj2 += $this->LineWidth;
  18670.                                     }
  18671.                                 }
  18672.                                 if ($side == 'B') {
  18673.                                     $xadj -= $this->LineWidth 2;
  18674.                                     $xadj2 -= $this->LineWidth;
  18675.                                     if ($this->issetBorder($bordBorder::LEFT)) {
  18676.                                         $xadj += $this->LineWidth 2;
  18677.                                     }
  18678.                                     if ($this->issetBorder($bordBorder::RIGHT)) {
  18679.                                         $xadj2 += $this->LineWidth;
  18680.                                     }
  18681.                                 }
  18682.                                 if ($side == 'R') {
  18683.                                     $yadj -= $this->LineWidth 2;
  18684.                                     $yadj2 -= $this->LineWidth;
  18685.                                     if ($this->issetBorder($bordBorder::TOP)) {
  18686.                                         $yadj += $this->LineWidth 2;
  18687.                                     }
  18688.                                     if ($this->issetBorder($bordBorder::BOTTOM)) {
  18689.                                         $yadj2 += $this->LineWidth;
  18690.                                     }
  18691.                                 }
  18692.                             }
  18693.                             $this->SetLineWidth($this->LineWidth 3);
  18694.                             $tbcol $this->colorConverter->convert(255$this->PDFAXwarnings);
  18695.                             for ($l 0$l <= $this->blklvl$l++) {
  18696.                                 if ($this->blk[$l]['bgcolor']) {
  18697.                                     $tbcol = ($this->blk[$l]['bgcolorarray']);
  18698.                                 }
  18699.                             }
  18700.                             if ($bSeparate) {
  18701.                                 $cellBorderOverlay[] = [
  18702.                                     'x' => $lx1 $xadj,
  18703.                                     'y' => $ly1 $yadj,
  18704.                                     'x2' => $lx2 $xadj2,
  18705.                                     'y2' => $ly2 $yadj2,
  18706.                                     'col' => $tbcol,
  18707.                                     'lw' => $this->LineWidth,
  18708.                                 ];
  18709.                             } else {
  18710.                                 $this->SetDColor($tbcol);
  18711.                                 $this->Line($lx1 $xadj$ly1 $yadj$lx2 $xadj2$ly2 $yadj2);
  18712.                             }
  18713.                         }
  18714.                     } elseif (isset($details[$side]['style']) && ($details[$side]['style'] == 'ridge' || $details[$side]['style'] == 'groove' || $details[$side]['style'] == 'inset' || $details[$side]['style'] == 'outset')) {
  18715.                         if (!isset($details[$side]['overlay']) || !$details[$side]['overlay'] || $bSeparate) {
  18716.                             if ($details[$side]['c']) {
  18717.                                 $this->SetDColor($details[$side]['c']);
  18718.                             } else {
  18719.                                 $this->SetDColor($this->colorConverter->convert(0$this->PDFAXwarnings));
  18720.                             }
  18721.                             if ($details[$side]['style'] == 'outset' || $details[$side]['style'] == 'groove') {
  18722.                                 $nc $this->colorConverter->darken($details[$side]['c']);
  18723.                                 $this->SetDColor($nc);
  18724.                             } elseif ($details[$side]['style'] == 'ridge' || $details[$side]['style'] == 'inset') {
  18725.                                 $nc $this->colorConverter->lighten($details[$side]['c']);
  18726.                                 $this->SetDColor($nc);
  18727.                             }
  18728.                             $this->Line($lx1 $xadj$ly1 $yadj$lx2 $xadj2$ly2 $yadj2);
  18729.                         }
  18730.                         if ((isset($details[$side]['overlay']) && $details[$side]['overlay']) || $bSeparate) {
  18731.                             if ($details[$side]['c']) {
  18732.                                 $this->SetDColor($details[$side]['c']);
  18733.                             } else {
  18734.                                 $this->SetDColor($this->colorConverter->convert(0$this->PDFAXwarnings));
  18735.                             }
  18736.                             $doubleadj = ($this->LineWidth) / 3;
  18737.                             $this->SetLineWidth($this->LineWidth 2);
  18738.                             $xadj3 $yadj3 $wadj3 $hadj3 0;
  18739.                             if ($details[$side]['style'] == 'ridge' || $details[$side]['style'] == 'inset') {
  18740.                                 $nc $this->colorConverter->darken($details[$side]['c']);
  18741.                                 if ($bSeparate && $cort == 'table') {
  18742.                                     if ($side == 'T') {
  18743.                                         $yadj3 $this->LineWidth 2;
  18744.                                         $xadj3 = -$this->LineWidth 2;
  18745.                                         $wadj3 $this->LineWidth;
  18746.                                         if ($this->issetBorder($bordBorder::LEFT)) {
  18747.                                             $xadj3 += $this->LineWidth;
  18748.                                             $wadj3 -= $this->LineWidth;
  18749.                                         }
  18750.                                         if ($this->issetBorder($bordBorder::RIGHT)) {
  18751.                                             $wadj3 -= $this->LineWidth 2;
  18752.                                         }
  18753.                                     }
  18754.                                     if ($side == 'L') {
  18755.                                         $xadj3 $this->LineWidth 2;
  18756.                                         $yadj3 = -$this->LineWidth 2;
  18757.                                         $hadj3 $this->LineWidth;
  18758.                                         if ($this->issetBorder($bordBorder::TOP)) {
  18759.                                             $yadj3 += $this->LineWidth;
  18760.                                             $hadj3 -= $this->LineWidth;
  18761.                                         }
  18762.                                         if ($this->issetBorder($bordBorder::BOTTOM)) {
  18763.                                             $hadj3 -= $this->LineWidth 2;
  18764.                                         }
  18765.                                     }
  18766.                                     if ($side == 'B') {
  18767.                                         $yadj3 $this->LineWidth 2;
  18768.                                         $xadj3 = -$this->LineWidth 2;
  18769.                                         $wadj3 $this->LineWidth;
  18770.                                     }
  18771.                                     if ($side == 'R') {
  18772.                                         $xadj3 $this->LineWidth 2;
  18773.                                         $yadj3 = -$this->LineWidth 2;
  18774.                                         $hadj3 $this->LineWidth;
  18775.                                     }
  18776.                                 } elseif ($side == 'T') {
  18777.                                     $yadj3 $this->LineWidth 2;
  18778.                                     $xadj3 $this->LineWidth 2;
  18779.                                     $wadj3 = -$this->LineWidth 2;
  18780.                                 } elseif ($side == 'L') {
  18781.                                     $xadj3 $this->LineWidth 2;
  18782.                                     $yadj3 $this->LineWidth 2;
  18783.                                     $hadj3 = -$this->LineWidth 2;
  18784.                                 } elseif ($side == 'B' && $bSeparate) {
  18785.                                     $yadj3 $this->LineWidth 2;
  18786.                                     $wadj3 $this->LineWidth 2;
  18787.                                 } elseif ($side == 'R' && $bSeparate) {
  18788.                                     $xadj3 $this->LineWidth 2;
  18789.                                     $hadj3 $this->LineWidth 2;
  18790.                                 } elseif ($side == 'B') {
  18791.                                     $yadj3 $this->LineWidth 2;
  18792.                                     $xadj3 $this->LineWidth 2;
  18793.                                 } elseif ($side == 'R') {
  18794.                                     $xadj3 $this->LineWidth 2;
  18795.                                     $yadj3 $this->LineWidth 2;
  18796.                                 }
  18797.                             } else {
  18798.                                 $nc $this->colorConverter->lighten($details[$side]['c']);
  18799.                                 if ($bSeparate && $cort == 'table') {
  18800.                                     if ($side == 'T') {
  18801.                                         $yadj3 $this->LineWidth 2;
  18802.                                         $xadj3 = -$this->LineWidth 2;
  18803.                                         $wadj3 $this->LineWidth;
  18804.                                         if ($this->issetBorder($bordBorder::LEFT)) {
  18805.                                             $xadj3 += $this->LineWidth;
  18806.                                             $wadj3 -= $this->LineWidth;
  18807.                                         }
  18808.                                     }
  18809.                                     if ($side == 'L') {
  18810.                                         $xadj3 $this->LineWidth 2;
  18811.                                         $yadj3 = -$this->LineWidth 2;
  18812.                                         $hadj3 $this->LineWidth;
  18813.                                         if ($this->issetBorder($bordBorder::TOP)) {
  18814.                                             $yadj3 += $this->LineWidth;
  18815.                                             $hadj3 -= $this->LineWidth;
  18816.                                         }
  18817.                                     }
  18818.                                     if ($side == 'B') {
  18819.                                         $yadj3 $this->LineWidth 2;
  18820.                                         $xadj3 = -$this->LineWidth 2;
  18821.                                         $wadj3 $this->LineWidth;
  18822.                                         if ($this->issetBorder($bordBorder::LEFT)) {
  18823.                                             $xadj3 += $this->LineWidth;
  18824.                                             $wadj3 -= $this->LineWidth;
  18825.                                         }
  18826.                                     }
  18827.                                     if ($side == 'R') {
  18828.                                         $xadj3 $this->LineWidth 2;
  18829.                                         $yadj3 = -$this->LineWidth 2;
  18830.                                         $hadj3 $this->LineWidth;
  18831.                                         if ($this->issetBorder($bordBorder::TOP)) {
  18832.                                             $yadj3 += $this->LineWidth;
  18833.                                             $hadj3 -= $this->LineWidth;
  18834.                                         }
  18835.                                     }
  18836.                                 } elseif ($side == 'T') {
  18837.                                     $yadj3 $this->LineWidth 2;
  18838.                                     $xadj3 $this->LineWidth 2;
  18839.                                 } elseif ($side == 'L') {
  18840.                                     $xadj3 $this->LineWidth 2;
  18841.                                     $yadj3 $this->LineWidth 2;
  18842.                                 } elseif ($side == 'B' && $bSeparate) {
  18843.                                     $yadj3 $this->LineWidth 2;
  18844.                                     $xadj3 $this->LineWidth 2;
  18845.                                 } elseif ($side == 'R' && $bSeparate) {
  18846.                                     $xadj3 $this->LineWidth 2;
  18847.                                     $yadj3 $this->LineWidth 2;
  18848.                                 } elseif ($side == 'B') {
  18849.                                     $yadj3 $this->LineWidth 2;
  18850.                                     $xadj3 = -$this->LineWidth 2;
  18851.                                     $wadj3 $this->LineWidth;
  18852.                                 } elseif ($side == 'R') {
  18853.                                     $xadj3 $this->LineWidth 2;
  18854.                                     $yadj3 = -$this->LineWidth 2;
  18855.                                     $hadj3 $this->LineWidth;
  18856.                                 }
  18857.                             }
  18858.                             if ($bSeparate) {
  18859.                                 $cellBorderOverlay[] = [
  18860.                                     'x' => $lx1 $xadj $xadj3,
  18861.                                     'y' => $ly1 $yadj $yadj3,
  18862.                                     'x2' => $lx2 $xadj2 $xadj3 $wadj3,
  18863.                                     'y2' => $ly2 $yadj2 $yadj3 $hadj3,
  18864.                                     'col' => $nc,
  18865.                                     'lw' => $this->LineWidth,
  18866.                                 ];
  18867.                             } else {
  18868.                                 $this->SetDColor($nc);
  18869.                                 $this->Line($lx1 $xadj $xadj3$ly1 $yadj $yadj3$lx2 $xadj2 $xadj3 $wadj3$ly2 $yadj2 $yadj3 $hadj3);
  18870.                             }
  18871.                         }
  18872.                     } else {
  18873.                         /* -- END TABLES-ADVANCED-BORDERS -- */
  18874.                         if ($details[$side]['style'] == 'dashed') {
  18875.                             $dashsize 2// final dash will be this + 1*linewidth
  18876.                             $dashsizek 1.5// ratio of Dash/Blank
  18877.                             $this->SetDash($dashsize, ($dashsize $dashsizek) + ($this->LineWidth 2));
  18878.                         } elseif ($details[$side]['style'] == 'dotted') {
  18879.                             $this->SetLineJoin(1);
  18880.                             $this->SetLineCap(1);
  18881.                             $this->SetDash(0.001, ($this->LineWidth 2));
  18882.                         }
  18883.                         if ($details[$side]['c']) {
  18884.                             $this->SetDColor($details[$side]['c']);
  18885.                         } else {
  18886.                             $this->SetDColor($this->colorConverter->convert(0$this->PDFAXwarnings));
  18887.                         }
  18888.                         $this->Line($lx1 $xadj$ly1 $yadj$lx2 $xadj2$ly2 $yadj2);
  18889.                         /* -- TABLES-ADVANCED-BORDERS -- */
  18890.                     }
  18891.                     /* -- END TABLES-ADVANCED-BORDERS -- */
  18892.                     // Reset Corners
  18893.                     $this->SetDash();
  18894.                     // BUTT style line cap
  18895.                     $this->SetLineCap(2);
  18896.                 }
  18897.             }
  18898.             if ($bSeparate && count($cellBorderOverlay)) {
  18899.                 foreach ($cellBorderOverlay as $cbo) {
  18900.                     $this->SetLineWidth($cbo['lw']);
  18901.                     $this->SetDColor($cbo['col']);
  18902.                     $this->Line($cbo['x'], $cbo['y'], $cbo['x2'], $cbo['y2']);
  18903.                 }
  18904.             }
  18905.             // $this->SetLineWidth($oldlinewidth);
  18906.             // $this->SetDColor($this->colorConverter->convert(0, $this->PDFAXwarnings));
  18907.         }
  18908.     }
  18909.     /* -- TABLES -- */
  18910.     /* -- TABLES-ADVANCED-BORDERS -- */
  18911.     /* -- END TABLES-ADVANCED-BORDERS -- */
  18912.     function setBorder(&$var$flag$set true)
  18913.     {
  18914.         $flag intval($flag);
  18915.         if ($set) {
  18916.             $set true;
  18917.         }
  18918.         $var intval($var);
  18919.         $var $set ? ($var $flag) : ($var & ~$flag);
  18920.     }
  18921.     function issetBorder($var$flag)
  18922.     {
  18923.         $flag intval($flag);
  18924.         $var intval($var);
  18925.         return (($var $flag) == $flag);
  18926.     }
  18927.     function _table2cellBorder(&$tableb, &$cbdb, &$cellb$bval)
  18928.     {
  18929.         if ($tableb && $tableb['w'] > $cbdb['w']) {
  18930.             $cbdb $tableb;
  18931.             $this->setBorder($cellb$bval);
  18932.         } elseif ($tableb && $tableb['w'] == $cbdb['w'] && array_search($tableb['style'], $this->borderstyles) > array_search($cbdb['style'], $this->borderstyles)) {
  18933.             $cbdb $tableb;
  18934.             $this->setBorder($cellb$bval);
  18935.         }
  18936.     }
  18937.     // FIX BORDERS ********************************************
  18938.     function _fixTableBorders(&$table)
  18939.     {
  18940.         if (!$table['borders_separate'] && $table['border_details']['L']['w']) {
  18941.             $table['max_cell_border_width']['L'] = $table['border_details']['L']['w'];
  18942.         }
  18943.         if (!$table['borders_separate'] && $table['border_details']['R']['w']) {
  18944.             $table['max_cell_border_width']['R'] = $table['border_details']['R']['w'];
  18945.         }
  18946.         if (!$table['borders_separate'] && $table['border_details']['T']['w']) {
  18947.             $table['max_cell_border_width']['T'] = $table['border_details']['T']['w'];
  18948.         }
  18949.         if (!$table['borders_separate'] && $table['border_details']['B']['w']) {
  18950.             $table['max_cell_border_width']['B'] = $table['border_details']['B']['w'];
  18951.         }
  18952.         if ($this->simpleTables) {
  18953.             return;
  18954.         }
  18955.         $cells = &$table['cells'];
  18956.         $numcols $table['nc'];
  18957.         $numrows $table['nr'];
  18958.         /* -- TABLES-ADVANCED-BORDERS -- */
  18959.         if (isset($table['topntail']) && $table['topntail']) {
  18960.             $tntborddet $this->border_details($table['topntail']);
  18961.         }
  18962.         if (isset($table['thead-underline']) && $table['thead-underline']) {
  18963.             $thuborddet $this->border_details($table['thead-underline']);
  18964.         }
  18965.         /* -- END TABLES-ADVANCED-BORDERS -- */
  18966.         for ($i 0$i $numrows$i++) { // Rows
  18967.             for ($j 0$j $numcols$j++) { // Columns
  18968.                 if (isset($cells[$i][$j]) && $cells[$i][$j]) {
  18969.                     $cell = &$cells[$i][$j];
  18970.                     if ($this->packTableData) {
  18971.                         $cbord $this->_unpackCellBorder($cell['borderbin']);
  18972.                     } else {
  18973.                         $cbord = &$cells[$i][$j];
  18974.                     }
  18975.                     // mPDF 5.7.3
  18976.                     if (!$cbord['border'] && $cbord['border'] !== && isset($table['border']) && $table['border'] && $this->table_border_attr_set) {
  18977.                         $cbord['border'] = $table['border'];
  18978.                         $cbord['border_details'] = $table['border_details'];
  18979.                     }
  18980.                     if (isset($cell['colspan']) && $cell['colspan'] > 1) {
  18981.                         $ccolsp $cell['colspan'];
  18982.                     } else {
  18983.                         $ccolsp 1;
  18984.                     }
  18985.                     if (isset($cell['rowspan']) && $cell['rowspan'] > 1) {
  18986.                         $crowsp $cell['rowspan'];
  18987.                     } else {
  18988.                         $crowsp 1;
  18989.                     }
  18990.                     $cbord['border_details']['cellposdom'] = ((($i 1) / $numrows) / 10000 ) + ((($j 1) / $numcols) / 10 );
  18991.                     // Inherit Cell border from Table border
  18992.                     if ($this->table_border_css_set && !$table['borders_separate']) {
  18993.                         if ($i == 0) {
  18994.                             $this->_table2cellBorder($table['border_details']['T'], $cbord['border_details']['T'], $cbord['border'], Border::TOP);
  18995.                         }
  18996.                         if ($i == ($numrows 1) || ($i $crowsp) == ($numrows)) {
  18997.                             $this->_table2cellBorder($table['border_details']['B'], $cbord['border_details']['B'], $cbord['border'], Border::BOTTOM);
  18998.                         }
  18999.                         if ($j == 0) {
  19000.                             $this->_table2cellBorder($table['border_details']['L'], $cbord['border_details']['L'], $cbord['border'], Border::LEFT);
  19001.                         }
  19002.                         if ($j == ($numcols 1) || ($j $ccolsp) == ($numcols)) {
  19003.                             $this->_table2cellBorder($table['border_details']['R'], $cbord['border_details']['R'], $cbord['border'], Border::RIGHT);
  19004.                         }
  19005.                     }
  19006.                     /* -- TABLES-ADVANCED-BORDERS -- */
  19007.                     $fixbottom true;
  19008.                     if (isset($table['topntail']) && $table['topntail']) {
  19009.                         if ($i == 0) {
  19010.                             $cbord['border_details']['T'] = $tntborddet;
  19011.                             $this->setBorder($cbord['border'], Border::TOP);
  19012.                         }
  19013.                         if ($this->tableLevel == && $table['headernrows'] > && $i == $table['headernrows'] - 1) {
  19014.                             $cbord['border_details']['B'] = $tntborddet;
  19015.                             $this->setBorder($cbord['border'], Border::BOTTOM);
  19016.                             $fixbottom false;
  19017.                         } elseif ($this->tableLevel == && $table['headernrows'] > && $i == $table['headernrows']) {
  19018.                             if (!$table['borders_separate']) {
  19019.                                 $cbord['border_details']['T'] = $tntborddet;
  19020.                                 $this->setBorder($cbord['border'], Border::TOP);
  19021.                             }
  19022.                         }
  19023.                         if ($this->tableLevel == && $table['footernrows'] > && $i == ($numrows $table['footernrows'] - 1)) {
  19024.                             if (!$table['borders_separate']) {
  19025.                                 $cbord['border_details']['B'] = $tntborddet;
  19026.                                 $this->setBorder($cbord['border'], Border::BOTTOM);
  19027.                                 $fixbottom false;
  19028.                             }
  19029.                         } elseif ($this->tableLevel == && $table['footernrows'] > && $i == ($numrows $table['footernrows'])) {
  19030.                             $cbord['border_details']['T'] = $tntborddet;
  19031.                             $this->setBorder($cbord['border'], Border::TOP);
  19032.                         }
  19033.                         if ($this->tabletheadjustfinished) { // $this->tabletheadjustfinished called from tableheader
  19034.                             if (!$table['borders_separate']) {
  19035.                                 $cbord['border_details']['T'] = $tntborddet;
  19036.                                 $this->setBorder($cbord['border'], Border::TOP);
  19037.                             }
  19038.                         }
  19039.                         if ($i == ($numrows 1) || ($i $crowsp) == ($numrows)) {
  19040.                             $cbord['border_details']['B'] = $tntborddet;
  19041.                             $this->setBorder($cbord['border'], Border::BOTTOM);
  19042.                         }
  19043.                     }
  19044.                     if (isset($table['thead-underline']) && $table['thead-underline']) {
  19045.                         if ($table['borders_separate']) {
  19046.                             if ($i == 0) {
  19047.                                 $cbord['border_details']['B'] = $thuborddet;
  19048.                                 $this->setBorder($cbord['border'], Border::BOTTOM);
  19049.                                 $fixbottom false;
  19050.                             }
  19051.                         } else {
  19052.                             if ($this->tableLevel == && $table['headernrows'] > && $i == $table['headernrows'] - 1) {
  19053.                                 $cbord['border_details']['T'] = $thuborddet;
  19054.                                 $this->setBorder($cbord['border'], Border::TOP);
  19055.                             } elseif ($this->tabletheadjustfinished) { // $this->tabletheadjustfinished called from tableheader
  19056.                                 $cbord['border_details']['T'] = $thuborddet;
  19057.                                 $this->setBorder($cbord['border'], Border::TOP);
  19058.                             }
  19059.                         }
  19060.                     }
  19061.                     // Collapse Border - Algorithm for conflicting borders
  19062.                     // Hidden >> Width >> double>solid>dashed>dotted... >> style set on cell>table >> top/left>bottom/right
  19063.                     // Do not turn off border which is overridden
  19064.                     // Needed for page break for TOP/BOTTOM both to be defined in Collapsed borders
  19065.                     // Means it is painted twice. (Left/Right can still disable overridden border)
  19066.                     if (!$table['borders_separate']) {
  19067.                         if (($i < ($numrows 1) || ($i $crowsp) < $numrows ) && $fixbottom) { // Bottom
  19068.                             for ($cspi 0$cspi $ccolsp$cspi++) {
  19069.                                 // already defined Top for adjacent cell below
  19070.                                 if (isset($cells[($i $crowsp)][$j $cspi])) {
  19071.                                     if ($this->packTableData) {
  19072.                                         $adjc $cells[($i $crowsp)][$j $cspi];
  19073.                                         $celladj $this->_unpackCellBorder($adjc['borderbin']);
  19074.                                     } else {
  19075.                                         $celladj = & $cells[($i $crowsp)][$j $cspi];
  19076.                                     }
  19077.                                 } else {
  19078.                                     $celladj false;
  19079.                                 }
  19080.                                 if (isset($celladj['border_details']['T']['s']) && $celladj['border_details']['T']['s'] == 1) {
  19081.                                     $csadj $celladj['border_details']['T']['w'];
  19082.                                     $csthis $cbord['border_details']['B']['w'];
  19083.                                     // Hidden
  19084.                                     if ($cbord['border_details']['B']['style'] == 'hidden') {
  19085.                                         $celladj['border_details']['T'] = $cbord['border_details']['B'];
  19086.                                         $this->setBorder($celladj['border'], Border::TOPfalse);
  19087.                                         $this->setBorder($cbord['border'], Border::BOTTOMfalse);
  19088.                                     } elseif ($celladj['border_details']['T']['style'] == 'hidden') {
  19089.                                         $cbord['border_details']['B'] = $celladj['border_details']['T'];
  19090.                                         $this->setBorder($cbord['border'], Border::BOTTOMfalse);
  19091.                                         $this->setBorder($celladj['border'], Border::TOPfalse);
  19092.                                     } elseif ($csthis $csadj) { // Width
  19093.                                         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
  19094.                                             $celladj['border_details']['T'] = $cbord['border_details']['B'];
  19095.                                             $this->setBorder($cbord['border'], Border::BOTTOM);
  19096.                                         }
  19097.                                     } elseif ($csadj $csthis) {
  19098.                                         if ($ccolsp 2) { // don't overwrite this cell if it spans
  19099.                                             $cbord['border_details']['B'] = $celladj['border_details']['T'];
  19100.                                             $this->setBorder($celladj['border'], Border::TOP);
  19101.                                         }
  19102.                                     } elseif (array_search($cbord['border_details']['B']['style'], $this->borderstyles) > array_search($celladj['border_details']['T']['style'], $this->borderstyles)) { // double>solid>dashed>dotted...
  19103.                                         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
  19104.                                             $celladj['border_details']['T'] = $cbord['border_details']['B'];
  19105.                                             $this->setBorder($cbord['border'], Border::BOTTOM);
  19106.                                         }
  19107.                                     } elseif (array_search($celladj['border_details']['T']['style'], $this->borderstyles) > array_search($cbord['border_details']['B']['style'], $this->borderstyles)) {
  19108.                                         if ($ccolsp 2) { // don't overwrite this cell if it spans
  19109.                                             $cbord['border_details']['B'] = $celladj['border_details']['T'];
  19110.                                             $this->setBorder($celladj['border'], Border::TOP);
  19111.                                         }
  19112.                                     } elseif ($celladj['border_details']['T']['dom'] > $celladj['border_details']['B']['dom']) { // Style set on cell vs. table
  19113.                                         if ($ccolsp 2) { // don't overwrite this cell if it spans
  19114.                                             $cbord['border_details']['B'] = $celladj['border_details']['T'];
  19115.                                             $this->setBorder($celladj['border'], Border::TOP);
  19116.                                         }
  19117.                                     } else { // Style set on cell vs. table  - OR - LEFT/TOP (cell) in preference to BOTTOM/RIGHT
  19118.                                         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
  19119.                                             $celladj['border_details']['T'] = $cbord['border_details']['B'];
  19120.                                             $this->setBorder($cbord['border'], Border::BOTTOM);
  19121.                                         }
  19122.                                     }
  19123.                                 } elseif ($celladj) {
  19124.                                     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
  19125.                                         $celladj['border_details']['T'] = $cbord['border_details']['B'];
  19126.                                     }
  19127.                                 }
  19128.                                 // mPDF 5.7.4
  19129.                                 if ($celladj && $this->packTableData) {
  19130.                                     $cells[$i $crowsp][$j $cspi]['borderbin'] = $this->_packCellBorder($celladj);
  19131.                                 }
  19132.                                 unset($celladj);
  19133.                             }
  19134.                         }
  19135.                         if ($j < ($numcols 1) || ($j $ccolsp) < $numcols) { // Right-Left
  19136.                             for ($cspi 0$cspi $crowsp$cspi++) {
  19137.                                 // already defined Left for adjacent cell to R
  19138.                                 if (isset($cells[($i $cspi)][$j $ccolsp])) {
  19139.                                     if ($this->packTableData) {
  19140.                                         $adjc $cells[($i $cspi)][$j $ccolsp];
  19141.                                         $celladj $this->_unpackCellBorder($adjc['borderbin']);
  19142.                                     } else {
  19143.                                         $celladj = & $cells[$i $cspi][$j $ccolsp];
  19144.                                     }
  19145.                                 } else {
  19146.                                     $celladj false;
  19147.                                 }
  19148.                                 if ($celladj && $celladj['border_details']['L']['s'] == 1) {
  19149.                                     $csadj $celladj['border_details']['L']['w'];
  19150.                                     $csthis $cbord['border_details']['R']['w'];
  19151.                                     // Hidden
  19152.                                     if ($cbord['border_details']['R']['style'] == 'hidden') {
  19153.                                         $celladj['border_details']['L'] = $cbord['border_details']['R'];
  19154.                                         $this->setBorder($celladj['border'], Border::LEFTfalse);
  19155.                                         $this->setBorder($cbord['border'], Border::RIGHTfalse);
  19156.                                     } elseif ($celladj['border_details']['L']['style'] == 'hidden') {
  19157.                                         $cbord['border_details']['R'] = $celladj['border_details']['L'];
  19158.                                         $this->setBorder($cbord['border'], Border::RIGHTfalse);
  19159.                                         $this->setBorder($celladj['border'], Border::LEFTfalse);
  19160.                                     } // Width
  19161.                                     elseif ($csthis $csadj) {
  19162.                                         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
  19163.                                             $celladj['border_details']['L'] = $cbord['border_details']['R'];
  19164.                                             $this->setBorder($cbord['border'], Border::RIGHT);
  19165.                                             $this->setBorder($celladj['border'], Border::LEFTfalse);
  19166.                                         }
  19167.                                     } elseif ($csadj $csthis) {
  19168.                                         if ($crowsp 2) { // don't overwrite this cell if it spans
  19169.                                             $cbord['border_details']['R'] = $celladj['border_details']['L'];
  19170.                                             $this->setBorder($cbord['border'], Border::RIGHTfalse);
  19171.                                             $this->setBorder($celladj['border'], Border::LEFT);
  19172.                                         }
  19173.                                     } // double>solid>dashed>dotted...
  19174.                                     elseif (array_search($cbord['border_details']['R']['style'], $this->borderstyles) > array_search($celladj['border_details']['L']['style'], $this->borderstyles)) {
  19175.                                         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
  19176.                                             $celladj['border_details']['L'] = $cbord['border_details']['R'];
  19177.                                             $this->setBorder($celladj['border'], Border::LEFTfalse);
  19178.                                             $this->setBorder($cbord['border'], Border::RIGHT);
  19179.                                         }
  19180.                                     } elseif (array_search($celladj['border_details']['L']['style'], $this->borderstyles) > array_search($cbord['border_details']['R']['style'], $this->borderstyles)) {
  19181.                                         if ($crowsp 2) { // don't overwrite this cell if it spans
  19182.                                             $cbord['border_details']['R'] = $celladj['border_details']['L'];
  19183.                                             $this->setBorder($cbord['border'], Border::RIGHTfalse);
  19184.                                             $this->setBorder($celladj['border'], Border::LEFT);
  19185.                                         }
  19186.                                     } // Style set on cell vs. table
  19187.                                     elseif ($celladj['border_details']['L']['dom'] > $cbord['border_details']['R']['dom']) {
  19188.                                         if ($crowsp 2) { // don't overwrite this cell if it spans
  19189.                                             $cbord['border_details']['R'] = $celladj['border_details']['L'];
  19190.                                             $this->setBorder($celladj['border'], Border::LEFT);
  19191.                                         }
  19192.                                     } // Style set on cell vs. table  - OR - LEFT/TOP (cell) in preference to BOTTOM/RIGHT
  19193.                                     else {
  19194.                                         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
  19195.                                             $celladj['border_details']['L'] = $cbord['border_details']['R'];
  19196.                                             $this->setBorder($cbord['border'], Border::RIGHT);
  19197.                                         }
  19198.                                     }
  19199.                                 } elseif ($celladj) {
  19200.                                     // if right-cell border is not set
  19201.                                     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
  19202.                                         $celladj['border_details']['L'] = $cbord['border_details']['R'];
  19203.                                     }
  19204.                                 }
  19205.                                 // mPDF 5.7.4
  19206.                                 if ($celladj && $this->packTableData) {
  19207.                                     $cells[$i $cspi][$j $ccolsp]['borderbin'] = $this->_packCellBorder($celladj);
  19208.                                 }
  19209.                                 unset($celladj);
  19210.                             }
  19211.                         }
  19212.                     }
  19213.                     // Set maximum cell border width meeting at LRTB edges of cell - used for extended cell border
  19214.                     // ['border_details']['mbw']['LT'] = meeting border width - Left border - Top end
  19215.                     if (!$table['borders_separate']) {
  19216.                         $cbord['border_details']['mbw']['BL'] = max($cbord['border_details']['mbw']['BL'], $cbord['border_details']['L']['w']);
  19217.                         $cbord['border_details']['mbw']['BR'] = max($cbord['border_details']['mbw']['BR'], $cbord['border_details']['R']['w']);
  19218.                         $cbord['border_details']['mbw']['RT'] = max($cbord['border_details']['mbw']['RT'], $cbord['border_details']['T']['w']);
  19219.                         $cbord['border_details']['mbw']['RB'] = max($cbord['border_details']['mbw']['RB'], $cbord['border_details']['B']['w']);
  19220.                         $cbord['border_details']['mbw']['TL'] = max($cbord['border_details']['mbw']['TL'], $cbord['border_details']['L']['w']);
  19221.                         $cbord['border_details']['mbw']['TR'] = max($cbord['border_details']['mbw']['TR'], $cbord['border_details']['R']['w']);
  19222.                         $cbord['border_details']['mbw']['LT'] = max($cbord['border_details']['mbw']['LT'], $cbord['border_details']['T']['w']);
  19223.                         $cbord['border_details']['mbw']['LB'] = max($cbord['border_details']['mbw']['LB'], $cbord['border_details']['B']['w']);
  19224.                         if (($i $crowsp) < $numrows && isset($cells[$i $crowsp][$j])) { // Has Bottom adjoining cell
  19225.                             if ($this->packTableData) {
  19226.                                 $adjc $cells[$i $crowsp][$j];
  19227.                                 $celladj $this->_unpackCellBorder($adjc['borderbin']);
  19228.                             } else {
  19229.                                 $celladj = & $cells[$i $crowsp][$j];
  19230.                             }
  19231.                             $cbord['border_details']['mbw']['BL'] = max(
  19232.                                 $cbord['border_details']['mbw']['BL'],
  19233.                                 $celladj $celladj['border_details']['L']['w'] : 0,
  19234.                                 $celladj $celladj['border_details']['mbw']['TL']: 0
  19235.                             );
  19236.                             $cbord['border_details']['mbw']['BR'] = max(
  19237.                                 $cbord['border_details']['mbw']['BR'],
  19238.                                 $celladj $celladj['border_details']['R']['w'] : 0,
  19239.                                 $celladj $celladj['border_details']['mbw']['TR']: 0
  19240.                             );
  19241.                             $cbord['border_details']['mbw']['LB'] = max(
  19242.                                 $cbord['border_details']['mbw']['LB'],
  19243.                                 $celladj $celladj['border_details']['mbw']['LT'] : 0
  19244.                             );
  19245.                             $cbord['border_details']['mbw']['RB'] = max(
  19246.                                 $cbord['border_details']['mbw']['RB'],
  19247.                                 $celladj $celladj['border_details']['mbw']['RT'] : 0
  19248.                             );
  19249.                             unset($celladj);
  19250.                         }
  19251.                         if (($j $ccolsp) < $numcols && isset($cells[$i][$j $ccolsp])) { // Has Right adjoining cell
  19252.                             if ($this->packTableData) {
  19253.                                 $adjc $cells[$i][$j $ccolsp];
  19254.                                 $celladj $this->_unpackCellBorder($adjc['borderbin']);
  19255.                             } else {
  19256.                                 $celladj = & $cells[$i][$j $ccolsp];
  19257.                             }
  19258.                             $cbord['border_details']['mbw']['RT'] = max(
  19259.                                 $cbord['border_details']['mbw']['RT'],
  19260.                                 $celladj $celladj['border_details']['T']['w'] : 0,
  19261.                                 $celladj $celladj['border_details']['mbw']['LT'] : 0
  19262.                             );
  19263.                             $cbord['border_details']['mbw']['RB'] = max(
  19264.                                 $cbord['border_details']['mbw']['RB'],
  19265.                                 $celladj $celladj['border_details']['B']['w'] : 0,
  19266.                                 $celladj $celladj['border_details']['mbw']['LB'] : 0
  19267.                             );
  19268.                             $cbord['border_details']['mbw']['TR'] = max(
  19269.                                 $cbord['border_details']['mbw']['TR'],
  19270.                                 $celladj $celladj['border_details']['mbw']['TL'] : 0
  19271.                             );
  19272.                             $cbord['border_details']['mbw']['BR'] = max(
  19273.                                 $cbord['border_details']['mbw']['BR'],
  19274.                                 $celladj $celladj['border_details']['mbw']['BL'] : 0
  19275.                             );
  19276.                             unset($celladj);
  19277.                         }
  19278.                         if ($i && isset($cells[$i 1][$j]) && is_array($cells[$i 1][$j]) && (($this->packTableData && $cells[$i 1][$j]['borderbin']) || $cells[$i 1][$j]['border'])) { // Has Top adjoining cell
  19279.                             if ($this->packTableData) {
  19280.                                 $adjc $cells[$i 1][$j];
  19281.                                 $celladj $this->_unpackCellBorder($adjc['borderbin']);
  19282.                             } else {
  19283.                                 $celladj = & $cells[$i 1][$j];
  19284.                             }
  19285.                             $cbord['border_details']['mbw']['TL'] = max(
  19286.                                 $cbord['border_details']['mbw']['TL'],
  19287.                                 $celladj $celladj['border_details']['L']['w'] : 0,
  19288.                                 $celladj $celladj['border_details']['mbw']['BL'] : 0
  19289.                             );
  19290.                             $cbord['border_details']['mbw']['TR'] = max(
  19291.                                 $cbord['border_details']['mbw']['TR'],
  19292.                                 $celladj $celladj['border_details']['R']['w'] : 0,
  19293.                                 $celladj $celladj['border_details']['mbw']['BR'] : 0
  19294.                             );
  19295.                             $cbord['border_details']['mbw']['LT'] = max(
  19296.                                 $cbord['border_details']['mbw']['LT'],
  19297.                                 $celladj $celladj['border_details']['mbw']['LB'] : 0
  19298.                             );
  19299.                             $cbord['border_details']['mbw']['RT'] = max(
  19300.                                 $cbord['border_details']['mbw']['RT'],
  19301.                                 $celladj $celladj['border_details']['mbw']['RB'] : 0
  19302.                             );
  19303.                             if ($celladj['border_details']['mbw']['BL']) {
  19304.                                 $celladj['border_details']['mbw']['BL'] = max($cbord['border_details']['mbw']['TL'], $celladj['border_details']['mbw']['BL']);
  19305.                             }
  19306.                             if ($celladj['border_details']['mbw']['BR']) {
  19307.                                 $celladj['border_details']['mbw']['BR'] = max($celladj['border_details']['mbw']['BR'], $cbord['border_details']['mbw']['TR']);
  19308.                             }
  19309.                             if ($this->packTableData) {
  19310.                                 $cells[$i 1][$j]['borderbin'] = $this->_packCellBorder($celladj);
  19311.                             }
  19312.                             unset($celladj);
  19313.                         }
  19314.                         if ($j && isset($cells[$i][$j 1]) && is_array($cells[$i][$j 1]) && (($this->packTableData && $cells[$i][$j 1]['borderbin']) || $cells[$i][$j 1]['border'])) { // Has Left adjoining cell
  19315.                             if ($this->packTableData) {
  19316.                                 $adjc $cells[$i][$j 1];
  19317.                                 $celladj $this->_unpackCellBorder($adjc['borderbin']);
  19318.                             } else {
  19319.                                 $celladj = & $cells[$i][$j 1];
  19320.                             }
  19321.                             $cbord['border_details']['mbw']['LT'] = max(
  19322.                                 $cbord['border_details']['mbw']['LT'],
  19323.                                 $celladj $celladj['border_details']['T']['w'] : 0,
  19324.                                 $celladj $celladj['border_details']['mbw']['RT'] : 0
  19325.                             );
  19326.                             $cbord['border_details']['mbw']['LB'] = max(
  19327.                                 $cbord['border_details']['mbw']['LB'],
  19328.                                 $celladj $celladj['border_details']['B']['w'] : 0,
  19329.                                 $celladj $celladj['border_details']['mbw']['RB'] : 0
  19330.                             );
  19331.                             $cbord['border_details']['mbw']['BL'] = max(
  19332.                                 $cbord['border_details']['mbw']['BL'],
  19333.                                 $celladj $celladj['border_details']['mbw']['BR'] : 0
  19334.                             );
  19335.                             $cbord['border_details']['mbw']['TL'] = max(
  19336.                                 $cbord['border_details']['mbw']['TL'],
  19337.                                 $celladj $celladj['border_details']['mbw']['TR'] : 0
  19338.                             );
  19339.                             if ($celladj['border_details']['mbw']['RT']) {
  19340.                                 $celladj['border_details']['mbw']['RT'] = max($celladj['border_details']['mbw']['RT'], $cbord['border_details']['mbw']['LT']);
  19341.                             }
  19342.                             if ($celladj['border_details']['mbw']['RB']) {
  19343.                                 $celladj['border_details']['mbw']['RB'] = max($celladj['border_details']['mbw']['RB'], $cbord['border_details']['mbw']['LB']);
  19344.                             }
  19345.                             if ($this->packTableData) {
  19346.                                 $cells[$i][$j 1]['borderbin'] = $this->_packCellBorder($celladj);
  19347.                             }
  19348.                             unset($celladj);
  19349.                         }
  19350.                         // Update maximum cell border width at LRTB edges of table - used for overall table width
  19351.                         if ($j == && $cbord['border_details']['L']['w']) {
  19352.                             $table['max_cell_border_width']['L'] = max($table['max_cell_border_width']['L'], $cbord['border_details']['L']['w']);
  19353.                         }
  19354.                         if (($j == ($numcols 1) || ($j $ccolsp) == $numcols ) && $cbord['border_details']['R']['w']) {
  19355.                             $table['max_cell_border_width']['R'] = max($table['max_cell_border_width']['R'], $cbord['border_details']['R']['w']);
  19356.                         }
  19357.                         if ($i == && $cbord['border_details']['T']['w']) {
  19358.                             $table['max_cell_border_width']['T'] = max($table['max_cell_border_width']['T'], $cbord['border_details']['T']['w']);
  19359.                         }
  19360.                         if (($i == ($numrows 1) || ($i $crowsp) == $numrows ) && $cbord['border_details']['B']['w']) {
  19361.                             $table['max_cell_border_width']['B'] = max($table['max_cell_border_width']['B'], $cbord['border_details']['B']['w']);
  19362.                         }
  19363.                     }
  19364.                     /* -- END TABLES-ADVANCED-BORDERS -- */
  19365.                     if ($this->packTableData) {
  19366.                         $cell['borderbin'] = $this->_packCellBorder($cbord);
  19367.                     }
  19368.                     unset($cbord);
  19369.                     unset($cell);
  19370.                 }
  19371.             }
  19372.         }
  19373.         unset($cell);
  19374.     }
  19375.     // END FIX BORDERS ************************************************************************************
  19376.     function _reverseTableDir(&$table)
  19377.     {
  19378.         $cells = &$table['cells'];
  19379.         $numcols $table['nc'];
  19380.         $numrows $table['nr'];
  19381.         for ($i 0$i $numrows$i++) { // Rows
  19382.             $row = [];
  19383.             for ($j = ($numcols 1); $j >= 0$j--) { // Columns
  19384.                 if (isset($cells[$i][$j]) && $cells[$i][$j]) {
  19385.                     $cell = &$cells[$i][$j];
  19386.                     $col $numcols $j 1;
  19387.                     if (isset($cell['colspan']) && $cell['colspan'] > 1) {
  19388.                         $col -= ($cell['colspan'] - 1);
  19389.                     }
  19390.                     // Nested content
  19391.                     if (isset($cell['textbuffer'])) {
  19392.                         for ($n 0$n count($cell['textbuffer']); $n++) {
  19393.                             $t $cell['textbuffer'][$n][0];
  19394.                             if (substr($t019) == Mpdf::OBJECT_IDENTIFIER "type=nestedtable") {
  19395.                                 $objattr $this->_getObjAttr($t);
  19396.                                 $objattr['col'] = $col;
  19397.                                 $cell['textbuffer'][$n][0] = Mpdf::OBJECT_IDENTIFIER "type=nestedtable,objattr=" serialize($objattr) . Mpdf::OBJECT_IDENTIFIER;
  19398.                                 $this->table[($this->tableLevel 1)][$objattr['nestedcontent']]['nestedpos'][1] = $col;
  19399.                             }
  19400.                         }
  19401.                     }
  19402.                     $row[$col] = $cells[$i][$j];
  19403.                     unset($cell);
  19404.                 }
  19405.             }
  19406.             for ($f 0$f $numcols$f++) {
  19407.                 if (!isset($row[$f])) {
  19408.                     $row[$f] = 0;
  19409.                 }
  19410.             }
  19411.             $table['cells'][$i] = $row;
  19412.         }
  19413.     }
  19414.     function _tableWrite(&$table$split false$startrow 0$startcol 0$splitpg 0$rety 0)
  19415.     {
  19416.         $level $table['level'];
  19417.         $levelid $table['levelid'];
  19418.         $cells = &$table['cells'];
  19419.         $numcols $table['nc'];
  19420.         $numrows $table['nr'];
  19421.         $maxbwtop 0;
  19422.         if ($this->ColActive && $level == 1) {
  19423.             $this->breakpoints[$this->CurrCol][] = $this->y;
  19424.         } // *COLUMNS*
  19425.         if (!$split || ($startrow == && $splitpg == 0) || $startrow 0) {
  19426.             // TABLE TOP MARGIN
  19427.             if ($table['margin']['T']) {
  19428.                 if (!$this->table_rotate && $level == 1) {
  19429.                     $this->DivLn($table['margin']['T'], $this->blklvltrue1);  // collapsible
  19430.                 } else {
  19431.                     $this->+= ($table['margin']['T']);
  19432.                 }
  19433.             }
  19434.             // Advance down page by half width of top border
  19435.             if ($table['borders_separate']) {
  19436.                 if ($startrow && (!isset($table['is_thead']) || count($table['is_thead']) == 0)) {
  19437.                     $adv $table['border_spacing_V'] / 2;
  19438.                 } else {
  19439.                     $adv $table['padding']['T'] + $table['border_details']['T']['w'] + $table['border_spacing_V'] / 2;
  19440.                 }
  19441.             } else {
  19442.                 $adv $table['max_cell_border_width']['T'] / 2;
  19443.             }
  19444.             if (!$this->table_rotate && $level == 1) {
  19445.                 $this->DivLn($adv);
  19446.             } else {
  19447.                 $this->+= $adv;
  19448.             }
  19449.         }
  19450.         if ($level == 1) {
  19451.             $this->$this->lMargin $this->blk[$this->blklvl]['outer_left_margin'] + $this->blk[$this->blklvl]['padding_left'] + $this->blk[$this->blklvl]['border_left']['w'];
  19452.             $x0 $this->x;
  19453.             $y0 $this->y;
  19454.             $right $x0 $this->blk[$this->blklvl]['inner_width'];
  19455.             $outerfilled $this->y// Keep track of how far down the outer DIV bgcolor is painted (NB rowspans)
  19456.             $this->outerfilled $this->y;
  19457.             $this->colsums = [];
  19458.         } else {
  19459.             $x0 $this->x;
  19460.             $y0 $this->y;
  19461.             $right $x0 $table['w'];
  19462.         }
  19463.         if ($this->table_rotate) {
  19464.             $temppgwidth $this->tbrot_maxw;
  19465.             $this->PageBreakTrigger $pagetrigger $y0 + ($this->blk[$this->blklvl]['inner_width']);
  19466.             if ($level == 1) {
  19467.                 $this->tbrot_y0 $this->$adv $table['margin']['T'];
  19468.                 $this->tbrot_x0 $this->x;
  19469.                 $this->tbrot_w $table['w'];
  19470.                 if ($table['borders_separate']) {
  19471.                     $this->tbrot_h $table['margin']['T'] + $table['padding']['T'] + $table['border_details']['T']['w'] + $table['border_spacing_V'] / 2;
  19472.                 } else {
  19473.                     $this->tbrot_h $table['margin']['T'] + $table['padding']['T'] + $table['max_cell_border_width']['T'];
  19474.                 }
  19475.             }
  19476.         } else {
  19477.             $this->PageBreakTrigger $pagetrigger = ($this->$this->bMargin);
  19478.             if ($level == 1) {
  19479.                 $temppgwidth $this->blk[$this->blklvl]['inner_width'];
  19480.                 if (isset($table['a']) and ( $table['w'] < $this->blk[$this->blklvl]['inner_width'])) {
  19481.                     if ($table['a'] == 'C') {
  19482.                         $x0 += ((($right $x0) - $table['w']) / 2);
  19483.                     } elseif ($table['a'] == 'R') {
  19484.                         $x0 $right $table['w'];
  19485.                     }
  19486.                 }
  19487.             } else {
  19488.                 $temppgwidth $table['w'];
  19489.             }
  19490.         }
  19491.         if (!isset($table['overflow'])) {
  19492.             $table['overflow'] = null;
  19493.         }
  19494.         if ($table['overflow'] == 'hidden' && $level == && !$this->table_rotate && !$this->ColActive) {
  19495.             // Bounding rectangle to clip
  19496.             $this->tableClipPath sprintf('q %.3F %.3F %.3F %.3F re W n'$x0 Mpdf::SCALE$this->Mpdf::SCALE$this->blk[$this->blklvl]['inner_width'] * Mpdf::SCALE, -$this->Mpdf::SCALE);
  19497.             $this->writer->write($this->tableClipPath);
  19498.         } else {
  19499.             $this->tableClipPath '';
  19500.         }
  19501.         if ($table['borders_separate']) {
  19502.             $indent $table['margin']['L'] + $table['border_details']['L']['w'] + $table['padding']['L'] + $table['border_spacing_H'] / 2;
  19503.         } else {
  19504.             $indent $table['margin']['L'] + $table['max_cell_border_width']['L'] / 2;
  19505.         }
  19506.         $x0 += $indent;
  19507.         $returny 0;
  19508.         $lastCol 0;
  19509.         $tableheader = [];
  19510.         $tablefooter = [];
  19511.         $tableheaderrowheight 0;
  19512.         $tablefooterrowheight 0;
  19513.         $footery 0;
  19514.         // mPD 3.0 Set the Page & Column where table starts
  19515.         if (($this->mirrorMargins) && (($this->page) % == 0)) { // EVEN
  19516.             $tablestartpage 'EVEN';
  19517.         } elseif (($this->mirrorMargins) && (($this->page) % == 1)) { // ODD
  19518.             $tablestartpage 'ODD';
  19519.         } else {
  19520.             $tablestartpage '';
  19521.         }
  19522.         if ($this->ColActive) {
  19523.             $tablestartcolumn $this->CurrCol;
  19524.         } else {
  19525.             $tablestartcolumn '';
  19526.         }
  19527.         $y $h 0;
  19528.         for ($i 0$i $numrows$i++) { // Rows
  19529.             if (isset($table['is_tfoot'][$i]) && $table['is_tfoot'][$i] && $level == 1) {
  19530.                 $tablefooterrowheight += $table['hr'][$i];
  19531.                 $tablefooter[$i][0]['trbackground-images'] = $table['trbackground-images'][$i];
  19532.                 $tablefooter[$i][0]['trgradients'] = $table['trgradients'][$i];
  19533.                 $tablefooter[$i][0]['trbgcolor'] = $table['bgcolor'][$i];
  19534.                 for ($j $startcol$j $numcols$j++) { // Columns
  19535.                     if (isset($cells[$i][$j]) && $cells[$i][$j]) {
  19536.                         $cell = &$cells[$i][$j];
  19537.                         if ($split) {
  19538.                             if ($table['colPg'][$j] != $splitpg) {
  19539.                                 continue;
  19540.                             }
  19541.                             list($x$w) = $this->_splitTableGetWidth($table$i$j);
  19542.                             $js $j $startcol;
  19543.                         } else {
  19544.                             list($x$w) = $this->_tableGetWidth($table$i$j);
  19545.                             $js $j;
  19546.                         }
  19547.                         list($y$h) = $this->_tableGetHeight($table$i$j);
  19548.                         $x += $x0;
  19549.                         $y += $y0;
  19550.                         // Get info of tfoot ==>> table footer
  19551.                         $tablefooter[$i][$js]['x'] = $x;
  19552.                         $tablefooter[$i][$js]['y'] = $y;
  19553.                         $tablefooter[$i][$js]['h'] = $h;
  19554.                         $tablefooter[$i][$js]['w'] = $w;
  19555.                         if (isset($cell['textbuffer'])) {
  19556.                             $tablefooter[$i][$js]['textbuffer'] = $cell['textbuffer'];
  19557.                         } else {
  19558.                             $tablefooter[$i][$js]['textbuffer'] = '';
  19559.                         }
  19560.                         $tablefooter[$i][$js]['a'] = $cell['a'];
  19561.                         $tablefooter[$i][$js]['R'] = $cell['R'];
  19562.                         $tablefooter[$i][$js]['va'] = $cell['va'];
  19563.                         $tablefooter[$i][$js]['mih'] = $cell['mih'];
  19564.                         if (isset($cell['gradient'])) {
  19565.                             $tablefooter[$i][$js]['gradient'] = $cell['gradient']; // *BACKGROUNDS*
  19566.                         }
  19567.                         if (isset($cell['background-image'])) {
  19568.                             $tablefooter[$i][$js]['background-image'] = $cell['background-image']; // *BACKGROUNDS*
  19569.                         }
  19570.                         // CELL FILL BGCOLOR
  19571.                         if (!$this->simpleTables) {
  19572.                             if ($this->packTableData) {
  19573.                                 $c $this->_unpackCellBorder($cell['borderbin']);
  19574.                                 $tablefooter[$i][$js]['border'] = $c['border'];
  19575.                                 $tablefooter[$i][$js]['border_details'] = $c['border_details'];
  19576.                             } else {
  19577.                                 $tablefooter[$i][$js]['border'] = $cell['border'];
  19578.                                 $tablefooter[$i][$js]['border_details'] = $cell['border_details'];
  19579.                             }
  19580.                         } elseif ($this->simpleTables) {
  19581.                             $tablefooter[$i][$js]['border'] = $table['simple']['border'];
  19582.                             $tablefooter[$i][$js]['border_details'] = $table['simple']['border_details'];
  19583.                         }
  19584.                         $tablefooter[$i][$js]['bgcolor'] = $cell['bgcolor'];
  19585.                         $tablefooter[$i][$js]['padding'] = $cell['padding'];
  19586.                         if (isset($cell['rowspan'])) {
  19587.                             $tablefooter[$i][$js]['rowspan'] = $cell['rowspan'];
  19588.                         }
  19589.                         if (isset($cell['colspan'])) {
  19590.                             $tablefooter[$i][$js]['colspan'] = $cell['colspan'];
  19591.                         }
  19592.                         if (isset($cell['direction'])) {
  19593.                             $tablefooter[$i][$js]['direction'] = $cell['direction'];
  19594.                         }
  19595.                         if (isset($cell['cellLineHeight'])) {
  19596.                             $tablefooter[$i][$js]['cellLineHeight'] = $cell['cellLineHeight'];
  19597.                         }
  19598.                         if (isset($cell['cellLineStackingStrategy'])) {
  19599.                             $tablefooter[$i][$js]['cellLineStackingStrategy'] = $cell['cellLineStackingStrategy'];
  19600.                         }
  19601.                         if (isset($cell['cellLineStackingShift'])) {
  19602.                             $tablefooter[$i][$js]['cellLineStackingShift'] = $cell['cellLineStackingShift'];
  19603.                         }
  19604.                     }
  19605.                 }
  19606.             }
  19607.         }
  19608.         if ($level == 1) {
  19609.             $this->writer->write('___TABLE___BACKGROUNDS' $this->uniqstr);
  19610.         }
  19611.         $tableheaderadj 0;
  19612.         $tablefooteradj 0;
  19613.         $tablestartpageno $this->page;
  19614.         // Draw Table Contents and Borders
  19615.         for ($i 0$i $numrows$i++) { // Rows
  19616.             if ($split && $startrow 0) {
  19617.                 $thnr = (isset($table['is_thead']) ? count($table['is_thead']) : 0);
  19618.                 if ($i >= $thnr && $i $startrow) {
  19619.                     continue;
  19620.                 }
  19621.                 if ($i == $startrow) {
  19622.                     $returny $rety $tableheaderrowheight;
  19623.                 }
  19624.             }
  19625.             // Get Maximum row/cell height in row - including rowspan>1 + 1 overlapping
  19626.             $maxrowheight $this->_tableGetMaxRowHeight($table$i);
  19627.             $skippage false;
  19628.             $newpagestarted false;
  19629.             for ($j $startcol$j $numcols$j++) { // Columns
  19630.                 if ($split) {
  19631.                     if ($table['colPg'][$j] > $splitpg) {
  19632.                         break;
  19633.                     }
  19634.                     $lastCol $j;
  19635.                 }
  19636.                 if (isset($cells[$i][$j]) && $cells[$i][$j]) {
  19637.                     $cell = &$cells[$i][$j];
  19638.                     if ($split) {
  19639.                         $lastCol $j + (isset($cell['colspan']) ? ($cell['colspan'] - 1) : 0);
  19640.                         list($x$w) = $this->_splitTableGetWidth($table$i$j);
  19641.                     } else {
  19642.                         list($x$w) = $this->_tableGetWidth($table$i$j);
  19643.                     }
  19644.                     list($y$h) = $this->_tableGetHeight($table$i$j);
  19645.                     $x += $x0;
  19646.                     $y += $y0;
  19647.                     $y -= $returny;
  19648.                     if ($table['borders_separate']) {
  19649.                         if (!empty($tablefooter) || $i == ($numrows 1) || (isset($cell['rowspan']) && ($i $cell['rowspan']) == $numrows) || (!isset($cell['rowspan']) && ($i 1) == $numrows)) {
  19650.                             $extra $table['padding']['B'] + $table['border_details']['B']['w'] + $table['border_spacing_V'] / 2;
  19651.                             // $extra = $table['margin']['B'] + $table['padding']['B'] + $table['border_details']['B']['w'] + $table['border_spacing_V']/2;
  19652.                         } else {
  19653.                             $extra $table['border_spacing_V'] / 2;
  19654.                         }
  19655.                     } else {
  19656.                         $extra $table['max_cell_border_width']['B'] / 2;
  19657.                     }
  19658.                     // lookahead for pagebreak
  19659.                     $pagebreaklookahead 1;
  19660.                     while (isset($table['pagebreak-before']) && isset($table['pagebreak-before'][$i $pagebreaklookahead]) && $table['pagebreak-before'][$i $pagebreaklookahead] == 'avoid') {
  19661.                         // pagebreak-after is mapped to pagebreak-before on i+1 in Tags/Tr.php
  19662.                         $pagebreaklookahead++;
  19663.                     }
  19664.                     if ($j == $startcol && ((($y $pagebreaklookahead $maxrowheight $extra ) > ($pagetrigger 0.001)) || (($this->keepColumns || !$this->ColActive) && !empty($tablefooter) && ($y $maxrowheight $tablefooterrowheight $extra) > $pagetrigger) && ($this->tableLevel == && $i < ($numrows $table['headernrows']))) && ($y0 || $x0 0) && !$this->InFooter && $this->autoPageBreak) {
  19665.                         if (!$skippage) {
  19666.                             $finalSpread true;
  19667.                             $firstSpread true;
  19668.                             if ($split) {
  19669.                                 for ($t $startcol$t $numcols$t++) {
  19670.                                     // Are there more columns to print on a next page?
  19671.                                     if ($table['colPg'][$t] > $splitpg) {
  19672.                                         $finalSpread false;
  19673.                                         break;
  19674.                                     }
  19675.                                 }
  19676.                                 if ($startcol 0) {
  19677.                                     $firstSpread false;
  19678.                                 }
  19679.                             }
  19680.                             if (($this->keepColumns || !$this->ColActive) && !empty($tablefooter) && $i 0) {
  19681.                                 $this->$y;
  19682.                                 $ya $this->y;
  19683.                                 $this->TableHeaderFooter($tablefooter$tablestartpage$tablestartcolumn'F'$level$firstSpread$finalSpread);
  19684.                                 if ($this->table_rotate) {
  19685.                                     $this->tbrot_h += $this->$ya;
  19686.                                 }
  19687.                                 $tablefooteradj $this->$ya;
  19688.                             }
  19689.                             $y -= $y0;
  19690.                             $returny += $y;
  19691.                             $oldcolumn $this->CurrCol;
  19692.                             if ($this->AcceptPageBreak()) {
  19693.                                 $newpagestarted true;
  19694.                                 $this->$y $y0;
  19695.                                 // Move down to account for border-spacing or
  19696.                                 // extra half border width in case page breaks in middle
  19697.                                 if ($i && !$this->table_rotate && $level == && !$this->ColActive) {
  19698.                                     if ($table['borders_separate']) {
  19699.                                         $adv $table['border_spacing_V'] / 2;
  19700.                                         // If table footer
  19701.                                         if (($this->keepColumns || !$this->ColActive) && !empty($tablefooter) && $i 0) {
  19702.                                             $adv += ($table['padding']['B'] + $table['border_details']['B']['w']);
  19703.                                         }
  19704.                                     } else {
  19705.                                         $maxbwtop 0;
  19706.                                         $maxbwbottom 0;
  19707.                                         if (!$this->simpleTables) {
  19708.                                             if (!empty($tablefooter)) {
  19709.                                                 $maxbwbottom $table['max_cell_border_width']['B'];
  19710.                                             } else {
  19711.                                                 $brow $i 1;
  19712.                                                 for ($ctj 0$ctj $numcols$ctj++) {
  19713.                                                     if (isset($cells[$brow][$ctj]) && $cells[$brow][$ctj]) {
  19714.                                                         if ($this->packTableData) {
  19715.                                                             list($bt$br$bb$bl) = $this->_getBorderWidths($cells[$brow][$ctj]['borderbin']);
  19716.                                                         } else {
  19717.                                                             $bb $cells[$brow][$ctj]['border_details']['B']['w'];
  19718.                                                         }
  19719.                                                         $maxbwbottom max($maxbwbottom$bb);
  19720.                                                     }
  19721.                                                 }
  19722.                                             }
  19723.                                             if (!empty($tableheader)) {
  19724.                                                 $maxbwtop $table['max_cell_border_width']['T'];
  19725.                                             } else {
  19726.                                                 $trow $i 1;
  19727.                                                 for ($ctj 0$ctj $numcols$ctj++) {
  19728.                                                     if (isset($cells[$trow][$ctj]) && $cells[$trow][$ctj]) {
  19729.                                                         if ($this->packTableData) {
  19730.                                                             list($bt$br$bb$bl) = $this->_getBorderWidths($cells[$trow][$ctj]['borderbin']);
  19731.                                                         } else {
  19732.                                                             $bt $cells[$trow][$ctj]['border_details']['T']['w'];
  19733.                                                         }
  19734.                                                         $maxbwtop max($maxbwtop$bt);
  19735.                                                     }
  19736.                                                 }
  19737.                                             }
  19738.                                         } elseif ($this->simpleTables) {
  19739.                                             $maxbwtop $table['simple']['border_details']['T']['w'];
  19740.                                             $maxbwbottom $table['simple']['border_details']['B']['w'];
  19741.                                         }
  19742.                                         $adv $maxbwbottom 2;
  19743.                                     }
  19744.                                     $this->+= $adv;
  19745.                                 }
  19746.                                 // Rotated table split over pages - needs this->y for borders/backgrounds
  19747.                                 if ($i && $this->table_rotate && $level == 1) {
  19748.                                     //         $this->y = $y0 + $this->tbrot_w;
  19749.                                 }
  19750.                                 if ($this->tableClipPath) {
  19751.                                     $this->writer->write("Q");
  19752.                                 }
  19753.                                 $bx $x0;
  19754.                                 $by $y0;
  19755.                                 if ($table['borders_separate']) {
  19756.                                     $bx -= ($table['padding']['L'] + $table['border_details']['L']['w'] + $table['border_spacing_H'] / 2);
  19757.                                     if ($tablestartpageno != $this->page) { // IF already broken across a previous pagebreak
  19758.                                         $by += $table['max_cell_border_width']['T'] / 2;
  19759.                                         if (empty($tableheader)) {
  19760.                                             $by -= ($table['border_spacing_V'] / 2);
  19761.                                         }
  19762.                                     } else {
  19763.                                         $by -= ($table['padding']['T'] + $table['border_details']['T']['w'] + $table['border_spacing_V'] / 2);
  19764.                                     }
  19765.                                 } elseif ($tablestartpageno != $this->page && !empty($tableheader)) {
  19766.                                     $by += $maxbwtop 2;
  19767.                                 }
  19768.                                 $by -= $tableheaderadj;
  19769.                                 $bh $this->$by $tablefooteradj;
  19770.                                 if (!$table['borders_separate']) {
  19771.                                     $bh -= $adv;
  19772.                                 }
  19773.                                 if ($split) {
  19774.                                     $bw 0;
  19775.                                     for ($t $startcol$t $numcols$t++) {
  19776.                                         if ($table['colPg'][$t] == $splitpg) {
  19777.                                             $bw += $table['wc'][$t];
  19778.                                         }
  19779.                                         if ($table['colPg'][$t] > $splitpg) {
  19780.                                             break;
  19781.                                         }
  19782.                                     }
  19783.                                     if ($table['borders_separate']) {
  19784.                                         if ($firstSpread) {
  19785.                                             $bw += $table['padding']['L'] + $table['border_details']['L']['w'] + $table['border_spacing_H'];
  19786.                                         } else {
  19787.                                             $bx += ($table['padding']['L'] + $table['border_details']['L']['w']);
  19788.                                             $bw += $table['border_spacing_H'];
  19789.                                         }
  19790.                                         if ($finalSpread) {
  19791.                                             $bw += $table['padding']['R'] + $table['border_details']['R']['w'] / $table['border_spacing_H'];
  19792.                                         }
  19793.                                     }
  19794.                                 } else {
  19795.                                     $bw $table['w'] - ($table['max_cell_border_width']['L'] / 2) - ($table['max_cell_border_width']['R'] / 2) - $table['margin']['L'] - $table['margin']['R'];
  19796.                                 }
  19797.                                 if ($this->splitTableBorderWidth && ($this->keepColumns || !$this->ColActive) && empty($tablefooter) && $i && $table['border_details']['B']['w']) {
  19798.                                     $prevDrawColor $this->DrawColor;
  19799.                                     $lw $this->LineWidth;
  19800.                                     $this->SetLineWidth($this->splitTableBorderWidth);
  19801.                                     $this->SetDColor($table['border_details']['B']['c']);
  19802.                                     $this->SetLineJoin(0);
  19803.                                     $this->SetLineCap(0);
  19804.                                     $blx $bx;
  19805.                                     $blw $bw;
  19806.                                     if (!$table['borders_separate']) {
  19807.                                         $blx -= ($table['max_cell_border_width']['L'] / 2);
  19808.                                         $blw += ($table['max_cell_border_width']['L'] / $table['max_cell_border_width']['R'] / 2);
  19809.                                     }
  19810.                                     $this->Line($blx$this->+ ($this->splitTableBorderWidth 2), $blx $blw$this->+ ($this->splitTableBorderWidth 2));
  19811.                                     $this->DrawColor $prevDrawColor;
  19812.                                     $this->writer->write($this->DrawColor);
  19813.                                     $this->SetLineWidth($lw);
  19814.                                     $this->SetLineJoin(2);
  19815.                                     $this->SetLineCap(2);
  19816.                                 }
  19817.                                 if (!$this->ColActive && ($i || $j 0)) {
  19818.                                     if (isset($table['bgcolor'][-1])) {
  19819.                                         $color $this->colorConverter->convert($table['bgcolor'][-1], $this->PDFAXwarnings);
  19820.                                         if ($color) {
  19821.                                             if (!$table['borders_separate']) {
  19822.                                                 $bh -= $table['max_cell_border_width']['B'] / 2;
  19823.                                             }
  19824.                                             $this->tableBackgrounds[$level 9][] = ['gradient' => false'x' => $bx'y' => $by'w' => $bw'h' => $bh'col' => $color];
  19825.                                         }
  19826.                                     }
  19827.                                     /* -- BACKGROUNDS -- */
  19828.                                     if (isset($table['gradient'])) {
  19829.                                         $g $this->gradient->parseBackgroundGradient($table['gradient']);
  19830.                                         if ($g) {
  19831.                                             $this->tableBackgrounds[$level 1][] = ['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' => ''];
  19832.                                         }
  19833.                                     }
  19834.                                     if (isset($table['background-image'])) {
  19835.                                         if ($table['background-image']['gradient'] && preg_match('/(-moz-)*(repeating-)*(linear|radial)-gradient/'$table['background-image']['gradient'])) {
  19836.                                             $g $this->gradient->parseMozGradient($table['background-image']['gradient']);
  19837.                                             if ($g) {
  19838.                                                 $this->tableBackgrounds[$level 1][] = ['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' => ''];
  19839.                                             }
  19840.                                         } else {
  19841.                                             $image_id $table['background-image']['image_id'];
  19842.                                             $orig_w $table['background-image']['orig_w'];
  19843.                                             $orig_h $table['background-image']['orig_h'];
  19844.                                             $x_pos $table['background-image']['x_pos'];
  19845.                                             $y_pos $table['background-image']['y_pos'];
  19846.                                             $x_repeat $table['background-image']['x_repeat'];
  19847.                                             $y_repeat $table['background-image']['y_repeat'];
  19848.                                             $resize $table['background-image']['resize'];
  19849.                                             $opacity $table['background-image']['opacity'];
  19850.                                             $itype $table['background-image']['itype'];
  19851.                                             $this->tableBackgrounds[$level 2][] = ['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];
  19852.                                         }
  19853.                                     }
  19854.                                     /* -- END BACKGROUNDS -- */
  19855.                                 }
  19856.                                 // $this->AcceptPageBreak() has moved tablebuffer to $this->pages content
  19857.                                 if ($this->tableBackgrounds) {
  19858.                                     $s $this->PrintTableBackgrounds();
  19859.                                     if ($this->bufferoutput) {
  19860.                                         $this->headerbuffer preg_replace('/(___TABLE___BACKGROUNDS' $this->uniqstr ')/''\\1' "\n" $s "\n"$this->headerbuffer);
  19861.                                         $this->headerbuffer preg_replace('/(___TABLE___BACKGROUNDS' $this->uniqstr ')/'" "$this->headerbuffer);
  19862.                                     } else {
  19863.                                         $this->pages[$this->page] = preg_replace('/(___TABLE___BACKGROUNDS' $this->uniqstr ')/''\\1' "\n" $s "\n"$this->pages[$this->page]);
  19864.                                         $this->pages[$this->page] = preg_replace('/(___TABLE___BACKGROUNDS' $this->uniqstr ')/'" "$this->pages[$this->page]);
  19865.                                     }
  19866.                                     $this->tableBackgrounds = [];
  19867.                                 }
  19868.                                 if ($split) {
  19869.                                     if ($i == && $j == 0) {
  19870.                                         $y0 = -1;
  19871.                                     } elseif ($finalSpread) {
  19872.                                         $splitpg 0;
  19873.                                         $startcol 0;
  19874.                                         $startrow $i;
  19875.                                     } else {
  19876.                                         $splitpg++;
  19877.                                         $startcol $t;
  19878.                                         $returny -= $y;
  19879.                                     }
  19880.                                     return [false$startrow$startcol$splitpg$returny$y0];
  19881.                                 }
  19882.                                 $this->AddPage($this->CurOrientation);
  19883.                                 $this->writer->write('___TABLE___BACKGROUNDS' $this->uniqstr);
  19884.                                 if ($this->tableClipPath) {
  19885.                                     $this->writer->write($this->tableClipPath);
  19886.                                 }
  19887.                                 // Added to correct for OddEven Margins
  19888.                                 $x $x $this->MarginCorrection;
  19889.                                 $x0 $x0 $this->MarginCorrection;
  19890.                                 if ($this->splitTableBorderWidth && ($this->keepColumns || !$this->ColActive) && empty($tableheader) && $i && $table['border_details']['T']['w']) {
  19891.                                     $prevDrawColor $this->DrawColor;
  19892.                                     $lw $this->LineWidth;
  19893.                                     $this->SetLineWidth($this->splitTableBorderWidth);
  19894.                                     $this->SetDColor($table['border_details']['T']['c']);
  19895.                                     $this->SetLineJoin(0);
  19896.                                     $this->SetLineCap(0);
  19897.                                     $blx += $this->MarginCorrection;
  19898.                                     $this->Line($blx$this->- ($this->splitTableBorderWidth 2), $blx $blw$this->- ($this->splitTableBorderWidth 2));
  19899.                                     $this->DrawColor $prevDrawColor;
  19900.                                     $this->writer->write($this->DrawColor);
  19901.                                     $this->SetLineWidth($lw);
  19902.                                     $this->SetLineJoin(2);
  19903.                                     $this->SetLineCap(2);
  19904.                                 }
  19905.                                 // Move down to account for half of top border-spacing or
  19906.                                 // extra half border width in case page was broken in middle
  19907.                                 if ($i && !$this->table_rotate && $level == && $table['headernrows'] == 0) {
  19908.                                     if ($table['borders_separate']) {
  19909.                                         $adv $table['border_spacing_V'] / 2;
  19910.                                     } else {
  19911.                                         $maxbwtop 0;
  19912.                                         for ($ctj 0$ctj $numcols$ctj++) {
  19913.                                             if (isset($cells[$i][$ctj]) && $cells[$i][$ctj]) {
  19914.                                                 if (!$this->simpleTables) {
  19915.                                                     if ($this->packTableData) {
  19916.                                                         list($bt$br$bb$bl) = $this->_getBorderWidths($cells[$i][$ctj]['borderbin']);
  19917.                                                     } else {
  19918.                                                         $bt $cells[$i][$ctj]['border_details']['T']['w'];
  19919.                                                     }
  19920.                                                     $maxbwtop max($maxbwtop$bt);
  19921.                                                 } elseif ($this->simpleTables) {
  19922.                                                     $maxbwtop max($maxbwtop$table['simple']['border_details']['T']['w']);
  19923.                                                 }
  19924.                                             }
  19925.                                         }
  19926.                                         $adv $maxbwtop 2;
  19927.                                     }
  19928.                                     $this->+= $adv;
  19929.                                 }
  19930.                                 if ($this->table_rotate) {
  19931.                                     $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'];
  19932.                                     if ($table['borders_separate']) {
  19933.                                         $this->tbrot_h $table['margin']['T'] + $table['padding']['T'] + $table['border_details']['T']['w'] + $table['border_spacing_V'] / 2;
  19934.                                     } else {
  19935.                                         $this->tbrot_h $table['margin']['T'] + $table['max_cell_border_width']['T'];
  19936.                                     }
  19937.                                     $this->tbrot_y0 $this->y;
  19938.                                     $pagetrigger $y0 $tableheaderadj + ($this->blk[$this->blklvl]['inner_width']);
  19939.                                 } else {
  19940.                                     $pagetrigger $this->PageBreakTrigger;
  19941.                                 }
  19942.                                 if ($this->kwt_saved && $level == 1) {
  19943.                                     $this->kwt_moved true;
  19944.                                 }
  19945.                                 if (!empty($tableheader)) {
  19946.                                     $ya $this->y;
  19947.                                     $this->TableHeaderFooter($tableheader$tablestartpage$tablestartcolumn'H'$level);
  19948.                                     if ($this->table_rotate) {
  19949.                                         $this->tbrot_h $this->$ya;
  19950.                                     }
  19951.                                     $tableheaderadj $this->$ya;
  19952.                                 } elseif ($i == && !$this->table_rotate && $level == && !$this->ColActive) {
  19953.                                     // Advance down page
  19954.                                     if ($table['borders_separate']) {
  19955.                                         $adv $table['border_spacing_V'] / $table['border_details']['T']['w'] + $table['padding']['T'];
  19956.                                     } else {
  19957.                                         $adv $table['max_cell_border_width']['T'] / 2;
  19958.                                     }
  19959.                                     if ($adv) {
  19960.                                         if ($this->table_rotate) {
  19961.                                             $this->+= ($adv);
  19962.                                         } else {
  19963.                                             $this->DivLn($adv$this->blklvltrue);
  19964.                                         }
  19965.                                     }
  19966.                                 }
  19967.                                 $outerfilled 0;
  19968.                                 $y $y0 $this->y;
  19969.                             }
  19970.                             /* -- COLUMNS -- */
  19971.                             // COLS
  19972.                             // COLUMN CHANGE
  19973.                             if ($this->CurrCol != $oldcolumn) {
  19974.                                 // Added to correct for Columns
  19975.                                 $x += $this->ChangeColumn * ($this->ColWidth $this->ColGap);
  19976.                                 $x0 += $this->ChangeColumn * ($this->ColWidth $this->ColGap);
  19977.                                 if ($this->CurrCol == 0) {  // just added a page - possibly with tableheader
  19978.                                     $y0 $this->y;  // this->y0 is global used by Columns - $y0 is internal to tablewrite
  19979.                                 } else {
  19980.                                     $y0 $this->y0;  // this->y0 is global used by Columns - $y0 is internal to tablewrite
  19981.                                 }
  19982.                                 $y $y0;
  19983.                                 $outerfilled 0;
  19984.                                 if ($this->CurrCol != && ($this->keepColumns && $this->ColActive) && !empty($tableheader) && $i 0) {
  19985.                                     $this->$x;
  19986.                                     $this->$y;
  19987.                                     $this->TableHeaderFooter($tableheader$tablestartpage$tablestartcolumn'H'$level);
  19988.                                     $y0 $y $this->y;
  19989.                                 }
  19990.                             }
  19991.                             /* -- END COLUMNS -- */
  19992.                         }
  19993.                         $skippage true;
  19994.                     }
  19995.                     $this->$x;
  19996.                     $this->$y;
  19997.                     if ($this->kwt_saved && $level == 1) {
  19998.                         $this->printkwtbuffer();
  19999.                         $x0 $x $this->x;
  20000.                         $y0 $y $this->y;
  20001.                         $this->kwt_moved false;
  20002.                         $this->kwt_saved false;
  20003.                     }
  20004.                     // Set the Page & Column where table actually starts
  20005.                     if ($i == && $j == && $level == 1) {
  20006.                         if (($this->mirrorMargins) && (($this->page) % == 0)) {    // EVEN
  20007.                             $tablestartpage 'EVEN';
  20008.                         } elseif (($this->mirrorMargins) && (($this->page) % == 1)) {    // ODD
  20009.                             $tablestartpage 'ODD';
  20010.                         } else {
  20011.                             $tablestartpage '';
  20012.                         }
  20013.                         $tablestartpageno $this->page;
  20014.                         if ($this->ColActive) {
  20015.                             $tablestartcolumn $this->CurrCol;
  20016.                         } // *COLUMNS*
  20017.                     }
  20018.                     // ALIGN
  20019.                     $align $cell['a'];
  20020.                     /* -- COLUMNS -- */
  20021.                     // If outside columns, this is done in PaintDivBB
  20022.                     if ($this->ColActive) {
  20023.                         // OUTER FILL BGCOLOR of DIVS
  20024.                         if ($this->blklvl && ($j == 0) && !$this->table_rotate && $level == 1) {
  20025.                             $firstblockfill $this->GetFirstBlockFill();
  20026.                             if ($firstblockfill && $this->blklvl >= $firstblockfill) {
  20027.                                 $divh $maxrowheight;
  20028.                                 // Last row
  20029.                                 if ((!isset($cell['rowspan']) && $i == $numrows 1) || (isset($cell['rowspan']) && (($i == $numrows && $cell['rowspan'] < 2) || ($cell['rowspan'] > && ($i $cell['rowspan'] - 1) == $numrows 1)))) {
  20030.                                     if ($table['borders_separate']) {
  20031.                                         $adv $table['margin']['B'] + $table['padding']['B'] + $table['border_details']['B']['w'] + $table['border_spacing_V'] / 2;
  20032.                                     } else {
  20033.                                         $adv $table['margin']['B'] + $table['max_cell_border_width']['B'] / 2;
  20034.                                     }
  20035.                                     $divh += $adv;  // last row: fill bottom half of bottom border (y advanced at end)
  20036.                                 }
  20037.                                 if (($this->$divh) > $outerfilled) { // if not already painted by previous rowspan
  20038.                                     $bak_x $this->x;
  20039.                                     $bak_y $this->y;
  20040.                                     if ($outerfilled $this->y) {
  20041.                                         $divh = ($this->$divh) - $outerfilled;
  20042.                                         $this->$outerfilled;
  20043.                                     }
  20044.                                     $this->DivLn($divh, -3false);
  20045.                                     $outerfilled $this->$divh;
  20046.                                     // Reset current block fill
  20047.                                     $bcor $this->blk[$this->blklvl]['bgcolorarray'];
  20048.                                     if ($bcor) {
  20049.                                         $this->SetFColor($bcor);
  20050.                                     }
  20051.                                     $this->$bak_x;
  20052.                                     $this->$bak_y;
  20053.                                 }
  20054.                             }
  20055.                         }
  20056.                     }
  20057.                     // TABLE BACKGROUND FILL BGCOLOR - for cellSpacing
  20058.                     if ($this->ColActive) {
  20059.                         if ($table['borders_separate']) {
  20060.                             $fill = isset($table['bgcolor'][-1]) ? $table['bgcolor'][-1] : 0;
  20061.                             if ($fill) {
  20062.                                 $color $this->colorConverter->convert($fill$this->PDFAXwarnings);
  20063.                                 if ($color) {
  20064.                                     $xadj = ($table['border_spacing_H'] / 2);
  20065.                                     $yadj = ($table['border_spacing_V'] / 2);
  20066.                                     $wadj $table['border_spacing_H'];
  20067.                                     $hadj $table['border_spacing_V'];
  20068.                                     if ($i == 0) {  // Top
  20069.                                         $yadj += $table['padding']['T'] + $table['border_details']['T']['w'];
  20070.                                         $hadj += $table['padding']['T'] + $table['border_details']['T']['w'];
  20071.                                     }
  20072.                                     if ($j == 0) {  // Left
  20073.                                         $xadj += $table['padding']['L'] + $table['border_details']['L']['w'];
  20074.                                         $wadj += $table['padding']['L'] + $table['border_details']['L']['w'];
  20075.                                     }
  20076.                                     if ($i == ($numrows 1) || (isset($cell['rowspan']) && ($i $cell['rowspan']) == $numrows) || (!isset($cell['rowspan']) && ($i 1) == $numrows)) { // Bottom
  20077.                                         $hadj += $table['padding']['B'] + $table['border_details']['B']['w'];
  20078.                                     }
  20079.                                     if ($j == ($numcols 1) || (isset($cell['colspan']) && ($j $cell['colspan']) == $numcols) || (!isset($cell['colspan']) && ($j 1) == $numcols)) { // Right
  20080.                                         $wadj += $table['padding']['R'] + $table['border_details']['R']['w'];
  20081.                                     }
  20082.                                     $this->SetFColor($color);
  20083.                                     $this->Rect($x $xadj$y $yadj$w $wadj$h $hadj'F');
  20084.                                 }
  20085.                             }
  20086.                         }
  20087.                     }
  20088.                     /* -- END COLUMNS -- */
  20089.                     if ($table['empty_cells'] != 'hide' || !empty($cell['textbuffer']) || (isset($cell['nestedcontent']) && $cell['nestedcontent']) || !$table['borders_separate']) {
  20090.                         $paintcell true;
  20091.                     } else {
  20092.                         $paintcell false;
  20093.                     }
  20094.                     // Set Borders
  20095.                     $bord 0;
  20096.                     $bord_det = [];
  20097.                     if (!$this->simpleTables) {
  20098.                         if ($this->packTableData) {
  20099.                             $c $this->_unpackCellBorder($cell['borderbin']);
  20100.                             $bord $c['border'];
  20101.                             $bord_det $c['border_details'];
  20102.                         } else {
  20103.                             $bord $cell['border'];
  20104.                             $bord_det $cell['border_details'];
  20105.                         }
  20106.                     } elseif ($this->simpleTables) {
  20107.                         $bord $table['simple']['border'];
  20108.                         $bord_det $table['simple']['border_details'];
  20109.                     }
  20110.                     // TABLE ROW OR CELL FILL BGCOLOR
  20111.                     $fill 0;
  20112.                     if (isset($cell['bgcolor']) && $cell['bgcolor'] && $cell['bgcolor'] != 'transparent') {
  20113.                         $fill $cell['bgcolor'];
  20114.                         $leveladj 6;
  20115.                     } elseif (isset($table['bgcolor'][$i]) && $table['bgcolor'][$i] && $table['bgcolor'][$i] != 'transparent') { // Row color
  20116.                         $fill $table['bgcolor'][$i];
  20117.                         $leveladj 3;
  20118.                     }
  20119.                     if ($fill && $paintcell) {
  20120.                         $color $this->colorConverter->convert($fill$this->PDFAXwarnings);
  20121.                         if ($color) {
  20122.                             if ($table['borders_separate']) {
  20123.                                 if ($this->ColActive) {
  20124.                                     $this->SetFColor($color);
  20125.                                     $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');
  20126.                                 } else {
  20127.                                     $this->tableBackgrounds[$level $leveladj][] = ['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];
  20128.                                 }
  20129.                             } else {
  20130.                                 if ($this->ColActive) {
  20131.                                     $this->SetFColor($color);
  20132.                                     $this->Rect($x$y$w$h'F');
  20133.                                 } else {
  20134.                                     $this->tableBackgrounds[$level $leveladj][] = ['gradient' => false'x' => $x'y' => $y'w' => $w'h' => $h'col' => $color];
  20135.                                 }
  20136.                             }
  20137.                         }
  20138.                     }
  20139.                     /* -- BACKGROUNDS -- */
  20140.                     if (isset($cell['gradient']) && $cell['gradient'] && $paintcell) {
  20141.                         $g $this->gradient->parseBackgroundGradient($cell['gradient']);
  20142.                         if ($g) {
  20143.                             if ($table['borders_separate']) {
  20144.                                 $px $x + ($table['border_spacing_H'] / 2);
  20145.                                 $py $y + ($table['border_spacing_V'] / 2);
  20146.                                 $pw $w $table['border_spacing_H'];
  20147.                                 $ph $h $table['border_spacing_V'];
  20148.                             } else {
  20149.                                 $px $x;
  20150.                                 $py $y;
  20151.                                 $pw $w;
  20152.                                 $ph $h;
  20153.                             }
  20154.                             if ($this->ColActive) {
  20155.                                 $this->gradient->Gradient($px$py$pw$ph$g['type'], $g['stops'], $g['colorspace'], $g['coords'], $g['extend']);
  20156.                             } else {
  20157.                                 $this->tableBackgrounds[$level 7][] = ['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' => ''];
  20158.                             }
  20159.                         }
  20160.                     }
  20161.                     if (isset($cell['background-image']) && $paintcell) {
  20162.                         if (isset($cell['background-image']['gradient']) && $cell['background-image']['gradient'] && preg_match('/(-moz-)*(repeating-)*(linear|radial)-gradient/'$cell['background-image']['gradient'])) {
  20163.                             $g $this->gradient->parseMozGradient($cell['background-image']['gradient']);
  20164.                             if ($g) {
  20165.                                 if ($table['borders_separate']) {
  20166.                                     $px $x + ($table['border_spacing_H'] / 2);
  20167.                                     $py $y + ($table['border_spacing_V'] / 2);
  20168.                                     $pw $w $table['border_spacing_H'];
  20169.                                     $ph $h $table['border_spacing_V'];
  20170.                                 } else {
  20171.                                     $px $x;
  20172.                                     $py $y;
  20173.                                     $pw $w;
  20174.                                     $ph $h;
  20175.                                 }
  20176.                                 if ($this->ColActive) {
  20177.                                     $this->gradient->Gradient($px$py$pw$ph$g['type'], $g['stops'], $g['colorspace'], $g['coords'], $g['extend']);
  20178.                                 } else {
  20179.                                     $this->tableBackgrounds[$level 7][] = ['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' => ''];
  20180.                                 }
  20181.                             }
  20182.                         } elseif (isset($cell['background-image']['image_id']) && $cell['background-image']['image_id']) { // Background pattern
  20183.                             $n count($this->patterns) + 1;
  20184.                             if ($table['borders_separate']) {
  20185.                                 $px $x + ($table['border_spacing_H'] / 2);
  20186.                                 $py $y + ($table['border_spacing_V'] / 2);
  20187.                                 $pw $w $table['border_spacing_H'];
  20188.                                 $ph $h $table['border_spacing_V'];
  20189.                             } else {
  20190.                                 $px $x;
  20191.                                 $py $y;
  20192.                                 $pw $w;
  20193.                                 $ph $h;
  20194.                             }
  20195.                             if ($this->ColActive) {
  20196.                                 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']);
  20197.                                 $this->patterns[$n] = ['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];
  20198.                                 if ($cell['background-image']['opacity'] > && $cell['background-image']['opacity'] < 1) {
  20199.                                     $opac $this->SetAlpha($cell['background-image']['opacity'], 'Normal'true);
  20200.                                 } else {
  20201.                                     $opac '';
  20202.                                 }
  20203.                                 $this->writer->write(sprintf('q /Pattern cs /P%d scn %s %.3F %.3F %.3F %.3F re f Q'$n$opac$px Mpdf::SCALE, ($this->$py) * Mpdf::SCALE$pw Mpdf::SCALE, -$ph Mpdf::SCALE));
  20204.                             } else {
  20205.                                 $image_id $cell['background-image']['image_id'];
  20206.                                 $orig_w $cell['background-image']['orig_w'];
  20207.                                 $orig_h $cell['background-image']['orig_h'];
  20208.                                 $x_pos $cell['background-image']['x_pos'];
  20209.                                 $y_pos $cell['background-image']['y_pos'];
  20210.                                 $x_repeat $cell['background-image']['x_repeat'];
  20211.                                 $y_repeat $cell['background-image']['y_repeat'];
  20212.                                 $resize $cell['background-image']['resize'];
  20213.                                 $opacity $cell['background-image']['opacity'];
  20214.                                 $itype $cell['background-image']['itype'];
  20215.                                 $this->tableBackgrounds[$level 8][] = ['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];
  20216.                             }
  20217.                         }
  20218.                     }
  20219.                     /* -- END BACKGROUNDS -- */
  20220.                     if (isset($cell['colspan']) && $cell['colspan'] > 1) {
  20221.                         $ccolsp $cell['colspan'];
  20222.                     } else {
  20223.                         $ccolsp 1;
  20224.                     }
  20225.                     if (isset($cell['rowspan']) && $cell['rowspan'] > 1) {
  20226.                         $crowsp $cell['rowspan'];
  20227.                     } else {
  20228.                         $crowsp 1;
  20229.                     }
  20230.                     // but still need to do this for repeated headers...
  20231.                     if (!$table['borders_separate'] && $this->tabletheadjustfinished && !$this->simpleTables) {
  20232.                         if (isset($table['topntail']) && $table['topntail']) {
  20233.                             $bord_det['T'] = $this->border_details($table['topntail']);
  20234.                             $bord_det['T']['w'] /= $this->shrin_k;
  20235.                             $this->setBorder($bordBorder::TOP);
  20236.                         }
  20237.                         if (isset($table['thead-underline']) && $table['thead-underline']) {
  20238.                             $bord_det['T'] = $this->border_details($table['thead-underline']);
  20239.                             $bord_det['T']['w'] /= $this->shrin_k;
  20240.                             $this->setBorder($bordBorder::TOP);
  20241.                         }
  20242.                     }
  20243.                     // Get info of first row ==>> table header
  20244.                     // Use > 1 row if THEAD
  20245.                     if (isset($table['is_thead'][$i]) && $table['is_thead'][$i] && $level == 1) {
  20246.                         if ($j == 0) {
  20247.                             $tableheaderrowheight += $table['hr'][$i];
  20248.                         }
  20249.                         $tableheader[$i][0]['trbackground-images'] = (isset($table['trbackground-images'][$i]) ? $table['trbackground-images'][$i] : null);
  20250.                         $tableheader[$i][0]['trgradients'] = (isset($table['trgradients'][$i]) ? $table['trgradients'][$i] : null);
  20251.                         $tableheader[$i][0]['trbgcolor'] = (isset($table['bgcolor'][$i]) ? $table['bgcolor'][$i] : null);
  20252.                         $tableheader[$i][$j]['x'] = $x;
  20253.                         $tableheader[$i][$j]['y'] = $y;
  20254.                         $tableheader[$i][$j]['h'] = $h;
  20255.                         $tableheader[$i][$j]['w'] = $w;
  20256.                         if (isset($cell['textbuffer'])) {
  20257.                             $tableheader[$i][$j]['textbuffer'] = $cell['textbuffer'];
  20258.                         } else {
  20259.                             $tableheader[$i][$j]['textbuffer'] = '';
  20260.                         }
  20261.                         $tableheader[$i][$j]['a'] = $cell['a'];
  20262.                         $tableheader[$i][$j]['R'] = $cell['R'];
  20263.                         $tableheader[$i][$j]['va'] = $cell['va'];
  20264.                         $tableheader[$i][$j]['mih'] = $cell['mih'];
  20265.                         $tableheader[$i][$j]['gradient'] = (isset($cell['gradient']) ? $cell['gradient'] : null); // *BACKGROUNDS*
  20266.                         $tableheader[$i][$j]['background-image'] = (isset($cell['background-image']) ? $cell['background-image'] : null); // *BACKGROUNDS*
  20267.                         $tableheader[$i][$j]['rowspan'] = (isset($cell['rowspan']) ? $cell['rowspan'] : null);
  20268.                         $tableheader[$i][$j]['colspan'] = (isset($cell['colspan']) ? $cell['colspan'] : null);
  20269.                         $tableheader[$i][$j]['bgcolor'] = $cell['bgcolor'];
  20270.                         if (!$this->simpleTables) {
  20271.                             $tableheader[$i][$j]['border'] = $bord;
  20272.                             $tableheader[$i][$j]['border_details'] = $bord_det;
  20273.                         } elseif ($this->simpleTables) {
  20274.                             $tableheader[$i][$j]['border'] = $table['simple']['border'];
  20275.                             $tableheader[$i][$j]['border_details'] = $table['simple']['border_details'];
  20276.                         }
  20277.                         $tableheader[$i][$j]['padding'] = $cell['padding'];
  20278.                         if (isset($cell['direction'])) {
  20279.                             $tableheader[$i][$j]['direction'] = $cell['direction'];
  20280.                         }
  20281.                         if (isset($cell['cellLineHeight'])) {
  20282.                             $tableheader[$i][$j]['cellLineHeight'] = $cell['cellLineHeight'];
  20283.                         }
  20284.                         if (isset($cell['cellLineStackingStrategy'])) {
  20285.                             $tableheader[$i][$j]['cellLineStackingStrategy'] = $cell['cellLineStackingStrategy'];
  20286.                         }
  20287.                         if (isset($cell['cellLineStackingShift'])) {
  20288.                             $tableheader[$i][$j]['cellLineStackingShift'] = $cell['cellLineStackingShift'];
  20289.                         }
  20290.                     }
  20291.                     // CELL BORDER
  20292.                     if ($bord) {
  20293.                         if ($table['borders_separate'] && $paintcell) {
  20294.                             $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_detfalse$table['borders_separate']);
  20295.                         } elseif (!$table['borders_separate']) {
  20296.                             $this->_tableRect($x$y$w$h$bord$bord_dettrue$table['borders_separate']);  // true causes buffer
  20297.                         }
  20298.                     }
  20299.                     // VERTICAL ALIGN
  20300.                     if ($cell['R'] && intval($cell['R']) > && intval($cell['R']) < 90 && isset($cell['va']) && $cell['va'] != 'B') {
  20301.                         $cell['va'] = 'B';
  20302.                     }
  20303.                     if (!isset($cell['va']) || $cell['va'] == 'M') {
  20304.                         $this->+= ($h $cell['mih']) / 2;
  20305.                     } elseif (isset($cell['va']) && $cell['va'] == 'B') {
  20306.                         $this->+= $h $cell['mih'];
  20307.                     }
  20308.                     // NESTED CONTENT
  20309.                     // TEXT (and nested tables)
  20310.                     $this->divwidth $w;
  20311.                     if (!empty($cell['textbuffer'])) {
  20312.                         $this->cellTextAlign $align;
  20313.                         $this->cellLineHeight $cell['cellLineHeight'];
  20314.                         $this->cellLineStackingStrategy $cell['cellLineStackingStrategy'];
  20315.                         $this->cellLineStackingShift $cell['cellLineStackingShift'];
  20316.                         if ($level == 1) {
  20317.                             if (isset($table['is_tfoot'][$i]) && $table['is_tfoot'][$i]) {
  20318.                                 if (preg_match('/{colsum([0-9]*)[_]*}/'$cell['textbuffer'][0][0], $m)) {
  20319.                                     $rep sprintf("%01." intval($m[1]) . "f"$this->colsums[$j]);
  20320.                                     $cell['textbuffer'][0][0] = preg_replace('/{colsum[0-9_]*}/'$rep$cell['textbuffer'][0][0]);
  20321.                                 }
  20322.                             } elseif (!isset($table['is_thead'][$i])) {
  20323.                                 if (isset($this->colsums[$j])) {
  20324.                                     $this->colsums[$j] += $this->toFloat($cell['textbuffer'][0][0]);
  20325.                                 } else {
  20326.                                     $this->colsums[$j] = $this->toFloat($cell['textbuffer'][0][0]);
  20327.                                 }
  20328.                             }
  20329.                         }
  20330.                         $opy $this->y;
  20331.                         // mPDF ITERATION
  20332.                         if ($this->iterationCounter) {
  20333.                             foreach ($cell['textbuffer'] as $k => $t) {
  20334.                                 if (preg_match('/{iteration ([a-zA-Z0-9_]+)}/'$t[0], $m)) {
  20335.                                     $vname '__' $m[1] . '_';
  20336.                                     if (!isset($this->$vname)) {
  20337.                                         $this->$vname 1;
  20338.                                     } else {
  20339.                                         $this->$vname++;
  20340.                                     }
  20341.                                     $cell['textbuffer'][$k][0] = preg_replace('/{iteration ' $m[1] . '}/'$this->$vname$cell['textbuffer'][$k][0]);
  20342.                                 }
  20343.                             }
  20344.                         }
  20345.                         if ($cell['R']) {
  20346.                             $cellPtSize $cell['textbuffer'][0][11] / $this->shrin_k;
  20347.                             if (!$cellPtSize) {
  20348.                                 $cellPtSize $this->default_font_size;
  20349.                             }
  20350.                             $cellFontHeight = ($cellPtSize Mpdf::SCALE);
  20351.                             $opx $this->x;
  20352.                             $angle intval($cell['R']);
  20353.                             // Only allow 45 to 89 degrees (when bottom-aligned) or exactly 90 or -90
  20354.                             if ($angle 90) {
  20355.                                 $angle 90;
  20356.                             } elseif ($angle && $angle 45) {
  20357.                                 $angle 45;
  20358.                             } elseif ($angle 0) {
  20359.                                 $angle = -90;
  20360.                             }
  20361.                             $offset = ((sin(deg2rad($angle))) * 0.37 $cellFontHeight);
  20362.                             if (isset($cell['a']) && $cell['a'] == 'R') {
  20363.                                 $this->+= ($w) + ($offset) - ($cellFontHeight 3) - ($cell['padding']['R'] + ($table['border_spacing_H'] / 2));
  20364.                             } elseif (!isset($cell['a']) || $cell['a'] == 'C') {
  20365.                                 $this->+= ($w 2) + ($offset);
  20366.                             } else {
  20367.                                 $this->+= ($offset) + ($cellFontHeight 3) + ($cell['padding']['L'] + ($table['border_spacing_H'] / 2));
  20368.                             }
  20369.                             $str '';
  20370.                             foreach ($cell['textbuffer'] as $t) {
  20371.                                 $str .= $t[0] . ' ';
  20372.                             }
  20373.                             $str rtrim($str);
  20374.                             if (!isset($cell['va']) || $cell['va'] == 'M') {
  20375.                                 $this->-= ($h $cell['mih']) / 2// Undo what was added earlier VERTICAL ALIGN
  20376.                                 if ($angle 0) {
  20377.                                     $this->+= (($h $cell['mih']) / 2) + $cell['padding']['T'] + ($cell['mih'] - ($cell['padding']['T'] + $cell['padding']['B']));
  20378.                                 } elseif ($angle 0) {
  20379.                                     $this->+= (($h $cell['mih']) / 2) + ($cell['padding']['T'] + ($table['border_spacing_V'] / 2));
  20380.                                 }
  20381.                             } elseif (isset($cell['va']) && $cell['va'] == 'B') {
  20382.                                 $this->-= $h $cell['mih']; // Undo what was added earlier VERTICAL ALIGN
  20383.                                 if ($angle 0) {
  20384.                                     $this->+= $h - ($cell['padding']['B'] + ($table['border_spacing_V'] / 2));
  20385.                                 } elseif ($angle 0) {
  20386.                                     $this->+= $h $cell['mih'] + ($cell['padding']['T'] + ($table['border_spacing_V'] / 2));
  20387.                                 }
  20388.                             } elseif (isset($cell['va']) && $cell['va'] == 'T') {
  20389.                                 if ($angle 0) {
  20390.                                     $this->+= $cell['mih'] - ($cell['padding']['B'] + ($table['border_spacing_V'] / 2));
  20391.                                 } elseif ($angle 0) {
  20392.                                     $this->+= ($cell['padding']['T'] + ($table['border_spacing_V'] / 2));
  20393.                                 }
  20394.                             }
  20395.                             $this->Rotate($angle$this->x$this->y);
  20396.                             $s_fs $this->FontSizePt;
  20397.                             $s_f $this->FontFamily;
  20398.                             $s_st $this->FontStyle;
  20399.                             if (!empty($cell['textbuffer'][0][3])) { // Font Color
  20400.                                 $cor $cell['textbuffer'][0][3];
  20401.                                 $this->SetTColor($cor);
  20402.                             }
  20403.                             $this->SetFont($cell['textbuffer'][0][4], $cell['textbuffer'][0][2], $cellPtSizetruetrue);
  20404.                             $this->magic_reverse_dir($str$this->directionality$cell['textbuffer'][0][18]);
  20405.                             $this->Text($this->x$this->y$str$cell['textbuffer'][0][18], $cell['textbuffer'][0][8]); // textvar
  20406.                             $this->Rotate(0);
  20407.                             $this->SetFont($s_f$s_st$s_fstruetrue);
  20408.                             $this->SetTColor(0);
  20409.                             $this->$opx;
  20410.                         } else {
  20411.                             if (!$this->simpleTables) {
  20412.                                 if ($bord_det) {
  20413.                                     $btlw $bord_det['L']['w'];
  20414.                                     $btrw $bord_det['R']['w'];
  20415.                                     $bttw $bord_det['T']['w'];
  20416.                                 } else {
  20417.                                     $btlw 0;
  20418.                                     $btrw 0;
  20419.                                     $bttw 0;
  20420.                                 }
  20421.                                 if ($table['borders_separate']) {
  20422.                                     $xadj $btlw $cell['padding']['L'] + ($table['border_spacing_H'] / 2);
  20423.                                     $wadj $btlw $btrw $cell['padding']['L'] + $cell['padding']['R'] + $table['border_spacing_H'];
  20424.                                     $yadj $bttw $cell['padding']['T'] + ($table['border_spacing_H'] / 2);
  20425.                                 } else {
  20426.                                     $xadj $btlw $cell['padding']['L'];
  20427.                                     $wadj = ($btlw $btrw) / $cell['padding']['L'] + $cell['padding']['R'];
  20428.                                     $yadj $bttw $cell['padding']['T'];
  20429.                                 }
  20430.                             } elseif ($this->simpleTables) {
  20431.                                 if ($table['borders_separate']) { // NB twice border width
  20432.                                     $xadj $table['simple']['border_details']['L']['w'] + $cell['padding']['L'] + ($table['border_spacing_H'] / 2);
  20433.                                     $wadj $table['simple']['border_details']['L']['w'] + $table['simple']['border_details']['R']['w'] + $cell['padding']['L'] + $cell['padding']['R'] + $table['border_spacing_H'];
  20434.                                     $yadj $table['simple']['border_details']['T']['w'] + $cell['padding']['T'] + ($table['border_spacing_H'] / 2);
  20435.                                 } else {
  20436.                                     $xadj $table['simple']['border_details']['L']['w'] / $cell['padding']['L'];
  20437.                                     $wadj = ($table['simple']['border_details']['L']['w'] + $table['simple']['border_details']['R']['w']) / $cell['padding']['L'] + $cell['padding']['R'];
  20438.                                     $yadj $table['simple']['border_details']['T']['w'] / $cell['padding']['T'];
  20439.                                 }
  20440.                             }
  20441.                             $this->decimal_offset 0;
  20442.                             if (substr($cell['a'], 01) == 'D') {
  20443.                                 if (isset($cell['colspan']) && $cell['colspan'] > 1) {
  20444.                                     $this->cellTextAlign $c['a'] = substr($cell['a'], 21);
  20445.                                 } else {
  20446.                                     $smax $table['decimal_align'][$j]['maxs0'];
  20447.                                     $d_content $table['decimal_align'][$j]['maxs0'] + $table['decimal_align'][$j]['maxs1'];
  20448.                                     $this->decimal_offset $smax;
  20449.                                     $extra = ($w $d_content $wadj);
  20450.                                     if ($extra 0) {
  20451.                                         if (substr($cell['a'], 21) == 'R') {
  20452.                                             $this->decimal_offset += $extra;
  20453.                                         } elseif (substr($cell['a'], 21) == 'C') {
  20454.                                             $this->decimal_offset += ($extra) / 2;
  20455.                                         }
  20456.                                     }
  20457.                                 }
  20458.                             }
  20459.                             $this->divwidth $w $wadj;
  20460.                             if ($this->divwidth == 0) {
  20461.                                 $this->divwidth 0.0001;
  20462.                             }
  20463.                             $this->+= $xadj;
  20464.                             $this->+= $yadj;
  20465.                             $this->printbuffer($cell['textbuffer'], ''truefalse$cell['direction']);
  20466.                         }
  20467.                         $this->$opy;
  20468.                     }
  20469.                     /* -- BACKGROUNDS -- */
  20470.                     if (!$this->ColActive) {
  20471.                         if (isset($table['trgradients'][$i]) && ($j == || $table['borders_separate'])) {
  20472.                             $g $this->gradient->parseBackgroundGradient($table['trgradients'][$i]);
  20473.                             if ($g) {
  20474.                                 $gx $x0;
  20475.                                 $gy $y;
  20476.                                 $gh $h;
  20477.                                 $gw $table['w'] - ($table['max_cell_border_width']['L'] / 2) - ($table['max_cell_border_width']['R'] / 2) - $table['margin']['L'] - $table['margin']['R'];
  20478.                                 if ($table['borders_separate']) {
  20479.                                     $gw -= ($table['padding']['L'] + $table['border_details']['L']['w'] + $table['padding']['R'] + $table['border_details']['R']['w'] + $table['border_spacing_H']);
  20480.                                     $clx $x + ($table['border_spacing_H'] / 2);
  20481.                                     $cly $y + ($table['border_spacing_V'] / 2);
  20482.                                     $clw $w $table['border_spacing_H'];
  20483.                                     $clh $h $table['border_spacing_V'];
  20484.                                     // Set clipping path
  20485.                                     $s $this->_setClippingPath($clx$cly$clw$clh); // mPDF 6
  20486.                                     $this->tableBackgrounds[$level 4][] = ['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];
  20487.                                 } else {
  20488.                                     $this->tableBackgrounds[$level 4][] = ['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' => ''];
  20489.                                 }
  20490.                             }
  20491.                         }
  20492.                         if (isset($table['trbackground-images'][$i]) && ($j == || $table['borders_separate'])) {
  20493.                             if (isset($table['trbackground-images'][$i]['gradient']) && preg_match('/(-moz-)*(repeating-)*(linear|radial)-gradient/'$table['trbackground-images'][$i]['gradient'])) {
  20494.                                 $g $this->gradient->parseMozGradient($table['trbackground-images'][$i]['gradient']);
  20495.                                 if ($g) {
  20496.                                     $gx $x0;
  20497.                                     $gy $y;
  20498.                                     $gh $h;
  20499.                                     $gw $table['w'] - ($table['max_cell_border_width']['L'] / 2) - ($table['max_cell_border_width']['R'] / 2) - $table['margin']['L'] - $table['margin']['R'];
  20500.                                     if ($table['borders_separate']) {
  20501.                                         $gw -= ($table['padding']['L'] + $table['border_details']['L']['w'] + $table['padding']['R'] + $table['border_details']['R']['w'] + $table['border_spacing_H']);
  20502.                                         $clx $x + ($table['border_spacing_H'] / 2);
  20503.                                         $cly $y + ($table['border_spacing_V'] / 2);
  20504.                                         $clw $w $table['border_spacing_H'];
  20505.                                         $clh $h $table['border_spacing_V'];
  20506.                                         // Set clipping path
  20507.                                         $s $this->_setClippingPath($clx$cly$clw$clh); // mPDF 6
  20508.                                         $this->tableBackgrounds[$level 4][] = ['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];
  20509.                                     } else {
  20510.                                         $this->tableBackgrounds[$level 4][] = ['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' => ''];
  20511.                                     }
  20512.                                 }
  20513.                             } else {
  20514.                                 $image_id $table['trbackground-images'][$i]['image_id'];
  20515.                                 $orig_w $table['trbackground-images'][$i]['orig_w'];
  20516.                                 $orig_h $table['trbackground-images'][$i]['orig_h'];
  20517.                                 $x_pos $table['trbackground-images'][$i]['x_pos'];
  20518.                                 $y_pos $table['trbackground-images'][$i]['y_pos'];
  20519.                                 $x_repeat $table['trbackground-images'][$i]['x_repeat'];
  20520.                                 $y_repeat $table['trbackground-images'][$i]['y_repeat'];
  20521.                                 $resize $table['trbackground-images'][$i]['resize'];
  20522.                                 $opacity $table['trbackground-images'][$i]['opacity'];
  20523.                                 $itype $table['trbackground-images'][$i]['itype'];
  20524.                                 $clippath '';
  20525.                                 $gx $x0;
  20526.                                 $gy $y;
  20527.                                 $gh $h;
  20528.                                 $gw $table['w'] - ($table['max_cell_border_width']['L'] / 2) - ($table['max_cell_border_width']['R'] / 2) - $table['margin']['L'] - $table['margin']['R'];
  20529.                                 if ($table['borders_separate']) {
  20530.                                     $gw -= ($table['padding']['L'] + $table['border_details']['L']['w'] + $table['padding']['R'] + $table['border_details']['R']['w'] + $table['border_spacing_H']);
  20531.                                     $clx $x + ($table['border_spacing_H'] / 2);
  20532.                                     $cly $y + ($table['border_spacing_V'] / 2);
  20533.                                     $clw $w $table['border_spacing_H'];
  20534.                                     $clh $h $table['border_spacing_V'];
  20535.                                     // Set clipping path
  20536.                                     $s $this->_setClippingPath($clx$cly$clw$clh); // mPDF 6
  20537.                                     $this->tableBackgrounds[$level 5][] = ['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];
  20538.                                 } else {
  20539.                                     $this->tableBackgrounds[$level 5][] = ['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];
  20540.                                 }
  20541.                             }
  20542.                         }
  20543.                     }
  20544.                     /* -- END BACKGROUNDS -- */
  20545.                     // TABLE BORDER - if separate
  20546.                     if (($table['borders_separate'] || ($this->simpleTables && !$table['simple']['border'])) && $table['border']) {
  20547.                         $halfspaceL $table['padding']['L'] + ($table['border_spacing_H'] / 2);
  20548.                         $halfspaceR $table['padding']['R'] + ($table['border_spacing_H'] / 2);
  20549.                         $halfspaceT $table['padding']['T'] + ($table['border_spacing_V'] / 2);
  20550.                         $halfspaceB $table['padding']['B'] + ($table['border_spacing_V'] / 2);
  20551.                         $tbx $x;
  20552.                         $tby $y;
  20553.                         $tbw $w;
  20554.                         $tbh $h;
  20555.                         $tab_bord 0;
  20556.                         $corner '';
  20557.                         if ($i == 0) {  // Top
  20558.                             $tby -= $halfspaceT + ($table['border_details']['T']['w'] / 2);
  20559.                             $tbh += $halfspaceT + ($table['border_details']['T']['w'] / 2);
  20560.                             $this->setBorder($tab_bordBorder::TOP);
  20561.                             $corner .= 'T';
  20562.                         }
  20563.                         if ($i == ($numrows 1) || (isset($cell['rowspan']) && ($i $cell['rowspan']) == $numrows)) { // Bottom
  20564.                             $tbh += $halfspaceB + ($table['border_details']['B']['w'] / 2);
  20565.                             $this->setBorder($tab_bordBorder::BOTTOM);
  20566.                             $corner .= 'B';
  20567.                         }
  20568.                         if ($j == 0) {  // Left
  20569.                             $tbx -= $halfspaceL + ($table['border_details']['L']['w'] / 2);
  20570.                             $tbw += $halfspaceL + ($table['border_details']['L']['w'] / 2);
  20571.                             $this->setBorder($tab_bordBorder::LEFT);
  20572.                             $corner .= 'L';
  20573.                         }
  20574.                         if ($j == ($numcols 1) || (isset($cell['colspan']) && ($j $cell['colspan']) == $numcols)) { // Right
  20575.                             $tbw += $halfspaceR + ($table['border_details']['R']['w'] / 2);
  20576.                             $this->setBorder($tab_bordBorder::RIGHT);
  20577.                             $corner .= 'R';
  20578.                         }
  20579.                         $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']);
  20580.                     }
  20581.                     unset($cell);
  20582.                     // Reset values
  20583.                     $this->Reset();
  20584.                 }//end of (if isset(cells)...)
  20585.             }// end of columns
  20586.             $newpagestarted false;
  20587.             $this->tabletheadjustfinished false;
  20588.             /* -- COLUMNS -- */
  20589.             if ($this->ColActive) {
  20590.                 if (!$this->table_keep_together && $i $numrows && $level == 1) {
  20591.                     $this->breakpoints[$this->CurrCol][] = $y $h;
  20592.                 } // mPDF 6
  20593.                 if (count($this->cellBorderBuffer)) {
  20594.                     $this->printcellbuffer();
  20595.                 }
  20596.             }
  20597.             /* -- END COLUMNS -- */
  20598.             if ($i == $numrows 1) {
  20599.                 $this->$y $h;
  20600.             } // last row jump (update this->y position)
  20601.             if ($this->table_rotate && $level == 1) {
  20602.                 $this->tbrot_h += $h;
  20603.             }
  20604.         } // end of rows
  20605.         if (count($this->cellBorderBuffer)) {
  20606.             $this->printcellbuffer();
  20607.         }
  20608.         if ($this->tableClipPath) {
  20609.             $this->writer->write("Q");
  20610.         }
  20611.         $this->tableClipPath '';
  20612.         // Advance down page by half width of bottom border
  20613.         if ($table['borders_separate']) {
  20614.             $this->+= $table['padding']['B'] + $table['border_details']['B']['w'] + $table['border_spacing_V'] / 2;
  20615.         } else {
  20616.             $this->+= $table['max_cell_border_width']['B'] / 2;
  20617.         }
  20618.         if ($table['borders_separate'] && $level == 1) {
  20619.             $this->tbrot_h += $table['margin']['B'] + $table['padding']['B'] + $table['border_details']['B']['w'] + $table['border_spacing_V'] / 2;
  20620.         } elseif ($level == 1) {
  20621.             $this->tbrot_h += $table['margin']['B'] + $table['max_cell_border_width']['B'] / 2;
  20622.         }
  20623.         $bx $x0;
  20624.         $by $y0;
  20625.         if ($table['borders_separate']) {
  20626.             $bx -= ($table['padding']['L'] + $table['border_details']['L']['w'] + $table['border_spacing_H'] / 2);
  20627.             if ($tablestartpageno != $this->page) { // IF broken across page
  20628.                 $by += $table['max_cell_border_width']['T'] / 2;
  20629.                 if (empty($tableheader)) {
  20630.                     $by -= ($table['border_spacing_V'] / 2);
  20631.                 }
  20632.             } elseif ($split && $startrow && empty($tableheader)) {
  20633.                 $by -= ($table['border_spacing_V'] / 2);
  20634.             } else {
  20635.                 $by -= ($table['padding']['T'] + $table['border_details']['T']['w'] + $table['border_spacing_V'] / 2);
  20636.             }
  20637.         } elseif ($tablestartpageno != $this->page && !empty($tableheader)) {
  20638.             $by += $maxbwtop 2;
  20639.         }
  20640.         $by -= $tableheaderadj;
  20641.         $bh $this->$by;
  20642.         if (!$table['borders_separate']) {
  20643.             $bh -= $table['max_cell_border_width']['B'] / 2;
  20644.         }
  20645.         if ($split) {
  20646.             $bw 0;
  20647.             $finalSpread true;
  20648.             for ($t $startcol$t $numcols$t++) {
  20649.                 if ($table['colPg'][$t] == $splitpg) {
  20650.                     $bw += $table['wc'][$t];
  20651.                 }
  20652.                 if ($table['colPg'][$t] > $splitpg) {
  20653.                     $finalSpread false;
  20654.                     break;
  20655.                 }
  20656.             }
  20657.             if ($startcol == 0) {
  20658.                 $firstSpread true;
  20659.             } else {
  20660.                 $firstSpread false;
  20661.             }
  20662.             if ($table['borders_separate']) {
  20663.                 $bw += $table['border_spacing_H'];
  20664.                 if ($firstSpread) {
  20665.                     $bw += $table['padding']['L'] + $table['border_details']['L']['w'];
  20666.                 } else {
  20667.                     $bx += ($table['padding']['L'] + $table['border_details']['L']['w']);
  20668.                 }
  20669.                 if ($finalSpread) {
  20670.                     $bw += $table['padding']['R'] + $table['border_details']['R']['w'];
  20671.                 }
  20672.             }
  20673.         } else {
  20674.             $bw $table['w'] - ($table['max_cell_border_width']['L'] / 2) - ($table['max_cell_border_width']['R'] / 2) - $table['margin']['L'] - $table['margin']['R'];
  20675.         }
  20676.         if (!$this->ColActive) {
  20677.             if (isset($table['bgcolor'][-1])) {
  20678.                 $color $this->colorConverter->convert($table['bgcolor'][-1], $this->PDFAXwarnings);
  20679.                 if ($color) {
  20680.                     $this->tableBackgrounds[$level 9][] = ['gradient' => false'x' => $bx'y' => $by'w' => $bw'h' => $bh'col' => $color];
  20681.                 }
  20682.             }
  20683.             /* -- BACKGROUNDS -- */
  20684.             if (isset($table['gradient'])) {
  20685.                 $g $this->gradient->parseBackgroundGradient($table['gradient']);
  20686.                 if ($g) {
  20687.                     $this->tableBackgrounds[$level 1][] = ['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' => ''];
  20688.                 }
  20689.             }
  20690.             if (isset($table['background-image'])) {
  20691.                 if (isset($table['background-image']['gradient']) && $table['background-image']['gradient'] && preg_match('/(-moz-)*(repeating-)*(linear|radial)-gradient/'$table['background-image']['gradient'])) {
  20692.                     $g $this->gradient->parseMozGradient($table['background-image']['gradient']);
  20693.                     if ($g) {
  20694.                         $this->tableBackgrounds[$level 1][] = ['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' => ''];
  20695.                     }
  20696.                 } else {
  20697.                     $image_id $table['background-image']['image_id'];
  20698.                     $orig_w $table['background-image']['orig_w'];
  20699.                     $orig_h $table['background-image']['orig_h'];
  20700.                     $x_pos $table['background-image']['x_pos'];
  20701.                     $y_pos $table['background-image']['y_pos'];
  20702.                     $x_repeat $table['background-image']['x_repeat'];
  20703.                     $y_repeat $table['background-image']['y_repeat'];
  20704.                     $resize $table['background-image']['resize'];
  20705.                     $opacity $table['background-image']['opacity'];
  20706.                     $itype $table['background-image']['itype'];
  20707.                     $this->tableBackgrounds[$level 2][] = ['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];
  20708.                 }
  20709.             }
  20710.             /* -- END BACKGROUNDS -- */
  20711.         }
  20712.         if ($this->tableBackgrounds && $level == 1) {
  20713.             $s $this->PrintTableBackgrounds();
  20714.             if ($this->table_rotate && !$this->processingHeader && !$this->processingFooter) {
  20715.                 $this->tablebuffer preg_replace('/(___TABLE___BACKGROUNDS' $this->uniqstr ')/''\\1' "\n" $s "\n"$this->tablebuffer);
  20716.                 if ($level == 1) {
  20717.                     $this->tablebuffer preg_replace('/(___TABLE___BACKGROUNDS' $this->uniqstr ')/'" "$this->tablebuffer);
  20718.                 }
  20719.             } elseif ($this->bufferoutput) {
  20720.                 $this->headerbuffer preg_replace('/(___TABLE___BACKGROUNDS' $this->uniqstr ')/''\\1' "\n" $s "\n"$this->headerbuffer);
  20721.                 if ($level == 1) {
  20722.                     $this->headerbuffer preg_replace('/(___TABLE___BACKGROUNDS' $this->uniqstr ')/'" "$this->headerbuffer);
  20723.                 }
  20724.             } else {
  20725.                 $this->pages[$this->page] = preg_replace('/(___TABLE___BACKGROUNDS' $this->uniqstr ')/''\\1' "\n" $s "\n"$this->pages[$this->page]);
  20726.                 if ($level == 1) {
  20727.                     $this->pages[$this->page] = preg_replace('/(___TABLE___BACKGROUNDS' $this->uniqstr ')/'" "$this->pages[$this->page]);
  20728.                 }
  20729.             }
  20730.             $this->tableBackgrounds = [];
  20731.         }
  20732.         // TABLE BOTTOM MARGIN
  20733.         if ($table['margin']['B']) {
  20734.             if (!$this->table_rotate && $level == 1) {
  20735.                 $this->DivLn($table['margin']['B'], $this->blklvltrue);  // collapsible
  20736.             } else {
  20737.                 $this->+= ($table['margin']['B']);
  20738.             }
  20739.         }
  20740.         if ($this->ColActive && $level == 1) {
  20741.             $this->breakpoints[$this->CurrCol][] = $this->y;
  20742.         } // *COLUMNS*
  20743.         if ($split) {
  20744.             // Are there more columns to print on a next page?
  20745.             if ($lastCol $numcols 1) {
  20746.                 $splitpg++;
  20747.                 $startcol $lastCol 1;
  20748.                 return [false$startrow$startcol$splitpg$returny$y0];
  20749.             } else {
  20750.                 return [true000falsefalse];
  20751.             }
  20752.         }
  20753.     }
  20754.     // END OF FUNCTION _tableWrite()
  20755.     /////////////////////////END OF TABLE CODE//////////////////////////////////
  20756.     /* -- END TABLES -- */
  20757.     function _putextgstates()
  20758.     {
  20759.         for ($i 1$i <= count($this->extgstates); $i++) {
  20760.             $this->writer->object();
  20761.             $this->extgstates[$i]['n'] = $this->n;
  20762.             $this->writer->write('<</Type /ExtGState');
  20763.             foreach ($this->extgstates[$i]['parms'] as $k => $v) {
  20764.                 $this->writer->write('/' $k ' ' $v);
  20765.             }
  20766.             $this->writer->write('>>');
  20767.             $this->writer->write('endobj');
  20768.         }
  20769.     }
  20770.     function SetProtection($permissions = [], $user_pass ''$owner_pass null$length 40)
  20771.     {
  20772.         $this->encrypted $this->protection->setProtection($permissions$user_pass$owner_pass$length);
  20773.     }
  20774.     // =========================================
  20775.     // FROM class PDF_Bookmark
  20776.     function Bookmark($txt$level 0$y 0)
  20777.     {
  20778.         $txt $this->purify_utf8_text($txt);
  20779.         if ($this->text_input_as_HTML) {
  20780.             $txt $this->all_entities_to_utf8($txt);
  20781.         }
  20782.         if ($y == -1) {
  20783.             if (!$this->ColActive) {
  20784.                 $y $this->y;
  20785.             } else {
  20786.                 $y $this->y0;
  20787.             } // If columns are on - mark top of columns
  20788.         }
  20789.         // else y is used as set, or =0 i.e. top of page
  20790.         // DIRECTIONALITY RTL
  20791.         $bmo = ['t' => $txt'l' => $level'y' => $y'p' => $this->page];
  20792.         if ($this->keep_block_together) {
  20793.             // do nothing
  20794.         } elseif ($this->table_rotate) {
  20795.             $this->tbrot_BMoutlines[] = $bmo;
  20796.         } elseif ($this->kwt) {
  20797.             $this->kwt_BMoutlines[] = $bmo;
  20798.         } elseif ($this->ColActive) {
  20799.             $this->col_BMoutlines[] = $bmo;
  20800.         } else {
  20801.             $this->BMoutlines[] = $bmo;
  20802.         }
  20803.     }
  20804.     /**
  20805.      * Initiate, and Mark a place for the Table of Contents to be inserted
  20806.      */
  20807.     function TOC(
  20808.         $tocfont '',
  20809.         $tocfontsize 0,
  20810.         $tocindent 0,
  20811.         $resetpagenum '',
  20812.         $pagenumstyle '',
  20813.         $suppress '',
  20814.         $toc_orientation '',
  20815.         $TOCusePaging true,
  20816.         $TOCuseLinking false,
  20817.         $toc_id 0,
  20818.         $tocoutdent ''
  20819.     ) {
  20820.         $this->tableOfContents->TOC(
  20821.             $tocfont,
  20822.             $tocfontsize,
  20823.             $tocindent,
  20824.             $resetpagenum,
  20825.             $pagenumstyle,
  20826.             $suppress,
  20827.             $toc_orientation,
  20828.             $TOCusePaging,
  20829.             $TOCuseLinking,
  20830.             $toc_id,
  20831.             $tocoutdent
  20832.         );
  20833.     }
  20834.     function TOCpagebreakByArray($a)
  20835.     {
  20836.         if (!is_array($a)) {
  20837.             $a = [];
  20838.         }
  20839.         $tocoutdent = (isset($a['tocoutdent']) ? $a['tocoutdent'] : (isset($a['outdent']) ? $a['outdent'] : ''));
  20840.         $TOCusePaging = (isset($a['TOCusePaging']) ? $a['TOCusePaging'] : (isset($a['paging']) ? $a['paging'] : true));
  20841.         $TOCuseLinking = (isset($a['TOCuseLinking']) ? $a['TOCuseLinking'] : (isset($a['links']) ? $a['links'] : ''));
  20842.         $toc_orientation = (isset($a['toc_orientation']) ? $a['toc_orientation'] : (isset($a['toc-orientation']) ? $a['toc-orientation'] : ''));
  20843.         $toc_mgl = (isset($a['toc_mgl']) ? $a['toc_mgl'] : (isset($a['toc-margin-left']) ? $a['toc-margin-left'] : ''));
  20844.         $toc_mgr = (isset($a['toc_mgr']) ? $a['toc_mgr'] : (isset($a['toc-margin-right']) ? $a['toc-margin-right'] : ''));
  20845.         $toc_mgt = (isset($a['toc_mgt']) ? $a['toc_mgt'] : (isset($a['toc-margin-top']) ? $a['toc-margin-top'] : ''));
  20846.         $toc_mgb = (isset($a['toc_mgb']) ? $a['toc_mgb'] : (isset($a['toc-margin-bottom']) ? $a['toc-margin-bottom'] : ''));
  20847.         $toc_mgh = (isset($a['toc_mgh']) ? $a['toc_mgh'] : (isset($a['toc-margin-header']) ? $a['toc-margin-header'] : ''));
  20848.         $toc_mgf = (isset($a['toc_mgf']) ? $a['toc_mgf'] : (isset($a['toc-margin-footer']) ? $a['toc-margin-footer'] : ''));
  20849.         $toc_ohname = (isset($a['toc_ohname']) ? $a['toc_ohname'] : (isset($a['toc-odd-header-name']) ? $a['toc-odd-header-name'] : ''));
  20850.         $toc_ehname = (isset($a['toc_ehname']) ? $a['toc_ehname'] : (isset($a['toc-even-header-name']) ? $a['toc-even-header-name'] : ''));
  20851.         $toc_ofname = (isset($a['toc_ofname']) ? $a['toc_ofname'] : (isset($a['toc-odd-footer-name']) ? $a['toc-odd-footer-name'] : ''));
  20852.         $toc_efname = (isset($a['toc_efname']) ? $a['toc_efname'] : (isset($a['toc-even-footer-name']) ? $a['toc-even-footer-name'] : ''));
  20853.         $toc_ohvalue = (isset($a['toc_ohvalue']) ? $a['toc_ohvalue'] : (isset($a['toc-odd-header-value']) ? $a['toc-odd-header-value'] : 0));
  20854.         $toc_ehvalue = (isset($a['toc_ehvalue']) ? $a['toc_ehvalue'] : (isset($a['toc-even-header-value']) ? $a['toc-even-header-value'] : 0));
  20855.         $toc_ofvalue = (isset($a['toc_ofvalue']) ? $a['toc_ofvalue'] : (isset($a['toc-odd-footer-value']) ? $a['toc-odd-footer-value'] : 0));
  20856.         $toc_efvalue = (isset($a['toc_efvalue']) ? $a['toc_efvalue'] : (isset($a['toc-even-footer-value']) ? $a['toc-even-footer-value'] : 0));
  20857.         $toc_preHTML = (isset($a['toc_preHTML']) ? $a['toc_preHTML'] : (isset($a['toc-preHTML']) ? $a['toc-preHTML'] : ''));
  20858.         $toc_postHTML = (isset($a['toc_postHTML']) ? $a['toc_postHTML'] : (isset($a['toc-postHTML']) ? $a['toc-postHTML'] : ''));
  20859.         $toc_bookmarkText = (isset($a['toc_bookmarkText']) ? $a['toc_bookmarkText'] : (isset($a['toc-bookmarkText']) ? $a['toc-bookmarkText'] : ''));
  20860.         $resetpagenum = (isset($a['resetpagenum']) ? $a['resetpagenum'] : '');
  20861.         $pagenumstyle = (isset($a['pagenumstyle']) ? $a['pagenumstyle'] : '');
  20862.         $suppress = (isset($a['suppress']) ? $a['suppress'] : '');
  20863.         $orientation = (isset($a['orientation']) ? $a['orientation'] : '');
  20864.         $mgl = (isset($a['mgl']) ? $a['mgl'] : (isset($a['margin-left']) ? $a['margin-left'] : ''));
  20865.         $mgr = (isset($a['mgr']) ? $a['mgr'] : (isset($a['margin-right']) ? $a['margin-right'] : ''));
  20866.         $mgt = (isset($a['mgt']) ? $a['mgt'] : (isset($a['margin-top']) ? $a['margin-top'] : ''));
  20867.         $mgb = (isset($a['mgb']) ? $a['mgb'] : (isset($a['margin-bottom']) ? $a['margin-bottom'] : ''));
  20868.         $mgh = (isset($a['mgh']) ? $a['mgh'] : (isset($a['margin-header']) ? $a['margin-header'] : ''));
  20869.         $mgf = (isset($a['mgf']) ? $a['mgf'] : (isset($a['margin-footer']) ? $a['margin-footer'] : ''));
  20870.         $ohname = (isset($a['ohname']) ? $a['ohname'] : (isset($a['odd-header-name']) ? $a['odd-header-name'] : ''));
  20871.         $ehname = (isset($a['ehname']) ? $a['ehname'] : (isset($a['even-header-name']) ? $a['even-header-name'] : ''));
  20872.         $ofname = (isset($a['ofname']) ? $a['ofname'] : (isset($a['odd-footer-name']) ? $a['odd-footer-name'] : ''));
  20873.         $efname = (isset($a['efname']) ? $a['efname'] : (isset($a['even-footer-name']) ? $a['even-footer-name'] : ''));
  20874.         $ohvalue = (isset($a['ohvalue']) ? $a['ohvalue'] : (isset($a['odd-header-value']) ? $a['odd-header-value'] : 0));
  20875.         $ehvalue = (isset($a['ehvalue']) ? $a['ehvalue'] : (isset($a['even-header-value']) ? $a['even-header-value'] : 0));
  20876.         $ofvalue = (isset($a['ofvalue']) ? $a['ofvalue'] : (isset($a['odd-footer-value']) ? $a['odd-footer-value'] : 0));
  20877.         $efvalue = (isset($a['efvalue']) ? $a['efvalue'] : (isset($a['even-footer-value']) ? $a['even-footer-value'] : 0));
  20878.         $toc_id = (isset($a['toc_id']) ? $a['toc_id'] : (isset($a['name']) ? $a['name'] : 0));
  20879.         $pagesel = (isset($a['pagesel']) ? $a['pagesel'] : (isset($a['pageselector']) ? $a['pageselector'] : ''));
  20880.         $toc_pagesel = (isset($a['toc_pagesel']) ? $a['toc_pagesel'] : (isset($a['toc-pageselector']) ? $a['toc-pageselector'] : ''));
  20881.         $sheetsize = (isset($a['sheetsize']) ? $a['sheetsize'] : (isset($a['sheet-size']) ? $a['sheet-size'] : ''));
  20882.         $toc_sheetsize = (isset($a['toc_sheetsize']) ? $a['toc_sheetsize'] : (isset($a['toc-sheet-size']) ? $a['toc-sheet-size'] : ''));
  20883.         $this->TOCpagebreak(''''''$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);
  20884.     }
  20885.     function TOCpagebreak($tocfont ''$tocfontsize ''$tocindent ''$TOCusePaging true$TOCuseLinking ''$toc_orientation ''$toc_mgl ''$toc_mgr ''$toc_mgt ''$toc_mgb ''$toc_mgh ''$toc_mgf ''$toc_ohname ''$toc_ehname ''$toc_ofname ''$toc_efname ''$toc_ohvalue 0$toc_ehvalue 0$toc_ofvalue 0$toc_efvalue 0$toc_preHTML ''$toc_postHTML ''$toc_bookmarkText ''$resetpagenum ''$pagenumstyle ''$suppress ''$orientation ''$mgl ''$mgr ''$mgt ''$mgb ''$mgh ''$mgf ''$ohname ''$ehname ''$ofname ''$efname ''$ohvalue 0$ehvalue 0$ofvalue 0$efvalue 0$toc_id 0$pagesel ''$toc_pagesel ''$sheetsize ''$toc_sheetsize ''$tocoutdent '')
  20886.     {
  20887.         // Start a new page
  20888.         if ($this->state == 0) {
  20889.             $this->AddPage();
  20890.         }
  20891.         if ($this->== $this->tMargin && (!$this->mirrorMargins || ($this->mirrorMargins && $this->page == 1))) {
  20892.             // Don't add a page
  20893.             if ($this->page == && count($this->PageNumSubstitutions) == 0) {
  20894.                 if (!$suppress) {
  20895.                     $suppress 'off';
  20896.                 }
  20897.                 // $this->PageNumSubstitutions[] = array('from'=>1, 'reset'=> $resetpagenum, 'type'=>$pagenumstyle, 'suppress'=> $suppress);
  20898.             }
  20899.             $this->PageNumSubstitutions[] = ['from' => $this->page'reset' => $resetpagenum'type' => $pagenumstyle'suppress' => $suppress];
  20900.         } else {
  20901.             $this->AddPage($orientation'NEXT-ODD'$resetpagenum$pagenumstyle$suppress$mgl$mgr$mgt$mgb$mgh$mgf$ohname$ehname$ofname$efname$ohvalue$ehvalue$ofvalue$efvalue$pagesel$sheetsize);
  20902.         }
  20903.         $this->tableOfContents->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);
  20904.     }
  20905.     function TOC_Entry($txt$level 0$toc_id 0)
  20906.     {
  20907.         if ($this->ColActive) {
  20908.             $ily $this->y0;
  20909.         } else {
  20910.             $ily $this->y;
  20911.         } // use top of columns
  20912.         $linkn $this->AddLink();
  20913.         $uid '__mpdfinternallink_' $linkn;
  20914.         if ($this->table_rotate) {
  20915.             $this->internallink[$uid] = ["Y" => $ily"PAGE" => $this->page"tbrot" => true];
  20916.         } elseif ($this->kwt) {
  20917.             $this->internallink[$uid] = ["Y" => $ily"PAGE" => $this->page"kwt" => true];
  20918.         } elseif ($this->ColActive) {
  20919.             $this->internallink[$uid] = ["Y" => $ily"PAGE" => $this->page"col" => $this->CurrCol];
  20920.         } elseif (!$this->keep_block_together) {
  20921.             $this->internallink[$uid] = ["Y" => $ily"PAGE" => $this->page];
  20922.         }
  20923.         $this->internallink['#' $uid] = $linkn;
  20924.         $this->SetLink($linkn$ily$this->page);
  20925.         if (strtoupper($toc_id) == 'ALL') {
  20926.             $toc_id '_mpdf_all';
  20927.         } elseif (!$toc_id) {
  20928.             $toc_id 0;
  20929.         } else {
  20930.             $toc_id strtolower($toc_id);
  20931.         }
  20932.         $btoc = ['t' => $txt'l' => $level'p' => $this->page'link' => $linkn'toc_id' => $toc_id];
  20933.         if ($this->keep_block_together) {
  20934.             // do nothing
  20935.         /* -- TABLES -- */ elseif ($this->table_rotate) {
  20936.             $this->tbrot_toc[] = $btoc;
  20937.         } elseif ($this->kwt) {
  20938.             $this->kwt_toc[] = $btoc;
  20939.         } /* -- END TABLES -- */ elseif ($this->ColActive) {  // *COLUMNS*
  20940.             $this->col_toc[] = $btoc// *COLUMNS*
  20941.         // *COLUMNS*
  20942.         else {
  20943.             $this->tableOfContents->_toc[] = $btoc;
  20944.         }
  20945.     }
  20946.     /* -- END TOC -- */
  20947.     // ======================================================
  20948.     function MovePages($target_page$start_page$end_page = -1)
  20949.     {
  20950.         // move a page/pages EARLIER in the document
  20951.         if ($end_page 1) {
  20952.             $end_page $start_page;
  20953.         }
  20954.         $n_toc $end_page $start_page 1;
  20955.         // Set/Update PageNumSubstitutions changes before moving anything
  20956.         if (count($this->PageNumSubstitutions)) {
  20957.             $tp_present false;
  20958.             $sp_present false;
  20959.             $ep_present false;
  20960.             foreach ($this->PageNumSubstitutions as $k => $v) {
  20961.                 if ($this->PageNumSubstitutions[$k]['from'] == $target_page) {
  20962.                     $tp_present true;
  20963.                     if ($this->PageNumSubstitutions[$k]['suppress'] != 'on' && $this->PageNumSubstitutions[$k]['suppress'] != 1) {
  20964.                         $this->PageNumSubstitutions[$k]['suppress'] = 'off';
  20965.                     }
  20966.                 }
  20967.                 if ($this->PageNumSubstitutions[$k]['from'] == $start_page) {
  20968.                     $sp_present true;
  20969.                     if ($this->PageNumSubstitutions[$k]['suppress'] != 'on' && $this->PageNumSubstitutions[$k]['suppress'] != 1) {
  20970.                         $this->PageNumSubstitutions[$k]['suppress'] = 'off';
  20971.                     }
  20972.                 }
  20973.                 if ($this->PageNumSubstitutions[$k]['from'] == ($end_page 1)) {
  20974.                     $ep_present true;
  20975.                     if ($this->PageNumSubstitutions[$k]['suppress'] != 'on' && $this->PageNumSubstitutions[$k]['suppress'] != 1) {
  20976.                         $this->PageNumSubstitutions[$k]['suppress'] = 'off';
  20977.                     }
  20978.                 }
  20979.             }
  20980.             if (!$tp_present) {
  20981.                 list($tp_type$tp_suppress$tp_reset) = $this->docPageSettings($target_page);
  20982.             }
  20983.             if (!$sp_present) {
  20984.                 list($sp_type$sp_suppress$sp_reset) = $this->docPageSettings($start_page);
  20985.             }
  20986.             if (!$ep_present) {
  20987.                 list($ep_type$ep_suppress$ep_reset) = $this->docPageSettings($start_page 1);
  20988.             }
  20989.         }
  20990.         $last = [];
  20991.         // store pages
  20992.         for ($i $start_page$i <= $end_page$i++) {
  20993.             $last[] = $this->pages[$i];
  20994.         }
  20995.         // move pages
  20996.         for ($i $start_page 1$i >= ($target_page); $i--) {
  20997.             $this->pages[$i $n_toc] = $this->pages[$i];
  20998.         }
  20999.         // Put toc pages at insert point
  21000.         for ($i 0$i $n_toc$i++) {
  21001.             $this->pages[$target_page $i] = $last[$i];
  21002.         }
  21003.         /* -- BOOKMARKS -- */
  21004.         // Update Bookmarks
  21005.         foreach ($this->BMoutlines as $i => $o) {
  21006.             if ($o['p'] >= $target_page) {
  21007.                 $this->BMoutlines[$i]['p'] += $n_toc;
  21008.             }
  21009.         }
  21010.         /* -- END BOOKMARKS -- */
  21011.         // Update Page Links
  21012.         if (count($this->PageLinks)) {
  21013.             $newarr = [];
  21014.             foreach ($this->PageLinks as $i => $o) {
  21015.                 foreach ($this->PageLinks[$i] as $key => $pl) {
  21016.                     if (strpos($pl[4], '@') === 0) {
  21017.                         $p substr($pl[4], 1);
  21018.                         if ($p >= $start_page && $p <= $end_page) {
  21019.                             $this->PageLinks[$i][$key][4] = '@' . ($p + ($target_page $start_page));
  21020.                         } elseif ($p >= $target_page && $p $start_page) {
  21021.                             $this->PageLinks[$i][$key][4] = '@' . ($p $n_toc);
  21022.                         }
  21023.                     }
  21024.                 }
  21025.                 if ($i >= $start_page && $i <= $end_page) {
  21026.                     $newarr[($i + ($target_page $start_page))] = $this->PageLinks[$i];
  21027.                 } elseif ($i >= $target_page && $i $start_page) {
  21028.                     $newarr[($i $n_toc)] = $this->PageLinks[$i];
  21029.                 } else {
  21030.                     $newarr[$i] = $this->PageLinks[$i];
  21031.                 }
  21032.             }
  21033.             $this->PageLinks $newarr;
  21034.         }
  21035.         // OrientationChanges
  21036.         if (count($this->OrientationChanges)) {
  21037.             $newarr = [];
  21038.             foreach ($this->OrientationChanges as $p => $v) {
  21039.                 if ($p >= $start_page && $p <= $end_page) {
  21040.                     $newarr[($p + ($target_page $start_page))] = $this->OrientationChanges[$p];
  21041.                 } elseif ($p >= $target_page && $p $start_page) {
  21042.                     $newarr[$p $n_toc] = $this->OrientationChanges[$p];
  21043.                 } else {
  21044.                     $newarr[$p] = $this->OrientationChanges[$p];
  21045.                 }
  21046.             }
  21047.             ksort($newarr);
  21048.             $this->OrientationChanges $newarr;
  21049.         }
  21050.         // Page Dimensions
  21051.         if (count($this->pageDim)) {
  21052.             $newarr = [];
  21053.             foreach ($this->pageDim as $p => $v) {
  21054.                 if ($p >= $start_page && $p <= $end_page) {
  21055.                     $newarr[($p + ($target_page $start_page))] = $this->pageDim[$p];
  21056.                 } elseif ($p >= $target_page && $p $start_page) {
  21057.                     $newarr[$p $n_toc] = $this->pageDim[$p];
  21058.                 } else {
  21059.                     $newarr[$p] = $this->pageDim[$p];
  21060.                 }
  21061.             }
  21062.             ksort($newarr);
  21063.             $this->pageDim $newarr;
  21064.         }
  21065.         // HTML Headers & Footers
  21066.         if (count($this->saveHTMLHeader)) {
  21067.             $newarr = [];
  21068.             foreach ($this->saveHTMLHeader as $p => $v) {
  21069.                 if ($p >= $start_page && $p <= $end_page) {
  21070.                     $newarr[($p + ($target_page $start_page))] = $this->saveHTMLHeader[$p];
  21071.                 } elseif ($p >= $target_page && $p $start_page) {
  21072.                     $newarr[$p $n_toc] = $this->saveHTMLHeader[$p];
  21073.                 } else {
  21074.                     $newarr[$p] = $this->saveHTMLHeader[$p];
  21075.                 }
  21076.             }
  21077.             ksort($newarr);
  21078.             $this->saveHTMLHeader $newarr;
  21079.         }
  21080.         if (count($this->saveHTMLFooter)) {
  21081.             $newarr = [];
  21082.             foreach ($this->saveHTMLFooter as $p => $v) {
  21083.                 if ($p >= $start_page && $p <= $end_page) {
  21084.                     $newarr[($p + ($target_page $start_page))] = $this->saveHTMLFooter[$p];
  21085.                 } elseif ($p >= $target_page && $p $start_page) {
  21086.                     $newarr[$p $n_toc] = $this->saveHTMLFooter[$p];
  21087.                 } else {
  21088.                     $newarr[$p] = $this->saveHTMLFooter[$p];
  21089.                 }
  21090.             }
  21091.             ksort($newarr);
  21092.             $this->saveHTMLFooter $newarr;
  21093.         }
  21094.         // Update Internal Links
  21095.         if (count($this->internallink)) {
  21096.             foreach ($this->internallink as $key => $o) {
  21097.                 if (is_array($o) && $o['PAGE'] >= $start_page && $o['PAGE'] <= $end_page) {
  21098.                     $this->internallink[$key]['PAGE'] += ($target_page $start_page);
  21099.                 } elseif (is_array($o) && $o['PAGE'] >= $target_page && $o['PAGE'] < $start_page) {
  21100.                     $this->internallink[$key]['PAGE'] += $n_toc;
  21101.                 }
  21102.             }
  21103.         }
  21104.         // Update Links
  21105.         if (count($this->links)) {
  21106.             foreach ($this->links as $key => $o) {
  21107.                 if ($o[0] >= $start_page && $o[0] <= $end_page) {
  21108.                     $this->links[$key][0] += ($target_page $start_page);
  21109.                 }
  21110.                 if ($o[0] >= $target_page && $o[0] < $start_page) {
  21111.                     $this->links[$key][0] += $n_toc;
  21112.                 }
  21113.             }
  21114.         }
  21115.         // Update Form fields
  21116.         if (count($this->form->forms)) {
  21117.             foreach ($this->form->forms as $key => $f) {
  21118.                 if ($f['page'] >= $start_page && $f['page'] <= $end_page) {
  21119.                     $this->form->forms[$key]['page'] += ($target_page $start_page);
  21120.                 }
  21121.                 if ($f['page'] >= $target_page && $f['page'] < $start_page) {
  21122.                     $this->form->forms[$key]['page'] += $n_toc;
  21123.                 }
  21124.             }
  21125.         }
  21126.         /* -- ANNOTATIONS -- */
  21127.         // Update Annotations
  21128.         if (count($this->PageAnnots)) {
  21129.             $newarr = [];
  21130.             foreach ($this->PageAnnots as $p => $anno) {
  21131.                 if ($p >= $start_page && $p <= $end_page) {
  21132.                     $np $p + ($target_page $start_page);
  21133.                     foreach ($anno as $o) {
  21134.                         $newarr[$np][] = $o;
  21135.                     }
  21136.                 } elseif ($p >= $target_page && $p $start_page) {
  21137.                     $np $p $n_toc;
  21138.                     foreach ($anno as $o) {
  21139.                         $newarr[$np][] = $o;
  21140.                     }
  21141.                 } else {
  21142.                     $newarr[$p] = $this->PageAnnots[$p];
  21143.                 }
  21144.             }
  21145.             $this->PageAnnots $newarr;
  21146.             unset($newarr);
  21147.         }
  21148.         /* -- END ANNOTATIONS -- */
  21149.         // Update TOC pages
  21150.         if (count($this->tableOfContents->_toc)) {
  21151.             foreach ($this->tableOfContents->_toc as $key => $t) {
  21152.                 if ($t['p'] >= $start_page && $t['p'] <= $end_page) {
  21153.                     $this->tableOfContents->_toc[$key]['p'] += ($target_page $start_page);
  21154.                 }
  21155.                 if ($t['p'] >= $target_page && $t['p'] < $start_page) {
  21156.                     $this->tableOfContents->_toc[$key]['p'] += $n_toc;
  21157.                 }
  21158.             }
  21159.         }
  21160.         // Update PageNumSubstitutions
  21161.         if (count($this->PageNumSubstitutions)) {
  21162.             $newarr = [];
  21163.             foreach ($this->PageNumSubstitutions as $k => $v) {
  21164.                 if ($this->PageNumSubstitutions[$k]['from'] >= $start_page && $this->PageNumSubstitutions[$k]['from'] <= $end_page) {
  21165.                     $this->PageNumSubstitutions[$k]['from'] += ($target_page $start_page);
  21166.                     $newarr[$this->PageNumSubstitutions[$k]['from']] = $this->PageNumSubstitutions[$k];
  21167.                 } elseif ($this->PageNumSubstitutions[$k]['from'] >= $target_page && $this->PageNumSubstitutions[$k]['from'] < $start_page) {
  21168.                     $this->PageNumSubstitutions[$k]['from'] += $n_toc;
  21169.                     $newarr[$this->PageNumSubstitutions[$k]['from']] = $this->PageNumSubstitutions[$k];
  21170.                 } else {
  21171.                     $newarr[$this->PageNumSubstitutions[$k]['from']] = $this->PageNumSubstitutions[$k];
  21172.                 }
  21173.             }
  21174.             if (!$sp_present) {
  21175.                 $newarr[$target_page] = ['from' => $target_page'suppress' => $sp_suppress'reset' => $sp_reset'type' => $sp_type];
  21176.             }
  21177.             if (!$tp_present) {
  21178.                 $newarr[($target_page $n_toc)] = ['from' => ($target_page $n_toc), 'suppress' => $tp_suppress'reset' => $tp_reset'type' => $tp_type];
  21179.             }
  21180.             if (!$ep_present && $end_page count($this->pages)) {
  21181.                 $newarr[($end_page 1)] = ['from' => ($end_page 1), 'suppress' => $ep_suppress'reset' => $ep_reset'type' => $ep_type];
  21182.             }
  21183.             ksort($newarr);
  21184.             $this->PageNumSubstitutions = [];
  21185.             foreach ($newarr as $v) {
  21186.                 $this->PageNumSubstitutions[] = $v;
  21187.             }
  21188.         }
  21189.     }
  21190.     function DeletePages($start_page$end_page = -1)
  21191.     {
  21192.         // move a page/pages EARLIER in the document
  21193.         if ($end_page 1) {
  21194.             $end_page $start_page;
  21195.         }
  21196.         $n_tod $end_page $start_page 1;
  21197.         $last_page count($this->pages);
  21198.         $n_atend $last_page $end_page 1;
  21199.         // move pages
  21200.         for ($i 0$i $n_atend$i++) {
  21201.             $this->pages[$start_page $i] = $this->pages[$end_page $i];
  21202.         }
  21203.         // delete pages
  21204.         for ($i 0$i $n_tod$i++) {
  21205.             unset($this->pages[$last_page $i]);
  21206.         }
  21207.         /* -- BOOKMARKS -- */
  21208.         // Update Bookmarks
  21209.         foreach ($this->BMoutlines as $i => $o) {
  21210.             if ($o['p'] >= $end_page) {
  21211.                 $this->BMoutlines[$i]['p'] -= $n_tod;
  21212.             } elseif ($p $start_page) {
  21213.                 unset($this->BMoutlines[$i]);
  21214.             }
  21215.         }
  21216.         /* -- END BOOKMARKS -- */
  21217.         // Update Page Links
  21218.         if (count($this->PageLinks)) {
  21219.             $newarr = [];
  21220.             foreach ($this->PageLinks as $i => $o) {
  21221.                 foreach ($this->PageLinks[$i] as $key => $pl) {
  21222.                     if (strpos($pl[4], '@') === 0) {
  21223.                         $p substr($pl[4], 1);
  21224.                         if ($p $end_page) {
  21225.                             $this->PageLinks[$i][$key][4] = '@' . ($p $n_tod);
  21226.                         } elseif ($p $start_page) {
  21227.                             unset($this->PageLinks[$i][$key]);
  21228.                         }
  21229.                     }
  21230.                 }
  21231.                 if ($i $end_page) {
  21232.                     $newarr[($i $n_tod)] = $this->PageLinks[$i];
  21233.                 } elseif ($p $start_page) {
  21234.                     $newarr[$i] = $this->PageLinks[$i];
  21235.                 }
  21236.             }
  21237.             $this->PageLinks $newarr;
  21238.         }
  21239.         // OrientationChanges
  21240.         if (count($this->OrientationChanges)) {
  21241.             $newarr = [];
  21242.             foreach ($this->OrientationChanges as $p => $v) {
  21243.                 if ($p $end_page) {
  21244.                     $newarr[($p $t_tod)] = $this->OrientationChanges[$p];
  21245.                 } elseif ($p $start_page) {
  21246.                     $newarr[$p] = $this->OrientationChanges[$p];
  21247.                 }
  21248.             }
  21249.             ksort($newarr);
  21250.             $this->OrientationChanges $newarr;
  21251.         }
  21252.         // Page Dimensions
  21253.         if (count($this->pageDim)) {
  21254.             $newarr = [];
  21255.             foreach ($this->pageDim as $p => $v) {
  21256.                 if ($p $end_page) {
  21257.                     $newarr[($p $n_tod)] = $this->pageDim[$p];
  21258.                 } elseif ($p $start_page) {
  21259.                     $newarr[$p] = $this->pageDim[$p];
  21260.                 }
  21261.             }
  21262.             ksort($newarr);
  21263.             $this->pageDim $newarr;
  21264.         }
  21265.         // HTML Headers & Footers
  21266.         if (count($this->saveHTMLHeader)) {
  21267.             foreach ($this->saveHTMLHeader as $p => $v) {
  21268.                 if ($p $end_page) {
  21269.                     $newarr[($p $n_tod)] = $this->saveHTMLHeader[$p];
  21270.                 } // mPDF 5.7.3
  21271.                 elseif ($p $start_page) {
  21272.                     $newarr[$p] = $this->saveHTMLHeader[$p];
  21273.                 }
  21274.             }
  21275.             ksort($newarr);
  21276.             $this->saveHTMLHeader $newarr;
  21277.         }
  21278.         if (count($this->saveHTMLFooter)) {
  21279.             $newarr = [];
  21280.             foreach ($this->saveHTMLFooter as $p => $v) {
  21281.                 if ($p $end_page) {
  21282.                     $newarr[($p $n_tod)] = $this->saveHTMLFooter[$p];
  21283.                 } elseif ($p $start_page) {
  21284.                     $newarr[$p] = $this->saveHTMLFooter[$p];
  21285.                 }
  21286.             }
  21287.             ksort($newarr);
  21288.             $this->saveHTMLFooter $newarr;
  21289.         }
  21290.         // Update Internal Links
  21291.         foreach ($this->internallink as $key => $o) {
  21292.             if ($o['PAGE'] > $end_page) {
  21293.                 $this->internallink[$key]['PAGE'] -= $n_tod;
  21294.             } elseif ($o['PAGE'] < $start_page) {
  21295.                 unset($this->internallink[$key]);
  21296.             }
  21297.         }
  21298.         // Update Links
  21299.         foreach ($this->links as $key => $o) {
  21300.             if ($o[0] > $end_page) {
  21301.                 $this->links[$key][0] -= $n_tod;
  21302.             } elseif ($o[0] < $start_page) {
  21303.                 unset($this->links[$key]);
  21304.             }
  21305.         }
  21306.         // Update Form fields
  21307.         foreach ($this->form->forms as $key => $f) {
  21308.             if ($f['page'] > $end_page) {
  21309.                 $this->form->forms[$key]['page'] -= $n_tod;
  21310.             } elseif ($f['page'] < $start_page) {
  21311.                 unset($this->form->forms[$key]);
  21312.             }
  21313.         }
  21314.         /* -- ANNOTATIONS -- */
  21315.         // Update Annotations
  21316.         if (count($this->PageAnnots)) {
  21317.             $newarr = [];
  21318.             foreach ($this->PageAnnots as $p => $anno) {
  21319.                 if ($p $end_page) {
  21320.                     foreach ($anno as $o) {
  21321.                         $newarr[($p $n_tod)][] = $o;
  21322.                     }
  21323.                 } elseif ($p $start_page) {
  21324.                     $newarr[$p] = $this->PageAnnots[$p];
  21325.                 }
  21326.             }
  21327.             ksort($newarr);
  21328.             $this->PageAnnots $newarr;
  21329.         }
  21330.         /* -- END ANNOTATIONS -- */
  21331.         // Update PageNumSubstitutions
  21332.         foreach ($this->PageNumSubstitutions as $k => $v) {
  21333.             if ($this->PageNumSubstitutions[$k]['from'] > $end_page) {
  21334.                 $this->PageNumSubstitutions[$k]['from'] -= $n_tod;
  21335.             } elseif ($this->PageNumSubstitutions[$k]['from'] < $start_page) {
  21336.                 unset($this->PageNumSubstitutions[$k]);
  21337.             }
  21338.         }
  21339.         unset($newarr);
  21340.         $this->page count($this->pages);
  21341.     }
  21342.     // ======================================================
  21343.         /* -- INDEX -- */
  21344.     // FROM class PDF_Ref == INDEX
  21345.     function IndexEntry($txt$xref '')
  21346.     {
  21347.         if ($xref) {
  21348.             $this->IndexEntrySee($txt$xref);
  21349.             return;
  21350.         }
  21351.         // Search the reference (AND Ref/PageNo) in the array
  21352.         $Present false;
  21353.         if ($this->keep_block_together) {
  21354.             // do nothing
  21355.         /* -- TABLES -- */ elseif ($this->kwt) {
  21356.             $size count($this->kwt_Reference);
  21357.             for ($i 0$i $size$i++) {
  21358.                 if (isset($this->kwt_Reference[$i]['t']) && $this->kwt_Reference[$i]['t'] == $txt) {
  21359.                     $Present true;
  21360.                     if ($this->page != $this->kwt_Reference[$i]['op']) {
  21361.                         $this->kwt_Reference[$i]['op'] = $this->page;
  21362.                     }
  21363.                 }
  21364.             }
  21365.             if (!$Present) { // If not found, add it
  21366.                 $this->kwt_Reference[] = ['t' => $txt'op' => $this->page];
  21367.             }
  21368.         } /* -- END TABLES -- */ else {
  21369.             $size count($this->Reference);
  21370.             for ($i 0$i $size$i++) {
  21371.                 if (isset($this->Reference[$i]['t']) && $this->Reference[$i]['t'] == $txt) {
  21372.                     $Present true;
  21373.                     if (!in_array($this->page$this->Reference[$i]['p'])) {
  21374.                         $this->Reference[$i]['p'][] = $this->page;
  21375.                     }
  21376.                 }
  21377.             }
  21378.             if (!$Present) { // If not found, add it
  21379.                 $this->Reference[] = ['t' => $txt'p' => [$this->page]];
  21380.             }
  21381.         }
  21382.     }
  21383.     // Added function to add a reference "Elephants. See Chickens"
  21384.     function IndexEntrySee($txta$txtb)
  21385.     {
  21386.         if ($this->directionality == 'rtl') { // *OTL*
  21387.             // ONLY DO THIS IF NOT IN TAGS
  21388.             if ($txta == strip_tags($txta)) {
  21389.                 $txta str_replace(':'' - '$txta); // *OTL*
  21390.             }
  21391.             if ($txtb == strip_tags($txtb)) {
  21392.                 $txtb str_replace(':'' - '$txtb); // *OTL*
  21393.             }
  21394.         } // *OTL*
  21395.         else { // *OTL*
  21396.             if ($txta == strip_tags($txta)) {
  21397.                 $txta str_replace(':'', '$txta);
  21398.             }
  21399.             if ($txtb == strip_tags($txtb)) {
  21400.                 $txtb str_replace(':'', '$txtb);
  21401.             }
  21402.         } // *OTL*
  21403.         $this->Reference[] = ['t' => $txta ' - see ' $txtb'p' => []];
  21404.     }
  21405.     private function filesInDir($directory)
  21406.     {
  21407.         $files = [];
  21408.         foreach ((new \DirectoryIterator($directory)) as $v) {
  21409.             if ($v->isDir() || $v->isDot()) {
  21410.                 continue;
  21411.             }
  21412.             $files[] = $v->getPathname();
  21413.         }
  21414.         return $files;
  21415.     }
  21416.     function InsertIndex($usedivletters 1$useLinking false$indexCollationLocale ''$indexCollationGroup '')
  21417.     {
  21418.         $size count($this->Reference);
  21419.         if ($size == 0) {
  21420.             return false;
  21421.         }
  21422.         // $spacer used after named entry
  21423.         // $sep  separates number [groups], $joiner joins numbers in range
  21424.         //  e.g. "elephant 73, 97-99"  =  elephant[$spacer]73[$sep]97[$joiner]99
  21425.         // $subEntrySeparator separates main and subentry (if $this->indexUseSubentries == false;) e.g.
  21426.         // Mammal:elephant => Mammal[$subEntrySeparator]elephant
  21427.         // $subEntryInset specifies what precedes a subentry (if $this->indexUseSubentries == true;) e.g.
  21428.         // Mammal:elephant => [$subEntryInset]elephant
  21429.         $spacer "\xc2\xa0 ";
  21430.         if ($this->directionality == 'rtl') {
  21431.             $sep '&#x060c; ';
  21432.             $joiner '-';
  21433.             $subEntrySeparator '&#x060c; ';
  21434.             $subEntryInset ' - ';
  21435.         } else {
  21436.             $sep ', ';
  21437.             $joiner '-';
  21438.             $subEntrySeparator ', ';
  21439.             $subEntryInset ' - ';
  21440.         }
  21441.         for ($i 0$i $size$i++) {
  21442.             $txt $this->Reference[$i]['t'];
  21443.             $txt strip_tags($txt); // mPDF 6
  21444.             $txt $this->purify_utf8($txt);
  21445.             $this->Reference[$i]['uf'] = $txt// Unformatted e.g. pure utf-8 encoded characters, no mark-up/tags
  21446.             // Used for ordering and collation
  21447.         }
  21448.         if ($usedivletters) {
  21449.             if ($indexCollationGroup && \in_array(strtolower($indexCollationGroup), array_map(function ($v) {
  21450.                     return strtolower(basename($v'.php'));
  21451.             }, $this->filesInDir(__DIR__ '/../data/collations/')))) {
  21452.                 $collation = require __DIR__ '/../data/collations/' $indexCollationGroup '.php';
  21453.             } else {
  21454.                 $collation = [];
  21455.             }
  21456.             for ($i 0$i $size$i++) {
  21457.                 if ($this->Reference[$i]['uf']) {
  21458.                     $l mb_substr($this->Reference[$i]['uf'], 01'UTF-8');
  21459.                     if (isset($indexCollationGroup) && $indexCollationGroup) {
  21460.                         $uni $this->UTF8StringToArray($l);
  21461.                         $ucode $uni[0];
  21462.                         if (isset($collation[$ucode])) {
  21463.                             $this->Reference[$i]['d'] = UtfString::code2utf($collation[$ucode]);
  21464.                         } else {
  21465.                             $this->Reference[$i]['d'] = mb_strtolower($l'UTF-8');
  21466.                         }
  21467.                     } else {
  21468.                         $this->Reference[$i]['d'] = mb_strtolower($l'UTF-8');
  21469.                     }
  21470.                 }
  21471.             }
  21472.         }
  21473.         // Alphabetic sort of the references
  21474.         $originalLocale setlocale(LC_COLLATE0);
  21475.         if ($indexCollationLocale) {
  21476.             setlocale(LC_COLLATE$indexCollationLocale);
  21477.         }
  21478.         usort($this->Reference, function ($a$b) {
  21479.             return strcoll(strtolower($a['uf']), strtolower($b['uf']));
  21480.         });
  21481.         if ($indexCollationLocale) {
  21482.             setlocale(LC_COLLATE$originalLocale);
  21483.         }
  21484.         $html '<div class="mpdf_index_main">';
  21485.         $lett '';
  21486.         $last_lett '';
  21487.         $mainentry '';
  21488.         for ($i 0$i $size$i++) {
  21489.             if ($this->Reference[$i]['t']) {
  21490.                 if ($usedivletters) {
  21491.                     $lett $this->Reference[$i]['d'];
  21492.                     if ($lett != $last_lett) {
  21493.                         $html .= '<div class="mpdf_index_letter">' $lett '</div>';
  21494.                     }
  21495.                 }
  21496.                 $txt $this->Reference[$i]['t'];
  21497.                 // Sub-entries e.g. Mammals:elephant
  21498.                 // But allow for tags e.g. <b>Mammal</b>:elephants
  21499.                 $a preg_split('/(<.*?>)/'$txt, -1PREG_SPLIT_DELIM_CAPTURE);
  21500.                 $txt '';
  21501.                 $marker false;
  21502.                 foreach ($a as $k => $e) {
  21503.                     if ($k == && !$marker) {
  21504.                         if (strpos($e':') !== false) { // == SubEntry
  21505.                             if ($this->indexUseSubentries) {
  21506.                                 // If the Main entry does not have any page numbers associated with it
  21507.                                 // create and insert an entry
  21508.                                 list($txtmain$sub) = preg_split('/[:]/'$e2);
  21509.                                 if (strip_tags($txt $txtmain) != $mainentry) {
  21510.                                     $html .= '<div class="mpdf_index_entry">' $txt $txtmain '</div>';
  21511.                                     $mainentry strip_tags($txt $txtmain);
  21512.                                 }
  21513.                                 $txt $subEntryInset;
  21514.                                 $e $sub// Only replace first one
  21515.                             } else {
  21516.                                 $e preg_replace('/[:]/'$subEntrySeparator$e1); // Only replace first one
  21517.                             }
  21518.                             $marker true// Don't replace any more once the subentry marker has been found
  21519.                         }
  21520.                     }
  21521.                     $txt .= $e;
  21522.                 }
  21523.                 if (!$marker) {
  21524.                     $mainentry strip_tags($txt);
  21525.                 }
  21526.                 $html .= '<div class="mpdf_index_entry">';
  21527.                 $html .= $txt;
  21528.                 $ppp $this->Reference[$i]['p']; // = array of page numbers to point to
  21529.                 if (count($ppp)) {
  21530.                     sort($ppp);
  21531.                     $newarr = [];
  21532.                     $range_start $ppp[0];
  21533.                     $range_end 0;
  21534.                     $html .= $spacer;
  21535.                     for ($zi 1$zi count($ppp); $zi++) {
  21536.                         if ($ppp[$zi] == ($ppp[($zi 1)] + 1)) {
  21537.                             $range_end $ppp[$zi];
  21538.                         } else {
  21539.                             if ($range_end) {
  21540.                                 if ($range_end == $range_start 1) {
  21541.                                     if ($useLinking) {
  21542.                                         $html .= '<a class="mpdf_index_link" href="@' $range_start '">';
  21543.                                     }
  21544.                                     $html .= $this->docPageNum($range_start);
  21545.                                     if ($useLinking) {
  21546.                                         $html .= '</a>';
  21547.                                     }
  21548.                                     $html .= $sep;
  21549.                                     if ($useLinking) {
  21550.                                         $html .= '<a class="mpdf_index_link" href="@' $ppp[$zi 1] . '">';
  21551.                                     }
  21552.                                     $html .= $this->docPageNum($ppp[$zi 1]);
  21553.                                     if ($useLinking) {
  21554.                                         $html .= '</a>';
  21555.                                     }
  21556.                                     $html .= $sep;
  21557.                                 }
  21558.                             } else {
  21559.                                 if ($useLinking) {
  21560.                                     $html .= '<a class="mpdf_index_link" href="@' $ppp[$zi 1] . '">';
  21561.                                 }
  21562.                                 $html .= $this->docPageNum($ppp[$zi 1]);
  21563.                                 if ($useLinking) {
  21564.                                     $html .= '</a>';
  21565.                                 }
  21566.                                 $html .= $sep;
  21567.                             }
  21568.                             $range_start $ppp[$zi];
  21569.                             $range_end 0;
  21570.                         }
  21571.                     }
  21572.                     if ($range_end) {
  21573.                         if ($useLinking) {
  21574.                             $html .= '<a class="mpdf_index_link" href="@' $range_start '">';
  21575.                         }
  21576.                         $html .= $this->docPageNum($range_start);
  21577.                         if ($range_end == $range_start 1) {
  21578.                             if ($useLinking) {
  21579.                                 $html .= '</a>';
  21580.                             }
  21581.                             $html .= $sep;
  21582.                             if ($useLinking) {
  21583.                                 $html .= '<a class="mpdf_index_link" href="@' $range_end '">';
  21584.                             }
  21585.                             $html .= $this->docPageNum($range_end);
  21586.                             if ($useLinking) {
  21587.                                 $html .= '</a>';
  21588.                             }
  21589.                         } else {
  21590.                             $html .= $joiner;
  21591.                             $html .= $this->docPageNum($range_end);
  21592.                             if ($useLinking) {
  21593.                                 $html .= '</a>';
  21594.                             }
  21595.                         }
  21596.                     } else {
  21597.                         if ($useLinking) {
  21598.                             $html .= '<a class="mpdf_index_link" href="@' $ppp[(count($ppp) - 1)] . '">';
  21599.                         }
  21600.                         $html .= $this->docPageNum($ppp[(count($ppp) - 1)]);
  21601.                         if ($useLinking) {
  21602.                             $html .= '</a>';
  21603.                         }
  21604.                     }
  21605.                 }
  21606.             }
  21607.             $html .= '</div>';
  21608.             $last_lett $lett;
  21609.         }
  21610.         $html .= '</div>';
  21611.         $save_fpb $this->fixedPosBlockSave;
  21612.         $this->WriteHTML($html);
  21613.         $this->fixedPosBlockSave $save_fpb;
  21614.         $this->breakpoints[$this->CurrCol][] = $this->y;  // *COLUMNS*
  21615.     }
  21616.     /* -- END INDEX -- */
  21617.     function AcceptPageBreak()
  21618.     {
  21619.         if (count($this->cellBorderBuffer)) {
  21620.             $this->printcellbuffer();
  21621.         } // *TABLES*
  21622.         /* -- COLUMNS -- */
  21623.         if ($this->ColActive == 1) {
  21624.             if ($this->CurrCol $this->NbCol 1) {
  21625.                 // Go to the next column
  21626.                 $this->CurrCol++;
  21627.                 $this->SetCol($this->CurrCol);
  21628.                 $this->$this->y0;
  21629.                 $this->ChangeColumn 1// Number (and direction) of columns changed +1, +2, -2 etc.
  21630.                 // DIRECTIONALITY RTL
  21631.                 if ($this->directionality == 'rtl') {
  21632.                     $this->ChangeColumn = -($this->ChangeColumn);
  21633.                 } // *OTL*
  21634.                 // Stay on the page
  21635.                 return false;
  21636.             } else {
  21637.                 // Go back to the first column - NEW PAGE
  21638.                 if (count($this->columnbuffer)) {
  21639.                     $this->printcolumnbuffer();
  21640.                 }
  21641.                 $this->SetCol(0);
  21642.                 $this->y0 $this->tMargin;
  21643.                 $this->ChangeColumn = -($this->NbCol 1);
  21644.                 // DIRECTIONALITY RTL
  21645.                 if ($this->directionality == 'rtl') {
  21646.                     $this->ChangeColumn = -($this->ChangeColumn);
  21647.                 } // *OTL*
  21648.                 // Page break
  21649.                 return true;
  21650.             }
  21651.         } /* -- END COLUMNS -- */
  21652.         /* -- TABLES -- */ elseif ($this->table_rotate) {
  21653.             if ($this->tablebuffer) {
  21654.                 $this->printtablebuffer();
  21655.             }
  21656.             return true;
  21657.         } /* -- END TABLES -- */ else { // *COLUMNS*
  21658.             $this->ChangeColumn 0;
  21659.             return $this->autoPageBreak;
  21660.         } // *COLUMNS*
  21661.         return $this->autoPageBreak;
  21662.     }
  21663.     // ----------- COLUMNS ---------------------
  21664.     /* -- COLUMNS -- */
  21665.     function SetColumns($NbCol$vAlign ''$gap 5)
  21666.     {
  21667.         // NbCol = number of columns
  21668.         // Anything less than 2 turns columns off
  21669.         if ($NbCol 2) { // SET COLUMNS OFF
  21670.             if ($this->ColActive) {
  21671.                 $this->ColActive 0;
  21672.                 if (count($this->columnbuffer)) {
  21673.                     $this->printcolumnbuffer();
  21674.                 }
  21675.                 $this->NbCol 1;
  21676.                 $this->ResetMargins();
  21677.                 $this->pgwidth $this->$this->lMargin $this->rMargin;
  21678.                 $this->divwidth 0;
  21679.                 $this->Ln();
  21680.             }
  21681.             $this->ColActive 0;
  21682.             $this->columnbuffer = [];
  21683.             $this->ColDetails = [];
  21684.             $this->columnLinks = [];
  21685.             $this->columnAnnots = [];
  21686.             $this->columnForms = [];
  21687.             $this->col_BMoutlines = [];
  21688.             $this->col_toc = [];
  21689.             $this->breakpoints = [];
  21690.         } else { // SET COLUMNS ON
  21691.             if ($this->ColActive) {
  21692.                 $this->ColActive 0;
  21693.                 if (count($this->columnbuffer)) {
  21694.                     $this->printcolumnbuffer();
  21695.                 }
  21696.                 $this->ResetMargins();
  21697.             }
  21698.             if (isset($this->y) && $this->$this->tMargin) {
  21699.                 $this->Ln();
  21700.             }
  21701.             $this->NbCol $NbCol;
  21702.             $this->ColGap $gap;
  21703.             $this->divwidth 0;
  21704.             $this->ColActive 1;
  21705.             $this->ColumnAdjust true// enables column height adjustment for the page
  21706.             $this->columnbuffer = [];
  21707.             $this->ColDetails = [];
  21708.             $this->columnLinks = [];
  21709.             $this->columnAnnots = [];
  21710.             $this->columnForms = [];
  21711.             $this->col_BMoutlines = [];
  21712.             $this->col_toc = [];
  21713.             $this->breakpoints = [];
  21714.             if ((strtoupper($vAlign) == 'J') || (strtoupper($vAlign) == 'JUSTIFY')) {
  21715.                 $vAlign 'J';
  21716.             } else {
  21717.                 $vAlign '';
  21718.             }
  21719.             $this->colvAlign $vAlign;
  21720.             // Save the ordinate
  21721.             $absL $this->DeflMargin - ($gap 2);
  21722.             $absR $this->DefrMargin - ($gap 2);
  21723.             $PageWidth $this->$absL $absR// virtual pagewidth for calculation only
  21724.             $ColWidth = (($PageWidth - ($gap * ($NbCol))) / $NbCol);
  21725.             $this->ColWidth $ColWidth;
  21726.             /* -- OTL -- */
  21727.             if ($this->directionality == 'rtl') {
  21728.                 for ($i 0$i $this->NbCol$i++) {
  21729.                     $this->ColL[$i] = $absL + ($gap 2) + (($NbCol - ($i 1)) * ($PageWidth $NbCol));
  21730.                     $this->ColR[$i] = $this->ColL[$i] + $ColWidth// NB This is not R margin -> R pos
  21731.                 }
  21732.             } else {
  21733.                 /* -- END OTL -- */
  21734.                 for ($i 0$i $this->NbCol$i++) {
  21735.                     $this->ColL[$i] = $absL + ($gap 2) + ($i * ($PageWidth $NbCol) );
  21736.                     $this->ColR[$i] = $this->ColL[$i] + $ColWidth// NB This is not R margin -> R pos
  21737.                 }
  21738.             } // *OTL*
  21739.             $this->pgwidth $ColWidth;
  21740.             $this->SetCol(0);
  21741.             $this->y0 $this->y;
  21742.         }
  21743.         $this->$this->lMargin;
  21744.     }
  21745.     function SetCol($CurrCol)
  21746.     {
  21747.         // Used internally to set column by number: 0 is 1st column
  21748.         // Set position on a column
  21749.         $this->CurrCol $CurrCol;
  21750.         $x $this->ColL[$CurrCol];
  21751.         $xR $this->ColR[$CurrCol]; // NB This is not R margin -> R pos
  21752.         if (($this->mirrorMargins) && (($this->page) % == 0)) { // EVEN
  21753.             $x += $this->MarginCorrection;
  21754.             $xR += $this->MarginCorrection;
  21755.         }
  21756.         $this->SetMargins($x, ($this->$xR), $this->tMargin);
  21757.     }
  21758.     function AddColumn()
  21759.     {
  21760.         $this->NewColumn();
  21761.         $this->ColumnAdjust false// disables all column height adjustment for the page.
  21762.     }
  21763.     function NewColumn()
  21764.     {
  21765.         if ($this->ColActive == 1) {
  21766.             if ($this->CurrCol $this->NbCol 1) {
  21767.                 // Go to the next column
  21768.                 $this->CurrCol++;
  21769.                 $this->SetCol($this->CurrCol);
  21770.                 $this->$this->y0;
  21771.                 $this->ChangeColumn 1;
  21772.                 // DIRECTIONALITY RTL
  21773.                 if ($this->directionality == 'rtl') {
  21774.                     $this->ChangeColumn = -($this->ChangeColumn);
  21775.                 } // *OTL*
  21776.                 // Stay on the page
  21777.             } else {
  21778.                 // Go back to the first column
  21779.                 // Page break
  21780.                 if (count($this->columnbuffer)) {
  21781.                     $this->printcolumnbuffer();
  21782.                 }
  21783.                 $this->AddPage($this->CurOrientation);
  21784.                 $this->SetCol(0);
  21785.                 $this->y0 $this->tMargin;
  21786.                 $this->ChangeColumn = -($this->NbCol 1);
  21787.                 // DIRECTIONALITY RTL
  21788.                 if ($this->directionality == 'rtl') {
  21789.                     $this->ChangeColumn = -($this->ChangeColumn);
  21790.                 } // *OTL*
  21791.             }
  21792.             $this->$this->lMargin;
  21793.         } else {
  21794.             $this->AddPage($this->CurOrientation);
  21795.         }
  21796.     }
  21797.     function printcolumnbuffer()
  21798.     {
  21799.         // Columns ended (but page not ended) -> try to match all columns - unless disabled by using a custom column-break
  21800.         if (!$this->ColActive && $this->ColumnAdjust && !$this->keepColumns) {
  21801.             // Calculate adjustment to add to each column to calculate rel_y value
  21802.             $this->ColDetails[0]['add_y'] = 0;
  21803.             $last_col 0;
  21804.             // Recursively add previous column's height
  21805.             for ($i 1$i $this->NbCol$i++) {
  21806.                 if (isset($this->ColDetails[$i]['bottom_margin']) && $this->ColDetails[$i]['bottom_margin']) { // If any entries in the column
  21807.                     $this->ColDetails[$i]['add_y'] = ($this->ColDetails[$i 1]['bottom_margin'] - $this->y0) + $this->ColDetails[$i 1]['add_y'];
  21808.                     $last_col $i;  // Last column actually printed
  21809.                 }
  21810.             }
  21811.             // Calculate value for each position sensitive entry as though for one column
  21812.             foreach ($this->columnbuffer as $key => $s) {
  21813.                 $t $s['s'];
  21814.                 if ($t == 'ACROFORM') {
  21815.                     $this->columnbuffer[$key]['rel_y'] = $s['y'] + $this->ColDetails[$s['col']]['add_y'] - $this->y0;
  21816.                     $this->columnbuffer[$key]['s'] = '';
  21817.                 } elseif (preg_match('/BT \d+\.\d\d+ (\d+\.\d\d+) Td/'$t)) {
  21818.                     $this->columnbuffer[$key]['rel_y'] = $s['y'] + $this->ColDetails[$s['col']]['add_y'] - $this->y0;
  21819.                 } elseif (preg_match('/\d+\.\d\d+ (\d+\.\d\d+) \d+\.\d\d+ [\-]{0,1}\d+\.\d\d+ re/'$t)) {
  21820.                     $this->columnbuffer[$key]['rel_y'] = $s['y'] + $this->ColDetails[$s['col']]['add_y'] - $this->y0;
  21821.                 } elseif (preg_match('/\d+\.\d\d+ (\d+\.\d\d+) m/'$t)) {
  21822.                     $this->columnbuffer[$key]['rel_y'] = $s['y'] + $this->ColDetails[$s['col']]['add_y'] - $this->y0;
  21823.                 } elseif (preg_match('/\d+\.\d\d+ (\d+\.\d\d+) l/'$t)) {
  21824.                     $this->columnbuffer[$key]['rel_y'] = $s['y'] + $this->ColDetails[$s['col']]['add_y'] - $this->y0;
  21825.                 } elseif (preg_match('/q \d+\.\d\d+ 0 0 \d+\.\d\d+ \d+\.\d\d+ (\d+\.\d\d+) cm \/(I|FO)\d+ Do Q/'$t)) {
  21826.                     $this->columnbuffer[$key]['rel_y'] = $s['y'] + $this->ColDetails[$s['col']]['add_y'] - $this->y0;
  21827.                 } elseif (preg_match('/\d+\.\d\d+ (\d+\.\d\d+) \d+\.\d\d+ \d+\.\d\d+ \d+\.\d\d+ \d+\.\d\d+ c/'$t)) {
  21828.                     $this->columnbuffer[$key]['rel_y'] = $s['y'] + $this->ColDetails[$s['col']]['add_y'] - $this->y0;
  21829.                 }
  21830.             }
  21831.             foreach ($this->internallink as $key => $f) {
  21832.                 if (is_array($f) && isset($f['col'])) {
  21833.                     $this->internallink[$key]['rel_y'] = $f['Y'] + $this->ColDetails[$f['col']]['add_y'] - $this->y0;
  21834.                 }
  21835.             }
  21836.             $breaks = [];
  21837.             foreach ($this->breakpoints as $c => $bpa) {
  21838.                 foreach ($bpa as $rely) {
  21839.                     $breaks[] = $rely $this->ColDetails[$c]['add_y'] - $this->y0;
  21840.                 }
  21841.             }
  21842.             if (isset($this->ColDetails[$last_col]['bottom_margin'])) {
  21843.                 $lcbm $this->ColDetails[$last_col]['bottom_margin'];
  21844.             } else {
  21845.                 $lcbm 0;
  21846.             }
  21847.             $sum_h $this->ColDetails[$last_col]['add_y'] + $lcbm $this->y0;
  21848.             // $sum_h = max($this->ColDetails[$last_col]['add_y'] + $this->ColDetails[$last_col]['bottom_margin'] - $this->y0, end($breaks));
  21849.             $target_h = ($sum_h $this->NbCol);
  21850.             $cbr = [];
  21851.             for ($i 1$i $this->NbCol$i++) {
  21852.                 $th = ($sum_h $i $this->NbCol);
  21853.                 foreach ($breaks as $bk => $val) {
  21854.                     if ($val $th) {
  21855.                         if (!$bk || ($val $th) < ($th $breaks[$bk 1])) {
  21856.                             $cbr[$i 1] = $val;
  21857.                         } else {
  21858.                             $cbr[$i 1] = $breaks[$bk 1];
  21859.                         }
  21860.                         break;
  21861.                     }
  21862.                 }
  21863.             }
  21864.             $cbr[($this->NbCol 1)] = $sum_h;
  21865.             // mPDF 6
  21866.             // Avoid outputing with 1st column empty
  21867.             if (isset($cbr[0]) && $cbr[0] == 0) {
  21868.                 for ($i 0$i $this->NbCol 1$i++) {
  21869.                     $cbr[$i] = $cbr[$i 1];
  21870.                 }
  21871.             }
  21872.             // Now update the columns - divide into columns of approximately equal value
  21873.             $last_new_col 0;
  21874.             $yadj 0// mm
  21875.             $xadj 0;
  21876.             $last_col_bottom 0;
  21877.             $lowest_bottom_y 0;
  21878.             $block_bottom 0;
  21879.             $newcolumn 0;
  21880.             foreach ($this->columnbuffer as $key => $s) {
  21881.                 if (isset($s['rel_y'])) { // only process position sensitive data
  21882.                     if ($s['rel_y'] >= $cbr[$newcolumn]) {
  21883.                         $newcolumn++;
  21884.                     } else {
  21885.                         $newcolumn $last_new_col;
  21886.                     }
  21887.                     $block_bottom max($block_bottom, ($s['rel_y'] + $s['h']));
  21888.                     if ($this->directionality == 'rtl') { // *OTL*
  21889.                         $xadj = -(($newcolumn $s['col']) * ($this->ColWidth $this->ColGap)); // *OTL*
  21890.                     // *OTL*
  21891.                     else { // *OTL*
  21892.                         $xadj = ($newcolumn $s['col']) * ($this->ColWidth $this->ColGap);
  21893.                     } // *OTL*
  21894.                     if ($last_new_col != $newcolumn) { // Added new column
  21895.                         $last_col_bottom $this->columnbuffer[$key]['rel_y'];
  21896.                         $block_bottom 0;
  21897.                     }
  21898.                     $yadj = ($s['rel_y'] - $s['y']) - ($last_col_bottom) + $this->y0;
  21899.                     // callback function
  21900.                     $t $s['s'];
  21901.                     // mPDF 5.7+
  21902.                     $t $this->columnAdjustPregReplace('Td'$xadj$yadj'/BT (\d+\.\d\d+) (\d+\.\d\d+) Td/'$t);
  21903.                     $t $this->columnAdjustPregReplace('re'$xadj$yadj'/(\d+\.\d\d+) (\d+\.\d\d+) (\d+\.\d\d+) ([\-]{0,1}\d+\.\d\d+) re/'$t);
  21904.                     $t $this->columnAdjustPregReplace('l'$xadj$yadj'/(\d+\.\d\d+) (\d+\.\d\d+) l/'$t);
  21905.                     $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);
  21906.                     $t $this->columnAdjustPregReplace('draw'$xadj$yadj'/(\d+\.\d\d+) (\d+\.\d\d+) m/'$t);
  21907.                     $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);
  21908.                     $this->columnbuffer[$key]['s'] = $t;
  21909.                     $this->columnbuffer[$key]['newcol'] = $newcolumn;
  21910.                     $this->columnbuffer[$key]['newy'] = $s['y'] + $yadj;
  21911.                     $last_new_col $newcolumn;
  21912.                     $clb $s['y'] + $yadj $s['h']; // bottom_margin of current
  21913.                     if ((isset($this->ColDetails[$newcolumn]['max_bottom']) && $clb $this->ColDetails[$newcolumn]['max_bottom']) || (!isset($this->ColDetails[$newcolumn]['max_bottom']) && $clb)) {
  21914.                         $this->ColDetails[$newcolumn]['max_bottom'] = $clb;
  21915.                     }
  21916.                     if ($clb $lowest_bottom_y) {
  21917.                         $lowest_bottom_y $clb;
  21918.                     }
  21919.                     // Adjust LINKS
  21920.                     if (isset($this->columnLinks[$s['col']][intval($s['x'])][intval($s['y'])])) {
  21921.                         $ref $this->columnLinks[$s['col']][intval($s['x'])][intval($s['y'])];
  21922.                         $this->PageLinks[$this->page][$ref][0] += ($xadj Mpdf::SCALE);
  21923.                         $this->PageLinks[$this->page][$ref][1] -= ($yadj Mpdf::SCALE);
  21924.                         unset($this->columnLinks[$s['col']][intval($s['x'])][intval($s['y'])]);
  21925.                     }
  21926.                     // Adjust FORM FIELDS
  21927.                     if (isset($this->columnForms[$s['col']][intval($s['x'])][intval($s['y'])])) {
  21928.                         $ref $this->columnForms[$s['col']][intval($s['x'])][intval($s['y'])];
  21929.                         $this->form->forms[$ref]['x'] += ($xadj);
  21930.                         $this->form->forms[$ref]['y'] += ($yadj);
  21931.                         unset($this->columnForms[$s['col']][intval($s['x'])][intval($s['y'])]);
  21932.                     }
  21933.                     /* -- ANNOTATIONS -- */
  21934.                     if (isset($this->columnAnnots[$s['col']][intval($s['x'])][intval($s['y'])])) {
  21935.                         $ref $this->columnAnnots[$s['col']][intval($s['x'])][intval($s['y'])];
  21936.                         if ($this->PageAnnots[$this->page][$ref]['x'] < 0) {
  21937.                             $this->PageAnnots[$this->page][$ref]['x'] -= ($xadj);
  21938.                         } else {
  21939.                             $this->PageAnnots[$this->page][$ref]['x'] += ($xadj);
  21940.                         }
  21941.                         $this->PageAnnots[$this->page][$ref]['y'] += ($yadj); // unlike PageLinks, Page annots has y values from top in mm
  21942.                         unset($this->columnAnnots[$s['col']][intval($s['x'])][intval($s['y'])]);
  21943.                     }
  21944.                     /* -- END ANNOTATIONS -- */
  21945.                 }
  21946.             }
  21947.             /* -- BOOKMARKS -- */
  21948.             // Adjust Bookmarks
  21949.             foreach ($this->col_BMoutlines as $v) {
  21950.                 $this->BMoutlines[] = ['t' => $v['t'], 'l' => $v['l'], 'y' => $this->y0'p' => $v['p']];
  21951.             }
  21952.             /* -- END BOOKMARKS -- */
  21953.             /* -- TOC -- */
  21954.             // Adjust ToC
  21955.             foreach ($this->col_toc as $v) {
  21956.                 $this->tableOfContents->_toc[] = ['t' => $v['t'], 'l' => $v['l'], 'p' => $v['p'], 'link' => $v['link'], 'toc_id' => $v['toc_id']];
  21957.                 $this->links[$v['link']][1] = $this->y0;
  21958.             }
  21959.             /* -- END TOC -- */
  21960.             // Adjust column length to be equal
  21961.             if ($this->colvAlign == 'J') {
  21962.                 foreach ($this->columnbuffer as $key => $s) {
  21963.                     if (isset($s['rel_y'])) { // only process position sensitive data
  21964.                         // Set ratio to expand y values or heights
  21965.                         if (isset($this->ColDetails[$s['newcol']]['max_bottom']) && $this->ColDetails[$s['newcol']]['max_bottom'] && $this->ColDetails[$s['newcol']]['max_bottom'] != $this->y0) {
  21966.                             $ratio = ($lowest_bottom_y - ($this->y0)) / ($this->ColDetails[$s['newcol']]['max_bottom'] - ($this->y0));
  21967.                         } else {
  21968.                             $ratio 1;
  21969.                         }
  21970.                         if (($ratio 1) && ($ratio <= $this->max_colH_correction)) {
  21971.                             $yadj = ($s['newy'] - $this->y0) * ($ratio 1);
  21972.                             // Adjust LINKS
  21973.                             if (isset($this->columnLinks[$s['col']][intval($s['x'])][intval($s['y'])])) {
  21974.                                 $ref $this->columnLinks[$s['col']][intval($s['x'])][intval($s['y'])];
  21975.                                 $this->PageLinks[$this->page][$ref][1] -= ($yadj Mpdf::SCALE); // y value
  21976.                                 $this->PageLinks[$this->page][$ref][3] *= $ratio// height
  21977.                                 unset($this->columnLinks[$s['col']][intval($s['x'])][intval($s['y'])]);
  21978.                             }
  21979.                             // Adjust FORM FIELDS
  21980.                             if (isset($this->columnForms[$s['col']][intval($s['x'])][intval($s['y'])])) {
  21981.                                 $ref $this->columnForms[$s['col']][intval($s['x'])][intval($s['y'])];
  21982.                                 $this->form->forms[$ref]['x'] += ($xadj);
  21983.                                 $this->form->forms[$ref]['y'] += ($yadj);
  21984.                                 unset($this->columnForms[$s['col']][intval($s['x'])][intval($s['y'])]);
  21985.                             }
  21986.                             /* -- ANNOTATIONS -- */
  21987.                             if (isset($this->columnAnnots[$s['col']][intval($s['x'])][intval($s['y'])])) {
  21988.                                 $ref $this->columnAnnots[$s['col']][intval($s['x'])][intval($s['y'])];
  21989.                                 $this->PageAnnots[$this->page][$ref]['y'] += ($yadj);
  21990.                                 unset($this->columnAnnots[$s['col']][intval($s['x'])][intval($s['y'])]);
  21991.                             }
  21992.                             /* -- END ANNOTATIONS -- */
  21993.                         }
  21994.                     }
  21995.                 }
  21996.                 foreach ($this->internallink as $key => $f) {
  21997.                     if (is_array($f) && isset($f['col'])) {
  21998.                         $last_col_bottom 0;
  21999.                         for ($nbc 0$nbc $this->NbCol$nbc++) {
  22000.                             if ($f['rel_y'] >= $cbr[$nbc]) {
  22001.                                 $last_col_bottom $cbr[$nbc];
  22002.                             }
  22003.                         }
  22004.                         $yadj = ($f['rel_y'] - $f['Y']) - $last_col_bottom $this->y0;
  22005.                         $f['Y'] += $yadj;
  22006.                         unset($f['col']);
  22007.                         unset($f['rel_y']);
  22008.                         $this->internallink[$key] = $f;
  22009.                     }
  22010.                 }
  22011.                 $last_col = -1;
  22012.                 $trans_on false;
  22013.                 foreach ($this->columnbuffer as $key => $s) {
  22014.                     if (isset($s['rel_y'])) { // only process position sensitive data
  22015.                         // Set ratio to expand y values or heights
  22016.                         if (isset($this->ColDetails[$s['newcol']]['max_bottom']) && $this->ColDetails[$s['newcol']]['max_bottom'] && $this->ColDetails[$s['newcol']]['max_bottom'] != $this->y0) {
  22017.                             $ratio = ($lowest_bottom_y - ($this->y0)) / ($this->ColDetails[$s['newcol']]['max_bottom'] - ($this->y0));
  22018.                         } else {
  22019.                             $ratio 1;
  22020.                         }
  22021.                         if (($ratio 1) && ($ratio <= $this->max_colH_correction)) {
  22022.                             // Start Transformation
  22023.                             $this->pages[$this->page] .= $this->StartTransform(true) . "\n";
  22024.                             $this->pages[$this->page] .= $this->transformScale(100$ratio 100$x ''$this->y0true) . "\n";
  22025.                             $trans_on true;
  22026.                         }
  22027.                     }
  22028.                     // Now output the adjusted values
  22029.                     $this->pages[$this->page] .= $s['s'] . "\n";
  22030.                     if (isset($s['rel_y']) && ($ratio 1) && ($ratio <= $this->max_colH_correction)) { // only process position sensitive data
  22031.                         // Stop Transformation
  22032.                         $this->pages[$this->page] .= $this->StopTransform(true) . "\n";
  22033.                         $trans_on false;
  22034.                     }
  22035.                 }
  22036.                 if ($trans_on) {
  22037.                     $this->pages[$this->page] .= $this->StopTransform(true) . "\n";
  22038.                 }
  22039.             } else { // if NOT $this->colvAlign == 'J'
  22040.                 // Now output the adjusted values
  22041.                 foreach ($this->columnbuffer as $s) {
  22042.                     $this->pages[$this->page] .= $s['s'] . "\n";
  22043.                 }
  22044.             }
  22045.             if ($lowest_bottom_y 0) {
  22046.                 $this->$lowest_bottom_y;
  22047.             }
  22048.         } // Columns not ended but new page -> align columns (can leave the columns alone - just tidy up the height)
  22049.         elseif ($this->colvAlign == 'J' && $this->ColumnAdjust && !$this->keepColumns) {
  22050.             // calculate the lowest bottom margin
  22051.             $lowest_bottom_y 0;
  22052.             foreach ($this->columnbuffer as $key => $s) {
  22053.                 // Only process output data
  22054.                 $t $s['s'];
  22055.                 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)) ||
  22056.                     (preg_match('/\d+\.\d\d+ (\d+\.\d\d+) l/'$t)) ||
  22057.                     (preg_match('/q \d+\.\d\d+ 0 0 \d+\.\d\d+ \d+\.\d\d+ (\d+\.\d\d+) cm \/(I|FO)\d+ Do Q/'$t)) ||
  22058.                     (preg_match('/\d+\.\d\d+ (\d+\.\d\d+) m/'$t)) ||
  22059.                     (preg_match('/\d+\.\d\d+ (\d+\.\d\d+) \d+\.\d\d+ \d+\.\d\d+ \d+\.\d\d+ \d+\.\d\d+ c/'$t))) {
  22060.                     $clb $s['y'] + $s['h'];
  22061.                     if ((isset($this->ColDetails[$s['col']]['max_bottom']) && $clb $this->ColDetails[$s['col']]['max_bottom']) || !isset($this->ColDetails[$s['col']]['max_bottom'])) {
  22062.                         $this->ColDetails[$s['col']]['max_bottom'] = $clb;
  22063.                     }
  22064.                     if ($clb $lowest_bottom_y) {
  22065.                         $lowest_bottom_y $clb;
  22066.                     }
  22067.                     $this->columnbuffer[$key]['rel_y'] = $s['y']; // Marks position sensitive data to process later
  22068.                     if ($t == 'ACROFORM') {
  22069.                         $this->columnbuffer[$key]['s'] = '';
  22070.                     }
  22071.                 }
  22072.             }
  22073.             // Adjust column length equal
  22074.             foreach ($this->columnbuffer as $key => $s) {
  22075.                 // Set ratio to expand y values or heights
  22076.                 if (isset($this->ColDetails[$s['col']]['max_bottom']) && $this->ColDetails[$s['col']]['max_bottom']) {
  22077.                     $ratio = ($lowest_bottom_y - ($this->y0)) / ($this->ColDetails[$s['col']]['max_bottom'] - ($this->y0));
  22078.                 } else {
  22079.                     $ratio 1;
  22080.                 }
  22081.                 if (($ratio 1) && ($ratio <= $this->max_colH_correction)) {
  22082.                     $yadj = ($s['y'] - $this->y0) * ($ratio 1);
  22083.                     // Adjust LINKS
  22084.                     if (isset($s['rel_y'])) { // only process position sensitive data
  22085.                         // otherwise triggers for all entries in column buffer (.e.g. formatting) and makes below adjustments more than once
  22086.                         if (isset($this->columnLinks[$s['col']][intval($s['x'])][intval($s['y'])])) {
  22087.                             $ref $this->columnLinks[$s['col']][intval($s['x'])][intval($s['y'])];
  22088.                             $this->PageLinks[$this->page][$ref][1] -= ($yadj Mpdf::SCALE); // y value
  22089.                             $this->PageLinks[$this->page][$ref][3] *= $ratio// height
  22090.                             unset($this->columnLinks[$s['col']][intval($s['x'])][intval($s['y'])]);
  22091.                         }
  22092.                         // Adjust FORM FIELDS
  22093.                         if (isset($this->columnForms[$s['col']][intval($s['x'])][intval($s['y'])])) {
  22094.                             $ref $this->columnForms[$s['col']][intval($s['x'])][intval($s['y'])];
  22095.                             $this->form->forms[$ref]['x'] += ($xadj);
  22096.                             $this->form->forms[$ref]['y'] += ($yadj);
  22097.                             unset($this->columnForms[$s['col']][intval($s['x'])][intval($s['y'])]);
  22098.                         }
  22099.                         /* -- ANNOTATIONS -- */
  22100.                         if (isset($this->columnAnnots[$s['col']][intval($s['x'])][intval($s['y'])])) {
  22101.                             $ref $this->columnAnnots[$s['col']][intval($s['x'])][intval($s['y'])];
  22102.                             $this->PageAnnots[$this->page][$ref]['y'] += ($yadj);
  22103.                             unset($this->columnAnnots[$s['col']][intval($s['x'])][intval($s['y'])]);
  22104.                         }
  22105.                         /* -- END ANNOTATIONS -- */
  22106.                     }
  22107.                 }
  22108.             }
  22109.             /* -- BOOKMARKS -- */
  22110.             // Adjust Bookmarks
  22111.             foreach ($this->col_BMoutlines as $v) {
  22112.                 $this->BMoutlines[] = ['t' => $v['t'], 'l' => $v['l'], 'y' => $this->y0'p' => $v['p']];
  22113.             }
  22114.             /* -- END BOOKMARKS -- */
  22115.             /* -- TOC -- */
  22116.             // Adjust ToC
  22117.             foreach ($this->col_toc as $v) {
  22118.                 $this->tableOfContents->_toc[] = ['t' => $v['t'], 'l' => $v['l'], 'p' => $v['p'], 'link' => $v['link'], 'toc_id' => $v['toc_id']];
  22119.                 $this->links[$v['link']][1] = $this->y0;
  22120.             }
  22121.             /* -- END TOC -- */
  22122.             $trans_on false;
  22123.             foreach ($this->columnbuffer as $key => $s) {
  22124.                 if (isset($s['rel_y'])) { // only process position sensitive data
  22125.                     // Set ratio to expand y values or heights
  22126.                     if (isset($this->ColDetails[$s['col']]['max_bottom']) && $this->ColDetails[$s['col']]['max_bottom']) {
  22127.                         $ratio = ($lowest_bottom_y - ($this->y0)) / ($this->ColDetails[$s['col']]['max_bottom'] - ($this->y0));
  22128.                     } else {
  22129.                         $ratio 1;
  22130.                     }
  22131.                     if (($ratio 1) && ($ratio <= $this->max_colH_correction)) {
  22132.                         // Start Transformation
  22133.                         $this->pages[$this->page] .= $this->StartTransform(true) . "\n";
  22134.                         $this->pages[$this->page] .= $this->transformScale(100$ratio 100$x ''$this->y0true) . "\n";
  22135.                         $trans_on true;
  22136.                     }
  22137.                 }
  22138.                 // Now output the adjusted values
  22139.                 $this->pages[$this->page] .= $s['s'] . "\n";
  22140.                 if (isset($s['rel_y']) && ($ratio 1) && ($ratio <= $this->max_colH_correction)) {
  22141.                     // Stop Transformation
  22142.                     $this->pages[$this->page] .= $this->StopTransform(true) . "\n";
  22143.                     $trans_on false;
  22144.                 }
  22145.             }
  22146.             if ($trans_on) {
  22147.                 $this->pages[$this->page] .= $this->StopTransform(true) . "\n";
  22148.             }
  22149.             if ($lowest_bottom_y 0) {
  22150.                 $this->$lowest_bottom_y;
  22151.             }
  22152.         } else { // Just reproduce the page as it was
  22153.             // If page has not ended but height adjustment was disabled by custom column-break - adjust y
  22154.             $lowest_bottom_y 0;
  22155.             if (!$this->ColActive && (!$this->ColumnAdjust || $this->keepColumns)) {
  22156.                 // calculate the lowest bottom margin
  22157.                 foreach ($this->columnbuffer as $key => $s) {
  22158.                     // Only process output data
  22159.                     $t $s['s'];
  22160.                     if ($t === 'ACROFORM'
  22161.                             || (preg_match('/BT \d+\.\d\d+ (\d+\.\d\d+) Td/'$t))
  22162.                             || (preg_match('/\d+\.\d\d+ (\d+\.\d\d+) \d+\.\d\d+ [\-]{0,1}\d+\.\d\d+ re/'$t))
  22163.                             || (preg_match('/\d+\.\d\d+ (\d+\.\d\d+) l/'$t))
  22164.                             || (preg_match('/q \d+\.\d\d+ 0 0 \d+\.\d\d+ \d+\.\d\d+ (\d+\.\d\d+) cm \/(I|FO)\d+ Do Q/'$t))
  22165.                             || (preg_match('/\d+\.\d\d+ (\d+\.\d\d+) m/'$t))
  22166.                             || (preg_match('/\d+\.\d\d+ (\d+\.\d\d+) \d+\.\d\d+ \d+\.\d\d+ \d+\.\d\d+ \d+\.\d\d+ c/'$t))) {
  22167.                         $clb $s['y'] + $s['h'];
  22168.                         if (isset($this->ColDetails[$s['col']]['max_bottom']) && $clb $this->ColDetails[$s['col']]['max_bottom'] || (!isset($this->ColDetails[$s['col']]['max_bottom']) && $clb)) {
  22169.                             $this->ColDetails[$s['col']]['max_bottom'] = $clb;
  22170.                         }
  22171.                         if ($clb $lowest_bottom_y) {
  22172.                             $lowest_bottom_y $clb;
  22173.                         }
  22174.                     }
  22175.                 }
  22176.             }
  22177.             foreach ($this->columnbuffer as $key => $s) {
  22178.                 if ($s['s'] != 'ACROFORM') {
  22179.                     $this->pages[$this->page] .= $s['s'] . "\n";
  22180.                 }
  22181.             }
  22182.             if ($lowest_bottom_y 0) {
  22183.                 $this->$lowest_bottom_y;
  22184.             }
  22185.             /* -- BOOKMARKS -- */
  22186.             // Output Bookmarks
  22187.             foreach ($this->col_BMoutlines as $v) {
  22188.                 $this->BMoutlines[] = ['t' => $v['t'], 'l' => $v['l'], 'y' => $v['y'], 'p' => $v['p']];
  22189.             }
  22190.             /* -- END BOOKMARKS -- */
  22191.             /* -- TOC -- */
  22192.             // Output ToC
  22193.             foreach ($this->col_toc as $v) {
  22194.                 $this->tableOfContents->_toc[] = ['t' => $v['t'], 'l' => $v['l'], 'p' => $v['p'], 'link' => $v['link'], 'toc_id' => $v['toc_id']];
  22195.             }
  22196.             /* -- END TOC -- */
  22197.         }
  22198.         foreach ($this->internallink as $key => $f) {
  22199.             if (isset($this->internallink[$key]['col'])) {
  22200.                 unset($this->internallink[$key]['col']);
  22201.             }
  22202.             if (isset($this->internallink[$key]['rel_y'])) {
  22203.                 unset($this->internallink[$key]['rel_y']);
  22204.             }
  22205.         }
  22206.         $this->columnbuffer = [];
  22207.         $this->ColDetails = [];
  22208.         $this->columnLinks = [];
  22209.         $this->columnAnnots = [];
  22210.         $this->columnForms = [];
  22211.         $this->col_BMoutlines = [];
  22212.         $this->col_toc = [];
  22213.         $this->breakpoints = [];
  22214.     }
  22215.     // mPDF 5.7+
  22216.     function columnAdjustPregReplace($type$xadj$yadj$pattern$subject)
  22217.     {
  22218.         preg_match($pattern$subject$matches);
  22219.         if (!count($matches)) {
  22220.             return $subject;
  22221.         }
  22222.         if (!isset($matches[3])) {
  22223.             $matches[3] = 0;
  22224.         }
  22225.         if (!isset($matches[4])) {
  22226.             $matches[4] = 0;
  22227.         }
  22228.         if (!isset($matches[5])) {
  22229.             $matches[5] = 0;
  22230.         }
  22231.         if (!isset($matches[6])) {
  22232.             $matches[6] = 0;
  22233.         }
  22234.         return str_replace($matches[0], $this->columnAdjustAdd($typeMpdf::SCALE$xadj$yadj$matches[1], $matches[2], $matches[3], $matches[4], $matches[5], $matches[6]), $subject);
  22235.     }
  22236.     /* -- END COLUMNS -- */
  22237.     // ==================================================================
  22238.     /* -- TABLES -- */
  22239.     function printcellbuffer()
  22240.     {
  22241.         if (count($this->cellBorderBuffer)) {
  22242.             sort($this->cellBorderBuffer);
  22243.             foreach ($this->cellBorderBuffer as $cbb) {
  22244.                 $cba unpack("A16dom/nbord/A1side/ns/dbw/a6ca/A10style/dx/dy/dw/dh/dmbl/dmbr/dmrt/dmrb/dmtl/dmtr/dmlt/dmlb/dcpd/dover/"$cbb);
  22245.                 $side $cba['side'];
  22246.                 $color str_pad($cba['ca'], 6"\x00");
  22247.                 $details = [];
  22248.                 $details[$side]['dom'] = (float) $cba['dom'];
  22249.                 $details[$side]['s'] = $cba['s'];
  22250.                 $details[$side]['w'] = $cba['bw'];
  22251.                 $details[$side]['c'] = $color;
  22252.                 $details[$side]['style'] = trim($cba['style']);
  22253.                 $details['mbw']['BL'] = $cba['mbl'];
  22254.                 $details['mbw']['BR'] = $cba['mbr'];
  22255.                 $details['mbw']['RT'] = $cba['mrt'];
  22256.                 $details['mbw']['RB'] = $cba['mrb'];
  22257.                 $details['mbw']['TL'] = $cba['mtl'];
  22258.                 $details['mbw']['TR'] = $cba['mtr'];
  22259.                 $details['mbw']['LT'] = $cba['mlt'];
  22260.                 $details['mbw']['LB'] = $cba['mlb'];
  22261.                 $details['cellposdom'] = $cba['cpd'];
  22262.                 $details['p'] = $side;
  22263.                 if ($cba['over'] == 1) {
  22264.                     $details[$side]['overlay'] = true;
  22265.                 } else {
  22266.                     $details[$side]['overlay'] = false;
  22267.                 }
  22268.                 $this->_tableRect($cba['x'], $cba['y'], $cba['w'], $cba['h'], $cba['bord'], $detailsfalsefalse);
  22269.             }
  22270.             $this->cellBorderBuffer = [];
  22271.         }
  22272.     }
  22273.     // ==================================================================
  22274.     function printtablebuffer()
  22275.     {
  22276.         if (!$this->table_rotate) {
  22277.             $this->pages[$this->page] .= $this->tablebuffer;
  22278.             foreach ($this->tbrot_Links as $p => $l) {
  22279.                 foreach ($l as $v) {
  22280.                     $this->PageLinks[$p][] = $v;
  22281.                 }
  22282.             }
  22283.             $this->tbrot_Links = [];
  22284.             /* -- ANNOTATIONS -- */
  22285.             foreach ($this->tbrot_Annots as $p => $l) {
  22286.                 foreach ($l as $v) {
  22287.                     $this->PageAnnots[$p][] = $v;
  22288.                 }
  22289.             }
  22290.             $this->tbrot_Annots = [];
  22291.             /* -- END ANNOTATIONS -- */
  22292.             /* -- BOOKMARKS -- */
  22293.             // Output Bookmarks
  22294.             foreach ($this->tbrot_BMoutlines as $v) {
  22295.                 $this->BMoutlines[] = ['t' => $v['t'], 'l' => $v['l'], 'y' => $v['y'], 'p' => $v['p']];
  22296.             }
  22297.             $this->tbrot_BMoutlines = [];
  22298.             /* -- END BOOKMARKS -- */
  22299.             /* -- TOC -- */
  22300.             // Output ToC
  22301.             foreach ($this->tbrot_toc as $v) {
  22302.                 $this->tableOfContents->_toc[] = ['t' => $v['t'], 'l' => $v['l'], 'p' => $v['p'], 'link' => $v['link'], 'toc_id' => $v['toc_id']];
  22303.             }
  22304.             $this->tbrot_toc = [];
  22305.             /* -- END TOC -- */
  22306.             return;
  22307.         }
  22308.         // elseif rotated
  22309.         $lm $this->lMargin $this->blk[$this->blklvl]['outer_left_margin'] + $this->blk[$this->blklvl]['border_left']['w'] + $this->blk[$this->blklvl]['padding_left'];
  22310.         $pw $this->blk[$this->blklvl]['inner_width'];
  22311.         // Start Transformation
  22312.         $this->pages[$this->page] .= $this->StartTransform(true) . "\n";
  22313.         if ($this->table_rotate 1) { // clockwise
  22314.             if ($this->tbrot_align == 'L') {
  22315.                 $xadj $this->tbrot_h// align L (as is)
  22316.             } elseif ($this->tbrot_align == 'R') {
  22317.                 $xadj $lm $this->tbrot_x0 + ($pw); // align R
  22318.             } else {
  22319.                 $xadj $lm $this->tbrot_x0 + (($pw $this->tbrot_h) / 2); // align C
  22320.             }
  22321.             $yadj 0;
  22322.         } else { // anti-clockwise
  22323.             if ($this->tbrot_align == 'L') {
  22324.                 $xadj 0// align L (as is)
  22325.             } elseif ($this->tbrot_align == 'R') {
  22326.                 $xadj $lm $this->tbrot_x0 + ($pw $this->tbrot_h); // align R
  22327.             } else {
  22328.                 $xadj $lm $this->tbrot_x0 + (($pw $this->tbrot_h) / 2); // align C
  22329.             }
  22330.             $yadj $this->tbrot_w;
  22331.         }
  22332.         $this->pages[$this->page] .= $this->transformTranslate($xadj$yadjtrue) . "\n";
  22333.         $this->pages[$this->page] .= $this->transformRotate($this->table_rotate$this->tbrot_x0$this->tbrot_y0true) . "\n";
  22334.         // Now output the adjusted values
  22335.         $this->pages[$this->page] .= $this->tablebuffer;
  22336.         foreach ($this->tbrot_Links as $p => $l) {
  22337.             foreach ($l as $v) {
  22338.                 $w $v[2] / Mpdf::SCALE;
  22339.                 $h $v[3] / Mpdf::SCALE;
  22340.                 $ax = ($v[0] / Mpdf::SCALE) - $this->tbrot_x0;
  22341.                 $ay = (($this->hPt $v[1]) / Mpdf::SCALE) - $this->tbrot_y0;
  22342.                 if ($this->table_rotate 1) { // clockwise
  22343.                     $bx $this->tbrot_x0 $xadj $ay $h;
  22344.                     $by $this->tbrot_y0 $yadj $ax;
  22345.                 } else {
  22346.                     $bx $this->tbrot_x0 $xadj $ay;
  22347.                     $by $this->tbrot_y0 $yadj $ax $w;
  22348.                 }
  22349.                 $v[0] = $bx Mpdf::SCALE;
  22350.                 $v[1] = ($this->$by) * Mpdf::SCALE;
  22351.                 $v[2] = $h Mpdf::SCALE// swap width and height
  22352.                 $v[3] = $w Mpdf::SCALE;
  22353.                 $this->PageLinks[$p][] = $v;
  22354.             }
  22355.         }
  22356.         $this->tbrot_Links = [];
  22357.         foreach ($this->internallink as $key => $f) {
  22358.             if (is_array($f) && isset($f['tbrot'])) {
  22359.                 $f['Y'] = $this->tbrot_y0;
  22360.                 $f['PAGE'] = $this->page;
  22361.                 unset($f['tbrot']);
  22362.                 $this->internallink[$key] = $f;
  22363.             }
  22364.         }
  22365.         /* -- ANNOTATIONS -- */
  22366.         foreach ($this->tbrot_Annots as $p => $l) {
  22367.             foreach ($l as $v) {
  22368.                 $ax abs($v['x']) - $this->tbrot_x0// abs because -ve values are internally set and held for reference if annotMargin set
  22369.                 $ay $v['y'] - $this->tbrot_y0;
  22370.                 if ($this->table_rotate 1) { // clockwise
  22371.                     $bx $this->tbrot_x0 $xadj $ay;
  22372.                     $by $this->tbrot_y0 $yadj $ax;
  22373.                 } else {
  22374.                     $bx $this->tbrot_x0 $xadj $ay;
  22375.                     $by $this->tbrot_y0 $yadj $ax;
  22376.                 }
  22377.                 if ($v['x'] < 0) {
  22378.                     $v['x'] = -$bx;
  22379.                 } else {
  22380.                     $v['x'] = $bx;
  22381.                 }
  22382.                 $v['y'] = ($by);
  22383.                 $this->PageAnnots[$p][] = $v;
  22384.             }
  22385.         }
  22386.         $this->tbrot_Annots = [];
  22387.         /* -- END ANNOTATIONS -- */
  22388.         /* -- BOOKMARKS -- */
  22389.         // Adjust Bookmarks
  22390.         foreach ($this->tbrot_BMoutlines as $v) {
  22391.             $v['y'] = $this->tbrot_y0;
  22392.             $this->BMoutlines[] = ['t' => $v['t'], 'l' => $v['l'], 'y' => $v['y'], 'p' => $this->page];
  22393.         }
  22394.         /* -- END BOOKMARKS -- */
  22395.         /* -- TOC -- */
  22396.         // Adjust ToC - uses document page number
  22397.         foreach ($this->tbrot_toc as $v) {
  22398.             $this->tableOfContents->_toc[] = ['t' => $v['t'], 'l' => $v['l'], 'p' => $this->page'link' => $v['link'], 'toc_id' => $v['toc_id']];
  22399.             $this->links[$v['link']][1] = $this->tbrot_y0;
  22400.         }
  22401.         /* -- END TOC -- */
  22402.         $this->tbrot_BMoutlines = [];
  22403.         $this->tbrot_toc = [];
  22404.         // Stop Transformation
  22405.         $this->pages[$this->page] .= $this->StopTransform(true) . "\n";
  22406.         $this->$this->tbrot_y0 $this->tbrot_w;
  22407.         $this->$this->lMargin;
  22408.         $this->tablebuffer '';
  22409.     }
  22410.     /**
  22411.      * Keep-with-table This buffers contents of h1-6 to keep on page with table
  22412.      */
  22413.     function printkwtbuffer()
  22414.     {
  22415.         if (!$this->kwt_moved) {
  22416.             foreach ($this->kwt_buffer as $s) {
  22417.                 $this->pages[$this->page] .= $s['s'] . "\n";
  22418.             }
  22419.             foreach ($this->kwt_Links as $p => $l) {
  22420.                 foreach ($l as $v) {
  22421.                     $this->PageLinks[$p][] = $v;
  22422.                 }
  22423.             }
  22424.             $this->kwt_Links = [];
  22425.             /* -- ANNOTATIONS -- */
  22426.             foreach ($this->kwt_Annots as $p => $l) {
  22427.                 foreach ($l as $v) {
  22428.                     $this->PageAnnots[$p][] = $v;
  22429.                 }
  22430.             }
  22431.             $this->kwt_Annots = [];
  22432.             /* -- END ANNOTATIONS -- */
  22433.             /* -- INDEX -- */
  22434.             // Output Reference (index)
  22435.             foreach ($this->kwt_Reference as $v) {
  22436.                 $Present 0;
  22437.                 for ($i 0$i count($this->Reference); $i++) {
  22438.                     if ($this->Reference[$i]['t'] == $v['t']) {
  22439.                         $Present 1;
  22440.                         if (!in_array($v['op'], $this->Reference[$i]['p'])) {
  22441.                             $this->Reference[$i]['p'][] = $v['op'];
  22442.                         }
  22443.                     }
  22444.                 }
  22445.                 if ($Present == 0) {
  22446.                     $this->Reference[] = ['t' => $v['t'], 'p' => [$v['op']]];
  22447.                 }
  22448.             }
  22449.             $this->kwt_Reference = [];
  22450.             /* -- END INDEX -- */
  22451.             /* -- BOOKMARKS -- */
  22452.             // Output Bookmarks
  22453.             foreach ($this->kwt_BMoutlines as $v) {
  22454.                 $this->BMoutlines[] = ['t' => $v['t'], 'l' => $v['l'], 'y' => $v['y'], 'p' => $v['p']];
  22455.             }
  22456.             $this->kwt_BMoutlines = [];
  22457.             /* -- END BOOKMARKS -- */
  22458.             /* -- TOC -- */
  22459.             // Output ToC
  22460.             foreach ($this->kwt_toc as $v) {
  22461.                 $this->tableOfContents->_toc[] = ['t' => $v['t'], 'l' => $v['l'], 'p' => $v['p'], 'link' => $v['link'], 'toc_id' => $v['toc_id']];
  22462.             }
  22463.             $this->kwt_toc = [];
  22464.             /* -- END TOC -- */
  22465.             $this->pageoutput[$this->page] = []; // mPDF 6
  22466.             return;
  22467.         }
  22468.         // Start Transformation
  22469.         $this->pages[$this->page] .= $this->StartTransform(true) . "\n";
  22470.         $xadj $this->lMargin $this->kwt_x0;
  22471.         // $yadj = $this->y - $this->kwt_y0 ;
  22472.         $yadj $this->tMargin $this->kwt_y0;
  22473.         $this->pages[$this->page] .= $this->transformTranslate($xadj$yadjtrue) . "\n";
  22474.         // Now output the adjusted values
  22475.         foreach ($this->kwt_buffer as $s) {
  22476.             $this->pages[$this->page] .= $s['s'] . "\n";
  22477.         }
  22478.         // Adjust hyperLinks
  22479.         foreach ($this->kwt_Links as $p => $l) {
  22480.             foreach ($l as $v) {
  22481.                 $bx $this->kwt_x0 $xadj;
  22482.                 $by $this->kwt_y0 $yadj;
  22483.                 $v[0] = $bx Mpdf::SCALE;
  22484.                 $v[1] = ($this->$by) * Mpdf::SCALE;
  22485.                 $this->PageLinks[$p][] = $v;
  22486.             }
  22487.         }
  22488.         foreach ($this->internallink as $key => $f) {
  22489.             if (is_array($f) && isset($f['kwt'])) {
  22490.                 $f['Y'] += $yadj;
  22491.                 $f['PAGE'] = $this->page;
  22492.                 unset($f['kwt']);
  22493.                 $this->internallink[$key] = $f;
  22494.             }
  22495.         }
  22496.         /* -- ANNOTATIONS -- */
  22497.         foreach ($this->kwt_Annots as $p => $l) {
  22498.             foreach ($l as $v) {
  22499.                 $bx $this->kwt_x0 $xadj;
  22500.                 $by $this->kwt_y0 $yadj;
  22501.                 if ($v['x'] < 0) {
  22502.                     $v['x'] = -$bx;
  22503.                 } else {
  22504.                     $v['x'] = $bx;
  22505.                 }
  22506.                 $v['y'] = $by;
  22507.                 $this->PageAnnots[$p][] = $v;
  22508.             }
  22509.         }
  22510.         /* -- END ANNOTATIONS -- */
  22511.         /* -- BOOKMARKS -- */
  22512.         // Adjust Bookmarks
  22513.         foreach ($this->kwt_BMoutlines as $v) {
  22514.             if ($v['y'] != 0) {
  22515.                 $v['y'] += $yadj;
  22516.             }
  22517.             $this->BMoutlines[] = ['t' => $v['t'], 'l' => $v['l'], 'y' => $v['y'], 'p' => $this->page];
  22518.         }
  22519.         /* -- END BOOKMARKS -- */
  22520.         /* -- INDEX -- */
  22521.         // Adjust Reference (index)
  22522.         foreach ($this->kwt_Reference as $v) {
  22523.             $Present 0;
  22524.             // Search the reference (AND Ref/PageNo) in the array
  22525.             for ($i 0$i count($this->Reference); $i++) {
  22526.                 if ($this->Reference[$i]['t'] == $v['t']) {
  22527.                     $Present 1;
  22528.                     if (!in_array($this->page$this->Reference[$i]['p'])) {
  22529.                         $this->Reference[$i]['p'][] = $this->page;
  22530.                     }
  22531.                 }
  22532.             }
  22533.             if ($Present == 0) {
  22534.                 $this->Reference[] = ['t' => $v['t'], 'p' => [$this->page]];
  22535.             }
  22536.         }
  22537.         /* -- END INDEX -- */
  22538.         /* -- TOC -- */
  22539.         // Adjust ToC
  22540.         foreach ($this->kwt_toc as $v) {
  22541.             $this->tableOfContents->_toc[] = ['t' => $v['t'], 'l' => $v['l'], 'p' => $this->page'link' => $v['link'], 'toc_id' => $v['toc_id']];
  22542.             $this->links[$v['link']][0] = $this->page;
  22543.             $this->links[$v['link']][1] += $yadj;
  22544.         }
  22545.         /* -- END TOC -- */
  22546.         $this->kwt_Links = [];
  22547.         $this->kwt_Annots = [];
  22548.         $this->kwt_Reference = [];
  22549.         $this->kwt_BMoutlines = [];
  22550.         $this->kwt_toc = [];
  22551.         // Stop Transformation
  22552.         $this->pages[$this->page] .= $this->StopTransform(true) . "\n";
  22553.         $this->kwt_buffer = [];
  22554.         $this->+= $this->kwt_height;
  22555.         $this->pageoutput[$this->page] = []; // mPDF 6
  22556.     }
  22557.     /* -- END TABLES -- */
  22558.     function printfloatbuffer()
  22559.     {
  22560.         if (count($this->floatbuffer)) {
  22561.             $this->objectbuffer $this->floatbuffer;
  22562.             $this->printobjectbuffer(false);
  22563.             $this->objectbuffer = [];
  22564.             $this->floatbuffer = [];
  22565.             $this->floatmargins = [];
  22566.         }
  22567.     }
  22568.     function Circle($x$y$r$style 'S')
  22569.     {
  22570.         $this->Ellipse($x$y$r$r$style);
  22571.     }
  22572.     function Ellipse($x$y$rx$ry$style 'S')
  22573.     {
  22574.         if ($style === 'F') {
  22575.             $op 'f';
  22576.         } elseif ($style === 'FD' or $style === 'DF') {
  22577.             $op 'B';
  22578.         } else {
  22579.             $op 'S';
  22580.         }
  22581.         $lx * (M_SQRT2 1) * $rx;
  22582.         $ly * (M_SQRT2 1) * $ry;
  22583.         $h $this->h;
  22584.         $this->writer->write(sprintf('%.3F %.3F m %.3F %.3F %.3F %.3F %.3F %.3F c', ($x $rx) * Mpdf::SCALE, ($h $y) * Mpdf::SCALE, ($x $rx) * Mpdf::SCALE, ($h - ($y $ly)) * Mpdf::SCALE, ($x $lx) * Mpdf::SCALE, ($h - ($y $ry)) * Mpdf::SCALE$x Mpdf::SCALE, ($h - ($y $ry)) * Mpdf::SCALE));
  22585.         $this->writer->write(sprintf('%.3F %.3F %.3F %.3F %.3F %.3F c', ($x $lx) * Mpdf::SCALE, ($h - ($y $ry)) * Mpdf::SCALE, ($x $rx) * Mpdf::SCALE, ($h - ($y $ly)) * Mpdf::SCALE, ($x $rx) * Mpdf::SCALE, ($h $y) * Mpdf::SCALE));
  22586.         $this->writer->write(sprintf('%.3F %.3F %.3F %.3F %.3F %.3F c', ($x $rx) * Mpdf::SCALE, ($h - ($y $ly)) * Mpdf::SCALE, ($x $lx) * Mpdf::SCALE, ($h - ($y $ry)) * Mpdf::SCALE$x Mpdf::SCALE, ($h - ($y $ry)) * Mpdf::SCALE));
  22587.         $this->writer->write(sprintf('%.3F %.3F %.3F %.3F %.3F %.3F c %s', ($x $lx) * Mpdf::SCALE, ($h - ($y $ry)) * Mpdf::SCALE, ($x $rx) * Mpdf::SCALE, ($h - ($y $ly)) * Mpdf::SCALE, ($x $rx) * Mpdf::SCALE, ($h $y) * Mpdf::SCALE$op));
  22588.     }
  22589.     /* -- DIRECTW -- */
  22590.     function AutosizeText($text$w$font$style$szfont 72)
  22591.     {
  22592.         $text ' ' $text ' ';
  22593.         $this->SetFont($font$style$szfontfalse);
  22594.         $text $this->purify_utf8_text($text);
  22595.         if ($this->text_input_as_HTML) {
  22596.             $text $this->all_entities_to_utf8($text);
  22597.         }
  22598.         if ($this->usingCoreFont) {
  22599.             $text mb_convert_encoding($text$this->mb_enc'UTF-8');
  22600.         }
  22601.         // DIRECTIONALITY
  22602.         if (preg_match("/([" $this->pregRTLchars "])/u"$text)) {
  22603.             $this->biDirectional true;
  22604.         }
  22605.         $textvar 0;
  22606.         $save_OTLtags $this->OTLtags;
  22607.         $this->OTLtags = [];
  22608.         if ($this->useKerning) {
  22609.             if ($this->CurrentFont['haskernGPOS']) {
  22610.                 $this->OTLtags['Plus'] .= ' kern';
  22611.             } else {
  22612.                 $textvar = ($textvar TextVars::FC_KERNING);
  22613.             }
  22614.         }
  22615.         /* -- OTL -- */
  22616.         // Use OTL OpenType Table Layout - GSUB & GPOS
  22617.         if (isset($this->CurrentFont['useOTL']) && $this->CurrentFont['useOTL']) {
  22618.             $text $this->otl->applyOTL($text$this->CurrentFont['useOTL']);
  22619.             $OTLdata $this->otl->OTLdata;
  22620.         }
  22621.         /* -- END OTL -- */
  22622.         $this->OTLtags $save_OTLtags;
  22623.         $this->magic_reverse_dir($text$this->directionality$OTLdata);
  22624.         $width $this->sizeConverter->convert($w);
  22625.         $loop 0;
  22626.         while ($loop == 0) {
  22627.             $this->SetFont($font$style$szfontfalse);
  22628.             $sz $this->GetStringWidth($texttrue$OTLdata$textvar);
  22629.             if ($sz $w) {
  22630.                 $szfont --;
  22631.             } else {
  22632.                 $loop ++;
  22633.             }
  22634.         }
  22635.         $this->SetFont($font$style$szfonttruetrue);
  22636.         $this->Cell($w0$text00"C"0''000'M'0false$OTLdata$textvar);
  22637.     }
  22638.     /* -- END DIRECTW -- */
  22639.     // ====================================================
  22640.     // ====================================================
  22641.     function magic_reverse_dir(&$chunk$dir, &$chunkOTLdata)
  22642.     {
  22643.         /* -- OTL -- */
  22644.         if ($this->usingCoreFont) {
  22645.             return 0;
  22646.         }
  22647.         if ($chunk == '') {
  22648.             return 0;
  22649.         }
  22650.         if ($this->biDirectional || $dir == 'rtl') {
  22651.             // check if string contains RTL text
  22652.             // including any added from OTL tables (in PUA)
  22653.             $pregRTLchars $this->pregRTLchars;
  22654.             if (isset($this->CurrentFont['rtlPUAstr']) && $this->CurrentFont['rtlPUAstr']) {
  22655.                 $pregRTLchars .= $this->CurrentFont['rtlPUAstr'];
  22656.             }
  22657.             if (!preg_match("/[" $pregRTLchars "]/u"$chunk) && $dir != 'rtl') {
  22658.                 return 0;
  22659.             }   // Chunk doesn't contain RTL characters
  22660.             $unicode $this->UTF8StringToArray($chunkfalse);
  22661.             $isStrong false;
  22662.             if (empty($chunkOTLdata)) {
  22663.                 $this->getBasicOTLdata($chunkOTLdata$unicode$isStrong);
  22664.             }
  22665.             $useGPOS = isset($this->CurrentFont['useOTL']) && ($this->CurrentFont['useOTL'] & 0x80);
  22666.             // NB Returned $chunk may be a shorter string (with adjusted $cOTLdata) by removal of LRE, RLE etc embedding codes.
  22667.             list($chunk$rtl_content) = $this->otl->bidiSort($unicode$chunk$dir$chunkOTLdata$useGPOS);
  22668.             return $rtl_content;
  22669.         }
  22670.         /* -- END OTL -- */
  22671.         return 0;
  22672.     }
  22673.     /* -- OTL -- */
  22674.     function getBasicOTLdata(&$chunkOTLdata$unicode, &$is_strong)
  22675.     {
  22676.         if (empty($this->otl)) {
  22677.             $this->otl = new Otl($this$this->fontCache);
  22678.         }
  22679.         $chunkOTLdata['group'] = '';
  22680.         $chunkOTLdata['GPOSinfo'] = [];
  22681.         $chunkOTLdata['char_data'] = [];
  22682.         foreach ($unicode as $char) {
  22683.             $ucd_record Ucdn::get_ucd_record($char);
  22684.             $chunkOTLdata['char_data'][] = ['bidi_class' => $ucd_record[2], 'uni' => $char];
  22685.             if ($ucd_record[2] == || $ucd_record[2] == || $ucd_record[2] == 4) {
  22686.                 $is_strong true;
  22687.             } // contains strong character
  22688.             if ($ucd_record[0] == Ucdn::UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK) {
  22689.                 $chunkOTLdata['group'] .= 'M';
  22690.             } elseif ($char == 32 || $char == 12288) {
  22691.                 $chunkOTLdata['group'] .= 'S';
  22692.             } else {
  22693.                 $chunkOTLdata['group'] .= 'C';
  22694.             }
  22695.         }
  22696.     }
  22697.     function _setBidiCodes($mode 'start'$bdf '')
  22698.     {
  22699.         $s '';
  22700.         if ($mode == 'end') {
  22701.             // PDF comes before PDI to close isolate-override (e.g. "LRILROPDFPDI")
  22702.             if (strpos($bdf'PDF') !== false) {
  22703.                 $s .= UtfString::code2utf(0x202C);
  22704.             } // POP DIRECTIONAL FORMATTING
  22705.             if (strpos($bdf'PDI') !== false) {
  22706.                 $s .= UtfString::code2utf(0x2069);
  22707.             } // POP DIRECTIONAL ISOLATE
  22708.         } elseif ($mode == 'start') {
  22709.             // LRI comes before LRO to open isolate-override (e.g. "LRILROPDFPDI")
  22710.             if (strpos($bdf'LRI') !== false) {  // U+2066 LRI
  22711.                 $s .= UtfString::code2utf(0x2066);
  22712.             } elseif (strpos($bdf'RLI') !== false) { // U+2067 RLI
  22713.                 $s .= UtfString::code2utf(0x2067);
  22714.             } elseif (strpos($bdf'FSI') !== false) { // U+2068 FSI
  22715.                 $s .= UtfString::code2utf(0x2068);
  22716.             }
  22717.             if (strpos($bdf'LRO') !== false) { // U+202D LRO
  22718.                 $s .= UtfString::code2utf(0x202D);
  22719.             } elseif (strpos($bdf'RLO') !== false) { // U+202E RLO
  22720.                 $s .= UtfString::code2utf(0x202E);
  22721.             } elseif (strpos($bdf'LRE') !== false) { // U+202A LRE
  22722.                 $s .= UtfString::code2utf(0x202A);
  22723.             } elseif (strpos($bdf'RLE') !== false) { // U+202B RLE
  22724.                 $s .= UtfString::code2utf(0x202B);
  22725.             }
  22726.         }
  22727.         return $s;
  22728.     }
  22729.     /* -- END OTL -- */
  22730.     function SetSubstitutions()
  22731.     {
  22732.         $subsarray = [];
  22733.         require __DIR__ '/../data/subs_win-1252.php';
  22734.         $this->substitute = [];
  22735.         foreach ($subsarray as $key => $val) {
  22736.             $this->substitute[UtfString::code2utf($key)] = $val;
  22737.         }
  22738.     }
  22739.     function SubstituteChars($html)
  22740.     {
  22741.         // only substitute characters between tags
  22742.         if (count($this->substitute)) {
  22743.             $a preg_split('/(<.*?>)/ms'$html, -1PREG_SPLIT_DELIM_CAPTURE);
  22744.             $html '';
  22745.             foreach ($a as $i => $e) {
  22746.                 if ($i == 0) {
  22747.                     $e strtr($e$this->substitute);
  22748.                 }
  22749.                 $html .= $e;
  22750.             }
  22751.         }
  22752.         return $html;
  22753.     }
  22754.     function SubstituteCharsSIP(&$writehtml_a, &$writehtml_i, &$writehtml_e)
  22755.     {
  22756.         if (preg_match("/^(.*?)([\x{20000}-\x{2FFFF}]+)(.*)/u"$writehtml_e$m)) {
  22757.             if (isset($this->CurrentFont['sipext']) && $this->CurrentFont['sipext']) {
  22758.                 $font $this->CurrentFont['sipext'];
  22759.                 if (!in_array($font$this->available_unifonts)) {
  22760.                     return 0;
  22761.                 }
  22762.                 $writehtml_a[$writehtml_i] = $writehtml_e $m[1];
  22763.                 array_splice($writehtml_a$writehtml_i 10, ['span style="font-family: ' $font '"'$m[2], '/span'$m[3]]);
  22764.                 $this->subPos $writehtml_i;
  22765.                 return 4;
  22766.             }
  22767.         }
  22768.         return 0;
  22769.     }
  22770.     /**
  22771.      * If core font is selected in document which is not onlyCoreFonts - substitute with non-core font
  22772.      */
  22773.     function SubstituteCharsNonCore(&$writehtml_a, &$writehtml_i, &$writehtml_e)
  22774.     {
  22775.         // Ignore if in Textarea
  22776.         if ($writehtml_i && strtolower(substr($writehtml_a[$writehtml_i 1], 08)) == 'textarea') {
  22777.             return 0;
  22778.         }
  22779.         if (mb_convert_encoding(mb_convert_encoding($writehtml_e$this->mb_enc"UTF-8"), "UTF-8"$this->mb_enc) == $writehtml_e) {
  22780.             return 0;
  22781.         }
  22782.         $cw = &$this->CurrentFont['cw'];
  22783.         $unicode $this->UTF8StringToArray($writehtml_efalse);
  22784.         $start = -1;
  22785.         $end 0;
  22786.         $flag 0;
  22787.         $ftype '';
  22788.         $u = [];
  22789.         if (!$this->subArrMB) {
  22790.             require __DIR__ '/../data/subs_core.php';
  22791.             $this->subArrMB['a'] = $aarr;
  22792.             $this->subArrMB['s'] = $sarr;
  22793.             $this->subArrMB['z'] = $zarr;
  22794.         }
  22795.         foreach ($unicode as $c => $char) {
  22796.             if (($char 127 || ($flag == && $char == 32)) && $char != 173 && (!isset($this->subArrMB['a'][$char]) || ($flag == && $char == 32)) && ($char 1536 || ($char 1791 && $char 2304) || $char 3455)) {
  22797.                 if ($flag == 0) {
  22798.                     $start $c;
  22799.                 }
  22800.                 $flag 1;
  22801.                 $u[] = $char;
  22802.             } elseif ($flag 0) {
  22803.                 $end $c 1;
  22804.                 break;
  22805.             }
  22806.         }
  22807.         if ($flag && !$end) {
  22808.             $end count($unicode) - 1;
  22809.         }
  22810.         if ($start == -1) {
  22811.             return 0;
  22812.         }
  22813.         // Try in backup subs font
  22814.         if (!is_array($this->backupSubsFont)) {
  22815.             $this->backupSubsFont = ["$this->backupSubsFont"];
  22816.         }
  22817.         foreach ($this->backupSubsFont as $bsfctr => $bsf) {
  22818.             if ($this->fonttrans[$bsf] == 'chelvetica' || $this->fonttrans[$bsf] == 'ctimes' || $this->fonttrans[$bsf] == 'ccourier') {
  22819.                 continue;
  22820.             }
  22821.             $font $bsf;
  22822.             unset($cw);
  22823.             $cw '';
  22824.             if (isset($this->fonts[$font])) {
  22825.                 $cw = &$this->fonts[$font]['cw'];
  22826.             } elseif ($this->fontCache->has($font '.cw.dat')) {
  22827.                 $cw $this->fontCache->load($font '.cw.dat');
  22828.             } else {
  22829.                 $prevFontFamily $this->FontFamily;
  22830.                 $prevFontStyle $this->currentfontstyle;
  22831.                 $prevFontSizePt $this->FontSizePt;
  22832.                 $this->SetFont($bsf''''false);
  22833.                 $this->SetFont($prevFontFamily$prevFontStyle$prevFontSizePtfalse);
  22834.             }
  22835.             if (!$cw) {
  22836.                 continue;
  22837.             }
  22838.             $l 0;
  22839.             foreach ($u as $char) {
  22840.                 if ($char == 173 || $this->_charDefined($cw$char) || ($char 1536 && $char 1791) || ($char 2304 && $char 3455 )) {
  22841.                     $l++;
  22842.                 } else {
  22843.                     if ($l == && $bsfctr == (count($this->backupSubsFont) - 1)) { // Not found even in last backup font
  22844.                         $cont mb_substr($writehtml_e$start 1);
  22845.                         $writehtml_e mb_substr($writehtml_e0$start 1'UTF-8');
  22846.                         array_splice($writehtml_a$writehtml_i 10, [''$cont]);
  22847.                         $this->subPos $writehtml_i 1;
  22848.                         return 2;
  22849.                     } else {
  22850.                         break;
  22851.                     }
  22852.                 }
  22853.             }
  22854.             if ($l 0) {
  22855.                 $patt mb_substr($writehtml_e$start$l'UTF-8');
  22856.                 if (preg_match("/(.*?)(" preg_quote($patt'/') . ")(.*)/u"$writehtml_e$m)) {
  22857.                     $writehtml_e $m[1];
  22858.                     array_splice($writehtml_a$writehtml_i 10, ['span style="font-family: ' $font '"'$m[2], '/span'$m[3]]);
  22859.                     $this->subPos $writehtml_i 3;
  22860.                     return 4;
  22861.                 }
  22862.             }
  22863.         }
  22864.         unset($cw);
  22865.         return 0;
  22866.     }
  22867.     function SubstituteCharsMB(&$writehtml_a, &$writehtml_i, &$writehtml_e)
  22868.     {
  22869.         // Ignore if in Textarea
  22870.         if ($writehtml_i && strtolower(substr($writehtml_a[$writehtml_i 1], 08)) == 'textarea') {
  22871.             return 0;
  22872.         }
  22873.         $cw = &$this->CurrentFont['cw'];
  22874.         $unicode $this->UTF8StringToArray($writehtml_efalse);
  22875.         $start = -1;
  22876.         $end 0;
  22877.         $flag 0;
  22878.         $ftype '';
  22879.         $u = [];
  22880.         foreach ($unicode as $c => $char) {
  22881.             if (($flag == || $flag == 2) && (!$this->_charDefined($cw$char) || ($flag == && $char == 32)) && $this->checkSIP && $char 131071) {  // Unicode Plane 2 (SIP)
  22882.                 if (in_array($this->FontFamily$this->available_CJK_fonts)) {
  22883.                     return 0;
  22884.                 }
  22885.                 if ($flag == 0) {
  22886.                     $start $c;
  22887.                 }
  22888.                 $flag 2;
  22889.                 $u[] = $char;
  22890.                 // elseif (($flag == 0 || $flag==1) && $char != 173 && !$this->_charDefined($cw,$char) && ($char<1423 ||  ($char>3583 && $char < 11263))) {
  22891.             } elseif (($flag == || $flag == 1) && $char != 173 && (!$this->_charDefined($cw$char) || ($flag == && $char == 32)) && ($char 1536 || ($char 1791 && $char 2304) || $char 3455)) {
  22892.                 if ($flag == 0) {
  22893.                     $start $c;
  22894.                 }
  22895.                 $flag 1;
  22896.                 $u[] = $char;
  22897.             } elseif ($flag 0) {
  22898.                 $end $c 1;
  22899.                 break;
  22900.             }
  22901.         }
  22902.         if ($flag && !$end) {
  22903.             $end count($unicode) - 1;
  22904.         }
  22905.         if ($start == -1) {
  22906.             return 0;
  22907.         }
  22908.         if ($flag == 2) { // SIP
  22909.             // Check if current CJK font has a ext-B related font
  22910.             if (isset($this->CurrentFont['sipext']) && $this->CurrentFont['sipext']) {
  22911.                 $font $this->CurrentFont['sipext'];
  22912.                 unset($cw);
  22913.                 $cw '';
  22914.                 if (isset($this->fonts[$font])) {
  22915.                     $cw = &$this->fonts[$font]['cw'];
  22916.                 } elseif ($this->fontCache->has($font '.cw.dat')) {
  22917.                     $cw $this->fontCache->load($font '.cw.dat');
  22918.                 } else {
  22919.                     $prevFontFamily $this->FontFamily;
  22920.                     $prevFontStyle $this->currentfontstyle;
  22921.                     $prevFontSizePt $this->FontSizePt;
  22922.                     $this->SetFont($font''''false);
  22923.                     $this->SetFont($prevFontFamily$prevFontStyle$prevFontSizePtfalse);
  22924.                 }
  22925.                 if (!$cw) {
  22926.                     return 0;
  22927.                 }
  22928.                 $l 0;
  22929.                 foreach ($u as $char) {
  22930.                     if ($this->_charDefined($cw$char) || $char 131071) {
  22931.                         $l++;
  22932.                     } else {
  22933.                         break;
  22934.                     }
  22935.                 }
  22936.                 if ($l 0) {
  22937.                     $patt mb_substr($writehtml_e$start$l);
  22938.                     if (preg_match("/(.*?)(" preg_quote($patt'/') . ")(.*)/u"$writehtml_e$m)) {
  22939.                         $writehtml_e $m[1];
  22940.                         array_splice($writehtml_a$writehtml_i 10, ['span style="font-family: ' $font '"'$m[2], '/span'$m[3]]);
  22941.                         $this->subPos $writehtml_i 3;
  22942.                         return 4;
  22943.                     }
  22944.                 }
  22945.             }
  22946.             // Check Backup SIP font (defined in Config\FontVariables)
  22947.             if (isset($this->backupSIPFont) && $this->backupSIPFont) {
  22948.                 if ($this->currentfontfamily != $this->backupSIPFont) {
  22949.                     $font $this->backupSIPFont;
  22950.                 } else {
  22951.                     unset($cw);
  22952.                     return 0;
  22953.                 }
  22954.                 unset($cw);
  22955.                 $cw '';
  22956.                 if (isset($this->fonts[$font])) {
  22957.                     $cw = &$this->fonts[$font]['cw'];
  22958.                 } elseif ($this->fontCache->has($font '.cw.dat')) {
  22959.                     $cw $this->fontCache->load($font '.cw.dat');
  22960.                 } else {
  22961.                     $prevFontFamily $this->FontFamily;
  22962.                     $prevFontStyle $this->currentfontstyle;
  22963.                     $prevFontSizePt $this->FontSizePt;
  22964.                     $this->SetFont($this->backupSIPFont''''false);
  22965.                     $this->SetFont($prevFontFamily$prevFontStyle$prevFontSizePtfalse);
  22966.                 }
  22967.                 if (!$cw) {
  22968.                     return 0;
  22969.                 }
  22970.                 $l 0;
  22971.                 foreach ($u as $char) {
  22972.                     if ($this->_charDefined($cw$char) || $char 131071) {
  22973.                         $l++;
  22974.                     } else {
  22975.                         break;
  22976.                     }
  22977.                 }
  22978.                 if ($l 0) {
  22979.                     $patt mb_substr($writehtml_e$start$l);
  22980.                     if (preg_match("/(.*?)(" preg_quote($patt'/') . ")(.*)/u"$writehtml_e$m)) {
  22981.                         $writehtml_e $m[1];
  22982.                         array_splice($writehtml_a$writehtml_i 10, ['span style="font-family: ' $font '"'$m[2], '/span'$m[3]]);
  22983.                         $this->subPos $writehtml_i 3;
  22984.                         return 4;
  22985.                     }
  22986.                 }
  22987.             }
  22988.             return 0;
  22989.         }
  22990.         // FIRST TRY CORE FONTS (when appropriate)
  22991.         if (!$this->PDFA && !$this->PDFX && !$this->biDirectional) {  // mPDF 6
  22992.             $repl = [];
  22993.             if (!$this->subArrMB) {
  22994.                 require __DIR__ '/../data/subs_core.php';
  22995.                 $this->subArrMB['a'] = $aarr;
  22996.                 $this->subArrMB['s'] = $sarr;
  22997.                 $this->subArrMB['z'] = $zarr;
  22998.             }
  22999.             if (isset($this->subArrMB['a'][$u[0]])) {
  23000.                 $font 'tta';
  23001.                 $ftype 'C';
  23002.                 foreach ($u as $char) {
  23003.                     if (isset($this->subArrMB['a'][$char])) {
  23004.                         $repl[] = $this->subArrMB['a'][$char];
  23005.                     } else {
  23006.                         break;
  23007.                     }
  23008.                 }
  23009.             } elseif (isset($this->subArrMB['z'][$u[0]])) {
  23010.                 $font 'ttz';
  23011.                 $ftype 'C';
  23012.                 foreach ($u as $char) {
  23013.                     if (isset($this->subArrMB['z'][$char])) {
  23014.                         $repl[] = $this->subArrMB['z'][$char];
  23015.                     } else {
  23016.                         break;
  23017.                     }
  23018.                 }
  23019.             } elseif (isset($this->subArrMB['s'][$u[0]])) {
  23020.                 $font 'tts';
  23021.                 $ftype 'C';
  23022.                 foreach ($u as $char) {
  23023.                     if (isset($this->subArrMB['s'][$char])) {
  23024.                         $repl[] = $this->subArrMB['s'][$char];
  23025.                     } else {
  23026.                         break;
  23027.                     }
  23028.                 }
  23029.             }
  23030.             if ($ftype == 'C') {
  23031.                 $patt mb_substr($writehtml_e$startcount($repl));
  23032.                 if (preg_match("/(.*?)(" preg_quote($patt'/') . ")(.*)/u"$writehtml_e$m)) {
  23033.                     $writehtml_e $m[1];
  23034.                     array_splice($writehtml_a$writehtml_i 10, [$fontimplode('|'$repl), '/' $font$m[3]]); // e.g. <tts>
  23035.                     $this->subPos $writehtml_i 3;
  23036.                     return 4;
  23037.                 }
  23038.                 return 0;
  23039.             }
  23040.         }
  23041.         // LASTLY TRY IN BACKUP SUBS FONT
  23042.         if (!is_array($this->backupSubsFont)) {
  23043.             $this->backupSubsFont = ["$this->backupSubsFont"];
  23044.         }
  23045.         foreach ($this->backupSubsFont as $bsfctr => $bsf) {
  23046.             if ($this->currentfontfamily != $bsf) {
  23047.                 $font $bsf;
  23048.             } else {
  23049.                 continue;
  23050.             }
  23051.             unset($cw);
  23052.             $cw '';
  23053.             if (isset($this->fonts[$font])) {
  23054.                 $cw = &$this->fonts[$font]['cw'];
  23055.             } elseif ($this->fontCache->has($font '.cw.dat')) {
  23056.                 $cw $this->fontCache->load($font '.cw.dat');
  23057.             } else {
  23058.                 $prevFontFamily $this->FontFamily;
  23059.                 $prevFontStyle $this->currentfontstyle;
  23060.                 $prevFontSizePt $this->FontSizePt;
  23061.                 $this->SetFont($bsf''''false);
  23062.                 $this->SetFont($prevFontFamily$prevFontStyle$prevFontSizePtfalse);
  23063.                 if ($this->fontCache->has($font '.cw.dat')) {
  23064.                     $cw $this->fontCache->load($font '.cw.dat');
  23065.                 }
  23066.             }
  23067.             if (!$cw) {
  23068.                 continue;
  23069.             }
  23070.             $l 0;
  23071.             foreach ($u as $char) {
  23072.                 if ($char == 173 || $this->_charDefined($cw$char) || ($char 1536 && $char 1791) || ($char 2304 && $char 3455 )) {  // Arabic and Indic
  23073.                     $l++;
  23074.                 } else {
  23075.                     if ($l == && $bsfctr == (count($this->backupSubsFont) - 1)) { // Not found even in last backup font
  23076.                         $cont mb_substr($writehtml_e$start 1);
  23077.                         $writehtml_e mb_substr($writehtml_e0$start 1);
  23078.                         array_splice($writehtml_a$writehtml_i 10, [''$cont]);
  23079.                         $this->subPos $writehtml_i 1;
  23080.                         return 2;
  23081.                     } else {
  23082.                         break;
  23083.                     }
  23084.                 }
  23085.             }
  23086.             if ($l 0) {
  23087.                 $patt mb_substr($writehtml_e$start$l);
  23088.                 if (preg_match("/(.*?)(" preg_quote($patt'/') . ")(.*)/u"$writehtml_e$m)) {
  23089.                     $writehtml_e $m[1];
  23090.                     array_splice($writehtml_a$writehtml_i 10, ['span style="font-family: ' $font '"'$m[2], '/span'$m[3]]);
  23091.                     $this->subPos $writehtml_i 3;
  23092.                     return 4;
  23093.                 }
  23094.             }
  23095.         }
  23096.         unset($cw);
  23097.         return 0;
  23098.     }
  23099.     function setHiEntitySubstitutions()
  23100.     {
  23101.         $entarr = include __DIR__ '/../data/entity_substitutions.php';
  23102.         foreach ($entarr as $key => $val) {
  23103.             $this->entsearch[] = '&' $key ';';
  23104.             $this->entsubstitute[] = UtfString::code2utf($val);
  23105.         }
  23106.     }
  23107.     function SubstituteHiEntities($html)
  23108.     {
  23109.         // converts html_entities > ASCII 127 to unicode
  23110.         // Leaves in particular &lt; to distinguish from tag marker
  23111.         if (count($this->entsearch)) {
  23112.             $html str_replace($this->entsearch$this->entsubstitute$html);
  23113.         }
  23114.         return $html;
  23115.     }
  23116.     /**
  23117.      * Edited v1.2 Pass by reference; option to continue if invalid UTF-8 chars
  23118.      */
  23119.     function is_utf8(&$string)
  23120.     {
  23121.         if ($string === mb_convert_encoding(mb_convert_encoding($string"UTF-32""UTF-8"), "UTF-8""UTF-32")) {
  23122.             return true;
  23123.         }
  23124.         if ($this->ignore_invalid_utf8) {
  23125.             $string mb_convert_encoding(mb_convert_encoding($string"UTF-32""UTF-8"), "UTF-8""UTF-32");
  23126.             return true;
  23127.         }
  23128.         return false;
  23129.     }
  23130.     /**
  23131.      * For HTML
  23132.      *
  23133.      * Checks string is valid UTF-8 encoded
  23134.      * converts html_entities > ASCII 127 to UTF-8
  23135.      * Only exception - leaves low ASCII entities e.g. &lt; &amp; etc.
  23136.      * Leaves in particular &lt; to distinguish from tag marker
  23137.      */
  23138.     function purify_utf8($html$lo true)
  23139.     {
  23140.         if (!$this->is_utf8($html)) {
  23141.             while (mb_convert_encoding(mb_convert_encoding($html"UTF-32""UTF-8"), "UTF-8""UTF-32") !== $html) {
  23142.                 $a = @iconv('UTF-8''UTF-8'$html);
  23143.                 $error error_get_last();
  23144.                 if ($error && $error['message'] === 'iconv(): Detected an illegal character in input string') {
  23145.                     throw new \Mpdf\MpdfException('Invalid input characters. Did you set $mpdf->in_charset properly?');
  23146.                 }
  23147.                 $pos $start strlen($a);
  23148.                 $err '';
  23149.                 while (ord(substr($html$pos1)) > 128) {
  23150.                     $err .= '[[#' ord(substr($html$pos1)) . ']]';
  23151.                     $pos++;
  23152.                 }
  23153.                 $this->logger->error($err, ['context' => LogContext::UTF8]);
  23154.                 $html substr($html$pos);
  23155.             }
  23156.             throw new \Mpdf\MpdfException("HTML contains invalid UTF-8 character(s). See log for further details");
  23157.         }
  23158.         $html preg_replace("/\r/"""$html);
  23159.         // converts html_entities > ASCII 127 to UTF-8
  23160.         // Leaves in particular &lt; to distinguish from tag marker
  23161.         $html $this->SubstituteHiEntities($html);
  23162.         // converts all &#nnn; or &#xHHH; to UTF-8 multibyte
  23163.         // If $lo==true then includes ASCII < 128
  23164.         $html UtfString::strcode2utf($html$lo);
  23165.         return $html;
  23166.     }
  23167.     /**
  23168.      * For TEXT
  23169.      */
  23170.     function purify_utf8_text($txt)
  23171.     {
  23172.         // Make sure UTF-8 string of characters
  23173.         if (!$this->is_utf8($txt)) {
  23174.             throw new \Mpdf\MpdfException("Text contains invalid UTF-8 character(s)");
  23175.         }
  23176.         $txt preg_replace("/\r/"""$txt);
  23177.         return ($txt);
  23178.     }
  23179.     function all_entities_to_utf8($txt)
  23180.     {
  23181.         // converts txt_entities > ASCII 127 to UTF-8
  23182.         // Leaves in particular &lt; to distinguish from tag marker
  23183.         $txt $this->SubstituteHiEntities($txt);
  23184.         // converts all &#nnn; or &#xHHH; to UTF-8 multibyte
  23185.         $txt UtfString::strcode2utf($txt);
  23186.         $txt $this->lesser_entity_decode($txt);
  23187.         return ($txt);
  23188.     }
  23189.     /* -- BARCODES -- */
  23190.     /**
  23191.      * UPC/EAN barcode
  23192.      *
  23193.      * EAN13, EAN8, UPCA, UPCE, ISBN, ISSN
  23194.      * Accepts 12 or 13 digits with or without - hyphens
  23195.      */
  23196.     function WriteBarcode($code$showtext 1$x ''$y ''$size 1$border 0$paddingL 1$paddingR 1$paddingT 2$paddingB 2$height 1$bgcol false$col false$btype 'ISBN'$supplement '0'$supplement_code ''$k 1)
  23197.     {
  23198.         if (empty($code)) {
  23199.             return;
  23200.         }
  23201.         $codestr $code;
  23202.         $code preg_replace('/\-/'''$code);
  23203.         $this->barcode = new Barcode();
  23204.         if ($btype == 'ISSN' || $btype == 'ISBN') {
  23205.             $arrcode $this->barcode->getBarcodeArray($code'EAN13');
  23206.         } else {
  23207.             $arrcode $this->barcode->getBarcodeArray($code$btype);
  23208.         }
  23209.         if ($arrcode === false) {
  23210.             throw new \Mpdf\MpdfException('Error in barcode string: ' $codestr);
  23211.         }
  23212.         if ((($btype === 'EAN13' || $btype === 'ISBN' || $btype === 'ISSN') && strlen($code) === 12)
  23213.                 || ($btype == 'UPCA' && strlen($code) === 11)
  23214.                 || ($btype == 'UPCE' && strlen($code) === 11)
  23215.                 || ($btype == 'EAN8' && strlen($code) === 7)) {
  23216.             $code .= $arrcode['checkdigit'];
  23217.             if (stristr($codestr'-')) {
  23218.                 $codestr .= '-' $arrcode['checkdigit'];
  23219.             } else {
  23220.                 $codestr .= $arrcode['checkdigit'];
  23221.             }
  23222.         }
  23223.         if ($btype === 'ISBN') {
  23224.             $codestr 'ISBN ' $codestr;
  23225.         }
  23226.         if ($btype === 'ISSN') {
  23227.             $codestr 'ISSN ' $codestr;
  23228.         }
  23229.         if (empty($x)) {
  23230.             $x $this->x;
  23231.         }
  23232.         if (empty($y)) {
  23233.             $y $this->y;
  23234.         }
  23235.         // set foreground color
  23236.         $prevDrawColor $this->DrawColor;
  23237.         $prevTextColor $this->TextColor;
  23238.         $prevFillColor $this->FillColor;
  23239.         $lw $this->LineWidth;
  23240.         $this->SetLineWidth(0.01);
  23241.         $size /= $k// in case resized in a table
  23242.         $xres $arrcode['nom-X'] * $size;
  23243.         $llm $arrcode['lightmL'] * $arrcode['nom-X'] * $size// Left Light margin
  23244.         $rlm $arrcode['lightmR'] * $arrcode['nom-X'] * $size// Right Light margin
  23245.         $bcw = ($arrcode["maxw"] * $xres); // Barcode width = Should always be 31.35mm * $size
  23246.         $fbw $bcw $llm $rlm// Full barcode width incl. light margins
  23247.         $ow $fbw $paddingL $paddingR// Full overall width incl. user-defined padding
  23248.         $fbwi $fbw 2// Full barcode width incl. light margins - 2mm - for isbn string
  23249.         // cf. http://www.gs1uk.org/downloads/bar_code/Bar coding getting it right.pdf
  23250.         $num_height $size;     // Height of numerals
  23251.         $fbh $arrcode['nom-H'] * $size $height;  // Full barcode height incl. numerals
  23252.         $bch $fbh - (1.5 $size);     // Barcode height of bars     (3mm for numerals)
  23253.         if (($btype == 'EAN13' && $showtext) || $btype == 'ISSN' || $btype == 'ISBN') { // Add height for ISBN string + margin from top of bars
  23254.             $tisbnm 1.5 $size// Top margin between isbn (if shown) & bars
  23255.             $codestr_fontsize 2.1 $size;
  23256.             $paddingT += $codestr_fontsize $tisbnm;
  23257.         }
  23258.         $oh $fbh $paddingT $paddingB;  // Full overall height incl. user-defined padding
  23259.         // PRINT border background color
  23260.         $xpos $x;
  23261.         $ypos $y;
  23262.         if ($col) {
  23263.             $this->SetDColor($col);
  23264.             $this->SetTColor($col);
  23265.         } else {
  23266.             $this->SetDColor($this->colorConverter->convert(0$this->PDFAXwarnings));
  23267.             $this->SetTColor($this->colorConverter->convert(0$this->PDFAXwarnings));
  23268.         }
  23269.         if ($bgcol) {
  23270.             $this->SetFColor($bgcol);
  23271.         } else {
  23272.             $this->SetFColor($this->colorConverter->convert(255$this->PDFAXwarnings));
  23273.         }
  23274.         if (!$bgcol && !$col) { // fn. called directly - not via HTML
  23275.             if ($border) {
  23276.                 $fillb 'DF';
  23277.             } else {
  23278.                 $fillb 'F';
  23279.             }
  23280.             $this->Rect($xpos$ypos$ow$oh$fillb);
  23281.         }
  23282.         // PRINT BARS
  23283.         $xpos $x $paddingL $llm;
  23284.         $ypos $y $paddingT;
  23285.         if ($col) {
  23286.             $this->SetFColor($col);
  23287.         } else {
  23288.             $this->SetFColor($this->colorConverter->convert(0$this->PDFAXwarnings));
  23289.         }
  23290.         if ($arrcode !== false) {
  23291.             foreach ($arrcode["bcode"] as $v) {
  23292.                 $bw = ($v["w"] * $xres);
  23293.                 if ($v["t"]) {
  23294.                     // draw a vertical bar
  23295.                     $this->Rect($xpos$ypos$bw$bch'F');
  23296.                 }
  23297.                 $xpos += $bw;
  23298.             }
  23299.         }
  23300.         // print text
  23301.         $prevFontFamily $this->FontFamily;
  23302.         $prevFontStyle $this->FontStyle;
  23303.         $prevFontSizePt $this->FontSizePt;
  23304.         // ISBN string
  23305.         if (($btype === 'EAN13' && $showtext) || $btype === 'ISBN' || $btype === 'ISSN') {
  23306.             if ($this->onlyCoreFonts) {
  23307.                 $this->SetFont('chelvetica');
  23308.             } else {
  23309.                 $this->SetFont('sans');
  23310.             }
  23311.             if ($bgcol) {
  23312.                 $this->SetFColor($bgcol);
  23313.             } else {
  23314.                 $this->SetFColor($this->colorConverter->convert(255$this->PDFAXwarnings));
  23315.             }
  23316.             $this->$x $paddingL 1// 1mm left margin (cf. $fbwi above)
  23317.             // max width is $fbwi
  23318.             $loop 0;
  23319.             while ($loop == 0) {
  23320.                 $this->SetFontSize($codestr_fontsize 1.4 Mpdf::SCALEfalse); // don't write
  23321.                 $sz $this->GetStringWidth($codestr);
  23322.                 if ($sz $fbwi) {
  23323.                     $codestr_fontsize -= 0.1;
  23324.                 } else {
  23325.                     $loop ++;
  23326.                 }
  23327.             }
  23328.             $this->SetFont(''''$codestr_fontsize 1.4 Mpdf::SCALEtruetrue); // * 1.4 because font height is only 7/10 of given mm
  23329.             // WORD SPACING
  23330.             if ($fbwi $sz) {
  23331.                 $xtra $fbwi $sz;
  23332.                 $charspacing $xtra / (strlen($codestr) - 1);
  23333.                 if ($charspacing) {
  23334.                     $this->writer->write(sprintf('BT %.3F Tc ET'$charspacing Mpdf::SCALE));
  23335.                 }
  23336.             }
  23337.             $this->$y $paddingT - ($codestr_fontsize ) - $tisbnm;
  23338.             $this->Cell($fbw$codestr_fontsize$codestr);
  23339.             if ($charspacing) {
  23340.                 $this->writer->write('BT 0 Tc ET');
  23341.             }
  23342.         }
  23343.         // Bottom NUMERALS
  23344.         // mPDF 5.7.4
  23345.         if ($this->onlyCoreFonts) {
  23346.             $this->SetFont('ccourier');
  23347.             $fh 1.3;
  23348.         } else {
  23349.             $this->SetFont('ocrb');
  23350.             $fh 1.06;
  23351.         }
  23352.         $charRO '';
  23353.         if ($btype === 'EAN13' || $btype === 'ISBN' || $btype === 'ISSN') {
  23354.             $outerfontsize 3// Inner fontsize = 3
  23355.             $outerp $xres 4;
  23356.             $innerp $xres 2.5;
  23357.             $textw = ($bcw 0.5) - $outerp $innerp;
  23358.             $chars 6// number of numerals in each half
  23359.             $charLO substr($code01); // Left Outer
  23360.             $charLI substr($code16); // Left Inner
  23361.             $charRI substr($code76); // Right Inner
  23362.             if (!$supplement) {
  23363.                 $charRO '>'// Right Outer
  23364.             }
  23365.         } elseif ($btype === 'UPCA') {
  23366.             $outerfontsize 2.3// Inner fontsize = 3
  23367.             $outerp $xres 10;
  23368.             $innerp $xres 2.5;
  23369.             $textw = ($bcw 0.5) - $outerp $innerp;
  23370.             $chars 5;
  23371.             $charLO substr($code01); // Left Outer
  23372.             $charLI substr($code15); // Left Inner
  23373.             $charRI substr($code65); // Right Inner
  23374.             $charRO substr($code111); // Right Outer
  23375.         } elseif ($btype === 'UPCE') {
  23376.             $outerfontsize 2.3// Inner fontsize = 3
  23377.             $outerp $xres 4;
  23378.             $innerp 0;
  23379.             $textw = ($bcw 0.5) - $outerp $innerp;
  23380.             $chars 3;
  23381.             $upce_code $arrcode['code'];
  23382.             $charLO substr($code01); // Left Outer
  23383.             $charLI substr($upce_code03); // Left Inner
  23384.             $charRI substr($upce_code33); // Right Inner
  23385.             $charRO substr($code111); // Right Outer
  23386.         } elseif ($btype === 'EAN8') {
  23387.             $outerfontsize 3// Inner fontsize = 3
  23388.             $outerp $xres 4;
  23389.             $innerp $xres 2.5;
  23390.             $textw = ($bcw 0.5) - $outerp $innerp;
  23391.             $chars 4;
  23392.             $charLO '<'// Left Outer
  23393.             $charLI substr($code04); // Left Inner
  23394.             $charRI substr($code44); // Right Inner
  23395.             if (!$supplement) {
  23396.                 $charRO '>'// Right Outer
  23397.             }
  23398.         }
  23399.         $this->SetFontSize(($outerfontsize 3) * $fh $size Mpdf::SCALE); // 3mm numerals (FontSize is larger to account for space above/below characters)
  23400.         if (!$this->usingCoreFont) { // character width at 3mm
  23401.             $cw $this->_getCharWidth($this->CurrentFont['cw'], 32) * $fh $size 1000;
  23402.         } else {
  23403.             $cw 600 $fh $size 1000;
  23404.         }
  23405.         // Outer left character
  23406.         $y_text $y $paddingT $bch - ($num_height 2);
  23407.         $y_text_outer $y $paddingT $bch - ($num_height * ($outerfontsize 3) / 2);
  23408.         $this->$x $paddingL - ($cw * ($outerfontsize 3) * 0.1); // 0.1 is correction as char does not fill full width;
  23409.         $this->$y_text_outer;
  23410.         $this->Cell($cw$num_height$charLO);
  23411.         // WORD SPACING for inner chars
  23412.         $xtra $textw - ($cw $chars);
  23413.         $charspacing $xtra / ($chars 1);
  23414.         if ($charspacing) {
  23415.             $this->writer->write(sprintf('BT %.3F Tc ET'$charspacing Mpdf::SCALE));
  23416.         }
  23417.         if ($bgcol) {
  23418.             $this->SetFColor($bgcol);
  23419.         } else {
  23420.             $this->SetFColor($this->colorConverter->convert(255$this->PDFAXwarnings));
  23421.         }
  23422.         $this->SetFontSize($fh $size Mpdf::SCALE); // 3mm numerals (FontSize is larger to account for space above/below characters)
  23423.         // Inner left half characters
  23424.         $this->$x $paddingL $llm $outerp;
  23425.         $this->$y_text;
  23426.         $this->Cell($textw$num_height$charLI00''1);
  23427.         // Inner right half characters
  23428.         $this->$x $paddingL $llm + ($bcw 0.5) + $innerp;
  23429.         $this->$y_text;
  23430.         $this->Cell($textw$num_height$charRI00''1);
  23431.         if ($charspacing) {
  23432.             $this->writer->write('BT 0 Tc ET');
  23433.         }
  23434.         // Outer Right character
  23435.         $this->SetFontSize(($outerfontsize 3) * $fh $size Mpdf::SCALE); // 3mm numerals (FontSize is larger to account for space above/below characters)
  23436.         $this->$x $paddingL $llm $bcw $rlm - ($cw * ($outerfontsize 3) * 0.9); // 0.9 is correction as char does not fill full width
  23437.         $this->$y_text_outer;
  23438.         $this->Cell($cw * ($outerfontsize 3), $num_height$charRO00'R');
  23439.         if ($supplement) { // EAN-2 or -5 Supplement
  23440.             // PRINT BARS
  23441.             $supparrcode $this->barcode->getBarcodeArray($supplement_code'EAN' $supplement);
  23442.             if ($supparrcode === false) {
  23443.                 throw new \Mpdf\MpdfException('Error in barcode string (supplement): ' $codestr ' ' $supplement_code);
  23444.             }
  23445.             if (strlen($supplement_code) != $supplement) {
  23446.                 throw new \Mpdf\MpdfException('Barcode supplement incorrect: ' $supplement_code);
  23447.             }
  23448.             $llm $fbw - (($arrcode['lightmR'] - $supparrcode['sepM']) * $arrcode['nom-X'] * $size); // Left Light margin
  23449.             $rlm $arrcode['lightmR'] * $arrcode['nom-X'] * $size// Right Light margin
  23450.             $bcw = ($supparrcode["maxw"] * $xres); // Barcode width = Should always be 31.35mm * $size
  23451.             $fbw $bcw $llm $rlm// Full barcode width incl. light margins
  23452.             $ow $fbw $paddingL $paddingR// Full overall width incl. user-defined padding
  23453.             $bch $fbh - (1.5 $size) - ($num_height 0.5);  // Barcode height of bars     (3mm for numerals)
  23454.             $xpos $x $paddingL $llm;
  23455.             $ypos $y $paddingT $num_height 0.5;
  23456.             if ($col) {
  23457.                 $this->SetFColor($col);
  23458.             } else {
  23459.                 $this->SetFColor($this->colorConverter->convert(0$this->PDFAXwarnings));
  23460.             }
  23461.             if ($supparrcode !== false) {
  23462.                 foreach ($supparrcode["bcode"] as $v) {
  23463.                     $bw = ($v["w"] * $xres);
  23464.                     if ($v["t"]) {
  23465.                         // draw a vertical bar
  23466.                         $this->Rect($xpos$ypos$bw$bch'F');
  23467.                     }
  23468.                     $xpos += $bw;
  23469.                 }
  23470.             }
  23471.             // Characters
  23472.             if ($bgcol) {
  23473.                 $this->SetFColor($bgcol);
  23474.             } else {
  23475.                 $this->SetFColor($this->colorConverter->convert(255$this->PDFAXwarnings));
  23476.             }
  23477.             $this->SetFontSize($fh $size Mpdf::SCALE); // 3mm numerals (FontSize is larger to account for space above/below characters)
  23478.             $this->$x $paddingL $llm;
  23479.             $this->$y $paddingT;
  23480.             $this->Cell($bcw$num_height$supplement_code00'C');
  23481.             // Outer Right character (light margin)
  23482.             $this->SetFontSize(($outerfontsize 3) * $fh $size Mpdf::SCALE); // 3mm numerals (FontSize is larger to account for space above/below characters)
  23483.             $this->$x $paddingL $llm $bcw $rlm - ($cw 0.9); // 0.9 is correction as char does not fill full width
  23484.             $this->$y $paddingT;
  23485.             $this->Cell($cw * ($outerfontsize 3), $num_height'>'00'R');
  23486.         }
  23487.         // Restore **************
  23488.         $this->SetFont($prevFontFamily$prevFontStyle$prevFontSizePt);
  23489.         $this->DrawColor $prevDrawColor;
  23490.         $this->TextColor $prevTextColor;
  23491.         $this->FillColor $prevFillColor;
  23492.         $this->SetLineWidth($lw);
  23493.         $this->SetY($y);
  23494.     }
  23495.     /**
  23496.      * POSTAL and OTHER barcodes
  23497.      */
  23498.     function WriteBarcode2($code$x ''$y ''$size 1$height 1$bgcol false$col false$btype 'IMB'$print_ratio ''$k 1$quiet_zone_left null$quiet_zone_right null)
  23499.     {
  23500.         if (empty($code)) {
  23501.             return;
  23502.         }
  23503.         $this->barcode = new Barcode();
  23504.         $arrcode $this->barcode->getBarcodeArray($code$btype$print_ratio$quiet_zone_left$quiet_zone_right);
  23505.         if (empty($x)) {
  23506.             $x $this->x;
  23507.         }
  23508.         if (empty($y)) {
  23509.             $y $this->y;
  23510.         }
  23511.         $prevDrawColor $this->DrawColor;
  23512.         $prevTextColor $this->TextColor;
  23513.         $prevFillColor $this->FillColor;
  23514.         $lw $this->LineWidth;
  23515.         $this->SetLineWidth(0.01);
  23516.         $size /= $k// in case resized in a table
  23517.         $xres $arrcode['nom-X'] * $size;
  23518.         if ($btype === 'IMB' || $btype === 'RM4SCC' || $btype === 'KIX' || $btype === 'POSTNET' || $btype === 'PLANET') {
  23519.             $llm $arrcode['quietL'] / $k// Left Quiet margin
  23520.             $rlm $arrcode['quietR'] / $k// Right Quiet margin
  23521.             $tlm $blm $arrcode['quietTB'] / $k;
  23522.             $height 1;  // Overrides
  23523.         } elseif (in_array($btype, ['C128A''C128B''C128C''C128RAW''EAN128A''EAN128B''EAN128C''C39''C39+''C39E''C39E+''S25''S25+''I25''I25+''I25B''I25B+''C93''MSI''MSI+''CODABAR''CODE11'])) {
  23524.             $llm $arrcode['lightmL'] * $xres// Left Quiet margin
  23525.             $rlm $arrcode['lightmR'] * $xres// Right Quiet margin
  23526.             $tlm $blm $arrcode['lightTB'] * $xres $height;
  23527.         }
  23528.         $bcw = ($arrcode["maxw"] * $xres);
  23529.         $fbw $bcw $llm $rlm;  // Full barcode width incl. light margins
  23530.         $bch = ($arrcode["nom-H"] * $size $height);
  23531.         $fbh $bch $tlm $blm;  // Full barcode height
  23532.         // PRINT border background color
  23533.         $xpos $x;
  23534.         $ypos $y;
  23535.         if ($col) {
  23536.             $this->SetDColor($col);
  23537.             $this->SetTColor($col);
  23538.         } else {
  23539.             $this->SetDColor($this->colorConverter->convert(0$this->PDFAXwarnings));
  23540.             $this->SetTColor($this->colorConverter->convert(0$this->PDFAXwarnings));
  23541.         }
  23542.         if ($bgcol) {
  23543.             $this->SetFColor($bgcol);
  23544.         } else {
  23545.             $this->SetFColor($this->colorConverter->convert(255$this->PDFAXwarnings));
  23546.         }
  23547.         // PRINT BARS
  23548.         if ($col) {
  23549.             $this->SetFColor($col);
  23550.         } else {
  23551.             $this->SetFColor($this->colorConverter->convert(0$this->PDFAXwarnings));
  23552.         }
  23553.         $xpos $x $llm;
  23554.         if ($arrcode !== false) {
  23555.             foreach ($arrcode["bcode"] as $v) {
  23556.                 $bw = ($v["w"] * $xres);
  23557.                 if ($v["t"]) {
  23558.                     $ypos $y $tlm + ($bch $v['p'] / $arrcode['maxh']);
  23559.                     $this->Rect($xpos$ypos$bw, ($v['h'] * $bch $arrcode['maxh']), 'F');
  23560.                 }
  23561.                 $xpos += $bw;
  23562.             }
  23563.         }
  23564.         // PRINT BEARER BARS
  23565.         if ($btype == 'I25B' || $btype == 'I25B+') {
  23566.             $this->Rect($x$y$fbw, ($arrcode['lightTB'] * $xres $height), 'F');
  23567.             $this->Rect($x$y $tlm $bch$fbw, ($arrcode['lightTB'] * $xres $height), 'F');
  23568.         }
  23569.         // Restore **************
  23570.         $this->DrawColor $prevDrawColor;
  23571.         $this->TextColor $prevTextColor;
  23572.         $this->FillColor $prevFillColor;
  23573.         $this->SetLineWidth($lw);
  23574.         $this->SetY($y);
  23575.     }
  23576.     /* -- END BARCODES -- */
  23577.     function StartTransform($returnstring false)
  23578.     {
  23579.         if ($returnstring) {
  23580.             return('q');
  23581.         } else {
  23582.             $this->writer->write('q');
  23583.         }
  23584.     }
  23585.     function StopTransform($returnstring false)
  23586.     {
  23587.         if ($returnstring) {
  23588.             return('Q');
  23589.         } else {
  23590.             $this->writer->write('Q');
  23591.         }
  23592.     }
  23593.     function transformScale($s_x$s_y$x ''$y ''$returnstring false)
  23594.     {
  23595.         if ($x === '') {
  23596.             $x $this->x;
  23597.         }
  23598.         if ($y === '') {
  23599.             $y $this->y;
  23600.         }
  23601.         if (($s_x == 0) or ( $s_y == 0)) {
  23602.             throw new \Mpdf\MpdfException('Please do not use values equal to zero for scaling');
  23603.         }
  23604.         $y = ($this->$y) * Mpdf::SCALE;
  23605.         $x *= Mpdf::SCALE;
  23606.         // calculate elements of transformation matrix
  23607.         $s_x /= 100;
  23608.         $s_y /= 100;
  23609.         $tm = [];
  23610.         $tm[0] = $s_x;
  23611.         $tm[1] = 0;
  23612.         $tm[2] = 0;
  23613.         $tm[3] = $s_y;
  23614.         $tm[4] = $x * ($s_x);
  23615.         $tm[5] = $y * ($s_y);
  23616.         // scale the coordinate system
  23617.         if ($returnstring) {
  23618.             return($this->_transform($tmtrue));
  23619.         } else {
  23620.             $this->_transform($tm);
  23621.         }
  23622.     }
  23623.     function transformTranslate($t_x$t_y$returnstring false)
  23624.     {
  23625.         // calculate elements of transformation matrix
  23626.         $tm = [];
  23627.         $tm[0] = 1;
  23628.         $tm[1] = 0;
  23629.         $tm[2] = 0;
  23630.         $tm[3] = 1;
  23631.         $tm[4] = $t_x Mpdf::SCALE;
  23632.         $tm[5] = -$t_y Mpdf::SCALE;
  23633.         // translate the coordinate system
  23634.         if ($returnstring) {
  23635.             return($this->_transform($tmtrue));
  23636.         } else {
  23637.             $this->_transform($tm);
  23638.         }
  23639.     }
  23640.     function transformRotate($angle$x ''$y ''$returnstring false)
  23641.     {
  23642.         if ($x === '') {
  23643.             $x $this->x;
  23644.         }
  23645.         if ($y === '') {
  23646.             $y $this->y;
  23647.         }
  23648.         $angle = -$angle;
  23649.         $y = ($this->$y) * Mpdf::SCALE;
  23650.         $x *= Mpdf::SCALE;
  23651.         // calculate elements of transformation matrix
  23652.         $tm = [];
  23653.         $tm[0] = cos(deg2rad($angle));
  23654.         $tm[1] = sin(deg2rad($angle));
  23655.         $tm[2] = -$tm[1];
  23656.         $tm[3] = $tm[0];
  23657.         $tm[4] = $x $tm[1] * $y $tm[0] * $x;
  23658.         $tm[5] = $y $tm[0] * $y $tm[1] * $x;
  23659.         // rotate the coordinate system around ($x,$y)
  23660.         if ($returnstring) {
  23661.             return $this->_transform($tmtrue);
  23662.         } else {
  23663.             $this->_transform($tm);
  23664.         }
  23665.     }
  23666.     /**
  23667.      * mPDF 5.7.3 TRANSFORMS
  23668.      */
  23669.     function transformSkew($angle_x$angle_y$x ''$y ''$returnstring false)
  23670.     {
  23671.         if ($x === '') {
  23672.             $x $this->x;
  23673.         }
  23674.         if ($y === '') {
  23675.             $y $this->y;
  23676.         }
  23677.         $angle_x = -$angle_x;
  23678.         $angle_y = -$angle_y;
  23679.         $x *= Mpdf::SCALE;
  23680.         $y = ($this->$y) * Mpdf::SCALE;
  23681.         // calculate elements of transformation matrix
  23682.         $tm = [];
  23683.         $tm[0] = 1;
  23684.         $tm[1] = tan(deg2rad($angle_y));
  23685.         $tm[2] = tan(deg2rad($angle_x));
  23686.         $tm[3] = 1;
  23687.         $tm[4] = -$tm[2] * $y;
  23688.         $tm[5] = -$tm[1] * $x;
  23689.         // skew the coordinate system
  23690.         if ($returnstring) {
  23691.             return $this->_transform($tmtrue);
  23692.         } else {
  23693.             $this->_transform($tm);
  23694.         }
  23695.     }
  23696.     function _transform($tm$returnstring false)
  23697.     {
  23698.         if ($returnstring) {
  23699.             return(sprintf('%.4F %.4F %.4F %.4F %.4F %.4F cm'$tm[0], $tm[1], $tm[2], $tm[3], $tm[4], $tm[5]));
  23700.         } else {
  23701.             $this->writer->write(sprintf('%.4F %.4F %.4F %.4F %.4F %.4F cm'$tm[0], $tm[1], $tm[2], $tm[3], $tm[4], $tm[5]));
  23702.         }
  23703.     }
  23704.     // AUTOFONT =========================
  23705.     function markScriptToLang($html)
  23706.     {
  23707.         if ($this->onlyCoreFonts) {
  23708.             return $html;
  23709.         }
  23710.         $n '';
  23711.         $a preg_split('/<(.*?)>/ms'$html, -1PREG_SPLIT_DELIM_CAPTURE);
  23712.         foreach ($a as $i => $e) {
  23713.             if ($i == 0) {
  23714.                 // ignore if in Textarea
  23715.                 if ($i && strtolower(substr($a[$i 1], 18)) == 'textarea') {
  23716.                     $a[$i] = $e;
  23717.                     continue;
  23718.                 }
  23719.                 $e UtfString::strcode2utf($e);
  23720.                 $e $this->lesser_entity_decode($e);
  23721.                 $earr $this->UTF8StringToArray($efalse);
  23722.                 $scriptblock 0;
  23723.                 $scriptblocks = [];
  23724.                 $scriptblocks[0] = 0;
  23725.                 $chardata = [];
  23726.                 $subchunk 0;
  23727.                 $charctr 0;
  23728.                 foreach ($earr as $char) {
  23729.                     $ucd_record Ucdn::get_ucd_record($char);
  23730.                     $sbl $ucd_record[6];
  23731.                     if ($sbl && $sbl != 40 && $sbl != 102) {
  23732.                         if ($scriptblock == 0) {
  23733.                             $scriptblock $sbl;
  23734.                             $scriptblocks[$subchunk] = $scriptblock;
  23735.                         } elseif ($scriptblock && $scriptblock != $sbl) {
  23736.                             // NEW (non-common) Script encountered in this chunk.
  23737.                             // Start a new subchunk
  23738.                             $subchunk++;
  23739.                             $scriptblock $sbl;
  23740.                             $charctr 0;
  23741.                             $scriptblocks[$subchunk] = $scriptblock;
  23742.                         }
  23743.                     }
  23744.                     $chardata[$subchunk][$charctr]['script'] = $sbl;
  23745.                     $chardata[$subchunk][$charctr]['uni'] = $char;
  23746.                     $charctr++;
  23747.                 }
  23748.                 // If scriptblock[x] = common & non-baseScript
  23749.                 // and scriptblock[x+1] = baseScript
  23750.                 // Move common script from end of x to start of x+1
  23751.                 for ($sch 0$sch $subchunk$sch++) {
  23752.                     if ($scriptblocks[$sch] > && $scriptblocks[$sch] != $this->baseScript && $scriptblocks[$sch 1] == $this->baseScript) {
  23753.                         $end count($chardata[$sch]) - 1;
  23754.                         while ($chardata[$sch][$end]['script'] == && $end 1) { // common script
  23755.                             $tmp array_pop($chardata[$sch]);
  23756.                             array_unshift($chardata[$sch 1], $tmp);
  23757.                             $end--;
  23758.                         }
  23759.                     }
  23760.                 }
  23761.                 $o '';
  23762.                 for ($sch 0$sch <= $subchunk$sch++) {
  23763.                     if (isset($chardata[$sch])) {
  23764.                         $s '';
  23765.                         for ($j 0$j count($chardata[$sch]); $j++) {
  23766.                             $s .= UtfString::code2utf($chardata[$sch][$j]['uni']);
  23767.                         }
  23768.                         // ZZZ99 Undo lesser_entity_decode as above - but only for <>&
  23769.                         $s str_replace("&""&amp;"$s);
  23770.                         $s str_replace("<""&lt;"$s);
  23771.                         $s str_replace(">""&gt;"$s);
  23772.                         // Check Vietnamese if Latin script - even if Basescript
  23773.                         if ($scriptblocks[$sch] == Ucdn::SCRIPT_LATIN && $this->autoVietnamese && preg_match("/([" $this->scriptToLanguage->getLanguageDelimiters('viet') . "])/u"$s)) {
  23774.                             $o .= '<span lang="vi" class="lang_vi">' $s '</span>';
  23775.                         } elseif ($scriptblocks[$sch] == Ucdn::SCRIPT_ARABIC && $this->autoArabic) { // Check Arabic for different languages if Arabic script - even if Basescript
  23776.                             if (preg_match("/[" $this->scriptToLanguage->getLanguageDelimiters('sindhi') . "]/u"$s)) {
  23777.                                 $o .= '<span lang="sd" class="lang_sd">' $s '</span>';
  23778.                             } elseif (preg_match("/[" $this->scriptToLanguage->getLanguageDelimiters('urdu') . "]/u"$s)) {
  23779.                                 $o .= '<span lang="ur" class="lang_ur">' $s '</span>';
  23780.                             } elseif (preg_match("/[" $this->scriptToLanguage->getLanguageDelimiters('pashto') . "]/u"$s)) {
  23781.                                 $o .= '<span lang="ps" class="lang_ps">' $s '</span>';
  23782.                             } elseif (preg_match("/[" $this->scriptToLanguage->getLanguageDelimiters('persian') . "]/u"$s)) {
  23783.                                 $o .= '<span lang="fa" class="lang_fa">' $s '</span>';
  23784.                             } elseif ($this->baseScript != Ucdn::SCRIPT_ARABIC && $this->scriptToLanguage->getLanguageByScript($scriptblocks[$sch])) {
  23785.                                 $o .= '<span lang="' $this->scriptToLanguage->getLanguageByScript($scriptblocks[$sch]) . '" class="lang_' $this->scriptToLanguage->getLanguageByScript($scriptblocks[$sch]) . '">' $s '</span>';
  23786.                             } else {
  23787.                                 // Just output chars
  23788.                                 $o .= $s;
  23789.                             }
  23790.                         } elseif ($scriptblocks[$sch] > && $scriptblocks[$sch] != $this->baseScript && $this->scriptToLanguage->getLanguageByScript($scriptblocks[$sch])) { // Identify Script block if not Basescript, and mark up as language
  23791.                             // Encase in <span>
  23792.                             $o .= '<span lang="' $this->scriptToLanguage->getLanguageByScript($scriptblocks[$sch]) . '" class="lang_' $this->scriptToLanguage->getLanguageByScript($scriptblocks[$sch]) . '">';
  23793.                             $o .= $s;
  23794.                             $o .= '</span>';
  23795.                         } else {
  23796.                             // Just output chars
  23797.                             $o .= $s;
  23798.                         }
  23799.                     }
  23800.                 }
  23801.                 $a[$i] = $o;
  23802.             } else {
  23803.                 $a[$i] = '<' $e '>';
  23804.             }
  23805.         }
  23806.         $n implode(''$a);
  23807.         return $n;
  23808.     }
  23809.     /* -- COLUMNS -- */
  23810.     /**
  23811.      * Callback function from function printcolumnbuffer in mpdf
  23812.      */
  23813.     function columnAdjustAdd($type$k$xadj$yadj$a$b$c 0$d 0$e 0$f 0)
  23814.     {
  23815.         if ($type === 'Td') {  // xpos,ypos
  23816.             $a += ($xadj $k);
  23817.             $b -= ($yadj $k);
  23818.             return 'BT ' sprintf('%.3F %.3F'$a$b) . ' Td';
  23819.         } elseif ($type === 're') {  // xpos,ypos,width,height
  23820.             $a += ($xadj $k);
  23821.             $b -= ($yadj $k);
  23822.             return sprintf('%.3F %.3F %.3F %.3F'$a$b$c$d) . ' re';
  23823.         } elseif ($type === 'l') {  // xpos,ypos,x2pos,y2pos
  23824.             $a += ($xadj $k);
  23825.             $b -= ($yadj $k);
  23826.             return sprintf('%.3F %.3F l'$a$b);
  23827.         } elseif ($type === 'img') {  // width,height,xpos,ypos
  23828.             $c += ($xadj $k);
  23829.             $d -= ($yadj $k);
  23830.             return sprintf('q %.3F 0 0 %.3F %.3F %.3F'$a$b$c$d) . ' cm /' $e;
  23831.         } elseif ($type === 'draw') {  // xpos,ypos
  23832.             $a += ($xadj $k);
  23833.             $b -= ($yadj $k);
  23834.             return sprintf('%.3F %.3F m'$a$b);
  23835.         } elseif ($type === 'bezier') {  // xpos,ypos,x2pos,y2pos,x3pos,y3pos
  23836.             $a += ($xadj $k);
  23837.             $b -= ($yadj $k);
  23838.             $c += ($xadj $k);
  23839.             $d -= ($yadj $k);
  23840.             $e += ($xadj $k);
  23841.             $f -= ($yadj $k);
  23842.             return sprintf('%.3F %.3F %.3F %.3F %.3F %.3F'$a$b$c$d$e$f) . ' c';
  23843.         }
  23844.     }
  23845.     /* -- END COLUMNS -- */
  23846.     // mPDF 5.7.3 TRANSFORMS
  23847.     function ConvertAngle($s$makepositive true)
  23848.     {
  23849.         if (preg_match('/([\-]*[0-9\.]+)(deg|grad|rad)/i'$s$m)) {
  23850.             $angle $m[1] + 0;
  23851.             if (strtolower($m[2]) == 'deg') {
  23852.                 $angle $angle;
  23853.             } elseif (strtolower($m[2]) == 'grad') {
  23854.                 $angle *= (360 400);
  23855.             } elseif (strtolower($m[2]) == 'rad') {
  23856.                 $angle rad2deg($angle);
  23857.             }
  23858.             while ($angle >= 360) {
  23859.                 $angle -= 360;
  23860.             }
  23861.             while ($angle <= -360) {
  23862.                 $angle += 360;
  23863.             }
  23864.             if ($makepositive) { // always returns an angle between 0 and 360deg
  23865.                 if ($angle 0) {
  23866.                     $angle += 360;
  23867.                 }
  23868.             }
  23869.         } else {
  23870.             $angle $s 0;
  23871.         }
  23872.         return $angle;
  23873.     }
  23874.     function lesser_entity_decode($html)
  23875.     {
  23876.         // supports the most used entity codes (only does ascii safe characters)
  23877.         $html str_replace("&lt;""<"$html);
  23878.         $html str_replace("&gt;"">"$html);
  23879.         $html str_replace("&apos;""'"$html);
  23880.         $html str_replace("&quot;"'"'$html);
  23881.         $html str_replace("&amp;""&"$html);
  23882.         return $html;
  23883.     }
  23884.     function AdjustHTML($html$tabSpaces 8)
  23885.     {
  23886.         $limit ini_get('pcre.backtrack_limit');
  23887.         if (>= (int) $limit) {
  23888.             throw new \Mpdf\MpdfException(sprintf(
  23889.                 'mPDF will not process HTML with disabled pcre.backtrack_limit to prevent unexpected behaviours, please set a positive backtrack limit.',
  23890.                 $limit
  23891.             ));
  23892.         }
  23893.         if (strlen($html) > (int) $limit) {
  23894.             throw new \Mpdf\MpdfException(sprintf(
  23895.                 'The HTML code size is larger than pcre.backtrack_limit %d. You should use WriteHTML() with smaller string lengths. Pass your HTML in smaller chunks.',
  23896.                 $limit
  23897.             ));
  23898.         }
  23899.         preg_match_all("/(<annotation.*?>)/si"$html$m);
  23900.         if (count($m[1])) {
  23901.             for ($i 0$i count($m[1]); $i++) {
  23902.                 $sub preg_replace("/\n/si"Mpdf::OBJECT_IDENTIFIER$m[1][$i]);
  23903.                 $html preg_replace('/' preg_quote($m[1][$i], '/') . '/si'$sub$html);
  23904.             }
  23905.         }
  23906.         preg_match_all("/(<svg.*?<\/svg>)/si"$html$svgi);
  23907.         if (count($svgi[0])) {
  23908.             for ($i 0$i count($svgi[0]); $i++) {
  23909.                 $file $this->cache->write('/_tempSVG' uniqid(random_int(1100000), true) . '_' $i '.svg'$svgi[0][$i]);
  23910.                 $html str_replace($svgi[0][$i], '<img src="' $file '" />'$html);
  23911.             }
  23912.         }
  23913.         // Remove javascript code from HTML (should not appear in the PDF file)
  23914.         $html preg_replace('/<script.*?<\/script>/is'''$html);
  23915.         // Remove special comments
  23916.         $html preg_replace('/<!--mpdf/i'''$html);
  23917.         $html preg_replace('/mpdf-->/i'''$html);
  23918.         // Remove comments from HTML (should not appear in the PDF file)
  23919.         $html preg_replace('/<!--.*?-->/s'''$html);
  23920.         $html preg_replace('/\f/'''$html); // replace formfeed by nothing
  23921.         $html preg_replace('/\r/'''$html); // replace carriage return by nothing
  23922.         // Well formed XHTML end tags
  23923.         $html preg_replace('/<(br|hr)>/i'"<\\1 />"$html); // mPDF 6
  23924.         $html preg_replace('/<(br|hr)\/>/i'"<\\1 />"$html);
  23925.         // Get rid of empty <thead></thead> etc
  23926.         $html preg_replace('/<tr>\s*<\/tr>/i'''$html);
  23927.         $html preg_replace('/<thead>\s*<\/thead>/i'''$html);
  23928.         $html preg_replace('/<tfoot>\s*<\/tfoot>/i'''$html);
  23929.         $html preg_replace('/<table[^>]*>\s*<\/table>/i'''$html);
  23930.         // Remove spaces at end of table cells
  23931.         $html preg_replace("/[ \n\r]+<\/t(d|h)/"'</t\\1'$html);
  23932.         $html preg_replace("/[ ]*<dottab\s*[\/]*>[ ]*/"'<dottab />'$html);
  23933.         // Concatenates any Substitute characters from symbols/dingbats
  23934.         $html str_replace('</tts><tts>''|'$html);
  23935.         $html str_replace('</ttz><ttz>''|'$html);
  23936.         $html str_replace('</tta><tta>''|'$html);
  23937.         $html preg_replace('/<br \/>\s*/is'"<br />"$html);
  23938.         $html preg_replace('/<wbr[ \/]*>\s*/is'"&#173;"$html);
  23939.         // Preserve '\n's in content between the tags <pre> and </pre>
  23940.         if (preg_match('/<pre/'$html)) {
  23941.             $html_a preg_split('/(\<\/?pre[^\>]*\>)/'$html, -12);
  23942.             $h = [];
  23943.             $c 0;
  23944.             foreach ($html_a as $s) {
  23945.                 if ($c && preg_match('/^<\/pre/i'$s)) {
  23946.                     $c--;
  23947.                     $s preg_replace('/<\/pre/i''</innerpre'$s);
  23948.                 } elseif ($c && preg_match('/^<pre/i'$s)) {
  23949.                     $c++;
  23950.                     $s preg_replace('/<pre/i''<innerpre'$s);
  23951.                 } elseif (preg_match('/^<pre/i'$s)) {
  23952.                     $c++;
  23953.                 } elseif (preg_match('/^<\/pre/i'$s)) {
  23954.                     $c--;
  23955.                 }
  23956.                 array_push($h$s);
  23957.             }
  23958.             $html implode(''$h);
  23959.         }
  23960.         $thereispre preg_match_all('#<pre(.*?)>(.*?)</pre>#si'$html$temp);
  23961.         // Preserve '\n's in content between the tags <textarea> and </textarea>
  23962.         $thereistextarea preg_match_all('#<textarea(.*?)>(.*?)</textarea>#si'$html$temp2);
  23963.         $html preg_replace('/[\n]/'' '$html); // replace linefeed by spaces
  23964.         $html preg_replace('/[\t]/'' '$html); // replace tabs by spaces
  23965.         // Converts < to &lt; when not a tag
  23966.         $html preg_replace('/<([^!\/a-zA-Z_:])/i''&lt;\\1'$html); // mPDF 5.7.3
  23967.         $html preg_replace("/[ ]+/"' '$html);
  23968.         $html preg_replace('/\/li>\s+<\/(u|o)l/i''/li></\\1l'$html);
  23969.         $html preg_replace('/\/(u|o)l>\s+<\/li/i''/\\1l></li'$html);
  23970.         $html preg_replace('/\/li>\s+<\/(u|o)l/i''/li></\\1l'$html);
  23971.         $html preg_replace('/\/li>\s+<li/i''/li><li'$html);
  23972.         $html preg_replace('/<(u|o)l([^>]*)>[ ]+/i''<\\1l\\2>'$html);
  23973.         $html preg_replace('/[ ]+<(u|o)l/i''<\\1l'$html);
  23974.         // Make self closing tabs valid XHTML
  23975.         // Tags which are self-closing: 1) Replaceable and 2) Non-replaced items
  23976.         $selftabs 'input|hr|img|br|barcode|dottab';
  23977.         $selftabs2 'indexentry|indexinsert|bookmark|watermarktext|watermarkimage|column_break|columnbreak|newcolumn|newpage|page_break|pagebreak|formfeed|columns|toc|tocpagebreak|setpageheader|setpagefooter|sethtmlpageheader|sethtmlpagefooter|annotation';
  23978.         // Fix self-closing tags which don't close themselves
  23979.         $html preg_replace('/(<(' $selftabs '|' $selftabs2 ')[^>\/]*)>/i''\\1 />'$html);
  23980.         // Fix self-closing tags that don't include a space between the tag name and the closing slash
  23981.         $html preg_replace('/(<(' $selftabs '|' $selftabs2 '))\/>/i''\\1 />'$html);
  23982.         $iterator 0;
  23983.         while ($thereispre) { // Recover <pre attributes>content</pre>
  23984.             $temp[2][$iterator] = preg_replace('/<([^!\/a-zA-Z_:])/''&lt;\\1'$temp[2][$iterator]); // mPDF 5.7.2    // mPDF 5.7.3
  23985.             $temp[2][$iterator] = preg_replace_callback("/^([^\n\t]*?)\t/m", [$this'tabs2spaces_callback'], $temp[2][$iterator]); // mPDF 5.7+
  23986.             $temp[2][$iterator] = preg_replace('/\t/'str_repeat(" "$tabSpaces), $temp[2][$iterator]);
  23987.             $temp[2][$iterator] = preg_replace('/\n/'"<br />"$temp[2][$iterator]);
  23988.             $temp[2][$iterator] = str_replace('\\'"\\\\"$temp[2][$iterator]);
  23989.             // $html = preg_replace('#<pre(.*?)>(.*?)</pre>#si','<erp'.$temp[1][$iterator].'>'.$temp[2][$iterator].'</erp>',$html,1);
  23990.             $html preg_replace('#<pre(.*?)>(.*?)</pre>#si''<erp' $temp[1][$iterator] . '>' str_replace('$''\$'$temp[2][$iterator]) . '</erp>'$html1); // mPDF 5.7+
  23991.             $thereispre--;
  23992.             $iterator++;
  23993.         }
  23994.         $iterator 0;
  23995.         while ($thereistextarea) { // Recover <textarea attributes>content</textarea>
  23996.             $temp2[2][$iterator] = preg_replace('/\t/'str_repeat(" "$tabSpaces), $temp2[2][$iterator]);
  23997.             $temp2[2][$iterator] = str_replace('\\'"\\\\"$temp2[2][$iterator]);
  23998.             $html preg_replace('#<textarea(.*?)>(.*?)</textarea>#si''<aeratxet' $temp2[1][$iterator] . '>' trim($temp2[2][$iterator]) . '</aeratxet>'$html1);
  23999.             $thereistextarea--;
  24000.             $iterator++;
  24001.         }
  24002.         // Restore original tag names
  24003.         $html str_replace("<erp""<pre"$html);
  24004.         $html str_replace("</erp>""</pre>"$html);
  24005.         $html str_replace("<aeratxet""<textarea"$html);
  24006.         $html str_replace("</aeratxet>""</textarea>"$html);
  24007.         $html str_replace("</innerpre""</pre"$html);
  24008.         $html str_replace("<innerpre""<pre"$html);
  24009.         $html preg_replace('/<textarea([^>]*)><\/textarea>/si''<textarea\\1> </textarea>'$html);
  24010.         $html preg_replace('/(<table[^>]*>)\s*(<caption)(.*?<\/caption>)(.*?<\/table>)/si''\\2 position="top"\\3\\1\\4\\2 position="bottom"\\3'$html); // *TABLES*
  24011.         if ($this->use_kwt) {
  24012.             $returnHtml preg_replace('/<(h[1-6])([^>]*(?<!\/))(>[^>]*<\/\\1>\s*<table)/si''<\\1\\2 keep-with-table="1"\\3'$html);
  24013.             /* If no errors then save the return value */
  24014.             if (preg_last_error() === PREG_NO_ERROR) {
  24015.                 $html $returnHtml;
  24016.             }
  24017.         }
  24018.         $html preg_replace('/' Mpdf::OBJECT_IDENTIFIER '/'"\n"$html);
  24019.         // Fixes <p>&#8377</p> which browser copes with even though it is wrong!
  24020.         $html preg_replace("/(&#[x]{0,1}[0-9a-f]{1,5})</i""\\1;<"$html);
  24021.         return $html;
  24022.     }
  24023.     // mPDF 5.7+
  24024.     function tabs2spaces_callback($matches)
  24025.     {
  24026.         return (stripslashes($matches[1]) . str_repeat(' '$this->tabSpaces - (mb_strlen(stripslashes($matches[1])) % $this->tabSpaces)));
  24027.     }
  24028.     // mPDF 5.7+
  24029.     function date_callback($matches)
  24030.     {
  24031.         return date($matches[1]);
  24032.     }
  24033.     // ========== OVERWRITE SEARCH STRING IN A PDF FILE ================
  24034.     function OverWrite($file_in$search$replacement$dest Destination::DOWNLOAD$file_out "mpdf")
  24035.     {
  24036.         $pdf file_get_contents($file_in);
  24037.         if (!is_array($search)) {
  24038.             $x $search;
  24039.             $search = [$x];
  24040.         }
  24041.         if (!is_array($replacement)) {
  24042.             $x $replacement;
  24043.             $replacement = [$x]; // mPDF 5.7.4
  24044.         }
  24045.         if (!$this->onlyCoreFonts && !$this->usingCoreFont) {
  24046.             foreach ($search as $k => $val) {
  24047.                 $search[$k] = $this->writer->utf8ToUtf16BigEndian($search[$k], false);
  24048.                 $search[$k] = $this->writer->escape($search[$k]);
  24049.                 $replacement[$k] = $this->writer->utf8ToUtf16BigEndian($replacement[$k], false);
  24050.                 $replacement[$k] = $this->writer->escape($replacement[$k]);
  24051.             }
  24052.         } else {
  24053.             foreach ($replacement as $k => $val) {
  24054.                 $replacement[$k] = mb_convert_encoding($replacement[$k], $this->mb_enc'utf-8');
  24055.                 $replacement[$k] = $this->writer->escape($replacement[$k]);
  24056.             }
  24057.         }
  24058.         // Get xref into array
  24059.         $xref = [];
  24060.         preg_match("/xref\n0 (\d+)\n(.*?)\ntrailer/s"$pdf$m);
  24061.         $xref_objid $m[1];
  24062.         preg_match_all('/(\d{10}) (\d{5}) (f|n)/'$m[2], $x);
  24063.         for ($i 0$i count($x[0]); $i++) {
  24064.             $xref[] = [(int) $x[1][$i], $x[2][$i], $x[3][$i]];
  24065.         }
  24066.         $changes = [];
  24067.         preg_match("/<<\s*\/Type\s*\/Pages\s*\/Kids\s*\[(.*?)\]\s*\/Count/s"$pdf$m);
  24068.         preg_match_all("/(\d+) 0 R /s"$m[1], $o);
  24069.         $objlist $o[1];
  24070.         foreach ($objlist as $obj) {
  24071.             if ($this->compress) {
  24072.                 preg_match("/" . ($obj 1) . " 0 obj\n<<\s*\/Filter\s*\/FlateDecode\s*\/Length (\d+)>>\nstream\n(.*?)\nendstream\n/s"$pdf$m);
  24073.             } else {
  24074.                 preg_match("/" . ($obj 1) . " 0 obj\n<<\s*\/Length (\d+)>>\nstream\n(.*?)\nendstream\n/s"$pdf$m);
  24075.             }
  24076.             $s $m[2];
  24077.             if (!$s) {
  24078.                 continue;
  24079.             }
  24080.             $oldlen $m[1];
  24081.             if ($this->encrypted) {
  24082.                 $s $this->protection->rc4($this->protection->objectKey($obj 1), $s);
  24083.             }
  24084.             if ($this->compress) {
  24085.                 $s gzuncompress($s);
  24086.             }
  24087.             foreach ($search as $k => $val) {
  24088.                 $s str_replace($search[$k], $replacement[$k], $s);
  24089.             }
  24090.             if ($this->compress) {
  24091.                 $s gzcompress($s);
  24092.             }
  24093.             if ($this->encrypted) {
  24094.                 $s $this->protection->rc4($this->protection->objectKey($obj 1), $s);
  24095.             }
  24096.             $newlen strlen($s);
  24097.             $changes[($xref[$obj 1][0])] = ($newlen $oldlen) + (strlen($newlen) - strlen($oldlen));
  24098.             if ($this->compress) {
  24099.                 $newstr = ($obj 1) . " 0 obj\n<</Filter /FlateDecode /Length " $newlen ">>\nstream\n" $s "\nendstream\n";
  24100.             } else {
  24101.                 $newstr = ($obj 1) . " 0 obj\n<</Length " $newlen ">>\nstream\n" $s "\nendstream\n";
  24102.             }
  24103.             $pdf str_replace($m[0], $newstr$pdf);
  24104.         }
  24105.         // Update xref in PDF
  24106.         krsort($changes);
  24107.         $newxref "xref\n0 " $xref_objid "\n";
  24108.         foreach ($xref as $v) {
  24109.             foreach ($changes as $ck => $cv) {
  24110.                 if ($v[0] > $ck) {
  24111.                     $v[0] += $cv;
  24112.                 }
  24113.             }
  24114.             $newxref .= sprintf('%010d'$v[0]) . ' ' $v[1] . ' ' $v[2] . " \n";
  24115.         }
  24116.         $newxref .= "trailer";
  24117.         $pdf preg_replace("/xref\n0 \d+\n.*?\ntrailer/s"$newxref$pdf);
  24118.         // Update startxref in PDF
  24119.         preg_match("/startxref\n(\d+)\n%%EOF/s"$pdf$m);
  24120.         $startxref $m[1];
  24121.         $startxref += array_sum($changes);
  24122.         $pdf preg_replace("/startxref\n(\d+)\n%%EOF/s""startxref\n" $startxref "\n%%EOF"$pdf);
  24123.         // OUTPUT
  24124.         switch ($dest) {
  24125.             case Destination::INLINE:
  24126.                 if (isset($_SERVER['SERVER_NAME'])) {
  24127.                     // We send to a browser
  24128.                     header('Content-Type: application/pdf');
  24129.                     header('Content-Length: ' strlen($pdf));
  24130.                     header('Content-disposition: inline; filename=' $file_out);
  24131.                 }
  24132.                 echo $pdf;
  24133.                 break;
  24134.             case Destination::FILE:
  24135.                 if (!$file_out) {
  24136.                     $file_out 'mpdf.pdf';
  24137.                 }
  24138.                 $f fopen($file_out'wb');
  24139.                 if (!$f) {
  24140.                     throw new \Mpdf\MpdfException('Unable to create output file: ' $file_out);
  24141.                 }
  24142.                 fwrite($f$pdfstrlen($pdf));
  24143.                 fclose($f);
  24144.                 break;
  24145.             case Destination::STRING_RETURN:
  24146.                 return $pdf;
  24147.             case Destination::DOWNLOAD// Download file
  24148.             default:
  24149.                 if (isset($_SERVER['HTTP_USER_AGENT']) and strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE')) {
  24150.                     header('Content-Type: application/force-download');
  24151.                 } else {
  24152.                     header('Content-Type: application/octet-stream');
  24153.                 }
  24154.                 header('Content-Length: ' strlen($pdf));
  24155.                 header('Content-disposition: attachment; filename=' $file_out);
  24156.                 echo $pdf;
  24157.                 break;
  24158.         }
  24159.     }
  24160.     function Thumbnail($file$npr 3$spacing 10)
  24161.     {
  24162.         // $npr = number per row
  24163.         $w = (($this->pgwidth $spacing) / $npr) - $spacing;
  24164.         $oldlinewidth $this->LineWidth;
  24165.         $this->SetLineWidth(0.02);
  24166.         $this->SetDColor($this->colorConverter->convert(0$this->PDFAXwarnings));
  24167.         $h 0;
  24168.         $maxh 0;
  24169.         $x $_x $this->lMargin;
  24170.         $_y $this->tMargin;
  24171.         if ($this->== 0) {
  24172.             $y $_y;
  24173.         } else {
  24174.             $y $this->y;
  24175.         }
  24176.         $pagecount $this->setSourceFile($file);
  24177.         for ($n 1$n <= $pagecount$n++) {
  24178.             $tplidx $this->importPage($n);
  24179.             $size $this->useTemplate($tplidx$x$y$w);
  24180.             $this->Rect($x$y$size['width'], $size['height']);
  24181.             $h max($h$size['height']);
  24182.             $maxh max($h$maxh);
  24183.             if ($n $npr == 0) {
  24184.                 if (($y $h $spacing $maxh) > $this->PageBreakTrigger && $n != $pagecount) {
  24185.                     $this->AddPage();
  24186.                     $x $_x;
  24187.                     $y $_y;
  24188.                 } else {
  24189.                     $y += $h $spacing;
  24190.                     $x $_x;
  24191.                     $h 0;
  24192.                 }
  24193.             } else {
  24194.                 $x += $w $spacing;
  24195.             }
  24196.         }
  24197.         $this->SetLineWidth($oldlinewidth);
  24198.     }
  24199.     function SetPageTemplate($tplidx '')
  24200.     {
  24201.         if (!isset($this->importedPages[$tplidx])) {
  24202.             $this->pageTemplate '';
  24203.             return false;
  24204.         }
  24205.         $this->pageTemplate $tplidx;
  24206.     }
  24207.     function SetDocTemplate($file ''$continue 0$continue2pages 0)
  24208.     {
  24209.         $this->docTemplate $file;
  24210.         $this->docTemplateContinue $continue;
  24211.         $this->docTemplateContinue2pages $continue2pages;
  24212.         if ($this->docTemplateContinue2pages) { // Enable continue when continue2pages is set
  24213.             $this->docTemplateContinue $this->docTemplateContinue2pages;
  24214.         }
  24215.     }
  24216.     /* -- END IMPORTS -- */
  24217.     // JAVASCRIPT
  24218.     function _set_object_javascript($string)
  24219.     {
  24220.         $this->writer->object();
  24221.         $this->writer->write('<<');
  24222.         $this->writer->write('/S /JavaScript ');
  24223.         $this->writer->write('/JS ' $this->writer->string($string));
  24224.         $this->writer->write('>>');
  24225.         $this->writer->write('endobj');
  24226.     }
  24227.     function SetJS($script)
  24228.     {
  24229.         $this->js $script;
  24230.     }
  24231.     /**
  24232.      * This function takes the last comma or dot (if any) to make a clean float, ignoring thousand separator, currency or any other letter
  24233.      *
  24234.      * @param string $num
  24235.      * @see http://php.net/manual/de/function.floatval.php#114486
  24236.      * @return float
  24237.      */
  24238.     public function toFloat($num)
  24239.     {
  24240.         $dotPos strrpos($num'.');
  24241.         $commaPos strrpos($num',');
  24242.         $sep = (($dotPos $commaPos) && $dotPos) ? $dotPos : ((($commaPos $dotPos) && $commaPos) ? $commaPos false);
  24243.         if (!$sep) {
  24244.             return floatval(preg_replace('/[^0-9]/'''$num));
  24245.         }
  24246.         return floatval(
  24247.             preg_replace('/[^0-9]/'''substr($num0$sep)) . '.' .
  24248.             preg_replace('/[^0-9]/'''substr($num$sep+1strlen($num)))
  24249.         );
  24250.     }
  24251.     public function getFontDescriptor()
  24252.     {
  24253.         return $this->fontDescriptor;
  24254.     }
  24255.     /**
  24256.      * Temporarily return the method to preserve example 44 yearbook
  24257.      */
  24258.     public function _out($s)
  24259.     {
  24260.         $this->writer->write($s);
  24261.     }
  24262.     /**
  24263.      * @param string $html
  24264.      * @param string $PAGENO
  24265.      * @param string $NbPgGp
  24266.      * @param string $NbPg
  24267.      * @return string
  24268.      */
  24269.     protected function aliasReplace($html$PAGENO$NbPgGp$NbPg)
  24270.     {
  24271.         // Replaces for header and footer
  24272.         $html str_replace('{PAGENO}'$PAGENO$html);
  24273.         $html str_replace($this->aliasNbPgGp$NbPgGp$html); // {nbpg}
  24274.         $html str_replace($this->aliasNbPg$NbPg$html); // {nb}
  24275.         // Replaces for the body
  24276.         $html str_replace(mb_convert_encoding('{PAGENO}''UTF-16BE''UTF-8'), mb_convert_encoding($PAGENO'UTF-16BE''UTF-8'), $html);
  24277.         $html str_replace(mb_convert_encoding($this->aliasNbPgGp'UTF-16BE''UTF-8'), mb_convert_encoding($NbPgGp'UTF-16BE''UTF-8'), $html); // {nbpg}
  24278.         $html str_replace(mb_convert_encoding($this->aliasNbPg'UTF-16BE''UTF-8'), mb_convert_encoding($NbPg'UTF-16BE''UTF-8'), $html); // {nb}
  24279.         // Date replace
  24280.         $html preg_replace_callback('/\{DATE\s+(.*?)\}/', [$this'date_callback'], $html); // mPDF 5.7
  24281.         return $html;
  24282.     }
  24283. }