« February 2007 | Main | December 2007 »

2007.11.30

WPF の縦書き、さらに続く

image縦書き用の GSUB vert/vrt2 テーブルは、なんとか取れました。メイリオでは 99 のグリフが置換されるようになっているようです。ちなみに MS Gothic では 101。この差は何でしょうね。

ちなみに TrueType/OpenType のフォントテーブルはフォントのメーカーやフォントそのものによってかなりつくりに差があり、またデータのおかしいフォントも数多くあります。昔の Windows では、壊れたフォントを入れて表示すると Blue Screen、なんてこともよくありました。ので、直接テーブルを読みたくはない。

この実験コードでは、一応公開 API だけでなんとかここまで来れています。Interop は使っていますが。

image しかしフォントによってはこんなことに。句点「。」の位置もおかしいですが、他の文字も微妙に上下左右におかしくずれています。

グリフ置換はきちんと入って処理しているので、他の縦書きメトリックス系のテーブルをきちんと読まないと正しくレンダリングできないフォントは、もっときちんとやらなければいけないようです。

| | Comments (151) | TrackBack (2)

2007.11.28

WPF の縦書き実証実験

句読点がこんな形の縦書き画面ショット だけ掲載しても後味が悪いので、さらに実証実験を続けます。

WPF の縦書き実証実験まず Word でメイリオを指定して、縦書きにして XPS で保存します。その中を覗くと、メイリオの句点「。」の縦書き用グリフインデックスが 9236 であることが分かります。

あとは、TextBox の Visual Tree を解析して GlyphRun を作る時に、「。」の場所だけ GlyphIndices を置き換えてやります。結果がこちら⇒

さて。できることは分かりました。句点の位置が少しずれただけだけど、先の画面での不思議な落ち着かなさがなくなりました。

あとは、フォントから GSUB を読み取って、vertvrt2 のテーブルに従って GlyphIndices を置き換えてやれば、すごく基本的な縦書きの表示まではできそうです。

問題は、これらのテーブルを読み取るための API が WPF にはないので、自作するか、Uniscribe を触ってみるか、というあたりで迷い中。

気がつけば、Microsoft Typography Specifications にはこれだけの言語のフォントの作り方がある のに、その中に日本語の縦書きについては記述がないですね。WPF 1.0 で縦書きを忘れられたのはこの辺から来ているのでは、という気もします。

| | Comments (201) | TrackBack (2)

WPF TextBox の Visual Tree

WPF の縦書きの続き にさらに続く。XamlPad で覗いてみる。

  • TextBox
    • TextBoxView
      • DrawingVisual
        • [0]=DrawingGroup
          • [0~n]=GlyphRunDrawing
            • GlyphRun

TextBoxView が TextFormatter.FormatLine を呼んで、帰ってきた結果の TextLine が GlyphRun を生成しているらしい。

LineServices は MurrayS が言っているように OS などに依存しない構造 なので、LineServices の callback を実装している TextLine あたりが Uniscribe で言うところの "Shaping" をしているのだろう。

WPF でまともに縦書きを実装するのがとても大変、というのはよくわかった。Wrapper をかませて、ちょいちょい、と遊ぶレベルでは実現できそうにない。

WPF の縦書き幸い、日本語の縦書き Shaping は、ほかの言語と違ってレイアウトに変更が出ない。固定幅フォントを使っている限り、縦書き用のグリフに置換しても文字の送りが変わらないからだ。

Visual Tree を VisualTreeHelper で覗いて、同じ構造を作りつつ、グリフ置換をすれば、なんとか縦に表示することはできそう。

とはいえ、グリフ置換をするためのテーブルを取得する API は WPF にはない。作るか、Uniscribe を使うか、というあたりで、これもなかなか難儀。まだ迷いは続く。

BiDi の Shaping をしっかりやったものを WPF 1.0 (.NET 3.0) にきちんと入れてきたんだから、日本の縦書きの Shaping なんて大したことないと思うですけどね。

| | Comments (281) | TrackBack (1)

2007.11.27

WPF Text API

Quick Tour of WPF Text Architecture がきれいに書いてある。英語だけど。画像拝借。

| | Comments (3) | TrackBack (0)

WPFの縦書き続き

WPFの縦書きの続き。

Word の XPS 出力はきちんと縦書きになっていた。XPS には縦書き、というか、縦書き用にグリフを反時計回りに90度回転する、という IsSideways がある。これで文字を回転しておいて、行を逆に時計回りに90度回転すれば、縦書きになるでしょ、という仕様。

しかし日本語には、「、」や「ー」などのように縦書きになると位置や形が変わる文字がある。XPS の IsSideways はそれは解釈してくれない模様。アプリがやれ、という話らしい。FontVariants に Ruby があったり、EastAsianLanguage に異体字があったりするので、どちらかに入りそうなものだが、これがない。ルビ専用グリフをやる前に縦書き用グリフじゃないの、と思うが、ないものはない。

だから、XPS の仕様書で句読点の位置がおかしいのにはそれなりに理にかなっていて、XPS 1.0 ではそこまで自動では面倒見ませんよ、という話らしい。Glyphs には Unicode 文字列を指定するモードとグリフインデックスを指定するモードがあるので、Unicode 文字列じゃなくて縦書き用のグリフを指定してくれれば表示できます、というお話。Unicode 文字列で動いているアプリを縦書き対応するには、グリフインデックスを取れ、というお話。Word は元々自前でフォントを読み込んでグリフインデックスで指定しているから、縦書きできる。横書きは Unicode 文字列でも動くようになっているのになぁ。

で、フォント周りのクラスを覗くと、通常の文字コードからグリフインデックスへの変換はサポートされているのだが、縦書き用グリフインデックスが取れそうにない。ぎょぎょ。フォントファイルを直接読め、という話か。フォント周りのクラスは、FontFamily と Typeface が主だったクラスのようだが、他に FamilyTypeface, GlyphTypeface というのがある。この辺の関連はいまいち不明。でもどこにも見当たらない。

フォントまわりを一旦あきらめて少し上のレベルを探ると、WPF の組版関連は結構なボリュームがあり、またレイヤーに分かれている。レイヤー毎に同じようなクラス名があるのでややこしい。

  • TextBox は TextFormatter を利用して組版を行う。
  • RichTextBox は FlowDocument を利用して組版を行う。FlowDocument はその下で TextFormatter を利用している模様。

最終的にどちらも TextFormatter に落ち着くらしい。これが TextRun とか TextSpan とかの組み合わせで組版結果を表現するようだ。ここから TextLine.Draw で DrawingContext へ。だから縦書きの出力をしたいなら、まず TextFormatter に手を入れることになりそうだが、この辺は abstract と internal 実装でしっかりガード。でも中で TextBox と RichTextBox は実装が分かれていて、RichTextBox は LineServices/PTS を使っているらしい。だったらその中は縦書きをサポートしていそうなものだが、上と下に繋がっていない、ということらしい。

さて。とても困った、ということが分かった。縦書きだけやりたいなら WPF を諦めて GDI に戻る。でもやりたいのは OpenType を使った縦書き。GDI/GDI+ ベースの Windows Forms では OpenType を上手に扱えない。GDI/GDI+ ではプロの印刷品質も出せない。

Mac + PostScript/PDF を使えよ、というお話?

| | Comments (36) | TrackBack (2)

WPFの縦書き

まさかないとは思いませんでした。どうした、がんばれ、日本のMS。

XPS にもないとなると大変だなぁ、と思ったけど、XPS にはある模様。でもこのサンプル画像はひどいね。できてないじゃんと思わせる。

Word で縦書して XPS で保存したらできた。ので、とりあえず XPS はだいじょうぶなのか。

GlyphRun.IsSideways プロパティは WPF で定義されているので、ここまで自分で落としてやれば描画できるらしい。ほんとかな。Word の出力した XPS を解析してみるか。

| | Comments (30) | TrackBack (2)

« February 2007 | Main | December 2007 »