New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
レイアウト桁位置に対するロジック桁位置の進め方を改善する #1658
Conversation
✅ Build sakura 1.0.3728 completed (commit 2ec9b6627d by @kazasaku) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
概要を読んだ限りでは不適切な仕様を改善する変更のように思えますが、実際に現在の実装でサロゲートペアが分割される例があるのかどうかが分かりませんでした。
分割される例があるかどうかの検証が必要だと思います。実害がないなら変更そのものが不要になってしまいますし、あるのなら改善を証明するテスト手法があったほうが良いように思います。
//! 指定した位置の文字がwchar_t何個分かを返す | ||
static CLogicInt GetSizeOfChar( const wchar_t* pData, int nDataLen, int nIdx ); | ||
static CLogicInt GetSizeOfChar( const CStringRef& cStr, int nIdx ) | ||
{ return GetSizeOfChar( cStr.GetPtr(), cStr.GetLength(), nIdx ); } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
追加したオーバーロードを検証するテストが欲しいです。
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
CStringRef を扱う GetKetaOfChar / GetColmOfChar のオーバーロードにもテストが無いです。
これも追加しときます。
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
対応完了。
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
CStringRef を扱う GetKetaOfChar / GetColmOfChar のオーバーロードにもテストが無いです。
これはたぶん私のやらかしです。追加していただきありがとうございます。
CLayoutInt k = cLayoutMgr.GetLayoutXOfChar(cLineStr, nPos); | ||
if(0 == k)k = CLayoutInt(1); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
これ、削除して大丈夫ですか? ゼロ幅スペースなどの幅0pxの文字でも1px描画するのが今の仕様であるように見えます。消してしまうと仕様変更になりませんか?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
現時点ではここに来るのは次の文字の時だけです( IS_KEYWORD_CHAR の仕様による)。
#$0123456789@ABCDEFGHIJKLMNOPQRSTUVWXYZ\_abcdefghijklmnopqrstuvwxyz
自分には過去に行ったサロゲートペア対応時の削除漏れに見えました。
また、この箇所以外に0桁を1桁にみなす動作をしている箇所はすべてコメントアウトされているはずです。
(このPRではCode Smellになってしまうので除去しています。)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
おっしゃる通り、IS_KEYWORD_CHAR の条件があるので不要ということでよさそうですね。了解しました。
実際に問題になったのは行頭禁則処理においてです。次行に追い出されるロジック単位文字数が足りませんでした。 |
✅ Build sakura 1.0.3730 completed (commit 8be14e313d by @kazasaku) |
tests/unittests/test-cnative.cpp
Outdated
// テスト用の文字列参照を提供するユーティリティ | ||
class GetStringRef { | ||
public: | ||
CStringRef SetString(const wchar_t* pcStr, size_t nLen) { return CStringRef(pcStr, nLen); } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
GetSizeOfChar の呼び出し時に CStringRef を直接構築すると不都合があるのでしょうか? 少し考えてみましたがよく分かりませんでした。
tests/unittests/test-cnative.cpp
Outdated
@brief CStringRef型文字列を使用したGetSizeOfCharの仕様確認 | ||
@remark 文字列中の指定位置にある文字の符号単位数を返す | ||
*/ | ||
TEST(CNativeW, GetSizeOfChar_with_CStringRef) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
これは好みの問題かもしれませんが、テストケースごと増やすよりも以前からのテストケースに assertion を追加する形の方が簡潔で良いように思えます。同じコメントを繰り返す必要がなくなりますし、内容のほぼ同じ asssertion は隣接していた方が読む人のストレス軽減に役立ちそうです。
//! 指定した位置の文字がwchar_t何個分かを返す | ||
static CLogicInt GetSizeOfChar( const wchar_t* pData, int nDataLen, int nIdx ); | ||
static CLogicInt GetSizeOfChar( const CStringRef& cStr, int nIdx ) | ||
{ return GetSizeOfChar( cStr.GetPtr(), cStr.GetLength(), nIdx ); } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
CStringRef を扱う GetKetaOfChar / GetColmOfChar のオーバーロードにもテストが無いです。
これはたぶん私のやらかしです。追加していただきありがとうございます。
SonarCloud Quality Gate failed. |
✅ Build sakura 1.0.3732 completed (commit 639d03ccf7 by @kazasaku) |
添付のマクロを動かしてみました。
行番号を数えて29でしょうか? 終了時のステータスバーの表示であれば「28 行」になっています。 |
…!
27 行で正しいです。失礼しました。 |
でしたら大丈夫ですね😃
ある種の弥縫策を改めて本修正にしたという理解でよろしいでしょうか。そういうことでしたら前後で変化がないことを確認するテストで適切ですね。 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
良さそうに見えます。
レビューありがとうございます。 サクラエディタの内部文字コードは、いわゆるUnicodeです。
サクラエディタでは、Unicodeに変換できなかったバイトデータを |
レビューありがとうございます。 |
PR の目的
レイアウト情報の作成過程で、ロジック桁位置の進む量を文字に応じて変化させる。
カテゴリ
PR の背景
現状のレイアウト作成処理では、レイアウト桁位置に対応するロジック桁を次の数だけ進めるようになっています。
ここでいう文字の桁数は、1文字が必ずロジック単位で1つであることを想定しているようです。
ロジック行上のデータはUTF-16で表現されるため、サロゲートペアはロジック単位で2つ進めなければなりません。
このため、レイアウト作成フローはサロゲートペアが分割されてしまうリスクを抱えています。
一方、行データのイテレータである CMemoryIterator クラスでは、
以前からロジック・レイアウト単位の増分をそれぞれ CNativeW クラスの静的メンバで計算しており、
サロゲートペアに遭遇しても問題がないようになっています。
PR のメリット
レイアウト作成時にサロゲートペアが前後に分割処理されることによって発生しうる不具合を防げます。
PR のデメリット (トレードオフとかあれば)
この PR の変更対象としたクラスには単体テストがなく、共有データ依存のため追加も難しいです。
このため一時的にカバレッジが低下します(全期間で見たカバレッジには影響ありません)。
仕様・動作説明
レイアウト作成処理において、現在処理している物理データ行上の文字の位置は、 SLayoutWork 構造体のメンバ変数に保持されています。
これまでこの変数にロジック単位で(文字ごとに)1ずつ加算していたところを、各文字毎に
CNativeW::GetSizeOfChar()
で取得した値を加算するように変更します。なお、既存コードに追加した GetSizeOfChar のオーバーロードを活用できる箇所がいくつかありますが、遡及適用は行っていません。
PR の影響範囲
各行のレイアウト作成を行う際の準処理(
CLayoutMgr::_MakeOneLine()
)テスト内容
以下の手順で変更前後の動作に変更がないことを確認してください。
手順
指定した内容でタイプ別設定を変更したのち、添付したマクロ実行します。
テスト用マクロ (test.zip)
(この設定変更を忘れないでください。)
2927 行です。関連 issue, PR
#1543
参考資料