ホームページ開発ツール>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での実装

 以下のメソッドを(必要なプロジェクトに)追加
メソッド名: 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
注)objectAtIndex:の戻り値が何型なのかよく分かりません。こちらのサイトによると、NSMutableAttributedStringのような気もしますが、だとすると(上記はFontメソッドを直接発行しているが)NSDictionaryを経由して取得した方がいいのかもしれません。


 おわりに

 取得したフルネームは、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]