[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[debian-users:58105] Re: [debian-users:58104] Re: バックスラッシュと円の問題



松井さま

綾小路です。

At Thu, 18 Aug 2016 18:28:18 +0900,
Kenji Matsui <kmatsui@xxxxxxxxxxxxxxxxxx> wrote:
>
> まずフォントの状況ですが、
> バックスラッシュが出力されるdebianでは
> $ fc-match monospace
> DroidSansFallbackFull.ttf: "Droid Sans Fallback" "Regular"
> $ fc-match :lang=ja
> DroidSansFallbackFull.ttf: "Droid Sans Fallback" "Regular"
> 円が出力されるdebianでは
> $ fc-match monospace
> ipag.ttf: "IPAゴシック" "Regular"
> $ fc-match :lang=ja
> ipag.ttf: "IPAゴシック" "Regular"
> となっておりました。
> $ gsettings set org.gnome.desktop.interface font-name 'Droid Sans Fallback'
> $ fc-cache
> の後に再ログインして円が出力される方をバックスラッシュが出力される方に合わせようとおもったのですけど、うまくいきませんでした。
> フォントの変更方法はよく分かりません。

ipag.ttf に含まれる U+005c と U+00a5 に対応するグリフは異なる [1] ので、
バイト列を utf8 エンコーディングとして解釈して ipag.ttf を使って表示すれば、
バックスラッシュと円記号は違った文字として表示されるはずです。

今問題になっているアプリケーション (ターミナル、gedit、pluma)
のフォント設定が ipag.ttf を参照するようになっているか否かを
再確認してみるのはいかがでしょうか。

また、0x5c、0xa5、0xc2a5 というバイト列を含むファイルを作って [2]、
それらが期待通り表示されるか確認してみるのも良いかもしれません。
アプリケーションが適切にエンコーディングを判別して、ipag.ttf を使って表示したなら、
それぞれバックスラッシュ、円記号、円記号のように表示されるはずです。

[1]
$ ttx -d . /usr/share/fonts/opentype/ipafont-gothic/ipag.ttf
$ grep '<map code="0x\(5c\|a5\)"' ipag.ttx
      <map code="0x5c" name="aj291"/><!-- REVERSE SOLIDUS -->
      <map code="0xa5" name="aj711"/><!-- YEN SIGN -->
      <map code="0x5c" name="aj291"/><!-- REVERSE SOLIDUS -->
      <map code="0xa5" name="aj711"/><!-- YEN SIGN -->
      <map code="0x5c" name="aj291"/><!-- REVERSE SOLIDUS -->
      <map code="0xa5" name="aj711"/><!-- YEN SIGN -->
$ grep '"\(aj291\|aj711\)"' ipag.ttx
    <GlyphID id="258" name="aj291"/>
    <GlyphID id="466" name="aj711"/>
    <mtx name="aj291" width="1024" lsb="51"/>
    <mtx name="aj711" width="2048" lsb="404"/>
      <map code="0x5c" name="aj291"/><!-- REVERSE SOLIDUS -->
      <map code="0xa5" name="aj711"/><!-- YEN SIGN -->
      <map code="0xffe5" name="aj711"/><!-- FULLWIDTH YEN SIGN -->
      <map code="0x5c" name="aj291"/><!-- REVERSE SOLIDUS -->
      <map code="0xa5" name="aj711"/><!-- YEN SIGN -->
      <map code="0xffe5" name="aj711"/><!-- FULLWIDTH YEN SIGN -->
      <map code="0x5c" name="aj291"/><!-- REVERSE SOLIDUS -->
      <map code="0xa5" name="aj711"/><!-- YEN SIGN -->
      <map code="0xffe5" name="aj711"/><!-- FULLWIDTH YEN SIGN -->
    <TTGlyph name="aj291" xMin="51" yMin="104" xMax="972" yMax="1538">
    <TTGlyph name="aj711" xMin="404" yMin="104" xMax="1645" yMax="1538">
      <psName name="aj291"/>
      <psName name="aj711"/>
      <ClassDef glyph="aj291" class="1"/>
      <ClassDef glyph="aj711" class="1"/>
    <mtx name="aj291" height="2048" tsb="264"/>
    <mtx name="aj711" height="2048" tsb="264"/>

[2]
$ printf '0000000: 5c' | xxd -g 1 -revert - backslash_ascii_5c.txt
$ printf '0000000: a5' | xxd -g 1 -revert - yen_latin1_a5.txt
$ printf '0000000: c2 a5' | xxd -g 1 -revert - yen_utf8_c2a5.txt

> バイナリーデータとして ¥ を \ に置き換えれば一番いいのかなと思いまして、
> $ cat tf9.txt
> \,¥, a
> 普通のテキストを16進数テキストに変換
> $ hexdump tf9.txt
> 0000000 2c5c a5c2 202c 0a61
> 0000008
> (エディタにコピペすると、0000000 と 0000008 のサイズが違ってきます)
> $ hexdump tf9.txt > tf9.hex
> 16進数テキストをバイナリファイルに変換
> $ xxd -r -p tf9.hex tf9.bin
> 円のa5(8進数で245)をバックスラッシュの5c(8進数で134)に置き換える
> $ tr '¥245' '¥134' < tf9.bin > tf9_after.bin
> c2(8進数で302)を削除する
> $ tr -d '¥302' < tf9_after.bin > tf9_after_2.bin
> 最後のバイナリファイルを16進数テキストに変換
> $ xxd -p tf9_after_2.bin tf9_after_2.hex
> と、ここまでやっても
> $ cat tf9_after_2.hex
> 00000002c5ca5c2202c0a610000008
> というように全く変更されていません。
>
> ちなみに、hexdump で -C オプションをつけると並び方が変わってきます。
> $ hexdump -C tf9.txt
> 00000000  5c 2c c2 a5 2c 20 61 0a                           |¥,.., a.|
> 00000008
> $ hexdump -C tf9.txt > tf9_2.hex
> $ xxd -r -p tf9_2.hex tf9_2.bin
> $ diff -s tf9.bin tf9_2.bin
> バイナリーファイル tf9.bin とtf9_2.bin は異なります
>
> マニュアルを見てもよく分からなかったのですけど
> -C オプションを付けた場合が特殊であれば
> -C オプションをつけないやり方で押し通せばよいのかもしれません。

0xa5 を 0x5c に変換する方針はしばしば問題を引き起こします。
なぜなら、円記号に対応するバイト列表現はエンコーディングに依存する [3] からです。
また、この方針はバイト単位で変換を行うので、文字という意味単位は失われ、
意図しない変換が行われる場合があります [4]。
入力エンコーディングが utf8 ならば、文字単位の変換は簡単です [5]。
しかしながら、「古いファイル」が Shift_JIS エンコーディングの場合、
[5] で挙げた concept code は使えません。

[3]
                 | ascii | latin1 | utf8
=================+=======+========+=============バックスラッシュ | 0x5c  | 0x5c   | 0x5c
円記号           |       | 0xa5   | 0x2ca5
-----------------+-------+--------+--------------

[4]
$ printf '\¥づ' | xxd -g 1
0000000: 5c c2 a5 e3 81 a5                                \.....
$ printf '\¥づ' | tr '\245' '\134' | xxd -g 1
0000000: 5c c2 5c e3 81 5c                                \.\..\

[5]
$ printf '\¥づ' | perl -C -0777 -ne 'while (m/(.)/g) { if($1 eq "\N{U+00a5}") { print "\N{U+005c}"; } else { print $1; } }' | xxd -g 1
0000000: 5c 5c e3 81 a5                                   \\...

綾小路龍之介
--
AYANOKOUZI, Ryuunosuke <i38w7i3@xxxxxxxxxxx>

Attachment: pgpTpNQoLQB5p.pgp
Description: OpenPGP Digital Signature