Lines Matching +full:font +full:- +full:size +(+path:plugin +path:dw2pdf) -(+path:plugin +path:dw2pdf +path:lang)

21  * mPDF, PHP library generating PDF files from UTF-8 encoded HTML
26 * @license GPL-2.0
76 var $PDFAversion = '1-B';
296 // mPDF 5.7.3 inline text-decoration parameters
320 var $docTemplateStart; // Internal flag for page (page no. -1) that docTemplate starts on
351 var $writingHTMLheader; // internal flag - used both for writing HTMLHeaders/Footers and FixedPos block
407 var $pageDim; // Keep track of page wxh for orientation changes - set in _beginpage, used in _putannots
472 // List of ALL available CJK fonts (incl. styles) (Adobe add-ons) hw removed
552 // mPDF 6 Used for table cell (block-type) properties
597 var $keep_block_together; // Keep a Block from page-break-inside: avoid
610 var $extgstates; // Used for alpha channel - Transparency (Watermark)
653 var $shrin_k; // factor with which to shrink tables - used internally - do not change
725 * Set the User-Agent header in the HTTP requests sent by cURL.
747 var $buffer; // buffer holding in-memory PDF
784 var $CoreFonts; // array of standard font names
786 var $FontFiles; // array of font files
793 var $FontFamily; // current font family
794 var $FontStyle; // current font style
795 var $CurrentFont; // current font info
796 var $FontSizePt; // current font size in points
797 var $FontSize; // current font size in user unit
807 var $processingFooter; // flag set when processing footer - added for columns
808 var $processingHeader; // flag set when processing header - added for columns
1034 $this->_dochecks();
1048 ) = $this->initConstructorParams($config);
1050 $this->logger = new NullLogger();
1053 $config = $this->initConfig($originalConfig);
1056 $services = $serviceFactory->getServices(
1058 $this->logger,
1060 $this->restrictColorSpace,
1061 $this->languageToFont,
1062 $this->scriptToLanguage,
1063 $this->fontDescriptor,
1064 $this->bmp,
1065 $this->directWrite,
1066 $this->wmf
1069 $this->services = [];
1072 $this->{$key} = $service;
1073 $this->services[] = $key;
1076 $this->time0 = microtime(true);
1078 $this->writingToC = false;
1080 $this->layers = [];
1081 $this->current_layer = 0;
1082 $this->open_layer_pane = false;
1084 $this->visibility = 'visible';
1086 $this->tableBackgrounds = [];
1087 $this->uniqstr = '20110230'; // mPDF 5.7.2
1088 $this->kt_y00 = 0;
1089 $this->kt_p00 = 0;
1090 $this->BMPonly = [];
1091 $this->page = 0;
1092 $this->n = 2;
1093 $this->buffer = '';
1094 $this->objectbuffer = [];
1095 $this->pages = [];
1096 $this->OrientationChanges = [];
1097 $this->state = 0;
1098 $this->fonts = [];
1099 $this->FontFiles = [];
1100 $this->images = [];
1101 $this->links = [];
1102 $this->InFooter = false;
1103 $this->processingFooter = false;
1104 $this->processingHeader = false;
1105 $this->lasth = 0;
1106 $this->FontFamily = '';
1107 $this->FontStyle = '';
1108 $this->FontSizePt = 9;
1111 $this->inMeter = false;
1112 $this->decimal_offset = 0;
1114 $this->PDFAXwarnings = [];
1116 $this->defTextColor = $this->TextColor = $this->SetTColor($this->colorConverter->convert(0, $this->PDFAXwarnings), true);
1117 $this->defDrawColor = $this->DrawColor = $this->SetDColor($this->colorConverter->convert(0, $this->PDFAXwarnings), true);
1118 $this->defFillColor = $this->FillColor = $this->SetFColor($this->colorConverter->convert(255, $this->PDFAXwarnings), true);
1120 $this->upperCase = require __DIR__ . '/../data/upperCase.php';
1122 $this->extrapagebreak = true; // mPDF 6 pagebreaktype
1124 $this->ColorFlag = false;
1125 $this->extgstates = [];
1127 $this->mb_enc = 'windows-1252';
1128 $this->originalMbEnc = mb_internal_encoding();
1129 $this->originalMbRegexEnc = mb_regex_encoding();
1131 $this->directionality = 'ltr';
1132 $this->defaultAlign = 'L';
1133 $this->defaultTableAlign = 'L';
1135 $this->fixedPosBlockSave = [];
1136 $this->extraFontSubsets = 0;
1138 $this->blockContext = 1;
1139 $this->floatDivs = [];
1140 $this->DisplayPreferences = '';
1143 $this->patterns = [];
1144 $this->pageBackgrounds = [];
1145 $this->gradients = [];
1147 // internal flag - used both for writing HTMLHeaders/Footers and FixedPos block
1148 $this->writingHTMLheader = false;
1149 // internal flag - used both for writing HTMLHeaders/Footers and FixedPos block
1150 $this->writingHTMLfooter = false;
1152 $this->kwt_Reference = [];
1153 $this->kwt_BMoutlines = [];
1154 $this->kwt_toc = [];
1156 $this->tbrot_BMoutlines = [];
1157 $this->tbrot_toc = [];
1159 $this->col_BMoutlines = [];
1160 $this->col_toc = [];
1162 $this->pgsIns = [];
1163 $this->PDFAXwarnings = [];
1164 $this->inlineDisplayOff = false;
1165 $this->lSpacingCSS = '';
1166 $this->wSpacingCSS = '';
1167 $this->fixedlSpacing = false;
1168 $this->minwSpacing = 0;
1171 $this->baselineC = 0.35;
1173 // mPDF 5.7.3 inline text-decoration parameters
1176 $this->baselineSup = 0.5;
1179 $this->baselineSub = -0.2;
1181 $this->baselineS = 0.3;
1183 $this->baselineO = 1.1;
1185 $this->noImageFile = __DIR__ . '/../data/no_image.jpg';
1186 $this->subPos = 0;
1188 $this->fullImageHeight = false;
1189 $this->floatbuffer = [];
1190 $this->floatmargins = [];
1191 $this->formobjects = []; // array of Form Objects for WMF
1192 $this->InlineProperties = [];
1193 $this->InlineAnnots = [];
1194 $this->InlineBDF = []; // mPDF 6
1195 $this->InlineBDFctr = 0; // mPDF 6
1196 $this->tbrot_Annots = [];
1197 $this->kwt_Annots = [];
1198 $this->columnAnnots = [];
1199 $this->PageLinks = [];
1200 $this->OrientationChanges = [];
1201 $this->pageDim = [];
1202 $this->saveHTMLHeader = [];
1203 $this->saveHTMLFooter = [];
1204 $this->PageAnnots = [];
1205 $this->PageNumSubstitutions = [];
1206 $this->breakpoints = []; // used in columnbuffer
1207 $this->tableLevel = 0;
1208 $this->tbctr = []; // counter for nested tables at each level
1209 $this->page_box = [];
1210 $this->show_marks = ''; // crop or cross marks
1211 $this->kwt = false;
1212 $this->kwt_height = 0;
1213 $this->kwt_y0 = 0;
1214 $this->kwt_x0 = 0;
1215 $this->kwt_buffer = [];
1216 $this->kwt_Links = [];
1217 $this->kwt_moved = false;
1218 $this->kwt_saved = false;
1219 $this->PageNumSubstitutions = [];
1220 $this->base_table_properties = [];
1221 $this->borderstyles = ['inset', 'groove', 'outset', 'ridge', 'dotted', 'dashed', 'solid', 'double'];
1222 $this->tbrot_align = 'C';
1224 $this->pageHTMLheaders = [];
1225 $this->pageHTMLfooters = [];
1226 $this->HTMLheaderPageLinks = [];
1227 $this->HTMLheaderPageAnnots = [];
1229 $this->HTMLheaderPageForms = [];
1230 $this->columnForms = [];
1231 $this->tbrotForms = [];
1233 $this->pageoutput = [];
1235 $this->bufferoutput = false;
1237 $this->encrypted = false;
1239 $this->BMoutlines = [];
1240 $this->ColActive = 0; // Flag indicating that columns are on (the index is being processed)
1241 $this->Reference = []; // Array containing the references
1242 $this->CurrCol = 0; // Current column number
1243 $this->ColL = [0]; // Array of Left pos of columns - absolute - needs Margin correction for Odd-Even
1244 $this->ColR = [0]; // Array of Right pos of columns - absolute pos - needs Margin correction for Odd-Even
1245 $this->ChangeColumn = 0;
1246 $this->columnbuffer = [];
1247 $this->ColDetails = []; // Keeps track of some column details
1248 $this->columnLinks = []; // Cross references PageLinks
1249 $this->substitute = []; // Array of substitution strings e.g. <ttz>112</ttz>
1250 $this->entsearch = []; // Array of HTML entities (>ASCII 127) to substitute
1251 $this->entsubstitute = []; // Array of substitution decimal unicode for the Hi entities
1252 $this->lastoptionaltag = '';
1253 $this->charset_in = '';
1254 $this->blk = [];
1255 $this->blklvl = 0;
1256 $this->tts = false;
1257 $this->ttz = false;
1258 $this->tta = false;
1259 $this->ispre = false;
1261 $this->checkSIP = false;
1262 $this->checkSMP = false;
1263 $this->checkCJK = false;
1265 $this->page_break_after_avoid = false;
1266 $this->margin_bottom_collapse = false;
1267 $this->tablethead = 0;
1268 $this->tabletfoot = 0;
1269 $this->table_border_attr_set = 0;
1270 $this->table_border_css_set = 0;
1271 $this->shrin_k = 1.0;
1272 $this->shrink_this_table_to_fit = 0;
1273 $this->MarginCorrection = 0;
1275 $this->tabletheadjustfinished = false;
1276 $this->usingCoreFont = false;
1277 $this->charspacing = 0;
1279 $this->autoPageBreak = true;
1281 $this->_setPageSize($format, $orientation);
1282 $this->DefOrientation = $orientation;
1284 $this->margin_header = $mgh;
1285 $this->margin_footer = $mgf;
1289 $this->DeflMargin = $mgl;
1290 $this->DefrMargin = $mgr;
1292 $this->orig_tMargin = $mgt;
1293 $this->orig_bMargin = $bmargin;
1294 $this->orig_lMargin = $this->DeflMargin;
1295 $this->orig_rMargin = $this->DefrMargin;
1296 $this->orig_hMargin = $this->margin_header;
1297 $this->orig_fMargin = $this->margin_footer;
1299 if ($this->setAutoTopMargin == 'pad') {
1300 $mgt += $this->margin_header;
1302 if ($this->setAutoBottomMargin == 'pad') {
1303 $mgb += $this->margin_footer;
1307 $this->SetMargins($this->DeflMargin, $this->DefrMargin, $mgt);
1310 // sets $this->bMargin & PageBreakTrigger
1311 $this->SetAutoPageBreak($this->autoPageBreak, $bmargin);
1313 $this->pgwidth = $this->w - $this->lMargin - $this->rMargin;
1316 $this->cMarginL = 1;
1317 $this->cMarginR = 1;
1320 $this->LineWidth = .567 / Mpdf::SCALE;
1323 $this->DisableTags();
1325 $this->SetDisplayMode(100); // fullwidth? 'fullpage'
1328 $this->SetCompression(true);
1330 $this->SetDisplayPreferences('');
1332 $this->initFontConfig($originalConfig);
1335 $this->available_unifonts = [];
1336 foreach ($this->fontdata as $f => $fs) {
1338 $this->available_unifonts[] = $f;
1341 $this->available_unifonts[] = $f . 'B';
1344 $this->available_unifonts[] = $f . 'I';
1347 $this->available_unifonts[] = $f . 'BI';
1351 $this->default_available_fonts = $this->available_unifonts;
1355 if (preg_match('/([\-+])aCJK/i', $mode, $m)) {
1356 $mode = preg_replace('/([\-+])aCJK/i', '', $mode); // mPDF 6
1358 $this->useAdobeCJK = true;
1360 $this->useAdobeCJK = false;
1366 $this->percentSubset = 100;
1372 } elseif (substr($mode, -2) == '-s') {
1373 $this->percentSubset = 100;
1374 $mode = substr($mode, 0, strlen($mode) - 2);
1375 } elseif (substr($mode, -2) == '-c') {
1377 $mode = substr($mode, 0, strlen($mode) - 2);
1378 } elseif (substr($mode, -2) == '-x') {
1380 $mode = substr($mode, 0, strlen($mode) - 2);
1383 // Autodetect if mode is a language_country string (en-GB or en_GB or en)
1384 if ($mode && $mode != 'UTF-8') { // mPDF 6
1385 list ($coreSuitable, $mpdf_pdf_unifont) = $this->languageToFont->getLanguageOptions($mode, $this->useAdobeCJK);
1392 $this->currentLang = $mode;
1393 $this->default_lang = $mode;
1396 $this->onlyCoreFonts = $onlyCoreFonts;
1398 if ($this->onlyCoreFonts) {
1399 $this->setMBencoding('windows-1252'); // sets $this->mb_enc
1401 $this->setMBencoding('UTF-8'); // sets $this->mb_enc
1403 @mb_regex_encoding('UTF-8'); // required only for mb_ereg... and mb_split functions
1406 $this->available_CJK_fonts = [
1426 $this->CoreFonts = [
1428 'ccourierB' => 'Courier-Bold',
1429 'ccourierI' => 'Courier-Oblique',
1430 'ccourierBI' => 'Courier-BoldOblique',
1432 'chelveticaB' => 'Helvetica-Bold',
1433 'chelveticaI' => 'Helvetica-Oblique',
1434 'chelveticaBI' => 'Helvetica-BoldOblique',
1435 'ctimes' => 'Times-Roman',
1436 'ctimesB' => 'Times-Bold',
1437 'ctimesI' => 'Times-Italic',
1438 'ctimesBI' => 'Times-BoldItalic',
1443 $this->fontlist = [
1452 $this->setHiEntitySubstitutions();
1454 if ($this->onlyCoreFonts) {
1455 $this->useSubstitutions = true;
1456 $this->SetSubstitutions();
1458 $this->useSubstitutions = $config['useSubstitutions'];
1461 if (file_exists($this->defaultCssFile)) {
1462 $css = file_get_contents($this->defaultCssFile);
1463 $this->cssManager->ReadCSS('<style> ' . $css . ' </style>');
1465 throw new \Mpdf\MpdfException(sprintf('Unable to read default CSS file "%s"', $this->defaultCssFile));
1469 if ($this->onlyCoreFonts) {
1470 if (in_array(strtolower($this->defaultCSS['BODY']['FONT-FAMILY']), $this->mono_fonts)) {
1472 } elseif (in_array(strtolower($this->defaultCSS['BODY']['FONT-FAMILY']), $this->sans_fonts)) {
1478 $default_font = $this->defaultCSS['BODY']['FONT-FAMILY'];
1482 $mmsize = $this->sizeConverter->convert($this->defaultCSS['BODY']['FONT-SIZE']);
1487 $this->SetDefaultFont($default_font);
1490 $this->SetDefaultFontSize($default_font_size);
1493 $this->SetLineHeight(); // lineheight is in mm
1495 $this->SetFColor($this->colorConverter->convert(255, $this->PDFAXwarnings));
1496 $this->HREF = '';
1497 $this->oldy = -1;
1498 $this->B = 0;
1499 $this->I = 0;
1502 $this->listlvl = 0;
1503 $this->listtype = [];
1504 $this->listitem = [];
1505 $this->listcounter = [];
1507 $this->tdbegin = false;
1508 $this->table = [];
1509 $this->cell = [];
1510 $this->col = -1;
1511 $this->row = -1;
1512 $this->cellBorderBuffer = [];
1514 $this->divbegin = false;
1516 $this->cellTextAlign = '';
1517 $this->cellLineHeight = '';
1518 $this->cellLineStackingStrategy = '';
1519 $this->cellLineStackingShift = '';
1521 $this->divwidth = 0;
1522 $this->divheight = 0;
1523 $this->spanbgcolor = false;
1524 $this->spanborder = false;
1525 $this->spanborddet = [];
1527 $this->blockjustfinished = false;
1528 $this->ignorefollowingspaces = true; // in order to eliminate exceeding left-side spaces
1529 $this->dash_on = false;
1530 $this->dotted_on = false;
1531 $this->textshadow = '';
1533 $this->currentfontfamily = '';
1534 $this->currentfontsize = '';
1535 $this->currentfontstyle = '';
1536 $this->colorarray = ''; // mPDF 6
1537 $this->spanbgcolorarray = ''; // mPDF 6
1538 $this->textbuffer = [];
1539 $this->internallink = [];
1540 $this->basepath = "";
1542 $this->SetBasePath('');
1544 $this->textparam = [];
1546 $this->specialcontent = '';
1547 $this->selectoption = [];
1552 mb_internal_encoding($this->originalMbEnc);
1553 @mb_regex_encoding($this->originalMbRegexEnc);
1556 foreach ($this->createdReaders as $id) {
1557 $this->readers[$id]->getParser()->getStreamReader()->cleanUp();
1558 unset($this->readers[$id]);
1561 $this->createdReaders = [];
1571 $this->logger = $logger;
1573 foreach ($this->services as $name) {
1574 if ($this->$name && $this->$name instanceof \Psr\Log\LoggerAwareInterface) {
1575 $this->$name->setLogger($logger);
1585 $defaults = $configObject->getDefaults();
1589 $this->{$var} = $val;
1623 $defaults = $configObject->getDefaults();
1626 $this->{$var} = $val;
1640 // e.g. A4-L = A4 landscape, A4-P = A4 portrait
1641 if (preg_match('/([0-9a-zA-Z]*)-([P,L])/i', $format, $m)) {
1650 $this->fwPt = $format[0];
1651 $this->fhPt = $format[1];
1659 $this->fwPt = $format[0] * Mpdf::SCALE;
1660 $this->fhPt = $format[1] * Mpdf::SCALE;
1663 $this->fw = $this->fwPt / Mpdf::SCALE;
1664 $this->fh = $this->fhPt / Mpdf::SCALE;
1670 $this->wPt = $this->fwPt;
1671 $this->hPt = $this->fhPt;
1674 $this->wPt = $this->fhPt;
1675 $this->hPt = $this->fwPt;
1680 $this->CurOrientation = $orientation;
1682 $this->w = $this->wPt / Mpdf::SCALE;
1683 $this->h = $this->hPt / Mpdf::SCALE;
1688 // $res = array of (Unicode) fonts to restrict to: e.g. norasi|norasiB - language specific
1690 $this->available_unifonts = $res;
1692 $this->available_unifonts = $this->default_available_fonts;
1694 if (count($this->available_unifonts) == 0) {
1695 $this->available_unifonts[] = $this->default_available_fonts[0];
1697 $this->available_unifonts = array_values($this->available_unifonts);
1702 if ($this->mb_enc != $enc) {
1703 $this->mb_enc = $enc;
1704 mb_internal_encoding($this->mb_enc);
1711 $this->lMargin = $left;
1712 $this->rMargin = $right;
1713 $this->tMargin = $top;
1719 if (($this->forcePortraitHeaders || $this->forcePortraitMargins) && $this->DefOrientation == 'P' && $this->CurOrientation == 'L') {
1720 if (($this->mirrorMargins) && (($this->page) % 2 == 0)) { // EVEN
1721 $this->tMargin = $this->orig_rMargin;
1722 $this->bMargin = $this->orig_lMargin;
1724 $this->tMargin = $this->orig_lMargin;
1725 $this->bMargin = $this->orig_rMargin;
1727 $this->lMargin = $this->DeflMargin;
1728 $this->rMargin = $this->DefrMargin;
1729 $this->MarginCorrection = 0;
1730 $this->PageBreakTrigger = $this->h - $this->bMargin;
1731 } elseif (($this->mirrorMargins) && (($this->page) % 2 == 0)) { // EVEN
1732 $this->lMargin = $this->DefrMargin;
1733 $this->rMargin = $this->DeflMargin;
1734 $this->MarginCorrection = $this->DefrMargin - $this->DeflMargin;
1736 $this->lMargin = $this->DeflMargin;
1737 $this->rMargin = $this->DefrMargin;
1738 if ($this->mirrorMargins) {
1739 $this->MarginCorrection = $this->DeflMargin - $this->DefrMargin;
1742 $this->x = $this->lMargin;
1748 $this->lMargin = $margin;
1749 if ($this->page > 0 and $this->x < $margin) {
1750 $this->x = $margin;
1757 $this->tMargin = $margin;
1763 $this->rMargin = $margin;
1769 $this->autoPageBreak = $auto;
1770 $this->bMargin = $margin;
1771 $this->PageBreakTrigger = $this->h - $margin;
1779 $this->ZoomMode = $zoom;
1787 $this->LayoutMode = $layout;
1797 $this->compress = $compress;
1799 $this->compress = false;
1805 // Title of document // Arrives as UTF-8
1806 $this->title = $title;
1812 $this->subject = $subject;
1818 $this->author = $author;
1824 $this->keywords = $keywords;
1830 $this->creator = $creator;
1835 $this->customProperties[$key] = $value;
1839 * Set one or multiple associated file ("/AF" as required by PDF/A-3)
1847 * AFRelationship (optional): PDF/A-3 AFRelationship (e.g. "Alternative")
1863 $this->associatedFiles = $files;
1868 $this->additionalXmpRdf = $s;
1873 $this->anchor2Bookmark = $x;
1879 $this->aliasNbPg = $alias;
1885 $this->aliasNbPgGp = $alias;
1894 // set alpha for stroking (CA) and non-stroking (ca) operations
1896 if (($this->PDFA || $this->PDFX) && $alpha != 1) {
1897 if (($this->PDFA && !$this->PDFAauto) || ($this->PDFX && !$this->PDFXauto)) {
1898 $this->PDFAXwarnings[] = "Image opacity must be 100% (Opacity changed to 100%)";
1909 $gs = $this->AddExtGState($a);
1913 $this->writer->write(sprintf('/GS%d gs', $gs));
1919 $n = count($this->extgstates);
1922 if (count($this->extgstates[$i]['parms']) == count($parms)) {
1924 foreach ($this->extgstates[$i]['parms'] as $k => $v) {
1936 $this->extgstates[$n]['parms'] = $parms;
1942 if (($this->PDFA || $this->PDFX) && $this->visibility != 'visible') {
1943 $this->PDFAXwarnings[] = "Cannot set visibility to anything other than full when using PDFA or PDFX";
1945 } elseif (!$this->PDFA && !$this->PDFX) {
1946 $this->pdf_version = '1.5';
1948 if ($this->visibility != 'visible') {
1949 $this->writer->write('EMC');
1950 $this->hasOC = intval($this->hasOC);
1953 $this->writer->write('/OC /OC1 BDC');
1954 $this->hasOC = ($this->hasOC | 1);
1956 $this->writer->write('/OC /OC2 BDC');
1957 $this->hasOC = ($this->hasOC | 2);
1959 $this->writer->write('/OC /OC3 BDC');
1960 $this->hasOC = ($this->hasOC | 4);
1964 $this->visibility = $v;
1970 if ($this->state == 0) {
1971 $this->state = 1;
1972 if (false === $this->preambleWritten) {
1973 $this->writer->write('%PDF-' . $this->pdf_version);
1974 $this->writer->write('%' . chr(226) . chr(227) . chr(207) . chr(211)); // 4 chars > 128 to show binary file
1975 $this->preambleWritten = true;
1985 if ($this->state == 3) {
1989 if ($this->page == 0) {
1990 $this->AddPage($this->CurOrientation);
1993 if (count($this->cellBorderBuffer)) {
1994 $this->printcellbuffer();
1998 if ($this->tablebuffer) {
1999 $this->printtablebuffer();
2002 /* -- COLUMNS -- */
2004 if ($this->ColActive) {
2005 $this->SetColumns(0);
2006 $this->ColActive = 0;
2007 if (count($this->columnbuffer)) {
2008 $this->printcolumnbuffer();
2012 /* -- END COLUMNS -- */
2017 $s .= $this->PrintBodyBackgrounds();
2018 $s .= $this->PrintPageBackgrounds();
2020 $this->pages[$this->page] = preg_replace(
2021 '/(___BACKGROUND___PATTERNS' . $this->uniqstr . ')/',
2023 $this->pages[$this->page]
2026 $this->pageBackgrounds = [];
2028 if ($this->visibility != 'visible') {
2029 $this->SetVisibility('visible');
2032 $this->EndLayer();
2034 if (!$this->tableOfContents->TOCmark) { // Page footer
2035 $this->InFooter = true;
2036 $this->Footer();
2037 $this->InFooter = false;
2040 if ($this->tableOfContents->TOCmark || count($this->tableOfContents->m_TOC)) {
2041 $this->tableOfContents->insertTOC();
2045 $this->_endpage();
2048 $this->_enddoc();
2051 /* -- BACKGROUNDS -- */
2053 function _resizeBackgroundImage($imw, $imh, $cw, $ch, $resize, $repx, $repy, $pba = [], $size = [])
2055 // pba is background positioning area (from CSS background-origin) may not always be set [x,y,w,h]
2056 // size is from CSS3 background-size - takes precendence over old resize
2057 // $w - absolute length or % or auto or cover | contain
2058 // $h - absolute length or % or auto or cover | contain
2068 if (empty($size) && !$resize) {
2072 if (isset($size['w']) && $size['w']) {
2073 if ($size['w'] == 'contain') {
2075 // to the largest size such that both its width and its height can fit inside the background positioning area.
2083 } elseif ($size['w'] == 'cover') {
2085 // to the smallest size such that both its width and its height can completely cover the background positioning area.
2093 if (stristr($size['w'], '%')) {
2094 $size['w'] = (float) $size['w'];
2095 $size['w'] /= 100;
2096 $size['w'] = ($cw * $size['w']);
2098 if (stristr($size['h'], '%')) {
2099 $size['h'] = (float) $size['h'];
2100 $size['h'] /= 100;
2101 $size['h'] = ($ch * $size['h']);
2103 if ($size['w'] == 'auto' && $size['h'] == 'auto') {
2106 } elseif ($size['w'] == 'auto' && $size['h'] != 'auto') {
2107 $w = $imw * $size['h'] / $imh;
2108 $h = $size['h'];
2109 } elseif ($size['w'] != 'auto' && $size['h'] == 'auto') {
2110 $h = $imh * $size['w'] / $imw;
2111 $w = $size['w'];
2113 $w = $size['w'];
2114 $h = $size['h'];
2150 if (isset($properties['BACKGROUND-ORIGIN']) && ($properties['BACKGROUND-ORIGIN'] == 'border-box' || $properties['BACKGROUND-ORIGIN'] == 'content-box')) {
2151 $origin = $properties['BACKGROUND-ORIGIN'];
2153 $origin = 'padding-box';
2156 if (isset($properties['BACKGROUND-SIZE'])) {
2157 if (stristr($properties['BACKGROUND-SIZE'], 'contain')) {
2159 } elseif (stristr($properties['BACKGROUND-SIZE'], 'cover')) {
2163 $sz = preg_split('/\s+/', trim($properties['BACKGROUND-SIZE']));
2171 $bsw = $this->sizeConverter->convert($bsw, $maxwidth, $this->FontSize);
2174 $bsh = $this->sizeConverter->convert($bsh, $maxwidth, $this->FontSize);
2177 $size = ['w' => $bsw, 'h' => $bsh];
2179 $size = false;
2181 if (preg_match('/(-moz-)*(repeating-)*(linear|radial)-gradient/', $properties['BACKGROUND-IMAGE'])) {
2182 return ['gradient' => $properties['BACKGROUND-IMAGE'], 'origin' => $origin, 'size' => $size];
2184 $file = $properties['BACKGROUND-IMAGE'];
2185 $sizesarray = $this->Image($file, 0, 0, 0, 0, '', '', false, false, false, false, true);
2189 $orig_h = $sizesarray['HEIGHT'] * Mpdf::SCALE; // (using $this->img_dpi)
2190 if (isset($properties['BACKGROUND-IMAGE-RESOLUTION'])) {
2191 if (preg_match('/from-image/i', $properties['BACKGROUND-IMAGE-RESOLUTION']) && isset($sizesarray['set-dpi']) && $sizesarray['set-dpi'] > 0) {
2192 $orig_w *= $this->img_dpi / $sizesarray['set-dpi'];
2193 $orig_h *= $this->img_dpi / $sizesarray['set-dpi'];
2194 } elseif (preg_match('/(\d+)dpi/i', $properties['BACKGROUND-IMAGE-RESOLUTION'], $m)) {
2197 $orig_w *= $this->img_dpi / $dpi;
2198 $orig_h *= $this->img_dpi / $dpi;
2204 if (isset($properties['BACKGROUND-REPEAT'])) {
2205 if ($properties['BACKGROUND-REPEAT'] == 'no-repeat' || $properties['BACKGROUND-REPEAT'] == 'repeat-x') {
2208 if ($properties['BACKGROUND-REPEAT'] == 'no-repeat' || $properties['BACKGROUND-REPEAT'] == 'repeat-y') {
2214 if (isset($properties['BACKGROUND-POSITION'])) {
2215 $ppos = preg_split('/\s+/', $properties['BACKGROUND-POSITION']);
2219 $x_pos = $this->sizeConverter->convert($x_pos, $maxwidth, $this->FontSize);
2222 $y_pos = $this->sizeConverter->convert($y_pos, $maxwidth, $this->FontSize);
2225 if (isset($properties['BACKGROUND-IMAGE-RESIZE'])) {
2226 $resize = $properties['BACKGROUND-IMAGE-RESIZE'];
2230 if (isset($properties['BACKGROUND-IMAGE-OPACITY'])) {
2231 $opacity = $properties['BACKGROUND-IMAGE-OPACITY'];
2235 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];
2241 /* -- END BACKGROUNDS -- */
2248 $clw = $this->w;
2249 $clh = $this->h;
2251 if ($this->pageDim[$this->page]['outer_width_LR'] || $this->pageDim[$this->page]['outer_width_TB']) {
2252 $clx = $this->pageDim[$this->page]['outer_width_LR'] - $this->pageDim[$this->page]['bleedMargin'];
2253 $cly = $this->pageDim[$this->page]['outer_width_TB'] - $this->pageDim[$this->page]['bleedMargin'];
2254 $clw = $this->w - 2 * $clx;
2255 $clh = $this->h - 2 * $cly;
2258 if ($this->bodyBackgroundColor) {
2259 $s .= 'q ' . $this->SetFColor($this->bodyBackgroundColor, true) . "\n";
2260 if ($this->bodyBackgroundColor[0] == 5) { // RGBa
2261 $s .= $this->SetAlpha(ord($this->bodyBackgroundColor[4]) / 100, 'Normal', true, 'F') . "\n";
2262 } elseif ($this->bodyBackgroundColor[0] == 6) { // CMYKa
2263 $s .= $this->SetAlpha(ord($this->bodyBackgroundColor[5]) / 100, 'Normal', true, 'F') . "\n";
2268 /* -- BACKGROUNDS -- */
2269 if ($this->bodyBackgroundGradient) {
2270 $g = $this->gradient->parseBackgroundGradient($this->bodyBackgroundGradient);
2272 $s .= $this->gradient->Gradient($clx, $cly, $clw, $clh, (isset($g['gradtype']) ? $g['gradtype'] : null), $g['stops'], $g['colorspace'], $g['coords'], $g['extend'], true);
2275 if ($this->bodyBackgroundImage) {
2276 if (isset($this->bodyBackgroundImage['gradient']) && $this->bodyBackgroundImage['gradient'] && preg_match('/(-moz-)*(repeating-)*(linear|radial)-gradient/', $this->bodyBackgroundImage['gradient'])) {
2277 $g = $this->gradient->parseMozGradient($this->bodyBackgroundImage['gradient']);
2279 $s .= $this->gradient->Gradient($clx, $cly, $clw, $clh, $g['type'], $g['stops'], $g['colorspace'], $g['coords'], $g['extend'], true);
2281 } elseif ($this->bodyBackgroundImage['image_id']) { // Background pattern
2282 $n = count($this->patterns) + 1;
2284 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']);
2286 $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']];
2287 if (($this->bodyBackgroundImage['opacity'] > 0 || $this->bodyBackgroundImage['opacity'] === '0') && $this->bodyBackgroundImage['opacity'] < 1) {
2288 $opac = $this->SetAlpha($this->bodyBackgroundImage['opacity'], 'Normal', true);
2295 /* -- END BACKGROUNDS -- */
2302 $s .= sprintf('%.3F %.3F m ', ($clx) * Mpdf::SCALE, ($this->h - ($cly)) * Mpdf::SCALE); // start point TL before the arc
2303 $s .= sprintf('%.3F %.3F l ', ($clx) * Mpdf::SCALE, ($this->h - ($cly + $clh)) * Mpdf::SCALE); // line to BL
2304 $s .= sprintf('%.3F %.3F l ', ($clx + $clw) * Mpdf::SCALE, ($this->h - ($cly + $clh)) * Mpdf::SCALE); // line to BR
2305 $s .= sprintf('%.3F %.3F l ', ($clx + $clw) * Mpdf::SCALE, ($this->h - ($cly)) * Mpdf::SCALE); // line to TR
2306 $s .= sprintf('%.3F %.3F l ', ($clx) * Mpdf::SCALE, ($this->h - ($cly)) * Mpdf::SCALE); // line to TL
2307 $s .= ' W n '; // Ends path no-op & Sets the clipping path
2315 ksort($this->pageBackgrounds);
2317 foreach ($this->pageBackgrounds as $bl => $pbs) {
2323 if ($pb['z-index'] > 0) {
2324 $this->current_layer = $pb['z-index'];
2325 $s .= "\n" . '/OCBZ-index /ZI' . $pb['z-index'] . ' BDC' . "\n";
2347 $s .= 'q ' . $this->SetFColor($pb['col'], true) . "\n";
2350 $s .= $this->SetAlpha(ord($pb['col'][4]) / 100, 'Normal', true, 'F') . "\n";
2352 $s .= $this->SetAlpha(ord($pb['col'][5]) / 100, 'Normal', true, 'F') . "\n";
2355 $s .= sprintf('%.3F %.3F %.3F %.3F re f Q', $pb['x'] * Mpdf::SCALE, ($this->h - $pb['y']) * Mpdf::SCALE, $pb['w'] * Mpdf::SCALE, -$pb['h'] * Mpdf::SCALE) . "\n";
2365 if ($pb['z-index'] > 0) {
2366 $s .= "\n" . 'EMCBZ-index' . "\n";
2367 $this->current_layer = 0;
2372 /* -- BACKGROUNDS -- */
2377 if ($pb['z-index'] > 0) {
2378 $this->current_layer = $pb['z-index'];
2379 $s .= "\n" . '/OCGZ-index /ZI' . $pb['z-index'] . ' BDC' . "\n";
2400 $s .= $this->gradient->Gradient($pb['x'], $pb['y'], $pb['w'], $pb['h'], $pb['gradtype'], $pb['stops'], $pb['colorspace'], $pb['coords'], $pb['extend'], true);
2408 $pb['y'] -= $adjustmenty;
2410 $n = count($this->patterns) + 1;
2412 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']);
2414 $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']];
2417 $y = ($this->h - $pb['y']) * Mpdf::SCALE;
2419 $h = -$pb['h'] * Mpdf::SCALE;
2425 if ($this->writingHTMLfooter || $this->writingHTMLheader) { // Write each (tiles) image rather than use as a pattern
2442 if (isset($pb['size']['w']) && $pb['size']['w']) {
2443 $size = $pb['size'];
2445 if ($size['w'] == 'contain') {
2447 // size such that both its width and its height can fit inside the background positioning area.
2455 } elseif ($size['w'] == 'cover') {
2457 // size such that both its width and its height can completely cover the background positioning area.
2466 if (NumericString::containsPercentChar($size['w'])) {
2467 $size['w'] = NumericString::removePercentChar($size['w']);
2468 $size['w'] /= 100;
2469 $size['w'] = ($pb['bpa']['w'] * $size['w']);
2472 if (NumericString::containsPercentChar($size['h'])) {
2473 $size['h'] = NumericString::removePercentChar($size['h']);
2474 $size['h'] /= 100;
2475 $size['h'] = ($pb['bpa']['h'] * $size['h']);
2478 if ($size['w'] == 'auto' && $size['h'] == 'auto') {
2481 } elseif ($size['w'] == 'auto' && $size['h'] != 'auto') {
2482 $iw = $iw * $size['h'] / $ih;
2483 $ih = $size['h'];
2484 } elseif ($size['w'] != 'auto' && $size['h'] == 'auto') {
2485 $ih = $ih * $size['w'] / $iw;
2486 $iw = $size['w'];
2488 $iw = $size['w'];
2489 $ih = $size['h'];
2511 $x_pos = ($pb['bpa']['w'] * $x_pos) - ($iw * $x_pos);
2519 $y_pos = ($pb['bpa']['h'] * $y_pos) - ($ih * $y_pos);
2523 while ($x_pos > ($pb['x'] - $pb['bpa']['x'])) {
2524 $x_pos -= $iw;
2529 while ($y_pos > ($pb['y'] - $pb['bpa']['y'])) {
2530 $y_pos -= $ih;
2539 $opac = $this->SetAlpha($pb['opacity'], 'Normal', true);
2543 $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->h - ($y + $ih)) * Mpdf::SCALE, $pb['image_id']) . "\n";
2549 $opac = $this->SetAlpha($pb['opacity'], 'Normal', true);
2566 if ($pb['z-index'] > 0) {
2567 $s .= "\n" . 'EMCGZ-index' . "\n";
2568 $this->current_layer = 0;
2572 /* -- END BACKGROUNDS -- */
2581 /* -- BACKGROUNDS -- */
2582 ksort($this->tableBackgrounds);
2583 foreach ($this->tableBackgrounds as $bl => $pbs) {
2586 $s .= 'q ' . $this->SetFColor($pb['col'], true) . "\n";
2588 $s .= $this->SetAlpha(ord($pb['col'][4]) / 100, 'Normal', true, 'F') . "\n";
2590 $s .= $this->SetAlpha(ord($pb['col'][5]) / 100, 'Normal', true, 'F') . "\n";
2592 $s .= sprintf('%.3F %.3F %.3F %.3F re %s Q', $pb['x'] * Mpdf::SCALE, ($this->h - $pb['y']) * Mpdf::SCALE, $pb['w'] * Mpdf::SCALE, -$pb['h'] * Mpdf::SCALE, 'f') . "\n";
2598 $s .= $this->gradient->Gradient($pb['x'], $pb['y'], $pb['w'], $pb['h'], $pb['gradtype'], $pb['stops'], $pb['colorspace'], $pb['coords'], $pb['extend'], true);
2604 $pb['y'] -= $adjustmenty;
2606 $n = count($this->patterns) + 1;
2607 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']);
2608 $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']];
2610 $y = ($this->h - $pb['y']) * Mpdf::SCALE;
2612 $h = -$pb['h'] * Mpdf::SCALE;
2615 if (($this->writingHTMLfooter || $this->writingHTMLheader) && (!isset($pb['clippath']) || $pb['clippath'] == '')) {
2625 if ($this->writingHTMLfooter || $this->writingHTMLheader) { // Write each (tiles) image rather than use as a pattern
2639 } // At present 'bpa' (background page area) is not set for tablebackgrounds - only pagebackgrounds
2645 if (isset($pb['size']['w']) && $pb['size']['w']) {
2646 $size = $pb['size'];
2648 if ($size['w'] == 'contain') {
2649 // 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.
2657 } elseif ($size['w'] == 'cover') {
2658 // 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.
2666 if (NumericString::containsPercentChar($size['w'])) {
2667 $size['w'] = NumericString::removePercentChar($size['w']);
2668 $size['w'] /= 100;
2669 $size['w'] = ($pb['bpa']['w'] * $size['w']);
2671 if (NumericString::containsPercentChar($size['h'])) {
2672 $size['h'] = NumericString::removePercentChar($size['h']);
2673 $size['h'] /= 100;
2674 $size['h'] = ($pb['bpa']['h'] * $size['h']);
2676 if ($size['w'] == 'auto' && $size['h'] == 'auto') {
2679 } elseif ($size['w'] == 'auto' && $size['h'] != 'auto') {
2680 $iw = $iw * $size['h'] / $ih;
2681 $ih = $size['h'];
2682 } elseif ($size['w'] != 'auto' && $size['h'] == 'auto') {
2683 $ih = $ih * $size['w'] / $iw;
2684 $iw = $size['w'];
2686 $iw = $size['w'];
2687 $ih = $size['h'];
2708 $x_pos = ($pb['bpa']['w'] * $x_pos) - ($iw * $x_pos);
2714 $y_pos = ($pb['bpa']['h'] * $y_pos) - ($ih * $y_pos);
2717 while ($x_pos > ($pb['x'] - $pb['bpa']['x'])) {
2718 $x_pos -= $iw;
2722 while ($y_pos > ($pb['y'] - $pb['bpa']['y'])) {
2723 $y_pos -= $ih;
2731 $opac = $this->SetAlpha($pb['opacity'], 'Normal', true);
2735 $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->h - ($y + $ih)) * Mpdf::SCALE, $pb['image_id']) . "\n";
2740 $opac = $this->SetAlpha($pb['opacity'], 'Normal', true);
2753 /* -- END BACKGROUNDS -- */
2759 if ($this->current_layer > 0) {
2760 $this->EndLayer();
2765 if (!isset($this->layers[$id])) {
2766 $this->layers[$id] = ['name' => 'Layer ' . ($id)];
2767 if (($this->PDFA || $this->PDFX)) {
2768 $this->PDFAXwarnings[] = "Cannot use layers when using PDFA or PDFX";
2770 } elseif (!$this->PDFA && !$this->PDFX) {
2771 $this->pdf_version = '1.5';
2774 $this->current_layer = $id;
2775 $this->writer->write('/OCZ-index /ZI' . $id . ' BDC');
2777 $this->pageoutput[$this->page] = [];
2782 if ($this->current_layer > 0) {
2783 $this->writer->write('EMCZ-index');
2784 $this->current_layer = 0;
2799 $mgl = (isset($a['mgl']) ? $a['mgl'] : (isset($a['margin-left']) ? $a['margin-left'] : ''));
2800 $mgr = (isset($a['mgr']) ? $a['mgr'] : (isset($a['margin-right']) ? $a['margin-right'] : ''));
2801 $mgt = (isset($a['mgt']) ? $a['mgt'] : (isset($a['margin-top']) ? $a['margin-top'] : ''));
2802 $mgb = (isset($a['mgb']) ? $a['mgb'] : (isset($a['margin-bottom']) ? $a['margin-bottom'] : ''));
2803 $mgh = (isset($a['mgh']) ? $a['mgh'] : (isset($a['margin-header']) ? $a['margin-header'] : ''));
2804 $mgf = (isset($a['mgf']) ? $a['mgf'] : (isset($a['margin-footer']) ? $a['margin-footer'] : ''));
2805 $ohname = (isset($a['ohname']) ? $a['ohname'] : (isset($a['odd-header-name']) ? $a['odd-header-name'] : ''));
2806 $ehname = (isset($a['ehname']) ? $a['ehname'] : (isset($a['even-header-name']) ? $a['even-header-name'] : ''));
2807 $ofname = (isset($a['ofname']) ? $a['ofname'] : (isset($a['odd-footer-name']) ? $a['odd-footer-name'] : ''));
2808 $efname = (isset($a['efname']) ? $a['efname'] : (isset($a['even-footer-name']) ? $a['even-footer-name'] : ''));
2809 $ohvalue = (isset($a['ohvalue']) ? $a['ohvalue'] : (isset($a['odd-header-value']) ? $a['odd-header-value'] : 0));
2810 $ehvalue = (isset($a['ehvalue']) ? $a['ehvalue'] : (isset($a['even-header-value']) ? $a['even-header-value'] : 0));
2811 $ofvalue = (isset($a['ofvalue']) ? $a['ofvalue'] : (isset($a['odd-footer-value']) ? $a['odd-footer-value'] : 0));
2812 $efvalue = (isset($a['efvalue']) ? $a['efvalue'] : (isset($a['even-footer-value']) ? $a['even-footer-value'] : 0));
2814 $newformat = (isset($a['newformat']) ? $a['newformat'] : (isset($a['sheet-size']) ? $a['sheet-size'] : ''));
2816 $this->AddPage($orientation, $condition, $resetpagenum, $pagenumstyle, $suppress, $mgl, $mgr, $mgt, $mgb, $mgh, $mgf, $ohname, $ehname, $ofname, $efname, $ohvalue, $ehvalue, $ofvalue, $efvalue, $pagesel, $newformat);
2826 for ($b = $this->blklvl; $b > 0; $b--) {
2827 $this->tag->CloseTag($this->blk[$b]['tag'], $arr, $ai);
2829 if ($this->blklvl == 0 && !empty($this->textbuffer)) { // Output previously buffered content
2830 $this->printbuffer($this->textbuffer, 1);
2831 $this->textbuffer = [];
2834 // Close open block tags whilst box-decoration-break==clone
2837 for ($b = $this->blklvl; $b > 0; $b--) {
2838 if (isset($this->blk[$b]['box_decoration_break']) && $this->blk[$b]['box_decoration_break'] == 'clone') {
2839 $this->tag->CloseTag($this->blk[$b]['tag'], $arr, $ai);
2841 if ($b == $this->blklvl && !empty($this->textbuffer)) { // Output previously buffered content
2842 $this->printbuffer($this->textbuffer, 1);
2843 $this->textbuffer = [];
2848 } elseif (!empty($this->textbuffer)) { // Output previously buffered content
2849 $this->printbuffer($this->textbuffer, 1);
2850 $this->textbuffer = [];
2858 $this->blk = [];
2859 $this->blk[0] = $save_blk[0];
2860 // Re-open block tags
2861 $this->blklvl = 0;
2865 $this->tag->OpenTag($save_blk[$b]['tag'], $save_blk[$b]['attr'], $arr, $i);
2868 $this->blk = [];
2869 $this->blk[0] = $save_blk[0];
2870 // Don't re-open tags for lowest level elements - so need to do some adjustments
2871 for ($b = 1; $b <= $this->blklvl; $b++) {
2872 $this->blk[$b] = $save_blk[$b];
2873 $this->blk[$b]['startpage'] = 0;
2874 $this->blk[$b]['y0'] = $this->y; // ?? $this->tMargin
2875 if (($this->page - $startpage) % 2) {
2876 if (isset($this->blk[$b]['x0'])) {
2877 $this->blk[$b]['x0'] += $this->MarginCorrection;
2879 $this->blk[$b]['x0'] = $this->MarginCorrection;
2883 $this->blk[$b]['marginCorrected'][$this->page] = true;
2886 // Re-open block tags for any that have box_decoration_break==clone
2889 for ($b = $this->blklvl + 1; $b <= $save_blklvl; $b++) {
2890 if ($b < $this->blklvl) {
2891 $this->lastblocklevelchange = -1;
2893 $this->tag->OpenTag($save_blk[$b]['tag'], $save_blk[$b]['attr'], $arr, $i);
2895 if ($this->blk[$this->blklvl]['box_decoration_break'] != 'clone') {
2896 $this->lastblocklevelchange = -1;
2899 $this->lastblocklevelchange = -1;
2926 /* -- CSS-FLOAT -- */
2929 // If next page already exists - i.e background /headers and footers already written
2930 if ($this->state > 0 && $this->page < count($this->pages)) {
2931 $bak_cml = $this->cMarginL;
2932 $bak_cmr = $this->cMarginR;
2933 $bak_dw = $this->divwidth;
2935 if ($this->blklvl > 0) {
2936 $save_tr = $this->table_rotate; // *TABLES*
2937 $this->table_rotate = 0; // *TABLES*
2938 if (isset($this->blk[$this->blklvl]['y0']) && $this->y == $this->blk[$this->blklvl]['y0']) {
2939 $this->blk[$this->blklvl]['startpage'] ++;
2941 if ((isset($this->blk[$this->blklvl]['y0']) && $this->y > $this->blk[$this->blklvl]['y0']) || $this->flowingBlockAttr['is_table']) {
2942 $toplvl = $this->blklvl;
2944 $toplvl = $this->blklvl - 1;
2946 $sy = $this->y;
2948 $this->PaintDivBB('pagebottom', 0, $bl);
2950 $this->y = $sy;
2951 $this->table_rotate = $save_tr; // *TABLES*
2953 $s = $this->PrintPageBackgrounds();
2956 $this->pages[$this->page] = preg_replace(
2957 '/(___BACKGROUND___PATTERNS' . $this->uniqstr . ')/',
2959 $this->pages[$this->page]
2962 $this->pageBackgrounds = [];
2963 $family = $this->FontFamily;
2964 $style = $this->FontStyle;
2965 $size = $this->FontSizePt;
2966 $lw = $this->LineWidth;
2967 $dc = $this->DrawColor;
2968 $fc = $this->FillColor;
2969 $tc = $this->TextColor;
2970 $cf = $this->ColorFlag;
2972 $this->printfloatbuffer();
2975 $this->page++;
2977 $this->ResetMargins();
2978 $this->SetAutoPageBreak($this->autoPageBreak, $this->bMargin);
2979 $this->x = $this->lMargin;
2980 $this->y = $this->tMargin;
2981 $this->FontFamily = '';
2982 $this->writer->write('2 J');
2983 $this->LineWidth = $lw;
2984 $this->writer->write(sprintf('%.3F w', $lw * Mpdf::SCALE));
2987 $this->SetFont($family, $style, $size, true, true);
2990 $this->DrawColor = $dc;
2992 if ($dc != $this->defDrawColor) {
2993 $this->writer->write($dc);
2996 $this->FillColor = $fc;
2998 if ($fc != $this->defFillColor) {
2999 $this->writer->write($fc);
3002 $this->TextColor = $tc;
3003 $this->ColorFlag = $cf;
3005 for ($bl = 1; $bl <= $this->blklvl; $bl++) {
3006 $this->blk[$bl]['y0'] = $this->y;
3008 if (!isset($this->blk[$bl]['marginCorrected'][$this->page])) {
3009 if (isset($this->blk[$bl]['x0'])) {
3010 $this->blk[$bl]['x0'] += $this->MarginCorrection;
3012 $this->blk[$bl]['x0'] = $this->MarginCorrection;
3015 $this->blk[$bl]['marginCorrected'][$this->page] = true;
3018 $this->cMarginL = $bak_cml;
3019 $this->cMarginR = $bak_cmr;
3020 $this->divwidth = $bak_dw;
3024 /* -- END CSS-FLOAT -- */
3027 if ($this->state == 0) {
3028 $this->Open();
3031 $bak_cml = $this->cMarginL;
3032 $bak_cmr = $this->cMarginR;
3033 $bak_dw = $this->divwidth;
3035 $bak_lh = $this->lineheight;
3042 if (!$this->mirrorMargins || ($this->page) % 2 == 0) {
3046 if (!$this->mirrorMargins || ($this->page) % 2 == 1) {
3049 } elseif ($condition == 'NEXT-EVEN') { // always adds at least one new page to create an Even page
3050 if (!$this->mirrorMargins) {
3056 } // *CSS-PAGE*
3059 } // *CSS-PAGE*
3060 $this->AddPage($this->CurOrientation, 'O');
3061 $this->extrapagebreak = true; // mPDF 6 pagebreaktype
3064 } // *CSS-PAGE*
3067 } elseif ($condition == 'NEXT-ODD') { // always adds at least one new page to create an Odd page
3068 if (!$this->mirrorMargins) {
3074 } // *CSS-PAGE*
3077 } // *CSS-PAGE*
3078 $this->AddPage($this->CurOrientation, 'E');
3079 $this->extrapagebreak = true; // mPDF 6 pagebreaktype
3082 } // *CSS-PAGE*
3088 $this->PageNumSubstitutions[] = ['from' => ($this->page + 1), 'reset' => $resetpagenum, 'type' => $pagenumstyle, 'suppress' => $suppress];
3091 $save_tr = $this->table_rotate; // *TABLES*
3092 $this->table_rotate = 0; // *TABLES*
3093 $save_kwt = $this->kwt;
3094 $this->kwt = 0;
3095 $save_layer = $this->current_layer;
3096 $save_vis = $this->visibility;
3098 if ($this->visibility != 'visible') {
3099 $this->SetVisibility('visible');
3102 $this->EndLayer();
3105 // PAINTS BACKGROUND COLOUR OR BORDERS for DIV - DISABLED FOR COLUMNS (cf. AcceptPageBreak) AT PRESENT in ->PaintDivBB
3106 if (!$this->ColActive && $this->blklvl > 0) {
3107 if (isset($this->blk[$this->blklvl]['y0']) && $this->y == $this->blk[$this->blklvl]['y0'] && !$this->extrapagebreak) { // mPDF 6 pagebreaktype
3108 if (isset($this->blk[$this->blklvl]['startpage'])) {
3109 $this->blk[$this->blklvl]['startpage'] ++;
3111 $this->blk[$this->blklvl]['startpage'] = 1;
3114 if ((isset($this->blk[$this->blklvl]['y0']) && $this->y > $this->blk[$this->blklvl]['y0']) || $this->flowingBlockAttr['is_table'] || $this->extrapagebreak) {
3115 $toplvl = $this->blklvl;
3118 $toplvl = $this->blklvl - 1;
3120 $sy = $this->y;
3122 if (isset($this->blk[$bl]['z-index']) && $this->blk[$bl]['z-index'] > 0) {
3123 $this->BeginLayer($this->blk[$bl]['z-index']);
3125 if (isset($this->blk[$bl]['visibility']) && $this->blk[$bl]['visibility'] && $this->blk[$bl]['visibility'] != 'visible') {
3126 $this->SetVisibility($this->blk[$bl]['visibility']);
3128 $this->PaintDivBB('pagebottom', 0, $bl);
3130 $this->y = $sy;
3131 // RESET block y0 and x0 - see below
3133 $this->extrapagebreak = false; // mPDF 6 pagebreaktype
3135 if ($this->visibility != 'visible') {
3136 $this->SetVisibility('visible');
3139 $this->EndLayer();
3142 if ($this->page > 0) {
3144 $s .= $this->PrintBodyBackgrounds();
3146 $s .= $this->PrintPageBackgrounds();
3147 $this->pages[$this->page] = preg_replace('/(___BACKGROUND___PATTERNS' . $this->uniqstr . ')/', "\n" . $s . "\n" . '\\1', $this->pages[$this->page]);
3148 $this->pageBackgrounds = [];
3151 $save_kt = $this->keep_block_together;
3152 $this->keep_block_together = 0;
3156 /* -- COLUMNS -- */
3157 if ($this->ColActive) {
3159 $save_nbcol = $this->NbCol; // other values of gap and vAlign will not change by setting Columns off
3160 $this->SetColumns(0);
3162 /* -- END COLUMNS -- */
3164 $family = $this->FontFamily;
3165 $style = $this->FontStyle;
3166 $size = $this->FontSizePt;
3167 $this->ColumnAdjust = true; // enables column height adjustment for the page
3168 $lw = $this->LineWidth;
3169 $dc = $this->DrawColor;
3170 $fc = $this->FillColor;
3171 $tc = $this->TextColor;
3172 $cf = $this->ColorFlag;
3173 if ($this->page > 0) {
3175 $this->InFooter = true;
3177 $this->Reset();
3178 $this->pageoutput[$this->page] = [];
3180 $this->Footer();
3182 $this->_endpage();
3186 $pageBeforeNewPage = $this->page;
3187 $this->_beginpage($orientation, $mgl, $mgr, $mgt, $mgb, $mgh, $mgf, $ohname, $ehname, $ofname, $efname, $ohvalue, $ehvalue, $ofvalue, $efvalue, $pagesel, $newformat);
3188 $isNewPage = $pageBeforeNewPage !== $this->page;
3190 if ($this->docTemplate) {
3191 $currentReaderId = $this->currentReaderId;
3193 $pagecount = $this->setSourceFile($this->docTemplate);
3194 if (($this->page - $this->docTemplateStart) > $pagecount) {
3195 if ($this->docTemplateContinue) {
3196 if ($this->docTemplateContinue2pages && $pagecount >= 2 && (0 === $this->page % 2)) {
3197 $tplIdx = $this->importPage(($pagecount - 1));
3198 $this->useTemplate($tplIdx);
3200 $tplIdx = $this->importPage($pagecount);
3201 $this->useTemplate($tplIdx);
3205 $tplIdx = $this->importPage(($this->page - $this->docTemplateStart));
3206 $this->useTemplate($tplIdx);
3209 $this->currentReaderId = $currentReaderId;
3212 if ($this->pageTemplate) {
3213 $this->useTemplate($this->pageTemplate);
3219 $this->writer->write('___PAGE___START' . $this->uniqstr);
3220 $this->writer->write('___BACKGROUND___PATTERNS' . $this->uniqstr);
3221 $this->writer->write('___HEADER___MARKER' . $this->uniqstr);
3224 $this->pageBackgrounds = [];
3227 $this->SetLineCap(2);
3229 $this->LineWidth = $lw;
3230 $this->writer->write(sprintf('%.3F w', $lw * Mpdf::SCALE));
3231 // Set font
3233 $this->SetFont($family, $style, $size, true, true); // forces write
3237 $this->DrawColor = $dc;
3238 if ($dc != $this->defDrawColor) {
3239 $this->writer->write($dc);
3241 $this->FillColor = $fc;
3242 if ($fc != $this->defFillColor) {
3243 $this->writer->write($fc);
3245 $this->TextColor = $tc;
3246 $this->ColorFlag = $cf;
3249 $this->Header();
3252 if ($this->LineWidth != $lw) {
3253 $this->LineWidth = $lw;
3254 $this->writer->write(sprintf('%.3F w', $lw * Mpdf::SCALE));
3256 // Restore font
3258 $this->SetFont($family, $style, $size, true, true); // forces write
3262 if ($this->DrawColor != $dc) {
3263 $this->DrawColor = $dc;
3264 $this->writer->write($dc);
3266 if ($this->FillColor != $fc) {
3267 $this->FillColor = $fc;
3268 $this->writer->write($fc);
3270 $this->TextColor = $tc;
3271 $this->ColorFlag = $cf;
3272 $this->InFooter = false;
3275 $this->BeginLayer($save_layer);
3279 $this->SetVisibility($save_vis);
3282 /* -- COLUMNS -- */
3285 $this->SetColumns($save_nbcol, $this->colvAlign, $this->ColGap);
3287 if ($this->ColActive) {
3288 $this->SetCol(0);
3290 /* -- END COLUMNS -- */
3294 if (!$this->ColActive) {
3295 for ($bl = 1; $bl <= $this->blklvl; $bl++) {
3296 $this->blk[$bl]['y0'] = $this->y;
3297 if (isset($this->blk[$bl]['x0'])) {
3298 $this->blk[$bl]['x0'] += $this->MarginCorrection;
3300 $this->blk[$bl]['x0'] = $this->MarginCorrection;
3303 $this->blk[$bl]['marginCorrected'][$this->page] = true;
3308 $this->table_rotate = $save_tr; // *TABLES*
3309 $this->kwt = $save_kwt;
3311 $this->keep_block_together = $save_kt;
3313 $this->cMarginL = $bak_cml;
3314 $this->cMarginR = $bak_cmr;
3315 $this->divwidth = $bak_dw;
3317 $this->lineheight = $bak_lh;
3327 return $this->page;
3334 throw new \Mpdf\MpdfException("Cannot load spot colors file - " . $file);
3342 $this->AddSpotColor($name, $c, $m, $y, $k);
3349 if (!isset($this->spotColors[$name])) {
3350 $i = count($this->spotColors) + 1;
3351 $this->spotColors[$name] = ['i' => $i, 'c' => $c, 'm' => $m, 'y' => $y, 'k' => $k];
3352 $this->spotColorIDs[$i] = $name;
3382 $out = $this->SetColor($col, 'Draw');
3389 $this->DrawColor = $out;
3390 if ($this->page > 0 && ((isset($this->pageoutput[$this->page]['DrawColor']) && $this->pageoutput[$this->page]['DrawColor'] != $this->DrawColor) || !isset($this->pageoutput[$this->page]['DrawColor']))) {
3391 $this->writer->write($this->DrawColor);
3393 $this->pageoutput[$this->page]['DrawColor'] = $this->DrawColor;
3398 $out = $this->SetColor($col, 'Fill');
3405 $this->FillColor = $out;
3406 $this->ColorFlag = ($out != $this->TextColor);
3407 if ($this->page > 0 && ((isset($this->pageoutput[$this->page]['FillColor']) && $this->pageoutput[$this->page]['FillColor'] != $this->FillColor) || !isset($this->pageoutput[$this->page]['FillColor']))) {
3408 $this->writer->write($this->FillColor);
3410 $this->pageoutput[$this->page]['FillColor'] = $this->FillColor;
3415 $out = $this->SetColor($col, 'Text');
3422 $this->TextColor = $out;
3423 $this->ColorFlag = ($this->FillColor != $out);
3426 function SetDrawColor($r, $g = -1, $b = -1, $col4 = -1, $return = false)
3430 if (($r == 0 and $g == 0 and $b == 0 && $col4 == -1) or $g == -1) {
3431 $col = $this->colorConverter->convert($r, $this->PDFAXwarnings);
3432 } elseif ($col4 == -1) {
3433 $col = $this->colorConverter->convert('rgb(' . $r . ',' . $g . ',' . $b . ')', $this->PDFAXwarnings);
3435 $col = $this->colorConverter->convert('cmyk(' . $r . ',' . $g . ',' . $b . ',' . $col4 . ')', $this->PDFAXwarnings);
3437 $out = $this->SetDColor($col, $return);
3441 function SetFillColor($r, $g = -1, $b = -1, $col4 = -1, $return = false)
3445 if (($r == 0 and $g == 0 and $b == 0 && $col4 == -1) or $g == -1) {
3446 $col = $this->colorConverter->convert($r, $this->PDFAXwarnings);
3447 } elseif ($col4 == -1) {
3448 $col = $this->colorConverter->convert('rgb(' . $r . ',' . $g . ',' . $b . ')', $this->PDFAXwarnings);
3450 $col = $this->colorConverter->convert('cmyk(' . $r . ',' . $g . ',' . $b . ',' . $col4 . ')', $this->PDFAXwarnings);
3452 $out = $this->SetFColor($col, $return);
3456 function SetTextColor($r, $g = -1, $b = -1, $col4 = -1, $return = false)
3460 if (($r == 0 and $g == 0 and $b == 0 && $col4 == -1) or $g == -1) {
3461 $col = $this->colorConverter->convert($r, $this->PDFAXwarnings);
3462 } elseif ($col4 == -1) {
3463 $col = $this->colorConverter->convert('rgb(' . $r . ',' . $g . ',' . $b . ')', $this->PDFAXwarnings);
3465 $col = $this->colorConverter->convert('cmyk(' . $r . ',' . $g . ',' . $b . ',' . $col4 . ')', $this->PDFAXwarnings);
3467 $out = $this->SetTColor($col, $return);
3507 // Get width of a single character in the current Core font
3511 if ($c == chr(173) && $this->FontFamily != 'csymbol' && $this->FontFamily != 'czapfdingbats') {
3513 } elseif (($this->textvar & TextVars::FC_SMALLCAPS) && isset($this->upperCase[ord($c)])) { // mPDF 5.7.1
3514 $charw = $this->CurrentFont['cw'][chr($this->upperCase[ord($c)])];
3516 $charw = $charw * $this->smCapsScale * $this->smCapsStretch / 100;
3519 } elseif (isset($this->CurrentFont['cw'][$c])) {
3520 $w += $this->CurrentFont['cw'][$c];
3521 } elseif (isset($this->CurrentFont['cw'][ord($c)])) {
3522 $w += $this->CurrentFont['cw'][ord($c)];
3524 $w *= ($this->FontSize / 1000);
3525 if ($this->minwSpacing || $this->fixedlSpacing) {
3531 $w += $this->fixedlSpacing + ($nb_spaces * $this->minwSpacing);
3538 // Get width of a single character in the current Non-Core font
3541 $unicode = $this->UTF8StringToArray($c, $addSubset);
3543 /* -- CJK-FONTS -- */
3544 if ($this->CurrentFont['type'] == 'Type0') { // CJK Adobe fonts
3548 elseif (isset($this->CurrentFont['cw'][$char])) {
3549 $w+=$this->CurrentFont['cw'][$char];
3550 } elseif (isset($this->CurrentFont['MissingWidth'])) {
3551 $w += $this->CurrentFont['MissingWidth'];
3556 /* -- END CJK-FONTS -- */
3560 elseif (($this->textvar & TextVars::FC_SMALLCAPS) && isset($this->upperCase[$char])) { // mPDF 5.7.1
3561 $charw = $this->_getCharWidth($this->CurrentFont['cw'], $this->upperCase[$char]);
3563 $charw = $charw * $this->smCapsScale * $this->smCapsStretch / 100;
3565 } elseif (isset($this->CurrentFont['desc']['MissingWidth'])) {
3566 $w += $this->CurrentFont['desc']['MissingWidth'];
3567 } elseif (isset($this->CurrentFont['MissingWidth'])) {
3568 $w += $this->CurrentFont['MissingWidth'];
3573 $charw = $this->_getCharWidth($this->CurrentFont['cw'], $char);
3576 } elseif (isset($this->CurrentFont['desc']['MissingWidth'])) {
3577 $w += $this->CurrentFont['desc']['MissingWidth'];
3578 } elseif (isset($this->CurrentFont['MissingWidth'])) {
3579 $w += $this->CurrentFont['MissingWidth'];
3584 } // *CJK-FONTS*
3585 $w *= ($this->FontSize / 1000);
3586 if ($this->minwSpacing || $this->fixedlSpacing) {
3592 $w += $this->fixedlSpacing + ($nb_spaces * $this->minwSpacing);
3599 if (!$this->usingCoreFont) {
3600 return $this->GetCharWidthNonCore($c, $addSubset);
3602 return $this->GetCharWidthCore($c);
3609 // Get width of a string in the current font
3611 $cw = &$this->CurrentFont['cw'];
3619 if ($this->iterationCounter) {
3620 $s = preg_replace('/{iteration ([a-zA-Z0-9_]+)}/', '\\1', $s);
3622 if (!$this->usingCoreFont) {
3624 $unicode = $this->UTF8StringToArray($s, $addSubset);
3625 if ($this->minwSpacing || $this->fixedlSpacing) {
3626 $nb_spaces = mb_substr_count($s, ' ', $this->mb_enc);
3627 $nb_carac = count($unicode) - $discards; // mPDF 6
3630 if (isset($this->CurrentFont['useOTL']) && $this->CurrentFont['useOTL']) {
3632 $nb_carac -= substr_count($OTLdata['group'], 'M');
3636 /* -- CJK-FONTS -- */
3637 if ($this->CurrentFont['type'] == 'Type0') { // CJK Adobe fonts
3644 } elseif (isset($this->CurrentFont['MissingWidth'])) {
3645 $w += $this->CurrentFont['MissingWidth'];
3651 /* -- END CJK-FONTS -- */
3656 if (($textvar & TextVars::FC_SMALLCAPS) && isset($this->upperCase[$char])) {
3657 $charw = $this->_getCharWidth($cw, $this->upperCase[$char]);
3659 $charw = $charw * $this->smCapsScale * $this->smCapsStretch / 100;
3661 } elseif (isset($this->CurrentFont['desc']['MissingWidth'])) {
3662 $w += $this->CurrentFont['desc']['MissingWidth'];
3663 } elseif (isset($this->CurrentFont['MissingWidth'])) {
3664 $w += $this->CurrentFont['MissingWidth'];
3669 $charw = $this->_getCharWidth($cw, $char);
3672 } elseif (isset($this->CurrentFont['desc']['MissingWidth'])) {
3673 $w += $this->CurrentFont['desc']['MissingWidth'];
3674 } elseif (isset($this->CurrentFont['MissingWidth'])) {
3675 $w += $this->CurrentFont['MissingWidth'];
3682 if (isset($this->CurrentFont['useOTL']) && ($this->CurrentFont['useOTL'] & 0xFF) && !empty($OTLdata)) {
3685 $w += $OTLdata['GPOSinfo'][$i]['XAdvanceR'] * 1000 / $this->CurrentFont['unitsPerEm'];
3689 $w += $OTLdata['GPOSinfo'][$i]['XAdvanceL'] * 1000 / $this->CurrentFont['unitsPerEm'];
3699 if (isset($this->CurrentFont['kerninfo'][$lastchar][$char])) {
3700 $kerning += $this->CurrentFont['kerninfo'][$lastchar][$char];
3706 } // *CJK-FONTS*
3708 if ($this->FontFamily != 'csymbol' && $this->FontFamily != 'czapfdingbats') {
3712 if ($this->minwSpacing || $this->fixedlSpacing) {
3716 if (($textvar & TextVars::FC_SMALLCAPS) && isset($this->upperCase[ord($s[$i])])) { // mPDF 5.7.1
3717 $charw = $cw[chr($this->upperCase[ord($s[$i])])];
3719 $charw = $charw * $this->smCapsScale * $this->smCapsStretch / 100;
3728 if (isset($this->CurrentFont['kerninfo'][$s[($i - 1)]][$s[$i]])) {
3729 $kerning += $this->CurrentFont['kerninfo'][$s[($i - 1)]][$s[$i]];
3738 $w *= ($this->FontSize / 1000);
3739 $w += (($nb_carac + $nb_spaces) * $this->fixedlSpacing) + ($nb_spaces * $this->minwSpacing);
3748 $this->LineWidth = $width;
3750 if ($this->page > 0 && ((isset($this->pageoutput[$this->page]['LineWidth']) && $this->pageoutput[$this->page]['LineWidth'] != $lwout) || !isset($this->pageoutput[$this->page]['LineWidth']))) {
3751 $this->writer->write($lwout);
3753 $this->pageoutput[$this->page]['LineWidth'] = $lwout;
3759 $this->writer->write(sprintf('%.3F %.3F m %.3F %.3F l S', $x1 * Mpdf::SCALE, ($this->h - $y1) * Mpdf::SCALE, $x2 * Mpdf::SCALE, ($this->h - $y2) * Mpdf::SCALE));
3765 // angle = splay of arrowhead - 1 - 89 degrees
3773 $a = atan2(($y2 - $y1), ($x2 - $x1));
3775 $c = $a - deg2rad($angle);
3776 $x3 = $x2 - ($headsize * cos($b));
3777 $y3 = $this->h - ($y2 - ($headsize * sin($b)));
3778 $x4 = $x2 - ($headsize * cos($c));
3779 $y4 = $this->h - ($y2 - ($headsize * sin($c)));
3781 $x5 = $x3 - ($x3 - $x4) / 2; // mid point of base of arrowhead - to join arrow line to
3782 $y5 = $y3 - ($y3 - $y4) / 2;
3785 $s .= sprintf('%.3F %.3F m %.3F %.3F l S', $x1 * Mpdf::SCALE, ($this->h - $y1) * Mpdf::SCALE, $x5 * Mpdf::SCALE, $y5 * Mpdf::SCALE);
3786 $this->writer->write($s);
3789 $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->h - $y2) * Mpdf::SCALE, $x4 * Mpdf::SCALE, $y4 * Mpdf::SCALE, $x5 * Mpdf::SCALE, $y5 * Mpdf::SCALE);
3791 $this->writer->write($s);
3804 $this->writer->write(sprintf('%.3F %.3F %.3F %.3F re %s', $x * Mpdf::SCALE, ($this->h - $y) * Mpdf::SCALE, $w * Mpdf::SCALE, -$h * Mpdf::SCALE, $op));
3809 $this->fontDir[] = $directory;
3810 $this->fontFileFinder->setDirectories($this->fontDir);
3829 // check if the font has been already added
3830 if (isset($this->fonts[$fontkey])) {
3834 /* -- CJK-FONTS -- */
3835 if (in_array($family, $this->available_CJK_fonts)) {
3836 if (empty($this->Big5_widths)) {
3839 $this->AddCJKFont($family); // don't need to add style
3842 /* -- END CJK-FONTS -- */
3844 if ($this->usingCoreFont) {
3845 throw new \Mpdf\MpdfException("mPDF Error - problem with Font management");
3853 if (!isset($this->fontdata[$family][$stylekey]) || !$this->fontdata[$family][$stylekey]) {
3854 throw new \Mpdf\MpdfException(sprintf('Font "%s%s%s" is not supported', $family, $style ? ' - ' : '', $style));
3858 $font = [
3886 if ($this->fontCache->jsonHas($fontCacheFilename)) {
3887 $font = $this->fontCache->jsonLoad($fontCacheFilename);
3890 $ttffile = $this->fontFileFinder->findFontFile($this->fontdata[$family][$stylekey]);
3893 $TTCfontID = isset($this->fontdata[$family]['TTCfontID'][$stylekey]) ? isset($this->fontdata[$family]['TTCfontID'][$stylekey]) : 0;
3894 $fontUseOTL = isset($this->fontdata[$family]['useOTL']) ? $this->fontdata[$family]['useOTL'] : false;
3895 $BMPonly = in_array($family, $this->BMPonly) ? true : false;
3898 if ($BMPonly && !$font['BMPselected']) {
3900 } elseif (!$BMPonly && $font['BMPselected']) {
3904 if ($fontUseOTL && $font['useOTL'] != $fontUseOTL) {
3906 $font['useOTL'] = $fontUseOTL;
3907 } elseif (!$fontUseOTL && $font['useOTL']) {
3909 $font['useOTL'] = 0;
3912 if ($this->fontDescriptor != $font['fontmetrics']) {
3916 if (empty($font['name']) || $font['originalsize'] != $ttfstat['size'] || $regenerate) {
3917 $generator = new MetricsGenerator($this->fontCache, $this->fontDescriptor);
3919 $generator->generateMetrics(
3924 $this->debugfonts,
3926 $font['useOTL'],
3930 $font = $this->fontCache->jsonLoad($fontCacheFilename);
3931 $cw = $this->fontCache->load($fontkey . '.cw.dat');
3932 $glyphIDtoUni = $this->fontCache->load($fontkey . '.gid.dat');
3934 if ($this->fontCache->has($fontkey . '.cw.dat')) {
3935 $cw = $this->fontCache->load($fontkey . '.cw.dat');
3938 if ($this->fontCache->has($fontkey . '.gid.dat')) {
3939 $glyphIDtoUni = $this->fontCache->load($fontkey . '.gid.dat');
3943 if (isset($this->fontdata[$family]['sip-ext']) && $this->fontdata[$family]['sip-ext']) {
3944 $sipext = $this->fontdata[$family]['sip-ext'];
3950 if (isset($this->fontdata[$family]['Ascent']) && $this->fontdata[$family]['Ascent']) {
3951 $desc['Ascent'] = $this->fontdata[$family]['Ascent'];
3953 if (isset($this->fontdata[$family]['Descent']) && $this->fontdata[$family]['Descent']) {
3954 $desc['Descent'] = $this->fontdata[$family]['Descent'];
3956 if (isset($this->fontdata[$family]['Leading']) && $this->fontdata[$family]['Leading']) {
3957 $desc['Leading'] = $this->fontdata[$family]['Leading'];
3960 $i = count($this->fonts) + $this->extraFontSubsets + 1;
3962 $this->fonts[$fontkey] = [
3964 'name' => $font['name'],
3965 'type' => $font['type'],
3966 'desc' => $font['desc'],
3967 'panose' => $font['panose'],
3968 'unitsPerEm' => $font['unitsPerEm'],
3969 'up' => $font['up'],
3970 'ut' => $font['ut'],
3971 'strs' => $font['strs'],
3972 'strp' => $font['strp'],
3977 'sip' => $font['sip'],
3979 'smp' => $font['smp'],
3982 'useKashida' => (isset($this->fontdata[$family]['useKashida']) ? $this->fontdata[$family]['useKashida'] : false),
3983 'GSUBScriptLang' => $font['GSUBScriptLang'],
3984 'GSUBFeatures' => $font['GSUBFeatures'],
3985 'GSUBLookups' => $font['GSUBLookups'],
3986 'GPOSScriptLang' => $font['GPOSScriptLang'],
3987 'GPOSFeatures' => $font['GPOSFeatures'],
3988 'GPOSLookups' => $font['GPOSLookups'],
3989 'rtlPUAstr' => $font['rtlPUAstr'],
3991 'haskerninfo' => $font['haskerninfo'],
3992 'haskernGPOS' => $font['haskernGPOS'],
3993 'hassmallcapsGSUB' => $font['hassmallcapsGSUB'],
3997 if (!$font['sip'] && !$font['smp']) {
3999 $this->fonts[$fontkey]['subset'] = array_combine($subsetRange, $subsetRange);
4001 $this->fonts[$fontkey]['subsets'] = [0 => range(0, 127)];
4002 $this->fonts[$fontkey]['subsetfontids'] = [$i];
4005 if ($font['haskerninfo']) {
4006 $this->fonts[$fontkey]['kerninfo'] = $font['kerninfo'];
4009 $this->FontFiles[$fontkey] = [
4010 'length1' => $font['originalsize'],
4013 'sip' => $font['sip'],
4014 'smp' => $font['smp'],
4020 function SetFont($family, $style = '', $size = 0, $write = true, $forcewrite = false)
4024 if (!$this->onlyCoreFonts) {
4025 if ($family == 'sans' || $family == 'sans-serif') {
4026 $family = $this->sans_fonts[0];
4029 $family = $this->serif_fonts[0];
4032 $family = $this->mono_fonts[0];
4036 if (isset($this->fonttrans[$family]) && $this->fonttrans[$family]) {
4037 $family = $this->fonttrans[$family];
4041 if ($this->FontFamily) {
4042 $family = $this->FontFamily;
4043 } elseif ($this->default_font) {
4044 $family = $this->default_font;
4046 throw new \Mpdf\MpdfException("No font or default font set!");
4050 $this->ReqFontStyle = $style; // required or requested style - used later for artificial bold/italic
4053 if ($this->PDFA || $this->PDFX) {
4055 throw new \Mpdf\MpdfException("Symbol and Zapfdingbats cannot be embedded in mPDF (required for PDFA1-b or PDFX/1-a).");
4058 if (($this->PDFA && !$this->PDFAauto) || ($this->PDFX && !$this->PDFXauto)) {
4059 $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.)";
4071 $this->usingCoreFont = false;
4073 $this->usingCoreFont = true;
4079 $this->usingCoreFont = false;
4090 if (!$size) {
4091 $size = $this->FontSizePt;
4102 if (!$this->onlyCoreFonts && !$this->usingCoreFont) {
4103 if (!isset($this->fonts[$fontkey]) || count($this->default_available_fonts) != count($this->available_unifonts)) { // not already added
4105 /* -- CJK-FONTS -- */
4106 if (in_array($fontkey, $this->available_CJK_fonts)) {
4107 if (!isset($this->fonts[$fontkey])) { // already added
4108 if (empty($this->Big5_widths)) {
4111 $this->AddCJKFont($family); // don't need to add style
4113 } else { // Test to see if requested font/style is available - or substitute /* -- END CJK-FONTS -- */
4114 if (!in_array($fontkey, $this->available_unifonts)) {
4115 // If font[nostyle] exists - set it
4116 if (in_array($family, $this->available_unifonts)) {
4118 } // elseif only one font available - set it (assumes if only one font available it will not have a style)
4119 elseif (count($this->available_unifonts) == 1) {
4120 $family = $this->available_unifonts[0];
4124 // else substitute font of similar type
4125 if (in_array($family, $this->sans_fonts)) {
4126 $i = array_intersect($this->sans_fonts, $this->available_unifonts);
4130 if (!in_array(($i[0] . $style), $this->available_unifonts)) {
4136 } elseif (in_array($family, $this->serif_fonts)) {
4137 $i = array_intersect($this->serif_fonts, $this->available_unifonts);
4141 if (!in_array(($i[0] . $style), $this->available_unifonts)) {
4147 } elseif (in_array($family, $this->mono_fonts)) {
4148 $i = array_intersect($this->mono_fonts, $this->available_unifonts);
4152 if (!in_array(($i[0] . $style), $this->available_unifonts)) {
4161 // set first available font
4162 $fs = $this->available_unifonts[0];
4163 preg_match('/^([a-z_0-9\-]+)([BI]{0,2})$/', $fs, $fas); // Allow "-"
4166 if (in_array($ws, $this->available_unifonts)) {
4168 } elseif (in_array($fas[1], $this->available_unifonts)) {
4184 // try to add font (if not already added)
4185 $this->AddFont($family, $style);
4187 // Test if font is already selected
4188 if ($this->FontFamily == $family && $this->FontFamily == $this->currentfontfamily && $this->FontStyle == $style && $this->FontStyle == $this->currentfontstyle && $this->FontSizePt == $size && $this->FontSizePt == $this->currentfontsize && !$forcewrite) {
4195 $this->FontFamily = $family;
4196 $this->FontStyle = $style;
4197 $this->FontSizePt = $size;
4198 $this->FontSize = $size / Mpdf::SCALE;
4199 $this->CurrentFont = &$this->fonts[$fontkey];
4201 $fontout = (sprintf('BT /F%d %.3F Tf ET', $this->CurrentFont['i'], $this->FontSizePt));
4202 if ($this->page > 0 && ((isset($this->pageoutput[$this->page]['Font']) && $this->pageoutput[$this->page]['Font'] != $fontout) || !isset($this->pageoutput[$this->page]['Font']))) {
4203 $this->writer->write($fontout);
4205 $this->pageoutput[$this->page]['Font'] = $fontout;
4208 // Added - currentfont (lowercase) used in HTML2PDF
4209 $this->currentfontfamily = $family;
4210 $this->currentfontsize = $size;
4211 $this->currentfontstyle = $style;
4212 $this->setMBencoding('UTF-8');
4214 if ($this->PDFA || $this->PDFX) {
4215 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.');
4217 $this->setMBencoding('windows-1252');
4219 // Test if font is already selected
4220 if (($this->FontFamily == $family) and ( $this->FontStyle == $style) and ( $this->FontSizePt == $size) && !$forcewrite) {
4224 if (!isset($this->CoreFonts[$fontkey])) {
4225 if (in_array($family, $this->serif_fonts)) {
4227 } elseif (in_array($family, $this->mono_fonts)) {
4232 $this->usingCoreFont = true;
4236 if (!isset($this->fonts[$fontkey])) {
4238 if (isset($this->CoreFonts[$fontkey])) {
4244 require __DIR__ . '/../data/font/' . $file . '.php';
4246 throw new \Mpdf\MpdfException(sprintf('Could not include font metric file "%s"', $file));
4248 $i = count($this->fonts) + $this->extraFontSubsets + 1;
4249 $this->fonts[$fontkey] = ['i' => $i, 'type' => 'core', 'name' => $this->CoreFonts[$fontkey], 'desc' => $desc, 'up' => $up, 'ut' => $ut, 'cw' => $cw];
4250 if ($this->useKerning && isset($kerninfo)) {
4251 $this->fonts[$fontkey]['kerninfo'] = $kerninfo;
4254 throw new \Mpdf\MpdfException(sprintf('Font %s not defined', $fontkey));
4258 // Test if font is already selected
4259 if (($this->FontFamily == $family) and ( $this->FontStyle == $style) and ( $this->FontSizePt == $size) && !$forcewrite) {
4263 $this->FontFamily = $family;
4264 $this->FontStyle = $style;
4265 $this->FontSizePt = $size;
4266 $this->FontSize = $size / Mpdf::SCALE;
4267 $this->CurrentFont = &$this->fonts[$fontkey];
4269 $fontout = (sprintf('BT /F%d %.3F Tf ET', $this->CurrentFont['i'], $this->FontSizePt));
4270 if ($this->page > 0 && ((isset($this->pageoutput[$this->page]['Font']) && $this->pageoutput[$this->page]['Font'] != $fontout) || !isset($this->pageoutput[$this->page]['Font']))) {
4271 $this->writer->write($fontout);
4273 $this->pageoutput[$this->page]['Font'] = $fontout;
4275 // Added - currentfont (lowercase) used in HTML2PDF
4276 $this->currentfontfamily = $family;
4277 $this->currentfontsize = $size;
4278 $this->currentfontstyle = $style;
4284 function SetFontSize($size, $write = true)
4286 // Set font size in points
4287 if ($this->FontSizePt == $size) {
4290 $this->FontSizePt = $size;
4291 $this->FontSize = $size / Mpdf::SCALE;
4292 $this->currentfontsize = $size;
4294 $fontout = (sprintf('BT /F%d %.3F Tf ET', $this->CurrentFont['i'], $this->FontSizePt));
4296 if ($this->page > 0 && ((isset($this->pageoutput[$this->page]['Font']) && $this->pageoutput[$this->page]['Font'] != $fontout) || !isset($this->pageoutput[$this->page]['Font']))) {
4297 $this->writer->write($fontout);
4299 $this->pageoutput[$this->page]['Font'] = $fontout;
4306 $n = count($this->links) + 1;
4307 $this->links[$n] = [0, 0];
4311 function SetLink($link, $y = 0, $page = -1)
4314 if ($y == -1) {
4315 $y = $this->y;
4317 if ($page == -1) {
4318 $page = $this->page;
4320 $this->links[$link] = [$page, $y];
4325 $l = [$x * Mpdf::SCALE, $this->hPt - $y * Mpdf::SCALE, $w * Mpdf::SCALE, $h * Mpdf::SCALE, $link];
4326 if ($this->keep_block_together) { // don't write yet
4328 } elseif ($this->table_rotate) { // *TABLES*
4329 $this->tbrot_Links[$this->page][] = $l; // *TABLES*
4332 elseif ($this->kwt) {
4333 $this->kwt_Links[$this->page][] = $l;
4337 if ($this->writingHTMLheader || $this->writingHTMLfooter) {
4338 $this->HTMLheaderPageLinks[] = $l;
4342 $this->PageLinks[$this->page][] = $l;
4343 // Save cross-reference to Column buffer
4344 $ref = count($this->PageLinks[$this->page]) - 1; // *COLUMNS*
4345 $this->columnLinks[$this->CurrCol][(int) $this->x][(int) $this->y] = $ref; // *COLUMNS*
4353 // Expects Font to be set
4357 if ($this->falseBoldWeight && strpos($this->ReqFontStyle, "B") !== false && strpos($this->FontStyle, "B") === false) {
4359 $s .= sprintf('%.3F w ', ($this->FontSize / 130) * Mpdf::SCALE * $this->falseBoldWeight);
4360 $tc = strtoupper($this->TextColor); // change 0 0 0 rg to 0 0 0 RG
4361 if ($this->FillColor != $tc) {
4365 if (strpos($this->ReqFontStyle, "I") !== false && strpos($this->FontStyle, "I") === false) {
4373 if ($this->ColorFlag) {
4374 $s .= $this->TextColor . ' ';
4377 $this->CurrentFont['used'] = true;
4379 if ($this->usingCoreFont) {
4389 $py = ($this->h - $y) * Mpdf::SCALE;
4397 if ($this->usingCoreFont && !($textvar & TextVars::FC_SMALLCAPS) && !($textvar & TextVars::FC_KERNING)) {
4398 $txt2 = $this->writer->escape($txt2);
4402 elseif (!$this->usingCoreFont && !($textvar & TextVars::FC_SMALLCAPS) && !($textvar & TextVars::FC_KERNING) && !(isset($this->CurrentFont['useOTL']) && ($this->CurrentFont['useOTL'] & 0xFF) && !empty($OTLdata['GPOSinfo']))) {
4404 if ($this->CurrentFont['sip'] || $this->CurrentFont['smp']) {
4405 $txt2 = $this->UTF8toSubset($txt2);
4409 $txt2 = $this->writer->utf8ToUtf16BigEndian($txt2, false);
4410 $txt2 = $this->writer->escape($txt2);
4417 $s .= $this->applyGPOSpdf($txt2, $aix, $px, $py, $OTLdata, $textvar);
4424 $c = strtoupper($this->TextColor); // change 0 0 0 rg to 0 0 0 RG
4425 if ($this->FillColor != $c) {
4428 if (isset($this->CurrentFont['up']) && $this->CurrentFont['up']) {
4429 $up = $this->CurrentFont['up'];
4431 $up = -100;
4433 $adjusty = (-$up / 1000 * $this->FontSize);
4434 if (isset($this->CurrentFont['ut']) && $this->CurrentFont['ut']) {
4435 $ut = $this->CurrentFont['ut'] / 1000 * $this->FontSize;
4437 $ut = 60 / 1000 * $this->FontSize;
4439 $olw = $this->LineWidth;
4441 $s .= ' ' . $this->_dounderline($x, $y + $adjusty, $txt, $OTLdata, $textvar);
4443 if ($this->FillColor != $c) {
4444 $s.= ' ' . $this->FillColor . ' ';
4449 $c = strtoupper($this->TextColor); // change 0 0 0 rg to 0 0 0 RG
4450 if ($this->FillColor != $c) {
4453 // Superscript and Subscript Y coordinate adjustment (now for striked-through texts)
4454 if (isset($this->CurrentFont['desc']['CapHeight']) && $this->CurrentFont['desc']['CapHeight']) {
4455 $ch = $this->CurrentFont['desc']['CapHeight'];
4459 $adjusty = (-$ch / 1000 * $this->FontSize) * 0.35;
4460 if (isset($this->CurrentFont['ut']) && $this->CurrentFont['ut']) {
4461 $ut = $this->CurrentFont['ut'] / 1000 * $this->FontSize;
4463 $ut = 60 / 1000 * $this->FontSize;
4465 $olw = $this->LineWidth;
4467 $s .= ' ' . $this->_dounderline($x, $y + $adjusty, $txt, $OTLdata, $textvar);
4469 if ($this->FillColor != $c) {
4470 $s.= ' ' . $this->FillColor . ' ';
4478 $this->writer->write($s);
4481 /* -- DIRECTW -- */
4486 $txt = $this->purify_utf8_text($txt);
4487 if ($this->text_input_as_HTML) {
4488 $txt = $this->all_entities_to_utf8($txt);
4490 if ($this->usingCoreFont) {
4491 $txt = mb_convert_encoding($txt, $this->mb_enc, 'UTF-8');
4495 if (preg_match("/([" . $this->pregRTLchars . "])/u", $txt)) {
4496 $this->biDirectional = true;
4500 $save_OTLtags = $this->OTLtags;
4501 $this->OTLtags = [];
4502 if ($this->useKerning) {
4503 if ($this->CurrentFont['haskernGPOS']) {
4504 $this->OTLtags['Plus'] .= ' kern';
4510 /* -- OTL -- */
4511 // Use OTL OpenType Table Layout - GSUB & GPOS
4512 if (isset($this->CurrentFont['useOTL']) && $this->CurrentFont['useOTL']) {
4513 $txt = $this->otl->applyOTL($txt, $this->CurrentFont['useOTL']);
4514 $OTLdata = $this->otl->OTLdata;
4516 /* -- END OTL -- */
4517 $this->OTLtags = $save_OTLtags;
4519 $this->magic_reverse_dir($txt, $this->directionality, $OTLdata);
4521 $this->Text($x, $y, $txt, $OTLdata, $textvar);
4527 $txt = $this->purify_utf8_text($txt);
4528 if ($this->text_input_as_HTML) {
4529 $txt = $this->all_entities_to_utf8($txt);
4531 if ($this->usingCoreFont) {
4532 $txt = mb_convert_encoding($txt, $this->mb_enc, 'UTF-8');
4535 if (preg_match("/([" . $this->pregRTLchars . "])/u", $txt)) {
4536 $this->biDirectional = true;
4540 $save_OTLtags = $this->OTLtags;
4541 $this->OTLtags = [];
4542 if ($this->useKerning) {
4543 if ($this->CurrentFont['haskernGPOS']) {
4544 $this->OTLtags['Plus'] .= ' kern';
4550 /* -- OTL -- */
4551 // Use OTL OpenType Table Layout - GSUB & GPOS
4552 if (isset($this->CurrentFont['useOTL']) && $this->CurrentFont['useOTL']) {
4553 $txt = $this->otl->applyOTL($txt, $this->CurrentFont['useOTL']);
4554 $OTLdata = $this->otl->OTLdata;
4556 /* -- END OTL -- */
4557 $this->OTLtags = $save_OTLtags;
4559 $this->magic_reverse_dir($txt, $this->directionality, $OTLdata);
4561 $this->Cell($w, $h, $txt, $border, $ln, $align, $fill, $link, $currentx, 0, 0, 'M', 0, false, $OTLdata, $textvar);
4564 /* -- END DIRECTW -- */
4568 if ($this->ws != 0) {
4569 $this->writer->write('BT 0 Tw ET');
4571 $this->ws = 0;
4572 if ($this->charspacing != 0) {
4573 $this->writer->write('BT 0 Tc ET');
4575 $this->charspacing = 0;
4584 $this->writer->write(sprintf('BT %.3F Tc ET', $cs));
4585 } elseif ($this->charspacing != 0) {
4586 $this->writer->write('BT 0 Tc ET');
4588 $this->charspacing = $cs;
4593 $this->writer->write(sprintf('BT %.3F Tw ET', $ws));
4594 } elseif ($this->ws != 0) {
4595 $this->writer->write('BT 0 Tw ET');
4597 $this->ws = $ws;
4605 if ($w > 0 && $inclCursive && isset($this->CurrentFont['useKashida']) && $this->CurrentFont['useKashida'] && !empty($cOTLdata)) {
4621 $last_kashida_in_word = -1;
4633 $last_kashida_in_word = -1;
4660 // % ratio divided between word-spacing and kashida-spacing
4661 $kashida_space_ratio = intval($this->CurrentFont['useKashida']) / 100;
4666 $tatw = $this->_getCharWidth($this->CurrentFont['cw'], 0x0640);
4669 // If not just leave to adjust word-spacing
4674 // At this point kashida is a number representing priority (higher number - higher priority)
4681 $w -= $kashida_space;
4687 $ww = $this->jSWord;
4688 $ncx = $nc - 1;
4692 elseif ($this->fixedlSpacing !== false || $inclCursive) {
4700 if (($this->jSmaxChar > 0) && ($charspacing > $this->jSmaxChar)) {
4701 $charspacing = $this->jSmaxChar;
4706 if ($this->usingCoreFont) {
4707 $cs = ($w * (1 - $this->jSWord)) / ($ncx );
4708 if (($this->jSmaxChar > 0) && ($cs > $this->jSmaxChar)) {
4709 $cs = $this->jSmaxChar;
4710 $ww = 1 - (($cs * ($ncx )) / $w);
4715 $cs = ($w * (1 - $this->jSWord)) / ($ncx - $ns);
4716 if (($this->jSmaxChar > 0) && ($cs > $this->jSmaxChar)) {
4717 $cs = $this->jSmaxChar;
4718 $ww = 1 - (($cs * ($ncx - $ns)) / $w);
4721 $ws = (($w * ($ww) ) / $ns) - $charspacing;
4737 if ($this->usingCoreFont) {
4743 $oldcolumn = $this->CurrCol;
4746 // Allows PAGE-BREAK-AFTER = avoid to work
4747 if (isset($this->blk[$this->blklvl])) {
4748 $bottom = $this->blk[$this->blklvl]['padding_bottom'] + $this->blk[$this->blklvl]['margin_bottom'];
4753 if (!$this->tableLevel
4755 ($this->y + $this->divheight > $this->PageBreakTrigger)
4756 || ($this->y + $h > $this->PageBreakTrigger)
4758 $this->y + ($h * 2) + $bottom > $this->PageBreakTrigger
4759 && (isset($this->blk[$this->blklvl]['page_break_after_avoid']) && $this->blk[$this->blklvl]['page_break_after_avoid'])
4762 && !$this->InFooter
4763 && $this->AcceptPageBreak()
4766 $x = $this->x; // Current X position
4769 $ws = $this->ws; // Word Spacing
4770 $charspacing = $this->charspacing; // Character Spacing
4771 $this->ResetSpacing();
4773 $this->AddPage($this->CurOrientation);
4776 $x += $this->MarginCorrection;
4778 $currentx += $this->MarginCorrection;
4780 $this->x = $x;
4782 $this->SetSpacing($charspacing, $ws);
4785 // Test: to put line through centre of cell: $this->Line($this->x,$this->y+($h/2),$this->x+50,$this->y+($h/2));
4788 /* -- COLUMNS -- */
4791 if ($this->CurrCol != $oldcolumn) {
4793 $currentx += $this->ChangeColumn * ($this->ColWidth + $this->ColGap);
4795 $this->x += $this->ChangeColumn * ($this->ColWidth + $this->ColGap);
4799 if ($this->ColActive) {
4801 $this->ColDetails[$this->CurrCol]['bottom_margin'] = $this->y + $h;
4803 $this->ColDetails[$this->CurrCol]['bottom_margin'] = $this->y + $this->divheight;
4806 /* -- END COLUMNS -- */
4810 $w = $this->w - $this->rMargin - $this->x;
4814 if ($fill == 1 && $this->FillColor) {
4815 if ((isset($this->pageoutput[$this->page]['FillColor']) && $this->pageoutput[$this->page]['FillColor'] != $this->FillColor) || !isset($this->pageoutput[$this->page]['FillColor'])) {
4816 $s .= $this->FillColor . ' ';
4818 $this->pageoutput[$this->page]['FillColor'] = $this->FillColor;
4821 if ($lineBox && isset($lineBox['boxtop']) && $txt) { // i.e. always from WriteFlowingBlock/finishFlowingBlock (but not objects -
4823 $boxtop = $this->y + $lineBox['boxtop'];
4824 $boxbottom = $this->y + $lineBox['boxbottom'];
4826 $baseline_shift = $lineBox['baseline-shift'];
4827 $bord_boxtop = $bg_boxtop = $boxtop = $boxtop - $baseline_shift;
4828 $bord_boxbottom = $bg_boxbottom = $boxbottom = $boxbottom - $baseline_shift;
4829 $bord_boxheight = $bg_boxheight = $boxheight = $boxbottom - $boxtop;
4832 if (isset($lineBox['background-boxtop'])) {
4833 $bg_boxtop = $this->y + $lineBox['background-boxtop'] - $lineBox['background-baseline-shift'];
4834 $bg_boxbottom = $this->y + $lineBox['background-boxbottom'] - $lineBox['background-baseline-shift'];
4835 $bg_boxheight = $bg_boxbottom - $bg_boxtop;
4838 if (isset($lineBox['border-boxtop'])) {
4839 $bord_boxtop = $this->y + $lineBox['border-boxtop'] - $lineBox['border-baseline-shift'];
4840 $bord_boxbottom = $this->y + $lineBox['border-boxbottom'] - $lineBox['border-baseline-shift'];
4841 $bord_boxheight = $bord_boxbottom - $bord_boxtop;
4846 $boxtop = $this->y;
4848 $boxbottom = $this->y + $h;
4853 // FONT SIZE - this determines the baseline caculation
4854 $bfs = $this->FontSize;
4856 $bfx = $this->baselineC;
4860 $baseline_shift = $this->textparam['text-baseline'];
4862 $baseline_shift = $this->textparam['text-baseline'];
4863 } elseif ($this->bullet) {
4864 $baseline += ($bfx - 0.7) * $this->FontSize;
4869 $va = (0.5 * $bfs * $this->normalLineheight);
4871 $va = $h - (0.5 * $bfs * $this->normalLineheight);
4876 // ONLY SET THESE IF WANT TO CONFINE BORDER +/- FILL TO FIT FONTSIZE - NOT FULL CELL AS IS ORIGINAL FUNCTION
4878 if ($spanfill || !empty($this->spanborddet) || $link != '') {
4880 $boxtop = $this->y + $baseline + $va - ($this->FontSize * (1 + $exth / 2) * (0.5 + $bfx));
4881 $boxheight = $this->FontSize * (1 + $exth);
4888 $boxtop -= $baseline_shift;
4889 $boxbottom -= $baseline_shift;
4892 $bord_boxheight = $bg_boxheight = $boxheight = $boxbottom - $boxtop;
4896 if (!empty($this->spanborddet)) {
4898 if (!isset($this->spanborddet['B'])) {
4899 $this->spanborddet['B'] = ['s' => 0, 'style' => '', 'w' => 0];
4902 if (!isset($this->spanborddet['T'])) {
4903 $this->spanborddet['T'] = ['s' => 0, 'style' => '', 'w' => 0];
4906 if (!isset($this->spanborddet['L'])) {
4907 $this->spanborddet['L'] = ['s' => 0, 'style' => '', 'w' => 0];
4910 if (!isset($this->spanborddet['R'])) {
4911 $this->spanborddet['R'] = ['s' => 0, 'style' => '', 'w' => 0];
4914 $bbw = $this->spanborddet['B']['w'];
4915 $tbw = $this->spanborddet['T']['w'];
4916 $lbw = $this->spanborddet['L']['w'];
4917 $rbw = $this->spanborddet['R']['w'];
4920 if ($fill == 1 || $border == 1 || !empty($this->spanborddet)) {
4922 if (!empty($this->spanborddet)) {
4925 $s .= sprintf('%.3F %.3F %.3F %.3F re f ', ($this->x - $lbw) * Mpdf::SCALE, ($this->h - $bg_boxtop + $tbw) * Mpdf::SCALE, ($w + $lbw + $rbw) * Mpdf::SCALE, (-$bg_boxheight - $tbw - $bbw) * Mpdf::SCALE);
4936 if ($this->spanborddet['T']['style'] == 'dashed') {
4938 } elseif ($this->spanborddet['T']['style'] == 'dotted') {
4939 $s .= sprintf(' 1 j 1 J [%.3F %.3F] %.3F d ', 0.001, $tbw * $dot * Mpdf::SCALE, -$tbw / 2 * Mpdf::SCALE);
4945 if ($this->spanborddet['T']['style'] != 'dotted') {
4947 $s .= sprintf('%.3F %.3F m ', ($this->x - $lbw) * Mpdf::SCALE, ($this->h - $bord_boxtop + $tbw) * Mpdf::SCALE);
4948 $s .= sprintf('%.3F %.3F l ', ($this->x + $w + $rbw) * Mpdf::SCALE, ($this->h - $bord_boxtop + $tbw) * Mpdf::SCALE);
4949 $s .= sprintf('%.3F %.3F l ', ($this->x + $w) * Mpdf::SCALE, ($this->h - $bord_boxtop) * Mpdf::SCALE);
4950 $s .= sprintf('%.3F %.3F l ', ($this->x) * Mpdf::SCALE, ($this->h - $bord_boxtop) * Mpdf::SCALE);
4951 $s .= ' h W n '; // Ends path no-op & Sets the clipping path
4954 $c = $this->SetDColor($this->spanborddet['T']['c'], true);
4956 if ($this->spanborddet['T']['style'] == 'double') {
4958 $s .= sprintf('%.3F %.3F m %.3F %.3F l S ', ($this->x - $lbw) * Mpdf::SCALE, ($this->h - $bord_boxtop + $tbw * 5 / 6) * Mpdf::SCALE, ($this->x + $w + $rbw) * Mpdf::SCALE, ($this->h - $bord_boxtop + $tbw * 5 / 6) * Mpdf::SCALE);
4959 $s .= sprintf('%.3F %.3F m %.3F %.3F l S ', ($this->x - $lbw) * Mpdf::SCALE, ($this->h - $bord_boxtop + $tbw / 6) * Mpdf::SCALE, ($this->x + $w + $rbw) * Mpdf::SCALE, ($this->h - $bord_boxtop + $tbw / 6) * Mpdf::SCALE);
4960 } elseif ($this->spanborddet['T']['style'] == 'dotted') {
4962 $s .= sprintf('%.3F %.3F m %.3F %.3F l S ', ($this->x - $lbw) * Mpdf::SCALE, ($this->h - $bord_boxtop + $tbw / 2) * Mpdf::SCALE, ($this->x + $w + $rbw - $short) * Mpdf::SCALE, ($this->h - $bord_boxtop + $tbw / 2) * Mpdf::SCALE);
4965 $s .= sprintf('%.3F %.3F m %.3F %.3F l S ', ($this->x - $lbw) * Mpdf::SCALE, ($this->h - $bord_boxtop + $tbw / 2) * Mpdf::SCALE, ($this->x + $w + $rbw - $short) * Mpdf::SCALE, ($this->h - $bord_boxtop + $tbw / 2) * Mpdf::SCALE);
4968 if ($this->spanborddet['T']['style'] != 'dotted') {
4975 if ($this->spanborddet['B']['style'] == 'dashed') {
4977 } elseif ($this->spanborddet['B']['style'] == 'dotted') {
4978 $s .= sprintf(' 1 j 1 J [%.3F %.3F] %.3F d ', 0.001, $bbw * $dot * Mpdf::SCALE, -$bbw / 2 * Mpdf::SCALE);
4984 if ($this->spanborddet['B']['style'] != 'dotted') {
4986 $s .= sprintf('%.3F %.3F m ', ($this->x - $lbw) * Mpdf::SCALE, ($this->h - $bord_boxbottom - $bbw) * Mpdf::SCALE);
4987 $s .= sprintf('%.3F %.3F l ', ($this->x + $w + $rbw) * Mpdf::SCALE, ($this->h - $bord_boxbottom - $bbw) * Mpdf::SCALE);
4988 $s .= sprintf('%.3F %.3F l ', ($this->x + $w) * Mpdf::SCALE, ($this->h - $bord_boxbottom) * Mpdf::SCALE);
4989 $s .= sprintf('%.3F %.3F l ', ($this->x) * Mpdf::SCALE, ($this->h - $bord_boxbottom) * Mpdf::SCALE);
4990 $s .= ' h W n '; // Ends path no-op & Sets the clipping path
4993 $c = $this->SetDColor($this->spanborddet['B']['c'], true);
4995 if ($this->spanborddet['B']['style'] == 'double') {
4997 $s .= sprintf('%.3F %.3F m %.3F %.3F l S ', ($this->x - $lbw) * Mpdf::SCALE, ($this->h - $bord_boxbottom - $bbw / 6) * Mpdf::SCALE, ($this->x + $w + $rbw - $short) * Mpdf::SCALE, ($this->h - $bord_boxbottom - $bbw / 6) * Mpdf::SCALE);
4998 $s .= sprintf('%.3F %.3F m %.3F %.3F l S ', ($this->x - $lbw) * Mpdf::SCALE, ($this->h - $bord_boxbottom - $bbw * 5 / 6) * Mpdf::SCALE, ($this->x + $w + $rbw - $short) * Mpdf::SCALE, ($this->h - $bord_boxbottom - $bbw * 5 / 6) * Mpdf::SCALE);
4999 } elseif ($this->spanborddet['B']['style'] == 'dotted') {
5001 $s .= sprintf('%.3F %.3F m %.3F %.3F l S ', ($this->x - $lbw) * Mpdf::SCALE, ($this->h - $bord_boxbottom - $bbw / 2) * Mpdf::SCALE, ($this->x + $w + $rbw - $short) * Mpdf::SCALE, ($this->h - $bord_boxbottom - $bbw / 2) * Mpdf::SCALE);
5004 $s .= sprintf('%.3F %.3F m %.3F %.3F l S ', ($this->x - $lbw) * Mpdf::SCALE, ($this->h - $bord_boxbottom - $bbw / 2) * Mpdf::SCALE, ($this->x + $w + $rbw - $short) * Mpdf::SCALE, ($this->h - $bord_boxbottom - $bbw / 2) * Mpdf::SCALE);
5007 if ($this->spanborddet['B']['style'] != 'dotted') {
5014 if ($this->spanborddet['L']['style'] == 'dashed') {
5016 } elseif ($this->spanborddet['L']['style'] == 'dotted') {
5017 $s .= sprintf(' 1 j 1 J [%.3F %.3F] %.3F d ', 0.001, $lbw * $dot * Mpdf::SCALE, -$lbw / 2 * Mpdf::SCALE);
5023 if ($this->spanborddet['L']['style'] != 'dotted') {
5025 $s .= sprintf('%.3F %.3F m ', ($this->x - $lbw) * Mpdf::SCALE, ($this->h - $bord_boxbottom - $bbw) * Mpdf::SCALE);
5026 $s .= sprintf('%.3F %.3F l ', ($this->x) * Mpdf::SCALE, ($this->h - $bord_boxbottom) * Mpdf::SCALE);
5027 $s .= sprintf('%.3F %.3F l ', ($this->x) * Mpdf::SCALE, ($this->h - $bord_boxtop) * Mpdf::SCALE);
5028 $s .= sprintf('%.3F %.3F l ', ($this->x - $lbw) * Mpdf::SCALE, ($this->h - $bord_boxtop + $tbw) * Mpdf::SCALE);
5029 $s .= ' h W n '; // Ends path no-op & Sets the clipping path
5032 $c = $this->SetDColor($this->spanborddet['L']['c'], true);
5033 if ($this->spanborddet['L']['style'] == 'double') {
5035 $s .= sprintf('%.3F %.3F m %.3F %.3F l S ', ($this->x - $lbw / 6) * Mpdf::SCALE, ($this->h - $bord_boxtop + $tbw) * Mpdf::SCALE, ($this->x - $lbw / 6) * Mpdf::SCALE, ($this->h - $bord_boxbottom - $bbw + $short) * Mpdf::SCALE);
5036 $s .= sprintf('%.3F %.3F m %.3F %.3F l S ', ($this->x - $lbw * 5 / 6) * Mpdf::SCALE, ($this->h - $bord_boxtop + $tbw) * Mpdf::SCALE, ($this->x - $lbw * 5 / 6) * Mpdf::SCALE, ($this->h - $bord_boxbottom - $bbw + $short) * Mpdf::SCALE);
5037 } elseif ($this->spanborddet['L']['style'] == 'dotted') {
5039 $s .= sprintf('%.3F %.3F m %.3F %.3F l S ', ($this->x - $lbw / 2) * Mpdf::SCALE, ($this->h - $bord_boxtop + $tbw) * Mpdf::SCALE, ($this->x - $lbw / 2) * Mpdf::SCALE, ($this->h - $bord_boxbottom - $bbw + $short) * Mpdf::SCALE);
5042 $s .= sprintf('%.3F %.3F m %.3F %.3F l S ', ($this->x - $lbw / 2) * Mpdf::SCALE, ($this->h - $bord_boxtop + $tbw) * Mpdf::SCALE, ($this->x - $lbw / 2) * Mpdf::SCALE, ($this->h - $bord_boxbottom - $bbw + $short) * Mpdf::SCALE);
5045 if ($this->spanborddet['L']['style'] != 'dotted') {
5053 if ($this->spanborddet['R']['style'] == 'dashed') {
5055 } elseif ($this->spanborddet['R']['style'] == 'dotted') {
5056 $s .= sprintf(' 1 j 1 J [%.3F %.3F] %.3F d ', 0.001, $rbw * $dot * Mpdf::SCALE, -$rbw / 2 * Mpdf::SCALE);
5062 if ($this->spanborddet['R']['style'] != 'dotted') {
5064 $s .= sprintf('%.3F %.3F m ', ($this->x + $w + $rbw) * Mpdf::SCALE, ($this->h - $bord_boxbottom - $bbw) * Mpdf::SCALE);
5065 $s .= sprintf('%.3F %.3F l ', ($this->x + $w) * Mpdf::SCALE, ($this->h - $bord_boxbottom) * Mpdf::SCALE);
5066 $s .= sprintf('%.3F %.3F l ', ($this->x + $w) * Mpdf::SCALE, ($this->h - $bord_boxtop) * Mpdf::SCALE);
5067 $s .= sprintf('%.3F %.3F l ', ($this->x + $w + $rbw) * Mpdf::SCALE, ($this->h - $bord_boxtop + $tbw) * Mpdf::SCALE);
5068 $s .= ' h W n '; // Ends path no-op & Sets the clipping path
5071 $c = $this->SetDColor($this->spanborddet['R']['c'], true);
5072 if ($this->spanborddet['R']['style'] == 'double') {
5074 $s .= sprintf('%.3F %.3F m %.3F %.3F l S ', ($this->x + $w + $rbw / 6) * Mpdf::SCALE, ($this->h - $bord_boxtop + $tbw) * Mpdf::SCALE, ($this->x + $w + $rbw / 6) * Mpdf::SCALE, ($this->h - $bord_boxbottom - $bbw + $short) * Mpdf::SCALE);
5075 $s .= sprintf('%.3F %.3F m %.3F %.3F l S ', ($this->x + $w + $rbw * 5 / 6) * Mpdf::SCALE, ($this->h - $bord_boxtop + $tbw) * Mpdf::SCALE, ($this->x + $w + $rbw * 5 / 6) * Mpdf::SCALE, ($this->h - $bord_boxbottom - $bbw + $short) * Mpdf::SCALE);
5076 } elseif ($this->spanborddet['R']['style'] == 'dotted') {
5078 $s .= sprintf('%.3F %.3F m %.3F %.3F l S ', ($this->x + $w + $rbw / 2) * Mpdf::SCALE, ($this->h - $bord_boxtop + $tbw) * Mpdf::SCALE, ($this->x + $w + $rbw / 2) * Mpdf::SCALE, ($this->h - $bord_boxbottom - $bbw + $short) * Mpdf::SCALE);
5081 $s .= sprintf('%.3F %.3F m %.3F %.3F l S ', ($this->x + $w + $rbw / 2) * Mpdf::SCALE, ($this->h - $bord_boxtop + $tbw) * Mpdf::SCALE, ($this->x + $w + $rbw / 2) * Mpdf::SCALE, ($this->h - $bord_boxbottom - $bbw + $short) * Mpdf::SCALE);
5084 if ($this->spanborddet['R']['style'] != 'dotted') {
5099 $s .= sprintf('%.3F %.3F %.3F %.3F re %s ', $this->x * Mpdf::SCALE, ($this->h - $bg_boxtop) * Mpdf::SCALE, $w * Mpdf::SCALE, -$bg_boxheight * Mpdf::SCALE, $op);
5105 $x = $this->x;
5106 $y = $this->y;
5109 $s .= sprintf('%.3F %.3F m %.3F %.3F l S ', $x * Mpdf::SCALE, ($this->h - $bord_boxtop) * Mpdf::SCALE, $x * Mpdf::SCALE, ($this->h - ($bord_boxbottom)) * Mpdf::SCALE);
5113 $s .= sprintf('%.3F %.3F m %.3F %.3F l S ', $x * Mpdf::SCALE, ($this->h - $bord_boxtop) * Mpdf::SCALE, ($x + $w) * Mpdf::SCALE, ($this->h - $bord_boxtop) * Mpdf::SCALE);
5117 $s .= sprintf('%.3F %.3F m %.3F %.3F l S ', ($x + $w) * Mpdf::SCALE, ($this->h - $bord_boxtop) * Mpdf::SCALE, ($x + $w) * Mpdf::SCALE, ($this->h - ($bord_boxbottom)) * Mpdf::SCALE);
5121 $s .= sprintf('%.3F %.3F m %.3F %.3F l S ', $x * Mpdf::SCALE, ($this->h - ($bord_boxbottom)) * Mpdf::SCALE, ($x + $w) * Mpdf::SCALE, ($this->h - ($bord_boxbottom)) * Mpdf::SCALE);
5130 $stringWidth = $this->GetStringWidth($txt, true, $OTLdata, $textvar) + ( $this->charspacing * mb_strlen($txt, $this->mb_enc) / Mpdf::SCALE ) + ( $this->ws * mb_substr_count($txt, ' ', $this->mb_enc) / Mpdf::SCALE );
5135 $dx = $w - $this->cMarginR - $stringWidth - $lcpaddingR;
5137 $dx = (($w - $stringWidth ) / 2);
5139 $dx = $this->cMarginL + $lcpaddingL;
5144 if ($this->ColorFlag) {
5145 $s .='q ' . $this->TextColor . ' ';
5149 if (isset($this->textparam['outline-s']) && $this->textparam['outline-s'] && !($textvar & TextVars::FC_SMALLCAPS)) { // mPDF 5.7.1
5150 $s .=' ' . sprintf('%.3F w', $this->LineWidth * Mpdf::SCALE) . ' ';
5151 $s .=" $this->DrawColor ";
5153 } 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 ???
5155 $s .= ' ' . sprintf('%.3F w', ($this->FontSize / 130) * Mpdf::SCALE * $this->falseBoldWeight) . ' ';
5156 $tc = strtoupper($this->TextColor); // change 0 0 0 rg to 0 0 0 RG
5157 if ($this->FillColor != $tc) {
5164 if (strpos($this->ReqFontStyle, "I") !== false && strpos($this->FontStyle, "I") === false) { // Artificial italic
5170 $px = ($this->x + $dx) * Mpdf::SCALE;
5171 $py = ($this->h - ($this->y + $glyphYorigin - $baseline_shift)) * Mpdf::SCALE;
5176 $this->CurrentFont['used'] = true;
5182 if ($this->usingCoreFont && !($textvar & TextVars::FC_SMALLCAPS) && !($textvar & TextVars::FC_KERNING)) {
5183 $txt2 = $this->writer->escape($txt2);
5187 elseif (!$this->usingCoreFont && !$this->ws && !($textvar & TextVars::FC_SMALLCAPS) && !($textvar & TextVars::FC_KERNING) && !(isset($this->CurrentFont['useOTL']) && ($this->CurrentFont['useOTL'] & 0xFF) && !empty($OTLdata['GPOSinfo']))) {
5189 if ((isset($this->CurrentFont['sip']) && $this->CurrentFont['sip']) || (isset($this->CurrentFont['smp']) && $this->CurrentFont['smp'])) {
5190 $txt2 = $this->UTF8toSubset($txt2);
5194 $txt2 = $this->writer->utf8ToUtf16BigEndian($txt2, false);
5195 $txt2 = $this->writer->escape($txt2);
5200 // IF multibyte - Tw has no effect - need to do word spacing using an adjustment before each space
5201 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)) )) {
5203 $space = $this->writer->utf8ToUtf16BigEndian($space, false);
5204 $space = $this->writer->escape($space);
5205 $sub .=sprintf('BT ' . $aix . ' %.3F Tc [', $px, $py, $this->charspacing);
5210 $tx = $this->writer->utf8ToUtf16BigEndian($tx, false);
5211 $tx = $this->writer->escape($tx);
5214 $adj = -($this->ws) * 1000 / $this->FontSizePt;
5222 $sub = $this->applyGPOSpdf($txt, $aix, $px, $py, $OTLdata, $textvar);
5227 if ($this->shrin_k > 1) {
5228 $shrin_k = $this->shrin_k;
5236 // mPDF 5.7.3 inline text-decoration parameters
5238 $c = isset($this->textparam['u-decoration']['color']) ? $this->textparam['u-decoration']['color'] : '';
5239 if ($this->FillColor != $c) {
5243 // mPDF 5.7.3 inline text-decoration parameters
5244 $decorationfontkey = isset($this->textparam['u-decoration']['fontkey']) ? $this->textparam['u-decoration']['fontkey'] : '';
5245 $decorationfontsize = isset($this->textparam['u-decoration']['fontsize']) ? $this->textparam['u-decoration']['fontsize'] / $shrin_k : 0;
5247 if (isset($this->fonts[$decorationfontkey]['ut']) && $this->fonts[$decorationfontkey]['ut']) {
5248 $ut = $this->fonts[$decorationfontkey]['ut'] / 1000 * $decorationfontsize;
5253 if (isset($this->fonts[$decorationfontkey]['up']) && $this->fonts[$decorationfontkey]['up']) {
5254 $up = $this->fonts[$decorationfontkey]['up'];
5256 $up = -100;
5259 $adjusty = (-$up / 1000 * $decorationfontsize) + $ut / 2;
5260 $ubaseline = isset($this->textparam['u-decoration']['baseline'])
5261 ? $glyphYorigin - $this->textparam['u-decoration']['baseline'] / $shrin_k
5264 $olw = $this->LineWidth;
5267 $sub .= ' ' . $this->_dounderline($this->x + $dx, $this->y + $ubaseline + $adjusty, $txt, $OTLdata, $textvar);
5270 if ($this->FillColor != $c) {
5271 $sub .= ' ' . $this->FillColor . ' ';
5278 // mPDF 5.7.3 inline text-decoration parameters
5279 $c = $this->textparam['s-decoration']['color'];
5281 if ($this->FillColor != $c) {
5285 // mPDF 5.7.3 inline text-decoration parameters
5286 $decorationfontkey = $this->textparam['s-decoration']['fontkey'];
5287 $decorationfontsize = $this->textparam['s-decoration']['fontsize'] / $shrin_k;
5290 if (isset($this->fonts[$decorationfontkey]['strs']) && $this->fonts[$decorationfontkey]['strs']) {
5291 $ut = $this->fonts[$decorationfontkey]['strs'] / 1000 * $decorationfontsize;
5293 elseif (isset($this->fonts[$decorationfontkey]['ut']) && $this->fonts[$decorationfontkey]['ut']) {
5294 $ut = $this->fonts[$decorationfontkey]['ut'] / 1000 * $decorationfontsize;
5300 if (isset($this->fonts[$decorationfontkey]['strp']) && $this->fonts[$decorationfontkey]['strp']) {
5301 $up = $this->fonts[$decorationfontkey]['strp'];
5302 $adjusty = (-$up / 1000 * $decorationfontsize);
5303 } // else use a fraction ($this->baselineS) of CapHeight
5305 if (isset($this->fonts[$decorationfontkey]['desc']['CapHeight']) && $this->fonts[$decorationfontkey]['desc']['CapHeight']) {
5306 $ch = $this->fonts[$decorationfontkey]['desc']['CapHeight'];
5310 $adjusty = (-$ch / 1000 * $decorationfontsize) * $this->baselineS;
5313 $sbaseline = $glyphYorigin - $this->textparam['s-decoration']['baseline'] / $shrin_k;
5315 $olw = $this->LineWidth;
5318 $sub .=' ' . $this->_dounderline($this->x + $dx, $this->y + $sbaseline + $adjusty, $txt, $OTLdata, $textvar);
5321 if ($this->FillColor != $c) {
5322 $sub .= ' ' . $this->FillColor . ' ';
5326 // mPDF 5.7.3 inline text-decoration parameters
5329 // mPDF 5.7.3 inline text-decoration parameters
5330 $c = $this->textparam['o-decoration']['color'];
5331 if ($this->FillColor != $c) {
5335 // mPDF 5.7.3 inline text-decoration parameters
5336 $decorationfontkey = (int) (((float) $this->textparam['o-decoration']['fontkey']) / $shrin_k);
5337 $decorationfontsize = $this->textparam['o-decoration']['fontsize'];
5339 if (isset($this->fonts[$decorationfontkey]['ut']) && $this->fonts[$decorationfontkey]['ut']) {
5340 $ut = $this->fonts[$decorationfontkey]['ut'] / 1000 * $decorationfontsize;
5344 if (isset($this->fonts[$decorationfontkey]['desc']['CapHeight']) && $this->fonts[$decorationfontkey]['desc']['CapHeight']) {
5345 $ch = $this->fonts[$decorationfontkey]['desc']['CapHeight'];
5349 $adjusty = (-$ch / 1000 * $decorationfontsize) * $this->baselineO;
5350 $obaseline = $glyphYorigin - $this->textparam['o-decoration']['baseline'] / $shrin_k;
5351 $olw = $this->LineWidth;
5353 $sub .=' ' . $this->_dounderline($this->x + $dx, $this->y + $obaseline + $adjusty, $txt, $OTLdata, $textvar);
5355 if ($this->FillColor != $c) {
5356 $sub .= ' ' . $this->FillColor . ' ';
5361 if ($this->textshadow) { // First to process is last in CSS comma separated shadows
5362 foreach ($this->textshadow as $ts) {
5364 $s .= $this->SetTColor($ts['col'], true) . "\n";
5366 $s .= $this->SetAlpha(ord($ts['col'][4]) / 100, 'Normal', true, 'F') . "\n";
5368 $s .= $this->SetAlpha(ord($ts['col'][5]) / 100, 'Normal', true, 'F') . "\n";
5370 $s .= $this->SetAlpha(ord($ts['col'][3]) / 100, 'Normal', true, 'F') . "\n";
5372 $s .= sprintf(' 1 0 0 1 %.4F %.4F cm', $ts['x'] * Mpdf::SCALE, -$ts['y'] * Mpdf::SCALE) . "\n";
5381 if ($this->ColorFlag) {
5387 $this->Link($this->x, $boxtop, $w, $boxheight, $link);
5391 $this->writer->write($s);
5395 if ($this->ws && !$this->usingCoreFont) {
5396 $this->writer->write(sprintf('BT %.3F Tc ET', $this->charspacing));
5398 $this->lasth = $h;
5404 $this->y += $h;
5408 $this->x = $currentx;
5410 $this->x = $this->lMargin;
5414 $this->x+=$w;
5422 if ((isset($this->CurrentFont['sip']) && $this->CurrentFont['sip']) || (isset($this->CurrentFont['smp']) && $this->CurrentFont['smp'])) {
5436 $fontid = $last_fontid = $original_fontid = $this->CurrentFont['subsetfontids'][0];
5438 $fontid = $last_fontid = $original_fontid = $this->CurrentFont['i'];
5442 $last_fontsize = $fontsize = $this->FontSizePt;
5446 $unicode = $this->UTF8StringToArray($txt);
5449 $charspacing = ($this->charspacing * 1000 / $this->FontSizePt);
5450 $wordspacing = ($this->ws * 1000 / $this->FontSizePt);
5458 // $txt= preg_replace('/'.preg_quote($this->aliasNbPg,'/').'/', chr(7), $txt); // ? Need to adjust OTL info
5459 // $txt= preg_replace('/'.preg_quote($this->aliasNbPgGp,'/').'/', chr(8), $txt); // ? Need to adjust OTL info
5476 $YPlacement = $GPOSinfo[$i]['YPlacement'] * $this->FontSizePt / $this->CurrentFont['unitsPerEm'];
5483 $GPOSinfo[$i]['XPlacement'] -= $GPOSinfo[$i]['BaseWidth'];
5488 $XshiftBefore += $GPOSinfo[$i]['XPlacement'] * 1000 / $this->CurrentFont['unitsPerEm'];
5489 $XshiftAfter += -$GPOSinfo[$i]['XPlacement'] * 1000 / $this->CurrentFont['unitsPerEm'];
5494 // font-related size
5503 if (substr($OTLdata['group'], ($i + 1), 1) != 'M') { // Don't add inter-character spacing before Marks
5508 // XAdvance from GPOS - Convert to PDF Text space (thousandths of a unit );
5510 $XshiftAfter += $GPOSinfo[$i]['XAdvanceL'] * 1000 / $this->CurrentFont['unitsPerEm'];
5512 $XshiftAfter += $GPOSinfo[$i]['XAdvanceR'] * 1000 / $this->CurrentFont['unitsPerEm'];
5514 } // Character & Word spacing - if NOT OTL
5524 if ($i > 0 && isset($this->CurrentFont['kerninfo'][$unicode[($i - 1)]][$unicode[$i]])) {
5525 $XshiftBefore += $this->CurrentFont['kerninfo'][$unicode[($i - 1)]][$unicode[$i]];
5537 $tj .= sprintf('>%d<', (-$XshiftBefore));
5539 $tj .= sprintf(')%d(', (-$XshiftBefore));
5543 // Small-Caps
5545 if (isset($this->upperCase[$c])) {
5546 $c = $this->upperCase[$c];
5547 // $this->CurrentFont['subset'][$this->upperCase[$c]] = $this->upperCase[$c]; // add the CAP to subset
5552 $fontstretch = $this->smCapsStretch;
5553 $fontsize = $this->FontSizePt * $this->smCapsScale;
5560 $fontsize = $this->FontSizePt;
5565 // Prepare Text and Select Font ID
5573 // if ($c == 7) { $tj .= $this->aliasNbPgHex; }
5574 // else { $tj .= $this->aliasNbPgGpHex; }
5578 $init = array_search($c, $this->CurrentFont['subsets'][$j]);
5580 if ($this->CurrentFont['subsetfontids'][$j] != $last_fontid) {
5582 $fontid = $this->CurrentFont['subsetfontids'][$j];
5586 } elseif (count($this->CurrentFont['subsets'][$j]) < 255) {
5587 $n = count($this->CurrentFont['subsets'][$j]);
5588 $this->CurrentFont['subsets'][$j][$n] = $c;
5589 if ($this->CurrentFont['subsetfontids'][$j] != $last_fontid) {
5591 $fontid = $this->CurrentFont['subsetfontids'][$j];
5595 } elseif (!isset($this->CurrentFont['subsets'][($j + 1)])) {
5596 $this->CurrentFont['subsets'][($j + 1)] = [0 => 0];
5597 $this->CurrentFont['subsetfontids'][($j + 1)] = count($this->fonts) + $this->extraFontSubsets + 1;
5598 $this->extraFontSubsets++;
5603 if ($this->usingCoreFont) {
5606 $tx = $this->writer->utf8ToUtf16BigEndian($tx, false);
5608 $tx = $this->writer->escape($tx);
5644 if (isset($this->CurrentFont['subset'])) {
5645 $this->CurrentFont['subset'][$c] = $c;
5647 $kashida *= 1000 / $this->FontSizePt;
5648 $tatw = $this->_getCharWidth($this->CurrentFont['cw'], 0x0640);
5656 $YPlacement = $GPOSinfo[$nextbase]['YPlacement'] * $this->FontSizePt / $this->CurrentFont['unitsPerEm'];
5659 // Prepare Text and Select Font ID
5662 $init = array_search($c, $this->CurrentFont['subsets'][$j]);
5664 if ($this->CurrentFont['subsetfontids'][$j] != $last_fontid) {
5665 $fontid = $this->CurrentFont['subsetfontids'][$j];
5669 } elseif (count($this->CurrentFont['subsets'][$j]) < 255) {
5670 $n = count($this->CurrentFont['subsets'][$j]);
5671 $this->CurrentFont['subsets'][$j][$n] = $c;
5672 if ($this->CurrentFont['subsetfontids'][$j] != $last_fontid) {
5673 $fontid = $this->CurrentFont['subsetfontids'][$j];
5677 } elseif (!isset($this->CurrentFont['subsets'][($j + 1)])) {
5678 $this->CurrentFont['subsets'][($j + 1)] = [0 => 0];
5679 $this->CurrentFont['subsetfontids'][($j + 1)] = count($this->fonts) + $this->extraFontSubsets + 1;
5680 $this->extraFontSubsets++;
5685 $tx = $this->writer->utf8ToUtf16BigEndian($tx, false);
5686 $tx = $this->writer->escape($tx);
5693 $nudgeback = (($nt + 1) * $tatw) - $kashida;
5740 $tj .= sprintf('%d', (-$XshiftAfter));
5751 $tj .= sprintf('%d', (-$XshiftAfter));
5772 // Convert string to UTF-16BE without BOM
5773 $space = $this->writer->utf8ToUtf16BigEndian($space, false);
5774 $space = $this->writer->escape($space);
5775 $s = sprintf(' BT ' . $aix, $x * Mpdf::SCALE, ($this->h - $y) * Mpdf::SCALE);
5781 $unicode = $this->UTF8StringToArray($tx);
5783 if ($ti > 0 && isset($this->CurrentFont['kerninfo'][$unicode[($ti - 1)]][$unicode[$ti]])) {
5784 $kern = -$this->CurrentFont['kerninfo'][$unicode[($ti - 1)]][$unicode[$ti]];
5788 $tc = $this->writer->utf8ToUtf16BigEndian($tc, false);
5789 $tj .= $this->writer->escape($tc);
5792 $s .= sprintf(' %.3F Tc [%s] TJ', $this->charspacing, $tj);
5796 $s .= sprintf(' %.3F Tc (%s) Tj', $this->ws + $this->charspacing, $space);
5800 } elseif (!$this->usingCoreFont) {
5803 $unicode = $this->UTF8StringToArray($txt);
5805 if ($i > 0 && isset($this->CurrentFont['kerninfo'][$unicode[($i - 1)]][$unicode[$i]])) {
5806 $kern = -$this->CurrentFont['kerninfo'][$unicode[($i - 1)]][$unicode[$i]];
5810 $tx = $this->writer->utf8ToUtf16BigEndian($tx, false);
5811 $tj .= $this->writer->escape($tx);
5814 $s .= sprintf(' BT ' . $aix . ' [%s] TJ ET ', $x * Mpdf::SCALE, ($this->h - $y) * Mpdf::SCALE, $tj);
5815 } else { // CORE Font
5820 if ($i > 0 && isset($this->CurrentFont['kerninfo'][$txt[($i - 1)]][$txt[$i]])) {
5821 $kern = -$this->CurrentFont['kerninfo'][$txt[($i - 1)]][$txt[$i]];
5824 $tj .= $this->writer->escape($txt[$i]);
5827 $s .= sprintf(' BT ' . $aix . ' [%s] TJ ET ', $x * Mpdf::SCALE, ($this->h - $y) * Mpdf::SCALE, $tj);
5846 // maxrows is called from mpdfform->TEXTAREA
5847 // Parameter (pre-)encoded - When called internally from form::textarea -
5848 // mb_encoding already done and OTL - but not reverse RTL
5851 $txt = $this->purify_utf8_text($txt);
5853 if ($this->text_input_as_HTML) {
5854 $txt = $this->all_entities_to_utf8($txt);
5857 if ($this->usingCoreFont) {
5858 $txt = mb_convert_encoding($txt, $this->mb_enc, 'UTF-8');
5861 if (preg_match("/([" . $this->pregRTLchars . "])/u", $txt)) {
5862 $this->biDirectional = true;
5865 /* -- OTL -- */
5870 // Use OTL OpenType Table Layout - GSUB & GPOS
5871 if (isset($this->CurrentFont['useOTL']) && $this->CurrentFont['useOTL']) {
5872 $txt = $this->otl->applyOTL($txt, $this->CurrentFont['useOTL']);
5873 $OTLdata = $this->otl->OTLdata;
5876 if ($directionality == 'rtl' || $this->biDirectional) {
5878 $unicode = $this->UTF8StringToArray($txt, false);
5880 $this->getBasicOTLdata($OTLdata, $unicode, $is_strong);
5883 /* -- END OTL -- */
5887 $align = $this->defaultAlign;
5891 $cw = &$this->CurrentFont['cw'];
5894 $w = $this->w - $this->rMargin - $this->x;
5897 $wmax = ($w - ($this->cMarginL + $this->cMarginR));
5899 if ($this->usingCoreFont) {
5902 while ($nb > 0 and $s[$nb - 1] == "\n") {
5903 $nb--;
5907 $nb = mb_strlen($s, $this->mb_enc);
5908 while ($nb > 0 and mb_substr($s, $nb - 1, 1, $this->mb_enc) == "\n") {
5909 $nb--;
5933 $sep = -1;
5941 $start_y = $this->y;
5943 if (!$this->usingCoreFont) {
5947 if (preg_match("/([" . $this->pregCURSchars . "])/u", $s)) {
5954 $c = mb_substr($s, $i, 1, $this->mb_enc);
5959 $this->ResetSpacing();
5960 $tmp = rtrim(mb_substr($s, $j, $i - $j, $this->mb_enc));
5963 /* -- OTL -- */
5965 $tmpOTLdata = $this->otl->sliceOTLdata($OTLdata, $j, $i - $j);
5966 $this->otl->trimOTLdata($tmpOTLdata, false, true);
5967 $this->magic_reverse_dir($tmp, $directionality, $tmpOTLdata);
5969 /* -- END OTL -- */
5971 $this->Cell($w, $h, $tmp, $b, 2, $align, $fill, $link, 0, 0, 0, 'M', 0, false, $tmpOTLdata);
5973 if ($maxrows != false && isset($this->form) && ($this->y - $start_y) / $h > $maxrows) {
5978 $sep = -1;
5997 $l += $this->GetCharWidthNonCore($c);
6002 if ($sep == -1) { // Only one word
6009 $this->ResetSpacing();
6010 $tmp = rtrim(mb_substr($s, $j, $i - $j, $this->mb_enc));
6013 /* -- OTL -- */
6015 $tmpOTLdata = $this->otl->sliceOTLdata($OTLdata, $j, $i - $j);
6016 $this->otl->trimOTLdata($tmpOTLdata, false, true);
6017 $this->magic_reverse_dir($tmp, $directionality, $tmpOTLdata);
6019 /* -- END OTL -- */
6021 $this->Cell($w, $h, $tmp, $b, 2, $align, $fill, $link, 0, 0, 0, 'M', 0, false, $tmpOTLdata);
6025 $tmp = rtrim(mb_substr($s, $j, $sep - $j, $this->mb_enc));
6028 /* -- OTL -- */
6030 $tmpOTLdata = $this->otl->sliceOTLdata($OTLdata, $j, $sep - $j);
6031 $this->otl->trimOTLdata($tmpOTLdata, false, true);
6033 /* -- END OTL -- */
6042 $len_ligne = $this->GetStringWidth($tmp, false, $tmpOTLdata);
6043 $nb_carac = mb_strlen($tmp, $this->mb_enc);
6044 $nb_spaces = mb_substr_count($tmp, ' ', $this->mb_enc);
6049 if (isset($this->CurrentFont['useOTL']) && ($this->CurrentFont['useOTL'])) {
6051 $nb_carac -= substr_count($tmpOTLdata['group'], 'M');
6055 list($charspacing, $ws, $kashida) = $this->GetJspacing($nb_carac, $nb_spaces, ((($wmax) - $len_ligne) * Mpdf::SCALE), $inclCursive, $tmpOTLdata);
6056 $this->SetSpacing($charspacing, $ws);
6060 $this->magic_reverse_dir($tmp, $directionality, $tmpOTLdata);
6063 $this->Cell($w, $h, $tmp, $b, 2, $align, $fill, $link, 0, 0, 0, 'M', 0, false, $tmpOTLdata);
6068 if ($maxrows != false && isset($this->form) && ($this->y - $start_y) / $h > $maxrows) {
6072 $sep = -1;
6090 $this->ResetSpacing();
6103 $this->ResetSpacing();
6104 $this->Cell($w, $h, substr($s, $j, $i - $j), $b, 2, $align, $fill, $link);
6106 if ($maxrows != false && isset($this->form) && ($this->y - $start_y) / $h > $maxrows) {
6111 $sep = -1;
6130 $l += $this->GetCharWidthCore($c);
6135 if ($sep == -1) {
6142 $this->ResetSpacing();
6143 $this->Cell($w, $h, substr($s, $j, $i - $j), $b, 2, $align, $fill, $link);
6149 $tmp = rtrim(substr($s, $j, $sep - $j));
6156 $len_ligne = $this->GetStringWidth($tmp);
6161 list($charspacing, $ws, $kashida) = $this->GetJspacing($nb_carac, $nb_spaces, ((($wmax) - $len_ligne) * Mpdf::SCALE), false, $tmpOTLdata);
6162 $this->SetSpacing($charspacing, $ws);
6165 $this->Cell($w, $h, substr($s, $j, $sep - $j), $b, 2, $align, $fill, $link);
6169 if ($maxrows != false && isset($this->form) && ($this->y - $start_y) / $h > $maxrows) {
6173 $sep = -1;
6191 $this->ResetSpacing();
6199 if (!$this->usingCoreFont) {
6201 $tmp = rtrim(mb_substr($s, $j, $i - $j, $this->mb_enc));
6204 /* -- OTL -- */
6206 $tmpOTLdata = $this->otl->sliceOTLdata($OTLdata, $j, $i - $j);
6207 $this->otl->trimOTLdata($tmpOTLdata, false, true);
6208 $this->magic_reverse_dir($tmp, $directionality, $tmpOTLdata);
6210 /* -- END OTL -- */
6212 $this->Cell($w, $h, $tmp, $b, 2, $align, $fill, $link, 0, 0, 0, 'M', 0, false, $tmpOTLdata);
6214 $this->Cell($w, $h, substr($s, $j, $i - $j), $b, 2, $align, $fill, $link);
6217 $this->x = $this->lMargin;
6220 /* -- DIRECTW -- */
6224 if (empty($this->directWrite)) {
6225 $this->directWrite = new DirectWrite($this, $this->otl, $this->sizeConverter, $this->colorConverter);
6228 $this->directWrite->Write($h, $txt, $currentx, $link, $directionality, $align, $fill);
6231 /* -- END DIRECTW -- */
6234 /* -- HTML-CSS -- */
6239 $saved['family'] = $this->FontFamily;
6240 $saved['style'] = $this->FontStyle;
6241 $saved['sizePt'] = $this->FontSizePt;
6242 $saved['size'] = $this->FontSize;
6243 $saved['HREF'] = $this->HREF;
6244 $saved['textvar'] = $this->textvar; // mPDF 5.7.1
6245 $saved['OTLtags'] = $this->OTLtags; // mPDF 5.7.1
6246 $saved['textshadow'] = $this->textshadow;
6247 $saved['linewidth'] = $this->LineWidth;
6248 $saved['drawcolor'] = $this->DrawColor;
6249 $saved['textparam'] = $this->textparam;
6250 $saved['lSpacingCSS'] = $this->lSpacingCSS;
6251 $saved['wSpacingCSS'] = $this->wSpacingCSS;
6252 $saved['I'] = $this->I;
6253 $saved['B'] = $this->B;
6254 $saved['colorarray'] = $this->colorarray;
6255 $saved['bgcolorarray'] = $this->spanbgcolorarray;
6256 $saved['border'] = $this->spanborddet;
6257 $saved['color'] = $this->TextColor;
6258 $saved['bgcolor'] = $this->FillColor;
6259 $saved['lang'] = $this->currentLang;
6260 $saved['fontLanguageOverride'] = $this->fontLanguageOverride; // mPDF 5.7.1
6261 $saved['display_off'] = $this->inlineDisplayOff;
6269 $this->FontStyle = $saved['style'];
6270 $this->FontSizePt = $saved['sizePt'];
6271 $this->FontSize = $saved['size'];
6273 $this->currentLang = $saved['lang'];
6274 $this->fontLanguageOverride = $saved['fontLanguageOverride']; // mPDF 5.7.1
6276 $this->ColorFlag = ($this->FillColor != $this->TextColor); // Restore ColorFlag as well
6278 $this->HREF = $saved['HREF'];
6279 $this->textvar = $saved['textvar']; // mPDF 5.7.1
6280 $this->OTLtags = $saved['OTLtags']; // mPDF 5.7.1
6281 $this->textshadow = $saved['textshadow'];
6282 $this->LineWidth = $saved['linewidth'];
6283 $this->DrawColor = $saved['drawcolor'];
6284 $this->textparam = $saved['textparam'];
6285 $this->inlineDisplayOff = $saved['display_off'];
6287 $this->lSpacingCSS = $saved['lSpacingCSS'];
6288 if (($this->lSpacingCSS || $this->lSpacingCSS === '0') && strtoupper($this->lSpacingCSS) != 'NORMAL') {
6289 $this->fixedlSpacing = $this->sizeConverter->convert($this->lSpacingCSS, $this->FontSize);
6291 $this->fixedlSpacing = false;
6293 $this->wSpacingCSS = $saved['wSpacingCSS'];
6294 if ($this->wSpacingCSS && strtoupper($this->wSpacingCSS) != 'NORMAL') {
6295 $this->minwSpacing = $this->sizeConverter->convert($this->wSpacingCSS, $this->FontSize);
6297 $this->minwSpacing = 0;
6300 $this->SetFont($FontFamily, $saved['style'], $saved['sizePt'], false);
6302 $this->currentfontstyle = $saved['style'];
6303 $this->currentfontsize = $saved['sizePt'];
6304 $this->SetStylesArray(['B' => $saved['B'], 'I' => $saved['I']]); // mPDF 5.7.1
6306 $this->TextColor = $saved['color'];
6307 $this->FillColor = $saved['bgcolor'];
6308 $this->colorarray = $saved['colorarray'];
6311 $this->SetTColor($cor);
6313 $this->spanbgcolorarray = $saved['bgcolorarray'];
6316 $this->SetFColor($cor);
6318 $this->spanborddet = $saved['border'];
6321 // Used when ColActive for tables - updated to return first block with background fill OR borders
6326 for ($i = 1; $i <= $this->blklvl; $i++) {
6327 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']) {
6335 // -------------------------FLOWING BLOCK------------------------------------//
6337 // --------------------------------------------------------------------------//
6342 $saved['family'] = $this->FontFamily;
6343 $saved['style'] = $this->FontStyle;
6344 $saved['sizePt'] = $this->FontSizePt;
6345 $saved['size'] = $this->FontSize;
6346 $saved['curr'] = &$this->CurrentFont;
6347 $saved['lang'] = $this->currentLang; // mPDF 6
6348 $saved['color'] = $this->TextColor;
6349 $saved['spanbgcolor'] = $this->spanbgcolor;
6350 $saved['spanbgcolorarray'] = $this->spanbgcolorarray;
6351 $saved['bord'] = $this->spanborder;
6352 $saved['border'] = $this->spanborddet;
6353 $saved['HREF'] = $this->HREF;
6354 $saved['textvar'] = $this->textvar; // mPDF 5.7.1
6355 $saved['textshadow'] = $this->textshadow;
6356 $saved['linewidth'] = $this->LineWidth;
6357 $saved['drawcolor'] = $this->DrawColor;
6358 $saved['textparam'] = $this->textparam;
6359 $saved['ReqFontStyle'] = $this->ReqFontStyle;
6360 $saved['fixedlSpacing'] = $this->fixedlSpacing;
6361 $saved['minwSpacing'] = $this->minwSpacing;
6371 $this->FontFamily = $saved['family'];
6372 $this->FontStyle = $saved['style'];
6373 $this->FontSizePt = $saved['sizePt'];
6374 $this->FontSize = $saved['size'];
6375 $this->CurrentFont = &$saved['curr'];
6376 $this->currentLang = $saved['lang']; // mPDF 6
6377 $this->TextColor = $saved['color'];
6378 $this->spanbgcolor = $saved['spanbgcolor'];
6379 $this->spanbgcolorarray = $saved['spanbgcolorarray'];
6380 $this->spanborder = $saved['bord'];
6381 $this->spanborddet = $saved['border'];
6382 $this->ColorFlag = ($this->FillColor != $this->TextColor); // Restore ColorFlag as well
6383 $this->HREF = $saved['HREF'];
6384 $this->fixedlSpacing = $saved['fixedlSpacing'];
6385 $this->minwSpacing = $saved['minwSpacing'];
6386 $this->textvar = $saved['textvar']; // mPDF 5.7.1
6387 $this->textshadow = $saved['textshadow'];
6388 $this->LineWidth = $saved['linewidth'];
6389 $this->DrawColor = $saved['drawcolor'];
6390 $this->textparam = $saved['textparam'];
6392 $this->SetFont($saved['family'], $saved['style'], $saved['sizePt'], true, true); // force output
6393 $fontout = (sprintf('BT /F%d %.3F Tf ET', $this->CurrentFont['i'], $this->FontSizePt));
6394 if ($this->page > 0 && ((isset($this->pageoutput[$this->page]['Font']) && $this->pageoutput[$this->page]['Font'] != $fontout) || !isset($this->pageoutput[$this->page]['Font']))) {
6395 $this->writer->write($fontout);
6397 $this->pageoutput[$this->page]['Font'] = $fontout;
6399 $this->SetFont($saved['family'], $saved['style'], $saved['sizePt'], false);
6401 $this->ReqFontStyle = $saved['ReqFontStyle'];
6413 $this->flowingBlockAttr['width'] = ($w * Mpdf::SCALE);
6415 $this->flowingBlockAttr['is_table'] = $is_table;
6416 $this->flowingBlockAttr['table_draft'] = $table_draft;
6417 $this->flowingBlockAttr['height'] = $h;
6418 $this->flowingBlockAttr['lineCount'] = 0;
6419 $this->flowingBlockAttr['align'] = $a;
6420 $this->flowingBlockAttr['font'] = [];
6421 $this->flowingBlockAttr['content'] = [];
6422 $this->flowingBlockAttr['contentB'] = [];
6423 $this->flowingBlockAttr['contentWidth'] = 0;
6424 $this->flowingBlockAttr['blockstate'] = $blockstate;
6426 $this->flowingBlockAttr['newblock'] = $newblock;
6427 $this->flowingBlockAttr['valign'] = 'M';
6428 $this->flowingBlockAttr['blockdir'] = $blockdir;
6429 $this->flowingBlockAttr['cOTLdata'] = []; // mPDF 5.7.1
6430 $this->flowingBlockAttr['lastBidiText'] = ''; // mPDF 5.7.1
6431 if (!empty($this->otl)) {
6432 $this->otl->lastBidiStrongType = '';
6438 $currentx = $this->x;
6440 $is_table = $this->flowingBlockAttr['is_table'];
6441 $table_draft = $this->flowingBlockAttr['table_draft'];
6442 $maxWidth = & $this->flowingBlockAttr['width'];
6443 $stackHeight = & $this->flowingBlockAttr['height'];
6444 $align = & $this->flowingBlockAttr['align'];
6445 $content = & $this->flowingBlockAttr['content'];
6446 $contentB = & $this->flowingBlockAttr['contentB'];
6447 $font = & $this->flowingBlockAttr['font'];
6448 $contentWidth = & $this->flowingBlockAttr['contentWidth'];
6449 $lineCount = & $this->flowingBlockAttr['lineCount'];
6450 $valign = & $this->flowingBlockAttr['valign'];
6451 $blockstate = $this->flowingBlockAttr['blockstate'];
6453 $cOTLdata = & $this->flowingBlockAttr['cOTLdata']; // mPDF 5.7.1
6454 $newblock = $this->flowingBlockAttr['newblock'];
6455 $blockdir = $this->flowingBlockAttr['blockdir'];
6458 if ($this->blk[$this->blklvl]['bgcolor'] && !$is_table) {
6461 $this->SetFColor($this->colorConverter->convert(255, $this->PDFAXwarnings));
6468 if (isset($content[count($content) - 1]) && preg_match('/[ ]+$/', $content[count($content) - 1], $m)) {
6470 $content[count($content) - 1] = substr($content[count($content) - 1], 0, (strlen($content[count($content) - 1]) - $strip));
6471 /* -- OTL -- */
6472 if (isset($this->CurrentFont['useOTL']) && $this->CurrentFont['useOTL']) {
6473 $this->otl->trimOTLdata($cOTLdata[count($cOTLdata) - 1], false, true);
6475 /* -- END OTL -- */
6482 $oldcolumn = $this->CurrCol;
6484 if ($this->ColActive && !$is_table) {
6485 $this->breakpoints[$this->CurrCol][] = $this->y;
6489 /* -- TABLES -- */
6496 /* -- END TABLES -- */
6497 $ipaddingL = $this->blk[$this->blklvl]['padding_left'];
6498 $ipaddingR = $this->blk[$this->blklvl]['padding_right'];
6501 $this->cMarginL = $this->blk[$this->blklvl]['border_left']['w'];
6502 $this->cMarginR = $this->blk[$this->blklvl]['border_right']['w'];
6507 /* -- CSS-FLOAT -- */
6508 if (count($this->floatDivs)) {
6509 list($l_exists, $r_exists, $l_max, $r_max, $l_width, $r_width) = $this->GetFloatDivInfo($this->blklvl);
6517 /* -- END CSS-FLOAT -- */
6519 $usey = $this->y + 0.002;
6521 $usey += $this->blk[$this->blklvl]['margin_top'] + $this->blk[$this->blklvl]['padding_top'] + $this->blk[$this->blklvl]['border_top']['w'];
6523 /* -- CSS-IMAGE-FLOAT -- */
6525 if (isset($this->floatmargins['R']) && $usey <= $this->floatmargins['R']['y1'] && $usey >= $this->floatmargins['R']['y0'] && !$this->floatmargins['R']['skipline']) {
6526 $fpaddingR += $this->floatmargins['R']['w'];
6528 if (isset($this->floatmargins['L']) && $usey <= $this->floatmargins['L']['y1'] && $usey >= $this->floatmargins['L']['y0'] && !$this->floatmargins['L']['skipline']) {
6529 $fpaddingL += $this->floatmargins['L']['w'];
6531 /* -- END CSS-IMAGE-FLOAT -- */
6537 $this->_setInlineBlockHeights($lineBox, $stackHeight, $content, $font, $is_table);
6544 $this->y += $stackHeight;
6545 $this->objectbuffer = [];
6551 // Re-calculate contentWidth
6555 $this->restoreFont($font[$k], false);
6556 if (!isset($this->objectbuffer[$k]) || (isset($this->objectbuffer[$k]) && !$this->objectbuffer[$k])) {
6558 if (!$this->usingCoreFont) {
6559 /* -- OTL -- */
6561 if (isset($this->CurrentFont['useOTL']) && $this->CurrentFont['useOTL']) {
6562 $this->otl->removeChar($chunk, $cOTLdata[$k], "\xc2\xad");
6563 $this->otl->replaceSpace($chunk, $cOTLdata[$k]);
6565 } /* -- END OTL -- */ else { // *OTL*
6569 } elseif ($this->FontFamily != 'csymbol' && $this->FontFamily != 'czapfdingbats') {
6573 $contentWidth += $this->GetStringWidth($chunk, true, (isset($cOTLdata[$k]) ? $cOTLdata[$k] : false), $this->textvar) * Mpdf::SCALE;
6574 } elseif (isset($this->objectbuffer[$k]) && $this->objectbuffer[$k]) {
6576 if ($this->objectbuffer[$k]['type'] == 'image' && isset($this->objectbuffer[$k]['listmarker']) && $this->objectbuffer[$k]['listmarker'] && $this->objectbuffer[$k]['listmarkerposition'] == 'outside') {
6579 $contentWidth += $this->objectbuffer[$k]['OUTER-WIDTH'] * Mpdf::SCALE;
6584 if (isset($font[count($font) - 1])) {
6585 $lastfontreqstyle = (isset($font[count($font) - 1]['ReqFontStyle']) ? $font[count($font) - 1]['ReqFontStyle'] : '');
6586 $lastfontstyle = (isset($font[count($font) - 1]['style']) ? $font[count($font) - 1]['style'] : '');
6592 $lastitalic = $this->FontSize * 0.15 * Mpdf::SCALE;
6598 $check_h = max($this->divheight, $stackHeight);
6607 if ($this->blklvl > 0 && !$is_table) {
6609 if ($this->blk[$this->blklvl]['page_break_after_avoid']) {
6612 $check_h += ($this->blk[$this->blklvl]['padding_bottom'] + $this->blk[$this->blklvl]['border_bottom']['w']);
6615 $check_h += ($this->blk[$this->blklvl]['padding_top'] + $this->blk[$this->blklvl]['margin_top'] + $this->blk[$this->blklvl]['border_top']['w']);
6619 // Force PAGE break if column height cannot take check-height
6620 if ($this->ColActive && $check_h > ($this->PageBreakTrigger - $this->y0)) {
6621 $this->SetCol($this->NbCol - 1);
6624 // Avoid just border/background-color moved on to next page
6626 $buff = $this->margBuffer;
6633 if (!$is_table && ($this->y + $check_h) > ($this->PageBreakTrigger + $buff) and ! $this->InFooter and $this->AcceptPageBreak()) {
6634 $bak_x = $this->x; // Current X position
6636 $ws = $this->ws; // Word Spacing
6637 $charspacing = $this->charspacing; // Character Spacing
6638 $this->ResetSpacing();
6640 $this->AddPage($this->CurOrientation);
6642 $this->x = $bak_x;
6644 $currentx += $this->MarginCorrection;
6645 $this->x += $this->MarginCorrection;
6648 $this->SetSpacing($charspacing, $ws);
6652 /* -- COLUMNS -- */
6655 if ($this->CurrCol != $oldcolumn) {
6656 $currentx += $this->ChangeColumn * ($this->ColWidth + $this->ColGap);
6657 $this->x += $this->ChangeColumn * ($this->ColWidth + $this->ColGap);
6658 $oldcolumn = $this->CurrCol;
6662 if ($this->ColActive && !$is_table) {
6663 $this->breakpoints[$this->CurrCol][] = $this->y;
6665 /* -- END COLUMNS -- */
6668 if ($newblock && ($blockstate == 1 || $blockstate == 3) && ($this->blk[$this->blklvl]['margin_top']) && $lineCount == 0 && !$is_table) {
6669 $this->DivLn($this->blk[$this->blklvl]['margin_top'], $this->blklvl - 1, true, $this->blk[$this->blklvl]['margin_collapse']);
6670 if ($this->ColActive) {
6671 $this->breakpoints[$this->CurrCol][] = $this->y;
6676 $this->blk[$this->blklvl]['y0'] = $this->y;
6677 $this->blk[$this->blklvl]['startpage'] = $this->page;
6678 if ($this->blk[$this->blklvl]['float']) {
6679 $this->blk[$this->blklvl]['float_start_y'] = $this->y;
6681 if ($this->ColActive) {
6682 $this->breakpoints[$this->CurrCol][] = $this->y;
6688 if (($newblock) && ($blockstate == 1 || $blockstate == 3) && isset($this->blk[$this->blklvl]['text_indent']) && ($lineCount == 0) && (!$is_table) && ($align != 'C')) {
6689 $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
6695 if (($newblock) && ($blockstate == 1 || $blockstate == 3) && (($this->blk[$this->blklvl]['padding_top']) || ($this->blk[$this->blklvl]['border_top'])) && ($lineCount == 0) && (!$is_table)) {
6697 $this->DivLn($this->blk[$this->blklvl]['padding_top'] + $this->blk[$this->blklvl]['border_top']['w'], -3, true, false, 1);
6698 if ($this->ColActive) {
6699 $this->breakpoints[$this->CurrCol][] = $this->y;
6701 $this->x = $currentx;
6708 /* -- CSS-FLOAT -- */
6709 if (count($this->floatDivs)) {
6710 list($l_exists, $r_exists, $l_max, $r_max, $l_width, $r_width) = $this->GetFloatDivInfo($this->blklvl);
6718 /* -- END CSS-FLOAT -- */
6720 $usey = $this->y + 0.002;
6722 $usey += $this->blk[$this->blklvl]['margin_top'] + $this->blk[$this->blklvl]['padding_top'] + $this->blk[$this->blklvl]['border_top']['w'];
6724 /* -- CSS-IMAGE-FLOAT -- */
6726 if (isset($this->floatmargins['R']) && $usey <= $this->floatmargins['R']['y1'] && $usey >= $this->floatmargins['R']['y0'] && !$this->floatmargins['R']['skipline']) {
6727 $fpaddingR += $this->floatmargins['R']['w'];
6729 if (isset($this->floatmargins['L']) && $usey <= $this->floatmargins['L']['y1'] && $usey >= $this->floatmargins['L']['y0'] && !$this->floatmargins['L']['skipline']) {
6730 $fpaddingL += $this->floatmargins['L']['w'];
6732 /* -- END CSS-IMAGE-FLOAT -- */
6738 // JUSTIFICATION J - NOT!
6747 if (!isset($this->objectbuffer[$k]) || (isset($this->objectbuffer[$k]) && !$this->objectbuffer[$k])) {
6748 $nb_carac += mb_strlen($chunk, $this->mb_enc);
6749 $nb_spaces += mb_substr_count($chunk, ' ', $this->mb_enc);
6752 $this->restoreFont($font[$k], false);
6753 if (isset($this->CurrentFont['useOTL']) && $this->CurrentFont['useOTL']) {
6756 $nb_carac -= $nb_marks;
6758 if (preg_match("/([" . $this->pregCURSchars . "])/u", $chunk)) {
6764 if ($this->objectbuffer[$k]['type'] == 'dottab') {
6765 $dottab = $this->objectbuffer[$k]['outdent'];
6771 $chunkorder = range(0, count($content) - 1); // mPDF 6
6772 /* -- OTL -- */
6774 if ($blockdir == 'rtl' || $this->biDirectional) {
6775 $this->otl->bidiReorder($chunkorder, $content, $cOTLdata, $blockdir);
6776 // From this point on, $content and $cOTLdata may contain more elements (and re-ordered) compared to
6777 // $this->objectbuffer and $font ($chunkorder contains the mapping)
6779 /* -- END OTL -- */
6786 $this->restoreFont($font[$k], false);
6788 if ($aord == count($chunkorder) - 1 && isset($cOTLdata[$aord]['group'])) { // Last chunk on line
6789 $nGPOS = strlen($cOTLdata[$aord]['group']) - 1; // Last character
6792 $w = $cOTLdata[$aord]['GPOSinfo'][$nGPOS]['XAdvanceL'] * 1000 / $this->CurrentFont['unitsPerEm'];
6794 $w = $cOTLdata[$aord]['GPOSinfo'][$nGPOS]['XAdvanceR'] * 1000 / $this->CurrentFont['unitsPerEm'];
6796 $w *= ($this->FontSize / 1000);
6797 $contentWidth -= $w * Mpdf::SCALE;
6804 $w = -$cOTLdata[$aord]['GPOSinfo'][$nGPOS]['XPlacement'] * 1000 / $this->CurrentFont['unitsPerEm'];
6805 $w *= ($this->FontSize / 1000);
6806 $contentWidth -= $w * Mpdf::SCALE;
6815 // If "orphans" in fact is just a final space - ignore this
6816 $lastchar = mb_substr($content[(count($chunkorder) - 1)], mb_strlen($content[(count($chunkorder) - 1)], $this->mb_enc) - 1, 1, $this->mb_enc);
6817 if (preg_match("/[" . $this->CJKoverflow . "]/u", $lastchar)) {
6822 if ((((($contentWidth + $lastitalic) > $maxWidth) && ($content[(count($chunkorder) - 1)] != ' ') ) ||
6823 (!$endofblock && $align == 'J' && ($next == 'image' || $next == 'select' || $next == 'input' || $next == 'textarea' || ($next == 'br' && $this->justifyB4br)))) && !($CJKoverflow && $this->allowCJKoverflow)) {
6825 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);
6826 } /* -- CJK-FONTS -- */ elseif ($this->checkCJK && $align == 'J' && $CJKoverflow && $this->allowCJKoverflow && $this->CJKforceend) {
6827 // force-end overhang
6828 $hanger = mb_substr($content[(count($chunkorder) - 1)], mb_strlen($content[(count($chunkorder) - 1)], $this->mb_enc) - 1, 1, $this->mb_enc);
6829 if (preg_match("/[" . $this->CJKoverflow . "]/u", $hanger)) {
6830 $content[(count($chunkorder) - 1)] = mb_substr($content[(count($chunkorder) - 1)], 0, mb_strlen($content[(count($chunkorder) - 1)], $this->mb_enc) - 1, $this->mb_enc);
6831 $this->restoreFont($font[$chunkorder[count($chunkorder) - 1]], false);
6832 $contentWidth -= $this->GetStringWidth($hanger) * Mpdf::SCALE;
6833 $nb_carac -= 1;
6834 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);
6836 } /* -- END CJK-FONTS -- */
6838 // Check if will fit at word/char spacing of previous line - if so continue it
6839 // but only allow a maximum of $this->jSmaxWordLast and $this->jSmaxCharLast
6840 elseif ($contentWidth < ($maxWidth - $lastitalic - $WidthCorrection - (($this->cMarginL + $this->cMarginR) * Mpdf::SCALE) - ($paddingL + $paddingR + (($fpaddingL + $fpaddingR) * Mpdf::SCALE))) && !$this->fixedlSpacing) {
6841 if ($this->ws > $this->jSmaxWordLast) {
6842 $jws = $this->jSmaxWordLast;
6844 if ($this->charspacing > $this->jSmaxCharLast) {
6845 $jcharspacing = $this->jSmaxCharLast;
6847 $check = $maxWidth - $lastitalic - $WidthCorrection - $contentWidth - (($this->cMarginL + $this->cMarginR) * Mpdf::SCALE) - ($paddingL + $paddingR + (($fpaddingL + $fpaddingR) * Mpdf::SCALE) ) - ( $jcharspacing * $nb_carac) - ( $jws * $nb_spaces);
6854 $empty = $maxWidth - $lastitalic - $WidthCorrection - $contentWidth - (($this->cMarginL + $this->cMarginR) * Mpdf::SCALE) - ($paddingL + $paddingR + (($fpaddingL + $fpaddingR) * Mpdf::SCALE) );
6857 $empty -= ($jcharspacing * ($nb_carac - 1)); // mPDF 6 nb_carac MINUS 1
6858 $empty -= ($jws * $nb_spaces);
6859 $empty -= ($jkashida);
6864 $this->maxPosR = max($this->maxPosR, ($this->w - $this->rMargin - $this->blk[$this->blklvl]['outer_right_margin'] - $empty));
6865 $this->maxPosL = min($this->maxPosL, ($this->lMargin + $this->blk[$this->blklvl]['outer_left_margin'] + $empty));
6870 $margins = ($this->cMarginL + $this->cMarginR) + ($ipaddingL + $ipaddingR + $fpaddingR + $fpaddingR );
6873 $this->DivLn($stackHeight, $this->blklvl, false);
6874 } // false -> don't advance y
6876 $this->x = $currentx + $this->cMarginL + $ipaddingL + $fpaddingL;
6878 $this->x -= $dottab;
6880 $this->x += $empty;
6882 $this->x += $empty;
6884 $this->x += ($empty / 2);
6889 if (($newblock) && ($blockstate == 1 || $blockstate == 3) && isset($this->blk[$this->blklvl]['text_indent']) && ($lineCount == 0) && (!$is_table) && ($align != 'C')) {
6890 $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
6892 $this->x += $ti;
6898 if (isset($this->objectbuffer[$k]) && $this->objectbuffer[$k]) {
6899 $xadj = $this->x - $this->objectbuffer[$k]['OUTER-X'];
6900 $this->objectbuffer[$k]['OUTER-X'] += $xadj;
6901 $this->objectbuffer[$k]['BORDER-X'] += $xadj;
6902 $this->objectbuffer[$k]['INNER-X'] += $xadj;
6904 if ($this->objectbuffer[$k]['type'] == 'listmarker') {
6905 $this->objectbuffer[$k]['lineBox'] = $lineBox[-1]; // Block element details for glyph-origin
6907 $yadj = $this->y - $this->objectbuffer[$k]['OUTER-Y'];
6908 if ($this->objectbuffer[$k]['type'] == 'dottab') { // mPDF 6 DOTTAB
6909 $this->objectbuffer[$k]['lineBox'] = $lineBox[$k]; // element details for glyph-origin
6911 if ($this->objectbuffer[$k]['type'] != 'dottab') { // mPDF 6 DOTTAB
6914 $this->objectbuffer[$k]['OUTER-Y'] += $yadj;
6915 $this->objectbuffer[$k]['BORDER-Y'] += $yadj;
6916 $this->objectbuffer[$k]['INNER-Y'] += $yadj;
6919 $this->restoreFont($font[$k]); // mPDF 5.7
6922 $dp = $this->decimal_align[substr($align, 0, 2)];
6924 $s0 = $this->GetStringWidth($s[0], false);
6925 $this->x += ($this->decimal_offset - $s0);
6928 $this->SetSpacing(($this->fixedlSpacing * Mpdf::SCALE) + $jcharspacing, ($this->fixedlSpacing + $this->minwSpacing) * Mpdf::SCALE + $jws);
6929 $this->fixedlSpacing = false;
6930 $this->minwSpacing = 0;
6932 $save_vis = $this->visibility;
6933 if (isset($this->textparam['visibility']) && $this->textparam['visibility'] && $this->textparam['visibility'] != $this->visibility) {
6934 $this->SetVisibility($this->textparam['visibility']);
6938 if (isset($this->spanbgcolor) && $this->spanbgcolor) {
6939 $cor = $this->spanbgcolorarray;
6940 $this->SetFColor($cor);
6945 if (!empty($this->spanborddet)) {
6946 if (strpos($contentB[$k], 'L') !== false && isset($this->spanborddet['L'])) {
6947 $this->x += $this->spanborddet['L']['w'];
6950 $this->spanborddet['L']['s'] = $this->spanborddet['L']['w'] = 0;
6953 $this->spanborddet['R']['s'] = $this->spanborddet['R']['w'] = 0;
6958 $stringWidth = $this->GetStringWidth($chunk, true, (isset($cOTLdata[$aord]) ? $cOTLdata[$aord] : false), $this->textvar);
6959 $nch = mb_strlen($chunk, $this->mb_enc);
6961 if (isset($this->CurrentFont['useOTL']) && $this->CurrentFont['useOTL']) {
6963 $nch -= substr_count($cOTLdata[$aord]['group'], 'M');
6966 $stringWidth += ( $this->charspacing * $nch / Mpdf::SCALE );
6968 $stringWidth += ( $this->ws * mb_substr_count($chunk, ' ', $this->mb_enc) / Mpdf::SCALE );
6970 if (isset($this->objectbuffer[$k])) {
6971 if ($this->objectbuffer[$k]['type'] == 'dottab') {
6972 $this->objectbuffer[$k]['OUTER-WIDTH'] +=$empty;
6973 $this->objectbuffer[$k]['OUTER-WIDTH'] +=$this->objectbuffer[$k]['outdent'];
6976 if ($this->objectbuffer[$k]['type'] == 'image' && isset($this->objectbuffer[$k]['listmarker']) && $this->objectbuffer[$k]['listmarker'] && $this->objectbuffer[$k]['listmarkerposition'] == 'outside') {
6979 $stringWidth = $this->objectbuffer[$k]['OUTER-WIDTH'];
6986 if ($aord == $arraysize - 1) { // mPDF 5.7
6988 if ($this->checkCJK && $CJKoverflow && $align == 'J' && $this->allowCJKoverflow && $hanger && $this->CJKforceend) {
6989 // force-end overhang
6990 $this->Cell($stringWidth, $stackHeight, $chunk, '', 0, '', $fill, $this->HREF, $currentx, 0, 0, 'M', $fill, true, (isset($cOTLdata[$aord]) ? $cOTLdata[$aord] : false), $this->textvar, (isset($lineBox[$k]) ? $lineBox[$k] : false)); // mPDF 5.7.1
6991 $this->Cell($this->GetStringWidth($hanger), $stackHeight, $hanger, '', 1, '', $fill, $this->HREF, $currentx, 0, 0, 'M', $fill, true, (isset($cOTLdata[$aord]) ? $cOTLdata[$aord] : false), $this->textvar, (isset($lineBox[$k]) ? $lineBox[$k] : false)); // mPDF 5.7.1
6993 $this->Cell($stringWidth, $stackHeight, $chunk, '', 1, '', $fill, $this->HREF, $currentx, 0, 0, 'M', $fill, true, (isset($cOTLdata[$aord]) ? $cOTLdata[$aord] : false), $this->textvar, (isset($lineBox[$k]) ? $lineBox[$k] : false)); // mPDF 5.7.1
6996 $this->Cell($stringWidth, $stackHeight, $chunk, '', 0, '', $fill, $this->HREF, 0, 0, 0, 'M', $fill, true, (isset($cOTLdata[$aord]) ? $cOTLdata[$aord] : false), $this->textvar, (isset($lineBox[$k]) ? $lineBox[$k] : false)); // first or middle part // mPDF 5.7.1
7000 if (!empty($this->spanborddet)) {
7001 if (strpos($contentB[$k], 'R') !== false && $aord != $arraysize - 1) {
7002 $this->x += $this->spanborddet['R']['w'];
7005 // *********** SPAN BACKGROUND COLOR OFF - RESET BLOCK BGCOLOR ***************** //
7010 $this->SetFColor($bcor);
7013 if (isset($this->textparam['visibility']) && $this->textparam['visibility'] && $this->visibility != $save_vis) {
7014 $this->SetVisibility($save_vis);
7018 $this->printobjectbuffer($is_table, $blockdir);
7019 $this->objectbuffer = [];
7020 $this->ResetSpacing();
7023 /* -- CSS-IMAGE-FLOAT -- */
7025 if ($this->floatmargins) {
7026 $this->_advanceFloatMargins();
7032 if (isset($this->floatmargins['R']['y1'])) {
7033 $fry1 = $this->floatmargins['R']['y1'];
7037 if (isset($this->floatmargins['L']['y1'])) {
7038 $fly1 = $this->floatmargins['L']['y1'];
7042 if ($this->y < $fry1 || $this->y < $fly1) {
7043 $drop = max($fry1, $fly1) - $this->y;
7044 $this->DivLn($drop);
7045 $this->x = $currentx;
7048 /* -- END CSS-IMAGE-FLOAT -- */
7052 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)) {
7053 // If CSS height set, extend bottom - if on same page as block started, and CSS HEIGHT > actual height,
7056 if (isset($this->blk[$this->blklvl]['css_set_height']) && $this->blk[$this->blklvl]['css_set_height'] && $this->blk[$this->blklvl]['startpage'] == $this->page) {
7058 $h1 = ($this->y - $this->blk[$this->blklvl]['y0']) + $this->blk[$this->blklvl]['padding_bottom'] + $this->blk[$this->blklvl]['border_bottom']['w'];
7059 if ($h1 < ($this->blk[$this->blklvl]['css_set_height'] + $this->blk[$this->blklvl]['padding_bottom'] + $this->blk[$this->blklvl]['padding_top'])) {
7060 $extra = ($this->blk[$this->blklvl]['css_set_height'] + $this->blk[$this->blklvl]['padding_bottom'] + $this->blk[$this->blklvl]['padding_top']) - $h1;
7062 if ($this->y + $this->blk[$this->blklvl]['padding_bottom'] + $this->blk[$this->blklvl]['border_bottom']['w'] + $extra > $this->PageBreakTrigger) {
7063 $extra = $this->PageBreakTrigger - ($this->y + $this->blk[$this->blklvl]['padding_bottom'] + $this->blk[$this->blklvl]['border_bottom']['w']);
7068 $this->DivLn($this->blk[$this->blklvl]['padding_bottom'] + $this->blk[$this->blklvl]['border_bottom']['w'] + $extra, -3, true, false, 2);
7069 $this->x = $currentx;
7071 if ($this->ColActive) {
7072 $this->breakpoints[$this->CurrCol][] = $this->y;
7078 $this->blk[$this->blklvl]['y1'] = $this->y;
7082 if (($endofblock) && ($blockstate > 1) && ($this->blk[$this->blklvl]['margin_bottom']) && (!$is_table)) {
7083 if ($this->y + $this->blk[$this->blklvl]['margin_bottom'] < $this->PageBreakTrigger and ! $this->InFooter) {
7084 $this->DivLn($this->blk[$this->blklvl]['margin_bottom'], $this->blklvl - 1, true, $this->blk[$this->blklvl]['margin_collapse']);
7085 if ($this->ColActive) {
7086 $this->breakpoints[$this->CurrCol][] = $this->y;
7092 $stackHeight = $this->divheight;
7098 $blockdir = $this->directionality;
7101 if ($is_table && $this->shrin_k > 1) {
7102 $k = $this->shrin_k;
7107 $save_y = $this->y;
7108 $save_x = $this->x;
7110 $save_currentfontfamily = $this->FontFamily;
7111 $save_currentfontsize = $this->FontSizePt;
7112 $save_currentfontstyle = $this->FontStyle;
7120 foreach ($this->objectbuffer as $ib => $objattr) {
7123 $x = $objattr['OUTER-X'];
7124 $y = $objattr['OUTER-Y'];
7125 $this->y = $y - $this->FontSize / 2;
7126 $this->x = $x;
7128 $this->Bookmark($objattr['CONTENT'], $objattr['bklevel'], $y - $this->FontSize);
7131 $this->IndexEntry($objattr['CONTENT']);
7134 $this->TOC_Entry($objattr['CONTENT'], $objattr['toclevel'], (isset($objattr['toc_id']) ? $objattr['toc_id'] : ''));
7136 } /* -- ANNOTATIONS -- */ elseif ($objattr['type'] == 'annot') {
7137 if ($objattr['POS-X']) {
7138 $x = $objattr['POS-X'];
7139 } elseif ($this->annotMargin <> 0) {
7140 $x = -$objattr['OUTER-X'];
7142 $x = $objattr['OUTER-X'];
7144 if ($objattr['POS-Y']) {
7145 $y = $objattr['POS-Y'];
7147 $y = $objattr['OUTER-Y'] - $this->FontSize / 2;
7150 // linking $y-1 in the Columnbuffer with entry in $this->columnAnnots
7152 $this->y = $y - 1;
7153 $this->x = $x - 1;
7154 $this->Line($x - 1, $y - 1, $x - 1, $y - 1);
7155 $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'] : ''));
7156 } /* -- END ANNOTATIONS -- */ else {
7157 $y = $objattr['OUTER-Y'];
7158 $x = $objattr['OUTER-X'];
7159 $w = $objattr['OUTER-WIDTH'];
7160 $h = $objattr['OUTER-HEIGHT'];
7164 $this->y = $y;
7165 $this->x = $x;
7167 $this->SetFont($objattr['fontfamily'], '', $objattr['fontsize']);
7173 $this->SetDColor($objattr['color']);
7176 $empty = $objattr['OUTER-WIDTH'] - $objattr['INNER-WIDTH'];
7181 $empty = $objattr['OUTER-WIDTH'] - $objattr['INNER-WIDTH'];
7185 $oldlinewidth = $this->LineWidth;
7186 $this->SetLineWidth($objattr['linewidth'] / $k);
7187 $this->y += ($objattr['linewidth'] / 2) + $objattr['margin_top'] / $k;
7188 $this->Line($x, $this->y, $x + $objattr['INNER-WIDTH'], $this->y);
7189 $this->SetLineWidth($oldlinewidth);
7190 $this->SetDColor($this->colorConverter->convert(0, $this->PDFAXwarnings));
7196 $this->writer->write("\n" . '% BTR'); // Begin Transform
7198 if (isset($objattr['z-index']) && $objattr['z-index'] > 0 && $this->current_layer == 0) {
7199 $this->BeginLayer($objattr['z-index']);
7202 $this->SetVisibility($objattr['visibility']);
7205 $this->SetAlpha($objattr['opacity']);
7208 $obiw = $objattr['INNER-WIDTH'];
7209 $obih = $objattr['INNER-HEIGHT'];
7211 $sx = $objattr['orig_w'] ? ($objattr['INNER-WIDTH'] * Mpdf::SCALE / $objattr['orig_w']) : INF;
7212 $sy = $objattr['orig_h'] ? ($objattr['INNER-HEIGHT'] * Mpdf::SCALE / $objattr['orig_h']) : INF;
7221 $obiw = $objattr['INNER-HEIGHT'];
7222 $obih = $objattr['INNER-WIDTH'];
7223 $tr = $this->transformTranslate(0, -$objattr['INNER-WIDTH'], true);
7224 $tr .= ' ' . $this->transformRotate(90, $objattr['INNER-X'], ($objattr['INNER-Y'] + $objattr['INNER-WIDTH']), true);
7227 } elseif ($rotate == -90 || $rotate == 270) {
7229 $obiw = $objattr['INNER-HEIGHT'];
7230 $obih = $objattr['INNER-WIDTH'];
7231 $tr = $this->transformTranslate($objattr['INNER-WIDTH'], ($objattr['INNER-HEIGHT'] - $objattr['INNER-WIDTH']), true);
7232 $tr .= ' ' . $this->transformRotate(-90, $objattr['INNER-X'], ($objattr['INNER-Y'] + $objattr['INNER-WIDTH']), true);
7237 $tr = $this->transformTranslate($objattr['INNER-WIDTH'], -$objattr['INNER-HEIGHT'], true);
7238 $tr .= ' ' . $this->transformRotate(180, $objattr['INNER-X'], ($objattr['INNER-Y'] + $objattr['INNER-HEIGHT']), true);
7262 $translate_x = $this->sizeConverter->convert($vv[0], $maxsize_x, false, false);
7264 $translate_y = $this->sizeConverter->convert($vv[1], $maxsize_y, false, false);
7268 $tr2 .= $this->transformTranslate($translate_x, $translate_y, true) . ' ';
7270 $translate_x = $this->sizeConverter->convert($vv[0], $maxsize_x, false, false);
7271 $tr2 .= $this->transformTranslate($translate_x, 0, true) . ' ';
7273 $translate_y = $this->sizeConverter->convert($vv[1], $maxsize_y, false, false);
7274 $tr2 .= $this->transformTranslate(0, $translate_y, true) . ' ';
7282 $tr2 .= $this->transformScale($scale_x, $scale_y, $cx, $cy, true) . ' ';
7285 $tr2 .= $this->transformScale($scale_x, 0, $cx, $cy, true) . ' ';
7288 $tr2 .= $this->transformScale(0, $scale_y, $cx, $cy, true) . ' ';
7290 $angle_x = $this->ConvertAngle($vv[0], false);
7292 $angle_y = $this->ConvertAngle($vv[1], false);
7296 $tr2 .= $this->transformSkew($angle_x, $angle_y, $cx, $cy, true) . ' ';
7298 $angle = $this->ConvertAngle($vv[0], false);
7299 $tr2 .= $this->transformSkew($angle, 0, $cx, $cy, true) . ' ';
7301 $angle = $this->ConvertAngle($vv[0], false);
7302 $tr2 .= $this->transformSkew(0, $angle, $cx, $cy, true) . ' ';
7304 $angle = $this->ConvertAngle($vv[0]);
7305 $tr2 .= $this->transformRotate($angle, $cx, $cy, true) . ' ';
7313 $mw = $objattr['OUTER-WIDTH'];
7314 // NB If change marker-offset, also need to alter in function _getListMarkerWidth
7315 $adjx = $this->sizeConverter->convert($this->list_marker_offset, $this->FontSize);
7317 $objattr['INNER-X'] += $adjx;
7319 $objattr['INNER-X'] -= $adjx;
7320 $objattr['INNER-X'] -= $mw;
7326 $this->writer->write('q ' . $tr2 . ' ');
7330 $this->SetFColor($bgcol);
7331 $this->Rect($x, $y, $w, $h, 'F');
7332 $this->SetFColor($this->colorConverter->convert(255, $this->PDFAXwarnings));
7335 $this->writer->write('Q');
7338 /* -- BACKGROUNDS -- */
7339 if (isset($objattr['GRADIENT-MASK'])) {
7340 $g = $this->gradient->parseMozGradient($objattr['GRADIENT-MASK']);
7342 $dummy = $this->gradient->Gradient($objattr['INNER-X'], $objattr['INNER-Y'], $obiw, $obih, $g['type'], $g['stops'], $g['colorspace'], $g['coords'], $g['extend'], true, true);
7343 $gradmask = '/TGS' . count($this->gradients) . ' gs ';
7346 /* -- END BACKGROUNDS -- */
7347 /* -- IMAGES-WMF -- */
7349 $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->h - $objattr['INNER-Y']) * Mpdf::SCALE) + $sy * $objattr['wmf_y'], $objattr['ID']); // mPDF 5.7.3 TRANSFORMS
7350 } else { /* -- END IMAGES-WMF -- */
7352 $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->h - $objattr['INNER-Y']) * Mpdf::SCALE) + $sy * $objattr['wmf_y'], $objattr['ID']); // mPDF 5.7.3 TRANSFORMS
7354 $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->h - ($objattr['INNER-Y'] + $obih )) * Mpdf::SCALE, $objattr['ID']); // mPDF 5.7.3 TRANSFORMS
7357 $this->writer->write($outstring);
7360 $this->Link($objattr['INNER-X'], $objattr['INNER-Y'], $objattr['INNER-WIDTH'], $objattr['INNER-HEIGHT'], $objattr['link']);
7363 $this->SetAlpha(1);
7369 $this->writer->write('q ' . $tr2 . ' ');
7372 $this->PaintImgBorder($objattr, $is_table);
7375 $this->writer->write('Q');
7379 $this->SetVisibility('visible');
7381 if (isset($objattr['z-index']) && $objattr['z-index'] > 0 && $this->current_layer == 0) {
7382 $this->EndLayer();
7386 $this->writer->write("\n" . '% ETR'); // End Transform
7392 $bgcol = $this->colorConverter->convert(255, $this->PDFAXwarnings);
7398 $col = $this->colorConverter->convert(0, $this->PDFAXwarnings);
7404 $this->SetFColor($bgcol);
7405 $this->Rect($objattr['BORDER-X'], $objattr['BORDER-Y'], $objattr['BORDER-WIDTH'], $objattr['BORDER-HEIGHT'], 'F');
7406 $this->SetFColor($this->colorConverter->convert(255, $this->PDFAXwarnings));
7408 if (isset($objattr['BORDER-WIDTH'])) {
7409 $this->PaintImgBorder($objattr, $is_table);
7415 $this->WriteBarcode(
7418 $objattr['INNER-X'],
7419 $objattr['INNER-Y'],
7446 $qrcode->disableBorder();
7455 explode(" ", $this->SetColor($objattr['bgcolor'], 'CodeOnly'))
7464 explode(" ", $this->SetColor($objattr['color'], 'CodeOnly'))
7469 $out->output(
7472 $objattr['INNER-X'],
7473 $objattr['INNER-Y'],
7482 $this->WriteBarcode2(
7484 $objattr['INNER-X'],
7485 $objattr['INNER-Y'],
7505 $col = $this->colorConverter->convert(0, $this->PDFAXwarnings);
7509 $this->SetTColor($col);
7510 $this->SetFColor($bgcol);
7512 $this->Rect($objattr['BORDER-X'], $objattr['BORDER-Y'], $objattr['BORDER-WIDTH'], $objattr['BORDER-HEIGHT'], 'F');
7514 $this->SetFColor($this->colorConverter->convert(255, $this->PDFAXwarnings));
7515 if (isset($objattr['BORDER-WIDTH'])) {
7516 $this->PaintImgBorder($objattr, $is_table);
7518 if (empty($this->directWrite)) {
7519 $this->directWrite = new DirectWrite($this, $this->otl, $this->sizeConverter, $this->colorConverter);
7521 if (isset($objattr['top-text'])) {
7522 $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'] : ''));
7524 if (isset($objattr['bottom-text'])) {
7525 $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'] : ''));
7529 $this->ResetSpacing();
7534 $this->SetFont($objattr['fontfamily'], $objattr['fontstyle'], $objattr['fontsizept']);
7536 $col = $this->colorConverter->convert(0, $this->PDFAXwarnings);
7543 $size = $objattr['size'];
7546 $adjx = $size / 2;
7550 $this->x += $adjx;
7553 $adjx += $size / 2;
7555 $this->x += $adjx;
7557 $this->x -= $adjx;
7562 if (isset($this->CurrentFont['desc']['XHeight']) && $this->CurrentFont['desc']['XHeight']) {
7563 $xh = $this->CurrentFont['desc']['XHeight'];
7567 $yadj -= ($this->FontSize * $xh / 1000) * 0.625; // Vertical height of bullet (centre) from baseline= XHeight * 0.625
7568 $this->y += $yadj;
7570 $this->_printListBullet($this->x, $this->y, $size, $type, $col);
7572 $this->SetTColor($col);
7573 $w = $this->GetStringWidth($texto);
7574 // NB If change marker-offset, also need to alter in function _getListMarkerWidth
7575 $adjx = $this->sizeConverter->convert($this->list_marker_offset, $this->FontSize);
7578 $this->x += $adjx;
7580 // Use these lines to set as marker-offset, right-aligned - default
7582 $this->x -= $adjx;
7583 $this->x -= $w;
7585 $this->Cell($w, $this->FontSize, $texto, 0, 0, $align, 0, '', 0, 0, 0, 'T', 0, false, false, 0, $objattr['lineBox']);
7586 $this->SetTColor($this->colorConverter->convert(0, $this->PDFAXwarnings));
7590 // DOT-TAB
7593 $this->SetFont($objattr['fontfamily'], '', $objattr['fontsize']);
7595 $sp = $this->GetStringWidth(' ');
7596 $nb = floor(($w - 2 * $sp) / $this->GetStringWidth('.'));
7602 $col = $this->colorConverter->convert(0, $this->PDFAXwarnings);
7606 $this->SetTColor($col);
7607 $save_dh = $this->divheight;
7608 $save_sbd = $this->spanborddet;
7609 $save_textvar = $this->textvar; // mPDF 5.7.1
7610 $this->spanborddet = '';
7611 $this->divheight = 0;
7612 $this->textvar = 0x00; // mPDF 5.7.1
7614 $this->Cell($w, $h, $dots, 0, 0, 'C', 0, '', 0, 0, 0, 'T', 0, false, false, 0, $objattr['lineBox']); // mPDF 6 DOTTAB
7615 $this->spanborddet = $save_sbd;
7616 $this->textvar = $save_textvar; // mPDF 5.7.1
7617 $this->divheight = $save_dh;
7618 $this->SetTColor($this->colorConverter->convert(0, $this->PDFAXwarnings));
7621 /* -- FORMS -- */
7624 $this->form->print_ob_text($objattr, $w, $h, $texto, $rtlalign, $k, $blockdir);
7629 $this->form->print_ob_textarea($objattr, $w, $h, $texto, $rtlalign, $k, $blockdir);
7634 $this->form->print_ob_select($objattr, $w, $h, $texto, $rtlalign, $k, $blockdir);
7640 $this->form->print_ob_imageinput($objattr, $w, $h, $texto, $rtlalign, $k, $blockdir, $is_table);
7645 $this->form->print_ob_button($objattr, $w, $h, $texto, $rtlalign, $k, $blockdir);
7650 $this->form->print_ob_checkbox($objattr, $w, $h, $texto, $rtlalign, $k, $blockdir, $x, $y);
7654 $this->form->print_ob_radio($objattr, $w, $h, $texto, $rtlalign, $k, $blockdir, $x, $y);
7656 /* -- END FORMS -- */
7659 $this->SetFont($save_currentfontfamily, $save_currentfontstyle, $save_currentfontsize);
7661 $this->y = $save_y;
7662 $this->x = $save_x;
7667 function _printListBullet($x, $y, $size, $type, $color)
7669 // x and y are the centre of the bullet; size is the width and/or height in mm
7670 $fcol = $this->SetTColor($color, true);
7672 $this->writer->write(sprintf('q %s %s', $lcol, $fcol));
7673 $this->writer->write('0 j 0 J [] 0 d');
7675 $size *= 0.85; // Smaller to appear the same size as circle/disc
7676 $this->writer->write(sprintf('%.3F %.3F %.3F %.3F re f', ($x - $size / 2) * Mpdf::SCALE, ($this->h - $y + $size / 2) * Mpdf::SCALE, ($size) * Mpdf::SCALE, (-$size) * Mpdf::SCALE));
7678 $this->Circle($x, $y, $size / 2, 'F'); // Fill
7680 $lw = $size / 12; // Line width
7681 $this->writer->write(sprintf('%.3F w ', $lw * Mpdf::SCALE));
7682 $this->Circle($x, $y, $size / 2 - $lw / 2, 'S'); // Stroke
7684 $this->writer->write('Q');
7692 $charctr--;
7694 $contentctr--;
7698 if ($this->usingCoreFont) {
7699 $charctr = strlen($content[$contentctr]) - 1;
7701 $charctr = mb_strlen($content[$contentctr], $this->mb_enc) - 1;
7704 if ($this->usingCoreFont) {
7707 $lastchar = mb_substr($content[$contentctr], $charctr, 1, $this->mb_enc);
7716 $charctr--;
7718 $contentctr--;
7722 if ($this->usingCoreFont) {
7723 $charctr = strlen($content[$contentctr]) - 1;
7725 $charctr = mb_strlen($content[$contentctr], $this->mb_enc) - 1;
7728 if ($this->usingCoreFont) {
7731 $lastchar = mb_substr($content[$contentctr], $charctr, 1, $this->mb_enc);
7739 $currentx = $this->x;
7740 $is_table = $this->flowingBlockAttr['is_table'];
7741 $table_draft = $this->flowingBlockAttr['table_draft'];
7743 $contentWidth = & $this->flowingBlockAttr['contentWidth'];
7745 $maxWidth = & $this->flowingBlockAttr['width'];
7746 $lineCount = & $this->flowingBlockAttr['lineCount'];
7748 $stackHeight = & $this->flowingBlockAttr['height'];
7749 $align = & $this->flowingBlockAttr['align'];
7750 $content = & $this->flowingBlockAttr['content'];
7751 $contentB = & $this->flowingBlockAttr['contentB'];
7752 $font = & $this->flowingBlockAttr['font'];
7753 $valign = & $this->flowingBlockAttr['valign'];
7754 $blockstate = $this->flowingBlockAttr['blockstate'];
7755 $cOTLdata = & $this->flowingBlockAttr['cOTLdata']; // mPDF 5.7.1
7757 $newblock = $this->flowingBlockAttr['newblock'];
7758 $blockdir = $this->flowingBlockAttr['blockdir'];
7761 if ($this->blk[$this->blklvl]['bgcolor'] && !$is_table) {
7764 $this->SetFColor($this->colorConverter->convert(255, $this->PDFAXwarnings));
7767 $font[] = $this->saveFont();
7771 $currContent = & $content[count($content) - 1];
7778 $oldcolumn = $this->CurrCol;
7779 if ($this->ColActive && !$is_table) {
7780 $this->breakpoints[$this->CurrCol][] = $this->y;
7783 /* -- TABLES -- */
7795 /* -- END TABLES -- */
7796 $ipaddingL = $this->blk[$this->blklvl]['padding_left'];
7797 $ipaddingR = $this->blk[$this->blklvl]['padding_right'];
7800 $this->cMarginL = $this->blk[$this->blklvl]['border_left']['w'];
7801 $cpaddingadjustL = -$this->cMarginL;
7802 $this->cMarginR = $this->blk[$this->blklvl]['border_right']['w'];
7803 $cpaddingadjustR = -$this->cMarginR;
7807 /* -- CSS-FLOAT -- */
7808 if (count($this->floatDivs)) {
7809 list($l_exists, $r_exists, $l_max, $r_max, $l_width, $r_width) = $this->GetFloatDivInfo($this->blklvl);
7817 /* -- END CSS-FLOAT -- */
7819 $usey = $this->y + 0.002;
7821 $usey += $this->blk[$this->blklvl]['margin_top'] + $this->blk[$this->blklvl]['padding_top'] + $this->blk[$this->blklvl]['border_top']['w'];
7823 /* -- CSS-IMAGE-FLOAT -- */
7825 if (isset($this->floatmargins['R']) && $usey <= $this->floatmargins['R']['y1'] && $usey >= $this->floatmargins['R']['y0'] && !$this->floatmargins['R']['skipline']) {
7826 $fpaddingR += $this->floatmargins['R']['w'];
7828 if (isset($this->floatmargins['L']) && $usey <= $this->floatmargins['L']['y1'] && $usey >= $this->floatmargins['L']['y0'] && !$this->floatmargins['L']['skipline']) {
7829 $fpaddingL += $this->floatmargins['L']['w'];
7831 /* -- END CSS-IMAGE-FLOAT -- */
7833 // OBJECTS - IMAGES & FORM Elements (NB has already skipped line/page if required - in printbuffer)
7835 $objattr = $this->_getObjAttr($s);
7838 $maximumW = ($maxWidth / Mpdf::SCALE) - ($this->cellPaddingL + $this->cMarginL + $this->cellPaddingR + $this->cMarginR); // *TABLES*
7842 $h_corr = $this->blk[$this->blklvl]['padding_top'] + $this->blk[$this->blklvl]['border_top']['w'];
7844 $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 );
7846 $objattr = $this->inlineObject($objattr['type'], $this->lMargin + $fpaddingL + ($contentWidth / Mpdf::SCALE), ($this->y + $h_corr), $objattr, $this->lMargin, ($contentWidth / Mpdf::SCALE), $maximumW, $stackHeight, true, $is_table);
7849 $stackHeight = max($stackHeight, $objattr['OUTER-HEIGHT']);
7850 $this->objectbuffer[count($content) - 1] = $objattr;
7851 // if (isset($objattr['vertical-align'])) { $valign = $objattr['vertical-align']; }
7857 $contentWidth += ($objattr['OUTER-WIDTH'] * Mpdf::SCALE);
7863 if (!empty($this->spanborddet)) {
7864 if (isset($this->spanborddet['L'])) {
7865 $lbw = $this->spanborddet['L']['w'];
7867 if (isset($this->spanborddet['R'])) {
7868 $rbw = $this->spanborddet['R']['w'];
7872 if ($this->usingCoreFont) {
7875 $clen = mb_strlen($s, $this->mb_enc);
7882 if ($this->usingCoreFont) {
7885 $cw = ($this->GetCharWidthCore($c) * Mpdf::SCALE);
7886 if (($this->textvar & TextVars::FC_KERNING) && $i > 0) { // mPDF 5.7.1
7887 if (isset($this->CurrentFont['kerninfo'][$s[($i - 1)]][$c])) {
7888 $cw += ($this->CurrentFont['kerninfo'][$s[($i - 1)]][$c] * $this->FontSizePt / 1000 );
7892 $c = mb_substr($s, $i, 1, $this->mb_enc);
7893 $cw = ($this->GetCharWidthNonCore($c, false) * Mpdf::SCALE);
7896 if (isset($this->CurrentFont['useOTL']) && ($this->CurrentFont['useOTL'] & 0xFF)) {
7901 $cw += $sOTLdata['GPOSinfo'][$i]['XAdvanceL'] * (1000 / $this->CurrentFont['unitsPerEm']) * ($this->FontSize / 1000) * Mpdf::SCALE;
7904 if (($this->textvar & TextVars::FC_KERNING) && $i > 0) { // mPDF 5.7.1
7905 $lastc = mb_substr($s, ($i - 1), 1, $this->mb_enc);
7906 $ulastc = $this->UTF8StringToArray($lastc, false);
7907 $uc = $this->UTF8StringToArray($c, false);
7908 if (isset($this->CurrentFont['kerninfo'][$ulastc[0]][$uc[0]])) {
7909 $cw += ($this->CurrentFont['kerninfo'][$ulastc[0]][$uc[0]] * $this->FontSizePt / 1000 );
7916 $contentB[(count($contentB) - 1)] .= 'L';
7918 if ($i == ($clen - 1)) {
7920 $contentB[(count($contentB) - 1)] .= 'R';
7930 if (($newblock) && ($blockstate == 1 || $blockstate == 3) && isset($this->blk[$this->blklvl]['text_indent']) && ($lineCount == 0) && (!$is_table) && ($align != 'C')) {
7931 $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
7935 foreach ($this->objectbuffer as $k => $objattr) { // mPDF 6 DOTTAB
7937 $WidthCorrection -= ($objattr['outdent'] * Mpdf::SCALE);
7946 /* -- CSS-FLOAT -- */
7947 if (count($this->floatDivs)) {
7948 list($l_exists, $r_exists, $l_max, $r_max, $l_width, $r_width) = $this->GetFloatDivInfo($this->blklvl);
7956 /* -- END CSS-FLOAT -- */
7958 $usey = $this->y + 0.002;
7960 $usey += $this->blk[$this->blklvl]['margin_top'] + $this->blk[$this->blklvl]['padding_top'] + $this->blk[$this->blklvl]['border_top']['w'];
7963 /* -- CSS-IMAGE-FLOAT -- */
7965 if (isset($this->floatmargins['R']) && $usey <= $this->floatmargins['R']['y1'] && $usey >= $this->floatmargins['R']['y0'] && !$this->floatmargins['R']['skipline']) {
7966 $fpaddingR += $this->floatmargins['R']['w'];
7968 if (isset($this->floatmargins['L']) && $usey <= $this->floatmargins['L']['y1'] && $usey >= $this->floatmargins['L']['y0'] && !$this->floatmargins['L']['skipline']) {
7969 $fpaddingL += $this->floatmargins['L']['w'];
7971 /* -- END CSS-IMAGE-FLOAT -- */
7975 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
7991 // New line-breaking algorithm
7996 $contentctr = count($content) - 1;
7997 if ($this->usingCoreFont) {
8000 $charctr = mb_strlen($currContent, $this->mb_enc);
8003 $prevchar = $this->_getPrevChar($contentctr, $charctr, $content);
8005 /* -- CJK-FONTS -- */
8013 if (!$this->usingCoreFont && !$breakfound && $this->checkCJK) {
8017 if ($i < ($clen - 1)) {
8018 if ($this->usingCoreFont) {
8021 $followingchar = mb_substr($s, $i + 1, 1, $this->mb_enc);
8026 if (preg_match("/[" . $this->pregCJKchars . "]/u", $prevchar) && preg_match("/[" . $this->CJKoverflow . "]/u", $checkchar) && $this->allowCJKorphans) {
8032 } elseif (preg_match("/[" . $this->pregCJKchars . "]/u", $checkchar) && $this->allowCJKorphans &&
8033 (preg_match("/[" . $this->CJKleading . "]/u", $followingchar) || preg_match("/[" . $this->CJKfollowing . "]/u", $checkchar)) &&
8034 !preg_match("/[" . $this->CJKleading . "]/u", $checkchar) && !preg_match("/[" . $this->CJKfollowing . "]/u", $followingchar) &&
8035 !(preg_match("/[0-9\x{ff10}-\x{ff19}]/u", $followingchar) && preg_match("/[0-9\x{ff10}-\x{ff19}]/u", $checkchar))) {
8046 /* -- END CJK-FONTS -- */
8047 /* -- HYPHENATION -- */
8051 if (isset($this->textparam['hyphens']) && $this->textparam['hyphens'] == 1) {
8054 for ($ac = $charctr - 1; $ac >= 0; $ac--) {
8055 if ($this->usingCoreFont) {
8058 $addc = mb_substr($currContent, $ac, 1, $this->mb_enc);
8066 for ($ac = $i; $ac < ($clen - 1); $ac++) {
8067 if ($this->usingCoreFont) {
8070 $addc = mb_substr($s, $ac, 1, $this->mb_enc);
8077 $ptr = $this->hyphenator->hyphenateWord($currWord, $charctr - $start);
8078 if ($ptr > -1) {
8082 /* -- END HYPHENATION -- */
8084 // Search backwards to find first line-break opportunity
8088 $prevchar = $this->_moveToPrevChar($contentctr, $charctr, $content);
8097 elseif ($prevchar == "\xe2\x80\x8b") { // U+200B Zero-width Word Break
8100 // 5) Break at Hard HYPHEN '-' or U+2010
8102 elseif (isset($this->textparam['hyphens']) && $this->textparam['hyphens'] != 2 && ($prevchar == '-' || $prevchar == "\xe2\x80\x90")) {
8106 for ($ac = $charctr - 1; $ac >= 0; $ac--) {
8107 if ($this->usingCoreFont) {
8110 $addc = mb_substr($currContent, $ac, 1, $this->mb_enc);
8118 if ((!preg_match('/(http:|ftp:|https:|www\.)/', $checkw) && $checkchar != '>' && !preg_match('/[0-9]/', $checkchar)) || $prevchar == "\xe2\x80\x90") {
8124 elseif (isset($this->textparam['hyphens']) && $this->textparam['hyphens'] != 2 && !$this->usingCoreFont && $prevchar == "\xc2\xad") {
8126 $content[$contentctr] = mb_substr($content[$contentctr], 0, $charctr, $this->mb_enc) . '-' . mb_substr($content[$contentctr], $charctr + 1, mb_strlen($content[$contentctr]), $this->mb_enc);
8131 } elseif (isset($this->textparam['hyphens']) && $this->textparam['hyphens'] != 2 && $this->FontFamily != 'csymbol' && $this->FontFamily != 'czapfdingbats' && $prevchar == chr(173)) {
8133 $content[$contentctr] = substr($content[$contentctr], 0, $charctr) . '-' . substr($content[$contentctr], $charctr + 1);
8134 } /* -- CJK-FONTS -- */
8139 elseif (!$this->usingCoreFont && $this->checkCJK && preg_match("/[" . $this->pregCJKchars . "]/u", $checkchar) &&
8140 !preg_match("/[" . $this->CJKfollowing . "]/u", $checkchar) && !preg_match("/[" . $this->CJKleading . "]/u", $prevchar) &&
8141 !(preg_match("/[0-9\x{ff10}-\x{ff19}]/u", $prevchar) && preg_match("/[0-9\x{ff10}-\x{ff19}]/u", $checkchar))) {
8144 /* -- END CJK-FONTS -- */
8146 // 8) Break at OBJECT (Break before all objects here - selected objects are moved forward to next line below e.g. dottab)
8148 if (isset($this->objectbuffer[$contentctr])) {
8156 // If a line-break opportunity found:
8164 for ($ix = count($content) - 1; $ix > $cutcontentctr; $ix--) {
8166 /* -- OTL -- */
8171 /* -- END OTL -- */
8174 $savedPreFont[] = array_pop($font);
8178 if ($this->usingCoreFont) {
8181 $savedPreContent[] = mb_substr($content[$cutcontentctr], $cutcharctr, mb_strlen($content[$cutcontentctr]), $this->mb_enc);
8184 $savedPreFont[] = $font[$cutcontentctr];
8185 /* -- OTL -- */
8187 $savedPreOTLdata[] = $this->otl->splitOTLdata($cOTLdata[$cutcontentctr], $cutcharctr, $cutcharctr);
8189 /* -- END OTL -- */
8196 array_pop($font);
8200 $currContent = & $content[count($content) - 1];
8201 if ($this->usingCoreFont) {
8204 $currContent = mb_substr($currContent, 0, $charctr, $this->mb_enc);
8208 $savedPreOTLdata[] = $this->otl->splitOTLdata($cOTLdata[(count($cOTLdata) - 1)], mb_strlen($currContent, $this->mb_enc));
8211 if (strpos($contentB[(count($contentB) - 1)], 'R') !== false) { // ???
8212 $contentB[count($content) - 1] = preg_replace('/R/', '', $contentB[count($content) - 1]); // ???
8216 $currContent .= '-';
8217 if (!empty($cOTLdata[(count($cOTLdata) - 1)])) {
8218 $cOTLdata[(count($cOTLdata) - 1)]['char_data'][] = ['bidi_class' => 9, 'uni' => 45];
8219 $cOTLdata[(count($cOTLdata) - 1)]['group'] .= 'C';
8228 // If no line-break opportunity found - split at current position
8229 // or - Next character ($c) is suitable to add as overhanging or squeezed punctuation, or Oikomi, as set above by:
8234 $savedFont = $this->saveFont();
8236 $savedOTLdata = $this->otl->splitOTLdata($cOTLdata[(count($cOTLdata) - 1)], mb_strlen($currContent, $this->mb_enc));
8240 if ($content[count($content) - 1] == '' && !isset($this->objectbuffer[count($content) - 1])) {
8243 array_pop($font);
8245 $currContent = & $content[count($content) - 1];
8248 // Right Trim current content - including CJK space, and for OTLdata
8249 // incl. CJK - strip CJK space at end of line &#x3000; = \xe3\x80\x80 = CJK space
8251 if ($this->checkCJK) {
8253 } // *CJK-FONTS*
8254 /* -- OTL -- */
8255 if (isset($this->CurrentFont['useOTL']) && $this->CurrentFont['useOTL']) {
8256 $this->otl->trimOTLdata($cOTLdata[count($cOTLdata) - 1], false, true); // NB also does U+3000
8258 /* -- END OTL -- */
8262 if (isset($this->objectbuffer[(count($content) - 1)]) && (!isset($type) || $type != 'discard')) {
8263 $objtype = $this->objectbuffer[(count($content) - 1)]['type'];
8265 $savedObj = array_pop($this->objectbuffer);
8277 $this->_setInlineBlockHeights($lineBox, $stackHeight, $content, $font, $is_table);
8284 if (isset($this->objectbuffer[$k]) && $this->objectbuffer[$k]) {
8286 if ($this->objectbuffer[$k]['type'] == 'image' && isset($this->objectbuffer[$k]['listmarker']) && $this->objectbuffer[$k]['listmarker']) {
8287 if ($this->objectbuffer[$k]['listmarkerposition'] != 'outside') {
8288 $contentWidth += $this->objectbuffer[$k]['OUTER-WIDTH'] * Mpdf::SCALE;
8291 $contentWidth += $this->objectbuffer[$k]['OUTER-WIDTH'] * Mpdf::SCALE;
8293 } elseif (!isset($this->objectbuffer[$k]) || (isset($this->objectbuffer[$k]) && !$this->objectbuffer[$k])) {
8294 $this->restoreFont($font[$k], false);
8295 if ($this->checkCJK && $k == count($content) - 1 && $CJKoverflow && $align == 'J' && $this->allowCJKoverflow && $this->CJKforceend) {
8296 // force-end overhang
8297 $hanger = mb_substr($chunk, mb_strlen($chunk, $this->mb_enc) - 1, 1, $this->mb_enc);
8299 $content[$k] = $chunk = mb_substr($chunk, 0, mb_strlen($chunk, $this->mb_enc) - 1, $this->mb_enc);
8303 if (!$this->usingCoreFont) {
8304 /* -- OTL -- */
8305 if ((isset($this->CurrentFont['useOTL']) && $this->CurrentFont['useOTL']) || !empty($sOTLdata)) {
8306 $this->otl->removeChar($chunk, $cOTLdata[$k], "\xc2\xad");
8307 $this->otl->replaceSpace($chunk, $cOTLdata[$k]); // NBSP -> space
8308 if (preg_match("/([" . $this->pregCURSchars . "])/u", $chunk)) {
8312 } /* -- END OTL -- */ else { // *OTL*
8316 } elseif ($this->FontFamily != 'csymbol' && $this->FontFamily != 'czapfdingbats') {
8321 $contentWidth += $this->GetStringWidth($chunk, true, (isset($cOTLdata[$k]) ? $cOTLdata[$k] : false), $this->textvar) * Mpdf::SCALE; // mPDF 5.7.1
8322 if (!empty($this->spanborddet)) {
8323 if (isset($this->spanborddet['L']['w']) && strpos($contentB[$k], 'L') !== false) {
8324 $contentWidth += $this->spanborddet['L']['w'] * Mpdf::SCALE;
8326 if (isset($this->spanborddet['R']['w']) && strpos($contentB[$k], 'R') !== false) {
8327 $contentWidth += $this->spanborddet['R']['w'] * Mpdf::SCALE;
8333 $lastfontreqstyle = (isset($font[count($font) - 1]['ReqFontStyle']) ? $font[count($font) - 1]['ReqFontStyle'] : '');
8334 $lastfontstyle = (isset($font[count($font) - 1]['style']) ? $font[count($font) - 1]['style'] : '');
8336 $lastitalic = $this->FontSize * 0.15 * Mpdf::SCALE;
8347 $chunkorder = range(0, count($content) - 1); // mPDF 5.7
8348 /* -- OTL -- */
8350 if ($blockdir == 'rtl' || $this->biDirectional) {
8351 $this->otl->bidiReorder($chunkorder, $content, $cOTLdata, $blockdir);
8352 // From this point on, $content and $cOTLdata may contain more elements (and re-ordered) compared to
8353 // $this->objectbuffer and $font ($chunkorder contains the mapping)
8356 /* -- END OTL -- */
8360 $this->restoreFont($font[$k], false);
8362 if ($aord == count($chunkorder) - 1 && isset($cOTLdata[$aord]['group'])) { // Last chunk on line
8363 $nGPOS = strlen($cOTLdata[$aord]['group']) - 1; // Last character
8366 $w = $cOTLdata[$aord]['GPOSinfo'][$nGPOS]['XAdvanceL'] * 1000 / $this->CurrentFont['unitsPerEm'];
8368 $w = $cOTLdata[$aord]['GPOSinfo'][$nGPOS]['XAdvanceR'] * 1000 / $this->CurrentFont['unitsPerEm'];
8370 $w *= ($this->FontSize / 1000);
8371 $contentWidth -= $w * Mpdf::SCALE;
8378 $w = -$cOTLdata[$aord]['GPOSinfo'][$nGPOS]['XPlacement'] * 1000 / $this->CurrentFont['unitsPerEm'];
8379 $w *= ($this->FontSize / 1000);
8380 $contentWidth -= $w * Mpdf::SCALE;
8394 // if it's justified, we need to find the char/word spacing (or if hanger $this->CJKforceend)
8395 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
8401 if (!isset($this->objectbuffer[$k]) || (isset($this->objectbuffer[$k]) && !$this->objectbuffer[$k])) {
8402 $nb_carac += mb_strlen($chunk, $this->mb_enc);
8403 $nb_spaces += mb_substr_count($chunk, ' ', $this->mb_enc);
8405 if (isset($this->CurrentFont['useOTL']) && ($this->CurrentFont['useOTL'] & 0xFF)) {
8407 $nb_carac -= substr_count($cOTLdata[$aord]['group'], 'M');
8414 // GetJSpacing adds kashida spacing to GPOSinfo if appropriate for Font
8415 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);
8419 $empty = $maxWidth - $lastitalic - $WidthCorrection - $contentWidth - (($this->cMarginL + $this->cMarginR) * Mpdf::SCALE) - ($paddingL + $paddingR + (($fpaddingL + $fpaddingR) * Mpdf::SCALE) );
8421 $empty -= ($jcharspacing * ($nb_carac - 1)); // mPDF 6 nb_carac MINUS 1
8422 $empty -= ($jws * $nb_spaces);
8423 $empty -= ($jkashida);
8428 $check_h = max($this->divheight, $stackHeight);
8429 if (($newblock) && ($blockstate == 1 || $blockstate == 3) && ($this->blklvl > 0) && ($lineCount == 1) && (!$is_table)) {
8430 $check_h += ($this->blk[$this->blklvl]['padding_top'] + $this->blk[$this->blklvl]['margin_top'] + $this->blk[$this->blklvl]['border_top']['w']);
8433 if ($this->ColActive && $check_h > ($this->PageBreakTrigger - $this->y0)) {
8434 $this->SetCol($this->NbCol - 1);
8438 // 'If' below used in order to fix "first-line of other page with justify on" bug
8439 if (!$is_table && ($this->y + $check_h) > $this->PageBreakTrigger and ! $this->InFooter and $this->AcceptPageBreak()) {
8440 $bak_x = $this->x; // Current X position
8442 $ws = $this->ws; // Word Spacing
8443 $charspacing = $this->charspacing; // Character Spacing
8444 $this->ResetSpacing();
8446 $this->AddPage($this->CurOrientation);
8448 $this->x = $bak_x;
8450 $currentx += $this->MarginCorrection;
8451 $this->x += $this->MarginCorrection;
8454 $this->SetSpacing($charspacing, $ws);
8457 if ($this->kwt && !$is_table) { // mPDF 5.7+
8458 $this->printkwtbuffer();
8459 $this->kwt = false;
8463 /* -- COLUMNS -- */
8466 if ($this->CurrCol != $oldcolumn) {
8467 $currentx += $this->ChangeColumn * ($this->ColWidth + $this->ColGap);
8468 $this->x += $this->ChangeColumn * ($this->ColWidth + $this->ColGap);
8469 $oldcolumn = $this->CurrCol;
8472 if ($this->ColActive && !$is_table) {
8473 $this->breakpoints[$this->CurrCol][] = $this->y;
8475 /* -- END COLUMNS -- */
8478 if (($newblock) && ($blockstate == 1 || $blockstate == 3) && ($this->blk[$this->blklvl]['margin_top']) && ($lineCount == 1) && (!$is_table)) {
8479 $this->DivLn($this->blk[$this->blklvl]['margin_top'], $this->blklvl - 1, true, $this->blk[$this->blklvl]['margin_collapse']);
8480 if ($this->ColActive) {
8481 $this->breakpoints[$this->CurrCol][] = $this->y;
8488 $this->blk[$this->blklvl]['y0'] = $this->y;
8489 $this->blk[$this->blklvl]['startpage'] = $this->page;
8490 if ($this->blk[$this->blklvl]['float']) {
8491 $this->blk[$this->blklvl]['float_start_y'] = $this->y;
8496 if (($newblock) && ($blockstate == 1 || $blockstate == 3) && (($this->blk[$this->blklvl]['padding_top']) || ($this->blk[$this->blklvl]['border_top'])) && ($lineCount == 1) && (!$is_table)) {
8498 $this->DivLn($this->blk[$this->blklvl]['padding_top'] + $this->blk[$this->blklvl]['border_top']['w'], -3, true, false, 1);
8499 if ($this->ColActive) {
8500 $this->breakpoints[$this->CurrCol][] = $this->y;
8506 $margins = ($this->cMarginL + $this->cMarginR) + ($ipaddingL + $ipaddingR + $fpaddingR + $fpaddingR );
8510 $this->DivLn($stackHeight, $this->blklvl, false);
8511 } // false -> don't advance y
8513 $this->x = $currentx + $this->cMarginL + $ipaddingL + $fpaddingL;
8515 $this->x += $empty;
8517 $this->x += ($empty / 2);
8521 if (isset($this->blk[$this->blklvl]['text_indent']) && ($newblock) && ($blockstate == 1 || $blockstate == 3) && ($lineCount == 1) && (!$is_table) && ($blockdir != 'rtl') && ($align != 'C')) {
8522 $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
8523 $this->x += $ti;
8531 if (isset($this->objectbuffer[$k]) && $this->objectbuffer[$k]) {
8532 $xadj = $this->x - $this->objectbuffer[$k]['OUTER-X'];
8533 $this->objectbuffer[$k]['OUTER-X'] += $xadj;
8534 $this->objectbuffer[$k]['BORDER-X'] += $xadj;
8535 $this->objectbuffer[$k]['INNER-X'] += $xadj;
8537 if ($this->objectbuffer[$k]['type'] == 'listmarker') {
8538 $this->objectbuffer[$k]['lineBox'] = $lineBox[-1]; // Block element details for glyph-origin
8540 $yadj = $this->y - $this->objectbuffer[$k]['OUTER-Y'];
8541 if ($this->objectbuffer[$k]['type'] == 'dottab') { // mPDF 6 DOTTAB
8542 $this->objectbuffer[$k]['lineBox'] = $lineBox[$k]; // element details for glyph-origin
8544 if ($this->objectbuffer[$k]['type'] != 'dottab') { // mPDF 6 DOTTAB
8547 $this->objectbuffer[$k]['OUTER-Y'] += $yadj;
8548 $this->objectbuffer[$k]['BORDER-Y'] += $yadj;
8549 $this->objectbuffer[$k]['INNER-Y'] += $yadj;
8552 $this->restoreFont($font[$k]); // mPDF 5.7
8554 $this->SetSpacing(($this->fixedlSpacing * Mpdf::SCALE) + $jcharspacing, ($this->fixedlSpacing + $this->minwSpacing) * Mpdf::SCALE + $jws);
8556 $this->fixedlSpacing = false;
8557 $this->minwSpacing = 0;
8559 $save_vis = $this->visibility;
8560 if (isset($this->textparam['visibility']) && $this->textparam['visibility'] && $this->textparam['visibility'] != $this->visibility) {
8561 $this->SetVisibility($this->textparam['visibility']);
8564 if ($this->spanbgcolor) {
8565 $cor = $this->spanbgcolorarray;
8566 $this->SetFColor($cor);
8571 if (!empty($this->spanborddet)) {
8573 $this->x += (isset($this->spanborddet['L']['w']) ? $this->spanborddet['L']['w'] : 0);
8576 $this->spanborddet['L']['s'] = $this->spanborddet['L']['w'] = 0;
8579 $this->spanborddet['R']['s'] = $this->spanborddet['R']['w'] = 0;
8585 $stringWidth = $this->GetStringWidth($chunk, true, (isset($cOTLdata[$aord]) ? $cOTLdata[$aord] : false), $this->textvar, true);
8587 $nch = mb_strlen($chunk, $this->mb_enc);
8589 if (isset($this->CurrentFont['useOTL']) && ($this->CurrentFont['useOTL'] & 0xFF)) {
8591 $nch -= substr_count($cOTLdata[$aord]['group'], 'M');
8594 $stringWidth += ( $this->charspacing * $nch / Mpdf::SCALE );
8596 $stringWidth += ( $this->ws * mb_substr_count($chunk, ' ', $this->mb_enc) / Mpdf::SCALE );
8598 if (isset($this->objectbuffer[$k])) {
8600 if ($this->objectbuffer[$k]['type'] == 'image' && isset($this->objectbuffer[$k]['listmarker']) && $this->objectbuffer[$k]['listmarker'] && $this->objectbuffer[$k]['listmarkerposition'] == 'outside') {
8603 $stringWidth = $this->objectbuffer[$k]['OUTER-WIDTH'];
8611 if ($aord == $arraysize - 1) {
8612 $stringWidth -= ( $this->charspacing / Mpdf::SCALE );
8613 if ($this->checkCJK && $CJKoverflow && $align == 'J' && $this->allowCJKoverflow && $hanger && $this->CJKforceend) {
8614 // force-end overhang
8615 $this->Cell($stringWidth, $stackHeight, $chunk, '', 0, '', $fill, $this->HREF, $currentx, 0, 0, 'M', $fill, true, (isset($cOTLdata[$aord]) ? $cOTLdata[$aord] : false), $this->textvar, (isset($lineBox[$k]) ? $lineBox[$k] : false));
8616 $this->Cell($this->GetStringWidth($hanger), $stackHeight, $hanger, '', 1, '', $fill, $this->HREF, $currentx, 0, 0, 'M', $fill, true, (isset($cOTLdata[$aord]) ? $cOTLdata[$aord] : false), $this->textvar, (isset($lineBox[$k]) ? $lineBox[$k] : false));
8618 $this->Cell($stringWidth, $stackHeight, $chunk, '', 1, '', $fill, $this->HREF, $currentx, 0, 0, 'M', $fill, true, (isset($cOTLdata[$aord]) ? $cOTLdata[$aord] : false), $this->textvar, (isset($lineBox[$k]) ? $lineBox[$k] : false)); // mono-style line or last part (skips line)
8621 $this->Cell($stringWidth, $stackHeight, $chunk, '', 0, '', $fill, $this->HREF, 0, 0, 0, 'M', $fill, true, (isset($cOTLdata[$aord]) ? $cOTLdata[$aord] : false), $this->textvar, (isset($lineBox[$k]) ? $lineBox[$k] : false)); // first or middle part
8624 if (!empty($this->spanborddet)) {
8625 if (strpos($contentB[$k], 'R') !== false && $aord != $arraysize - 1) {
8626 $this->x += $this->spanborddet['R']['w'];
8629 // *********** SPAN BACKGROUND COLOR OFF - RESET BLOCK BGCOLOR ***************** //
8634 $this->SetFColor($bcor);
8637 if (isset($this->textparam['visibility']) && $this->textparam['visibility'] && $this->visibility != $save_vis) {
8638 $this->SetVisibility($save_vis);
8642 $this->y += $stackHeight;
8646 $this->maxPosR = max($this->maxPosR, ($this->w - $this->rMargin - $this->blk[$this->blklvl]['outer_right_margin']));
8647 $this->maxPosL = min($this->maxPosL, ($this->lMargin + $this->blk[$this->blklvl]['outer_left_margin']));
8653 $this->printobjectbuffer($is_table, $blockdir);
8655 $this->objectbuffer = [];
8658 /* -- CSS-IMAGE-FLOAT -- */
8660 if ($this->floatmargins) {
8661 $this->_advanceFloatMargins();
8663 /* -- END CSS-IMAGE-FLOAT -- */
8666 $stackHeight = $this->divheight;
8669 $font = [];
8675 $this->objectbuffer[] = $savedObj;
8676 $font[] = $savedFont;
8680 $contentWidth += $savedObj['OUTER-WIDTH'] * Mpdf::SCALE;
8683 for ($ix = count($savedPreContent) - 1; $ix >= 0; $ix--) {
8684 $font[] = $savedPreFont[$ix];
8690 $this->restoreFont($savedPreFont[$ix]);
8692 if (!empty($this->spanborddet)) {
8693 $lbw = (isset($this->spanborddet['L']['w']) ? $this->spanborddet['L']['w'] : 0);
8694 $rbw = (isset($this->spanborddet['R']['w']) ? $this->spanborddet['R']['w'] : 0);
8697 $contentWidth += $this->GetStringWidth($savedPreContent[$ix], true, (isset($savedPreOTLdata[$ix]) ? $savedPreOTLdata[$ix] : false), $this->textvar) * Mpdf::SCALE; // mPDF 5.7.1
8710 $content[(count($content) - 1)] .= $c;
8712 $font[] = $savedFont;
8718 $currContent = & $content[(count($content) - 1)];
8719 $this->restoreFont($font[(count($font) - 1)]); // mPDF 6.0
8721 /* -- CJK-FONTS -- */
8722 // CJK - strip CJK space at start of line
8724 if ($this->checkCJK && $currContent == "\xe3\x80\x80") {
8726 if (isset($this->CurrentFont['useOTL']) && $this->CurrentFont['useOTL']) {
8727 $this->otl->trimOTLdata($cOTLdata[count($cOTLdata) - 1], true, false); // left trim U+3000
8730 /* -- END CJK-FONTS -- */
8733 if (!empty($this->spanborddet)) {
8734 $lbw = (isset($this->spanborddet['L']['w']) ? $this->spanborddet['L']['w'] : 0);
8735 $rbw = (isset($this->spanborddet['R']['w']) ? $this->spanborddet['R']['w'] : 0);
8738 $contentWidth += $this->GetStringWidth($currContent, false, (isset($cOTLdata[(count($cOTLdata) - 1)]) ? $cOTLdata[(count($cOTLdata) - 1)] : false), $this->textvar) * Mpdf::SCALE; // mPDF 5.7.1
8755 // ----------------------END OF FLOWING BLOCK------------------------------------//
8758 /* -- CSS-IMAGE-FLOAT -- */
8762 // Update floatmargins - L
8763 if (isset($this->floatmargins['L']) && $this->floatmargins['L']['skipline'] && $this->floatmargins['L']['y0'] != $this->y) {
8764 $yadj = $this->y - $this->floatmargins['L']['y0'];
8765 $this->floatmargins['L']['y0'] = $this->y;
8766 $this->floatmargins['L']['y1'] += $yadj;
8769 if ($this->floatbuffer[$this->floatmargins['L']['id']]['border_left']['w']) {
8770 $this->floatbuffer[$this->floatmargins['L']['id']]['BORDER-Y'] += $yadj;
8772 $this->floatbuffer[$this->floatmargins['L']['id']]['INNER-Y'] += $yadj;
8773 $this->floatbuffer[$this->floatmargins['L']['id']]['OUTER-Y'] += $yadj;
8776 $this->floatbuffer[$this->floatmargins['L']['id']]['skipline'] = false;
8777 $this->floatmargins['L']['skipline'] = false;
8778 $this->floatmargins['L']['id'] = '';
8780 // Update floatmargins - R
8781 if (isset($this->floatmargins['R']) && $this->floatmargins['R']['skipline'] && $this->floatmargins['R']['y0'] != $this->y) {
8782 $yadj = $this->y - $this->floatmargins['R']['y0'];
8783 $this->floatmargins['R']['y0'] = $this->y;
8784 $this->floatmargins['R']['y1'] += $yadj;
8787 if ($this->floatbuffer[$this->floatmargins['R']['id']]['border_left']['w']) {
8788 $this->floatbuffer[$this->floatmargins['R']['id']]['BORDER-Y'] += $yadj;
8790 $this->floatbuffer[$this->floatmargins['R']['id']]['INNER-Y'] += $yadj;
8791 $this->floatbuffer[$this->floatmargins['R']['id']]['OUTER-Y'] += $yadj;
8794 $this->floatbuffer[$this->floatmargins['R']['id']]['skipline'] = false;
8795 $this->floatmargins['R']['skipline'] = false;
8796 $this->floatmargins['R']['id'] = '';
8800 /* -- END CSS-IMAGE-FLOAT -- */
8804 /* -- END HTML-CSS -- */
8812 if ($this->page > 0 && ((isset($this->pageoutput[$this->page]['TextRendering']) && $this->pageoutput[$this->page]['TextRendering'] != $tr) || !isset($this->pageoutput[$this->page]['TextRendering']))) {
8813 $this->writer->write($tr);
8815 $this->pageoutput[$this->page]['TextRendering'] = $tr;
8820 if (isset($params['outline-s']) && $params['outline-s']) {
8821 $this->SetLineWidth($params['outline-WIDTH']);
8822 $this->SetDColor($params['outline-COLOR']);
8824 if ($this->page > 0 && ((isset($this->pageoutput[$this->page]['TextRendering']) && $this->pageoutput[$this->page]['TextRendering'] != $tr) || !isset($this->pageoutput[$this->page]['TextRendering']))) {
8825 $this->writer->write($tr);
8827 $this->pageoutput[$this->page]['TextRendering'] = $tr;
8829 $this->SetLineWidth(0.2);
8830 $this->SetDColor($this->colorConverter->convert(0, $this->PDFAXwarnings));
8831 $this->_SetTextRendering(0);
8833 if ($this->page > 0 && ((isset($this->pageoutput[$this->page]['TextRendering']) && $this->pageoutput[$this->page]['TextRendering'] != $tr) || !isset($this->pageoutput[$this->page]['TextRendering']))) {
8834 $this->writer->write($tr);
8836 $this->pageoutput[$this->page]['TextRendering'] = $tr;
8843 $this->GetFullPath($file);
8845 $info = $this->imageProcessor->getImage($file, true, $allowvector, $orig_srcpath);
8847 $info = $this->imageProcessor->getImage($this->noImageFile);
8849 $file = $this->noImageFile;
8850 $w = ($info['w'] * (25.4 / $this->img_dpi)); // 14 x 16px
8851 $h = ($info['h'] * (25.4 / $this->img_dpi)); // 14 x 16px
8859 /* -- IMAGES-WMF -- */
8866 } else { /* -- END IMAGES-WMF -- */
8874 $w = ($info['w'] / Mpdf::SCALE) * (72 / $this->img_dpi);
8875 $h = ($info['h'] / Mpdf::SCALE) * (72 / $this->img_dpi);
8886 /* -- WATERMARK -- */
8888 $maxw = $this->w;
8889 $maxh = $this->h;
8890 // Size = D PF or array
8891 if (is_array($this->watermark_size)) {
8892 $w = $this->watermark_size[0];
8893 $h = $this->watermark_size[1];
8894 } elseif (!is_string($this->watermark_size)) {
8895 $maxw -= $this->watermark_size * 2;
8896 $maxh -= $this->watermark_size * 2;
8903 } elseif ($this->watermark_size == 'F') {
8904 if ($this->ColActive) {
8905 $maxw = $this->w - ($this->DeflMargin + $this->DefrMargin);
8907 $maxw = $this->pgwidth;
8909 $maxh = $this->h - ($this->tMargin + $this->bMargin);
8916 } elseif ($this->watermark_size == 'P') { // Default P
8934 if (is_array($this->watermark_pos)) {
8935 $x = $this->watermark_pos[0];
8936 $y = $this->watermark_pos[1];
8937 } elseif ($this->watermark_pos == 'F') { // centred on printable area
8938 if ($this->ColActive) { // *COLUMNS*
8939 if (($this->mirrorMargins) && (($this->page) % 2 == 0)) {
8940 $xadj = $this->DeflMargin - $this->DefrMargin;
8945 $x = ($this->DeflMargin - $xadj + ($this->w - ($this->DeflMargin + $this->DefrMargin)) / 2) - ($w / 2); // *COLUMNS*
8948 $x = ($this->lMargin + ($this->pgwidth) / 2) - ($w / 2);
8950 $y = ($this->tMargin + ($this->h - ($this->tMargin + $this->bMargin)) / 2) - ($h / 2);
8951 } else { // default P - centred on whole page
8952 $x = ($this->w / 2) - ($w / 2);
8953 $y = ($this->h / 2) - ($h / 2);
8955 /* -- IMAGES-WMF -- */
8958 $sy = -$h * Mpdf::SCALE / $info['h'];
8959 $outstring = sprintf('q %.3F 0 0 %.3F %.3F %.3F cm /FO%d Do Q', $sx, $sy, $x * Mpdf::SCALE - $sx * $info['x'], (($this->h - $y) * Mpdf::SCALE) - $sy * $info['y'], $info['i']);
8960 } else { /* -- END IMAGES-WMF -- */
8963 $sy = -$h * Mpdf::SCALE / $info['h'];
8964 $outstring = sprintf('q %.3F 0 0 %.3F %.3F %.3F cm /FO%d Do Q', $sx, $sy, $x * Mpdf::SCALE - $sx * $info['x'], (($this->h - $y) * Mpdf::SCALE) - $sy * $info['y'], $info['i']);
8966 $outstring = sprintf("q %.3F 0 0 %.3F %.3F %.3F cm /I%d Do Q", $w * Mpdf::SCALE, $h * Mpdf::SCALE, $x * Mpdf::SCALE, ($this->h - ($y + $h)) * Mpdf::SCALE, $info['i']);
8970 if ($this->watermarkImgBehind) {
8971 $outstring = $this->watermarkImgAlpha . "\n" . $outstring . "\n" . $this->SetAlpha(1, 'Normal', true) . "\n";
8972 $this->pages[$this->page] = preg_replace('/(___BACKGROUND___PATTERNS' . $this->uniqstr . ')/', "\n" . $outstring . "\n" . '\\1', $this->pages[$this->page]);
8974 $this->writer->write($outstring);
8979 /* -- END WATERMARK -- */
8983 if (isset($this->blk[$this->blklvl]['inner_width']) && $this->blk[$this->blklvl]['inner_width']) {
8984 $maxw = $this->blk[$this->blklvl]['inner_width'];
8986 $maxw = $this->pgwidth;
8992 if ($h > $this->h - ($this->tMargin + $this->bMargin + 1)) { // see below - +10 to avoid drawing too close to border of page
8993 $h = $this->h - ($this->tMargin + $this->bMargin + 1);
8994 if ($this->fullImageHeight) {
8995 $h = $this->fullImageHeight;
9002 // if ( ($x + $w) > $this->fw ) {
9003 if (($x + $w) > $this->w) {
9004 $x = $this->lMargin;
9009 $oldcolumn = $this->CurrCol;
9011 if ($y + $h > $this->PageBreakTrigger and ! $this->InFooter and $this->AcceptPageBreak()) {
9012 $this->AddPage($this->CurOrientation);
9014 $x = $x + $this->MarginCorrection;
9015 $y = $this->tMargin; // mPDF 5.7.3
9018 /* -- COLUMNS -- */
9021 if ($this->CurrCol != $oldcolumn) {
9022 $y = $this->y0;
9023 $x += $this->ChangeColumn * ($this->ColWidth + $this->ColGap);
9024 $this->x += $this->ChangeColumn * ($this->ColWidth + $this->ColGap);
9026 /* -- END COLUMNS -- */
9029 /* -- IMAGES-WMF -- */
9032 $sy = -$h * Mpdf::SCALE / $info['h'];
9033 $outstring = sprintf('q %.3F 0 0 %.3F %.3F %.3F cm /FO%d Do Q', $sx, $sy, $x * Mpdf::SCALE - $sx * $info['x'], (($this->h - $y) * Mpdf::SCALE) - $sy * $info['y'], $info['i']);
9034 } else { /* -- END IMAGES-WMF -- */
9037 $sy = -$h * Mpdf::SCALE / $info['h'];
9038 $outstring = sprintf('q %.3F 0 0 %.3F %.3F %.3F cm /FO%d Do Q', $sx, $sy, $x * Mpdf::SCALE - $sx * $info['x'], (($this->h - $y) * Mpdf::SCALE) - $sy * $info['y'], $info['i']);
9040 $outstring = sprintf("q %.3F 0 0 %.3F %.3F %.3F cm /I%d Do Q", $w * Mpdf::SCALE, $h * Mpdf::SCALE, $x * Mpdf::SCALE, ($this->h - ($y + $h)) * Mpdf::SCALE, $info['i']);
9045 $this->writer->write($outstring);
9047 $this->Link($x, $y, $w, $h, $link);
9051 $this->y = $y + $h;
9054 // Return width-height array
9063 $sizesarray['set-dpi'] = (isset($info['set-dpi']) ? $info['set-dpi'] : 0);
9072 /* -- HTML-CSS -- */
9088 $k = $this->shrin_k;
9103 $widthLeft = $maxWidth - $widthUsed;
9104 $maxHeight = $this->h - ($this->tMargin + $this->bMargin + 10);
9105 if ($this->fullImageHeight) {
9106 $maxHeight = $this->fullImageHeight;
9119 if (!isset($objattr['vertical-align'])) {
9121 $objattr['vertical-align'] = 'M';
9123 $objattr['vertical-align'] = 'BS';
9130 $info = $this->formobjects[$file];
9133 $info = $this->images[$file];
9144 if (($y + $h + $lineHeight > $this->PageBreakTrigger) && !$this->InFooter && !$is_table) {
9145 return [-2, $w, $h];
9163 if (($y + $displayheight + $lineHeight > $this->PageBreakTrigger) && !$this->InFooter) {
9164 return [-2, $w, $h];
9170 elseif (($y + $displayheight > $this->PageBreakTrigger) && !$this->InFooter && !$is_table) {
9171 return [-1, $w, $h];
9182 $objattr['BORDER-WIDTH'] = 0;
9183 $objattr['BORDER-HEIGHT'] = 0;
9184 $objattr['BORDER-X'] = $x;
9185 $objattr['BORDER-Y'] = $y;
9186 $objattr['INNER-WIDTH'] = 0;
9187 $objattr['INNER-HEIGHT'] = 0;
9188 $objattr['INNER-X'] = $x;
9189 $objattr['INNER-Y'] = $y;
9198 $img_w = $w - $extraWidth;
9199 $img_h = $h - $extraHeight;
9201 $objattr['BORDER-WIDTH'] = $img_w + $objattr['padding_left'] / $k + $objattr['padding_right'] / $k + (($objattr['border_left']['w'] / $k + $objattr['border_right']['w'] / $k) / 2);
9202 $objattr['BORDER-HEIGHT'] = $img_h + $objattr['padding_top'] / $k + $objattr['padding_bottom'] / $k + (($objattr['border_top']['w'] / $k + $objattr['border_bottom']['w'] / $k) / 2);
9203 $objattr['BORDER-X'] = $x + $objattr['margin_left'] / $k + (($objattr['border_left']['w'] / $k) / 2);
9204 $objattr['BORDER-Y'] = $y + $objattr['margin_top'] / $k + (($objattr['border_top']['w'] / $k) / 2);
9205 $objattr['INNER-WIDTH'] = $img_w;
9206 $objattr['INNER-HEIGHT'] = $img_h;
9207 $objattr['INNER-X'] = $x + $objattr['padding_left'] / $k + $objattr['margin_left'] / $k + ($objattr['border_left']['w'] / $k);
9208 $objattr['INNER-Y'] = $y + $objattr['padding_top'] / $k + $objattr['margin_top'] / $k + ($objattr['border_top']['w'] / $k);
9213 $img_w = $w - $extraWidth;
9214 $img_h = $h - $extraHeight;
9215 $objattr['BORDER-WIDTH'] = $img_w + (($objattr['border_left']['w'] / $k + $objattr['border_right']['w'] / $k) / 2);
9216 $objattr['BORDER-HEIGHT'] = $img_h + (($objattr['border_top']['w'] / $k + $objattr['border_bottom']['w'] / $k) / 2);
9217 $objattr['BORDER-X'] = $x + $objattr['margin_left'] / $k + (($objattr['border_left']['w'] / $k) / 2);
9218 $objattr['BORDER-Y'] = $y + $objattr['margin_top'] / $k + (($objattr['border_top']['w'] / $k) / 2);
9219 $objattr['INNER-WIDTH'] = $img_w;
9220 $objattr['INNER-HEIGHT'] = $img_h;
9221 $objattr['INNER-X'] = $x + $objattr['margin_left'] / $k + ($objattr['border_left']['w'] / $k);
9222 $objattr['INNER-Y'] = $y + $objattr['margin_top'] / $k + ($objattr['border_top']['w'] / $k);
9227 $b_w = $w - $extraWidth;
9228 $b_h = $h - $extraHeight;
9229 $objattr['BORDER-WIDTH'] = $b_w + $objattr['padding_left'] / $k + $objattr['padding_right'] / $k + (($objattr['border_left']['w'] / $k + $objattr['border_right']['w'] / $k) / 2);
9230 $objattr['BORDER-HEIGHT'] = $b_h + $objattr['padding_top'] / $k + $objattr['padding_bottom'] / $k + (($objattr['border_top']['w'] / $k + $objattr['border_bottom']['w'] / $k) / 2);
9231 $objattr['BORDER-X'] = $x + $objattr['margin_left'] / $k + (($objattr['border_left']['w'] / $k) / 2);
9232 $objattr['BORDER-Y'] = $y + $objattr['margin_top'] / $k + (($objattr['border_top']['w'] / $k) / 2);
9233 $objattr['INNER-X'] = $x + $objattr['padding_left'] / $k + $objattr['margin_left'] / $k + ($objattr['border_left']['w'] / $k);
9234 $objattr['INNER-Y'] = $y + $objattr['padding_top'] / $k + $objattr['margin_top'] / $k + ($objattr['border_top']['w'] / $k);
9235 $objattr['INNER-WIDTH'] = $b_w;
9236 $objattr['INNER-HEIGHT'] = $b_h;
9246 // if (($y + $h > $this->PageBreakTrigger) && !$this->InFooter) {
9247 // $h=$this->h - $y - $this->bMargin;
9253 $objattr['INNER-WIDTH'] = $maxWidth * $objattr['W-PERCENT'] / 100;
9254 $objattr['width'] = $objattr['INNER-WIDTH'];
9260 $objattr['INNER-WIDTH'] = $w;
9283 if (!isset($objattr['BORDER-Y'])) {
9284 $objattr['BORDER-Y'] = 0;
9286 if (!isset($objattr['BORDER-X'])) {
9287 $objattr['BORDER-X'] = 0;
9289 if (!isset($objattr['INNER-Y'])) {
9290 $objattr['INNER-Y'] = 0;
9292 if (!isset($objattr['INNER-X'])) {
9293 $objattr['INNER-X'] = 0;
9296 // Return width-height array
9297 $objattr['OUTER-WIDTH'] = $w;
9298 $objattr['OUTER-HEIGHT'] = $h;
9299 $objattr['OUTER-X'] = $x;
9300 $objattr['OUTER-Y'] = $y;
9304 /* -- END HTML-CSS -- */
9315 if ($this->page > 0 && ((isset($this->pageoutput[$this->page]['LineJoin']) && $this->pageoutput[$this->page]['LineJoin'] != $s) || !isset($this->pageoutput[$this->page]['LineJoin']))) {
9316 $this->writer->write($s);
9318 $this->pageoutput[$this->page]['LineJoin'] = $s;
9324 if ($this->page > 0 && ((isset($this->pageoutput[$this->page]['LineCap']) && $this->pageoutput[$this->page]['LineCap'] != $s) || !isset($this->pageoutput[$this->page]['LineCap']))) {
9325 $this->writer->write($s);
9327 $this->pageoutput[$this->page]['LineCap'] = $s;
9338 if ($this->page > 0 && ((isset($this->pageoutput[$this->page]['Dash']) && $this->pageoutput[$this->page]['Dash'] != $s) || !isset($this->pageoutput[$this->page]['Dash']))) {
9339 $this->writer->write($s);
9342 $this->pageoutput[$this->page]['Dash'] = $s;
9349 $this->DisplayPreferences .= $preferences;
9354 // Added collapsible to allow collapsible top-margin on new page
9357 $margin = isset($this->blk[$this->blklvl]['outer_left_margin']) ? $this->blk[$this->blklvl]['outer_left_margin'] : 0;
9359 $this->x = $this->lMargin + $margin;
9361 if ($collapsible && ($this->y == $this->tMargin) && (!$this->ColActive)) {
9366 $this->y += $this->lasth;
9368 $this->y += $h;
9372 /* -- HTML-CSS -- */
9374 function DivLn($h, $level = -3, $move_y = true, $collapsible = false, $state = 0)
9377 // Used in Columns and keep-with-table i.e. "kwt"
9381 // this->x is returned as it was
9383 if ($collapsible && (sprintf("%0.4f", $this->y) == sprintf("%0.4f", $this->tMargin)) && (!$this->ColActive)) {
9388 // if ($collapsible && (sprintf("%0.4f", $this->y)==sprintf("%0.4f", $this->y0)) && ($this->ColActive) && $this->CurrCol == 0) { return; } // *COLUMNS*
9389 if ($collapsible && (sprintf("%0.4f", $this->y) == sprintf("%0.4f", $this->y0)) && ($this->ColActive)) {
9392 // Still use this method if columns or keep-with-table, as it allows repositioning later
9394 if (!$this->ColActive && !$this->kwt) {
9395 if ($move_y && !$this->ColActive) {
9396 $this->y += $h;
9401 if ($level == -3) {
9402 $level = $this->blklvl;
9404 $firstblockfill = $this->GetFirstBlockFill();
9405 if ($firstblockfill && $this->blklvl > 0 && $this->blklvl >= $firstblockfill) {
9408 $last_fc = $this->FillColor;
9409 $bak_x = $this->x;
9410 $bak_h = $this->divheight;
9411 $this->divheight = 0; // Temporarily turn off divheight - as Cell() uses it to check for PageBreak
9413 $this->x = $this->lMargin + $this->blk[$blvl]['outer_left_margin'];
9415 if ($this->blk[$blvl]['bgcolor']) {
9416 $this->SetFColor($this->blk[$blvl]['bgcolorarray']);
9418 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'])) {
9419 $x = $this->x;
9420 $this->Cell(($this->blk[$blvl]['width']), $h, '', '', 0, '', 1);
9421 $this->x = $x;
9422 if (!$this->keep_block_together && !$this->writingHTMLheader && !$this->writingHTMLfooter) {
9424 if ($blvl == $this->blklvl) {
9425 $this->PaintDivLnBorder($state, $blvl, $h);
9427 $this->PaintDivLnBorder(0, $blvl, $h);
9431 $last_x = $this->lMargin + $this->blk[$blvl]['outer_left_margin'];
9432 $last_w = $this->blk[$blvl]['width'];
9433 $last_fc = $this->FillColor;
9436 if (isset($this->blk[$this->blklvl]['bgcolorarray'])) {
9437 $bcor = $this->blk[$this->blklvl]['bgcolorarray'];
9438 $this->SetFColor($bcor);
9440 $this->x = $bak_x;
9441 $this->divheight = $bak_h;
9444 $this->y += $h;
9448 /* -- END HTML-CSS -- */
9454 $this->x = $x;
9456 $this->x = $this->w + $x;
9463 $this->x = $this->lMargin;
9465 $this->y = $y;
9467 $this->y = $this->h + $y;
9474 $this->SetY($y);
9475 $this->SetX($x);
9480 $this->logger->debug(sprintf('PDF generated in %.6F seconds', microtime(true) - $this->time0), ['context' => LogContext::STATISTICS]);
9483 if ($this->state < 3) {
9484 $this->Close();
9487 if ($this->debug && error_get_last()) {
9500 if (($this->PDFA || $this->PDFX) && $this->encrypted) {
9501 throw new \Mpdf\MpdfException('PDF/A1-b or PDF/X1-a does not permit encryption of documents.');
9504 if (count($this->PDFAXwarnings) && (($this->PDFA && !$this->PDFAauto) || ($this->PDFX && !$this->PDFXauto))) {
9505 if ($this->PDFA) {
9506 $standard = 'PDFA/1-b';
9507 $option = '$mpdf->PDFAauto';
9509 $standard = 'PDFX/1-a ';
9510 $option = '$mpdf->PDFXauto';
9513 $this->logger->warning(sprintf('PDF could not be generated as it stands as a %s compliant file.', $standard), ['context' => LogContext::PDFA_PDFX]);
9514 $this->logger->warning(sprintf('These issues can be automatically fixed by mPDF using %s = true;', $option), ['context' => LogContext::PDFA_PDFX]);
9515 $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]);
9517 $this->PDFAXwarnings = array_unique($this->PDFAXwarnings);
9518 foreach ($this->PDFAXwarnings as $w) {
9519 $this->logger->warning($w, ['context' => LogContext::PDFA_PDFX]);
9525 $this->logger->debug(sprintf('Compiled in %.6F seconds', microtime(true) - $this->time0), ['context' => LogContext::STATISTICS]);
9526 $this->logger->debug(sprintf('Peak Memory usage %s MB', number_format(memory_get_peak_usage(true) / (1024 * 1024), 2)), ['context' => LogContext::STATISTICS]);
9527 $this->logger->debug(sprintf('PDF file size %s kB', number_format(strlen($this->buffer) / 1024)), ['context' => LogContext::STATISTICS]);
9528 $this->logger->debug(sprintf('%d fonts used', count($this->fonts)), ['context' => LogContext::STATISTICS]);
9554 if ($this->debug && !$this->allow_output_buffering && ob_get_contents()) {
9555 throw new \Mpdf\MpdfException('Output has already been sent from the script - PDF file generation aborted.');
9560 header('Content-Type: application/pdf');
9564 header('Content-Length: ' . strlen($this->buffer));
9567 header('Content-disposition: inline; filename="' . $name . '"');
9568 header('Cache-Control: public, must-revalidate, max-age=0');
9570 header('X-Generator: mPDF' . ($this->exposeVersion ? (' ' . static::VERSION) : ''));
9572 header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
9575 echo $this->buffer;
9585 header('Content-Description: File Transfer');
9586 header('Content-Transfer-Encoding: binary');
9587 header('Cache-Control: public, must-revalidate, max-age=0');
9589 header('X-Generator: mPDF' . ($this->exposeVersion ? (' ' . static::VERSION) : ''));
9591 header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
9592 header('Content-Type: application/pdf');
9596 header('Content-Length: ' . strlen($this->buffer));
9599 header('Content-Disposition: attachment; filename="' . $name . '"');
9601 echo $this->buffer;
9612 fwrite($f, $this->buffer, strlen($this->buffer));
9618 $this->cache->clearOld();
9619 return $this->buffer;
9625 $this->cache->clearOld();
9635 // Check for locale-related bug
9664 $this->state = 2;
9665 $nb = $this->page;
9667 if ($this->mirrorMargins && $n % 2 == 0) {
9673 $this->page = $n;
9674 $pn = $this->docPageNum($n);
9676 $pnstr = $this->pagenumPrefix . $pn . $this->pagenumSuffix;
9681 $pnt = $this->docPageNumTotal($n);
9684 $pntstr = $this->nbpgPrefix . $pnt . $this->nbpgSuffix;
9689 if (isset($this->saveHTMLHeader[$n][$OE])) {
9690 $html = isset($this->saveHTMLHeader[$n][$OE]['html']) ? $this->saveHTMLHeader[$n][$OE]['html'] : '';
9691 $this->lMargin = $this->saveHTMLHeader[$n][$OE]['ml'];
9692 $this->rMargin = $this->saveHTMLHeader[$n][$OE]['mr'];
9693 $this->tMargin = $this->saveHTMLHeader[$n][$OE]['mh'];
9694 $this->bMargin = $this->saveHTMLHeader[$n][$OE]['mf'];
9695 $this->margin_header = $this->saveHTMLHeader[$n][$OE]['mh'];
9696 $this->margin_footer = $this->saveHTMLHeader[$n][$OE]['mf'];
9697 $this->w = $this->saveHTMLHeader[$n][$OE]['pw'];
9698 $this->h = $this->saveHTMLHeader[$n][$OE]['ph'];
9699 $rotate = (isset($this->saveHTMLHeader[$n][$OE]['rotate']) ? $this->saveHTMLHeader[$n][$OE]['rotate'] : null);
9700 $this->Reset();
9701 $this->pageoutput[$n] = [];
9702 $this->pgwidth = $this->w - $this->lMargin - $this->rMargin;
9703 $this->x = $this->lMargin;
9704 $this->y = $this->margin_header;
9707 $html = $this->aliasReplace($html, $pnstr, $pntstr, $nb);
9709 $this->HTMLheaderPageLinks = [];
9710 $this->HTMLheaderPageAnnots = [];
9711 $this->HTMLheaderPageForms = [];
9712 $this->pageBackgrounds = [];
9714 $this->writingHTMLheader = true;
9715 $this->WriteHTML($html, HTMLParserMode::HTML_HEADER_BUFFER);
9716 $this->writingHTMLheader = false;
9717 $this->Reset();
9718 $this->pageoutput[$n] = [];
9720 $s = $this->PrintPageBackgrounds();
9721 $this->headerbuffer = $s . $this->headerbuffer;
9724 $os .= sprintf('q 0 -1 1 0 0 %.3F cm ', ($this->w * Mpdf::SCALE));
9726 // $os .= sprintf('q 0 1 -1 0 %.3F %.3F cm ',($this->h*Mpdf::SCALE), (($this->rMargin - $this->lMargin )*Mpdf::SCALE));
9728 $os .= $this->headerbuffer;
9736 $this->pages[$n] = preg_replace('/(___HEADER___MARKER' . $this->uniqstr . ')/', "\n" . $os . "\n" . '\\1', $this->pages[$n]);
9738 $lks = $this->HTMLheaderPageLinks;
9747 $bx = $ay - ($lh / Mpdf::SCALE);
9748 $by = $this->w - $ax;
9750 $lk[1] = ($this->h - $by) * Mpdf::SCALE - $lw;
9752 $this->PageLinks[$n][] = $lk;
9754 /* -- FORMS -- */
9755 foreach ($this->HTMLheaderPageForms as $f) {
9756 $this->form->forms[$f['n']] = $f;
9758 /* -- END FORMS -- */
9761 if (isset($this->saveHTMLFooter[$n][$OE])) {
9763 $html = $this->saveHTMLFooter[$this->page][$OE]['html'];
9765 $this->lMargin = $this->saveHTMLFooter[$n][$OE]['ml'];
9766 $this->rMargin = $this->saveHTMLFooter[$n][$OE]['mr'];
9767 $this->tMargin = $this->saveHTMLFooter[$n][$OE]['mh'];
9768 $this->bMargin = $this->saveHTMLFooter[$n][$OE]['mf'];
9769 $this->margin_header = $this->saveHTMLFooter[$n][$OE]['mh'];
9770 $this->margin_footer = $this->saveHTMLFooter[$n][$OE]['mf'];
9771 $this->w = $this->saveHTMLFooter[$n][$OE]['pw'];
9772 $this->h = $this->saveHTMLFooter[$n][$OE]['ph'];
9773 $rotate = (isset($this->saveHTMLFooter[$n][$OE]['rotate']) ? $this->saveHTMLFooter[$n][$OE]['rotate'] : null);
9774 $this->Reset();
9775 $this->pageoutput[$n] = [];
9776 $this->pgwidth = $this->w - $this->lMargin - $this->rMargin;
9777 $this->x = $this->lMargin;
9778 $top_y = $this->y = $this->h - $this->margin_footer;
9780 // if bottom-margin==0, corrects to avoid division by zero
9781 if ($this->y == $this->h) {
9782 $top_y = $this->y = ($this->h + 0.01);
9786 $html = $this->aliasReplace($html, $pnstr, $pntstr, $nb);
9788 $this->HTMLheaderPageLinks = [];
9789 $this->HTMLheaderPageAnnots = [];
9790 $this->HTMLheaderPageForms = [];
9791 $this->pageBackgrounds = [];
9793 $this->writingHTMLfooter = true;
9794 $this->InFooter = true;
9795 $this->WriteHTML($html, HTMLParserMode::HTML_HEADER_BUFFER);
9796 $this->InFooter = false;
9797 $this->Reset();
9798 $this->pageoutput[$n] = [];
9800 $fheight = $this->y - $top_y;
9801 $adj = -$fheight;
9803 $s = $this->PrintPageBackgrounds(-$adj);
9804 $this->headerbuffer = $s . $this->headerbuffer;
9805 $this->writingHTMLfooter = false; // mPDF 5.7.3 (moved after PrintPageBackgrounds so can adjust position of images in footer)
9808 $os .= $this->StartTransform(true) . "\n";
9811 $os .= sprintf('q 0 -1 1 0 0 %.3F cm ', ($this->w * Mpdf::SCALE));
9813 // $os .= sprintf('q 0 1 -1 0 %.3F %.3F cm ',($this->h*Mpdf::SCALE), (($this->rMargin - $this->lMargin )*Mpdf::SCALE));
9816 $os .= $this->transformTranslate(0, $adj, true) . "\n";
9817 $os .= $this->headerbuffer;
9823 $os .= $this->StopTransform(true) . "\n";
9828 $this->pages[$n] = preg_replace('/(___HEADER___MARKER' . $this->uniqstr . ')/', "\n" . $os . "\n" . '\\1', $this->pages[$n]);
9830 $lks = $this->HTMLheaderPageLinks;
9834 $lk[1] -= $adj * Mpdf::SCALE;
9844 $bx = $ay - ($lh / Mpdf::SCALE);
9845 $by = $this->w - $ax;
9847 $lk[1] = ($this->h - $by) * Mpdf::SCALE - $lw;
9850 $this->PageLinks[$n][] = $lk;
9853 /* -- FORMS -- */
9854 foreach ($this->HTMLheaderPageForms as $f) {
9856 $this->form->forms[$f['n']] = $f;
9858 /* -- END FORMS -- */
9863 $this->pages[$n] = $this->aliasReplace($this->pages[$n], $pnstr, $pntstr, $nb);
9866 $this->page = $nb;
9867 $this->state = 1;
9870 /* -- ANNOTATIONS -- */
9874 $colarray = $this->colorConverter->convert('rgb(' . $colarray[0] . ',' . $colarray[1] . ',' . $colarray[2] . ')', $this->PDFAXwarnings);
9877 $colarray = $this->colorConverter->convert('yellow', $this->PDFAXwarnings);
9880 $x = $this->x;
9883 $y = $this->y;
9885 $page = $this->page;
9886 if ($page < 1) { // Document has not been started - assume it's for first page
9889 $x = $this->lMargin;
9892 $y = $this->tMargin;
9896 if ($this->PDFA || $this->PDFX) {
9897 if (($this->PDFA && !$this->PDFAauto) || ($this->PDFX && !$this->PDFXauto)) {
9898 $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)";
9900 $x = ($this->w) - $this->rMargin * 0.66;
9902 if (!$this->annotMargin) {
9903 $y -= $this->FontSize / 2;
9906 if (!$opacity && $this->annotMargin) {
9909 $opacity = $this->annotOpacity;
9914 if ($this->keep_block_together) { // don't write yet
9916 } elseif ($this->table_rotate) {
9917 $this->tbrot_Annots[$this->page][] = $an;
9919 } elseif ($this->kwt) {
9920 $this->kwt_Annots[$this->page][] = $an;
9924 if ($this->writingHTMLheader || $this->writingHTMLfooter) {
9925 $this->HTMLheaderPageAnnots[] = $an;
9930 $this->PageAnnots[$page][] = $an;
9932 /* -- COLUMNS -- */
9933 // Save cross-reference to Column buffer
9934 $ref = isset($this->PageAnnots[$this->page]) ? (count($this->PageAnnots[$this->page]) - 1) : -1;
9935 $this->columnAnnots[$this->CurrCol][intval($this->x)][intval($this->y)] = $ref;
9936 /* -- END COLUMNS -- */
9939 /* -- END ANNOTATIONS -- */
9945 $this->_puthtmlheaders();
9949 // Remove references to unused fonts (usually default font)
9950 foreach ($this->fonts as $fk => $font) {
9951 if (isset($font['type']) && $font['type'] == 'TTF' && !$font['used']) {
9952 if ($font['sip'] || $font['smp']) {
9953 foreach ($font['subsetfontids'] as $k => $fid) {
9954 foreach ($this->pages as $pn => $page) {
9955 $this->pages[$pn] = preg_replace('/\s\/F' . $fid . ' \d[\d.]* Tf\s/is', ' ', $this->pages[$pn]);
9959 foreach ($this->pages as $pn => $page) {
9960 $this->pages[$pn] = preg_replace('/\s\/F' . $font['i'] . ' \d[\d.]* Tf\s/is', ' ', $this->pages[$pn]);
9966 if (count($this->layers)) {
9967 foreach ($this->pages as $pn => $page) {
9968 preg_match_all('/\/OCZ-index \/ZI(\d+) BDC(.*?)(EMCZ)-index/is', $this->pages[$pn], $m1);
9969 preg_match_all('/\/OCBZ-index \/ZI(\d+) BDC(.*?)(EMCBZ)-index/is', $this->pages[$pn], $m2);
9970 preg_match_all('/\/OCGZ-index \/ZI(\d+) BDC(.*?)(EMCGZ)-index/is', $this->pages[$pn], $m3);
9988 $this->pages[$pn] = str_replace($m[0][$i], '', $this->pages[$pn]);
9989 $this->pages[$pn] .= "\n" . $m[0][$i] . "\n";
9991 $this->pages[$pn] = preg_replace('/\/OC[BG]{0,1}Z-index \/ZI(\d+) BDC/is', '/OC /ZI\\1 BDC ', $this->pages[$pn]);
9992 $this->pages[$pn] = preg_replace('/EMC[BG]{0,1}Z-index/is', 'EMC', $this->pages[$pn]);
9997 $this->pageWriter->writePages();
10001 $this->resourceWriter->writeResources();
10004 $this->writer->object();
10005 $this->InfoRoot = $this->n;
10006 $this->writer->write('<<');
10009 $this->metadataWriter->writeInfo();
10011 $this->writer->write('>>');
10012 $this->writer->write('endobj');
10015 if ($this->PDFA || $this->PDFX) {
10016 $this->metadataWriter->writeMetadata();
10020 if ($this->PDFA || $this->PDFX || $this->ICCProfile) {
10021 $this->metadataWriter->writeOutputIntent();
10025 if ($this->associatedFiles) {
10026 $this->metadataWriter->writeAssociatedFiles();
10030 $this->writer->object();
10031 $this->writer->write('<<');
10035 $this->metadataWriter->writeCatalog();
10037 $this->writer->write('>>');
10038 $this->writer->write('endobj');
10040 // Cross-ref
10041 $o = strlen($this->buffer);
10042 $this->writer->write('xref');
10043 $this->writer->write('0 ' . ($this->n + 1));
10044 $this->writer->write('0000000000 65535 f ');
10046 for ($i = 1; $i <= $this->n; $i++) {
10047 $this->writer->write(sprintf('%010d 00000 n ', $this->offsets[$i]));
10051 $this->writer->write('trailer');
10052 $this->writer->write('<<');
10054 $this->metadataWriter->writeTrailer();
10056 $this->writer->write('>>');
10057 $this->writer->write('startxref');
10058 $this->writer->write($o);
10060 $this->buffer .= '%%EOF';
10061 $this->state = 3;
10083 if (!($pagesel && $this->page == 1 && (sprintf("%0.4f", $this->y) == sprintf("%0.4f", $this->tMargin)))) {
10084 $this->page++;
10085 $this->pages[$this->page] = '';
10087 $this->state = 2;
10091 $this->_setPageSize($newformat, $orientation);
10094 /* -- CSS-PAGE -- */
10095 // Paged media (page-box)
10096 if ($pagesel || (isset($this->page_box['using']) && $this->page_box['using'])) {
10098 if ($pagesel || $this->page == 1) {
10104 if ($this->mirrorMargins && ($this->page % 2 == 0)) {
10112 } elseif ($this->page_box['current']) {
10113 $psel = $this->page_box['current'];
10118 list($orientation, $mgl, $mgr, $mgt, $mgb, $mgh, $mgf, $hname, $fname, $bg, $resetpagenum, $pagenumstyle, $suppress, $marks, $newformat) = $this->SetPagedMediaCSS($psel, $first, $oddEven);
10120 if ($this->mirrorMargins && ($this->page % 2 == 0)) {
10126 $ehvalue = -1;
10133 $efvalue = -1;
10142 $ohvalue = -1;
10149 $ofvalue = -1;
10154 $this->PageNumSubstitutions[] = ['from' => ($this->page), 'reset' => $resetpagenum, 'type' => $pagenumstyle, 'suppress' => $suppress];
10157 // PAGED MEDIA - CROP / CROSS MARKS from @PAGE
10158 $this->show_marks = $marks;
10161 if (isset($bg['BACKGROUND-COLOR'])) {
10162 $cor = $this->colorConverter->convert($bg['BACKGROUND-COLOR'], $this->PDFAXwarnings);
10164 $this->bodyBackgroundColor = $cor;
10167 $this->bodyBackgroundColor = false;
10170 /* -- BACKGROUNDS -- */
10171 if (isset($bg['BACKGROUND-GRADIENT'])) {
10172 $this->bodyBackgroundGradient = $bg['BACKGROUND-GRADIENT'];
10174 $this->bodyBackgroundGradient = false;
10178 if (isset($bg['BACKGROUND-IMAGE']) && $bg['BACKGROUND-IMAGE']) {
10179 $ret = $this->SetBackground($bg, $this->pgwidth);
10181 $this->bodyBackgroundImage = $ret;
10184 $this->bodyBackgroundImage = false;
10186 /* -- END BACKGROUNDS -- */
10188 $this->page_box['current'] = $psel;
10189 $this->page_box['using'] = true;
10191 /* -- END CSS-PAGE -- */
10195 $orientation = $this->DefOrientation;
10198 if ($orientation != $this->DefOrientation) {
10199 $this->OrientationChanges[$this->page] = true;
10203 if ($orientation != $this->CurOrientation || $newformat) {
10207 $this->wPt = $this->fwPt;
10208 $this->hPt = $this->fhPt;
10209 $this->w = $this->fw;
10210 $this->h = $this->fh;
10211 if (($this->forcePortraitHeaders || $this->forcePortraitMargins) && $this->DefOrientation == 'P') {
10212 $this->tMargin = $this->orig_tMargin;
10213 $this->bMargin = $this->orig_bMargin;
10214 $this->DeflMargin = $this->orig_lMargin;
10215 $this->DefrMargin = $this->orig_rMargin;
10216 $this->margin_header = $this->orig_hMargin;
10217 $this->margin_footer = $this->orig_fMargin;
10222 $this->wPt = $this->fhPt;
10223 $this->hPt = $this->fwPt;
10224 $this->w = $this->fh;
10225 $this->h = $this->fw;
10227 if (($this->forcePortraitHeaders || $this->forcePortraitMargins) && $this->DefOrientation == 'P') {
10228 $this->tMargin = $this->orig_lMargin;
10229 $this->bMargin = $this->orig_rMargin;
10230 $this->DeflMargin = $this->orig_bMargin;
10231 $this->DefrMargin = $this->orig_tMargin;
10232 $this->margin_header = $this->orig_hMargin;
10233 $this->margin_footer = $this->orig_fMargin;
10239 $this->CurOrientation = $orientation;
10240 $this->ResetMargins();
10241 $this->pgwidth = $this->w - $this->lMargin - $this->rMargin;
10242 $this->PageBreakTrigger = $this->h - $this->bMargin;
10245 $this->pageDim[$this->page]['w'] = $this->w;
10246 $this->pageDim[$this->page]['h'] = $this->h;
10248 $this->pageDim[$this->page]['outer_width_LR'] = isset($this->page_box['outer_width_LR']) ? $this->page_box['outer_width_LR'] : 0;
10249 $this->pageDim[$this->page]['outer_width_TB'] = isset($this->page_box['outer_width_TB']) ? $this->page_box['outer_width_TB'] : 0;
10251 if (!isset($this->page_box['outer_width_LR']) && !isset($this->page_box['outer_width_TB'])) {
10252 $this->pageDim[$this->page]['bleedMargin'] = 0;
10253 } elseif ($this->bleedMargin <= $this->page_box['outer_width_LR'] && $this->bleedMargin <= $this->page_box['outer_width_TB']) {
10254 $this->pageDim[$this->page]['bleedMargin'] = $this->bleedMargin;
10256 $this->pageDim[$this->page]['bleedMargin'] = min($this->page_box['outer_width_LR'], $this->page_box['outer_width_TB']) - 0.01;
10259 // If Page Margins are re-defined
10261 if ((strlen($mgl) > 0 && $this->DeflMargin != $mgl) || (strlen($mgr) > 0 && $this->DefrMargin != $mgr) || (strlen($mgt) > 0 && $this->tMargin != $mgt) || (strlen($mgb) > 0 && $this->bMargin != $mgb) || (strlen($mgh) > 0 && $this->margin_header != $mgh) || (strlen($mgf) > 0 && $this->margin_footer != $mgf)) {
10264 $this->DeflMargin = $mgl;
10268 $this->DefrMargin = $mgr;
10272 $this->tMargin = $mgt;
10276 $this->bMargin = $mgb;
10280 $this->margin_header = $mgh;
10284 $this->margin_footer = $mgf;
10287 $this->ResetMargins();
10288 $this->SetAutoPageBreak($this->autoPageBreak, $this->bMargin);
10290 $this->pgwidth = $this->w - $this->lMargin - $this->rMargin;
10294 $this->ResetMargins();
10295 $this->pgwidth = $this->w - $this->lMargin - $this->rMargin;
10296 $this->SetAutoPageBreak($this->autoPageBreak, $this->bMargin);
10299 $this->y0 = $this->tMargin;
10301 $this->x = $this->lMargin;
10302 $this->y = $this->tMargin;
10303 $this->FontFamily = '';
10307 $this->HTMLHeader = '';
10315 if (isset($this->pageHTMLheaders[$name])) {
10316 $this->HTMLHeader = $this->pageHTMLheaders[$name];
10318 $this->HTMLHeader = '';
10324 $this->HTMLHeaderE = '';
10332 if (isset($this->pageHTMLheaders[$name])) {
10333 $this->HTMLHeaderE = $this->pageHTMLheaders[$name];
10335 $this->HTMLHeaderE = '';
10341 $this->HTMLFooter = '';
10349 if (isset($this->pageHTMLfooters[$name])) {
10350 $this->HTMLFooter = $this->pageHTMLfooters[$name];
10352 $this->HTMLFooter = '';
10358 $this->HTMLFooterE = '';
10366 if (isset($this->pageHTMLfooters[$name])) {
10367 $this->HTMLFooterE = $this->pageHTMLfooters[$name];
10369 $this->HTMLFooterE = '';
10375 $this->SetHTMLHeader($this->HTMLHeader);
10376 $this->SetHTMLHeader($this->HTMLHeaderE, 'E');
10377 $this->SetHTMLFooter($this->HTMLFooter);
10378 $this->SetHTMLFooter($this->HTMLFooterE, 'E');
10382 if (($this->mirrorMargins) && (($this->page) % 2 == 0)) { // EVEN
10383 $this->_setAutoHeaderHeight($this->HTMLHeaderE);
10384 $this->_setAutoFooterHeight($this->HTMLFooterE);
10386 $this->_setAutoHeaderHeight($this->HTMLHeader);
10387 $this->_setAutoFooterHeight($this->HTMLFooter);
10391 $this->y0 = $this->tMargin;
10393 $this->x = $this->lMargin;
10394 $this->y = $this->tMargin;
10401 if ($this->HTMLHeader === '' && $this->HTMLHeaderE === '') {
10405 if ($this->setAutoTopMargin == 'pad') {
10412 $this->tMargin = $this->margin_header + $h + $this->orig_tMargin;
10413 } elseif ($this->setAutoTopMargin == 'stretch') {
10420 $this->tMargin = max($this->orig_tMargin, $this->margin_header + $h + $this->autoMarginPadding);
10428 if ($this->HTMLFooter === '' && $this->HTMLFooterE === '') {
10432 if ($this->setAutoBottomMargin == 'pad') {
10439 $this->bMargin = $this->margin_footer + $h + $this->orig_bMargin;
10440 $this->PageBreakTrigger = $this->h - $this->bMargin;
10441 } elseif ($this->setAutoBottomMargin == 'stretch') {
10448 $this->bMargin = max($this->orig_bMargin, $this->margin_footer + $h + $this->autoMarginPadding);
10449 $this->PageBreakTrigger = $this->h - $this->bMargin;
10455 /* -- CSS-IMAGE-FLOAT -- */
10456 $this->printfloatbuffer();
10457 /* -- END CSS-IMAGE-FLOAT -- */
10459 if ($this->visibility != 'visible') {
10460 $this->SetVisibility('visible');
10462 $this->EndLayer();
10464 $this->state = 1;
10469 // Now print line exactly where $y secifies - called from Text() and Cell() - adjust position there
10471 $w = ($this->GetStringWidth($txt, false, $OTLdata, $textvar) * Mpdf::SCALE) + ($this->charspacing * mb_strlen($txt, $this->mb_enc)) + ( $this->ws * mb_substr_count($txt, ' ', $this->mb_enc));
10473 return sprintf('%.3F %.3F m %.3F %.3F l S', $x * Mpdf::SCALE, ($this->h - $y) * Mpdf::SCALE, ($x * Mpdf::SCALE) + $w, ($this->h - $y) * Mpdf::SCALE);
10478 /* -- WATERMARK -- */
10483 if ($this->PDFA || $this->PDFX) {
10487 if (!$this->watermark_font) {
10488 $this->watermark_font = $this->default_font;
10491 $this->SetFont($this->watermark_font, "B", $fontsize, false); // Don't output
10492 $texte = $this->purify_utf8_text($texte);
10494 if ($this->text_input_as_HTML) {
10495 $texte = $this->all_entities_to_utf8($texte);
10498 if ($this->usingCoreFont) {
10499 $texte = mb_convert_encoding($texte, $this->mb_enc, 'UTF-8');
10503 if (preg_match("/([" . $this->pregRTLchars . "])/u", $texte)) {
10504 $this->biDirectional = true;
10508 $save_OTLtags = $this->OTLtags;
10509 $this->OTLtags = [];
10510 if ($this->useKerning) {
10511 if ($this->CurrentFont['haskernGPOS']) {
10512 $this->OTLtags['Plus'] .= ' kern';
10518 /* -- OTL -- */
10519 // Use OTL OpenType Table Layout - GSUB & GPOS
10520 if (isset($this->CurrentFont['useOTL']) && $this->CurrentFont['useOTL']) {
10521 $texte = $this->otl->applyOTL($texte, $this->CurrentFont['useOTL']);
10522 $OTLdata = $this->otl->OTLdata;
10524 /* -- END OTL -- */
10525 $this->OTLtags = $save_OTLtags;
10527 $this->magic_reverse_dir($texte, $this->directionality, $OTLdata);
10529 $this->SetAlpha($alpha);
10531 $this->SetTColor($this->colorConverter->convert(0, $this->PDFAXwarnings));
10535 $maxlen = (min($this->w, $this->h) ); // sets max length of text as 7/8 width/height of page
10538 $this->SetFont($this->watermark_font, "B", $szfont, false); // Don't output
10541 $strlen = $this->GetStringWidth($texte, true, $OTLdata, $textvar);
10542 if ($strlen > $maxlen - $offset) {
10543 $szfont --;
10549 $this->SetFont($this->watermark_font, "B", $szfont - 0.1, true, true); // Output The -0.1 is because SetFont above is not written to PDF
10555 $wx = ($this->w / 2) - $adj + $offset / 3;
10556 $wy = ($this->h / 2) + $opp;
10558 $this->Rotate($angle, $wx, $wy);
10559 $this->Text($wx, $wy, $texte, $OTLdata, $textvar);
10560 $this->Rotate(0);
10561 $this->SetTColor($this->colorConverter->convert(0, $this->PDFAXwarnings));
10563 $this->SetAlpha(1);
10568 if ($this->PDFA || $this->PDFX) {
10572 if ($this->watermarkImgBehind) {
10573 $this->watermarkImgAlpha = $this->SetAlpha($alpha, 'Normal', true);
10575 $this->SetAlpha($alpha, $this->watermarkImgAlphaBlend);
10578 $this->Image($src, 0, 0, 0, 0, '', '', true, true, true);
10580 if (!$this->watermarkImgBehind) {
10581 $this->SetAlpha(1);
10585 /* -- END WATERMARK -- */
10587 function Rotate($angle, $x = -1, $y = -1)
10589 if ($x == -1) {
10590 $x = $this->x;
10592 if ($y == -1) {
10593 $y = $this->y;
10595 if ($this->angle != 0) {
10596 $this->writer->write('Q');
10598 $this->angle = $angle;
10604 $cy = ($this->h - $y) * Mpdf::SCALE;
10605 $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));
10611 if (empty($this->directWrite)) {
10612 $this->directWrite = new DirectWrite($this, $this->otl, $this->sizeConverter, $this->colorConverter);
10615 $this->directWrite->CircularText($x, $y, $r, $text, $align, $fontfamily, $fontsize, $fontstyle, $kerning, $fontwidth, $divider);
10621 $hp = $this->h;
10631 $MyArc = 4 / 3 * (sqrt(2) - 1);
10632 $this->writer->write(sprintf('%.3F %.3F m', ($x + $r) * Mpdf::SCALE, ($hp - $y) * Mpdf::SCALE));
10633 $xc = $x + $w - $r;
10635 $this->writer->write(sprintf('%.3F %.3F l', $xc * Mpdf::SCALE, ($hp - $y) * Mpdf::SCALE));
10637 $this->_Arc($xc + $r * $MyArc, $yc - $r, $xc + $r, $yc - $r * $MyArc, $xc + $r, $yc);
10638 $xc = $x + $w - $r;
10639 $yc = $y + $h - $r;
10640 $this->writer->write(sprintf('%.3F %.3F l', ($x + $w) * Mpdf::SCALE, ($hp - $yc) * Mpdf::SCALE));
10642 $this->_Arc($xc + $r, $yc + $r * $MyArc, $xc + $r * $MyArc, $yc + $r, $xc, $yc + $r);
10644 $yc = $y + $h - $r;
10645 $this->writer->write(sprintf('%.3F %.3F l', $xc * Mpdf::SCALE, ($hp - ($y + $h)) * Mpdf::SCALE));
10647 $this->_Arc($xc - $r * $MyArc, $yc + $r, $xc - $r, $yc + $r * $MyArc, $xc - $r, $yc);
10650 $this->writer->write(sprintf('%.3F %.3F l', ($x) * Mpdf::SCALE, ($hp - $yc) * Mpdf::SCALE));
10652 $this->_Arc($xc - $r, $yc - $r * $MyArc, $xc - $r * $MyArc, $yc - $r, $xc, $yc - $r);
10653 $this->writer->write($op);
10658 $h = $this->h;
10659 $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));
10666 /* -- DIRECTW -- */
10667 function Shaded_box($text, $font = '', $fontstyle = 'B', $szfont = '', $width = '70%', $style = 'DF', $radius = 2.5, $fill = '#FFFFFF', $color = '#000000', $pad = 2)
10669 // F (shading - no line),S (line, no shading),DF (both)
10670 if (empty($this->directWrite)) {
10671 $this->directWrite = new DirectWrite($this, $this->otl, $this->sizeConverter, $this->colorConverter);
10673 $this->directWrite->Shaded_box($text, $font, $fontstyle, $szfont, $width, $style, $radius, $fill, $color, $pad);
10676 /* -- END DIRECTW -- */
10683 $uni = -1;
10688 if (($h <= 0xDF) && ($i < $len - 1)) {
10690 } elseif (($h <= 0xEF) && ($i < $len - 2)) {
10692 } elseif (($h <= 0xF4) && ($i < $len - 3)) {
10698 if ($addSubset && isset($this->CurrentFont['subset'])) {
10699 $this->CurrentFont['subset'][$uni] = $uni;
10706 // Convert utf-8 string to <HHHHHH> for Font Subsets
10710 // $str = preg_replace('/'.preg_quote($this->aliasNbPg,'/').'/', chr(7), $str ); // mPDF 6 deleted
10711 // $str = preg_replace('/'.preg_quote($this->aliasNbPgGp,'/').'/', chr(8), $str ); // mPDF 6 deleted
10712 $unicode = $this->UTF8StringToArray($str);
10713 $orig_fid = $this->CurrentFont['subsetfontids'][0];
10714 $last_fid = $this->CurrentFont['subsetfontids'][0];
10719 $ret .= '> Tj /F'.$orig_fid.' '.$this->FontSizePt.' Tf <';
10722 if ($c == 7) { $ret .= $this->aliasNbPgHex; }
10723 else { $ret .= $this->aliasNbPgGpHex; }
10727 if (!$this->_charDefined($this->CurrentFont['cw'], $c)) {
10732 $init = array_search($c, $this->CurrentFont['subsets'][$i]);
10734 if ($this->CurrentFont['subsetfontids'][$i] != $last_fid) {
10735 $ret .= '> Tj /F' . $this->CurrentFont['subsetfontids'][$i] . ' ' . $this->FontSizePt . ' Tf <';
10736 $last_fid = $this->CurrentFont['subsetfontids'][$i];
10741 elseif (count($this->CurrentFont['subsets'][$i]) < 255) {
10742 $n = count($this->CurrentFont['subsets'][$i]);
10743 $this->CurrentFont['subsets'][$i][$n] = $c;
10744 if ($this->CurrentFont['subsetfontids'][$i] != $last_fid) {
10745 $ret .= '> Tj /F' . $this->CurrentFont['subsetfontids'][$i] . ' ' . $this->FontSizePt . ' Tf <';
10746 $last_fid = $this->CurrentFont['subsetfontids'][$i];
10750 } elseif (!isset($this->CurrentFont['subsets'][($i + 1)])) {
10752 $this->CurrentFont['subsets'][($i + 1)] = [0 => 0];
10753 $new_fid = count($this->fonts) + $this->extraFontSubsets + 1;
10754 $this->CurrentFont['subsetfontids'][($i + 1)] = $new_fid;
10755 $this->extraFontSubsets++;
10761 $ret .= ' Tj /F' . $orig_fid . ' ' . $this->FontSizePt . ' Tf <> ';
10766 /* -- CJK-FONTS -- */
10772 if (isset($this->fonts[$fontkey])) {
10773 throw new \Mpdf\MpdfException("Font already added: $family $style");
10775 $i = count($this->fonts) + $this->extraFontSubsets + 1;
10778 $up = -120;
10780 $up = -130;
10783 $this->fonts[$fontkey] = ['i' => $i, 'type' => 'Type0', 'name' => $name, 'up' => $up, 'ut' => 40, 'cw' => $cw, 'CMap' => $CMap, 'registry' => $registry, 'MissingWidth' => 1000, 'desc' => $desc];
10789 if ($this->PDFA || $this->PDFX) {
10790 throw new \Mpdf\MpdfException("Adobe CJK fonts cannot be embedded in mPDF (required for PDFA1-b and PDFX/1-a).");
10793 $this->AddBig5Font();
10795 $this->AddGBFont();
10797 $this->AddSJISFont();
10799 $this->AddUHCFont();
10805 // Add Big5 font with proportional Latin
10807 $name = 'MSungStd-Light-Acro';
10808 $cw = $this->Big5_widths;
10809 $CMap = 'UniCNS-UTF16-H';
10813 'Descent' => -120,
10816 'FontBBox' => '[-160 -249 1015 1071]',
10820 $this->AddCIDFont($family, '', $name, $cw, $CMap, $registry, $desc);
10821 $this->AddCIDFont($family, 'B', $name . ',Bold', $cw, $CMap, $registry, $desc);
10822 $this->AddCIDFont($family, 'I', $name . ',Italic', $cw, $CMap, $registry, $desc);
10823 $this->AddCIDFont($family, 'BI', $name . ',BoldItalic', $cw, $CMap, $registry, $desc);
10828 // Add GB font with proportional Latin
10830 $name = 'STSongStd-Light-Acro';
10831 $cw = $this->GB_widths;
10832 $CMap = 'UniGB-UTF16-H';
10836 'Descent' => -120,
10839 'FontBBox' => '[-25 -254 1000 880]',
10844 $this->AddCIDFont($family, '', $name, $cw, $CMap, $registry, $desc);
10845 $this->AddCIDFont($family, 'B', $name . ',Bold', $cw, $CMap, $registry, $desc);
10846 $this->AddCIDFont($family, 'I', $name . ',Italic', $cw, $CMap, $registry, $desc);
10847 $this->AddCIDFont($family, 'BI', $name . ',BoldItalic', $cw, $CMap, $registry, $desc);
10852 // Add SJIS font with proportional Latin
10854 $name = 'KozMinPro-Regular-Acro';
10855 $cw = $this->SJIS_widths;
10856 $CMap = 'UniJIS-UTF16-H';
10860 'Descent' => -120,
10863 'FontBBox' => '[-195 -272 1110 1075]',
10868 $this->AddCIDFont($family, '', $name, $cw, $CMap, $registry, $desc);
10869 $this->AddCIDFont($family, 'B', $name . ',Bold', $cw, $CMap, $registry, $desc);
10870 $this->AddCIDFont($family, 'I', $name . ',Italic', $cw, $CMap, $registry, $desc);
10871 $this->AddCIDFont($family, 'BI', $name . ',BoldItalic', $cw, $CMap, $registry, $desc);
10876 // Add UHC font with proportional Latin
10878 $name = 'HYSMyeongJoStd-Medium-Acro';
10879 $cw = $this->UHC_widths;
10880 $CMap = 'UniKS-UTF16-H';
10884 'Descent' => -120,
10887 'FontBBox' => '[-28 -148 1001 880]',
10892 $this->AddCIDFont($family, '', $name, $cw, $CMap, $registry, $desc);
10893 $this->AddCIDFont($family, 'B', $name . ',Bold', $cw, $CMap, $registry, $desc);
10894 $this->AddCIDFont($family, 'I', $name . ',Italic', $cw, $CMap, $registry, $desc);
10895 $this->AddCIDFont($family, 'BI', $name . ',BoldItalic', $cw, $CMap, $registry, $desc);
10898 /* -- END CJK-FONTS -- */
10908 function SetDefaultFont($font)
10911 if ($this->PDFA || $this->PDFX) {
10912 if (strtolower($font) == 'ctimes') {
10913 $font = 'serif';
10915 if (strtolower($font) == 'ccourier') {
10916 $font = 'monospace';
10918 if (strtolower($font) == 'chelvetica') {
10919 $font = 'sans-serif';
10922 $font = $this->SetFont($font); // returns substituted font if necessary
10923 $this->default_font = $font;
10924 $this->original_default_font = $font;
10925 if (!$this->watermark_font) {
10926 $this->watermark_font = $font;
10928 $this->defaultCSS['BODY']['FONT-FAMILY'] = $font;
10929 $this->cssManager->CSS['BODY']['FONT-FAMILY'] = $font;
10934 $this->default_font_size = $fontsize;
10935 $this->original_default_font_size = $fontsize;
10936 $this->SetFontSize($fontsize);
10937 $this->defaultCSS['BODY']['FONT-SIZE'] = $fontsize . 'pt';
10938 $this->cssManager->CSS['BODY']['FONT-SIZE'] = $fontsize . 'pt';
10944 $this->defaultCSS['BODY'][strtoupper($prop)] = $val;
10945 $this->cssManager->CSS['BODY'][strtoupper($prop)] = $val;
10951 /* -- OTL -- */
10953 if ($this->directionality != 'rtl') {
10955 $tmp = $this->DeflMargin;
10956 $this->DeflMargin = $this->DefrMargin;
10957 $this->DefrMargin = $tmp;
10958 $this->orig_lMargin = $this->DeflMargin;
10959 $this->orig_rMargin = $this->DefrMargin;
10961 $this->SetMargins($this->DeflMargin, $this->DefrMargin, $this->tMargin);
10963 $this->directionality = 'rtl';
10964 $this->defaultAlign = 'R';
10965 $this->defaultTableAlign = 'R';
10967 /* -- END OTL -- */
10968 $this->directionality = 'ltr';
10969 $this->defaultAlign = 'L';
10970 $this->defaultTableAlign = 'L';
10972 $this->cssManager->CSS['BODY']['DIRECTION'] = $this->directionality;
10975 // Return either a number (factor) - based on current set fontsize (if % or em) - or exact lineheight (with 'mm' after it)
10979 if (preg_match('/^[0-9\.,]*$/', $v) && $v >= 0) {
10984 $tlh = $this->sizeConverter->convert($v, $this->FontSize, $this->FontSize, true);
10989 return $this->normalLineheight;
10995 $desc = $this->CurrentFont['desc'];
11000 if ($this->useFixedNormalLineHeight) {
11001 $lh = $this->normalLineheight;
11003 $lh = ($this->adjustFontDescLineheight * ($desc['Ascent'] - $desc['Descent'] + $desc['Leading']) / 1000);
11005 $lh = $this->normalLineheight;
11010 // Set a (fixed) lineheight to an actual value - either to named fontsize(pts) or default
11014 $FontPt = $this->FontSizePt;
11017 $this->lineheight = $this->_computeLineheight($lh, $fs);
11022 if ($this->shrin_k > 1) {
11023 $k = $this->shrin_k;
11028 $fs = $this->FontSize;
11031 $lh = $this->_getNormalLineheight();
11038 return ($fs * $this->normalLineheight);
11044 $ypos['baseline-shift'] = 0;
11048 if (isset($fontdesc['Ascent']) && $fontdesc['Ascent'] && !$this->useFixedTextBaseline) {
11049 // Fontsize uses font metrics - this method seems to produce results compatible with browsers (except IE9)
11055 } // Default if not set - uses baselineC
11057 $ypos['boxtop'] = (0.5 + $this->baselineC) * $fontsize;
11058 $ypos['boxbottom'] = -(0.5 - $this->baselineC) * $fontsize;
11060 $fontheight = $ypos['boxtop'] - $ypos['boxbottom'];
11062 if ($this->shrin_k > 1) {
11063 $shrin_k = $this->shrin_k;
11070 $lh = $this->_getNormalLineheight($fontdesc);
11076 // Could depend on value for $text_height - a draft CSS value as set above for now
11080 $lineheight = ($fontsize * $this->normalLineheight);
11083 // In general, calculate the "leading" - the difference between the fontheight and the lineheight
11085 // If an inline element has a font-size less than the block element, and the line-height is set as an em or % value
11086 // it will add too much leading below the font and expand the height of the line - so just use the block element exttop/extbottom:
11096 $leading += ($lineheight - $fontheight);
11099 $ypos['extbottom'] = $ypos['boxbottom'] - $leading / 2;
11115 function _setInlineBlockHeights(&$lineBox, &$stackHeight, &$content, &$font, $is_table)
11117 if ($this->shrin_k > 1) {
11118 $shrin_k = $this->shrin_k;
11129 $fontsize = $this->FontSize;
11130 $fontkey = $this->FontFamily . $this->FontStyle;
11131 $fontdesc = $this->fonts[$fontkey]['desc'];
11132 $CSSlineheight = $this->cellLineHeight;
11133 $line_stacking_strategy = $this->cellLineStackingStrategy; // inline-line-height [default] | block-line-height | max-height | grid-height
11134 $line_stacking_shift = $this->cellLineStackingShift; // consider-shifts [default] | disregard-shifts
11136 // FOR BLOCK FONT
11137 $fontsize = $this->blk[$this->blklvl]['InlineProperties']['size'];
11138 $fontkey = $this->blk[$this->blklvl]['InlineProperties']['family'] . $this->blk[$this->blklvl]['InlineProperties']['style'];
11139 $fontdesc = $this->fonts[$fontkey]['desc'];
11140 $CSSlineheight = $this->blk[$this->blklvl]['line_height'];
11141 // inline-line-height | block-line-height | max-height | grid-height
11142 $line_stacking_strategy = (isset($this->blk[$this->blklvl]['line_stacking_strategy']) ? $this->blk[$this->blklvl]['line_stacking_strategy'] : 'inline-line-height');
11143 // consider-shifts | disregard-shifts
11144 $line_stacking_shift = (isset($this->blk[$this->blklvl]['line_stacking_shift']) ? $this->blk[$this->blklvl]['line_stacking_shift'] : 'consider-shifts');
11146 $boxLineHeight = $this->_computeLineheight($CSSlineheight, $fontsize);
11149 // First, set a "strut" using block font at index $lineBox[-1]
11150 $ypos[-1] = $this->_setLineYpos($fontsize, $fontdesc, $CSSlineheight);
11152 // for the block element - always taking the block EXTENDED progression including leading - which may be negative
11153 if ($line_stacking_strategy == 'block-line-height') {
11154 $topy = $ypos[-1]['exttop'];
11155 $bottomy = $ypos[-1]['extbottom'];
11161 // Get text-middle for aligning images/objects
11162 $midpoint = $ypos[-1]['boxtop'] - (($ypos[-1]['boxtop'] - $ypos[-1]['boxbottom']) / 2);
11165 $mta = 0; // Maximum top-aligned
11166 $mba = 0; // Maximum bottom-aligned
11168 if (isset($this->objectbuffer[$k]) && $this->objectbuffer[$k]['type'] == 'listmarker') {
11169 $ypos[$k] = $ypos[-1];
11171 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
11186 } elseif (isset($this->objectbuffer[$k]) && $this->objectbuffer[$k]['type'] == 'dottab') { // mPDF 6 DOTTAB
11187 $fontsize = $font[$k]['size'];
11188 $fontdesc = $font[$k]['curr']['desc'];
11190 $ypos[$k] = $this->_setLineYpos($fontsize, $fontdesc, $lh, $ypos[-1]); // Lineheight=1 fixed
11191 } elseif (isset($this->objectbuffer[$k])) {
11192 $oh = $this->objectbuffer[$k]['OUTER-HEIGHT'];
11193 $va = $this->objectbuffer[$k]['vertical-align'];
11203 if (($midpoint - $oh / 2) < $bottomy) {
11204 $bottomy = $midpoint - $oh / 2;
11207 if (($ypos[-1]['boxtop'] - $oh) < $bottomy) {
11208 $bottomy = $ypos[-1]['boxtop'] - $oh;
11209 $topy = max($topy, $ypos[-1]['boxtop']);
11212 if (($ypos[-1]['boxbottom'] + $oh) > $topy) {
11213 $topy = $ypos[-1]['boxbottom'] + $oh;
11214 $bottomy = min($bottomy, $ypos[-1]['boxbottom']);
11227 $fontsize = $font[$k]['size'];
11228 $fontdesc = $font[$k]['curr']['desc'];
11229 // In future could set CSS line-height from inline elements; for now, use block level:
11230 $ypos[$k] = $this->_setLineYpos($fontsize, $fontdesc, $CSSlineheight, $ypos[-1]);
11232 if (isset($font[$k]['textparam']['text-baseline']) && $font[$k]['textparam']['text-baseline'] != 0) {
11233 $ypos[$k]['baseline-shift'] = $font[$k]['textparam']['text-baseline'];
11238 // $ypos[$k] compared to $ypos[-1] or $ypos[$k-1] using $dominant_baseline and $baseline_table
11240 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
11241 if ($line_stacking_shift == 'disregard-shifts') {
11249 if (($ypos[$k]['boxtop'] + $ypos[$k]['baseline-shift']) > $topy) {
11250 $topy = $ypos[$k]['boxtop'] + $ypos[$k]['baseline-shift'];
11252 if (($ypos[$k]['boxbottom'] + $ypos[$k]['baseline-shift']) < $bottomy) {
11253 $bottomy = $ypos[$k]['boxbottom'] + $ypos[$k]['baseline-shift'];
11257 if ($line_stacking_shift == 'disregard-shifts') {
11265 if (($ypos[$k]['exttop'] + $ypos[$k]['baseline-shift']) > $topy) {
11266 $topy = $ypos[$k]['exttop'] + $ypos[$k]['baseline-shift'];
11268 if (($ypos[$k]['extbottom'] + $ypos[$k]['baseline-shift']) < $bottomy) {
11269 $bottomy = $ypos[$k]['extbottom'] + $ypos[$k]['baseline-shift'];
11275 if (isset($font[$k]['bord']) && $font[$k]['bord']) {
11276 $bordfontsize = $font[$k]['textparam']['bord-decoration']['fontsize'] / $shrin_k;
11277 $bordfontkey = $font[$k]['textparam']['bord-decoration']['fontkey'];
11278 if ($bordfontkey != $fontkey || $bordfontsize != $fontsize || isset($font[$k]['textparam']['bord-decoration']['baseline'])) {
11279 $bordfontdesc = $this->fonts[$bordfontkey]['desc'];
11280 $bordypos[$k] = $this->_setLineYpos($bordfontsize, $bordfontdesc, $CSSlineheight, $ypos[-1]);
11281 if (isset($font[$k]['textparam']['bord-decoration']['baseline']) && $font[$k]['textparam']['bord-decoration']['baseline'] != 0) {
11282 $bordypos[$k]['baseline-shift'] = $font[$k]['textparam']['bord-decoration']['baseline'] / $shrin_k;
11287 if (isset($font[$k]['spanbgcolor']) && $font[$k]['spanbgcolor']) {
11288 $bgfontsize = $font[$k]['textparam']['bg-decoration']['fontsize'] / $shrin_k;
11289 $bgfontkey = $font[$k]['textparam']['bg-decoration']['fontkey'];
11290 if ($bgfontkey != $fontkey || $bgfontsize != $fontsize || isset($font[$k]['textparam']['bg-decoration']['baseline'])) {
11291 $bgfontdesc = $this->fonts[$bgfontkey]['desc'];
11292 $bgypos[$k] = $this->_setLineYpos($bgfontsize, $bgfontdesc, $CSSlineheight, $ypos[-1]);
11293 if (isset($font[$k]['textparam']['bg-decoration']['baseline']) && $font[$k]['textparam']['bg-decoration']['baseline'] != 0) {
11294 $bgypos[$k]['baseline-shift'] = $font[$k]['textparam']['bg-decoration']['baseline'] / $shrin_k;
11303 if ($mta > ($topy - $bottomy)) {
11304 if (($topy - $mta) < $bottomy) {
11305 $bottomy = $topy - $mta;
11308 if ($mba > ($topy - $bottomy)) {
11314 if ($line_stacking_strategy == 'block-line-height') { // fixed height set by block element (whether present or not)
11315 $topy = $ypos[-1]['exttop'];
11316 $bottomy = $ypos[-1]['extbottom'];
11319 $inclusiveHeight = $topy - $bottomy;
11324 if ($line_stacking_strategy == 'block-line-height') { // fixed = extended block progression height of block element
11326 } elseif ($line_stacking_strategy == 'max-height') { // smallest height which includes extended block progression height of block element
11329 } elseif ($line_stacking_strategy == 'grid-height') { // smallest multiple of block element lineheight to include
11335 } else { // 'inline-line-height' = default // smallest height which includes extended block progression height of block element
11340 $diff = $stackHeight - $inclusiveHeight;
11342 $bottomy -= $diff / 2;
11346 $lineBox[-1]['boxtop'] = $topy - $ypos[-1]['boxtop'];
11347 $lineBox[-1]['boxbottom'] = $topy - $ypos[-1]['boxbottom'];
11348 // $lineBox[-1]['exttop'] = $topy - $ypos[-1]['exttop'];
11349 // $lineBox[-1]['extbottom'] = $topy - $ypos[-1]['extbottom'];
11350 $lineBox[-1]['glyphYorigin'] = $topy - $ypos[-1]['glyphYorigin'];
11351 $lineBox[-1]['baseline-shift'] = $ypos[-1]['baseline-shift'];
11353 $midpoint = $lineBox[-1]['boxbottom'] - (($lineBox[-1]['boxbottom'] - $lineBox[-1]['boxtop']) / 2);
11356 if (isset($this->objectbuffer[$k])) {
11357 $oh = $this->objectbuffer[$k]['OUTER-HEIGHT'];
11359 if ($this->objectbuffer[$k]['type'] == 'listmarker') {
11361 } elseif ($this->objectbuffer[$k]['type'] == 'dottab') { // mPDF 6 DOTTAB
11362 $oh = $font[$k]['size']; // == $this->objectbuffer[$k]['fontsize']/Mpdf::SCALE;
11363 $lineBox[$k]['boxtop'] = $topy - $ypos[$k]['boxtop'];
11364 $lineBox[$k]['boxbottom'] = $topy - $ypos[$k]['boxbottom'];
11365 $lineBox[$k]['glyphYorigin'] = $topy - $ypos[$k]['glyphYorigin'];
11366 $lineBox[$k]['baseline-shift'] = 0;
11369 $va = $this->objectbuffer[$k]['vertical-align']; // = $objattr['vertical-align'] = set as M,T,B,S
11372 $lineBox[$k]['top'] = $lineBox[-1]['glyphYorigin'] - $oh;
11374 $lineBox[$k]['top'] = $midpoint - $oh / 2;
11376 $lineBox[$k]['top'] = $lineBox[-1]['boxtop'];
11378 $lineBox[$k]['top'] = $lineBox[-1]['boxbottom'] - $oh;
11382 $lineBox[$k]['top'] = $stackHeight - $oh;
11385 $lineBox[$k]['boxtop'] = $topy - $ypos[$k]['boxtop'];
11386 $lineBox[$k]['boxbottom'] = $topy - $ypos[$k]['boxbottom'];
11387 // $lineBox[$k]['exttop'] = $topy - $ypos[$k]['exttop'];
11388 // $lineBox[$k]['extbottom'] = $topy - $ypos[$k]['extbottom'];
11389 $lineBox[$k]['glyphYorigin'] = $topy - $ypos[$k]['glyphYorigin'];
11390 $lineBox[$k]['baseline-shift'] = $ypos[$k]['baseline-shift'];
11392 $lineBox[$k]['border-boxtop'] = $topy - $bordypos[$k]['boxtop'];
11393 $lineBox[$k]['border-boxbottom'] = $topy - $bordypos[$k]['boxbottom'];
11394 $lineBox[$k]['border-baseline-shift'] = $bordypos[$k]['baseline-shift'];
11397 $lineBox[$k]['background-boxtop'] = $topy - $bgypos[$k]['boxtop'];
11398 $lineBox[$k]['background-boxbottom'] = $topy - $bgypos[$k]['boxbottom'];
11399 $lineBox[$k]['background-baseline-shift'] = $bgypos[$k]['baseline-shift'];
11433 $this->basepath = $currpath;
11434 $this->basepathIsLocal = true;
11442 $this->basepath = dirname($str) . "/"; // returns e.g. e.g. http://www.google.com/dir1/dir2/dir3/
11443 $this->basepath = str_replace("\\", "/", $this->basepath); // If on Windows
11444 $tr = parse_url($this->basepath);
11446 $this->basepathIsLocal = true;
11448 $this->basepathIsLocal = false;
11454 // When parsing CSS need to pass temporary basepath - so links are relative to current stylesheet
11456 $basepath = $this->basepath;
11477 $pattern = sprintf('@^(?!%s)[a-z0-9\.\-+]+:.*@i', implode('|', $wrappers));
11485 $maxbacktrack = substr_count($basepath, "/") - 3;
11528 $num = $this->page;
11531 $type = $this->defaultPageNumStyle; // set default Page Number Style
11537 foreach ($this->PageNumSubstitutions as $psarr) {
11543 $offset = $psarr['reset'] - 1;
11545 $ppgno = $num - $psarr['from'] + 1 + $offset;
11565 $ppgno = $this->_getStyledNumber($ppgno, $type);
11568 $ppgno = $this->pagenumPrefix . $ppgno . $this->pagenumSuffix;
11577 $num = $this->page;
11580 $type = $this->defaultPageNumStyle; // set default Page Number Style
11582 $ppgend = count($this->pages) + 1;
11586 foreach ($this->PageNumSubstitutions as $psarr) {
11590 $offset = $psarr['reset'] - 1;
11593 $ppgend = count($this->pages) + 1 + $offset;
11616 $ppgno = $ppgend - $ppgstart + $offset;
11617 $ppgno = $this->_getStyledNumber($ppgno, $type);
11620 $ppgno = $this->pagenumPrefix . $ppgno . $this->pagenumSuffix;
11631 $checkfont = true; // Using list - font is set, so check if character is available
11634 $checkfont = false; // For pagenumbers - font is not set, so no check
11645 if ($lowertype == 'upper-latin' || $lowertype == 'upper-alpha' || $type == 'A') {
11647 $ppgno = $decToAlpha->convert($ppgno, true);
11649 } elseif ($lowertype == 'lower-latin' || $lowertype == 'lower-alpha' || $type == 'a') {
11651 $ppgno = $decToAlpha->convert($ppgno, false);
11653 } elseif ($lowertype == 'upper-roman' || $type == 'I') {
11655 $ppgno = $decToRoman->convert($ppgno, true);
11657 } elseif ($lowertype == 'lower-roman' || $type == 'i') {
11659 $ppgno = $decToRoman->convert($ppgno, false);
11663 $ppgno = $decToHebrew->convert($ppgno, $reverse);
11665 } elseif (preg_match('/(arabic-indic|bengali|devanagari|gujarati|gurmukhi|kannada|malayalam|oriya|persian|tamil|telugu|thai|urdu|cambodian|khmer|lao|myanmar)/i', $lowertype, $m)) {
11667 $cp = $decToOther->getCodePage($m[1]);
11668 $ppgno = $decToOther->convert($ppgno, $cp, $checkfont);
11670 } elseif ($lowertype == 'cjk-decimal') {
11672 $ppgno = $decToCjk->convert($ppgno);
11684 $num = $this->page;
11687 $type = $this->defaultPageNumStyle; // set default Page Number Style
11693 foreach ($this->PageNumSubstitutions as $psarr) {
11697 $offset = $psarr['reset'] - 1;
11699 $ppgno = $num - $psarr['from'] + 1 + $offset;
11726 $this->docTemplateStart = $this->page;
11733 $this->cMarginL = 0;
11734 $this->cMarginR = 0;
11737 if (($this->mirrorMargins && ($this->page % 2 == 0) && $this->HTMLHeaderE) || ($this->mirrorMargins && ($this->page % 2 == 1) && $this->HTMLHeader) || (!$this->mirrorMargins && $this->HTMLHeader)) {
11738 $this->writeHTMLHeaders();
11743 /* -- TABLES -- */
11747 $table = &$this->table[1][1];
11751 $firstrow = count($table['cells']) - $table['footernrows'];
11752 $lastrow = count($table['cells']) - 1;
11755 $lastrow = $table['headernrows'] - 1;
11758 if ($this->debug) {
11774 if ($this->table_rotate) {
11775 $this->y += ($adv);
11777 $this->DivLn($adv, $this->blklvl, true);
11782 $topy = $content[$firstrow][0]['y'] - $this->y;
11785 $y = $this->y;
11787 /* -- COLUMNS -- */
11789 if ($this->ColActive) {
11791 if ($this->blklvl > 0) {
11792 $firstblockfill = $this->GetFirstBlockFill();
11793 if ($firstblockfill && $this->blklvl >= $firstblockfill) {
11795 $bak_x = $this->x;
11796 $this->DivLn($divh, -3, false);
11798 $bcor = $this->blk[$this->blklvl]['bgcolorarray'];
11799 $this->SetFColor($bcor);
11800 $this->x = $bak_x;
11804 /* -- END COLUMNS -- */
11809 $y = Arrays::get($tablehf, 'y', null) - $topy;
11810 $this->y = $y;
11813 if (($this->mirrorMargins) && ($tablestartpage == 'ODD') && (($this->page) % 2 == 0)) { // EVEN
11814 $x = $x + $this->MarginCorrection;
11815 } elseif (($this->mirrorMargins) && ($tablestartpage == 'EVEN') && (($this->page) % 2 == 1)) { // ODD
11816 $x = $x + $this->MarginCorrection;
11818 /* -- COLUMNS -- */
11820 if ($this->ColActive) {
11821 if ($this->directionality == 'rtl') { // *OTL*
11822 $x -= ($this->CurrCol - $tablestartcolumn) * ($this->ColWidth + $this->ColGap); // *OTL*
11825 $x += ($this->CurrCol - $tablestartcolumn) * ($this->ColWidth + $this->ColGap);
11828 /* -- END COLUMNS -- */
11835 if ($this->iterationCounter) {
11837 if (!is_array($t[0]) && preg_match('/{iteration ([a-zA-Z0-9_]+)}/', $t[0], $m)) {
11839 if (!isset($this->$vname)) {
11840 $this->$vname = 1;
11842 $this->$vname++;
11844 $tablehf['textbuffer'][$k][0] = preg_replace('/{iteration ' . $m[1] . '}/', $this->$vname, $tablehf['textbuffer'][$k][0]);
11858 $this->tabletheadjustfinished = true;
11864 $this->cellTextAlign = $align;
11866 $this->cellLineHeight = Arrays::get($tablehf, 'cellLineHeight', null);
11867 $this->cellLineStackingStrategy = Arrays::get($tablehf, 'cellLineStackingStrategy', null);
11868 $this->cellLineStackingShift = Arrays::get($tablehf, 'cellLineStackingShift', null);
11870 $this->x = $x;
11872 if ($this->ColActive) {
11874 $tablefill = isset($table['bgcolor'][-1]) ? $table['bgcolor'][-1] : 0;
11876 $color = $this->colorConverter->convert($tablefill, $this->PDFAXwarnings);
11896 $this->SetFColor($color);
11897 $this->Rect($x - $xadj, $y - $yadj, $w + $wadj, $h + $hadj, 'F');
11915 $this->y += ($h - $mih) / 2;
11917 $this->y += $h - $mih;
11931 $color = $this->colorConverter->convert($fill, $this->PDFAXwarnings);
11934 if ($this->ColActive) {
11935 $this->SetFColor($color);
11936 $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');
11938 $this->tableBackgrounds[$level * 9 + $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];
11941 if ($this->ColActive) {
11942 $this->SetFColor($color);
11943 $this->Rect($x, $y, $w, $h, 'F');
11945 $this->tableBackgrounds[$level * 9 + $leveladj][] = ['gradient' => false, 'x' => $x, 'y' => $y, 'w' => $w, 'h' => $h, 'col' => $color];
11952 /* -- BACKGROUNDS -- */
11954 $g = $this->gradient->parseBackgroundGradient($tablehf['gradient']);
11959 $pw = $w - $table['border_spacing_H'];
11960 $ph = $h - $table['border_spacing_V'];
11967 if ($this->ColActive) {
11968 $this->gradient->Gradient($px, $py, $pw, $ph, $g['type'], $g['stops'], $g['colorspace'], $g['coords'], $g['extend']);
11970 $this->tableBackgrounds[$level * 9 + 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' => ''];
11975 if (isset($tablehf['background-image']) && $paintcell) {
11976 if ($tablehf['background-image']['gradient'] && preg_match('/(-moz-)*(repeating-)*(linear|radial)-gradient/', $tablehf['background-image']['gradient'])) {
11977 $g = $this->gradient->parseMozGradient($tablehf['background-image']['gradient']);
11982 $pw = $w - $table['border_spacing_H'];
11983 $ph = $h - $table['border_spacing_V'];
11990 if ($this->ColActive) {
11991 $this->gradient->Gradient($px, $py, $pw, $ph, $g['type'], $g['stops'], $g['colorspace'], $g['coords'], $g['extend']);
11993 $this->tableBackgrounds[$level * 9 + 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' => ''];
11996 } elseif ($tablehf['background-image']['image_id']) { // Background pattern
11997 $n = count($this->patterns) + 1;
12001 $pw = $w - $table['border_spacing_H'];
12002 $ph = $h - $table['border_spacing_V'];
12009 if ($this->ColActive) {
12010 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']);
12011 $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']];
12012 if ($tablehf['background-image']['opacity'] > 0 && $tablehf['background-image']['opacity'] < 1) {
12013 $opac = $this->SetAlpha($tablehf['background-image']['opacity'], 'Normal', true);
12017 $this->writer->write(sprintf('q /Pattern cs /P%d scn %s %.3F %.3F %.3F %.3F re f Q', $n, $opac, $px * Mpdf::SCALE, ($this->h - $py) * Mpdf::SCALE, $pw * Mpdf::SCALE, -$ph * Mpdf::SCALE));
12019 $this->tableBackgrounds[$level * 9 + 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']];
12023 /* -- END BACKGROUNDS -- */
12027 $this->_tableRect($x + ($table['border_spacing_H'] / 2) + ($border_details['L']['w'] / 2), $y + ($table['border_spacing_V'] / 2) + ($border_details['T']['w'] / 2), $w - $table['border_spacing_H'] - ($border_details['L']['w'] / 2) - ($border_details['R']['w'] / 2), $h - $table['border_spacing_V'] - ($border_details['T']['w'] / 2) - ($border_details['B']['w'] / 2), $border, $border_details, false, $table['borders_separate']);
12029 $this->_tableRect($x, $y, $w, $h, $border, $border_details, true, $table['borders_separate']); // true causes buffer
12034 if ($horf == 'F' && preg_match('/{colsum([0-9]*)[_]*}/', $textbuffer[0][0], $m)) {
12035 $rep = sprintf("%01." . intval($m[1]) . "f", $this->colsums[$colctr - 1]);
12036 $textbuffer[0][0] = preg_replace('/{colsum[0-9_]*}/', $rep, $textbuffer[0][0]);
12040 $cellPtSize = $textbuffer[0][11] / $this->shrin_k;
12042 $cellPtSize = $this->default_font_size;
12045 $opx = $this->x;
12046 $opy = $this->y;
12049 // Only allow 45 - 90 degrees (when bottom-aligned) or -90
12057 $angle = -90;
12062 $this->x += ($w) + ($offset) - ($cellFontHeight / 3) - ($padding['R'] + $border_details['R']['w']);
12064 $this->x += ($w / 2) + ($offset);
12066 $this->x += ($offset) + ($cellFontHeight / 3) + ($padding['L'] + $border_details['L']['w']);
12075 $this->y -= ($h - $mih) / 2; // Undo what was added earlier VERTICAL ALIGN
12077 $this->y += (($h - $mih) / 2) + ($padding['T'] + $border_details['T']['w']) + ($mih - ($padding['T'] + $border_details['T']['w'] + $border_details['B']['w'] + $padding['B']));
12079 $this->y += (($h - $mih) / 2) + ($padding['T'] + $border_details['T']['w']);
12082 $this->y -= $h - $mih; // Undo what was added earlier VERTICAL ALIGN
12084 $this->y += $h - ($border_details['B']['w'] + $padding['B']);
12086 $this->y += $h - $mih + ($padding['T'] + $border_details['T']['w']);
12090 $this->y += $mih - ($border_details['B']['w'] + $padding['B']);
12092 $this->y += ($padding['T'] + $border_details['T']['w']);
12096 $this->Rotate($angle, $this->x, $this->y);
12097 $s_fs = $this->FontSizePt;
12098 $s_f = $this->FontFamily;
12099 $s_st = $this->FontStyle;
12100 if (!empty($textbuffer[0][3])) { // Font Color
12102 $this->SetTColor($cor);
12104 $this->SetFont($textbuffer[0][4], $textbuffer[0][2], $cellPtSize, true, true);
12106 $this->magic_reverse_dir($str, $this->directionality, $textbuffer[0][18]);
12107 $this->Text($this->x, $this->y, $str, $textbuffer[0][18], $textbuffer[0][8]); // textvar
12108 $this->Rotate(0);
12109 $this->SetFont($s_f, $s_st, $s_fs, true, true);
12110 $this->SetTColor(0);
12111 $this->x = $opx;
12112 $this->y = $opy;
12124 $this->divwidth = $w - ($wadj);
12125 $this->x += $xadj;
12126 $this->y += $yadj;
12127 $this->printbuffer($textbuffer, '', true, false, $direction);
12132 /* -- BACKGROUNDS -- */
12133 if (!$this->ColActive) {
12135 $g = $this->gradient->parseBackgroundGradient($content[$i][0]['trgradients']);
12140 $gw = $table['w'] - ($table['max_cell_border_width']['L'] / 2) - ($table['max_cell_border_width']['R'] / 2) - $table['margin']['L'] - $table['margin']['R'];
12142 $gw -= ($table['padding']['L'] + $table['border_details']['L']['w'] + $table['padding']['R'] + $table['border_details']['R']['w'] + $table['border_spacing_H']);
12145 $clw = $w - $table['border_spacing_H'];
12146 $clh = $h - $table['border_spacing_V'];
12148 $s = $this->_setClippingPath($clx, $cly, $clw, $clh); // mPDF 6
12149 $this->tableBackgrounds[$level * 9 + 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];
12151 $this->tableBackgrounds[$level * 9 + 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' => ''];
12156 if (isset($content[$i][0]['trbackground-images']) && ($colctr == 1 || $table['borders_separate'])) {
12157 if ($content[$i][0]['trbackground-images']['gradient'] && preg_match('/(-moz-)*(repeating-)*(linear|radial)-gradient/', $content[$i][0]['trbackground-images']['gradient'])) {
12158 $g = $this->gradient->parseMozGradient($content[$i][0]['trbackground-images']['gradient']);
12163 $gw = $table['w'] - ($table['max_cell_border_width']['L'] / 2) - ($table['max_cell_border_width']['R'] / 2) - $table['margin']['L'] - $table['margin']['R'];
12165 $gw -= ($table['padding']['L'] + $table['border_details']['L']['w'] + $table['padding']['R'] + $table['border_details']['R']['w'] + $table['border_spacing_H']);
12168 $clw = $w - $table['border_spacing_H'];
12169 $clh = $h - $table['border_spacing_V'];
12171 $s = $this->_setClippingPath($clx, $cly, $clw, $clh); // mPDF 6
12172 $this->tableBackgrounds[$level * 9 + 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];
12174 $this->tableBackgrounds[$level * 9 + 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' => ''];
12178 $image_id = $content[$i][0]['trbackground-images']['image_id'];
12179 $orig_w = $content[$i][0]['trbackground-images']['orig_w'];
12180 $orig_h = $content[$i][0]['trbackground-images']['orig_h'];
12181 $x_pos = $content[$i][0]['trbackground-images']['x_pos'];
12182 $y_pos = $content[$i][0]['trbackground-images']['y_pos'];
12183 $x_repeat = $content[$i][0]['trbackground-images']['x_repeat'];
12184 $y_repeat = $content[$i][0]['trbackground-images']['y_repeat'];
12185 $resize = $content[$i][0]['trbackground-images']['resize'];
12186 $opacity = $content[$i][0]['trbackground-images']['opacity'];
12187 $itype = $content[$i][0]['trbackground-images']['itype'];
12193 $gw = $table['w'] - ($table['max_cell_border_width']['L'] / 2) - ($table['max_cell_border_width']['R'] / 2) - $table['margin']['L'] - $table['margin']['R'];
12195 $gw -= ($table['padding']['L'] + $table['border_details']['L']['w'] + $table['padding']['R'] + $table['border_details']['R']['w'] + $table['border_spacing_H']);
12198 $clw = $w - $table['border_spacing_H'];
12199 $clh = $h - $table['border_spacing_V'];
12201 $s = $this->_setClippingPath($clx, $cly, $clw, $clh); // mPDF 6
12202 $this->tableBackgrounds[$level * 9 + 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];
12204 $this->tableBackgrounds[$level * 9 + 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];
12209 /* -- END BACKGROUNDS -- */
12211 // TABLE BORDER - if separate OR collapsed and only table border
12212 if (($table['borders_separate'] || ($this->simpleTables && !$table['simple']['border'])) && $table['border']) {
12224 $tby -= $halfspaceT + ($table['border_details']['T']['w'] / 2);
12226 $this->setBorder($tab_bord, Border::TOP);
12231 $this->setBorder($tab_bord, Border::BOTTOM);
12235 $tbx -= $halfspaceL + ($table['border_details']['L']['w'] / 2);
12237 $this->setBorder($tab_bord, Border::LEFT);
12242 $this->setBorder($tab_bord, Border::RIGHT);
12245 $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']);
12248 $this->y = $y + $h; // Update y coordinate
12251 $this->colsums = [];
12255 /* -- END TABLES -- */
12263 if ($this->setAutoTopMargin) {
12267 $height = $this->_getHtmlHeight($Hhtml);
12272 if ($this->setAutoTopMargin) {
12273 $height = $this->_getHtmlHeight($Hhtml);
12285 $this->HTMLHeaderE = [];
12286 $this->HTMLHeaderE['html'] = $Hhtml;
12287 $this->HTMLHeaderE['h'] = $height;
12289 $this->HTMLHeaderE = '';
12293 $this->HTMLHeader = [];
12294 $this->HTMLHeader['html'] = $Hhtml;
12295 $this->HTMLHeader['h'] = $height;
12297 $this->HTMLHeader = '';
12301 if (!$this->mirrorMargins && $OE == 'E') {
12308 if ($this->setAutoTopMargin == 'pad') {
12309 $this->tMargin = $this->margin_header + $height + $this->orig_tMargin;
12310 if (isset($this->saveHTMLHeader[$this->page][$OE]['mt'])) {
12311 $this->saveHTMLHeader[$this->page][$OE]['mt'] = $this->tMargin;
12313 } elseif ($this->setAutoTopMargin == 'stretch') {
12314 $this->tMargin = max($this->orig_tMargin, $this->margin_header + $height + $this->autoMarginPadding);
12315 if (isset($this->saveHTMLHeader[$this->page][$OE]['mt'])) {
12316 $this->saveHTMLHeader[$this->page][$OE]['mt'] = $this->tMargin;
12319 if ($write && $this->state != 0 && (($this->mirrorMargins && $OE == 'E' && ($this->page) % 2 == 0) || ($this->mirrorMargins && $OE != 'E' && ($this->page) % 2 == 1) || !$this->mirrorMargins)) {
12320 $this->writeHTMLHeaders();
12329 if ($this->setAutoBottomMargin) {
12333 $height = $this->_getHtmlHeight($Fhtml);
12338 if ($this->setAutoBottomMargin) {
12339 $height = $this->_getHtmlHeight($Fhtml);
12351 $this->HTMLFooterE = [];
12352 $this->HTMLFooterE['html'] = $Fhtml;
12353 $this->HTMLFooterE['h'] = $height;
12355 $this->HTMLFooterE = '';
12359 $this->HTMLFooter = [];
12360 $this->HTMLFooter['html'] = $Fhtml;
12361 $this->HTMLFooter['h'] = $height;
12363 $this->HTMLFooter = '';
12367 if (!$this->mirrorMargins && $OE == 'E') {
12375 if ($this->setAutoBottomMargin == 'pad') {
12376 $this->bMargin = $this->margin_footer + $height + $this->orig_bMargin;
12377 $this->PageBreakTrigger = $this->h - $this->bMargin;
12378 if (isset($this->saveHTMLHeader[$this->page][$OE]['mb'])) {
12379 $this->saveHTMLHeader[$this->page][$OE]['mb'] = $this->bMargin;
12381 } elseif ($this->setAutoBottomMargin == 'stretch') {
12382 $this->bMargin = max($this->orig_bMargin, $this->margin_footer + $height + $this->autoMarginPadding);
12383 $this->PageBreakTrigger = $this->h - $this->bMargin;
12384 if (isset($this->saveHTMLHeader[$this->page][$OE]['mb'])) {
12385 $this->saveHTMLHeader[$this->page][$OE]['mb'] = $this->bMargin;
12392 $save_state = $this->state;
12393 if ($this->state == 0) {
12394 $this->AddPage($this->CurOrientation);
12396 $this->state = 2;
12397 $this->Reset();
12398 $this->pageoutput[$this->page] = [];
12399 $save_x = $this->x;
12400 $save_y = $this->y;
12401 $this->x = $this->lMargin;
12402 $this->y = $this->margin_header;
12405 $pnstr = $this->pagenumPrefix . $this->docPageNum($this->page) . $this->pagenumSuffix;
12406 $pntstr = $this->nbpgPrefix . $this->docPageNumTotal($this->page) . $this->nbpgSuffix;
12407 $nb = $this->page;
12408 $html = $this->aliasReplace($html, $pnstr, $pntstr, $nb);
12410 $this->HTMLheaderPageLinks = [];
12411 $this->HTMLheaderPageAnnots = [];
12412 $this->HTMLheaderPageForms = [];
12413 $savepb = $this->pageBackgrounds;
12414 $this->writingHTMLheader = true;
12415 $this->WriteHTML($html, HTMLParserMode::HTML_HEADER_BUFFER);
12416 $this->writingHTMLheader = false;
12417 $h = ($this->y - $this->margin_header);
12418 $this->Reset();
12420 // mPDF 5.7.2 - Clear in case Float used in Header/Footer
12421 $this->blk[0]['blockContext'] = 0;
12422 $this->blk[0]['float_endpos'] = 0;
12424 $this->pageoutput[$this->page] = [];
12425 $this->headerbuffer = '';
12426 $this->pageBackgrounds = $savepb;
12427 $this->x = $save_x;
12428 $this->y = $save_y;
12429 $this->state = $save_state;
12432 unset($this->pages[1]);
12433 $this->page = 0;
12442 if ($this->mirrorMargins && ($this->page) % 2 == 0) {
12449 $this->saveHTMLHeader[$this->page][$OE]['html'] = $this->HTMLHeaderE['html'];
12451 $this->saveHTMLHeader[$this->page][$OE]['html'] = $this->HTMLHeader['html'];
12454 if ($this->forcePortraitHeaders && $this->CurOrientation == 'L' && $this->CurOrientation != $this->DefOrientation) {
12455 $this->saveHTMLHeader[$this->page][$OE]['rotate'] = true;
12456 $this->saveHTMLHeader[$this->page][$OE]['ml'] = $this->tMargin;
12457 $this->saveHTMLHeader[$this->page][$OE]['mr'] = $this->bMargin;
12458 $this->saveHTMLHeader[$this->page][$OE]['mh'] = $this->margin_header;
12459 $this->saveHTMLHeader[$this->page][$OE]['mf'] = $this->margin_footer;
12460 $this->saveHTMLHeader[$this->page][$OE]['pw'] = $this->h;
12461 $this->saveHTMLHeader[$this->page][$OE]['ph'] = $this->w;
12463 $this->saveHTMLHeader[$this->page][$OE]['ml'] = $this->lMargin;
12464 $this->saveHTMLHeader[$this->page][$OE]['mr'] = $this->rMargin;
12465 $this->saveHTMLHeader[$this->page][$OE]['mh'] = $this->margin_header;
12466 $this->saveHTMLHeader[$this->page][$OE]['mf'] = $this->margin_footer;
12467 $this->saveHTMLHeader[$this->page][$OE]['pw'] = $this->w;
12468 $this->saveHTMLHeader[$this->page][$OE]['ph'] = $this->h;
12475 if ($this->mirrorMargins && ($this->page) % 2 == 0) {
12482 $this->saveHTMLFooter[$this->page][$OE]['html'] = $this->HTMLFooterE['html'];
12484 $this->saveHTMLFooter[$this->page][$OE]['html'] = $this->HTMLFooter['html'];
12487 if ($this->forcePortraitHeaders && $this->CurOrientation == 'L' && $this->CurOrientation != $this->DefOrientation) {
12488 $this->saveHTMLFooter[$this->page][$OE]['rotate'] = true;
12489 $this->saveHTMLFooter[$this->page][$OE]['ml'] = $this->tMargin;
12490 $this->saveHTMLFooter[$this->page][$OE]['mr'] = $this->bMargin;
12491 $this->saveHTMLFooter[$this->page][$OE]['mt'] = $this->rMargin;
12492 $this->saveHTMLFooter[$this->page][$OE]['mb'] = $this->lMargin;
12493 $this->saveHTMLFooter[$this->page][$OE]['mh'] = $this->margin_header;
12494 $this->saveHTMLFooter[$this->page][$OE]['mf'] = $this->margin_footer;
12495 $this->saveHTMLFooter[$this->page][$OE]['pw'] = $this->h;
12496 $this->saveHTMLFooter[$this->page][$OE]['ph'] = $this->w;
12498 $this->saveHTMLFooter[$this->page][$OE]['ml'] = $this->lMargin;
12499 $this->saveHTMLFooter[$this->page][$OE]['mr'] = $this->rMargin;
12500 $this->saveHTMLFooter[$this->page][$OE]['mt'] = $this->tMargin;
12501 $this->saveHTMLFooter[$this->page][$OE]['mb'] = $this->bMargin;
12502 $this->saveHTMLFooter[$this->page][$OE]['mh'] = $this->margin_header;
12503 $this->saveHTMLFooter[$this->page][$OE]['mf'] = $this->margin_footer;
12504 $this->saveHTMLFooter[$this->page][$OE]['pw'] = $this->w;
12505 $this->saveHTMLFooter[$this->page][$OE]['ph'] = $this->h;
12513 $l = mb_strlen($cl, 'UTF-8');
12514 $c = mb_strlen($cc, 'UTF-8');
12515 $r = mb_strlen($cr, 'UTF-8');
12526 // Create an HTML header/footer from array (non-HTML header/footer)
12533 list($lw, $cw, $rw) = $this->_shareHeaderFooterWidth($lContent, $cContent, $rContent);
12537 $vpadding = '0 0 ' . $this->header_line_spacing . 'em 0';
12540 $vpadding = '' . $this->footer_line_spacing . 'em 0 0 0';
12543 if ($this->directionality == 'rtl') { // table columns get reversed so need different text-alignment
12551 $html = '<table width="100%" style="border-collapse: collapse; margin: 0; vertical-align: ' . $valign . '; color: #000000; ';
12554 $html .= ' border-' . $valign . ': 0.1mm solid #000000;';
12559 $html .= '<td width="' . $lw . '%" style="padding: ' . $vpadding . '; text-align: ' . $talignL . '; ';
12561 if (isset($arr['L']['font-family'])) {
12562 $html .= ' font-family: ' . $arr['L']['font-family'] . ';';
12569 if (isset($arr['L']['font-size'])) {
12570 $html .= ' font-size: ' . $arr['L']['font-size'] . 'pt;';
12573 if (isset($arr['L']['font-style'])) {
12574 if ($arr['L']['font-style'] == 'B' || $arr['L']['font-style'] == 'BI') {
12575 $html .= ' font-weight: bold;';
12577 if ($arr['L']['font-style'] == 'I' || $arr['L']['font-style'] == 'BI') {
12578 $html .= ' font-style: italic;';
12583 $html .= '<td width="' . $cw . '%" style="padding: ' . $vpadding . '; text-align: center; ';
12585 if (isset($arr['C']['font-family'])) {
12586 $html .= ' font-family: ' . $arr['C']['font-family'] . ';';
12593 if (isset($arr['C']['font-size'])) {
12594 $html .= ' font-size: ' . $arr['C']['font-size'] . 'pt;';
12597 if (isset($arr['C']['font-style'])) {
12598 if ($arr['C']['font-style'] == 'B' || $arr['C']['font-style'] == 'BI') {
12599 $html .= ' font-weight: bold;';
12601 if ($arr['C']['font-style'] == 'I' || $arr['C']['font-style'] == 'BI') {
12602 $html .= ' font-style: italic;';
12607 $html .= '<td width="' . $rw . '%" style="padding: ' . $vpadding . '; text-align: ' . $talignR . '; ';
12609 if (isset($arr['R']['font-family'])) {
12610 $html .= ' font-family: ' . $arr['R']['font-family'] . ';';
12617 if (isset($arr['R']['font-size'])) {
12618 $html .= ' font-size: ' . $arr['R']['font-size'] . 'pt;';
12621 if (isset($arr['R']['font-style'])) {
12622 if ($arr['R']['font-style'] == 'B' || $arr['R']['font-style'] == 'BI') {
12623 $html .= ' font-weight: bold;';
12625 if ($arr['R']['font-style'] == 'I' || $arr['R']['font-style'] == 'BI') {
12626 $html .= ' font-style: italic;';
12641 $html = $this->_createHTMLheaderFooter($arr, 'H');
12643 $this->pageHTMLheaders[$name]['html'] = $html;
12644 $this->pageHTMLheaders[$name]['h'] = $this->_getHtmlHeight($html);
12652 $html = $this->_createHTMLheaderFooter($arr, 'F');
12654 $this->pageHTMLfooters[$name]['html'] = $html;
12655 $this->pageHTMLfooters[$name]['h'] = $this->_getHtmlHeight($html);
12663 $this->SetHTMLHeader($this->pageHTMLheaders[$name], $side, $write);
12671 $this->SetHTMLFooter($this->pageHTMLfooters[$name], $side);
12680 $this->pageHTMLheaders[$name]['html'] = $html;
12681 $this->pageHTMLheaders[$name]['h'] = $this->_getHtmlHeight($html);
12690 $this->pageHTMLfooters[$name]['html'] = $html;
12691 $this->pageHTMLfooters[$name]['h'] = $this->_getHtmlHeight($html);
12699 $this->SetHTMLHeader($this->pageHTMLheaders[$name], $side, $write);
12707 $this->SetHTMLFooter($this->pageHTMLfooters[$name], $side);
12726 list($lw, $cw, $rw) = $this->_shareHeaderFooterWidth($hdet[0], $hdet[1], $hdet[2]);
12727 $oddhtml = '<table width="100%" style="border-collapse: collapse; margin: 0; vertical-align: bottom; color: #000000; ';
12729 if ($this->defaultheaderfontsize) {
12730 $oddhtml .= ' font-size: ' . $this->defaultheaderfontsize . 'pt;';
12733 if ($this->defaultheaderfontstyle) {
12735 if ($this->defaultheaderfontstyle == 'B' || $this->defaultheaderfontstyle == 'BI') {
12736 $oddhtml .= ' font-weight: bold;';
12739 if ($this->defaultheaderfontstyle == 'I' || $this->defaultheaderfontstyle == 'BI') {
12740 $oddhtml .= ' font-style: italic;';
12744 if ($this->defaultheaderline) {
12745 $oddhtml .= ' border-bottom: 0.1mm solid #000000;';
12750 $oddhtml .= '<td width="' . $lw . '%" style="padding: 0 0 ' . $this->header_line_spacing . 'em 0; text-align: left; ">' . $hdet[0] . '</td>';
12751 $oddhtml .= '<td width="' . $cw . '%" style="padding: 0 0 ' . $this->header_line_spacing . 'em 0; text-align: center; ">' . $hdet[1] . '</td>';
12752 $oddhtml .= '<td width="' . $rw . '%" style="padding: 0 0 ' . $this->header_line_spacing . 'em 0; text-align: right; ">' . $hdet[2] . '</td>';
12755 $evenhtml = '<table width="100%" style="border-collapse: collapse; margin: 0; vertical-align: bottom; color: #000000; ';
12757 if ($this->defaultheaderfontsize) {
12758 $evenhtml .= ' font-size: ' . $this->defaultheaderfontsize . 'pt;';
12761 if ($this->defaultheaderfontstyle) {
12762 if ($this->defaultheaderfontstyle == 'B' || $this->defaultheaderfontstyle == 'BI') {
12763 $evenhtml .= ' font-weight: bold;';
12765 if ($this->defaultheaderfontstyle == 'I' || $this->defaultheaderfontstyle == 'BI') {
12766 $evenhtml .= ' font-style: italic;';
12770 if ($this->defaultheaderline) {
12771 $evenhtml .= ' border-bottom: 0.1mm solid #000000;';
12776 $evenhtml .= '<td width="' . $rw . '%" style="padding: 0 0 ' . $this->header_line_spacing . 'em 0; text-align: left; ">' . $hdet[2] . '</td>';
12777 $evenhtml .= '<td width="' . $cw . '%" style="padding: 0 0 ' . $this->header_line_spacing . 'em 0; text-align: center; ">' . $hdet[1] . '</td>';
12778 $evenhtml .= '<td width="' . $lw . '%" style="padding: 0 0 ' . $this->header_line_spacing . 'em 0; text-align: right; ">' . $hdet[0] . '</td>';
12785 if ($this->defaultheaderfontsize) {
12786 $oddhtml .= ' font-size: ' . $this->defaultheaderfontsize . 'pt;';
12789 if ($this->defaultheaderfontstyle) {
12791 if ($this->defaultheaderfontstyle == 'B' || $this->defaultheaderfontstyle == 'BI') {
12792 $oddhtml .= ' font-weight: bold;';
12795 if ($this->defaultheaderfontstyle == 'I' || $this->defaultheaderfontstyle == 'BI') {
12796 $oddhtml .= ' font-style: italic;';
12800 if ($this->defaultheaderline) {
12801 $oddhtml .= ' border-bottom: 0.1mm solid #000000;';
12804 $oddhtml .= 'text-align: right; ">' . $Harray . '</div>';
12807 if ($this->defaultheaderfontsize) {
12808 $evenhtml .= ' font-size: ' . $this->defaultheaderfontsize . 'pt;';
12811 if ($this->defaultheaderfontstyle) {
12813 if ($this->defaultheaderfontstyle == 'B' || $this->defaultheaderfontstyle == 'BI') {
12814 $evenhtml .= ' font-weight: bold;';
12817 if ($this->defaultheaderfontstyle == 'I' || $this->defaultheaderfontstyle == 'BI') {
12818 $evenhtml .= ' font-style: italic;';
12822 if ($this->defaultheaderline) {
12823 $evenhtml .= ' border-bottom: 0.1mm solid #000000;';
12826 $evenhtml .= 'text-align: left; ">' . $Harray . '</div>';
12843 $oddhtml = $this->_createHTMLheaderFooter($odd, 'H');
12844 $evenhtml = $this->_createHTMLheaderFooter($even, 'H');
12848 $this->SetHTMLHeader($evenhtml, 'E', $write);
12850 $this->SetHTMLHeader($oddhtml, 'O', $write);
12852 $this->SetHTMLHeader($oddhtml, 'O', $write);
12853 $this->SetHTMLHeader($evenhtml, 'E', $write);
12872 $oddhtml = '<table width="100%" style="border-collapse: collapse; margin: 0; vertical-align: top; color: #000000; ';
12874 if ($this->defaultfooterfontsize) {
12875 $oddhtml .= ' font-size: ' . $this->defaultfooterfontsize . 'pt;';
12878 if ($this->defaultfooterfontstyle) {
12879 if ($this->defaultfooterfontstyle == 'B' || $this->defaultfooterfontstyle == 'BI') {
12880 $oddhtml .= ' font-weight: bold;';
12882 if ($this->defaultfooterfontstyle == 'I' || $this->defaultfooterfontstyle == 'BI') {
12883 $oddhtml .= ' font-style: italic;';
12887 if ($this->defaultfooterline) {
12888 $oddhtml .= ' border-top: 0.1mm solid #000000;';
12893 $oddhtml .= '<td width="33%" style="padding: ' . $this->footer_line_spacing . 'em 0 0 0; text-align: left; ">' . $hdet[0] . '</td>';
12894 $oddhtml .= '<td width="33%" style="padding: ' . $this->footer_line_spacing . 'em 0 0 0; text-align: center; ">' . $hdet[1] . '</td>';
12895 $oddhtml .= '<td width="33%" style="padding: ' . $this->footer_line_spacing . 'em 0 0 0; text-align: right; ">' . $hdet[2] . '</td>';
12898 $evenhtml = '<table width="100%" style="border-collapse: collapse; margin: 0; vertical-align: top; color: #000000; ';
12900 if ($this->defaultfooterfontsize) {
12901 $evenhtml .= ' font-size: ' . $this->defaultfooterfontsize . 'pt;';
12904 if ($this->defaultfooterfontstyle) {
12906 if ($this->defaultfooterfontstyle == 'B' || $this->defaultfooterfontstyle == 'BI') {
12907 $evenhtml .= ' font-weight: bold;';
12910 if ($this->defaultfooterfontstyle == 'I' || $this->defaultfooterfontstyle == 'BI') {
12911 $evenhtml .= ' font-style: italic;';
12915 if ($this->defaultfooterline) {
12916 $evenhtml .= ' border-top: 0.1mm solid #000000;';
12921 $evenhtml .= '<td width="33%" style="padding: ' . $this->footer_line_spacing . 'em 0 0 0; text-align: left; ">' . $hdet[2] . '</td>';
12922 $evenhtml .= '<td width="33%" style="padding: ' . $this->footer_line_spacing . 'em 0 0 0; text-align: center; ">' . $hdet[1] . '</td>';
12923 $evenhtml .= '<td width="33%" style="padding: ' . $this->footer_line_spacing . 'em 0 0 0; text-align: right; ">' . $hdet[0] . '</td>';
12930 if ($this->defaultfooterfontsize) {
12931 $oddhtml .= ' font-size: ' . $this->defaultfooterfontsize . 'pt;';
12934 if ($this->defaultfooterfontstyle) {
12936 if ($this->defaultfooterfontstyle == 'B' || $this->defaultfooterfontstyle == 'BI') {
12937 $oddhtml .= ' font-weight: bold;';
12940 if ($this->defaultfooterfontstyle == 'I' || $this->defaultfooterfontstyle == 'BI') {
12941 $oddhtml .= ' font-style: italic;';
12945 if ($this->defaultfooterline) {
12946 $oddhtml .= ' border-top: 0.1mm solid #000000;';
12949 $oddhtml .= 'text-align: right; ">' . $Farray . '</div>';
12953 if ($this->defaultfooterfontsize) {
12954 $evenhtml .= ' font-size: ' . $this->defaultfooterfontsize . 'pt;';
12957 if ($this->defaultfooterfontstyle) {
12959 if ($this->defaultfooterfontstyle == 'B' || $this->defaultfooterfontstyle == 'BI') {
12960 $evenhtml .= ' font-weight: bold;';
12963 if ($this->defaultfooterfontstyle == 'I' || $this->defaultfooterfontstyle == 'BI') {
12964 $evenhtml .= ' font-style: italic;';
12968 if ($this->defaultfooterline) {
12969 $evenhtml .= ' border-top: 0.1mm solid #000000;';
12972 $evenhtml .= 'text-align: left; ">' . $Farray . '</div>';
12989 $oddhtml = $this->_createHTMLheaderFooter($odd, 'F');
12990 $evenhtml = $this->_createHTMLheaderFooter($even, 'F');
12994 $this->SetHTMLFooter($evenhtml, 'E');
12996 $this->SetHTMLFooter($oddhtml, 'O');
12998 $this->SetHTMLFooter($oddhtml, 'O');
12999 $this->SetHTMLFooter($evenhtml, 'E');
13003 /* -- WATERMARK -- */
13005 function SetWatermarkText($txt = '', $alpha = -1)
13008 $this->watermarkTextAlpha = $alpha;
13010 $this->watermarkText = $txt;
13013 function SetWatermarkImage($src, $alpha = -1, $size = 'D', $pos = 'F')
13016 $this->watermarkImageAlpha = $alpha;
13018 $this->watermarkImage = $src;
13019 $this->watermark_size = $size;
13020 $this->watermark_pos = $pos;
13023 /* -- END WATERMARK -- */
13028 /* -- CSS-PAGE -- */
13029 // PAGED MEDIA - CROP / CROSS MARKS from @PAGE
13030 if ($this->show_marks == 'CROP' || $this->show_marks == 'CROPCROSS') {
13032 $this->SetLineWidth(0.1); // = 0.1 mm
13033 $this->SetDColor($this->colorConverter->convert(0, $this->PDFAXwarnings));
13034 $l = $this->cropMarkLength;
13035 $m = $this->cropMarkMargin; // Distance of crop mark from margin
13036 $b = $this->nonPrintMargin; // Non-printable border at edge of paper sheet
13038 $bx = $this->page_box['outer_width_LR'] - $m;
13039 $ax = max($ax1, $bx - $l);
13040 $cx1 = $this->w - $b;
13041 $dx = $this->w - $this->page_box['outer_width_LR'] + $m;
13044 $by = $this->page_box['outer_width_TB'] - $m;
13045 $ay = max($ay1, $by - $l);
13046 $cy1 = $this->h - $b;
13047 $dy = $this->h - $this->page_box['outer_width_TB'] + $m;
13050 $this->Line($ax, $this->page_box['outer_width_TB'], $bx, $this->page_box['outer_width_TB']);
13051 $this->Line($cx, $this->page_box['outer_width_TB'], $dx, $this->page_box['outer_width_TB']);
13052 $this->Line($ax, $this->h - $this->page_box['outer_width_TB'], $bx, $this->h - $this->page_box['outer_width_TB']);
13053 $this->Line($cx, $this->h - $this->page_box['outer_width_TB'], $dx, $this->h - $this->page_box['outer_width_TB']);
13054 $this->Line($this->page_box['outer_width_LR'], $ay, $this->page_box['outer_width_LR'], $by);
13055 $this->Line($this->page_box['outer_width_LR'], $cy, $this->page_box['outer_width_LR'], $dy);
13056 $this->Line($this->w - $this->page_box['outer_width_LR'], $ay, $this->w - $this->page_box['outer_width_LR'], $by);
13057 $this->Line($this->w - $this->page_box['outer_width_LR'], $cy, $this->w - $this->page_box['outer_width_LR'], $dy);
13059 if ($this->printers_info) {
13060 $hd = date('Y-m-d H:i') . ' Page ' . $this->page . ' of {nb}';
13061 $this->SetTColor($this->colorConverter->convert(0, $this->PDFAXwarnings));
13062 $this->SetFont('arial', '', 7.5, true, true);
13063 $this->x = $this->page_box['outer_width_LR'] + 1.5;
13064 $this->y = 1;
13065 $this->Cell(0, $this->FontSize, $hd, 0, 0, 'L', 0, '', 0, 0, 0, 'M');
13066 $this->SetFont($this->default_font, '', $this->original_default_font_size);
13069 if ($this->show_marks == 'CROSS' || $this->show_marks == 'CROPCROSS') {
13070 $this->SetLineWidth(0.1); // = 0.1 mm
13071 $this->SetDColor($this->colorConverter->convert(0, $this->PDFAXwarnings));
13075 $m = $this->crossMarkMargin; // Distance of cross mark from margin
13076 $x1 = $this->page_box['outer_width_LR'] - $m;
13077 $x2 = $this->w - $this->page_box['outer_width_LR'] + $m;
13078 $y1 = $this->page_box['outer_width_TB'] - $m;
13079 $y2 = $this->h - $this->page_box['outer_width_TB'] + $m;
13081 $this->Circle($x1, $this->h / 2, $r, 'S');
13082 $this->Line($x1 - $w, $this->h / 2, $x1 + $w, $this->h / 2);
13083 $this->Line($x1, $this->h / 2 - $l, $x1, $this->h / 2 + $l);
13085 $this->Circle($x2, $this->h / 2, $r, 'S');
13086 $this->Line($x2 - $w, $this->h / 2, $x2 + $w, $this->h / 2);
13087 $this->Line($x2, $this->h / 2 - $l, $x2, $this->h / 2 + $l);
13089 $this->Circle($this->w / 2, $y1, $r, 'S');
13090 $this->Line($this->w / 2, $y1 - $w, $this->w / 2, $y1 + $w);
13091 $this->Line($this->w / 2 - $l, $y1, $this->w / 2 + $l, $y1);
13093 $this->Circle($this->w / 2, $y2, $r, 'S');
13094 $this->Line($this->w / 2, $y2 - $w, $this->w / 2, $y2 + $w);
13095 $this->Line($this->w / 2 - $l, $y2, $this->w / 2 + $l, $y2);
13098 /* -- END CSS-PAGE -- */
13101 // If @page set non-HTML headers/footers named, they were not read until later in the HTML code - so now set them
13102 if ($this->page == 1) {
13103 if ($this->firstPageBoxHeader) {
13104 if (isset($this->pageHTMLheaders[$this->firstPageBoxHeader])) {
13105 $this->HTMLHeader = $this->pageHTMLheaders[$this->firstPageBoxHeader];
13107 $this->Header();
13109 if ($this->firstPageBoxFooter) {
13110 if (isset($this->pageHTMLfooters[$this->firstPageBoxFooter])) {
13111 $this->HTMLFooter = $this->pageHTMLfooters[$this->firstPageBoxFooter];
13114 $this->firstPageBoxHeader = '';
13115 $this->firstPageBoxFooter = '';
13119 if (($this->mirrorMargins && ($this->page % 2 == 0) && $this->HTMLFooterE) || ($this->mirrorMargins && ($this->page % 2 == 1) && $this->HTMLFooter) || (!$this->mirrorMargins && $this->HTMLFooter)) {
13120 $this->writeHTMLFooters();
13123 /* -- WATERMARK -- */
13124 if (($this->watermarkText) && ($this->showWatermarkText)) {
13125 $this->watermark($this->watermarkText, $this->watermarkAngle, 120, $this->watermarkTextAlpha); // Watermark text
13127 if (($this->watermarkImage) && ($this->showWatermarkImage)) {
13128 $this->watermarkImg($this->watermarkImage, $this->watermarkImageAlpha); // Watermark image
13130 /* -- END WATERMARK -- */
13133 /* -- HTML-CSS -- */
13165 $this->headerbuffer = '';
13166 $this->textbuffer = [];
13167 $this->fixedPosBlockSave = [];
13173 if ($this->allow_charset_conversion) {
13175 $this->ReadCharset($html);
13177 if ($this->charset_in && $mode !== HTMLParserMode::HTML_HEADER_BUFFER) {
13178 $success = iconv($this->charset_in, 'UTF-8//TRANSLIT', $html);
13185 $html = $this->purify_utf8($html, false);
13187 $this->blklvl = 0;
13188 $this->lastblocklevelchange = 0;
13189 $this->blk = [];
13190 $this->initialiseBlock($this->blk[0]);
13191 $this->blk[0]['width'] = & $this->pgwidth;
13192 $this->blk[0]['inner_width'] = & $this->pgwidth;
13193 $this->blk[0]['blockContext'] = $this->blockContext;
13198 $this->ReadMetaTags($html);
13201 $this->SetBasePath($m[1]);
13203 $html = $this->cssManager->ReadCSS($html);
13205 if ($this->autoLangToFont && !$this->usingCoreFont && preg_match('/<html [^>]*lang=[\'\"](.*?)[\'\"]/ism', $html, $m)) {
13213 // allow in-line CSS for body tag to be parsed // Get <body> tag inline CSS
13218 $zproperties = $this->cssManager->readInlineCSS($mm[1]);
13226 if ($this->autoLangToFont && !$this->onlyCoreFonts && preg_match('/lang=[\'\"](.*?)[\'\"]/ism', $m[1], $mm)) {
13231 $properties = $this->cssManager->MergeCSS('BLOCK', 'BODY', '');
13233 $properties = $this->cssManager->array_merge_recursive_unique($properties, $zproperties);
13237 $this->cssManager->CSS['BODY']['DIRECTION'] = $properties['DIRECTION'];
13239 if (!isset($this->cssManager->CSS['BODY']['DIRECTION'])) {
13240 $this->cssManager->CSS['BODY']['DIRECTION'] = $this->directionality;
13242 $this->SetDirectionality($this->cssManager->CSS['BODY']['DIRECTION']);
13245 $this->setCSS($properties, '', 'BODY');
13247 $this->blk[0]['InlineProperties'] = $this->saveInlineProperties();
13252 if (!isset($this->cssManager->CSS['BODY'])) {
13253 $this->cssManager->CSS['BODY'] = [];
13256 /* -- BACKGROUNDS -- */
13257 if (isset($properties['BACKGROUND-GRADIENT'])) {
13258 $this->bodyBackgroundGradient = $properties['BACKGROUND-GRADIENT'];
13261 if (isset($properties['BACKGROUND-IMAGE']) && $properties['BACKGROUND-IMAGE']) {
13262 $ret = $this->SetBackground($properties, $this->pgwidth);
13264 $this->bodyBackgroundImage = $ret;
13267 /* -- END BACKGROUNDS -- */
13269 /* -- CSS-PAGE -- */
13270 // If page-box is set
13271 if ($this->state == 0 && ((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
13272 $this->page_box['current'] = '';
13273 $this->page_box['using'] = true;
13274 list($pborientation, $pbmgl, $pbmgr, $pbmgt, $pbmgb, $pbmgh, $pbmgf, $hname, $fname, $bg, $resetpagenum, $pagenumstyle, $suppress, $marks, $newformat) = $this->SetPagedMediaCSS('', false, 'O');
13275 $this->DefOrientation = $this->CurOrientation = $pborientation;
13276 $this->orig_lMargin = $this->DeflMargin = $pbmgl;
13277 $this->orig_rMargin = $this->DefrMargin = $pbmgr;
13278 $this->orig_tMargin = $this->tMargin = $pbmgt;
13279 $this->orig_bMargin = $this->bMargin = $pbmgb;
13280 $this->orig_hMargin = $this->margin_header = $pbmgh;
13281 $this->orig_fMargin = $this->margin_footer = $pbmgf;
13282 list($pborientation, $pbmgl, $pbmgr, $pbmgt, $pbmgb, $pbmgh, $pbmgf, $hname, $fname, $bg, $resetpagenum, $pagenumstyle, $suppress, $marks, $newformat) = $this->SetPagedMediaCSS('', true, 'O'); // first page
13283 $this->show_marks = $marks;
13285 $this->firstPageBoxHeader = $hname;
13288 $this->firstPageBoxFooter = $fname;
13291 /* -- END CSS-PAGE -- */
13294 $this->bufferoutput = false;
13300 for ($b = $this->blklvl; $b > 0; $b--) {
13301 $this->tag->CloseTag($this->blk[$b]['tag'], $arr, $ai);
13304 if (count($this->textbuffer)) {
13305 $this->printbuffer($this->textbuffer);
13307 $this->textbuffer = [];
13312 for ($b = $this->blklvl; $b > 0; $b--) {
13313 $this->tag->CloseTag($this->blk[$b]['tag'], $arr, $ai);
13316 if (count($this->textbuffer)) {
13317 $this->printbuffer($this->textbuffer);
13319 $this->bufferoutput = true;
13320 $this->textbuffer = [];
13321 $this->headerbuffer = '';
13322 $properties = $this->cssManager->MergeCSS('BLOCK', 'BODY', '');
13323 $this->setCSS($properties, '', 'BODY');
13326 mb_internal_encoding('UTF-8');
13328 $html = $this->AdjustHTML($html, $this->tabSpaces); // Try to make HTML look more like XHTML
13330 if ($this->autoScriptToLang) {
13331 $html = $this->markScriptToLang($html);
13337 $this->pageHTMLheaders[$n[1]]['html'] = $h[2][$i];
13338 $this->pageHTMLheaders[$n[1]]['h'] = $this->_getHtmlHeight($h[2][$i]);
13344 $this->pageHTMLfooters[$n[1]]['html'] = $f[2][$i];
13345 $this->pageHTMLfooters[$n[1]]['h'] = $this->_getHtmlHeight($f[2][$i]);
13352 if ($this->state == 0 && ($mode === HTMLParserMode::DEFAULT_MODE || $mode === HTMLParserMode::HTML_BODY)) {
13353 $this->AddPage($this->CurOrientation);
13358 $this->SetHTMLHeader($this->pageHTMLheaders[$n[1]], 'O', true);
13361 $this->SetHTMLFooter($this->pageHTMLfooters[$n[1]], 'O');
13368 $this->checkSIP = false;
13369 $this->checkSMP = false;
13370 $this->checkCJK = false;
13371 if ($this->onlyCoreFonts) {
13372 $html = $this->SubstituteChars($html);
13374 if (preg_match("/([" . $this->pregRTLchars . "])/u", $html)) {
13375 $this->biDirectional = true;
13377 if (preg_match("/([\x{20000}-\x{2FFFF}])/u", $html)) {
13378 $this->checkSIP = true;
13380 if (preg_match("/([\x{10000}-\x{1FFFF}])/u", $html)) {
13381 $this->checkSMP = true;
13383 /* -- CJK-FONTS -- */
13384 if (preg_match("/([" . $this->pregCJKchars . "])/u", $html)) {
13385 $this->checkCJK = true;
13387 /* -- END CJK-FONTS -- */
13390 // Don't allow non-breaking spaces that are converted to substituted chars or will break anyway and mess up table width calc.
13397 $html = strip_tags($html, $this->enabledtags); // remove all unsupported tags, but the ones inside the 'enabledtags' string
13399 $a = preg_split('/<(.*?)>/ms', $html, -1, PREG_SPLIT_DELIM_CAPTURE);
13401 // if changing - also change in fn.SubstituteChars()
13402 // $a = preg_split ('/<((?:[^<>]+(?:"[^"]*"|\'[^\']*\')?)+)>/ms', $html, -1, PREG_SPLIT_DELIM_CAPTURE);
13404 if ($this->mb_enc) {
13405 mb_internal_encoding($this->mb_enc);
13408 $this->subPos = -1;
13414 if ($this->blk[$this->blklvl]['hide']) {
13417 if ($this->inlineDisplayOff) {
13420 if ($this->inMeter) {
13424 if ($this->inFixedPosBlock) {
13425 $this->fixedPosBlock .= $e;
13427 } // *CSS-POSITION*
13432 if ($this->ignorefollowingspaces && !$this->ispre) {
13436 if ($this->FontFamily != 'csymbol' && $this->FontFamily != 'czapfdingbats' && substr($e, 0, 1) == ' ') {
13437 $this->ignorefollowingspaces = false;
13442 $this->OTLdata = null; // mPDF 5.7.1
13445 $e = $this->lesser_entity_decode($e);
13447 if ($this->usingCoreFont) {
13448 // If core font is selected in document which is not onlyCoreFonts - substitute with non-core font
13449 if ($this->useSubstitutions && !$this->onlyCoreFonts && $this->subPos < $i && !$this->specialcontent) {
13450 $cnt += $this->SubstituteCharsNonCore($a, $i, $e);
13453 $e = mb_convert_encoding($e, $this->mb_enc, 'UTF-8');
13454 if ($this->textvar & TextVars::FT_UPPERCASE) {
13455 $e = mb_strtoupper($e, $this->mb_enc);
13457 elseif ($this->textvar & TextVars::FT_LOWERCASE) {
13458 $e = mb_strtolower($e, $this->mb_enc);
13460 elseif ($this->textvar & TextVars::FT_CAPITALIZE) {
13461 $e = mb_convert_case($e, MB_CASE_TITLE, "UTF-8");
13464 if ($this->checkSIP && $this->CurrentFont['sipext'] && $this->subPos < $i && (!$this->specialcontent || !$this->useActiveForms)) {
13465 $cnt += $this->SubstituteCharsSIP($a, $i, $e);
13468 if ($this->useSubstitutions && !$this->onlyCoreFonts && $this->CurrentFont['type'] != 'Type0' && $this->subPos < $i && (!$this->specialcontent || !$this->useActiveForms)) {
13469 $cnt += $this->SubstituteCharsMB($a, $i, $e);
13472 if ($this->textvar & TextVars::FT_UPPERCASE) {
13473 $e = mb_strtoupper($e, $this->mb_enc);
13474 } elseif ($this->textvar & TextVars::FT_LOWERCASE) {
13475 $e = mb_strtolower($e, $this->mb_enc);
13476 } elseif ($this->textvar & TextVars::FT_CAPITALIZE) {
13477 $e = mb_convert_case($e, MB_CASE_TITLE, "UTF-8");
13480 /* -- OTL -- */
13481 // Use OTL OpenType Table Layout - GSUB & GPOS
13482 if (isset($this->CurrentFont['useOTL']) && $this->CurrentFont['useOTL'] && (!$this->specialcontent || !$this->useActiveForms)) {
13483 if (!$this->otl) {
13484 $this->otl = new Otl($this, $this->fontCache);
13486 $e = $this->otl->applyOTL($e, $this->CurrentFont['useOTL']);
13487 $this->OTLdata = $this->otl->OTLdata;
13488 $this->otl->removeChar($e, $this->OTLdata, "\xef\xbb\xbf"); // Remove ZWNBSP (also Byte order mark FEFF)
13489 } /* -- END OTL -- */
13491 // removes U+200E/U+200F LTR and RTL mark and U+200C/U+200D Zero-width Joiner and Non-joiner
13497 if (($this->tts) || ($this->ttz) || ($this->tta)) {
13506 if ($this->specialcontent) {
13507 /* -- FORMS -- */
13509 if ($this->specialcontent == "type=select") {
13511 if (!empty($this->OTLdata)) {
13512 $this->otl->trimOTLdata($this->OTLdata, true, false);
13514 $stringwidth = $this->GetStringWidth($e);
13515 if (!isset($this->selectoption['MAXWIDTH']) || $stringwidth > $this->selectoption['MAXWIDTH']) {
13516 $this->selectoption['MAXWIDTH'] = $stringwidth;
13518 if (!isset($this->selectoption['SELECTED']) || $this->selectoption['SELECTED'] == '') {
13519 $this->selectoption['SELECTED'] = $e;
13520 if (!empty($this->OTLdata)) {
13521 $this->selectoption['SELECTED-OTLDATA'] = $this->OTLdata;
13525 if (isset($this->selectoption['ACTIVE']) && $this->selectoption['ACTIVE']) {
13526 $this->selectoption['ITEMS'][] = ['exportValue' => $this->selectoption['currentVAL'], 'content' => $e, 'selected' => $this->selectoption['currentSEL']];
13528 $this->OTLdata = [];
13531 $objattr = unserialize($this->specialcontent);
13533 $objattr['OTLdata'] = $this->OTLdata;
13534 $this->OTLdata = [];
13536 if ($this->tdbegin) {
13537 $this->_saveCellTextBuffer($te, $this->HREF);
13539 $this->_saveTextBuffer($te, $this->HREF);
13542 /* -- END FORMS -- */
13544 elseif ($this->tableLevel) {
13545 /* -- TABLES -- */
13546 if ($this->tdbegin) {
13547 if (($this->ignorefollowingspaces) && !$this->ispre) {
13549 if (!empty($this->OTLdata)) {
13550 $this->otl->trimOTLdata($this->OTLdata, true, false);
13554 if ($this->blockjustfinished && $this->cell[$this->row][$this->col]['s'] > 0) {
13555 $this->_saveCellTextBuffer("\n");
13556 if (!isset($this->cell[$this->row][$this->col]['maxs'])) {
13557 $this->cell[$this->row][$this->col]['maxs'] = $this->cell[$this->row][$this->col]['s'];
13558 } elseif ($this->cell[$this->row][$this->col]['maxs'] < $this->cell[$this->row][$this->col]['s']) {
13559 $this->cell[$this->row][$this->col]['maxs'] = $this->cell[$this->row][$this->col]['s'];
13561 $this->cell[$this->row][$this->col]['s'] = 0; // reset
13563 $this->blockjustfinished = false;
13565 if (!isset($this->cell[$this->row][$this->col]['R']) || !$this->cell[$this->row][$this->col]['R']) {
13566 if (isset($this->cell[$this->row][$this->col]['s'])) {
13567 $this->cell[$this->row][$this->col]['s'] += $this->GetStringWidth($e, false, $this->OTLdata, $this->textvar);
13569 $this->cell[$this->row][$this->col]['s'] = $this->GetStringWidth($e, false, $this->OTLdata, $this->textvar);
13571 if (!empty($this->spanborddet)) {
13572 $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);
13576 $this->_saveCellTextBuffer($e, $this->HREF);
13578 if (substr($this->cell[$this->row][$this->col]['a'], 0, 1) == 'D') {
13580 $dp = $this->decimal_align[substr($this->cell[$this->row][$this->col]['a'], 0, 2)];
13582 $s0 = $this->GetStringWidth($s[0], false);
13585 $s1 = $this->GetStringWidth(($s[1] . $dp), false);
13590 if (!isset($this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['decimal_align'][$this->col]['maxs0'])) {
13591 if ($this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['decimal_align'] === false) {
13592 $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['decimal_align'] = [];
13594 $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['decimal_align'][$this->col]['maxs0'] = $s0;
13596 $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']);
13599 if (!isset($this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['decimal_align'][$this->col]['maxs1'])) {
13600 $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['decimal_align'][$this->col]['maxs1'] = $s1;
13602 $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']);
13606 $this->nestedtablejustfinished = false;
13607 $this->linebreakjustfinished = false;
13610 /* -- END TABLES -- */
13613 if ($this->ignorefollowingspaces && !$this->ispre) {
13615 if (!empty($this->OTLdata)) {
13616 $this->otl->trimOTLdata($this->OTLdata, true, false);
13620 $this->_saveTextBuffer($e, $this->HREF);
13624 $this->ignorefollowingspaces = false; // mPDF 6
13626 if (substr($e, -1, 1) == ' ' && !$this->ispre && $this->FontFamily != 'csymbol' && $this->FontFamily != 'czapfdingbats') {
13627 $this->ignorefollowingspaces = true;
13633 /* -- CSS-POSITION -- */
13635 if ($this->inFixedPosBlock) {
13636 if (in_array($endtag, $this->outerblocktags) || in_array($endtag, $this->innerblocktags)) {
13637 $this->fixedPosBlockDepth--;
13639 if ($this->fixedPosBlockDepth == 0) {
13640 $this->fixedPosBlockSave[] = [$this->fixedPosBlock, $this->fixedPosBlockBBox, $this->page];
13641 $this->fixedPosBlock = '';
13642 $this->inFixedPosBlock = false;
13645 $this->fixedPosBlock .= '<' . $e . '>';
13648 /* -- END CSS-POSITION -- */
13652 if ($this->allow_html_optional_endtags && !$parseonly) {
13653 if (isset($this->blk[$this->blklvl]['tag'])) {
13656 if (!$closed && $this->blk[$this->blklvl]['tag'] == 'LI' && $endtag != 'LI' && (in_array($endtag, $this->outerblocktags) || in_array($endtag, $this->innerblocktags))) {
13657 $this->tag->CloseTag('LI', $a, $i);
13661 if (!$closed && $this->blk[$this->blklvl]['tag'] == 'DD' && $endtag != 'DD' && (in_array($endtag, $this->outerblocktags) || in_array($endtag, $this->innerblocktags))) {
13662 $this->tag->CloseTag('DD', $a, $i);
13666 if (!$closed && $this->blk[$this->blklvl]['tag'] == 'P' && $endtag != 'P' && (in_array($endtag, $this->outerblocktags) || in_array($endtag, $this->innerblocktags))) {
13667 $this->tag->CloseTag('P', $a, $i);
13671 if (!$closed && $this->blk[$this->blklvl]['tag'] == 'OPTION' && $endtag != 'OPTION' && (in_array($endtag, $this->outerblocktags) || in_array($endtag, $this->innerblocktags))) {
13672 $this->tag->CloseTag('OPTION', $a, $i);
13676 /* -- TABLES -- */
13679 if ($this->lastoptionaltag == 'THEAD' || $this->lastoptionaltag == 'TBODY' || $this->lastoptionaltag == 'TFOOT') {
13680 $this->tag->CloseTag($this->lastoptionaltag, $a, $i);
13682 if ($this->lastoptionaltag == 'TR') {
13683 $this->tag->CloseTag('TR', $a, $i);
13685 if ($this->lastoptionaltag == 'TD' || $this->lastoptionaltag == 'TH') {
13686 $this->tag->CloseTag($this->lastoptionaltag, $a, $i);
13687 $this->tag->CloseTag('TR', $a, $i);
13691 if ($this->lastoptionaltag == 'TR') {
13692 $this->tag->CloseTag('TR', $a, $i);
13694 if ($this->lastoptionaltag == 'TD' || $this->lastoptionaltag == 'TH') {
13695 $this->tag->CloseTag($this->lastoptionaltag, $a, $i);
13696 $this->tag->CloseTag('TR', $a, $i);
13700 if ($this->lastoptionaltag == 'TD' || $this->lastoptionaltag == 'TH') {
13701 $this->tag->CloseTag($this->lastoptionaltag, $a, $i);
13704 /* -- END TABLES -- */
13709 if ($this->blk[$this->blklvl]['hide']) {
13710 if (in_array($endtag, $this->outerblocktags) || in_array($endtag, $this->innerblocktags)) {
13711 unset($this->blk[$this->blklvl]);
13712 $this->blklvl--;
13718 $this->tag->CloseTag($endtag, $a, $i); // mPDF 6
13720 if ($this->blk[$this->blklvl]['hide']) {
13728 $this->lastoptionaltag = $te;
13730 if (in_array($te, $this->outerblocktags) || in_array($te, $this->innerblocktags)) {
13731 $this->blklvl++;
13732 $this->blk[$this->blklvl]['hide'] = true;
13733 $this->blk[$this->blklvl]['tag'] = $te; // mPDF 6
13738 /* -- CSS-POSITION -- */
13739 if ($this->inFixedPosBlock) {
13745 $this->fixedPosBlock .= '<' . $e . '>';
13746 if (in_array($te, $this->outerblocktags) || in_array($te, $this->innerblocktags)) {
13747 $this->fixedPosBlockDepth++;
13751 /* -- END CSS-POSITION -- */
13775 $this->GetFullPath($path);
13786 // Increase allowed attribute name to 32 - cutting off "toc-even-header-name" etc.
13803 } // includes header-style-right etc. used for <pageheader>
13804 elseif (preg_match('/^(HEADER|FOOTER)-STYLE/i', $a3[1])) {
13812 $this->tag->OpenTag($tag, $attr, $a, $i); // mPDF 6
13813 /* -- CSS-POSITION -- */
13814 if ($this->inFixedPosBlock) {
13815 $this->fixedPosBlockBBox = [$tag, $attr, $this->x, $this->y];
13816 $this->fixedPosBlock = '';
13817 $this->fixedPosBlockDepth = 1;
13819 /* -- END CSS-POSITION -- */
13821 $this->tag->CloseTag($tag, $a, $i);
13829 for ($b = $this->blklvl; $b > 0; $b--) {
13830 $this->tag->CloseTag($this->blk[$b]['tag'], $a, $i);
13834 if (count($this->textbuffer) && !$parseonly) {
13835 $this->printbuffer($this->textbuffer);
13838 $this->textbuffer = [];
13841 /* -- CSS-FLOAT -- */
13843 $currpos = $this->page * 1000 + $this->y;
13844 if (isset($this->blk[$this->blklvl]['float_endpos']) && $this->blk[$this->blklvl]['float_endpos'] > $currpos) {
13845 $old_page = $this->page;
13846 $new_page = intval($this->blk[$this->blklvl]['float_endpos'] / 1000);
13848 $s = $this->PrintPageBackgrounds();
13850 $this->pages[$this->page] = preg_replace('/(___BACKGROUND___PATTERNS' . $this->uniqstr . ')/', '\\1' . "\n" . $s . "\n", $this->pages[$this->page]);
13851 $this->pageBackgrounds = [];
13852 $this->page = $new_page;
13853 $this->ResetMargins();
13854 $this->Reset();
13855 $this->pageoutput[$this->page] = [];
13857 $this->y = (round($this->blk[$this->blklvl]['float_endpos'] * 1000) % 1000000) / 1000; // mod changes operands to integers before processing
13859 /* -- END CSS-FLOAT -- */
13861 /* -- CSS-IMAGE-FLOAT -- */
13862 $this->printfloatbuffer();
13863 /* -- END CSS-IMAGE-FLOAT -- */
13866 if (!empty($this->internallink)) {
13868 foreach ($this->internallink as $k => $v) {
13882 while (array_key_exists($sharp . $k, $this->internallink)) {
13883 $internallink = $this->internallink[$sharp . $k];
13884 $this->SetLink($internallink, $ypos, $pagenum);
13890 $this->bufferoutput = false;
13892 /* -- CSS-POSITION -- */
13893 if (count($this->fixedPosBlockSave)) {
13894 foreach ($this->fixedPosBlockSave as $fpbs) {
13895 $old_page = $this->page;
13896 $this->page = $fpbs[2];
13897 $this->WriteFixedPosHTML($fpbs[0], 0, 0, 100, 100, 'auto', $fpbs[1]); // 0,0,10,10 are overwritten by bbox
13898 $this->page = $old_page;
13900 $this->fixedPosBlockSave = [];
13902 /* -- END CSS-POSITION -- */
13906 /* -- CSS-POSITION -- */
13910 // $overflow can be 'hidden', 'visible' or 'auto' - 'auto' causes autofit to size
13911 // Annotations disabled - enabled in mPDF 5.0
13919 if ($this->state == 0) {
13920 $this->AddPage($this->CurOrientation);
13922 $save_y = $this->y;
13923 $save_x = $this->x;
13924 $this->fullImageHeight = $this->h;
13926 /* -- COLUMNS -- */
13927 if ($this->ColActive) {
13929 $save_nbcol = $this->NbCol; // other values of gap and vAlign will not change by setting Columns off
13930 $this->SetColumns(0);
13932 /* -- END COLUMNS -- */
13933 $save_annots = $this->title2annots; // *ANNOTATIONS*
13934 $this->writingHTMLheader = true; // a FIX to stop pagebreaks etc.
13935 $this->writingHTMLfooter = true;
13936 $this->InFooter = true; // suppresses autopagebreaks
13937 $save_bgs = $this->pageBackgrounds;
13941 if ($w > $this->w) {
13943 $w = $this->w;
13945 if ($h > $this->h) {
13947 $h = $this->h;
13949 if ($x > $this->w) {
13950 $x = $this->w - $w;
13952 if ($y > $this->h) {
13953 $y = $this->h - $h;
13960 // font*[family/size/style/weight]/line-height/text*[align/decoration/transform/indent]/color are transferred to $inner
13970 $this->blklvl = 0;
13971 $this->lastblocklevelchange = 0;
13972 $this->blk = [];
13973 $this->initialiseBlock($this->blk[0]);
13975 $this->blk[0]['width'] = & $this->pgwidth;
13976 $this->blk[0]['inner_width'] = & $this->pgwidth;
13978 $this->blk[0]['blockContext'] = $this->blockContext;
13980 $properties = $this->cssManager->MergeCSS('BLOCK', 'BODY', '');
13981 $this->setCSS($properties, '', 'BODY');
13982 $this->blklvl = 1;
13983 $this->initialiseBlock($this->blk[1]);
13984 $this->blk[1]['tag'] = $tag;
13985 $this->blk[1]['attr'] = $attr;
13986 $this->Reset();
13987 $p = $this->cssManager->MergeCSS('BLOCK', $tag, $attr);
13988 if (isset($p['ROTATE']) && ($p['ROTATE'] == 90 || $p['ROTATE'] == -90 || $p['ROTATE'] == 180)) {
13995 $cont_w = $this->pgwidth; // $this->blk[0]['inner_width'];
13996 $cont_h = $this->h - $this->tMargin - $this->bMargin;
13997 $cont_x = $this->lMargin;
13998 $cont_y = $this->tMargin;
14000 $cont_w = $this->w; // ABSOLUTE;
14001 $cont_h = $this->h;
14006 // Pass on in-line properties to the innerhtml
14008 if (isset($p['TEXT-ALIGN'])) {
14009 $css .= 'text-align: ' . strtolower($p['TEXT-ALIGN']) . '; ';
14011 if (isset($p['TEXT-TRANSFORM'])) {
14012 $css .= 'text-transform: ' . strtolower($p['TEXT-TRANSFORM']) . '; ';
14014 if (isset($p['TEXT-INDENT'])) {
14015 $css .= 'text-indent: ' . strtolower($p['TEXT-INDENT']) . '; ';
14017 if (isset($p['TEXT-DECORATION'])) {
14018 $css .= 'text-decoration: ' . strtolower($p['TEXT-DECORATION']) . '; ';
14020 if (isset($p['FONT-FAMILY'])) {
14021 $css .= 'font-family: ' . strtolower($p['FONT-FAMILY']) . '; ';
14023 if (isset($p['FONT-STYLE'])) {
14024 $css .= 'font-style: ' . strtolower($p['FONT-STYLE']) . '; ';
14026 if (isset($p['FONT-WEIGHT'])) {
14027 $css .= 'font-weight: ' . strtolower($p['FONT-WEIGHT']) . '; ';
14029 if (isset($p['FONT-SIZE'])) {
14030 $css .= 'font-size: ' . strtolower($p['FONT-SIZE']) . '; ';
14032 if (isset($p['LINE-HEIGHT'])) {
14033 $css .= 'line-height: ' . strtolower($p['LINE-HEIGHT']) . '; ';
14035 if (isset($p['TEXT-SHADOW'])) {
14036 $css .= 'text-shadow: ' . strtolower($p['TEXT-SHADOW']) . '; ';
14038 if (isset($p['LETTER-SPACING'])) {
14039 $css .= 'letter-spacing: ' . strtolower($p['LETTER-SPACING']) . '; ';
14042 if (isset($p['FONT-VARIANT-POSITION'])) {
14043 $css .= 'font-variant-position: ' . strtolower($p['FONT-VARIANT-POSITION']) . '; ';
14045 if (isset($p['FONT-VARIANT-CAPS'])) {
14046 $css .= 'font-variant-caps: ' . strtolower($p['FONT-VARIANT-CAPS']) . '; ';
14048 if (isset($p['FONT-VARIANT-LIGATURES'])) {
14049 $css .= 'font-variant-ligatures: ' . strtolower($p['FONT-VARIANT-LIGATURES']) . '; ';
14051 if (isset($p['FONT-VARIANT-NUMERIC'])) {
14052 $css .= 'font-variant-numeric: ' . strtolower($p['FONT-VARIANT-NUMERIC']) . '; ';
14054 if (isset($p['FONT-VARIANT-ALTERNATES'])) {
14055 $css .= 'font-variant-alternates: ' . strtolower($p['FONT-VARIANT-ALTERNATES']) . '; ';
14057 if (isset($p['FONT-FEATURE-SETTINGS'])) {
14058 $css .= 'font-feature-settings: ' . strtolower($p['FONT-FEATURE-SETTINGS']) . '; ';
14060 if (isset($p['FONT-LANGUAGE-OVERRIDE'])) {
14061 $css .= 'font-language-override: ' . strtolower($p['FONT-LANGUAGE-OVERRIDE']) . '; ';
14063 if (isset($p['FONT-KERNING'])) {
14064 $css .= 'font-kerning: ' . strtolower($p['FONT-KERNING']) . '; ';
14070 if (isset($p['Z-INDEX'])) {
14071 $css .= 'z-index: ' . $p['Z-INDEX'] . '; ';
14078 $pb['MARGIN-TOP'] = (isset($p['MARGIN-TOP']) ? $p['MARGIN-TOP'] : '');
14079 $pb['MARGIN-RIGHT'] = (isset($p['MARGIN-RIGHT']) ? $p['MARGIN-RIGHT'] : '');
14080 $pb['MARGIN-BOTTOM'] = (isset($p['MARGIN-BOTTOM']) ? $p['MARGIN-BOTTOM'] : '');
14081 $pb['MARGIN-LEFT'] = (isset($p['MARGIN-LEFT']) ? $p['MARGIN-LEFT'] : '');
14082 $pb['PADDING-TOP'] = (isset($p['PADDING-TOP']) ? $p['PADDING-TOP'] : '');
14083 $pb['PADDING-RIGHT'] = (isset($p['PADDING-RIGHT']) ? $p['PADDING-RIGHT'] : '');
14084 $pb['PADDING-BOTTOM'] = (isset($p['PADDING-BOTTOM']) ? $p['PADDING-BOTTOM'] : '');
14085 $pb['PADDING-LEFT'] = (isset($p['PADDING-LEFT']) ? $p['PADDING-LEFT'] : '');
14086 $pb['BORDER-TOP'] = (isset($p['BORDER-TOP']) ? $p['BORDER-TOP'] : '');
14087 $pb['BORDER-RIGHT'] = (isset($p['BORDER-RIGHT']) ? $p['BORDER-RIGHT'] : '');
14088 $pb['BORDER-BOTTOM'] = (isset($p['BORDER-BOTTOM']) ? $p['BORDER-BOTTOM'] : '');
14089 $pb['BORDER-LEFT'] = (isset($p['BORDER-LEFT']) ? $p['BORDER-LEFT'] : '');
14090 if (isset($p['BORDER-TOP-LEFT-RADIUS-H'])) {
14091 $pb['BORDER-TOP-LEFT-RADIUS-H'] = $p['BORDER-TOP-LEFT-RADIUS-H'];
14093 if (isset($p['BORDER-TOP-LEFT-RADIUS-V'])) {
14094 $pb['BORDER-TOP-LEFT-RADIUS-V'] = $p['BORDER-TOP-LEFT-RADIUS-V'];
14096 if (isset($p['BORDER-TOP-RIGHT-RADIUS-H'])) {
14097 $pb['BORDER-TOP-RIGHT-RADIUS-H'] = $p['BORDER-TOP-RIGHT-RADIUS-H'];
14099 if (isset($p['BORDER-TOP-RIGHT-RADIUS-V'])) {
14100 $pb['BORDER-TOP-RIGHT-RADIUS-V'] = $p['BORDER-TOP-RIGHT-RADIUS-V'];
14102 if (isset($p['BORDER-BOTTOM-LEFT-RADIUS-H'])) {
14103 $pb['BORDER-BOTTOM-LEFT-RADIUS-H'] = $p['BORDER-BOTTOM-LEFT-RADIUS-H'];
14105 if (isset($p['BORDER-BOTTOM-LEFT-RADIUS-V'])) {
14106 $pb['BORDER-BOTTOM-LEFT-RADIUS-V'] = $p['BORDER-BOTTOM-LEFT-RADIUS-V'];
14108 if (isset($p['BORDER-BOTTOM-RIGHT-RADIUS-H'])) {
14109 $pb['BORDER-BOTTOM-RIGHT-RADIUS-H'] = $p['BORDER-BOTTOM-RIGHT-RADIUS-H'];
14111 if (isset($p['BORDER-BOTTOM-RIGHT-RADIUS-V'])) {
14112 $pb['BORDER-BOTTOM-RIGHT-RADIUS-V'] = $p['BORDER-BOTTOM-RIGHT-RADIUS-V'];
14114 if (isset($p['BACKGROUND-COLOR'])) {
14115 $pb['BACKGROUND-COLOR'] = $p['BACKGROUND-COLOR'];
14117 if (isset($p['BOX-SHADOW'])) {
14118 $pb['BOX-SHADOW'] = $p['BOX-SHADOW'];
14120 /* -- BACKGROUNDS -- */
14121 if (isset($p['BACKGROUND-IMAGE'])) {
14122 $pb['BACKGROUND-IMAGE'] = $p['BACKGROUND-IMAGE'];
14124 if (isset($p['BACKGROUND-IMAGE-RESIZE'])) {
14125 $pb['BACKGROUND-IMAGE-RESIZE'] = $p['BACKGROUND-IMAGE-RESIZE'];
14127 if (isset($p['BACKGROUND-IMAGE-OPACITY'])) {
14128 $pb['BACKGROUND-IMAGE-OPACITY'] = $p['BACKGROUND-IMAGE-OPACITY'];
14130 if (isset($p['BACKGROUND-REPEAT'])) {
14131 $pb['BACKGROUND-REPEAT'] = $p['BACKGROUND-REPEAT'];
14133 if (isset($p['BACKGROUND-POSITION'])) {
14134 $pb['BACKGROUND-POSITION'] = $p['BACKGROUND-POSITION'];
14136 if (isset($p['BACKGROUND-GRADIENT'])) {
14137 $pb['BACKGROUND-GRADIENT'] = $p['BACKGROUND-GRADIENT'];
14139 if (isset($p['BACKGROUND-SIZE'])) {
14140 $pb['BACKGROUND-SIZE'] = $p['BACKGROUND-SIZE'];
14142 if (isset($p['BACKGROUND-ORIGIN'])) {
14143 $pb['BACKGROUND-ORIGIN'] = $p['BACKGROUND-ORIGIN'];
14145 if (isset($p['BACKGROUND-CLIP'])) {
14146 $pb['BACKGROUND-CLIP'] = $p['BACKGROUND-CLIP'];
14149 /* -- END BACKGROUNDS -- */
14151 $this->setCSS($pb, 'BLOCK', $tag);
14154 $bbox_br = $this->blk[1]['border_right']['w'];
14155 $bbox_bl = $this->blk[1]['border_left']['w'];
14156 $bbox_bt = $this->blk[1]['border_top']['w'];
14157 $bbox_bb = $this->blk[1]['border_bottom']['w'];
14158 $bbox_pr = $this->blk[1]['padding_right'];
14159 $bbox_pl = $this->blk[1]['padding_left'];
14160 $bbox_pt = $this->blk[1]['padding_top'];
14161 $bbox_pb = $this->blk[1]['padding_bottom'];
14162 $bbox_mr = $this->blk[1]['margin_right'];
14163 if (isset($p['MARGIN-RIGHT']) && strtolower($p['MARGIN-RIGHT']) == 'auto') {
14166 $bbox_ml = $this->blk[1]['margin_left'];
14167 if (isset($p['MARGIN-LEFT']) && strtolower($p['MARGIN-LEFT']) == 'auto') {
14170 $bbox_mt = $this->blk[1]['margin_top'];
14171 if (isset($p['MARGIN-TOP']) && strtolower($p['MARGIN-TOP']) == 'auto') {
14174 $bbox_mb = $this->blk[1]['margin_bottom'];
14175 if (isset($p['MARGIN-BOTTOM']) && strtolower($p['MARGIN-BOTTOM']) == 'auto') {
14179 $bbox_left = $this->sizeConverter->convert($p['LEFT'], $cont_w, $this->FontSize, false);
14184 $bbox_top = $this->sizeConverter->convert($p['TOP'], $cont_h, $this->FontSize, false);
14189 $bbox_right = $this->sizeConverter->convert($p['RIGHT'], $cont_w, $this->FontSize, false);
14194 $bbox_bottom = $this->sizeConverter->convert($p['BOTTOM'], $cont_h, $this->FontSize, false);
14199 $inner_w = $this->sizeConverter->convert($p['WIDTH'], $cont_w, $this->FontSize, false);
14204 $inner_h = $this->sizeConverter->convert($p['HEIGHT'], $cont_h, $this->FontSize, false);
14209 // If bottom or right pos are set and not left / top - save this to adjust rotated block later
14210 if ($rotate == 90 || $rotate == -90) { // mPDF 6
14228 $inner_w = 2 * $this->GetCharWidth('W', false);
14231 // Algorithm from CSS2.1 See http://www.w3.org/TR/CSS21/visudet.html#abs-non-replaced-height
14243 $bbox_top = $orig_y0 - $bbox_mt - $cont_y;
14244 // solve for $bbox_bottom when content_h known - $inner_h=='auto' && $bbox_bottom=='auto'
14247 $bbox_top_orig = $bbox_top = $orig_y0 - $cont_y;
14254 // solve for $bbox_bottom when content_h known - $inner_h=='auto' && $bbox_bottom=='auto'
14257 $x = $cont_h - $bbox_top - $bbox_bt - $bbox_pt - $inner_h - $bbox_pb - $bbox_bb - $bbox_bottom;
14260 $bbox_mt = $cont_h - $bbox_top - $bbox_bt - $bbox_pt - $inner_h - $bbox_pb - $bbox_bb - $bbox_mb - $bbox_bottom;
14262 $bbox_mb = $cont_h - $bbox_top - $bbox_mt - $bbox_bt - $bbox_pt - $inner_h - $bbox_pb - $bbox_bb - $bbox_bottom;
14264 $bbox_bottom = $cont_h - $bbox_top - $bbox_mt - $bbox_bt - $bbox_pt - $inner_h - $bbox_pb - $bbox_bb - $bbox_mt;
14274 // solve for $bbox_top when content_h known - $inner_h=='auto' && $bbox_top =='auto'
14276 $bbox_top = $orig_y0 - $bbox_mt - $cont_y;
14277 $bbox_bottom = $cont_h - $bbox_top - $bbox_mt - $bbox_bt - $bbox_pt - $inner_h - $bbox_pb - $bbox_bb - $bbox_mt;
14279 // solve for $bbox_bottom when content_h known - $inner_h=='auto' && $bbox_bottom=='auto'
14281 $bbox_top = $cont_h - $bbox_mt - $bbox_bt - $bbox_pt - $inner_h - $bbox_pb - $bbox_bb - $bbox_mt - $bbox_bottom;
14283 $inner_h = $cont_h - $bbox_top - $bbox_mt - $bbox_bt - $bbox_pt - $bbox_pb - $bbox_bb - $bbox_mt - $bbox_bottom;
14285 $bbox_bottom = $cont_h - $bbox_top - $bbox_mt - $bbox_bt - $bbox_pt - $inner_h - $bbox_pb - $bbox_bb - $bbox_mt;
14290 // http://www.w3.org/TR/CSS21/visudet.html#abs-non-replaced-width
14299 $bbox_left = $orig_x0 - $bbox_ml - $cont_x;
14300 // solve for $bbox_right when content_w known - $inner_w=='auto' && $bbox_right=='auto'
14303 $x = $cont_w - $bbox_left - $bbox_bl - $bbox_pl - $inner_w - $bbox_pr - $bbox_br - $bbox_right;
14306 $bbox_ml = $cont_w - $bbox_left - $bbox_bl - $bbox_pl - $inner_w - $bbox_pr - $bbox_br - $bbox_mr - $bbox_right;
14308 $bbox_mr = $cont_w - $bbox_left - $bbox_ml - $bbox_bl - $bbox_pl - $inner_w - $bbox_pr - $bbox_br - $bbox_right;
14310 $bbox_right = $cont_w - $bbox_left - $bbox_ml - $bbox_bl - $bbox_pl - $inner_w - $bbox_pr - $bbox_br - $bbox_ml;
14320 // solve for $bbox_left when content_w known - $inner_w=='auto' && $bbox_left =='auto'
14323 $bbox_left = $orig_x0 - $bbox_ml - $cont_x;
14324 $bbox_right = $cont_w - $bbox_left - $bbox_ml - $bbox_bl - $bbox_pl - $inner_w - $bbox_pr - $bbox_br - $bbox_ml;
14326 // solve for $bbox_right when content_w known - $inner_w=='auto' && $bbox_right=='auto'
14328 $bbox_left = $cont_w - $bbox_ml - $bbox_bl - $bbox_pl - $inner_w - $bbox_pr - $bbox_br - $bbox_ml - $bbox_right;
14330 $inner_w = $cont_w - $bbox_left - $bbox_ml - $bbox_bl - $bbox_pl - $bbox_pr - $bbox_br - $bbox_ml - $bbox_right;
14332 $bbox_right = $cont_w - $bbox_left - $bbox_ml - $bbox_bl - $bbox_pl - $inner_w - $bbox_pr - $bbox_br - $bbox_ml;
14338 /* -- BACKGROUNDS -- */
14339 if (isset($pb['BACKGROUND-IMAGE']) && $pb['BACKGROUND-IMAGE']) {
14340 $ret = $this->SetBackground($pb, $this->blk[1]['inner_width']);
14342 $this->blk[1]['background-image'] = $ret;
14345 /* -- END BACKGROUNDS -- */
14358 $h = $cont_h - $bbox_top - $bbox_mt - $bbox_bt - $bbox_pt - $bbox_pb - $bbox_bb - $bbox_mb - $bbox_bottom;
14361 $w = $cont_w - $bbox_left - $bbox_ml - $bbox_bl - $bbox_pl - $bbox_pr - $bbox_br - $bbox_mr - $bbox_right;
14366 $h = $cont_h - ($bbox_bottom + $bbox_mt + $bbox_mb + $bbox_bt + $bbox_bb + $bbox_pt + $bbox_pb);
14369 $h = $cont_h - ($bbox_top + $bbox_mt + $bbox_mb + $bbox_bt + $bbox_bb + $bbox_pt + $bbox_pb);
14373 $w = $cont_w - ($bbox_right + $bbox_ml + $bbox_mr + $bbox_bl + $bbox_br + $bbox_pl + $bbox_pr);
14376 $w = $cont_w - ($bbox_left + $bbox_ml + $bbox_mr + $bbox_bl + $bbox_br + $bbox_pl + $bbox_pr);
14382 $saved_block1 = $this->blk[1];
14389 $this->lMargin = $x;
14390 $this->rMargin = $this->w - $w - $x;
14392 // SET POSITION & FONT VALUES
14393 $this->pgwidth = $this->w - $this->lMargin - $this->rMargin;
14394 $this->pageoutput[$this->page] = [];
14395 $this->x = $x;
14396 $this->y = $y;
14397 $this->HTMLheaderPageLinks = [];
14398 $this->HTMLheaderPageAnnots = [];
14399 $this->HTMLheaderPageForms = [];
14400 $this->pageBackgrounds = [];
14401 $this->maxPosR = 0;
14402 $this->maxPosL = $this->w; // For RTL
14403 $this->WriteHTML($html, HTMLParserMode::HTML_HEADER_BUFFER);
14404 $inner_w = $this->maxPosR - $this->lMargin;
14406 $bbox_right = $cont_w - $bbox_left - $bbox_ml - $bbox_bl - $bbox_pl - $inner_w - $bbox_pr - $bbox_br - $bbox_ml;
14408 $bbox_left = $cont_w - $bbox_ml - $bbox_bl - $bbox_pl - $inner_w - $bbox_pr - $bbox_br - $bbox_ml - $bbox_right;
14421 $this->lMargin = $x;
14422 $this->rMargin = $this->w - $w - $x;
14424 // SET POSITION & FONT VALUES
14425 $this->pgwidth = $this->w - $this->lMargin - $this->rMargin;
14426 $this->pageoutput[$this->page] = [];
14427 $this->x = $x;
14428 $this->y = $y;
14429 $this->HTMLheaderPageLinks = [];
14430 $this->HTMLheaderPageAnnots = [];
14431 $this->HTMLheaderPageForms = [];
14432 $this->pageBackgrounds = [];
14433 $this->WriteHTML($html, HTMLParserMode::HTML_HEADER_BUFFER);
14434 $inner_h = $this->y - $y;
14437 if (($this->y + $bbox_pb + $bbox_bb) > ($cont_y + $cont_h)) {
14438 $adj = ($this->y + $bbox_pb + $bbox_bb) - ($cont_y + $cont_h);
14439 $inner_h -= $adj;
14443 $bbox_bottom = $bbox_top = ($cont_h - $bbox_mt - $bbox_bt - $bbox_pt - $inner_h - $bbox_pb - $bbox_bb - $bbox_mb) / 2;
14447 $inner_h = $cont_h - $bbox_top - $bbox_mt - $bbox_bt - $bbox_pt - $bbox_pb - $bbox_bb - $bbox_mb - $bbox_bottom;
14454 $bbox_bottom = $cont_h - $bbox_top - $bbox_mt - $bbox_bt - $bbox_pt - $inner_h - $bbox_pb - $bbox_bb - $bbox_mb;
14456 $bbox_top = $cont_h - $bbox_mt - $bbox_bt - $bbox_pt - $inner_h - $bbox_pb - $bbox_bb - $bbox_mb - $bbox_bottom;
14460 $inner_h = $cont_h - $bbox_top - $bbox_mt - $bbox_bt - $bbox_pt - $bbox_pb - $bbox_bb - $bbox_mb - $bbox_bottom;
14476 $this->lMargin = $x;
14477 $this->rMargin = $this->w - $w - $x;
14479 // SET POSITION & FONT VALUES
14480 $this->pgwidth = $this->w - $this->lMargin - $this->rMargin;
14481 $this->pageoutput[$this->page] = [];
14483 $this->x = $x;
14484 $this->y = $y;
14486 $this->HTMLheaderPageLinks = [];
14487 $this->HTMLheaderPageAnnots = [];
14488 $this->HTMLheaderPageForms = [];
14490 $this->pageBackgrounds = [];
14492 $this->WriteHTML($html, HTMLParserMode::HTML_HEADER_BUFFER);
14494 $actual_h = $this->y - $y;
14503 $nl = ceil($actual_h / $this->lineheight);
14505 $est_w = sqrt(($l * $this->lineheight) / $target) * 0.8;
14506 $use_w += ($est_w - $use_w) - ($w / 100);
14512 // @log 'Auto-sizing fixed-position block $bpcctr++
14514 $this->x = $x;
14515 $this->y = $y;
14518 $use_w += ($w / $this->incrementFPR1);
14520 $use_w += ($w / $this->incrementFPR2);
14522 $use_w += ($w / $this->incrementFPR3);
14524 $use_w += ($w / $this->incrementFPR4);
14528 $this->rMargin = $this->w - $use_w - $x;
14529 $this->pgwidth = $this->w - $this->lMargin - $this->rMargin;
14530 $this->HTMLheaderPageLinks = [];
14531 $this->HTMLheaderPageAnnots = [];
14532 $this->HTMLheaderPageForms = [];
14533 $this->pageBackgrounds = [];
14534 $this->WriteHTML($html, HTMLParserMode::HTML_HEADER_BUFFER);
14535 $actual_h = $this->y - $y;
14545 $this->pages[$this->page] .= '___BEFORE_BORDERS___';
14546 $block_s = $this->PrintPageBackgrounds(); // Save to print later inside clipping path
14547 $this->pageBackgrounds = [];
14551 if ($rotate == 90 || $rotate == -90) { // mPDF 6
14563 $adjh = -$prerotw + $preroth;
14569 $adjw = $prerotw - $preroth;
14580 $rot_start .= $this->transformTranslate($adjw, $adjh, true) . "\n";
14581 $rot_start .= $this->transformRotate($rotate, $bbox_x, $bbox_y, true) . "\n";
14585 $rot_start .= $this->transformTranslate($bbox_bl + $bbox_pl + $inner_w + $bbox_pr + $bbox_br, $bbox_bt + $bbox_pt + $inner_h + $bbox_pb + $bbox_bb, true) . "\n";
14586 $rot_start .= $this->transformRotate(180, $bbox_x, $bbox_y, true) . "\n";
14595 // WHEN HEIGHT // BOTTOM EDGE IS KNOWN and $this->y is set to the bottom
14596 // Re-instate saved $this->blk[1]
14597 $this->blk[1] = $saved_block1;
14600 $this->blk[1]['width'] = $bbox_w = $cont_w - $bbox_left - $bbox_ml - $bbox_mr - $bbox_right;
14601 $this->blk[1]['x0'] = $bbox_x;
14602 $this->blk[1]['y0'] = $bbox_y;
14603 $this->blk[1]['startpage'] = $this->page;
14604 $this->blk[1]['y1'] = $bbox_y + $bbox_bt + $bbox_pt + $inner_h + $bbox_pb + $bbox_bb;
14605 $this->writer->write($rot_start);
14606 $this->PaintDivBB('', 0, 1); // Prints borders and sets backgrounds in $this->pageBackgrounds
14607 $this->writer->write($rot_end);
14610 $s = $this->PrintPageBackgrounds();
14612 $this->pages[$this->page] = preg_replace('/___BEFORE_BORDERS___/', "\n" . $s . "\n", $this->pages[$this->page]);
14613 $this->pageBackgrounds = [];
14615 $this->writer->write($rot_start);
14620 $clip_y1 = $this->y;
14621 if (!empty($bounding) && ($this->y + $bbox_pb + $bbox_bb) > ($bbox_y + $bbox_bt + $bbox_pt + $inner_h + $bbox_pb + $bbox_bb )) {
14622 $clip_y1 = ($bbox_y + $bbox_bt + $bbox_pt + $inner_h + $bbox_pb + $bbox_bb ) - ($bbox_pb + $bbox_bb);
14626 $this->writer->write("q");
14627 $ch = $clip_y1 - $y;
14628 $this->writer->write(sprintf('%.3F %.3F %.3F %.3F re %s', $x * Mpdf::SCALE, ($this->h - $y) * Mpdf::SCALE, $w * Mpdf::SCALE, -$ch * Mpdf::SCALE, $op));
14630 $tmp = "q\n" . sprintf('%.3F %.3F %.3F %.3F re %s', $x * Mpdf::SCALE, ($this->h - $y) * Mpdf::SCALE, $w * Mpdf::SCALE, -$ch * Mpdf::SCALE, $op);
14639 $tmp = "q\n" . $this->transformScale(($shrink_f * 100), ($shrink_f * 100), $x, $y, true);
14643 $this->writer->write($block_s);
14649 $this->StartTransform();
14650 $this->transformScale(($shrink_f * 100), ($shrink_f * 100), $x, $y);
14653 $this->writer->write($this->headerbuffer);
14656 $this->StopTransform();
14661 $this->writer->write("Q");
14664 $this->writer->write($rot_end);
14668 foreach ($this->HTMLheaderPageLinks as $lk) {
14670 $tmp = $lk[2]; // Switch h - w
14675 $ly1 = (($this->h - ($lk[1] / Mpdf::SCALE)));
14677 $adjx = -($lx1 - $bbox_x) + ($preroth - ($ly1 - $bbox_y));
14678 $adjy = -($ly1 - $bbox_y) + ($lx1 - $bbox_x);
14679 $lk[2] = -$lk[2];
14680 } elseif ($rotate == -90) {
14681 $adjx = -($lx1 - $bbox_x) + ($ly1 - $bbox_y);
14682 $adjy = -($ly1 - $bbox_y) - ($lx1 - $bbox_x) + $prerotw;
14683 $lk[3] = -$lk[3];
14686 $adjx += $prerotw - $preroth;
14689 $adjy += $preroth - $prerotw;
14695 $lk[1] = ($this->h - $ly1) * Mpdf::SCALE;
14698 $lx1 = (($lk[0] / Mpdf::SCALE) - $x);
14701 $ly1 = (($this->h - ($lk[1] / Mpdf::SCALE)) - $y);
14703 $lk[1] = ($this->h - $ly2) * Mpdf::SCALE;
14707 $this->PageLinks[$this->page][] = $lk;
14710 foreach ($this->HTMLheaderPageForms as $n => $f) {
14712 $f['x'] = $x + (($f['x'] - $x) * $shrink_f);
14713 $f['y'] = $y + (($f['y'] - $y) * $shrink_f);
14718 $this->form->forms[$f['n']] = $f;
14721 foreach ($this->HTMLheaderPageAnnots as $lk) {
14724 $adjx = -($lk['x'] - $bbox_x) + ($preroth - ($lk['y'] - $bbox_y));
14725 $adjy = -($lk['y'] - $bbox_y) + ($lk['x'] - $bbox_x);
14726 } elseif ($rotate == -90) {
14727 $adjx = -($lk['x'] - $bbox_x) + ($lk['y'] - $bbox_y);
14728 $adjy = -($lk['y'] - $bbox_y) - ($lk['x'] - $bbox_x) + $prerotw;
14731 $adjx += $prerotw - $preroth;
14734 $adjy += $preroth - $prerotw;
14740 $lk['x'] = $x + (($lk['x'] - $x) * $shrink_f);
14741 $lk['y'] = $y + (($lk['y'] - $y) * $shrink_f);
14743 $this->PageAnnots[$this->page][] = $lk;
14747 $this->headerbuffer = '';
14748 $this->HTMLheaderPageLinks = [];
14749 $this->HTMLheaderPageAnnots = [];
14750 $this->HTMLheaderPageForms = [];
14751 $this->pageBackgrounds = $save_bgs;
14752 $this->writingHTMLheader = false;
14754 $this->writingHTMLfooter = false;
14755 $this->fullImageHeight = false;
14756 $this->ResetMargins();
14757 $this->pgwidth = $this->w - $this->lMargin - $this->rMargin;
14758 $this->SetXY($save_x, $save_y);
14759 $this->title2annots = $save_annots; // *ANNOTATIONS*
14760 $this->InFooter = false; // turns back on autopagebreaks
14761 $this->pageoutput[$this->page] = [];
14762 $this->pageoutput[$this->page]['Font'] = '';
14763 /* -- COLUMNS -- */
14765 $this->SetColumns($save_nbcol, $this->colvAlign, $this->ColGap);
14767 /* -- END COLUMNS -- */
14770 /* -- END CSS-POSITION -- */
14791 $blk['block-align'] = false;
14804 if (isset($this->blk[$this->blklvl]['inner_width'])) {
14805 $refw = $this->blk[$this->blklvl]['inner_width'];
14806 } elseif (isset($this->blk[$this->blklvl - 1]['inner_width'])) {
14807 $refw = $this->blk[$this->blklvl - 1]['inner_width'];
14809 $refw = $this->w;
14812 $bsize = $this->sizeConverter->convert($prop[0], $refw, $this->FontSize, false);
14814 return ['s' => 1, 'w' => $bsize, 'c' => $this->colorConverter->convert(0, $this->PDFAXwarnings), 'style' => 'solid'];
14820 if (in_array($prop[1], $this->borderstyles) || $prop[1] == 'none' || $prop[1] == 'hidden') {
14823 elseif (in_array($prop[0], $this->borderstyles) || $prop[0] == 'none' || $prop[0] == 'hidden') {
14846 elseif (in_array($prop[0], $this->borderstyles) || $prop[0] == 'none' || $prop[0] == 'hidden') {
14854 // Size
14855 $bsize = $this->sizeConverter->convert($prop[0], $refw, $this->FontSize, false);
14857 $coul = $this->colorConverter->convert($prop[2], $this->PDFAXwarnings); // returns array
14860 if (in_array($prop[1], $this->borderstyles) && $bsize > 0) {
14879 /* -- END HTML-CSS -- */
14882 /* -- BORDER-RADIUS -- */
14889 $x = $a - $px;
14890 $y = $b - $py;
14900 $px = max($px, $a - $newx + $added);
14901 $py = max($py, $b - $newy + $added);
14904 /* -- END BORDER-RADIUS -- */
14905 /* -- HTML-CSS -- */
14906 /* -- CSS-PAGE -- */
14911 if ($this->directionality == 'rtl') {
14917 if ($this->directionality == 'rtl') {
14925 $p['SIZE'] = 'AUTO';
14928 $p['MARGIN-RIGHT'] = strval($this->orig_rMargin) . 'mm';
14929 $p['MARGIN-LEFT'] = strval($this->orig_lMargin) . 'mm';
14930 $p['MARGIN-TOP'] = strval($this->orig_tMargin) . 'mm';
14931 $p['MARGIN-BOTTOM'] = strval($this->orig_bMargin) . 'mm';
14932 $p['MARGIN-HEADER'] = strval($this->orig_hMargin) . 'mm';
14933 $p['MARGIN-FOOTER'] = strval($this->orig_fMargin) . 'mm';
14936 if (isset($this->cssManager->CSS['@PAGE'])) {
14937 $zp = $this->cssManager->CSS['@PAGE'];
14945 if (isset($p['EVEN-HEADER-NAME']) && $oddEven == 'E') {
14946 $p['HEADER'] = $p['EVEN-HEADER-NAME'];
14947 unset($p['EVEN-HEADER-NAME']);
14949 if (isset($p['ODD-HEADER-NAME']) && $oddEven != 'E') {
14950 $p['HEADER'] = $p['ODD-HEADER-NAME'];
14951 unset($p['ODD-HEADER-NAME']);
14953 if (isset($p['EVEN-FOOTER-NAME']) && $oddEven == 'E') {
14954 $p['FOOTER'] = $p['EVEN-FOOTER-NAME'];
14955 unset($p['EVEN-FOOTER-NAME']);
14957 if (isset($p['ODD-FOOTER-NAME']) && $oddEven != 'E') {
14958 $p['FOOTER'] = $p['ODD-FOOTER-NAME'];
14959 unset($p['ODD-FOOTER-NAME']);
14963 if (isset($this->cssManager->CSS['@PAGE>>PSEUDO>>RIGHT']) && $side == 'R') {
14964 $zp = $this->cssManager->CSS['@PAGE>>PSEUDO>>RIGHT'];
14968 if (isset($zp['SIZE'])) {
14969 unset($zp['SIZE']);
14971 if (isset($zp['SHEET-SIZE'])) {
14972 unset($zp['SHEET-SIZE']);
14974 // Disallow margin-left or -right on :LEFT or :RIGHT
14975 if (isset($zp['MARGIN-LEFT'])) {
14976 unset($zp['MARGIN-LEFT']);
14978 if (isset($zp['MARGIN-RIGHT'])) {
14979 unset($zp['MARGIN-RIGHT']);
14986 if (isset($this->cssManager->CSS['@PAGE>>PSEUDO>>LEFT']) && $side == 'L') {
14987 $zp = $this->cssManager->CSS['@PAGE>>PSEUDO>>LEFT'];
14991 if (isset($zp['SIZE'])) {
14992 unset($zp['SIZE']);
14994 if (isset($zp['SHEET-SIZE'])) {
14995 unset($zp['SHEET-SIZE']);
14997 // Disallow margin-left or -right on :LEFT or :RIGHT
14998 if (isset($zp['MARGIN-LEFT'])) {
14999 unset($zp['MARGIN-LEFT']);
15001 if (isset($zp['MARGIN-RIGHT'])) {
15002 unset($zp['MARGIN-RIGHT']);
15009 if (isset($this->cssManager->CSS['@PAGE>>PSEUDO>>FIRST']) && $first) {
15010 $zp = $this->cssManager->CSS['@PAGE>>PSEUDO>>FIRST'];
15014 if (isset($zp['SIZE'])) {
15015 unset($zp['SIZE']);
15017 if (isset($zp['SHEET-SIZE'])) {
15018 unset($zp['SHEET-SIZE']);
15020 // Disallow margin-left or -right on :FIRST // mPDF 5.7.3
15021 if (isset($zp['MARGIN-LEFT'])) {
15022 unset($zp['MARGIN-LEFT']);
15024 if (isset($zp['MARGIN-RIGHT'])) {
15025 unset($zp['MARGIN-RIGHT']);
15033 if (isset($this->cssManager->CSS['@PAGE>>NAMED>>' . $name])) {
15034 $zp = $this->cssManager->CSS['@PAGE>>NAMED>>' . $name];
15042 if (isset($p['EVEN-HEADER-NAME']) && $oddEven == 'E') {
15043 $p['HEADER'] = $p['EVEN-HEADER-NAME'];
15044 unset($p['EVEN-HEADER-NAME']);
15046 if (isset($p['ODD-HEADER-NAME']) && $oddEven != 'E') {
15047 $p['HEADER'] = $p['ODD-HEADER-NAME'];
15048 unset($p['ODD-HEADER-NAME']);
15050 if (isset($p['EVEN-FOOTER-NAME']) && $oddEven == 'E') {
15051 $p['FOOTER'] = $p['EVEN-FOOTER-NAME'];
15052 unset($p['EVEN-FOOTER-NAME']);
15054 if (isset($p['ODD-FOOTER-NAME']) && $oddEven != 'E') {
15055 $p['FOOTER'] = $p['ODD-FOOTER-NAME'];
15056 unset($p['ODD-FOOTER-NAME']);
15060 if (isset($this->cssManager->CSS['@PAGE>>NAMED>>' . $name . '>>PSEUDO>>RIGHT']) && $side == 'R') {
15061 $zp = $this->cssManager->CSS['@PAGE>>NAMED>>' . $name . '>>PSEUDO>>RIGHT'];
15065 if (isset($zp['SIZE'])) {
15066 unset($zp['SIZE']);
15068 if (isset($zp['SHEET-SIZE'])) {
15069 unset($zp['SHEET-SIZE']);
15071 // Disallow margin-left or -right on :LEFT or :RIGHT
15072 if (isset($zp['MARGIN-LEFT'])) {
15073 unset($zp['MARGIN-LEFT']);
15075 if (isset($zp['MARGIN-RIGHT'])) {
15076 unset($zp['MARGIN-RIGHT']);
15083 if (isset($this->cssManager->CSS['@PAGE>>NAMED>>' . $name . '>>PSEUDO>>LEFT']) && $side == 'L') {
15084 $zp = $this->cssManager->CSS['@PAGE>>NAMED>>' . $name . '>>PSEUDO>>LEFT'];
15088 if (isset($zp['SIZE'])) {
15089 unset($zp['SIZE']);
15091 if (isset($zp['SHEET-SIZE'])) {
15092 unset($zp['SHEET-SIZE']);
15094 // Disallow margin-left or -right on :LEFT or :RIGHT
15095 if (isset($zp['MARGIN-LEFT'])) {
15096 unset($zp['MARGIN-LEFT']);
15098 if (isset($zp['MARGIN-RIGHT'])) {
15099 unset($zp['MARGIN-RIGHT']);
15106 if (isset($this->cssManager->CSS['@PAGE>>NAMED>>' . $name . '>>PSEUDO>>FIRST']) && $first) {
15107 $zp = $this->cssManager->CSS['@PAGE>>NAMED>>' . $name . '>>PSEUDO>>FIRST'];
15111 if (isset($zp['SIZE'])) {
15112 unset($zp['SIZE']);
15114 if (isset($zp['SHEET-SIZE'])) {
15115 unset($zp['SHEET-SIZE']);
15117 // Disallow margin-left or -right on :FIRST // mPDF 5.7.3
15118 if (isset($zp['MARGIN-LEFT'])) {
15119 unset($zp['MARGIN-LEFT']);
15121 if (isset($zp['MARGIN-RIGHT'])) {
15122 unset($zp['MARGIN-RIGHT']);
15138 if (isset($p['SHEET-SIZE']) && is_array($p['SHEET-SIZE'])) {
15139 $newformat = $p['SHEET-SIZE'];
15146 $this->_setPageSize($newformat, $p['ORIENTATION']);
15149 if (isset($p['SIZE']) && is_array($p['SIZE']) && !$newformat) {
15150 if ($p['SIZE']['W'] > $p['SIZE']['H']) {
15156 if (is_array($p['SIZE'])) {
15157 if ($p['SIZE']['W'] > $this->fw) {
15158 $p['SIZE']['W'] = $this->fw;
15160 if ($p['SIZE']['H'] > $this->fh) {
15161 $p['SIZE']['H'] = $this->fh;
15163 if (($p['ORIENTATION'] == $this->DefOrientation && !$newformat) || ($newformat && $p['ORIENTATION'] == 'P')) {
15164 $outer_width_LR = ($this->fw - $p['SIZE']['W']) / 2;
15165 $outer_width_TB = ($this->fh - $p['SIZE']['H']) / 2;
15167 $outer_width_LR = ($this->fh - $p['SIZE']['W']) / 2;
15168 $outer_width_TB = ($this->fw - $p['SIZE']['H']) / 2;
15170 $pgw = $p['SIZE']['W'];
15171 $pgh = $p['SIZE']['H'];
15176 if (strtoupper($p['SIZE']) == 'AUTO') {
15177 $p['ORIENTATION'] = $this->DefOrientation;
15178 } elseif (strtoupper($p['SIZE']) == 'LANDSCAPE') {
15184 if (($p['ORIENTATION'] == $this->DefOrientation && !$newformat) || ($newformat && $p['ORIENTATION'] == 'P')) {
15185 $pgw = $this->fw;
15186 $pgh = $this->fh;
15188 $pgw = $this->fh;
15189 $pgh = $this->fw;
15219 if (isset($p['BACKGROUND-COLOR']) && $p['BACKGROUND-COLOR']) {
15220 $bg['BACKGROUND-COLOR'] = $p['BACKGROUND-COLOR'];
15222 /* -- BACKGROUNDS -- */
15223 if (isset($p['BACKGROUND-GRADIENT']) && $p['BACKGROUND-GRADIENT']) {
15224 $bg['BACKGROUND-GRADIENT'] = $p['BACKGROUND-GRADIENT'];
15226 if (isset($p['BACKGROUND-IMAGE']) && $p['BACKGROUND-IMAGE']) {
15227 $bg['BACKGROUND-IMAGE'] = $p['BACKGROUND-IMAGE'];
15229 if (isset($p['BACKGROUND-REPEAT']) && $p['BACKGROUND-REPEAT']) {
15230 $bg['BACKGROUND-REPEAT'] = $p['BACKGROUND-REPEAT'];
15232 if (isset($p['BACKGROUND-POSITION']) && $p['BACKGROUND-POSITION']) {
15233 $bg['BACKGROUND-POSITION'] = $p['BACKGROUND-POSITION'];
15235 if (isset($p['BACKGROUND-IMAGE-RESIZE']) && $p['BACKGROUND-IMAGE-RESIZE']) {
15236 $bg['BACKGROUND-IMAGE-RESIZE'] = $p['BACKGROUND-IMAGE-RESIZE'];
15238 if (isset($p['BACKGROUND-IMAGE-OPACITY'])) {
15239 $bg['BACKGROUND-IMAGE-OPACITY'] = $p['BACKGROUND-IMAGE-OPACITY'];
15241 /* -- END BACKGROUNDS -- */
15243 if (isset($p['MARGIN-LEFT'])) {
15244 $mgl = $this->sizeConverter->convert($p['MARGIN-LEFT'], $pgw) + $outer_width_LR;
15246 if (isset($p['MARGIN-RIGHT'])) {
15247 $mgr = $this->sizeConverter->convert($p['MARGIN-RIGHT'], $pgw) + $outer_width_LR;
15249 if (isset($p['MARGIN-BOTTOM'])) {
15250 $mgb = $this->sizeConverter->convert($p['MARGIN-BOTTOM'], $pgh) + $outer_width_TB;
15252 if (isset($p['MARGIN-TOP'])) {
15253 $mgt = $this->sizeConverter->convert($p['MARGIN-TOP'], $pgh) + $outer_width_TB;
15255 if (isset($p['MARGIN-HEADER'])) {
15256 $mgh = $this->sizeConverter->convert($p['MARGIN-HEADER'], $pgh) + $outer_width_TB;
15258 if (isset($p['MARGIN-FOOTER'])) {
15259 $mgf = $this->sizeConverter->convert($p['MARGIN-FOOTER'], $pgh) + $outer_width_TB;
15265 $this->page_box['outer_width_LR'] = $outer_width_LR; // Used in MARKS:crop etc.
15266 $this->page_box['outer_width_TB'] = $outer_width_TB;
15271 /* -- END CSS-PAGE -- */
15275 /* -- CSS-FLOAT -- */
15277 // Added mPDF 3.0 Float DIV - CLEAR
15280 list($l_exists, $r_exists, $l_max, $r_max, $l_width, $r_width) = $this->GetFloatDivInfo($blklvl, true);
15281 $end = $currpos = ($this->page * 1000 + $this->y);
15283 $this->pageoutput[$this->page] = [];
15286 $this->pageoutput[$this->page] = [];
15289 $this->pageoutput[$this->page] = [];
15294 $old_page = $this->page;
15297 $s = $this->PrintPageBackgrounds();
15299 $this->pages[$this->page] = preg_replace('/(___BACKGROUND___PATTERNS' . $this->uniqstr . ')/', '\\1' . "\n" . $s . "\n", $this->pages[$this->page]);
15300 $this->pageBackgrounds = [];
15301 $this->page = $new_page;
15303 $this->ResetMargins();
15304 $this->pageoutput[$this->page] = [];
15306 $this->y = (round($end * 1000) % 1000000) / 1000; // mod changes operands to integers before processing
15312 // If blklvl specified, only returns floats at that level - for ClearFloats
15319 if (count($this->floatDivs)) {
15320 $currpos = ($this->page * 1000 + $this->y);
15321 foreach ($this->floatDivs as $f) {
15322 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'])) {
15339 /* -- END CSS-FLOAT -- */
15344 // if position:inside (and NOT table) - output now as a textbuffer; (so if next is block, will move to new line)
15345 // elseif position:outside (and NOT table) - output in front of first textbuffer output by setting listitem (cf. _saveTextBuffer)
15347 $this->listitem = '';
15376 $objattr['vertical-align'] = 'BS'; // vertical alignment of marker (baseline)
15381 $info = $this->imageProcessor->getImage($srcpath, true, true, $orig_srcpath);
15387 $info['h'] = $this->sizeConverter->convert('1em', $this->blk[$this->blklvl]['inner_width'], $this->FontSize, false);
15394 /* -- IMAGES-WMF -- */
15401 } else { /* -- END IMAGES-WMF -- */
15408 $w = ($info['w'] / Mpdf::SCALE) * (72 / $this->img_dpi);
15409 $h = ($info['h'] / Mpdf::SCALE) * (72 / $this->img_dpi);
15437 /* -- IMAGES-WMF -- */
15441 } else { /* -- END IMAGES-WMF -- */
15453 $objattr['dir'] = (isset($this->blk[$this->blklvl]['direction']) ? $this->blk[$this->blklvl]['direction'] : 'ltr');
15459 $this->_saveTextBuffer($e);
15463 $this->_saveTextBuffer($e);
15465 } elseif ($listitemtype == 'disc' || $listitemtype == 'circle' || $listitemtype == 'square') { // SYMBOL (needs new font)
15470 $size = $this->sizeConverter->convert($this->list_symbol_size, $this->FontSize);
15471 $objattr['size'] = $size;
15472 $objattr['offset'] = $this->sizeConverter->convert($this->list_marker_offset, $this->FontSize);
15475 $objattr['width'] = $size + $objattr['offset'];
15478 $objattr['height'] = $this->FontSize;
15479 $objattr['vertical-align'] = 'T';
15481 $objattr['dir'] = (isset($this->blk[$this->blklvl]['direction']) ? $this->blk[$this->blklvl]['direction'] : 'ltr');
15483 $objattr['colorarray'] = $this->colorarray;
15484 $objattr['fontfamily'] = $this->FontFamily;
15485 $objattr['fontsize'] = $this->FontSize;
15486 $objattr['fontsizept'] = $this->FontSizePt;
15487 $objattr['fontstyle'] = $this->FontStyle;
15490 $this->listitem = $this->_saveTextBuffer($e, '', '', true); // true returns array
15492 } elseif (preg_match('/U\+([a-fA-F0-9]+)/i', $listitemtype, $m)) { // SYMBOL 2 (needs new font)
15494 if ($this->_charDefined($this->CurrentFont['cw'], hexdec($m[1]))) {
15497 $list_item_marker = '-';
15500 $list_item_color = $this->colorConverter->convert($m[0], $this->PDFAXwarnings);
15506 $save_colorarray = $this->colorarray;
15508 $this->colorarray = $list_item_color;
15513 $this->_saveTextBuffer($e);
15518 $objattr['height'] = $this->FontSize;
15519 $objattr['vertical-align'] = 'T';
15521 $objattr['dir'] = (isset($this->blk[$this->blklvl]['direction']) ? $this->blk[$this->blklvl]['direction'] : 'ltr');
15522 $objattr['colorarray'] = $this->colorarray;
15523 $objattr['fontfamily'] = $this->FontFamily;
15524 $objattr['fontsize'] = $this->FontSize;
15525 $objattr['fontsizept'] = $this->FontSizePt;
15526 $objattr['fontstyle'] = $this->FontStyle;
15528 $this->listitem = $this->_saveTextBuffer($e, '', '', true); // true returns array
15532 $this->colorarray = $save_colorarray;
15535 $counter = $this->listcounter[$this->listlvl];
15541 $num = $this->_getStyledNumber($counter, $listitemtype, true);
15544 $e = $num . $this->list_number_suffix . $spacer;
15545 $this->_saveTextBuffer($e);
15547 if (isset($this->blk[$this->blklvl]['direction']) && $this->blk[$this->blklvl]['direction'] == 'rtl') {
15548 // REPLACE MIRRORED RTL $this->list_number_suffix e.g. ) -> ( (NB could use Ucdn::$mirror_pairs)
15549 $m = strtr($this->list_number_suffix, ")]}", "([{") . $num;
15551 $m = $num . $this->list_number_suffix;
15557 $objattr['height'] = $this->FontSize;
15558 $objattr['vertical-align'] = 'T';
15560 $objattr['dir'] = (isset($this->blk[$this->blklvl]['direction']) ? $this->blk[$this->blklvl]['direction'] : 'ltr');
15561 $objattr['colorarray'] = $this->colorarray;
15562 $objattr['fontfamily'] = $this->FontFamily;
15563 $objattr['fontsize'] = $this->FontSize;
15564 $objattr['fontsizept'] = $this->FontSizePt;
15565 $objattr['fontstyle'] = $this->FontStyle;
15568 $this->listitem = $this->_saveTextBuffer($e, '', '', true); // true returns array
15578 $markeroffset = $this->sizeConverter->convert($this->list_marker_offset, $this->FontSize);
15581 $maxnum = $this->listcounter[$this->listlvl];
15595 $lvl--;
15620 $blt_width = $this->GetStringWidth(str_repeat('5', strlen($maxnum)) . $this->list_number_suffix);
15625 case 'upper-alpha':
15626 case 'upper-latin':
15628 $maxnumA = $decToAlpha->convert($maxnum, true);
15630 $blt_width = $this->GetStringWidth('D' . $this->list_number_suffix);
15632 $blt_width = $this->GetStringWidth(str_repeat('W', strlen($maxnumA)) . $this->list_number_suffix);
15635 case 'lower-alpha':
15636 case 'lower-latin':
15638 $maxnuma = $decToAlpha->convert($maxnum, false);
15640 $blt_width = $this->GetStringWidth('b' . $this->list_number_suffix);
15642 $blt_width = $this->GetStringWidth(str_repeat('m', strlen($maxnuma)) . $this->list_number_suffix);
15645 case 'upper-roman':
15673 $maxlnum = $decToRoman->convert($bbit, true);
15674 $blt_width = $this->GetStringWidth($maxlnum . $this->list_number_suffix);
15677 case 'lower-roman':
15704 $maxlnum = $decToRoman->convert($bbit, false);
15705 $blt_width = $this->GetStringWidth($maxlnum . $this->list_number_suffix);
15711 $size = $this->sizeConverter->convert($this->list_symbol_size, $this->FontSize);
15712 $offset = $this->sizeConverter->convert($this->list_marker_offset, $this->FontSize);
15713 $blt_width = $size + $offset;
15716 case 'arabic-indic':
15717 $blt_width = $this->GetStringWidth(str_repeat($decToOther->convert(3, 0x0660), strlen($maxnum)) . $this->list_number_suffix);
15721 $blt_width = $this->GetStringWidth(str_repeat($decToOther->convert(3, 0x06F0), strlen($maxnum)) . $this->list_number_suffix);
15724 $blt_width = $this->GetStringWidth(str_repeat($decToOther->convert(3, 0x09E6), strlen($maxnum)) . $this->list_number_suffix);
15727 $blt_width = $this->GetStringWidth(str_repeat($decToOther->convert(3, 0x0966), strlen($maxnum)) . $this->list_number_suffix);
15730 $blt_width = $this->GetStringWidth(str_repeat($decToOther->convert(3, 0x0AE6), strlen($maxnum)) . $this->list_number_suffix);
15733 $blt_width = $this->GetStringWidth(str_repeat($decToOther->convert(3, 0x0A66), strlen($maxnum)) . $this->list_number_suffix);
15736 $blt_width = $this->GetStringWidth(str_repeat($decToOther->convert(3, 0x0CE6), strlen($maxnum)) . $this->list_number_suffix);
15739 $blt_width = $this->GetStringWidth(str_repeat($decToOther->convert(6, 0x0D66), strlen($maxnum)) . $this->list_number_suffix);
15742 $blt_width = $this->GetStringWidth(str_repeat($decToOther->convert(3, 0x0B66), strlen($maxnum)) . $this->list_number_suffix);
15745 $blt_width = $this->GetStringWidth(str_repeat($decToOther->convert(3, 0x0C66), strlen($maxnum)) . $this->list_number_suffix);
15748 $blt_width = $this->GetStringWidth(str_repeat($decToOther->convert(9, 0x0BE6), strlen($maxnum)) . $this->list_number_suffix);
15751 $blt_width = $this->GetStringWidth(str_repeat($decToOther->convert(5, 0x0E50), strlen($maxnum)) . $this->list_number_suffix);
15754 $blt_width = $this->GetStringWidth(str_repeat('5', strlen($maxnum)) . $this->list_number_suffix);
15769 $arr[2] = $this->currentfontstyle;
15770 if (isset($this->colorarray) && $this->colorarray) {
15771 $arr[3] = $this->colorarray;
15773 $arr[4] = $this->currentfontfamily;
15774 $arr[5] = $this->currentLang; // mPDF 6
15782 if (isset($this->OTLtags['Plus']) && strpos($this->OTLtags['Plus'], 'kern') !== false && empty($this->OTLdata['GPOSinfo'])) {
15783 $this->textvar = ($this->textvar | TextVars::FC_KERNING);
15785 $arr[8] = $this->textvar; // mPDF 5.7.1
15786 if (isset($this->textparam) && $this->textparam) {
15787 $arr[9] = $this->textparam;
15789 if (isset($this->spanbgcolorarray) && $this->spanbgcolorarray) {
15790 $arr[10] = $this->spanbgcolorarray;
15792 $arr[11] = $this->currentfontsize;
15793 if (isset($this->ReqFontStyle) && $this->ReqFontStyle) {
15794 $arr[12] = $this->ReqFontStyle;
15796 if (isset($this->lSpacingCSS) && $this->lSpacingCSS) {
15797 $arr[14] = $this->lSpacingCSS;
15799 if (isset($this->wSpacingCSS) && $this->wSpacingCSS) {
15800 $arr[15] = $this->wSpacingCSS;
15802 if (isset($this->spanborddet) && $this->spanborddet) {
15803 $arr[16] = $this->spanborddet;
15805 if (isset($this->textshadow) && $this->textshadow) {
15806 $arr[17] = $this->textshadow;
15808 if (isset($this->OTLdata) && $this->OTLdata) {
15809 $arr[18] = $this->OTLdata;
15810 $this->OTLdata = [];
15819 if ($this->listitem) {
15820 $this->textbuffer[] = $this->listitem;
15821 $this->listitem = [];
15823 $this->textbuffer[] = $arr;
15833 $arr[2] = $this->currentfontstyle;
15834 if (isset($this->colorarray) && $this->colorarray) {
15835 $arr[3] = $this->colorarray;
15837 $arr[4] = $this->currentfontfamily;
15845 if (isset($this->OTLtags['Plus']) && strpos($this->OTLtags['Plus'], 'kern') !== false && empty($this->OTLdata['GPOSinfo'])) {
15846 $this->textvar = ($this->textvar | TextVars::FC_KERNING);
15848 $arr[8] = $this->textvar; // mPDF 5.7.1
15849 if (isset($this->textparam) && $this->textparam) {
15850 $arr[9] = $this->textparam;
15852 if (isset($this->spanbgcolorarray) && $this->spanbgcolorarray) {
15853 $arr[10] = $this->spanbgcolorarray;
15855 $arr[11] = $this->currentfontsize;
15856 if (isset($this->ReqFontStyle) && $this->ReqFontStyle) {
15857 $arr[12] = $this->ReqFontStyle;
15859 if (isset($this->lSpacingCSS) && $this->lSpacingCSS) {
15860 $arr[14] = $this->lSpacingCSS;
15862 if (isset($this->wSpacingCSS) && $this->wSpacingCSS) {
15863 $arr[15] = $this->wSpacingCSS;
15865 if (isset($this->spanborddet) && $this->spanborddet) {
15866 $arr[16] = $this->spanborddet;
15868 if (isset($this->textshadow) && $this->textshadow) {
15869 $arr[17] = $this->textshadow;
15871 if (isset($this->OTLdata) && $this->OTLdata) {
15872 $arr[18] = $this->OTLdata;
15873 $this->OTLdata = [];
15878 $this->cell[$this->row][$this->col]['textbuffer'][] = $arr;
15887 $this->spanbgcolorarray = '';
15888 $this->spanbgcolor = false;
15889 $this->spanborder = false;
15890 $this->spanborddet = [];
15892 /* -- CSS-FLOAT -- */
15893 if (count($this->floatDivs)) {
15894 list($l_exists, $r_exists, $l_max, $r_max, $l_width, $r_width) = $this->GetFloatDivInfo($this->blklvl);
15895 if (($this->blk[$this->blklvl]['inner_width'] - $l_width - $r_width) < (2 * $this->GetCharWidth('W', false))) {
15896 // Too narrow to fit - try to move down past L or R float
15897 if ($l_max < $r_max && ($this->blk[$this->blklvl]['inner_width'] - $r_width) > (2 * $this->GetCharWidth('W', false))) {
15898 $this->ClearFloats('LEFT', $this->blklvl);
15899 } elseif ($r_max < $l_max && ($this->blk[$this->blklvl]['inner_width'] - $l_width) > (2 * $this->GetCharWidth('W', false))) {
15900 $this->ClearFloats('RIGHT', $this->blklvl);
15902 $this->ClearFloats('BOTH', $this->blklvl);
15906 /* -- END CSS-FLOAT -- */
15907 $bak_y = $this->y;
15908 $bak_x = $this->x;
15911 if (isset($this->blk[$this->blklvl]['align']) && $this->blk[$this->blklvl]['align']) {
15912 $align = $this->blk[$this->blklvl]['align'];
15914 // Block-align is set by e.g. <.. align="center"> Takes priority for this block but not inherited
15915 if (isset($this->blk[$this->blklvl]['block-align']) && $this->blk[$this->blklvl]['block-align']) {
15916 $align = $this->blk[$this->blklvl]['block-align'];
15918 if (isset($this->blk[$this->blklvl]['direction'])) {
15919 $blockdir = $this->blk[$this->blklvl]['direction'];
15923 $this->divwidth = $this->blk[$this->blklvl]['width'];
15925 $align = $this->cellTextAlign;
15928 $oldpage = $this->page;
15931 if ($this->divwidth == 0) {
15932 $this->divwidth = $this->pgwidth;
15936 $this->SetLineHeight($this->FontSizePt, $this->blk[$this->blklvl]['line_height']);
15938 $this->divheight = $this->lineheight;
15939 $old_height = $this->divheight;
15941 // As a failsafe - if font has been set but not output to page
15943 $this->SetFont($this->default_font, '', $this->default_font_size, true, true); // force output to page
15946 $this->newFlowingBlock($this->divwidth, $this->divheight, $align, $is_table, $blockstate, true, $blockdir, $table_draft);
15950 // Added - Otherwise <div><div><p> did not output top margins/padding for 1st/2nd div
15952 $this->finishFlowingBlock(true);
15962 $unicode = $this->UTF8StringToArray($arrayaux[$i][0], false);
15965 $this->getBasicOTLdata($arrayaux[$i][18], $unicode, $is_strong);
15967 // Gets messed up if try and use core fonts inside a paragraph of text which needs to be BiDi re-ordered or OTLdata set
15968 if (($blockdir == 'rtl' || $this->biDirectional) && isset($arrayaux[$i][4]) && in_array($arrayaux[$i][4], ['ccourier', 'ctimes', 'chelvetica', 'csymbol', 'czapfdingbats'])) {
15973 // Process bidirectional text ready for bidi-re-ordering (which is done after line-breaks are established in WriteFlowingBlock etc.)
15974 if (($blockdir == 'rtl' || $this->biDirectional) && !$table_draft) {
15975 if (empty($this->otl)) {
15976 $this->otl = new Otl($this, $this->fontCache);
15978 $this->otl->bidiPrepare($arrayaux, $blockdir);
15984 for ($i = $array_size - 1; $i > 0; $i--) {
15998 ((!isset($arrayaux[$i][9]['bord-decoration']) && !isset($arrayaux[$i - 1][9]['bord-decoration'])) ||
15999 (isset($arrayaux[$i][9]['bord-decoration']) && isset($arrayaux[$i - 1][9]['bord-decoration']) && $arrayaux[$i][9]['bord-decoration'] == $arrayaux[$i - 1][9]['bord-decoration'])
16009 $arrayaux[$i - 1][16]['R']['s'] = 0;
16010 $arrayaux[$i - 1][16]['R']['w'] = 0;
16022 $oldcolumn = $this->CurrCol;
16024 if ($i == 0 && $vetor[0] != "\n" && ! $this->ispre) {
16027 $this->otl->trimOTLdata($vetor[18], true, false);
16034 if ($i == ($array_size - 1)) {
16035 $this->finishFlowingBlock(true);
16042 if (isset($vetor[11]) && $vetor[11] != '') { // Font Size
16043 if ($is_table && $this->shrin_k) {
16044 $this->SetFontSize($vetor[11] / $this->shrin_k, false);
16046 $this->SetFontSize($vetor[11], false);
16051 $this->textshadow = $vetor[17];
16054 $this->spanborddet = $vetor[16];
16055 $this->spanborder = true;
16059 $this->wSpacingCSS = $vetor[15];
16060 if ($this->wSpacingCSS && strtoupper($this->wSpacingCSS) != 'NORMAL') {
16061 $this->minwSpacing = $this->sizeConverter->convert($this->wSpacingCSS, $this->FontSize) / $this->shrin_k; // mPDF 5.7.3
16065 $this->lSpacingCSS = $vetor[14];
16066 if (($this->lSpacingCSS || $this->lSpacingCSS === '0') && strtoupper($this->lSpacingCSS) != 'NORMAL') {
16067 $this->fixedlSpacing = $this->sizeConverter->convert($this->lSpacingCSS, $this->FontSize) / $this->shrin_k; // mPDF 5.7.3
16073 $this->spanbgcolorarray = $vetor[10];
16074 $this->spanbgcolor = true;
16076 if (isset($vetor[9]) and ! empty($vetor[9])) { // Text parameters - Outline + hyphens
16077 $this->textparam = $vetor[9];
16078 $this->SetTextOutline($this->textparam);
16079 // mPDF 5.7.3 inline text-decoration parameters
16080 if ($is_table && $this->shrin_k) {
16081 if (isset($this->textparam['text-baseline'])) {
16082 $this->textparam['text-baseline'] /= $this->shrin_k;
16084 if (isset($this->textparam['decoration-baseline'])) {
16085 $this->textparam['decoration-baseline'] /= $this->shrin_k;
16087 if (isset($this->textparam['decoration-fontsize'])) {
16088 $this->textparam['decoration-fontsize'] /= $this->shrin_k;
16093 $this->textvar = $vetor[8];
16096 $ily = $this->y;
16097 if ($this->table_rotate) {
16098 $this->internallink[$vetor[7]] = ["Y" => $ily, "PAGE" => $this->page, "tbrot" => true];
16099 } elseif ($this->kwt) {
16100 $this->internallink[$vetor[7]] = ["Y" => $ily, "PAGE" => $this->page, "kwt" => true];
16101 } elseif ($this->ColActive) {
16102 $this->internallink[$vetor[7]] = ["Y" => $ily, "PAGE" => $this->page, "col" => $this->CurrCol];
16103 } elseif (!$this->keep_block_together) {
16104 $this->internallink[$vetor[7]] = ["Y" => $ily, "PAGE" => $this->page];
16108 if ($i == ($array_size - 1)) {
16109 $this->finishFlowingBlock(true);
16115 $this->currentLang = $vetor[5];
16117 if (isset($vetor[4]) and $vetor[4] != '') { // Font Family
16118 $font = $this->SetFont($vetor[4], $this->FontStyle, 0, false);
16120 if (!empty($vetor[3])) { // Font Color
16122 $this->SetTColor($cor);
16125 $this->SetStyles($vetor[2]);
16129 $this->ReqFontStyle = $vetor[12];
16134 while (array_key_exists($vetor[1], $this->internallink)) {
16137 $this->internallink[$vetor[1]] = $this->AddLink();
16138 $vetor[1] = $this->internallink[$vetor[1]];
16140 $this->HREF = $vetor[1]; // HREF link style set here ******
16143 // SPECIAL CONTENT - IMAGES & FORM OBJECTS
16144 // Print-out special content
16147 $objattr = $this->_getObjAttr($vetor[0]);
16149 /* -- TABLES -- */
16153 $table = &$this->table[$level][$objattr['table']];
16156 $this->y += $this->table[($level + 1)][$objattr['nestedcontent']]['h']; // nested table height
16157 $this->finishFlowingBlock(false, 'nestedtable');
16160 $this->finishFlowingBlock(false, 'nestedtable');
16161 $save_dw = $this->divwidth;
16162 $save_buffer = $this->cellBorderBuffer;
16163 $this->cellBorderBuffer = [];
16164 $ncx = $this->x;
16165 list($dummyx, $w) = $this->_tableGetWidth($table, $objattr['row'], $objattr['col']);
16166 $ntw = $this->table[($level + 1)][$objattr['nestedcontent']]['w']; // nested table width
16167 if (!$this->simpleTables) {
16168 if ($this->packTableData) {
16169 list($bt, $br, $bb, $bl) = $this->_getBorderWidths($cell['borderbin']);
16175 $innerw = $w - $bl - $br - $cell['padding']['L'] - $cell['padding']['R'] - $table['border_spacing_H'];
16177 $innerw = $w - $bl / 2 - $br / 2 - $cell['padding']['L'] - $cell['padding']['R'];
16179 } elseif ($this->simpleTables) {
16181 $innerw = $w - $table['simple']['border_details']['L']['w'] - $table['simple']['border_details']['R']['w'] - $cell['padding']['L'] - $cell['padding']['R'] - $table['border_spacing_H'];
16183 $innerw = $w - $table['simple']['border_details']['L']['w'] / 2 - $table['simple']['border_details']['R']['w'] / 2 - $cell['padding']['L'] - $cell['padding']['R'];
16186 if ($cell['a'] == 'C' || $this->table[($level + 1)][$objattr['nestedcontent']]['a'] == 'C') {
16187 $ncx += ($innerw - $ntw) / 2;
16188 } elseif ($cell['a'] == 'R' || $this->table[($level + 1)][$objattr['nestedcontent']]['a'] == 'R') {
16189 $ncx += $innerw - $ntw;
16191 $this->x = $ncx;
16193 $this->_tableWrite($this->table[($level + 1)][$objattr['nestedcontent']]);
16194 $this->cellBorderBuffer = $save_buffer;
16195 $this->x = $bak_x;
16196 $this->divwidth = $save_dw;
16199 $this->newFlowingBlock($this->divwidth, $this->divheight, $align, $is_table, $blockstate, false, $blockdir, $table_draft);
16202 /* -- END TABLES -- */
16204 $maxWidth = $this->divwidth; // *TABLES*
16207 $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']);
16210 /* -- CSS-IMAGE-FLOAT -- */
16212 if (isset($this->floatmargins['R']) && $this->y <= $this->floatmargins['R']['y1'] && $this->y >= $this->floatmargins['R']['y0']) {
16213 $maxWidth -= $this->floatmargins['R']['w'];
16215 if (isset($this->floatmargins['L']) && $this->y <= $this->floatmargins['L']['y1'] && $this->y >= $this->floatmargins['L']['y0']) {
16216 $maxWidth -= $this->floatmargins['L']['w'];
16218 /* -- END CSS-IMAGE-FLOAT -- */
16220 list($skipln) = $this->inlineObject($objattr['type'], '', $this->y, $objattr, $this->lMargin, ($this->flowingBlockAttr['contentWidth'] / Mpdf::SCALE), $maxWidth, $this->flowingBlockAttr['height'], false, $is_table);
16221 // 1 -> New line needed because of width
16222 // -1 -> Will fit width on line but NEW PAGE REQUIRED because of height
16223 // -2 -> Will not fit on line therefore needs new line but thus NEW PAGE REQUIRED
16224 $iby = $this->y;
16225 $oldpage = $this->page;
16226 $oldcol = $this->CurrCol;
16227 if (($skipln == 1 || $skipln == -2) && !isset($objattr['float'])) {
16228 $this->finishFlowingBlock(false, $objattr['type']);
16229 $this->newFlowingBlock($this->divwidth, $this->divheight, $align, $is_table, $blockstate, false, $blockdir, $table_draft);
16233 $thispage = $this->page;
16234 if ($this->CurrCol != $oldcol) {
16241 if (!$changedcol && $skipln < 0 && $this->AcceptPageBreak() && $thispage == $oldpage) {
16242 $this->AddPage($this->CurOrientation);
16246 if (count($this->objectbuffer)) {
16247 $yadj = $iby - $this->y;
16248 foreach ($this->objectbuffer as $ib => $val) {
16249 if ($this->objectbuffer[$ib]['OUTER-Y']) {
16250 $this->objectbuffer[$ib]['OUTER-Y'] -= $yadj;
16252 if ($this->objectbuffer[$ib]['BORDER-Y']) {
16253 $this->objectbuffer[$ib]['BORDER-Y'] -= $yadj;
16255 if ($this->objectbuffer[$ib]['INNER-Y']) {
16256 $this->objectbuffer[$ib]['INNER-Y'] -= $yadj;
16263 if ($this->page != $oldpage) {
16264 if (($this->page - $oldpage) % 2 == 1) {
16265 $bak_x += $this->MarginCorrection;
16267 $oldpage = $this->page;
16268 $y = $this->tMargin - $paint_ht_corr;
16269 $this->oldy = $this->tMargin - $paint_ht_corr;
16272 $this->x = $bak_x;
16273 /* -- COLUMNS -- */
16276 if ($this->CurrCol != $oldcolumn) {
16277 if ($this->directionality == 'rtl') { // *OTL*
16278 $bak_x -= ($this->CurrCol - $oldcolumn) * ($this->ColWidth + $this->ColGap); // *OTL*
16281 $bak_x += ($this->CurrCol - $oldcolumn) * ($this->ColWidth + $this->ColGap);
16283 $this->x = $bak_x;
16284 $oldcolumn = $this->CurrCol;
16285 $y = $this->y0 - $paint_ht_corr;
16286 $this->oldy = $this->y0 - $paint_ht_corr;
16289 /* -- END COLUMNS -- */
16292 /* -- CSS-IMAGE-FLOAT -- */
16294 $fy = $this->y;
16297 if ($this->flowingBlockAttr['newblock'] && ($this->flowingBlockAttr['blockstate'] == 1 || $this->flowingBlockAttr['blockstate'] == 3) && $this->flowingBlockAttr['lineCount'] == 0) {
16298 $fy += $this->blk[$this->blklvl]['margin_top'] + $this->blk[$this->blklvl]['padding_top'] + $this->blk[$this->blklvl]['border_top']['w'];
16302 $fx = $this->w - $this->rMargin - $objattr['width'] - ($this->blk[$this->blklvl]['outer_right_margin'] + $this->blk[$this->blklvl]['border_right']['w'] + $this->blk[$this->blklvl]['padding_right']);
16304 $fx = $this->lMargin + ($this->blk[$this->blklvl]['outer_left_margin'] + $this->blk[$this->blklvl]['border_left']['w'] + $this->blk[$this->blklvl]['padding_left']);
16309 $widthLeft = $maxWidth - ($this->flowingBlockAttr['contentWidth'] / Mpdf::SCALE);
16310 $maxHeight = $this->h - ($this->tMargin + $this->margin_header + $this->bMargin + 10);
16317 $info = $this->formobjects[$file];
16320 $info = $this->images[$file];
16322 $img_w = $w - $extraWidth;
16323 $img_h = $h - $extraHeight;
16325 $objattr['BORDER-WIDTH'] = $img_w + (($objattr['border_left']['w'] + $objattr['border_right']['w']) / 2);
16326 $objattr['BORDER-HEIGHT'] = $img_h + (($objattr['border_top']['w'] + $objattr['border_bottom']['w']) / 2);
16327 $objattr['BORDER-X'] = $fx + $objattr['margin_left'] + (($objattr['border_left']['w']) / 2);
16328 $objattr['BORDER-Y'] = $fy + $objattr['margin_top'] + (($objattr['border_top']['w']) / 2);
16330 $objattr['INNER-WIDTH'] = $img_w;
16331 $objattr['INNER-HEIGHT'] = $img_h;
16332 $objattr['INNER-X'] = $fx + $objattr['margin_left'] + ($objattr['border_left']['w']);
16333 $objattr['INNER-Y'] = $fy + $objattr['margin_top'] + ($objattr['border_top']['w']);
16335 $objattr['OUTER-WIDTH'] = $w;
16336 $objattr['OUTER-HEIGHT'] = $h;
16337 $objattr['OUTER-X'] = $fx;
16338 $objattr['OUTER-Y'] = $fy;
16341 $this->floatmargins['R']['skipline'] = false;
16342 if (isset($this->floatmargins['R']['y1']) && $this->floatmargins['R']['y1'] > 0 && $fy < $this->floatmargins['R']['y1']) {
16343 $this->WriteFlowingBlock($vetor[0], $vetor[18]); // mPDF 5.7.1
16345 elseif (isset($this->floatmargins['L']['y1']) && $this->floatmargins['L']['y1'] > 0 && $fy < $this->floatmargins['L']['y1']) {
16347 $mw = 2 * $this->GetCharWidth('W', false);
16348 if (($this->blk[$this->blklvl]['inner_width'] - $w - $this->floatmargins['L']['w']) < $mw) {
16349 $this->WriteFlowingBlock($vetor[0], $vetor[18]); // mPDF 5.7.1
16351 $this->floatmargins['R']['x'] = $fx;
16352 $this->floatmargins['R']['w'] = $w;
16353 $this->floatmargins['R']['y0'] = $fy;
16354 $this->floatmargins['R']['y1'] = $fy + $h;
16356 $this->floatmargins['R']['skipline'] = true;
16357 $this->floatmargins['R']['id'] = count($this->floatbuffer) + 0;
16360 $this->floatbuffer[] = $objattr;
16363 $this->floatmargins['R']['x'] = $fx;
16364 $this->floatmargins['R']['w'] = $w;
16365 $this->floatmargins['R']['y0'] = $fy;
16366 $this->floatmargins['R']['y1'] = $fy + $h;
16368 $this->floatmargins['R']['skipline'] = true;
16369 $this->floatmargins['R']['id'] = count($this->floatbuffer) + 0;
16372 $this->floatbuffer[] = $objattr;
16376 $this->floatmargins['L']['skipline'] = false;
16377 if (isset($this->floatmargins['L']['y1']) && $this->floatmargins['L']['y1'] > 0 && $fy < $this->floatmargins['L']['y1']) {
16378 $this->floatmargins['L']['skipline'] = false;
16379 $this->WriteFlowingBlock($vetor[0], $vetor[18]); // mPDF 5.7.1
16381 elseif (isset($this->floatmargins['R']['y1']) && $this->floatmargins['R']['y1'] > 0 && $fy < $this->floatmargins['R']['y1']) {
16383 $mw = 2 * $this->GetCharWidth('W', false);
16384 if (($this->blk[$this->blklvl]['inner_width'] - $w - $this->floatmargins['R']['w']) < $mw) {
16385 $this->WriteFlowingBlock($vetor[0], $vetor[18]); // mPDF 5.7.1
16387 $this->floatmargins['L']['x'] = $fx + $w;
16388 $this->floatmargins['L']['w'] = $w;
16389 $this->floatmargins['L']['y0'] = $fy;
16390 $this->floatmargins['L']['y1'] = $fy + $h;
16392 $this->floatmargins['L']['skipline'] = true;
16393 $this->floatmargins['L']['id'] = count($this->floatbuffer) + 0;
16396 $this->floatbuffer[] = $objattr;
16399 $this->floatmargins['L']['x'] = $fx + $w;
16400 $this->floatmargins['L']['w'] = $w;
16401 $this->floatmargins['L']['y0'] = $fy;
16402 $this->floatmargins['L']['y1'] = $fy + $h;
16404 $this->floatmargins['L']['skipline'] = true;
16405 $this->floatmargins['L']['id'] = count($this->floatbuffer) + 0;
16408 $this->floatbuffer[] = $objattr;
16412 /* -- END CSS-IMAGE-FLOAT -- */
16413 $this->WriteFlowingBlock($vetor[0], (isset($vetor[18]) ? $vetor[18] : null)); // mPDF 5.7.1
16414 /* -- CSS-IMAGE-FLOAT -- */
16416 /* -- END CSS-IMAGE-FLOAT -- */
16420 if ($this->tableLevel) {
16424 $paint_ht_corr = $this->blk[$this->blklvl]['border_top']['w'];
16428 if ($this->flowingBlockAttr['content']) {
16429 $this->finishFlowingBlock(false, 'br');
16431 $this->y+= $this->_computeLineheight($this->cellLineHeight);
16433 $this->DivLn($this->lineheight);
16434 if ($this->ColActive) {
16435 $this->breakpoints[$this->CurrCol][] = $this->y;
16439 if ($this->page != $oldpage) {
16440 if (($this->page - $oldpage) % 2 == 1) {
16441 $bak_x += $this->MarginCorrection;
16443 $oldpage = $this->page;
16444 $y = $this->tMargin - $paint_ht_corr;
16445 $this->oldy = $this->tMargin - $paint_ht_corr;
16448 $this->x = $bak_x;
16449 /* -- COLUMNS -- */
16452 if ($this->CurrCol != $oldcolumn) {
16453 if ($this->directionality == 'rtl') { // *OTL*
16454 $bak_x -= ($this->CurrCol - $oldcolumn) * ($this->ColWidth + $this->ColGap); // *OTL*
16457 $bak_x += ($this->CurrCol - $oldcolumn) * ($this->ColWidth + $this->ColGap);
16459 $this->x = $bak_x;
16460 $oldcolumn = $this->CurrCol;
16461 $y = $this->y0 - $paint_ht_corr;
16462 $this->oldy = $this->y0 - $paint_ht_corr;
16465 /* -- END COLUMNS -- */
16466 $this->newFlowingBlock($this->divwidth, $this->divheight, $align, $is_table, $blockstate, false, $blockdir, $table_draft);
16468 $this->WriteFlowingBlock($vetor[0], $vetor[18]); // mPDF 5.7.1
16470 if ($this->page != $oldpage) {
16471 if (($this->page - $oldpage) % 2 == 1) {
16472 $bak_x += $this->MarginCorrection;
16473 $this->x = $bak_x;
16475 $oldpage = $this->page;
16476 $y = $this->tMargin - $paint_ht_corr;
16477 $this->oldy = $this->tMargin - $paint_ht_corr;
16480 /* -- COLUMNS -- */
16483 if ($this->CurrCol != $oldcolumn) {
16484 if ($this->directionality == 'rtl') { // *OTL*
16485 $bak_x -= ($this->CurrCol - $oldcolumn) * ($this->ColWidth + $this->ColGap); // *OTL*
16488 $bak_x += ($this->CurrCol - $oldcolumn) * ($this->ColWidth + $this->ColGap);
16490 $this->x = $bak_x;
16491 $oldcolumn = $this->CurrCol;
16492 $y = $this->y0 - $paint_ht_corr;
16493 $this->oldy = $this->y0 - $paint_ht_corr;
16496 /* -- END COLUMNS -- */
16501 if ($i == ($array_size - 1)) {
16502 $this->finishFlowingBlock(true); // true = END of flowing block
16504 if ($this->page != $oldpage) {
16505 if (($this->page - $oldpage) % 2 == 1) {
16506 $bak_x += $this->MarginCorrection;
16507 $this->x = $bak_x;
16509 $oldpage = $this->page;
16510 $y = $this->tMargin - $paint_ht_corr;
16511 $this->oldy = $this->tMargin - $paint_ht_corr;
16515 /* -- COLUMNS -- */
16518 if ($this->CurrCol != $oldcolumn) {
16519 if ($this->directionality == 'rtl') { // *OTL*
16520 $bak_x -= ($this->CurrCol - $oldcolumn) * ($this->ColWidth + $this->ColGap); // *OTL*
16523 $bak_x += ($this->CurrCol - $oldcolumn) * ($this->ColWidth + $this->ColGap);
16525 $this->x = $bak_x;
16526 $oldcolumn = $this->CurrCol;
16527 $y = $this->y0 - $paint_ht_corr;
16528 $this->oldy = $this->y0 - $paint_ht_corr;
16531 /* -- END COLUMNS -- */
16535 $this->SetTColor($this->colorConverter->convert(0, $this->PDFAXwarnings));
16536 $this->SetDColor($this->colorConverter->convert(0, $this->PDFAXwarnings));
16537 $this->SetFColor($this->colorConverter->convert(255, $this->PDFAXwarnings));
16538 $this->colorarray = '';
16539 $this->spanbgcolorarray = '';
16540 $this->spanbgcolor = false;
16541 $this->spanborder = false;
16542 $this->spanborddet = [];
16543 $this->HREF = '';
16544 $this->textparam = [];
16545 $this->SetTextOutline();
16547 $this->textvar = 0x00; // mPDF 5.7.1
16548 $this->OTLtags = [];
16549 $this->textshadow = '';
16551 $this->currentfontfamily = '';
16552 $this->currentfontsize = '';
16553 $this->currentfontstyle = '';
16554 $this->currentLang = $this->default_lang; // mPDF 6
16555 $this->RestrictUnicodeFonts($this->default_available_fonts); // mPDF 6
16556 /* -- TABLES -- */
16557 if ($this->tableLevel) {
16558 $this->SetLineHeight('', $this->table[1][1]['cellLineHeight']); // *TABLES*
16559 } else { /* -- END TABLES -- */
16560 if (isset($this->blk[$this->blklvl]['line_height']) && $this->blk[$this->blklvl]['line_height']) {
16561 $this->SetLineHeight('', $this->blk[$this->blklvl]['line_height']); // sets default line height
16564 $this->ResetStyles();
16565 $this->lSpacingCSS = '';
16566 $this->wSpacingCSS = '';
16567 $this->fixedlSpacing = false;
16568 $this->minwSpacing = 0;
16569 $this->SetDash();
16570 $this->dash_on = false;
16571 $this->dotted_on = false;
16574 $this->Reset(); // mPDF 6
16576 if ((isset($this->blk[$this->blklvl]['border']) || isset($this->blk[$this->blklvl]['bgcolor']) || isset($this->blk[$this->blklvl]['box_shadow'])) && $blockstate && ($this->y != $this->oldy)) {
16577 $bottom_y = $this->y; // Does not include Bottom Margin
16578 if (isset($this->blk[$this->blklvl]['startpage']) && $this->blk[$this->blklvl]['startpage'] != $this->page && $blockstate != 1) {
16579 $this->PaintDivBB('pagetop', $blockstate);
16581 $this->PaintDivBB('', $blockstate);
16583 $this->y = $bottom_y;
16584 $this->x = $bak_x;
16587 // Reset Font
16588 $this->SetFontSize($this->default_font_size, false);
16590 $ch = $this->y - $bak_y;
16591 $this->y = $bak_y;
16592 $this->x = $bak_x;
16602 $this->SetDash($dashsize, ($dashsize / $dashsizek) + ($this->LineWidth * 2));
16605 $this->SetLineJoin(1);
16606 $this->SetLineCap(1);
16607 $this->SetDash(0.001, ($this->LineWidth * 3));
16613 $this->SetLineWidth($b['w'] / $k);
16614 $this->SetDColor($b['c']);
16616 $this->SetAlpha(ord($b['c'][4]) / 100, 'Normal', false, 'S'); // mPDF 5.7.2
16618 $this->SetAlpha(ord($b['c'][5]) / 100, 'Normal', false, 'S'); // mPDF 5.7.2
16624 // Borders & backgrounds are done elsewhere for columns - messes up the repositioning in printcolumnbuffer
16625 if ($this->ColActive) {
16628 if ($this->keep_block_together) {
16631 $save_y = $this->y;
16633 $blvl = $this->blklvl;
16638 if (isset($this->blk[$blvl]['bb_painted'][$this->page]) && $this->blk[$blvl]['bb_painted'][$this->page]) {
16640 } // *CSS-FLOAT*
16642 if (isset($this->blk[$blvl]['x0'])) {
16643 $x0 = $this->blk[$blvl]['x0'];
16645 if (isset($this->blk[$blvl]['y1'])) {
16646 $y1 = $this->blk[$blvl]['y1'];
16648 // Added mPDF 3.0 Float DIV - ensures backgrounds/borders are drawn to bottom of page
16651 $y1 = $this->h - $this->bMargin;
16653 $y1 = $this->y;
16657 $continuingpage = (isset($this->blk[$blvl]['startpage']) && $this->blk[$blvl]['startpage'] != $this->page);
16659 if (isset($this->blk[$blvl]['y0'])) {
16660 $y0 = $this->blk[$blvl]['y0'];
16662 $h = $y1 - $y0;
16663 $w = $this->blk[$blvl]['width'];
16666 // Set border-widths as used here
16667 $border_top = $this->blk[$blvl]['border_top']['w'];
16668 $border_bottom = $this->blk[$blvl]['border_bottom']['w'];
16669 $border_left = $this->blk[$blvl]['border_left']['w'];
16670 $border_right = $this->blk[$blvl]['border_right']['w'];
16671 if (!$this->blk[$blvl]['border_top'] || $divider == 'pagetop' || $continuingpage) {
16674 if (!$this->blk[$blvl]['border_bottom'] || $blockstate == 1 || $divider == 'pagebottom') {
16688 /* -- BORDER-RADIUS -- */
16689 if (isset($this->blk[$blvl]['border_radius_TL_H'])) {
16690 $brTL_H = $this->blk[$blvl]['border_radius_TL_H'];
16693 if (isset($this->blk[$blvl]['border_radius_TL_V'])) {
16694 $brTL_V = $this->blk[$blvl]['border_radius_TL_V'];
16697 if (isset($this->blk[$blvl]['border_radius_TR_H'])) {
16698 $brTR_H = $this->blk[$blvl]['border_radius_TR_H'];
16701 if (isset($this->blk[$blvl]['border_radius_TR_V'])) {
16702 $brTR_V = $this->blk[$blvl]['border_radius_TR_V'];
16705 if (isset($this->blk[$blvl]['border_radius_BR_H'])) {
16706 $brBR_H = $this->blk[$blvl]['border_radius_BR_H'];
16709 if (isset($this->blk[$blvl]['border_radius_BR_V'])) {
16710 $brBR_V = $this->blk[$blvl]['border_radius_BR_V'];
16713 if (isset($this->blk[$blvl]['border_radius_BL_H'])) {
16714 $brBL_H = $this->blk[$blvl]['border_radius_BL_H'];
16717 if (isset($this->blk[$blvl]['border_radius_BL_V'])) {
16718 $brBL_V = $this->blk[$blvl]['border_radius_BL_V'];
16722 if (!$this->blk[$blvl]['border_top'] || $divider == 'pagetop' || $continuingpage) {
16728 if (!$this->blk[$blvl]['border_bottom'] || $blockstate == 1 || $divider == 'pagebottom') {
16735 // Disallow border-radius if it is smaller than the border width.
16773 /* -- END BORDER-RADIUS -- */
16775 $tbcol = $this->colorConverter->convert(255, $this->PDFAXwarnings);
16777 if ($this->blk[$l]['bgcolor']) {
16778 $tbcol = $this->blk[$l]['bgcolorarray'];
16783 if (isset($this->blk[$blvl]['y0']) && $this->blk[$blvl]['y0']) {
16784 $y0 = $this->blk[$blvl]['y0'];
16786 $h = $y1 - $y0;
16787 $w = $this->blk[$blvl]['width'];
16789 if ($this->blk[$blvl]['border_top'] && $divider != 'pagetop' && !$continuingpage) {
16790 $tbd = $this->blk[$blvl]['border_top'];
16796 if (isset($this->blk[$blvl]['border_legend']) && $this->blk[$blvl]['border_legend']) {
16797 $legend = $this->blk[$blvl]['border_legend']; // Same structure array as textbuffer
16800 $this->otl->trimOTLdata($legend[18], true, false);
16802 // Set font, size, style, color
16803 $this->SetFont($legend[4], $legend[2], $legend[11]);
16806 $this->SetTColor($cor);
16808 $stringWidth = $this->GetStringWidth($txt, true, $legend[18], $legend[8]);
16809 $save_x = $this->x;
16810 $save_y = $this->y;
16811 $save_currentfontfamily = $this->FontFamily;
16812 $save_currentfontsize = $this->FontSizePt;
16813 $save_currentfontstyle = $this->FontStyle;
16814 $this->y = $y0 - $this->FontSize / 2 + $this->blk[$blvl]['border_top']['w'] / 2;
16815 $this->x = $x0 + $this->blk[$blvl]['padding_left'] + $this->blk[$blvl]['border_left']['w'];
16818 $gap = 0.2 * $this->FontSize;
16819 $legbreakL = $this->x - $gap;
16820 $legbreakR = $this->x + $stringWidth + $gap;
16821 $this->magic_reverse_dir($txt, $this->blk[$blvl]['direction'], $legend[18]);
16823 $this->Cell($stringWidth, $this->FontSize, $txt, '', 0, 'C', $fill, '', 0, 0, 0, 'M', $fill, false, $legend[18], $legend[8]);
16825 $this->x = $save_x;
16826 $this->y = $save_y;
16827 $this->SetFont($save_currentfontfamily, $save_currentfontstyle, $save_currentfontsize);
16828 $this->SetTColor($this->colorConverter->convert(0, $this->PDFAXwarnings));
16833 $this->writer->write('q');
16834 $this->SetLineWidth(0);
16835 $this->writer->write(sprintf('%.3F %.3F m ', ($x0) * Mpdf::SCALE, ($this->h - ($y0)) * Mpdf::SCALE));
16836 $this->writer->write(sprintf('%.3F %.3F l ', ($x0 + $border_left) * Mpdf::SCALE, ($this->h - ($y0 + $border_top)) * Mpdf::SCALE));
16837 $this->writer->write(sprintf('%.3F %.3F l ', ($x0 + $w - $border_right) * Mpdf::SCALE, ($this->h - ($y0 + $border_top)) * Mpdf::SCALE));
16838 $this->writer->write(sprintf('%.3F %.3F l ', ($x0 + $w) * Mpdf::SCALE, ($this->h - ($y0)) * Mpdf::SCALE));
16839 $this->writer->write(' h W n '); // Ends path no-op & Sets the clipping path
16842 $this->_setBorderLine($tbd);
16844 $legbreakL -= $border_top / 2; // because line cap different
16846 $this->_setDashBorder($tbd['style'], $divider, $continuingpage, 'T');
16847 } /* -- BORDER-RADIUS -- */ elseif (($brTL_V && $brTL_H) || ($brTR_V && $brTR_H) || $tbd['style'] == 'solid' || $tbd['style'] == 'double') {
16848 $this->SetLineJoin(0);
16849 $this->SetLineCap(0);
16853 $s .= ($this->_EllipseArc($x0 + $w - $brTR_H, $y0 + $brTR_V, $brTR_H - $border_top / 2, $brTR_V - $border_top / 2, 1, 2, true)) . "\n";
16854 } else { /* -- END BORDER-RADIUS -- */
16856 $s .= (sprintf('%.3F %.3F m ', ($x0 + $w) * Mpdf::SCALE, ($this->h - ($y0 + ($border_top / 2))) * Mpdf::SCALE)) . "\n";
16858 $s .= (sprintf('%.3F %.3F m ', ($x0 + $w - ($border_top / 2)) * Mpdf::SCALE, ($this->h - ($y0 + ($border_top / 2))) * Mpdf::SCALE)) . "\n";
16861 /* -- BORDER-RADIUS -- */
16864 if ($legbreakR < ($x0 + $w - $brTR_H)) {
16865 $s .= (sprintf('%.3F %.3F l ', $legbreakR * Mpdf::SCALE, ($this->h - ($y0 + ($border_top / 2))) * Mpdf::SCALE)) . "\n";
16868 $s .= (sprintf('%.3F %.3F m ', $legbreakL * Mpdf::SCALE, ($this->h - ($y0 + ($border_top / 2))) * Mpdf::SCALE)) . "\n";
16869 $s .= (sprintf('%.3F %.3F l ', ($x0 + $brTL_H ) * Mpdf::SCALE, ($this->h - ($y0 + ($border_top / 2))) * Mpdf::SCALE) . "\n");
16871 $s .= (sprintf('%.3F %.3F m ', ($x0 + $brTL_H ) * Mpdf::SCALE, ($this->h - ($y0 + ($border_top / 2))) * Mpdf::SCALE)) . "\n";
16874 $s .= (sprintf('%.3F %.3F l ', ($x0 + $brTL_H ) * Mpdf::SCALE, ($this->h - ($y0 + ($border_top / 2))) * Mpdf::SCALE)) . "\n";
16876 $s .= ($this->_EllipseArc($x0 + $brTL_H, $y0 + $brTL_V, $brTL_H - $border_top / 2, $brTL_V - $border_top / 2, 2, 1)) . "\n";
16878 /* -- END BORDER-RADIUS -- */
16881 $s .= (sprintf('%.3F %.3F l ', $legbreakR * Mpdf::SCALE, ($this->h - ($y0 + ($border_top / 2))) * Mpdf::SCALE)) . "\n";
16884 $s .= (sprintf('%.3F %.3F m ', $legbreakL * Mpdf::SCALE, ($this->h - ($y0 + ($border_top / 2))) * Mpdf::SCALE)) . "\n";
16886 $s .= (sprintf('%.3F %.3F l ', ($x0) * Mpdf::SCALE, ($this->h - ($y0 + ($border_top / 2))) * Mpdf::SCALE)) . "\n";
16888 $s .= (sprintf('%.3F %.3F l ', ($x0 + ($border_top / 2)) * Mpdf::SCALE, ($this->h - ($y0 + ($border_top / 2))) * Mpdf::SCALE)) . "\n";
16891 $s .= (sprintf('%.3F %.3F m ', ($x0) * Mpdf::SCALE, ($this->h - ($y0 + ($border_top / 2))) * Mpdf::SCALE)) . "\n";
16893 $s .= (sprintf('%.3F %.3F m ', ($x0 + $border_top / 2) * Mpdf::SCALE, ($this->h - ($y0 + ($border_top / 2))) * Mpdf::SCALE)) . "\n";
16896 $s .= (sprintf('%.3F %.3F l ', ($x0) * Mpdf::SCALE, ($this->h - ($y0 + ($border_top / 2))) * Mpdf::SCALE)) . "\n";
16898 $s .= (sprintf('%.3F %.3F l ', ($x0 + ($border_top / 2)) * Mpdf::SCALE, ($this->h - ($y0 + ($border_top / 2))) * Mpdf::SCALE)) . "\n";
16900 /* -- BORDER-RADIUS -- */
16902 /* -- END BORDER-RADIUS -- */
16904 $this->writer->write($s);
16907 $this->SetLineWidth($tbd['w'] / 3);
16908 $this->SetDColor($tbcol);
16909 $this->writer->write($s);
16912 $this->writer->write('Q');
16916 $this->SetLineWidth(0.1);
16917 $this->SetDColor($this->colorConverter->convert(0, $this->PDFAXwarnings));
16918 $this->SetLineJoin(2);
16919 $this->SetLineCap(2);
16920 $this->SetDash();
16926 if ($this->blk[$blvl]['border_bottom'] && $blockstate != 1 && $divider != 'pagebottom') {
16927 $tbd = $this->blk[$blvl]['border_bottom'];
16930 $this->writer->write('q');
16931 $this->SetLineWidth(0);
16932 $this->writer->write(sprintf('%.3F %.3F m ', ($x0) * Mpdf::SCALE, ($this->h - ($y0 + $h)) * Mpdf::SCALE));
16933 $this->writer->write(sprintf('%.3F %.3F l ', ($x0 + $border_left) * Mpdf::SCALE, ($this->h - ($y0 + $h - $border_bottom)) * Mpdf::SCALE));
16934 $this->writer->write(sprintf('%.3F %.3F l ', ($x0 + $w - $border_right) * Mpdf::SCALE, ($this->h - ($y0 + $h - $border_bottom)) * Mpdf::SCALE));
16935 $this->writer->write(sprintf('%.3F %.3F l ', ($x0 + $w) * Mpdf::SCALE, ($this->h - ($y0 + $h)) * Mpdf::SCALE));
16936 $this->writer->write(' h W n '); // Ends path no-op & Sets the clipping path
16939 $this->_setBorderLine($tbd);
16941 $this->_setDashBorder($tbd['style'], $divider, $continuingpage, 'B');
16942 } /* -- BORDER-RADIUS -- */ elseif (($brBL_V && $brBL_H) || ($brBR_V && $brBR_H) || $tbd['style'] == 'solid' || $tbd['style'] == 'double') {
16943 $this->SetLineJoin(0);
16944 $this->SetLineCap(0);
16948 $s .= ($this->_EllipseArc($x0 + $brBL_H, $y0 + $h - $brBL_V, $brBL_H - $border_bottom / 2, $brBL_V - $border_bottom / 2, 3, 2, true)) . "\n";
16949 } else { /* -- END BORDER-RADIUS -- */
16951 $s .= (sprintf('%.3F %.3F m ', ($x0) * Mpdf::SCALE, ($this->h - ($y0 + $h - ($border_bottom / 2))) * Mpdf::SCALE)) . "\n";
16953 $s .= (sprintf('%.3F %.3F m ', ($x0 + ($border_bottom / 2)) * Mpdf::SCALE, ($this->h - ($y0 + $h - ($border_bottom / 2))) * Mpdf::SCALE)) . "\n";
16956 /* -- BORDER-RADIUS -- */
16958 $s .= (sprintf('%.3F %.3F l ', ($x0 + $w - ($border_bottom / 2) - $brBR_H ) * Mpdf::SCALE, ($this->h - ($y0 + $h - ($border_bottom / 2))) * Mpdf::SCALE)) . "\n";
16959 $s .= ($this->_EllipseArc($x0 + $w - $brBR_H, $y0 + $h - $brBR_V, $brBR_H - $border_bottom / 2, $brBR_V - $border_bottom / 2, 4, 1)) . "\n";
16960 } else { /* -- END BORDER-RADIUS -- */
16962 $s .= (sprintf('%.3F %.3F l ', ($x0 + $w) * Mpdf::SCALE, ($this->h - ($y0 + $h - ($border_bottom / 2))) * Mpdf::SCALE)) . "\n";
16964 $s .= (sprintf('%.3F %.3F l ', ($x0 + $w - ($border_bottom / 2)) * Mpdf::SCALE, ($this->h - ($y0 + $h - ($border_bottom / 2))) * Mpdf::SCALE)) . "\n";
16968 $this->writer->write($s);
16971 $this->SetLineWidth($tbd['w'] / 3);
16972 $this->SetDColor($tbcol);
16973 $this->writer->write($s);
16976 $this->writer->write('Q');
16980 $this->SetLineWidth(0.1);
16981 $this->SetDColor($this->colorConverter->convert(0, $this->PDFAXwarnings));
16982 $this->SetLineJoin(2);
16983 $this->SetLineCap(2);
16984 $this->SetDash();
16990 if ($this->blk[$blvl]['border_left']) {
16991 $tbd = $this->blk[$blvl]['border_left'];
16994 $this->writer->write('q');
16995 $this->SetLineWidth(0);
16996 $this->writer->write(sprintf('%.3F %.3F m ', ($x0) * Mpdf::SCALE, ($this->h - ($y0)) * Mpdf::SCALE));
16997 $this->writer->write(sprintf('%.3F %.3F l ', ($x0 + $border_left) * Mpdf::SCALE, ($this->h - ($y0 + $border_top)) * Mpdf::SCALE));
16998 $this->writer->write(sprintf('%.3F %.3F l ', ($x0 + $border_left) * Mpdf::SCALE, ($this->h - ($y0 + $h - $border_bottom)) * Mpdf::SCALE));
16999 $this->writer->write(sprintf('%.3F %.3F l ', ($x0) * Mpdf::SCALE, ($this->h - ($y0 + $h)) * Mpdf::SCALE));
17000 $this->writer->write(' h W n '); // Ends path no-op & Sets the clipping path
17003 $this->_setBorderLine($tbd);
17005 $this->_setDashBorder($tbd['style'], $divider, $continuingpage, 'L');
17006 } /* -- BORDER-RADIUS -- */ elseif (($brTL_V && $brTL_H) || ($brBL_V && $brBL_H) || $tbd['style'] == 'solid' || $tbd['style'] == 'double') {
17007 $this->SetLineJoin(0);
17008 $this->SetLineCap(0);
17012 $s .= ($this->_EllipseArc($x0 + $brTL_H, $y0 + $brTL_V, $brTL_H - $border_left / 2, $brTL_V - $border_left / 2, 2, 2, true)) . "\n";
17013 } else { /* -- END BORDER-RADIUS -- */
17015 $s .= (sprintf('%.3F %.3F m ', ($x0 + ($border_left / 2)) * Mpdf::SCALE, ($this->h - ($y0)) * Mpdf::SCALE)) . "\n";
17017 $s .= (sprintf('%.3F %.3F m ', ($x0 + ($border_left / 2)) * Mpdf::SCALE, ($this->h - ($y0 + ($border_left / 2))) * Mpdf::SCALE)) . "\n";
17020 /* -- BORDER-RADIUS -- */
17022 $s .= (sprintf('%.3F %.3F l ', ($x0 + ($border_left / 2)) * Mpdf::SCALE, ($this->h - ($y0 + $h - ($border_left / 2) - $brBL_V) ) * Mpdf::SCALE)) . "\n";
17023 $s .= ($this->_EllipseArc($x0 + $brBL_H, $y0 + $h - $brBL_V, $brBL_H - $border_left / 2, $brBL_V - $border_left / 2, 3, 1)) . "\n";
17024 } else { /* -- END BORDER-RADIUS -- */
17026 $s .= (sprintf('%.3F %.3F l ', ($x0 + ($border_left / 2)) * Mpdf::SCALE, ($this->h - ($y0 + $h) ) * Mpdf::SCALE)) . "\n";
17028 $s .= (sprintf('%.3F %.3F l ', ($x0 + ($border_left / 2)) * Mpdf::SCALE, ($this->h - ($y0 + $h - ($border_left / 2)) ) * Mpdf::SCALE)) . "\n";
17032 $this->writer->write($s);
17035 $this->SetLineWidth($tbd['w'] / 3);
17036 $this->SetDColor($tbcol);
17037 $this->writer->write($s);
17040 $this->writer->write('Q');
17044 $this->SetLineWidth(0.1);
17045 $this->SetDColor($this->colorConverter->convert(0, $this->PDFAXwarnings));
17046 $this->SetLineJoin(2);
17047 $this->SetLineCap(2);
17048 $this->SetDash();
17051 if ($this->blk[$blvl]['border_right']) {
17052 $tbd = $this->blk[$blvl]['border_right'];
17055 $this->writer->write('q');
17056 $this->SetLineWidth(0);
17057 $this->writer->write(sprintf('%.3F %.3F m ', ($x0 + $w) * Mpdf::SCALE, ($this->h - ($y0)) * Mpdf::SCALE));
17058 $this->writer->write(sprintf('%.3F %.3F l ', ($x0 + $w - $border_right) * Mpdf::SCALE, ($this->h - ($y0 + $border_top)) * Mpdf::SCALE));
17059 $this->writer->write(sprintf('%.3F %.3F l ', ($x0 + $w - $border_right) * Mpdf::SCALE, ($this->h - ($y0 + $h - $border_bottom)) * Mpdf::SCALE));
17060 $this->writer->write(sprintf('%.3F %.3F l ', ($x0 + $w) * Mpdf::SCALE, ($this->h - ($y0 + $h)) * Mpdf::SCALE));
17061 $this->writer->write(' h W n '); // Ends path no-op & Sets the clipping path
17064 $this->_setBorderLine($tbd);
17066 $this->_setDashBorder($tbd['style'], $divider, $continuingpage, 'R');
17067 } /* -- BORDER-RADIUS -- */ elseif (($brTR_V && $brTR_H) || ($brBR_V && $brBR_H) || $tbd['style'] == 'solid' || $tbd['style'] == 'double') {
17068 $this->SetLineJoin(0);
17069 $this->SetLineCap(0);
17073 $s .= ($this->_EllipseArc($x0 + $w - $brBR_H, $y0 + $h - $brBR_V, $brBR_H - $border_right / 2, $brBR_V - $border_right / 2, 4, 2, true)) . "\n";
17074 } else { /* -- END BORDER-RADIUS -- */
17076 $s .= (sprintf('%.3F %.3F m ', ($x0 + $w - ($border_right / 2)) * Mpdf::SCALE, ($this->h - ($y0 + $h)) * Mpdf::SCALE)) . "\n";
17078 $s .= (sprintf('%.3F %.3F m ', ($x0 + $w - ($border_right / 2)) * Mpdf::SCALE, ($this->h - ($y0 + $h - ($border_right / 2))) * Mpdf::SCALE)) . "\n";
17081 /* -- BORDER-RADIUS -- */
17083 $s .= (sprintf('%.3F %.3F l ', ($x0 + $w - ($border_right / 2)) * Mpdf::SCALE, ($this->h - ($y0 + ($border_right / 2) + $brTR_V) ) * Mpdf::SCALE)) . "\n";
17084 $s .= ($this->_EllipseArc($x0 + $w - $brTR_H, $y0 + $brTR_V, $brTR_H - $border_right / 2, $brTR_V - $border_right / 2, 1, 1)) . "\n";
17085 } else { /* -- END BORDER-RADIUS -- */
17087 $s .= (sprintf('%.3F %.3F l ', ($x0 + $w - ($border_right / 2)) * Mpdf::SCALE, ($this->h - ($y0) ) * Mpdf::SCALE)) . "\n";
17089 $s .= (sprintf('%.3F %.3F l ', ($x0 + $w - ($border_right / 2)) * Mpdf::SCALE, ($this->h - ($y0 + ($border_right / 2)) ) * Mpdf::SCALE)) . "\n";
17093 $this->writer->write($s);
17096 $this->SetLineWidth($tbd['w'] / 3);
17097 $this->SetDColor($tbcol);
17098 $this->writer->write($s);
17101 $this->writer->write('Q');
17105 $this->SetLineWidth(0.1);
17106 $this->SetDColor($this->colorConverter->convert(0, $this->PDFAXwarnings));
17107 $this->SetLineJoin(2);
17108 $this->SetLineCap(2);
17109 $this->SetDash();
17114 $this->SetDash();
17115 $this->y = $save_y;
17118 // BACKGROUNDS are disabled in columns/kbt/headers - messes up the repositioning in printcolumnbuffer
17119 if ($this->ColActive || $this->kwt || $this->keep_block_together) {
17129 // Defined br values represent the radius of the outer curve - need to take border-width/2 from each radius for drawing the borders
17130 if (isset($this->blk[$blvl]['background_clip']) && $this->blk[$blvl]['background_clip'] == 'padding-box') {
17131 $brbgTL_H = max(0, $brTL_H - $this->blk[$blvl]['border_left']['w']);
17132 $brbgTL_V = max(0, $brTL_V - $this->blk[$blvl]['border_top']['w']);
17133 $brbgTR_H = max(0, $brTR_H - $this->blk[$blvl]['border_right']['w']);
17134 $brbgTR_V = max(0, $brTR_V - $this->blk[$blvl]['border_top']['w']);
17135 $brbgBL_H = max(0, $brBL_H - $this->blk[$blvl]['border_left']['w']);
17136 $brbgBL_V = max(0, $brBL_V - $this->blk[$blvl]['border_bottom']['w']);
17137 $brbgBR_H = max(0, $brBR_H - $this->blk[$blvl]['border_right']['w']);
17138 $brbgBR_V = max(0, $brBR_V - $this->blk[$blvl]['border_bottom']['w']);
17139 $bgx0 += $this->blk[$blvl]['border_left']['w'];
17140 $bgx1 -= $this->blk[$blvl]['border_right']['w'];
17141 if ($this->blk[$blvl]['border_top'] && $divider != 'pagetop' && !$continuingpage) {
17142 $bgy0 += $this->blk[$blvl]['border_top']['w'];
17144 if ($this->blk[$blvl]['border_bottom'] && $blockstate != 1 && $divider != 'pagebottom') {
17145 $bgy1 -= $this->blk[$blvl]['border_bottom']['w'];
17147 } elseif (isset($this->blk[$blvl]['background_clip']) && $this->blk[$blvl]['background_clip'] == 'content-box') {
17148 $brbgTL_H = max(0, $brTL_H - $this->blk[$blvl]['border_left']['w'] - $this->blk[$blvl]['padding_left']);
17149 $brbgTL_V = max(0, $brTL_V - $this->blk[$blvl]['border_top']['w'] - $this->blk[$blvl]['padding_top']);
17150 $brbgTR_H = max(0, $brTR_H - $this->blk[$blvl]['border_right']['w'] - $this->blk[$blvl]['padding_right']);
17151 $brbgTR_V = max(0, $brTR_V - $this->blk[$blvl]['border_top']['w'] - $this->blk[$blvl]['padding_top']);
17152 $brbgBL_H = max(0, $brBL_H - $this->blk[$blvl]['border_left']['w'] - $this->blk[$blvl]['padding_left']);
17153 $brbgBL_V = max(0, $brBL_V - $this->blk[$blvl]['border_bottom']['w'] - $this->blk[$blvl]['padding_bottom']);
17154 $brbgBR_H = max(0, $brBR_H - $this->blk[$blvl]['border_right']['w'] - $this->blk[$blvl]['padding_right']);
17155 $brbgBR_V = max(0, $brBR_V - $this->blk[$blvl]['border_bottom']['w'] - $this->blk[$blvl]['padding_bottom']);
17156 $bgx0 += $this->blk[$blvl]['border_left']['w'] + $this->blk[$blvl]['padding_left'];
17157 $bgx1 -= $this->blk[$blvl]['border_right']['w'] + $this->blk[$blvl]['padding_right'];
17158 if (($this->blk[$blvl]['border_top']['w'] || $this->blk[$blvl]['padding_top']) && $divider != 'pagetop' && !$continuingpage) {
17159 $bgy0 += $this->blk[$blvl]['border_top']['w'] + $this->blk[$blvl]['padding_top'];
17161 if (($this->blk[$blvl]['border_bottom']['w'] || $this->blk[$blvl]['padding_bottom']) && $blockstate != 1 && $divider != 'pagebottom') {
17162 $bgy1 -= $this->blk[$blvl]['border_bottom']['w'] + $this->blk[$blvl]['padding_bottom'];
17177 $s .= sprintf('%.3F %.3F m ', ($bgx0 + $brbgTL_H ) * Mpdf::SCALE, ($this->h - $bgy0) * Mpdf::SCALE); // start point TL before the arc
17178 /* -- BORDER-RADIUS -- */
17180 $s .= $this->_EllipseArc($bgx0 + $brbgTL_H, $bgy0 + $brbgTL_V, $brbgTL_H, $brbgTL_V, 2); // segment 2 TL
17182 /* -- END BORDER-RADIUS -- */
17183 $s .= sprintf('%.3F %.3F l ', ($bgx0) * Mpdf::SCALE, ($this->h - ($bgy1 - $brbgBL_V )) * Mpdf::SCALE); // line to BL
17184 /* -- BORDER-RADIUS -- */
17186 $s .= $this->_EllipseArc($bgx0 + $brbgBL_H, $bgy1 - $brbgBL_V, $brbgBL_H, $brbgBL_V, 3); // segment 3 BL
17188 /* -- END BORDER-RADIUS -- */
17189 $s .= sprintf('%.3F %.3F l ', ($bgx1 - $brbgBR_H ) * Mpdf::SCALE, ($this->h - ($bgy1)) * Mpdf::SCALE); // line to BR
17190 /* -- BORDER-RADIUS -- */
17192 $s .= $this->_EllipseArc($bgx1 - $brbgBR_H, $bgy1 - $brbgBR_V, $brbgBR_H, $brbgBR_V, 4); // segment 4 BR
17194 /* -- END BORDER-RADIUS -- */
17195 $s .= sprintf('%.3F %.3F l ', ($bgx1) * Mpdf::SCALE, ($this->h - ($bgy0 + $brbgTR_V)) * Mpdf::SCALE); // line to TR
17196 /* -- BORDER-RADIUS -- */
17198 $s .= $this->_EllipseArc($bgx1 - $brbgTR_H, $bgy0 + $brbgTR_V, $brbgTR_H, $brbgTR_V, 1); // segment 1 TR
17200 /* -- END BORDER-RADIUS -- */
17201 $s .= sprintf('%.3F %.3F l ', ($bgx0 + $brbgTL_H ) * Mpdf::SCALE, ($this->h - $bgy0) * Mpdf::SCALE); // line to TL
17204 if (isset($this->blk[$blvl]['box_shadow']) && $this->blk[$blvl]['box_shadow'] && $h > 0) {
17205 foreach ($this->blk[$blvl]['box_shadow'] as $sh) {
17235 $shadow .= sprintf('0 %.3F m %.3F %.3F l ', $this->h * Mpdf::SCALE, $this->w * Mpdf::SCALE, $this->h * Mpdf::SCALE);
17236 $shadow .= sprintf('%.3F 0 l 0 0 l 0 %.3F l ', $this->w * Mpdf::SCALE, $this->h * Mpdf::SCALE);
17242 if (-$sh['spread'] + $sh['blur'] / 2 > min($w / 2, $h / 2)) {
17243 $sh['spread'] = $sh['blur'] / 2 - min($w / 2, $h / 2) + 0.01;
17247 $shadow .= sprintf(' q 1 0 0 1 %.4F %.4F cm', $sh['x'] * Mpdf::SCALE, -$sh['y'] * Mpdf::SCALE) . "\n";
17252 $shadow .= $this->SetFColor($col1, true) . "\n";
17254 $shadow .= $this->SetAlpha(ord($col1[4]) / 100, 'Normal', true, 'F') . "\n";
17256 $shadow .= $this->SetAlpha(ord($col1[5]) / 100, 'Normal', true, 'F') . "\n";
17258 $shadow .= $this->SetAlpha(ord($col1[3]) / 100, 'Normal', true, 'F') . "\n";
17262 $mag = 0.551784; // Bezier Control magic number for 4-part spline for circle/ellipse
17265 $d2 = $sh['spread'] - $sh['blur'] / 2;
17267 $x00 = $x0 - $d1;
17268 $y00 = $y0 - $d1;
17272 // If any border-radius is greater width-negative spread(inner edge), ignore radii for shadow or screws up
17283 $p1x = $x00 + $w00 - $d1 - $brbgTR_H;
17286 $p2x = $x00 + $w00 - $d1 - $brbgTR_H;
17291 $p3c2x = $p3x - $bl / 2;
17293 $p3c1y = $p3y - ($d1 + $brbgTR_V) * $mag;
17294 $p4x = $x00 + $w00 - $bl;
17296 $p4c2y = $p4y - ($d2 + $brbgTR_V) * $mag;
17297 if (-$d2 > min($brbgTR_H, $brbgTR_V) || $flatten) {
17298 $p1x = $x00 + $w00 - $bl;
17300 $p2x = $x00 + $w00 - $bl;
17303 $p3c1y = $p3y - $bl * $mag2;
17308 $shadow .= sprintf('%.3F %.3F m ', ($p1x ) * Mpdf::SCALE, ($this->h - ($p1y )) * Mpdf::SCALE);
17309 $shadow .= sprintf('%.3F %.3F %.3F %.3F %.3F %.3F c ', ($p1c2x) * Mpdf::SCALE, ($this->h - ($p1y)) * Mpdf::SCALE, ($p4x) * Mpdf::SCALE, ($this->h - ($p4c2y)) * Mpdf::SCALE, ($p4x) * Mpdf::SCALE, ($this->h - ($p4y)) * Mpdf::SCALE);
17322 $p2x = $x00 + $w00 - $bl; // control point only matches p4 preceding
17324 $p3x = $x00 + $w00 - $bl;
17325 $p3y = $y00 + $h00 - $d1 - $brbgBR_V;
17327 $p4c1x = $p4x - $bl / 2;
17328 $p4y = $y00 + $h00 - $d1 - $brbgBR_V;
17329 if (-$d2 > min($brbgTR_H, $brbgTR_V) || $flatten) {
17333 if (-$d2 > min($brbgBR_H, $brbgBR_V) || $flatten) {
17334 $p3y = $y00 + $h00 - $bl;
17335 $p4y = $y00 + $h00 - $bl;
17338 $shadow .= sprintf('%.3F %.3F l ', ($p3x ) * Mpdf::SCALE, ($this->h - ($p3y )) * Mpdf::SCALE);
17348 $p1x = $x00 + $w00 - $bl; // control points only matches p3 preceding
17349 $p1y = $y00 + $h00 - $d1 - $brbgBR_V;
17352 $p2y = $y00 + $h00 - $d1 - $brbgBR_V;
17354 $p3x = $x00 + $w00 - $d1 - $brbgBR_H;
17357 $p3c2y = $p3y - $bl / 2;
17358 $p4x = $x00 + $w00 - $d1 - $brbgBR_H;
17360 $p4y = $y00 + $h00 - $bl;
17362 if (-$d2 > min($brbgBR_H, $brbgBR_V) || $flatten) {
17363 $p1y = $y00 + $h00 - $bl;
17365 $p2y = $y00 + $h00 - $bl;
17367 $p3x = $x00 + $w00 - $bl;
17369 $p4x = $x00 + $w00 - $bl;
17373 $shadow .= sprintf('%.3F %.3F %.3F %.3F %.3F %.3F c ', ($p1x) * Mpdf::SCALE, ($this->h - ($p1c2y)) * Mpdf::SCALE, ($p4c2x) * Mpdf::SCALE, ($this->h - ($p4y)) * Mpdf::SCALE, ($p4x) * Mpdf::SCALE, ($this->h - ($p4y)) * Mpdf::SCALE);
17384 $p1x = $x00 + $w00 - $d1 - $brbgBR_H; // control point only matches p3 preceding
17386 $p2x = $x00 + $w00 - $d1 - $brbgBR_H; // control point only matches p4 preceding
17387 $p2y = $y00 + $h00 - $bl;
17389 $p3y = $y00 + $h00 - $bl;
17392 $p4c1y = $p4y - $bl / 2;
17394 if (-$d2 > min($brbgBR_H, $brbgBR_V) || $flatten) {
17395 $p1x = $x00 + $w00 - $bl;
17396 $p2x = $x00 + $w00 - $bl;
17398 if (-$d2 > min($brbgBL_H, $brbgBL_V) || $flatten) {
17403 $shadow .= sprintf('%.3F %.3F l ', ($p3x ) * Mpdf::SCALE, ($this->h - ($p3y )) * Mpdf::SCALE);
17413 $p1c2x = $p1x - ($d2 + $brbgBL_H) * $mag; // control points only matches p3 preceding
17414 $p1y = $y00 + $h00 - $bl;
17416 $p2c2x = $p2x - ($d1 + $brbgBL_H) * $mag; // control point only matches p4 preceding
17420 $p3y = $y00 + $h00 - $d1 - $brbgBL_V;
17423 $p4y = $y00 + $h00 - $d1 - $brbgBL_V;
17425 if (-$d2 > min($brbgBL_H, $brbgBL_V) || $flatten) {
17429 $p2c2x = $p2x - $bl * $mag2;
17430 $p3y = $y00 + $h00 - $bl;
17432 $p4y = $y00 + $h00 - $bl;
17436 $shadow .= sprintf('%.3F %.3F %.3F %.3F %.3F %.3F c ', ($p1c2x) * Mpdf::SCALE, ($this->h - ($p1y)) * Mpdf::SCALE, ($p4x) * Mpdf::SCALE, ($this->h - ($p4c2y)) * Mpdf::SCALE, ($p4x) * Mpdf::SCALE, ($this->h - ($p4y)) * Mpdf::SCALE);
17445 // LEFT - joins on the right (C3-C4 of previous): f = 2
17447 $p1y = $y00 + $h00 - $d1 - $brbgBL_V;
17449 $p2y = $y00 + $h00 - $d1 - $brbgBL_V;
17455 if (-$d2 > min($brbgBL_H, $brbgBL_V) || $flatten) {
17456 $p1y = $y00 + $h00 - $bl;
17457 $p2y = $y00 + $h00 - $bl;
17459 if (-$d2 > min($brbgTL_H, $brbgTL_V) || $flatten) {
17464 $shadow .= sprintf('%.3F %.3F l ', ($p3x ) * Mpdf::SCALE, ($this->h - ($p3y )) * Mpdf::SCALE);
17475 $p1c2y = $p1y - ($d2 + $brbgTL_V) * $mag;
17478 $p2c2y = $p2y - ($d1 + $brbgTL_V) * $mag;
17480 $p3c1x = $p3x - ($d1 + $brbgTL_H) * $mag;
17484 $p4c2x = $p4x - ($d2 + $brbgTL_H) * $mag;
17487 if (-$d2 > min($brbgTL_H, $brbgTL_V) || $flatten) {
17491 $p2c2y = $p2y - $bl * $mag2;
17493 $p3c1x = $p3x - $bl * $mag2;
17498 $shadow .= sprintf('%.3F %.3F %.3F %.3F %.3F %.3F c ', ($p1x) * Mpdf::SCALE, ($this->h - ($p1c2y)) * Mpdf::SCALE, ($p4c2x) * Mpdf::SCALE, ($this->h - ($p4y)) * Mpdf::SCALE, ($p4x) * Mpdf::SCALE, ($this->h - ($p4y)) * Mpdf::SCALE);
17507 // TOP - joins on the right (C3-C4 of previous): f = 2
17512 $p3x = $x00 + $w00 - $d1 - $brbgTR_H;
17514 $p4x = $x00 + $w00 - $d1 - $brbgTR_H;
17517 if (-$d2 > min($brbgTL_H, $brbgTL_V) || $flatten) {
17521 if (-$d2 > min($brbgTR_H, $brbgTR_V) || $flatten) {
17522 $p3x = $x00 + $w00 - $bl;
17523 $p4x = $x00 + $w00 - $bl;
17526 $shadow .= sprintf('%.3F %.3F l ', ($p3x ) * Mpdf::SCALE, ($this->h - ($p3y )) * Mpdf::SCALE);
17537 $shadow .= $this->gradient->CoonsPatchMesh($x00, $y00, $w00, $h00, $patch_array, $x00, $x00 + $w00, $y00, $y00 + $h00, $colspace, true);
17543 $shadow .= ' Q' . "\n"; // Ends path no-op & Sets the clipping path
17547 $s .= ' W n '; // Ends path no-op & Sets the clipping path
17549 if ($this->blk[$blvl]['bgcolor']) {
17550 $this->pageBackgrounds[$blvl][] = [
17555 'col' => $this->blk[$blvl]['bgcolorarray'],
17557 'visibility' => $this->visibility,
17559 'z-index' => $this->current_layer,
17562 $this->pageBackgrounds[$blvl][] = [
17570 'visibility' => $this->visibility,
17572 'z-index' => $this->current_layer,
17576 /* -- BACKGROUNDS -- */
17577 if (isset($this->blk[$blvl]['gradient'])) {
17578 $g = $this->gradient->parseBackgroundGradient($this->blk[$blvl]['gradient']);
17582 $this->pageBackgrounds[$blvl][] = [
17594 'visibility' => $this->visibility,
17595 'z-index' => $this->current_layer
17600 if (isset($this->blk[$blvl]['background-image'])) {
17601 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'])) {
17602 $g = $this->gradient->parseMozGradient($this->blk[$blvl]['background-image']['gradient']);
17606 // origin specifies the background-positioning-area (bpa)
17607 if ($this->blk[$blvl]['background-image']['origin'] == 'padding-box') {
17608 $gx += $this->blk[$blvl]['border_left']['w'];
17609 $w -= ($this->blk[$blvl]['border_left']['w'] + $this->blk[$blvl]['border_right']['w']);
17610 if ($this->blk[$blvl]['border_top'] && $divider != 'pagetop' && !$continuingpage) {
17611 $gy += $this->blk[$blvl]['border_top']['w'];
17613 if ($this->blk[$blvl]['border_bottom'] && $blockstate != 1 && $divider != 'pagebottom') {
17614 $gy1 = $y1 - $this->blk[$blvl]['border_bottom']['w'];
17618 $h = $gy1 - $gy;
17619 } elseif ($this->blk[$blvl]['background-image']['origin'] == 'content-box') {
17620 $gx += $this->blk[$blvl]['border_left']['w'] + $this->blk[$blvl]['padding_left'];
17621 $w -= ($this->blk[$blvl]['border_left']['w'] + $this->blk[$blvl]['padding_left'] + $this->blk[$blvl]['border_right']['w'] + $this->blk[$blvl]['padding_right']);
17622 if ($this->blk[$blvl]['border_top'] && $divider != 'pagetop' && !$continuingpage) {
17623 $gy += $this->blk[$blvl]['border_top']['w'] + $this->blk[$blvl]['padding_top'];
17625 if ($this->blk[$blvl]['border_bottom'] && $blockstate != 1 && $divider != 'pagebottom') {
17626 $gy1 = $y1 - ($this->blk[$blvl]['border_bottom']['w'] + $this->blk[$blvl]['padding_bottom']);
17628 $gy1 = $y1 - $this->blk[$blvl]['padding_bottom'];
17630 $h = $gy1 - $gy;
17633 if (isset($this->blk[$blvl]['background-image']['size']['w']) && $this->blk[$blvl]['background-image']['size']['w']) {
17634 $size = $this->blk[$blvl]['background-image']['size'];
17635 if ($size['w'] != 'contain' && $size['w'] != 'cover') {
17636 if (stristr($size['w'], '%')) {
17637 $size['w'] = (float) $size['w'];
17638 $size['w'] /= 100;
17639 $w *= $size['w'];
17640 } elseif ($size['w'] != 'auto') {
17641 $w = $size['w'];
17643 if (stristr($size['h'], '%')) {
17644 $size['h'] = (float) $size['h'];
17645 $size['h'] /= 100;
17646 $h *= $size['h'];
17647 } elseif ($size['h'] != 'auto') {
17648 $h = $size['h'];
17652 $this->pageBackgrounds[$blvl][] = [
17664 'visibility' => $this->visibility,
17665 'z-index' => $this->current_layer
17671 $image_id = $this->blk[$blvl]['background-image']['image_id'];
17672 $orig_w = $this->blk[$blvl]['background-image']['orig_w'];
17673 $orig_h = $this->blk[$blvl]['background-image']['orig_h'];
17674 $x_pos = $this->blk[$blvl]['background-image']['x_pos'];
17675 $y_pos = $this->blk[$blvl]['background-image']['y_pos'];
17676 $x_repeat = $this->blk[$blvl]['background-image']['x_repeat'];
17677 $y_repeat = $this->blk[$blvl]['background-image']['y_repeat'];
17678 $resize = $this->blk[$blvl]['background-image']['resize'];
17679 $opacity = $this->blk[$blvl]['background-image']['opacity'];
17680 $itype = $this->blk[$blvl]['background-image']['itype'];
17681 $size = $this->blk[$blvl]['background-image']['size'];
17682 // origin specifies the background-positioning-area (bpa)
17686 if ($this->blk[$blvl]['background-image']['origin'] == 'padding-box') {
17688 $bpa['x'] = $x0 + $this->blk[$blvl]['border_left']['w'];
17689 $bpa['w'] = $w - ($this->blk[$blvl]['border_left']['w'] + $this->blk[$blvl]['border_right']['w']);
17690 if ($this->blk[$blvl]['border_top'] && $divider != 'pagetop' && !$continuingpage) {
17691 $bpa['y'] = $y0 + $this->blk[$blvl]['border_top']['w'];
17695 if ($this->blk[$blvl]['border_bottom'] && $blockstate != 1 && $divider != 'pagebottom') {
17696 $bpay = $y1 - $this->blk[$blvl]['border_bottom']['w'];
17700 $bpa['h'] = $bpay - $bpa['y'];
17702 } elseif ($this->blk[$blvl]['background-image']['origin'] == 'content-box') {
17704 $bpa['x'] = $x0 + $this->blk[$blvl]['border_left']['w'] + $this->blk[$blvl]['padding_left'];
17705 $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']);
17706 if ($this->blk[$blvl]['border_top'] && $divider != 'pagetop' && !$continuingpage) {
17707 $bpa['y'] = $y0 + $this->blk[$blvl]['border_top']['w'] + $this->blk[$blvl]['padding_top'];
17709 $bpa['y'] = $y0 + $this->blk[$blvl]['padding_top'];
17711 if ($this->blk[$blvl]['border_bottom'] && $blockstate != 1 && $divider != 'pagebottom') {
17712 $bpay = $y1 - ($this->blk[$blvl]['border_bottom']['w'] + $this->blk[$blvl]['padding_bottom']);
17714 $bpay = $y1 - $this->blk[$blvl]['padding_bottom'];
17716 $bpa['h'] = $bpay - $bpa['y'];
17720 $this->pageBackgrounds[$blvl][] = [
17736 'visibility' => $this->visibility,
17737 'z-index' => $this->current_layer,
17738 'size' => $size,
17743 /* -- END BACKGROUNDS -- */
17746 $this->blk[$blvl]['bb_painted'][$this->page] = true;
17748 /* -- BORDER-RADIUS -- */
17752 // Anticlockwise segment 1-4 TR-TL-BL-BR (part=1 or 2)
17785 $totalAngle = $afinish - $astart;
17789 $y0 = ($this->h - $y0) * Mpdf::SCALE;
17793 $c0 = -$rx * sin($t1);
17802 $c1 = -$rx * sin($t1);
17804 if ($i > ($nSeg - 4) && (!$part || ($part == 1 && $i <= $nSeg - 2) || ($part == 2 && $i > $nSeg - 2))) {
17808 $s .= sprintf('%.3F %.3F %.3F %.3F %.3F %.3F c ', ($a0 + ($c0 * $dtm)), ($b0 + ($d0 * $dtm)), ($a1 - ($c1 * $dtm)), ($b1 - ($d1 * $dtm)), $a1, $b1);
17820 /* -- END BORDER-RADIUS -- */
17825 $this->ColDetails[$this->CurrCol]['bottom_margin'] = $this->y + $h;
17827 $save_y = $this->y;
17829 $w = $this->blk[$blvl]['width'];
17830 $x0 = $this->x; // left
17831 $y0 = $this->y; // top
17832 $x1 = $this->x + $w; // bottom
17833 $y1 = $this->y + $h; // bottom
17834 $continuingpage = (isset($this->blk[$blvl]['startpage']) && $this->blk[$blvl]['startpage'] != $this->page);
17836 if ($this->blk[$blvl]['border_top'] && ($state == 1 || $state == 3)) {
17837 $tbd = $this->blk[$blvl]['border_top'];
17839 $this->_setBorderLine($tbd);
17840 $this->y = $y0 + ($tbd['w'] / 2);
17842 $this->_setDashBorder($tbd['style'], '', $continuingpage, 'T');
17843 $this->Line($x0 + ($tbd['w'] / 2), $this->y, $x0 + $w - ($tbd['w'] / 2), $this->y);
17845 $this->SetLineJoin(0);
17846 $this->SetLineCap(0);
17847 $this->Line($x0, $this->y, $x0 + $w, $this->y);
17849 $this->y += $tbd['w'];
17851 $this->SetLineJoin(2);
17852 $this->SetLineCap(2);
17853 $this->SetDash();
17856 if ($this->blk[$blvl]['border_left']) {
17857 $tbd = $this->blk[$blvl]['border_left'];
17859 $this->_setBorderLine($tbd);
17861 $this->y = $y0 + ($tbd['w'] / 2);
17862 $this->_setDashBorder($tbd['style'], '', $continuingpage, 'L');
17863 $this->Line($x0 + ($tbd['w'] / 2), $this->y, $x0 + ($tbd['w'] / 2), $y0 + $h - ($tbd['w'] / 2));
17865 $this->y = $y0;
17866 $this->SetLineJoin(0);
17867 $this->SetLineCap(0);
17868 $this->Line($x0 + ($tbd['w'] / 2), $this->y, $x0 + ($tbd['w'] / 2), $y0 + $h);
17870 $this->y += $tbd['w'];
17872 $this->SetLineJoin(2);
17873 $this->SetLineCap(2);
17874 $this->SetDash();
17877 if ($this->blk[$blvl]['border_right']) {
17878 $tbd = $this->blk[$blvl]['border_right'];
17880 $this->_setBorderLine($tbd);
17882 $this->y = $y0 + ($tbd['w'] / 2);
17883 $this->_setDashBorder($tbd['style'], '', $continuingpage, 'R');
17884 $this->Line($x0 + $w - ($tbd['w'] / 2), $this->y, $x0 + $w - ($tbd['w'] / 2), $y0 + $h - ($tbd['w'] / 2));
17886 $this->y = $y0;
17887 $this->SetLineJoin(0);
17888 $this->SetLineCap(0);
17889 $this->Line($x0 + $w - ($tbd['w'] / 2), $this->y, $x0 + $w - ($tbd['w'] / 2), $y0 + $h);
17891 $this->y += $tbd['w'];
17893 $this->SetLineJoin(2);
17894 $this->SetLineCap(2);
17895 $this->SetDash();
17898 if ($this->blk[$blvl]['border_bottom'] && $state > 1) {
17899 $tbd = $this->blk[$blvl]['border_bottom'];
17901 $this->_setBorderLine($tbd);
17902 $this->y = $y0 + $h - ($tbd['w'] / 2);
17904 $this->_setDashBorder($tbd['style'], '', $continuingpage, 'B');
17905 $this->Line($x0 + ($tbd['w'] / 2), $this->y, $x0 + $w - ($tbd['w'] / 2), $this->y);
17907 $this->SetLineJoin(0);
17908 $this->SetLineCap(0);
17909 $this->Line($x0, $this->y, $x0 + $w, $this->y);
17911 $this->y += $tbd['w'];
17913 $this->SetLineJoin(2);
17914 $this->SetLineCap(2);
17915 $this->SetDash();
17918 $this->SetDash();
17919 $this->y = $save_y;
17924 // Borders are disabled in columns - messes up the repositioning in printcolumnbuffer
17925 if ($this->ColActive) {
17929 $k = $this->shrin_k;
17933 $h = (isset($objattr['BORDER-HEIGHT']) ? $objattr['BORDER-HEIGHT'] : 0);
17934 $w = (isset($objattr['BORDER-WIDTH']) ? $objattr['BORDER-WIDTH'] : 0);
17935 $x0 = (isset($objattr['BORDER-X']) ? $objattr['BORDER-X'] : 0);
17936 $y0 = (isset($objattr['BORDER-Y']) ? $objattr['BORDER-Y'] : 0);
17942 $this->_setBorderLine($tbd, $k);
17944 $this->_setDashBorder($tbd['style'], '', '', 'T');
17946 $this->Line($x0, $y0, $x0 + $w, $y0);
17948 $this->SetLineJoin(2);
17949 $this->SetLineCap(2);
17950 $this->SetDash();
17956 $this->_setBorderLine($tbd, $k);
17958 $this->_setDashBorder($tbd['style'], '', '', 'L');
17960 $this->Line($x0, $y0, $x0, $y0 + $h);
17962 $this->SetLineJoin(2);
17963 $this->SetLineCap(2);
17964 $this->SetDash();
17970 $this->_setBorderLine($tbd, $k);
17972 $this->_setDashBorder($tbd['style'], '', '', 'R');
17974 $this->Line($x0 + $w, $y0, $x0 + $w, $y0 + $h);
17976 $this->SetLineJoin(2);
17977 $this->SetLineCap(2);
17978 $this->SetDash();
17984 $this->_setBorderLine($tbd, $k);
17986 $this->_setDashBorder($tbd['style'], '', '', 'B');
17988 $this->Line($x0, $y0 + $h, $x0 + $w, $y0 + $h);
17990 $this->SetLineJoin(2);
17991 $this->SetLineCap(2);
17992 $this->SetDash();
17995 $this->SetDash();
17996 $this->SetAlpha(1);
17999 /* -- END HTML-CSS -- */
18003 $this->SetTColor($this->colorConverter->convert(0, $this->PDFAXwarnings));
18004 $this->SetDColor($this->colorConverter->convert(0, $this->PDFAXwarnings));
18005 $this->SetFColor($this->colorConverter->convert(255, $this->PDFAXwarnings));
18006 $this->SetAlpha(1);
18007 $this->colorarray = '';
18009 $this->spanbgcolorarray = '';
18010 $this->spanbgcolor = false;
18011 $this->spanborder = false;
18012 $this->spanborddet = [];
18014 $this->ResetStyles();
18016 $this->HREF = '';
18017 $this->textparam = [];
18018 $this->SetTextOutline();
18020 $this->textvar = 0x00; // mPDF 5.7.1
18021 $this->OTLtags = [];
18022 $this->textshadow = '';
18024 $this->currentLang = $this->default_lang; // mPDF 6
18025 $this->RestrictUnicodeFonts($this->default_available_fonts); // mPDF 6
18026 $this->SetFont($this->default_font, '', 0, false);
18027 $this->SetFontSize($this->default_font_size, false);
18029 $this->currentfontfamily = '';
18030 $this->currentfontsize = '';
18031 $this->currentfontstyle = '';
18033 if ($this->tableLevel && isset($this->table[1][1]['cellLineHeight'])) {
18034 $this->SetLineHeight('', $this->table[1][1]['cellLineHeight']);
18036 if (isset($this->blk[$this->blklvl]['line_height']) && $this->blk[$this->blklvl]['line_height']) {
18037 $this->SetLineHeight('', $this->blk[$this->blklvl]['line_height']); // sets default line height
18041 $this->lSpacingCSS = '';
18042 $this->wSpacingCSS = '';
18043 $this->fixedlSpacing = false;
18044 $this->minwSpacing = 0;
18045 $this->SetDash(); // restore to no dash
18046 $this->dash_on = false;
18047 $this->dotted_on = false;
18048 $this->divwidth = 0;
18049 $this->divheight = 0;
18050 $this->cellTextAlign = '';
18051 $this->cellLineHeight = '';
18052 $this->cellLineStackingStrategy = '';
18053 $this->cellLineStackingShift = '';
18054 $this->oldy = -1;
18058 if (isset($this->cssManager->CSS['BODY']['FONT-STYLE'])) {
18059 $bodystyle['FONT-STYLE'] = $this->cssManager->CSS['BODY']['FONT-STYLE'];
18062 if (isset($this->cssManager->CSS['BODY']['FONT-WEIGHT'])) {
18063 $bodystyle['FONT-WEIGHT'] = $this->cssManager->CSS['BODY']['FONT-WEIGHT'];
18066 if (isset($this->cssManager->CSS['BODY']['COLOR'])) {
18067 $bodystyle['COLOR'] = $this->cssManager->CSS['BODY']['COLOR'];
18071 $this->setCSS($bodystyle, 'BLOCK', 'BODY');
18075 /* -- HTML-CSS -- */
18083 $this->SetTitle($m[1]);
18093 $this->SetKeywords($content);
18096 $this->SetAuthor($content);
18099 $this->SetSubject($content);
18108 if ($this->allow_charset_conversion) {
18110 if (strtoupper($m[1]) != 'UTF-8') {
18111 $this->charset_in = strtoupper($m[1]);
18124 // mPDF 5.7.3 inline text-decoration parameters
18125 $preceeding_fontkey = $this->FontFamily . $this->FontStyle;
18126 $preceeding_fontsize = $this->FontSize;
18130 $prevlevel = (($this->blklvl == 0) ? 0 : $this->blklvl - 1);
18132 // Set font size first so that e.g. MARGIN 0.83em works on font size for this element
18133 if (isset($arrayaux['FONT-SIZE'])) {
18134 $v = $arrayaux['FONT-SIZE'];
18137 if ($type == 'BLOCK' && $this->blklvl > 0 && isset($this->blk[$this->blklvl - 1]['InlineProperties']) && isset($this->blk[$this->blklvl - 1]['InlineProperties']['size'])) {
18138 $mmsize = $this->sizeConverter->convert($v, $this->blk[$this->blklvl - 1]['InlineProperties']['size']);
18140 $mmsize = $this->sizeConverter->convert($v, $this->default_font_size / Mpdf::SCALE);
18142 $mmsize = $this->sizeConverter->convert($v, $this->FontSize);
18144 $this->SetFontSize($mmsize * (Mpdf::SCALE), false); // Get size in points (pt)
18147 if (isset($this->fontsizes[$v])) {
18148 $this->SetFontSize($this->fontsizes[$v] * $this->default_font_size, false);
18152 $this->SetDefaultFontSize($this->FontSizePt);
18158 if ($this->autoLangToFont && !$this->usingCoreFont) {
18159 if ($arrayaux['LANG'] != $this->default_lang && $arrayaux['LANG'] != 'UTF-8') {
18160 list ($coreSuitable, $mpdf_pdf_unifont) = $this->languageToFont->getLanguageOptions($arrayaux['LANG'], $this->useAdobeCJK);
18162 $arrayaux['FONT-FAMILY'] = $mpdf_pdf_unifont;
18165 $this->default_lang = $arrayaux['LANG'];
18169 $this->currentLang = $arrayaux['LANG'];
18173 if (isset($arrayaux['FONT-FAMILY'])) {
18174 $v = $arrayaux['FONT-FAMILY'];
18175 // If it is a font list, get all font types
18183 if (isset($this->fonttrans[$v]) && $this->fonttrans[$v]) {
18184 $v = $this->fonttrans[$v];
18186 if ((!$this->onlyCoreFonts && in_array($v, $this->available_unifonts)) ||
18188 ($this->onlyCoreFonts && in_array($v, ['courier', 'times', 'helvetica', 'arial'])) ||
18201 if (isset($this->fonttrans[$v]) && $this->fonttrans[$v]) {
18202 $v = $this->fonttrans[$v];
18204 if (in_array($v, $this->sans_fonts) || in_array($v, $this->serif_fonts) || in_array($v, $this->mono_fonts)) {
18212 $this->SetDefaultFont($fonttype);
18214 $this->SetFont($fonttype, $this->currentfontstyle, 0, false);
18216 $this->SetFont($this->currentfontfamily, $this->currentfontstyle, 0, false);
18223 case 'BORDER-TOP':
18224 $this->blk[$this->blklvl]['border_top'] = $this->border_details($v);
18225 if ($this->blk[$this->blklvl]['border_top']['s']) {
18226 $this->blk[$this->blklvl]['border'] = 1;
18229 case 'BORDER-BOTTOM':
18230 $this->blk[$this->blklvl]['border_bottom'] = $this->border_details($v);
18231 if ($this->blk[$this->blklvl]['border_bottom']['s']) {
18232 $this->blk[$this->blklvl]['border'] = 1;
18235 case 'BORDER-LEFT':
18236 $this->blk[$this->blklvl]['border_left'] = $this->border_details($v);
18237 if ($this->blk[$this->blklvl]['border_left']['s']) {
18238 $this->blk[$this->blklvl]['border'] = 1;
18241 case 'BORDER-RIGHT':
18242 $this->blk[$this->blklvl]['border_right'] = $this->border_details($v);
18243 if ($this->blk[$this->blklvl]['border_right']['s']) {
18244 $this->blk[$this->blklvl]['border'] = 1;
18249 case 'PADDING-TOP':
18250 $this->blk[$this->blklvl]['padding_top'] = $this->sizeConverter->convert($v, $this->blk[$prevlevel]['inner_width'], $this->FontSize, false);
18252 case 'PADDING-BOTTOM':
18253 $this->blk[$this->blklvl]['padding_bottom'] = $this->sizeConverter->convert($v, $this->blk[$prevlevel]['inner_width'], $this->FontSize, false);
18255 case 'PADDING-LEFT':
18257 $this->blk[$this->blklvl]['padding_left'] = 'auto';
18260 $this->blk[$this->blklvl]['padding_left'] = $this->sizeConverter->convert($v, $this->blk[$prevlevel]['inner_width'], $this->FontSize, false);
18262 case 'PADDING-RIGHT':
18264 $this->blk[$this->blklvl]['padding_right'] = 'auto';
18267 $this->blk[$this->blklvl]['padding_right'] = $this->sizeConverter->convert($v, $this->blk[$prevlevel]['inner_width'], $this->FontSize, false);
18271 case 'MARGIN-TOP':
18272 $tmp = $this->sizeConverter->convert($v, $this->blk[$prevlevel]['inner_width'], $this->FontSize, false);
18273 if (isset($this->blk[$this->blklvl]['lastbottommargin'])) {
18274 if ($tmp > $this->blk[$this->blklvl]['lastbottommargin']) {
18275 $tmp -= $this->blk[$this->blklvl]['lastbottommargin'];
18280 $this->blk[$this->blklvl]['margin_top'] = $tmp;
18282 case 'MARGIN-BOTTOM':
18283 $this->blk[$this->blklvl]['margin_bottom'] = $this->sizeConverter->convert($v, $this->blk[$prevlevel]['inner_width'], $this->FontSize, false);
18285 case 'MARGIN-LEFT':
18286 $this->blk[$this->blklvl]['margin_left'] = $this->sizeConverter->convert($v, $this->blk[$prevlevel]['inner_width'], $this->FontSize, false);
18288 case 'MARGIN-RIGHT':
18289 $this->blk[$this->blklvl]['margin_right'] = $this->sizeConverter->convert($v, $this->blk[$prevlevel]['inner_width'], $this->FontSize, false);
18292 /* -- BORDER-RADIUS -- */
18293 case 'BORDER-TOP-LEFT-RADIUS-H':
18294 $this->blk[$this->blklvl]['border_radius_TL_H'] = $this->sizeConverter->convert($v, $this->blk[$prevlevel]['inner_width'], $this->FontSize, false);
18296 case 'BORDER-TOP-LEFT-RADIUS-V':
18297 $this->blk[$this->blklvl]['border_radius_TL_V'] = $this->sizeConverter->convert($v, $this->blk[$prevlevel]['inner_width'], $this->FontSize, false);
18299 case 'BORDER-TOP-RIGHT-RADIUS-H':
18300 $this->blk[$this->blklvl]['border_radius_TR_H'] = $this->sizeConverter->convert($v, $this->blk[$prevlevel]['inner_width'], $this->FontSize, false);
18302 case 'BORDER-TOP-RIGHT-RADIUS-V':
18303 $this->blk[$this->blklvl]['border_radius_TR_V'] = $this->sizeConverter->convert($v, $this->blk[$prevlevel]['inner_width'], $this->FontSize, false);
18305 case 'BORDER-BOTTOM-LEFT-RADIUS-H':
18306 $this->blk[$this->blklvl]['border_radius_BL_H'] = $this->sizeConverter->convert($v, $this->blk[$prevlevel]['inner_width'], $this->FontSize, false);
18308 case 'BORDER-BOTTOM-LEFT-RADIUS-V':
18309 $this->blk[$this->blklvl]['border_radius_BL_V'] = $this->sizeConverter->convert($v, $this->blk[$prevlevel]['inner_width'], $this->FontSize, false);
18311 case 'BORDER-BOTTOM-RIGHT-RADIUS-H':
18312 $this->blk[$this->blklvl]['border_radius_BR_H'] = $this->sizeConverter->convert($v, $this->blk[$prevlevel]['inner_width'], $this->FontSize, false);
18314 case 'BORDER-BOTTOM-RIGHT-RADIUS-V':
18315 $this->blk[$this->blklvl]['border_radius_BR_V'] = $this->sizeConverter->convert($v, $this->blk[$prevlevel]['inner_width'], $this->FontSize, false);
18317 /* -- END BORDER-RADIUS -- */
18319 case 'BOX-SHADOW':
18320 $bs = $this->cssManager->setCSSboxshadow($v);
18322 $this->blk[$this->blklvl]['box_shadow'] = $bs;
18326 case 'BACKGROUND-CLIP':
18327 if (strtoupper($v) == 'PADDING-BOX') {
18328 $this->blk[$this->blklvl]['background_clip'] = 'padding-box';
18329 } elseif (strtoupper($v) == 'CONTENT-BOX') {
18330 $this->blk[$this->blklvl]['background_clip'] = 'content-box';
18334 case 'PAGE-BREAK-AFTER':
18336 $this->blk[$this->blklvl]['page_break_after_avoid'] = true;
18338 $this->blk[$this->blklvl]['page_break_after'] = strtoupper($v);
18343 case 'BOX-DECORATION-BREAK':
18345 $this->blk[$this->blklvl]['box_decoration_break'] = 'clone';
18347 $this->blk[$this->blklvl]['box_decoration_break'] = 'slice';
18353 $this->blk[$this->blklvl]['css_set_width'] = $this->sizeConverter->convert($v, $this->blk[$prevlevel]['inner_width'], $this->FontSize, false);
18359 case 'LIST-STYLE-TYPE':
18360 $this->blk[$this->blklvl]['list_style_type'] = strtolower($v);
18362 case 'LIST-STYLE-IMAGE':
18363 $this->blk[$this->blklvl]['list_style_image'] = strtolower($v);
18365 case 'LIST-STYLE-POSITION':
18366 $this->blk[$this->blklvl]['list_style_position'] = strtolower($v);
18372 if ($type != 'INLINE' && $type != 'TABLECELL') { // All block-level, including BODY tag
18374 case 'TEXT-INDENT':
18375 // Computed value - to inherit
18376 $this->blk[$this->blklvl]['text_indent'] = $this->sizeConverter->convert($v, $this->blk[$prevlevel]['inner_width'], $this->FontSize, false) . 'mm';
18379 case 'MARGIN-COLLAPSE': // Custom tag to collapse margins at top and bottom of page
18381 $this->blk[$this->blklvl]['margin_collapse'] = true;
18385 case 'LINE-HEIGHT':
18386 $this->blk[$this->blklvl]['line_height'] = $this->fixLineheight($v);
18387 if (!$this->blk[$this->blklvl]['line_height']) {
18388 $this->blk[$this->blklvl]['line_height'] = 'N';
18393 case 'LINE-STACKING-STRATEGY':
18394 $this->blk[$this->blklvl]['line_stacking_strategy'] = strtolower($v);
18397 case 'LINE-STACKING-SHIFT':
18398 $this->blk[$this->blklvl]['line_stacking_shift'] = strtolower($v);
18401 case 'TEXT-ALIGN': // left right center justify
18404 $this->blk[$this->blklvl]['align'] = "L";
18407 $this->blk[$this->blklvl]['align'] = "C";
18410 $this->blk[$this->blklvl]['align'] = "R";
18413 $this->blk[$this->blklvl]['align'] = "J";
18418 /* -- BACKGROUNDS -- */
18419 case 'BACKGROUND-GRADIENT':
18421 $this->blk[$this->blklvl]['gradient'] = $v;
18424 /* -- END BACKGROUNDS -- */
18428 $this->blk[$this->blklvl]['direction'] = strtolower($v);
18439 $this->inlineDisplayOff = true;
18450 case 'BORDER-TOP':
18451 $this->spanborddet['T'] = $this->border_details($v);
18452 $this->spanborder = true;
18455 case 'BORDER-BOTTOM':
18456 $this->spanborddet['B'] = $this->border_details($v);
18457 $this->spanborder = true;
18460 case 'BORDER-LEFT':
18461 $this->spanborddet['L'] = $this->border_details($v);
18462 $this->spanborder = true;
18465 case 'BORDER-RIGHT':
18466 $this->spanborddet['R'] = $this->border_details($v);
18467 $this->spanborder = true;
18473 $this->textparam['visibility'] = $v;
18482 case 'TEXT-ALIGN': // left right center justify
18483 if (strtoupper($v) == 'NOJUSTIFY' && $this->blk[$this->blklvl]['align'] == "J") {
18484 $this->blk[$this->blklvl]['align'] = "";
18487 // bgcolor only - to stay consistent with original html2fpdf
18489 case 'BACKGROUND-COLOR':
18490 $cor = $this->colorConverter->convert($v, $this->PDFAXwarnings);
18493 $this->bodyBackgroundColor = $cor;
18495 $this->spanbgcolorarray = $cor;
18496 $this->spanbgcolor = true;
18499 $this->blk[$this->blklvl]['bgcolorarray'] = $cor;
18500 $this->blk[$this->blklvl]['bgcolor'] = true;
18503 if ($this->ColActive) {
18504 $this->blk[$this->blklvl]['bgcolorarray'] = $this->blk[$prevlevel]['bgcolorarray'];
18505 $this->blk[$this->blklvl]['bgcolor'] = $this->blk[$prevlevel]['bgcolor'];
18510 case 'VERTICAL-ALIGN': // super and sub only dealt with here e.g. <SUB> and <SUP>
18513 $this->textvar = ($this->textvar | TextVars::FA_SUPERSCRIPT); // mPDF 5.7.1
18514 $this->textvar = ($this->textvar & ~TextVars::FA_SUBSCRIPT);
18515 // mPDF 5.7.3 inline text-decoration parameters
18516 if (isset($this->textparam['text-baseline'])) {
18517 $this->textparam['text-baseline'] += ($this->baselineSup) * $preceeding_fontsize;
18519 $this->textparam['text-baseline'] = ($this->baselineSup) * $preceeding_fontsize;
18523 $this->textvar = ($this->textvar | TextVars::FA_SUBSCRIPT);
18524 $this->textvar = ($this->textvar & ~TextVars::FA_SUPERSCRIPT);
18525 // mPDF 5.7.3 inline text-decoration parameters
18526 if (isset($this->textparam['text-baseline'])) {
18527 $this->textparam['text-baseline'] += ($this->baselineSub) * $preceeding_fontsize;
18529 $this->textparam['text-baseline'] = ($this->baselineSub) * $preceeding_fontsize;
18533 $this->textvar = ($this->textvar & ~TextVars::FA_SUBSCRIPT);
18534 $this->textvar = ($this->textvar & ~TextVars::FA_SUPERSCRIPT);
18535 // mPDF 5.7.3 inline text-decoration parameters
18536 if (isset($this->textparam['text-baseline'])) {
18537 unset($this->textparam['text-baseline']);
18540 // mPDF 5.7.3 inline text-decoration parameters
18542 $lh = $this->_computeLineheight($this->blk[$this->blklvl]['line_height']);
18543 $sz = $this->sizeConverter->convert($v, $lh, $this->FontSize, false);
18544 $this->textvar = ($this->textvar & ~TextVars::FA_SUBSCRIPT);
18545 $this->textvar = ($this->textvar & ~TextVars::FA_SUPERSCRIPT);
18548 $this->textvar = ($this->textvar | TextVars::FA_SUPERSCRIPT);
18550 $this->textvar = ($this->textvar | TextVars::FA_SUBSCRIPT);
18552 if (isset($this->textparam['text-baseline'])) {
18553 $this->textparam['text-baseline'] += $sz;
18555 $this->textparam['text-baseline'] = $sz;
18566 case 'LETTER-SPACING':
18567 $this->lSpacingCSS = $v;
18568 if (($this->lSpacingCSS || $this->lSpacingCSS === '0') && strtoupper($this->lSpacingCSS) != 'NORMAL') {
18569 $this->fixedlSpacing = $this->sizeConverter->convert($this->lSpacingCSS, $this->FontSize);
18573 case 'WORD-SPACING':
18574 $this->wSpacingCSS = $v;
18575 if ($this->wSpacingCSS && strtoupper($this->wSpacingCSS) != 'NORMAL') {
18576 $this->minwSpacing = $this->sizeConverter->convert($this->wSpacingCSS, $this->FontSize);
18580 case 'FONT-STYLE': // italic normal oblique
18584 $this->SetStyle('I', true);
18587 $this->SetStyle('I', false);
18592 case 'FONT-WEIGHT': // normal bold // Does not support: bolder, lighter, 100..900(step value=100)
18595 $this->SetStyle('B', true);
18598 $this->SetStyle('B', false);
18603 case 'FONT-KERNING':
18604 if (strtoupper($v) == 'NORMAL' || (strtoupper($v) == 'AUTO' && $this->useKerning)) {
18605 /* -- OTL -- */
18606 if ($this->CurrentFont['haskernGPOS']) {
18607 if (isset($this->OTLtags['Plus'])) {
18608 $this->OTLtags['Plus'] .= ' kern';
18610 $this->OTLtags['Plus'] = ' kern';
18612 } /* -- END OTL -- */ else { // *OTL*
18613 $this->textvar = ($this->textvar | TextVars::FC_KERNING);
18615 } elseif (strtoupper($v) == 'NONE' || (strtoupper($v) == 'AUTO' && !$this->useKerning)) {
18616 if (isset($this->OTLtags['Plus'])) {
18617 $this->OTLtags['Plus'] = str_replace('kern', '', $this->OTLtags['Plus']); // *OTL*
18619 if (isset($this->OTLtags['FFPlus'])) {
18620 $this->OTLtags['FFPlus'] = preg_replace('/kern[\d]*/', '', $this->OTLtags['FFPlus']);
18622 $this->textvar = ($this->textvar & ~TextVars::FC_KERNING);
18626 /* -- OTL -- */
18627 case 'FONT-LANGUAGE-OVERRIDE':
18630 $this->fontLanguageOverride = '';
18632 $this->fontLanguageOverride = trim($v);
18637 case 'FONT-VARIANT-POSITION':
18638 if (isset($this->OTLtags['Plus'])) {
18639 $this->OTLtags['Plus'] = str_replace(['sups', 'subs'], '', $this->OTLtags['Plus']);
18643 $this->OTLtags['Plus'] .= ' sups';
18646 $this->OTLtags['Plus'] .= ' subs';
18653 case 'FONT-VARIANT-CAPS':
18655 if (!isset($this->OTLtags['Plus'])) {
18656 $this->OTLtags['Plus'] = '';
18658 $this->OTLtags['Plus'] = str_replace(['c2sc', 'smcp', 'c2pc', 'pcap', 'unic', 'titl'], '', $this->OTLtags['Plus']);
18659 $this->textvar = ($this->textvar & ~TextVars::FC_SMALLCAPS); // ?????????????? <small-caps>
18660 if (strpos($v, 'ALL-SMALL-CAPS') !== false) {
18661 $this->OTLtags['Plus'] .= ' c2sc smcp';
18662 } elseif (strpos($v, 'SMALL-CAPS') !== false) {
18663 if (isset($this->CurrentFont['hassmallcapsGSUB']) && $this->CurrentFont['hassmallcapsGSUB']) {
18664 $this->OTLtags['Plus'] .= ' smcp';
18666 $this->textvar = ($this->textvar | TextVars::FC_SMALLCAPS);
18668 } elseif (strpos($v, 'ALL-PETITE-CAPS') !== false) {
18669 $this->OTLtags['Plus'] .= ' c2pc pcap';
18670 } elseif (strpos($v, 'PETITE-CAPS') !== false) {
18671 $this->OTLtags['Plus'] .= ' pcap';
18673 $this->OTLtags['Plus'] .= ' unic';
18674 } elseif (strpos($v, 'TITLING-CAPS') !== false) {
18675 $this->OTLtags['Plus'] .= ' titl';
18679 case 'FONT-VARIANT-LIGATURES':
18681 if (!isset($this->OTLtags['Plus'])) {
18682 $this->OTLtags['Plus'] = '';
18684 if (!isset($this->OTLtags['Minus'])) {
18685 $this->OTLtags['Minus'] = '';
18688 $this->OTLtags['Minus'] = str_replace(['liga', 'clig', 'calt'], '', $this->OTLtags['Minus']);
18689 $this->OTLtags['Plus'] = str_replace(['dlig', 'hlig'], '', $this->OTLtags['Plus']);
18691 $this->OTLtags['Minus'] .= ' liga clig calt';
18692 $this->OTLtags['Plus'] = str_replace(['dlig', 'hlig'], '', $this->OTLtags['Plus']);
18694 if (strpos($v, 'NO-COMMON-LIGATURES') !== false) {
18695 $this->OTLtags['Minus'] .= ' liga clig';
18696 } elseif (strpos($v, 'COMMON-LIGATURES') !== false) {
18697 $this->OTLtags['Minus'] = str_replace(['liga', 'clig'], '', $this->OTLtags['Minus']);
18699 if (strpos($v, 'NO-CONTEXTUAL') !== false) {
18700 $this->OTLtags['Minus'] .= ' calt';
18702 $this->OTLtags['Minus'] = str_replace('calt', '', $this->OTLtags['Minus']);
18704 if (strpos($v, 'NO-DISCRETIONARY-LIGATURES') !== false) {
18705 $this->OTLtags['Plus'] = str_replace('dlig', '', $this->OTLtags['Plus']);
18706 } elseif (strpos($v, 'DISCRETIONARY-LIGATURES') !== false) {
18707 $this->OTLtags['Plus'] .= ' dlig';
18709 if (strpos($v, 'NO-HISTORICAL-LIGATURES') !== false) {
18710 $this->OTLtags['Plus'] = str_replace('hlig', '', $this->OTLtags['Plus']);
18711 } elseif (strpos($v, 'HISTORICAL-LIGATURES') !== false) {
18712 $this->OTLtags['Plus'] .= ' hlig';
18717 case 'FONT-VARIANT-NUMERIC':
18719 if (!isset($this->OTLtags['Plus'])) {
18720 $this->OTLtags['Plus'] = '';
18723 $this->OTLtags['Plus'] = str_replace(['ordn', 'zero', 'lnum', 'onum', 'pnum', 'tnum', 'frac', 'afrc'], '', $this->OTLtags['Plus']);
18726 $this->OTLtags['Plus'] .= ' ordn';
18728 if (strpos($v, 'SLASHED-ZERO') !== false) {
18729 $this->OTLtags['Plus'] .= ' zero';
18731 if (strpos($v, 'LINING-NUMS') !== false) {
18732 $this->OTLtags['Plus'] .= ' lnum';
18733 $this->OTLtags['Plus'] = str_replace('onum', '', $this->OTLtags['Plus']);
18734 } elseif (strpos($v, 'OLDSTYLE-NUMS') !== false) {
18735 $this->OTLtags['Plus'] .= ' onum';
18736 $this->OTLtags['Plus'] = str_replace('lnum', '', $this->OTLtags['Plus']);
18738 if (strpos($v, 'PROPORTIONAL-NUMS') !== false) {
18739 $this->OTLtags['Plus'] .= ' pnum';
18740 $this->OTLtags['Plus'] = str_replace('tnum', '', $this->OTLtags['Plus']);
18741 } elseif (strpos($v, 'TABULAR-NUMS') !== false) {
18742 $this->OTLtags['Plus'] .= ' tnum';
18743 $this->OTLtags['Plus'] = str_replace('pnum', '', $this->OTLtags['Plus']);
18745 if (strpos($v, 'DIAGONAL-FRACTIONS') !== false) {
18746 $this->OTLtags['Plus'] .= ' frac';
18747 $this->OTLtags['Plus'] = str_replace('afrc', '', $this->OTLtags['Plus']);
18748 } elseif (strpos($v, 'STACKED-FRACTIONS') !== false) {
18749 $this->OTLtags['Plus'] .= ' afrc';
18750 $this->OTLtags['Plus'] = str_replace('frac', '', $this->OTLtags['Plus']);
18754 case 'FONT-VARIANT-ALTERNATES': // Only supports historical-forms
18756 if (!isset($this->OTLtags['Plus'])) {
18757 $this->OTLtags['Plus'] = '';
18760 $this->OTLtags['Plus'] = str_replace('hist', '', $this->OTLtags['Plus']);
18762 if (strpos($v, 'HISTORICAL-FORMS') !== false) {
18763 $this->OTLtags['Plus'] .= ' hist';
18768 case 'FONT-FEATURE-SETTINGS':
18771 $this->OTLtags['FFMinus'] = '';
18772 $this->OTLtags['FFPlus'] = '';
18774 if (!isset($this->OTLtags['FFPlus'])) {
18775 $this->OTLtags['FFPlus'] = '';
18777 if (!isset($this->OTLtags['FFMinus'])) {
18778 $this->OTLtags['FFMinus'] = '';
18782 if (preg_match('/[\"\']([a-zA-Z0-9]{4})[\"\']\s*(on|off|\d*){0,1}/', $t, $m)) {
18784 if (strpos($this->OTLtags['FFMinus'], $m[1]) === false) {
18785 $this->OTLtags['FFMinus'] .= ' ' . $m[1];
18787 $this->OTLtags['FFPlus'] = preg_replace('/' . $m[1] . '[\d]*/', '', $this->OTLtags['FFPlus']);
18792 if (strpos($this->OTLtags['FFPlus'], $m[1]) === false) {
18793 $this->OTLtags['FFPlus'] .= ' ' . $m[1] . $m[2];
18795 $this->OTLtags['FFMinus'] = str_replace($m[1], '', $this->OTLtags['FFMinus']);
18801 /* -- END OTL -- */
18804 case 'TEXT-TRANSFORM': // none uppercase lowercase // Does support: capitalize
18807 $this->textvar = ($this->textvar | TextVars::FT_CAPITALIZE); // mPDF 5.7.1
18808 $this->textvar = ($this->textvar & ~TextVars::FT_UPPERCASE); // mPDF 5.7.1
18809 $this->textvar = ($this->textvar & ~TextVars::FT_LOWERCASE); // mPDF 5.7.1
18812 $this->textvar = ($this->textvar | TextVars::FT_UPPERCASE); // mPDF 5.7.1
18813 $this->textvar = ($this->textvar & ~TextVars::FT_LOWERCASE); // mPDF 5.7.1
18814 $this->textvar = ($this->textvar & ~TextVars::FT_CAPITALIZE); // mPDF 5.7.1
18817 $this->textvar = ($this->textvar | TextVars::FT_LOWERCASE); // mPDF 5.7.1
18818 $this->textvar = ($this->textvar & ~TextVars::FT_UPPERCASE); // mPDF 5.7.1
18819 $this->textvar = ($this->textvar & ~TextVars::FT_CAPITALIZE); // mPDF 5.7.1
18823 $this->textvar = ($this->textvar & ~TextVars::FT_UPPERCASE); // mPDF 5.7.1
18824 $this->textvar = ($this->textvar & ~TextVars::FT_LOWERCASE); // mPDF 5.7.1
18825 $this->textvar = ($this->textvar & ~TextVars::FT_CAPITALIZE); // mPDF 5.7.1
18829 case 'TEXT-SHADOW':
18830 $ts = $this->cssManager->setCSStextshadow($v);
18832 $this->textshadow = $ts;
18838 $this->textparam['hyphens'] = 2;
18840 $this->textparam['hyphens'] = 1;
18842 $this->textparam['hyphens'] = 0;
18846 case 'TEXT-OUTLINE':
18848 $this->textparam['outline-s'] = false;
18852 case 'TEXT-OUTLINE-WIDTH':
18853 case 'OUTLINE-WIDTH':
18865 $w = $this->sizeConverter->convert($v, $this->FontSize, $this->FontSize);
18867 $this->textparam['outline-WIDTH'] = $w;
18868 $this->textparam['outline-s'] = true;
18870 $this->textparam['outline-s'] = false;
18874 case 'TEXT-OUTLINE-COLOR':
18875 case 'OUTLINE-COLOR':
18877 if ($this->colorarray) {
18878 $cor = $this->colorarray;
18879 $this->textparam['outline-COLOR'] = $this->colorConverter->invert($cor);
18881 $this->textparam['outline-COLOR'] = $this->colorConverter->convert(255, $this->PDFAXwarnings);
18884 $cor = $this->colorConverter->convert($v, $this->PDFAXwarnings);
18886 $this->textparam['outline-COLOR'] = $cor;
18891 case 'COLOR': // font color
18892 $cor = $this->colorConverter->convert($v, $this->PDFAXwarnings);
18894 $this->colorarray = $cor;
18895 $this->SetTColor($cor);
18900 // mPDF 5.7.3 inline text-decoration parameters
18901 // Needs to be set at the end - after vertical-align = super/sub, so that textparam['text-baseline'] is set
18902 if (isset($arrayaux['TEXT-DECORATION'])) {
18903 $v = $arrayaux['TEXT-DECORATION']; // none underline line-through (strikeout) // Does not support: blink
18904 if (stristr($v, 'LINE-THROUGH')) {
18905 $this->textvar = ($this->textvar | TextVars::FD_LINETHROUGH);
18906 // mPDF 5.7.3 inline text-decoration parameters
18907 if (isset($this->textparam['text-baseline'])) {
18908 $this->textparam['s-decoration']['baseline'] = $this->textparam['text-baseline'];
18910 $this->textparam['s-decoration']['baseline'] = 0;
18912 $this->textparam['s-decoration']['fontkey'] = $this->FontFamily . $this->FontStyle;
18913 $this->textparam['s-decoration']['fontsize'] = $this->FontSize;
18914 $this->textparam['s-decoration']['color'] = strtoupper($this->TextColor); // change 0 0 0 rg to 0 0 0 RG
18917 $this->textvar = ($this->textvar | TextVars::FD_UNDERLINE);
18918 // mPDF 5.7.3 inline text-decoration parameters
18919 if (isset($this->textparam['text-baseline'])) {
18920 $this->textparam['u-decoration']['baseline'] = $this->textparam['text-baseline'];
18922 $this->textparam['u-decoration']['baseline'] = 0;
18924 $this->textparam['u-decoration']['fontkey'] = $this->FontFamily . $this->FontStyle;
18925 $this->textparam['u-decoration']['fontsize'] = $this->FontSize;
18926 $this->textparam['u-decoration']['color'] = strtoupper($this->TextColor); // change 0 0 0 rg to 0 0 0 RG
18929 $this->textvar = ($this->textvar | TextVars::FD_OVERLINE);
18930 // mPDF 5.7.3 inline text-decoration parameters
18931 if (isset($this->textparam['text-baseline'])) {
18932 $this->textparam['o-decoration']['baseline'] = $this->textparam['text-baseline'];
18934 $this->textparam['o-decoration']['baseline'] = 0;
18936 $this->textparam['o-decoration']['fontkey'] = $this->FontFamily . $this->FontStyle;
18937 $this->textparam['o-decoration']['fontsize'] = $this->FontSize;
18938 $this->textparam['o-decoration']['color'] = strtoupper($this->TextColor); // change 0 0 0 rg to 0 0 0 RG
18941 $this->textvar = ($this->textvar & ~TextVars::FD_UNDERLINE);
18942 $this->textvar = ($this->textvar & ~TextVars::FD_LINETHROUGH);
18943 $this->textvar = ($this->textvar & ~TextVars::FD_OVERLINE);
18944 // mPDF 5.7.3 inline text-decoration parameters
18945 if (isset($this->textparam['u-decoration'])) {
18946 unset($this->textparam['u-decoration']);
18948 if (isset($this->textparam['s-decoration'])) {
18949 unset($this->textparam['s-decoration']);
18951 if (isset($this->textparam['o-decoration'])) {
18952 unset($this->textparam['o-decoration']);
18958 if (isset($this->textparam['text-baseline'])) {
18959 $this->textparam['bord-decoration']['baseline'] = $this->textparam['text-baseline'];
18961 $this->textparam['bord-decoration']['baseline'] = 0;
18963 $this->textparam['bord-decoration']['fontkey'] = $this->FontFamily . $this->FontStyle;
18964 $this->textparam['bord-decoration']['fontsize'] = $this->FontSize;
18966 if ($spanbgset) { // BACKGROUND[-COLOR] has been set on this INLINE element
18967 if (isset($this->textparam['text-baseline'])) {
18968 $this->textparam['bg-decoration']['baseline'] = $this->textparam['text-baseline'];
18970 $this->textparam['bg-decoration']['baseline'] = 0;
18972 $this->textparam['bg-decoration']['fontkey'] = $this->FontFamily . $this->FontStyle;
18973 $this->textparam['bg-decoration']['fontsize'] = $this->FontSize;
18977 /* -- END HTML-CSS -- */
18981 $this->$tag = $enable;
18984 if ($this->$s) {
18988 $this->currentfontstyle = $style;
18989 $this->SetFont('', $style, 0, false);
18999 $this->$s = true;
19002 $this->$s = false;
19004 } elseif ($this->$s) {
19008 $this->currentfontstyle = $style;
19009 $this->SetFont('', $style, 0, false);
19018 $this->$s = true;
19021 $this->$s = false;
19024 $this->currentfontstyle = $style;
19025 $this->SetFont('', $style, 0, false);
19031 $this->$s = false;
19033 $this->currentfontstyle = '';
19034 $this->SetFont('', '', 0, false);
19041 $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>";
19045 $this->enabledtags = str_replace(trim($v), '', $this->enabledtags);
19050 /* -- TABLES -- */
19068 if ($this->iterationCounter) {
19069 $line = preg_replace('/{iteration ([a-zA-Z0-9_]+)}/', '\\1', $line);
19073 if (substr($line, 0, 3) == "\xbb\xa4\xac") { // inline object - FORM element or IMAGE!
19074 $objattr = $this->_getObjAttr($line);
19075 if ($objattr['type'] != 'hr' && isset($objattr['width']) && ($objattr['width'] / $this->shrin_k) > ($maxwidth + 0.0001)) {
19076 if (($objattr['width'] / $this->shrin_k) > $biggestword) {
19077 $biggestword = ($objattr['width'] / $this->shrin_k);
19090 $this->otl->trimOTLdata($OTLdata, true, true);
19092 // SET FONT SIZE/STYLE from $chunk[n]
19095 if ($this->shrin_k) {
19096 $this->SetFontSize($chunk[11] / $this->shrin_k, false);
19098 $this->SetFontSize($chunk[11], false);
19103 $font = $this->SetFont($chunk[4], $this->FontStyle, 0, false);
19107 $this->SetStyles($chunk[2]);
19112 $this->spanborddet = $chunk[16];
19113 $lbw = (isset($this->spanborddet['L']['w']) ? $this->spanborddet['L']['w'] : 0);
19114 $rbw = (isset($this->spanborddet['R']['w']) ? $this->spanborddet['R']['w'] : 0);
19117 $this->wSpacingCSS = $chunk[15];
19118 if ($this->wSpacingCSS && strtoupper($this->wSpacingCSS) != 'NORMAL') {
19119 $this->minwSpacing = $this->sizeConverter->convert($this->wSpacingCSS, $this->FontSize) / $this->shrin_k; // mPDF 5.7.3
19123 $this->lSpacingCSS = $chunk[14];
19124 if (($this->lSpacingCSS || $this->lSpacingCSS === '0') && strtoupper($this->lSpacingCSS) != 'NORMAL') {
19125 $this->fixedlSpacing = $this->sizeConverter->convert($this->lSpacingCSS, $this->FontSize) / $this->shrin_k; // mPDF 5.7.3
19129 $this->textvar = $chunk[8];
19134 if ($checkletter || (!preg_match('/(\xe2\x80\x8b| )/', trim($line)) && preg_match("/([" . $this->pregCJKchars . "])/u", $line) )) {
19135 if (preg_match("/([" . $this->pregCJKchars . "])/u", $line)) {
19145 if (preg_match("/[" . $this->CJKleading . "]/u", $letter) && $k > 0) {
19146 $letter = $letters[$k - 1] . $letter;
19148 if (preg_match("/[" . $this->CJKfollowing . "]/u", $letter) && $k < (count($letters) - 1)) {
19153 $letterwidth = $this->GetStringWidth($letter, false, false, $chunk[8]); // Pass $textvar ($chunk[8]), but do OTLdata here
19158 if ($k == (count($letters) - 1)) {
19177 $k = -1; // Added so that if no spaces found, "last word" later is calculated for the one and only word
19209 $wordwidth = $this->GetStringWidth($word, false, false, $chunk[8]); // Pass $textvar ($chunk[8]), but do OTLdata here
19212 $wordwidth += ($wordXAdvance[$k] * 1000 / $this->CurrentFont['unitsPerEm']) * ($this->FontSize / 1000);
19217 if ($k == (count($words) - 1)) {
19230 if (count($words) == 1 && substr($chunk[0], -1, 1) == ' ') {
19232 } elseif (count($words) > 1 && ($k != (count($words) - 1) || substr($chunk[0], -1, 1) == ' ')) {
19246 // mPDF 6 Accumulated length of biggest word - across multiple chunks
19254 // RESET FONT SIZE/STYLE
19258 $this->ResetStyles();
19261 $this->SetFont($this->default_font, $this->FontStyle, 0, false);
19264 $this->SetFontSize($this->default_font_size, false);
19266 $this->spanborddet = [];
19267 $this->textvar = 0x00; // mPDF 5.7.1
19268 $this->OTLtags = [];
19269 $this->lSpacingCSS = '';
19270 $this->wSpacingCSS = '';
19271 $this->fixedlSpacing = false;
19272 $this->minwSpacing = 0;
19275 // Return -(wordsize) if word is bigger than maxwidth
19277 if (($toonarrow) && ($this->table_error_report)) {
19278 throw new \Mpdf\MpdfException("Word is too long to fit in table - " . $this->table_error_report_param);
19281 return -$biggestword;
19320 if ($this->simpleTables) {
19356 if (!$this->simpleTables) {
19358 if ($this->packTableData) {
19360 $cell = $this->_unpackCellBorder($c['borderbin']);
19375 $c['borderbin'] = $this->_packCellBorder($cell);
19436 $a = ($a - (1 << 16));
19447 if (!$this->packTableData) {
19460 if (!$this->packTableData) {
19477 if (!$this->packTableData) {
19548 // = total length of text approx (using $c['s']) in that column - used to approximately distribute col widths in _tableWidth
19556 if ($this->simpleTables) {
19563 if ($this->packTableData) {
19564 list($bt, $br, $bb, $bl) = $this->_getBorderWidths($c['borderbin']);
19576 // $mw = $this->GetStringWidth('W') + $extrcw ;
19585 $c['maw'] = $c['miw'] = $this->FontSize + $extrcw;
19633 if (isset($c['nestedmiw']) && (!isset($this->table[1][1]['overflow']) || $this->table[1][1]['overflow'] != 'visible')) {
19651 if (($c['maw'] + $tblbw) > $this->blk[$this->blklvl]['inner_width']) {
19652 $c['maw'] = $this->blk[$this->blklvl]['inner_width'] - $tblbw;
19661 if (isset($c['colspan'])) { // Not perfect - but % set on colspan is shared equally on cols.
19667 $c['w'] = $c['wpercent'] / 100 * ($table['w'] - $tblbw );
19674 if (isset($c['w']) && ($c['w'] + $tblbw) > $this->blk[$this->blklvl]['inner_width']) {
19675 $c['w'] = $this->blk[$this->blklvl]['inner_width'] - $tblbw;
19688 // cf. http://www.mpdf1.com/forum/discussion/2221/colspan-bug
19694 // mPDF 5.7.3 cf. http://www.mpdf1.com/forum/discussion/1648/nested-table-bug-
19698 } // If cell width not specified -> set Cell min width it to minimum allowed (W)
19702 } // If Cell max width < Minwidth - increase it to =
19732 $minwidth = $this->TableCheckMinWidth($wc['miw'] - $extrcw, 0, $c['textbuffer'], $letter);
19739 $wc['miw'] = max((isset($wc['miw']) ? $wc['miw'] : 0), ((-$minwidth) + $extrcw));
19741 $c['miw'] = max((isset($c['miw']) ? $c['miw'] : 0), ((-$minwidth) + $extrcw));
19793 $wi = $c['miw'] - $wis;
19798 $wi = $c['miw'] - $wis;
19814 $wi = $c['maw'] - $was;
19819 $wi = $c['maw'] - $was;
19821 // cf. http://www.mpdf1.com/forum/discussion/2221/colspan-bug
19864 $sumnonpc = (100 - $sumpc);
19895 if (($miwnon > $checkminwidth || $maxcalcmiw > $checkminwidth) && $this->keep_table_proportions) {
19897 $miwsurplusnonpc = round((($miwnon * $sumnonpc / 100) - $miwleft), 3);
19916 $mawsurplusnonpc = round((($mawnon * $sumnonpc / 100) - $mawleft), 3);
19961 if ($this->table_rotate) {
19962 $mxw = $this->tbrot_maxw;
19964 $mxw = $this->blk[$this->blklvl]['inner_width'];
19973 } elseif ($table['overflow'] == 'hidden' && !$this->table_rotate && !$this->ColActive && $checkminwidth > $mxw) {
19983 } elseif ($table['w'] >= $checkminwidth && $table['w'] > $mxw && $this->keep_table_proportions) {
19985 } elseif ($table['w'] < $checkminwidth && $checkminwidth < $mxw && $this->keep_table_proportions) {
20018 $table['w'] = $temppgwidth = (($table['w'] - $tblbw) * $table['wpercent'] / 100) + $tblbw;
20023 } elseif ($this->table_rotate) {
20025 $temppgwidth = $this->tbrot_maxw;
20028 $enddiv = $this->blk[$this->blklvl]['padding_bottom'] + $this->blk[$this->blklvl]['border_bottom']['w'];
20031 $temppgwidth -= $enddiv;
20036 if (isset($table['w']) && $table['w'] < $this->blk[$this->blklvl]['inner_width']) {
20041 } elseif ($table['overflow'] == 'hidden' && !$this->ColActive && isset($table['w']) && $table['w'] > $this->blk[$this->blklvl]['inner_width'] && $table['w'] == $table) {
20042 // $temppgwidth = $this->blk[$this->blklvl]['inner_width'];
20045 $temppgwidth = $this->blk[$this->blklvl]['inner_width'];
20050 $totaltextlength = 0; // Added - to sum $table['l'][colno]
20051 $totalatextlength = 0; // Added - to sum $table['l'][colno] for those columns where width not set
20083 // IF the table width is now set - Need to distribute columns widths
20101 if (!isset($widthcols[$i]['w']) || ($widthcols[$i]['w'] && $table['w'] > $temppgwidth && !$this->keep_table_proportions && !$notfullwidth )) {
20117 if ($table['w'] < $temppgwidth || $this->keep_table_proportions) {
20121 $widthcols[$k]['miw'] = ($table['w'] - $tblbw) * $widthcols[$k]['wpercent'] / 100;
20122 $wis += $widthcols[$k]['miw'] - $curr;
20123 $wisa += $widthcols[$k]['miw'] - $curr;
20134 $wi = ($table['w'] - ($wis + $tblbw)); // i.e. extra space to distribute
20140 // Don't allocate more than Maximum required width - save rest in surplus
20142 $surplus += ($wi * $spareratio) - ($widthcols[$k]['maw'] - $widthcols[$k]['miw']);
20153 $wi = ($table['w'] - ($wis + $tblbw)); // i.e. extra space to distribute
20159 // Don't allocate more than Maximum required width - save rest in surplus
20161 $surplus += ($wi * $spareratio) - ($widthcols[$k]['maw'] - $widthcols[$k]['miw']);
20174 if (count($notsetlist) && count($notsetlist) < $numcols) { // if some are set only add to remaining - otherwise add to all of them
20207 if ($checktablewidth > ($temppgwidth + 0.001 - $tblbw)) {
20213 if ((isset($widthcols[$i]) && $widthcols[$i] > (($temppgwidth - $tblbw) / $numcols)) && (!isset($widthcols[$i]['w']))) {
20223 $widthcols[$i] = ((($temppgwidth - $tblbw) - $usedup) / ($numleft));
20234 if (isset($widthcols[$i]['wpercent']) && $this->keep_table_proportions) {
20250 if ($tablewidth > $this->blk[$this->blklvl]['inner_width']) {
20267 if ($w > $this->blk[$this->blklvl]['inner_width']) {
20268 $diff = $w - ($this->blk[$this->blklvl]['inner_width'] - $tblbw);
20270 $widthcols[$c] -= $diff * ($widthcols[$c] / $w);
20272 $table['w'] -= $diff;
20273 $table['csp'][$j] = $w - $diff;
20293 if (($currWc + $w + $tblbw) > $this->blk[$this->blklvl]['inner_width']) {
20321 if ($this->table_rotate) {
20322 $temppgheight = $this->tbrot_maxh;
20323 $remainingpage = $this->tbrot_maxh;
20325 $temppgheight = ($this->h - $this->bMargin - $this->tMargin) - $this->kwt_height;
20326 $remainingpage = ($this->h - $this->bMargin - $this->y) - $this->kwt_height;
20330 $enddiv = $this->blk[$this->blklvl]['padding_bottom'] + $this->blk[$this->blklvl]['border_bottom']['w'] + $table['margin']['B'];
20332 $remainingpage -= $enddiv;
20337 $temppgheight -= $enddiv;
20355 if ($this->simpleTables) {
20364 if ($this->packTableData) {
20365 list($bt, $br, $bb, $bl) = $this->_getBorderWidths($c['borderbin']);
20382 list($x, $cw) = $this->_splitTableGetWidth($table, $i, $j);
20384 list($x, $cw) = $this->_tableGetWidth($table, $i, $j);
20396 $s_fs = $this->FontSizePt;
20397 $s_f = $this->FontFamily;
20398 $s_st = $this->FontStyle;
20399 $this->SetFont($c['textbuffer'][0][4], $c['textbuffer'][0][2], $c['textbuffer'][0][11] / $this->shrin_k, true, true);
20400 $tempch = $this->GetStringWidth($str, true, $c['textbuffer'][0][18], $c['textbuffer'][0][8]);
20402 $tempch = ((sin(deg2rad($c['R']))) * $tempch ) + ((sin(deg2rad($c['R']))) * (($c['textbuffer'][0][11] / Mpdf::SCALE) / $this->shrin_k));
20404 $this->SetFont($s_f, $s_st, $s_fs, true, true);
20408 $this->cellLineHeight = $c['cellLineHeight'];
20409 $this->cellLineStackingStrategy = $c['cellLineStackingStrategy'];
20410 $this->cellLineStackingShift = $c['cellLineStackingShift'];
20411 $this->divwidth = $cw - $extraWLR;
20412 $tempch = $this->printbuffer($c['textbuffer'], '', true, true);
20435 if ($i == ($numrows - 1) || (isset($c['rowspan']) && ($i + $c['rowspan']) == ($numrows))) {
20441 if (!$this->simpleTables) {
20443 } elseif ($this->simpleTables) {
20461 if ($this->tableLevel == 1 && $i == (isset($table['headernrows']) ? $table['headernrows'] : 0)) {
20499 if ($i == ($numrows - 1) || ($i + $c['rowspan']) == ($numrows)) {
20505 if (!$this->simpleTables) {
20506 if ($this->packTableData) {
20507 list($bt, $br, $bb, $bl) = $this->_getBorderWidths($c['borderbin']);
20512 } elseif ($this->simpleTables) {
20526 if ($this->tableLevel == 1 && $i == (isset($table['headernrows']) ? $table['headernrows'] : 0)) {
20536 $hi = $c['mih'] - $hs;
20541 $hi = $c['mih'] - $hs; // mPDF 6
20559 if (($cki + $c['rowspan'] - 1) >= $i) {
20564 $bottom = $i + $c['rowspan'] - 1;
20571 // check again that top and bottom are not crossed by rowspans - or abort (too complicated)
20590 // Intentionally do not substract border-spacing
20616 $newhr[$i] = $extH - array_sum($newhr);
20654 for ($k = $j + $cell['colspan'] - 1; $k > $j; $k--) {
20682 for ($k = $j + $cell['colspan'] - 1; $k > $j; $k--) {
20709 for ($k = $i + $cell['rowspan'] - 1; $k > $i; $k--) {
20713 $this->logger->debug('Possible non-wellformed HTML markup in a table', ['context' => LogContext::HTML_MARKUP]);
20726 if ($row == $table['nc'] - 1) {
20750 // CHANGED TO ALLOW TABLE BORDER TO BE SPECIFIED CORRECTLY - added border_details
20751 function _tableRect($x, $y, $w, $h, $bord = -1, $details = [], $buffer = false, $bSeparate = false, $cort = 'cell', $tablecorner = '', $bsv = 0, $bsh = 0)
20755 if ($bord == -1) {
20756 $this->Rect($x, $y, $w, $h);
20757 } elseif ($this->simpleTables && ($cort == 'cell')) {
20758 $this->SetLineWidth($details['L']['w']);
20760 $this->SetDColor($details['L']['c']);
20762 $this->SetDColor($this->colorConverter->convert(0, $this->PDFAXwarnings));
20764 $this->SetLineJoin(0);
20765 $this->Rect($x, $y, $w, $h);
20778 $dom += (array_search($details[$side]['style'], $this->borderstyles) * 100);
20788 $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);
20790 } // 10 black - 0 white
20800 if ($side == 'T' && $this->issetBorder($bord, Border::TOP)) {
20803 } elseif ($side == 'L' && $this->issetBorder($bord, Border::LEFT)) {
20806 } elseif ($side == 'R' && $this->issetBorder($bord, Border::RIGHT)) {
20809 } elseif ($side == 'B' && $this->issetBorder($bord, Border::BOTTOM)) {
20815 $this->cellBorderBuffer[] = pack("A16nCnda6A10d14", str_pad(sprintf("%08.7f", $dom), 16, "0", STR_PAD_LEFT), $cbord, ord($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);
20818 $this->cellBorderBuffer[] = pack("A16nCnda6A10d14", str_pad(sprintf("%08.7f", ($dom + 4)), 16, "0", STR_PAD_LEFT), $cbord, ord($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);
20849 $oldlinewidth = $this->LineWidth;
20858 if ($Tw && $side == 'T' && $this->issetBorder($bord, Border::TOP)) { // TOP
20863 $this->SetLineWidth($Tw);
20866 $xadj = ($Tw - $Lw) / 2;
20872 $xadj = $Tw / 2 - $bsh / 2;
20876 $xadj2 = ($Tw - $Rw) / 2;
20882 $xadj2 = $Tw / 2 - $bsh / 2;
20885 $xadj = ($Tw - $details['mbw']['TL']) / 2;
20888 $xadj2 = ($Tw - $details['mbw']['TR']) / 2;
20892 if ($Lw && $side == 'L' && $this->issetBorder($bord, Border::LEFT)) { // LEFT
20897 $this->SetLineWidth($Lw);
20900 $yadj = ($Lw - $Tw) / 2;
20906 $yadj = $Lw / 2 - $bsv / 2;
20910 $yadj2 = ($Lw - $Bw) / 2;
20916 $yadj2 = $Lw / 2 - $bsv / 2;
20919 $yadj = ($Lw - $details['mbw']['LT']) / 2;
20922 $yadj2 = ($Lw - $details['mbw']['LB']) / 2;
20926 if ($Rw && $side == 'R' && $this->issetBorder($bord, Border::RIGHT)) { // RIGHT
20931 $this->SetLineWidth($Rw);
20937 $yadj = ($Rw - $Tw) / 2;
20940 $yadj = $Rw / 2 - $bsv / 2;
20945 $yadj2 = ($Rw - $Bw) / 2;
20951 $yadj2 = $Rw / 2 - $bsv / 2;
20955 $yadj = ($Rw - $details['mbw']['RT']) / 2;
20958 $yadj2 = ($Rw - $details['mbw']['RB']) / 2;
20962 if ($Bw && $side == 'B' && $this->issetBorder($bord, Border::BOTTOM)) { // BOTTOM
20967 $this->SetLineWidth($Bw);
20970 $xadj = ($Bw - $Lw) / 2;
20976 $xadj = $Bw / 2 - $bsh / 2;
20980 $xadj2 = ($Bw - $Rw) / 2;
20986 $xadj2 = $Bw / 2 - $bsh / 2;
20989 $xadj = ($Bw - $details['mbw']['BL']) / 2;
20992 $xadj2 = ($Bw - $details['mbw']['BR']) / 2;
20999 /* -- TABLES-ADVANCED-BORDERS -- */
21003 $this->SetDColor($details[$side]['c']);
21005 $this->SetDColor($this->colorConverter->convert(0, $this->PDFAXwarnings));
21007 $this->Line($lx1 + $xadj, $ly1 + $yadj, $lx2 - $xadj2, $ly2 - $yadj2);
21012 $xadj -= $this->LineWidth / 2;
21013 $xadj2 -= $this->LineWidth;
21014 if ($this->issetBorder($bord, Border::LEFT)) {
21015 $xadj += $this->LineWidth / 2;
21017 if ($this->issetBorder($bord, Border::RIGHT)) {
21018 $xadj2 += $this->LineWidth;
21022 $yadj -= $this->LineWidth / 2;
21023 $yadj2 -= $this->LineWidth;
21024 if ($this->issetBorder($bord, Border::TOP)) {
21025 $yadj += $this->LineWidth / 2;
21027 if ($this->issetBorder($bord, Border::BOTTOM)) {
21028 $yadj2 += $this->LineWidth;
21032 $xadj -= $this->LineWidth / 2;
21033 $xadj2 -= $this->LineWidth;
21034 if ($this->issetBorder($bord, Border::LEFT)) {
21035 $xadj += $this->LineWidth / 2;
21037 if ($this->issetBorder($bord, Border::RIGHT)) {
21038 $xadj2 += $this->LineWidth;
21042 $yadj -= $this->LineWidth / 2;
21043 $yadj2 -= $this->LineWidth;
21044 if ($this->issetBorder($bord, Border::TOP)) {
21045 $yadj += $this->LineWidth / 2;
21047 if ($this->issetBorder($bord, Border::BOTTOM)) {
21048 $yadj2 += $this->LineWidth;
21053 $this->SetLineWidth($this->LineWidth / 3);
21055 $tbcol = $this->colorConverter->convert(255, $this->PDFAXwarnings);
21056 for ($l = 0; $l <= $this->blklvl; $l++) {
21057 if ($this->blk[$l]['bgcolor']) {
21058 $tbcol = ($this->blk[$l]['bgcolorarray']);
21066 'x2' => $lx2 - $xadj2,
21067 'y2' => $ly2 - $yadj2,
21069 'lw' => $this->LineWidth,
21072 $this->SetDColor($tbcol);
21073 $this->Line($lx1 + $xadj, $ly1 + $yadj, $lx2 - $xadj2, $ly2 - $yadj2);
21079 $this->SetDColor($details[$side]['c']);
21081 $this->SetDColor($this->colorConverter->convert(0, $this->PDFAXwarnings));
21084 $nc = $this->colorConverter->darken($details[$side]['c']);
21085 $this->SetDColor($nc);
21087 $nc = $this->colorConverter->lighten($details[$side]['c']);
21088 $this->SetDColor($nc);
21090 $this->Line($lx1 + $xadj, $ly1 + $yadj, $lx2 - $xadj2, $ly2 - $yadj2);
21094 $this->SetDColor($details[$side]['c']);
21096 $this->SetDColor($this->colorConverter->convert(0, $this->PDFAXwarnings));
21098 $doubleadj = ($this->LineWidth) / 3;
21099 $this->SetLineWidth($this->LineWidth / 2);
21103 $nc = $this->colorConverter->darken($details[$side]['c']);
21107 $yadj3 = $this->LineWidth / 2;
21108 $xadj3 = -$this->LineWidth / 2;
21109 $wadj3 = $this->LineWidth;
21110 if ($this->issetBorder($bord, Border::LEFT)) {
21111 $xadj3 += $this->LineWidth;
21112 $wadj3 -= $this->LineWidth;
21114 if ($this->issetBorder($bord, Border::RIGHT)) {
21115 $wadj3 -= $this->LineWidth * 2;
21119 $xadj3 = $this->LineWidth / 2;
21120 $yadj3 = -$this->LineWidth / 2;
21121 $hadj3 = $this->LineWidth;
21122 if ($this->issetBorder($bord, Border::TOP)) {
21123 $yadj3 += $this->LineWidth;
21124 $hadj3 -= $this->LineWidth;
21126 if ($this->issetBorder($bord, Border::BOTTOM)) {
21127 $hadj3 -= $this->LineWidth * 2;
21131 $yadj3 = $this->LineWidth / 2;
21132 $xadj3 = -$this->LineWidth / 2;
21133 $wadj3 = $this->LineWidth;
21136 $xadj3 = $this->LineWidth / 2;
21137 $yadj3 = -$this->LineWidth / 2;
21138 $hadj3 = $this->LineWidth;
21141 $yadj3 = $this->LineWidth / 2;
21142 $xadj3 = $this->LineWidth / 2;
21143 $wadj3 = -$this->LineWidth * 2;
21145 $xadj3 = $this->LineWidth / 2;
21146 $yadj3 = $this->LineWidth / 2;
21147 $hadj3 = -$this->LineWidth * 2;
21149 $yadj3 = $this->LineWidth / 2;
21150 $wadj3 = $this->LineWidth / 2;
21152 $xadj3 = $this->LineWidth / 2;
21153 $hadj3 = $this->LineWidth / 2;
21155 $yadj3 = $this->LineWidth / 2;
21156 $xadj3 = $this->LineWidth / 2;
21158 $xadj3 = $this->LineWidth / 2;
21159 $yadj3 = $this->LineWidth / 2;
21162 $nc = $this->colorConverter->lighten($details[$side]['c']);
21166 $yadj3 = $this->LineWidth / 2;
21167 $xadj3 = -$this->LineWidth / 2;
21168 $wadj3 = $this->LineWidth;
21169 if ($this->issetBorder($bord, Border::LEFT)) {
21170 $xadj3 += $this->LineWidth;
21171 $wadj3 -= $this->LineWidth;
21175 $xadj3 = $this->LineWidth / 2;
21176 $yadj3 = -$this->LineWidth / 2;
21177 $hadj3 = $this->LineWidth;
21178 if ($this->issetBorder($bord, Border::TOP)) {
21179 $yadj3 += $this->LineWidth;
21180 $hadj3 -= $this->LineWidth;
21184 $yadj3 = $this->LineWidth / 2;
21185 $xadj3 = -$this->LineWidth / 2;
21186 $wadj3 = $this->LineWidth;
21187 if ($this->issetBorder($bord, Border::LEFT)) {
21188 $xadj3 += $this->LineWidth;
21189 $wadj3 -= $this->LineWidth;
21193 $xadj3 = $this->LineWidth / 2;
21194 $yadj3 = -$this->LineWidth / 2;
21195 $hadj3 = $this->LineWidth;
21196 if ($this->issetBorder($bord, Border::TOP)) {
21197 $yadj3 += $this->LineWidth;
21198 $hadj3 -= $this->LineWidth;
21202 $yadj3 = $this->LineWidth / 2;
21203 $xadj3 = $this->LineWidth / 2;
21205 $xadj3 = $this->LineWidth / 2;
21206 $yadj3 = $this->LineWidth / 2;
21208 $yadj3 = $this->LineWidth / 2;
21209 $xadj3 = $this->LineWidth / 2;
21211 $xadj3 = $this->LineWidth / 2;
21212 $yadj3 = $this->LineWidth / 2;
21214 $yadj3 = $this->LineWidth / 2;
21215 $xadj3 = -$this->LineWidth / 2;
21216 $wadj3 = $this->LineWidth;
21218 $xadj3 = $this->LineWidth / 2;
21219 $yadj3 = -$this->LineWidth / 2;
21220 $hadj3 = $this->LineWidth;
21228 'x2' => $lx2 - $xadj2 + $xadj3 + $wadj3,
21229 'y2' => $ly2 - $yadj2 + $yadj3 + $hadj3,
21231 'lw' => $this->LineWidth,
21234 $this->SetDColor($nc);
21235 $this->Line($lx1 + $xadj + $xadj3, $ly1 + $yadj + $yadj3, $lx2 - $xadj2 + $xadj3 + $wadj3, $ly2 - $yadj2 + $yadj3 + $hadj3);
21239 /* -- END TABLES-ADVANCED-BORDERS -- */
21243 $this->SetDash($dashsize, ($dashsize / $dashsizek) + ($this->LineWidth * 2));
21245 $this->SetLineJoin(1);
21246 $this->SetLineCap(1);
21247 $this->SetDash(0.001, ($this->LineWidth * 2));
21250 $this->SetDColor($details[$side]['c']);
21252 $this->SetDColor($this->colorConverter->convert(0, $this->PDFAXwarnings));
21254 $this->Line($lx1 + $xadj, $ly1 + $yadj, $lx2 - $xadj2, $ly2 - $yadj2);
21255 /* -- TABLES-ADVANCED-BORDERS -- */
21257 /* -- END TABLES-ADVANCED-BORDERS -- */
21260 $this->SetDash();
21262 $this->SetLineCap(2);
21268 $this->SetLineWidth($cbo['lw']);
21269 $this->SetDColor($cbo['col']);
21270 $this->Line($cbo['x'], $cbo['y'], $cbo['x2'], $cbo['y2']);
21274 // $this->SetLineWidth($oldlinewidth);
21275 // $this->SetDColor($this->colorConverter->convert(0, $this->PDFAXwarnings));
21279 /* -- TABLES -- */
21280 /* -- TABLES-ADVANCED-BORDERS -- */
21282 /* -- END TABLES-ADVANCED-BORDERS -- */
21305 $this->setBorder($cellb, $bval);
21306 } elseif ($tableb && $tableb['w'] == $cbdb['w'] && array_search($tableb['style'], $this->borderstyles) > array_search($cbdb['style'], $this->borderstyles)) {
21308 $this->setBorder($cellb, $bval);
21327 if ($this->simpleTables) {
21333 /* -- TABLES-ADVANCED-BORDERS -- */
21335 $tntborddet = $this->border_details($table['topntail']);
21337 if (isset($table['thead-underline']) && $table['thead-underline']) {
21338 $thuborddet = $this->border_details($table['thead-underline']);
21340 /* -- END TABLES-ADVANCED-BORDERS -- */
21346 if ($this->packTableData) {
21347 $cbord = $this->_unpackCellBorder($cell['borderbin']);
21353 if (!$cbord['border'] && $cbord['border'] !== 0 && isset($table['border']) && $table['border'] && $this->table_border_attr_set) {
21371 if ($this->table_border_css_set && !$table['borders_separate']) {
21373 $this->_table2cellBorder($table['border_details']['T'], $cbord['border_details']['T'], $cbord['border'], Border::TOP);
21375 if ($i == ($numrows - 1) || ($i + $crowsp) == ($numrows)) {
21376 $this->_table2cellBorder($table['border_details']['B'], $cbord['border_details']['B'], $cbord['border'], Border::BOTTOM);
21379 $this->_table2cellBorder($table['border_details']['L'], $cbord['border_details']['L'], $cbord['border'], Border::LEFT);
21381 if ($j == ($numcols - 1) || ($j + $ccolsp) == ($numcols)) {
21382 $this->_table2cellBorder($table['border_details']['R'], $cbord['border_details']['R'], $cbord['border'], Border::RIGHT);
21386 /* -- TABLES-ADVANCED-BORDERS -- */
21391 $this->setBorder($cbord['border'], Border::TOP);
21393 if ($this->tableLevel == 1 && $table['headernrows'] > 0 && $i == $table['headernrows'] - 1) {
21395 $this->setBorder($cbord['border'], Border::BOTTOM);
21397 } elseif ($this->tableLevel == 1 && $table['headernrows'] > 0 && $i == $table['headernrows']) {
21400 $this->setBorder($cbord['border'], Border::TOP);
21403 if ($this->tableLevel == 1 && $table['footernrows'] > 0 && $i == ($numrows - $table['footernrows'] - 1)) {
21406 $this->setBorder($cbord['border'], Border::BOTTOM);
21409 } elseif ($this->tableLevel == 1 && $table['footernrows'] > 0 && $i == ($numrows - $table['footernrows'])) {
21411 $this->setBorder($cbord['border'], Border::TOP);
21413 if ($this->tabletheadjustfinished) { // $this->tabletheadjustfinished called from tableheader
21416 $this->setBorder($cbord['border'], Border::TOP);
21419 if ($i == ($numrows - 1) || ($i + $crowsp) == ($numrows)) {
21421 $this->setBorder($cbord['border'], Border::BOTTOM);
21424 if (isset($table['thead-underline']) && $table['thead-underline']) {
21428 $this->setBorder($cbord['border'], Border::BOTTOM);
21432 if ($this->tableLevel == 1 && $table['headernrows'] > 0 && $i == $table['headernrows'] - 1) {
21434 $this->setBorder($cbord['border'], Border::TOP);
21435 } elseif ($this->tabletheadjustfinished) { // $this->tabletheadjustfinished called from tableheader
21437 $this->setBorder($cbord['border'], Border::TOP);
21442 // Collapse Border - Algorithm for conflicting borders
21449 if (($i < ($numrows - 1) || ($i + $crowsp) < $numrows ) && $fixbottom) { // Bottom
21455 if ($this->packTableData) {
21457 $celladj = $this->_unpackCellBorder($adjc['borderbin']);
21474 $this->setBorder($celladj['border'], Border::TOP, false);
21475 $this->setBorder($cbord['border'], Border::BOTTOM, false);
21480 $this->setBorder($cbord['border'], Border::BOTTOM, false);
21481 $this->setBorder($celladj['border'], Border::TOP, false);
21487 $this->setBorder($cbord['border'], Border::BOTTOM);
21494 $this->setBorder($celladj['border'], Border::TOP);
21497 } elseif (array_search($cbord['border_details']['B']['style'], $this->borderstyles) > array_search($celladj['border_details']['T']['style'], $this->borderstyles)) { // double>solid>dashed>dotted...
21501 $this->setBorder($cbord['border'], Border::BOTTOM);
21504 } elseif (array_search($celladj['border_details']['T']['style'], $this->borderstyles) > array_search($cbord['border_details']['B']['style'], $this->borderstyles)) {
21508 $this->setBorder($celladj['border'], Border::TOP);
21515 $this->setBorder($celladj['border'], Border::TOP);
21518 } else { // Style set on cell vs. table - OR - LEFT/TOP (cell) in preference to BOTTOM/RIGHT
21522 $this->setBorder($cbord['border'], Border::BOTTOM);
21536 if ($celladj && $this->packTableData) {
21537 $cells[$i + $crowsp][$j + $cspi]['borderbin'] = $this->_packCellBorder($celladj);
21544 if ($j < ($numcols - 1) || ($j + $ccolsp) < $numcols) { // Right-Left
21550 if ($this->packTableData) {
21552 $celladj = $this->_unpackCellBorder($adjc['borderbin']);
21565 $this->setBorder($celladj['border'], Border::LEFT, false);
21566 $this->setBorder($cbord['border'], Border::RIGHT, false);
21569 $this->setBorder($cbord['border'], Border::RIGHT, false);
21570 $this->setBorder($celladj['border'], Border::LEFT, false);
21575 $this->setBorder($cbord['border'], Border::RIGHT);
21576 $this->setBorder($celladj['border'], Border::LEFT, false);
21581 $this->setBorder($cbord['border'], Border::RIGHT, false);
21582 $this->setBorder($celladj['border'], Border::LEFT);
21585 elseif (array_search($cbord['border_details']['R']['style'], $this->borderstyles) > array_search($celladj['border_details']['L']['style'], $this->borderstyles)) {
21588 $this->setBorder($celladj['border'], Border::LEFT, false);
21589 $this->setBorder($cbord['border'], Border::RIGHT);
21591 } elseif (array_search($celladj['border_details']['L']['style'], $this->borderstyles) > array_search($cbord['border_details']['R']['style'], $this->borderstyles)) {
21594 $this->setBorder($cbord['border'], Border::RIGHT, false);
21595 $this->setBorder($celladj['border'], Border::LEFT);
21601 $this->setBorder($celladj['border'], Border::LEFT);
21603 } // Style set on cell vs. table - OR - LEFT/TOP (cell) in preference to BOTTOM/RIGHT
21607 $this->setBorder($cbord['border'], Border::RIGHT);
21611 // if right-cell border is not set
21617 if ($celladj && $this->packTableData) {
21618 $cells[$i + $cspi][$j + $ccolsp]['borderbin'] = $this->_packCellBorder($celladj);
21626 // Set maximum cell border width meeting at LRTB edges of cell - used for extended cell border
21627 // ['border_details']['mbw']['LT'] = meeting border width - Left border - Top end
21641 if ($this->packTableData) {
21643 $celladj = $this->_unpackCellBorder($adjc['borderbin']);
21675 if ($this->packTableData) {
21677 $celladj = $this->_unpackCellBorder($adjc['borderbin']);
21707 if ($i > 0 && 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
21709 if ($this->packTableData) {
21710 $adjc = $cells[$i - 1][$j];
21711 $celladj = $this->_unpackCellBorder($adjc['borderbin']);
21713 $celladj = & $cells[$i - 1][$j];
21746 if ($this->packTableData) {
21747 $cells[$i - 1][$j]['borderbin'] = $this->_packCellBorder($celladj);
21752 if ($j > 0 && 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
21754 if ($this->packTableData) {
21755 $adjc = $cells[$i][$j - 1];
21756 $celladj = $this->_unpackCellBorder($adjc['borderbin']);
21758 $celladj = & $cells[$i][$j - 1];
21791 if ($this->packTableData) {
21792 $cells[$i][$j - 1]['borderbin'] = $this->_packCellBorder($celladj);
21799 // Update maximum cell border width at LRTB edges of table - used for overall table width
21803 if (($j == ($numcols - 1) || ($j + $ccolsp) == $numcols ) && $cbord['border_details']['R']['w']) {
21809 if (($i == ($numrows - 1) || ($i + $crowsp) == $numrows ) && $cbord['border_details']['B']['w']) {
21813 /* -- END TABLES-ADVANCED-BORDERS -- */
21815 if ($this->packTableData) {
21816 $cell['borderbin'] = $this->_packCellBorder($cbord);
21837 for ($j = ($numcols - 1); $j >= 0; $j--) { // Columns
21840 $col = $numcols - $j - 1;
21842 $col -= ($cell['colspan'] - 1);
21849 $objattr = $this->_getObjAttr($t);
21852 $this->table[($this->tableLevel + 1)][$objattr['nestedcontent']]['nestedpos'][1] = $col;
21878 if ($this->ColActive && $level == 1) {
21879 $this->breakpoints[$this->CurrCol][] = $this->y;
21885 if (!$this->table_rotate && $level == 1) {
21886 $this->DivLn($table['margin']['T'], $this->blklvl, true, 1); // collapsible
21888 $this->y += ($table['margin']['T']);
21901 if (!$this->table_rotate && $level == 1) {
21902 $this->DivLn($adv);
21904 $this->y += $adv;
21909 $this->x = $this->lMargin + $this->blk[$this->blklvl]['outer_left_margin'] + $this->blk[$this->blklvl]['padding_left'] + $this->blk[$this->blklvl]['border_left']['w'];
21910 $x0 = $this->x;
21911 $y0 = $this->y;
21912 $right = $x0 + $this->blk[$this->blklvl]['inner_width'];
21913 $outerfilled = $this->y; // Keep track of how far down the outer DIV bgcolor is painted (NB rowspans)
21914 $this->outerfilled = $this->y;
21915 $this->colsums = [];
21917 $x0 = $this->x;
21918 $y0 = $this->y;
21922 if ($this->table_rotate) {
21923 $temppgwidth = $this->tbrot_maxw;
21924 $this->PageBreakTrigger = $pagetrigger = $y0 + ($this->blk[$this->blklvl]['inner_width']);
21926 $this->tbrot_y0 = $this->y - $adv - $table['margin']['T'];
21927 $this->tbrot_x0 = $this->x;
21928 $this->tbrot_w = $table['w'];
21930 $this->tbrot_h = $table['margin']['T'] + $table['padding']['T'] + $table['border_details']['T']['w'] + $table['border_spacing_V'] / 2;
21932 $this->tbrot_h = $table['margin']['T'] + $table['padding']['T'] + $table['max_cell_border_width']['T'];
21936 $this->PageBreakTrigger = $pagetrigger = ($this->h - $this->bMargin);
21938 $temppgwidth = $this->blk[$this->blklvl]['inner_width'];
21939 if (isset($table['a']) and ( $table['w'] < $this->blk[$this->blklvl]['inner_width'])) {
21941 $x0 += ((($right - $x0) - $table['w']) / 2);
21943 $x0 = $right - $table['w'];
21953 if ($table['overflow'] == 'hidden' && $level == 1 && !$this->table_rotate && !$this->ColActive) {
21955 $this->tableClipPath = sprintf('q %.3F %.3F %.3F %.3F re W n', $x0 * Mpdf::SCALE, $this->h * Mpdf::SCALE, $this->blk[$this->blklvl]['inner_width'] * Mpdf::SCALE, -$this->h * Mpdf::SCALE);
21956 $this->writer->write($this->tableClipPath);
21958 $this->tableClipPath = '';
21978 if (($this->mirrorMargins) && (($this->page) % 2 == 0)) { // EVEN
21980 } elseif (($this->mirrorMargins) && (($this->page) % 2 == 1)) { // ODD
21985 if ($this->ColActive) {
21986 $tablestartcolumn = $this->CurrCol;
21995 $tablefooter[$i][0]['trbackground-images'] = $table['trbackground-images'][$i];
22005 list($x, $w) = $this->_splitTableGetWidth($table, $i, $j);
22006 $js = $j - $startcol;
22008 list($x, $w) = $this->_tableGetWidth($table, $i, $j);
22012 list($y, $h) = $this->_tableGetHeight($table, $i, $j);
22032 if (isset($cell['background-image'])) {
22033 $tablefooter[$i][$js]['background-image'] = $cell['background-image']; // *BACKGROUNDS*
22037 if (!$this->simpleTables) {
22038 if ($this->packTableData) {
22039 $c = $this->_unpackCellBorder($cell['borderbin']);
22046 } elseif ($this->simpleTables) {
22076 $this->writer->write('___TABLE___BACKGROUNDS' . $this->uniqstr);
22081 $tablestartpageno = $this->page;
22091 $returny = $rety - $tableheaderrowheight;
22095 // Get Maximum row/cell height in row - including rowspan>1 + 1 overlapping
22096 $maxrowheight = $this->_tableGetMaxRowHeight($table, $i);
22110 $lastCol = $j + (isset($cell['colspan']) ? ($cell['colspan'] - 1) : 0);
22111 list($x, $w) = $this->_splitTableGetWidth($table, $i, $j);
22113 list($x, $w) = $this->_tableGetWidth($table, $i, $j);
22116 list($y, $h) = $this->_tableGetHeight($table, $i, $j);
22119 $y -= $returny;
22122 if (!empty($tablefooter) || $i == ($numrows - 1) || (isset($cell['rowspan']) && ($i + $cell['rowspan']) == $numrows) || (!isset($cell['rowspan']) && ($i + 1) == $numrows)) {
22132 if ($j == $startcol && ((($y + $maxrowheight + $extra ) > ($pagetrigger + 0.001)) || (($this->keepColumns || !$this->ColActive) && !empty($tablefooter) && ($y + $maxrowheight + $tablefooterrowheight + $extra) > $pagetrigger) && ($this->tableLevel == 1 && $i < ($numrows - $table['headernrows']))) && ($y0 > 0 || $x0 > 0) && !$this->InFooter && $this->autoPageBreak) {
22149 if (($this->keepColumns || !$this->ColActive) && !empty($tablefooter) && $i > 0) {
22150 $this->y = $y;
22151 $ya = $this->y;
22152 $this->TableHeaderFooter($tablefooter, $tablestartpage, $tablestartcolumn, 'F', $level, $firstSpread, $finalSpread);
22153 if ($this->table_rotate) {
22154 $this->tbrot_h += $this->y - $ya;
22156 $tablefooteradj = $this->y - $ya;
22158 $y -= $y0;
22161 $oldcolumn = $this->CurrCol;
22162 if ($this->AcceptPageBreak()) {
22164 $this->y = $y + $y0;
22166 // Move down to account for border-spacing or
22168 if ($i > 0 && !$this->table_rotate && $level == 1 && !$this->ColActive) {
22172 if (($this->keepColumns || !$this->ColActive) && !empty($tablefooter) && $i > 0) {
22178 if (!$this->simpleTables) {
22182 $brow = $i - 1;
22185 if ($this->packTableData) {
22186 list($bt, $br, $bb, $bl) = $this->_getBorderWidths($cells[$brow][$ctj]['borderbin']);
22197 $trow = $i - 1;
22200 if ($this->packTableData) {
22201 list($bt, $br, $bb, $bl) = $this->_getBorderWidths($cells[$trow][$ctj]['borderbin']);
22209 } elseif ($this->simpleTables) {
22215 $this->y += $adv;
22218 // Rotated table split over pages - needs this->y for borders/backgrounds
22219 if ($i > 0 && $this->table_rotate && $level == 1) {
22220 // $this->y = $y0 + $this->tbrot_w;
22223 if ($this->tableClipPath) {
22224 $this->writer->write("Q");
22231 $bx -= ($table['padding']['L'] + $table['border_details']['L']['w'] + $table['border_spacing_H'] / 2);
22232 if ($tablestartpageno != $this->page) { // IF already broken across a previous pagebreak
22235 $by -= ($table['border_spacing_V'] / 2);
22238 $by -= ($table['padding']['T'] + $table['border_details']['T']['w'] + $table['border_spacing_V'] / 2);
22240 } elseif ($tablestartpageno != $this->page && !empty($tableheader)) {
22244 $by -= $tableheaderadj;
22245 $bh = $this->y - $by + $tablefooteradj;
22247 $bh -= $adv;
22271 $bw = $table['w'] - ($table['max_cell_border_width']['L'] / 2) - ($table['max_cell_border_width']['R'] / 2) - $table['margin']['L'] - $table['margin']['R'];
22274 if ($this->splitTableBorderWidth && ($this->keepColumns || !$this->ColActive) && empty($tablefooter) && $i > 0 && $table['border_details']['B']['w']) {
22275 $prevDrawColor = $this->DrawColor;
22276 $lw = $this->LineWidth;
22277 $this->SetLineWidth($this->splitTableBorderWidth);
22278 $this->SetDColor($table['border_details']['B']['c']);
22279 $this->SetLineJoin(0);
22280 $this->SetLineCap(0);
22284 $blx -= ($table['max_cell_border_width']['L'] / 2);
22287 $this->Line($blx, $this->y + ($this->splitTableBorderWidth / 2), $blx + $blw, $this->y + ($this->splitTableBorderWidth / 2));
22288 $this->DrawColor = $prevDrawColor;
22289 $this->writer->write($this->DrawColor);
22290 $this->SetLineWidth($lw);
22291 $this->SetLineJoin(2);
22292 $this->SetLineCap(2);
22295 if (!$this->ColActive && ($i > 0 || $j > 0)) {
22296 if (isset($table['bgcolor'][-1])) {
22297 $color = $this->colorConverter->convert($table['bgcolor'][-1], $this->PDFAXwarnings);
22300 $bh -= $table['max_cell_border_width']['B'] / 2;
22302 $this->tableBackgrounds[$level * 9][] = ['gradient' => false, 'x' => $bx, 'y' => $by, 'w' => $bw, 'h' => $bh, 'col' => $color];
22306 /* -- BACKGROUNDS -- */
22308 $g = $this->gradient->parseBackgroundGradient($table['gradient']);
22310 $this->tableBackgrounds[$level * 9 + 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' => ''];
22314 if (isset($table['background-image'])) {
22315 if ($table['background-image']['gradient'] && preg_match('/(-moz-)*(repeating-)*(linear|radial)-gradient/', $table['background-image']['gradient'])) {
22316 $g = $this->gradient->parseMozGradient($table['background-image']['gradient']);
22318 $this->tableBackgrounds[$level * 9 + 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' => ''];
22321 $image_id = $table['background-image']['image_id'];
22322 $orig_w = $table['background-image']['orig_w'];
22323 $orig_h = $table['background-image']['orig_h'];
22324 $x_pos = $table['background-image']['x_pos'];
22325 $y_pos = $table['background-image']['y_pos'];
22326 $x_repeat = $table['background-image']['x_repeat'];
22327 $y_repeat = $table['background-image']['y_repeat'];
22328 $resize = $table['background-image']['resize'];
22329 $opacity = $table['background-image']['opacity'];
22330 $itype = $table['background-image']['itype'];
22331 $this->tableBackgrounds[$level * 9 + 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];
22334 /* -- END BACKGROUNDS -- */
22337 // $this->AcceptPageBreak() has moved tablebuffer to $this->pages content
22338 if ($this->tableBackgrounds) {
22339 $s = $this->PrintTableBackgrounds();
22340 if ($this->bufferoutput) {
22341 $this->headerbuffer = preg_replace('/(___TABLE___BACKGROUNDS' . $this->uniqstr . ')/', '\\1' . "\n" . $s . "\n", $this->headerbuffer);
22342 $this->headerbuffer = preg_replace('/(___TABLE___BACKGROUNDS' . $this->uniqstr . ')/', " ", $this->headerbuffer);
22344 $this->pages[$this->page] = preg_replace('/(___TABLE___BACKGROUNDS' . $this->uniqstr . ')/', '\\1' . "\n" . $s . "\n", $this->pages[$this->page]);
22345 $this->pages[$this->page] = preg_replace('/(___TABLE___BACKGROUNDS' . $this->uniqstr . ')/', " ", $this->pages[$this->page]);
22347 $this->tableBackgrounds = [];
22352 $y0 = -1;
22360 $returny -= $y;
22365 $this->AddPage($this->CurOrientation);
22367 $this->writer->write('___TABLE___BACKGROUNDS' . $this->uniqstr);
22370 if ($this->tableClipPath) {
22371 $this->writer->write($this->tableClipPath);
22375 $x = $x + $this->MarginCorrection;
22376 $x0 = $x0 + $this->MarginCorrection;
22378 if ($this->splitTableBorderWidth && ($this->keepColumns || !$this->ColActive) && empty($tableheader) && $i > 0 && $table['border_details']['T']['w']) {
22379 $prevDrawColor = $this->DrawColor;
22380 $lw = $this->LineWidth;
22381 $this->SetLineWidth($this->splitTableBorderWidth);
22382 $this->SetDColor($table['border_details']['T']['c']);
22383 $this->SetLineJoin(0);
22384 $this->SetLineCap(0);
22385 $blx += $this->MarginCorrection;
22386 $this->Line($blx, $this->y - ($this->splitTableBorderWidth / 2), $blx + $blw, $this->y - ($this->splitTableBorderWidth / 2));
22387 $this->DrawColor = $prevDrawColor;
22388 $this->writer->write($this->DrawColor);
22389 $this->SetLineWidth($lw);
22390 $this->SetLineJoin(2);
22391 $this->SetLineCap(2);
22394 // Move down to account for half of top border-spacing or
22396 if ($i > 0 && !$this->table_rotate && $level == 1 && $table['headernrows'] == 0) {
22403 if (!$this->simpleTables) {
22404 if ($this->packTableData) {
22405 list($bt, $br, $bb, $bl) = $this->_getBorderWidths($cells[$i][$ctj]['borderbin']);
22410 } elseif ($this->simpleTables) {
22417 $this->y += $adv;
22421 if ($this->table_rotate) {
22422 $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'];
22424 $this->tbrot_h = $table['margin']['T'] + $table['padding']['T'] + $table['border_details']['T']['w'] + $table['border_spacing_V'] / 2;
22426 $this->tbrot_h = $table['margin']['T'] + $table['max_cell_border_width']['T'];
22428 $this->tbrot_y0 = $this->y;
22429 $pagetrigger = $y0 - $tableheaderadj + ($this->blk[$this->blklvl]['inner_width']);
22431 $pagetrigger = $this->PageBreakTrigger;
22434 if ($this->kwt_saved && $level == 1) {
22435 $this->kwt_moved = true;
22440 $ya = $this->y;
22441 $this->TableHeaderFooter($tableheader, $tablestartpage, $tablestartcolumn, 'H', $level);
22442 if ($this->table_rotate) {
22443 $this->tbrot_h = $this->y - $ya;
22445 $tableheaderadj = $this->y - $ya;
22446 } elseif ($i == 0 && !$this->table_rotate && $level == 1 && !$this->ColActive) {
22454 if ($this->table_rotate) {
22455 $this->y += ($adv);
22457 $this->DivLn($adv, $this->blklvl, true);
22463 $y = $y0 = $this->y;
22466 /* -- COLUMNS -- */
22469 if ($this->CurrCol != $oldcolumn) {
22471 $x += $this->ChangeColumn * ($this->ColWidth + $this->ColGap);
22472 $x0 += $this->ChangeColumn * ($this->ColWidth + $this->ColGap);
22473 if ($this->CurrCol == 0) { // just added a page - possibly with tableheader
22474 $y0 = $this->y; // this->y0 is global used by Columns - $y0 is internal to tablewrite
22476 $y0 = $this->y0; // this->y0 is global used by Columns - $y0 is internal to tablewrite
22480 if ($this->CurrCol != 0 && ($this->keepColumns && $this->ColActive) && !empty($tableheader) && $i > 0) {
22481 $this->x = $x;
22482 $this->y = $y;
22483 $this->TableHeaderFooter($tableheader, $tablestartpage, $tablestartcolumn, 'H', $level);
22484 $y0 = $y = $this->y;
22487 /* -- END COLUMNS -- */
22492 $this->x = $x;
22493 $this->y = $y;
22495 if ($this->kwt_saved && $level == 1) {
22496 $this->printkwtbuffer();
22497 $x0 = $x = $this->x;
22498 $y0 = $y = $this->y;
22499 $this->kwt_moved = false;
22500 $this->kwt_saved = false;
22506 if (($this->mirrorMargins) && (($this->page) % 2 == 0)) { // EVEN
22508 } elseif (($this->mirrorMargins) && (($this->page) % 2 == 1)) { // ODD
22513 $tablestartpageno = $this->page;
22514 if ($this->ColActive) {
22515 $tablestartcolumn = $this->CurrCol;
22522 /* -- COLUMNS -- */
22524 if ($this->ColActive) {
22526 if ($this->blklvl > 0 && ($j == 0) && !$this->table_rotate && $level == 1) {
22527 $firstblockfill = $this->GetFirstBlockFill();
22528 if ($firstblockfill && $this->blklvl >= $firstblockfill) {
22531 if ((!isset($cell['rowspan']) && $i == $numrows - 1) || (isset($cell['rowspan']) && (($i == $numrows - 1 && $cell['rowspan'] < 2) || ($cell['rowspan'] > 1 && ($i + $cell['rowspan'] - 1) == $numrows - 1)))) {
22540 if (($this->y + $divh) > $outerfilled) { // if not already painted by previous rowspan
22541 $bak_x = $this->x;
22542 $bak_y = $this->y;
22543 if ($outerfilled > $this->y) {
22544 $divh = ($this->y + $divh) - $outerfilled;
22545 $this->y = $outerfilled;
22548 $this->DivLn($divh, -3, false);
22549 $outerfilled = $this->y + $divh;
22551 $bcor = $this->blk[$this->blklvl]['bgcolorarray'];
22553 $this->SetFColor($bcor);
22555 $this->x = $bak_x;
22556 $this->y = $bak_y;
22562 // TABLE BACKGROUND FILL BGCOLOR - for cellSpacing
22563 if ($this->ColActive) {
22565 $fill = isset($table['bgcolor'][-1]) ? $table['bgcolor'][-1] : 0;
22567 $color = $this->colorConverter->convert($fill, $this->PDFAXwarnings);
22581 if ($i == ($numrows - 1) || (isset($cell['rowspan']) && ($i + $cell['rowspan']) == $numrows) || (!isset($cell['rowspan']) && ($i + 1) == $numrows)) { // Bottom
22584 if ($j == ($numcols - 1) || (isset($cell['colspan']) && ($j + $cell['colspan']) == $numcols) || (!isset($cell['colspan']) && ($j + 1) == $numcols)) { // Right
22587 $this->SetFColor($color);
22588 $this->Rect($x - $xadj, $y - $yadj, $w + $wadj, $h + $hadj, 'F');
22593 /* -- END COLUMNS -- */
22605 if (!$this->simpleTables) {
22606 if ($this->packTableData) {
22607 $c = $this->_unpackCellBorder($cell['borderbin']);
22614 } elseif ($this->simpleTables) {
22629 $color = $this->colorConverter->convert($fill, $this->PDFAXwarnings);
22632 if ($this->ColActive) {
22633 $this->SetFColor($color);
22634 $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');
22636 $this->tableBackgrounds[$level * 9 + $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];
22639 if ($this->ColActive) {
22640 $this->SetFColor($color);
22641 $this->Rect($x, $y, $w, $h, 'F');
22643 $this->tableBackgrounds[$level * 9 + $leveladj][] = ['gradient' => false, 'x' => $x, 'y' => $y, 'w' => $w, 'h' => $h, 'col' => $color];
22649 /* -- BACKGROUNDS -- */
22651 $g = $this->gradient->parseBackgroundGradient($cell['gradient']);
22656 $pw = $w - $table['border_spacing_H'];
22657 $ph = $h - $table['border_spacing_V'];
22664 if ($this->ColActive) {
22665 $this->gradient->Gradient($px, $py, $pw, $ph, $g['type'], $g['stops'], $g['colorspace'], $g['coords'], $g['extend']);
22667 $this->tableBackgrounds[$level * 9 + 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' => ''];
22672 if (isset($cell['background-image']) && $paintcell) {
22673 if (isset($cell['background-image']['gradient']) && $cell['background-image']['gradient'] && preg_match('/(-moz-)*(repeating-)*(linear|radial)-gradient/', $cell['background-image']['gradient'])) {
22674 $g = $this->gradient->parseMozGradient($cell['background-image']['gradient']);
22679 $pw = $w - $table['border_spacing_H'];
22680 $ph = $h - $table['border_spacing_V'];
22687 if ($this->ColActive) {
22688 $this->gradient->Gradient($px, $py, $pw, $ph, $g['type'], $g['stops'], $g['colorspace'], $g['coords'], $g['extend']);
22690 $this->tableBackgrounds[$level * 9 + 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' => ''];
22693 } elseif (isset($cell['background-image']['image_id']) && $cell['background-image']['image_id']) { // Background pattern
22694 $n = count($this->patterns) + 1;
22698 $pw = $w - $table['border_spacing_H'];
22699 $ph = $h - $table['border_spacing_V'];
22706 if ($this->ColActive) {
22707 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']);
22708 $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];
22709 if ($cell['background-image']['opacity'] > 0 && $cell['background-image']['opacity'] < 1) {
22710 $opac = $this->SetAlpha($cell['background-image']['opacity'], 'Normal', true);
22714 $this->writer->write(sprintf('q /Pattern cs /P%d scn %s %.3F %.3F %.3F %.3F re f Q', $n, $opac, $px * Mpdf::SCALE, ($this->h - $py) * Mpdf::SCALE, $pw * Mpdf::SCALE, -$ph * Mpdf::SCALE));
22716 $image_id = $cell['background-image']['image_id'];
22717 $orig_w = $cell['background-image']['orig_w'];
22718 $orig_h = $cell['background-image']['orig_h'];
22719 $x_pos = $cell['background-image']['x_pos'];
22720 $y_pos = $cell['background-image']['y_pos'];
22721 $x_repeat = $cell['background-image']['x_repeat'];
22722 $y_repeat = $cell['background-image']['y_repeat'];
22723 $resize = $cell['background-image']['resize'];
22724 $opacity = $cell['background-image']['opacity'];
22725 $itype = $cell['background-image']['itype'];
22726 $this->tableBackgrounds[$level * 9 + 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];
22730 /* -- END BACKGROUNDS -- */
22745 if (!$table['borders_separate'] && $this->tabletheadjustfinished && !$this->simpleTables) {
22747 $bord_det['T'] = $this->border_details($table['topntail']);
22748 $bord_det['T']['w'] /= $this->shrin_k;
22749 $this->setBorder($bord, Border::TOP);
22751 if (isset($table['thead-underline']) && $table['thead-underline']) {
22752 $bord_det['T'] = $this->border_details($table['thead-underline']);
22753 $bord_det['T']['w'] /= $this->shrin_k;
22754 $this->setBorder($bord, Border::TOP);
22765 $tableheader[$i][0]['trbackground-images'] = (isset($table['trbackground-images'][$i]) ? $table['trbackground-images'][$i] : null);
22783 $tableheader[$i][$j]['background-image'] = (isset($cell['background-image']) ? $cell['background-image'] : null); // *BACKGROUNDS*
22788 if (!$this->simpleTables) {
22791 } elseif ($this->simpleTables) {
22813 $this->_tableRect($x + ($table['border_spacing_H'] / 2) + ($bord_det['L']['w'] / 2), $y + ($table['border_spacing_V'] / 2) + ($bord_det['T']['w'] / 2), $w - $table['border_spacing_H'] - ($bord_det['L']['w'] / 2) - ($bord_det['R']['w'] / 2), $h - $table['border_spacing_V'] - ($bord_det['T']['w'] / 2) - ($bord_det['B']['w'] / 2), $bord, $bord_det, false, $table['borders_separate']);
22815 $this->_tableRect($x, $y, $w, $h, $bord, $bord_det, true, $table['borders_separate']); // true causes buffer
22824 $this->y += ($h - $cell['mih']) / 2;
22826 $this->y += $h - $cell['mih'];
22832 $this->divwidth = $w;
22834 $this->cellTextAlign = $align;
22835 $this->cellLineHeight = $cell['cellLineHeight'];
22836 $this->cellLineStackingStrategy = $cell['cellLineStackingStrategy'];
22837 $this->cellLineStackingShift = $cell['cellLineStackingShift'];
22840 if (preg_match('/{colsum([0-9]*)[_]*}/', $cell['textbuffer'][0][0], $m)) {
22841 $rep = sprintf("%01." . intval($m[1]) . "f", $this->colsums[$j]);
22842 $cell['textbuffer'][0][0] = preg_replace('/{colsum[0-9_]*}/', $rep, $cell['textbuffer'][0][0]);
22845 if (isset($this->colsums[$j])) {
22846 $this->colsums[$j] += $this->toFloat($cell['textbuffer'][0][0]);
22848 $this->colsums[$j] = $this->toFloat($cell['textbuffer'][0][0]);
22852 $opy = $this->y;
22854 if ($this->iterationCounter) {
22856 if (preg_match('/{iteration ([a-zA-Z0-9_]+)}/', $t[0], $m)) {
22858 if (!isset($this->$vname)) {
22859 $this->$vname = 1;
22861 $this->$vname++;
22863 $cell['textbuffer'][$k][0] = preg_replace('/{iteration ' . $m[1] . '}/', $this->$vname, $cell['textbuffer'][$k][0]);
22870 $cellPtSize = $cell['textbuffer'][0][11] / $this->shrin_k;
22872 $cellPtSize = $this->default_font_size;
22875 $opx = $this->x;
22877 // Only allow 45 to 89 degrees (when bottom-aligned) or exactly 90 or -90
22883 $angle = -90;
22887 $this->x += ($w) + ($offset) - ($cellFontHeight / 3) - ($cell['padding']['R'] + ($table['border_spacing_H'] / 2));
22889 $this->x += ($w / 2) + ($offset);
22891 $this->x += ($offset) + ($cellFontHeight / 3) + ($cell['padding']['L'] + ($table['border_spacing_H'] / 2));
22899 $this->y -= ($h - $cell['mih']) / 2; // Undo what was added earlier VERTICAL ALIGN
22901 $this->y += (($h - $cell['mih']) / 2) + $cell['padding']['T'] + ($cell['mih'] - ($cell['padding']['T'] + $cell['padding']['B']));
22903 $this->y += (($h - $cell['mih']) / 2) + ($cell['padding']['T'] + ($table['border_spacing_V'] / 2));
22906 $this->y -= $h - $cell['mih']; // Undo what was added earlier VERTICAL ALIGN
22908 $this->y += $h - ($cell['padding']['B'] + ($table['border_spacing_V'] / 2));
22910 $this->y += $h - $cell['mih'] + ($cell['padding']['T'] + ($table['border_spacing_V'] / 2));
22914 $this->y += $cell['mih'] - ($cell['padding']['B'] + ($table['border_spacing_V'] / 2));
22916 $this->y += ($cell['padding']['T'] + ($table['border_spacing_V'] / 2));
22919 $this->Rotate($angle, $this->x, $this->y);
22920 $s_fs = $this->FontSizePt;
22921 $s_f = $this->FontFamily;
22922 $s_st = $this->FontStyle;
22923 if (!empty($cell['textbuffer'][0][3])) { // Font Color
22925 $this->SetTColor($cor);
22927 $this->SetFont($cell['textbuffer'][0][4], $cell['textbuffer'][0][2], $cellPtSize, true, true);
22929 $this->magic_reverse_dir($str, $this->directionality, $cell['textbuffer'][0][18]);
22930 $this->Text($this->x, $this->y, $str, $cell['textbuffer'][0][18], $cell['textbuffer'][0][8]); // textvar
22931 $this->Rotate(0);
22932 $this->SetFont($s_f, $s_st, $s_fs, true, true);
22933 $this->SetTColor(0);
22934 $this->x = $opx;
22936 if (!$this->simpleTables) {
22955 } elseif ($this->simpleTables) {
22966 $this->decimal_offset = 0;
22969 $this->cellTextAlign = $c['a'] = substr($cell['a'], 2, 1);
22973 $this->decimal_offset = $smax;
22974 $extra = ($w - $d_content - $wadj);
22977 $this->decimal_offset += $extra;
22979 $this->decimal_offset += ($extra) / 2;
22984 $this->divwidth = $w - $wadj;
22985 if ($this->divwidth == 0) {
22986 $this->divwidth = 0.0001;
22988 $this->x += $xadj;
22989 $this->y += $yadj;
22990 $this->printbuffer($cell['textbuffer'], '', true, false, $cell['direction']);
22992 $this->y = $opy;
22995 /* -- BACKGROUNDS -- */
22996 if (!$this->ColActive) {
22998 $g = $this->gradient->parseBackgroundGradient($table['trgradients'][$i]);
23003 $gw = $table['w'] - ($table['max_cell_border_width']['L'] / 2) - ($table['max_cell_border_width']['R'] / 2) - $table['margin']['L'] - $table['margin']['R'];
23005 $gw -= ($table['padding']['L'] + $table['border_details']['L']['w'] + $table['padding']['R'] + $table['border_details']['R']['w'] + $table['border_spacing_H']);
23008 $clw = $w - $table['border_spacing_H'];
23009 $clh = $h - $table['border_spacing_V'];
23011 $s = $this->_setClippingPath($clx, $cly, $clw, $clh); // mPDF 6
23012 $this->tableBackgrounds[$level * 9 + 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];
23014 $this->tableBackgrounds[$level * 9 + 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' => ''];
23018 if (isset($table['trbackground-images'][$i]) && ($j == 0 || $table['borders_separate'])) {
23019 if (isset($table['trbackground-images'][$i]['gradient']) && preg_match('/(-moz-)*(repeating-)*(linear|radial)-gradient/', $table['trbackground-images'][$i]['gradient'])) {
23020 $g = $this->gradient->parseMozGradient($table['trbackground-images'][$i]['gradient']);
23025 $gw = $table['w'] - ($table['max_cell_border_width']['L'] / 2) - ($table['max_cell_border_width']['R'] / 2) - $table['margin']['L'] - $table['margin']['R'];
23027 $gw -= ($table['padding']['L'] + $table['border_details']['L']['w'] + $table['padding']['R'] + $table['border_details']['R']['w'] + $table['border_spacing_H']);
23030 $clw = $w - $table['border_spacing_H'];
23031 $clh = $h - $table['border_spacing_V'];
23033 $s = $this->_setClippingPath($clx, $cly, $clw, $clh); // mPDF 6
23034 $this->tableBackgrounds[$level * 9 + 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];
23036 $this->tableBackgrounds[$level * 9 + 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' => ''];
23040 $image_id = $table['trbackground-images'][$i]['image_id'];
23041 $orig_w = $table['trbackground-images'][$i]['orig_w'];
23042 $orig_h = $table['trbackground-images'][$i]['orig_h'];
23043 $x_pos = $table['trbackground-images'][$i]['x_pos'];
23044 $y_pos = $table['trbackground-images'][$i]['y_pos'];
23045 $x_repeat = $table['trbackground-images'][$i]['x_repeat'];
23046 $y_repeat = $table['trbackground-images'][$i]['y_repeat'];
23047 $resize = $table['trbackground-images'][$i]['resize'];
23048 $opacity = $table['trbackground-images'][$i]['opacity'];
23049 $itype = $table['trbackground-images'][$i]['itype'];
23054 $gw = $table['w'] - ($table['max_cell_border_width']['L'] / 2) - ($table['max_cell_border_width']['R'] / 2) - $table['margin']['L'] - $table['margin']['R'];
23056 $gw -= ($table['padding']['L'] + $table['border_details']['L']['w'] + $table['padding']['R'] + $table['border_details']['R']['w'] + $table['border_spacing_H']);
23059 $clw = $w - $table['border_spacing_H'];
23060 $clh = $h - $table['border_spacing_V'];
23062 $s = $this->_setClippingPath($clx, $cly, $clw, $clh); // mPDF 6
23063 $this->tableBackgrounds[$level * 9 + 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];
23065 $this->tableBackgrounds[$level * 9 + 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];
23071 /* -- END BACKGROUNDS -- */
23073 // TABLE BORDER - if separate
23074 if (($table['borders_separate'] || ($this->simpleTables && !$table['simple']['border'])) && $table['border']) {
23087 $tby -= $halfspaceT + ($table['border_details']['T']['w'] / 2);
23089 $this->setBorder($tab_bord, Border::TOP);
23092 if ($i == ($numrows - 1) || (isset($cell['rowspan']) && ($i + $cell['rowspan']) == $numrows)) { // Bottom
23094 $this->setBorder($tab_bord, Border::BOTTOM);
23098 $tbx -= $halfspaceL + ($table['border_details']['L']['w'] / 2);
23100 $this->setBorder($tab_bord, Border::LEFT);
23103 if ($j == ($numcols - 1) || (isset($cell['colspan']) && ($j + $cell['colspan']) == $numcols)) { // Right
23105 $this->setBorder($tab_bord, Border::RIGHT);
23108 $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']);
23113 $this->Reset();
23118 $this->tabletheadjustfinished = false;
23120 /* -- COLUMNS -- */
23121 if ($this->ColActive) {
23122 if (!$this->table_keep_together && $i < $numrows - 1 && $level == 1) {
23123 $this->breakpoints[$this->CurrCol][] = $y + $h;
23125 if (count($this->cellBorderBuffer)) {
23126 $this->printcellbuffer();
23129 /* -- END COLUMNS -- */
23131 if ($i == $numrows - 1) {
23132 $this->y = $y + $h;
23133 } // last row jump (update this->y position)
23134 if ($this->table_rotate && $level == 1) {
23135 $this->tbrot_h += $h;
23139 if (count($this->cellBorderBuffer)) {
23140 $this->printcellbuffer();
23144 if ($this->tableClipPath) {
23145 $this->writer->write("Q");
23147 $this->tableClipPath = '';
23151 $this->y += $table['padding']['B'] + $table['border_details']['B']['w'] + $table['border_spacing_V'] / 2;
23153 $this->y += $table['max_cell_border_width']['B'] / 2;
23157 $this->tbrot_h += $table['margin']['B'] + $table['padding']['B'] + $table['border_details']['B']['w'] + $table['border_spacing_V'] / 2;
23159 $this->tbrot_h += $table['margin']['B'] + $table['max_cell_border_width']['B'] / 2;
23165 $bx -= ($table['padding']['L'] + $table['border_details']['L']['w'] + $table['border_spacing_H'] / 2);
23166 if ($tablestartpageno != $this->page) { // IF broken across page
23169 $by -= ($table['border_spacing_V'] / 2);
23172 $by -= ($table['border_spacing_V'] / 2);
23174 $by -= ($table['padding']['T'] + $table['border_details']['T']['w'] + $table['border_spacing_V'] / 2);
23176 } elseif ($tablestartpageno != $this->page && !empty($tableheader)) {
23179 $by -= $tableheaderadj;
23180 $bh = $this->y - $by;
23182 $bh -= $table['max_cell_border_width']['B'] / 2;
23214 $bw = $table['w'] - ($table['max_cell_border_width']['L'] / 2) - ($table['max_cell_border_width']['R'] / 2) - $table['margin']['L'] - $table['margin']['R'];
23217 if (!$this->ColActive) {
23218 if (isset($table['bgcolor'][-1])) {
23219 $color = $this->colorConverter->convert($table['bgcolor'][-1], $this->PDFAXwarnings);
23221 $this->tableBackgrounds[$level * 9][] = ['gradient' => false, 'x' => $bx, 'y' => $by, 'w' => $bw, 'h' => $bh, 'col' => $color];
23225 /* -- BACKGROUNDS -- */
23227 $g = $this->gradient->parseBackgroundGradient($table['gradient']);
23229 $this->tableBackgrounds[$level * 9 + 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' => ''];
23233 if (isset($table['background-image'])) {
23234 if (isset($table['background-image']['gradient']) && $table['background-image']['gradient'] && preg_match('/(-moz-)*(repeating-)*(linear|radial)-gradient/', $table['background-image']['gradient'])) {
23235 $g = $this->gradient->parseMozGradient($table['background-image']['gradient']);
23237 $this->tableBackgrounds[$level * 9 + 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' => ''];
23240 $image_id = $table['background-image']['image_id'];
23241 $orig_w = $table['background-image']['orig_w'];
23242 $orig_h = $table['background-image']['orig_h'];
23243 $x_pos = $table['background-image']['x_pos'];
23244 $y_pos = $table['background-image']['y_pos'];
23245 $x_repeat = $table['background-image']['x_repeat'];
23246 $y_repeat = $table['background-image']['y_repeat'];
23247 $resize = $table['background-image']['resize'];
23248 $opacity = $table['background-image']['opacity'];
23249 $itype = $table['background-image']['itype'];
23250 $this->tableBackgrounds[$level * 9 + 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];
23253 /* -- END BACKGROUNDS -- */
23256 if ($this->tableBackgrounds && $level == 1) {
23257 $s = $this->PrintTableBackgrounds();
23258 if ($this->table_rotate && !$this->processingHeader && !$this->processingFooter) {
23259 $this->tablebuffer = preg_replace('/(___TABLE___BACKGROUNDS' . $this->uniqstr . ')/', '\\1' . "\n" . $s . "\n", $this->tablebuffer);
23261 $this->tablebuffer = preg_replace('/(___TABLE___BACKGROUNDS' . $this->uniqstr . ')/', " ", $this->tablebuffer);
23263 } elseif ($this->bufferoutput) {
23264 $this->headerbuffer = preg_replace('/(___TABLE___BACKGROUNDS' . $this->uniqstr . ')/', '\\1' . "\n" . $s . "\n", $this->headerbuffer);
23266 $this->headerbuffer = preg_replace('/(___TABLE___BACKGROUNDS' . $this->uniqstr . ')/', " ", $this->headerbuffer);
23269 $this->pages[$this->page] = preg_replace('/(___TABLE___BACKGROUNDS' . $this->uniqstr . ')/', '\\1' . "\n" . $s . "\n", $this->pages[$this->page]);
23271 $this->pages[$this->page] = preg_replace('/(___TABLE___BACKGROUNDS' . $this->uniqstr . ')/', " ", $this->pages[$this->page]);
23274 $this->tableBackgrounds = [];
23280 if (!$this->table_rotate && $level == 1) {
23281 $this->DivLn($table['margin']['B'], $this->blklvl, true); // collapsible
23283 $this->y += ($table['margin']['B']);
23287 if ($this->ColActive && $level == 1) {
23288 $this->breakpoints[$this->CurrCol][] = $this->y;
23293 if ($lastCol < $numcols - 1) {
23305 /* -- END TABLES -- */
23309 for ($i = 1; $i <= count($this->extgstates); $i++) {
23310 $this->writer->object();
23311 $this->extgstates[$i]['n'] = $this->n;
23312 $this->writer->write('<</Type /ExtGState');
23313 foreach ($this->extgstates[$i]['parms'] as $k => $v) {
23314 $this->writer->write('/' . $k . ' ' . $v);
23316 $this->writer->write('>>');
23317 $this->writer->write('endobj');
23323 $this->encrypted = $this->protection->setProtection($permissions, $user_pass, $owner_pass, $length);
23330 $txt = $this->purify_utf8_text($txt);
23331 if ($this->text_input_as_HTML) {
23332 $txt = $this->all_entities_to_utf8($txt);
23334 if ($y == -1) {
23335 if (!$this->ColActive) {
23336 $y = $this->y;
23338 $y = $this->y0;
23339 } // If columns are on - mark top of columns
23344 $bmo = ['t' => $txt, 'l' => $level, 'y' => $y, 'p' => $this->page];
23346 if ($this->keep_block_together) {
23348 } elseif ($this->table_rotate) {
23349 $this->tbrot_BMoutlines[] = $bmo;
23350 } elseif ($this->kwt) {
23351 $this->kwt_BMoutlines[] = $bmo;
23352 } elseif ($this->ColActive) {
23353 $this->col_BMoutlines[] = $bmo;
23355 $this->BMoutlines[] = $bmo;
23376 $this->tableOfContents->TOC(
23399 $toc_orientation = (isset($a['toc_orientation']) ? $a['toc_orientation'] : (isset($a['toc-orientation']) ? $a['toc-orientation'] : ''));
23400 $toc_mgl = (isset($a['toc_mgl']) ? $a['toc_mgl'] : (isset($a['toc-margin-left']) ? $a['toc-margin-left'] : ''));
23401 $toc_mgr = (isset($a['toc_mgr']) ? $a['toc_mgr'] : (isset($a['toc-margin-right']) ? $a['toc-margin-right'] : ''));
23402 $toc_mgt = (isset($a['toc_mgt']) ? $a['toc_mgt'] : (isset($a['toc-margin-top']) ? $a['toc-margin-top'] : ''));
23403 $toc_mgb = (isset($a['toc_mgb']) ? $a['toc_mgb'] : (isset($a['toc-margin-bottom']) ? $a['toc-margin-bottom'] : ''));
23404 $toc_mgh = (isset($a['toc_mgh']) ? $a['toc_mgh'] : (isset($a['toc-margin-header']) ? $a['toc-margin-header'] : ''));
23405 $toc_mgf = (isset($a['toc_mgf']) ? $a['toc_mgf'] : (isset($a['toc-margin-footer']) ? $a['toc-margin-footer'] : ''));
23406 $toc_ohname = (isset($a['toc_ohname']) ? $a['toc_ohname'] : (isset($a['toc-odd-header-name']) ? $a['toc-odd-header-name'] : ''));
23407 $toc_ehname = (isset($a['toc_ehname']) ? $a['toc_ehname'] : (isset($a['toc-even-header-name']) ? $a['toc-even-header-name'] : ''));
23408 $toc_ofname = (isset($a['toc_ofname']) ? $a['toc_ofname'] : (isset($a['toc-odd-footer-name']) ? $a['toc-odd-footer-name'] : ''));
23409 $toc_efname = (isset($a['toc_efname']) ? $a['toc_efname'] : (isset($a['toc-even-footer-name']) ? $a['toc-even-footer-name'] : ''));
23410 $toc_ohvalue = (isset($a['toc_ohvalue']) ? $a['toc_ohvalue'] : (isset($a['toc-odd-header-value']) ? $a['toc-odd-header-value'] : 0));
23411 $toc_ehvalue = (isset($a['toc_ehvalue']) ? $a['toc_ehvalue'] : (isset($a['toc-even-header-value']) ? $a['toc-even-header-value'] : 0));
23412 $toc_ofvalue = (isset($a['toc_ofvalue']) ? $a['toc_ofvalue'] : (isset($a['toc-odd-footer-value']) ? $a['toc-odd-footer-value'] : 0));
23413 $toc_efvalue = (isset($a['toc_efvalue']) ? $a['toc_efvalue'] : (isset($a['toc-even-footer-value']) ? $a['toc-even-footer-value'] : 0));
23414 $toc_preHTML = (isset($a['toc_preHTML']) ? $a['toc_preHTML'] : (isset($a['toc-preHTML']) ? $a['toc-preHTML'] : ''));
23415 $toc_postHTML = (isset($a['toc_postHTML']) ? $a['toc_postHTML'] : (isset($a['toc-postHTML']) ? $a['toc-postHTML'] : ''));
23416 $toc_bookmarkText = (isset($a['toc_bookmarkText']) ? $a['toc_bookmarkText'] : (isset($a['toc-bookmarkText']) ? $a['toc-bookmarkText'] : ''));
23421 $mgl = (isset($a['mgl']) ? $a['mgl'] : (isset($a['margin-left']) ? $a['margin-left'] : ''));
23422 $mgr = (isset($a['mgr']) ? $a['mgr'] : (isset($a['margin-right']) ? $a['margin-right'] : ''));
23423 $mgt = (isset($a['mgt']) ? $a['mgt'] : (isset($a['margin-top']) ? $a['margin-top'] : ''));
23424 $mgb = (isset($a['mgb']) ? $a['mgb'] : (isset($a['margin-bottom']) ? $a['margin-bottom'] : ''));
23425 $mgh = (isset($a['mgh']) ? $a['mgh'] : (isset($a['margin-header']) ? $a['margin-header'] : ''));
23426 $mgf = (isset($a['mgf']) ? $a['mgf'] : (isset($a['margin-footer']) ? $a['margin-footer'] : ''));
23427 $ohname = (isset($a['ohname']) ? $a['ohname'] : (isset($a['odd-header-name']) ? $a['odd-header-name'] : ''));
23428 $ehname = (isset($a['ehname']) ? $a['ehname'] : (isset($a['even-header-name']) ? $a['even-header-name'] : ''));
23429 $ofname = (isset($a['ofname']) ? $a['ofname'] : (isset($a['odd-footer-name']) ? $a['odd-footer-name'] : ''));
23430 $efname = (isset($a['efname']) ? $a['efname'] : (isset($a['even-footer-name']) ? $a['even-footer-name'] : ''));
23431 $ohvalue = (isset($a['ohvalue']) ? $a['ohvalue'] : (isset($a['odd-header-value']) ? $a['odd-header-value'] : 0));
23432 $ehvalue = (isset($a['ehvalue']) ? $a['ehvalue'] : (isset($a['even-header-value']) ? $a['even-header-value'] : 0));
23433 $ofvalue = (isset($a['ofvalue']) ? $a['ofvalue'] : (isset($a['odd-footer-value']) ? $a['odd-footer-value'] : 0));
23434 $efvalue = (isset($a['efvalue']) ? $a['efvalue'] : (isset($a['even-footer-value']) ? $a['even-footer-value'] : 0));
23437 $toc_pagesel = (isset($a['toc_pagesel']) ? $a['toc_pagesel'] : (isset($a['toc-pageselector']) ? $a['toc-pageselector'] : ''));
23438 $sheetsize = (isset($a['sheetsize']) ? $a['sheetsize'] : (isset($a['sheet-size']) ? $a['sheet-size'] : ''));
23439 $toc_sheetsize = (isset($a['toc_sheetsize']) ? $a['toc_sheetsize'] : (isset($a['toc-sheet-size']) ? $a['toc-sheet-size'] : ''));
23441 $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);
23447 if ($this->state == 0) {
23448 $this->AddPage();
23450 if ($this->y == $this->tMargin && (!$this->mirrorMargins || ($this->mirrorMargins && $this->page % 2 == 1))) {
23452 if ($this->page == 1 && count($this->PageNumSubstitutions) == 0) {
23456 // $this->PageNumSubstitutions[] = array('from'=>1, 'reset'=> $resetpagenum, 'type'=>$pagenumstyle, 'suppress'=> $suppress);
23458 $this->PageNumSubstitutions[] = ['from' => $this->page, 'reset' => $resetpagenum, 'type' => $pagenumstyle, 'suppress' => $suppress];
23460 $this->AddPage($orientation, 'NEXT-ODD', $resetpagenum, $pagenumstyle, $suppress, $mgl, $mgr, $mgt, $mgb, $mgh, $mgf, $ohname, $ehname, $ofname, $efname, $ohvalue, $ehvalue, $ofvalue, $efvalue, $pagesel, $sheetsize);
23462 $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);
23467 if ($this->ColActive) {
23468 $ily = $this->y0;
23470 $ily = $this->y;
23473 $linkn = $this->AddLink();
23475 if ($this->table_rotate) {
23476 $this->internallink[$uid] = ["Y" => $ily, "PAGE" => $this->page, "tbrot" => true];
23477 } elseif ($this->kwt) {
23478 $this->internallink[$uid] = ["Y" => $ily, "PAGE" => $this->page, "kwt" => true];
23479 } elseif ($this->ColActive) {
23480 $this->internallink[$uid] = ["Y" => $ily, "PAGE" => $this->page, "col" => $this->CurrCol];
23481 } elseif (!$this->keep_block_together) {
23482 $this->internallink[$uid] = ["Y" => $ily, "PAGE" => $this->page];
23484 $this->internallink['#' . $uid] = $linkn;
23485 $this->SetLink($linkn, $ily, $this->page);
23494 $btoc = ['t' => $txt, 'l' => $level, 'p' => $this->page, 'link' => $linkn, 'toc_id' => $toc_id];
23495 if ($this->keep_block_together) {
23497 } /* -- TABLES -- */ elseif ($this->table_rotate) {
23498 $this->tbrot_toc[] = $btoc;
23499 } elseif ($this->kwt) {
23500 $this->kwt_toc[] = $btoc;
23501 } /* -- END TABLES -- */ elseif ($this->ColActive) { // *COLUMNS*
23502 $this->col_toc[] = $btoc; // *COLUMNS*
23505 $this->tableOfContents->_toc[] = $btoc;
23509 /* -- END TOC -- */
23512 function MovePages($target_page, $start_page, $end_page = -1)
23518 $n_toc = $end_page - $start_page + 1;
23521 if (count($this->PageNumSubstitutions)) {
23525 foreach ($this->PageNumSubstitutions as $k => $v) {
23526 if ($this->PageNumSubstitutions[$k]['from'] == $target_page) {
23528 if ($this->PageNumSubstitutions[$k]['suppress'] != 'on' && $this->PageNumSubstitutions[$k]['suppress'] != 1) {
23529 $this->PageNumSubstitutions[$k]['suppress'] = 'off';
23532 if ($this->PageNumSubstitutions[$k]['from'] == $start_page) {
23534 if ($this->PageNumSubstitutions[$k]['suppress'] != 'on' && $this->PageNumSubstitutions[$k]['suppress'] != 1) {
23535 $this->PageNumSubstitutions[$k]['suppress'] = 'off';
23538 if ($this->PageNumSubstitutions[$k]['from'] == ($end_page + 1)) {
23540 if ($this->PageNumSubstitutions[$k]['suppress'] != 'on' && $this->PageNumSubstitutions[$k]['suppress'] != 1) {
23541 $this->PageNumSubstitutions[$k]['suppress'] = 'off';
23547 list($tp_type, $tp_suppress, $tp_reset) = $this->docPageSettings($target_page);
23550 list($sp_type, $sp_suppress, $sp_reset) = $this->docPageSettings($start_page);
23553 list($ep_type, $ep_suppress, $ep_reset) = $this->docPageSettings($start_page - 1);
23560 $last[] = $this->pages[$i];
23563 for ($i = $start_page - 1; $i >= ($target_page); $i--) {
23564 $this->pages[$i + $n_toc] = $this->pages[$i];
23568 $this->pages[$target_page + $i] = $last[$i];
23571 /* -- BOOKMARKS -- */
23573 foreach ($this->BMoutlines as $i => $o) {
23575 $this->BMoutlines[$i]['p'] += $n_toc;
23578 /* -- END BOOKMARKS -- */
23581 if (count($this->PageLinks)) {
23583 foreach ($this->PageLinks as $i => $o) {
23584 foreach ($this->PageLinks[$i] as $key => $pl) {
23588 $this->PageLinks[$i][$key][4] = '@' . ($p + ($target_page - $start_page));
23590 $this->PageLinks[$i][$key][4] = '@' . ($p + $n_toc);
23595 $newarr[($i + ($target_page - $start_page))] = $this->PageLinks[$i];
23597 $newarr[($i + $n_toc)] = $this->PageLinks[$i];
23599 $newarr[$i] = $this->PageLinks[$i];
23602 $this->PageLinks = $newarr;
23606 if (count($this->OrientationChanges)) {
23608 foreach ($this->OrientationChanges as $p => $v) {
23610 $newarr[($p + ($target_page - $start_page))] = $this->OrientationChanges[$p];
23612 $newarr[$p + $n_toc] = $this->OrientationChanges[$p];
23614 $newarr[$p] = $this->OrientationChanges[$p];
23618 $this->OrientationChanges = $newarr;
23622 if (count($this->pageDim)) {
23624 foreach ($this->pageDim as $p => $v) {
23626 $newarr[($p + ($target_page - $start_page))] = $this->pageDim[$p];
23628 $newarr[$p + $n_toc] = $this->pageDim[$p];
23630 $newarr[$p] = $this->pageDim[$p];
23634 $this->pageDim = $newarr;
23638 if (count($this->saveHTMLHeader)) {
23640 foreach ($this->saveHTMLHeader as $p => $v) {
23642 $newarr[($p + ($target_page - $start_page))] = $this->saveHTMLHeader[$p];
23644 $newarr[$p + $n_toc] = $this->saveHTMLHeader[$p];
23646 $newarr[$p] = $this->saveHTMLHeader[$p];
23650 $this->saveHTMLHeader = $newarr;
23652 if (count($this->saveHTMLFooter)) {
23654 foreach ($this->saveHTMLFooter as $p => $v) {
23656 $newarr[($p + ($target_page - $start_page))] = $this->saveHTMLFooter[$p];
23658 $newarr[$p + $n_toc] = $this->saveHTMLFooter[$p];
23660 $newarr[$p] = $this->saveHTMLFooter[$p];
23664 $this->saveHTMLFooter = $newarr;
23668 if (count($this->internallink)) {
23669 foreach ($this->internallink as $key => $o) {
23671 $this->internallink[$key]['PAGE'] += ($target_page - $start_page);
23673 $this->internallink[$key]['PAGE'] += $n_toc;
23679 if (count($this->links)) {
23680 foreach ($this->links as $key => $o) {
23682 $this->links[$key][0] += ($target_page - $start_page);
23685 $this->links[$key][0] += $n_toc;
23691 if (count($this->form->forms)) {
23692 foreach ($this->form->forms as $key => $f) {
23694 $this->form->forms[$key]['page'] += ($target_page - $start_page);
23697 $this->form->forms[$key]['page'] += $n_toc;
23702 /* -- ANNOTATIONS -- */
23704 if (count($this->PageAnnots)) {
23706 foreach ($this->PageAnnots as $p => $anno) {
23708 $np = $p + ($target_page - $start_page);
23718 $newarr[$p] = $this->PageAnnots[$p];
23721 $this->PageAnnots = $newarr;
23724 /* -- END ANNOTATIONS -- */
23727 if (count($this->tableOfContents->_toc)) {
23728 foreach ($this->tableOfContents->_toc as $key => $t) {
23730 $this->tableOfContents->_toc[$key]['p'] += ($target_page - $start_page);
23733 $this->tableOfContents->_toc[$key]['p'] += $n_toc;
23739 if (count($this->PageNumSubstitutions)) {
23741 foreach ($this->PageNumSubstitutions as $k => $v) {
23742 if ($this->PageNumSubstitutions[$k]['from'] >= $start_page && $this->PageNumSubstitutions[$k]['from'] <= $end_page) {
23743 $this->PageNumSubstitutions[$k]['from'] += ($target_page - $start_page);
23744 $newarr[$this->PageNumSubstitutions[$k]['from']] = $this->PageNumSubstitutions[$k];
23745 } elseif ($this->PageNumSubstitutions[$k]['from'] >= $target_page && $this->PageNumSubstitutions[$k]['from'] < $start_page) {
23746 $this->PageNumSubstitutions[$k]['from'] += $n_toc;
23747 $newarr[$this->PageNumSubstitutions[$k]['from']] = $this->PageNumSubstitutions[$k];
23749 $newarr[$this->PageNumSubstitutions[$k]['from']] = $this->PageNumSubstitutions[$k];
23759 if (!$ep_present && $end_page > count($this->pages)) {
23763 $this->PageNumSubstitutions = [];
23765 $this->PageNumSubstitutions[] = $v;
23770 function DeletePages($start_page, $end_page = -1)
23776 $n_tod = $end_page - $start_page + 1;
23777 $last_page = count($this->pages);
23778 $n_atend = $last_page - $end_page + 1;
23782 $this->pages[$start_page + $i] = $this->pages[$end_page + 1 + $i];
23786 unset($this->pages[$last_page - $i]);
23790 /* -- BOOKMARKS -- */
23792 foreach ($this->BMoutlines as $i => $o) {
23794 $this->BMoutlines[$i]['p'] -= $n_tod;
23796 unset($this->BMoutlines[$i]);
23799 /* -- END BOOKMARKS -- */
23802 if (count($this->PageLinks)) {
23804 foreach ($this->PageLinks as $i => $o) {
23805 foreach ($this->PageLinks[$i] as $key => $pl) {
23809 $this->PageLinks[$i][$key][4] = '@' . ($p - $n_tod);
23811 unset($this->PageLinks[$i][$key]);
23816 $newarr[($i - $n_tod)] = $this->PageLinks[$i];
23818 $newarr[$i] = $this->PageLinks[$i];
23821 $this->PageLinks = $newarr;
23825 if (count($this->OrientationChanges)) {
23827 foreach ($this->OrientationChanges as $p => $v) {
23829 $newarr[($p - $t_tod)] = $this->OrientationChanges[$p];
23831 $newarr[$p] = $this->OrientationChanges[$p];
23835 $this->OrientationChanges = $newarr;
23839 if (count($this->pageDim)) {
23841 foreach ($this->pageDim as $p => $v) {
23843 $newarr[($p - $n_tod)] = $this->pageDim[$p];
23845 $newarr[$p] = $this->pageDim[$p];
23849 $this->pageDim = $newarr;
23853 if (count($this->saveHTMLHeader)) {
23854 foreach ($this->saveHTMLHeader as $p => $v) {
23856 $newarr[($p - $n_tod)] = $this->saveHTMLHeader[$p];
23859 $newarr[$p] = $this->saveHTMLHeader[$p];
23863 $this->saveHTMLHeader = $newarr;
23865 if (count($this->saveHTMLFooter)) {
23867 foreach ($this->saveHTMLFooter as $p => $v) {
23869 $newarr[($p - $n_tod)] = $this->saveHTMLFooter[$p];
23871 $newarr[$p] = $this->saveHTMLFooter[$p];
23875 $this->saveHTMLFooter = $newarr;
23879 foreach ($this->internallink as $key => $o) {
23881 $this->internallink[$key]['PAGE'] -= $n_tod;
23883 unset($this->internallink[$key]);
23888 foreach ($this->links as $key => $o) {
23890 $this->links[$key][0] -= $n_tod;
23892 unset($this->links[$key]);
23897 foreach ($this->form->forms as $key => $f) {
23899 $this->form->forms[$key]['page'] -= $n_tod;
23901 unset($this->form->forms[$key]);
23905 /* -- ANNOTATIONS -- */
23907 if (count($this->PageAnnots)) {
23909 foreach ($this->PageAnnots as $p => $anno) {
23912 $newarr[($p - $n_tod)][] = $o;
23915 $newarr[$p] = $this->PageAnnots[$p];
23919 $this->PageAnnots = $newarr;
23921 /* -- END ANNOTATIONS -- */
23924 foreach ($this->PageNumSubstitutions as $k => $v) {
23925 if ($this->PageNumSubstitutions[$k]['from'] > $end_page) {
23926 $this->PageNumSubstitutions[$k]['from'] -= $n_tod;
23927 } elseif ($this->PageNumSubstitutions[$k]['from'] < $start_page) {
23928 unset($this->PageNumSubstitutions[$k]);
23933 $this->page = count($this->pages);
23937 /* -- INDEX -- */
23943 $this->IndexEntrySee($txt, $xref);
23949 if ($this->keep_block_together) {
23951 } /* -- TABLES -- */ elseif ($this->kwt) {
23952 $size = count($this->kwt_Reference);
23953 for ($i = 0; $i < $size; $i++) {
23954 if (isset($this->kwt_Reference[$i]['t']) && $this->kwt_Reference[$i]['t'] == $txt) {
23956 if ($this->page != $this->kwt_Reference[$i]['op']) {
23957 $this->kwt_Reference[$i]['op'] = $this->page;
23962 $this->kwt_Reference[] = ['t' => $txt, 'op' => $this->page];
23964 } /* -- END TABLES -- */ else {
23965 $size = count($this->Reference);
23966 for ($i = 0; $i < $size; $i++) {
23967 if (isset($this->Reference[$i]['t']) && $this->Reference[$i]['t'] == $txt) {
23969 if (!in_array($this->page, $this->Reference[$i]['p'])) {
23970 $this->Reference[$i]['p'][] = $this->page;
23975 $this->Reference[] = ['t' => $txt, 'p' => [$this->page]];
23983 if ($this->directionality == 'rtl') { // *OTL*
23986 $txta = str_replace(':', ' - ', $txta); // *OTL*
23989 $txtb = str_replace(':', ' - ', $txtb); // *OTL*
24000 $this->Reference[] = ['t' => $txta . ' - see ' . $txtb, 'p' => []];
24007 if ($v->isDir() || $v->isDot()) {
24011 $files[] = $v->getPathname();
24019 $size = count($this->Reference);
24020 if ($size == 0) {
24026 // e.g. "elephant 73, 97-99" = elephant[$spacer]73[$sep]97[$joiner]99
24027 // $subEntrySeparator separates main and subentry (if $this->indexUseSubentries == false;) e.g.
24029 // $subEntryInset specifies what precedes a subentry (if $this->indexUseSubentries == true;) e.g.
24032 if ($this->directionality == 'rtl') {
24034 $joiner = '-';
24036 $subEntryInset = ' - ';
24039 $joiner = '-';
24041 $subEntryInset = ' - ';
24044 for ($i = 0; $i < $size; $i++) {
24045 $txt = $this->Reference[$i]['t'];
24047 $txt = $this->purify_utf8($txt);
24048 $this->Reference[$i]['uf'] = $txt; // Unformatted e.g. pure utf-8 encoded characters, no mark-up/tags
24055 }, $this->filesInDir(__DIR__ . '/../data/collations/')))) {
24060 for ($i = 0; $i < $size; $i++) {
24061 if ($this->Reference[$i]['uf']) {
24062 $l = mb_substr($this->Reference[$i]['uf'], 0, 1, 'UTF-8');
24064 $uni = $this->UTF8StringToArray($l);
24067 $this->Reference[$i]['d'] = UtfString::code2utf($collation[$ucode]);
24069 $this->Reference[$i]['d'] = mb_strtolower($l, 'UTF-8');
24072 $this->Reference[$i]['d'] = mb_strtolower($l, 'UTF-8');
24084 usort($this->Reference, function ($a, $b) {
24097 for ($i = 0; $i < $size; $i++) {
24098 if ($this->Reference[$i]['t']) {
24100 $lett = $this->Reference[$i]['d'];
24105 $txt = $this->Reference[$i]['t'];
24107 // Sub-entries e.g. Mammals:elephant
24109 $a = preg_split('/(<.*?>)/', $txt, -1, PREG_SPLIT_DELIM_CAPTURE);
24115 if ($this->indexUseSubentries) {
24141 $ppp = $this->Reference[$i]['p']; // = array of page numbers to point to
24151 if ($ppp[$zi] == ($ppp[($zi - 1)] + 1)) {
24159 $html .= $this->docPageNum($range_start);
24166 $html .= '<a class="mpdf_index_link" href="@' . $ppp[$zi - 1] . '">';
24168 $html .= $this->docPageNum($ppp[$zi - 1]);
24176 $html .= '<a class="mpdf_index_link" href="@' . $ppp[$zi - 1] . '">';
24178 $html .= $this->docPageNum($ppp[$zi - 1]);
24193 $html .= $this->docPageNum($range_start);
24202 $html .= $this->docPageNum($range_end);
24208 $html .= $this->docPageNum($range_end);
24215 $html .= '<a class="mpdf_index_link" href="@' . $ppp[(count($ppp) - 1)] . '">';
24217 $html .= $this->docPageNum($ppp[(count($ppp) - 1)]);
24228 $save_fpb = $this->fixedPosBlockSave;
24229 $this->WriteHTML($html);
24230 $this->fixedPosBlockSave = $save_fpb;
24232 $this->breakpoints[$this->CurrCol][] = $this->y; // *COLUMNS*
24235 /* -- END INDEX -- */
24239 if (count($this->cellBorderBuffer)) {
24240 $this->printcellbuffer();
24242 /* -- COLUMNS -- */
24243 if ($this->ColActive == 1) {
24244 if ($this->CurrCol < $this->NbCol - 1) {
24246 $this->CurrCol++;
24247 $this->SetCol($this->CurrCol);
24248 $this->y = $this->y0;
24249 $this->ChangeColumn = 1; // Number (and direction) of columns changed +1, +2, -2 etc.
24251 if ($this->directionality == 'rtl') {
24252 $this->ChangeColumn = -($this->ChangeColumn);
24257 // Go back to the first column - NEW PAGE
24258 if (count($this->columnbuffer)) {
24259 $this->printcolumnbuffer();
24261 $this->SetCol(0);
24262 $this->y0 = $this->tMargin;
24263 $this->ChangeColumn = -($this->NbCol - 1);
24265 if ($this->directionality == 'rtl') {
24266 $this->ChangeColumn = -($this->ChangeColumn);
24271 } /* -- END COLUMNS -- */
24272 /* -- TABLES -- */ elseif ($this->table_rotate) {
24273 if ($this->tablebuffer) {
24274 $this->printtablebuffer();
24277 } /* -- END TABLES -- */ else { // *COLUMNS*
24278 $this->ChangeColumn = 0;
24279 return $this->autoPageBreak;
24281 return $this->autoPageBreak;
24284 // ----------- COLUMNS ---------------------
24285 /* -- COLUMNS -- */
24292 if ($this->ColActive) {
24293 $this->ColActive = 0;
24294 if (count($this->columnbuffer)) {
24295 $this->printcolumnbuffer();
24297 $this->NbCol = 1;
24298 $this->ResetMargins();
24299 $this->pgwidth = $this->w - $this->lMargin - $this->rMargin;
24300 $this->divwidth = 0;
24301 $this->Ln();
24303 $this->ColActive = 0;
24304 $this->columnbuffer = [];
24305 $this->ColDetails = [];
24306 $this->columnLinks = [];
24307 $this->columnAnnots = [];
24308 $this->columnForms = [];
24309 $this->col_BMoutlines = [];
24310 $this->col_toc = [];
24311 $this->breakpoints = [];
24313 if ($this->ColActive) {
24314 $this->ColActive = 0;
24315 if (count($this->columnbuffer)) {
24316 $this->printcolumnbuffer();
24318 $this->ResetMargins();
24320 if (isset($this->y) && $this->y > $this->tMargin) {
24321 $this->Ln();
24323 $this->NbCol = $NbCol;
24324 $this->ColGap = $gap;
24325 $this->divwidth = 0;
24326 $this->ColActive = 1;
24327 $this->ColumnAdjust = true; // enables column height adjustment for the page
24328 $this->columnbuffer = [];
24329 $this->ColDetails = [];
24330 $this->columnLinks = [];
24331 $this->columnAnnots = [];
24332 $this->columnForms = [];
24333 $this->col_BMoutlines = [];
24334 $this->col_toc = [];
24335 $this->breakpoints = [];
24341 $this->colvAlign = $vAlign;
24343 $absL = $this->DeflMargin - ($gap / 2);
24344 $absR = $this->DefrMargin - ($gap / 2);
24345 $PageWidth = $this->w - $absL - $absR; // virtual pagewidth for calculation only
24346 $ColWidth = (($PageWidth - ($gap * ($NbCol))) / $NbCol);
24347 $this->ColWidth = $ColWidth;
24348 /* -- OTL -- */
24350 if ($this->directionality == 'rtl') {
24351 for ($i = 0; $i < $this->NbCol; $i++) {
24352 $this->ColL[$i] = $absL + ($gap / 2) + (($NbCol - ($i + 1)) * ($PageWidth / $NbCol));
24353 $this->ColR[$i] = $this->ColL[$i] + $ColWidth; // NB This is not R margin -> R pos
24356 /* -- END OTL -- */
24357 for ($i = 0; $i < $this->NbCol; $i++) {
24358 $this->ColL[$i] = $absL + ($gap / 2) + ($i * ($PageWidth / $NbCol) );
24359 $this->ColR[$i] = $this->ColL[$i] + $ColWidth; // NB This is not R margin -> R pos
24362 $this->pgwidth = $ColWidth;
24363 $this->SetCol(0);
24364 $this->y0 = $this->y;
24366 $this->x = $this->lMargin;
24373 $this->CurrCol = $CurrCol;
24374 $x = $this->ColL[$CurrCol];
24375 $xR = $this->ColR[$CurrCol]; // NB This is not R margin -> R pos
24376 if (($this->mirrorMargins) && (($this->page) % 2 == 0)) { // EVEN
24377 $x += $this->MarginCorrection;
24378 $xR += $this->MarginCorrection;
24380 $this->SetMargins($x, ($this->w - $xR), $this->tMargin);
24385 $this->NewColumn();
24386 $this->ColumnAdjust = false; // disables all column height adjustment for the page.
24391 if ($this->ColActive == 1) {
24392 if ($this->CurrCol < $this->NbCol - 1) {
24394 $this->CurrCol++;
24395 $this->SetCol($this->CurrCol);
24396 $this->y = $this->y0;
24397 $this->ChangeColumn = 1;
24399 if ($this->directionality == 'rtl') {
24400 $this->ChangeColumn = -($this->ChangeColumn);
24406 if (count($this->columnbuffer)) {
24407 $this->printcolumnbuffer();
24409 $this->AddPage($this->CurOrientation);
24410 $this->SetCol(0);
24411 $this->y0 = $this->tMargin;
24412 $this->ChangeColumn = -($this->NbCol - 1);
24414 if ($this->directionality == 'rtl') {
24415 $this->ChangeColumn = -($this->ChangeColumn);
24418 $this->x = $this->lMargin;
24420 $this->AddPage($this->CurOrientation);
24426 // Columns ended (but page not ended) -> try to match all columns - unless disabled by using a custom column-break
24427 if (!$this->ColActive && $this->ColumnAdjust && !$this->keepColumns) {
24429 $this->ColDetails[0]['add_y'] = 0;
24432 for ($i = 1; $i < $this->NbCol; $i++) {
24433 if (isset($this->ColDetails[$i]['bottom_margin']) && $this->ColDetails[$i]['bottom_margin']) { // If any entries in the column
24434 $this->ColDetails[$i]['add_y'] = ($this->ColDetails[$i - 1]['bottom_margin'] - $this->y0) + $this->ColDetails[$i - 1]['add_y'];
24440 foreach ($this->columnbuffer as $key => $s) {
24443 $this->columnbuffer[$key]['rel_y'] = $s['y'] + $this->ColDetails[$s['col']]['add_y'] - $this->y0;
24444 $this->columnbuffer[$key]['s'] = '';
24446 $this->columnbuffer[$key]['rel_y'] = $s['y'] + $this->ColDetails[$s['col']]['add_y'] - $this->y0;
24447 } elseif (preg_match('/\d+\.\d\d+ (\d+\.\d\d+) \d+\.\d\d+ [\-]{0,1}\d+\.\d\d+ re/', $t)) {
24448 $this->columnbuffer[$key]['rel_y'] = $s['y'] + $this->ColDetails[$s['col']]['add_y'] - $this->y0;
24450 $this->columnbuffer[$key]['rel_y'] = $s['y'] + $this->ColDetails[$s['col']]['add_y'] - $this->y0;
24452 $this->columnbuffer[$key]['rel_y'] = $s['y'] + $this->ColDetails[$s['col']]['add_y'] - $this->y0;
24454 $this->columnbuffer[$key]['rel_y'] = $s['y'] + $this->ColDetails[$s['col']]['add_y'] - $this->y0;
24456 $this->columnbuffer[$key]['rel_y'] = $s['y'] + $this->ColDetails[$s['col']]['add_y'] - $this->y0;
24459 foreach ($this->internallink as $key => $f) {
24461 $this->internallink[$key]['rel_y'] = $f['Y'] + $this->ColDetails[$f['col']]['add_y'] - $this->y0;
24466 foreach ($this->breakpoints as $c => $bpa) {
24468 $breaks[] = $rely + $this->ColDetails[$c]['add_y'] - $this->y0;
24473 if (isset($this->ColDetails[$last_col]['bottom_margin'])) {
24474 $lcbm = $this->ColDetails[$last_col]['bottom_margin'];
24478 $sum_h = $this->ColDetails[$last_col]['add_y'] + $lcbm - $this->y0;
24479 // $sum_h = max($this->ColDetails[$last_col]['add_y'] + $this->ColDetails[$last_col]['bottom_margin'] - $this->y0, end($breaks));
24480 $target_h = ($sum_h / $this->NbCol);
24483 for ($i = 1; $i < $this->NbCol; $i++) {
24484 $th = ($sum_h * $i / $this->NbCol);
24487 if (($val - $th) < ($th - $breaks[$bk - 1])) {
24488 $cbr[$i - 1] = $val;
24490 $cbr[$i - 1] = $breaks[$bk - 1];
24496 $cbr[($this->NbCol - 1)] = $sum_h;
24501 for ($i = 0; $i < $this->NbCol - 1; $i++) {
24506 // Now update the columns - divide into columns of approximately equal value
24514 foreach ($this->columnbuffer as $key => $s) {
24525 if ($this->directionality == 'rtl') { // *OTL*
24526 $xadj = -(($newcolumn - $s['col']) * ($this->ColWidth + $this->ColGap)); // *OTL*
24529 $xadj = ($newcolumn - $s['col']) * ($this->ColWidth + $this->ColGap);
24533 $last_col_bottom = $this->columnbuffer[$key]['rel_y'];
24536 $yadj = ($s['rel_y'] - $s['y']) - ($last_col_bottom) + $this->y0;
24541 $t = $this->columnAdjustPregReplace('Td', $xadj, $yadj, '/BT (\d+\.\d\d+) (\d+\.\d\d+) Td/', $t);
24542 $t = $this->columnAdjustPregReplace('re', $xadj, $yadj, '/(\d+\.\d\d+) (\d+\.\d\d+) (\d+\.\d\d+) ([\-]{0,1}\d+\.\d\d+) re/', $t);
24543 $t = $this->columnAdjustPregReplace('l', $xadj, $yadj, '/(\d+\.\d\d+) (\d+\.\d\d+) l/', $t);
24544 $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);
24545 $t = $this->columnAdjustPregReplace('draw', $xadj, $yadj, '/(\d+\.\d\d+) (\d+\.\d\d+) m/', $t);
24546 $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);
24548 $this->columnbuffer[$key]['s'] = $t;
24549 $this->columnbuffer[$key]['newcol'] = $newcolumn;
24550 $this->columnbuffer[$key]['newy'] = $s['y'] + $yadj;
24553 if ((isset($this->ColDetails[$newcolumn]['max_bottom']) && $clb > $this->ColDetails[$newcolumn]['max_bottom']) || (!isset($this->ColDetails[$newcolumn]['max_bottom']) && $clb)) {
24554 $this->ColDetails[$newcolumn]['max_bottom'] = $clb;
24560 if (isset($this->columnLinks[$s['col']][intval($s['x'])][intval($s['y'])])) {
24561 $ref = $this->columnLinks[$s['col']][intval($s['x'])][intval($s['y'])];
24562 $this->PageLinks[$this->page][$ref][0] += ($xadj * Mpdf::SCALE);
24563 $this->PageLinks[$this->page][$ref][1] -= ($yadj * Mpdf::SCALE);
24564 unset($this->columnLinks[$s['col']][intval($s['x'])][intval($s['y'])]);
24567 if (isset($this->columnForms[$s['col']][intval($s['x'])][intval($s['y'])])) {
24568 $ref = $this->columnForms[$s['col']][intval($s['x'])][intval($s['y'])];
24569 $this->form->forms[$ref]['x'] += ($xadj);
24570 $this->form->forms[$ref]['y'] += ($yadj);
24571 unset($this->columnForms[$s['col']][intval($s['x'])][intval($s['y'])]);
24573 /* -- ANNOTATIONS -- */
24574 if (isset($this->columnAnnots[$s['col']][intval($s['x'])][intval($s['y'])])) {
24575 $ref = $this->columnAnnots[$s['col']][intval($s['x'])][intval($s['y'])];
24576 if ($this->PageAnnots[$this->page][$ref]['x'] < 0) {
24577 $this->PageAnnots[$this->page][$ref]['x'] -= ($xadj);
24579 $this->PageAnnots[$this->page][$ref]['x'] += ($xadj);
24581 $this->PageAnnots[$this->page][$ref]['y'] += ($yadj); // unlike PageLinks, Page annots has y values from top in mm
24582 unset($this->columnAnnots[$s['col']][intval($s['x'])][intval($s['y'])]);
24584 /* -- END ANNOTATIONS -- */
24588 /* -- BOOKMARKS -- */
24590 foreach ($this->col_BMoutlines as $v) {
24591 $this->BMoutlines[] = ['t' => $v['t'], 'l' => $v['l'], 'y' => $this->y0, 'p' => $v['p']];
24593 /* -- END BOOKMARKS -- */
24595 /* -- TOC -- */
24598 foreach ($this->col_toc as $v) {
24599 $this->tableOfContents->_toc[] = ['t' => $v['t'], 'l' => $v['l'], 'p' => $v['p'], 'link' => $v['link'], 'toc_id' => $v['toc_id']];
24600 $this->links[$v['link']][1] = $this->y0;
24602 /* -- END TOC -- */
24605 if ($this->colvAlign == 'J') {
24606 foreach ($this->columnbuffer as $key => $s) {
24609 if (isset($this->ColDetails[$s['newcol']]['max_bottom']) && $this->ColDetails[$s['newcol']]['max_bottom'] && $this->ColDetails[$s['newcol']]['max_bottom'] != $this->y0) {
24610 $ratio = ($lowest_bottom_y - ($this->y0)) / ($this->ColDetails[$s['newcol']]['max_bottom'] - ($this->y0));
24614 if (($ratio > 1) && ($ratio <= $this->max_colH_correction)) {
24615 $yadj = ($s['newy'] - $this->y0) * ($ratio - 1);
24618 if (isset($this->columnLinks[$s['col']][intval($s['x'])][intval($s['y'])])) {
24619 $ref = $this->columnLinks[$s['col']][intval($s['x'])][intval($s['y'])];
24620 $this->PageLinks[$this->page][$ref][1] -= ($yadj * Mpdf::SCALE); // y value
24621 $this->PageLinks[$this->page][$ref][3] *= $ratio; // height
24622 unset($this->columnLinks[$s['col']][intval($s['x'])][intval($s['y'])]);
24625 if (isset($this->columnForms[$s['col']][intval($s['x'])][intval($s['y'])])) {
24626 $ref = $this->columnForms[$s['col']][intval($s['x'])][intval($s['y'])];
24627 $this->form->forms[$ref]['x'] += ($xadj);
24628 $this->form->forms[$ref]['y'] += ($yadj);
24629 unset($this->columnForms[$s['col']][intval($s['x'])][intval($s['y'])]);
24631 /* -- ANNOTATIONS -- */
24632 if (isset($this->columnAnnots[$s['col']][intval($s['x'])][intval($s['y'])])) {
24633 $ref = $this->columnAnnots[$s['col']][intval($s['x'])][intval($s['y'])];
24634 $this->PageAnnots[$this->page][$ref]['y'] += ($yadj);
24635 unset($this->columnAnnots[$s['col']][intval($s['x'])][intval($s['y'])]);
24637 /* -- END ANNOTATIONS -- */
24641 foreach ($this->internallink as $key => $f) {
24644 for ($nbc = 0; $nbc < $this->NbCol; $nbc++) {
24649 $yadj = ($f['rel_y'] - $f['Y']) - $last_col_bottom + $this->y0;
24653 $this->internallink[$key] = $f;
24657 $last_col = -1;
24659 foreach ($this->columnbuffer as $key => $s) {
24662 if (isset($this->ColDetails[$s['newcol']]['max_bottom']) && $this->ColDetails[$s['newcol']]['max_bottom'] && $this->ColDetails[$s['newcol']]['max_bottom'] != $this->y0) {
24663 $ratio = ($lowest_bottom_y - ($this->y0)) / ($this->ColDetails[$s['newcol']]['max_bottom'] - ($this->y0));
24667 if (($ratio > 1) && ($ratio <= $this->max_colH_correction)) {
24669 $this->pages[$this->page] .= $this->StartTransform(true) . "\n";
24670 $this->pages[$this->page] .= $this->transformScale(100, $ratio * 100, $x = '', $this->y0, true) . "\n";
24675 $this->pages[$this->page] .= $s['s'] . "\n";
24676 if (isset($s['rel_y']) && ($ratio > 1) && ($ratio <= $this->max_colH_correction)) { // only process position sensitive data
24678 $this->pages[$this->page] .= $this->StopTransform(true) . "\n";
24683 $this->pages[$this->page] .= $this->StopTransform(true) . "\n";
24685 } else { // if NOT $this->colvAlign == 'J'
24687 foreach ($this->columnbuffer as $s) {
24688 $this->pages[$this->page] .= $s['s'] . "\n";
24692 $this->y = $lowest_bottom_y;
24694 } // Columns not ended but new page -> align columns (can leave the columns alone - just tidy up the height)
24695 elseif ($this->colvAlign == 'J' && $this->ColumnAdjust && !$this->keepColumns) {
24698 foreach ($this->columnbuffer as $key => $s) {
24701 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)) ||
24707 if ((isset($this->ColDetails[$s['col']]['max_bottom']) && $clb > $this->ColDetails[$s['col']]['max_bottom']) || !isset($this->ColDetails[$s['col']]['max_bottom'])) {
24708 $this->ColDetails[$s['col']]['max_bottom'] = $clb;
24713 $this->columnbuffer[$key]['rel_y'] = $s['y']; // Marks position sensitive data to process later
24715 $this->columnbuffer[$key]['s'] = '';
24720 foreach ($this->columnbuffer as $key => $s) {
24722 if (isset($this->ColDetails[$s['col']]['max_bottom']) && $this->ColDetails[$s['col']]['max_bottom']) {
24723 $ratio = ($lowest_bottom_y - ($this->y0)) / ($this->ColDetails[$s['col']]['max_bottom'] - ($this->y0));
24727 if (($ratio > 1) && ($ratio <= $this->max_colH_correction)) {
24728 $yadj = ($s['y'] - $this->y0) * ($ratio - 1);
24733 if (isset($this->columnLinks[$s['col']][intval($s['x'])][intval($s['y'])])) {
24734 $ref = $this->columnLinks[$s['col']][intval($s['x'])][intval($s['y'])];
24735 $this->PageLinks[$this->page][$ref][1] -= ($yadj * Mpdf::SCALE); // y value
24736 $this->PageLinks[$this->page][$ref][3] *= $ratio; // height
24737 unset($this->columnLinks[$s['col']][intval($s['x'])][intval($s['y'])]);
24740 if (isset($this->columnForms[$s['col']][intval($s['x'])][intval($s['y'])])) {
24741 $ref = $this->columnForms[$s['col']][intval($s['x'])][intval($s['y'])];
24742 $this->form->forms[$ref]['x'] += ($xadj);
24743 $this->form->forms[$ref]['y'] += ($yadj);
24744 unset($this->columnForms[$s['col']][intval($s['x'])][intval($s['y'])]);
24746 /* -- ANNOTATIONS -- */
24747 if (isset($this->columnAnnots[$s['col']][intval($s['x'])][intval($s['y'])])) {
24748 $ref = $this->columnAnnots[$s['col']][intval($s['x'])][intval($s['y'])];
24749 $this->PageAnnots[$this->page][$ref]['y'] += ($yadj);
24750 unset($this->columnAnnots[$s['col']][intval($s['x'])][intval($s['y'])]);
24752 /* -- END ANNOTATIONS -- */
24757 /* -- BOOKMARKS -- */
24760 foreach ($this->col_BMoutlines as $v) {
24761 $this->BMoutlines[] = ['t' => $v['t'], 'l' => $v['l'], 'y' => $this->y0, 'p' => $v['p']];
24763 /* -- END BOOKMARKS -- */
24765 /* -- TOC -- */
24768 foreach ($this->col_toc as $v) {
24769 $this->tableOfContents->_toc[] = ['t' => $v['t'], 'l' => $v['l'], 'p' => $v['p'], 'link' => $v['link'], 'toc_id' => $v['toc_id']];
24770 $this->links[$v['link']][1] = $this->y0;
24772 /* -- END TOC -- */
24775 foreach ($this->columnbuffer as $key => $s) {
24780 if (isset($this->ColDetails[$s['col']]['max_bottom']) && $this->ColDetails[$s['col']]['max_bottom']) {
24781 $ratio = ($lowest_bottom_y - ($this->y0)) / ($this->ColDetails[$s['col']]['max_bottom'] - ($this->y0));
24786 if (($ratio > 1) && ($ratio <= $this->max_colH_correction)) {
24788 $this->pages[$this->page] .= $this->StartTransform(true) . "\n";
24789 $this->pages[$this->page] .= $this->transformScale(100, $ratio * 100, $x = '', $this->y0, true) . "\n";
24795 $this->pages[$this->page] .= $s['s'] . "\n";
24796 if (isset($s['rel_y']) && ($ratio > 1) && ($ratio <= $this->max_colH_correction)) {
24798 $this->pages[$this->page] .= $this->StopTransform(true) . "\n";
24804 $this->pages[$this->page] .= $this->StopTransform(true) . "\n";
24808 $this->y = $lowest_bottom_y;
24813 // If page has not ended but height adjustment was disabled by custom column-break - adjust y
24816 if (!$this->ColActive && (!$this->ColumnAdjust || $this->keepColumns)) {
24819 foreach ($this->columnbuffer as $key => $s) {
24825 || (preg_match('/\d+\.\d\d+ (\d+\.\d\d+) \d+\.\d\d+ [\-]{0,1}\d+\.\d\d+ re/', $t))
24833 if (isset($this->ColDetails[$s['col']]['max_bottom']) && $clb > $this->ColDetails[$s['col']]['max_bottom'] || (!isset($this->ColDetails[$s['col']]['max_bottom']) && $clb)) {
24834 $this->ColDetails[$s['col']]['max_bottom'] = $clb;
24844 foreach ($this->columnbuffer as $key => $s) {
24846 $this->pages[$this->page] .= $s['s'] . "\n";
24851 $this->y = $lowest_bottom_y;
24854 /* -- BOOKMARKS -- */
24856 foreach ($this->col_BMoutlines as $v) {
24857 $this->BMoutlines[] = ['t' => $v['t'], 'l' => $v['l'], 'y' => $v['y'], 'p' => $v['p']];
24859 /* -- END BOOKMARKS -- */
24861 /* -- TOC -- */
24863 foreach ($this->col_toc as $v) {
24864 $this->tableOfContents->_toc[] = ['t' => $v['t'], 'l' => $v['l'], 'p' => $v['p'], 'link' => $v['link'], 'toc_id' => $v['toc_id']];
24866 /* -- END TOC -- */
24869 foreach ($this->internallink as $key => $f) {
24871 if (isset($this->internallink[$key]['col'])) {
24872 unset($this->internallink[$key]['col']);
24875 if (isset($this->internallink[$key]['rel_y'])) {
24876 unset($this->internallink[$key]['rel_y']);
24880 $this->columnbuffer = [];
24881 $this->ColDetails = [];
24882 $this->columnLinks = [];
24883 $this->columnAnnots = [];
24884 $this->columnForms = [];
24886 $this->col_BMoutlines = [];
24887 $this->col_toc = [];
24888 $this->breakpoints = [];
24916 return str_replace($matches[0], $this->columnAdjustAdd($type, Mpdf::SCALE, $xadj, $yadj, $matches[1], $matches[2], $matches[3], $matches[4], $matches[5], $matches[6]), $subject);
24918 /* -- END COLUMNS -- */
24921 /* -- TABLES -- */
24924 if (count($this->cellBorderBuffer)) {
24926 sort($this->cellBorderBuffer);
24928 foreach ($this->cellBorderBuffer as $cbb) {
24961 $this->_tableRect($cba['x'], $cba['y'], $cba['w'], $cba['h'], $cba['bord'], $details, false, false);
24964 $this->cellBorderBuffer = [];
24972 if (!$this->table_rotate) {
24974 $this->pages[$this->page] .= $this->tablebuffer;
24976 foreach ($this->tbrot_Links as $p => $l) {
24978 $this->PageLinks[$p][] = $v;
24981 $this->tbrot_Links = [];
24983 /* -- ANNOTATIONS -- */
24984 foreach ($this->tbrot_Annots as $p => $l) {
24986 $this->PageAnnots[$p][] = $v;
24989 $this->tbrot_Annots = [];
24990 /* -- END ANNOTATIONS -- */
24992 /* -- BOOKMARKS -- */
24994 foreach ($this->tbrot_BMoutlines as $v) {
24995 $this->BMoutlines[] = ['t' => $v['t'], 'l' => $v['l'], 'y' => $v['y'], 'p' => $v['p']];
24997 $this->tbrot_BMoutlines = [];
24998 /* -- END BOOKMARKS -- */
25000 /* -- TOC -- */
25002 foreach ($this->tbrot_toc as $v) {
25003 $this->tableOfContents->_toc[] = ['t' => $v['t'], 'l' => $v['l'], 'p' => $v['p'], 'link' => $v['link'], 'toc_id' => $v['toc_id']];
25005 $this->tbrot_toc = [];
25006 /* -- END TOC -- */
25012 $lm = $this->lMargin + $this->blk[$this->blklvl]['outer_left_margin'] + $this->blk[$this->blklvl]['border_left']['w'] + $this->blk[$this->blklvl]['padding_left'];
25013 $pw = $this->blk[$this->blklvl]['inner_width'];
25016 $this->pages[$this->page] .= $this->StartTransform(true) . "\n";
25018 if ($this->table_rotate > 1) { // clockwise
25020 if ($this->tbrot_align == 'L') {
25021 $xadj = $this->tbrot_h; // align L (as is)
25022 } elseif ($this->tbrot_align == 'R') {
25023 $xadj = $lm - $this->tbrot_x0 + ($pw); // align R
25025 $xadj = $lm - $this->tbrot_x0 + (($pw + $this->tbrot_h) / 2); // align C
25030 } else { // anti-clockwise
25032 if ($this->tbrot_align == 'L') {
25034 } elseif ($this->tbrot_align == 'R') {
25035 $xadj = $lm - $this->tbrot_x0 + ($pw - $this->tbrot_h); // align R
25037 $xadj = $lm - $this->tbrot_x0 + (($pw - $this->tbrot_h) / 2); // align C
25040 $yadj = $this->tbrot_w;
25044 $this->pages[$this->page] .= $this->transformTranslate($xadj, $yadj, true) . "\n";
25045 $this->pages[$this->page] .= $this->transformRotate($this->table_rotate, $this->tbrot_x0, $this->tbrot_y0, true) . "\n";
25048 $this->pages[$this->page] .= $this->tablebuffer;
25050 foreach ($this->tbrot_Links as $p => $l) {
25056 $ax = ($v[0] / Mpdf::SCALE) - $this->tbrot_x0;
25057 $ay = (($this->hPt - $v[1]) / Mpdf::SCALE) - $this->tbrot_y0;
25059 if ($this->table_rotate > 1) { // clockwise
25060 $bx = $this->tbrot_x0 + $xadj - $ay - $h;
25061 $by = $this->tbrot_y0 + $yadj + $ax;
25063 $bx = $this->tbrot_x0 + $xadj + $ay;
25064 $by = $this->tbrot_y0 + $yadj - $ax - $w;
25068 $v[1] = ($this->h - $by) * Mpdf::SCALE;
25072 $this->PageLinks[$p][] = $v;
25076 $this->tbrot_Links = [];
25077 foreach ($this->internallink as $key => $f) {
25079 $f['Y'] = $this->tbrot_y0;
25080 $f['PAGE'] = $this->page;
25082 $this->internallink[$key] = $f;
25086 /* -- ANNOTATIONS -- */
25087 foreach ($this->tbrot_Annots as $p => $l) {
25089 $ax = abs($v['x']) - $this->tbrot_x0; // abs because -ve values are internally set and held for reference if annotMargin set
25090 $ay = $v['y'] - $this->tbrot_y0;
25092 if ($this->table_rotate > 1) { // clockwise
25093 $bx = $this->tbrot_x0 + $xadj - $ay;
25094 $by = $this->tbrot_y0 + $yadj + $ax;
25096 $bx = $this->tbrot_x0 + $xadj + $ay;
25097 $by = $this->tbrot_y0 + $yadj - $ax;
25101 $v['x'] = -$bx;
25107 $this->PageAnnots[$p][] = $v;
25111 $this->tbrot_Annots = [];
25112 /* -- END ANNOTATIONS -- */
25114 /* -- BOOKMARKS -- */
25116 foreach ($this->tbrot_BMoutlines as $v) {
25117 $v['y'] = $this->tbrot_y0;
25118 $this->BMoutlines[] = ['t' => $v['t'], 'l' => $v['l'], 'y' => $v['y'], 'p' => $this->page];
25120 /* -- END BOOKMARKS -- */
25122 /* -- TOC -- */
25123 // Adjust ToC - uses document page number
25124 foreach ($this->tbrot_toc as $v) {
25125 $this->tableOfContents->_toc[] = ['t' => $v['t'], 'l' => $v['l'], 'p' => $this->page, 'link' => $v['link'], 'toc_id' => $v['toc_id']];
25126 $this->links[$v['link']][1] = $this->tbrot_y0;
25128 /* -- END TOC -- */
25130 $this->tbrot_BMoutlines = [];
25131 $this->tbrot_toc = [];
25134 $this->pages[$this->page] .= $this->StopTransform(true) . "\n";
25136 $this->y = $this->tbrot_y0 + $this->tbrot_w;
25137 $this->x = $this->lMargin;
25139 $this->tablebuffer = '';
25143 * Keep-with-table This buffers contents of h1-6 to keep on page with table
25147 if (!$this->kwt_moved) {
25149 foreach ($this->kwt_buffer as $s) {
25150 $this->pages[$this->page] .= $s['s'] . "\n";
25153 foreach ($this->kwt_Links as $p => $l) {
25155 $this->PageLinks[$p][] = $v;
25159 $this->kwt_Links = [];
25161 /* -- ANNOTATIONS -- */
25162 foreach ($this->kwt_Annots as $p => $l) {
25164 $this->PageAnnots[$p][] = $v;
25167 $this->kwt_Annots = [];
25168 /* -- END ANNOTATIONS -- */
25170 /* -- INDEX -- */
25172 foreach ($this->kwt_Reference as $v) {
25176 for ($i = 0; $i < count($this->Reference); $i++) {
25177 if ($this->Reference[$i]['t'] == $v['t']) {
25179 if (!in_array($v['op'], $this->Reference[$i]['p'])) {
25180 $this->Reference[$i]['p'][] = $v['op'];
25186 $this->Reference[] = ['t' => $v['t'], 'p' => [$v['op']]];
25189 $this->kwt_Reference = [];
25190 /* -- END INDEX -- */
25192 /* -- BOOKMARKS -- */
25194 foreach ($this->kwt_BMoutlines as $v) {
25195 $this->BMoutlines[] = ['t' => $v['t'], 'l' => $v['l'], 'y' => $v['y'], 'p' => $v['p']];
25197 $this->kwt_BMoutlines = [];
25198 /* -- END BOOKMARKS -- */
25200 /* -- TOC -- */
25202 foreach ($this->kwt_toc as $v) {
25203 $this->tableOfContents->_toc[] = ['t' => $v['t'], 'l' => $v['l'], 'p' => $v['p'], 'link' => $v['link'], 'toc_id' => $v['toc_id']];
25205 $this->kwt_toc = [];
25206 /* -- END TOC -- */
25208 $this->pageoutput[$this->page] = []; // mPDF 6
25214 $this->pages[$this->page] .= $this->StartTransform(true) . "\n";
25215 $xadj = $this->lMargin - $this->kwt_x0;
25216 // $yadj = $this->y - $this->kwt_y0 ;
25217 $yadj = $this->tMargin - $this->kwt_y0;
25219 $this->pages[$this->page] .= $this->transformTranslate($xadj, $yadj, true) . "\n";
25222 foreach ($this->kwt_buffer as $s) {
25223 $this->pages[$this->page] .= $s['s'] . "\n";
25227 foreach ($this->kwt_Links as $p => $l) {
25229 $bx = $this->kwt_x0 + $xadj;
25230 $by = $this->kwt_y0 + $yadj;
25232 $v[1] = ($this->h - $by) * Mpdf::SCALE;
25233 $this->PageLinks[$p][] = $v;
25237 foreach ($this->internallink as $key => $f) {
25240 $f['PAGE'] = $this->page;
25242 $this->internallink[$key] = $f;
25246 /* -- ANNOTATIONS -- */
25247 foreach ($this->kwt_Annots as $p => $l) {
25249 $bx = $this->kwt_x0 + $xadj;
25250 $by = $this->kwt_y0 + $yadj;
25252 $v['x'] = -$bx;
25257 $this->PageAnnots[$p][] = $v;
25260 /* -- END ANNOTATIONS -- */
25262 /* -- BOOKMARKS -- */
25265 foreach ($this->kwt_BMoutlines as $v) {
25269 $this->BMoutlines[] = ['t' => $v['t'], 'l' => $v['l'], 'y' => $v['y'], 'p' => $this->page];
25271 /* -- END BOOKMARKS -- */
25273 /* -- INDEX -- */
25275 foreach ($this->kwt_Reference as $v) {
25280 for ($i = 0; $i < count($this->Reference); $i++) {
25281 if ($this->Reference[$i]['t'] == $v['t']) {
25283 if (!in_array($this->page, $this->Reference[$i]['p'])) {
25284 $this->Reference[$i]['p'][] = $this->page;
25290 $this->Reference[] = ['t' => $v['t'], 'p' => [$this->page]];
25293 /* -- END INDEX -- */
25295 /* -- TOC -- */
25298 foreach ($this->kwt_toc as $v) {
25299 $this->tableOfContents->_toc[] = ['t' => $v['t'], 'l' => $v['l'], 'p' => $this->page, 'link' => $v['link'], 'toc_id' => $v['toc_id']];
25300 $this->links[$v['link']][0] = $this->page;
25301 $this->links[$v['link']][1] += $yadj;
25303 /* -- END TOC -- */
25306 $this->kwt_Links = [];
25307 $this->kwt_Annots = [];
25309 $this->kwt_Reference = [];
25310 $this->kwt_BMoutlines = [];
25311 $this->kwt_toc = [];
25314 $this->pages[$this->page] .= $this->StopTransform(true) . "\n";
25316 $this->kwt_buffer = [];
25318 $this->y += $this->kwt_height;
25319 $this->pageoutput[$this->page] = []; // mPDF 6
25321 /* -- END TABLES -- */
25325 if (count($this->floatbuffer)) {
25326 $this->objectbuffer = $this->floatbuffer;
25327 $this->printobjectbuffer(false);
25328 $this->objectbuffer = [];
25329 $this->floatbuffer = [];
25330 $this->floatmargins = [];
25336 $this->Ellipse($x, $y, $r, $r, $style);
25349 $lx = 4 / 3 * (M_SQRT2 - 1) * $rx;
25350 $ly = 4 / 3 * (M_SQRT2 - 1) * $ry;
25352 $h = $this->h;
25354 $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));
25355 $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));
25356 $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));
25357 $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));
25360 /* -- DIRECTW -- */
25361 function AutosizeText($text, $w, $font, $style, $szfont = 72)
25366 $this->SetFont($font, $style, $szfont, false);
25368 $text = $this->purify_utf8_text($text);
25369 if ($this->text_input_as_HTML) {
25370 $text = $this->all_entities_to_utf8($text);
25372 if ($this->usingCoreFont) {
25373 $text = mb_convert_encoding($text, $this->mb_enc, 'UTF-8');
25377 if (preg_match("/([" . $this->pregRTLchars . "])/u", $text)) {
25378 $this->biDirectional = true;
25382 $save_OTLtags = $this->OTLtags;
25383 $this->OTLtags = [];
25385 if ($this->useKerning) {
25386 if ($this->CurrentFont['haskernGPOS']) {
25387 $this->OTLtags['Plus'] .= ' kern';
25393 /* -- OTL -- */
25394 // Use OTL OpenType Table Layout - GSUB & GPOS
25395 if (isset($this->CurrentFont['useOTL']) && $this->CurrentFont['useOTL']) {
25396 $text = $this->otl->applyOTL($text, $this->CurrentFont['useOTL']);
25397 $OTLdata = $this->otl->OTLdata;
25399 /* -- END OTL -- */
25401 $this->OTLtags = $save_OTLtags;
25403 $this->magic_reverse_dir($text, $this->directionality, $OTLdata);
25405 $width = $this->sizeConverter->convert($w);
25410 $this->SetFont($font, $style, $szfont, false);
25411 $sz = $this->GetStringWidth($text, true, $OTLdata, $textvar);
25414 $szfont --;
25420 $this->SetFont($font, $style, $szfont, true, true);
25421 $this->Cell($w, 0, $text, 0, 0, "C", 0, '', 0, 0, 0, 'M', 0, false, $OTLdata, $textvar);
25423 /* -- END DIRECTW -- */
25430 /* -- OTL -- */
25431 if ($this->usingCoreFont) {
25439 if ($this->biDirectional || $dir == 'rtl') {
25443 $pregRTLchars = $this->pregRTLchars;
25445 if (isset($this->CurrentFont['rtlPUAstr']) && $this->CurrentFont['rtlPUAstr']) {
25446 $pregRTLchars .= $this->CurrentFont['rtlPUAstr'];
25453 $unicode = $this->UTF8StringToArray($chunk, false);
25457 $this->getBasicOTLdata($chunkOTLdata, $unicode, $isStrong);
25460 $useGPOS = isset($this->CurrentFont['useOTL']) && ($this->CurrentFont['useOTL'] & 0x80);
25463 list($chunk, $rtl_content) = $this->otl->bidiSort($unicode, $chunk, $dir, $chunkOTLdata, $useGPOS);
25468 /* -- END OTL -- */
25472 /* -- OTL -- */
25476 if (empty($this->otl)) {
25477 $this->otl = new Otl($this, $this->fontCache);
25509 // PDF comes before PDI to close isolate-override (e.g. "LRILROPDFPDI")
25520 // LRI comes before LRO to open isolate-override (e.g. "LRILROPDFPDI")
25542 /* -- END OTL -- */
25547 require __DIR__ . '/../data/subs_win-1252.php';
25548 $this->substitute = [];
25550 $this->substitute[UtfString::code2utf($key)] = $val;
25557 if (count($this->substitute)) {
25558 $a = preg_split('/(<.*?>)/ms', $html, -1, PREG_SPLIT_DELIM_CAPTURE);
25562 $e = strtr($e, $this->substitute);
25573 if (preg_match("/^(.*?)([\x{20000}-\x{2FFFF}]+)(.*)/u", $writehtml_e, $m)) {
25574 if (isset($this->CurrentFont['sipext']) && $this->CurrentFont['sipext']) {
25575 $font = $this->CurrentFont['sipext'];
25576 if (!in_array($font, $this->available_unifonts)) {
25580 array_splice($writehtml_a, $writehtml_i + 1, 0, ['span style="font-family: ' . $font . '"', $m[2], '/span', $m[3]]);
25581 $this->subPos = $writehtml_i;
25590 * If core font is selected in document which is not onlyCoreFonts - substitute with non-core font
25595 if ($writehtml_i > 0 && strtolower(substr($writehtml_a[$writehtml_i - 1], 0, 8)) == 'textarea') {
25599 if (mb_convert_encoding(mb_convert_encoding($writehtml_e, $this->mb_enc, "UTF-8"), "UTF-8", $this->mb_enc) == $writehtml_e) {
25603 $cw = &$this->CurrentFont['cw'];
25604 $unicode = $this->UTF8StringToArray($writehtml_e, false);
25605 $start = -1;
25611 if (!$this->subArrMB) {
25615 $this->subArrMB['a'] = $aarr;
25616 $this->subArrMB['s'] = $sarr;
25617 $this->subArrMB['z'] = $zarr;
25622 if (($char > 127 || ($flag == 1 && $char == 32)) && $char != 173 && (!isset($this->subArrMB['a'][$char]) || ($flag == 1 && $char == 32)) && ($char < 1536 || ($char > 1791 && $char < 2304) || $char > 3455)) {
25629 $end = $c - 1;
25635 $end = count($unicode) - 1;
25638 if ($start == -1) {
25642 // Try in backup subs font
25643 if (!is_array($this->backupSubsFont)) {
25644 $this->backupSubsFont = ["$this->backupSubsFont"];
25647 foreach ($this->backupSubsFont as $bsfctr => $bsf) {
25649 if ($this->fonttrans[$bsf] == 'chelvetica' || $this->fonttrans[$bsf] == 'ctimes' || $this->fonttrans[$bsf] == 'ccourier') {
25653 $font = $bsf;
25657 if (isset($this->fonts[$font])) {
25658 $cw = &$this->fonts[$font]['cw'];
25659 } elseif ($this->fontCache->has($font . '.cw.dat')) {
25660 $cw = $this->fontCache->load($font . '.cw.dat');
25662 $prevFontFamily = $this->FontFamily;
25663 $prevFontStyle = $this->currentfontstyle;
25664 $prevFontSizePt = $this->FontSizePt;
25665 $this->SetFont($bsf, '', '', false);
25666 $this->SetFont($prevFontFamily, $prevFontStyle, $prevFontSizePt, false);
25675 if ($char == 173 || $this->_charDefined($cw, $char) || ($char > 1536 && $char < 1791) || ($char > 2304 && $char < 3455 )) {
25678 if ($l == 0 && $bsfctr == (count($this->backupSubsFont) - 1)) { // Not found even in last backup font
25680 $writehtml_e = mb_substr($writehtml_e, 0, $start + 1, 'UTF-8');
25682 $this->subPos = $writehtml_i + 1;
25692 $patt = mb_substr($writehtml_e, $start, $l, 'UTF-8');
25695 array_splice($writehtml_a, $writehtml_i + 1, 0, ['span style="font-family: ' . $font . '"', $m[2], '/span', $m[3]]);
25696 $this->subPos = $writehtml_i + 3;
25711 if ($writehtml_i > 0 && strtolower(substr($writehtml_a[$writehtml_i - 1], 0, 8)) == 'textarea') {
25715 $cw = &$this->CurrentFont['cw'];
25716 $unicode = $this->UTF8StringToArray($writehtml_e, false);
25717 $start = -1;
25725 if (($flag == 0 || $flag == 2) && (!$this->_charDefined($cw, $char) || ($flag == 2 && $char == 32)) && $this->checkSIP && $char > 131071) { // Unicode Plane 2 (SIP)
25727 if (in_array($this->FontFamily, $this->available_CJK_fonts)) {
25738 // elseif (($flag == 0 || $flag==1) && $char != 173 && !$this->_charDefined($cw,$char) && ($char<1423 || ($char>3583 && $char < 11263))) {
25740 } elseif (($flag == 0 || $flag == 1) && $char != 173 && (!$this->_charDefined($cw, $char) || ($flag == 1 && $char == 32)) && ($char < 1536 || ($char > 1791 && $char < 2304) || $char > 3455)) {
25751 $end = $c - 1;
25758 $end = count($unicode) - 1;
25761 if ($start == -1) {
25767 // Check if current CJK font has a ext-B related font
25768 if (isset($this->CurrentFont['sipext']) && $this->CurrentFont['sipext']) {
25769 $font = $this->CurrentFont['sipext'];
25773 if (isset($this->fonts[$font])) {
25774 $cw = &$this->fonts[$font]['cw'];
25775 } elseif ($this->fontCache->has($font . '.cw.dat')) {
25776 $cw = $this->fontCache->load($font . '.cw.dat');
25778 $prevFontFamily = $this->FontFamily;
25779 $prevFontStyle = $this->currentfontstyle;
25780 $prevFontSizePt = $this->FontSizePt;
25781 $this->SetFont($font, '', '', false);
25782 $this->SetFont($prevFontFamily, $prevFontStyle, $prevFontSizePt, false);
25791 if ($this->_charDefined($cw, $char) || $char > 131071) {
25802 array_splice($writehtml_a, $writehtml_i + 1, 0, ['span style="font-family: ' . $font . '"', $m[2], '/span', $m[3]]);
25803 $this->subPos = $writehtml_i + 3;
25809 // Check Backup SIP font (defined in Config\FontVariables)
25810 if (isset($this->backupSIPFont) && $this->backupSIPFont) {
25812 if ($this->currentfontfamily != $this->backupSIPFont) {
25813 $font = $this->backupSIPFont;
25822 if (isset($this->fonts[$font])) {
25823 $cw = &$this->fonts[$font]['cw'];
25824 } elseif ($this->fontCache->has($font . '.cw.dat')) {
25825 $cw = $this->fontCache->load($font . '.cw.dat');
25827 $prevFontFamily = $this->FontFamily;
25828 $prevFontStyle = $this->currentfontstyle;
25829 $prevFontSizePt = $this->FontSizePt;
25830 $this->SetFont($this->backupSIPFont, '', '', false);
25831 $this->SetFont($prevFontFamily, $prevFontStyle, $prevFontSizePt, false);
25840 if ($this->_charDefined($cw, $char) || $char > 131071) {
25851 array_splice($writehtml_a, $writehtml_i + 1, 0, ['span style="font-family: ' . $font . '"', $m[2], '/span', $m[3]]);
25852 $this->subPos = $writehtml_i + 3;
25862 if (!$this->PDFA && !$this->PDFX && !$this->biDirectional) { // mPDF 6
25864 if (!$this->subArrMB) {
25866 $this->subArrMB['a'] = $aarr;
25867 $this->subArrMB['s'] = $sarr;
25868 $this->subArrMB['z'] = $zarr;
25870 if (isset($this->subArrMB['a'][$u[0]])) {
25871 $font = 'tta';
25874 if (isset($this->subArrMB['a'][$char])) {
25875 $repl[] = $this->subArrMB['a'][$char];
25880 } elseif (isset($this->subArrMB['z'][$u[0]])) {
25881 $font = 'ttz';
25884 if (isset($this->subArrMB['z'][$char])) {
25885 $repl[] = $this->subArrMB['z'][$char];
25890 } elseif (isset($this->subArrMB['s'][$u[0]])) {
25891 $font = 'tts';
25894 if (isset($this->subArrMB['s'][$char])) {
25895 $repl[] = $this->subArrMB['s'][$char];
25905 array_splice($writehtml_a, $writehtml_i + 1, 0, [$font, implode('|', $repl), '/' . $font, $m[3]]); // e.g. <tts>
25906 $this->subPos = $writehtml_i + 3;
25913 // LASTLY TRY IN BACKUP SUBS FONT
25914 if (!is_array($this->backupSubsFont)) {
25915 $this->backupSubsFont = ["$this->backupSubsFont"];
25918 foreach ($this->backupSubsFont as $bsfctr => $bsf) {
25919 if ($this->currentfontfamily != $bsf) {
25920 $font = $bsf;
25928 if (isset($this->fonts[$font])) {
25929 $cw = &$this->fonts[$font]['cw'];
25930 } elseif ($this->fontCache->has($font . '.cw.dat')) {
25931 $cw = $this->fontCache->load($font . '.cw.dat');
25933 $prevFontFamily = $this->FontFamily;
25934 $prevFontStyle = $this->currentfontstyle;
25935 $prevFontSizePt = $this->FontSizePt;
25936 $this->SetFont($bsf, '', '', false);
25937 $this->SetFont($prevFontFamily, $prevFontStyle, $prevFontSizePt, false);
25938 if ($this->fontCache->has($font . '.cw.dat')) {
25939 $cw = $this->fontCache->load($font . '.cw.dat');
25949 if ($char == 173 || $this->_charDefined($cw, $char) || ($char > 1536 && $char < 1791) || ($char > 2304 && $char < 3455 )) { // Arabic and Indic
25952 if ($l == 0 && $bsfctr == (count($this->backupSubsFont) - 1)) { // Not found even in last backup font
25956 $this->subPos = $writehtml_i + 1;
25968 array_splice($writehtml_a, $writehtml_i + 1, 0, ['span style="font-family: ' . $font . '"', $m[2], '/span', $m[3]]);
25969 $this->subPos = $writehtml_i + 3;
25985 $this->entsearch[] = '&' . $key . ';';
25986 $this->entsubstitute[] = UtfString::code2utf($val);
25994 if (count($this->entsearch)) {
25995 $html = str_replace($this->entsearch, $this->entsubstitute, $html);
26002 * Edited v1.2 Pass by reference; option to continue if invalid UTF-8 chars
26006 if ($string === mb_convert_encoding(mb_convert_encoding($string, "UTF-32", "UTF-8"), "UTF-8", "UTF-32")) {
26010 if ($this->ignore_invalid_utf8) {
26011 $string = mb_convert_encoding(mb_convert_encoding($string, "UTF-32", "UTF-8"), "UTF-8", "UTF-32");
26021 * Checks string is valid UTF-8 encoded
26022 * converts html_entities > ASCII 127 to UTF-8
26023 * Only exception - leaves low ASCII entities e.g. &lt; &amp; etc.
26028 if (!$this->is_utf8($html)) {
26030 while (mb_convert_encoding(mb_convert_encoding($html, "UTF-32", "UTF-8"), "UTF-8", "UTF-32") != $html) {
26032 $a = @iconv('UTF-8', 'UTF-8', $html);
26035 throw new \Mpdf\MpdfException('Invalid input characters. Did you set $mpdf->in_charset properly?');
26045 $this->logger->error($err, ['context' => LogContext::UTF8]);
26049 throw new \Mpdf\MpdfException("HTML contains invalid UTF-8 character(s). See log for further details");
26054 // converts html_entities > ASCII 127 to UTF-8
26056 $html = $this->SubstituteHiEntities($html);
26058 // converts all &#nnn; or &#xHHH; to UTF-8 multibyte
26070 // Make sure UTF-8 string of characters
26071 if (!$this->is_utf8($txt)) {
26072 throw new \Mpdf\MpdfException("Text contains invalid UTF-8 character(s)");
26082 // converts txt_entities > ASCII 127 to UTF-8
26084 $txt = $this->SubstituteHiEntities($txt);
26086 // converts all &#nnn; or &#xHHH; to UTF-8 multibyte
26089 $txt = $this->lesser_entity_decode($txt);
26093 /* -- BARCODES -- */
26098 * Accepts 12 or 13 digits with or without - hyphens
26100 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)
26107 $code = preg_replace('/\-/', '', $code);
26109 $this->barcode = new Barcode();
26111 $arrcode = $this->barcode->getBarcodeArray($code, 'EAN13');
26113 $arrcode = $this->barcode->getBarcodeArray($code, $btype);
26127 if (stristr($codestr, '-')) {
26128 $codestr .= '-' . $arrcode['checkdigit'];
26143 $x = $this->x;
26147 $y = $this->y;
26151 $prevDrawColor = $this->DrawColor;
26152 $prevTextColor = $this->TextColor;
26153 $prevFillColor = $this->FillColor;
26155 $lw = $this->LineWidth;
26156 $this->SetLineWidth(0.01);
26158 $size /= $k; // in case resized in a table
26160 $xres = $arrcode['nom-X'] * $size;
26161 $llm = $arrcode['lightmL'] * $arrcode['nom-X'] * $size; // Left Light margin
26162 $rlm = $arrcode['lightmR'] * $arrcode['nom-X'] * $size; // Right Light margin
26164 $bcw = ($arrcode["maxw"] * $xres); // Barcode width = Should always be 31.35mm * $size
26167 $ow = $fbw + $paddingL + $paddingR; // Full overall width incl. user-defined padding
26169 $fbwi = $fbw - 2; // Full barcode width incl. light margins - 2mm - for isbn string
26171 $num_height = 3 * $size; // Height of numerals
26172 $fbh = $arrcode['nom-H'] * $size * $height; // Full barcode height incl. numerals
26173 $bch = $fbh - (1.5 * $size); // Barcode height of bars (3mm for numerals)
26176 $tisbnm = 1.5 * $size; // Top margin between isbn (if shown) & bars
26177 $codestr_fontsize = 2.1 * $size;
26181 $oh = $fbh + $paddingT + $paddingB; // Full overall height incl. user-defined padding
26188 $this->SetDColor($col);
26189 $this->SetTColor($col);
26191 $this->SetDColor($this->colorConverter->convert(0, $this->PDFAXwarnings));
26192 $this->SetTColor($this->colorConverter->convert(0, $this->PDFAXwarnings));
26196 $this->SetFColor($bgcol);
26198 $this->SetFColor($this->colorConverter->convert(255, $this->PDFAXwarnings));
26201 if (!$bgcol && !$col) { // fn. called directly - not via HTML
26209 $this->Rect($xpos, $ypos, $ow, $oh, $fillb);
26218 $this->SetFColor($col);
26220 $this->SetFColor($this->colorConverter->convert(0, $this->PDFAXwarnings));
26228 $this->Rect($xpos, $ypos, $bw, $bch, 'F');
26235 $prevFontFamily = $this->FontFamily;
26236 $prevFontStyle = $this->FontStyle;
26237 $prevFontSizePt = $this->FontSizePt;
26242 if ($this->onlyCoreFonts) {
26243 $this->SetFont('chelvetica');
26245 $this->SetFont('sans');
26249 $this->SetFColor($bgcol);
26251 $this->SetFColor($this->colorConverter->convert(255, $this->PDFAXwarnings));
26254 $this->x = $x + $paddingL + 1; // 1mm left margin (cf. $fbwi above)
26259 $this->SetFontSize($codestr_fontsize * 1.4 * Mpdf::SCALE, false); // don't write
26260 $sz = $this->GetStringWidth($codestr);
26263 $codestr_fontsize -= 0.1;
26269 $this->SetFont('', '', $codestr_fontsize * 1.4 * Mpdf::SCALE, true, true); // * 1.4 because font height is only 7/10 of given mm
26272 $xtra = $fbwi - $sz;
26273 $charspacing = $xtra / (strlen($codestr) - 1);
26275 $this->writer->write(sprintf('BT %.3F Tc ET', $charspacing * Mpdf::SCALE));
26279 $this->y = $y + $paddingT - ($codestr_fontsize ) - $tisbnm;
26280 $this->Cell($fbw, $codestr_fontsize, $codestr);
26283 $this->writer->write('BT 0 Tc ET');
26290 if ($this->onlyCoreFonts) {
26291 $this->SetFont('ccourier');
26294 $this->SetFont('ocrb');
26305 $textw = ($bcw * 0.5) - $outerp - $innerp;
26320 $textw = ($bcw * 0.5) - $outerp - $innerp;
26332 $textw = ($bcw * 0.5) - $outerp - $innerp;
26345 $textw = ($bcw * 0.5) - $outerp - $innerp;
26356 $this->SetFontSize(($outerfontsize / 3) * 3 * $fh * $size * Mpdf::SCALE); // 3mm numerals (FontSize is larger to account for space above/below characters)
26358 if (!$this->usingCoreFont) { // character width at 3mm
26359 $cw = $this->_getCharWidth($this->CurrentFont['cw'], 32) * 3 * $fh * $size / 1000;
26361 $cw = 600 * 3 * $fh * $size / 1000;
26365 $y_text = $y + $paddingT + $bch - ($num_height / 2);
26366 $y_text_outer = $y + $paddingT + $bch - ($num_height * ($outerfontsize / 3) / 2);
26368 $this->x = $x + $paddingL - ($cw * ($outerfontsize / 3) * 0.1); // 0.1 is correction as char does not fill full width;
26369 $this->y = $y_text_outer;
26370 $this->Cell($cw, $num_height, $charLO);
26373 $xtra = $textw - ($cw * $chars);
26374 $charspacing = $xtra / ($chars - 1);
26376 $this->writer->write(sprintf('BT %.3F Tc ET', $charspacing * Mpdf::SCALE));
26380 $this->SetFColor($bgcol);
26382 $this->SetFColor($this->colorConverter->convert(255, $this->PDFAXwarnings));
26385 $this->SetFontSize(3 * $fh * $size * Mpdf::SCALE); // 3mm numerals (FontSize is larger to account for space above/below characters)
26388 $this->x = $x + $paddingL + $llm + $outerp;
26389 $this->y = $y_text;
26390 $this->Cell($textw, $num_height, $charLI, 0, 0, '', 1);
26393 $this->x = $x + $paddingL + $llm + ($bcw * 0.5) + $innerp;
26394 $this->y = $y_text;
26395 $this->Cell($textw, $num_height, $charRI, 0, 0, '', 1);
26398 $this->writer->write('BT 0 Tc ET');
26402 $this->SetFontSize(($outerfontsize / 3) * 3 * $fh * $size * Mpdf::SCALE); // 3mm numerals (FontSize is larger to account for space above/below characters)
26404 $this->x = $x + $paddingL + $llm + $bcw + $rlm - ($cw * ($outerfontsize / 3) * 0.9); // 0.9 is correction as char does not fill full width
26405 $this->y = $y_text_outer;
26406 $this->Cell($cw * ($outerfontsize / 3), $num_height, $charRO, 0, 0, 'R');
26408 if ($supplement) { // EAN-2 or -5 Supplement
26410 $supparrcode = $this->barcode->getBarcodeArray($supplement_code, 'EAN' . $supplement);
26420 $llm = $fbw - (($arrcode['lightmR'] - $supparrcode['sepM']) * $arrcode['nom-X'] * $size); // Left Light margin
26421 $rlm = $arrcode['lightmR'] * $arrcode['nom-X'] * $size; // Right Light margin
26423 $bcw = ($supparrcode["maxw"] * $xres); // Barcode width = Should always be 31.35mm * $size
26426 $ow = $fbw + $paddingL + $paddingR; // Full overall width incl. user-defined padding
26427 $bch = $fbh - (1.5 * $size) - ($num_height + 0.5); // Barcode height of bars (3mm for numerals)
26433 $this->SetFColor($col);
26435 $this->SetFColor($this->colorConverter->convert(0, $this->PDFAXwarnings));
26443 $this->Rect($xpos, $ypos, $bw, $bch, 'F');
26451 $this->SetFColor($bgcol);
26453 $this->SetFColor($this->colorConverter->convert(255, $this->PDFAXwarnings));
26456 $this->SetFontSize(3 * $fh * $size * Mpdf::SCALE); // 3mm numerals (FontSize is larger to account for space above/below characters)
26457 $this->x = $x + $paddingL + $llm;
26458 $this->y = $y + $paddingT;
26459 $this->Cell($bcw, $num_height, $supplement_code, 0, 0, 'C');
26462 $this->SetFontSize(($outerfontsize / 3) * 3 * $fh * $size * Mpdf::SCALE); // 3mm numerals (FontSize is larger to account for space above/below characters)
26463 $this->x = $x + $paddingL + $llm + $bcw + $rlm - ($cw * 0.9); // 0.9 is correction as char does not fill full width
26464 $this->y = $y + $paddingT;
26465 $this->Cell($cw * ($outerfontsize / 3), $num_height, '>', 0, 0, 'R');
26469 $this->SetFont($prevFontFamily, $prevFontStyle, $prevFontSizePt);
26470 $this->DrawColor = $prevDrawColor;
26471 $this->TextColor = $prevTextColor;
26472 $this->FillColor = $prevFillColor;
26473 $this->SetLineWidth($lw);
26474 $this->SetY($y);
26480 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)
26486 $this->barcode = new Barcode();
26487 $arrcode = $this->barcode->getBarcodeArray($code, $btype, $print_ratio, $quiet_zone_left, $quiet_zone_right);
26490 $x = $this->x;
26494 $y = $this->y;
26497 $prevDrawColor = $this->DrawColor;
26498 $prevTextColor = $this->TextColor;
26499 $prevFillColor = $this->FillColor;
26500 $lw = $this->LineWidth;
26501 $this->SetLineWidth(0.01);
26502 $size /= $k; // in case resized in a table
26503 $xres = $arrcode['nom-X'] * $size;
26519 $bch = ($arrcode["nom-H"] * $size * $height);
26527 $this->SetDColor($col);
26528 $this->SetTColor($col);
26530 $this->SetDColor($this->colorConverter->convert(0, $this->PDFAXwarnings));
26531 $this->SetTColor($this->colorConverter->convert(0, $this->PDFAXwarnings));
26535 $this->SetFColor($bgcol);
26537 $this->SetFColor($this->colorConverter->convert(255, $this->PDFAXwarnings));
26542 $this->SetFColor($col);
26544 $this->SetFColor($this->colorConverter->convert(0, $this->PDFAXwarnings));
26553 $this->Rect($xpos, $ypos, $bw, ($v['h'] * $bch / $arrcode['maxh']), 'F');
26561 $this->Rect($x, $y, $fbw, ($arrcode['lightTB'] * $xres * $height), 'F');
26562 $this->Rect($x, $y + $tlm + $bch, $fbw, ($arrcode['lightTB'] * $xres * $height), 'F');
26566 $this->DrawColor = $prevDrawColor;
26567 $this->TextColor = $prevTextColor;
26568 $this->FillColor = $prevFillColor;
26569 $this->SetLineWidth($lw);
26570 $this->SetY($y);
26572 /* -- END BARCODES -- */
26579 $this->writer->write('q');
26588 $this->writer->write('Q');
26595 $x = $this->x;
26599 $y = $this->y;
26606 $y = ($this->h - $y) * Mpdf::SCALE;
26617 $tm[4] = $x * (1 - $s_x);
26618 $tm[5] = $y * (1 - $s_y);
26622 return($this->_transform($tm, true));
26624 $this->_transform($tm);
26637 $tm[5] = -$t_y * Mpdf::SCALE;
26641 return($this->_transform($tm, true));
26643 $this->_transform($tm);
26650 $x = $this->x;
26654 $y = $this->y;
26657 $angle = -$angle;
26658 $y = ($this->h - $y) * Mpdf::SCALE;
26665 $tm[2] = -$tm[1];
26667 $tm[4] = $x + $tm[1] * $y - $tm[0] * $x;
26668 $tm[5] = $y - $tm[0] * $y - $tm[1] * $x;
26672 return $this->_transform($tm, true);
26674 $this->_transform($tm);
26684 $x = $this->x;
26688 $y = $this->y;
26691 $angle_x = -$angle_x;
26692 $angle_y = -$angle_y;
26695 $y = ($this->h - $y) * Mpdf::SCALE;
26703 $tm[4] = -$tm[2] * $y;
26704 $tm[5] = -$tm[1] * $x;
26708 return $this->_transform($tm, true);
26710 $this->_transform($tm);
26719 $this->writer->write(sprintf('%.4F %.4F %.4F %.4F %.4F %.4F cm', $tm[0], $tm[1], $tm[2], $tm[3], $tm[4], $tm[5]));
26726 if ($this->onlyCoreFonts) {
26731 $a = preg_split('/<(.*?)>/ms', $html, -1, PREG_SPLIT_DELIM_CAPTURE);
26736 if ($i > 0 && strtolower(substr($a[$i - 1], 1, 8)) == 'textarea') {
26742 $e = $this->lesser_entity_decode($e);
26744 $earr = $this->UTF8StringToArray($e, false);
26763 // NEW (non-common) Script encountered in this chunk.
26777 // If scriptblock[x] = common & non-baseScript
26781 if ($scriptblocks[$sch] > 0 && $scriptblocks[$sch] != $this->baseScript && $scriptblocks[$sch + 1] == $this->baseScript) {
26782 $end = count($chardata[$sch]) - 1;
26786 $end--;
26800 // ZZZ99 Undo lesser_entity_decode as above - but only for <>&
26805 // Check Vietnamese if Latin script - even if Basescript
26806 if ($scriptblocks[$sch] == Ucdn::SCRIPT_LATIN && $this->autoVietnamese && preg_match("/([" . $this->scriptToLanguage->getLanguageDelimiters('viet') . "])/u", $s)) {
26808 } elseif ($scriptblocks[$sch] == Ucdn::SCRIPT_ARABIC && $this->autoArabic) { // Check Arabic for different languages if Arabic script - even if Basescript
26809 if (preg_match("/[" . $this->scriptToLanguage->getLanguageDelimiters('sindhi') . "]/u", $s)) {
26811 } elseif (preg_match("/[" . $this->scriptToLanguage->getLanguageDelimiters('urdu') . "]/u", $s)) {
26813 } elseif (preg_match("/[" . $this->scriptToLanguage->getLanguageDelimiters('pashto') . "]/u", $s)) {
26815 } elseif (preg_match("/[" . $this->scriptToLanguage->getLanguageDelimiters('persian') . "]/u", $s)) {
26817 } elseif ($this->baseScript != Ucdn::SCRIPT_ARABIC && $this->scriptToLanguage->getLanguageByScript($scriptblocks[$sch])) {
26818 $o .= '<span lang="' . $this->scriptToLanguage->getLanguageByScript($scriptblocks[$sch]) . '" class="lang_' . $this->scriptToLanguage->getLanguageByScript($scriptblocks[$sch]) . '">' . $s . '</span>';
26823 } elseif ($scriptblocks[$sch] > 0 && $scriptblocks[$sch] != $this->baseScript && $this->scriptToLanguage->getLanguageByScript($scriptblocks[$sch])) { // Identify Script block if not Basescript, and mark up as language
26825 $o .= '<span lang="' . $this->scriptToLanguage->getLanguageByScript($scriptblocks[$sch]) . '" class="lang_' . $this->scriptToLanguage->getLanguageByScript($scriptblocks[$sch]) . '">';
26846 /* -- COLUMNS -- */
26855 $b -= ($yadj * $k);
26862 $b -= ($yadj * $k);
26869 $b -= ($yadj * $k);
26876 $d -= ($yadj * $k);
26883 $b -= ($yadj * $k);
26890 $b -= ($yadj * $k);
26892 $d -= ($yadj * $k);
26894 $f -= ($yadj * $k);
26900 /* -- END COLUMNS -- */
26905 if (preg_match('/([\-]*[0-9\.]+)(deg|grad|rad)/i', $s, $m)) {
26918 $angle -= 360;
26921 while ($angle <= -360) {
26964 'The HTML code size is larger than pcre.backtrack_limit %d. You should use WriteHTML() with smaller string lengths.',
26980 $file = $this->cache->write('/_tempSVG' . uniqid(random_int(1, 100000), true) . '_' . $i . '.svg', $svgi[0][$i]);
26989 $html = preg_replace('/<!--mpdf/i', '', $html);
26990 $html = preg_replace('/mpdf-->/i', '', $html);
26993 $html = preg_replace('/<!--.*?-->/s', '', $html);
27025 $html_a = preg_split('/(\<\/?pre[^\>]*\>)/', $html, -1, 2);
27031 $c--;
27039 $c--;
27055 $html = preg_replace('/<([^!\/a-zA-Z_:])/i', '&lt;\\1', $html); // mPDF 5.7.3
27066 // Tags which are self-closing: 1) Replaceable and 2) Non-replaced items
27070 // Fix self-closing tags which don't close themselves
27073 // Fix self-closing tags that don't include a space between the tag name and the closing slash
27078 $temp[2][$iterator] = preg_replace('/<([^!\/a-zA-Z_:])/', '&lt;\\1', $temp[2][$iterator]); // mPDF 5.7.2 // mPDF 5.7.3
27087 $thereispre--;
27096 $thereistextarea--;
27110 $html = preg_replace('/<(h[1-6])([^>]*)(>(?:(?!h[1-6]).)*?<\/\\1>\s*<table)/si', '<\\1\\2 keep-with-table="1"\\3', $html); // *TABLES*
27114 $html = preg_replace("/(&#[x]{0,1}[0-9a-f]{1,5})</i", "\\1;<", $html);
27122 return (stripslashes($matches[1]) . str_repeat(' ', $this->tabSpaces - (mb_strlen(stripslashes($matches[1])) % $this->tabSpaces)));
27145 if (!$this->onlyCoreFonts && !$this->usingCoreFont) {
27147 $search[$k] = $this->writer->utf8ToUtf16BigEndian($search[$k], false);
27148 $search[$k] = $this->writer->escape($search[$k]);
27149 $replacement[$k] = $this->writer->utf8ToUtf16BigEndian($replacement[$k], false);
27150 $replacement[$k] = $this->writer->escape($replacement[$k]);
27154 $replacement[$k] = mb_convert_encoding($replacement[$k], $this->mb_enc, 'utf-8');
27155 $replacement[$k] = $this->writer->escape($replacement[$k]);
27174 if ($this->compress) {
27187 if ($this->encrypted) {
27188 $s = $this->protection->rc4($this->protection->objectKey($obj + 1), $s);
27191 if ($this->compress) {
27199 if ($this->compress) {
27203 if ($this->encrypted) {
27204 $s = $this->protection->rc4($this->protection->objectKey($obj + 1), $s);
27209 $changes[($xref[$obj + 1][0])] = ($newlen - $oldlen) + (strlen($newlen) - strlen($oldlen));
27211 if ($this->compress) {
27245 header('Content-Type: application/pdf');
27246 header('Content-Length: ' . strlen($pdf));
27247 header('Content-disposition: inline; filename=' . $file_out);
27277 header('Content-Type: application/force-download');
27279 header('Content-Type: application/octet-stream');
27282 header('Content-Length: ' . strlen($pdf));
27283 header('Content-disposition: attachment; filename=' . $file_out);
27295 $w = (($this->pgwidth + $spacing) / $npr) - $spacing;
27296 $oldlinewidth = $this->LineWidth;
27297 $this->SetLineWidth(0.02);
27298 $this->SetDColor($this->colorConverter->convert(0, $this->PDFAXwarnings));
27301 $x = $_x = $this->lMargin;
27302 $_y = $this->tMargin;
27304 if ($this->y == 0) {
27307 $y = $this->y;
27310 $pagecount = $this->setSourceFile($file);
27313 $tplidx = $this->importPage($n);
27314 $size = $this->useTemplate($tplidx, $x, $y, $w);
27315 $this->Rect($x, $y, $size['width'], $size['height']);
27316 $h = max($h, $size['height']);
27320 if (($y + $h + $spacing + $maxh) > $this->PageBreakTrigger && $n != $pagecount) {
27321 $this->AddPage();
27333 $this->SetLineWidth($oldlinewidth);
27338 if (!isset($this->importedPages[$tplidx])) {
27339 $this->pageTemplate = '';
27342 $this->pageTemplate = $tplidx;
27347 $this->docTemplate = $file;
27348 $this->docTemplateContinue = $continue;
27349 $this->docTemplateContinue2pages = $continue2pages;
27351 if ($this->docTemplateContinue2pages) { // Enable continue when continue2pages is set
27352 $this->docTemplateContinue = $this->docTemplateContinue2pages;
27356 /* -- END IMPORTS -- */
27361 $this->writer->object();
27362 $this->writer->write('<<');
27363 $this->writer->write('/S /JavaScript ');
27364 $this->writer->write('/JS ' . $this->writer->string($string));
27365 $this->writer->write('>>');
27366 $this->writer->write('endobj');
27371 $this->js = $script;
27388 return floatval(preg_replace('/[^0-9]/', '', $num));
27392 preg_replace('/[^0-9]/', '', substr($num, 0, $sep)) . '.' .
27393 preg_replace('/[^0-9]/', '', substr($num, $sep+1, strlen($num)))
27399 return $this->fontDescriptor;
27407 $this->writer->write($s);
27421 $html = str_replace($this->aliasNbPgGp, $NbPgGp, $html); // {nbpg}
27422 $html = str_replace($this->aliasNbPg, $NbPg, $html); // {nb}
27425 $html = str_replace(mb_convert_encoding('{PAGENO}', 'UTF-16BE', 'UTF-8'), mb_convert_encoding($PAGENO, 'UTF-16BE', 'UTF-8'), $html);
27426 $html = str_replace(mb_convert_encoding($this->aliasNbPgGp, 'UTF-16BE', 'UTF-8'), mb_convert_encoding($NbPgGp, 'UTF-16BE', 'UTF-8'), $html); // {nbpg}
27427 $html = str_replace(mb_convert_encoding($this->aliasNbPg, 'UTF-16BE', 'UTF-8'), mb_convert_encoding($NbPg, 'UTF-16BE', 'UTF-8'), $html); // {nb}