How to use FPDF_CellFit with FPDI

1k views Asked by At

I've been playing with FPDF and need to create a PDF using a starting template PDF so managed to get that figured out using FPDI. I then needed to use a non-standard font which I managed to get working as well. However... the letter spacing is all messed up (some letters tight together, others spaced way far apart in the same words).

I found the add on solution of FPDF_CellFit but that class extends FPDF so how can I make it work when using FPDI? Here is my code:

$pdf =& new FPDI();

$pdf->AddFont('AgencyFB-Reg','','agencyfbb.php');
$pdf->AddPage('mm', array(54,92));
$pdf->setSourceFile('test.pdf'); 
$tplIdx = $pdf->importPage(1);
$pdf->useTemplate($tplIdx, 0, 0, 92);
$pdf->SetFont('AgencyFB-Reg','',14);  
$pdf->SetXY(100, 27);  
$pdf->Write(0, "testing");
$pdf->Output();

But as explained above, when I look at the FPDF_CellFit class it starts this way:

$pdf = new FPDF_CellFit();

class FPDF_CellFit extends FPDF {
... ... ...
}

Please help... I am so close!

1

There are 1 answers

0
chadyred On

I have make a package to fix that problem. You have to keep the same PDF all the time. So when you add some effect to it, it must be the same all the time.

In fact, the decorator pattern is a good way to do this.

The decorator class

<?php
abstract class DecoratorPdf extends \FPDF {
    protected $pdf;

    public function __construct(\FPDF $pdf) {
        $this->pdf = $pdf;
    }
}

And I have made the class cleft in object like this

<?php

class FPDF_CellFit extends \DecoratorPdf {
    //Cell with horizontal scaling if text is too wide
    function CellFit($w, $h=0, $txt='', $border=0, $ln=0, $align='', $fill=false, $link='', $scale=false, $force=true)
    {
        //Get string width
        $str_width=$this->pdf->GetStringWidth($txt);
        //Calculate ratio to fit cell
        if($w==0)
            $w = $this->pdf->w-$this->pdf->rMargin-$this->x;
        $ratio = ($w-$this->pdf->cMargin*2)/$str_width;
        $fit = ($ratio < 1 || ($ratio > 1 && $force));
        ..

So now when you use it you create a PDF class which extends FPDF. So the pdf will be create and you can call the cellfit class which extends the decorator class and add in the constructor your PDF. So all the time you keep the same PDF.

Example

class Pdf extends \FPDI
{
//Fonction qui représente une zone ciblée concernant le code postale de l'adresse   du destinataire

    function destinataireCodePostal($string)
    { 
        // Helvetica 12
        $this->SetFont('Helvetica',"",10);

        //PdfDraw enrichie avec la pattern Decorator mon PDF
        $cellfit = new \FPDF_CellFit($this);

         //Position du code poste
        $this->SetXY(102, 67.3);

        //Permet d'espacer les lettres de manière égale
        $cellfit->CellFitSpaceForce(15.5, 10, utf8_decode($string), 0, 0, 'l', 0);

        //Retour à la police normal
        $this->mainFont();
    }

Use with composer, the seating project will be autoloader

 "require": {
        "php": ">=5.3.3",
        "setasign/fpdi-fpdf": "1.5.4"
    },
    "autoload": {
            "classmap": [
            "lib/draw/draw.php",
            "lib/cellfit/cellfit.php",
            "lib/DecoratorPdf.php"
        ]
    }

The full package with example is here, in the lib folder I have made draw and cellfit in this object pattern.

lib for cellfit in object