はじめに
等幅フォントを使っていてもUnicodeの文字列が綺麗に揃わないのでフォントの横幅を知りたいと思いました。
調べた結果、Pythonで簡単に取得できる方法がありましたので記事にしてみました。
環境
OS
Windows 11 Pro
py -VV
Python 3.12.0 (tags/v3.12.0:0fb18b0, Oct 2 2023, 13:03:39) [MSC v.1935 64 bit (AMD64)]
コード
python
import argparse
from pathlib import Path
from fontTools import ttLib
NoBreakSpace = "\u00a0"
def argumentParser():
parser = argparse.ArgumentParser()
parser.add_argument("inputPath", type=Path, help="input path")
parser.add_argument("-a", "--showArgument", action="store_true", help="show arguments.")
return parser.parse_args()
def dump(font, output):
glyphSet = font.getGlyphSet()
cmap = font.getBestCmap()
with output.open("w", encoding="utf-8") as file:
file.write(f"number = {len(cmap)}\n")
for codePoint, name in cmap.items():
g = glyphSet[name]
c = f"|{NoBreakSpace}{chr(codePoint)}{NoBreakSpace}|"
h = g.height
h = h if h is not None else ""
string = f"{name:20}, {codePoint:6x}, {g.width:4}, {h:4}, {c}\n"
file.write(string)
if __name__ == "__main__":
args = argumentParser()
if args.showArgument:
print(args)
Path("font").mkdir(exist_ok=True)
if args.inputPath.suffix == ".ttf":
output = Path(f"./font/{args.inputPath.stem}.txt")
with ttLib.TTFont(args.inputPath) as font:
dump(font, output)
if args.inputPath.suffix == ".ttc":
for i, font in enumerate(ttLib.ttCollection.TTCollection(args.inputPath)):
output = Path(f"./font/{args.inputPath.stem}{i}.txt")
dump(font, output)
フォントの情報を取得するために"fontTools"を使いました。
始めに、ttLib.TTFont(path)
へフォントファイル(.ttf
)のパスを渡してフォントの情報が入ったTTFontオブジェクトを取得します。
次に、TTFontオブジェクトからgetGlyphSet()
を使って全てのグリフ情報が入ったオブジェクト(TTGlyphとしておきます)を取得します。
このTTGlyphオブジェクトからグリフの情報を得るにはグリフの名前が必要です。
そこで、getBestCmap()
を使い、Cmap(Character Map)を取得します。
これは、キーがUnicodeのコードポイントで、値がコードポイントに対応するグリフの名前である辞書を返します。
得られた名前を使ってTTGlyphにアクセスすればグリフの情報が手に入ります。
with ttLib.TTFont(args.inputPath) as font:
glyphSet = font.getGlyphSet()
cmap = font.getBestCmap()
for codePoint, name in cmap.items()
g = glyphSet[name]
以下は、出力例です。
実際の出力から制御文字を削除しています。
出力例
number = 16127
uni0000 , 0, 0, 0, | |
uni000D , d, 0, 0, | |
space , 20, 128, 256, | |
exclam , 21, 128, 256, | ! |
quotedbl , 22, 128, 256, | " |
numbersign , 23, 128, 256, | # |
dollar , 24, 128, 256, | $ |
percent , 25, 128, 256, | % |
ampersand , 26, 128, 256, | & |
quotesingle , 27, 128, 256, | ' |
parenleft , 28, 128, 256, | ( |
parenright , 29, 128, 256, | ) |
参考