tdf#128428 RTF: clean-up for longer space sequence mode

Fix regressions from commit 24b04db5a63b57a74e58a7616091437ad68548ac
(tdf#123703 RTF import: fix length of space character sequence).

It seems, longer space sequence is an obsolete RTF-only feature, eg.
new RTF documents created in MSO don't use it, but old RTF documents
still keep their layout (only in RTF).

- Only old-style (without \stshfdbch) or compatible (\stshfdbch31505)
  RTF documents get longer space sequences using a one-time conversion;

- because Writer always exports old-style RTF documents, to avoid of
  enlargement of space sequences of new-style RTF documents later, RTF
  import doesn't modify the RTF documents saved in Writer (checking
  \generator);

- text in monospaced font "Courier New" doesn't get longer space
  sequence (despite its \prq2 (not monospaced) font setting).

Change-Id: I308ab06db57a2db5deec1d4c4573da3317cad8e9
Reviewed-on: https://gerrit.libreoffice.org/82145
Tested-by: Jenkins
Reviewed-by: László Németh <nemeth@numbertext.org>
diff --git a/sw/qa/extras/rtfexport/data/tdf123703_compatible.rtf b/sw/qa/extras/rtfexport/data/tdf123703_compatible.rtf
new file mode 100644
index 0000000..3713b5f
--- /dev/null
+++ b/sw/qa/extras/rtfexport/data/tdf123703_compatible.rtf
@@ -0,0 +1,37 @@
{\rtf1\adeflang1025\ansi\ansicpg1250\uc1\adeff31507\deff0\stshfdbch31505\stshfloch31506\stshfhich31506\stshfbi31507\deflang1038\deflangfe1038\themelang1038\themelangfe0\themelangcs0{\fonttbl{\f0\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\f2\fbidi \fmodern\fcharset0\fprq1{\*\panose 02070309020205020404}Courier New;}
{\f11\fbidi \fmodern\fcharset128\fprq1{\*\panose 02020609040205080304}MS Mincho{\*\falt \'82\'6c\'82\'72 \'96\'be\'92\'a9};}{\f11\fbidi \fmodern\fcharset128\fprq1{\*\panose 02020609040205080304}MS Mincho{\*\falt \'82\'6c\'82\'72 \'96\'be\'92\'a9};}
{\f39\fbidi \fswiss\fcharset0\fprq2{\*\panose 020f0502020204030204}Calibri;}{\f128\fbidi \fmodern\fcharset128\fprq1{\*\panose 02020609040205080304}@MS Mincho;}{\flomajor\f31500\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}
{\fdbmajor\f31501\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\fhimajor\f31502\fbidi \fswiss\fcharset0\fprq2{\*\panose 020f0302020204030204}Calibri Light;}
{\fbimajor\f31503\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\flominor\f31504\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}
{\fdbminor\f31505\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\fhiminor\f31506\fbidi \fswiss\fcharset0\fprq2{\*\panose 020f0502020204030204}Calibri;}
{\fbiminor\f31507\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\f369\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\f370\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}}
word                                                                                                                  word2\par
word                                                                                                                  word2\par
word                                                                                                                  word2\par
word                                                                                                                  word2\par
word                                                                                                                  word2\par
word                                                                                                                  word2\par
word                                                                                                                  word2\par
word                                                                                                                  word2\par
word                                                                                                                  word2\par
word                                                                                                                  word2\par
word                                                                                                                  word2\par
word                                                                                                                  word2\par
word                                                                                                                  word2\par
word                                                                                                                  word2\par
word                                                                                                                  word2\par
word                                                                                                                  word2\par
word                                                                                                                  word2\par
word                                                                                                                  word2\par
word                                                                                                                  word2\par
word                                                                                                                  word2\par
word                                                                                                                  word2\par
word                                                                                                                  word2\par
word                                                                                                                  word2\par
word                                                                                                                  word2\par
word                                                                                                                  word2\par
word                                                                                                                  word2\par
word                                                                                                                  word2\par
word                                                                                                                  word2\par
word                                                                                                                  word2\par
}
diff --git a/sw/qa/extras/rtfexport/data/tdf123703_stshfdbch.rtf b/sw/qa/extras/rtfexport/data/tdf123703_stshfdbch.rtf
new file mode 100644
index 0000000..7d074c4
--- /dev/null
+++ b/sw/qa/extras/rtfexport/data/tdf123703_stshfdbch.rtf
@@ -0,0 +1,31 @@
{\rtf1\adeflang1025\ansi\ansicpg1252\uc1\adeff0\deff0\stshfdbch0\stshfloch0\stshfhich0\stshfbi0\deflang1036\deflangfe1036{\fonttbl{\f0\froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}}
word                                                                                                                  word2\par
word                                                                                                                  word2\par
word                                                                                                                  word2\par
word                                                                                                                  word2\par
word                                                                                                                  word2\par
word                                                                                                                  word2\par
word                                                                                                                  word2\par
word                                                                                                                  word2\par
word                                                                                                                  word2\par
word                                                                                                                  word2\par
word                                                                                                                  word2\par
word                                                                                                                  word2\par
word                                                                                                                  word2\par
word                                                                                                                  word2\par
word                                                                                                                  word2\par
word                                                                                                                  word2\par
word                                                                                                                  word2\par
word                                                                                                                  word2\par
word                                                                                                                  word2\par
word                                                                                                                  word2\par
word                                                                                                                  word2\par
word                                                                                                                  word2\par
word                                                                                                                  word2\par
word                                                                                                                  word2\par
word                                                                                                                  word2\par
word                                                                                                                  word2\par
word                                                                                                                  word2\par
word                                                                                                                  word2\par
word                                                                                                                  word2\par
}
diff --git a/sw/qa/extras/rtfexport/data/tdf128428_compatible_monospaced.rtf b/sw/qa/extras/rtfexport/data/tdf128428_compatible_monospaced.rtf
new file mode 100644
index 0000000..24f0a66
--- /dev/null
+++ b/sw/qa/extras/rtfexport/data/tdf128428_compatible_monospaced.rtf
@@ -0,0 +1,38 @@
{\rtf1\adeflang1025\ansi\ansicpg1250\uc1\adeff31507\deff0\stshfdbch31505\stshfloch31506\stshfhich31506\stshfbi31507\deflang1038\deflangfe1038\themelang1038\themelangfe0\themelangcs0{\fonttbl{\f0\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\f2\fbidi \fmodern\fcharset0\fprq1{\*\panose 02070309020205020404}Courier New;}
{\f11\fbidi \fmodern\fcharset128\fprq1{\*\panose 02020609040205080304}MS Mincho{\*\falt \'82\'6c\'82\'72 \'96\'be\'92\'a9};}{\f11\fbidi \fmodern\fcharset128\fprq1{\*\panose 02020609040205080304}MS Mincho{\*\falt \'82\'6c\'82\'72 \'96\'be\'92\'a9};}
{\f39\fbidi \fswiss\fcharset0\fprq2{\*\panose 020f0502020204030204}Calibri;}{\f128\fbidi \fmodern\fcharset128\fprq1{\*\panose 02020609040205080304}@MS Mincho;}{\flomajor\f31500\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}
{\fdbmajor\f31501\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\fhimajor\f31502\fbidi \fswiss\fcharset0\fprq2{\*\panose 020f0302020204030204}Calibri Light;}
{\fbimajor\f31503\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\flominor\f31504\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}
{\fdbminor\f31505\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\fhiminor\f31506\fbidi \fswiss\fcharset0\fprq2{\*\panose 020f0502020204030204}Calibri;}
{\fbiminor\f31507\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\f369\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\f370\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}}
\af2 
word                                                      word2\par
word                                                      word2\par
word                                                      word2\par
word                                                      word2\par
word                                                      word2\par
word                                                      word2\par
word                                                      word2\par
word                                                      word2\par
word                                                      word2\par
word                                                      word2\par
word                                                      word2\par
word                                                      word2\par
word                                                      word2\par
word                                                      word2\par
word                                                      word2\par
word                                                      word2\par
word                                                      word2\par
word                                                      word2\par
word                                                      word2\par
word                                                      word2\par
word                                                      word2\par
word                                                      word2\par
word                                                      word2\par
word                                                      word2\par
word                                                      word2\par
word                                                      word2\par
word                                                      word2\par
word                                                      word2\par
word                                                      word2\par
}
diff --git a/sw/qa/extras/rtfexport/data/tdf128428_monospaced.rtf b/sw/qa/extras/rtfexport/data/tdf128428_monospaced.rtf
new file mode 100644
index 0000000..18c9381
--- /dev/null
+++ b/sw/qa/extras/rtfexport/data/tdf128428_monospaced.rtf
@@ -0,0 +1,33 @@
{\rtf1{\fonttbl{\f0\froman\fcharset0\fprq2{\*\panose 02020603050405020304}Courier New;}}
\af0
word                                                      word2\par
word                                                      word2\par
word                                                      word2\par
word                                                      word2\par
word                                                      word2\par
word                                                      word2\par
word                                                      word2\par
word                                                      word2\par
word                                                      word2\par
word                                                      word2\par
word                                                      word2\par
word                                                      word2\par
word                                                      word2\par
word                                                      word2\par
word                                                      word2\par
word                                                      word2\par
word                                                      word2\par
word                                                      word2\par
word                                                      word2\par
word                                                      word2\par
word                                                      word2\par
word                                                      word2\par
word                                                      word2\par
word                                                      word2\par
word                                                      word2\par
word                                                      word2\par
word                                                      word2\par
word                                                      word2\par
word                                                      word2\par
}
}
diff --git a/sw/qa/extras/rtfexport/rtfexport3.cxx b/sw/qa/extras/rtfexport/rtfexport3.cxx
index 8845e89..749da31 100644
--- a/sw/qa/extras/rtfexport/rtfexport3.cxx
+++ b/sw/qa/extras/rtfexport/rtfexport3.cxx
@@ -265,6 +265,35 @@ DECLARE_RTFEXPORT_TEST(testTdf123703, "tdf123703.rtf")
#endif
}

DECLARE_RTFEXPORT_TEST(testTdf123703_stshfdbch, "tdf123703_stshfdbch.rtf")
{
    // still 1 here
    CPPUNIT_ASSERT_EQUAL(1, getPages());
}

DECLARE_RTFEXPORT_TEST(testTdf123703_compatible, "tdf123703_compatible.rtf")
{
#if !defined(MACOSX)
    // in the case of compatibility font id 31505
    CPPUNIT_ASSERT_EQUAL(2, getPages());
#else
    // still 1 here
    CPPUNIT_ASSERT_EQUAL(1, getPages());
#endif
}

DECLARE_RTFEXPORT_TEST(testTdf128428_monospaced, "tdf128428_monospaced.rtf")
{
    // still 1 here
    CPPUNIT_ASSERT_EQUAL(1, getPages());
}

DECLARE_RTFEXPORT_TEST(testTdf128428_compatible_monospaced, "tdf128428_compatible_monospaced.rtf")
{
    // still 1 here
    CPPUNIT_ASSERT_EQUAL(1, getPages());
}

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 6fe0624..89de28b 100644
--- a/sw/source/filter/ww8/wrtw8nds.cxx
+++ b/sw/source/filter/ww8/wrtw8nds.cxx
@@ -1676,17 +1676,6 @@ OUString SwWW8AttrIter::GetSnippet(const OUString &rStr, sal_Int32 nCurrentPos,
    aSnippet = aSnippet.replace(CHAR_HARDHYPHEN, 0x1e);
    aSnippet = aSnippet.replace(CHAR_SOFTHYPHEN, 0x1f);

    // tdf#123703 revert import workaround for longer space characters in consecutive spaces
    sal_Int32 nPos;
    if ((nPos = aSnippet.indexOf(0x2006)) > -1)
    {
        const sal_Unicode aExtraSpace[5] = { 0x2006, 0x20, 0x2006, 0x20, 0 };
        const sal_Unicode aExtraSpace2[4] = { 0x20, 0x2006, 0x20, 0 };
        OUString sDoubleSpace("  ");
        aSnippet = aSnippet.replaceAll(aExtraSpace, sDoubleSpace, nPos)
                           .replaceAll(aExtraSpace2, sDoubleSpace);
    }

    m_rExport.m_aCurrentCharPropStarts.push( nCurrentPos );
    const SfxPoolItem &rItem = GetItem(RES_CHRATR_CASEMAP);

diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.cxx b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
index c787d7b..be549f1 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.cxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
@@ -1884,11 +1884,18 @@ void DomainMapper_Impl::appendTextPortion( const OUString& rString, const Proper
                else
                {
#if !defined(MACOSX) // TODO: check layout differences and support all platforms, if needed
                    sal_Int32 nPos;
                    sal_Int32 nPos = 0;
                    OUString sFontName;
                    OUString sDoubleSpace("  ");
                    if (IsRTFImport() && !IsOpenFieldCommand() && (nPos = rString.indexOf(sDoubleSpace)) > -1)
                    PropertyMapPtr pContext = GetTopContextOfType(CONTEXT_CHARACTER);
                    // tdf#123703 workaround for longer space sequences of the old or compatible RTF documents
                    if (GetSettingsTable()->GetLongerSpaceSequence() && !IsOpenFieldCommand() && (nPos = rString.indexOf(sDoubleSpace)) != -1 &&
                        // monospaced fonts have no longer space sequences, regardless of \fprq2 (not monospaced) font setting
                        // fix for the base monospaced font Courier
                        (!pContext || !pContext->isSet(PROP_CHAR_FONT_NAME) ||
                            ((pContext->getProperty(PROP_CHAR_FONT_NAME)->second >>= sFontName) && sFontName.indexOf("Courier") == -1)))
                    {
                        // tdf#123703 an RTF space character is longer by an extra six-em-space in a space sequence,
                        // an RTF space character is longer by an extra six-em-space in an old-style RTF space sequence,
                        // insert them to keep RTF document layout formatted by consecutive spaces
                        const sal_Unicode aExtraSpace[5] = { 0x2006, 0x20, 0x2006, 0x20, 0 };
                        const sal_Unicode aExtraSpace2[4] = { 0x20, 0x2006, 0x20, 0 };
diff --git a/writerfilter/source/dmapper/SettingsTable.cxx b/writerfilter/source/dmapper/SettingsTable.cxx
index a861ac7..c71850b 100644
--- a/writerfilter/source/dmapper/SettingsTable.cxx
+++ b/writerfilter/source/dmapper/SettingsTable.cxx
@@ -246,6 +246,7 @@ struct SettingsTable_Impl
    bool                m_bAutoHyphenation;
    sal_Int16           m_nHyphenationZone;
    bool                m_bWidowControl;
    bool                m_bLongerSpaceSequence;
    bool                m_bSplitPgBreakAndParaMark;
    bool                m_bMirrorMargin;
    bool                m_bDoNotExpandShiftReturn;
@@ -280,6 +281,7 @@ struct SettingsTable_Impl
    , m_bAutoHyphenation(false)
    , m_nHyphenationZone(0)
    , m_bWidowControl(false)
    , m_bLongerSpaceSequence(false)
    , m_bSplitPgBreakAndParaMark(false)
    , m_bMirrorMargin(false)
    , m_bDoNotExpandShiftReturn(false)
@@ -298,9 +300,13 @@ SettingsTable::SettingsTable(const DomainMapper& rDomainMapper)
, LoggedTable("SettingsTable")
, m_pImpl( new SettingsTable_Impl )
{
    // HTML paragraph auto-spacing is opt-in for RTF, opt-out for OOXML.
    if (rDomainMapper.IsRTFImport())
    {
        // HTML paragraph auto-spacing is opt-in for RTF, opt-out for OOXML.
        m_pImpl->m_bDoNotUseHTMLParagraphAutoSpacing = true;
        // Longer space sequence is opt-in for RTF, and not in OOXML.
        m_pImpl->m_bLongerSpaceSequence = true;
    }
}

SettingsTable::~SettingsTable()
@@ -547,6 +553,9 @@ void SettingsTable::lcl_sprm(Sprm& rSprm)
    case NS_ooxml::LN_CT_Settings_widowControl:
        m_pImpl->m_bWidowControl = nIntValue;
        break;
    case NS_ooxml::LN_CT_Settings_longerSpaceSequence:
        m_pImpl->m_bLongerSpaceSequence = nIntValue;
        break;
    case NS_ooxml::LN_CT_Compat_doNotExpandShiftReturn:
        m_pImpl->m_bDoNotExpandShiftReturn = true;
        break;
@@ -753,6 +762,11 @@ sal_Int32 SettingsTable::GetWordCompatibilityMode() const
    return -1; // Word compatibility mode not found
}

bool SettingsTable::GetLongerSpaceSequence() const
{
    return m_pImpl->m_bLongerSpaceSequence;
}

}//namespace dmapper
} //namespace writerfilter

diff --git a/writerfilter/source/dmapper/SettingsTable.hxx b/writerfilter/source/dmapper/SettingsTable.hxx
index 631ab5d..8d717c7 100644
--- a/writerfilter/source/dmapper/SettingsTable.hxx
+++ b/writerfilter/source/dmapper/SettingsTable.hxx
@@ -77,6 +77,7 @@ class SettingsTable : public LoggedProperties, public LoggedTable
    bool GetDoNotExpandShiftReturn() const;
    bool GetNoColumnBalance() const;
    bool GetProtectForm() const;
    bool GetLongerSpaceSequence() const;
    sal_Int16 GetHypenationZone() const;

    css::uno::Sequence<css::beans::PropertyValue> const & GetThemeFontLangProperties() const;
diff --git a/writerfilter/source/ooxml/model.xml b/writerfilter/source/ooxml/model.xml
index f4fdf41..66eedca 100644
--- a/writerfilter/source/ooxml/model.xml
+++ b/writerfilter/source/ooxml/model.xml
@@ -65,6 +65,7 @@

  <!-- Present in RTF, but not in OOXML. -->
  <token tokenid="ooxml:CT_Settings_widowControl"/>
  <token tokenid="ooxml:CT_Settings_longerSpaceSequence"/>

  <namespace name="dml-stylesheet">
    <start name="theme"/>
diff --git a/writerfilter/source/rtftok/rtfcontrolwords.hxx b/writerfilter/source/rtftok/rtfcontrolwords.hxx
index 392b300..2b350e5 100644
--- a/writerfilter/source/rtftok/rtfcontrolwords.hxx
+++ b/writerfilter/source/rtftok/rtfcontrolwords.hxx
@@ -158,6 +158,7 @@ enum class Destination
    USERPROPS,
    PROPNAME,
    STATICVAL,
    GENERATOR,
};

enum RTFKeyword
diff --git a/writerfilter/source/rtftok/rtfdispatchdestination.cxx b/writerfilter/source/rtftok/rtfdispatchdestination.cxx
index 6cdaab1..79dfe91 100644
--- a/writerfilter/source/rtftok/rtfdispatchdestination.cxx
+++ b/writerfilter/source/rtftok/rtfdispatchdestination.cxx
@@ -632,6 +632,9 @@ RTFError RTFDocumentImpl::dispatchDestination(RTFKeyword nKeyword)
            case RTF_STATICVAL:
                m_aStates.top().setDestination(Destination::STATICVAL);
                break;
            case RTF_GENERATOR:
                m_aStates.top().setDestination(Destination::GENERATOR);
                break;
            default:
            {
                // Check if it's a math token.
diff --git a/writerfilter/source/rtftok/rtfdispatchvalue.cxx b/writerfilter/source/rtftok/rtfdispatchvalue.cxx
index 3b74342..4f7c71e 100644
--- a/writerfilter/source/rtftok/rtfdispatchvalue.cxx
+++ b/writerfilter/source/rtftok/rtfdispatchvalue.cxx
@@ -519,6 +519,12 @@ RTFError RTFDocumentImpl::dispatchValue(RTFKeyword nKeyword, int nParam)
        case RTF_DEFF:
            m_nDefaultFontIndex = nParam;
            break;
        case RTF_STSHFDBCH:
            // tdf#123703 switch off longer space sequence except in the case of the fixed compatibility setting font id 31505
            if (nParam != 31505)
                m_aSettingsTableSprms.set(NS_ooxml::LN_CT_Settings_longerSpaceSequence,
                                          new RTFValue(0));
            break;
        case RTF_DEFLANG:
        case RTF_ADEFLANG:
        {
diff --git a/writerfilter/source/rtftok/rtfdocumentimpl.cxx b/writerfilter/source/rtftok/rtfdocumentimpl.cxx
index 5a9d71d..d92730f 100644
--- a/writerfilter/source/rtftok/rtfdocumentimpl.cxx
+++ b/writerfilter/source/rtftok/rtfdocumentimpl.cxx
@@ -1467,6 +1467,12 @@ void RTFDocumentImpl::text(OUString& rString)
        case Destination::STATICVAL:
            m_aStates.top().appendDestinationText(rString);
            break;
        case Destination::GENERATOR:
            // don't enlarge space sequences again, if the document was saved in LibreOffice
            if (rString.indexOf("LibreOffice") != -1)
                m_aSettingsTableSprms.set(NS_ooxml::LN_CT_Settings_longerSpaceSequence,
                                          new RTFValue(0));
            break;
        default:
            bRet = false;
            break;