フォントファイルからフォント名を取得するモジュールを作ったのでこちらで公開してみます。
いろいろと中途半端なところがありますが、とりあえず公開しておいて後日更新することにします。
このモジュールを使用することで以下の命令が有効になります。
get_fontname
この命令に指定するパラメータは、
第一パラメータには フォントファイルへのパス 第二パラメータには 結果を受け取る変数
を指定します。
「例」
get_fontname "font.ttf", getname
なおフォントファイルの対応形式は、
TTF, TTC, OTF
のみになっています。
フォントのバージョン情報など多々無視してたり、私自身フォントについて詳しい訳でもないので、対応形式であっても上手く読み込めない物もあるかもしれません。何か問題があれば報告して頂ければありがたいです。
もしくは wiki なので修正してくださっても構いません、むしろ助かります。
// モジュールの説明 : // これは TrueType(Collection 対応), OpenType の // フォントファイルからフォント名を取得するモジュールです。 // // このモジュールが提供する命令 : // get_fontname # ttf, ttc, otf 形式のフォントファイルのパスからフォント名を取得する #ifndef mod_getfontname #module mod_getfontname // 対応したフォントファイルからフォント名を取得する(ttf, ttc, otf に対応) // get_fontname fontpath, getdata // fontpath : 取得するフォントのファイル名 // getdata : 取得したフォント名を受け取る変数 // 戻り値 : 取得したフォント名の数が返る(失敗したら 0 が返る) #deffunc get_fontname str fontpath, var getdata // ファイルの存在確認 exist fontpath if strsize = -1 :return 0 // 拡張子によって処理を分ける switch getpath(fontpath, 2 | 16) // そのまま TTF として取得する case ".ttf" case ".otf" get_fontname_ttf fontpath, getdata swbreak // TTC ヘッダーから TTF のオフセットを読み取ってそこから取得する // (get_fontname_ttc 内で get_fontname_ttf をオフセット付きで実行) case ".ttc" get_fontname_ttc fontpath, getdata swbreak default return 0 swbreak swend return stat // TTC 形式のフォントファイルからフォント名を取得する // get_fontname_ttc fontpath, getdata // fontpath : 取得するフォントのファイル名 // getdata : 取得したフォント名を受け取る変数 // 戻り値 : 取得したフォント名の数が返る(失敗したら 0 が返る) #deffunc local get_fontname_ttc str fontpath, var getdata // TTCヘッダーのオフセットテーブルへのオフセット配列直前までを読み込む sdim TTC_Header, 12 bload fontpath, TTC_Header, 12 // 読み込んだ TTCヘッダー部分のデータを個別変数に取り出す TTCTag = "" :lpoke TTCTag, 0, lpeek(TTC_Header, 0) ; Version = lpeek_big2litle(TTC_Header, 4) numFonts = lpeek_big2litle(TTC_Header, 8) // ttc フォントファイルじゃなかったら処理しない if TTCTag ! "ttcf" :return 0 // 取得した numFonts を元に TTCヘッダーのオフセットテーブルを配列に取得 dim OffsetTable, numFonts bload fontpath, OffsetTable, 4 * numFonts, 12 // オフセットテーブル配列をビッグエンディアンからリトルエンディアンに変換して格納し直す repeat numFonts OffsetTable(cnt) = lpeek_big2litle(OffsetTable(cnt)) loop // オフセットテーブルへのオフセットを使ってフォント名を取り出す getdata = "" repeat numFonts get_fontname_ttf fontpath, fontname, OffsetTable(cnt) if cnt > 0 :getdata += "\n" getdata += fontname loop return numFonts // TTF 形式のフォントファイルからフォント名を取得する // get_fontname_ttc fontpath, getdata // fontpath : 取得するフォントのファイル名 // getdata : 取得したフォント名を受け取る変数 // 戻り値 : 取得すれば 1 が、出来なければ 0 が返るが今のところ 1 しか返らない #deffunc local get_fontname_ttf str fontpath, var getdata, int offset_position // フォントの始めのオフセットテーブルの情報を読み込む dim offset_table, 3 bload fontpath, offset_table, 12, offset_position sfnt_version = offset_table numTables = wpeek_big2litle(offset_table, 4) searchRange = wpeek_big2litle(offset_table, 6) entrySelector = wpeek_big2litle(offset_table, 8) rangeShift = wpeek_big2litle(offset_table, 10) // 指定したタグ名のテーブルを探しそこから値を取得 dim table_record, 4 * numTables bload fontpath, table_record, 16 * numTables, 12 + offset_position tr_tag = "" repeat numTables index = cnt * 4 memcpy tr_tag, table_record(index), 4 if tr_tag = "name" :break loop tr_offset = lpeek_big2litle(table_record, index * 4 + 8) tr_length = lpeek_big2litle(table_record, index * 4 + 12) // 名前テーブルから値を取得 dim naming_table, 2 bload fontpath, naming_table, 6, tr_offset nt_count = wpeek_big2litle(naming_table, 2) nt_stringOffset = wpeek_big2litle(naming_table, 4) // ネームレコードの特定の要素を取得 dim name_records, 3 * nt_count bload fontpath, name_records, 12 * nt_count, tr_offset + 6 repeat nt_count index = cnt * 12 nr_platformID = wpeek_big2litle(name_records, index) nr_languageID = wpeek_big2litle(name_records, index + 4) nr_nameID = wpeek_big2litle(name_records, index + 6) nr_length = wpeek_big2litle(name_records, index + 8) nr_offset = wpeek_big2litle(name_records, index + 10) if nr_platformID = 3 & nr_languageID = 0x409 & nr_nameID = 4 :break loop // ファイルからフォント名を取得 getdata = bload_biguni2sjis(fontpath, tr_offset + nt_stringOffset + nr_offset, nr_length) return 1 // 内部で使用する専用マクロと命令 #define ctype getbyte(%1,%2)((%1) >> (%2) * 8 & $ff) #defcfunc big2litle_endian_4 int lit return getbyte(lit, 0) << 24 | getbyte(lit, 1) << 16 | getbyte(lit, 2) << 8 | getbyte(lit, 3) #defcfunc big2litle_endian_2 int lit return getbyte(lit, 0) << 8 | getbyte(lit, 1) #defcfunc lpeek_big2litle var data, int idx return big2litle_endian_4(lpeek(data, idx)) #defcfunc wpeek_big2litle var data, int idx return big2litle_endian_2(wpeek(data, idx)) #deffunc big2litle_endian_unicode var data, int size repeat size / 2 wpoke data, cnt * 2, wpeek_big2litle(data, cnt * 2) loop return #defcfunc bload_big2litle_4 str path, int idx ldata = 0 bload path, ldata, 4, idx return big2litle_endian_4(ldata) #defcfunc bload_big2litle_2 str path, int idx wdata = 0 bload path, wdata, 2, idx return big2litle_endian_2(wdata) #defcfunc bload_biguni2sjis str path, int idx, int size sdim string, size + 2 bload path, string, size, idx big2litle_endian_unicode string, size return cnvwtos(string) #global #endif // サンプルスクリプト #if 0;1 ; ←ここを 1 にするとサンプルスクリプトを実行できる // 実行するサンプルスクリプトを切り替える(0〜1) #define TEST 0 ; ←ここの数字を変えると実行サンプルが変わる /* 簡単な使い方のサンプル */ #if TEST = 0 // フォントファイルのパス fontpath = "font.ttf" ; ここに取得したいフォントのファイル名を代入 // フォントファイル名からフォント名を得る get_fontname fontpath, fontlist ; fontpaht 部分には直接パスを書いてもOK num = stat ; ここに取得数が入る mes "取得数:" + num // 取得できていればフォント名を表示する if num > 0 { mes fontlist ; 取得したフォント名を表示 } #endif /* フォントフォルダから取得してみるサンプル */ #if TEST = 1 #define CSIDL_FONTS 0x0014 #define DIR_FONT dirinfo(CSIDL_FONTS | 0x10000) screen 0, 800, 480 // フォントフォルダ内のフォントファイル一覧を取得 chdir DIR_FONT notesel list dirlist list_tmp, "*.ttc" :list += list_tmp :listmax += stat dirlist list_tmp, "*.ttf" :list += list_tmp :listmax += stat dirlist list_tmp, "*.otf" :list += list_tmp :listmax += stat title "" + listmax + " files" ; ファイル数表示 sdim list_tmp ; メモリ削減 // リストボックス作成 lb_w = GINFO_WINX / 3 lb_h = GINFO_WINY - 15 listsel = -1, -1 objsize lb_w listbox listsel, lb_h, list cx = lb_w + 5 // リストボックスの選択変更を監視 repeat wait 25 if listsel ! listsel(1) { listsel(1) = listsel // 画面クリア color 255, 255, 255 :boxf color :pos lb_w, 0 // 選択したフォントファイル名を取得して表示 noteget filename, listsel mes "「ファイル名」\n" + filename + "\n" // フォントファイルからフォント名を取得 get_fontname filename, fontname num = stat // 状況に応じて表示 if num > 0 { // コレクションファイルなら格納数を表示 if getpath(filename, 2 | 16) = ".ttc" { mes "「格納数」\n" + num + "\n" } // 取得したフォント名を表示 mes "「フォント名」" mes fontname } else { mes "取得できませんでした。" } } loop #endif #endif