hinekure.net が http://hspdev-wiki.net/ から自動クローリングした結果を表示しています。画像やリソースなどのリンクが切れています。予めご了承ください。 |
文字列の自動改行の解説です。
実装できればアドベンチャーゲームなどの作成などで使えそうな機能です。
あとあと何かと必要になってくる2バイト文字の判定関数モジュールです。
文字は通常、日本語や記号は2バイト、それ以外は1バイトを使用して表現されています。
またこれらは文字列中に混在するので多少厄介です。
しかしHSPで通常扱われているシフトJISコードにおいては次のルールが適用されているようです。
シフトJISコードが2バイト文字で使用している値
1バイト目:0x81〜0x9f, 0xe0〜0xfc
2バイト目:0x40〜0x7e, 0x80〜0xfc
マニュアルにも記載があります。
コードが129〜159か、224〜252の範囲にある場合は、次の1バイトと合わせて1文字の全角コードとなる。 (HSPマニュアルより引用)
1バイト文字と2バイト文字の領域を次のように色分けして表示してみます。
1バイト文字 |
2バイト文字 |
その他 |
このように2バイト文字の2バイト目では、1バイト文字 2バイト文字両方の領域で重なっていることが分かります。
1バイト目 | 0x20 | 〜 | 0x7e | 0x81 | 〜 | 0x9f | 0xA1 | 〜 | 0xdf | 0xe0 | 〜 | 0xfc | ||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
2バイト目 | 0x40 | 〜 | 0x7e | 0x80 | 〜 | 0xfc |
1バイトずつ順番に取り出して、これを用いて判定すれば1バイト文字か2バイト文字かの判定が出来ます。
順番を数え間違えると2バイト文字の1バイト目なのか2バイト目なのか分からなくなるので注意が必要です。
取り出した1バイトが2バイト文字の1バイト目領域内にあるかどうかの判定を行うモジュールが次のものになります。
(※アドベンチャーエンジンのところから持ってきました。)
1 2 3 4 5 6 7 8 9 |
|
文字列を順番に取り出していき、最初にIsByte?()=1が出たところが2バイト文字1バイト目、次のバイトはIsByte?()は0でも1でも2バイト文字2バイト目になります。
これ以外のときのIsByte?()=0が1バイト文字となります。
msvcrt.dllの_mbsbtype関数の動きをHSP標準命令で作ったモジュールで再現してみました。
+ | _mbsbtype(by msvcrt.dll) |
|
+ | _mbsbtype(by HSP標準命令) |
|
とりあえずやってみたサンプル
String/矩形で解説されている、文字列サイズの取得機能を使用することで、指定サイズでの
改行を実現します。
これによりプロポーショナルフォント*1を使用した場合でも自然な位置に改行を入れることができるはずです。
+ | 自動改行 moji06 |
moji06.hsp
|
禁則処理とは行末や行頭に来ると見た目の悪い文字の配置を調整する処理のことです。
「】」や「?」、「『」など行頭や行末に来ると見栄えの悪いものを行末に押し込んだりあるいは行頭に移動したり(行頭禁則、行末禁則)、「19,800円」など途中に改行を入れると見栄えの悪いものを前の行の行末や今の行の行頭に全部押し込んでしまう処理(分離禁則)のことを言います。
禁則処理対象文字リスト
行末禁則文字:
‘“(〔[{〈《「『【
行頭禁則文字:
、。,.’”)〕]}〉》」』】 ・:;?!ヽヾゝゞ〃々ー―〜…‥ っゃゅょッャュョぁぃぅぇぉァィゥェォ
APIのDrawText?を使用すると禁則処理などに対応した自動改行が簡単に表現できるようです。
+ | DrawText?使用サンプル |
|
モジュール化しました。
2バイト文字対応型の自動改行サンプル(禁則処理非対応)をモジュール化したものです。
モジュール化での大きな変更点は、改行を入れる際に
buf+="\n"
を
poke buf, j, 13 poke buf,j+1, 10
に変えた点です。
変数は初期化せずに使用しており、かつ処理中は終了コードを入れないので、処理中は前の
変数内容が残った状態になっています。
うかつに+=を使うと変なところに追加されてしまうのでpokeで上書きしています。
+ | 自動改行 moji20 |
moji20.hsp
|
上のサンプルのやりかたで禁則処理に対応しようとするとなかなかに難しいことが分かりました。orz
そこでサンプルとは手法を変え、やり方を整理して、さらに禁則処理に対応させたものがこれです。
キーボードの←→キーを押すか、マウスクリックで改行位置が変わります。
実行して確認してみてください。
+ | 自動改行モジュールサンプル moji18 |
moji18.hsp
|
String/矩形で解説されている、文字列サイズの取得機能を使用することで、プロポーショナルフォント*2を使用した場合での改行を実現します。
これによりプロポーショナルフォントを使用した場合でも自然な位置に改行を入れることができるようになります。
+ | 自動改行 moji21 |
moji21.hsp
|
基本的には文字数指定タイプと同じです。
改行を挿入するトリガーが文字数から文字幅サイズに変わっただけです。
文字幅を1文字ずつ計って加算して、指定サイズを超えたら改行するようになっています。
改行後の文字幅を取得するため、改行候補位置までの文字幅も記録しています。
ilenstr ;1行の文字列xサイズ ilenstret ;1行の改行候補文字までの文字列xサイズ
文字の処理をする際、2バイト目に\(0x5c)を含む駄目文字があるため取扱いは注意が必要です。
該当文字は次の通り。
ソ噂浬欺圭構蚕十申曾箪貼能表暴予禄兔喀媾彌拿杤歃濬畚秉綵臀藹觸軆鐔饅鷭
+ | _mbsbtype |
|
0 1 2#pragma twiceの解説によれば…