. // // See LICENSE.TXT file for more information. // ---------------------------------------------------------------------------- // // Description : This is a PHP class for generating PDF documents without // requiring external extensions. // // NOTE: // This class was originally derived in 2002 from the Public // Domain FPDF class by Olivier Plathey (http://www.fpdf.org), // but now is almost entirely rewritten. // // Main features: // * no external libraries are required for the basic functions; // * supports all ISO page formats; // * supports UTF-8 Unicode and Right-To-Left languages; // * supports document encryption; // * includes methods to publish some XHTML code; // * includes graphic (geometric) and transformation methods; // * includes bookmarks; // * includes Javascript and forms support; // * includes a method to print various barcode formats; // * supports TrueTypeUnicode, TrueType, Type1 and CID-0 fonts; // * supports custom page formats, margins and units of measure; // * includes methods for page header and footer management; // * supports automatic page break; // * supports automatic page numbering and page groups; // * supports automatic line break and text justification; // * supports JPEG and PNG images whitout GD library and all images supported by GD: GD, GD2, GD2PART, GIF, JPEG, PNG, BMP, XBM, XPM; // * supports stroke and clipping mode for text; // * supports clipping masks; // * supports Grayscale, RGB and CMYK colors and transparency; // * supports links; // * supports page compression (requires zlib extension); // * supports PDF user's rights. // // ----------------------------------------------------------- // THANKS TO: // // Olivier Plathey (http://www.fpdf.org) for original FPDF. // Efthimios Mavrogeorgiadis (emavro@yahoo.com) for suggestions on RTL language support. // Klemen Vodopivec (http://www.fpdf.de/downloads/addons/37/) for Encryption algorithm. // Warren Sherliker (wsherliker@gmail.com) for better image handling. // dullus for text Justification. // Bob Vincent (pillarsdotnet@users.sourceforge.net) for
* $this->Cell(0,10,'Page '.$pdf->PageNo().'/{nb}',0,0,'C'); ** @param string $alias The alias. Default value: {nb}. * @since 1.4 * @see PageNo(), Footer() */ public function AliasNbPages($alias='{nb}') { //Define an alias for total number of pages $this->AliasNbPages = $this->_escapetext($alias); } /** * This method is automatically called in case of fatal error; it simply outputs the message and halts the execution. An inherited class may override it to customize the error handling but should always halt the script, or the resulting document would probably be invalid. * 2004-06-11 :: Nicola Asuni : changed bold tag with strong * @param string $msg The error message * @since 1.0 */ public function Error($msg) { //Fatal error die('TCPDF error: '.$msg); } /** * This method begins the generation of the PDF document. It is not necessary to call it explicitly because AddPage() does it automatically. * Note: no page is created by this method * @since 1.0 * @see AddPage(), Close() */ public function Open() { //Begin document $this->state = 1; } /** * Terminates the PDF document. It is not necessary to call this method explicitly because Output() does it automatically. If the document contains no page, AddPage() is called to prevent from getting an invalid document. * @since 1.0 * @see Open(), Output() */ public function Close() { //Terminate document if ($this->state == 3) { return; } if ($this->page == 0) { $this->AddPage(); } //Page footer $this->setFooter(); //Close page $this->_endpage(); //Close document $this->_enddoc(); } /** * Move pointer at the specified document page and update page dimensions. * @param int $pnum page number * @param boolean $resetmargins if true reset left, right, top margins and Y position. * @since 2.1.000 (2008-01-07) * @see getPage(), lastpage(), getNumPages() */ public function setPage($pnum, $resetmargins=false) { if (($pnum > 0) AND ($pnum <= count($this->pages))) { $this->page = $pnum; $this->wPt = $this->pagedim[$this->page]['w']; $this->hPt = $this->pagedim[$this->page]['h']; $this->w = $this->wPt / $this->k; $this->h = $this->hPt / $this->k; $this->tMargin = $this->pagedim[$this->page]['tm']; $this->bMargin = $this->pagedim[$this->page]['bm']; $this->AutoPageBreak = $this->pagedim[$this->page]['pb']; $this->CurOrientation = $this->pagedim[$this->page]['or']; $this->SetAutoPageBreak($this->AutoPageBreak, $this->bMargin); if ($resetmargins) { $this->lMargin = $this->pagedim[$this->page]['lm']; $this->rMargin = $this->pagedim[$this->page]['rm']; $this->SetY($this->tMargin); } } else { $this->Error('Wrong page number on setPage() function.'); } } /** * Reset pointer to the last document page. * @since 2.0.000 (2008-01-04) * @see setPage(), getPage(), getNumPages() */ public function lastPage() { $this->setPage($this->getNumPages()); } /** * Get current document page number. * @return int page number * @since 2.1.000 (2008-01-07) * @see setPage(), lastpage(), getNumPages() */ public function getPage() { return $this->page; } /** * Get the total number of insered pages. * @return int number of pages * @since 2.1.000 (2008-01-07) * @see setPage(), getPage(), lastpage() */ public function getNumPages() { return count($this->pages); } /** * Adds a new page to the document. If a page is already present, the Footer() method is called first to output the footer. Then the page is added, the current position set to the top-left corner according to the left and top margins, and Header() is called to display the header. * The font which was set before calling is automatically restored. There is no need to call SetFont() again if you want to continue with the same font. The same is true for colors and line width. * The origin of the coordinate system is at the top-left corner and increasing ordinates go downwards. * @param string $orientation page orientation. Possible values are (case insensitive):
* 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 * --------------------------------------------------------------------- ** @param string $str string to process. * @return array containing codepoints (UTF-8 characters values) * @access protected * @author Nicola Asuni * @since 1.53.0.TC005 (2005-01-05) */ protected function UTF8StringToArray($str) { if (!$this->isunicode) { // split string into array of equivalent codes $strarr = array(); $strlen = strlen($str); for($i=0; $i < $strlen; $i++) { $strarr[] = ord($str{$i}); } return $strarr; } $unicode = array(); // array containing unicode values $bytes = array(); // array containing single character byte sequences $numbytes = 1; // number of octetc needed to represent the UTF-8 character $str .= ""; // force $str to be a string $length = strlen($str); for($i = 0; $i < $length; $i++) { $char = ord($str{$i}); // get one string character at time if (count($bytes) == 0) { // get starting octect if ($char <= 0x7F) { $unicode[] = $char; // use the character "as is" because is ASCII $numbytes = 1; } elseif (($char >> 0x05) == 0x06) { // 2 bytes character (0x06 = 110 BIN) $bytes[] = ($char - 0xC0) << 0x06; $numbytes = 2; } elseif (($char >> 0x04) == 0x0E) { // 3 bytes character (0x0E = 1110 BIN) $bytes[] = ($char - 0xE0) << 0x0C; $numbytes = 3; } elseif (($char >> 0x03) == 0x1E) { // 4 bytes character (0x1E = 11110 BIN) $bytes[] = ($char - 0xF0) << 0x12; $numbytes = 4; } else { // use replacement character for other invalid sequences $unicode[] = 0xFFFD; $bytes = array(); $numbytes = 1; } } elseif (($char >> 0x06) == 0x02) { // bytes 2, 3 and 4 must start with 0x02 = 10 BIN $bytes[] = $char - 0x80; if (count($bytes) == $numbytes) { // compose UTF-8 bytes to a single unicode value $char = $bytes[0]; for($j = 1; $j < $numbytes; $j++) { $char += ($bytes[$j] << (($numbytes - $j - 1) * 0x06)); } if ((($char >= 0xD800) AND ($char <= 0xDFFF)) OR ($char >= 0x10FFFF)) { /* The definition of UTF-8 prohibits encoding character numbers between U+D800 and U+DFFF, which are reserved for use with the UTF-16 encoding form (as surrogate pairs) and do not directly represent characters. */ $unicode[] = 0xFFFD; // use replacement character } else { $unicode[] = $char; // add char to array } // reset data for next char $bytes = array(); $numbytes = 1; } } else { // use replacement character for other invalid sequences $unicode[] = 0xFFFD; $bytes = array(); $numbytes = 1; } } return $unicode; } /** * Converts UTF-8 strings to UTF16-BE.
* 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 ** @param array $unicode array containing UTF-8 unicode values * @param boolean $setbom if true set the Byte Order Mark (BOM = 0xFEFF) * @return string * @access protected * @author Nicola Asuni * @since 2.1.000 (2008-01-08) * @see UTF8ToUTF16BE() */ protected function arrUTF8ToUTF16BE($unicode, $setbom=true) { $outstr = ""; // string to be returned if ($setbom) { $outstr .= "\xFE\xFF"; // Byte Order Mark (BOM) } foreach($unicode as $char) { if ($char == 0xFFFD) { $outstr .= "\xFF\xFD"; // replacement character } elseif ($char < 0x10000) { $outstr .= chr($char >> 0x08); $outstr .= chr($char & 0xFF); } else { $char -= 0x10000; $w1 = 0xD800 | ($char >> 0x10); $w2 = 0xDC00 | ($char & 0x3FF); $outstr .= chr($w1 >> 0x08); $outstr .= chr($w1 & 0xFF); $outstr .= chr($w2 >> 0x08); $outstr .= chr($w2 & 0xFF); } } return $outstr; } // ==================================================== /** * Set header font. * @param array $font font * @since 1.1 */ public function setHeaderFont($font) { $this->header_font = $font; } /** * Get header font. * @return array() * @since 4.0.012 (2008-07-24) */ public function getHeaderFont() { return $this->header_font; } /** * Set footer font. * @param array $font font * @since 1.1 */ public function setFooterFont($font) { $this->footer_font = $font; } /** * Get Footer font. * @return array() * @since 4.0.012 (2008-07-24) */ public function getFooterFont() { return $this->footer_font; } /** * Set language array. * @param array $language * @since 1.1 */ public function setLanguageArray($language) { $this->l = $language; $this->rtl = $this->l['a_meta_dir']=='rtl' ? true : false; } /** * Returns the PDF data. */ public function getPDFData() { if ($this->state < 3) { $this->Close(); } return $this->buffer; } /** * Sets font style. * @param string $tag tag name in lowercase. Supported tags are:
', $html); $html = preg_replace('/[\s]*<\/tr>[\s]*/', '', $html); $html = preg_replace('/[\s]*
"); //replace carriage returns, newlines and tabs $repTable = array("\t" => " ", "\n" => " ", "\r" => " ", "\0" => " ", "\x0B" => " ", "\\" => "\\\\"); $html = strtr($html, $repTable); // remove extra spaces from tables $html = preg_replace('/[\s]*<\/table>[\s]*/', '
[\s]*/', '', $html); $html = preg_replace('/[\s]* [\s]*/', '', $html); $html = preg_replace('/[\s]* ]+>)/Uu'; // explodes the string $a = preg_split($tagpattern, $html, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY); // count elements $maxel = count($a); $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'] = ''; $key++; $level = array(); array_push($level, 0); // root while ($key <= $maxel) { if ($key > 0) { $dom[$key] = array(); } $element = $a[($key-1)]; if (preg_match($tagpattern, $element)) { // html tag $dom[$key]['tag'] = true; $element = substr($element, 1, -1); // get tag name preg_match('/[\/]?([a-zA-Z0-9]*)/', $element, $tag); $dom[$key]['value'] = strtolower($tag[1]); 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']; // 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[($i-1)]; } $key = $i; } } 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 if ($key > 0) { $dom[$key]['fontname'] = $dom[($dom[$key]['parent'])]['fontname']; $dom[$key]['fontstyle'] = $dom[($dom[$key]['parent'])]['fontstyle']; $dom[$key]['fontsize'] = $dom[($dom[$key]['parent'])]['fontsize']; $dom[$key]['bgcolor'] = $dom[($dom[$key]['parent'])]['bgcolor']; $dom[$key]['fgcolor'] = $dom[($dom[$key]['parent'])]['fgcolor']; $dom[$key]['align'] = $dom[($dom[$key]['parent'])]['align']; } // 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)] = $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 = split(",", strtolower($dom[$key]['style']['font-family'])); foreach($fontslist as $font) { $font = trim(strtolower($font)); if (in_array($font, $this->fontlist)){ $dom[$key]['fontname'] = $font; break; } } } } // font size if (isset($dom[$key]['style']['font-size'])) { $dom[$key]['fontsize'] = intval($dom[$key]['style']['font-size']); } // font style $dom[$key]['fontstyle'] = ""; 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"; } // check for width attribute if (isset($dom[$key]['style']['width'])) { $dom[$key]['width'] = intval($dom[$key]['style']['width']); } // check for height attribute if (isset($dom[$key]['style']['height'])) { $dom[$key]['height'] = intval($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 font tag if ($dom[$key]['value'] == "font") { // font family if (isset($dom[$key]['attribute']['face'])) { $fontslist = split(",", strtolower($dom[$key]['attribute']['face'])); foreach($fontslist as $font) { $font = trim(strtolower($font)); if (in_array($font, $this->fontlist)){ $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']); } } } if (($dom[$key]['value'] == "ul") OR ($dom[$key]['value'] == "ol") OR ($dom[$key]['value'] == "dl")) { // force natural alignment for lists 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']{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 } 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 (($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 (!empty($dom[$key]['attribute']['color']))) { $dom[$key]['fgcolor'] = $this->convertHTMLColorToDec($dom[$key]['attribute']['color']); } // set background color attribute if (isset($dom[$key]['attribute']['bgcolor']) AND (!empty($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'] = intval($dom[$key]['attribute']['width']); } // check for height attribute if (isset($dom[$key]['attribute']['height'])) { $dom[$key]['height'] = intval($dom[$key]['attribute']['height']); } // check for text alignment if (isset($dom[$key]['attribute']['align']) AND (!empty($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); // calculate text width //$dom[$key]['width'] = $this->GetStringWidth($dom[$key]['value'], $dom[($dom[$key]['parent'])]['fontname'], $dom[($dom[$key]['parent'])]['fontstyle'], $dom[($dom[$key]['parent'])]['fontsize']); } $key++; } return $dom; } /** * Allows to preserve some HTML formatting (limited support).
* 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, small, span, strong, sub, sup, table, td, th, tr, 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:*/ public function writeHTML($html, $ln=true, $fill=false, $reseth=false, $cell=false, $align='') { // store current values $prevlMargin = $this->lMargin; $prevrMargin = $this->rMargin; $prevcMargin = $this->cMargin; $prevFontFamily = $this->FontFamily; $prevFontStyle = $this->FontStyle; $prevFontSizePt = $this->FontSizePt; $curfontname = $prevFontFamily; $curfontstyle = $prevFontStyle; $curfontsize = $prevFontSizePt; $prevbgcolor = $this->bgcolor; $prevfgcolor = $this->fgcolor; $this->newline = true; $startlinepage = $this->page; if (isset($this->footerpos[$this->page])) { $this->footerpos[$this->page] = strlen($this->pages[$this->page]) - $this->footerlen[$this->page]; $startlinepos = $this->footerpos[$this->page]; } else { $startlinepos = strlen($this->pages[$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; } } $this->listindent = $this->GetStringWidth("0000"); $this->listnum = 0; if ((empty($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'] OR ($key == 0)) { if (isset($dom[$key]['fontname']) OR isset($dom[$key]['fontstyle']) OR isset($dom[$key]['fontsize'])) { $fontname = isset($dom[$key]['fontname']) ? $dom[$key]['fontname'] : ''; $fontstyle = isset($dom[$key]['fontstyle']) ? $dom[$key]['fontstyle'] : ''; $fontsize = isset($dom[$key]['fontsize']) ? $dom[$key]['fontsize'] : ''; if (($fontname != $curfontname) OR ($fontstyle != $curfontstyle) OR ($fontsize != $curfontsize)) { $this->SetFont($fontname, $fontstyle, $fontsize); $this->lasth = $this->FontSize * $this->cell_height_ratio; $curfontname = $fontname; $curfontstyle = $fontstyle; $curfontsize = $fontsize; } } 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 (empty($lalign)) { $lalign = $align; } } // align lines if ($this->newline AND (strlen($dom[$key]['value']) > 0) AND ($dom[$key]['value'] != 'td') AND ($dom[$key]['value'] != 'th')) { // we are at the beginning of a new line if (isset($startlinex)) { if (isset($plalign) AND ((($plalign == "C") OR (($plalign == "R") AND (!$this->rtl)) OR (($plalign == "L") AND ($this->rtl))))) { // the last line must be shifted to be aligned as requested $linew = abs($this->endlinex - $startlinex); $pstart = substr($this->pages[$startlinepage], 0, $startlinepos); if (isset($opentagpos) AND isset($this->footerpos[$startlinepage])) { $this->footerpos[$startlinepage] = strlen($this->pages[$startlinepage]) - $this->footerlen[$startlinepage]; $midpos = min($opentagpos, $this->footerpos[$startlinepage]); } elseif (isset($opentagpos)) { $midpos = $opentagpos; } elseif (isset($this->footerpos[$startlinepage])) { $this->footerpos[$startlinepage] = strlen($this->pages[$startlinepage]) - $this->footerlen[$startlinepage]; $midpos = $this->footerpos[$startlinepage]; } else { $midpos = 0; } if ($midpos > 0) { $pmid = substr($this->pages[$startlinepage], $startlinepos, ($midpos - $startlinepos)); $pend = substr($this->pages[$startlinepage], $midpos); } else { $pmid = substr($this->pages[$startlinepage], $startlinepos); $pend = ""; } // calculate shifting amount $mdiff = abs($w - $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; } // shift the line $trx = sprintf('1 0 0 1 %.3f 0 cm', ($t_x * $this->k)); $this->pages[$startlinepage] = $pstart."\nq\n".$trx."\n".$pmid."\nQ\n".$pend; $endlinepos = strlen($pstart."\nq\n".$trx."\n".$pmid."\nQ\n"); } } $this->checkPageBreak($this->lasth); $this->SetFont($fontname, $fontstyle, $fontsize); if ($wfill) { $this->SetFillColorArray($this->bgcolor); } $startlinex = $this->x; $startlinepage = $this->page; if (isset($endlinepos)) { $startlinepos = $endlinepos; unset($endlinepos); } else { if (isset($this->footerpos[$this->page])) { $this->footerpos[$this->page] = strlen($this->pages[$this->page]) - $this->footerlen[$this->page]; $startlinepos = $this->footerpos[$this->page]; } else { $startlinepos = strlen($this->pages[$this->page]); } } $plalign = $lalign; $this->newline = false; } if (isset($opentagpos)) { unset($opentagpos); } if ($dom[$key]['tag']) { if ($dom[$key]['opening']) { // 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']; } // calculate cell width if (isset($dom[($dom[$key]['parent'])]['width'])) { $table_width = $this->pixelsToUnits($dom[($dom[$key]['parent'])]['width']); } else { $table_width = $w; } if (isset($dom[($dom[$trid]['parent'])]['attribute']['cellpadding'])) { $currentcmargin = $this->pixelsToUnits($dom[($dom[$trid]['parent'])]['attribute']['cellpadding']); $this->cMargin = $currentcmargin; } else { $currentcmargin = 0; } if (isset($dom[($dom[$trid]['parent'])]['attribute']['cellspacing'])) { $cellspacing = $this->pixelsToUnits($dom[($dom[$trid]['parent'])]['attribute']['cellspacing']); } else { $cellspacing = 0; } if ($this->rtl) { $cellspacingx = -$cellspacing; } else { $cellspacingx = $cellspacing; } $colspan = $dom[$key]['attribute']['colspan']; if (isset($dom[$key]['width'])) { $cellw = $this->pixelsToUnits($dom[$key]['width']); } else { $cellw = ($colspan * ($table_width / $dom[$table_el]['cols'])); } $cellw -= $cellspacing; $cell_content = $dom[$key]['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'])) { foreach ($dom[$table_el]['rowspans'] as $k => $trwsp) { if (($trwsp['startx'] == $this->x) AND (($trwsp['starty'] < $this->y) OR ($trwsp['startpage'] < $this->page)) AND ($trwsp['rowspan'] > 0)) { $this->x = $trwsp['endx'] + $cellspacingx; } } } // add rowspan information to table element if ($rowspan > 1) { if (isset($this->footerpos[$this->page])) { $this->footerpos[$this->page] = strlen($this->pages[$this->page]) - $this->footerlen[$this->page]; $trintmrkpos = $this->footerpos[$this->page]; } else { $trintmrkpos = strlen($this->pages[$this->page]); } $trsid = array_push($dom[$table_el]['rowspans'], array('rowspan' => $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']; } // write the cell content $this->MultiCell($cellw, 0, $cell_content, false, $lalign, false, 2, '', '', true, 0, true); $this->cMargin = $currentcmargin; $dom[$trid]['cellpos'][($cellid - 1)]['endx'] = $this->x; // update the end of row position 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; } // account for row-spanned cells if ($rowspan > 1) { $dom[$table_el]['rowspans'][($trsid - 1)]['endx'] = $this->x; } if (isset($dom[$table_el]['rowspans'])) { foreach ($dom[$table_el]['rowspans'] as $k => $trwsp) { if ($trwsp['rowspan'] > 0) { $dom[$table_el]['rowspans'][$k]['endy'] = $dom[$trid]['endy']; $dom[$table_el]['rowspans'][$k]['endpage'] = $dom[$trid]['endpage']; } } } $this->x += ($cellspacingx / 2); } else { // opening tag (or self-closing tag) if (!isset($opentagpos)) { if (isset($this->footerpos[$this->page])) { $this->footerpos[$this->page] = strlen($this->pages[$this->page]) - $this->footerlen[$this->page]; $opentagpos = $this->footerpos[$this->page]; } else { $opentagpos = strlen($this->pages[$this->page]); } } $this->openHTMLTagHandler($dom, $key, $cell); } } else { // closing tag $this->closeHTMLTagHandler($dom, $key, $cell); } } elseif (strlen($dom[$key]['value']) > 0) { // text if ($this->HREF) { // HTML Link $strrest = $this->addHtmlLink($this->HREF, $dom[$key]['value'], $wfill, true); } else { $ctmpmargin = $this->cMargin; $this->cMargin = 0; // write only the first line and get the rest $strrest = $this->Write($this->lasth, $dom[$key]['value'], '', $wfill, "", false, 0, true); $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; } } $dom[$key]['value'] = ltrim($strrest); $key--; } } $key++; } // end for each $key // align the last line if (isset($startlinex)) { if (isset($plalign) AND ((($plalign == "C") OR (($plalign == "R") AND (!$this->rtl)) OR (($plalign == "L") AND ($this->rtl))))) { // the last line must be shifted to be aligned as requested $linew = abs($this->endlinex - $startlinex); $pstart = substr($this->pages[$startlinepage], 0, $startlinepos); if (isset($opentagpos) AND isset($this->footerpos[$startlinepage])) { $this->footerpos[$startlinepage] = strlen($this->pages[$startlinepage]) - $this->footerlen[$startlinepage]; $midpos = min($opentagpos, $this->footerpos[$startlinepage]); } elseif (isset($opentagpos)) { $midpos = $opentagpos; } elseif (isset($this->footerpos[$startlinepage])) { $this->footerpos[$startlinepage] = strlen($this->pages[$startlinepage]) - $this->footerlen[$startlinepage]; $midpos = $this->footerpos[$startlinepage]; } else { $midpos = 0; } if ($midpos > 0) { $pmid = substr($this->pages[$startlinepage], $startlinepos, ($midpos - $startlinepos)); $pend = substr($this->pages[$startlinepage], $midpos); } else { $pmid = substr($this->pages[$startlinepage], $startlinepos); $pend = ""; } // calculate shifting amount $mdiff = abs($w - $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; } // shift the line $trx = sprintf('1 0 0 1 %.3f 0 cm', ($t_x * $this->k)); $this->pages[$startlinepage] = $pstart."\nq\n".$trx."\n".$pmid."\nQ\n".$pend; } } if ($ln AND (!($cell AND ($dom[$key-1]['value'] == "table")))) { $this->Ln($this->lasth); } // restore previous values $this->SetFont($prevFontFamily, $prevFontStyle, $prevFontSizePt); $this->SetFillColorArray($prevbgcolor); $this->SetTextColorArray($prevfgcolor); $this->lMargin = $prevlMargin; $this->rMargin = $prevrMargin; $this->cMargin = $prevcMargin; 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'])]; // 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': { $dom[$key]['rowspans'] = array(); if (isset($tag['attribute']['cellpadding'])) { $this->oldcMargin = $this->cMargin; $this->cMargin = $this->pixelsToUnits($tag['attribute']['cellpadding']); } break; } case 'tr': { // array of columns positions $dom[$key]['cellpos'] = array(); break; } case 'td': case 'th': { break; } case 'hr': { $this->Ln('', $cell); if ((isset($tag['attribute']['width'])) AND ($tag['attribute']['width'] != '')) { $hrWidth = $this->pixelsToUnits($tag['attribute']['width']); } else { $hrWidth = $this->w - $this->lMargin - $this->rMargin; } $x = $this->GetX(); $y = $this->GetY(); $prevlinewidth = $this->GetLineWidth(); $this->Line($x, $y, $x + $hrWidth, $y); $this->SetLineWidth($prevlinewidth); $this->Ln('', $cell); break; } case 'u': { $this->setStyle('u', true); break; } case 'del': { $this->setStyle('d', true); break; } case 'a': { $this->HREF = $tag['attribute']['href']; break; } case 'img': { if (isset($tag['attribute']['src'])) { // replace relative path with real server path if ($tag['attribute']['src'][0] == '/') { $tag['attribute']['src'] = $_SERVER['DOCUMENT_ROOT'].$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'])) { $align = 'N'; } else { switch($tag['attribute']['align']) { case 'top':{ $align = 'T'; break; } case 'middle':{ $align = 'M'; break; } case 'bottom':{ $align = 'B'; break; } default:{ $align = 'N'; break; } } } $fileinfo = pathinfo($tag['attribute']['src']); if (isset($fileinfo['extension']) AND (!empty($fileinfo['extension']))) { $type = strtolower($fileinfo['extension']); } if (($type == "eps") OR ($type == "ai")) { $this->ImageEps($tag['attribute']['src'], $this->GetX(), $this->GetY(), $this->pixelsToUnits($tag['attribute']['width']), $this->pixelsToUnits($tag['attribute']['height']), '', true, $align); } else { $this->Image($tag['attribute']['src'], $this->GetX(), $this->GetY(), $this->pixelsToUnits($tag['attribute']['width']), $this->pixelsToUnits($tag['attribute']['height']), '', '', $align); } } break; } case 'dl': { $this->listnum++; break; } case 'dt': { $this->Ln('', $cell); break; } case 'dd': { if ($this->rtl) { $this->rMargin += $this->listindent; } else { $this->lMargin += $this->listindent; } $this->Ln('', $cell); break; } case 'ul': case 'ol': { $this->listnum++; if ($tag['value'] == "ol") { $this->listordered[$this->listnum] = true; } else { $this->listordered[$this->listnum] = false; } $this->listcount[$this->listnum] = 0; if ($this->rtl) { $this->rMargin += $this->listindent; } else { $this->lMargin += $this->listindent; } break; } case 'li': { $this->Ln('', $cell); if ($tag['value'] == 'li') { if ($this->listordered[$this->listnum]) { if (isset($tag['attribute']['value'])) { $this->listcount[$this->listnum] = intval($tag['attribute']['value']); } $this->listcount[$this->listnum]++; if ($this->rtl) { $this->lispacer = ".".($this->listcount[$this->listnum]); } else { $this->lispacer = ($this->listcount[$this->listnum])."."; } } else { //unordered list symbol $this->lispacer = "-"; } } else { $this->lispacer = ""; } $tmpx = $this->x; $lspace = $this->GetStringWidth($this->lispacer." "); if ($this->rtl) { $this->x += $lspace; } else { $this->x -= $lspace; } $this->Write($this->lasth, $this->lispacer, '', false, '', false, 0, false); $this->x = $tmpx; break; } case 'blockquote': case 'br': { $this->Ln('', $cell); break; } case 'p': { $this->Ln('', $cell); $this->Ln('', $cell); break; } case 'sup': { $this->SetXY($this->GetX(), $this->GetY() - (($parent['fontsize'] - $this->FontSizePt) / $this->k)); break; } case 'sub': { $this->SetXY($this->GetX(), $this->GetY() + (($parent['fontsize'] - (0.5 * $this->FontSizePt)) / $this->k)); break; } case 'small': { $this->SetXY($this->GetX(), $this->GetY() + (($parent['fontsize'] - $this->FontSizePt)/$this->k)); break; } case 'h1': case 'h2': case 'h3': case 'h4': case 'h5': case 'h6': { $this->Ln(($tag['fontsize'] * 1.5) / $this->k, $cell); break; } 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'])]; //Closing tag switch($tag['value']) { case 'td': case 'th': { break; } case 'tr': { $table_el = $dom[($dom[$key]['parent'])]['parent']; $this->setPage($parent['endpage']); $this->y = $parent['endy']; if (isset($dom[$table_el]['attribute']['cellspacing'])) { $cellspacing = $this->pixelsToUnits($dom[$table_el]['attribute']['cellspacing']); $this->y += $cellspacing; } $this->Ln(0, $cell); $this->x = $parent['startx']; // 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; } } break; } 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; } // for each row foreach ($table_el['trids'] as $j => $trkey) { $parent = $dom[$trkey]; $this->setPage($parent['startpage']); $this->y = $parent['starty']; $restspace = $this->getPageHeight() - $this->y - $this->getBreakMargin(); $startpage = $parent['startpage']; $endpage = $parent['endpage']; // for each cell on the row foreach ($parent['cellpos'] as $k => $cellpos) { if (isset($cellpos['rowspanid'])) { $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']; } if ($endpage > $startpage) { // design borders around HTML cells. for ($page=$startpage; $page <= $endpage; $page++) { $this->setPage($page); if ($page == $startpage) { $this->y = $this->getPageHeight() - $restspace - $this->getBreakMargin(); $ch = $restspace; } elseif ($page == $endpage) { $this->y = $this->tMargin; // put cursor at the beginning of text $ch = $endy - $this->tMargin; } else { $this->y = $this->tMargin; // put cursor at the beginning of text $ch = $this->getPageHeight() - $this->tMargin - $this->getBreakMargin(); } 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']; // design a cell around the text $ccode = $this->FillColor."\n".$this->getCellCode($cw, $ch, "", $border, 1, '', $fill); $pstart = substr($this->pages[$this->page], 0, $this->intmrk[$this->page]); $pend = substr($this->pages[$this->page], $this->intmrk[$this->page]); $this->pages[$this->page] = $pstart.$ccode."\n".$pend; $this->intmrk[$this->page] += strlen($ccode."\n"); } } else { $ch = $endy - $parent['starty']; 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']; $this->y = $parent['starty']; // design a cell around the text $ccode = $this->FillColor."\n".$this->getCellCode($cw, $ch, "", $border, 1, '', $fill); $pstart = substr($this->pages[$this->page], 0, $this->intmrk[$this->page]); $pend = substr($this->pages[$this->page], $this->intmrk[$this->page]); $this->pages[$this->page] = $pstart.$ccode."\n".$pend; $this->intmrk[$this->page] += strlen($ccode."\n"); } } if (isset($table_el['attribute']['cellspacing'])) { $cellspacing = $this->pixelsToUnits($table_el['attribute']['cellspacing']); $this->y += $cellspacing; } $this->Ln(0, $cell); $this->x = $parent['startx']; } if (isset($parent['cellpadding'])) { $this->cMargin = $this->oldcMargin; } //set row height $this->lasth = $this->FontSize * $this->cell_height_ratio; break; } case 'u': { $this->setStyle('u', false); break; } case 'del': { $this->setStyle('d', false); break; } case 'a': { $this->HREF = ''; break; } case 'sup': { $this->SetXY($this->GetX(), $this->GetY() + (($this->FontSizePt - $parent['fontsize'])/$this->k)); break; } case 'sub': { $this->SetXY($this->GetX(), $this->GetY() - (($this->FontSizePt - (0.5 * $parent['fontsize']))/$this->k)); break; } case 'small': { $this->SetXY($this->GetX(), $this->GetY() - (($this->FontSizePt - $parent['fontsize'])/$this->k)); break; } case 'p': { $this->Ln('', $cell); $this->Ln('', $cell); break; } case 'dl': { $this->listnum--; if ($this->listnum <= 0) { $this->listnum = 0; $this->Ln('', $cell); $this->Ln('', $cell); } break; } case 'dt': { $this->lispacer = ""; break; } case 'dd': { $this->lispacer = ""; if ($this->rtl) { $this->rMargin -= $this->listindent; } else { $this->lMargin -= $this->listindent; } 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->Ln('', $cell); $this->Ln('', $cell); } $this->lasth = $this->FontSize * $this->cell_height_ratio; break; } case 'li': { $this->lispacer = ""; break; } case 'h1': case 'h2': case 'h3': case 'h4': case 'h5': case 'h6': { $this->Ln(($parent['fontsize'] * 1.5) / $this->k, $cell); break; } default : { break; } } $this->tmprtl = false; } } // END OF TCPDF CLASS } //============================================================+ // END OF FILE //============================================================+ ?>
- L : left align
- C : center
- R : right align
- '' : empty string : left for LTR or right for RTL