* Char. number range | UTF-8 octet sequence * (hexadecimal) | (binary) * --------------------+----------------------------------------------- * 0000 0000-0000 007F | 0xxxxxxx * 0000 0080-0000 07FF | 110xxxxx 10xxxxxx * 0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx * 0001 0000-0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx * --------------------------------------------------------------------- * * ABFN notation: * --------------------------------------------------------------------- * UTF8-octets = *( UTF8-char ) * UTF8-char = UTF8-1 / UTF8-2 / UTF8-3 / UTF8-4 * UTF8-1 = %x00-7F * UTF8-2 = %xC2-DF UTF8-tail * * UTF8-3 = %xE0 %xA0-BF UTF8-tail / %xE1-EC 2( UTF8-tail ) / * %xED %x80-9F UTF8-tail / %xEE-EF 2( UTF8-tail ) * UTF8-4 = %xF0 %x90-BF 2( UTF8-tail ) / %xF1-F3 3( UTF8-tail ) / * %xF4 %x80-8F 2( UTF8-tail ) * UTF8-tail = %x80-BF * --------------------------------------------------------------------- *
* Encoding UTF-16: * * Encoding of a single character from an ISO 10646 character value to * UTF-16 proceeds as follows. Let U be the character number, no greater * than 0x10FFFF. * * 1) If U < 0x10000, encode U as a 16-bit unsigned integer and * terminate. * * 2) Let U' = U - 0x10000. Because U is less than or equal to 0x10FFFF, * U' must be less than or equal to 0xFFFFF. That is, U' can be * represented in 20 bits. * * 3) Initialize two 16-bit unsigned integers, W1 and W2, to 0xD800 and * 0xDC00, respectively. These integers each have 10 bits free to * encode the character value, for a total of 20 bits. * * 4) Assign the 10 high-order bits of the 20-bit U' to the 10 low-order * bits of W1 and the 10 low-order bits of U' to the 10 low-order * bits of W2. Terminate. * * Graphically, steps 2 through 4 look like: * U' = yyyyyyyyyyxxxxxxxxxx * W1 = 110110yyyyyyyyyy * W2 = 110111xxxxxxxxxx *
'); //replace some blank characters $html = preg_replace('/]*)>[\n\r\t]+/', '<\\1\\2>', $html); $html = preg_replace('@(\r\n|\r)@', "\n", $html); $repTable = array("\t" => ' ', "\0" => ' ', "\x0B" => ' ', "\\" => "\\\\"); $html = strtr($html, $repTable); $offset = 0; while (($offset < strlen($html)) AND ($pos = strpos($html, '', $offset)) !== false) { $html_a = substr($html, 0, $offset); $html_b = substr($html, $offset, ($pos - $offset + 6)); while (preg_match("']*)>(.*?)\n(.*?)'si", $html_b)) { // preserve newlines on tag $html_b = preg_replace("']*)>(.*?)\n(.*?)'si", "\\2\\3", $html_b); } $html = $html_a.$html_b.substr($html, $pos + 6); $offset = strlen($html_a.$html_b); } $offset = 0; while (($offset < strlen($html)) AND ($pos = strpos($html, '</textarea>', $offset)) !== false) { $html_a = substr($html, 0, $offset); $html_b = substr($html, $offset, ($pos - $offset + 11)); while (preg_match("']*)>(.*?)\n(.*?)</textarea>'si", $html_b)) { // preserve newlines on tag $html_b = preg_replace("']*)>(.*?)\n(.*?)</textarea>'si", "\\2\\3</textarea>", $html_b); $html_b = preg_replace("']*)>(.*?)[\"](.*?)</textarea>'si", "\\2''\\3</textarea>", $html_b); } $html = $html_a.$html_b.substr($html, $pos + 11); $offset = strlen($html_a.$html_b); } $html = preg_replace("'([\s]*)([\s]*)'si", "", $html); $offset = 0; while (($offset < strlen($html)) AND ($pos = strpos($html, '', $offset)) !== false) { $html_a = substr($html, 0, $offset); $html_b = substr($html, $offset, ($pos - $offset + 9)); while (preg_match("']*)>(.*?)'si", $html_b)) { $html_b = preg_replace("']*)>(.*?)'si", "\\2\t\\4\r", $html_b); $html_b = preg_replace("']*)>(.*?)'si", "\\2\r", $html_b); } $html = $html_a.$html_b.substr($html, $pos + 9); $offset = strlen($html_a.$html_b); } $html = preg_replace("']*)>'si", "'si", "\" />", $html); $html = str_replace("\n", ' ', $html); // restore textarea newlines $html = str_replace('', "\n", $html); // remove extra spaces from code $html = preg_replace('/[\s]+<\/(table|tr|td|th|ul|ol|li)>/', '\\1>', $html); $html = preg_replace('/[\s]+<(tr|td|th|ul|ol|li|br)/', '<\\1', $html); $html = preg_replace('/<\/(table|tr|td|th|blockquote|dd|div|dt|h1|h2|h3|h4|h5|h6|hr|li|ol|ul|p)>[\s]+', '\\1><', $html); $html = preg_replace('/<\/(td|th)>/', '\\1>', $html); $html = preg_replace('/<\/table>([\s]*)/', '', $html); $html = preg_replace('/]*)>/xi', '', $html); $html = preg_replace('/]*)>/xi', '', $html); // trim string $html = preg_replace('/^[\s]+/', '', $html); $html = preg_replace('/[\s]+$/', '', $html); // pattern for generic tag $tagpattern = '/(<[^>]+>)/'; // explodes the string $a = preg_split($tagpattern, $html, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY); // count elements $maxel = count($a); $elkey = 0; $key = 0; // create an array of elements $dom = array(); $dom[$key] = array(); // set first void element $dom[$key]['tag'] = false; $dom[$key]['value'] = ''; $dom[$key]['parent'] = 0; $dom[$key]['fontname'] = $this->FontFamily; $dom[$key]['fontstyle'] = $this->FontStyle; $dom[$key]['fontsize'] = $this->FontSizePt; $dom[$key]['bgcolor'] = false; $dom[$key]['fgcolor'] = $this->fgcolor; $dom[$key]['align'] = ''; $dom[$key]['listtype'] = ''; $dom[$key]['text-indent'] = 0; $thead = false; // true when we are inside the THEAD tag ++$key; $level = array(); array_push($level, 0); // root while ($elkey < $maxel) { $dom[$key] = array(); $element = $a[$elkey]; $dom[$key]['elkey'] = $elkey; if (preg_match($tagpattern, $element)) { // html tag $element = substr($element, 1, -1); // get tag name preg_match('/[\/]?([a-zA-Z0-9]*)/', $element, $tag); $tagname = strtolower($tag[1]); // check if we are inside a table header if ($tagname == 'thead') { if ($element{0} == '/') { $thead = false; } else { $thead = true; } ++$elkey; continue; } $dom[$key]['tag'] = true; $dom[$key]['value'] = $tagname; if ($element{0} == '/') { // closing html tag $dom[$key]['opening'] = false; $dom[$key]['parent'] = end($level); array_pop($level); $dom[$key]['fontname'] = $dom[($dom[($dom[$key]['parent'])]['parent'])]['fontname']; $dom[$key]['fontstyle'] = $dom[($dom[($dom[$key]['parent'])]['parent'])]['fontstyle']; $dom[$key]['fontsize'] = $dom[($dom[($dom[$key]['parent'])]['parent'])]['fontsize']; $dom[$key]['bgcolor'] = $dom[($dom[($dom[$key]['parent'])]['parent'])]['bgcolor']; $dom[$key]['fgcolor'] = $dom[($dom[($dom[$key]['parent'])]['parent'])]['fgcolor']; $dom[$key]['align'] = $dom[($dom[($dom[$key]['parent'])]['parent'])]['align']; if (isset($dom[($dom[($dom[$key]['parent'])]['parent'])]['listtype'])) { $dom[$key]['listtype'] = $dom[($dom[($dom[$key]['parent'])]['parent'])]['listtype']; } // set the number of columns in table tag if (($dom[$key]['value'] == 'tr') AND (!isset($dom[($dom[($dom[$key]['parent'])]['parent'])]['cols']))) { $dom[($dom[($dom[$key]['parent'])]['parent'])]['cols'] = $dom[($dom[$key]['parent'])]['cols']; } if (($dom[$key]['value'] == 'td') OR ($dom[$key]['value'] == 'th')) { $dom[($dom[$key]['parent'])]['content'] = ''; for ($i = ($dom[$key]['parent'] + 1); $i < $key; ++$i) { $dom[($dom[$key]['parent'])]['content'] .= $a[$dom[$i]['elkey']]; } $key = $i; } // store header rows on a new table if (($dom[$key]['value'] == 'tr') AND ($dom[($dom[$key]['parent'])]['thead'] === true)) { if ($this->empty_string($dom[($dom[($dom[$key]['parent'])]['parent'])]['thead'])) { $dom[($dom[($dom[$key]['parent'])]['parent'])]['thead'] = $a[$dom[($dom[($dom[$key]['parent'])]['parent'])]['elkey']]; } for ($i = $dom[$key]['parent']; $i <= $key; ++$i) { $dom[($dom[($dom[$key]['parent'])]['parent'])]['thead'] .= $a[$dom[$i]['elkey']]; } } if (($dom[$key]['value'] == 'table') AND (!$this->empty_string($dom[($dom[$key]['parent'])]['thead']))) { $dom[($dom[$key]['parent'])]['thead'] .= ''; } } else { // opening html tag $dom[$key]['opening'] = true; $dom[$key]['parent'] = end($level); if (substr($element, -1, 1) != '/') { // not self-closing tag array_push($level, $key); $dom[$key]['self'] = false; } else { $dom[$key]['self'] = true; } // copy some values from parent $parentkey = 0; if ($key > 0) { $parentkey = $dom[$key]['parent']; $dom[$key]['fontname'] = $dom[$parentkey]['fontname']; $dom[$key]['fontstyle'] = $dom[$parentkey]['fontstyle']; $dom[$key]['fontsize'] = $dom[$parentkey]['fontsize']; $dom[$key]['bgcolor'] = $dom[$parentkey]['bgcolor']; $dom[$key]['fgcolor'] = $dom[$parentkey]['fgcolor']; $dom[$key]['align'] = $dom[$parentkey]['align']; $dom[$key]['listtype'] = $dom[$parentkey]['listtype']; $dom[$key]['text-indent'] = $dom[$parentkey]['text-indent']; } // get attributes preg_match_all('/([^=\s]*)=["]?([^"]*)["]?/', $element, $attr_array, PREG_PATTERN_ORDER); $dom[$key]['attribute'] = array(); // reset attribute array while (list($id, $name) = each($attr_array[1])) { $dom[$key]['attribute'][strtolower($name)] = $attr_array[2][$id]; } // split style attributes if (isset($dom[$key]['attribute']['style'])) { // get style attributes preg_match_all('/([^;:\s]*):([^;]*)/', $dom[$key]['attribute']['style'], $style_array, PREG_PATTERN_ORDER); $dom[$key]['style'] = array(); // reset style attribute array while (list($id, $name) = each($style_array[1])) { $dom[$key]['style'][strtolower($name)] = trim($style_array[2][$id]); } // --- get some style attributes --- if (isset($dom[$key]['style']['font-family'])) { // font family if (isset($dom[$key]['style']['font-family'])) { $fontslist = preg_split('/[,]/', strtolower($dom[$key]['style']['font-family'])); foreach ($fontslist as $font) { $font = trim(strtolower($font)); if (in_array($font, $this->fontlist) OR in_array($font, $this->fontkeys)) { $dom[$key]['fontname'] = $font; break; } } } } // list-style-type if (isset($dom[$key]['style']['list-style-type'])) { $dom[$key]['listtype'] = trim(strtolower($dom[$key]['style']['list-style-type'])); if ($dom[$key]['listtype'] == 'inherit') { $dom[$key]['listtype'] = $dom[$parentkey]['listtype']; } } // text-indent if (isset($dom[$key]['style']['text-indent'])) { $dom[$key]['text-indent'] = $this->getHTMLUnitToUnits($dom[$key]['style']['text-indent']); if ($dom[$key]['text-indent'] == 'inherit') { $dom[$key]['text-indent'] = $dom[$parentkey]['text-indent']; } } // font size if (isset($dom[$key]['style']['font-size'])) { $fsize = trim($dom[$key]['style']['font-size']); switch ($fsize) { // absolute-size case 'xx-small': { $dom[$key]['fontsize'] = $dom[0]['fontsize'] - 4; break; } case 'x-small': { $dom[$key]['fontsize'] = $dom[0]['fontsize'] - 3; break; } case 'small': { $dom[$key]['fontsize'] = $dom[0]['fontsize'] - 2; break; } case 'medium': { $dom[$key]['fontsize'] = $dom[0]['fontsize']; break; } case 'large': { $dom[$key]['fontsize'] = $dom[0]['fontsize'] + 2; break; } case 'x-large': { $dom[$key]['fontsize'] = $dom[0]['fontsize'] + 4; break; } case 'xx-large': { $dom[$key]['fontsize'] = $dom[0]['fontsize'] + 6; break; } // relative-size case 'smaller': { $dom[$key]['fontsize'] = $dom[$parentkey]['fontsize'] - 3; break; } case 'larger': { $dom[$key]['fontsize'] = $dom[$parentkey]['fontsize'] + 3; break; } default: { $dom[$key]['fontsize'] = $this->getHTMLUnitToUnits($fsize, $dom[$parentkey]['fontsize'], 'pt', true); } } } // font style if (isset($dom[$key]['style']['font-weight']) AND (strtolower($dom[$key]['style']['font-weight']{0}) == 'b')) { $dom[$key]['fontstyle'] .= 'B'; } if (isset($dom[$key]['style']['font-style']) AND (strtolower($dom[$key]['style']['font-style']{0}) == 'i')) { $dom[$key]['fontstyle'] .= '"I'; } // font color if (isset($dom[$key]['style']['color']) AND (!$this->empty_string($dom[$key]['style']['color']))) { $dom[$key]['fgcolor'] = $this->convertHTMLColorToDec($dom[$key]['style']['color']); } // background color if (isset($dom[$key]['style']['background-color']) AND (!$this->empty_string($dom[$key]['style']['background-color']))) { $dom[$key]['bgcolor'] = $this->convertHTMLColorToDec($dom[$key]['style']['background-color']); } // text-decoration if (isset($dom[$key]['style']['text-decoration'])) { $decors = explode(' ', strtolower($dom[$key]['style']['text-decoration'])); foreach ($decors as $dec) { $dec = trim($dec); if (!$this->empty_string($dec)) { if ($dec{0} == 'u') { $dom[$key]['fontstyle'] .= 'U'; } elseif ($dec{0} == 'l') { $dom[$key]['fontstyle'] .= 'D'; } } } } // check for width attribute if (isset($dom[$key]['style']['width'])) { $dom[$key]['width'] = $dom[$key]['style']['width']; } // check for height attribute if (isset($dom[$key]['style']['height'])) { $dom[$key]['height'] = $dom[$key]['style']['height']; } // check for text alignment if (isset($dom[$key]['style']['text-align'])) { $dom[$key]['align'] = strtoupper($dom[$key]['style']['text-align']{0}); } // check for border attribute if (isset($dom[$key]['style']['border'])) { $dom[$key]['attribute']['border'] = $dom[$key]['style']['border']; } } // check for font tag if ($dom[$key]['value'] == 'font') { // font family if (isset($dom[$key]['attribute']['face'])) { $fontslist = preg_split('/[,]/', strtolower($dom[$key]['attribute']['face'])); foreach ($fontslist as $font) { $font = trim(strtolower($font)); if (in_array($font, $this->fontlist) OR in_array($font, $this->fontkeys)) { $dom[$key]['fontname'] = $font; break; } } } // font size if (isset($dom[$key]['attribute']['size'])) { if ($key > 0) { if ($dom[$key]['attribute']['size']{0} == '+') { $dom[$key]['fontsize'] = $dom[($dom[$key]['parent'])]['fontsize'] + intval(substr($dom[$key]['attribute']['size'], 1)); } elseif ($dom[$key]['attribute']['size']{0} == '-') { $dom[$key]['fontsize'] = $dom[($dom[$key]['parent'])]['fontsize'] - intval(substr($dom[$key]['attribute']['size'], 1)); } else { $dom[$key]['fontsize'] = intval($dom[$key]['attribute']['size']); } } else { $dom[$key]['fontsize'] = intval($dom[$key]['attribute']['size']); } } } // force natural alignment for lists if ((($dom[$key]['value'] == 'ul') OR ($dom[$key]['value'] == 'ol') OR ($dom[$key]['value'] == 'dl')) AND (!isset($dom[$key]['align']) OR $this->empty_string($dom[$key]['align']) OR ($dom[$key]['align'] != 'J'))) { if ($this->rtl) { $dom[$key]['align'] = 'R'; } else { $dom[$key]['align'] = 'L'; } } if (($dom[$key]['value'] == 'small') OR ($dom[$key]['value'] == 'sup') OR ($dom[$key]['value'] == 'sub')) { $dom[$key]['fontsize'] = $dom[$key]['fontsize'] * K_SMALL_RATIO; } if (($dom[$key]['value'] == 'strong') OR ($dom[$key]['value'] == 'b')) { $dom[$key]['fontstyle'] .= 'B'; } if (($dom[$key]['value'] == 'em') OR ($dom[$key]['value'] == 'i')) { $dom[$key]['fontstyle'] .= 'I'; } if ($dom[$key]['value'] == 'u') { $dom[$key]['fontstyle'] .= 'U'; } if ($dom[$key]['value'] == 'del') { $dom[$key]['fontstyle'] .= 'D'; } if (($dom[$key]['value'] == 'pre') OR ($dom[$key]['value'] == 'tt')) { $dom[$key]['fontname'] = $this->default_monospaced_font; } if (($dom[$key]['value']{0} == 'h') AND (intval($dom[$key]['value']{1}) > 0) AND (intval($dom[$key]['value']{1}) < 7)) { $headsize = (4 - intval($dom[$key]['value']{1})) * 2; $dom[$key]['fontsize'] = $dom[0]['fontsize'] + $headsize; $dom[$key]['fontstyle'] .= 'B'; } if (($dom[$key]['value'] == 'table')) { $dom[$key]['rows'] = 0; // number of rows $dom[$key]['trids'] = array(); // IDs of TR elements $dom[$key]['thead'] = ''; // table header rows } if (($dom[$key]['value'] == 'tr')) { $dom[$key]['cols'] = 0; // store the number of rows on table element ++$dom[($dom[$key]['parent'])]['rows']; // store the TR elements IDs on table element array_push($dom[($dom[$key]['parent'])]['trids'], $key); if ($thead) { $dom[$key]['thead'] = true; } else { $dom[$key]['thead'] = false; } } if (($dom[$key]['value'] == 'th') OR ($dom[$key]['value'] == 'td')) { if (isset($dom[$key]['attribute']['colspan'])) { $colspan = intval($dom[$key]['attribute']['colspan']); } else { $colspan = 1; } $dom[$key]['attribute']['colspan'] = $colspan; $dom[($dom[$key]['parent'])]['cols'] += $colspan; } // set foreground color attribute if (isset($dom[$key]['attribute']['color']) AND (!$this->empty_string($dom[$key]['attribute']['color']))) { $dom[$key]['fgcolor'] = $this->convertHTMLColorToDec($dom[$key]['attribute']['color']); } // set background color attribute if (isset($dom[$key]['attribute']['bgcolor']) AND (!$this->empty_string($dom[$key]['attribute']['bgcolor']))) { $dom[$key]['bgcolor'] = $this->convertHTMLColorToDec($dom[$key]['attribute']['bgcolor']); } // check for width attribute if (isset($dom[$key]['attribute']['width'])) { $dom[$key]['width'] = $dom[$key]['attribute']['width']; } // check for height attribute if (isset($dom[$key]['attribute']['height'])) { $dom[$key]['height'] = $dom[$key]['attribute']['height']; } // check for text alignment if (isset($dom[$key]['attribute']['align']) AND (!$this->empty_string($dom[$key]['attribute']['align'])) AND ($dom[$key]['value'] !== 'img')) { $dom[$key]['align'] = strtoupper($dom[$key]['attribute']['align']{0}); } } // end opening tag } else { // text $dom[$key]['tag'] = false; $dom[$key]['value'] = stripslashes($this->unhtmlentities($element)); $dom[$key]['parent'] = end($level); } ++$elkey; ++$key; } return $dom; } /** * Allows to preserve some HTML formatting (limited support). * IMPORTANT: The HTML must be well formatted - try to clean-up it using an application like HTML-Tidy before submitting. * Supported tags are: a, b, blockquote, br, dd, del, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, img, li, ol, p, pre, small, span, strong, sub, sup, table, tcpdf, td, th, thead, tr, tt, u, ul * @param string $html text to display * @param boolean $ln if true add a new line after text (default = true) * @param int $fill Indicates if the background must be painted (true) or transparent (false). * @param boolean $reseth if true reset the last cell height (default false). * @param boolean $cell if true add the default cMargin space to each Write (default false). * @param string $align Allows to center or align the text. Possible values are:L : left alignC : centerR : right align'' : empty string : left for LTR or right for RTL * @access public */ public function writeHTML($html, $ln=true, $fill=false, $reseth=false, $cell=false, $align='') { $gvars = $this->getGraphicVars(); // store current values $prevPage = $this->page; $prevlMargin = $this->lMargin; $prevrMargin = $this->rMargin; $curfontname = $this->FontFamily; $curfontstyle = $this->FontStyle; $curfontsize = $this->FontSizePt; $this->newline = true; $startlinepage = $this->page; $minstartliney = $this->y; $startlinex = $this->x; $startliney = $this->y; $yshift = 0; $newline = true; $loop = 0; $curpos = 0; $this_method_vars = array(); $undo = false; $blocktags = array('blockquote','br','dd','div','dt','h1','h2','h3','h4','h5','h6','hr','li','ol','p','ul','tcpdf'); $this->premode = false; if (isset($this->PageAnnots[$this->page])) { $pask = count($this->PageAnnots[$this->page]); } else { $pask = 0; } if (isset($this->footerlen[$this->page])) { $this->footerpos[$this->page] = $this->pagelen[$this->page] - $this->footerlen[$this->page]; } else { $this->footerpos[$this->page] = $this->pagelen[$this->page]; } $startlinepos = $this->footerpos[$this->page]; $lalign = $align; $plalign = $align; if ($this->rtl) { $w = $this->x - $this->lMargin; } else { $w = $this->w - $this->rMargin - $this->x; } $w -= (2 * $this->cMargin); if ($cell) { if ($this->rtl) { $this->x -= $this->cMargin; } else { $this->x += $this->cMargin; } } if ($this->customlistindent >= 0) { $this->listindent = $this->customlistindent; } else { $this->listindent = $this->GetStringWidth('0000'); } // save previous states $prev_listnum = $this->listnum; $prev_listordered = $this->listordered; $prev_listcount = $this->listcount; $prev_lispacer = $this->lispacer; $this->listnum = 0; $this->listordered = array(); $this->listcount = array(); $this->lispacer = ''; if (($this->empty_string($this->lasth)) OR ($reseth)) { //set row height $this->lasth = $this->FontSize * $this->cell_height_ratio; } $dom = $this->getHtmlDomArray($html); $maxel = count($dom); $key = 0; while ($key < $maxel) { if ($dom[$key]['tag'] AND $dom[$key]['opening'] AND isset($dom[$key]['attribute']['nobr']) AND ($dom[$key]['attribute']['nobr'] == 'true')) { if (isset($dom[($dom[$key]['parent'])]['attribute']['nobr']) AND ($dom[($dom[$key]['parent'])]['attribute']['nobr'] == 'true')) { $dom[$key]['attribute']['nobr'] = false; } else { // store current object $this->startTransaction(); // save this method vars $this_method_vars['html'] = $html; $this_method_vars['ln'] = $ln; $this_method_vars['fill'] = $fill; $this_method_vars['reseth'] = $reseth; $this_method_vars['cell'] = $cell; $this_method_vars['align'] = $align; $this_method_vars['gvars'] = $gvars; $this_method_vars['prevPage'] = $prevPage; $this_method_vars['prevlMargin'] = $prevlMargin; $this_method_vars['prevrMargin'] = $prevrMargin; $this_method_vars['curfontname'] = $curfontname; $this_method_vars['curfontstyle'] = $curfontstyle; $this_method_vars['curfontsize'] = $curfontsize; $this_method_vars['minstartliney'] = $minstartliney; $this_method_vars['yshift'] = $yshift; $this_method_vars['startlinepage'] = $startlinepage; $this_method_vars['startlinepos'] = $startlinepos; $this_method_vars['startlinex'] = $startlinex; $this_method_vars['startliney'] = $startliney; $this_method_vars['newline'] = $newline; $this_method_vars['loop'] = $loop; $this_method_vars['curpos'] = $curpos; $this_method_vars['pask'] = $pask; $this_method_vars['lalign'] = $lalign; $this_method_vars['plalign'] = $plalign; $this_method_vars['w'] = $w; $this_method_vars['prev_listnum'] = $prev_listnum; $this_method_vars['prev_listordered'] = $prev_listordered; $this_method_vars['prev_listcount'] = $prev_listcount; $this_method_vars['prev_lispacer'] = $prev_lispacer; $this_method_vars['key'] = $key; $this_method_vars['dom'] = $dom; } } if ($dom[$key]['tag'] OR ($key == 0)) { if ((($dom[$key]['value'] == 'table') OR ($dom[$key]['value'] == 'tr')) AND (isset($dom[$key]['align']))) { $dom[$key]['align'] = ($this->rtl) ? 'R' : 'L'; } // vertically align image in line if ((!$this->newline) AND ($dom[$key]['value'] == 'img') AND (isset($dom[$key]['attribute']['height'])) AND ($dom[$key]['attribute']['height'] > 0)) { // get image height $imgh = $this->getHTMLUnitToUnits($dom[$key]['attribute']['height'], $this->lasth, 'px'); if (!$this->InFooter) { // check for page break $this->checkPageBreak($imgh); } if ($this->page > $startlinepage) { // fix line splitted over two pages if (isset($this->footerlen[$startlinepage])) { $curpos = $this->pagelen[$startlinepage] - $this->footerlen[$startlinepage]; } // line to be moved one page forward $pagebuff = $this->getPageBuffer($startlinepage); $linebeg = substr($pagebuff, $startlinepos, ($curpos - $startlinepos)); $tstart = substr($pagebuff, 0, $startlinepos); $tend = substr($this->getPageBuffer($startlinepage), $curpos); // remove line from previous page $this->setPageBuffer($startlinepage, $tstart.''.$tend); $pagebuff = $this->getPageBuffer($this->page); $tstart = substr($pagebuff, 0, $this->cntmrk[$this->page]); $tend = substr($pagebuff, $this->cntmrk[$this->page]); // add line start to current page $yshift = $minstartliney - $this->y; $try = sprintf('1 0 0 1 0 %.3F cm', ($yshift * $this->k)); $this->setPageBuffer($this->page, $tstart."\nq\n".$try."\n".$linebeg."\nQ\n".$tend); // shift the annotations and links if (isset($this->PageAnnots[$this->page])) { $next_pask = count($this->PageAnnots[$this->page]); } else { $next_pask = 0; } if (isset($this->PageAnnots[$startlinepage])) { foreach ($this->PageAnnots[$startlinepage] as $pak => $pac) { if ($pak >= $pask) { $this->PageAnnots[$this->page][] = $pac; unset($this->PageAnnots[$startlinepage][$pak]); $npak = count($this->PageAnnots[$this->page]) - 1; $this->PageAnnots[$this->page][$npak]['y'] -= $yshift; } } } $pask = $next_pask; $startlinepos = $this->cntmrk[$this->page]; $startlinepage = $this->page; $startliney = $this->y; } $this->y += (($curfontsize / $this->k) - $imgh); $minstartliney = min($this->y, $minstartliney); } elseif (isset($dom[$key]['fontname']) OR isset($dom[$key]['fontstyle']) OR isset($dom[$key]['fontsize'])) { // account for different font size $pfontname = $curfontname; $pfontstyle = $curfontstyle; $pfontsize = $curfontsize; $fontname = isset($dom[$key]['fontname']) ? $dom[$key]['fontname'] : $curfontname; $fontstyle = isset($dom[$key]['fontstyle']) ? $dom[$key]['fontstyle'] : $curfontstyle; $fontsize = isset($dom[$key]['fontsize']) ? $dom[$key]['fontsize'] : $curfontsize; if (($fontname != $curfontname) OR ($fontstyle != $curfontstyle) OR ($fontsize != $curfontsize)) { $this->SetFont($fontname, $fontstyle, $fontsize); $this->lasth = $this->FontSize * $this->cell_height_ratio; if (is_numeric($fontsize) AND ($fontsize > 0) AND is_numeric($curfontsize) AND ($curfontsize > 0) AND ($fontsize != $curfontsize) AND (!$this->newline) AND ($key < ($maxel - 1)) ) { if ((!$this->newline) AND ($this->page > $startlinepage)) { // fix lines splitted over two pages if (isset($this->footerlen[$startlinepage])) { $curpos = $this->pagelen[$startlinepage] - $this->footerlen[$startlinepage]; } // line to be moved one page forward $pagebuff = $this->getPageBuffer($startlinepage); $linebeg = substr($pagebuff, $startlinepos, ($curpos - $startlinepos)); $tstart = substr($pagebuff, 0, $startlinepos); $tend = substr($this->getPageBuffer($startlinepage), $curpos); // remove line start from previous page $this->setPageBuffer($startlinepage, $tstart.''.$tend); $pagebuff = $this->getPageBuffer($this->page); $tstart = substr($pagebuff, 0, $this->cntmrk[$this->page]); $tend = substr($pagebuff, $this->cntmrk[$this->page]); // add line start to current page $yshift = $minstartliney - $this->y; $try = sprintf('1 0 0 1 0 %.3F cm', ($yshift * $this->k)); $this->setPageBuffer($this->page, $tstart."\nq\n".$try."\n".$linebeg."\nQ\n".$tend); // shift the annotations and links if (isset($this->PageAnnots[$this->page])) { $next_pask = count($this->PageAnnots[$this->page]); } else { $next_pask = 0; } if (isset($this->PageAnnots[$startlinepage])) { foreach ($this->PageAnnots[$startlinepage] as $pak => $pac) { if ($pak >= $pask) { $this->PageAnnots[$this->page][] = $pac; unset($this->PageAnnots[$startlinepage][$pak]); $npak = count($this->PageAnnots[$this->page]) - 1; $this->PageAnnots[$this->page][$npak]['y'] -= $yshift; } } } $pask = $next_pask; } if (($dom[$key]['value'] != 'td') AND ($dom[$key]['value'] != 'th')) { $this->y += (($curfontsize - $fontsize) / $this->k); } $minstartliney = min($this->y, $minstartliney); } $curfontname = $fontname; $curfontstyle = $fontstyle; $curfontsize = $fontsize; } } if (($plalign == 'J') AND (in_array($dom[$key]['value'], $blocktags))) { $plalign = ''; } // get current position on page buffer $curpos = $this->pagelen[$startlinepage]; if (isset($dom[$key]['bgcolor']) AND ($dom[$key]['bgcolor'] !== false)) { $this->SetFillColorArray($dom[$key]['bgcolor']); $wfill = true; } else { $wfill = $fill | false; } if (isset($dom[$key]['fgcolor']) AND ($dom[$key]['fgcolor'] !== false)) { $this->SetTextColorArray($dom[$key]['fgcolor']); } if (isset($dom[$key]['align'])) { $lalign = $dom[$key]['align']; } if ($this->empty_string($lalign)) { $lalign = $align; } } // align lines if ($this->newline AND (strlen($dom[$key]['value']) > 0) AND ($dom[$key]['value'] != 'td') AND ($dom[$key]['value'] != 'th')) { $newline = true; // we are at the beginning of a new line if (isset($startlinex)) { $yshift = $minstartliney - $startliney; if (($yshift > 0) OR ($this->page > $startlinepage)) { $yshift = 0; } if ((isset($plalign) AND ((($plalign == 'C') OR ($plalign == 'J') OR (($plalign == 'R') AND (!$this->rtl)) OR (($plalign == 'L') AND ($this->rtl))))) OR ($yshift < 0)) { // the last line must be shifted to be aligned as requested $linew = abs($this->endlinex - $startlinex); $pstart = substr($this->getPageBuffer($startlinepage), 0, $startlinepos); if (isset($opentagpos) AND isset($this->footerlen[$startlinepage]) AND (!$this->InFooter)) { $this->footerpos[$startlinepage] = $this->pagelen[$startlinepage] - $this->footerlen[$startlinepage]; $midpos = min($opentagpos, $this->footerpos[$startlinepage]); } elseif (isset($opentagpos)) { $midpos = $opentagpos; } elseif (isset($this->footerlen[$startlinepage]) AND (!$this->InFooter)) { $this->footerpos[$startlinepage] = $this->pagelen[$startlinepage] - $this->footerlen[$startlinepage]; $midpos = $this->footerpos[$startlinepage]; } else { $midpos = 0; } if ($midpos > 0) { $pmid = substr($this->getPageBuffer($startlinepage), $startlinepos, ($midpos - $startlinepos)); $pend = substr($this->getPageBuffer($startlinepage), $midpos); } else { $pmid = substr($this->getPageBuffer($startlinepage), $startlinepos); $pend = ''; } // calculate shifting amount $tw = $w; if ($this->lMargin != $prevlMargin) { $tw += ($prevlMargin - $this->lMargin); } if ($this->rMargin != $prevrMargin) { $tw += ($prevrMargin - $this->rMargin); } $mdiff = abs($tw - $linew); $t_x = 0; if ($plalign == 'C') { if ($this->rtl) { $t_x = -($mdiff / 2); } else { $t_x = ($mdiff / 2); } } elseif (($plalign == 'R') AND (!$this->rtl)) { // right alignment on LTR document $t_x = $mdiff; } elseif (($plalign == 'L') AND ($this->rtl)) { // left alignment on RTL document $t_x = -$mdiff; } elseif (($plalign == 'J') AND ($plalign == $lalign)) { // Justification if ($this->rtl OR $this->tmprtl) { $t_x = $this->lMargin - $this->endlinex; } $no = 0; $ns = 0; $pmidtemp = $pmid; // escape special characters $pmidtemp = preg_replace('/[\\\][\(]/x', '\\#!#OP#!#', $pmidtemp); $pmidtemp = preg_replace('/[\\\][\)]/x', '\\#!#CP#!#', $pmidtemp); // search spaces if (preg_match_all('/\[\(([^\)]*)\)\]/x', $pmidtemp, $lnstring, PREG_PATTERN_ORDER)) { $maxkk = count($lnstring[1]) - 1; for ($kk=0; $kk <= $maxkk; ++$kk) { // restore special characters $lnstring[1][$kk] = str_replace('#!#OP#!#', '(', $lnstring[1][$kk]); $lnstring[1][$kk] = str_replace('#!#CP#!#', ')', $lnstring[1][$kk]); if ($kk == $maxkk) { if ($this->rtl OR $this->tmprtl) { $tvalue = ltrim($lnstring[1][$kk]); } else { $tvalue = rtrim($lnstring[1][$kk]); } } else { $tvalue = $lnstring[1][$kk]; } // count spaces on line $no += substr_count($lnstring[1][$kk], chr(32)); $ns += substr_count($tvalue, chr(32)); } if ($this->rtl OR $this->tmprtl) { $t_x = $this->lMargin - $this->endlinex - (($no - $ns - 1) * $this->GetStringWidth(chr(32))); } // calculate additional space to add to each space $spacelen = $this->GetStringWidth(chr(32)); $spacewidth = (($tw - $linew + (($no - $ns) * $spacelen)) / ($ns?$ns:1)) * $this->k; $spacewidthu = -1000 * ($tw - $linew + ($no * $spacelen)) / ($ns?$ns:1) / $this->FontSize; $nsmax = $ns; $ns = 0; reset($lnstring); $offset = 0; $strcount = 0; $prev_epsposbeg = 0; global $spacew; while (preg_match('/([0-9\.\+\-]*)[\s](Td|cm|m|l|c|re)[\s]/x', $pmid, $strpiece, PREG_OFFSET_CAPTURE, $offset) == 1) { // check if we are inside a string section '[( ... )]' $stroffset = strpos($pmid, '[(', $offset); if (($stroffset !== false) AND ($stroffset <= $strpiece[2][1])) { // set offset to the end of string section $offset = strpos($pmid, ')]', $stroffset); while (($offset !== false) AND ($pmid{($offset - 1)} == '\\')) { $offset = strpos($pmid, ')]', ($offset + 1)); } if ($offset === false) { $this->Error('HTML Justification: malformed PDF code.'); } continue; } if ($this->rtl OR $this->tmprtl) { $spacew = ($spacewidth * ($nsmax - $ns)); } else { $spacew = ($spacewidth * $ns); } $offset = $strpiece[2][1] + strlen($strpiece[2][0]); $epsposbeg = strpos($pmid, 'q'.$this->epsmarker, $offset); $epsposend = strpos($pmid, $this->epsmarker.'Q', $offset) + strlen($this->epsmarker.'Q'); if ((($epsposbeg > 0) AND ($epsposend > 0) AND ($offset > $epsposbeg) AND ($offset < $epsposend)) OR (($epsposbeg === false) AND ($epsposend > 0) AND ($offset < $epsposend))) { // shift EPS images $trx = sprintf('1 0 0 1 %.3F 0 cm', $spacew); $epsposbeg = strpos($pmid, 'q'.$this->epsmarker, ($prev_epsposbeg - 6)); $pmid_b = substr($pmid, 0, $epsposbeg); $pmid_m = substr($pmid, $epsposbeg, ($epsposend - $epsposbeg)); $pmid_e = substr($pmid, $epsposend); $pmid = $pmid_b."\nq\n".$trx."\n".$pmid_m."\nQ\n".$pmid_e; $offset = $epsposend; continue; } $prev_epsposbeg = $epsposbeg; $currentxpos = 0; // shift blocks of code switch ($strpiece[2][0]) { case 'Td': case 'cm': case 'm': case 'l': { // get current X position preg_match('/([0-9\.\+\-]*)[\s]('.$strpiece[1][0].')[\s]('.$strpiece[2][0].')([\s]*)/x', $pmid, $xmatches); $currentxpos = $xmatches[1]; if (($strcount <= $maxkk) AND ($strpiece[2][0] == 'Td')) { if ($strcount == $maxkk) { if ($this->rtl OR $this->tmprtl) { $tvalue = $lnstring[1][$strcount]; } else { $tvalue = rtrim($lnstring[1][$strcount]); } } else { $tvalue = $lnstring[1][$strcount]; } $ns += substr_count($tvalue, chr(32)); ++$strcount; } if ($this->rtl OR $this->tmprtl) { $spacew = ($spacewidth * ($nsmax - $ns)); } // justify block $pmid = preg_replace_callback('/([0-9\.\+\-]*)[\s]('.$strpiece[1][0].')[\s]('.$strpiece[2][0].')([\s]*)/x', create_function('$matches', 'global $spacew; $newx = sprintf("%.2F",(floatval($matches[1]) + $spacew)); return "".$newx." ".$matches[2]." x*#!#*x".$matches[3].$matches[4];'), $pmid, 1); break; } case 're': { // get current X position preg_match('/([0-9\.\+\-]*)[\s]([0-9\.\+\-]*)[\s]([0-9\.\+\-]*)[\s]('.$strpiece[1][0].')[\s]('.$strpiece[2][0].')([\s]*)/x', $pmid, $xmatches); $currentxpos = $xmatches[1]; // justify block $pmid = preg_replace_callback('/([0-9\.\+\-]*)[\s]([0-9\.\+\-]*)[\s]([0-9\.\+\-]*)[\s]('.$strpiece[1][0].')[\s]('.$strpiece[2][0].')([\s]*)/x', create_function('$matches', 'global $spacew; $newx = sprintf("%.2F",(floatval($matches[1]) + $spacew)); return "".$newx." ".$matches[2]." ".$matches[3]." ".$matches[4]." x*#!#*x".$matches[5].$matches[6];'), $pmid, 1); break; } case 'c': { // get current X position preg_match('/([0-9\.\+\-]*)[\s]([0-9\.\+\-]*)[\s]([0-9\.\+\-]*)[\s]([0-9\.\+\-]*)[\s]([0-9\.\+\-]*)[\s]('.$strpiece[1][0].')[\s]('.$strpiece[2][0].')([\s]*)/x', $pmid, $xmatches); $currentxpos = $xmatches[1]; // justify block $pmid = preg_replace_callback('/([0-9\.\+\-]*)[\s]([0-9\.\+\-]*)[\s]([0-9\.\+\-]*)[\s]([0-9\.\+\-]*)[\s]([0-9\.\+\-]*)[\s]('.$strpiece[1][0].')[\s]('.$strpiece[2][0].')([\s]*)/x', create_function('$matches', 'global $spacew; $newx1 = sprintf("%.3F",(floatval($matches[1]) + $spacew)); $newx2 = sprintf("%.3F",(floatval($matches[3]) + $spacew)); $newx3 = sprintf("%.3F",(floatval($matches[5]) + $spacew)); return "".$newx1." ".$matches[2]." ".$newx2." ".$matches[4]." ".$newx3." ".$matches[6]." x*#!#*x".$matches[7].$matches[8];'), $pmid, 1); break; } } // shift the annotations and links if (isset($this->PageAnnots[$this->page])) { foreach ($this->PageAnnots[$this->page] as $pak => $pac) { if (($pac['y'] >= $minstartliney) AND (($pac['x'] * $this->k) >= ($currentxpos - $this->feps)) AND (($pac['x'] * $this->k) <= ($currentxpos + $this->feps))) { $this->PageAnnots[$this->page][$pak]['x'] += ($spacew / $this->k); $this->PageAnnots[$this->page][$pak]['w'] += (($spacewidth * $pac['numspaces']) / $this->k); break; } } } } // end of while // remove markers $pmid = str_replace('x*#!#*x', '', $pmid); if (($this->CurrentFont['type'] == 'TrueTypeUnicode') OR ($this->CurrentFont['type'] == 'cidfont0')) { // multibyte characters $spacew = $spacewidthu; $pmidtemp = $pmid; // escape special characters $pmidtemp = preg_replace('/[\\\][\(]/x', '\\#!#OP#!#', $pmidtemp); $pmidtemp = preg_replace('/[\\\][\)]/x', '\\#!#CP#!#', $pmidtemp); $pmid = preg_replace_callback("/\[\(([^\)]*)\)\]/x", create_function('$matches', 'global $spacew; $matches[1] = str_replace("#!#OP#!#", "(", $matches[1]); $matches[1] = str_replace("#!#CP#!#", ")", $matches[1]); return "[(".str_replace(chr(0).chr(32), ") ".($spacew)." (", $matches[1]).")]";'), $pmidtemp); $this->setPageBuffer($startlinepage, $pstart."\n".$pmid."\n".$pend); $endlinepos = strlen($pstart."\n".$pmid."\n"); } else { // non-unicode (single-byte characters) $rs = sprintf("%.3F Tw", $spacewidth); $pmid = preg_replace("/\[\(/x", $rs.' [(', $pmid); $this->setPageBuffer($startlinepage, $pstart."\n".$pmid."\nBT 0 Tw ET\n".$pend); $endlinepos = strlen($pstart."\n".$pmid."\nBT 0 Tw ET\n"); } } } // end of J if (($t_x != 0) OR ($yshift < 0)) { // shift the line $trx = sprintf('1 0 0 1 %.3F %.3F cm', ($t_x * $this->k), ($yshift * $this->k)); $this->setPageBuffer($startlinepage, $pstart."\nq\n".$trx."\n".$pmid."\nQ\n".$pend); $endlinepos = strlen($pstart."\nq\n".$trx."\n".$pmid."\nQ\n"); // shift the annotations and links if (isset($this->PageAnnots[$this->page])) { foreach ($this->PageAnnots[$this->page] as $pak => $pac) { if ($pak >= $pask) { $this->PageAnnots[$this->page][$pak]['x'] += $t_x; $this->PageAnnots[$this->page][$pak]['y'] -= $yshift; } } } $this->y -= $yshift; } } } $this->newline = false; $pbrk = $this->checkPageBreak($this->lasth); $this->SetFont($fontname, $fontstyle, $fontsize); if ($wfill) { $this->SetFillColorArray($this->bgcolor); } $startlinex = $this->x; $startliney = $this->y; $minstartliney = $this->y; $startlinepage = $this->page; if (isset($endlinepos) AND (!$pbrk)) { $startlinepos = $endlinepos; unset($endlinepos); } else { if (isset($this->footerlen[$this->page])) { $this->footerpos[$this->page] = $this->pagelen[$this->page] - $this->footerlen[$this->page]; } else { $this->footerpos[$this->page] = $this->pagelen[$this->page]; } $startlinepos = $this->footerpos[$this->page]; } $plalign = $lalign; if (isset($this->PageAnnots[$this->page])) { $pask = count($this->PageAnnots[$this->page]); } else { $pask = 0; } } if (isset($opentagpos)) { unset($opentagpos); } if ($dom[$key]['tag']) { if ($dom[$key]['opening']) { // get text indentation (if any) if (isset($dom[$key]['text-indent']) AND in_array($dom[$key]['value'], array('blockquote','dd','div','dt','h1','h2','h3','h4','h5','h6','li','ol','p','ul','table','tr','td'))) { $this->textindent = $dom[$key]['text-indent']; } if ($dom[$key]['value'] == 'table') { if ($this->rtl) { $wtmp = $this->x - $this->lMargin; } else { $wtmp = $this->w - $this->rMargin - $this->x; } $wtmp -= (2 * $this->cMargin); // calculate cell width if (isset($dom[$key]['width'])) { $table_width = $this->getHTMLUnitToUnits($dom[$key]['width'], $wtmp, 'px'); } else { $table_width = $wtmp; } } // table content is handled in a special way if (($dom[$key]['value'] == 'td') OR ($dom[$key]['value'] == 'th')) { $trid = $dom[$key]['parent']; $table_el = $dom[$trid]['parent']; if (!isset($dom[$table_el]['cols'])) { $dom[$table_el]['cols'] = $trid['cols']; } $oldmargin = $this->cMargin; if (isset($dom[($dom[$trid]['parent'])]['attribute']['cellpadding'])) { $currentcmargin = $this->getHTMLUnitToUnits($dom[($dom[$trid]['parent'])]['attribute']['cellpadding'], 1, 'px'); } else { $currentcmargin = 0; } $this->cMargin = $currentcmargin; if (isset($dom[($dom[$trid]['parent'])]['attribute']['cellspacing'])) { $cellspacing = $this->getHTMLUnitToUnits($dom[($dom[$trid]['parent'])]['attribute']['cellspacing'], 1, 'px'); } else { $cellspacing = 0; } if ($this->rtl) { $cellspacingx = -$cellspacing; } else { $cellspacingx = $cellspacing; } $colspan = $dom[$key]['attribute']['colspan']; $wtmp = ($colspan * ($table_width / $dom[$table_el]['cols'])); if (isset($dom[$key]['width'])) { $cellw = $this->getHTMLUnitToUnits($dom[$key]['width'], $table_width, 'px'); } else { $cellw = $wtmp; } if (isset($dom[$key]['height'])) { // minimum cell height $cellh = $this->getHTMLUnitToUnits($dom[$key]['height'], 0, 'px'); } else { $cellh = 0; } $cellw -= $cellspacing; if (isset($dom[$key]['content'])) { $cell_content = $dom[$key]['content']; } else { $cell_content = ' '; } $tagtype = $dom[$key]['value']; $parentid = $key; while (($key < $maxel) AND (!(($dom[$key]['tag']) AND (!$dom[$key]['opening']) AND ($dom[$key]['value'] == $tagtype) AND ($dom[$key]['parent'] == $parentid)))) { // move $key index forward ++$key; } if (!isset($dom[$trid]['startpage'])) { $dom[$trid]['startpage'] = $this->page; } else { $this->setPage($dom[$trid]['startpage']); } if (!isset($dom[$trid]['starty'])) { $dom[$trid]['starty'] = $this->y; } else { $this->y = $dom[$trid]['starty']; } if (!isset($dom[$trid]['startx'])) { $dom[$trid]['startx'] = $this->x; } $this->x += ($cellspacingx / 2); if (isset($dom[$parentid]['attribute']['rowspan'])) { $rowspan = intval($dom[$parentid]['attribute']['rowspan']); } else { $rowspan = 1; } // skip row-spanned cells started on the previous rows if (isset($dom[$table_el]['rowspans'])) { $rsk = 0; $rskmax = count($dom[$table_el]['rowspans']); while ($rsk < $rskmax) { $trwsp = $dom[$table_el]['rowspans'][$rsk]; $rsstartx = $trwsp['startx']; $rsendx = $trwsp['endx']; // account for margin changes if ($trwsp['startpage'] < $this->page) { if (($this->rtl) AND ($this->pagedim[$this->page]['orm'] != $this->pagedim[$trwsp['startpage']]['orm'])) { $dl = ($this->pagedim[$this->page]['orm'] - $this->pagedim[$trwsp['startpage']]['orm']); $rsstartx -= $dl; $rsendx -= $dl; } elseif ((!$this->rtl) AND ($this->pagedim[$this->page]['olm'] != $this->pagedim[$trwsp['startpage']]['olm'])) { $dl = ($this->pagedim[$this->page]['olm'] - $this->pagedim[$trwsp['startpage']]['olm']); $rsstartx += $dl; $rsendx += $dl; } } if (($trwsp['rowspan'] > 0) AND ($rsstartx > ($this->x - $cellspacing - $currentcmargin - $this->feps)) AND ($rsstartx < ($this->x + $cellspacing + $currentcmargin + $this->feps)) AND (($trwsp['starty'] < ($this->y - $this->feps)) OR ($trwsp['startpage'] < $this->page))) { // set the starting X position of the current cell $this->x = $rsendx + $cellspacingx; if (($trwsp['rowspan'] == 1) AND (isset($dom[$trid]['endy'])) AND (isset($dom[$trid]['endpage'])) AND ($trwsp['endpage'] == $dom[$trid]['endpage'])) { // set ending Y position for row $dom[$table_el]['rowspans'][$rsk]['endy'] = max($dom[$trid]['endy'], $trwsp['endy']); $dom[$trid]['endy'] = $dom[$table_el]['rowspans'][$rsk]['endy']; } $rsk = 0; } else { ++$rsk; } } } // add rowspan information to table element if ($rowspan > 1) { if (isset($this->footerlen[$this->page])) { $this->footerpos[$this->page] = $this->pagelen[$this->page] - $this->footerlen[$this->page]; } else { $this->footerpos[$this->page] = $this->pagelen[$this->page]; } $trintmrkpos = $this->footerpos[$this->page]; $trsid = array_push($dom[$table_el]['rowspans'], array('trid' => $trid, 'rowspan' => $rowspan, 'mrowspan' => $rowspan, 'colspan' => $colspan, 'startpage' => $this->page, 'startx' => $this->x, 'starty' => $this->y, 'intmrkpos' => $trintmrkpos)); } $cellid = array_push($dom[$trid]['cellpos'], array('startx' => $this->x)); if ($rowspan > 1) { $dom[$trid]['cellpos'][($cellid - 1)]['rowspanid'] = ($trsid - 1); } // push background colors if (isset($dom[$parentid]['bgcolor']) AND ($dom[$parentid]['bgcolor'] !== false)) { $dom[$trid]['cellpos'][($cellid - 1)]['bgcolor'] = $dom[$parentid]['bgcolor']; } $prevLastH = $this->lasth; // ****** write the cell content ****** $this->MultiCell($cellw, $cellh, $cell_content, false, $lalign, false, 2, '', '', true, 0, true); $this->lasth = $prevLastH; $this->cMargin = $oldmargin; $dom[$trid]['cellpos'][($cellid - 1)]['endx'] = $this->x; // update the end of row position if ($rowspan <= 1) { if (isset($dom[$trid]['endy'])) { if ($this->page == $dom[$trid]['endpage']) { $dom[$trid]['endy'] = max($this->y, $dom[$trid]['endy']); } elseif ($this->page > $dom[$trid]['endpage']) { $dom[$trid]['endy'] = $this->y; } } else { $dom[$trid]['endy'] = $this->y; } if (isset($dom[$trid]['endpage'])) { $dom[$trid]['endpage'] = max($this->page, $dom[$trid]['endpage']); } else { $dom[$trid]['endpage'] = $this->page; } } else { // account for row-spanned cells $dom[$table_el]['rowspans'][($trsid - 1)]['endx'] = $this->x; $dom[$table_el]['rowspans'][($trsid - 1)]['endy'] = $this->y; $dom[$table_el]['rowspans'][($trsid - 1)]['endpage'] = $this->page; } if (isset($dom[$table_el]['rowspans'])) { // update endy and endpage on rowspanned cells foreach ($dom[$table_el]['rowspans'] as $k => $trwsp) { if ($trwsp['rowspan'] > 0) { if (isset($dom[$trid]['endpage'])) { if ($trwsp['endpage'] == $dom[$trid]['endpage']) { $dom[$table_el]['rowspans'][$k]['endy'] = max($dom[$trid]['endy'], $trwsp['endy']); } elseif ($trwsp['endpage'] < $dom[$trid]['endpage']) { $dom[$table_el]['rowspans'][$k]['endy'] = $dom[$trid]['endy']; $dom[$table_el]['rowspans'][$k]['endpage'] = $dom[$trid]['endpage']; } else { $dom[$trid]['endy'] = $this->pagedim[$dom[$trid]['endpage']]['hk'] - $this->pagedim[$dom[$trid]['endpage']]['bm']; } } } } } $this->x += ($cellspacingx / 2); } else { // opening tag (or self-closing tag) if (!isset($opentagpos)) { if (!$this->InFooter) { if (isset($this->footerlen[$this->page])) { $this->footerpos[$this->page] = $this->pagelen[$this->page] - $this->footerlen[$this->page]; } else { $this->footerpos[$this->page] = $this->pagelen[$this->page]; } $opentagpos = $this->footerpos[$this->page]; } } $this->openHTMLTagHandler($dom, $key, $cell); } } else { // closing tag $this->closeHTMLTagHandler($dom, $key, $cell); } } elseif (strlen($dom[$key]['value']) > 0) { // print list-item if (!$this->empty_string($this->lispacer)) { $this->SetFont($pfontname, $pfontstyle, $pfontsize); $this->lasth = $this->FontSize * $this->cell_height_ratio; $minstartliney = $this->y; $this->putHtmlListBullet($this->listnum, $this->lispacer, $pfontsize); $this->SetFont($curfontname, $curfontstyle, $curfontsize); $this->lasth = $this->FontSize * $this->cell_height_ratio; if (is_numeric($pfontsize) AND ($pfontsize > 0) AND is_numeric($curfontsize) AND ($curfontsize > 0) AND ($pfontsize != $curfontsize)) { $this->y += (($pfontsize - $curfontsize) / $this->k); $minstartliney = min($this->y, $minstartliney); } } // text $this->htmlvspace = 0; if ((!$this->premode) AND ($this->rtl OR $this->tmprtl)) { // reverse spaces order $len1 = strlen($dom[$key]['value']); $lsp = $len1 - strlen(ltrim($dom[$key]['value'])); $rsp = $len1 - strlen(rtrim($dom[$key]['value'])); $tmpstr = ''; if ($rsp > 0) { $tmpstr .= substr($dom[$key]['value'], -$rsp); } $tmpstr .= trim($dom[$key]['value']); if ($lsp > 0) { $tmpstr .= substr($dom[$key]['value'], 0, $lsp); } $dom[$key]['value'] = $tmpstr; } if ($newline) { if (!$this->premode) { if (($this->rtl OR $this->tmprtl)) { $dom[$key]['value'] = rtrim($dom[$key]['value']); } else { $dom[$key]['value'] = ltrim($dom[$key]['value']); } } $newline = false; $firstblock = true; } else { $firstblock = false; } $strrest = ''; if (!empty($this->HREF) AND (isset($this->HREF['url']))) { // HTML Link $strrest = $this->addHtmlLink($this->HREF['url'], $dom[$key]['value'], $wfill, true, $this->HREF['color'], $this->HREF['style']); } else { $ctmpmargin = $this->cMargin; $this->cMargin = 0; if ($this->rtl) { $this->x -= $this->textindent; } else { $this->x += $this->textindent; } // ****** write only until the end of the line and get the rest ****** $strrest = $this->Write($this->lasth, $dom[$key]['value'], '', $wfill, '', false, 0, true, $firstblock); $this->textindent = 0; $this->cMargin = $ctmpmargin; } if (strlen($strrest) > 0) { // store the remaining string on the previous $key position $this->newline = true; if ($cell) { if ($this->rtl) { $this->x -= $this->cMargin; } else { $this->x += $this->cMargin; } } if ($strrest == $dom[$key]['value']) { // used to avoid infinite loop ++$loop; } else { $loop = 0; } $dom[$key]['value'] = ltrim($strrest); if ($loop < 3) { --$key; } } else { $loop = 0; } } ++$key; if (isset($dom[$key]['tag']) AND $dom[$key]['tag'] AND (!isset($dom[$key]['opening']) OR !$dom[$key]['opening']) AND isset($dom[($dom[$key]['parent'])]['attribute']['nobr']) AND ($dom[($dom[$key]['parent'])]['attribute']['nobr'] == 'true')) { if ((!$undo) AND ($this->start_transaction_page == ($this->numpages - 1))) { // restore previous object $this->rollbackTransaction(true); // restore previous values foreach ($this_method_vars as $vkey => $vval) { $$vkey = $vval; } // add a page $this->AddPage(); $undo = true; // avoid infinite loop } else { $undo = false; } } } // end for each $key // align the last line if (isset($startlinex)) { $yshift = $minstartliney - $startliney; if (($yshift > 0) OR ($this->page > $startlinepage)) { $yshift = 0; } if ((isset($plalign) AND ((($plalign == 'C') OR ($plalign == 'J') OR (($plalign == 'R') AND (!$this->rtl)) OR (($plalign == 'L') AND ($this->rtl))))) OR ($yshift < 0)) { // the last line must be shifted to be aligned as requested $linew = abs($this->endlinex - $startlinex); $pstart = substr($this->getPageBuffer($startlinepage), 0, $startlinepos); if (isset($opentagpos) AND isset($this->footerlen[$startlinepage]) AND (!$this->InFooter)) { $this->footerpos[$startlinepage] = $this->pagelen[$startlinepage] - $this->footerlen[$startlinepage]; $midpos = min($opentagpos, $this->footerpos[$startlinepage]); } elseif (isset($opentagpos)) { $midpos = $opentagpos; } elseif (isset($this->footerlen[$startlinepage]) AND (!$this->InFooter)) { $this->footerpos[$startlinepage] = $this->pagelen[$startlinepage] - $this->footerlen[$startlinepage]; $midpos = $this->footerpos[$startlinepage]; } else { $midpos = 0; } if ($midpos > 0) { $pmid = substr($this->getPageBuffer($startlinepage), $startlinepos, ($midpos - $startlinepos)); $pend = substr($this->getPageBuffer($startlinepage), $midpos); } else { $pmid = substr($this->getPageBuffer($startlinepage), $startlinepos); $pend = ''; } // calculate shifting amount $tw = $w; if ($this->lMargin != $prevlMargin) { $tw += ($prevlMargin - $this->lMargin); } if ($this->rMargin != $prevrMargin) { $tw += ($prevrMargin - $this->rMargin); } $mdiff = abs($tw - $linew); if ($plalign == 'C') { if ($this->rtl) { $t_x = -($mdiff / 2); } else { $t_x = ($mdiff / 2); } } elseif (($plalign == 'R') AND (!$this->rtl)) { // right alignment on LTR document $t_x = $mdiff; } elseif (($plalign == 'L') AND ($this->rtl)) { // left alignment on RTL document $t_x = -$mdiff; } else { $t_x = 0; } if (($t_x != 0) OR ($yshift < 0)) { // shift the line $trx = sprintf('1 0 0 1 %.3F %.3F cm', ($t_x * $this->k), ($yshift * $this->k)); $this->setPageBuffer($startlinepage, $pstart."\nq\n".$trx."\n".$pmid."\nQ\n".$pend); $endlinepos = strlen($pstart."\nq\n".$trx."\n".$pmid."\nQ\n"); // shift the annotations and links if (isset($this->PageAnnots[$this->page])) { foreach ($this->PageAnnots[$this->page] as $pak => $pac) { if ($pak >= $pask) { $this->PageAnnots[$this->page][$pak]['x'] += $t_x; $this->PageAnnots[$this->page][$pak]['y'] -= $yshift; } } } $this->y -= $yshift; } } } if ($ln AND (!($cell AND ($dom[$key-1]['value'] == 'table')))) { $this->Ln($this->lasth); } // restore previous values $this->setGraphicVars($gvars); if ($this->page > $prevPage) { $this->lMargin = $this->pagedim[$this->page]['olm']; $this->rMargin = $this->pagedim[$this->page]['orm']; } // restore previous list state $this->listnum = $prev_listnum; $this->listordered = $prev_listordered; $this->listcount = $prev_listcount; $this->lispacer = $prev_lispacer; unset($dom); } /** * Process opening tags. * @param array $dom html dom array * @param int $key current element id * @param boolean $cell if true add the default cMargin space to each new line (default false). * @access protected */ protected function openHTMLTagHandler(&$dom, $key, $cell=false) { $tag = $dom[$key]; $parent = $dom[($dom[$key]['parent'])]; $firstorlast = ($key == 1); // check for text direction attribute if (isset($tag['attribute']['dir'])) { $this->tmprtl = $tag['attribute']['dir'] == 'rtl' ? 'R' : 'L'; } else { $this->tmprtl = false; } //Opening tag switch($tag['value']) { case 'table': { $cp = 0; $cs = 0; $dom[$key]['rowspans'] = array(); if (!$this->empty_string($dom[$key]['thead'])) { // set table header $this->thead = $dom[$key]['thead']; if (!isset($this->theadMargins) OR (empty($this->theadMargins))) { $this->theadMargins = array(); $this->theadMargins['cmargin'] = $this->cMargin; } } if (isset($tag['attribute']['cellpadding'])) { $cp = $this->getHTMLUnitToUnits($tag['attribute']['cellpadding'], 1, 'px'); $this->oldcMargin = $this->cMargin; $this->cMargin = $cp; } if (isset($tag['attribute']['cellspacing'])) { $cs = $this->getHTMLUnitToUnits($tag['attribute']['cellspacing'], 1, 'px'); } $this->checkPageBreak((2 * $cp) + (2 * $cs) + $this->lasth); break; } case 'tr': { // array of columns positions $dom[$key]['cellpos'] = array(); break; } case 'hr': { $this->addHTMLVertSpace(1, $cell, '', $firstorlast, $tag['value'], false); $this->htmlvspace = 0; $wtmp = $this->w - $this->lMargin - $this->rMargin; if ((isset($tag['attribute']['width'])) AND ($tag['attribute']['width'] != '')) { $hrWidth = $this->getHTMLUnitToUnits($tag['attribute']['width'], $wtmp, 'px'); } else { $hrWidth = $wtmp; } $x = $this->GetX(); $y = $this->GetY(); $prevlinewidth = $this->GetLineWidth(); $this->Line($x, $y, $x + $hrWidth, $y); $this->SetLineWidth($prevlinewidth); $this->addHTMLVertSpace(1, $cell, '', !isset($dom[($key + 1)]), $tag['value'], false); break; } case 'a': { if (array_key_exists('href', $tag['attribute'])) { $this->HREF['url'] = $tag['attribute']['href']; } $this->HREF['color'] = $this->htmlLinkColorArray; $this->HREF['style'] = $this->htmlLinkFontStyle; if (array_key_exists('style', $tag['attribute'])) { // get style attributes preg_match_all('/([^;:\s]*):([^;]*)/', $tag['attribute']['style'], $style_array, PREG_PATTERN_ORDER); $astyle = array(); while (list($id, $name) = each($style_array[1])) { $name = strtolower($name); $astyle[$name] = trim($style_array[2][$id]); } if (isset($astyle['color'])) { $this->HREF['color'] = $this->convertHTMLColorToDec($astyle['color']); } if (isset($astyle['text-decoration'])) { $this->HREF['style'] = ''; $decors = explode(' ', strtolower($astyle['text-decoration'])); foreach ($decors as $dec) { $dec = trim($dec); if (!$this->empty_string($dec)) { if ($dec{0} == 'u') { $this->HREF['style'] .= 'U'; } elseif ($dec{0} == 'l') { $this->HREF['style'] .= 'D'; } } } } } break; } case 'img': { if (isset($tag['attribute']['src'])) { // replace relative path with real server path if (($tag['attribute']['src'][0] == '/') AND ($_SERVER['DOCUMENT_ROOT'] != '/')) { $tag['attribute']['src'] = $_SERVER['DOCUMENT_ROOT'].$tag['attribute']['src']; } $tag['attribute']['src'] = urldecode($tag['attribute']['src']); $tag['attribute']['src'] = str_replace(K_PATH_URL, K_PATH_MAIN, $tag['attribute']['src']); if (!isset($tag['attribute']['width'])) { $tag['attribute']['width'] = 0; } if (!isset($tag['attribute']['height'])) { $tag['attribute']['height'] = 0; } //if (!isset($tag['attribute']['align'])) { // the only alignment supported is "bottom" // further development is required for other modes. $tag['attribute']['align'] = 'bottom'; //} switch($tag['attribute']['align']) { case 'top': { $align = 'T'; break; } case 'middle': { $align = 'M'; break; } case 'bottom': { $align = 'B'; break; } default: { $align = 'B'; break; } } $fileinfo = pathinfo($tag['attribute']['src']); if (isset($fileinfo['extension']) AND (!$this->empty_string($fileinfo['extension']))) { $type = strtolower($fileinfo['extension']); } $prevy = $this->y; $xpos = $this->GetX(); if (isset($dom[($key - 1)]) AND ($dom[($key - 1)]['value'] == ' ')) { if ($this->rtl) { $xpos += $this->GetStringWidth(' '); } else { $xpos -= $this->GetStringWidth(' '); } } $imglink = ''; if (isset($this->HREF['url']) AND !$this->empty_string($this->HREF['url'])) { $imglink = $this->HREF['url']; if ($imglink{0} == '#') { // convert url to internal link $page = intval(substr($imglink, 1)); $imglink = $this->AddLink(); $this->SetLink($imglink, 0, $page); } } $border = 0; if (isset($tag['attribute']['border']) AND !empty($tag['attribute']['border'])) { // currently only support 1 (frame) or a combination of 'LTRB' $border = $tag['attribute']['border']; } $iw = ''; if (isset($tag['attribute']['width'])) { $iw = $this->getHTMLUnitToUnits($tag['attribute']['width'], 1, 'px', false); } $ih = ''; if (isset($tag['attribute']['height'])) { $ih = $this->getHTMLUnitToUnits($tag['attribute']['height'], 1, 'px', false); } if (($type == 'eps') OR ($type == 'ai')) { $this->ImageEps($tag['attribute']['src'], $xpos, $this->GetY(), $iw, $ih, $imglink, true, $align, '', $border); } else { $this->Image($tag['attribute']['src'], $xpos, $this->GetY(), $iw, $ih, '', $imglink, $align, false, 300, '', false, false, $border); } switch($align) { case 'T': { $this->y = $prevy; break; } case 'M': { $this->y = (($this->img_rb_y + $prevy - ($tag['fontsize'] / $this->k)) / 2) ; break; } case 'B': { $this->y = $this->img_rb_y - ($tag['fontsize'] / $this->k); break; } } } break; } case 'dl': { ++$this->listnum; $this->addHTMLVertSpace(0, $cell, '', $firstorlast, $tag['value'], false); break; } case 'dt': { $this->addHTMLVertSpace(1, $cell, '', $firstorlast, $tag['value'], false); break; } case 'dd': { if ($this->rtl) { $this->rMargin += $this->listindent; } else { $this->lMargin += $this->listindent; } $this->addHTMLVertSpace(1, $cell, '', $firstorlast, $tag['value'], false); break; } case 'ul': case 'ol': { $this->addHTMLVertSpace(0, $cell, '', $firstorlast, $tag['value'], false); $this->htmlvspace = 0; ++$this->listnum; if ($tag['value'] == 'ol') { $this->listordered[$this->listnum] = true; } else { $this->listordered[$this->listnum] = false; } if (isset($tag['attribute']['start'])) { $this->listcount[$this->listnum] = intval($tag['attribute']['start']) - 1; } else { $this->listcount[$this->listnum] = 0; } if ($this->rtl) { $this->rMargin += $this->listindent; } else { $this->lMargin += $this->listindent; } $this->addHTMLVertSpace(0, $cell, '', $firstorlast, $tag['value'], false); $this->htmlvspace = 0; break; } case 'li': { $this->addHTMLVertSpace(1, $cell, '', $firstorlast, $tag['value'], false); if ($this->listordered[$this->listnum]) { // ordered item if (isset($parent['attribute']['type']) AND !$this->empty_string($parent['attribute']['type'])) { $this->lispacer = $parent['attribute']['type']; } elseif (isset($parent['listtype']) AND !$this->empty_string($parent['listtype'])) { $this->lispacer = $parent['listtype']; } elseif (isset($this->lisymbol) AND !$this->empty_string($this->lisymbol)) { $this->lispacer = $this->lisymbol; } else { $this->lispacer = '#'; } ++$this->listcount[$this->listnum]; if (isset($tag['attribute']['value'])) { $this->listcount[$this->listnum] = intval($tag['attribute']['value']); } } else { // unordered item if (isset($parent['attribute']['type']) AND !$this->empty_string($parent['attribute']['type'])) { $this->lispacer = $parent['attribute']['type']; } elseif (isset($parent['listtype']) AND !$this->empty_string($parent['listtype'])) { $this->lispacer = $parent['listtype']; } elseif (isset($this->lisymbol) AND !$this->empty_string($this->lisymbol)) { $this->lispacer = $this->lisymbol; } else { $this->lispacer = '!'; } } break; } case 'blockquote': { if ($this->rtl) { $this->rMargin += $this->listindent; } else { $this->lMargin += $this->listindent; } $this->addHTMLVertSpace(2, $cell, '', $firstorlast, $tag['value'], false); break; } case 'br': { $this->Ln('', $cell); break; } case 'div': { $this->addHTMLVertSpace(1, $cell, '', $firstorlast, $tag['value'], false); break; } case 'p': { $this->addHTMLVertSpace(2, $cell, '', $firstorlast, $tag['value'], false); break; } case 'pre': { $this->addHTMLVertSpace(1, $cell, '', $firstorlast, $tag['value'], false); $this->premode = true; break; } case 'sup': { $this->SetXY($this->GetX(), $this->GetY() - ((0.7 * $this->FontSizePt) / $this->k)); break; } case 'sub': { $this->SetXY($this->GetX(), $this->GetY() + ((0.3 * $this->FontSizePt) / $this->k)); break; } case 'h1': case 'h2': case 'h3': case 'h4': case 'h5': case 'h6': { $this->addHTMLVertSpace(1, $cell, ($tag['fontsize'] * 1.5) / $this->k, $firstorlast, $tag['value'], false); break; } // Form fields (since 4.8.000 - 2009-09-07) case 'form': { if (isset($tag['attribute']['action'])) { $this->form_action = $tag['attribute']['action']; } else { $this->form_action = K_PATH_URL.$_SERVER['SCRIPT_NAME']; } if (isset($tag['attribute']['enctype'])) { $this->form_enctype = $tag['attribute']['enctype']; } else { $this->form_enctype = 'application/x-www-form-urlencoded'; } if (isset($tag['attribute']['method'])) { $this->form_mode = $tag['attribute']['method']; } else { $this->form_mode = 'post'; } break; } case 'input': { if (isset($tag['attribute']['name']) AND !$this->empty_string($tag['attribute']['name'])) { $name = $tag['attribute']['name']; } else { break; } $prop = array(); $opt = array(); if (isset($tag['attribute']['value']) AND !$this->empty_string($tag['attribute']['value'])) { $value = $tag['attribute']['value']; } if (isset($tag['attribute']['maxlength']) AND !$this->empty_string($tag['attribute']['maxlength'])) { $opt['maxlen'] = intval($tag['attribute']['value']); } $h = $this->FontSize * $this->cell_height_ratio; if (isset($tag['attribute']['size']) AND !$this->empty_string($tag['attribute']['size'])) { $w = intval($tag['attribute']['size']) * $this->GetStringWidth(chr(32)) * 2; } else { $w = $h; } if (isset($tag['attribute']['checked']) AND (($tag['attribute']['checked'] == 'checked') OR ($tag['attribute']['checked'] == 'true'))) { $checked = true; } else { $checked = false; } switch ($tag['attribute']['type']) { case 'text': { if (isset($value)) { $opt['v'] = $value; } $this->TextField($name, $w, $h, $prop, $opt, '', '', false); break; } case 'password': { if (isset($value)) { $opt['v'] = $value; } $prop['password'] = 'true'; $this->TextField($name, $w, $h, $prop, $opt, '', '', false); break; } case 'checkbox': { $this->CheckBox($name, $w, $checked, $prop, $opt, $value, '', '', false); break; } case 'radio': { $this->RadioButton($name, $w, $prop, $opt, $value, $checked, '', '', false); break; } case 'submit': { $w = $this->GetStringWidth($value) * 1.5; $h *= 1.6; $prop = array('lineWidth'=>1, 'borderStyle'=>'beveled', 'fillColor'=>array(196, 196, 196), 'strokeColor'=>array(255, 255, 255)); $action = array(); $action['S'] = 'SubmitForm'; $action['F'] = $this->form_action; if ($this->form_enctype != 'FDF') { $action['Flags'] = array('ExportFormat'); } if ($this->form_mode == 'get') { $action['Flags'] = array('GetMethod'); } $this->Button($name, $w, $h, $value, $action, $prop, $opt, '', '', false); break; } case 'reset': { $w = $this->GetStringWidth($value) * 1.5; $h *= 1.6; $prop = array('lineWidth'=>1, 'borderStyle'=>'beveled', 'fillColor'=>array(196, 196, 196), 'strokeColor'=>array(255, 255, 255)); $this->Button($name, $w, $h, $value, array('S'=>'ResetForm'), $prop, $opt, '', '', false); break; } case 'file': { $prop['fileSelect'] = 'true'; $this->TextField($name, $w, $h, $prop, $opt, '', '', false); if (!isset($value)) { $value = '*'; } $w = $this->GetStringWidth($value) * 2; $h *= 1.2; $prop = array('lineWidth'=>1, 'borderStyle'=>'beveled', 'fillColor'=>array(196, 196, 196), 'strokeColor'=>array(255, 255, 255)); $jsaction = 'var f=this.getField(\''.$name.'\'); f.browseForFileToSubmit();'; $this->Button('FB_'.$name, $w, $h, $value, $jsaction, $prop, $opt, '', '', false); break; } case 'hidden': { if (isset($value)) { $opt['v'] = $value; } $opt['f'] = array('invisible', 'hidden'); $this->TextField($name, 0, 0, $prop, $opt, '', '', false); break; } case 'image': { // THIS TYPE MUST BE FIXED if (isset($tag['attribute']['src']) AND !$this->empty_string($tag['attribute']['src'])) { $img = $tag['attribute']['src']; } else { break; } $value = 'img'; //$opt['mk'] = array('i'=>$img, 'tp'=>1, 'if'=>array('sw'=>'A', 's'=>'A', 'fb'=>false)); if (isset($tag['attribute']['onclick']) AND !empty($tag['attribute']['onclick'])) { $jsaction = $tag['attribute']['onclick']; } else { $jsaction = ''; } $this->Button($name, $w, $h, $value, $jsaction, $prop, $opt, '', '', false); break; } case 'button': { $w = $this->GetStringWidth($value) * 1.5; $h *= 1.6; $prop = array('lineWidth'=>1, 'borderStyle'=>'beveled', 'fillColor'=>array(196, 196, 196), 'strokeColor'=>array(255, 255, 255)); if (isset($tag['attribute']['onclick']) AND !empty($tag['attribute']['onclick'])) { $jsaction = $tag['attribute']['onclick']; } else { $jsaction = ''; } $this->Button($name, $w, $h, $value, $jsaction, $prop, $opt, '', '', false); break; } } break; } case 'textarea': { $prop = array(); $opt = array(); if (isset($tag['attribute']['name']) AND !$this->empty_string($tag['attribute']['name'])) { $name = $tag['attribute']['name']; } else { break; } if (isset($tag['attribute']['value']) AND !$this->empty_string($tag['attribute']['value'])) { $opt['v'] = $tag['attribute']['value']; } if (isset($tag['attribute']['cols']) AND !$this->empty_string($tag['attribute']['cols'])) { $w = intval($tag['attribute']['cols']) * $this->GetStringWidth(chr(32)) * 2; } else { $w = 40; } if (isset($tag['attribute']['rows']) AND !$this->empty_string($tag['attribute']['rows'])) { $h = intval($tag['attribute']['rows']) * $this->FontSize * $this->cell_height_ratio; } else { $h = 10; } $prop['multiline'] = 'true'; $this->TextField($name, $w, $h, $prop, $opt, '', '', false); break; } case 'select': { $h = $this->FontSize * $this->cell_height_ratio; if (isset($tag['attribute']['size']) AND !$this->empty_string($tag['attribute']['size'])) { $h *= ($tag['attribute']['size'] + 1); } $prop = array(); $opt = array(); if (isset($tag['attribute']['name']) AND !$this->empty_string($tag['attribute']['name'])) { $name = $tag['attribute']['name']; } else { break; } $w = 0; if (isset($tag['attribute']['opt']) AND !$this->empty_string($tag['attribute']['opt'])) { $options = explode ("\r", $tag['attribute']['opt']); $values = array(); foreach ($options as $val) { if (strpos($val, "\t") !== false) { $opts = explode("\t", $val); $values[] = $opts; $w = max($w, $this->GetStringWidth($opts[1])); } else { $values[] = $val; $w = max($w, $this->GetStringWidth($val)); } } } else { break; } $w *= 2; if (isset($tag['attribute']['multiple']) AND ($tag['attribute']['multiple']='multiple')) { $prop['multipleSelection'] = 'true'; $this->ListBox($name, $w, $h, $values, $prop, $opt, '', '', false); } else { $this->ComboBox($name, $w, $h, $values, $prop, $opt, '', '', false); } break; } case 'tcpdf': { // NOT HTML: used to call TCPDF methods if (isset($tag['attribute']['method'])) { $tcpdf_method = $tag['attribute']['method']; if (method_exists($this, $tcpdf_method)) { if (isset($tag['attribute']['params']) AND (!empty($tag['attribute']['params']))) { eval('$params = array('.$this->unhtmlentities($tag['attribute']['params']).');'); call_user_func_array(array($this, $tcpdf_method), $params); } else { $this->$tcpdf_method(); } $this->newline = true; } } } default: { break; } } } /** * Process closing tags. * @param array $dom html dom array * @param int $key current element id * @param boolean $cell if true add the default cMargin space to each new line (default false). * @access protected */ protected function closeHTMLTagHandler(&$dom, $key, $cell=false) { $tag = $dom[$key]; $parent = $dom[($dom[$key]['parent'])]; $firstorlast = ((!isset($dom[($key + 1)])) OR ((!isset($dom[($key + 2)])) AND ($dom[($key + 1)]['value'] == 'marker'))); $in_table_head = false; //Closing tag switch($tag['value']) { case 'tr': { $table_el = $dom[($dom[$key]['parent'])]['parent']; if(!isset($parent['endy'])) { $dom[($dom[$key]['parent'])]['endy'] = $this->y; $parent['endy'] = $this->y; } if(!isset($parent['endpage'])) { $dom[($dom[$key]['parent'])]['endpage'] = $this->page; $parent['endpage'] = $this->page; } // update row-spanned cells if (isset($dom[$table_el]['rowspans'])) { foreach ($dom[$table_el]['rowspans'] as $k => $trwsp) { $dom[$table_el]['rowspans'][$k]['rowspan'] -= 1; if ($dom[$table_el]['rowspans'][$k]['rowspan'] == 0) { if ($dom[$table_el]['rowspans'][$k]['endpage'] == $parent['endpage']) { $dom[($dom[$key]['parent'])]['endy'] = max($dom[$table_el]['rowspans'][$k]['endy'], $parent['endy']); } elseif ($dom[$table_el]['rowspans'][$k]['endpage'] > $parent['endpage']) { $dom[($dom[$key]['parent'])]['endy'] = $dom[$table_el]['rowspans'][$k]['endy']; $dom[($dom[$key]['parent'])]['endpage'] = $dom[$table_el]['rowspans'][$k]['endpage']; } } } // report new endy and endpage to the rowspanned cells foreach ($dom[$table_el]['rowspans'] as $k => $trwsp) { if ($dom[$table_el]['rowspans'][$k]['rowspan'] == 0) { $dom[$table_el]['rowspans'][$k]['endpage'] = max($dom[$table_el]['rowspans'][$k]['endpage'], $dom[($dom[$key]['parent'])]['endpage']); $dom[($dom[$key]['parent'])]['endpage'] = $dom[$table_el]['rowspans'][$k]['endpage']; $dom[$table_el]['rowspans'][$k]['endy'] = max($dom[$table_el]['rowspans'][$k]['endy'], $dom[($dom[$key]['parent'])]['endy']); $dom[($dom[$key]['parent'])]['endy'] = $dom[$table_el]['rowspans'][$k]['endy']; } } // update remaining rowspanned cells foreach ($dom[$table_el]['rowspans'] as $k => $trwsp) { if ($dom[$table_el]['rowspans'][$k]['rowspan'] == 0) { $dom[$table_el]['rowspans'][$k]['endpage'] = $dom[($dom[$key]['parent'])]['endpage']; $dom[$table_el]['rowspans'][$k]['endy'] = $dom[($dom[$key]['parent'])]['endy']; } } } $this->setPage($dom[($dom[$key]['parent'])]['endpage']); $this->y = $dom[($dom[$key]['parent'])]['endy']; if (isset($dom[$table_el]['attribute']['cellspacing'])) { $cellspacing = $this->getHTMLUnitToUnits($dom[$table_el]['attribute']['cellspacing'], 1, 'px'); $this->y += $cellspacing; } $this->Ln(0, $cell); $this->x = $parent['startx']; // account for booklet mode if ($this->page > $parent['startpage']) { if (($this->rtl) AND ($this->pagedim[$this->page]['orm'] != $this->pagedim[$parent['startpage']]['orm'])) { $this->x += ($this->pagedim[$this->page]['orm'] - $this->pagedim[$parent['startpage']]['orm']); } elseif ((!$this->rtl) AND ($this->pagedim[$this->page]['olm'] != $this->pagedim[$parent['startpage']]['olm'])) { $this->x += ($this->pagedim[$this->page]['olm'] - $this->pagedim[$parent['startpage']]['olm']); } } break; } case 'tablehead': // closing tag used for the thead part $in_table_head = true; case 'table': { // draw borders $table_el = $parent; if ((isset($table_el['attribute']['border']) AND ($table_el['attribute']['border'] > 0)) OR (isset($table_el['style']['border']) AND ($table_el['style']['border'] > 0))) { $border = 1; } else { $border = 0; } // fix bottom line alignment of last line before page break foreach ($dom[($dom[$key]['parent'])]['trids'] as $j => $trkey) { // update row-spanned cells if (isset($dom[($dom[$key]['parent'])]['rowspans'])) { foreach ($dom[($dom[$key]['parent'])]['rowspans'] as $k => $trwsp) { if ($trwsp['trid'] == $trkey) { $dom[($dom[$key]['parent'])]['rowspans'][$k]['mrowspan'] -= 1; } if (isset($prevtrkey) AND ($trwsp['trid'] == $prevtrkey) AND ($trwsp['mrowspan'] >= 0)) { $dom[($dom[$key]['parent'])]['rowspans'][$k]['trid'] = $trkey; } } } if (isset($prevtrkey) AND ($dom[$trkey]['startpage'] > $dom[$prevtrkey]['endpage'])) { $pgendy = $this->pagedim[$dom[$prevtrkey]['endpage']]['hk'] - $this->pagedim[$dom[$prevtrkey]['endpage']]['bm']; $dom[$prevtrkey]['endy'] = $pgendy; // update row-spanned cells if (isset($dom[($dom[$key]['parent'])]['rowspans'])) { foreach ($dom[($dom[$key]['parent'])]['rowspans'] as $k => $trwsp) { if (($trwsp['trid'] == $trkey) AND ($trwsp['mrowspan'] == 1) AND ($trwsp['endpage'] == $dom[$prevtrkey]['endpage'])) { $dom[($dom[$key]['parent'])]['rowspans'][$k]['endy'] = $pgendy; $dom[($dom[$key]['parent'])]['rowspans'][$k]['mrowspan'] = -1; } } } } $prevtrkey = $trkey; $table_el = $dom[($dom[$key]['parent'])]; } // for each row foreach ($table_el['trids'] as $j => $trkey) { $parent = $dom[$trkey]; // for each cell on the row foreach ($parent['cellpos'] as $k => $cellpos) { if (isset($cellpos['rowspanid']) AND ($cellpos['rowspanid'] >= 0)) { $cellpos['startx'] = $table_el['rowspans'][($cellpos['rowspanid'])]['startx']; $cellpos['endx'] = $table_el['rowspans'][($cellpos['rowspanid'])]['endx']; $endy = $table_el['rowspans'][($cellpos['rowspanid'])]['endy']; $startpage = $table_el['rowspans'][($cellpos['rowspanid'])]['startpage']; $endpage = $table_el['rowspans'][($cellpos['rowspanid'])]['endpage']; } else { $endy = $parent['endy']; $startpage = $parent['startpage']; $endpage = $parent['endpage']; } if ($endpage > $startpage) { // design borders around HTML cells. for ($page=$startpage; $page <= $endpage; ++$page) { $this->setPage($page); if ($page == $startpage) { $this->y = $parent['starty']; // put cursor at the beginning of row on the first page $ch = $this->getPageHeight() - $parent['starty'] - $this->getBreakMargin(); $cborder = $this->getBorderMode($border, $position='start'); } elseif ($page == $endpage) { $this->y = $this->tMargin; // put cursor at the beginning of last page $ch = $endy - $this->tMargin; $cborder = $this->getBorderMode($border, $position='end'); } else { $this->y = $this->tMargin; // put cursor at the beginning of the current page $ch = $this->getPageHeight() - $this->tMargin - $this->getBreakMargin(); $cborder = $this->getBorderMode($border, $position='middle'); } if (isset($cellpos['bgcolor']) AND ($cellpos['bgcolor']) !== false) { $this->SetFillColorArray($cellpos['bgcolor']); $fill = true; } else { $fill = false; } $cw = abs($cellpos['endx'] - $cellpos['startx']); $this->x = $cellpos['startx']; // account for margin changes if ($page > $startpage) { if (($this->rtl) AND ($this->pagedim[$page]['orm'] != $this->pagedim[$startpage]['orm'])) { $this->x -= ($this->pagedim[$page]['orm'] - $this->pagedim[$startpage]['orm']); } elseif ((!$this->rtl) AND ($this->pagedim[$page]['lm'] != $this->pagedim[$startpage]['olm'])) { $this->x += ($this->pagedim[$page]['olm'] - $this->pagedim[$startpage]['olm']); } } // design a cell around the text $ccode = $this->FillColor."\n".$this->getCellCode($cw, $ch, '', $cborder, 1, '', $fill, '', 0, true); if ($cborder OR $fill) { $pagebuff = $this->getPageBuffer($this->page); $pstart = substr($pagebuff, 0, $this->intmrk[$this->page]); $pend = substr($pagebuff, $this->intmrk[$this->page]); $this->setPageBuffer($this->page, $pstart.$ccode."\n".$pend); $this->intmrk[$this->page] += strlen($ccode."\n"); } } } else { $this->setPage($startpage); if (isset($cellpos['bgcolor']) AND ($cellpos['bgcolor']) !== false) { $this->SetFillColorArray($cellpos['bgcolor']); $fill = true; } else { $fill = false; } $this->x = $cellpos['startx']; $this->y = $parent['starty']; $cw = abs($cellpos['endx'] - $cellpos['startx']); $ch = $endy - $parent['starty']; // design a cell around the text $ccode = $this->FillColor."\n".$this->getCellCode($cw, $ch, '', $border, 1, '', $fill, '', 0, true); if ($border OR $fill) { if (end($this->transfmrk[$this->page]) !== false) { $pagemarkkey = key($this->transfmrk[$this->page]); $pagemark = &$this->transfmrk[$this->page][$pagemarkkey]; } elseif ($this->InFooter) { $pagemark = &$this->footerpos[$this->page]; } else { $pagemark = &$this->intmrk[$this->page]; } $pagebuff = $this->getPageBuffer($this->page); $pstart = substr($pagebuff, 0, $pagemark); $pend = substr($pagebuff, $pagemark); $this->setPageBuffer($this->page, $pstart.$ccode."\n".$pend); $pagemark += strlen($ccode."\n"); } } } if (isset($table_el['attribute']['cellspacing'])) { $cellspacing = $this->getHTMLUnitToUnits($table_el['attribute']['cellspacing'], 1, 'px'); $this->y += $cellspacing; } $this->Ln(0, $cell); $this->x = $parent['startx']; if ($endpage > $startpage) { if (($this->rtl) AND ($this->pagedim[$endpage]['orm'] != $this->pagedim[$startpage]['orm'])) { $this->x += ($this->pagedim[$endpage]['orm'] - $this->pagedim[$startpage]['orm']); } elseif ((!$this->rtl) AND ($this->pagedim[$endpage]['olm'] != $this->pagedim[$startpage]['olm'])) { $this->x += ($this->pagedim[$endpage]['olm'] - $this->pagedim[$startpage]['olm']); } } } if (!$in_table_head) { // we are not inside a thead section if (isset($parent['cellpadding'])) { $this->cMargin = $this->oldcMargin; } $this->lasth = $this->FontSize * $this->cell_height_ratio; if (isset($this->theadMargins['top'])) { // restore top margin $this->tMargin = $this->theadMargins['top']; $this->pagedim[$this->page]['tm'] = $this->tMargin; } // reset table header $this->thead = ''; $this->theadMargins = array(); } break; } case 'a': { $this->HREF = ''; break; } case 'sup': { $this->SetXY($this->GetX(), $this->GetY() + ((0.7 * $parent['fontsize']) / $this->k)); break; } case 'sub': { $this->SetXY($this->GetX(), $this->GetY() - ((0.3 * $parent['fontsize'])/$this->k)); break; } case 'div': { $this->addHTMLVertSpace(1, $cell, '', $firstorlast, $tag['value'], true); break; } case 'blockquote': { if ($this->rtl) { $this->rMargin -= $this->listindent; } else { $this->lMargin -= $this->listindent; } $this->addHTMLVertSpace(2, $cell, '', $firstorlast, $tag['value'], true); break; } case 'p': { $this->addHTMLVertSpace(2, $cell, '', $firstorlast, $tag['value'], true); break; } case 'pre': { $this->addHTMLVertSpace(1, $cell, '', $firstorlast, $tag['value'], true); $this->premode = false; break; } case 'dl': { --$this->listnum; if ($this->listnum <= 0) { $this->listnum = 0; $this->addHTMLVertSpace(2, $cell, '', $firstorlast, $tag['value'], true); } break; } case 'dt': { $this->lispacer = ''; $this->addHTMLVertSpace(0, $cell, '', $firstorlast, $tag['value'], true); break; } case 'dd': { $this->lispacer = ''; if ($this->rtl) { $this->rMargin -= $this->listindent; } else { $this->lMargin -= $this->listindent; } $this->addHTMLVertSpace(0, $cell, '', $firstorlast, $tag['value'], true); break; } case 'ul': case 'ol': { --$this->listnum; $this->lispacer = ''; if ($this->rtl) { $this->rMargin -= $this->listindent; } else { $this->lMargin -= $this->listindent; } if ($this->listnum <= 0) { $this->listnum = 0; $this->addHTMLVertSpace(2, $cell, '', $firstorlast, $tag['value'], true); } $this->lasth = $this->FontSize * $this->cell_height_ratio; break; } case 'li': { $this->lispacer = ''; $this->addHTMLVertSpace(0, $cell, '', $firstorlast, $tag['value'], true); break; } case 'h1': case 'h2': case 'h3': case 'h4': case 'h5': case 'h6': { $this->addHTMLVertSpace(1, $cell, ($parent['fontsize'] * 1.5) / $this->k, $firstorlast, $tag['value'], true); break; } // Form fields (since 4.8.000 - 2009-09-07) case 'form': { $this->form_action = ''; $this->form_enctype = 'application/x-www-form-urlencoded'; break; } default : { break; } } $this->tmprtl = false; } /** * Add vertical spaces if needed. * @param int $n number of spaces to add * @param boolean $cell if true add the default cMargin space to each new line (default false). * @param string $h The height of the break. By default, the value equals the height of the last printed cell. * @param boolean $firstorlast if true do not print additional empty lines. * @param string $tag HTML tag to which this space will be applied * @param boolean $closing true if this space will be applied to a closing tag, false otherwise * @access protected */ protected function addHTMLVertSpace($n, $cell=false, $h='', $firstorlast=false, $tag='', $closing=false) { if ($firstorlast) { $this->Ln(0, $cell); $this->htmlvspace = 0; return; } if (isset($this->tagvspaces[$tag][intval($closing)]['n'])) { $n = $this->tagvspaces[$tag][intval($closing)]['n']; } if (isset($this->tagvspaces[$tag][intval($closing)]['h'])) { $h = $this->tagvspaces[$tag][intval($closing)]['h']; } if (is_string($h)) { $vsize = $n * $this->lasth; } else { $vsize = $n * $h; } if ($vsize > $this->htmlvspace) { $this->Ln(($vsize - $this->htmlvspace), $cell); $this->htmlvspace = $vsize; } } /** * Set the default bullet to be used as LI bullet symbol * @param string $symbol character or string to be used (legal values are: '' = automatic, '!' = auto bullet, '#' = auto numbering, 'disc', 'disc', 'circle', 'square', '1', 'decimal', 'decimal-leading-zero', 'i', 'lower-roman', 'I', 'upper-roman', 'a', 'lower-alpha', 'lower-latin', 'A', 'upper-alpha', 'upper-latin', 'lower-greek') * @access public * @since 4.0.028 (2008-09-26) */ public function setLIsymbol($symbol='!') { $symbol = strtolower($symbol); switch ($symbol) { case '!' : case '#' : case 'disc' : case 'disc' : case 'circle' : case 'square' : case '1': case 'decimal': case 'decimal-leading-zero': case 'i': case 'lower-roman': case 'I': case 'upper-roman': case 'a': case 'lower-alpha': case 'lower-latin': case 'A': case 'upper-alpha': case 'upper-latin': case 'lower-greek': { $this->lisymbol = $symbol; break; } default : { $this->lisymbol = ''; } } } /** * Set the booklet mode for double-sided pages. * @param boolean $booklet true set the booklet mode on, fals eotherwise. * @param float $inner Inner page margin. * @param float $outer Outer page margin. * @access public * @since 4.2.000 (2008-10-29) */ public function SetBooklet($booklet=true, $inner=-1, $outer=-1) { $this->booklet = $booklet; if ($inner >= 0) { $this->lMargin = $inner; } if ($outer >= 0) { $this->rMargin = $outer; } } /** * Swap the left and right margins. * @param boolean $reverse if true swap left and right margins. * @access protected * @since 4.2.000 (2008-10-29) */ protected function swapMargins($reverse=true) { if ($reverse) { // swap left and right margins $mtemp = $this->original_lMargin; $this->original_lMargin = $this->original_rMargin; $this->original_rMargin = $mtemp; $deltam = $this->original_lMargin - $this->original_rMargin; $this->lMargin += $deltam; $this->rMargin -= $deltam; } } /** * Set the vertical spaces for HTML tags. * The array must have the following structure (example): * $tagvs = array('h1' => array(0 => array('h' => '', 'n' => 2), 1 => array('h' => 1.3, 'n' => 1))); * The first array level contains the tag names, * the second level contains 0 for opening tags or 1 for closing tags, * the third level contains the vertical space unit (h) and the number spaces to add (n). * If the h parameter is not specified, default values are used. * @param array $tagvs array of tags and relative vertical spaces. * @access public * @since 4.2.001 (2008-10-30) */ public function setHtmlVSpace($tagvs) { $this->tagvspaces = $tagvs; } /** * Set custom width for list indentation. * @param float $width width of the indentation. Use negative value to disable it. * @access public * @since 4.2.007 (2008-11-12) */ public function setListIndentWidth($width) { return $this->customlistindent = floatval($width); } /** * Set the top/bottom cell sides to be open or closed when the cell cross the page. * @param boolean $isopen if true keeps the top/bottom border open for the cell sides that cross the page. * @access public * @since 4.2.010 (2008-11-14) */ public function setOpenCell($isopen) { $this->opencell = $isopen; } /** * Set the color and font style for HTML links. * @param array $color RGB array of colors * @param string $fontstyle additional font styles to add * @access public * @since 4.4.003 (2008-12-09) */ public function setHtmlLinksStyle($color=array(0,0,255), $fontstyle='U') { $this->htmlLinkColorArray = $color; $this->htmlLinkFontStyle = $fontstyle; } /** * convert html string containing value and unit of measure to user's units or points. * @param string $htmlval string containing values and unit * @param string $refsize reference value in points * @param string $defaultunit default unit (can be one of the following: %, em, ex, px, in, mm, pc, pt). * @param boolean $point if true returns points, otherwise returns value in user's units * @return float value in user's unit or point if $points=true * @access public * @since 4.4.004 (2008-12-10) */ public function getHTMLUnitToUnits($htmlval, $refsize=1, $defaultunit='px', $points=false) { $supportedunits = array('%', 'em', 'ex', 'px', 'in', 'cm', 'mm', 'pc', 'pt'); $retval = 0; $value = 0; $unit = 'px'; $k = $this->k; if ($points) { $k = 1; } if (in_array($defaultunit, $supportedunits)) { $unit = $defaultunit; } if (is_numeric($htmlval)) { $value = floatval($htmlval); } elseif (preg_match('/([0-9\.]+)/', $htmlval, $mnum)) { $value = floatval($mnum[1]); if (preg_match('/([a-z%]+)/', $htmlval, $munit)) { if (in_array($munit[1], $supportedunits)) { $unit = $munit[1]; } } } switch ($unit) { // percentage case '%': { $retval = (($value * $refsize) / 100); break; } // relative-size case 'em': { $retval = ($value * $refsize); break; } case 'ex': { $retval = $value * ($refsize / 2); break; } // absolute-size case 'in': { $retval = ($value * $this->dpi) / $k; break; } case 'cm': { $retval = ($value / 2.54 * $this->dpi) / $k; break; } case 'mm': { $retval = ($value / 25.4 * $this->dpi) / $k; break; } case 'pc': { // one pica is 12 points $retval = ($value * 12) / $k; break; } case 'pt': { $retval = $value / $k; break; } case 'px': { $retval = $this->pixelsToUnits($value); break; } } return $retval; } /** * Returns the Roman representation of an integer number * @param int number to convert * @return string roman representation of the specified number * @access public * @since 4.4.004 (2008-12-10) */ public function intToRoman($number) { $roman = ''; while ($number >= 1000) { $roman .= 'M'; $number -= 1000; } while ($number >= 900) { $roman .= 'CM'; $number -= 900; } while ($number >= 500) { $roman .= 'D'; $number -= 500; } while ($number >= 400) { $roman .= 'CD'; $number -= 400; } while ($number >= 100) { $roman .= 'C'; $number -= 100; } while ($number >= 90) { $roman .= 'XC'; $number -= 90; } while ($number >= 50) { $roman .= 'L'; $number -= 50; } while ($number >= 40) { $roman .= 'XL'; $number -= 40; } while ($number >= 10) { $roman .= 'X'; $number -= 10; } while ($number >= 9) { $roman .= 'IX'; $number -= 9; } while ($number >= 5) { $roman .= 'V'; $number -= 5; } while ($number >= 4) { $roman .= 'IV'; $number -= 4; } while ($number >= 1) { $roman .= 'I'; --$number; } return $roman; } /** * Output an HTML list bullet or ordered item symbol * @param int $listdepth list nesting level * @param string $listtype type of list * @param float $size current font size * @access protected * @since 4.4.004 (2008-12-10) */ protected function putHtmlListBullet($listdepth, $listtype='', $size=10) { $size /= $this->k; $fill = ''; $color = $this->fgcolor; $width = 0; $textitem = ''; $tmpx = $this->x; $lspace = $this->GetStringWidth(' '); if ($listtype == '!') { // set default list type for unordered list $deftypes = array('disc', 'circle', 'square'); $listtype = $deftypes[($listdepth - 1) % 3]; } elseif ($listtype == '#') { // set default list type for ordered list $listtype = 'decimal'; } switch ($listtype) { // unordered types case 'none': { break; } case 'disc': { $fill = 'F'; } case 'circle': { $fill .= 'D'; $r = $size / 6; $lspace += (2 * $r); if ($this->rtl) { $this->x = $this->w - $this->x - $lspace; } else { $this->x -= $lspace; } $this->Circle(($this->x + $r), ($this->y + ($this->lasth / 2)), $r, 0, 360, $fill, array('color'=>$color), $color, 8); break; } case 'square': { $l = $size / 3; $lspace += $l; if ($this->rtl) { $this->x = $this->w - $this->x - $lspace; } else { $this->x -= $lspace; } $this->Rect($this->x, ($this->y + (($this->lasth - $l)/ 2)), $l, $l, 'F', array(), $color); break; } // ordered types // $this->listcount[$this->listnum]; // $textitem case '1': case 'decimal': { $textitem = $this->listcount[$this->listnum]; break; } case 'decimal-leading-zero': { $textitem = sprintf("%02d", $this->listcount[$this->listnum]); break; } case 'i': case 'lower-roman': { $textitem = strtolower($this->intToRoman($this->listcount[$this->listnum])); break; } case 'I': case 'upper-roman': { $textitem = $this->intToRoman($this->listcount[$this->listnum]); break; } case 'a': case 'lower-alpha': case 'lower-latin': { $textitem = chr(97 + $this->listcount[$this->listnum] - 1); break; } case 'A': case 'upper-alpha': case 'upper-latin': { $textitem = chr(65 + $this->listcount[$this->listnum] - 1); break; } case 'lower-greek': { $textitem = $this->unichr(945 + $this->listcount[$this->listnum] - 1); break; } /* // Types to be implemented (special handling) case 'hebrew': { break; } case 'armenian': { break; } case 'georgian': { break; } case 'cjk-ideographic': { break; } case 'hiragana': { break; } case 'katakana': { break; } case 'hiragana-iroha': { break; } case 'katakana-iroha': { break; } */ default: { $textitem = $this->listcount[$this->listnum]; } } if (!$this->empty_string($textitem)) { // print ordered item if ($this->rtl) { $textitem = '.'.$textitem; } else { $textitem = $textitem.'.'; } $lspace += $this->GetStringWidth($textitem); if ($this->rtl) { $this->x += $lspace; } else { $this->x -= $lspace; } $this->Write($this->lasth, $textitem, '', false, '', false, 0, false); } $this->x = $tmpx; $this->lispacer = ''; } /** * Returns current graphic variables as array. * @return array graphic variables * @access protected * @since 4.2.010 (2008-11-14) */ protected function getGraphicVars() { $grapvars = array( 'FontFamily' => $this->FontFamily, 'FontStyle' => $this->FontStyle, 'FontSizePt' => $this->FontSizePt, 'rMargin' => $this->rMargin, 'lMargin' => $this->lMargin, 'cMargin' => $this->cMargin, 'LineWidth' => $this->LineWidth, 'linestyleWidth' => $this->linestyleWidth, 'linestyleCap' => $this->linestyleCap, 'linestyleJoin' => $this->linestyleJoin, 'linestyleDash' => $this->linestyleDash, 'DrawColor' => $this->DrawColor, 'FillColor' => $this->FillColor, 'TextColor' => $this->TextColor, 'ColorFlag' => $this->ColorFlag, 'bgcolor' => $this->bgcolor, 'fgcolor' => $this->fgcolor, 'htmlvspace' => $this->htmlvspace, 'lasth' => $this->lasth ); return $grapvars; } /** * Set graphic variables. * @param $gvars array graphic variables * @access protected * @since 4.2.010 (2008-11-14) */ protected function setGraphicVars($gvars) { $this->FontFamily = $gvars['FontFamily']; $this->FontStyle = $gvars['FontStyle']; $this->FontSizePt = $gvars['FontSizePt']; $this->rMargin = $gvars['rMargin']; $this->lMargin = $gvars['lMargin']; $this->cMargin = $gvars['cMargin']; $this->LineWidth = $gvars['LineWidth']; $this->linestyleWidth = $gvars['linestyleWidth']; $this->linestyleCap = $gvars['linestyleCap']; $this->linestyleJoin = $gvars['linestyleJoin']; $this->linestyleDash = $gvars['linestyleDash']; $this->DrawColor = $gvars['DrawColor']; $this->FillColor = $gvars['FillColor']; $this->TextColor = $gvars['TextColor']; $this->ColorFlag = $gvars['ColorFlag']; $this->bgcolor = $gvars['bgcolor']; $this->fgcolor = $gvars['fgcolor']; $this->htmlvspace = $gvars['htmlvspace']; //$this->lasth = $gvars['lasth']; $this->_out(''.$this->linestyleWidth.' '.$this->linestyleCap.' '.$this->linestyleJoin.' '.$this->linestyleDash.' '.$this->DrawColor.' '.$this->FillColor.''); if (!$this->empty_string($this->FontFamily)) { $this->SetFont($this->FontFamily, $this->FontStyle, $this->FontSizePt); } } /** * Returns a temporary filename for caching object on filesystem. * @param string $prefix prefix to add to filename * return string filename. * @access protected * @since 4.5.000 (2008-12-31) */ protected function getObjFilename($name) { return tempnam(K_PATH_CACHE, $name.'_'); } /** * Writes data to a temporary file on filesystem. * @param string $file file name * @param mixed $data data to write on file * @param boolean $append if true append data, false replace. * @access protected * @since 4.5.000 (2008-12-31) */ protected function writeDiskCache($filename, $data, $append=false) { if ($append) { $fmode = 'ab+'; } else { $fmode = 'wb+'; } $f = @fopen($filename, $fmode); if (!$f) { $this->Error('Unable to write cache file: '.$filename); } else { fwrite($f, $data); fclose($f); } // update file lenght (needed for transactions) if (!isset($this->cache_file_lenght['_'.$filename])) { $this->cache_file_lenght['_'.$filename] = strlen($data); } else { $this->cache_file_lenght['_'.$filename] += strlen($data); } } /** * Read data from a temporary file on filesystem. * @param string $file file name * @return mixed retrieved data * @access protected * @since 4.5.000 (2008-12-31) */ protected function readDiskCache($filename) { return file_get_contents($filename); } /** * Set buffer content (always append data). * @param string $data data * @access protected * @since 4.5.000 (2009-01-02) */ protected function setBuffer($data) { $this->bufferlen += strlen($data); if ($this->diskcache) { if (!isset($this->buffer) OR $this->empty_string($this->buffer)) { $this->buffer = $this->getObjFilename('buffer'); } $this->writeDiskCache($this->buffer, $data, true); } else { $this->buffer .= $data; } } /** * Get buffer content. * @return string buffer content * @access protected * @since 4.5.000 (2009-01-02) */ protected function getBuffer() { if ($this->diskcache) { return $this->readDiskCache($this->buffer); } else { return $this->buffer; } } /** * Set page buffer content. * @param int $page page number * @param string $data page data * @param boolean $append if true append data, false replace. * @access protected * @since 4.5.000 (2008-12-31) */ protected function setPageBuffer($page, $data, $append=false) { if ($this->diskcache) { if (!isset($this->pages[$page])) { $this->pages[$page] = $this->getObjFilename('page'.$page); } $this->writeDiskCache($this->pages[$page], $data, $append); } else { if ($append) { $this->pages[$page] .= $data; } else { $this->pages[$page] = $data; } } if ($append AND isset($this->pagelen[$page])) { $this->pagelen[$page] += strlen($data); } else { $this->pagelen[$page] = strlen($data); } } /** * Get page buffer content. * @param int $page page number * @return string page buffer content or false in case of error * @access protected * @since 4.5.000 (2008-12-31) */ protected function getPageBuffer($page) { if ($this->diskcache) { return $this->readDiskCache($this->pages[$page]); } elseif (isset($this->pages[$page])) { return $this->pages[$page]; } return false; } /** * Set image buffer content. * @param string $image image key * @param array $data image data * @access protected * @since 4.5.000 (2008-12-31) */ protected function setImageBuffer($image, $data) { if ($this->diskcache) { if (!isset($this->images[$image])) { $this->images[$image] = $this->getObjFilename('image'.$image); } $this->writeDiskCache($this->images[$image], serialize($data)); } else { $this->images[$image] = $data; } if (!in_array($image, $this->imagekeys)) { $this->imagekeys[] = $image; } ++$this->numimages; } /** * Set image buffer content. * @param string $image image key * @param string $key image sub-key * @param array $data image data * @access protected * @since 4.5.000 (2008-12-31) */ protected function setImageSubBuffer($image, $key, $data) { if (!isset($this->images[$image])) { $this->setImageBuffer($image, array()); } if ($this->diskcache) { $tmpimg = $this->getImageBuffer($image); $tmpimg[$key] = $data; $this->writeDiskCache($this->images[$image], serialize($tmpimg)); } else { $this->images[$image][$key] = $data; } } /** * Get image buffer content. * @param string $image image key * @return string image buffer content or false in case of error * @access protected * @since 4.5.000 (2008-12-31) */ protected function getImageBuffer($image) { if ($this->diskcache AND isset($this->images[$image])) { return unserialize($this->readDiskCache($this->images[$image])); } elseif (isset($this->images[$image])) { return $this->images[$image]; } return false; } /** * Set font buffer content. * @param string $font font key * @param array $data font data * @access protected * @since 4.5.000 (2009-01-02) */ protected function setFontBuffer($font, $data) { if ($this->diskcache) { if (!isset($this->fonts[$font])) { $this->fonts[$font] = $this->getObjFilename('font'); } $this->writeDiskCache($this->fonts[$font], serialize($data)); } else { $this->fonts[$font] = $data; } if (!in_array($font, $this->fontkeys)) { $this->fontkeys[] = $font; } } /** * Set font buffer content. * @param string $font font key * @param string $key font sub-key * @param array $data font data * @access protected * @since 4.5.000 (2009-01-02) */ protected function setFontSubBuffer($font, $key, $data) { if (!isset($this->fonts[$font])) { $this->setFontBuffer($font, array()); } if ($this->diskcache) { $tmpfont = $this->getFontBuffer($font); $tmpfont[$key] = $data; $this->writeDiskCache($this->fonts[$font], serialize($tmpfont)); } else { $this->fonts[$font][$key] = $data; } } /** * Get font buffer content. * @param string $font font key * @return string font buffer content or false in case of error * @access protected * @since 4.5.000 (2009-01-02) */ protected function getFontBuffer($font) { if ($this->diskcache AND isset($this->fonts[$font])) { return unserialize($this->readDiskCache($this->fonts[$font])); } elseif (isset($this->fonts[$font])) { return $this->fonts[$font]; } return false; } /** * Move a page to a previous position. * @param int $frompage number of the source page * @param int $topage number of the destination page (must be less than $frompage) * @return true in case of success, false in case of error. * @access public * @since 4.5.000 (2009-01-02) */ public function movePage($frompage, $topage) { if (($frompage > $this->numpages) OR ($frompage <= $topage)) { return false; } if ($frompage == $this->page) { // close the page before moving it $this->endPage(); } // move all page-related states $tmppage = $this->pages[$frompage]; $tmppagedim = $this->pagedim[$frompage]; $tmppagelen = $this->pagelen[$frompage]; $tmpintmrk = $this->intmrk[$frompage]; if (isset($this->footerpos[$frompage])) { $tmpfooterpos = $this->footerpos[$frompage]; } if (isset($this->footerlen[$frompage])) { $tmpfooterlen = $this->footerlen[$frompage]; } if (isset($this->transfmrk[$frompage])) { $tmptransfmrk = $this->transfmrk[$frompage]; } if (isset($this->PageAnnots[$frompage])) { $tmpannots = $this->PageAnnots[$frompage]; } if (isset($this->newpagegroup[$frompage])) { $tmpnewpagegroup = $this->newpagegroup[$frompage]; } for ($i = $frompage; $i > $topage; --$i) { $j = $i - 1; // shift pages down $this->pages[$i] = $this->pages[$j]; $this->pagedim[$i] = $this->pagedim[$j]; $this->pagelen[$i] = $this->pagelen[$j]; $this->intmrk[$i] = $this->intmrk[$j]; if (isset($this->footerpos[$j])) { $this->footerpos[$i] = $this->footerpos[$j]; } elseif (isset($this->footerpos[$i])) { unset($this->footerpos[$i]); } if (isset($this->footerlen[$j])) { $this->footerlen[$i] = $this->footerlen[$j]; } elseif (isset($this->footerlen[$i])) { unset($this->footerlen[$i]); } if (isset($this->transfmrk[$j])) { $this->transfmrk[$i] = $this->transfmrk[$j]; } elseif (isset($this->transfmrk[$i])) { unset($this->transfmrk[$i]); } if (isset($this->PageAnnots[$j])) { $this->PageAnnots[$i] = $this->PageAnnots[$j]; } elseif (isset($this->PageAnnots[$i])) { unset($this->PageAnnots[$i]); } if (isset($this->newpagegroup[$j])) { $this->newpagegroup[$i] = $this->newpagegroup[$j]; } elseif (isset($this->newpagegroup[$i])) { unset($this->newpagegroup[$i]); } } $this->pages[$topage] = $tmppage; $this->pagedim[$topage] = $tmppagedim; $this->pagelen[$topage] = $tmppagelen; $this->intmrk[$topage] = $tmpintmrk; if (isset($tmpfooterpos)) { $this->footerpos[$topage] = $tmpfooterpos; } elseif (isset($this->footerpos[$topage])) { unset($this->footerpos[$topage]); } if (isset($tmpfooterlen)) { $this->footerlen[$topage] = $tmpfooterlen; } elseif (isset($this->footerlen[$topage])) { unset($this->footerlen[$topage]); } if (isset($tmptransfmrk)) { $this->transfmrk[$topage] = $tmptransfmrk; } elseif (isset($this->transfmrk[$topage])) { unset($this->transfmrk[$topage]); } if (isset($tmpannots)) { $this->PageAnnots[$topage] = $tmpannots; } elseif (isset($this->PageAnnots[$topage])) { unset($this->PageAnnots[$topage]); } if (isset($tmpnewpagegroup)) { $this->newpagegroup[$topage] = $tmpnewpagegroup; } elseif (isset($this->newpagegroup[$topage])) { unset($this->newpagegroup[$topage]); } // adjust outlines $tmpoutlines = $this->outlines; foreach ($tmpoutlines as $key => $outline) { if (($outline['p'] >= $topage) AND ($outline['p'] < $frompage)) { $this->outlines[$key]['p'] = $outline['p'] + 1; } elseif ($outline['p'] == $frompage) { $this->outlines[$key]['p'] = $topage; } } // adjust links $tmplinks = $this->links; foreach ($tmplinks as $key => $link) { if (($link[0] >= $topage) AND ($link[0] < $frompage)) { $this->links[$key][0] = $link[0] + 1; } elseif ($link[0] == $frompage) { $this->links[$key][0] = $topage; } } // adjust javascript $tmpjavascript = $this->javascript; global $jfrompage, $jtopage; $jfrompage = $frompage; $jtopage = $topage; $this->javascript = preg_replace_callback('/this\.addField\(\'([^\']*)\',\'([^\']*)\',([0-9]+)/', create_function('$matches', 'global $jfrompage, $jtopage; $pagenum = intval($matches[3]) + 1; if (($pagenum >= $jtopage) AND ($pagenum < $jfrompage)) { $newpage = ($pagenum + 1); } elseif ($pagenum == $jfrompage) { $newpage = $jtopage; } else { $newpage = $pagenum; } --$newpage; return "this.addField(\'".$matches[1]."\',\'".$matches[2]."\',".$newpage."";'), $tmpjavascript); // return to last page $this->lastPage(true); return true; } /** * Remove the specified page. * @param int $page page to remove * @return true in case of success, false in case of error. * @access public * @since 4.6.004 (2009-04-23) */ public function deletePage($page) { if ($page > $this->numpages) { return false; } // delete current page unset($this->pages[$page]); unset($this->pagedim[$page]); unset($this->pagelen[$page]); unset($this->intmrk[$page]); if (isset($this->footerpos[$page])) { unset($this->footerpos[$page]); } if (isset($this->footerlen[$page])) { unset($this->footerlen[$page]); } if (isset($this->transfmrk[$page])) { unset($this->transfmrk[$page]); } if (isset($this->PageAnnots[$page])) { unset($this->PageAnnots[$page]); } if (isset($this->newpagegroup[$page])) { unset($this->newpagegroup[$page]); } if (isset($this->pageopen[$page])) { unset($this->pageopen[$page]); } // update remaining pages for ($i = $page; $i < $this->numpages; ++$i) { $j = $i + 1; // shift pages $this->pages[$i] = $this->pages[$j]; $this->pagedim[$i] = $this->pagedim[$j]; $this->pagelen[$i] = $this->pagelen[$j]; $this->intmrk[$i] = $this->intmrk[$j]; if (isset($this->footerpos[$j])) { $this->footerpos[$i] = $this->footerpos[$j]; } elseif (isset($this->footerpos[$i])) { unset($this->footerpos[$i]); } if (isset($this->footerlen[$j])) { $this->footerlen[$i] = $this->footerlen[$j]; } elseif (isset($this->footerlen[$i])) { unset($this->footerlen[$i]); } if (isset($this->transfmrk[$j])) { $this->transfmrk[$i] = $this->transfmrk[$j]; } elseif (isset($this->transfmrk[$i])) { unset($this->transfmrk[$i]); } if (isset($this->PageAnnots[$j])) { $this->PageAnnots[$i] = $this->PageAnnots[$j]; } elseif (isset($this->PageAnnots[$i])) { unset($this->PageAnnots[$i]); } if (isset($this->newpagegroup[$j])) { $this->newpagegroup[$i] = $this->newpagegroup[$j]; } elseif (isset($this->newpagegroup[$i])) { unset($this->newpagegroup[$i]); } if (isset($this->pageopen[$j])) { $this->pageopen[$i] = $this->pageopen[$j]; } elseif (isset($this->pageopen[$i])) { unset($this->pageopen[$i]); } } // remove last page unset($this->pages[$this->numpages]); unset($this->pagedim[$this->numpages]); unset($this->pagelen[$this->numpages]); unset($this->intmrk[$this->numpages]); if (isset($this->footerpos[$this->numpages])) { unset($this->footerpos[$this->numpages]); } if (isset($this->footerlen[$this->numpages])) { unset($this->footerlen[$this->numpages]); } if (isset($this->transfmrk[$this->numpages])) { unset($this->transfmrk[$this->numpages]); } if (isset($this->PageAnnots[$this->numpages])) { unset($this->PageAnnots[$this->numpages]); } if (isset($this->newpagegroup[$this->numpages])) { unset($this->newpagegroup[$this->numpages]); } if (isset($this->pageopen[$this->numpages])) { unset($this->pageopen[$this->numpages]); } --$this->numpages; $this->page = $this->numpages; // adjust outlines $tmpoutlines = $this->outlines; foreach ($tmpoutlines as $key => $outline) { if ($outline['p'] > $page) { $this->outlines[$key]['p'] = $outline['p'] - 1; } elseif ($outline['p'] == $page) { unset($this->outlines[$key]); } } // adjust links $tmplinks = $this->links; foreach ($tmplinks as $key => $link) { if ($link[0] > $page) { $this->links[$key][0] = $link[0] - 1; } elseif ($link[0] == $page) { unset($this->links[$key]); } } // adjust javascript $tmpjavascript = $this->javascript; global $jpage; $jpage = $page; $this->javascript = preg_replace_callback('/this\.addField\(\'([^\']*)\',\'([^\']*)\',([0-9]+)/', create_function('$matches', 'global $jpage; $pagenum = intval($matches[3]) + 1; if ($pagenum >= $jpage) { $newpage = ($pagenum - 1); } elseif ($pagenum == $jpage) { $newpage = 1; } else { $newpage = $pagenum; } --$newpage; return "this.addField(\'".$matches[1]."\',\'".$matches[2]."\',".$newpage."";'), $tmpjavascript); // return to last page $this->lastPage(true); return true; } /** * Output a Table of Content Index (TOC). * You can override this method to achieve different styles. * @param int $page page number where this TOC should be inserted (leave empty for current page). * @param string $numbersfont set the font for page numbers (please use monospaced font for better alignment). * @param string $filler string used to fill the space between text and page number. * @access public * @author Nicola Asuni * @since 4.5.000 (2009-01-02) */ public function addTOC($page='', $numbersfont='', $filler='.') { $fontsize = $this->FontSizePt; $fontfamily = $this->FontFamily; $fontstyle = $this->FontStyle; $w = $this->w - $this->lMargin - $this->rMargin; $spacer = $this->GetStringWidth(' ') * 4; $page_first = $this->getPage(); $lmargin = $this->lMargin; $rmargin = $this->rMargin; $x_start = $this->GetX(); if ($this->empty_string($numbersfont)) { $numbersfont = $this->default_monospaced_font; } if ($this->empty_string($filler)) { $filler = ' '; } if ($this->empty_string($page)) { $gap = ' '; } else { $gap = ''; } foreach ($this->outlines as $key => $outline) { if ($this->rtl) { $aligntext = 'R'; $alignnum = 'L'; } else { $aligntext = 'L'; $alignnum = 'R'; } if ($outline['l'] == 0) { $this->SetFont($fontfamily, $fontstyle.'B', $fontsize); } else { $this->SetFont($fontfamily, $fontstyle, $fontsize - $outline['l']); } $indent = ($spacer * $outline['l']); if ($this->rtl) { $this->rMargin += $indent; $this->x -= $indent; } else { $this->lMargin += $indent; $this->x += $indent; } $link = $this->AddLink(); $this->SetLink($link, 0, $outline['p']); // write the text $this->Write(0, $outline['t'], $link, 0, $aligntext, false, 0, false, false, 0); $this->SetFont($numbersfont, $fontstyle, $fontsize); if ($this->empty_string($page)) { $pagenum = $outline['p']; } else { // placemark to be replaced with the correct number $pagenum = '{#'.($outline['p']).'}'; if (($this->CurrentFont['type'] == 'TrueTypeUnicode') OR ($this->CurrentFont['type'] == 'cidfont0')) { $pagenum = '{'.$pagenum.'}'; } } $numwidth = $this->GetStringWidth($pagenum); if ($this->rtl) { $tw = $this->x - $this->lMargin; } else { $tw = $this->w - $this->rMargin - $this->x; } $fw = $tw - $numwidth - $this->GetStringWidth(' '); $numfills = floor($fw / $this->GetStringWidth($filler)); if ($numfills > 0) { $rowfill = str_repeat($filler, $numfills); } else { $rowfill = ''; } if ($this->rtl) { $pagenum = $pagenum.$gap.$rowfill.' '; } else { $pagenum = ' '.$rowfill.$gap.$pagenum; } // write the number //$this->SetX($x_start); $this->Cell($tw, 0, $pagenum, 0, 1, $alignnum, 0, $link, 0); $this->SetX($x_start); $this->lMargin = $lmargin; $this->rMargin = $rmargin; } $page_last = $this->getPage(); $numpages = $page_last - $page_first + 1; if (!$this->empty_string($page)) { for ($p = $page_first; $p <= $page_last; ++$p) { // get page data $temppage = $this->getPageBuffer($p); for ($n = 1; $n <= $this->numpages; ++$n) { // update page numbers $k = '{#'.$n.'}'; $ku = '{'.$k.'}'; $alias_a = $this->_escape($k); $alias_au = $this->_escape('{'.$k.'}'); if ($this->isunicode) { $alias_b = $this->_escape($this->UTF8ToLatin1($k)); $alias_bu = $this->_escape($this->UTF8ToLatin1($ku)); $alias_c = $this->_escape($this->utf8StrRev($k, false, $this->tmprtl)); $alias_cu = $this->_escape($this->utf8StrRev($ku, false, $this->tmprtl)); } if ($n >= $page) { $np = $n + $numpages; } else { $np = $n; } $ns = $this->formatTOCPageNumber($np); $nu = $ns; $sdiff = strlen($k) - strlen($ns) - 1; $sdiffu = strlen($ku) - strlen($ns) - 1; $sfill = str_repeat($filler, $sdiff); $sfillu = str_repeat($filler, $sdiffu); if ($this->rtl) { $ns = $ns.' '.$sfill; $nu = $nu.' '.$sfillu; } else { $ns = $sfill.' '.$ns; $nu = $sfillu.' '.$nu; } $nu = $this->UTF8ToUTF16BE($nu, false); $temppage = str_replace($alias_au, $nu, $temppage); if ($this->isunicode) { $temppage = str_replace($alias_bu, $nu, $temppage); $temppage = str_replace($alias_cu, $nu, $temppage); $temppage = str_replace($alias_b, $ns, $temppage); $temppage = str_replace($alias_c, $ns, $temppage); } $temppage = str_replace($alias_a, $ns, $temppage); } // save changes $this->setPageBuffer($p, $temppage); } // move pages for ($i = 0; $i < $numpages; ++$i) { $this->movePage($page_last, $page); } } $this->SetFont($fontfamily, $fontstyle, $fontsize); } /** * Stores a copy of the current TCPDF object used for undo operation. * @access public * @since 4.5.029 (2009-03-19) */ public function startTransaction() { if (isset($this->objcopy)) { // remove previous copy $this->commitTransaction(); } // record current page number $this->start_transaction_page = $this->page; // clone current object $this->objcopy = $this->objclone($this); } /** * Delete the copy of the current TCPDF object used for undo operation. * @access public * @since 4.5.029 (2009-03-19) */ public function commitTransaction() { if (isset($this->objcopy)) { $this->objcopy->_destroy(true, true); unset($this->objcopy); } } /** * This method allows to undo the latest transaction by returning the latest saved TCPDF object with startTransaction(). * @param boolean $self if true restores current class object to previous state without the need of reassignment via the returned value. * @return TCPDF object. * @access public * @since 4.5.029 (2009-03-19) */ public function rollbackTransaction($self=false) { if (isset($this->objcopy)) { if (isset($this->objcopy->diskcache) AND $this->objcopy->diskcache) { // truncate files to previous values foreach ($this->objcopy->cache_file_lenght as $file => $lenght) { $file = substr($file, 1); $handle = fopen($file, 'r+'); ftruncate($handle, $lenght); } } $this->_destroy(true, true); if ($self) { $objvars = get_object_vars($this->objcopy); foreach ($objvars as $key => $value) { $this->$key = $value; } } return $this->objcopy; } return $this; } /** * Creates a copy of a class object * @param object $object class object to be cloned * @return cloned object * @access public * @since 4.5.029 (2009-03-19) */ public function objclone($object) { return @clone($object); } /** * Determine whether a string is empty. * @param srting $str string to be checked * @return boolean true if string is empty * @access public * @since 4.5.044 (2009-04-16) */ public function empty_string($str) { return (is_null($str) OR (is_string($str) AND (strlen($str) == 0))); } } // END OF TCPDF CLASS } //============================================================+ // END OF FILE //============================================================+ ?>
]*)>[\n\r\t]+/', '<\\1\\2>', $html); $html = preg_replace('@(\r\n|\r)@', "\n", $html); $repTable = array("\t" => ' ', "\0" => ' ', "\x0B" => ' ', "\\" => "\\\\"); $html = strtr($html, $repTable); $offset = 0; while (($offset < strlen($html)) AND ($pos = strpos($html, '
tag $html_b = preg_replace("']*)>(.*?)\n(.*?)