XPS中のXAMLの文字コード
Glyphs を TextBlock に置き換えると、Visual Studio や Blend で編集可能になります。
これを試したときに気が付いたのですが、数式中の英字がXAMLエディタのソース表示では □ に表示されています。実行したときには正常に表示されます。
ワードが作るXPSファイルの話です。
1.予備知識
- XPS 中のページを記述したXAMLファイルは、BOM 付きの UTF-16LE でした。
- XAMLの FixedPage タグには、xml:lang="ja-JP" と書かれています。
2.Glyphs の文字の表現
FontUriプロパティは必須で、使われている文字からなるフォントファイルが作られ、これが指定されています。
文字そのものは、UnicodeString プロパティかindices プロパティに設定されています。日本語の文字列は、両方が指定されているようです。
見た限り、UnicodeString がないことはありますが、indices は必ずあるようです。(indicesが使われないときは、indices=""となっている。)
下記は、二次方程式の根の公式の最初の部分です。
- <Glyphs Name="a0" BidiLevel="0" Fill="#FF000000"
- FontUri="61AB6E7E-4B67-0B55-593F-5546F50C4A18.ttf"
- FontRenderingEmSize="10.56" StyleSimulations="None" OriginX="0"
- OriginY="24.36" UnicodeString="𝑥" Indices="(2:1)1876" xml:lang="en-US">
- </Glyphs>
- <Glyphs Name="a1" BidiLevel="0" Fill="#FF000000"
- FontUri="5EE342DC-734D-0982-B465-1769B379800F.ttf"
- FontRenderingEmSize="10.56" StyleSimulations="None" OriginX="8.88"
- OriginY="24.36" UnicodeString="=" Indices="" xml:lang="en-US">
- </Glyphs>
- <Glyphs Name="a2" BidiLevel="0" Fill="#FF000000"
- FontUri="5EE342DC-734D-0982-B465-1769B379800F.ttf"
- FontRenderingEmSize="10.56" StyleSimulations="None" OriginX="19.56"
- OriginY="16.32" UnicodeString="−" Indices="" xml:lang="en-US">
- </Glyphs>
- <Glyphs Name="a3" BidiLevel="0" Fill="#FF000000"
- FontUri="61AB6E7E-4B67-0B55-593F-5546F50C4A18.ttf"
- FontRenderingEmSize="10.56" StyleSimulations="None" OriginX="27.48"
- OriginY="16.32" UnicodeString="𝑏" Indices="(2:1)1854" xml:lang="en-US">
- </Glyphs>
- <Glyphs Name="a4" BidiLevel="0" Fill="#FF000000"
- FontUri="5EE342DC-734D-0982-B465-1769B379800F.ttf"
- FontRenderingEmSize="10.56" StyleSimulations="None" OriginX="35.64"
- OriginY="16.32" UnicodeString="±" Indices="" xml:lang="en-US">
- </Glyphs>
3.UnicodeString、indices
UnicodeString には、2通りの記述があります。
- 文字列そのもの
- 𝑥 のような表記
この表記は、Visual Studio で表示するとエラーになります。属性の区切りを超えてエラーのマークが付くので構文解釈を狂わせるようです。
二次方程式の根の公式の最初の文字は、x なのですが、UnicodeString="𝑥" Indices="(2:1)1876" を調べて見ました。
左図は、Indices="(2:1)1876" が、x を表していることを示しています。
61AB6E7E-4B67-0B55-593F-5546F50C4A18.ttf は、ttfdump ツールで CAMBRIA フォントだとわかっているので、左図のように指定しました。
UnicodeString="𝑥" は、構文的にエラーとみなされるので削除してあります。
UnicodeString="aa" などと書いて見ましたが、デザイン表示に変化はないようです。
したがって、UnicodeString="𝑥" が何を示すのかはわかりません。1876 を、1854 に変えれば、表示が b に変わり、フォントのインデクスだとわかります。
(インデクスからUnicodeに変えられれば、Gryphs を TextBlock に変えて、フォントファイル不要にしたいところです。後で試します。)
UnicodeString が記述されずに、indices="958" と記されたところもあります。同じ方法で確かめると、√でした。
4.Glyphs を TextBlock に置き換えたときの □ 表示
これは、XmlReader で、UnicodeString="𝑥" を読み込むと、□ 表示になる文字列が返されると言うことでした。Visual Studio のエディタでは、エラーになる箇所ですが、XmlReader は、エラーにはなりません。
この箇所をダンプして見ると、F0 9D 91 A5 でした。
119909 は、16進で表すと、1D465 です。これを UTF-16で表すには、サロゲートペア符号化が必要です。
D465 = 1101 0100 0110 0101
0000 1101 01 / 00 0110 0101 (20ビットに拡張して2分する)
110110 0000 1101 01 / 110111 00 0110 0101 (それぞれに決まった6ビットを付ける)
1101 1000 0011 0101 / 1101 1100 0110 0101 = D8 35 DC 65
UTF-8 で符号化して見ます。16進で 1nnnn 区画は、元のビット列が
1 yyyy yyyy xxxx xxxx
なら、
1111 0000 1001 yyyy 10yy yyxx 10xx xxxx
となります。
F0 9D 91 A5
どうやら、UTF-8 で書きだしたソースコードのダンプでは、当然 UTF-8 に変換されているだけのことで、メモリ上では U+1D465 を正しく扱っているようです。
念のため、unsafe コードを書いて確認しました。メモリ上は、35 d8 65 dc でした。
- string型は、UTF-16 の 0x10000 以上のコードも正しく扱える。
- Visual Studio のエディタは、通常 UTF-8形式でソースコード扱うので、変換されている。
- Visual Studio のエディタは、これを表示しない。□ として表示される。
- プログラムの実行環境では正しく表示できる。
- おそらくブラウザも正しく表示する。
- Char や string には、UTF-32 との変換が用意されている。
- ファイルなど、byte[] からは、Encoding.UTF-32.GetString()が使える。
これは、UTF-32LE表現を入力とする。
- メモリ上では、BEでもLEでもない形式のようだ。ワード順は正順で、ワード内のバイト順は逆転している。
|