mikeo_410


XPS中のXAMLの文字コード

  Glyphs を TextBlock に置き換えると、Visual Studio や Blend で編集可能になります。
  これを試したときに気が付いたのですが、数式中の英字がXAMLエディタのソース表示では □ に表示されています。実行したときには正常に表示されます。
  ワードが作るXPSファイルの話です。

1.予備知識

  1. XPS 中のページを記述したXAMLファイルは、BOM 付きの UTF-16LE でした。
  2. XAMLの FixedPage タグには、xml:lang="ja-JP" と書かれています。

2.Glyphs の文字の表現

  FontUriプロパティは必須で、使われている文字からなるフォントファイルが作られ、これが指定されています。
  文字そのものは、UnicodeString プロパティかindices プロパティに設定されています。日本語の文字列は、両方が指定されているようです。
  見た限り、UnicodeString がないことはありますが、indices は必ずあるようです。(indicesが使われないときは、indices=""となっている。)
  下記は、二次方程式の根の公式の最初の部分です。

  1. <Glyphs Name="a0" BidiLevel="0" Fill="#FF000000"
  2. FontUri="61AB6E7E-4B67-0B55-593F-5546F50C4A18.ttf"
  3. FontRenderingEmSize="10.56" StyleSimulations="None" OriginX="0"
  4. OriginY="24.36" UnicodeString="&#119909;" Indices="(2:1)1876" xml:lang="en-US">
  5. </Glyphs>
  6. <Glyphs Name="a1" BidiLevel="0" Fill="#FF000000"
  7. FontUri="5EE342DC-734D-0982-B465-1769B379800F.ttf"
  8. FontRenderingEmSize="10.56" StyleSimulations="None" OriginX="8.88"
  9. OriginY="24.36" UnicodeString="=" Indices="" xml:lang="en-US">
  10. </Glyphs>
  11. <Glyphs Name="a2" BidiLevel="0" Fill="#FF000000"
  12. FontUri="5EE342DC-734D-0982-B465-1769B379800F.ttf"
  13. FontRenderingEmSize="10.56" StyleSimulations="None" OriginX="19.56"
  14. OriginY="16.32" UnicodeString="−" Indices="" xml:lang="en-US">
  15. </Glyphs>
  16. <Glyphs Name="a3" BidiLevel="0" Fill="#FF000000"
  17. FontUri="61AB6E7E-4B67-0B55-593F-5546F50C4A18.ttf"
  18. FontRenderingEmSize="10.56" StyleSimulations="None" OriginX="27.48"
  19. OriginY="16.32" UnicodeString="&#119887;" Indices="(2:1)1854" xml:lang="en-US">
  20. </Glyphs>
  21. <Glyphs Name="a4" BidiLevel="0" Fill="#FF000000"
  22. FontUri="5EE342DC-734D-0982-B465-1769B379800F.ttf"
  23. FontRenderingEmSize="10.56" StyleSimulations="None" OriginX="35.64"
  24. OriginY="16.32" UnicodeString="±" Indices="" xml:lang="en-US">
  25. </Glyphs>

3.UnicodeString、indices


  UnicodeString には、2通りの記述があります。

  1. 文字列そのもの
  2. &#119909 のような表記
    この表記は、Visual Studio で表示するとエラーになります。属性の区切りを超えてエラーのマークが付くので構文解釈を狂わせるようです。

  二次方程式の根の公式の最初の文字は、x なのですが、UnicodeString="&#119909;" Indices="(2:1)1876" を調べて見ました。

  左図は、Indices="(2:1)1876" が、x を表していることを示しています。
  61AB6E7E-4B67-0B55-593F-5546F50C4A18.ttf は、ttfdump ツールで CAMBRIA フォントだとわかっているので、左図のように指定しました。
  UnicodeString="&#119909;" は、構文的にエラーとみなされるので削除してあります。
  UnicodeString="aa" などと書いて見ましたが、デザイン表示に変化はないようです。

  したがって、UnicodeString="&#119909;" が何を示すのかはわかりません。1876 を、1854 に変えれば、表示が b に変わり、フォントのインデクスだとわかります。
  (インデクスからUnicodeに変えられれば、Gryphs を TextBlock に変えて、フォントファイル不要にしたいところです。後で試します。)

  UnicodeString が記述されずに、indices="958" と記されたところもあります。同じ方法で確かめると、√でした。

4.Glyphs を TextBlock に置き換えたときの □ 表示

  これは、XmlReader で、UnicodeString="&#119909;" を読み込むと、□ 表示になる文字列が返されると言うことでした。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 でした。

  1. string型は、UTF-16 の 0x10000 以上のコードも正しく扱える。
  2. Visual Studio のエディタは、通常 UTF-8形式でソースコード扱うので、変換されている。
  3. Visual Studio のエディタは、これを表示しない。□ として表示される。
  4. プログラムの実行環境では正しく表示できる。
  5. おそらくブラウザも正しく表示する。
  6. Char や string には、UTF-32 との変換が用意されている。
  7. ファイルなど、byte[] からは、Encoding.UTF-32.GetString()が使える。
    これは、UTF-32LE表現を入力とする。
  8. メモリ上では、BEでもLEでもない形式のようだ。ワード順は正順で、ワード内のバイト順は逆転している。


mikeo_410@hotmail.com