LCOV - code coverage report
Current view: top level - usr/local/src/libreoffice/writerfilter/source/rtftok - rtfdocumentimpl.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 2420 2840 85.2 %
Date: 2013-07-09 Functions: 81 83 97.6 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  */
       9             : 
      10             : #include <com/sun/star/beans/PropertyAttribute.hpp>
      11             : #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
      12             : #include <com/sun/star/drawing/XEnhancedCustomShapeDefaulter.hpp>
      13             : #include <com/sun/star/graphic/GraphicProvider.hpp>
      14             : #include <com/sun/star/io/UnexpectedEOFException.hpp>
      15             : #include <com/sun/star/lang/XServiceInfo.hpp>
      16             : #include <com/sun/star/text/XTextFrame.hpp>
      17             : #include <com/sun/star/text/SizeType.hpp>
      18             : #include <com/sun/star/text/HoriOrientation.hpp>
      19             : #include <com/sun/star/text/VertOrientation.hpp>
      20             : #include <com/sun/star/text/RelOrientation.hpp>
      21             : #include <com/sun/star/text/WrapTextMode.hpp>
      22             : #include <rtl/tencinfo.h>
      23             : #include <svl/lngmisc.hxx>
      24             : #include <unotools/ucbstreamhelper.hxx>
      25             : #include <unotools/streamwrap.hxx>
      26             : #include <com/sun/star/drawing/XDrawPageSupplier.hpp>
      27             : #include <rtl/ustring.hxx>
      28             : #include <svtools/grfmgr.hxx>
      29             : #include <vcl/graph.hxx>
      30             : #include <vcl/outdev.hxx>
      31             : #include <vcl/svapp.hxx>
      32             : #include <vcl/wmf.hxx>
      33             : #include <filter/msfilter/util.hxx>
      34             : #include <filter/msfilter/escherex.hxx>
      35             : #include <comphelper/string.hxx>
      36             : #include <tools/globname.hxx>
      37             : #include <comphelper/classids.hxx>
      38             : #include <comphelper/embeddedobjectcontainer.hxx>
      39             : #include <sfx2/sfxbasemodel.hxx>
      40             : 
      41             : #include <oox/mathml/import.hxx>
      42             : #include <doctok/sprmids.hxx> // NS_sprm namespace
      43             : #include <doctok/resourceids.hxx> // NS_rtf namespace
      44             : #include <ooxml/resourceids.hxx> // NS_ooxml namespace
      45             : #include <ooxml/OOXMLFastTokens.hxx> // ooxml namespace
      46             : #include <oox/token/namespaces.hxx> // oox namespace
      47             : #include <oox/token/tokens.hxx>
      48             : #include <dmapper/GraphicHelpers.hxx>
      49             : 
      50             : #include <rtfsdrimport.hxx>
      51             : #include <rtftokenizer.hxx>
      52             : #include <rtflookahead.hxx>
      53             : #include <rtfcharsets.hxx>
      54             : #include <rtfreferenceproperties.hxx>
      55             : #include <rtfskipdestination.hxx>
      56             : #include <rtffly.hxx>
      57             : 
      58             : #define TWIP_TO_MM100(TWIP)     ((TWIP) >= 0 ? (((TWIP)*127L+36L)/72L) : (((TWIP)*127L-36L)/72L))
      59             : #define MM100_TO_EMU(MM100)     (MM100 * 360)
      60             : #define M_TOKEN(token) OOX_TOKEN(officeMath, token)
      61             : #define OPEN_M_TOKEN( rtftok, ooxtok ) \
      62             :         case RTF_M##rtftok: \
      63             :             m_aMathBuffer.appendOpeningTag(M_TOKEN(ooxtok)); \
      64             :             m_aStates.top().nDestinationState = DESTINATION_M##rtftok; \
      65             :             break
      66             : 
      67             : using std::make_pair;
      68             : 
      69             : namespace writerfilter {
      70             : namespace rtftok {
      71             : 
      72           9 : static Id lcl_getParagraphBorder(sal_uInt32 nIndex)
      73             : {
      74             :     static const Id aBorderIds[] =
      75             :     {
      76             :         NS_sprm::LN_PBrcTop, NS_sprm::LN_PBrcLeft, NS_sprm::LN_PBrcBottom, NS_sprm::LN_PBrcRight
      77             :     };
      78             : 
      79           9 :     return aBorderIds[nIndex];
      80             : }
      81             : 
      82        2998 : static void lcl_putNestedAttribute(RTFSprms& rSprms, Id nParent, Id nId, RTFValue::Pointer_t pValue,
      83             :         bool bOverwrite = true, bool bAttribute = true)
      84             : {
      85        2998 :     RTFValue::Pointer_t pParent = rSprms.find(nParent);
      86        2998 :     if (!pParent.get())
      87             :     {
      88        1016 :         RTFSprms aAttributes;
      89        1016 :         if (nParent == NS_ooxml::LN_CT_TcPrBase_shd)
      90             :         {
      91             :             // RTF default is 'auto', see writerfilter::dmapper::CellColorHandler
      92           1 :             aAttributes.set(NS_ooxml::LN_CT_Shd_color, RTFValue::Pointer_t(new RTFValue(0x0a)));
      93           1 :             aAttributes.set(NS_ooxml::LN_CT_Shd_fill, RTFValue::Pointer_t(new RTFValue(0x0a)));
      94             :         }
      95        2032 :         RTFValue::Pointer_t pParentValue(new RTFValue(aAttributes));
      96        1016 :         rSprms.set(nParent, pParentValue, bOverwrite);
      97        2032 :         pParent = pParentValue;
      98             :     }
      99        2998 :     RTFSprms& rAttributes = (bAttribute ? pParent->getAttributes() : pParent->getSprms());
     100        2998 :     rAttributes.set(nId, pValue, bOverwrite);
     101        2998 : }
     102             : 
     103        1075 : static void lcl_putNestedSprm(RTFSprms& rSprms, Id nParent, Id nId, RTFValue::Pointer_t pValue, bool bOverwrite = false)
     104             : {
     105        1075 :     lcl_putNestedAttribute(rSprms, nParent, nId, pValue, bOverwrite, false);
     106        1075 : }
     107             : 
     108         306 : static bool lcl_eraseNestedAttribute(RTFSprms& rSprms, Id nParent, Id nId)
     109             : {
     110         306 :     RTFValue::Pointer_t pParent = rSprms.find(nParent);
     111         306 :     if (!pParent.get())
     112             :         // It doesn't even have a parent, we're done!
     113         256 :         return false;
     114          50 :     RTFSprms& rAttributes = pParent->getAttributes();
     115          50 :     return rAttributes.erase(nId);
     116             : }
     117             : 
     118         626 : static RTFSprms& lcl_getLastAttributes(RTFSprms& rSprms, Id nId)
     119             : {
     120         626 :     RTFValue::Pointer_t p = rSprms.find(nId);
     121         626 :     if (p.get() && p->getSprms().size())
     122         536 :         return p->getSprms().back().second->getAttributes();
     123             :     else
     124             :     {
     125             :         SAL_WARN("writerfilter", "trying to set property when no type is defined");
     126          90 :         return rSprms;
     127         626 :     }
     128             : }
     129             : 
     130         717 : static void lcl_putBorderProperty(std::stack<RTFParserState>& aStates, Id nId, RTFValue::Pointer_t pValue)
     131             : {
     132         717 :     RTFSprms* pAttributes = 0;
     133         717 :     if (aStates.top().nBorderState == BORDER_PARAGRAPH_BOX)
     134           5 :         for (int i = 0; i < 4; i++)
     135             :         {
     136           4 :             RTFValue::Pointer_t p = aStates.top().aParagraphSprms.find(lcl_getParagraphBorder(i));
     137           4 :             if (p.get())
     138             :             {
     139           4 :                 RTFSprms& rAttributes = p->getAttributes();
     140           4 :                 rAttributes.set(nId, pValue);
     141             :             }
     142           4 :         }
     143             :     // Attributes of the last border type
     144         716 :     else if (aStates.top().nBorderState == BORDER_PARAGRAPH)
     145           3 :         pAttributes = &lcl_getLastAttributes(aStates.top().aParagraphSprms, NS_ooxml::LN_CT_PrBase_pBdr);
     146         713 :     else if (aStates.top().nBorderState == BORDER_CELL)
     147         623 :         pAttributes = &lcl_getLastAttributes(aStates.top().aTableCellSprms, NS_ooxml::LN_CT_TcPrBase_tcBorders);
     148          90 :     else if (aStates.top().nBorderState == BORDER_PAGE)
     149           0 :         pAttributes = &lcl_getLastAttributes(aStates.top().aSectionSprms, NS_ooxml::LN_EG_SectPrContents_pgBorders);
     150         717 :     if (pAttributes)
     151         626 :         pAttributes->set(nId, pValue);
     152         717 : }
     153             : 
     154           2 : static OString lcl_DTTM22OString(long lDTTM)
     155             : {
     156           2 :     return msfilter::util::DateTimeToOString(msfilter::util::DTTM2DateTime(lDTTM));
     157             : }
     158             : 
     159           4 : static writerfilter::Reference<Properties>::Pointer_t lcl_getBookmarkProperties(int nPos, OUString& rString)
     160             : {
     161           4 :     RTFSprms aAttributes;
     162           8 :     RTFValue::Pointer_t pPos(new RTFValue(nPos));
     163           4 :     if (!rString.isEmpty())
     164             :     {
     165             :         // If present, this should be sent first.
     166           2 :         RTFValue::Pointer_t pString(new RTFValue(rString));
     167           2 :         aAttributes.set(NS_rtf::LN_BOOKMARKNAME, pString);
     168             :     }
     169           4 :     aAttributes.set(NS_rtf::LN_IBKL, pPos);
     170           8 :     return writerfilter::Reference<Properties>::Pointer_t(new RTFReferenceProperties(aAttributes));
     171             : }
     172             : 
     173           2 : static writerfilter::Reference<Properties>::Pointer_t lcl_getBookmarkProperties(int nPos)
     174             : {
     175           2 :     OUString aStr;
     176           2 :     return lcl_getBookmarkProperties(nPos, aStr);
     177             : }
     178             : 
     179           0 : static const char* lcl_RtfToString(RTFKeyword nKeyword)
     180             : {
     181           0 :     for (int i = 0; i < nRTFControlWords; i++)
     182             :     {
     183           0 :         if (nKeyword == aRTFControlWords[i].nIndex)
     184           0 :             return aRTFControlWords[i].sKeyword;
     185             :     }
     186           0 :     return NULL;
     187             : }
     188             : 
     189         134 : static util::DateTime lcl_getDateTime(RTFParserState& aState)
     190             : {
     191             :     return util::DateTime(0 /*100sec*/, 0 /*sec*/, aState.nMinute, aState.nHour,
     192         134 :             aState.nDay, aState.nMonth, aState.nYear);
     193             : }
     194             : 
     195        1282 : static void lcl_DestinationToMath(OUStringBuffer& rDestinationText, oox::formulaimport::XmlStreamBuilder& rMathBuffer, bool& rMathNor)
     196             : {
     197        1282 :     OUString aStr = rDestinationText.makeStringAndClear();
     198        1282 :     if (!aStr.isEmpty())
     199             :     {
     200         511 :         rMathBuffer.appendOpeningTag(M_TOKEN(r));
     201         511 :         if (rMathNor)
     202             :         {
     203           6 :             rMathBuffer.appendOpeningTag(M_TOKEN(rPr));
     204             :             // Same as M_TOKEN(lit)
     205           6 :             rMathBuffer.appendOpeningTag(M_TOKEN(nor));
     206           6 :             rMathBuffer.appendClosingTag(M_TOKEN(nor));
     207           6 :             rMathBuffer.appendClosingTag(M_TOKEN(rPr));
     208           6 :             rMathNor = false;
     209             :         }
     210         511 :         rMathBuffer.appendOpeningTag(M_TOKEN(t));
     211         511 :         rMathBuffer.appendCharacters(aStr);
     212         511 :         rMathBuffer.appendClosingTag(M_TOKEN(t));
     213         511 :         rMathBuffer.appendClosingTag(M_TOKEN(r));
     214        1282 :     }
     215        1282 : }
     216             : 
     217         206 : RTFDocumentImpl::RTFDocumentImpl(uno::Reference<uno::XComponentContext> const& xContext,
     218             :         uno::Reference<io::XInputStream> const& xInputStream,
     219             :         uno::Reference<lang::XComponent> const& xDstDoc,
     220             :         uno::Reference<frame::XFrame>    const& xFrame,
     221             :         uno::Reference<task::XStatusIndicator> const& xStatusIndicator)
     222             :     : m_xContext(xContext),
     223             :     m_xInputStream(xInputStream),
     224             :     m_xDstDoc(xDstDoc),
     225             :     m_xFrame(xFrame),
     226             :     m_xStatusIndicator(xStatusIndicator),
     227             :     m_aDefaultState(this),
     228             :     m_bSkipUnknown(false),
     229             :     m_aFontEncodings(),
     230             :     m_aFontIndexes(),
     231             :     m_aColorTable(),
     232             :     m_bFirstRun(true),
     233             :     m_bNeedPap(true),
     234             :     m_bNeedCr(false),
     235             :     m_bNeedCrOrig(false),
     236             :     m_bNeedPar(true),
     237             :     m_bNeedFinalPar(false),
     238             :     m_aListTableSprms(),
     239             :     m_aSettingsTableAttributes(),
     240             :     m_aSettingsTableSprms(),
     241             :     m_xStorage(),
     242             :     m_aTableBuffer(),
     243             :     m_aSuperBuffer(),
     244             :     m_bHasFootnote(false),
     245             :     m_pSuperstream(0),
     246             :     m_nHeaderFooterPositions(),
     247             :     m_nGroupStartPos(0),
     248             :     m_aBookmarks(),
     249             :     m_aAuthors(),
     250             :     m_aFormfieldSprms(),
     251             :     m_aFormfieldAttributes(),
     252             :     m_nFormFieldType(FORMFIELD_NONE),
     253             :     m_aObjectSprms(),
     254             :     m_aObjectAttributes(),
     255             :     m_bObject(false),
     256             :     m_aFontTableEntries(),
     257             :     m_nCurrentFontIndex(0),
     258             :     m_aStyleTableEntries(),
     259             :     m_nCurrentStyleIndex(0),
     260             :     m_bFormField(false),
     261             :     m_bIsInFrame(false),
     262             :     m_aUnicodeBuffer(),
     263             :     m_aHexBuffer(),
     264             :     m_bMathNor(false),
     265             :     m_bIgnoreNextContSectBreak(false),
     266             :     m_bNeedSect(true),
     267             :     m_bWasInFrame(false),
     268             :     m_bHadPicture(false),
     269             :     m_bHadSect(false),
     270             :     m_nCellxMax(0),
     271         206 :     m_nListPictureId(0)
     272             : {
     273             :     OSL_ASSERT(xInputStream.is());
     274         206 :     m_pInStream.reset(utl::UcbStreamHelper::CreateStream(xInputStream, sal_True));
     275             : 
     276         206 :     m_xModelFactory.set(m_xDstDoc, uno::UNO_QUERY);
     277             : 
     278         206 :     uno::Reference<document::XDocumentPropertiesSupplier> xDocumentPropertiesSupplier(m_xDstDoc, uno::UNO_QUERY);
     279         206 :     if (xDocumentPropertiesSupplier.is())
     280         193 :         m_xDocumentProperties.set(xDocumentPropertiesSupplier->getDocumentProperties(), uno::UNO_QUERY);
     281             : 
     282         206 :     m_pGraphicHelper.reset(new oox::GraphicHelper(m_xContext, xFrame, m_xStorage));
     283             : 
     284         206 :     m_pTokenizer.reset(new RTFTokenizer(*this, m_pInStream.get(), m_xStatusIndicator));
     285         206 :     m_pSdrImport.reset(new RTFSdrImport(*this, m_xDstDoc));
     286         206 : }
     287             : 
     288         412 : RTFDocumentImpl::~RTFDocumentImpl()
     289             : {
     290         412 : }
     291             : 
     292     1550881 : SvStream& RTFDocumentImpl::Strm()
     293             : {
     294     1550881 :     return *m_pInStream;
     295             : }
     296             : 
     297       23003 : Stream& RTFDocumentImpl::Mapper()
     298             : {
     299       23003 :     return *m_pMapperStream;
     300             : }
     301             : 
     302          13 : void RTFDocumentImpl::setSuperstream(RTFDocumentImpl *pSuperstream)
     303             : {
     304          13 :     m_pSuperstream = pSuperstream;
     305          13 : }
     306             : 
     307           2 : void RTFDocumentImpl::setAuthor(OUString& rAuthor)
     308             : {
     309           2 :     m_aAuthor = rAuthor;
     310           2 : }
     311             : 
     312           2 : void RTFDocumentImpl::setAuthorInitials(OUString& rAuthorInitials)
     313             : {
     314           2 :     m_aAuthorInitials = rAuthorInitials;
     315           2 : }
     316             : 
     317         203 : bool RTFDocumentImpl::isSubstream() const
     318             : {
     319         203 :     return m_pSuperstream != 0;
     320             : }
     321             : 
     322          13 : void RTFDocumentImpl::finishSubstream()
     323             : {
     324          13 :     checkUnicode(/*bUnicode =*/ true, /*bHex =*/ true);
     325             :     // At the end of a footnote stream, we need to emit a run break when importing from Word.
     326             :     // We can't do so unconditionally, as Writer already writes a \par at the end of the footnote.
     327          13 :     if (m_bNeedCr)
     328             :     {
     329           0 :         Mapper().startCharacterGroup();
     330           0 :         runBreak();
     331           0 :         Mapper().endCharacterGroup();
     332             :     }
     333          13 : }
     334             : 
     335          13 : void RTFDocumentImpl::setIgnoreFirst(OUString& rIgnoreFirst)
     336             : {
     337          13 :     m_aIgnoreFirst = rIgnoreFirst;
     338          13 : }
     339             : 
     340           8 : void RTFDocumentImpl::resolveSubstream(sal_uInt32 nPos, Id nId)
     341             : {
     342           8 :     OUString aStr;
     343           8 :     resolveSubstream(nPos, nId, aStr);
     344           8 : }
     345          13 : void RTFDocumentImpl::resolveSubstream(sal_uInt32 nPos, Id nId, OUString& rIgnoreFirst)
     346             : {
     347          13 :     sal_uInt32 nCurrent = Strm().Tell();
     348             :     // Seek to header position, parse, then seek back.
     349          13 :     RTFDocumentImpl::Pointer_t pImpl(new RTFDocumentImpl(m_xContext, m_xInputStream, m_xDstDoc, m_xFrame, m_xStatusIndicator));
     350          13 :     pImpl->setSuperstream(this);
     351          13 :     pImpl->setIgnoreFirst(rIgnoreFirst);
     352          13 :     if (!m_aAuthor.isEmpty())
     353             :     {
     354           2 :         pImpl->setAuthor(m_aAuthor);
     355           2 :         m_aAuthor = OUString();
     356             :     }
     357          13 :     if (!m_aAuthorInitials.isEmpty())
     358             :     {
     359           2 :         pImpl->setAuthorInitials(m_aAuthorInitials);
     360           2 :         m_aAuthorInitials = OUString();
     361             :     }
     362          13 :     pImpl->seek(nPos);
     363             :     SAL_INFO("writerfilter", "substream start");
     364          13 :     Mapper().substream(nId, pImpl);
     365             :     SAL_INFO("writerfilter", "substream end");
     366          13 :     Strm().Seek(nCurrent);
     367          13 :     nPos = 0;
     368          13 : }
     369             : 
     370        5379 : void RTFDocumentImpl::checkFirstRun()
     371             : {
     372        5379 :     if (m_bFirstRun)
     373             :     {
     374             :         // output settings table
     375         200 :         writerfilter::Reference<Properties>::Pointer_t const pProp(new RTFReferenceProperties(m_aSettingsTableAttributes, m_aSettingsTableSprms));
     376         400 :         RTFReferenceTable::Entries_t aSettingsTableEntries;
     377         200 :         aSettingsTableEntries.insert(make_pair(0, pProp));
     378         400 :         writerfilter::Reference<Table>::Pointer_t const pTable(new RTFReferenceTable(aSettingsTableEntries));
     379         200 :         Mapper().table(NS_ooxml::LN_settings_settings, pTable);
     380             :         // start initial paragraph
     381         200 :         if (!m_pSuperstream)
     382         187 :             Mapper().startSectionGroup();
     383         200 :         Mapper().startParagraphGroup();
     384             : 
     385             :         // set the requested default font
     386         400 :         RTFValue::Pointer_t pFont = m_aDefaultState.aCharacterSprms.find(NS_sprm::LN_CRgFtc0);
     387         200 :         if (pFont.get())
     388          73 :             dispatchValue(RTF_F, pFont->getInt());
     389         400 :         m_bFirstRun = false;
     390             :     }
     391        5379 : }
     392             : 
     393         132 : bool RTFDocumentImpl::getFirstRun()
     394             : {
     395         132 :     return m_bFirstRun;
     396             : }
     397             : 
     398           9 : void RTFDocumentImpl::setNeedPar(bool bNeedPar)
     399             : {
     400           9 :     m_bNeedPar = bNeedPar;
     401           9 : }
     402             : 
     403       61755 : void RTFDocumentImpl::setNeedSect(bool bNeedSect)
     404             : {
     405       61755 :     m_bNeedSect = bNeedSect;
     406       61755 : }
     407             : 
     408        4658 : writerfilter::Reference<Properties>::Pointer_t RTFDocumentImpl::getProperties(RTFSprms& rAttributes, RTFSprms& rSprms)
     409             : {
     410        4658 :     int nStyle = m_aStates.top().nCurrentStyleIndex;
     411        4658 :     RTFReferenceTable::Entries_t::iterator it = m_aStyleTableEntries.find(nStyle);
     412        4658 :     if (it != m_aStyleTableEntries.end())
     413             :     {
     414         278 :         RTFReferenceProperties& rProps = *(RTFReferenceProperties*)it->second.get();
     415             :         // Get rid of direct formatting what is already in the style.
     416         278 :         rSprms.deduplicate(rProps.getSprms());
     417         278 :         rAttributes.deduplicate(rProps.getAttributes());
     418             :     }
     419        4658 :     writerfilter::Reference<Properties>::Pointer_t pRet(new RTFReferenceProperties(rAttributes, rSprms));
     420        4658 :     return pRet;
     421             : }
     422             : 
     423        5225 : void RTFDocumentImpl::checkNeedPap()
     424             : {
     425        5225 :     if (m_bNeedPap)
     426             :     {
     427         589 :         m_bNeedPap = false; // reset early, so we can avoid recursion when calling ourselves
     428         589 :         if (!m_aStates.top().pCurrentBuffer)
     429             :         {
     430             :             writerfilter::Reference<Properties>::Pointer_t const pParagraphProperties(
     431         906 :                     getProperties(m_aStates.top().aParagraphAttributes, m_aStates.top().aParagraphSprms)
     432         906 :                     );
     433             : 
     434             :             // Writer will ignore a page break before a text frame, so guard it with empty paragraphs
     435         495 :             bool hasBreakBeforeFrame = m_aStates.top().aFrame.hasProperties() &&
     436         495 :                 m_aStates.top().aParagraphSprms.find(NS_sprm::LN_PFPageBreakBefore).get();
     437         453 :             if (hasBreakBeforeFrame)
     438             :             {
     439           0 :                 dispatchSymbol(RTF_PAR);
     440           0 :                 m_bNeedPap = false;
     441             :             }
     442         453 :             Mapper().props(pParagraphProperties);
     443         453 :             if (hasBreakBeforeFrame)
     444           0 :                 dispatchSymbol(RTF_PAR);
     445             : 
     446         453 :             if (m_aStates.top().aFrame.hasProperties())
     447             :             {
     448             :                 writerfilter::Reference<Properties>::Pointer_t const pFrameProperties(
     449          21 :                         new RTFReferenceProperties(RTFSprms(), m_aStates.top().aFrame.getSprms()));
     450          21 :                 Mapper().props(pFrameProperties);
     451         453 :             }
     452             :         }
     453             :         else
     454             :         {
     455         136 :             RTFValue::Pointer_t pValue(new RTFValue(m_aStates.top().aParagraphAttributes, m_aStates.top().aParagraphSprms));
     456         136 :             m_aStates.top().pCurrentBuffer->push_back(make_pair(BUFFER_PROPS, pValue));
     457             :         }
     458             :     }
     459        5225 : }
     460             : 
     461        4354 : void RTFDocumentImpl::runProps()
     462             : {
     463        4354 :     if (!m_aStates.top().pCurrentBuffer)
     464             :     {
     465        4155 :         writerfilter::Reference<Properties>::Pointer_t const pProperties = getProperties(m_aStates.top().aCharacterAttributes, m_aStates.top().aCharacterSprms);
     466        4155 :         Mapper().props(pProperties);
     467             :     }
     468             :     else
     469             :     {
     470         199 :         RTFValue::Pointer_t pValue(new RTFValue(m_aStates.top().aCharacterAttributes, m_aStates.top().aCharacterSprms));
     471         199 :         m_aStates.top().pCurrentBuffer->push_back(make_pair(BUFFER_PROPS, pValue));
     472             :     }
     473        4354 : }
     474             : 
     475         719 : void RTFDocumentImpl::runBreak()
     476             : {
     477         719 :     sal_uInt8 sBreak[] = { 0xd };
     478         719 :     Mapper().text(sBreak, 1);
     479         719 :     m_bNeedCr = false;
     480         719 : }
     481             : 
     482         204 : void RTFDocumentImpl::tableBreak()
     483             : {
     484         204 :     runBreak();
     485         204 :     Mapper().endParagraphGroup();
     486         204 :     Mapper().startParagraphGroup();
     487         204 : }
     488             : 
     489         515 : void RTFDocumentImpl::parBreak()
     490             : {
     491         515 :     checkFirstRun();
     492         515 :     checkNeedPap();
     493             :     // end previous paragraph
     494         515 :     Mapper().startCharacterGroup();
     495         515 :     runBreak();
     496         515 :     Mapper().endCharacterGroup();
     497         515 :     Mapper().endParagraphGroup();
     498             : 
     499         515 :     m_bHadPicture = false;
     500             : 
     501             :     // start new one
     502         515 :     Mapper().startParagraphGroup();
     503         515 : }
     504             : 
     505         207 : void RTFDocumentImpl::sectBreak(bool bFinal = false)
     506             : {
     507             :     SAL_INFO("writerfilter", OSL_THIS_FUNC << ": final? " << bFinal << ", needed? " << m_bNeedSect);
     508         207 :     bool bNeedSect = m_bNeedSect;
     509         207 :     RTFValue::Pointer_t pBreak = m_aStates.top().aSectionSprms.find(NS_sprm::LN_SBkc);
     510         207 :     bool bContinuous = pBreak.get() && pBreak->getInt() == 0;
     511             :     // If there is no paragraph in this section, then insert a dummy one, as required by Writer,
     512             :     // unless this is the end of the doc, we had nothing since the last section break and this is not a continuous one.
     513         207 :     if (m_bNeedPar && !(bFinal && !m_bNeedSect && !bContinuous))
     514           8 :         dispatchSymbol(RTF_PAR);
     515             :     // It's allowed to not have a non-table paragraph at the end of an RTF doc, add it now if required.
     516         207 :     if (m_bNeedFinalPar && bFinal)
     517             :     {
     518           1 :         dispatchFlag(RTF_PARD);
     519           1 :         dispatchSymbol(RTF_PAR);
     520             :     }
     521         420 :     while (!m_nHeaderFooterPositions.empty())
     522             :     {
     523           6 :         std::pair<Id, sal_uInt32> aPair = m_nHeaderFooterPositions.front();
     524           6 :         m_nHeaderFooterPositions.pop();
     525           6 :         resolveSubstream(aPair.second, aPair.first);
     526             :     }
     527             : 
     528             :     // Normally a section break at the end of the doc is necessary. Unless the
     529             :     // last control word in the document is a section break itself.
     530         207 :     if (!bNeedSect || !m_bHadSect)
     531             :     {
     532             :         // In case the last section is a continuous one, we don't need to output a section break.
     533         198 :         if (bFinal && bContinuous)
     534          54 :             m_aStates.top().aSectionSprms.erase(NS_sprm::LN_SBkc);
     535             :     }
     536             : 
     537             :     // Section properties are a paragraph sprm.
     538         414 :     RTFValue::Pointer_t pValue(new RTFValue(m_aStates.top().aSectionAttributes, m_aStates.top().aSectionSprms));
     539         414 :     RTFSprms aAttributes;
     540         414 :     RTFSprms aSprms;
     541         207 :     aSprms.set(NS_ooxml::LN_CT_PPr_sectPr, pValue);
     542             :     writerfilter::Reference<Properties>::Pointer_t const pProperties(
     543         207 :             new RTFReferenceProperties(aAttributes, aSprms)
     544         621 :             );
     545             :     // The trick is that we send properties of the previous section right now, which will be exactly what dmapper expects.
     546         207 :     Mapper().props(pProperties);
     547         207 :     Mapper().endParagraphGroup();
     548         207 :     if (!m_pSuperstream)
     549         194 :         Mapper().endSectionGroup();
     550         207 :     if (!bFinal)
     551             :     {
     552           8 :         Mapper().startSectionGroup();
     553           8 :         Mapper().startParagraphGroup();
     554             :     }
     555         207 :     m_bNeedPar = true;
     556         414 :     m_bNeedSect = false;
     557         207 : }
     558             : 
     559          13 : void RTFDocumentImpl::seek(sal_uInt32 nPos)
     560             : {
     561          13 :     Strm().Seek(nPos);
     562          13 : }
     563             : 
     564         349 : sal_uInt32 RTFDocumentImpl::getColorTable(sal_uInt32 nIndex)
     565             : {
     566         349 :     if (!m_pSuperstream)
     567             :     {
     568         347 :         if (nIndex < m_aColorTable.size())
     569         243 :             return m_aColorTable[nIndex];
     570         104 :         return 0;
     571             :     }
     572             :     else
     573           2 :         return m_pSuperstream->getColorTable(nIndex);
     574             : }
     575             : 
     576        4621 : rtl_TextEncoding RTFDocumentImpl::getEncoding(sal_uInt32 nFontIndex)
     577             : {
     578        4621 :     if (!m_pSuperstream)
     579             :     {
     580        4617 :         std::map<int, rtl_TextEncoding>::iterator it = m_aFontEncodings.find(nFontIndex);
     581        4617 :         if (it != m_aFontEncodings.end())
     582        2813 :             return it->second;
     583        1804 :         return msfilter::util::getBestTextEncodingFromLocale(Application::GetSettings().GetLanguageTag().getLocale());
     584             :     }
     585             :     else
     586           4 :         return m_pSuperstream->getEncoding(nFontIndex);
     587             : }
     588             : 
     589        5176 : int RTFDocumentImpl::getFontIndex(int nIndex)
     590             : {
     591        5176 :     if (!m_pSuperstream)
     592        5175 :         return std::find(m_aFontIndexes.begin(), m_aFontIndexes.end(), nIndex) - m_aFontIndexes.begin();
     593             :     else
     594           1 :         return m_pSuperstream->getFontIndex(nIndex);
     595             : }
     596             : 
     597         452 : RTFParserState& RTFDocumentImpl::getDefaultState()
     598             : {
     599         452 :     if (!m_pSuperstream)
     600         438 :         return m_aDefaultState;
     601             :     else
     602          14 :         return m_pSuperstream->getDefaultState();
     603             : }
     604             : 
     605          13 : oox::GraphicHelper& RTFDocumentImpl::getGraphicHelper()
     606             : {
     607          13 :     return *m_pGraphicHelper;
     608             : }
     609             : 
     610         206 : void RTFDocumentImpl::resolve(Stream & rMapper)
     611             : {
     612         206 :     m_pMapperStream = &rMapper;
     613         206 :     switch (m_pTokenizer->resolveParse())
     614             :     {
     615             :         case ERROR_OK:
     616             :             SAL_INFO("writerfilter", OSL_THIS_FUNC << ": finished without errors");
     617         203 :             break;
     618             :         case ERROR_GROUP_UNDER:
     619             :             SAL_INFO("writerfilter", OSL_THIS_FUNC << ": unmatched '}'");
     620           0 :             break;
     621             :         case ERROR_GROUP_OVER:
     622             :             SAL_INFO("writerfilter", OSL_THIS_FUNC << ": unmatched '{'");
     623           2 :             throw io::WrongFormatException(m_pTokenizer->getPosition(), uno::Reference< uno::XInterface >());
     624             :             break;
     625             :         case ERROR_EOF:
     626             :             SAL_INFO("writerfilter", OSL_THIS_FUNC << ": unexpected end of file");
     627           0 :             throw io::WrongFormatException(m_pTokenizer->getPosition(), uno::Reference< uno::XInterface >());
     628             :             break;
     629             :         case ERROR_HEX_INVALID:
     630             :             SAL_INFO("writerfilter", OSL_THIS_FUNC << ": invalid hex char");
     631           0 :             throw io::WrongFormatException(m_pTokenizer->getPosition(), uno::Reference< uno::XInterface >());
     632             :             break;
     633             :         case ERROR_CHAR_OVER:
     634             :             SAL_INFO("writerfilter", OSL_THIS_FUNC << ": characters after last '}'");
     635           0 :             break;
     636             :     }
     637         203 : }
     638             : 
     639          15 : int RTFDocumentImpl::resolvePict(bool bInline)
     640             : {
     641          15 :     SvMemoryStream aStream;
     642          15 :     SvStream *pStream = 0;
     643          15 :     if (!m_pBinaryData.get())
     644             :     {
     645          14 :         pStream = &aStream;
     646          14 :         int b = 0, count = 2;
     647             : 
     648             :         // Feed the destination text to a stream.
     649          14 :         OString aStr = OUStringToOString(m_aStates.top().aDestinationText.makeStringAndClear(), RTL_TEXTENCODING_ASCII_US);
     650          14 :         const char *str = aStr.getStr();
     651       45756 :         for (int i = 0; i < aStr.getLength(); ++i)
     652             :         {
     653       45742 :             char ch = str[i];
     654       45742 :             if (ch != 0x0d && ch != 0x0a && ch != 0x20)
     655             :             {
     656       45742 :                 b = b << 4;
     657       45742 :                 sal_Int8 parsed = m_pTokenizer->asHex(ch);
     658       45742 :                 if (parsed == -1)
     659           0 :                     return ERROR_HEX_INVALID;
     660       45742 :                 b += parsed;
     661       45742 :                 count--;
     662       45742 :                 if (!count)
     663             :                 {
     664       22871 :                     aStream << (char)b;
     665       22871 :                     count = 2;
     666       22871 :                     b = 0;
     667             :                 }
     668             :             }
     669          14 :         }
     670             :     }
     671             :     else
     672           1 :         pStream = m_pBinaryData.get();
     673             : 
     674          15 :     if (!pStream->Tell())
     675             :         // No destination text? Then we'll get it later.
     676           1 :         return 0;
     677             : 
     678             :     // Store, and get its URL.
     679          14 :     pStream->Seek(0);
     680          28 :     uno::Reference<io::XInputStream> xInputStream(new utl::OInputStreamWrapper(pStream));
     681          14 :     WMF_EXTERNALHEADER aExtHeader;
     682          14 :     aExtHeader.mapMode = m_aStates.top().aPicture.eWMetafile;
     683          14 :     aExtHeader.xExt = m_aStates.top().aPicture.nWidth;
     684          14 :     aExtHeader.yExt = m_aStates.top().aPicture.nHeight;
     685          14 :     WMF_EXTERNALHEADER* pExtHeader = &aExtHeader;
     686          28 :     uno::Reference<lang::XServiceInfo> xServiceInfo(m_aStates.top().aDrawingObject.xShape, uno::UNO_QUERY);
     687          14 :     if (xServiceInfo.is() && xServiceInfo->supportsService("com.sun.star.text.TextFrame"))
     688           0 :         pExtHeader = 0;
     689          28 :     OUString aGraphicUrl = m_pGraphicHelper->importGraphicObject(xInputStream, pExtHeader);
     690             : 
     691          14 :     if (m_aStates.top().aPicture.nStyle != BMPSTYLE_NONE)
     692             :     {
     693             :         // In case of PNG/JPEG, the real size is known, don't use the values
     694             :         // provided by picw and pich.
     695          11 :         OString aURLBS(OUStringToOString(aGraphicUrl, RTL_TEXTENCODING_UTF8));
     696          11 :         const char aURLBegin[] = "vnd.sun.star.GraphicObject:";
     697          11 :         if (aURLBS.compareTo(aURLBegin, RTL_CONSTASCII_LENGTH(aURLBegin)) == 0)
     698             :         {
     699          11 :             Graphic aGraphic = GraphicObject(aURLBS.copy(RTL_CONSTASCII_LENGTH(aURLBegin))).GetTransformedGraphic();
     700          11 :             Size aSize(aGraphic.GetPrefSize());
     701          22 :             MapMode aMap(MAP_100TH_MM);
     702          11 :             if (aGraphic.GetPrefMapMode().GetMapUnit() == MAP_PIXEL)
     703           9 :                 aSize = Application::GetDefaultDevice()->PixelToLogic(aSize, aMap);
     704             :             else
     705           2 :                 aSize = OutputDevice::LogicToLogic(aSize, aGraphic.GetPrefMapMode(), aMap);
     706          11 :             m_aStates.top().aPicture.nWidth = aSize.Width();
     707          22 :             m_aStates.top().aPicture.nHeight = aSize.Height();
     708          11 :         }
     709             :     }
     710             : 
     711             :     // Wrap it in an XShape.
     712          28 :     uno::Reference<drawing::XShape> xShape;
     713          14 :     if (m_xModelFactory.is())
     714          14 :         xShape.set(m_xModelFactory->createInstance("com.sun.star.drawing.GraphicObjectShape"), uno::UNO_QUERY);
     715          28 :     uno::Reference<beans::XPropertySet> xPropertySet(xShape, uno::UNO_QUERY);
     716          28 :     uno::Reference<drawing::XDrawPageSupplier> xDrawSupplier( m_xDstDoc, uno::UNO_QUERY);
     717          14 :     if ( xDrawSupplier.is() )
     718             :     {
     719          14 :         uno::Reference< drawing::XShapes > xShapes( xDrawSupplier->getDrawPage(), uno::UNO_QUERY );
     720          14 :         if ( xShapes.is() )
     721          14 :             xShapes->add( xShape );
     722             :     }
     723             : 
     724             :     // check if the picture is in an OLE object and if the \objdata element is used
     725             :     // (see RTF_OBJECT in RTFDocumentImpl::dispatchDestination)
     726          14 :     if (m_bObject)
     727             :     {
     728             :         // Set bitmap
     729           0 :         beans::PropertyValues aMediaProperties(1);
     730           0 :         aMediaProperties[0].Name = "URL";
     731           0 :         aMediaProperties[0].Value <<= aGraphicUrl;
     732           0 :         uno::Reference<graphic::XGraphicProvider> xGraphicProvider(graphic::GraphicProvider::create(m_xContext));
     733           0 :         uno::Reference<graphic::XGraphic> xGraphic = xGraphicProvider->queryGraphic(aMediaProperties);
     734           0 :         xPropertySet->setPropertyValue("Graphic", uno::Any(xGraphic));
     735             : 
     736             :         // Set the object size
     737           0 :         awt::Size aSize;
     738           0 :         aSize.Width = (m_aStates.top().aPicture.nGoalWidth ? m_aStates.top().aPicture.nGoalWidth : m_aStates.top().aPicture.nWidth);
     739           0 :         aSize.Height = (m_aStates.top().aPicture.nGoalHeight ? m_aStates.top().aPicture.nGoalHeight : m_aStates.top().aPicture.nHeight);
     740           0 :         xShape->setSize( aSize );
     741             : 
     742           0 :         RTFValue::Pointer_t pShapeValue(new RTFValue(xShape));
     743           0 :         m_aObjectAttributes.set(NS_ooxml::LN_shape, pShapeValue);
     744           0 :         return 0;
     745             :     }
     746             : 
     747          14 :     if (xPropertySet.is())
     748          14 :         xPropertySet->setPropertyValue("GraphicURL", uno::Any(aGraphicUrl));
     749             : 
     750          14 :     if (m_aStates.top().bInListpicture)
     751             :     {
     752             :         // Send the shape directly, no section is started, to additional properties will be ignored anyway.
     753           2 :         Mapper().startShape(xShape);
     754           2 :         Mapper().endShape();
     755           2 :         return 0;
     756             :     }
     757             : 
     758             :     // Send it to the dmapper.
     759          24 :     RTFSprms aSprms;
     760          24 :     RTFSprms aAttributes;
     761             :     // shape attribute
     762          24 :     RTFSprms aPicAttributes;
     763          24 :     RTFValue::Pointer_t pShapeValue(new RTFValue(xShape));
     764          12 :     aPicAttributes.set(NS_ooxml::LN_shape, pShapeValue);
     765             :     // pic sprm
     766          24 :     RTFSprms aGraphicDataAttributes;
     767          24 :     RTFSprms aGraphicDataSprms;
     768          24 :     RTFValue::Pointer_t pPicValue(new RTFValue(aPicAttributes));
     769          12 :     aGraphicDataSprms.set(NS_ooxml::LN_pic_pic, pPicValue);
     770             :     // graphicData sprm
     771          24 :     RTFSprms aGraphicAttributes;
     772          24 :     RTFSprms aGraphicSprms;
     773          24 :     RTFValue::Pointer_t pGraphicDataValue(new RTFValue(aGraphicDataAttributes, aGraphicDataSprms));
     774          12 :     aGraphicSprms.set(NS_ooxml::LN_CT_GraphicalObject_graphicData, pGraphicDataValue);
     775             :     // graphic sprm
     776          24 :     RTFValue::Pointer_t pGraphicValue(new RTFValue(aGraphicAttributes, aGraphicSprms));
     777             :     // extent sprm
     778          24 :     RTFSprms aExtentAttributes;
     779             :     int nXExt, nYExt;
     780          12 :     nXExt = (m_aStates.top().aPicture.nGoalWidth ? m_aStates.top().aPicture.nGoalWidth : m_aStates.top().aPicture.nWidth);
     781          12 :     nYExt = (m_aStates.top().aPicture.nGoalHeight ? m_aStates.top().aPicture.nGoalHeight : m_aStates.top().aPicture.nHeight);
     782          12 :     if (m_aStates.top().aPicture.nScaleX != 100)
     783           5 :         nXExt = (((long)m_aStates.top().aPicture.nScaleX) * ( nXExt - ( m_aStates.top().aPicture.nCropL + m_aStates.top().aPicture.nCropR ))) / 100L;
     784          12 :     if (m_aStates.top().aPicture.nScaleY != 100)
     785           5 :         nYExt = (((long)m_aStates.top().aPicture.nScaleY) * ( nYExt - ( m_aStates.top().aPicture.nCropT + m_aStates.top().aPicture.nCropB ))) / 100L;
     786          24 :     RTFValue::Pointer_t pXExtValue(new RTFValue(nXExt));
     787          24 :     RTFValue::Pointer_t pYExtValue(new RTFValue(nYExt));
     788          12 :     aExtentAttributes.set(NS_rtf::LN_XEXT, pXExtValue);
     789          12 :     aExtentAttributes.set(NS_rtf::LN_YEXT, pYExtValue);
     790          24 :     RTFValue::Pointer_t pExtentValue(new RTFValue(aExtentAttributes));
     791             :     // docpr sprm
     792          24 :     RTFSprms aDocprAttributes;
     793          15 :     for (RTFSprms::Iterator_t i = m_aStates.top().aCharacterAttributes.begin(); i != m_aStates.top().aCharacterAttributes.end(); ++i)
     794           3 :         if (i->first == NS_ooxml::LN_CT_NonVisualDrawingProps_name || i->first == NS_ooxml::LN_CT_NonVisualDrawingProps_descr)
     795           0 :             aDocprAttributes.set(i->first, i->second);
     796          24 :     RTFValue::Pointer_t pDocprValue(new RTFValue(aDocprAttributes));
     797          12 :     if (bInline)
     798             :     {
     799           8 :         RTFSprms aInlineAttributes;
     800           8 :         aInlineAttributes.set(NS_ooxml::LN_CT_Inline_distT, RTFValue::Pointer_t(new RTFValue(0)));
     801           8 :         aInlineAttributes.set(NS_ooxml::LN_CT_Inline_distB, RTFValue::Pointer_t(new RTFValue(0)));
     802           8 :         aInlineAttributes.set(NS_ooxml::LN_CT_Inline_distL, RTFValue::Pointer_t(new RTFValue(0)));
     803           8 :         aInlineAttributes.set(NS_ooxml::LN_CT_Inline_distR, RTFValue::Pointer_t(new RTFValue(0)));
     804          16 :         RTFSprms aInlineSprms;
     805           8 :         aInlineSprms.set(NS_ooxml::LN_CT_Inline_extent, pExtentValue);
     806           8 :         aInlineSprms.set(NS_ooxml::LN_CT_Inline_docPr, pDocprValue);
     807           8 :         aInlineSprms.set(NS_ooxml::LN_graphic_graphic, pGraphicValue);
     808             :         // inline sprm
     809          16 :         RTFValue::Pointer_t pValue(new RTFValue(aInlineAttributes, aInlineSprms));
     810          16 :         aSprms.set(NS_ooxml::LN_inline_inline, pValue);
     811             :     }
     812             :     else // anchored
     813             :     {
     814             :         // wrap sprm
     815           4 :         RTFSprms aAnchorWrapAttributes;
     816           8 :         RTFSprms aAnchorAttributes;
     817           7 :         for (RTFSprms::Iterator_t i = m_aStates.top().aCharacterAttributes.begin(); i != m_aStates.top().aCharacterAttributes.end(); ++i)
     818             :         {
     819           3 :             if (i->first == NS_ooxml::LN_CT_WrapSquare_wrapText)
     820           0 :                 aAnchorWrapAttributes.set(i->first, i->second);
     821           3 :             else if (i->first == NS_rtf::LN_WR)
     822           3 :                 aAnchorAttributes.set(i->first, i->second);
     823             :         }
     824           8 :         RTFValue::Pointer_t pAnchorWrapValue(new RTFValue(aAnchorWrapAttributes));
     825           8 :         RTFSprms aAnchorSprms;
     826           4 :         aAnchorSprms.set(NS_ooxml::LN_CT_Anchor_extent, pExtentValue);
     827           4 :         if (aAnchorWrapAttributes.size())
     828           0 :             aAnchorSprms.set(NS_ooxml::LN_EG_WrapType_wrapSquare, pAnchorWrapValue);
     829             : 
     830             :         // See OOXMLFastContextHandler::positionOffset(), we can't just put values in an RTFValue.
     831           4 :         if (m_aStates.top().aShape.nLeft > 0)
     832             :         {
     833           3 :             writerfilter::dmapper::PositionHandler::setPositionOffset(OUString::number(MM100_TO_EMU(m_aStates.top().aShape.nLeft)), false);
     834           3 :             aAnchorSprms.set(NS_ooxml::LN_CT_Anchor_positionH, RTFValue::Pointer_t(new RTFValue(RTFSprms())));
     835             :         }
     836           4 :         if (m_aStates.top().aShape.nTop > 0)
     837             :         {
     838           3 :             writerfilter::dmapper::PositionHandler::setPositionOffset(OUString::number(MM100_TO_EMU(m_aStates.top().aShape.nTop)), true);
     839           3 :             aAnchorSprms.set(NS_ooxml::LN_CT_Anchor_positionV, RTFValue::Pointer_t(new RTFValue(RTFSprms())));
     840             :         }
     841             : 
     842           4 :         aAnchorSprms.set(NS_ooxml::LN_CT_Anchor_docPr, pDocprValue);
     843           4 :         aAnchorSprms.set(NS_ooxml::LN_graphic_graphic, pGraphicValue);
     844             :         // anchor sprm
     845           8 :         RTFValue::Pointer_t pValue(new RTFValue(aAnchorAttributes, aAnchorSprms));
     846           8 :         aSprms.set(NS_ooxml::LN_anchor_anchor, pValue);
     847             :     }
     848          24 :     writerfilter::Reference<Properties>::Pointer_t const pProperties(new RTFReferenceProperties(aAttributes, aSprms));
     849          12 :     checkFirstRun();
     850             : 
     851          12 :     if (!m_aStates.top().pCurrentBuffer)
     852             :     {
     853           8 :         Mapper().props(pProperties);
     854             :         // Make sure we don't loose these properties with a too early reset.
     855           8 :         m_bHadPicture = true;
     856             :     }
     857             :     else
     858             :     {
     859           4 :         RTFValue::Pointer_t pValue(new RTFValue(aAttributes, aSprms));
     860           4 :         m_aStates.top().pCurrentBuffer->push_back(make_pair(BUFFER_PROPS, pValue));
     861             :     }
     862             : 
     863          27 :     return 0;
     864             : }
     865             : 
     866       29408 : int RTFDocumentImpl::resolveChars(char ch)
     867             : {
     868       29408 :     if (m_aStates.top().nInternalState == INTERNAL_BIN)
     869             :     {
     870           1 :         m_pBinaryData.reset(new SvMemoryStream());
     871           1 :         *m_pBinaryData << ch;
     872       21996 :         for (int i = 0; i < m_aStates.top().nBinaryToRead - 1; ++i)
     873             :         {
     874       21995 :             Strm() >> ch;
     875       21995 :             *m_pBinaryData << ch;
     876             :         }
     877           1 :         m_aStates.top().nInternalState = INTERNAL_NORMAL;
     878           1 :         return 0;
     879             :     }
     880             : 
     881       29407 :     if (m_aStates.top().nInternalState != INTERNAL_HEX)
     882        5958 :         checkUnicode(/*bUnicode =*/ false, /*bHex =*/ true);
     883             : 
     884       29407 :     OStringBuffer aBuf;
     885             : 
     886       29407 :     bool bUnicodeChecked = false;
     887       29407 :     bool bSkipped = false;
     888      798781 :     while(!Strm().IsEof() && (m_aStates.top().nInternalState == INTERNAL_HEX || (ch != '{' && ch != '}' && ch != '\\')))
     889             :     {
     890      763416 :         if (m_aStates.top().nInternalState == INTERNAL_HEX || (ch != 0x0d && ch != 0x0a))
     891             :         {
     892      757972 :             if (m_aStates.top().nCharsToSkip == 0)
     893             :             {
     894      757842 :                 if (!bUnicodeChecked)
     895             :                 {
     896       29281 :                     checkUnicode(/*bUnicode =*/ true, /*bHex =*/ false);
     897       29281 :                     bUnicodeChecked = true;
     898             :                 }
     899      757842 :                 aBuf.append(ch);
     900             :             }
     901             :             else
     902             :             {
     903         130 :                 bSkipped = true;
     904         130 :                 m_aStates.top().nCharsToSkip--;
     905             :             }
     906             :         }
     907             :         // read a single char if we're in hex mode
     908      763416 :         if (m_aStates.top().nInternalState == INTERNAL_HEX)
     909       23449 :             break;
     910      739967 :         Strm() >> ch;
     911             :     }
     912       29407 :     if (m_aStates.top().nInternalState != INTERNAL_HEX && !Strm().IsEof())
     913        5958 :         Strm().SeekRel(-1);
     914             : 
     915       29407 :     if (m_aStates.top().nInternalState == INTERNAL_HEX && m_aStates.top().nDestinationState != DESTINATION_LEVELNUMBERS)
     916             :     {
     917       23426 :         if (!bSkipped)
     918       23331 :             m_aHexBuffer.append(ch);
     919       23426 :         return 0;
     920             :     }
     921             : 
     922        5981 :     if (m_aStates.top().nDestinationState == DESTINATION_SKIP)
     923         533 :         return 0;
     924       10896 :     OString aStr = aBuf.makeStringAndClear();
     925        5448 :     if (m_aStates.top().nDestinationState == DESTINATION_LEVELNUMBERS)
     926             :     {
     927          56 :         if (aStr.toChar() != ';')
     928          23 :             m_aStates.top().aLevelNumbers.push_back(sal_Int32(ch));
     929          56 :         return 0;
     930             :     }
     931             : 
     932       10784 :     OUString aOUStr(OStringToOUString(aStr, m_aStates.top().nCurrentEncoding));
     933             :     SAL_INFO("writerfilter", OSL_THIS_FUNC << ": collected '" << aOUStr << "'");
     934             : 
     935        5392 :     if (m_aStates.top().nDestinationState == DESTINATION_COLORTABLE)
     936             :     {
     937             :         // we hit a ';' at the end of each color entry
     938         284 :         sal_uInt32 color = (m_aStates.top().aCurrentColor.nRed << 16) | ( m_aStates.top().aCurrentColor.nGreen << 8)
     939         284 :             | m_aStates.top().aCurrentColor.nBlue;
     940         284 :         m_aColorTable.push_back(color);
     941             :         // set components back to zero
     942         284 :         m_aStates.top().aCurrentColor = RTFColorTableEntry();
     943             :     }
     944        5108 :     else if (!aOUStr.isEmpty())
     945        5077 :         text(aOUStr);
     946             : 
     947       34799 :     return 0;
     948             : }
     949             : 
     950        7893 : bool RTFFrame::inFrame()
     951             : {
     952        7893 :     return nW > 0
     953        7764 :         || nH > 0
     954        7764 :         || nX > 0
     955       15657 :         || nY > 0;
     956             : }
     957             : 
     958          88 : void RTFDocumentImpl::singleChar(sal_uInt8 nValue, bool bRunProps)
     959             : {
     960          88 :     sal_uInt8 sValue[] = { nValue };
     961          88 :     RTFBuffer_t* pCurrentBuffer = m_aStates.top().pCurrentBuffer;
     962             : 
     963          88 :     if (!pCurrentBuffer)
     964             :     {
     965          85 :         Mapper().startCharacterGroup();
     966             :         // Should we send run properties?
     967          85 :         if (bRunProps)
     968           2 :             runProps();
     969          85 :         Mapper().text(sValue, 1);
     970          85 :         Mapper().endCharacterGroup();
     971             :     }
     972             :     else
     973             :     {
     974           3 :         pCurrentBuffer->push_back(make_pair(BUFFER_STARTRUN, RTFValue::Pointer_t()));
     975           3 :         RTFValue::Pointer_t pValue(new RTFValue(*sValue));
     976           3 :         pCurrentBuffer->push_back(make_pair(BUFFER_TEXT, pValue));
     977           3 :         pCurrentBuffer->push_back(make_pair(BUFFER_ENDRUN, RTFValue::Pointer_t()));
     978             :     }
     979          88 : }
     980             : 
     981        7436 : void RTFDocumentImpl::text(OUString& rString)
     982             : {
     983        7436 :     if (rString.getLength() == 1 && m_aStates.top().nDestinationState != DESTINATION_DOCCOMM)
     984             :     {
     985             :         // No cheating! Tokenizer ignores bare \r and \n, their hex \'0d / \'0a form doesn't count, either.
     986        3296 :         sal_Unicode ch = rString.getStr()[0];
     987        3296 :         if (ch == 0x0d || ch == 0x0a)
     988           1 :             return;
     989             :     }
     990             : 
     991        7435 :     bool bRet = true;
     992        7435 :     switch (m_aStates.top().nDestinationState)
     993             :     {
     994             :         case DESTINATION_FONTTABLE:
     995             :         case DESTINATION_FONTENTRY:
     996             :         case DESTINATION_STYLESHEET:
     997             :         case DESTINATION_STYLEENTRY:
     998             :         case DESTINATION_REVISIONTABLE:
     999             :         case DESTINATION_REVISIONENTRY:
    1000             :             {
    1001             :                 // ; is the end of the entry
    1002        1299 :                 bool bEnd = false;
    1003        1299 :                 if (rString.endsWithAsciiL(";", 1))
    1004             :                 {
    1005        1130 :                     rString = rString.copy(0, rString.getLength() - 1);
    1006        1130 :                     bEnd = true;
    1007             :                 }
    1008        1299 :                 m_aStates.top().aDestinationText.append(rString);
    1009        1299 :                 if (bEnd)
    1010             :                 {
    1011        1130 :                     switch (m_aStates.top().nDestinationState)
    1012             :                     {
    1013             :                         case DESTINATION_FONTTABLE:
    1014             :                         case DESTINATION_FONTENTRY:
    1015             :                             {
    1016         710 :                                 RTFValue::Pointer_t pValue(new RTFValue(m_aStates.top().aDestinationText.makeStringAndClear()));
    1017         710 :                                 m_aStates.top().aTableAttributes.set(NS_rtf::LN_XSZFFN, pValue);
    1018             : 
    1019             :                                 writerfilter::Reference<Properties>::Pointer_t const pProp(
    1020        2130 :                                         new RTFReferenceProperties(m_aStates.top().aTableAttributes, m_aStates.top().aTableSprms)
    1021        2840 :                                         );
    1022             : 
    1023             :                                 //See fdo#47347 initial invalid font entry properties are inserted first,
    1024             :                                 //so when we attempt to insert the correct ones, there's already an
    1025             :                                 //entry in the map for them, so the new ones aren't inserted.
    1026         710 :                                 RTFReferenceTable::Entries_t::iterator lb = m_aFontTableEntries.lower_bound(m_nCurrentFontIndex);
    1027         710 :                                 if (lb != m_aFontTableEntries.end() && !(m_aFontTableEntries.key_comp()(m_nCurrentFontIndex, lb->first)))
    1028           0 :                                     lb->second = pProp;
    1029             :                                 else
    1030        1420 :                                     m_aFontTableEntries.insert(lb, make_pair(m_nCurrentFontIndex, pProp));
    1031             :                             }
    1032         710 :                             break;
    1033             :                         case DESTINATION_STYLESHEET:
    1034             :                         case DESTINATION_STYLEENTRY:
    1035         417 :                             if (m_aStates.top().aTableAttributes.find(NS_rtf::LN_SGC))
    1036             :                             {
    1037         402 :                                 RTFValue::Pointer_t pValue(new RTFValue(m_aStates.top().aDestinationText.makeStringAndClear()));
    1038         402 :                                 m_aStates.top().aTableAttributes.set(NS_rtf::LN_XSTZNAME1, pValue);
    1039             : 
    1040             :                                 writerfilter::Reference<Properties>::Pointer_t const pProp(
    1041         402 :                                         new RTFReferenceProperties(mergeAttributes(), mergeSprms())
    1042        1206 :                                         );
    1043         804 :                                 m_aStyleTableEntries.insert(make_pair(m_nCurrentStyleIndex, pProp));
    1044             :                             }
    1045             :                             else
    1046             :                                 SAL_INFO("writerfilter", "no RTF style type defined, ignoring");
    1047         417 :                             break;
    1048             :                         case DESTINATION_REVISIONTABLE:
    1049             :                         case DESTINATION_REVISIONENTRY:
    1050           3 :                             m_aAuthors[m_aAuthors.size()] = m_aStates.top().aDestinationText.makeStringAndClear();
    1051           3 :                             break;
    1052           0 :                         default: break;
    1053             :                     }
    1054        1130 :                     resetAttributes();
    1055        1130 :                     resetSprms();
    1056             :                 }
    1057             :             }
    1058        1299 :             break;
    1059             :         case DESTINATION_LEVELTEXT:
    1060             :         case DESTINATION_SHAPEPROPERTYNAME:
    1061             :         case DESTINATION_SHAPEPROPERTYVALUE:
    1062             :         case DESTINATION_BOOKMARKEND:
    1063             :         case DESTINATION_PICT:
    1064             :         case DESTINATION_SHAPEPROPERTYVALUEPICT:
    1065             :         case DESTINATION_FORMFIELDNAME:
    1066             :         case DESTINATION_FORMFIELDLIST:
    1067             :         case DESTINATION_DATAFIELD:
    1068             :         case DESTINATION_AUTHOR:
    1069             :         case DESTINATION_KEYWORDS:
    1070             :         case DESTINATION_OPERATOR:
    1071             :         case DESTINATION_COMPANY:
    1072             :         case DESTINATION_COMMENT:
    1073             :         case DESTINATION_OBJDATA:
    1074             :         case DESTINATION_ANNOTATIONDATE:
    1075             :         case DESTINATION_ANNOTATIONAUTHOR:
    1076             :         case DESTINATION_FALT:
    1077             :         case DESTINATION_PARAGRAPHNUMBERING_TEXTAFTER:
    1078             :         case DESTINATION_PARAGRAPHNUMBERING_TEXTBEFORE:
    1079             :         case DESTINATION_TITLE:
    1080             :         case DESTINATION_SUBJECT:
    1081             :         case DESTINATION_DOCCOMM:
    1082             :         case DESTINATION_ATNID:
    1083             :         case DESTINATION_MR:
    1084             :         case DESTINATION_MCHR:
    1085             :         case DESTINATION_MPOS:
    1086             :         case DESTINATION_MVERTJC:
    1087             :         case DESTINATION_MSTRIKEH:
    1088             :         case DESTINATION_MDEGHIDE:
    1089             :         case DESTINATION_MBEGCHR:
    1090             :         case DESTINATION_MSEPCHR:
    1091             :         case DESTINATION_MENDCHR:
    1092             :         case DESTINATION_MSUBHIDE:
    1093             :         case DESTINATION_MSUPHIDE:
    1094             :         case DESTINATION_MTYPE:
    1095             :         case DESTINATION_MGROW:
    1096        1939 :             m_aStates.top().aDestinationText.append(rString);
    1097        1939 :             break;
    1098             :         default:
    1099        4197 :             bRet = false;
    1100        4197 :             break;
    1101             :     }
    1102        7435 :     if (bRet)
    1103        3238 :         return;
    1104             : 
    1105        4197 :     if (!m_aIgnoreFirst.isEmpty() && m_aIgnoreFirst.equals(rString))
    1106             :     {
    1107           0 :         m_aIgnoreFirst = OUString();
    1108           0 :         return;
    1109             :     }
    1110             : 
    1111             :     // Are we in the middle of the table definition? (No cell defs yet, but we already have some cell props.)
    1112        4198 :     if (m_aStates.top().aTableCellSprms.find(NS_ooxml::LN_CT_TcPrBase_vAlign).get() &&
    1113           1 :         m_aStates.top().nCells == 0)
    1114             :     {
    1115           1 :         m_aTableBuffer.push_back(make_pair(BUFFER_UTEXT, RTFValue::Pointer_t(new RTFValue(rString))));
    1116           1 :         return;
    1117             :     }
    1118             : 
    1119        4196 :     checkFirstRun();
    1120        4196 :     checkNeedPap();
    1121             : 
    1122             :     // Don't return earlier, a bookmark start has to be in a paragraph group.
    1123        4196 :     if (m_aStates.top().nDestinationState == DESTINATION_BOOKMARKSTART)
    1124             :     {
    1125           2 :         m_aStates.top().aDestinationText.append(rString);
    1126           2 :         return;
    1127             :     }
    1128             : 
    1129        4194 :     RTFBuffer_t* pCurrentBuffer = m_aStates.top().pCurrentBuffer;
    1130             : 
    1131        4194 :     if (!pCurrentBuffer && m_aStates.top().nDestinationState != DESTINATION_FOOTNOTE)
    1132        3999 :         Mapper().startCharacterGroup();
    1133         195 :     else if (pCurrentBuffer)
    1134             :     {
    1135         195 :         RTFValue::Pointer_t pValue;
    1136         195 :         pCurrentBuffer->push_back(make_pair(BUFFER_STARTRUN, pValue));
    1137             :     }
    1138             : 
    1139        8388 :     if (m_aStates.top().nDestinationState == DESTINATION_NORMAL
    1140          31 :             || m_aStates.top().nDestinationState == DESTINATION_FIELDRESULT
    1141        4222 :             || m_aStates.top().nDestinationState == DESTINATION_SHAPETEXT)
    1142        4181 :         runProps();
    1143             : 
    1144        4194 :     if (!pCurrentBuffer)
    1145        3999 :         Mapper().utext(reinterpret_cast<sal_uInt8 const*>(rString.getStr()), rString.getLength());
    1146             :     else
    1147             :     {
    1148         195 :         RTFValue::Pointer_t pValue(new RTFValue(rString));
    1149         195 :         pCurrentBuffer->push_back(make_pair(BUFFER_UTEXT, pValue));
    1150             :     }
    1151             : 
    1152        4194 :     m_bNeedCr = true;
    1153             : 
    1154        4194 :     if (!pCurrentBuffer && m_aStates.top().nDestinationState != DESTINATION_FOOTNOTE)
    1155        3999 :         Mapper().endCharacterGroup();
    1156         195 :     else if(pCurrentBuffer)
    1157             :     {
    1158         195 :         RTFValue::Pointer_t pValue;
    1159         195 :         pCurrentBuffer->push_back(make_pair(BUFFER_ENDRUN, pValue));
    1160             :     }
    1161             : }
    1162             : 
    1163         255 : void RTFDocumentImpl::replayBuffer(RTFBuffer_t& rBuffer)
    1164             : {
    1165        1516 :     while (rBuffer.size())
    1166             :     {
    1167        1160 :         std::pair<RTFBufferTypes, RTFValue::Pointer_t> aPair = rBuffer.front();
    1168        1160 :         rBuffer.pop_front();
    1169        1160 :         if (aPair.first == BUFFER_PROPS)
    1170             :         {
    1171             :             writerfilter::Reference<Properties>::Pointer_t const pProp(
    1172        1203 :                     new RTFReferenceProperties(aPair.second->getAttributes(), aPair.second->getSprms())
    1173        1203 :                     );
    1174         401 :             Mapper().props(pProp);
    1175             :         }
    1176         759 :         else if (aPair.first == BUFFER_CELLEND)
    1177             :         {
    1178         154 :             RTFValue::Pointer_t pValue(new RTFValue(1));
    1179         154 :             m_aStates.top().aTableCellSprms.set(NS_sprm::LN_PCell, pValue);
    1180             :             writerfilter::Reference<Properties>::Pointer_t const pTableCellProperties(
    1181         462 :                     new RTFReferenceProperties(m_aStates.top().aTableCellAttributes, m_aStates.top().aTableCellSprms)
    1182         616 :                     );
    1183         154 :             Mapper().props(pTableCellProperties);
    1184         154 :             tableBreak();
    1185         308 :             break;
    1186             :         }
    1187         605 :         else if (aPair.first == BUFFER_STARTRUN)
    1188         198 :             Mapper().startCharacterGroup();
    1189         407 :         else if (aPair.first == BUFFER_TEXT)
    1190             :         {
    1191           3 :             sal_uInt8 nValue = aPair.second->getInt();
    1192           3 :             Mapper().text(&nValue, 1);
    1193             :         }
    1194         404 :         else if (aPair.first == BUFFER_UTEXT)
    1195             :         {
    1196         196 :             OUString aString(aPair.second->getString());
    1197         196 :             Mapper().utext(reinterpret_cast<sal_uInt8 const*>(aString.getStr()), aString.getLength());
    1198             :         }
    1199         208 :         else if (aPair.first == BUFFER_ENDRUN)
    1200         198 :             Mapper().endCharacterGroup();
    1201          10 :         else if (aPair.first == BUFFER_PAR)
    1202           8 :             parBreak();
    1203           2 :         else if (aPair.first == BUFFER_STARTSHAPE)
    1204           1 :             m_pSdrImport->resolve(aPair.second->getShape(), false);
    1205           1 :         else if (aPair.first == BUFFER_ENDSHAPE)
    1206           1 :             m_pSdrImport->close();
    1207             :         else
    1208             :             SAL_WARN("writerfilter", "should not happen");
    1209        1006 :     }
    1210             : 
    1211         255 : }
    1212             : 
    1213        4315 : int RTFDocumentImpl::dispatchDestination(RTFKeyword nKeyword)
    1214             : {
    1215        4315 :     checkUnicode(/*bUnicode =*/ true, /*bHex =*/ true);
    1216        4315 :     setNeedSect();
    1217        4315 :     RTFSkipDestination aSkip(*this);
    1218        4315 :     switch (nKeyword)
    1219             :     {
    1220             :         case RTF_RTF:
    1221         192 :             break;
    1222             :         case RTF_FONTTBL:
    1223          77 :             m_aStates.top().nDestinationState = DESTINATION_FONTTABLE;
    1224          77 :             break;
    1225             :         case RTF_COLORTBL:
    1226          61 :             m_aStates.top().nDestinationState = DESTINATION_COLORTABLE;
    1227          61 :             break;
    1228             :         case RTF_STYLESHEET:
    1229          63 :             m_aStates.top().nDestinationState = DESTINATION_STYLESHEET;
    1230          63 :             break;
    1231             :         case RTF_FIELD:
    1232          10 :             m_aStates.top().nDestinationState = DESTINATION_FIELD;
    1233          10 :             break;
    1234             :         case RTF_FLDINST:
    1235             :             {
    1236             :                 // Look for the field type
    1237          10 :                 sal_Int32 nPos = Strm().Tell();
    1238          10 :                 OStringBuffer aBuf;
    1239          10 :                 char ch = 0;
    1240          10 :                 bool bFoundCode = false;
    1241          10 :                 bool bInKeyword = false;
    1242         159 :                 while (!bFoundCode && ch != '}')
    1243             :                 {
    1244         139 :                     Strm() >> ch;
    1245         139 :                     if ('\\' == ch)
    1246           9 :                         bInKeyword = true;
    1247         139 :                     if (!bInKeyword  && isalnum(ch))
    1248          58 :                         aBuf.append(ch);
    1249          81 :                     else if (bInKeyword && isspace(ch))
    1250           5 :                         bInKeyword = false;
    1251         139 :                     if (!aBuf.isEmpty() && !isalnum(ch))
    1252          10 :                         bFoundCode = true;
    1253             :                 }
    1254          10 :                 Strm().Seek(nPos);
    1255             : 
    1256             :                 // Form data should be handled only for form fields if any
    1257          10 :                 if (aBuf.toString().indexOf(OString("FORM")) != -1 )
    1258           0 :                     m_bFormField = true;
    1259             : 
    1260          10 :                 singleChar(0x13);
    1261          10 :                 m_aStates.top().nDestinationState = DESTINATION_FIELDINSTRUCTION;
    1262             :             }
    1263          10 :             break;
    1264             :         case RTF_FLDRSLT:
    1265           8 :             m_aStates.top().nDestinationState = DESTINATION_FIELDRESULT;
    1266           8 :             break;
    1267             :         case RTF_LISTTABLE:
    1268          10 :             m_aStates.top().nDestinationState = DESTINATION_LISTTABLE;
    1269          10 :             break;
    1270             :         case RTF_LISTPICTURE:
    1271           2 :             m_aStates.top().nDestinationState = DESTINATION_LISTPICTURE;
    1272           2 :             m_aStates.top().bInListpicture = true;
    1273           2 :             break;
    1274             :         case RTF_LIST:
    1275          11 :             m_aStates.top().nDestinationState = DESTINATION_LISTENTRY;
    1276          11 :             break;
    1277             :         case RTF_LFOLEVEL:
    1278           1 :             m_aStates.top().nDestinationState = DESTINATION_LFOLEVEL;
    1279           1 :             m_aStates.top().aTableSprms.clear();
    1280           1 :             break;
    1281             :         case RTF_LISTOVERRIDETABLE:
    1282           9 :             m_aStates.top().nDestinationState = DESTINATION_LISTOVERRIDETABLE;
    1283           9 :             break;
    1284             :         case RTF_LISTOVERRIDE:
    1285          10 :             m_aStates.top().nDestinationState = DESTINATION_LISTOVERRIDEENTRY;
    1286          10 :             break;
    1287             :         case RTF_LISTLEVEL:
    1288          31 :             m_aStates.top().nDestinationState = DESTINATION_LISTLEVEL;
    1289          31 :             break;
    1290             :         case RTF_LEVELTEXT:
    1291          32 :             m_aStates.top().nDestinationState = DESTINATION_LEVELTEXT;
    1292          32 :             break;
    1293             :         case RTF_LEVELNUMBERS:
    1294          33 :             m_aStates.top().nDestinationState = DESTINATION_LEVELNUMBERS;
    1295          33 :             break;
    1296             :         case RTF_SHPPICT:
    1297           7 :             m_aStates.top().resetFrame();
    1298           7 :             m_aStates.top().nDestinationState = DESTINATION_SHPPICT;
    1299           7 :             break;
    1300             :         case RTF_PICT:
    1301          14 :             if (m_aStates.top().nDestinationState != DESTINATION_SHAPEPROPERTYVALUE)
    1302          10 :                 m_aStates.top().nDestinationState = DESTINATION_PICT; // as character
    1303             :             else
    1304           4 :                 m_aStates.top().nDestinationState = DESTINATION_SHAPEPROPERTYVALUEPICT; // anchored inside a shape
    1305          14 :             break;
    1306             :         case RTF_PICPROP:
    1307           3 :             m_aStates.top().nDestinationState = DESTINATION_PICPROP;
    1308           3 :             break;
    1309             :         case RTF_SP:
    1310         426 :             m_aStates.top().nDestinationState = DESTINATION_SHAPEPROPERTY;
    1311         426 :             break;
    1312             :         case RTF_SN:
    1313         426 :             m_aStates.top().nDestinationState = DESTINATION_SHAPEPROPERTYNAME;
    1314         426 :             break;
    1315             :         case RTF_SV:
    1316         426 :             m_aStates.top().nDestinationState = DESTINATION_SHAPEPROPERTYVALUE;
    1317         426 :             break;
    1318             :         case RTF_SHP:
    1319          43 :             m_bNeedCrOrig = m_bNeedCr;
    1320          43 :             m_aStates.top().nDestinationState = DESTINATION_SHAPE;
    1321          43 :             break;
    1322             :         case RTF_SHPINST:
    1323          44 :             m_aStates.top().nDestinationState = DESTINATION_SHAPEINSTRUCTION;
    1324          44 :             break;
    1325             :         case RTF_NESTTABLEPROPS:
    1326             :             // Don't try to support nested tables having table styles for now.
    1327           3 :             if (!m_aStates.top().bHasTableStyle)
    1328           0 :                 m_aStates.top().nDestinationState = DESTINATION_NESTEDTABLEPROPERTIES;
    1329             :             else
    1330           3 :                 m_aStates.top().nDestinationState = DESTINATION_SKIP;
    1331           3 :             break;
    1332             :         case RTF_HEADER:
    1333             :         case RTF_FOOTER:
    1334             :         case RTF_HEADERL:
    1335             :         case RTF_HEADERR:
    1336             :         case RTF_HEADERF:
    1337             :         case RTF_FOOTERL:
    1338             :         case RTF_FOOTERR:
    1339             :         case RTF_FOOTERF:
    1340          12 :             if (!m_pSuperstream)
    1341             :             {
    1342           6 :                 Id nId = 0;
    1343           6 :                 sal_uInt32 nPos = m_nGroupStartPos - 1;
    1344           6 :                 switch (nKeyword)
    1345             :                 {
    1346           4 :                     case RTF_HEADER: nId = NS_rtf::LN_headerr; break;
    1347           0 :                     case RTF_FOOTER: nId = NS_rtf::LN_footerr; break;
    1348           0 :                     case RTF_HEADERL: nId = NS_rtf::LN_headerl; break;
    1349           1 :                     case RTF_HEADERR: nId = NS_rtf::LN_headerr; break;
    1350           1 :                     case RTF_HEADERF: nId = NS_rtf::LN_headerf; break;
    1351           0 :                     case RTF_FOOTERL: nId = NS_rtf::LN_footerl; break;
    1352           0 :                     case RTF_FOOTERR: nId = NS_rtf::LN_footerr; break;
    1353           0 :                     case RTF_FOOTERF: nId = NS_rtf::LN_footerf; break;
    1354           0 :                     default: break;
    1355             :                 }
    1356           6 :                 m_nHeaderFooterPositions.push(make_pair(nId, nPos));
    1357           6 :                 m_aStates.top().nDestinationState = DESTINATION_SKIP;
    1358             :             }
    1359          12 :             break;
    1360             :         case RTF_FOOTNOTE:
    1361          10 :             if (!m_pSuperstream)
    1362             :             {
    1363           5 :                 Id nId = NS_rtf::LN_footnote;
    1364             : 
    1365             :                 // Check if this is an endnote.
    1366           5 :                 OStringBuffer aBuf;
    1367             :                 char ch;
    1368          40 :                 for (int i = 0; i < 7; ++i)
    1369             :                 {
    1370          35 :                     Strm() >> ch;
    1371          35 :                     aBuf.append(ch);
    1372             :                 }
    1373          10 :                 OString aKeyword = aBuf.makeStringAndClear();
    1374           5 :                 if (aKeyword.equals("\\ftnalt"))
    1375           0 :                     nId = NS_rtf::LN_endnote;
    1376             : 
    1377           5 :                 m_bHasFootnote = true;
    1378           5 :                 if (m_aStates.top().pCurrentBuffer == &m_aSuperBuffer)
    1379           3 :                     m_aStates.top().pCurrentBuffer = 0;
    1380           5 :                 bool bCustomMark = false;
    1381          10 :                 OUString aCustomMark;
    1382          10 :                 while (m_aSuperBuffer.size())
    1383             :                 {
    1384           0 :                     std::pair<RTFBufferTypes, RTFValue::Pointer_t> aPair = m_aSuperBuffer.front();
    1385           0 :                     m_aSuperBuffer.pop_front();
    1386           0 :                     if (aPair.first == BUFFER_UTEXT)
    1387             :                     {
    1388           0 :                         aCustomMark = aPair.second->getString();
    1389           0 :                         bCustomMark = true;
    1390             :                     }
    1391           0 :                 }
    1392           5 :                 m_aStates.top().nDestinationState = DESTINATION_FOOTNOTE;
    1393           5 :                 if (bCustomMark)
    1394           0 :                     Mapper().startCharacterGroup();
    1395           5 :                 resolveSubstream(m_nGroupStartPos - 1, nId, aCustomMark);
    1396           5 :                 if (bCustomMark)
    1397             :                 {
    1398           0 :                     m_aStates.top().aCharacterAttributes.clear();
    1399           0 :                     m_aStates.top().aCharacterSprms.clear();
    1400           0 :                     RTFValue::Pointer_t pValue(new RTFValue(1));
    1401           0 :                     m_aStates.top().aCharacterAttributes.set(NS_ooxml::LN_CT_FtnEdnRef_customMarkFollows, pValue);
    1402           0 :                     text(aCustomMark);
    1403           0 :                     Mapper().endCharacterGroup();
    1404             :                 }
    1405          10 :                 m_aStates.top().nDestinationState = DESTINATION_SKIP;
    1406             :             }
    1407          10 :             break;
    1408             :         case RTF_BKMKSTART:
    1409           2 :             m_aStates.top().nDestinationState = DESTINATION_BOOKMARKSTART;
    1410           2 :             break;
    1411             :         case RTF_BKMKEND:
    1412           2 :             m_aStates.top().nDestinationState = DESTINATION_BOOKMARKEND;
    1413           2 :             break;
    1414             :         case RTF_REVTBL:
    1415           2 :             m_aStates.top().nDestinationState = DESTINATION_REVISIONTABLE;
    1416           2 :             break;
    1417             :         case RTF_ANNOTATION:
    1418           4 :             if (!m_pSuperstream)
    1419             :             {
    1420           2 :                 resolveSubstream(m_nGroupStartPos - 1, NS_rtf::LN_annotation);
    1421           2 :                 m_aStates.top().nDestinationState = DESTINATION_SKIP;
    1422             :             }
    1423             :             else
    1424             :             {
    1425             :                 // If there is an author set, emit it now.
    1426           2 :                 if (!m_aAuthor.isEmpty() || !m_aAuthorInitials.isEmpty())
    1427             :                 {
    1428           2 :                     RTFSprms aAttributes;
    1429           2 :                     if (!m_aAuthor.isEmpty())
    1430             :                     {
    1431           2 :                         RTFValue::Pointer_t pValue(new RTFValue(m_aAuthor));
    1432           2 :                         aAttributes.set(NS_ooxml::LN_CT_TrackChange_author, pValue);
    1433             :                     }
    1434           2 :                     if (!m_aAuthorInitials.isEmpty())
    1435             :                     {
    1436           2 :                         RTFValue::Pointer_t pValue(new RTFValue(m_aAuthorInitials));
    1437           2 :                         aAttributes.set(NS_ooxml::LN_CT_Comment_initials, pValue);
    1438             :                     }
    1439           4 :                     writerfilter::Reference<Properties>::Pointer_t const pProperties(new RTFReferenceProperties(aAttributes));
    1440           4 :                     Mapper().props(pProperties);
    1441             :                 }
    1442             :             }
    1443           4 :             break;
    1444             :         case RTF_SHPTXT:
    1445             :         case RTF_DPTXBXTEXT:
    1446          27 :             m_aStates.top().nDestinationState = DESTINATION_SHAPETEXT;
    1447          27 :             checkFirstRun();
    1448          27 :             dispatchFlag(RTF_PARD);
    1449          27 :             m_bNeedPap = true;
    1450          27 :             if (nKeyword == RTF_SHPTXT)
    1451             :             {
    1452          20 :                 if (!m_aStates.top().pCurrentBuffer)
    1453          19 :                     m_pSdrImport->resolve(m_aStates.top().aShape, false);
    1454             :                 else
    1455             :                 {
    1456           1 :                     RTFValue::Pointer_t pValue(new RTFValue(m_aStates.top().aShape));
    1457           1 :                     m_aStates.top().pCurrentBuffer->push_back(make_pair(BUFFER_STARTSHAPE, pValue));
    1458             :                 }
    1459             :             }
    1460          27 :             break;
    1461             :         case RTF_FORMFIELD:
    1462           0 :             if (m_aStates.top().nDestinationState == DESTINATION_FIELDINSTRUCTION)
    1463           0 :                 m_aStates.top().nDestinationState = DESTINATION_FORMFIELD;
    1464           0 :             break;
    1465             :         case RTF_FFNAME:
    1466           0 :             m_aStates.top().nDestinationState = DESTINATION_FORMFIELDNAME;
    1467           0 :             break;
    1468             :         case RTF_FFL:
    1469           0 :             m_aStates.top().nDestinationState = DESTINATION_FORMFIELDLIST;
    1470           0 :             break;
    1471             :         case RTF_DATAFIELD:
    1472           0 :             m_aStates.top().nDestinationState = DESTINATION_DATAFIELD;
    1473           0 :             break;
    1474             :         case RTF_INFO:
    1475          58 :             m_aStates.top().nDestinationState = DESTINATION_INFO;
    1476          58 :             break;
    1477             :         case RTF_CREATIM:
    1478          47 :             m_aStates.top().nDestinationState = DESTINATION_CREATIONTIME;
    1479          47 :             break;
    1480             :         case RTF_REVTIM:
    1481          47 :             m_aStates.top().nDestinationState = DESTINATION_REVISIONTIME;
    1482          47 :             break;
    1483             :         case RTF_PRINTIM:
    1484          45 :             m_aStates.top().nDestinationState = DESTINATION_PRINTTIME;
    1485          45 :             break;
    1486             :         case RTF_AUTHOR:
    1487          11 :             m_aStates.top().nDestinationState = DESTINATION_AUTHOR;
    1488          11 :             break;
    1489             :         case RTF_KEYWORDS:
    1490           2 :             m_aStates.top().nDestinationState = DESTINATION_KEYWORDS;
    1491           2 :             break;
    1492             :         case RTF_OPERATOR:
    1493           3 :             m_aStates.top().nDestinationState = DESTINATION_OPERATOR;
    1494           3 :             break;
    1495             :         case RTF_COMPANY:
    1496           5 :             m_aStates.top().nDestinationState = DESTINATION_COMPANY;
    1497           5 :             break;
    1498             :         case RTF_COMMENT:
    1499          46 :             m_aStates.top().nDestinationState = DESTINATION_COMMENT;
    1500          46 :             break;
    1501             :         case RTF_OBJECT:
    1502             :             {
    1503             :                 // beginning of an OLE Object
    1504           1 :                 m_aStates.top().nDestinationState = DESTINATION_OBJECT;
    1505             : 
    1506             :                 // check if the object is in a special container (e.g. a table)
    1507           1 :                 if (!m_aStates.top().pCurrentBuffer)
    1508             :                 {
    1509             :                     // the object is in a table or another container.
    1510             :                     // Don't try to treate it as an OLE object (fdo#53594).
    1511             :                     // Use the \result (RTF_RESULT) element of the object instead,
    1512             :                     // the result element contain picture representing the OLE Object.
    1513           0 :                     m_bObject = true;
    1514             :                 }
    1515             :             }
    1516           1 :             break;
    1517             :         case RTF_OBJDATA:
    1518             :             // check if the object is in a special container (e.g. a table)
    1519           1 :             if (m_aStates.top().pCurrentBuffer)
    1520             :             {
    1521             :                 // the object is in a table or another container.
    1522             :                 // Use the \result (RTF_RESULT) element of the object instead,
    1523             :                 // of the \objdata.
    1524           1 :                 m_aStates.top().nDestinationState = DESTINATION_SKIP;
    1525             :             }
    1526             :             else
    1527             :             {
    1528           0 :                 m_aStates.top().nDestinationState = DESTINATION_OBJDATA;
    1529             :             }
    1530           1 :             break;
    1531             :         case RTF_RESULT:
    1532           1 :             m_aStates.top().nDestinationState = DESTINATION_RESULT;
    1533           1 :             break;
    1534             :         case RTF_ATNDATE:
    1535           2 :             m_aStates.top().nDestinationState = DESTINATION_ANNOTATIONDATE;
    1536           2 :             break;
    1537             :         case RTF_ATNAUTHOR:
    1538           2 :             m_aStates.top().nDestinationState = DESTINATION_ANNOTATIONAUTHOR;
    1539           2 :             break;
    1540             :         case RTF_FALT:
    1541         153 :             m_aStates.top().nDestinationState = DESTINATION_FALT;
    1542         153 :             break;
    1543             :         case RTF_FLYMAINCNT:
    1544           1 :             m_aStates.top().nDestinationState = DESTINATION_FLYMAINCONTENT;
    1545           1 :             break;
    1546             :         case RTF_LISTTEXT:
    1547             :             // Should be ignored by any reader that understands Word 97 through Word 2007 numbering.
    1548             :         case RTF_NONESTTABLES:
    1549             :             // This destination should be ignored by readers that support nested tables.
    1550          12 :             m_aStates.top().nDestinationState = DESTINATION_SKIP;
    1551          12 :             break;
    1552             :         case RTF_DO:
    1553          18 :             m_aStates.top().nDestinationState = DESTINATION_DRAWINGOBJECT;
    1554          18 :             break;
    1555             :         case RTF_PN:
    1556           4 :             m_aStates.top().nDestinationState = DESTINATION_PARAGRAPHNUMBERING;
    1557           4 :             break;
    1558             :         case RTF_PNTEXT:
    1559             :             // This destination should be ignored by readers that support paragraph numbering.
    1560           0 :             m_aStates.top().nDestinationState = DESTINATION_SKIP;
    1561           0 :             break;
    1562             :         case RTF_PNTXTA:
    1563           3 :             m_aStates.top().nDestinationState = DESTINATION_PARAGRAPHNUMBERING_TEXTAFTER;
    1564           3 :             break;
    1565             :         case RTF_PNTXTB:
    1566           3 :             m_aStates.top().nDestinationState = DESTINATION_PARAGRAPHNUMBERING_TEXTBEFORE;
    1567           3 :             break;
    1568             :         case RTF_TITLE:
    1569             :             // \title inside \upr but outside \ud should be ignored.
    1570          10 :             if (m_aStates.top().nDestinationState != DESTINATION_UPR)
    1571           8 :                 m_aStates.top().nDestinationState = DESTINATION_TITLE;
    1572             :             else
    1573           2 :                 m_aStates.top().nDestinationState = DESTINATION_SKIP;
    1574          10 :             break;
    1575             :         case RTF_SUBJECT:
    1576           3 :             m_aStates.top().nDestinationState = DESTINATION_SUBJECT;
    1577           3 :             break;
    1578             :         case RTF_DOCCOMM:
    1579           4 :             m_aStates.top().nDestinationState = DESTINATION_DOCCOMM;
    1580           4 :             break;
    1581             :         case RTF_ATRFSTART:
    1582             :         case RTF_ATRFEND:
    1583             :             {
    1584             :                 // We could send the real value here, but that would make the
    1585             :                 // tokenizer more complicated, and dmapper doesn't read the
    1586             :                 // result anyway.
    1587           4 :                 RTFValue::Pointer_t pValue(new RTFValue(0));
    1588           4 :                 m_aStates.top().nDestinationState = DESTINATION_SKIP;
    1589             : 
    1590           8 :                 RTFSprms aAttributes;
    1591           4 :                 if (nKeyword == RTF_ATRFSTART)
    1592           2 :                     aAttributes.set(NS_ooxml::LN_EG_RangeMarkupElements_commentRangeStart, pValue);
    1593             :                 else
    1594           2 :                     aAttributes.set(NS_ooxml::LN_EG_RangeMarkupElements_commentRangeEnd, pValue);
    1595           8 :                 writerfilter::Reference<Properties>::Pointer_t const pProperties(new RTFReferenceProperties(aAttributes));
    1596           8 :                 Mapper().props(pProperties);
    1597             :             }
    1598           4 :             break;
    1599             :         case RTF_ATNID:
    1600           2 :             m_aStates.top().nDestinationState = DESTINATION_ATNID;
    1601           2 :             break;
    1602             :         case RTF_MMATH:
    1603             :         case RTF_MOMATHPARA:
    1604             :             // Nothing to do here (just enter the destination) till RTF_MMATHPR is implemented.
    1605          90 :             break;
    1606         508 :         case RTF_MR: m_aStates.top().nDestinationState = DESTINATION_MR; break;
    1607          42 :         case RTF_MCHR: m_aStates.top().nDestinationState = DESTINATION_MCHR; break;
    1608           4 :         case RTF_MPOS: m_aStates.top().nDestinationState = DESTINATION_MPOS; break;
    1609           3 :         case RTF_MVERTJC: m_aStates.top().nDestinationState = DESTINATION_MVERTJC; break;
    1610           2 :         case RTF_MSTRIKEH: m_aStates.top().nDestinationState = DESTINATION_MSTRIKEH; break;
    1611           4 :         case RTF_MDEGHIDE: m_aStates.top().nDestinationState = DESTINATION_MDEGHIDE; break;
    1612           6 :         case RTF_MTYPE: m_aStates.top().nDestinationState = DESTINATION_MTYPE; break;
    1613           2 :         case RTF_MGROW: m_aStates.top().nDestinationState = DESTINATION_MGROW; break;
    1614             :         case RTF_MHIDETOP:
    1615             :         case RTF_MHIDEBOT:
    1616             :         case RTF_MHIDELEFT:
    1617             :         case RTF_MHIDERIGHT:
    1618             :             // SmOoxmlImport::handleBorderBox will ignore these anyway, so silently ignore for now.
    1619           8 :             m_aStates.top().nDestinationState = DESTINATION_SKIP;
    1620           8 :             break;
    1621           2 :         case RTF_MSUBHIDE: m_aStates.top().nDestinationState = DESTINATION_MSUBHIDE; break;
    1622           2 :         case RTF_MSUPHIDE: m_aStates.top().nDestinationState = DESTINATION_MSUPHIDE; break;
    1623          32 :         case RTF_MBEGCHR: m_aStates.top().nDestinationState = DESTINATION_MBEGCHR; break;
    1624           3 :         case RTF_MSEPCHR: m_aStates.top().nDestinationState = DESTINATION_MSEPCHR; break;
    1625          32 :         case RTF_MENDCHR: m_aStates.top().nDestinationState = DESTINATION_MENDCHR; break;
    1626          61 :         OPEN_M_TOKEN(OMATH, oMath);
    1627          34 :         OPEN_M_TOKEN(F, f);
    1628          20 :         OPEN_M_TOKEN(FPR, fPr);
    1629         108 :         OPEN_M_TOKEN(CTRLPR, ctrlPr);
    1630          34 :         OPEN_M_TOKEN(NUM, num);
    1631          34 :         OPEN_M_TOKEN(DEN, den);
    1632          24 :         OPEN_M_TOKEN(ACC, acc);
    1633          24 :         OPEN_M_TOKEN(ACCPR, accPr);
    1634           2 :         OPEN_M_TOKEN(BAR, bar);
    1635           2 :         OPEN_M_TOKEN(BARPR, barPr);
    1636         201 :         OPEN_M_TOKEN(E, e);
    1637          45 :         OPEN_M_TOKEN(D, d);
    1638          45 :         OPEN_M_TOKEN(DPR, dPr);
    1639          12 :         OPEN_M_TOKEN(FUNC, func);
    1640          11 :         OPEN_M_TOKEN(FUNCPR, funcPr);
    1641          12 :         OPEN_M_TOKEN(FNAME, fName);
    1642           6 :         OPEN_M_TOKEN(LIMLOW, limLow);
    1643           3 :         OPEN_M_TOKEN(LIMLOWPR, limLowPr);
    1644          10 :         OPEN_M_TOKEN(LIM, lim);
    1645           2 :         OPEN_M_TOKEN(M, m);
    1646           1 :         OPEN_M_TOKEN(MPR, mPr);
    1647           4 :         OPEN_M_TOKEN(MR, mr);
    1648          17 :         OPEN_M_TOKEN(NARY, nary);
    1649          17 :         OPEN_M_TOKEN(NARYPR, naryPr);
    1650          33 :         OPEN_M_TOKEN(SUB, sub);
    1651          59 :         OPEN_M_TOKEN(SUP, sup);
    1652           4 :         OPEN_M_TOKEN(LIMUPP, limUpp);
    1653           2 :         OPEN_M_TOKEN(LIMUPPPR, limUppPr);
    1654           4 :         OPEN_M_TOKEN(GROUPCHR, groupChr);
    1655           4 :         OPEN_M_TOKEN(GROUPCHRPR, groupChrPr);
    1656           2 :         OPEN_M_TOKEN(BORDERBOX, borderBox);
    1657           2 :         OPEN_M_TOKEN(BORDERBOXPR, borderBoxPr);
    1658           6 :         OPEN_M_TOKEN(RAD, rad);
    1659           5 :         OPEN_M_TOKEN(RADPR, radPr);
    1660           6 :         OPEN_M_TOKEN(DEG, deg);
    1661           8 :         OPEN_M_TOKEN(SSUB, sSub);
    1662           4 :         OPEN_M_TOKEN(SSUBPR, sSubPr);
    1663          34 :         OPEN_M_TOKEN(SSUP, sSup);
    1664          17 :         OPEN_M_TOKEN(SSUPPR, sSupPr);
    1665           4 :         OPEN_M_TOKEN(SSUBSUP, sSubSup);
    1666           2 :         OPEN_M_TOKEN(SSUBSUPPR, sSubSupPr);
    1667           4 :         OPEN_M_TOKEN(SPRE, sPre);
    1668           2 :         OPEN_M_TOKEN(SPREPR, sPrePr);
    1669           1 :         OPEN_M_TOKEN(BOX, box);
    1670           6 :         OPEN_M_TOKEN(EQARR, eqArr);
    1671             :         case RTF_UPR:
    1672           3 :             m_aStates.top().nDestinationState = DESTINATION_UPR;
    1673           3 :             break;
    1674             :         case RTF_UD:
    1675             :             // Anything inside \ud is just normal Unicode content.
    1676           3 :             m_aStates.top().nDestinationState = DESTINATION_NORMAL;
    1677           3 :             break;
    1678             :         case RTF_BACKGROUND:
    1679           1 :             m_aStates.top().nDestinationState = DESTINATION_BACKGROUND;
    1680           1 :             m_aStates.top().bInBackground = true;
    1681           1 :             break;
    1682             :         case RTF_SHPGRP:
    1683             :             {
    1684           1 :                 RTFLookahead aLookahead(Strm(), m_pTokenizer->getGroupStart());
    1685             :                 SAL_WARN_IF(!aLookahead.hasTable(), "writerfilter", "no table in groupshape, should create it!");
    1686           1 :                 m_aStates.top().nDestinationState = DESTINATION_SHAPEGROUP;
    1687           1 :                 m_aStates.top().bInShapeGroup = true;
    1688             :             }
    1689           1 :             break;
    1690             :         default:
    1691             :             SAL_INFO("writerfilter", "TODO handle destination '" << lcl_RtfToString(nKeyword) << "'");
    1692             :             // Make sure we skip destinations (even without \*) till we don't handle them
    1693         130 :             m_aStates.top().nDestinationState = DESTINATION_SKIP;
    1694         130 :             aSkip.setParsed(false);
    1695         130 :             break;
    1696             :     }
    1697             : 
    1698        4315 :     return 0;
    1699             : }
    1700             : 
    1701       25254 : int RTFDocumentImpl::dispatchSymbol(RTFKeyword nKeyword)
    1702             : {
    1703       25254 :     if (nKeyword != RTF_HEXCHAR)
    1704        1805 :         checkUnicode(/*bUnicode =*/ true, /*bHex =*/ true);
    1705       25254 :     setNeedSect();
    1706       25254 :     RTFSkipDestination aSkip(*this);
    1707             : 
    1708       25254 :     if (RTF_LINE == nKeyword)
    1709             :     {   // very special handling since text() will eat lone '\n'
    1710          52 :         singleChar('\n');
    1711          52 :         return 0;
    1712             :     }
    1713             :     // Trivial symbols
    1714       25202 :     sal_uInt8 cCh = 0;
    1715       25202 :     switch (nKeyword)
    1716             :     {
    1717          41 :         case RTF_TAB: cCh = '\t'; break;
    1718          20 :         case RTF_BACKSLASH: cCh = '\\'; break;
    1719          23 :         case RTF_LBRACE: cCh = '{'; break;
    1720          20 :         case RTF_RBRACE: cCh = '}'; break;
    1721           9 :         case RTF_EMDASH: cCh = 151; break;
    1722          10 :         case RTF_ENDASH: cCh = 150; break;
    1723          15 :         case RTF_BULLET: cCh = 149; break;
    1724          16 :         case RTF_LQUOTE: cCh = 145; break;
    1725          13 :         case RTF_RQUOTE: cCh = 146; break;
    1726          22 :         case RTF_LDBLQUOTE: cCh = 147; break;
    1727           9 :         case RTF_RDBLQUOTE: cCh = 148; break;
    1728       25004 :         default: break;
    1729             :     }
    1730       25202 :     if (cCh > 0)
    1731             :     {
    1732         198 :         OUString aStr(OStringToOUString(OString(cCh), RTL_TEXTENCODING_MS_1252));
    1733         198 :         text(aStr);
    1734         198 :         return 0;
    1735             :     }
    1736             : 
    1737       25004 :     switch (nKeyword)
    1738             :     {
    1739             :         case RTF_IGNORE:
    1740             :             {
    1741         775 :                 m_bSkipUnknown = true;
    1742         775 :                 aSkip.setReset(false);
    1743         775 :                 return 0;
    1744             :             }
    1745             :             break;
    1746             :         case RTF_PAR:
    1747             :             {
    1748         458 :                 checkFirstRun();
    1749         458 :                 bool bNeedPap = m_bNeedPap;
    1750         458 :                 checkNeedPap();
    1751         458 :                 if (bNeedPap)
    1752         171 :                     runProps();
    1753         458 :                 if (!m_aStates.top().pCurrentBuffer)
    1754             :                 {
    1755         449 :                     parBreak();
    1756             :                     // Not in table? Reset max width.
    1757         449 :                     m_nCellxMax = 0;
    1758             :                 }
    1759           9 :                 else if (m_aStates.top().nDestinationState != DESTINATION_SHAPETEXT)
    1760             :                 {
    1761           9 :                     RTFValue::Pointer_t pValue;
    1762           9 :                     m_aStates.top().pCurrentBuffer->push_back(make_pair(BUFFER_PAR, pValue));
    1763             :                 }
    1764             :                 // but don't emit properties yet, since they may change till the first text token arrives
    1765         458 :                 m_bNeedPap = true;
    1766         458 :                 if (!m_aStates.top().aFrame.inFrame())
    1767         437 :                     m_bNeedPar = false;
    1768         458 :                 m_bNeedFinalPar = false;
    1769             :             }
    1770         458 :             break;
    1771             :         case RTF_SECT:
    1772             :             {
    1773           8 :                 m_bHadSect = true;
    1774           8 :                 if (m_bIgnoreNextContSectBreak)
    1775           2 :                     m_bIgnoreNextContSectBreak = false;
    1776             :                 else
    1777           6 :                     sectBreak();
    1778             :             }
    1779           8 :             break;
    1780             :         case RTF_NOBREAK:
    1781             :             {
    1782          23 :                 OUString aStr(SVT_HARD_SPACE);
    1783          23 :                 text(aStr);
    1784             :             }
    1785          23 :             break;
    1786             :         case RTF_NOBRKHYPH:
    1787             :             {
    1788           2 :                 OUString aStr(SVT_HARD_HYPHEN);
    1789           2 :                 text(aStr);
    1790             :             }
    1791           2 :             break;
    1792             :         case RTF_OPTHYPH:
    1793             :             {
    1794          13 :                 OUString aStr(SVT_SOFT_HYPHEN);
    1795          13 :                 text(aStr);
    1796             :             }
    1797          13 :             break;
    1798             :         case RTF_HEXCHAR:
    1799       23449 :             m_aStates.top().nInternalState = INTERNAL_HEX;
    1800       23449 :             break;
    1801             :         case RTF_CELL:
    1802             :         case RTF_NESTCELL:
    1803             :             {
    1804         155 :                 checkFirstRun();
    1805         155 :                 if (m_bNeedPap)
    1806             :                 {
    1807             :                     // There were no runs in the cell, so we need to send paragraph and character properties here.
    1808          35 :                     RTFValue::Pointer_t pPValue(new RTFValue(m_aStates.top().aParagraphAttributes, m_aStates.top().aParagraphSprms));
    1809          35 :                     m_aTableBuffer.push_back(make_pair(BUFFER_PROPS, pPValue));
    1810          70 :                     RTFValue::Pointer_t pCValue(new RTFValue(m_aStates.top().aCharacterAttributes, m_aStates.top().aCharacterSprms));
    1811          70 :                     m_aTableBuffer.push_back(make_pair(BUFFER_PROPS, pCValue));
    1812             :                 }
    1813             : 
    1814         155 :                 RTFValue::Pointer_t pValue;
    1815         155 :                 m_aTableBuffer.push_back(make_pair(BUFFER_CELLEND, pValue));
    1816         155 :                 m_bNeedPap = true;
    1817             :             }
    1818         155 :             break;
    1819             :         case RTF_ROW:
    1820             :         case RTF_NESTROW:
    1821             :             {
    1822             :                 // If the right edge of the last cell (row width) is smaller than the width of some other row, mimic the WW8 import: add a fake cell.
    1823          50 :                 if (nKeyword == RTF_ROW && m_aStates.top().nCellX < m_nCellxMax)
    1824           1 :                     dispatchValue(RTF_CELLX, m_nCellxMax);
    1825             : 
    1826          50 :                 if (m_aStates.top().nCells)
    1827             :                 {
    1828             :                     // Make a backup before we start popping elements
    1829          50 :                     m_aStates.top().aTableInheritingCellsSprms = m_aStates.top().aTableCellsSprms;
    1830          50 :                     m_aStates.top().aTableInheritingCellsAttributes = m_aStates.top().aTableCellsAttributes;
    1831          50 :                     m_aStates.top().nInheritingCells = m_aStates.top().nCells;
    1832             :                 }
    1833             :                 else
    1834             :                 {
    1835             :                     // No table definition? Then inherit from the previous row
    1836           0 :                     m_aStates.top().aTableCellsSprms = m_aStates.top().aTableInheritingCellsSprms;
    1837           0 :                     m_aStates.top().aTableCellsAttributes = m_aStates.top().aTableInheritingCellsAttributes;
    1838           0 :                     m_aStates.top().nCells = m_aStates.top().nInheritingCells;
    1839             :                     // This can't be the first row, and we need cell width only there
    1840           0 :                     while(m_aStates.top().aTableRowSprms.erase(NS_ooxml::LN_CT_TblGridBase_gridCol)) ;
    1841             :                 }
    1842         290 :                 for (int i = 0; i < m_aStates.top().nCells; ++i)
    1843             :                 {
    1844         240 :                     m_aStates.top().aTableCellSprms = m_aStates.top().aTableCellsSprms.front();
    1845         240 :                     m_aStates.top().aTableCellsSprms.pop_front();
    1846         240 :                     m_aStates.top().aTableCellAttributes = m_aStates.top().aTableCellsAttributes.front();
    1847         240 :                     m_aStates.top().aTableCellsAttributes.pop_front();
    1848         240 :                     replayBuffer(m_aTableBuffer);
    1849             :                 }
    1850          50 :                 m_aStates.top().aTableCellSprms = m_aDefaultState.aTableCellSprms;
    1851          50 :                 m_aStates.top().aTableCellAttributes = m_aDefaultState.aTableCellAttributes;
    1852             : 
    1853             :                 writerfilter::Reference<Properties>::Pointer_t const pParagraphProperties(
    1854         100 :                         getProperties(m_aStates.top().aParagraphAttributes, m_aStates.top().aParagraphSprms)
    1855         100 :                         );
    1856          50 :                 Mapper().props(pParagraphProperties);
    1857             : 
    1858          50 :                 if (m_aStates.top().aFrame.hasProperties())
    1859             :                 {
    1860             :                     writerfilter::Reference<Properties>::Pointer_t const pFrameProperties(
    1861           0 :                             new RTFReferenceProperties(RTFSprms(), m_aStates.top().aFrame.getSprms()));
    1862           0 :                     Mapper().props(pFrameProperties);
    1863             :                 }
    1864             : 
    1865             :                 // Table width.
    1866         100 :                 RTFValue::Pointer_t pUnitValue(new RTFValue(3));
    1867          50 :                 lcl_putNestedAttribute(m_aStates.top().aTableRowSprms,
    1868         100 :                         NS_ooxml::LN_CT_TblPrBase_tblW, NS_ooxml::LN_CT_TblWidth_type, pUnitValue);
    1869         100 :                 RTFValue::Pointer_t pWValue(new RTFValue(m_aStates.top().nCellX));
    1870          50 :                 lcl_putNestedAttribute(m_aStates.top().aTableRowSprms,
    1871         100 :                         NS_ooxml::LN_CT_TblPrBase_tblW, NS_ooxml::LN_CT_TblWidth_w, pWValue);
    1872             : 
    1873         100 :                 RTFValue::Pointer_t pRowValue(new RTFValue(1));
    1874          50 :                 if (m_aStates.top().nCells > 0)
    1875          50 :                     m_aStates.top().aTableRowSprms.set(NS_sprm::LN_PRow, pRowValue);
    1876             : 
    1877         100 :                 RTFValue::Pointer_t pCellMar = m_aStates.top().aTableRowSprms.find(NS_ooxml::LN_CT_TblPrBase_tblCellMar);
    1878          50 :                 if (!pCellMar.get())
    1879             :                 {
    1880             :                     // If no cell margins are defined, the default left/right margin is 0 in Word, but not in Writer.
    1881          50 :                     RTFSprms aAttributes;
    1882          50 :                     aAttributes.set(NS_ooxml::LN_CT_TblWidth_type, RTFValue::Pointer_t(new RTFValue(NS_ooxml::LN_Value_ST_TblWidth_dxa)));
    1883          50 :                     aAttributes.set(NS_ooxml::LN_CT_TblWidth_w, RTFValue::Pointer_t(new RTFValue(0)));
    1884          50 :                     lcl_putNestedSprm(m_aStates.top().aTableRowSprms,
    1885             :                             NS_ooxml::LN_CT_TblPrBase_tblCellMar, NS_ooxml::LN_CT_TblCellMar_left,
    1886         100 :                             RTFValue::Pointer_t(new RTFValue(aAttributes)));
    1887          50 :                     lcl_putNestedSprm(m_aStates.top().aTableRowSprms,
    1888             :                             NS_ooxml::LN_CT_TblPrBase_tblCellMar, NS_ooxml::LN_CT_TblCellMar_right,
    1889         100 :                             RTFValue::Pointer_t(new RTFValue(aAttributes)));
    1890             :                 }
    1891             : 
    1892             :                 writerfilter::Reference<Properties>::Pointer_t const pTableRowProperties(
    1893         150 :                         new RTFReferenceProperties(m_aStates.top().aTableRowAttributes, m_aStates.top().aTableRowSprms)
    1894         200 :                         );
    1895          50 :                 Mapper().props(pTableRowProperties);
    1896             : 
    1897          50 :                 tableBreak();
    1898          50 :                 m_bNeedPap = true;
    1899          50 :                 m_bNeedFinalPar = true;
    1900          50 :                 m_aTableBuffer.clear();
    1901          50 :                 m_aStates.top().nCells = 0;
    1902          50 :                 m_aStates.top().aTableCellsSprms.clear();
    1903         100 :                 m_aStates.top().aTableCellsAttributes.clear();
    1904             :             }
    1905          50 :             break;
    1906             :         case RTF_COLUMN:
    1907             :             {
    1908           1 :                 bool bColumns = false; // If we have multiple columns
    1909           1 :                 RTFValue::Pointer_t pCols = m_aStates.top().aSectionSprms.find(NS_ooxml::LN_EG_SectPrContents_cols);
    1910           1 :                 if (pCols.get())
    1911             :                 {
    1912           0 :                     RTFValue::Pointer_t pNum = pCols->getAttributes().find(NS_ooxml::LN_CT_Columns_num);
    1913           0 :                     if (pNum.get() && pNum->getInt() > 1)
    1914           0 :                         bColumns = true;
    1915             :                 }
    1916           1 :                 if (bColumns)
    1917             :                 {
    1918           0 :                     sal_uInt8 sBreak[] = { 0xe };
    1919           0 :                     Mapper().startCharacterGroup();
    1920           0 :                     Mapper().text(sBreak, 1);
    1921           0 :                     Mapper().endCharacterGroup();
    1922             :                 }
    1923             :                 else
    1924           1 :                     dispatchSymbol(RTF_PAGE);
    1925             :             }
    1926           1 :             break;
    1927             :         case RTF_CHFTN:
    1928             :             // Nothing to do, dmapper assumes this is the default.
    1929           8 :             break;
    1930             :         case RTF_PAGE:
    1931             :             {
    1932             :                 // If we're inside a continous section, we should send a section break, not a page one.
    1933          58 :                 RTFValue::Pointer_t pBreak = m_aStates.top().aSectionSprms.find(NS_sprm::LN_SBkc);
    1934             :                 // Unless we're on a title page.
    1935         116 :                 RTFValue::Pointer_t pTitlePg = m_aStates.top().aSectionSprms.find(NS_ooxml::LN_EG_SectPrContents_titlePg);
    1936          58 :                 if ((pBreak.get() && !pBreak->getInt()) && !(pTitlePg.get() && pTitlePg->getInt()))
    1937             :                 {
    1938           2 :                     if (m_bWasInFrame)
    1939             :                     {
    1940           2 :                         dispatchSymbol(RTF_PAR);
    1941           2 :                         m_bWasInFrame = false;
    1942             :                     }
    1943           2 :                     dispatchFlag(RTF_SBKPAGE);
    1944           2 :                     sectBreak();
    1945           2 :                     dispatchFlag(RTF_SBKNONE);
    1946           2 :                     if (m_bNeedPar)
    1947           2 :                         dispatchSymbol(RTF_PAR);
    1948           2 :                     m_bIgnoreNextContSectBreak = true;
    1949             :                 }
    1950             :                 else
    1951             :                 {
    1952          56 :                     checkNeedPap();
    1953          56 :                     sal_uInt8 sBreak[] = { 0xc };
    1954          56 :                     Mapper().text(sBreak, 1);
    1955          56 :                     if (!m_bNeedPap)
    1956          56 :                         parBreak();
    1957          56 :                     m_bNeedCr = true;
    1958          58 :                 }
    1959             :             }
    1960          58 :             break;
    1961             :         case RTF_CHPGN:
    1962             :             {
    1963           2 :                 OUString aStr("PAGE");
    1964           2 :                 singleChar(0x13);
    1965           2 :                 text(aStr);
    1966           2 :                 singleChar(0x14, true);
    1967           2 :                 singleChar(0x15);
    1968             :             }
    1969           2 :             break;
    1970             :         default:
    1971             :             {
    1972             :                 SAL_INFO("writerfilter", "TODO handle symbol '" << lcl_RtfToString(nKeyword) << "'");
    1973           2 :                 aSkip.setParsed(false);
    1974             :             }
    1975           2 :             break;
    1976             :     }
    1977       24229 :     return 0;
    1978             : }
    1979             : 
    1980       11533 : int RTFDocumentImpl::dispatchFlag(RTFKeyword nKeyword)
    1981             : {
    1982       11533 :     checkUnicode(/*bUnicode =*/ true, /*bHex =*/ true);
    1983       11533 :     setNeedSect();
    1984       11533 :     RTFSkipDestination aSkip(*this);
    1985       11533 :     int nParam = -1;
    1986       11533 :     int nSprm = -1;
    1987             : 
    1988             :     // Map all underline flags to a single sprm.
    1989       11533 :     switch (nKeyword)
    1990             :     {
    1991           1 :         case RTF_ULD: nSprm = 4; break;
    1992           0 :         case RTF_ULW: nSprm = 2; break;
    1993       11532 :         default: break;
    1994             :     }
    1995       11533 :     if (nSprm >= 0)
    1996             :     {
    1997           1 :         RTFValue::Pointer_t pValue(new RTFValue(nSprm));
    1998           1 :         m_aStates.top().aCharacterSprms.set(NS_sprm::LN_CKul, pValue);
    1999           1 :         return 0;
    2000             :     }
    2001             : 
    2002             :     // Indentation
    2003       11532 :     switch (nKeyword)
    2004             :     {
    2005          17 :         case RTF_QC: nParam = 1; break;
    2006           4 :         case RTF_QJ: nParam = 3; break;
    2007         169 :         case RTF_QL: nParam = 0; break;
    2008          14 :         case RTF_QR: nParam = 2; break;
    2009           0 :         case RTF_QD: nParam = 4; break;
    2010       11328 :         default: break;
    2011             :     }
    2012       11532 :     if (nParam >= 0)
    2013             :     {
    2014         204 :         RTFValue::Pointer_t pValue(new RTFValue(nParam));
    2015         204 :         m_aStates.top().aParagraphSprms.set(NS_sprm::LN_PJc, pValue);
    2016         204 :         return 0;
    2017             :     }
    2018             : 
    2019             :     // Font Alignment
    2020       11328 :     switch (nKeyword)
    2021             :     {
    2022             :         case RTF_FAFIXED:
    2023         143 :         case RTF_FAAUTO: nParam = NS_ooxml::LN_Value_wordprocessingml_ST_TextAlignment_auto; break;
    2024           0 :         case RTF_FAHANG: nParam = NS_ooxml::LN_Value_wordprocessingml_ST_TextAlignment_top; break;
    2025           0 :         case RTF_FACENTER: nParam = NS_ooxml::LN_Value_wordprocessingml_ST_TextAlignment_center; break;
    2026           0 :         case RTF_FAROMAN: nParam = NS_ooxml::LN_Value_wordprocessingml_ST_TextAlignment_baseline; break;
    2027           0 :         case RTF_FAVAR: nParam = NS_ooxml::LN_Value_wordprocessingml_ST_TextAlignment_bottom; break;
    2028       11185 :         default: break;
    2029             :     }
    2030       11328 :     if (nParam >= 0)
    2031             :     {
    2032         143 :         RTFValue::Pointer_t pValue(new RTFValue(nParam));
    2033         143 :         m_aStates.top().aParagraphSprms.set(NS_sprm::LN_PWAlignFont, pValue);
    2034         143 :         return 0;
    2035             :     }
    2036             : 
    2037             :     // Tab kind.
    2038       11185 :     switch (nKeyword)
    2039             :     {
    2040           5 :         case RTF_TQR: nParam = 2; break;
    2041           1 :         case RTF_TQC: nParam = 1; break;
    2042           0 :         case RTF_TQDEC: nParam = 3; break;
    2043       11179 :         default: break;
    2044             :     }
    2045       11185 :     if (nParam >= 0)
    2046             :     {
    2047           6 :         RTFValue::Pointer_t pValue(new RTFValue(nParam));
    2048           6 :         m_aStates.top().aTabAttributes.set(NS_ooxml::LN_CT_TabStop_val, pValue);
    2049           6 :         return 0;
    2050             :     }
    2051             : 
    2052             :     // Tab lead.
    2053       11179 :     switch (nKeyword)
    2054             :     {
    2055           0 :         case RTF_TLDOT: nParam = 1; break;
    2056           0 :         case RTF_TLMDOT: nParam = NS_ooxml::LN_Value_ST_TabTlc_middleDot; break;
    2057           0 :         case RTF_TLHYPH: nParam = 2; break;
    2058           0 :         case RTF_TLUL: nParam = 3; break;
    2059           0 :         case RTF_TLTH: nParam = 2; break; // thick line is not supported by dmapper, this is just a hack
    2060           0 :         case RTF_TLEQ: nParam = 0; break; // equal sign isn't, either
    2061       11179 :         default: break;
    2062             :     }
    2063       11179 :     if (nParam >= 0)
    2064             :     {
    2065           0 :         RTFValue::Pointer_t pValue(new RTFValue(nParam));
    2066           0 :         m_aStates.top().aTabAttributes.set(NS_ooxml::LN_CT_TabStop_leader, pValue);
    2067           0 :         return 0;
    2068             :     }
    2069             : 
    2070             :     // Border types
    2071             :     {
    2072       11179 :         switch (nKeyword)
    2073             :         {
    2074             :             // brdrhair and brdrs are the same, brdrw will make a difference
    2075             :             // map to values in ooxml/model.xml resource ST_Border
    2076          11 :             case RTF_BRDRHAIR: nParam = 5; break;
    2077         105 :             case RTF_BRDRS: nParam = 1; break;
    2078           0 :             case RTF_BRDRDOT: nParam = 6; break;
    2079           0 :             case RTF_BRDRDASH: nParam = 7; break;
    2080          17 :             case RTF_BRDRDB: nParam = 3; break;
    2081           0 :             case RTF_BRDRTNTHSG: nParam = 11; break;
    2082           0 :             case RTF_BRDRTNTHMG: nParam = 14; break;
    2083           0 :             case RTF_BRDRTNTHLG: nParam = 17; break;
    2084          10 :             case RTF_BRDRTHTNSG: nParam = 12; break;
    2085          20 :             case RTF_BRDRTHTNMG: nParam = 15; break;
    2086          18 :             case RTF_BRDRTHTNLG: nParam = 18; break;
    2087          12 :             case RTF_BRDREMBOSS: nParam = 24; break;
    2088          12 :             case RTF_BRDRENGRAVE: nParam = 25; break;
    2089          22 :             case RTF_BRDROUTSET: nParam = 18; break;
    2090          20 :             case RTF_BRDRINSET: nParam = 17; break;
    2091         112 :             case RTF_BRDRNONE: nParam = 0; break;
    2092       10820 :             default: break;
    2093             :         }
    2094       11179 :         if (nParam >= 0)
    2095             :         {
    2096         359 :             RTFValue::Pointer_t pValue(new RTFValue(nParam));
    2097         359 :             lcl_putBorderProperty(m_aStates, NS_rtf::LN_BRCTYPE, pValue);
    2098         359 :             return 0;
    2099             :         }
    2100             :     }
    2101             : 
    2102             :     // Section breaks
    2103       10820 :     switch (nKeyword)
    2104             :     {
    2105          58 :         case RTF_SBKNONE: nParam = 0; break;
    2106           0 :         case RTF_SBKCOL: nParam = 1; break;
    2107           5 :         case RTF_SBKPAGE: nParam = 2; break;
    2108           0 :         case RTF_SBKEVEN: nParam = 3; break;
    2109           0 :         case RTF_SBKODD: nParam = 4; break;
    2110       10757 :         default: break;
    2111             :     }
    2112       10820 :     if (nParam >= 0)
    2113             :     {
    2114          63 :         RTFValue::Pointer_t pValue(new RTFValue(nParam));
    2115          63 :         m_aStates.top().aSectionSprms.set(NS_sprm::LN_SBkc, pValue);
    2116          63 :         return 0;
    2117             :     }
    2118             : 
    2119             :     // Footnote numbering
    2120       10757 :     switch (nKeyword)
    2121             :     {
    2122          50 :         case RTF_FTNNAR: nParam = NS_ooxml::LN_Value_ST_NumberFormat_decimal; break;
    2123           0 :         case RTF_FTNNALC: nParam = NS_ooxml::LN_Value_ST_NumberFormat_lowerLetter; break;
    2124           0 :         case RTF_FTNNAUC: nParam = NS_ooxml::LN_Value_ST_NumberFormat_upperLetter; break;
    2125           0 :         case RTF_FTNNRLC: nParam = NS_ooxml::LN_Value_ST_NumberFormat_lowerRoman; break;
    2126           0 :         case RTF_FTNNRUC: nParam = NS_ooxml::LN_Value_ST_NumberFormat_upperRoman; break;
    2127           0 :         case RTF_FTNNCHI: nParam = NS_ooxml::LN_Value_ST_NumberFormat_chicago; break;
    2128       10707 :         default: break;
    2129             :     }
    2130       10757 :     if (nParam >= 0)
    2131             :     {
    2132          50 :         RTFValue::Pointer_t pValue(new RTFValue(nParam));
    2133          50 :         lcl_putNestedSprm(m_aDefaultState.aParagraphSprms, NS_ooxml::LN_EG_SectPrContents_footnotePr, NS_ooxml::LN_CT_FtnProps_numFmt, pValue);
    2134          50 :         return 0;
    2135             :     }
    2136             : 
    2137             :     // Footnote restart type
    2138       10707 :     switch (nKeyword)
    2139             :     {
    2140           0 :         case RTF_FTNRSTPG: nParam = NS_ooxml::LN_Value_ST_RestartNumber_eachPage; break;
    2141           0 :         case RTF_FTNRESTART: nParam = NS_ooxml::LN_Value_ST_RestartNumber_eachSect; break;
    2142          47 :         case RTF_FTNRSTCONT: nParam = NS_ooxml::LN_Value_ST_RestartNumber_continuous; break;
    2143       10660 :         default: break;
    2144             :     }
    2145       10707 :     if (nParam >= 0)
    2146             :     {
    2147          47 :         RTFValue::Pointer_t pValue(new RTFValue(nParam));
    2148          47 :         lcl_putNestedSprm(m_aDefaultState.aParagraphSprms, NS_ooxml::LN_EG_SectPrContents_footnotePr, NS_ooxml::LN_EG_FtnEdnNumProps_numRestart, pValue);
    2149          47 :         return 0;
    2150             :     }
    2151             : 
    2152             :     // Endnote numbering
    2153       10660 :     switch (nKeyword)
    2154             :     {
    2155           3 :         case RTF_AFTNNAR: nParam = NS_ooxml::LN_Value_ST_NumberFormat_decimal; break;
    2156           0 :         case RTF_AFTNNALC: nParam = NS_ooxml::LN_Value_ST_NumberFormat_lowerLetter; break;
    2157           0 :         case RTF_AFTNNAUC: nParam = NS_ooxml::LN_Value_ST_NumberFormat_upperLetter; break;
    2158          48 :         case RTF_AFTNNRLC: nParam = NS_ooxml::LN_Value_ST_NumberFormat_lowerRoman; break;
    2159           0 :         case RTF_AFTNNRUC: nParam = NS_ooxml::LN_Value_ST_NumberFormat_upperRoman; break;
    2160           0 :         case RTF_AFTNNCHI: nParam = NS_ooxml::LN_Value_ST_NumberFormat_chicago; break;
    2161       10609 :         default: break;
    2162             :     }
    2163       10660 :     if (nParam >= 0)
    2164             :     {
    2165          51 :         RTFValue::Pointer_t pValue(new RTFValue(nParam));
    2166          51 :         lcl_putNestedSprm(m_aDefaultState.aParagraphSprms, NS_ooxml::LN_EG_SectPrContents_endnotePr, NS_ooxml::LN_CT_EdnProps_numFmt, pValue);
    2167          51 :         return 0;
    2168             :     }
    2169             : 
    2170             :     // Cell Text Flow
    2171       10609 :     switch (nKeyword)
    2172             :     {
    2173         148 :         case RTF_CLTXLRTB:  nParam = 0; break;
    2174           0 :         case RTF_CLTXTBRL:  nParam = 1; break;
    2175           0 :         case RTF_CLTXBTLR:  nParam = 3; break;
    2176           0 :         case RTF_CLTXLRTBV: nParam = 4; break;
    2177           0 :         case RTF_CLTXTBRLV: nParam = 5; break;
    2178       10461 :         default: break;
    2179             :     }
    2180       10609 :     if (nParam >= 0)
    2181             :     {
    2182         148 :         RTFValue::Pointer_t pValue(new RTFValue(nParam));
    2183         148 :         m_aStates.top().aTableCellSprms.set(NS_ooxml::LN_CT_TcPrBase_textDirection, pValue);
    2184             :     }
    2185             : 
    2186             :     // Trivial paragraph flags
    2187       10609 :     switch (nKeyword)
    2188             :     {
    2189             :         case RTF_KEEP:
    2190           0 :             if (m_aStates.top().pCurrentBuffer != &m_aTableBuffer)
    2191           0 :                 nParam = NS_sprm::LN_PFKeep;
    2192           0 :             break;
    2193             :         case RTF_KEEPN:
    2194          54 :             if (m_aStates.top().pCurrentBuffer != &m_aTableBuffer)
    2195          45 :                 nParam = NS_sprm::LN_PFKeepFollow;
    2196          54 :             break;
    2197             :         case RTF_INTBL:
    2198             :             {
    2199         367 :                 m_aStates.top().pCurrentBuffer = &m_aTableBuffer;
    2200         367 :                 nParam = NS_sprm::LN_PFInTable;
    2201             :             }
    2202         367 :             break;
    2203             :         case RTF_PAGEBB:
    2204           2 :             nParam = NS_sprm::LN_PFPageBreakBefore;
    2205           2 :             break;
    2206             :         default:
    2207       10186 :             break;
    2208             :     }
    2209       10609 :     if (nParam >= 0)
    2210             :     {
    2211         562 :         RTFValue::Pointer_t pValue(new RTFValue(1));
    2212         562 :         m_aStates.top().aParagraphSprms.erase(NS_sprm::LN_PFInTable);
    2213         562 :         m_aStates.top().aParagraphSprms.set(nParam, pValue);
    2214         562 :         return 0;
    2215             :     }
    2216             : 
    2217       10047 :     switch (nKeyword)
    2218             :     {
    2219             :         case RTF_FNIL:
    2220             :         case RTF_FROMAN:
    2221             :         case RTF_FSWISS:
    2222             :         case RTF_FMODERN:
    2223             :         case RTF_FSCRIPT:
    2224             :         case RTF_FDECOR:
    2225             :         case RTF_FTECH:
    2226             :         case RTF_FBIDI:
    2227             :             // TODO ooxml:CT_Font_family seems to be ignored by the domain mapper
    2228         917 :             break;
    2229             :         case RTF_ANSI:
    2230          81 :             m_aStates.top().nCurrentEncoding = RTL_TEXTENCODING_MS_1252;
    2231          81 :             break;
    2232             :         case RTF_PLAIN:
    2233             :             {
    2234         219 :                 m_aStates.top().aCharacterSprms = getDefaultState().aCharacterSprms;
    2235         219 :                 RTFValue::Pointer_t pValue = m_aStates.top().aCharacterSprms.find(NS_sprm::LN_CRgFtc0);
    2236         219 :                 if (pValue.get())
    2237         164 :                     m_aStates.top().nCurrentEncoding = getEncoding(pValue->getInt());
    2238         219 :                 m_aStates.top().aCharacterAttributes = getDefaultState().aCharacterAttributes;
    2239             :             }
    2240         219 :             break;
    2241             :         case RTF_PARD:
    2242         371 :             if (m_bHadPicture)
    2243           1 :                 dispatchSymbol(RTF_PAR);
    2244             :             // \pard is allowed between \cell and \row, but in that case it should not reset the fact that we're inside a table.
    2245         371 :             if (m_aStates.top().nCells == 0)
    2246             :             {
    2247             :                 // Reset everything.
    2248         268 :                 m_aStates.top().aParagraphSprms = m_aDefaultState.aParagraphSprms;
    2249         268 :                 m_aStates.top().aParagraphAttributes = m_aDefaultState.aParagraphAttributes;
    2250         268 :                 m_aStates.top().pCurrentBuffer = 0;
    2251             :             }
    2252             :             else
    2253             :             {
    2254             :                 // Reset only margins.
    2255         103 :                 lcl_eraseNestedAttribute(m_aStates.top().aParagraphSprms, NS_ooxml::LN_CT_PPrBase_spacing, NS_ooxml::LN_CT_Spacing_before);
    2256         103 :                 lcl_eraseNestedAttribute(m_aStates.top().aParagraphSprms, NS_ooxml::LN_CT_PPrBase_spacing, NS_ooxml::LN_CT_Spacing_after);
    2257         103 :                 m_aStates.top().aParagraphSprms.erase(NS_sprm::LN_PDxaLeft);
    2258         103 :                 m_aStates.top().aParagraphSprms.erase(NS_sprm::LN_PDxaRight);
    2259             :             }
    2260         371 :             m_aStates.top().resetFrame();
    2261         371 :             break;
    2262             :         case RTF_SECTD:
    2263             :             {
    2264          65 :                 m_aStates.top().aSectionSprms = m_aDefaultState.aSectionSprms;
    2265          65 :                 m_aStates.top().aSectionAttributes = m_aDefaultState.aSectionAttributes;
    2266             :             }
    2267          65 :             break;
    2268             :         case RTF_TROWD:
    2269             :             {
    2270          75 :                 m_aStates.top().aTableRowSprms = m_aDefaultState.aTableRowSprms;
    2271          75 :                 m_aStates.top().aTableRowSprms.set(NS_ooxml::LN_CT_TblGridBase_gridCol, RTFValue::Pointer_t(new RTFValue(-1)), false);
    2272          75 :                 m_aStates.top().aTableRowAttributes = m_aDefaultState.aTableRowAttributes;
    2273          75 :                 m_aStates.top().nCellX = 0;
    2274             :                 // In case the table definition is in the middle of the row
    2275             :                 // (invalid), make sure table definition is emitted.
    2276          75 :                 m_bNeedPap = true;
    2277             :             }
    2278          75 :             break;
    2279             :         case RTF_WIDCTLPAR:
    2280             :         case RTF_NOWIDCTLPAR:
    2281             :             {
    2282         344 :                 RTFValue::Pointer_t pValue(new RTFValue(nKeyword == RTF_WIDCTLPAR));
    2283         344 :                 m_aStates.top().aParagraphSprms.set(NS_sprm::LN_PFWidowControl, pValue);
    2284             :             }
    2285         344 :             break;
    2286             :         case RTF_BOX:
    2287             :             {
    2288           1 :                 RTFSprms aAttributes;
    2289           2 :                 RTFValue::Pointer_t pValue(new RTFValue(aAttributes));
    2290           5 :                 for (int i = 0; i < 4; i++)
    2291           4 :                     m_aStates.top().aParagraphSprms.set(lcl_getParagraphBorder(i), pValue);
    2292           2 :                 m_aStates.top().nBorderState = BORDER_PARAGRAPH_BOX;
    2293             :             }
    2294           1 :             break;
    2295             :         case RTF_LTRSECT:
    2296             :         case RTF_RTLSECT:
    2297             :             {
    2298           9 :                 RTFValue::Pointer_t pValue(new RTFValue(nKeyword == RTF_LTRSECT ? 0 : 1));
    2299           9 :                 m_aStates.top().aParagraphSprms.set(NS_sprm::LN_STextFlow, pValue);
    2300             :             }
    2301           9 :             break;
    2302             :         case RTF_LTRPAR:
    2303             :         case RTF_RTLPAR:
    2304             :             {
    2305         165 :                 RTFValue::Pointer_t pValue(new RTFValue(nKeyword == RTF_LTRPAR ? 0 : 1));
    2306         165 :                 m_aStates.top().aParagraphSprms.set(NS_sprm::LN_PFrameTextFlow, pValue);
    2307             :             }
    2308         165 :             break;
    2309             :         case RTF_LTRROW:
    2310             :         case RTF_RTLROW:
    2311             :             {
    2312          64 :                 RTFValue::Pointer_t pValue(new RTFValue(nKeyword == RTF_LTRROW ? 0 : 1));
    2313          64 :                 m_aStates.top().aParagraphSprms.set(NS_sprm::LN_TTextFlow, pValue);
    2314             :             }
    2315          64 :             break;
    2316             :         case RTF_LTRCH:
    2317             :             // dmapper does not support this.
    2318         896 :             break;
    2319             :         case RTF_RTLCH:
    2320         890 :             if (m_aDefaultState.nCurrentEncoding == RTL_TEXTENCODING_MS_1255)
    2321           1 :                 m_aStates.top().nCurrentEncoding = m_aDefaultState.nCurrentEncoding;
    2322         890 :             break;
    2323             :         case RTF_ULNONE:
    2324             :             {
    2325           0 :                 RTFValue::Pointer_t pValue(new RTFValue(0));
    2326           0 :                 m_aStates.top().aCharacterSprms.set(NS_sprm::LN_CKul, pValue);
    2327             :             }
    2328           0 :             break;
    2329             :         case RTF_NONSHPPICT:
    2330             :         case RTF_MMATHPICT: // Picture group used by readers not understanding \moMath group
    2331           0 :             m_aStates.top().nDestinationState = DESTINATION_SKIP;
    2332           0 :             break;
    2333             :         case RTF_CLBRDRT:
    2334             :         case RTF_CLBRDRL:
    2335             :         case RTF_CLBRDRB:
    2336             :         case RTF_CLBRDRR:
    2337             :             {
    2338         599 :                 RTFSprms aAttributes;
    2339        1198 :                 RTFSprms aSprms;
    2340        1198 :                 RTFValue::Pointer_t pValue(new RTFValue(aAttributes, aSprms));
    2341         599 :                 switch (nKeyword)
    2342             :                 {
    2343         150 :                     case RTF_CLBRDRT: nParam = NS_ooxml::LN_CT_TcBorders_top; break;
    2344         150 :                     case RTF_CLBRDRL: nParam = NS_ooxml::LN_CT_TcBorders_left; break;
    2345         150 :                     case RTF_CLBRDRB: nParam = NS_ooxml::LN_CT_TcBorders_bottom; break;
    2346         149 :                     case RTF_CLBRDRR: nParam = NS_ooxml::LN_CT_TcBorders_right; break;
    2347           0 :                     default: break;
    2348             :                 }
    2349         599 :                 lcl_putNestedSprm(m_aStates.top().aTableCellSprms, NS_ooxml::LN_CT_TcPrBase_tcBorders, nParam, pValue);
    2350        1198 :                 m_aStates.top().nBorderState = BORDER_CELL;
    2351             :             }
    2352         599 :             break;
    2353             :         case RTF_PGBRDRT:
    2354             :         case RTF_PGBRDRL:
    2355             :         case RTF_PGBRDRB:
    2356             :         case RTF_PGBRDRR:
    2357             :             {
    2358           0 :                 RTFSprms aAttributes;
    2359           0 :                 RTFSprms aSprms;
    2360           0 :                 RTFValue::Pointer_t pValue(new RTFValue(aAttributes, aSprms));
    2361           0 :                 switch (nKeyword)
    2362             :                 {
    2363           0 :                     case RTF_PGBRDRT: nParam = NS_ooxml::LN_CT_PageBorders_top; break;
    2364           0 :                     case RTF_PGBRDRL: nParam = NS_ooxml::LN_CT_PageBorders_left; break;
    2365           0 :                     case RTF_PGBRDRB: nParam = NS_ooxml::LN_CT_PageBorders_bottom; break;
    2366           0 :                     case RTF_PGBRDRR: nParam = NS_ooxml::LN_CT_PageBorders_right; break;
    2367           0 :                     default: break;
    2368             :                 }
    2369           0 :                 lcl_putNestedSprm(m_aStates.top().aSectionSprms, NS_ooxml::LN_EG_SectPrContents_pgBorders, nParam, pValue);
    2370           0 :                 m_aStates.top().nBorderState = BORDER_PAGE;
    2371             :             }
    2372           0 :             break;
    2373             :         case RTF_BRDRT:
    2374             :         case RTF_BRDRL:
    2375             :         case RTF_BRDRB:
    2376             :         case RTF_BRDRR:
    2377             :             {
    2378           1 :                 RTFSprms aAttributes;
    2379           2 :                 RTFSprms aSprms;
    2380           2 :                 RTFValue::Pointer_t pValue(new RTFValue(aAttributes, aSprms));
    2381           1 :                 switch (nKeyword)
    2382             :                 {
    2383           0 :                     case RTF_BRDRT: nParam = lcl_getParagraphBorder(0); break;
    2384           0 :                     case RTF_BRDRL: nParam = lcl_getParagraphBorder(1); break;
    2385           1 :                     case RTF_BRDRB: nParam = lcl_getParagraphBorder(2); break;
    2386           0 :                     case RTF_BRDRR: nParam = lcl_getParagraphBorder(3); break;
    2387           0 :                     default: break;
    2388             :                 }
    2389           1 :                 lcl_putNestedSprm(m_aStates.top().aParagraphSprms, NS_ooxml::LN_CT_PrBase_pBdr, nParam, pValue);
    2390           2 :                 m_aStates.top().nBorderState = BORDER_PARAGRAPH;
    2391             :             }
    2392           1 :             break;
    2393             :         case RTF_CLVMGF:
    2394             :             {
    2395           0 :                 RTFValue::Pointer_t pValue(new RTFValue(NS_ooxml::LN_Value_ST_Merge_restart));
    2396           0 :                 m_aStates.top().aTableCellSprms.set(NS_ooxml::LN_CT_TcPrBase_vMerge, pValue);
    2397             :             }
    2398           0 :             break;
    2399             :         case RTF_CLVMRG:
    2400             :             {
    2401           0 :                 RTFValue::Pointer_t pValue(new RTFValue(NS_ooxml::LN_Value_ST_Merge_continue));
    2402           0 :                 m_aStates.top().aTableCellSprms.set(NS_ooxml::LN_CT_TcPrBase_vMerge, pValue);
    2403             :             }
    2404           0 :             break;
    2405             :         case RTF_CLVERTALT:
    2406             :         case RTF_CLVERTALC:
    2407             :         case RTF_CLVERTALB:
    2408             :             {
    2409         183 :                 switch (nKeyword)
    2410             :                 {
    2411         183 :                     case RTF_CLVERTALT: nParam = 0; break;
    2412           0 :                     case RTF_CLVERTALC: nParam = 1; break;
    2413           0 :                     case RTF_CLVERTALB: nParam = 3; break;
    2414           0 :                     default: break;
    2415             :                 }
    2416         183 :                 RTFValue::Pointer_t pValue(new RTFValue(nParam));
    2417         183 :                 m_aStates.top().aTableCellSprms.set(NS_ooxml::LN_CT_TcPrBase_vAlign, pValue);
    2418             :             }
    2419         183 :             break;
    2420             :         case RTF_TRKEEP:
    2421             :             {
    2422           0 :                 RTFValue::Pointer_t pValue(new RTFValue(1));
    2423           0 :                 m_aStates.top().aTableRowSprms.set(NS_sprm::LN_TCantSplit, pValue);
    2424             :             }
    2425             :         case RTF_SECTUNLOCKED:
    2426             :             {
    2427          47 :                 RTFValue::Pointer_t pValue(new RTFValue(!nParam));
    2428          47 :                 m_aStates.top().aSectionSprms.set(NS_ooxml::LN_EG_SectPrContents_formProt, pValue);
    2429             :             }
    2430             :         case RTF_PGNDEC:
    2431             :         case RTF_PGNUCRM:
    2432             :         case RTF_PGNLCRM:
    2433             :         case RTF_PGNUCLTR:
    2434             :         case RTF_PGNLCLTR:
    2435             :         case RTF_PGNBIDIA:
    2436             :         case RTF_PGNBIDIB:
    2437             :             // These should be mapped to NS_ooxml::LN_EG_SectPrContents_pgNumType, but dmapper has no API for that at the moment.
    2438         140 :             break;
    2439             :         case RTF_LOCH:
    2440             :             // Noop, dmapper detects this automatically.
    2441        1229 :             break;
    2442             :         case RTF_HICH:
    2443         763 :             m_aStates.top().bIsCjk = true;
    2444         763 :             break;
    2445             :         case RTF_DBCH:
    2446        1364 :             m_aStates.top().bIsCjk = false;
    2447        1364 :             break;
    2448             :         case RTF_TITLEPG:
    2449             :             {
    2450           8 :                 RTFValue::Pointer_t pValue(new RTFValue(1));
    2451           8 :                 m_aStates.top().aSectionSprms.set(NS_ooxml::LN_EG_SectPrContents_titlePg, pValue);
    2452             :             }
    2453           8 :             break;
    2454             :         case RTF_SUPER:
    2455             :             {
    2456          16 :                 if (!m_aStates.top().pCurrentBuffer)
    2457          16 :                     m_aStates.top().pCurrentBuffer = &m_aSuperBuffer;
    2458             : 
    2459          16 :                 RTFValue::Pointer_t pValue(new RTFValue("superscript"));
    2460          16 :                 m_aStates.top().aCharacterSprms.set(NS_ooxml::LN_EG_RPrBase_vertAlign, pValue);
    2461             :             }
    2462          16 :             break;
    2463             :         case RTF_SUB:
    2464             :             {
    2465           1 :                 RTFValue::Pointer_t pValue(new RTFValue("subscript"));
    2466           1 :                 m_aStates.top().aCharacterSprms.set(NS_ooxml::LN_EG_RPrBase_vertAlign, pValue);
    2467             :             }
    2468           1 :             break;
    2469             :         case RTF_NOSUPERSUB:
    2470             :             {
    2471           1 :                 if (m_aStates.top().pCurrentBuffer == &m_aSuperBuffer)
    2472             :                 {
    2473           1 :                     replayBuffer(m_aSuperBuffer);
    2474           1 :                     m_aStates.top().pCurrentBuffer = 0;
    2475             :                 }
    2476           1 :                 m_aStates.top().aCharacterSprms.erase(NS_ooxml::LN_EG_RPrBase_vertAlign);
    2477             :             }
    2478           1 :             break;
    2479             :         case RTF_LINEPPAGE:
    2480             :         case RTF_LINECONT:
    2481             :             {
    2482           0 :                 RTFValue::Pointer_t pValue(new RTFValue(nKeyword == RTF_LINEPPAGE ? 0 : 2));
    2483           0 :                 lcl_putNestedAttribute(m_aStates.top().aSectionSprms,
    2484           0 :                         NS_ooxml::LN_EG_SectPrContents_lnNumType, NS_ooxml::LN_CT_LineNumber_restart, pValue);
    2485             :             }
    2486           0 :             break;
    2487             :         case RTF_AENDDOC:
    2488             :             // Noop, this is the default in Writer.
    2489          54 :             break;
    2490             :         case RTF_AENDNOTES:
    2491             :             // Noop, Writer does not support having endnotes at the end of section.
    2492           0 :             break;
    2493             :         case RTF_AFTNRSTCONT:
    2494             :             // Noop, this is the default in Writer.
    2495          47 :             break;
    2496             :         case RTF_AFTNRESTART:
    2497             :             // Noop, Writer does not support restarting endnotes at each section.
    2498           0 :             break;
    2499             :         case RTF_FTNBJ:
    2500             :             // Noop, this is the default in Writer.
    2501          60 :             break;
    2502             :         case RTF_ENDDOC:
    2503             :             {
    2504           0 :                 RTFValue::Pointer_t pValue(new RTFValue(NS_ooxml::LN_Value_ST_RestartNumber_eachSect));
    2505             :                 lcl_putNestedSprm(m_aDefaultState.aParagraphSprms,
    2506             :                         NS_ooxml::LN_EG_SectPrContents_footnotePr,
    2507           0 :                         NS_ooxml::LN_EG_FtnEdnNumProps_numRestart, pValue);
    2508             :             }
    2509           0 :             break;
    2510             :         case RTF_NOLINE:
    2511         100 :             lcl_eraseNestedAttribute(m_aStates.top().aSectionSprms, NS_ooxml::LN_EG_SectPrContents_lnNumType, NS_ooxml::LN_CT_LineNumber_distance);
    2512         100 :             break;
    2513             :         case RTF_FORMSHADE:
    2514             :             // Noop, this is the default in Writer.
    2515          48 :             break;
    2516             :         case RTF_PNGBLIP:
    2517          10 :             m_aStates.top().aPicture.nStyle = BMPSTYLE_PNG;
    2518          10 :             break;
    2519             :         case RTF_JPEGBLIP:
    2520           1 :             m_aStates.top().aPicture.nStyle = BMPSTYLE_JPEG;
    2521           1 :             break;
    2522           0 :         case RTF_POSYT: m_aStates.top().aFrame.setSprm(NS_ooxml::LN_CT_FramePr_yAlign, NS_ooxml::LN_Value_wordprocessingml_ST_YAlign_top); break;
    2523           0 :         case RTF_POSYB: m_aStates.top().aFrame.setSprm(NS_ooxml::LN_CT_FramePr_yAlign, NS_ooxml::LN_Value_wordprocessingml_ST_YAlign_bottom); break;
    2524           0 :         case RTF_POSYC: m_aStates.top().aFrame.setSprm(NS_ooxml::LN_CT_FramePr_yAlign, NS_ooxml::LN_Value_wordprocessingml_ST_YAlign_center); break;
    2525           0 :         case RTF_POSYIN: m_aStates.top().aFrame.setSprm(NS_ooxml::LN_CT_FramePr_yAlign, NS_ooxml::LN_Value_wordprocessingml_ST_YAlign_inside); break;
    2526           0 :         case RTF_POSYOUT: m_aStates.top().aFrame.setSprm(NS_ooxml::LN_CT_FramePr_yAlign, NS_ooxml::LN_Value_wordprocessingml_ST_YAlign_outside); break;
    2527           0 :         case RTF_POSYIL: m_aStates.top().aFrame.setSprm(NS_ooxml::LN_CT_FramePr_yAlign, NS_ooxml::LN_Value_wordprocessingml_ST_YAlign_inline); break;
    2528             : 
    2529           3 :         case RTF_PHMRG: m_aStates.top().aFrame.setSprm(NS_ooxml::LN_CT_FramePr_hAnchor, NS_ooxml::LN_Value_wordprocessingml_ST_HAnchor_margin); break;
    2530           2 :         case RTF_PVMRG: m_aStates.top().aFrame.setSprm(NS_ooxml::LN_CT_FramePr_vAnchor, NS_ooxml::LN_Value_wordprocessingml_ST_VAnchor_margin); break;
    2531          10 :         case RTF_PHPG: m_aStates.top().aFrame.setSprm(NS_ooxml::LN_CT_FramePr_hAnchor, NS_ooxml::LN_Value_wordprocessingml_ST_HAnchor_page); break;
    2532          12 :         case RTF_PVPG: m_aStates.top().aFrame.setSprm(NS_ooxml::LN_CT_FramePr_vAnchor, NS_ooxml::LN_Value_wordprocessingml_ST_VAnchor_page); break;
    2533           0 :         case RTF_PHCOL: m_aStates.top().aFrame.setSprm(NS_ooxml::LN_CT_FramePr_hAnchor, NS_ooxml::LN_Value_wordprocessingml_ST_HAnchor_text); break;
    2534           0 :         case RTF_PVPARA: m_aStates.top().aFrame.setSprm(NS_ooxml::LN_CT_FramePr_vAnchor, NS_ooxml::LN_Value_wordprocessingml_ST_VAnchor_text); break;
    2535             : 
    2536           0 :         case RTF_POSXC: m_aStates.top().aFrame.setSprm(NS_ooxml::LN_CT_FramePr_xAlign, NS_ooxml::LN_Value_wordprocessingml_ST_XAlign_center); break;
    2537           0 :         case RTF_POSXI: m_aStates.top().aFrame.setSprm(NS_ooxml::LN_CT_FramePr_xAlign, NS_ooxml::LN_Value_wordprocessingml_ST_XAlign_inside); break;
    2538           0 :         case RTF_POSXO: m_aStates.top().aFrame.setSprm(NS_ooxml::LN_CT_FramePr_xAlign, NS_ooxml::LN_Value_wordprocessingml_ST_XAlign_outside); break;
    2539           0 :         case RTF_POSXL: m_aStates.top().aFrame.setSprm(NS_ooxml::LN_CT_FramePr_xAlign, NS_ooxml::LN_Value_wordprocessingml_ST_XAlign_left); break;
    2540           0 :         case RTF_POSXR: m_aStates.top().aFrame.setSprm(NS_ooxml::LN_CT_FramePr_xAlign, NS_ooxml::LN_Value_wordprocessingml_ST_XAlign_right); break;
    2541             : 
    2542             :         case RTF_DPLINE:
    2543             :         case RTF_DPRECT:
    2544             :         case RTF_DPELLIPSE:
    2545             :         case RTF_DPTXBX:
    2546             :         case RTF_DPPOLYLINE:
    2547             :                 {
    2548          18 :                     sal_Int32 nType = 0;
    2549          18 :                     switch (nKeyword)
    2550             :                     {
    2551             :                         case RTF_DPLINE:
    2552           4 :                             m_aStates.top().aDrawingObject.xShape.set(getModelFactory()->createInstance("com.sun.star.drawing.LineShape"), uno::UNO_QUERY);
    2553           4 :                             break;
    2554             :                         case RTF_DPPOLYLINE:
    2555             :                             // The reason this is not a simple CustomShape is that in the old syntax we have no ViewBox info.
    2556           4 :                             m_aStates.top().aDrawingObject.xShape.set(getModelFactory()->createInstance("com.sun.star.drawing.PolyLineShape"), uno::UNO_QUERY);
    2557           4 :                             break;
    2558             :                         case RTF_DPRECT:
    2559           3 :                             m_aStates.top().aDrawingObject.xShape.set(getModelFactory()->createInstance("com.sun.star.drawing.RectangleShape"), uno::UNO_QUERY);
    2560           3 :                             break;
    2561             :                         case RTF_DPELLIPSE:
    2562           0 :                             nType = ESCHER_ShpInst_Ellipse;
    2563           0 :                             break;
    2564             :                         case RTF_DPTXBX:
    2565             :                             {
    2566           7 :                                 m_aStates.top().aDrawingObject.xShape.set(getModelFactory()->createInstance("com.sun.star.text.TextFrame"), uno::UNO_QUERY);
    2567           7 :                                 std::vector<beans::PropertyValue> aDefaults = m_pSdrImport->getTextFrameDefaults(false);
    2568          77 :                                 for (size_t i = 0; i < aDefaults.size(); ++i)
    2569          70 :                                     m_aStates.top().aDrawingObject.aPendingProperties.push_back(aDefaults[i]);
    2570           7 :                                 checkFirstRun();
    2571           7 :                                 Mapper().startShape(m_aStates.top().aDrawingObject.xShape);
    2572           7 :                                 m_aStates.top().aDrawingObject.bHadShapeText = true;
    2573             :                             }
    2574           7 :                             break;
    2575             :                         default:
    2576           0 :                             break;
    2577             :                     }
    2578          18 :                     if (nType)
    2579           0 :                             m_aStates.top().aDrawingObject.xShape.set(getModelFactory()->createInstance("com.sun.star.drawing.CustomShape"), uno::UNO_QUERY);
    2580          18 :                     uno::Reference<drawing::XDrawPageSupplier> xDrawSupplier( m_xDstDoc, uno::UNO_QUERY);
    2581          18 :                     if (xDrawSupplier.is())
    2582             :                     {
    2583          18 :                         uno::Reference<drawing::XShapes> xShapes(xDrawSupplier->getDrawPage(), uno::UNO_QUERY);
    2584          18 :                         if (xShapes.is() && nKeyword != RTF_DPTXBX)
    2585          11 :                             xShapes->add(m_aStates.top().aDrawingObject.xShape);
    2586             :                     }
    2587          18 :                     if (nType)
    2588             :                     {
    2589           0 :                             uno::Reference<drawing::XEnhancedCustomShapeDefaulter> xDefaulter(m_aStates.top().aDrawingObject.xShape, uno::UNO_QUERY);
    2590           0 :                             xDefaulter->createCustomShapeDefaults(OUString::valueOf(nType));
    2591             :                     }
    2592          18 :                     m_aStates.top().aDrawingObject.xPropertySet.set(m_aStates.top().aDrawingObject.xShape, uno::UNO_QUERY);
    2593          18 :                     std::vector<beans::PropertyValue>& rPendingProperties = m_aStates.top().aDrawingObject.aPendingProperties;
    2594         121 :                     for (std::vector<beans::PropertyValue>::iterator i = rPendingProperties.begin(); i != rPendingProperties.end(); ++i)
    2595         103 :                         m_aStates.top().aDrawingObject.xPropertySet->setPropertyValue(i->Name, i->Value);
    2596          18 :                     m_pSdrImport->resolveDhgt(m_aStates.top().aDrawingObject.xPropertySet, m_aStates.top().aDrawingObject.nDhgt);
    2597             :                 }
    2598          18 :                 break;
    2599             :         case RTF_DOBXMARGIN:
    2600             :         case RTF_DOBYMARGIN:
    2601             :                 {
    2602           1 :                     beans::PropertyValue aPropertyValue;
    2603           1 :                     aPropertyValue.Name = (nKeyword == RTF_DOBXMARGIN ? OUString("HoriOrientRelation") : OUString("VertOrientRelation"));
    2604           1 :                     aPropertyValue.Value <<= text::RelOrientation::PAGE_PRINT_AREA;
    2605           1 :                     m_aStates.top().aDrawingObject.aPendingProperties.push_back(aPropertyValue);
    2606             :                 }
    2607           1 :                 break;
    2608             :         case RTF_DOBXPAGE:
    2609             :         case RTF_DOBYPAGE:
    2610             :                 {
    2611          23 :                     beans::PropertyValue aPropertyValue;
    2612          23 :                     aPropertyValue.Name = (nKeyword == RTF_DOBXPAGE ? OUString("HoriOrientRelation") : OUString("VertOrientRelation"));
    2613          23 :                     aPropertyValue.Value <<= text::RelOrientation::PAGE_FRAME;
    2614          23 :                     m_aStates.top().aDrawingObject.aPendingProperties.push_back(aPropertyValue);
    2615             :                 }
    2616          23 :                 break;
    2617             :         case RTF_DOBYPARA:
    2618             :                 {
    2619           9 :                     beans::PropertyValue aPropertyValue;
    2620           9 :                     aPropertyValue.Name = OUString("VertOrientRelation");
    2621           9 :                     aPropertyValue.Value <<= text::RelOrientation::FRAME;
    2622           9 :                     m_aStates.top().aDrawingObject.aPendingProperties.push_back(aPropertyValue);
    2623             :                 }
    2624           9 :                 break;
    2625             :         case RTF_CONTEXTUALSPACE:
    2626             :                 {
    2627           2 :                     RTFValue::Pointer_t pValue(new RTFValue(1));
    2628           2 :                     m_aStates.top().aParagraphSprms.set(NS_sprm::LN_PContextualSpacing, pValue);
    2629             :                 }
    2630           2 :                 break;
    2631             :         case RTF_LINKSTYLES:
    2632             :                 {
    2633           1 :                     RTFValue::Pointer_t pValue(new RTFValue(1));
    2634           1 :                     m_aSettingsTableSprms.set(NS_ooxml::LN_CT_Settings_linkStyles, pValue);
    2635             :                 }
    2636           1 :                 break;
    2637             :         case RTF_PNLVLBODY:
    2638             :                 {
    2639           3 :                     RTFValue::Pointer_t pValue(new RTFValue(2));
    2640           3 :                     m_aStates.top().aTableAttributes.set(NS_rtf::LN_LSID, pValue);
    2641             :                 }
    2642           3 :                 break;
    2643             :         case RTF_PNDEC:
    2644             :                 {
    2645           3 :                     RTFValue::Pointer_t pValue(new RTFValue(0)); // decimal, same as \levelnfc0
    2646           3 :                     m_aStates.top().aTableSprms.set(NS_rtf::LN_NFC, pValue);
    2647             :                 }
    2648           3 :                 break;
    2649             :         case RTF_PNLVLBLT:
    2650             :                 {
    2651           1 :                     m_aStates.top().aTableAttributes.set(NS_rtf::LN_LSID, RTFValue::Pointer_t(new RTFValue(1)));
    2652           1 :                     m_aStates.top().aTableSprms.set(NS_rtf::LN_NFC, RTFValue::Pointer_t(new RTFValue(23))); // bullets, same as \levelnfc23
    2653             :                 }
    2654           1 :                 break;
    2655             :         case RTF_LANDSCAPE:
    2656           3 :                 lcl_putNestedAttribute(m_aStates.top().aSectionSprms, NS_ooxml::LN_EG_SectPrContents_pgSz, NS_ooxml::LN_CT_PageSz_orient, RTFValue::Pointer_t(new RTFValue(1)));
    2657           3 :                 break;
    2658             :         case RTF_FACINGP:
    2659           2 :                 m_aSettingsTableSprms.set(NS_ooxml::LN_CT_Settings_evenAndOddHeaders, RTFValue::Pointer_t(new RTFValue(1)));
    2660           2 :                 break;
    2661             :         case RTF_SHPBXPAGE:
    2662          15 :                 m_aStates.top().aShape.nHoriOrientRelation = text::RelOrientation::PAGE_FRAME;
    2663          15 :                 break;
    2664             :         case RTF_SHPBYPAGE:
    2665          14 :                 m_aStates.top().aShape.nVertOrientRelation = text::RelOrientation::PAGE_FRAME;
    2666          14 :                 break;
    2667             :         case RTF_DPLINEHOLLOW:
    2668           7 :                 m_aStates.top().aDrawingObject.nFLine = 0;
    2669           7 :                 break;
    2670             :         case RTF_DPROUNDR:
    2671           0 :                 if (m_aStates.top().aDrawingObject.xPropertySet.is())
    2672             :                     // Seems this old syntax has no way to specify a custom radius, and this is the default
    2673           0 :                     m_aStates.top().aDrawingObject.xPropertySet->setPropertyValue("CornerRadius", uno::makeAny(sal_Int32(83)));
    2674           0 :                 break;
    2675             :         case RTF_NOWRAP:
    2676           1 :                 m_aStates.top().aFrame.setSprm(NS_sprm::LN_PWr, NS_ooxml::LN_Value_wordprocessingml_ST_Wrap_notBeside);
    2677           1 :                 break;
    2678             :         case RTF_MNOR:
    2679           6 :                 m_bMathNor = true;
    2680           6 :                 break;
    2681             :         case RTF_REVISIONS:
    2682           2 :                 m_aSettingsTableSprms.set(NS_ooxml::LN_CT_Settings_trackRevisions, RTFValue::Pointer_t(new RTFValue(1)));
    2683           2 :                 break;
    2684             :         default:
    2685             :                 {
    2686             :                     SAL_INFO("writerfilter", "TODO handle flag '" << lcl_RtfToString(nKeyword) << "'");
    2687        1187 :                     aSkip.setParsed(false);
    2688             :                 }
    2689        1187 :                 break;
    2690             :     }
    2691       10047 :     return 0;
    2692             : }
    2693             : 
    2694       19980 : int RTFDocumentImpl::dispatchValue(RTFKeyword nKeyword, int nParam)
    2695             : {
    2696       19980 :     checkUnicode(/*bUnicode =*/ nKeyword != RTF_U, /*bHex =*/ true);
    2697       19980 :     setNeedSect();
    2698       19980 :     RTFSkipDestination aSkip(*this);
    2699       19980 :     int nSprm = 0;
    2700       39960 :     RTFValue::Pointer_t pIntValue(new RTFValue(nParam));
    2701             :     // Trivial table sprms.
    2702       19980 :     switch (nKeyword)
    2703             :     {
    2704         690 :         case RTF_FPRQ: nSprm = NS_rtf::LN_PRQ; break;
    2705          29 :         case RTF_LEVELJC: nSprm = NS_ooxml::LN_CT_Lvl_lvlJc; break;
    2706          33 :         case RTF_LEVELNFC: nSprm = NS_rtf::LN_NFC; break;
    2707          33 :         case RTF_LEVELSTARTAT: nSprm = NS_rtf::LN_ISTARTAT; break;
    2708           2 :         case RTF_LEVELPICTURE: nSprm = NS_ooxml::LN_CT_Lvl_lvlPicBulletId; break;
    2709       19193 :         default: break;
    2710             :     }
    2711       19980 :     if (nSprm > 0)
    2712             :     {
    2713         787 :         m_aStates.top().aTableSprms.set(nSprm, pIntValue);
    2714         787 :         return 0;
    2715             :     }
    2716             :     // Trivial character sprms.
    2717       19193 :     switch (nKeyword)
    2718             :     {
    2719         503 :         case RTF_FS: nSprm = NS_sprm::LN_CHps; break;
    2720         419 :         case RTF_AFS: nSprm = NS_sprm::LN_CHpsBi; break;
    2721           0 :         case RTF_ANIMTEXT: nSprm = NS_sprm::LN_CSfxText; break;
    2722           3 :         case RTF_EXPNDTW: nSprm = NS_sprm::LN_CDxaSpace; break;
    2723         194 :         case RTF_KERNING: nSprm = NS_sprm::LN_CHpsKern; break;
    2724           0 :         case RTF_CHARSCALEX: nSprm = NS_sprm::LN_CCharScale; break;
    2725         341 :         case RTF_LANG: nSprm = NS_sprm::LN_CRgLid0; break;
    2726         326 :         case RTF_LANGFE: nSprm = NS_sprm::LN_CRgLid1; break;
    2727         282 :         case RTF_ALANG: nSprm = NS_sprm::LN_CLidBi; break;
    2728       17125 :         default: break;
    2729             :     }
    2730       19193 :     if (nSprm > 0)
    2731             :     {
    2732        2068 :         m_aStates.top().aCharacterSprms.set(nSprm, pIntValue);
    2733             :         // Language is a character property, but we should store it at a paragraph level as well for fields.
    2734        2068 :         if (nKeyword == RTF_LANG && m_bNeedPap)
    2735         337 :             m_aStates.top().aParagraphSprms.set(nSprm, pIntValue);
    2736        2068 :         return 0;
    2737             :     }
    2738             :     // Trivial paragraph sprms.
    2739       17125 :     switch (nKeyword)
    2740             :     {
    2741         137 :         case RTF_FI: nSprm = NS_sprm::LN_PDxaLeft1; break;
    2742         165 :         case RTF_LIN: nSprm = 0x845e; break;
    2743         162 :         case RTF_RI: nSprm = NS_sprm::LN_PDxaRight; break;
    2744         157 :         case RTF_RIN: nSprm = 0x845d; break;
    2745          72 :         case RTF_ITAP: nSprm = NS_sprm::LN_PTableDepth; break;
    2746       16432 :         default: break;
    2747             :     }
    2748       17125 :     if (nSprm > 0)
    2749             :     {
    2750         693 :         m_aStates.top().aParagraphSprms.set(nSprm, pIntValue);
    2751         693 :         if (nKeyword == RTF_ITAP && nParam > 0)
    2752             :             // Invalid tables may omit INTBL after ITAP
    2753          10 :             dispatchFlag(RTF_INTBL);
    2754         693 :         return 0;
    2755             :     }
    2756             : 
    2757             :     // Trivial table attributes.
    2758       16432 :     switch (nKeyword)
    2759             :     {
    2760         302 :         case RTF_SBASEDON: nSprm = NS_rtf::LN_ISTDBASE; break;
    2761         350 :         case RTF_SNEXT: nSprm = NS_rtf::LN_ISTDNEXT; break;
    2762       15780 :         default: break;
    2763             :     }
    2764       16432 :     if (nSprm > 0)
    2765             :     {
    2766         652 :         m_aStates.top().aTableAttributes.set(nSprm, pIntValue);
    2767         652 :         return 0;
    2768             :     }
    2769             : 
    2770             :     // Info group.
    2771       15780 :     switch (nKeyword)
    2772             :     {
    2773             :         case RTF_YR:
    2774             :             {
    2775         139 :                 m_aStates.top().nYear = nParam;
    2776         139 :                 nSprm = 1;
    2777             :             }
    2778         139 :             break;
    2779             :         case RTF_MO:
    2780             :             {
    2781         139 :                 m_aStates.top().nMonth = nParam;
    2782         139 :                 nSprm = 1;
    2783             :             }
    2784         139 :             break;
    2785             :         case RTF_DY:
    2786             :             {
    2787         139 :                 m_aStates.top().nDay = nParam;
    2788         139 :                 nSprm = 1;
    2789             :             }
    2790         139 :             break;
    2791             :         case RTF_HR:
    2792             :             {
    2793         139 :                 m_aStates.top().nHour = nParam;
    2794         139 :                 nSprm = 1;
    2795             :             }
    2796         139 :             break;
    2797             :         case RTF_MIN:
    2798             :             {
    2799         139 :                 m_aStates.top().nMinute = nParam;
    2800         139 :                 nSprm = 1;
    2801             :             }
    2802         139 :             break;
    2803             :         default:
    2804       15085 :             break;
    2805             :     }
    2806       15780 :     if (nSprm > 0)
    2807         695 :         return 0;
    2808             : 
    2809             :     // Frame size / position.
    2810       15085 :     Id nId = 0;
    2811       15085 :     switch (nKeyword)
    2812             :     {
    2813             :         case RTF_ABSW:
    2814          15 :             nId = NS_sprm::LN_PDxaWidth;
    2815          15 :             break;
    2816             :         case RTF_ABSH:
    2817          15 :             nId = NS_sprm::LN_PWHeightAbs;
    2818          15 :             break;
    2819             :         case RTF_POSX:
    2820             :             {
    2821          15 :                 nId = NS_ooxml::LN_CT_FramePr_x;
    2822          15 :                 m_aStates.top().aFrame.setSprm(NS_ooxml::LN_CT_FramePr_xAlign, 0);
    2823             :             }
    2824          15 :             break;
    2825             :         case RTF_POSY:
    2826             :             {
    2827          15 :                 nId = NS_ooxml::LN_CT_FramePr_y;
    2828          15 :                 m_aStates.top().aFrame.setSprm(NS_ooxml::LN_CT_FramePr_yAlign, 0);
    2829             :             }
    2830          15 :             break;
    2831             :         default:
    2832       15025 :             break;
    2833             :     }
    2834             : 
    2835       15085 :     if (nId > 0)
    2836             :     {
    2837          60 :         m_bNeedPap = true;
    2838             :         // Don't try to support text frames inside tables for now.
    2839          60 :         if (m_aStates.top().pCurrentBuffer != &m_aTableBuffer)
    2840          60 :             m_aStates.top().aFrame.setSprm(nId, nParam);
    2841             : 
    2842          60 :         return 0;
    2843             :     }
    2844             : 
    2845             :     // Then check for the more complex ones.
    2846       15025 :     switch (nKeyword)
    2847             :     {
    2848             :         case RTF_F:
    2849             :         case RTF_AF:
    2850        5170 :             if (nKeyword == RTF_F)
    2851        1978 :                 nSprm = NS_sprm::LN_CRgFtc0;
    2852             :             else
    2853        3192 :                 nSprm = (m_aStates.top().bIsCjk ? NS_sprm::LN_CRgFtc1 : NS_sprm::LN_CRgFtc2);
    2854        5170 :             if (m_aStates.top().nDestinationState == DESTINATION_FONTTABLE || m_aStates.top().nDestinationState == DESTINATION_FONTENTRY)
    2855             :             {
    2856         710 :                 m_aFontIndexes.push_back(nParam);
    2857         710 :                 m_nCurrentFontIndex = getFontIndex(nParam);
    2858             :             }
    2859        4460 :             else if (m_aStates.top().nDestinationState == DESTINATION_LISTLEVEL)
    2860             :             {
    2861           7 :                 RTFSprms aFontSprms;
    2862           7 :                 aFontSprms.set(nSprm, RTFValue::Pointer_t(new RTFValue(getFontIndex(nParam))));
    2863             :                 // In the context of listlevels, \af seems to imply \f.
    2864           7 :                 if (nKeyword == RTF_AF)
    2865           4 :                     aFontSprms.set(NS_sprm::LN_CRgFtc0, RTFValue::Pointer_t(new RTFValue(getFontIndex(nParam))));
    2866          14 :                 RTFSprms aRunPropsSprms;
    2867           7 :                 aRunPropsSprms.set(NS_ooxml::LN_EG_RPrBase_rFonts, RTFValue::Pointer_t(new RTFValue(RTFSprms(), aFontSprms)));
    2868             :                 // If there are multiple \f or \af tokens, only handle the first one.
    2869           7 :                 if (!m_aStates.top().aTableSprms.find(NS_ooxml::LN_CT_Lvl_rPr))
    2870          12 :                     m_aStates.top().aTableSprms.set(NS_ooxml::LN_CT_Lvl_rPr, RTFValue::Pointer_t(new RTFValue(RTFSprms(), aRunPropsSprms)));
    2871             :             }
    2872             :             else
    2873             :             {
    2874        4453 :                 int nFontIndex = getFontIndex(nParam);
    2875        4453 :                 RTFValue::Pointer_t pValue(new RTFValue(nFontIndex));
    2876        4453 :                 m_aStates.top().aCharacterSprms.set(nSprm, pValue);
    2877        4453 :                 m_aStates.top().nCurrentEncoding = getEncoding(nFontIndex);
    2878             :             }
    2879        5170 :             break;
    2880             :         case RTF_RED:
    2881         227 :             m_aStates.top().aCurrentColor.nRed = nParam;
    2882         227 :             break;
    2883             :         case RTF_GREEN:
    2884         227 :             m_aStates.top().aCurrentColor.nGreen = nParam;
    2885         227 :             break;
    2886             :         case RTF_BLUE:
    2887         227 :             m_aStates.top().aCurrentColor.nBlue = nParam;
    2888         227 :             break;
    2889             :         case RTF_FCHARSET:
    2890             :             {
    2891             :                 // we always send text to the domain mapper in OUString, so no
    2892             :                 // need to send encoding info
    2893             :                 int i;
    2894        6662 :                 for (i = 0; i < nRTFEncodings; i++)
    2895             :                 {
    2896        6662 :                     if (aRTFEncodings[i].charset == nParam)
    2897         699 :                         break;
    2898             :                 }
    2899         699 :                 if (i == nRTFEncodings)
    2900             :                     // not found
    2901           0 :                     return 0;
    2902             : 
    2903         699 :                 m_aFontEncodings[m_nCurrentFontIndex] = rtl_getTextEncodingFromWindowsCodePage(aRTFEncodings[i].codepage);
    2904             :             }
    2905         699 :             break;
    2906             :         case RTF_ANSICPG:
    2907             :             {
    2908          17 :                 m_aDefaultState.nCurrentEncoding = rtl_getTextEncodingFromWindowsCodePage(nParam);
    2909          17 :                 m_aStates.top().nCurrentEncoding = rtl_getTextEncodingFromWindowsCodePage(nParam);
    2910             :             }
    2911          17 :             break;
    2912             :         case RTF_CPG:
    2913           4 :             m_aFontEncodings[m_nCurrentFontIndex] = rtl_getTextEncodingFromWindowsCodePage(nParam);
    2914           4 :             break;
    2915             :         case RTF_CF:
    2916             :             {
    2917             :                 // NS_sprm::LN_CIco won't work, that would be an index in a static table
    2918         228 :                 RTFValue::Pointer_t pValue(new RTFValue(getColorTable(nParam)));
    2919         228 :                 m_aStates.top().aCharacterAttributes.set(NS_ooxml::LN_CT_Color_val, pValue);
    2920             :             }
    2921         228 :             break;
    2922             :         case RTF_S:
    2923             :             {
    2924         531 :                 m_aStates.top().nCurrentStyleIndex = nParam;
    2925             : 
    2926         531 :                 if (m_aStates.top().nDestinationState == DESTINATION_STYLESHEET || m_aStates.top().nDestinationState == DESTINATION_STYLEENTRY)
    2927             :                 {
    2928         365 :                     m_nCurrentStyleIndex = nParam;
    2929         365 :                     m_aStates.top().aTableAttributes.set(NS_rtf::LN_ISTD, pIntValue);
    2930         365 :                     RTFValue::Pointer_t pValue(new RTFValue(1));
    2931         365 :                     m_aStates.top().aTableAttributes.set(NS_rtf::LN_SGC, pValue); // paragraph style
    2932             :                 }
    2933             :                 else
    2934         166 :                    m_aStates.top().aParagraphAttributes.set(NS_rtf::LN_ISTD, pIntValue);
    2935             :             }
    2936         531 :             break;
    2937             :         case RTF_CS:
    2938          40 :             if (m_aStates.top().nDestinationState == DESTINATION_STYLESHEET || m_aStates.top().nDestinationState == DESTINATION_STYLEENTRY)
    2939             :             {
    2940          37 :                 m_nCurrentStyleIndex = nParam;
    2941          37 :                 m_aStates.top().aTableAttributes.set(NS_rtf::LN_ISTD, pIntValue);
    2942          37 :                 RTFValue::Pointer_t pValue(new RTFValue(2));
    2943          37 :                 m_aStates.top().aTableAttributes.set(NS_rtf::LN_SGC, pValue); // character style
    2944             :             }
    2945             :             else
    2946           3 :                 m_aStates.top().aCharacterAttributes.set(NS_rtf::LN_ISTD, pIntValue);
    2947          40 :             break;
    2948             :         case RTF_DEFF:
    2949          75 :             m_aDefaultState.aCharacterSprms.set(NS_sprm::LN_CRgFtc0, pIntValue);
    2950          75 :             break;
    2951             :         case RTF_DEFLANG:
    2952          13 :             m_aDefaultState.aCharacterSprms.set(NS_sprm::LN_CRgLid0, pIntValue);
    2953          13 :             break;
    2954             :         case RTF_ADEFLANG:
    2955          55 :             m_aDefaultState.aCharacterSprms.set(NS_sprm::LN_CLidBi, pIntValue);
    2956          55 :             break;
    2957             :         case RTF_CHCBPAT:
    2958             :             {
    2959           4 :                 RTFValue::Pointer_t pValue(new RTFValue(nParam ? getColorTable(nParam) : COL_AUTO));
    2960           4 :                 lcl_putNestedAttribute(m_aStates.top().aCharacterSprms, NS_sprm::LN_CShd, NS_ooxml::LN_CT_Shd_fill, pValue);
    2961             :             }
    2962           4 :             break;
    2963             :         case RTF_CLCBPAT:
    2964             :             {
    2965           1 :                 RTFValue::Pointer_t pValue(new RTFValue(getColorTable(nParam)));
    2966           1 :                 lcl_putNestedAttribute(m_aStates.top().aTableCellSprms,
    2967           2 :                         NS_ooxml::LN_CT_TcPrBase_shd, NS_ooxml::LN_CT_Shd_fill, pValue);
    2968             :             }
    2969           1 :             break;
    2970             :         case RTF_CBPAT:
    2971           2 :             if (nParam)
    2972             :             {
    2973           1 :                 RTFValue::Pointer_t pValue(new RTFValue(getColorTable(nParam)));
    2974           1 :                 lcl_putNestedAttribute(m_aStates.top().aParagraphSprms, NS_sprm::LN_PShd, NS_ooxml::LN_CT_Shd_fill, pValue);
    2975             :             }
    2976           2 :             break;
    2977             :         case RTF_ULC:
    2978             :             {
    2979           3 :                 RTFValue::Pointer_t pValue(new RTFValue(getColorTable(nParam)));
    2980           3 :                 m_aStates.top().aCharacterSprms.set(0x6877, pValue);
    2981             :             }
    2982           3 :             break;
    2983             :         case RTF_HIGHLIGHT:
    2984             :             {
    2985           1 :                 RTFValue::Pointer_t pValue(new RTFValue(getColorTable(nParam)));
    2986           1 :                 m_aStates.top().aCharacterSprms.set(NS_sprm::LN_CHighlight, pValue);
    2987             :             }
    2988           1 :             break;
    2989             :         case RTF_UP:
    2990             :         case RTF_DN:
    2991             :             {
    2992           2 :                 RTFValue::Pointer_t pValue(new RTFValue(nParam * (nKeyword == RTF_UP ? 1 : -1)));
    2993           2 :                 m_aStates.top().aCharacterSprms.set(NS_sprm::LN_CHpsPos, pValue);
    2994             :             }
    2995           2 :             break;
    2996             :         case RTF_HORZVERT:
    2997             :             {
    2998           0 :                 RTFValue::Pointer_t pValue(new RTFValue(true));
    2999           0 :                 m_aStates.top().aCharacterAttributes.set(NS_ooxml::LN_CT_EastAsianLayout_vert, pValue);
    3000           0 :                 if (nParam)
    3001             :                     // rotate fits to a single line
    3002           0 :                     m_aStates.top().aCharacterAttributes.set(NS_ooxml::LN_CT_EastAsianLayout_vertCompress, pValue);
    3003             :             }
    3004           0 :             break;
    3005             :         case RTF_EXPND:
    3006             :             {
    3007           3 :                 RTFValue::Pointer_t pValue(new RTFValue(nParam/5));
    3008           3 :                 m_aStates.top().aCharacterSprms.set(NS_sprm::LN_CDxaSpace, pValue);
    3009             :             }
    3010           3 :             break;
    3011             :         case RTF_TWOINONE:
    3012             :             {
    3013           0 :                 RTFValue::Pointer_t pValue(new RTFValue(true));
    3014           0 :                 m_aStates.top().aCharacterAttributes.set(NS_ooxml::LN_CT_EastAsianLayout_combine, pValue);
    3015           0 :                 if (nParam > 0)
    3016           0 :                     m_aStates.top().aCharacterAttributes.set(NS_ooxml::LN_CT_EastAsianLayout_combineBrackets, pIntValue);
    3017             :             }
    3018           0 :             break;
    3019             :         case RTF_SL:
    3020             :             {
    3021             :                 // This is similar to RTF_ABSH, negative value means 'exact', positive means 'at least'.
    3022          64 :                 RTFValue::Pointer_t pValue(new RTFValue(NS_ooxml::LN_Value_wordprocessingml_ST_LineSpacingRule_atLeast));
    3023          64 :                 if (nParam < 0)
    3024             :                 {
    3025           6 :                     pValue.reset(new RTFValue(NS_ooxml::LN_Value_wordprocessingml_ST_LineSpacingRule_exact));
    3026           6 :                     pIntValue.reset(new RTFValue(-nParam));
    3027             :                 }
    3028          64 :                 m_aStates.top().aParagraphAttributes.set(NS_ooxml::LN_CT_Spacing_lineRule, pValue);
    3029          64 :                 m_aStates.top().aParagraphAttributes.set(NS_ooxml::LN_CT_Spacing_line, pIntValue);
    3030             :             }
    3031          64 :             break;
    3032             :         case RTF_SLMULT:
    3033          57 :             if (nParam > 0)
    3034             :             {
    3035          37 :                 RTFValue::Pointer_t pValue(new RTFValue(NS_ooxml::LN_Value_wordprocessingml_ST_LineSpacingRule_auto));
    3036          37 :                 m_aStates.top().aParagraphAttributes.set(NS_ooxml::LN_CT_Spacing_lineRule, pValue);
    3037             :             }
    3038          57 :             break;
    3039             :         case RTF_BRDRW:
    3040             :             {
    3041             :                 // dmapper expects it in 1/8 pt, we have it in twip - but avoid rounding 1 to 0
    3042         246 :                 if (nParam > 1)
    3043         235 :                     nParam = nParam * 2 / 5;
    3044         246 :                 RTFValue::Pointer_t pValue(new RTFValue(nParam));
    3045         246 :                 lcl_putBorderProperty(m_aStates, NS_rtf::LN_DPTLINEWIDTH, pValue);
    3046             :             }
    3047         246 :             break;
    3048             :         case RTF_BRDRCF:
    3049             :             {
    3050         111 :                 RTFValue::Pointer_t pValue(new RTFValue(getColorTable(nParam)));
    3051         111 :                 lcl_putBorderProperty(m_aStates, NS_ooxml::LN_CT_Border_color, pValue);
    3052             :             }
    3053         111 :             break;
    3054             :         case RTF_BRSP:
    3055             :             {
    3056             :                 // dmapper expects it in points, we have it in twip
    3057           1 :                 RTFValue::Pointer_t pValue(new RTFValue(nParam / 20));
    3058           1 :                 lcl_putBorderProperty(m_aStates, NS_rtf::LN_DPTSPACE, pValue);
    3059             :             }
    3060           1 :             break;
    3061             :         case RTF_TX:
    3062             :             {
    3063          96 :                 m_aStates.top().aTabAttributes.set(NS_ooxml::LN_CT_TabStop_pos, pIntValue);
    3064          96 :                 RTFValue::Pointer_t pValue(new RTFValue(m_aStates.top().aTabAttributes));
    3065          96 :                 lcl_putNestedSprm(m_aStates.top().aParagraphSprms, NS_ooxml::LN_CT_PPrBase_tabs, NS_ooxml::LN_CT_Tabs_tab, pValue);
    3066          96 :                 m_aStates.top().aTabAttributes.clear();
    3067             :             }
    3068          96 :             break;
    3069             :         case RTF_ILVL:
    3070           7 :             lcl_putNestedSprm(m_aStates.top().aParagraphSprms, NS_ooxml::LN_CT_PPrBase_numPr, NS_sprm::LN_PIlvl, pIntValue);
    3071           7 :             break;
    3072             :         case RTF_LISTTEMPLATEID:
    3073             :             // This one is not referenced anywhere, so it's pointless to store it at the moment.
    3074          11 :             break;
    3075             :         case RTF_LISTID:
    3076             :             {
    3077          21 :                 if (m_aStates.top().nDestinationState == DESTINATION_LISTENTRY)
    3078          11 :                     m_aStates.top().aTableAttributes.set(NS_ooxml::LN_CT_AbstractNum_abstractNumId, pIntValue);
    3079          10 :                 else if (m_aStates.top().nDestinationState == DESTINATION_LISTOVERRIDEENTRY)
    3080          10 :                     m_aStates.top().aTableSprms.set(NS_ooxml::LN_CT_Num_abstractNumId, pIntValue);
    3081             :             }
    3082          21 :             break;
    3083             :         case RTF_LS:
    3084             :             {
    3085          23 :                 if (m_aStates.top().nDestinationState == DESTINATION_LISTOVERRIDEENTRY)
    3086          10 :                     m_aStates.top().aTableAttributes.set(NS_rtf::LN_LSID, pIntValue);
    3087             :                 else
    3088          13 :                     lcl_putNestedSprm(m_aStates.top().aParagraphSprms, NS_ooxml::LN_CT_PPrBase_tabs, NS_sprm::LN_PIlfo, pIntValue);
    3089             :             }
    3090          23 :             break;
    3091             :         case RTF_UC:
    3092          18 :             if ((SAL_MIN_INT16 <= nParam) && (nParam <= SAL_MAX_INT16))
    3093          18 :                 m_aStates.top().nUc = nParam;
    3094          18 :             break;
    3095             :         case RTF_U:
    3096             :             // sal_Unicode is unsigned 16-bit, RTF may represent that as a
    3097             :             // signed SAL_MIN_INT16..SAL_MAX_INT16 or 0..SAL_MAX_UINT16. The
    3098             :             // static_cast() will do the right thing.
    3099         129 :             if ((SAL_MIN_INT16 <= nParam) && (nParam <= SAL_MAX_UINT16))
    3100             :             {
    3101         129 :                 m_aUnicodeBuffer.append(static_cast<sal_Unicode>(nParam));
    3102         129 :                 m_aStates.top().nCharsToSkip = m_aStates.top().nUc;
    3103             :             }
    3104         129 :             break;
    3105             :         case RTF_LEVELFOLLOW:
    3106          33 :             m_aStates.top().aTableAttributes.set(NS_rtf::LN_IXCHFOLLOW, pIntValue);
    3107          33 :             break;
    3108             :         case RTF_LISTOVERRIDECOUNT:
    3109             :             // Ignore this for now, the exporter always emits it with a zero parameter.
    3110          10 :             break;
    3111             :         case RTF_PICSCALEX:
    3112          10 :             m_aStates.top().aPicture.nScaleX = nParam;
    3113          10 :             break;
    3114             :         case RTF_PICSCALEY:
    3115          10 :             m_aStates.top().aPicture.nScaleY = nParam;
    3116          10 :             break;
    3117             :         case RTF_PICW:
    3118          11 :             m_aStates.top().aPicture.nWidth = nParam;
    3119          11 :             break;
    3120             :         case RTF_PICH:
    3121          11 :             m_aStates.top().aPicture.nHeight = nParam;
    3122          11 :             break;
    3123             :         case RTF_PICWGOAL:
    3124          12 :             m_aStates.top().aPicture.nGoalWidth = TWIP_TO_MM100(nParam);
    3125          12 :             break;
    3126             :         case RTF_PICHGOAL:
    3127          12 :             m_aStates.top().aPicture.nGoalHeight = TWIP_TO_MM100(nParam);
    3128          12 :             break;
    3129           8 :         case RTF_PICCROPL: m_aStates.top().aPicture.nCropL = TWIP_TO_MM100(nParam); break;
    3130           8 :         case RTF_PICCROPR: m_aStates.top().aPicture.nCropR = TWIP_TO_MM100(nParam); break;
    3131           8 :         case RTF_PICCROPT: m_aStates.top().aPicture.nCropT = TWIP_TO_MM100(nParam); break;
    3132           8 :         case RTF_PICCROPB: m_aStates.top().aPicture.nCropB = TWIP_TO_MM100(nParam); break;
    3133             :         case RTF_SHPWRK:
    3134             :             {
    3135          23 :                 int nValue = 0;
    3136          23 :                 switch (nParam)
    3137             :                 {
    3138          23 :                     case 0: nValue = NS_ooxml::LN_Value_wordprocessingDrawing_ST_WrapText_bothSides; break;
    3139           0 :                     case 1: nValue = NS_ooxml::LN_Value_wordprocessingDrawing_ST_WrapText_left; break;
    3140           0 :                     case 2: nValue = NS_ooxml::LN_Value_wordprocessingDrawing_ST_WrapText_right; break;
    3141           0 :                     case 3: nValue = NS_ooxml::LN_Value_wordprocessingDrawing_ST_WrapText_largest; break;
    3142           0 :                     default: break;
    3143             :                 }
    3144          23 :                 RTFValue::Pointer_t pValue(new RTFValue(nValue));
    3145          23 :                 m_aStates.top().aCharacterAttributes.set(NS_ooxml::LN_CT_WrapSquare_wrapText, pValue);
    3146             :             }
    3147          23 :             break;
    3148             :         case RTF_SHPWR:
    3149             :             {
    3150          28 :                 switch (nParam)
    3151             :                 {
    3152             :                 case 1:
    3153           0 :                     m_aStates.top().aShape.nWrap = com::sun::star::text::WrapTextMode_NONE; break;
    3154             :                 case 2:
    3155           1 :                     m_aStates.top().aShape.nWrap = com::sun::star::text::WrapTextMode_PARALLEL; break;
    3156             :                 case 3:
    3157          26 :                     m_aStates.top().aShape.nWrap = com::sun::star::text::WrapTextMode_THROUGHT; break;
    3158             :                 case 4:
    3159           0 :                     m_aStates.top().aShape.nWrap = com::sun::star::text::WrapTextMode_PARALLEL; break;
    3160             :                 case 5:
    3161           0 :                     m_aStates.top().aShape.nWrap = com::sun::star::text::WrapTextMode_THROUGHT; break;
    3162             :                 }
    3163             :             }
    3164          28 :             break;
    3165             :         case RTF_CELLX:
    3166             :             {
    3167         240 :                 int nCellX = nParam - m_aStates.top().nCellX;
    3168             : 
    3169             :                 // If there is a negative left margin, then the first cellx is relateve to that.
    3170         240 :                 RTFValue::Pointer_t pTblInd = m_aStates.top().aTableRowSprms.find(NS_ooxml::LN_CT_TblPrBase_tblInd);
    3171         240 :                 if (m_aStates.top().nCellX == 0 && pTblInd.get())
    3172             :                 {
    3173          44 :                     RTFValue::Pointer_t pWidth = pTblInd->getAttributes().find(NS_ooxml::LN_CT_TblWidth_w);
    3174          44 :                     if (pWidth.get() && pWidth->getInt() < 0)
    3175          36 :                         nCellX = -1 * (pWidth->getInt() - nParam);
    3176             :                 }
    3177             : 
    3178         240 :                 m_aStates.top().nCellX = nParam;
    3179         480 :                 RTFValue::Pointer_t pXValue(new RTFValue(nCellX));
    3180         240 :                 m_aStates.top().aTableRowSprms.set(NS_ooxml::LN_CT_TblGridBase_gridCol, pXValue, false);
    3181         240 :                 m_aStates.top().nCells++;
    3182             : 
    3183             :                 // Push cell properties.
    3184         240 :                 m_aStates.top().aTableCellsSprms.push_back(m_aStates.top().aTableCellSprms);
    3185         240 :                 m_aStates.top().aTableCellsAttributes.push_back(m_aStates.top().aTableCellAttributes);
    3186         240 :                 m_aStates.top().aTableCellSprms = m_aDefaultState.aTableCellSprms;
    3187         240 :                 m_aStates.top().aTableCellAttributes = m_aDefaultState.aTableCellAttributes;
    3188             :                 // We assume text after a row definition always belongs to the table, to handle text before the real INTBL token
    3189         240 :                 dispatchFlag(RTF_INTBL);
    3190         480 :                 m_nCellxMax = std::max(m_nCellxMax, nParam);
    3191             :             }
    3192         240 :             break;
    3193             :         case RTF_TRRH:
    3194             :             {
    3195           3 :                 OUString hRule("auto");
    3196           3 :                 if ( nParam < 0 )
    3197             :                 {
    3198           0 :                     RTFValue::Pointer_t pAbsValue(new RTFValue(-nParam));
    3199           0 :                     pIntValue.swap( pAbsValue );
    3200             : 
    3201           0 :                     hRule = "exact";
    3202             :                 }
    3203           3 :                 else if ( nParam > 0 )
    3204           3 :                     hRule = "atLeast";
    3205             : 
    3206           3 :                 lcl_putNestedAttribute(m_aStates.top().aTableRowSprms,
    3207           6 :                         NS_ooxml::LN_CT_TrPrBase_trHeight, NS_ooxml::LN_CT_Height_val, pIntValue);
    3208             : 
    3209           6 :                 RTFValue::Pointer_t pHRule(new RTFValue(hRule));
    3210           3 :                 lcl_putNestedAttribute(m_aStates.top().aTableRowSprms,
    3211           9 :                     NS_ooxml::LN_CT_TrPrBase_trHeight, NS_ooxml::LN_CT_Height_hRule, pHRule);
    3212             :             }
    3213           3 :             break;
    3214             :         case RTF_TRLEFT:
    3215             :             {
    3216             :                 // the value is in twips
    3217          44 :                 lcl_putNestedAttribute(m_aStates.top().aTableRowSprms,
    3218             :                         NS_ooxml::LN_CT_TblPrBase_tblInd, NS_ooxml::LN_CT_TblWidth_type,
    3219          88 :                         RTFValue::Pointer_t(new RTFValue(NS_ooxml::LN_Value_ST_TblWidth_dxa)));
    3220          44 :                 lcl_putNestedAttribute(m_aStates.top().aTableRowSprms,
    3221             :                         NS_ooxml::LN_CT_TblPrBase_tblInd, NS_ooxml::LN_CT_TblWidth_w,
    3222          88 :                         RTFValue::Pointer_t(new RTFValue(nParam)));
    3223             :             }
    3224          44 :             break;
    3225             :         case RTF_COLS:
    3226           1 :             lcl_putNestedAttribute(m_aStates.top().aSectionSprms,
    3227           2 :                     NS_ooxml::LN_EG_SectPrContents_cols, NS_ooxml::LN_CT_Columns_num, pIntValue);
    3228           1 :             break;
    3229             :         case RTF_COLSX:
    3230           4 :             lcl_putNestedAttribute(m_aStates.top().aSectionSprms,
    3231           8 :                     NS_ooxml::LN_EG_SectPrContents_cols, NS_ooxml::LN_CT_Columns_space, pIntValue);
    3232           4 :             break;
    3233             :         case RTF_COLNO:
    3234           0 :             lcl_putNestedSprm(m_aStates.top().aSectionSprms,
    3235           0 :                     NS_ooxml::LN_EG_SectPrContents_cols, NS_ooxml::LN_CT_Columns_col, pIntValue);
    3236           0 :             break;
    3237             :         case RTF_COLW:
    3238             :         case RTF_COLSR:
    3239             :             {
    3240           0 :                 RTFSprms& rAttributes = lcl_getLastAttributes(m_aStates.top().aSectionSprms, NS_ooxml::LN_EG_SectPrContents_cols);
    3241           0 :                 rAttributes.set((nKeyword == RTF_COLW ? NS_ooxml::LN_CT_Column_w : NS_ooxml::LN_CT_Column_space), pIntValue);
    3242             :             }
    3243           0 :             break;
    3244             :         case RTF_PAPERH: // fall through: set the default + current value
    3245             :             lcl_putNestedAttribute(m_aDefaultState.aSectionSprms,
    3246          71 :                     NS_ooxml::LN_EG_SectPrContents_pgSz, NS_ooxml::LN_CT_PageSz_h, pIntValue, true);
    3247             :         case RTF_PGHSXN:
    3248         121 :             lcl_putNestedAttribute(m_aStates.top().aSectionSprms,
    3249         242 :                     NS_ooxml::LN_EG_SectPrContents_pgSz, NS_ooxml::LN_CT_PageSz_h, pIntValue, true);
    3250         121 :             break;
    3251             :         case RTF_PAPERW: // fall through: set the default + current value
    3252             :             lcl_putNestedAttribute(m_aDefaultState.aSectionSprms,
    3253          71 :                     NS_ooxml::LN_EG_SectPrContents_pgSz, NS_ooxml::LN_CT_PageSz_w, pIntValue, true);
    3254             :         case RTF_PGWSXN:
    3255         121 :             lcl_putNestedAttribute(m_aStates.top().aSectionSprms,
    3256         242 :                     NS_ooxml::LN_EG_SectPrContents_pgSz, NS_ooxml::LN_CT_PageSz_w, pIntValue, true);
    3257         121 :             break;
    3258             :         case RTF_MARGL: // fall through: set the default + current value
    3259             :             lcl_putNestedAttribute(m_aDefaultState.aSectionSprms,
    3260          71 :                     NS_ooxml::LN_EG_SectPrContents_pgMar, NS_ooxml::LN_CT_PageMar_left, pIntValue, true);
    3261             :         case RTF_MARGLSXN:
    3262         123 :             lcl_putNestedAttribute(m_aStates.top().aSectionSprms,
    3263         246 :                     NS_ooxml::LN_EG_SectPrContents_pgMar, NS_ooxml::LN_CT_PageMar_left, pIntValue, true);
    3264         123 :             break;
    3265             :         case RTF_MARGR: // fall through: set the default + current value
    3266             :             lcl_putNestedAttribute(m_aDefaultState.aSectionSprms,
    3267          71 :                     NS_ooxml::LN_EG_SectPrContents_pgMar, NS_ooxml::LN_CT_PageMar_right, pIntValue, true);
    3268             :         case RTF_MARGRSXN:
    3269         123 :             lcl_putNestedAttribute(m_aStates.top().aSectionSprms,
    3270         246 :                     NS_ooxml::LN_EG_SectPrContents_pgMar, NS_ooxml::LN_CT_PageMar_right, pIntValue, true);
    3271         123 :             break;
    3272             :         case RTF_MARGT: // fall through: set the default + current value
    3273             :             lcl_putNestedAttribute(m_aDefaultState.aSectionSprms,
    3274          70 :                     NS_ooxml::LN_EG_SectPrContents_pgMar, NS_ooxml::LN_CT_PageMar_top, pIntValue, true);
    3275             :         case RTF_MARGTSXN:
    3276         121 :             lcl_putNestedAttribute(m_aStates.top().aSectionSprms,
    3277         242 :                     NS_ooxml::LN_EG_SectPrContents_pgMar, NS_ooxml::LN_CT_PageMar_top, pIntValue, true);
    3278         121 :             break;
    3279             :         case RTF_MARGB: // fall through: set the default + current value
    3280             :             lcl_putNestedAttribute(m_aDefaultState.aSectionSprms,
    3281          69 :                     NS_ooxml::LN_EG_SectPrContents_pgMar, NS_ooxml::LN_CT_PageMar_bottom, pIntValue, true);
    3282             :         case RTF_MARGBSXN:
    3283         120 :             lcl_putNestedAttribute(m_aStates.top().aSectionSprms,
    3284         240 :                     NS_ooxml::LN_EG_SectPrContents_pgMar, NS_ooxml::LN_CT_PageMar_bottom, pIntValue, true);
    3285         120 :             break;
    3286             :         case RTF_HEADERY:
    3287           6 :             lcl_putNestedAttribute(m_aStates.top().aSectionSprms,
    3288          12 :                     NS_ooxml::LN_EG_SectPrContents_pgMar, NS_ooxml::LN_CT_PageMar_header, pIntValue, true);
    3289           6 :             break;
    3290             :         case RTF_FOOTERY:
    3291           5 :             lcl_putNestedAttribute(m_aStates.top().aSectionSprms,
    3292          10 :                     NS_ooxml::LN_EG_SectPrContents_pgMar, NS_ooxml::LN_CT_PageMar_footer, pIntValue, true);
    3293           5 :             break;
    3294             :         case RTF_DEFTAB:
    3295          51 :             m_aSettingsTableSprms.set(NS_ooxml::LN_CT_Settings_defaultTabStop, pIntValue);
    3296          51 :             break;
    3297             :         case RTF_LINEMOD:
    3298           0 :             lcl_putNestedAttribute(m_aStates.top().aSectionSprms,
    3299           0 :                     NS_ooxml::LN_EG_SectPrContents_lnNumType, NS_ooxml::LN_CT_LineNumber_countBy, pIntValue);
    3300           0 :             break;
    3301             :         case RTF_LINEX:
    3302           8 :             if (nParam)
    3303           0 :                 lcl_putNestedAttribute(m_aStates.top().aSectionSprms,
    3304           0 :                         NS_ooxml::LN_EG_SectPrContents_lnNumType, NS_ooxml::LN_CT_LineNumber_distance, pIntValue);
    3305           8 :             break;
    3306             :         case RTF_LINESTARTS:
    3307           0 :             lcl_putNestedAttribute(m_aStates.top().aSectionSprms,
    3308           0 :                     NS_ooxml::LN_EG_SectPrContents_lnNumType, NS_ooxml::LN_CT_LineNumber_start, pIntValue);
    3309           0 :             break;
    3310             :         case RTF_REVAUTH:
    3311             :         case RTF_REVAUTHDEL:
    3312             :             {
    3313           0 :                 RTFValue::Pointer_t pValue(new RTFValue(m_aAuthors[nParam]));
    3314           0 :                 lcl_putNestedAttribute(m_aStates.top().aCharacterSprms,
    3315           0 :                         NS_ooxml::LN_trackchange, NS_ooxml::LN_CT_TrackChange_author, pValue);
    3316             :             }
    3317           0 :             break;
    3318             :         case RTF_REVDTTM:
    3319             :         case RTF_REVDTTMDEL:
    3320             :             {
    3321           0 :                 OUString aStr(OStringToOUString(lcl_DTTM22OString(nParam), m_aStates.top().nCurrentEncoding));
    3322           0 :                 RTFValue::Pointer_t pValue(new RTFValue(aStr));
    3323           0 :                 lcl_putNestedAttribute(m_aStates.top().aCharacterSprms,
    3324           0 :                         NS_ooxml::LN_trackchange, NS_ooxml::LN_CT_TrackChange_date, pValue);
    3325             :             }
    3326           0 :             break;
    3327             :         case RTF_SHPLEFT:
    3328          43 :             m_aStates.top().aShape.nLeft = TWIP_TO_MM100(nParam);
    3329          43 :             break;
    3330             :         case RTF_SHPTOP:
    3331          43 :             m_aStates.top().aShape.nTop = TWIP_TO_MM100(nParam);
    3332          43 :             break;
    3333             :         case RTF_SHPRIGHT:
    3334          41 :             m_aStates.top().aShape.nRight = TWIP_TO_MM100(nParam);
    3335          41 :             break;
    3336             :         case RTF_SHPBOTTOM:
    3337          41 :             m_aStates.top().aShape.nBottom = TWIP_TO_MM100(nParam);
    3338          41 :             break;
    3339             :         case RTF_SHPZ:
    3340          24 :             m_aStates.top().aShape.oZ.reset(nParam);
    3341          24 :             break;
    3342             :         case RTF_FFTYPE:
    3343           0 :             switch (nParam)
    3344             :             {
    3345           0 :                 case 0: m_nFormFieldType = FORMFIELD_TEXT; break;
    3346           0 :                 case 1: m_nFormFieldType = FORMFIELD_CHECKBOX; break;
    3347           0 :                 case 2: m_nFormFieldType = FORMFIELD_LIST; break;
    3348           0 :                 default: m_nFormFieldType = FORMFIELD_NONE; break;
    3349             :             }
    3350           0 :             break;
    3351             :         case RTF_FFDEFRES:
    3352           0 :             if (m_nFormFieldType == FORMFIELD_CHECKBOX)
    3353           0 :                 m_aFormfieldSprms.set(NS_ooxml::LN_CT_FFCheckBox_default, pIntValue);
    3354           0 :             else if (m_nFormFieldType == FORMFIELD_LIST)
    3355           0 :                 m_aFormfieldSprms.set(NS_ooxml::LN_CT_FFDDList_default, pIntValue);
    3356           0 :             break;
    3357             :         case RTF_FFRES:
    3358           0 :             if (m_nFormFieldType == FORMFIELD_CHECKBOX)
    3359           0 :                 m_aFormfieldSprms.set(NS_ooxml::LN_CT_FFCheckBox_checked, pIntValue);
    3360           0 :             else if (m_nFormFieldType == FORMFIELD_LIST)
    3361           0 :                 m_aFormfieldSprms.set(NS_ooxml::LN_CT_FFDDList_result, pIntValue);
    3362           0 :             break;
    3363             :         case RTF_EDMINS:
    3364           3 :             if (m_xDocumentProperties.is())
    3365           1 :                 m_xDocumentProperties->setEditingDuration(nParam);
    3366           3 :             break;
    3367             :         case RTF_NOFPAGES:
    3368             :         case RTF_NOFWORDS:
    3369             :         case RTF_NOFCHARS:
    3370             :         case RTF_NOFCHARSWS:
    3371          12 :             if (m_xDocumentProperties.is())
    3372             :             {
    3373           4 :                 uno::Sequence<beans::NamedValue> aSet = m_xDocumentProperties->getDocumentStatistics();
    3374           8 :                 OUString aName;
    3375           4 :                 switch (nKeyword)
    3376             :                 {
    3377           1 :                     case RTF_NOFPAGES: aName = "PageCount"; nParam = 99; break;
    3378           1 :                     case RTF_NOFWORDS: aName = "WordCount"; break;
    3379           1 :                     case RTF_NOFCHARS: aName = "CharacterCount"; break;
    3380           1 :                     case RTF_NOFCHARSWS: aName = "NonWhitespaceCharacterCount"; break;
    3381           0 :                     default: break;
    3382             :                 }
    3383           4 :                 if (!aName.isEmpty())
    3384             :                 {
    3385           4 :                     bool bFound = false;
    3386           4 :                     int nLen = aSet.getLength();
    3387          10 :                     for (int i = 0; i < nLen; ++i)
    3388           6 :                         if (aSet[i].Name.equals(aName))
    3389           0 :                             aSet[i].Value = uno::makeAny(sal_Int32(nParam));
    3390           4 :                     if (!bFound)
    3391             :                     {
    3392           4 :                         aSet.realloc(nLen + 1);
    3393           4 :                         aSet[nLen].Name = aName;
    3394           4 :                         aSet[nLen].Value = uno::makeAny(sal_Int32(nParam));
    3395             :                     }
    3396           4 :                     m_xDocumentProperties->setDocumentStatistics(aSet);
    3397           4 :                 }
    3398             :             }
    3399          12 :             break;
    3400             :         case RTF_VERSION:
    3401           3 :             if (m_xDocumentProperties.is())
    3402           1 :                 m_xDocumentProperties->setEditingCycles(nParam);
    3403           3 :             break;
    3404             :         case RTF_VERN:
    3405             :             // Ignore this for now, later the RTF writer version could be used to add hacks for older buggy writers.
    3406          49 :             break;
    3407             :         case RTF_FTNSTART:
    3408             :             lcl_putNestedSprm(m_aDefaultState.aParagraphSprms,
    3409          52 :                     NS_ooxml::LN_EG_SectPrContents_footnotePr, NS_ooxml::LN_EG_FtnEdnNumProps_numStart, pIntValue);
    3410          52 :             break;
    3411             :         case RTF_AFTNSTART:
    3412             :             lcl_putNestedSprm(m_aDefaultState.aParagraphSprms,
    3413          50 :                     NS_ooxml::LN_EG_SectPrContents_endnotePr, NS_ooxml::LN_EG_FtnEdnNumProps_numStart, pIntValue);
    3414          50 :             break;
    3415             :         case RTF_DFRMTXTX:
    3416           3 :             m_aStates.top().aFrame.setSprm(NS_sprm::LN_PDxaFromText, nParam);
    3417           3 :             break;
    3418             :         case RTF_DFRMTXTY:
    3419           3 :             m_aStates.top().aFrame.setSprm(NS_sprm::LN_PDyaFromText, nParam);
    3420           3 :             break;
    3421             :         case RTF_DXFRTEXT:
    3422             :             {
    3423           2 :                 m_aStates.top().aFrame.setSprm(NS_sprm::LN_PDxaFromText, nParam);
    3424           2 :                 m_aStates.top().aFrame.setSprm(NS_sprm::LN_PDyaFromText, nParam);
    3425             :             }
    3426           2 :             break;
    3427             :         case RTF_FLYVERT:
    3428             :             {
    3429           1 :                 RTFVertOrient aVertOrient(nParam);
    3430           1 :                 m_aStates.top().aFrame.setSprm(NS_ooxml::LN_CT_FramePr_yAlign, aVertOrient.GetAlign());
    3431           1 :                 m_aStates.top().aFrame.setSprm(NS_ooxml::LN_CT_FramePr_vAnchor, aVertOrient.GetAnchor());
    3432             :             }
    3433           1 :             break;
    3434             :         case RTF_FLYHORZ:
    3435             :             {
    3436           1 :                 RTFHoriOrient aHoriOrient(nParam);
    3437           1 :                 m_aStates.top().aFrame.setSprm(NS_ooxml::LN_CT_FramePr_xAlign, aHoriOrient.GetAlign());
    3438           1 :                 m_aStates.top().aFrame.setSprm(NS_ooxml::LN_CT_FramePr_hAnchor, aHoriOrient.GetAnchor());
    3439             :             }
    3440           1 :             break;
    3441             :         case RTF_FLYANCHOR:
    3442           1 :             m_aStates.top().aFrame.nAnchorType = nParam;
    3443           1 :             break;
    3444             :         case RTF_WMETAFILE:
    3445           2 :             m_aStates.top().aPicture.eWMetafile = nParam;
    3446           2 :             break;
    3447             :         case RTF_SB:
    3448         262 :             lcl_putNestedAttribute(m_aStates.top().aParagraphSprms,
    3449         524 :                     NS_ooxml::LN_CT_PPrBase_spacing, NS_ooxml::LN_CT_Spacing_before, pIntValue, true);
    3450         262 :             break;
    3451             :         case RTF_SA:
    3452         290 :             lcl_putNestedAttribute(m_aStates.top().aParagraphSprms,
    3453         580 :                     NS_ooxml::LN_CT_PPrBase_spacing, NS_ooxml::LN_CT_Spacing_after, pIntValue, true);
    3454         290 :             break;
    3455             :         case RTF_DPX:
    3456          18 :             m_aStates.top().aDrawingObject.nLeft = TWIP_TO_MM100(nParam);
    3457          18 :             break;
    3458             :         case RTF_DPY:
    3459          18 :             m_aStates.top().aDrawingObject.nTop = TWIP_TO_MM100(nParam);
    3460          18 :             break;
    3461             :         case RTF_DPXSIZE:
    3462          18 :             m_aStates.top().aDrawingObject.nRight = TWIP_TO_MM100(nParam);
    3463          18 :             break;
    3464             :         case RTF_DPYSIZE:
    3465          18 :             m_aStates.top().aDrawingObject.nBottom = TWIP_TO_MM100(nParam);
    3466          18 :             break;
    3467             :         case RTF_PNSTART:
    3468           4 :             m_aStates.top().aTableSprms.set(NS_rtf::LN_ISTARTAT, pIntValue);
    3469           4 :             break;
    3470             :         case RTF_PNF:
    3471             :             {
    3472           1 :                 int nFontIndex = getFontIndex(nParam);
    3473           1 :                 RTFValue::Pointer_t pValue(new RTFValue(nFontIndex));
    3474           1 :                 lcl_putNestedSprm(m_aStates.top().aTableSprms, NS_ooxml::LN_CT_Lvl_rPr, NS_sprm::LN_CRgFtc0, pValue);
    3475             :             }
    3476           1 :             break;
    3477             :         case RTF_VIEWSCALE:
    3478          55 :             m_aSettingsTableAttributes.set(NS_ooxml::LN_CT_Zoom_percent, pIntValue);
    3479          55 :             break;
    3480             :         case RTF_BIN:
    3481             :             {
    3482           1 :                 m_aStates.top().nInternalState = INTERNAL_BIN;
    3483           1 :                 m_aStates.top().nBinaryToRead = nParam;
    3484             :             }
    3485           1 :             break;
    3486             :         case RTF_DPLINECOR:
    3487           7 :             m_aStates.top().aDrawingObject.nLineColorR = nParam; m_aStates.top().aDrawingObject.bHasLineColor = true;
    3488           7 :             break;
    3489             :         case RTF_DPLINECOG:
    3490           7 :             m_aStates.top().aDrawingObject.nLineColorG = nParam; m_aStates.top().aDrawingObject.bHasLineColor = true;
    3491           7 :             break;
    3492             :         case RTF_DPLINECOB:
    3493           7 :             m_aStates.top().aDrawingObject.nLineColorB = nParam; m_aStates.top().aDrawingObject.bHasLineColor = true;
    3494           7 :             break;
    3495             :         case RTF_DPFILLBGCR:
    3496           3 :             m_aStates.top().aDrawingObject.nFillColorR = nParam; m_aStates.top().aDrawingObject.bHasFillColor = true;
    3497           3 :             break;
    3498             :         case RTF_DPFILLBGCG:
    3499           3 :             m_aStates.top().aDrawingObject.nFillColorG = nParam; m_aStates.top().aDrawingObject.bHasFillColor = true;
    3500           3 :             break;
    3501             :         case RTF_DPFILLBGCB:
    3502           3 :             m_aStates.top().aDrawingObject.nFillColorB = nParam; m_aStates.top().aDrawingObject.bHasFillColor = true;
    3503           3 :             break;
    3504             :         case RTF_LI:
    3505             :             {
    3506         243 :                 m_aStates.top().aParagraphSprms.set(NS_sprm::LN_PDxaLeft, pIntValue);
    3507             :                 // It turns out \li should reset the \fi inherited from the stylesheet.
    3508             :                 // So set the direct formatting to zero, if we don't have such direct formatting yet.
    3509         243 :                 if (!m_aStates.top().aParagraphSprms.find(NS_sprm::LN_PDxaLeft1).get())
    3510         105 :                     m_aStates.top().aParagraphSprms.set(NS_sprm::LN_PDxaLeft1, RTFValue::Pointer_t(new RTFValue(0)));
    3511             :             }
    3512         243 :             break;
    3513             :         case RTF_CLSHDNG:
    3514             :             {
    3515           0 :                 int nValue = -1;
    3516           0 :                 switch (nParam)
    3517             :                 {
    3518           0 :                     case 500: nValue = 2; break;
    3519           0 :                     case 1000: nValue = 3; break;
    3520           0 :                     case 1200: nValue = 27; break;
    3521           0 :                     case 1500: nValue = 28; break;
    3522           0 :                     case 2000: nValue = 4; break;
    3523           0 :                     case 2500: nValue = 5; break;
    3524           0 :                     case 3000: nValue = 6; break;
    3525           0 :                     case 3500: nValue = 43; break;
    3526           0 :                     case 3700: nValue = 44; break;
    3527           0 :                     case 4000: nValue = 7; break;
    3528           0 :                     case 4500: nValue = 46; break;
    3529           0 :                     case 5000: nValue = 8; break;
    3530           0 :                     case 5500: nValue = 49; break;
    3531           0 :                     case 6000: nValue = 9; break;
    3532           0 :                     case 6200: nValue = 51; break;
    3533           0 :                     case 6500: nValue = 52; break;
    3534           0 :                     case 7000: nValue = 10; break;
    3535           0 :                     case 7500: nValue = 11; break;
    3536           0 :                     case 8000: nValue = 12; break;
    3537           0 :                     case 8500: nValue = 57; break;
    3538           0 :                     case 8700: nValue = 58; break;
    3539           0 :                     case 9000: nValue = 13; break;
    3540           0 :                     case 9500: nValue = 60; break;
    3541           0 :                     default: break;
    3542             :                 }
    3543           0 :                 if (nValue != -1)
    3544           0 :                     lcl_putNestedAttribute(m_aStates.top().aTableCellSprms,
    3545           0 :                             NS_ooxml::LN_CT_TcPrBase_shd, NS_ooxml::LN_CT_Shd_val, RTFValue::Pointer_t(new RTFValue(nValue)));
    3546             :             }
    3547           0 :             break;
    3548             :         case RTF_DODHGT:
    3549          10 :             m_aStates.top().aDrawingObject.nDhgt = nParam;
    3550          10 :             break;
    3551             :         case RTF_DPPOLYCOUNT:
    3552           7 :             if (nParam >= 0)
    3553             :             {
    3554           7 :                 m_aStates.top().aDrawingObject.nPolyLineCount = nParam;
    3555           7 :                 m_aStates.top().aDrawingObject.aPolyLinePoints.realloc(nParam);
    3556             :             }
    3557           7 :             break;
    3558             :         case RTF_DPPTX:
    3559             :             {
    3560          14 :                 RTFDrawingObject& rDrawingObject = m_aStates.top().aDrawingObject;
    3561             : 
    3562          14 :                 if (!rDrawingObject.aPolyLinePoints.hasElements())
    3563           3 :                     dispatchValue(RTF_DPPOLYCOUNT, 2);
    3564             : 
    3565          14 :                 rDrawingObject.aPolyLinePoints[rDrawingObject.aPolyLinePoints.getLength() - rDrawingObject.nPolyLineCount].X = TWIP_TO_MM100(nParam);
    3566             :             }
    3567          14 :             break;
    3568             :         case RTF_DPPTY:
    3569             :             {
    3570          14 :                 RTFDrawingObject& rDrawingObject = m_aStates.top().aDrawingObject;
    3571          14 :                 if (rDrawingObject.aPolyLinePoints.hasElements())
    3572             :                 {
    3573          14 :                     rDrawingObject.aPolyLinePoints[rDrawingObject.aPolyLinePoints.getLength() - rDrawingObject.nPolyLineCount].Y = TWIP_TO_MM100(nParam);
    3574          14 :                     rDrawingObject.nPolyLineCount--;
    3575          14 :                     if (rDrawingObject.nPolyLineCount == 0)
    3576             :                     {
    3577           7 :                         uno::Sequence< uno::Sequence<awt::Point> >aPointSequenceSequence(1);
    3578           7 :                         aPointSequenceSequence[0] = rDrawingObject.aPolyLinePoints;
    3579           7 :                         rDrawingObject.xPropertySet->setPropertyValue("PolyPolygon", uno::Any(aPointSequenceSequence));
    3580             :                     }
    3581             :                 }
    3582             :             }
    3583          14 :             break;
    3584             :         case RTF_SHPFBLWTXT:
    3585          23 :             if (nParam == 1)
    3586             :             {
    3587             :                 // Shape is below text -> send it to the background.
    3588          12 :                 m_aStates.top().aCharacterAttributes.erase(NS_ooxml::LN_CT_WrapSquare_wrapText);
    3589          12 :                 m_aStates.top().aCharacterAttributes.set(NS_rtf::LN_WR, RTFValue::Pointer_t(new RTFValue(3)));
    3590             :             }
    3591          23 :             break;
    3592             :         case RTF_TS:
    3593          36 :             m_aStates.top().bHasTableStyle = true;
    3594          36 :             break;
    3595             :         default:
    3596             :             {
    3597             :                 SAL_INFO("writerfilter", "TODO handle value '" << lcl_RtfToString(nKeyword) << "'");
    3598        3993 :                 aSkip.setParsed(false);
    3599             :             }
    3600        3993 :             break;
    3601             :     }
    3602       35005 :     return 0;
    3603             : }
    3604             : 
    3605         673 : int RTFDocumentImpl::dispatchToggle(RTFKeyword nKeyword, bool bParam, int nParam)
    3606             : {
    3607         673 :     checkUnicode(/*bUnicode =*/ true, /*bHex =*/ true);
    3608         673 :     setNeedSect();
    3609         673 :     RTFSkipDestination aSkip(*this);
    3610         673 :     int nSprm = -1;
    3611        1346 :     RTFValue::Pointer_t pBoolValue(new RTFValue(!bParam || nParam != 0));
    3612             : 
    3613             :     // Map all underline toggles to a single sprm.
    3614         673 :     switch (nKeyword)
    3615             :     {
    3616          16 :         case RTF_UL: nSprm = 1; break;
    3617           0 :         case RTF_ULDASH: nSprm = 7; break;
    3618           0 :         case RTF_ULDASHD: nSprm = 9; break;
    3619           0 :         case RTF_ULDASHDD: nSprm = 10; break;
    3620           0 :         case RTF_ULDB: nSprm = 3; break;
    3621           0 :         case RTF_ULHWAVE: nSprm = 27; break;
    3622           0 :         case RTF_ULLDASH: nSprm = 39; break;
    3623           0 :         case RTF_ULTH: nSprm = 6; break;
    3624           0 :         case RTF_ULTHD: nSprm = 20; break;
    3625           0 :         case RTF_ULTHDASH: nSprm = 23; break;
    3626           0 :         case RTF_ULTHDASHD: nSprm = 25; break;
    3627           0 :         case RTF_ULTHDASHDD: nSprm = 26; break;
    3628           0 :         case RTF_ULTHLDASH: nSprm = 55; break;
    3629           0 :         case RTF_ULULDBWAVE: nSprm = 43; break;
    3630           0 :         case RTF_ULWAVE: nSprm = 11; break;
    3631         657 :         default: break;
    3632             :     }
    3633         673 :     if (nSprm >= 0)
    3634             :     {
    3635          16 :         RTFValue::Pointer_t pValue(new RTFValue((!bParam || nParam != 0) ? nSprm : 0));
    3636          16 :         m_aStates.top().aCharacterSprms.set(NS_sprm::LN_CKul, pValue);
    3637          16 :         return 0;
    3638             :     }
    3639             : 
    3640             :     // Accent characters (over dot / over coma).
    3641         657 :     switch (nKeyword)
    3642             :     {
    3643           0 :         case RTF_ACCNONE: nSprm = 0; break;
    3644           0 :         case RTF_ACCDOT: nSprm = 1; break;
    3645           0 :         case RTF_ACCCOMMA: nSprm = 2; break;
    3646           0 :         case RTF_ACCCIRCLE: nSprm = 3; break;
    3647           0 :         case RTF_ACCUNDERDOT: nSprm = 4; break;
    3648         657 :         default: break;
    3649             :     }
    3650         657 :     if (nSprm >= 0)
    3651             :     {
    3652           0 :         RTFValue::Pointer_t pValue(new RTFValue((!bParam || nParam != 0) ? nSprm : 0));
    3653           0 :         m_aStates.top().aCharacterSprms.set(NS_sprm::LN_CKcd, pValue);
    3654           0 :         return 0;
    3655             :     }
    3656             : 
    3657             :     // Trivial character sprms.
    3658         657 :     switch (nKeyword)
    3659             :     {
    3660          49 :         case RTF_B: nSprm = NS_sprm::LN_CFBold; break;
    3661          17 :         case RTF_AB: nSprm = NS_sprm::LN_CFBoldBi; break;
    3662         294 :         case RTF_I: nSprm = NS_sprm::LN_CFItalic; break;
    3663          52 :         case RTF_AI: nSprm = NS_sprm::LN_CFItalicBi; break;
    3664           0 :         case RTF_UL: nSprm = NS_sprm::LN_CKul; break;
    3665           0 :         case RTF_OUTL: nSprm = NS_sprm::LN_CFOutline; break;
    3666           0 :         case RTF_SHAD: nSprm = NS_sprm::LN_CFShadow; break;
    3667           0 :         case RTF_V: nSprm = NS_sprm::LN_CFVanish; break;
    3668           8 :         case RTF_STRIKE: nSprm = NS_sprm::LN_CFStrike; break;
    3669           0 :         case RTF_STRIKED: nSprm = NS_sprm::LN_CFDStrike; break;
    3670           6 :         case RTF_SCAPS: nSprm = NS_sprm::LN_CFSmallCaps; break;
    3671           0 :         case RTF_IMPR: nSprm = NS_sprm::LN_CFImprint; break;
    3672           1 :         case RTF_CAPS: nSprm = NS_sprm::LN_CFCaps; break;
    3673         230 :         default: break;
    3674             :     }
    3675         657 :     if (nSprm >= 0)
    3676             :     {
    3677         427 :         m_aStates.top().aCharacterSprms.set(nSprm, pBoolValue);
    3678         427 :         return 0;
    3679             :     }
    3680             : 
    3681         230 :     switch (nKeyword)
    3682             :     {
    3683             :         case RTF_ASPALPHA:
    3684         124 :             m_aStates.top().aParagraphSprms.set(NS_sprm::LN_PFAutoSpaceDE, pBoolValue);
    3685         124 :             break;
    3686             :         case RTF_DELETED:
    3687             :         case RTF_REVISED:
    3688             :             {
    3689           0 :                 RTFValue::Pointer_t pValue(new RTFValue(nKeyword == RTF_DELETED ? ooxml::OOXML_del : ooxml::OOXML_ins));
    3690           0 :                 lcl_putNestedAttribute(m_aStates.top().aCharacterSprms,
    3691           0 :                         NS_ooxml::LN_trackchange, NS_ooxml::LN_token, pValue);
    3692             :             }
    3693           0 :             break;
    3694             :         default:
    3695             :             {
    3696             :                 SAL_INFO("writerfilter", "TODO handle toggle '" << lcl_RtfToString(nKeyword) << "'");
    3697         106 :                 aSkip.setParsed(false);
    3698             :             }
    3699         106 :             break;
    3700             :     }
    3701         903 :     return 0;
    3702             : }
    3703             : 
    3704        7395 : int RTFDocumentImpl::pushState()
    3705             : {
    3706             :     //SAL_INFO("writerfilter", OSL_THIS_FUNC << " before push: " << m_pTokenizer->getGroup());
    3707             : 
    3708        7395 :     checkUnicode(/*bUnicode =*/ true, /*bHex =*/ true);
    3709        7395 :     m_nGroupStartPos = Strm().Tell();
    3710             : 
    3711        7395 :     if (m_aStates.empty())
    3712         206 :         m_aStates.push(m_aDefaultState);
    3713             :     else
    3714             :     {
    3715        7189 :         if (m_aStates.top().nDestinationState == DESTINATION_MR)
    3716         231 :             lcl_DestinationToMath(m_aStates.top().aDestinationText, m_aMathBuffer, m_bMathNor);
    3717        7189 :         m_aStates.push(m_aStates.top());
    3718             :     }
    3719        7395 :     m_aStates.top().aDestinationText.setLength(0);
    3720             : 
    3721        7395 :     m_pTokenizer->pushGroup();
    3722             : 
    3723        7395 :     switch (m_aStates.top().nDestinationState)
    3724             :     {
    3725             :         case DESTINATION_FONTTABLE:
    3726         708 :             m_aStates.top().nDestinationState = DESTINATION_FONTENTRY;
    3727         708 :             break;
    3728             :         case DESTINATION_STYLESHEET:
    3729         417 :             m_aStates.top().nDestinationState = DESTINATION_STYLEENTRY;
    3730         417 :             break;
    3731             :         case DESTINATION_FIELDRESULT:
    3732             :         case DESTINATION_SHAPETEXT:
    3733             :         case DESTINATION_FORMFIELD:
    3734             :         case DESTINATION_FIELDINSTRUCTION:
    3735          34 :             m_aStates.top().nDestinationState = DESTINATION_NORMAL;
    3736          34 :             break;
    3737             :         case DESTINATION_MNUM:
    3738             :         case DESTINATION_MDEN:
    3739             :         case DESTINATION_ME:
    3740             :         case DESTINATION_MFNAME:
    3741             :         case DESTINATION_MLIM:
    3742             :         case DESTINATION_MSUB:
    3743             :         case DESTINATION_MSUP:
    3744             :         case DESTINATION_MDEG:
    3745             :         case DESTINATION_MOMATH:
    3746        1035 :             m_aStates.top().nDestinationState = DESTINATION_MR;
    3747        1035 :             break;
    3748             :         case DESTINATION_REVISIONTABLE:
    3749           3 :             m_aStates.top().nDestinationState = DESTINATION_REVISIONENTRY;
    3750           3 :             break;
    3751             :         default:
    3752        5198 :             break;
    3753             :     }
    3754             : 
    3755        7395 :     return 0;
    3756             : }
    3757             : 
    3758         402 : RTFSprms RTFDocumentImpl::mergeSprms()
    3759             : {
    3760         402 :     RTFSprms aSprms;
    3761        1206 :     for (RTFSprms::Iterator_t i = m_aStates.top().aTableSprms.begin();
    3762         804 :             i != m_aStates.top().aTableSprms.end(); ++i)
    3763           0 :         aSprms.set(i->first, i->second);
    3764        4764 :     for (RTFSprms::Iterator_t i = m_aStates.top().aCharacterSprms.begin();
    3765        3176 :             i != m_aStates.top().aCharacterSprms.end(); ++i)
    3766        1186 :         aSprms.set(i->first, i->second);
    3767        3093 :     for (RTFSprms::Iterator_t i = m_aStates.top().aParagraphSprms.begin();
    3768        2062 :             i != m_aStates.top().aParagraphSprms.end(); ++i)
    3769         629 :         aSprms.set(i->first, i->second);
    3770         402 :     return aSprms;
    3771             : }
    3772             : 
    3773        1130 : void RTFDocumentImpl::resetSprms()
    3774             : {
    3775        1130 :     m_aStates.top().aTableSprms.clear();
    3776        1130 :     m_aStates.top().aCharacterSprms.clear();
    3777        1130 :     m_aStates.top().aParagraphSprms.clear();
    3778        1130 : }
    3779             : 
    3780         402 : RTFSprms RTFDocumentImpl::mergeAttributes()
    3781             : {
    3782         402 :     RTFSprms aAttributes;
    3783        6738 :     for (RTFSprms::Iterator_t i = m_aStates.top().aTableAttributes.begin();
    3784        4492 :             i != m_aStates.top().aTableAttributes.end(); ++i)
    3785        1844 :         aAttributes.set(i->first, i->second);
    3786        1374 :     for (RTFSprms::Iterator_t i = m_aStates.top().aCharacterAttributes.begin();
    3787         916 :             i != m_aStates.top().aCharacterAttributes.end(); ++i)
    3788          56 :         aAttributes.set(i->first, i->second);
    3789        1236 :     for (RTFSprms::Iterator_t i = m_aStates.top().aParagraphAttributes.begin();
    3790         824 :             i != m_aStates.top().aParagraphAttributes.end(); ++i)
    3791          10 :         aAttributes.set(i->first, i->second);
    3792         402 :     return aAttributes;
    3793             : }
    3794             : 
    3795        1130 : void RTFDocumentImpl::resetAttributes()
    3796             : {
    3797        1130 :     m_aStates.top().aTableAttributes.clear();
    3798        1130 :     m_aStates.top().aCharacterAttributes.clear();
    3799        1130 :     m_aStates.top().aParagraphAttributes.clear();
    3800        1130 : }
    3801             : 
    3802        7392 : int RTFDocumentImpl::popState()
    3803             : {
    3804             :     //SAL_INFO("writerfilter", OSL_THIS_FUNC << " before pop: m_pTokenizer->getGroup() " << m_pTokenizer->getGroup() <<
    3805             :     //                         ", dest state: " << m_aStates.top().nDestinationState);
    3806             : 
    3807        7392 :     checkUnicode(/*bUnicode =*/ true, /*bHex =*/ true);
    3808        7392 :     RTFParserState aState(m_aStates.top());
    3809        7392 :     m_bWasInFrame = aState.aFrame.inFrame();
    3810             : 
    3811        7392 :     switch (aState.nDestinationState)
    3812             :     {
    3813             :         case DESTINATION_FONTTABLE:
    3814             :             {
    3815          77 :                 writerfilter::Reference<Table>::Pointer_t const pTable(new RTFReferenceTable(m_aFontTableEntries));
    3816          77 :                 Mapper().table(NS_rtf::LN_FONTTABLE, pTable);
    3817             :             }
    3818          77 :             break;
    3819             :         case DESTINATION_STYLESHEET:
    3820             :             {
    3821          63 :                 writerfilter::Reference<Table>::Pointer_t const pTable(new RTFReferenceTable(m_aStyleTableEntries));
    3822          63 :                 Mapper().table(NS_rtf::LN_STYLESHEET, pTable);
    3823             :             }
    3824          63 :             break;
    3825             :         case DESTINATION_LISTOVERRIDETABLE:
    3826             :             {
    3827           9 :                 RTFSprms aListTableAttributes;
    3828          18 :                 writerfilter::Reference<Properties>::Pointer_t const pProp(new RTFReferenceProperties(aListTableAttributes, m_aListTableSprms));
    3829          18 :                 RTFReferenceTable::Entries_t aListTableEntries;
    3830           9 :                 aListTableEntries.insert(make_pair(0, pProp));
    3831          18 :                 writerfilter::Reference<Table>::Pointer_t const pTable(new RTFReferenceTable(aListTableEntries));
    3832          18 :                 Mapper().table(NS_rtf::LN_LISTTABLE, pTable);
    3833             :             }
    3834           9 :             break;
    3835             :         case DESTINATION_LISTENTRY:
    3836          41 :             for (RTFSprms::Iterator_t i = aState.aListLevelEntries.begin(); i != aState.aListLevelEntries.end(); ++i)
    3837          30 :                 aState.aTableSprms.set(i->first, i->second, false);
    3838          11 :             break;
    3839             :         case DESTINATION_FIELDINSTRUCTION:
    3840             :             {
    3841          10 :                 RTFValue::Pointer_t pValue(new RTFValue(m_aFormfieldAttributes, m_aFormfieldSprms));
    3842          20 :                 RTFSprms aFFAttributes;
    3843          20 :                 RTFSprms aFFSprms;
    3844          10 :                 aFFSprms.set(NS_ooxml::LN_ffdata, pValue);
    3845          20 :                 writerfilter::Reference<Properties>::Pointer_t const pProperties(new RTFReferenceProperties(aFFAttributes, aFFSprms));
    3846          10 :                 Mapper().props(pProperties);
    3847          10 :                 m_aFormfieldAttributes.clear();
    3848          10 :                 m_aFormfieldSprms.clear();
    3849          20 :                 singleChar(0x14);
    3850             :             }
    3851          10 :             break;
    3852             :         case DESTINATION_FIELDRESULT:
    3853           8 :             singleChar(0x15);
    3854           8 :             break;
    3855             :         case DESTINATION_LEVELTEXT:
    3856             :             {
    3857          32 :                 OUString aStr = m_aStates.top().aDestinationText.makeStringAndClear();
    3858             : 
    3859             :                 // The first character is the length of the string (the rest should be ignored).
    3860          32 :                 sal_Int32 nLength(aStr.toChar());
    3861          64 :                 OUString aValue;
    3862          32 :                 if (nLength <= aStr.getLength())
    3863          32 :                     aValue = aStr.copy(1, nLength);
    3864             :                 else
    3865           0 :                     aValue = aStr;
    3866          64 :                 RTFValue::Pointer_t pValue(new RTFValue(aValue, true));
    3867          64 :                 aState.aTableAttributes.set(NS_ooxml::LN_CT_LevelText_val, pValue);
    3868             :             }
    3869          32 :             break;
    3870             :         case DESTINATION_LEVELNUMBERS:
    3871          33 :             if (aState.aTableSprms.find(NS_ooxml::LN_CT_Lvl_lvlText))
    3872             :             {
    3873          32 :                 RTFSprms& rAttributes = aState.aTableSprms.find(NS_ooxml::LN_CT_Lvl_lvlText)->getAttributes();
    3874          32 :                 RTFValue::Pointer_t pValue = rAttributes.find(NS_ooxml::LN_CT_LevelText_val);
    3875          64 :                 OUString aOrig = pValue->getString();
    3876             : 
    3877          64 :                 OUStringBuffer aBuf;
    3878          32 :                 sal_Int32 nReplaces = 1;
    3879          79 :                 for (int i = 0; i < aOrig.getLength(); i++)
    3880             :                 {
    3881         188 :                     if (std::find(aState.aLevelNumbers.begin(), aState.aLevelNumbers.end(), i+1)
    3882         188 :                             != aState.aLevelNumbers.end())
    3883             :                     {
    3884          23 :                         aBuf.append(sal_Unicode('%'));
    3885             :                         // '1.1.1' -> '%1.%2.%3', but '1.' (with '2.' prefix omitted) is %2.
    3886          23 :                         aBuf.append(sal_Int32(nReplaces++ + aState.nListLevelNum + 1 - aState.aLevelNumbers.size()));
    3887             :                     }
    3888             :                     else
    3889          24 :                         aBuf.append(aOrig.copy(i, 1));
    3890             :                 }
    3891             : 
    3892          64 :                 pValue->setString(aBuf.makeStringAndClear());
    3893             :             }
    3894          33 :             break;
    3895             :         case DESTINATION_SHAPEPROPERTYNAME:
    3896         426 :             aState.aShape.aProperties.push_back(make_pair(m_aStates.top().aDestinationText.makeStringAndClear(), OUString()));
    3897         426 :             break;
    3898             :         case DESTINATION_SHAPEPROPERTYVALUE:
    3899         426 :             if (aState.aShape.aProperties.size())
    3900             :             {
    3901         425 :                 aState.aShape.aProperties.back().second = m_aStates.top().aDestinationText.makeStringAndClear();
    3902         425 :                 if (m_aStates.top().bHadShapeText)
    3903           8 :                     m_pSdrImport->append(aState.aShape.aProperties.back().first, aState.aShape.aProperties.back().second);
    3904             :             }
    3905         426 :             break;
    3906             :         case DESTINATION_PICPROP:
    3907             :         case DESTINATION_SHAPEINSTRUCTION:
    3908          47 :             if (!m_bObject && !aState.bInListpicture && !m_aStates.top().bHadShapeText && !m_aStates.top().bInShapeGroup)
    3909          25 :                 m_pSdrImport->resolve(m_aStates.top().aShape, true);
    3910          47 :             break;
    3911             :         case DESTINATION_BOOKMARKSTART:
    3912             :             {
    3913           2 :                 OUString aStr = m_aStates.top().aDestinationText.makeStringAndClear();
    3914           2 :                 int nPos = m_aBookmarks.size();
    3915           2 :                 m_aBookmarks[aStr] = nPos;
    3916           2 :                 Mapper().props(lcl_getBookmarkProperties(nPos, aStr));
    3917             :             }
    3918           2 :             break;
    3919             :         case DESTINATION_BOOKMARKEND:
    3920           2 :             Mapper().props(lcl_getBookmarkProperties(m_aBookmarks[m_aStates.top().aDestinationText.makeStringAndClear()]));
    3921           2 :             break;
    3922             :         case DESTINATION_PICT:
    3923          11 :             resolvePict(true);
    3924          11 :             break;
    3925             :         case DESTINATION_FORMFIELDNAME:
    3926             :             {
    3927           0 :                 RTFValue::Pointer_t pValue(new RTFValue(m_aStates.top().aDestinationText.makeStringAndClear()));
    3928           0 :                 m_aFormfieldSprms.set(NS_ooxml::LN_CT_FFData_name, pValue);
    3929             :             }
    3930           0 :             break;
    3931             :         case DESTINATION_FORMFIELDLIST:
    3932             :             {
    3933           0 :                 RTFValue::Pointer_t pValue(new RTFValue(m_aStates.top().aDestinationText.makeStringAndClear()));
    3934           0 :                 m_aFormfieldSprms.set(NS_ooxml::LN_CT_FFDDList_listEntry, pValue);
    3935             :             }
    3936           0 :             break;
    3937             :         case DESTINATION_DATAFIELD:
    3938             :             {
    3939           0 :                 OString aStr = OUStringToOString(m_aStates.top().aDestinationText.makeStringAndClear(), aState.nCurrentEncoding);
    3940             :                 // decode hex dump
    3941           0 :                 OStringBuffer aBuf;
    3942           0 :                 const char *str = aStr.getStr();
    3943           0 :                 int b = 0, count = 2;
    3944           0 :                 for (int i = 0; i < aStr.getLength(); ++i)
    3945             :                 {
    3946           0 :                     char ch = str[i];
    3947           0 :                     if (ch != 0x0d && ch != 0x0a)
    3948             :                     {
    3949           0 :                         b = b << 4;
    3950           0 :                         sal_Int8 parsed = m_pTokenizer->asHex(ch);
    3951           0 :                         if (parsed == -1)
    3952           0 :                             return ERROR_HEX_INVALID;
    3953           0 :                         b += parsed;
    3954           0 :                         count--;
    3955           0 :                         if (!count)
    3956             :                         {
    3957           0 :                             aBuf.append((char)b);
    3958           0 :                             count = 2;
    3959           0 :                             b = 0;
    3960             :                         }
    3961             :                     }
    3962             :                 }
    3963           0 :                 aStr = aBuf.makeStringAndClear();
    3964             :                 // ignore the first bytes
    3965           0 :                 if (aStr.getLength() > 8)
    3966           0 :                     aStr = aStr.copy(8);
    3967             :                 // extract name
    3968           0 :                 int nLength = aStr.toChar();
    3969           0 :                 aStr = aStr.copy(1);
    3970           0 :                 OString aName = aStr.copy(0, nLength);
    3971           0 :                 aStr = aStr.copy(nLength+1); // zero-terminated string
    3972             :                 // extract default text
    3973           0 :                 nLength = aStr.toChar();
    3974           0 :                 aStr = aStr.copy(1);
    3975           0 :                 RTFValue::Pointer_t pNValue(new RTFValue(OStringToOUString(aName, aState.nCurrentEncoding)));
    3976           0 :                 m_aFormfieldSprms.set(NS_ooxml::LN_CT_FFData_name, pNValue);
    3977           0 :                 if (nLength > 0)
    3978             :                 {
    3979           0 :                     OString aDefaultText = aStr.copy(0, nLength);
    3980           0 :                     RTFValue::Pointer_t pDValue(new RTFValue(OStringToOUString(aDefaultText, aState.nCurrentEncoding)));
    3981           0 :                     m_aFormfieldSprms.set(NS_ooxml::LN_CT_FFTextInput_default, pDValue);
    3982             :                 }
    3983             : 
    3984           0 :                 m_bFormField = false;
    3985             :             }
    3986           0 :             break;
    3987             :         case DESTINATION_CREATIONTIME:
    3988          47 :             if (m_xDocumentProperties.is())
    3989          45 :                 m_xDocumentProperties->setCreationDate(lcl_getDateTime(aState));
    3990          47 :             break;
    3991             :         case DESTINATION_REVISIONTIME:
    3992          47 :             if (m_xDocumentProperties.is())
    3993          45 :                 m_xDocumentProperties->setModificationDate(lcl_getDateTime(aState));
    3994          47 :             break;
    3995             :         case DESTINATION_PRINTTIME:
    3996          45 :             if (m_xDocumentProperties.is())
    3997          44 :                 m_xDocumentProperties->setPrintDate(lcl_getDateTime(aState));
    3998          45 :             break;
    3999             :         case DESTINATION_AUTHOR:
    4000          11 :             if (m_xDocumentProperties.is())
    4001           9 :                 m_xDocumentProperties->setAuthor(m_aStates.top().aDestinationText.makeStringAndClear());
    4002          11 :             break;
    4003             :         case DESTINATION_KEYWORDS:
    4004           2 :             if (m_xDocumentProperties.is())
    4005           2 :                 m_xDocumentProperties->setKeywords(comphelper::string::convertCommaSeparated(m_aStates.top().aDestinationText.makeStringAndClear()));
    4006           2 :             break;
    4007             :         case DESTINATION_COMMENT:
    4008          87 :             if (m_xDocumentProperties.is())
    4009          85 :                 m_xDocumentProperties->setGenerator(m_aStates.top().aDestinationText.makeStringAndClear());
    4010          87 :             break;
    4011             :         case DESTINATION_SUBJECT:
    4012           3 :             if (m_xDocumentProperties.is())
    4013           3 :                 m_xDocumentProperties->setSubject(m_aStates.top().aDestinationText.makeStringAndClear());
    4014           3 :             break;
    4015             :         case DESTINATION_DOCCOMM:
    4016           4 :             if (m_xDocumentProperties.is())
    4017           4 :                 m_xDocumentProperties->setDescription(m_aStates.top().aDestinationText.makeStringAndClear());
    4018           4 :             break;
    4019             :         case DESTINATION_OPERATOR:
    4020             :         case DESTINATION_COMPANY:
    4021             :             {
    4022           8 :                 OUString aName = aState.nDestinationState == DESTINATION_OPERATOR ? OUString("Operator") : OUString("Company");
    4023           8 :                 if (m_xDocumentProperties.is())
    4024             :                 {
    4025           4 :                     uno::Reference<beans::XPropertyContainer> xUserDefinedProperties = m_xDocumentProperties->getUserDefinedProperties();
    4026           4 :                     xUserDefinedProperties->addProperty(aName, beans::PropertyAttribute::REMOVABLE,
    4027           4 :                             uno::makeAny(m_aStates.top().aDestinationText.makeStringAndClear()));
    4028           8 :                 }
    4029             :             }
    4030           8 :             break;
    4031             :         case DESTINATION_OBJDATA:
    4032             :             {
    4033           0 :                 m_pObjectData.reset(new SvMemoryStream());
    4034           0 :                 int b = 0, count = 2;
    4035             : 
    4036             :                 // Feed the destination text to a stream.
    4037           0 :                 OString aStr = OUStringToOString(m_aStates.top().aDestinationText.makeStringAndClear(), RTL_TEXTENCODING_ASCII_US);
    4038           0 :                 const char *str = aStr.getStr();
    4039           0 :                 for (int i = 0; i < aStr.getLength(); ++i)
    4040             :                 {
    4041           0 :                     char ch = str[i];
    4042           0 :                     if (ch != 0x0d && ch != 0x0a)
    4043             :                     {
    4044           0 :                         b = b << 4;
    4045           0 :                         sal_Int8 parsed = m_pTokenizer->asHex(ch);
    4046           0 :                         if (parsed == -1)
    4047           0 :                             return ERROR_HEX_INVALID;
    4048           0 :                         b += parsed;
    4049           0 :                         count--;
    4050           0 :                         if (!count)
    4051             :                         {
    4052           0 :                             *m_pObjectData << (char)b;
    4053           0 :                             count = 2;
    4054           0 :                             b = 0;
    4055             :                         }
    4056             :                     }
    4057             :                 }
    4058             : 
    4059           0 :                 if (m_pObjectData->Tell())
    4060             :                 {
    4061           0 :                     m_pObjectData->Seek(0);
    4062             : 
    4063             :                     // Skip ObjectHeader
    4064             :                     sal_uInt32 nData;
    4065           0 :                     *m_pObjectData >> nData; // OLEVersion
    4066           0 :                     *m_pObjectData >> nData; // FormatID
    4067           0 :                     *m_pObjectData >> nData; // ClassName
    4068           0 :                     m_pObjectData->SeekRel(nData);
    4069           0 :                     *m_pObjectData >> nData; // TopicName
    4070           0 :                     m_pObjectData->SeekRel(nData);
    4071           0 :                     *m_pObjectData >> nData; // ItemName
    4072           0 :                     m_pObjectData->SeekRel(nData);
    4073           0 :                     *m_pObjectData >> nData; // NativeDataSize
    4074             :                 }
    4075             : 
    4076           0 :                 uno::Reference<io::XInputStream> xInputStream(new utl::OInputStreamWrapper(m_pObjectData.get()));
    4077           0 :                 RTFValue::Pointer_t pStreamValue(new RTFValue(xInputStream));
    4078             : 
    4079           0 :                 RTFSprms aOLEAttributes;
    4080           0 :                 aOLEAttributes.set(NS_ooxml::LN_inputstream, pStreamValue);
    4081           0 :                 RTFValue::Pointer_t pValue(new RTFValue(aOLEAttributes));
    4082           0 :                 m_aObjectSprms.set(NS_ooxml::LN_OLEObject_OLEObject, pValue);
    4083             :             }
    4084           0 :             break;
    4085             :         case DESTINATION_OBJECT:
    4086             :             {
    4087           1 :                 if (!m_bObject)
    4088             :                 {
    4089             :                     // if the object is in a special container we will use the \result
    4090             :                     // element instead of the \objdata
    4091             :                     // (see RTF_OBJECT in RTFDocumentImpl::dispatchDestination)
    4092           1 :                     break;
    4093             :                 }
    4094             : 
    4095           0 :                 RTFSprms aObjAttributes;
    4096           0 :                 RTFSprms aObjSprms;
    4097           0 :                 RTFValue::Pointer_t pValue(new RTFValue(m_aObjectAttributes, m_aObjectSprms));
    4098           0 :                 aObjSprms.set(NS_ooxml::LN_object, pValue);
    4099           0 :                 writerfilter::Reference<Properties>::Pointer_t const pProperties(new RTFReferenceProperties(aObjAttributes, aObjSprms));
    4100           0 :                 uno::Reference<drawing::XShape> xShape;
    4101           0 :                 RTFValue::Pointer_t pShape = m_aObjectAttributes.find(NS_ooxml::LN_shape);
    4102             :                 OSL_ASSERT(pShape.get());
    4103           0 :                 if (pShape.get())
    4104           0 :                     pShape->getAny() >>= xShape;
    4105           0 :                 Mapper().startShape(xShape);
    4106           0 :                 Mapper().props(pProperties);
    4107           0 :                 Mapper().endShape();
    4108           0 :                 m_aObjectAttributes.clear();
    4109           0 :                 m_aObjectSprms.clear();
    4110           0 :                 m_bObject = false;
    4111             :             }
    4112           0 :             break;
    4113             :         case DESTINATION_ANNOTATIONDATE:
    4114             :             {
    4115           2 :                 OUString aStr(OStringToOUString(lcl_DTTM22OString(m_aStates.top().aDestinationText.makeStringAndClear().toInt32()),
    4116           4 :                             aState.nCurrentEncoding));
    4117           4 :                 RTFValue::Pointer_t pValue(new RTFValue(aStr));
    4118           4 :                 RTFSprms aAnnAttributes;
    4119           2 :                 aAnnAttributes.set(NS_ooxml::LN_CT_TrackChange_date, pValue);
    4120           4 :                 writerfilter::Reference<Properties>::Pointer_t const pProperties(new RTFReferenceProperties(aAnnAttributes));
    4121           4 :                 Mapper().props(pProperties);
    4122             :             }
    4123           2 :             break;
    4124             :         case DESTINATION_ANNOTATIONAUTHOR:
    4125           2 :             m_aAuthor = m_aStates.top().aDestinationText.makeStringAndClear();
    4126           2 :             break;
    4127             :         case DESTINATION_ATNID:
    4128           2 :             m_aAuthorInitials = m_aStates.top().aDestinationText.makeStringAndClear();
    4129           2 :             break;
    4130             :         case DESTINATION_FALT:
    4131             :             {
    4132         153 :                 OUString aStr(m_aStates.top().aDestinationText.makeStringAndClear());
    4133         306 :                 RTFValue::Pointer_t pValue(new RTFValue(aStr));
    4134         306 :                 aState.aTableSprms.set(NS_ooxml::LN_CT_Font_altName, pValue);
    4135             :             }
    4136         153 :             break;
    4137             :         case DESTINATION_DRAWINGOBJECT:
    4138          18 :             if (m_aStates.top().aDrawingObject.xShape.is())
    4139             :             {
    4140          18 :                 RTFDrawingObject& rDrawing = m_aStates.top().aDrawingObject;
    4141          18 :                 uno::Reference<drawing::XShape> xShape(rDrawing.xShape);
    4142          36 :                 uno::Reference<beans::XPropertySet> xPropertySet(rDrawing.xPropertySet);
    4143             : 
    4144          36 :                 uno::Reference<lang::XServiceInfo> xServiceInfo(xShape, uno::UNO_QUERY);
    4145          18 :                 bool bTextFrame = xServiceInfo->supportsService("com.sun.star.text.TextFrame");
    4146             : 
    4147          18 :                 if (bTextFrame)
    4148             :                 {
    4149           7 :                     xPropertySet->setPropertyValue("HoriOrientPosition", uno::makeAny((sal_Int32)rDrawing.nLeft));
    4150           7 :                     xPropertySet->setPropertyValue("VertOrientPosition", uno::makeAny((sal_Int32)rDrawing.nTop));
    4151             :                 }
    4152             :                 else
    4153             :                 {
    4154          11 :                     xShape->setPosition(awt::Point(rDrawing.nLeft, rDrawing.nTop));
    4155             :                 }
    4156          18 :                 xShape->setSize(awt::Size(rDrawing.nRight, rDrawing.nBottom));
    4157             : 
    4158          18 :                 if (rDrawing.bHasLineColor)
    4159           7 :                     xPropertySet->setPropertyValue("LineColor", uno::makeAny(sal_uInt32((rDrawing.nLineColorR<<16) + (rDrawing.nLineColorG<<8) + rDrawing.nLineColorB)));
    4160          18 :                 if (rDrawing.bHasFillColor)
    4161           3 :                     xPropertySet->setPropertyValue("FillColor", uno::makeAny(sal_uInt32((rDrawing.nFillColorR<<16) + (rDrawing.nFillColorG<<8) + rDrawing.nFillColorB)));
    4162          15 :                 else if (!bTextFrame)
    4163             :                     // If there is no fill, the Word default is 100% transparency.
    4164           8 :                     xPropertySet->setPropertyValue("FillTransparence", uno::makeAny(sal_Int32(100)));
    4165             : 
    4166          18 :                 m_pSdrImport->resolveFLine(xPropertySet, rDrawing.nFLine);
    4167             : 
    4168          18 :                 if (!m_aStates.top().aDrawingObject.bHadShapeText)
    4169             :                 {
    4170          11 :                     Mapper().startShape(xShape);
    4171             :                 }
    4172          36 :                 Mapper().endShape();
    4173             :             }
    4174          18 :             break;
    4175             :         case DESTINATION_SHAPE:
    4176          43 :             m_bNeedCr = m_bNeedCrOrig;
    4177          43 :             if (aState.aFrame.inFrame())
    4178             :             {
    4179             :                 // parBreak modify m_aStates.top() so we can't apply resetFrame directly on aState
    4180           2 :                 m_aStates.top().resetFrame();
    4181           2 :                 parBreak();
    4182             :                 // Save this state for later use, so we only reset frame status only for the first shape inside a frame.
    4183           2 :                 aState = m_aStates.top();
    4184           2 :                 m_bNeedPap = true;
    4185             :             }
    4186          43 :             break;
    4187             :         case DESTINATION_MOMATH:
    4188             :             {
    4189          61 :                 m_aMathBuffer.appendClosingTag(M_TOKEN(oMath));
    4190             : 
    4191          61 :                 SvGlobalName aGlobalName(SO3_SM_CLASSID);
    4192         122 :                 comphelper::EmbeddedObjectContainer aContainer;
    4193         122 :                 OUString aName;
    4194         122 :                 uno::Reference<embed::XEmbeddedObject> xObject = aContainer.CreateEmbeddedObject(aGlobalName.GetByteSequence(), aName);
    4195         122 :                 uno::Reference<util::XCloseable> xComponent(xObject->getComponent(), uno::UNO_QUERY);
    4196             :                 // gcc4.4 (and 4.3 and possibly older) have a problem with dynamic_cast directly to the target class,
    4197             :                 // so help it with an intermediate cast. I'm not sure what exactly the problem is, seems to be unrelated
    4198             :                 // to RTLD_GLOBAL, so most probably a gcc bug.
    4199          61 :                 oox::FormulaImportBase* pImport = dynamic_cast<oox::FormulaImportBase*>(dynamic_cast<SfxBaseModel*>(xComponent.get()));
    4200             :                 assert( pImport != NULL );
    4201          61 :                 pImport->readFormulaOoxml(m_aMathBuffer);
    4202         122 :                 RTFValue::Pointer_t pValue(new RTFValue(xObject));
    4203         122 :                 RTFSprms aMathAttributes;
    4204          61 :                 aMathAttributes.set(NS_ooxml::LN_starmath, pValue);
    4205         122 :                 writerfilter::Reference<Properties>::Pointer_t const pProperties(new RTFReferenceProperties(aMathAttributes));
    4206          61 :                 Mapper().props(pProperties);
    4207         122 :                 m_aMathBuffer = oox::formulaimport::XmlStreamBuilder();
    4208             :             }
    4209          61 :             break;
    4210             :         case DESTINATION_MR:
    4211        1051 :             lcl_DestinationToMath(m_aStates.top().aDestinationText, m_aMathBuffer, m_bMathNor);
    4212        1051 :             break;
    4213             :         case DESTINATION_MF:
    4214          34 :             m_aMathBuffer.appendClosingTag(M_TOKEN(f));
    4215          34 :             break;
    4216             :         case DESTINATION_MFPR:
    4217          20 :             m_aMathBuffer.appendClosingTag(M_TOKEN(fPr));
    4218          20 :             break;
    4219             :         case DESTINATION_MCTRLPR:
    4220         108 :             m_aMathBuffer.appendClosingTag(M_TOKEN(ctrlPr));
    4221         108 :             break;
    4222             :         case DESTINATION_MNUM:
    4223          34 :             m_aMathBuffer.appendClosingTag(M_TOKEN(num));
    4224          34 :             break;
    4225             :         case DESTINATION_MDEN:
    4226          34 :             m_aMathBuffer.appendClosingTag(M_TOKEN(den));
    4227          34 :             break;
    4228             :         case DESTINATION_MACC:
    4229          24 :             m_aMathBuffer.appendClosingTag(M_TOKEN(acc));
    4230          24 :             break;
    4231             :         case DESTINATION_MACCPR:
    4232          24 :             m_aMathBuffer.appendClosingTag(M_TOKEN(accPr));
    4233          24 :             break;
    4234             :         case DESTINATION_MCHR:
    4235             :         case DESTINATION_MPOS:
    4236             :         case DESTINATION_MVERTJC:
    4237             :         case DESTINATION_MSTRIKEH:
    4238             :         case DESTINATION_MDEGHIDE:
    4239             :         case DESTINATION_MBEGCHR:
    4240             :         case DESTINATION_MSEPCHR:
    4241             :         case DESTINATION_MENDCHR:
    4242             :         case DESTINATION_MSUBHIDE:
    4243             :         case DESTINATION_MSUPHIDE:
    4244             :         case DESTINATION_MTYPE:
    4245             :         case DESTINATION_MGROW:
    4246             :             {
    4247         134 :                 sal_Int32 nMathToken = 0;
    4248         134 :                 switch (aState.nDestinationState)
    4249             :                 {
    4250             :                     case DESTINATION_MCHR:
    4251          42 :                         nMathToken = M_TOKEN(chr);
    4252          42 :                         break;
    4253             :                     case DESTINATION_MPOS:
    4254           4 :                         nMathToken = M_TOKEN(pos);
    4255           4 :                         break;
    4256             :                     case DESTINATION_MVERTJC:
    4257           3 :                         nMathToken = M_TOKEN(vertJc);
    4258           3 :                         break;
    4259             :                     case DESTINATION_MSTRIKEH:
    4260           2 :                         nMathToken = M_TOKEN(strikeH);
    4261           2 :                         break;
    4262             :                     case DESTINATION_MDEGHIDE:
    4263           4 :                         nMathToken = M_TOKEN(degHide);
    4264           4 :                         break;
    4265             :                     case DESTINATION_MBEGCHR:
    4266          32 :                         nMathToken = M_TOKEN(begChr);
    4267          32 :                         break;
    4268             :                     case DESTINATION_MSEPCHR:
    4269           3 :                         nMathToken = M_TOKEN(sepChr);
    4270           3 :                         break;
    4271             :                     case DESTINATION_MENDCHR:
    4272          32 :                         nMathToken = M_TOKEN(endChr);
    4273          32 :                         break;
    4274             :                     case DESTINATION_MSUBHIDE:
    4275           2 :                         nMathToken = M_TOKEN(subHide);
    4276           2 :                         break;
    4277             :                     case DESTINATION_MSUPHIDE:
    4278           2 :                         nMathToken = M_TOKEN(supHide);
    4279           2 :                         break;
    4280             :                     case DESTINATION_MTYPE:
    4281           6 :                         nMathToken = M_TOKEN(type);
    4282           6 :                         break;
    4283             :                     case DESTINATION_MGROW:
    4284           2 :                         nMathToken = M_TOKEN(grow);
    4285           2 :                         break;
    4286             :                     default:
    4287           0 :                         break;
    4288             :                 }
    4289             : 
    4290         134 :                 oox::formulaimport::XmlStream::AttributeList aAttribs;
    4291         134 :                 aAttribs[M_TOKEN(val)] = m_aStates.top().aDestinationText.makeStringAndClear();
    4292         134 :                 m_aMathBuffer.appendOpeningTag(nMathToken, aAttribs);
    4293         134 :                 m_aMathBuffer.appendClosingTag(nMathToken);
    4294             :             }
    4295         134 :             break;
    4296             :         case DESTINATION_ME:
    4297         201 :             m_aMathBuffer.appendClosingTag(M_TOKEN(e));
    4298         201 :             break;
    4299             :         case DESTINATION_MBAR:
    4300           2 :             m_aMathBuffer.appendClosingTag(M_TOKEN(bar));
    4301           2 :             break;
    4302             :         case DESTINATION_MBARPR:
    4303           2 :             m_aMathBuffer.appendClosingTag(M_TOKEN(barPr));
    4304           2 :             break;
    4305             :         case DESTINATION_MD:
    4306          45 :             m_aMathBuffer.appendClosingTag(M_TOKEN(d));
    4307          45 :             break;
    4308             :         case DESTINATION_MDPR:
    4309          45 :             m_aMathBuffer.appendClosingTag(M_TOKEN(dPr));
    4310          45 :             break;
    4311             :         case DESTINATION_MFUNC:
    4312          12 :             m_aMathBuffer.appendClosingTag(M_TOKEN(func));
    4313          12 :             break;
    4314             :         case DESTINATION_MFUNCPR:
    4315          11 :             m_aMathBuffer.appendClosingTag(M_TOKEN(funcPr));
    4316          11 :             break;
    4317             :         case DESTINATION_MFNAME:
    4318          12 :             m_aMathBuffer.appendClosingTag(M_TOKEN(fName));
    4319          12 :             break;
    4320             :         case DESTINATION_MLIMLOW:
    4321           6 :             m_aMathBuffer.appendClosingTag(M_TOKEN(limLow));
    4322           6 :             break;
    4323             :         case DESTINATION_MLIMLOWPR:
    4324           3 :             m_aMathBuffer.appendClosingTag(M_TOKEN(limLowPr));
    4325           3 :             break;
    4326             :         case DESTINATION_MLIM:
    4327          10 :             m_aMathBuffer.appendClosingTag(M_TOKEN(lim));
    4328          10 :             break;
    4329             :         case DESTINATION_MM:
    4330           2 :             m_aMathBuffer.appendClosingTag(M_TOKEN(m));
    4331           2 :             break;
    4332             :         case DESTINATION_MMPR:
    4333           1 :             m_aMathBuffer.appendClosingTag(M_TOKEN(mPr));
    4334           1 :             break;
    4335             :         case DESTINATION_MMR:
    4336           4 :             m_aMathBuffer.appendClosingTag(M_TOKEN(mr));
    4337           4 :             break;
    4338             :         case DESTINATION_MNARY:
    4339          17 :             m_aMathBuffer.appendClosingTag(M_TOKEN(nary));
    4340          17 :             break;
    4341             :         case DESTINATION_MNARYPR:
    4342          17 :             m_aMathBuffer.appendClosingTag(M_TOKEN(naryPr));
    4343          17 :             break;
    4344             :         case DESTINATION_MSUB:
    4345          33 :             m_aMathBuffer.appendClosingTag(M_TOKEN(sub));
    4346          33 :             break;
    4347             :         case DESTINATION_MSUP:
    4348          59 :             m_aMathBuffer.appendClosingTag(M_TOKEN(sup));
    4349          59 :             break;
    4350             :         case DESTINATION_MLIMUPP:
    4351           4 :             m_aMathBuffer.appendClosingTag(M_TOKEN(limUpp));
    4352           4 :             break;
    4353             :         case DESTINATION_MLIMUPPPR:
    4354           2 :             m_aMathBuffer.appendClosingTag(M_TOKEN(limUppPr));
    4355           2 :             break;
    4356             :         case DESTINATION_MGROUPCHR:
    4357           4 :             m_aMathBuffer.appendClosingTag(M_TOKEN(groupChr));
    4358           4 :             break;
    4359             :         case DESTINATION_MGROUPCHRPR:
    4360           4 :             m_aMathBuffer.appendClosingTag(M_TOKEN(groupChrPr));
    4361           4 :             break;
    4362             :         case DESTINATION_MBORDERBOX:
    4363           2 :             m_aMathBuffer.appendClosingTag(M_TOKEN(borderBox));
    4364           2 :             break;
    4365             :         case DESTINATION_MBORDERBOXPR:
    4366           2 :             m_aMathBuffer.appendClosingTag(M_TOKEN(borderBoxPr));
    4367           2 :             break;
    4368             :         case DESTINATION_MRAD:
    4369           6 :             m_aMathBuffer.appendClosingTag(M_TOKEN(rad));
    4370           6 :             break;
    4371             :         case DESTINATION_MRADPR:
    4372           5 :             m_aMathBuffer.appendClosingTag(M_TOKEN(radPr));
    4373           5 :             break;
    4374             :         case DESTINATION_MDEG:
    4375           6 :             m_aMathBuffer.appendClosingTag(M_TOKEN(deg));
    4376           6 :             break;
    4377             :         case DESTINATION_MSSUB:
    4378           8 :             m_aMathBuffer.appendClosingTag(M_TOKEN(sSub));
    4379           8 :             break;
    4380             :         case DESTINATION_MSSUBPR:
    4381           4 :             m_aMathBuffer.appendClosingTag(M_TOKEN(sSubPr));
    4382           4 :             break;
    4383             :         case DESTINATION_MSSUP:
    4384          34 :             m_aMathBuffer.appendClosingTag(M_TOKEN(sSup));
    4385          34 :             break;
    4386             :         case DESTINATION_MSSUPPR:
    4387          17 :             m_aMathBuffer.appendClosingTag(M_TOKEN(sSupPr));
    4388          17 :             break;
    4389             :         case DESTINATION_MSSUBSUP:
    4390           4 :             m_aMathBuffer.appendClosingTag(M_TOKEN(sSubSup));
    4391           4 :             break;
    4392             :         case DESTINATION_MSSUBSUPPR:
    4393           2 :             m_aMathBuffer.appendClosingTag(M_TOKEN(sSubSupPr));
    4394           2 :             break;
    4395             :         case DESTINATION_MSPRE:
    4396           4 :             m_aMathBuffer.appendClosingTag(M_TOKEN(sPre));
    4397           4 :             break;
    4398             :         case DESTINATION_MSPREPR:
    4399           2 :             m_aMathBuffer.appendClosingTag(M_TOKEN(sPrePr));
    4400           2 :             break;
    4401             :         case DESTINATION_MBOX:
    4402           1 :             m_aMathBuffer.appendClosingTag(M_TOKEN(box));
    4403           1 :             break;
    4404             :         case DESTINATION_MEQARR:
    4405           6 :             m_aMathBuffer.appendClosingTag(M_TOKEN(eqArr));
    4406           6 :             break;
    4407             :         default:
    4408        3637 :             break;
    4409             :     }
    4410             : 
    4411             :     // See if we need to end a track change
    4412        7392 :     RTFValue::Pointer_t pTrackchange = aState.aCharacterSprms.find(NS_ooxml::LN_trackchange);
    4413        7392 :     if (pTrackchange.get())
    4414             :     {
    4415           0 :         RTFSprms aTCAttributes;
    4416           0 :         RTFValue::Pointer_t pValue(new RTFValue(0));
    4417           0 :         aTCAttributes.set(NS_ooxml::LN_endtrackchange, pValue);
    4418           0 :         writerfilter::Reference<Properties>::Pointer_t const pProperties(new RTFReferenceProperties(aTCAttributes));
    4419           0 :         Mapper().props(pProperties);
    4420             :     }
    4421             : 
    4422             :     // This is the end of the doc, see if we need to close the last section.
    4423        7392 :     if (m_pTokenizer->getGroup() == 1 && !m_bFirstRun)
    4424             :     {
    4425         199 :         if (m_bNeedCr)
    4426          15 :             dispatchSymbol(RTF_PAR);
    4427         199 :         sectBreak(true);
    4428             :     }
    4429             : 
    4430        7392 :     m_aStates.pop();
    4431             : 
    4432        7392 :     m_pTokenizer->popGroup();
    4433             : 
    4434             :     // list table
    4435        7392 :     switch (aState.nDestinationState)
    4436             :     {
    4437             :         case DESTINATION_LISTENTRY:
    4438             :             {
    4439          11 :                 RTFValue::Pointer_t pValue(new RTFValue(aState.aTableAttributes, aState.aTableSprms));
    4440          11 :                 m_aListTableSprms.set(NS_ooxml::LN_CT_Numbering_abstractNum, pValue, false);
    4441             :             }
    4442          11 :             break;
    4443             :         case DESTINATION_PARAGRAPHNUMBERING:
    4444             :             {
    4445           4 :                 RTFValue::Pointer_t pIdValue = aState.aTableAttributes.find(NS_rtf::LN_LSID);
    4446           4 :                 if (pIdValue.get())
    4447             :                 {
    4448             :                     // Abstract numbering
    4449           4 :                     RTFSprms aLeveltextAttributes;
    4450           8 :                     OUString aTextValue;
    4451           8 :                     RTFValue::Pointer_t pTextBefore = aState.aTableAttributes.find(NS_ooxml::LN_CT_LevelText_val);
    4452           4 :                     if (pTextBefore.get())
    4453           3 :                         aTextValue += pTextBefore->getString();
    4454           4 :                     aTextValue += "%1";
    4455           8 :                     RTFValue::Pointer_t pTextAfter = aState.aTableAttributes.find(NS_ooxml::LN_CT_LevelSuffix_val);
    4456           4 :                     if (pTextAfter.get())
    4457           3 :                         aTextValue += pTextAfter->getString();
    4458           8 :                     RTFValue::Pointer_t pTextValue(new RTFValue(aTextValue));
    4459           4 :                     aLeveltextAttributes.set(NS_ooxml::LN_CT_LevelText_val, pTextValue);
    4460             : 
    4461           8 :                     RTFSprms aLevelAttributes;
    4462           8 :                     RTFSprms aLevelSprms;
    4463           8 :                     RTFValue::Pointer_t pIlvlValue(new RTFValue(0));
    4464           4 :                     aLevelAttributes.set(NS_ooxml::LN_CT_Lvl_ilvl, pIlvlValue);
    4465             : 
    4466           8 :                     RTFValue::Pointer_t pNfcValue = aState.aTableSprms.find(NS_rtf::LN_NFC);
    4467           4 :                     if (pNfcValue.get())
    4468           4 :                         aLevelSprms.set(NS_rtf::LN_NFC, pNfcValue);
    4469             : 
    4470           8 :                     RTFValue::Pointer_t pStartatValue = aState.aTableSprms.find(NS_rtf::LN_ISTARTAT);
    4471           4 :                     if (pStartatValue.get())
    4472           4 :                         aLevelSprms.set(NS_rtf::LN_ISTARTAT, pStartatValue);
    4473             : 
    4474           8 :                     RTFValue::Pointer_t pLeveltextValue(new RTFValue(aLeveltextAttributes));
    4475           4 :                     aLevelSprms.set(NS_ooxml::LN_CT_Lvl_lvlText, pLeveltextValue);
    4476           8 :                     RTFValue::Pointer_t pRunProps = aState.aTableSprms.find(NS_ooxml::LN_CT_Lvl_rPr);
    4477           4 :                     if (pRunProps.get())
    4478           1 :                         aLevelSprms.set(NS_ooxml::LN_CT_Lvl_rPr, pRunProps);
    4479             : 
    4480           8 :                     RTFSprms aAbstractAttributes;
    4481           8 :                     RTFSprms aAbstractSprms;
    4482           4 :                     aAbstractAttributes.set(NS_ooxml::LN_CT_AbstractNum_abstractNumId, pIdValue);
    4483           8 :                     RTFValue::Pointer_t pLevelValue(new RTFValue(aLevelAttributes, aLevelSprms));
    4484           4 :                     aAbstractSprms.set(NS_ooxml::LN_CT_AbstractNum_lvl, pLevelValue, false);
    4485             : 
    4486           8 :                     RTFSprms aListTableSprms;
    4487           8 :                     RTFValue::Pointer_t pAbstractValue(new RTFValue(aAbstractAttributes, aAbstractSprms));
    4488             :                     // It's important that Numbering_abstractNum and Numbering_num never overwrites previous values.
    4489           4 :                     aListTableSprms.set(NS_ooxml::LN_CT_Numbering_abstractNum, pAbstractValue, false);
    4490             : 
    4491             :                     // Numbering
    4492           8 :                     RTFSprms aNumberingAttributes;
    4493           8 :                     RTFSprms aNumberingSprms;
    4494           4 :                     aNumberingAttributes.set(NS_rtf::LN_LSID, pIdValue);
    4495           4 :                     aNumberingSprms.set(NS_ooxml::LN_CT_Num_abstractNumId, pIdValue);
    4496           8 :                     RTFValue::Pointer_t pNumberingValue(new RTFValue(aNumberingAttributes, aNumberingSprms));
    4497           4 :                     aListTableSprms.set(NS_ooxml::LN_CT_Numbering_num, pNumberingValue, false);
    4498             : 
    4499             :                     // Table
    4500           8 :                     RTFSprms aListTableAttributes;
    4501           8 :                     writerfilter::Reference<Properties>::Pointer_t const pProp(new RTFReferenceProperties(aListTableAttributes, aListTableSprms));
    4502             : 
    4503           8 :                     RTFReferenceTable::Entries_t aListTableEntries;
    4504           4 :                     aListTableEntries.insert(make_pair(0, pProp));
    4505           8 :                     writerfilter::Reference<Table>::Pointer_t const pTable(new RTFReferenceTable(aListTableEntries));
    4506           4 :                     Mapper().table(NS_rtf::LN_LISTTABLE, pTable);
    4507             : 
    4508             :                     // Use it
    4509           4 :                     lcl_putNestedSprm(m_aStates.top().aParagraphSprms, NS_ooxml::LN_CT_PPrBase_numPr, NS_sprm::LN_PIlvl, pIlvlValue);
    4510           8 :                     lcl_putNestedSprm(m_aStates.top().aParagraphSprms, NS_ooxml::LN_CT_PPrBase_tabs, NS_sprm::LN_PIlfo, pIdValue);
    4511           4 :                 }
    4512             :             }
    4513           4 :             break;
    4514             :         case DESTINATION_PARAGRAPHNUMBERING_TEXTAFTER:
    4515             :             {
    4516           3 :                 RTFValue::Pointer_t pValue(new RTFValue(aState.aDestinationText.makeStringAndClear(), true));
    4517           3 :                 m_aStates.top().aTableAttributes.set(NS_ooxml::LN_CT_LevelSuffix_val, pValue);
    4518             :             }
    4519           3 :             break;
    4520             :         case DESTINATION_PARAGRAPHNUMBERING_TEXTBEFORE:
    4521             :             {
    4522           3 :                 RTFValue::Pointer_t pValue(new RTFValue(aState.aDestinationText.makeStringAndClear(), true));
    4523           3 :                 m_aStates.top().aTableAttributes.set(NS_ooxml::LN_CT_LevelText_val, pValue);
    4524             :             }
    4525           3 :             break;
    4526             :         case DESTINATION_LISTLEVEL:
    4527             :             {
    4528          31 :                 RTFValue::Pointer_t pInnerValue(new RTFValue(m_aStates.top().nListLevelNum++));
    4529          31 :                 aState.aTableAttributes.set(NS_ooxml::LN_CT_Lvl_ilvl, pInnerValue);
    4530             : 
    4531          62 :                 RTFValue::Pointer_t pValue(new RTFValue(aState.aTableAttributes, aState.aTableSprms));
    4532          31 :                 if (m_aStates.top().nDestinationState != DESTINATION_LFOLEVEL)
    4533          30 :                     m_aStates.top().aListLevelEntries.set(NS_ooxml::LN_CT_AbstractNum_lvl, pValue, false);
    4534             :                 else
    4535          32 :                     m_aStates.top().aTableSprms.set(NS_ooxml::LN_CT_NumLvl_lvl, pValue);
    4536             :             }
    4537          31 :             break;
    4538             :         case DESTINATION_LFOLEVEL:
    4539             :             {
    4540           1 :                 RTFValue::Pointer_t pInnerValue(new RTFValue(m_aStates.top().nListLevelNum++));
    4541           1 :                 aState.aTableAttributes.set(NS_ooxml::LN_CT_NumLvl_ilvl, pInnerValue);
    4542             : 
    4543           2 :                 RTFValue::Pointer_t pValue(new RTFValue(aState.aTableAttributes, aState.aTableSprms));
    4544           2 :                 m_aStates.top().aTableSprms.set(NS_ooxml::LN_CT_Num_lvlOverride, pValue);
    4545             :             }
    4546           1 :             break;
    4547             :             // list override table
    4548             :         case DESTINATION_LISTOVERRIDEENTRY:
    4549             :             {
    4550          10 :                 RTFValue::Pointer_t pValue(new RTFValue(aState.aTableAttributes, aState.aTableSprms));
    4551          10 :                 m_aListTableSprms.set(NS_ooxml::LN_CT_Numbering_num, pValue, false);
    4552             :             }
    4553          10 :             break;
    4554             :         case DESTINATION_LEVELTEXT:
    4555             :             {
    4556          32 :                 RTFValue::Pointer_t pValue(new RTFValue(aState.aTableAttributes));
    4557          32 :                 m_aStates.top().aTableSprms.set(NS_ooxml::LN_CT_Lvl_lvlText, pValue);
    4558             :             }
    4559          32 :             break;
    4560             :         case DESTINATION_LEVELNUMBERS:
    4561          33 :             m_aStates.top().aTableSprms = aState.aTableSprms;
    4562          33 :             break;
    4563             :         case DESTINATION_FIELDINSTRUCTION:
    4564          10 :             m_aStates.top().nFieldStatus = FIELD_INSTRUCTION;
    4565          10 :             break;
    4566             :         case DESTINATION_FIELDRESULT:
    4567           8 :             m_aStates.top().nFieldStatus = FIELD_RESULT;
    4568           8 :             break;
    4569             :         case DESTINATION_FIELD:
    4570          11 :             if (aState.nFieldStatus == FIELD_INSTRUCTION)
    4571           2 :                 singleChar(0x15);
    4572          11 :             break;
    4573             :         case DESTINATION_SHAPEPROPERTYVALUEPICT:
    4574             :             {
    4575           4 :                 m_aStates.top().aPicture = aState.aPicture;
    4576           4 :                 m_aStates.top().aDestinationText = aState.aDestinationText;
    4577             :             }
    4578           4 :             break;
    4579             :         case DESTINATION_FALT:
    4580         153 :             m_aStates.top().aTableSprms = aState.aTableSprms;
    4581         153 :             break;
    4582             :         case DESTINATION_SHAPEPROPERTYNAME:
    4583             :         case DESTINATION_SHAPEPROPERTYVALUE:
    4584             :         case DESTINATION_SHAPEPROPERTY:
    4585             :             {
    4586        1278 :                 m_aStates.top().aShape = aState.aShape;
    4587        1278 :                 m_aStates.top().aPicture = aState.aPicture;
    4588        1278 :                 m_aStates.top().aCharacterAttributes = aState.aCharacterAttributes;
    4589             :             }
    4590        1278 :             break;
    4591             :         case DESTINATION_FLYMAINCONTENT:
    4592             :         case DESTINATION_SHPPICT:
    4593             :         case DESTINATION_SHAPE:
    4594          51 :             m_aStates.top().aFrame = aState.aFrame;
    4595          51 :             if (aState.nDestinationState == DESTINATION_SHPPICT && !m_aStates.empty() && m_aStates.top().nDestinationState == DESTINATION_LISTPICTURE)
    4596             :             {
    4597           2 :                 RTFSprms aAttributes;
    4598           2 :                 aAttributes.set(NS_ooxml::LN_CT_NumPicBullet_numPicBulletId, RTFValue::Pointer_t(new RTFValue(m_nListPictureId++)));
    4599           4 :                 RTFSprms aSprms;
    4600             :                 // Dummy value, real picture is already sent to dmapper.
    4601           2 :                 aSprms.set(NS_ooxml::LN_CT_NumPicBullet_pict, RTFValue::Pointer_t(new RTFValue(0)));
    4602           4 :                 RTFValue::Pointer_t pValue(new RTFValue(aAttributes, aSprms));
    4603           4 :                 m_aListTableSprms.set(NS_ooxml::LN_CT_Numbering_numPicBullet, pValue, false);
    4604             :             }
    4605          51 :             break;
    4606             :         case DESTINATION_TITLE:
    4607             :             {
    4608           9 :                 if (m_aStates.top().nDestinationState == DESTINATION_TITLE)
    4609             :                     // The parent is a title as well, just append what we have so far.
    4610           1 :                     m_aStates.top().aDestinationText.append(aState.aDestinationText.makeStringAndClear());
    4611           8 :                 else if (m_xDocumentProperties.is())
    4612           6 :                     m_xDocumentProperties->setTitle(aState.aDestinationText.makeStringAndClear());
    4613             :             }
    4614           9 :             break;
    4615             :         case DESTINATION_SHAPETEXT:
    4616             :             // If we're leaving the shapetext group (it may have nested ones) and this is a shape, not an old drawingobject.
    4617          27 :             if (m_aStates.top().nDestinationState != DESTINATION_SHAPETEXT && !m_aStates.top().aDrawingObject.bHadShapeText)
    4618             :             {
    4619          20 :                 m_aStates.top().bHadShapeText = true;
    4620          20 :                 if (!m_aStates.top().pCurrentBuffer)
    4621          19 :                     m_pSdrImport->close();
    4622             :                 else
    4623           1 :                     m_aStates.top().pCurrentBuffer->push_back(make_pair(BUFFER_ENDSHAPE, RTFValue::Pointer_t()));
    4624             :             }
    4625          27 :             break;
    4626             :         default:
    4627             :             {
    4628        5713 :                 if (m_aStates.size() && m_aStates.top().nDestinationState == DESTINATION_PICT)
    4629           7 :                     m_aStates.top().aPicture = aState.aPicture;
    4630             :             }
    4631        5713 :             break;
    4632             :     }
    4633             : 
    4634        7392 :     if (aState.pCurrentBuffer == &m_aSuperBuffer)
    4635             :     {
    4636             :         OSL_ASSERT(!m_aStates.empty() && m_aStates.top().pCurrentBuffer == 0);
    4637             : 
    4638          17 :         if (!m_bHasFootnote)
    4639          14 :             replayBuffer(m_aSuperBuffer);
    4640             : 
    4641          17 :         m_bHasFootnote = false;
    4642             :     }
    4643             : 
    4644        7392 :     if (!m_aStates.empty())
    4645             :     {
    4646        7189 :         m_aStates.top().nCells = aState.nCells;
    4647        7189 :         m_aStates.top().aTableCellsSprms = aState.aTableCellsSprms;
    4648        7189 :         m_aStates.top().aTableCellsAttributes = aState.aTableCellsAttributes;
    4649             :     }
    4650             : 
    4651        7392 :     return 0;
    4652             : }
    4653             : 
    4654           0 : ::std::string RTFDocumentImpl::getType() const
    4655             : {
    4656           0 :     return "RTFDocumentImpl";
    4657             : }
    4658             : 
    4659         192 : uno::Reference<lang::XMultiServiceFactory> RTFDocumentImpl::getModelFactory()
    4660             : {
    4661         192 :     return m_xModelFactory;
    4662             : }
    4663             : 
    4664          40 : bool RTFDocumentImpl::isInBackground()
    4665             : {
    4666          40 :     return m_aStates.top().bInBackground;
    4667             : }
    4668             : 
    4669      195554 : RTFInternalState RTFDocumentImpl::getInternalState()
    4670             : {
    4671      195554 :     return m_aStates.top().nInternalState;
    4672             : }
    4673             : 
    4674       23449 : void RTFDocumentImpl::setInternalState(RTFInternalState nInternalState)
    4675             : {
    4676       23449 :     m_aStates.top().nInternalState = nInternalState;
    4677       23449 : }
    4678             : 
    4679       65252 : RTFDestinationState RTFDocumentImpl::getDestinationState()
    4680             : {
    4681       65252 :     return m_aStates.top().nDestinationState;
    4682             : }
    4683             : 
    4684         352 : void RTFDocumentImpl::setDestinationState(RTFDestinationState nDestinationState)
    4685             : {
    4686         352 :     m_aStates.top().nDestinationState = nDestinationState;
    4687         352 : }
    4688             : 
    4689           4 : void RTFDocumentImpl::setDestinationText(OUString& rString)
    4690             : {
    4691           4 :     m_aStates.top().aDestinationText.setLength(0);
    4692           4 :     m_aStates.top().aDestinationText.append(rString);
    4693           4 : }
    4694             : 
    4695       62028 : bool RTFDocumentImpl::getSkipUnknown()
    4696             : {
    4697       62028 :     return m_bSkipUnknown;
    4698             : }
    4699             : 
    4700         775 : void RTFDocumentImpl::setSkipUnknown(bool bSkipUnknown)
    4701             : {
    4702         775 :     m_bSkipUnknown = bSkipUnknown;
    4703         775 : }
    4704             : 
    4705       88345 : void RTFDocumentImpl::checkUnicode(bool bUnicode, bool bHex)
    4706             : {
    4707       88345 :     if (bUnicode && !m_aUnicodeBuffer.isEmpty())
    4708             :     {
    4709         118 :         OUString aString = m_aUnicodeBuffer.makeStringAndClear();
    4710         118 :         text(aString);
    4711             :     }
    4712       88345 :     if (bHex && !m_aHexBuffer.isEmpty())
    4713             :     {
    4714        2003 :         OUString aString = OStringToOUString(m_aHexBuffer.makeStringAndClear(), m_aStates.top().nCurrentEncoding);
    4715        2003 :         text(aString);
    4716             :     }
    4717       88345 : }
    4718             : 
    4719         206 : RTFParserState::RTFParserState(RTFDocumentImpl *pDocumentImpl)
    4720             :     : m_pDocumentImpl(pDocumentImpl),
    4721             :     nInternalState(INTERNAL_NORMAL),
    4722             :     nDestinationState(DESTINATION_NORMAL),
    4723             :     nFieldStatus(FIELD_NONE),
    4724             :     nBorderState(BORDER_NONE),
    4725             :     aTableSprms(),
    4726             :     aTableAttributes(),
    4727             :     aCharacterSprms(),
    4728             :     aCharacterAttributes(),
    4729             :     aParagraphSprms(),
    4730             :     aParagraphAttributes(),
    4731             :     aSectionSprms(),
    4732             :     aSectionAttributes(),
    4733             :     aTableRowSprms(),
    4734             :     aTableRowAttributes(),
    4735             :     aTableCellSprms(),
    4736             :     aTableCellAttributes(),
    4737             :     aTableCellsSprms(),
    4738             :     aTableCellsAttributes(),
    4739             :     aTabAttributes(),
    4740             :     aCurrentColor(),
    4741         206 :     nCurrentEncoding(rtl_getTextEncodingFromWindowsCharset(0)),
    4742             :     nUc(1),
    4743             :     nCharsToSkip(0),
    4744             :     nBinaryToRead(0),
    4745             :     nListLevelNum(0),
    4746             :     aListLevelEntries(),
    4747             :     aLevelNumbers(),
    4748             :     aPicture(),
    4749             :     aShape(),
    4750             :     aDrawingObject(),
    4751             :     aFrame(this),
    4752             :     nCellX(0),
    4753             :     nCells(0),
    4754             :     nInheritingCells(0),
    4755             :     bIsCjk(false),
    4756             :     nYear(0),
    4757             :     nMonth(0),
    4758             :     nDay(0),
    4759             :     nHour(0),
    4760             :     nMinute(0),
    4761             :     nCurrentStyleIndex(-1),
    4762             :     pCurrentBuffer(0),
    4763             :     bHasTableStyle(false),
    4764             :     bInListpicture(false),
    4765             :     bInBackground(false),
    4766             :     bHadShapeText(false),
    4767         412 :     bInShapeGroup(false)
    4768             : {
    4769         206 : }
    4770             : 
    4771         380 : void RTFParserState::resetFrame()
    4772             : {
    4773         380 :     aFrame = RTFFrame(this);
    4774         380 : }
    4775             : 
    4776         490 : RTFColorTableEntry::RTFColorTableEntry()
    4777             :     : nRed(0),
    4778             :     nGreen(0),
    4779         490 :     nBlue(0)
    4780             : {
    4781         490 : }
    4782             : 
    4783         206 : RTFPicture::RTFPicture()
    4784             :     : nWidth(0),
    4785             :     nHeight(0),
    4786             :     nGoalWidth(0),
    4787             :     nGoalHeight(0),
    4788             :     nScaleX(100),
    4789             :     nScaleY(100),
    4790             :     nCropT(0),
    4791             :     nCropB(0),
    4792             :     nCropL(0),
    4793             :     nCropR(0),
    4794             :     eWMetafile(0),
    4795         206 :     nStyle(BMPSTYLE_NONE)
    4796             : {
    4797         206 : }
    4798             : 
    4799       34642 : RTFShape::RTFShape()
    4800             :     : nLeft(0),
    4801             :     nTop(0),
    4802             :     nRight(0),
    4803             :     nBottom(0),
    4804             :     nHoriOrientRelation(0),
    4805             :     nVertOrientRelation(0),
    4806       34642 :     nWrap(-1)
    4807             : {
    4808       34642 : }
    4809             : 
    4810         206 : RTFDrawingObject::RTFDrawingObject()
    4811             :     : nLineColorR(0),
    4812             :     nLineColorG(0),
    4813             :     nLineColorB(0),
    4814             :     bHasLineColor(false),
    4815             :     nFillColorR(0),
    4816             :     nFillColorG(0),
    4817             :     nFillColorB(0),
    4818             :     bHasFillColor(false),
    4819             :     nDhgt(0),
    4820             :     nFLine(-1),
    4821             :     nPolyLineCount(0),
    4822         206 :     bHadShapeText(false)
    4823             : {
    4824         206 : }
    4825             : 
    4826         586 : RTFFrame::RTFFrame(RTFParserState* pParserState)
    4827             :     : m_pParserState(pParserState),
    4828             :     nX(0),
    4829             :     nY(0),
    4830             :     nW(0),
    4831             :     nH(0),
    4832             :     nHoriPadding(0),
    4833             :     nVertPadding(0),
    4834             :     nHoriAlign(0),
    4835             :     nHoriAnchor(0),
    4836             :     nVertAlign(0),
    4837             :     nVertAnchor(0),
    4838             :     nHRule(NS_ooxml::LN_Value_wordprocessingml_ST_HeightRule_auto),
    4839         586 :     nAnchorType(0)
    4840             : {
    4841         586 : }
    4842             : 
    4843         132 : void RTFFrame::setSprm(Id nId, Id nValue)
    4844             : {
    4845         132 :     if (m_pParserState->m_pDocumentImpl->getFirstRun())
    4846             :     {
    4847           9 :         m_pParserState->m_pDocumentImpl->checkFirstRun();
    4848           9 :         m_pParserState->m_pDocumentImpl->setNeedPar(false);
    4849             :     }
    4850         132 :     switch (nId)
    4851             :     {
    4852             :         case NS_sprm::LN_PDxaWidth:
    4853          15 :             nW = nValue;
    4854          15 :             break;
    4855             :         case NS_sprm::LN_PWHeightAbs:
    4856          15 :             nH = nValue;
    4857          15 :             break;
    4858             :         case NS_ooxml::LN_CT_FramePr_x:
    4859          15 :             nX = nValue;
    4860          15 :             break;
    4861             :         case NS_ooxml::LN_CT_FramePr_y:
    4862          15 :             nY = nValue;
    4863          15 :             break;
    4864             :         case NS_sprm::LN_PDxaFromText:
    4865           5 :             nHoriPadding = nValue;
    4866           5 :             break;
    4867             :         case NS_sprm::LN_PDyaFromText:
    4868           5 :             nVertPadding = nValue;
    4869           5 :             break;
    4870             :         case NS_ooxml::LN_CT_FramePr_xAlign:
    4871          16 :             nHoriAlign = nValue;
    4872          16 :             break;
    4873             :         case NS_ooxml::LN_CT_FramePr_hAnchor:
    4874          14 :             nHoriAnchor = nValue;
    4875          14 :             break;
    4876             :         case NS_ooxml::LN_CT_FramePr_yAlign:
    4877          16 :             nVertAlign = nValue;
    4878          16 :             break;
    4879             :         case NS_ooxml::LN_CT_FramePr_vAnchor:
    4880          15 :             nVertAnchor = nValue;
    4881          15 :             break;
    4882             :         case NS_sprm::LN_PWr:
    4883           1 :             oWrap.reset(nValue);
    4884           1 :             break;
    4885             :         default:
    4886           0 :             break;
    4887             :     }
    4888         132 : }
    4889             : 
    4890          21 : RTFSprms RTFFrame::getSprms()
    4891             : {
    4892          21 :     RTFSprms sprms;
    4893             : 
    4894             :     static Id pNames[] =
    4895             :     {
    4896             :         NS_ooxml::LN_CT_FramePr_x,
    4897             :         NS_ooxml::LN_CT_FramePr_y,
    4898             :         NS_ooxml::LN_CT_FramePr_hRule, // Make sure nHRule is processed before nH
    4899             :         NS_sprm::LN_PWHeightAbs,
    4900             :         NS_sprm::LN_PDxaWidth,
    4901             :         NS_sprm::LN_PDxaFromText,
    4902             :         NS_sprm::LN_PDyaFromText,
    4903             :         NS_ooxml::LN_CT_FramePr_hAnchor,
    4904             :         NS_ooxml::LN_CT_FramePr_vAnchor,
    4905             :         NS_ooxml::LN_CT_FramePr_xAlign,
    4906             :         NS_ooxml::LN_CT_FramePr_yAlign,
    4907             :         NS_sprm::LN_PWr,
    4908             :         NS_ooxml::LN_CT_FramePr_dropCap,
    4909             :         NS_ooxml::LN_CT_FramePr_lines
    4910             :     };
    4911             : 
    4912         315 :     for ( int i = 0, len = SAL_N_ELEMENTS(pNames); i < len; ++i )
    4913             :     {
    4914         294 :         Id nId = pNames[i];
    4915         294 :         RTFValue::Pointer_t pValue;
    4916             : 
    4917         294 :         switch ( nId )
    4918             :         {
    4919             :             case NS_ooxml::LN_CT_FramePr_x:
    4920          21 :                 if ( nX != 0 )
    4921          21 :                     pValue.reset(new RTFValue(nX));
    4922          21 :                 break;
    4923             :             case NS_ooxml::LN_CT_FramePr_y:
    4924          21 :                 if ( nY != 0 )
    4925          21 :                     pValue.reset(new RTFValue(nY));
    4926          21 :                 break;
    4927             :             case NS_sprm::LN_PWHeightAbs:
    4928          21 :                 if ( nH != 0 )
    4929             :                 {
    4930          19 :                     if (nHRule == NS_ooxml::LN_Value_wordprocessingml_ST_HeightRule_exact)
    4931          18 :                         pValue.reset(new RTFValue(-nH)); // The negative value just sets nHRule
    4932             :                     else
    4933           1 :                         pValue.reset(new RTFValue(nH));
    4934             :                 }
    4935          21 :                 break;
    4936             :             case NS_sprm::LN_PDxaWidth:
    4937          21 :                 if ( nW != 0 )
    4938          21 :                     pValue.reset(new RTFValue(nW));
    4939          21 :                 break;
    4940             :             case NS_sprm::LN_PDxaFromText:
    4941          21 :                 if ( nHoriPadding != 0 )
    4942           1 :                     pValue.reset(new RTFValue(nHoriPadding));
    4943          21 :                 break;
    4944             :             case NS_sprm::LN_PDyaFromText:
    4945          21 :                 if ( nVertPadding != 0 )
    4946           1 :                     pValue.reset(new RTFValue(nVertPadding));
    4947          21 :                 break;
    4948             :             case NS_ooxml::LN_CT_FramePr_hAnchor:
    4949             :                 {
    4950          21 :                     if ( nHoriAnchor == 0 )
    4951           2 :                         nHoriAnchor = NS_ooxml::LN_Value_wordprocessingml_ST_HAnchor_margin;
    4952          21 :                     pValue.reset(new RTFValue(nHoriAnchor));
    4953             :                 }
    4954          21 :                 break;
    4955             :             case NS_ooxml::LN_CT_FramePr_vAnchor:
    4956             :                 {
    4957          21 :                     if ( nVertAnchor == 0 )
    4958           1 :                         nVertAnchor = NS_ooxml::LN_Value_wordprocessingml_ST_VAnchor_margin;
    4959          21 :                     pValue.reset(new RTFValue(nVertAnchor));
    4960             :                 }
    4961          21 :                 break;
    4962             :             case NS_ooxml::LN_CT_FramePr_xAlign:
    4963          21 :                 pValue.reset(new RTFValue(nHoriAlign));
    4964          21 :                 break;
    4965             :             case NS_ooxml::LN_CT_FramePr_yAlign:
    4966          21 :                 pValue.reset(new RTFValue(nVertAlign));
    4967          21 :                 break;
    4968             :             case NS_ooxml::LN_CT_FramePr_hRule:
    4969             :                 {
    4970          21 :                     if ( nH < 0 )
    4971          18 :                         nHRule = NS_ooxml::LN_Value_wordprocessingml_ST_HeightRule_exact;
    4972           3 :                     else if ( nH > 0 )
    4973           1 :                         nHRule = NS_ooxml::LN_Value_wordprocessingml_ST_HeightRule_atLeast;
    4974          21 :                     pValue.reset(new RTFValue(nHRule));
    4975             :                 }
    4976          21 :                 break;
    4977             :             case NS_sprm::LN_PWr:
    4978          21 :                 if (oWrap)
    4979           1 :                     pValue.reset(new RTFValue(*oWrap));
    4980          21 :                 break;
    4981             :             default:
    4982          42 :                 break;
    4983             :         }
    4984             : 
    4985         294 :         if (pValue.get())
    4986         190 :             sprms.set(nId, pValue);
    4987         294 :     }
    4988             : 
    4989          21 :     RTFSprms frameprSprms;
    4990          42 :     RTFValue::Pointer_t pFrameprValue(new RTFValue(sprms));
    4991          21 :     frameprSprms.set(NS_ooxml::LN_CT_PPrBase_framePr, pFrameprValue);
    4992             : 
    4993          42 :     return frameprSprms;
    4994             : }
    4995             : 
    4996         956 : bool RTFFrame::hasProperties()
    4997             : {
    4998        2784 :     return nX != 0 || nY != 0 || nW != 0 || nH != 0 ||
    4999        2742 :         nHoriPadding != 0 || nVertPadding != 0 ||
    5000        3698 :         nHoriAlign != 0 || nHoriAnchor != 0 || nVertAlign != 0 || nVertAnchor != 0 ||
    5001        1870 :         nAnchorType != 0;
    5002             : }
    5003             : 
    5004             : } // namespace rtftok
    5005          24 : } // namespace writerfilter
    5006             : 
    5007             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10