[要望]ゼロ幅接合子U+200Dの扱いについてNo.38533
fzok4234 さん 20/11/09 07:13
 
コードポイント値がゼロ幅接合子U+200Dで連結されて1つの書記素クラスターを形成
している場合に
ついでですが、この1つの書記素クラスターをエディター上とマクロ上の両方で1文字
として扱うように
改善してもらいたいのですが、技術的に可能でしょうか?

まずエディター上についてですが、例えば、11個のコードポイント値の
1F469 1F3FC 200D 1F468 1F3FD 200D 1F466 1F3FC 200D 1F467 1F3FD
で表される肌の色の異なる4人家族の絵文字の場合、「動作環境」->「高度な編集2」
->「結合文字」を
有効にしても、
1F469 1F3FC
200D
1F468 1F3FD
200D
1F466 1F3FC
200D
1F467 1F3FD
の7文字に分割されて表示され、さらに、文字数計算ではコードポイント値の個数で
ある11が返って
きます。一方、Windows付属のメモ帳ではモノクロではあるもののちゃんと1個の合字
として表示
されます。要望としては、
  1. 表示/編集においてU+200Dでの連結を有効にしてちゃんと1文字として扱うオプ
ションを「動作環境」に
     設ける。
  2. 文字数計算においてU+200Dで連結されたものも含めて1つの書記素クラスターを
1文字として数える
     機能の追加。
  3. 複雑な書記素クラスターの入力などを容易にするため、コードポイントの16進
数/10進数の
     入力ダイアログを「編集」または「挿入」メニューに設ける。また、検索/置換
/Grepもコードポイントで
     行えるようにする。
といったところです。

また、マクロに於いてはUTF-16の要素数の19を返すwcslen()関数はあっても、書記素
クラスター単位で
文字数を数える関数はおろか、サロゲートペアを1個とするようなコードポイント値
を数える関数すら
そもそも備わっていません。このため、Unicodeの仕様を自分で調べて複雑なマクロ
を組まなければ
ならなくなっています。こちらも、
  1. 文字列値のコードポイント値の個数および書記素クラスターの個数を数える関数。
  2. 文字位置をUTF-16コード<->コードポイント<->書記素クラスターの個数単位で
相互に変換する関数。
があればマクロの記述がかなり簡潔になるので助かります。

おそらく、Windows 10の1703以降のicuuc.dllとicuin.dllや、あるいは1903以降のic
u.dllを呼び出すか、
もしくはICUの公式バイナリ
https://github.com/unicode-org/icu/releases/download/release-68-1/icu4c-68_1-Win64-MSVC2019.zip
https://github.com/unicode-org/icu/releases/download/release-68-1/icu4c-68_1-Win32-MSVC2019.zip
を秀丸エディタに同梱するかユーザーにインストールしてもらうかになると思われま
す。ICUライブラリを
使わずに自前で実装するとなると、各コードポイントの属性
https://www.unicode.org/Public/13.0.0/ucd/UnicodeData.txt
と、コードポイント同士の接合ルール
https://www.unicode.org/Public/13.0.0/ucd/auxiliary/GraphemeBreakProperty.txt
のテーブルからコード生成を行う必要があるようです。ちょっと自分勝手な(?)要望
となってしまいましたが、
どうかよろしくお願いします。

参考のまとめサイト:
https://ufcpp.net/blog/2016/9/unicode/
https://ufcpp.net/blog/2017/10/graphemesplitter/
https://ufcpp.net/blog/2017/11/graphemesplitterbyproduct/
https://ufcpp.net/blog/2018/12/unicodecategory/



[ ]
RE:38533 [要望]ゼロ幅接合子U+200Dの扱いNo.38534
秀丸担当 さん 20/11/09 16:45
 

いろいろご指摘ありがとうございます。
U+200Dでつながった絵文字は、一応現状でも一部対応がありました。
[その他]→[動作環境]→[編集]→[高度な編集2]の「結合文字を1つの文字として扱
う」と、
[その他]→[動作環境]→[表示/操作]→[文字の描画]の「3Dグラフィックスアクセラ
レータによる文字の描画」と「カラー絵文字」もONにする必要があります。
例えば、
1F468 200D 1F469 200D 1F467 200D 1F466
は4人が1つになった文字になります。

順番が違ったり、肌の色の文字が組み合わさったりすると、ご指摘の通りうまくいき
ませんでした。
ICUなどの情報もありがとうございます。
もしICUでやるとしたら、Windowsの対応も新しめのようなので、秀丸エディタは従来
の動作もできるハイブリッドか段階的かになるので、全面的にICUにするのは簡単で
はなさそうでした。
秀丸エディタの現状では、カラー絵文字の組み合わせの対応は独自判断をしていてい
たりします。
とりあえずわかっている範囲のことだけでもできたらと思います。
全ての組み合わせがリストアップされたようなものをもしご存知でしたら教えてもら
えると助かります。(たぶん組み合わせがすごい数なのでリストアップは現実的では
ないかもしれませんが)

文字数計算は、書記素クラスター単位のような数え方は確かに対応していませんでし
た。
やってみないとわからないこともありますが、カラー絵文字が結合しているときの
カーソル移動と同じようにできればいいと思います。

Unicodeの文字コードの入力は、「制御コード入力...」コマンドを拡張してやるとい
うネタもあったので、今後やろうかと思います。
現状でよく使う場合は、マクロでもできるので、マクロにしておくといいです。

マクロの例:
$a=input("Unicode16進数入力","U+1F468");
if(leftstr($a,2)=="U+"){
    $a=rightstr($a,strlen($a)-2);
}
insert unichar(val("0x"+$a));
endmacro;

grepの場合で、マクロを使わずgrepダイアログのままでやるとしたら、正規表現をON
にして、HmJreであれば「[\U00003042]」といったように書くとできます。
参考までの情報として、マクロでも他に各種の書き方があります。
setcompatiblemode 0x20000;
insert "\u3042"; //文字列16進数4桁
insert "\U00003042"; //文字列16進数8桁
insert unichar(0x3042); //数値
insert unichar(val("0x3042")); //16進数文字列を数値に変換
searchdown "\u3042";//マクロの文字列として検索
searchdown "\U00003042";//マクロの文字列として検索
searchdown "[\\u3042]",regular;//正規表現16進数4桁として検索
 //または @"[\u3042]",regular;
searchdown "[\\U00003042]",regular;//正規表現16進数8桁として検索
 //または @"[\U00003042]",regular;
endmacro;

マクロでサロゲートペアを1個とするような数え方や、書記素クラスター単位の数え
方も確かに無いです。
現状では、サロゲートペアは、一文字目のコードが0xD800から0xDBFFで二文字目が0x
DC00から0xDFFFであるとか、そういった面倒なことをする必要があると思います。
書記素クラスター単位であれば、現状のカラー絵文字で一部対応できている範囲にお
いては、実際にエディタ上に挿入するなどをしてright;で一文字分とかで数えるとか
になってしまうと思います。
もっと簡便にできたらいいと思います。
複雑なこともあってすぐに対応しますと言い切れないところもありますが、いろいろ
検討したいと思います。

[ ]
RE:38534 [要望]ゼロ幅接合子U+200Dの扱いNo.38535
fzok4234 さん 20/11/09 18:20
 
回答ありがとうございます。

> 秀丸エディタの現状では、カラー絵文字の組み合わせの対応は独自判断をしていて
>いたりします。
> とりあえずわかっている範囲のことだけでもできたらと思います。
> 全ての組み合わせがリストアップされたようなものをもしご存知でしたら教えても
>らえると助かります。
> (たぶん組み合わせがすごい数なのでリストアップは現実的ではないかもしれませ
>んが)

U+200Dで連結された書記素クラスターを正しく扱うためには、複数の書記素クラス
ター同士の「境界」が
どこにあるのかを判別することが大変重要になってきます。そのためには、コードポ
イント同士が連結して
1つの書記素クラスターとなるための「ルール」を解析しなければなりません。

このルールは、
  1. 各コードポイントが持つ役割、すなわち「属性」を定義したUnicodeData.txt。
  2. どの属性のコードポイント同士が連結可能かを定義したGraphemeBreakProperty.
txt。
からなっています。拝見されたと思いますが、この定義書は単なる「テーブル」であ
り、なおかつその
エントリー数も目がくらむほどの膨大な量となっています。

したがって、このテーブルに基づいて全ての組み合わせをリストアップするのは現実
的ではないと思われます。
実際、このテーブルからC#のコードを自動生成して作成した書記素クラスター境界判
別ツールの例
https://github.com/ufcpp/GraphemeSplitter/blob/master/GraphemeSplitter/Character.GetGraphemeBreakPropertyV10.cs
を見ればわかると思いますが、if文による判定が2万行にわたって延々と続いており、
これにUnicodeの
バージョンアップなどの理由で人の手での修正を加えることなどはほとんど不可能な
状態です。もちろん、
ユーザーがこれを秀丸マクロに移植することは無理難題であるといえます。

このような事情から、書記素クラスターを正しく扱う機能を独自判断で自前で実装す
るのは甚だ困難であるのは
明確であります。そこで、問題の解決の最適な策となるのは、Unicode規格のお膝下
である「Unicodeコンソーシアム」が
公式にリリースしているUnicode処理ライブラリを利用させていただくことです。そ
のライブラリが、最初に
取り上げた「ICU」です。

> もしICUでやるとしたら、Windowsの対応も新しめのようなので、秀丸エディタは従
>来の動作もできるハイブリッドか
> 段階的かになるので、全面的にICUにするのは簡単ではなさそうでした。

確かに、icuuc.dllとicuin.dllはWindows 10 1703以降でないと使えないので「対応
も新しめ」といえます。一方、
UnicodeコンソーシアムがリリースしているICUバイナリのDLLである「ICU4C」は、
http://site.icu-project.org/download/68#TOC-ICU4C-Download
に書かれているようにWindows 7でも使用可能とのことであるため、これを利用した
ほうがよいと思います。一応、
サイズが20MB超とかなり大きいことと、OSSのアプリを商用アプリである秀丸エディ
タに同梱するのはライセンス上
問題になることから、ユーザー側で各自インストールしてもらう形になると思われま
す。

> Unicodeの文字コードの入力は、「制御コード入力...」コマンドを拡張してやると
>いうネタもあったので、
> 今後やろうかと思います。
> 現状でよく使う場合は、マクロでもできるので、マクロにしておくといいです。
>
> マクロの例:
> $a=input("Unicode16進数入力","U+1F468");
> if(leftstr($a,2)=="U+"){
>     $a=rightstr($a,strlen($a)-2);
> }
> insert unichar(val("0x"+$a));
> endmacro;
>
> grepの場合で、マクロを使わずgrepダイアログのままでやるとしたら、正規表現を
>ONにして、HmJreであれば
> 「[\U00003042]」といったように書くとできます。
> 参考までの情報として、マクロでも他に各種の書き方があります。
> setcompatiblemode 0x20000;
> insert "\u3042"; //文字列16進数4桁
> insert "\U00003042"; //文字列16進数8桁
> insert unichar(0x3042); //数値
> insert unichar(val("0x3042")); //16進数文字列を数値に変換
> searchdown "\u3042";//マクロの文字列として検索
> searchdown "\U00003042";//マクロの文字列として検索
> searchdown "[\\u3042]",regular;//正規表現16進数4桁として検索
>  //または @"[\u3042]",regular;
> searchdown "[\\U00003042]",regular;//正規表現16進数8桁として検索
>  //または @"[\U00003042]",regular;
> endmacro;

代替マクロの提案ありがとうございます。当面はこれでしのげると思います。

> 現状では、サロゲートペアは、一文字目のコードが0xD800から0xDBFFで二文字目が
>0xDC00から0xDFFFであるとか、
> そういった面倒なことをする必要があると思います。

一応、.NET FrameworkのSystem.CharクラスのIsSurrogatePair()メソッドなどでサロ
ゲートペアの検出は可能なので、
C#で処理用クラスライブラリを作ってこみやんま氏のhm.NETから呼び出す形で当面は
しのぐことになりそうです。




[ ]
RE:38535 [要望]ゼロ幅接合子U+200Dの扱いNo.38536
fzok4234 さん 20/11/09 18:53
 
-追伸-

もし、外部のICUを利用する場合は、ユーザーがUnicode処理機能を
  1. 秀丸エディタ独自の内臓Unicode処理ルーチン(秀丸エディタ対応の全てのOS)。
  2. UnicodeコンソーシアムのICU4C(現時点でWindows 7以降)。
  3. Windows標準のicuuc.dllとicuin.dll(Windows 10 1703以降)。
  4. Windows標準のicu.dll(Windows 10 1903以降)。
の中から選択して切り替えができるようにしたらよいでしょう。



[ ]
RE:38536 [要望]ゼロ幅接合子U+200Dの扱いNo.38537
秀まるお2 さん 20/11/10 09:23
 
 いろいろ情報ありがとうございます。絵文字の処理は僕の担当部分なので僕の方で
これから調べてみます。

 − icuなどのライブラリを使うのもいろいろ大変。
 − すべての結合文字をリストアップするのもほとんど不可能に近い。
 − ちゃんとしたロジックを自前実装するのも無理がある。

 ということでどうするかですが、とりあえず現状の結合に加えて、「U+200D」でく
っつき要求があった時に、どれだけの長さがくっつくのか、DirectWriteのIDWriteTe
xtAnalyzer::GetGlyphsってAPI呼び出しで調査できると思うので、それを見た結果を
キャッシュするような方法が出来ないか、一回トライしてみようと思います。

 進捗があったらまた書き込みさせていただきます。

[ ]
RE:38537 [要望]ゼロ幅接合子U+200Dの扱いNo.38538
fzok4234 さん 20/11/10 11:31
 
>  − すべての結合文字をリストアップするのもほとんど不可能に近い。
>  − ちゃんとしたロジックを自前実装するのも無理がある。

このことについてふと思ったことがあります。先ほど申したUnicodeData.txtとGraph
emeBreakProperty.txtに
基づいての結合文字の判別ルーチンの自動生成についてですが、自動生成した数万行
のコードを静的に
秀丸エディタのコンパイル時に取り込むのではなく、秀丸エディタの「実行時」に判
別コードを「動的」に
メモリ上に生成して実行する、というやり方を採用すればそれほど大きな労力を費や
さなくても済むのではと
考えたのですがどうでしょうか?

先ほど例として取り上げた数万行に及ぶ
https://github.com/ufcpp/GraphemeSplitter/blob/master/GraphemeSplitter/Character.GetGraphemeBreakPropertyV10.cs
のコードも、元は
https://github.com/ufcpp/GraphemeSplitter/tree/master/GraphemeBreakPropertyCodeGenerator
にあるコード自動生成ツールでUnicodeData.txtとGraphemeBreakProperty.txtを読み
取って生成したもの
みたいです。この自動生成ツール自体はとりわけ巨大というわけではなく、他言語へ
の移植もそれほど
難しくないと思います。

.NET Frameworkには「式木」と言って、2項演算・代入・条件分岐・ループといった
演算処理の組み合わせを
実行時に動的にデリゲートとして生成してこれを呼び出し実行する、という機能が備
わっています。当方では
ネイティブなWin32プログラミングには疎いのですが、ひょっとしたらこれと同じよ
うな実行時の動的コード
生成/実行をネイティブ環境で実現するためのライブラリが存在するかもしれません。

もしこのようなライブラリが存在するのであれば、先ほどの自動生成ツールと同じア
ルゴリズムの動的コード
生成機能を秀丸エディタに実装すれば、後はユーザーが秀丸エディタを起動するとき
にUnicodeData.txtと
GraphemeBreakProperty.txtを読み込んでの結合文字の判別ルーチンの生成/実行が自
動で行われる、といった
ことが可能になるわけです。Unicodeの仕様のバージョンアップに伴う修正も、秀丸
エディタに同梱されている
UnicodeData.txtとGraphemeBreakProperty.txtを最新版に差し替えるだけで簡単に済
みます。

> 「U+200D」でくっつき要求があった時に、どれだけの長さがくっつくのか、Direct
>Writeの
> IDWriteTextAnalyzer::GetGlyphsってAPI呼び出しで調査できると思うので、それ
>を見た結果をキャッシュする
> ような方法が出来ないか、一回トライしてみようと思います。

https://docs.microsoft.com/en-us/windows/win32/api/dwrite/nf-dwrite-idwritetextanalyzer-getglyphs
によると、IDWriteTextAnalyzer::GetGlyphsは「フォントや描画ルールに基づいて解
析を行う」ようなので、
もしかしたらフォントの設定次第で書記素クラスターのサイズが変わってしまったり、
そもそもエディター上に
表示されていないマクロの文字列型の式では使えないのでは?、と思ってしまいまし
たが果たして大丈夫なのでしょうか?



[ ]
RE:38538 [要望]ゼロ幅接合子U+200Dの扱いNo.38539
秀まるお2 さん 20/11/10 12:13
 
> によると、IDWriteTextAnalyzer::GetGlyphsは「フォントや描画ルールに基づいて
>解析を行う」ようなので、
> もしかしたらフォントの設定次第で書記素クラスターのサイズが変わってしまった
>り、そもそもエディター上に
> 表示されていないマクロの文字列型の式では使えないのでは?、と思ってしまいま
>したが果たして大丈夫なのでしょうか?

 秀丸エディタでのカラー絵文字の描画は必ずSegoe UI Emojiフォントを使ってるの
で、テストも必ずSegoe UI Emojiでやる処理にするつもりではありますが、昨日テス
トしてたら、たしかにフォントによって結合具合が変わることがあるようでした。

 昨日テストして分かったんですが、メモ帳で、

insert "\uD83D\uDC69\u200D\u2764\uFE0F\u200D\uD83D\uDC8B\u200D\uD83D\uDC69";

 で出てくる結合文字をテストすると、フォントをSegoe UIまたはSegoe UI Emojiに
すれば結合しますがMeiryo UIとかだと結合しないで出てくるようです。元の発言で
連絡いただいた4人分の家族絵文字はちゃんと結合するのに、こっちはフォントによ
る違いが発生します。???

 こういう謎現象もあるので、やはりDirectWriteでたしかに結合することを確認す
る方式が一番安全な気がします。

 今まだDirectWriteでいけるかどうか確認できてないので、まだ先のことは分かり
ませんが、とりあえずそれでいけるつもりでテストしようと思ってる所です。

[ ]
RE:38539 [要望]ゼロ幅接合子U+200Dの扱いNo.38540
fzok4234 さん 20/11/10 13:31
 
ありがとうございます。

[ ]
RE:38534 [要望]ゼロ幅接合子U+200Dの扱いNo.38544
fzok4234 さん 20/11/13 17:08
 
v8.96β2にて、制御コード入力コマンドとcharcount()関数の改善、ucs4系関数の新
設などの対応
ありがとうございます。

現在、charcount( 0x00000088 )の挙動は「動作環境」->「高度な編集2」->「結合文
字」の設定状況に
依存しています。そこで、「結合文字」の設定に関して重ねての要望なのですが、
  1. 現在の設定状況を取得するキーワードの新設。
  2. マクロの実行中に「そのマクロの中だけ」設定値を変更する文の新設。マクロ
の外には一切影響を
     及ぼさない。
を実現していただければ、マクロの環境依存性を少しでも減らせるので助かります。

本当は、上記のような設定の取得やマクロ上のみの変更の文などが
https://help.maruo.co.jp/hidemac/html/051_Dependence.html
で示された全項目で実装されていればありがたいのですが、一気に全て対応するのは
大変なため、今回は
遠慮しておきます。



[ ]
RE:38544 [要望]ゼロ幅接合子U+200Dの扱いNo.38545
秀丸担当 さん 20/11/13 17:45
 

結合文字の動作は設定に依存しているので、有効であるかどうかを調べたり、setcom
patiblemodeで指定できたらいいと思います。
今後検討したいと思います。

現状で設定を調べるには、レジストリのだいぶん奥のほうというか知らないとわから
ない場所にあって、無理矢理ですが以下のようにして取得できます。
openreg "CURRENTUSER", "Software\\Hidemaruo\\Hidemaru\\Env";
#f = val("0x"+getregbinary( "ExEnv2", 9, 1 ));
closereg;
if(#f){
    message "結合文字ON";
} else {
    message "結合文字OFF";
}
endmacro;


とりあえずサロゲートペアの取り扱いが非常に面倒なのでucs4系関数を追加しました
が、これだけでは不十分と思っていて、実際のカーソル移動単位や書記素クラスター
単位で操作できたらいいと思います。
例えば書記素クラスター単位(Grapheme Clusters Unit)の略として、gcustrlenとか
movetogcuとか、そういうのが一式あったら楽になると思います。
今家族の絵文字など対応してもらっているのですが、ICU準拠だと無限に子供が増や
せるようで、それだと困るので、実際は完全準拠ではない上限を付けたりすることに
なると思います。あとOS依存性もあります。
そうなると、実用上のカーソル移動単位(Cursor Move Unit)の略でcmustrlenとかmov
etocmuとかがあったらいいと思います。
そういう一式も増やすとごっそり関数群などが増えてしまうのですが、関数群を減ら
して変換に頼るとものすごくマクロを作るのが面倒なので、増えるのも仕方ないかと
思っています。

[ ]
RE:38545 [要望]ゼロ幅接合子U+200Dの扱いNo.38548
秀丸担当 さん 20/11/16 09:51
 

現状でfontmodeというキーワードがあって、これでプロポーショナルフォントかどう
かを判別できるのですが、これで結合文字やカラー絵文字かなども取得できるように
しようと思います。
結合文字が有効かどうかだけでなく、カラー絵文字が有効に働いているかどうかでも
違いがあり、レジストリを見るだけでは正確な判断はできませんでした。

setcompatiblemodeでマクロ内だけで強制的に指定できないかと思ったのですが、結
合文字の変化によって折り返しが変化したり、「3Dグラフィックスアクセラレータに
よる文字の描画」やカラー絵文字でフォントの状態が一時的に変わるのは、現実的で
はなさそうでした。
結合文字が必要な場合fontmode等で判別して、メッセージを出したりしていただくほ
うがよさそうです。


[ ]
RE:38540 [要望]ゼロ幅接合子U+200Dの扱いNo.38551
秀まるお2 さん 20/11/19 13:48
 
 今日アップロードされた秀丸エディタのVersion 8.96β3にて、肌色指定付きの家
族絵文字の結合などに対応しましたが、一部制限があるので念のためここに書かせて
いただきますと・・・

 家族絵文字ですが、いろいろテストすると家族何人でもくっついて1つの絵文字に
なってしまうようです。たとえば

insert "12人それぞれ肌色指定。\U0001F469\U0001F3FC\u200D\U0001F468\U0001F3FD
\u200D\U0001F466\U0001F3FC\u200D\U0001F467\U0001F3FD\u200D\U0001F467\U0001F3
FD\u200D\U0001F467\U0001F3FD\u200D\U0001F467\U0001F3FD\u200D\U0001F467\U0001
F3FD\u200D\U0001F467\U0001F3FD\u200D\U0001F467\U0001F3FD\u200D\U0001F467\U00
01F3FD\u200D\U0001F467\U0001F3FD\n";

 で出てくる文字も、FirefoxやChromeのアドレスバーでは1つの文字として出てき
ます。しかし、カーソルの動き方がちょっとおかしいです。テストしたら10人までは
カーソルの動きが正しいですが、それを超えるとダメみたいです。

 なぜそうなってるのか理由がよく分かりませんが、とりあえず、無制限につながっ
てしまうと内部的な処理の都合(結合用のバッファサイズなど)的に問題が出るので、
秀丸エディタの中では結合する文字数を制限しています。

 U+200Dの文字が9文字以内(10人家族まで)、
 ユニコード文字で49文字まで。

 という制限にしています。それを超えた分は切れるようにしています。

 あと、絵文字にはU+FE0FやU+FE0Eの指定(FE0Fはカラー、FE0Eはモノクロ指定)が
付く場合が多くて、家族絵文字のそれぞれの人にもこれを付けてしまうことが可能な
んですが、一応、秀丸エディタでは、FE0Fが1つだけ付いてるのはうまく認識します
が、それ以外の、FE0Eが付いてたりFE0Fが複数個付いてたりするのは除外するように
しにした。(くっつく場合もあるかもしれないけど、その辺不定という扱い)

 そういう制限があることだけご了承お願いします。

 動作確認のテストに使ったマクロも念のため掲載します。

--------------------------------------------------------
insert "肌色指定。\U0001F469\U0001F3FC\n";

insert "2人家族絵文字。\U0001F468\u200D\U0001F469\n";
insert "2人家族絵文字。FE0F入り\U0001F468\uFE0F\u200D\U0001F469\uFE0F\n";
insert "2人家族絵文字。FE0F2つずつ入り\U0001F468\uFE0F\uFE0F\u200D\U0001F469
\uFE0F\uFE0F\n";


insert "2人家族絵文字あかちゃん。\U0001F468\u200D\U0001F476\n";
insert "4人家族絵文字。\U0001F469\u200D\U0001F468\u200D\U0001F466\u200D\U000
1F467\n";
insert "4人家族絵文字FE0F入り。\U0001F469\uFE0F\u200D\U0001F468\uFE0F\u200D\
U0001F466\uFE0F\u200D\U0001F467\uFE0F\n";
insert "4人家族絵文字FE0F2つずつ入り。\U0001F469\uFE0F\uFE0F\u200D\U0001F468
\uFE0F\uFE0F\u200D\U0001F466\uFE0F\uFE0F\u200D\U0001F467\uFE0F\uFE0F\n";
insert "5人家族絵文字。\U0001F469\u200D\U0001F468\u200D\U0001F466\u200D\U000
1F467\u200D\U0001F467\n";
insert "6人家族絵文字。\U0001F469\u200D\U0001F468\u200D\U0001F466\u200D\U000
1F467\u200D\U0001F467\u200D\U0001F467\n";
insert "7人家族絵文字。\U0001F469\u200D\U0001F468\u200D\U0001F466\u200D\U000
1F467\u200D\U0001F467\u200D\U0001F467\u200D\U0001F467\n";
insert "8人家族絵文字。\U0001F469\u200D\U0001F468\u200D\U0001F466\u200D\U000
1F467\u200D\U0001F467\u200D\U0001F467\u200D\U0001F467\u200D\U0001F467\n";
insert "9人家族絵文字。\U0001F469\u200D\U0001F468\u200D\U0001F466\u200D\U000
1F467\u200D\U0001F467\u200D\U0001F467\u200D\U0001F467\u200D\U0001F467\u200D\
U0001F467\u200D\U0001F467\n";
insert "10人家族絵文字。\U0001F469\u200D\U0001F468\u200D\U0001F466\u200D\U00
01F467\u200D\U0001F467\u200D\U0001F467\u200D\U0001F467\u200D\U0001F467\u200D
\U0001F467\u200D\U0001F467\u200D\U0001F467\n";
insert "11人家族絵文字。\U0001F469\u200D\U0001F468\u200D\U0001F466\u200D\U00
01F467\u200D\U0001F467\u200D\U0001F467\u200D\U0001F467\u200D\U0001F467\u200D
\U0001F467\u200D\U0001F467\u200D\U0001F467\u200D\U0001F467\n";
insert "12人家族絵文字。\U0001F469\u200D\U0001F468\u200D\U0001F466\u200D\U00
01F467\u200D\U0001F467\u200D\U0001F467\u200D\U0001F467\u200D\U0001F467\u200D
\U0001F467\u200D\U0001F467\u200D\U0001F467\u200D\U0001F467\u200D\U0001F467\n";

//4人それぞれ肌色指定付きの家族絵文字
insert "4人それぞれ肌色指定。\U0001F469\U0001F3FC\u200D\U0001F468\U0001F3FD\
u200D\U0001F466\U0001F3FC\u200D\U0001F467\U0001F3FD\n";

insert "5人それぞれ肌色指定。\U0001F469\U0001F3FC\u200D\U0001F468\U0001F3FD\
u200D\U0001F466\U0001F3FC\u200D\U0001F467\U0001F3FD\u200D\U0001F467\U0001F3F
D\n";
insert "6人それぞれ肌色指定。\U0001F469\U0001F3FC\u200D\U0001F468\U0001F3FD\
u200D\U0001F466\U0001F3FC\u200D\U0001F467\U0001F3FD\u200D\U0001F467\U0001F3F
D\u200D\U0001F467\U0001F3FD\n";
insert "7人それぞれ肌色指定。\U0001F469\U0001F3FC\u200D\U0001F468\U0001F3FD\
u200D\U0001F466\U0001F3FC\u200D\U0001F467\U0001F3FD\u200D\U0001F467\U0001F3F
D\u200D\U0001F467\U0001F3FD\u200D\U0001F467\U0001F3FD\n";
insert "8人それぞれ肌色指定。\U0001F469\U0001F3FC\u200D\U0001F468\U0001F3FD\
u200D\U0001F466\U0001F3FC\u200D\U0001F467\U0001F3FD\u200D\U0001F467\U0001F3F
D\u200D\U0001F467\U0001F3FD\u200D\U0001F467\U0001F3FD\u200D\U0001F467\U0001F
3FD\n";
insert "9人それぞれ肌色指定。\U0001F469\U0001F3FC\u200D\U0001F468\U0001F3FD\
u200D\U0001F466\U0001F3FC\u200D\U0001F467\U0001F3FD\u200D\U0001F467\U0001F3F
D\u200D\U0001F467\U0001F3FD\u200D\U0001F467\U0001F3FD\u200D\U0001F467\U0001F
3FD\u200D\U0001F467\U0001F3FD\n";
insert "10人それぞれ肌色指定。\U0001F469\U0001F3FC\u200D\U0001F468\U0001F3FD
\u200D\U0001F466\U0001F3FC\u200D\U0001F467\U0001F3FD\u200D\U0001F467\U0001F3
FD\u200D\U0001F467\U0001F3FD\u200D\U0001F467\U0001F3FD\u200D\U0001F467\U0001
F3FD\u200D\U0001F467\U0001F3FD\u200D\U0001F467\U0001F3FD\n";

insert "10人それぞれ肌色指定。U+FE0Fも入り。\U0001F469\U0001F3FC\uFE0F\u200D
\U0001F468\U0001F3FD\uFE0F\u200D\U0001F466\U0001F3FC\uFE0F\u200D\U0001F467\U
0001F3FD\uFE0F\u200D\U0001F467\U0001F3FD\uFE0F\u200D\U0001F467\U0001F3FD\uFE
0F\u200D\U0001F467\U0001F3FD\uFE0F\u200D\U0001F467\U0001F3FD\uFE0F\u200D\U00
01F467\U0001F3FD\uFE0F\u200D\U0001F467\U0001F3FD\uFE0F\n";


insert "11人それぞれ肌色指定。\U0001F469\U0001F3FC\u200D\U0001F468\U0001F3FD
\u200D\U0001F466\U0001F3FC\u200D\U0001F467\U0001F3FD\u200D\U0001F467\U0001F3
FD\u200D\U0001F467\U0001F3FD\u200D\U0001F467\U0001F3FD\u200D\U0001F467\U0001
F3FD\u200D\U0001F467\U0001F3FD\u200D\U0001F467\U0001F3FD\u200D\U0001F467\U00
01F3FD\n";
insert "12人それぞれ肌色指定。\U0001F469\U0001F3FC\u200D\U0001F468\U0001F3FD
\u200D\U0001F466\U0001F3FC\u200D\U0001F467\U0001F3FD\u200D\U0001F467\U0001F3
FD\u200D\U0001F467\U0001F3FD\u200D\U0001F467\U0001F3FD\u200D\U0001F467\U0001
F3FD\u200D\U0001F467\U0001F3FD\u200D\U0001F467\U0001F3FD\u200D\U0001F467\U00
01F3FD\u200D\U0001F467\U0001F3FD\n";

// 44文字 + 5 = 49文字  196バイト


//ハートマークでくっつく絵文字。メモ帳でうまく結合しないやつ。
insert "\uD83D\uDC69\u200D\u2764\uFE0F\u200D\uD83D\uDC8B\u200D\uD83D\uDC69\n";


insert "\U0001F469\U0000200D\U0001F4BB\n";
insert "\U0000200D\U0001F4BB\n";

insert "\uD83D\uDC69\u200D\uD83D\uDCBB\u200D\uD83D\uDCBB\n";



insert "\U0001F469\U0001F3FC\n";

insert "\uD83D\uDC69\u200D\uD83D\uDCBB\u200D\uD83D\uDCBB\n";


insert "\u2640\n";
insert "\u2708\n";
insert "\uD83D\uDC68\u200D\u2708\n";


insert "白髪指定男。\U0001f471\U0000200d\U00002642\U0000fe0f\n";

insert "男+白髪指定男はくっつかない。\U0001F468\u200D\U0001f471\U0000200d\U0
0002642\U0000fe0f\n";
insert "男+男。\U0001F468\u200D\U0001F468\n";

insert "男+Person with blond hairはくっつかない。\U0001F468\u200D\U0001f471\n";
insert "Person with blond hair同士もくっつかない。\U0001f471\u200D\U0001f471
\n";

insert "cGlyphTargetを補正する処理が動く文字。\uD83D\uDC68\u200D\u2764\uFE0F
\u200D\uD83D\uDC68\n";
insert "FE0F連続。\uD83D\uDC68\u200D\u2764\uFE0F\uFE0F\uFE0F\u200D\uD83D\uDC
68\n";
insert "FE0F無し。\uD83D\uDC68\u200D\u2764\u200D\uD83D\uDC68\n";
insert "FE0E入り。\uD83D\uDC68\u200D\u2764\uFE0E\u200D\uD83D\uDC68\n";

insert "\u26F9\uD83C\uDFFF\u200D\u2642\n";
insert "\u26F9\uD83C\uDFFF\n";
insert "\u26F9\uFE0F\u200D\u2640\n";
insert "\u26F9\uFE0F\u200D\u2642\n";
insert "\u26F9\u200D\u2642\n";
insert "\u26F9\n";


insert "cGlyphTargetを補正する処理が動く文字。\uD83D\uDC68\u200D\u2764\u200D
\uD83D\uDC68\n";
insert "\uD83D\uDC69\u200D\u2764\uFE0F\u200D\uD83D\uDC68\n";
insert "\uD83D\uDC69\u200D\u2764\uFE0F\u200D\uD83D\uDC69\n";
insert "\uD83D\uDC69\u200D\u2764\uFE0F\u200D\uD83D\uDC8B\u200D\uD83D\uDC68\n";
insert "\uD83D\uDC69\u200D\u2764\uFE0F\u200D\uD83D\uDC8B\u200D\uD83D\uDC69\n";


insert "FE0F入り絵文字\n";

insert "\u26F9\uFE0F\u200D\u2640\n";
insert "\u26F9\uFE0F\u200D\u2642\n";
insert "\uD83C\uDFCB\uFE0F\u200D\u2640\n";
insert "\uD83C\uDFCB\uFE0F\u200D\u2642\n";
insert "\uD83C\uDFCC\uFE0F\u200D\u2640\n";
insert "\uD83C\uDFCC\uFE0F\u200D\u2642\n";
insert "\uD83C\uDFF3\uFE0F\u200D\uD83C\uDF08\n";
insert "\uD83D\uDC41\uFE0F\u200D\uD83D\uDDE8\n";
insert "\uD83D\uDC68\u200D\u2764\uFE0F\u200D\uD83D\uDC68\n";
insert "\uD83D\uDC68\u200D\u2764\uFE0F\u200D\uD83D\uDC8B\u200D\uD83D\uDC68\n";
insert "\uD83D\uDC69\u200D\u2764\uFE0F\u200D\uD83D\uDC68\n";
insert "\uD83D\uDC69\u200D\u2764\uFE0F\u200D\uD83D\uDC69\n";
insert "\uD83D\uDC69\u200D\u2764\uFE0F\u200D\uD83D\uDC8B\u200D\uD83D\uDC68\n";
insert "\uD83D\uDC69\u200D\u2764\uFE0F\u200D\uD83D\uDC8B\u200D\uD83D\uDC69\n";
insert "\uD83D\uDD75\uFE0F\u200D\u2640\n";
insert "\uD83D\uDD75\uFE0F\u200D\u2642\n";


insert "FE0Fが無くても結合するかどうかテスト\n";

insert "\u26F9\u200D\u2640\n";
insert "\u26F9\u200D\u2642\n";
insert "\uD83C\uDFCB\u200D\u2640\n";
insert "\uD83C\uDFCB\u200D\u2642\n";
insert "\uD83C\uDFCC\u200D\u2640\n";
insert "\uD83C\uDFCC\u200D\u2642\n";
insert "\uD83C\uDFF3\u200D\uD83C\uDF08\n";
insert "\uD83D\uDC41\u200D\uD83D\uDDE8\n";
insert "\uD83D\uDC68\u200D\u2764\u200D\uD83D\uDC68\n";
insert "\uD83D\uDC68\u200D\u2764\u200D\uD83D\uDC8B\u200D\uD83D\uDC68\n";
insert "\uD83D\uDC69\u200D\u2764\u200D\uD83D\uDC68\n";
insert "\uD83D\uDC69\u200D\u2764\u200D\uD83D\uDC69\n";
insert "\uD83D\uDC69\u200D\u2764\u200D\uD83D\uDC8B\u200D\uD83D\uDC68\n";
insert "\uD83D\uDC69\u200D\u2764\u200D\uD83D\uDC8B\u200D\uD83D\uDC69\n";
insert "\uD83D\uDD75\u200D\u2640\n";
insert "\uD83D\uDD75\u200D\u2642\n";

[ ]
RE:38551 [要望]ゼロ幅接合子U+200Dの扱いNo.38552
fzok4234 さん 20/11/19 17:26
 
いろいろ対応していただいてありがとうございます。お疲れさまでした。

> insert "12人それぞれ肌色指定。\U0001F469\U0001F3FC\u200D\U0001F468\U0001F3
>FD\u200D\U0001F466\U0001F3FC\u200D\U0001F467\U0001F3FD\u200D\U0001F467\U000
>1F3FD\u200D\U0001F467\U0001F3FD\u200D\U0001F467\U0001F3FD\u200D\U0001F467\U
>0001F3FD\u200D\U0001F467\U0001F3FD\u200D\U0001F467\U0001F3FD\u200D\U0001F46
>7\U0001F3FD\u200D\U0001F467\U0001F3FD\n";
>
> で出てくる文字も、FirefoxやChromeのアドレスバーでは1つの文字として出てき
>ます。しかし、
> カーソルの動き方がちょっとおかしいです。テストしたら10人まではカーソルの動
>きが正しいですが、
> それを超えるとダメみたいです。
>
> なぜそうなってるのか理由がよく分かりませんが、とりあえず、無制限につながっ
>てしまうと
> 内部的な処理の都合(結合用のバッファサイズなど)的に問題が出るので、秀丸エ
>ディタの中では
> 結合する文字数を制限しています。
>
>  U+200Dの文字が9文字以内(10人家族まで)、
>  ユニコード文字で49文字まで。
>
> という制限にしています。それを超えた分は切れるようにしています。

手元のFirefox 75.0のアドレスバーでも12人文字でのカーソルの動きが確かにおかし
かったです。
しかし、これはFirefoxやChromeといった秀丸エディタとは関係のない「外部アプ
リ」の話なので、
わざわざこれに合わせた制限をかける必要はないように感じてしまいます。

>  U+200Dの文字が9文字以内(10人家族まで)、
>  ユニコード文字で49文字まで。

この2つの制限値を「動作環境」からユーザーが自由に変更できるようにして、それ
に応じて結合用の
内部バッファーサイズを動的に変化させるようにした方がよいと思います。もちろん、
ユーザーが
U+200Dを10個以上にとかコードポイント値数を50個以上に設定しようとしたときは
「FirefoxやChromeなどが
対応していない」旨の確認ダイアログを表示させるべきです。

また、
  ・この2つの制限値をマクロのキーワードで取得可能にする。
  ・ファイルオープン時にこの制限値に引っかかったときには、そのことを通知する
ダイアログを
    表示する。
といった対策もあった方がよいと思います。


[ ]
RE:38552 [要望]ゼロ幅接合子U+200Dの扱いNo.38553
秀まるお2 さん 20/11/19 17:58
 
> この2つの制限値を「動作環境」からユーザーが自由に変更できるようにして、そ
>れに応じて結合用の
> 内部バッファーサイズを動的に変化させるようにした方がよいと思います。

 文字数的な制限を設定する理由としては、いわゆるバッファオーバーフローなどの
「バグ」を防ぐ目的なので、ユーザーさんに任意に設定できようにってのはちょっと
無理があります。10人/49文字程度で制限したのは、一応、内部的なバッファに余裕
がある範囲でなるべく多くってことだとこのくらいだろうという感じで適当に決めた
所です。

 とりあえず、そんなに大人数の家族絵文字を日常的に使うことは無いと思うので、
とりあえずはこのままの仕様にしようと思います。

[ ]
RE:38553 [要望]ゼロ幅接合子U+200Dの扱いNo.38555
fzok4234 さん 20/11/20 11:25
 
> いわゆるバッファオーバーフローなどの「バグ」を防ぐ目的なので、

もしかして、この結合用バッファーの実装はstd::vectorやstd::listのような要素の
追加や削除で
自動でメモリ領域のサイズが変更されるコレクションではなく、wchar_t buffer[6
4];といった
固定長配列やmalloc()によるヒープへのベタ書きなどでサイズの固定値をハードコー
ドする、といった
融通が利かず脆弱性にもなりうる実装になってしまっているのでしょうか?

もし仮にそうであったならば、この結合用バッファー以外にも機能拡張の妨げのみな
らず
バッファーオーバーフローなどの脆弱性にもつながるような問題が秀丸エディタ内に
多数存在する
のではないかと疑ってしまいます。今一度各種バッファーの実装の確認をお願いしま
す。



[ ]
RE:38555 [要望]ゼロ幅接合子U+200Dの扱いNo.38556
秀まるお2 さん 20/11/20 13:08
 
 固定長のバッファを取ってる処理はいくらでもあります。たとえばファイル名用の
バッファはMAX_PATH分確保したりするし、そもそも的にWindowsのAPIが固定長バッフ
ァを扱う前提になってるのに、固定長バッファ一切使わずにってのは無理があります。
また、ヒープをあんまり使うとそれはそれで性能劣化になるし、逆にメモリリークの
バグが出やすくなったりで、デメリットもあります。ライブラリを使うと、そのライ
ブラリのバグによってとんでもない目に遭うこともあります。

 人に言われて何かいじって、それで結果的にバグが出たり性能問題が出たりしても、
その要望した人が責任取ってくれる訳でも無いですから、この辺は僕の判断で決めさ
せていただきます。

[ ]
RE:38556 [要望]ゼロ幅接合子U+200Dの扱いNo.38557
fzok4234 さん 20/11/21 11:32
 
とりあえず、バッファーサイズによる10人/49文字の制限から「はみ出した文字」を
識別する方法を
ご教示いただければありがたいです。具体的には、
  ・ぶら下げ処理。
  ・はみ出した文字のみを検索する。
といった処理を行って「はみ出した文字」を特別扱いさせたいからです。



[ ]
RE:38557 [要望]ゼロ幅接合子U+200Dの扱いNo.38560
秀丸担当 さん 20/11/24 10:45
 

目的と合っているかわからないですが、V8.96β3で追加されたマクロでは、カーソル
移動単位と書記素クラスター単位の違いを見ることで一応検出できるようになりまし
た。
β3では折り返しをまたげない制約もあって、やっぱり扱いづらいので、V8.96β4で
1つの折り返しはまたげるようにしています。

移動してみて違いを見る例:
moveto_cmu column_cmu + 1, lineno; //カーソル移動単位で右の位置
#column1=column;
#lineno1=lineno;
moveto2 #column0,#lineno0;
moveto_gcu column_gcu + 1, lineno; //書記素クラスター単位で右の位置
#column2=column;
#lineno2=lineno;
moveto2 #column0,#lineno0;
right;
if( #column1 != #column2 ) {
    message "カーソル移動と書記素クラスター単位の相違";
}
endmacro;

位置を変換して違いを見る例:
if(cmu_to_char(lineno,column_cmu + 1) != gcu_to_char(lineno,column_gcu + 1) ) {
    message "カーソル移動と書記素クラスター単位の相違";
}
right;
endmacro;

[ ]