editeng/qa/editeng/editeng.cxx      |   22 ++++++++++++++++++++++
 editeng/source/editeng/impedit4.cxx |    6 ++++++
 2 files changed, 28 insertions(+)

New commits:
commit c28307fa99dae0322a3dca7ce0010d87c93ec85a
Author:     Jonathan Clark <jonat...@libreoffice.org>
AuthorDate: Tue Jun 17 04:06:49 2025 -0600
Commit:     Jonathan Clark <jonat...@libreoffice.org>
CommitDate: Tue Jun 17 23:59:39 2025 +0200

    tdf#119192 editeng: Fix for copy-and-paste using font from wrong script
    
    To minimize the size of the output RTF, Edit Engine only emits font
    attributes when either the font changes or when the script type changes.
    
    In the latter case, Edit Engine was previously writing font attributes
    inside a child scope, rather than the paragraph scope. Font changes
    related to a language change would thus apply only to the first run of
    characters in that language, while following runs would appear to use an
    arbitrary language.
    
    Change-Id: Iff38299bffaf3045cef5c6e71b8cab441ba0be39
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/186612
    Reviewed-by: Jonathan Clark <jonat...@libreoffice.org>
    Tested-by: Jenkins

diff --git a/editeng/qa/editeng/editeng.cxx b/editeng/qa/editeng/editeng.cxx
index f3df37592f14..6c5e9e29596c 100644
--- a/editeng/qa/editeng/editeng.cxx
+++ b/editeng/qa/editeng/editeng.cxx
@@ -190,6 +190,28 @@ CPPUNIT_TEST_FIXTURE(Test, 
testRTFStyleExportFollowRecursive)
     SvMemoryStream& rStream = pData->GetRTFStream();
     CPPUNIT_ASSERT_GREATER(static_cast<sal_uInt64>(0), 
rStream.remainingSize());
 }
+
+CPPUNIT_TEST_FIXTURE(Test, testTdf119192)
+{
+    // Tests that font changes due to a script type change are placed in 
paragraph scope
+    EditEngine aEditEngine(mpItemPool.get());
+
+    OUString aText = u"mytest"_ustr;
+    aEditEngine.SetText(aText);
+
+    uno::Reference<datatransfer::XTransferable> xData
+        = aEditEngine.CreateTransferable(ESelection(0, 0, 0, 
aText.getLength()));
+
+    auto pData = dynamic_cast<EditDataObject*>(xData.get());
+    SvMemoryStream& rStream = pData->GetRTFStream();
+
+    std::string aCnt{ static_cast<const char*>(rStream.GetData()),
+                      static_cast<size_t>(rStream.GetSize()) };
+
+    // Without the fix, the RTF text will include font attributes inside the 
curly braces.
+    bool bContains = (aCnt.find("{mytest}") != std::string::npos);
+    CPPUNIT_ASSERT(bContains);
+}
 }
 
 CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/editeng/source/editeng/impedit4.cxx 
b/editeng/source/editeng/impedit4.cxx
index c8ae50031c19..a3a349f04243 100644
--- a/editeng/source/editeng/impedit4.cxx
+++ b/editeng/source/editeng/impedit4.cxx
@@ -716,6 +716,12 @@ ErrCode ImpEditEngine::WriteRTF( SvStream& rOutput, 
EditSelection aSel, bool bCl
                     aAttribItems.Insert( &aAttribs.Get( GetScriptItemId( 
EE_CHAR_WEIGHT, nScriptType ) ) );
                     aAttribItems.Insert( &aAttribs.Get( GetScriptItemId( 
EE_CHAR_ITALIC, nScriptType ) ) );
                     aAttribItems.Insert( &aAttribs.Get( GetScriptItemId( 
EE_CHAR_LANGUAGE, nScriptType ) ) );
+
+                    // tdf#119192: Write these font attributes at paragraph 
scope, so they can be
+                    // reused across multiple runs.
+                    WriteItemListAsRTF(aAttribItems, rOutput, nNode, nIndex, 
aFontTable,
+                                       aColorList);
+                    aAttribItems.Clear();
                 }
                 // Insert hard attribs AFTER CJK attribs...
                 lcl_FindValidAttribs( aAttribItems, pNode, nIndex, 
nScriptTypeI18N );

Reply via email to