tdf#99474 close direct char fmt at end of para

When exporting to doc, ensure that the FKP entry for direct character
formatting is closed at the end of a paragraph, so that any direct
character formatting in the next paragraph does not apply to the
end-of-paragraph marker (CR).

Also revert the changes for i#119650 and tdf#87437 which targetted
more specific examples of this problem, as those issues should now be
covered by this fix.

Add a test case for the example from tdf#99474

Change-Id: I2cb482adb39a84f152707dafcb18f289ca0bd550
Reviewed-on: https://gerrit.libreoffice.org/24402
Tested-by: Jenkins <ci@libreoffice.org>
Reviewed-by: Miklos Vajna <vmiklos@collabora.co.uk>
diff --git a/sw/qa/extras/ww8export/data/tdf99474.odt b/sw/qa/extras/ww8export/data/tdf99474.odt
new file mode 100644
index 0000000..7530488
--- /dev/null
+++ b/sw/qa/extras/ww8export/data/tdf99474.odt
Binary files differ
diff --git a/sw/qa/extras/ww8export/ww8export.cxx b/sw/qa/extras/ww8export/ww8export.cxx
index 452c8c2..0d59e31 100644
--- a/sw/qa/extras/ww8export/ww8export.cxx
+++ b/sw/qa/extras/ww8export/ww8export.cxx
@@ -692,6 +692,34 @@ DECLARE_WW8EXPORT_TEST(testTdf94386, "tdf94386.odt")
    CPPUNIT_ASSERT((fSize.Width != lSize.Width) && (fSize.Height != lSize.Height));
}

DECLARE_WW8EXPORT_TEST(testTdf99474, "tdf99474.odt")
{
    // The bullet colour of paragraph #3 should be COL_AUTO
    auto xPara = getParagraph(3);
    uno::Reference<container::XIndexReplace> xNumRules(
        getProperty< uno::Reference<container::XIndexReplace> >(
            xPara, "NumberingRules"),
        uno::UNO_QUERY);
    int numLevel = getProperty<sal_Int32>(xPara, "NumberingLevel");
    uno::Sequence< beans::PropertyValue > aPropertyValues;
    xNumRules->getByIndex(numLevel) >>= aPropertyValues;
    OUString charStyleName;
    for(int j = 0 ; j< aPropertyValues.getLength() ; ++j)
    {
        auto aProp = aPropertyValues[j];
        if (aProp.Name == OUString("CharStyleName")) {
            charStyleName = aProp.Value.get<OUString>();
            break;
        }
    }
    CPPUNIT_ASSERT(charStyleName.getLength());
    uno::Reference<beans::XPropertySet> xStyle(
        getStyles("CharacterStyles")->getByName(charStyleName),
        uno::UNO_QUERY);
    ColorData charColor = getProperty<util::Color>(xStyle, "CharColor");
    CPPUNIT_ASSERT_EQUAL(COL_AUTO, charColor);
}

CPPUNIT_PLUGIN_IMPLEMENT();

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/filter/ww8/wrtw8nds.cxx b/sw/source/filter/ww8/wrtw8nds.cxx
index 0ca9415..3bbb733 100644
--- a/sw/source/filter/ww8/wrtw8nds.cxx
+++ b/sw/source/filter/ww8/wrtw8nds.cxx
@@ -2111,7 +2111,6 @@ void MSWordExportBase::OutputTextNode( const SwTextNode& rNode )

    sal_Int32 nAktPos = 0;
    sal_Int32 const nEnd = aStr.getLength();
    bool bIsEndOfCell = false;
    bool bIncludeEndOfParaCRInRedlineProperties = false;
    sal_Int32 nOpenAttrWithRange = 0;
    OUString aStringForImage("\001");
@@ -2120,9 +2119,6 @@ void MSWordExportBase::OutputTextNode( const SwTextNode& rNode )
    if ( pTextNodeInfo.get() != nullptr )
    {
        pTextNodeInfoInner = pTextNodeInfo->getFirstInner();
        if ( pTextNodeInfoInner && pTextNodeInfoInner->isEndOfCell() ) {
            bIsEndOfCell = true;
        }
    }

    do {
@@ -2332,11 +2328,6 @@ void MSWordExportBase::OutputTextNode( const SwTextNode& rNode )
                    }

                    WriteCR( pTextNodeInfoInner );

                    if ( (0 != nEnd) && bIsEndOfCell )
                    {
                        AttrOutput().OutputFKP(true);
                    }
                }
            }
        }
@@ -2364,7 +2355,12 @@ void MSWordExportBase::OutputTextNode( const SwTextNode& rNode )
                    "odd to see this happening, expected 0");
            }

            AttrOutput().OutputFKP();
            // !bIncludeEndOfParaCRInRedlineProperties implies we have just
            // emitted a CR, in which case we want to pass force=true to
            // OutputFKP to ensure that an FKP entry for direct character
            // formatting is written even if empty, so that the next one will
            // start after the CR.
            AttrOutput().OutputFKP(!bIncludeEndOfParaCRInRedlineProperties);

            if (bTextAtr || bAttrWithRange || bIncludeEndOfParaCRInRedlineProperties)
            {
diff --git a/sw/source/filter/ww8/ww8atr.cxx b/sw/source/filter/ww8/ww8atr.cxx
index cf98b68..e6f139e 100644
--- a/sw/source/filter/ww8/ww8atr.cxx
+++ b/sw/source/filter/ww8/ww8atr.cxx
@@ -951,8 +951,6 @@ void WW8AttributeOutput::EndParagraph( ww8::WW8TableNodeInfoInner::Pointer_t pTe
            TableInfoRow( pTextNodeInfoInner );
            m_rWW8Export.m_pPapPlc->AppendFkpEntry( m_rWW8Export.Strm().Tell(), m_rWW8Export.pO->size(), m_rWW8Export.pO->data());
            m_rWW8Export.pO->clear();
            //For Bug 119650, should break the properties of CHP PLC after a paragraph end.
            m_rWW8Export.m_pChpPlc->AppendFkpEntry( m_rWW8Export.Strm().Tell(), m_rWW8Export.pO->size(), m_rWW8Export.pO->data());
        }
    }
}