33

我不敢相信这个问题没有专门针对 OpenType 字体提出,但有人知道从这些字体中删除字形的方法吗?

我有一个非常大的文件大小(几乎 10MB)的 .OTF,我需要使它更小。原因有两个。

1)我正在尝试为网络嵌入做准备,所以文件越小,客户端就越容易。

2) Font Squirrel(用于轻松准备字体文件)有 2MB 的上传限制 - 我知道有替代方案,但到目前为止还没有成功。为了节省浪费人们的时间,我尝试过的失败的是http://fontface.codeandmore.com/http://www.font2web.com/。CodeAndMore.com 似乎可以工作,但它吐出的字体与我给它的字体完全不同。

请注意,我不是字体专家,所以请轻松回答。

4

8 回答 8

25

我用fontforge 库编写了一个 Python2 脚本,它执行以下操作:

  • 接受源字体
  • 接受包含要使用的所有字符的文件。它可以是翻译文件、字符串资产文件、HTML 文件等。
  • 输出包含文件中未显示的字符的字体已删除

这是代码:

#!/usr/bin/python2
import sys
import fontforge

if len(sys.argv) == 4:
    font = fontforge.open(sys.argv[1])

    with open(sys.argv[2], "r") as f:
        for i in f.read().decode("UTF-8"):
            font.selection[ord(i)] = True

    font.selection.invert()

    for i in font.selection.byGlyphs:
        font.removeGlyph(i)

    font.generate(sys.argv[3])
else:
    print "WARNING: Check the license of the source font\nbefore distributing the output font generated by this script.\nI'm not responsible for any legal issue caused by\ninappropriate use of this script!\n"
    print "Usage: {} [source font] [file with glyphs NOT to be removed] [output]".format(sys.argv[0])
    print "Example: {} /path/to/ukai.ttc chineseTranslation.txt ukaiStripped.ttf".format(sys.argv[0])

请注意,在某些字体上使用此脚本可能是不合法的。确保签出源字体的许可证。对于因使用此脚本生成的任何字体而引起的任何法律问题,我概不负责。

于 2015-12-07T11:50:50.087 回答
22

FontTools 有一个名为 pyftsubset 的程序可以做到这一点

https://github.com/behdad/fonttools

用法是这样的:

pyftsubset MyFont.otf --output-file=MyFontStripped.otf --unicodes-file=file-of-codes.txt

其中 file-of-codes.txt 包含以下代码列表:

U+09c78
U+09ce5
U+09ce7
U+09ce9
U+09ceb
U+09cec
U+09cf0
U+09cf3
U+09cf4
U+09cf6
...
于 2016-05-11T09:58:28.237 回答
4

以下最新评论:您可以一次在左侧菜单(语言)中使用 shift 和 command 键一次选择多组。请注意,图像保留了基本拉丁语 (AZ az)。选择集合后,单击字形窗口并全选 (cmd-A)。如果像这种情况有很多,这将需要一些时间。然后 cmd-Delete 删除所有内容。您只需要使用“类别”重复操作即可。然后导出 .otf

类别选择 语言选择

于 2013-02-08T18:56:37.397 回答
3

10 MB 的 Opentype 字体非常罕见,因为它非常重,所以我认为它是内部特定字体而不是商业字体。要删除字形,您可以在FontForge(免费)或任何其他商业字体编辑器中编辑字体,然后重新生成 .otf(也是 .ttf)

要构建 webfonts(我猜你需要 .ttf、.svg、.eot 和 .woff),你可以在本地使用几个免费工具:sfnt2woffttf2eotBatik SVGttfautohint ,你可以改进字体在进行转换之前的屏幕。

于 2013-01-28T16:38:05.017 回答
3

今天遇到这个问题,因为我试图在 CTRL+A 之后保存字体并设置宽度(不要那样做,顺便说一句)。因为我已经在 FontForge 中打开了字体,所以我采用了更直接的 Python 脚本方法。

这假设您打开了预期的字体并使其处于活动状态。它还假设您只想保留前 128 个字符(ASCII 范围)。它选择所有内容,然后使用“less”标志取消选择 0-127 的范围。查看FontForge Python 脚本指南,了解更多关于操作选择的不同方式的信息。

文件 > 执行脚本

font = fontforge.activeFont()
font.selection.all()
font.selection.select(("ranges","less"),0,127)
font.clear()
于 2019-04-27T06:13:57.827 回答
1

正如其他人所指出的,您可以使用fonttools从字体中删除不需要的字形。

安装很简单pip

pip install fonttools

然后,您可以使用pyftsubset函数将字体限制为字符子集。例如,如果您只想保留基本的拉丁字符(标点符号、数字、字母):

pyftsubset myFont.otf --output-file=mySmallerFont.otf --unicodes=U+0020-007E

也可以同时转换字体:

pyftsubset myFont.otf --output-file=mySmallerFont.woff --flavor=woff --unicodes=U+0020-007E

请注意,如果您需要转换为 woff2,则必须先安装brotli,使用pip install brotli.

完整的文档可在此处获得。

于 2021-02-17T08:54:28.933 回答
1

fonttools现已被 Google 采用:https ://github.com/googlei18n/fonttools 。我一直在使用它来减少Google 的 Noto 字体中用于嵌入式系统的字形数量。工作一种享受!

于 2018-07-04T13:50:45.873 回答
0

@remeus 的回答启发了我,但我不想直接使用pyftsubset.exe fontTools.subset;我想使用该脚本,因为我可以轻松地向其中添加一些内容。

代码

import fontTools.subset
from pathlib import Path
import os

SOURCE_FILE = Path('YOUR.ttf') # ttf, otf, ...
OUT_FORMAT = 'woff' # otf, woff, woff2, ...
TEXT_FILE = Path('YOUR.txt')

def main():
    output_file = Path('temp') / Path(SOURCE_FILE.stem + '.' + OUT_FORMAT)
    output_file.parent.mkdir(parents=True, exist_ok=True)
    args = [SOURCE_FILE,
            f"--output-file={output_file}",
            # f"--text=中英文 abcdefg",
            f"--text-file={TEXT_FILE}",  # 中英文 abcdefg
            # "--unicodes=U+0020-007E",
            f"--flavor={OUT_FORMAT}",
            #  https://github.com/fonttools/fonttools/blob/1df4f1e/Lib/fontTools/subset/__init__.py#L332-L337
            "--verbose=true", # https://github.com/fonttools/fonttools/blob/1df4f1e/Lib/fontTools/subset/__init__.py#L3015
            # "--xml=true",
            "--timing=true",
            ]
    fontTools.subset.main([str(_) for _ in args])
    os.startfile(output_file.parent)


if __name__ == "__main__":
    main()

解释

以下是指定所需子集的三种方法

  1. --text: 直接写

  2. --text-file: 将文本写入文件中(重复也没关系,代码会自动为你删除)(我推荐这种方式。

    例子:

    我的.txt (utf-8)

    0123456
    abcdefg
    ABCDEFG
    中英文
    
  3. --unicodes: 使用 unicode 范围

如果您需要转换为 woff2,则必须先使用 pip install brotlicffi 安装brotli

理由:

其他问题

下面是间接问题。不想看的可以直接跳过这一段。

这是我的经验,我想在浏览器上使用字体,但出现如下错误

OTS解析错误:网页字体大小超过30MB

我的字体大小

  • 大小:40MB
  • 格式:ttf

因此,如果我将格式更改为 Woff 或 Woff2 可能会解决问题。

不过,您可以再次使用 fontTools

TTFont(Path()).save(Path())

当您的文件很大时,它会花费太多时间。

包裹

字体工具

于 2021-06-21T11:00:06.570 回答