[ Index ] |
|
Code source de SPIP Agora 1.4 |
1 <?php 2 /***************************************************** 3 * This file is part of Agora, web based content management system. 4 * 5 * Agora is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation; version 2 of the License. 8 * 9 * Agora is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details (file "COPYING"). 13 * 14 * Copyright © Arnaud Martin, Antoine Pitrou et Philippe Rivière. 15 * List of authors detailed in "copyright_fr.html" file. 16 * E-mail : agora@sig.premier-ministre.gouv.fr 17 * Web site : http://www.agora.gouv.fr 18 *****************************************************/ 19 /** 20 * class PDF extends FPDF : FPDF/tutoriel/tuto6.htm 21 * 22 * Février-Août 2003 : Jérôme Fenal (jerome.fenal@logicacmg.com) 23 * Ajout de la prise en compte des tableaux, tag <code>, et diverses autres choses de SPIP 24 */ 25 26 class PDF extends FPDF { 27 var $B; 28 var $I; 29 var $U; 30 var $HREF; 31 var $SRC; 32 var $columnProp = array(); # propriétés de la ligne 33 var $inFirstRow; # flag si première ligne en cours 34 var $TableX; # abscisse du tableau 35 var $HeaderColor; 36 var $RowColors; 37 var $tableProp = array(); 38 var $ProcessingTable = false; # =1 : en cours lecture table 39 var $ProcessingTDTH = false; # =1 : en cours lecture cellule tableau 40 var $ProcessingTH = false; # =1 : en cours lecture cellule tableau heading 41 var $ProcessingCadre = false; # =1 : en cours lecture contenu d'un cadre SPIP (TEXTAREA HTML) 42 var $tableCurrentCol; # numéro de cellule courante 43 var $tableCurrentRow; # Numero de ligne courante pendant la lecture d'un tableau 44 var $tableContent = array(); # Contenu de la table courante pendant son absorption. Non réentrant car SPIP ne permet pas de faire 45 # de table dans une autre table. 46 var $listDepth = 0; # profondeur courante de liste à puce 47 var $listParm = array(); # paramètres des listes à puces en fonction du niveau 48 var $debug = 0; 49 50 function AddCol ($field = -1, $width = -1, $align = 'L') { 51 //Ajoute une colonne au tableau 52 if ($field == -1) 53 $field = count($this->columnProp); 54 55 $this->columnProp[$field] = array('f' => $field, 'w' => $width, 'a' => $align); 56 #$this->Write(5, "Ajout de colonne : ".$field."/".$width."/".$align); $this->Ln(); 57 } 58 59 function PDF ($orientation = 'P', $unit = 'mm', $format = 'A4') { 60 //Appel au constructeur parent 61 $this->FPDF($orientation, $unit, $format); 62 $this->SetCompression(1); 63 //Initialisation 64 $this->B = 0; 65 $this->I = 0; 66 $this->U = 0; 67 $this->HREF = ''; 68 } 69 70 function unhtmlentities ($string) { 71 $trans_tbl = get_html_translation_table(HTML_ENTITIES); 72 $trans_tbl = array_flip($trans_tbl); 73 $ret = strtr($string, $trans_tbl); 74 return preg_replace('/&#(\d+);/me', "chr('\\1')", $ret); 75 } 76 77 function WriteHTML ($html) { 78 //Parseur HTML 79 $html = str_replace("\n", ' ', $html); 80 $html = $this->unhtmlentities($html); 81 $a = preg_split('/<(.*)>/U', $html, i - 1, PREG_SPLIT_DELIM_CAPTURE); 82 83 foreach ($a as $i => $e) { 84 if ($i % 2 == 0) { 85 //Texte 86 # Attention, ce mécanisme ne permet pas de traiter les liens dans les tableaux... 87 # ni les tableaux dans les tableaux, d'ailleurs... 88 if ($this->ProcessingTDTH) { 89 # tableCurrentCol - 1 car tableCurrentCol déjà incrémenté. 90 $this->tableContent[$this->tableCurrentRow][$this->tableCurrentCol - 1]['content'] .= $e; 91 if ($this->ProcessingTH) { 92 $this->tableContent[$this->tableCurrentRow][$this->tableCurrentCol - 1]['TH'] = 1; 93 } 94 else { 95 $this->tableContent[$this->tableCurrentRow][$this->tableCurrentCol - 1]['TH'] = 0; 96 } 97 } 98 else { 99 if ($this->HREF) { 100 $this->PutLink($this->HREF, $e); 101 } 102 else { 103 $this->Write(5, $e); 104 } 105 } 106 } 107 else { 108 //Balise 109 if ($e{0}== '/') { 110 $this->CloseTag(strtoupper(substr($e, 1))); 111 } 112 else { 113 //Extraction des propriétés 114 $a2 = split(' ', $e); 115 $tag = strtoupper(array_shift($a2)); 116 $this->prop = array(); 117 118 foreach ($a2 as $v) 119 if (ereg('^([^=]*)=["\']?([^"\']*)["\']?$', $v, $a3)) 120 $this->prop[strtoupper($a3[1])] = $a3[2]; 121 $this->OpenTag($tag, $this->prop); 122 } 123 } 124 } 125 } 126 127 function OpenTag ($tag, $prop) { 128 //Balise ouvrante 129 if ($tag == 'B' or $tag == 'I' or $tag == 'U') { 130 $this->SetStyle($tag, true); 131 } 132 133 if ($tag == 'A') { 134 $this->HREF = $this->prop['HREF']; 135 } 136 137 if ($tag == 'BR') { 138 $this->Ln(5); 139 } 140 141 if ($tag == 'P') { 142 $this->Ln(5); 143 } 144 145 if ($tag == 'CODE') { 146 $this->Write(5, '<code>'); 147 } 148 149 if ($tag == 'H3') { 150 $this->Ln(15); 151 // $this->$align = "C"; 152 $this->SetStyle($tag = 'B', true, 14); 153 } 154 155 if ($tag == 'UL' or $tag == 'OL') { 156 $this->SetLeftMargin($this->lMargin + 7); 157 $this->listDepth++; 158 $this->listParm[$this->listDepth]['type'] = $tag; 159 $this->listParm[$this->listDepth]['curr'] = 0; # numéro si OL 160 } 161 162 if ($tag == 'LI') { 163 $this->Ln(); 164 $this->listParm[$this->listDepth]['curr']++; 165 $this->SetX($this->GetX() - 7); 166 if ($this->listParm[$this->listDepth]['type'] == 'OL') 167 $this->Cell(7, 5, $this->listParm[$this->listDepth]['curr']. '.', 0, 0, 'C'); 168 else 169 $this->Cell(7, 5, chr(149), 0, 0, 'C'); 170 } 171 172 if ($tag == 'IMG') { 173 $this->SRC = $this->prop['SRC']; 174 $size = getimagesize( 175 $this->SRC); # Attention, utilisation de GD !!! FPDF ne sait pas lire les images à moitié... et je n'ai pas envie de surcharger la méthode Image... 176 if ($size[0] < 30 && $size[1] < 30) { 177 # pixel / 3 pour avoir des cm. Petite cuisine... 178 $imgX = $size[0] / 3; 179 $imgY = $size[1] / 3; 180 $yoffset = $imgY / 4; 181 182 if ($this->GetY() + $imgY > $this->h - $this->bMargin) 183 $this->AddPage(); 184 185 $this->Image($this->SRC, $this->GetX(), $this->GetY() - $yoffset, $imgX, $imgY); 186 $this->SetX($this->GetX() + $size[0] / 2); 187 } 188 else if ($size[0] < 600 && $size[1] < 600) { 189 $pwidth = $this->w - $this->lMargin - $this->rMargin; 190 $ratio = 0.24; # ce qui fait environ 600 pixels sur 16cm d'espace utile (160/600) - 2 pouillièmes 191 $imgX = $size[0] * $ratio; 192 $imgY = $size[1] * $ratio; 193 194 if ($this->GetY() + $imgY > $this->h - $this->bMargin) { 195 if ($this->GetY() + $imgY * 0.8 > $this->h - $this->bMargin) { 196 $this->AddPage(); 197 } 198 else { 199 $imgX = $imgX * 0.8; 200 $imgY = $imgY * 0.8; 201 } 202 } 203 204 $this->Image($this->SRC, $this->GetX() + ($pwidth - $imgX) / 2, $this->GetY(), $imgX, $imgY); 205 $this->SetY($this->GetY() + $imgY); 206 } 207 else { 208 // les deux dimensions sont supérieurs à 600 pixels 209 $pwidth = $this->w - $this->lMargin - $this->rMargin; 210 $ratioX = $pwidth / $size[0]; 211 $plen = $this->h - $this->GetY() - $this->bMargin 212 - 20; // on retire 20mm pour placer le cartouche de l'image 213 $ratioY = $plen / $size[1]; 214 $ratio = 0.24; # ce qui fait environ 600 pixels sur 16cm d'espace utile (160/600) - 2 pouillièmes 215 $imgX = $size[0] * $ratio; 216 $imgY = $size[1] * $ratio; 217 218 if ($size[1] > 900 || ($plen - ($size[1] * $ratio) < 0)) { 219 if ($plen - ($size[1] * $ratio * 0.8) < 0) { 220 $this->AddPage(); 221 $plen = $this->h - $this->GetY() - $this->bMargin - 20; // toujours la marge du cartouche 222 $ratioY = $plen / $size[1]; 223 } 224 else { 225 $ratioX *= 0.8; 226 $ratioY *= 0.8; 227 } 228 } 229 230 $ratio = min(0.24, $ratioX, $ratioY); 231 232 $imgX = $size[0] * $ratio; 233 $imgY = $size[1] * $ratio; 234 235 $this->Image($this->SRC, $this->GetX() + ($pwidth - $imgX) / 2, $this->GetY(), $imgX, $imgY); 236 $this->SetY($this->GetY() + $imgY); 237 } 238 } 239 240 if ($tag == 'TT' or $tag == 'TEXTAREA') { 241 $this->SetFont('courier', '', 8); 242 $this->SetTextColor(255, 0, 0); 243 if ($tag == 'TEXTAREA') 244 $this->ProcessingCadre = true; 245 } 246 247 if ($tag == 'TABLE') { 248 $this->ProcessingTable = true; 249 $this->inFirstRow = 1; 250 251 # on commence une table 252 if (!isset($this->tableProp['width'])) 253 $this->tableProp['width'] = 0; 254 255 if ($this->tableProp['width'] == 0) 256 $this->tableProp['width'] = $this->w - $this->lMargin - $this->rMargin; 257 258 if (!isset($this->tableProp['align'])) 259 $this->tableProp['align'] = 'C'; 260 261 if (!isset($this->tableProp['padding'])) 262 $this->tableProp['padding'] = $this->cMargin; 263 264 $cMargin = $this->cMargin; 265 $this->cMargin = $this->tableProp['padding']; 266 267 if (!isset($this->tableProp['HeaderColor'])) 268 $this->tableProp['HeaderColor'] = array(200, 200, 200); 269 270 $this->HeaderColor = $this->tableProp['HeaderColor']; 271 272 if (!isset($this->tableProp['color1'])) 273 $this->tableProp['color1'] = array(); 274 275 if (!isset($this->tableProp['color2'])) 276 $this->tableProp['color2'] = array(230, 230, 230); 277 278 $this->RowColors = array($this->tableProp['color1'], $this->tableProp['color2']); 279 $this->tableCurrentRow = 0; 280 } 281 282 if ($tag == 'TR') { 283 # on commence une ligne 284 $this->tableCurrentCol = 0; 285 $this->tableCurrentRow++; 286 if ($prop['CLASS'] == 'row_first') { 287 $this->ProcessingTH = true; 288 } 289 } 290 291 if ($tag == 'TH' or $tag == 'TD') { 292 # Cellule (pas titre) 293 $this->tableCurrentCol += 1; 294 295 if ($this->inFirstRow) { 296 $this->nCols = $this->tableCurrentCol; 297 $this->AddCol(); 298 } 299 $this->ProcessingTDTH = true; 300 } 301 302 if ($tag == 'HR') { 303 # Ligne horizontale 304 $this->SetLineWidth(0.3); 305 $this->Line($this->lMargin, $this->GetY(), $this->w - $this->rMargin, $this->GetY()); 306 } 307 } 308 309 function CloseTag ($tag) { 310 //Balise fermante 311 if ($tag == 'B' or $tag == 'I' or $tag == 'U') { 312 $this->SetStyle($tag, false); 313 } 314 315 if ($tag == 'A') { 316 $this->HREF = ''; 317 } 318 319 if ($tag == 'P') { 320 $this->Ln(5); 321 } 322 323 if ($tag == 'CODE') { 324 $this->Write(5, '</code>'); 325 } 326 327 if ($tag == 'H3') { 328 $this->SetStyle($tag = 'B', false, 10); 329 $this->Ln(5); 330 } 331 332 if ($tag == 'UL' or $tag == 'OL') { 333 $this->SetLeftMargin($this->lMargin - 7); 334 $this->Ln(); 335 $this->listParm[$this->listDepth] = array(); 336 $this->listDepth--; 337 } 338 339 if ($tag == 'TT' or $tag == 'TEXTAREA') { 340 $this->SetFont('helvetica', '', 10); 341 $this->SetTextColor(0); 342 if ($tag == 'TEXTAREA') 343 $this->ProcessingCadre = false; 344 } 345 346 if ($tag == 'TD' or $tag == 'TH') { 347 $this->ProcessingTDTH = false; 348 } 349 350 if ($tag == 'TR') { 351 $this->inFirstRow = 0; # on a fini une ligne donc la première aussi 352 $this->ProcessingTH = false; 353 } 354 355 if ($tag == 'TABLE') { 356 $this->TableShow('C'); 357 $this->inFirstRow = 0; 358 $this->ProcessingTable = false; 359 $this->cMargin = $cMargin; 360 $this->columnProp = array(); 361 $this->tableContent = array(); 362 } 363 } 364 365 function SetStyle ($tag, $enable, $size = 0) { 366 //Modifie le style et sélectionne la police correspondante 367 $this->$tag += ($enable ? 1 : -1); 368 $style = ''; 369 370 foreach (array('B', 'I', 'U')as $s) 371 if ($this->$s > 0) 372 $style .= $s; 373 374 if ($size == 0) 375 $this->SetFont('', $style); 376 else 377 $this->SetFont('', $style, $size); 378 } 379 380 function PutLink ($URL, $txt) { 381 //Place un hyperlien 382 $this->SetTextColor(0, 0, 255); 383 $this->SetStyle('U', true); 384 $this->Write(5, $txt, $URL); 385 $this->SetStyle('U', false); 386 $this->SetTextColor(0); 387 } 388 389 function Header () { } 390 391 /* 392 Pas utilisé pour l'instant 393 function Header() 394 { 395 //Imprime l'en-tête du tableau si nécessaire 396 if($this->ProcessingTable) 397 $this->TableHeader(); 398 } 399 400 function TableHeader() 401 { 402 $this->SetFont('helvetica','B',8); 403 $this->SetX($this->TableX); 404 $fill=!empty($this->HeaderColor); 405 if($fill) 406 $this->SetFillColor($this->HeaderColor[0],$this->HeaderColor[1],$this->HeaderColor[2]); 407 foreach($this->columnProp as $col) 408 $this->Cell($column['w'],6,1,0,'C',$fill); 409 $this->Ln(); 410 } 411 */ 412 413 function TableShow ($align) { 414 415 // Calcul de la taille de police optimale 416 // Le calcul ne l'est pas, lui ;-) 417 $oldFontSizePt = $this->FontSizePt; 418 $oldFontFamily = $this->FontFamily; 419 420 $tableFontFamily = 'helvetica'; 421 $cellmargin = 3.0; // pifomètre : un peu de marge sur la largeur de cellule 422 $wrwi = $this->w - $this->lMargin - $this->rMargin; 423 //----------- 424 $tableFontSize = 10.0; 425 426 do { 427 $tableFontSize = $tableFontSize - 1.0; 428 // on boucle sur la taille de police tant que la largeur du tableau ne rentre pas dans la page 429 430 $this->SetFont($tableFontFamily, '', $tableFontSize); 431 432 // remise à zéro des largeurs de colonnes 433 foreach ($this->columnProp as $i => $cprop) { 434 $this->columnProp[$i]['w'] = 0.0; 435 } 436 437 // on passe toutes les cellules du tableau en revue 438 // de façon à calculer la largeur max de chaque colonne pour la taille de police courante 439 foreach ($this->tableContent as $j => $row) { 440 foreach ($row as $i => $cell) { 441 if ($this->tableContent[$j][$i]['TH']) { 442 $this->SetFont($tableFontFamily, 'B', $tableFontSize); 443 } 444 445 $len = $this->GetStringWidth($cell['content']); 446 $len += $cellmargin; 447 448 if ($len > $this->columnProp[$i]['w']) { 449 // max... 450 $this->columnProp[$i]['w'] = $len; 451 } 452 $this->SetFont($tableFontFamily, '', $tableFontSize); 453 } 454 } 455 456 // Repris de CalcWidth : calcul de la largeur de la table 457 $TableWidth = 0.0; 458 459 foreach ($this->columnProp as $col) { 460 $TableWidth += $col['w']; 461 } 462 } while ($TableWidth > $wrwi && $tableFontSize > 1.0); 463 464 //----------- 465 // Envoi du tableau dans le flux PDF 466 //----------- 467 468 //Calcule l'abscisse du tableau 469 if ($align == 'C') 470 $this->TableX = max(($this->w - $TableWidth) / 2, 0); 471 elseif ($align == 'R') 472 $this->TableX = max($this->w - $this->rMargin - $TableWidth, 0); 473 else 474 $this->TableX = $this->lMargin; 475 476 $ci = 0; # flip-flop pour couleur de fond de ligne 477 478 foreach ($this->tableContent as $j => $row) { 479 $this->SetX($this->TableX); 480 $fill = !empty($this->RowColors[$ci]); 481 482 if ($fill) { 483 $this->SetFillColor($this->RowColors[$ci][0], $this->RowColors[$ci][1], $this->RowColors[$ci][2]); 484 } 485 486 foreach ($this->tableContent[$j] as $i => $cell) { 487 // print("Cellule : [".$cell."], \$i=".$i." largeur : ".$this->columnProp[$i]['w']."<BR>"); 488 if ($this->tableContent[$j][$i]['TH'] == true) { 489 $this->SetFont($tableFontFamily, 'B', $tableFontSize); 490 $this->SetFillColor(255, 255, 0); // jaune 491 $fill = 1; 492 } 493 494 $this->Cell($this->columnProp[$i]['w'], 5, $cell['content'], 1, 0, $this->columnProp[$i]['a'], $fill); 495 if ($this->tableContent[$j][$i]['TH']) { 496 $this->SetFont('', '', $tableFontSize); 497 $this->SetFillColor(255); // blanc 498 } 499 } 500 501 $ci = 1 - $ci; 502 $this->Ln(); 503 } 504 505 $this->SetFont($oldFontFamily, '', $oldFontSizePt); 506 } 507 } 508 ?>
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
Généré le : Sat Feb 24 14:40:03 2007 | par Balluche grâce à PHPXref 0.7 |