生成PDF时能处理中文、西里尔字母等的任何字体?

6
我正在使用Prawn宝石在Ruby on Rails中创建PDF文档生成器,但是遇到了一个问题,当我有中文、日文和西里尔字母时,它们显示不正确。 我通过谷歌发现这是因为“当我生成字体时,需要指定pdf文本应该用什么字体呈现”。

现在的问题不在于此,而在于我的文档将包含gTLD支持的所有不同可能的字符。

问题1:

你知道任何用于生成PDF文档的字体,将包含尽可能多的字符(亚洲、欧洲、符号等)吗?理想情况下,包括gTLD支持的所有字符。

我知道Prawn默认包括,但它专注于中文字符,我正在寻找包容性以包含所有字符(就像口袋妖怪一样,必须抓住它们所有;我知道我要求太多了,但仍然...)

另一个问题是当客户打开此文档时:

问题2:

Prawn生成的PDF文件中是否包含我的字体,以便其他计算机打开时可以使用该字体?这是默认标准吗?还是我需要确保/强制执行此功能?

请不要交叉发布。我知道你在这里的问题略有不同,但本质上是相同的。最好从根本上解决这个问题 - 即使用Ruby和Prawn。 - slhck
@slhck,这同一个问题,但我希望听到不同组别的回答。在SO上,我期望得到那些使用Prawn(或任何其他pdf转换)宝石并遇到类似问题处理该库的开发人员的答案,而在SuperUser上,我想听到那些在非编程环境中使用PDF的人给出的理论解决方案。这只是因为在SO上,我预计会得到比在SU上少得多的答案。 - equivalent8
2个回答

8
我会尽力帮助你翻译。这段内容与IT技术有关,提到了PDF字体和Unicode编码。在SuperUser上有人提出类似问题,询问是否有一种字体支持所有的Unicode字符。主要结论是没有这样的字体存在,但幸运的是PDF和prawn gem支持回退字体。下面是提供的解决方案:首先设置回退字体。
  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
       }
    )

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

2/ 调用

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

现在,我只是使用Prawn默认包含的字体,但是这样您可以添加几个具有不同字符集的字体,并将它们指定为备选字体

例如,您可以将字体放在Rails根目录的某个位置,然后从那里包含它们

注意 在“Kai”字体中,我没有加任何样式地指定了普通、斜体、粗体、粗斜体相同的字体。我故意这样做。从我的经验来看,gkai00mp字体没有粗体或斜体字符。所以当斜体/粗体字符被渲染时,它将以正常风格打印(这比不渲染要好)。

如果我不为字体(例如“Kai”)指定粗体/斜体字体..

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

...而且您尝试呈现的样式化字符将会回退到楷体字...

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

我会获取...

Prawn::Errors::UnknownFont in Foo

  is not a known font. 

注意 2:如果您想在 Ruby 文件中使用非 ASCII 字符,则需要在文件顶部放置编码。

# coding: utf-8

class Foo
...
end

然而,这只适用于 Ruby 1.9。Ruby 1.8.x 只能处理 ASCII(更多信息请参见 P.C. 的 Ruby 1.9 Walkthrough)但在 Rails 中,您应该使用 I18n(国际化)。

注3

Prawn 有非常好的文档,只需从 GitHub 克隆 prawn 并检查 ./manuals。


2

2014年,谷歌发布了Noto字体(https://www.google.com/get/noto/),该字体支持各种语言。您可以使用ttf、otf字体或嵌入完整的ttc集合来支持所需的语言。

对于中文、日文和韩文,NotoSansCJK是一个完美的选择。


有趣,知道这个很好。虽然我不再从事与这个问题相关的项目,但下次遇到这个情况时,我会尝试使用你的解决方案。 - equivalent8

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接