如何在 HexaPDF 中使用多种字体,即复合字体

Posted

技术标签:

【中文标题】如何在 HexaPDF 中使用多种字体,即复合字体【英文标题】:How do I use multiple fonts ie a composite font in HexaPDF 【发布时间】:2021-01-01 16:28:44 【问题描述】:

我们的用户给了我们表情符号和许多其他奇怪的字符,而内置的 Helvetica 无法处理。 Google 的 Noto 字体本身也不能——我需要弄清楚如何在 HexaPDF 中声明 Noto 字体系列,而我无法弄清楚如何使用给定的文档来做到这一点。 OpenSans 是一个改进,但我仍然想要更多的字形覆盖率。

更新:

我用这个方法设置字体:

def self.pdf_summary_font
  @@pdf_summary_font ||= File.open(Rails.root.join('public', 
'OpenSansEmoji.ttf'), 'r')
end
canvas = page.canvas(type: :overlay)
canvas.font(self.class.pdf_summary_font, size: 10)

但是,没有 Noto 字体可以使用它 - 我会收到类似“缺少字形 - 'A'”这样的错误

我能做的最好的就是使用 OpenSansEmoji,并用以下块替换丢失的字形:

  begin
    style = HexaPDF::Layout::Style.new(font: canvas.font, fill_color: color, stroke_color: color, align: :left, valign: :center)
    fragment = HexaPDF::Layout::TextFragment.create(str, style)
    layouter = HexaPDF::Layout::TextLayouter.new(style)
    layouter.fit([fragment], w, h).draw(canvas, x1, y2)
  rescue HexaPDF::Error => e
    if e.message.include?('Glyph for')
      glyph =  e.message.match(/\(.*?)\/).captures.first
      str = str.grapheme_clusters.map do |char|
        if char.dump.include?(glyph)
          "\uFFFD"
        else
          char
        end
      end.join

      retry
    end

【问题讨论】:

【参考方案1】:

查看https://hexapdf.gettalong.org/documentation/reference/api/HexaPDF/index.html 和配置选项“font_map”。这允许您声明任何 TrueType 文件并使用它。

您也可以通过Canvas#font 方法直接使用字体文件的路径。

如果您需要覆盖大量字符,则需要使用涵盖所有字符的单一字体,the fonts included in this ZIP file 中的一个应该可以工作(Google 说 582 种语言,包括 237 个地区)。

【讨论】:

@getalong,感谢您的回复,对我发布的解决方案有何意见? @EntaroAdun 您能否提供一个不适合您的示例字符串? @EntaroAdun 还可以查看“font.on_missing_glyph”配置选项 - 请参阅 hexapdf.gettalong.org/documentation/reference/api/HexaPDF/…。这允许您为丢失的字形指定自定义行为。

以上是关于如何在 HexaPDF 中使用多种字体,即复合字体的主要内容,如果未能解决你的问题,请参考以下文章

如何在C#中更改richtextbox中多种大小的字体?

如何加载同一系列的多种字体

C#/VB.NET 在Excel单元格中应用多种字体格式

如何使用 iText 获取使用多种字体呈现的 pdf

如何在窗口小部件中放置多个字体

如何确定 CRichEditCtrl 中的文本选择是不是具有多种字体大小?