Skip to content
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

タブ幅が半角単位8桁を超える場合でも下線が最後まで描画されるようにする #1673

Merged
1 commit merged into from May 23, 2021

Conversation

ghost
Copy link

@ghost ghost commented May 21, 2021

PR の目的

タブ記号の描画処理に関する不具合を修正します。

カテゴリ

  • 不具合修正

背景

patchunicode#1053 で指摘されている通り、タブ記号に対して下線を描画する設定が有効になっている際、
下線が半角単位8桁分しか描画されない不具合が存在します。
対策を行って、下線がタブ幅いっぱいに描画されるようにします。

再現手順

  1. タイプ別設定を開く
  2. スクリーンタブのレイアウト設定にて、タブ幅に「8」を超える値を設定する
  3. カラータブの色指定にて、「TAB記号」を選択し、「下線」のチェックボックスをオンにする
  4. タブ文字を入力する

参考画像

スクリーンショット 2021-05-21 203029

PR のメリット

  • 下線がタブ幅いっぱいに描画されるようになります。

PR のデメリット (トレードオフとかあれば)

  • 変更箇所は自動化された単体テストのカバー範囲外です。

仕様・動作説明

この不具合は、タブ記号の描画幅が最長で8桁に固定されているためです。
なお、タブ幅の上限値は「64」です。

以前よりタブの描画処理ではタブ幅をCLayoutMgrから取得するようになっていましたので、この PR では取得した値を半角単位桁数に換算し、タブ描画文字列の長さが換算値よりも小さければ不足分を補うようにしました。
(以下、前後比較)

  • タブ通常表示
    • 前:タブ表示文字列を、その長さ分描画するようになっていた。
      タブ表示文字列は最大で8字分しかないため、下線はそこまでしか描画されない。
    • 後:タブ表示文字列をstd::wstring型オブジェクトに入れ、タブ幅の長さが足りないときは空白を補うようにした。
  • タブ矢印表示
    • 前:矢印の背景として描画される空白の長さが8文字固定でした。
      なお、長い矢印表示の場合、矢印だけはタブ幅いっぱいに描画されます。
    • 後:タブ幅の長さ分の空白を持つstd::wstring型オブジェクトを作成し、これを描画に使うようにした。
  • CSVモード
    • 前:タブの背景として描画される空白の長さが8文字固定でした。
    • 後:タブ幅の長さ分の空白を持つstd::wstring型オブジェクトを作成し、これを描画に使うようにした。

なお、既存パッチでは不具合と関係しない他の変更が同時に実施されているように見えたため、既存パッチは利用していません。

PR の影響範囲

  • タブ記号の描画処理
  • CSVモードにおけるカンマ記号の描画処理

テスト内容

変更後のサクラエディタで前述した手順を再現し、発生しないことを確認します。
TSV/CSVモードでのテストは、添付のファイル( 6be2aec のビルドログ)を開いてタイプ別設定を変更し、設定が反映されたときの描画結果を確認します。
各自で用意したカンマ区切り・タブ区切りテキストでも確認できます。
test-file.zip

なお、TAB通常表示およびTAB矢印表示における影響は下表の通りです。
TAB表示の設定を切り替えてそれぞれの描画を確認してください。

TAB表示 →
表示モード↓
文字指定 短い矢印 長い矢印
通常モード 下線の描画に影響 下線の描画に影響 矢印記号と下線の描画に影響
TSVモード 下線の描画に影響 下線の描画に影響 矢印記号と下線の描画に影響

確認方法

  • 通常モード
    1. サクラエディタを開く
    2. タイプ別設定を変更
      スクリーンタブ:TAB幅に「8」を超える値を設定する
      スクリーンタブ:TAB表示に確認したい表示形式(上記表を参照)を設定
      カラータブ:色指定でTAB記号の下線を有効にする
    3. タブ文字を入力し、描画結果を確認する
  • TSV モード
    1. サクラエディタを開く
    2. 添付した圧縮ファイルに含まれる sample_buildlog_x64_release.txt を開く
    3. タイプ別設定を変更
      スクリーンタブ:折り返し方法を「折り返さない」に設定
      スクリーンタブ:TAB表示に確認したい表示形式(上記表を参照)を設定
      スクリーンタブ:レイアウトセクション一番下のコンボボックスを「TSV」に設定する
      カラータブ:色指定でTAB記号の下線を有効にする
    4. 設定変更後のタブ表示を確認する
  • CSV モード
    1. サクラエディタを開く
    2. 添付した圧縮ファイルに含まれる sample_buildlog_x64_release.csv を開く
    3. タイプ別設定を変更
      スクリーンタブ:折り返し方法を「折り返さない」に設定
      スクリーンタブ:レイアウトセクション一番下のコンボボックスを「CSV」に設定する
      カラータブ:色指定でTAB記号の下線を有効にする
    4. 設定変更後のタブ表示を確認する

いずれのパターンにおいて、次の2点が確認できれば問題ないと思います。

  1. 下線がタブ幅いっぱいに描画されるようになった
  2. 長い矢印記号がこれまで通りタブ幅いっぱいに描画されている(CSVモードの時は矢印記号を使わないので確認不要です)

関連 issue, PR

close: patchunicode#1053
#1645 … 単位を桁数に戻した場合はタブ記号描画幅の計算処理も必ず変更しなければなりません。

// tabDispWidth <= 8 ? tabDispWidth : 8, // Sep. 22, 2002 genta
nLen,
szForeViewString.c_str(),
static_cast<UINT>(szForeViewString.length()),
pMetrics->GetDxArray_AllHankaku() // FIXME:半角固定?
Copy link
Author

@ghost ghost May 21, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ここでは半角文字の文字間隔配列を取得していますが、タブ記号には全角文字も設定できるので、
GenerateDxArray2()の方が良いのかもしれません。
ただ、全角文字を指定しても現状正しく表示されているように見えるので、実害があるのか判断できませんでした。

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

指摘ではありませんが、タブ幅の最小値って2なんでしたっけ?

最小値に1以下を指定できるとしたら、この修正内容と関係なく問題ありな気がします。

Copy link
Author

@ghost ghost May 22, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

おそらく設定できます。
タイプ別ダイアログのコードを見たところ、スピンコントロールに対して「正の整数で1~64の範囲内」という入力規則が設定されていました。

if( nVal < 1 ){
nVal = 1;
}
if( nVal > 64 ){
nVal = 64;
}
::SetDlgItemInt( hwndDlg, IDC_EDIT_TABSPACE, nVal, FALSE );

タブ幅を1にしている人がいないとも限らないので、GenerateDxArray2を使用するように仕様変更(=このPRには含めない)しましょうか?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

めんどくさそうな感じっすねw

TAB幅に1を指定するのは趣味だと思うので、放置しましょう。

TAB幅に1を指定してあるのなら、
タブ描画に使うカスタム文字に全角文字を指定できてはいけない気がします。

TAB幅2未満のときだけ全角文字を無効とする、ないし、TAB描画文字に全角を指定したときは幅を2未満にできないようにする、みたいな修正を入れておくのがベターだと思います。
(自己責任っちゅうことで、放置でよいような・・・)

@AppVeyorBot
Copy link

Build sakura 1.0.3782 completed (commit 6a7a98bffe by @kazasaku)

@beru beru added the 🐛bug🦋 ■バグ修正(Something isn't working) label May 22, 2021
@ghost ghost marked this pull request as ready for review May 22, 2021 03:00
Copy link
Contributor

@berryzplus berryzplus left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

不具合内容は了解しました。
修正したほうがよい、も合意です。

なんとなく、必要でない箇所が直ってるように見えています。
・どのコードが原因で不具合が起きてました。だから直しました。
・修正と関連して、こういう修正を行いました。
という2点がハッキリしないのが気になってます。

::ExtTextOut(
gr,
sPos.GetDrawPos().x,
sPos.GetDrawPos().y,
ExtTextOutOption() & ~(bTrans? ETO_OPAQUE: 0),
&rcClip2,
L" ",
8,
szBackViewString.c_str(),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

不具合修正として直すべき箇所はココだけのように見えました。

sakura_core/view/figures/CFigure_Tab.cpp Outdated Show resolved Hide resolved
const CTextMetrics* pMetrics=&pcView->GetTextMetrics();
const CTextArea* pArea=&pcView->GetTextArea();

int nLineHeight = pMetrics->GetHankakuDy();
int nCharWidth = pMetrics->GetCharPxWidth(); // Layout→Px
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

換算方法の見直しで使用されなくなるので除去
(CLayoutMgr由来のピクセル単位数値は、CLayoutMgrの持つ基準値で換算すべき。)

CLayoutXInt tabDispWidthLayout = pcView->m_pcEditDoc->m_cLayoutMgr.GetActualTsvSpace( sPos.GetDrawCol(), L',' );
int tabDispWidth = (Int)tabDispWidthLayout;
CLayoutXInt nTabLayoutWidth = pcLayoutMgr.GetActualTsvSpace(sPos.GetDrawCol(), L',');
size_t nTabDispWidth = static_cast<Int>(nTabLayoutWidth) / pcLayoutMgr.GetWidthPerKeta();
Copy link
Author

@ghost ghost May 22, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

変数名変更
nTabLayoutWidht:タブのレイアウト幅(ピクセル単位数値)
nTabDispWidth:タブの表示幅(半角単位桁数)
nTabDispWidhtは後でsize_t型の値と演算するのでsize_tで宣言します。

Comment on lines -83 to +80
rcClip2.right = rcClip2.left + nCharWidth * tabDispWidth;
rcClip2.right = rcClip2.left + static_cast<Int>(nTabLayoutWidth);
Copy link
Author

@ghost ghost May 22, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

変更前はタブのピクセル幅に文字のピクセル幅を乗じていました。
(この計算結果は事実上「桁数×ピクセル単位文字幅^2」になってしまいます。)

Copy link
Author

@ghost ghost May 22, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

見直したら2乗にならないことがわかりました。

[[nodiscard]] int GetCharPxWidth() const { return 1; }

ただ、tabDispWidthの中身はピクセル単位数値なのだから、この演算をする意味はないと思います。

if( rcClip2.left < pArea->GetAreaLeft() ){
rcClip2.left = pArea->GetAreaLeft();
}
rcClip2.top = sPos.GetDrawPos().y;
rcClip2.bottom = sPos.GetDrawPos().y + nLineHeight;
int nLen = wcslen( m_pTypeData->m_szTabViewString );
Copy link
Author

@ghost ghost May 22, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Smell:未使用変数の定義・縮小型変換

@sonarcloud
Copy link

sonarcloud bot commented May 22, 2021

@@ -58,51 +56,53 @@ void CFigure_Comma::DispSpace(CGraphics& gr, DispPos* pDispPos, CEditView* pcVie
DispPos& sPos=*pDispPos;

//必要なインターフェース
const CLayoutMgr& pcLayoutMgr = pcView->GetDocument()->m_cLayoutMgr;
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CLayoutMgrを編集可能な状態でアクセスする必要はないので、const参照経由で使用します。

Comment on lines -31 to +32
void _DispTab( CGraphics& gr, DispPos* pDispPos, const CEditView* pcView );

// -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- //
// CFigure_Comma //
// CFigure_Comma //
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CFigure_Tab.cppをコピーした名残だと思われます。
未定義かつ使用されることはないと思うので消してしまいます。

Comment on lines -157 to +159
nCharWidth * tabDispWidth - (nPosLeft - sPos.GetDrawPos().x), // Tab Area一杯に 2013/4/11 Uchi
static_cast<Int>(nTabLayoutWidth) - (nPosLeft - sPos.GetDrawPos().x), // Tab Area一杯に 2013/4/11 Uchi
Copy link
Author

@ghost ghost May 22, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ここもタブのピクセル幅に文字のピクセル幅を乗じていました。

@ghost
Copy link
Author

ghost commented May 22, 2021

加筆しました。

@AppVeyorBot
Copy link

Build sakura 1.0.3784 completed (commit 469fcb1c26 by @kazasaku)

@ghost
Copy link
Author

ghost commented May 22, 2021

このPRは全く関係無いですが、ローカルでビルドしたときに次のような差分表示がVSのステータスバーに出ます。

  • ビルド後:変更差分「99%」
  • クリーン後:変更差分「16」

身に覚えのない大規模変更(99%ということは、リポジトリ内のほぼすべてのファイルということ?)なのですごい謎です。

@berryzplus
Copy link
Contributor

身に覚えのない大規模変更(99%ということは、リポジトリ内のほぼすべてのファイルということ?)なのですごい謎です。

gitの設定が影響していませんかね?

環境 設定内容
世間一般 gitに登録された通りの改行コードで取得し、ローカルブランチの改行コード通りに登録する。
このリポジトリ gitから取得する際にLFをCRLFに変換する。コミット時にCRLFをLFに変換して登録する。

https://qiita.com/yoshiplur/items/568d1e83c54a5c68da30
https://note.com/dafujii/n/n36c7ca892e90

ここのリポジトリはなんかおかしいので、autocrlf=trueを設定したほうが使いやすいです。「良識」に従えば、改行コードの自動変換は行うべきじゃないんですが、理解して設定するのをとやかく言うのは違うと思います。

こんな感じでコマンド叩けばそのうち治ると思います。

git config core.autoCRLF true
git config core.safeCRLF warn
git remote remove origin
git remote add origin git@github.com:sakura-editor/sakura.git
git fetch project --prune

remoteがいっぱいある場合はそれぞれ対処が必要っす。

@ghost
Copy link
Author

ghost commented May 22, 2021

身に覚えのない大規模変更(99%ということは、リポジトリ内のほぼすべてのファイルということ?)なのですごい謎です。

gitの設定が影響していませんかね?
環境 設定内容
世間一般 gitに登録された通りの改行コードで取得し、ローカルブランチの改行コード通りに登録する。
このリポジトリ gitから取得する際にLFをCRLFに変換する。コミット時にCRLFをLFに変換して登録する。

https://qiita.com/yoshiplur/items/568d1e83c54a5c68da30
https://note.com/dafujii/n/n36c7ca892e90

ここのリポジトリはなんかおかしいので、autocrlf=trueを設定したほうが使いやすいです。「良識」に従えば、改行コードの自動変換は行うべきじゃないんですが、理解して設定するのをとやかく言うのは違うと思います。

こんな感じでコマンド叩けばそのうち治ると思います。

git config core.autoCRLF true
git config core.safeCRLF warn
git remote remove origin
git remote add origin git@github.com:sakura-editor/sakura.git
git fetch project --prune

remoteがいっぱいある場合はそれぞれ対処が必要っす。

前にcore.autocrlfをtrueにして別にcloneしたことがあったんですが、そっちはincludeGuard.ps1に差分が出て --force オプションなしではブランチを移動できなくなりました。

作業前にソリューションをクリーンして、buildディレクトリを削除すれば「0」に戻るので、当分はinputのままでいきます。

@berryzplus
Copy link
Contributor

前にcore.autocrlfをtrueにして別にcloneしたことがあったんですが、そっちはincludeGuard.ps1に差分が出て --force オプションなしではブランチを移動できなくなりました。

作業前にソリューションをクリーンして、buildディレクトリを削除すれば「0」に戻るので、当分はinputのままでいきます。

なんかわかった気がします。 #1666 が原因ですね。

ぼくのとこでは、
repository-root/.git/info/exclude に
にDebugとかReleaseが入ってます。

Copy link
Contributor

@berryzplus berryzplus left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

問題なさそうに見えます。

@berryzplus
Copy link
Contributor

#1666 じゃなくて #1670 ですね<中間生成物の変更

@ghost
Copy link
Author

ghost commented May 22, 2021

確認ありがとうございます。
タブ幅計算処理はレイアウト単位の変更を実施したときに変更が必要になる(プロポーショナルフォント対応時、この2ファイルも変更されていました)ので、計算式はその時に再検討しようと思います。
静的コード解析の警告は"Complex method"と"Duplicated lines"でしたので、特に要求がなければ対応は行いません。

他に指摘等なければ近日中にマージしようと思います。

@ghost
Copy link
Author

ghost commented May 23, 2021

マージします。ご確認ありがとうございます。
何かありましたらお知らせください。

@ghost ghost merged commit 81f08b1 into sakura-editor:master May 23, 2021
@ghost ghost deleted the feature/fix_draw_length_tab_figures branch May 25, 2021 12:43
This pull request was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🐛bug🦋 ■バグ修正(Something isn't working)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants