Rebased ref, commits from common ancestor:
commit 59b131fdba2042971826a7c29dcc2bb564728c82
Author:     Michael Stahl <[email protected]>
AuthorDate: Thu Feb 1 15:11:03 2024 +0100
Commit:     Thorsten Behrens <[email protected]>
CommitDate: Sat Feb 10 05:18:38 2024 +0100

    tdf#159015 sw: layout: fix infinite loop in ::CalcContent()
    
    SwObjectFormatter::FormatObj() will just return if IsAgain() is set, so
    the while loop here won't make any progress.
    
    (regression from commit 191babee4f0ec643b80e96b0cd98c2d04ff96e4e)
    
    Change-Id: I1c194b148760ae05cf4dee1d5729be28e87d6ba0
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/162880
    Tested-by: Jenkins
    Reviewed-by: Michael Stahl <[email protected]>
    (cherry picked from commit 13865c4da30a3a2a5ab8efbd568c47952d3ffcee)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/162895
    Reviewed-by: Caolán McNamara <[email protected]>

diff --git a/sw/source/core/layout/fly.cxx b/sw/source/core/layout/fly.cxx
index 503dfedb35fa..fd15d4d22cd0 100644
--- a/sw/source/core/layout/fly.cxx
+++ b/sw/source/core/layout/fly.cxx
@@ -43,6 +43,7 @@
 #include <svx/svdoashp.hxx>
 #include <svx/svdpage.hxx>
 #include <layouter.hxx>
+#include <layact.hxx>
 #include <pagefrm.hxx>
 #include <rootfrm.hxx>
 #include <viewimp.hxx>
@@ -1743,6 +1744,10 @@ void CalcContent( SwLayoutFrame *pLay, bool bNoColl )
                         if (!SwObjectFormatter::FormatObj(*pAnchoredObj, 
pAnchorFrame, pAnchorPageFrame,
                                 rShell.Imp()->IsAction() ? 
&rShell.Imp()->GetLayAction() : nullptr))
                         {
+                            if (rShell.Imp()->IsAction() && 
rShell.Imp()->GetLayAction().IsAgain())
+                            {   // tdf#159015 will always fail, don't loop
+                                return;
+                            }
                             bRestartLayoutProcess = true;
                             break;
                         }
commit 2060fbdadd6277f5edb9d09f6eb41735c5079977
Author:     Michael Stahl <[email protected]>
AuthorDate: Thu Feb 1 12:53:07 2024 +0100
Commit:     Thorsten Behrens <[email protected]>
CommitDate: Sat Feb 10 05:15:39 2024 +0100

    writerfilter: fix missing paragraph break on tdf136445-1.rtf
    
    This causes an assert:
    crossrefbookmark.cxx:44: sw::mark::CrossRefBookmark::CrossRefBookmark(): 
Assertion `IDocumentMarkAccess::IsLegalPaMForCrossRefHeadingBookmark(rPaM) && 
"<CrossRefBookmark::CrossRefBookmark(..)>" "- creation of cross-reference 
bookmark with an illegal PaM that does not expand over exactly one whole 
paragraph."' failed.
    
    The problem is that there is an annotation at the end of a paragraph,
    and reading the annotation changes various members of DomainMapper_Impl,
    in particular m_bParaSectpr and m_bParaChanged, causing "bRemove" in
    DomainMapper::lcl_utext() to be erroneously true, removing the just
    inserted paragraph break again.
    
    Move all flags that are evaluated for bRemove to SubstreamContext.
    
    This causes one test failure, but it turns out that the new result is
    the same as in Word 2013.
    
      Test name: (anonymous namespace)::testTdf108947::TestBody
      equality assertion failed
      - Expected: Header Page 2 ?
      - Actual  :
      Header Page 2 ?
    
    (regression from commit 15b886f460919ea3dce425a621dc017c2992a96b)
    
    Change-Id: I44a7a8928ab04c600d4d3c43bc4e4deeafe57d89
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/162932
    Tested-by: Jenkins
    Reviewed-by: Michael Stahl <[email protected]>
    (cherry picked from commit 86ad08f9d25110e91e92a0badf6de75e785b3644)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/162936
    Reviewed-by: Caolán McNamara <[email protected]>

diff --git a/sw/qa/extras/rtfexport/data/tdf136445-1-min.rtf 
b/sw/qa/extras/rtfexport/data/tdf136445-1-min.rtf
new file mode 100644
index 000000000000..c0abd0d293be
--- /dev/null
+++ b/sw/qa/extras/rtfexport/data/tdf136445-1-min.rtf
@@ -0,0 +1,17 @@
+{ tf1
+{\*\listtable
+{\list\listtemplateid8
+{\listlevel\levelnfc0\leveljc0\levelstartat1\levelfollow0{\leveltext 
\'02E\'00;}{\levelnumbers\'02;}i-720\li720}\listid8}
+}
+{\listoverridetable{\listoverride\listid8\listoverridecount0\ls8}}
+
+\ltrpar \sectd
+\pard\plain \ltrpar{ tlch\hich \ltrch\loch
+I ax xoixx xuxixx xxe xixxx. (Xaxxexx 1989 x.x. xaxax a)}{ tlch\hich 
\ltrch\loch
+{\*tnid CL}{\*tnauthor Christian}+sic!}}}
+\par \pard\plain {\listtext\pard\plain  E119   ab}\ilvl0\ls8 \li720 i0\lin720 
in0i-720\ql\ltrpar{{\*kmkstart __RefNumPara__395941_134077278}{\*kmkend 
__RefNumPara__395941_134077278} tlch\hich \ltrch\loch
+Xix    ab xaxa ab x-a  ab      ab      ab xix  ab }{ tlch\hich 
\ltrch\langfe0\dbch\loch\lang255\loch
+x xi = xa.}
+\par
+}
diff --git a/sw/qa/extras/rtfexport/rtfexport8.cxx 
b/sw/qa/extras/rtfexport/rtfexport8.cxx
index a611a3bf4c1d..943735098082 100644
--- a/sw/qa/extras/rtfexport/rtfexport8.cxx
+++ b/sw/qa/extras/rtfexport/rtfexport8.cxx
@@ -109,6 +109,20 @@ DECLARE_RTFEXPORT_TEST(testTdf158586_lostFrame, 
"tdf158586_lostFrame.rtf")
     CPPUNIT_ASSERT_EQUAL(2, getPages());
 }
 
+DECLARE_RTFEXPORT_TEST(testAnnotationPar, "tdf136445-1-min.rtf")
+{
+    // the problem was that the paragraph break following annotation was 
missing
+    CPPUNIT_ASSERT_EQUAL(2, getParagraphs());
+    CPPUNIT_ASSERT_EQUAL(
+        OUString("Annotation"),
+        getProperty<OUString>(
+            getRun(getParagraph(1, "I ax xoixx xuxixx xxe xixxx. (Xaxxexx 1989 
x.x. xaxax a)"), 2),
+            "TextPortionType"));
+    CPPUNIT_ASSERT(
+        !getProperty<OUString>(getParagraph(2, "Xix    xaxa    x-a             
        xix     x xi = xa."), "ListId")
+             .isEmpty());
+}
+
 DECLARE_RTFEXPORT_TEST(testTdf158826_extraCR, "tdf158826_extraCR.rtf")
 {
     // Note: this is a hand-minimized sample, and very likely doesn't follow 
RTF { } rules...
diff --git a/sw/qa/extras/rtfimport/rtfimport.cxx 
b/sw/qa/extras/rtfimport/rtfimport.cxx
index f85016e13447..f42f5cee5f4f 100644
--- a/sw/qa/extras/rtfimport/rtfimport.cxx
+++ b/sw/qa/extras/rtfimport/rtfimport.cxx
@@ -1572,7 +1572,7 @@ CPPUNIT_TEST_FIXTURE(Test, testTdf108947)
     uno::Reference<text::XText> xHeaderTextLeft = 
getProperty<uno::Reference<text::XText>>(
         getStyles("PageStyles")->getByName("Default Page Style"), 
"HeaderTextLeft");
     aActual = xHeaderTextLeft->getString();
-    CPPUNIT_ASSERT_EQUAL(OUString("Header Page 2 ?"), aActual);
+    CPPUNIT_ASSERT_EQUAL(OUString(SAL_NEWLINE_STRING "Header Page 2 ?"), 
aActual);
 #endif
 }
 
diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.cxx 
b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
index 9a2160d488d8..6358cd90b664 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.cxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
@@ -373,16 +373,10 @@ DomainMapper_Impl::DomainMapper_Impl(
         m_bIsParaMarkerChange( false ),
         m_bIsParaMarkerMove( false ),
         m_bRedlineImageInPreviousRun( false ),
-        m_bParaChanged( false ),
-        m_bIsFirstParaInSection( true ),
-        m_bIsFirstParaInSectionAfterRedline( true ),
         m_bDummyParaAddedForTableInSection( false ),
         m_bDummyParaAddedForTableInSectionPage( false ),
         m_bTextFrameInserted(false),
-        m_bIsPreviousParagraphFramed( false ),
-        m_bIsLastParaInSection( false ),
         m_bIsLastSectionGroup( false ),
-        m_bParaSectpr( false ),
         m_bUsingEnhancedFields( false ),
         m_bSdt(false),
         m_bIsFirstRun(false),
@@ -404,7 +398,6 @@ DomainMapper_Impl::DomainMapper_Impl(
         m_bIsSplitPara(false),
         m_bIsActualParagraphFramed( false ),
         m_bParaAutoBefore(false),
-        m_bParaWithInlineObject(false),
         m_bSaxError(false)
 {
     m_StreamStateStack.emplace(); // add state for document body
@@ -912,25 +905,27 @@ void DomainMapper_Impl::SetIsLastSectionGroup( bool 
bIsLast )
 
 void DomainMapper_Impl::SetIsLastParagraphInSection( bool bIsLast )
 {
-    m_bIsLastParaInSection = bIsLast;
+    m_StreamStateStack.top().bIsLastParaInSection = bIsLast;
 }
 
 
 void DomainMapper_Impl::SetIsFirstParagraphInSection( bool bIsFirst )
 {
-    m_bIsFirstParaInSection = bIsFirst;
+    m_StreamStateStack.top().bIsFirstParaInSection = bIsFirst;
 }
 
 void DomainMapper_Impl::SetIsFirstParagraphInSectionAfterRedline( bool 
bIsFirstAfterRedline )
 {
-    m_bIsFirstParaInSectionAfterRedline = bIsFirstAfterRedline;
+    m_StreamStateStack.top().bIsFirstParaInSectionAfterRedline = 
bIsFirstAfterRedline;
 }
 
 bool DomainMapper_Impl::GetIsFirstParagraphInSection( bool bAfterRedline ) 
const
 {
     // Anchored objects may include multiple paragraphs,
     // and none of them should be considered the first para in section.
-    return ( bAfterRedline ? m_bIsFirstParaInSectionAfterRedline : 
m_bIsFirstParaInSection )
+    return (bAfterRedline
+                    ? 
m_StreamStateStack.top().bIsFirstParaInSectionAfterRedline
+                    : m_StreamStateStack.top().bIsFirstParaInSection)
                 && !IsInShape()
                 && !IsInComments()
                 && !IsInFootOrEndnote();
@@ -958,13 +953,11 @@ void DomainMapper_Impl::SetIsTextFrameInserted( bool 
bIsInserted )
     m_bTextFrameInserted  = bIsInserted;
 }
 
-
 void DomainMapper_Impl::SetParaSectpr(bool bParaSectpr)
 {
-    m_bParaSectpr = bParaSectpr;
+    m_StreamStateStack.top().bParaSectpr = bParaSectpr;
 }
 
-
 void DomainMapper_Impl::SetSdt(bool bSdt)
 {
     m_bSdt = bSdt;
@@ -2805,7 +2798,7 @@ void DomainMapper_Impl::finishParagraph( const 
PropertyMapPtr& pPropertyMap, con
 
                     xCur->goLeft( 1 , true );
                     // Extend the redline ranges for empty paragraphs
-                    if ( !m_bParaChanged && m_previousRedline )
+                    if (!m_StreamStateStack.top().bParaChanged && 
m_previousRedline)
                         CreateRedline( xCur, m_previousRedline );
                     CheckParaMarkerRedline( xCur );
                 }
@@ -2949,21 +2942,21 @@ void DomainMapper_Impl::finishParagraph( const 
PropertyMapPtr& pPropertyMap, con
     else
         SetIsPreviousParagraphFramed(false);
 
-    m_bRemoveThisParagraph = false;
+    m_StreamStateStack.top().bRemoveThisParagraph = false;
     if( !IsInHeaderFooter() && !IsInShape()
         && (!pParaContext || !pParaContext->props().IsFrameMode()) )
     { // If the paragraph is in a frame, shape or header/footer, it's not a 
paragraph of the section itself.
         SetIsFirstParagraphInSection(false);
         // don't count an empty deleted paragraph as first paragraph in 
section to avoid of
         // the deletion of the next empty paragraph later, resulting loss of 
the associated page break
-        if (!m_previousRedline || m_bParaChanged)
+        if (!m_previousRedline || m_StreamStateStack.top().bParaChanged)
         {
             SetIsFirstParagraphInSectionAfterRedline(false);
             SetIsLastParagraphInSection(false);
         }
     }
     m_previousRedline.clear();
-    m_bParaChanged = false;
+    m_StreamStateStack.top().bParaChanged = false;
 
     if (IsInComments() && pParaContext)
     {
@@ -3000,7 +2993,7 @@ void DomainMapper_Impl::finishParagraph( const 
PropertyMapPtr& pPropertyMap, con
     }
 
     m_bParaAutoBefore = false;
-    m_bParaWithInlineObject = false;
+    m_StreamStateStack.top().bParaWithInlineObject = false;
 
 #ifdef DBG_UTIL
     TagLogger::getInstance().endElement();
@@ -3280,7 +3273,7 @@ void DomainMapper_Impl::applyToggleAttributes(const 
PropertyMapPtr& pPropertyMap
             m_pParaMarkerRedlineMove.clear();
         }
         CheckRedline( xTextRange );
-        m_bParaChanged = true;
+        m_StreamStateStack.top().bParaChanged = true;
 
         //getTableManager( ).handle(xTextRange);
     }
@@ -4015,7 +4008,8 @@ void DomainMapper_Impl::CheckRedline( uno::Reference< 
text::XTextRange > const&
 
     // only export ParagraphFormat, when there is no other redline in the same 
text portion to avoid missing redline compression,
     // but always export the first ParagraphFormat redline in a paragraph to 
keep the paragraph style change data for rejection
-    if( (!bUsedRange || !m_bParaChanged) && 
GetTopContextOfType(CONTEXT_PARAGRAPH) )
+    if ((!bUsedRange || !m_StreamStateStack.top().bParaChanged)
+        && GetTopContextOfType(CONTEXT_PARAGRAPH))
     {
         std::vector<RedlineParamsPtr>& avRedLines = 
GetTopContextOfType(CONTEXT_PARAGRAPH)->Redlines();
         for( const auto& rRedline : avRedLines )
@@ -4660,7 +4654,7 @@ void DomainMapper_Impl::PushShapeContext( const 
uno::Reference< drawing::XShape
                         getPropertyName( PROP_OPAQUE ),
                         uno::Any( true ) );
         }
-        m_bParaChanged = true;
+        m_StreamStateStack.top().bParaChanged = true;
         getTableManager().setIsInShape(true);
     }
     catch ( const uno::Exception& )
@@ -6643,15 +6637,15 @@ OUString DomainMapper_Impl::extractTocTitle()
 css::uno::Reference<css::beans::XPropertySet>
 DomainMapper_Impl::StartIndexSectionChecked(const OUString& sServiceName)
 {
-    if (m_bParaChanged)
+    if (m_StreamStateStack.top().bParaChanged)
     {
-        finishParagraph(GetTopContextOfType(CONTEXT_PARAGRAPH), false); // 
resets m_bParaChanged
+        finishParagraph(GetTopContextOfType(CONTEXT_PARAGRAPH), false); // 
resets bParaChanged
         PopProperties(CONTEXT_PARAGRAPH);
         PushProperties(CONTEXT_PARAGRAPH);
         SetIsFirstRun(true);
         // The first paragraph of the index that is continuation of just 
finished one needs to be
-        // removed when finished (unless more content will arrive, which will 
set m_bParaChanged)
-        m_bRemoveThisParagraph = true;
+        // removed when finished (unless more content will arrive, which will 
set bParaChanged)
+        m_StreamStateStack.top().bRemoveThisParagraph = true;
     }
     const auto& xTextAppend = GetTopTextAppend();
     const auto xTextRange = xTextAppend->getEnd();
@@ -8423,7 +8417,7 @@ void DomainMapper_Impl::PopFieldContext()
                     if (m_bStartedTOC || m_bStartIndex || m_bStartBibliography)
                     {
                         // inside SDT, last empty paragraph is also part of 
index
-                        if (!m_bParaChanged && !m_xSdtEntryStart)
+                        if (!m_StreamStateStack.top().bParaChanged && 
!m_xSdtEntryStart)
                         {
                             // End of index is the first item on a new 
paragraph - this paragraph
                             // should not be part of index
@@ -8449,7 +8443,7 @@ void DomainMapper_Impl::PopFieldContext()
                         m_bStartedTOC = false;
                         m_aTextAppendStack.pop();
                         m_StreamStateStack.top().bTextInserted = false;
-                        m_bParaChanged = true; // the paragraph must stay 
anyway
+                        m_StreamStateStack.top().bParaChanged = true; // the 
paragraph must stay anyway
                     }
                     m_bStartTOC = false;
                     m_bStartIndex = false;
@@ -9038,7 +9032,7 @@ void  DomainMapper_Impl::ImportGraphic(const 
writerfilter::Reference<Properties>
         }
         else if (m_eGraphicImportType == IMPORT_AS_DETECTED_INLINE)
         {
-            m_bParaWithInlineObject = true;
+            m_StreamStateStack.top().bParaWithInlineObject = true;
 
             // store inline images with track changes, because the anchor point
             // to set redlining is not available yet
diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.hxx 
b/writerfilter/source/dmapper/DomainMapper_Impl.hxx
index 6d7a2bbb8cf4..6f788e177d07 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.hxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.hxx
@@ -194,14 +194,26 @@ struct SubstreamContext
      * inTbl SPRM or not).
      */
     sal_Int32 nTableDepth = 0;
-    // deferred breaks need to be saved for RTF, probably not for DOCX
-    bool      bIsColumnBreakDeferred = false;
-    bool      bIsPageBreakDeferred = false;
+    // deferred breaks need to be saved for RTF, also for DOCX annotations
+    bool bIsColumnBreakDeferred = false;
+    bool bIsPageBreakDeferred = false;
     sal_Int32 nLineBreaksDeferred = 0;
     /// Current paragraph had at least one field in it.
-    bool      bParaHadField = false;
+    bool bParaHadField = false;
     /// Current paragraph in a table is first paragraph of a cell
-    bool      bFirstParagraphInCell = true;
+    bool bFirstParagraphInCell = true;
+    /// If the current paragraph has any runs.
+    bool bParaChanged = false;
+    bool bIsFirstParaInSectionAfterRedline = true;
+    bool bIsFirstParaInSection = true;
+    bool bIsLastParaInSection = false;
+    /// If the current paragraph contains section property definitions.
+    bool bParaSectpr = false;
+    bool bIsPreviousParagraphFramed = false;
+    /// Current paragraph had at least one inline object in it.
+    bool bParaWithInlineObject = false;
+    /// This is a continuation of already finished paragraph - e.g., first in 
an index section
+    bool bRemoveThisParagraph = false;
 };
 
 /// Information about a paragraph to be finished after a field end.
@@ -622,26 +634,16 @@ private:
     // text ZWSPs to keep the change tracking of the image in Writer.)
     bool                            m_bRedlineImageInPreviousRun;
 
-    /// If the current paragraph has any runs.
-    bool                            m_bParaChanged;
-    bool                            m_bIsFirstParaInSection;
-    bool                            m_bIsFirstParaInSectionAfterRedline;
     bool                            m_bIsFirstParaInShape = false;
     bool                            m_bDummyParaAddedForTableInSection;
     bool                            m_bDummyParaAddedForTableInSectionPage;
     bool                            m_bTextFrameInserted;
-    bool                            m_bIsPreviousParagraphFramed;
-    bool                            m_bIsLastParaInSection;
     bool                            m_bIsLastSectionGroup;
-    /// If the current paragraph contains section property definitions.
-    bool                            m_bParaSectpr;
     bool                            m_bUsingEnhancedFields;
     /// If the current paragraph is inside a structured document element.
     bool                            m_bSdt;
     bool                            m_bIsFirstRun;
     bool                            m_bIsOutsideAParagraph;
-    /// This is a continuation of already finished paragraph - e.g., first in 
an index section
-    bool                            m_bRemoveThisParagraph = false;
 
     css::uno::Reference< css::text::XTextCursor > m_xTOCMarkerCursor;
 
@@ -740,7 +742,7 @@ public:
 
     void SetIsDecimalComma() { m_bIsDecimalComma = true; };
     void SetIsLastParagraphInSection( bool bIsLast );
-    bool GetIsLastParagraphInSection() const { return m_bIsLastParaInSection;}
+    bool GetIsLastParagraphInSection() const { return 
m_StreamStateStack.top().bIsLastParaInSection; }
     void SetRubySprmId( sal_uInt32 nSprmId) { m_aRubyInfo.nSprmId = nSprmId ; }
     void SetRubyText( OUString const &sText, OUString const &sStyle) {
         m_aRubyInfo.sRubyText = sText;
@@ -766,10 +768,11 @@ public:
     bool GetIsTextFrameInserted() const { return m_bTextFrameInserted;}
     void SetIsTextDeleted(bool bIsTextDeleted) { m_bTextDeleted = 
bIsTextDeleted; }
 
-    void SetIsPreviousParagraphFramed( bool bIsFramed ) { 
m_bIsPreviousParagraphFramed = bIsFramed; }
-    bool GetIsPreviousParagraphFramed() const { return 
m_bIsPreviousParagraphFramed; }
+    void SetIsPreviousParagraphFramed(bool const bIsFramed)
+    { m_StreamStateStack.top().bIsPreviousParagraphFramed = bIsFramed; }
+    bool GetIsPreviousParagraphFramed() const { return 
m_StreamStateStack.top().bIsPreviousParagraphFramed; }
     void SetParaSectpr(bool bParaSectpr);
-    bool GetParaSectpr() const { return m_bParaSectpr;}
+    bool GetParaSectpr() const { return m_StreamStateStack.top().bParaSectpr; }
 
     void SetSymbolChar( sal_Int32 nSymbol) { m_aSymbolData.cSymbol = 
sal_Unicode(nSymbol); }
     void SetSymbolFont( OUString const &rName ) { m_aSymbolData.sFont = rName; 
}
@@ -785,9 +788,9 @@ public:
 
     /// Getter method for m_bSdt.
     bool GetSdt() const { return m_bSdt;}
-    bool GetParaChanged() const { return m_bParaChanged;}
+    bool GetParaChanged() const { return 
m_StreamStateStack.top().bParaChanged; }
     bool GetParaHadField() const { return 
m_StreamStateStack.top().bParaHadField; }
-    bool GetRemoveThisPara() const { return m_bRemoveThisParagraph; }
+    bool GetRemoveThisPara() const { return 
m_StreamStateStack.top().bRemoveThisParagraph; }
 
     void deferBreak( BreakType deferredBreakType );
     bool isBreakDeferred( BreakType deferredBreakType );
@@ -1221,7 +1224,7 @@ public:
     bool m_bIsActualParagraphFramed;
     std::deque<css::uno::Any> m_aStoredRedlines[StoredRedlines::NONE];
 
-    bool IsParaWithInlineObject() const { return m_bParaWithInlineObject; }
+    bool IsParaWithInlineObject() const { return 
m_StreamStateStack.top().bParaWithInlineObject; }
 
     css::uno::Reference< css::embed::XStorage > m_xDocumentStorage;
 
@@ -1251,8 +1254,6 @@ private:
     css::uno::Reference<css::beans::XPropertySet> m_xPreviousParagraph;
     /// Current paragraph has automatic before spacing.
     bool m_bParaAutoBefore;
-    /// Current paragraph had at least one inline object in it.
-    bool m_bParaWithInlineObject;
     /// SAXException was seen so document will be abandoned
     bool m_bSaxError;
 
diff --git a/writerfilter/source/rtftok/rtfdispatchsymbol.cxx 
b/writerfilter/source/rtftok/rtfdispatchsymbol.cxx
index 6c1c94b944d9..0f01d79f5cd4 100644
--- a/writerfilter/source/rtftok/rtfdispatchsymbol.cxx
+++ b/writerfilter/source/rtftok/rtfdispatchsymbol.cxx
@@ -406,6 +406,8 @@ RTFError RTFDocumentImpl::dispatchSymbol(RTFKeyword 
nKeyword)
                 }
                 sal_uInt8 const sBreak[] = { 0xc };
                 Mapper().text(sBreak, 1);
+                // testFdo81892 don't do another \par break directly; because 
of
+                // GetSplitPgBreakAndParaMark() it does finishParagraph *twice*
                 m_bNeedCr = true;
             }
         }
commit be9e9f35d54871efba151a949299ab37f73c85b8
Author:     Michael Stahl <[email protected]>
AuthorDate: Wed Jan 31 14:47:22 2024 +0100
Commit:     Thorsten Behrens <[email protected]>
CommitDate: Sat Feb 10 05:15:12 2024 +0100

    writerfilter: move members to SubstreamContext
    
    writerfilter: move m_bParaHadField to SubstreamContext
    
    Change-Id: Ie15e35d304a423bfa3d7b7ead71015d5ec1228d4
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/162839
    Tested-by: Jenkins
    Reviewed-by: Michael Stahl <[email protected]>
    (cherry picked from commit 4913812baeabd44b46302e54b73a227e760c688a)
    
    writerfilter: use SubstreamContext for all substreams
    
    <vmiklos> possibly just nobody needed that so far. could be some more
    general SubstreamContext, i don't see an obvious problem reusing that at
    more places.
    
    Change-Id: If0749155452f65f8dfc4ac2b10f91bb8e48a6b2b
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/162840
    Tested-by: Jenkins
    Reviewed-by: Michael Stahl <[email protected]>
    (cherry picked from commit 95b01848b18283fd2f903c982108ccdb8efee022)
    
    writerfilter: move m_bFirstParagraphInCell to SubstreamContext
    
    This is a change to set it for all substreams.
    
    Change-Id: I44ed9a5485000f40f8ccfe3ec885ef8f05f5aab2
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/162841
    Tested-by: Jenkins
    Reviewed-by: Michael Stahl <[email protected]>
    (cherry picked from commit 30323c813977eb0127251848fecd2532dce75749)
    
    writerfilter: replace members w/ SubstreamContext::eSubstreamType
    
    This should not change any behaviour.
    
    Change-Id: Ic970f0e1b6401119d875c9e811589b9c210e0c34
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/162842
    Tested-by: Jenkins
    Reviewed-by: Michael Stahl <[email protected]>
    (cherry picked from commit 992f7114ab8645fb5b7a22b5f974a95fe7be7712)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/162933
    Reviewed-by: Caolán McNamara <[email protected]>

diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.cxx 
b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
index 118bae8dfe6e..9a2160d488d8 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.cxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
@@ -360,10 +360,7 @@ DomainMapper_Impl::DomainMapper_Impl(
         m_bInStyleSheetImport( false ),
         m_bInNumberingImport(false),
         m_bInAnyTableImport( false ),
-        m_eInHeaderFooterImport( HeaderFooterImportState::none ),
         m_bDiscardHeaderFooter( false ),
-        m_bInFootOrEndnote(false),
-        m_bInFootnote(false),
         m_bHasFootnoteStyle(false),
         m_bCheckFootnoteStyle(false),
         m_eSkipFootnoteState(SkipFootnoteSeparator::OFF),
@@ -385,7 +382,6 @@ DomainMapper_Impl::DomainMapper_Impl(
         m_bIsPreviousParagraphFramed( false ),
         m_bIsLastParaInSection( false ),
         m_bIsLastSectionGroup( false ),
-        m_bIsInComments( false ),
         m_bParaSectpr( false ),
         m_bUsingEnhancedFields( false ),
         m_bSdt(false),
@@ -407,11 +403,7 @@ DomainMapper_Impl::DomainMapper_Impl(
         m_bIgnoreNextTab(false),
         m_bIsSplitPara(false),
         m_bIsActualParagraphFramed( false ),
-        m_bParaHadField(false),
-        m_bSaveParaHadField(false),
         m_bParaAutoBefore(false),
-        m_bFirstParagraphInCell(true),
-        m_bSaveFirstParagraphInCell(false),
         m_bParaWithInlineObject(false),
         m_bSaxError(false)
 {
@@ -940,7 +932,7 @@ bool DomainMapper_Impl::GetIsFirstParagraphInSection( bool 
bAfterRedline ) const
     // and none of them should be considered the first para in section.
     return ( bAfterRedline ? m_bIsFirstParaInSectionAfterRedline : 
m_bIsFirstParaInSection )
                 && !IsInShape()
-                && !m_bIsInComments
+                && !IsInComments()
                 && !IsInFootOrEndnote();
 }
 
@@ -2336,7 +2328,7 @@ void DomainMapper_Impl::finishParagraph( const 
PropertyMapPtr& pPropertyMap, con
         {
             if ( GetIsFirstParagraphInShape() ||
                  (GetIsFirstParagraphInSection() && GetSectionContext() && 
GetSectionContext()->IsFirstSection()) ||
-                (m_bFirstParagraphInCell
+                (m_StreamStateStack.top().bFirstParagraphInCell
                  && 0 < m_StreamStateStack.top().nTableDepth
                  && m_StreamStateStack.top().nTableDepth == m_nTableCellDepth))
             {
@@ -2591,7 +2583,8 @@ void DomainMapper_Impl::finishParagraph( const 
PropertyMapPtr& pPropertyMap, con
                 else
                 {
                     uno::Reference<text::XTextCursor> xCursor;
-                    if (m_bParaHadField && !m_bIsInComments && 
!m_xTOCMarkerCursor.is())
+                    if (m_StreamStateStack.top().bParaHadField
+                        && !IsInComments() && !m_xTOCMarkerCursor.is())
                     {
                         // Workaround to make sure char props of the field are 
not lost.
                         // Not relevant for editeng-based comments.
@@ -2633,9 +2626,10 @@ void DomainMapper_Impl::finishParagraph( const 
PropertyMapPtr& pPropertyMap, con
                                 TOOLS_WARN_EXCEPTION("writerfilter", 
"DomainMapper_Impl::finishParagraph NumberingRules");
                             }
                         }
-                        else if ( 
m_xPreviousParagraph->getPropertySetInfo()->hasPropertyByName("NumberingStyleName")
 &&
+                        else if 
(m_xPreviousParagraph->getPropertySetInfo()->hasPropertyByName("NumberingStyleName")
                                 // don't update before tables
-                                (m_StreamStateStack.top().nTableDepth == 0 || 
!m_bFirstParagraphInCell))
+                            && (m_StreamStateStack.top().nTableDepth == 0
+                                || 
!m_StreamStateStack.top().bFirstParagraphInCell))
                         {
                             aCurrentNumberingName = GetListStyleName(nListId);
                             
m_xPreviousParagraph->getPropertyValue("NumberingStyleName") >>= 
aPreviousNumberingName;
@@ -2819,7 +2813,7 @@ void DomainMapper_Impl::finishParagraph( const 
PropertyMapPtr& pPropertyMap, con
                 css::uno::Reference<css::beans::XPropertySet> 
xParaProps(xTextRange, uno::UNO_QUERY);
 
                 // table style precedence and not hidden shapes anchored to 
hidden empty table paragraphs
-                if (xParaProps && !m_bIsInComments
+                if (xParaProps && !IsInComments()
                     && (0 < m_StreamStateStack.top().nTableDepth
                         || !m_aAnchoredObjectAnchors.empty()))
                 {
@@ -2971,7 +2965,7 @@ void DomainMapper_Impl::finishParagraph( const 
PropertyMapPtr& pPropertyMap, con
     m_previousRedline.clear();
     m_bParaChanged = false;
 
-    if (m_bIsInComments && pParaContext)
+    if (IsInComments() && pParaContext)
     {
         if (const OUString sParaId = pParaContext->props().GetParaId(); 
!sParaId.isEmpty())
         {
@@ -2994,15 +2988,15 @@ void DomainMapper_Impl::finishParagraph( const 
PropertyMapPtr& pPropertyMap, con
     }
 
     SetIsOutsideAParagraph(true);
-    m_bParaHadField = false;
+    m_StreamStateStack.top().bParaHadField = false;
 
     // don't overwrite m_bFirstParagraphInCell in table separator nodes
     // and in text boxes anchored to the first paragraph of table cells
     if (0 < m_StreamStateStack.top().nTableDepth
         && m_StreamStateStack.top().nTableDepth == m_nTableCellDepth
-        && !IsInShape() && !m_bIsInComments)
+        && !IsInShape() && !IsInComments())
     {
-        m_bFirstParagraphInCell = false;
+        m_StreamStateStack.top().bFirstParagraphInCell = false;
     }
 
     m_bParaAutoBefore = false;
@@ -3174,7 +3168,7 @@ void DomainMapper_Impl::applyToggleAttributes(const 
PropertyMapPtr& pPropertyMap
     {
         applyToggleAttributes(pPropertyMap);
         // If we are in comments, then disable CharGrabBag, comment text 
doesn't support that.
-        uno::Sequence< beans::PropertyValue > aValues = 
pPropertyMap->GetPropertyValues(/*bCharGrabBag=*/!m_bIsInComments);
+        uno::Sequence<beans::PropertyValue> aValues = 
pPropertyMap->GetPropertyValues(/*bCharGrabBag=*/!IsInComments());
 
         if (IsInTOC() || m_bStartIndex || m_bStartBibliography)
             for( auto& rValue : asNonConstRange(aValues) )
@@ -3685,9 +3679,6 @@ bool isContentEmpty(uno::Reference<text::XText> const& 
xText, uno::Reference<tex
 
 void DomainMapper_Impl::PushPageHeaderFooter(PagePartType ePagePartType, 
PageType eType)
 {
-    m_bSaveParaHadField = m_bParaHadField;
-    m_StreamStateStack.emplace();
-
     bool bHeader = ePagePartType == PagePartType::Header;
 
     const PropertyIds ePropIsOn = bHeader ? PROP_HEADER_IS_ON: 
PROP_FOOTER_IS_ON;
@@ -3697,7 +3688,7 @@ void DomainMapper_Impl::PushPageHeaderFooter(PagePartType 
ePagePartType, PageTyp
     const PropertyIds ePropTextRight = bHeader ? PROP_HEADER_TEXT: 
PROP_FOOTER_TEXT;
 
     m_bDiscardHeaderFooter = true;
-    m_eInHeaderFooterImport = bHeader ? HeaderFooterImportState::header : 
HeaderFooterImportState::footer;
+    m_StreamStateStack.top().eSubstreamType = bHeader ? SubstreamType::Header 
: SubstreamType::Footer;
 
     //get the section context
     SectionPropertyMap* pSectionContext = GetSectionContext();;
@@ -3846,21 +3837,13 @@ void 
DomainMapper_Impl::PopPageHeaderFooter(PagePartType ePagePartType, PageType
         }
         m_bDiscardHeaderFooter = false;
     }
-    m_eInHeaderFooterImport = HeaderFooterImportState::none;
-
-    assert(!m_StreamStateStack.empty());
-    m_StreamStateStack.pop();
-
-    m_bParaHadField = m_bSaveParaHadField;
 }
 
 void DomainMapper_Impl::PushFootOrEndnote( bool bIsFootnote )
 {
-    SAL_WARN_IF(m_bInFootOrEndnote, "writerfilter.dmapper", 
"PushFootOrEndnote() is called from another foot or endnote");
-    m_bInFootOrEndnote = true;
-    m_bInFootnote = bIsFootnote;
+    SAL_WARN_IF(m_StreamStateStack.top().eSubstreamType != 
SubstreamType::Body, "writerfilter.dmapper", "PushFootOrEndnote() is called 
from another foot or endnote");
+    m_StreamStateStack.top().eSubstreamType = bIsFootnote ? 
SubstreamType::Footnote : SubstreamType::Endnote;
     m_bCheckFirstFootnoteTab = true;
-    m_bSaveFirstParagraphInCell = m_bFirstParagraphInCell;
     try
     {
         // Redlines outside the footnote should not affect footnote content
@@ -4091,7 +4074,7 @@ void DomainMapper_Impl::PushAnnotation()
 {
     try
     {
-        m_bIsInComments = true;
+        m_StreamStateStack.top().eSubstreamType = SubstreamType::Annotation;
         if (!GetTextFactory().is())
             return;
         m_xAnnotationField.set( GetTextFactory()->createInstance( 
"com.sun.star.text.TextField.Annotation" ),
@@ -4353,16 +4336,13 @@ void DomainMapper_Impl::PopFootOrEndnote()
     }
     m_aRedlines.pop();
     m_eSkipFootnoteState = SkipFootnoteSeparator::OFF;
-    m_bInFootOrEndnote = m_bInFootnote = false;
     m_pFootnoteContext = nullptr;
-    m_bFirstParagraphInCell = m_bSaveFirstParagraphInCell;
 }
 
 void DomainMapper_Impl::PopAnnotation()
 {
     RemoveLastParagraph();
 
-    m_bIsInComments = false;
     m_aTextAppendStack.pop();
 
     try
@@ -4842,7 +4822,7 @@ void DomainMapper_Impl::ClearPreviousParagraph()
     m_xPreviousParagraph.clear();
 
     // next table paragraph will be first paragraph in a cell
-    m_bFirstParagraphInCell = true;
+    m_StreamStateStack.top().bFirstParagraphInCell = true;
 }
 
 void DomainMapper_Impl::HandleAltChunk(const OUString& rStreamName)
@@ -5792,7 +5772,7 @@ uno::Reference<beans::XPropertySet> 
DomainMapper_Impl::FindOrCreateFieldMaster(c
 
 void DomainMapper_Impl::PushFieldContext()
 {
-    m_bParaHadField = true;
+    m_StreamStateStack.top().bParaHadField = true;
     if(m_bDiscardHeaderFooter)
         return;
 #ifdef DBG_UTIL
@@ -6906,7 +6886,7 @@ void DomainMapper_Impl::handleToc
 
     m_bStartTOC = true;
     pContext->SetTOC(xTOC);
-    m_bParaHadField = false;
+    m_StreamStateStack.top().bParaHadField = false;
 
     if (!xTOC)
         return;
@@ -7139,7 +7119,7 @@ void DomainMapper_Impl::handleBibliography
         xTOC->setPropertyValue(getPropertyName( PROP_TITLE ), 
uno::Any(OUString()));
 
     pContext->SetTOC( xTOC );
-    m_bParaHadField = false;
+    m_StreamStateStack.top().bParaHadField = false;
 
     uno::Reference< text::XTextContent > xToInsert( xTOC, uno::UNO_QUERY );
     appendTextContent(xToInsert, uno::Sequence< beans::PropertyValue >() );
@@ -7182,7 +7162,7 @@ void DomainMapper_Impl::handleIndex
         }
     }
     pContext->SetTOC( xTOC );
-    m_bParaHadField = false;
+    m_StreamStateStack.top().bParaHadField = false;
 
     uno::Reference< text::XTextContent > xToInsert( xTOC, uno::UNO_QUERY );
     appendTextContent(xToInsert, uno::Sequence< beans::PropertyValue >() );
@@ -8146,7 +8126,7 @@ void DomainMapper_Impl::CloseFieldCommand()
                 }
             }
             else
-                m_bParaHadField = false;
+                m_StreamStateStack.top().bParaHadField = false;
         }
     }
     catch( const uno::Exception& )
@@ -8708,8 +8688,11 @@ void DomainMapper_Impl::StartOrEndBookmark( const 
OUString& rId )
                     // keep bookmark range, if it doesn't exceed cell boundary
                     uno::Reference< text::XTextRange > xStart = 
xCursor->getStart();
                     xCursor->goLeft( 1, false );
-                    if (m_StreamStateStack.top().nTableDepth == 0 || 
!m_bFirstParagraphInCell)
+                    if (m_StreamStateStack.top().nTableDepth == 0
+                        || !m_StreamStateStack.top().bFirstParagraphInCell)
+                    {
                         xCursor->gotoRange(xStart, true );
+                    }
                 }
                 uno::Reference< container::XNamed > xBkmNamed( xBookmark, 
uno::UNO_QUERY_THROW );
                 SAL_WARN_IF(aBookmarkIter->second.m_sBookmarkName.isEmpty(), 
"writerfilter.dmapper", "anonymous bookmark");
@@ -9550,6 +9533,8 @@ void DomainMapper_Impl::substream(Id rName,
     appendTableHandler();
     getTableManager().startLevel();
 
+    m_StreamStateStack.emplace();
+
     //import of page header/footer
     //Ensure that only one header/footer per section is pushed
 
@@ -9580,8 +9565,12 @@ void DomainMapper_Impl::substream(Id rName,
     case NS_ooxml::LN_annotation :
         PushAnnotation();
     break;
+    default:
+        assert(false); // unexpected?
     }
 
+    assert(m_StreamStateStack.top().eSubstreamType != SubstreamType::Body);
+
     try
     {
         ref->resolve(m_rDMapper);
@@ -9621,6 +9610,9 @@ void DomainMapper_Impl::substream(Id rName,
     break;
     }
 
+    assert(!m_StreamStateStack.empty());
+    m_StreamStateStack.pop();
+
     getTableManager().endLevel();
     popTableManager();
     m_bHasFtn = bHasFtn;
diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.hxx 
b/writerfilter/source/dmapper/DomainMapper_Impl.hxx
index 96e4e578482f..6d7a2bbb8cf4 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.hxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.hxx
@@ -163,6 +163,16 @@ enum StoredRedlines
     NONE
 };
 
+enum class SubstreamType
+{
+    Body,
+    Header,
+    Footer,
+    Footnote,
+    Endnote,
+    Annotation,
+};
+
 /**
  * Storage for state that is relevant outside a header/footer, but not inside 
it.
  *
@@ -174,6 +184,7 @@ enum StoredRedlines
  */
 struct SubstreamContext
 {
+    SubstreamType eSubstreamType = SubstreamType::Body;
     bool      bTextInserted = false;
     /**
      * This contains the raw table depth. nTableDepth > 0 is the same as
@@ -187,6 +198,10 @@ struct SubstreamContext
     bool      bIsColumnBreakDeferred = false;
     bool      bIsPageBreakDeferred = false;
     sal_Int32 nLineBreaksDeferred = 0;
+    /// Current paragraph had at least one field in it.
+    bool      bParaHadField = false;
+    /// Current paragraph in a table is first paragraph of a cell
+    bool      bFirstParagraphInCell = true;
 };
 
 /// Information about a paragraph to be finished after a field end.
@@ -569,15 +584,7 @@ private:
     bool                            m_bInStyleSheetImport; //in import of 
fonts, styles, lists or lfos
     bool                            m_bInNumberingImport; //in import of 
numbering (i.e. numbering.xml)
     bool                            m_bInAnyTableImport; //in import of fonts, 
styles, lists or lfos
-    enum class HeaderFooterImportState
-    {
-        none,
-        header,
-        footer,
-    }                               m_eInHeaderFooterImport;
     bool                            m_bDiscardHeaderFooter;
-    bool                            m_bInFootOrEndnote;
-    bool                            m_bInFootnote;
     PropertyMapPtr m_pFootnoteContext;
     bool m_bHasFootnoteStyle;
     bool m_bCheckFootnoteStyle;
@@ -626,7 +633,6 @@ private:
     bool                            m_bIsPreviousParagraphFramed;
     bool                            m_bIsLastParaInSection;
     bool                            m_bIsLastSectionGroup;
-    bool                            m_bIsInComments;
     /// If the current paragraph contains section property definitions.
     bool                            m_bParaSectpr;
     bool                            m_bUsingEnhancedFields;
@@ -780,7 +786,7 @@ public:
     /// Getter method for m_bSdt.
     bool GetSdt() const { return m_bSdt;}
     bool GetParaChanged() const { return m_bParaChanged;}
-    bool GetParaHadField() const { return m_bParaHadField; }
+    bool GetParaHadField() const { return 
m_StreamStateStack.top().bParaHadField; }
     bool GetRemoveThisPara() const { return m_bRemoveThisParagraph; }
 
     void deferBreak( BreakType deferredBreakType );
@@ -900,7 +906,7 @@ public:
     css::uno::Reference<css::drawing::XShape> PopPendingShape();
 
     void PopPageHeaderFooter(PagePartType ePagePartType, PageType eType);
-    bool IsInHeaderFooter() const { return m_eInHeaderFooterImport != 
HeaderFooterImportState::none; }
+    bool IsInHeaderFooter() const { auto const 
type(m_StreamStateStack.top().eSubstreamType); return type == 
SubstreamType::Header || type == SubstreamType::Footer; }
     void ConvertHeaderFooterToTextFrame(bool, bool);
     static void 
fillEmptyFrameProperties(std::vector<css::beans::PropertyValue>& 
rFrameProperties, bool bSetAnchorToChar);
 
@@ -908,8 +914,8 @@ public:
 
     void PushFootOrEndnote( bool bIsFootnote );
     void PopFootOrEndnote();
-    bool IsInFootOrEndnote() const { return m_bInFootOrEndnote; }
-    bool IsInFootnote() const { return IsInFootOrEndnote() && m_bInFootnote; }
+    bool IsInFootOrEndnote() const { auto const 
type(m_StreamStateStack.top().eSubstreamType); return type == 
SubstreamType::Footnote || type == SubstreamType::Endnote; }
+    bool IsInFootnote() const { return m_StreamStateStack.top().eSubstreamType 
== SubstreamType::Footnote; }
 
     void StartCustomFootnote(const PropertyMapPtr pContext);
     void EndCustomFootnote();
@@ -1059,7 +1065,7 @@ public:
     void SetInFootnoteProperties(bool bSet) { m_bIsInFootnoteProperties = 
bSet;}
     bool IsInFootnoteProperties() const { return m_bIsInFootnoteProperties;}
 
-    bool IsInComments() const { return m_bIsInComments; };
+    bool IsInComments() const { return m_StreamStateStack.top().eSubstreamType 
== SubstreamType::Annotation; };
 
     std::vector<css::beans::PropertyValue> MakeFrameProperties(const 
ParagraphProperties& rProps);
     void CheckUnregisteredFrameConversion(bool bPreventOverlap = false);
@@ -1242,15 +1248,9 @@ private:
     // Start a new index section; if needed, finish current paragraph
     css::uno::Reference<css::beans::XPropertySet> 
StartIndexSectionChecked(const OUString& sServiceName);
     std::vector<css::uno::Reference< css::drawing::XShape > > 
m_vTextFramesForChaining ;
-    /// Current paragraph had at least one field in it.
-    bool m_bParaHadField;
-    bool m_bSaveParaHadField;
     css::uno::Reference<css::beans::XPropertySet> m_xPreviousParagraph;
     /// Current paragraph has automatic before spacing.
     bool m_bParaAutoBefore;
-    /// Current paragraph in a table is first paragraph of a cell
-    bool m_bFirstParagraphInCell;
-    bool m_bSaveFirstParagraphInCell;
     /// Current paragraph had at least one inline object in it.
     bool m_bParaWithInlineObject;
     /// SAXException was seen so document will be abandoned
commit 01114829abd9928c044a60807de5b0d5e48d6b60
Author:     Thorsten Behrens <[email protected]>
AuthorDate: Fri Jan 12 12:01:29 2024 +0100
Commit:     Thorsten Behrens <[email protected]>
CommitDate: Sat Feb 10 05:03:48 2024 +0100

    Fix system-libfixmath
    
    Seems distros start to disagree on whether its liblibfixmath or just
    libfixmath.
    
    Change-Id: I54a42b2ba050980ae632ab3c82254131cad7787e
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/161969
    Tested-by: Jenkins
    Reviewed-by: Thorsten Behrens <[email protected]>

diff --git a/config_host.mk.in b/config_host.mk.in
index eb5e751e100b..3693a2977124 100644
--- a/config_host.mk.in
+++ b/config_host.mk.in
@@ -438,6 +438,7 @@ export LIBXML_JAR=@LIBXML_JAR@
 export LIBXML_LIBS=$(gb_SPACE)@LIBXML_LIBS@
 export LIBXSLT_CFLAGS=$(gb_SPACE)@LIBXSLT_CFLAGS@
 export LIBXSLT_LIBS=$(gb_SPACE)@LIBXSLT_LIBS@
+export LIBFIXMATH_LIBS=$(gb_SPACE)@LIBFIXMATH_LIBS@
 export LOCKFILE=@LOCKFILE@
 export LO_CLANG_CC=@LO_CLANG_CC@
 export LO_CLANG_CXX=@LO_CLANG_CXX@
diff --git a/configure.ac b/configure.ac
index 8dc1e2c8c24b..7a0a11c7960a 100644
--- a/configure.ac
+++ b/configure.ac
@@ -10578,13 +10578,17 @@ if test "$with_system_libfixmath" = "yes"; then
     AC_LANG_PUSH([C++])
     AC_CHECK_HEADER([libfixmath/fix16.hpp], [],
        [AC_MSG_ERROR([libfixmath/fix16.hpp not found. install libfixmath])], 
[])
-    AC_CHECK_LIB([libfixmath], [fix16_mul], [:], [AC_MSG_ERROR(libfixmath lib 
not found or functional)], [])
+    AC_CHECK_LIB([libfixmath], [fix16_mul], [LIBFIXMATH_LIBS=-llibfixmath],
+                 [AC_CHECK_LIB([fixmath], [fix16_mul], 
[LIBFIXMATH_LIBS=-lfixmath],
+                               [AC_MSG_ERROR(libfixmath lib not found or 
functional)])])
     AC_LANG_POP([C++])
 else
     AC_MSG_RESULT([internal])
     SYSTEM_LIBFIXMATH=
+    LIBFIXMATH_LIBS=
 fi
 AC_SUBST([SYSTEM_LIBFIXMATH])
+AC_SUBST([LIBFIXMATH_LIBS])
 
 dnl ===================================================================
 dnl Check for system glm
diff --git a/tools/Library_tl.mk b/tools/Library_tl.mk
index 8269e6ae98bf..7933e7735cd6 100644
--- a/tools/Library_tl.mk
+++ b/tools/Library_tl.mk
@@ -116,7 +116,7 @@ endif
 
 ifeq ($(SYSTEM_LIBFIXMATH),TRUE)
 $(eval $(call gb_Library_add_libs,tl,\
-       -llibfixmath \
+       $(LIBFIXMATH_LIBS) \
 ))
 endif
 
diff --git a/vcl/Library_vcl.mk b/vcl/Library_vcl.mk
index 9fd8db050b39..fede35eb962c 100644
--- a/vcl/Library_vcl.mk
+++ b/vcl/Library_vcl.mk
@@ -572,7 +572,7 @@ vcl_headless_freetype_code=\
 
 ifeq ($(SYSTEM_LIBFIXMATH),TRUE)
 $(eval $(call gb_Library_add_libs,vcl,\
-        -llibfixmath \
+        $(LIBFIXMATH_LIBS) \
 ))
 endif
 
commit 305108ce4a8112676509bf34bc3cb64da54c2954
Author:     Thorsten Behrens <[email protected]>
AuthorDate: Sun Jan 14 01:32:29 2024 +0100
Commit:     Thorsten Behrens <[email protected]>
CommitDate: Sat Feb 10 05:03:48 2024 +0100

    Only run solver uitest if either lpsolve or coinbase is in
    
    Change-Id: Ic03a6df33344b92dccc9bc393d718b4011aa1613
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/162034
    Tested-by: Jenkins
    Reviewed-by: Thorsten Behrens <[email protected]>

diff --git a/sc/Module_sc.mk b/sc/Module_sc.mk
index 0c2178b7fea1..af2450d9d14d 100644
--- a/sc/Module_sc.mk
+++ b/sc/Module_sc.mk
@@ -270,7 +270,6 @@ $(eval $(call gb_Module_add_uicheck_targets,sc,\
        UITest_csv_dialog \
        UITest_external_links \
        UITest_statistics \
-       UITest_solver \
        UITest_goalSeek \
        UITest_protect \
        UITest_sc_options \
@@ -292,6 +291,12 @@ $(eval $(call gb_Module_add_uicheck_targets,sc,\
        UITest_function_wizard \
        UITest_manual_tests \
 ))
+
+ifneq ($(or $(ENABLE_LPSOLVE),$(ENABLE_COINMP)),)
+$(eval $(call gb_Module_add_uicheck_targets,sc,\
+       UITest_solver \
+))
+endif
 endif
 
 # vim: set noet sw=4 ts=4:
commit 3508aff99a6817a2e77b6a92397b29d1e3f9847b
Author:     Michael Stahl <[email protected]>
AuthorDate: Wed Feb 7 13:04:14 2024 +0100
Commit:     Thorsten Behrens <[email protected]>
CommitDate: Sat Feb 10 05:03:48 2024 +0100

    tdf#158586 writerfilter: RTF import: fix assert on ooo113308-1.rtf
    
      warn:legacy.osl:::writerfilter/source/dmapper/DomainMapper_Impl.cxx:1278: 
section stack already empty
      DomainMapper_Impl.cxx:9817: void 
writerfilter::dmapper::DomainMapper_Impl::substream(): Assertion 
`m_aContextStack.size() == contextSize' failed.
    
    Before substream(), there is one CONTEXT_SECTION, after there is an
    additional CONTEXT_PARAGRPAH.
    
    The first OSL_ENSURE is because RTFDocumentImpl::tableBreak() calls
    endParagraphGroup() but in the substream, startParagraphGroup() hadn't
    been called; fixing this also makes the assert failure go away.
    
    This worked previously because sectBreak() called endParagraphGroup()
    after reading the header substreams, but it seems dubious that a
    paragraph group started in the body should be used in the substream.
    
    (regression from commit 57abad5cf990111fd7de011809d4421dc0550193)
    
    Change-Id: I98864bca03b59099c17080c0a7582de2b77d41e1
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/163096
    Tested-by: Jenkins
    Reviewed-by: Michael Stahl <[email protected]>

diff --git a/writerfilter/source/rtftok/rtfdocumentimpl.cxx 
b/writerfilter/source/rtftok/rtfdocumentimpl.cxx
index 652a910c9869..b9c17c0adc61 100644
--- a/writerfilter/source/rtftok/rtfdocumentimpl.cxx
+++ b/writerfilter/source/rtftok/rtfdocumentimpl.cxx
@@ -653,6 +653,7 @@ void RTFDocumentImpl::runBreak()
 
 void RTFDocumentImpl::tableBreak()
 {
+    checkFirstRun(); // ooo113308-1.rtf has a header at offset 151084 that 
doesn't startParagraphGroup() without this
     runBreak();
     Mapper().endParagraphGroup();
     Mapper().startParagraphGroup();
commit 63bfefc52b7426701481adda60327150f181ca77
Author:     Justin Luth <[email protected]>
AuthorDate: Mon Dec 18 12:29:25 2023 -0500
Commit:     Thorsten Behrens <[email protected]>
CommitDate: Sat Feb 10 05:03:48 2024 +0100

    tdf#158586 RTF writerfilter: substitute hasProperties for inFrame
    
    A proper inFrame() would be identical to hasProperties,
    so just substitute the existing, complete function for inFrame.
    
    This is based on a code read, not a problem document,
    but finding a document that depended on inFrame
    returning true made it trivial to modify it to fail.
    
    Somewhat surprisingly, it made it all the way through
    the rtfexports without failing.
    
    make CppunitTest_sw_rtfimport CPPUNIT_TEST_NAME=testFdo52052
    
    Change-Id: I96f00c9b542dabd3709a896d778569b7681c8f19
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/160928
    Tested-by: Jenkins
    Reviewed-by: Justin Luth <[email protected]>
    Reviewed-by: Miklos Vajna <[email protected]>

diff --git a/sw/qa/extras/rtfimport/data/fdo52052.rtf 
b/sw/qa/extras/rtfimport/data/fdo52052.rtf
index e58a64bd43f6..8ae92383c443 100644
--- a/sw/qa/extras/rtfimport/data/fdo52052.rtf
+++ b/sw/qa/extras/rtfimport/data/fdo52052.rtf
@@ -13,7 +13,7 @@
 {\pard \pvpg\phpg\posx2007\posy597bsw12870bsh-900i0 \ltrpar\qc first
 \par }
 \page\sect 
-{\pard \pvpg\phpg\posx13152\posy612bsw2984bsh-210i0 \ltrpar\qr      x360    
x720    x1080   x1440   x1800   x2160   x2520   x2880
+{\pard \pvpg\phpg \posxc\posyc i0 \ltrpar\qr  x360    x720    x1080   x1440   
x1800   x2160   x2520   x2880
 {\ltrch0 \i0\ul0\strike0s15  \par }
 \page\sect 
diff --git a/writerfilter/source/rtftok/rtfdispatchsymbol.cxx 
b/writerfilter/source/rtftok/rtfdispatchsymbol.cxx
index e79143d54a06..6c1c94b944d9 100644
--- a/writerfilter/source/rtftok/rtfdispatchsymbol.cxx
+++ b/writerfilter/source/rtftok/rtfdispatchsymbol.cxx
@@ -124,7 +124,7 @@ RTFError RTFDocumentImpl::dispatchSymbol(RTFKeyword 
nKeyword)
             }
             // but don't emit properties yet, since they may change till the 
first text token arrives
             m_bNeedPap = true;
-            if (!m_aStates.top().getFrame().inFrame())
+            if (!m_aStates.top().getFrame().hasProperties())
                 m_bNeedPar = false;
             m_bNeedFinalPar = false;
         }
diff --git a/writerfilter/source/rtftok/rtfdocumentimpl.cxx 
b/writerfilter/source/rtftok/rtfdocumentimpl.cxx
index 0e72b318ed55..652a910c9869 100644
--- a/writerfilter/source/rtftok/rtfdocumentimpl.cxx
+++ b/writerfilter/source/rtftok/rtfdocumentimpl.cxx
@@ -1349,8 +1349,6 @@ RTFError RTFDocumentImpl::resolveChars(char ch)
     return RTFError::OK;
 }
 
-bool RTFFrame::inFrame() const { return m_nW > 0 || m_nH > 0 || m_nX > 0 || 
m_nY > 0; }
-
 void RTFDocumentImpl::singleChar(sal_uInt8 nValue, bool bRunProps)
 {
     sal_uInt8 sValue[] = { nValue };
@@ -2966,7 +2964,7 @@ RTFError RTFDocumentImpl::beforePopState(RTFParserState& 
rState)
         case Destination::SHAPE:
             m_bNeedFinalPar = true;
             m_bNeedCr = m_bNeedCrOrig;
-            if (rState.getFrame().inFrame())
+            if (rState.getFrame().hasProperties())
             {
                 // parBreak() modifies m_aStates.top() so we can't apply 
resetFrame() directly on aState
                 resetFrame();
@@ -3629,7 +3627,7 @@ RTFError RTFDocumentImpl::popState()
 
     checkUnicode(/*bUnicode =*/true, /*bHex =*/true);
     RTFParserState aState(m_aStates.top());
-    m_bWasInFrame = aState.getFrame().inFrame();
+    m_bWasInFrame = aState.getFrame().hasProperties();
 
     // dmapper expects some content in header/footer, so if there would be 
nothing, add an empty paragraph.
     if (m_pTokenizer->getGroup() == 1 && m_bFirstRun)
diff --git a/writerfilter/source/rtftok/rtfdocumentimpl.hxx 
b/writerfilter/source/rtftok/rtfdocumentimpl.hxx
index 8f415ac101e7..f05f7d321cdd 100644
--- a/writerfilter/source/rtftok/rtfdocumentimpl.hxx
+++ b/writerfilter/source/rtftok/rtfdocumentimpl.hxx
@@ -384,9 +384,8 @@ public:
     RTFSprms getSprms();
     /// Store a property
     void setSprm(Id nId, Id nValue);
-    bool hasProperties() const;
     /// If we got tokens indicating we're in a frame.
-    bool inFrame() const;
+    bool hasProperties() const;
 };
 
 /// State of the parser, which gets saved / restored when changing groups.
@@ -969,7 +968,7 @@ private:
     RTFKeyword m_nResetBreakOnSectBreak;
     /// If a section break is needed before the end of the doc (false right 
after a section break).
     bool m_bNeedSect;
-    /// If aFrame.inFrame() was true in the previous state.
+    /// If aFrame.hasProperties() was true in the previous state.
     bool m_bWasInFrame;
     /// A picture was seen in the current paragraph.
     bool m_bHadPicture;
commit 5e0a358fc7ba8ba650db52970126ed11a58d80a6
Author:     Justin Luth <[email protected]>
AuthorDate: Wed Dec 13 22:25:32 2023 -0500
Commit:     Thorsten Behrens <[email protected]>
CommitDate: Sat Feb 10 05:03:48 2024 +0100

    related tdf#158586 RTF writerfilter: HAnchor's default is text, not margin
    
    \phcol: Use the column as the horizontal reference frame.
    This is the default if no horizontal reference frame is given.
    
    Change-Id: I8ef4a35c578768810edc0a68e3fd3b227c069dfe
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/160776
    Reviewed-by: Justin Luth <[email protected]>
    Tested-by: Jenkins

diff --git a/writerfilter/source/rtftok/rtfdocumentimpl.cxx 
b/writerfilter/source/rtftok/rtfdocumentimpl.cxx
index 5d6df1ddc80c..0e72b318ed55 100644
--- a/writerfilter/source/rtftok/rtfdocumentimpl.cxx
+++ b/writerfilter/source/rtftok/rtfdocumentimpl.cxx
@@ -3981,7 +3981,7 @@ RTFSprms RTFFrame::getSprms()
             case NS_ooxml::LN_CT_FramePr_hAnchor:
             {
                 if (m_nHoriAnchor == 0)
-                    m_nHoriAnchor = NS_ooxml::LN_Value_doc_ST_HAnchor_margin;
+                    m_nHoriAnchor = NS_ooxml::LN_Value_doc_ST_HAnchor_text;
                 pValue = new RTFValue(m_nHoriAnchor);
             }
             break;
commit 92b71da9aba3845b5a93fca25b2d820bfc9962dd
Author:     Justin Luth <[email protected]>
AuthorDate: Fri Dec 1 14:30:45 2023 -0500
Commit:     Thorsten Behrens <[email protected]>
CommitDate: Sat Feb 10 05:03:48 2024 +0100

    tdf#148540 Revert "tdf#109790 RTF import: keep remembering...
    
    ... paragraph style between     This reverts 5.4.1 commit 
aaa6a5202a447fb4e86d5f016d8e79fbc34a3ed7,
    and rtfexport7's tdf109790.rtf unit test still passes.
    I also did a visual test, which looks good.
    
    After      ow is completely unexpected most of the time.
    I'm not really sure why that patch was ever thought to be good.
    
    The problem was that \pard was not removing the paragraph style
    that was assigned to an earlier column. The end result seemed
    innocent (no bad formatting noticed),
    but that is probably based on other work
    done in the meantime which allows the unit test to still pass
    even after all of "its code" has been reverted.
    
    [If this causes a regression, perhaps m_pLastCharacterContext
    could be of value?]
    
    Change-Id: Ide9b65f5e5fa39c21bac6d8ed354bb88e0bbefe5
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/160233
    Tested-by: Jenkins
    Reviewed-by: Justin Luth <[email protected]>

diff --git a/sw/qa/extras/rtfexport/rtfexport6.cxx 
b/sw/qa/extras/rtfexport/rtfexport6.cxx
index 569a65069b31..8140e1724e2d 100644
--- a/sw/qa/extras/rtfexport/rtfexport6.cxx
+++ b/sw/qa/extras/rtfexport/rtfexport6.cxx
@@ -172,6 +172,8 @@ DECLARE_RTFEXPORT_TEST(testTdf108505_fieldCharFormat, 
"tdf108505_fieldCharFormat
     CPPUNIT_ASSERT_EQUAL(awt::FontWeight::BOLD, getProperty<float>(xRun, 
"CharWeight"));
     CPPUNIT_ASSERT_EQUAL(awt::FontSlant_NONE, 
getProperty<awt::FontSlant>(xRun, "CharPosture"));
     CPPUNIT_ASSERT_EQUAL(COL_LIGHTGREEN, getProperty<Color>(xRun, 
"CharColor"));
+
+    CPPUNIT_ASSERT_EQUAL(OUString("Standard"), getProperty<OUString>(xPara, 
"ParaStyleName"));
 }
 
 DECLARE_RTFEXPORT_TEST(testTdf108505_fieldCharFormat2, 
"tdf108505_fieldCharFormat2.rtf")
diff --git a/writerfilter/source/rtftok/rtfdispatchflag.cxx 
b/writerfilter/source/rtftok/rtfdispatchflag.cxx
index 49e82d3b9a88..753f1c3fbba9 100644
--- a/writerfilter/source/rtftok/rtfdispatchflag.cxx
+++ b/writerfilter/source/rtftok/rtfdispatchflag.cxx
@@ -581,8 +581,6 @@ RTFError RTFDocumentImpl::dispatchFlag(RTFKeyword nKeyword)
                 dispatchSymbol(RTFKeyword::PAR);
             // \pard is allowed between              // It should not reset 
the paragraph style, either, so remember the old paragraph style.
-            RTFValue::Pointer_t pOldStyle
-                = 
m_aStates.top().getParagraphSprms().find(NS_ooxml::LN_CT_PPrBase_pStyle);
             m_aStates.top().getParagraphSprms() = 
m_aDefaultState.getParagraphSprms();
             m_aStates.top().getParagraphAttributes() = 
m_aDefaultState.getParagraphAttributes();
 
@@ -595,19 +593,14 @@ RTFError RTFDocumentImpl::dispatchFlag(RTFKeyword 
nKeyword)
             {
                 // We are still in a table.
                 m_aStates.top().getParagraphSprms().set(NS_ooxml::LN_inTbl, 
new RTFValue(1));
-                if (m_bAfterCellBeforeRow && pOldStyle)
-                    // And we still have the same paragraph style.
-                    
m_aStates.top().getParagraphSprms().set(NS_ooxml::LN_CT_PPrBase_pStyle,
-                                                            pOldStyle);
                 // Ideally getDefaultSPRM() would take care of this, but it 
would not when we're buffering.
                 
m_aStates.top().getParagraphSprms().set(NS_ooxml::LN_CT_PPrBase_tabs,
                                                         new RTFValue());
             }
             resetFrame();
 
-            // Reset currently selected paragraph style as well, unless we are 
in the special "after +            // Reset currently selected paragraph style 
as well.
             // By default the style with index 0 is applied.
-            if (!m_bAfterCellBeforeRow)
             {
                 OUString const aName = getStyleName(0);
                 // But only in case it's not a character style.
diff --git a/writerfilter/source/rtftok/rtfdispatchsymbol.cxx 
b/writerfilter/source/rtftok/rtfdispatchsymbol.cxx
index c7eee5b0f4b1..e79143d54a06 100644
--- a/writerfilter/source/rtftok/rtfdispatchsymbol.cxx
+++ b/writerfilter/source/rtftok/rtfdispatchsymbol.cxx
@@ -181,9 +181,6 @@ RTFError RTFDocumentImpl::dispatchSymbol(RTFKeyword 
nKeyword)
         case RTFKeyword::CELL:
         case RTFKeyword::NESTCELL:
         {
-            if (nKeyword == RTFKeyword::CELL)
-                m_bAfterCellBeforeRow = true;
-
             checkFirstRun();
             if (m_bNeedPap)
             {
@@ -237,7 +234,6 @@ RTFError RTFDocumentImpl::dispatchSymbol(RTFKeyword 
nKeyword)
         break;
         case RTFKeyword::ROW:
         {
-            m_bAfterCellBeforeRow = false;
             if (m_aStates.top().getTableRowWidthAfter() > 0)
             {
                 // Add fake cellx / cell, RTF equivalent of
diff --git a/writerfilter/source/rtftok/rtfdocumentimpl.cxx 
b/writerfilter/source/rtftok/rtfdocumentimpl.cxx
index 53f414b57524..5d6df1ddc80c 100644
--- a/writerfilter/source/rtftok/rtfdocumentimpl.cxx
+++ b/writerfilter/source/rtftok/rtfdocumentimpl.cxx
@@ -330,7 +330,6 @@ 
RTFDocumentImpl::RTFDocumentImpl(uno::Reference<uno::XComponentContext> const& x
     , m_hasFHeader(false)
     , m_hasRFooter(false)
     , m_hasFFooter(false)
-    , m_bAfterCellBeforeRow(false)
 {
     OSL_ASSERT(xInputStream.is());
     m_pInStream = utl::UcbStreamHelper::CreateStream(xInputStream, true);
diff --git a/writerfilter/source/rtftok/rtfdocumentimpl.hxx 
b/writerfilter/source/rtftok/rtfdocumentimpl.hxx
index f96c8ada6453..8f415ac101e7 100644
--- a/writerfilter/source/rtftok/rtfdocumentimpl.hxx
+++ b/writerfilter/source/rtftok/rtfdocumentimpl.hxx
@@ -990,9 +990,6 @@ private:
     bool m_hasFHeader;
     bool m_hasRFooter;
     bool m_hasFFooter;
-
-    /// Are we after a -    bool m_bAfterCellBeforeRow;
 };
 } // namespace writerfilter::rtftok
 
commit aa535bd7d3c512f2fae4d1a37e9f2090ef45164a
Author:     Justin Luth <[email protected]>
AuthorDate: Tue Dec 5 21:43:16 2023 -0500
Commit:     Thorsten Behrens <[email protected]>
CommitDate: Sat Feb 10 05:03:48 2024 +0100

    tdf#108505 rtfexport: avoid mis-inheriting field char settings
    
    The field result fully defines its own character properties,
    so it should not inherit any "parent" properties from the field.
    
    My test file didn't show any problems with DOCX or DOC,
    and reading through the code I didn't notice anything
    that looked wrong. Both are very different from RTF syntax,
    and it didn't look like they did anything "special"
    for this situation, so nothing to copy from...
    
    This whole area of field properties looks very hacky,
    but it seems pretty clear that OutputTextNode
    loops through OutAttr's run properties for each of
    start/sep/end for fields. OutAttr picks up all of the
    direct formatting, so nothing should be "missing",
    and therefore a \plain character reset should be appropriate.
    
    The good news is that MS Word 2010 imported both the bad
    and the good export just like we do.
    
    make CppunitTest_sw_rtfexport6 \
        CPPUNIT_TEST_NAME=testTdf108505_fieldCharFormat2
    
    Change-Id: I713c071dfcd40117bfff03d152718eb5d847327e
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/160375
    Tested-by: Jenkins
    Reviewed-by: Justin Luth <[email protected]>
    Reviewed-by: Miklos Vajna <[email protected]>
    (cherry picked from commit 5f888fa920c99cce91dfd18244a5c3869807b970)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/160580
    Reviewed-by: Xisco Fauli <[email protected]>

diff --git a/sw/qa/extras/rtfexport/rtfexport6.cxx 
b/sw/qa/extras/rtfexport/rtfexport6.cxx
index f64e3035c529..569a65069b31 100644
--- a/sw/qa/extras/rtfexport/rtfexport6.cxx
+++ b/sw/qa/extras/rtfexport/rtfexport6.cxx
@@ -176,21 +176,19 @@ DECLARE_RTFEXPORT_TEST(testTdf108505_fieldCharFormat, 
"tdf108505_fieldCharFormat
 
 DECLARE_RTFEXPORT_TEST(testTdf108505_fieldCharFormat2, 
"tdf108505_fieldCharFormat2.rtf")
 {
-    // not exported properly. Currrently xyz exports as run 6, red, italic.
-    if (isExported())
-        return;
-
     uno::Reference<text::XTextTable> xTable(getParagraphOrTable(1), 
uno::UNO_QUERY);
     uno::Reference<text::XTextRange> xCell(xTable->getCellByName("C1"), 
uno::UNO_QUERY);
     uno::Reference<text::XTextRange> xPara = getParagraphOfText(1, 
xCell->getText());
 
-    // Preemptive test: nothing found wrong/fixed by the accompanying patch
+    const sal_Int32 nRun = isExported() ? 6 : 5;
+    const Color aColor = isExported() ? COL_BLACK : COL_AUTO;
+
     // Character formatting should only be defined by the ldrslt, and not by 
prior formatting.
     // Prior formatting is italic, red, 20pt.
-    uno::Reference<text::XTextRange> xRun = getRun(xPara, 5, u"xyz"_ustr);
+    uno::Reference<text::XTextRange> xRun = getRun(xPara, nRun, u"xyz");
     CPPUNIT_ASSERT_EQUAL(awt::FontWeight::BOLD, getProperty<float>(xRun, 
"CharWeight"));
     CPPUNIT_ASSERT_EQUAL(awt::FontSlant_NONE, 
getProperty<awt::FontSlant>(xRun, "CharPosture"));
-    CPPUNIT_ASSERT_EQUAL(COL_AUTO, getProperty<Color>(xRun, "CharColor"));
+    CPPUNIT_ASSERT_EQUAL(aColor, getProperty<Color>(xRun, "CharColor"));
 }
 
 /** Make sure that the document variable "Unused", which is not referenced in 
the document,
diff --git a/sw/source/filter/ww8/rtfattributeoutput.cxx 
b/sw/source/filter/ww8/rtfattributeoutput.cxx
index c8ac5b4cadf4..2e255d43be02 100644
--- a/sw/source/filter/ww8/rtfattributeoutput.cxx
+++ b/sw/source/filter/ww8/rtfattributeoutput.cxx
@@ -1856,7 +1856,13 @@ void RtfAttributeOutput::WriteField_Impl(const SwField* 
const pField, ww::eField
                 msfilter::rtfutil::OutString(rFieldCmd, 
m_rExport.GetCurrentEncoding()));
         if (nMode & FieldFlags::CmdEnd)
         {
-            m_aRunText->append("}}{" OOO_STRING_SVTOOLS_RTF_FLDRSLT " {");
+            m_aRunText->append("}}{" OOO_STRING_SVTOOLS_RTF_FLDRSLT);
+            // The fldrslt contains its own full copy of character formatting,
+            // but if the result is empty (nMode & FieldFlags::End) or field 
export is condensed
+            // in any way (multiple flags) then avoid spamming an unnecessary 
plain character reset.
+            if (nMode == FieldFlags::CmdEnd)
+                m_aRunText->append(OOO_STRING_SVTOOLS_RTF_PLAIN);
+            m_aRunText->append(" {");
         }
         if (nMode & FieldFlags::Close)
         {
diff --git a/sw/source/filter/ww8/wrtw8nds.cxx 
b/sw/source/filter/ww8/wrtw8nds.cxx
index e27137946ef5..1d02b5a6f73d 100644
--- a/sw/source/filter/ww8/wrtw8nds.cxx
+++ b/sw/source/filter/ww8/wrtw8nds.cxx
@@ -2621,7 +2621,12 @@ void MSWordExportBase::OutputTextNode( SwTextNode& rNode 
)
                     // DateFieldmark / ODF_FORMDATE is not a field...
                     if (pFieldmark->GetFieldname() != ODF_FORMDATE)
                     {
-                        OutputField( nullptr, lcl_getFieldId( pFieldmark ), 
OUString(), FieldFlags::CmdEnd );
+                        FieldFlags nFlags = FieldFlags::CmdEnd;
+                        // send hint that fldrslt is empty, to avoid spamming 
RTF CharProp reset.
+                        // ::End does nothing when sending 
rFieldCmd=OUString(), so safe to do.
+                        if (pFieldmark->GetContent().isEmpty())
+                            nFlags |= FieldFlags::End;
+                        OutputField(nullptr, lcl_getFieldId(pFieldmark), 
OUString(), nFlags);
 
                         if (pFieldmark->GetFieldname() == ODF_UNHANDLED)
                         {
commit 93dcbe19982f02c859c83037c2e08f7778e521eb
Author:     Justin Luth <[email protected]>
AuthorDate: Fri Dec 1 14:16:14 2023 -0500
Commit:     Thorsten Behrens <[email protected]>
CommitDate: Sat Feb 10 05:03:48 2024 +0100

    tdf#108505 writerfilter: fix field direct char settings
    
    Instead of adding characters properties one at a time,
    lets take care of everything all at once.
    
    The results seem to be good so far.
    There is even some similarity between
    how MS Word has these properties on the
    "in-between" pseudo end character, where
    placing the cursor after the field gets these properties.
    I don't see it happening in MS Word
    at the pseudo start character, but it does in LO now...
    
    Hopefully that doesn't end up doing bad things.
    
    In the unit test, replacing the content ends up
    in red, italic. However, I see the same thing in MSO
    when testing with my second FORMTEXT example,
    so I think everything is "working as expected".
    
    I tried to see if I could limit doing this
    for only certain types of fields or conditions.
    However, pContext->GetResult() doesn't have a ldrslt
    yet at the time this is happening. Also, TextField.is()
    happens less than I expected. I'm sure I could limit it
    to just certain pContext->GetFieldId(),
    but so far no problems are noticed for all field types.
    
    make CppunitTest_sw_rtfexport6 \
        CPPUNIT_TEST_NAME=testTdf108505_fieldCharFormat
    
    make CppunitTest_sw_rtfexport6 \
        CPPUNIT_TEST_NAME=testTdf108505_fieldCharFormat2
    
    Change-Id: I3223437fd0d694f5e5733a9f7323f10f03d7802f
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/160232
    Tested-by: Jenkins
    Tested-by: Gabor Kelemen <[email protected]>
    Reviewed-by: Miklos Vajna <[email protected]>

diff --git a/sw/qa/extras/rtfexport/data/tdf108505_fieldCharFormat2.rtf 
b/sw/qa/extras/rtfexport/data/tdf108505_fieldCharFormat2.rtf
new file mode 100644
index 000000000000..bb45e3052011
--- /dev/null
+++ b/sw/qa/extras/rtfexport/data/tdf108505_fieldCharFormat2.rtf
@@ -0,0 +1,37 @@
+{ 
tf1deflang1025nsinsicpg1252\uc1deff0\deff0\stshfdbch0\stshfloch0\stshfhich0\stshfbi0\deflang2057\deflangfe2057
   hemelang3079    hemelangfe0     hemelangcs0
+
+
oqfpromote {\stylesheet{\ql \li0 i0\widctlpar\wrapdefaultspalphaspnum
aautodjustright in0\lin0\itap0  tlchcs1 
+f0fs20lang1025 \ltrchcs0 s26\lang1031\langfe3079+ qc      x4819   qr      
x9071\wrapdefaultspalphaspnumaautodjustright in0\lin0\itap0  tlchcs1 
f0fs20lang1025 \ltrchcs0 s26\lang1031\langfe3079+}
+\paperw16834\paperh11913\margl1134\margr1418\margt1418\margb567\gutter0\ltrsect
 
+\deftab708\widowctrltnbjenddoc\hyphhotz425   rackmoves0      
rackformatting1\donotembedsysfont0 elyonvml0\donotembedlingdata0\grfdocevents0
alidatexml1\showplaceholdtext0\ignoremixedcontent0\saveinvalidxml0
+\showxmlerrors1
oextrasprl\prcolbl+\jexpandiewkind1iewscale70\pgbrdrhead\pgbrdrfoot
olnhtadjtbl
ojkernpunct sidroot3825670 et0
+
+\ltrrow        rowd \irow0\irowband0\lastrow \ltrrow
+       s11     rgaph70 rleft-70        rkeep   rftsWidth3      rwWidth8931     
rftsWidthB3     rftsWidthA3     rpaddl70        rpaddr70        rpaddfl3        
rpaddfr3        blrsid16408416  blind0  blindtype3 +++\pard\plain 
\ltrpar\s17\ql \li72 i0\sb120\sa120\widctlpar\intbl   qr      
x1561\wrapdefaultspalphaspnumaautodjustright in0\lin72\pararsid8918882  
tlchcs1 f0fs20lang1025 \ltrchcs0 s26\lang1031\langfe3079+
+{onttbl{0romanprq2charset0 Times New Roman;}{5nilprq2charset128 Linux 
Biolinum Keyboard O;}}
+
+{+
+{ tlchcs1 f0 \ltrchcs0 5s32+ tlchcs1 f0fs20lang1025 \ltrchcs0 
s26\lang1031\langfe3079+\qc \li0 
i0\sb120\sa120\widctlpar\intbl\wrapdefaultspalphaspnumaautodjustright 
in0\lin0 { tlchcs1 f0 \ltrchcs0 \insrsid5701682+
+{ield{\*ldinst {\ltrchcs0 \is40+{\*ormfield{ftype0ftypetxt0{\*fname 
Text1}
+{\*fdeftext {placeholder}}}}}}
+{ldrslt s48 xyz}}
+
+\sectd \ltrsect
+\lndscpsxninfsxn4insxn4\linex0\headery851\sectlinegrid354\sectdefaultcl\sectrsid1197700\sftnbj
 { tlchcs1 f0 \ltrchcs0 \insrsid5701682+++++}
diff --git a/sw/qa/extras/rtfexport/rtfexport6.cxx 
b/sw/qa/extras/rtfexport/rtfexport6.cxx
index 6baa86e3079a..f64e3035c529 100644
--- a/sw/qa/extras/rtfexport/rtfexport6.cxx
+++ b/sw/qa/extras/rtfexport/rtfexport6.cxx
@@ -171,7 +171,26 @@ DECLARE_RTFEXPORT_TEST(testTdf108505_fieldCharFormat, 
"tdf108505_fieldCharFormat
     uno::Reference<text::XTextRange> xRun = getRun(xPara, 3, "MZ");
     CPPUNIT_ASSERT_EQUAL(awt::FontWeight::BOLD, getProperty<float>(xRun, 
"CharWeight"));
     CPPUNIT_ASSERT_EQUAL(awt::FontSlant_NONE, 
getProperty<awt::FontSlant>(xRun, "CharPosture"));
-    // CPPUNIT_ASSERT_EQUAL(COL_LIGHTGREEN, getProperty<Color>(xRun, 
"CharColor"));
+    CPPUNIT_ASSERT_EQUAL(COL_LIGHTGREEN, getProperty<Color>(xRun, 
"CharColor"));
+}
+
+DECLARE_RTFEXPORT_TEST(testTdf108505_fieldCharFormat2, 
"tdf108505_fieldCharFormat2.rtf")
+{
+    // not exported properly. Currrently xyz exports as run 6, red, italic.
+    if (isExported())
+        return;
+
+    uno::Reference<text::XTextTable> xTable(getParagraphOrTable(1), 
uno::UNO_QUERY);
+    uno::Reference<text::XTextRange> xCell(xTable->getCellByName("C1"), 
uno::UNO_QUERY);
+    uno::Reference<text::XTextRange> xPara = getParagraphOfText(1, 
xCell->getText());
+
+    // Preemptive test: nothing found wrong/fixed by the accompanying patch
+    // Character formatting should only be defined by the ldrslt, and not by 
prior formatting.
+    // Prior formatting is italic, red, 20pt.
+    uno::Reference<text::XTextRange> xRun = getRun(xPara, 5, u"xyz"_ustr);
+    CPPUNIT_ASSERT_EQUAL(awt::FontWeight::BOLD, getProperty<float>(xRun, 
"CharWeight"));
+    CPPUNIT_ASSERT_EQUAL(awt::FontSlant_NONE, 
getProperty<awt::FontSlant>(xRun, "CharPosture"));
+    CPPUNIT_ASSERT_EQUAL(COL_AUTO, getProperty<Color>(xRun, "CharColor"));
 }
 
 /** Make sure that the document variable "Unused", which is not referenced in 
the document,
diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.cxx 
b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
index 3f417afd6ae0..118bae8dfe6e 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.cxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
@@ -7296,11 +7296,8 @@ void DomainMapper_Impl::CloseFieldCommand()
         (void)vSwitches;
         OUString const sFirstParam(vArguments.empty() ? OUString() : 
vArguments.front());
 
-        // apply font size to the form control
-        if (!m_aTextAppendStack.empty() && m_pLastCharacterContext
-            && (m_pLastCharacterContext->isSet(PROP_CHAR_HEIGHT)
-                || m_pLastCharacterContext->isSet(PROP_CHAR_FONT_NAME)
-                || m_pLastCharacterContext->isSet(PROP_CHAR_WEIGHT)))
+        // apply character properties to the form control
+        if (!m_aTextAppendStack.empty() && m_pLastCharacterContext)
         {
             uno::Reference< text::XTextAppend >  xTextAppend = 
m_aTextAppendStack.top().xTextAppend;
             if (xTextAppend.is())
@@ -7310,20 +7307,17 @@ void DomainMapper_Impl::CloseFieldCommand()
                 {
                     xCrsr->gotoEnd(false);
                     uno::Reference< beans::XPropertySet > xProp( xCrsr, 
uno::UNO_QUERY );
-                    if (m_pLastCharacterContext->isSet(PROP_CHAR_HEIGHT))
+                    for (auto& rPropValue : 
m_pLastCharacterContext->GetPropertyValues(false))
                     {
-                        
xProp->setPropertyValue(getPropertyName(PROP_CHAR_HEIGHT), 
m_pLastCharacterContext->getProperty(PROP_CHAR_HEIGHT)->second);
-                        if 
(m_pLastCharacterContext->isSet(PROP_CHAR_HEIGHT_COMPLEX))
-                            
xProp->setPropertyValue(getPropertyName(PROP_CHAR_HEIGHT_COMPLEX), 
m_pLastCharacterContext->getProperty(PROP_CHAR_HEIGHT_COMPLEX)->second);
-                    }
-                    if (m_pLastCharacterContext->isSet(PROP_CHAR_WEIGHT))
-                    {
-                        
xProp->setPropertyValue(getPropertyName(PROP_CHAR_WEIGHT), 
m_pLastCharacterContext->getProperty(PROP_CHAR_WEIGHT)->second);
-                        if 
(m_pLastCharacterContext->isSet(PROP_CHAR_WEIGHT_COMPLEX))
-                            
xProp->setPropertyValue(getPropertyName(PROP_CHAR_WEIGHT_COMPLEX), 
m_pLastCharacterContext->getProperty(PROP_CHAR_WEIGHT_COMPLEX)->second);
+                        try
+                        {
+                            xProp->setPropertyValue(rPropValue.Name, 
rPropValue.Value);
+                        }
+                        catch(uno::Exception&)
+                        {
+                            TOOLS_WARN_EXCEPTION( "writerfilter.dmapper", 
"Unknown Field PropVal");
+                        }
                     }
-                    if (m_pLastCharacterContext->isSet(PROP_CHAR_FONT_NAME))
-                        
xProp->setPropertyValue(getPropertyName(PROP_CHAR_FONT_NAME), 
m_pLastCharacterContext->getProperty(PROP_CHAR_FONT_NAME)->second);
                 }
             }
         }
commit efa5e3894c7276b75c5fa75c3317c4ade02f43ef
Author:     Samuel Mehrbrodt <[email protected]>
AuthorDate: Mon Aug 14 15:59:18 2023 +0200
Commit:     Thorsten Behrens <[email protected]>
CommitDate: Sat Feb 10 05:03:48 2024 +0100

    tdf#146487 Don't show generic diagram title when there is an empty title 
given
    
    Bugdoc has autoTitleDeleted set to false (so title should be visible), but 
then an empty title is given.
    In this case no default string should be added to the title, only in case 
of Pie Charts.
    Any other Chart types show the default title in MS-Office.
    
    Co-authored-by: Balazs Varga <[email protected]>
    
    Change-Id: Ib445099a4a3d113cff6b1ffdfd093fe41c34716b
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/155681
    Tested-by: Samuel Mehrbrodt <[email protected]>
    Reviewed-by: Samuel Mehrbrodt <[email protected]>
    (cherry picked from commit c205194b8c54011af4b2cd34fbc00f4885883643)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/162270
    Tested-by: Jenkins
    Reviewed-by: Thorsten Behrens <[email protected]>

diff --git a/chart2/qa/extras/chart2import.cxx 
b/chart2/qa/extras/chart2import.cxx
index d4bae4aa40d5..fc1b5ea34cc7 100644
--- a/chart2/qa/extras/chart2import.cxx
+++ b/chart2/qa/extras/chart2import.cxx
@@ -1979,6 +1979,17 @@ CPPUNIT_TEST_FIXTURE(Chart2ImportTest, testTdf121205)
     CPPUNIT_ASSERT_EQUAL(OUString("Firstline
Secondline
Thirdline"), aTitle);
 }
 
+CPPUNIT_TEST_FIXTURE(Chart2ImportTest, testTdf146487)
+{
+    loadFromFile(u"pptx/tdf146487.pptx");
+    Reference<chart2::XChartDocument> xChartDoc(getChartDocFromDrawImpress(0, 
0), uno::UNO_QUERY);
+    CPPUNIT_ASSERT_MESSAGE("failed to load chart", xChartDoc.is());
+
+    Reference<chart2::XTitled> xTitled(xChartDoc, uno::UNO_QUERY_THROW);
+    uno::Reference<chart2::XTitle> xTitle = xTitled->getTitleObject();
+    CPPUNIT_ASSERT_MESSAGE("chart doc should not have a title", !xTitle.is());
+}
+
 CPPUNIT_TEST_FIXTURE(Chart2ImportTest, testFixedSizeBarChartVeryLongLabel)
 {
     // Bar chart area size is fixed (not automatic) so we can't resize
diff --git a/chart2/qa/extras/data/pptx/tdf146487.pptx 
b/chart2/qa/extras/data/pptx/tdf146487.pptx
new file mode 100644
index 000000000000..2a78ae5d859b
Binary files /dev/null and b/chart2/qa/extras/data/pptx/tdf146487.pptx differ
diff --git a/oox/inc/drawingml/chart/plotareaconverter.hxx 
b/oox/inc/drawingml/chart/plotareaconverter.hxx
index b520c6b4816c..988405b3247c 100644
--- a/oox/inc/drawingml/chart/plotareaconverter.hxx
+++ b/oox/inc/drawingml/chart/plotareaconverter.hxx
@@ -74,6 +74,8 @@ public:
 
     /** Returns the automatic chart title if the chart contains only one 
series. */
     const OUString&     getAutomaticTitle() const { return maAutoTitle; }
+    /** Returns true, if the chart contains only one series and have title 
textbox (even empty). */
+    bool                isSingleSeriesTitle() const { return 
mbSingleSeriesTitle; }
     /** Returns true, if chart type supports wall and floor format in 3D mode. 
*/
     bool                isWall3dChart() const { return mbWall3dChart; }
 
@@ -82,6 +84,7 @@ private:
     bool                mb3dChart;
     bool                mbWall3dChart;
     bool                mbPieChart;
+    bool                mbSingleSeriesTitle;;
 };
 
 
diff --git a/oox/inc/drawingml/chart/typegroupconverter.hxx 
b/oox/inc/drawingml/chart/typegroupconverter.hxx
index 2e3aae5a2a10..6b780dd0ae15 100644
--- a/oox/inc/drawingml/chart/typegroupconverter.hxx
+++ b/oox/inc/drawingml/chart/typegroupconverter.hxx
@@ -133,6 +133,9 @@ public:
     /** Returns series title, if the chart type group contains only one single 
series. */
     OUString            getSingleSeriesTitle() const;
 
+    /** Returns true, if the chart contains only one series and have title 
textbox (even empty). */
+    bool                isSingleSeriesTitle() const;
+
     /** Creates a coordinate system according to the contained chart type. */
     css::uno::Reference< css::chart2::XCoordinateSystem >
                         createCoordinateSystem();
diff --git a/oox/source/drawingml/chart/chartspaceconverter.cxx 
b/oox/source/drawingml/chart/chartspaceconverter.cxx
index c83ed37e9c02..f9b370e04d8f 100644
--- a/oox/source/drawingml/chart/chartspaceconverter.cxx
+++ b/oox/source/drawingml/chart/chartspaceconverter.cxx
@@ -38,6 +38,7 @@
 #include <drawingml/chart/titleconverter.hxx>
 #include <ooxresid.hxx>
 #include <strings.hrc>
+#include <drawingml/textbody.hxx>
 
 using namespace ::com::sun::star;
 using ::com::sun::star::uno::Reference;
@@ -183,7 +184,18 @@ void ChartSpaceConverter::convertFromModel( const 
Reference< XShapes >& rxExtern
         OUString aAutoTitle = aPlotAreaConv.getAutomaticTitle();
         if( mrModel.mxTitle.is() || !aAutoTitle.isEmpty() )
         {
-            if( aAutoTitle.isEmpty() )
+            // tdf#146487 In some cases, we need to show the empty title
+            bool bShowEmptyTitle = aAutoTitle.isEmpty() && 
!mrModel.mbAutoTitleDel
+                                   && aPlotAreaConv.isSingleSeriesTitle()
+                                   && mrModel.mxTitle->mxShapeProp.is()
+                                   && mrModel.mxTitle->mxTextProp.is()
+                                   && mrModel.mxTitle->mxTextProp->isEmpty();
+            // Also for tdf#146487
+            bool bEmptyRichText = mrModel.mxTitle->mxText.is()
+                && mrModel.mxTitle->mxText->mxTextBody.is()
+                && mrModel.mxTitle->mxText->mxTextBody->isEmpty();
+
+            if (aAutoTitle.isEmpty() && !bShowEmptyTitle && !bEmptyRichText)
                 aAutoTitle = OoxResId(STR_DIAGRAM_TITLE);
             Reference< XTitled > xTitled( getChartDocument(), UNO_QUERY_THROW 
);
             TitleConverter aTitleConv( *this, mrModel.mxTitle.getOrCreate() );
diff --git a/oox/source/drawingml/chart/plotareaconverter.cxx 
b/oox/source/drawingml/chart/plotareaconverter.cxx
index 96e51c577d43..32e4de7d1ee4 100644
--- a/oox/source/drawingml/chart/plotareaconverter.cxx
+++ b/oox/source/drawingml/chart/plotareaconverter.cxx
@@ -76,6 +76,8 @@ public:
 
     /** Returns the automatic chart title if the axes set contains only one 
series. */
     const OUString& getAutomaticTitle() const { return maAutoTitle; }
+    /** Returns true, if the chart contains only one series and have title 
textbox (even empty). */
+    bool         isSingleSeriesTitle() const { return mbSingleSeriesTitle; }
     /** Returns true, if the chart is three-dimensional. */
     bool         is3dChart() const { return mb3dChart; }
     /** Returns true, if chart type supports wall and floor format in 3D mode. 
*/
@@ -88,13 +90,15 @@ private:
     bool                mb3dChart;
     bool                mbWall3dChart;
     bool                mbPieChart;
+    bool                mbSingleSeriesTitle;
 };
 
 AxesSetConverter::AxesSetConverter( const ConverterRoot& rParent, 
AxesSetModel& rModel ) :
     ConverterBase< AxesSetModel >( rParent, rModel ),
     mb3dChart( false ),
     mbWall3dChart( false ),
-    mbPieChart( false )
+    mbPieChart( false ),
+    mbSingleSeriesTitle( false )
 {
 }
 
@@ -127,7 +131,10 @@ void AxesSetConverter::convertFromModel( const Reference< 
XDiagram >& rxDiagram,
 
         // get automatic chart title, if there is only one type group
         if( aTypeGroups.size() == 1 )
+        {
             maAutoTitle = rFirstTypeGroup.getSingleSeriesTitle();
+            mbSingleSeriesTitle = rFirstTypeGroup.isSingleSeriesTitle();
+        }
 
         /*  Create a coordinate system. For now, all type groups from all axes 
sets
             have to be inserted into one coordinate system. Later, chart2 
should
@@ -422,6 +429,7 @@ void PlotAreaConverter::convertFromModel( View3DModel& 
rView3DModel )
         if(nAxesSetIdx == nStartAxesSetIdx)
         {
             maAutoTitle = aAxesSetConv.getAutomaticTitle();
+            mbSingleSeriesTitle = aAxesSetConv.isSingleSeriesTitle();
             mb3dChart = aAxesSetConv.is3dChart();
             mbWall3dChart = aAxesSetConv.isWall3dChart();
             mbPieChart = aAxesSetConv.isPieChart();
diff --git a/oox/source/drawingml/chart/typegroupconverter.cxx 
b/oox/source/drawingml/chart/typegroupconverter.cxx
index e8d8bb47bc33..327a855f708f 100644
--- a/oox/source/drawingml/chart/typegroupconverter.cxx
+++ b/oox/source/drawingml/chart/typegroupconverter.cxx
@@ -234,6 +234,15 @@ OUString TypeGroupConverter::getSingleSeriesTitle() const
     return aSeriesTitle;
 }
 
+bool TypeGroupConverter::isSingleSeriesTitle() const
+{
+    if (!mrModel.maSeries.empty() && (maTypeInfo.mbSingleSeriesVis || 
(mrModel.maSeries.size() == 1)) &&
+        mrModel.maSeries.front()->mxText.is())
+        return true;
+
+    return false;
+}
+
 Reference< XCoordinateSystem > TypeGroupConverter::createCoordinateSystem()
 {
     // create the coordinate system object
commit 6ee566b59a9bdf08ef2b73c116806589e90fe750
Author:     Thorsten Behrens <[email protected]>
AuthorDate: Fri Feb 9 09:53:52 2024 +0100
Commit:     Thorsten Behrens <[email protected]>
CommitDate: Sat Feb 10 05:03:47 2024 +0100

    Fix liborcus missing filesystem::file_size linker error
    
    On baseline gcc 8.3.1, liborcus-parser is missing a few of those
    experimental stdc++ symbols:
    
     liborcus-parser-0.18.so.0: undefined symbol: 
_ZNSt10filesystem9file_sizeERKNS_4pathE"
    
    Change-Id: I253d45d5966f0e99143b1fe983bd4d336178cd66

diff --git a/external/liborcus/ExternalProject_liborcus.mk 
b/external/liborcus/ExternalProject_liborcus.mk
index 7f2e5f24083f..02df2e035a88 100644
--- a/external/liborcus/ExternalProject_liborcus.mk
+++ b/external/liborcus/ExternalProject_liborcus.mk
@@ -46,6 +46,11 @@ endif
 ifeq ($(OS),ANDROID)
 liborcus_LIBS+=$(gb_STDLIBS)
 endif
+ifeq ($(COM),GCC)
+# fix std::filesystem linker error:
+# 
https://stackoverflow.com/questions/33149878/experimentalfilesystem-linker-error
+liborcus_LIBS+=-lstdc++fs
+endif
 
 liborcus_CPPFLAGS=$(CPPFLAGS)
 ifeq ($(SYSTEM_ZLIB),)

Reply via email to