HSPポータル
サイトマップ お問い合わせ


HSPTV!掲示板


未解決 解決 停止 削除要請

2015
0728
ぺろフォントファイルからファイル名を取得15未解決


ぺろ

リンク

2015/7/28(Tue) 01:40:21|NO.70275

ファイルファイル(.ttf 等)からフォント名を取得したいのですが
色々調べたのですがフォント名の取得のサンプルがありませんでした。
わかる方教えていただけないでしょうか?
お願いいたします



この記事に返信する


kanamaru

リンク

2015/7/28(Tue) 08:40:07|NO.70279

windowsAPIを使ってフォントファイルからのフォント指定。
そのあとに指定されたフォント名を取得すればいいと思います。



ぺろ

リンク

2015/7/28(Tue) 12:50:39|NO.70282

タイトルに誤りがありました。

誤 : フォントファイルからファイル名を取得
正 : フォントファイルからフォント名を取得

WindowsAPIを使ってフォントファイルからフォントの指定ですか
今調べたのですが、よく分かりませんすみません



kanamaru

リンク

2015/7/28(Tue) 15:20:03|NO.70284


#include "gdi32.as" ; 簡易対応チェック if varptr(AddFontMemResourceEx) { notesel buf noteload "(フォントファイル名)" AddFontResource varptr(buf), strsize, 0, varptr(pcFonts) hFont = stat ; フォントハンドル font "(フォント名)", 60 mref BMSCR, 67 dupptr lfFaceName, varptr(BMSCR.56), 32, 2 RemoveFontMemResourceEx hFont } notesel buf noteload "(フォントファイル名)" AddFontMemResourceEx varptr(buf), strsize, 0, varptr(pcFonts) hFont = stat ; フォントハンドル font "(フォント名)", 60 mref BMSCR, 67 dupptr lfFaceName, varptr(BMSCR.56), 32, 2 RemoveFontMemResourceEx hFont
実際に動かしてないのでわかりませんが、こんな感じです。



kanamaru

リンク

2015/7/28(Tue) 17:22:07|NO.70285

lFfacaNameにフォント名が代入されていると思います。



ぺろ

リンク

2015/7/28(Tue) 20:28:05|NO.70291

今スクリプト作動させてみたのですが
フォント名が代入されませんでした
何が原因なのでしょう??



ぺろ

リンク

2015/7/28(Tue) 22:26:20|NO.70296

ちなみに読み込んだフォントファイルからフォント名を取得したいわけでして
つまりフォントファイルを起動せずとも読み込むだけでファイル名を取得したいのです。
今色々探してみましたが、フォント名→インストールされているフォントファイル名なら取得できるみたいですが
やりたい事はなかなか見つかりません



ぺろ

リンク

2015/7/28(Tue) 22:36:39|NO.70297

また間違えてしまいました

読み込むだけでフォント名を取得したいのです。



ぺろ

リンク

2015/7/28(Tue) 22:44:05|NO.70298

今色々調べた所
フォントファイルのフォーマットを調べてフォント名が書かれている部分を抜き出すと言った形で取得できるみたいなのですがC言語でなにがなんだか分かりません><;;
以下参考サイトになります

http://www.geocities.jp/is3000nx/reading/tip/vc.html



kanamaru

リンク

2015/7/28(Tue) 22:52:26|NO.70299

フォーマットを分析するのは厳しいと思います。
とりあえず明日修正版を作ります。
フォントファイルからのフォント指定の方法を間違えていたようです。



ぺろ

リンク

2015/7/28(Tue) 22:54:58|NO.70300

ありがとうございます。
最悪フォントファイル指定でフォントをユーザーが指定しなくてもフォントが適用できたらなと思います



osakana

リンク

2015/9/3(Thu) 03:10:56|NO.71281

しばらく動きが無い様なので書き込んでみます。

.ttf 等から取得したいということですが、
多様な種類のフォントを対象にしたい場合
内部を自分で調べて行くのは無理があるので、
ここはそれとは別の考え方で取得してみます。

手法というか手順としては、
1:現時点でインストールされているフォント名一覧を取得
2:AddFontResource API 関数を使って任意のフォントファイルを一時的に追加する
3:一時的に追加した物を含む、現時点でインストールされているフォント名一覧を取得
4:1と3の一覧の差から指定したフォントファイル名のフォント名を割り出す
という感じです。

HSP にはフォント名の一覧を取得する命令は無い(と思う)ので自分で取得します。
しかしフォント名一覧を取得するためにはフォントの列挙をしますが、
HSP はそれをするのに必須なコールバック関数がありません。
これまでは自分で専用の機械語を埋め込んだり
それが出来るプラグインを別に入手して使用してきましたが、
幸い最近になって、それが手軽に実現できる素晴らしいモジュールを作られた方がいるので
今回はそれを使わせてもらって処理してみました。

性質上、他で偶然同じタイミングでフォントのインストールがあると
それも同時に取得してしまうかもしれません(未確認ですが)
ほぼ起こらない問題でしょうが心配ならば
数回実行して結果が安定なら確定とすると良いかもしれません。


一応使いやすいように無理やりモジュールにまとめてみました
以下モジュールとサンプルです。

// tds12 さんのコールバックモジュールを使用させていただきます // http://hsp.tv/play/pforum.php?mode=all&num=62130 #ifndef _MODCLBK3B2_AS #ifdef _MODCLBK3A1_AS #undef _MODCLBK3A1_AS #undef newclbk3 #undef clbkargprotect #undef CLBKMODE_CDECL #undef _newclbk3 #undef modclbk_term #endif #ifdef _MODCLBK3B2_AS #undef clbk_getthisptr #endif #define global _MODCLBK3A1_AS #define global _MODCLBK3B1_AS #define global _MODCLBK3B2_AS #define global _MODCLBK3B3_AS #define global newclbk3(%1,%2 = 0,%3,%4 = 0) tmpclbklb@modclbk3b3=%3:%1=_newclbk3(%2,tmpclbklb@modclbk3b3,%4) //新しい関数ポインタを取得する // %1...関数ポインタを受け取る変数 // %2...引数の数 // %3...呼び出されるラベル // %4...作成のモード(CLBKMODE) #define global clbkargprotect(%1) lp@modclbk3b3=lparam:wp@modclbk3b3=wparam:dupptr args@modclbk3b3,lp@modclbk3b3,wp@modclbk3b3*4,4:dim %1,wp@modclbk3b3:memcpy %1,args@modclbk3b3,wp@modclbk3b3*4 //引数を取得する // %1...引数を受け取るための変数 #module "modclbk3b2" #define ctype uintbitshiftright(%1,%2) (((%1&$7fffffff)>>%2)|((1&(%1>>31))<<(31-%2))) #uselib "msvcrt.dll" #cfunc malloc "malloc" int #func free "free" int #uselib "kernel32.dll" #func VirtualProtect "VirtualProtect" var,int,int,var #cfunc LoadLibrary "LoadLibraryA" sptr #cfunc GetProcAddress "GetProcAddress" int,sptr #func FreeLibrary "FreeLibrary" int #define global CLBKMODE_CDECL $00000001 // 呼び出し規約をcdeclに設定する // 通常はthiscall(clbk_getthisptrを呼ばなければstdcall)で、CLBKMODE_CDECL定数を指定した時のみcdeclになります。 #defcfunc _newclbk3 int _argmax,var clbklb,int mode // int _argmax ... 関数の引数の数 // var clbklb ... 呼び出すサブルーチンが入った変数 // int mode ... コールバック関数のモード(CLBKMODE_) dim _x,1 mref ctx,68 ilb=0 memcpy ilb,clbklb,4,0,0 argmax = _argmax if inited == 0{ inited = 1 dim ptrtable ptrmax = 0 hcrt = LoadLibrary("msvcrt.dll") ptrtomalloc = GetProcAddress(hcrt,"malloc") ptrtofree = GetProcAddress(hcrt,"free") thisptr = 0 } code_callptr = lpeek(ctx,168 + 48)// if argmax>0{ dim clbk,57 clbk(0) = $83ec8b55,$45c730ec,$000000fc,$f845c700 clbk(4) = $00000000,$00e045c7,$c7000000,$0000e445 clbk(8) = $45c70000,$000000ec,$d845c700,$00000000 clbk(12) = $8bd84d89,$e0c1f845,$4d8b5002,$83d1ffe0 clbk(16) = $458904c4,$f445c7d4,$00000000,$00dc45c7 clbk(20) = $c7000000,$0000f045,$45c70000,$000000e8 clbk(24) = $0c558d00,$8be85589,$4d8bd445,$c7088908 clbk(28) = $0001d045,$09eb0000,$83d0558b,$558901c2 clbk(32) = $f8458bd0,$7dd04539,$e84d8b1a,$8904c183 clbk(36) = $558be84d,$d4458bd0,$8be84d8b,$0c89fc49 clbk(40) = $8bd5eb90,$458bf455,$8b0289f8,$558bdc4d clbk(44) = $681189d4,$00000000,$ffec458b,$04c483d0 clbk(48) = $8bf04d8b,$fc558911,$00e845c7,$8b000000 clbk(52) = $8b50d445,$d1ffe44d,$8b04c483,$e58bfc45 clbk(56) = $0000c25d lpoke clbk,$10,argmax:lpoke clbk,$17,ptrtomalloc:lpoke clbk,$1e,ptrtofree lpoke clbk,$25,code_callptr:lpoke clbk,$2c,varptr(thisptr) lpoke clbk,$48,varptr(ctx) + 36:lpoke clbk,$4f,varptr(ctx) + 40 lpoke clbk,$56,varptr(ctx) + 784:lpoke clbk,$b4,ilb if ((mode & $f) == CLBKMODE_CDECL) == 0:wpoke clbk,$e2,(argmax * 4) & $ffff funcsize = 228 } if argmax==0{ dim clbk,25 clbk(0) = $83ec8b55,$45c718ec,$000000fc,$f045c700 clbk(4) = $00000000,$00f845c7,$c7000000,$0000e845 clbk(8) = $45c70000,$000000f4,$ec45c700,$00000000 clbk(12) = $8bec4d89,$00c7f845,$00000000,$c7e84d8b clbk(16) = $00000001,$00006800,$558b0000,$83d2fff0 clbk(20) = $458b04c4,$89088bf4,$458bfc4d,$5de58bfc clbk(24) = $000000c3 lpoke clbk,$10,code_callptr:lpoke clbk,$17,varptr(ctx) + 36 lpoke clbk,$1e,varptr(ctx) + 40:lpoke clbk,$25,varptr(ctx) + 784 lpoke clbk,$2c,varptr(thisptr):lpoke clbk,$46,ilb funcsize = 100 } clbkptr = malloc(funcsize) dupptr clbkfunc,clbkptr,funcsize,4 memcpy clbkfunc,clbk,funcsize VirtualProtect clbkfunc,funcsize,$40,_x ptrtable(ptrmax) = clbkptr ptrmax++ return clbkptr #defcfunc clbk_getthisptr //Thisポインタを取得する。 //コールバックとして呼び出された直後に別変数へコピーしなければならない。 return thisptr #deffunc modclbk_term onexit repeat ptrmax free ptrtable(cnt) loop if inited{ FreeLibrary hcrt } ptrmax = 0 return #global #endif // インストールフォント一覧取得モジュール // http://hsp.tv/play/pforum.php?mode=all&num=62130#65032 // の kanahiron さんの書き込みを参考に書き直した物 #module mod_enumfont #uselib "gdi32.dll" #func global EnumFontFamiliesEx "EnumFontFamiliesExA" sptr,sptr,sptr,sptr,sptr // インストール済みのフォント名一覧を取得 #deffunc get_enumfont var fontlist, int charset,\ local pfunc, local lf, local num, local sep, local tmp, local name, local prm // コールバックポインタ取得 newclbk3 pfunc, 4, *CALLBACK_EnumFontFamExProc // フォント名列挙関数のパラメータに渡す LOGFONT 構造体を準備 sdim lf, 60 :poke lf, 23, charset // コールバック処理内で使用する変数を準備 num = 0 ; 列挙数 sep = "\n" ; フォント名の区切り文字 fontlist = "" ; 書き込み先 tmp = "" ; フォント名のバックアップ // フォント名列挙のコールバック開始 EnumFontFamiliesEx hdc, varptr(lf), pfunc, 0, 0 return num // コールバック関数に見立てたラベル *CALLBACK_EnumFontFamExProc // コールバック関数のパラメータを取得 clbkargprotect prm // パラメータからフォント名を取得 #if 01 dupptr name, prm + 28, 32, 2 #else dupptr name, prm + 60, 64, 2 #endif // フィルタリング if peek(name) != '@' & name ! tmp { ; 横書き用でダブらないフォント名 if num > 0 :fontlist += sep fontlist += name num ++ } tmp = name ; 次の判定のためにフォント名をバックアップ return 1 #global // 指定した2つの文字列の行要素を相殺し違いのみを取り出すモジュール // 気分的に sqlele を使ってみるの巻き #include "sqlele.hsp" #module mod_strsymdif // 2つの文字列から互いに固有の行を取得 #deffunc get_strsymdif var result, var s1, var s2, local num sql_open ":memory:" sql_q "create table tmp1(data text unique)" ; テーブル作成 sql_q "create table tmp2(data text unique)" ; テーブル作成 add_db "insert into tmp1 values('%s')", s1 ; s1 を一行ずつ全行追加 add_db "insert into tmp2 values('%s')", s2 ; s2 を一行ずつ全行追加 ; tmp2 が含まれない tmp1 と、tmp1 が含まれない tmp2 を、結合した結果を result に受け取る get_db "select data from tmp1 where data not in(select data from tmp2) union select data from tmp2 where data not in(select data from tmp1) order by data", result num = stat sql_close return num // ローカル命令 改行ごとにデータベーステーブルに追加 #deffunc local add_db str sql, var str_add, local idx, local stt, local tmp repeat getstr tmp, str_add, idx stt = stat idx += strsize sql_q strf(sql, tmp) if stt = 0 :break loop return // ローカル命令 データベーステーブルからデータを取得し改行区切り文字列に仕立て直す #deffunc local get_db str sql, var str_get, local num str_get = "" sql_q sql num = stat repeat num if cnt > 0 :str_get += "\n" str_get += sql_v("data") sql_next loop return num #global // 指定したフォントファイル名のフォント名を取得するモジュール // 一時的なインストール前後のフォントリストから推測する手法 #module mod_getfontname // フォントを一時的に使えるようにするAPI #uselib "gdi32.dll" #func AddFontResource "AddFontResourceA" str #func RemoveFontResource "RemoveFontResourceA" str #define ANSI_CHARSET $00000000 #define DEFAULT_CHARSET $00000001 #define SHIFTJIS_CHARSET $00000080 #define CHARSET DEFAULT_CHARSET // 一時的なフォントを追加前後のフォントリストの差からフォント名を取得する // パラメータには フォント名を受け取る変数, 取得対象のフォントファイルのパス を渡す #deffunc get_fontname var fontname, str path_fontfile, local fontlist1, local fontlist2 get_enumfont fontlist1, CHARSET ; はじめに実行時のインストールフォント一覧を取得 AddFontResource path_fontfile ; 任意のフォントを一時的にインストール get_enumfont fontlist2, CHARSET ; 一時的にインストールした状態のフォント一覧を取得 RemoveFontResource path_fontfile ; 一時的にインストールしたフォントを取り除く get_strsymdif fontname, fontlist1, fontlist2 ; 2つのフォントリストの重複を取り除いたものを取得 return stat #global // 以下サンプル // フォントパス fontpath = "font.ttf" ; ←ここに取得したいフォントファイルのパスを指定する // 指定したフォントファイル名からフォント名を取得する get_fontname fontname, fontpath mes "フォント名 = " + fontname mes "取得数 = " + stat
いい加減な作りでお恥ずかしいですが
こちらで試した限りではなんとか取得できている様です。


他にも、TrueType フォントだけで十分ならばこちらもどうぞ
http://zuzazann.boy.jp/wiki/index.php?get_font_info



ぺろ

リンク

2015/9/12(Sat) 01:26:10|NO.71603

お返事遅れてしまい申し訳御座いません。
フォントファイルからフォント取得
一時的にフォントを適用してmesするとちゃんとフォントが適用されていますが
二度目以降、フォントが使えなくなりますがこれは何故なんでしょうか?



osakana

リンク

2015/9/13(Sun) 02:52:39|NO.71631

どっちのモジュールを使って、どんなスクリプトを
書いたのか教えてもらえますか?

ちなみにどちらのモジュールでも、
PCにインストールしていないフォントファイルを利用する場合は
一時的にフォントを使えるようにするAPIを使用してから
font 命令で指定しないと反映されません。



osakana

リンク

2015/10/8(Thu) 10:09:15|NO.72171

> 他にも、TrueType フォントだけで十分ならばこちらもどうぞ
> http://zuzazann.boy.jp/wiki/index.php?get_font_info

実行できなかったのを修正しました。
手元では実行できてたので気が付きませんでした…。



toto

リンク

2015/10/9(Fri) 01:39:18|NO.72184

フォント名を取得できるAPIがあってほとんどの種類のフォントに対応しているみたい。

#include "gdi32.as" #define QFR_DESCRIPTION 1 #define QFR_LOGFONT 2 ;フォントファイル名 fontfile=dir_win+"\\Fonts\\msgothic.ttc" AddFontResource fontfile if stat=0:mes "失敗":stop bufsize=0 GetFontResourceInfoW fontfile,varptr(bufsize),varptr(buf),QFR_DESCRIPTION sdim buf,bufsize GetFontResourceInfoW fontfile,varptr(bufsize),varptr(buf),QFR_DESCRIPTION if stat=0:mes "失敗":goto *exit title cnvwtos(buf) bufsize=0 GetFontResourceInfoW fontfile,varptr(bufsize),varptr(buf),QFR_LOGFONT dim buf,(bufsize+3)/4 GetFontResourceInfoW fontfile,varptr(bufsize),varptr(buf),QFR_LOGFONT if stat=0:mes "失敗":goto *exit repeat bufsize/92;sizeof(LOGFONTW) fontname=cnvwtos(buf(23*cnt+7)) mes fontname loop *exit RemoveFontResource fontfile



ONION software Copyright 1997-2023(c) All rights reserved.