sw/qa/core/uwriter.cxx            |   15 +++++++++++++++
 sw/source/core/inc/scriptinfo.hxx |    6 +++++-
 sw/source/core/text/porlay.cxx    |    2 +-
 3 files changed, 21 insertions(+), 2 deletions(-)

New commits:
commit dda85e275d70d6365009042b8e207337f2e712c2
Author:     Jonathan Clark <jonat...@libreoffice.org>
AuthorDate: Tue Aug 13 12:32:18 2024 -0600
Commit:     Jonathan Clark <jonat...@libreoffice.org>
CommitDate: Thu Aug 15 00:31:07 2024 +0200

    tdf#156211 sw: Fix spurious kashida inserted after undo
    
    This change fixes an issue presenting as incorrectly-positioned kashida
    glyphs overlapping Arabic text after certain edit operations.
    
    During layout with kashida justification, Writer builds a table of lines
    that require fallback to whitespace justification. Normally, this table
    is built sequentially from the first line, but it may be updated
    out-of-order following certain edit operations.
    
    Due to an off-by-one error, if Writer cleared the exclusion for a line
    immediately before a legitimately-excluded line, Writer would also clear
    the legitimate exclusion. In such a situation, portions of excluded text
    would be redrawn with kashida justification, and because that text
    usually does not have enough free space, the kashida glyphs would be
    drawn on top of the base text.
    
    Change-Id: I204661286531fa6064f7a6adc35f1606e35e5d39
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/171878
    Tested-by: Jenkins
    Reviewed-by: Jonathan Clark <jonat...@libreoffice.org>

diff --git a/sw/qa/core/uwriter.cxx b/sw/qa/core/uwriter.cxx
index 63f417464be6..861b8b3d272e 100644
--- a/sw/qa/core/uwriter.cxx
+++ b/sw/qa/core/uwriter.cxx
@@ -71,6 +71,7 @@
 #include <calbck.hxx>
 #include <pagedesc.hxx>
 #include <calc.hxx>
+#include <scriptinfo.hxx>
 
 #include <tblafmt.hxx>
 #include <unotbl.hxx>
@@ -128,6 +129,7 @@ public:
     void test64kPageDescs();
     void testTdf92308();
     void testTableCellComparison();
+    void testTdf156211();
 
     CPPUNIT_TEST_SUITE(SwDocTest);
 
@@ -165,6 +167,7 @@ public:
     CPPUNIT_TEST(test64kPageDescs);
     CPPUNIT_TEST(testTdf92308);
     CPPUNIT_TEST(testTableCellComparison);
+    CPPUNIT_TEST(testTdf156211);
     CPPUNIT_TEST_SUITE_END();
 
 private:
@@ -1966,6 +1969,18 @@ void SwDocTest::tearDown()
     BootstrapFixture::tearDown();
 }
 
+void SwDocTest::testTdf156211()
+{
+    SwScriptInfo oSI;
+    oSI.SetNoKashidaLine(TextFrameIndex{ 89 }, TextFrameIndex{ 95 });
+
+    CPPUNIT_ASSERT(!oSI.IsKashidaLine(TextFrameIndex{ 95 }));
+
+    oSI.ClearNoKashidaLine(TextFrameIndex{ 0 }, TextFrameIndex{ 89 });
+
+    CPPUNIT_ASSERT(!oSI.IsKashidaLine(TextFrameIndex{ 95 }));
+}
+
 CPPUNIT_TEST_SUITE_REGISTRATION(SwDocTest);
 
 CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/sw/source/core/inc/scriptinfo.hxx 
b/sw/source/core/inc/scriptinfo.hxx
index 5abe7157c14b..4f6933c520d4 100644
--- a/sw/source/core/inc/scriptinfo.hxx
+++ b/sw/source/core/inc/scriptinfo.hxx
@@ -96,7 +96,6 @@ private:
     void ClearKashidaInvalid(size_t nKashPos);
     bool MarkOrClearKashidaInvalid(TextFrameIndex nStt, TextFrameIndex nLen,
             bool bMark, sal_Int32 nMarkCount);
-    bool IsKashidaLine(TextFrameIndex nCharIdx) const;
     // examines the range [ nStart, nStart + nEnd ] if there are kanas
     // returns start index of kana entry in array, otherwise SAL_MAX_SIZE
     size_t HasKana(TextFrameIndex nStart, TextFrameIndex nEnd) const;
@@ -335,6 +334,11 @@ public:
 */
     void ClearNoKashidaLine(TextFrameIndex nStt, TextFrameIndex nLen);
 
+/** Checks whether the character is on a line excluded from kashida 
justification.
+   nCharIdx Char index within the paragraph.
+*/
+    bool IsKashidaLine(TextFrameIndex nCharIdx) const;
+
 /** Checks if text is Arabic text.
 
      @descr  Checks if text is Arabic text.
diff --git a/sw/source/core/text/porlay.cxx b/sw/source/core/text/porlay.cxx
index 730be567d39b..0e7f7b8a4634 100644
--- a/sw/source/core/text/porlay.cxx
+++ b/sw/source/core/text/porlay.cxx
@@ -2591,7 +2591,7 @@ void SwScriptInfo::ClearNoKashidaLine(TextFrameIndex 
const nStt, TextFrameIndex
     size_t i = 0;
     while (i < m_NoKashidaLine.size())
     {
-        if (nStt + nLen >= m_NoKashidaLine[i] && nStt < m_NoKashidaLineEnd[i])
+        if (nStt + nLen > m_NoKashidaLine[i] && nStt < m_NoKashidaLineEnd[i])
         {
             m_NoKashidaLine.erase(m_NoKashidaLine.begin() + i);
             m_NoKashidaLineEnd.erase(m_NoKashidaLineEnd.begin() + i);

Reply via email to