PDF Font embedding problem in Magento / Zend Framework
4 Jan 2012
Have you ever had problems with custom fonts embedding, while trying to generate PDF ducoments in Magento or using Zend Framework. May be I found solution for you, If you get next error message:
“This font cannot be embedded in the PDF document. If you would like to use it anyway, you must pass Zend_Pdf_Font::EMBED_SUPPRESS_EMBED_EXCEPTION in the $options parameter of the font constructor.”
As a result of my research I decided, that the problem comes from Zend Framework core and seems, that it doesn’t recognize correctly if your custom font can be embedded if has some embedding permissions.
What I mean, when say embedding permissions:
- Licensed for print and preview embedding
- Licensed for editable embedding
- Licensed for modification
I am suggesting next workaround / quick fix:
There is a file Zend/Pdf/Resource/Font/FontDescriptor.php in Zend Framework core. My suggestion is to comment from line 161 to line 173 and also we need to comment line 199. By this modification we pass the check if our custom font can’t be embedded.
Notice: Never modify core files!!!
For reference take a look at next code in file Zend/Pdf/Resource/Font/FontDescriptor.php from line 161 to line 199 :
// if (! $fontParser->isEmbeddable) {
// /* This exception may be suppressed if the developer decides that
// * it's not a big deal that the font program can't be embedded.
// */
// if (!($embeddingOptions & Zend_Pdf_Font::EMBED_SUPPRESS_EMBED_EXCEPTION)) {
// $message = 'This font cannot be embedded in the PDF document. If you would like to use '
// . 'it anyway, you must pass Zend_Pdf_Font::EMBED_SUPPRESS_EMBED_EXCEPTION '
// . 'in the $options parameter of the font constructor.';
// #require_once 'Zend/Pdf/Exception.php';
// throw new Zend_Pdf_Exception($message, Zend_Pdf_Exception::FONT_CANT_BE_EMBEDDED);
// }
//
// } else {
/* Otherwise, the default behavior is to embed all custom fonts.
*/
/* This section will change soon to a stream object data
* provider model so that we don't have to keep a copy of the
* entire font in memory.
*
* We also cannot build font subsetting until the data provider
* model is in place.
*/
$fontFile = $fontParser->getDataSource()->readAllBytes();
$fontFileObject = $font->getFactory()->newStreamObject($fontFile);
$fontFileObject->dictionary->Length1 = new Zend_Pdf_Element_Numeric(strlen($fontFile));
if (!($embeddingOptions & Zend_Pdf_Font::EMBED_DONT_COMPRESS)) {
/* Compress the font file using Flate. This generally cuts file
* sizes by about half!
*/
$fontFileObject->dictionary->Filter = new Zend_Pdf_Element_Name('FlateDecode');
}
if ($fontParser instanceof Zend_Pdf_FileParser_Font_OpenType_Type1 /* not implemented now */) {
$fontDescriptor->FontFile = $fontFileObject;
} else if ($fontParser instanceof Zend_Pdf_FileParser_Font_OpenType_TrueType) {
$fontDescriptor->FontFile2 = $fontFileObject;
} else {
$fontDescriptor->FontFile3 = $fontFileObject;
}
// }
I experienced this problem in Magento, while was trying to create some invoice PDF documents. So what we need to do is to copy /lib/Zend/Pdf/Resource/Font/FontDescriptor.php to /app/code/local/Zend/Pdf/Resource/Font/FontDescriptor.php and to apply the change to /app/code/local/Zend/Pdf/Resource/Font/FontDescriptor.php
Hope, that may help to somebody.
Cheers
How came?
My client sent me examples how generated PDF documents should look and he wanted custom font to be used. The font name is Gill Sans.
So I did everything needed to embed it:
protected function _setFontBold($object, $size = 10)
{
$font = Zend_Pdf_Font::fontWithPath(Mage::getBaseDir() . '/lib/GillSans/GillSans.ttf');
$object->setFont($font, $size);
return $font;
}
but got the error:
“This font cannot be embedded in the PDF document. If you would like to use it anyway, you must pass Zend_Pdf_Font::EMBED_SUPPRESS_EMBED_EXCEPTION in the $options parameter of the font constructor.”
I googled about Gill Sans embed permissions and landed on next page:
http://www.adobe.com/type/browser/legal/additional_licenses.html
From this page I understand, that I have the permission to embed Gill Sans for print and preview, but I am not allowed to embed it for edit or modifications … but seems, that Zend Framework doesn’t allow me to embed it for print and preview.
I had no time for deep research about the problem, but found the code in /lib/Zend/Pdf/FileParser/Font/OpenType.php from line 570 to line 597:
/* Describes the font embedding licensing rights. We can only embed and
* subset a font when given explicit permission.
*
* NOTE: We always interpret these bits according to the rules defined
* in version 3 of this table, regardless of the actual version. This
* means we will perform our checks in order from the most-restrictive
* to the least.
*/
$embeddingFlags = $this->readUInt(2);
$this->_debugLog('Embedding flags: %d', $embeddingFlags);
if ($this->isBitSet(9, $embeddingFlags)) {
/* Only bitmaps may be embedded. We don't have the ability to strip
* outlines from fonts yet, so this means no embed.
*/
$this->isEmbeddable = false;
} else if ($this->isBitSet(1, $embeddingFlags)) {
/* Restricted license embedding. We currently don't have any way to
* enforce this, so interpret this as no embed. This may be revised
* in the future...
*/
$this->isEmbeddable = false;
} else {
/* The remainder of the bit settings grant us permission to embed
* the font. There may be additional usage rights granted or denied
* but those only affect the PDF viewer application, not our code.
*/
$this->isEmbeddable = true;
}
The comment, that disturbed me is:
/* Restricted license embedding. We currently don't have any way to
* enforce this, so interpret this as no embed. This may be revised
* in the future...
*/
So community, do you have some experience in this area? May be you can share your thoughts.
This entry was posted on Wednesday, January 4th, 2012 at 12:10 am and is filed under Magento. You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site.
-
A Fulde
-
ceckoslab

