WeberDev.com PHP and MySQL Code

LOG IN
BEGINNER GUIDES  |  PHP CLASSES  |  CODE SEARCH  |  ARTICLES SEARCH  |  PHP FORUMS  |  PHP MANUAL  |  PHP FUNCTIONS LIST  |  WEB SITE TEMPLATES
Start typing to search for PHP and MySQL Code Snippets and Articles Search
Submit a code Example / Snippet Submit Your Code
Search Engine Optimization Monitor SEO Monitor
Web Site UpTime Monitor UpTime Monitor
WeberDev's Monthly code contest PHP Code Contest
Your Personal Examples List My Favorite Examples
Your Personal Articles List My Favorite Articles
Edit Account Info Update Your Profile
PHP Code Search
Web Development Forums
Learn MySQL Playing Trivia
PHPBB2 Templates
Web Development Index
Web Development Resources
Web Development Content
PHPClasses
PHP Editor
PHP Jobs
Vision.To Design
Ajax Tutorials
PHP Programming Help
PHP/MySQL Programming
Webmaster Resources
Webmaster Forum
XML meta language
website builder
Forex Trading Online forex trading platform

Go Back Add a Comment Send this Article to a friend Add this Article to your personal favoritest for easy future access to your favorite Code Examples and Articles. Submit a code example Print this code example.
BACK ADD A COMMENT SEND TO A FRIEND ADD TO MY FAVORITES SUBMIT AN ARTICLE PRINT
Title : FPDF, a PHP class which allows to generate PDF without using the PDFlib library.
Categories : PHP, PDF Picture not available
Olivier
Date : 2006-01-18
Grade : 5 of 5 (graded 1 times)
Viewed : 37866
Search : More Articles by Olivier
Action : Grade This Article
Tools : My Favotite Articles


  Submit your own code examples 
 


What is FPDF?
FPDF is a PHP class which allows to generate PDF files with pure PHP, that is to say without using the PDFlib library. The advantage is that PDFlib requires a fee for a commercial usage. F from FPDF stands for Free: you may use it for any kind of usage and modify it to suit your needs.

FPDF has other advantages: high level functions. Here is a list of its main features:


  • Choice of measure unit, page format and margins
  • Page header and footer management
  • Automatic page break
  • Automatic line break and text justification
  • Image support (JPEG and PNG)
  • Colors
  • Links
  • TrueType, Type1 and encoding support
  • Page compression
  • FPDF requires no extension (except zlib to activate compression) and works with PHP4 and PHP5.


Minimal example
Let's start with the classic example:


<?php
require('fpdf.php');

$pdf=new FPDF();
$pdf->AddPage();
$pdf->SetFont('Arial','B',16);
$pdf->Cell(40,10,'Hello World!');
$pdf->Output();
?>


After including the library file, we create an FPDF object. The FPDF() constructor is used here with the default values: pages are in A4 portrait and the measure unit is millimeter. It could have been specified explicitly with:


<?
$pdf
=new FPDF('P','mm','A4');
?>




It is possible to use landscape (L), other page formats (such as Letter and Legal) and measure units (pt, cm, in).

There is no page for the moment, so we have to add one with AddPage(). The origin is at the upper-left corner and the current position is by default placed at 1 cm from the borders; the margins can be changed with SetMargins().

Before we can print text, it is mandatory to select a font with SetFont(), otherwise the document would be invalid. We choose Arial bold 16:


<?
$pdf
->SetFont('Arial','B',16);
?>


We could have specified italics with I, underlined with U or a regular font with an empty string (or any combination). Note that the font size is given in points, not millimeters (or another user unit); it is the only exception. The other standard fonts are Times, Courier, Symbol and ZapfDingbats.

We can now print a cell with Cell(). A cell is a rectangular area, possibly framed, which contains some text. It is output at the current position. We specify its dimensions, its text (centered or aligned), if borders should be drawn, and where the current position moves after it (to the right, below or to the beginning of the next line). To add a frame, we would do this:


<?
$pdf
->Cell(40,10,'Hello World !',1);
?>


To add a new cell next to it with centered text and go to the next line, we would do:


<?
$pdf
->Cell(60,10,'Powered by FPDF.',0,1,'C');
?>


Remark : the line break can also be done with Ln(). This method allows to specify in addition the height of the break.

Finally, the document is closed and sent to the browser with Output(). We could have saved it in a file by passing the desired file name.

Caution: in case when the PDF is sent to the browser, nothing else must be output, not before nor after (the least space or carriage return matters). If you send some data before, you will get the error message: "Some data has already been output to browser, can't send PDF file". If you send after, your browser may display a blank page.

Header, footer, page break and image

Here is a two page example with header, footer and logo:


<?php
require('fpdf.php');

class
PDF extends FPDF
{
//Page header
function Header()
{
//Logo
$this->Image('logo_pb.png',10,8,33);
//Arial bold 15
$this->SetFont('Arial','B',15);
//Move to the right
$this->Cell(80);
//Title
$this->Cell(30,10,'Title',1,0,'C');
//Line break
$this->Ln(20);
}

//Page footer
function Footer()
{
//Position at 1.5 cm from bottom
$this->SetY(-15);
//Arial italic 8
$this->SetFont('Arial','I',8);
//Page number
$this->Cell(0,10,'Page '.$this->PageNo().'/{nb}',0,0,'C');
}
}

//Instanciation of inherited class
$pdf=new PDF();
$pdf->AliasNbPages();
$pdf->AddPage();
$pdf->SetFont('Times','',12);
for(
$i=1;$i<=40;$i++)
$pdf->Cell(0,10,'Printing line number '.$i,0,1);
$pdf->Output();
?>


This example makes use of the Header() and Footer() methods to process page headers and footers. They are called automatically. They already exist in the FPDF class but do nothing, therefore we have to extend the class and override them.

The logo is printed with the Image() method by specifying its upper-left corner and its width. The height is calculated automatically to respect the image proportions.

To print the page number, a null value is passed as the cell width. It means that the cell should extend up to the right margin of the page; it is handy to center text. The current page number is returned by the PageNo() method; as for the total number of pages, it is obtained by means of the special value {nb} which will be substituted on document closure (provided you first called AliasNbPages()).
Note the use of the SetY() method which allows to set position at an absolute location in the page, starting from the top or the bottom.

Another interesting feature is used here: the automatic page breaking. As soon as a cell would cross a limit in the page (at 2 centimeters from the bottom by default), a break is performed and the font restored. Although the header and footer select their own font (Arial), the body continues with Times. This mechanism of automatic restoration also applies to colors and line width. The limit which triggers page breaks can be set with SetAutoPageBreak().

Line breaks and colors

Let's continue with an example which prints justified paragraphs. It also illustrates the use of colors.


<?php
require('fpdf.php');

class
PDF extends FPDF
{
function
Header()
{
global
$title;

//Arial bold 15
$this->SetFont('Arial','B',15);
//Calculate width of title and position
$w=$this->GetStringWidth($title)+6;
$this->SetX((210-$w)/2);
//Colors of frame, background and text
$this->SetDrawColor(0,80,180);
$this->SetFillColor(230,230,0);
$this->SetTextColor(220,50,50);
//Thickness of frame (1 mm)
$this->SetLineWidth(1);
//Title
$this->Cell($w,9,$title,1,1,'C',1);
//Line break
$this->Ln(10);
}

function
Footer()
{
//Position at 1.5 cm from bottom
$this->SetY(-15);
//Arial italic 8
$this->SetFont('Arial','I',8);
//Text color in gray
$this->SetTextColor(128);
//Page number
$this->Cell(0,10,'Page '.$this->PageNo(),0,0,'C');
}

function
ChapterTitle($num,$label)
{
//Arial 12
$this->SetFont('Arial','',12);
//Background color
$this->SetFillColor(200,220,255);
//Title
$this->Cell(0,6,"Chapter $num : $label",0,1,'L',1);
//Line break
$this->Ln(4);
}

function
ChapterBody($file)
{
//Read text file
$f=fopen($file,'r');
$txt=fread($f,filesize($file));
fclose($f);
//Times 12
$this->SetFont('Times','',12);
//Output justified text
$this->MultiCell(0,5,$txt);
//Line break
$this->Ln();
//Mention in italics
$this->SetFont('','I');
$this->Cell(0,5,'(end of excerpt)');
}

function
PrintChapter($num,$title,$file)
{
$this->AddPage();
$this->ChapterTitle($num,$title);
$this->ChapterBody($file);
}
}

$pdf=new PDF();
$title='20000 Leagues Under the Seas';
$pdf->SetTitle($title);
$pdf->SetAuthor('Jules Verne');
$pdf->PrintChapter(1,'A RUNAWAY REEF','20k_c1.txt');
$pdf->PrintChapter(2,'THE PROS AND CONS','20k_c2.txt');
$pdf->Output();
?>


The GetStringWidth() method allows to determine the length of a string in the current font, which is used here to calculate the position and the width of the frame surrounding the title. Then colors are set (via SetDrawColor(), SetFillColor() and SetTextColor()) and the thickness of the line is set to 1 mm (against 0.2 by default) with SetLineWidth(). Finally, we output the cell (the last parameter to 1 indicates that the background must be filled).

The method used to print the paragraphs is MultiCell(). Each time a line reaches the right extremity of the cell or a carriage-return character is met, a line break is issued and a new cell automatically created under the current one. Text is justified by default.

Two document properties are defined: title (SetTitle()) and author (SetAuthor()). Properties can be viewed by two means. First is open the document directly with Acrobat Reader, go to the File menu, Document info, General. Second, also available from the plug-in, is click on the triangle just above the right scrollbar and choose Document info.

Multi-columns

This example is a variant of the previous one showing how to lay the text across multiple columns.


<?php
require('fpdf.php');

class
PDF extends FPDF
{
//Current column
var $col=0;
//Ordinate of column start
var $y0;

function
Header()
{
//Page header
global $title;

$this->SetFont('Arial','B',15);
$w=$this->GetStringWidth($title)+6;
$this->SetX((210-$w)/2);
$this->SetDrawColor(0,80,180);
$this->SetFillColor(230,230,0);
$this->SetTextColor(220,50,50);
$this->SetLineWidth(1);
$this->Cell($w,9,$title,1,1,'C',1);
$this->Ln(10);
//Save ordinate
$this->y0=$this->GetY();
}

function
Footer()
{
//Page footer
$this->SetY(-15);
$this->SetFont('Arial','I',8);
$this->SetTextColor(128);
$this->Cell(0,10,'Page '.$this->PageNo(),0,0,'C');
}

function
SetCol($col)
{
//Set position at a given column
$this->col=$col;
$x=10+$col*65;
$this->SetLeftMargin($x);
$this->SetX($x);
}

function
AcceptPageBreak()
{
//Method accepting or not automatic page break
if($this->col<2)
{
//Go to next column
$this->SetCol($this->col+1);
//Set ordinate to top
$this->SetY($this->y0);
//Keep on page
return false;
}
else
{
//Go back to first column
$this->SetCol(0);
//Page break
return true;
}
}

function
ChapterTitle($num,$label)
{
//Title
$this->SetFont('Arial','',12);
$this->SetFillColor(200,220,255);
$this->Cell(0,6,"Chapter $num : $label",0,1,'L',1);
$this->Ln(4);
//Save ordinate
$this->y0=$this->GetY();
}

function
ChapterBody($fichier)
{
//Read text file
$f=fopen($fichier,'r');
$txt=fread($f,filesize($fichier));
fclose($f);
//Font
$this->SetFont('Times','',12);
//Output text in a 6 cm width column
$this->MultiCell(60,5,$txt);
$this->Ln();
//Mention
$this->SetFont('','I');
$this->Cell(0,5,'(end of excerpt)');
//Go back to first column
$this->SetCol(0);
}

function
PrintChapter($num,$title,$file)
{
//Add chapter
$this->AddPage();
$this->ChapterTitle($num,$title);
$this->ChapterBody($file);
}
}

$pdf=new PDF();
$title='20000 Leagues Under the Seas';
$pdf->SetTitle($title);
$pdf->SetAuthor('Jules Verne');
$pdf->PrintChapter(1,'A RUNAWAY REEF','20k_c1.txt');
$pdf->PrintChapter(2,'THE PROS AND CONS','20k_c2.txt');
$pdf->Output();
?>


The key method used is AcceptPageBreak(). It allows to accept or not an automatic page break. By refusing it and altering the margin and current position, the desired column layout is achieved.
For the rest, not much change; two properties have been added to the class to save the current column number and the position where columns begin, and the MultiCell() call specifies a 6 centimeter width.

Tables

This tutorial shows how to make tables easily


<?php
require('fpdf.php');

class
PDF extends FPDF
{
//Load data
function LoadData($file)
{
//Read file lines
$lines=file($file);
$data=array();
foreach(
$lines as $line)
$data[]=explode(';',chop($line));
return
$data;
}

//Simple table
function BasicTable($header,$data)
{
//Header
foreach($header as $col)
$this->Cell(40,7,$col,1);
$this->Ln();
//Data
foreach($data as $row)
{
foreach(
$row as $col)
$this->Cell(40,6,$col,1);
$this->Ln();
}
}

//Better table
function ImprovedTable($header,$data)
{
//Column widths
$w=array(40,35,40,45);
//Header
for($i=0;$i<count($header);$i++)
$this->Cell($w[$i],7,$header[$i],1,0,'C');
$this->Ln();
//Data
foreach($data as $row)
{
$this->Cell($w[0],6,$row[0],'LR');
$this->Cell($w[1],6,$row[1],'LR');
$this->Cell($w[2],6,number_format($row[2]),'LR',0,'R');
$this->Cell($w[3],6,number_format($row[3]),'LR',0,'R');
$this->Ln();
}
//Closure line
$this->Cell(array_sum($w),0,'','T');
}

//Colored table
function FancyTable($header,$data)
{
//Colors, line width and bold font
$this->SetFillColor(255,0,0);
$this->SetTextColor(255);
$this->SetDrawColor(128,0,0);
$this->SetLineWidth(.3);
$this->SetFont('','B');
//Header
$w=array(40,35,40,45);
for(
$i=0;$i<count($header);$i++)
$this->Cell($w[$i],7,$header[$i],1,0,'C',1);
$this->Ln();
//Color and font restoration
$this->SetFillColor(224,235,255);
$this->SetTextColor(0);
$this->SetFont('');
//Data
$fill=0;
foreach(
$data as $row)
{
$this->Cell($w[0],6,$row[0],'LR',0,'L',$fill);
$this->Cell($w[1],6,$row[1],'LR',0,'L',$fill);
$this->Cell($w[2],6,number_format($row[2]),'LR',0,'R',$fill);
$this->Cell($w[3],6,number_format($row[3]),'LR',0,'R',$fill);
$this->Ln();
$fill=!$fill;
}
$this->Cell(array_sum($w),0,'','T');
}
}

$pdf=new PDF();
//Column titles
$header=array('Country','Capital','Area (sq km)','Pop. (thousands)');
//Data loading
$data=$pdf->LoadData('countries.txt');
$pdf->SetFont('Arial','',14);
$pdf->AddPage();
$pdf->BasicTable($header,$data);
$pdf->AddPage();
$pdf->ImprovedTable($header,$data);
$pdf->AddPage();
$pdf->FancyTable($header,$data);
$pdf->Output();
?>


A table being just a collection of cells, it is natural to build one from them. The first example is achieved in the most basic way possible: simple framed cells, all of the same size and left aligned. The result is rudimentary but very quick to obtain.

The second table brings some improvements: each column has its own width, titles are centered and figures right aligned. Moreover, horizontal lines have been removed. This is done by means of the border parameter of the Cell() method, which specifies which sides of the cell must be drawn. Here we want the left (L) and right (R) ones. It remains the problem of the horizontal line to finish the table. There are two possibilities: either check for the last line in the loop, in which case we use LRB for the border parameter; or, as done here, add the line once the loop is over.

The third table is similar to the second one but uses colors. Fill, text and line colors are simply specified. Alternate coloring for rows is obtained by using alternatively transparent and filled cells.

Links and flowing text
This tutorial explains how to insert links (internal and external) and shows a new text writing mode. It also contains a rudimentary HTML parser.





<?php
require('fpdf.php');

class
PDF extends FPDF
{
var
$B;
var
$I;
var
$U;
var
$HREF;

function
PDF($orientation='P',$unit='mm',$format='A4')
{
//Call parent constructor
$this->FPDF($orientation,$unit,$format);
//Initialization
$this->B=0;
$this->I=0;
$this->U=0;
$this->HREF='';
}

function
WriteHTML($html)
{
//HTML parser
$html=str_replace("\n",' ',$html);
$a=preg_split('/<(.*)>/U',$html,-1,PREG_SPLIT_DELIM_CAPTURE);
foreach(
$a as $i=>$e)
{
if(
$i%2==0)
{
//Text
if($this->HREF)
$this->PutLink($this->HREF,$e);
else
$this->Write(5,$e);
}
else
{
//Tag
if($e{0}=='/')
$this->CloseTag(strtoupper(substr($e,1)));
else
{
//Extract attributes
$a2=explode(' ',$e);
$tag=strtoupper(array_shift($a2));
$attr=array();
foreach(
$a2 as $v)
if(
ereg('^([^=]*)=["\']?([^"\']*)["\']?$',$v,$a3))
$attr[strtoupper($a3[1])]=$a3[2];
$this->OpenTag($tag,$attr);
}
}
}
}

function
OpenTag($tag,$attr)
{
//Opening tag
if($tag=='B' or $tag=='I' or $tag=='U')
$this->SetStyle($tag,true);
if(
$tag=='A')
$this->HREF=$attr['HREF'];
if(
$tag=='BR')
$this->Ln(5);
}

function
CloseTag($tag)
{
//Closing tag
if($tag=='B' or $tag=='I' or $tag=='U')
$this->SetStyle($tag,false);
if(
$tag=='A')
$this->HREF='';
}

function
SetStyle($tag,$enable)
{
//Modify style and select corresponding font
$this->$tag+=($enable ? 1 : -1);
$style='';
foreach(array(
'B','I','U') as $s)
if(
$this->$s>0)
$style.=$s;
$this->SetFont('',$style);
}

function
PutLink($URL,$txt)
{
//Put a hyperlink
$this->SetTextColor(0,0,255);
$this->SetStyle('U',true);
$this->Write(5,$txt,$URL);
$this->SetStyle('U',false);
$this->SetTextColor(0);
}
}

$html='You can now easily print text mixing different
styles : <B>bold</B>, <I>italic</I>, <U>underlined</U>, or
<B><I><U>all at once</U></I></B>!<BR>You can also insert links
on text, such as <A HREF="http://www.fpdf.org">www.fpdf.org</A>,
or on an image: click on the logo.'
;

$pdf=new PDF();
//First page
$pdf->AddPage();
$pdf->SetFont('Arial','',20);
$pdf->Write(5,'To find out what\'s new in this tutorial, click ');
$pdf->SetFont('','U');
$link=$pdf->AddLink();
$pdf->Write(5,'here',$link);
$pdf->SetFont('');
//Second page
$pdf->AddPage();
$pdf->SetLink($link);
$pdf->Image('logo.png',10,10,30,0,'','http://www.fpdf.org');
$pdf->SetLeftMargin(45);
$pdf->SetFontSize(14);
$pdf->WriteHTML($html);
$pdf->Output();
?>


The new method to print text is Write(). It is very close to MultiCell(); the differences are:
The end of line is at the right margin and the next line begins at the left one
The current position moves at the end of the text
So it allows to write a chunk of text, alter the font style, then continue from the exact place we left it. On the other hand, you cannot full justify it.

The method is used on the first page to put a link pointing to the second one. The beginning of the sentence is written in regular style, then we switch to underline and finish it. The link is created with AddLink(), which returns a link identifier. The identifier is passed as third parameter of Write(). Once the second page is created, we use SetLink() to make the link point to the beginning of the current page.

Then we put an image with a link on it. An external link points to an URL (HTTP, mailto...). The URL is simply passed as last parameter of Image(). Note that external links do not work when the PDF is displayed inside Netscape's plug-in.

Finally, the left margin is moved after the image with SetLeftMargin() and some text in HTML format is output. An HTML parser is used for this, based on the regular expression splitting function preg_split() and the option PREG_SPLIT_DELIM_CAPTURE (introduced in PHP 4.0.5) which allows to fetch the separators as well (in this case the tags). If you use an older version of PHP, replace the line with this one:


$a=preg_split('/[<>]/',$html);


which is less strict but gives the same results with valid HTML.
Recognized tags are <B>, <I>, <U>, <A> and <BR>; the others are ignored. The parser also makes use of the Write() method. An external link is put the same way as an internal one (third parameter of Write()).
Note that Cell() also allows to put links.

Adding new fonts and encoding support

This tutorial explains how to use TrueType or Type1 fonts so that you are not limited to the standard fonts any more. The other interest is that you can choose the font encoding, which allows you to use other languages than the Western ones (the standard fonts having too few available characters).

There are two ways to use a new font: embedding it in the PDF or not. When a font is not embedded, it is sought in the system. The advantage is that the PDF file is lighter; on the other hand, if it is not available, a substitution font is used. So it is preferable to ensure that the needed font is installed on the client systems. If the file is to be viewed by a large audience, it is better to embed.

Adding a new font requires three steps for TrueTypes:


  • Generation of the metric file (.afm)
  • Generation of the font definition file (.php)
  • Declaration of the font in the script


For Type1, the first one is theoretically not necessary because the AFM file is usually shipped with the font. In case you have only a metric file in PFM format, use the convertor available here.

Generation of the metric file
The first step for a TrueType consists in generating the AFM file. A utility exists to do this task: ttf2pt1. The Windows binary is available here. The command line to use is the following:


ttf2pt1 -a font.ttf font


For example, for Comic Sans MS Regular:


ttf2pt1 -a c:\windows\fonts\comic.ttf comic


Two files are created; the one we are interested in is comic.afm.

Generation of the font definition file

The second step consists in generating a PHP file containing all the information needed by FPDF; in addition, the font file is compressed. To do this, a helper script is provided in the font/makefont/ directory of the package: makefont.php. It contains the following function:


MakeFont(string fontfile, string afmfile [, string enc [, array patch [, string type]]])



  • fontfile - Path to the .ttf or .pfb file.
  • afmfile - Path to the .afm file.
  • enc - Name of the encoding to use. Default value: cp1252.
  • patch - Optional modification of the encoding. Empty by default.
  • type - Type of the font (TrueType or Type1). Default value: TrueType.


The first parameter is the name of the font file. The extension must be either .ttf or .pfb and determines the font type. If you own a Type1 font in ASCII format (.pfa), you can convert it to binary format with t1utils.
If you don't want to embed the font, pass an empty string. In this case, type is given by the type parameter.
Note: in the case of a font with the same name as a standard one, for instance arial.ttf, it is mandatory to embed. If you don't, Acrobat will use its own font.

The AFM file is the one previously generated.

The encoding defines the association between a code (from 0 to 255) and a character. The first 128 are fixed and correspond to ASCII; the following are variable. The encodings are stored in .map files. Those available are:


  • cp1250 (Central Europe)
  • cp1251 (Cyrillic)
  • cp1252 (Western Europe)
  • cp1253 (Greek)
  • cp1254 (Turkish)
  • cp1255 (Hebrew)
  • cp1257 (Baltic)
  • cp1258 (Vietnamese)
  • cp874 (Thai)
  • ISO-8859-1 (Western Europe)
  • ISO-8859-2 (Central Europe)
  • ISO-8859-4 (Baltic)
  • ISO-8859-5 (Cyrillic)
  • ISO-8859-7 (Greek)
  • ISO-8859-9 (Turkish)
  • ISO-8859-11 (Thai)
  • ISO-8859-15 (Western Europe)
  • ISO-8859-16 (Central Europe)
  • KOI8-R (Russian)
  • KOI8-U (Ukrainian)


Of course, the font must contain the characters corresponding to the chosen encoding.
In the particular case of a symbolic font (that is to say which does not contain letters, such as Symbol or ZapfDingbats), pass an empty string.
The encodings which begin with cp are those used by Windows; Linux systems usually use ISO.
Remark: the standard fonts use cp1252.

The fourth parameter gives the possibility to alter the encoding. Sometimes you may want to add some characters. For instance, ISO-8859-1 does not contain the euro symbol. To add it at position 164, pass array(164=>'Euro').

The last parameter is used to give the type of the font in case it is not embedded (that is to say the first parameter is empty).

After you have called the function (create a new file for this and include makefont.php, or simply add the call directly inside), a .php file is created, with the same name as the .afm one. You may rename it if you wish. If the case of embedding, the font file is compressed and gives a second file with .z as extension (except if the compression function is not available, it requires zlib). You may rename it too, but in this case you have to alter the variable $file in the .php file accordingly.

Example:


MakeFont('c:\\windows\\fonts\\comic.ttf','comic.afm','cp1252');


which gives the files comic.php and comic.z.

Then you have to copy the generated file(s) to the font directory. If the font file could not be compressed, copy the .ttf or .pfb instead of the .z.

Declaration of the font in the script

The last step is the most simple. You just need to call the AddFont() method. For instance:


<?
$pdf
->AddFont('Comic','','comic.php');
?>


or simply:


<?
$pdf
->AddFont('Comic');
?>


And the font is now available (in regular and underlined styles), usable like the others. If we had worked with Comic Sans MS Bold (comicbd.ttf), we would have put:


<?
$pdf
->AddFont('Comic','B','comicbd.php');
?>


Example
Let's now see a small complete example. The font used is Calligrapher, available at www.abstractfonts.com (a site offering numerous free TrueType fonts). The first step is the generation of the AFM file:

ttf2pt1 -a calligra.ttf calligra

which gives calligra.afm (and calligra.t1a that we can delete). Then we generate the definition file:


<?php
require('font/makefont/makefont.php');

MakeFont('calligra.ttf','calligra.afm');
?>


The function call gives the following report:


Warning: character Euro is missing
Warning: character Zcaron is missing
Warning: character zcaron is missing
Warning: character eth is missing
Font file compressed (calligra.z)
Font definition file generated (calligra.php)


The euro character is not present in the font (it is too old). Three other characters are missing too, but we are not interested in them anyway.
We can now copy the two files to the font directory and write the script:


<?php
require('fpdf.php');

$pdf=new FPDF();
$pdf->AddFont('Calligrapher','','calligra.php');
$pdf->AddPage();
$pdf->SetFont('Calligrapher','',35);
$pdf->Cell(0,10,'Enjoy new fonts with FPDF!');
$pdf->Output();
?>


About the euro symbol
The euro character is not present in all encodings, and is not always placed at the same position:




ISO-8859-1 is widespread but does not include the euro sign. If you need it, the simplest thing to do is using cp1252 or ISO-8859-15 instead, which are nearly identical but contain the precious symbol.
As for ISO-8859-2, it is possible to use ISO-8859-16 instead, but it contains many differences. It is therefore simpler to patch the encoding to add the symbol to it, as explained above. The same is true for the other encodings.

Font synthesis under Windows

When a TrueType font is not available in a given style, Windows is able to synthesize it from the regular version. For instance, there is no Comic Sans MS Italic, but it can be built from Comic Sans MS Regular. This feature can be used in a PDF file, but unfortunately requires that the regular font be present in the system (you must not embed it). Here is how to do it:


  • Generate the definition file for the regular font without embedding (you may rename it to reflect the desired style)
  • Open it and append to the variable $name a comma followed by the desired style (Italic, Bold or BoldItalic)


For instance, for the file comici.php:


<?
$name
='ComicSansMS,Italic';
?>


It can then be used normally:


<?
$pdf
->AddFont('Comic','I','comici.php');
?>


Reducing the size of TrueType fonts

Font files are often quite voluminous (more than 100, even 200KB); this is due to the fact that they contain the characters corresponding to many encodings. zlib compression reduces them but they remain fairly big. A technique exists to reduce them further. It consists in converting the font to the Type1 format with ttf2pt1 by specifying the encoding you are interested in; all other characters will be discarded.
For instance, the arial.ttf font shipped with Windows 98 is 267KB (it contains 1296 characters). After compression it gives 147. Let's convert it to Type1 by keeping only cp1250 characters:


ttf2pt1 -b -L cp1250.map c:\windows\fonts\arial.ttf arial


The .map files are located in the font/makefont/ directory of the package. The command produces arial.pfb and arial.afm. The arial.pfb file is only 35KB, and 30KB after compression.

It is possible to go even further. If you are interested only by a subset of the encoding (you probably don't need all 217 characters), you can open the .map file and remove the lines you are not interested in. This will reduce the file size accordingly.









Use PHP to Create Dynamic pdf Files
Categories : PHP, PDF
Beginners Guide to PHP - Introduction to cookies
Categories : Beginner Guides, Cookies, To PHP, PHP
Building XML Trees with PEAR's XML_Tree Class
Categories : PHP, Pear, XML
Setup and Install Apache with PHP4 as a Dynamic Module (DSO)
Categories : PHP, PHP Configuration, Apache
PHP 101 Part 11 of 15 : Sinfully Simple
Categories : PHP, SimpleXML, XML
Protecting PHP Scripts with HTTP Authorization
Categories : PHP, HTTP, Security, Authentication
Honey, I Shrunk My Website
Categories : PHP, PHP options/info, Site Planning, Other
PHP 101 Part 8 of 15 : Databases and Other Animals
Categories : PHP, Beginner Guides, Databases
Simple PHP Templates With PatTemplate
Categories : PHP, Templates
Referer Statistics
Categories : PHP, MySQL, HTTP, Databases
Simple Connection to PostgreSQL with PHP
Categories : PHP, PostgreSQL, Databases
Making PHP Forms Object-Oriented
Categories : PHP, HTML and PHP, Object Oriented
Extracting Elements from a Database into a Select Form Field
Categories : PHP, HTML
Introduction to using PHP 5.0 and SQLite
Categories : PHP, SQLite, Databases
PHP And Regular Expressions 101
Categories : PHP, Regexps