summaryrefslogtreecommitdiff
path: root/editeng
diff options
context:
space:
mode:
authorJonathan Clark <jonathan@libreoffice.org>2024-09-04 03:16:06 -0600
committerXisco Fauli <xiscofauli@libreoffice.org>2024-09-05 09:03:11 +0200
commitac40f72c97703979994ac9d54ce861269653950e (patch)
tree794305fd697af9769337eb4a76a94107748bcce3 /editeng
parenta2eb29995f8f4ba91496242ed7b98237f6c0e763 (diff)
tdf#151748 editeng: Fix crash in kashida justification after update
Commit 937023bca427f803a9e7085d5090d5d2b17623ed aggravated a bug that would cause editeng to use stale kashida positions after document changes (for example, font changes). This could cause crashes or spurious kashida, and both much more often after the above commit. This change fixes the underlying logic error. Change-Id: Id6465e739740a38ed11c9d9378d30faa51948731 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/172866 Reviewed-by: Jonathan Clark <jonathan@libreoffice.org> Tested-by: Jenkins (cherry picked from commit 7ff601feca1796b6656e66c7ce2e77edcf0bdd67) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/172885 Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org>
Diffstat (limited to 'editeng')
-rw-r--r--editeng/qa/unit/core-test.cxx64
-rw-r--r--editeng/source/editeng/impedit3.cxx2
2 files changed, 66 insertions, 0 deletions
diff --git a/editeng/qa/unit/core-test.cxx b/editeng/qa/unit/core-test.cxx
index e40d5f0bf4c9..75e19df6028d 100644
--- a/editeng/qa/unit/core-test.cxx
+++ b/editeng/qa/unit/core-test.cxx
@@ -18,6 +18,7 @@
#include <sfx2/app.hxx>
#include <svl/itempool.hxx>
+#include <editeng/adjustitem.hxx>
#include <editeng/editeng.hxx>
#include <editeng/eeitem.hxx>
#include <editeng/lspcitem.hxx>
@@ -123,6 +124,7 @@ public:
void testMoveParagraph();
void testCreateLines();
void testTdf154248MultilineFieldWrapping();
+ void testTdf151748StaleKashidaArray();
DECL_STATIC_LINK( Test, CalcFieldValueHdl, EditFieldInfo*, void );
@@ -154,6 +156,7 @@ public:
CPPUNIT_TEST(testMoveParagraph);
CPPUNIT_TEST(testCreateLines);
CPPUNIT_TEST(testTdf154248MultilineFieldWrapping);
+ CPPUNIT_TEST(testTdf151748StaleKashidaArray);
CPPUNIT_TEST_SUITE_END();
private:
@@ -2293,6 +2296,67 @@ void Test::testTdf154248MultilineFieldWrapping()
}
}
+void Test::testTdf151748StaleKashidaArray()
+{
+ ScopedVclPtrInstance<VirtualDevice> pVirtualDevice(DeviceFormat::WITHOUT_ALPHA);
+
+ EditEngine aEditEngine(mpItemPool.get());
+ aEditEngine.SetRefDevice(pVirtualDevice.get());
+ aEditEngine.SetPaperSize(Size(1500, 500));
+ aEditEngine.SetDefaultHorizontalTextDirection(EEHorizontalTextDirection::R2L);
+ aEditEngine.SetText(u"خط تخوردگی و توسط"_ustr);
+
+ CPPUNIT_ASSERT_EQUAL(true, aEditEngine.IsFormatted());
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(1), aEditEngine.GetParagraphCount());
+
+ SfxItemSet aSet{ aEditEngine.GetParaAttribs(0) };
+ aSet.Put(SvxAdjustItem{ SvxAdjust::Block, EE_PARA_JUST });
+ aEditEngine.SetParaAttribs(0, aSet);
+
+ CPPUNIT_ASSERT_EQUAL(SvxAdjust::Block, aEditEngine.GetParaAttrib(0, EE_PARA_JUST).GetAdjust());
+ CPPUNIT_ASSERT_EQUAL(true, aEditEngine.IsFormatted());
+
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(2), aEditEngine.GetLineCount(0));
+
+ // Initial state: Check that a kashida array has been created
+ {
+ ParaPortionList& rParagraphPortionList = aEditEngine.GetParaPortions();
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(1), rParagraphPortionList.Count());
+
+ EditLineList& rLines = rParagraphPortionList.getRef(0).GetLines();
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(2), rLines.Count());
+ EditLine const& rLine = rLines[0];
+
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(0), rLine.GetStart());
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(11), rLine.GetEnd());
+
+ std::vector<sal_Bool> const& rArray = rLine.GetKashidaArray();
+ CPPUNIT_ASSERT_EQUAL(size_t(17), rArray.size());
+ }
+
+ // Resize the paper so there is no longer room for kashida
+ aEditEngine.SetPaperSize(Size(1400, 500));
+
+ // Follow-up state: Check that the kashida array has been cleared
+ {
+ ParaPortionList& rParagraphPortionList = aEditEngine.GetParaPortions();
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(1), rParagraphPortionList.Count());
+
+ EditLineList& rLines = rParagraphPortionList.getRef(0).GetLines();
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(2), rLines.Count());
+ EditLine const& rLine = rLines[0];
+
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(0), rLine.GetStart());
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(11), rLine.GetEnd());
+
+ std::vector<sal_Bool> const& rArray = rLine.GetKashidaArray();
+
+ // Since there is no room for kashida, the kashida array should be empty.
+ // Without the bug fix, this will be 17:
+ CPPUNIT_ASSERT_EQUAL(size_t(0), rArray.size());
+ }
+}
+
CPPUNIT_TEST_SUITE_REGISTRATION(Test);
}
diff --git a/editeng/source/editeng/impedit3.cxx b/editeng/source/editeng/impedit3.cxx
index 8d6abb99920b..408964373c48 100644
--- a/editeng/source/editeng/impedit3.cxx
+++ b/editeng/source/editeng/impedit3.cxx
@@ -2367,6 +2367,8 @@ void ImpEditEngine::ImpAdjustBlocks(ParaPortion& rParaPortion, EditLine& rLine,
// Mark Kashida positions, so that VCL knows where to insert Kashida and
// where to only expand the width.
+ // The underlying array may be reused across updates. Ensure there is no stale data.
+ rLine.GetKashidaArray().clear();
if (nKashidas)
{
rLine.GetKashidaArray().resize(rLine.GetCharPosArray().size(), false);