Kaydet (Commit) 8c7915eb authored tarafından Mark Hung's avatar Mark Hung

tdf#113481 Let backspace delete complete CJK ideograph IVS.

If the character to be deleted is in CJK script and
is a Unicode variance selector, delete the complete IVS
if the base character is a CJK unified ideograph.

Change-Id: I5d29664d5e964fc685110333f8109b0bfa8e0955
Reviewed-on: https://gerrit.libreoffice.org/44555Tested-by: 's avatarJenkins <ci@libreoffice.org>
Reviewed-by: 's avatarMark Hung <marklh9@gmail.com>
üst 085852e2
......@@ -292,6 +292,7 @@ public:
void testTdf113790();
void testTdf108048();
void testTdf114306();
void testTdf113481();
CPPUNIT_TEST_SUITE(SwUiWriterTest);
CPPUNIT_TEST(testReplaceForward);
......@@ -464,6 +465,7 @@ public:
CPPUNIT_TEST(testTdf113790);
CPPUNIT_TEST(testTdf108048);
CPPUNIT_TEST(testTdf114306);
CPPUNIT_TEST(testTdf113481);
CPPUNIT_TEST_SUITE_END();
private:
......@@ -5668,6 +5670,37 @@ void SwUiWriterTest::testTdf108048()
CPPUNIT_ASSERT_EQUAL(sal_uInt16(6), nPageNumber);
}
void SwUiWriterTest::testTdf113481()
{
SwDoc* pDoc = createDoc("tdf113481-IVS.odt");
SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
// One backspace should completely remove the CJK ideograph varation sequence
pWrtShell->EndPara();
// Before: U+8FBA U+E0102. After: empty
pWrtShell->DelLeft();
const uno::Reference< text::XTextRange > xPara1 = getParagraph(1);
CPPUNIT_ASSERT_EQUAL(sal_Int32(0), xPara1->getString().getLength());
// In case that weak script is treated as CJK script, remove one character.
pWrtShell->Down(false);
pWrtShell->EndPara();
// Before: U+4E2D U+2205 U+FE00. After: U+4E2D U+2205
pWrtShell->DelLeft();
const uno::Reference< text::XTextRange > xPara2 = getParagraph(2);
CPPUNIT_ASSERT_EQUAL(sal_Int32(2), xPara2->getString().getLength());
CPPUNIT_ASSERT_EQUAL(u'\x2205', xPara2->getString()[1]);
// Characters of other scripts, remove one character.
pWrtShell->Down(false);
pWrtShell->EndPara();
// Before: U+1820 U+180B. After: U+1820
pWrtShell->DelLeft();
const uno::Reference< text::XTextRange > xPara3 = getParagraph(3);
CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xPara3->getString().getLength());
CPPUNIT_ASSERT_EQUAL(u'\x1820', xPara3->getString()[0]);
}
CPPUNIT_TEST_SUITE_REGISTRATION(SwUiWriterTest);
CPPUNIT_PLUGIN_IMPLEMENT();
......
......@@ -42,6 +42,25 @@ inline void SwWrtShell::CloseMark( bool bOkFlag )
EndAllAction();
}
namespace {
inline bool isUnicodeVariationSequenceSelector( sal_uInt32 nCode )
{
return ( nCode >= 0xFE00 && nCode <= 0xFE0F ) // Variation Selectors block
|| ( nCode >= 0xE0100 && nCode <= 0xE01EF );// Variation Selectors Supplement block
}
// Return if the chracter might be a base character of a CJK ideographic varaiation sequence
inline bool isCJKIVSCharacters( sal_uInt32 nCode )
{
return ( nCode >= 0x4E00 && nCode <= 0x9FFF ) // CJK Unified Ideographs
|| ( nCode >= 0x3400 && nCode <= 0x4DBF ) // CJK Unified Ideographs Extension A
|| ( nCode >= 0x20000 && nCode <= 0x2A6DF ); // CJK Unified Ideographs Extension B
}
}
// #i23725#
bool SwWrtShell::TryRemoveIndent()
{
......@@ -222,6 +241,29 @@ long SwWrtShell::DelLeft()
OpenMark();
SwCursorShell::Left(1, CRSR_SKIP_CHARS);
if (SvtScriptType::ASIAN == GetScriptType())
{
sal_uInt32 nCode = GetChar(false);
if ( rtl::isSurrogate( nCode ) )
{
OUString sStr = GetSelText();
sal_Int32 nIndex = 0;
nCode = sStr.iterateCodePoints( &nIndex );
}
if ( isUnicodeVariationSequenceSelector( nCode ) )
{
SwCursorShell::Push();
SwCursorShell::Left(1, CRSR_SKIP_CHARS);
OUString sStr = GetSelText();
sal_Int32 nIndex = 0;
nCode = sStr.iterateCodePoints( &nIndex );
if ( isCJKIVSCharacters( nCode ) )
SwCursorShell::Pop( SwCursorShell::PopMode::DeleteStack );
else
SwCursorShell::Pop( SwCursorShell::PopMode::DeleteCurrent ); // For the weak script.
}
}
}
long nRet = Delete();
if( !nRet && bSwap )
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment