Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Any font for generating pdf that will handle Chinese, Cyrillic... ?

I'm creating generator of pdf documents in Ruby on Rails with Prawn gem and I came up with issue that when I have Chinese, Japanese and Cyrillic chars they are displayed incorrectly. I googled out that it's because "when I'm generating font I need to specify, what font should pdf text be rendered with".

Now this isn't the issue, but the fact that my documents will include all different possible chars that gTLD supports.

Question 1:

Do you know any font for generating pdf documents that will include as many as possible chars (Asian, Europe, Symbols, ...)? Ideally all chars that gTLD supports.

I know that Prawn by default includes gkai00mp.ttf but its focused on Chinese chars and I'm looking for permissibility to include them all (Like PokeMon, got to catch them all; I know I'm asking for too much but still...)

Another issue is when client opens this document:

Question 2

Is pdf generated by Prawn including my font in pdf file, so when other computers open it, the font will be present? Is this by default standard? Or I need to ensure/force this functionality?

like image 494
equivalent8 Avatar asked Jun 18 '12 10:06

equivalent8


2 Answers

Ok, going to answer it by myself. On SuperUser I asked similar question (focusing on answers in more theoretical way), and the main conclusion was answer that:

There is no single font that supports the whole of Unicode.

but fortunately pdf supports fall-back fonts, and prawn gem too.

here is my solution:

1/ set your fall-back fonts

  kai = "#{Prawn::BASEDIR}/data/fonts/gkai00mp.ttf"
  action_man_path = "#{Prawn::BASEDIR}/data/fonts/Action Man.dfont"
  dejavu = "#{Prawn::BASEDIR}/data/fonts/DejaVuSans.ttf"

  font_families.update("dejavu" => {
    :normal      => dejavu,
    :italic      => dejavu,
    :bold        => dejavu,
    :bold_italic => dejavu
  })

  #Times is defined in prawn
  font_families.update("times" => {
    :normal => "Times-Roman",
    :italic      => "Times-Italic",
    :bold        => "Times-Bold",
    :bold_italic => "Times-BoldItalic"
  })

  font_families.update("action_man" => {
    :normal      => { :file => action_man_path, :font => "ActionMan" },
    :italic      => { :file => action_man_path, :font => "ActionMan-Italic" },
    :bold        => { :file => action_man_path, :font => "ActionMan-Bold" },
    :bold_italic => { :file => action_man_path, :font => "ActionMan-BoldItalic" }
  })

  font_families.update(
      "kai" => {
        :normal => { :file => kai, :font => "Kai" },
        :bold   => kai,
        :italic => kai,
        :bold_italic => kai
       }
    )

and

def fallback_fonts
  ["dejavu", "times", 'kai', 'action_man']
end

2/ call

 font("Helvetica", size: 14) do  #keyword "Helvetica" is specified in Prawn by default
   text "址 foo", :fallback_fonts => fallback_fonts 
 end

Now, here I'm just using fonts that are included in Prawn by default, but this way you can add several fonts with different charsets and just specify them as fall-back

For example you can put your fonts somewhere in your Rails root and just include them from there

note in "Kai" font, I'm specifying same font for normal, italic, bold, bold_italic without styling. I'm doing this on purpose. From what I was experiencing gkai00mp font don't have bold chars or italic chars. So when italic/bold char get rendered it will be printed in normal style (which is better than not to render at all).

If I don't specify bold/italic font for font (exaple "Kai")..

  font_families.update(
      "kai" => {
        :normal => { :file => kai, :font => "Kai" }
        }
    )

.. and you try to render styled char that will fall-back to kai...

 text "<b>址 foo</b>", :fallback_fonts => fallback_fonts, :inline_format=>true 

...I'll get

Prawn::Errors::UnknownFont in Foo

  is not a known font. 

note 2: if you want to put non-ascii chars to ruby file you need to put encoding at top of the file

# coding: utf-8

class Foo
...
end

this however works form ruby 1.9. Ruby 1.8.x source can handle ASCII only (more on that in ruby 1.9 walkthrough by P.C. but in Rails you should use I18n (internationalization)

note 3

Prawn has really great documentation, just git clone prawn from github and check ./manuals

like image 64
equivalent8 Avatar answered Sep 27 '22 22:09

equivalent8


In 2014 google has released Noto fonts (https://www.google.com/get/noto/) and that includes supports for all kinds of languages. You can use ttf, otf fonts or embed the complete collection ttc to support the language you want. For Chinese, Japanese and Korean, NotoSansCJK works perfectly.

like image 33
vsingh Avatar answered Sep 27 '22 21:09

vsingh