4

I'm using TCPDF to generate PDFs (obviously). All has been well, but now I'm trying to make a PDF with the character "đ" (which apparently is a slovic character).

The data is user-generated, so I won't know if they're planning on using these type of characters or not - that's why I thought I should use UTF-8. But apparently that's not right.

The PDF gets created, but it's completely empty / white.

Here is my relevant code:

$pdf = new XTCPDF('P', PDF_UNIT, 'Letter', true, 'UTF-8', false);
$pdf->SetPrintHeader(false);
$pdf->SetPrintFooter(false);
$pdf->SetDefaultMonospacedFont(PDF_FONT_MONOSPACED);
$pdf->SetMargins($pageMargin, $pageMargin, $pageMargin); //PDF_MARGIN_LEFT, PDF_MARGIN_TOP, PDF_MARGIN_RIGHT
$pdf->SetAutoPageBreak(TRUE, $pageMargin/2);
$pdf->setImageScale(PDF_IMAGE_SCALE_RATIO);
$pdf->SetFont('helvetica', '', 10, '', true);

$pdf->AddPage();

$pdf->setJPEGQuality(70);

I found this answer but changing to this didn't work either:

$pdf = new XTCPDF('P', PDF_UNIT, 'Letter', false, 'ISO-8859-1', false);

My data pieces (user's name, address...etc) are currently wrapped like this:

trim(mb_convert_encoding($myHtml, "HTML-ENTITIES", "UTF-8"))

Questions:

What can I change to make it so that:

  1. I can create a PDF with a character like "đ"
  2. I can make the settings so it will create regardless of the character(s) the user uses.
Community
  • 1
  • 1
Dave
  • 28,833
  • 23
  • 113
  • 183
  • Try another charset. Search for the slovic charset. – Robin May 13 '15 at 21:22
  • @RobinR - using a slovic charset would then make me unable to use other non-slavic characters though, right? Would kind of defeat the purpose. – Dave May 13 '15 at 22:09
  • Can you post an example (empty) PDF file? It'd perhaps be interesting to see whether it still contains any content and if so what that is. – David van Driessche May 16 '15 at 17:10
  • 1
    Also, have you tried setting another font than a standard PDF font? You're using Helvetica and the documentation states the default fonts use the "cp1252" encoding which as far as I know doesn't support the character you're talking about. It would be interesting to know whether other special characters that *are* in that character set *do* work or not. – David van Driessche May 16 '15 at 17:15

3 Answers3

5

David van Driessche has correctly identified the problem; the font in use doesn't support the đ character.

A basic test (note that I saved this PHP script as a UTF8 file):

require './tcpdf/tcpdf.php';

function write($pdf)
{
    $pdf->Write(0, 'test đ   ', '', 0, '', false, 0, false, false, 0);
    $pdf->writeHTML(trim(mb_convert_encoding('test2 đ', "HTML-ENTITIES", "UTF-8")), true, false, true, false, '');
}

$pdf = new TCPDF('P', PDF_UNIT, 'Letter', true, 'UTF-8', false);
$pdf->AddPage();

$pdf->SetFont('helvetica', '', 20);
write($pdf);

$pdf->SetFont('freesans', '', 20);
write($pdf);

$pdf->Output();

This gives me the following PDF output (rendered in Firefox):

PDF result

Looking at the TCPDF example for including an external UTF-8 text file you can see the following very interesting line:

$pdf->SetFont('freeserif', '', 12);

Strangely freeserif is not listed as one of the standard TCPDF fonts but is in the fonts folder distributed with TCPDF (looking in this folder led me to freesans as well, so I used that in the example above). I can only assume the documentation is not up-to-date.

It seems your choices are to either use freesans or load a third-party font via the AddFont() method.

Edit: I tested the above with a slightly older build of TCPDF: 6.0.099.

Community
  • 1
  • 1
timclutton
  • 12,682
  • 3
  • 33
  • 43
  • Thanks! Any ideas on how to keep the filesize low? Changing from helvetica to freesans (or dejavusans) almost quadruples the filesize (15k to 60k). Is there anything that can be done for that? I tried to turn on subsetting, but that was slower and only reduced down to 59k. – Dave May 21 '15 at 15:10
  • @Dave The only thing that comes to mind is `setFontSubsetting(true)` but as you say you've tried this I don't know what else to suggest. Relatively speaking 60K is still tiny; unless your application is very heavily used I would say the trade-off (file size vs. character support) is worth it. – timclutton May 21 '15 at 19:56
  • Ok, thanks. 60k is "ok", but - still a quadruple in size, and I'd like to keep it as small as possible. That being said, I suppose having a larger font set is going to inherently create larger files. Just didn't figure it'd be 45k (300%) bigger. – Dave May 21 '15 at 23:42
1

Try this before you insert the string into the pdf.

$string = htmlentities( (string) $your_slovic_string, ENT_QUOTES, 'utf-8', FALSE);

You could also use: html_entity_decode().

I ran into a similar problem with user entered content and this cleared it up for me.

silversunhunter
  • 1,219
  • 2
  • 12
  • 32
  • I updated my answer with how I'm wrapping my data - I believe it's the same thing (basically), but when I try yours, I get all the HTML characters showing like Name (and the character in question is an actual questionmark) – Dave May 13 '15 at 22:19
  • You want to get slovic characters in your PDF file fulley? Or not? Because otherwise you can set the headers... Try to explain it a bit more. – Robin May 14 '15 at 07:58
1

In version 6.2.8 I modified just first example by adding character đ and everything seems to work fine. This is the code:

// Include the main TCPDF library (search for installation path).
require_once('tcpdf_include.php');

// create new PDF document
$pdf = new TCPDF(PDF_PAGE_ORIENTATION, PDF_UNIT, PDF_PAGE_FORMAT, true, 'UTF-8', false);

// set document information
$pdf->SetCreator(PDF_CREATOR);
$pdf->SetAuthor('Nicola Asuni');
$pdf->SetTitle('TCPDF Example 001');
$pdf->SetSubject('TCPDF Tutorial');
$pdf->SetKeywords('TCPDF, PDF, example, test, guide');

// set default header data
$pdf->SetHeaderData(PDF_HEADER_LOGO, PDF_HEADER_LOGO_WIDTH, PDF_HEADER_TITLE.' 001', PDF_HEADER_STRING, array(0,64,255), array(0,64,128));
$pdf->setFooterData(array(0,64,0), array(0,64,128));

// set header and footer fonts
$pdf->setHeaderFont(Array(PDF_FONT_NAME_MAIN, '', PDF_FONT_SIZE_MAIN));
$pdf->setFooterFont(Array(PDF_FONT_NAME_DATA, '', PDF_FONT_SIZE_DATA));

// set default monospaced font
$pdf->SetDefaultMonospacedFont(PDF_FONT_MONOSPACED);

// set margins
$pdf->SetMargins(PDF_MARGIN_LEFT, PDF_MARGIN_TOP, PDF_MARGIN_RIGHT);
$pdf->SetHeaderMargin(PDF_MARGIN_HEADER);
$pdf->SetFooterMargin(PDF_MARGIN_FOOTER);

// set auto page breaks
$pdf->SetAutoPageBreak(TRUE, PDF_MARGIN_BOTTOM);

// set image scale factor
$pdf->setImageScale(PDF_IMAGE_SCALE_RATIO);

// set some language-dependent strings (optional)
if (@file_exists(dirname(__FILE__).'/lang/eng.php')) {
    require_once(dirname(__FILE__).'/lang/eng.php');
    $pdf->setLanguageArray($l);
}

// ---------------------------------------------------------

// set default font subsetting mode
$pdf->setFontSubsetting(true);

// Set font
// dejavusans is a UTF-8 Unicode font, if you only need to
// print standard ASCII chars, you can use core fonts like
// helvetica or times to reduce file size.
$pdf->SetFont('dejavusans', '', 14, '', true);

// Add a page
// This method has several options, check the source code documentation for more information.
$pdf->AddPage();

// Set some content to print
$html = <<<EOD
<h1>Welcome tćžžćččšđ <a href="http://www.tcpdf.org" style="text-decoration:none;background-color:#CC0000;color:black;">
&nbsp;<span style="color:black;">TC</span><span style="color:white;">PDF</span>&nbsp;</a>!</h1>
<i>This is the first example of TCPDF library.</i>
<p>This text is printed using the <i>writeHTMLCell()</i> method but you can also use: <i>Multicell(), writeHTML(), Write(), Cell() and Text()</i>.</p>
<p>Please check the source code documentation and other examples for further information.</p>
<p style="color:#CC0000;">TO IMPROVE AND EXPAND TCPDF I NEED YOUR SUPPORT, PLEASE <a href="http://sourceforge.net/donate/index.php?group_id=128076">MAKE A DONATION!</a></p>
EOD;

// Print text using writeHTMLCell()
$pdf->writeHTMLCell(0, 0, '', '', $html, 0, 1, 0, true, '', true);

// ---------------------------------------------------------

// Close and output PDF document
// This method has several options, check the source code documentation for more information.
$pdf->Output('example_001.pdf', 'I');

//============================================================+
// END OF FILE
//============================================================+

As for download link for this version, you can find this here.

And this is how it looks as PDF

Marko Vasic
  • 690
  • 9
  • 27