*
// License: GPL *
// *
// Changes: See changelog.txt *
// ******************************************************************************
define('mPDF_VERSION','5.0');
define('AUTOFONT_CJK',1);
define('AUTOFONT_THAIVIET',2);
define('AUTOFONT_RTL',4);
define('AUTOFONT_INDIC',8);
define('AUTOFONT_ALL',15);
define('_BORDER_ALL',15);
define('_BORDER_TOP',8);
define('_BORDER_RIGHT',4);
define('_BORDER_BOTTOM',2);
define('_BORDER_LEFT',1);
if (!defined('_MPDF_PATH')) define('_MPDF_PATH', dirname(preg_replace('/\\\\/','/',__FILE__)) . '/');
if (!defined('_MPDF_URI')) define('_MPDF_URI',_MPDF_PATH); // mPDF 5.0
require_once(_MPDF_PATH.'includes/functions.php');
require_once(_MPDF_PATH.'config_cp.php');
if (!defined('_JPGRAPH_PATH')) define("_JPGRAPH_PATH", _MPDF_PATH.'jpgraph/');
if (!defined('_MPDF_TEMP_PATH')) define("_MPDF_TEMP_PATH", _MPDF_PATH.'tmp/');
if (!defined('_MPDF_TTFONTPATH')) { define('_MPDF_TTFONTPATH',_MPDF_PATH.'ttfonts/'); } // mPDF 5.0
if (!defined('_MPDF_TTFONTDATAPATH')) { define('_MPDF_TTFONTDATAPATH',_MPDF_PATH.'ttfontdata/'); }
$errorlevel=error_reporting();
$errorlevel=error_reporting($errorlevel & ~E_NOTICE);
//error_reporting(E_ALL);
if(function_exists("date_default_timezone_set") and function_exists("date_default_timezone_get"))
@date_default_timezone_set(@date_default_timezone_get());
if (!function_exists("mb_strlen")) { die("Error - mPDF requires mb_string functions. Ensure that PHP is compiled with php_mbstring.dll enabled."); }
// mPDF 5.0
if (!defined('PHP_VERSION_ID')) {
$version = explode('.', PHP_VERSION);
define('PHP_VERSION_ID', ($version[0] * 10000 + $version[1] * 100 + $version[2]));
}
class mPDF
{
///////////////////////////////
// EXTERNAL (PUBLIC) VARIABLES
// Define these in config.php
///////////////////////////////
// mPDF 5.0
var $iterationCounter;
var $smCapsScale;
var $smCapsStretch;
var $backupSubsFont;
var $backupSIPFont;
var $debugfonts;
var $useAdobeCJK;
var $percentSubset;
var $maxTTFFilesize;
var $BMPonly;
var $tableMinSizePriority;
var $dpi;
var $watermarkImgAlphaBlend;
var $watermarkImgBehind;
var $justifyB4br;
var $packTableData;
var $pgsIns;var $PDFA;var $PDFAauto;var $ICCProfile;var $simpleTables;
var $enableImports;
var $debug;
var $showStats;
var $setAutoTopMargin;
var $setAutoBottomMargin;
var $autoMarginPadding;
var $collapseBlockMargins;
var $falseBoldWeight;
var $normalLineheight;
var $progressBar;
var $incrementFPR1;
var $incrementFPR2;
var $incrementFPR3;
var $incrementFPR4;
var $hyphenate;
var $hyphenateTables;
var $SHYlang;
var $SHYleftmin;
var $SHYrightmin;
var $SHYcharmin;
var $SHYcharmax;
var $SHYlanguages;
// PageNumber Conditional Text
var $pagenumPrefix;
var $pagenumSuffix;
var $nbpgPrefix;
var $nbpgSuffix;
var $showImageErrors;
var $allow_output_buffering;
var $autoPadding;
var $useGraphs;
var $autoFontGroupSize;
var $disableMultilingualJustify;
var $tabSpaces;
var $useLang;
var $restoreBlockPagebreaks;
var $watermarkTextAlpha;
var $watermarkImageAlpha;
var $watermark_size;
var $watermark_pos;
var $annotSize;
var $annotMargin;
var $annotOpacity;
var $title2annots;
var $keepColumns;
var $keep_table_proportions;
var $ignore_table_widths;
var $ignore_table_percents;
var $list_align_style;
var $list_number_suffix;
var $useSubstitutions;
var $CSSselectMedia;
// $disablePrintCSS depracated
var $forcePortraitHeaders;
var $forcePortraitMargins;
var $displayDefaultOrientation;
var $ignore_invalid_utf8;
var $allowedCSStags;
var $onlyCoreFonts;
var $allow_charset_conversion;
var $jSpacing;
var $jSWord;
var $jSmaxChar;
var $jSmaxCharLast;
var $jSmaxWordLast;
var $orphansAllowed;
var $max_colH_correction;
var $table_error_report;
var $table_error_report_param;
var $biDirectional;
var $text_input_as_HTML;
var $anchor2Bookmark;
var $list_indent_first_level;
var $shrink_tables_to_fit;
var $rtlCSS;
var $allow_html_optional_endtags;
var $img_dpi;
var $defaultheaderfontsize;
var $defaultheaderfontstyle;
var $defaultheaderline;
var $defaultfooterfontsize;
var $defaultfooterfontstyle;
var $defaultfooterline;
var $header_line_spacing;
var $footer_line_spacing;
var $textarea_lineheight;
var $pregRTLchars;
var $pregUHCchars;
var $pregSJISchars;
var $pregCJKchars;
var $pregASCIIchars1;
var $pregASCIIchars2;
var $pregASCIIchars3;
var $pregVIETchars;
var $pregVIETPluschars;
var $pregHEBchars;
var $pregARABICchars;
var $pregNonARABICchars;
// INDIC
var $pregHIchars;
var $pregBNchars;
var $pregPAchars;
var $pregGUchars;
var $pregORchars;
var $pregTAchars;
var $pregTEchars;
var $pregKNchars;
var $pregMLchars;
var $pregSHchars;
var $pregINDextra;
var $mirrorMargins;
var $default_lineheight_correction;
var $watermarkText;
var $watermarkImage;
var $showWatermarkText;
var $showWatermarkImage;
var $fontsizes;
// Aliases for backward compatability
var $UnvalidatedText; // alias = $watermarkText
var $TopicIsUnvalidated; // alias = $showWatermarkText
var $useOddEven; // alias = $mirrorMargins
var $useSubstitutionsMB; // alias = $useSubstitutions
//////////////////////
// INTERNAL VARIABLES
//////////////////////
var $inlineDisplayOff; // mPDF 5.0
var $kt_y00;
var $kt_p00;
var $upperCase;
var $checkSIP; // mPDF 5.0
var $checkSMP; // mPDF 5.0.03
var $checkCJK; // mPDF 5.0
var $tableCJK; // mPDF 5.0
var $watermarkImgAlpha;
var $PDFAwarnings;
var $MetadataRoot;
var $OutputIntentRoot;
var $InfoRoot;
var $current_filename;
var $parsers;
var $current_parser;
var $_obj_stack;
var $_don_obj_stack;
var $_current_obj_id;
var $tpls;
var $tpl;
var $tplprefix;
var $_res;
var $pdf_version;
var $noImageFile;
var $lastblockbottommargin;
var $baselineC;
var $subPos;
var $subArrMB;
var $ReqFontStyle;
var $tableClipPath ;
var $forceExactLineheight;
var $listOcc;
var $fullImageHeight;
var $inFixedPosBlock; // Internal flag for position:fixed block
var $fixedPosBlock; // Buffer string for position:fixed block
var $fixedPosBlockDepth;
var $fixedPosBlockBBox;
var $fixedPosBlockSave;
var $maxPosL;
var $maxPosR;
var $loaded;
var $extraFontSubsets;
var $docTemplateStart; // Internal flag for page (page no. -1) that docTemplate starts on
var $time0;
// Classes
var $indic;
var $barcode;
var $SHYpatterns;
var $loadedSHYpatterns;
var $loadedSHYdictionary;
var $SHYdictionary;
var $SHYdictionaryWords;
var $spanbgcolorarray;
var $default_font;
var $list_lineheight;
var $headerbuffer;
var $lastblocklevelchange;
var $nestedtablejustfinished;
var $linebreakjustfinished;
var $cell_border_dominance_L;
var $cell_border_dominance_R;
var $cell_border_dominance_T;
var $cell_border_dominance_B;
var $tbCSSlvl;
var $listCSSlvl;
var $table_keep_together;
var $plainCell_properties;
var $inherit_lineheight;
var $listitemtype;
var $shrin_k1;
var $outerfilled;
var $blockContext;
var $floatDivs;
var $tablecascadeCSS;
var $listcascadeCSS;
var $patterns;
var $pageBackgrounds;
var $bodyBackgroundGradient;
var $bodyBackgroundImage;
var $bodyBackgroundColor;
var $writingHTMLheader; // internal flag - used both for writing HTMLHeaders/Footers and FixedPos block
var $writingHTMLfooter;
var $autoFontGroups;
var $angle;
var $gradients;
var $kwt_Reference;
var $kwt_BMoutlines;
var $kwt_toc;
var $tbrot_Reference;
var $tbrot_BMoutlines;
var $tbrot_toc;
var $col_Reference;
var $col_BMoutlines;
var $col_toc;
var $currentGraphId;
var $graphs;
var $floatbuffer;
var $floatmargins;
var $bullet;
var $bulletarray;
var $rtlAsArabicFarsi; // DEPRACATED
var $currentLang;
var $default_lang;
var $default_jSpacing;
var $default_available_fonts;
var $default_dir;
var $pageTemplate;
var $docTemplate;
var $docTemplateContinue;
var $arabGlyphs;
var $arabHex;
var $persianGlyphs;
var $persianHex;
var $arabVowels;
var $arabPrevLink;
var $arabNextLink;
var $formobjects; // array of Form Objects for WMF
var $gdiObjectArray; // array of GDI objects for WMF
var $InlineProperties; // Should have done this a long time ago
var $InlineAnnots;
var $ktAnnots;
var $tbrot_Annots;
var $kwt_Annots;
var $columnAnnots;
var $PageAnnots;
var $pageDim; // Keep track of page wxh for orientation changes - set in _beginpage, used in _putannots
var $breakpoints;
var $tableLevel;
var $tbctr;
var $innermostTableLevel;
var $saveTableCounter;
var $cellBorderBuffer;
var $saveHTMLFooter_height;
var $saveHTMLFooterE_height;
var $firstPageBoxHeader;
var $firstPageBoxHeaderEven;
var $firstPageBoxFooter;
var $firstPageBoxFooterEven;
var $page_box;
var $show_marks; // crop or cross marks
var $basepathIsLocal;
var $use_kwt;
var $kwt;
var $kwt_height;
var $kwt_y0;
var $kwt_x0;
var $kwt_buffer;
var $kwt_Links;
var $kwt_moved;
var $kwt_saved;
// NOT USED???
var $formBgColor;
var $formBgColorSmall; // Color used for background of form fields if reduced in size (so border disappears)
var $PageNumSubstitutions;
var $table_borders_separate;
var $base_table_properties;
var $borderstyles;
// doesn't include none or hidden
var $listjustfinished;
var $blockjustfinished;
var $orig_bMargin;
var $orig_tMargin;
var $orig_lMargin;
var $orig_rMargin;
var $orig_hMargin;
var $orig_fMargin;
var $pageheaders;
var $pagefooters;
var $pageHTMLheaders;
var $pageHTMLfooters;
var $saveHTMLHeader;
var $saveHTMLFooter;
var $HTMLheaderPageLinks;
var $HTMLheaderPageAnnots; // mPDF 5.0
// See config_fonts.php for these next 5 values
var $available_unifonts;
var $sans_fonts;
var $serif_fonts;
var $mono_fonts;
var $defaultSubsFont; // mPDF 5.0
// List of ALL available CJK fonts (incl. styles) (Adobe add-ons) hw removed
var $available_CJK_fonts;
var $cascadeCSS;
var $HTMLHeader;
var $HTMLFooter;
var $HTMLHeaderE; // for Even pages
var $HTMLFooterE; // for Even pages
var $bufferoutput;
var $showdefaultpagenos; // DEPRACATED -left for backward compatability
var $chrs;
var $ords;
// CJK fonts
var $Big5_widths;
var $GB_widths;
var $SJIS_widths;
var $UHC_widths;
// SetProtection
var $encrypted; //whether document is protected
var $Uvalue; //U entry in pdf document
var $Ovalue; //O entry in pdf document
var $Pvalue; //P entry in pdf document
var $enc_obj_id; //encryption object id
var $last_rc4_key; //last RC4 key encrypted (cached for optimisation)
var $last_rc4_key_c; //last RC4 computed key
var $encryption_key;
var $padding; //used for encryption
// Bookmark
var $BMoutlines;
var $OutlineRoot;
// TOC
var $_toc;
var $TOCmark;
var $TOCfont;
var $TOCfontsize;
var $TOCindent;
var $TOCheader;
var $TOCfooter;
var $TOCpreHTML;
var $TOCpostHTML;
var $TOCbookmarkText;
var $TOCusePaging;
var $TOCuseLinking;
var $TOCorientation;
var $TOC_margin_left;
var $TOC_margin_right;
var $TOC_margin_top;
var $TOC_margin_bottom;
var $TOC_margin_header;
var $TOC_margin_footer;
var $TOC_odd_header_name;
var $TOC_even_header_name;
var $TOC_odd_footer_name;
var $TOC_even_footer_name;
var $TOC_odd_header_value;
var $TOC_even_header_value;
var $TOC_odd_footer_value;
var $TOC_even_footer_value;
var $TOC_start;
var $TOC_end;
var $TOC_npages;
var $m_TOC;
// INDEX
var $ColActive;
var $ChangePage; //Flag indicating that a page break has occurred
var $Reference;
var $CurrCol;
var $NbCol;
var $y0; //Top ordinate of columns
var $ColL;
var $ColWidth;
var $ColGap;
// COLUMNS
var $ColR;
var $ChangeColumn;
var $columnbuffer;
var $ColDetails;
var $columnLinks;
var $colvAlign;
// Substitutions
var $substitute; // Array of substitution strings e.g. 112
var $entsearch; // Array of HTML entities (>ASCII 127) to substitute
var $entsubstitute; // Array of substitution decimal unicode for the Hi entities
// Default values if no style sheet offered (cf. http://www.w3.org/TR/CSS21/sample.html)
var $defaultCSS;
var $form_element_spacing;
var $linemaxfontsize;
var $lineheight_correction;
var $lastoptionaltag; // Save current block item which HTML specifies optionsl endtag
var $pageoutput;
var $charset_in;
var $blk;
var $blklvl;
var $ColumnAdjust;
var $ws; // Word spacing
var $HREF;
var $pgwidth;
var $fontlist;
var $issetfont;
var $issetcolor;
var $oldx;
var $oldy;
var $B;
var $U; //underlining flag
var $S; // mPDF 5.0 SmallCaps flag
var $I;
var $tdbegin;
var $table;
var $cell;
var $col;
var $row;
var $divbegin;
var $divalign;
var $divwidth;
var $divheight;
var $divrevert;
var $spanbgcolor;
var $spanlvl;
var $listlvl;
var $listnum;
var $listtype;
var $listoccur;
var $listlist;
var $listitem;
var $pjustfinished;
var $ignorefollowingspaces;
var $SUP;
var $SUB;
var $SMALL;
var $BIG;
var $toupper;
var $tolower;
var $dash_on;
var $dotted_on;
var $strike;
var $CSS;
var $textbuffer;
var $currentfontstyle;
var $currentfontfamily;
var $currentfontsize;
var $colorarray;
var $bgcolorarray;
var $internallink;
var $enabledtags;
var $lineheight;
var $basepath;
var $outlineparam;
var $outline_on;
var $specialcontent;
var $selectoption;
var $usecss;
var $usepre;
var $usetableheader;
var $tableheadernrows;
var $tablefooternrows;
var $objectbuffer;
// Table Rotation
var $table_rotate;
var $tbrot_maxw;
var $tbrot_maxh;
var $tablebuffer;
var $tbrot_align;
var $tbrot_Links;
var $divbuffer; // Buffer used when keeping DIV on one page
var $keep_block_together; // Keep a Block from page-break-inside: avoid
var $ktLinks; // Keep-together Block links array
var $ktBlock; // Keep-together Block array
var $ktReference;
var $ktBMoutlines;
var $_kttoc;
var $tbrot_y0;
var $tbrot_x0;
var $tbrot_w;
var $tbrot_h;
var $mb_enc;
var $directionality;
var $extgstates; // Used for alpha channel - Transparency (Watermark)
var $tt_savefont;
var $mgl;
var $mgt;
var $mgr;
var $mgb;
var $tts;
var $ttz;
var $tta;
var $headerDetails;
var $footerDetails;
// Best to alter the below variables using default stylesheet above
var $div_margin_bottom;
var $div_bottom_border;
var $p_margin_bottom;
var $p_bottom_border;
var $page_break_after_avoid;
var $margin_bottom_collapse;
var $img_margin_top; // default is set at top of fn.openTag 'IMG'
var $img_margin_bottom;
var $list_indent;
var $list_align;
var $list_margin_bottom;
var $default_font_size; // in pts
var $original_default_font_size; // used to save default sizes when using table default
var $original_default_font;
var $watermark_font;
var $defaultAlign;
// TABLE
var $defaultTableAlign;
var $tablethead;
var $thead_font_weight;
var $thead_font_style;
var $thead_font_smCaps; // mPDF 5.0
var $thead_valign_default;
var $thead_textalign_default;
var $tabletfoot;
var $tfoot_font_weight;
var $tfoot_font_style;
var $tfoot_font_smCaps; // mPDF 5.0
var $tfoot_valign_default;
var $tfoot_textalign_default;
var $trow_text_rotate;
var $cellPaddingL;
var $cellPaddingR;
var $cellPaddingT;
var $cellPaddingB;
var $table_lineheight;
var $table_border_attr_set;
var $table_border_css_set;
var $shrin_k; // factor with which to shrink tables - used internally - do not change
var $shrink_this_table_to_fit; // 0 or false to disable; value (if set) gives maximum factor to reduce fontsize
var $MarginCorrection; // corrects for OddEven Margins
var $margin_footer;
var $margin_header;
var $tabletheadjustfinished;
var $usingCoreFont;
var $charspacing;
//Private properties FROM FPDF
var $DisplayPreferences;
var $outlines;
var $flowingBlockAttr;
var $page; //current page number
var $n; //current object number
var $offsets; //array of object offsets
var $buffer; //buffer holding in-memory PDF
var $pages; //array containing pages
var $state; //current document state
var $compress; //compression flag
var $DefOrientation; //default orientation
var $CurOrientation; //current orientation
var $OrientationChanges; //array indicating orientation changes
var $k; //scale factor (number of points in user unit)
var $fwPt;
var $fhPt; //dimensions of page format in points
var $fw;
var $fh; //dimensions of page format in user unit
var $wPt;
var $hPt; //current dimensions of page in points
var $w;
var $h; //current dimensions of page in user unit
var $lMargin; //left margin
var $tMargin; //top margin
var $rMargin; //right margin
var $bMargin; //page break margin
var $cMarginL; //cell margin Left
var $cMarginR; //cell margin Right
var $cMarginT; //cell margin Left
var $cMarginB; //cell margin Right
var $DeflMargin; //Default left margin
var $DefrMargin; //Default right margin
var $x;
var $y; //current position in user unit for cell positioning
var $lasth; //height of last cell printed
var $LineWidth; //line width in user unit
var $CoreFonts; //array of standard font names
var $fonts; //array of used fonts
var $FontFiles; //array of font files
var $diffs; //array of encoding differences
var $images; //array of used images
var $PageLinks; //array of links in pages
var $links; //array of internal links
var $FontFamily; //current font family
var $FontStyle; //current font style
var $CurrentFont; //current font info
var $FontSizePt; //current font size in points
var $FontSize; //current font size in user unit
var $DrawColor; //commands for drawing color
var $FillColor; //commands for filling color
var $TextColor; //commands for text color
var $ColorFlag; //indicates whether fill and text colors are different
var $autoPageBreak; //automatic page breaking
var $PageBreakTrigger; //threshold used to trigger page breaks
var $InFooter; //flag set when processing footer
var $InHTMLFooter;
var $processingFooter; //flag set when processing footer - added for columns
var $processingHeader; //flag set when processing header - added for columns
var $ZoomMode; //zoom display mode
var $LayoutMode; //layout display mode
var $title; //title
var $subject; //subject
var $author; //author
var $keywords; //keywords
var $creator; //creator
var $aliasNbPg; //alias for total number of pages
var $aliasNbPgGp; //alias for total number of pages in page group
var $aliasNbPgHex; // mPDF 5.0.04
var $aliasNbPgGpHex; // mPDF 5.0.04
var $ispre;
var $outerblocktags;
var $innerblocktags;
// NOT Currently used
var $inlinetags;
var $listtags;
var $tabletags;
var $formtags;
// **********************************
// **********************************
// **********************************
// **********************************
// **********************************
// **********************************
// **********************************
// **********************************
// **********************************
function mPDF($mode='',$format='A4',$default_font_size=0,$default_font='',$mgl=15,$mgr=15,$mgt=16,$mgb=16,$mgh=9,$mgf=9, $orientation='P') {
$this->time0 = microtime(true);
$unit='mm';
//Some checks
$this->_dochecks();
// Set up Aliases for backwards compatability
$this->UnvalidatedText =& $this->watermarkText;
$this->TopicIsUnvalidated =& $this->showWatermarkText;
$this->AliasNbPg =& $this->aliasNbPg;
$this->AliasNbPgGp =& $this->aliasNbPgGp;
$this->BiDirectional =& $this->biDirectional;
$this->Anchor2Bookmark =& $this->anchor2Bookmark;
$this->KeepColumns =& $this->keepColumns;
$this->useOddEven =& $this->mirrorMargins;
$this->useSubstitutionsMB =& $this->useSubstitutions; // mPDF 5.0
//Initialization of properties
// mPDF 5.0
$this->kt_y00 = '';
$this->kt_p00 = '';
$this->iterationCounter = false;
$this->BMPonly = array();
$this->page=0;
$this->n=2;
$this->buffer='';
$this->objectbuffer = array();
$this->pages=array();
$this->OrientationChanges=array();
$this->state=0;
$this->fonts=array();
$this->FontFiles=array();
$this->diffs=array();
$this->images=array();
$this->links=array();
$this->InFooter=false;
$this->processingFooter=false;
$this->processingHeader=false;
$this->lasth=0;
$this->FontFamily='';
$this->FontStyle='';
$this->FontSizePt=9;
$this->U=false;
// mPDF 5.0 Small Caps
$this->upperCase = array();
@include(_MPDF_PATH.'includes/upperCase.php');
$this->S = false; // mPDF 5.0
$this->smCapsScale = 1;
$this->smCapsStretch = 100;
$this->DrawColor='0 G';
$this->FillColor='0 g';
$this->TextColor='0 g';
$this->ColorFlag=false;
$this->extgstates = array();
$this->mb_enc='windows-1252';
$this->directionality='ltr';
$this->defaultAlign = 'L';
$this->defaultTableAlign = 'L';
$this->fixedPosBlockSave = array();
$this->extraFontSubsets = 0;
$this->SHYpatterns = array();
$this->loadedSHYdictionary = false;
$this->SHYdictionary = array();
$this->SHYdictionaryWords = array();
$this->blockContext = 1;
$this->floatDivs = array();
$this->DisplayPreferences='';
$this->tablecascadeCSS = array();
$this->listcascadeCSS = array();
$this->patterns = array(); // Tiling patterns used for backgrounds
$this->pageBackgrounds = array();
$this->writingHTMLheader = false; // internal flag - used both for writing HTMLHeaders/Footers and FixedPos block
$this->writingHTMLfooter = false; // internal flag - used both for writing HTMLHeaders/Footers and FixedPos block
$this->gradients = array();
$this->kwt_Reference = array();
$this->kwt_BMoutlines = array();
$this->kwt_toc = array();
$this->tbrot_Reference = array();
$this->tbrot_BMoutlines = array();
$this->tbrot_toc = array();
$this->col_Reference = array();
$this->col_BMoutlines = array();
$this->col_toc = array();
$this->graphs = array();
$this->pgsIns = array();
$this->PDFAwarnings = array();
$this->inlineDisplayOff = false; // mPDF 5.0
$this->baselineC = 0.35; // Baseline for text
$this->noImageFile = str_replace("\\","/",dirname(__FILE__)) . '/includes/no_image.jpg';
$this->subPos = 0;
$this->forceExactLineheight = false;
$this->listOcc = 0;
$this->normalLineheight = 1.3;
// These are intended as configuration variables, and should be set in config.php - which will override these values;
// set here as failsafe as will cause an error if not defined
$this->incrementFPR1 = 10;
$this->incrementFPR2 = 10;
$this->incrementFPR3 = 10;
$this->incrementFPR4 = 10;
$this->fullImageHeight = false;
$this->floatbuffer = array();
$this->floatmargins = array();
$this->autoFontGroups = 0;
$this->formobjects=array(); // array of Form Objects for WMF
$this->InlineProperties=array();
$this->InlineAnnots=array();
$this->ktAnnots=array();
$this->tbrot_Annots=array();
$this->kwt_Annots=array();
$this->columnAnnots=array();
$this->pageDim=array();
$this->breakpoints = array(); // used in columnbuffer
$this->tableLevel=0;
$this->tbctr=array(); // counter for nested tables at each level
$this->page_box = array();
$this->show_marks = ''; // crop or cross marks
$this->kwt = false;
$this->kwt_height = 0;
$this->kwt_y0 = 0;
$this->kwt_x0 = 0;
$this->kwt_buffer = array();
$this->kwt_Links = array();
$this->kwt_moved = false;
$this->kwt_saved = false;
$this->PageNumSubstitutions = array();
$this->base_table_properties=array();
$this->borderstyles = array('inset','groove','outset','ridge','dotted','dashed','solid','double');
$this->tbrot_align = 'C';
$this->pageheaders=array();
$this->pagefooters=array();
$this->pageHTMLheaders=array();
$this->pageHTMLfooters=array();
$this->HTMLheaderPageLinks = array();
$this->HTMLheaderPageAnnots = array(); // mPDF 5.0
$this->cascadeCSS = array();
$this->bufferoutput = false;
$this->encrypted=false; //whether document is protected
$this->BMoutlines=array();
$this->_toc=array();
$this->TOCheader=false;
$this->TOCfooter=false;
$this->ColActive=0; //Flag indicating that columns are on (the index is being processed)
$this->ChangePage=0; //Flag indicating that a page break has occurred
$this->Reference=array(); //Array containing the references
$this->CurrCol=0; //Current column number
$this->ColL = array(0); // Array of Left pos of columns - absolute - needs Margin correction for Odd-Even
$this->ColR = array(0); // Array of Right pos of columns - absolute pos - needs Margin correction for Odd-Even
$this->ChangeColumn = 0;
$this->columnbuffer = array();
$this->ColDetails = array(); // Keeps track of some column details
$this->columnLinks = array(); // Cross references PageLinks
$this->substitute = array(); // Array of substitution strings e.g. 112
$this->entsearch = array(); // Array of HTML entities (>ASCII 127) to substitute
$this->entsubstitute = array(); // Array of substitution decimal unicode for the Hi entities
$this->lastoptionaltag = '';
$this->charset_in = '';
$this->blk = array();
$this->blklvl = 0;
$this->TOCmark = 0;
$this->tts = false;
$this->ttz = false;
$this->tta = false;
$this->ispre=false;
$this->checkSIP = false; // mPDF 5.0
$this->checkSMP = false; // mPDF 5.0.03
$this->checkCJK = false; // mPDF 5.0
$this->tableCJK = false; // mPDF 5.0
$this->headerDetails=array();
$this->footerDetails=array();
$this->div_bottom_border = '';
$this->p_bottom_border = '';
$this->page_break_after_avoid = false;
$this->margin_bottom_collapse = false;
$this->tablethead = 0;
$this->tabletfoot = 0;
$this->table_border_attr_set = 0;
$this->table_border_css_set = 0;
$this->shrin_k = 1.0;
$this->shrink_this_table_to_fit = 0;
$this->MarginCorrection = 0;
$this->tabletheadjustfinished = false;
$this->usingCoreFont = false;
$this->charspacing=0;
$this->outlines=array();
$this->autoPageBreak = true;
require(_MPDF_PATH.'config.php'); // config data
//Scale factor
$this->k=72/25.4; // Will only use mm
$this->_setPageSize($format, $orientation);
$this->DefOrientation=$orientation;
$this->margin_header=$mgh;
$this->margin_footer=$mgf;
$bmargin=$mgb;
$this->DeflMargin = $mgl;
$this->DefrMargin = $mgr;
// v1.4 Save orginal settings in case of changed orientation
$this->orig_tMargin = $mgt;
$this->orig_bMargin = $bmargin;
$this->orig_lMargin = $this->DeflMargin;
$this->orig_rMargin = $this->DefrMargin;
$this->orig_hMargin = $this->margin_header;
$this->orig_fMargin = $this->margin_footer;
if ($this->setAutoTopMargin=='pad') { $mgt += $this->margin_header; }
if ($this->setAutoBottomMargin=='pad') { $mgb += $this->margin_footer; }
$this->SetMargins($this->DeflMargin,$this->DefrMargin,$mgt); // sets l r t margin
//Automatic page break
$this->SetAutoPageBreak($this->autoPageBreak,$bmargin); // sets $this->bMargin & PageBreakTrigger
$this->pgwidth = $this->w - $this->lMargin - $this->rMargin;
//Interior cell margin (1 mm) ? not used
$this->cMarginL = 1;
$this->cMarginR = 1;
//Line width (0.2 mm)
$this->LineWidth=.567/$this->k;
//To make the function Footer() work - replaces {nb} with page number
$this->AliasNbPages();
$this->AliasNbPageGroups();
// mPDF 5.0.04
$this->aliasNbPgHex = '{nbHEXmarker}';
$this->aliasNbPgGpHex = '{nbpgHEXmarker}';
//Enable all tags as default
$this->DisableTags();
//Full width display mode
$this->SetDisplayMode(100); // fullwidth? 'fullpage'
//Compression
$this->SetCompression(true);
//Set default display preferences
$this->SetDisplayPreferences('');
// Font data
require(_MPDF_PATH.'config_fonts.php');
// Available fonts
$this->available_unifonts = array();
foreach ($this->fontdata AS $f => $fs) {
if (isset($fs['R']) && $fs['R']) { $this->available_unifonts[] = $f; }
if (isset($fs['B']) && $fs['B']) { $this->available_unifonts[] = $f.'B'; }
if (isset($fs['I']) && $fs['I']) { $this->available_unifonts[] = $f.'I'; }
if (isset($fs['BI']) && $fs['BI']) { $this->available_unifonts[] = $f.'BI'; }
}
$this->default_available_fonts = $this->available_unifonts;
$optcore = false;
$onlyCoreFonts = false;
// mPDF 5.0
if (preg_match('/([\-+])aCJK/i',$mode, $m)) {
preg_replace('/([\-+])aCJK/i','',$mode);
if ($m[1]=='+') { $this->useAdobeCJK = true; }
else { $this->useAdobeCJK = false; }
}
if (strlen($mode)==1) {
if ($mode=='s') { $this->percentSubset = 100; $mode = ''; }
else if ($mode=='c') { $onlyCoreFonts = true; $mode = ''; }
}
else if (substr($mode,-2)=='-s') {
$this->percentSubset = 100;
$mode = substr($mode,0,strlen($mode)-2);
}
else if (substr($mode,-2)=='-c') {
$onlyCoreFonts = true;
$mode = substr($mode,0,strlen($mode)-2);
}
else if (substr($mode,-2)=='-x') {
$optcore = true;
$mode = substr($mode,0,strlen($mode)-2);
}
// Autodetect if mode is a language_country string (en-GB or en_GB or en)
if ((strlen($mode) == 5 && $mode != 'UTF-8') || strlen($mode) == 2) {
list ($coreSuitable,$mpdf_pdf_unifonts,$mpdf_directionality,$mpdf_jSpacing) = GetLangOpts($mode, $this->useAdobeCJK);
if ($coreSuitable && $optcore) { $onlyCoreFonts = true; }
$this->jSpacing = $mpdf_jSpacing;
if ($mpdf_pdf_unifonts) {
$this->RestrictUnicodeFonts($mpdf_pdf_unifonts);
$this->default_available_fonts = $mpdf_pdf_unifonts;
}
$this->SetDirectionality($mpdf_directionality);
$this->currentLang = $mode;
$this->default_lang = $mode;
$this->default_jSpacing = $mpdf_jSpacing;
$this->default_dir = $mpdf_directionality;
}
$this->onlyCoreFonts = $onlyCoreFonts;
if ($this->onlyCoreFonts) {
$this->setMBencoding('windows-1252'); // sets $this->mb_enc
}
else {
$this->setMBencoding('UTF-8'); // sets $this->mb_enc
}
@mb_regex_encoding('UTF-8');
// mPDF 5.0 Adobe CJK fonts
//if ($this->useAdobeCJK) {
$this->available_CJK_fonts = array('gb','big5','sjis','uhc','gbB','big5B','sjisB','uhcB','gbI','big5I','sjisI','uhcI',
'gbBI','big5BI','sjisBI','uhcBI');
//}
//else { $this->available_CJK_fonts = array(); }
//Standard fonts
$this->CoreFonts=array('ccourier'=>'Courier','ccourierB'=>'Courier-Bold','ccourierI'=>'Courier-Oblique','ccourierBI'=>'Courier-BoldOblique',
'chelvetica'=>'Helvetica','chelveticaB'=>'Helvetica-Bold','chelveticaI'=>'Helvetica-Oblique','chelveticaBI'=>'Helvetica-BoldOblique',
'ctimes'=>'Times-Roman','ctimesB'=>'Times-Bold','ctimesI'=>'Times-Italic','ctimesBI'=>'Times-BoldItalic',
'csymbol'=>'Symbol','czapfdingbats'=>'ZapfDingbats');
$this->fontlist=array("ctimes","ccourier","chelvetica","csymbol","czapfdingbats");
// Substitutions
$this->setHiEntitySubstitutions();
if ($this->onlyCoreFonts) {
$this->useSubstitutions = true;
$this->SetSubstitutions();
}
else { $this->useSubstitutions = false; }
if (file_exists(_MPDF_PATH.'mpdf.css')) {
$css = file_get_contents(_MPDF_PATH.'mpdf.css');
$css2 = $this->ReadDefaultCSS($css);
$this->defaultCSS = $this->array_merge_recursive_unique($this->defaultCSS,$css2);
}
if ($default_font=='') {
if ($this->onlyCoreFonts) {
if (in_array(strtolower($this->defaultCSS['BODY']['FONT-FAMILY']),$this->mono_fonts)) { $default_font = 'ccourier'; }
else if (in_array(strtolower($this->defaultCSS['BODY']['FONT-FAMILY']),$this->sans_fonts)) { $default_font = 'chelvetica'; }
else { $default_font = 'ctimes'; }
}
else { $default_font = $this->defaultCSS['BODY']['FONT-FAMILY']; }
}
if (!$default_font_size) {
$mmsize = $this->ConvertSize($this->defaultCSS['BODY']['FONT-SIZE']);
$default_font_size = $mmsize*($this->k);
}
if ($default_font) { $this->SetDefaultFont($default_font); }
if ($default_font_size) { $this->SetDefaultFontSize($default_font_size); }
$this->SetLineHeight(); // lineheight is in mm
$this->SetFillColor(255);
$this->HREF='';
$this->oldy=-1;
$this->B=0;
$this->U=0;
$this->S=0; // mPDF 5.0
$this->I=0;
$this->listlvl=0;
$this->listnum=0;
$this->listtype='';
$this->listoccur=array();
$this->listlist=array();
$this->listitem=array();
$this->tdbegin=false;
$this->table=array();
$this->cell=array();
$this->col=-1;
$this->row=-1;
$this->cellBorderBuffer = array();
$this->divbegin=false;
$this->divalign=$this->defaultAlign;
$this->divwidth=0;
$this->divheight=0;
$this->spanbgcolor=false;
$this->divrevert=false;
$this->issetfont=false;
$this->issetcolor=false;
$this->blockjustfinished=false;
$this->listjustfinished=false;
$this->ignorefollowingspaces = true; //in order to eliminate exceeding left-side spaces
$this->toupper=false;
$this->tolower=false;
$this->dash_on=false;
$this->dotted_on=false;
$this->SUP=false;
$this->SUB=false;
$this->strike=false;
$this->currentfontfamily='';
$this->currentfontsize='';
$this->currentfontstyle='';
$this->colorarray=array();
$this->spanbgcolorarray=array();
$this->textbuffer=array();
$this->CSS=array();
$this->internallink=array();
$this->basepath = "";
$this->SetBasePath('');
$this->outlineparam = array();
$this->outline_on = false;
$this->specialcontent = '';
$this->selectoption = array();
$this->usetableheader=false;
$this->usecss=true;
$this->usepre=true;
for($i=0;$i<256;$i++) {
$this->chrs[$i] = chr($i);
$this->ords[chr($i)] = $i;
}
if ($this->progressBar) { $this->StartProgressBarOutput($this->progressBar) ; }
}
function _setPageSize($format, &$orientation) {
//Page format
if(is_string($format))
{
if ($format=='') { $format = 'A4'; }
$pfo = 'P';
if(preg_match('/([0-9a-zA-Z]*)-L/i',$format,$m)) { // e.g. A4-L = A$ landscape
$format=$m[1];
$pfo='L';
}
$format = $this->_getPageFormat($format);
if (!$format) { $this->Error('Unknown page format: '.$format); }
else { $orientation = $pfo; }
$this->fwPt=$format[0];
$this->fhPt=$format[1];
}
else
{
if (!$format[0] || !$format[1]) { $this->Error('Invalid page format: '.$format[0].' '.$format[1]); }
$this->fwPt=$format[0]*$this->k;
$this->fhPt=$format[1]*$this->k;
}
$this->fw=$this->fwPt/$this->k;
$this->fh=$this->fhPt/$this->k;
//Page orientation
$orientation=strtolower($orientation);
if($orientation=='p' or $orientation=='portrait')
{
$orientation='P';
$this->wPt=$this->fwPt;
$this->hPt=$this->fhPt;
}
elseif($orientation=='l' or $orientation=='landscape')
{
$orientation='L';
$this->wPt=$this->fhPt;
$this->hPt=$this->fwPt;
}
else $this->Error('Incorrect orientation: '.$orientation);
$this->CurOrientation=$orientation;
$this->w=$this->wPt/$this->k;
$this->h=$this->hPt/$this->k;
}
function _getPageFormat($format) {
switch (strtoupper($format)) {
case '4A0': {$format = array(4767.87,6740.79); break;}
case '2A0': {$format = array(3370.39,4767.87); break;}
case 'A0': {$format = array(2383.94,3370.39); break;}
case 'A1': {$format = array(1683.78,2383.94); break;}
case 'A2': {$format = array(1190.55,1683.78); break;}
case 'A3': {$format = array(841.89,1190.55); break;}
case 'A4': default: {$format = array(595.28,841.89); break;}
case 'A5': {$format = array(419.53,595.28); break;}
case 'A6': {$format = array(297.64,419.53); break;}
case 'A7': {$format = array(209.76,297.64); break;}
case 'A8': {$format = array(147.40,209.76); break;}
case 'A9': {$format = array(104.88,147.40); break;}
case 'A10': {$format = array(73.70,104.88); break;}
case 'B0': {$format = array(2834.65,4008.19); break;}
case 'B1': {$format = array(2004.09,2834.65); break;}
case 'B2': {$format = array(1417.32,2004.09); break;}
case 'B3': {$format = array(1000.63,1417.32); break;}
case 'B4': {$format = array(708.66,1000.63); break;}
case 'B5': {$format = array(498.90,708.66); break;}
case 'B6': {$format = array(354.33,498.90); break;}
case 'B7': {$format = array(249.45,354.33); break;}
case 'B8': {$format = array(175.75,249.45); break;}
case 'B9': {$format = array(124.72,175.75); break;}
case 'B10': {$format = array(87.87,124.72); break;}
case 'C0': {$format = array(2599.37,3676.54); break;}
case 'C1': {$format = array(1836.85,2599.37); break;}
case 'C2': {$format = array(1298.27,1836.85); break;}
case 'C3': {$format = array(918.43,1298.27); break;}
case 'C4': {$format = array(649.13,918.43); break;}
case 'C5': {$format = array(459.21,649.13); break;}
case 'C6': {$format = array(323.15,459.21); break;}
case 'C7': {$format = array(229.61,323.15); break;}
case 'C8': {$format = array(161.57,229.61); break;}
case 'C9': {$format = array(113.39,161.57); break;}
case 'C10': {$format = array(79.37,113.39); break;}
case 'RA0': {$format = array(2437.80,3458.27); break;}
case 'RA1': {$format = array(1729.13,2437.80); break;}
case 'RA2': {$format = array(1218.90,1729.13); break;}
case 'RA3': {$format = array(864.57,1218.90); break;}
case 'RA4': {$format = array(609.45,864.57); break;}
case 'SRA0': {$format = array(2551.18,3628.35); break;}
case 'SRA1': {$format = array(1814.17,2551.18); break;}
case 'SRA2': {$format = array(1275.59,1814.17); break;}
case 'SRA3': {$format = array(907.09,1275.59); break;}
case 'SRA4': {$format = array(637.80,907.09); break;}
case 'LETTER': {$format = array(612.00,792.00); break;}
case 'LEGAL': {$format = array(612.00,1008.00); break;}
case 'EXECUTIVE': {$format = array(521.86,756.00); break;}
case 'FOLIO': {$format = array(612.00,936.00); break;}
case 'B': {$format=array(362.83,561.26 ); break;} // 'B' format paperback size 128x198mm
case 'A': {$format=array(314.65,504.57 ); break;} // 'A' format paperback size 111x178mm
case 'DEMY': {$format=array(382.68,612.28 ); break;} // 'Demy' format paperback size 135x216mm
case 'ROYAL': {$format=array(433.70,663.30 ); break;} // 'Royal' format paperback size 153x234mm
default: $format = false;
}
return $format;
}
function StartProgressBarOutput($mode=1) {
// must be relative path, or URI (not a file system path)
if (!defined('_MPDF_URI')) {
$this->progressBar = false;
if ($this->debug) { $this->Error("You need to define _MPDF_URI to use the progress bar!"); }
else return false;
}
$this->progressBar = $mode;
if ($this->progbar_altHTML) {
echo $this->progbar_altHTML;
}
else {
echo '
'.$this->progbar_heading.'
';
if ($this->progressBar==2) { echo '
Writing HTML code
|
Autosizing elements
Writing Tables
|
| |
'; }
echo ' Writing PDF file
';
if ($this->progressBar==2) { echo '
|
Memory usage
0 '.ini_get("memory_limit").'
Memory usage (peak)
0 '.ini_get("memory_limit").'
|
'; }
echo '
';
}
ob_flush();
flush();
}
function UpdateProgressBar($el,$val,$txt='') {
// $val should be a string - 5 = actual value, +15 = increment
if ($this->progressBar<2) {
if ($el>3) { return; }
else if ($el ==1) { $el = 2; }
}
echo ''."\n";
ob_flush();
flush();
}
function RestrictUnicodeFonts($res) {
// $res = array of (Unicode) fonts to restrict to: e.g. norasi|norasiB - language specific
if (count($res)) { // Leave full list of available fonts if passed blank array
$this->available_unifonts = $res;
}
else { $this->available_unifonts = $this->default_available_fonts; }
if (count($this->available_unifonts) == 0) { $this->available_unifonts[] = $this->default_available_fonts[0]; }
$this->available_unifonts = array_values($this->available_unifonts);
}
function setMBencoding($enc) {
@mb_regex_encoding('UTF-8');
$curr = $this->mb_enc;
$this->mb_enc = $enc;
if (!$this->mb_enc || $curr != $this->mb_enc) {
mb_internal_encoding($this->mb_enc);
if ($enc == 'UTF-8') { @mb_regex_encoding('UTF-8'); }
// else if ($enc == 'windows-1252') { @mb_regex_encoding('ISO-8859-1'); }
}
}
function SetMargins($left,$right,$top) {
//Set left, top and right margins
$this->lMargin=$left;
$this->rMargin=$right;
$this->tMargin=$top;
}
function ResetMargins() {
//ReSet left, top margins
if (($this->forcePortraitHeaders || $this->forcePortraitMargins) && $this->DefOrientation=='P' && $this->CurOrientation=='L') {
if (($this->mirrorMargins) && (($this->page)%2==0)) { // EVEN
$this->tMargin=$this->orig_rMargin;
$this->bMargin=$this->orig_lMargin;
}
else { // ODD // OR NOT MIRRORING MARGINS/FOOTERS
$this->tMargin=$this->orig_lMargin;
$this->bMargin=$this->orig_rMargin;
}
$this->lMargin=$this->DeflMargin;
$this->rMargin=$this->DefrMargin;
$this->MarginCorrection = 0;
$this->PageBreakTrigger=$this->h-$this->bMargin;
}
else if (($this->mirrorMargins) && (($this->page)%2==0)) { // EVEN
$this->lMargin=$this->DefrMargin;
$this->rMargin=$this->DeflMargin;
$this->MarginCorrection = $this->DefrMargin-$this->DeflMargin;
}
else { // ODD // OR NOT MIRRORING MARGINS/FOOTERS
$this->lMargin=$this->DeflMargin;
$this->rMargin=$this->DefrMargin;
if ($this->mirrorMargins) { $this->MarginCorrection = $this->DeflMargin-$this->DefrMargin; }
}
$this->x=$this->lMargin;
}
function SetLeftMargin($margin) {
//Set left margin
$this->lMargin=$margin;
if($this->page>0 and $this->x<$margin) $this->x=$margin;
}
function SetTopMargin($margin) {
//Set top margin
$this->tMargin=$margin;
}
function SetRightMargin($margin) {
//Set right margin
$this->rMargin=$margin;
}
function SetAutoPageBreak($auto,$margin=0) {
//Set auto page break mode and triggering margin
$this->autoPageBreak=$auto;
$this->bMargin=$margin;
$this->PageBreakTrigger=$this->h-$margin;
}
function SetDisplayMode($zoom,$layout='continuous') {
//Set display mode in viewer
if($zoom=='fullpage' or $zoom=='fullwidth' or $zoom=='real' or $zoom=='default' or !is_string($zoom))
$this->ZoomMode=$zoom;
else
$this->Error('Incorrect zoom display mode: '.$zoom);
if($layout=='single' or $layout=='continuous' or $layout=='two' or $layout=='default')
$this->LayoutMode=$layout;
else
$this->Error('Incorrect layout display mode: '.$layout);
}
function SetCompression($compress) {
//Set page compression
if(function_exists('gzcompress')) $this->compress=$compress;
else $this->compress=false;
}
function SetTitle($title) {
//Title of document // Arrives as UTF-8
$this->title = $title;
}
function SetSubject($subject) {
//Subject of document
$this->subject= $subject;
}
function SetAuthor($author) {
//Author of document
$this->author= $author;
}
function SetKeywords($keywords) {
//Keywords of document
$this->keywords= $keywords;
}
function SetCreator($creator) {
//Creator of document
$this->creator= $creator;
}
function SetAnchor2Bookmark($x) {
$this->anchor2Bookmark = $x;
}
function AliasNbPages($alias='{nb}') {
//Define an alias for total number of pages
$this->aliasNbPg=$alias;
}
function AliasNbPageGroups($alias='{nbpg}') {
//Define an alias for total number of pages in a group
$this->aliasNbPgGp=$alias;
}
function SetAlpha($alpha, $bm='Normal', $return=false) {
// alpha: real value from 0 (transparent) to 1 (opaque)
// bm: blend mode, one of the following:
// Normal, Multiply, Screen, Overlay, Darken, Lighten, ColorDodge, ColorBurn,
// HardLight, SoftLight, Difference, Exclusion, Hue, Saturation, Color, Luminosity
// set alpha for stroking (CA) and non-stroking (ca) operations
if ($this->PDFA && $alpha!=1) {
if (!$this->PDFAauto) { $this->PDFAwarnings[] = "Image opacity must be 100% (Opacity changed to 100%)"; }
$alpha = 1;
}
$gs = $this->AddExtGState(array('ca'=>$alpha, 'CA'=>$alpha, 'BM'=>'/'.$bm));
if ($return) { return sprintf('/GS%d gs', $gs); }
else { $this->_out(sprintf('/GS%d gs', $gs)); }
}
// mPDF 5.0 - Accepts any Graphic state
function AddExtGState($parms) {
$n = count($this->extgstates);
// check if graphics state already exists
for ($i=1; $i<=$n; $i++) {
if (count($this->extgstates[$i]['parms']) == count($parms)) {
$same = true;
foreach($this->extgstates[$i]['parms'] AS $k=>$v) {
if (!isset($parms[$k]) || $parms[$k] != $v) { $same = false; break; }
}
if ($same) { return $i; }
}
}
$n++;
$this->extgstates[$n]['parms'] = $parms;
return $n;
}
function Error($msg) {
//Fatal error
header('Content-Type: text/html; charset=utf-8');
die('
mPDF error: '.$msg);
}
function Open() {
//Begin document
if($this->state==0) $this->_begindoc();
}
function Close() {
if ($this->progressBar) { $this->UpdateProgressBar(2,'2','Closing last page'); }
//Terminate document
if($this->state==3) return;
if($this->page==0) $this->AddPage($this->CurOrientation);
if (count($this->divbuffer)) { $this->printdivbuffer(); }
// BODY Backgrounds
$s = '';
$bby = $this->h;
$bbw = $this->w;
$bbh = $this->h;
if ($this->bodyBackgroundColor) {
$s .= sprintf('%.3f %.3f %.3f rg',$this->bodyBackgroundColor['R']/255,$this->bodyBackgroundColor['G']/255,$this->bodyBackgroundColor['B']/255)."\n";
$s .= sprintf('%.3f %.3f %.3f %.3f re f',0,$bby*$this->k,$bbw*$this->k,-$bbh*$this->k)."\n";
}
$s .= $this->PrintPageBackgrounds();
$this->pages[$this->page] = preg_replace('/(___BACKGROUND___PATTERNS'.date('jY').')/', "\n".$s."\n".'\\1', $this->pages[$this->page]);
$this->pageBackgrounds = array();
if (!$this->TOCmark) { //Page footer
$this->InFooter=true;
$this->Footer();
$this->InFooter=false;
}
//Close page
$this->_endpage();
//Close document
$this->_enddoc();
}
function _resizeBackgroundImage($imw, $imh, $cw, $ch, $resize=0, $repx, $repy) {
$cw = $cw*$this->k;
$ch = $ch*$this->k;
if (!$resize) { return array($imw, $imh, $repx, $repy); }
if ($resize==1 && $imw > $cw) {
$h = $imh * $cw/$imw;
$repx = false;
return array($cw, $h, $repx, $repy);
}
else if ($resize==2 && $imh > $ch) {
$w = $imw * $ch/$imh;
$repy = false;
return array($w, $ch, $repx, $repy);
}
else if ($resize==3) {
$w = $imw;
$h = $imh;
$saverepx = $repx;
if ($w > $cw) {
$h = $h * $cw/$w;
$w = $cw;
$repx = false;
}
if ($h > $ch) {
$w = $w * $ch/$h;
$h = $ch;
$repy = false;
$repx = $saverepx;
}
return array($w, $h, $repx, $repy);
}
else if ($resize==4) {
$h = $imh * $cw/$imw;
$repx = false;
return array($cw, $h, $repx, $repy);
}
else if ($resize==5) {
$w = $imw * $ch/$imh;
$repy = false;
return array($w, $ch, $repx, $repy);
}
else if ($resize==6) {
$repx = false;
$repy = false;
return array($cw, $ch, $repx, $repy);
}
return array($imw, $imh, $repx, $repy);
}
function PrintPageBackgrounds($adjustmenty=0) {
$s = '';
ksort($this->pageBackgrounds);
foreach($this->pageBackgrounds AS $bl=>$pbs) {
foreach ($pbs AS $pb) {
if (!isset($pb['image_id']) && !isset($pb['gradient'])) { // Background colour
if (isset($pb['clippath']) && $pb['clippath']) { $s .= $pb['clippath']."\n"; }
$s .= sprintf('%.3f %.3f %.3f rg',$pb['col']['R']/255,$pb['col']['G']/255,$pb['col']['B']/255)."\n";
$s .= sprintf('%.3f %.3f %.3f %.3f re f',$pb['x']*$this->k,($this->h-$pb['y'])*$this->k,$pb['w']*$this->k,-$pb['h']*$this->k)."\n";
if (isset($pb['clippath']) && $pb['clippath']) { $s .= 'Q'."\n"; }
}
}
}
return $s;
}
// Depracated - can use AddPage for all
function AddPages($orientation='',$condition='', $resetpagenum='', $pagenumstyle='', $suppress='',$mgl='',$mgr='',$mgt='',$mgb='',$mgh='',$mgf='',$ohname='',$ehname='',$ofname='',$efname='',$ohvalue=0,$ehvalue=0,$ofvalue=0,$efvalue=0,$pagesel='',$newformat='')
{
$this->AddPage($orientation,$condition,$resetpagenum, $pagenumstyle, $suppress,$mgl,$mgr,$mgt,$mgb,$mgh,$mgf, $ohname, $ehname, $ofname, $efname, $ohvalue, $ehvalue, $ofvalue, $efvalue,$pagesel,$newformat);
}
function AddPageByArray($a) {
if (!is_array($a)) { $a = array(); }
$orientation = (isset($a['orientation']) ? $a['orientation'] : '');
$condition = (isset($a['condition']) ? $a['condition'] : '');
$resetpagenum = (isset($a['resetpagenum']) ? $a['resetpagenum'] : '');
$pagenumstyle = (isset($a['pagenumstyle']) ? $a['pagenumstyle'] : '');
$suppress = (isset($a['suppress']) ? $a['suppress'] : '');
$mgl = (isset($a['mgl']) ? $a['mgl'] : '');
$mgr = (isset($a['mgr']) ? $a['mgr'] : '');
$mgt = (isset($a['mgt']) ? $a['mgt'] : '');
$mgb = (isset($a['mgb']) ? $a['mgb'] : '');
$mgh = (isset($a['mgh']) ? $a['mgh'] : '');
$mgf = (isset($a['mgf']) ? $a['mgf'] : '');
$ohname = (isset($a['ohname']) ? $a['ohname'] : '');
$ehname = (isset($a['ehname']) ? $a['ehname'] : '');
$ofname = (isset($a['ofname']) ? $a['ofname'] : '');
$efname = (isset($a['efname']) ? $a['efname'] : '');
$ohvalue = (isset($a['ohvalue']) ? $a['ohvalue'] : 0);
$ehvalue = (isset($a['ehvalue']) ? $a['ehvalue'] : 0);
$ofvalue = (isset($a['ofvalue']) ? $a['ofvalue'] : 0);
$efvalue = (isset($a['efvalue']) ? $a['efvalue'] : 0);
$pagesel = (isset($a['pagesel']) ? $a['pagesel'] : '');
$newformat = (isset($a['newformat']) ? $a['newformat'] : '');
$this->AddPage($orientation,$condition,$resetpagenum, $pagenumstyle, $suppress,$mgl,$mgr,$mgt,$mgb,$mgh,$mgf, $ohname, $ehname, $ofname, $efname, $ohvalue, $ehvalue, $ofvalue, $efvalue,$pagesel,$newformat);
}
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='')
{
//Start a new page
if($this->state==0) $this->Open();
$bak_cml = $this->cMarginL;
$bak_cmr = $this->cMarginR;
$bak_dw = $this->divwidth;
$bak_lh = $this->lineheight;
$orientation = substr(strtoupper($orientation),0,1);
$condition = strtoupper($condition);
if ($condition == 'NEXT-EVEN') { // always adds at least one new page to create an Even page
if (!$this->mirrorMargins) { $condition = ''; }
else {
$this->AddPage($this->CurOrientation,'O');
$condition = '';
}
}
if ($condition == 'NEXT-ODD') { // always adds at least one new page to create an Odd page
if (!$this->mirrorMargins) { $condition = ''; }
else {
$this->AddPage($this->CurOrientation,'E');
$condition = '';
}
}
if ($condition == 'E') { // only adds new page if needed to create an Even page
if (!$this->mirrorMargins || ($this->page)%2==0) { return false; }
}
if ($condition == 'O') { // only adds new page if needed to create an Odd page
if (!$this->mirrorMargins || ($this->page)%2==1) { return false; }
}
if ($resetpagenum || $pagenumstyle || $suppress) {
$this->PageNumSubstitutions[] = array('from'=>($this->page+1), 'reset'=> $resetpagenum, 'type'=>$pagenumstyle, 'suppress'=>$suppress);
}
$save_kwt = $this->kwt;
$this->kwt = 0;
// Paint Div Border if necessary
//PAINTS BACKGROUND COLOUR OR BORDERS for DIV - DISABLED FOR COLUMNS (cf. AcceptPageBreak) AT PRESENT in ->PaintDivBB
if (!$this->ColActive && $this->blklvl > 0) {
if (isset($this->blk[$this->blklvl]['y0']) && $this->y == $this->blk[$this->blklvl]['y0']) {
if (isset($this->blk[$this->blklvl]['startpage'])) { $this->blk[$this->blklvl]['startpage']++; }
else { $this->blk[$this->blklvl]['startpage'] = 1; }
}
if ((isset($this->blk[$this->blklvl]['y0']) && $this->y > $this->blk[$this->blklvl]['y0']) || $this->flowingBlockAttr['is_table'] ) { $toplvl = $this->blklvl; }
else { $toplvl = $this->blklvl-1; }
$sy = $this->y;
for ($bl=1;$bl<=$toplvl;$bl++) {
$this->PaintDivBB('pagebottom',0,$bl);
}
$this->y = $sy;
// RESET block y0 and x0 - see below
}
// BODY Backgrounds
if ($this->page > 0) {
$s = '';
$bby = $this->h;
$bbw = $this->w;
$bbh = $this->h;
if ($this->bodyBackgroundColor) {
$s .= sprintf('%.3f %.3f %.3f rg',$this->bodyBackgroundColor['R']/255,$this->bodyBackgroundColor['G']/255,$this->bodyBackgroundColor['B']/255)."\n";
$s .= sprintf('%.3f %.3f %.3f %.3f re f',0,$bby*$this->k,$bbw*$this->k,-$bbh*$this->k)."\n";
}
$s .= $this->PrintPageBackgrounds();
$this->pages[$this->page] = preg_replace('/(___BACKGROUND___PATTERNS'.date('jY').')/', "\n".$s."\n".'\\1', $this->pages[$this->page]);
$this->pageBackgrounds = array();
}
$save_kt = $this->keep_block_together; // mPDF 5.0
$this->keep_block_together = 0;
$save_cols = false;
$family=$this->FontFamily;
$style=$this->FontStyle.($this->U ? 'U' : '').($this->S ? 'S' : '');
$size=$this->FontSizePt;
$this->ColumnAdjust = true; // enables column height adjustment for the page
$lw=$this->LineWidth;
$dc=$this->DrawColor;
$fc=$this->FillColor;
$tc=$this->TextColor;
$cf=$this->ColorFlag;
if($this->page>0)
{
//Page footer
$this->InFooter=true;
$this->Reset();
$this->pageoutput[$this->page] = array();
$this->Footer();
//Close page
$this->_endpage();
}
//Start new page
$this->_beginpage($orientation,$mgl,$mgr,$mgt,$mgb,$mgh,$mgf,$ohname,$ehname,$ofname,$efname,$ohvalue,$ehvalue,$ofvalue,$efvalue,$pagesel,$newformat);
if ($this->docTemplate) {
$pagecount = $this->SetSourceFile($this->docTemplate);
if (($this->page - $this->docTemplateStart) > $pagecount) {
if ($this->docTemplateContinue) {
$tplIdx = $this->ImportPage($pagecount);
$this->UseTemplate($tplIdx);
}
}
else {
$tplIdx = $this->ImportPage(($this->page - $this->docTemplateStart));
$this->UseTemplate($tplIdx);
}
}
if ($this->pageTemplate) {
$this->UseTemplate($this->pageTemplate);
}
// Tiling Patterns // Moved here mPDF 4.0
$this->_out('___PAGE___START'.date('jY')); // mPDF 5.0
$this->_out('___BACKGROUND___PATTERNS'.date('jY'));
$this->_out('___HEADER___MARKER'.date('jY'));
$this->pageBackgrounds = array();
//Set line cap style to square
$this->_out('2 J');
//Set line width
$this->LineWidth=$lw;
$this->_out(sprintf('%.3f w',$lw*$this->k));
//Set font
if($family) $this->SetFont($family,$style,$size,true,true); // forces write
//Set colors
$this->DrawColor=$dc;
if($dc!='0 G') $this->_out($dc);
$this->FillColor=$fc;
if($fc!='0 g') $this->_out($fc);
$this->TextColor=$tc;
$this->ColorFlag=$cf;
//Page header
$this->Header();
//Restore line width
if($this->LineWidth!=$lw)
{
$this->LineWidth=$lw;
$this->_out(sprintf('%.3f w',$lw*$this->k));
}
//Restore font
if($family) $this->SetFont($family,$style,$size,true,true); // forces write
//Restore colors
if($this->DrawColor!=$dc)
{
$this->DrawColor=$dc;
$this->_out($dc);
}
if($this->FillColor!=$fc)
{
$this->FillColor=$fc;
$this->_out($fc);
}
$this->TextColor=$tc;
$this->ColorFlag=$cf;
$this->InFooter=false;
//RESET BLOCK BORDER TOP
if (!$this->ColActive) {
for($bl=1;$bl<=$this->blklvl;$bl++) {
$this->blk[$bl]['y0'] = $this->y;
if (isset($this->blk[$bl]['x0'])) { $this->blk[$bl]['x0'] += $this->MarginCorrection; }
else { $this->blk[$bl]['x0'] = $this->MarginCorrection; }
// Added mPDF 3.0 Float DIV
$this->blk[$bl]['marginCorrected'][$this->page] = true;
}
}
$this->kwt = $save_kwt;
$this->keep_block_together = $save_kt ; // mPDF 5.0
$this->cMarginL = $bak_cml;
$this->cMarginR = $bak_cmr;
$this->divwidth = $bak_dw;
$this->lineheight = $bak_lh;
}
function PageNo() {
//Get current page number
return $this->page;
}
function SetDrawColor($r,$g=-1,$b=-1,$col4=-1) {
//Set color for all stroking operations
if(($r==0 and $g==0 and $b==0 && $col4 == -1) or $g==-1) $this->DrawColor=sprintf('%.3f G',$r/255);
else if ($col4 == -1) $this->DrawColor=sprintf('%.3f %.3f %.3f RG',$r/255,$g/255,$b/255);
else {
// CMYK
if ($this->PDFA) { $this->Error("PDFA1-b does not permit CMYK colours (fn. SetDrawColor)."); }
$this->DrawColor = sprintf('%.3f %.3f %.3f %.3f K', $r/100, $g/100, $b/100, $col4/100);
}
if($this->page>0 && ((isset($this->pageoutput[$this->page]['DrawColor']) && $this->pageoutput[$this->page]['DrawColor'] != $this->DrawColor) || !isset($this->pageoutput[$this->page]['DrawColor']) || $this->keep_block_together)) { $this->_out($this->DrawColor); }
$this->pageoutput[$this->page]['DrawColor'] = $this->DrawColor;
}
function SetFillColor($r,$g=-1,$b=-1,$col4=-1) {
//Set color for all filling operations
if(($r==0 and $g==0 and $b==0 && $col4 == -1) or $g==-1) $this->FillColor=sprintf('%.3f g',$r/255);
else if ($col4 == -1) $this->FillColor=sprintf('%.3f %.3f %.3f rg',$r/255,$g/255,$b/255);
else {
// CMYK
if ($this->PDFA) { $this->Error("PDFA1-b does not permit CMYK colours (fn. SetFillColor)."); }
$this->FillColor = sprintf('%.3f %.3f %.3f %.3f k', $r/100, $g/100, $b/100, $col4/100);
}
$this->ColorFlag = ($this->FillColor != $this->TextColor);
if($this->page>0 && ((isset($this->pageoutput[$this->page]['FillColor']) && $this->pageoutput[$this->page]['FillColor'] != $this->FillColor) || !isset($this->pageoutput[$this->page]['FillColor']) || $this->keep_block_together)) { $this->_out($this->FillColor); }
$this->pageoutput[$this->page]['FillColor'] = $this->FillColor;
}
function SetTextColor($r,$g=-1,$b=-1,$col4=-1) {
//Set color for text
if(($r==0 and $g==0 and $b==0 && $col4 == -1) or $g==-1) $this->TextColor=sprintf('%.3f g',$r/255);
else if ($col4 == -1) $this->TextColor=sprintf('%.3f %.3f %.3f rg',$r/255,$g/255,$b/255);
else {
// CMYK
if ($this->PDFA) { $this->Error("PDFA1-b does not permit CMYK colours (fn. SetTextColor)."); }
$this->TextColor = sprintf('%.3f %.3f %.3f %.3f k', $r/100, $g/100, $b/100, $col4/100);
}
$this->ColorFlag = ($this->FillColor != $this->TextColor);
}
// mPDF 5.0
function _getCharWidth(&$cw, $u, $isdef=true) {
if ($u==0) { $w = false; }
else { $w = (ord($cw[$u*2]) << 8) + ord($cw[$u*2+1]); }
if ($w == 65535) { return 0; }
else if ($w) { return $w; }
else if ($isdef) { return false; }
else { return 0; }
}
// mPDF 5.0
function _charDefined(&$cw, $u) {
if ($u==0) { return false; }
$w = (ord($cw[$u*2]) << 8) + ord($cw[$u*2+1]);
if ($w) { return true; }
else { return false; }
}
function GetStringWidth($s) {
//Get width of a string in the current font
$s = (string)$s;
$cw = &$this->CurrentFont['cw'];
$w = 0;
// mPDF ITERATION
if ($this->iterationCounter) $s = preg_replace('/{iteration ([a-zA-Z0-9_]+)}/', '\\1', $s);
if (!$this->usingCoreFont) {
$unicode = $this->UTF8StringToArray($s);
if ($this->CurrentFont['type'] == 'Type0') { // CJK Adobe fonts
foreach($unicode as $char) {
if ($char == 173) { continue; } // Soft Hyphens
elseif (isset($cw[$char])) { $w+=$cw[$char]; }
elseif(isset($this->CurrentFont['MissingWidth'])) { $w += $this->CurrentFont['MissingWidth']; }
else { $w += 500; }
}
}
else {
foreach($unicode as $char) {
if ($char == 173) { continue; } // Soft Hyphens
else if ($this->S && isset($this->upperCase[$char])) {
$charw = $this->_getCharWidth($cw,$this->upperCase[$char]);
if ($charw!==false) {
$charw = $charw*$this->smCapsScale * $this->smCapsStretch/100;
$w+=$charw;
}
elseif(isset($this->CurrentFont['desc']['MissingWidth'])) { $w += $this->CurrentFont['desc']['MissingWidth']; }
elseif(isset($this->CurrentFont['MissingWidth'])) { $w += $this->CurrentFont['MissingWidth']; }
else { $w += 500; }
}
else {
$charw = $this->_getCharWidth($cw,$char);
if ($charw!==false) { $w+=$charw; } // mPDF 5.0
elseif(isset($this->CurrentFont['desc']['MissingWidth'])) { $w += $this->CurrentFont['desc']['MissingWidth']; }
elseif(isset($this->CurrentFont['MissingWidth'])) { $w += $this->CurrentFont['MissingWidth']; }
else { $w += 500; }
}
}
}
}
else {
$l = strlen($s);
for($i=0; $i<$l; $i++) {
// Soft Hyphens chr(173)
if ($s[$i] == chr(173) && $this->FontFamily!='csymbol' && $this->FontFamily!='czapfdingbats') {
continue;
}
else if ($this->S && isset($this->upperCase[ord($s[$i])])) {
$charw = $cw[chr($this->upperCase[ord($s[$i])])];
if ($charw!==false) {
$charw = $charw*$this->smCapsScale * $this->smCapsStretch/100;
$w+=$charw;
}
}
else if (isset($cw[$s[$i]])) { $w += $cw[$s[$i]]; }
else if (isset($cw[ord($s[$i])])) { $w += $cw[ord($s[$i])]; }
}
}
unset($cw);
return ($w * $this->FontSize/ 1000);
}
function SetLineWidth($width) {
//Set line width
$this->LineWidth=$width;
$lwout = (sprintf('%.3f w',$width*$this->k));
if($this->page>0 && ((isset($this->pageoutput[$this->page]['LineWidth']) && $this->pageoutput[$this->page]['LineWidth'] != $lwout) || !isset($this->pageoutput[$this->page]['LineWidth']) || $this->keep_block_together)) {
$this->_out($lwout);
}
$this->pageoutput[$this->page]['LineWidth'] = $lwout;
}
function Line($x1,$y1,$x2,$y2) {
//Draw a line
$this->_out(sprintf('%.3f %.3f m %.3f %.3f l S',$x1*$this->k,($this->h-$y1)*$this->k,$x2*$this->k,($this->h-$y2)*$this->k));
}
function Arrow($x1,$y1,$x2,$y2,$headsize=3,$fill='B',$angle=25) {
//F == fill //S == stroke //B == stroke and fill
// angle = splay of arrowhead - 1 - 89 degrees
if($fill=='F') $fill='f';
elseif($fill=='FD' or $fill=='DF' or $fill=='B') $fill='B';
else $fill='S';
$a = atan2(($y2-$y1),($x2-$x1));
$b = $a + deg2rad($angle);
$c = $a - deg2rad($angle);
$x3 = $x2 - ($headsize* cos($b));
$y3 = $this->h-($y2 - ($headsize* sin($b)));
$x4 = $x2 - ($headsize* cos($c));
$y4 = $this->h-($y2 - ($headsize* sin($c)));
$x5 = $x3-($x3-$x4)/2; // mid point of base of arrowhead - to join arrow line to
$y5 = $y3-($y3-$y4)/2;
$s = '';
$s.=sprintf('%.3f %.3f m %.3f %.3f l S',$x1*$this->k,($this->h-$y1)*$this->k,$x5*$this->k,$y5*$this->k);
$this->_out($s);
$s = '';
$s.=sprintf('%.3f %.3f m %.3f %.3f l %.3f %.3f l %.3f %.3f l %.3f %.3f l ',$x5*$this->k,$y5*$this->k,$x3*$this->k,$y3*$this->k,$x2*$this->k,($this->h-$y2)*$this->k,$x4*$this->k,$y4*$this->k,$x5*$this->k,$y5*$this->k);
$s.=$fill;
$this->_out($s);
}
function Rect($x,$y,$w,$h,$style='') {
//Draw a rectangle
if($style=='F') $op='f';
elseif($style=='FD' or $style=='DF') $op='B';
else $op='S';
$this->_out(sprintf('%.3f %.3f %.3f %.3f re %s',$x*$this->k,($this->h-$y)*$this->k,$w*$this->k,-$h*$this->k,$op));
}
function AddFont($family,$style='') { // mPDF 5.0
if(empty($family)) { return; }
$family = strtolower($family);
$style=strtoupper($style);
$style=str_replace('U','',$style);
if($style=='IB') $style='BI';
$fontkey = $family.$style;
// check if the font has been already added
if(isset($this->fonts[$fontkey])) {
return;
}
if (in_array($family,$this->available_CJK_fonts)) {
if (empty($this->Big5_widths)) { require(_MPDF_PATH . 'includes/CJKdata.php'); }
$this->AddCJKFont($family); // don't need to add style
return;
}
if ($this->usingCoreFont) { die("mPDF Error - problem with Font management"); }
$stylekey = $style;
if (!$style) { $stylekey = 'R'; }
if (!isset($this->fontdata[$family][$stylekey]) || !$this->fontdata[$family][$stylekey]) {
die('mPDF Error - Font is not supported - '.$family.' '.$style);
}
$name = '';
$originalsize = 0;
$sip = false;
$smp = false;
$BMPselected = false;
@include(_MPDF_TTFONTDATAPATH.$fontkey.'.mtx.php');
$ttffile = '';
if (defined('_MPDF_SYSTEM_TTFONTS')) {
$ttffile = _MPDF_SYSTEM_TTFONTS.$this->fontdata[$family][$stylekey];
if (!file_exists($ttffile)) { $ttffile = ''; }
}
if (!$ttffile) {
$ttffile = _MPDF_TTFONTPATH.$this->fontdata[$family][$stylekey];
if (!file_exists($ttffile)) { die("mPDF Error - cannot find TTF TrueType font file - ".$ttffile); }
}
$ttfstat = stat($ttffile);
if (isset($this->fontdata[$family]['TTCfontID'][$stylekey])) { $TTCfontID = $this->fontdata[$family]['TTCfontID'][$stylekey]; }
else { $TTCfontID = 0; }
// mPDF 5.0Beta.16
$BMPonly = false;
if (in_array($family,$this->BMPonly)) { $BMPonly = true; }
$regenerate = false;
if ($BMPonly && !$BMPselected) { $regenerate = true; }
else if (!$BMPonly && $BMPselected) { $regenerate = true; }
if (!isset($name) || $originalsize != $ttfstat['size'] || $regenerate) {
$mqr=$this->_getMQR(); // mPDF 5.0
if ($mqr) { set_magic_quotes_runtime(0); }
if (!class_exists('TTFontFile', false)) { include(_MPDF_PATH .'classes/ttfontsuni.php'); }
$ttf = new TTFontFile();
// mPDF 5.0.03
$ttf->getMetrics($ttffile, $TTCfontID, $this->debugfonts, $BMPonly);
$cw = $ttf->charWidths;
$name = preg_replace('/[ ()]/','',$ttf->fullName);
$sip = $ttf->sipset;
$smp = $ttf->smpset;
//$name = $ttf->familyName;
//if (preg_match('/(bold|italic|oblique|heavy)/i',$ttf->styleName)) { $name .= ','.$ttf->styleName; }
//$name = preg_replace('/[()]/','',$name);
//$name = preg_replace('/[ ]/','#20',$name);
$desc= array('Ascent'=>round($ttf->ascent),
'Descent'=>round($ttf->descent),
'CapHeight'=>round($ttf->capHeight),
'Flags'=>$ttf->flags,
'FontBBox'=>'['.round($ttf->bbox[0])." ".round($ttf->bbox[1])." ".round($ttf->bbox[2])." ".round($ttf->bbox[3]).']',
'ItalicAngle'=>$ttf->italicAngle,
'StemV'=>round($ttf->stemV),
'MissingWidth'=>round($ttf->defaultWidth));
$panose = '';
// mPDF 5.0
if (count($ttf->panose)) { $panose = $ttf->sFamilyClass.' '.$ttf->sFamilySubClass.' '.implode(' ',$ttf->panose); }
$up = round($ttf->underlinePosition);
$ut = round($ttf->underlineThickness);
$originalsize = $ttfstat['size']+0;
$type = 'TTF';
//Generate metrics .php file
$s='";
if (is_writable(dirname(_MPDF_TTFONTDATAPATH.'x'))) {
$fh = fopen(_MPDF_TTFONTDATAPATH.$fontkey.'.mtx.php',"w");
fwrite($fh,$s,strlen($s));
fclose($fh);
$fh = fopen(_MPDF_TTFONTDATAPATH.$fontkey.'.cw.dat',"wb");
fwrite($fh,$cw,strlen($cw));
fclose($fh);
@unlink(_MPDF_TTFONTDATAPATH.$fontkey.'.cgm');
@unlink(_MPDF_TTFONTDATAPATH.$fontkey.'.z');
@unlink(_MPDF_TTFONTDATAPATH.$fontkey.'.cw127.php');
@unlink(_MPDF_TTFONTDATAPATH.$fontkey.'.cw');
}
else if ($this->debugfonts) { $this->Error('Cannot write to the font caching directory - '._MPDF_TTFONTDATAPATH); }
unset($ttf);
if ($mqr) { set_magic_quotes_runtime($mqr); }
}
else {
$cw = @file_get_contents(_MPDF_TTFONTDATAPATH.$fontkey.'.cw.dat');
}
if (isset($this->fontdata[$family]['indic']) && $this->fontdata[$family]['indic']) { $indic = true; }
else { $indic = false; }
if (isset($this->fontdata[$family]['sip-ext']) && $this->fontdata[$family]['sip-ext']) { $sipext = $this->fontdata[$family]['sip-ext']; }
else { $sipext = ''; }
$i = count($this->fonts)+$this->extraFontSubsets+1;
if ($sip || $smp) { // mPDF 5.0.03 Added SMP
$this->fonts[$fontkey] = array('i'=>$i, 'type'=>$type, 'name'=>$name, 'desc'=>$desc, 'panose'=>$panose, 'up'=>$up, 'ut'=>$ut, 'cw'=>$cw, 'ttffile'=>$ttffile, 'fontkey'=>$fontkey, 'subsets'=>array(0=>range(0,127)), 'subsetfontids'=>array($i), 'used'=>false, 'indic'=>$indic, 'sip'=>$sip, 'sipext'=>$sipext, 'smp'=>$smp, 'TTCfontID' => $TTCfontID);
}
else {
$this->fonts[$fontkey] = array('i'=>$i, 'type'=>$type, 'name'=>$name, 'desc'=>$desc, 'panose'=>$panose, 'up'=>$up, 'ut'=>$ut, 'cw'=>$cw, 'ttffile'=>$ttffile, 'fontkey'=>$fontkey, 'subset'=>range(0,127), 'used'=>false, 'indic'=>$indic, 'sip'=>$sip, 'sipext'=>$sipext, 'smp'=>$smp, 'TTCfontID' => $TTCfontID );
}
$this->FontFiles[$fontkey]=array('length1'=>$originalsize, 'type'=>"TTF", 'ttffile'=>$ttffile, 'sip'=>$sip, 'smp'=>$smp);
unset($cw);
}
function SetFont($family,$style='',$size=0, $write=true, $forcewrite=false) {
$family=strtolower($family);
if($family=='') {
if ($this->FontFamily) { $family=$this->FontFamily; }
else if ($this->default_font) { $family=$this->default_font; }
else { $this->Error("No font or default font set!"); }
}
$this->ReqFontStyle = $style; // required or requested style - used later for artificial bold/italic
if (($family == 'csymbol') || ($family == 'czapfdingbats') || ($family == 'ctimes') || ($family == 'ccourier') || ($family == 'chelvetica')) {
if ($this->PDFA) {
if ($family == 'csymbol' || $family == 'czapfdingbats') {
$this->Error("Symbol and Zapfdingbats cannot be embedded in mPDF (required for PDFA1-b).");
}
if ($family == 'ctimes' || $family == 'ccourier' || $family == 'chelvetica') {
if (!$this->PDFAauto) { $this->PDFAwarnings[] = "Core Adobe font ".ucfirst($family)." cannot be embedded in mPDF, which is required for PDFA1-b. (Embedded font will be substituted.)"; }
if ($family == 'chelvetica') { $family = 'sans'; }
if ($family == 'ctimes') { $family = 'serif'; }
if ($family == 'ccourier') { $family = 'mono'; }
}
$this->usingCoreFont = false;
}
else { $this->usingCoreFont = true; }
}
else { $this->usingCoreFont = false; }
if($family=='csymbol' or $family=='czapfdingbats') { $style=''; }
$style=strtoupper($style);
if(strpos($style,'U')!==false) {
$this->U=true;
$style=str_replace('U','',$style);
}
else { $this->U=false; }
if(strpos($style,'S')!==false) { // mPDF 5.0
$this->S=true;
$style=str_replace('S','',$style);
}
else { $this->S=false; }
if ($style=='IB') $style='BI';
if ($size==0) $size=$this->FontSizePt;
$fontkey=$family.$style;
$stylekey = $style; // mPDF 5.0
if (!$stylekey) { $stylekey = "R"; }
if (!$this->onlyCoreFonts && !$this->usingCoreFont) {
// CJK fonts
if (in_array($fontkey,$this->available_CJK_fonts)) {
if(!isset($this->fonts[$fontkey])) { // already added
if (empty($this->Big5_widths)) { require(_MPDF_PATH . 'includes/CJKdata.php'); }
$this->AddCJKFont($family); // don't need to add style
}
}
// Test to see if requested font/style is available - or substitute
else if (!in_array($fontkey,$this->available_unifonts)) {
// If font[nostyle] exists - set it
if (in_array($family,$this->available_unifonts)) {
$style = '';
}
// Else if only one font available - set it (assumes if only one font available it will not have a style)
else if (count($this->available_unifonts) == 1) {
$family = $this->available_unifonts[0];
$style = '';
}
else {
$found = 0;
// else substitute font of similar type
if (in_array($family,$this->sans_fonts)) {
$i = array_intersect($this->sans_fonts,$this->available_unifonts);
if (count($i)) {
$i = array_values($i);
// with requested style if possible
if (!in_array(($i[0].$style),$this->available_unifonts)) {
$style = '';
}
$family = $i[0];
$found = 1;
}
}
else if (in_array($family,$this->serif_fonts)) {
$i = array_intersect($this->serif_fonts,$this->available_unifonts);
if (count($i)) {
$i = array_values($i);
// with requested style if possible
if (!in_array(($i[0].$style),$this->available_unifonts)) {
$style = '';
}
$family = $i[0];
$found = 1;
}
}
else if (in_array($family,$this->mono_fonts)) {
$i = array_intersect($this->mono_fonts,$this->available_unifonts);
if (count($i)) {
$i = array_values($i);
// with requested style if possible
if (!in_array(($i[0].$style),$this->available_unifonts)) {
$style = '';
}
$family = $i[0];
$found = 1;
}
}
if (!$found) {
// set first available font
$fs = $this->available_unifonts[0];
preg_match('/^([a-z_0-9\-]+)([BI]{0,2})$/',$fs,$fas); // mPDF 5.0 Allow "-"
// with requested style if possible
$ws = $fas[1].$style;
if (in_array($ws,$this->available_unifonts)) {
$family = $fas[1]; // leave $style as is
}
else if (in_array($fas[1],$this->available_unifonts)) {
// or without style
$family = $fas[1];
$style = '';
}
else {
// or with the style specified
$family = $fas[1];
$style = $fas[2];
}
}
}
$fontkey = $family.$style;
}
// try to add font (if not already added)
$this->AddFont($family, $style);
//Test if font is already selected
if(($this->FontFamily == $family) AND ($this->FontStyle == $style) AND ($this->FontSizePt == $size) && !$forcewrite) {
return $family;
}
$fontkey = $family.$style;
//Select it
$this->FontFamily = $family;
$this->FontStyle = $style;
$this->FontSizePt = $size;
$this->FontSize = $size / $this->k;
$this->CurrentFont = &$this->fonts[$fontkey];
if ($write) {
$fontout = (sprintf('BT /F%d %.3f Tf ET', $this->CurrentFont['i'], $this->FontSizePt));
// Edited mPDF 3.0
if($this->page>0 && ((isset($this->pageoutput[$this->page]['Font']) && $this->pageoutput[$this->page]['Font'] != $fontout) || !isset($this->pageoutput[$this->page]['Font']) || $this->keep_block_together)) { $this->_out($fontout); }
$this->pageoutput[$this->page]['Font'] = $fontout;
}
// Added - currentfont (lowercase) used in HTML2PDF
$this->currentfontfamily=$family;
$this->currentfontsize=$size;
$this->currentfontstyle=$style.($this->U ? 'U' : '').($this->S ? 'S' : '');
$this->setMBencoding('UTF-8');
}
else { // if using core fonts
if ($this->PDFA) {
$this->Error('Core Adobe fonts cannot be embedded in mPDF (required for PDFA1-b) - cannot use option to use core fonts.');
}
$this->setMBencoding('windows-1252');
//Test if font is already selected
if(($this->FontFamily == $family) AND ($this->FontStyle == $style) AND ($this->FontSizePt == $size) && !$forcewrite) {
return $family;
}
if (!isset($this->CoreFonts[$fontkey])) {
if (in_array($family,$this->serif_fonts)) { $family = 'ctimes'; }
else if (in_array($family,$this->mono_fonts)) { $family = 'ccourier'; }
else { $family = 'chelvetica'; }
$this->usingCoreFont = true;
$fontkey = $family.$style;
}
if(!isset($this->fonts[$fontkey])) {
// STANDARD CORE FONTS
if (isset($this->CoreFonts[$fontkey])) {
//Load metric file
$file=$family;
if($family=='ctimes' || $family=='chelvetica' || $family=='ccourier') { $file.=strtolower($style); }
$file.='.php';
include(_MPDF_PATH.'font/'.$file);
if(!isset($cw)) { $this->Error('Could not include font metric file'); }
$i=count($this->fonts)+$this->extraFontSubsets+1;
$this->fonts[$fontkey]=array('i'=>$i,'type'=>'core','name'=>$this->CoreFonts[$fontkey],'desc'=>$desc,'up'=>$up,'ut'=>$ut,'cw'=>$cw);
}
else {
die('mPDF error - Font not defined');
}
}
//Test if font is already selected
if(($this->FontFamily == $family) AND ($this->FontStyle == $style) AND ($this->FontSizePt == $size) && !$forcewrite) {
return $family;
}
//Select it
$this->FontFamily=$family;
$this->FontStyle=$style;
$this->FontSizePt=$size;
$this->FontSize=$size/$this->k;
$this->CurrentFont=&$this->fonts[$fontkey];
if ($write) {
$fontout = (sprintf('BT /F%d %.3f Tf ET', $this->CurrentFont['i'], $this->FontSizePt));
if($this->page>0 && ((isset($this->pageoutput[$this->page]['Font']) && $this->pageoutput[$this->page]['Font'] != $fontout) || !isset($this->pageoutput[$this->page]['Font']) || $this->keep_block_together)) { $this->_out($fontout); }
$this->pageoutput[$this->page]['Font'] = $fontout;
}
// Added - currentfont (lowercase) used in HTML2PDF
$this->currentfontfamily=$family;
$this->currentfontsize=$size;
$this->currentfontstyle=$style.($this->U ? 'U' : '').($this->S ? 'S' : '');
}
return $family;
}
function SetFontSize($size,$write=true) {
//Set font size in points
if($this->FontSizePt==$size) return;
$this->FontSizePt=$size;
$this->FontSize=$size/$this->k;
$this->currentfontsize=$size;
if ($write) {
$fontout = (sprintf('BT /F%d %.3f Tf ET', $this->CurrentFont['i'], $this->FontSizePt));
// Edited mPDF 3.0
if($this->page>0 && ((isset($this->pageoutput[$this->page]['Font']) && $this->pageoutput[$this->page]['Font'] != $fontout) || !isset($this->pageoutput[$this->page]['Font']) || $this->keep_block_together)) { $this->_out($fontout); }
$this->pageoutput[$this->page]['Font'] = $fontout;
}
}
function AddLink() {
//Create a new internal link
$n=count($this->links)+1;
$this->links[$n]=array(0,0);
return $n;
}
function SetLink($link,$y=0,$page=-1) {
//Set destination of internal link
if($y==-1) $y=$this->y;
if($page==-1) $page=$this->page;
$this->links[$link]=array($page,$y);
}
function Link($x,$y,$w,$h,$link) {
if ($this->keep_block_together) { // Save to array - don't write yet
$this->ktLinks[$this->page][]=array($x*$this->k,$this->hPt-$y*$this->k,$w*$this->k,$h*$this->k,$link);
return;
}
else if ($this->kwt) {
$this->kwt_Links[$this->page][]=array($x*$this->k,$this->hPt-$y*$this->k,$w*$this->k,$h*$this->k,$link);
return;
}
if ($this->writingHTMLheader || $this->writingHTMLfooter) {
$this->HTMLheaderPageLinks[]=array($x*$this->k,$this->hPt-$y*$this->k,$w*$this->k,$h*$this->k,$link);
return;
}
//Put a link on the page
$this->PageLinks[$this->page][]=array($x*$this->k,$this->hPt-$y*$this->k,$w*$this->k,$h*$this->k,$link);
// Save cross-reference to Column buffer
}
function Text($x,$y,$txt) {
// Output a string
// Called (internally) by Watermark and _tableWrite [rotated cells]
// Expects input to be mb_encoded if necessary and RTL reversed
// mPDF 5.0 ARTIFICIAL BOLD AND ITALIC
$s = 'q ';
if ($this->falseBoldWeight && strpos($this->ReqFontStyle,"B") !== false && strpos($this->FontStyle,"B") === false) {
$s .= '2 Tr 1 J 1 j ';
$s .= sprintf('%.3f w ',($this->FontSize/130)*$this->k*$this->falseBoldWeight);
$tc = strtoupper($this->TextColor); // change 0 0 0 rg to 0 0 0 RG
if($this->FillColor!=$tc) { $s .= $tc.' '; } // stroke (outline) = same colour as text(fill)
}
if (strpos($this->ReqFontStyle,"I") !== false && strpos($this->FontStyle,"I") === false) {
$aix = '1 0 0.261799 1 %.3f %.3f Tm';
}
else { $aix = '%.3f %.3f Td'; }
if($this->ColorFlag) $s.=$this->TextColor.' ';
$this->CurrentFont['used']= true;
if ($this->CurrentFont['type']=='TTF' && ($this->CurrentFont['sip'] || $this->CurrentFont['smp'])) { // mPDF 5.0.03 Added SMP
$txt2 = str_replace($this->chrs[194].$this->chrs[160],$this->chrs[32],$txt); // mPDF 5.0
$txt2 = $this->UTF8toSubset($txt2);
$s.=sprintf('BT '.$aix.' %s Tj ET ',$x*$this->k,($this->h-$y)*$this->k,$txt2);
}
else if (!$this->onlyCoreFonts && !$this->usingCoreFont) {
$txt2 = str_replace($this->chrs[194].$this->chrs[160],$this->chrs[32],$txt);
$this->UTF8StringToArray($txt2); // mPDF 5.0 this is just to add chars to subset list
//Convert string to UTF-16BE without BOM
$txt2= $this->UTF8ToUTF16BE($txt2, false);
$s.=sprintf('BT '.$aix.' (%s) Tj ET ',$x*$this->k,($this->h-$y)*$this->k,$this->_escape($txt2));
}
else {
$txt2 = str_replace($this->chrs[160],$this->chrs[32],$txt);
$s.=sprintf('BT '.$aix.' (%s) Tj ET ',$x*$this->k,($this->h-$y)*$this->k,$this->_escape($txt2));
}
if($this->U and $txt!='') {
$s.=$this->_dounderline($x,$y + (0.1* $this->FontSize),$txt).' ';
}
$s .= 'Q';
$this->_out($s);
}
function ResetSpacing() {
if ($this->ws != 0) { $this->_out('BT 0 Tw ET'); }
$this->ws=0;
if ($this->charspacing != 0) { $this->_out('BT 0 Tc ET'); }
$this->charspacing=0;
}
function SetSpacing($cs,$ws) {
if ($cs) { $this->_out(sprintf('BT %.3f Tc ET',$cs)); }
else if ($this->charspacing != 0) { $this->_out('BT 0 Tc ET'); }
$this->charspacing=$cs;
if ($ws) { $this->_out(sprintf('BT %.3f Tw ET',$ws)); }
else if ($this->ws != 0) { $this->_out('BT 0 Tw ET'); }
$this->ws=$ws;
}
// WORD SPACING
function GetJspacing($nc,$ns,$w) {
$ws = 0;
$charspacing = 0;
$ww = $this->jSWord;
$ncx = $nc-1;
if ($nc == 0 && $ns == 0) { return array(0,0); }
if ($nc==1) { $charspacing = $w; }
else if ($this->jSpacing == 'C') {
if ($nc) { $charspacing = $w / ($ncx ); }
}
else if ($this->jSpacing == 'W') {
if ($ns) { $ws = $w / $ns; }
}
else if (!$ns) {
if ($nc) { $charspacing = $w / ($ncx ); }
if (($this->jSmaxChar > 0) && ($charspacing > $this->jSmaxChar)) {
$charspacing = $this->jSmaxChar;
}
}
else if ($ns == ($ncx )) {
$charspacing = $w / $ns;
}
else {
if ($nc) {
if ($this->usingCoreFont) {
$cs = ($w * (1 - $this->jSWord)) / ($ncx );
if (($this->jSmaxChar > 0) && ($cs > $this->jSmaxChar)) {
$cs = $this->jSmaxChar;
$ww = 1 - (($cs * ($ncx ))/$w);
}
$charspacing = $cs;
$ws = ($w * ($ww) ) / $ns;
}
else {
$cs = ($w * (1 - $this->jSWord)) / ($ncx -$ns); if (($this->jSmaxChar > 0) && ($cs > $this->jSmaxChar)) {
$cs = $this->jSmaxChar;
$ww = 1 - (($cs * ($ncx -$ns))/$w);
}
$charspacing = $cs;
$ws = (($w * ($ww) ) / $ns) - $charspacing;
}
}
}
return array($charspacing,$ws);
}
function Cell($w,$h=0,$txt='',$border=0,$ln=0,$align='',$fill=0,$link='', $currentx=0, $lcpaddingL=0, $lcpaddingR=0, $valign='M', $spanfill=0, $abovefont=0, $belowfont=0) {
//Output a cell
// Expects input to be mb_encoded if necessary and RTL reversed
// NON_BREAKING SPACE
if ($this->usingCoreFont) {
$txt = str_replace($this->chrs[160],$this->chrs[32],$txt);
}
else {
$txt = str_replace($this->chrs[194].$this->chrs[160],$this->chrs[32],$txt);
}
$k=$this->k;
$oldcolumn = $this->CurrCol;
// Automatic page break
// Allows PAGE-BREAK-AFTER = avoid to work
if (!$this->tableLevel && (($this->y+$this->divheight>$this->PageBreakTrigger) || ($this->y+$h>$this->PageBreakTrigger) ||
($this->y+($h*2)>$this->PageBreakTrigger && $this->blk[$this->blklvl]['page_break_after_avoid'])) and !$this->InFooter and $this->AcceptPageBreak()) {
$x=$this->x;//Current X position
// WORD SPACING
$ws=$this->ws;//Word Spacing
$charspacing=$this->charspacing;//Character Spacing
$this->ResetSpacing();
$this->AddPage($this->CurOrientation);
// Added to correct for OddEven Margins
$x += $this->MarginCorrection;
if ($currentx) {
$currentx += $this->MarginCorrection;
}
$this->x=$x;
// WORD SPACING
$this->SetSpacing($charspacing,$ws);
}
// Test: to put border round each cell: $border=1;
// Test: to put line through centre of cell: $this->Line($this->x,$this->y+($h/2),$this->x+50,$this->y+($h/2));
// KEEP BLOCK TOGETHER Update/overwrite the lowest bottom of printing y value on first page
if ($this->keep_block_together) {
if ($h) { $this->ktBlock[$this->page]['bottom_margin'] = $this->y+$h; }
// else { $this->ktBlock[$this->page]['bottom_margin'] = $this->y+$this->divheight; }
}
if($w==0) $w = $this->w-$this->rMargin-$this->x;
$s='';
if($fill==1 && $this->FillColor) {
if((isset($this->pageoutput[$this->page]['FillColor']) && $this->pageoutput[$this->page]['FillColor'] != $this->FillColor) || !isset($this->pageoutput[$this->page]['FillColor']) || $this->keep_block_together) { $s .= $this->FillColor.' '; }
$this->pageoutput[$this->page]['FillColor'] = $this->FillColor;
}
$boxtop = $this->y;
$boxheight = $h;
$boxbottom = $this->y+$h;
if($txt!='') {
// FONT SIZE - this determines the baseline caculation
if ($this->linemaxfontsize && !$this->processingHeader) { $bfs = $this->linemaxfontsize; }
else { $bfs = $this->FontSize; }
//Calculate baseline Superscript and Subscript Y coordinate adjustment
$bfx = $this->baselineC;
$baseline = $bfx*$bfs;
if($this->SUP) { $baseline += ($bfx-1.05)*$this->FontSize; }
else if($this->SUB) { $baseline += ($bfx + 0.04)*$this->FontSize; }
else if($this->bullet) { $baseline += ($bfx-0.7)*$this->FontSize; }
// Vertical align (for Images)
if ($abovefont || $belowfont) { // from flowing block - valign always M
$va = $abovefont + (0.5*$bfs);
}
else if ($this->lineheight_correction) {
if ($valign == 'T') { $va = (0.5 * $bfs * $this->lineheight_correction); }
else if ($valign == 'B') { $va = $h-(0.5 * $bfs * $this->lineheight_correction); }
else { $va = 0.5*$h; } // Middle
}
else {
if ($valign == 'T') { $va = (0.5 * $bfs * $this->default_lineheight_correction); }
else if ($valign == 'B') { $va = $h-(0.5 * $bfs * $this->default_lineheight_correction); }
else { $va = 0.5*$h; } // Middle
}
// ONLY SET THESE IF WANT TO CONFINE BORDER +- FILL TO FIT FONTSIZE - NOT FULL CELL
if ($spanfill) {
$boxtop = $this->y+$baseline+$va-($this->FontSize*(0.5+$bfx));
$boxheight = $this->FontSize;
$boxbottom = $boxtop + $boxheight;
}
}
if($fill==1 or $border==1) {
if ($fill==1) $op=($border==1) ? 'B' : 'f';
else $op='S';
$s.=sprintf('%.3f %.3f %.3f %.3f re %s ',$this->x*$k,($this->h-$boxtop)*$k,$w*$k,-$boxheight*$k,$op);
}
if(is_string($border)) {
$x=$this->x;
$y=$this->y;
if(is_int(strpos($border,'L')))
$s.=sprintf('%.3f %.3f m %.3f %.3f l S ',$x*$k,($this->h-$boxtop)*$k,$x*$k,($this->h-($boxbottom))*$k);
if(is_int(strpos($border,'T')))
$s.=sprintf('%.3f %.3f m %.3f %.3f l S ',$x*$k,($this->h-$boxtop)*$k,($x+$w)*$k,($this->h-$boxtop)*$k);
if(is_int(strpos($border,'R')))
$s.=sprintf('%.3f %.3f m %.3f %.3f l S ',($x+$w)*$k,($this->h-$boxtop)*$k,($x+$w)*$k,($this->h-($boxbottom))*$k);
if(is_int(strpos($border,'B')))
$s.=sprintf('%.3f %.3f m %.3f %.3f l S ',$x*$k,($this->h-($boxbottom))*$k,($x+$w)*$k,($this->h-($boxbottom))*$k);
}
if($txt!='') {
$stringWidth = $this->GetStringWidth($txt) + ( $this->charspacing * mb_strlen( $txt, $this->mb_enc ) / $k )
+ ( $this->ws * mb_substr_count( $txt, ' ', $this->mb_enc ) / $k );
// Set x OFFSET FOR PRINTING
if($align=='R') {
$dx=$w-$this->cMarginR - $stringWidth - $lcpaddingR;
}
elseif($align=='C') {
$dx=(($w - $stringWidth )/2);
}
elseif($align=='L' or $align=='J') $dx=$this->cMarginL + $lcpaddingL;
else $dx = 0;
if($this->ColorFlag) $s.='q '.$this->TextColor.' ';
// OUTLINE
if($this->outline_on && !$this->S) {
$s.=' '.sprintf('%.3f w',$this->LineWidth*$k).' ';
$s.=" $this->DrawColor ";
$s.=" 2 Tr ";
}
else if ($this->falseBoldWeight && strpos($this->ReqFontStyle,"B") !== false && strpos($this->FontStyle,"B") === false && !$this->S) { // can't use together with OUTLINE or Small Caps
$s .= ' 2 Tr 1 J 1 j ';
$s .= ' '.sprintf('%.3f w',($this->FontSize/130)*$k*$this->falseBoldWeight).' ';
$tc = strtoupper($this->TextColor); // change 0 0 0 rg to 0 0 0 RG
if($this->FillColor!=$tc) { $s .= ' '.$tc.' '; } // stroke (outline) = same colour as text(fill)
}
if (strpos($this->ReqFontStyle,"I") !== false && strpos($this->FontStyle,"I") === false) { // Artificial italic
$aix = '1 0 0.261799 1 %.3f %.3f Tm ';
}
else { $aix = '%.3f %.3f Td '; }
// THE TEXT
$this->CurrentFont['used']= true;
// WORD SPACING
// IF multibyte - Tw has no effect - need to do word spacing by setting character spacing for spaces between words
if ($this->ws && !$this->usingCoreFont && !$this->CurrentFont['sip'] && !$this->CurrentFont['smp'] && !$this->S) { // mPDF 5.0.03
$space = ' ';
//Convert string to UTF-16BE without BOM
$space= $this->UTF8ToUTF16BE($space , false);
$space=$this->_escape($space );
$s.=sprintf('BT '.$aix,($this->x+$dx)*$k,($this->h-($this->y+$baseline+$va))*$k);
$t = explode(' ',$txt);
for($i=0;$i
UTF8ToUTF16BE($tx , false);
$tx = $this->_escape($tx);
$s.=sprintf(' %.3f Tc (%s) Tj',$this->charspacing,$tx);
if (($i+1)ws+$this->charspacing,$space);
}
}
$s.=' ET';
}
else {
$txt2= $txt;
if ($this->CurrentFont['type']=='TTF' && ($this->CurrentFont['sip'] || $this->CurrentFont['smp'])) { // mPDF 5.0.03 Added SMP
if ($this->S) { $s .= $this->_smallCaps($txt2, 'SIPSMP', $aix, $dx, $k, $baseline, $va, $space); }
else {
$txt2 = $this->UTF8toSubset($txt2);
$s.=sprintf('BT '.$aix.' %s Tj ET',($this->x+$dx)*$k,($this->h-($this->y+$baseline+$va))*$k,$txt2);
}
}
else {
if ($this->S) { $s .= $this->_smallCaps($txt2, '', $aix, $dx, $k, $baseline, $va, $space); }
else {
if (!$this->usingCoreFont) {
$txt2 = $this->UTF8ToUTF16BE($txt2, false);
}
$txt2=$this->_escape($txt2);
$s.=sprintf('BT '.$aix.' (%s) Tj ET',($this->x+$dx)*$k,($this->h-($this->y+$baseline+$va))*$k,$txt2);
}
}
}
// UNDERLINE
if($this->U) {
$c = strtoupper($this->TextColor); // change 0 0 0 rg to 0 0 0 RG
if($this->FillColor!=$c) { $s.= ' '.$c.' '; }
if (isset($this->CurrentFont['up'])) { $up=$this->CurrentFont['up']; }
else { $up = -100; }
$adjusty = (-$up/1000* $this->FontSize);
if (isset($this->CurrentFont['ut'])) { $ut=$this->CurrentFont['ut']/1000* $this->FontSize; }
else { $ut = 60/1000* $this->FontSize; }
$olw = $this->LineWidth;
$s.=' '.(sprintf(' %.3f w',$ut*$this->k));
$s.=' '.$this->_dounderline($this->x+$dx,$this->y+$baseline+$va+$adjusty,$txt);
$s.=' '.(sprintf(' %.3f w',$olw*$this->k));
if($this->FillColor!=$c) { $s.= ' '.$this->FillColor.' '; }
}
// STRIKETHROUGH
if($this->strike) {
$c = strtoupper($this->TextColor); // change 0 0 0 rg to 0 0 0 RG
if($this->FillColor!=$c) { $s.= ' '.$c.' '; }
//Superscript and Subscript Y coordinate adjustment (now for striked-through texts)
if (isset($this->CurrentFont['desc']['CapHeight'])) { $ch=$this->CurrentFont['desc']['CapHeight']; }
else { $ch = 700; }
$adjusty = (-$ch/1000* $this->FontSize) * 0.35;
if (isset($this->CurrentFont['ut'])) { $ut=$this->CurrentFont['ut']/1000* $this->FontSize; }
else { $ut = 60/1000* $this->FontSize; }
$olw = $this->LineWidth;
$s.=' '.(sprintf(' %.3f w',$ut*$this->k));
$s.=' '.$this->_dounderline($this->x+$dx,$this->y+$baseline+$va+$adjusty,$txt);
$s.=' '.(sprintf(' %.3f w',$olw));
if($this->FillColor!=$c) { $s.= ' '.$this->FillColor.' '; }
}
// COLOR
if($this->ColorFlag) $s.=' Q';
// LINK
if($link!='') {
$this->Link($this->x+$dx,$this->y+$va-.5*$this->FontSize,$stringWidth,$this->FontSize,$link);
}
}
if($s) $this->_out($s);
// WORD SPACING
if ($this->ws && !$this->usingCoreFont) {
$this->_out(sprintf('BT %.3f Tc ET',$this->charspacing));
}
$this->lasth=$h;
if( strpos($txt,"\n") !== false) $ln=1; // cell recognizes \n from
tag
if($ln>0)
{
//Go to next line
$this->y += $h;
if($ln==1) {
//Move to next line
if ($currentx != 0) { $this->x=$currentx; }
else { $this->x=$this->lMargin; }
}
}
else $this->x+=$w;
}
function _smallCaps($txt, $mode, $aix, $dx, $k, $baseline, $va, $space) {
$upp = false;
$str = array();
$bits = array();
if (!$this->usingCoreFont) {
$unicode = $this->UTF8StringToArray($txt);
foreach($unicode as $char) {
if (isset($this->upperCase[$char])) {
if (!$upp) {
if (count($str)) { $bits[] = array($upp, $str); }
$str = array();
}
$str[] = $this->upperCase[$char];
if ((!isset($this->CurrentFont['sip']) || !$this->CurrentFont['sip']) && (!isset($this->CurrentFont['smp']) || !$this->CurrentFont['smp'])) {
$this->CurrentFont['subset'][$this->upperCase[$char]] = $this->upperCase[$char];
}
$upp = true;
}
else {
if ($upp) {
if (count($str)) { $bits[] = array($upp, $str); }
$str = array();
}
$str[] = $char;
$upp = false;
}
}
}
else {
for($i=0;$iupperCase[ord($txt[$i])]) && $this->upperCase[ord($txt[$i])] < 256) {
if (!$upp) {
if (count($str)) { $bits[] = array($upp, $str); }
$str = array();
}
$str[] = $this->upperCase[ord($txt[$i])];
$upp = true;
}
else {
if ($upp) {
if (count($str)) { $bits[] = array($upp, $str); }
$str = array();
}
$str[] = ord($txt[$i]);
$upp = false;
}
}
}
if (count($str)) { $bits[] = array($upp, $str); }
$fid = $this->CurrentFont['i'];
$s.=sprintf(' BT '.$aix,($this->x+$dx)*$k,($this->h-($this->y+$baseline+$va))*$k);
foreach($bits AS $b) {
if ($b[0]) { $upp = true; }
else { $upp = false; }
$size = count ($b[1]);
$txt = '';
for ($i = 0; $i < $size; $i++) {
$txt .= code2utf($b[1][$i]);
}
if ($this->usingCoreFont) {
$txt = utf8_decode($txt);
}
if ($mode == 'SIPSMP') {
$txt = $this->UTF8toSubset($txt);
if ($upp) { $s.=sprintf(' /F%d %.3f Tf %d Tz', $fid, $this->FontSizePt*$this->smCapsScale, $this->smCapsStretch); }
else { $s.=sprintf(' /F%d %.3f Tf %d Tz', $fid, $this->FontSizePt, 100); }
$s.=sprintf(' %s Tj', $txt);
}
else {
if (!$this->usingCoreFont) {
$txt = $this->UTF8ToUTF16BE($txt, false);
}
$txt=$this->_escape($txt);
if ($upp) { $s.=sprintf(' /F%d %.3f Tf %d Tz', $fid, $this->FontSizePt*$this->smCapsScale, $this->smCapsStretch); }
else { $s.=sprintf(' /F%d %.3f Tf %d Tz', $fid, $this->FontSizePt, 100); }
$s.=sprintf(' (%s) Tj', $txt);
}
}
$s.=' ET ';
return $s;
}
function MultiCell($w,$h,$txt,$border=0,$align='',$fill=0,$link='',$directionality='ltr',$encoded=false)
{
// Parameter (pre-)encoded - When called internally from ToC or textarea: mb_encoding already done - but not reverse RTL/Indic
if (!$encoded) {
$txt = $this->purify_utf8_text($txt);
if ($this->text_input_as_HTML) {
$txt = $this->all_entities_to_utf8($txt);
}
if ($this->usingCoreFont) { $txt = mb_convert_encoding($txt,$this->mb_enc,'UTF-8'); }
// Font-specific ligature substitution for Indic fonts
}
if (!$align) { $align = $this->defaultAlign; }
//Output text with automatic or explicit line breaks
$cw=&$this->CurrentFont['cw'];
if($w==0) $w=$this->w-$this->rMargin-$this->x;
$wmax = ($w - ($this->cMarginL+$this->cMarginR)); // mPDF 5.0
if ($this->usingCoreFont) {
$s=str_replace("\r",'',$txt);
$nb=strlen($s);
while($nb>0 and $s[$nb-1]=="\n") $nb--;
}
else {
$s=str_replace("\r",'',$txt);
$nb=mb_strlen($s, $this->mb_enc );
while($nb>0 and mb_substr($s,$nb-1,1,$this->mb_enc )=="\n") $nb--;
}
$b=0;
if($border) {
if($border==1) {
$border='LTRB';
$b='LRT';
$b2='LR';
}
else {
$b2='';
if(is_int(strpos($border,'L'))) $b2.='L';
if(is_int(strpos($border,'R'))) $b2.='R';
$b=is_int(strpos($border,'T')) ? $b2.'T' : $b2;
}
}
$sep=-1;
$i=0;
$j=0;
$l=0;
$ns=0;
$nl=1;
if (!$this->usingCoreFont) {
while($i<$nb) {
//Get next character
$c = mb_substr($s,$i,1,$this->mb_enc );
if($c == "\n") {
//Explicit line break
// WORD SPACING
$this->ResetSpacing();
$tmp = rtrim(mb_substr($s,$j,$i-$j,$this->mb_enc));
// DIRECTIONALITY
$this->Cell($w,$h,$tmp,$b,2,$align,$fill,$link);
$i++;
$sep=-1;
$j=$i;
$l=0;
$ns=0;
$nl++;
if($border and $nl==2) $b=$b2;
continue;
}
if($c == " ") {
$sep=$i;
$ls=$l;
$ns++;
}
$l = $this->GetStringWidth(mb_substr($s, $j, $i-$j,$this->mb_enc ));
if($l>$wmax) {
//Automatic line break
if($sep==-1) { // Only one word
if($i==$j) $i++;
// WORD SPACING
$this->ResetSpacing();
$tmp = rtrim(mb_substr($s,$j,$i-$j,$this->mb_enc));
// DIRECTIONALITY
$this->Cell($w,$h,$tmp,$b,2,$align,$fill,$link);
}
else {
$tmp = rtrim(mb_substr($s,$j,$sep-$j,$this->mb_enc));
if($align=='J') {
//$this->ws=($ns>1) ? ((($wmax-$ls)/($ns-1))) : 0;
//$this->_out(sprintf('%.3f Tw',$this->ws*$this->k));
//////////////////////////////////////////
// JUSTIFY J using Unicode fonts (Word spacing doesn't work)
// WORD SPACING UNICODE
// Change NON_BREAKING SPACE to spaces so they are 'spaced' properly
$tmp = str_replace($this->chrs[194].$this->chrs[160],$this->chrs[32],$tmp );
$len_ligne = $this->GetStringWidth($tmp );
$nb_carac = mb_strlen( $tmp , $this->mb_enc ) ;
$nb_spaces = mb_substr_count( $tmp ,' ', $this->mb_enc ) ;
list($charspacing,$ws) = $this->GetJspacing($nb_carac,$nb_spaces,((($w-2) - $len_ligne) * $this->k));
$this->SetSpacing($charspacing,$ws);
//////////////////////////////////////////
}
// DIRECTIONALITY
$this->Cell($w,$h,$tmp,$b,2,$align,$fill,$link);
$i=$sep+1;
}
$sep=-1;
$j=$i;
$l=0;
$ns=0;
$nl++;
if($border and $nl==2) $b=$b2;
}
else $i++;
}
//Last chunk
// WORD SPACING
$this->ResetSpacing();
}
else {
while($i<$nb) {
//Get next character
$c=$s[$i];
if($c == "\n") {
//Explicit line break
// WORD SPACING
$this->ResetSpacing();
$this->Cell($w,$h,substr($s,$j,$i-$j),$b,2,$align,$fill,$link);
$i++;
$sep=-1;
$j=$i;
$l=0;
$ns=0;
$nl++;
if($border and $nl==2) $b=$b2;
continue;
}
if($c == " ") {
$sep=$i;
$ls=$l;
$ns++;
}
$l += $this->GetStringWidth($c);
if($l>$wmax) {
//Automatic line break
if($sep==-1) {
if($i==$j) $i++;
// WORD SPACING
$this->ResetSpacing();
$this->Cell($w,$h,substr($s,$j,$i-$j),$b,2,$align,$fill,$link);
}
else {
if($align=='J') {
$tmp = rtrim(substr($s,$j,$sep-$j));
//////////////////////////////////////////
// JUSTIFY J using Unicode fonts (Word spacing doesn't work)
// WORD SPACING NON_UNICDOE/CJK
// Change NON_BREAKING SPACE to spaces so they are 'spaced' properly
$tmp = str_replace($this->chrs[160],$this->chrs[32],$tmp);
$len_ligne = $this->GetStringWidth($tmp );
$nb_carac = strlen( $tmp ) ;
$nb_spaces = substr_count( $tmp ,' ' ) ;
list($charspacing,$ws) = $this->GetJspacing($nb_carac,$nb_spaces,((($w-2) - $len_ligne) * $this->k));
$this->SetSpacing($charspacing,$ws);
//////////////////////////////////////////
}
$this->Cell($w,$h,substr($s,$j,$sep-$j),$b,2,$align,$fill,$link);
$i=$sep+1;
}
$sep=-1;
$j=$i;
$l=0;
$ns=0;
$nl++;
if($border and $nl==2) $b=$b2;
}
else $i++;
}
//Last chunk
// WORD SPACING
$this->ResetSpacing();
}
//Last chunk
if($border and is_int(strpos($border,'B'))) $b.='B';
if (!$this->usingCoreFont) {
$tmp = rtrim(mb_substr($s,$j,$i-$j,$this->mb_enc));
// DIRECTIONALITY
$this->Cell($w,$h,$tmp,$b,2,$align,$fill,$link);
}
else { $this->Cell($w,$h,substr($s,$j,$i-$j),$b,2,$align,$fill,$link); }
$this->x=$this->lMargin;
}
function saveInlineProperties() {
$saved = array();
$saved[ 'family' ] = $this->FontFamily;
$saved[ 'style' ] = $this->FontStyle;
$saved[ 'sizePt' ] = $this->FontSizePt;
$saved[ 'size' ] = $this->FontSize;
$saved[ 'HREF' ] = $this->HREF;
$saved[ 'underline' ] = $this->U;
$saved[ 'smCaps' ] = $this->S; // mPDF 5.0
$saved[ 'strike' ] = $this->strike;
$saved[ 'SUP' ] = $this->SUP;
$saved[ 'SUB' ] = $this->SUB;
$saved[ 'linewidth' ] = $this->LineWidth;
$saved[ 'drawcolor' ] = $this->DrawColor;
$saved[ 'is_outline' ] = $this->outline_on;
$saved[ 'outlineparam' ] = $this->outlineparam;
$saved[ 'toupper' ] = $this->toupper;
$saved[ 'tolower' ] = $this->tolower;
$saved[ 'I' ] = $this->I;
$saved[ 'B' ] = $this->B;
$saved[ 'colorarray' ] = $this->colorarray;
$saved[ 'bgcolorarray' ] = $this->spanbgcolorarray;
$saved[ 'color' ] = $this->TextColor;
$saved[ 'bgcolor' ] = $this->FillColor;
$saved['lang'] = $this->currentLang;
$saved['display_off'] = $this->inlineDisplayOff; // mPDF 5.0
return $saved;
}
function restoreInlineProperties( &$saved) {
$FontFamily = $saved[ 'family' ];
$this->FontStyle = $saved[ 'style' ];
$this->FontSizePt = $saved[ 'sizePt' ];
$this->FontSize = $saved[ 'size' ];
$this->currentLang = $saved['lang'];
if ($this->useLang && !$this->usingCoreFont) {
if ($this->currentLang != $this->default_lang && ((strlen($this->currentLang) == 5 && $this->currentLang != 'UTF-8') || strlen($this->currentLang ) == 2)) {
list ($coreSuitable,$mpdf_pdf_unifonts,$mpdf_directionality,$mpdf_jSpacing) = GetLangOpts($this->currentLang, $this->useAdobeCJK);
if ($mpdf_pdf_unifonts) { $this->RestrictUnicodeFonts($mpdf_pdf_unifonts); }
else { $this->RestrictUnicodeFonts($this->default_available_fonts ); }
}
else {
$this->RestrictUnicodeFonts($this->default_available_fonts );
}
}
$this->ColorFlag = ($this->FillColor != $this->TextColor); //Restore ColorFlag as well
$this->HREF = $saved[ 'HREF' ];
$this->U = $saved[ 'underline' ];
$this->S = $saved[ 'smCaps' ]; // mPDF 5.0
$this->strike = $saved[ 'strike' ];
$this->SUP = $saved[ 'SUP' ];
$this->SUB = $saved[ 'SUB' ];
$this->LineWidth = $saved[ 'linewidth' ];
$this->DrawColor = $saved[ 'drawcolor' ];
$this->outline_on = $saved[ 'is_outline' ];
$this->outlineparam = $saved[ 'outlineparam' ];
$this->inlineDisplayOff = $saved['display_off']; // mPDF 5.0
$this->toupper = $saved[ 'toupper' ];
$this->tolower = $saved[ 'tolower' ];
$this->SetFont($FontFamily, $saved[ 'style' ].($this->U ? 'U' : '').($this->S ? 'S' : ''),$saved[ 'sizePt' ],false);
//$this->currentfontfamily = $saved[ 'family' ];
$this->currentfontstyle = $saved[ 'style' ].($this->U ? 'U' : '').($this->S ? 'S' : '');
$this->currentfontsize = $saved[ 'sizePt' ];
$this->SetStylesArray(array('S'=>$this->S, 'U'=>$this->U, 'B'=>$saved[ 'B' ], 'I'=>$saved[ 'I' ])); // mPDF 5.0
$this->TextColor = $saved[ 'color' ];
$this->FillColor = $saved[ 'bgcolor' ];
$this->colorarray = $saved[ 'colorarray' ];
$cor = $saved[ 'colorarray' ];
if ($cor) $this->SetTextColor($cor['R'],$cor['G'],$cor['B']);
$this->spanbgcolorarray = $saved[ 'bgcolorarray' ];
$cor = $saved[ 'bgcolorarray' ];
if ($cor) $this->SetFillColor($cor['R'],$cor['G'],$cor['B']);
}
// Used when ColActive for tables - updated to return first block with background fill OR borders
function GetFirstBlockFill() {
// Returns the first blocklevel that uses a bgcolor fill
$startfill = 0;
for ($i=1;$i<=$this->blklvl;$i++) {
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'] ) {
$startfill = $i;
break;
}
}
return $startfill;
}
function SetBlockFill($blvl) {
if ($this->blk[$blvl]['bgcolor']) {
$this->SetFillColor($this->blk[$blvl]['bgcolorarray']['R'],$this->blk[$blvl]['bgcolorarray']['G'],$this->blk[$blvl]['bgcolorarray']['B']);
return 1;
}
else {
$this->SetFillColor(255);
return 0;
}
}
//-------------------------FLOWING BLOCK------------------------------------//
//The following functions were originally written by Damon Kohler //
//--------------------------------------------------------------------------//
function saveFont() {
$saved = array();
$saved[ 'family' ] = $this->FontFamily;
$saved[ 'style' ] = $this->FontStyle;
$saved[ 'sizePt' ] = $this->FontSizePt;
$saved[ 'size' ] = $this->FontSize;
$saved[ 'curr' ] = &$this->CurrentFont;
$saved[ 'color' ] = $this->TextColor;
$saved[ 'spanbgcolor' ] = $this->spanbgcolor;
$saved[ 'spanbgcolorarray' ] = $this->spanbgcolorarray;
$saved[ 'HREF' ] = $this->HREF;
$saved[ 'underline' ] = $this->U;
$saved[ 'smCaps' ] = $this->S; // mPDF 5.0
$saved[ 'strike' ] = $this->strike;
$saved[ 'SUP' ] = $this->SUP;
$saved[ 'SUB' ] = $this->SUB;
$saved[ 'linewidth' ] = $this->LineWidth;
$saved[ 'drawcolor' ] = $this->DrawColor;
$saved[ 'is_outline' ] = $this->outline_on;
$saved[ 'outlineparam' ] = $this->outlineparam;
$saved[ 'ReqFontStyle' ] = $this->ReqFontStyle;
return $saved;
}
function restoreFont( &$saved, $write=true) {
if (!isset($saved) || empty($saved)) return;
$this->FontFamily = $saved[ 'family' ];
$this->FontStyle = $saved[ 'style' ];
$this->FontSizePt = $saved[ 'sizePt' ];
$this->FontSize = $saved[ 'size' ];
$this->CurrentFont = &$saved[ 'curr' ];
$this->TextColor = $saved[ 'color' ];
$this->spanbgcolor = $saved[ 'spanbgcolor' ];
$this->spanbgcolorarray = $saved[ 'spanbgcolorarray' ];
$this->ColorFlag = ($this->FillColor != $this->TextColor); //Restore ColorFlag as well
$this->HREF = $saved[ 'HREF' ];
$this->U = $saved[ 'underline' ];
$this->S = $saved[ 'smCaps' ]; // mPDF 5.0
$this->strike = $saved[ 'strike' ];
$this->SUP = $saved[ 'SUP' ];
$this->SUB = $saved[ 'SUB' ];
$this->LineWidth = $saved[ 'linewidth' ];
$this->DrawColor = $saved[ 'drawcolor' ];
$this->outline_on = $saved[ 'is_outline' ];
$this->outlineparam = $saved[ 'outlineparam' ];
if ($write) {
$this->SetFont($saved[ 'family' ],$saved[ 'style' ].($this->U ? 'U' : '').($this->S ? 'S' : ''),$saved[ 'sizePt' ],true,true); // force output
$fontout = (sprintf('BT /F%d %.3f Tf ET', $this->CurrentFont['i'], $this->FontSizePt));
if($this->page>0 && ((isset($this->pageoutput[$this->page]['Font']) && $this->pageoutput[$this->page]['Font'] != $fontout) || !isset($this->pageoutput[$this->page]['Font']) || $this->keep_block_together)) { $this->_out($fontout); }
$this->pageoutput[$this->page]['Font'] = $fontout;
}
else
$this->SetFont($saved[ 'family' ],$saved[ 'style' ].($this->U ? 'U' : '').($this->S ? 'S' : ''),$saved[ 'sizePt' ]);
$this->ReqFontStyle = $saved[ 'ReqFontStyle' ];
}
function newFlowingBlock( $w, $h, $a = '', $is_table = false, $is_list = false, $blockstate = 0, $newblock=true )
{
if (!$a) { $a = $this->defaultAlign; }
// cell width in points
$this->flowingBlockAttr[ 'width' ] = ($w * $this->k);
// line height in user units
$this->flowingBlockAttr[ 'is_table' ] = $is_table;
$this->flowingBlockAttr[ 'is_list' ] = $is_list;
$this->flowingBlockAttr[ 'height' ] = $h;
$this->flowingBlockAttr[ 'lineCount' ] = 0;
$this->flowingBlockAttr[ 'align' ] = $a;
$this->flowingBlockAttr[ 'font' ] = array();
$this->flowingBlockAttr[ 'content' ] = array();
$this->flowingBlockAttr[ 'contentWidth' ] = 0;
$this->flowingBlockAttr[ 'blockstate' ] = $blockstate;
$this->flowingBlockAttr[ 'newblock' ] = $newblock;
$this->flowingBlockAttr[ 'valign' ] = 'M';
}
function finishFlowingBlock($endofblock=false, $next='') {
$currentx = $this->x;
//prints out the last chunk
$is_table = $this->flowingBlockAttr[ 'is_table' ];
$is_list = $this->flowingBlockAttr[ 'is_list' ];
$maxWidth =& $this->flowingBlockAttr[ 'width' ];
$lineHeight =& $this->flowingBlockAttr[ 'height' ];
$align =& $this->flowingBlockAttr[ 'align' ];
$content =& $this->flowingBlockAttr[ 'content' ];
$font =& $this->flowingBlockAttr[ 'font' ];
$contentWidth =& $this->flowingBlockAttr[ 'contentWidth' ];
$lineCount =& $this->flowingBlockAttr[ 'lineCount' ];
$valign =& $this->flowingBlockAttr[ 'valign' ];
$blockstate = $this->flowingBlockAttr[ 'blockstate' ];
$newblock = $this->flowingBlockAttr[ 'newblock' ];
// *********** BLOCK BACKGROUND COLOR *****************//
if ($this->blk[$this->blklvl]['bgcolor'] && !$is_table) {
$fill = 0;
}
else {
$this->SetFillColor(255);
$fill = 0;
}
// Right trim content and adjust width if need to justify (later)
if (!$endofblock && $align=='J' && ($next=='image' || $next=='select' || $next=='input' || $next=='textarea' || ($next=='br' && $this->justifyB4br))) {
if (preg_match('/[ ]+$/',$content[count($content)-1], $m)) {
$strip = strlen($m[0]);
$content[count($content)-1] = substr($content[count($content)-1],0,(strlen($content[count($content)-1])-$strip));
$this->restoreFont( $font[ count($content)-1 ],false );
$contentWidth -= $this->GetStringWidth($m[0]) * $this->k;
}
}
// the amount of space taken up so far in user units
$usedWidth = 0;
// COLS
$oldcolumn = $this->CurrCol;
// Print out each chunk
$ipaddingL = $this->blk[$this->blklvl]['padding_left'];
$ipaddingR = $this->blk[$this->blklvl]['padding_right'];
$paddingL = ($ipaddingL * $this->k);
$paddingR = ($ipaddingR * $this->k);
$this->cMarginL = $this->blk[$this->blklvl]['border_left']['w'];
$this->cMarginR = $this->blk[$this->blklvl]['border_right']['w'];
// Added mPDF 3.0 Float DIV
$fpaddingR = 0;
$fpaddingL = 0;
$usey = $this->y + 0.002;
if (($newblock) && ($blockstate==1 || $blockstate==3) && ($lineCount == 0) ) {
$usey += $this->blk[$this->blklvl]['margin_top'] + $this->blk[$this->blklvl]['padding_top'] + $this->blk[$this->blklvl]['border_top']['w'];
}
// Set Current lineheight (correction factor)
$lhfixed = false;
if ($is_list) {
if (preg_match('/([0-9.,]+)mm/',$this->list_lineheight[$this->listlvl][$this->listOcc],$am)) {
$lhfixed = true;
$def_fontsize = $this->InlineProperties['LISTITEM'][$this->listlvl][$this->listOcc][$this->listnum]['size'];
$this->lineheight_correction = $am[1] / $def_fontsize ;
}
else {
$this->lineheight_correction = $this->list_lineheight[$this->listlvl][$this->listOcc];
}
}
else
if (isset($this->blk[$this->blklvl]['line_height']) && $this->blk[$this->blklvl]['line_height']) {
if (preg_match('/([0-9.,]+)mm/',$this->blk[$this->blklvl]['line_height'],$am)) {
$lhfixed = true;
$def_fontsize = $this->blk[$this->blklvl]['InlineProperties']['size']; // needs to be default font-size for block ****
$this->lineheight_correction = $am[1] / $def_fontsize ;
}
else {
$this->lineheight_correction = $this->blk[$this->blklvl]['line_height'];
}
}
else {
$this->lineheight_correction = $this->normalLineheight;
}
// correct lineheight to maximum fontsize
if ($lhfixed) { $maxlineHeight = $this->lineheight; }
else { $maxlineHeight = 0; }
$this->forceExactLineheight = true;
$maxfontsize = 0;
foreach ( $content as $k => $chunk )
{
$this->restoreFont( $font[ $k ],false );
if (!isset($this->objectbuffer[$k])) {
// Soft Hyphens chr(173)
if (!$this->usingCoreFont) {
$content[$k] = $chunk = str_replace("\xc2\xad",'',$chunk );
}
else if ($this->FontFamily!='csymbol' && $this->FontFamily!='czapfdingbats') {
$content[$k] = $chunk = str_replace($this->chrs[173],'',$chunk );
}
// Special case of sub/sup carried over on its own to last line
if (($this->SUB || $this->SUP) && count($content)==1) { $actfs = $this->FontSize*100/55; } // 55% is font change for sub/sup
else { $actfs = $this->FontSize; }
if (!$lhfixed) { $maxlineHeight = max($maxlineHeight,$actfs * $this->lineheight_correction ); }
if ($lhfixed && ($actfs > $def_fontsize || ($actfs > ($lineHeight * $this->lineheight_correction) && $is_list))) {
$this->forceExactLineheight = false;
}
$maxfontsize = max($maxfontsize,$actfs);
}
}
$lastfontreqstyle = $font[count($font)-1]['ReqFontStyle'];
$lastfontstyle = $font[count($font)-1]['style'];
if ($this->directionality == 'ltr' && strpos($lastfontreqstyle,"I") !== false && strpos($lastfontstyle,"I") === false) { // Artificial italic
$lastitalic = $this->FontSize*0.15*$this->k;
}
else { $lastitalic = 0; }
if ($is_list && is_array($this->bulletarray) && count($this->bulletarray)) {
$actfs = $this->bulletarray['fontsize'];
if (!$lhfixed) { $maxlineHeight = max($maxlineHeight,$actfs * $this->lineheight_correction ); }
if ($lhfixed && $actfs > $def_fontsize) { $this->forceExactLineheight = false; }
$maxfontsize = max($maxfontsize,$actfs);
}
// when every text item checked i.e. $maxfontsize is set properly
$af = 0; // Above font
$bf = 0; // Below font
$mta = 0; // Maximum top-aligned
$mba = 0; // Maximum bottom-aligned
foreach ( $content as $k => $chunk )
{
if (isset($this->objectbuffer[$k])) {
$oh = $this->objectbuffer[$k]['OUTER-HEIGHT'];
$va = $this->objectbuffer[$k]['vertical-align']; // = $objattr['vertical-align'] = set as M,T,B,S
if ($lhfixed && $oh > $def_fontsize) { $this->forceExactLineheight = false; }
if ($va == 'BS') { // (BASELINE default)
$af = max($af, ($oh - ($maxfontsize * (0.5 + $this->baselineC))));
}
else if ($va == 'M') {
$af = max($af, ($oh - $maxfontsize)/2);
$bf = max($bf, ($oh - $maxfontsize)/2);
}
else if ($va == 'TT') {
$bf = max($bf, ($oh - $maxfontsize));
}
else if ($va == 'TB') {
$af = max($af, ($oh - $maxfontsize));
}
else if ($va == 'T') {
$mta = max($mta, $oh);
}
else if ($va == 'B') {
$mba = max($mba, $oh);
}
}
}
if ((!$lhfixed || !$this->forceExactLineheight) && ($af > (($maxlineHeight - $maxfontsize)/2) || $bf > (($maxlineHeight - $maxfontsize)/2))) {
$maxlineHeight = $maxfontsize + $af + $bf;
}
else if (!$lhfixed) { $af = $bf = ($maxlineHeight - $maxfontsize)/2; }
if ($mta > $maxlineHeight) {
$bf += ($mta - $maxlineHeight);
$maxlineHeight = $mta;
}
if ($mba > $maxlineHeight) {
$af += ($mba - $maxlineHeight);
$maxlineHeight = $mba;
}
$lineHeight = $maxlineHeight;
// If NOT images, and maxfontsize NOT > lineHeight - this value determines text baseline positioning
if ($lhfixed && $af==0 && $bf==0 && $maxfontsize<=($def_fontsize * $this->lineheight_correction * 0.8 )) {
$this->linemaxfontsize = $def_fontsize;
}
else { $this->linemaxfontsize = $maxfontsize; }
// Get PAGEBREAK TO TEST for height including the bottom border/padding
$check_h = max($this->divheight,$lineHeight);
if ($this->blklvl > 0 && !$is_table) {
if ($endofblock && $blockstate > 1) {
if ($this->blk[$this->blklvl]['page_break_after_avoid']) { $check_h += $lineHeight; }
$check_h += ($this->blk[$this->blklvl]['padding_bottom'] + $this->blk[$this->blklvl]['border_bottom']['w']);
}
if (($newblock && ($blockstate==1 || $blockstate==3) && $lineCount == 0) || ($endofblock && $blockstate > 1 && $lineCount == 0)) {
$check_h += ($this->blk[$this->blklvl]['padding_top'] + $this->blk[$this->blklvl]['margin_top'] + $this->blk[$this->blklvl]['border_top']['w']);
}
}
// Force PAGE break if column height cannot take check-height
if ($this->ColActive && $check_h > ($this->PageBreakTrigger - $this->y0)) { $this->CurrCol = $this->NbCol; }
// PAGEBREAK
//'If' below used in order to fix "first-line of other page with justify on" bug
if(!$is_table && ($this->y+$check_h) > $this->PageBreakTrigger and !$this->InFooter and $this->AcceptPageBreak()) {
$bak_x=$this->x;//Current X position
// WORD SPACING
$ws=$this->ws;//Word Spacing
$charspacing=$this->charspacing;//Character Spacing
$this->ResetSpacing();
$this->AddPage($this->CurOrientation);
$this->x=$bak_x;
// Added to correct for OddEven Margins
$currentx += $this->MarginCorrection;
$this->x += $this->MarginCorrection;
// WORD SPACING
$this->SetSpacing($charspacing,$ws);
}
// mPDF 5.0
if ($this->keep_block_together && !$is_table && $this->kt_p00 < $this->page && ($this->y+$check_h) > $this->kt_y00) {
$this->printdivbuffer();
$this->keep_block_together = 0;
}
// TOP MARGIN
if ($newblock && ($blockstate==1 || $blockstate==3) && ($this->blk[$this->blklvl]['margin_top']) && $lineCount == 0 && !$is_table && !$is_list) {
$this->DivLn($this->blk[$this->blklvl]['margin_top'],$this->blklvl-1,true,$this->blk[$this->blklvl]['margin_collapse']);
}
if ($newblock && ($blockstate==1 || $blockstate==3) && $lineCount == 0 && !$is_table && !$is_list) {
$this->blk[$this->blklvl]['y0'] = $this->y;
$this->blk[$this->blklvl]['startpage'] = $this->page;
}
// ADDED for Paragraph_indent
$WidthCorrection = 0;
if (($newblock) && ($blockstate==1 || $blockstate==3) && isset($this->blk[$this->blklvl]['text_indent']) && ($lineCount == 0) && (!$is_table) && (!$is_list) && ($align != 'C')) {
$ti = $this->ConvertSize($this->blk[$this->blklvl]['text_indent'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
$WidthCorrection = ($ti*$this->k);
}
// PADDING and BORDER spacing/fill
if (($newblock) && ($blockstate==1 || $blockstate==3) && (($this->blk[$this->blklvl]['padding_top']) || ($this->blk[$this->blklvl]['border_top'])) && ($lineCount == 0) && (!$is_table) && (!$is_list)) {
// $state = 0 normal; 1 top; 2 bottom; 3 top and bottom
$this->DivLn($this->blk[$this->blklvl]['padding_top'] + $this->blk[$this->blklvl]['border_top']['w'],-3,true,false,1);
$this->x = $currentx;
}
// Added mPDF 3.0 Float DIV
$fpaddingR = 0;
$fpaddingL = 0;
$usey = $this->y + 0.002;
if (($newblock) && ($blockstate==1 || $blockstate==3) && ($lineCount == 0) ) {
$usey += $this->blk[$this->blklvl]['margin_top'] + $this->blk[$this->blklvl]['padding_top'] + $this->blk[$this->blklvl]['border_top']['w'];
}
if ($content) {
$empty = $maxWidth - $lastitalic-$WidthCorrection - $contentWidth - (($this->cMarginL+$this->cMarginR)* $this->k) - ($paddingL+$paddingR +(($fpaddingL + $fpaddingR) * $this->k) );
$empty /= $this->k;
// In FinishFlowing Block no lines are justified as it is always last line
// but if orphansAllowed have allowed content width to go over max width, use J charspacing to compress line
// JUSTIFICATION J - NOT!
$nb_carac = 0;
$nb_spaces = 0;
foreach ( $content as $k => $chunk ) {
if (!isset($this->objectbuffer[$k]) || (isset($this->objectbuffer[$k]) && !$this->objectbuffer[$k])) {
if ($this->usingCoreFont) {
$chunk = str_replace($this->chrs[160],$this->chrs[32],$chunk );
}
else {
$chunk = str_replace($this->chrs[194].$this->chrs[160],$this->chrs[32],$chunk );
}
$nb_carac += mb_strlen( $chunk, $this->mb_enc );
$nb_spaces += mb_substr_count( $chunk,' ', $this->mb_enc );
}
}
// 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)
// If "orphans" in fact is just a final space - ignore this
if (((($contentWidth + $lastitalic) > $maxWidth) && ($content[count($content)-1] != ' ') ) ||
(!$endofblock && $align=='J' && ($next=='image' || $next=='select' || $next=='input' || $next=='textarea' || ($next=='br' && $this->justifyB4br)))
) {
// WORD SPACING
list($charspacing,$ws) = $this->GetJspacing($nb_carac,$nb_spaces,($maxWidth-$lastitalic-$contentWidth-$WidthCorrection-(($this->cMarginL+$this->cMarginR)*$this->k)-($paddingL+$paddingR +(($fpaddingL + $fpaddingR) * $this->k) )));
$this->SetSpacing($charspacing,$ws);
}
// Check if will fit at word/char spacing of previous line - if so continue it
// but only allow a maximum of $this->jSmaxWordLast and $this->jSmaxCharLast
else if ($contentWidth < ($maxWidth - $lastitalic-$WidthCorrection - (($this->cMarginL+$this->cMarginR)* $this->k) - ($paddingL+$paddingR +(($fpaddingL + $fpaddingR) * $this->k)))) {
if ($this->ws > $this->jSmaxWordLast) {
$ws=$this->jSmaxWord;
$this->_out(sprintf('BT %.3f Tw ET',$ws));
$this->ws=$ws;
}
if ($this->charspacing > $this->jSmaxCharLast) {
$charspacing=$this->jSmaxCharLast;
$this->_out(sprintf('BT %.3f Tc ET',$charspacing));
$this->charspacing=$charspacing;
}
$check = $maxWidth - $lastitalic-$WidthCorrection - $contentWidth - (($this->cMarginL+$this->cMarginR)* $this->k) - ($paddingL+$paddingR +(($fpaddingL + $fpaddingR) * $this->k) ) - ( $this->charspacing * $nb_carac) - ( $this->ws * $nb_spaces);
if ($check <= 0) {
$this->ResetSpacing();
}
}
else {
$this->ResetSpacing();
}
$empty = $maxWidth - $lastitalic-$WidthCorrection - $contentWidth - (($this->cMarginL+$this->cMarginR)* $this->k) - ($paddingL+$paddingR +(($fpaddingL + $fpaddingR) * $this->k) ) - ( $this->charspacing * $nb_carac) - ( $this->ws * $nb_spaces);
$empty /= $this->k;
if (!$is_table) {
$this->maxPosR = max($this->maxPosR , ($this->w - $this->rMargin - $this->blk[$this->blklvl]['outer_right_margin'] - $empty));
$this->maxPosL = min($this->maxPosL , ($this->lMargin + $this->blk[$this->blklvl]['outer_left_margin'] + $empty));
}
$arraysize = count($content);
$margins = ($this->cMarginL+$this->cMarginR) + ($ipaddingL+$ipaddingR + $fpaddingR + $fpaddingR );
if (!$is_table) { $this->DivLn($lineHeight,$this->blklvl,false); } // false -> don't advance y
// DIRECTIONALITY RTL
$all_rtl = false;
$contains_rtl = false;
$this->x = $currentx + $this->cMarginL + $ipaddingL + $fpaddingL;
if ($align == 'R') { $this->x += $empty; }
else if ($align == 'J') {
if ($this->directionality == 'rtl' && $contains_rtl) { $this->x += $empty; }
else if ($this->directionality == 'ltr' && $all_rtl) { $this->x += $empty; }
}
else if ($align == 'C') { $this->x += ($empty / 2); }
// Paragraph INDENT
$WidthCorrection = 0;
if (($newblock) && ($blockstate==1 || $blockstate==3) && isset($this->blk[$this->blklvl]['text_indent']) && ($lineCount == 0) && (!$is_table) && (!$is_list) && ($align !='C')) {
$ti = $this->ConvertSize($this->blk[$this->blklvl]['text_indent'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
$this->x += $ti;
}
foreach ( $content as $k => $chunk )
{
// FOR IMAGES
if (($this->directionality=='rtl' && $contains_rtl) || $all_rtl) { $dirk = $arraysize-1 - $k; } else { $dirk = $k; }
$va = 'M'; // default for text
if (isset($this->objectbuffer[$dirk]) && $this->objectbuffer[$dirk]) {
$xadj = $this->x - $this->objectbuffer[$dirk]['OUTER-X'];
$this->objectbuffer[$dirk]['OUTER-X'] += $xadj;
$this->objectbuffer[$dirk]['BORDER-X'] += $xadj;
$this->objectbuffer[$dirk]['INNER-X'] += $xadj;
$va = $this->objectbuffer[$dirk]['vertical-align'];
$yadj = $this->y - $this->objectbuffer[$dirk]['OUTER-Y'];
if ($va == 'BS') {
$yadj += $af + ($this->linemaxfontsize * (0.5 + $this->baselineC)) - $this->objectbuffer[$dirk]['OUTER-HEIGHT'];
}
else if ($va == 'M' || $va == '') {
$yadj += $af + ($this->linemaxfontsize /2) - ($this->objectbuffer[$dirk]['OUTER-HEIGHT']/2);
}
else if ($va == 'TB') {
$yadj += $af + $this->linemaxfontsize - $this->objectbuffer[$dirk]['OUTER-HEIGHT'];
}
else if ($va == 'TT') {
$yadj += $af;
}
else if ($va == 'B') {
$yadj += $af + $this->linemaxfontsize + $bf - $this->objectbuffer[$dirk]['OUTER-HEIGHT'];
}
else if ($va == 'T') {
$yadj += 0;
}
$this->objectbuffer[$dirk]['OUTER-Y'] += $yadj;
$this->objectbuffer[$dirk]['BORDER-Y'] += $yadj;
$this->objectbuffer[$dirk]['INNER-Y'] += $yadj;
}
// DIRECTIONALITY RTL
if ((($this->directionality == 'rtl') && ($contains_rtl )) || ($all_rtl )) { $this->restoreFont( $font[ $arraysize-1 - $k ] ); }
else { $this->restoreFont( $font[ $k ] ); }
// *********** SPAN BACKGROUND COLOR ***************** //
if (isset($this->spanbgcolor) && $this->spanbgcolor) {
$cor = $this->spanbgcolorarray;
$this->SetFillColor($cor['R'],$cor['G'],$cor['B']);
$save_fill = $fill; $spanfill = 1; $fill = 1;
}
// WORD SPACING
$stringWidth = $this->GetStringWidth($chunk ) + ( $this->charspacing * mb_strlen($chunk,$this->mb_enc ) / $this->k )
+ ( $this->ws * mb_substr_count($chunk,' ',$this->mb_enc ) / $this->k );
if (isset($this->objectbuffer[$dirk])) {
if ($this->objectbuffer[$dirk]['type']=='dottab') {
$this->objectbuffer[$dirk]['OUTER-WIDTH'] +=$empty;
}
$stringWidth = $this->objectbuffer[$dirk]['OUTER-WIDTH'];
}
if ($stringWidth==0) { $stringWidth = 0.000001; } // mPDF 5.0
if ($k == $arraysize-1) $this->Cell( $stringWidth, $lineHeight, $chunk, '', 1, '', $fill, $this->HREF , $currentx,0,0,'M', $fill, $af, $bf ); //mono-style line or last part (skips line)
else $this->Cell( $stringWidth, $lineHeight, $chunk, '', 0, '', $fill, $this->HREF, 0, 0,0,'M', $fill, $af, $bf );//first or middle part
// *********** SPAN BACKGROUND COLOR OFF - RESET BLOCK BGCOLOR ***************** //
if (isset($spanfill) && $spanfill) {
$fill = $save_fill; $spanfill = 0;
if ($fill) { $this->SetFillColor($bcor['R'],$bcor['G'],$bcor['B']); }
}
}
$this->printobjectbuffer($is_table);
$this->objectbuffer = array();
$this->ResetSpacing();
// LIST BULLETS/NUMBERS
if ($is_list && is_array($this->bulletarray) && ($lineCount == 0) ) {
$savedFont = $this->saveFont();
$bull = $this->bulletarray;
if (isset($bull['level']) && isset($bull['occur']) && isset($this->InlineProperties['LIST'][$bull['level']][$bull['occur']])) {
$this->restoreInlineProperties($this->InlineProperties['LIST'][$bull['level']][$bull['occur']]);
}
if (isset($bull['level']) && isset($bull['occur']) && isset($bull['num']) && isset($this->InlineProperties['LISTITEM'][$bull['level']][$bull['occur']][$bull['num']]) && $this->InlineProperties['LISTITEM'][$bull['level']][$bull['occur']][$bull['num']]) { $this->restoreInlineProperties($this->InlineProperties['LISTITEM'][$bull['level']][$bull['occur']][$bull['num']]); }
if (isset($bull['font']) && $bull['font'] == 'czapfdingbats') {
$this->bullet = true;
$this->SetFont('czapfdingbats','',$this->FontSizePt/2.5);
}
else { $this->SetFont($this->FontFamily,$this->FontStyle,$this->FontSizePt,true,true); } // force output
//Output bullet
$this->x = $currentx;
if (isset($bull['x'])) { $this->x += $bull['x']; }
$this->y -= $lineHeight;
if (isset($bull['txt'])) { $this->Cell($bull['w'], $lineHeight,$bull['txt'],'','',$bull['align'],0,'',0,-$this->cMarginL, -$this->cMarginR ); }
if (isset($bull['font']) && $bull['font'] == 'czapfdingbats') {
$this->bullet = false;
}
$this->x = $currentx; // Reset
$this->y += $lineHeight;
$this->restoreFont( $savedFont );
// $font = array( $savedFont );
$this->bulletarray = array(); // prevents repeat of bullet/number if ....
.....
}
} // END IF CONTENT
// PADDING and BORDER spacing/fill
if ($endofblock && ($blockstate > 1) && ($this->blk[$this->blklvl]['padding_bottom'] || $this->blk[$this->blklvl]['border_bottom'] || $this->blk[$this->blklvl]['css_set_height']) && (!$is_table) && (!$is_list)) {
// If CSS height set, extend bottom - if on same page as block started, and CSS HEIGHT > actual height,
// and does not force pagebreak
$extra = 0;
if ($this->blk[$this->blklvl]['css_set_height'] && $this->blk[$this->blklvl]['startpage']==$this->page) {
// predicted height
$h1 = ($this->y-$this->blk[$this->blklvl]['y0']) + $this->blk[$this->blklvl]['padding_bottom'] + $this->blk[$this->blklvl]['border_bottom']['w'];
if ($h1 < $this->blk[$this->blklvl]['css_set_height']) { $extra = $this->blk[$this->blklvl]['css_set_height'] - $h1; }
if($this->y + $this->blk[$this->blklvl]['padding_bottom'] + $this->blk[$this->blklvl]['border_bottom']['w'] + $extra > $this->PageBreakTrigger) {
$extra = $this->PageBreakTrigger - ($this->y + $this->blk[$this->blklvl]['padding_bottom'] + $this->blk[$this->blklvl]['border_bottom']['w']);
}
}
// $state = 0 normal; 1 top; 2 bottom; 3 top and bottom
$this->DivLn($this->blk[$this->blklvl]['padding_bottom'] + $this->blk[$this->blklvl]['border_bottom']['w'] + $extra,-3,true,false,2);
$this->x = $currentx;
}
// SET Bottom y1 of block (used for painting borders)
if (($endofblock) && ($blockstate > 1) && (!$is_table) && (!$is_list)) {
$this->blk[$this->blklvl]['y1'] = $this->y;
}
// BOTTOM MARGIN
if (($endofblock) && ($blockstate > 1) && ($this->blk[$this->blklvl]['margin_bottom']) && (!$is_table) && (!$is_list)) {
if($this->y+$this->blk[$this->blklvl]['margin_bottom'] < $this->PageBreakTrigger and !$this->InFooter) {
$this->DivLn($this->blk[$this->blklvl]['margin_bottom'],$this->blklvl-1,true,$this->blk[$this->blklvl]['margin_collapse']);
}
}
// Reset lineheight
$lineHeight = $this->divheight;
}
function printobjectbuffer($is_table=false) {
if ($is_table && $this->shrin_k > 1) { $k = $this->shrin_k; }
else { $k = 1; }
$save_y = $this->y;
$save_x = $this->x;
$save_currentfontfamily = $this->FontFamily;
$save_currentfontsize = $this->FontSizePt;
$save_currentfontstyle = $this->FontStyle.($this->U ? 'U' : '').($this->S ? 'S' : '');
if ($this->directionality == 'rtl') { $rtlalign = 'R'; } else { $rtlalign = 'L'; }
foreach ($this->objectbuffer AS $ib => $objattr) {
if ($objattr['type'] == 'bookmark' || $objattr['type'] == 'indexentry' || $objattr['type'] == 'toc') {
$x = $objattr['OUTER-X'];
$y = $objattr['OUTER-Y'];
$this->y = $y - $this->FontSize/2;
$this->x = $x;
if ($objattr['type'] == 'bookmark' ) { $this->Bookmark($objattr['CONTENT'],$objattr['bklevel'] ,$y - $this->FontSize); } // *BOOKMARKS*
}
else {
$y = $objattr['OUTER-Y'];
$x = $objattr['OUTER-X'];
$w = $objattr['OUTER-WIDTH'];
$h = $objattr['OUTER-HEIGHT'];
if (isset($objattr['text'])) { $texto = $objattr['text']; }
$this->y = $y;
$this->x = $x;
if (isset($objattr['fontfamily'])) { $this->SetFont($objattr['fontfamily'],'',$objattr['fontsize'] ); }
}
// HR
if ($objattr['type'] == 'hr') {
$this->SetDrawColor($objattr['color']['R'],$objattr['color']['G'],$objattr['color']['B']);
switch($objattr['align']) {
case 'C':
$empty = $objattr['OUTER-WIDTH'] - $objattr['INNER-WIDTH'];
$empty /= 2;
$x += $empty;
break;
case 'R':
$empty = $objattr['OUTER-WIDTH'] - $objattr['INNER-WIDTH'];
$x += $empty;
break;
}
$oldlinewidth = $this->LineWidth;
$this->SetLineWidth($objattr['linewidth']/$k );
$this->y += ($objattr['linewidth']/2) + $objattr['margin_top']/$k;
$this->Line($x,$this->y,$x+$objattr['INNER-WIDTH'],$this->y);
$this->SetLineWidth($oldlinewidth);
$this->SetDrawColor(0);
}
// IMAGE
if ($objattr['type'] == 'image') {
if (isset($objattr['opacity'])) { $this->SetAlpha($objattr['opacity']); }
$rotate = 0;
$obiw = $objattr['INNER-WIDTH'];
$obih = $objattr['INNER-HEIGHT'];
$sx = $objattr['INNER-WIDTH']*$this->k / $objattr['orig_w'];
$sy = abs($objattr['INNER-HEIGHT'])*$this->k / abs($objattr['orig_h']);
$sx = ($objattr['INNER-WIDTH']*$this->k / $objattr['orig_w']);
$sy = ($objattr['INNER-HEIGHT']*$this->k / $objattr['orig_h']);
if (isset($objattr['ROTATE'])) { $rotate = $objattr['ROTATE']; }
if ($rotate==90) {
// Clockwise
$obiw = $objattr['INNER-HEIGHT'];
$obih = $objattr['INNER-WIDTH'];
$tr = $this->transformTranslate(0, -$objattr['INNER-WIDTH'], true) ;
$tr .= ' '. $this->transformRotate(90, $objattr['INNER-X'],($objattr['INNER-Y'] +$objattr['INNER-WIDTH'] ),true) ;
$sx = $obiw*$this->k / $objattr['orig_h'];
$sy = $obih*$this->k / $objattr['orig_w'];
}
else if ($rotate==-90) {
// AntiClockwise
$obiw = $objattr['INNER-HEIGHT'];
$obih = $objattr['INNER-WIDTH'];
$tr = $this->transformTranslate($objattr['INNER-WIDTH'], ($objattr['INNER-HEIGHT']-$objattr['INNER-WIDTH']), true) ;
$tr .= ' '. $this->transformRotate(-90, $objattr['INNER-X'],($objattr['INNER-Y'] +$objattr['INNER-WIDTH'] ),true) ;
$sx = $obiw*$this->k / $objattr['orig_h'];
$sy = $obih*$this->k / $objattr['orig_w'];
}
else if ($rotate==180) {
// Mirror
$tr = $this->transformTranslate($objattr['INNER-WIDTH'], -$objattr['INNER-HEIGHT'], true) ;
$tr .= ' '. $this->transformRotate(180, $objattr['INNER-X'],($objattr['INNER-Y'] +$objattr['INNER-HEIGHT'] ),true) ;
}
else { $tr = ''; }
$tr = trim($tr);
if ($tr) { $tr .= ' '; }
if (isset($objattr['itype']) && $objattr['itype']=='svg') {
$outstring = sprintf('q '.$tr.'%.3f 0 0 %.3f %.3f %.3f cm /FO%d Do Q', $sx, -$sy, $objattr['INNER-X']*$this->k-$sx*$objattr['wmf_x'], (($this->h-$objattr['INNER-Y'])*$this->k)+$sy*$objattr['wmf_y'], $objattr['ID']);
}
else {
$outstring = sprintf("q ".$tr."%.3f 0 0 %.3f %.3f %.3f cm /I%d Do Q",$obiw*$this->k, $obih*$this->k, $objattr['INNER-X'] *$this->k, ($this->h-($objattr['INNER-Y'] +$obih ))*$this->k,$objattr['ID'] );
}
$this->_out($outstring);
// LINK
if (isset($objattr['link'])) $this->Link($objattr['INNER-X'],$objattr['INNER-Y'],$objattr['INNER-WIDTH'],$objattr['INNER-HEIGHT'],$objattr['link']);
if (isset($objattr['BORDER-WIDTH'])) { $this->PaintImgBorder($objattr,$is_table); }
if (isset($objattr['opacity'])) { $this->SetAlpha(1); }
}
$this->ResetSpacing();
if ($objattr['type'] == 'dottab') {
$sp = $this->GetStringWidth(' ');
$nb=floor(($w-2*$sp)/$this->GetStringWidth('.'));
if ($nb>0) { $dots=' '.str_repeat('.',$nb).' '; }
else { $dots=' '; }
// mPDF 5.0
$this->SetTextColor($objattr['colorarray']['R'],$objattr['colorarray']['G'],$objattr['colorarray']['B']);
$this->Cell($w,$h,$dots,0,0,'C');
// mPDF 5.0
$this->SetTextColor(0);
}
}
$this->SetFont($save_currentfontfamily,$save_currentfontstyle,$save_currentfontsize);
$this->y = $save_y;
$this->x = $save_x;
unset($content);
}
function WriteFlowingBlock( $s)
{
$currentx = $this->x;
$is_table = $this->flowingBlockAttr[ 'is_table' ];
$is_list = $this->flowingBlockAttr[ 'is_list' ];
// width of all the content so far in points
$contentWidth =& $this->flowingBlockAttr[ 'contentWidth' ];
// cell width in points
$maxWidth =& $this->flowingBlockAttr[ 'width' ];
$lineCount =& $this->flowingBlockAttr[ 'lineCount' ];
// line height in user units
$lineHeight =& $this->flowingBlockAttr[ 'height' ];
$align =& $this->flowingBlockAttr[ 'align' ];
$content =& $this->flowingBlockAttr[ 'content' ];
$font =& $this->flowingBlockAttr[ 'font' ];
$valign =& $this->flowingBlockAttr[ 'valign' ];
$blockstate = $this->flowingBlockAttr[ 'blockstate' ];
$newblock = $this->flowingBlockAttr[ 'newblock' ];
// *********** BLOCK BACKGROUND COLOR ***************** //
if ($this->blk[$this->blklvl]['bgcolor'] && !$is_table) {
$fill = 0;
// $fill = 1;
// $bcor = $this->blk[$this->blklvl]['bgcolorarray'];
// $this->SetFillColor($bcor['R'],$bcor['G'],$bcor['B']);
}
else {
$this->SetFillColor(255);
$fill = 0;
}
$font[] = $this->saveFont();
$content[] = '';
$currContent =& $content[ count( $content ) - 1 ];
// where the line should be cutoff if it is to be justified
$cutoffWidth = $contentWidth;
$curlyquote = mb_convert_encoding("\xe2\x80\x9e",$this->mb_enc,'UTF-8');
$curlylowquote = mb_convert_encoding("\xe2\x80\x9d",$this->mb_enc,'UTF-8');
// COLS
$oldcolumn = $this->CurrCol;
$ipaddingL = $this->blk[$this->blklvl]['padding_left'];
$ipaddingR = $this->blk[$this->blklvl]['padding_right'];
$paddingL = ($ipaddingL * $this->k);
$paddingR = ($ipaddingR * $this->k);
$this->cMarginL = $this->blk[$this->blklvl]['border_left']['w'];
$cpaddingadjustL = -$this->cMarginL;
$this->cMarginR = $this->blk[$this->blklvl]['border_right']['w'];
$cpaddingadjustR = -$this->cMarginR;
// Added mPDF 3.0 Float DIV
$fpaddingR = 0;
$fpaddingL = 0;
$usey = $this->y + 0.002;
if (($newblock) && ($blockstate==1 || $blockstate==3) && ($lineCount == 0) ) {
$usey += $this->blk[$this->blklvl]['margin_top'] + $this->blk[$this->blklvl]['padding_top'] + $this->blk[$this->blklvl]['border_top']['w'];
}
//OBJECTS - IMAGES & FORM Elements (NB has already skipped line/page if required - in printbuffer)
if (substr($s,0,3) == "\xbb\xa4\xac") { //identifier has been identified!
$objattr = $this->_getObjAttr($s);
$h_corr = 0;
if (($newblock) && ($blockstate==1 || $blockstate==3) && ($lineCount == 0) && (!$is_table)) { $h_corr = $this->blk[$this->blklvl]['padding_top'] + $this->blk[$this->blklvl]['border_top']['w']; }
$maximumW = ($maxWidth/$this->k) - ($this->blk[$this->blklvl]['padding_left'] + $this->blk[$this->blklvl]['border_left']['w'] + $this->blk[$this->blklvl]['padding_right'] + $this->blk[$this->blklvl]['border_right']['w'] + $fpaddingL + $fpaddingR );
$objattr = $this->inlineObject($objattr['type'],$this->lMargin + $fpaddingL + ($contentWidth/$this->k),($this->y + $h_corr), $objattr, $this->lMargin,($contentWidth/$this->k),$maximumW,$lineHeight,true,$is_table);
// SET LINEHEIGHT for this line ================ RESET AT END
$lineHeight = MAX($lineHeight,$objattr['OUTER-HEIGHT']);
$this->objectbuffer[count($content)-1] = $objattr;
// if (isset($objattr['vertical-align'])) { $valign = $objattr['vertical-align']; }
// else { $valign = ''; }
$contentWidth += ($objattr['OUTER-WIDTH'] * $this->k);
return;
}
if ($this->usingCoreFont) {
$tmp = strlen( $s );
}
else {
$tmp = mb_strlen( $s, $this->mb_enc );
}
$orphs = 0;
$check = 0;
// for every character in the string
for ( $i = 0; $i < $tmp; $i++ ) {
// extract the current character
// get the width of the character in points
if ($this->usingCoreFont) {
$c = $s[$i];
// Soft Hyphens chr(173)
if ($c == chr(173) && ($this->FontFamily!='csymbol' && $this->FontFamily!='czapfdingbats')) { $cw = 0; }
else if ($this->S) { $cw = ($this->GetStringWidth($c) * $this->k); } // mPDF 5.0
else { $cw = $this->CurrentFont[ 'cw' ][ $c ] * ( $this->FontSizePt / 1000 ); }
}
else {
$c = mb_substr($s,$i,1,$this->mb_enc );
$cw = ($this->GetStringWidth($c) * $this->k);
}
if ($c==' ') { $check = 1; }
// CHECK for ORPHANS
// mPDF 5.0 Added "]"
else if ($c=='.' || $c==',' || $c==')' || $c==']' || $c==';' || $c==':' || $c=='!' || $c=='?'|| $c=='"' || $c==$curlyquote || $c==$curlylowquote || $c=="\xef\xbc\x8c" || $c=="\xef\xbc\x8e" || $c=="\xe3\x80\x81" || $c=="\xe3\x80\x82") {$check++; }
else { $check = 0; }
// There's an orphan '. ' or ', ' or 32 about to be cut off at the end of line
if($check==1) {
$currContent .= $c;
$cutoffWidth = $contentWidth;
$contentWidth += $cw;
continue;
}
if(($this->SUP || $this->SUB) && ($orphs < $this->orphansAllowed)) { // ? disable orphans in table if borders used
$currContent .= $c;
$cutoffWidth = $contentWidth;
$contentWidth += $cw;
$orphs++;
continue;
}
else { $orphs = 0; }
// ADDED for Paragraph_indent
$WidthCorrection = 0;
if (($newblock) && ($blockstate==1 || $blockstate==3) && isset($this->blk[$this->blklvl]['text_indent']) && ($lineCount == 0) && (!$is_table) && (!$is_list) && ($align != 'C')) {
$ti = $this->ConvertSize($this->blk[$this->blklvl]['text_indent'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
$WidthCorrection = ($ti*$this->k);
}
// Added mPDF 3.0 Float DIV
$fpaddingR = 0;
$fpaddingL = 0;
$usey = $this->y + 0.002;
if (($newblock) && ($blockstate==1 || $blockstate==3) && ($lineCount == 0) ) {
$usey += $this->blk[$this->blklvl]['margin_top'] + $this->blk[$this->blklvl]['padding_top'] + $this->blk[$this->blklvl]['border_top']['w'];
}
// try adding another char
if (( $contentWidth + $cw > $maxWidth - $WidthCorrection - (($this->cMarginL+$this->cMarginR)*$this->k) - ($paddingL+$paddingR +(($fpaddingL + $fpaddingR) * $this->k) ) + 0.001)) {// 0.001 is to correct for deviations converting mm=>pts
// it won't fit, output what we already have
$lineCount++;
// contains any content that didn't make it into this print
$savedContent = '';
$savedFont = array();
$savedObj = array();
// mPDF 5.0
// CJK - allow to split anywhere, but strip CJK space at end of line
// = \xe3\x80\x80 = CJK space
if ($this->checkCJK && preg_match("/([".$this->pregCJKchars."])/u", $c)) {
$words = array(); $words[] = preg_replace("/\xe3\x80\x80$/",'',$currContent) ;
}
// cut off and save any partial words at the end of the string
else {
$words = explode( ' ', $currContent );
///////////////////
// HYPHENATION
$currWord = $words[count($words)-1] ;
$success = false;
} // *CJK*
// if it looks like we didn't finish any words for this chunk
if ( count( $words ) == 1 ) {
// TO correct for error when word too wide for page - but only when one long word from left to right margin
if (count($content) == 1 && $currContent != ' ') {
$lastContent = $words[0];
$savedFont = $this->saveFont();
// replace the current content with the cropped version
$currContent = rtrim( $lastContent );
}
else {
// save and crop off the content currently on the stack
$savedContent = array_pop( $content );
$savedFont = array_pop( $font );
// trim any trailing spaces off the last bit of content
$currContent =& $content[ count( $content ) - 1 ];
$currContent = rtrim( $currContent );
}
}
else { // otherwise, we need to find which bit to cut off
$lastContent = '';
for ( $w = 0; $w < count( $words ) - 1; $w++) { $lastContent .= $words[ $w ]." "; }
$savedContent = $words[ count( $words ) - 1 ];
$savedFont = $this->saveFont();
// replace the current content with the cropped version
$currContent = rtrim( $lastContent );
}
if (isset($this->objectbuffer[(count($content)-1)]) && $this->objectbuffer[(count($content)-1)]['type']=='dottab') {
$savedObj = array_pop( $this->objectbuffer );
$contentWidth -= ($this->objectbuffer[(count($content)-1)]['OUTER-WIDTH'] * $this->k);
}
// Set Current lineheight (correction factor)
$lhfixed = false;
if ($is_list) {
if (preg_match('/([0-9.,]+)mm/',$this->list_lineheight[$this->listlvl][$this->listOcc],$am)) {
$lhfixed = true;
$def_fontsize = $this->InlineProperties['LISTITEM'][$this->listlvl][$this->listOcc][$this->listnum]['size'];
$this->lineheight_correction = $am[1] / $def_fontsize ;
}
else {
$this->lineheight_correction = $this->list_lineheight[$this->listlvl][$this->listOcc];
}
}
else
if (isset($this->blk[$this->blklvl]['line_height']) && $this->blk[$this->blklvl]['line_height']) {
if (preg_match('/([0-9.,]+)mm/',$this->blk[$this->blklvl]['line_height'],$am)) {
$lhfixed = true;
$def_fontsize = $this->blk[$this->blklvl]['InlineProperties']['size']; // needs to be default font-size for block ****
$this->lineheight_correction = $am[1] / $def_fontsize ;
}
else {
$this->lineheight_correction = $this->blk[$this->blklvl]['line_height'];
}
}
else {
$this->lineheight_correction = $this->normalLineheight;
}
// update $contentWidth and $cutoffWidth since they changed with cropping
// Also correct lineheight to maximum fontsize (not for tables)
$contentWidth = 0;
// correct lineheight to maximum fontsize
if ($lhfixed) { $maxlineHeight = $this->lineheight; }
else { $maxlineHeight = 0; }
$this->forceExactLineheight = true;
$maxfontsize = 0;
foreach ( $content as $k => $chunk )
{
$this->restoreFont( $font[ $k ]);
if (!isset($this->objectbuffer[$k])) {
if (!$this->usingCoreFont) {
$content[$k] = $chunk = str_replace("\xc2\xad",'',$chunk );
}
// Soft Hyphens chr(173)
else if ($this->FontFamily!='csymbol' && $this->FontFamily!='czapfdingbats') {
$content[$k] = $chunk = str_replace($this->chrs[173],'',$chunk );
}
$contentWidth += $this->GetStringWidth( $chunk ) * $this->k;
if (!$lhfixed) { $maxlineHeight = max($maxlineHeight,$this->FontSize * $this->lineheight_correction ); }
if ($lhfixed && ($this->FontSize > $def_fontsize || ($this->FontSize > ($lineHeight * $this->lineheight_correction) && $is_list))) {
$this->forceExactLineheight = false;
}
$maxfontsize = max($maxfontsize,$this->FontSize);
}
}
$lastfontreqstyle = $font[count($font)-1]['ReqFontStyle'];
$lastfontstyle = $font[count($font)-1]['style'];
if ($this->directionality == 'ltr' && strpos($lastfontreqstyle,"I") !== false && strpos($lastfontstyle,"I") === false) { // Artificial italic
$lastitalic = $this->FontSize*0.15*$this->k;
}
else { $lastitalic = 0; }
if ($is_list && is_array($this->bulletarray) && $this->bulletarray) {
$actfs = $this->bulletarray['fontsize'];
if (!$lhfixed) { $maxlineHeight = max($maxlineHeight,$actfs * $this->lineheight_correction ); }
if ($lhfixed && $actfs > $def_fontsize) { $this->forceExactLineheight = false; }
$maxfontsize = max($maxfontsize,$actfs);
}
// when every text item checked i.e. $maxfontsize is set properly
$af = 0; // Above font
$bf = 0; // Below font
$mta = 0; // Maximum top-aligned
$mba = 0; // Maximum bottom-aligned
foreach ( $content as $k => $chunk ) {
if (isset($this->objectbuffer[$k]) && $this->objectbuffer[$k]) {
$contentWidth += $this->objectbuffer[$k]['OUTER-WIDTH'] * $this->k;
$oh = $this->objectbuffer[$k]['OUTER-HEIGHT'];
$va = $this->objectbuffer[$k]['vertical-align']; // = $objattr['vertical-align'] = set as M,T,B,S
if ($lhfixed && $oh > $def_fontsize) { $this->forceExactLineheight = false; }
if ($va == 'BS') { // (BASELINE default)
$af = max($af, ($oh - ($maxfontsize * (0.5 + $this->baselineC))));
}
else if ($va == 'M') {
$af = max($af, ($oh - $maxfontsize)/2);
$bf = max($bf, ($oh - $maxfontsize)/2);
}
else if ($va == 'TT') {
$bf = max($bf, ($oh - $maxfontsize));
}
else if ($va == 'TB') {
$af = max($af, ($oh - $maxfontsize));
}
else if ($va == 'T') {
$mta = max($mta, $oh);
}
else if ($va == 'B') {
$mba = max($mba, $oh);
}
}
}
if ((!$lhfixed || !$this->forceExactLineheight) && ($af > (($maxlineHeight - $maxfontsize)/2) || $bf > (($maxlineHeight - $maxfontsize)/2))) {
$maxlineHeight = $maxfontsize + $af + $bf;
}
else if (!$lhfixed) { $af = $bf = ($maxlineHeight - $maxfontsize)/2; }
if ($mta > $maxlineHeight) {
$bf += ($mta - $maxlineHeight);
$maxlineHeight = $mta;
}
if ($mba > $maxlineHeight) {
$af += ($mba - $maxlineHeight);
$maxlineHeight = $mba;
}
$lineHeight = $maxlineHeight;
$cutoffWidth = $contentWidth;
// If NOT images, and maxfontsize NOT > lineHeight - this value determines text baseline positioning
if ($lhfixed && $af==0 && $bf==0 && $maxfontsize<=($def_fontsize * $this->lineheight_correction * 0.8 )) {
$this->linemaxfontsize = $def_fontsize;
}
else { $this->linemaxfontsize = $maxfontsize; }
// JUSTIFICATION J
$nb_carac = 0;
$nb_spaces = 0;
// 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)
if(( $align == 'J' ) || ($cutoffWidth + $lastitalic > $maxWidth - $WidthCorrection - (($this->cMarginL+$this->cMarginR)*$this->k) - ($paddingL+$paddingR +(($fpaddingL + $fpaddingR) * $this->k) ) + 0.001)) { // 0.001 is to correct for deviations converting mm=>pts
// JUSTIFY J (Use character spacing)
// WORD SPACING
foreach ( $content as $k => $chunk ) {
if (!isset($this->objectbuffer[$k]) || (isset($this->objectbuffer[$k]) && !$this->objectbuffer[$k])) {
if ($this->usingCoreFont) {
$chunk = str_replace($this->chrs[160],$this->chrs[32],$chunk );
}
else {
$chunk = str_replace($this->chrs[194].$this->chrs[160],$this->chrs[32],$chunk );
}
$nb_carac += mb_strlen( $chunk, $this->mb_enc ) ;
$nb_spaces += mb_substr_count( $chunk,' ', $this->mb_enc ) ;
}
}
list($charspacing,$ws) = $this->GetJspacing($nb_carac,$nb_spaces,($maxWidth-$lastitalic-$cutoffWidth-$WidthCorrection-(($this->cMarginL+$this->cMarginR)*$this->k)-($paddingL+$paddingR +(($fpaddingL + $fpaddingR) * $this->k) )));
$this->SetSpacing($charspacing,$ws);
}
// otherwise, we want normal spacing
else {
$this->ResetSpacing();
}
// WORD SPACING
$empty = $maxWidth - $lastitalic-$WidthCorrection - $contentWidth - (($this->cMarginL+$this->cMarginR)* $this->k) - ($paddingL+$paddingR +(($fpaddingL + $fpaddingR) * $this->k) ) - ( $this->charspacing * $nb_carac) - ( $this->ws * $nb_spaces);
$empty /= $this->k;
$b = ''; //do not use borders
// Get PAGEBREAK TO TEST for height including the top border/padding
$check_h = max($this->divheight,$lineHeight);
if (($newblock) && ($blockstate==1 || $blockstate==3) && ($this->blklvl > 0) && ($lineCount == 1) && (!$is_table) && (!$is_list)) {
$check_h += ($this->blk[$this->blklvl]['padding_top'] + $this->blk[$this->blklvl]['margin_top'] + $this->blk[$this->blklvl]['border_top']['w']);
}
if ($this->ColActive && $check_h > ($this->PageBreakTrigger - $this->y0)) { $this->CurrCol = $this->NbCol; }
// PAGEBREAK
// 'If' below used in order to fix "first-line of other page with justify on" bug
if(!$is_table && ($this->y+$check_h) > $this->PageBreakTrigger and !$this->InFooter and $this->AcceptPageBreak()) {
$bak_x=$this->x;//Current X position
// WORD SPACING
$ws=$this->ws;//Word Spacing
$charspacing=$this->charspacing;//Character Spacing
$this->ResetSpacing();
$this->AddPage($this->CurOrientation);
$this->x = $bak_x;
// Added to correct for OddEven Margins
$currentx += $this->MarginCorrection;
$this->x += $this->MarginCorrection;
// WORD SPACING
$this->SetSpacing($charspacing,$ws);
}
// mPDF 5.0
if ($this->keep_block_together && !$is_table && $this->kt_p00 < $this->page && ($this->y+$check_h) > $this->kt_y00) {
$this->printdivbuffer();
$this->keep_block_together = 0;
}
// TOP MARGIN
if (($newblock) && ($blockstate==1 || $blockstate==3) && ($this->blk[$this->blklvl]['margin_top']) && ($lineCount == 1) && (!$is_table) && (!$is_list)) {
$this->DivLn($this->blk[$this->blklvl]['margin_top'],$this->blklvl-1,true,$this->blk[$this->blklvl]['margin_collapse']);
}
// Update y0 for top of block (used to paint border)
if (($newblock) && ($blockstate==1 || $blockstate==3) && ($lineCount == 1) && (!$is_table) && (!$is_list)) {
$this->blk[$this->blklvl]['y0'] = $this->y;
$this->blk[$this->blklvl]['startpage'] = $this->page;
}
// TOP PADDING and BORDER spacing/fill
if (($newblock) && ($blockstate==1 || $blockstate==3) && (($this->blk[$this->blklvl]['padding_top']) || ($this->blk[$this->blklvl]['border_top'])) && ($lineCount == 1) && (!$is_table) && (!$is_list)) {
// $state = 0 normal; 1 top; 2 bottom; 3 top and bottom
$this->DivLn($this->blk[$this->blklvl]['padding_top'] + $this->blk[$this->blklvl]['border_top']['w'],-3,true,false,1);
}
$arraysize = count($content);
$margins = ($this->cMarginL+$this->cMarginR) + ($ipaddingL+$ipaddingR + $fpaddingR + $fpaddingR );
// PAINT BACKGROUND FOR THIS LINE
if (!$is_table) { $this->DivLn($lineHeight,$this->blklvl,false); } // false -> don't advance y
$this->x = $currentx + $this->cMarginL + $ipaddingL + $fpaddingL ;
if ($align == 'R') { $this->x += $empty; }
else if ($align == 'C') { $this->x += ($empty / 2); }
// Paragraph INDENT
if (isset($this->blk[$this->blklvl]['text_indent']) && ($newblock) && ($blockstate==1 || $blockstate==3) && ($lineCount == 1) && (!$is_table) && ($this->directionality!='rtl') && ($align !='C')) {
$ti = $this->ConvertSize($this->blk[$this->blklvl]['text_indent'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
$this->x += $ti;
}
// DIRECTIONALITY RTL
$all_rtl = false;
$contains_rtl = false;
foreach ( $content as $k => $chunk ) {
// FOR IMAGES - UPDATE POSITION
if (($this->directionality=='rtl' && $contains_rtl) || $all_rtl) { $dirk = $arraysize-1 - $k ; } else { $dirk = $k; }
$va = 'M'; // default for text
if (isset($this->objectbuffer[$dirk]) && $this->objectbuffer[$dirk]) {
$xadj = $this->x - $this->objectbuffer[$dirk]['OUTER-X'] ;
$this->objectbuffer[$dirk]['OUTER-X'] += $xadj;
$this->objectbuffer[$dirk]['BORDER-X'] += $xadj;
$this->objectbuffer[$dirk]['INNER-X'] += $xadj;
$va = $this->objectbuffer[$dirk]['vertical-align'];
$yadj = $this->y - $this->objectbuffer[$dirk]['OUTER-Y'];
if ($va == 'BS') {
$yadj += $af + ($this->linemaxfontsize * (0.5 + $this->baselineC)) - $this->objectbuffer[$dirk]['OUTER-HEIGHT'];
}
else if ($va == 'M' || $va == '') {
$yadj += $af + ($this->linemaxfontsize /2) - ($this->objectbuffer[$dirk]['OUTER-HEIGHT']/2);
}
else if ($va == 'TB') {
$yadj += $af + $this->linemaxfontsize - $this->objectbuffer[$dirk]['OUTER-HEIGHT'];
}
else if ($va == 'TT') {
$yadj += $af;
}
else if ($va == 'B') {
$yadj += $af + $this->linemaxfontsize + $bf - $this->objectbuffer[$dirk]['OUTER-HEIGHT'];
}
else if ($va == 'T') {
$yadj += 0;
}
$this->objectbuffer[$dirk]['OUTER-Y'] += $yadj;
$this->objectbuffer[$dirk]['BORDER-Y'] += $yadj;
$this->objectbuffer[$dirk]['INNER-Y'] += $yadj;
}
// DIRECTIONALITY RTL
if ((($this->directionality == 'rtl') && ($contains_rtl )) || ($all_rtl )) { $this->restoreFont($font[$arraysize-1 - $k]); }
else { $this->restoreFont( $font[ $k ] ); }
// *********** SPAN BACKGROUND COLOR ***************** //
if ($this->spanbgcolor) {
$cor = $this->spanbgcolorarray;
$this->SetFillColor($cor['R'],$cor['G'],$cor['B']);
$save_fill = $fill; $spanfill = 1; $fill = 1;
}
// WORD SPACING
$stringWidth = $this->GetStringWidth($chunk ) + ( $this->charspacing * mb_strlen($chunk,$this->mb_enc ) / $this->k )
+ ( $this->ws * mb_substr_count($chunk,' ',$this->mb_enc ) / $this->k );
if (isset($this->objectbuffer[$dirk])) { $stringWidth = $this->objectbuffer[$dirk]['OUTER-WIDTH']; }
if ($stringWidth==0) { $stringWidth = 0.000001; } // mPDF 5.0
if ($k == $arraysize-1) {
$stringWidth -= ( $this->charspacing / $this->k );
$this->Cell( $stringWidth, $lineHeight, $chunk, '', 1, '', $fill, $this->HREF , $currentx,0,0,'M', $fill, $af, $bf ); //mono-style line or last part (skips line)
}
else $this->Cell( $stringWidth, $lineHeight, $chunk, '', 0, '', $fill, $this->HREF, 0, 0,0,'M', $fill, $af, $bf );//first or middle part
// *********** SPAN BACKGROUND COLOR OFF - RESET BLOCK BGCOLOR ***************** //
if (isset($spanfill) && $spanfill) {
$fill = $save_fill; $spanfill = 0;
if ($fill) { $this->SetFillColor($bcor['R'],$bcor['G'],$bcor['B']); }
}
}
if (!$is_table) {
$this->maxPosR = max($this->maxPosR , ($this->w - $this->rMargin - $this->blk[$this->blklvl]['outer_right_margin']));
$this->maxPosL = min($this->maxPosL , ($this->lMargin + $this->blk[$this->blklvl]['outer_left_margin']));
}
// move on to the next line, reset variables, tack on saved content and current char
$this->printobjectbuffer($is_table);
$this->objectbuffer = array();
// LIST BULLETS/NUMBERS
if ($is_list && is_array($this->bulletarray) && ($lineCount == 1) ) {
$this->ResetSpacing();
$bull = $this->bulletarray;
if (isset($bull['level']) && isset($bull['occur']) && isset($this->InlineProperties['LIST'][$bull['level']][$bull['occur']])) {
$this->restoreInlineProperties($this->InlineProperties['LIST'][$bull['level']][$bull['occur']]);
}
if (isset($bull['level']) && isset($bull['occur']) && isset($bull['num']) && isset($this->InlineProperties['LISTITEM'][$bull['level']][$bull['occur']][$bull['num']]) && $this->InlineProperties['LISTITEM'][$bull['level']][$bull['occur']][$bull['num']]) { $this->restoreInlineProperties($this->InlineProperties['LISTITEM'][$bull['level']][$bull['occur']][$bull['num']]); }
if (isset($bull['font']) && $bull['font'] == 'czapfdingbats') {
$this->bullet = true;
$this->SetFont('czapfdingbats','',$this->FontSizePt/2.5);
}
else { $this->SetFont($this->FontFamily,$this->FontStyle,$this->FontSizePt,true,true); } // force output
//Output bullet
$this->x = $currentx;
if (isset($bull['x'])) { $this->x += $bull['x']; }
$this->y -= $lineHeight;
if (isset($bull['txt'])) { $this->Cell($bull['w'], $lineHeight,$bull['txt'],'','',$bull['align'],0,'',0,-$this->cMarginL, -$this->cMarginR ); }
if (isset($bull['font']) && $bull['font'] == 'czapfdingbats') {
$this->bullet = false;
}
$this->x = $currentx; // Reset
$this->y += $lineHeight;
$this->bulletarray = array(); // prevents repeat of bullet/number if ....
.....
}
// Reset lineheight
$lineHeight = $this->divheight;
$valign = 'M';
$this->restoreFont( $savedFont );
$font = array();
$content = array();
$contentWidth = 0;
if (!empty($savedObj)) {
$this->objectbuffer[] = $savedObj;
$font[] = $savedFont;
$content[] = '';
$contentWidth += $savedObj['OUTER-WIDTH'] * $this->k;
}
$font[] = $savedFont;
$content[] = $savedContent . $c;
$currContent =& $content[ (count($content)-1) ];
$contentWidth += $this->GetStringWidth( $currContent ) * $this->k;
$cutoffWidth = $contentWidth;
}
// another character will fit, so add it on
else {
$contentWidth += $cw;
$currContent .= $c;
}
}
unset($content);
}
//----------------------END OF FLOWING BLOCK------------------------------------//
////////////////////////////////////////////////////////////////////////////////
// ADDED forcewrap - to call from inline OBJECT functions to breakwords if necessary in cell
////////////////////////////////////////////////////////////////////////////////
function WordWrap(&$text, $maxwidth, $forcewrap = 0) {
$biggestword=0;
$toonarrow=false;
$text = trim($text);
if ($text==='') return 0;
$space = $this->GetStringWidth(' ');
$lines = explode("\n", $text);
$text = '';
$count = 0;
foreach ($lines as $line) {
$words = explode(' ', $line);
$width = 0;
foreach ($words as $word) {
$word = trim($word);
$wordwidth = $this->GetStringWidth($word);
//Warn user that maxwidth is insufficient
if ($wordwidth > $maxwidth + 0.0001) {
if ($wordwidth > $biggestword) { $biggestword = $wordwidth; }
$toonarrow=true;
// ADDED
if ($forcewrap) {
while($wordwidth > $maxwidth) {
$chw = 0; // check width
for ( $i = 0; $i < mb_strlen($word, $this->mb_enc ); $i++ ) {
$chw = $this->GetStringWidth(mb_substr($word,0,$i+1,$this->mb_enc ));
if ($chw > $maxwidth ) {
if ($text) {
$text = rtrim($text)."\n".mb_substr($word,0,$i,$this->mb_enc );
$count++;
}
else {
$text = mb_substr($word,0,$i,$this->mb_enc );
}
$word = mb_substr($word,$i,mb_strlen($word, $this->mb_enc )-$i,$this->mb_enc );
$wordwidth = $this->GetStringWidth($word);
$width = $maxwidth;
break;
}
}
}
}
}
if ($width + $wordwidth < $maxwidth - 0.0001) {
$width += $wordwidth + $space;
$text .= $word.' ';
}
else {
$width = $wordwidth + $space;
$text = rtrim($text)."\n".$word.' ';
$count++;
}
}
$text = rtrim($text)."\n";
$count++;
}
$text = rtrim($text);
//Return -(wordsize) if word is bigger than maxwidth
// ADDED
if ($forcewrap) { return $count; }
if (($toonarrow) && ($this->table_error_report)) {
$this->Error("Word is too long to fit in table - ".$this->table_error_report_param);
}
if ($toonarrow) return -$biggestword;
else return $count;
}
function _SetTextRendering($mode) {
if (!(($mode == 0) || ($mode == 1) || ($mode == 2)))
$this->Error("Text rendering mode should be 0, 1 or 2 (value : $mode)");
$tr = ($mode.' Tr');
if($this->page>0 && ((isset($this->pageoutput[$this->page]['TextRendering']) && $this->pageoutput[$this->page]['TextRendering'] != $tr) || !isset($this->pageoutput[$this->page]['TextRendering']) || $this->keep_block_together)) { $this->_out($tr); }
$this->pageoutput[$this->page]['TextRendering'] = $tr;
}
function SetTextOutline($width, $r=0, $g=-1, $b=-1) {
if ($width == false) //Now resets all values
{
$this->outline_on = false;
$this->SetLineWidth(0.2);
$this->SetDrawColor(0);
$this->_SetTextRendering(0);
$tr = ('0 Tr');
if($this->page>0 && ((isset($this->pageoutput[$this->page]['TextRendering']) && $this->pageoutput[$this->page]['TextRendering'] != $tr) || !isset($this->pageoutput[$this->page]['TextRendering']) || $this->keep_block_together)) { $this->_out($tr); }
$this->pageoutput[$this->page]['TextRendering'] = $tr;
}
else
{
$this->SetLineWidth($width);
$this->SetDrawColor($r, $g , $b);
$tr = ('2 Tr');
if($this->page>0 && ((isset($this->pageoutput[$this->page]['TextRendering']) && $this->pageoutput[$this->page]['TextRendering'] != $tr) || !isset($this->pageoutput[$this->page]['TextRendering']) || $this->keep_block_together)) { $this->_out($tr); }
$this->pageoutput[$this->page]['TextRendering'] = $tr;
}
}
function Image($file,$x,$y,$w=0,$h=0,$type='',$link='',$paint=true, $constrain=true, $watermark=false, $shownoimg=true, $allowvector=true) {
$orig_srcpath = $file;
$this->GetFullPath($file);
$info=$this->_getImage($file, true, $allowvector, $orig_srcpath );
if(!$info && $paint) {
$info = $this->_getImage($this->noImageFile);
if ($info) {
$file = $this->noImageFile;
$w = ($info['w'] * (25.4/$this->dpi)); // 14 x 16px
$h = ($info['h'] * (25.4/$this->dpi)); // 14 x 16px
}
}
if(!$info) return false;
//Automatic width and height calculation if needed
if($w==0 and $h==0) {
if ($info['type']=='svg') {
// returned SVG units are pts
// divide by k to get user units (mm)
$w = abs($info['w'])/$this->k;
$h = abs($info['h']) /$this->k;
}
else {
//Put image at default image dpi
$w=($info['w']/$this->k) * (72/$this->img_dpi);
$h=($info['h']/$this->k) * (72/$this->img_dpi);
}
}
if($w==0) $w=abs($h*$info['w']/$info['h']);
if($h==0) $h=abs($w*$info['h']/$info['w']);
if ($constrain) {
// Automatically resize to maximum dimensions of page if too large
if (isset($this->blk[$this->blklvl]['inner_width']) && $this->blk[$this->blklvl]['inner_width']) { $maxw = $this->blk[$this->blklvl]['inner_width']; }
else { $maxw = $this->pgwidth; }
if ($w > $maxw) {
$w = $maxw;
$h=abs($w*$info['h']/$info['w']);
}
if ($h > $this->h - ($this->tMargin + $this->bMargin + 10)) { // see below - +10 to avoid drawing too close to border of page
$h = $this->h - ($this->tMargin + $this->bMargin + 10) ;
if ($this->fullImageHeight) { $h = $this->fullImageHeight; }
$w=abs($h*$info['w']/$info['h']);
}
//Avoid drawing out of the paper(exceeding width limits).
//if ( ($x + $w) > $this->fw ) {
if ( ($x + $w) > $this->w ) {
$x = $this->lMargin;
$y += 5;
}
$changedpage = false;
$oldcolumn = $this->CurrCol;
//Avoid drawing out of the page.
if($y+$h>$this->PageBreakTrigger and !$this->InFooter and $this->AcceptPageBreak()) {
$this->AddPage($this->CurOrientation);
// Added to correct for OddEven Margins
$x=$x +$this->MarginCorrection;
$y = $tMargin + $this->margin_header;
$changedpage = true;
}
} // end of IF constrain
if ($info['type']=='svg') {
$sx = $w*$this->k / $info['w'];
$sy = -$h*$this->k / $info['h'];
$outstring = sprintf('q %.3f 0 0 %.3f %.3f %.3f cm /FO%d Do Q', $sx, $sy, $x*$this->k-$sx*$info['x'], (($this->h-$y)*$this->k)-$sy*$info['y'], $info['i']);
}
else {
$outstring = sprintf("q %.3f 0 0 %.3f %.3f %.3f cm /I%d Do Q",$w*$this->k,$h*$this->k,$x*$this->k,($this->h-($y+$h))*$this->k,$info['i']);
}
if($paint) {
$this->_out($outstring);
if($link) $this->Link($x,$y,$w,$h,$link);
// Avoid writing text on top of the image. // THIS WAS OUTSIDE THE if ($paint) bit!!!!!!!!!!!!!!!!
$this->y = $y + $h;
}
//Return width-height array
$sizesarray['WIDTH'] = $w;
$sizesarray['HEIGHT'] = $h;
$sizesarray['X'] = $x; //Position before painting image
$sizesarray['Y'] = $y; //Position before painting image
$sizesarray['OUTPUT'] = $outstring;
$sizesarray['IMAGE_ID'] = $info['i'];
return $sizesarray;
}
//=============================================================
//=============================================================
//=============================================================
//=============================================================
//=============================================================
function _getObjAttr($t) {
$c = explode("\xbb\xa4\xac",$t,2);
$c = explode(",",$c[1],2);
foreach($c as $v) {
$v = explode("=",$v,2);
$sp[$v[0]] = $v[1];
}
return (unserialize($sp['objattr']));
}
function inlineObject($type,$x,$y,$objattr,$Lmargin,$widthUsed,$maxWidth,$lineHeight,$paint=false,$is_table=false)
{
if ($is_table) { $k = $this->shrin_k; } else { $k = 1; }
// NB $x is only used when paint=true
// Lmargin not used
$w = 0;
if (isset($objattr['width'])) { $w = $objattr['width']/$k; }
$h = 0;
if (isset($objattr['height'])) { $h = abs($objattr['height']/$k); }
$widthLeft = $maxWidth - $widthUsed;
$maxHeight = $this->h - ($this->tMargin + $this->bMargin + 10) ;
if ($this->fullImageHeight) { $maxHeight = $this->fullImageHeight; }
// For Images
if (isset($objattr['border_left'])) {
$extraWidth = ($objattr['border_left']['w'] + $objattr['border_right']['w'] + $objattr['margin_left']+ $objattr['margin_right'])/$k;
$extraHeight = ($objattr['border_top']['w'] + $objattr['border_bottom']['w'] + $objattr['margin_top']+ $objattr['margin_bottom'])/$k;
if ($type == 'image' || $type == 'barcode') {
$extraWidth += ($objattr['padding_left'] + $objattr['padding_right'])/$k;
$extraHeight += ($objattr['padding_top'] + $objattr['padding_bottom'])/$k;
}
}
if (!isset($objattr['vertical-align'])) { $objattr['vertical-align'] = 'M'; }
if ($type == 'image' || (isset($objattr['subtype']) && $objattr['subtype'] == 'IMAGE')) {
if (isset($objattr['itype']) && ($objattr['itype'] == 'wmf' || $objattr['itype'] == 'svg')) {
$file = $objattr['file'];
$info=$this->formobjects[$file];
}
else if (isset($objattr['file'])) {
$file = $objattr['file'];
$info=$this->images[$file];
}
}
if ($type == 'annot' || $type == 'bookmark' || $type == 'indexentry' || $type == 'toc') {
$w = 0.00001;
$h = 0.00001;
}
// TEST whether need to skipline
if (!$paint) {
if ($type == 'hr') { // always force new line
if (($y + $h + $lineHeight > $this->PageBreakTrigger) && !$this->InFooter && !$is_table) { return array(-2, $w ,$h ); } // New page + new line
else { return array(1, $w ,$h ); } // new line
}
else {
if ($widthUsed > 0 && $w > $widthLeft && (!$is_table || $type != 'image')) { // New line needed
if (($y + $h + $lineHeight > $this->PageBreakTrigger) && !$this->InFooter) { return array(-2,$w ,$h ); } // New page + new line
return array(1,$w ,$h ); // new line
}
else if ($widthUsed > 0 && $w > $widthLeft && $is_table) { // New line needed in TABLE
return array(1,$w ,$h ); // new line
}
// Will fit on line but NEW PAGE REQUIRED
else if (($y + $h > $this->PageBreakTrigger) && !$this->InFooter && !$is_table) { return array(-1,$w ,$h ); }
else { return array(0,$w ,$h ); }
}
}
if ($type == 'annot' || $type == 'bookmark' || $type == 'indexentry' || $type == 'toc') {
$w = 0.00001;
$h = 0.00001;
$objattr['BORDER-WIDTH'] = 0;
$objattr['BORDER-HEIGHT'] = 0;
$objattr['BORDER-X'] = $x;
$objattr['BORDER-Y'] = $y;
$objattr['INNER-WIDTH'] = 0;
$objattr['INNER-HEIGHT'] = 0;
$objattr['INNER-X'] = $x;
$objattr['INNER-Y'] = $y;
}
if ($type == 'image') {
// Automatically resize to width remaining
if ($w > $widthLeft && !$is_table) {
$w = $widthLeft ;
$h=abs($w*$info['h']/$info['w']);
}
$img_w = $w - $extraWidth ;
$img_h = $h - $extraHeight ;
$objattr['BORDER-WIDTH'] = $img_w + $objattr['padding_left']/$k + $objattr['padding_right']/$k + (($objattr['border_left']['w']/$k + $objattr['border_right']['w']/$k)/2) ;
$objattr['BORDER-HEIGHT'] = $img_h + $objattr['padding_top']/$k + $objattr['padding_bottom']/$k + (($objattr['border_top']['w']/$k + $objattr['border_bottom']['w']/$k)/2) ;
$objattr['BORDER-X'] = $x + $objattr['margin_left']/$k + (($objattr['border_left']['w']/$k)/2) ;
$objattr['BORDER-Y'] = $y + $objattr['margin_top']/$k + (($objattr['border_top']['w']/$k)/2) ;
$objattr['INNER-WIDTH'] = $img_w;
$objattr['INNER-HEIGHT'] = $img_h;
$objattr['INNER-X'] = $x + $objattr['padding_left']/$k + $objattr['margin_left']/$k + ($objattr['border_left']['w']/$k);
$objattr['INNER-Y'] = $y + $objattr['padding_top']/$k + $objattr['margin_top']/$k + ($objattr['border_top']['w']/$k) ;
$objattr['ID'] = $info['i'];
}
if ($type == 'input' && $objattr['subtype'] == 'IMAGE') {
$img_w = $w - $extraWidth ;
$img_h = $h - $extraHeight ;
$objattr['BORDER-WIDTH'] = $img_w + (($objattr['border_left']['w']/$k + $objattr['border_right']['w']/$k)/2) ;
$objattr['BORDER-HEIGHT'] = $img_h + (($objattr['border_top']['w']/$k + $objattr['border_bottom']['w']/$k)/2) ;
$objattr['BORDER-X'] = $x + $objattr['margin_left']/$k + (($objattr['border_left']['w']/$k)/2) ;
$objattr['BORDER-Y'] = $y + $objattr['margin_top']/$k + (($objattr['border_top']['w']/$k)/2) ;
$objattr['INNER-WIDTH'] = $img_w;
$objattr['INNER-HEIGHT'] = $img_h;
$objattr['INNER-X'] = $x + $objattr['margin_left']/$k + ($objattr['border_left']['w']/$k);
$objattr['INNER-Y'] = $y + $objattr['margin_top']/$k + ($objattr['border_top']['w']/$k) ;
$objattr['ID'] = $info['i'];
}
if ($type == 'textarea') {
// Automatically resize to width remaining
if ($w > $widthLeft && !$is_table) {
$w = $widthLeft ;
}
if (($y + $h > $this->PageBreakTrigger) && !$this->InFooter) {
$h=$this->h - $y - $this->bMargin;
}
}
if ($type == 'hr') {
if ($is_table) {
$objattr['INNER-WIDTH'] = $maxWidth * $objattr['W-PERCENT']/100;
$objattr['width'] = $objattr['INNER-WIDTH'];
$w = $maxWidth;
}
else {
if ($w>$maxWidth) { $w = $maxWidth; }
$objattr['INNER-WIDTH'] = $w;
$w = $maxWidth;
}
}
if (($type == 'select') || ($type == 'input' && ($objattr['subtype'] == 'TEXT' || $objattr['subtype'] == 'PASSWORD'))) {
// Automatically resize to width remaining
if ($w > $widthLeft && !$is_table) {
$w = $widthLeft;
}
}
if ($type == 'textarea' || $type == 'select' || $type == 'input') {
if (isset($objattr['fontsize'])) $objattr['fontsize'] /= $k;
if (isset($objattr['linewidth'])) $objattr['linewidth'] /= $k;
}
if (!isset($objattr['BORDER-Y'])) { $objattr['BORDER-Y'] = 0; }
if (!isset($objattr['BORDER-X'])) { $objattr['BORDER-X'] = 0; }
if (!isset($objattr['INNER-Y'])) { $objattr['INNER-Y'] = 0; }
if (!isset($objattr['INNER-X'])) { $objattr['INNER-X'] = 0; }
//Return width-height array
$objattr['OUTER-WIDTH'] = $w;
$objattr['OUTER-HEIGHT'] = $h;
$objattr['OUTER-X'] = $x;
$objattr['OUTER-Y'] = $y;
return $objattr;
}
//=============================================================
//=============================================================
//=============================================================
//=============================================================
//=============================================================
function SetDash($black=false,$white=false)
{
if($black and $white) $s=sprintf('[%.3f %.3f] 0 d',$black*$this->k,$white*$this->k);
else $s='[] 0 d';
if($this->page>0 && ((isset($this->pageoutput[$this->page]['Dash']) && $this->pageoutput[$this->page]['Dash'] != $s) || !isset($this->pageoutput[$this->page]['Dash']) || $this->keep_block_together)) { $this->_out($s); }
$this->pageoutput[$this->page]['Dash'] = $s;
}
function SetDisplayPreferences($preferences) {
// String containing any or none of /HideMenubar/HideToolbar/HideWindowUI/DisplayDocTitle/CenterWindow/FitWindow
$this->DisplayPreferences .= $preferences;
}
function Ln($h='',$collapsible=0)
{
// Added collapsible to allow collapsible top-margin on new page
//Line feed; default value is last cell height
$this->x = $this->lMargin + $this->blk[$this->blklvl]['outer_left_margin'];
if ($collapsible && ($this->y==$this->tMargin) && (!$this->ColActive)) { $h = 0; }
if(is_string($h)) $this->y+=$this->lasth;
else $this->y+=$h;
}
// $state = 0 normal; 1 top; 2 bottom; 3 top and bottom
function DivLn($h,$level=-3,$move_y=true,$collapsible=false,$state=0) {
// this->x is returned as it was
// adds lines (y) where DIV bgcolors are filled in
// allows .00001 as nominal height used for bookmarks/annotations etc.
if ($collapsible && (sprintf("%0.4f", $this->y)==sprintf("%0.4f", $this->tMargin)) && (!$this->ColActive)) { return; }
// Still use this method if columns or page-break-inside: avoid, as it allows repositioning later
// otherwise, now uses PaintDivBB()
if (!$this->ColActive && !$this->keep_block_together && !$this->kwt) {
if ($move_y && !$this->ColActive) { $this->y += $h; }
return;
}
if ($level == -3) { $level = $this->blklvl; }
$firstblockfill = $this->GetFirstBlockFill();
if ($firstblockfill && $this->blklvl > 0 && $this->blklvl >= $firstblockfill) {
$last_x = 0;
$last_w = 0;
$last_fc = $this->FillColor;
$bak_x = $this->x;
$bak_h = $this->divheight;
$this->divheight = 0; // Temporarily turn off divheight - as Cell() uses it to check for PageBreak
for ($blvl=$firstblockfill;$blvl<=$level;$blvl++) {
$this->SetBlockFill($blvl);
$this->x = $this->lMargin + $this->blk[$blvl]['outer_left_margin'];
if ($last_x != $this->lMargin + $this->blk[$blvl]['outer_left_margin'] || $last_w != $this->blk[$blvl]['width'] || $last_fc != $this->FillColor) {
$x = $this->x;
$this->Cell( ($this->blk[$blvl]['width']), $h, '', '', 0, '', 1);
if (!$this->keep_block_together && !$this->writingHTMLheader && !$this->writingHTMLfooter) {
$this->x = $x;
// $state = 0 normal; 1 top; 2 bottom; 3 top and bottom
if ($blvl == $this->blklvl) { $this->PaintDivLnBorder($state,$blvl,$h); }
else { $this->PaintDivLnBorder(0,$blvl,$h); }
}
}
$last_x = $this->lMargin + $this->blk[$blvl]['outer_left_margin'];
$last_w = $this->blk[$blvl]['width'];
$last_fc = $this->FillColor;
}
// Reset current block fill
if (isset($this->blk[$this->blklvl]['bgcolorarray'])) {
$bcor = $this->blk[$this->blklvl]['bgcolorarray'];
$this->SetFillColor($bcor['R'],$bcor['G'],$bcor['B']);
}
$this->x = $bak_x;
$this->divheight = $bak_h;
}
if ($move_y) { $this->y += $h; }
}
function GetX()
{
//Get x position
return $this->x;
}
function SetX($x)
{
//Set x position
if($x >= 0) $this->x=$x;
else $this->x = $this->w + $x;
}
function GetY()
{
//Get y position
return $this->y;
}
function SetY($y)
{
//Set y position and reset x
$this->x=$this->lMargin;
if($y>=0)
$this->y=$y;
else
$this->y=$this->h+$y;
}
function SetXY($x,$y)
{
//Set x and y positions
$this->SetY($y);
$this->SetX($x);
}
function Output($name='',$dest='')
{
//Output PDF to some destination
global $_SERVER;
if ($this->showStats) {
echo 'Generated in '.sprintf('%.2f',(microtime(true) - $this->time0)).' seconds
';
}
//Finish document if necessary
if ($this->progressBar) { $this->UpdateProgressBar(1,'100','Finished'); }
if($this->state < 3) $this->Close();
if ($this->progressBar) { $this->UpdateProgressBar(2,'100','Finished'); }
// fn. error_get_last is only in PHP>=5.2
if ($this->debug && function_exists('error_get_last') && error_get_last()) {
$e = error_get_last();
if (($e['type'] < 2048 && $e['type'] != 8) || (intval($e['type']) & intval(ini_get("error_reporting")))) {
echo "Error message detected - PDF file generation aborted.
";
echo $e['message'].'
';
echo 'File: '.$e['file'].'
';
echo 'Line: '.$e['line'].'
';
exit;
}
}
if ($this->PDFA && $this->encrypted) { $this->Error("PDFA1-b does not permit encryption of documents."); }
if (count($this->PDFAwarnings) && $this->PDFA && !$this->PDFAauto) {
echo 'WARNING - This file could not be generated as it stands as a PDFA1-b compliant file.
';
echo 'These issues can be automatically fixed by mPDF using $mpdf->PDFAauto=true;
';
echo 'Action that mPDF will take to automatically force PDFA1-b compliance are shown in brackets.
';
echo 'Warning(s) generated:
';
foreach($this->PDFAwarnings AS $w) {
echo '- '.$w.'
';
}
echo '
';
exit;
}
if ($this->showStats) {
echo 'Compiled in '.sprintf('%.2f',(microtime(true) - $this->time0)).' seconds (total)
';
echo 'Peak Memory usage '.number_format((memory_get_peak_usage(true)/(1024*1024)),2).' MB
';
echo 'PDF file size '.number_format((strlen($this->buffer)/1024)).' kB
';
echo 'Number of fonts '.count($this->fonts).'
';
exit;
}
if(is_bool($dest)) $dest=$dest ? 'D' : 'F';
$dest=strtoupper($dest);
if($dest=='') {
if($name=='') {
$name='mpdf.pdf';
$dest='I';
}
else { $dest='F'; }
}
if ($this->progressBar && ($dest=='D' || $dest=='I')) {
if($name=='') { $name='mpdf.pdf'; }
$tempfile = '_tempPDF'.RAND(1,10000);
//Save to local file
$f=fopen(_MPDF_TEMP_PATH.$tempfile.'.pdf','wb');
if(!$f) $this->Error('Unable to create temporary output file: '.$tempfile.'.pdf');
fwrite($f,$this->buffer,strlen($this->buffer));
fclose($f);
$this->UpdateProgressBar(3,'','Finished');
echo '
';
exit;
}
else {
if ($this->progressBar) { $this->UpdateProgressBar(3,'','Finished'); }
switch($dest) {
case 'I':
if ($this->debug && !$this->allow_output_buffering && ob_get_contents()) { echo "Output has already been sent from the script - PDF file generation aborted.
"; exit; }
//Send to standard output
if(isset($_SERVER['SERVER_NAME']))
{
//We send to a browser
header('Content-Type: application/pdf');
if(headers_sent())
$this->Error('Some data has already been output to browser, can\'t send PDF file');
header('Content-Length: '.strlen($this->buffer));
header('Content-disposition: inline; filename="'.$name.'"');
// NEW OUTPUT HEADERS mPDF 5.0
header('Cache-Control: public, must-revalidate, max-age=0');
header('Pragma: public');
header('Expires: Sat, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT');
/*
header('Pragma: no-cache');
header('Cache-Control: maxage=0');
*/
}
echo $this->buffer;
break;
case 'D':
//Download file
header('Content-Description: File Transfer');
if (headers_sent())
$this->Error('Some data has already been output to browser, can\'t send PDF file');
// NEW OUTPUT HEADERS mPDF 5.0
header('Content-Transfer-Encoding: binary');
header('Cache-Control: public, must-revalidate, max-age=0');
header('Pragma: public');
header('Expires: Sat, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT');
header('Content-Type: application/force-download');
header('Content-Type: application/octet-stream', false);
header('Content-Type: application/download', false);
header('Content-Type: application/pdf', false);
/*
if(isset($_SERVER['HTTP_USER_AGENT']) and strpos($_SERVER['HTTP_USER_AGENT'],'MSIE')) {
if(isset($_SERVER['HTTPS']) && $_SERVER['HTTPS']=='on') {
header('HTTP/1.1 200 OK');
header('Status: 200 OK');
header('Pragma: anytextexeptno-cache', true);
header("Cache-Control: public, must-revalidate");
}
else {
header('Pragma: no-cache');
header('Cache-Control: maxage=0');
}
header('Content-Type: application/force-download');
}
else {
header('Content-Type: application/octet-stream');
}
*/
header('Content-Length: '.strlen($this->buffer));
header('Content-disposition: attachment; filename="'.$name.'"');
echo $this->buffer;
break;
case 'F':
//Save to local file
$f=fopen($name,'wb');
if(!$f) $this->Error('Unable to create output file: '.$name);
fwrite($f,$this->buffer,strlen($this->buffer));
fclose($f);
break;
case 'S':
//Return as a string
return $this->buffer;
default:
$this->Error('Incorrect output destination: '.$dest);
}
}
return '';
}
// *****************************************************************************
// *
// Protected methods *
// *
// *****************************************************************************
function _dochecks()
{
//Check for locale-related bug
if(1.1==1)
$this->Error('Don\'t alter the locale before including class file');
//Check for decimal separator
if(sprintf('%.1f',1.0)!='1.0')
setlocale(LC_NUMERIC,'C');
}
function _begindoc()
{
//Start document
$this->state=1;
$this->_out('%PDF-'.$this->pdf_version);
$this->_out('%'.chr(226).chr(227).chr(207).chr(211)); // 4 chars > 128 to show binary file
}
function _puthtmlheaders() {
$this->state=2;
$nb=$this->page;
for($n=1;$n<=$nb;$n++) {
if ($this->mirrorMargins && $n%2==0) { $OE = 'E'; } // EVEN
else { $OE = 'O'; }
$this->page = $n;
if (isset($this->saveHTMLHeader[$n][$OE])) {
$html = $this->saveHTMLHeader[$n][$OE]['html'];
$this->lMargin = $this->saveHTMLHeader[$n][$OE]['ml'];
$this->rMargin = $this->saveHTMLHeader[$n][$OE]['mr'];
$this->tMargin = $this->saveHTMLHeader[$n][$OE]['mh'];
$this->bMargin = $this->saveHTMLHeader[$n][$OE]['mf'];
$this->margin_header = $this->saveHTMLHeader[$n][$OE]['mh'];
$this->margin_footer = $this->saveHTMLHeader[$n][$OE]['mf'];
$this->w = $this->saveHTMLHeader[$n][$OE]['pw'];
$this->h = $this->saveHTMLHeader[$n][$OE]['ph'];
$rotate = $this->saveHTMLHeader[$n][$OE]['rotate'];
$this->Reset();
$this->pageoutput[$n] = array();
$this->pgwidth = $this->w - $this->lMargin - $this->rMargin;
$this->x = $this->lMargin;
$this->y = $this->margin_header;
$html = str_replace('{PAGENO}',$this->pagenumPrefix.$this->docPageNum($n).$this->pagenumSuffix,$html);
$html = str_replace($this->aliasNbPgGp,$this->nbpgPrefix.$this->docPageNumTotal($n).$this->nbpgSuffix,$html ); // {nbpg}
$html = str_replace($this->aliasNbPg,$nb,$html ); // {nb}
$html = preg_replace('/\{DATE\s+(.*?)\}/e',"date('\\1')",$html );
$this->HTMLheaderPageLinks = array();
$this->pageBackgrounds = array();
$this->writingHTMLheader = true;
$this->WriteHTML($html , 4); // parameter 4 saves output to $this->headerbuffer
$this->writingHTMLheader = false;
$this->Reset();
$this->pageoutput[$n] = array();
$s = $this->PrintPageBackgrounds();
$this->headerbuffer = $s . $this->headerbuffer;
$os = '';
if ($rotate) {
$os .= sprintf('q 0 -1 1 0 0 %.3f cm ',($this->w*$this->k));
}
$os .= $this->headerbuffer ;
if ($rotate) {
$os .= ' Q' . "\n";
}
// Writes over the page background but behind any other output on page
$os = preg_replace('/\\\\/','\\\\\\\\',$os);
$this->pages[$n] = preg_replace('/(___HEADER___MARKER'.date('jY').')/', "\n".$os."\n".'\\1', $this->pages[$n]);
$lks = $this->HTMLheaderPageLinks;
foreach($lks AS $lk) {
if ($rotate) {
$lw = $lk[2];
$lh = $lk[3];
$lk[2] = $lh;
$lk[3] = $lw; // swap width and height
$ax = $lk[0]/$this->k;
$ay = $lk[1]/$this->k;
$bx = $ay-($lh/$this->k);
$by = $this->w-$ax;
$lk[0] = $bx*$this->k;
$lk[1] = ($this->h-$by)*$this->k - $lw;
}
$this->PageLinks[$n][]=$lk;
}
}
if (isset($this->saveHTMLFooter[$n][$OE])) {
$html = $this->saveHTMLFooter[$this->page][$OE]['html'];
$this->lMargin = $this->saveHTMLFooter[$n][$OE]['ml'];
$this->rMargin = $this->saveHTMLFooter[$n][$OE]['mr'];
$this->tMargin = $this->saveHTMLFooter[$n][$OE]['mh'];
$this->bMargin = $this->saveHTMLFooter[$n][$OE]['mf'];
$this->margin_header = $this->saveHTMLFooter[$n][$OE]['mh'];
$this->margin_footer = $this->saveHTMLFooter[$n][$OE]['mf'];
$this->w = $this->saveHTMLFooter[$n][$OE]['pw'];
$this->h = $this->saveHTMLFooter[$n][$OE]['ph'];
$rotate = $this->saveHTMLFooter[$n][$OE]['rotate'];
$this->Reset();
$this->pageoutput[$n] = array();
$this->pgwidth = $this->w - $this->lMargin - $this->rMargin;
$this->x = $this->lMargin;
$top_y = $this->y = $this->h - $this->margin_footer;
// if bottom-margin==0, corrects to avoid division by zero
if ($this->y == $this->h) { $top_y = $this->y = ($this->h - 0.1); }
$html = str_replace('{PAGENO}',$this->pagenumPrefix.$this->docPageNum($n).$this->pagenumSuffix,$html);
$html = str_replace($this->aliasNbPgGp,$this->nbpgPrefix.$this->docPageNumTotal($n).$this->nbpgSuffix,$html ); // {nbpg}
$html = str_replace($this->aliasNbPg,$nb,$html ); // {nb}
$html = preg_replace('/\{DATE\s+(.*?)\}/e',"date('\\1')",$html );
$this->HTMLheaderPageLinks = array();
$this->pageBackgrounds = array();
$this->writingHTMLfooter = true;
$this->InFooter = true;
$this->WriteHTML($html , 4); // parameter 4 saves output to $this->headerbuffer
$this->writingHTMLfooter = false;
$this->InFooter = false;
$this->Reset();
$this->pageoutput[$n] = array();
$fheight = $this->y - $top_y;
$adj = -$fheight;
$s = $this->PrintPageBackgrounds(-$adj);
$this->headerbuffer = $s . $this->headerbuffer;
$os = '';
$os .= $this->StartTransform(true)."\n";
if ($rotate) {
$os .= sprintf('q 0 -1 1 0 0 %.3f cm ',($this->w*$this->k));
}
$os .= $this->transformTranslate(0, $adj, true)."\n";
$os .= $this->headerbuffer ;
if ($rotate) {
$os .= ' Q' . "\n";
}
$os .= $this->StopTransform(true)."\n";
// Writes over the page background but behind any other output on page
$os = preg_replace('/\\\\/','\\\\\\\\',$os);
$this->pages[$n] = preg_replace('/(___HEADER___MARKER'.date('jY').')/', "\n".$os."\n".'\\1', $this->pages[$n]);
$lks = $this->HTMLheaderPageLinks;
foreach($lks AS $lk) {
$lk[1] -= $adj*$this->k;
if ($rotate) {
$lw = $lk[2];
$lh = $lk[3];
$lk[2] = $lh;
$lk[3] = $lw; // swap width and height
$ax = $lk[0]/$this->k;
$ay = $lk[1]/$this->k;
$bx = $ay-($lh/$this->k);
$by = $this->w-$ax;
$lk[0] = $bx*$this->k;
$lk[1] = ($this->h-$by)*$this->k - $lw;
}
$this->PageLinks[$n][]=$lk;
}
}
}
$this->page=$nb;
$this->state=1;
}
function _putpages()
{
$nb=$this->page;
$filter=($this->compress) ? '/Filter /FlateDecode ' : '';
if($this->DefOrientation=='P') {
$defwPt=$this->fwPt;
$defhPt=$this->fhPt;
}
else {
$defwPt=$this->fhPt;
$defhPt=$this->fwPt;
}
$annotid=(3+2*$nb);
for($n=1;$n<=$nb;$n++)
{
if(isset($this->OrientationChanges[$n])) {
$hPt=$this->pageDim[$n]['w']*$this->k;
$wPt=$this->pageDim[$n]['h']*$this->k;
}
else {
$wPt=$this->pageDim[$n]['w']*$this->k;
$hPt=$this->pageDim[$n]['h']*$this->k;
}
//Replace number of pages
if(!empty($this->aliasNbPg)) {
// mPDF 5.0
if (!$this->onlyCoreFonts) { $s1 = $this->UTF8ToUTF16BE($this->aliasNbPg, false); }
else { $s1 = $this->aliasNbPg; }
if (!$this->onlyCoreFonts) { $r = $this->UTF8ToUTF16BE($nb, false); }
else { $r = $nb; }
if (preg_match_all('/{mpdfheadernbpg (C|R) ff=(\S*) fs=(\S*) fz=(.*?)}/',$this->pages[$n],$m)) {
for($hi=0;$hi