. // // 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, CMYK, Spot colors and transparency; // * supports links and annotations; // * 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
* 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) */ 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() */ 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 */ function setHeaderFont($font) { $this->header_font = $font; } /** * Get header font. * @return array() * @since 4.0.012 (2008-07-24) */ function getHeaderFont() { return $this->header_font; } /** * Set footer font. * @param array $font font * @since 1.1 */ function setFooterFont($font) { $this->footer_font = $font; } /** * Get Footer font. * @return array() * @since 4.0.012 (2008-07-24) */ function getFooterFont() { return $this->footer_font; } /** * Set language array. * @param array $language * @since 1.1 */ function setLanguageArray($language) { $this->l = $language; $this->rtl = $this->l['a_meta_dir']=='rtl' ? true : false; } /** * Returns the PDF data. */ 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]* /', '', $html); $html = preg_replace('/<\/td>/', ' ', $html); // pattern for generic tag $tagpattern = '/(<[^>]+>)/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)] = 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)){ $dom[$key]['fontname'] = $font; break; } } } } // font size if (isset($dom[$key]['style']['font-size'])) { $fsize = trim($dom[$key]['style']['font-size']); switch ($fsize) { 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; } default: { $dom[$key]['fontsize'] = intval($fsize); } } } // 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"; } // font color if (isset($dom[$key]['style']['color']) AND (!empty($dom[$key]['style']['color']))) { $dom[$key]['fgcolor'] = $this->convertHTMLColorToDec($dom[$key]['style']['color']); } // background color if (isset($dom[$key]['style']['background-color']) AND (!empty($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 ($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'] = 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 = preg_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).
* 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, 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:*/ 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; $minstartliney = $this->y; $yshift = 0; $startlinepage = $this->page; $newline = true; if (isset($this->footerlen[$this->page])) { $this->footerpos[$this->page] = strlen($this->pages[$this->page]) - $this->footerlen[$this->page]; } else { $this->footerpos[$this->page] = strlen($this->pages[$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; } } $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 ((($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) ) { $this->y += (($curfontsize / $this->k) - $this->pixelsToUnits($dom[$key]['attribute']['height'])); $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)) { $this->y += (($curfontsize - $fontsize) / $this->k); $minstartliney = min($this->y, $minstartliney); } $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')) { $newline = true; // we are at the beginning of a new line if (isset($startlinex)) { $yshift = $minstartliney - $startliney; if ($yshift > 0) { $yshift = 0; } if ((isset($plalign) AND ((($plalign == "C") 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->pages[$startlinepage], 0, $startlinepos); if (isset($opentagpos) AND isset($this->footerlen[$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->footerlen[$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; } 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->pages[$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 ($pac['y'] >= $minstartliney) { $this->PageAnnots[$this->page][$pak]['x'] += $t_x; $this->PageAnnots[$this->page][$pak]['y'] -= $yshift; } } } $this->y -= $yshift; } } } $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)) { $startlinepos = $endlinepos; unset($endlinepos); } else { if (isset($this->footerlen[$this->page])) { $this->footerpos[$this->page] = strlen($this->pages[$this->page]) - $this->footerlen[$this->page]; } else { $this->footerpos[$this->page] = strlen($this->pages[$this->page]); } $startlinepos = $this->footerpos[$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']); } else { $currentcmargin = 0; } $this->cMargin = $currentcmargin; 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; 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'])) { 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->footerlen[$this->page])) { $this->footerpos[$this->page] = strlen($this->pages[$this->page]) - $this->footerlen[$this->page]; } else { $this->footerpos[$this->page] = strlen($this->pages[$this->page]); } $trintmrkpos = $this->footerpos[$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 ($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'])) { 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 ($dom[$table_el]['rowspans'][$k]['endpage'] > $dom[$trid]['endpage']) { $dom[$table_el]['rowspans'][$k]['endy'] = $trwsp['endy']; } else { $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->footerlen[$this->page])) { $this->footerpos[$this->page] = strlen($this->pages[$this->page]) - $this->footerlen[$this->page]; } else { $this->footerpos[$this->page] = strlen($this->pages[$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 (!empty($this->lispacer)) { $this->SetFont($pfontname, $pfontstyle, $pfontsize); $this->lasth = $this->FontSize * $this->cell_height_ratio; $minstartliney = $this->y; $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; $this->lispacer = ""; $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 ($newline) { if ($this->rtl OR $this->tmprtl) { $dom[$key]['value'] = rtrim($dom[$key]['value']); } else { $dom[$key]['value'] = ltrim($dom[$key]['value']); } $newline = false; } if ($this->HREF) { // HTML Link $strrest = $this->addHtmlLink($this->HREF, $dom[$key]['value'], $wfill, true); } else { $ctmpmargin = $this->cMargin; $this->cMargin = 0; // write only until the end of the 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)) { $yshift = $minstartliney - $startliney; if ($yshift > 0) { $yshift = 0; } if ((isset($plalign) AND ((($plalign == "C") 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->pages[$startlinepage], 0, $startlinepos); if (isset($opentagpos) AND isset($this->footerlen[$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->footerlen[$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; } 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->pages[$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 ($pac['y'] >= $minstartliney) { $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->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 */ 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->addHTMLVertSpace(1, $cell); $this->htmlvspace = 0; 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->addHTMLVertSpace(1, $cell); break; } case 'b': { $this->setStyle('b', true); break; } case 'i': { $this->setStyle('i', true); break; } case 'u': { $this->setStyle('u', true); break; } case 'del': { $this->setStyle('d', true); break; } case 'a': { if (array_key_exists('href', $tag['attribute'])) { $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'])) { // 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 (!empty($fileinfo['extension']))) { $type = strtolower($fileinfo['extension']); } $prevy = $this->y; 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); } 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++; break; } case 'dt': { $this->addHTMLVertSpace(1, $cell); break; } case 'dd': { if ($this->rtl) { $this->rMargin += $this->listindent; } else { $this->lMargin += $this->listindent; } $this->addHTMLVertSpace(1, $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 = ""; } break; } case 'blockquote': { if ($this->rtl) { $this->rMargin += $this->listindent; } else { $this->lMargin += $this->listindent; } $this->addHTMLVertSpace(2, $cell); break; } case 'br': { $this->Ln('', $cell); break; } case 'div': { $this->addHTMLVertSpace(2, $cell); break; } case 'p': { $this->addHTMLVertSpace(2, $cell); 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); 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 */ 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']; // 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'] == $dom[($dom[$key]['parent'])]['endpage']) { $dom[($dom[$key]['parent'])]['endy'] = max($dom[$table_el]['rowspans'][$k]['endy'], $dom[($dom[$key]['parent'])]['endy']); } elseif ($dom[$table_el]['rowspans'][$k]['endpage'] > $dom[($dom[$key]['parent'])]['endpage']) { $dom[($dom[$key]['parent'])]['endy'] = $dom[$table_el]['rowspans'][$k]['endy']; $dom[($dom[$key]['parent'])]['endpage'] = $dom[$table_el]['rowspans'][$k]['endpage']; } } } } $this->setPage($dom[($dom[$key]['parent'])]['endpage']); $this->y = $dom[($dom[$key]['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 = $dom[($dom[$key]['parent'])]['startx']; 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]; $restspace = $this->getPageHeight() - $this->y - $this->getBreakMargin(); // 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']; $startpage = $parent['startpage']; $endpage = $parent['endpage']; } $this->setPage($startpage); $this->y = $parent['starty']; 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 'b': { $this->setStyle('b', false); break; } case 'i': { $this->setStyle('i', false); 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() + ((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); break; } case 'blockquote': { if ($this->rtl) { $this->rMargin -= $this->listindent; } else { $this->lMargin -= $this->listindent; } $this->addHTMLVertSpace(2, $cell); break; } case 'p': { $this->addHTMLVertSpace(2, $cell); break; } case 'dl': { $this->listnum--; if ($this->listnum <= 0) { $this->listnum = 0; $this->addHTMLVertSpace(2, $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->addHTMLVertSpace(2, $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->addHTMLVertSpace(1, $cell, ($parent['fontsize'] * 1.5) / $this->k); 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. * @access protected */ function addHTMLVertSpace($n, $cell=false, $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; } } } // END OF TCPDF CLASS } //============================================================+ // END OF FILE //============================================================+
- L : left align
- C : center
- R : right align
- '' : empty string : left for LTR or right for RTL