/** * tracer une image * * @param string nom du fichier source * @return null */ function Image($src) { // est-ce que c'est une image ? $infos = @GetImageSize($src); if (count($infos) < 2) { HTML2PDF::makeError(6, __FILE__, __LINE__, $src); return false; } // récupération des dimensions dans l'unité du PDF $wi = $infos[0] / $this->pdf->k; $hi = $infos[1] / $this->pdf->k; // détermination des dimensions d'affichage en fonction du style if ($this->style->value['width'] && $this->style->value['height']) { $w = $this->style->value['width']; $h = $this->style->value['height']; } else { if ($this->style->value['width']) { $w = $this->style->value['width']; $h = $hi * $w / $wi; } else { if ($this->style->value['height']) { $h = $this->style->value['height']; $w = $wi * $h / $hi; } else { $w = $wi; $h = $hi; } } } // position d'affichage $x = $this->pdf->getX(); $y = $this->pdf->getY(); // détermination de la position réelle d'affichage en fonction du text-align du parent $old = isset($this->style->table[count($this->style->table) - 1]) ? $this->style->table[count($this->style->table) - 1] : $this->value; $parent_w = $old['width'] ? $old['width'] : $this->pdf->w - $this->pdf->lMargin - $this->pdf->rMargin; if ($parent_w > $w) { if ($this->style->value['text-align'] == 'center') { $x = $x + 0.5 * ($parent_w - $w); } else { if ($this->style->value['text-align'] == 'right') { $x = $x + $parent_w - $w; } } } // affichage de l'image, et positionnement à la suite $this->pdf->Image($src, $x, $y, $w, $h, '', $this->inLink); $this->pdf->SetX($x + $w); // position MAX $this->maxX = max($this->maxX, $x + $w); $this->maxY = max($this->maxY, $y + $h); $this->maxH = $h; }
/** * balise : TD * mode : FERMETURE * * @param array paramètres de l'élément de parsing * @return null */ function c_TD($param) { if ($this->forOneLine) return false; $this->maxH = 0; global $HTML2PDF_TABLEAU; // récupération de la marge $marge = array(); $marge['t'] = $this->style->value['padding']['t']+0.5*$HTML2PDF_TABLEAU[$param['num']]['cellspacing']+$this->style->value['border']['t']['width']; $marge['r'] = $this->style->value['padding']['r']+0.5*$HTML2PDF_TABLEAU[$param['num']]['cellspacing']+$this->style->value['border']['r']['width']; $marge['b'] = $this->style->value['padding']['b']+0.5*$HTML2PDF_TABLEAU[$param['num']]['cellspacing']+$this->style->value['border']['b']['width']; $marge['l'] = $this->style->value['padding']['l']+0.5*$HTML2PDF_TABLEAU[$param['num']]['cellspacing']+$this->style->value['border']['l']['width']; $marge['t']+= 0.01; $marge['r']+= 0.01; $marge['b']+= 0.01; $marge['l']+= 0.01; // si on est dans un sub_html if ($this->sub_part) { if ($this->testTDin1page && $this->sub_html->pdf->page>1) HTML2PDF::makeError(7, __FILE__, __LINE__); // dimentions de cette case $w0 = $this->sub_html->maxX + $marge['l'] + $marge['r']; $h0 = $this->sub_html->maxY + $marge['t'] + $marge['b']; // dimensions imposées par le style $w2 = $this->style->value['width'] + $marge['l'] + $marge['r']; $h2 = $this->style->value['height'] + $marge['t'] + $marge['b']; // dimension finale de la case = max des 2 ci-dessus $HTML2PDF_TABLEAU[$param['num']]['cases'][$HTML2PDF_TABLEAU[$param['num']]['tr_curr']-1][$HTML2PDF_TABLEAU[$param['num']]['td_curr']-1]['w'] = max(array($w0, $w2)); $HTML2PDF_TABLEAU[$param['num']]['cases'][$HTML2PDF_TABLEAU[$param['num']]['tr_curr']-1][$HTML2PDF_TABLEAU[$param['num']]['td_curr']-1]['h'] = max(array($h0, $h2)); $HTML2PDF_TABLEAU[$param['num']]['cases'][$HTML2PDF_TABLEAU[$param['num']]['tr_curr']-1][$HTML2PDF_TABLEAU[$param['num']]['td_curr']-1]['real_w'] = $w0; $HTML2PDF_TABLEAU[$param['num']]['cases'][$HTML2PDF_TABLEAU[$param['num']]['tr_curr']-1][$HTML2PDF_TABLEAU[$param['num']]['td_curr']-1]['real_h'] = $h0; // suppresion du sous_html $this->DestroySubHTML(); } else { $this->loadMargin(); //positionnement $HTML2PDF_TABLEAU[$param['num']]['td_x']+= $HTML2PDF_TABLEAU[$param['num']]['cases'][$HTML2PDF_TABLEAU[$param['num']]['tr_curr']-1][$HTML2PDF_TABLEAU[$param['num']]['td_curr']-1]['w']; } // restauration du style $this->style->load(); $this->style->FontSet(); return true; }
/** * parser le code HTML * * @return null */ function parse() { $parents = array(); // chercher les balises HTML du code $tmp = array(); $this->searchCode($tmp); // identifier les balises une à une $pre_in = false; $pre_br = array('name' => 'br', 'close' => false, 'param' => array('style' => array(), 'num' => 0)); $balises_no_closed = array('br', 'hr', 'img', 'col', 'input', 'link', 'option', 'circle', 'ellipse', 'path', 'rect', 'line', 'polygon', 'polyline'); $todos = array(); foreach ($tmp as $part) { // si c'est un code if ($part[0] == 'code') { $res = $this->analiseCode($part[1]); // si le code est bien un code analisable if ($res) { $res['html_pos'] = $part[2]; if (!in_array($res['name'], $balises_no_closed)) { if ($res['close']) { if (count($parents) < 1) { HTML2PDF::makeError(3, __FILE__, __LINE__, $res['name'], $this->getHtmlErrorCode($res['html_pos'])); } else { if ($parents[count($parents) - 1] != $res['name']) { HTML2PDF::makeError(4, __FILE__, __LINE__, $parents, $this->getHtmlErrorCode($res['html_pos'])); } else { unset($parents[count($parents) - 1]); } } } else { if ($res['autoclose']) { $todos[] = $res; $res['params'] = array(); $res['close'] = true; } else { $parents[count($parents)] = $res['name']; } } if (($res['name'] == 'pre' || $res['name'] == 'code') && !$res['autoclose']) { $pre_in = !$res['close']; } } $todos[] = $res; } else { $part[0] = 'txt'; } } // sinon si c'est un texte if ($part[0] == 'txt') { // enregistrer l'action correspondante if (!$pre_in) { // remplacer tous les espaces, tabulations, saufs de ligne multiples par de simples espaces $todos[] = array('name' => 'write', 'close' => false, 'param' => array('txt' => $this->prepareTxt($part[1]))); } else { $part[1] = str_replace("\r", '', $part[1]); $part[1] = explode("\n", $part[1]); foreach ($part[1] as $k => $txt) { $txt = str_replace("\t", ' ', $txt); $txt = str_replace(' ', ' ', $txt); if ($k > 0) { $todos[] = $pre_br; } $todos[] = array('name' => 'write', 'close' => false, 'param' => array('txt' => $this->prepareTxt($txt, false))); } } } } // pour chaque action identifiée, il faut nettoyer le début et la fin des textes // en fonction des balises qui l'entourent. $balises_clean = array('page', 'page_header', 'page_footer', 'form', 'table', 'thead', 'tfoot', 'tr', 'td', 'th', 'br', 'div', 'hr', 'p', 'ul', 'ol', 'li', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'bookmark', 'fieldset', 'legend', 'draw', 'circle', 'ellipse', 'path', 'rect', 'line', 'g', 'polygon', 'polyline'); $nb = count($todos); for ($k = 0; $k < $nb; $k++) { //si c'est un texte if ($todos[$k]['name'] == 'write') { // et qu'une balise spécifique le précède => on nettoye les espaces du début du texte if ($k > 0 && in_array($todos[$k - 1]['name'], $balises_clean)) { $todos[$k]['param']['txt'] = ltrim($todos[$k]['param']['txt']); } // et qu'une balise spécifique le suit => on nettoye les espaces de la fin du texte if ($k < $nb - 1 && in_array($todos[$k + 1]['name'], $balises_clean)) { $todos[$k]['param']['txt'] = rtrim($todos[$k]['param']['txt']); } if (!strlen($todos[$k]['param']['txt'])) { unset($todos[$k]); } } } if (count($parents)) { HTML2PDF::makeError(5, __FILE__, __LINE__, $parents); } // liste des actions sauvée $this->code = array_values($todos); }
/** * parser le code HTML * * @return null */ function parse() { $parents = array(); // récupérer le code à parser $content = $this->html; // chercher les balises HTML du code $tmp = array(); $this->searchCode($content, $tmp); // identifier les balises une à une $todos = array(); foreach ($tmp as $part) { // si c'est un texte if ($part[0] == 'txt') { // remplacer tous les espaces, tabulations, saufs de ligne multiples par de simples espaces $part[1] = preg_replace('/([\\s]+)/is', ' ', $part[1]); // si un texte est présent if (trim($part[1]) !== '') { // enregistrer l'action correspondante $todos[] = array('name' => 'write', 'close' => false, 'param' => array('txt' => $part[1])); } } else { $res = $this->analiseCode($part[1]); if ($res) { if (!in_array($res['name'], array('br', 'hr', 'img', 'input', 'link', 'option'))) { if ($res['close']) { if (count($parents) < 1) { HTML2PDF::makeError(3, __FILE__, __LINE__, $res['name']); } else { if ($parents[count($parents) - 1] != $res['name']) { HTML2PDF::makeError(4, __FILE__, __LINE__, $parents); } else { unset($parents[count($parents) - 1]); } } } else { $parents[count($parents)] = $res['name']; } } $todos[] = $res; } } } // pour chaque action identifiée, il faut nettoyer le début des textes // en fonction des balises qui le précèdent. for ($k = 0; $k < count($todos); $k++) { //si c'est un texte if ($todos[$k]['name'] == 'write') { // et qu'une balise spécifique le précède => on nettoye les espaces du début du texte if ($k > 0 && in_array($todos[$k - 1]['name'], array('table', 'tr', 'td', 'th', 'br', 'div', 'hr'))) { $todos[$k]['param']['txt'] = preg_replace('/^([\\s]*)([^\\s])/isU', '$2', $todos[$k]['param']['txt']); } // et qu'une balise spécifique le suit => on nettoye les espaces de la fin du texte if ($k < count($todos) - 1 && in_array($todos[$k + 1]['name'], array('table', 'tr', 'td', 'th', 'br', 'div', 'hr'))) { $todos[$k]['param']['txt'] = preg_replace('/([^\\s])([\\s]*)$/isU', '$1', $todos[$k]['param']['txt']); } } } if (count($parents)) { HTML2PDF::makeError(5, __FILE__, __LINE__, $parents); } // liste des actions sauvée $this->code = $todos; }
/** * balise : G * mode : OUVERTURE * * @param array paramètres de l'élément de parsing * @return null */ function o_G($param) { if (!$this->isInDraw) { HTML2PDF::makeError(8, __FILE__, __LINE__, 'LINE'); } $this->pdf->doTransform(isset($param['transform']) ? $this->_prepareTransform($param['transform']) : null); $this->style->save(); $styles = $this->style->getSvgStyle('path', $param); $style = $this->pdf->svgSetStyle($styles); }