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 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 | - | | | - | | | | | ! | | | - | | | - | | | | | ! | | ! |
|
禁則処理とは行末や行頭に来ると見た目の悪い文字の配置を調整する処理のことです。
「】」や「?」、「『」など行頭や行末に来ると見栄えの悪いものを行末に押し込んだりあるいは行頭に移動したり(行頭禁則、行末禁則)、「19,800円」など途中に改行を入れると見栄えの悪いものを前の行の行末や今の行の行頭に全部押し込んでしまう処理(分離禁則)のことを言います。
禁則処理対象文字リスト
行末禁則文字:
‘“(〔[{〈《「『【
行頭禁則文字:
、。,.’”)〕]}〉》」』】 ・:;?!ヽヾゝゞ〃々ー―〜…‥ っゃゅょッャュョぁぃぅぇぉァィゥェォ
APIのDrawText?を使用すると禁則処理などに対応した自動改行が簡単に表現できるようです。
+ | DrawText?使用サンプル |
![]() ![]()
|
モジュール化しました。
2バイト文字対応型の自動改行サンプル(禁則処理非対応)をモジュール化したものです。
モジュール化での大きな変更点は、改行を入れる際に
buf+="\n"
を
poke buf, j, 13 poke buf,j+1, 10
に変えた点です。
変数は初期化せずに使用しており、かつ処理中は終了コードを入れないので、処理中は前の
変数内容が残った状態になっています。
うかつに+=を使うと変なところに追加されてしまうのでpokeで上書きしています。
+ | 自動改行 moji20 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 | - | | - | | ! - | | | ! - | | | - | | ! - | | | | | | | | ! |
|
上のサンプルのやりかたで禁則処理に対応しようとするとなかなかに難しいことが分かりました。orz
そこでサンプルとは手法を変え、やり方を整理して、さらに禁則処理に対応させたものがこれです。
キーボードの←→キーを押すか、マウスクリックで改行位置が変わります。
実行して確認してみてください。
+ | 自動改行モジュールサンプル moji18 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 | - | | - | | ! - - | - | | ! ! ! - | | - | ! | | - | | ! | | | | | - - | ! ! ! - | | ! - | | | - | | ! - | | | | | | - - | | ! ! ! - | | | | | | | | ! |
|
String/矩形で解説されている、文字列サイズの取得機能を使用することで、プロポーショナルフォント*2を使用した場合での改行を実現します。
これによりプロポーショナルフォントを使用した場合でも自然な位置に改行を入れることができるようになります。
+ | 自動改行 moji21 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 | - | | - | | ! - - | - | | | ! ! ! - | | - | ! | | - | | | ! | | | | | - - | | ! ! ! - | | | ! - | | | | | | | | - | | | | | | | ! - | | | | | | | - - | | ! ! ! |
|
基本的には文字数指定タイプと同じです。
改行を挿入するトリガーが文字数から文字幅サイズに変わっただけです。
文字幅を1文字ずつ計って加算して、指定サイズを超えたら改行するようになっています。
改行後の文字幅を取得するため、改行候補位置までの文字幅も記録しています。
ilenstr ;1行の文字列xサイズ ilenstret ;1行の改行候補文字までの文字列xサイズ
文字の処理をする際、2バイト目に\(0x5c)を含む駄目文字があるため取扱いは注意が必要です。
該当文字は次の通り。
ソ噂浬欺圭構蚕十申曾箪貼能表暴予禄兔喀媾彌拿杤歃濬畚秉綵臀藹觸軆鐔饅鷭
+ | _mbsbtype |
|
0 1 2#pragma twiceの解説によれば…