« ◇各種フォントでPDF作成 | トップページ | ◆AozoraPDF.py(Python)のGUI化、exe化 »

◇ChatGPTでフォント情報取得プログラム生成

ChatGPTが生成したプログラムでこんなん出ました。

 ChatGPTだけでプログラム

"C:/Windows/Fonts"下のttcファイルを読み、情報をCSVに落とすプログラムをChatCPTで作成しました。

ChatGPTに対しいろいろ誘導は行いましたが、生成したコードは完全にChatCPTによるものです。

型にはまったプログラムの作成には役に立ちますね。

しかし、知恵がある訳ではないので、人間相手のように、ヒントを与えるとそれを学びながら、賢くなっていくということはなく、失敗を学習することもないので、間違った解答がループすることも多くあります。

Aの間違いを指摘すると、Bを出し、その間違いを指摘するとまたAを出すといった形です。間違った解答がループしていることを認識できないようで、「その解答は前に間違いだと指摘した」と言っても同じ解答が繰り返されます。

for文の書き方だとか、細かい質問は役にたちますが、まだ大きなものは難しいですね。

そんな中、この成果が得られました。

こういう形でフォント情報を拾い出します。

フォントファイル,フォント名,属性名,値,説明
BIZ-UDGothicB.ttc,BIZ UDゴシック - Bold,-,-,-
-,-,Ascender,1802,フォントの上部の最大高さ
-,-,Descender,-246,フォントの下部の最大の深さ
-,-,Line Gap,0,行間の追加のスペース
-,-,Font Width,1108,フォントの幅
-,-,Font Height,2048,フォントの高さ
-,-,tableTag,OS/2,不明
-,-,version,3,テーブルのバージョン
-,-,xAvgCharWidth,1024,平均文字幅
-,-,usWeightClass,700,フォントのウェイトクラス
-,-,usWidthClass,5,フォントの幅クラス
-,-,fsType,4,フォントのタイプフラグ
-,-,ySubscriptXSize,1024,下付き文字のXサイズ
-,-,ySubscriptYSize,1556,下付き文字のYサイズ
-,-,ySubscriptXOffset,0,下付き文字のXオフセット
-,-,ySubscriptYOffset,307,下付き文字のYオフセット
-,-,ySuperscriptXSize,1024,上付き文字のXサイズ
-,-,ySuperscriptYSize,1556,上付き文字のYサイズ
-,-,ySuperscriptXOffset,0,上付き文字のXオフセット
-,-,ySuperscriptYOffset,0,上付き文字のYオフセット
-,-,yStrikeoutSize,102,打ち消し線の太さ
-,-,yStrikeoutPosition,727,打ち消し線の位置
-,-,sFamilyClass,0,フォントファミリーのクラスおよびサブクラス
-,-,ulUnicodeRange1,3758097143,Unicode範囲1
-,-,ulUnicodeRange2,717745656,Unicode範囲2
-,-,ulUnicodeRange3,18,Unicode範囲3
-,-,ulUnicodeRange4,0,Unicode範囲4
-,-,achVendID,MRSW,ベンダーIDを示す4文字のASCII文字列
-,-,fsSelection,32,フォントの選択フラグ
-,-,usFirstCharIndex,32,使用可能な最初の文字のインデックス
-,-,usLastCharIndex,65535,使用可能な最後の文字のインデックス
-,-,sTypoAscender,1802,タイポグラフィのアセンダー
-,-,sTypoDescender,-246,タイポグラフィのディセンダー
-,-,sTypoLineGap,0,タイポグラフィのラインギャップ
-,-,usWinAscent,1802,Windowsでのアセンダーの値
-,-,usWinDescent,246,Windowsでのディセンダーの値
-,-,ulCodePageRange1,537001985,コードページ範囲1
-,-,ulCodePageRange2,0,コードページ範囲2
-,-,sxHeight,1108,不明
-,-,sCapHeight,1567,大文字の高さ
-,-,usDefaultChar,0,デフォルトの文字インデックス
-,-,usBreakChar,32,改行文字のインデックス
-,-,usMaxContext,6,コンテキストの最大数
BIZ-UDGothicR.ttc,BIZ UDゴシック - Regular,-,-,-
-,-,Ascender,1802,フォントの上部の最大高さ
-,-,Descender,-246,フォントの下部の最大の深さ
-,-,Line Gap,0,行間の追加のスペース
-,-,Font Width,1108,フォントの幅
-,-,Font Height,2048,フォントの高さ
・・・

一番重要なのはファイル名とフォント名の対応ですが、その他も気になる情報ですので、抜き出すようにしました。

 生成されたコード

import csv
import os
import argparse
from typing import Any, Dict, List, Tuple
from fontTools.ttLib import TTCollection

# os2_tableの属性名と説明の辞書
os2_table_attr_descriptions: Dict[str, str] = {
    "achVendID": "ベンダーIDを示す4文字のASCII文字列",
    "fsFirstCharIndex": "使用可能な文字の最初のインデックス",
    "fsLastCharIndex": "使用可能な文字の最後のインデックス",
    "fsSelection": "フォントの選択フラグ",
    "fsType": "フォントのタイプフラグ",
    "panose": "フォントのPANOSEナンバー",
    "sCapHeight": "大文字の高さ",
    "sFamilyClass": "フォントファミリーのクラスおよびサブクラス",
    "sTypoAscender": "タイポグラフィのアセンダー",
    "sTypoDescender": "タイポグラフィのディセンダー",
    "sTypoLineGap": "タイポグラフィのラインギャップ",
    "ulCodePageRange1": "コードページ範囲1",
    "ulCodePageRange2": "コードページ範囲2",
    "ulUnicodeRange1": "Unicode範囲1",
    "ulUnicodeRange2": "Unicode範囲2",
    "ulUnicodeRange3": "Unicode範囲3",
    "ulUnicodeRange4": "Unicode範囲4",
    "usBreakChar": "改行文字のインデックス",
    "usDefaultChar": "デフォルトの文字インデックス",
    "usFirstCharIndex": "使用可能な最初の文字のインデックス",
    "usLastCharIndex": "使用可能な最後の文字のインデックス",
    "usMaxContex": "コンテキストの最大数",
    "usMaxContext": "コンテキストの最大数",
    "usWeightClass": "フォントのウェイトクラス",
    "usWidthClass": "フォントの幅クラス",
    "usWinAscent": "Windowsでのアセンダーの値",
    "usWinDescent": "Windowsでのディセンダーの値",
    "version": "テーブルのバージョン",
    "xAvgCharWidth": "平均文字幅",
    "yStrikeoutPosition": "打ち消し線の位置",
    "yStrikeoutSize": "打ち消し線の太さ",
    "ySubscriptXOffset": "下付き文字のXオフセット",
    "ySubscriptXSize": "下付き文字のXサイズ",
    "ySubscriptYOffset": "下付き文字のYオフセット",
    "ySubscriptYSize": "下付き文字のYサイズ",
    "ySuperscriptXOffset": "上付き文字のXオフセット",
    "ySuperscriptXSize": "上付き文字のXサイズ",
    "ySuperscriptYOffset": "上付き文字のYオフセット",
    "ySuperscriptYSize": "上付き文字のYサイズ",
}

# フォントメトリクスの説明の辞書
font_metrics_descriptions: Dict[str, str] = {
    "Ascender": "フォントの上部の最大高さ",
    "Descender": "フォントの下部の最大の深さ",
    "Line Gap": "行間の追加のスペース",
    "Font Width": "フォントの幅",
    "Font Height": "フォントの高さ",
}

def parse_args():
    parser = argparse.ArgumentParser(description="Extract font information from TTC files to CSV")
    parser.add_argument("directory", help="The directory containing TTC font files")
    parser.add_argument("-out", help="Output CSV file name", default="font_info.csv")
    parser.add_argument("-omit", nargs="*", help="Attributes to omit")
    return parser.parse_args()

def get_font_info(font_file_name: str, output_file: str, omit: List[str]) -> None:
    try:
        ttc: TTCollection = TTCollection(font_file_name)
        font: Any = ttc.fonts[0]  # 最初のフォントを選択

        # フォント情報を取得
        family_name: str
        style_name: str
        family_name, style_name = get_font_name(font)
        font_metrics: List[Tuple[str, int]] = get_font_metrics(font)

        # CSVに書き込み
        with open(output_file, "a", newline="", encoding="utf-8") as csvfile:
            writer: Any = csv.writer(csvfile)
            if os.path.getsize(output_file) == 0:  # ファイルが空の場合
                writer.writerow(["フォントファイル", "フォント名", "属性名", "値", "説明"])  # ヘッダー行を書き込む
            writer.writerow([os.path.basename(font_file_name), f"{family_name} - {style_name}", "-", "-", "-"])
            for info in font_metrics:
                if info[0] not in omit:
                    writer.writerow(["-", "-", info[0], info[1], font_metrics_descriptions.get(info[0], "-")])

            # os2_tableの属性を書き込み
            for attr_name, attr_value in font["OS/2"].__dict__.items():
                if not attr_name.startswith("__") and attr_name not in omit:
                    attr_description: str = os2_table_attr_descriptions.get(attr_name, "不明")
                    writer.writerow(["-", "-", attr_name, attr_value, attr_description])

    except Exception as e:
        print(f"Error processing {font_file_name}: {e}")

def get_font_name(font: Any) -> Tuple[str, str]:
    family_name: str = None
    style_name: str = None
    if "name" in font:
        for name in font["name"].names:
            if name.nameID == 1:
                family_name = name.string.decode(name.getEncoding())
            elif name.nameID == 2:
                style_name = name.string.decode(name.getEncoding())
    return family_name, style_name

def get_font_metrics(font: Any) -> List[Tuple[str, int]]:
    font_info: List[Tuple[str, int]] = []
    try:
        if "OS/2" in font:
            os2_table: Any = font["OS/2"]
            font_info.append(["Ascender", os2_table.sTypoAscender])
            font_info.append(["Descender", os2_table.sTypoDescender])
            font_info.append(["Line Gap", os2_table.sTypoLineGap])
            font_info.append(["Font Width", getattr(os2_table, 'sxHeight', 0)])  # sxHeightがない場合はデフォルトの値を使う
            font_info.append(["Font Height", os2_table.sTypoAscender - os2_table.sTypoDescender + os2_table.sTypoLineGap])
    except Exception as e:
        print(f"Error processing font metrics: {e}")
    return font_info

if __name__ == "__main__":
    args = parse_args()

    # 既存のCSVファイルがあれば削除
    if os.path.exists(args.out):
        os.remove(args.out)

    fonts_dir: str = args.directory
    for filename in os.listdir(fonts_dir):
        if filename.lower().endswith(".ttc"):
            font_path: str = os.path.join(fonts_dir, filename)
            print(f"Processing {filename}")
            get_font_info(font_path, args.out, args.omit if args.omit else [])

 ダウンロード

コードは次の場所からダウンロードできます。
http://k-hiura.cocolog-nifty.com/blog/files/fontinfo.zip

次のものからなっています。

fontInfo
+-- getFontCSV.py   ChatCPTが生成したコード
+-- getFontCSV.bat  getFontCSV.pyを起動するバッチ
+-- font_info.csv   getoFontCSV.pyの出力
`-- font_info.xlsx  csvから作ったexcel

参考までに◇複数CSVから複数シートのEXCEL-BOOKを作るのツールを用いてexel化したものも置きました

|

« ◇各種フォントでPDF作成 | トップページ | ◆AozoraPDF.py(Python)のGUI化、exe化 »