editeng/qa/unit/core-test.cxx       |   65 ++++++++++++++++++++++++++++++++++++
 editeng/source/editeng/impedit3.cxx |    3 +
 sc/source/core/tool/addincol.cxx    |   16 +++++++-
 3 files changed, 82 insertions(+), 2 deletions(-)

New commits:
commit beda01bf3a7f805aa3f90c51cad5732b0cb1cce0
Author:     Eike Rathke <[email protected]>
AuthorDate: Mon Sep 2 11:35:21 2024 +0200
Commit:     Xisco Fauli <[email protected]>
CommitDate: Wed Sep 11 17:23:41 2024 +0200

    Add-In CompatibilityName: for "en-US" try the most likely fallback of "en"
    
    As this needs to be resolved for every occurrence of the function
    name during export to OOXML and .xls and Add-In authors tend to be
    lax with en-US vs en-GB, also because function names usually don't
    differ, and use "en" at least in DisplayName.
    
    Change-Id: If0b1b60c4806028c76296e5feaa74e7ddb307bb6
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/172735
    Tested-by: Jenkins
    Reviewed-by: Eike Rathke <[email protected]>
    (cherry picked from commit 79ed97b93be2711bab5530d8ddc18e318be644d9)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/172757
    Reviewed-by: Xisco Fauli <[email protected]>

diff --git a/sc/source/core/tool/addincol.cxx b/sc/source/core/tool/addincol.cxx
index e84a02802c01..ec1c53b22bf2 100644
--- a/sc/source/core/tool/addincol.cxx
+++ b/sc/source/core/tool/addincol.cxx
@@ -170,7 +170,19 @@ bool ScUnoAddInFuncData::GetExcelName( const LanguageTag& 
rDestLang, OUString& r
             return true;
         }
 
-        // Second, try match of fallback search with fallback locales,
+        // For "en-US" try the most likely fallback of "en".
+        if (aSearch == "en-US")
+        {
+            itNames = std::find_if(rCompNames.begin(), rCompNames.end(),
+                    [](const LocalizedName& rName) { return rName.maLocale == 
"en"; });
+            if (itNames != rCompNames.end())
+            {
+                rRetExcelName = (*itNames).maName;
+                return true;
+            }
+        }
+
+        // Try match of fallback search with fallback locales,
         // appending also 'en-US' and 'en' to search if not queried.
         ::std::vector< OUString > aFallbackSearch( 
rDestLang.getFallbackStrings( true));
         if (aSearch != "en-US")
@@ -196,7 +208,7 @@ bool ScUnoAddInFuncData::GetExcelName( const LanguageTag& 
rDestLang, OUString& r
 
         if (bFallbackToAny)
         {
-            // Third, last resort, use first (default) entry.
+            // Last resort, use first (default) entry.
             rRetExcelName = rCompNames[0].maName;
             return true;
         }
commit 26fa1ac0d738d2c6de780545848abf10f823a9c0
Author:     Jonathan Clark <[email protected]>
AuthorDate: Fri Sep 6 04:00:26 2024 -0600
Commit:     Xisco Fauli <[email protected]>
CommitDate: Wed Sep 11 17:23:35 2024 +0200

    tdf#162803 editeng: Fix invalid kashida array after layout
    
    This change updates editeng to clear the kashida array during layout, at
    the same time it clears other justification data.
    
    Previously, editeng could recycle stale kashida arrays and apply them to
    lines with different lengths. This would result in stray kashida
    rendered at inappropriate positions in lines, or accessing memory past
    the end of the kashida array, resulting in assertions or
    nondeterministic crashes.
    
    Change-Id: I9c06239298d630f2d61b5e67a54f4c3e079c1193
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/172967
    Reviewed-by: Jonathan Clark <[email protected]>
    Tested-by: Jenkins
    (cherry picked from commit 6eb0523e27473fe2ebe281b2682a5045f3b39312)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/173088
    Reviewed-by: Xisco Fauli <[email protected]>

diff --git a/editeng/qa/unit/core-test.cxx b/editeng/qa/unit/core-test.cxx
index 75e19df6028d..3987dbe89a66 100644
--- a/editeng/qa/unit/core-test.cxx
+++ b/editeng/qa/unit/core-test.cxx
@@ -125,6 +125,7 @@ public:
     void testCreateLines();
     void testTdf154248MultilineFieldWrapping();
     void testTdf151748StaleKashidaArray();
+    void testTdf162803StaleKashidaArray();
 
     DECL_STATIC_LINK( Test, CalcFieldValueHdl, EditFieldInfo*, void );
 
@@ -157,6 +158,7 @@ public:
     CPPUNIT_TEST(testCreateLines);
     CPPUNIT_TEST(testTdf154248MultilineFieldWrapping);
     CPPUNIT_TEST(testTdf151748StaleKashidaArray);
+    CPPUNIT_TEST(testTdf162803StaleKashidaArray);
     CPPUNIT_TEST_SUITE_END();
 
 private:
@@ -2296,6 +2298,7 @@ void Test::testTdf154248MultilineFieldWrapping()
     }
 }
 
+// tdf#151748: Verify that editeng produces an empty kashida array if the line 
does not have room
 void Test::testTdf151748StaleKashidaArray()
 {
     ScopedVclPtrInstance<VirtualDevice> 
pVirtualDevice(DeviceFormat::WITHOUT_ALPHA);
@@ -2357,6 +2360,68 @@ void Test::testTdf151748StaleKashidaArray()
     }
 }
 
+// tdf#162803: Verify that editeng clears stale kashida data during layout
+void Test::testTdf162803StaleKashidaArray()
+{
+    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 the entire text fits on a single line
+    aEditEngine.SetPaperSize(Size(4000, 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(1), rLines.Count());
+        EditLine const& rLine = rLines[0];
+
+        CPPUNIT_ASSERT_EQUAL(sal_Int32(0), rLine.GetStart());
+        CPPUNIT_ASSERT_EQUAL(sal_Int32(17), 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 408964373c48..db3b63d6c99b 100644
--- a/editeng/source/editeng/impedit3.cxx
+++ b/editeng/source/editeng/impedit3.cxx
@@ -910,6 +910,9 @@ bool ImpEditEngine::CreateLines( sal_Int32 nPara, 
sal_uInt32 nStartPosY )
         // =>...
         pLine->GetCharPosArray().clear();
 
+        // tdf#162803: Stale kashida position data also needs to be cleared on 
each layout.
+        pLine->GetKashidaArray().clear();
+
         sal_Int32 nTmpPos = nIndex;
         sal_Int32 nTmpPortion = pLine->GetStartPortion();
         tools::Long nTmpWidth = 0;

Reply via email to