A few days ago, my friend " pre-salt " left a message and asked a question related to the Kindle custom font function. He followed the steps provided in the article "How to use Kindle's native custom font function", put the font file into the fonts folder in the root directory of the Kindle, and found that the Chinese font should have been displayed when he selected the font in the font selection panel A string of question marks appeared in the place of the name as shown in the figure below.
The occurrence of this problem may be caused by irregular font file production. We can refer to the OpenType specification (hereinafter referred to as "the specification") and use appropriate tools to fix this problem. This article provides a solution to an issue where font names in OpenType formats (file extensions .otf, .otc, .ttf, or .ttc) do not display correctly in the Kindle's font selection panel.
1. Solutions
OpenType format font files contain a series of data presented in tabular form. There are many types of these data. For details, please refer to the specification for details . This article focuses only on the metadata information associated with the font name (the typeface you see when selecting a font), the font's "name" table.
The "name" table of the font can associate strings (text) in multiple languages to the font, such as copyright statement, font name, font family name, style name, etc., and its purpose is to display in operating systems in different locales The appropriate language version of this information.
If the name of a font is not displayed correctly, it means that there is a problem with the "name" table in the font file. To solve this problem, we can first use a tool to extract it, then correct it according to the specification, and finally put the corrected " name" table into the font file.
2. Preparation tools
Font files (that is, files with the extension .otf, .otc, .ttf, or .ttc) are independent binary files, and we cannot edit them directly. In order to be able to modify them as we need, we must use special tool or convert it to a human-readable text file.
The tool used in this article is fontTools , a Python-based font processing library that includes a tool called ttx , which can convert font files into XML text files with the extension .ttx, which is convenient for us to modify fonts related information.
To use fontTools, you need to ensure that your operating system has a Python version greater than or equal to 3.6. If your system does not have Python installed or the version is lower than 3.6, please go to the Python official website to download and install (macOS system can be installed through Homebrew ).
After the Python environment is ready, you can enter the following command in Terminal or Command Prompt to install fontTools:
pip3 install fonttools
After the fontTools installation is complete, you can enter the following command. If the version number can be output normally, the installation is successful:
ttx --version
3. Operation steps
Although the ttx program can convert an entire font file to a .ttx file, and can also convert a .ttx file back to a font file, if the font file is large, the converted .ttx file will also be large, which reduces the editing and conversion effort. efficiency. Therefore, in order to greatly improve efficiency, we only need to extract the "name" table of the font file for modification, and then use the merge function of ttx to merge the modified table back into the font file.
For the convenience of showing the operation steps, a fictional font file SampleSong.ttf with a name display problem is created below (just replace the file name with the actual font file name in actual operation). The book companion will give necessary explanations for the places that involve norms in the steps.
1. Extract the "name" table from the font file
To extract the "name" table in the font file separately, you can first switch to the directory where the font is located, and then run the following command:
ttx -t name SampleSong.ttf
* Tip: If you are dealing with " Font Collections " files (extension .ttc or .otc), you need to specify the number of a single font in the font collection in the command, that is, add the option -t
before -y
, and add the option in the Specify the number after the option. likettx -y 0 -t 'name' SampleFonts.ttc
.
By default, the extracted "name" table file name is the same as the font file name, and the storage location is also the same as the font file, but the extension is changed to .ttx. The file obtained in this example is SampleSong.ttx, open the file with a code editor, and you will see something like this:
<?xml version="1.0" encoding="UTF-8"?>
<ttFont sfntVersion="\x00\x01\x00\x00" ttLibVersion="4.22">
<name>
<namerecord nameID="1" platformID="3" platEncID="1" langID="0x409">
示例宋体
</namerecord>
<namerecord nameID="2" platformID="3" platEncID="1" langID="0x409">
Regular
</namerecord>
<namerecord nameID="3" platformID="3" platEncID="1" langID="0x409">
示例宋体 Regular; Version 1.0; 2019-09-27
</namerecord>
<namerecord nameID="4" platformID="3" platEncID="1" langID="0x409">
示例宋体 Regular
</namerecord>
<namerecord nameID="5" platformID="3" platEncID="1" langID="0x409">
Version 1.0 September 27, 2019
</namerecord>
<namerecord nameID="6" platformID="3" platEncID="1" langID="0x409">
SampleSong-Regular
</namerecord>
</name>
</ttFont>
This is all " Name Records " in the font file, which consists of multiple <namerecord>
elements , each element contains nameID
, platformID
, platEncID
and langID
attributes (corresponding to the nameID, platformID, encodingID, and languageID in the specification, respectively), these attributes Defines the meaning of each element in the font. The meanings of these properties are as follows:
- nameID : Name ID. Commonly used are 26 predefined IDs (from 0 to 25), each ID corresponds to a specific meaning. Among them, 1 and 2 correspond to "Font Family name" and "Font Subfamily name" respectively.
- platformID : Platform ID. 0 corresponds to Unicode, 1 corresponds to the Macintosh platform, and 3 corresponds to the Windows platform. The values of the next two attributes, encodingID and languageID, depend on this ID. This example uses the Windows platform.
- platEncID : Platform-specific encoding ID. The encoding ID commonly used under the Windows platform is 1 (Unicode BMP).
- langID : Language ID. The value of the language ID under the Windows platform is expressed in hexadecimal, where American English is 0x409, and Simplified Chinese is 0x804. This attribute is the key to solving the problem, it determines the language in which the system will resolve the content of the name record element.
* Note: "Family Name" is also called "Series Name", which is the name displayed when selecting a font; "Sub-Family Name" is also called "Style Name", which refers to font characteristics such as weight and italic.
The order of the name record elements depends on these attributes and must be sorted first by platform ID, then by platform-specific encoding ID, then by language ID, and finally by name ID. This orderly arrangement also helps us quickly identify which language a certain set of records corresponds to.
After understanding these technical details, we can see the problems in the sample "name" table. The name record containing simplified Chinese character strings has a language ID attribute value of 0x409 (that is, American English), which obviously makes some Systems (such as Kindle) cannot parse it correctly.
To solve this problem, the incorrect language ID in the font's name record needs to be corrected to match the actual language of the string.
2. Correct the wrong language ID in the "name" table
There are two ways to modify the language ID: one is to change the language ID of all name records containing Simplified Chinese strings to 0x804; the other is to add a name for Simplified Chinese without modifying the original name records Record, in this example, only need to add a name record with name ID 1, and set its language ID to Simplified Chinese (as shown below), it is enough to solve the font name display problem.
<?xml version="1.0" encoding="UTF-8"?>
<ttFont sfntVersion="\x00\x01\x00\x00" ttLibVersion="4.22">
<name>
<namerecord nameID="1" platformID="3" platEncID="1" langID="0x409">
示例宋体
</namerecord>
<namerecord nameID="2" platformID="3" platEncID="1" langID="0x409">
Regular
</namerecord>
<namerecord nameID="3" platformID="3" platEncID="1" langID="0x409">
示例宋体 Regular; Version 1.0; 2019-09-27
</namerecord>
<namerecord nameID="4" platformID="3" platEncID="1" langID="0x409">
示例宋体 Regular
</namerecord>
<namerecord nameID="5" platformID="3" platEncID="1" langID="0x409">
Version 1.0 April 25, 2021
</namerecord>
<namerecord nameID="6" platformID="3" platEncID="1" langID="0x409">
SampleSong-Regular
</namerecord>
<namerecord nameID="1" platformID="3" platEncID="1" langID="0x804">
示例宋体
</namerecord>
</name>
</ttFont>
The book companion recommends the second method. There may be some side effects if you choose the first method. Take the name record whose name ID is 6 as an example. The specification's suggestion for this record is: it should contain the name records of both platforms, Macintosh and Windows, and both should set the language ID to English. If you accidentally set it to Chinese, when adding fonts to the macOS system, you will encounter a situation where the structure of the font verification prompt table is wrong.
3. Merge revised "name" table into fonts
After correcting the language ID error in the font "name" table, you can run the following command to merge the "name" table back into the font file:
ttx -m SampleSong.ttf SampleSong.ttx
* Tips: If you are dealing with " Font Collections " files (extension .ttc or .otc), you need to pay attention, because ttx cannot directly merge font collection files, so you need to use the tool first The otc2otf program in Adobe Font Development Kit for OpenType (AFDKO) extracts all the individual font files in the font set, and then processes them with ttx, and finally merges them again with the otf2ot program in the tool suite.
After the command is successfully executed, a new font file will be generated. By default, the new font file name will add a serial number #1 to the original file name, such as SampleSong#1.ttf (you can also add options -m
before -o
, followed by a custom filename).
* Tip: In the macOS system, if the font file name has a # symbol, even if the font structure is fine, there will be a strange "system verification" error when adding it to the font book, and the font cannot be verified. If the font file you are dealing with needs to be used in the macOS system, it is recommended to delete the # symbol in the font file name.
After getting the newly generated font file, copy it to Kindle to view the correction effect, as shown below:
▲ The Chinese font name shows a question mark repair effect
When testing fonts, please note that after copying font files, if the e-book is open, you need to exit and return to the Kindle home page or library, stop for a few seconds and then reopen, so that Kindle can reload the newly copied fonts. Sometimes it may be necessary to retry several times in this way.
So far, the problem that the custom font name cannot be displayed normally in the font selection panel of Kindle is solved. The article looks very long, mainly because some specification descriptions have been added. Simply put, first use the ttx tool in fontTools to extract the "name" table from the font file, and then correct the error according to the specification, and finally the corrected "name" "Remerge into the font file to get a new font file