PDF font - .afm file "bad /BBox" error - pdf

I'm working on creating PDF files in PHP with the R&OS PDF class (http://www.ros.co.nz/pdf) trying to add some more fonts to the output. It requires a TTF file and an AFM file for the metrics, but I can't get around the "bad /BBox" error as referred to in this post: Generating .afm from .ttf
At first I thought it was that I wasn't using properly made ttf files, but I've tried converting some fonts that I know are legit (Arial) and I still get the error, so now I think it must be the AFM conversion.
The Stack post above refers to http://fpdf.fruit-lab.de/ as a good conversion tool- maybe I'm just using the wrong mapping? Is there a specific map format the PDF prefers?

I ran into the same problem using dompdf http://code.google.com/p/dompdf/ which uses R&OS PDF Class for rendering so this may help you.
If you have a .ttf font skip to step 2.
Upload your font to http://www.files-conversion.com/font-converter.php (Note: This website does have .afm as an option but the output file was 3mb vs 39kb from fruit-lab) select .ttf and save it.
Upload your .ttf to http://fpdf.fruit-lab.de/ and download the .afm file.
Copy both the .ttf and .afm file to your font directory and make sure they are exactly the same name and case!
I had problems with spaces so I used CamelCase and my .ttf extension was uppercase and my .afm extension was lower case. Once I made sure I had the .afm and .ttf named in CamelCase with no spaces and lower case extensions it worked!
This is probably dompdf specific, I then had to update dompdf_font_family_cache.dist.php and include my font in the array like so:
'testscript' => array (
'normal' => DOMPDF_FONT_DIR . 'TestScript',
'bold' => DOMPDF_FONT_DIR . 'TestScript',
'italic' => DOMPDF_FONT_DIR . 'TestScript',
'bold_italic' => DOMPDF_FONT_DIR . 'TestScript',
)
Note: I only wanted one version of the font - not bold, italic etc so I just made them all point to the same font file.

Related

Table of contents sidebar in Sphinx LaTeX PDF

I am generating a LaTeX document from Sphinx, and converting it to PDF using pdflatex (from MikTeX). The document is missing a table of contents in the sidebar of the PDF viewer.
If I add manually \usepackage{hyperref} to the tex file, it works. But how can I tell Sphinx to do it in the conf.py project file? There is no (evident) related option in the latex output options.
Thanks!
Section 2.5.3 Customizing the rendering of the Sphinx document mentions:
LaTeX preamble
Additional commands may be added as preamble in the generated LaTeX file. This is easily done by editing file conf.py:
f = open('latex-styling.tex', 'r+');
PREAMBLE = f.read();
latex_elements = {
# The paper size ('letterpaper' or 'a4paper').
#'papersize': 'a4paper',
# The font size ('10pt', '11pt' or '12pt').
#'pointsize': '10pt',
# Additional stuff for the LaTeX preamble.
'preamble': PREAMBLE
}
This will copy the contents of file latex-styling.tex (in same directory as conf.py) to the generated LaTeX document. For instance, if latex-styling.tex reads:
% My personal "bold" command
\newcommand{\mycommand}[1]{\textbf{#1}}
the generated LaTeX document becomes:
% Generated by Sphinx.
\def\sphinxdocclass{report}
\documentclass[a4paper,10pt,english]{sphinxmanual}
% snip (packages)
% My personal "bold" command
\newcommand{\mycommand}[1]{\textbf{#1}}
\title{My Extension Documentation}
\date{2013-06-30 22:25}
\release{1.0.0}
\author{Xavier Perseguers}
Other options
The configuration file conf.py lets you further tune the rendering with LaTeX. Please consult http://www.sphinx-doc.org/en/stable/config.html#options-for-latex-output for further instructions.
A more direct way of adding content rather than inserting it in a separate file (say, latex-styling.tex), is to specify if verbatim. The next subsection in the documentation mentions this for a specific package typo3:
TYPO3 template
We want to stick as much as possible to default rendering, to avoid having to change the LaTeX code generation from Sphinx. As such, we choose to include a custom package typo3 (file typo3.sty) that will override some settings of package sphinx. To include it automatically, we simply use the preamble option of conf.py:
latex_elements = {
# Additional stuff for the LaTeX preamble.
'preamble': '\\usepackage{typo3}'
}
It's better to contain your styling options in a separate latex-styling.tex file that you can include using the preamble key via an f.read(). That way you don't have to update conf.py. Compartmentalization is usually better.

Convert PDF text into outlines?

Does anybody know a way to vectorize the text in a PDF document? That is, I want each letter to be a shape/outline, without any textual content. I'm using a Linux system, and open source or a non-Windows solution would be preferred.
The context: I'm trying to edit some old PDFs, for which I no longer have the fonts. I'd like to do it in Inkscape, but that will replace all the fonts with generic ones, and that's barely readable. I've also been converting back and forth using pdf2ps and ps2pdf, but the font info stays there. So when I load it into Inkscape, it still looks awful.
Any ideas? Thanks.
To achieve this, you will have to:
Split your PDF into individual pages;
Convert your PDF pages into SVG;
Edit the pages you want
Reassemble the pages
This answer will omit step 3, since that's not programmable.
Splitting the PDF
If you don't want a programmatic way to split documents, the modern way would be with using stapler. In your favorite shell:
stapler burst file.pdf
Would generate {file_1.pdf,...,file_N.pdf}, where 1...N are the PDF pages. Stapler itself uses PyPDF2 and the code for splitting a PDF file is not that complex. The following function splits a file and saves the individual pages in the current directory. (shamelessly copying from the commands.py file)
import math
import os
from PyPDF2 import PdfFileWriter, PdfFileReader
def split(filename):
with open(filename) as inputfp:
inputpdf = PdfFileReader(inputfp)
base, ext = os.path.splitext(os.path.basename(filename))
# Prefix the output template with zeros so that ordering is preserved
# (page 10 after page 09)
output_template = ''.join([
base,
'_',
'%0',
str(math.ceil(math.log10(inputpdf.getNumPages()))),
'd',
ext
])
for page in range(inputpdf.getNumPages()):
outputpdf = PdfFileWriter()
outputpdf.addPage(inputpdf.getPage(page))
outputname = output_template % (page + 1)
with open(outputname, 'wb') as fp:
outputpdf.write(fp)
Converting the individual pages to SVG
Now to convert the PDFs to editable files, I'd probably use pdf2svg.
pdf2svg input.pdf output.svg
If we take a look at the pdf2svg.c file, we can see that the code in principle is not that complex (assuming the input filename is in the filename variable and the output file name is in the outputname variable). A minimal working example in python follows. It requires the pycairo and pypoppler libraries:
import os
import cairo
import poppler
def convert(inputname, outputname):
# Convert the input file name to an URI to please poppler
uri = 'file://' + os.path.abspath(inputname)
pdffile = poppler.document_new_from_file(uri, None)
# We only have one page, since we split prior to converting. Get the page
page = pdffile.get_page(0)
# Get the page dimensions
width, height = page.get_size()
# Open the SVG file to write on
surface = cairo.SVGSurface(outputname, width, height)
context = cairo.Context(surface)
# Now we finally can render the PDF to SVG
page.render_for_printing(context)
context.show_page()
At this point you should have an SVG in which all text has been converted to paths, and will be able to edit with Inkscape without rendering issues.
Combining steps 1 and 2
You can call pdf2svg in a for loop to do that. But you would need to know the number of pages beforehand. The code below figures the number of pages and does the conversion in a single step. It requires only pycairo and pypoppler:
import os, math
import cairo
import poppler
def convert(inputname, base=None):
'''Converts a multi-page PDF to multiple SVG files.
:param inputname: Name of the PDF to be converted
:param base: Base name for the SVG files (optional)
'''
if base is None:
base, ext = os.path.splitext(os.path.basename(inputname))
# Convert the input file name to an URI to please poppler
uri = 'file://' + os.path.abspath(inputname)
pdffile = poppler.document_new_from_file(uri, None)
pages = pdffile.get_n_pages()
# Prefix the output template with zeros so that ordering is preserved
# (page 10 after page 09)
output_template = ''.join([
base,
'_',
'%0',
str(math.ceil(math.log10(pages))),
'd',
'.svg'
])
# Iterate over all pages
for nthpage in range(pages):
page = pdffile.get_page(nthpage)
# Output file name based on template
outputname = output_template % (nthpage + 1)
# Get the page dimensions
width, height = page.get_size()
# Open the SVG file to write on
surface = cairo.SVGSurface(outputname, width, height)
context = cairo.Context(surface)
# Now we finally can render the PDF to SVG
page.render_for_printing(context)
context.show_page()
# Free some memory
surface.finish()
Assembling the SVGs into a single PDF
To reassemble you can use the pair inkscape / stapler to convert the files manually. But it is not hard to write code that does this. The code below uses rsvg and cairo. To convert from SVG and merge everything into a single PDF:
import rsvg
import cairo
def convert_merge(inputfiles, outputname):
# We have to create a PDF surface and inform a size. The size is
# irrelevant, though, as we will define the sizes of each page
# individually.
outputsurface = cairo.PDFSurface(outputname, 1, 1)
outputcontext = cairo.Context(outputsurface)
for inputfile in inputfiles:
# Open the SVG
svg = rsvg.Handle(file=inputfile)
# Set the size of the page itself
outputsurface.set_size(svg.props.width, svg.props.height)
# Draw on the PDF
svg.render_cairo(outputcontext)
# Finish the page and start a new one
outputcontext.show_page()
# Free some memory
outputsurface.finish()
PS: It should be possible to use the command pdftocairo, but it doesn't seem to call render_for_printing(), which makes the output SVG maintain the font information.
I'm afraid to vectorize the PDFs you would still need the original fonts (or a lot of work).
Some possibilities that come to mind:
dump the uncompressed PDF with pdftk and discover what the font names are, then look for them on FontMonster or other font service.
use some online font recognition service to get a close match with your font, in order to preserve kerning (I guess kerning and alignment are what's making your text unreadable)
try replacing the fonts manually (again pdftk to convert the PDF to a PDF which is editable with sed. This editing will break the PDF, but pdftk will then be able to recompress the damaged PDF to a useable one).
Here's what you really want - font substitution. You want some code/app to be able to go through the file and make appropriate changes to the embedded fonts.
This task is doable and is anywhere from easy to non-trivial. It's easy when you have a font that matches the metrics of the font in the file and the encoding used for the font is sane. You could probably do this with iText or DotPdf (the latter is not free beyond the evaluation, and is my company's product). If you modified pdf2ps, you could probably manage changing the fonts on the way through too.
If the fonts used in the file are font subsets that have creative reencoding, then you are in hell and will likely have all manner of pain doing the change. Here's why:
PostScript was designed at a point when there was no Unicode. Adobe used a single byte for characters and whenever you rendered any string, the glyph to draw was taken from a 256 entry table called the encoding vector. If a standard encoding didn't have what you wanted, you were encouraged to make fonts on the fly based on the standard font that differed only in encoding.
When Adobe created Acrobat, they wanted to make transition from PostScript as easy as possible so that font mechanism was modeled. When the ability to embed fonts into PDFs was added, it was clear that this would bloat the files, so PDF also included the ability to have font subsets. Font subsets are made by taking an existing font and removing all the glyphs that won't be used and re-encoding it into the PDF. The may be no standard relationship between the encoding vector and the code points in the file - all those may be changed. Instead, there may be an embedded PostScript function /ToUnicode which will translate encoded characters to a Unicode representation.
So yeah, non-trivial.
For the folks who come after me:
The best solutions I found were to use Evince to print as SVG, or to use the pdf2svg program that's accessible via Synaptic on Mint. However, Inkscape wasn't able to cope with the resulting SVGs--it entered an infinite loop with the error message:
File display/nr-arena-item.cpp line 323 (?): Assertion item->state & NR_ARENA_ITEM_STATE_BBOX failed
I'm giving up this quest for now, but maybe I'll try again in a year or two. In the meantime, maybe one of these solutions will work for you.

Is there an "Export to Pdf" plugin for Tiddlywiki?

Has anyone put together a plugin or tool for exporting a Tiddlywiki to pdf?
No, there isn't.
As a workaround, I write or find a decent printable stylesheet, then print to PDF.
Why not select the target tiddler to "Open in new window", and print it to PDF with any installed PDF printer?
To accomplish this I used a tool to convert HTML to PDF. These steps are a bit long but well worth it. Once you've got it working it is easily repeated.
In each tiddler that I want in my PDF, I mark with a specific tag; I used TableOfContents.
In each tiddler that is marked with this tag, I added an order field--to be used to define the order of tiddlers to appear in the PDF.
Ensure your HTML headers are properly defined for the document. I think tiddler titles use <h2>, so properly defining subheadings using <h3><h4> etc will ensure, if you want, a nice auto-generated Table of Contents in your PDF.
If you want each tiddler to start on a new page (in the PDF), we need to add this HTML to the end of each tiddler:
<div style = "display:block; clear:both; page-break-after:always;"></div>
With a completed TiddlyWiki document export the tiddlers to a single HTML file--this will be used to generate a PDF document. To export, go to the AdvancedSearch, select the Filter tab. In the search textbox enter your filter criteria--for me that was:
[tag[TableOfContents]sort[order]]
You'll see, immediately, on-screen a list of the tiddlers the system found based on that criteria. Then click on the Export icon and select Static HTML.
Optionally, but I think it's a great idea, manually create a cover page (in your favorite editor)--this will be a single HTML file to act as the cover page in the PDF document; call it cover.html. More on this later.
Download and install wkhtmltopdf (command-line tool to generate PDF from an HTML file).
https://wkhtmltopdf.org/downloads.html
Learn and get familiar with the wkhtmltopdf command line syntax. There are numerous features here so the command you end up with maybe lengthy. Use wkhtmltopdf /? to view general help, then wkhtmltopdf --extended-help to view details (well worth the read).
Generate a PDF document. At the command prompt navigate to the folder where your TiddlyWiki document is located. Here is a list of my favorite command-line switches. My app is installed in C:\Program Files..., so my command line starts with that...
"c:\Program Files\wkhtmltopdf\bin\wkhtmltopdf.exe"
Add this switch for a header on the left:
--header-left "My document title"
For a header on the right:
--header-right "v1.0.0.1"
Font size of header:
--header-font-size 8
Display a line below the header:
--header-line
Spacing between header and content in mm (default 0):
--header-spacing 5
A left-footer ([section] is replaced with the name of the current section:
--footer-left "[section]"
A centered footer:
--footer-center "Page [page] of [topage]"
Footer font size:
--footer-font-size 8
Footer spacing:
--footer-spacing 5
If you want titles to hyperlink (in the PDF) to go back to the TOC:
--enable-toc-back-links
Make sure no background images get printed:
--no-background
I added special styles in the TiddlyWiki document for print media--to hide tags and clean up the spacing. Then I used this switch to ensure print media is used:
--print-media-type
Being in North America I want letter-size pages; I think the default is A4:
-s Letter
IMPORTANT--give the tool access to local files, otherwise your images will be missing in the PDF:
--enable-local-file-access
Use this if you want to have a cover page (see step 6 above):
cover "cover.htm"
And use this if you want a TOC automatically generated. Without a cover page, the TOC will be your first page, so create a cover page:
toc
After the toc identify your exported tiddler HTML file as input to the tool:
tiddlers.html
And, the final argument on the command line is the output PDF file name:
MyDocument.pdf
Export the tid to html.
Then in the terminal, issue:
html2pdf $myTid.html $myTid.pdf
$myTid is only a var and can be any name
:)

How can I allow more file extensions with drupal file uploads?

I've got a module that has to let users upload files and everything works as long as the files are in the standard array of allowed extensions. I've tried using file_validate_extensions, but this doesn't seem to change anything.
This is the code I'm using to upload now (the docx extension is added to the standard drupal allowed ones, but it doesn't seem to get picked up):
$fid = $form_state['values']['attachment'];
$file = file_load($fid);
if($file != null){
file_validate_extensions($file, "jpg jpeg gif png txt doc xls pdf ppt pps odt ods odp docx");
$file->status = FILE_STATUS_PERMANENT;
file_save($file);
}
I just looked to this Drupal API, and it seems that you can use the function "file_save_upload" (with $validator as an array of valid extension), this get the file in a temporary state. And then, you have to call "file_save" to make it permanent.

How to implement custom fonts in TCPDF

In TCPDF, there are only a few fonts to choose from, to create pdf files. I want to set Tahoma as my pdf font. How can I include Tahoma in TCPDF??
The latest TCPDF version automatically convert fonts into TCPDF format using the addTTFfont() method. For example:
// convert TTF font to TCPDF format and store it on the fonts folder
$fontname = TCPDF_FONTS::addTTFfont('/path-to-font/FreeSerifItalic.ttf', 'TrueTypeUnicode', '', 96);
// use the font
$pdf->SetFont($fontname, '', 14, '', false);
For further information and examples, please check the TCPDF Fonts documentation page.
NOTE: Once the font has been converted, TCPDF no longer requires the TTF file or the above call to addTTFfont()!
I have discovered a very good tool online.
The only thing you need to do is to upload your .ttf file and then download the files and copy then into the /fonts folder.
https://www.xml-convert.com/en/convert-tff-font-to-afm-pfa-fpdf-tcpdf
The addTTFfont method is not available on TCPDF main class so following worked for me.
// convert TTF font to TCPDF format and store it on the fonts folder
$fontname = TCPDF_FONTS::addTTFfont('pathto/arial.ttf', 'TrueTypeUnicode', '', 96);
// use the font
$pdf->SetFont($fontname, '', 14, '', false);
Hope this helps!
the below lines will generate 3 files in ur fonts folder
1.rotisserifi56.php
2.rotisserifi56.ctg
3.rotisserifi56.rar
use this to generate the required php and other files
$fontname = $this->pdf->addTTFfont('D:/wamp/www/projectname/sites/all/modules/civicrm/packages/tcpdf/fonts/Rotis Serif Italic 56.ttf', 'TrueTypeUnicode', '', 32);
// use the font
$this->pdf->SetFont($fontname, '', 14, '', false);
Now,
use the fonts like this:
$this->pdf->AddFont('rotisserifi56', '', 'rotisserifi56.php');
$this->pdf->SetFont('rotisserifi56');
--hope this helps some one :)
First create .php ,.afm,.z from http://www.xml-convert.com/en/convert-tff-font-to-afm-pfa-fpdf-tcpdf and move all three in same directory containing .ttf file.
then Use This :
$pdf->AddFont(path-to/universe.ttf','',path-to/universe.php');
$pdf->SetFont(path-to/universe.ttf','',10);
I don't know anything about tcpdf or php, but I found this:
http://www.tcpdf.org/examples/example_033.phps
Apparently you just use the font's name, not the file name.
Strike one!
Okay, how about this page. To prep a font to be used by TCPDF, you have to run the file through a command line utility and a PHP script.
$ ttf2ufm -a -F myfont.ttf
And then:
$ php -q makefont.php myfont.ttf myfont.ufm
or
MakeFont(string $fontfile, string $fmfile [, boolean $embedded [, $enc="cp1252" [, $patch=array()]]])
ttf2ufm is distributed with TCPDF in the TCPDF/fonts directory.
I found the addTTFfont method a little finicky (ok, probably didn't try very hard) and the online tool mentioned above works for FPDF but misses the ctg.z file that TCPDF requires.
This one - http://fonts.snm-portal.com/ - generates the 3 required files (.php, .z and .ctg.z) for TCPDF. Convert the TTF, upload the three files to your fonts folder and you're good to go.
the best way i have been tried and worked 100%
put your TTF font in fonts folder and then use this constant K_PATH_FONTS + FONT NAME
$font1 = $this->pdf->addTTFfont(K_PATH_FONTS . 'arial.ttf', 'TrueTypeUnicode', '', 8);
$this->pdf->SetFont($font1, '', 15, '', false);
Latest TCPDF supports custom fonts.
Documentation about using custom fonts with TCPDF can be read here.
Create new font by the following script after adding php in your path
php /path_to_tcpdf_directory/tools/tcpdf_addfont.php -i font_name.ttf,font_nameb.ttf,font_namei.ttf
Then use the font by following code
$pdf->SetFont('Font_name');
Name of the font can be found in the /path_to_tcpdf_directory/fonts/font_name.php
To add php into your environment variables, refer How to set the env variable for PHP?
There is no point in using addTTFfont() if you don't have the .ttf file.
And the whole point is: if there is NO ttf file, how can someone use addTTFfont() function?
For example, there is no cid0cs file in font/ directory (TCPDF 6.0.20), only cid0cs.php, which is NOT a font file.
I wasn't able to find addTTFFont() in the latest release of tcpdf.
However, I was able to include a custom TTF file by myself. Within the tcpdf folder is a folder named tools which include a PHP file called tcpdf_addfont.php.
I symlinked it to my home directory (you can omit this step) and run it like this:
shell
./addfont.php -b -t TrueTypeUnicode -f 32 -i myfont.ttf
That's it, it will dump something similar to this:
```
Converting fonts for TCPDF:
*** Output dir set to /Users/pascalraszyk/XXX/XXX/pdf/vendor/tecnick.com/tcpdf/fonts/
+++ OK : /Users/pascalraszyk/XXX/XXX/pdf/myfont.ttf added as myfont
Process successfully completed!
```
Note: There are more examples within the tools folder for various font types.
I used composer to checkout tcpdf.
As long as you put your font definition files in the tcpdf/fonts folder you should be good to go!
I used HTML2PDF which uses tcpdf under the hood and it worked like a charm.
I had this problem despite having all the right files. I had to change the file names to all lower case
When was not possible convert font GothamRounded standard way, I was looking for another tool and only this one http://fonts.snm-portal.com/ worked for me.