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 を使えよ、というお話?
Recent Comments