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

Generated by: LCOV version 1.10