From 9586733adf6b5cc794f2f319153608b6c85edb7d Mon Sep 17 00:00:00 2001 From: Kohki Akikaze <67105596+kazasaku@users.noreply.github.com> Date: Sun, 11 Apr 2021 10:53:25 +0900 Subject: [PATCH 1/4] =?UTF-8?q?CNativeW::GetSizeOfChar=E3=81=ABCStringRef?= =?UTF-8?q?=E5=9E=8B=E3=81=AE=E6=96=87=E5=AD=97=E5=88=97=E3=82=92=E5=8F=97?= =?UTF-8?q?=E3=81=91=E5=85=A5=E3=82=8C=E3=82=8B=E3=82=AA=E3=83=BC=E3=83=90?= =?UTF-8?q?=E3=83=BC=E3=83=AD=E3=83=BC=E3=83=89=E3=82=92=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sakura_core/mem/CNativeW.h | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/sakura_core/mem/CNativeW.h b/sakura_core/mem/CNativeW.h index e96cb59bf4..ed82ed2d08 100644 --- a/sakura_core/mem/CNativeW.h +++ b/sakura_core/mem/CNativeW.h @@ -153,19 +153,20 @@ class CNativeW final : public CNative{ public: // -- -- staticインターフェース -- -- // - static CLogicInt GetSizeOfChar( const wchar_t* pData, int nDataLen, int nIdx ); //!< 指定した位置の文字がwchar_t何個分かを返す - static CHabaXInt GetHabaOfChar( const wchar_t* pData, int nDataLen, int nIdx, - bool bEnableExtEol, CCharWidthCache& cache = GetCharWidthCache() ); + //! 指定した位置の文字が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 ); } //! 指定した位置の文字が半角何個分かを返す static CKetaXInt GetKetaOfChar( const wchar_t* pData, int nDataLen, int nIdx, CCharWidthCache& cache = GetCharWidthCache() ); + static CKetaXInt GetKetaOfChar( const CStringRef& cStr, int nIdx ) + { return GetKetaOfChar( cStr.GetPtr(), cStr.GetLength(), nIdx ); } static const wchar_t* GetCharNext( const wchar_t* pData, int nDataLen, const wchar_t* pDataCurrent ); //!< ポインタで示した文字の次にある文字の位置を返します static const wchar_t* GetCharPrev(const wchar_t* pData, size_t nDataLen, const wchar_t* pDataCurrent); //!< ポインタで示した文字の直前にある文字の位置を返します - static CKetaXInt GetKetaOfChar( const CStringRef& cStr, int nIdx ) //!< 指定した位置の文字が半角何個分かを返す - { - return GetKetaOfChar(cStr.GetPtr(), cStr.GetLength(), nIdx); - } + static CHabaXInt GetHabaOfChar( const wchar_t* pData, int nDataLen, int nIdx, + bool bEnableExtEol, CCharWidthCache& cache = GetCharWidthCache() ); static CLayoutXInt GetColmOfChar( const wchar_t* pData, int nDataLen, int nIdx, bool bEnableExtEol ) { return GetHabaOfChar(pData,nDataLen,nIdx, bEnableExtEol); } From ffa332caacca1c98f9a2d6b8e9562e8d3a819bc4 Mon Sep 17 00:00:00 2001 From: Kohki Akikaze <67105596+kazasaku@users.noreply.github.com> Date: Fri, 23 Apr 2021 14:46:41 +0900 Subject: [PATCH 2/4] =?UTF-8?q?=E3=83=AC=E3=82=A4=E3=82=A2=E3=82=A6?= =?UTF-8?q?=E3=83=88=E4=BD=9C=E6=88=90=E3=83=95=E3=83=AD=E3=83=BC=E3=81=AB?= =?UTF-8?q?=E3=81=8A=E3=81=84=E3=81=A6=E7=89=A9=E7=90=86=E3=83=87=E3=83=BC?= =?UTF-8?q?=E3=82=BF=E5=8F=82=E7=85=A7=E4=BD=8D=E7=BD=AE=E3=81=AE=E5=A2=97?= =?UTF-8?q?=E5=88=86=E3=82=92=E6=96=87=E5=AD=97=E3=81=94=E3=81=A8=E3=81=AB?= =?UTF-8?q?=E9=83=BD=E5=BA=A6=E8=A8=88=E7=AE=97=E3=81=99=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../doc/layout/CLayoutMgr_DoLayout.cpp | 41 ++++++++----------- 1 file changed, 18 insertions(+), 23 deletions(-) diff --git a/sakura_core/doc/layout/CLayoutMgr_DoLayout.cpp b/sakura_core/doc/layout/CLayoutMgr_DoLayout.cpp index 2de5300a63..16b87369b7 100644 --- a/sakura_core/doc/layout/CLayoutMgr_DoLayout.cpp +++ b/sakura_core/doc/layout/CLayoutMgr_DoLayout.cpp @@ -49,12 +49,13 @@ static bool _GetKeywordLength( CLogicInt nWordLen = CLogicInt(0); CLayoutInt nWordKetas = CLayoutInt(0); while(nPos0){ @@ -188,7 +189,7 @@ void CLayoutMgr::_DoKutoBurasage(SLayoutWork* pWork) const if( _IsKinsokuPosKuto( GetMaxLineLayout() - pWork->nPosX, nCharKetas ) && IsKinsokuKuto( pWork->cLineStr.At( pWork->nPos ) ) ) { pWork->nWordBgn = pWork->nPos; - pWork->nWordLen = 1; + pWork->nWordLen = CNativeW::GetSizeOfChar( pWork->cLineStr, pWork->nPos ); pWork->eKinsokuType = KINSOKU_TYPE_KINSOKU_KUTO; } } @@ -203,24 +204,17 @@ void CLayoutMgr::_DoGyotoKinsoku(SLayoutWork* pWork, PF_OnLine pfOnLine) && (pWork->eKinsokuType == KINSOKU_TYPE_NONE) ) { // 2007.09.07 kobake レイアウトとロジックの区別 - CLayoutInt nCharKetas2 = GetLayoutXOfChar( pWork->cLineStr, pWork->nPos ); - CLayoutInt nCharKetas3 = GetLayoutXOfChar( pWork->cLineStr, pWork->nPos+1 ); - bool bLowSurrogate = false; + CLogicXInt nCharSize = CNativeW::GetSizeOfChar( pWork->cLineStr, pWork->nPos ); + CLayoutXInt nCharKetas1 = GetLayoutXOfChar( pWork->cLineStr, pWork->nPos ); + CLayoutXInt nCharKetas2 = GetLayoutXOfChar( pWork->cLineStr, pWork->nPos + nCharSize ); - if( nCharKetas3 == 0 && pWork->nPos + 2 < pWork->cLineStr.GetLength() ) - { - // サロゲートペア対策(取得した文字幅が0だったら下位側を読み取ったと判断し、次の位置に進ませる) - bLowSurrogate = true; - nCharKetas3 = GetLayoutXOfChar( pWork->cLineStr, pWork->nPos + 2 ); - } - - if( _IsKinsokuPosHead( GetMaxLineLayout() - pWork->nPosX, nCharKetas2, nCharKetas3 ) - && IsKinsokuHead( pWork->cLineStr.At( pWork->nPos + ( bLowSurrogate ? 2 : 1 ) ) ) + if( _IsKinsokuPosHead( GetMaxLineLayout() - pWork->nPosX, nCharKetas1, nCharKetas2 ) + && IsKinsokuHead( pWork->cLineStr.At( pWork->nPos + nCharSize ) ) && !IsKinsokuHead( pWork->cLineStr.At( pWork->nPos ) ) // 1字前が行頭禁則の対象でないこと && !IsKinsokuKuto( pWork->cLineStr.At( pWork->nPos ) ) ) // 1字前が句読点ぶら下げの対象でないこと { pWork->nWordBgn = pWork->nPos; - pWork->nWordLen = ( bLowSurrogate ? 3 : 2 ); + pWork->nWordLen = nCharSize + CNativeW::GetSizeOfChar( pWork->cLineStr, pWork->nPos + nCharSize ); pWork->eKinsokuType = KINSOKU_TYPE_KINSOKU_HEAD; (this->*pfOnLine)(pWork); @@ -236,13 +230,14 @@ void CLayoutMgr::_DoGyomatsuKinsoku(SLayoutWork* pWork, PF_OnLine pfOnLine) && ( pWork->nPosX > pWork->nIndent ) // 2004.04.09 pWork->nPosXの解釈変更のため,行頭チェックも変更 && (pWork->eKinsokuType == KINSOKU_TYPE_NONE) ) { - CLayoutInt nCharKetas2 = GetLayoutXOfChar( pWork->cLineStr, pWork->nPos ); - CLayoutInt nCharKetas3 = GetLayoutXOfChar( pWork->cLineStr, pWork->nPos+1 ); + CLogicXInt nCharSize = CNativeW::GetSizeOfChar( pWork->cLineStr, pWork->nPos ); + CLayoutXInt nCharKetas1 = GetLayoutXOfChar( pWork->cLineStr, pWork->nPos ); + CLayoutXInt nCharKetas2 = GetLayoutXOfChar( pWork->cLineStr, pWork->nPos + nCharSize ); - if( _IsKinsokuPosTail( GetMaxLineLayout() - pWork->nPosX, nCharKetas2, nCharKetas3 ) && IsKinsokuTail( pWork->cLineStr.At( pWork->nPos ) ) ) + if( _IsKinsokuPosTail( GetMaxLineLayout() - pWork->nPosX, nCharKetas1, nCharKetas2 ) && IsKinsokuTail( pWork->cLineStr.At( pWork->nPos ) ) ) { pWork->nWordBgn = pWork->nPos; - pWork->nWordLen = 1; + pWork->nWordLen = nCharSize; pWork->eKinsokuType = KINSOKU_TYPE_KINSOKU_TAIL; (this->*pfOnLine)(pWork); @@ -260,7 +255,7 @@ bool CLayoutMgr::_DoTab(SLayoutWork* pWork, PF_OnLine pfOnLine) return true; } pWork->nPosX += nCharKetas; - pWork->nPos += CLogicInt(1); + pWork->nPos += CNativeW::GetSizeOfChar( pWork->cLineStr, pWork->nPos ); return false; } @@ -336,7 +331,7 @@ void CLayoutMgr::_MakeOneLine(SLayoutWork* pWork, PF_OnLine pfOnLine) } } } - pWork->nPos += 1; + pWork->nPos += CNativeW::GetSizeOfChar( pWork->cLineStr, pWork->nPos ); pWork->nPosX += nCharKetas; } } From fe56cedaa6e8e9653e57a0257eb0c3c25a1a8f1f Mon Sep 17 00:00:00 2001 From: Kohki Akikaze <67105596+kazasaku@users.noreply.github.com> Date: Wed, 28 Apr 2021 00:12:43 +0900 Subject: [PATCH 3/4] =?UTF-8?q?=E3=82=B5=E3=83=AD=E3=82=B2=E3=83=BC?= =?UTF-8?q?=E3=83=88=E3=83=9A=E3=82=A2=E5=AF=BE=E7=AD=96=E3=81=A8=E3=81=97?= =?UTF-8?q?=E3=81=A6=E3=82=B3=E3=83=A1=E3=83=B3=E3=83=88=E3=82=A2=E3=82=A6?= =?UTF-8?q?=E3=83=88=E3=81=97=E3=81=9F=E3=82=B3=E3=83=BC=E3=83=89=E3=82=92?= =?UTF-8?q?=E5=89=8A=E9=99=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sakura_core/doc/layout/CLayoutMgr.cpp | 4 ---- sakura_core/doc/layout/CLayoutMgr_DoLayout.cpp | 4 ---- sakura_core/mem/CMemoryIterator.h | 2 -- 3 files changed, 10 deletions(-) diff --git a/sakura_core/doc/layout/CLayoutMgr.cpp b/sakura_core/doc/layout/CLayoutMgr.cpp index fcbc59c600..dc09c52a1e 100644 --- a/sakura_core/doc/layout/CLayoutMgr.cpp +++ b/sakura_core/doc/layout/CLayoutMgr.cpp @@ -873,8 +873,6 @@ void CLayoutMgr::LogicToLayout( else{ nCharKetas = GetLayoutXOfChar( pData, nDataLen, i ); } -// if( nCharKetas == 0 ) // 削除 サロゲートペア対策 2008/7/5 Uchi -// nCharKetas = CLayoutInt(1); //レイアウト加算 nCaretPosX += nCharKetas; @@ -1007,8 +1005,6 @@ checkloop:; else{ nCharKetas = GetLayoutXOfChar( pData, nDataLen, i ); } -// if( nCharKetas == 0 ) // 削除 サロゲートペア対策 2008/7/5 Uchi -// nCharKetas = CLayoutInt(1); //レイアウト加算 if( nX + nCharKetas > ptLayout.GetX2() && !bEOF ){ diff --git a/sakura_core/doc/layout/CLayoutMgr_DoLayout.cpp b/sakura_core/doc/layout/CLayoutMgr_DoLayout.cpp index 16b87369b7..10973b8f5d 100644 --- a/sakura_core/doc/layout/CLayoutMgr_DoLayout.cpp +++ b/sakura_core/doc/layout/CLayoutMgr_DoLayout.cpp @@ -51,7 +51,6 @@ static bool _GetKeywordLength( while(nPoscLineStr, pWork->nPos ); -// if( 0 == nCharKetas ){ // 削除 サロゲートペア対策 2008/7/5 Uchi -// nCharKetas = CLayoutInt(1); -// } if( pWork->nPosX + nCharKetas > GetMaxLineLayout() ){ if( pWork->eKinsokuType != KINSOKU_TYPE_KINSOKU_KUTO ) diff --git a/sakura_core/mem/CMemoryIterator.h b/sakura_core/mem/CMemoryIterator.h index 6f41e873a9..ef985b32b7 100644 --- a/sakura_core/mem/CMemoryIterator.h +++ b/sakura_core/mem/CMemoryIterator.h @@ -110,8 +110,6 @@ class CMemoryIterator if( m_nSpacing ){ m_nColumn_Delta += CLayoutXInt(CNativeW::GetKetaOfChar(m_pLine, m_nLineLen, m_nIndex) * m_nSpacing); } -// if( 0 == m_nColumn_Delta ) // 削除 サロゲートペア対策 2008/7/5 Uchi -// m_nColumn_Delta = CLayoutInt(1); } } From bf6a3aff9429e1ed01247d5bb005889e846f5084 Mon Sep 17 00:00:00 2001 From: Kohki Akikaze <67105596+kazasaku@users.noreply.github.com> Date: Tue, 4 May 2021 20:06:52 +0900 Subject: [PATCH 4/4] =?UTF-8?q?CNativeW::GetSizeOfChar=20=E5=8F=8A?= =?UTF-8?q?=E3=81=B3=20CNativeW::GetKetaOfChar=20=E3=81=AE=E3=82=AA?= =?UTF-8?q?=E3=83=BC=E3=83=90=E3=83=BC=E3=83=AD=E3=83=BC=E3=83=89=E3=81=AB?= =?UTF-8?q?=E5=AF=BE=E3=81=99=E3=82=8B=E3=83=86=E3=82=B9=E3=83=88=E3=81=AE?= =?UTF-8?q?=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sakura_core/mem/CNativeW.h | 4 ++-- tests/unittests/test-cnative.cpp | 16 +++++++++++++++- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/sakura_core/mem/CNativeW.h b/sakura_core/mem/CNativeW.h index ed82ed2d08..a3b2ee3cc5 100644 --- a/sakura_core/mem/CNativeW.h +++ b/sakura_core/mem/CNativeW.h @@ -160,8 +160,8 @@ class CNativeW final : public CNative{ //! 指定した位置の文字が半角何個分かを返す static CKetaXInt GetKetaOfChar( const wchar_t* pData, int nDataLen, int nIdx, CCharWidthCache& cache = GetCharWidthCache() ); - static CKetaXInt GetKetaOfChar( const CStringRef& cStr, int nIdx ) - { return GetKetaOfChar( cStr.GetPtr(), cStr.GetLength(), nIdx ); } + static CKetaXInt GetKetaOfChar(const CStringRef& cStr, int nIdx, CCharWidthCache& cache = GetCharWidthCache()) + { return GetKetaOfChar(cStr.GetPtr(), cStr.GetLength(), nIdx, cache); } static const wchar_t* GetCharNext( const wchar_t* pData, int nDataLen, const wchar_t* pDataCurrent ); //!< ポインタで示した文字の次にある文字の位置を返します static const wchar_t* GetCharPrev(const wchar_t* pData, size_t nDataLen, const wchar_t* pDataCurrent); //!< ポインタで示した文字の直前にある文字の位置を返します diff --git a/tests/unittests/test-cnative.cpp b/tests/unittests/test-cnative.cpp index 5982fc2ff5..6a795fd4f2 100644 --- a/tests/unittests/test-cnative.cpp +++ b/tests/unittests/test-cnative.cpp @@ -788,12 +788,16 @@ TEST(CNativeW, GetSizeOfChar) { // 基本多言語面の文字ならば1を返す。 EXPECT_EQ(CNativeW::GetSizeOfChar(L"a", 1, 0), 1); + EXPECT_EQ(CNativeW::GetSizeOfChar(CStringRef(L"a", 1), 0), 1); // 範囲外なら0を返す。 EXPECT_EQ(CNativeW::GetSizeOfChar(L"", 0, 0), 0); + EXPECT_EQ(CNativeW::GetSizeOfChar(CStringRef(L"", 0), 0), 0); // 上位・下位サロゲートの組み合わせであれば2を返す。 EXPECT_EQ(CNativeW::GetSizeOfChar(L"\xd83c\xdf38", 2, 0), 2); + EXPECT_EQ(CNativeW::GetSizeOfChar(CStringRef(L"\xd83c\xdf38", 2), 0), 2); // 指定位置が下位サロゲートならその他の文字と同様に1を返す。 EXPECT_EQ(CNativeW::GetSizeOfChar(L"\xd83c\xdf38", 2, 1), 1); + EXPECT_EQ(CNativeW::GetSizeOfChar(CStringRef(L"\xd83c\xdf38", 2), 1), 1); } /*! @@ -804,12 +808,16 @@ TEST(CNativeW, GetKetaOfChar) { // 範囲外なら0を返す。 EXPECT_EQ(CNativeW::GetKetaOfChar(L"", 0, 0), 0); + EXPECT_EQ(CNativeW::GetKetaOfChar(CStringRef(L"", 0), 0), 0); // 上位サロゲートなら2を返す。 EXPECT_EQ(CNativeW::GetKetaOfChar(L"\xd83c\xdf38", 2, 0), 2); + EXPECT_EQ(CNativeW::GetKetaOfChar(CStringRef(L"\xd83c\xdf38", 2), 0), 2); // 上位サロゲートに続く下位サロゲートであれば0を返す。 EXPECT_EQ(CNativeW::GetKetaOfChar(L"\xd83c\xdf38", 2, 1), 0); + EXPECT_EQ(CNativeW::GetKetaOfChar(CStringRef(L"\xd83c\xdf38", 2), 1), 0); // 下位サロゲートだけなら2を返す。 EXPECT_EQ(CNativeW::GetKetaOfChar(L"\xdf38", 1, 0), 2); + EXPECT_EQ(CNativeW::GetKetaOfChar(CStringRef(L"\xdf38", 1), 0), 2); // サクラエディタでは Unicode で表現できない文字コードの破壊を防ぐため、 // 不明バイトを下位サロゲートにマップして保持している。 @@ -819,12 +827,17 @@ TEST(CNativeW, GetKetaOfChar) // https://sourceforge.net/p/sakura-editor/patchunicode/57/ // http://sakura-editor.sourceforge.net/cgi-bin/cyclamen/cyclamen.cgi?log=unicode&v=833 EXPECT_EQ(CNativeW::GetKetaOfChar(L"\xdbff", 1, 0), 2); - for (wchar_t ch = 0xdc00; ch <= 0xdcff; ++ch) + EXPECT_EQ(CNativeW::GetKetaOfChar(CStringRef(L"\xdbff", 1), 0), 2); + for (wchar_t ch = 0xdc00; ch <= 0xdcff; ++ch) { EXPECT_EQ(CNativeW::GetKetaOfChar(&ch, 1, 0), 1); + EXPECT_EQ(CNativeW::GetKetaOfChar(CStringRef(&ch, 1), 0), 1); + } EXPECT_EQ(CNativeW::GetKetaOfChar(L"\xdd00", 1, 0), 2); + EXPECT_EQ(CNativeW::GetKetaOfChar(CStringRef(L"\xdd00", 1), 0), 2); // 文字が半角なら1を返す。 EXPECT_EQ(CNativeW::GetKetaOfChar(L"a", 1, 0), 1); + EXPECT_EQ(CNativeW::GetKetaOfChar(CStringRef(L"a", 1), 0), 1); // 文字が全角なら2を返す。 class FakeCache : public CCharWidthCache { @@ -832,6 +845,7 @@ TEST(CNativeW, GetKetaOfChar) bool CalcHankakuByFont(wchar_t c) override { return false; } } cache; EXPECT_EQ(CNativeW::GetKetaOfChar(L"あ", 1, 0, cache), 2); + EXPECT_EQ(CNativeW::GetKetaOfChar(CStringRef(L"あ", 1), 0, cache), 2); } /*!