openSUSE:Packaging Fonts

Jump to: navigation, search


The Packaging Fonts is an overview on how to build font packages for openSUSE and others using the openSUSE Build Service.

Purpose

This page is intended to define a common set of rules for package names, its content, and other related information.

How to Select a New Font

There are lots of "free" fonts out there which could theoretically be packaged. However, we should strive for quality, not quantity. Therefore, here are some guidelines you should answer first before you package a new font at all:

  • Is the font open source?
    You should focus on free fonts released under the OFL, GPL, or any other open or free source license. Although it should be clear, but commercial fonts MUST NOT be packaged at all!
  • Is the font already packaged?
    Before you package a new font, always look into M17N:fonts repository first. Search for similar package names.
  • How many font styles does the font bring with?
    Try to package fonts which have at least a regular and italic style. Preferably the font has also bold and italic+bold (that would make four styles). Sometimes, a font comes with small caps, other brings a condensed or wider variant, but this is not the usual case.
  • Can the font be used for different languages?
    Although you rarely will find a font which contains all possible languages, look for fonts which supports at least European languages. Some contains also Greek or Cyrillic glyphs. Others may support Asian characters. The more languages a font supports, the better will it be for the majority of users.
  • How many glyphs does the font have?
    This question is related to the previous one. However, there are more useful glyphs like arrows, dingbats, mathematical symbols, etc. Additional glyphs make it easier to use them for other purposes, like programming or specific texts.

Naming and Central Font Repository

Think of a good font name. The general syntax is this (all lower-case):

[foundryname-]projectname[-fontfamilyname][-fonttype]-fonts

Here is more detailed explanation

  • foundryname: Usually the name of the designer or a type foundry
  • projectname: the name of the font project
  • fontfamilyname: if the project contains different font families, specify it here
  • fonttype: subsitute 'bitmap' in case you package a bitmap font

In most cases, the package name is pretty short. For example, if you have a font project "foo", the package name will be "foo-fonts".

Almost all font packages are located in the M17N:fonts repository now.

See discussion on opensuse-packaging mailinglist RFC: Fonts Repo and Renaming Questions. It also evolved from FATE #313035 (Invent Consistent Font Naming Schema/Central Font Repository).

See M17N:fonts for names of packages and subpackages or the list of renamed packages in openSUSE:Packaging Fonts:Fontlist.

Package content

Fonts are different and so the project pages and their archives. Some projects just publish an archive and nothing else, others bring a specimen or additional information.

If possible, try to package these additional information in %{_docdir}/PACKAGENAME.

Package Layout for Fonts

Consider how you split your package into subpackages. Best practices are

  1. to spent one (noarch) rpm for one family and
  2. do not spread font files of one family over more rpms.

These rules are not binding though, you will meet some counterexamples in M17N:fonts for sure.

How to Create a New Font Package

The following procedure shows how to create a new font package.

  1. Create a new package in your home project (in our case "foo-fonts"):
    osc mkpac foo-fonts

    If you don't have a local copy of your home project yet, you can create one by:

    osc co home:yourname
  2. Download the font package archive from the project's home page and save it to your newly created foo-fonts directory.
  3. Create a spec file (in our case, it's foo-fonts.spec) and fill in the gaps. Usually, such file looks like this:
    #
    # spec file
    #
    # Copyright (c) 2022 SUSE LLC
    # 
    # 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 https://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
    Source:	%{fontname}-%{version}.tar.bz2
    ## If the font supports several languages (denoted as X and Y), it's recommended
    ## to add the following lines:
    # Provides:       scalable-font-X
    # Provides:       scalable-font-Y
    # Provides:       locale(X;Y)
    # You can do it conveniently with
    # %{lua: 
    # l = "X;Y;" 
    # print (string .gsub (l, "(%a+);", "Provides:       scalable-font-%1\n"), "\n") 
    # print (string .sub (l, 1, string .len (l) - 1)) }
    BuildRequires:  fontpackages-devel 
    BuildRequires:  unzip # only if zipped
    %reconfigure_fonts_prereq
    URL:		http://www.example.org/foo-font
    
    %description
    Foo fonts is...
    
    Designer: Add the name of the font designer
    
    %prep
    %autosetup -p1 -n %{fontname}-%{version}
    # Usually empty, but insert fixes here, if necessary
    
    # Zipped fonts require unzip and prepare like this:
    # %setup -cT
    # %{uncompress:%{S:0}}
    
    %build
    # Usually nothing to do
    
    %install
    install -d '%{buildroot}%{_ttfontsdir}
    install '-t%{buildroot}%{_ttfontsdir}' -m 644 *.ttf 
    
    # call fonts-config after installation or deinstallation of this package
    %reconfigure_fonts_scriptlets
    
    %files
    # Include additional content for the font package, if available
    # %doc METADATA FONTLOG.txt OFL.txt
    %{_ttfontsdir}
    
    %changelog
    
  4. Create a changelog and write your comment:
    osc vc
  5. Build the package locally:
    osc build --local-package 15.4 foo-fonts.spec
  6. If there are no errors, commit the font package:
    osc ci
  7. Check if everything is built correctly:
    osc r
  8. Submit your package to our M17N:fonts repository:
    osc sr YOUR_REPO foo-fonts M17N:fonts

RPM macros

Using rpm macros in font packages is highly recomended. Every font package should buildrequire fontpackages-devel and use macros defined in /etc/rpm/macros-fontconfig. That is because:

  1. changing common font package behaviour is centralized that way on one place and
  2. spec files using them can be more clear.

Examples

Here are some example packages with simple spec files:

How to Update an Existing Font Package

If you want to update a font to a newer version or you found a bug, the following procedure shows how to do it:

  1. Open a shell and branch the existing font package on M17N:fonts:
    osc bco M17N:fonts FONTPACKAGE

    The osc script checks out the font package and saves it into home/USER/branches/M17N/fonts/FONTPACKAGE (if you have set checkout_no_colon=1 in your ~/.oscrc config file). This will be your current working directory.

  2. Download the new package and save it into your working directory. Usually you can find the package from the project's homepage.
  3. Change the version number in the spec file.
  4. If needed, add patches or other requirements into the spec file (usually mostly not needed).
  5. Write a meaningful changelog entry:
    osc vc

    (Probably you find information about the changes in the Changelog file if included into the archive, or on the project's homepage).

  6. Remove the old archive and add the new one:
    osc rm OLD_ARCHIVE
    osc add NEW_ARCHIVE
  7. Build your package and fix any errors (you may replace openSUSE_Factory with your preferred distribution):
    osc build openSUSE_Factory *.spec
  8. Commit all your changes:
    osc ci
  9. Submit your changes back to the M17N:fonts repository:
    osc sr -m"Updated to version x.y"

Your submission will be reviewed and if it conforms to our packaging rules it will be accepted. In case it is declined, you will be informed about the reason. Fix the errors or problems and submit it again (probably you may want to combine the -s option (superseding another request by this one) with your sr command).

Font Package with More Families

Many packages don't split into subpackages even if it contains more font families. Nevertheless, when you want to give users the chance to choose which family from your package to install, then you will have to split your font package in subpackages.

As a general rule of thumb: split a font into several packages, if it's "big". For "big" there is no exact definition, but a font can be considered "big" if it contains more than one font families or has lots of files which lead to a monstrous file size.

The spec file can look like:

#
# spec file
#
# Copyright (c) 2022 SUSE LLC
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, 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 https://bugs.opensuse.org/
#

%define projname bar

Name:           bar-fonts
Version:        2.0
Release:        0
Summary:        ...
License:        OFL.1.1
Group:          System/X11/Fonts
Url:            ...
Source0:        %{projname}-%{version}.tar.bz2
BuildRequires:  fontpackages-devel
%reconfigure_fonts_prereq
BuildRoot:      %{_tmppath}/%{name}-%{version}-build
BuildArch:      noarch

%description
...

%package -n %{projname}-family1-fonts
Summary:        ...
Group:          System/X11/Fonts

%description -n %{projname}-family1-fonts
...

%package -n %{projname}-family2-fonts
Summary:        ...
Group:          System/X11/Fonts

%description -n %{projname}-family2-fonts
...

%package -n %{projname}-family3-fonts
Summary:        ...
Group:          System/X11/Fonts

%description -n %{projname}-family3-fonts
...

%prep
%setup -q -n %{projname}-%{version}

%build

%install
mkdir -p %{buildroot}%{_ttfontsdir}
for i in *.ttf
do
    install -m 644 $i %{buildroot}%{_ttfontsdir}
done

%reconfigure_fonts_scriptlets -c -n %{projname}-family1-fonts

%reconfigure_fonts_scriptlets -c -n %{projname}-family2-fonts

%reconfigure_fonts_scriptlets -c -n %{projname}-family3-fonts

# main package can be also empty, then don't inclue %files section
# at all
%files
# Include common content for the font package, if available
# %doc METADATA FONTLOG.txt


%files -n %{projname}-family1-fonts
%license OTF.txt
%dir %{_ttfontsdir}/
%{_ttfontsdir}/family1.*

%files -n %{projname}-family2-fonts
%license OTF.txt
%dir %{_ttfontsdir}/
%{_ttfontsdir}/family2.*

%files -n %{projname}-family3-fonts
%license OTF.txt
%dir %{_ttfontsdir}/
%{_ttfontsdir}/family3.*

%changelog

Examples

Packaging Fontconfig Files along Font Package

It may happen that you want to package a fontconfig file along with your font files. There's no policy that the fontconfig file should be part of fontconfig package itself, so you are encouraged to include it in your font package. With one exception: mapping to generic names serif, sans-serif, monospace, cursive and fantasy. Especially <default> alias: it is intended to help fontconfig to find similar fonts to yours when yours are not installed, so packaging it along with your package will evidently not work.

The fontconfig file can be shipped inside upstream tarball or you can add it as package source.

There's no strict rules for the name of the fontconfig file except common ones for fontconfig files (see /etc/fonts/conf.d/README). If you want to use the RPM macro %install_fontsconf, you have to ensure that the name of the fontconfig file is identical to that one you want to have in /etc/fonts/conf.d.

In following spec file example, we want to install /etc/fonts/conf.d/31-foo-fonts.conf, so the file name in package source is 31-foo-fonts.conf. If the fontconfig file is part of the upstream tarball, you have to either rename it manually or don't use the %install_fontsconf RPM macro (i. e. install it manually).

Example spec file follows; it packages one fontconfig file.

#
# spec file
#
# Copyright (c) 2022 SUSE LLC
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, 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 https://bugs.opensuse.org/
#


%define fontname foo

Name:           foo-fonts
Version:        3.0
Release:        0
Summary:        ...
License:        GPL-2.0-with-font-exception
Group:          System/X11/Fonts
Url:            ...
Source0:        %{fontname}-%{version}.tar.bz2
Source1:        31-%{fontname}-fonts.conf
BuildRequires:  fontconfig
BuildRequires:  fontpackages-devel
%reconfigure_fonts_prereq
BuildRoot:      %{_tmppath}/%{name}-%{version}-build
BuildArch:      noarch

%description
...

%prep
%setup -q -n %{fontname}

%build

%install
mkdir -p %{buildroot}%{_ttfontsdir}/
install -m 0644 *.otf %{buildroot}%{_ttfontsdir}
%install_fontsconf %{SOURCE1}

%reconfigure_fonts_scriptlets

%files
%doc COPYING README
%{_ttfontsdir}
%files_fontsconf_availdir
%files_fontsconf_file -l 31-linux-libertine.conf

%changelog

Note there are few essential additions compared to simple font package:

  • Adding configuration file into package sources
    Source1:        31-%{fontname}-fonts.conf
  • Adding build requirements for fontconfig:
    BuildRequires:  fontconfig
  • Installing fontconfig file into availdir (currently /usr/share/%{name}/conf.avail defined in %{_fontsconfavaildir} RPM macro) and link it into confdir (currently /etc/fonts/conf.d defined in %{_fontsconfddir} RPM macro) with
    %install_fontsconf %{SOURCE1}
  • Adding availdir to the package file list
    %files_fontsconf_availdir
  • Adding configuration file itself into file list; -l switch tells macro to include confdir link:
    %files_fontsconf_file -l 31-linux-libertine.conf

Including fontconfig files in fontpackage is not very common, though. At the time of writing, only 9 packages out of 141 in M17N:fonts do so.

Examples

  • linux-libertine-fonts -- includes one fontconfig file as package source
  • wqy-bitmap-fonts -- installs one fontconfig file shipped in upstream tarball
  • wqy-zenhei-fonts -- installs three fontconfig files (manually) but links only one to the system config
  • stix-fonts -- includes more fontconfig files as package source, installs one per subpackage
  • thai-fonts -- includes two fontconfig files but doesn't link them in confddir
  • cantarell-fonts -- installs one fontconfig file through native build process and link it into system config

Notes

How to Rename a Font

The following procedures show how to rename font package.

Preparing

  1. Check out the M17N:fonts repository:
    osc co M17N:fonts
  2. Open the Fedora Font Package List in your browser
  3. Get a listing of the M17N repository with:
    osc ls M17N
  4. Grab a font in this list, for example LinuxLibertine.
  5. Search the name in the above link to see which is the new name. In this case, it's linux-libertine-fonts.
    If you cannot find an equivalent package name, use the following naming schema:
    [foundryname-]projectname[-fontfamilyname][-fonttype]-fonts

Copying and Renaming

  1. Copy the LinuxLibertine font to the new font repository M17N:fonts and use the new name:
    osc copypac M17N LinuxLibertine M17N:fonts linux-libertine-fonts
  2. Update your M17N:fonts repository. You will get the new renamed font package:
    osc update
    cd linux-libertine-fonts
  3. Rename the .spec and .changes files to their new names:
    mv LinuxLibertine.spec     linux-libertine-fonts.spec
    mv LinuxLibertine.changes  linux-libertine-fonts.changes
  4. Open the file linux-libertine-fonts.spec. The important lines of the .spec file looks like this:
    Name:     LinuxLibertine
    ...
    Version:  5.1.3
    
  5. Change the content of the Name keyword to linux-libertine-fonts.
  6. Copy the version number from the Version keyword and insert it into the Obsoletes keyword. Add the following lines:
    # FIXME: This causes a rpmlint warning; change <= to < once there's a new upstream version
    Obsoletes:      LinuxLibertine <= 5.1.3
    Provides:       LinuxLibertine = %{version}
  7. Save the .spec file.

You can also see plenty examples in the M17N:fonts repository.

Finishing

  1. Build the package, the warning is normal and is expected:
    $ osc build openSUSE_12.1 *.spec
    [...]
    RPMLINT report:
    ===============
    linux-libertine-fonts.noarch: W: self-obsoletion LinuxLibertine <= 5.1.3 obsoletes LinuxLibertine = 5.1.3
    The package obsoletes itself.  This is known to cause errors in various tools
    and should thus be avoided, usually by using appropriately versioned Obsoletes
    and/or Provides and avoiding unversioned ones.
    
    2 packages and 0 specfiles checked; 0 errors, 1 warnings.
  2. Run osc vc to open an editor.
  3. Write some changelog lines and save it. We used the following wording:
    Renamed LinuxLibertine -> linux-libertine-fonts according to
    Fedora packaging guidelines and FATE#313035
    Adjusted Obsoletes and Provides accordingly
  4. Commit your changes:
    osc ci
  5. Submit your changes to factory:
    osc submitreq -m"... some meaningful message ..." openSUSE:Factory
  6. Wait until your submit request is accepted. If your submit request was declined, fix the problems. :-)
  7. Change the devel repository of the old font to the new repository:
    osc changedevelreq openSUSE:Factory LinuxLibertine M17N:fonts linux-libertine-fonts

BuildRequires Changes since 12.2 (bdftopcf,xmkmf,imake, mkfontdir)

Since openSUSE 12.2, X11:XOrg project split and changed some packages. The packages bdftopcf, imake (includes xmkmf), and mkfontdir are now split into separate subpackages. It's good for end users for a minimal system, but such changes now breaks the old automatic build requirement chain, and makes BuildRequires more complicated.

If your build fails in openSUSE 12.2 or Factory with error messages like

bdftopcf/xmkmf/mkfontdir: Command not found.

or

Imakefile.c:34:0: fatal error: Imake.tmpl: No such file or directory.

you need the tweaks in this section.

The common BuildRequires used to package fonts before:

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

need to make some changes.

Explanations of the old BuildRequires

xorg-x11 provides /usr/bin/bdftopcf,and xorg-x11-devel is actually used to call in xorg-x11-utils-devel,which includes xmkmf, imake and mkfontdir. so xorg-x11 can't be ignored.

  • If the error message is about bdftopcf, you need:
%if 0%{?suse_version} >= 1220
BuildRequires: bdftopcf
%else
BuildRequires: xorg-x11
BuildRequires: xorg-x11-devel
%endif
  • If the error message is about xmkmf/imake, you need:
%if 0%{?suse_version} >= 1220
BuildRequires: imake //includes xmkmf
BuildRequires: xorg-cf-files //includes Imake.tmpl
%else
BuildRequires: xorg-x11
BuildRequires: xorg-x11-devel
%endif
  • If the error message is about mkfontdir, you need:
%if 0%{?suse_version} >= 1220
BuildRequires: mkfontdir //this is a "fake" package points to mkfontscale
%else
BuildRequires: xorg-x11
BuildRequires: xorg-x11-devel
%endif
  • If the error message is about fc-cache, you need:
%if 0%{?suse_version} >= 1220
BuildRequires: fontconfig
%else
BuildRequires: xorg-x11
BuildRequires: xorg-x11-devel
%endif
  • If the error message is about libfreetype6.so, you need:
%if 0%{?suse_version} >= 1220
BuildRequires: freetype2-devel
%else
BuildRequires: xorg-x11
BuildRequires: xorg-x11-devel
%endif

In Fedora, bdftopcf and mkfontdir are in xorg-x11-font-utils, so needs some more changes:

%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