openSUSE:Packaging Fonts

跳转至: 导航, 搜索

字体打包 是讲如何使用 openSUSE 开放构建服务来为 openSUSE 或其他发行版打包字体的。


历史

请看 opensuse-packaging 邮件列表上的讨论 RFC: 字体源和重命名的问题. 它是从 FATE #313035 (创建一个统一的字体命名架构/中心化的字体源)这个新特性愿望演变过来的.

命名

openSUSE 字体 软件包是用小写字母命名的:

[foundryname-]projectname[-fontfamilyname][-fonttype]-fonts
[厂商名-]项目名[-字体家族名][-字体类型]-fonts
例如 jiyu-kobo-apple-snow-leopard-hiragino-sans-gb-opentype-fonts
    [厂商: 字游工房 - 项目: 苹果雪豹系统 - 家族: 柊野 - 字体类型: 无衬线国标开放式字体 - fonts]
还要适当的省略: apple-hiragino-sans-otf-fonts

当然闭源字体无法提交到 openSUSE:Factory 官方, 只能在你的私人车库中存在. 上述字体在 home:opensuse_zh 可以找到.

字体的软件包布局

  1. 上游以单独的存档包发布的字体, 如果它们不属于同一字体家族, 那么它们 必须 使用单独的源代码软件包 (src.rpm)打包.
  2. 如果字体是以一个大的一般发行存档发布的, 打包者 应该 请求上游把每个字体家族放在单独的有版本号的存档包中发布.
    1. 带有其他附属物的字体, 如程序代码, 或者不同字体家族的其他字体.
      • 如果一个项目是好几种字体家族的上游, 且这些字体家族以同样的许可发布并在同一天以同一个版本号发布, 那么作为例外, 这时以一个大的一般发行存档发布它们是可以接受的.
  3. 在源代码包的形式不和第一个 # 号里面的规则冲突的情况下, 打包者 必须 将每一个字体家族打包在单独的子软件包 (noarch.rpm) 中, 唯一可以接受的例外是:
    1. 源代码包只包含了一个字体家族并且没有其他的代码或内容 (字体的文档除外), 那么只用一个包是可以的, 不然就必须划分子软件包;
    2. 对于那些被设计使用更大的 Unicode 字符集来扩展其他的字体家族的字体家族 (比如 Arial Unicode, Droid Sans Fallback), 将该字体家族与它的母家族放到一个子软件包中也是可以接受的;
    3. 那些使用一种将不同字体家族的字体捆绑在一个文件里的格式制作的字体也可以不划分子软件包.
  4. 换句话说, 同一个字体家族的不同轻重/不同粗细的字体 必须 一起打包在同一个子软件包 (noarch.rpm) 中, 不可以再进一步划分子软件包.


澄清

  1. openSUSE 假设 “厂商” 是一个发布一系列符合字体质量标准的字体的实体. 因此一般的存放地例如 Sourceforge 不是一个厂商, 而应该是 Open Font Library 这种.
  2. 最好对厂商名用缩写.
  3. 厂商名可以省略:
    • 只发布一种字体的厂商, 或者字体项目和发布厂商是同一个机构.
  4. 如果 项目名 或者 厂商名字体家族名 中重复了, 那么 字体家族名 中可以省略该字段.
  5. 如果 厂商名, 项目名 或者 字体家族名 包含了 font 或者 fonts 后缀, 那么该后缀必须不写 (避免 foofont-fonts 这样的包名.)
  6. 如果一个软件包包括了多种不同家族, -字体家族名 应该被包含进 srpm 名.
  7. 任意字段的空格都必须用 “-” 替换.
  8. -fonts 后缀是固定的, 不随软件包里的字体数目变化.

如果仍不确定, 请咨询 opensuse-packaging 邮件列表.

实例

openSUSE:Packaging Fonts:Fontlist 中可以找到被重名好的现有字体.

从源代码包编译

一旦上游提供了源代码包, 那么字体 应该 使用源代码编译. 自动化编译保证了我们可以在字体 Bug 出现而上游又不管的时候能自行动手解决. 有时候这意味着和上游一起来优化字体的编译过程.

技术实现

如果你想要重命名 openSUSE 的老字体包,在 spec 文件中使用下面的方式来实现:

  • 在上游有新版发布之前:
 Provides:  $oldname = %{version}
 # FIXME: 这会造成一个 rpmlint 警报; 上游发布新版后把 <= 改成 < 就能解决。
 Obsoletes: $oldname <= %{version}
  • 有新版发布之后:
 Provides:  $oldname = %{version}
 Obsoletes: $oldname < %{version}

安装时 依赖

通用格式(TTF,OTF)的字体软件包属于资源类,因为 必须不能 通过直接或间接的 Requires (运行依赖) 来强行安装一个特定的字体处理器如 freetype2 等。因为字体可以用在不同的环境,包括无 X11 的环境,你不能替用户选择严重依赖环境的字处理器。

在某些情况下,在 代码片段 里执行依附环境的辅助配置命令是允许的。这些情况包括先判断了系统上是否有这些辅助配置命令,不强制安装它们到系统(可以通过 Requires(post) 之类来实现),和若它们不存在也不会阻止字体包的安装。

同样,在环境不满足则不起作用和自动检测环境的情况下,安装依附环境的配置文件也是允许的。

核心字体

曾几何时,Linux 图形界面软件使用叫做 核心字体 的服务器端 X11 后端。它造成了各种诡异的问题。自由软件的开发者们最终放弃了这种实现,宣称它是古老的和设计上有缺陷的,转到了客户端的字体处理(fontconfig)。现在几乎没有现代 Linux 图形界面软件还使用 核心字体 后端了。没几个人还会去修复这些历史遗留问题。

因此,如果不是你的字体已经被注册为 核心字体,并且由它造成的问题已有好心人修复了,你不应该声明它是核心字体。现代的 TTF 或 OTF 格式的字体都不属于曾经的核心字体类。

使用这些古老后端的用户也是不会感谢你的,因为添加新字体给它会增加它的不稳定性。他们视稳定为一切。不然他们早就像其他人一样转到 fontconfig 了。

如何选择一个新字体

网络上有许多 "自由" 字体,理论上它们都可以被打包。然而我们应该努力提高质量而不是数量。因此,下面是一些您在打包新字体之前应该回答的问题:

  • 这个字体是开源的吗?
    您应该专注于以 OFL,GPL 或其他任何自由源代码协议发布的自由字体。虽然商业字体可能更清晰,但它们根本 不能 被打包!(可以包了传到 suse.ws)
  • 该字体提供了多少字形风格?
    打包的字体至少要有常规和斜体。最好该字体也有粗体和粗斜体。极少有字体有小大写。有的也可能提供了更窄或更宽的变种,但这都不是常规例子。
小大写:就是大写字母的行高和小写字体的行高一样,但仍能分辨出大写字母。这主要用于印刷时不至于行高不一致。
  • 该字体可以用于不同语言吗?
    虽然您很少能够找到包含所有语言的字体,字体至少要支持欧洲语言。有些也支持希腊或西里尔文字。其他的也可能支持亚洲文字。字体支持的语言越多,对大多数用户越友好。
  • 该字体有多少种特殊文字?
    该问题和上一个相关。然而,有用的特殊文字还有像箭头,修饰符,数字符号,等等。

如何创建一个新字体

如下流程展示如何创建一个新字体包。

  1. 想一个好听的字体名。通用语法如下:
    [厂商名-]项目名[-字体家族名][-字体类型]-fonts

    大多数情况下,软件包名都很短。例如,如果您有一个字体项目叫 "foo",软件包名就可以是 "foo-fonts"。

  2. 在您的私人车库中创建一个新软件包 (本例中叫 "foo-fonts"):
    osc mkpac foo-fonts
  3. 从项目主页下载字体软件包存档并保存到您新创建的 foo-fonts 目录。
  4. 创建一个 spec 文件 (本例中是 foo-fonts.spec) 并填空。通常,这样的文件应该像下面这个一样:
    #
    # spec file for package foo-fonts
    #
    # Copyright (c) 2012 SUSE LINUX Products GmbH, Nuernberg, Germany.
    # 
    # All modifications and additions to the file contributed by third parties
    # remain the property of their copyright owner, unless otherwise agreed
    # upon. The license for this file, and modifications and additions to the
    # file, is the same license as for the pristine package itself (unless the
    # license for the pristine package is not an Open Source License, in which
    # case the license is the MIT License). An "Open Source License" is a
    # license that conforms to the Open Source Definition (Version 1.9)
    # published by the Open Source Initiative.
    #
    # Please submit bugfixes or comments via http://bugs.opensuse.org/
    
    # Definitions
    %define fontname foo
    
    Name:		foo-fonts
    Summary:	...
    License:	OFL-1.1
    Group:		System/X11/Fonts
    BuildArch:	noarch
    Version:	1.0
    Release:	0
    Source0:	%{fontname}-%{version}.tar.bz2
    BuildRoot:	%{_tmppath}/%{name}-%{version}-build
    ## 如果字体支持多种语言 (记为 X 和 Y) 则推荐添加下面几行:
    # Provides:       scalable-font-X
    # Provides:       scalable-font-Y
    # Provides:       locale(X;Y)
    BuildRequires:  fontpackages-devel
    %reconfigure_fonts_prereq
    URL:		http://www.example.org/foo-font
    
    %description
    Foo fonts is...
    
    Designer: Add the name of the font designer
    
    %prep
    %setup -n %{fontname}-%{version}
    # 通常留空,但必要时会在这里打补丁
    
    %build
    # 通常留空
    
    %install
    mkdir -p $RPM_BUILD_ROOT%{_ttfontsdir}
    install -m 644 *.ttf  $RPM_BUILD_ROOT%{_ttfontsdir}
    
    %reconfigure_fonts_scriptlets
    
    %files
    %defattr(-, root, root)
    # 要还有别的文件的话也添加到下面
    # %doc METADATA FONTLOG.txt OFL.txt
    %{_ttfontsdir}/*.ttf
    
    %changelog
    
  5. 创建一条修订历史并写入你的注释:
    osc vc
  6. 本地编译该软件包
    osc build --local-package openSUSE_12.2 foo-fonts.spec
  7. 如果没有错误,提交软件包:
    osc ci
  8. 检查是否编译成功:
    osc r
  9. 提交您的软件包到我们的 M17N:fonts 源:
    osc sr YOUR_REPO foo-fonts M17N:fonts

如何重命名字体

下面步骤展示了如何重命名字体包。

准备

  1. 捡出 M17N:fonts 源:
    osc co M17N:fonts
  2. 在你的浏览器里打开 Fedora 字体包列表
  3. 使用下面命令查看 M17N 的软件包列表
    osc ls M17N
  4. 从软件包列表里找出是字体的软件包,比如 LinuxLibertine
  5. 查询字体包列表,找出它的新名字,本例里是 linux-libertine-fonts
    如果找不到对应的名字,根据下面架构重命名字体包。
    [foundryname-]projectname[-fontfamilyname][-fonttype]-fonts

复制和重命名

  1. 复制 LinuxLibertine 字体到新字体源 M17N:fonts,并使用新名称:
    osc copypac M17N LinuxLibertine M17N:fonts linux-libertine-fonts
  2. 更新本地的 M17N:fonts 源。你将看到新的重命名好的字体包:
    osc update
    cd linux-libertine-fonts
  3. 重命名 .spec 文件和 .changes 变更日志到新名称:
    mv LinuxLibertine.spec     linux-libertine-fonts.spec
    mv LinuxLibertine.changes  linux-libertine-fonts.changes
  4. 打开 linux-libertine-fonts.spec.spec 文件中最重要的是下面几行:
    Name:     LinuxLibertine
    ...
    Version:  5.1.3
    
  5. Name 标签的内容改为 linux-libertine-fonts
  6. Version 标签复制版本号并插入它到 Obsoletes 标签。添加下面几行:
    # FIXME: This causes a rpmlint warning; change <= to < once there's a new upstream version
    Obsoletes:      LinuxLibertine <= 5.1.3
    Provides:       LinuxLibertine = %{version}
  7. 保存 .spec 文件。

你还可以在 M17N:fonts 源找到丰富的实例。

结尾

  1. 如果出现这样的警告是正常的:
    $ osc build openSUSE_12.1 *.spec
    [...]
    RPMLINT report:
    ===============
    linux-libertine-fonts.noarch: W: self-obsoletion LinuxLibertine <= 5.1.3 obsoletes LinuxLibertine = 5.1.3
    这个软件包把它自己标记为废弃的. 这已知在许多工具中会出错, 因此应该被避免, 通常需要在 ''废弃'' 和/或 ''提供'' 标记作业中使用合理的版本来避免无版本的上述作业.
    
    2 packages and 0 specfiles checked; 0 errors, 1 warnings.
  2. 运行 osc vc 来打开一个纯文本编辑器.
  3. 写几行变动日志并保存. 使用下面的措辞:
    Renamed LinuxLibertine --> linux-libertine-fonts according to
    Fedora packaging guidelines and FATE#313035
    Adjusted Obsoletes and Provides accordingly
    重命名 LinuxLibertine 为 linux-libertine-fonts, 
    依据是 openSUSE 打包指南和 新特性愿望 #313035
    相应的调整了 废弃 和 提供.
  4. 提交你的改动:
    osc ci
  5. 将你的改动提交到 openSUSE:Factory:
    osc submitreq -m"... 一些有用的提示 ..." openSUSE:Factory
  6. 等到你的提交被接受. 如果被拒绝了, 相应修复该软件包. :-)
  7. 将字体的旧开发源迁移到新的开发源:
    osc changedevelreq openSUSE:Factory LinuxLibertine M17N:fonts linux-libertine-fonts

自 12.2 起 BuildRequires 的变动(bdftopcf,xmkmf,imake, mkfontdir)

自 openSUSE 12.2 起,X11:XOrg 做了一些拆包与重命名,bdftopcf, imake(包含 xmkmf), mkfontdir 被拆分成了独立的子包。因此如果发现您的软件包在 openSUSE_12.2/openSUSE_Factory 的编译错误为 "bdftopcf/xmkmf/mkfontdir: Command not found." 或 "Imakefile.c:34:0: fatal error: Imake.tmpl: No such file or directory.",那么您需要本章节的修改。

因此之前打包字体常用的 BuildRequires:

BuildRequires: xorg-x11
BuildRequires: xorg-x11-devel

就需要做出一些变化。

首先说明一下老的 BuildRequires:

xorg-x11 用来提供 /usr/bin/bdftopcf,而 xorg-x11-devel 用来提供的实际上是 xorg-x11-utils-devel,该包里面包含了 xmkmf, imake 和 mkfontdir。因此 xorg-x11 不可以省略。

  • 如果报错提示为 bdftopcf,你需要:
%if 0%{?suse_version} >= 1220
BuildRequires: bdftopcf
%else
BuildRequires: xorg-x11
BuildRequires: xorg-x11-devel
%endif
  • 如果报错提示为 xmkmf/imake,你需要:
%if 0%{?suse_version} >= 1220
BuildRequires: imake //包含 xmkmf
BuildRequires: xorg-cf-files //包含 Imake.tmpl
%else
BuildRequires: xorg-x11
BuildRequires: xorg-x11-devel
%endif
  • 如果报错提示为 mkfontdir,你需要:
%if 0%{?suse_version} >= 1220
BuildRequires: mkfontdir //这是一个指向 mkfontscale 的虚包
%else
BuildRequires: xorg-x11
BuildRequires: xorg-x11-devel
%endif
  • 如果报错提示为 fc-cache,你需要:
%if 0%{?suse_version} >= 1220
BuildRequires: fontconfig
%else
BuildRequires: xorg-x11
BuildRequires: xorg-x11-devel
%endif
  • 如果报错提示为 libfreetype6.so,你需要:
%if 0%{?suse_version} >= 1220
BuildRequires: freetype2-devel
%else
BuildRequires: xorg-x11
BuildRequires: xorg-x11-devel
%endif

Fedora 中 bdftopcf 和 mkfontdir 所在的包名是 xorg-x11-font-utils,因此你需要做出相应修改:

%if 0%{?suse_version} >= 1220
BuildRequires: bdftopcf
BuildRequires: mkfontdir
%else
%if 0%{?fedora_version}
BuildRequires: xorg-x11-font-utils
%else
BuildRequires: xorg-x11
BuildRequires: xorg-x11-devel
%endif
%endif