.ttcファイルを1つ以上の.ttfファイルへ変換しよう!

エリファス1810

Pythonで.ttcファイルを1つ以上の.ttfファイルへ変換しよう!

 GithubでPythonのソース コードをパブリック ドメインで公開しております。

 マイクロソフトのBing検索エンジンで「github eliphas1810-tools」などで検索してみてください。

 残念ながらグーグル検索エンジンでは検索できません。


 Rustのeguiで日本語を表示するには.ttfファイルを指定する必要が有るのですが、.ttcファイルしかないフォントが多いので、.ttcファイルを1つ以上の.ttfファイルへ変換するアプリケーションを作ってみました。

 ただし、.ttfファイルが正しいかどうか確認する方法が分からないので、アプリケーションの動作が正しいかどうか確認できていません。

 不具合が有るかもしれないので利用は自己責任でお願いいたします。

 コピペする場合は、2文字の全角空白を4文字の半角空白に置換してください。

――――――――――――――――――――

import tkinter

from tkinter import filedialog

from tkinter import messagebox

import os

import re


root = tkinter.Tk()

root.geometry("800x300")

root.title(".ttcファイルを1つ以上の.ttfファイルに変換")


ttc_string_var = tkinter.StringVar()

ttc_string_var.set("")


ttc_label = tkinter.Label(root, textvariable=ttc_string_var)

ttc_label.place(x=10, y=40)


# .ttcファイル選択ボタンが押された時の処理

def select_ttc():

  try:

    ttc_string_var.set(filedialog.askopenfilename(initialdir=os.path.expanduser("~"), multiple=False, filetypes=[(".ttcファイル", ".ttc")]))

  except Exception as exception:

    messagebox.showerror(exception.__class__.__name__, str(exception))

    raise


ttc_select_button = tkinter.Button(root, text=".ttcファイル選択", command=select_ttc)

ttc_select_button.place(x=10, y=10)


out_dir_string_var = tkinter.StringVar()

out_dir_string_var.set("")


out_dir_label = tkinter.Label(root, textvariable=out_dir_string_var)

out_dir_label.place(x=10, y=110)


# 出力ディレクトリ選択ボタンが押された時の処理

def select_out_dir():

  try:

    out_dir_string_var.set(filedialog.askdirectory(initialdir=os.path.expanduser("~")))

  except Exception as exception:

    messagebox.showerror(exception.__class__.__name__, str(exception))

    raise


out_dir_select_button = tkinter.Button(root, text="出力ディレクトリ選択", command=select_out_dir)

out_dir_select_button.place(x=10, y=80)


message_string_var = tkinter.StringVar()

message_string_var.set("")


message_label = tkinter.Label(root, textvariable=message_string_var)

message_label.place(x=10, y=180)


# .ttcファイルから.ttfファイルへ変換ボタンが押された時の処理

def ttc_to_ttf():

  try:


    ttc = ttc_string_var.get()

    out_dir = out_dir_string_var.get()


    if ttc == "":

      message_string_var.set(".ttcファイルを選択してください。")

      return


    if out_dir == "":

      message_string_var.set("出力ディレクトリを選択してください。")

      return


    with open(ttc, "rb") as file:


      # .ttcファイルはビッグ エンディアン(ネス)

      # TTC Headerを読み込んでいく


      # 4バイトのASCII文字列のTTC Tagを読み込みUTF-8へ変換

      # "ttcf"

      ttc_tag = file.read(4).decode()


      # 4バイトのVersionを読み込み16進数表記のUTF-8文字列へ変換

      # "00010000"か"00020000"

      # "00010000"はTTC Header Version 1.0を意味

      # "00020000"はTTC Header Version 2.0を意味

      version = file.read(4).hex()


      # 4バイトのnumFontsを読み込み整数へ変換

      num_fonts = int.from_bytes(file.read(4), byteorder="big", signed=False)


      offset_list = []

      # numFontsの数だけ、くり返し

      for index in range(0, num_fonts):

        # 4バイトの各フォントのデータの開始バイトを読み込みへ整数へ変換

        # 0バイト目から開始バイトまでのバイト数

        offset_list.append(int.from_bytes(file.read(4), byteorder="big", signed=False))


      # TTC Header Version 2.0の場合は、numFontsの後にデジタル署名のTTC Headerが有るが、無視


      max_index = num_fonts - 1

      font_name = re.sub("\.[tT][tT][cC]$", "", os.path.basename(ttc))

      # numFontsの数だけ、くり返し

      for index in range(0, num_fonts):

        file.seek(offset_list[index], os.SEEK_SET)

        with open(os.path.join(out_dir, font_name + str(index + 1) + ".ttf"), "wb") as f:

          if index == max_index:

            f.write(file.read())

          else:

            f.write(file.read(offset_list[index + 1] - offset_list[index]))


    message_string_var.set(".ttcファイルから.ttfファイルへの変換が完了しました。")


  except Exception as exception:

    messagebox.showerror(exception.__class__.__name__, str(exception))

    raise


ttc_to_ttf_button = tkinter.Button(root, text=".ttcファイルから.ttfファイルへ変換", command=ttc_to_ttf)

ttc_to_ttf_button.place(x=10, y=150)


root.mainloop()

――――――――――――――――――――

  • Xで共有
  • Facebookで共有
  • はてなブックマークでブックマーク

作者を応援しよう!

ハートをクリックで、簡単に応援の気持ちを伝えられます。(ログインが必要です)

応援したユーザー

応援すると応援コメントも書けます

新規登録で充実の読書を

マイページ
読書の状況から作品を自動で分類して簡単に管理できる
小説の未読話数がひと目でわかり前回の続きから読める
フォローしたユーザーの活動を追える
通知
小説の更新や作者の新作の情報を受け取れる
閲覧履歴
以前読んだ小説が一覧で見つけやすい
新規ユーザー登録無料

アカウントをお持ちの方はログイン

カクヨムで可能な読書体験をくわしく知る