diff options
author | Jonathan Clark <jonathan@libreoffice.org> | 2024-09-04 03:16:06 -0600 |
---|---|---|
committer | Xisco Fauli <xiscofauli@libreoffice.org> | 2024-09-05 09:03:11 +0200 |
commit | ac40f72c97703979994ac9d54ce861269653950e (patch) | |
tree | 794305fd697af9769337eb4a76a94107748bcce3 /editeng | |
parent | a2eb29995f8f4ba91496242ed7b98237f6c0e763 (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.cxx | 64 | ||||
-rw-r--r-- | editeng/source/editeng/impedit3.cxx | 2 |
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); |