0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

[Python] フォントの情報を取得する

Last updated at Posted at 2025-04-05

はじめに

等幅フォントを使っていても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, | ) |

参考

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?