# 字体与 FreeBSD

* 原文：[Fonts and FreeBSD](https://docs.freebsd.org/en/articles/fonts/)

## 摘要

本文档包含了与 FreeBSD 和 syscons 驱动程序、X11、Ghostscript 和 Groff 配合使用的各种字体文件的描述。提供了示例，展示如何将 syscons 显示模式切换到 80x60 模式，以及如何在上述应用程序中使用 Type 1 字体。

***

## 1. 引言

有许多字体来源可供选择，可能会有人问这些字体如何在 FreeBSD 上使用。答案可以通过仔细查阅文档来找到，特别是针对希望使用的组件。这是一个非常耗时的过程，因此本文尝试为其他感兴趣的人提供捷径。

## 2. 基本术语

有许多不同的字体格式和相关的字体文件后缀，下面列出了一些将要讨论的字体格式：

**.pfa**, **.pfb**\
PostScript® Type 1 字体。**.pfa** 是 *A*scii 格式，**.pfb** 是 *B*inary 格式。

.afm\
与 Type 1 字体相关的字体度量信息。

.pfm\
与 Type 1 字体相关的打印字体度量信息。

.ttf\
TrueType® 字体

.fot\
指向 TrueType 字体的间接引用（不是实际的字体）

.fon, **.fnt**\
位图屏幕字体

**.fot** 文件是 Windows® 用来作为指向实际 TrueType® 字体（**.ttf**）文件的符号链接。**.fon** 字体文件也由 Windows 使用。我不知道如何在 FreeBSD 上使用这种字体格式。

## 3. 我可以使用哪些字体格式？

哪种字体文件格式有用，取决于所使用的应用程序。FreeBSD 本身不使用任何字体。应用程序和/或驱动程序可能会使用字体文件。以下是应用程序/驱动程序与字体类型后缀的简要对照：

驱动程序 v&#x74;**.hex**

syscon&#x73;**.fnt**

应用程序 Ghostscrip&#x74;**.pfa**, **.pfb**, **.ttf**

X1&#x31;**.pfa**, **.pfb**

Grof&#x66;**.pfa**, **.afm**

Povra&#x79;**.ttf**

**.fnt** 后缀被广泛使用。我怀疑每当有人想为他们的应用程序创建一个特殊的字体文件时，他们往往会选择这个后缀。因此，很可能具有此后缀的文件并不全是相同的格式；特别是，FreeBSD 下 syscons 使用的 **.fnt** 文件可能与在 MS-DOS®/Windows® 环境中遇到的 **.fnt** 文件格式不同。我并没有尝试使用除 FreeBSD 提供的 **.fnt** 文件之外的其他 **.fnt** 文件。

## 4. 将虚拟控制台设置为 80x60 行模式

首先，必须加载一个 8x8 字体。为此，**/etc/rc.conf** 文件应包含以下行（根据你的语言环境更改字体名称）：

```sh
font8x8="iso-8x8"		# 从 /usr/share/syscons/fonts/* 中获取 8x8 字体（或者 NO）。
```

实际切换模式的命令是 [vidcontrol(1)](https://man.freebsd.org/cgi/man.cgi?query=vidcontrol\&sektion=1\&format=html)：

```sh
% vidcontrol VGA_80x60
```

各种基于屏幕的程序，如 [vi(1)](https://man.freebsd.org/cgi/man.cgi?query=vi\&sektion=1\&format=html)，必须能够确定当前的屏幕尺寸。由于这是通过 `ioctl` 调用到控制台驱动程序（如 [syscons(4)](https://man.freebsd.org/cgi/man.cgi?query=syscons\&sektion=4\&format=html)）来实现的，因此它们将正确地确定新的屏幕尺寸。

为了使这一过程更加顺畅，可以将这些命令嵌入到启动脚本中，以便系统启动时自动执行。为此，可以在 **/etc/rc.conf** 中添加以下行：

```sh
allscreens_flags="VGA_80x60"	# 为所有虚拟屏幕设置此 vidcontrol 模式
```

参考资料：[rc.conf(5)](https://man.freebsd.org/cgi/man.cgi?query=rc.conf\&sektion=5\&format=html)，[vidcontrol(1)](https://man.freebsd.org/cgi/man.cgi?query=vidcontrol\&sektion=1\&format=html)。

## 5. 在 X11 中使用 Type 1 字体

X11 可以使用 **.pfa** 或 **.pfb** 格式的字体。X11 字体位于 **/usr/X11R6/lib/X11/fonts** 目录下的多个子目录中。每个字体文件都通过各个目录中的 **fonts.dir** 文件与其 X11 名称进行交叉引用。

已经有一个名为 **Type1** 的目录。最直接的添加新字体的方式是将其放入此目录。更好的方法是将所有新字体保存在单独的目录中，并使用符号链接来引用额外的字体。这样可以更轻松地跟踪自己的字体，而不会与最初提供的字体混淆。例如：

```sh
创建一个目录来存放字体文件
% mkdir -p /usr/local/share/fonts/type1
% cd /usr/local/share/fonts/type1

将 .pfa、.pfb 和 .afm 文件放在这里

也可以想要在这里保留 readme 文件和其他文档

% cp /cdrom/fonts/atm/showboat/showboat.pfb .
% cp /cdrom/fonts/atm/showboat/showboat.afm .

维护一个索引以交叉引用字体
% echo showboat - InfoMagic CICA, Dec 1994, /fonts/atm/showboat >>INDEX
```

现在，要在 X11 中使用新字体，必须使字体文件可用并更新字体名称文件。X11 字体名称看起来像这样：

```sh
-bitstream-charter-medium-r-normal-xxx-0-0-0-0-p-0-iso8859-1
     |        |      |    |   |     |  | | | | | |    \    \
     |        |      |    |   |     \  \ \ \ \ \ \     +----+- 字符集
     |        |      |    |   \      \  \ \ \ \ \ +- 平均宽度
     |        |      |    |    \      \  \ \ \ \ +- 间距
     |        |      |    \	\      \  \ \ \ \ +- 垂直分辨率
     |        |      |     \	 \	\  \ \ \ +- 水平分辨率
     |        |      |      \	  \	 \  \ +- 点数
     |        |      |       \     \	  \  +- 像素
     |        |      |        \     \	   \
  字体厂商  字体家族  粗细   倾斜  宽度  额外风格
```

每个新字体都需要创建一个新的名称。如果你有字体文档中附带的信息，可以将其作为创建名称的基础。如果没有相关信息，可以通过使用 [strings(1)](https://man.freebsd.org/cgi/man.cgi?query=strings\&sektion=1\&format=html) 命令查看字体文件来获取一些线索。例如：

```sh
% strings showboat.pfb | more
%!FontType1-1.0: Showboat 001.001
%%CreationDate: 1/15/91 5:16:03 PM
%%VMusage: 1024 45747
% Generated by Fontographer 3.1
% Showboat
 1991 by David Rakowski.  Alle Rechte Vorbehalten.
FontDirectory/Showboat known{/Showboat findfont dup/UniqueID known{dup
/UniqueID get 4962377 eq exch/FontType get 1 eq and}{pop false}ifelse
{save true}{false}ifelse}{false}ifelse
12 dict begin
/FontInfo 9 dict dup begin
 /version (001.001) readonly def
 /FullName (Showboat) readonly def
 /FamilyName (Showboat) readonly def
 /Weight (Medium) readonly def
 /ItalicAngle 0 def
 /isFixedPitch false def
 /UnderlinePosition -106 def
 /UnderlineThickness 16 def
 /Notice (Showboat
 1991 by David Rakowski.  Alle Rechte Vorbehalten.) readonly def
end readonly def
/FontName /Showboat def
--stdin--
```

使用这些信息，一个可能的字体名称是：

```sh
-type1-Showboat-medium-r-normal-decorative-0-0-0-0-p-0-iso8859-1
```

我们名称的组成部分如下：

**Foundry（字体厂商）**\
我们将所有新字体命名为 `type1`。

**Family（字体家族）**\
字体的名称。

**Weight（粗细）**\
如正常、粗体、中等、半粗体等。从上面使用 [strings(1)](https://man.freebsd.org/cgi/man.cgi?query=strings\&sektion=1\&format=html) 命令输出来看，这个字体的粗细是 *medium*。

**Slant（倾斜）***roman*、*italic*、*oblique* 等。由于 *ItalicAngle* 为零，使用 *roman*。

**Width（宽度）**\
正常、宽、紧凑、扩展等。假设为 *normal*，直到字体能被检查为止。

**Additional style（额外风格）**\
通常被省略，但这将指示字体包含装饰性的大写字母。

**Spacing（间距）**\
比例间距或等宽。由于 *isFixedPitch* 为 false，使用 *proportional*。

所有这些名称都是任意的，但应尽量与现有的命名约定兼容。字体是通过名称和可能的通配符由 X11 程序引用的，因此所选名称应具有一定的合理性。可以从简单地使用

```sh
...-normal-r-normal-...-p-...
```

作为名称开始，然后使用 [xfontsel(1)](https://man.freebsd.org/cgi/man.cgi?query=xfontsel\&sektion=1\&format=html) 查看字体并根据字体的外观调整名称。

因此，完成我们的示例：

```sh
使字体对 X11 可访问
% cd /usr/X11R6/lib/X11/fonts/Type1
% ln -s /usr/local/share/fonts/type1/showboat.pfb .

编辑 fonts.dir 和 fonts.scale，添加描述字体的行，并在第一行中递增字体的数量。
% ex fonts.dir
:1p
25
:1c
26
.
:$a
showboat.pfb -type1-showboat-medium-r-normal-decorative-0-0-0-0-p-0-iso8859-1
.
:wq

fonts.scale 看起来与 fonts.dir 相同...
% cp fonts.dir fonts.scale

告诉 X11 发生了变化
% xset fp rehash

检查新字体
% xfontsel -pattern -type1-*
```

参考资料：[xfontsel(1)](https://man.freebsd.org/cgi/man.cgi?query=xfontsel\&sektion=1\&format=html)，[xset(1)](https://man.freebsd.org/cgi/man.cgi?query=xset\&sektion=1\&format=html)，《The X Windows System in a Nutshell》，[O’Reilly & Associates](http://www.ora.com/)。

## 6. 使用 Type 1 字体与 Ghostscript

Ghostscript 通过其 **Fontmap** 引用字体。这个文件必须以类似于 X11 **fonts.dir** 的方式进行修改。Ghostscript 可以使用 **.pfa** 或 **.pfb** 格式的字体。使用之前示例中的字体，以下是如何将其与 Ghostscript 一起使用：

```sh
将字体放入 Ghostscript 的字体目录
% cd /usr/local/share/ghostscript/fonts
% ln -s /usr/local/share/fonts/type1/showboat.pfb .

编辑 Fontmap 以便 Ghostscript 知道字体
% cd /usr/local/share/ghostscript/4.01
% ex Fontmap
:$a
/Showboat        (showboat.pfb) ; % 来自 CICA /fonts/atm/showboat
.
:wq

使用 Ghostscript 检查字体
% gs prfont.ps
Aladdin Ghostscript 4.01 (1996-7-10)
Copyright (C) 1996 Aladdin Enterprises, Menlo Park, CA.  All rights
reserved.
This software comes with NO WARRANTY: see the file PUBLIC for details.
从 /usr/local/share/ghostscript/fonts/tir_____.pfb 加载 Times-Roman 字体...
 /1899520 581354 1300084 13826 0 完成。
GS>Showboat DoFont
从 /usr/local/share/ghostscript/fonts/showboat.pfb 加载 Showboat 字体...
 1939688 565415 1300084 16901 0 完成。
>>showpage, 按 <return> 键继续<<
>>showpage, 按 <return> 键继续<<
>>showpage, 按 <return> 键继续<<
GS>quit
```

参考资料：Ghostscript 4.01 分发包中的 **fonts.txt**

## 7. 使用 Type 1 字体与 Groff

现在，我们可以在 X11 和 Ghostscript 中使用新字体，那么如何在 Groff 中使用这个新字体呢？首先，由于我们使用的是 Type 1 PostScript® 字体，适用于 Groff 的设备是 *ps* 设备。必须为每个字体创建一个 Groff 字体文件。Groff 字体名实际上就是 **/usr/share/groff\_font/devps** 目录中的一个文件。对于我们的示例，字体文件可以是 **/usr/share/groff\_font/devps/SHOWBOAT**。该文件必须使用 Groff 提供的工具创建。

第一个工具是 `afmtodit`。这个工具通常没有安装，因此必须从源代码分发版中获取。我发现需要修改文件的第一行，所以我做了如下操作：

```sh
% cp /usr/src/gnu/usr.bin/groff/afmtodit/afmtodit.pl /tmp
% ex /tmp/afmtodit.pl
:1c
#!/usr/bin/perl -P-
.
:wq
```

这个工具将根据字体度量文件（**.afm** 后缀）创建 Groff 字体文件。继续我们的示例：

```sh
许多 .afm 文件是 Mac 格式的，行由 ^M 分隔
我们需要将它们转换为 UNIX(R) 风格的 ^J 分隔行
% cd /tmp
% cat /usr/local/share/fonts/type1/showboat.afm |
	tr '\015' '\012' >showboat.afm

现在创建 Groff 字体文件
% cd /usr/share/groff_font/devps
% /tmp/afmtodit.pl -d DESC -e text.enc /tmp/showboat.afm generate/textmap SHOWBOAT
```

现在，字体可以通过名称 SHOWBOAT 引用。

如果系统使用 Ghostscript 驱动打印机，那么不需要做更多的操作。然而，如果使用真正的 PostScript® 打印机，则必须将字体下载到打印机中才能使用该字体（除非打印机内建 Showboat 字体或字体磁盘可访问）。最后一步是创建一个可下载的字体。使用 `pfbtops` 工具创建 **.pfa** 格式的字体，并修改 **download** 文件以引用新字体。**download** 文件必须引用字体的内部名称。可以通过查看 Groff 字体文件轻松确定这个名称，如下所示：

```sh
创建 .pfa 字体文件
% pfbtops /usr/local/share/fonts/type1/showboat.pfb >showboat.pfa
```

当然，如果 **.pfa** 已经存在，只需使用符号链接引用它。

```sh
获取内部字体名称
% fgrep internalname SHOWBOAT
internalname Showboat
告诉 Groff 字体需要被下载
% ex download
:$a
Showboat      showboat.pfa
.
:wq
```

测试字体：

```sh
% cd /tmp
% cat >example.t <<EOF
.sp 5
.ps 16
这是 Showboat 字体的示例：
.br
.ps 48
.vs (\n(.s+2)p
.sp
.ft SHOWBOAT
ABCDEFGHI
.br
JKLMNOPQR
.br
STUVWXYZ
.sp
.ps 16
.vs (\n(.s+2)p
.fp 5 SHOWBOAT
.ft R
要使用它作为段落的第一个字母，它会显示如下：
.sp 50p
\s(48\f5H\s0\fRere 是段落的第一个字母，使用 Showboat 字体。
需要额外的垂直空间来为较大的字母留出空间。
EOF
% groff -Tps example.t >example.ps

使用 Ghostscript/Ghostview
% ghostview example.ps

打印
% lpr -Ppostscript example.ps
```

参考资料：**/usr/src/gnu/usr.bin/groff/afmtodit/afmtodit.man**， [groff\_font(5)](https://man.freebsd.org/cgi/man.cgi?query=groff_font\&sektion=5\&format=html)， [groff\_char(7)](https://man.freebsd.org/cgi/man.cgi?query=groff_char\&sektion=7\&format=html)， [pfbtops(1)](https://man.freebsd.org/cgi/man.cgi?query=pfbtops\&sektion=1\&format=html).

## 8. 将 TrueType 字体转换为适用于 Groff/PostScript 格式的字体

这可能需要一些工作，因为它依赖于一些并没有作为基础系统一部分安装的工具。它们包括：

`ttf2pf`：TrueType 到 PostScript 转换工具。它允许将 TrueType 字体转换为 ASCII 字体度量文件（**.afm**）。

目前可通过 <http://sunsite.icm.edu.pl/pub/GUST/contrib/BachoTeX98/ttf2pf/> 下载。注意：这些文件是 PostScript 程序，必须通过按住 Shift 键并点击链接来下载，否则浏览器可能会尝试启动 Ghostview 来查看它们。

感兴趣的文件包括：

* **GS\_TTF.PS**
* **PF2AFM.PS**
* **ttf2pf.ps**\
  这些文件的奇怪大小写是因为它们也旨在支持 DOS shell。因此，任何重命名必须与此一致。（实际上，**GS\_TTF.PS** 和 **PFS2AFM.PS** 应该是 Ghostscript 分发版的一部分，但使用这些作为独立工具同样有效。FreeBSD 似乎没有包含后者。）你也可能希望将它们安装到 **/usr/local/share/groff\_font/devps**（？）目录下。

`afmtodit`：从 ASCII 字体度量文件创建 Groff 字体文件。通常该工具位于目录 **/usr/src/contrib/groff/afmtodit** 中，且需要一些工作才能启动。

> **注意**
>
> 如果你不想在 **/usr/src** 目录下工作，只需将上述目录的内容复制到工作位置即可。

在工作目录中，需要构建该工具。只需输入以下命令：

```sh
# make -f Makefile.sub afmtodit
```

你可能还需要将 **/usr/contrib/groff/devps/generate/textmap** 复制到 **/usr/share/groff\_font/devps/generate**，如果该文件尚不存在。

这些工具准备好后，你就可以开始操作：

1. 创建 **.afm** 文件，输入以下命令：

   ```sh
   % gs -dNODISPLAY -q -- ttf2pf.ps TTF_name PS_font_name AFM_name
   ```

   其中，*TTF\_name* 是你的 TrueType 字体文件，*PS\_font\_name* 是 **.pfa** 的文件名，*AFM\_name* 是你希望为 **.afm** 文件指定的名称。如果你没有为 **.pfa** 或 **.afm** 文件指定输出文件名，那么将使用 TrueType 字体文件名生成默认名称。

   这也会生成一个 **.pfa** 文件，即 ASCII PostScript 字体度量文件（**.pfb** 是二进制形式）。虽然这个文件不一定需要，但它（我认为）对于字体服务器可能会有用。

   例如，若要将 30f9 Barcode 字体转换为默认文件名，可以使用以下命令：

   ```sh
   % gs -dNODISPLAY -- ttf2pf.ps 3of9.ttf
   Aladdin Ghostscript 5.10 (1997-11-23)
   Copyright (C) 1997 Aladdin Enterprises, Menlo Park, CA.  All rights reserved.
   This software comes with NO WARRANTY: see the file PUBLIC for details.
   Converting 3of9.ttf to 3of9.pfa and 3of9.afm.
   ```

   如果你希望将转换后的字体存储为 **A.pfa** 和 **B.afm**，可以使用以下命令：

   ```sh
   % gs -dNODISPLAY -- ttf2pf.ps 3of9.ttf A B
   Aladdin Ghostscript 5.10 (1997-11-23)
   Copyright (C) 1997 Aladdin Enterprises, Menlo Park, CA.  All rights reserved.
   This software comes with NO WARRANTY: see the file PUBLIC for details.
   Converting 3of9.ttf to A.pfa and B.afm.
   ```
2. 创建 Groff PostScript 文件：\
   切换到 **/usr/share/groff\_font/devps** 目录以便执行以下命令。你可能需要 root 权限来执行这些命令。（如果你不想在该目录中工作，确保引用 **DESC**、**text.enc** 和 **generate/textmap** 文件，并在此目录中找到它们。）

   ```sh
   % afmtodit -d DESC -e text.enc file.afm generate/textmap PS_font_name
   ```

   其中，**file.afm** 是上面使用 `ttf2pf.ps` 创建的 *AFM\_name* 文件，*PS\_font\_name* 是该命令使用的字体名称，也是 [groff(1)](https://man.freebsd.org/cgi/man.cgi?query=groff\&sektion=1\&format=html) 用于引用此字体的名称。例如，假设你使用了第一个 `ttf2pf.ps`，那么可以使用以下命令创建 3of9 Barcode 字体：

   ```sh
   % afmtodit -d DESC -e text.enc 3of9.afm generate/textmap 3of9
   ```

   确保将生成的 *PS\_font\_name* 文件（例如上述示例中的 **3of9**）放置在 **/usr/share/groff\_font/devps** 目录中，可以通过复制或移动来完成。

   注意，如果 **ttf2pf.ps** 使用 TrueType 字体文件中的字体名称来指定字体名称，并且你希望使用不同的名称，必须在运行 `afmtodit` 之前编辑 **.afm** 文件。此名称还必须与 Fontmap 文件中的名称匹配，如果你希望将 [groff(1)](https://man.freebsd.org/cgi/man.cgi?query=groff\&sektion=1\&format=html) 输入管道传递给 [gs(1)](https://man.freebsd.org/cgi/man.cgi?query=gs\&sektion=1\&format=html)。

## 9. TrueType 字体能否与其他程序一起使用？

TrueType 字体格式被 Windows、Windows 95 和 Mac 操作系统使用，十分流行，目前有大量的字体可供选择。

遗憾的是，目前我所知道的能够使用这种格式的应用程序不多：Ghostscript 和 Povray 就是其中之一。根据文档，Ghostscript 对 TrueType 字体的支持比较初步，效果可能不如 Type 1 字体。Povray 版本 3 也能使用 TrueType 字体，但我怀疑很少有人会创建一系列的光线追踪页面来生成文档 :-)。

这种情况可能很快会有所改变。[FreeType 项目](http://www.freetype.org/) 正在开发一套有用的 FreeType 工具：

* `xfsft` 字体服务器可为 X11 提供 TrueType 字体服务，除了常规字体外。虽然目前仍处于测试阶段，但据说它非常实用。更多信息请见 [Juliusz Chroboczek 的页面](http://www.dcs.ed.ac.uk/home/jec/programs/xfsft/)。FreeBSD 的移植说明可以在 [Stephen Montgomery 的软件页面](http://math.missouri.edu/~stephen/software/) 找到。
* xfstt 是另一个 X11 字体服务器，可以在 <ftp://sunsite.unc.edu/pub/Linux/X11/fonts/> 获取。
* 一个名为 `ttf2bdf` 的程序可以从 TrueType 字体文件生成适合 X 环境使用的 BDF 文件。据说 Linux 的二进制文件可以从 <ftp://crl.nmsu.edu/CLR/multiling/General/> 获取。
* 以及其他工具...

## 10. 从哪里可以获得其他的字体？

许多字体可以在互联网上找到。这些字体要么是完全免费的，要么是共享软件。此外，许多字体也可以在 Ports 中的 **x11-fonts/** 目录中找到。

## 11. 其他问题

* **.pfm** 文件有什么用途？
* 是否可以从 **.pfa** 或 **.pfb** 文件生成 **.afm** 文件？
* 如何为具有非标准字符名称的 PostScript 字体生成 groff 字符映射文件？
* 是否可以设置 xditview 和 devX?? 设备来访问所有新的字体？
* 为 Povray 和 Ghostscript 提供使用 TrueType 字体的示例会很有用。


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://book.bsdcn.org/wen-zhang/wen-zhang/zi-ti-yu-freebsd.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
