2010年7月7日水曜日

Core Graphics (Quartz) のみで日本語文字列を描画するライブラリのヘッダファイルを書いてみた

とある理由で UIKit の描画機能が使えず、 Core Graphics のみで文字列の描画処理を行わなければならないことになってしまったので、適当に調べてみました。


■ことのはじめ

Core Graphics の機能だけで日本語の文字列を描画する方法については、既に先人の方々が調べて記事にまとめてくださっていたので、そちらを見ていただければ大丈夫です。
http://iphone-dev.g.hatena.ne.jp/ktakayama/20100129
http://d.hatena.ne.jp/r_kurain/20100316
基本的にはこちらで紹介されている方法に従って進めていけば困ることはありません。ただし、描画した文字が上下反対になることがありますので、 CGContextSetTextMatrix を使う箇所を調整したりする必要があるかも。

で、最大の問題になるのがこれらの記事で紹介されている CGFontGetGlyphsForUnichars と呼ばれる関数です。この関数を使えば楽に日本語文字列を文字化けすることなく描画することができるのですが、あろうことかこの関数はプライベートAPIであり、使うとリジェクトされてしまうらしいです。ということで別の作戦をとらなければなりません。

上記の記事にいろいろな対処方法が載っているのですが、私は一番単純に
http://www.mexircus.com/codes/GlyphDrawing.mm
というライブラリを自分のアプリに組み込む方法を試してみることにしました。この方法を使えば、 CGFontGetGlyphsForUnichars でまず作って動くようにしてから、 CMFontGetGlyphsForUnichars と書き換えるだけでそのまま動作するので楽です。

問題はこのライブラリ、mmファイルしか用意されていないのでそのままではうまく使えません。適当にヘッダファイルを用意してやる必要があります。


■と言うわけで書いたもの

と言うわけで GlyphDrawing.h を書いてみました。
http://gist.github.com/466297

ライセンスは元の GlyphDrawing.mm に準じますが、 GlyphDrawing.mm のライセンスが不明なので、不安ならばまず作者さん (http://mexircus.com/blog/) に一言聞いてみるのがいいと思います。


■使い方
  1. http://gist.github.com/466297http://www.mexircus.com/codes/GlyphDrawing.mm をダウンロードします。
  2. GlyphDrawing.mm のインポートを以下のように書き換えます:
    //#import <Foundation/Foundation.h>
    #import "GlyphDrawing.h"
  3. GlyphDrawing.hGlyphDrawing.mm をプロジェクトに追加してビルドします。
  4. CGFontGetGlyphsForUnichars の代わりに CMFontGetGlyphsForUnichars を呼びだせばOKです。


■実際に使ったコードの例
NSString *message = @"本日は快晴なり";

// フォントを設定
// ついでにmessageのサイズも取得
// ただしsizeWithFontは UIGraphics の機能なので、本当に Core Graphics だけで描画したいならここで使ってはいけません
UIFont *font = [UIFont fontWithName:@"HiraKakuProN-W6" size:32.0];
CGRect messageRect = [message sizeWithFont:font];
CGFontRef fontRef = CGFontCreateWithFontName((CFStringRef)font.fontName);
CGContextSetFont(c, fontRef);
CGContextSetFontSize(c, font.pointSize);

// Glyphを作成
size_t length = [message length];
CGGlyph glyphs[length];
UniChar chars[length];
[message getCharacters:chars range:NSMakeRange(0, length)];
CMFontGetGlyphsForUnichars(fontRef, chars, glyphs, length);

// 文字列が上下反対になるのを防止する
CGAffineTransform transform = CGAffineTransformMakeScale(1.0, -1.0);
CGContextSetTextMatrix(c, transform);
CGContextTranslateCTM(c, 0, messageRect.size.height/2);

// 描画
CGFloat x = 100.0f;
CGFloat y = 100.0f;
CGContextShowGlyphsAtPoint(c, x, y, glyphs, length);

2010年6月26日土曜日

別スレッドで NSURLConnection を使うときのメモ

http://twitter.com/griffin_stewie/status/17022582070

@griffin_stewieさんにご指摘いただいたので調べてみました。

別スレッドでNSURLConnectionを使おうとすると、そのままではNSRunLoopのモードの問題なのか、上手い具合にデータを受信することが出来ません。私はメインスレッドでNSURLConnectionを動かすようにして難を逃れたのですが、それ以外にも教えていただいた方法を用いて、以下のように別スレッドのNSRunLoopのモードを変更して対応すると良いみたいです。
    NSURLRequest *theRequest = [NSURLRequest requestWithURL:iTunesURL];
// create the connection with the request and start loading the data
rssConnection = [[NSURLConnection alloc] initWithRequest:theRequest delegate:self];
// This creates a context for "push" parsing in which chunks of data that are not "well balanced" can be passed
// to the context for streaming parsing. The handler structure defined above will be used for all the parsing.
// The second argument, self, will be passed as user data to each of the SAX handlers. The last three arguments
// are left blank to avoid creating a tree in memory.
context = xmlCreatePushParserCtxt(&simpleSAXHandlerStruct, self, NULL, 0, NULL);
if (rssConnection != nil) {
do {
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
} while (!done);
}
runMode:beforeDateを使うわけですね。なるほど。

2010年6月20日日曜日

iPad を紙の代わりにするのに最適なアプリとスタイラスを探してみた



iPad を購入された皆さんが苦労されているのが「iPad の使い方を探す」事だと思います。私の場合は iPad を購入したら紙のシステム手帳を鞄から取り除いてしまいたいと考えていました。そのためには、カレンダーや連絡先はともかく、手書き機能が必要です。そこで購入直後からいろいろなアプリとスタイラスを買って(場合によっては作って)試行錯誤し、ようやくある程度の結論が出せたのでご紹介してみようと思います。

2011/05/29追記 - 記事全体の構造を再編成して、より分かりやすく、現状に即した形に書き換えました。私がこの記事を書き始めたころと比べ、スタイラスの性能もアプリの性能も飛躍的に向上し、どれを選んでもほぼ間違いないレベルにまで進化いたしましたので、そろそろまとめにして最終更新にするつもりです。
2011/02/01追記 - パワーサポート スマートペンを追記。
2010/10/10追記 - oStylusのレビューへのリンクを張りました。


実際に手持ちのスタイラスで書き比べてみた記事がこちら: http://akisute.com/2011/05/iphone-ipad-2.html
Bamboo Stylusのレビューはこちら: http://akisute.com/2011/05/ipad-bamboo-stylus.html
oStylusのレビューはこちら: http://akisute.com/2010/10/ipad-ostylus.html


■まず最初に結論

機能性、入手容易性、使い勝手、値段などを考慮した結果、2011/05/29現在私がオススメするアプリとスタイラスは以下のものです。それでは個別に見ていきます。


■アプリ編

手書きアプリには大きく分けて以下の三種類があると思っています。
  1. ノート型手書きアプリ
    • 紙のノートの代わりに使うための手書きアプリです。実際のノートのように背景に罫線が入っていたりする場合もあります。
    • 機能が絞られており、特にペン先は一種類しかない場合が多いですが、その代わり実際にペンで書いているかのような美しい線が書けます。
    • 拡大縮小は限定的にしかできません。
    • 見た目に非常にこだわっているアプリが多いです。
  2. お絵かき型手書きアプリ
    • キャンバス全体のスクロールや拡大縮小ができる手書きアプリです。どちらかというと、紙のキャンバスやホワイトボードを置き換えるアプリです。
    • 図形や絵を書くのに適しています。
    • 絵を描くのに必要な機能が多いです。たとえば色が多いとか、フィルタがついているとか、レイヤが使えるとか、ブラシの種類が多いとか。
  3. その他、独創的なもの
    • 全く新しい使い方を提案するアプリです。
    • 7notesのように手書き自動認識をしたり、Instavizのようにグラフを自動で作ってくれたりするものがあります。
ここでは私自身が紙のノートとホワイトボードの代わりを欲しているということで、キーボードでタイプする機能を持っているアプリについては除外しており、純粋に手書き機能のみで、かつ私が実際に試してみたことのある 1. と 2. の一部についてのみご紹介いたします。あらかじめご了承ください。

neu.Notes - お絵かき型

  • 良い点は、なんといっても無料で、ホワイトボードの代わりをするのに必要な機能は全てある。書き味も悪くない。
  • 悪い点は、デザインがイマイチ、ノートのページが増えてくるとだんだん重くなってきて書き味が劣ってくる。
これだけ使えるアプリが無料というのが何か間違ってる気がしますが、それぐらい素晴らしいです。とりあえず入れておいて損はありません。

Adobe Ideas - お絵かき型

  • 良い点は、neu.Notesよりも綺麗な書き味と使っていてしっくりくる美しいインターフェース。レイヤーも使える。
  • 悪い点は、高い(特に日本のストアでは)、ノートの整理が全く出来ないため数が増えてくると真っ先に破綻する、外部連携が弱い。
高いのが問題ですが、使っていてneu.Notesとどちらがイライラしないかと問われると、やはりこのAdobe Ideasですね。

Penultimate - ノート型

  • 良い点は、シンプルで必要最小限の機能だけを含んでいるところ。優れた書き味、比較的安い値段。
  • 悪い点は、シンプルすぎて出来ることが少ない、(ズームが一切出来ないのが致命的)、ノートの整理がイマイチ、ここ最近のアップデートの内容がイマイチで良い方向にアプリが改善される気配がない、外部連携が弱い。
昔はノートと言えばPenultimateというぐらい良かったんですが、最近は後述するNoteshelfやNoteTaker HDが見事なぐらい成長してしまったため、もはや過去の遺物という印象です。安いぐらいしかメリットがないです。

Noteshelf - ノート型

  • 良い点は、美しいUI、必要な機能は全てある上でよけいな物がないシンプルさ、ズームが出来て紙のノートと同じように細かく書ける、Penultimateと同等レベルの優れた書き味、そして何より外部連携が神。Dropboxは当然として、Evernoteにも連携可能。書いたノートをPDF形式で選択したページだけEvernoteにアップロードなどと言うことが余裕で出来る。あとはEvernoteにOCRしてもらってあとから検索する・・・
  • 悪い点は、 正直見当たらない。 いや本当に。自分のやりたいことが今のところ全部出来ているし、非常に安定していて1ノートに画像込みで40ページ以上追加しても性能劣化やクラッシュが発生しない。紙のノートみたいに200ページぐらいのノートを作っても大丈夫そうな勢いがある。
あの孫正義が絶賛!とか紹介に書いてあって超うさんくせぇと思っていたのですが、すみません、私が間違っておりました。本当にこのアプリは素晴らしいです。紙のノートを一冊買うぐらいなら、今すぐこちらを買ってください。

ここでご紹介した以外にも、たとえば むげんメモ ですとか Note Taker HD といったアプリが面白いと思いますが、実際に使っていないので評価は控えさせていただきます><


■スタイラス編

2011/05/29編集 - 近況に合わせて完全に書き直し。

スタイラスについては、時代別に見ていきます。

原始時代(2008年~iPad発売前後)

この時代に存在したiPhone用スタイラスと言えば、ほぼ全てが先端が黒い平らなゴム状になっているスタイラスです。例を挙げればこのような商品です。
http://www.ray-out.co.jp/products/t1pen1/

残念ながら魚肉ソーセージの方がマシなので、何を間違っても絶対に買わないでください。これらの原始時代スタイラスは、導電性の低い素材で出来た平らな先端を、無理矢理押しつけてタップすることしか考えられていないため、手書きは不可能です。

さすがに最近は第二世代が登場してきたおかげで、ほぼ市場から駆逐されたようです。

第一世代(iPad発売~iPad発売後9ヶ月程度)

とまぁiPadが発売されるまではほとんど暗黒時代だったのですが、iPadが登場してきたあたりから私が第一世代と呼んでいるレベルのスタイラスが登場し始めました。すなわち、
  • 何でもいいからとにかく引きずって手書きできる先端
  • とりあえずまともに使えるレベルの導電性
を持っているスタイラスです。主に先端が導電性スポンジで出来ているスポンジ型と、筆のようになっているブラシ型が主流でした。中には変わり者で先端が金属で出来ている物もあります。これでとりあえず手書きは出来るようになりましたが、第一世代のスタイラスは値段が高く、世間一般にあまり流通していないためAmazonなどで気軽に買えず、その割には第二世代と比べて性能が悪すぎるので、今はもう忘れて結構だと思います。一応列挙すると、
  • Pogo Sketch - 第一世代の中で飛び抜けて優秀だったスタイラス。導電性以外は今でもほぼ完璧
  • oStylus - 金属を使うことで素晴らしい導電性を確保したスタイラス
などがあります。

第二世代(2011年~)

そして2011年になってついに転機が。パワーサポート スマートペン PBJ-9Xシリーズの登場を皮切りに、第二世代と呼ぶにふさわしいスタイラスが次々と登場し始めました。

第二世代の特徴は、
  • 日本のAmazonで3000円以内で余裕で買えるため入手しやすい
  • 触れるだけで反応する、極めて高い導電性と感度
  • 普通のペンと全く同じように引きずって手書きできるスムースなペン先
などを兼ね備えているところで、ようやく誰でもいいスタイラスを簡単に入手できるようになりました。この世代のスタイラスはほぼ全て中空ドーム状の柔らかいシリコンをペン先に採用しているため、一目でわかります。

以下、実際に買って試したことがあるものを挙げてみます。

パワーサポート スマートペン PBJ-9Xシリーズ
  • 良い点は、驚異的な先端感度と、安めの値段。本体が軽いのも魅力。
  • 悪い点は、先端の強度にやや不安があること、柔らかくて太いため正確に書けず、少し引っかかりがあること。
おそらく最初に出てきた第二世代のiPhone/iPad用スタイラスだと思います。今でもまったく見劣りしません。今では他にもっと安い商品もあるようですが、500円程度しか変わりませんし、あまり神経質にならなくても良いかと思います。

Wacom Bamboo Stylus
  • 良い点は、細くてスムーズなペン先、本物のペンのような筆感。
  • 悪い点は、やや重い本体と、多少感度の悪い先端。
詳細なレビューはhttp://akisute.com/2011/05/ipad-bamboo-stylus.htmlをご覧ください。高いだけあって良いです。

プリンストンテクノロジー iPad/iPhone/iPod touch専用タッチペン(ブラック) PIP-TP2B
  • 良い点は、十分な感度と、スマートペンより固くしっかりしていて書きやすいペン先。軽くて疲れない軸。値段も相当安い。ストラップを通すための穴がある。
  • 悪い点は、軸が短い。女性にはちょうどいいかもしれませんが、ただでさえ軸が短めな上にクリップも大きいので、手の大きい人には不向き。
ちょうどパワーサポートのスマートペンとBamboo Stylusの中間のようなペン先です。軽くて感度がよいあたりはBambooより優れており、ペン先が固くてふにゃふにゃしないのがスマートペンより優れていて、さらに安いのがメリット。一方でペン軸が短め(Bamboo Stylusと比べると1cmも短い)という別の問題もあり、他の製品と比べて一長一短ありますが、オススメです。

その他にも最近ではなどがあるようですが、これらの商品は実際に買って試せていないのでここでは評価を控えさせていただきます><