はじめに
PythonでM+FONTSをベースにM+A1というフォントを作成しました。
(https://microraptor.booth.pm/items/2347968)
備忘録と布教の意味を込めて、プログラムでフォントを読み込み、書き出す手順を説明していきます。
- 筆者の環境
- anaconda + Python3
- 標準以外のライブラリ
- defcon
- ufo2ft
- 元となるフォント
- OpenType形式で改変が許可されているフォント
- TrueTypeでも専用のソフトでOpenTypeに変換すればOKです
やりたいこと
いきなりOTF(OpenType)を読み込むことはできないので、UFO(Unified Font Object)形式に書き出してから、そのファイルを読み込んでOTFを作ります。
UFOって何? となるでしょうが、難しいことはありません。単なるxmlファイルです。
フォントデータを構成しているベジェ曲線の制御点がxmlとして書き出されます。
OTF -> UFO
defconでFontオブジェクトを生成し、extractUFOでOTF->UFOへ書き出します。
import defcon
import extractor
IMPORT_FILE = r'C:\example\abc.otf'
EXPORT_FILE = r'C:\example\abc_ufo'
font = defcon.Font()
extractor.extractUFO(IMPORT_FILE, font)
font.save(EXPORT_FILE)
欧文なら数秒、日本語書体なら数分でエクスポートが行われます。
出力結果
- glyph
- 文字ごとのパス情報がXML形式で書かれています。(形式は.gilf)
- contents.plist
- 収録している文字のパスファイル(.gilf)のリスト
- fontinfo.plist
- フォント全体の情報(フォント名、アセンダ・ディセンダ等数値、などなど)
- kerning.plist
- カーニング情報
- layercontents.plist
- よくわからん
- lib.plist
- 収録している文字のパスファイル(.gilf)のリスト
- metainfo.plist
- フォーマット、作者等
lib.plistとcontents.plistは似ているファイルなので、どちらを見ても参照してもよいです
(lib.plistはフォント名とフォントファイルの紐付けがないが、各.gilf内にもフォント名が書かれている。contents.plistは大量の.gilf内に存在するので探すのが手間。たいていはどちらでも構わないと思われる。)
UFO -> OTF
import os
import defcon
import ufo2ft
from xml.etree import ElementTree as ET
# Const
UFO_FILE = r'C:\example\abc_ufo'
GLIF_PATH = os.path.join(UFO_FILE, 'glyphs')
font = defcon.Font()
# 編集する文字を選択
glif_root = ET.parse(os.path.join(GLIF_PATH, 'a.glif'))
glyph = font.newGlyph('a')
glyph.unicode = int(glif_root.find('.//unicode').attrib['hex'], 16)
contour_list = glif_root.findall('.//contour')
# glifファイルから<contour>配下の<point>タグを順次読み込み
for tag_contour in contour_list:
contour = defcon.Contour()
point_list = tag_contour.findall('./point')
for k, v in enumerate(point_list):
# <point>にtypeが定義されていないならNone
_type = v.attrib['type'] if 'type' in v.attrib else None
# ポイントを設定
contour.appendPoint(
defcon.Point(
(int(v.attrib['x']), int(v.attrib['y'])),
segmentType=_type,
)
)
# 1周分の輪郭を設定
glyph.appendContour(contour)
# OTFに書き出し
otf = ufo2ft.compileOTF(font)
otf.save('new_font.otf')
これで、"a"のみが設定されたフォントファイルが出力されました。
パスを操作してから書き込めば、オリジナルのフォントが作れます。
リファレンス・参考資料
UFO公式 : https://unifiedfontobject.org/
DEFCON : https://defcon.robotools.dev/en/latest/
https://qiita.com/irori/items/5518c242e0244838783b
https://blog.hgrs.me/20190806022544
https://irori.github.io/wapuro-mincho/