ホームページ>開発ツール>Xojo / Real Studio Trial and Error・CocoaのDeclareで書体を含めたフォント名を取得する
Xojo / Real Studio Trial and Error
目次
CocoaのDeclareで書体を含めたフォント名を取得する
はじめに
以下は、Xojo Cocoaビルドについての話題です。
TextAreaのスタイル付きテキストにおいて、フォント名の取得にはFontプロパティを用いることが一般的ですが、得られる名前はファミリー名で、書体(TypeFace)名、または書体名を含んだフォント名(以下、フルネーム)は取得できません。
Real Studioの頃は、TextStyleDataからフルネームを得るという技を使うことで、この件を回避できていたのですが、Xojo以降は(TextStyleDataがDeprecatedとなったため)不可となってしまいました。
なので、代替手段がないか、調べてみました。
なお検証には、Xojo 2014 Release 2を用いています。(Mac mini + OS X 10.9.5 Mavericks)
方針
方針を立てるにあたって、何か手がないか、情報の宝庫(!)であるmacoslibを調べてみました。
このとき、偶々CopyFont:メソッドが手掛かりとしてあったので、この項目を見てみたらt.TextViewRefという記述があったので、引き続きTextViewRefを見ると、documentViewが目につきました。これはNSScrollVewのメッセージ(メソッド)で、送り先にはXojoのTextArea(のハンドル)を直接指定しています。
これは即ち、XojoのTextArea(Cocoa)はNSScrollVewそのもの(またはそれを継承したコントロール)であることを示しています。改めて確認したら、周知の事実だった…つまり、CocoaのAPIを辿っていけば、必要な情報(NSFontはフルネームを持っている)に行き着けるかもしれない、ということです、
なので、その線に沿って更に調べることとしました。(結果として、フォントのフルネームのリストを得ることができました。)
Xojoでの実装
以下のメソッドを(必要なプロジェクトに)追加
注)objectAtIndex:の戻り値が何型なのかよく分かりません。こちらのサイトによると、NSMutableAttributedStringのような気もしますが、だとすると(上記はFontメソッドを直接発行しているが)NSDictionaryを経由して取得した方がいいのかもしれません。メソッド名: GetFontNameList 引数: EF As TextArea, byRef sFont() As String Dim pnt1 As Ptr declare function documentView lib "Cocoa" selector "documentView" (obj_id as Integer) as Ptr // Return NSTextView* pnt1 = documentView(EF.Handle) // EF.Handle = NSScrollVew* Dim pnt2 As Ptr declare function textStorage lib "Cocoa" selector "textStorage" (obj_id as Ptr) As Ptr // Return NSTextStorage* pnt2 = textStorage(pnt1) Dim pnt3 As Ptr declare function attributeRuns lib "Cocoa" selector "attributeRuns" (obj_id as Ptr) As Ptr // Return NSArray* pnt3 = attributeRuns(pnt2) Dim cnt As Integer declare function aCount lib "Cocoa" selector "count" (obj_id as Ptr) As Integer // Return Integer cnt = aCount(pnt3) Dim pnt4 As Ptr declare function ObjectAtIndex lib "Cocoa" selector "objectAtIndex:" (obj_id as Ptr, idx as Integer) As Ptr // Return ??? Dim pnt5 As Ptr declare function aFont lib "Cocoa" selector "font" (obj_id as Ptr) As Ptr // Return NSFont* declare function fontName lib "Cocoa" selector "fontName" (obj_id as Ptr) As CFStringRef // Return NSString* (Full Name) Dim i As Integer for i=0 to cnt-1 pnt4 = objectAtIndex(pnt3,i) pnt5 = aFont(pnt4) sFont.Append fontName(pnt5) next
おわりに
取得したフルネームは、StyleRunを用いてデータを作成する際に、StyleRunから取得したフォント名と差し替えることで、(フルネームを)データ中に保持することができます。(StyleRunの数と並びは、上記例のsFontの数と並びに一致する筈。)
なお、保持したデータをTextAreaにセットする場合は、フルネームのフォント名をそのまま使えます。(書体も含めて復元されます。)
最後に毎度の繰り返しになりますが、アプリを一から作るのであれば、macoslibをベースにした方が遥かに楽です。
あと、余談ですが、TextAreaの同類であるTextFieldは、NSTextFieldに対応している模様。
お世話になったサイト
貴重な情報をご提供頂いている皆様に、お礼申し上げます。(以下、順不同)
参考サイト(1):Xojo: Speeding up TextArea modifications under Cocoa
参考サイト(2):Text System Storage Layer Overview: The Storage Layer: The NSTextStorage Class
参考サイト(3):StyleRun - Xojo Documentation
更新履歴
2014.10.30 新規作成
[Home] [MacSoft] [Donation] [History] [Privacy Policy] [Affiliate Policy]