Research on font - Analysis of font file

Python wechat ordering applet course video

https://edu.csdn.net/course/detail/36074

Python actual combat quantitative transaction financial management system

https://edu.csdn.net/course/detail/35475

preface

This article mainly introduces the parsing operation of OpenType font files (including TrueType outline and Postscript outline) using Python third-party library fontTools.

fontTools introduction

fontTools is a python third-party library composed of a set of libraries and components that operate fonts. It requires Python 3 6 and later. These include merge (font merging), subset (taking font subset) and ttx (converting OpenType to XML).

install

pip install fontTools

The version used in this article is 4.28.5

Font file parsing

read

As mentioned above, the OpenType font file standard is encapsulated with sfnt structure. Based on the sfnt table structure, the OpenType font file can be divided into multiple table structures.

Create a TTFont instance, and view all table names of the font file through keys():

from fontTools.ttLib.ttFont import TTFont
font = TTFont("Resources/simsun.ttf")
print(font.keys()) 

The operation results are as follows:

['GlyphOrder', 'head', 'hhea', 'maxp', 'OS/2', 'hmtx', 'cmap', 'fpgm', 'prep', 'cvt ', 'loca', 'glyf', 'name', 'post', 'gasp', 'EBDT', 'EBLC', 'GDEF', 'GPOS', 'GSUB', 'MERG', 'meta', 'vhea', 'vmtx']

The table name contains' glyf ', so Simsun Ttf is a font file that uses TrueType outlines.

Replace the font file with Postscript Outline:

font = TTFont("Resources/AdobeSongStd-Light.otf")
print(font.keys())

The operation results are as follows:

['GlyphOrder', 'head', 'hhea', 'maxp', 'OS/2', 'name', 'cmap', 'post', 'CFF ', 'BASE', 'GPOS', 'GSUB', 'VORG', 'hmtx', 'vhea', 'vmtx', 'DSIG']

There is no 'glyf' in the table name, but there is' CFF ', which is the table that stores Postscript information.

For TrueType Collection files, you can use the following methods to read and return a list of TTFont instances

from fontTools.ttLib.ttCollection import TTCollection
collection = TTCollection("Resources/simsun.ttc")
print(list(collection))

The operation results are as follows:

[object at 0x000001F8BA66A700>, object at 0x000001F8BE072AF0>]

Extracting specific information directly from these tables is complex, but TTFont provides some methods to easily obtain information:

font.getGlyphOrder() # Returns a list of glyph names, sorted in the order they appear in the file
font.getGlyphNames() # Returns a list of font names, sorted alphabetically
font.getBestCmap() # Returns a dictionary with glyph ID as key and glyph name as value
font.getReverseGlyphMap() # Returns a dictionary with font name as key and Font ID as value
font.getGlyphName(10000) # Enter Font ID and return font name
font.getGlyphID("uni70E0") # Enter the font name and return the font ID
font.getGlyphSet() # Return a\_ TTGlyphSet object containing glyph outline data

Among the above methods, the last one related to contour data is the most important. Unfortunately, the official documents do not seem to further explain this object, so the following is my analysis after reading the source code and its comments. If there are any mistakes and omissions, please give me advice.

Pen and_ TTGlyphset

I think the difficulty in designing this part is that there are two different contour description methods in the OpenType font file standard. Pen and_ The existence of TTGlyphset enables two different contour description methods to be analyzed and displayed in the same set of methods.

The Pen Protocol

TrueType based font files and Postscript based font files are two distinct data formats. Pen is a standardized object for "drawing" outline, or a medium between data and actual outline.

Specifically, the subclass of pen object contains methods to convert the above two contour data into line drawing, moving and other methods to simulate the actual contour. The pen Library of fontTools contains pen subclasses that convert contour data into instances in third-party libraries such as qt and reportLab.

_TTGlpyhset

_ TTGlyphset is a dictionary like, with font name as the key_ Object with TTGlyph value_ TTGlyph contains glyph data and contour data, which can be "drawn" by the draw method_ Two subclasses of TTGlyph_ TTGlyphGlyf and_ TTGlyphCFF corresponds to TrueType contour and Postscript contour respectively. The specific application methods are as follows:

font = TTFont("Resources/simsun.ttf")
glyph = font.getGlyphSet()["uni70E0"]
glyph.draw(pen) # Pen is a subclass of pen after instantiation

freetypePen

Take the freetype py library as an example. To use freetypePen, you need to install freetype py first:

pip install freetype-py

The following code modifies the sample program provided in the official documentation of fontTools:

from fontTools.ttLib import TTFont
from fontTools.pens.freetypePen import FreeTypePen
from fontTools.misc.transform import Offset

pen = FreeTypePen(None) # Instantiate Pen subclass
font = TTFont("Resources/simsun.ttf") # Instantiate TTFont
glyph = font.getGlyphSet()["uni70E0"] # Select a glyph object by glyph name
glyph.draw(pen) # Draw a glyph outline
width, ascender, descender = glyph.width, font['OS/2'].usWinAscent, -font['OS/2'].usWinDescent # Gets the width and top and bottom edges of the glyph
height = ascender - descender # Use the top and bottom edges to calculate the height of the glyph
pen.show(width=width, height=height, transform=Offset(0, -descender)) # Display and correction

The operation results are as follows:

Note that it may be due to the problem of fonttools = = version 4.28.5. After installing through pip, freetypepen Py is not included in the pens folder. What you need to use can be downloaded from the GitHub warehouse of fonttools and placed in the site packages \ fonttools \ pens folder. The download path is https://github.com/fonttools/fonttools/blob/main/Lib/fontTools/pens/freetypePen.py . This problem may be fixed in a later version.

ttx

Finally, I think ttx is the most practical component in fontTools. Its function is to convert TTFont instances into XML format and XML files into TTFont. Based on this component, we can easily modify the content of font file.

from fontTools.ttLib import TTFont

font = TTFont("Resources/simsun.ttf") # Instantiate TTFont
font.saveXML("simsun.xml") # TTFont instance is converted to XML file, and the parameter is XML file path
font.importXML("simsun1.xml") # XML file is converted to TTFont instance, and the parameter is XML file path

In addition to converting the entire font file into an XML file, ttx can also convert a single table in the file into an XML file to avoid unnecessary storage and time consumption:

from fontTools.ttLib.ttFont import TTFont

font = TTFont("Resources/simsun.ttf")
font.saveXML("temp2.xml",tables=["glyf"]) # tables is a list of table names to be converted

When the XML file of a single table is directly imported into TTFont, only the existing tables of the XML file will be affected, while other tables remain unchanged:

font.importXML("temp2.xml")

reference resources

https://fonttools.readthedocs.io/en/latest/index.html

https://github.com/fonttools/fonttools

Keywords: Python IT

Added by jitesh on Thu, 27 Jan 2022 14:31:24 +0200