From 54c6db5b810523ba0aba4486ec7677bf3372055f Mon Sep 17 00:00:00 2001
From: Laurent Destailleur <eldy@destailleur.fr>
Date: Wed, 8 Aug 2012 04:12:20 +0200
Subject: [PATCH] Qual: Uniformize code for pdf generation. Refactoring of pdf
 code to make code cleaner and fix a lot of bug into page breaks.

---
 htdocs/admin/fournisseur.php                  |  26 +--
 htdocs/admin/project.php                      |  12 +-
 .../core/class/commondocgenerator.class.php   |  18 ++
 htdocs/core/lib/pdf.lib.php                   |  29 +--
 htdocs/core/modules/action/rapport.pdf.php    |   4 +-
 .../modules/cheque/pdf/pdf_blochet.class.php  |   4 +-
 .../commande/doc/pdf_edison.modules.php       |  75 +++++---
 .../commande/doc/pdf_einstein.modules.php     |  76 ++++----
 .../doc/pdf_expedition_merou.modules.php      |   8 +-
 .../doc/pdf_expedition_rouget.modules.php     |  21 ++-
 .../modules/facture/doc/pdf_crabe.modules.php | 166 ++++++++----------
 .../facture/doc/pdf_oursin.modules.php        | 122 +++++++++----
 .../fichinter/doc/pdf_soleil.modules.php      | 100 +++++------
 .../livraison/pdf/pdf_sirocco.modules.php     |  81 ++++-----
 .../livraison/pdf/pdf_typhon.modules.php      | 107 ++++++-----
 .../project/pdf/pdf_baleine.modules.php       |  84 +++++----
 .../modules/propale/doc/pdf_azur.modules.php  | 104 ++++++-----
 .../modules/propale/doc/pdf_jaune.modules.php | 104 ++++++-----
 .../pdf/pdf_canelle.modules.php               | 114 ++++++------
 .../pdf/pdf_muscadet.modules.php              | 111 ++++++------
 .../fourn/class/fournisseur.facture.class.php |   1 +
 21 files changed, 705 insertions(+), 662 deletions(-)

diff --git a/htdocs/admin/fournisseur.php b/htdocs/admin/fournisseur.php
index efc3b826b2a..4c6c3fa533d 100644
--- a/htdocs/admin/fournisseur.php
+++ b/htdocs/admin/fournisseur.php
@@ -55,7 +55,7 @@ if ($action == 'updateMask')
 {
     $maskconstorder=GETPOST('maskconstorder','alpha');
     $maskorder=GETPOST('maskorder','alpha');
-    
+
     if ($maskconstorder)  $res = dolibarr_set_const($db,$maskconstorder,$maskorder,'chaine',0,'',$conf->entity);
 
     if (! $res > 0) $error++;
@@ -77,7 +77,7 @@ if ($action == 'specimen')  // For orders
     $commande = new CommandeFournisseur($db);
     $commande->initAsSpecimen();
     $commande->thirdparty=$specimenthirdparty;
-    
+
     // Search template files
     $file=''; $classname=''; $filefound=0;
     $dirmodels=array_merge(array('/'),(array) $conf->modules_parts['models']);
@@ -91,13 +91,13 @@ if ($action == 'specimen')  // For orders
     		break;
     	}
     }
-    
+
     if ($filefound)
     {
     	require_once($file);
-    
-    	$module = new $classname($db);
-    
+
+    	$module = new $classname($db,$commande);
+
     	if ($module->write_file($commande,$langs) > 0)
     	{
     		header("Location: ".DOL_URL_ROOT."/document.php?modulepart=commande_fournisseur&file=SPECIMEN.pdf");
@@ -123,7 +123,7 @@ if ($action == 'specimenfacture')   // For invoices
     $facture = new FactureFournisseur($db);
     $facture->initAsSpecimen();
     $facture->thirdparty=$specimenthirdparty;    // Define who should has build the invoice (so the supplier)
-    
+
 	// Search template files
     $file=''; $classname=''; $filefound=0;
     $dirmodels=array_merge(array('/'),(array) $conf->modules_parts['models']);
@@ -137,13 +137,13 @@ if ($action == 'specimenfacture')   // For invoices
     		break;
     	}
     }
-    
+
     if ($filefound)
     {
     	require_once($file);
-    
-    	$module = new $classname($db);
-    
+
+    	$module = new $classname($db,$facture);
+
     	if ($module->write_file($facture,$langs) > 0)
     	{
     		header("Location: ".DOL_URL_ROOT."/document.php?modulepart=facture_fournisseur&file=SPECIMEN.pdf");
@@ -166,7 +166,7 @@ if ($action == 'set')
 {
 	$label = GETPOST('label','alpha');
 	$scandir = GETPOST('scandir','alpha');
-	
+
     $sql = "INSERT INTO ".MAIN_DB_PREFIX."document_model (nom, type, entity, libelle, description)";
     $sql.= " VALUES ('".$db->escape($value)."','".$type."',".$conf->entity.", ";
     $sql.= ($label?"'".$db->escape($label)."'":'null').", ";
@@ -198,7 +198,7 @@ if ($action == 'setdoc')
 {
 	$label = GETPOST('label','alpha');
 	$scandir = GETPOST('scandir','alpha');
-	
+
     $db->begin();
 
     if ($type == 'order_supplier' && dolibarr_set_const($db, "COMMANDE_SUPPLIER_ADDON_PDF",$value,'chaine',0,'',$conf->entity))
diff --git a/htdocs/admin/project.php b/htdocs/admin/project.php
index ad67ba3a317..80be64c8153 100644
--- a/htdocs/admin/project.php
+++ b/htdocs/admin/project.php
@@ -51,7 +51,7 @@ if ($action == 'updateMask')
 {
 	$maskconstproject=GETPOST('maskconstproject','alpha');
 	$maskproject=GETPOST('maskproject','alpha');
-	
+
 	if ($maskconstproject)  $res = dolibarr_set_const($db,$maskconstproject,$maskproject,'chaine',0,'',$conf->entity);
 
 	if (! $res > 0) $error++;
@@ -86,7 +86,7 @@ if ($action == 'specimen')
 			break;
 		}
 	}
-	
+
 	if ($filefound)
 	{
 		require_once($file);
@@ -207,7 +207,7 @@ foreach ($dirmodels as $reldir)
 					if ($module->version == 'experimental' && $conf->global->MAIN_FEATURES_LEVEL < 1) continue;
 
 					if ($module->isEnabled())
-					{						
+					{
 						$var=!$var;
 						print '<tr '.$bc[$var].'><td>'.$module->nom."</td><td>\n";
 						print $module->info();
@@ -339,10 +339,10 @@ foreach ($dirmodels as $reldir)
 					// Active
 					if (in_array($name, $def))
 					{
-						print "<td align=\"center\">\n";						
+						print "<td align=\"center\">\n";
 						print '<a href="'.$_SERVER["PHP_SELF"].'?action=del&amp;value='.$name.'&amp;scandir='.$module->scandir.'&amp;label='.urlencode($module->name).'">';
 						print img_picto($langs->trans("Enabled"),'switch_on');
-						print '</a>';						
+						print '</a>';
 						print "</td>";
 					}
 					else
@@ -371,7 +371,7 @@ foreach ($dirmodels as $reldir)
 					$htmltooltip.='<br><br><u>'.$langs->trans("FeaturesSupported").':</u>';
 					$htmltooltip.='<br>'.$langs->trans("Logo").': '.yn($module->option_logo,1,1);
 					print '<td align="center">';
-					$link='<a href="'.$_SERVER["PHP_SELF"].'?action=specimen&amp;module='.$name.'">'.img_object($langs->trans("Preview"),'order').'</a>';
+					$link='<a href="'.$_SERVER["PHP_SELF"].'?action=specimen&amp;module='.$name.'">'.img_object($langs->trans("Preview"),'project').'</a>';
 					print $form->textwithpicto(' &nbsp; &nbsp; '.$link,$htmltooltip,-1,0);
 					print '</td>';
 
diff --git a/htdocs/core/class/commondocgenerator.class.php b/htdocs/core/class/commondocgenerator.class.php
index 494867ec94f..cd474a141bf 100755
--- a/htdocs/core/class/commondocgenerator.class.php
+++ b/htdocs/core/class/commondocgenerator.class.php
@@ -165,6 +165,24 @@ abstract class CommonDocGenerator
         );
     }
 
+	/**
+	 * Rect pdf
+	 *
+	 * @param unknown_type $pdf
+	 * @param unknown_type $x
+	 * @param unknown_type $y
+	 * @param unknown_type $l
+	 * @param unknown_type $h
+	 * @param	int		$hidetop		Hide top
+	 * @param	int		$hidebottom		Hide bottom
+	 */
+    function printRect($pdf, $x, $y, $l, $h, $hidetop=0, $hidebottom=0)
+    {
+	    if (empty($hidetop)) $pdf->line($x, $y, $x+$l, $y);
+	    $pdf->line($x+$l, $y, $x+$l, $y+$h);
+	    if (empty($hidebottom)) $pdf->line($x+$l, $y+$h, $x, $y+$h);
+	    $pdf->line($x, $y+$h, $x, $y);
+    }
 }
 
 ?>
diff --git a/htdocs/core/lib/pdf.lib.php b/htdocs/core/lib/pdf.lib.php
index 99cac8eb60b..2a7b004c7c3 100644
--- a/htdocs/core/lib/pdf.lib.php
+++ b/htdocs/core/lib/pdf.lib.php
@@ -524,12 +524,12 @@ function pdf_bank(&$pdf,$outputlangs,$curx,$cury,$account,$onlynumber=0,$default
  *  @param  Translate	$outputlangs	Object lang for output
  * 	@param	string		$paramfreetext	Constant name of free text
  * 	@param	Societe		$fromcompany	Object company
- * 	@param	int			$marge_basse	Margin bottom
- * 	@param	int			$marge_gauche	Margin left
- * 	@param	int			$page_hauteur	Page height
+ * 	@param	int			$marge_basse	Margin bottom we use for the autobreak
+ * 	@param	int			$marge_gauche	Margin left (no more used)
+ * 	@param	int			$page_hauteur	Page height (no more used)
  * 	@param	Object		$object			Object shown in PDF
- * 	@param	int			$showdetails	Show company details
- * 	@return	void
+ * 	@param	int			$showdetails	Show company details into footer. This param seems to not be used by standard version.
+ * 	@return	int							Return height of bottom margin including footer text
  */
 function pdf_pagefoot(&$pdf,$outputlangs,$paramfreetext,$fromcompany,$marge_basse,$marge_gauche,$page_hauteur,$object,$showdetails=0)
 {
@@ -538,6 +538,8 @@ function pdf_pagefoot(&$pdf,$outputlangs,$paramfreetext,$fromcompany,$marge_bass
 	$outputlangs->load("dict");
 	$line='';
 
+	$dims=$pdf->getPageDimensions();
+
 	// Line of free text
 	if (! empty($conf->global->$paramfreetext))
 	{
@@ -659,11 +661,12 @@ function pdf_pagefoot(&$pdf,$outputlangs,$paramfreetext,$fromcompany,$marge_bass
 	$nbofline=dol_nboflines_bis($line,0,$outputlangs->charset_output);
 	//print 'nbofline='.$nbofline; exit;
 	//print 'e'.$line.'t'.dol_nboflines($line);exit;
-	$posy=$marge_basse + ($nbofline*3) + (! empty($line1)?3:0) + (! empty($line2)?3:0) + (! empty($line3)?3:0) + (! empty($line4)?3:0);
+	$marginwithfooter=$marge_basse + ($nbofline*3) + (! empty($line1)?3:0) + (! empty($line2)?3:0) + (! empty($line3)?3:0) + (! empty($line4)?3:0);
+	$posy=$marginwithfooter+0;
 
 	if ($line)	// Free text
 	{
-		$pdf->SetXY($marge_gauche,-$posy);
+		$pdf->SetXY($dims['lm'],-$posy);
 		$width=20000; $align='L';	// By default, ask a manual break: We use a large value 20000, to not have automatic wrap. This make user understand, he need to add CR on its text.
 		if ($conf->global->MAIN_USE_AUTOWRAP_ON_FREETEXT) { $width=200; $align='C'; }
 		$pdf->MultiCell($width, 3, $line, 0, $align, 0);
@@ -671,13 +674,13 @@ function pdf_pagefoot(&$pdf,$outputlangs,$paramfreetext,$fromcompany,$marge_bass
 	}
 
 	$pdf->SetY(-$posy);
-	$pdf->line($marge_gauche, $page_hauteur-$posy, 200, $page_hauteur-$posy);
+	$pdf->line($dims['lm'], $dims['hk']-$posy, $dims['wk']-$dims['rm'], $dims['hk']-$posy);
 	$posy--;
 
 	if (! empty($line1))
 	{
 		$pdf->SetFont('','B',7);
-		$pdf->SetXY($marge_gauche,-$posy);
+		$pdf->SetXY($dims['lm'],-$posy);
 		$pdf->MultiCell(200, 2, $line1, 0, 'C', 0);
 		$posy-=3;
 		$pdf->SetFont('','',7);
@@ -686,7 +689,7 @@ function pdf_pagefoot(&$pdf,$outputlangs,$paramfreetext,$fromcompany,$marge_bass
 	if (! empty($line2))
 	{
 		$pdf->SetFont('','B',7);
-		$pdf->SetXY($marge_gauche,-$posy);
+		$pdf->SetXY($dims['lm'],-$posy);
 		$pdf->MultiCell(200, 2, $line2, 0, 'C', 0);
 		$posy-=3;
 		$pdf->SetFont('','',7);
@@ -694,14 +697,14 @@ function pdf_pagefoot(&$pdf,$outputlangs,$paramfreetext,$fromcompany,$marge_bass
 
 	if (! empty($line3))
 	{
-		$pdf->SetXY($marge_gauche,-$posy);
+		$pdf->SetXY($dims['lm'],-$posy);
 		$pdf->MultiCell(200, 2, $line3, 0, 'C', 0);
 	}
 
 	if (! empty($line4))
 	{
 		$posy-=3;
-		$pdf->SetXY($marge_gauche,-$posy);
+		$pdf->SetXY($dims['lm'],-$posy);
 		$pdf->MultiCell(200, 2, $line4, 0, 'C', 0);
 	}
 
@@ -712,6 +715,8 @@ function pdf_pagefoot(&$pdf,$outputlangs,$paramfreetext,$fromcompany,$marge_bass
 		$pdf->MultiCell(11, 2, $pdf->PageNo().'/'.$pdf->getAliasNbPages(), 0, 'R', 0);
 		//print 'xxx'.$pdf->getAliasNbPages().'-'.$pdf->getAliasNumPage();exit;
 	}
+
+	return $marginwithfooter;
 }
 
 /**
diff --git a/htdocs/core/modules/action/rapport.pdf.php b/htdocs/core/modules/action/rapport.pdf.php
index e2a92b18753..5a9d1438261 100644
--- a/htdocs/core/modules/action/rapport.pdf.php
+++ b/htdocs/core/modules/action/rapport.pdf.php
@@ -112,6 +112,9 @@ class CommActionRapport
 		if (file_exists($dir))
 		{
             $pdf=pdf_getInstance($this->format);
+            $heightforinfotot = 80;	// Height reserved to output the info and total part (value include bottom margin)
+            $heightforfooter = 25;	// Height reserved to output the footer (value include bottom margin)
+            $pdf->SetAutoPageBreak(1,0);
 
             if (class_exists('TCPDF'))
             {
@@ -132,7 +135,6 @@ class CommActionRapport
 			$pdf->SetKeywords($outputlangs->convToOutputCharset($this->title." ".$this->subject));
 
 			$pdf->SetMargins($this->marge_gauche, $this->marge_haute, $this->marge_droite);   // Left, Top, Right
-			$pdf->SetAutoPageBreak(1,0);
 
 			$nbpage = $this->_pages($pdf, $outputlangs);
 
diff --git a/htdocs/core/modules/cheque/pdf/pdf_blochet.class.php b/htdocs/core/modules/cheque/pdf/pdf_blochet.class.php
index 923ee55baf0..98bea5676f8 100644
--- a/htdocs/core/modules/cheque/pdf/pdf_blochet.class.php
+++ b/htdocs/core/modules/cheque/pdf/pdf_blochet.class.php
@@ -117,6 +117,9 @@ class BordereauChequeBlochet extends ModeleChequeReceipts
 
 		// Create PDF instance
         $pdf=pdf_getInstance($this->format);
+        $heightforinfotot = 80;	// Height reserved to output the info and total part (value include bottom margin)
+        $heightforfooter = 25;	// Height reserved to output the footer (value include bottom margin)
+        $pdf->SetAutoPageBreak(1,0);
 
         if (class_exists('TCPDF'))
         {
@@ -137,7 +140,6 @@ class BordereauChequeBlochet extends ModeleChequeReceipts
 		if ($conf->global->MAIN_DISABLE_PDF_COMPRESSION) $pdf->SetCompression(false);
 
 		$pdf->SetMargins($this->marge_gauche, $this->marge_haute, $this->marge_droite);   // Left, Top, Right
-		$pdf->SetAutoPageBreak(1,0);
 
 		$nboflines=count($this->lines);
 		// Define nb of page
diff --git a/htdocs/core/modules/commande/doc/pdf_edison.modules.php b/htdocs/core/modules/commande/doc/pdf_edison.modules.php
index 0ec5df0960d..c8d707b51ce 100644
--- a/htdocs/core/modules/commande/doc/pdf_edison.modules.php
+++ b/htdocs/core/modules/commande/doc/pdf_edison.modules.php
@@ -141,6 +141,9 @@ class pdf_edison extends ModelePDFCommandes
 				$nblignes = count($object->lines);
 
 				$pdf=pdf_getInstance($this->format);
+				$heightforinfotot = 80;	// Height reserved to output the info and total part (value include bottom margin)
+				$heightforfooter = 25;	// Height reserved to output the footer (value include bottom margin)
+				$pdf->SetAutoPageBreak(1,0);
 
                 if (class_exists('TCPDF'))
                 {
@@ -167,7 +170,6 @@ class pdf_edison extends ModelePDFCommandes
 				if ($conf->global->MAIN_DISABLE_PDF_COMPRESSION) $pdf->SetCompression(false);
 
 				$pdf->SetMargins($this->marge_gauche, $this->marge_haute, $this->marge_droite);   // Left, Top, Right
-				$pdf->SetAutoPageBreak(1,0);
 
 				// New page
 				$pdf->AddPage();
@@ -200,9 +202,16 @@ class pdf_edison extends ModelePDFCommandes
 
 					$pdf->SetFont('','', $default_font_size - 1);   // Dans boucle pour gerer multi-page
 
+					$pdf->setPageOrientation('', 1, $this->marge_basse+$heightforfooter+$heightforinfotot);	// The only function to edit the bottom margin of current page to set it.
+					$pageposbefore=$pdf->getPage();
+
 					// Description of product line
 					pdf_writelinedesc($pdf,$object,$i,$outputlangs,100,3,30,$curY,1,$hidedesc,0,$hookmanager);
 
+					$pageposafter=$pdf->getPage();
+					$pdf->setPage($pageposbefore);
+					$pdf->setPageOrientation('', 1, 0);	// The only function to edit the bottom margin of current page to set it.
+
 					$pdf->SetFont('','', $default_font_size - 1);   // On repositionne la police par defaut
 					$nexY = $pdf->GetY();
 
@@ -228,39 +237,51 @@ class pdf_edison extends ModelePDFCommandes
 
 					$nexY+=2;    // Passe espace entre les lignes
 
-					// cherche nombre de lignes a venir pour savoir si place suffisante
-					if ($i < ($nblignes - 1) && empty($hidedesc))	// If it's not last line
-					{
-						//on recupere la description du produit suivant
-						$follow_descproduitservice = $object->lines[$i+1]->desc;
-						//on compte le nombre de ligne afin de verifier la place disponible (largeur de ligne 52 caracteres)
-						$nblineFollowDesc = (dol_nboflines_bis($follow_descproduitservice,52,$outputlangs->charset_output)*4);
-					}
-					else	// If it's last line
+					// Detect if some page were added automatically and output _tableau for past pages
+					while ($pagenb < $pageposafter)
 					{
-						$nblineFollowDesc = 0;
+						if ($pagenb == 1)
+						{
+							$this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforfooter, 0, $outputlangs, 0, 1);
+						}
+						else
+						{
+							$this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforfooter, 0, $outputlangs, 1, 1);
+						}
+						$this->_pagefoot($pdf,$object,$outputlangs);
+						$pagenb++;
+						$pdf->setPage($pagenb);
+						$pdf->setPageOrientation('', 1, 0);	// The only function to edit the bottom margin of current page to set it.
 					}
-
-					if ((($nexY+$nblineFollowDesc) > ($tab_top+$tab_height) && $i < ($nblignes - 1)) || (isset($object->lines[$i+1]->pagebreak) && $object->lines[$i+1]->pagebreak))
+					if (isset($object->lines[$i+1]->pagebreak) && $object->lines[$i+1]->pagebreak)
 					{
-						$this->_tableau($pdf, $tab_top, $tab_height, $nexY, $outputlangs);
-
+						if ($pagenb == 1)
+						{
+							$this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforfooter, 0, $outputlangs, 0, 1);
+						}
+						else
+						{
+							$this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforfooter, 0, $outputlangs, 1, 1);
+						}
+						$this->_pagefoot($pdf,$object,$outputlangs);
 						// New page
 						$pdf->AddPage();
-				        if (! empty($tplidx)) $pdf->useTemplate($tplidx);
+						if (! empty($tplidx)) $pdf->useTemplate($tplidx);
 						$pagenb++;
-						$this->_pagehead($pdf, $object, 0, $outputlangs, $hookmanager);
-						$pdf->SetFont('','', $default_font_size - 1);
-						$pdf->MultiCell(0, 3, '');		// Set interline to 3
-						$pdf->SetTextColor(0,0,0);
-
-						$nexY = $tab_top + 8;
 					}
 				}
 
-				$this->_tableau($pdf, $tab_top, $tab_height, $nexY, $outputlangs);
-
-				$bottomlasttab=$tab_top + $tab_height + 1;
+				// Show square
+				if ($pagenb == 1)
+				{
+					$this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforinfotot, 0, $outputlangs, 0, 0);
+					$bottomlasttab=$this->page_hauteur - $heightforinfotot + 1;
+				}
+				else
+				{
+					$this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforinfotot, 0, $outputlangs, 1, 0);
+					$bottomlasttab=$this->page_hauteur - $heightforinfotot + 1;
+				}
 
 				// Affiche zone infos
 				$this->_tableau_info($pdf, $object, $bottomlasttab, $outputlangs);
@@ -467,9 +488,11 @@ class pdf_edison extends ModelePDFCommandes
 	 *   @param		string		$tab_height		Height of table (rectangle)
 	 *   @param		int			$nexY			Y
 	 *   @param		Translate	$outputlangs	Langs object
+	 *   @param		int			$hidetop		Hide top bar of array
+	 *   @param		int			$hidebottom		Hide bottom bar of array
 	 *   @return	void
 	 */
-	function _tableau(&$pdf, $tab_top, $tab_height, $nexY, $outputlangs)
+	function _tableau(&$pdf, $tab_top, $tab_height, $nexY, $outputlangs, $hidetop=0, $hidebottom=0)
 	{
 		global $langs,$conf;
 		$langs->load("main");
diff --git a/htdocs/core/modules/commande/doc/pdf_einstein.modules.php b/htdocs/core/modules/commande/doc/pdf_einstein.modules.php
index 899ea1c69b4..76ac2268b0f 100644
--- a/htdocs/core/modules/commande/doc/pdf_einstein.modules.php
+++ b/htdocs/core/modules/commande/doc/pdf_einstein.modules.php
@@ -177,6 +177,9 @@ class pdf_einstein extends ModelePDFCommandes
 				$nblignes = count($object->lines);
 
                 $pdf=pdf_getInstance($this->format);
+                $heightforinfotot = 80;	// Height reserved to output the info and total part (value include bottom margin)
+                $heightforfooter = 25;	// Height reserved to output the footer (value include bottom margin)
+                $pdf->SetAutoPageBreak(1,0);
 
                 if (class_exists('TCPDF'))
                 {
@@ -203,7 +206,6 @@ class pdf_einstein extends ModelePDFCommandes
 				if ($conf->global->MAIN_DISABLE_PDF_COMPRESSION) $pdf->SetCompression(false);
 
 				$pdf->SetMargins($this->marge_gauche, $this->marge_haute, $this->marge_droite);   // Left, Top, Right
-				$pdf->SetAutoPageBreak(1,0);
 
 				// Positionne $this->atleastonediscount si on a au moins une remise
 				for ($i = 0 ; $i < $nblignes ; $i++)
@@ -262,10 +264,17 @@ class pdf_einstein extends ModelePDFCommandes
 
                     $pdf->SetFont('','', $default_font_size - 1);   // Into loop to work with multipage
 
+					$pdf->setPageOrientation('', 1, $this->marge_basse+$heightforfooter+$heightforinfotot);	// The only function to edit the bottom margin of current page to set it.
+					$pageposbefore=$pdf->getPage();
+
 					// Description of product line
 					$curX = $this->posxdesc-1;
 					pdf_writelinedesc($pdf,$object,$i,$outputlangs,$this->posxtva-$curX,3,$curX,$curY,$hideref,$hidedesc,0,$hookmanager);
 
+					$pageposafter=$pdf->getPage();
+					$pdf->setPage($pageposbefore);
+					$pdf->setPageOrientation('', 1, 0);	// The only function to edit the bottom margin of current page to set it.
+
 					$pdf->SetFont('','',  $default_font_size - 1);   // On repositionne la police par defaut
 					$nexY = $pdf->GetY();
 
@@ -321,71 +330,50 @@ class pdf_einstein extends ModelePDFCommandes
 
 					$nexY+=2;    // Passe espace entre les lignes
 
-					// Cherche nombre de lignes a venir pour savoir si place suffisante
-					if ($i < ($nblignes - 1) && empty($hidedesc))	// If it's not last line
+					// Detect if some page were added automatically and output _tableau for past pages
+					while ($pagenb < $pageposafter)
 					{
-						//on recupere la description du produit suivant
-						$follow_descproduitservice = $object->lines[$i+1]->desc;
-						//on compte le nombre de ligne afin de verifier la place disponible (largeur de ligne 52 caracteres)
-						$nblineFollowDesc = (dol_nboflines_bis($follow_descproduitservice,52,$outputlangs->charset_output)*4);
-						// Et si on affiche dates de validite, on ajoute encore une ligne
-						if ($object->lines[$i]->date_start && $object->lines[$i]->date_end)
+						if ($pagenb == 1)
 						{
-							$nblineFollowDesc += 4;
+							$this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforfooter, 0, $outputlangs, 0, 1);
 						}
+						else
+						{
+							$this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforfooter, 0, $outputlangs, 1, 1);
+						}
+						$this->_pagefoot($pdf,$object,$outputlangs);
+						$pagenb++;
+						$pdf->setPage($pagenb);
+						$pdf->setPageOrientation('', 1, 0);	// The only function to edit the bottom margin of current page to set it.
 					}
-					else	// If it's last line
-					{
-						$nblineFollowDesc = 0;
-					}
-
-					// Test if a new page is required
-					if ($pagenb == 1)
-					{
-						$tab_top_in_current_page=$tab_top;
-						$tab_height_in_current_page=$tab_height;
-					}
-					else
-					{
-						$tab_top_in_current_page=$tab_top_newpage;
-						$tab_height_in_current_page=$tab_height_newpage;
-					}
-					if ((($nexY+$nblineFollowDesc) > ($tab_top_in_current_page+$tab_height_in_current_page) && $i < ($nblignes - 1)) || (isset($object->lines[$i+1]->pagebreak) && $object->lines[$i+1]->pagebreak))
+					if (isset($object->lines[$i+1]->pagebreak) && $object->lines[$i+1]->pagebreak)
 					{
 						if ($pagenb == 1)
 						{
-							$this->_tableau($pdf, $tab_top, $tab_height + 20, $nexY, $outputlangs);
+							$this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforfooter, 0, $outputlangs, 0, 1);
 						}
 						else
 						{
-							$this->_tableau($pdf, $tab_top_newpage, $tab_height_newpage, $nexY, $outputlangs);
+							$this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforfooter, 0, $outputlangs, 1, 1);
 						}
-
 						$this->_pagefoot($pdf,$object,$outputlangs);
-
 						// New page
 						$pdf->AddPage();
-				        if (! empty($tplidx)) $pdf->useTemplate($tplidx);
+						if (! empty($tplidx)) $pdf->useTemplate($tplidx);
 						$pagenb++;
-						$this->_pagehead($pdf, $object, 0, $outputlangs, $hookmanager);
-						$pdf->SetFont('','', $default_font_size - 1);
-						$pdf->MultiCell(0, 3, '');		// Set interline to 3
-						$pdf->SetTextColor(0,0,0);
-
-						$nexY = $tab_top_newpage + 7;
 					}
 				}
 
 				// Show square
 				if ($pagenb == 1)
 				{
-					$this->_tableau($pdf, $tab_top, $tab_height, $nexY, $outputlangs);
-					$bottomlasttab=$tab_top + $tab_height + 1;
+					$this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforinfotot, 0, $outputlangs, 0, 0);
+					$bottomlasttab=$this->page_hauteur - $heightforinfotot + 1;
 				}
 				else
 				{
-					$this->_tableau($pdf, $tab_top_newpage, $tab_height_newpage, $nexY, $outputlangs);
-					$bottomlasttab=$tab_top_newpage + $tab_height_newpage + 1;
+					$this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforinfotot, 0, $outputlangs, 1, 0);
+					$bottomlasttab=$this->page_hauteur - $heightforinfotot + 1;
 				}
 
 				// Affiche zone infos
@@ -797,9 +785,11 @@ class pdf_einstein extends ModelePDFCommandes
 	 *   @param		string		$tab_height		Height of table (rectangle)
 	 *   @param		int			$nexY			Y
 	 *   @param		Translate	$outputlangs	Langs object
+	 *   @param		int			$hidetop		Hide top bar of array
+	 *   @param		int			$hidebottom		Hide bottom bar of array
 	 *   @return	void
 	 */
-	function _tableau(&$pdf, $tab_top, $tab_height, $nexY, $outputlangs)
+	function _tableau(&$pdf, $tab_top, $tab_height, $nexY, $outputlangs, $hidetop=0, $hidebottom=0)
 	{
 		global $conf;
 
diff --git a/htdocs/core/modules/expedition/doc/pdf_expedition_merou.modules.php b/htdocs/core/modules/expedition/doc/pdf_expedition_merou.modules.php
index 3b657f5967b..01575734d97 100644
--- a/htdocs/core/modules/expedition/doc/pdf_expedition_merou.modules.php
+++ b/htdocs/core/modules/expedition/doc/pdf_expedition_merou.modules.php
@@ -147,6 +147,9 @@ class pdf_expedition_merou extends ModelePdfExpedition
 			if (file_exists($dir))
 			{
                 $pdf=pdf_getInstance($this->format,'mm','l');
+                $heightforinfotot = 80;	// Height reserved to output the info and total part (value include bottom margin)
+                $heightforfooter = 25;	// Height reserved to output the footer (value include bottom margin)
+                $pdf->SetAutoPageBreak(1,0);
 
 			    if (class_exists('TCPDF'))
                 {
@@ -174,7 +177,6 @@ class pdf_expedition_merou extends ModelePdfExpedition
 				if ($conf->global->MAIN_DISABLE_PDF_COMPRESSION) $pdf->SetCompression(false);
 
 				$pdf->SetMargins($this->marge_gauche, $this->marge_haute, $this->marge_droite);   // Left, Top, Right
-				$pdf->SetAutoPageBreak(1,0);
 
 				$pdf->SetFont('','', $default_font_size - 3);
 
@@ -284,9 +286,11 @@ class pdf_expedition_merou extends ModelePdfExpedition
 	 *   @param		string		$tab_height		Height of table (rectangle)
 	 *   @param		int			$nexY			Y
 	 *   @param		Translate	$outputlangs	Langs object
+	 *   @param		int			$hidetop		Hide top bar of array
+	 *   @param		int			$hidebottom		Hide bottom bar of array
 	 *   @return	void
 	 */
-	function _tableau(&$pdf, $tab_top, $tab_height, $nexY, $outputlangs)
+	function _tableau(&$pdf, $tab_top, $tab_height, $nexY, $outputlangs, $hidetop=0, $hidebottom=0)
 	{
 		global $langs;
 		$default_font_size = pdf_getPDFFontSize($outputlangs);
diff --git a/htdocs/core/modules/expedition/doc/pdf_expedition_rouget.modules.php b/htdocs/core/modules/expedition/doc/pdf_expedition_rouget.modules.php
index 16d757aaafc..e0a9f5211a8 100644
--- a/htdocs/core/modules/expedition/doc/pdf_expedition_rouget.modules.php
+++ b/htdocs/core/modules/expedition/doc/pdf_expedition_rouget.modules.php
@@ -126,6 +126,9 @@ class pdf_expedition_rouget extends ModelePdfExpedition
 			if (file_exists($dir))
 			{
                 $pdf=pdf_getInstance($this->format);
+                $heightforinfotot = 80;	// Height reserved to output the info and total part (value include bottom margin)
+                $heightforfooter = 25;	// Height reserved to output the footer (value include bottom margin)
+                $pdf->SetAutoPageBreak(1,0);
 
                 if (class_exists('TCPDF'))
                 {
@@ -154,7 +157,6 @@ class pdf_expedition_rouget extends ModelePdfExpedition
 				if ($conf->global->MAIN_DISABLE_PDF_COMPRESSION) $pdf->SetCompression(false);
 
 				$pdf->SetMargins($this->marge_gauche, $this->marge_haute, $this->marge_droite);   // Left, Top, Right
-				$pdf->SetAutoPageBreak(1,0);
 
 				// New page
 				$pdf->AddPage();
@@ -223,9 +225,16 @@ class pdf_expedition_rouget extends ModelePdfExpedition
 
 					$pdf->SetFont('','', $default_font_size - 1);   // Dans boucle pour gerer multi-page
 
+					$pdf->setPageOrientation('', 1, $this->marge_basse+$heightforfooter+$heightforinfotot);	// The only function to edit the bottom margin of current page to set it.
+					$pageposbefore=$pdf->getPage();
+
 					// Description de la ligne produit
 					pdf_writelinedesc($pdf,$object,$i,$outputlangs,150,3,$this->posxdesc,$curY,0,1);
 
+					$pageposafter=$pdf->getPage();
+					$pdf->setPage($pageposbefore);
+					$pdf->setPageOrientation('', 1, 0);	// The only function to edit the bottom margin of current page to set it.
+
 					$pdf->SetFont('','', $default_font_size - 1);   // On repositionne la police par defaut
 					$nexY = $pdf->GetY();
 
@@ -274,9 +283,11 @@ class pdf_expedition_rouget extends ModelePdfExpedition
 	 *   @param		string		$tab_height		Height of table (rectangle)
 	 *   @param		int			$nexY			Y
 	 *   @param		Translate	$outputlangs	Langs object
+	 *   @param		int			$hidetop		Hide top bar of array
+	 *   @param		int			$hidebottom		Hide bottom bar of array
 	 *   @return	void
 	 */
-	function _tableau(&$pdf, $tab_top, $tab_height, $nexY, $outputlangs)
+	function _tableau(&$pdf, $tab_top, $tab_height, $nexY, $outputlangs, $hidetop=0, $hidebottom=0)
 	{
 		global $conf;
 
@@ -385,7 +396,7 @@ class pdf_expedition_rouget extends ModelePdfExpedition
 		}
 
 
-		$posx=100;
+		$posx=$this->page_largeur - 100 - $this->marge_droite;
 		$posy=$this->marge_haute;
 
 		$pdf->SetFont('','B', $default_font_size + 2);
@@ -467,7 +478,7 @@ class pdf_expedition_rouget extends ModelePdfExpedition
 			$posx=$this->marge_gauche;
 			$posy=42;
 			$hautcadre=40;
-			if (! empty($conf->global->MAIN_INVERT_SENDER_RECIPIENT)) $posx=118;
+			if (! empty($conf->global->MAIN_INVERT_SENDER_RECIPIENT)) $posx=$this->page_largeur - 80 - $this->marge_droite;
 
 			// Show sender frame
 			$pdf->SetTextColor(0,0,0);
@@ -516,7 +527,7 @@ class pdf_expedition_rouget extends ModelePdfExpedition
 
 			// Show recipient
 			$posy=42;
-			$posx=100;
+			$posx=$this->page_largeur - 100 - $this->marge_droite;
 			if (! empty($conf->global->MAIN_INVERT_SENDER_RECIPIENT)) $posx=$this->marge_gauche;
 
 			// Show recipient frame
diff --git a/htdocs/core/modules/facture/doc/pdf_crabe.modules.php b/htdocs/core/modules/facture/doc/pdf_crabe.modules.php
index 1ab1f99dbbc..327ad5e8b19 100755
--- a/htdocs/core/modules/facture/doc/pdf_crabe.modules.php
+++ b/htdocs/core/modules/facture/doc/pdf_crabe.modules.php
@@ -178,6 +178,9 @@ class pdf_crabe extends ModelePDFFactures
 				$nblignes = count($object->lines);
 
                 $pdf=pdf_getInstance($this->format);
+				$heightforinfotot = 80;	// Height reserved to output the info and total part (value include bottom margin)
+				$heightforfooter = 25;	// Height reserved to output the footer (value include bottom margin)
+                $pdf->SetAutoPageBreak(1,0);
 
                 if (class_exists('TCPDF'))
                 {
@@ -204,7 +207,6 @@ class pdf_crabe extends ModelePDFFactures
 				if ($conf->global->MAIN_DISABLE_PDF_COMPRESSION) $pdf->SetCompression(false);
 
 				$pdf->SetMargins($this->marge_gauche, $this->marge_haute, $this->marge_droite);   // Left, Top, Right
-				$pdf->SetAutoPageBreak(1,0);
 
 				// Positionne $this->atleastonediscount si on a au moins une remise
 				for ($i = 0 ; $i < $nblignes ; $i++)
@@ -225,7 +227,7 @@ class pdf_crabe extends ModelePDFFactures
 				$pdf->SetTextColor(0,0,0);
 
 				$tab_top = 90;
-				$tab_top_newpage = 50;
+				$tab_top_newpage = 10;
 				$tab_height = 130;
 				$tab_height_newpage = 150;
 
@@ -262,8 +264,9 @@ class pdf_crabe extends ModelePDFFactures
 				{
 					$curY = $nexY;
 
+					$pdf->setPageOrientation('', 1, $this->marge_basse+$heightforfooter+$heightforinfotot);	// The only function to edit the bottom margin of current page to set it.
 					$pageposbefore=$pdf->getPage();
-						
+
 					// Description of product line
 					$pdf->SetFont('','', $default_font_size - 1);   // Into loop to work with multipage
 					$curX = $this->posxdesc-1;
@@ -271,7 +274,8 @@ class pdf_crabe extends ModelePDFFactures
 
 					$pageposafter=$pdf->getPage();
 					$pdf->setPage($pageposbefore);
-					
+					$pdf->setPageOrientation('', 1, 0);	// The only function to edit the bottom margin of current page to set it.
+
 					$pdf->SetFont('','', $default_font_size - 1);   // On repositionne la police par defaut
 					$nexY = $pdf->GetY();
 
@@ -332,84 +336,47 @@ class pdf_crabe extends ModelePDFFactures
 					// Detect if some page were added automatically and output _tableau for past pages
 					while ($pagenb < $pageposafter)
 					{
-					    if ($pagenb == 1)
+						if ($pagenb == 1)
 						{
-							$this->_tableau($pdf, $tab_top, $tab_height + 40, 0, $outputlangs);
+							$this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforfooter, 0, $outputlangs, 0, 1);
 						}
 						else
 						{
-							$this->_tableau($pdf, $tab_top_newpage, $tab_height_newpage, 0, $outputlangs);
+							$this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforfooter, 0, $outputlangs, 1, 1);
 						}
+						$this->_pagefoot($pdf,$object,$outputlangs);
 						$pagenb++;
 						$pdf->setPage($pagenb);
+						$pdf->setPageOrientation('', 1, 0);	// The only function to edit the bottom margin of current page to set it.
 					}
-					
-					// Cherche nombre de lignes a venir pour savoir si place suffisante
-					if ($i < ($nblignes - 1) && empty($hidedesc))	// If it's not last line
+					if (isset($object->lines[$i+1]->pagebreak) && $object->lines[$i+1]->pagebreak)
 					{
-						//on recupere la description du produit suivant
-						$follow_descproduitservice = $object->lines[$i+1]->desc;
-						//on compte le nombre de ligne afin de verifier la place disponible (largeur de ligne 52 caracteres)
-						$nblineFollowDesc = dol_nboflines_bis($follow_descproduitservice,52,$outputlangs->charset_output)*4;
-						// Et si on affiche dates de validite, on ajoute encore une ligne
-						if ($object->lines[$i]->date_start && $object->lines[$i]->date_end)
-						{
-							$nblineFollowDesc += 4;
+						if ($pagenb == 1)
+						{
+							$this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforfooter, 0, $outputlangs, 0, 1);
+						}
+						else
+						{
+							$this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforfooter, 0, $outputlangs, 1, 1);
 						}
+						$this->_pagefoot($pdf,$object,$outputlangs);
+						// New page
+						$pdf->AddPage();
+						if (! empty($tplidx)) $pdf->useTemplate($tplidx);
+						$pagenb++;
 					}
-					else	// If it's last line
-					{
-						$nblineFollowDesc = 0;
-					}
-
-					// Test if a new page is required
-					if ($pagenb == 1)
-					{
-						$tab_top_in_current_page=$tab_top;
-						$tab_height_in_current_page=$tab_height;
-					}
-					else
-					{
-						$tab_top_in_current_page=$tab_top_newpage;
-						$tab_height_in_current_page=$tab_height_newpage;
-					}
-					if ((($nexY+$nblineFollowDesc) > ($tab_top_in_current_page+$tab_height_in_current_page) && $i < ($nblignes - 1)) || (isset($object->lines[$i+1]->pagebreak) && $object->lines[$i+1]->pagebreak))
-					{
-					    if ($pagenb == 1)
-						{
-							$this->_tableau($pdf, $tab_top, $tab_height + 40, $nexY, $outputlangs);
-						}
-						else
-						{
-							$this->_tableau($pdf, $tab_top_newpage, $tab_height_newpage, $nexY, $outputlangs);
-						}
-
-						$this->_pagefoot($pdf,$object,$outputlangs);
-
-						// New page
-						$pdf->AddPage();
-				        if (! empty($tplidx)) $pdf->useTemplate($tplidx);
-						$pagenb++;
-						$this->_pagehead($pdf, $object, 0, $outputlangs, $hookmanager);
-						$pdf->SetFont('','', $default_font_size - 1);
-						$pdf->MultiCell(0, 3, '');		// Set interline to 3
-						$pdf->SetTextColor(0,0,0);
-
-						$nexY = $tab_top_newpage + 7;
-					}
-
 				}
 
 				// Show square
 				if ($pagenb == 1)
 				{
-					$this->_tableau($pdf, $tab_top, $tab_height, $nexY, $outputlangs);
-					$bottomlasttab=$tab_top + $tab_height + 1;
+					$this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforinfotot, 0, $outputlangs, 0, 0);
+					$bottomlasttab=$this->page_hauteur - $heightforinfotot + 1;
 				}
 				else
 				{
-					$this->_tableau($pdf, $tab_top_newpage, $tab_height_newpage, $nexY, $outputlangs);
-					$bottomlasttab=$tab_top_newpage + $tab_height_newpage + 1;
+					$this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforinfotot, 0, $outputlangs, 1, 0);
+					$bottomlasttab=$this->page_hauteur - $heightforinfotot + 1;
 				}
 
 				// Affiche zone infos
@@ -960,11 +927,13 @@ class pdf_crabe extends ModelePDFFactures
 	 *   @param		PDF			&$pdf     		Object PDF
 	 *   @param		string		$tab_top		Top position of table
 	 *   @param		string		$tab_height		Height of table (rectangle)
-	 *   @param		int			$nexY			Y
+	 *   @param		int			$nexY			Y (not used)
 	 *   @param		Translate	$outputlangs	Langs object
+	 *   @param		int			$hidetop		Hide top bar of array
+	 *   @param		int			$hidebottom		Hide bottom bar of array
 	 *   @return	void
 	 */
-	function _tableau(&$pdf, $tab_top, $tab_height, $nexY, $outputlangs)
+	function _tableau(&$pdf, $tab_top, $tab_height, $nexY, $outputlangs, $hidetop=0, $hidebottom=0)
 	{
 		global $conf;
 
@@ -973,51 +942,70 @@ class pdf_crabe extends ModelePDFFactures
 		// Amount in (at tab_top - 1)
 		$pdf->SetTextColor(0,0,0);
 		$pdf->SetFont('','', $default_font_size - 2);
-		$titre = $outputlangs->transnoentities("AmountInCurrency",$outputlangs->transnoentitiesnoconv("Currency".$conf->currency));
-		$pdf->SetXY($this->page_largeur - $this->marge_droite - ($pdf->GetStringWidth($titre) + 3), $tab_top-4);
-		$pdf->MultiCell(($pdf->GetStringWidth($titre) + 3), 2, $titre);
+
+		if (empty($hidetop))
+		{
+			$titre = $outputlangs->transnoentities("AmountInCurrency",$outputlangs->transnoentitiesnoconv("Currency".$conf->currency));
+			$pdf->SetXY($this->page_largeur - $this->marge_droite - ($pdf->GetStringWidth($titre) + 3), $tab_top-4);
+			$pdf->MultiCell(($pdf->GetStringWidth($titre) + 3), 2, $titre);
+		}
 
 		$pdf->SetDrawColor(128,128,128);
+		$pdf->SetFont('','', $default_font_size - 1);
 
-		// Rect prend une longueur en 3eme param et 4eme param
-		$pdf->Rect($this->marge_gauche, $tab_top, $this->page_largeur-$this->marge_gauche-$this->marge_droite, $tab_height);
-		// line prend une position y en 2eme param et 4eme param
-		$pdf->line($this->marge_gauche, $tab_top+5, $this->page_largeur-$this->marge_droite, $tab_top+5);
+		// Output Rect
+		$this->printRect($pdf,$this->marge_gauche, $tab_top, $this->page_largeur-$this->marge_gauche-$this->marge_droite, $tab_height, $hidetop, $hidebottom);	// Rect prend une longueur en 3eme param et 4eme param
 
-		$pdf->SetFont('','', $default_font_size - 1);
+		if (empty($hidetop))
+		{
+			$pdf->line($this->marge_gauche, $tab_top+5, $this->page_largeur-$this->marge_droite, $tab_top+5);	// line prend une position y en 2eme param et 4eme param
 
-		$pdf->SetXY($this->posxdesc-1, $tab_top+1);
-		$pdf->MultiCell(108,2, $outputlangs->transnoentities("Designation"),'','L');
+			$pdf->SetXY($this->posxdesc-1, $tab_top+1);
+			$pdf->MultiCell(108,2, $outputlangs->transnoentities("Designation"),'','L');
+		}
 
 		if (empty($conf->global->MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT))
 		{
 			$pdf->line($this->posxtva-1, $tab_top, $this->posxtva-1, $tab_top + $tab_height);
-			$pdf->SetXY($this->posxtva-3, $tab_top+1);
-			$pdf->MultiCell($this->posxup-$this->posxtva+3,2, $outputlangs->transnoentities("VAT"),'','C');
+			if (empty($hidetop))
+			{
+				$pdf->SetXY($this->posxtva-3, $tab_top+1);
+				$pdf->MultiCell($this->posxup-$this->posxtva+3,2, $outputlangs->transnoentities("VAT"),'','C');
+			}
 		}
 
 		$pdf->line($this->posxup-1, $tab_top, $this->posxup-1, $tab_top + $tab_height);
-		$pdf->SetXY($this->posxup-1, $tab_top+1);
-		$pdf->MultiCell($this->posxqty-$this->posxup-1,2, $outputlangs->transnoentities("PriceUHT"),'','C');
+		if (empty($hidetop))
+		{
+			$pdf->SetXY($this->posxup-1, $tab_top+1);
+			$pdf->MultiCell($this->posxqty-$this->posxup-1,2, $outputlangs->transnoentities("PriceUHT"),'','C');
+		}
 
 		$pdf->line($this->posxqty-1, $tab_top, $this->posxqty-1, $tab_top + $tab_height);
-		$pdf->SetXY($this->posxqty-1, $tab_top+1);
-		$pdf->MultiCell($this->posxdiscount-$this->posxqty-1,2, $outputlangs->transnoentities("Qty"),'','C');
+		if (empty($hidetop))
+		{
+			$pdf->SetXY($this->posxqty-1, $tab_top+1);
+			$pdf->MultiCell($this->posxdiscount-$this->posxqty-1,2, $outputlangs->transnoentities("Qty"),'','C');
+		}
 
 		$pdf->line($this->posxdiscount-1, $tab_top, $this->posxdiscount-1, $tab_top + $tab_height);
-		if ($this->atleastonediscount)
+		if (empty($hidetop))
 		{
-			$pdf->SetXY($this->posxdiscount-1, $tab_top+1);
-			$pdf->MultiCell($this->postotalht-$this->posxdiscount+1,2, $outputlangs->transnoentities("ReductionShort"),'','C');
+			if ($this->atleastonediscount)
+			{
+				$pdf->SetXY($this->posxdiscount-1, $tab_top+1);
+				$pdf->MultiCell($this->postotalht-$this->posxdiscount+1,2, $outputlangs->transnoentities("ReductionShort"),'','C');
+			}
 		}
-
 		if ($this->atleastonediscount)
 		{
 			$pdf->line($this->postotalht, $tab_top, $this->postotalht, $tab_top + $tab_height);
 		}
-		$pdf->SetXY($this->postotalht-1, $tab_top+1);
-		$pdf->MultiCell(30,2, $outputlangs->transnoentities("TotalHT"),'','C');
-
+		if (empty($hidetop))
+		{
+			$pdf->SetXY($this->postotalht-1, $tab_top+1);
+			$pdf->MultiCell(30,2, $outputlangs->transnoentities("TotalHT"),'','C');
+		}
 	}
 
 	/**
@@ -1244,7 +1232,7 @@ class pdf_crabe extends ModelePDFFactures
 	 *   	@param	PDF			&$pdf     			PDF
 	 * 		@param	Object		$object				Object to show
 	 *      @param	Translate	$outputlangs		Object lang for output
-	 *      @return	void
+	 *      @return	int								Return height of bottom margin including footer text
 	 */
 	function _pagefoot(&$pdf,$object,$outputlangs)
 	{
diff --git a/htdocs/core/modules/facture/doc/pdf_oursin.modules.php b/htdocs/core/modules/facture/doc/pdf_oursin.modules.php
index d6c8102f2b7..57a7c7a3abd 100755
--- a/htdocs/core/modules/facture/doc/pdf_oursin.modules.php
+++ b/htdocs/core/modules/facture/doc/pdf_oursin.modules.php
@@ -166,6 +166,9 @@ class pdf_oursin extends ModelePDFFactures
 			if (file_exists($dir))
 			{
                 $pdf=pdf_getInstance($this->format);
+                $heightforinfotot = 80;	// Height reserved to output the info and total part (value include bottom margin)
+                $heightforfooter = 25;	// Height reserved to output the footer (value include bottom margin)
+                $pdf->SetAutoPageBreak(1,0);
 
                 if (class_exists('TCPDF'))
                 {
@@ -191,8 +194,16 @@ class pdf_oursin extends ModelePDFFactures
 				$pdf->SetKeyWords($outputlangs->convToOutputCharset($object->ref)." ".$outputlangs->transnoentities("Invoice"));
 				if ($conf->global->MAIN_DISABLE_PDF_COMPRESSION) $pdf->SetCompression(false);
 
-				$pdf->SetMargins(10, 10, 10);
-				$pdf->SetAutoPageBreak(1,0);
+				$pdf->SetMargins($this->marge_gauche, $this->marge_haute, $this->marge_droite);   // Left, Top, Right
+
+				// Positionne $this->atleastonediscount si on a au moins une remise
+				for ($i = 0 ; $i < $nblignes ; $i++)
+				{
+					if ($object->lines[$i]->remise_percent)
+					{
+						$this->atleastonediscount++;
+					}
+				}
 
 				// New page
 				$pdf->AddPage();
@@ -204,7 +215,9 @@ class pdf_oursin extends ModelePDFFactures
 				$pdf->SetTextColor(0,0,0);
 
 				$tab_top = $this->marges['h']+90;
+				$tab_top_newpage = $this->marges['h'];
 				$tab_height = 110;
+				$tab_height_newpage = 150;
 
 				$pdf->SetFillColor(220,220,220);
 				$pdf->SetFont('','', $default_font_size - 1);
@@ -220,20 +233,24 @@ class pdf_oursin extends ModelePDFFactures
 				{
 					$curY = $nexY;
 
+					$pdf->setPageOrientation('', 1, $this->marge_basse+$heightforfooter+$heightforinfotot);	// The only function to edit the bottom margin of current page to set it.
+					$pageposbefore=$pdf->getPage();
+
 					// Description of product line
                     pdf_writelinedesc($pdf,$object,$i,$outputlangs,108,3,$this->posxdesc-1,$curY+1,$hideref,$hidedesc,0,$hookmanager);
 
+					$pageposafter=$pdf->getPage();
+					$pdf->setPage($pageposbefore);
+					$pdf->setPageOrientation('', 1, 0);	// The only function to edit the bottom margin of current page to set it.
+
 					$nexY = $pdf->GetY();
 
 					// TVA
 					if (empty($conf->global->MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT))
 					{
-						if ($this->franchise!=1)
-						{
-							$vat_rate = pdf_getlinevatrate($object, $i, $outputlangs, $hidedetails, $hookmanager);
-							$pdf->SetXY($this->marges['g']+118, $curY);
-							$pdf->MultiCell(12, 3, $vat_rate, 0, 'R');
-						}
+						$vat_rate = pdf_getlinevatrate($object, $i, $outputlangs, $hidedetails, $hookmanager);
+						$pdf->SetXY($this->marges['g']+118, $curY);
+						$pdf->MultiCell(12, 3, $vat_rate, 0, 'R');
 					}
 
 					// Prix unitaire HT avant remise
@@ -258,25 +275,64 @@ class pdf_oursin extends ModelePDFFactures
 					$pdf->SetXY($this->marges['g']+168, $curY);
 					$pdf->MultiCell(21, 3, $total_excl_tax, 0, 'R', 0);
 
-
-					if (($nexY > 200 && $i < $nblignes - 1) || (isset($object->lines[$i+1]->pagebreak) && $object->lines[$i+1]->pagebreak))
-					{
-						$this->_tableau($pdf, $tab_top, $tab_height, $nexY, $object, $outputlangs);
-						$nexY = $iniY;
-
-						// New page
-						$pdf->AddPage();
-				        if (! empty($tplidx)) $pdf->useTemplate($tplidx);
-						$pagenb++;
-						$this->_pagehead($pdf, $object, 0, $outputlangs, $hookmanager);
-						$pdf->SetFont('','', $default_font_size - 1);
-						$pdf->MultiCell(0, 3, '');		// Set interline to 3
-						$pdf->SetTextColor(0,0,0);
+					// Detect if some page were added automatically and output _tableau for past pages
+					while ($pagenb < $pageposafter)
+					{
+						if ($pagenb == 1)
+						{
+							$this->_tableau($pdf, $tab_top, $tab_height + 40, 0, $outputlangs, 0, 1);
+						}
+						else
+						{
+							$this->_tableau($pdf, $tab_top_newpage, $tab_height_newpage, 0, $outputlangs, 1, 1);
+						}
+						$this->_pagefoot($pdf,$object,$outputlangs);
+						$pagenb++;
+						$pdf->setPage($pagenb);
 					}
+					/*if (isset($object->lines[$i+1]->pagebreak) && $object->lines[$i+1]->pagebreak)
+					{
+						if ($pagenb == 1)
+						{
+							$this->_tableau($pdf, $tab_top, $tab_height + 40, 0, $outputlangs, 0, 1);
+						}
+						else
+						{
+							$this->_tableau($pdf, $tab_top_newpage, $tab_height_newpage, 0, $outputlangs, 1, 1);
+						}
+						$this->_pagefoot($pdf,$object,$outputlangs);
+						// New page
+						$pdf->AddPage();
+						if (! empty($tplidx)) $pdf->useTemplate($tplidx);
+						$pagenb++;
+					}*/
+					if (($nexY > 200 && $i < $nblignes - 1) || (isset($object->lines[$i+1]->pagebreak) && $object->lines[$i+1]->pagebreak))
+					{
+						$this->_tableau($pdf, $tab_top, $tab_height, $nexY, $object, $outputlangs);
+						$nexY = $iniY;
+
+						// New page
+						$pdf->AddPage();
+						if (! empty($tplidx)) $pdf->useTemplate($tplidx);
+						$pagenb++;
+						$this->_pagehead($pdf, $object, 0, $outputlangs, $hookmanager);
+						$pdf->SetFont('','', $default_font_size - 1);
+						$pdf->MultiCell(0, 3, '');		// Set interline to 3
+						$pdf->SetTextColor(0,0,0);
+					}
+				}
 
+				// Show square
+				if ($pagenb == 1)
+				{
+					$this->_tableau($pdf, $tab_top, $tab_height, $nexY, $outputlangs);
+					$bottomlasttab=$tab_top + $tab_height + 1;
+				}
+				else
+				{
+					$this->_tableau($pdf, $tab_top, $tab_height, $nexY, $outputlangs, 1, 0);
+					$bottomlasttab=$tab_top + $tab_height + 1;
 				}
-				$posy=$this->_tableau($pdf, $tab_top, $tab_height, $nexY, $object, $outputlangs);
-				$bottomlasttab=$tab_top + $tab_height + 1;
 
 				// Affiche zone infos
 				$posy=$this->_tableau_info($pdf, $object, $bottomlasttab, $outputlangs);
@@ -744,11 +800,12 @@ class pdf_oursin extends ModelePDFFactures
 	 *   @param		string		$tab_top		Top position of table
 	 *   @param		string		$tab_height		Height of table (rectangle)
 	 *   @param		int			$nexY			Y
-	 *   @param		Object		$object			Object
 	 *   @param		Translate	$outputlangs	Langs object
+	 *   @param		int			$hidetop		Hide top bar of array
+	 *   @param		int			$hidebottom		Hide bottom bar of array
 	 *   @return	void
 	 */
-	function _tableau(&$pdf, $tab_top, $tab_height, $nexY, $object, $outputlangs)
+	function _tableau(&$pdf, $tab_top, $tab_height, $nexY, $outputlangs, $hidetop=0, $hidebottom=0)
 	{
 		global $conf,$langs;
 		$langs->load("main");
@@ -775,16 +832,7 @@ class pdf_oursin extends ModelePDFFactures
         $pdf->SetXY($this->marges['g']+153,$tab_top + 1);
         $pdf->MultiCell(0, 4, $outputlangs->transnoentities("Qty"), 0, 'L');
 
-		$nblignes = count($object->lines);
-		$rem=0;
-		for ($i = 0 ; $i < $nblignes ; $i++)
-		{
-    		if ($object->lines[$i]->remise_percent)
-    		{
-    			$rem=1;
-    		}
-		}
-		if ($rem==1)
+		if ($this->atleastonediscount)
 		{
             $pdf->SetXY($this->marges['g']+165,$tab_top + 1);
             $pdf->MultiCell(0, 4, $outputlangs->transnoentities("%"), 0, 'L');
@@ -1018,7 +1066,7 @@ class pdf_oursin extends ModelePDFFactures
 	 *   	@param	PDF			&$pdf     			PDF
 	 * 		@param	Object		$object				Object to show
 	 *      @param	Translate	$outputlangs		Object lang for output
-	 *      @return	void
+	 *      @return	int								Return height of bottom margin including footer text
 	 */
 	function _pagefoot(&$pdf, $object, $outputlangs)
 	{
diff --git a/htdocs/core/modules/fichinter/doc/pdf_soleil.modules.php b/htdocs/core/modules/fichinter/doc/pdf_soleil.modules.php
index 91f4b18c172..eee3a6ebf9d 100644
--- a/htdocs/core/modules/fichinter/doc/pdf_soleil.modules.php
+++ b/htdocs/core/modules/fichinter/doc/pdf_soleil.modules.php
@@ -134,6 +134,9 @@ class pdf_soleil extends ModelePDFFicheinter
 			if (file_exists($dir))
 			{
                 $pdf=pdf_getInstance($this->format);
+                $heightforinfotot = 80;	// Height reserved to output the info and total part (value include bottom margin)
+                $heightforfooter = 25;	// Height reserved to output the footer (value include bottom margin)
+                $pdf->SetAutoPageBreak(1,0);
 
                 if (class_exists('TCPDF'))
                 {
@@ -160,7 +163,6 @@ class pdf_soleil extends ModelePDFFicheinter
 				if ($conf->global->MAIN_DISABLE_PDF_COMPRESSION) $pdf->SetCompression(false);
 
 				$pdf->SetMargins($this->marge_gauche, $this->marge_haute, $this->marge_droite);   // Left, Top, Right
-				$pdf->SetAutoPageBreak(1,0);
 
 				// New page
 				$pdf->AddPage();
@@ -268,67 +270,51 @@ class pdf_soleil extends ModelePDFFicheinter
 
 						$nexY+=2;    // Passe espace entre les lignes
 
-						// Cherche nombre de lignes a venir pour savoir si place suffisante
-						if ($i < ($nblines - 1) && empty($hidedesc))	// If it's not last line
-						{
-							//on recupere la description du produit suivant
-							$follow_descproduitservice = $objectligne->desc;
-							//on compte le nombre de ligne afin de verifier la place disponible (largeur de ligne 52 caracteres)
-							$nblineFollowDesc = (dol_nboflines_bis($follow_descproduitservice,52,$outputlangs->charset_output)*3);
-						}
-						else	// If it's last line
-						{
-							$nblineFollowDesc = 0;
-						}
-
-						// Test if a new page is required
-						if ($pagenb == 1)
-						{
-							$tab_top_in_current_page=$tab_top;
-							$tab_height_in_current_page=$tab_height;
-						}
-						else
-						{
-							$tab_top_in_current_page=$tab_top_newpage;
-							$tab_height_in_current_page=$tab_height_middlepage;
-						}
-						if (($nexY+$nblineFollowDesc) > ($tab_top_in_current_page+$tab_height_in_current_page) && $i < ($nblines - 1))
-						{
-							if ($pagenb == 1)
-							{
-								$this->_tableau($pdf, $tab_top, $tab_height + 20, $nexY, $outputlangs);
-							}
-							else
-							{
-								$this->_tableau($pdf, $tab_top_newpage, $tab_height_middlepage, $nexY, $outputlangs);
-							}
-
-							$this->_pagefoot($pdf,$object,$outputlangs);
-
-							// New page
-							$pdf->AddPage();
-				            if (! empty($tplidx)) $pdf->useTemplate($tplidx);
-							$pagenb++;
-							$this->_pagehead($pdf, $object, 0, $outputlangs);
-							$pdf->SetFont('','', $default_font_size - 1);
-							$pdf->MultiCell(0, 3, '');		// Set interline to 3
-							$pdf->SetTextColor(0,0,0);
-
-							$nexY = $tab_top_newpage + 7;
-						}
+						// Detect if some page were added automatically and output _tableau for past pages
+						while ($pagenb < $pageposafter)
+						{
+							if ($pagenb == 1)
+							{
+								$this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforfooter, 0, $outputlangs, 0, 1);
+							}
+							else
+							{
+								$this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforfooter, 0, $outputlangs, 1, 1);
+							}
+							$this->_pagefoot($pdf,$object,$outputlangs);
+							$pagenb++;
+							$pdf->setPage($pagenb);
+							$pdf->setPageOrientation('', 1, 0);	// The only function to edit the bottom margin of current page to set it.
+						}
+						if (isset($object->lines[$i+1]->pagebreak) && $object->lines[$i+1]->pagebreak)
+						{
+							if ($pagenb == 1)
+							{
+								$this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforfooter, 0, $outputlangs, 0, 1);
+							}
+							else
+							{
+								$this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforfooter, 0, $outputlangs, 1, 1);
+							}
+							$this->_pagefoot($pdf,$object,$outputlangs);
+							// New page
+							$pdf->AddPage();
+							if (! empty($tplidx)) $pdf->useTemplate($tplidx);
+							$pagenb++;
+						}
 					}
 				}
 
 				// Show square
 				if ($pagenb == 1)
 				{
-					$this->_tableau($pdf, $tab_top, $tab_height, $nexY, $outputlangs);
-					$bottomlasttab=$tab_top + $tab_height + 1;
+					$this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforinfotot, 0, $outputlangs, 0, 0);
+					$bottomlasttab=$this->page_hauteur - $heightforinfotot + 1;
 				}
 				else
 				{
-					$this->_tableau($pdf, $tab_top_newpage, $tab_height_newpage, $nexY, $outputlangs);
-					$bottomlasttab=$tab_top_newpage + $tab_height_newpage + 1;
+					$this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforinfotot, 0, $outputlangs, 1, 0);
+					$bottomlasttab=$this->page_hauteur - $heightforinfotot + 1;
 				}
 
 				$pdf->SetFont('','', $default_font_size - 1);   // On repositionne la police par defaut
@@ -367,9 +353,11 @@ class pdf_soleil extends ModelePDFFicheinter
 	 *   @param		string		$tab_height		Height of table (rectangle)
 	 *   @param		int			$nexY			Y
 	 *   @param		Translate	$outputlangs	Langs object
+	 *   @param		int			$hidetop		Hide top bar of array
+	 *   @param		int			$hidebottom		Hide bottom bar of array
 	 *   @return	void
 	 */
-	function _tableau(&$pdf, $tab_top, $tab_height, $nexY, $outputlangs)
+	function _tableau(&$pdf, $tab_top, $tab_height, $nexY, $outputlangs, $hidetop=0, $hidebottom=0)
 	{
 		global $conf;
 		$default_font_size = pdf_getPDFFontSize($outputlangs);
@@ -406,13 +394,13 @@ class pdf_soleil extends ModelePDFFicheinter
 		$pdf->MultiCell(66,5, $outputlangs->transnoentities("NameAndSignatureOfInternalContact"),0,'L',0);
 
 		$pdf->SetXY(20,235);
-		$pdf->MultiCell(80,30, '', 1);
+		$pdf->MultiCell(80,25, '', 1);
 
 		$pdf->SetXY(110,230);
 		$pdf->MultiCell(80,5, $outputlangs->transnoentities("NameAndSignatureOfExternalContact"),0,'L',0);
 
 		$pdf->SetXY(110,235);
-		$pdf->MultiCell(80,30, '', 1);
+		$pdf->MultiCell(80,25, '', 1);
 	}
 
 	/**
diff --git a/htdocs/core/modules/livraison/pdf/pdf_sirocco.modules.php b/htdocs/core/modules/livraison/pdf/pdf_sirocco.modules.php
index d32f1370ef0..5ae3b4133e0 100644
--- a/htdocs/core/modules/livraison/pdf/pdf_sirocco.modules.php
+++ b/htdocs/core/modules/livraison/pdf/pdf_sirocco.modules.php
@@ -120,6 +120,9 @@ class pdf_sirocco extends ModelePDFDeliveryOrder
 			if (file_exists($dir))
 			{
                 $pdf=pdf_getInstance($this->format);
+                $heightforinfotot = 80;	// Height reserved to output the info and total part (value include bottom margin)
+                $heightforfooter = 25;	// Height reserved to output the footer (value include bottom margin)
+                $pdf->SetAutoPageBreak(1,0);
 
                 if (class_exists('TCPDF'))
                 {
@@ -158,7 +161,6 @@ class pdf_sirocco extends ModelePDFDeliveryOrder
 				if ($conf->global->MAIN_DISABLE_PDF_COMPRESSION) $pdf->SetCompression(false);
 
 				$pdf->SetMargins($this->marge_gauche, $this->marge_haute, $this->marge_droite);   // Left, Top, Right
-				$pdf->SetAutoPageBreak(1,0);
 
 				// New page
 				$pdf->AddPage();
@@ -184,10 +186,15 @@ class pdf_sirocco extends ModelePDFDeliveryOrder
 
 					$pdf->SetFont('','', $default_font_size - 1);   // Dans boucle pour gerer multi-page
 
-                    // Description de la ligne produit
-					//$libelleproduitservice=pdf_getlinedesc($object,$i,$outputlangs);
+					$pdf->setPageOrientation('', 1, $this->marge_basse+$heightforfooter+$heightforinfotot);	// The only function to edit the bottom margin of current page to set it.
+					$pageposbefore=$pdf->getPage();
+
+					// Description de la ligne produit
 					pdf_writelinedesc($pdf,$object,$i,$outputlangs,100,3,30,$curY,1);
-					//$pdf->writeHTMLCell(100, 3, 30, $curY, $outputlangs->convToOutputCharset($libelleproduitservice), 0, 1);
+
+					$pageposafter=$pdf->getPage();
+					$pdf->setPage($pageposbefore);
+					$pdf->setPageOrientation('', 1, 0);	// The only function to edit the bottom margin of current page to set it.
 
 					$pdf->SetFont('','', $default_font_size - 1);   // Dans boucle pour gerer multi-page
 					$nexY = $pdf->GetY();
@@ -217,66 +224,50 @@ class pdf_sirocco extends ModelePDFDeliveryOrder
 
 					$nexY+=2;    // Passe espace entre les lignes
 
-					// Cherche nombre de lignes a venir pour savoir si place suffisante
-					if ($i < ($nblines - 1) && empty($hidedesc))	// If it's not last line
-					{
-						//on recupere la description du produit suivant
-						$follow_descproduitservice = $object->lines[$i+1]->desc;
-						//on compte le nombre de ligne afin de verifier la place disponible (largeur de ligne 52 caracteres)
-						$nblineFollowDesc = (dol_nboflines_bis($follow_descproduitservice,52,$outputlangs->charset_output)*4);
-					}
-					else	// If it's last line
-					{
-						$nblineFollowDesc = 0;
-					}
-
-					// Test if a new page is required
-					if ($pagenb == 1)
+					// Detect if some page were added automatically and output _tableau for past pages
+					while ($pagenb < $pageposafter)
 					{
-						$tab_top_in_current_page=$tab_top;
-						$tab_height_in_current_page=$tab_height;
-					}
-					else
-					{
-						$tab_top_in_current_page=$tab_top_newpage;
-						$tab_height_in_current_page=$tab_height_newpage;
+						if ($pagenb == 1)
+						{
+							$this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforfooter, 0, $outputlangs, 0, 1);
+						}
+						else
+						{
+							$this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforfooter, 0, $outputlangs, 1, 1);
+						}
+						$this->_pagefoot($pdf,$object,$outputlangs);
+						$pagenb++;
+						$pdf->setPage($pagenb);
+						$pdf->setPageOrientation('', 1, 0);	// The only function to edit the bottom margin of current page to set it.
 					}
-
-					if (($nexY+$nblineFollowDesc) > ($tab_top_in_current_page+$tab_height_in_current_page) && $i < ($nblines - 1))
+					if (isset($object->lines[$i+1]->pagebreak) && $object->lines[$i+1]->pagebreak)
 					{
 						if ($pagenb == 1)
 						{
-							$this->_tableau($pdf, $tab_top, $tab_height + 20, $nexY, $outputlangs);
+							$this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforfooter, 0, $outputlangs, 0, 1);
 						}
 						else
 						{
-							$this->_tableau($pdf, $tab_top_newpage, $tab_height_newpage, $nexY, $outputlangs);
+							$this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforfooter, 0, $outputlangs, 1, 1);
 						}
-
-						$this->_pagefoot($pdf, $object, $outputlangs);
-
+						$this->_pagefoot($pdf,$object,$outputlangs);
 						// New page
 						$pdf->AddPage();
+						if (! empty($tplidx)) $pdf->useTemplate($tplidx);
 						$pagenb++;
-						$this->_pagehead($pdf, $object, 0, $outputlangs);
-						$pdf->SetFont('','', $default_font_size - 1);
-						$pdf->MultiCell(0, 3, '');		// Set interline to 3
-						$pdf->SetTextColor(0,0,0);
-
-						$nexY = $tab_top_newpage + 7;
 					}
 				}
 
 				// Show square
 				if ($pagenb == 1)
 				{
-					$this->_tableau($pdf, $tab_top, $tab_height, $nexY, $outputlangs);
-					$bottomlasttab=$tab_top + $tab_height + 1;
+					$this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforinfotot, 0, $outputlangs, 0, 0);
+					$bottomlasttab=$this->page_hauteur - $heightforinfotot + 1;
 				}
 				else
 				{
-					$this->_tableau($pdf, $tab_top_newpage, $tab_height_newpage, $nexY, $outputlangs);
-					$bottomlasttab=$tab_top_newpage + $tab_height_newpage + 1;
+					$this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforinfotot, 0, $outputlangs, 1, 0);
+					$bottomlasttab=$this->page_hauteur - $heightforinfotot + 1;
 				}
 
 				/*
@@ -309,9 +300,11 @@ class pdf_sirocco extends ModelePDFDeliveryOrder
 	 *   @param		string		$tab_height		Height of table (rectangle)
 	 *   @param		int			$nexY			Y
 	 *   @param		Translate	$outputlangs	Langs object
+	 *   @param		int			$hidetop		Hide top bar of array
+	 *   @param		int			$hidebottom		Hide bottom bar of array
 	 *   @return	void
 	 */
-	function _tableau(&$pdf, $tab_top, $tab_height, $nexY, $outputlangs)
+	function _tableau(&$pdf, $tab_top, $tab_height, $nexY, $outputlangs, $hidetop=0, $hidebottom=0)
 	{
 		$default_font_size = pdf_getPDFFontSize($outputlangs);
 		$pdf->SetFont('','', $default_font_size - 1);
diff --git a/htdocs/core/modules/livraison/pdf/pdf_typhon.modules.php b/htdocs/core/modules/livraison/pdf/pdf_typhon.modules.php
index 05da0f4bed4..098a59323da 100644
--- a/htdocs/core/modules/livraison/pdf/pdf_typhon.modules.php
+++ b/htdocs/core/modules/livraison/pdf/pdf_typhon.modules.php
@@ -142,6 +142,9 @@ class pdf_typhon extends ModelePDFDeliveryOrder
 			if (file_exists($dir))
 			{
                 $pdf=pdf_getInstance($this->format);
+                $heightforinfotot = 80;	// Height reserved to output the info and total part (value include bottom margin)
+                $heightforfooter = 25;	// Height reserved to output the footer (value include bottom margin)
+                $pdf->SetAutoPageBreak(1,0);
 
                 if (class_exists('TCPDF'))
                 {
@@ -180,7 +183,6 @@ class pdf_typhon extends ModelePDFDeliveryOrder
 				if ($conf->global->MAIN_DISABLE_PDF_COMPRESSION) $pdf->SetCompression(false);
 
 				$pdf->SetMargins($this->marge_gauche, $this->marge_haute, $this->marge_droite);   // Left, Top, Right
-				$pdf->SetAutoPageBreak(1,0);
 
 				/*
 				 // Positionne $this->atleastonediscount si on a au moins une remise
@@ -240,10 +242,15 @@ class pdf_typhon extends ModelePDFDeliveryOrder
 
                     $pdf->SetFont('','', $default_font_size - 1);   // Dans boucle pour gerer multi-page
 
-                    // Description de la ligne produit
-					//$libelleproduitservice=pdf_getlinedesc($object,$i,$outputlangs);
+					$pdf->setPageOrientation('', 1, $this->marge_basse+$heightforfooter+$heightforinfotot);	// The only function to edit the bottom margin of current page to set it.
+					$pageposbefore=$pdf->getPage();
+
+					// Description de la ligne produit
 					pdf_writelinedesc($pdf,$object,$i,$outputlangs,108,3,$this->posxdesc-1,$curY);
-					//$pdf->writeHTMLCell(108, 3, $this->posxdesc-1, $curY, $outputlangs->convToOutputCharset($libelleproduitservice), 0, 1);
+
+					$pageposafter=$pdf->getPage();
+					$pdf->setPage($pageposbefore);
+					$pdf->setPageOrientation('', 1, 0);	// The only function to edit the bottom margin of current page to set it.
 
 					$pdf->SetFont('','', $default_font_size - 1);   // On repositionne la police par defaut
 					$nexY = $pdf->GetY();
@@ -281,68 +288,52 @@ class pdf_typhon extends ModelePDFDeliveryOrder
 					 */
 					$nexY+=2;    // Passe espace entre les lignes
 
-					// Cherche nombre de lignes a venir pour savoir si place suffisante
-					if ($i < ($nblines - 1) && empty($hidedesc))	// If it's not last line
-					{
-						//on recupere la description du produit suivant
-						$follow_descproduitservice = $object->lines[$i+1]->desc;
-						//on compte le nombre de ligne afin de verifier la place disponible (largeur de ligne 52 caracteres)
-						$nblineFollowDesc = (dol_nboflines_bis($follow_descproduitservice,52,$outputlangs->charset_output)*4);
-					}
-					else	// If it's last line
-					{
-						$nblineFollowDesc = 0;
-					}
-
-					// Test if a new page is required
-					if ($pagenb == 1)
-					{
-						$tab_top_in_current_page=$tab_top;
-						$tab_height_in_current_page=$tab_height;
-					}
-					else
-					{
-						$tab_top_in_current_page=$tab_top_newpage;
-						$tab_height_in_current_page=$tab_height_newpage;
-					}
-					if (($nexY+$nblineFollowDesc) > ($tab_top_in_current_page+$tab_height_in_current_page) && $i < ($nblines - 1))
-					{
-						if ($pagenb == 1)
-						{
-							$this->_tableau($pdf, $tab_top, $tab_height + 20, $nexY, $outputlangs);
-						}
-						else
-						{
-							$this->_tableau($pdf, $tab_top_newpage, $tab_height_newpage, $nexY, $outputlangs);
-						}
-
-						$this->_pagefoot($pdf, $object, $outputlangs);
-
-						// New page
-						$pdf->AddPage();
-						$pagenb++;
-						$this->_pagehead($pdf, $object, 0, $outputlangs);
-						$pdf->SetFont('','', $default_font_size - 1);
-						$pdf->MultiCell(0, 3, '');		// Set interline to 3
-						$pdf->SetTextColor(0,0,0);
-
-						$nexY = $tab_top_newpage + 7;
-					}
+					// Detect if some page were added automatically and output _tableau for past pages
+					while ($pagenb < $pageposafter)
+					{
+						if ($pagenb == 1)
+						{
+							$this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforfooter, 0, $outputlangs, 0, 1);
+						}
+						else
+						{
+							$this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforfooter, 0, $outputlangs, 1, 1);
+						}
+						$this->_pagefoot($pdf,$object,$outputlangs);
+						$pagenb++;
+						$pdf->setPage($pagenb);
+						$pdf->setPageOrientation('', 1, 0);	// The only function to edit the bottom margin of current page to set it.
+					}
+					if (isset($object->lines[$i+1]->pagebreak) && $object->lines[$i+1]->pagebreak)
+					{
+						if ($pagenb == 1)
+						{
+							$this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforfooter, 0, $outputlangs, 0, 1);
+						}
+						else
+						{
+							$this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforfooter, 0, $outputlangs, 1, 1);
+						}
+						$this->_pagefoot($pdf,$object,$outputlangs);
+						// New page
+						$pdf->AddPage();
+						if (! empty($tplidx)) $pdf->useTemplate($tplidx);
+						$pagenb++;
+					}
 				}
 
 				// Show square
 				if ($pagenb == 1)
 				{
-					$this->_tableau($pdf, $tab_top, $tab_height, $nexY, $outputlangs);
-					$bottomlasttab=$tab_top + $tab_height + 1;
+					$this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforinfotot, 0, $outputlangs, 0, 0);
+					$bottomlasttab=$this->page_hauteur - $heightforinfotot + 1;
 				}
 				else
 				{
-					$this->_tableau($pdf, $tab_top_newpage, $tab_height_newpage, $nexY, $outputlangs);
-					$bottomlasttab=$tab_top_newpage + $tab_height_newpage + 1;
+					$this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforinfotot, 0, $outputlangs, 1, 0);
+					$bottomlasttab=$this->page_hauteur - $heightforinfotot + 1;
 				}
 
-
 				/*
 				 * Pied de page
 				 */
@@ -437,9 +428,11 @@ class pdf_typhon extends ModelePDFDeliveryOrder
 	 *   @param		string		$tab_height		Height of table (rectangle)
 	 *   @param		int			$nexY			Y
 	 *   @param		Translate	$outputlangs	Langs object
+	 *   @param		int			$hidetop		Hide top bar of array
+	 *   @param		int			$hidebottom		Hide bottom bar of array
 	 *   @return	void
 	 */
-	function _tableau(&$pdf, $tab_top, $tab_height, $nexY, $outputlangs)
+	function _tableau(&$pdf, $tab_top, $tab_height, $nexY, $outputlangs, $hidetop=0, $hidebottom=0)
 	{
 		global $conf,$mysoc;
 		$default_font_size = pdf_getPDFFontSize($outputlangs);
diff --git a/htdocs/core/modules/project/pdf/pdf_baleine.modules.php b/htdocs/core/modules/project/pdf/pdf_baleine.modules.php
index b34d3b9a6fc..8f6fe597449 100644
--- a/htdocs/core/modules/project/pdf/pdf_baleine.modules.php
+++ b/htdocs/core/modules/project/pdf/pdf_baleine.modules.php
@@ -127,6 +127,9 @@ class pdf_baleine extends ModelePDFProjects
 			if (file_exists($dir))
 			{
                 $pdf=pdf_getInstance($this->format);
+                $heightforinfotot = 80;	// Height reserved to output the info and total part (value include bottom margin)
+                $heightforfooter = 25;	// Height reserved to output the footer (value include bottom margin)
+                $pdf->SetAutoPageBreak(1,0);
 
                 if (class_exists('TCPDF'))
                 {
@@ -154,7 +157,6 @@ class pdf_baleine extends ModelePDFProjects
 				if ($conf->global->MAIN_DISABLE_PDF_COMPRESSION) $pdf->SetCompression(false);
 
 				$pdf->SetMargins($this->marge_gauche, $this->marge_haute, $this->marge_droite);   // Left, Top, Right
-				$pdf->SetAutoPageBreak(1,0);
 
 				// New page
 				$pdf->AddPage();
@@ -225,43 +227,51 @@ class pdf_baleine extends ModelePDFProjects
 
 					$nexY+=2;    // Passe espace entre les lignes
 
-					// Cherche nombre de lignes a venir pour savoir si place suffisante
-					if ($i < ($nblignes - 1) && empty($hidedesc))	// If it's not last line
-					{
-						//on recupere la description du produit suivant
-						$follow_descproduitservice = $object->lines[$i+1]->desc;
-						//on compte le nombre de ligne afin de verifier la place disponible (largeur de ligne 52 caracteres)
-						$nblineFollowDesc = (dol_nboflines_bis($follow_descproduitservice,52,$outputlangs->charset_output)*4);
-					}
-					else	// If it's last line
-					{
-						$nblineFollowDesc = 0;
-					}
-
-					if (($nexY+$nblineFollowDesc) > ($tab_top+$tab_height) && $i < ($nblignes - 1))
-					{
-						$this->_tableau($pdf, $tab_top, $tab_height + 20, $nexY, $outputlangs);
-
-						$this->_pagefoot($pdf, $object, $outputlangs);
-
-						// New page
-						$pdf->AddPage();
-						$pagenb++;
-						$this->_pagehead($pdf, $object, 0, $outputlangs);
-						$pdf->SetFont('','', $default_font_size - 1);
-						$pdf->MultiCell(0, 3, '');		// Set interline to 3
-						$pdf->SetTextColor(0,0,0);
-
-						$tab_top=$tab_top_newpage;
-						$tab_height=$tab_height_newpage;
-
-						$nexY = $tab_top + 7;
-					}
+					// Detect if some page were added automatically and output _tableau for past pages
+					while ($pagenb < $pageposafter)
+					{
+						if ($pagenb == 1)
+						{
+							$this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforfooter, 0, $outputlangs, 0, 1);
+						}
+						else
+						{
+							$this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforfooter, 0, $outputlangs, 1, 1);
+						}
+						$this->_pagefoot($pdf,$object,$outputlangs);
+						$pagenb++;
+						$pdf->setPage($pagenb);
+						$pdf->setPageOrientation('', 1, 0);	// The only function to edit the bottom margin of current page to set it.
+					}
+					if (isset($object->lines[$i+1]->pagebreak) && $object->lines[$i+1]->pagebreak)
+					{
+						if ($pagenb == 1)
+						{
+							$this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforfooter, 0, $outputlangs, 0, 1);
+						}
+						else
+						{
+							$this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforfooter, 0, $outputlangs, 1, 1);
+						}
+						$this->_pagefoot($pdf,$object,$outputlangs);
+						// New page
+						$pdf->AddPage();
+						if (! empty($tplidx)) $pdf->useTemplate($tplidx);
+						$pagenb++;
+					}
 				}
 
 				// Show square
-				$this->_tableau($pdf, $tab_top, $tab_height, $nexY, $outputlangs);
-				$bottomlasttab=$tab_top + $tab_height + 1;
+				if ($pagenb == 1)
+				{
+					$this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforinfotot, 0, $outputlangs, 0, 0);
+					$bottomlasttab=$this->page_hauteur - $heightforinfotot + 1;
+				}
+				else
+				{
+					$this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforinfotot, 0, $outputlangs, 1, 0);
+					$bottomlasttab=$this->page_hauteur - $heightforinfotot + 1;
+				}
 
 				/*
 				 * Pied de page
@@ -297,9 +307,11 @@ class pdf_baleine extends ModelePDFProjects
 	 *   @param		string		$tab_height		Height of table (rectangle)
 	 *   @param		int			$nexY			Y
 	 *   @param		Translate	$outputlangs	Langs object
+	 *   @param		int			$hidetop		Hide top bar of array
+	 *   @param		int			$hidebottom		Hide bottom bar of array
 	 *   @return	void
 	 */
-	function _tableau(&$pdf, $tab_top, $tab_height, $nexY, $outputlangs)
+	function _tableau(&$pdf, $tab_top, $tab_height, $nexY, $outputlangs, $hidetop=0, $hidebottom=0)
 	{
 		global $conf,$mysoc;
 
diff --git a/htdocs/core/modules/propale/doc/pdf_azur.modules.php b/htdocs/core/modules/propale/doc/pdf_azur.modules.php
index dd55cf728f9..a9d6e5d1fdb 100644
--- a/htdocs/core/modules/propale/doc/pdf_azur.modules.php
+++ b/htdocs/core/modules/propale/doc/pdf_azur.modules.php
@@ -163,6 +163,9 @@ class pdf_azur extends ModelePDFPropales
 
 				// Create pdf instance
                 $pdf=pdf_getInstance($this->format);
+                $heightforinfotot = 80;	// Height reserved to output the info and total part (value include bottom margin)
+                $heightforfooter = 25;	// Height reserved to output the footer (value include bottom margin)
+                $pdf->SetAutoPageBreak(1,0);
 
                 if (class_exists('TCPDF'))
                 {
@@ -189,7 +192,6 @@ class pdf_azur extends ModelePDFPropales
 				if ($conf->global->MAIN_DISABLE_PDF_COMPRESSION) $pdf->SetCompression(false);
 
 				$pdf->SetMargins($this->marge_gauche, $this->marge_haute, $this->marge_droite);   // Left, Top, Right
-				$pdf->SetAutoPageBreak(1,0);
 
 				// Positionne $this->atleastonediscount si on a au moins une remise
 				for ($i = 0 ; $i < $nblignes ; $i++)
@@ -249,10 +251,17 @@ class pdf_azur extends ModelePDFPropales
 
 					$pdf->SetFont('','', $default_font_size - 1);   // Dans boucle pour gerer multi-page
 
+					$pdf->setPageOrientation('', 1, $this->marge_basse+$heightforfooter+$heightforinfotot);	// The only function to edit the bottom margin of current page to set it.
+					$pageposbefore=$pdf->getPage();
+
 					// Description de la ligne produit
 					$curX = $this->posxdesc-1;
 					pdf_writelinedesc($pdf,$object,$i,$outputlangs,$this->posxtva-$curX,4,$curX,$curY,$hideref,$hidedesc,0,$hookmanager);
 
+					$pageposafter=$pdf->getPage();
+					$pdf->setPage($pageposbefore);
+					$pdf->setPageOrientation('', 1, 0);	// The only function to edit the bottom margin of current page to set it.
+
 					$pdf->SetFont('','', $default_font_size - 1);   // On repositionne la police par defaut
 					$nexY = $pdf->GetY();
 
@@ -308,67 +317,50 @@ class pdf_azur extends ModelePDFPropales
 
 					$nexY+=2;    // Passe espace entre les lignes
 
-					// Cherche nombre de lignes a venir pour savoir si place suffisante
-					if ($i < ($nblignes - 1) && empty($hidedesc))	// If it's not last line
-					{
-						//on recupere la description du produit suivant
-						$follow_descproduitservice = $object->lines[$i+1]->desc;
-						//on compte le nombre de ligne afin de verifier la place disponible (largeur de ligne 52 caracteres)
-						$nblineFollowDesc = (dol_nboflines_bis($follow_descproduitservice,52,$outputlangs->charset_output)*4);
-					}
-					else	// If it's last line
-					{
-						$nblineFollowDesc = 0;
-					}
-
-					// Test if a new page is required
-					if ($pagenb == 1)
-					{
-						$tab_top_in_current_page=$tab_top;
-						$tab_height_in_current_page=$tab_height;
-					}
-					else
-					{
-						$tab_top_in_current_page=$tab_top_newpage;
-						$tab_height_in_current_page=$tab_height_middlepage;
-					}
-					if ((($nexY+$nblineFollowDesc) > ($tab_top_in_current_page+$tab_height_in_current_page) && $i < ($nblignes - 1)) || (isset($object->lines[$i+1]->pagebreak) && $object->lines[$i+1]->pagebreak))
-					{
-						if ($pagenb == 1)
-						{
-							$this->_tableau($pdf, $tab_top, $tab_height + 20, $nexY, $outputlangs);
-						}
-						else
-						{
-							$this->_tableau($pdf, $tab_top_newpage, $tab_height_middlepage, $nexY, $outputlangs);
-						}
-
-						$this->_pagefoot($pdf,$object,$outputlangs);
-
-						// New page
-						$pdf->AddPage();
-				        if (! empty($tplidx)) $pdf->useTemplate($tplidx);
-						$pagenb++;
-						$this->_pagehead($pdf, $object, 0, $outputlangs, $hookmanager);
-						$pdf->SetFont('','', $default_font_size - 1);
-						$pdf->MultiCell(0, 3, '');		// Set interline to 3
-						$pdf->SetTextColor(0,0,0);
-
-						$nexY = $tab_top_newpage + 7;
-					}
-
+					// Detect if some page were added automatically and output _tableau for past pages
+					while ($pagenb < $pageposafter)
+					{
+						if ($pagenb == 1)
+						{
+							$this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforfooter, 0, $outputlangs, 0, 1);
+						}
+						else
+						{
+							$this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforfooter, 0, $outputlangs, 1, 1);
+						}
+						$this->_pagefoot($pdf,$object,$outputlangs);
+						$pagenb++;
+						$pdf->setPage($pagenb);
+						$pdf->setPageOrientation('', 1, 0);	// The only function to edit the bottom margin of current page to set it.
+					}
+					if (isset($object->lines[$i+1]->pagebreak) && $object->lines[$i+1]->pagebreak)
+					{
+						if ($pagenb == 1)
+						{
+							$this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforfooter, 0, $outputlangs, 0, 1);
+						}
+						else
+						{
+							$this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforfooter, 0, $outputlangs, 1, 1);
+						}
+						$this->_pagefoot($pdf,$object,$outputlangs);
+						// New page
+						$pdf->AddPage();
+						if (! empty($tplidx)) $pdf->useTemplate($tplidx);
+						$pagenb++;
+					}
 				}
 
 				// Show square
 				if ($pagenb == 1)
 				{
-					$this->_tableau($pdf, $tab_top, $tab_height, $nexY, $outputlangs);
-					$bottomlasttab=$tab_top + $tab_height + 1;
+					$this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforinfotot, 0, $outputlangs, 0, 0);
+					$bottomlasttab=$this->page_hauteur - $heightforinfotot + 1;
 				}
 				else
 				{
-					$this->_tableau($pdf, $tab_top_newpage, $tab_height_endpage, $nexY, $outputlangs);
-					$bottomlasttab=$tab_top_newpage + $tab_height_endpage + 1;
+					$this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforinfotot, 0, $outputlangs, 1, 0);
+					$bottomlasttab=$this->page_hauteur - $heightforinfotot + 1;
 				}
 
 				// Affiche zone infos
@@ -828,9 +820,11 @@ class pdf_azur extends ModelePDFPropales
 	 *   @param		string		$tab_height		Height of table (rectangle)
 	 *   @param		int			$nexY			Y
 	 *   @param		Translate	$outputlangs	Langs object
+	 *   @param		int			$hidetop		Hide top bar of array
+	 *   @param		int			$hidebottom		Hide bottom bar of array
 	 *   @return	void
 	 */
-	function _tableau(&$pdf, $tab_top, $tab_height, $nexY, $outputlangs)
+	function _tableau(&$pdf, $tab_top, $tab_height, $nexY, $outputlangs, $hidetop=0, $hidebottom=0)
 	{
 		global $conf;
 		$default_font_size = pdf_getPDFFontSize($outputlangs);
diff --git a/htdocs/core/modules/propale/doc/pdf_jaune.modules.php b/htdocs/core/modules/propale/doc/pdf_jaune.modules.php
index 400da56bb75..1160bdbf3c8 100644
--- a/htdocs/core/modules/propale/doc/pdf_jaune.modules.php
+++ b/htdocs/core/modules/propale/doc/pdf_jaune.modules.php
@@ -163,6 +163,9 @@ class pdf_jaune extends ModelePDFPropales
 
 				// Create pdf instance
                 $pdf=pdf_getInstance($this->format);
+                $heightforinfotot = 80;	// Height reserved to output the info and total part (value include bottom margin)
+                $heightforfooter = 25;	// Height reserved to output the footer (value include bottom margin)
+                $pdf->SetAutoPageBreak(1,0);
 
                 if (class_exists('TCPDF'))
                 {
@@ -189,7 +192,6 @@ class pdf_jaune extends ModelePDFPropales
 				if ($conf->global->MAIN_DISABLE_PDF_COMPRESSION) $pdf->SetCompression(false);
 
 				$pdf->SetMargins($this->marge_gauche, $this->marge_haute, $this->marge_droite);   // Left, Top, Right
-				$pdf->SetAutoPageBreak(1,0);
 
 				// Positionne $this->atleastonediscount si on a au moins une remise
 				for ($i = 0 ; $i < $nblignes ; $i++)
@@ -249,10 +251,17 @@ class pdf_jaune extends ModelePDFPropales
 
 					$pdf->SetFont('','', $default_font_size - 1);   // Dans boucle pour gerer multi-page
 
+					$pdf->setPageOrientation('', 1, $this->marge_basse+$heightforfooter+$heightforinfotot);	// The only function to edit the bottom margin of current page to set it.
+					$pageposbefore=$pdf->getPage();
+
 					// Description de la ligne produit
 					$curX = $this->posxdesc-1;
 					pdf_writelinedesc($pdf,$object,$i,$outputlangs,$this->posxtva-$curX,4,$curX,$curY,$hideref,$hidedesc,0,$hookmanager);
 
+					$pageposafter=$pdf->getPage();
+					$pdf->setPage($pageposbefore);
+					$pdf->setPageOrientation('', 1, 0);	// The only function to edit the bottom margin of current page to set it.
+
 					$pdf->SetFont('','', $default_font_size - 1);   // On repositionne la police par defaut
 					$nexY = $pdf->GetY();
 
@@ -308,67 +317,50 @@ class pdf_jaune extends ModelePDFPropales
 
 					$nexY+=2;    // Passe espace entre les lignes
 
-					// Cherche nombre de lignes a venir pour savoir si place suffisante
-					if ($i < ($nblignes - 1) && empty($hidedesc))	// If it's not last line
-					{
-						//on recupere la description du produit suivant
-						$follow_descproduitservice = $object->lines[$i+1]->desc;
-						//on compte le nombre de ligne afin de verifier la place disponible (largeur de ligne 52 caracteres)
-						$nblineFollowDesc = (dol_nboflines_bis($follow_descproduitservice,52,$outputlangs->charset_output)*4);
-					}
-					else	// If it's last line
-					{
-						$nblineFollowDesc = 0;
-					}
-
-					// Test if a new page is required
-					if ($pagenb == 1)
-					{
-						$tab_top_in_current_page=$tab_top;
-						$tab_height_in_current_page=$tab_height;
-					}
-					else
-					{
-						$tab_top_in_current_page=$tab_top_newpage;
-						$tab_height_in_current_page=$tab_height_middlepage;
-					}
-					if ((($nexY+$nblineFollowDesc) > ($tab_top_in_current_page+$tab_height_in_current_page) && $i < ($nblignes - 1)) || (isset($object->lines[$i+1]->pagebreak) && $object->lines[$i+1]->pagebreak))
-					{
-						if ($pagenb == 1)
-						{
-							$this->_tableau($pdf, $tab_top, $tab_height + 20, $nexY, $outputlangs);
-						}
-						else
-						{
-							$this->_tableau($pdf, $tab_top_newpage, $tab_height_middlepage, $nexY, $outputlangs);
-						}
-
-						$this->_pagefoot($pdf,$object,$outputlangs);
-
-						// New page
-						$pdf->AddPage();
-				        if (! empty($tplidx)) $pdf->useTemplate($tplidx);
-						$pagenb++;
-						$this->_pagehead($pdf, $object, 0, $outputlangs);
-						$pdf->SetFont('','', $default_font_size - 1);
-						$pdf->MultiCell(0, 3, '');		// Set interline to 3
-						$pdf->SetTextColor(0,0,0);
-
-						$nexY = $tab_top_newpage + 7;
-					}
-
+					// Detect if some page were added automatically and output _tableau for past pages
+					while ($pagenb < $pageposafter)
+					{
+						if ($pagenb == 1)
+						{
+							$this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforfooter, 0, $outputlangs, 0, 1);
+						}
+						else
+						{
+							$this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforfooter, 0, $outputlangs, 1, 1);
+						}
+						$this->_pagefoot($pdf,$object,$outputlangs);
+						$pagenb++;
+						$pdf->setPage($pagenb);
+						$pdf->setPageOrientation('', 1, 0);	// The only function to edit the bottom margin of current page to set it.
+					}
+					if (isset($object->lines[$i+1]->pagebreak) && $object->lines[$i+1]->pagebreak)
+					{
+						if ($pagenb == 1)
+						{
+							$this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforfooter, 0, $outputlangs, 0, 1);
+						}
+						else
+						{
+							$this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforfooter, 0, $outputlangs, 1, 1);
+						}
+						$this->_pagefoot($pdf,$object,$outputlangs);
+						// New page
+						$pdf->AddPage();
+						if (! empty($tplidx)) $pdf->useTemplate($tplidx);
+						$pagenb++;
+					}
 				}
 
 				// Show square
 				if ($pagenb == 1)
 				{
-					$this->_tableau($pdf, $tab_top, $tab_height, $nexY, $outputlangs);
-					$bottomlasttab=$tab_top + $tab_height + 1;
+					$this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforinfotot, 0, $outputlangs, 0, 0);
+					$bottomlasttab=$this->page_hauteur - $heightforinfotot + 1;
 				}
 				else
 				{
-					$this->_tableau($pdf, $tab_top_newpage, $tab_height_endpage, $nexY, $outputlangs);
-					$bottomlasttab=$tab_top_newpage + $tab_height_endpage + 1;
+					$this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforinfotot, 0, $outputlangs, 1, 0);
+					$bottomlasttab=$this->page_hauteur - $heightforinfotot + 1;
 				}
 
 				// Affiche zone infos
@@ -809,9 +801,11 @@ class pdf_jaune extends ModelePDFPropales
 	 *   @param		string		$tab_height		Height of table (rectangle)
 	 *   @param		int			$nexY			Y
 	 *   @param		Translate	$outputlangs	Langs object
+	 *   @param		int			$hidetop		Hide top bar of array
+	 *   @param		int			$hidebottom		Hide bottom bar of array
 	 *   @return	void
 	 */
-	function _tableau(&$pdf, $tab_top, $tab_height, $nexY, $outputlangs)
+	function _tableau(&$pdf, $tab_top, $tab_height, $nexY, $outputlangs, $hidetop=0, $hidebottom=0)
 	{
 		global $conf;
 		$default_font_size = pdf_getPDFFontSize($outputlangs);
diff --git a/htdocs/core/modules/supplier_invoice/pdf/pdf_canelle.modules.php b/htdocs/core/modules/supplier_invoice/pdf/pdf_canelle.modules.php
index 3fc64061d0b..70728e8ea4d 100755
--- a/htdocs/core/modules/supplier_invoice/pdf/pdf_canelle.modules.php
+++ b/htdocs/core/modules/supplier_invoice/pdf/pdf_canelle.modules.php
@@ -171,6 +171,9 @@ class pdf_canelle extends ModelePDFSuppliersInvoices
 				$nblignes = count($object->lines);
 
                 $pdf=pdf_getInstance($this->format);
+                $heightforinfotot = 80;	// Height reserved to output the info and total part (value include bottom margin)
+                $heightforfooter = 25;	// Height reserved to output the footer (value include bottom margin)
+                $pdf->SetAutoPageBreak(1,0);
 
                 if (class_exists('TCPDF'))
                 {
@@ -197,7 +200,6 @@ class pdf_canelle extends ModelePDFSuppliersInvoices
 				if ($conf->global->MAIN_DISABLE_PDF_COMPRESSION) $pdf->SetCompression(false);
 
 				$pdf->SetMargins($this->marge_gauche, $this->marge_haute, $this->marge_droite);   // Left, Top, Right
-				$pdf->SetAutoPageBreak(1,0);
 
 			    // Positionne $this->atleastonediscount si on a au moins une remise
                 for ($i = 0 ; $i < $nblignes ; $i++)
@@ -253,13 +255,19 @@ class pdf_canelle extends ModelePDFSuppliersInvoices
 				{
 					$curY = $nexY;
 
-                    $pdf->SetFont('','', $default_font_size - 1);   // Dans boucle pour gerer multi-page
-
-                    // Description of product line
                     $pdf->SetFont('','', $default_font_size - 1);   // Into loop to work with multipage
+
+					$pdf->setPageOrientation('', 1, $this->marge_basse+$heightforfooter+$heightforinfotot);	// The only function to edit the bottom margin of current page to set it.
+					$pageposbefore=$pdf->getPage();
+
+					// Description of product line
                     $curX = $this->posxdesc-1;
                     pdf_writelinedesc($pdf,$object,$i,$outputlangs,$this->posxtva-$curX,3,$curX,$curY,0,0,1);
 
+					$pageposafter=$pdf->getPage();
+					$pdf->setPage($pageposbefore);
+					$pdf->setPageOrientation('', 1, 0);	// The only function to edit the bottom margin of current page to set it.
+
 					$pdf->SetFont('','', $default_font_size - 1);   // On repositionne la police par defaut
 					$nexY = $pdf->GetY();
 
@@ -310,72 +318,50 @@ class pdf_canelle extends ModelePDFSuppliersInvoices
 
 					$nexY+=2;    // Passe espace entre les lignes
 
-					// Cherche nombre de lignes a venir pour savoir si place suffisante
-					if ($i < ($nblignes - 1) && empty($hidedesc))	// If it's not last line
-					{
-						//on recupere la description du produit suivant
-						$follow_descproduitservice = $object->lines[$i+1]->desc;
-						//on compte le nombre de ligne afin de verifier la place disponible (largeur de ligne 52 caracteres)
-						$nblineFollowDesc = dol_nboflines_bis($follow_descproduitservice,52,$outputlangs->charset_output)*4;
-						// Et si on affiche dates de validite, on ajoute encore une ligne
-						if ($object->lines[$i]->date_start && $object->lines[$i]->date_end)
-						{
-							$nblineFollowDesc += 4;
-						}
-					}
-					else	// If it's last line
-					{
-						$nblineFollowDesc = 0;
-					}
-
-					// Test if a new page is required
-					if ($pagenb == 1)
-					{
-						$tab_top_in_current_page=$tab_top;
-						$tab_height_in_current_page=$tab_height;
-					}
-					else
-					{
-						$tab_top_in_current_page=$tab_top_newpage;
-						$tab_height_in_current_page=$tab_height_newpage;
-					}
-					if (($nexY+$nblineFollowDesc) > ($tab_top_in_current_page+$tab_height_in_current_page) && $i < ($nblignes - 1))
-					{
-						if ($pagenb == 1)
-						{
-							$this->_tableau($pdf, $tab_top, $tab_height + 20, $nexY, $outputlangs);
-						}
-						else
-						{
-							$this->_tableau($pdf, $tab_top_newpage, $tab_height_newpage, $nexY, $outputlangs);
-						}
-
-						$this->_pagefoot($pdf, $object, $outputlangs);
-
-						// New page
-						$pdf->AddPage();
-				        if (! empty($tplidx)) $pdf->useTemplate($tplidx);
-						$pagenb++;
-						$this->_pagehead($pdf, $object, 0, $outputlangs);
-						$pdf->SetFont('','', $default_font_size - 1);
-						$pdf->MultiCell(0, 3, '');		// Set interline to 3
-						$pdf->SetTextColor(0,0,0);
-
-						$nexY = $tab_top_newpage + 7;
-					}
-
+					// Detect if some page were added automatically and output _tableau for past pages
+					while ($pagenb < $pageposafter)
+					{
+						if ($pagenb == 1)
+						{
+							$this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforfooter, 0, $outputlangs, 0, 1);
+						}
+						else
+						{
+							$this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforfooter, 0, $outputlangs, 1, 1);
+						}
+						$this->_pagefoot($pdf,$object,$outputlangs);
+						$pagenb++;
+						$pdf->setPage($pagenb);
+						$pdf->setPageOrientation('', 1, 0);	// The only function to edit the bottom margin of current page to set it.
+					}
+					if (isset($object->lines[$i+1]->pagebreak) && $object->lines[$i+1]->pagebreak)
+					{
+						if ($pagenb == 1)
+						{
+							$this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforfooter, 0, $outputlangs, 0, 1);
+						}
+						else
+						{
+							$this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforfooter, 0, $outputlangs, 1, 1);
+						}
+						$this->_pagefoot($pdf,$object,$outputlangs);
+						// New page
+						$pdf->AddPage();
+						if (! empty($tplidx)) $pdf->useTemplate($tplidx);
+						$pagenb++;
+					}
 				}
 
 				// Show square
 				if ($pagenb == 1)
 				{
-					$this->_tableau($pdf, $tab_top, $tab_height, $nexY, $outputlangs);
-					$bottomlasttab=$tab_top + $tab_height + 1;
+					$this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforinfotot, 0, $outputlangs, 0, 0);
+					$bottomlasttab=$this->page_hauteur - $heightforinfotot + 1;
 				}
 				else
 				{
-					$this->_tableau($pdf, $tab_top_newpage, $tab_height_newpage, $nexY, $outputlangs);
-					$bottomlasttab=$tab_top_newpage + $tab_height_newpage + 1;
+					$this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforinfotot, 0, $outputlangs, 1, 0);
+					$bottomlasttab=$this->page_hauteur - $heightforinfotot + 1;
 				}
 
 				// Affiche zone totaux
@@ -627,9 +613,11 @@ class pdf_canelle extends ModelePDFSuppliersInvoices
 	 *   @param		string		$tab_height		Height of table (rectangle)
 	 *   @param		int			$nexY			Y
 	 *   @param		Translate	$outputlangs	Langs object
+	 *   @param		int			$hidetop		Hide top bar of array
+	 *   @param		int			$hidebottom		Hide bottom bar of array
 	 *   @return	void
 	 */
-	function _tableau(&$pdf, $tab_top, $tab_height, $nexY, $outputlangs)
+	function _tableau(&$pdf, $tab_top, $tab_height, $nexY, $outputlangs, $hidetop=0, $hidebottom=0)
 	{
 		global $conf;
 
diff --git a/htdocs/core/modules/supplier_order/pdf/pdf_muscadet.modules.php b/htdocs/core/modules/supplier_order/pdf/pdf_muscadet.modules.php
index e8fba3d9b46..bc1904b20d6 100644
--- a/htdocs/core/modules/supplier_order/pdf/pdf_muscadet.modules.php
+++ b/htdocs/core/modules/supplier_order/pdf/pdf_muscadet.modules.php
@@ -188,6 +188,9 @@ class pdf_muscadet extends ModelePDFSuppliersOrders
 				$nblignes = count($object->lines);
 
                 $pdf=pdf_getInstance($this->format);
+                $heightforinfotot = 80;	// Height reserved to output the info and total part (value include bottom margin)
+                $heightforfooter = 25;	// Height reserved to output the footer (value include bottom margin)
+                $pdf->SetAutoPageBreak(1,0);
 
                 if (class_exists('TCPDF'))
                 {
@@ -214,7 +217,6 @@ class pdf_muscadet extends ModelePDFSuppliersOrders
 				if ($conf->global->MAIN_DISABLE_PDF_COMPRESSION) $pdf->SetCompression(false);
 
 				$pdf->SetMargins($this->marge_gauche, $this->marge_haute, $this->marge_droite);   // Left, Top, Right
-				$pdf->SetAutoPageBreak(1,0);
 
 				// Positionne $this->atleastonediscount si on a au moins une remise
 				for ($i = 0 ; $i < $nblignes ; $i++)
@@ -272,10 +274,17 @@ class pdf_muscadet extends ModelePDFSuppliersOrders
 
                     $pdf->SetFont('','', $default_font_size - 1);   // Into loop to work with multipage
 
+					$pdf->setPageOrientation('', 1, $this->marge_basse+$heightforfooter+$heightforinfotot);	// The only function to edit the bottom margin of current page to set it.
+					$pageposbefore=$pdf->getPage();
+
 					// Description of product line
                     $curX = $this->posxdesc-1;
                     pdf_writelinedesc($pdf,$object,$i,$outputlangs,$this->posxtva-$curX,3,$curX,$curY,0,0,1,$hookmanager);
 
+					$pageposafter=$pdf->getPage();
+					$pdf->setPage($pageposbefore);
+					$pdf->setPageOrientation('', 1, 0);	// The only function to edit the bottom margin of current page to set it.
+
 					$pdf->SetFont('','', $default_font_size - 1);   // On repositionne la police par defaut
 					$nexY = $pdf->GetY();
 
@@ -328,72 +337,50 @@ class pdf_muscadet extends ModelePDFSuppliersOrders
 
 					$nexY+=2;    // Passe espace entre les lignes
 
-					// Cherche nombre de lignes a venir pour savoir si place suffisante
-					if ($i < ($nblignes - 1) && empty($hidedesc))	// If it's not last line
-					{
-						//on recupere la description du produit suivant
-						$follow_descproduitservice = $object->lines[$i+1]->desc;
-						//on compte le nombre de ligne afin de verifier la place disponible (largeur de ligne 52 caracteres)
-						$nblineFollowDesc = (dol_nboflines_bis($follow_descproduitservice,52,$outputlangs->charset_output)*4);
-						// Et si on affiche dates de validite, on ajoute encore une ligne
-						if ($object->lines[$i]->date_start && $object->lines[$i]->date_end)
-						{
-							$nblineFollowDesc += 4;
-						}
-					}
-					else	// If it's last line
-					{
-						$nblineFollowDesc = 0;
-					}
-
-					// Test if a new page is required
-					if ($pagenb == 1)
-					{
-						$tab_top_in_current_page=$tab_top;
-						$tab_height_in_current_page=$tab_height;
-					}
-					else
-					{
-						$tab_top_in_current_page=$tab_top_newpage;
-						$tab_height_in_current_page=$tab_height_newpage;
-					}
-					if (($nexY+$nblineFollowDesc) > ($tab_top_in_current_page+$tab_height_in_current_page) && $i < ($nblignes - 1))
-					{
-						if ($pagenb == 1)
-						{
-							$this->_tableau($pdf, $tab_top, $tab_height + 20, $nexY, $outputlangs);
-						}
-						else
-						{
-							$this->_tableau($pdf, $tab_top_newpage, $tab_height_newpage, $nexY, $outputlangs);
-						}
-
-						$this->_pagefoot($pdf, $object, $outputlangs);
-
-						// New page
-						$pdf->AddPage();
-				        if (! empty($tplidx)) $pdf->useTemplate($tplidx);
-						$pagenb++;
-						$this->_pagehead($pdf, $object, 0, $outputlangs, $hookmanager);
-						$pdf->SetFont('','', $default_font_size - 1);
-						$pdf->MultiCell(0, 3, '');		// Set interline to 3
-						$pdf->SetTextColor(0,0,0);
-
-						$nexY = $tab_top_newpage + 7;
-					}
-
+					// Detect if some page were added automatically and output _tableau for past pages
+					while ($pagenb < $pageposafter)
+					{
+						if ($pagenb == 1)
+						{
+							$this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforfooter, 0, $outputlangs, 0, 1);
+						}
+						else
+						{
+							$this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforfooter, 0, $outputlangs, 1, 1);
+						}
+						$this->_pagefoot($pdf,$object,$outputlangs);
+						$pagenb++;
+						$pdf->setPage($pagenb);
+						$pdf->setPageOrientation('', 1, 0);	// The only function to edit the bottom margin of current page to set it.
+					}
+					if (isset($object->lines[$i+1]->pagebreak) && $object->lines[$i+1]->pagebreak)
+					{
+						if ($pagenb == 1)
+						{
+							$this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforfooter, 0, $outputlangs, 0, 1);
+						}
+						else
+						{
+							$this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforfooter, 0, $outputlangs, 1, 1);
+						}
+						$this->_pagefoot($pdf,$object,$outputlangs);
+						// New page
+						$pdf->AddPage();
+						if (! empty($tplidx)) $pdf->useTemplate($tplidx);
+						$pagenb++;
+					}
 				}
 
 				// Show square
 				if ($pagenb == 1)
 				{
-					$this->_tableau($pdf, $tab_top, $tab_height, $nexY, $outputlangs);
-					$bottomlasttab=$tab_top + $tab_height + 1;
+					$this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforinfotot, 0, $outputlangs, 0, 0);
+					$bottomlasttab=$this->page_hauteur - $heightforinfotot + 1;
 				}
 				else
 				{
-					$this->_tableau($pdf, $tab_top_newpage, $tab_height_newpage, $nexY, $outputlangs);
-					$bottomlasttab=$tab_top_newpage + $tab_height_newpage + 1;
+					$this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforinfotot, 0, $outputlangs, 1, 0);
+					$bottomlasttab=$this->page_hauteur - $heightforinfotot + 1;
 				}
 
 				// Affiche zone infos
@@ -808,9 +795,11 @@ class pdf_muscadet extends ModelePDFSuppliersOrders
 	 *   @param		string		$tab_height		Height of table (rectangle)
 	 *   @param		int			$nexY			Y
 	 *   @param		Translate	$outputlangs	Langs object
+	 *   @param		int			$hidetop		Hide top bar of array
+	 *   @param		int			$hidebottom		Hide bottom bar of array
 	 *   @return	void
-     */
-	function _tableau(&$pdf, $tab_top, $tab_height, $nexY, $outputlangs)
+	 */
+	function _tableau(&$pdf, $tab_top, $tab_height, $nexY, $outputlangs, $hidetop=0, $hidebottom=0)
 	{
 		global $conf;
 
diff --git a/htdocs/fourn/class/fournisseur.facture.class.php b/htdocs/fourn/class/fournisseur.facture.class.php
index d17b97393d0..c85e8e81dc8 100644
--- a/htdocs/fourn/class/fournisseur.facture.class.php
+++ b/htdocs/fourn/class/fournisseur.facture.class.php
@@ -1282,6 +1282,7 @@ class FactureFournisseur extends CommonInvoice
     function initAsSpecimen()
     {
         global $langs,$conf;
+		include_once(DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php');
 
         $now = dol_now();
 
-- 
GitLab