字体#

  • v1.16.18 新增

此类表示 MuPDF 中定义的字体(fz_font_s 结构体)。新类 TextWriter 和新的 Page.write_text() 方法需要它。目前,它与 Page.insert_text()Page.insert_textbox() 方法中使用字体的方式没有关联。

一个 Font 对象还包含一些有用的通用信息,例如字体 bbox、定义的字形数量、字形名称或单个字形的 bbox

方法 / 属性

简要描述

glyph_advance()

字符宽度

glyph_bbox()

字形矩形

glyph_name_to_unicode()

从字形名称获取 Unicode

has_glyph()

返回 Unicode 的字形 ID

text_length()

计算字符串长度

char_lengths()

字符串的字符宽度元组

unicode_to_glyph_name()

获取 Unicode 的字形名称

valid_codepoints()

支持的 Unicode 数组

ascender

字体上行高度

descender

字体下行高度

bbox

字体矩形

buffer

字体二进制图像的副本

flags

字体属性集合

glyph_count

支持的字形数量

name

字体名称

is_bold

如果是粗体则为 True

is_monospaced

如果是等宽字体则为 True

is_serif

如果是衬线字体则为 True,如果是非衬线字体则为 False

is_italic

如果是斜体则为 True

类 API

class Font#
__init__(self, fontname=None, fontfile=None,
fontbuffer=None, script=0, language=None, ordering=-1, is_bold=0,
is_italic=0, is_serif=0)

Font 构造函数。大量参数用于定位最符合要求的字体。并非所有参数都必须提供 – 请参阅下面的伪代码解释参数评估逻辑。

参数:
  • fontname (str) –

    PDF Base 14 字体 或 CJK 字体名称之一。也可以是少数其他名称(注意正确拼写):“Arial”、“Times”、“Times Roman”。

    (v1.17.5 中更改)

    如果您已安装 pymupdf-fonts,还有新的“保留”字体名称可用,这些名称列在 fitz_fonts 和下面的表格中。

  • fontfile (str) – 系统上某个位置的字体文件文件名 [1]

  • fontbuffer (bytes,bytearray,io.BytesIO) – 加载到内存中的字体文件 [1]

  • script (int) – UCDN 脚本编号。PyMuPDF 当前支持编号 24 以及 32 到 35。

  • language (str) – 值之一:“zh-Hant”(繁体中文)、“zh-Hans”(简体中文)、“ja”(日语)和“ko”(韩语)。否则,ISO 639 子集 1、2、3 和 5 中的所有代码也可能,但目前仅供文档参考。

  • ordering (int) – CJK 字体之一的替代选择器。

  • is_bold (bool) – 查找粗体字体。

  • is_italic (bool) – 查找斜体字体。

  • is_serif (bool) – 查找衬线字体。

返回:

如果成功,则返回 MuPDF 字体。这是确定合适字体的总体检查顺序:

参数

动作

fontfile?

从文件创建字体,失败时抛出异常。

fontbuffer?

从缓冲区创建字体,失败时抛出异常。

ordering>=0

创建通用字体,总是成功。

fontname?

创建 Base-14 字体、通用字体或由 pymupdf-fonts 提供的字体。参见下表。

注意

使用通常的保留名称“helv”、“tiro”等,您将创建具有预期名称“Helvetica”、“Times-Roman”等的字体。然而,与 Page.insert_font() 等方法不同的是,

  • 字体文件将始终嵌入到您的 PDF 中,

  • 支持希腊语和西里尔语字符,无需 encoding 参数。

使用 ordering >= 0,或字体名称“cjk”、“china-t”、“china-s”、“japan”或“korea”将始终创建相同的“通用”字体“Droid Sans Fallback Regular”。此字体支持所有中文、日文、韩文和拉丁字符,包括希腊语和西里尔语。这是一种无衬线字体。

实际上,您很少需要“Droid Sans Fallback Regular”之外的其他无衬线字体。此字体文件相对较大,会为您的 PDF 文件大小增加约 1.65 MB(压缩后)。如果您不需要 CJK 支持,请坚持指定“helv”、“tiro”等,您将获得约 35 KB 的压缩大小。

如果您知道文本中混合了 CJK 和拉丁字符,请考虑只使用 Font("cjk"),因为它支持所有字符,并且可以显著(最多三倍)加快执行速度:MuPDF 将始终在此单个字体中找到任何字符,无需检查回退字体。

但如果您使用了其他字体,您仍然可以自动写入 CJK 字符:MuPDF 会检测到这种情况并默默地回退到通用字体(当然,该字体也会嵌入到您的 PDF 中)。

(v1.17.5 新增) 可选地,如果您安装了 pymupdf-fonts (pip install pymupdf-fonts),则会提供一些新的“保留”字体名称代码。“Fira Mono”是一组等宽无衬线字体,“FiraGO”是另一组非衬线“通用”字体,支持所有拉丁字符(包括西里尔语和希腊语)以及泰语、阿拉伯语、希伯来语和天城文 – 但不支持任何 CJK 语言。FiraGO 字体的大小仅为“Droid Sans Fallback”大小的四分之一(压缩后 400 KB vs. 1.65 MB) – 并且它提供了粗体、斜体、粗斜体等字重,这是通用字体所不具备的。

Space Mono”是 Google Fonts 提供的另一种优秀且小巧的等宽字体,它支持拉丁语扩展字符并提供所有 4 种重要字重。

下表将字体名称代码映射到相应的字体。有关软件包的当前内容,请参阅其文档

代码

字体名称

新增于

注释

figo

FiraGO 常规体

v1.0.0

比 Helvetica 更窄

figbo

FiraGO 粗体

v1.0.0

figit

FiraGO 斜体

v1.0.0

figbi

FiraGO 粗斜体

v1.0.0

fimo

Fira Mono 常规体

v1.0.0

fimbo

Fira Mono 粗体

v1.0.0

spacemo

Space Mono 常规体

v1.0.1

spacembo

Space Mono 粗体

v1.0.1

spacemit

Space Mono 斜体

v1.0.1

spacembi

Space Mono 粗斜体

v1.0.1

math

Noto Sans Math 常规体

v1.0.2

数学符号

music

Noto Music 常规体

v1.0.2

音乐符号

symbol1

Noto Sans Symbols 常规体

v1.0.2

替代“symb”

symbol2

Noto Sans Symbols2 常规体

v1.0.2

扩展符号集

notos

Noto Sans 常规体

v1.0.3

Helvetica 的替代方案

notosit

Noto Sans 斜体

v1.0.3

notosbo

Noto Sans 粗体

v1.0.3

notosbi

Noto Sans 粗斜体

v1.0.3

has_glyph(chr, language=None, script=0, fallback=False)#

检查 Unicode 字符 chr 是否存在于字体中或(可选)某些回退字体中。可用于检查输出中是否会出现任何“豆腐”符号。

参数:
  • chr (int) – 字符的 Unicode(即 ord())。

  • language (str) – 语言 – 当前未使用。

  • script (int) – UCDN 脚本编号。

  • fallback (bool) – (v1.17.5 新增) 在回退字体中执行扩展搜索或限制为当前字体(默认)。

返回:

(1.17.7 中更改) 字形编号。零表示未找到字形。

valid_codepoints()#
  • v1.17.5 新增

返回此字体支持的 Unicode 数组。

返回:

一个长度最多为 Font.glyph_countarray.array [2]。即,此数组中每个项的 chr() 在字体中都有对应的字形,而无需使用回退字体。这是支持的字形示例显示

>>> import pymupdf
>>> font = pymupdf.Font("math")
>>> vuc = font.valid_codepoints()
>>> for i in vuc:
      print("%04X %s (%s)" % (i, chr(i), font.unicode_to_glyph_name(i)))
0000
000D   (CR)
0020   (space)
0021 ! (exclam)
0022 " (quotedbl)
0023 # (numbersign)
0024 $ (dollar)
0025 % (percent)
...
00AC ¬ (logicalnot)
00B1 ± (plusminus)
...
21D0 ⇐ (arrowdblleft)
21D1 ⇑ (arrowdblup)
21D2 ⇒ (arrowdblright)
21D3 ⇓ (arrowdbldown)
21D4 ⇔ (arrowdblboth)
...
221E ∞ (infinity)
...

注意

此方法仅对具有 CMAP(字符映射,charmap,/ToUnicode PDF 键)的字体返回有意义的数据。否则,此数组的长度将为 1,且仅包含零。

glyph_advance(chr, language=None, script=0, wmode=0)#

计算字符字形(视觉表示)的“宽度”。

参数:
  • chr (int) – 字符的 Unicode 编号。使用 ord(),而不是字符本身。同样,即使该字体不支持某个字符,这也应该正常工作,因为必要时会检查回退字体。

  • wmode (int) – 写入模式,0 = 水平,1 = 垂直。

其他参数当前未使用。

返回:

一个浮点数,表示字形相对于fontsize 1 的宽度。

glyph_name_to_unicode(name)#

返回给定字形名称的 Unicode 值。如果您想输出例如某个符号,请结合 chr() 使用。

参数:

name (str) – 字形名称。

返回:

Unicode 整数;如果名称未知,则返回 65533 = 0xFFFD。示例:font.glyph_name_to_unicode("Sigma") = 931font.glyph_name_to_unicode("sigma") = 963。有关字形名称及其 Unicode 编号的列表,请参阅 Adobe Glyph List 出版物。示例

>>> font = pymupdf.Font("helv")
>>> font.has_glyph(font.glyph_name_to_unicode("infinity"))
True

glyph_bbox(chr, language=None, script=0)#

字形矩形,相对于 fontsize 1。

参数:

chr (int) – 字符的 ord() 值。

返回:

一个 Rect 对象。

unicode_to_glyph_name(ch)#

显示字符字形的名称。

参数:

ch (int) – 字符的 Unicode 编号。使用 ord(),而不是字符本身。

返回:

一个表示字形名称的字符串。例如 font.glyph_name(ord("#")) = "numbersign"。对于无效代码,返回“.notfound”。

注意

(v1.18.0 中更改) 此方法和 Font.glyph_name_to_unicode() 不再依赖于字体,而是从 Adobe Glyph List 中检索信息。也可作为 pymupdf.unicode_to_glyph_name()pymupdf.glyph_name_to_unicode() 使用。

text_length(text, fontsize=11)#

计算 Unicode 字符串的点数长度。

注意

对于 Base-14 字体,与 get_text_length() 存在功能重叠。

参数:
  • text (str) – 文本字符串,UTF-8 编码。

  • fontsize (float) – fontsize

返回类型:

float

返回:

字符串在 PDF 中存储时的点数长度。如果字体中不包含某个字符,它将自动在回退字体中查找。

注意

此方法最初是基于调用 Font.glyph_advance() 在 Python 中实现的。出于性能原因,它在 v1.18.14 中已用 C 重写。现在您可以使用以下任一方式计算单个字符的宽度,且无性能损失:

  1. font.glyph_advance(ord("Ä")) * fontsize

  2. font.text_length("Ä", fontsize=fontsize)

对于多字符字符串,此方法与之前的实现相比具有巨大的性能优势:每个字符大约需要 0.5 微秒,而第二个及后续字符仅需 12.5 纳秒。

char_lengths(text, fontsize=11)#

v1.18.14 新增

Unicode 字符串的字符长度序列(点数)。

参数:
  • text (str) – 文本字符串,UTF-8 编码。

  • fontsize (float) – fontsize

返回类型:

tuple

返回:

字符串在 PDF 中存储时字符的点数长度。它类似于 Font.text_length() 分解到单个字符。这是一个高速方法,例如在 TextWriter.fill_textbox() 中使用。以下断言成立(允许舍入误差):font.text_length(text) == sum(font.char_lengths(text))

>>> font = pymupdf.Font("helv")
>>> text = "PyMuPDF"
>>> font.text_length(text)
50.115999937057495
>>> pymupdf.get_text_length(text, fontname="helv")
50.115999937057495
>>> sum(font.char_lengths(text))
50.115999937057495
>>> pprint(font.char_lengths(text))
(7.336999952793121,  # P
5.5,                 # y
9.163000047206879,   # M
6.115999937057495,   # u
7.336999952793121,   # P
7.942000031471252,   # D
6.721000015735626)   # F

buffer#
  • v1.17.6 新增

二进制字体文件内容的副本。

返回类型:

bytes

flags#

包含各种字体属性的字典,每个属性表示为布尔值。Helvetica 的示例:

>>> pprint(font.flags)
{'bold': 0,
'fake-bold': 0,
'fake-italic': 0,
'invalid-bbox': 0,
'italic': 0,
'mono': 0,
'opentype': 0,
'serif': 1,
'stretch': 0,
'substitute': 0}
返回类型:

dict

name#
返回类型:

str

字体名称。可能为“”或“(null)”。

bbox#

字体 bbox。这是其字形 bbox 的最大值。

返回类型:

Rect

glyph_count#
返回类型:

int

字体中定义的字形数量。

ascender#
  • v1.18.0 新增

字体的上行高度值,详情请参阅 上行高度 排版学。请注意,这与严格定义有所不同:我们的值包括基线上方的一切 – 而不仅仅是大写“A”和小写“a”之间的高度差。

返回类型:

float

descender#
  • v1.18.0 新增

字体的下行高度值,详情请参阅 下行高度 排版学。此值总是负数,表示某些字形(例如“g”或“y”)下降到基线以下的部分。因此,ascender - descender 的值是字体中每个字形可以容纳的总高度。至少对于大多数字体来说是如此 – 一如既往,也有例外情况,特别是对于书法字体等。

返回类型:

float

is_bold#
is_italic#
is_monospaced#
is_serif#

一系列含义明确的属性。反映 Font.flags 字典中的一些值。

返回类型:

bool

脚注


本软件按“原样”提供,不附带任何明示或暗示的担保。本软件根据许可协议分发,除非该许可协议明确授权,否则不得复制、修改或分发。有关许可信息,请参阅 artifex.com,或联系 Artifex Software Inc., 39 Mesa Street, Suite 108A, San Francisco CA 94129, United States 获取进一步信息。