Unicodeの各文字の全角or半角の判断について


くろねこ  2004-03-11 04:17:46  No: 112302

こんにちは。くろねこです。

環境:Win2000  VB6.0 SP5

ハングル文字を含んだUnicode文字列の各文字の全角or半角の判断はどのようにしたらよいのでしょうか?

用途としては、「Microsoft Forms 2.0」の「TextBox」に文字列を表示した時に
ある位置まで表示したら改行するといった処理をやりたのです。

以上。よろしくお願いします。


魔界の仮面弁士  2004-03-11 06:32:47  No: 112303

> ハングル文字を含んだUnicode文字列の各文字の全角or半角の判断はどのようにしたらよいのでしょうか?

Unicodeには合成可能グリフなどもありますので…付きつめていくと、結構厄介ですよ。(^_^;)
http://www.uri.sakura.ne.jp/~cosmic/yuno/lab/unicode_glyph.html

とりあえず、東アジア圏における各文字の(Unicodeにおける)全角/半角の定義に関しては、ユニコード コンソーシアムの『EastAsianWidth.txt』という変換表を参照してください。
http://www.unicode.org/Public/UNIDATA/EastAsianWidth.txt

この表は、行ごとに
  1. コード値。これは、Hex(AscW(文字))』で得られる値です。
  2. 東アジアにおける「横幅」を表す値。Na(Narrow)、W(Wide)、H(Half Width)、F(Full Width)、N(Not Asian)、A(Ambiguous)の6種。
  3. Unicodeの文字名
が記載されていますので、これを使えば、全角/半角をプログラムで一応の判断ができると思います。とりあえず、Na/Hが半角、W/Fが全角という扱いですかね。

ただし、N(Not Asian) と、A(Ambiguous)に分類される文字に関しては、全角/半角という区分けが困難なので、これらをどう扱うかは別途考えてください。

---------
  [A]は、文脈によって全角とも半角ともとられる文字を示しています。例えば『α』は、JIS X 0208との互換性の関係で全角と扱われる事もありますが、本来は半角とされるべきなので、[A]に分類されます。そして[N]は、日中韓の文字集合に無い文字を示します。
---------

例えば、EastAsianWidth.txt では、
    30AB;W # KATAKANA LETTER KA           ……片仮名の「カ」。Wide属性。
    FF76;H # HALFWIDTH KATAKANA LETTER KA ……こちらは、Half Width属性。
などのように記述されています。前者は全角、後者は半角ですね。

また、“RIEL”という『己』に似た形のハングル字母を見てみると、初声部に使われる方の字母は、
    1105;W # HANGUL CHOSEONG RIEUL
のように、Wide属性になっています。全角ですね。

# でも、終声部で使われる 11AF は、Not Asian属性のようです。(何故だろう?)
#     11AF;N # HANGUL JONGSEONG RIEUL

> 用途としては、「Microsoft Forms 2.0」の「TextBox」に文字列を表示した時に
> ある位置まで表示したら改行するといった処理をやりたのです。
そういう用途であれば、全角/半角で判定するよりも、TextWidthメソッド等で判断した方が良いかも知れません。文字の幅は、フォントによっても変化しますから。


putno  2004-03-11 08:29:33  No: 112304

頭の byte が 0 かそうでないか,でいいんでないの.要するに「半角」「全角」の定義の問題だわな…
表示幅を考えたいなら上の「TextWidthメソッド等で判断」ってのが正解だと思う.私ならそうする.何文字とったら指定幅になるかって routine をつくればいいわけだ.


んっ  2004-03-11 09:35:50  No: 112305

> 頭の byte が 0 かそうでないか,でいいんでないの.要するに「半角」「全角」の定義の問題だわな…

Unicodeじゃだめじゃねーの。


nanashi  2004-03-11 19:32:06  No: 112306

> 用途としては、「Microsoft Forms 2.0」の「TextBox」に文字列を表示した時に
> ある位置まで表示したら改行するといった処理をやりたのです。

そもそも『Microsoft Forms 2.0』は再頒布権が無いから使用できないと思いますが。

http://www.gj.il24.net/~nakasima/vb/trap/#VBTRAP12


魔界の仮面弁士  2004-03-11 19:33:22  No: 112307

最初が0、というのは、Unicode 3.0の文字ブロックでいうと
  U+0000〜U+007F Basic Latin (基本ラテン文字)領域
  U+0080〜U+00FF Latin-1 Supplement (ラテン1補助)領域
の事でしょうか? >putnoさん

だとすると、んっさんが書かれたように、Unicodeには通用しないと思います。

その方法で変換してしまうと、例えば、
  U+FF00〜U+FFFF Halfwidth and Fullwidth Forms (半角・全角系)領域
にある文字の取り扱いなどで問題が起きます。

--------------
具体例)半角の片仮名の「タ」の文字(Halfwidth Katakana Letter Ta)は、FF80 ですし、
半角ハングルの「己人」のような文字(Halfwidth Hangul Letter Rieul-Sios)は FFAD です。
--------------

それ以外にも、Unicodeには「Zero Width Space」のような幅の無い文字や、「Combining Tilde」のような、他の文字と結合される文字も存在しますから、Shift_JISの場合のように単純にはいかなかったりします。
(今回は多言語文字列となっているので、他の文字コードに変換させるわけにもいきませんし…)

で。いずれにしても、半角/全角という判断から表示位置を探るのは、(たとえ固定ピッチフォントだとしても)無理があるので、私やputnoさんが書いたように、TextWidthなどを利用される事をおすすめします。>元質問者殿


くろねこ  2004-03-11 19:56:56  No: 112308

魔界の仮面弁士様、putno様、んっ様、nanashi様
お返事ありがとうございます。

全角半角での判断には無理があるみたいですので、
魔界の仮面弁士様やputno様がおっしゃられている
TextWidthメソッドを利用し、実現させていこうと思います。


punto  2004-03-11 20:02:27  No: 112309

うん.仰るとおりです.
言いたかったのは,じゃぁ Unicode で「半角」・「全角」って何?ってことだよ.ある context じゃ 頭 0 = 半角 が通用しちまうんだから,character code から文字幅割り出そうって魂胆に無理があるんでないかって話.

ともかく,みな意見は一致しているようですね!


40859  2004-03-11 20:50:20  No: 112310

> そもそも『Microsoft Forms 2.0』は再頒布権が無いから使用できないと思いますが。

nanashiさん。「再頒布できないので、使用できない」というのは、
ちょっと方向性が違いませんか。これが、"Out of Memory"の問題や、
Shift-Tabが使えない、などの理由を挙げて使用できないというのならば
わかりますけど・・・。

私自身は「使わないで済むなら、使わない方が良い」と思っていますが、
それでも、その再頒布権の問題に関しては、「再頒布しなければ良い」
というだけで済みますよね。コンポーネントが最初からインストール
されている(または、ユーザーがOfficeやActiveX Control Padなどを、
別途インストールする)なら、Fm20.dllをインストーラに含める必要も
無いのですから。

もちろん、MSForms 2.0自体は、本来はVB6用のコンポーネントでは
ないですから、問題があってもMSはサポートしてくれませんが、それは
「使うなら、自己責任で」と「再頒布してはいけない」というだけで、
それらを理解した上であれば、使用できない事は無いと思っています。


くろねこ  2004-03-12 00:39:37  No: 112311

TextWidthメソッドを試してみたのですが、
ハングル文字の文字サイズがちゃんととれませんでした。なぜでしょうか・・・?
予想としては、HEXでAC00(ハングル文字の”フト”という文字になります)を指定したば場合に全角文字としてのサイズが返ってくると思っていたのですが、実際には半角文字のサイズが返ってきました。
(日本語や英数字はちゃんとサイズがとれていました)

以下に確認した内容を記しておきます、ご教授よろしくお願いいたします。

環境:
  Win2000  VB6.0 SP5

確認した内容:
  FormとPictureBoxのTextWidthメソッドを利用した。
  フォントは、MSゴシック、MS UI Gothic、Gulim(ハングル)を試した

コード:
Private Sub Command5_Click()

    Dim strChar As String
    
    strChar = ChrW(&HAC00)

    MsgBox Picture1.TextWidth(strChar)
    MsgBox Me.TextWidth(strChar)

End Sub


魔界の仮面弁士  2004-03-12 01:08:00  No: 112312

あ。うっかりしてました。
「Unicodeにしか無い文字」は、TextWidthメソッドを利用できないのです。

替わりに、GetTextExtentPoint32 API (のWide系エントリ)を使って測定してみてください。


punto  2004-03-12 02:16:53  No: 112313

う…ついていけん….余計な事に口出しちまった.すまん.


※返信する前に利用規約をご確認ください。




  


  このエントリーをはてなブックマークに追加