summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Hung <marklh9@gmail.com>2017-11-09 23:53:19 +0800
committerMark Hung <marklh9@gmail.com>2018-01-13 12:07:29 +0100
commit8c7915eb9693f7c385308ec2b76b1d5b582bceed (patch)
tree8853ac716ddcb494fe987ba82c299cfdbc1a54b2
parent085852e2e2779de1712cf18b5e67740cb7a4bcb6 (diff)
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/44555 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Mark Hung <marklh9@gmail.com>
-rw-r--r--sw/qa/extras/uiwriter/data/tdf113481-IVS.odtbin0 -> 9571 bytes
-rw-r--r--sw/qa/extras/uiwriter/uiwriter.cxx33
-rw-r--r--sw/source/uibase/wrtsh/delete.cxx42
3 files changed, 75 insertions, 0 deletions
diff --git a/sw/qa/extras/uiwriter/data/tdf113481-IVS.odt b/sw/qa/extras/uiwriter/data/tdf113481-IVS.odt
new file mode 100644
index 000000000000..1d4a13929d37
--- /dev/null
+++ b/sw/qa/extras/uiwriter/data/tdf113481-IVS.odt
Binary files differ
diff --git a/sw/qa/extras/uiwriter/uiwriter.cxx b/sw/qa/extras/uiwriter/uiwriter.cxx
index e8bc2ea51aae..7319c80a6835 100644
--- a/sw/qa/extras/uiwriter/uiwriter.cxx
+++ b/sw/qa/extras/uiwriter/uiwriter.cxx
@@ -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();
diff --git a/sw/source/uibase/wrtsh/delete.cxx b/sw/source/uibase/wrtsh/delete.cxx
index 6c2a7d04d272..2f0be3984c85 100644
--- a/sw/source/uibase/wrtsh/delete.cxx
+++ b/sw/source/uibase/wrtsh/delete.cxx
@@ -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 )