欧美一区二区三区老妇人-欧美做爰猛烈大尺度电-99久久夜色精品国产亚洲a-亚洲福利视频一区二区

字的研究(2)fontTools-字體文件的解析

前言

本文主要介紹如果使用Python第三方庫fontTools對OpenType字體文件(包括TrueType輪廓和Postscript輪廓)的解析操作。

創(chuàng)新互聯(lián)-云計算及IDC服務(wù)提供商,涵蓋公有云、IDC機(jī)房租用、眉山服務(wù)器托管、等保安全、私有云建設(shè)等企業(yè)級互聯(lián)網(wǎng)基礎(chǔ)服務(wù),聯(lián)系電話:18980820575

fontTools簡介

fontTools是由一組操作字體的庫和組件組成的Python第三方庫,要求Python3.6以及更高的版本。其中包括merge(字體合并)、subset(取字體子集)以及ttx(將OpenType轉(zhuǎn)化為XML)等。

安裝

pip install fontTools

本文中使用的版本為4.28.5

字體文件的解析

讀取

如前文所述,OpenType字體文件標(biāo)準(zhǔn)是有sfnt結(jié)構(gòu)封裝的,基于sfnt的表結(jié)構(gòu),OpenType格式的字體文件可以分為多個表結(jié)構(gòu)。

創(chuàng)建TTFont實例,通過keys()可以查看字體文件的所有表名:

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

運(yùn)行結(jié)果如下:

['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']

表名中包含‘glyf‘,所以simsun.ttf是一個使用TrueType輪廓的字體文件。

換成使用Postscript輪廓的字體文件:

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

運(yùn)行結(jié)果如下:

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

表名中沒有'glyf'而存在'CFF ',后者是存儲Postscript信息的表格。

對于TrueType Collection文件則可以使用如下方法讀取,返回一個TTFont實例的列表

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

運(yùn)行結(jié)果如下:

[<fontTools.ttLib.ttFont.TTFont object at 0x000001F8BA66A700>, <fontTools.ttLib.ttFont.TTFont object at 0x000001F8BE072AF0>]

直接從這些表格提取到具體信息是復(fù)雜的,但TTFont提供了一些方法以方便地獲取信息:

font.getGlyphOrder() # 返回一個字形名稱列表,以其在文件中的順序排序
font.getGlyphNames() # 返回一個字形名稱列表,以字母順序排序
font.getBestCmap() # 返回一個字形ID為鍵、字形名稱為值的字典
font.getReverseGlyphMap() # 返回一個字形名稱為鍵、字形ID為值的字典
font.getGlyphName() # 輸入字形ID返回字形名稱
font.getGlyphID("uni70E0") # 輸入字形名稱返回字形ID
font.getGlyphSet() # 返回一個_TTGlyphSet對象,包含字形輪廓數(shù)據(jù)

上述方法中,最后一項與輪廓數(shù)據(jù)有關(guān)的方法是最重要的??上У氖牵俜轿臋n似乎并沒有對這個對象做進(jìn)一步解釋,故下文是我讀源碼及其中注釋后的分析,如有錯漏,敬請指教。

Pen與_TTGlyphset

我認(rèn)為,作者設(shè)計這一部分時的難點(diǎn)在于OpenType字體文件標(biāo)準(zhǔn)存在兩種不同輪廓描述方式。Pen和_TTGlyphset的存在使得兩種不同的輪廓描述方式可以用同一套方法解析和顯示。

The Pen Protocol

基于TrueType輪廓的字體文件和基于Postscript輪廓是兩種截然不同的數(shù)據(jù)格式。Pen是一個用于標(biāo)準(zhǔn)化的”畫"出輪廓的對象,或者是數(shù)據(jù)和實際輪廓間的媒介。

具體來說,Pen對象的子類包含將上述兩種輪廓數(shù)據(jù)轉(zhuǎn)化為畫線、移動等模擬實際輪廓的方法。在fontTools的pen庫中包含將輪廓數(shù)據(jù)轉(zhuǎn)化為qt、reportLab等第三方庫中實例的Pen子類。

_TTGlpyhset

_TTGlyphset是一個類似字典的,以字形名稱為鍵、_TTGlyph為值的對象。_TTGlyph中包含字形數(shù)據(jù)輪廓數(shù)據(jù)并可以通過draw方法“畫”出。_TTGlyph的兩個子類_TTGlyphGlyf和_TTGlyphCFF分別對應(yīng)TrueType輪廓和Postscript輪廓。具體使用方法如下:

font = TTFont("Resources/simsun.ttf")
glyph = font.getGlyphSet()["uni70E0"]
glyph.draw(pen) # pen為實例化后的Pen子類

freetypePen

以freetype-py庫為例,使用freetypePen首先需要安裝freetype-py:

pip install freetype-py

以下代碼修改自自fontTools的官方文檔提供的范例程序:

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

pen = FreeTypePen(None) # 實例化Pen子類
font = TTFont("Resources/simsun.ttf") # 實例化TTFont
glyph = font.getGlyphSet()["uni70E0"] # 通過字形名稱選擇某一字形對象
glyph.draw(pen) # “畫”出字形輪廓
width, ascender, descender = glyph.width, font['OS/2'].usWinAscent, -font['OS/2'].usWinDescent # 獲取字形的寬度和上沿以及下沿
height = ascender - descender # 利用上沿和下沿計算字形高度
pen.show(width=width, height=height, transform=Offset(0, -descender)) # 顯示以及矯正

運(yùn)行結(jié)果如下:

注意,可能由于fontTools==4.28.5版本問題,通過pip安裝后freetypePen.py并沒有包含在pens文件夾下,需要使用的可以從fontTools的GitHub倉庫中下載,放到site-packages\fontTools\pens文件夾下,下載路徑為https://github.com/fonttools/fonttools/blob/main/Lib/fontTools/pens/freetypePen.py。該問題可能在后續(xù)版本中修復(fù)。

ttx

最后是我個人認(rèn)為fontTools中最為實用的一個組件ttx,其功能為將TTFont實例轉(zhuǎn)化為XML格式以及將XML文件轉(zhuǎn)化為TTFont?;谶@一組件,我們可以較為方便的實現(xiàn)對字體文件內(nèi)容的修改。

from fontTools.ttLib import TTFont

font = TTFont("Resources/simsun.ttf") # 實例化TTFont
font.saveXML("simsun.xml") # TTFont實例轉(zhuǎn)化為XML文件,參數(shù)為XML文件路徑
font.importXML("simsun1.xml") # XML文件轉(zhuǎn)化為TTFont實例,參數(shù)為XML文件路徑

除了將整個字體文件轉(zhuǎn)化為XML文件,ttx還可以將文件中的單個表轉(zhuǎn)化為XML文件,避免多余的存儲和時間消耗:

from fontTools.ttLib.ttFont import TTFont

font = TTFont("Resources/simsun.ttf")
font.saveXML("temp2.xml",tables=["glyf"]) # tables為需要轉(zhuǎn)化的表名組成列表

單個表的XML文件直接導(dǎo)入TTFont時,只會影響XML文件存在的表,而其他表不變:

font.importXML("temp2.xml")

參考

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

https://github.com/fonttools/fonttools

當(dāng)前名稱:字的研究(2)fontTools-字體文件的解析
本文URL:http://chinadenli.net/article26/dsojdcg.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供品牌網(wǎng)站建設(shè)、域名注冊動態(tài)網(wǎng)站、Google、網(wǎng)站排名、網(wǎng)站維護(hù)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

商城網(wǎng)站建設(shè)