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?
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
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.