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);