[Libreoffice-commits] core.git: sw/qa sw/source

Mark Hung marklh9 at gmail.com
Sat Jan 13 11:08:07 UTC 2018


 sw/qa/extras/uiwriter/data/tdf113481-IVS.odt |binary
 sw/qa/extras/uiwriter/uiwriter.cxx           |   33 +++++++++++++++++++++
 sw/source/uibase/wrtsh/delete.cxx            |   42 +++++++++++++++++++++++++++
 3 files changed, 75 insertions(+)

New commits:
commit 8c7915eb9693f7c385308ec2b76b1d5b582bceed
Author: Mark Hung <marklh9 at gmail.com>
Date:   Thu Nov 9 23:53:19 2017 +0800

    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 at libreoffice.org>
    Reviewed-by: Mark Hung <marklh9 at gmail.com>

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
Binary files /dev/null and b/sw/qa/extras/uiwriter/data/tdf113481-IVS.odt 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 )


More information about the Libreoffice-commits mailing list