/vendor/blueliquiddesigns/mpdf/mpdf.php

  1. <?php 
  2.  
  3. // ****************************************************************************** 
  4. // Software: mPDF, Unicode-HTML Free PDF generator * 
  5. // Version: 6.1 based on * 
  6. // FPDF by Olivier PLATHEY * 
  7. // HTML2FPDF by Renato Coelho * 
  8. // Date: 2016-03-25 * 
  9. // Author: Ian Back <ianb@bpm1.com> * 
  10. // License: GPL * 
  11. // * 
  12. // Changes: See changelog.txt * 
  13. // ****************************************************************************** 
  14.  
  15. define('mPDF_VERSION', '6.1'); 
  16.  
  17. //Scale factor 
  18. define('_MPDFK', (72 / 25.4)); 
  19.  
  20. // Specify which font metrics to use: 
  21. // 'winTypo' uses sTypoAscender etc from the OS/2 table and is the one usually recommended - BUT 
  22. // 'win' use WinAscent etc from OS/2 and inpractice seems to be used more commonly in Windows environment 
  23. // 'mac' uses Ascender etc from hhea table, and is used on Mac/OSX environment 
  24. if (!defined('_FONT_DESCRIPTOR')) { 
  25. define("_FONT_DESCRIPTOR", 'win'); // Values: '' [BLANK] or 'win', 'mac', 'winTypo' 
  26.  
  27. /** -- HTML-CSS -- */ 
  28. define('_BORDER_ALL', 15); 
  29. define('_BORDER_TOP', 8); 
  30. define('_BORDER_RIGHT', 4); 
  31. define('_BORDER_BOTTOM', 2); 
  32. define('_BORDER_LEFT', 1); 
  33. /** -- END HTML-CSS -- */ 
  34.  
  35. // mPDF 6.0 
  36. // Used for $textvars - user settings via CSS 
  37. define('FD_UNDERLINE', 1); // font-decoration 
  38. define('FD_LINETHROUGH', 2); 
  39. define('FD_OVERLINE', 4); 
  40. define('FA_SUPERSCRIPT', 8); // font-(vertical)-align 
  41. define('FA_SUBSCRIPT', 16); 
  42. define('FT_UPPERCASE', 32); // font-transform 
  43. define('FT_LOWERCASE', 64); 
  44. define('FT_CAPITALIZE', 128); 
  45. define('FC_KERNING', 256); // font-(other)-controls 
  46. define('FC_SMALLCAPS', 512); 
  47.  
  48.  
  49. if (!defined('_MPDF_PATH')) { 
  50. define('_MPDF_PATH', dirname(preg_replace('/\\\\/', '/', __FILE__)) . '/'); 
  51.  
  52. if (!defined('_MPDF_URI')) { 
  53. define('_MPDF_URI', _MPDF_PATH); 
  54.  
  55. require_once _MPDF_PATH . 'includes/functions.php'; 
  56. require_once _MPDF_PATH . 'config_lang2fonts.php'; 
  57.  
  58. require_once _MPDF_PATH . 'classes/ucdn.php'; // mPDF 6.0 
  59.  
  60. /** -- OTL -- */ 
  61. require_once _MPDF_PATH . 'classes/indic.php'; // mPDF 6.0 
  62. require_once _MPDF_PATH . 'classes/myanmar.php'; // mPDF 6.0 
  63. require_once _MPDF_PATH . 'classes/sea.php'; // mPDF 6.0 
  64. /** -- END OTL -- */ 
  65.  
  66. require_once _MPDF_PATH . 'Tag.php'; 
  67. require_once _MPDF_PATH . 'WordPress.php'; 
  68. require_once _MPDF_PATH . 'MpdfException.php'; 
  69.  
  70. if (!defined('_JPGRAPH_PATH')) { 
  71. define("_JPGRAPH_PATH", apply_filters('mpdf_jgraph_path', _MPDF_PATH . 'jpgraph/')); 
  72.  
  73. if (!defined('_MPDF_TEMP_PATH')) { 
  74. define("_MPDF_TEMP_PATH", apply_filters('mpdf_tmp_path', _MPDF_PATH.'tmp/')); 
  75.  
  76. if (!defined('_MPDF_TTFONTPATH')) { 
  77. define('_MPDF_TTFONTPATH', apply_filters('mpdf_font_path', _MPDF_PATH.'ttfonts/')); 
  78.  
  79. if (!defined('_MPDF_TTFONTDATAPATH')) { 
  80. define('_MPDF_TTFONTDATAPATH', apply_filters('mpdf_fontdata_path', _MPDF_PATH.'ttfontdata/')); 
  81.  
  82. $errorlevel = error_reporting(); 
  83. $errorlevel = error_reporting($errorlevel & ~E_NOTICE); 
  84.  
  85. if (!function_exists('mb_strlen')) { 
  86. throw new MpdfException('mPDF requires mb_string functions. Ensure that mb_string extension is loaded.'); 
  87.  
  88. if (!defined('PHP_VERSION_ID')) { 
  89. $version = explode('.', PHP_VERSION); 
  90. define('PHP_VERSION_ID', ($version[0] * 10000 + $version[1] * 100 + $version[2])); 
  91.  
  92. class mPDF 
  93.  
  94. /////////////////////////////// 
  95. // EXTERNAL (PUBLIC) VARIABLES 
  96. // Define these in config.php 
  97. /////////////////////////////// 
  98. var $useFixedNormalLineHeight; // mPDF 6 
  99. var $useFixedTextBaseline; // mPDF 6 
  100. var $adjustFontDescLineheight; // mPDF 6 
  101. var $interpolateImages; // mPDF 6 
  102. var $defaultPagebreakType; // mPDF 6 pagebreaktype 
  103. var $indexUseSubentries; // mPDF 6 
  104.  
  105. var $autoScriptToLang; // mPDF 6 
  106. var $baseScript; // mPDF 6 
  107. var $autoVietnamese; // mPDF 6 
  108. var $autoArabic; // mPDF 6 
  109.  
  110. var $CJKforceend; 
  111. var $h2bookmarks; 
  112. var $h2toc; 
  113. var $decimal_align; 
  114. var $margBuffer; 
  115. var $splitTableBorderWidth; 
  116.  
  117. var $bookmarkStyles; 
  118. var $useActiveForms; 
  119.  
  120. var $repackageTTF; 
  121. var $allowCJKorphans; 
  122. var $allowCJKoverflow; 
  123.  
  124. var $useKerning; 
  125. var $restrictColorSpace; 
  126. var $bleedMargin; 
  127. var $crossMarkMargin; 
  128. var $cropMarkMargin; 
  129. var $cropMarkLength; 
  130. var $nonPrintMargin; 
  131.  
  132. var $PDFX; 
  133. var $PDFXauto; 
  134.  
  135. var $PDFA; 
  136. var $PDFAauto; 
  137. var $ICCProfile; 
  138.  
  139. var $printers_info; 
  140. var $iterationCounter; 
  141. var $smCapsScale; 
  142. var $smCapsStretch; 
  143.  
  144. var $backupSubsFont; 
  145. var $backupSIPFont; 
  146. var $debugfonts; 
  147. var $useAdobeCJK; 
  148. var $percentSubset; 
  149. var $maxTTFFilesize; 
  150. var $BMPonly; 
  151.  
  152. var $tableMinSizePriority; 
  153.  
  154. var $dpi; 
  155. var $watermarkImgAlphaBlend; 
  156. var $watermarkImgBehind; 
  157. var $justifyB4br; 
  158. var $packTableData; 
  159. var $pgsIns; 
  160. var $simpleTables; 
  161. var $enableImports; 
  162.  
  163. var $debug; 
  164.  
  165. var $showStats; 
  166. var $setAutoTopMargin; 
  167. var $setAutoBottomMargin; 
  168. var $autoMarginPadding; 
  169. var $collapseBlockMargins; 
  170. var $falseBoldWeight; 
  171. var $normalLineheight; 
  172. var $incrementFPR1; 
  173. var $incrementFPR2; 
  174. var $incrementFPR3; 
  175. var $incrementFPR4; 
  176.  
  177. var $SHYlang; 
  178. var $SHYleftmin; 
  179. var $SHYrightmin; 
  180. var $SHYcharmin; 
  181. var $SHYcharmax; 
  182. var $SHYlanguages; 
  183.  
  184. // PageNumber Conditional Text 
  185. var $pagenumPrefix; 
  186. var $pagenumSuffix; 
  187.  
  188. var $nbpgPrefix; 
  189. var $nbpgSuffix; 
  190. var $showImageErrors; 
  191. var $allow_output_buffering; 
  192. var $autoPadding; 
  193. var $useGraphs; 
  194. var $tabSpaces; 
  195. var $autoLangToFont; 
  196. var $watermarkTextAlpha; 
  197. var $watermarkImageAlpha; 
  198. var $watermark_size; 
  199. var $watermark_pos; 
  200. var $annotSize; 
  201. var $annotMargin; 
  202. var $annotOpacity; 
  203. var $title2annots; 
  204. var $keepColumns; 
  205. var $keep_table_proportions; 
  206. var $ignore_table_widths; 
  207. var $ignore_table_percents; 
  208. var $list_number_suffix; 
  209.  
  210. var $list_auto_mode; // mPDF 6 
  211. var $list_indent_first_level; // mPDF 6 
  212. var $list_indent_default; // mPDF 6 
  213. var $list_marker_offset; // mPDF 6 
  214.  
  215. var $useSubstitutions; 
  216. var $CSSselectMedia; 
  217.  
  218. var $forcePortraitHeaders; 
  219. var $forcePortraitMargins; 
  220. var $displayDefaultOrientation; 
  221. var $ignore_invalid_utf8; 
  222. var $allowedCSStags; 
  223. var $onlyCoreFonts; 
  224. var $allow_charset_conversion; 
  225.  
  226. var $jSWord; 
  227. var $jSmaxChar; 
  228. var $jSmaxCharLast; 
  229. var $jSmaxWordLast; 
  230.  
  231. var $max_colH_correction; 
  232.  
  233. var $table_error_report; 
  234. var $table_error_report_param; 
  235. var $biDirectional; 
  236. var $text_input_as_HTML; 
  237. var $anchor2Bookmark; 
  238. var $shrink_tables_to_fit; 
  239.  
  240. var $allow_html_optional_endtags; 
  241.  
  242. var $img_dpi; 
  243.  
  244. var $defaultheaderfontsize; 
  245. var $defaultheaderfontstyle; 
  246. var $defaultheaderline; 
  247. var $defaultfooterfontsize; 
  248. var $defaultfooterfontstyle; 
  249. var $defaultfooterline; 
  250. var $header_line_spacing; 
  251. var $footer_line_spacing; 
  252.  
  253. var $pregCJKchars; 
  254. var $pregRTLchars; 
  255. var $pregCURSchars; // mPDF 6 
  256.  
  257. var $mirrorMargins; 
  258. var $watermarkText; 
  259. var $watermarkImage; 
  260. var $showWatermarkText; 
  261. var $showWatermarkImage; 
  262.  
  263. var $fontsizes; 
  264.  
  265. var $defaultPageNumStyle; // mPDF 6 
  266.  
  267. ////////////////////// 
  268. // CLASS OBJECTS 
  269. ////////////////////// 
  270. var $otl; // mPDF 5.7.1 
  271. var $cssmgr; 
  272. var $grad; 
  273. var $bmp; 
  274. var $wmf; 
  275. var $tocontents; 
  276. var $mpdfform; 
  277. var $directw; 
  278.  
  279. ////////////////////// 
  280. // INTERNAL VARIABLES 
  281. ////////////////////// 
  282. var $script2lang; 
  283. var $viet; 
  284. var $pashto; 
  285. var $urdu; 
  286. var $persian; 
  287. var $sindhi; 
  288. var $extrapagebreak; // mPDF 6 pagebreaktype 
  289.  
  290. var $uniqstr; // mPDF 5.7.2 
  291. var $hasOC; 
  292.  
  293. var $textvar; // mPDF 5.7.1 
  294. var $fontLanguageOverride; // mPDF 5.7.1 
  295. var $OTLtags; // mPDF 5.7.1 
  296. var $OTLdata; // mPDF 5.7.1 
  297.  
  298. var $writingToC; 
  299. var $layers; 
  300. var $current_layer; 
  301. var $open_layer_pane; 
  302. var $decimal_offset; 
  303. var $inMeter; 
  304.  
  305. var $CJKleading; 
  306. var $CJKfollowing; 
  307. var $CJKoverflow; 
  308.  
  309. var $textshadow; 
  310.  
  311. var $colsums; 
  312. var $spanborder; 
  313. var $spanborddet; 
  314.  
  315. var $visibility; 
  316.  
  317. var $useRC128encryption; 
  318. var $uniqid; 
  319.  
  320. var $kerning; 
  321. var $fixedlSpacing; 
  322. var $minwSpacing; 
  323. var $lSpacingCSS; 
  324. var $wSpacingCSS; 
  325.  
  326. var $spotColorIDs; 
  327. var $SVGcolors; 
  328. var $spotColors; 
  329. var $defTextColor; 
  330. var $defDrawColor; 
  331. var $defFillColor; 
  332.  
  333. var $tableBackgrounds; 
  334. var $inlineDisplayOff; 
  335. var $kt_y00; 
  336. var $kt_p00; 
  337. var $upperCase; 
  338. var $checkSIP; 
  339. var $checkSMP; 
  340. var $checkCJK; 
  341.  
  342. var $watermarkImgAlpha; 
  343. var $PDFAXwarnings; 
  344. var $MetadataRoot; 
  345. var $OutputIntentRoot; 
  346. var $InfoRoot; 
  347. var $current_filename; 
  348. var $parsers; 
  349. var $current_parser; 
  350. var $_obj_stack; 
  351. var $_don_obj_stack; 
  352. var $_current_obj_id; 
  353. var $tpls; 
  354. var $tpl; 
  355. var $tplprefix; 
  356. var $_res; 
  357.  
  358. var $pdf_version; 
  359. var $noImageFile; 
  360. var $lastblockbottommargin; 
  361. var $baselineC; 
  362.  
  363. // mPDF 5.7.3 inline text-decoration parameters 
  364. var $baselineSup; 
  365. var $baselineSub; 
  366. var $baselineS; 
  367. var $subPos; 
  368. var $subArrMB; 
  369. var $ReqFontStyle; 
  370. var $tableClipPath; 
  371.  
  372. var $fullImageHeight; 
  373.  
  374. var $inFixedPosBlock; // Internal flag for position:fixed block 
  375. var $fixedPosBlock; // Buffer string for position:fixed block 
  376. var $fixedPosBlockDepth; 
  377. var $fixedPosBlockBBox; 
  378. var $fixedPosBlockSave; 
  379. var $maxPosL; 
  380. var $maxPosR; 
  381. var $loaded; 
  382.  
  383. var $extraFontSubsets; 
  384.  
  385. var $docTemplateStart; // Internal flag for page (page no. -1) that docTemplate starts on 
  386.  
  387. var $time0; 
  388.  
  389. // Classes 
  390. var $indic; 
  391. var $barcode; 
  392.  
  393. var $SHYpatterns; 
  394. var $loadedSHYpatterns; 
  395. var $loadedSHYdictionary; 
  396. var $SHYdictionary; 
  397. var $SHYdictionaryWords; 
  398.  
  399. var $spanbgcolorarray; 
  400. var $default_font; 
  401. var $headerbuffer; 
  402. var $lastblocklevelchange; 
  403. var $nestedtablejustfinished; 
  404. var $linebreakjustfinished; 
  405. var $cell_border_dominance_L; 
  406. var $cell_border_dominance_R; 
  407. var $cell_border_dominance_T; 
  408. var $cell_border_dominance_B; 
  409. var $table_keep_together; 
  410. var $plainCell_properties; 
  411. var $shrin_k1; 
  412. var $outerfilled; 
  413.  
  414. var $blockContext; 
  415. var $floatDivs; 
  416.  
  417. var $patterns; 
  418. var $pageBackgrounds; 
  419.  
  420. var $bodyBackgroundGradient; 
  421. var $bodyBackgroundImage; 
  422. var $bodyBackgroundColor; 
  423.  
  424. var $writingHTMLheader; // internal flag - used both for writing HTMLHeaders/Footers and FixedPos block 
  425. var $writingHTMLfooter; 
  426.  
  427. var $angle; 
  428.  
  429. var $gradients; 
  430.  
  431. var $kwt_Reference; 
  432. var $kwt_BMoutlines; 
  433. var $kwt_toc; 
  434.  
  435. var $tbrot_BMoutlines; 
  436. var $tbrot_toc; 
  437.  
  438. var $col_BMoutlines; 
  439. var $col_toc; 
  440.  
  441. var $currentGraphId; 
  442. var $graphs; 
  443.  
  444. var $floatbuffer; 
  445. var $floatmargins; 
  446.  
  447. var $bullet; 
  448. var $bulletarray; 
  449.  
  450. var $currentLang; 
  451. var $default_lang; 
  452.  
  453. var $default_available_fonts; 
  454.  
  455. var $pageTemplate; 
  456. var $docTemplate; 
  457. var $docTemplateContinue; 
  458.  
  459. var $arabGlyphs; 
  460. var $arabHex; 
  461. var $persianGlyphs; 
  462. var $persianHex; 
  463. var $arabVowels; 
  464. var $arabPrevLink; 
  465. var $arabNextLink; 
  466.  
  467. var $formobjects; // array of Form Objects for WMF 
  468. var $InlineProperties; 
  469. var $InlineAnnots; 
  470. var $InlineBDF; // mPDF 6 Bidirectional formatting 
  471. var $InlineBDFctr; // mPDF 6 
  472.  
  473. var $ktAnnots; 
  474. var $tbrot_Annots; 
  475. var $kwt_Annots; 
  476. var $columnAnnots; 
  477. var $columnForms; 
  478.  
  479. var $PageAnnots; 
  480.  
  481. var $pageDim; // Keep track of page wxh for orientation changes - set in _beginpage, used in _putannots 
  482.  
  483. var $breakpoints; 
  484.  
  485. var $tableLevel; 
  486. var $tbctr; 
  487. var $innermostTableLevel; 
  488. var $saveTableCounter; 
  489. var $cellBorderBuffer; 
  490.  
  491. var $saveHTMLFooter_height; 
  492. var $saveHTMLFooterE_height; 
  493.  
  494. var $firstPageBoxHeader; 
  495. var $firstPageBoxHeaderEven; 
  496. var $firstPageBoxFooter; 
  497. var $firstPageBoxFooterEven; 
  498.  
  499. var $page_box; 
  500.  
  501. var $show_marks; // crop or cross marks 
  502. var $basepathIsLocal; 
  503.  
  504. var $use_kwt; 
  505. var $kwt; 
  506. var $kwt_height; 
  507. var $kwt_y0; 
  508. var $kwt_x0; 
  509. var $kwt_buffer; 
  510. var $kwt_Links; 
  511. var $kwt_moved; 
  512. var $kwt_saved; 
  513.  
  514. var $PageNumSubstitutions; 
  515.  
  516. var $table_borders_separate; 
  517. var $base_table_properties; 
  518. var $borderstyles; 
  519.  
  520. var $blockjustfinished; 
  521.  
  522. var $orig_bMargin; 
  523. var $orig_tMargin; 
  524. var $orig_lMargin; 
  525. var $orig_rMargin; 
  526. var $orig_hMargin; 
  527. var $orig_fMargin; 
  528.  
  529. var $pageHTMLheaders; 
  530. var $pageHTMLfooters; 
  531.  
  532. var $saveHTMLHeader; 
  533. var $saveHTMLFooter; 
  534.  
  535. var $HTMLheaderPageLinks; 
  536. var $HTMLheaderPageAnnots; 
  537. var $HTMLheaderPageForms; 
  538.  
  539. // See config_fonts.php for these next 5 values 
  540. var $available_unifonts; 
  541. var $sans_fonts; 
  542. var $serif_fonts; 
  543. var $mono_fonts; 
  544. var $defaultSubsFont; 
  545.  
  546. // List of ALL available CJK fonts (incl. styles) (Adobe add-ons) hw removed 
  547. var $available_CJK_fonts; 
  548.  
  549. var $HTMLHeader; 
  550. var $HTMLFooter; 
  551. var $HTMLHeaderE; 
  552. var $HTMLFooterE; 
  553. var $bufferoutput; 
  554.  
  555. // CJK fonts 
  556. var $Big5_widths; 
  557. var $GB_widths; 
  558. var $SJIS_widths; 
  559. var $UHC_widths; 
  560.  
  561. // SetProtection 
  562. var $encrypted; // whether document is protected 
  563. var $Uvalue; // U entry in pdf document 
  564. var $Ovalue; // O entry in pdf document 
  565. var $Pvalue; // P entry in pdf document 
  566.  
  567. var $enc_obj_id; //encryption object id 
  568. var $last_rc4_key; //last RC4 key encrypted (cached for optimisation) 
  569. var $last_rc4_key_c; //last RC4 computed key 
  570.  
  571. var $encryption_key; 
  572.  
  573. var $padding; //used for encryption 
  574.  
  575. // Bookmark 
  576. var $BMoutlines; 
  577. var $OutlineRoot; 
  578.  
  579. // INDEX 
  580. var $ColActive; 
  581. var $Reference; 
  582. var $CurrCol; 
  583. var $NbCol; 
  584. var $y0; //Top ordinate of columns 
  585.  
  586. var $ColL; 
  587. var $ColWidth; 
  588. var $ColGap; 
  589.  
  590. // COLUMNS 
  591. var $ColR; 
  592. var $ChangeColumn; 
  593. var $columnbuffer; 
  594. var $ColDetails; 
  595. var $columnLinks; 
  596. var $colvAlign; 
  597.  
  598. // Substitutions 
  599. var $substitute; // Array of substitution strings e.g. <ttz>112</ttz> 
  600. var $entsearch; // Array of HTML entities (>ASCII 127) to substitute 
  601. var $entsubstitute; // Array of substitution decimal unicode for the Hi entities 
  602.  
  603. // Default values if no style sheet offered (cf. http://www.w3.org/TR/CSS21/sample.html) 
  604. var $defaultCSS; 
  605. var $lastoptionaltag; // Save current block item which HTML specifies optionsl endtag 
  606. var $pageoutput; 
  607. var $charset_in; 
  608. var $blk; 
  609. var $blklvl; 
  610. var $ColumnAdjust; 
  611.  
  612. var $ws; // Word spacing 
  613.  
  614. var $HREF; 
  615. var $pgwidth; 
  616. var $fontlist; 
  617. var $oldx; 
  618. var $oldy; 
  619. var $B; 
  620. var $I; 
  621.  
  622. var $tdbegin; 
  623. var $table; 
  624. var $cell; 
  625. var $col; 
  626. var $row; 
  627.  
  628. var $divbegin; 
  629. var $divwidth; 
  630. var $divheight; 
  631. var $spanbgcolor; 
  632.  
  633. // mPDF 6 Used for table cell (block-type) properties 
  634. var $cellTextAlign; 
  635. var $cellLineHeight; 
  636. var $cellLineStackingStrategy; 
  637. var $cellLineStackingShift; 
  638.  
  639. // mPDF 6 Lists 
  640. var $listcounter; 
  641. var $listlvl; 
  642. var $listtype; 
  643. var $listitem; 
  644.  
  645. var $pjustfinished; 
  646. var $ignorefollowingspaces; 
  647. var $SMALL; 
  648. var $BIG; 
  649. var $dash_on; 
  650. var $dotted_on; 
  651.  
  652. var $textbuffer; 
  653. var $currentfontstyle; 
  654. var $currentfontfamily; 
  655. var $currentfontsize; 
  656. var $colorarray; 
  657. var $bgcolorarray; 
  658. var $internallink; 
  659. var $enabledtags; 
  660.  
  661. var $lineheight; 
  662. var $basepath; 
  663. var $textparam; 
  664.  
  665. var $specialcontent; 
  666. var $selectoption; 
  667. var $objectbuffer; 
  668.  
  669. // Table Rotation 
  670. var $table_rotate; 
  671. var $tbrot_maxw; 
  672. var $tbrot_maxh; 
  673. var $tablebuffer; 
  674. var $tbrot_align; 
  675. var $tbrot_Links; 
  676.  
  677. var $keep_block_together; // Keep a Block from page-break-inside: avoid 
  678.  
  679. var $tbrot_y0; 
  680. var $tbrot_x0; 
  681. var $tbrot_w; 
  682. var $tbrot_h; 
  683.  
  684. var $mb_enc; 
  685. var $directionality; 
  686.  
  687. var $extgstates; // Used for alpha channel - Transparency (Watermark) 
  688. var $mgl; 
  689. var $mgt; 
  690. var $mgr; 
  691. var $mgb; 
  692.  
  693. var $tts; 
  694. var $ttz; 
  695. var $tta; 
  696.  
  697. // Best to alter the below variables using default stylesheet above 
  698. var $page_break_after_avoid; 
  699. var $margin_bottom_collapse; 
  700. var $default_font_size; // in pts 
  701. var $original_default_font_size; // used to save default sizes when using table default 
  702. var $original_default_font; 
  703. var $watermark_font; 
  704. var $defaultAlign; 
  705.  
  706. // TABLE 
  707. var $defaultTableAlign; 
  708. var $tablethead; 
  709. var $thead_font_weight; 
  710. var $thead_font_style; 
  711. var $thead_font_smCaps; 
  712. var $thead_valign_default; 
  713. var $thead_textalign_default; 
  714. var $tabletfoot; 
  715. var $tfoot_font_weight; 
  716. var $tfoot_font_style; 
  717. var $tfoot_font_smCaps; 
  718. var $tfoot_valign_default; 
  719. var $tfoot_textalign_default; 
  720.  
  721. var $trow_text_rotate; 
  722.  
  723. var $cellPaddingL; 
  724. var $cellPaddingR; 
  725. var $cellPaddingT; 
  726. var $cellPaddingB; 
  727. var $table_border_attr_set; 
  728. var $table_border_css_set; 
  729.  
  730. var $shrin_k; // factor with which to shrink tables - used internally - do not change 
  731. var $shrink_this_table_to_fit; // 0 or false to disable; value (if set) gives maximum factor to reduce fontsize 
  732. var $MarginCorrection; // corrects for OddEven Margins 
  733. var $margin_footer; 
  734. var $margin_header; 
  735.  
  736. var $tabletheadjustfinished; 
  737. var $usingCoreFont; 
  738. var $charspacing; 
  739.  
  740. //Private properties FROM FPDF 
  741. var $DisplayPreferences; 
  742. var $flowingBlockAttr; 
  743. var $page; //current page number 
  744. var $n; //current object number 
  745. var $offsets; //array of object offsets 
  746. var $buffer; //buffer holding in-memory PDF 
  747. var $pages; //array containing pages 
  748. var $state; //current document state 
  749. var $compress; //compression flag 
  750. var $DefOrientation; //default orientation 
  751. var $CurOrientation; //current orientation 
  752. var $OrientationChanges; //array indicating orientation changes 
  753. var $k; //scale factor (number of points in user unit) 
  754. var $fwPt; 
  755. var $fhPt; //dimensions of page format in points 
  756. var $fw; 
  757. var $fh; //dimensions of page format in user unit 
  758. var $wPt; 
  759. var $hPt; //current dimensions of page in points 
  760. var $w; 
  761. var $h; //current dimensions of page in user unit 
  762. var $lMargin; //left margin 
  763. var $tMargin; //top margin 
  764. var $rMargin; //right margin 
  765. var $bMargin; //page break margin 
  766. var $cMarginL; //cell margin Left 
  767. var $cMarginR; //cell margin Right 
  768. var $cMarginT; //cell margin Left 
  769. var $cMarginB; //cell margin Right 
  770. var $DeflMargin; //Default left margin 
  771. var $DefrMargin; //Default right margin 
  772. var $x; 
  773. var $y; //current position in user unit for cell positioning 
  774. var $lasth; //height of last cell printed 
  775. var $LineWidth; //line width in user unit 
  776. var $CoreFonts; //array of standard font names 
  777. var $fonts; //array of used fonts 
  778. var $FontFiles; //array of font files 
  779. var $images; //array of used images 
  780. var $PageLinks; //array of links in pages 
  781. var $links; //array of internal links 
  782. var $FontFamily; //current font family 
  783. var $FontStyle; //current font style 
  784. var $CurrentFont; //current font info 
  785. var $FontSizePt; //current font size in points 
  786. var $FontSize; //current font size in user unit 
  787. var $DrawColor; //commands for drawing color 
  788. var $FillColor; //commands for filling color 
  789. var $TextColor; //commands for text color 
  790. var $ColorFlag; //indicates whether fill and text colors are different 
  791. var $autoPageBreak; //automatic page breaking 
  792. var $PageBreakTrigger; //threshold used to trigger page breaks 
  793. var $InFooter; //flag set when processing footer 
  794.  
  795. var $InHTMLFooter; 
  796. var $processingFooter; //flag set when processing footer - added for columns 
  797. var $processingHeader; //flag set when processing header - added for columns 
  798. var $ZoomMode; //zoom display mode 
  799. var $LayoutMode; //layout display mode 
  800. var $title; //title 
  801. var $subject; //subject 
  802. var $author; //author 
  803. var $keywords; //keywords 
  804. var $creator; //creator 
  805.  
  806. var $aliasNbPg; //alias for total number of pages 
  807. var $aliasNbPgGp; //alias for total number of pages in page group 
  808.  
  809. //var $aliasNbPgHex; // mPDF 6 deleted 
  810. //var $aliasNbPgGpHex; // mPDF 6 deleted 
  811.  
  812. var $ispre; 
  813. var $outerblocktags; 
  814. var $innerblocktags; 
  815.  
  816. // ********************************** 
  817. // ********************************** 
  818. // ********************************** 
  819. // ********************************** 
  820. // ********************************** 
  821. // ********************************** 
  822. // ********************************** 
  823. // ********************************** 
  824. // ********************************** 
  825.  
  826. private $tag; 
  827.  
  828. public function __construct($mode = '', $format = 'A4', $default_font_size = 0, $default_font = '', $mgl = 15, $mgr = 15, $mgt = 16, $mgb = 16, $mgh = 9, $mgf = 9, $orientation = 'P') 
  829. /** -- BACKGROUNDS -- */ 
  830. if (!class_exists('grad', false)) { 
  831. include(_MPDF_PATH . 'classes/grad.php'); 
  832. if (empty($this->grad)) { 
  833. $this->grad = new grad($this); 
  834. /** -- END BACKGROUNDS -- */ 
  835. /** -- FORMS -- */ 
  836. if (!class_exists('mpdfform', false)) { 
  837. include(_MPDF_PATH . 'classes/mpdfform.php'); 
  838. if (empty($this->mpdfform)) { 
  839. $this->mpdfform = new mpdfform($this); 
  840. /** -- END FORMS -- */ 
  841.  
  842. $this->time0 = microtime(true); 
  843. //Some checks 
  844. $this->_dochecks(); 
  845.  
  846. $this->writingToC = false; 
  847. $this->layers = array(); 
  848. $this->current_layer = 0; 
  849. $this->open_layer_pane = false; 
  850.  
  851. $this->visibility = 'visible'; 
  852.  
  853. //Initialization of properties 
  854. $this->spotColors = array(); 
  855. $this->spotColorIDs = array(); 
  856. $this->tableBackgrounds = array(); 
  857. $this->uniqstr = '20110230'; // mPDF 5.7.2 
  858. $this->kt_y00 = ''; 
  859. $this->kt_p00 = ''; 
  860. $this->iterationCounter = false; 
  861. $this->BMPonly = array(); 
  862. $this->page = 0; 
  863. $this->n = 2; 
  864. $this->buffer = ''; 
  865. $this->objectbuffer = array(); 
  866. $this->pages = array(); 
  867. $this->OrientationChanges = array(); 
  868. $this->state = 0; 
  869. $this->fonts = array(); 
  870. $this->FontFiles = array(); 
  871. $this->images = array(); 
  872. $this->links = array(); 
  873. $this->InFooter = false; 
  874. $this->processingFooter = false; 
  875. $this->processingHeader = false; 
  876. $this->lasth = 0; 
  877. $this->FontFamily = ''; 
  878. $this->FontStyle = ''; 
  879. $this->FontSizePt = 9; 
  880. $this->U = false; 
  881. // Small Caps 
  882. $this->upperCase = array(); 
  883. $this->smCapsScale = 1; 
  884. $this->smCapsStretch = 100; 
  885. $this->margBuffer = 0; 
  886. $this->inMeter = false; 
  887. $this->decimal_offset = 0; 
  888.  
  889. $this->defTextColor = $this->TextColor = $this->SetTColor($this->ConvertColor(0), true); 
  890. $this->defDrawColor = $this->DrawColor = $this->SetDColor($this->ConvertColor(0), true); 
  891. $this->defFillColor = $this->FillColor = $this->SetFColor($this->ConvertColor(255), true); 
  892.  
  893. //SVG color names array 
  894. //http://www.w3schools.com/css/css_colornames.asp 
  895. $this->SVGcolors = array('antiquewhite' => '#FAEBD7', 'aqua' => '#00FFFF', 'aquamarine' => '#7FFFD4', 'beige' => '#F5F5DC', 'black' => '#000000',  
  896. 'blue' => '#0000FF', 'brown' => '#A52A2A', 'cadetblue' => '#5F9EA0', 'chocolate' => '#D2691E', 'cornflowerblue' => '#6495ED', 'crimson' => '#DC143C',  
  897. 'darkblue' => '#00008B', 'darkgoldenrod' => '#B8860B', 'darkgreen' => '#006400', 'darkmagenta' => '#8B008B', 'darkorange' => '#FF8C00',  
  898. 'darkred' => '#8B0000', 'darkseagreen' => '#8FBC8F', 'darkslategray' => '#2F4F4F', 'darkviolet' => '#9400D3', 'deepskyblue' => '#00BFFF',  
  899. 'dodgerblue' => '#1E90FF', 'firebrick' => '#B22222', 'forestgreen' => '#228B22', 'fuchsia' => '#FF00FF', 'gainsboro' => '#DCDCDC', 'gold' => '#FFD700',  
  900. 'gray' => '#808080', 'green' => '#008000', 'greenyellow' => '#ADFF2F', 'hotpink' => '#FF69B4', 'indigo' => '#4B0082', 'khaki' => '#F0E68C',  
  901. 'lavenderblush' => '#FFF0F5', 'lemonchiffon' => '#FFFACD', 'lightcoral' => '#F08080', 'lightgoldenrodyellow' => '#FAFAD2', 'lightgreen' => '#90EE90',  
  902. 'lightsalmon' => '#FFA07A', 'lightskyblue' => '#87CEFA', 'lightslategray' => '#778899', 'lightyellow' => '#FFFFE0', 'lime' => '#00FF00', 'limegreen' => '#32CD32',  
  903. 'magenta' => '#FF00FF', 'maroon' => '#800000', 'mediumaquamarine' => '#66CDAA', 'mediumorchid' => '#BA55D3', 'mediumseagreen' => '#3CB371',  
  904. 'mediumspringgreen' => '#00FA9A', 'mediumvioletred' => '#C71585', 'midnightblue' => '#191970', 'mintcream' => '#F5FFFA', 'moccasin' => '#FFE4B5', 'navy' => '#000080',  
  905. 'olive' => '#808000', 'orange' => '#FFA500', 'orchid' => '#DA70D6', 'palegreen' => '#98FB98',  
  906. 'palevioletred' => '#D87093', 'peachpuff' => '#FFDAB9', 'pink' => '#FFC0CB', 'powderblue' => '#B0E0E6', 'purple' => '#800080',  
  907. 'red' => '#FF0000', 'royalblue' => '#4169E1', 'salmon' => '#FA8072', 'seagreen' => '#2E8B57', 'sienna' => '#A0522D', 'silver' => '#C0C0C0', 'skyblue' => '#87CEEB',  
  908. 'slategray' => '#708090', 'springgreen' => '#00FF7F', 'steelblue' => '#4682B4', 'tan' => '#D2B48C', 'teal' => '#008080', 'thistle' => '#D8BFD8', 'turquoise' => '#40E0D0',  
  909. 'violetred' => '#D02090', 'white' => '#FFFFFF', 'yellow' => '#FFFF00',  
  910. 'aliceblue' => '#f0f8ff', 'azure' => '#f0ffff', 'bisque' => '#ffe4c4', 'blanchedalmond' => '#ffebcd', 'blueviolet' => '#8a2be2', 'burlywood' => '#deb887',  
  911. 'chartreuse' => '#7fff00', 'coral' => '#ff7f50', 'cornsilk' => '#fff8dc', 'cyan' => '#00ffff', 'darkcyan' => '#008b8b', 'darkgray' => '#a9a9a9',  
  912. 'darkgrey' => '#a9a9a9', 'darkkhaki' => '#bdb76b', 'darkolivegreen' => '#556b2f', 'darkorchid' => '#9932cc', 'darksalmon' => '#e9967a',  
  913. 'darkslateblue' => '#483d8b', 'darkslategrey' => '#2f4f4f', 'darkturquoise' => '#00ced1', 'deeppink' => '#ff1493', 'dimgray' => '#696969',  
  914. 'dimgrey' => '#696969', 'floralwhite' => '#fffaf0', 'ghostwhite' => '#f8f8ff', 'goldenrod' => '#daa520', 'grey' => '#808080', 'honeydew' => '#f0fff0',  
  915. 'indianred' => '#cd5c5c', 'ivory' => '#fffff0', 'lavender' => '#e6e6fa', 'lawngreen' => '#7cfc00', 'lightblue' => '#add8e6', 'lightcyan' => '#e0ffff',  
  916. 'lightgray' => '#d3d3d3', 'lightgrey' => '#d3d3d3', 'lightpink' => '#ffb6c1', 'lightseagreen' => '#20b2aa', 'lightslategrey' => '#778899',  
  917. 'lightsteelblue' => '#b0c4de', 'linen' => '#faf0e6', 'mediumblue' => '#0000cd', 'mediumpurple' => '#9370db', 'mediumslateblue' => '#7b68ee',  
  918. 'mediumturquoise' => '#48d1cc', 'mistyrose' => '#ffe4e1', 'navajowhite' => '#ffdead', 'oldlace' => '#fdf5e6', 'olivedrab' => '#6b8e23', 'orangered' => '#ff4500',  
  919. 'palegoldenrod' => '#eee8aa', 'paleturquoise' => '#afeeee', 'papayawhip' => '#ffefd5', 'peru' => '#cd853f', 'plum' => '#dda0dd', 'rosybrown' => '#bc8f8f',  
  920. 'saddlebrown' => '#8b4513', 'sandybrown' => '#f4a460', 'seashell' => '#fff5ee', 'slateblue' => '#6a5acd', 'slategrey' => '#708090', 'snow' => '#fffafa',  
  921. 'tomato' => '#ff6347', 'violet' => '#ee82ee', 'wheat' => '#f5deb3', 'whitesmoke' => '#f5f5f5', 'yellowgreen' => '#9acd32'); 
  922.  
  923. // Uppercase alternatives (for Small Caps) 
  924. if (empty($this->upperCase)) { 
  925. @include(_MPDF_PATH . 'includes/upperCase.php'); 
  926. $this->extrapagebreak = true; // mPDF 6 pagebreaktype 
  927.  
  928. $this->ColorFlag = false; 
  929. $this->extgstates = array(); 
  930.  
  931. $this->mb_enc = 'windows-1252'; 
  932. $this->directionality = 'ltr'; 
  933. $this->defaultAlign = 'L'; 
  934. $this->defaultTableAlign = 'L'; 
  935.  
  936. $this->fixedPosBlockSave = array(); 
  937. $this->extraFontSubsets = 0; 
  938.  
  939. $this->SHYpatterns = array(); 
  940. $this->loadedSHYdictionary = false; 
  941. $this->SHYdictionary = array(); 
  942. $this->SHYdictionaryWords = array(); 
  943. $this->blockContext = 1; 
  944. $this->floatDivs = array(); 
  945. $this->DisplayPreferences = ''; 
  946.  
  947. $this->patterns = array(); // Tiling patterns used for backgrounds 
  948. $this->pageBackgrounds = array(); 
  949. $this->writingHTMLheader = false; // internal flag - used both for writing HTMLHeaders/Footers and FixedPos block 
  950. $this->writingHTMLfooter = false; // internal flag - used both for writing HTMLHeaders/Footers and FixedPos block 
  951. $this->gradients = array(); 
  952.  
  953. $this->kwt_Reference = array(); 
  954. $this->kwt_BMoutlines = array(); 
  955. $this->kwt_toc = array(); 
  956.  
  957. $this->tbrot_BMoutlines = array(); 
  958. $this->tbrot_toc = array(); 
  959.  
  960. $this->col_BMoutlines = array(); 
  961. $this->col_toc = array(); 
  962. $this->graphs = array(); 
  963.  
  964. $this->pgsIns = array(); 
  965. $this->PDFAXwarnings = array(); 
  966. $this->inlineDisplayOff = false; 
  967. $this->lSpacingCSS = ''; 
  968. $this->wSpacingCSS = ''; 
  969. $this->fixedlSpacing = false; 
  970. $this->minwSpacing = 0; 
  971.  
  972.  
  973. $this->baselineC = 0.35; // Baseline for text 
  974. // mPDF 5.7.3 inline text-decoration parameters 
  975. $this->baselineSup = 0.5; // Sets default change in baseline for <sup> text as factor of preceeding fontsize 
  976. // 0.35 has been recommended; 0.5 matches applications like MS Word 
  977. $this->baselineSub = -0.2; // Sets default change in baseline for <sub> text as factor of preceeding fontsize 
  978. $this->baselineS = 0.3; // Sets default height for <strike> text as factor of fontsize 
  979. $this->baselineO = 1.1; // Sets default height for overline text as factor of fontsize 
  980.  
  981. $this->noImageFile = str_replace("\\", "/", dirname(__FILE__)) . '/includes/no_image.jpg'; 
  982. $this->subPos = 0; 
  983. $this->normalLineheight = 1.3; // This should be overridden in config.php - but it is so important a default value is put here 
  984. // These are intended as configuration variables, and should be set in config.php - which will override these values; 
  985. // set here as failsafe as will cause an error if not defined 
  986. $this->incrementFPR1 = 10; 
  987. $this->incrementFPR2 = 10; 
  988. $this->incrementFPR3 = 10; 
  989. $this->incrementFPR4 = 10; 
  990.  
  991. $this->fullImageHeight = false; 
  992. $this->floatbuffer = array(); 
  993. $this->floatmargins = array(); 
  994. $this->formobjects = array(); // array of Form Objects for WMF 
  995. $this->InlineProperties = array(); 
  996. $this->InlineAnnots = array(); 
  997. $this->InlineBDF = array(); // mPDF 6 
  998. $this->InlineBDFctr = 0; // mPDF 6 
  999. $this->tbrot_Annots = array(); 
  1000. $this->kwt_Annots = array(); 
  1001. $this->columnAnnots = array(); 
  1002. $this->pageDim = array(); 
  1003. $this->breakpoints = array(); // used in columnbuffer 
  1004. $this->tableLevel = 0; 
  1005. $this->tbctr = array(); // counter for nested tables at each level 
  1006. $this->page_box = array(); 
  1007. $this->show_marks = ''; // crop or cross marks 
  1008. $this->kwt = false; 
  1009. $this->kwt_height = 0; 
  1010. $this->kwt_y0 = 0; 
  1011. $this->kwt_x0 = 0; 
  1012. $this->kwt_buffer = array(); 
  1013. $this->kwt_Links = array(); 
  1014. $this->kwt_moved = false; 
  1015. $this->kwt_saved = false; 
  1016. $this->PageNumSubstitutions = array(); 
  1017. $this->base_table_properties = array(); 
  1018. $this->borderstyles = array('inset', 'groove', 'outset', 'ridge', 'dotted', 'dashed', 'solid', 'double'); 
  1019. $this->tbrot_align = 'C'; 
  1020.  
  1021. $this->pageHTMLheaders = array(); 
  1022. $this->pageHTMLfooters = array(); 
  1023. $this->HTMLheaderPageLinks = array(); 
  1024. $this->HTMLheaderPageAnnots = array(); 
  1025.  
  1026. $this->HTMLheaderPageForms = array(); 
  1027. $this->columnForms = array(); 
  1028. $this->tbrotForms = array(); 
  1029. $this->useRC128encryption = false; 
  1030. $this->uniqid = ''; 
  1031.  
  1032. $this->pageoutput = array(); 
  1033.  
  1034. $this->bufferoutput = false; 
  1035. $this->encrypted = false; //whether document is protected 
  1036. $this->BMoutlines = array(); 
  1037. $this->ColActive = 0; //Flag indicating that columns are on (the index is being processed) 
  1038. $this->Reference = array(); //Array containing the references 
  1039. $this->CurrCol = 0; //Current column number 
  1040. $this->ColL = array(0); // Array of Left pos of columns - absolute - needs Margin correction for Odd-Even 
  1041. $this->ColR = array(0); // Array of Right pos of columns - absolute pos - needs Margin correction for Odd-Even 
  1042. $this->ChangeColumn = 0; 
  1043. $this->columnbuffer = array(); 
  1044. $this->ColDetails = array(); // Keeps track of some column details 
  1045. $this->columnLinks = array(); // Cross references PageLinks 
  1046. $this->substitute = array(); // Array of substitution strings e.g. <ttz>112</ttz> 
  1047. $this->entsearch = array(); // Array of HTML entities (>ASCII 127) to substitute 
  1048. $this->entsubstitute = array(); // Array of substitution decimal unicode for the Hi entities 
  1049. $this->lastoptionaltag = ''; 
  1050. $this->charset_in = ''; 
  1051. $this->blk = array(); 
  1052. $this->blklvl = 0; 
  1053. $this->tts = false; 
  1054. $this->ttz = false; 
  1055. $this->tta = false; 
  1056. $this->ispre = false; 
  1057.  
  1058. $this->checkSIP = false; 
  1059. $this->checkSMP = false; 
  1060. $this->checkCJK = false; 
  1061.  
  1062. $this->page_break_after_avoid = false; 
  1063. $this->margin_bottom_collapse = false; 
  1064. $this->tablethead = 0; 
  1065. $this->tabletfoot = 0; 
  1066. $this->table_border_attr_set = 0; 
  1067. $this->table_border_css_set = 0; 
  1068. $this->shrin_k = 1.0; 
  1069. $this->shrink_this_table_to_fit = 0; 
  1070. $this->MarginCorrection = 0; 
  1071.  
  1072. $this->tabletheadjustfinished = false; 
  1073. $this->usingCoreFont = false; 
  1074. $this->charspacing = 0; 
  1075.  
  1076. $this->autoPageBreak = true; 
  1077.  
  1078. require(_MPDF_PATH . 'config.php'); // config data 
  1079.  
  1080. $this->_setPageSize($format, $orientation); 
  1081. $this->DefOrientation = $orientation; 
  1082.  
  1083. $this->margin_header = $mgh; 
  1084. $this->margin_footer = $mgf; 
  1085.  
  1086. $bmargin = $mgb; 
  1087.  
  1088. $this->DeflMargin = $mgl; 
  1089. $this->DefrMargin = $mgr; 
  1090.  
  1091. $this->orig_tMargin = $mgt; 
  1092. $this->orig_bMargin = $bmargin; 
  1093. $this->orig_lMargin = $this->DeflMargin; 
  1094. $this->orig_rMargin = $this->DefrMargin; 
  1095. $this->orig_hMargin = $this->margin_header; 
  1096. $this->orig_fMargin = $this->margin_footer; 
  1097.  
  1098. if ($this->setAutoTopMargin == 'pad') { 
  1099. $mgt += $this->margin_header; 
  1100. if ($this->setAutoBottomMargin == 'pad') { 
  1101. $mgb += $this->margin_footer; 
  1102. $this->SetMargins($this->DeflMargin, $this->DefrMargin, $mgt); // sets l r t margin 
  1103. //Automatic page break 
  1104. $this->SetAutoPageBreak($this->autoPageBreak, $bmargin); // sets $this->bMargin & PageBreakTrigger 
  1105.  
  1106. $this->pgwidth = $this->w - $this->lMargin - $this->rMargin; 
  1107.  
  1108. //Interior cell margin (1 mm) ? not used 
  1109. $this->cMarginL = 1; 
  1110. $this->cMarginR = 1; 
  1111. //Line width (0.2 mm) 
  1112. $this->LineWidth = .567 / _MPDFK; 
  1113.  
  1114. //To make the function Footer() work - replaces {nb} with page number 
  1115. $this->AliasNbPages(); 
  1116. $this->AliasNbPageGroups(); 
  1117.  
  1118. //$this->aliasNbPgHex = '{nbHEXmarker}'; // mPDF 6 deleted 
  1119. //$this->aliasNbPgGpHex = '{nbpgHEXmarker}'; // mPDF 6 deleted 
  1120. //Enable all tags as default 
  1121. $this->DisableTags(); 
  1122. //Full width display mode 
  1123. $this->SetDisplayMode(100); // fullwidth? 'fullpage' 
  1124. //Compression 
  1125. $this->SetCompression(true); 
  1126. //Set default display preferences 
  1127. $this->SetDisplayPreferences(''); 
  1128.  
  1129. // Font data 
  1130. require(_MPDF_PATH . 'config_fonts.php'); 
  1131.  
  1132. // check for a custom config file that can add/overwrite the default config 
  1133. if (defined('_MPDF_SYSTEM_TTFONTS_CONFIG') && file_exists(_MPDF_SYSTEM_TTFONTS_CONFIG)) { 
  1134. require(_MPDF_SYSTEM_TTFONTS_CONFIG); 
  1135.  
  1136. // Available fonts 
  1137. $this->available_unifonts = array(); 
  1138. foreach ($this->fontdata AS $f => $fs) { 
  1139. if (isset($fs['R']) && $fs['R']) { 
  1140. $this->available_unifonts[] = $f; 
  1141. if (isset($fs['B']) && $fs['B']) { 
  1142. $this->available_unifonts[] = $f . 'B'; 
  1143. if (isset($fs['I']) && $fs['I']) { 
  1144. $this->available_unifonts[] = $f . 'I'; 
  1145. if (isset($fs['BI']) && $fs['BI']) { 
  1146. $this->available_unifonts[] = $f . 'BI'; 
  1147.  
  1148. $this->default_available_fonts = $this->available_unifonts; 
  1149.  
  1150. $optcore = false; 
  1151. $onlyCoreFonts = false; 
  1152. if (preg_match('/([\-+])aCJK/i', $mode, $m)) { 
  1153. $mode = preg_replace('/([\-+])aCJK/i', '', $mode); // mPDF 6 
  1154. if ($m[1] == '+') { 
  1155. $this->useAdobeCJK = true; 
  1156. } else { 
  1157. $this->useAdobeCJK = false; 
  1158.  
  1159. if (strlen($mode) == 1) { 
  1160. if ($mode == 's') { 
  1161. $this->percentSubset = 100; 
  1162. $mode = ''; 
  1163. } elseif ($mode == 'c') { 
  1164. $onlyCoreFonts = true; 
  1165. $mode = ''; 
  1166. } elseif (substr($mode, -2) == '-s') { 
  1167. $this->percentSubset = 100; 
  1168. $mode = substr($mode, 0, strlen($mode) - 2); 
  1169. } elseif (substr($mode, -2) == '-c') { 
  1170. $onlyCoreFonts = true; 
  1171. $mode = substr($mode, 0, strlen($mode) - 2); 
  1172. } elseif (substr($mode, -2) == '-x') { 
  1173. $optcore = true; 
  1174. $mode = substr($mode, 0, strlen($mode) - 2); 
  1175.  
  1176. // Autodetect if mode is a language_country string (en-GB or en_GB or en) 
  1177. if ($mode && $mode != 'UTF-8') { // mPDF 6 
  1178. list ($coreSuitable, $mpdf_pdf_unifont) = GetLangOpts($mode, $this->useAdobeCJK, $this->fontdata); 
  1179. if ($coreSuitable && $optcore) { 
  1180. $onlyCoreFonts = true; 
  1181. if ($mpdf_pdf_unifont) { // mPDF 6 
  1182. $default_font = $mpdf_pdf_unifont; 
  1183. $this->currentLang = $mode; 
  1184. $this->default_lang = $mode; 
  1185.  
  1186. $this->onlyCoreFonts = $onlyCoreFonts; 
  1187.  
  1188. if ($this->onlyCoreFonts) { 
  1189. $this->setMBencoding('windows-1252'); // sets $this->mb_enc 
  1190. } else { 
  1191. $this->setMBencoding('UTF-8'); // sets $this->mb_enc 
  1192. @mb_regex_encoding('UTF-8'); // required only for mb_ereg... and mb_split functions 
  1193. // Adobe CJK fonts 
  1194. $this->available_CJK_fonts = array('gb', 'big5', 'sjis', 'uhc', 'gbB', 'big5B', 'sjisB', 'uhcB', 'gbI', 'big5I', 'sjisI', 'uhcI',  
  1195. 'gbBI', 'big5BI', 'sjisBI', 'uhcBI'); 
  1196.  
  1197.  
  1198. //Standard fonts 
  1199. $this->CoreFonts = array('ccourier' => 'Courier', 'ccourierB' => 'Courier-Bold', 'ccourierI' => 'Courier-Oblique', 'ccourierBI' => 'Courier-BoldOblique',  
  1200. 'chelvetica' => 'Helvetica', 'chelveticaB' => 'Helvetica-Bold', 'chelveticaI' => 'Helvetica-Oblique', 'chelveticaBI' => 'Helvetica-BoldOblique',  
  1201. 'ctimes' => 'Times-Roman', 'ctimesB' => 'Times-Bold', 'ctimesI' => 'Times-Italic', 'ctimesBI' => 'Times-BoldItalic',  
  1202. 'csymbol' => 'Symbol', 'czapfdingbats' => 'ZapfDingbats'); 
  1203. $this->fontlist = array("ctimes", "ccourier", "chelvetica", "csymbol", "czapfdingbats"); 
  1204.  
  1205. // Substitutions 
  1206. $this->setHiEntitySubstitutions(); 
  1207.  
  1208. if ($this->onlyCoreFonts) { 
  1209. $this->useSubstitutions = true; 
  1210. $this->SetSubstitutions(); 
  1211.  
  1212. /** -- HTML-CSS -- */ 
  1213.  
  1214. if (!class_exists('cssmgr', false)) { 
  1215. include(_MPDF_PATH . 'classes/cssmgr.php'); 
  1216. $this->cssmgr = new cssmgr($this); 
  1217. // mPDF 6 
  1218. if (file_exists(_MPDF_PATH . 'mpdf.css')) { 
  1219. $css = file_get_contents(_MPDF_PATH . 'mpdf.css'); 
  1220. $this->cssmgr->ReadCSS('<style> ' . $css . ' </style>'); 
  1221. /** -- END HTML-CSS -- */ 
  1222.  
  1223. if ($default_font == '') { 
  1224. if ($this->onlyCoreFonts) { 
  1225. if (in_array(strtolower($this->defaultCSS['BODY']['FONT-FAMILY']), $this->mono_fonts)) { 
  1226. $default_font = 'ccourier'; 
  1227. } elseif (in_array(strtolower($this->defaultCSS['BODY']['FONT-FAMILY']), $this->sans_fonts)) { 
  1228. $default_font = 'chelvetica'; 
  1229. } else { 
  1230. $default_font = 'ctimes'; 
  1231. } else { 
  1232. $default_font = $this->defaultCSS['BODY']['FONT-FAMILY']; 
  1233. if (!$default_font_size) { 
  1234. $mmsize = $this->ConvertSize($this->defaultCSS['BODY']['FONT-SIZE']); 
  1235. $default_font_size = $mmsize * (_MPDFK); 
  1236.  
  1237. if ($default_font) { 
  1238. $this->SetDefaultFont($default_font); 
  1239. if ($default_font_size) { 
  1240. $this->SetDefaultFontSize($default_font_size); 
  1241.  
  1242. $this->SetLineHeight(); // lineheight is in mm 
  1243.  
  1244. $this->SetFColor($this->ConvertColor(255)); 
  1245. $this->HREF = ''; 
  1246. $this->oldy = -1; 
  1247. $this->B = 0; 
  1248. $this->I = 0; 
  1249.  
  1250. // mPDF 6 Lists 
  1251. $this->listlvl = 0; 
  1252. $this->listtype = array(); 
  1253. $this->listitem = array(); 
  1254. $this->listcounter = array(); 
  1255.  
  1256. $this->tdbegin = false; 
  1257. $this->table = array(); 
  1258. $this->cell = array(); 
  1259. $this->col = -1; 
  1260. $this->row = -1; 
  1261. $this->cellBorderBuffer = array(); 
  1262.  
  1263. $this->divbegin = false; 
  1264. // mPDF 6 
  1265. $this->cellTextAlign = ''; 
  1266. $this->cellLineHeight = ''; 
  1267. $this->cellLineStackingStrategy = ''; 
  1268. $this->cellLineStackingShift = ''; 
  1269.  
  1270. $this->divwidth = 0; 
  1271. $this->divheight = 0; 
  1272. $this->spanbgcolor = false; 
  1273. $this->spanborder = false; 
  1274. $this->spanborddet = array(); 
  1275.  
  1276. $this->blockjustfinished = false; 
  1277. $this->ignorefollowingspaces = true; //in order to eliminate exceeding left-side spaces 
  1278. $this->dash_on = false; 
  1279. $this->dotted_on = false; 
  1280. $this->textshadow = ''; 
  1281.  
  1282. $this->currentfontfamily = ''; 
  1283. $this->currentfontsize = ''; 
  1284. $this->currentfontstyle = ''; 
  1285. $this->colorarray = ''; // mPDF 6 
  1286. $this->spanbgcolorarray = ''; // mPDF 6 
  1287. $this->textbuffer = array(); 
  1288. $this->internallink = array(); 
  1289. $this->basepath = ""; 
  1290.  
  1291. $this->SetBasePath(''); 
  1292.  
  1293. $this->textparam = array(); 
  1294.  
  1295. $this->specialcontent = ''; 
  1296. $this->selectoption = array(); 
  1297.  
  1298. /** -- IMPORTS -- */ 
  1299.  
  1300. $this->tpls = array(); 
  1301. $this->tpl = 0; 
  1302. $this->tplprefix = "/TPL"; 
  1303. $this->res = array(); 
  1304. if ($this->enableImports) { 
  1305. $this->SetImportUse(); 
  1306. /** -- END IMPORTS -- */ 
  1307.  
  1308. $this->tag = new Tag($this); 
  1309.  
  1310. function _setPageSize($format, &$orientation) 
  1311. //Page format 
  1312. if (is_string($format)) { 
  1313. if ($format == '') { 
  1314. $format = 'A4'; 
  1315. $pfo = 'P'; 
  1316. if (preg_match('/([0-9a-zA-Z]*)-L/i', $format, $m)) { // e.g. A4-L = A4 landscape 
  1317. $format = $m[1]; 
  1318. $pfo = 'L'; 
  1319. $format = $this->_getPageFormat($format); 
  1320. if (!$format) { 
  1321. throw new MpdfException('Unknown page format: ' . $format); 
  1322. } else { 
  1323. $orientation = $pfo; 
  1324.  
  1325. $this->fwPt = $format[0]; 
  1326. $this->fhPt = $format[1]; 
  1327. } else { 
  1328. if (!$format[0] || !$format[1]) { 
  1329. throw new MpdfException('Invalid page format: ' . $format[0] . ' ' . $format[1]); 
  1330. $this->fwPt = $format[0] * _MPDFK; 
  1331. $this->fhPt = $format[1] * _MPDFK; 
  1332. $this->fw = $this->fwPt / _MPDFK; 
  1333. $this->fh = $this->fhPt / _MPDFK; 
  1334. //Page orientation 
  1335. $orientation = strtolower($orientation); 
  1336. if ($orientation == 'p' or $orientation == 'portrait') { 
  1337. $orientation = 'P'; 
  1338. $this->wPt = $this->fwPt; 
  1339. $this->hPt = $this->fhPt; 
  1340. } elseif ($orientation == 'l' or $orientation == 'landscape') { 
  1341. $orientation = 'L'; 
  1342. $this->wPt = $this->fhPt; 
  1343. $this->hPt = $this->fwPt; 
  1344. } else 
  1345. throw new MpdfException('Incorrect orientation: ' . $orientation); 
  1346. $this->CurOrientation = $orientation; 
  1347.  
  1348. $this->w = $this->wPt / _MPDFK; 
  1349. $this->h = $this->hPt / _MPDFK; 
  1350.  
  1351. function _getPageFormat($format) 
  1352. switch (strtoupper($format)) { 
  1353. case '4A0': { 
  1354. $format = array(4767.87, 6740.79); 
  1355. break; 
  1356. case '2A0': { 
  1357. $format = array(3370.39, 4767.87); 
  1358. break; 
  1359. case 'A0': { 
  1360. $format = array(2383.94, 3370.39); 
  1361. break; 
  1362. case 'A1': { 
  1363. $format = array(1683.78, 2383.94); 
  1364. break; 
  1365. case 'A2': { 
  1366. $format = array(1190.55, 1683.78); 
  1367. break; 
  1368. case 'A3': { 
  1369. $format = array(841.89, 1190.55); 
  1370. break; 
  1371. case 'A4': { 
  1372. $format = array(595.28, 841.89); 
  1373. break; 
  1374. case 'A5': { 
  1375. $format = array(419.53, 595.28); 
  1376. break; 
  1377. case 'A6': { 
  1378. $format = array(297.64, 419.53); 
  1379. break; 
  1380. case 'A7': { 
  1381. $format = array(209.76, 297.64); 
  1382. break; 
  1383. case 'A8': { 
  1384. $format = array(147.40, 209.76); 
  1385. break; 
  1386. case 'A9': { 
  1387. $format = array(104.88, 147.40); 
  1388. break; 
  1389. case 'A10': { 
  1390. $format = array(73.70, 104.88); 
  1391. break; 
  1392. case 'B0': { 
  1393. $format = array(2834.65, 4008.19); 
  1394. break; 
  1395. case 'B1': { 
  1396. $format = array(2004.09, 2834.65); 
  1397. break; 
  1398. case 'B2': { 
  1399. $format = array(1417.32, 2004.09); 
  1400. break; 
  1401. case 'B3': { 
  1402. $format = array(1000.63, 1417.32); 
  1403. break; 
  1404. case 'B4': { 
  1405. $format = array(708.66, 1000.63); 
  1406. break; 
  1407. case 'B5': { 
  1408. $format = array(498.90, 708.66); 
  1409. break; 
  1410. case 'B6': { 
  1411. $format = array(354.33, 498.90); 
  1412. break; 
  1413. case 'B7': { 
  1414. $format = array(249.45, 354.33); 
  1415. break; 
  1416. case 'B8': { 
  1417. $format = array(175.75, 249.45); 
  1418. break; 
  1419. case 'B9': { 
  1420. $format = array(124.72, 175.75); 
  1421. break; 
  1422. case 'B10': { 
  1423. $format = array(87.87, 124.72); 
  1424. break; 
  1425. case 'C0': { 
  1426. $format = array(2599.37, 3676.54); 
  1427. break; 
  1428. case 'C1': { 
  1429. $format = array(1836.85, 2599.37); 
  1430. break; 
  1431. case 'C2': { 
  1432. $format = array(1298.27, 1836.85); 
  1433. break; 
  1434. case 'C3': { 
  1435. $format = array(918.43, 1298.27); 
  1436. break; 
  1437. case 'C4': { 
  1438. $format = array(649.13, 918.43); 
  1439. break; 
  1440. case 'C5': { 
  1441. $format = array(459.21, 649.13); 
  1442. break; 
  1443. case 'C6': { 
  1444. $format = array(323.15, 459.21); 
  1445. break; 
  1446. case 'C7': { 
  1447. $format = array(229.61, 323.15); 
  1448. break; 
  1449. case 'C8': { 
  1450. $format = array(161.57, 229.61); 
  1451. break; 
  1452. case 'C9': { 
  1453. $format = array(113.39, 161.57); 
  1454. break; 
  1455. case 'C10': { 
  1456. $format = array(79.37, 113.39); 
  1457. break; 
  1458. case 'RA0': { 
  1459. $format = array(2437.80, 3458.27); 
  1460. break; 
  1461. case 'RA1': { 
  1462. $format = array(1729.13, 2437.80); 
  1463. break; 
  1464. case 'RA2': { 
  1465. $format = array(1218.90, 1729.13); 
  1466. break; 
  1467. case 'RA3': { 
  1468. $format = array(864.57, 1218.90); 
  1469. break; 
  1470. case 'RA4': { 
  1471. $format = array(609.45, 864.57); 
  1472. break; 
  1473. case 'SRA0': { 
  1474. $format = array(2551.18, 3628.35); 
  1475. break; 
  1476. case 'SRA1': { 
  1477. $format = array(1814.17, 2551.18); 
  1478. break; 
  1479. case 'SRA2': { 
  1480. $format = array(1275.59, 1814.17); 
  1481. break; 
  1482. case 'SRA3': { 
  1483. $format = array(907.09, 1275.59); 
  1484. break; 
  1485. case 'SRA4': { 
  1486. $format = array(637.80, 907.09); 
  1487. break; 
  1488. case 'LETTER': { 
  1489. $format = array(612.00, 792.00); 
  1490. break; 
  1491. case 'LEGAL': { 
  1492. $format = array(612.00, 1008.00); 
  1493. break; 
  1494. case 'LEDGER': { 
  1495. $format = array(1224.00, 792.00); 
  1496. break; 
  1497. case 'TABLOID': { 
  1498. $format = array(792.00, 1224.00); 
  1499. break; 
  1500. case 'EXECUTIVE': { 
  1501. $format = array(521.86, 756.00); 
  1502. break; 
  1503. case 'FOLIO': { 
  1504. $format = array(612.00, 936.00); 
  1505. break; 
  1506. case 'B': { 
  1507. $format = array(362.83, 561.26); 
  1508. break; 
  1509. } // 'B' format paperback size 128x198mm 
  1510. case 'A': { 
  1511. $format = array(314.65, 504.57); 
  1512. break; 
  1513. } // 'A' format paperback size 111x178mm 
  1514. case 'DEMY': { 
  1515. $format = array(382.68, 612.28); 
  1516. break; 
  1517. } // 'Demy' format paperback size 135x216mm 
  1518. case 'ROYAL': { 
  1519. $format = array(433.70, 663.30); 
  1520. break; 
  1521. } // 'Royal' format paperback size 153x234mm 
  1522. default: { 
  1523. $format = array(595.28, 841.89); 
  1524. break; 
  1525. return $format; 
  1526.  
  1527. function RestrictUnicodeFonts($res) 
  1528. // $res = array of (Unicode) fonts to restrict to: e.g. norasi|norasiB - language specific 
  1529. if (count($res)) { // Leave full list of available fonts if passed blank array 
  1530. $this->available_unifonts = $res; 
  1531. } else { 
  1532. $this->available_unifonts = $this->default_available_fonts; 
  1533. if (count($this->available_unifonts) == 0) { 
  1534. $this->available_unifonts[] = $this->default_available_fonts[0]; 
  1535. $this->available_unifonts = array_values($this->available_unifonts); 
  1536.  
  1537. function setMBencoding($enc) 
  1538. if ($this->mb_enc != $enc) { 
  1539. $this->mb_enc = $enc; 
  1540. mb_internal_encoding($this->mb_enc); 
  1541.  
  1542. function SetMargins($left, $right, $top) 
  1543. //Set left, top and right margins 
  1544. $this->lMargin = $left; 
  1545. $this->rMargin = $right; 
  1546. $this->tMargin = $top; 
  1547.  
  1548. function ResetMargins() 
  1549. //ReSet left, top margins 
  1550. if (($this->forcePortraitHeaders || $this->forcePortraitMargins) && $this->DefOrientation == 'P' && $this->CurOrientation == 'L') { 
  1551. if (($this->mirrorMargins) && (($this->page) % 2 == 0)) { // EVEN 
  1552. $this->tMargin = $this->orig_rMargin; 
  1553. $this->bMargin = $this->orig_lMargin; 
  1554. } else { // ODD // OR NOT MIRRORING MARGINS/FOOTERS 
  1555. $this->tMargin = $this->orig_lMargin; 
  1556. $this->bMargin = $this->orig_rMargin; 
  1557. $this->lMargin = $this->DeflMargin; 
  1558. $this->rMargin = $this->DefrMargin; 
  1559. $this->MarginCorrection = 0; 
  1560. $this->PageBreakTrigger = $this->h - $this->bMargin; 
  1561. } elseif (($this->mirrorMargins) && (($this->page) % 2 == 0)) { // EVEN 
  1562. $this->lMargin = $this->DefrMargin; 
  1563. $this->rMargin = $this->DeflMargin; 
  1564. $this->MarginCorrection = $this->DefrMargin - $this->DeflMargin; 
  1565. } else { // ODD // OR NOT MIRRORING MARGINS/FOOTERS 
  1566. $this->lMargin = $this->DeflMargin; 
  1567. $this->rMargin = $this->DefrMargin; 
  1568. if ($this->mirrorMargins) { 
  1569. $this->MarginCorrection = $this->DeflMargin - $this->DefrMargin; 
  1570. $this->x = $this->lMargin; 
  1571.  
  1572. function SetLeftMargin($margin) 
  1573. //Set left margin 
  1574. $this->lMargin = $margin; 
  1575. if ($this->page > 0 and $this->x < $margin) 
  1576. $this->x = $margin; 
  1577.  
  1578. function SetTopMargin($margin) 
  1579. //Set top margin 
  1580. $this->tMargin = $margin; 
  1581.  
  1582. function SetRightMargin($margin) 
  1583. //Set right margin 
  1584. $this->rMargin = $margin; 
  1585.  
  1586. function SetAutoPageBreak($auto, $margin = 0) 
  1587. //Set auto page break mode and triggering margin 
  1588. $this->autoPageBreak = $auto; 
  1589. $this->bMargin = $margin; 
  1590. $this->PageBreakTrigger = $this->h - $margin; 
  1591.  
  1592. function SetDisplayMode($zoom, $layout = 'continuous') 
  1593. //Set display mode in viewer 
  1594. if ($zoom == 'fullpage' or $zoom == 'fullwidth' or $zoom == 'real' or $zoom == 'default' or ! is_string($zoom)) 
  1595. $this->ZoomMode = $zoom; 
  1596. else 
  1597. throw new MpdfException('Incorrect zoom display mode: ' . $zoom); 
  1598. if ($layout == 'single' or $layout == 'continuous' or $layout == 'two' or $layout == 'twoleft' or $layout == 'tworight' or $layout == 'default') 
  1599. $this->LayoutMode = $layout; 
  1600. else 
  1601. throw new MpdfException('Incorrect layout display mode: ' . $layout); 
  1602.  
  1603. function SetCompression($compress) 
  1604. //Set page compression 
  1605. if (function_exists('gzcompress')) 
  1606. $this->compress = $compress; 
  1607. else 
  1608. $this->compress = false; 
  1609.  
  1610. function SetTitle($title) 
  1611. //Title of document // Arrives as UTF-8 
  1612. $this->title = $title; 
  1613.  
  1614. function SetSubject($subject) 
  1615. //Subject of document 
  1616. $this->subject = $subject; 
  1617.  
  1618. function SetAuthor($author) 
  1619. //Author of document 
  1620. $this->author = $author; 
  1621.  
  1622. function SetKeywords($keywords) 
  1623. //Keywords of document 
  1624. $this->keywords = $keywords; 
  1625.  
  1626. function SetCreator($creator) 
  1627. //Creator of document 
  1628. $this->creator = $creator; 
  1629.  
  1630. function SetAnchor2Bookmark($x) 
  1631. $this->anchor2Bookmark = $x; 
  1632.  
  1633. function AliasNbPages($alias = '{nb}') 
  1634. //Define an alias for total number of pages 
  1635. $this->aliasNbPg = $alias; 
  1636.  
  1637. function AliasNbPageGroups($alias = '{nbpg}') 
  1638. //Define an alias for total number of pages in a group 
  1639. $this->aliasNbPgGp = $alias; 
  1640.  
  1641. function SetAlpha($alpha, $bm = 'Normal', $return = false, $mode = 'B') 
  1642. // alpha: real value from 0 (transparent) to 1 (opaque) 
  1643. // bm: blend mode, one of the following: 
  1644. // Normal, Multiply, Screen, Overlay, Darken, Lighten, ColorDodge, ColorBurn,  
  1645. // HardLight, SoftLight, Difference, Exclusion, Hue, Saturation, Color, Luminosity 
  1646. // set alpha for stroking (CA) and non-stroking (ca) operations 
  1647. // mode determines F (fill) S (stroke) B (both) 
  1648. if (($this->PDFA || $this->PDFX) && $alpha != 1) { 
  1649. if (($this->PDFA && !$this->PDFAauto) || ($this->PDFX && !$this->PDFXauto)) { 
  1650. $this->PDFAXwarnings[] = "Image opacity must be 100% (Opacity changed to 100%)"; 
  1651. $alpha = 1; 
  1652. $a = array('BM' => '/' . $bm); 
  1653. if ($mode == 'F' || $mode == 'B') 
  1654. $a['ca'] = $alpha; // mPDF 5.7.2 
  1655. if ($mode == 'S' || $mode == 'B') 
  1656. $a['CA'] = $alpha; // mPDF 5.7.2 
  1657. $gs = $this->AddExtGState($a); 
  1658. if ($return) { 
  1659. return sprintf('/GS%d gs', $gs); 
  1660. } else { 
  1661. $this->_out(sprintf('/GS%d gs', $gs)); 
  1662.  
  1663. function AddExtGState($parms) 
  1664. $n = count($this->extgstates); 
  1665. // check if graphics state already exists 
  1666. for ($i = 1; $i <= $n; $i++) { 
  1667. if (count($this->extgstates[$i]['parms']) == count($parms)) { 
  1668. $same = true; 
  1669. foreach ($this->extgstates[$i]['parms'] AS $k => $v) { 
  1670. if (!isset($parms[$k]) || $parms[$k] != $v) { 
  1671. $same = false; 
  1672. break; 
  1673. if ($same) { 
  1674. return $i; 
  1675. $n++; 
  1676. $this->extgstates[$n]['parms'] = $parms; 
  1677. return $n; 
  1678.  
  1679. function SetVisibility($v) 
  1680. if (($this->PDFA || $this->PDFX) && $this->visibility != 'visible') { 
  1681. $this->PDFAXwarnings[] = "Cannot set visibility to anything other than full when using PDFA or PDFX"; 
  1682. return ''; 
  1683. } elseif (!$this->PDFA && !$this->PDFX) 
  1684. $this->pdf_version = '1.5'; 
  1685. if ($this->visibility != 'visible') { 
  1686. $this->_out('EMC'); 
  1687. $this->hasOC = intval($this->hasOC); 
  1688. if ($v == 'printonly') { 
  1689. $this->_out('/OC /OC1 BDC'); 
  1690. $this->hasOC = ($this->hasOC | 1); 
  1691. } elseif ($v == 'screenonly') { 
  1692. $this->_out('/OC /OC2 BDC'); 
  1693. $this->hasOC = ($this->hasOC | 2); 
  1694. } elseif ($v == 'hidden') { 
  1695. $this->_out('/OC /OC3 BDC'); 
  1696. $this->hasOC = ($this->hasOC | 4); 
  1697. } elseif ($v != 'visible') 
  1698. throw new MpdfException('Incorrect visibility: ' . $v); 
  1699. $this->visibility = $v; 
  1700.  
  1701. function Open() 
  1702. //Begin document 
  1703. if ($this->state == 0) { 
  1704. // Was is function _begindoc() 
  1705. // Start document 
  1706. $this->state = 1; 
  1707. $this->_out('%PDF-' . $this->pdf_version); 
  1708. $this->_out('%' . chr(226) . chr(227) . chr(207) . chr(211)); // 4 chars > 128 to show binary file 
  1709.  
  1710. /** 
  1711. * Trigger a E_USER_NOTICE so the message is stored in PHP's log 
  1712. * @param String $message 
  1713. */ 
  1714. function Notice( $message ) { 
  1715. trigger_error( $message ); 
  1716.  
  1717. // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 
  1718. // DEPRACATED but included for backwards compatability 
  1719. // Depracated - can use AddPage for all 
  1720. function AddPages($a = '', $b = '', $c = '', $d = '', $e = '', $f = '', $g = '', $h = '', $i = '', $j = '', $k = '', $l = '', $m = '', $n = '', $o = '', $p = 0, $q = 0, $r = 0, $s = 0, $t = '', $u = '') 
  1721. $this->Notice('function AddPages is depracated as of mPDF 6. Please use AddPage or HTML code methods instead.'); 
  1722.  
  1723. function startPageNums() 
  1724. $this->Notice('function startPageNums is depracated as of mPDF 6.'); 
  1725.  
  1726. function setUnvalidatedText($a = '', $b = -1) 
  1727. $this->Notice('function setUnvalidatedText is depracated as of mPDF 6. Please use SetWatermarkText instead.'); 
  1728.  
  1729. function SetAutoFont($a) 
  1730. if($a === 0) { 
  1731. $this->autoLangToFont = false; 
  1732. $this->autoScriptToLang = false; 
  1733. } else { 
  1734. $this->autoLangToFont = true; 
  1735. $this->autoScriptToLang = true; 
  1736.  
  1737. $this->Notice('function SetAutoFont is depracated as of mPDF 6. Please use autoScriptToLang instead. See config.php'); 
  1738.  
  1739. function Reference($a) 
  1740. $this->Notice('function Reference is depracated as of mPDF 6. Please use IndexEntry instead.'); 
  1741.  
  1742. function ReferenceSee($a, $b) 
  1743. $this->Notice('function ReferenceSee is depracated as of mPDF 6. Please use IndexEntrySee instead.'); 
  1744.  
  1745. function CreateReference($a = 1, $b = '', $c = '', $d = 3, $e = 1, $f = '', $g = 5, $h = '', $i = '', $j = false) 
  1746. $this->Notice('function CreateReference is depracated as of mPDF 6. Please use InsertIndex instead.'); 
  1747.  
  1748. function CreateIndex($a = 1, $b = '', $c = '', $d = 3, $e = 1, $f = '', $g = 5, $h = '', $i = '', $j = false) 
  1749. $this->Notice('function CreateIndex is depracated as of mPDF 6. Please use InsertIndex instead.'); 
  1750.  
  1751. // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 
  1752.  
  1753. function Close() 
  1754. // Check old Aliases - now depracated mPDF 6 
  1755. if (isset($this->UnvalidatedText)) { 
  1756. $this->Notice('$mpdf->UnvalidatedText is depracated as of mPDF 6. Please use $mpdf->watermarkText instead.'); 
  1757. if (isset($this->TopicIsUnvalidated)) { 
  1758. $this->Notice('$mpdf->TopicIsUnvalidated is depracated as of mPDF 6. Please use $mpdf->showWatermarkText instead.'); 
  1759. if (isset($this->AliasNbPg)) { 
  1760. $this->Notice('$mpdf->AliasNbPg is depracated as of mPDF 6. Please use $mpdf->aliasNbPg instead.'); 
  1761. if (isset($this->AliasNbPgGp)) { 
  1762. $this->Notice('$mpdf->AliasNbPgGp is depracated as of mPDF 6. Please use $mpdf->aliasNbPgGp instead.'); 
  1763. if (isset($this->BiDirectional)) { 
  1764. $this->Notice('$mpdf->BiDirectional is depracated as of mPDF 6. Please use $mpdf->biDirectional instead.'); 
  1765. if (isset($this->Anchor2Bookmark)) { 
  1766. $this->Notice('$mpdf->Anchor2Bookmark is depracated as of mPDF 6. Please use $mpdf->anchor2Bookmark instead.'); 
  1767. if (isset($this->KeepColumns)) { 
  1768. $this->Notice('$mpdf->KeepColumns is depracated as of mPDF 6. Please use $mpdf->keepColumns instead.'); 
  1769. if (isset($this->useOddEven)) { 
  1770. $this->Notice('$mpdf->useOddEven is depracated as of mPDF 6. Please use $mpdf->mirrorMargins instead.'); 
  1771. if (isset($this->useSubstitutionsMB)) { 
  1772. $this->Notice('$mpdf->useSubstitutionsMB is depracated as of mPDF 6. Please use $mpdf->useSubstitutions instead.'); 
  1773. if (isset($this->useLang)) { 
  1774. $this->Notice('$mpdf->useLang is depracated as of mPDF 6. Please use $mpdf->autoLangToFont instead.'); 
  1775. if (isset($this->useAutoFont)) { 
  1776. $this->Notice('$mpdf->useAutoFont is depracated. Please use $mpdf->autoScriptToLang instead.'); 
  1777.  
  1778. //Terminate document 
  1779. if ($this->state == 3) 
  1780. return; 
  1781. if ($this->page == 0) 
  1782. $this->AddPage($this->CurOrientation); 
  1783. if (count($this->cellBorderBuffer)) { 
  1784. $this->printcellbuffer(); 
  1785. } // *TABLES* 
  1786. if ($this->tablebuffer) { 
  1787. $this->printtablebuffer(); 
  1788. } // *TABLES* 
  1789. /** -- COLUMNS -- */ 
  1790.  
  1791. if ($this->ColActive) { 
  1792. $this->SetColumns(0); 
  1793. $this->ColActive = 0; 
  1794. if (count($this->columnbuffer)) { 
  1795. $this->printcolumnbuffer(); 
  1796. /** -- END COLUMNS -- */ 
  1797.  
  1798. // BODY Backgrounds 
  1799. $s = ''; 
  1800.  
  1801. $s .= $this->PrintBodyBackgrounds(); 
  1802.  
  1803. $s .= $this->PrintPageBackgrounds(); 
  1804. $this->pages[$this->page] = preg_replace('/(___BACKGROUND___PATTERNS' . $this->uniqstr . ')/', "\n" . $s . "\n" . '\\1', $this->pages[$this->page]); 
  1805. $this->pageBackgrounds = array(); 
  1806.  
  1807. if ($this->visibility != 'visible') 
  1808. $this->SetVisibility('visible'); 
  1809. $this->EndLayer(); 
  1810.  
  1811. if (!$this->tocontents || !$this->tocontents->TOCmark) { //Page footer 
  1812. $this->InFooter = true; 
  1813. $this->Footer(); 
  1814. $this->InFooter = false; 
  1815. if ($this->tocontents && ($this->tocontents->TOCmark || count($this->tocontents->m_TOC))) { 
  1816. $this->tocontents->insertTOC(); 
  1817. } // *TOC* 
  1818. //Close page 
  1819. $this->_endpage(); 
  1820.  
  1821. //Close document 
  1822. $this->_enddoc(); 
  1823.  
  1824. /** -- BACKGROUNDS -- */ 
  1825.  
  1826. function _resizeBackgroundImage($imw, $imh, $cw, $ch, $resize = 0, $repx, $repy, $pba = array(), $size = array()) 
  1827. // pba is background positioning area (from CSS background-origin) may not always be set [x, y, w, h] 
  1828. // size is from CSS3 background-size - takes precendence over old resize 
  1829. // $w - absolute length or % or auto or cover | contain 
  1830. // $h - absolute length or % or auto or cover | contain 
  1831. if (isset($pba['w'])) 
  1832. $cw = $pba['w']; 
  1833. if (isset($pba['h'])) 
  1834. $ch = $pba['h']; 
  1835.  
  1836. $cw = $cw * _MPDFK; 
  1837. $ch = $ch * _MPDFK; 
  1838. if (empty($size) && !$resize) { 
  1839. return array($imw, $imh, $repx, $repy); 
  1840.  
  1841. if (isset($size['w']) && $size['w']) { 
  1842. if ($size['w'] == 'contain') { 
  1843. // 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. 
  1844. // Same as resize==3 
  1845. $h = $imh * $cw / $imw; 
  1846. $w = $cw; 
  1847. if ($h > $ch) { 
  1848. $w = $w * $ch / $h; 
  1849. $h = $ch; 
  1850. } elseif ($size['w'] == 'cover') { 
  1851. // 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. 
  1852. $h = $imh * $cw / $imw; 
  1853. $w = $cw; 
  1854. if ($h < $ch) { 
  1855. $w = $w * $h / $ch; 
  1856. $h = $ch; 
  1857. } else { 
  1858. if (stristr($size['w'], '%')) { 
  1859. $size['w'] += 0; 
  1860. $size['w'] /= 100; 
  1861. $size['w'] = ($cw * $size['w']); 
  1862. if (stristr($size['h'], '%')) { 
  1863. $size['h'] += 0; 
  1864. $size['h'] /= 100; 
  1865. $size['h'] = ($ch * $size['h']); 
  1866. if ($size['w'] == 'auto' && $size['h'] == 'auto') { 
  1867. $w = $imw; 
  1868. $h = $imh; 
  1869. } elseif ($size['w'] == 'auto' && $size['h'] != 'auto') { 
  1870. $w = $imw * $size['h'] / $imh; 
  1871. $h = $size['h']; 
  1872. } elseif ($size['w'] != 'auto' && $size['h'] == 'auto') { 
  1873. $h = $imh * $size['w'] / $imw; 
  1874. $w = $size['w']; 
  1875. } else { 
  1876. $w = $size['w']; 
  1877. $h = $size['h']; 
  1878. return array($w, $h, $repx, $repy); 
  1879. } elseif ($resize == 1 && $imw > $cw) { 
  1880. $h = $imh * $cw / $imw; 
  1881. return array($cw, $h, $repx, $repy); 
  1882. } elseif ($resize == 2 && $imh > $ch) { 
  1883. $w = $imw * $ch / $imh; 
  1884. return array($w, $ch, $repx, $repy); 
  1885. } elseif ($resize == 3) { 
  1886. $w = $imw; 
  1887. $h = $imh; 
  1888. if ($w > $cw) { 
  1889. $h = $h * $cw / $w; 
  1890. $w = $cw; 
  1891. if ($h > $ch) { 
  1892. $w = $w * $ch / $h; 
  1893. $h = $ch; 
  1894. return array($w, $h, $repx, $repy); 
  1895. } elseif ($resize == 4) { 
  1896. $h = $imh * $cw / $imw; 
  1897. return array($cw, $h, $repx, $repy); 
  1898. } elseif ($resize == 5) { 
  1899. $w = $imw * $ch / $imh; 
  1900. return array($w, $ch, $repx, $repy); 
  1901. } elseif ($resize == 6) { 
  1902. return array($cw, $ch, $repx, $repy); 
  1903. return array($imw, $imh, $repx, $repy); 
  1904.  
  1905. function SetBackground(&$properties, &$maxwidth) 
  1906. if (isset($properties['BACKGROUND-ORIGIN']) && ($properties['BACKGROUND-ORIGIN'] == 'border-box' || $properties['BACKGROUND-ORIGIN'] == 'content-box')) { 
  1907. $origin = $properties['BACKGROUND-ORIGIN']; 
  1908. } else { 
  1909. $origin = 'padding-box'; 
  1910. if (isset($properties['BACKGROUND-SIZE'])) { 
  1911. if (stristr($properties['BACKGROUND-SIZE'], 'contain')) { 
  1912. $bsw = $bsh = 'contain'; 
  1913. } elseif (stristr($properties['BACKGROUND-SIZE'], 'cover')) { 
  1914. $bsw = $bsh = 'cover'; 
  1915. } else { 
  1916. $bsw = $bsh = 'auto'; 
  1917. $sz = preg_split('/\s+/', trim($properties['BACKGROUND-SIZE'])); 
  1918. if (count($sz) == 2) { 
  1919. $bsw = $sz[0]; 
  1920. $bsh = $sz[1]; 
  1921. } else { 
  1922. $bsw = $sz[0]; 
  1923. if (!stristr($bsw, '%') && !stristr($bsw, 'auto')) { 
  1924. $bsw = $this->ConvertSize($bsw, $maxwidth, $this->FontSize); 
  1925. if (!stristr($bsh, '%') && !stristr($bsh, 'auto')) { 
  1926. $bsh = $this->ConvertSize($bsh, $maxwidth, $this->FontSize); 
  1927. $size = array('w' => $bsw, 'h' => $bsh); 
  1928. } else { 
  1929. $size = false; 
  1930. } // mPDF 6 
  1931. if (preg_match('/(-moz-)*(repeating-)*(linear|radial)-gradient/', $properties['BACKGROUND-IMAGE'])) { 
  1932. return array('gradient' => $properties['BACKGROUND-IMAGE'], 'origin' => $origin, 'size' => $size); 
  1933. } else { 
  1934. $file = $properties['BACKGROUND-IMAGE']; 
  1935. $sizesarray = $this->Image($file, 0, 0, 0, 0, '', '', false, false, false, false, true); 
  1936. if (isset($sizesarray['IMAGE_ID'])) { 
  1937. $image_id = $sizesarray['IMAGE_ID']; 
  1938. $orig_w = $sizesarray['WIDTH'] * _MPDFK; // in user units i.e. mm 
  1939. $orig_h = $sizesarray['HEIGHT'] * _MPDFK; // (using $this->img_dpi) 
  1940. if (isset($properties['BACKGROUND-IMAGE-RESOLUTION'])) { 
  1941. if (preg_match('/from-image/i', $properties['BACKGROUND-IMAGE-RESOLUTION']) && isset($sizesarray['set-dpi']) && $sizesarray['set-dpi'] > 0) { 
  1942. $orig_w *= $this->img_dpi / $sizesarray['set-dpi']; 
  1943. $orig_h *= $this->img_dpi / $sizesarray['set-dpi']; 
  1944. } elseif (preg_match('/(\d+)dpi/i', $properties['BACKGROUND-IMAGE-RESOLUTION'], $m)) { 
  1945. $dpi = $m[1]; 
  1946. if ($dpi > 0) { 
  1947. $orig_w *= $this->img_dpi / $dpi; 
  1948. $orig_h *= $this->img_dpi / $dpi; 
  1949. $x_repeat = true; 
  1950. $y_repeat = true; 
  1951. if (isset($properties['BACKGROUND-REPEAT'])) { 
  1952. if ($properties['BACKGROUND-REPEAT'] == 'no-repeat' || $properties['BACKGROUND-REPEAT'] == 'repeat-x') { 
  1953. $y_repeat = false; 
  1954. if ($properties['BACKGROUND-REPEAT'] == 'no-repeat' || $properties['BACKGROUND-REPEAT'] == 'repeat-y') { 
  1955. $x_repeat = false; 
  1956. $x_pos = 0; 
  1957. $y_pos = 0; 
  1958. if (isset($properties['BACKGROUND-POSITION'])) { 
  1959. $ppos = preg_split('/\s+/', $properties['BACKGROUND-POSITION']); 
  1960. $x_pos = $ppos[0]; 
  1961. $y_pos = $ppos[1]; 
  1962. if (!stristr($x_pos, '%')) { 
  1963. $x_pos = $this->ConvertSize($x_pos, $maxwidth, $this->FontSize); 
  1964. if (!stristr($y_pos, '%')) { 
  1965. $y_pos = $this->ConvertSize($y_pos, $maxwidth, $this->FontSize); 
  1966. if (isset($properties['BACKGROUND-IMAGE-RESIZE'])) { 
  1967. $resize = $properties['BACKGROUND-IMAGE-RESIZE']; 
  1968. } else { 
  1969. $resize = 0; 
  1970. if (isset($properties['BACKGROUND-IMAGE-OPACITY'])) { 
  1971. $opacity = $properties['BACKGROUND-IMAGE-OPACITY']; 
  1972. } else { 
  1973. $opacity = 1; 
  1974. return array('image_id' => $image_id, 'orig_w' => $orig_w, 'orig_h' => $orig_h, 'x_pos' => $x_pos, 'y_pos' => $y_pos, 'x_repeat' => $x_repeat, 'y_repeat' => $y_repeat, 'resize' => $resize, 'opacity' => $opacity, 'itype' => $sizesarray['itype'], 'origin' => $origin, 'size' => $size); 
  1975. return false; 
  1976.  
  1977. /** -- END BACKGROUNDS -- */ 
  1978.  
  1979. function PrintBodyBackgrounds() 
  1980. $s = ''; 
  1981. $clx = 0; 
  1982. $cly = 0; 
  1983. $clw = $this->w; 
  1984. $clh = $this->h; 
  1985. // If using bleed and trim margins in paged media 
  1986. if ($this->pageDim[$this->page]['outer_width_LR'] || $this->pageDim[$this->page]['outer_width_TB']) { 
  1987. $clx = $this->pageDim[$this->page]['outer_width_LR'] - $this->pageDim[$this->page]['bleedMargin']; 
  1988. $cly = $this->pageDim[$this->page]['outer_width_TB'] - $this->pageDim[$this->page]['bleedMargin']; 
  1989. $clw = $this->w - 2 * $clx; 
  1990. $clh = $this->h - 2 * $cly; 
  1991.  
  1992. if ($this->bodyBackgroundColor) { 
  1993. $s .= 'q ' . $this->SetFColor($this->bodyBackgroundColor, true) . "\n"; 
  1994. if ($this->bodyBackgroundColor{0} == 5) { // RGBa 
  1995. $s .= $this->SetAlpha(ord($this->bodyBackgroundColor{4}) / 100, 'Normal', true, 'F') . "\n"; 
  1996. } elseif ($this->bodyBackgroundColor{0} == 6) { // CMYKa 
  1997. $s .= $this->SetAlpha(ord($this->bodyBackgroundColor{5}) / 100, 'Normal', true, 'F') . "\n"; 
  1998. $s .= sprintf('%.3F %.3F %.3F %.3F re f Q', ($clx * _MPDFK), ($cly * _MPDFK), $clw * _MPDFK, $clh * _MPDFK) . "\n"; 
  1999.  
  2000. /** -- BACKGROUNDS -- */ 
  2001. if ($this->bodyBackgroundGradient) { 
  2002. $g = $this->grad->parseBackgroundGradient($this->bodyBackgroundGradient); 
  2003. if ($g) { 
  2004. $s .= $this->grad->Gradient($clx, $cly, $clw, $clh, (isset($g['gradtype']) ? $g['gradtype'] : null), $g['stops'], $g['colorspace'], $g['coords'], $g['extend'], true); 
  2005. if ($this->bodyBackgroundImage) { 
  2006. if (isset($this->bodyBackgroundImage['gradient']) && $this->bodyBackgroundImage['gradient'] && preg_match('/(-moz-)*(repeating-)*(linear|radial)-gradient/', $this->bodyBackgroundImage['gradient'])) { 
  2007. $g = $this->grad->parseMozGradient($this->bodyBackgroundImage['gradient']); 
  2008. if ($g) { 
  2009. $s .= $this->grad->Gradient($clx, $cly, $clw, $clh, $g['type'], $g['stops'], $g['colorspace'], $g['coords'], $g['extend'], true); 
  2010. } elseif ($this->bodyBackgroundImage['image_id']) { // Background pattern 
  2011. $n = count($this->patterns) + 1; 
  2012. // If using resize, uses TrimBox (not including the bleed) 
  2013. 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']); 
  2014.  
  2015. $this->patterns[$n] = array('x' => $clx, 'y' => $cly, 'w' => $clw, 'h' => $clh, 'pgh' => $this->h, 'image_id' => $this->bodyBackgroundImage['image_id'], 'orig_w' => $orig_w, 'orig_h' => $orig_h, 'x_pos' => $this->bodyBackgroundImage['x_pos'], 'y_pos' => $this->bodyBackgroundImage['y_pos'], 'x_repeat' => $x_repeat, 'y_repeat' => $y_repeat, 'itype' => $this->bodyBackgroundImage['itype']); 
  2016. if (($this->bodyBackgroundImage['opacity'] > 0 || $this->bodyBackgroundImage['opacity'] === '0') && $this->bodyBackgroundImage['opacity'] < 1) { 
  2017. $opac = $this->SetAlpha($this->bodyBackgroundImage['opacity'], 'Normal', true); 
  2018. } else { 
  2019. $opac = ''; 
  2020. $s .= sprintf('q /Pattern cs /P%d scn %s %.3F %.3F %.3F %.3F re f Q', $n, $opac, ($clx * _MPDFK), ($cly * _MPDFK), $clw * _MPDFK, $clh * _MPDFK) . "\n"; 
  2021. /** -- END BACKGROUNDS -- */ 
  2022. return $s; 
  2023.  
  2024. function _setClippingPath($clx, $cly, $clw, $clh) 
  2025. $s = ' q 0 w '; // Line width=0 
  2026. $s .= sprintf('%.3F %.3F m ', ($clx) * _MPDFK, ($this->h - ($cly)) * _MPDFK); // start point TL before the arc 
  2027. $s .= sprintf('%.3F %.3F l ', ($clx) * _MPDFK, ($this->h - ($cly + $clh)) * _MPDFK); // line to BL 
  2028. $s .= sprintf('%.3F %.3F l ', ($clx + $clw) * _MPDFK, ($this->h - ($cly + $clh)) * _MPDFK); // line to BR 
  2029. $s .= sprintf('%.3F %.3F l ', ($clx + $clw) * _MPDFK, ($this->h - ($cly)) * _MPDFK); // line to TR 
  2030. $s .= sprintf('%.3F %.3F l ', ($clx) * _MPDFK, ($this->h - ($cly)) * _MPDFK); // line to TL 
  2031. $s .= ' W n '; // Ends path no-op & Sets the clipping path 
  2032. return $s; 
  2033.  
  2034. function PrintPageBackgrounds($adjustmenty = 0) 
  2035. $s = ''; 
  2036.  
  2037. ksort($this->pageBackgrounds); 
  2038. foreach ($this->pageBackgrounds AS $bl => $pbs) { 
  2039. foreach ($pbs AS $pb) { 
  2040. if ((!isset($pb['image_id']) && !isset($pb['gradient'])) || isset($pb['shadowonly'])) { // Background colour or boxshadow 
  2041. if ($pb['z-index'] > 0) { 
  2042. $this->current_layer = $pb['z-index']; 
  2043. $s .= "\n" . '/OCBZ-index /ZI' . $pb['z-index'] . ' BDC' . "\n"; 
  2044.  
  2045. if ($pb['visibility'] != 'visible') { 
  2046. if ($pb['visibility'] == 'printonly') 
  2047. $s .= '/OC /OC1 BDC' . "\n"; 
  2048. elseif ($pb['visibility'] == 'screenonly') 
  2049. $s .= '/OC /OC2 BDC' . "\n"; 
  2050. elseif ($pb['visibility'] == 'hidden') 
  2051. $s .= '/OC /OC3 BDC' . "\n"; 
  2052. // Box shadow 
  2053. if (isset($pb['shadow']) && $pb['shadow']) { 
  2054. $s .= $pb['shadow'] . "\n"; 
  2055. if (isset($pb['clippath']) && $pb['clippath']) { 
  2056. $s .= $pb['clippath'] . "\n"; 
  2057. $s .= 'q ' . $this->SetFColor($pb['col'], true) . "\n"; 
  2058. if ($pb['col']{0} == 5) { // RGBa 
  2059. $s .= $this->SetAlpha(ord($pb['col']{4}) / 100, 'Normal', true, 'F') . "\n"; 
  2060. } elseif ($pb['col']{0} == 6) { // CMYKa 
  2061. $s .= $this->SetAlpha(ord($pb['col']{5}) / 100, 'Normal', true, 'F') . "\n"; 
  2062. $s .= sprintf('%.3F %.3F %.3F %.3F re f Q', $pb['x'] * _MPDFK, ($this->h - $pb['y']) * _MPDFK, $pb['w'] * _MPDFK, -$pb['h'] * _MPDFK) . "\n"; 
  2063. if (isset($pb['clippath']) && $pb['clippath']) { 
  2064. $s .= 'Q' . "\n"; 
  2065. if ($pb['visibility'] != 'visible') 
  2066. $s .= 'EMC' . "\n"; 
  2067.  
  2068. if ($pb['z-index'] > 0) { 
  2069. $s .= "\n" . 'EMCBZ-index' . "\n"; 
  2070. $this->current_layer = 0; 
  2071. /** -- BACKGROUNDS -- */ 
  2072. foreach ($pbs AS $pb) { 
  2073. if ((isset($pb['gradient']) && $pb['gradient']) || (isset($pb['image_id']) && $pb['image_id'])) { 
  2074. if ($pb['z-index'] > 0) { 
  2075. $this->current_layer = $pb['z-index']; 
  2076. $s .= "\n" . '/OCGZ-index /ZI' . $pb['z-index'] . ' BDC' . "\n"; 
  2077. if ($pb['visibility'] != 'visible') { 
  2078. if ($pb['visibility'] == 'printonly') 
  2079. $s .= '/OC /OC1 BDC' . "\n"; 
  2080. elseif ($pb['visibility'] == 'screenonly') 
  2081. $s .= '/OC /OC2 BDC' . "\n"; 
  2082. elseif ($pb['visibility'] == 'hidden') 
  2083. $s .= '/OC /OC3 BDC' . "\n"; 
  2084. if (isset($pb['gradient']) && $pb['gradient']) { 
  2085. if (isset($pb['clippath']) && $pb['clippath']) { 
  2086. $s .= $pb['clippath'] . "\n"; 
  2087. $s .= $this->grad->Gradient($pb['x'], $pb['y'], $pb['w'], $pb['h'], $pb['gradtype'], $pb['stops'], $pb['colorspace'], $pb['coords'], $pb['extend'], true); 
  2088. if (isset($pb['clippath']) && $pb['clippath']) { 
  2089. $s .= 'Q' . "\n"; 
  2090. } elseif (isset($pb['image_id']) && $pb['image_id']) { // Background Image 
  2091. $pb['y'] -= $adjustmenty; 
  2092. $pb['h'] += $adjustmenty; 
  2093. $n = count($this->patterns) + 1; 
  2094. 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']); 
  2095. $this->patterns[$n] = array('x' => $pb['x'], 'y' => $pb['y'], 'w' => $pb['w'], 'h' => $pb['h'], 'pgh' => $this->h, 'image_id' => $pb['image_id'], 'orig_w' => $orig_w, 'orig_h' => $orig_h, 'x_pos' => $pb['x_pos'], 'y_pos' => $pb['y_pos'], 'x_repeat' => $x_repeat, 'y_repeat' => $y_repeat, 'itype' => $pb['itype'], 'bpa' => $pb['bpa']); 
  2096. $x = $pb['x'] * _MPDFK; 
  2097. $y = ($this->h - $pb['y']) * _MPDFK; 
  2098. $w = $pb['w'] * _MPDFK; 
  2099. $h = -$pb['h'] * _MPDFK; 
  2100. if (isset($pb['clippath']) && $pb['clippath']) { 
  2101. $s .= $pb['clippath'] . "\n"; 
  2102. if ($this->writingHTMLfooter || $this->writingHTMLheader) { // Write each (tiles) image rather than use as a pattern 
  2103. $iw = $pb['orig_w'] / _MPDFK; 
  2104. $ih = $pb['orig_h'] / _MPDFK; 
  2105.  
  2106. $w = $pb['w']; 
  2107. $h = $pb['h']; 
  2108. $x0 = $pb['x']; 
  2109. $y0 = $pb['y']; 
  2110.  
  2111. if (isset($pb['bpa']) && $pb['bpa']) { 
  2112. $w = $pb['bpa']['w']; 
  2113. $h = $pb['bpa']['h']; 
  2114. $x0 = $pb['bpa']['x']; 
  2115. $y0 = $pb['bpa']['y']; 
  2116.  
  2117. if (isset($pb['size']['w']) && $pb['size']['w']) { 
  2118. $size = $pb['size']; 
  2119.  
  2120. if ($size['w'] == 'contain') { 
  2121. // 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. 
  2122. // Same as resize==3 
  2123. $ih = $ih * $pb['bpa']['w'] / $iw; 
  2124. $iw = $pb['bpa']['w']; 
  2125. if ($ih > $pb['bpa']['h']) { 
  2126. $iw = $iw * $pb['bpa']['h'] / $ih; 
  2127. $ih = $pb['bpa']['h']; 
  2128. } elseif ($size['w'] == 'cover') { 
  2129. // 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. 
  2130. $ih = $ih * $pb['bpa']['w'] / $iw; 
  2131. $iw = $pb['bpa']['w']; 
  2132. if ($ih < $pb['bpa']['h']) { 
  2133. $iw = $iw * $ih / $pb['bpa']['h']; 
  2134. $ih = $pb['bpa']['h']; 
  2135. } else { 
  2136. if (stristr($size['w'], '%')) { 
  2137. $size['w'] += 0; 
  2138. $size['w'] /= 100; 
  2139. $size['w'] = ($pb['bpa']['w'] * $size['w']); 
  2140. if (stristr($size['h'], '%')) { 
  2141. $size['h'] += 0; 
  2142. $size['h'] /= 100; 
  2143. $size['h'] = ($pb['bpa']['h'] * $size['h']); 
  2144. if ($size['w'] == 'auto' && $size['h'] == 'auto') { 
  2145. $iw = $iw; 
  2146. $ih = $ih; 
  2147. } elseif ($size['w'] == 'auto' && $size['h'] != 'auto') { 
  2148. $iw = $iw * $size['h'] / $ih; 
  2149. $ih = $size['h']; 
  2150. } elseif ($size['w'] != 'auto' && $size['h'] == 'auto') { 
  2151. $ih = $ih * $size['w'] / $iw; 
  2152. $iw = $size['w']; 
  2153. } else { 
  2154. $iw = $size['w']; 
  2155. $ih = $size['h']; 
  2156.  
  2157. // Number to repeat 
  2158. if ($pb['x_repeat']) { 
  2159. $nx = ceil($pb['w'] / $iw) + 1; 
  2160. } else { 
  2161. $nx = 1; 
  2162. if ($pb['y_repeat']) { 
  2163. $ny = ceil($pb['h'] / $ih) + 1; 
  2164. } else { 
  2165. $ny = 1; 
  2166.  
  2167. $x_pos = $pb['x_pos']; 
  2168. if (stristr($x_pos, '%')) { 
  2169. $x_pos += 0; 
  2170. $x_pos /= 100; 
  2171. $x_pos = ($pb['bpa']['w'] * $x_pos) - ($iw * $x_pos); 
  2172. $y_pos = $pb['y_pos']; 
  2173. if (stristr($y_pos, '%')) { 
  2174. $y_pos += 0; 
  2175. $y_pos /= 100; 
  2176. $y_pos = ($pb['bpa']['h'] * $y_pos) - ($ih * $y_pos); 
  2177. if ($nx > 1) { 
  2178. while ($x_pos > ($pb['x'] - $pb['bpa']['x'])) { 
  2179. $x_pos -= $iw; 
  2180. if ($ny > 1) { 
  2181. while ($y_pos > ($pb['y'] - $pb['bpa']['y'])) { 
  2182. $y_pos -= $ih; 
  2183. for ($xi = 0; $xi < $nx; $xi++) { 
  2184. for ($yi = 0; $yi < $ny; $yi++) { 
  2185. $x = $x0 + $x_pos + ($iw * $xi); 
  2186. $y = $y0 + $y_pos + ($ih * $yi); 
  2187. if ($pb['opacity'] > 0 && $pb['opacity'] < 1) { 
  2188. $opac = $this->SetAlpha($pb['opacity'], 'Normal', true); 
  2189. } else { 
  2190. $opac = ''; 
  2191. $s .= sprintf("q %s %.3F 0 0 %.3F %.3F %.3F cm /I%d Do Q", $opac, $iw * _MPDFK, $ih * _MPDFK, $x * _MPDFK, ($this->h - ($y + $ih)) * _MPDFK, $pb['image_id']) . "\n"; 
  2192. } else { 
  2193. if (($pb['opacity'] > 0 || $pb['opacity'] === '0') && $pb['opacity'] < 1) { 
  2194. $opac = $this->SetAlpha($pb['opacity'], 'Normal', true); 
  2195. } else { 
  2196. $opac = ''; 
  2197. $s .= sprintf('q /Pattern cs /P%d scn %s %.3F %.3F %.3F %.3F re f Q', $n, $opac, $x, $y, $w, $h) . "\n"; 
  2198. if (isset($pb['clippath']) && $pb['clippath']) { 
  2199. $s .= 'Q' . "\n"; 
  2200. if ((isset($pb['gradient']) && $pb['gradient']) || (isset($pb['image_id']) && $pb['image_id'])) { 
  2201. if ($pb['visibility'] != 'visible') 
  2202. $s .= 'EMC' . "\n"; 
  2203.  
  2204. if ($pb['z-index'] > 0) { 
  2205. $s .= "\n" . 'EMCGZ-index' . "\n"; 
  2206. $this->current_layer = 0; 
  2207. /** -- END BACKGROUNDS -- */ 
  2208. return $s; 
  2209.  
  2210. function PrintTableBackgrounds($adjustmenty = 0) 
  2211. $s = ''; 
  2212. /** -- BACKGROUNDS -- */ 
  2213. ksort($this->tableBackgrounds); 
  2214. foreach ($this->tableBackgrounds AS $bl => $pbs) { 
  2215. foreach ($pbs AS $pb) { 
  2216. if ((!isset($pb['gradient']) || !$pb['gradient']) && (!isset($pb['image_id']) || !$pb['image_id'])) { 
  2217. $s .= 'q ' . $this->SetFColor($pb['col'], true) . "\n"; 
  2218. if ($pb['col']{0} == 5) { // RGBa 
  2219. $s .= $this->SetAlpha(ord($pb['col']{4}) / 100, 'Normal', true, 'F') . "\n"; 
  2220. } elseif ($pb['col']{0} == 6) { // CMYKa 
  2221. $s .= $this->SetAlpha(ord($pb['col']{5}) / 100, 'Normal', true, 'F') . "\n"; 
  2222. $s .= sprintf('%.3F %.3F %.3F %.3F re %s Q', $pb['x'] * _MPDFK, ($this->h - $pb['y']) * _MPDFK, $pb['w'] * _MPDFK, -$pb['h'] * _MPDFK, 'f') . "\n"; 
  2223. if (isset($pb['gradient']) && $pb['gradient']) { 
  2224. if (isset($pb['clippath']) && $pb['clippath']) { 
  2225. $s .= $pb['clippath'] . "\n"; 
  2226. $s .= $this->grad->Gradient($pb['x'], $pb['y'], $pb['w'], $pb['h'], $pb['gradtype'], $pb['stops'], $pb['colorspace'], $pb['coords'], $pb['extend'], true); 
  2227. if (isset($pb['clippath']) && $pb['clippath']) { 
  2228. $s .= 'Q' . "\n"; 
  2229. if (isset($pb['image_id']) && $pb['image_id']) { // Background pattern 
  2230. $pb['y'] -= $adjustmenty; 
  2231. $pb['h'] += $adjustmenty; 
  2232. $n = count($this->patterns) + 1; 
  2233. 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']); 
  2234. $this->patterns[$n] = array('x' => $pb['x'], 'y' => $pb['y'], 'w' => $pb['w'], 'h' => $pb['h'], 'pgh' => $this->h, 'image_id' => $pb['image_id'], 'orig_w' => $orig_w, 'orig_h' => $orig_h, 'x_pos' => $pb['x_pos'], 'y_pos' => $pb['y_pos'], 'x_repeat' => $x_repeat, 'y_repeat' => $y_repeat, 'itype' => $pb['itype']); 
  2235. $x = $pb['x'] * _MPDFK; 
  2236. $y = ($this->h - $pb['y']) * _MPDFK; 
  2237. $w = $pb['w'] * _MPDFK; 
  2238. $h = -$pb['h'] * _MPDFK; 
  2239.  
  2240. // mPDF 5.7.3 
  2241. if (($this->writingHTMLfooter || $this->writingHTMLheader) && (!isset($pb['clippath']) || $pb['clippath'] == '')) { 
  2242. // Set clipping path 
  2243. $pb['clippath'] = sprintf(' q 0 w %.3F %.3F m %.3F %.3F l %.3F %.3F l %.3F %.3F l %.3F %.3F l W n ', $x, $y, $x, $y + $h, $x + $w, $y + $h, $x + $w, $y, $x, $y); 
  2244.  
  2245. if (isset($pb['clippath']) && $pb['clippath']) { 
  2246. $s .= $pb['clippath'] . "\n"; 
  2247.  
  2248. // mPDF 5.7.3 
  2249. if ($this->writingHTMLfooter || $this->writingHTMLheader) { // Write each (tiles) image rather than use as a pattern 
  2250. $iw = $pb['orig_w'] / _MPDFK; 
  2251. $ih = $pb['orig_h'] / _MPDFK; 
  2252.  
  2253. $w = $pb['w']; 
  2254. $h = $pb['h']; 
  2255. $x0 = $pb['x']; 
  2256. $y0 = $pb['y']; 
  2257.  
  2258. if (isset($pb['bpa']) && $pb['bpa']) { 
  2259. $w = $pb['bpa']['w']; 
  2260. $h = $pb['bpa']['h']; 
  2261. $x0 = $pb['bpa']['x']; 
  2262. $y0 = $pb['bpa']['y']; 
  2263. // At present 'bpa' (background page area) is not set for tablebackgrounds - only pagebackgrounds 
  2264. // For now, just set it as: 
  2265. else { 
  2266. $pb['bpa'] = array('x' => $x0, 'y' => $y0, 'w' => $w, 'h' => $h); 
  2267.  
  2268. if (isset($pb['size']['w']) && $pb['size']['w']) { 
  2269. $size = $pb['size']; 
  2270.  
  2271. if ($size['w'] == 'contain') { 
  2272. // 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. 
  2273. // Same as resize==3 
  2274. $ih = $ih * $pb['bpa']['w'] / $iw; 
  2275. $iw = $pb['bpa']['w']; 
  2276. if ($ih > $pb['bpa']['h']) { 
  2277. $iw = $iw * $pb['bpa']['h'] / $ih; 
  2278. $ih = $pb['bpa']['h']; 
  2279. } elseif ($size['w'] == 'cover') { 
  2280. // 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. 
  2281. $ih = $ih * $pb['bpa']['w'] / $iw; 
  2282. $iw = $pb['bpa']['w']; 
  2283. if ($ih < $pb['bpa']['h']) { 
  2284. $iw = $iw * $ih / $pb['bpa']['h']; 
  2285. $ih = $pb['bpa']['h']; 
  2286. } else { 
  2287. if (stristr($size['w'], '%')) { 
  2288. $size['w'] += 0; 
  2289. $size['w'] /= 100; 
  2290. $size['w'] = ($pb['bpa']['w'] * $size['w']); 
  2291. if (stristr($size['h'], '%')) { 
  2292. $size['h'] += 0; 
  2293. $size['h'] /= 100; 
  2294. $size['h'] = ($pb['bpa']['h'] * $size['h']); 
  2295. if ($size['w'] == 'auto' && $size['h'] == 'auto') { 
  2296. $iw = $iw; 
  2297. $ih = $ih; 
  2298. } elseif ($size['w'] == 'auto' && $size['h'] != 'auto') { 
  2299. $iw = $iw * $size['h'] / $ih; 
  2300. $ih = $size['h']; 
  2301. } elseif ($size['w'] != 'auto' && $size['h'] == 'auto') { 
  2302. $ih = $ih * $size['w'] / $iw; 
  2303. $iw = $size['w']; 
  2304. } else { 
  2305. $iw = $size['w']; 
  2306. $ih = $size['h']; 
  2307.  
  2308. // Number to repeat 
  2309. if (isset($pb['x_repeat']) && $pb['x_repeat']) { 
  2310. $nx = ceil($pb['w'] / $iw) + 1; 
  2311. } else { 
  2312. $nx = 1; 
  2313. if (isset($pb['y_repeat']) && $pb['y_repeat']) { 
  2314. $ny = ceil($pb['h'] / $ih) + 1; 
  2315. } else { 
  2316. $ny = 1; 
  2317.  
  2318. $x_pos = $pb['x_pos']; 
  2319. if (stristr($x_pos, '%')) { 
  2320. $x_pos += 0; 
  2321. $x_pos /= 100; 
  2322. $x_pos = ($pb['bpa']['w'] * $x_pos) - ($iw * $x_pos); 
  2323. $y_pos = $pb['y_pos']; 
  2324. if (stristr($y_pos, '%')) { 
  2325. $y_pos += 0; 
  2326. $y_pos /= 100; 
  2327. $y_pos = ($pb['bpa']['h'] * $y_pos) - ($ih * $y_pos); 
  2328. if ($nx > 1) { 
  2329. while ($x_pos > ($pb['x'] - $pb['bpa']['x'])) { 
  2330. $x_pos -= $iw; 
  2331. if ($ny > 1) { 
  2332. while ($y_pos > ($pb['y'] - $pb['bpa']['y'])) { 
  2333. $y_pos -= $ih; 
  2334. for ($xi = 0; $xi < $nx; $xi++) { 
  2335. for ($yi = 0; $yi < $ny; $yi++) { 
  2336. $x = $x0 + $x_pos + ($iw * $xi); 
  2337. $y = $y0 + $y_pos + ($ih * $yi); 
  2338. if ($pb['opacity'] > 0 && $pb['opacity'] < 1) { 
  2339. $opac = $this->SetAlpha($pb['opacity'], 'Normal', true); 
  2340. } else { 
  2341. $opac = ''; 
  2342. $s .= sprintf("q %s %.3F 0 0 %.3F %.3F %.3F cm /I%d Do Q", $opac, $iw * _MPDFK, $ih * _MPDFK, $x * _MPDFK, ($this->h - ($y + $ih)) * _MPDFK, $pb['image_id']) . "\n"; 
  2343. } else { 
  2344. if (($pb['opacity'] > 0 || $pb['opacity'] === '0') && $pb['opacity'] < 1) { 
  2345. $opac = $this->SetAlpha($pb['opacity'], 'Normal', true); 
  2346. } else { 
  2347. $opac = ''; 
  2348. $s .= sprintf('q /Pattern cs /P%d scn %s %.3F %.3F %.3F %.3F re f Q', $n, $opac, $x, $y, $w, $h) . "\n"; 
  2349.  
  2350. if (isset($pb['clippath']) && $pb['clippath']) { 
  2351. $s .= 'Q' . "\n"; 
  2352. /** -- END BACKGROUNDS -- */ 
  2353. return $s; 
  2354.  
  2355. function BeginLayer($id) 
  2356. if ($this->current_layer > 0) 
  2357. $this->EndLayer(); 
  2358. if ($id < 1) { 
  2359. return false; 
  2360. if (!isset($this->layers[$id])) { 
  2361. $this->layers[$id] = array('name' => 'Layer ' . ($id)); 
  2362. if (($this->PDFA || $this->PDFX)) { 
  2363. $this->PDFAXwarnings[] = "Cannot use layers when using PDFA or PDFX"; 
  2364. return ''; 
  2365. } elseif (!$this->PDFA && !$this->PDFX) { 
  2366. $this->pdf_version = '1.5'; 
  2367. $this->current_layer = $id; 
  2368. $this->_out('/OCZ-index /ZI' . $id . ' BDC'); 
  2369.  
  2370. $this->pageoutput[$this->page] = array(); 
  2371.  
  2372. function EndLayer() 
  2373. if ($this->current_layer > 0) { 
  2374. $this->_out('EMCZ-index'); 
  2375. $this->current_layer = 0; 
  2376.  
  2377. function AddPageByArray($a) 
  2378. if (!is_array($a)) { 
  2379. $a = array(); 
  2380. $orientation = (isset($a['orientation']) ? $a['orientation'] : ''); 
  2381. $condition = (isset($a['condition']) ? $a['condition'] : (isset($a['type']) ? $a['type'] : '')); 
  2382. $resetpagenum = (isset($a['resetpagenum']) ? $a['resetpagenum'] : ''); 
  2383. $pagenumstyle = (isset($a['pagenumstyle']) ? $a['pagenumstyle'] : ''); 
  2384. $suppress = (isset($a['suppress']) ? $a['suppress'] : ''); 
  2385. $mgl = (isset($a['mgl']) ? $a['mgl'] : (isset($a['margin-left']) ? $a['margin-left'] : '')); 
  2386. $mgr = (isset($a['mgr']) ? $a['mgr'] : (isset($a['margin-right']) ? $a['margin-right'] : '')); 
  2387. $mgt = (isset($a['mgt']) ? $a['mgt'] : (isset($a['margin-top']) ? $a['margin-top'] : '')); 
  2388. $mgb = (isset($a['mgb']) ? $a['mgb'] : (isset($a['margin-bottom']) ? $a['margin-bottom'] : '')); 
  2389. $mgh = (isset($a['mgh']) ? $a['mgh'] : (isset($a['margin-header']) ? $a['margin-header'] : '')); 
  2390. $mgf = (isset($a['mgf']) ? $a['mgf'] : (isset($a['margin-footer']) ? $a['margin-footer'] : '')); 
  2391. $ohname = (isset($a['ohname']) ? $a['ohname'] : (isset($a['odd-header-name']) ? $a['odd-header-name'] : '')); 
  2392. $ehname = (isset($a['ehname']) ? $a['ehname'] : (isset($a['even-header-name']) ? $a['even-header-name'] : '')); 
  2393. $ofname = (isset($a['ofname']) ? $a['ofname'] : (isset($a['odd-footer-name']) ? $a['odd-footer-name'] : '')); 
  2394. $efname = (isset($a['efname']) ? $a['efname'] : (isset($a['even-footer-name']) ? $a['even-footer-name'] : '')); 
  2395. $ohvalue = (isset($a['ohvalue']) ? $a['ohvalue'] : (isset($a['odd-header-value']) ? $a['odd-header-value'] : 0)); 
  2396. $ehvalue = (isset($a['ehvalue']) ? $a['ehvalue'] : (isset($a['even-header-value']) ? $a['even-header-value'] : 0)); 
  2397. $ofvalue = (isset($a['ofvalue']) ? $a['ofvalue'] : (isset($a['odd-footer-value']) ? $a['odd-footer-value'] : 0)); 
  2398. $efvalue = (isset($a['efvalue']) ? $a['efvalue'] : (isset($a['even-footer-value']) ? $a['even-footer-value'] : 0)); 
  2399. $pagesel = (isset($a['pagesel']) ? $a['pagesel'] : (isset($a['pageselector']) ? $a['pageselector'] : '')); 
  2400. $newformat = (isset($a['newformat']) ? $a['newformat'] : (isset($a['sheet-size']) ? $a['sheet-size'] : '')); 
  2401.  
  2402. $this->AddPage($orientation, $condition, $resetpagenum, $pagenumstyle, $suppress, $mgl, $mgr, $mgt, $mgb, $mgh, $mgf, $ohname, $ehname, $ofname, $efname, $ohvalue, $ehvalue, $ofvalue, $efvalue, $pagesel, $newformat); 
  2403.  
  2404. // mPDF 6 pagebreaktype 
  2405. function _preForcedPagebreak($pagebreaktype) 
  2406. if ($pagebreaktype == 'cloneall') { 
  2407. // Close any open block tags 
  2408. $arr = array(); 
  2409. $ai = 0; 
  2410. for ($b = $this->blklvl; $b > 0; $b--) { 
  2411. $this->tag->CloseTag($this->blk[$b]['tag'], $arr, $ai); 
  2412. if ($this->blklvl == 0 && !empty($this->textbuffer)) { //Output previously buffered content 
  2413. $this->printbuffer($this->textbuffer, 1); 
  2414. $this->textbuffer = array(); 
  2415. } elseif ($pagebreaktype == 'clonebycss') { 
  2416. // Close open block tags whilst box-decoration-break==clone 
  2417. $arr = array(); 
  2418. $ai = 0; 
  2419. for ($b = $this->blklvl; $b > 0; $b--) { 
  2420. if (isset($this->blk[$b]['box_decoration_break']) && $this->blk[$b]['box_decoration_break'] == 'clone') { 
  2421. $this->tag->CloseTag($this->blk[$b]['tag'], $arr, $ai); 
  2422. } else { 
  2423. if ($b == $this->blklvl && !empty($this->textbuffer)) { //Output previously buffered content 
  2424. $this->printbuffer($this->textbuffer, 1); 
  2425. $this->textbuffer = array(); 
  2426. break; 
  2427. } elseif (!empty($this->textbuffer)) { //Output previously buffered content 
  2428. $this->printbuffer($this->textbuffer, 1); 
  2429. $this->textbuffer = array(); 
  2430.  
  2431. // mPDF 6 pagebreaktype 
  2432. function _postForcedPagebreak($pagebreaktype, $startpage, $save_blk, $save_blklvl) 
  2433. if ($pagebreaktype == 'cloneall') { 
  2434. $this->blk = array(); 
  2435. $this->blk[0] = $save_blk[0]; 
  2436. // Re-open block tags 
  2437. $this->blklvl = 0; 
  2438. $arr = array(); 
  2439. $i = 0; 
  2440. for ($b = 1; $b <= $save_blklvl; $b++) { 
  2441. $this->tag->OpenTag($save_blk[$b]['tag'], $save_blk[$b]['attr'], $arr, $i); 
  2442. } elseif ($pagebreaktype == 'clonebycss') { 
  2443. $this->blk = array(); 
  2444. $this->blk[0] = $save_blk[0]; 
  2445. // Don't re-open tags for lowest level elements - so need to do some adjustments 
  2446. for ($b = 1; $b <= $this->blklvl; $b++) { 
  2447. $this->blk[$b] = $save_blk[$b]; 
  2448. $this->blk[$b]['startpage'] = 0; 
  2449. $this->blk[$b]['y0'] = $this->y; // ?? $this->tMargin 
  2450. if (($this->page - $startpage) % 2) { 
  2451. if (isset($this->blk[$b]['x0'])) { 
  2452. $this->blk[$b]['x0'] += $this->MarginCorrection; 
  2453. } else { 
  2454. $this->blk[$b]['x0'] = $this->MarginCorrection; 
  2455. //for Float DIV 
  2456. $this->blk[$b]['marginCorrected'][$this->page] = true; 
  2457.  
  2458. // Re-open block tags for any that have box_decoration_break==clone 
  2459. $arr = array(); 
  2460. $i = 0; 
  2461. for ($b = $this->blklvl + 1; $b <= $save_blklvl; $b++) { 
  2462. if ($b < $this->blklvl) { 
  2463. $this->lastblocklevelchange = -1; 
  2464. $this->tag->OpenTag($save_blk[$b]['tag'], $save_blk[$b]['attr'], $arr, $i); 
  2465. if ($this->blk[$this->blklvl]['box_decoration_break'] != 'clone') { 
  2466. $this->lastblocklevelchange = -1; 
  2467. } else { 
  2468. $this->lastblocklevelchange = -1; 
  2469.  
  2470. function AddPage($orientation = '', $condition = '', $resetpagenum = '', $pagenumstyle = '', $suppress = '', $mgl = '', $mgr = '', $mgt = '', $mgb = '', $mgh = '', $mgf = '', $ohname = '', $ehname = '', $ofname = '', $efname = '', $ohvalue = 0, $ehvalue = 0, $ofvalue = 0, $efvalue = 0, $pagesel = '', $newformat = '') 
  2471.  
  2472. /** -- CSS-FLOAT -- */ 
  2473. // Float DIV 
  2474. // Cannot do with columns on, or if any change in page orientation/margins etc. 
  2475. // If next page already exists - i.e background /headers and footers already written 
  2476. if ($this->state > 0 && $this->page < count($this->pages)) { 
  2477. $bak_cml = $this->cMarginL; 
  2478. $bak_cmr = $this->cMarginR; 
  2479. $bak_dw = $this->divwidth; 
  2480. // Paint Div Border if necessary 
  2481. if ($this->blklvl > 0) { 
  2482. $save_tr = $this->table_rotate; // *TABLES* 
  2483. $this->table_rotate = 0; // *TABLES* 
  2484. if (($this->y > $this->blk[$this->blklvl]['y0']) || $this->flowingBlockAttr['is_table']) { 
  2485. $toplvl = $this->blklvl; 
  2486. } else { 
  2487. $toplvl = $this->blklvl - 1; 
  2488. $sy = $this->y; 
  2489. for ($bl = 1; $bl <= $toplvl; $bl++) { 
  2490. $this->PaintDivBB('pagebottom', 0, $bl); 
  2491. $this->y = $sy; 
  2492. $this->table_rotate = $save_tr; // *TABLES* 
  2493. $s = $this->PrintPageBackgrounds(); 
  2494.  
  2495. // Writes after the marker so not overwritten later by page background etc. 
  2496. $this->pages[$this->page] = preg_replace('/(___BACKGROUND___PATTERNS' . $this->uniqstr . ')/', '\\1' . "\n" . $s . "\n", $this->pages[$this->page]); 
  2497. $this->pageBackgrounds = array(); 
  2498. $family = $this->FontFamily; 
  2499. $style = $this->FontStyle; 
  2500. $size = $this->FontSizePt; 
  2501. $lw = $this->LineWidth; 
  2502. $dc = $this->DrawColor; 
  2503. $fc = $this->FillColor; 
  2504. $tc = $this->TextColor; 
  2505. $cf = $this->ColorFlag; 
  2506.  
  2507. $this->printfloatbuffer(); 
  2508.  
  2509. //Move to next page 
  2510. $this->page++; 
  2511. $this->ResetMargins(); 
  2512. $this->SetAutoPageBreak($this->autoPageBreak, $this->bMargin); 
  2513. $this->x = $this->lMargin; 
  2514. $this->y = $this->tMargin; 
  2515. $this->FontFamily = ''; 
  2516. $this->_out('2 J'); 
  2517. $this->LineWidth = $lw; 
  2518. $this->_out(sprintf('%.3F w', $lw * _MPDFK)); 
  2519. if ($family) 
  2520. $this->SetFont($family, $style, $size, true, true); 
  2521. $this->DrawColor = $dc; 
  2522. if ($dc != $this->defDrawColor) 
  2523. $this->_out($dc); 
  2524. $this->FillColor = $fc; 
  2525. if ($fc != $this->defFillColor) 
  2526. $this->_out($fc); 
  2527. $this->TextColor = $tc; 
  2528. $this->ColorFlag = $cf; 
  2529. for ($bl = 1; $bl <= $this->blklvl; $bl++) { 
  2530. $this->blk[$bl]['y0'] = $this->y; 
  2531. // Don't correct more than once for background DIV containing a Float 
  2532. if (!isset($this->blk[$bl]['marginCorrected'][$this->page])) { 
  2533. $this->blk[$bl]['x0'] += $this->MarginCorrection; 
  2534. $this->blk[$bl]['marginCorrected'][$this->page] = true; 
  2535. $this->cMarginL = $bak_cml; 
  2536. $this->cMarginR = $bak_cmr; 
  2537. $this->divwidth = $bak_dw; 
  2538. return ''; 
  2539. /** -- END CSS-FLOAT -- */ 
  2540.  
  2541. //Start a new page 
  2542. if ($this->state == 0) 
  2543. $this->Open(); 
  2544.  
  2545. $bak_cml = $this->cMarginL; 
  2546. $bak_cmr = $this->cMarginR; 
  2547. $bak_dw = $this->divwidth; 
  2548.  
  2549.  
  2550. $bak_lh = $this->lineheight; 
  2551.  
  2552. $orientation = substr(strtoupper($orientation), 0, 1); 
  2553. $condition = strtoupper($condition); 
  2554.  
  2555.  
  2556. if ($condition == 'E') { // only adds new page if needed to create an Even page 
  2557. if (!$this->mirrorMargins || ($this->page) % 2 == 0) { 
  2558. return false; 
  2559. } elseif ($condition == 'O') { // only adds new page if needed to create an Odd page 
  2560. if (!$this->mirrorMargins || ($this->page) % 2 == 1) { 
  2561. return false; 
  2562. } elseif ($condition == 'NEXT-EVEN') { // always adds at least one new page to create an Even page 
  2563. if (!$this->mirrorMargins) { 
  2564. $condition = ''; 
  2565. } else { 
  2566. if ($pagesel) { 
  2567. $pbch = $pagesel; 
  2568. $pagesel = ''; 
  2569. } // *CSS-PAGE* 
  2570. else { 
  2571. $pbch = false; 
  2572. } // *CSS-PAGE* 
  2573. $this->AddPage($this->CurOrientation, 'O'); 
  2574. $this->extrapagebreak = true; // mPDF 6 pagebreaktype 
  2575. if ($pbch) { 
  2576. $pagesel = $pbch; 
  2577. } // *CSS-PAGE* 
  2578. $condition = ''; 
  2579. } elseif ($condition == 'NEXT-ODD') { // always adds at least one new page to create an Odd page 
  2580. if (!$this->mirrorMargins) { 
  2581. $condition = ''; 
  2582. } else { 
  2583. if ($pagesel) { 
  2584. $pbch = $pagesel; 
  2585. $pagesel = ''; 
  2586. } // *CSS-PAGE* 
  2587. else { 
  2588. $pbch = false; 
  2589. } // *CSS-PAGE* 
  2590. $this->AddPage($this->CurOrientation, 'E'); 
  2591. $this->extrapagebreak = true; // mPDF 6 pagebreaktype 
  2592. if ($pbch) { 
  2593. $pagesel = $pbch; 
  2594. } // *CSS-PAGE* 
  2595. $condition = ''; 
  2596.  
  2597.  
  2598. if ($resetpagenum || $pagenumstyle || $suppress) { 
  2599. $this->PageNumSubstitutions[] = array('from' => ($this->page + 1), 'reset' => $resetpagenum, 'type' => $pagenumstyle, 'suppress' => $suppress); 
  2600.  
  2601.  
  2602. $save_tr = $this->table_rotate; // *TABLES* 
  2603. $this->table_rotate = 0; // *TABLES* 
  2604. $save_kwt = $this->kwt; 
  2605. $this->kwt = 0; 
  2606. $save_layer = $this->current_layer; 
  2607. $save_vis = $this->visibility; 
  2608.  
  2609. if ($this->visibility != 'visible') 
  2610. $this->SetVisibility('visible'); 
  2611. $this->EndLayer(); 
  2612.  
  2613. // Paint Div Border if necessary 
  2614. //PAINTS BACKGROUND COLOUR OR BORDERS for DIV - DISABLED FOR COLUMNS (cf. AcceptPageBreak) AT PRESENT in ->PaintDivBB 
  2615. if (!$this->ColActive && $this->blklvl > 0) { 
  2616. if (isset($this->blk[$this->blklvl]['y0']) && $this->y == $this->blk[$this->blklvl]['y0'] && !$this->extrapagebreak && !$this->blk[$this->blklvl]['float']) { // mPDF 6 pagebreaktype 
  2617. if (isset($this->blk[$this->blklvl]['startpage'])) { 
  2618. $this->blk[$this->blklvl]['startpage'] ++; 
  2619. } else { 
  2620. $this->blk[$this->blklvl]['startpage'] = 1; 
  2621. if ((isset($this->blk[$this->blklvl]['y0']) && $this->y > $this->blk[$this->blklvl]['y0']) || $this->flowingBlockAttr['is_table'] || $this->extrapagebreak) { 
  2622. $toplvl = $this->blklvl; 
  2623. } // mPDF 6 pagebreaktype 
  2624. else { 
  2625. $toplvl = $this->blklvl - 1; 
  2626. $sy = $this->y; 
  2627. for ($bl = 1; $bl <= $toplvl; $bl++) { 
  2628.  
  2629. if (isset($this->blk[$bl]['z-index']) && $this->blk[$bl]['z-index'] > 0) { 
  2630. $this->BeginLayer($this->blk[$bl]['z-index']); 
  2631. if (isset($this->blk[$bl]['visibility']) && $this->blk[$bl]['visibility'] && $this->blk[$bl]['visibility'] != 'visible') { 
  2632. $this->SetVisibility($this->blk[$bl]['visibility']); 
  2633. $this->PaintDivBB('pagebottom', 0, $bl); 
  2634. $this->y = $sy; 
  2635. // RESET block y0 and x0 - see below 
  2636. $this->extrapagebreak = false; // mPDF 6 pagebreaktype 
  2637.  
  2638. if ($this->visibility != 'visible') 
  2639. $this->SetVisibility('visible'); 
  2640. $this->EndLayer(); 
  2641.  
  2642. // BODY Backgrounds 
  2643. if ($this->page > 0) { 
  2644. $s = ''; 
  2645. $s .= $this->PrintBodyBackgrounds(); 
  2646.  
  2647. $s .= $this->PrintPageBackgrounds(); 
  2648. $this->pages[$this->page] = preg_replace('/(___BACKGROUND___PATTERNS' . $this->uniqstr . ')/', "\n" . $s . "\n" . '\\1', $this->pages[$this->page]); 
  2649. $this->pageBackgrounds = array(); 
  2650.  
  2651. $save_kt = $this->keep_block_together; 
  2652. $this->keep_block_together = 0; 
  2653.  
  2654. $save_cols = false; 
  2655. /** -- COLUMNS -- */ 
  2656. if ($this->ColActive) { 
  2657. $save_cols = true; 
  2658. $save_nbcol = $this->NbCol; // other values of gap and vAlign will not change by setting Columns off 
  2659. $this->SetColumns(0); 
  2660. /** -- END COLUMNS -- */ 
  2661.  
  2662.  
  2663. $family = $this->FontFamily; 
  2664. $style = $this->FontStyle; 
  2665. $size = $this->FontSizePt; 
  2666. $this->ColumnAdjust = true; // enables column height adjustment for the page 
  2667. $lw = $this->LineWidth; 
  2668. $dc = $this->DrawColor; 
  2669. $fc = $this->FillColor; 
  2670. $tc = $this->TextColor; 
  2671. $cf = $this->ColorFlag; 
  2672. if ($this->page > 0) { 
  2673. //Page footer 
  2674. $this->InFooter = true; 
  2675.  
  2676. $this->Reset(); 
  2677. $this->pageoutput[$this->page] = array(); 
  2678.  
  2679. $this->Footer(); 
  2680. //Close page 
  2681. $this->_endpage(); 
  2682.  
  2683.  
  2684. //Start new page 
  2685. $this->_beginpage($orientation, $mgl, $mgr, $mgt, $mgb, $mgh, $mgf, $ohname, $ehname, $ofname, $efname, $ohvalue, $ehvalue, $ofvalue, $efvalue, $pagesel, $newformat); 
  2686. if ($this->docTemplate) { 
  2687. $pagecount = $this->SetSourceFile($this->docTemplate); 
  2688. if (($this->page - $this->docTemplateStart) > $pagecount) { 
  2689. if ($this->docTemplateContinue) { 
  2690. $tplIdx = $this->ImportPage($pagecount); 
  2691. $this->UseTemplate($tplIdx); 
  2692. } else { 
  2693. $tplIdx = $this->ImportPage(($this->page - $this->docTemplateStart)); 
  2694. $this->UseTemplate($tplIdx); 
  2695. if ($this->pageTemplate) { 
  2696. $this->UseTemplate($this->pageTemplate); 
  2697.  
  2698. // Tiling Patterns 
  2699. $this->_out('___PAGE___START' . $this->uniqstr); 
  2700. $this->_out('___BACKGROUND___PATTERNS' . $this->uniqstr); 
  2701. $this->_out('___HEADER___MARKER' . $this->uniqstr); 
  2702. $this->pageBackgrounds = array(); 
  2703.  
  2704. //Set line cap style to square 
  2705. $this->SetLineCap(2); 
  2706. //Set line width 
  2707. $this->LineWidth = $lw; 
  2708. $this->_out(sprintf('%.3F w', $lw * _MPDFK)); 
  2709. //Set font 
  2710. if ($family) 
  2711. $this->SetFont($family, $style, $size, true, true); // forces write 
  2712.  
  2713. //Set colors 
  2714. $this->DrawColor = $dc; 
  2715. if ($dc != $this->defDrawColor) 
  2716. $this->_out($dc); 
  2717. $this->FillColor = $fc; 
  2718. if ($fc != $this->defFillColor) 
  2719. $this->_out($fc); 
  2720. $this->TextColor = $tc; 
  2721. $this->ColorFlag = $cf; 
  2722.  
  2723. //Page header 
  2724. $this->Header(); 
  2725.  
  2726. //Restore line width 
  2727. if ($this->LineWidth != $lw) { 
  2728. $this->LineWidth = $lw; 
  2729. $this->_out(sprintf('%.3F w', $lw * _MPDFK)); 
  2730. //Restore font 
  2731. if ($family) 
  2732. $this->SetFont($family, $style, $size, true, true); // forces write 
  2733.  
  2734. //Restore colors 
  2735. if ($this->DrawColor != $dc) { 
  2736. $this->DrawColor = $dc; 
  2737. $this->_out($dc); 
  2738. if ($this->FillColor != $fc) { 
  2739. $this->FillColor = $fc; 
  2740. $this->_out($fc); 
  2741. $this->TextColor = $tc; 
  2742. $this->ColorFlag = $cf; 
  2743. $this->InFooter = false; 
  2744.  
  2745. if ($save_layer > 0) 
  2746. $this->BeginLayer($save_layer); 
  2747.  
  2748. if ($save_vis != 'visible') 
  2749. $this->SetVisibility($save_vis); 
  2750.  
  2751. /** -- COLUMNS -- */ 
  2752. if ($save_cols) { 
  2753. // Restore columns 
  2754. $this->SetColumns($save_nbcol, $this->colvAlign, $this->ColGap); 
  2755. if ($this->ColActive) { 
  2756. $this->SetCol(0); 
  2757. /** -- END COLUMNS -- */ 
  2758.  
  2759.  
  2760. //RESET BLOCK BORDER TOP 
  2761. if (!$this->ColActive) { 
  2762. for ($bl = 1; $bl <= $this->blklvl; $bl++) { 
  2763. $this->blk[$bl]['y0'] = $this->y; 
  2764. if (isset($this->blk[$bl]['x0'])) { 
  2765. $this->blk[$bl]['x0'] += $this->MarginCorrection; 
  2766. } else { 
  2767. $this->blk[$bl]['x0'] = $this->MarginCorrection; 
  2768. // Added mPDF 3.0 Float DIV 
  2769. $this->blk[$bl]['marginCorrected'][$this->page] = true; 
  2770.  
  2771.  
  2772. $this->table_rotate = $save_tr; // *TABLES* 
  2773. $this->kwt = $save_kwt; 
  2774.  
  2775. $this->keep_block_together = $save_kt; 
  2776.  
  2777. $this->cMarginL = $bak_cml; 
  2778. $this->cMarginR = $bak_cmr; 
  2779. $this->divwidth = $bak_dw; 
  2780.  
  2781. $this->lineheight = $bak_lh; 
  2782.  
  2783. function PageNo() 
  2784. //Get current page number 
  2785. return $this->page; 
  2786.  
  2787. function AddSpotColorsFromFile($file) 
  2788. $colors = @file($file); 
  2789. if (!$colors) { 
  2790. throw new MpdfException("Cannot load spot colors file - " . $file); 
  2791. foreach ($colors AS $sc) { 
  2792. list($name, $c, $m, $y, $k) = preg_split("/\t/", $sc); 
  2793. $c = intval($c); 
  2794. $m = intval($m); 
  2795. $y = intval($y); 
  2796. $k = intval($k); 
  2797. $this->AddSpotColor($name, $c, $m, $y, $k); 
  2798.  
  2799. function AddSpotColor($name, $c, $m, $y, $k) 
  2800. $name = strtoupper(trim($name)); 
  2801. if (!isset($this->spotColors[$name])) { 
  2802. $i = count($this->spotColors) + 1; 
  2803. $this->spotColors[$name] = array('i' => $i, 'c' => $c, 'm' => $m, 'y' => $y, 'k' => $k); 
  2804. $this->spotColorIDs[$i] = $name; 
  2805.  
  2806. function SetColor($col, $type = '') 
  2807. $out = ''; 
  2808. if (!$col) { 
  2809. return ''; 
  2810. } // mPDF 6 
  2811. if ($col{0} == 3 || $col{0} == 5) { // RGB / RGBa 
  2812. $out = sprintf('%.3F %.3F %.3F rg', ord($col{1}) / 255, ord($col{2}) / 255, ord($col{3}) / 255); 
  2813. } elseif ($col{0} == 1) { // GRAYSCALE 
  2814. $out = sprintf('%.3F g', ord($col{1}) / 255); 
  2815. } elseif ($col{0} == 2) { // SPOT COLOR 
  2816. $out = sprintf('/CS%d cs %.3F scn', ord($col{1}), ord($col{2}) / 100); 
  2817. } elseif ($col{0} == 4 || $col{0} == 6) { // CMYK / CMYKa 
  2818. $out = sprintf('%.3F %.3F %.3F %.3F k', ord($col{1}) / 100, ord($col{2}) / 100, ord($col{3}) / 100, ord($col{4}) / 100); 
  2819. if ($type == 'Draw') { 
  2820. $out = strtoupper($out); 
  2821. } // e.g. rg => RG 
  2822. elseif ($type == 'CodeOnly') { 
  2823. $out = preg_replace('/\s(rg|g|k)/', '', $out); 
  2824. return $out; 
  2825.  
  2826. function SetDColor($col, $return = false) 
  2827. $out = $this->SetColor($col, 'Draw'); 
  2828. if ($return) { 
  2829. return $out; 
  2830. if ($out == '') { 
  2831. return ''; 
  2832. $this->DrawColor = $out; 
  2833. if ($this->page > 0 && ((isset($this->pageoutput[$this->page]['DrawColor']) && $this->pageoutput[$this->page]['DrawColor'] != $this->DrawColor) || !isset($this->pageoutput[$this->page]['DrawColor']))) { 
  2834. $this->_out($this->DrawColor); 
  2835. $this->pageoutput[$this->page]['DrawColor'] = $this->DrawColor; 
  2836.  
  2837. function SetFColor($col, $return = false) 
  2838. $out = $this->SetColor($col, 'Fill'); 
  2839. if ($return) { 
  2840. return $out; 
  2841. if ($out == '') { 
  2842. return ''; 
  2843. $this->FillColor = $out; 
  2844. $this->ColorFlag = ($out != $this->TextColor); 
  2845. if ($this->page > 0 && ((isset($this->pageoutput[$this->page]['FillColor']) && $this->pageoutput[$this->page]['FillColor'] != $this->FillColor) || !isset($this->pageoutput[$this->page]['FillColor']))) { 
  2846. $this->_out($this->FillColor); 
  2847. $this->pageoutput[$this->page]['FillColor'] = $this->FillColor; 
  2848.  
  2849. function SetTColor($col, $return = false) 
  2850. $out = $this->SetColor($col, 'Text'); 
  2851. if ($return) { 
  2852. return $out; 
  2853. if ($out == '') { 
  2854. return ''; 
  2855. $this->TextColor = $out; 
  2856. $this->ColorFlag = ($this->FillColor != $out); 
  2857.  
  2858. function SetDrawColor($r, $g = -1, $b = -1, $col4 = -1, $return = false) 
  2859. //Set color for all stroking operations 
  2860. $col = array(); 
  2861. if (($r == 0 and $g == 0 and $b == 0 && $col4 == -1) or $g == -1) { 
  2862. $col = $this->ConvertColor($r); 
  2863. } elseif ($col4 == -1) { 
  2864. $col = $this->ConvertColor('rgb(' . $r . ', ' . $g . ', ' . $b . ')'); 
  2865. } else { 
  2866. $col = $this->ConvertColor('cmyk(' . $r . ', ' . $g . ', ' . $b . ', ' . $col4 . ')'); 
  2867. $out = $this->SetDColor($col, $return); 
  2868. return $out; 
  2869.  
  2870. function SetFillColor($r, $g = -1, $b = -1, $col4 = -1, $return = false) 
  2871. //Set color for all filling operations 
  2872. $col = array(); 
  2873. if (($r == 0 and $g == 0 and $b == 0 && $col4 == -1) or $g == -1) { 
  2874. $col = $this->ConvertColor($r); 
  2875. } elseif ($col4 == -1) { 
  2876. $col = $this->ConvertColor('rgb(' . $r . ', ' . $g . ', ' . $b . ')'); 
  2877. } else { 
  2878. $col = $this->ConvertColor('cmyk(' . $r . ', ' . $g . ', ' . $b . ', ' . $col4 . ')'); 
  2879. $out = $this->SetFColor($col, $return); 
  2880. return $out; 
  2881.  
  2882. function SetTextColor($r, $g = -1, $b = -1, $col4 = -1, $return = false) 
  2883. //Set color for text 
  2884. $col = array(); 
  2885. if (($r == 0 and $g == 0 and $b == 0 && $col4 == -1) or $g == -1) { 
  2886. $col = $this->ConvertColor($r); 
  2887. } elseif ($col4 == -1) { 
  2888. $col = $this->ConvertColor('rgb(' . $r . ', ' . $g . ', ' . $b . ')'); 
  2889. } else { 
  2890. $col = $this->ConvertColor('cmyk(' . $r . ', ' . $g . ', ' . $b . ', ' . $col4 . ')'); 
  2891. $out = $this->SetTColor($col, $return); 
  2892. return $out; 
  2893.  
  2894. function _getCharWidth(&$cw, $u, $isdef = true) 
  2895. $w = 0; 
  2896. if ($u == 0) { 
  2897. $w = false; 
  2898. } elseif (isset($cw[$u * 2 + 1])) { 
  2899. $w = (ord($cw[$u * 2]) << 8) + ord($cw[$u * 2 + 1]); 
  2900. if ($w == 65535) { 
  2901. return 0; 
  2902. } elseif ($w) { 
  2903. return $w; 
  2904. } elseif ($isdef) { 
  2905. return false; 
  2906. } else { 
  2907. return 0; 
  2908.  
  2909. function _charDefined(&$cw, $u) 
  2910. $w = 0; 
  2911. if ($u == 0) { 
  2912. return false; 
  2913. if (isset($cw[$u * 2 + 1])) { 
  2914. $w = (ord($cw[$u * 2]) << 8) + ord($cw[$u * 2 + 1]); 
  2915. if ($w) { 
  2916. return true; 
  2917. } else { 
  2918. return false; 
  2919.  
  2920. function GetCharWidthCore($c) 
  2921. //Get width of a single character in the current Core font 
  2922. $c = (string) $c; 
  2923. $w = 0; 
  2924. // Soft Hyphens chr(173) 
  2925. if ($c == chr(173) && $this->FontFamily != 'csymbol' && $this->FontFamily != 'czapfdingbats') { 
  2926. return 0; 
  2927. } elseif (($this->textvar & FC_SMALLCAPS) && isset($this->upperCase[ord($c)])) { // mPDF 5.7.1 
  2928. $charw = $this->CurrentFont['cw'][chr($this->upperCase[ord($c)])]; 
  2929. if ($charw !== false) { 
  2930. $charw = $charw * $this->smCapsScale * $this->smCapsStretch / 100; 
  2931. $w+=$charw; 
  2932. } elseif (isset($this->CurrentFont['cw'][$c])) { 
  2933. $w += $this->CurrentFont['cw'][$c]; 
  2934. } elseif (isset($this->CurrentFont['cw'][ord($c)])) { 
  2935. $w += $this->CurrentFont['cw'][ord($c)]; 
  2936. $w *= ($this->FontSize / 1000); 
  2937. if ($this->minwSpacing || $this->fixedlSpacing) { 
  2938. if ($c == ' ') 
  2939. $nb_spaces = 1; 
  2940. else 
  2941. $nb_spaces = 0; 
  2942. $w += $this->fixedlSpacing + ($nb_spaces * $this->minwSpacing); 
  2943. return ($w); 
  2944.  
  2945. function GetCharWidthNonCore($c, $addSubset = true) 
  2946. //Get width of a single character in the current Non-Core font 
  2947. $c = (string) $c; 
  2948. $w = 0; 
  2949. $unicode = $this->UTF8StringToArray($c, $addSubset); 
  2950. $char = $unicode[0]; 
  2951. /** -- CJK-FONTS -- */ 
  2952. if ($this->CurrentFont['type'] == 'Type0') { // CJK Adobe fonts 
  2953. if ($char == 173) { 
  2954. return 0; 
  2955. } // Soft Hyphens 
  2956. elseif (isset($this->CurrentFont['cw'][$char])) { 
  2957. $w+=$this->CurrentFont['cw'][$char]; 
  2958. } elseif (isset($this->CurrentFont['MissingWidth'])) { 
  2959. $w += $this->CurrentFont['MissingWidth']; 
  2960. } else { 
  2961. $w += 500; 
  2962. } else { 
  2963. /** -- END CJK-FONTS -- */ 
  2964. if ($char == 173) { 
  2965. return 0; 
  2966. } // Soft Hyphens 
  2967. elseif (($this->textvar & FC_SMALLCAPS) && isset($this->upperCase[$char])) { // mPDF 5.7.1 
  2968. $charw = $this->_getCharWidth($this->CurrentFont['cw'], $this->upperCase[$char]); 
  2969. if ($charw !== false) { 
  2970. $charw = $charw * $this->smCapsScale * $this->smCapsStretch / 100; 
  2971. $w+=$charw; 
  2972. } elseif (isset($this->CurrentFont['desc']['MissingWidth'])) { 
  2973. $w += $this->CurrentFont['desc']['MissingWidth']; 
  2974. } elseif (isset($this->CurrentFont['MissingWidth'])) { 
  2975. $w += $this->CurrentFont['MissingWidth']; 
  2976. } else { 
  2977. $w += 500; 
  2978. } else { 
  2979. $charw = $this->_getCharWidth($this->CurrentFont['cw'], $char); 
  2980. if ($charw !== false) { 
  2981. $w+=$charw; 
  2982. } elseif (isset($this->CurrentFont['desc']['MissingWidth'])) { 
  2983. $w += $this->CurrentFont['desc']['MissingWidth']; 
  2984. } elseif (isset($this->CurrentFont['MissingWidth'])) { 
  2985. $w += $this->CurrentFont['MissingWidth']; 
  2986. } else { 
  2987. $w += 500; 
  2988. } // *CJK-FONTS* 
  2989. $w *= ($this->FontSize / 1000); 
  2990. if ($this->minwSpacing || $this->fixedlSpacing) { 
  2991. if ($c == ' ') 
  2992. $nb_spaces = 1; 
  2993. else 
  2994. $nb_spaces = 0; 
  2995. $w += $this->fixedlSpacing + ($nb_spaces * $this->minwSpacing); 
  2996. return ($w); 
  2997.  
  2998. function GetCharWidth($c, $addSubset = true) 
  2999. if (!$this->usingCoreFont) { 
  3000. return $this->GetCharWidthNonCore($c, $addSubset); 
  3001. } else { 
  3002. return $this->GetCharWidthCore($c); 
  3003.  
  3004. function GetStringWidth($s, $addSubset = true, $OTLdata = false, $textvar = 0, $includeKashida = false) 
  3005. { // mPDF 5.7.1 
  3006. //Get width of a string in the current font 
  3007. $s = (string) $s; 
  3008. $cw = &$this->CurrentFont['cw']; 
  3009. $w = 0; 
  3010. $kerning = 0; 
  3011. $lastchar = 0; 
  3012. $nb_carac = 0; 
  3013. $nb_spaces = 0; 
  3014. $kashida = 0; 
  3015. // mPDF ITERATION 
  3016. if ($this->iterationCounter) 
  3017. $s = preg_replace('/{iteration ([a-zA-Z0-9_]+)}/', '\\1', $s); 
  3018. if (!$this->usingCoreFont) { 
  3019. $discards = substr_count($s, "\xc2\xad"); // mPDF 6 soft hyphens [U+00AD] 
  3020. $unicode = $this->UTF8StringToArray($s, $addSubset); 
  3021. if ($this->minwSpacing || $this->fixedlSpacing) { 
  3022. $nb_spaces = mb_substr_count($s, ' ', $this->mb_enc); 
  3023. $nb_carac = count($unicode) - $discards; // mPDF 6 
  3024. // mPDF 5.7.1 
  3025. // Use GPOS OTL 
  3026. if (isset($this->CurrentFont['useOTL']) && $this->CurrentFont['useOTL']) { 
  3027. if (isset($OTLdata['group']) && $OTLdata['group']) { 
  3028. $nb_carac -= substr_count($OTLdata['group'], 'M'); 
  3029. /** -- CJK-FONTS -- */ 
  3030. if ($this->CurrentFont['type'] == 'Type0') { // CJK Adobe fonts 
  3031. foreach ($unicode as $char) { 
  3032. if ($char == 0x00AD) { 
  3033. continue; 
  3034. } // mPDF 6 soft hyphens [U+00AD] 
  3035. if (isset($cw[$char])) { 
  3036. $w+=$cw[$char]; 
  3037. } elseif (isset($this->CurrentFont['MissingWidth'])) { 
  3038. $w += $this->CurrentFont['MissingWidth']; 
  3039. } else { 
  3040. $w += 500; 
  3041. } else { 
  3042. /** -- END CJK-FONTS -- */ 
  3043. foreach ($unicode as $i => $char) { 
  3044. if ($char == 0x00AD) { 
  3045. continue; 
  3046. } // mPDF 6 soft hyphens [U+00AD] 
  3047. if (($textvar & FC_SMALLCAPS) && isset($this->upperCase[$char])) { 
  3048. $charw = $this->_getCharWidth($cw, $this->upperCase[$char]); 
  3049. if ($charw !== false) { 
  3050. $charw = $charw * $this->smCapsScale * $this->smCapsStretch / 100; 
  3051. $w+=$charw; 
  3052. } elseif (isset($this->CurrentFont['desc']['MissingWidth'])) { 
  3053. $w += $this->CurrentFont['desc']['MissingWidth']; 
  3054. } elseif (isset($this->CurrentFont['MissingWidth'])) { 
  3055. $w += $this->CurrentFont['MissingWidth']; 
  3056. } else { 
  3057. $w += 500; 
  3058. } else { 
  3059. $charw = $this->_getCharWidth($cw, $char); 
  3060. if ($charw !== false) { 
  3061. $w+=$charw; 
  3062. } elseif (isset($this->CurrentFont['desc']['MissingWidth'])) { 
  3063. $w += $this->CurrentFont['desc']['MissingWidth']; 
  3064. } elseif (isset($this->CurrentFont['MissingWidth'])) { 
  3065. $w += $this->CurrentFont['MissingWidth']; 
  3066. } else { 
  3067. $w += 500; 
  3068. // mPDF 5.7.1 
  3069. // Use GPOS OTL 
  3070. // ...GetStringWidth... 
  3071. if (isset($this->CurrentFont['useOTL']) && ($this->CurrentFont['useOTL'] & 0xFF) && !empty($OTLdata)) { 
  3072. if (isset($OTLdata['GPOSinfo'][$i]['wDir']) && $OTLdata['GPOSinfo'][$i]['wDir'] == 'RTL') { 
  3073. if (isset($OTLdata['GPOSinfo'][$i]['XAdvanceR']) && $OTLdata['GPOSinfo'][$i]['XAdvanceR']) { 
  3074. $w += $OTLdata['GPOSinfo'][$i]['XAdvanceR'] * 1000 / $this->CurrentFont['unitsPerEm']; 
  3075. } else { 
  3076. if (isset($OTLdata['GPOSinfo'][$i]['XAdvanceL']) && $OTLdata['GPOSinfo'][$i]['XAdvanceL']) { 
  3077. $w += $OTLdata['GPOSinfo'][$i]['XAdvanceL'] * 1000 / $this->CurrentFont['unitsPerEm']; 
  3078. // Kashida from GPOS 
  3079. // Kashida is set as an absolute length value (already set as a proportion based on useKashida %) 
  3080. if ($includeKashida && isset($OTLdata['GPOSinfo'][$i]['kashida_space']) && $OTLdata['GPOSinfo'][$i]['kashida_space']) { 
  3081. $kashida += $OTLdata['GPOSinfo'][$i]['kashida_space']; 
  3082. if (($textvar & FC_KERNING) && $lastchar) { 
  3083. if (isset($this->CurrentFont['kerninfo'][$lastchar][$char])) { 
  3084. $kerning += $this->CurrentFont['kerninfo'][$lastchar][$char]; 
  3085. $lastchar = $char; 
  3086. } // *CJK-FONTS* 
  3087. } else { 
  3088. if ($this->FontFamily != 'csymbol' && $this->FontFamily != 'czapfdingbats') { 
  3089. $s = str_replace(chr(173), '', $s); 
  3090. $nb_carac = $l = strlen($s); 
  3091. if ($this->minwSpacing || $this->fixedlSpacing) { 
  3092. $nb_spaces = substr_count($s, ' '); 
  3093. for ($i = 0; $i < $l; $i++) { 
  3094. if (($textvar & FC_SMALLCAPS) && isset($this->upperCase[ord($s[$i])])) { // mPDF 5.7.1 
  3095. $charw = $cw[chr($this->upperCase[ord($s[$i])])]; 
  3096. if ($charw !== false) { 
  3097. $charw = $charw * $this->smCapsScale * $this->smCapsStretch / 100; 
  3098. $w+=$charw; 
  3099. } elseif (isset($cw[$s[$i]])) { 
  3100. $w += $cw[$s[$i]]; 
  3101. } elseif (isset($cw[ord($s[$i])])) { 
  3102. $w += $cw[ord($s[$i])]; 
  3103. if (($textvar & FC_KERNING) && $i > 0) { // mPDF 5.7.1 
  3104. if (isset($this->CurrentFont['kerninfo'][$s[($i - 1)]][$s[$i]])) { 
  3105. $kerning += $this->CurrentFont['kerninfo'][$s[($i - 1)]][$s[$i]]; 
  3106. unset($cw); 
  3107. if ($textvar & FC_KERNING) { 
  3108. $w += $kerning; 
  3109. } // mPDF 5.7.1 
  3110. $w *= ($this->FontSize / 1000); 
  3111. $w += (($nb_carac + $nb_spaces) * $this->fixedlSpacing) + ($nb_spaces * $this->minwSpacing); 
  3112. $w += $kashida / _MPDFK; 
  3113.  
  3114. return ($w); 
  3115.  
  3116. function SetLineWidth($width) 
  3117. //Set line width 
  3118. $this->LineWidth = $width; 
  3119. $lwout = (sprintf('%.3F w', $width * _MPDFK)); 
  3120. if ($this->page > 0 && ((isset($this->pageoutput[$this->page]['LineWidth']) && $this->pageoutput[$this->page]['LineWidth'] != $lwout) || !isset($this->pageoutput[$this->page]['LineWidth']))) { 
  3121. $this->_out($lwout); 
  3122. $this->pageoutput[$this->page]['LineWidth'] = $lwout; 
  3123.  
  3124. function Line($x1, $y1, $x2, $y2) 
  3125. //Draw a line 
  3126. $this->_out(sprintf('%.3F %.3F m %.3F %.3F l S', $x1 * _MPDFK, ($this->h - $y1) * _MPDFK, $x2 * _MPDFK, ($this->h - $y2) * _MPDFK)); 
  3127.  
  3128. function Arrow($x1, $y1, $x2, $y2, $headsize = 3, $fill = 'B', $angle = 25) 
  3129. //F == fill //S == stroke //B == stroke and fill 
  3130. // angle = splay of arrowhead - 1 - 89 degrees 
  3131. if ($fill == 'F') 
  3132. $fill = 'f'; 
  3133. elseif ($fill == 'FD' or $fill == 'DF' or $fill == 'B') 
  3134. $fill = 'B'; 
  3135. else 
  3136. $fill = 'S'; 
  3137. $a = atan2(($y2 - $y1), ($x2 - $x1)); 
  3138. $b = $a + deg2rad($angle); 
  3139. $c = $a - deg2rad($angle); 
  3140. $x3 = $x2 - ($headsize * cos($b)); 
  3141. $y3 = $this->h - ($y2 - ($headsize * sin($b))); 
  3142. $x4 = $x2 - ($headsize * cos($c)); 
  3143. $y4 = $this->h - ($y2 - ($headsize * sin($c))); 
  3144.  
  3145. $x5 = $x3 - ($x3 - $x4) / 2; // mid point of base of arrowhead - to join arrow line to 
  3146. $y5 = $y3 - ($y3 - $y4) / 2; 
  3147.  
  3148. $s = ''; 
  3149. $s.=sprintf('%.3F %.3F m %.3F %.3F l S', $x1 * _MPDFK, ($this->h - $y1) * _MPDFK, $x5 * _MPDFK, $y5 * _MPDFK); 
  3150. $this->_out($s); 
  3151.  
  3152. $s = ''; 
  3153. $s.=sprintf('%.3F %.3F m %.3F %.3F l %.3F %.3F l %.3F %.3F l %.3F %.3F l ', $x5 * _MPDFK, $y5 * _MPDFK, $x3 * _MPDFK, $y3 * _MPDFK, $x2 * _MPDFK, ($this->h - $y2) * _MPDFK, $x4 * _MPDFK, $y4 * _MPDFK, $x5 * _MPDFK, $y5 * _MPDFK); 
  3154. $s.=$fill; 
  3155. $this->_out($s); 
  3156.  
  3157. function Rect($x, $y, $w, $h, $style = '') 
  3158. //Draw a rectangle 
  3159. if ($style == 'F') 
  3160. $op = 'f'; 
  3161. elseif ($style == 'FD' or $style == 'DF') 
  3162. $op = 'B'; 
  3163. else 
  3164. $op = 'S'; 
  3165. $this->_out(sprintf('%.3F %.3F %.3F %.3F re %s', $x * _MPDFK, ($this->h - $y) * _MPDFK, $w * _MPDFK, -$h * _MPDFK, $op)); 
  3166.  
  3167. function AddFont($family, $style = '') 
  3168. if (empty($family)) { 
  3169. return; 
  3170. $family = strtolower($family); 
  3171. $style = strtoupper($style); 
  3172. $style = str_replace('U', '', $style); 
  3173. if ($style == 'IB') 
  3174. $style = 'BI'; 
  3175. $fontkey = $family . $style; 
  3176. // check if the font has been already added 
  3177. if (isset($this->fonts[$fontkey])) { 
  3178. return; 
  3179.  
  3180. /** -- CJK-FONTS -- */ 
  3181. if (in_array($family, $this->available_CJK_fonts)) { 
  3182. if (empty($this->Big5_widths)) { 
  3183. require(_MPDF_PATH . 'includes/CJKdata.php'); 
  3184. $this->AddCJKFont($family); // don't need to add style 
  3185. return; 
  3186. /** -- END CJK-FONTS -- */ 
  3187.  
  3188. if ($this->usingCoreFont) { 
  3189. throw new MpdfException("mPDF Error - problem with Font management"); 
  3190.  
  3191. $stylekey = $style; 
  3192. if (!$style) { 
  3193. $stylekey = 'R'; 
  3194.  
  3195. if (!isset($this->fontdata[$family][$stylekey]) || !$this->fontdata[$family][$stylekey]) { 
  3196. throw new MpdfException('mPDF Error - Font is not supported - ' . $family . ' ' . $style); 
  3197.  
  3198. $name = ''; 
  3199. $originalsize = 0; 
  3200. $sip = false; 
  3201. $smp = false; 
  3202. $useOTL = 0; // mPDF 5.7.1 
  3203. $fontmetrics = ''; // mPDF 6 
  3204. $haskerninfo = false; 
  3205. $haskernGPOS = false; 
  3206. $hassmallcapsGSUB = false; 
  3207. $BMPselected = false; 
  3208. $GSUBScriptLang = array(); 
  3209. $GSUBFeatures = array(); 
  3210. $GSUBLookups = array(); 
  3211. $GPOSScriptLang = array(); 
  3212. $GPOSFeatures = array(); 
  3213. $GPOSLookups = array(); 
  3214. if (file_exists(_MPDF_TTFONTDATAPATH . $fontkey . '.mtx.php')) { 
  3215. include(_MPDF_TTFONTDATAPATH . $fontkey . '.mtx.php'); 
  3216.  
  3217. $ttffile = ''; 
  3218. if (defined('_MPDF_SYSTEM_TTFONTS')) { 
  3219. $ttffile = _MPDF_SYSTEM_TTFONTS . $this->fontdata[$family][$stylekey]; 
  3220. if (!file_exists($ttffile)) { 
  3221. $ttffile = ''; 
  3222. if (!$ttffile) { 
  3223. /** Allow filter to change which file is loaded */ 
  3224. $ttffile = apply_filters('mpdf_current_font_path', _MPDF_TTFONTPATH . $this->fontdata[$family][$stylekey], $this->fontdata[$family][$stylekey]); 
  3225.  
  3226. if ( ! is_file($ttffile)) { 
  3227. throw new MpdfException("mPDF Error - cannot find TTF TrueType font file - " . $ttffile); 
  3228. $ttfstat = stat($ttffile); 
  3229.  
  3230. if (isset($this->fontdata[$family]['TTCfontID'][$stylekey])) { 
  3231. $TTCfontID = $this->fontdata[$family]['TTCfontID'][$stylekey]; 
  3232. } else { 
  3233. $TTCfontID = 0; 
  3234.  
  3235. $BMPonly = false; 
  3236. if (in_array($family, $this->BMPonly)) { 
  3237. $BMPonly = true; 
  3238. $regenerate = false; 
  3239. if ($BMPonly && !$BMPselected) { 
  3240. $regenerate = true; 
  3241. } elseif (!$BMPonly && $BMPselected) { 
  3242. $regenerate = true; 
  3243. // mPDF 5.7.1 
  3244. if (isset($this->fontdata[$family]['useOTL']) && $this->fontdata[$family]['useOTL'] && $useOTL != $this->fontdata[$family]['useOTL']) { 
  3245. $regenerate = true; 
  3246. $useOTL = $this->fontdata[$family]['useOTL']; 
  3247. } elseif ((!isset($this->fontdata[$family]['useOTL']) || !$this->fontdata[$family]['useOTL']) && $useOTL) { 
  3248. $regenerate = true; 
  3249. $useOTL = 0; 
  3250. if (_FONT_DESCRIPTOR != $fontmetrics) { 
  3251. $regenerate = true; 
  3252. } // mPDF 6 
  3253. if (!isset($name) || $originalsize != $ttfstat['size'] || $regenerate) { 
  3254. if (!class_exists('TTFontFile', false)) { 
  3255. include(_MPDF_PATH . 'classes/ttfontsuni.php'); 
  3256. $ttf = new TTFontFile(); 
  3257. $ttf->getMetrics($ttffile, $fontkey, $TTCfontID, $this->debugfonts, $BMPonly, $useOTL); // mPDF 5.7.1 
  3258. $cw = $ttf->charWidths; 
  3259. $kerninfo = $ttf->kerninfo; 
  3260. if ($kerninfo) 
  3261. $haskerninfo = true; 
  3262. $haskernGPOS = $ttf->haskernGPOS; 
  3263. $hassmallcapsGSUB = $ttf->hassmallcapsGSUB; 
  3264. $name = preg_replace('/[ ()]/', '', $ttf->fullName); 
  3265. $sip = $ttf->sipset; 
  3266. $smp = $ttf->smpset; 
  3267. // mPDF 6 
  3268. $GSUBScriptLang = $ttf->GSUBScriptLang; 
  3269. $GSUBFeatures = $ttf->GSUBFeatures; 
  3270. $GSUBLookups = $ttf->GSUBLookups; 
  3271. $rtlPUAstr = $ttf->rtlPUAstr; 
  3272. $GPOSScriptLang = $ttf->GPOSScriptLang; 
  3273. $GPOSFeatures = $ttf->GPOSFeatures; 
  3274. $GPOSLookups = $ttf->GPOSLookups; 
  3275. $glyphIDtoUni = $ttf->glyphIDtoUni; 
  3276.  
  3277.  
  3278. $desc = array( 
  3279. 'CapHeight' => round($ttf->capHeight),  
  3280. 'XHeight' => round($ttf->xHeight),  
  3281. 'FontBBox' => '[' . round($ttf->bbox[0]) . " " . round($ttf->bbox[1]) . " " . round($ttf->bbox[2]) . " " . round($ttf->bbox[3]) . ']', /** FontBBox from head table */ 
  3282.  
  3283. /** 'MaxWidth' => round($ttf->advanceWidthMax), // AdvanceWidthMax from hhea table NB ArialUnicode MS = 31990 ! */ 
  3284. 'Flags' => $ttf->flags,  
  3285. 'Ascent' => round($ttf->ascent),  
  3286. 'Descent' => round($ttf->descent),  
  3287. 'Leading' => round($ttf->lineGap),  
  3288. 'ItalicAngle' => $ttf->italicAngle,  
  3289. 'StemV' => round($ttf->stemV),  
  3290. 'MissingWidth' => round($ttf->defaultWidth) 
  3291. ); 
  3292. $panose = ''; 
  3293. if (count($ttf->panose)) { 
  3294. $panoseArray = array_merge(array($ttf->sFamilyClass, $ttf->sFamilySubClass), $ttf->panose); 
  3295. foreach ($panoseArray as $value) 
  3296. $panose .= ' ' . dechex($value); 
  3297. $unitsPerEm = round($ttf->unitsPerEm); 
  3298. $up = round($ttf->underlinePosition); 
  3299. $ut = round($ttf->underlineThickness); 
  3300. $strp = round($ttf->strikeoutPosition); // mPDF 6 
  3301. $strs = round($ttf->strikeoutSize); // mPDF 6 
  3302. $originalsize = $ttfstat['size'] + 0; 
  3303. $type = 'TTF'; 
  3304. //Generate metrics .php file 
  3305. $s = '<?php' . "\n"; 
  3306. $s.='$name=\'' . $name . "';\n"; 
  3307. $s.='$type=\'' . $type . "';\n"; 
  3308. $s.='$desc=' . var_export($desc, true) . ";\n"; 
  3309. $s.='$unitsPerEm=' . $unitsPerEm . ";\n"; 
  3310. $s.='$up=' . $up . ";\n"; 
  3311. $s.='$ut=' . $ut . ";\n"; 
  3312. $s.='$strp=' . $strp . ";\n"; // mPDF 6 
  3313. $s.='$strs=' . $strs . ";\n"; // mPDF 6 
  3314. $s.='$ttffile=\'' . $ttffile . "';\n"; 
  3315. $s.='$TTCfontID=\'' . $TTCfontID . "';\n"; 
  3316. $s.='$originalsize=' . $originalsize . ";\n"; 
  3317. if ($sip) 
  3318. $s.='$sip=true;' . "\n"; 
  3319. else 
  3320. $s.='$sip=false;' . "\n"; 
  3321. if ($smp) 
  3322. $s.='$smp=true;' . "\n"; 
  3323. else 
  3324. $s.='$smp=false;' . "\n"; 
  3325. if ($BMPonly) 
  3326. $s.='$BMPselected=true;' . "\n"; 
  3327. else 
  3328. $s.='$BMPselected=false;' . "\n"; 
  3329. $s.='$fontkey=\'' . $fontkey . "';\n"; 
  3330. $s.='$panose=\'' . $panose . "';\n"; 
  3331. if ($haskerninfo) 
  3332. $s.='$haskerninfo=true;' . "\n"; 
  3333. else 
  3334. $s.='$haskerninfo=false;' . "\n"; 
  3335. if ($haskernGPOS) 
  3336. $s.='$haskernGPOS=true;' . "\n"; 
  3337. else 
  3338. $s.='$haskernGPOS=false;' . "\n"; 
  3339. if ($hassmallcapsGSUB) 
  3340. $s.='$hassmallcapsGSUB=true;' . "\n"; 
  3341. else 
  3342. $s.='$hassmallcapsGSUB=false;' . "\n"; 
  3343. $s.='$fontmetrics=\'' . _FONT_DESCRIPTOR . "';\n"; // mPDF 6 
  3344.  
  3345. $s.='// TypoAscender/TypoDescender/TypoLineGap = ' . round($ttf->typoAscender) . ', ' . round($ttf->typoDescender) . ', ' . round($ttf->typoLineGap) . "\n"; 
  3346. $s.='// usWinAscent/usWinDescent = ' . round($ttf->usWinAscent) . ', ' . round(-$ttf->usWinDescent) . "\n"; 
  3347. $s.='// hhea Ascent/Descent/LineGap = ' . round($ttf->hheaascent) . ', ' . round($ttf->hheadescent) . ', ' . round($ttf->hhealineGap) . "\n"; 
  3348.  
  3349. // mPDF 5.7.1 
  3350. if (isset($this->fontdata[$family]['useOTL'])) { 
  3351. $s.='$useOTL=' . $this->fontdata[$family]['useOTL'] . ';' . "\n"; 
  3352. } else 
  3353. $s.='$useOTL=0x0000;' . "\n"; 
  3354. if ($rtlPUAstr) { 
  3355. $s.='$rtlPUAstr=\'' . $rtlPUAstr . "';\n"; 
  3356. } else 
  3357. $s.='$rtlPUAstr=\'\';' . "\n"; 
  3358. if (count($GSUBScriptLang)) { 
  3359. $s.='$GSUBScriptLang=' . var_export($GSUBScriptLang, true) . ";\n"; 
  3360. if (count($GSUBFeatures)) { 
  3361. $s.='$GSUBFeatures=' . var_export($GSUBFeatures, true) . ";\n"; 
  3362. if (count($GSUBLookups)) { 
  3363. $s.='$GSUBLookups=' . var_export($GSUBLookups, true) . ";\n"; 
  3364. if (count($GPOSScriptLang)) { 
  3365. $s.='$GPOSScriptLang=' . var_export($GPOSScriptLang, true) . ";\n"; 
  3366. if (count($GPOSFeatures)) { 
  3367. $s.='$GPOSFeatures=' . var_export($GPOSFeatures, true) . ";\n"; 
  3368. if (count($GPOSLookups)) { 
  3369. $s.='$GPOSLookups=' . var_export($GPOSLookups, true) . ";\n"; 
  3370. if ($kerninfo) { 
  3371. $s.='$kerninfo=' . var_export($kerninfo, true) . ";\n"; 
  3372. $s.="?>"; 
  3373. if (is_writable(dirname(_MPDF_TTFONTDATAPATH . 'x'))) { 
  3374. $fh = fopen(_MPDF_TTFONTDATAPATH . $fontkey . '.mtx.php', "w"); 
  3375. fwrite($fh, $s, strlen($s)); 
  3376. fclose($fh); 
  3377. $fh = fopen(_MPDF_TTFONTDATAPATH . $fontkey . '.cw.dat', "wb"); 
  3378. fwrite($fh, $cw, strlen($cw)); 
  3379. fclose($fh); 
  3380. // mPDF 5.7.1 
  3381. $fh = fopen(_MPDF_TTFONTDATAPATH . $fontkey . '.gid.dat', "wb"); 
  3382. fwrite($fh, $glyphIDtoUni, strlen($glyphIDtoUni)); 
  3383. fclose($fh); 
  3384. if (file_exists(_MPDF_TTFONTDATAPATH . $fontkey . '.cgm')) 
  3385. unlink(_MPDF_TTFONTDATAPATH . $fontkey . '.cgm'); 
  3386. if (file_exists(_MPDF_TTFONTDATAPATH . $fontkey . '.z')) 
  3387. unlink(_MPDF_TTFONTDATAPATH . $fontkey . '.z'); 
  3388. if (file_exists(_MPDF_TTFONTDATAPATH . $fontkey . '.cw127.php')) 
  3389. unlink(_MPDF_TTFONTDATAPATH . $fontkey . '.cw127.php'); 
  3390. if (file_exists(_MPDF_TTFONTDATAPATH . $fontkey . '.cw')) 
  3391. unlink(_MPDF_TTFONTDATAPATH . $fontkey . '.cw'); 
  3392. elseif ($this->debugfonts) { 
  3393. throw new MpdfException('Cannot write to the font caching directory - ' . _MPDF_TTFONTDATAPATH); 
  3394. unset($ttf); 
  3395. } else { 
  3396. $cw = ''; 
  3397. $glyphIDtoUni = ''; 
  3398. if (file_exists(_MPDF_TTFONTDATAPATH . $fontkey . '.cw.dat')) 
  3399. $cw = file_get_contents(_MPDF_TTFONTDATAPATH . $fontkey . '.cw.dat'); 
  3400. if (file_exists(_MPDF_TTFONTDATAPATH . $fontkey . '.gid.dat')) 
  3401. $glyphIDtoUni = file_get_contents(_MPDF_TTFONTDATAPATH . $fontkey . '.gid.dat'); 
  3402.  
  3403. /** -- OTL -- */ 
  3404. // mPDF 5.7.1 
  3405. // Use OTL OpenType Table Layout - GSUB 
  3406. if (isset($this->fontdata[$family]['useOTL']) && ($this->fontdata[$family]['useOTL'])) { 
  3407. if (!class_exists('otl', false)) { 
  3408. include(_MPDF_PATH . 'classes/otl.php'); 
  3409. if (empty($this->otl)) { 
  3410. $this->otl = new otl($this); 
  3411. /** -- END OTL -- */ 
  3412.  
  3413. if (isset($this->fontdata[$family]['sip-ext']) && $this->fontdata[$family]['sip-ext']) { 
  3414. $sipext = $this->fontdata[$family]['sip-ext']; 
  3415. } else { 
  3416. $sipext = ''; 
  3417.  
  3418. // Override with values from config_font.php 
  3419. if (isset($this->fontdata[$family]['Ascent']) && $this->fontdata[$family]['Ascent']) { 
  3420. $desc['Ascent'] = $this->fontdata[$family]['Ascent']; 
  3421. if (isset($this->fontdata[$family]['Descent']) && $this->fontdata[$family]['Descent']) { 
  3422. $desc['Descent'] = $this->fontdata[$family]['Descent']; 
  3423. if (isset($this->fontdata[$family]['Leading']) && $this->fontdata[$family]['Leading']) { 
  3424. $desc['Leading'] = $this->fontdata[$family]['Leading']; 
  3425.  
  3426.  
  3427.  
  3428. $i = count($this->fonts) + $this->extraFontSubsets + 1; 
  3429. if ($sip || $smp) { 
  3430. $this->fonts[$fontkey] = array('i' => $i, 'type' => $type, 'name' => $name, 'desc' => $desc, 'panose' => $panose, 'unitsPerEm' => $unitsPerEm, 'up' => $up, 'ut' => $ut, 'strs' => $strs, 'strp' => $strp, 'cw' => $cw, 'ttffile' => $ttffile, 'fontkey' => $fontkey, 'subsets' => array(0 => range(0, 127)), 'subsetfontids' => array($i), 'used' => false, 'sip' => $sip, 'sipext' => $sipext, 'smp' => $smp, 'TTCfontID' => $TTCfontID, 'useOTL' => (isset($this->fontdata[$family]['useOTL']) ? $this->fontdata[$family]['useOTL'] : false), 'useKashida' => (isset($this->fontdata[$family]['useKashida']) ? $this->fontdata[$family]['useKashida'] : false), 'GSUBScriptLang' => $GSUBScriptLang, 'GSUBFeatures' => $GSUBFeatures, 'GSUBLookups' => $GSUBLookups, 'GPOSScriptLang' => $GPOSScriptLang, 'GPOSFeatures' => $GPOSFeatures, 'GPOSLookups' => $GPOSLookups, 'rtlPUAstr' => $rtlPUAstr, 'glyphIDtoUni' => $glyphIDtoUni, 'haskerninfo' => $haskerninfo, 'haskernGPOS' => $haskernGPOS, 'hassmallcapsGSUB' => $hassmallcapsGSUB); // mPDF 5.7.1 // mPDF 6 
  3431. } else { 
  3432. $ss = array(); 
  3433. for ($s = 32; $s < 128; $s++) { 
  3434. $ss[$s] = $s; 
  3435. $this->fonts[$fontkey] = array('i' => $i, 'type' => $type, 'name' => $name, 'desc' => $desc, 'panose' => $panose, 'unitsPerEm' => $unitsPerEm, 'up' => $up, 'ut' => $ut, 'strs' => $strs, 'strp' => $strp, 'cw' => $cw, 'ttffile' => $ttffile, 'fontkey' => $fontkey, 'subset' => $ss, 'used' => false, 'sip' => $sip, 'sipext' => $sipext, 'smp' => $smp, 'TTCfontID' => $TTCfontID, 'useOTL' => (isset($this->fontdata[$family]['useOTL']) ? $this->fontdata[$family]['useOTL'] : false), 'useKashida' => (isset($this->fontdata[$family]['useKashida']) ? $this->fontdata[$family]['useKashida'] : false), 'GSUBScriptLang' => $GSUBScriptLang, 'GSUBFeatures' => $GSUBFeatures, 'GSUBLookups' => $GSUBLookups, 'GPOSScriptLang' => $GPOSScriptLang, 'GPOSFeatures' => $GPOSFeatures, 'GPOSLookups' => $GPOSLookups, 'rtlPUAstr' => $rtlPUAstr, 'glyphIDtoUni' => $glyphIDtoUni, 'haskerninfo' => $haskerninfo, 'haskernGPOS' => $haskernGPOS, 'hassmallcapsGSUB' => $hassmallcapsGSUB); // mPDF 5.7.1 // mPDF 6 
  3436. if ($haskerninfo) { 
  3437. $this->fonts[$fontkey]['kerninfo'] = $kerninfo; 
  3438. $this->FontFiles[$fontkey] = array('length1' => $originalsize, 'type' => "TTF", 'ttffile' => $ttffile, 'sip' => $sip, 'smp' => $smp); 
  3439. unset($cw); 
  3440.  
  3441. function SetFont($family, $style = '', $size = 0, $write = true, $forcewrite = false) 
  3442. $family = strtolower($family); 
  3443. if (!$this->onlyCoreFonts) { 
  3444. if ($family == 'sans' || $family == 'sans-serif') { 
  3445. $family = $this->sans_fonts[0]; 
  3446. if ($family == 'serif') { 
  3447. $family = $this->serif_fonts[0]; 
  3448. if ($family == 'mono' || $family == 'monospace') { 
  3449. $family = $this->mono_fonts[0]; 
  3450. if (isset($this->fonttrans[$family]) && $this->fonttrans[$family]) { 
  3451. $family = $this->fonttrans[$family]; 
  3452. if ($family == '') { 
  3453. if ($this->FontFamily) { 
  3454. $family = $this->FontFamily; 
  3455. } elseif ($this->default_font) { 
  3456. $family = $this->default_font; 
  3457. } else { 
  3458. throw new MpdfException("No font or default font set!"); 
  3459. $this->ReqFontStyle = $style; // required or requested style - used later for artificial bold/italic 
  3460.  
  3461. if (($family == 'csymbol') || ($family == 'czapfdingbats') || ($family == 'ctimes') || ($family == 'ccourier') || ($family == 'chelvetica')) { 
  3462. if ($this->PDFA || $this->PDFX) { 
  3463. if ($family == 'csymbol' || $family == 'czapfdingbats') { 
  3464. throw new MpdfException("Symbol and Zapfdingbats cannot be embedded in mPDF (required for PDFA1-b or PDFX/1-a)."); 
  3465. if ($family == 'ctimes' || $family == 'ccourier' || $family == 'chelvetica') { 
  3466. if (($this->PDFA && !$this->PDFAauto) || ($this->PDFX && !$this->PDFXauto)) { 
  3467. $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.)"; 
  3468. if ($family == 'chelvetica') { 
  3469. $family = 'sans'; 
  3470. if ($family == 'ctimes') { 
  3471. $family = 'serif'; 
  3472. if ($family == 'ccourier') { 
  3473. $family = 'mono'; 
  3474. $this->usingCoreFont = false; 
  3475. } else { 
  3476. $this->usingCoreFont = true; 
  3477. if ($family == 'csymbol' || $family == 'czapfdingbats') { 
  3478. $style = ''; 
  3479. } else { 
  3480. $this->usingCoreFont = false; 
  3481.  
  3482. // mPDF 5.7.1 
  3483. if ($style) { 
  3484. $style = strtoupper($style); 
  3485. if ($style == 'IB') 
  3486. $style = 'BI'; 
  3487. if ($size == 0) 
  3488. $size = $this->FontSizePt; 
  3489.  
  3490. $fontkey = $family . $style; 
  3491.  
  3492. $stylekey = $style; 
  3493. if (!$stylekey) { 
  3494. $stylekey = "R"; 
  3495.  
  3496. if (!$this->onlyCoreFonts && !$this->usingCoreFont) { 
  3497. if (!isset($this->fonts[$fontkey]) || count($this->default_available_fonts) != count($this->available_unifonts)) { // not already added 
  3498. /** -- CJK-FONTS -- */ 
  3499. // CJK fonts 
  3500. if (in_array($fontkey, $this->available_CJK_fonts)) { 
  3501. if (!isset($this->fonts[$fontkey])) { // already added 
  3502. if (empty($this->Big5_widths)) { 
  3503. require(_MPDF_PATH . 'includes/CJKdata.php'); 
  3504. $this->AddCJKFont($family); // don't need to add style 
  3505. // Test to see if requested font/style is available - or substitute 
  3506. else 
  3507. /** -- END CJK-FONTS -- */ 
  3508. if (!in_array($fontkey, $this->available_unifonts)) { 
  3509. // If font[nostyle] exists - set it 
  3510. if (in_array($family, $this->available_unifonts)) { 
  3511. $style = ''; 
  3512.  
  3513. // elseif only one font available - set it (assumes if only one font available it will not have a style) 
  3514. elseif (count($this->available_unifonts) == 1) { 
  3515. $family = $this->available_unifonts[0]; 
  3516. $style = ''; 
  3517. } else { 
  3518. $found = 0; 
  3519. // else substitute font of similar type 
  3520. if (in_array($family, $this->sans_fonts)) { 
  3521. $i = array_intersect($this->sans_fonts, $this->available_unifonts); 
  3522. if (count($i)) { 
  3523. $i = array_values($i); 
  3524. // with requested style if possible 
  3525. if (!in_array(($i[0] . $style), $this->available_unifonts)) { 
  3526. $style = ''; 
  3527. $family = $i[0]; 
  3528. $found = 1; 
  3529. } elseif (in_array($family, $this->serif_fonts)) { 
  3530. $i = array_intersect($this->serif_fonts, $this->available_unifonts); 
  3531. if (count($i)) { 
  3532. $i = array_values($i); 
  3533. // with requested style if possible 
  3534. if (!in_array(($i[0] . $style), $this->available_unifonts)) { 
  3535. $style = ''; 
  3536. $family = $i[0]; 
  3537. $found = 1; 
  3538. } elseif (in_array($family, $this->mono_fonts)) { 
  3539. $i = array_intersect($this->mono_fonts, $this->available_unifonts); 
  3540. if (count($i)) { 
  3541. $i = array_values($i); 
  3542. // with requested style if possible 
  3543. if (!in_array(($i[0] . $style), $this->available_unifonts)) { 
  3544. $style = ''; 
  3545. $family = $i[0]; 
  3546. $found = 1; 
  3547.  
  3548. if (!$found) { 
  3549. // set first available font 
  3550. $fs = $this->available_unifonts[0]; 
  3551. preg_match('/^([a-z_0-9\-]+)([BI]{0, 2})$/', $fs, $fas); // Allow "-" 
  3552. // with requested style if possible 
  3553. $ws = $fas[1] . $style; 
  3554. if (in_array($ws, $this->available_unifonts)) { 
  3555. $family = $fas[1]; // leave $style as is 
  3556. } elseif (in_array($fas[1], $this->available_unifonts)) { 
  3557. // or without style 
  3558. $family = $fas[1]; 
  3559. $style = ''; 
  3560. } else { 
  3561. // or with the style specified 
  3562. $family = $fas[1]; 
  3563. $style = $fas[2]; 
  3564. $fontkey = $family . $style; 
  3565. // try to add font (if not already added) 
  3566. $this->AddFont($family, $style); 
  3567.  
  3568. //Test if font is already selected 
  3569. if ($this->FontFamily == $family && $this->FontFamily == $this->currentfontfamily && $this->FontStyle == $style && $this->FontStyle == $this->currentfontstyle && $this->FontSizePt == $size && $this->FontSizePt == $this->currentfontsize && !$forcewrite) { 
  3570. return $family; 
  3571.  
  3572. $fontkey = $family . $style; 
  3573.  
  3574. //Select it 
  3575. $this->FontFamily = $family; 
  3576. $this->FontStyle = $style; 
  3577. $this->FontSizePt = $size; 
  3578. $this->FontSize = $size / _MPDFK; 
  3579. $this->CurrentFont = &$this->fonts[$fontkey]; 
  3580. if ($write) { 
  3581. $fontout = (sprintf('BT /F%d %.3F Tf ET', $this->CurrentFont['i'], $this->FontSizePt)); 
  3582. if ($this->page > 0 && ((isset($this->pageoutput[$this->page]['Font']) && $this->pageoutput[$this->page]['Font'] != $fontout) || !isset($this->pageoutput[$this->page]['Font']))) { 
  3583. $this->_out($fontout); 
  3584. $this->pageoutput[$this->page]['Font'] = $fontout; 
  3585.  
  3586.  
  3587.  
  3588. // Added - currentfont (lowercase) used in HTML2PDF 
  3589. $this->currentfontfamily = $family; 
  3590. $this->currentfontsize = $size; 
  3591. $this->currentfontstyle = $style; 
  3592. $this->setMBencoding('UTF-8'); 
  3593. } else { // if using core fonts 
  3594. if ($this->PDFA || $this->PDFX) { 
  3595. throw new MpdfException('Core Adobe fonts cannot be embedded in mPDF (required for PDFA1-b or PDFX/1-a) - cannot use option to use core fonts.'); 
  3596. $this->setMBencoding('windows-1252'); 
  3597.  
  3598. //Test if font is already selected 
  3599. if (($this->FontFamily == $family) AND ( $this->FontStyle == $style) AND ( $this->FontSizePt == $size) && !$forcewrite) { 
  3600. return $family; 
  3601.  
  3602. if (!isset($this->CoreFonts[$fontkey])) { 
  3603. if (in_array($family, $this->serif_fonts)) { 
  3604. $family = 'ctimes'; 
  3605. } elseif (in_array($family, $this->mono_fonts)) { 
  3606. $family = 'ccourier'; 
  3607. } else { 
  3608. $family = 'chelvetica'; 
  3609. $this->usingCoreFont = true; 
  3610. $fontkey = $family . $style; 
  3611.  
  3612. if (!isset($this->fonts[$fontkey])) { 
  3613. // STANDARD CORE FONTS 
  3614. if (isset($this->CoreFonts[$fontkey])) { 
  3615. //Load metric file 
  3616. $file = $family; 
  3617. if ($family == 'ctimes' || $family == 'chelvetica' || $family == 'ccourier') { 
  3618. $file.=strtolower($style); 
  3619. $file.='.php'; 
  3620. include(_MPDF_PATH . 'font/' . $file); 
  3621. if (!isset($cw)) { 
  3622. throw new MpdfException('Could not include font metric file'); 
  3623. $i = count($this->fonts) + $this->extraFontSubsets + 1; 
  3624. $this->fonts[$fontkey] = array('i' => $i, 'type' => 'core', 'name' => $this->CoreFonts[$fontkey], 'desc' => $desc, 'up' => $up, 'ut' => $ut, 'cw' => $cw); 
  3625. if ($this->useKerning && isset($kerninfo)) { 
  3626. $this->fonts[$fontkey]['kerninfo'] = $kerninfo; 
  3627. } else { 
  3628. throw new MpdfException('mPDF error - Font not defined'); 
  3629. //Test if font is already selected 
  3630. if (($this->FontFamily == $family) AND ( $this->FontStyle == $style) AND ( $this->FontSizePt == $size) && !$forcewrite) { 
  3631. return $family; 
  3632. //Select it 
  3633. $this->FontFamily = $family; 
  3634. $this->FontStyle = $style; 
  3635. $this->FontSizePt = $size; 
  3636. $this->FontSize = $size / _MPDFK; 
  3637. $this->CurrentFont = &$this->fonts[$fontkey]; 
  3638. if ($write) { 
  3639. $fontout = (sprintf('BT /F%d %.3F Tf ET', $this->CurrentFont['i'], $this->FontSizePt)); 
  3640. if ($this->page > 0 && ((isset($this->pageoutput[$this->page]['Font']) && $this->pageoutput[$this->page]['Font'] != $fontout) || !isset($this->pageoutput[$this->page]['Font']))) { 
  3641. $this->_out($fontout); 
  3642. $this->pageoutput[$this->page]['Font'] = $fontout; 
  3643. // Added - currentfont (lowercase) used in HTML2PDF 
  3644. $this->currentfontfamily = $family; 
  3645. $this->currentfontsize = $size; 
  3646. $this->currentfontstyle = $style; 
  3647.  
  3648. return $family; 
  3649.  
  3650. function SetFontSize($size, $write = true) 
  3651. //Set font size in points 
  3652. if ($this->FontSizePt == $size) 
  3653. return; 
  3654. $this->FontSizePt = $size; 
  3655. $this->FontSize = $size / _MPDFK; 
  3656. $this->currentfontsize = $size; 
  3657. if ($write) { 
  3658. $fontout = (sprintf('BT /F%d %.3F Tf ET', $this->CurrentFont['i'], $this->FontSizePt)); 
  3659. // Edited mPDF 3.0 
  3660. if ($this->page > 0 && ((isset($this->pageoutput[$this->page]['Font']) && $this->pageoutput[$this->page]['Font'] != $fontout) || !isset($this->pageoutput[$this->page]['Font']))) { 
  3661. $this->_out($fontout); 
  3662. $this->pageoutput[$this->page]['Font'] = $fontout; 
  3663.  
  3664. function AddLink() 
  3665. //Create a new internal link 
  3666. $n = count($this->links) + 1; 
  3667. $this->links[$n] = array(0, 0); 
  3668. return $n; 
  3669.  
  3670. function SetLink($link, $y = 0, $page = -1) 
  3671. //Set destination of internal link 
  3672. if ($y == -1) 
  3673. $y = $this->y; 
  3674. if ($page == -1) 
  3675. $page = $this->page; 
  3676. $this->links[$link] = array($page, $y); 
  3677.  
  3678. function Link($x, $y, $w, $h, $link) 
  3679. $l = array($x * _MPDFK, $this->hPt - $y * _MPDFK, $w * _MPDFK, $h * _MPDFK, $link); 
  3680. if ($this->keep_block_together) { // don't write yet 
  3681. return; 
  3682. } elseif ($this->table_rotate) { // *TABLES* 
  3683. $this->tbrot_Links[$this->page][] = $l; // *TABLES* 
  3684. return; // *TABLES* 
  3685. } // *TABLES* 
  3686. elseif ($this->kwt) { 
  3687. $this->kwt_Links[$this->page][] = $l; 
  3688. return; 
  3689.  
  3690. if ($this->writingHTMLheader || $this->writingHTMLfooter) { 
  3691. $this->HTMLheaderPageLinks[] = $l; 
  3692. return; 
  3693. //Put a link on the page 
  3694. $this->PageLinks[$this->page][] = $l; 
  3695. // Save cross-reference to Column buffer 
  3696. $ref = count($this->PageLinks[$this->page]) - 1; // *COLUMNS* 
  3697. $this->columnLinks[$this->CurrCol][INTVAL($this->x)][INTVAL($this->y)] = $ref; // *COLUMNS* 
  3698.  
  3699. function Text($x, $y, $txt, $OTLdata = array(), $textvar = 0, $aixextra = '', $coordsys = '', $return = false) 
  3700. // Output (or return) a string 
  3701. // Called (internally) by Watermark() & _tableWrite() [rotated cells] & TableHeaderFooter() & WriteText() 
  3702. // Called also from classes/svg.php 
  3703. // Expects Font to be set 
  3704. // Expects input to be mb_encoded if necessary and RTL reversed & OTL processed 
  3705. // ARTIFICIAL BOLD AND ITALIC 
  3706. $s = 'q '; 
  3707. if ($this->falseBoldWeight && strpos($this->ReqFontStyle, "B") !== false && strpos($this->FontStyle, "B") === false) { 
  3708. $s .= '2 Tr 1 J 1 j '; 
  3709. $s .= sprintf('%.3F w ', ($this->FontSize / 130) * _MPDFK * $this->falseBoldWeight); 
  3710. $tc = strtoupper($this->TextColor); // change 0 0 0 rg to 0 0 0 RG 
  3711. if ($this->FillColor != $tc) { 
  3712. $s .= $tc . ' '; 
  3713. } // stroke (outline) = same colour as text(fill) 
  3714. if (strpos($this->ReqFontStyle, "I") !== false && strpos($this->FontStyle, "I") === false) { 
  3715. $aix = '1 0 0.261799 1 %.3F %.3F Tm'; 
  3716. } else { 
  3717. $aix = '%.3F %.3F Td'; 
  3718.  
  3719. $aix = $aixextra . $aix; 
  3720.  
  3721. if ($this->ColorFlag) 
  3722. $s.=$this->TextColor . ' '; 
  3723.  
  3724. $this->CurrentFont['used'] = true; 
  3725.  
  3726. if ($this->usingCoreFont) { 
  3727. $txt2 = str_replace(chr(160), chr(32), $txt); 
  3728. } else { 
  3729. $txt2 = str_replace(chr(194) . chr(160), chr(32), $txt); 
  3730.  
  3731. $px = $x; 
  3732. $py = $y; 
  3733. if ($coordsys != 'SVG') { 
  3734. $px = $x * _MPDFK; 
  3735. $py = ($this->h - $y) * _MPDFK; 
  3736.  
  3737.  
  3738. /** * ************** SIMILAR TO Cell() ************************ */ 
  3739.  
  3740. // IF corefonts AND NOT SmCaps AND NOT Kerning 
  3741. // Just output text 
  3742. if ($this->usingCoreFont && !($textvar & FC_SMALLCAPS) && !($textvar & FC_KERNING)) { 
  3743. $txt2 = $this->_escape($txt2); 
  3744. $s .=sprintf('BT ' . $aix . ' (%s) Tj ET', $px, $py, $txt2); 
  3745.  
  3746.  
  3747. // IF NOT corefonts [AND NO wordspacing] AND NOT SIP/SMP AND NOT SmCaps AND NOT Kerning AND NOT OTL 
  3748. // Just output text 
  3749. elseif (!$this->usingCoreFont && !($textvar & FC_SMALLCAPS) && !($textvar & FC_KERNING) && !(isset($this->CurrentFont['useOTL']) && ($this->CurrentFont['useOTL'] & 0xFF) && !empty($OTLdata['GPOSinfo']))) { 
  3750. // IF SIP/SMP 
  3751. if ($this->CurrentFont['sip'] || $this->CurrentFont['smp']) { 
  3752. $txt2 = $this->UTF8toSubset($txt2); 
  3753. $s .=sprintf('BT ' . $aix . ' %s Tj ET', $px, $py, $txt2); 
  3754. // NOT SIP/SMP 
  3755. else { 
  3756. $txt2 = $this->UTF8ToUTF16BE($txt2, false); 
  3757. $txt2 = $this->_escape($txt2); 
  3758. $s .=sprintf('BT ' . $aix . ' (%s) Tj ET', $px, $py, $txt2); 
  3759.  
  3760. // IF NOT corefonts [AND IS wordspacing] AND NOT SIP AND NOT SmCaps AND NOT Kerning AND NOT OTL 
  3761. // Not required here (cf. Cell() ) 
  3762. // ELSE (IF SmCaps || Kerning || OTL) [corefonts or not corefonts; SIP or SMP or BMP] 
  3763. else { 
  3764. $s .= $this->applyGPOSpdf($txt2, $aix, $px, $py, $OTLdata, $textvar); 
  3765. /** * ************** END ************************ */ 
  3766.  
  3767. $s .= ' '; 
  3768.  
  3769. if (($textvar & FD_UNDERLINE) && $txt != '') { // mPDF 5.7.1 
  3770. $c = strtoupper($this->TextColor); // change 0 0 0 rg to 0 0 0 RG 
  3771. if ($this->FillColor != $c) { 
  3772. $s.= ' ' . $c . ' '; 
  3773. if (isset($this->CurrentFont['up']) && $this->CurrentFont['up']) { 
  3774. $up = $this->CurrentFont['up']; 
  3775. } else { 
  3776. $up = -100; 
  3777. $adjusty = (-$up / 1000 * $this->FontSize); 
  3778. if (isset($this->CurrentFont['ut']) && $this->CurrentFont['ut']) { 
  3779. $ut = $this->CurrentFont['ut'] / 1000 * $this->FontSize; 
  3780. } else { 
  3781. $ut = 60 / 1000 * $this->FontSize; 
  3782. $olw = $this->LineWidth; 
  3783. $s.=' ' . (sprintf(' %.3F w', $ut * _MPDFK)); 
  3784. $s.=' ' . $this->_dounderline($x, $y + $adjusty, $txt, $OTLdata, $textvar); 
  3785. $s.=' ' . (sprintf(' %.3F w', $olw * _MPDFK)); 
  3786. if ($this->FillColor != $c) { 
  3787. $s.= ' ' . $this->FillColor . ' '; 
  3788. // STRIKETHROUGH 
  3789. if (($textvar & FD_LINETHROUGH) && $txt != '') { // mPDF 5.7.1 
  3790. $c = strtoupper($this->TextColor); // change 0 0 0 rg to 0 0 0 RG 
  3791. if ($this->FillColor != $c) { 
  3792. $s.= ' ' . $c . ' '; 
  3793. //Superscript and Subscript Y coordinate adjustment (now for striked-through texts) 
  3794. if (isset($this->CurrentFont['desc']['CapHeight']) && $this->CurrentFont['desc']['CapHeight']) { 
  3795. $ch = $this->CurrentFont['desc']['CapHeight']; 
  3796. } else { 
  3797. $ch = 700; 
  3798. $adjusty = (-$ch / 1000 * $this->FontSize) * 0.35; 
  3799. if (isset($this->CurrentFont['ut']) && $this->CurrentFont['ut']) { 
  3800. $ut = $this->CurrentFont['ut'] / 1000 * $this->FontSize; 
  3801. } else { 
  3802. $ut = 60 / 1000 * $this->FontSize; 
  3803. $olw = $this->LineWidth; 
  3804. $s.=' ' . (sprintf(' %.3F w', $ut * _MPDFK)); 
  3805. $s.=' ' . $this->_dounderline($x, $y + $adjusty, $txt, $OTLdata, $textvar); 
  3806. $s.=' ' . (sprintf(' %.3F w', $olw * _MPDFK)); 
  3807. if ($this->FillColor != $c) { 
  3808. $s.= ' ' . $this->FillColor . ' '; 
  3809. $s .= 'Q'; 
  3810.  
  3811. if ($return) { 
  3812. return $s . " \n"; 
  3813. $this->_out($s); 
  3814.  
  3815. /** -- DIRECTW -- */ 
  3816.  
  3817. function WriteText($x, $y, $txt) 
  3818. // Output a string using Text() but does encoding and text reversing of RTL 
  3819. $txt = $this->purify_utf8_text($txt); 
  3820. if ($this->text_input_as_HTML) { 
  3821. $txt = $this->all_entities_to_utf8($txt); 
  3822. if ($this->usingCoreFont) { 
  3823. $txt = mb_convert_encoding($txt, $this->mb_enc, 'UTF-8'); 
  3824.  
  3825. // DIRECTIONALITY 
  3826. if (preg_match("/([" . $this->pregRTLchars . "])/u", $txt)) { 
  3827. $this->biDirectional = true; 
  3828. } // *OTL* 
  3829.  
  3830. $textvar = 0; 
  3831. $save_OTLtags = $this->OTLtags; 
  3832. $this->OTLtags = array(); 
  3833. if ($this->useKerning) { 
  3834. if ($this->CurrentFont['haskernGPOS']) { 
  3835. $this->OTLtags['Plus'] .= ' kern'; 
  3836. } else { 
  3837. $textvar = ($textvar | FC_KERNING); 
  3838.  
  3839. /** -- OTL -- */ 
  3840. // Use OTL OpenType Table Layout - GSUB & GPOS 
  3841. if (isset($this->CurrentFont['useOTL']) && $this->CurrentFont['useOTL']) { 
  3842. $txt = $this->otl->applyOTL($txt, $this->CurrentFont['useOTL']); 
  3843. $OTLdata = $this->otl->OTLdata; 
  3844. /** -- END OTL -- */ 
  3845. $this->OTLtags = $save_OTLtags; 
  3846.  
  3847. $this->magic_reverse_dir($txt, $this->directionality, $OTLdata); 
  3848.  
  3849. $this->Text($x, $y, $txt, $OTLdata, $textvar); 
  3850.  
  3851. function WriteCell($w, $h = 0, $txt = '', $border = 0, $ln = 0, $align = '', $fill = 0, $link = '', $currentx = 0) 
  3852. //Output a cell using Cell() but does encoding and text reversing of RTL 
  3853. $txt = $this->purify_utf8_text($txt); 
  3854. if ($this->text_input_as_HTML) { 
  3855. $txt = $this->all_entities_to_utf8($txt); 
  3856. if ($this->usingCoreFont) { 
  3857. $txt = mb_convert_encoding($txt, $this->mb_enc, 'UTF-8'); 
  3858. // DIRECTIONALITY 
  3859. if (preg_match("/([" . $this->pregRTLchars . "])/u", $txt)) { 
  3860. $this->biDirectional = true; 
  3861. } // *OTL* 
  3862.  
  3863. $textvar = 0; 
  3864. $save_OTLtags = $this->OTLtags; 
  3865. $this->OTLtags = array(); 
  3866. if ($this->useKerning) { 
  3867. if ($this->CurrentFont['haskernGPOS']) { 
  3868. $this->OTLtags['Plus'] .= ' kern'; 
  3869. } else { 
  3870. $textvar = ($textvar | FC_KERNING); 
  3871.  
  3872. /** -- OTL -- */ 
  3873. // Use OTL OpenType Table Layout - GSUB & GPOS 
  3874. if (isset($this->CurrentFont['useOTL']) && $this->CurrentFont['useOTL']) { 
  3875. $txt = $this->otl->applyOTL($txt, $this->CurrentFont['useOTL']); 
  3876. $OTLdata = $this->otl->OTLdata; 
  3877. /** -- END OTL -- */ 
  3878. $this->OTLtags = $save_OTLtags; 
  3879.  
  3880. $this->magic_reverse_dir($txt, $this->directionality, $OTLdata); 
  3881.  
  3882. $this->Cell($w, $h, $txt, $border, $ln, $align, $fill, $link, $currentx, 0, 0, 'M', 0, false, $OTLdata, $textvar); 
  3883.  
  3884. /** -- END DIRECTW -- */ 
  3885.  
  3886. function ResetSpacing() 
  3887. if ($this->ws != 0) { 
  3888. $this->_out('BT 0 Tw ET'); 
  3889. $this->ws = 0; 
  3890. if ($this->charspacing != 0) { 
  3891. $this->_out('BT 0 Tc ET'); 
  3892. $this->charspacing = 0; 
  3893.  
  3894. function SetSpacing($cs, $ws) 
  3895. if (intval($cs * 1000) == 0) { 
  3896. $cs = 0; 
  3897. if ($cs) { 
  3898. $this->_out(sprintf('BT %.3F Tc ET', $cs)); 
  3899. } elseif ($this->charspacing != 0) { 
  3900. $this->_out('BT 0 Tc ET'); 
  3901. $this->charspacing = $cs; 
  3902. if (intval($ws * 1000) == 0) { 
  3903. $ws = 0; 
  3904. if ($ws) { 
  3905. $this->_out(sprintf('BT %.3F Tw ET', $ws)); 
  3906. } elseif ($this->ws != 0) { 
  3907. $this->_out('BT 0 Tw ET'); 
  3908. $this->ws = $ws; 
  3909.  
  3910. // WORD SPACING 
  3911. function GetJspacing($nc, $ns, $w, $inclCursive, &$cOTLdata) 
  3912. $kashida_present = false; 
  3913. $kashida_space = 0; 
  3914. if ($w > 0 && $inclCursive && isset($this->CurrentFont['useKashida']) && $this->CurrentFont['useKashida'] && !empty($cOTLdata)) { 
  3915. for ($c = 0; $c < count($cOTLdata); $c++) { 
  3916. for ($i = 0; $i < strlen($cOTLdata[$c]['group']); $i++) { 
  3917. if (isset($cOTLdata[$c]['GPOSinfo'][$i]['kashida']) && $cOTLdata[$c]['GPOSinfo'][$i]['kashida'] > 0) { 
  3918. $kashida_present = true; 
  3919. break 2; 
  3920.  
  3921. if ($kashida_present) { 
  3922. $k_ctr = 0; // Number of kashida points 
  3923. $k_total = 0; // Total of kashida values (priority) 
  3924. // Reset word 
  3925. $max_kashida_in_word = 0; 
  3926. $last_kashida_in_word = -1; 
  3927.  
  3928. for ($c = 0; $c < count($cOTLdata); $c++) { 
  3929. for ($i = 0; $i < strlen($cOTLdata[$c]['group']); $i++) { 
  3930.  
  3931. if ($cOTLdata[$c]['group']{$i} == 'S') { 
  3932. // Save from last word 
  3933. if ($max_kashida_in_word) { 
  3934. $k_ctr++; 
  3935. $k_total = $max_kashida_in_word; 
  3936. // Reset word 
  3937. $max_kashida_in_word = 0; 
  3938. $last_kashida_in_word = -1; 
  3939.  
  3940. if (isset($cOTLdata[$c]['GPOSinfo'][$i]['kashida']) && $cOTLdata[$c]['GPOSinfo'][$i]['kashida'] > 0) { 
  3941. if ($max_kashida_in_word) { 
  3942. if ($cOTLdata[$c]['GPOSinfo'][$i]['kashida'] > $max_kashida_in_word) { 
  3943. $max_kashida_in_word = $cOTLdata[$c]['GPOSinfo'][$i]['kashida']; 
  3944. $cOTLdata[$c]['GPOSinfo'][$last_kashida_in_word]['kashida'] = 0; 
  3945. $last_kashida_in_word = $i; 
  3946. } else { 
  3947. $cOTLdata[$c]['GPOSinfo'][$i]['kashida'] = 0; 
  3948. } else { 
  3949. $max_kashida_in_word = $cOTLdata[$c]['GPOSinfo'][$i]['kashida']; 
  3950. $last_kashida_in_word = $i; 
  3951. // Save from last word 
  3952. if ($max_kashida_in_word) { 
  3953. $k_ctr++; 
  3954. $k_total = $max_kashida_in_word; 
  3955.  
  3956. // Number of kashida points = $k_ctr 
  3957. // $useKashida is a % value from CurrentFont/config_fonts.php 
  3958. // % ratio divided between word-spacing and kashida-spacing 
  3959. $kashida_space_ratio = intval($this->CurrentFont['useKashida']) / 100; 
  3960.  
  3961.  
  3962. $kashida_space = $w * $kashida_space_ratio; 
  3963.  
  3964. $tatw = $this->_getCharWidth($this->CurrentFont['cw'], 0x0640); 
  3965. // Only use kashida if each allocated kashida width is > 0.01 x width of a tatweel 
  3966. // Otherwise fontstretch is too small and errors 
  3967. // If not just leave to adjust word-spacing 
  3968. if ($tatw && (($kashida_space / $k_ctr) / $tatw) > 0.01) { 
  3969. for ($c = 0; $c < count($cOTLdata); $c++) { 
  3970. for ($i = 0; $i < strlen($cOTLdata[$c]['group']); $i++) { 
  3971. if (isset($cOTLdata[$c]['GPOSinfo'][$i]['kashida']) && $cOTLdata[$c]['GPOSinfo'][$i]['kashida'] > 0) { 
  3972. // At this point kashida is a number representing priority (higher number - higher priority) 
  3973. // We are now going to set it as an actual length 
  3974. // This shares it equally amongst words: 
  3975. $cOTLdata[$c]['GPOSinfo'][$i]['kashida_space'] = (1 / $k_ctr) * $kashida_space; 
  3976. $w -= $kashida_space; 
  3977.  
  3978. $ws = 0; 
  3979. $charspacing = 0; 
  3980. $ww = $this->jSWord; 
  3981. $ncx = $nc - 1; 
  3982. if ($nc == 0) { 
  3983. return array(0, 0, 0); 
  3984. // Only word spacing allowed / possible 
  3985. elseif ($this->fixedlSpacing !== false || $inclCursive) { 
  3986. if ($ns) { 
  3987. $ws = $w / $ns; 
  3988. } elseif ($nc == 1) { 
  3989. $charspacing = $w; 
  3990. } elseif (!$ns) { 
  3991. $charspacing = $w / ($ncx ); 
  3992. if (($this->jSmaxChar > 0) && ($charspacing > $this->jSmaxChar)) { 
  3993. $charspacing = $this->jSmaxChar; 
  3994. } elseif ($ns == ($ncx )) { 
  3995. $charspacing = $w / $ns; 
  3996. } else { 
  3997. if ($this->usingCoreFont) { 
  3998. $cs = ($w * (1 - $this->jSWord)) / ($ncx ); 
  3999. if (($this->jSmaxChar > 0) && ($cs > $this->jSmaxChar)) { 
  4000. $cs = $this->jSmaxChar; 
  4001. $ww = 1 - (($cs * ($ncx )) / $w); 
  4002. $charspacing = $cs; 
  4003. $ws = ($w * ($ww) ) / $ns; 
  4004. } else { 
  4005. $cs = ($w * (1 - $this->jSWord)) / ($ncx - $ns); 
  4006. if (($this->jSmaxChar > 0) && ($cs > $this->jSmaxChar)) { 
  4007. $cs = $this->jSmaxChar; 
  4008. $ww = 1 - (($cs * ($ncx - $ns)) / $w); 
  4009. $charspacing = $cs; 
  4010. $ws = (($w * ($ww) ) / $ns) - $charspacing; 
  4011. return array($charspacing, $ws, $kashida_space); 
  4012.  
  4013. function Cell($w, $h = 0, $txt = '', $border = 0, $ln = 0, $align = '', $fill = 0, $link = '', $currentx = 0, $lcpaddingL = 0, $lcpaddingR = 0, $valign = 'M', $spanfill = 0, $exactWidth = false, $OTLdata = false, $textvar = 0, $lineBox = false) 
  4014. { // mPDF 5.7.1 
  4015. //Output a cell 
  4016. // Expects input to be mb_encoded if necessary and RTL reversed 
  4017. // NON_BREAKING SPACE 
  4018. if ($this->usingCoreFont) { 
  4019. $txt = str_replace(chr(160), chr(32), $txt); 
  4020. } else { 
  4021. $txt = str_replace(chr(194) . chr(160), chr(32), $txt); 
  4022.  
  4023. $oldcolumn = $this->CurrCol; 
  4024. // Automatic page break 
  4025. // Allows PAGE-BREAK-AFTER = avoid to work 
  4026. if (isset($this->blk[$this->blklvl])) { 
  4027. $bottom = $this->blk[$this->blklvl]['padding_bottom'] + $this->blk[$this->blklvl]['margin_bottom']; 
  4028. } else { 
  4029. $bottom = 0; 
  4030. if (!$this->tableLevel && (($this->y + $this->divheight > $this->PageBreakTrigger) || ($this->y + $h > $this->PageBreakTrigger) || 
  4031. ($this->y + ($h * 2) + $bottom > $this->PageBreakTrigger && $this->blk[$this->blklvl]['page_break_after_avoid'])) and ! $this->InFooter and $this->AcceptPageBreak()) { // mPDF 5.7.2 
  4032. $x = $this->x; //Current X position 
  4033. // WORD SPACING 
  4034. $ws = $this->ws; //Word Spacing 
  4035. $charspacing = $this->charspacing; //Character Spacing 
  4036. $this->ResetSpacing(); 
  4037.  
  4038. $this->AddPage($this->CurOrientation); 
  4039. // Added to correct for OddEven Margins 
  4040. $x += $this->MarginCorrection; 
  4041. if ($currentx) { 
  4042. $currentx += $this->MarginCorrection; 
  4043. $this->x = $x; 
  4044. // WORD SPACING 
  4045. $this->SetSpacing($charspacing, $ws); 
  4046.  
  4047. // Test: to put line through centre of cell: $this->Line($this->x, $this->y+($h/2), $this->x+50, $this->y+($h/2)); 
  4048. // Test: to put border around cell as it is specified: $border='LRTB'; 
  4049.  
  4050.  
  4051. /** -- COLUMNS -- */ 
  4052. // COLS 
  4053. // COLUMN CHANGE 
  4054. if ($this->CurrCol != $oldcolumn) { 
  4055. if ($currentx) { 
  4056. $currentx += $this->ChangeColumn * ($this->ColWidth + $this->ColGap); 
  4057. $this->x += $this->ChangeColumn * ($this->ColWidth + $this->ColGap); 
  4058.  
  4059. // COLUMNS Update/overwrite the lowest bottom of printing y value for a column 
  4060. if ($this->ColActive) { 
  4061. if ($h) { 
  4062. $this->ColDetails[$this->CurrCol]['bottom_margin'] = $this->y + $h; 
  4063. } else { 
  4064. $this->ColDetails[$this->CurrCol]['bottom_margin'] = $this->y + $this->divheight; 
  4065. /** -- END COLUMNS -- */ 
  4066.  
  4067.  
  4068. if ($w == 0) 
  4069. $w = $this->w - $this->rMargin - $this->x; 
  4070. $s = ''; 
  4071. if ($fill == 1 && $this->FillColor) { 
  4072. if ((isset($this->pageoutput[$this->page]['FillColor']) && $this->pageoutput[$this->page]['FillColor'] != $this->FillColor) || !isset($this->pageoutput[$this->page]['FillColor'])) { 
  4073. $s .= $this->FillColor . ' '; 
  4074. $this->pageoutput[$this->page]['FillColor'] = $this->FillColor; 
  4075.  
  4076.  
  4077. if ($lineBox && isset($lineBox['boxtop']) && $txt) { // i.e. always from WriteFlowingBlock/finishFlowingBlock (but not objects - 
  4078. // which only have $lineBox['top'] set) 
  4079. $boxtop = $this->y + $lineBox['boxtop']; 
  4080. $boxbottom = $this->y + $lineBox['boxbottom']; 
  4081. $glyphYorigin = $lineBox['glyphYorigin']; 
  4082. $baseline_shift = $lineBox['baseline-shift']; 
  4083. $bord_boxtop = $bg_boxtop = $boxtop = $boxtop - $baseline_shift; 
  4084. $bord_boxbottom = $bg_boxbottom = $boxbottom = $boxbottom - $baseline_shift; 
  4085. $bord_boxheight = $bg_boxheight = $boxheight = $boxbottom - $boxtop; 
  4086.  
  4087. // If inline element BACKGROUND has bounding box set by parent element: 
  4088. if (isset($lineBox['background-boxtop'])) { 
  4089. $bg_boxtop = $this->y + $lineBox['background-boxtop'] - $lineBox['background-baseline-shift']; 
  4090. $bg_boxbottom = $this->y + $lineBox['background-boxbottom'] - $lineBox['background-baseline-shift']; 
  4091. $bg_boxheight = $bg_boxbottom - $bg_boxtop; 
  4092. // If inline element BORDER has bounding box set by parent element: 
  4093. if (isset($lineBox['border-boxtop'])) { 
  4094. $bord_boxtop = $this->y + $lineBox['border-boxtop'] - $lineBox['border-baseline-shift']; 
  4095. $bord_boxbottom = $this->y + $lineBox['border-boxbottom'] - $lineBox['border-baseline-shift']; 
  4096. $bord_boxheight = $bord_boxbottom - $bord_boxtop; 
  4097. } else { 
  4098. $boxtop = $this->y; 
  4099. $boxheight = $h; 
  4100. $boxbottom = $this->y + $h; 
  4101. $baseline_shift = 0; 
  4102. if ($txt != '') { 
  4103. // FONT SIZE - this determines the baseline caculation 
  4104. $bfs = $this->FontSize; 
  4105. //Calculate baseline Superscript and Subscript Y coordinate adjustment 
  4106. $bfx = $this->baselineC; 
  4107. $baseline = $bfx * $bfs; 
  4108.  
  4109. if ($textvar & FA_SUPERSCRIPT) { 
  4110. $baseline_shift = $this->textparam['text-baseline']; 
  4111. } // mPDF 5.7.1 // mPDF 6 
  4112. elseif ($textvar & FA_SUBSCRIPT) { 
  4113. $baseline_shift = $this->textparam['text-baseline']; 
  4114. } // mPDF 5.7.1 // mPDF 6 
  4115. elseif ($this->bullet) { 
  4116. $baseline += ($bfx - 0.7) * $this->FontSize; 
  4117.  
  4118. // Vertical align (for Images) 
  4119. if ($valign == 'T') { 
  4120. $va = (0.5 * $bfs * $this->normalLineheight); 
  4121. } elseif ($valign == 'B') { 
  4122. $va = $h - (0.5 * $bfs * $this->normalLineheight); 
  4123. } else { 
  4124. $va = 0.5 * $h; 
  4125. } // Middle 
  4126. // ONLY SET THESE IF WANT TO CONFINE BORDER +/- FILL TO FIT FONTSIZE - NOT FULL CELL AS IS ORIGINAL FUNCTION 
  4127. // spanfill or spanborder are set in FlowingBlock functions 
  4128. if ($spanfill || !empty($this->spanborddet) || $link != '') { 
  4129. $exth = 0.2; // Add to fontsize to increase height of background / link / border 
  4130. $boxtop = $this->y + $baseline + $va - ($this->FontSize * (1 + $exth / 2) * (0.5 + $bfx)); 
  4131. $boxheight = $this->FontSize * (1 + $exth); 
  4132. $boxbottom = $boxtop + $boxheight; 
  4133. $glyphYorigin = $baseline + $va; 
  4134. $boxtop -= $baseline_shift; 
  4135. $boxbottom -= $baseline_shift; 
  4136. $bord_boxtop = $bg_boxtop = $boxtop; 
  4137. $bord_boxbottom = $bg_boxbottom = $boxbottom; 
  4138. $bord_boxheight = $bg_boxheight = $boxheight = $boxbottom - $boxtop; 
  4139.  
  4140.  
  4141. $bbw = $tbw = $lbw = $rbw = 0; // Border widths 
  4142. if (!empty($this->spanborddet)) { 
  4143. if (!isset($this->spanborddet['B'])) { 
  4144. $this->spanborddet['B'] = array('s' => 0, 'style' => '', 'w' => 0); 
  4145. if (!isset($this->spanborddet['T'])) { 
  4146. $this->spanborddet['T'] = array('s' => 0, 'style' => '', 'w' => 0); 
  4147. if (!isset($this->spanborddet['L'])) { 
  4148. $this->spanborddet['L'] = array('s' => 0, 'style' => '', 'w' => 0); 
  4149. if (!isset($this->spanborddet['R'])) { 
  4150. $this->spanborddet['R'] = array('s' => 0, 'style' => '', 'w' => 0); 
  4151. $bbw = $this->spanborddet['B']['w']; 
  4152. $tbw = $this->spanborddet['T']['w']; 
  4153. $lbw = $this->spanborddet['L']['w']; 
  4154. $rbw = $this->spanborddet['R']['w']; 
  4155. if ($fill == 1 || $border == 1 || !empty($this->spanborddet)) { 
  4156. if (!empty($this->spanborddet)) { 
  4157. if ($fill == 1) { 
  4158. $s.=sprintf('%.3F %.3F %.3F %.3F re f ', ($this->x - $lbw) * _MPDFK, ($this->h - $bg_boxtop + $tbw) * _MPDFK, ($w + $lbw + $rbw) * _MPDFK, (-$bg_boxheight - $tbw - $bbw) * _MPDFK); 
  4159. $s.= ' q '; 
  4160. $dashon = 3; 
  4161. $dashoff = 3.5; 
  4162. $dot = 2.5; 
  4163. if ($tbw) { 
  4164. $short = 0; 
  4165. if ($this->spanborddet['T']['style'] == 'dashed') { 
  4166. $s.=sprintf(' 0 j 0 J [%.3F %.3F] 0 d ', $tbw * $dashon * _MPDFK, $tbw * $dashoff * _MPDFK); 
  4167. } elseif ($this->spanborddet['T']['style'] == 'dotted') { 
  4168. $s.=sprintf(' 1 j 1 J [%.3F %.3F] %.3F d ', 0.001, $tbw * $dot * _MPDFK, -$tbw / 2 * _MPDFK); 
  4169. $short = $tbw / 2; 
  4170. } else { 
  4171. $s.=' 0 j 0 J [] 0 d '; 
  4172. if ($this->spanborddet['T']['style'] != 'dotted') { 
  4173. $s .= 'q '; 
  4174. $s .= sprintf('%.3F %.3F m ', ($this->x - $lbw) * _MPDFK, ($this->h - $bord_boxtop + $tbw) * _MPDFK); 
  4175. $s .= sprintf('%.3F %.3F l ', ($this->x + $w + $rbw) * _MPDFK, ($this->h - $bord_boxtop + $tbw) * _MPDFK); 
  4176. $s .= sprintf('%.3F %.3F l ', ($this->x + $w) * _MPDFK, ($this->h - $bord_boxtop) * _MPDFK); 
  4177. $s .= sprintf('%.3F %.3F l ', ($this->x) * _MPDFK, ($this->h - $bord_boxtop) * _MPDFK); 
  4178. $s .= ' h W n '; // Ends path no-op & Sets the clipping path 
  4179. $c = $this->SetDColor($this->spanborddet['T']['c'], true); 
  4180. if ($this->spanborddet['T']['style'] == 'double') { 
  4181. $s.=sprintf(' %s %.3F w ', $c, $tbw / 3 * _MPDFK); 
  4182. $s.=sprintf('%.3F %.3F m %.3F %.3F l S ', ($this->x - $lbw) * _MPDFK, ($this->h - $bord_boxtop + $tbw * 5 / 6) * _MPDFK, ($this->x + $w + $rbw) * _MPDFK, ($this->h - $bord_boxtop + $tbw * 5 / 6) * _MPDFK); 
  4183. $s.=sprintf('%.3F %.3F m %.3F %.3F l S ', ($this->x - $lbw) * _MPDFK, ($this->h - $bord_boxtop + $tbw / 6) * _MPDFK, ($this->x + $w + $rbw) * _MPDFK, ($this->h - $bord_boxtop + $tbw / 6) * _MPDFK); 
  4184. } elseif ($this->spanborddet['T']['style'] == 'dotted') { 
  4185. $s.=sprintf(' %s %.3F w ', $c, $tbw * _MPDFK); 
  4186. $s.=sprintf('%.3F %.3F m %.3F %.3F l S ', ($this->x - $lbw) * _MPDFK, ($this->h - $bord_boxtop + $tbw / 2) * _MPDFK, ($this->x + $w + $rbw - $short) * _MPDFK, ($this->h - $bord_boxtop + $tbw / 2) * _MPDFK); 
  4187. } else { 
  4188. $s.=sprintf(' %s %.3F w ', $c, $tbw * _MPDFK); 
  4189. $s.=sprintf('%.3F %.3F m %.3F %.3F l S ', ($this->x - $lbw) * _MPDFK, ($this->h - $bord_boxtop + $tbw / 2) * _MPDFK, ($this->x + $w + $rbw - $short) * _MPDFK, ($this->h - $bord_boxtop + $tbw / 2) * _MPDFK); 
  4190. if ($this->spanborddet['T']['style'] != 'dotted') { 
  4191. $s .= ' Q '; 
  4192. if ($bbw) { 
  4193. $short = 0; 
  4194. if ($this->spanborddet['B']['style'] == 'dashed') { 
  4195. $s.=sprintf(' 0 j 0 J [%.3F %.3F] 0 d ', $bbw * $dashon * _MPDFK, $bbw * $dashoff * _MPDFK); 
  4196. } elseif ($this->spanborddet['B']['style'] == 'dotted') { 
  4197. $s.=sprintf(' 1 j 1 J [%.3F %.3F] %.3F d ', 0.001, $bbw * $dot * _MPDFK, -$bbw / 2 * _MPDFK); 
  4198. $short = $bbw / 2; 
  4199. } else { 
  4200. $s.=' 0 j 0 J [] 0 d '; 
  4201. if ($this->spanborddet['B']['style'] != 'dotted') { 
  4202. $s .= 'q '; 
  4203. $s .= sprintf('%.3F %.3F m ', ($this->x - $lbw) * _MPDFK, ($this->h - $bord_boxbottom - $bbw) * _MPDFK); 
  4204. $s .= sprintf('%.3F %.3F l ', ($this->x + $w + $rbw) * _MPDFK, ($this->h - $bord_boxbottom - $bbw) * _MPDFK); 
  4205. $s .= sprintf('%.3F %.3F l ', ($this->x + $w) * _MPDFK, ($this->h - $bord_boxbottom) * _MPDFK); 
  4206. $s .= sprintf('%.3F %.3F l ', ($this->x) * _MPDFK, ($this->h - $bord_boxbottom) * _MPDFK); 
  4207. $s .= ' h W n '; // Ends path no-op & Sets the clipping path 
  4208. $c = $this->SetDColor($this->spanborddet['B']['c'], true); 
  4209. if ($this->spanborddet['B']['style'] == 'double') { 
  4210. $s.=sprintf(' %s %.3F w ', $c, $bbw / 3 * _MPDFK); 
  4211. $s.=sprintf('%.3F %.3F m %.3F %.3F l S ', ($this->x - $lbw) * _MPDFK, ($this->h - $bord_boxbottom - $bbw / 6) * _MPDFK, ($this->x + $w + $rbw - $short) * _MPDFK, ($this->h - $bord_boxbottom - $bbw / 6) * _MPDFK); 
  4212. $s.=sprintf('%.3F %.3F m %.3F %.3F l S ', ($this->x - $lbw) * _MPDFK, ($this->h - $bord_boxbottom - $bbw * 5 / 6) * _MPDFK, ($this->x + $w + $rbw - $short) * _MPDFK, ($this->h - $bord_boxbottom - $bbw * 5 / 6) * _MPDFK); 
  4213. } elseif ($this->spanborddet['B']['style'] == 'dotted') { 
  4214. $s.=sprintf(' %s %.3F w ', $c, $bbw * _MPDFK); 
  4215. $s.=sprintf('%.3F %.3F m %.3F %.3F l S ', ($this->x - $lbw) * _MPDFK, ($this->h - $bord_boxbottom - $bbw / 2) * _MPDFK, ($this->x + $w + $rbw - $short) * _MPDFK, ($this->h - $bord_boxbottom - $bbw / 2) * _MPDFK); 
  4216. } else { 
  4217. $s.=sprintf(' %s %.3F w ', $c, $bbw * _MPDFK); 
  4218. $s.=sprintf('%.3F %.3F m %.3F %.3F l S ', ($this->x - $lbw) * _MPDFK, ($this->h - $bord_boxbottom - $bbw / 2) * _MPDFK, ($this->x + $w + $rbw - $short) * _MPDFK, ($this->h - $bord_boxbottom - $bbw / 2) * _MPDFK); 
  4219. if ($this->spanborddet['B']['style'] != 'dotted') { 
  4220. $s .= ' Q '; 
  4221. if ($lbw) { 
  4222. $short = 0; 
  4223. if ($this->spanborddet['L']['style'] == 'dashed') { 
  4224. $s.=sprintf(' 0 j 0 J [%.3F %.3F] 0 d ', $lbw * $dashon * _MPDFK, $lbw * $dashoff * _MPDFK); 
  4225. } elseif ($this->spanborddet['L']['style'] == 'dotted') { 
  4226. $s.=sprintf(' 1 j 1 J [%.3F %.3F] %.3F d ', 0.001, $lbw * $dot * _MPDFK, -$lbw / 2 * _MPDFK); 
  4227. $short = $lbw / 2; 
  4228. } else { 
  4229. $s.=' 0 j 0 J [] 0 d '; 
  4230. if ($this->spanborddet['L']['style'] != 'dotted') { 
  4231. $s .= 'q '; 
  4232. $s .= sprintf('%.3F %.3F m ', ($this->x - $lbw) * _MPDFK, ($this->h - $bord_boxbottom - $bbw) * _MPDFK); 
  4233. $s .= sprintf('%.3F %.3F l ', ($this->x) * _MPDFK, ($this->h - $bord_boxbottom) * _MPDFK); 
  4234. $s .= sprintf('%.3F %.3F l ', ($this->x) * _MPDFK, ($this->h - $bord_boxtop) * _MPDFK); 
  4235. $s .= sprintf('%.3F %.3F l ', ($this->x - $lbw) * _MPDFK, ($this->h - $bord_boxtop + $tbw) * _MPDFK); 
  4236. $s .= ' h W n '; // Ends path no-op & Sets the clipping path 
  4237. $c = $this->SetDColor($this->spanborddet['L']['c'], true); 
  4238. if ($this->spanborddet['L']['style'] == 'double') { 
  4239. $s.=sprintf(' %s %.3F w ', $c, $lbw / 3 * _MPDFK); 
  4240. $s.=sprintf('%.3F %.3F m %.3F %.3F l S ', ($this->x - $lbw / 6) * _MPDFK, ($this->h - $bord_boxtop + $tbw) * _MPDFK, ($this->x - $lbw / 6) * _MPDFK, ($this->h - $bord_boxbottom - $bbw + $short) * _MPDFK); 
  4241. $s.=sprintf('%.3F %.3F m %.3F %.3F l S ', ($this->x - $lbw * 5 / 6) * _MPDFK, ($this->h - $bord_boxtop + $tbw) * _MPDFK, ($this->x - $lbw * 5 / 6) * _MPDFK, ($this->h - $bord_boxbottom - $bbw + $short) * _MPDFK); 
  4242. } elseif ($this->spanborddet['L']['style'] == 'dotted') { 
  4243. $s.=sprintf(' %s %.3F w ', $c, $lbw * _MPDFK); 
  4244. $s.=sprintf('%.3F %.3F m %.3F %.3F l S ', ($this->x - $lbw / 2) * _MPDFK, ($this->h - $bord_boxtop + $tbw) * _MPDFK, ($this->x - $lbw / 2) * _MPDFK, ($this->h - $bord_boxbottom - $bbw + $short) * _MPDFK); 
  4245. } else { 
  4246. $s.=sprintf(' %s %.3F w ', $c, $lbw * _MPDFK); 
  4247. $s.=sprintf('%.3F %.3F m %.3F %.3F l S ', ($this->x - $lbw / 2) * _MPDFK, ($this->h - $bord_boxtop + $tbw) * _MPDFK, ($this->x - $lbw / 2) * _MPDFK, ($this->h - $bord_boxbottom - $bbw + $short) * _MPDFK); 
  4248. if ($this->spanborddet['L']['style'] != 'dotted') { 
  4249. $s .= ' Q '; 
  4250. if ($rbw) { 
  4251. $short = 0; 
  4252. if ($this->spanborddet['R']['style'] == 'dashed') { 
  4253. $s.=sprintf(' 0 j 0 J [%.3F %.3F] 0 d ', $rbw * $dashon * _MPDFK, $rbw * $dashoff * _MPDFK); 
  4254. } elseif ($this->spanborddet['R']['style'] == 'dotted') { 
  4255. $s.=sprintf(' 1 j 1 J [%.3F %.3F] %.3F d ', 0.001, $rbw * $dot * _MPDFK, -$rbw / 2 * _MPDFK); 
  4256. $short = $rbw / 2; 
  4257. } else { 
  4258. $s.=' 0 j 0 J [] 0 d '; 
  4259. if ($this->spanborddet['R']['style'] != 'dotted') { 
  4260. $s .= 'q '; 
  4261. $s .= sprintf('%.3F %.3F m ', ($this->x + $w + $rbw) * _MPDFK, ($this->h - $bord_boxbottom - $bbw) * _MPDFK); 
  4262. $s .= sprintf('%.3F %.3F l ', ($this->x + $w) * _MPDFK, ($this->h - $bord_boxbottom) * _MPDFK); 
  4263. $s .= sprintf('%.3F %.3F l ', ($this->x + $w) * _MPDFK, ($this->h - $bord_boxtop) * _MPDFK); 
  4264. $s .= sprintf('%.3F %.3F l ', ($this->x + $w + $rbw) * _MPDFK, ($this->h - $bord_boxtop + $tbw) * _MPDFK); 
  4265. $s .= ' h W n '; // Ends path no-op & Sets the clipping path 
  4266. $c = $this->SetDColor($this->spanborddet['R']['c'], true); 
  4267. if ($this->spanborddet['R']['style'] == 'double') { 
  4268. $s.=sprintf(' %s %.3F w ', $c, $rbw / 3 * _MPDFK); 
  4269. $s.=sprintf('%.3F %.3F m %.3F %.3F l S ', ($this->x + $w + $rbw / 6) * _MPDFK, ($this->h - $bord_boxtop + $tbw) * _MPDFK, ($this->x + $w + $rbw / 6) * _MPDFK, ($this->h - $bord_boxbottom - $bbw + $short) * _MPDFK); 
  4270. $s.=sprintf('%.3F %.3F m %.3F %.3F l S ', ($this->x + $w + $rbw * 5 / 6) * _MPDFK, ($this->h - $bord_boxtop + $tbw) * _MPDFK, ($this->x + $w + $rbw * 5 / 6) * _MPDFK, ($this->h - $bord_boxbottom - $bbw + $short) * _MPDFK); 
  4271. } elseif ($this->spanborddet['R']['style'] == 'dotted') { 
  4272. $s.=sprintf(' %s %.3F w ', $c, $rbw * _MPDFK); 
  4273. $s.=sprintf('%.3F %.3F m %.3F %.3F l S ', ($this->x + $w + $rbw / 2) * _MPDFK, ($this->h - $bord_boxtop + $tbw) * _MPDFK, ($this->x + $w + $rbw / 2) * _MPDFK, ($this->h - $bord_boxbottom - $bbw + $short) * _MPDFK); 
  4274. } else { 
  4275. $s.=sprintf(' %s %.3F w ', $c, $rbw * _MPDFK); 
  4276. $s.=sprintf('%.3F %.3F m %.3F %.3F l S ', ($this->x + $w + $rbw / 2) * _MPDFK, ($this->h - $bord_boxtop + $tbw) * _MPDFK, ($this->x + $w + $rbw / 2) * _MPDFK, ($this->h - $bord_boxbottom - $bbw + $short) * _MPDFK); 
  4277. if ($this->spanborddet['R']['style'] != 'dotted') { 
  4278. $s .= ' Q '; 
  4279. $s.= ' Q '; 
  4280. } else { // If "border", does not come from WriteFlowingBlock or FinishFlowingBlock 
  4281. if ($fill == 1) 
  4282. $op = ($border == 1) ? 'B' : 'f'; 
  4283. else 
  4284. $op = 'S'; 
  4285. $s.=sprintf('%.3F %.3F %.3F %.3F re %s ', $this->x * _MPDFK, ($this->h - $bg_boxtop) * _MPDFK, $w * _MPDFK, -$bg_boxheight * _MPDFK, $op); 
  4286.  
  4287. if (is_string($border)) { // If "border", does not come from WriteFlowingBlock or FinishFlowingBlock 
  4288. $x = $this->x; 
  4289. $y = $this->y; 
  4290. if (is_int(strpos($border, 'L'))) 
  4291. $s.=sprintf('%.3F %.3F m %.3F %.3F l S ', $x * _MPDFK, ($this->h - $bord_boxtop) * _MPDFK, $x * _MPDFK, ($this->h - ($bord_boxbottom)) * _MPDFK); 
  4292. if (is_int(strpos($border, 'T'))) 
  4293. $s.=sprintf('%.3F %.3F m %.3F %.3F l S ', $x * _MPDFK, ($this->h - $bord_boxtop) * _MPDFK, ($x + $w) * _MPDFK, ($this->h - $bord_boxtop) * _MPDFK); 
  4294. if (is_int(strpos($border, 'R'))) 
  4295. $s.=sprintf('%.3F %.3F m %.3F %.3F l S ', ($x + $w) * _MPDFK, ($this->h - $bord_boxtop) * _MPDFK, ($x + $w) * _MPDFK, ($this->h - ($bord_boxbottom)) * _MPDFK); 
  4296. if (is_int(strpos($border, 'B'))) 
  4297. $s.=sprintf('%.3F %.3F m %.3F %.3F l S ', $x * _MPDFK, ($this->h - ($bord_boxbottom)) * _MPDFK, ($x + $w) * _MPDFK, ($this->h - ($bord_boxbottom)) * _MPDFK); 
  4298.  
  4299. if ($txt != '') { 
  4300.  
  4301.  
  4302. if ($exactWidth) 
  4303. $stringWidth = $w; 
  4304. else 
  4305. $stringWidth = $this->GetStringWidth($txt, true, $OTLdata, $textvar) + ( $this->charspacing * mb_strlen($txt, $this->mb_enc) / _MPDFK ) + ( $this->ws * mb_substr_count($txt, ' ', $this->mb_enc) / _MPDFK ); 
  4306.  
  4307. // Set x OFFSET FOR PRINTING 
  4308. if ($align == 'R') { 
  4309. $dx = $w - $this->cMarginR - $stringWidth - $lcpaddingR; 
  4310. } elseif ($align == 'C') { 
  4311. $dx = (($w - $stringWidth ) / 2); 
  4312. } elseif ($align == 'L' or $align == 'J') 
  4313. $dx = $this->cMarginL + $lcpaddingL; 
  4314. else 
  4315. $dx = 0; 
  4316.  
  4317. if ($this->ColorFlag) 
  4318. $s .='q ' . $this->TextColor . ' '; 
  4319.  
  4320. // OUTLINE 
  4321. if (isset($this->textparam['outline-s']) && $this->textparam['outline-s'] && !($textvar & FC_SMALLCAPS)) { // mPDF 5.7.1 
  4322. $s .=' ' . sprintf('%.3F w', $this->LineWidth * _MPDFK) . ' '; 
  4323. $s .=" $this->DrawColor "; 
  4324. $s .=" 2 Tr "; 
  4325. } elseif ($this->falseBoldWeight && strpos($this->ReqFontStyle, "B") !== false && strpos($this->FontStyle, "B") === false && !($textvar & FC_SMALLCAPS)) { // can't use together with OUTLINE or Small Caps // mPDF 5.7.1 ??? why not with SmallCaps ??? 
  4326. $s .= ' 2 Tr 1 J 1 j '; 
  4327. $s .= ' ' . sprintf('%.3F w', ($this->FontSize / 130) * _MPDFK * $this->falseBoldWeight) . ' '; 
  4328. $tc = strtoupper($this->TextColor); // change 0 0 0 rg to 0 0 0 RG 
  4329. if ($this->FillColor != $tc) { 
  4330. $s .= ' ' . $tc . ' '; 
  4331. } // stroke (outline) = same colour as text(fill) 
  4332. } else { 
  4333. $s .=" 0 Tr "; 
  4334.  
  4335. if (strpos($this->ReqFontStyle, "I") !== false && strpos($this->FontStyle, "I") === false) { // Artificial italic 
  4336. $aix = '1 0 0.261799 1 %.3F %.3F Tm '; 
  4337. } else { 
  4338. $aix = '%.3F %.3F Td '; 
  4339.  
  4340. $px = ($this->x + $dx) * _MPDFK; 
  4341. $py = ($this->h - ($this->y + $glyphYorigin - $baseline_shift)) * _MPDFK; 
  4342.  
  4343. // THE TEXT 
  4344. $txt2 = $txt; 
  4345. $sub = ''; 
  4346. $this->CurrentFont['used'] = true; 
  4347.  
  4348. /** * ************** SIMILAR TO Text() ************************ */ 
  4349.  
  4350. // IF corefonts AND NOT SmCaps AND NOT Kerning 
  4351. // Just output text; charspacing and wordspacing already set by charspacing (Tc) and ws (Tw) 
  4352. if ($this->usingCoreFont && !($textvar & FC_SMALLCAPS) && !($textvar & FC_KERNING)) { 
  4353. $txt2 = $this->_escape($txt2); 
  4354. $sub .=sprintf('BT ' . $aix . ' (%s) Tj ET', $px, $py, $txt2); 
  4355.  
  4356.  
  4357. // IF NOT corefonts AND NO wordspacing AND NOT SIP/SMP AND NOT SmCaps AND NOT Kerning AND NOT OTL 
  4358. // Just output text 
  4359. elseif (!$this->usingCoreFont && !$this->ws && !($textvar & FC_SMALLCAPS) && !($textvar & FC_KERNING) && !(isset($this->CurrentFont['useOTL']) && ($this->CurrentFont['useOTL'] & 0xFF) && !empty($OTLdata['GPOSinfo']))) { 
  4360. // IF SIP/SMP 
  4361. if ((isset($this->CurrentFont['sip']) && $this->CurrentFont['sip']) || (isset($this->CurrentFont['smp']) && $this->CurrentFont['smp'])) { 
  4362. $txt2 = $this->UTF8toSubset($txt2); 
  4363. $sub .=sprintf('BT ' . $aix . ' %s Tj ET', $px, $py, $txt2); 
  4364. // NOT SIP/SMP 
  4365. else { 
  4366. $txt2 = $this->UTF8ToUTF16BE($txt2, false); 
  4367. $txt2 = $this->_escape($txt2); 
  4368. $sub .=sprintf('BT ' . $aix . ' (%s) Tj ET', $px, $py, $txt2); 
  4369.  
  4370.  
  4371. // IF NOT corefonts AND IS wordspacing AND NOT SIP AND NOT SmCaps AND NOT Kerning AND NOT OTL 
  4372. // Output text word by word with an adjustment to the intercharacter spacing for SPACEs to form word spacing 
  4373. // IF multibyte - Tw has no effect - need to do word spacing using an adjustment before each space 
  4374. elseif (!$this->usingCoreFont && $this->ws && !((isset($this->CurrentFont['sip']) && $this->CurrentFont['sip']) || (isset($this->CurrentFont['smp']) && $this->CurrentFont['smp'])) && !($textvar & FC_SMALLCAPS) && !($textvar & FC_KERNING) && !(isset($this->CurrentFont['useOTL']) && ($this->CurrentFont['useOTL'] & 0xFF) && (!empty($OTLdata['GPOSinfo']) || (strpos($OTLdata['group'], 'M') !== false && $this->charspacing)) )) { 
  4375. $space = " "; 
  4376. $space = $this->UTF8ToUTF16BE($space, false); 
  4377. $space = $this->_escape($space); 
  4378. $sub .=sprintf('BT ' . $aix . ' %.3F Tc [', $px, $py, $this->charspacing); 
  4379. $t = explode(' ', $txt2); 
  4380. $numt = count($t); 
  4381. for ($i = 0; $i < $numt; $i++) { 
  4382. $tx = $t[$i]; 
  4383. $tx = $this->UTF8ToUTF16BE($tx, false); 
  4384. $tx = $this->_escape($tx); 
  4385. $sub .=sprintf('(%s) ', $tx); 
  4386. if (($i + 1) < $numt) { 
  4387. $adj = -($this->ws) * 1000 / $this->FontSizePt; 
  4388. $sub .=sprintf('%d(%s) ', $adj, $space); 
  4389. $sub .='] TJ '; 
  4390. $sub .=' ET'; 
  4391.  
  4392.  
  4393. // ELSE (IF SmCaps || Kerning || OTL) [corefonts or not corefonts; SIP or SMP or BMP] 
  4394. else { 
  4395. $sub = $this->applyGPOSpdf($txt, $aix, $px, $py, $OTLdata, $textvar); 
  4396.  
  4397. /** * ************** END SIMILAR TO Text() ************************ */ 
  4398.  
  4399. if ($this->shrin_k > 1) { 
  4400. $shrin_k = $this->shrin_k; 
  4401. } else { 
  4402. $shrin_k = 1; 
  4403. // UNDERLINE 
  4404. if ($textvar & FD_UNDERLINE) { // mPDF 5.7.1 // mPDF 6 
  4405. // mPDF 5.7.3 inline text-decoration parameters 
  4406. $c = $this->textparam['u-decoration']['color']; 
  4407. if ($this->FillColor != $c) { 
  4408. $sub .= ' ' . $c . ' '; 
  4409. // mPDF 5.7.3 inline text-decoration parameters 
  4410. $decorationfontkey = $this->textparam['u-decoration']['fontkey']; 
  4411. $decorationfontsize = $this->textparam['u-decoration']['fontsize'] / $shrin_k; 
  4412. if (isset($this->fonts[$decorationfontkey]['ut']) && $this->fonts[$decorationfontkey]['ut']) { 
  4413. $ut = $this->fonts[$decorationfontkey]['ut'] / 1000 * $decorationfontsize; 
  4414. } else { 
  4415. $ut = 60 / 1000 * $decorationfontsize; 
  4416. if (isset($this->fonts[$decorationfontkey]['up']) && $this->fonts[$decorationfontkey]['up']) { 
  4417. $up = $this->fonts[$decorationfontkey]['up']; 
  4418. } else { 
  4419. $up = -100; 
  4420. $adjusty = (-$up / 1000 * $decorationfontsize) + $ut / 2; 
  4421. $ubaseline = $glyphYorigin - $this->textparam['u-decoration']['baseline'] / $shrin_k; 
  4422. $olw = $this->LineWidth; 
  4423. $sub .=' ' . (sprintf(' %.3F w 0 j 0 J ', $ut * _MPDFK)); 
  4424. $sub .=' ' . $this->_dounderline($this->x + $dx, $this->y + $ubaseline + $adjusty, $txt, $OTLdata, $textvar); 
  4425. $sub .=' ' . (sprintf(' %.3F w 2 j 2 J ', $olw * _MPDFK)); 
  4426. if ($this->FillColor != $c) { 
  4427. $sub .= ' ' . $this->FillColor . ' '; 
  4428.  
  4429. // STRIKETHROUGH 
  4430. if ($textvar & FD_LINETHROUGH) { // mPDF 5.7.1 // mPDF 6 
  4431. // mPDF 5.7.3 inline text-decoration parameters 
  4432. $c = $this->textparam['s-decoration']['color']; 
  4433. if ($this->FillColor != $c) { 
  4434. $sub .= ' ' . $c . ' '; 
  4435. // mPDF 5.7.3 inline text-decoration parameters 
  4436. $decorationfontkey = $this->textparam['s-decoration']['fontkey']; 
  4437. $decorationfontsize = $this->textparam['s-decoration']['fontsize'] / $shrin_k; 
  4438. // Use yStrikeoutSize from OS/2 if available 
  4439. if (isset($this->fonts[$decorationfontkey]['strs']) && $this->fonts[$decorationfontkey]['strs']) { 
  4440. $ut = $this->fonts[$decorationfontkey]['strs'] / 1000 * $decorationfontsize; 
  4441. // else use underlineThickness from post if available 
  4442. elseif (isset($this->fonts[$decorationfontkey]['ut']) && $this->fonts[$decorationfontkey]['ut']) { 
  4443. $ut = $this->fonts[$decorationfontkey]['ut'] / 1000 * $decorationfontsize; 
  4444. } else { 
  4445. $ut = 50 / 1000 * $decorationfontsize; 
  4446. // Use yStrikeoutPosition from OS/2 if available 
  4447. if (isset($this->fonts[$decorationfontkey]['strp']) && $this->fonts[$decorationfontkey]['strp']) { 
  4448. $up = $this->fonts[$decorationfontkey]['strp']; 
  4449. $adjusty = (-$up / 1000 * $decorationfontsize); 
  4450. // else use a fraction ($this->baselineS) of CapHeight 
  4451. else { 
  4452. if (isset($this->fonts[$decorationfontkey]['desc']['CapHeight']) && $this->fonts[$decorationfontkey]['desc']['CapHeight']) { 
  4453. $ch = $this->fonts[$decorationfontkey]['desc']['CapHeight']; 
  4454. } else { 
  4455. $ch = 700; 
  4456. $adjusty = (-$ch / 1000 * $decorationfontsize) * $this->baselineS; 
  4457.  
  4458. $sbaseline = $glyphYorigin - $this->textparam['s-decoration']['baseline'] / $shrin_k; 
  4459. $olw = $this->LineWidth; 
  4460. $sub .=' ' . (sprintf(' %.3F w 0 j 0 J ', $ut * _MPDFK)); 
  4461. $sub .=' ' . $this->_dounderline($this->x + $dx, $this->y + $sbaseline + $adjusty, $txt, $OTLdata, $textvar); 
  4462. $sub .=' ' . (sprintf(' %.3F w 2 j 2 J ', $olw * _MPDFK)); 
  4463. if ($this->FillColor != $c) { 
  4464. $sub .= ' ' . $this->FillColor . ' '; 
  4465.  
  4466. // mPDF 5.7.3 inline text-decoration parameters 
  4467. // OVERLINE 
  4468. if ($textvar & FD_OVERLINE) { // mPDF 5.7.1 // mPDF 6 
  4469. // mPDF 5.7.3 inline text-decoration parameters 
  4470. $c = $this->textparam['o-decoration']['color']; 
  4471. if ($this->FillColor != $c) { 
  4472. $sub .= ' ' . $c . ' '; 
  4473. // mPDF 5.7.3 inline text-decoration parameters 
  4474. $decorationfontkey = $this->textparam['o-decoration']['fontkey'] / $shrin_k; 
  4475. $decorationfontsize = $this->textparam['o-decoration']['fontsize']; 
  4476. if (isset($this->fonts[$decorationfontkey]['ut']) && $this->fonts[$decorationfontkey]['ut']) { 
  4477. $ut = $this->fonts[$decorationfontkey]['ut'] / 1000 * $decorationfontsize; 
  4478. } else { 
  4479. $ut = 60 / 1000 * $decorationfontsize; 
  4480. if (isset($this->fonts[$decorationfontkey]['desc']['CapHeight']) && $this->fonts[$decorationfontkey]['desc']['CapHeight']) { 
  4481. $ch = $this->fonts[$decorationfontkey]['desc']['CapHeight']; 
  4482. } else { 
  4483. $ch = 700; 
  4484. $adjusty = (-$ch / 1000 * $decorationfontsize) * $this->baselineO; 
  4485. $obaseline = $glyphYorigin - $this->textparam['o-decoration']['baseline'] / $shrin_k; 
  4486. $olw = $this->LineWidth; 
  4487. $sub .=' ' . (sprintf(' %.3F w 0 j 0 J ', $ut * _MPDFK)); 
  4488. $sub .=' ' . $this->_dounderline($this->x + $dx, $this->y + $obaseline + $adjusty, $txt, $OTLdata, $textvar); 
  4489. $sub .=' ' . (sprintf(' %.3F w 2 j 2 J ', $olw * _MPDFK)); 
  4490. if ($this->FillColor != $c) { 
  4491. $sub .= ' ' . $this->FillColor . ' '; 
  4492.  
  4493. // TEXT SHADOW 
  4494. if ($this->textshadow) { // First to process is last in CSS comma separated shadows 
  4495. foreach ($this->textshadow AS $ts) { 
  4496. $s .= ' q '; 
  4497. $s .= $this->SetTColor($ts['col'], true) . "\n"; 
  4498. if ($ts['col']{0} == 5 && ord($ts['col']{4}) < 100) { // RGBa 
  4499. $s .= $this->SetAlpha(ord($ts['col']{4}) / 100, 'Normal', true, 'F') . "\n"; 
  4500. } elseif ($ts['col']{0} == 6 && ord($ts['col']{5}) < 100) { // CMYKa 
  4501. $s .= $this->SetAlpha(ord($ts['col']{5}) / 100, 'Normal', true, 'F') . "\n"; 
  4502. } elseif ($ts['col']{0} == 1 && $ts['col']{2} == 1 && ord($ts['col']{3}) < 100) { // Gray 
  4503. $s .= $this->SetAlpha(ord($ts['col']{3}) / 100, 'Normal', true, 'F') . "\n"; 
  4504. $s .= sprintf(' 1 0 0 1 %.4F %.4F cm', $ts['x'] * _MPDFK, -$ts['y'] * _MPDFK) . "\n"; 
  4505. $s .= $sub; 
  4506. $s .= ' Q '; 
  4507.  
  4508. $s .= $sub; 
  4509.  
  4510. // COLOR 
  4511. if ($this->ColorFlag) 
  4512. $s .=' Q'; 
  4513.  
  4514. // LINK 
  4515. if ($link != '') { 
  4516. $this->Link($this->x, $boxtop, $w, $boxheight, $link); 
  4517. if ($s) 
  4518. $this->_out($s); 
  4519.  
  4520. // WORD SPACING 
  4521. if ($this->ws && !$this->usingCoreFont) { 
  4522. $this->_out(sprintf('BT %.3F Tc ET', $this->charspacing)); 
  4523. $this->lasth = $h; 
  4524. if (strpos($txt, "\n") !== false) 
  4525. $ln = 1; // cell recognizes \n from <BR> tag 
  4526. if ($ln > 0) { 
  4527. //Go to next line 
  4528. $this->y += $h; 
  4529. if ($ln == 1) { 
  4530. //Move to next line 
  4531. if ($currentx != 0) { 
  4532. $this->x = $currentx; 
  4533. } else { 
  4534. $this->x = $this->lMargin; 
  4535. } else 
  4536. $this->x+=$w; 
  4537.  
  4538. function applyGPOSpdf($txt, $aix, $x, $y, $OTLdata, $textvar = 0) 
  4539. // Generate PDF string 
  4540. //============================== 
  4541. if ((isset($this->CurrentFont['sip']) && $this->CurrentFont['sip']) || (isset($this->CurrentFont['smp']) && $this->CurrentFont['smp'])) { 
  4542. $sipset = true; 
  4543. } else { 
  4544. $sipset = false; 
  4545.  
  4546. if ($textvar & FC_SMALLCAPS) { 
  4547. $smcaps = true; 
  4548. } // IF SmallCaps using transformation, NOT OTL 
  4549. else { 
  4550. $smcaps = false; 
  4551.  
  4552. if ($sipset) { 
  4553. $fontid = $last_fontid = $original_fontid = $this->CurrentFont['subsetfontids'][0]; 
  4554. } else { 
  4555. $fontid = $last_fontid = $original_fontid = $this->CurrentFont['i']; 
  4556. $SmallCapsON = false; // state: uppercase/not 
  4557. $lastSmallCapsON = false; // state: uppercase/not 
  4558. $last_fontsize = $fontsize = $this->FontSizePt; 
  4559. $last_fontstretch = $fontstretch = 100; 
  4560. $groupBreak = false; 
  4561.  
  4562. $unicode = $this->UTF8StringToArray($txt); 
  4563.  
  4564. $GPOSinfo = (isset($OTLdata['GPOSinfo']) ? $OTLdata['GPOSinfo'] : array()); 
  4565. $charspacing = ($this->charspacing * 1000 / $this->FontSizePt); 
  4566. $wordspacing = ($this->ws * 1000 / $this->FontSizePt); 
  4567.  
  4568. $XshiftBefore = 0; 
  4569. $XshiftAfter = 0; 
  4570. $lastYPlacement = 0; 
  4571.  
  4572. if ($sipset) { 
  4573. // mPDF 6 DELETED ******** 
  4574. // $txt= preg_replace('/'.preg_quote($this->aliasNbPg, '/').'/', chr(7), $txt); // ? Need to adjust OTL info 
  4575. // $txt= preg_replace('/'.preg_quote($this->aliasNbPgGp, '/').'/', chr(8), $txt); // ? Need to adjust OTL info 
  4576. $tj = '<'; 
  4577. } else { 
  4578. $tj = '('; 
  4579.  
  4580. for ($i = 0; $i < count($unicode); $i++) { 
  4581. $c = $unicode[$i]; 
  4582. $tx = ''; 
  4583. $XshiftBefore = $XshiftAfter; 
  4584. $XshiftAfter = 0; 
  4585. $YPlacement = 0; 
  4586. $groupBreak = false; 
  4587. $kashida = 0; 
  4588. if (!empty($OTLdata)) { 
  4589. // YPlacement from GPOS 
  4590. if (isset($GPOSinfo[$i]['YPlacement']) && $GPOSinfo[$i]['YPlacement']) { 
  4591. $YPlacement = $GPOSinfo[$i]['YPlacement'] * $this->FontSizePt / $this->CurrentFont['unitsPerEm']; 
  4592. $groupBreak = true; 
  4593. // XPlacement from GPOS 
  4594. if (isset($GPOSinfo[$i]['XPlacement']) && $GPOSinfo[$i]['XPlacement']) { 
  4595.  
  4596. if (!isset($GPOSinfo[$i]['wDir']) || $GPOSinfo[$i]['wDir'] != 'RTL') { 
  4597. if (isset($GPOSinfo[$i]['BaseWidth'])) { 
  4598. $GPOSinfo[$i]['XPlacement'] -= $GPOSinfo[$i]['BaseWidth']; 
  4599.  
  4600. // Convert to PDF Text space (thousandths of a unit ); 
  4601. $XshiftBefore += $GPOSinfo[$i]['XPlacement'] * 1000 / $this->CurrentFont['unitsPerEm']; 
  4602. $XshiftAfter += -$GPOSinfo[$i]['XPlacement'] * 1000 / $this->CurrentFont['unitsPerEm']; 
  4603.  
  4604. // Kashida from GPOS 
  4605. // Kashida is set as an absolute length value, but to adjust text needs to be converted to 
  4606. // font-related size 
  4607. if (isset($GPOSinfo[$i]['kashida_space']) && $GPOSinfo[$i]['kashida_space']) { 
  4608. $kashida = $GPOSinfo[$i]['kashida_space']; 
  4609.  
  4610. if ($c == 32) { // word spacing 
  4611. $XshiftAfter += $wordspacing; 
  4612.  
  4613. if (substr($OTLdata['group'], ($i + 1), 1) != 'M') { // Don't add inter-character spacing before Marks 
  4614. $XshiftAfter += $charspacing; 
  4615.  
  4616. // ...applyGPOSpdf... 
  4617. // XAdvance from GPOS - Convert to PDF Text space (thousandths of a unit ); 
  4618. if (((isset($GPOSinfo[$i]['wDir']) && $GPOSinfo[$i]['wDir'] != 'RTL') || !isset($GPOSinfo[$i]['wDir'])) && isset($GPOSinfo[$i]['XAdvanceL']) && $GPOSinfo[$i]['XAdvanceL']) { 
  4619. $XshiftAfter += $GPOSinfo[$i]['XAdvanceL'] * 1000 / $this->CurrentFont['unitsPerEm']; 
  4620. } elseif (isset($GPOSinfo[$i]['wDir']) && $GPOSinfo[$i]['wDir'] == 'RTL' && isset($GPOSinfo[$i]['XAdvanceR']) && $GPOSinfo[$i]['XAdvanceR']) { 
  4621. $XshiftAfter += $GPOSinfo[$i]['XAdvanceR'] * 1000 / $this->CurrentFont['unitsPerEm']; 
  4622. // Character & Word spacing - if NOT OTL 
  4623. else { 
  4624. $XshiftAfter += $charspacing; 
  4625. if ($c == 32) { 
  4626. $XshiftAfter += $wordspacing; 
  4627.  
  4628. // IF Kerning done using pairs rather than OTL 
  4629. if ($textvar & FC_KERNING) { 
  4630. if ($i > 0 && isset($this->CurrentFont['kerninfo'][$unicode[($i - 1)]][$unicode[$i]])) { 
  4631. $XshiftBefore += $this->CurrentFont['kerninfo'][$unicode[($i - 1)]][$unicode[$i]]; 
  4632.  
  4633. if ($YPlacement != $lastYPlacement) { 
  4634. $groupBreak = true; 
  4635.  
  4636. if ($XshiftBefore) { // +ve value in PDF moves to the left 
  4637. // If Fontstretch is ongoing, need to adjust X adjustments because these will be stretched out. 
  4638. $XshiftBefore *= 100 / $last_fontstretch; 
  4639. if ($sipset) { 
  4640. $tj .= sprintf('>%d<', (-$XshiftBefore)); 
  4641. } else { 
  4642. $tj .= sprintf(')%d(', (-$XshiftBefore)); 
  4643.  
  4644. // Small-Caps 
  4645. if ($smcaps) { 
  4646. if (isset($this->upperCase[$c])) { 
  4647. $c = $this->upperCase[$c]; 
  4648. //$this->CurrentFont['subset'][$this->upperCase[$c]] = $this->upperCase[$c]; // add the CAP to subset 
  4649. $SmallCapsON = true; 
  4650. // For $sipset 
  4651. if (!$lastSmallCapsON) { // Turn ON SmallCaps 
  4652. $groupBreak = true; 
  4653. $fontstretch = $this->smCapsStretch; 
  4654. $fontsize = $this->FontSizePt * $this->smCapsScale; 
  4655. } else { 
  4656. $SmallCapsON = false; 
  4657. if ($lastSmallCapsON) { // Turn OFF SmallCaps 
  4658. $groupBreak = true; 
  4659. $fontstretch = 100; 
  4660. $fontsize = $this->FontSizePt; 
  4661.  
  4662. // Prepare Text and Select Font ID 
  4663. if ($sipset) { 
  4664. // mPDF 6 DELETED ******** 
  4665. //if ($c == 7 || $c == 8) { 
  4666. // if ($original_fontid != $last_fontid) { 
  4667. // $groupBreak = true; 
  4668. // $fontid = $original_fontid; 
  4669. // } 
  4670. // if ($c == 7) { $tj .= $this->aliasNbPgHex; } 
  4671. // else { $tj .= $this->aliasNbPgGpHex; } 
  4672. // continue; 
  4673. //} 
  4674. for ($j = 0; $j < 99; $j++) { 
  4675. $init = array_search($c, $this->CurrentFont['subsets'][$j]); 
  4676. if ($init !== false) { 
  4677. if ($this->CurrentFont['subsetfontids'][$j] != $last_fontid) { 
  4678. $groupBreak = true; 
  4679. $fontid = $this->CurrentFont['subsetfontids'][$j]; 
  4680. $tx = sprintf("%02s", strtoupper(dechex($init))); 
  4681. break; 
  4682. } elseif (count($this->CurrentFont['subsets'][$j]) < 255) { 
  4683. $n = count($this->CurrentFont['subsets'][$j]); 
  4684. $this->CurrentFont['subsets'][$j][$n] = $c; 
  4685. if ($this->CurrentFont['subsetfontids'][$j] != $last_fontid) { 
  4686. $groupBreak = true; 
  4687. $fontid = $this->CurrentFont['subsetfontids'][$j]; 
  4688. $tx = sprintf("%02s", strtoupper(dechex($n))); 
  4689. break; 
  4690. } elseif (!isset($this->CurrentFont['subsets'][($j + 1)])) { 
  4691. $this->CurrentFont['subsets'][($j + 1)] = array(0 => 0); 
  4692. $this->CurrentFont['subsetfontids'][($j + 1)] = count($this->fonts) + $this->extraFontSubsets + 1; 
  4693. $this->extraFontSubsets++; 
  4694. } else { 
  4695. $tx = code2utf($c); 
  4696. if ($this->usingCoreFont) { 
  4697. $tx = utf8_decode($tx); 
  4698. } else { 
  4699. $tx = $this->UTF8ToUTF16BE($tx, false); 
  4700. $tx = $this->_escape($tx); 
  4701.  
  4702. // If any settings require a new Text Group 
  4703. if ($groupBreak || $fontstretch != $last_fontstretch) { 
  4704. if ($sipset) { 
  4705. $tj .= '>] TJ '; 
  4706. } else { 
  4707. $tj .= ')] TJ '; 
  4708. if ($fontid != $last_fontid || $fontsize != $last_fontsize) { 
  4709. $tj .= sprintf(' /F%d %.3F Tf ', $fontid, $fontsize); 
  4710. if ($fontstretch != $last_fontstretch) { 
  4711. $tj .= sprintf('%d Tz ', $fontstretch); 
  4712. if ($YPlacement != $lastYPlacement) { 
  4713. $tj .= sprintf('%.3F Ts ', $YPlacement); 
  4714. if ($sipset) { 
  4715. $tj .= '[<'; 
  4716. } else { 
  4717. $tj .= '[('; 
  4718.  
  4719. // Output the code for the txt character 
  4720. $tj .= $tx; 
  4721. $lastSmallCapsON = $SmallCapsON; 
  4722. $last_fontid = $fontid; 
  4723. $last_fontsize = $fontsize; 
  4724. $last_fontstretch = $fontstretch; 
  4725.  
  4726. // Kashida 
  4727. if ($kashida) { 
  4728. $c = 0x0640; // add the Tatweel U+0640 
  4729. if (isset($this->CurrentFont['subset'])) { 
  4730. $this->CurrentFont['subset'][$c] = $c; 
  4731. $kashida *= 1000 / $this->FontSizePt; 
  4732. $tatw = $this->_getCharWidth($this->CurrentFont['cw'], 0x0640); 
  4733.  
  4734. // Get YPlacement from next Base character 
  4735. $nextbase = $i + 1; 
  4736. while ($OTLdata['group']{$nextbase} != 'C') { 
  4737. $nextbase++; 
  4738. if (isset($GPOSinfo[$nextbase]) && isset($GPOSinfo[$nextbase]['YPlacement']) && $GPOSinfo[$nextbase]['YPlacement']) { 
  4739. $YPlacement = $GPOSinfo[$nextbase]['YPlacement'] * $this->FontSizePt / $this->CurrentFont['unitsPerEm']; 
  4740.  
  4741. // Prepare Text and Select Font ID 
  4742. if ($sipset) { 
  4743. for ($j = 0; $j < 99; $j++) { 
  4744. $init = array_search($c, $this->CurrentFont['subsets'][$j]); 
  4745. if ($init !== false) { 
  4746. if ($this->CurrentFont['subsetfontids'][$j] != $last_fontid) { 
  4747. $fontid = $this->CurrentFont['subsetfontids'][$j]; 
  4748. $tx = sprintf("%02s", strtoupper(dechex($init))); 
  4749. break; 
  4750. } elseif (count($this->CurrentFont['subsets'][$j]) < 255) { 
  4751. $n = count($this->CurrentFont['subsets'][$j]); 
  4752. $this->CurrentFont['subsets'][$j][$n] = $c; 
  4753. if ($this->CurrentFont['subsetfontids'][$j] != $last_fontid) { 
  4754. $fontid = $this->CurrentFont['subsetfontids'][$j]; 
  4755. $tx = sprintf("%02s", strtoupper(dechex($n))); 
  4756. break; 
  4757. } elseif (!isset($this->CurrentFont['subsets'][($j + 1)])) { 
  4758. $this->CurrentFont['subsets'][($j + 1)] = array(0 => 0); 
  4759. $this->CurrentFont['subsetfontids'][($j + 1)] = count($this->fonts) + $this->extraFontSubsets + 1; 
  4760. $this->extraFontSubsets++; 
  4761. } else { 
  4762. $tx = code2utf($c); 
  4763. $tx = $this->UTF8ToUTF16BE($tx, false); 
  4764. $tx = $this->_escape($tx); 
  4765.  
  4766. if ($kashida > $tatw) { 
  4767. // Insert multiple tatweel characters, repositioning the last one to give correct total length 
  4768. $fontstretch = 100; 
  4769. $nt = intval($kashida / $tatw); 
  4770. $nudgeback = (($nt + 1) * $tatw) - $kashida; 
  4771. $optx = str_repeat($tx, $nt); 
  4772. if ($sipset) { 
  4773. $optx .= sprintf('>%d<', ($nudgeback)); 
  4774. } else { 
  4775. $optx .= sprintf(')%d(', ($nudgeback)); 
  4776. $optx .= $tx; // #last 
  4777. } else { 
  4778. // Insert single tatweel character and use fontstretch to get correct length 
  4779. $fontstretch = ($kashida / $tatw) * 100; 
  4780. $optx = $tx; 
  4781.  
  4782. if ($sipset) { 
  4783. $tj .= '>] TJ '; 
  4784. } else { 
  4785. $tj .= ')] TJ '; 
  4786. if ($fontid != $last_fontid || $fontsize != $last_fontsize) { 
  4787. $tj .= sprintf(' /F%d %.3F Tf ', $fontid, $fontsize); 
  4788. if ($fontstretch != $last_fontstretch) { 
  4789. $tj .= sprintf('%d Tz ', $fontstretch); 
  4790. $tj .= sprintf('%.3F Ts ', $YPlacement); 
  4791. if ($sipset) { 
  4792. $tj .= '[<'; 
  4793. } else { 
  4794. $tj .= '[('; 
  4795.  
  4796. // Output the code for the txt character(s) 
  4797. $tj .= $optx; 
  4798. $last_fontid = $fontid; 
  4799. $last_fontstretch = $fontstretch; 
  4800. $fontstretch = 100; 
  4801.  
  4802. $lastYPlacement = $YPlacement; 
  4803.  
  4804.  
  4805. // Finish up 
  4806. if ($sipset) { 
  4807. $tj .= '>'; 
  4808. if ($XshiftAfter) { 
  4809. $tj .= sprintf('%d', (-$XshiftAfter)); 
  4810. if ($last_fontid != $original_fontid) { 
  4811. $tj .= '] TJ '; 
  4812. $tj .= sprintf(' /F%d %.3F Tf ', $original_fontid, $fontsize); 
  4813. $tj .= '['; 
  4814. $tj = preg_replace('/([^\\\])<>/', '\\1 ', $tj); 
  4815. } else { 
  4816. $tj .= ')'; 
  4817. if ($XshiftAfter) { 
  4818. $tj .= sprintf('%d', (-$XshiftAfter)); 
  4819. if ($last_fontid != $original_fontid) { 
  4820. $tj .= '] TJ '; 
  4821. $tj .= sprintf(' /F%d %.3F Tf ', $original_fontid, $fontsize); 
  4822. $tj .= '['; 
  4823. $tj = preg_replace('/([^\\\])\(\)/', '\\1 ', $tj); 
  4824.  
  4825.  
  4826. $s = sprintf(' BT ' . $aix . ' 0 Tc 0 Tw [%s] TJ ET ', $x, $y, $tj); 
  4827.  
  4828. //echo $s."\n\n"; // exit; 
  4829.  
  4830. return $s; 
  4831.  
  4832. function _kern($txt, $mode, $aix, $x, $y) 
  4833. if ($mode == 'MBTw') { // Multibyte requiring word spacing 
  4834. $space = ' '; 
  4835. //Convert string to UTF-16BE without BOM 
  4836. $space = $this->UTF8ToUTF16BE($space, false); 
  4837. $space = $this->_escape($space); 
  4838. $s = sprintf(' BT ' . $aix, $x * _MPDFK, ($this->h - $y) * _MPDFK); 
  4839. $t = explode(' ', $txt); 
  4840. for ($i = 0; $i < count($t); $i++) { 
  4841. $tx = $t[$i]; 
  4842.  
  4843. $tj = '('; 
  4844. $unicode = $this->UTF8StringToArray($tx); 
  4845. for ($ti = 0; $ti < count($unicode); $ti++) { 
  4846. if ($ti > 0 && isset($this->CurrentFont['kerninfo'][$unicode[($ti - 1)]][$unicode[$ti]])) { 
  4847. $kern = -$this->CurrentFont['kerninfo'][$unicode[($ti - 1)]][$unicode[$ti]]; 
  4848. $tj .= sprintf(')%d(', $kern); 
  4849. $tc = code2utf($unicode[$ti]); 
  4850. $tc = $this->UTF8ToUTF16BE($tc, false); 
  4851. $tj .= $this->_escape($tc); 
  4852. $tj .= ')'; 
  4853. $s.=sprintf(' %.3F Tc [%s] TJ', $this->charspacing, $tj); 
  4854.  
  4855.  
  4856. if (($i + 1) < count($t)) { 
  4857. $s.=sprintf(' %.3F Tc (%s) Tj', $this->ws + $this->charspacing, $space); 
  4858. $s.=' ET '; 
  4859. } elseif (!$this->usingCoreFont) { 
  4860. $s = ''; 
  4861. $tj = '('; 
  4862. $unicode = $this->UTF8StringToArray($txt); 
  4863. for ($i = 0; $i < count($unicode); $i++) { 
  4864. if ($i > 0 && isset($this->CurrentFont['kerninfo'][$unicode[($i - 1)]][$unicode[$i]])) { 
  4865. $kern = -$this->CurrentFont['kerninfo'][$unicode[($i - 1)]][$unicode[$i]]; 
  4866. $tj .= sprintf(')%d(', $kern); 
  4867. $tx = code2utf($unicode[$i]); 
  4868. $tx = $this->UTF8ToUTF16BE($tx, false); 
  4869. $tj .= $this->_escape($tx); 
  4870. $tj .= ')'; 
  4871. $s.=sprintf(' BT ' . $aix . ' [%s] TJ ET ', $x * _MPDFK, ($this->h - $y) * _MPDFK, $tj); 
  4872. } else { // CORE Font 
  4873. $s = ''; 
  4874. $tj = '('; 
  4875. $l = strlen($txt); 
  4876. for ($i = 0; $i < $l; $i++) { 
  4877. if ($i > 0 && isset($this->CurrentFont['kerninfo'][$txt[($i - 1)]][$txt[$i]])) { 
  4878. $kern = -$this->CurrentFont['kerninfo'][$txt[($i - 1)]][$txt[$i]]; 
  4879. $tj .= sprintf(')%d(', $kern); 
  4880. $tj .= $this->_escape($txt[$i]); 
  4881. $tj .= ')'; 
  4882. $s.=sprintf(' BT ' . $aix . ' [%s] TJ ET ', $x * _MPDFK, ($this->h - $y) * _MPDFK, $tj); 
  4883.  
  4884. return $s; 
  4885.  
  4886. function MultiCell($w, $h, $txt, $border = 0, $align = '', $fill = 0, $link = '', $directionality = 'ltr', $encoded = false, $OTLdata = false, $maxrows = false) 
  4887. // maxrows is called from mpdfform->TEXTAREA 
  4888. // Parameter (pre-)encoded - When called internally from form::textarea - mb_encoding already done and OTL - but not reverse RTL 
  4889. if (!$encoded) { 
  4890. $txt = $this->purify_utf8_text($txt); 
  4891. if ($this->text_input_as_HTML) { 
  4892. $txt = $this->all_entities_to_utf8($txt); 
  4893. if ($this->usingCoreFont) { 
  4894. $txt = mb_convert_encoding($txt, $this->mb_enc, 'UTF-8'); 
  4895. if (preg_match("/([" . $this->pregRTLchars . "])/u", $txt)) { 
  4896. $this->biDirectional = true; 
  4897. } // *OTL* 
  4898. /** -- OTL -- */ 
  4899. $OTLdata = array(); 
  4900. // Use OTL OpenType Table Layout - GSUB & GPOS 
  4901. if (isset($this->CurrentFont['useOTL']) && $this->CurrentFont['useOTL']) { 
  4902. $txt = $this->otl->applyOTL($txt, $this->CurrentFont['useOTL']); 
  4903. $OTLdata = $this->otl->OTLdata; 
  4904. if ($directionality == 'rtl' || $this->biDirectional) { 
  4905. if (!isset($OTLdata)) { 
  4906. $unicode = $this->UTF8StringToArray($txt, false); 
  4907. $is_strong = false; 
  4908. $this->getBasicOTLdata($OTLdata, $unicode, $is_strong); 
  4909. /** -- END OTL -- */ 
  4910. if (!$align) { 
  4911. $align = $this->defaultAlign; 
  4912.  
  4913. //Output text with automatic or explicit line breaks 
  4914. $cw = &$this->CurrentFont['cw']; 
  4915. if ($w == 0) 
  4916. $w = $this->w - $this->rMargin - $this->x; 
  4917.  
  4918. $wmax = ($w - ($this->cMarginL + $this->cMarginR)); 
  4919. if ($this->usingCoreFont) { 
  4920. $s = str_replace("\r", '', $txt); 
  4921. $nb = strlen($s); 
  4922. while ($nb > 0 and $s[$nb - 1] == "\n") 
  4923. $nb--; 
  4924. } else { 
  4925. $s = str_replace("\r", '', $txt); 
  4926. $nb = mb_strlen($s, $this->mb_enc); 
  4927. while ($nb > 0 and mb_substr($s, $nb - 1, 1, $this->mb_enc) == "\n") 
  4928. $nb--; 
  4929. $b = 0; 
  4930. if ($border) { 
  4931. if ($border == 1) { 
  4932. $border = 'LTRB'; 
  4933. $b = 'LRT'; 
  4934. $b2 = 'LR'; 
  4935. } else { 
  4936. $b2 = ''; 
  4937. if (is_int(strpos($border, 'L'))) 
  4938. $b2.='L'; 
  4939. if (is_int(strpos($border, 'R'))) 
  4940. $b2.='R'; 
  4941. $b = is_int(strpos($border, 'T')) ? $b2 . 'T' : $b2; 
  4942. $sep = -1; 
  4943. $i = 0; 
  4944. $j = 0; 
  4945. $l = 0; 
  4946. $ns = 0; 
  4947. $nl = 1; 
  4948.  
  4949. $rows = 0; 
  4950. $start_y = $this->y; 
  4951.  
  4952. if (!$this->usingCoreFont) { 
  4953. $inclCursive = false; 
  4954. if (preg_match("/([" . $this->pregCURSchars . "])/u", $s)) { 
  4955. $inclCursive = true; 
  4956. while ($i < $nb) { 
  4957. //Get next character 
  4958. $c = mb_substr($s, $i, 1, $this->mb_enc); 
  4959. if ($c == "\n") { 
  4960. //Explicit line break 
  4961. // WORD SPACING 
  4962. $this->ResetSpacing(); 
  4963. $tmp = rtrim(mb_substr($s, $j, $i - $j, $this->mb_enc)); 
  4964. $tmpOTLdata = false; 
  4965. /** -- OTL -- */ 
  4966. if (isset($OTLdata)) { 
  4967. $tmpOTLdata = $this->otl->sliceOTLdata($OTLdata, $j, $i - $j); 
  4968. $this->otl->trimOTLdata($tmpOTLdata, false, true); 
  4969. $this->magic_reverse_dir($tmp, $directionality, $tmpOTLdata); 
  4970. /** -- END OTL -- */ 
  4971. $this->Cell($w, $h, $tmp, $b, 2, $align, $fill, $link, 0, 0, 0, 'M', 0, false, $tmpOTLdata); 
  4972. if ($maxrows != false && isset($this->mpdfform) && ($this->y - $start_y) / $h > $maxrows) { 
  4973. return false; 
  4974. $i++; 
  4975. $sep = -1; 
  4976. $j = $i; 
  4977. $l = 0; 
  4978. $ns = 0; 
  4979. $nl++; 
  4980. if ($border and $nl == 2) 
  4981. $b = $b2; 
  4982. continue; 
  4983. if ($c == " ") { 
  4984. $sep = $i; 
  4985. $ls = $l; 
  4986. $ns++; 
  4987.  
  4988. $l += $this->GetCharWidthNonCore($c); 
  4989.  
  4990. if ($l > $wmax) { 
  4991. //Automatic line break 
  4992. if ($sep == -1) { // Only one word 
  4993. if ($i == $j) 
  4994. $i++; 
  4995. // WORD SPACING 
  4996. $this->ResetSpacing(); 
  4997. $tmp = rtrim(mb_substr($s, $j, $i - $j, $this->mb_enc)); 
  4998. $tmpOTLdata = false; 
  4999. /** -- OTL -- */ 
  5000. if (isset($OTLdata)) { 
  5001. $tmpOTLdata = $this->otl->sliceOTLdata($OTLdata, $j, $i - $j); 
  5002. $this->otl->trimOTLdata($tmpOTLdata, false, true); 
  5003. $this->magic_reverse_dir($tmp, $directionality, $tmpOTLdata); 
  5004. /** -- END OTL -- */ 
  5005. $this->Cell($w, $h, $tmp, $b, 2, $align, $fill, $link, 0, 0, 0, 'M', 0, false, $tmpOTLdata); 
  5006. } else { 
  5007. $tmp = rtrim(mb_substr($s, $j, $sep - $j, $this->mb_enc)); 
  5008. $tmpOTLdata = false; 
  5009. /** -- OTL -- */ 
  5010. if (isset($OTLdata)) { 
  5011. $tmpOTLdata = $this->otl->sliceOTLdata($OTLdata, $j, $sep - $j); 
  5012. $this->otl->trimOTLdata($tmpOTLdata, false, true); 
  5013. /** -- END OTL -- */ 
  5014. if ($align == 'J') { 
  5015. ////////////////////////////////////////// 
  5016. // JUSTIFY J using Unicode fonts (Word spacing doesn't work) 
  5017. // WORD SPACING UNICODE 
  5018. // Change NON_BREAKING SPACE to spaces so they are 'spaced' properly 
  5019. $tmp = str_replace(chr(194) . chr(160), chr(32), $tmp); 
  5020. $len_ligne = $this->GetStringWidth($tmp, false, $tmpOTLdata); 
  5021. $nb_carac = mb_strlen($tmp, $this->mb_enc); 
  5022. $nb_spaces = mb_substr_count($tmp, ' ', $this->mb_enc); 
  5023. // Take off number of Marks 
  5024. // Use GPOS OTL 
  5025. if (isset($this->CurrentFont['useOTL']) && ($this->CurrentFont['useOTL'])) { 
  5026. if (isset($tmpOTLdata['group']) && $tmpOTLdata['group']) { 
  5027. $nb_carac -= substr_count($tmpOTLdata['group'], 'M'); 
  5028.  
  5029. list($charspacing, $ws, $kashida) = $this->GetJspacing($nb_carac, $nb_spaces, ((($wmax) - $len_ligne) * _MPDFK), $inclCursive, $tmpOTLdata); 
  5030. $this->SetSpacing($charspacing, $ws); 
  5031. ////////////////////////////////////////// 
  5032. if (isset($OTLdata)) { 
  5033. $this->magic_reverse_dir($tmp, $directionality, $tmpOTLdata); 
  5034. $this->Cell($w, $h, $tmp, $b, 2, $align, $fill, $link, 0, 0, 0, 'M', 0, false, $tmpOTLdata); 
  5035. $i = $sep + 1; 
  5036. if ($maxrows != false && isset($this->mpdfform) && ($this->y - $start_y) / $h > $maxrows) { 
  5037. return false; 
  5038. $sep = -1; 
  5039. $j = $i; 
  5040. $l = 0; 
  5041. $ns = 0; 
  5042. $nl++; 
  5043. if ($border and $nl == 2) 
  5044. $b = $b2; 
  5045. } else 
  5046. $i++; 
  5047. //Last chunk 
  5048. // WORD SPACING 
  5049.  
  5050. $this->ResetSpacing(); 
  5051.  
  5052.  
  5053. else { 
  5054.  
  5055. while ($i < $nb) { 
  5056. //Get next character 
  5057. $c = $s[$i]; 
  5058. if ($c == "\n") { 
  5059. //Explicit line break 
  5060. // WORD SPACING 
  5061. $this->ResetSpacing(); 
  5062. $this->Cell($w, $h, substr($s, $j, $i - $j), $b, 2, $align, $fill, $link); 
  5063. if ($maxrows != false && isset($this->mpdfform) && ($this->y - $start_y) / $h > $maxrows) { 
  5064. return false; 
  5065. $i++; 
  5066. $sep = -1; 
  5067. $j = $i; 
  5068. $l = 0; 
  5069. $ns = 0; 
  5070. $nl++; 
  5071. if ($border and $nl == 2) 
  5072. $b = $b2; 
  5073. continue; 
  5074. if ($c == " ") { 
  5075. $sep = $i; 
  5076. $ls = $l; 
  5077. $ns++; 
  5078.  
  5079. $l += $this->GetCharWidthCore($c); 
  5080. if ($l > $wmax) { 
  5081. //Automatic line break 
  5082. if ($sep == -1) { 
  5083. if ($i == $j) 
  5084. $i++; 
  5085. // WORD SPACING 
  5086. $this->ResetSpacing(); 
  5087. $this->Cell($w, $h, substr($s, $j, $i - $j), $b, 2, $align, $fill, $link); 
  5088. else { 
  5089. if ($align == 'J') { 
  5090. $tmp = rtrim(substr($s, $j, $sep - $j)); 
  5091. ////////////////////////////////////////// 
  5092. // JUSTIFY J using Unicode fonts (Word spacing doesn't work) 
  5093. // WORD SPACING NON_UNICODE/CJK 
  5094. // Change NON_BREAKING SPACE to spaces so they are 'spaced' properly 
  5095. $tmp = str_replace(chr(160), chr(32), $tmp); 
  5096. $len_ligne = $this->GetStringWidth($tmp); 
  5097. $nb_carac = strlen($tmp); 
  5098. $nb_spaces = substr_count($tmp, ' '); 
  5099. $tmpOTLdata = array(); 
  5100. list($charspacing, $ws, $kashida) = $this->GetJspacing($nb_carac, $nb_spaces, ((($wmax) - $len_ligne) * _MPDFK), false, $tmpOTLdata); 
  5101. $this->SetSpacing($charspacing, $ws); 
  5102. ////////////////////////////////////////// 
  5103. $this->Cell($w, $h, substr($s, $j, $sep - $j), $b, 2, $align, $fill, $link); 
  5104. $i = $sep + 1; 
  5105. if ($maxrows != false && isset($this->mpdfform) && ($this->y - $start_y) / $h > $maxrows) { 
  5106. return false; 
  5107. $sep = -1; 
  5108. $j = $i; 
  5109. $l = 0; 
  5110. $ns = 0; 
  5111. $nl++; 
  5112. if ($border and $nl == 2) 
  5113. $b = $b2; 
  5114. } else 
  5115. $i++; 
  5116. //Last chunk 
  5117. // WORD SPACING 
  5118.  
  5119. $this->ResetSpacing(); 
  5120. //Last chunk 
  5121. if ($border and is_int(strpos($border, 'B'))) 
  5122. $b.='B'; 
  5123. if (!$this->usingCoreFont) { 
  5124. $tmp = rtrim(mb_substr($s, $j, $i - $j, $this->mb_enc)); 
  5125. $tmpOTLdata = false; 
  5126. /** -- OTL -- */ 
  5127. if (isset($OTLdata)) { 
  5128. $tmpOTLdata = $this->otl->sliceOTLdata($OTLdata, $j, $i - $j); 
  5129. $this->otl->trimOTLdata($tmpOTLdata, false, true); 
  5130. $this->magic_reverse_dir($tmp, $directionality, $tmpOTLdata); 
  5131. /** -- END OTL -- */ 
  5132. $this->Cell($w, $h, $tmp, $b, 2, $align, $fill, $link, 0, 0, 0, 'M', 0, false, $tmpOTLdata); 
  5133. } else { 
  5134. $this->Cell($w, $h, substr($s, $j, $i - $j), $b, 2, $align, $fill, $link); 
  5135. $this->x = $this->lMargin; 
  5136.  
  5137. /** -- DIRECTW -- */ 
  5138.  
  5139. function Write($h, $txt, $currentx = 0, $link = '', $directionality = 'ltr', $align = '') 
  5140. if (!class_exists('directw', false)) { 
  5141. include(_MPDF_PATH . 'classes/directw.php'); 
  5142. if (empty($this->directw)) { 
  5143. $this->directw = new directw($this); 
  5144. $this->directw->Write($h, $txt, $currentx, $link, $directionality, $align); 
  5145.  
  5146. /** -- END DIRECTW -- */ 
  5147.  
  5148.  
  5149. /** -- HTML-CSS -- */ 
  5150.  
  5151. function saveInlineProperties() 
  5152. $saved = array(); 
  5153. $saved['family'] = $this->FontFamily; 
  5154. $saved['style'] = $this->FontStyle; 
  5155. $saved['sizePt'] = $this->FontSizePt; 
  5156. $saved['size'] = $this->FontSize; 
  5157. $saved['HREF'] = $this->HREF; 
  5158. $saved['textvar'] = $this->textvar; // mPDF 5.7.1 
  5159. $saved['OTLtags'] = $this->OTLtags; // mPDF 5.7.1 
  5160. $saved['textshadow'] = $this->textshadow; 
  5161. $saved['linewidth'] = $this->LineWidth; 
  5162. $saved['drawcolor'] = $this->DrawColor; 
  5163. $saved['textparam'] = $this->textparam; 
  5164. $saved['lSpacingCSS'] = $this->lSpacingCSS; 
  5165. $saved['wSpacingCSS'] = $this->wSpacingCSS; 
  5166. $saved['I'] = $this->I; 
  5167. $saved['B'] = $this->B; 
  5168. $saved['colorarray'] = $this->colorarray; 
  5169. $saved['bgcolorarray'] = $this->spanbgcolorarray; 
  5170. $saved['border'] = $this->spanborddet; 
  5171. $saved['color'] = $this->TextColor; 
  5172. $saved['bgcolor'] = $this->FillColor; 
  5173. $saved['lang'] = $this->currentLang; 
  5174. $saved['fontLanguageOverride'] = $this->fontLanguageOverride; // mPDF 5.7.1 
  5175. $saved['display_off'] = $this->inlineDisplayOff; 
  5176.  
  5177. return $saved; 
  5178.  
  5179. function restoreInlineProperties(&$saved) 
  5180. $FontFamily = $saved['family']; 
  5181. $this->FontStyle = $saved['style']; 
  5182. $this->FontSizePt = $saved['sizePt']; 
  5183. $this->FontSize = $saved['size']; 
  5184.  
  5185. $this->currentLang = $saved['lang']; 
  5186. $this->fontLanguageOverride = $saved['fontLanguageOverride']; // mPDF 5.7.1 
  5187.  
  5188. $this->ColorFlag = ($this->FillColor != $this->TextColor); //Restore ColorFlag as well 
  5189.  
  5190. $this->HREF = $saved['HREF']; 
  5191. $this->textvar = $saved['textvar']; // mPDF 5.7.1 
  5192. $this->OTLtags = $saved['OTLtags']; // mPDF 5.7.1 
  5193. $this->textshadow = $saved['textshadow']; 
  5194. $this->LineWidth = $saved['linewidth']; 
  5195. $this->DrawColor = $saved['drawcolor']; 
  5196. $this->textparam = $saved['textparam']; 
  5197. $this->inlineDisplayOff = $saved['display_off']; 
  5198.  
  5199. $this->lSpacingCSS = $saved['lSpacingCSS']; 
  5200. if (($this->lSpacingCSS || $this->lSpacingCSS === '0') && strtoupper($this->lSpacingCSS) != 'NORMAL') { 
  5201. $this->fixedlSpacing = $this->ConvertSize($this->lSpacingCSS, $this->FontSize); 
  5202. } else { 
  5203. $this->fixedlSpacing = false; 
  5204. $this->wSpacingCSS = $saved['wSpacingCSS']; 
  5205. if ($this->wSpacingCSS && strtoupper($this->wSpacingCSS) != 'NORMAL') { 
  5206. $this->minwSpacing = $this->ConvertSize($this->wSpacingCSS, $this->FontSize); 
  5207. } else { 
  5208. $this->minwSpacing = 0; 
  5209.  
  5210. $this->SetFont($FontFamily, $saved['style'], $saved['sizePt'], false); 
  5211.  
  5212. $this->currentfontstyle = $saved['style']; 
  5213. $this->currentfontsize = $saved['sizePt']; 
  5214. $this->SetStylesArray(array('B' => $saved['B'], 'I' => $saved['I'])); // mPDF 5.7.1 
  5215.  
  5216. $this->TextColor = $saved['color']; 
  5217. $this->FillColor = $saved['bgcolor']; 
  5218. $this->colorarray = $saved['colorarray']; 
  5219. $cor = $saved['colorarray']; 
  5220. if ($cor) 
  5221. $this->SetTColor($cor); 
  5222. $this->spanbgcolorarray = $saved['bgcolorarray']; 
  5223. $cor = $saved['bgcolorarray']; 
  5224. if ($cor) 
  5225. $this->SetFColor($cor); 
  5226. $this->spanborddet = $saved['border']; 
  5227.  
  5228. // Used when ColActive for tables - updated to return first block with background fill OR borders 
  5229. function GetFirstBlockFill() 
  5230. // Returns the first blocklevel that uses a bgcolor fill 
  5231. $startfill = 0; 
  5232. for ($i = 1; $i <= $this->blklvl; $i++) { 
  5233. 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']) { 
  5234. $startfill = $i; 
  5235. break; 
  5236. return $startfill; 
  5237.  
  5238. //-------------------------FLOWING BLOCK------------------------------------// 
  5239. //The following functions were originally written by Damon Kohler // 
  5240. //--------------------------------------------------------------------------// 
  5241.  
  5242. function saveFont() 
  5243. $saved = array(); 
  5244. $saved['family'] = $this->FontFamily; 
  5245. $saved['style'] = $this->FontStyle; 
  5246. $saved['sizePt'] = $this->FontSizePt; 
  5247. $saved['size'] = $this->FontSize; 
  5248. $saved['curr'] = &$this->CurrentFont; 
  5249. $saved['lang'] = $this->currentLang; // mPDF 6 
  5250. $saved['color'] = $this->TextColor; 
  5251. $saved['spanbgcolor'] = $this->spanbgcolor; 
  5252. $saved['spanbgcolorarray'] = $this->spanbgcolorarray; 
  5253. $saved['bord'] = $this->spanborder; 
  5254. $saved['border'] = $this->spanborddet; 
  5255. $saved['HREF'] = $this->HREF; 
  5256. $saved['textvar'] = $this->textvar; // mPDF 5.7.1 
  5257. $saved['textshadow'] = $this->textshadow; 
  5258. $saved['linewidth'] = $this->LineWidth; 
  5259. $saved['drawcolor'] = $this->DrawColor; 
  5260. $saved['textparam'] = $this->textparam; 
  5261. $saved['ReqFontStyle'] = $this->ReqFontStyle; 
  5262. $saved['fixedlSpacing'] = $this->fixedlSpacing; 
  5263. $saved['minwSpacing'] = $this->minwSpacing; 
  5264. return $saved; 
  5265.  
  5266. function restoreFont(&$saved, $write = true) 
  5267. if (!isset($saved) || empty($saved)) 
  5268. return; 
  5269.  
  5270. $this->FontFamily = $saved['family']; 
  5271. $this->FontStyle = $saved['style']; 
  5272. $this->FontSizePt = $saved['sizePt']; 
  5273. $this->FontSize = $saved['size']; 
  5274. $this->CurrentFont = &$saved['curr']; 
  5275. $this->currentLang = $saved['lang']; // mPDF 6 
  5276. $this->TextColor = $saved['color']; 
  5277. $this->spanbgcolor = $saved['spanbgcolor']; 
  5278. $this->spanbgcolorarray = $saved['spanbgcolorarray']; 
  5279. $this->spanborder = $saved['bord']; 
  5280. $this->spanborddet = $saved['border']; 
  5281. $this->ColorFlag = ($this->FillColor != $this->TextColor); //Restore ColorFlag as well 
  5282. $this->HREF = $saved['HREF']; 
  5283. $this->fixedlSpacing = $saved['fixedlSpacing']; 
  5284. $this->minwSpacing = $saved['minwSpacing']; 
  5285. $this->textvar = $saved['textvar']; // mPDF 5.7.1 
  5286. $this->textshadow = $saved['textshadow']; 
  5287. $this->LineWidth = $saved['linewidth']; 
  5288. $this->DrawColor = $saved['drawcolor']; 
  5289. $this->textparam = $saved['textparam']; 
  5290. if ($write) { 
  5291. $this->SetFont($saved['family'], $saved['style'], $saved['sizePt'], true, true); // force output 
  5292. $fontout = (sprintf('BT /F%d %.3F Tf ET', $this->CurrentFont['i'], $this->FontSizePt)); 
  5293. if ($this->page > 0 && ((isset($this->pageoutput[$this->page]['Font']) && $this->pageoutput[$this->page]['Font'] != $fontout) || !isset($this->pageoutput[$this->page]['Font']))) { 
  5294. $this->_out($fontout); 
  5295. $this->pageoutput[$this->page]['Font'] = $fontout; 
  5296. } else 
  5297. $this->SetFont($saved['family'], $saved['style'], $saved['sizePt'], false); 
  5298. $this->ReqFontStyle = $saved['ReqFontStyle']; 
  5299.  
  5300. function newFlowingBlock($w, $h, $a = '', $is_table = false, $blockstate = 0, $newblock = true, $blockdir = 'ltr', $table_draft = false) 
  5301. if (!$a) { 
  5302. if ($blockdir == 'rtl') { 
  5303. $a = 'R'; 
  5304. } else { 
  5305. $a = 'L'; 
  5306. $this->flowingBlockAttr['width'] = ($w * _MPDFK); 
  5307. // line height in user units 
  5308. $this->flowingBlockAttr['is_table'] = $is_table; 
  5309. $this->flowingBlockAttr['table_draft'] = $table_draft; 
  5310. $this->flowingBlockAttr['height'] = $h; 
  5311. $this->flowingBlockAttr['lineCount'] = 0; 
  5312. $this->flowingBlockAttr['align'] = $a; 
  5313. $this->flowingBlockAttr['font'] = array(); 
  5314. $this->flowingBlockAttr['content'] = array(); 
  5315. $this->flowingBlockAttr['contentB'] = array(); 
  5316. $this->flowingBlockAttr['contentWidth'] = 0; 
  5317. $this->flowingBlockAttr['blockstate'] = $blockstate; 
  5318.  
  5319. $this->flowingBlockAttr['newblock'] = $newblock; 
  5320. $this->flowingBlockAttr['valign'] = 'M'; 
  5321. $this->flowingBlockAttr['blockdir'] = $blockdir; 
  5322. $this->flowingBlockAttr['cOTLdata'] = array(); // mPDF 5.7.1 
  5323. $this->flowingBlockAttr['lastBidiText'] = ''; // mPDF 5.7.1 
  5324. if (!empty($this->otl)) { 
  5325. $this->otl->lastBidiStrongType = ''; 
  5326. } // *OTL* 
  5327.  
  5328. function finishFlowingBlock($endofblock = false, $next = '') 
  5329. $currentx = $this->x; 
  5330. //prints out the last chunk 
  5331. $is_table = $this->flowingBlockAttr['is_table']; 
  5332. $table_draft = $this->flowingBlockAttr['table_draft']; 
  5333. $maxWidth = & $this->flowingBlockAttr['width']; 
  5334. $stackHeight = & $this->flowingBlockAttr['height']; 
  5335. $align = & $this->flowingBlockAttr['align']; 
  5336. $content = & $this->flowingBlockAttr['content']; 
  5337. $contentB = & $this->flowingBlockAttr['contentB']; 
  5338. $font = & $this->flowingBlockAttr['font']; 
  5339. $contentWidth = & $this->flowingBlockAttr['contentWidth']; 
  5340. $lineCount = & $this->flowingBlockAttr['lineCount']; 
  5341. $valign = & $this->flowingBlockAttr['valign']; 
  5342. $blockstate = $this->flowingBlockAttr['blockstate']; 
  5343.  
  5344. $cOTLdata = & $this->flowingBlockAttr['cOTLdata']; // mPDF 5.7.1 
  5345. $newblock = $this->flowingBlockAttr['newblock']; 
  5346. $blockdir = $this->flowingBlockAttr['blockdir']; 
  5347.  
  5348. // *********** BLOCK BACKGROUND COLOR *****************// 
  5349. if ($this->blk[$this->blklvl]['bgcolor'] && !$is_table) { 
  5350. $fill = 0; 
  5351. } else { 
  5352. $this->SetFColor($this->ConvertColor(255)); 
  5353. $fill = 0; 
  5354.  
  5355. $hanger = ''; 
  5356. // Always right trim! 
  5357. // Right trim last content and adjust width if needed to justify (later) 
  5358. if (isset($content[count($content) - 1]) && preg_match('/[ ]+$/', $content[count($content) - 1], $m)) { 
  5359. $strip = strlen($m[0]); 
  5360. $content[count($content) - 1] = substr($content[count($content) - 1], 0, (strlen($content[count($content) - 1]) - $strip)); 
  5361. /** -- OTL -- */ 
  5362. if (isset($this->CurrentFont['useOTL']) && $this->CurrentFont['useOTL']) { 
  5363. $this->otl->trimOTLdata($cOTLdata[count($cOTLdata) - 1], false, true); 
  5364. /** -- END OTL -- */ 
  5365.  
  5366. // the amount of space taken up so far in user units 
  5367. $usedWidth = 0; 
  5368.  
  5369. // COLS 
  5370. $oldcolumn = $this->CurrCol; 
  5371.  
  5372. if ($this->ColActive && !$is_table) { 
  5373. $this->breakpoints[$this->CurrCol][] = $this->y; 
  5374. } // *COLUMNS* 
  5375. // Print out each chunk 
  5376.  
  5377. /** -- TABLES -- */ 
  5378. if ($is_table) { 
  5379. $ipaddingL = 0; 
  5380. $ipaddingR = 0; 
  5381. $paddingL = 0; 
  5382. $paddingR = 0; 
  5383. } else { 
  5384. /** -- END TABLES -- */ 
  5385. $ipaddingL = $this->blk[$this->blklvl]['padding_left']; 
  5386. $ipaddingR = $this->blk[$this->blklvl]['padding_right']; 
  5387. $paddingL = ($ipaddingL * _MPDFK); 
  5388. $paddingR = ($ipaddingR * _MPDFK); 
  5389. $this->cMarginL = $this->blk[$this->blklvl]['border_left']['w']; 
  5390. $this->cMarginR = $this->blk[$this->blklvl]['border_right']['w']; 
  5391.  
  5392. // Added mPDF 3.0 Float DIV 
  5393. $fpaddingR = 0; 
  5394. $fpaddingL = 0; 
  5395. /** -- CSS-FLOAT -- */ 
  5396. if (count($this->floatDivs)) { 
  5397. list($l_exists, $r_exists, $l_max, $r_max, $l_width, $r_width) = $this->GetFloatDivInfo($this->blklvl); 
  5398. if ($r_exists) { 
  5399. $fpaddingR = $r_width; 
  5400. if ($l_exists) { 
  5401. $fpaddingL = $l_width; 
  5402. /** -- END CSS-FLOAT -- */ 
  5403.  
  5404. $usey = $this->y + 0.002; 
  5405. if (($newblock) && ($blockstate == 1 || $blockstate == 3) && ($lineCount == 0)) { 
  5406. $usey += $this->blk[$this->blklvl]['margin_top'] + $this->blk[$this->blklvl]['padding_top'] + $this->blk[$this->blklvl]['border_top']['w']; 
  5407. /** -- CSS-IMAGE-FLOAT -- */ 
  5408. // If float exists at this level 
  5409. if (isset($this->floatmargins['R']) && $usey <= $this->floatmargins['R']['y1'] && $usey >= $this->floatmargins['R']['y0'] && !$this->floatmargins['R']['skipline']) { 
  5410. $fpaddingR += $this->floatmargins['R']['w']; 
  5411. if (isset($this->floatmargins['L']) && $usey <= $this->floatmargins['L']['y1'] && $usey >= $this->floatmargins['L']['y0'] && !$this->floatmargins['L']['skipline']) { 
  5412. $fpaddingL += $this->floatmargins['L']['w']; 
  5413. /** -- END CSS-IMAGE-FLOAT -- */ 
  5414. } // *TABLES* 
  5415.  
  5416.  
  5417. $lineBox = array(); 
  5418.  
  5419. $this->_setInlineBlockHeights($lineBox, $stackHeight, $content, $font, $is_table); 
  5420.  
  5421. if ($is_table && count($content) == 0) { 
  5422. $stackHeight = 0; 
  5423.  
  5424. if ($table_draft) { 
  5425. $this->y += $stackHeight; 
  5426. $this->objectbuffer = array(); 
  5427. return 0; 
  5428.  
  5429. // While we're at it, check if contains cursive text 
  5430. // Change NBSP to SPACE. 
  5431. // Re-calculate contentWidth 
  5432. $contentWidth = 0; 
  5433.  
  5434. foreach ($content as $k => $chunk) { 
  5435. $this->restoreFont($font[$k], false); 
  5436. if (!isset($this->objectbuffer[$k]) || (isset($this->objectbuffer[$k]) && !$this->objectbuffer[$k])) { 
  5437. // Soft Hyphens chr(173) 
  5438. if (!$this->usingCoreFont) { 
  5439. /** -- OTL -- */ 
  5440. // mPDF 5.7.1 
  5441. if (isset($this->CurrentFont['useOTL']) && $this->CurrentFont['useOTL']) { 
  5442. $this->otl->removeChar($chunk, $cOTLdata[$k], "\xc2\xad"); 
  5443. $this->otl->replaceSpace($chunk, $cOTLdata[$k]); 
  5444. $content[$k] = $chunk; 
  5445. /** -- END OTL -- */ else { // *OTL* 
  5446. $content[$k] = $chunk = str_replace("\xc2\xad", '', $chunk); 
  5447. $content[$k] = $chunk = str_replace(chr(194) . chr(160), chr(32), $chunk); 
  5448. } // *OTL* 
  5449. } elseif ($this->FontFamily != 'csymbol' && $this->FontFamily != 'czapfdingbats') { 
  5450. $content[$k] = $chunk = str_replace(chr(173), '', $chunk); 
  5451. $content[$k] = $chunk = str_replace(chr(160), chr(32), $chunk); 
  5452. $contentWidth += $this->GetStringWidth($chunk, true, (isset($cOTLdata[$k]) ? $cOTLdata[$k] : false), $this->textvar) * _MPDFK; 
  5453. } elseif (isset($this->objectbuffer[$k]) && $this->objectbuffer[$k]) { 
  5454. // LIST MARKERS // mPDF 6 Lists 
  5455. if ($this->objectbuffer[$k]['type'] == 'image' && isset($this->objectbuffer[$k]['listmarker']) && $this->objectbuffer[$k]['listmarker'] && $this->objectbuffer[$k]['listmarkerposition'] == 'outside') { 
  5456. // do nothing 
  5457. } else { 
  5458. $contentWidth += $this->objectbuffer[$k]['OUTER-WIDTH'] * _MPDFK; 
  5459.  
  5460. if (isset($font[count($font) - 1])) { 
  5461. $lastfontreqstyle = (isset($font[count($font) - 1]['ReqFontStyle']) ? $font[count($font) - 1]['ReqFontStyle'] : ''); 
  5462. $lastfontstyle = (isset($font[count($font) - 1]['style']) ? $font[count($font) - 1]['style'] : ''); 
  5463. } else { 
  5464. $lastfontreqstyle = null; 
  5465. $lastfontstyle = null; 
  5466. if ($blockdir == 'ltr' && strpos($lastfontreqstyle, "I") !== false && strpos($lastfontstyle, "I") === false) { // Artificial italic 
  5467. $lastitalic = $this->FontSize * 0.15 * _MPDFK; 
  5468. } else { 
  5469. $lastitalic = 0; 
  5470.  
  5471. // Get PAGEBREAK TO TEST for height including the bottom border/padding 
  5472. $check_h = max($this->divheight, $stackHeight); 
  5473.  
  5474. // This fixes a proven bug... 
  5475. if ($endofblock && $newblock && $blockstate == 0 && !$content) { 
  5476. $check_h = 0; 
  5477. // but ? needs to fix potentially more widespread... 
  5478. // if (!$content) { $check_h = 0; } 
  5479.  
  5480. if ($this->blklvl > 0 && !$is_table) { 
  5481. if ($endofblock && $blockstate > 1) { 
  5482. if ($this->blk[$this->blklvl]['page_break_after_avoid']) { 
  5483. $check_h += $stackHeight; 
  5484. $check_h += ($this->blk[$this->blklvl]['padding_bottom'] + $this->blk[$this->blklvl]['border_bottom']['w']); 
  5485. if (($newblock && ($blockstate == 1 || $blockstate == 3) && $lineCount == 0) || ($endofblock && $blockstate == 3 && $lineCount == 0)) { 
  5486. $check_h += ($this->blk[$this->blklvl]['padding_top'] + $this->blk[$this->blklvl]['margin_top'] + $this->blk[$this->blklvl]['border_top']['w']); 
  5487.  
  5488. // Force PAGE break if column height cannot take check-height 
  5489. if ($this->ColActive && $check_h > ($this->PageBreakTrigger - $this->y0)) { 
  5490. $this->SetCol($this->NbCol - 1); 
  5491.  
  5492. // Avoid just border/background-color moved on to next page 
  5493. if ($endofblock && $blockstate > 1 && !$content) { 
  5494. $buff = $this->margBuffer; 
  5495. } else { 
  5496. $buff = 0; 
  5497.  
  5498.  
  5499. // PAGEBREAK 
  5500. if (!$is_table && ($this->y + $check_h) > ($this->PageBreakTrigger + $buff) and ! $this->InFooter and $this->AcceptPageBreak()) { 
  5501. $bak_x = $this->x; //Current X position 
  5502. // WORD SPACING 
  5503. $ws = $this->ws; //Word Spacing 
  5504. $charspacing = $this->charspacing; //Character Spacing 
  5505. $this->ResetSpacing(); 
  5506.  
  5507. $this->AddPage($this->CurOrientation); 
  5508.  
  5509. $this->x = $bak_x; 
  5510. // Added to correct for OddEven Margins 
  5511. $currentx += $this->MarginCorrection; 
  5512. $this->x += $this->MarginCorrection; 
  5513.  
  5514. // WORD SPACING 
  5515. $this->SetSpacing($charspacing, $ws); 
  5516.  
  5517.  
  5518. /** -- COLUMNS -- */ 
  5519. // COLS 
  5520. // COLUMN CHANGE 
  5521. if ($this->CurrCol != $oldcolumn) { 
  5522. $currentx += $this->ChangeColumn * ($this->ColWidth + $this->ColGap); 
  5523. $this->x += $this->ChangeColumn * ($this->ColWidth + $this->ColGap); 
  5524. $oldcolumn = $this->CurrCol; 
  5525.  
  5526.  
  5527. if ($this->ColActive && !$is_table) { 
  5528. $this->breakpoints[$this->CurrCol][] = $this->y; 
  5529. /** -- END COLUMNS -- */ 
  5530.  
  5531. // TOP MARGIN 
  5532. if ($newblock && ($blockstate == 1 || $blockstate == 3) && ($this->blk[$this->blklvl]['margin_top']) && $lineCount == 0 && !$is_table) { 
  5533. $this->DivLn($this->blk[$this->blklvl]['margin_top'], $this->blklvl - 1, true, $this->blk[$this->blklvl]['margin_collapse']); 
  5534. if ($this->ColActive) { 
  5535. $this->breakpoints[$this->CurrCol][] = $this->y; 
  5536. } // *COLUMNS* 
  5537.  
  5538. if ($newblock && ($blockstate == 1 || $blockstate == 3) && $lineCount == 0 && !$is_table) { 
  5539. $this->blk[$this->blklvl]['y0'] = $this->y; 
  5540. $this->blk[$this->blklvl]['startpage'] = $this->page; 
  5541. if ($this->blk[$this->blklvl]['float']) { 
  5542. $this->blk[$this->blklvl]['float_start_y'] = $this->y; 
  5543. if ($this->ColActive) { 
  5544. $this->breakpoints[$this->CurrCol][] = $this->y; 
  5545. } // *COLUMNS* 
  5546.  
  5547. // Paragraph INDENT 
  5548. $WidthCorrection = 0; 
  5549. if (($newblock) && ($blockstate == 1 || $blockstate == 3) && isset($this->blk[$this->blklvl]['text_indent']) && ($lineCount == 0) && (!$is_table) && ($align != 'C')) { 
  5550. $ti = $this->ConvertSize($this->blk[$this->blklvl]['text_indent'], $this->blk[$this->blklvl]['inner_width'], $this->blk[$this->blklvl]['InlineProperties']['size'], false); // mPDF 5.7.4 
  5551. $WidthCorrection = ($ti * _MPDFK); 
  5552.  
  5553.  
  5554. // PADDING and BORDER spacing/fill 
  5555. if (($newblock) && ($blockstate == 1 || $blockstate == 3) && (($this->blk[$this->blklvl]['padding_top']) || ($this->blk[$this->blklvl]['border_top'])) && ($lineCount == 0) && (!$is_table)) { 
  5556. // $state = 0 normal; 1 top; 2 bottom; 3 top and bottom 
  5557. $this->DivLn($this->blk[$this->blklvl]['padding_top'] + $this->blk[$this->blklvl]['border_top']['w'], -3, true, false, 1); 
  5558. if ($this->ColActive) { 
  5559. $this->breakpoints[$this->CurrCol][] = $this->y; 
  5560. } // *COLUMNS* 
  5561. $this->x = $currentx; 
  5562.  
  5563.  
  5564. // Added mPDF 3.0 Float DIV 
  5565. $fpaddingR = 0; 
  5566. $fpaddingL = 0; 
  5567. /** -- CSS-FLOAT -- */ 
  5568. if (count($this->floatDivs)) { 
  5569. list($l_exists, $r_exists, $l_max, $r_max, $l_width, $r_width) = $this->GetFloatDivInfo($this->blklvl); 
  5570. if ($r_exists) { 
  5571. $fpaddingR = $r_width; 
  5572. if ($l_exists) { 
  5573. $fpaddingL = $l_width; 
  5574. /** -- END CSS-FLOAT -- */ 
  5575.  
  5576. $usey = $this->y + 0.002; 
  5577. if (($newblock) && ($blockstate == 1 || $blockstate == 3) && ($lineCount == 0)) { 
  5578. $usey += $this->blk[$this->blklvl]['margin_top'] + $this->blk[$this->blklvl]['padding_top'] + $this->blk[$this->blklvl]['border_top']['w']; 
  5579. /** -- CSS-IMAGE-FLOAT -- */ 
  5580. // If float exists at this level 
  5581. if (isset($this->floatmargins['R']) && $usey <= $this->floatmargins['R']['y1'] && $usey >= $this->floatmargins['R']['y0'] && !$this->floatmargins['R']['skipline']) { 
  5582. $fpaddingR += $this->floatmargins['R']['w']; 
  5583. if (isset($this->floatmargins['L']) && $usey <= $this->floatmargins['L']['y1'] && $usey >= $this->floatmargins['L']['y0'] && !$this->floatmargins['L']['skipline']) { 
  5584. $fpaddingL += $this->floatmargins['L']['w']; 
  5585. /** -- END CSS-IMAGE-FLOAT -- */ 
  5586.  
  5587.  
  5588. if ($content) { 
  5589.  
  5590. // In FinishFlowing Block no lines are justified as it is always last line 
  5591. // but if CJKorphan has allowed content width to go over max width, use J charspacing to compress line 
  5592. // JUSTIFICATION J - NOT! 
  5593. $nb_carac = 0; 
  5594. $nb_spaces = 0; 
  5595. $jcharspacing = 0; 
  5596. $jkashida = 0; 
  5597. $jws = 0; 
  5598. $inclCursive = false; 
  5599. $dottab = false; 
  5600. foreach ($content as $k => $chunk) { 
  5601. if (!isset($this->objectbuffer[$k]) || (isset($this->objectbuffer[$k]) && !$this->objectbuffer[$k])) { 
  5602. $nb_carac += mb_strlen($chunk, $this->mb_enc); 
  5603. $nb_spaces += mb_substr_count($chunk, ' ', $this->mb_enc); 
  5604. // mPDF 6 
  5605. // Use GPOS OTL 
  5606. $this->restoreFont($font[$k], false); 
  5607. if (isset($this->CurrentFont['useOTL']) && $this->CurrentFont['useOTL']) { 
  5608. if (isset($cOTLdata[$k]['group']) && $cOTLdata[$k]['group']) { 
  5609. $nb_marks = substr_count($cOTLdata[$k]['group'], 'M'); 
  5610. $nb_carac -= $nb_marks; 
  5611. if (preg_match("/([" . $this->pregCURSchars . "])/u", $chunk)) { 
  5612. $inclCursive = true; 
  5613. } else { 
  5614. $nb_carac ++; // mPDF 6 allow spacing for inline object 
  5615. if ($this->objectbuffer[$k]['type'] == 'dottab') { 
  5616. $dottab = $this->objectbuffer[$k]['outdent']; 
  5617.  
  5618. // DIRECTIONALITY RTL 
  5619. $chunkorder = range(0, count($content) - 1); // mPDF 6 
  5620. /** -- OTL -- */ 
  5621. // mPDF 6 
  5622. if ($blockdir == 'rtl' || $this->biDirectional) { 
  5623. $this->otl->_bidiReorder($chunkorder, $content, $cOTLdata, $blockdir); 
  5624. // From this point on, $content and $cOTLdata may contain more elements (and re-ordered) compared to 
  5625. // $this->objectbuffer and $font ($chunkorder contains the mapping) 
  5626. /** -- END OTL -- */ 
  5627.  
  5628. // Remove any XAdvance from OTL data at end of line 
  5629. // And correct for XPlacement on last character 
  5630. // BIDI is applied 
  5631. foreach ($chunkorder AS $aord => $k) { 
  5632. if (count($cOTLdata)) { 
  5633. $this->restoreFont($font[$k], false); 
  5634. // ...FinishFlowingBlock... 
  5635. if ($aord == count($chunkorder) - 1 && isset($cOTLdata[$aord]['group'])) { // Last chunk on line 
  5636. $nGPOS = strlen($cOTLdata[$aord]['group']) - 1; // Last character 
  5637. if (isset($cOTLdata[$aord]['GPOSinfo'][$nGPOS]['XAdvanceL']) || isset($cOTLdata[$aord]['GPOSinfo'][$nGPOS]['XAdvanceR'])) { 
  5638. if (isset($cOTLdata[$aord]['GPOSinfo'][$nGPOS]['XAdvanceL'])) { 
  5639. $w = $cOTLdata[$aord]['GPOSinfo'][$nGPOS]['XAdvanceL'] * 1000 / $this->CurrentFont['unitsPerEm']; 
  5640. } else { 
  5641. $w = $cOTLdata[$aord]['GPOSinfo'][$nGPOS]['XAdvanceR'] * 1000 / $this->CurrentFont['unitsPerEm']; 
  5642. $w *= ($this->FontSize / 1000); 
  5643. $contentWidth -= $w * _MPDFK; 
  5644. $cOTLdata[$aord]['GPOSinfo'][$nGPOS]['XAdvanceL'] = 0; 
  5645. $cOTLdata[$aord]['GPOSinfo'][$nGPOS]['XAdvanceR'] = 0; 
  5646.  
  5647. // If last character has an XPlacement set, adjust width calculation, and add to XAdvance to account for it 
  5648. if (isset($cOTLdata[$aord]['GPOSinfo'][$nGPOS]['XPlacement'])) { 
  5649. $w = -$cOTLdata[$aord]['GPOSinfo'][$nGPOS]['XPlacement'] * 1000 / $this->CurrentFont['unitsPerEm']; 
  5650. $w *= ($this->FontSize / 1000); 
  5651. $contentWidth -= $w * _MPDFK; 
  5652. $cOTLdata[$aord]['GPOSinfo'][$nGPOS]['XAdvanceL'] = $cOTLdata[$aord]['GPOSinfo'][$nGPOS]['XPlacement']; 
  5653. $cOTLdata[$aord]['GPOSinfo'][$nGPOS]['XAdvanceR'] = $cOTLdata[$aord]['GPOSinfo'][$nGPOS]['XPlacement']; 
  5654.  
  5655. // if it's justified, we need to find the char/word spacing (or if orphans have allowed length of line to go over the maxwidth) 
  5656. // If "orphans" in fact is just a final space - ignore this 
  5657. $lastchar = mb_substr($content[(count($chunkorder) - 1)], mb_strlen($content[(count($chunkorder) - 1)], $this->mb_enc) - 1, 1, $this->mb_enc); 
  5658. if (preg_match("/[" . $this->CJKoverflow . "]/u", $lastchar)) { 
  5659. $CJKoverflow = true; 
  5660. } else { 
  5661. $CJKoverflow = false; 
  5662. if ((((($contentWidth + $lastitalic) > $maxWidth) && ($content[(count($chunkorder) - 1)] != ' ') ) || 
  5663. (!$endofblock && $align == 'J' && ($next == 'image' || $next == 'select' || $next == 'input' || $next == 'textarea' || ($next == 'br' && $this->justifyB4br)))) && !($CJKoverflow && $this->allowCJKoverflow)) { 
  5664. // WORD SPACING 
  5665. list($jcharspacing, $jws, $jkashida) = $this->GetJspacing($nb_carac, $nb_spaces, ($maxWidth - $lastitalic - $contentWidth - $WidthCorrection - (($this->cMarginL + $this->cMarginR) * _MPDFK) - ($paddingL + $paddingR + (($fpaddingL + $fpaddingR) * _MPDFK) )), $inclCursive, $cOTLdata); 
  5666. /** -- CJK-FONTS -- */ elseif ($this->checkCJK && $align == 'J' && $CJKoverflow && $this->allowCJKoverflow && $this->CJKforceend) { 
  5667. // force-end overhang 
  5668. $hanger = mb_substr($content[(count($chunkorder) - 1)], mb_strlen($content[(count($chunkorder) - 1)], $this->mb_enc) - 1, 1, $this->mb_enc); 
  5669. if (preg_match("/[" . $this->CJKoverflow . "]/u", $hanger)) { 
  5670. $content[(count($chunkorder) - 1)] = mb_substr($content[(count($chunkorder) - 1)], 0, mb_strlen($content[(count($chunkorder) - 1)], $this->mb_enc) - 1, $this->mb_enc); 
  5671. $this->restoreFont($font[$chunkorder[count($chunkorder) - 1]], false); 
  5672. $contentWidth -= $this->GetStringWidth($hanger) * _MPDFK; 
  5673. $nb_carac -= 1; 
  5674. list($jcharspacing, $jws, $jkashida) = $this->GetJspacing($nb_carac, $nb_spaces, ($maxWidth - $lastitalic - $contentWidth - $WidthCorrection - (($this->cMarginL + $this->cMarginR) * _MPDFK) - ($paddingL + $paddingR + (($fpaddingL + $fpaddingR) * _MPDFK) )), $inclCursive, $cOTLdata); 
  5675. /** -- END CJK-FONTS -- */ 
  5676.  
  5677. // Check if will fit at word/char spacing of previous line - if so continue it 
  5678. // but only allow a maximum of $this->jSmaxWordLast and $this->jSmaxCharLast 
  5679. elseif ($contentWidth < ($maxWidth - $lastitalic - $WidthCorrection - (($this->cMarginL + $this->cMarginR) * _MPDFK) - ($paddingL + $paddingR + (($fpaddingL + $fpaddingR) * _MPDFK))) && !$this->fixedlSpacing) { 
  5680. if ($this->ws > $this->jSmaxWordLast) { 
  5681. $jws = $this->jSmaxWordLast; 
  5682. if ($this->charspacing > $this->jSmaxCharLast) { 
  5683. $jcharspacing = $this->jSmaxCharLast; 
  5684. $check = $maxWidth - $lastitalic - $WidthCorrection - $contentWidth - (($this->cMarginL + $this->cMarginR) * _MPDFK) - ($paddingL + $paddingR + (($fpaddingL + $fpaddingR) * _MPDFK) ) - ( $jcharspacing * $nb_carac) - ( $jws * $nb_spaces); 
  5685. if ($check <= 0) { 
  5686. $jcharspacing = 0; 
  5687. $jws = 0; 
  5688.  
  5689. $empty = $maxWidth - $lastitalic - $WidthCorrection - $contentWidth - (($this->cMarginL + $this->cMarginR) * _MPDFK) - ($paddingL + $paddingR + (($fpaddingL + $fpaddingR) * _MPDFK) ); 
  5690.  
  5691.  
  5692. $empty -= ($jcharspacing * ($nb_carac - 1)); // mPDF 6 nb_carac MINUS 1 
  5693. $empty -= ($jws * $nb_spaces); 
  5694. $empty -= ($jkashida); 
  5695.  
  5696. $empty /= _MPDFK; 
  5697.  
  5698. if (!$is_table) { 
  5699. $this->maxPosR = max($this->maxPosR, ($this->w - $this->rMargin - $this->blk[$this->blklvl]['outer_right_margin'] - $empty)); 
  5700. $this->maxPosL = min($this->maxPosL, ($this->lMargin + $this->blk[$this->blklvl]['outer_left_margin'] + $empty)); 
  5701.  
  5702. $arraysize = count($chunkorder); 
  5703.  
  5704. $margins = ($this->cMarginL + $this->cMarginR) + ($ipaddingL + $ipaddingR + $fpaddingR + $fpaddingR ); 
  5705.  
  5706. if (!$is_table) { 
  5707. $this->DivLn($stackHeight, $this->blklvl, false); 
  5708. } // false -> don't advance y 
  5709.  
  5710. $this->x = $currentx + $this->cMarginL + $ipaddingL + $fpaddingL; 
  5711. if ($dottab !== false && $blockdir == 'rtl') { 
  5712. $this->x -= $dottab; 
  5713. } elseif ($align == 'R') { 
  5714. $this->x += $empty; 
  5715. } elseif ($align == 'J' && $blockdir == 'rtl') { 
  5716. $this->x += $empty; 
  5717. } elseif ($align == 'C') { 
  5718. $this->x += ($empty / 2); 
  5719.  
  5720. // Paragraph INDENT 
  5721. $WidthCorrection = 0; 
  5722. if (($newblock) && ($blockstate == 1 || $blockstate == 3) && isset($this->blk[$this->blklvl]['text_indent']) && ($lineCount == 0) && (!$is_table) && ($align != 'C')) { 
  5723. $ti = $this->ConvertSize($this->blk[$this->blklvl]['text_indent'], $this->blk[$this->blklvl]['inner_width'], $this->blk[$this->blklvl]['InlineProperties']['size'], false); // mPDF 5.7.4 
  5724. if ($blockdir != 'rtl') { 
  5725. $this->x += $ti; 
  5726. } // mPDF 6 
  5727.  
  5728. foreach ($chunkorder AS $aord => $k) { // mPDF 5.7 
  5729. $chunk = $content[$aord]; 
  5730. if (isset($this->objectbuffer[$k]) && $this->objectbuffer[$k]) { 
  5731.  
  5732. $xadj = $this->x - $this->objectbuffer[$k]['OUTER-X']; 
  5733. $this->objectbuffer[$k]['OUTER-X'] += $xadj; 
  5734. $this->objectbuffer[$k]['BORDER-X'] += $xadj; 
  5735. $this->objectbuffer[$k]['INNER-X'] += $xadj; 
  5736.  
  5737. if ($this->objectbuffer[$k]['type'] == 'listmarker') { 
  5738. $this->objectbuffer[$k]['lineBox'] = $lineBox[-1]; // Block element details for glyph-origin 
  5739. $yadj = $this->y - $this->objectbuffer[$k]['OUTER-Y']; 
  5740. if ($this->objectbuffer[$k]['type'] == 'dottab') { // mPDF 6 DOTTAB 
  5741. $this->objectbuffer[$k]['lineBox'] = $lineBox[$k]; // element details for glyph-origin 
  5742. if ($this->objectbuffer[$k]['type'] != 'dottab') { // mPDF 6 DOTTAB 
  5743. $yadj += $lineBox[$k]['top']; 
  5744. $this->objectbuffer[$k]['OUTER-Y'] += $yadj; 
  5745. $this->objectbuffer[$k]['BORDER-Y'] += $yadj; 
  5746. $this->objectbuffer[$k]['INNER-Y'] += $yadj; 
  5747.  
  5748. $this->restoreFont($font[$k]); // mPDF 5.7 
  5749.  
  5750. if ($is_table && substr($align, 0, 1) == 'D' && $aord == 0) { 
  5751. $dp = $this->decimal_align[substr($align, 0, 2)]; 
  5752. $s = preg_split('/' . preg_quote($dp, '/') . '/', $content[0], 2); // ? needs to be /u if not core 
  5753. $s0 = $this->GetStringWidth($s[0], false); 
  5754. $this->x += ($this->decimal_offset - $s0); 
  5755.  
  5756. $this->SetSpacing(($this->fixedlSpacing * _MPDFK) + $jcharspacing, ($this->fixedlSpacing + $this->minwSpacing) * _MPDFK + $jws); 
  5757. $this->fixedlSpacing = false; 
  5758. $this->minwSpacing = 0; 
  5759.  
  5760. $save_vis = $this->visibility; 
  5761. if (isset($this->textparam['visibility']) && $this->textparam['visibility'] && $this->textparam['visibility'] != $this->visibility) { 
  5762. $this->SetVisibility($this->textparam['visibility']); 
  5763.  
  5764. // *********** SPAN BACKGROUND COLOR ***************** // 
  5765. if (isset($this->spanbgcolor) && $this->spanbgcolor) { 
  5766. $cor = $this->spanbgcolorarray; 
  5767. $this->SetFColor($cor); 
  5768. $save_fill = $fill; 
  5769. $spanfill = 1; 
  5770. $fill = 1; 
  5771. if (!empty($this->spanborddet)) { 
  5772. if (strpos($contentB[$k], 'L') !== false && isset($this->spanborddet['L'])) 
  5773. $this->x += $this->spanborddet['L']['w']; 
  5774. if (strpos($contentB[$k], 'L') === false) 
  5775. $this->spanborddet['L']['s'] = $this->spanborddet['L']['w'] = 0; 
  5776. if (strpos($contentB[$k], 'R') === false) 
  5777. $this->spanborddet['R']['s'] = $this->spanborddet['R']['w'] = 0; 
  5778. // WORD SPACING 
  5779. // mPDF 5.7.1 
  5780. $stringWidth = $this->GetStringWidth($chunk, true, (isset($cOTLdata[$aord]) ? $cOTLdata[$aord] : false), $this->textvar); 
  5781. $nch = mb_strlen($chunk, $this->mb_enc); 
  5782. // Use GPOS OTL 
  5783. if (isset($this->CurrentFont['useOTL']) && $this->CurrentFont['useOTL']) { 
  5784. if (isset($cOTLdata[$aord]['group']) && $cOTLdata[$aord]['group']) { 
  5785. $nch -= substr_count($cOTLdata[$aord]['group'], 'M'); 
  5786. $stringWidth += ( $this->charspacing * $nch / _MPDFK ); 
  5787.  
  5788. $stringWidth += ( $this->ws * mb_substr_count($chunk, ' ', $this->mb_enc) / _MPDFK ); 
  5789.  
  5790. if (isset($this->objectbuffer[$k])) { 
  5791. if ($this->objectbuffer[$k]['type'] == 'dottab') { 
  5792. $this->objectbuffer[$k]['OUTER-WIDTH'] +=$empty; 
  5793. $this->objectbuffer[$k]['OUTER-WIDTH'] +=$this->objectbuffer[$k]['outdent']; 
  5794. // LIST MARKERS // mPDF 6 Lists 
  5795. if ($this->objectbuffer[$k]['type'] == 'image' && isset($this->objectbuffer[$k]['listmarker']) && $this->objectbuffer[$k]['listmarker'] && $this->objectbuffer[$k]['listmarkerposition'] == 'outside') { 
  5796. // do nothing 
  5797. } else { 
  5798. $stringWidth = $this->objectbuffer[$k]['OUTER-WIDTH']; 
  5799.  
  5800. if ($stringWidth == 0) { 
  5801. $stringWidth = 0.000001; 
  5802. if ($aord == $arraysize - 1) { // mPDF 5.7 
  5803. // mPDF 5.7.1 
  5804. if ($this->checkCJK && $CJKoverflow && $align == 'J' && $this->allowCJKoverflow && $hanger && $this->CJKforceend) { 
  5805. // force-end overhang 
  5806. $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 
  5807. $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 
  5808. } else { 
  5809. $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 
  5810. } else 
  5811. $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 
  5812.  
  5813.  
  5814. if (!empty($this->spanborddet)) { 
  5815. if (strpos($contentB[$k], 'R') !== false && $aord != $arraysize - 1) 
  5816. $this->x += $this->spanborddet['R']['w']; 
  5817. // *********** SPAN BACKGROUND COLOR OFF - RESET BLOCK BGCOLOR ***************** // 
  5818. if (isset($spanfill) && $spanfill) { 
  5819. $fill = $save_fill; 
  5820. $spanfill = 0; 
  5821. if ($fill) { 
  5822. $this->SetFColor($bcor); 
  5823. if (isset($this->textparam['visibility']) && $this->textparam['visibility'] && $this->visibility != $save_vis) { 
  5824. $this->SetVisibility($save_vis); 
  5825.  
  5826. $this->printobjectbuffer($is_table, $blockdir); 
  5827. $this->objectbuffer = array(); 
  5828. $this->ResetSpacing(); 
  5829. } // END IF CONTENT 
  5830.  
  5831. /** -- CSS-IMAGE-FLOAT -- */ 
  5832. // Update values if set to skipline 
  5833. if ($this->floatmargins) { 
  5834. $this->_advanceFloatMargins(); 
  5835.  
  5836.  
  5837. if ($endofblock && $blockstate > 1) { 
  5838. // If float exists at this level 
  5839. if (isset($this->floatmargins['R']['y1'])) { 
  5840. $fry1 = $this->floatmargins['R']['y1']; 
  5841. } else { 
  5842. $fry1 = 0; 
  5843. if (isset($this->floatmargins['L']['y1'])) { 
  5844. $fly1 = $this->floatmargins['L']['y1']; 
  5845. } else { 
  5846. $fly1 = 0; 
  5847. if ($this->y < $fry1 || $this->y < $fly1) { 
  5848. $drop = max($fry1, $fly1) - $this->y; 
  5849. $this->DivLn($drop); 
  5850. $this->x = $currentx; 
  5851. /** -- END CSS-IMAGE-FLOAT -- */ 
  5852.  
  5853.  
  5854. // PADDING and BORDER spacing/fill 
  5855. 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)) { 
  5856. // If CSS height set, extend bottom - if on same page as block started, and CSS HEIGHT > actual height,  
  5857. // and does not force pagebreak 
  5858. $extra = 0; 
  5859. if (isset($this->blk[$this->blklvl]['css_set_height']) && $this->blk[$this->blklvl]['css_set_height'] && $this->blk[$this->blklvl]['startpage'] == $this->page) { 
  5860. // predicted height 
  5861. $h1 = ($this->y - $this->blk[$this->blklvl]['y0']) + $this->blk[$this->blklvl]['padding_bottom'] + $this->blk[$this->blklvl]['border_bottom']['w']; 
  5862. if ($h1 < ($this->blk[$this->blklvl]['css_set_height'] + $this->blk[$this->blklvl]['padding_bottom'] + $this->blk[$this->blklvl]['padding_top'])) { 
  5863. $extra = ($this->blk[$this->blklvl]['css_set_height'] + $this->blk[$this->blklvl]['padding_bottom'] + $this->blk[$this->blklvl]['padding_top']) - $h1; 
  5864. if ($this->y + $this->blk[$this->blklvl]['padding_bottom'] + $this->blk[$this->blklvl]['border_bottom']['w'] + $extra > $this->PageBreakTrigger) { 
  5865. $extra = $this->PageBreakTrigger - ($this->y + $this->blk[$this->blklvl]['padding_bottom'] + $this->blk[$this->blklvl]['border_bottom']['w']); 
  5866.  
  5867. // $state = 0 normal; 1 top; 2 bottom; 3 top and bottom 
  5868. $this->DivLn($this->blk[$this->blklvl]['padding_bottom'] + $this->blk[$this->blklvl]['border_bottom']['w'] + $extra, -3, true, false, 2); 
  5869. $this->x = $currentx; 
  5870.  
  5871. if ($this->ColActive) { 
  5872. $this->breakpoints[$this->CurrCol][] = $this->y; 
  5873. } // *COLUMNS* 
  5874.  
  5875. // SET Bottom y1 of block (used for painting borders) 
  5876. if (($endofblock) && ($blockstate > 1) && (!$is_table)) { 
  5877. $this->blk[$this->blklvl]['y1'] = $this->y; 
  5878.  
  5879. // BOTTOM MARGIN 
  5880. if (($endofblock) && ($blockstate > 1) && ($this->blk[$this->blklvl]['margin_bottom']) && (!$is_table)) { 
  5881. if ($this->y + $this->blk[$this->blklvl]['margin_bottom'] < $this->PageBreakTrigger and ! $this->InFooter) { 
  5882. $this->DivLn($this->blk[$this->blklvl]['margin_bottom'], $this->blklvl - 1, true, $this->blk[$this->blklvl]['margin_collapse']); 
  5883. if ($this->ColActive) { 
  5884. $this->breakpoints[$this->CurrCol][] = $this->y; 
  5885. } // *COLUMNS* 
  5886.  
  5887. // Reset lineheight 
  5888. $stackHeight = $this->divheight; 
  5889.  
  5890. function printobjectbuffer($is_table = false, $blockdir = false) 
  5891. if (!$blockdir) { 
  5892. $blockdir = $this->directionality; 
  5893. if ($is_table && $this->shrin_k > 1) { 
  5894. $k = $this->shrin_k; 
  5895. } else { 
  5896. $k = 1; 
  5897. $save_y = $this->y; 
  5898. $save_x = $this->x; 
  5899. $save_currentfontfamily = $this->FontFamily; 
  5900. $save_currentfontsize = $this->FontSizePt; 
  5901. $save_currentfontstyle = $this->FontStyle; 
  5902. if ($blockdir == 'rtl') { 
  5903. $rtlalign = 'R'; 
  5904. } else { 
  5905. $rtlalign = 'L'; 
  5906. foreach ($this->objectbuffer AS $ib => $objattr) { 
  5907. if ($objattr['type'] == 'bookmark' || $objattr['type'] == 'indexentry' || $objattr['type'] == 'toc') { 
  5908. $x = $objattr['OUTER-X']; 
  5909. $y = $objattr['OUTER-Y']; 
  5910. $this->y = $y - $this->FontSize / 2; 
  5911. $this->x = $x; 
  5912. if ($objattr['type'] == 'bookmark') { 
  5913. $this->Bookmark($objattr['CONTENT'], $objattr['bklevel'], $y - $this->FontSize); 
  5914. } // *BOOKMARKS* 
  5915. if ($objattr['type'] == 'indexentry') { 
  5916. $this->IndexEntry($objattr['CONTENT']); 
  5917. } // *INDEX* 
  5918. if ($objattr['type'] == 'toc') { 
  5919. $this->TOC_Entry($objattr['CONTENT'], $objattr['toclevel'], (isset($objattr['toc_id']) ? $objattr['toc_id'] : '')); 
  5920. } // *TOC* 
  5921. /** -- ANNOTATIONS -- */ elseif ($objattr['type'] == 'annot') { 
  5922. if ($objattr['POS-X']) { 
  5923. $x = $objattr['POS-X']; 
  5924. } elseif ($this->annotMargin <> 0) { 
  5925. $x = -$objattr['OUTER-X']; 
  5926. } else { 
  5927. $x = $objattr['OUTER-X']; 
  5928. if ($objattr['POS-Y']) { 
  5929. $y = $objattr['POS-Y']; 
  5930. } else { 
  5931. $y = $objattr['OUTER-Y'] - $this->FontSize / 2; 
  5932. // Create a dummy entry in the _out/columnBuffer with position sensitive data,  
  5933. // linking $y-1 in the Columnbuffer with entry in $this->columnAnnots 
  5934. // and when columns are split in length will not break annotation from current line 
  5935. $this->y = $y - 1; 
  5936. $this->x = $x - 1; 
  5937. $this->Line($x - 1, $y - 1, $x - 1, $y - 1); 
  5938. $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'] : '')); 
  5939. /** -- END ANNOTATIONS -- */ else { 
  5940. $y = $objattr['OUTER-Y']; 
  5941. $x = $objattr['OUTER-X']; 
  5942. $w = $objattr['OUTER-WIDTH']; 
  5943. $h = $objattr['OUTER-HEIGHT']; 
  5944. if (isset($objattr['text'])) { 
  5945. $texto = $objattr['text']; 
  5946. $this->y = $y; 
  5947. $this->x = $x; 
  5948. if (isset($objattr['fontfamily'])) { 
  5949. $this->SetFont($objattr['fontfamily'], '', $objattr['fontsize']); 
  5950.  
  5951. // HR 
  5952. if ($objattr['type'] == 'hr') { 
  5953. $this->SetDColor($objattr['color']); 
  5954. switch ($objattr['align']) { 
  5955. case 'C': 
  5956. $empty = $objattr['OUTER-WIDTH'] - $objattr['INNER-WIDTH']; 
  5957. $empty /= 2; 
  5958. $x += $empty; 
  5959. break; 
  5960. case 'R': 
  5961. $empty = $objattr['OUTER-WIDTH'] - $objattr['INNER-WIDTH']; 
  5962. $x += $empty; 
  5963. break; 
  5964. $oldlinewidth = $this->LineWidth; 
  5965. $this->SetLineWidth($objattr['linewidth'] / $k); 
  5966. $this->y += ($objattr['linewidth'] / 2) + $objattr['margin_top'] / $k; 
  5967. $this->Line($x, $this->y, $x + $objattr['INNER-WIDTH'], $this->y); 
  5968. $this->SetLineWidth($oldlinewidth); 
  5969. $this->SetDColor($this->ConvertColor(0)); 
  5970. // IMAGE 
  5971. if ($objattr['type'] == 'image') { 
  5972. // mPDF 5.7.3 TRANSFORMS 
  5973. if (isset($objattr['transform'])) { 
  5974. $this->_out("\n" . '% BTR'); // Begin Transform 
  5975. if (isset($objattr['z-index']) && $objattr['z-index'] > 0 && $this->current_layer == 0) { 
  5976. $this->BeginLayer($objattr['z-index']); 
  5977. if (isset($objattr['visibility']) && $objattr['visibility'] != 'visible' && $objattr['visibility']) { 
  5978. $this->SetVisibility($objattr['visibility']); 
  5979. if (isset($objattr['opacity'])) { 
  5980. $this->SetAlpha($objattr['opacity']); 
  5981.  
  5982. $obiw = $objattr['INNER-WIDTH']; 
  5983. $obih = $objattr['INNER-HEIGHT']; 
  5984. $sx = $objattr['INNER-WIDTH'] * _MPDFK / $objattr['orig_w']; 
  5985. $sy = abs($objattr['INNER-HEIGHT']) * _MPDFK / abs($objattr['orig_h']); 
  5986. $sx = ($objattr['INNER-WIDTH'] * _MPDFK / $objattr['orig_w']); 
  5987. $sy = ($objattr['INNER-HEIGHT'] * _MPDFK / $objattr['orig_h']); 
  5988.  
  5989. $rotate = 0; 
  5990. if (isset($objattr['ROTATE'])) { 
  5991. $rotate = $objattr['ROTATE']; 
  5992. if ($rotate == 90) { 
  5993. // Clockwise 
  5994. $obiw = $objattr['INNER-HEIGHT']; 
  5995. $obih = $objattr['INNER-WIDTH']; 
  5996. $tr = $this->transformTranslate(0, -$objattr['INNER-WIDTH'], true); 
  5997. $tr .= ' ' . $this->transformRotate(90, $objattr['INNER-X'], ($objattr['INNER-Y'] + $objattr['INNER-WIDTH']), true); 
  5998. $sx = $obiw * _MPDFK / $objattr['orig_h']; 
  5999. $sy = $obih * _MPDFK / $objattr['orig_w']; 
  6000. } elseif ($rotate == -90 || $rotate == 270) { 
  6001. // AntiClockwise 
  6002. $obiw = $objattr['INNER-HEIGHT']; 
  6003. $obih = $objattr['INNER-WIDTH']; 
  6004. $tr = $this->transformTranslate($objattr['INNER-WIDTH'], ($objattr['INNER-HEIGHT'] - $objattr['INNER-WIDTH']), true); 
  6005. $tr .= ' ' . $this->transformRotate(-90, $objattr['INNER-X'], ($objattr['INNER-Y'] + $objattr['INNER-WIDTH']), true); 
  6006. $sx = $obiw * _MPDFK / $objattr['orig_h']; 
  6007. $sy = $obih * _MPDFK / $objattr['orig_w']; 
  6008. } elseif ($rotate == 180) { 
  6009. // Mirror 
  6010. $tr = $this->transformTranslate($objattr['INNER-WIDTH'], -$objattr['INNER-HEIGHT'], true); 
  6011. $tr .= ' ' . $this->transformRotate(180, $objattr['INNER-X'], ($objattr['INNER-Y'] + $objattr['INNER-HEIGHT']), true); 
  6012. } else { 
  6013. $tr = ''; 
  6014. $tr = trim($tr); 
  6015. if ($tr) { 
  6016. $tr .= ' '; 
  6017. $gradmask = ''; 
  6018.  
  6019. // mPDF 5.7.3 TRANSFORMS 
  6020. $tr2 = ''; 
  6021. if (isset($objattr['transform'])) { 
  6022. $maxsize_x = $w; 
  6023. $maxsize_y = $h; 
  6024. $cx = $x + $w / 2; 
  6025. $cy = $y + $h / 2; 
  6026. preg_match_all('/(translatex|translatey|translate|scalex|scaley|scale|rotate|skewX|skewY|skew)\((.*?)\)/is', $objattr['transform'], $m); 
  6027. if (count($m[0])) { 
  6028. for ($i = 0; $i < count($m[0]); $i++) { 
  6029. $c = strtolower($m[1][$i]); 
  6030. $v = trim($m[2][$i]); 
  6031. $vv = preg_split('/[ , ]+/', $v); 
  6032. if ($c == 'translate' && count($vv)) { 
  6033. $translate_x = $this->ConvertSize($vv[0], $maxsize_x, false, false); 
  6034. if (count($vv) == 2) { 
  6035. $translate_y = $this->ConvertSize($vv[1], $maxsize_y, false, false); 
  6036. } else { 
  6037. $translate_y = 0; 
  6038. $tr2 .= $this->transformTranslate($translate_x, $translate_y, true) . ' '; 
  6039. } elseif ($c == 'translatex' && count($vv)) { 
  6040. $translate_x = $this->ConvertSize($vv[0], $maxsize_x, false, false); 
  6041. $tr2 .= $this->transformTranslate($translate_x, 0, true) . ' '; 
  6042. } elseif ($c == 'translatey' && count($vv)) { 
  6043. $translate_y = $this->ConvertSize($vv[1], $maxsize_y, false, false); 
  6044. $tr2 .= $this->transformTranslate(0, $translate_y, true) . ' '; 
  6045. } elseif ($c == 'scale' && count($vv)) { 
  6046. $scale_x = $vv[0] * 100; 
  6047. if (count($vv) == 2) { 
  6048. $scale_y = $vv[1] * 100; 
  6049. } else { 
  6050. $scale_y = $scale_x; 
  6051. $tr2 .= $this->transformScale($scale_x, $scale_y, $cx, $cy, true) . ' '; 
  6052. } elseif ($c == 'scalex' && count($vv)) { 
  6053. $scale_x = $vv[0] * 100; 
  6054. $tr2 .= $this->transformScale($scale_x, 0, $cx, $cy, true) . ' '; 
  6055. } elseif ($c == 'scaley' && count($vv)) { 
  6056. $scale_y = $vv[1] * 100; 
  6057. $tr2 .= $this->transformScale(0, $scale_y, $cx, $cy, true) . ' '; 
  6058. } elseif ($c == 'skew' && count($vv)) { 
  6059. $angle_x = $this->ConvertAngle($vv[0], false); 
  6060. if (count($vv) == 2) { 
  6061. $angle_y = $this->ConvertAngle($vv[1], false); 
  6062. } else { 
  6063. $angle_y = 0; 
  6064. $tr2 .= $this->transformSkew($angle_x, $angle_y, $cx, $cy, true) . ' '; 
  6065. } elseif ($c == 'skewx' && count($vv)) { 
  6066. $angle = $this->ConvertAngle($vv[0], false); 
  6067. $tr2 .= $this->transformSkew($angle, 0, $cx, $cy, true) . ' '; 
  6068. } elseif ($c == 'skewy' && count($vv)) { 
  6069. $angle = $this->ConvertAngle($vv[0], false); 
  6070. $tr2 .= $this->transformSkew(0, $angle, $cx, $cy, true) . ' '; 
  6071. } elseif ($c == 'rotate' && count($vv)) { 
  6072. $angle = $this->ConvertAngle($vv[0]); 
  6073. $tr2 .= $this->transformRotate($angle, $cx, $cy, true) . ' '; 
  6074.  
  6075. // LIST MARKERS (Images) // mPDF 6 Lists 
  6076. if (isset($objattr['listmarker']) && $objattr['listmarker'] && $objattr['listmarkerposition'] == 'outside') { 
  6077. $mw = $objattr['OUTER-WIDTH']; 
  6078. // NB If change marker-offset, also need to alter in function _getListMarkerWidth 
  6079. $adjx = $this->ConvertSize($this->list_marker_offset, $this->FontSize); 
  6080. if ($objattr['dir'] == 'rtl') { 
  6081. $objattr['INNER-X'] += $adjx; 
  6082. } else { 
  6083. $objattr['INNER-X'] -= $adjx; 
  6084. $objattr['INNER-X'] -= $mw; 
  6085. // mPDF 5.7.3 TRANSFORMS / BACKGROUND COLOR 
  6086. // Transform also affects image background 
  6087. if ($tr2) { 
  6088. $this->_out('q ' . $tr2 . ' '); 
  6089. if (isset($objattr['bgcolor']) && $objattr['bgcolor']) { 
  6090. $bgcol = $objattr['bgcolor']; 
  6091. $this->SetFColor($bgcol); 
  6092. $this->Rect($x, $y, $w, $h, 'F'); 
  6093. $this->SetFColor($this->ConvertColor(255)); 
  6094. if ($tr2) { 
  6095. $this->_out('Q'); 
  6096.  
  6097. /** -- BACKGROUNDS -- */ 
  6098. if (isset($objattr['GRADIENT-MASK'])) { 
  6099. $g = $this->grad->parseMozGradient($objattr['GRADIENT-MASK']); 
  6100. if ($g) { 
  6101. $dummy = $this->grad->Gradient($objattr['INNER-X'], $objattr['INNER-Y'], $obiw, $obih, $g['type'], $g['stops'], $g['colorspace'], $g['coords'], $g['extend'], true, true); 
  6102. $gradmask = '/TGS' . count($this->gradients) . ' gs '; 
  6103. /** -- END BACKGROUNDS -- */ 
  6104. /** -- IMAGES-WMF -- */ 
  6105. if (isset($objattr['itype']) && $objattr['itype'] == 'wmf') { 
  6106. $outstring = sprintf('q ' . $tr . $tr2 . '%.3F 0 0 %.3F %.3F %.3F cm /FO%d Do Q', $sx, -$sy, $objattr['INNER-X'] * _MPDFK - $sx * $objattr['wmf_x'], (($this->h - $objattr['INNER-Y']) * _MPDFK) + $sy * $objattr['wmf_y'], $objattr['ID']); // mPDF 5.7.3 TRANSFORMS 
  6107. } else 
  6108. /** -- END IMAGES-WMF -- */ 
  6109. if (isset($objattr['itype']) && $objattr['itype'] == 'svg') { 
  6110. $outstring = sprintf('q ' . $tr . $tr2 . '%.3F 0 0 %.3F %.3F %.3F cm /FO%d Do Q', $sx, -$sy, $objattr['INNER-X'] * _MPDFK - $sx * $objattr['wmf_x'], (($this->h - $objattr['INNER-Y']) * _MPDFK) + $sy * $objattr['wmf_y'], $objattr['ID']); // mPDF 5.7.3 TRANSFORMS 
  6111. } else { 
  6112. $outstring = sprintf("q " . $tr . $tr2 . "%.3F 0 0 %.3F %.3F %.3F cm " . $gradmask . "/I%d Do Q", $obiw * _MPDFK, $obih * _MPDFK, $objattr['INNER-X'] * _MPDFK, ($this->h - ($objattr['INNER-Y'] + $obih )) * _MPDFK, $objattr['ID']); // mPDF 5.7.3 TRANSFORMS 
  6113. $this->_out($outstring); 
  6114. // LINK 
  6115. if (isset($objattr['link'])) 
  6116. $this->Link($objattr['INNER-X'], $objattr['INNER-Y'], $objattr['INNER-WIDTH'], $objattr['INNER-HEIGHT'], $objattr['link']); 
  6117. if (isset($objattr['opacity'])) { 
  6118. $this->SetAlpha(1); 
  6119.  
  6120. // mPDF 5.7.3 TRANSFORMS 
  6121. // Transform also affects image borders 
  6122. if ($tr2) { 
  6123. $this->_out('q ' . $tr2 . ' '); 
  6124. if ((isset($objattr['border_top']) && $objattr['border_top'] > 0) || (isset($objattr['border_left']) && $objattr['border_left'] > 0) || (isset($objattr['border_right']) && $objattr['border_right'] > 0) || (isset($objattr['border_bottom']) && $objattr['border_bottom'] > 0)) { 
  6125. $this->PaintImgBorder($objattr, $is_table); 
  6126. if ($tr2) { 
  6127. $this->_out('Q'); 
  6128.  
  6129. if (isset($objattr['visibility']) && $objattr['visibility'] != 'visible' && $objattr['visibility']) { 
  6130. $this->SetVisibility('visible'); 
  6131. if (isset($objattr['z-index']) && $objattr['z-index'] > 0 && $this->current_layer == 0) { 
  6132. $this->EndLayer(); 
  6133. // mPDF 5.7.3 TRANSFORMS 
  6134. if (isset($objattr['transform'])) { 
  6135. $this->_out("\n" . '% ETR'); // End Transform 
  6136.  
  6137. /** -- BARCODES -- */ 
  6138. // BARCODE 
  6139. if ($objattr['type'] == 'barcode') { 
  6140. $bgcol = $this->ConvertColor(255); 
  6141. if (isset($objattr['bgcolor']) && $objattr['bgcolor']) { 
  6142. $bgcol = $objattr['bgcolor']; 
  6143. $col = $this->ConvertColor(0); 
  6144. if (isset($objattr['color']) && $objattr['color']) { 
  6145. $col = $objattr['color']; 
  6146. $this->SetFColor($bgcol); 
  6147. $this->Rect($objattr['BORDER-X'], $objattr['BORDER-Y'], $objattr['BORDER-WIDTH'], $objattr['BORDER-HEIGHT'], 'F'); 
  6148. $this->SetFColor($this->ConvertColor(255)); 
  6149. if (isset($objattr['BORDER-WIDTH'])) { 
  6150. $this->PaintImgBorder($objattr, $is_table); 
  6151. if ($objattr['btype'] == 'EAN13' || $objattr['btype'] == 'ISBN' || $objattr['btype'] == 'ISSN' || $objattr['btype'] == 'UPCA' || $objattr['btype'] == 'UPCE' || $objattr['btype'] == 'EAN8') { 
  6152. $this->WriteBarcode($objattr['code'], $objattr['showtext'], $objattr['INNER-X'], $objattr['INNER-Y'], $objattr['bsize'], 0, 0, 0, 0, 0, $objattr['bheight'], $bgcol, $col, $objattr['btype'], $objattr['bsupp'], (isset($objattr['bsupp_code']) ? $objattr['bsupp_code'] : ''), $k); 
  6153. // QR-code 
  6154. elseif ($objattr['btype'] == 'QR') { 
  6155. if (!class_exists('QRcode', false)) { 
  6156. include(_MPDF_PATH . 'qrcode/qrcode.class.php'); 
  6157. $this->qrcode = new QRcode($objattr['code'], $objattr['errorlevel']); 
  6158. $this->qrcode->displayFPDF($this, $objattr['INNER-X'], $objattr['INNER-Y'], $objattr['bsize'] * 25, array(255, 255, 255), array(0, 0, 0)); 
  6159. } else { 
  6160. $this->WriteBarcode2($objattr['code'], $objattr['INNER-X'], $objattr['INNER-Y'], $objattr['bsize'], $objattr['bheight'], $bgcol, $col, $objattr['btype'], $objattr['pr_ratio'], $k); 
  6161. /** -- END BARCODES -- */ 
  6162.  
  6163. // TEXT CIRCLE 
  6164. if ($objattr['type'] == 'textcircle') { 
  6165. $bgcol = ''; 
  6166. if (isset($objattr['bgcolor']) && $objattr['bgcolor']) { 
  6167. $bgcol = $objattr['bgcolor']; 
  6168. $col = $this->ConvertColor(0); 
  6169. if (isset($objattr['color']) && $objattr['color']) { 
  6170. $col = $objattr['color']; 
  6171. $this->SetTColor($col); 
  6172. $this->SetFColor($bgcol); 
  6173. if ($bgcol) 
  6174. $this->Rect($objattr['BORDER-X'], $objattr['BORDER-Y'], $objattr['BORDER-WIDTH'], $objattr['BORDER-HEIGHT'], 'F'); 
  6175. $this->SetFColor($this->ConvertColor(255)); 
  6176. if (isset($objattr['BORDER-WIDTH'])) { 
  6177. $this->PaintImgBorder($objattr, $is_table); 
  6178. if (!class_exists('directw', false)) { 
  6179. include(_MPDF_PATH . 'classes/directw.php'); 
  6180. if (empty($this->directw)) { 
  6181. $this->directw = new directw($this); 
  6182. if (isset($objattr['top-text'])) { 
  6183. $this->directw->CircularText($objattr['INNER-X'] + $objattr['INNER-WIDTH'] / 2, $objattr['INNER-Y'] + $objattr['INNER-HEIGHT'] / 2, $objattr['r'] / $k, $objattr['top-text'], 'top', $objattr['fontfamily'], $objattr['fontsize'] / $k, $objattr['fontstyle'], $objattr['space-width'], $objattr['char-width'], (isset($objattr['divider']) ? $objattr['divider'] : '')); 
  6184. if (isset($objattr['bottom-text'])) { 
  6185. $this->directw->CircularText($objattr['INNER-X'] + $objattr['INNER-WIDTH'] / 2, $objattr['INNER-Y'] + $objattr['INNER-HEIGHT'] / 2, $objattr['r'] / $k, $objattr['bottom-text'], 'bottom', $objattr['fontfamily'], $objattr['fontsize'] / $k, $objattr['fontstyle'], $objattr['space-width'], $objattr['char-width'], (isset($objattr['divider']) ? $objattr['divider'] : '')); 
  6186.  
  6187. $this->ResetSpacing(); 
  6188.  
  6189. // LIST MARKERS (Text or bullets)