MOSA Multi-OS Software Artists

MOSAはソフトウェア開発者を支援します

  • iPhone/iPod touch アプリ紹介
  • MOSA掲示板
  • 活動履歴
  • About MOSA(English)

MOSA Developer News[MOSADeN=モサ伝]第238号

2007-02-06

目次

  • 「「Wonderful Server Life」    第36回   田畑 英和
  • 小池邦人の「Carbon API 徒然草」
  • SqueakではじめるSmalltalk入門  第78回   鷲見 正人
  • ニュース・解説               木下 誠

「Wonderful Server Life」  第36回  田畑 英和

  〜アクセス権編〜

 ハードウェアRAIDのストレージ「Xserve RAID」がアップデートしました。
今回はまずこのニュースから始めたいと思います。アップデートしたといいましても基本的な仕様は変更ないのですが、利用可能なドライブが250GB、500GBに加え、新たに750GBのドライブも利用できるようになりました。
 Apple Store(Online)で750GBのドライブを14基(Xserve RAIDはドライブを最大14基搭載可能)選択すると計10.5TBのストレージが購入でき、価格は税込みで1,721,607円となります。10.5TBといいましても使用するRAIDのレベルにより、実際に利用可能な容量は少なくなります。ちなみに1GBあたりの価格を計算すると約164円になります。

 Xserve RAIDの管理ツール「RAID Admin」およびファームウェアもアップデートしました。このバージョンでは新たにリリースされた750GBのドライブをサポートするようになっています。またこれまでのバージョンでは「RAID Admin」で設定を変更しても設定項目が一部正しく保存されない問題がありましたが、1.5.1のアップデートでこの問題は解消されました。
 ファームウェアのアップデートですが、「RAID Admin」から実施することができます。「RAID Admin」の「システム」>「ファームウェアをアップデート」メニューから最新のファームウェアのアップデートファイルを選択してアップデートを実施します。ファームウェアのアップデート時にはXserve RAIDの再起動が必要になります。

・Xserve RAID Admin Tools v1.5.1
http://www.apple.com/jp/ftp-info/reference/xserveraidadmintools151.html
・「RAID Admin」とファームウェアのアップデートファイルのインストール先「/アプリケーション/ユーティリティ/Xserve RAID Update」
・ファームウェアのファイル名
「firmware-1.5.1-1.51.xfb」

◇ACLのアクセス権
 さて、本題のアクセス権に話を戻すとしましょう。前回まではPOSIXのアクセス権の確認方法と「ワークグループマネージャ」を使ったPOSIXのアクセス権の設定方法を解説しました。今回からv10.4で新たに導入されたACLのアクセス権について解説いたします。
 まずACLのアクセス権の概要をPOSIXのアクセス権と比較しながらみていきたいと思います。POSIXのアクセス権ではオーナーとグループは1つずつしか設できませんでしたが、ACLのアクセス権ではユーザおよびグループを複数設定することができます。
 POSIXのアクセス権しか使用できない場合に、例えばグループごとにアクセス権を管理したいとします。あるグループは特定のフォルダに対して「読み出し/書き込み」ができて、別のグループは「読み出し専用」しかできないように設定したいとします。しかしPOSIXのアクセス権ではフォルダに対してグループは1つしか設定できないためこのような設定はできないことになります。ですがACLのアクセス権の場合は複数のグループを1つのフォルダに対して設定できますので、より複雑なアクセス権の管理ができるようになります。

 ユーザ、グループが複数設定できるという特徴に加え、ACLのアクセス権ではPOSIXよりも多くの種類のアクセス権を設定することができます。POSIXのアクセス権は基本的に3種類(読み出し/書き込み/実行)しかありませんが、ACLのアクセス権では3つのカテゴリーに分類された次のような13種類のアクセス権を設定することができます。

・ACLのアクセス権の種類
<情報を管理>
 アクセス権を変更/オーナーを変更
<読み出し>
 属性を読み込む/拡張属性を読み込む/フォルダの内容を一覧表示
 フォルダをスキャン/アクセス権を読み込む
<書き込み>
 属性を書き込む/拡張属性を書き込む/ファイルを作成
 フォルダを作成/削除/サブフォルダとファイルを削除

 これらのアクセス権を複数のグループとユーザに対してそれぞれ設定することができます。さらに、ACLのアクセス権には継承の機能があり、フォルダに設定したアクセス権を、フォルダ内のファイルやフォルダに継承させることができます。
 どのレベルまで継承を行うかも設定することができ、継承のレベルとしては次の4種類が用意されています。

・ACLの継承のレベル
  このフォルダに適用
  子フォルダに適用
  子ファイルに適用
  すべての子孫に適用

 ACLのアクセス権には継承の機能があるため、個別のファイルにそれぞれアクセス権を設定しなくても、フォルダにアクセス権を設定するだけで、内部のファイル/フォルダのアクセス権を制御することができます。
 ACLのアクセス権のより詳しい仕様についてはMac OS X Serverのマニュアル「ファイルサービスの管理」(P.19)に解説があります。

・「ファイルサービスの管理」
http://images.apple.com/jp/server/pdfs/File_Services_v10.4_j.pdf
                             
 つづく

小池邦人のCarbon API 徒然草(2007/02/02)

〜 Carbonモダンアプリケーションへの道(その9) 〜

今回からは、Localizable.stringsなどから入手したテキストをウィンドウに表示したりプリントアウト(印刷)したりする状況を考えてみます。Carbonモダンアプリケーションでは、いったいどんなAPIを使えば最良の結果を得られるのでしょうか?

昔々、ToolBox APIを使ったテキスト描画には、QuickDrawのDrawString()や
DrawText()、もしくはTextEdit APIのTETextBox()などを選択していました(いや〜懐かしい)。しかし残念ながら、これらのAPIはMac OS X 10.4以降ではすべて「DEPRECATED指定ですので、そのうち消えてしまう運命です。それではテキスト描画を実行するにはどんなCarbon APIを使えば良いのでしょうか?

最初に思いつくのは、CoreGraphics(Quartz 2D)のテキスト描画用APIを使うことです。CoreGraphicsには、以下の2つのテキスト描画用APIが用意されています。

void CGContextShowText( CGContextRef c,const char *string,size_t length );

void CGContextShowTextAtPoint( CGContextRef c,float x,float y,const char
                                                 *string, size_t length );

CGContextShowText()とCGContextShowTextAtPoint()の違いは、先んじてテキスト描画位置をCGContextSetTextPosition()で指示しておくかどうかです。また、描画用フォントのサイズや種類はCGContextSelectFont()で、描画モードはCGContextSetTextDrawingMode()で設定します。QuickDraw環境とは異なりCoreGraphics環境ではテキスト描画位置は左下が原点となり、位置指定用の座標値(X,Y)には浮動小数点(1.0が1/72インチ)を利用しますので注意してください。

void drawQuartzText( CGContextRef cont )
{
    CGContextSaveGState( cont );     // 現在のCGContext環境を保存する
    CGContextSetTextDrawingMode( cont,kCGTextFill );     // 塗り文字
    CGContextSetRGBFillColor( cont,1.0,0.0,0.0,1.0 );    // 赤色指定
    CGContextSelectFont( cont,"Geneva",64.0,kCGEncodingMacRoman ); // フォン
ト
    CGContextShowTextAtPoint( cont,10,10,"Think Different",15 );   // 描画文
字
    CGContextFlush( cont );          // 描画実行
    CGContextRestoreGState( cont );  // 保存しておいたCGContext環境の復帰
}


上記ルーチンを実行すると、ウィンドウの左下付近に64ポイントのGenevaフォントで赤色の「Think Different」が描画されます。ちなみCGContextSetTextDrawingMode()で指定できるテキスト描画モードは以下の8種類です。

enum CGTextDrawingMode {

    kCGTextFill,
    kCGTextStroke,
    kCGTextFillStroke,
    kCGTextInvisible,
    kCGTextFillClip,
    kCGTextStrokeClip,
    kCGTextFillStrokeClip,
    kCGTextClip
};


kCGTextFill指定は文字のペイント描画です、kCGTextStrokeは縁取りのみの描画となります。kCGTextFillStrokeは各パートに別々の色が指定できます。kCGTextInvisibleは描画はしませんが、カレント描画位置のみを移動させます。最後にClipが付いたモードで描画した場合には、現在のクリッピング領域(Current Clipping Path)により描画領域が制限されます。一番最後の、kCGTextClipはテキスト描画はせず、描画対象がクリッピング領域に影響を受けるかどうかの判定に用います。

テキスト描画での色の指定方法は、CoreGraphicsで描画する他の図形とまったく同じであり、CGContextSetRGBFillColor()やCGContextSetRGBStrokeColor()で指定します。RGBの値は0.0から1.0の範囲で(0.0,0.0,0.0)で黒を(1.0,1.0,1.0)で白を表します。最後の引数は描画時のαチャンネル値(透明度)の指定で、1.0は完全な不透明を表します。また、描画文字のアンチエイリアスを制御したい時にはCGContextSetAllowsAntialiasing()を使います。2つ目の引数にfalseを渡せばアンチエイリアスはOFFになり、trueを渡せば再度ONとなります。

テキスト描画の位置やその方向は、他の図形描画と同様に、CGContextのCTM(Current Transformation Matrix)の影響を受けます。CTMとは描画用変換マトリックスのことです。例えば、CGContextRotateCTM()で角度を指定すれば、ある位置を中心にテキストを回転させて描画することも可能です(QuickDrawでは難しかった)。先ほどのルーチンのCGContextSaveGState()の次の行に以下の処理を追加すれば、描画テキストを原点(左下)を中心に左回りに45度回転させることができます。

CGContextRotateCTM( cont,3.1415/4.0 );

また、同様に以下のルーチンを追加すると、テキストはウィンドウの左上(QuickDrawと同じ座標系)に上下ミラー反転されて描画されることになります。

void flipQuartzContxt( WindowRef window,CGContextRef cont )
{
    Rect    prt;

    GetWindowPortBounds( window,&prt );
    CGContextTranslateCTM( cont,0.0,(float)(prt.bottom-prt.top) );
    CGContextScaleCTM( cont,1.0,-1.0 );
}


これらのAPI、使い勝手はQuickDrawのDrawText()と似たようなレベルなのですが、テキスト描画に日本語フォントを指定しようとすると大きな壁にぶつかります。フォント指定方法が良く分からないのです。先ほどの例では、CGContextSelectFont(に”Geneva”という文字列を代入し指定しています。この名称にはPostScriptフォント名を使う必要があるようですが、日本語フォント(例えばヒラギノ)のPostScriptフォント名がすぐに分かりません。そこで、もっと簡単な指定方法がないものかと探してみると、CGContext.hには以下のようなAPIも用意されていました。

void CGContextSetFont( CGContextRef c,CGFontRef font);

CGFontRefについては、CGFont.hの方に色々と操作するAPIが定義されていますので、そちらを探してみると、CGFontRefを得るために以下のルーチンが定義されていました。

CGFontRef CGFontCreateWithPlatformFont( void *platformFontReference );

で、引数として渡す「platformFontReference」とは何ぞや? ということでヘッダファイルのコメントを読んでみると、「Mac OS XではATSFontRefのことである」と記載されています。そこで今度はATSFont.hを探索して以下の2つのAPIを探し出しました。

OSStatus ATSFontFamilyGetName(
  ATSFontFamilyRef   iFamily,
  ATSOptionFlags     iOptions,
  CFStringRef *      oName );

ATSFontRef ATSFontFindFromName(
  CFStringRef      iName,
  ATSOptionFlags   iOptions );

フォントパネルで入手した情報を使いATSFontFindFromName()でフォントのファミリー名を得て、それをATSFontFindFromName()に渡してATSFontRefを得ました。やっとのことでCGContextSetFont()にATSFontRefを渡してCGFontRefを得ることができたわけです。しかし、この方法で手続きとしては正しいような気がしますが…日本語を描画させても文字化けしてしまいます(涙)。

CGContextSelectFont()に渡すエンコード指定のkCGEncodingMacRomanが間違っているのかと思い、こちらをkCGEncodingFontSpecificに変更してみても正しい描画は行われません。こうなると、さすがにギブアップです(笑)。どのたか、CoreGraphics APIで日本語フォントを指定し正しく日本語を描画する方法をご存じの方はいらしゃいませか?

まあどちらにしろ、矩形領域指定によるテキストのジャスティフィケーションなど、最低でもTETextBox()レベルのテキスト処理が可能でないと実際の作業では使いものになりません。また、CFStringRefで指定されたテキストやユニコードテキストを描画する時にもこのままでは扱いが大変そうです。そこで、CoreGraphics APIを利用することは止めにして、もう少し高級な(レベルが高い)テキスト描画用APIを探すことにしました。

次回は、CoreGraphics APIに頼らないテキスト描画を試します。何かと処理が大げさで複雑になりがちな、MLTE(Multilingual Text Engine)APIやATS(Apple Type Services)APIは避けたいところですので、それらには頼らないテキスト描画ルーチンを紹介したいと思います。
                                
つづく

SqueakではじめるSmalltalk入門   第78回  鷲見 正人

本連載では、名前は知っていてもなかなか触れる機会のないSmalltalkについて、最近話題のSqueakシステムを使って紹介しています。今回は、作成した簡易GUIビルダに出力させたスクリプトを、実際にGUIとして動作させてみます。

▼出力されたスクリプトをそのまま評価してみる
前回は、配置したウィジェット情報を出力する側、つまり、メソッド「GuiBuilder >> #generateScriptOf:」の手続きの内容を見て、おおまかには次の流れであることを確認しました。

1. ‘widget types’に分類してあるメソッドのソースをカタログ化。
2. 各ウィジェットからレイアウト情報を引き出す。
3. ソースとレイアウト情報を組み合わせて加工し、スクリプトを構成。
4. スクリプトをmywindow.stファイルに出力後、あらためてそれを表示。

たとえば、次図に示すような上半分に二つのリスト枠、下半分に一つのテキスト枠を設置したレイアウトの場合、

[fig.A]ウィジェットのレイアウト例

GUIビルダのウインドウメニューから「show script」を選ぶと、前述の手順に従ってスクリプトが生成され、画面に現われます。

| model window |
model := Model new.
window := (SystemWindow labelled: 'My Window') model: model.
window addMorph: (PluggableListMorph
      on: self
      list: nil
      selected: nil
      changeSelected: nil
      menu: nil) frame: (0.024@0.014 corner: 0.478@0.429).
window addMorph: (PluggableListMorph
      on: self
      list: nil
      selected: nil
      changeSelected: nil
      menu: nil) frame: (0.483@0.014 corner: 0.979@0.426).
window addMorph: (PluggableTextMorph
      on: self
      text: nil
      accept: nil
      readSelection: nil
      menu: nil) frame: (0.024@0.444 corner: 0.982@0.97).
^ window openInWorld


たしかに、二つのリスト枠(a PluggableListMorph)、ひとつのテキスト枠(a PluggableTextMorph)をウインドウ(a SystemWindow)に配置(#addMorph:frame:)した内容になっていますね。このスクリプトにより、アプリケーションソフトとしての機能こそ持ちませんが、GUIとしては立派に機能するウインドウを生じさせることが可能です。全選択してdo it(cmd +D)してみてください。

[fig.B]スクリプトの実行結果として現われるウインドウ

GUIというのは、アプリケーションソフトの実体(モデル)にかぶせる“皮”のようなものです。モデルを適切なものに差し替え、各ウィジェットをそのモデルにしかるべく“接続”することができれば、このスクリプトが記述するウィジェットたちを、特定のモデルの“手足”のように機能させることができるはずです。実際に試してみましょう。

▼プロセスブラウザと接続して動作させてみる
Smalltalkは、言語処理系というよりはOSに近い性質を持つソフトウエアで、事実、かつてはALTOのOSのひとつ(ちなみに、SmalltalkをOSとするときALTOは「暫定ダイナブック」と呼ばれて、これがMacを含めた現在主流のGUIの始祖…)として開発された経緯を持ちます。内部ではプロセスのようなものの管理も行なわれており、そのためのユーティリティソフト「プロセスブラウザ」も存在します。プロセスブラウザは、次の式をdo it(cmd + D)することで起動できます。

ProcessBrowser open

OS Xでいうところの「アクティビティモニタ」のようなソフトですね。

[fig.C]プロセスブラウザ

プロセスブラウザのGUIの生成は、メソッド「ProcessBrowser >>#openAsMorph」でその内容を読むことができます(上の式の「ProcessBrowser」をドラッグして選択し、browse it(cmd + B)でブラウザを開いた後、メソッドリスト枠から「openAsMorph」を探してクリックします)。実は先ほどの「リスト枠二つ、テキスト枠一つ」というウィジェットの構成は、このプロセスブラウザのGUIを意識したものです。したがって、この#openAsMorphの内容は、GUIビルダが出力した上のスクリプトと、その内容が非常に似通っていることがお分かりいただけると思います。

では、この#openAsMorphに倣って、先ほどのGUIビルダの出力スクリプトを書き換えてみましょう。

まず、モデル(model)はa Modelの代わりにa ProcessBrowserに差し替えます。一つめのリスト枠の第一引数(on:キーワード欄)はもちろんmodel、第二引数(list:欄)はプロセス一覧を得るための#processNameList、第三引数(selected:欄)には選択項目インデックスを得るための#processListIndex、第四引数(changeSelected:欄)には選択項目の変更をモデルに伝えるための#processListIndex:、第五引数(menu:欄)には黄ボタンメニューを得るための#processListMenu:を、それぞれすでに記入済みのnilと置き換えます。

二つめのリスト枠についても同様に#openAsMorphに従い、第一から第五引数について、それぞれ順に、model、#stackNameList、#stackListIndex、#stackListIndex:、#stackListMenu:に置き換えます(セレクタのコロンの有無に注意してください)。

テキスト枠については、第一、第二引数のみを、それぞれmodelと
#selectedMethodに置き換え、それ以外はnilのままで結構です。

| model window |
model := ProcessBrowser new.
window := (SystemWindow labelled: 'My ProcessBrower') model: model.
window addMorph: (PluggableListMorph
      on: model
      list: #processNameList
      selected: #processListIndex
      changeSelected: #processListIndex:
      menu: #processListMenu:) frame: (0.024@0.014 corner: 0.478@0.429).
window addMorph: (PluggableListMorph
      on: model
      list: #stackNameList
      selected: #stackListIndex
      changeSelected: #stackListIndex:
      menu: #stackListMenu:) frame: (0.483@0.014 corner: 0.979@0.426).
window addMorph: (PluggableTextMorph
      on: model
      text: #selectedMethod
      accept: nil
      readSelection: nil
      menu: nil) frame: (0.024@0.444 corner: 0.982@0.97).
^ window openInWorld

改めてこのスクリプトを全選択しdo it(cmd + D)すると、今度は“中味”のあるウインドウが現われ、そのままプロセスブラウザとして機能します。出力の順序の関係で、元のプロセスブラウザとは、上段の二つのリスト枠の左右が入れ替わったりしますが、ここではあまり気にする必要はないでしょう(#addMorph:frame:の第二引数の矩形情報を見ることで両者を見分けることは可能です)。

[fig.D]GUIビルダが生成したGUIで動作するプロセスブラウザ

ここでは、ウィジェット構成がシンプルなプロセスブラウザを選びましたが、比較的複雑にみえるシステムブラウザでも、GUIビルダ出力スクリプトを介して、元のGUIとほぼ同様に機能するGUIを作り出すことができます。ぜひ、チャレンジしてみてください。

バックナンバー:
http://squab.no-ip.com:8080/mosaren/

ニュース・解説

 今週の解説担当:木下 誠

———————————————————————-
オープンダイアログで、パッケージの内部を表示
———————————————————————-

オープンダイアログを表示するためのNSOpenPanelで、パッケージの中身も表
示させる方法を解説したQA、「NSOpenPanel – Choosing any file and
ignoring packages」が公開されています。

標準のオープンパネルでは、.appや.pluginなどのパッケージは、ファイルと
して見えます。それを、本来のフォルダとして表示し、内部のファイルにアク
セスしたいときに使います。

QA1468: NSOpenPanel – Choosing any file and ignoring packages
http://developer.apple.com/qa/qa2007/qa1468.html

 

◇MOSAからのお知らせと編集後記は割愛します◇

 

MOSA Developer News   略称[MOSADeN=モサ伝]
        配信停止 mailto:mosaden-ml@mosa.gr.jp
 記事内容に関するご意見 mailto:mosaden-toukou@mosa.gr.jp
      記事投稿受付 http://www.mosa.gr.jp/?page_id=850
Apple、Mac OSは米国アップル社の登録商標です。またそのほかの各製品名等はそれぞれ各社の商標ならびに登録商標です。このメールの再配信、および掲載された記事の無断転載を禁じます。
特定非営利活動法人MOSA  http://www.mosa.gr.jp/
Copyright (C)2007 MOSA. All rights reserved.