Ruby pdf-writer 1.1.3 and embedding fonts

I’ve been working with some interesting stuff with Ruby and PDF generating lately at work. This includes Ruby code reading one standard file format (used ie. for printing invoices by print houses here in Finland) and then converting that file format into similar looking PDF with pdf-writer Ruby library. we already had invoice generating in that file format and those print houses aren’t too good in providing services for PDF invoices if you want to archive or send PDF invoices, so we ended up using the same file and that makes invoice layout maintaining a lot easier.

Only problem with that above is that print houses provide standard and custom made layout templates which contain static graphical elements for the printed pages. Only the content text with few control codes are in the file format itself. Due this I also created small application for reading SVG files with Ruby REXML, converting the SVG files into structured arrays and hashes. From there the application writes it into Ruby code file which contains code lines for reproducing the SVG graphics in PDF with pdf-writer. So it’s sort of svg to pdf-writer rb converter. This static approach was decided for better performance. There’s no point parsing and converting the svg each time we need the static graphical elements.

The SVG converter supports about 70-80% of SVG specifications, which is all the basic stuff including the path curves for more complex graphics. This makes it possible to use other PDF files (when converted into SVG) or Adobe Illustrator (application I use here at work for vector graphics) to create invoice layouts.

Unfortunately I cannot share any of that, even if I wanted to, because that has been made during my work time.

However there’s something I can share to contribute something for all pdf-writer users. That is some help on embedding TrueType/OpenType and Type1 fonts. I had lots of troubles doing that and I did some debugging with Adobe Illustrator written PDF files and other PDF files. I had to dig the pdf-writer source code as well to see what’s going on. Not to mention the requirement for the AFM files. When I got some PDF files out I was just getting the famous “The font contains a bad /BBox” error message and it was so frusturating when the pdf-writer manual was incomplete on this matter.

Today I’m much wiser on those issues. I even had to do some changes for the pdf-writer source code to get the font-embedding to work properly. In addition to the changes I found perfect OpenSource tool called TTF2PT1 for creating the AFM/PFB files of TrueType fonts. There’s also link for downloading Windows binaries, which was great time saver for me.

First apply the patch to your pdf-writer. The patch includes replacements for the two changed files and diff files if you want to use patch instead of just replacing the files. What I changed is how the font files are handled. There even was a syntax error in the pdf-writer preventing the font embedding from working. In addition the TrueType license checking code was not working properly, atleast on the fonts I tried, so I removed that check from the code. Just make sure you’re using fonts which you are allowed to embed into your PDF files.

What the pdf-writer manual did not mention is the fact that the font files need to be renamed to same name as the FontName data in the AFM file. It just does not work unless you do that. Also the select_font() call takes the file name as parameter. My pdf-writer patch fixes select_font() a bit so you don’t have to give the .afm extension of the file name when using select_font(). That was also something the pdf-writer manual decided not to tell us.

The pdf-writer manual does tell that you need the AFM files (the PDF specification requires that information and pdf-writer doesn’t know how to extract this info by itself). You can use the TTF2PT1 program to convert TTF file into pair of AFM and PFB files. pdf-writer does prefer the PFB over TTF file if you have both in the fonts directory. To setup the fonts directories you can use the following code:

PDF::Writer::FONT_PATH << "./fonts"
PDF::Writer::FontMetrics::METRICS_PATH << "./fonts"

I prefer this, so I can have application specific font files. Copy your TTF font file(s) into that directory and use the following command to convert the font into AFM and PFB file pair:

ttf2pt1 -GFA -b -p ttf myfontfile.ttf

The open the AFM file into text editor and see the line starting with “FontName”. Take the font name and rename the 3 files with that name. For example if you had font “SF Movie Poster.ttf” you’d get files “SFMoviePoster.ttf”, “SFMoviePoster.pfb” and “SFMoviePoster.afm” because the AFM file has line “FontName SFMoviePoster”. As far I as I know the FontName should never contain spaces.

Now in pdf-writer you use this font name with select_font() method. For example:

pdf = PDF::Writer.new(:paper => "A4")
pdf.fill_color Color::RGB::Black
pdf.stroke_color Color::RGB::Black
pdf.select_font "SFMoviePoster"
pdf.add_text 10, 200, "Text with embedded font."
pdf.save_as "test.pdf"

And that’s about it. The generated PDF should open in Acrobat Reader without any error messages and the text is written with the given font. Also the font is shown as embedded font in the Acrobat document properties.

trackback | RSS feed
Posted on Tuesday, October 17th, 2006 at 15:26
Posted in Programming, Ruby

21 Responses to “Ruby pdf-writer 1.1.3 and embedding fonts”

  1. Anonymous Says:

    Ruby pdf-writer 1.1.3 and embedding fonts

    “I’ve been working with some interesting stuff with Ruby and PDF generating lately at work. This includes Ruby code reading one standard file format (used ie. for printing invoices by print houses here in Finland) and then converting that file format …

  2. Ruby pdf-writer 1.1.3 and embedding fonts at There was Code; Then there was AJAX! Says:

    […] How to embed TrueType/OpenType/Type1 fonts into generated PDF files with Ruby pdf-writer.read more | digg story Share and Enjoy:These icons link to social bookmarking sites where readers can share and discover new web pages. […]

  3. Marten, sthlm Says:

    Hello Mark, great article! Tried doing exactly as you wrote. However, i allways end up getting a pdf where the characters are replaced by squares (using preview in os X) and getting the message “The font ‘Futura-Bold’ contains a bad /BBox” (using Adobe Reader). Any ideas how to avoid this? I’ve tried using both ttf2afm (in pdfTex) and ttf2pt1 for conversion from .ttf to .afm
    Regards,
    Marten, sthlm

  4. Mark Vera Says:

    Did you use the updated version of pdfwriter I provided in the zip file? I have more recent version of it as well (with font kerning support and I think it also had the easier transformation support for text). I just haven’t had time to prepare it.

  5. Ben Jackson Says:

    Thanks so much for posting this! Just spent the last two hours banging my head against the wall to do exactly what you’ve done :)

  6. sree Says:

    can any body know how to show pdf files on the web

  7. Tom Says:

    Top job, surprised at their being such fundmental errors.

  8. Raghu Says:

    Hi Mark,

    It’s great article, looking for exactly for this.

    You said that “I also created small application for reading SVG files with Ruby REXML, converting the SVG files into structured arrays and hashes. From there the application writes it into Ruby code file which contains code lines for reproducing the SVG graphics in PDF with pdf-writer. So it’s sort of svg to pdf-writer rb converter”

    As I am new. Can you show a small working example on above procedure ?

    I have a deadline to finish this kind of procedure, I would be glad if you would be help me out.

    Thanks a lot.

  9. John Says:

    Hey Mark, nice job done.

    Can i get a working example of svg to pdf ?

    Thanks.

  10. Raghu Says:

    Hello Mark,

    Pls guide me on how to achieve svg to pdf conversion.

    Thanks a lot.

  11. Mark Vera Says:

    Thanks for the interest. I have to ask if I’m allowed to share this code at all. The changes to the PDFWriter I already put partly online. I made it into gem not too long ago though. Also I created rpdf template plugin which I have to ask if it’s okay to release that one.

    It’s not that I don’t want to release those, but the code was created during work time, so I have no say on it, besides the PDFWriter changes.

    The SVG to PDF Writer rb code converter was not that simple to do. If you omit the path part (for complex graphics), it should be fairly easy though. The PDFWriter has the basics almost 1:1 to the SVG tags.

  12. Munez Says:

    Does anyone have PDF::Reader…….I have download and use PDF::Writer and thanks alot for the embedded patch.

  13. Munez Says:

    I need the PDF::Reader to extract the text from the PDF file that I created using PDF::Writer.

    Hop someone can come out with this…I need it to complete my work done.Thanks alot!

  14. Tomasz Tomczyk Says:

    Great job, Mark.

    Thanks for your explanations, that opened up my eyes for “PDF inside” fonts related stuff.

    I also found some bugs when embedding fonts with differences (I needed to make polish chracters in the PDF). These bugs don’t apply to your fix but to orig version. Anyway I post it here maybe someone find it useful.
    So, in writer.rb file:
    - line 859: I commented it out, cause it made my special chars zero width
    - line 861: firstchar should be first_char
    - line 861: font.c[cname][’WX’] is incorrect - I suppose it should look like metrics.c[cname][’WX’]

    And finally a tip for having TTF font embedded instead of Type 1: don’t copy PFB file, only AFM and TTF into directory. As you mentioned - PDF Writer prefers PFB, so having both will cause that Type 1 (PFB) will be embedded.

    Rgrds,
    TT

  15. mace Says:

    good work! thanks a lot!!!

  16. der_flo Says:

    does anybody know a solution for pdf::writer 1.1.7 ?
    the patch cannot be applied …
    acrobat reader throws bbox errors!

    ideas?

  17. Gregory Brown Says:

    @der_flo

    We shoehorned this patch into branches/1.1 on subversion just now. Expect to see it in PDF::Writer 1.1.8+, but please help us try it out via:

    stonecode.svnrepository.com/svn/ruby_pdf/pdf-writer/branches/1.1/

    If you run into trouble, report the problem on the mailing list:
    groups.google.com/group/pdf-writer

    Thanks,
    -greg

  18. BA Says:

    Hello
    Thanks for the explanations.
    I tried to do this, the font was embedded without errors but characters are two close to each others.
    is there a solution?
    Thanks

  19. Mark Vera Says:

    You probably need the kerning changes so that the characters aren’t too close (or too far) each other. Also those changes added the character spacing for the text method in pdf writer.

  20. BA Says:

    How can I proceed so? :-)

  21. Neil Says:

    @Mark re: BA

    Any chance of getting that Kerning fix? I have the same issue.

    Thanks for the great info!

Leave a Reply