LCOV - code coverage report
Current view: top level - usr/local/src/libreoffice/sw/source/filter/ww8 - wrtww8.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 1367 1948 70.2 %
Date: 2013-07-09 Functions: 126 150 84.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             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : 
      21             : #include <iostream>
      22             : 
      23             : #include <com/sun/star/embed/ElementModes.hpp>
      24             : #include <com/sun/star/embed/XStorage.hpp>
      25             : #include <unotools/ucbstreamhelper.hxx>
      26             : 
      27             : #include <algorithm>
      28             : 
      29             : #include <hintids.hxx>
      30             : #include <string.h>             // memcpy()
      31             : #include <osl/endian.h>
      32             : #include <docsh.hxx>
      33             : 
      34             : #include <unotools/fltrcfg.hxx>
      35             : #include <vcl/salbtype.hxx>
      36             : #include <sot/storage.hxx>
      37             : #include <svl/zformat.hxx>
      38             : #include <sfx2/docinf.hxx>
      39             : #include <editeng/tstpitem.hxx>
      40             : #include <svx/svdmodel.hxx>
      41             : #include <svx/svdpage.hxx>
      42             : #include <editeng/hyphenzoneitem.hxx>
      43             : #include <editeng/langitem.hxx>
      44             : #include <filter/msfilter/msoleexp.hxx>
      45             : #include <editeng/lrspitem.hxx>
      46             : #include <editeng/ulspitem.hxx>
      47             : #include <editeng/boxitem.hxx>
      48             : #include <editeng/brushitem.hxx>
      49             : #include <swtypes.hxx>
      50             : #include <swrect.hxx>
      51             : #include <swtblfmt.hxx>
      52             : #include <txatbase.hxx>
      53             : #include <fmtcntnt.hxx>
      54             : #include <fmtpdsc.hxx>
      55             : #include <fmtrowsplt.hxx>
      56             : #include <frmatr.hxx>
      57             : #include <doc.hxx>
      58             : #include <viewopt.hxx>
      59             : #include <docary.hxx>
      60             : #include <pam.hxx>
      61             : #include <ndtxt.hxx>
      62             : #include <shellio.hxx>
      63             : #include <docstat.hxx>
      64             : #include <pagedesc.hxx>
      65             : #include <IMark.hxx>
      66             : #include <swtable.hxx>
      67             : #include <wrtww8.hxx>
      68             : #include <ww8par.hxx>
      69             : #include <fltini.hxx>
      70             : #include <swmodule.hxx>
      71             : #include <section.hxx>
      72             : #include <swfltopt.hxx>
      73             : #include <fmtinfmt.hxx>
      74             : #include <txtinet.hxx>
      75             : #include <fmturl.hxx>
      76             : #include <fesh.hxx>
      77             : #include <svtools/imap.hxx>
      78             : #include <svtools/imapobj.hxx>
      79             : #include <tools/urlobj.hxx>
      80             : #include <mdiexp.hxx>           // Progress
      81             : #include <statstr.hrc>          // ResId for the status bar
      82             : #include <fmtline.hxx>
      83             : #include <fmtfsize.hxx>
      84             : #include <comphelper/extract.hxx>
      85             : #include <comphelper/stlunosequence.hxx>
      86             : #include <comphelper/string.hxx>
      87             : #include <doctok/sprmids.hxx>
      88             : 
      89             : #include "writerhelper.hxx"
      90             : #include "writerwordglue.hxx"
      91             : #include "ww8attributeoutput.hxx"
      92             : 
      93             : #include <IDocumentMarkAccess.hxx>
      94             : #include <xmloff/odffields.hxx>
      95             : 
      96             : #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
      97             : #include <com/sun/star/document/XDocumentProperties.hpp>
      98             : 
      99             : #include "dbgoutsw.hxx"
     100             : 
     101             : #include <sfx2/docfile.hxx>
     102             : #include <sfx2/request.hxx>
     103             : #include <sfx2/frame.hxx>
     104             : #include <svl/stritem.hxx>
     105             : #include <unotools/tempfile.hxx>
     106             : #include <filter/msfilter/mscodec.hxx>
     107             : #include <filter/msfilter/svxmsbas.hxx>
     108             : #include <osl/time.h>
     109             : #include <rtl/random.h>
     110             : #include <vcl/svapp.hxx>
     111             : #include "WW8Sttbf.hxx"
     112             : #include <editeng/charrotateitem.hxx>
     113             : #include "WW8FibData.hxx"
     114             : #include "numrule.hxx"//For i120928
     115             : 
     116             : using namespace css;
     117             : using namespace sw::util;
     118             : using namespace sw::types;
     119             : 
     120             : /** FKP - Formatted disK Page
     121             : */
     122             : class WW8_WrFkp
     123             : {
     124             :     sal_uInt8* pFkp;         // Fkp total ( first and only FCs and Sprms )
     125             :     sal_uInt8* pOfs;         // pointer to the offset area, later copied to pFkp
     126             :     ePLCFT ePlc;
     127             :     short nStartGrp;    // ab hier grpprls
     128             :     short nOldStartGrp;
     129             :     sal_uInt8 nItemSize;
     130             :     sal_uInt8 nIMax;         // number of entry pairs
     131             :     sal_uInt8 nOldVarLen;
     132             :     bool bCombined;     // true : paste not allowed
     133             : 
     134             :     sal_uInt8 SearchSameSprm( sal_uInt16 nVarLen, const sal_uInt8* pSprms );
     135             : public:
     136             :     WW8_WrFkp(ePLCFT ePl, WW8_FC nStartFc, bool bWrtWW8);
     137             :     ~WW8_WrFkp();
     138             :     bool Append( WW8_FC nEndFc, sal_uInt16 nVarLen = 0, const sal_uInt8* pSprms = 0 );
     139             :     bool Combine();
     140             :     void Write( SvStream& rStrm, SwWW8WrGrf& rGrf );
     141             : 
     142         709 :     bool IsEqualPos(WW8_FC nEndFc) const
     143         709 :     {   return !bCombined && nIMax && nEndFc == ((sal_Int32*)pFkp)[nIMax]; }
     144             :     void MergeToNew( short& rVarLen, sal_uInt8 *& pNewSprms );
     145         137 :     bool IsEmptySprm() const
     146         137 :     {   return !bCombined && nIMax && !nOldVarLen;  }
     147          69 :     void SetNewEnd( WW8_FC nEnd )
     148          69 :     {   ((sal_Int32*)pFkp)[nIMax] = nEnd; }
     149             : 
     150             : #ifdef __WW8_NEEDS_COPY
     151             :     WW8_FC GetStartFc() const;
     152             :     WW8_FC GetEndFc() const;
     153             : #else
     154             :     WW8_FC GetStartFc() const { return ((sal_Int32*)pFkp)[0]; };
     155             :     WW8_FC GetEndFc() const { return ((sal_Int32*)pFkp)[nIMax]; };
     156             : #endif // defined __WW8_NEEDS_COPY
     157             : 
     158             :     sal_uInt8 *CopyLastSprms(sal_uInt8 &rLen, bool bVer8);
     159             : };
     160             : 
     161             : 
     162             : // class WW8_WrPc collects all piece entries for one piece
     163             : class WW8_WrPc
     164             : {
     165             :     WW8_CP nStartCp;                    // Starting character position of the text
     166             :     WW8_FC nStartFc;                    // Starting file position of the text
     167             :     sal_uInt16 nStatus;                     // End of paragraph inside the piece?
     168             : 
     169             : public:
     170           8 :     WW8_WrPc(WW8_FC nSFc, WW8_CP nSCp )
     171           8 :         : nStartCp( nSCp ), nStartFc( nSFc ), nStatus( 0x0040 )
     172           8 :     {}
     173             : 
     174         367 :     void SetStatus()                { nStatus = 0x0050; }
     175           8 :     sal_uInt16 GetStatus()  const       { return nStatus; }
     176         180 :     WW8_CP GetStartCp() const       { return nStartCp; }
     177           8 :     WW8_FC GetStartFc() const       { return nStartFc; }
     178             : };
     179             : 
     180             : class WW8_WrtBookmarks
     181             : {
     182             : private:
     183             :     //! Holds information about a single bookmark.
     184          11 :     struct BookmarkInfo {
     185             :         sal_uLong  startPos; //!< Starting character position.
     186             :         sal_uLong  endPos;   //!< Ending character position.
     187             :         bool   isField;  //!< True if the bookmark is in a field result.
     188             :         String name;     //!< Name of this bookmark.
     189           2 :         inline BookmarkInfo(sal_uLong start, sal_uLong end, bool isFld, const String& bkName) : startPos(start), endPos(end), isField(isFld), name(bkName) {};
     190             :         //! Operator < is defined purely for sorting.
     191           2 :         inline bool operator<(const BookmarkInfo &other) const { return startPos < other.startPos; }
     192             :     };
     193             :     std::vector<BookmarkInfo> aBookmarks;
     194             :     typedef std::vector<BookmarkInfo>::iterator BkmIter;
     195             : 
     196             :     //! Return the position in aBookmarks where the string rNm can be found.
     197             :     BkmIter GetPos( const String& rNm );
     198             : 
     199             :     //No copying
     200             :     WW8_WrtBookmarks(const WW8_WrtBookmarks&);
     201             :     WW8_WrtBookmarks& operator=(const WW8_WrtBookmarks&);
     202             : public:
     203             :     WW8_WrtBookmarks();
     204             :     ~WW8_WrtBookmarks();
     205             : 
     206             :     //! Add a new bookmark to the list OR add an end position to an existing bookmark.
     207             :     void Append( WW8_CP nStartCp, const String& rNm, const ::sw::mark::IMark* pBkmk=NULL );
     208             :     //! Write out bookmarks to file.
     209             :     void Write( WW8Export& rWrt );
     210             :     //! Move existing field marks from one position to another.
     211             :     void MoveFieldMarks(sal_uLong nFrom,sal_uLong nTo);
     212             : 
     213             : };
     214             : 
     215             : #define ANZ_DEFAULT_STYLES 16
     216             : 
     217             : // Names of the storage streams
     218             : #define sMainStream OUString("WordDocument")
     219             : #define sCompObj OUString("\1CompObj")
     220             : 
     221           8 : static void WriteDop( WW8Export& rWrt )
     222             : {
     223           8 :     WW8Dop& rDop = *rWrt.pDop;
     224             : 
     225             :     // i#78951#, store the value of unknown compatability options
     226           8 :     rDop.SetCompatabilityOptions( rWrt.pDoc->Getn32DummyCompatabilityOptions1());
     227           8 :     rDop.SetCompatabilityOptions2( rWrt.pDoc->Getn32DummyCompatabilityOptions2());
     228             : 
     229           8 :     rDop.fNoLeading = !rWrt.pDoc->get(IDocumentSettingAccess::ADD_EXT_LEADING);
     230           8 :     rDop.fUsePrinterMetrics = !rWrt.pDoc->get(IDocumentSettingAccess::USE_VIRTUAL_DEVICE);
     231             : 
     232             :     // write default TabStop
     233             :     const SvxTabStopItem& rTabStop =
     234           8 :         DefaultItemGet<SvxTabStopItem>(*rWrt.pDoc, RES_PARATR_TABSTOP);
     235           8 :     rDop.dxaTab = (sal_uInt16)rTabStop[0].GetTabPos();
     236             : 
     237             :     // Zoom factor
     238           8 :     ViewShell *pViewShell(rWrt.pDoc->GetCurrentViewShell());
     239           8 :     if (pViewShell && pViewShell->GetViewOptions()->GetZoomType() == SVX_ZOOM_PERCENT)
     240           8 :         rDop.wScaleSaved = pViewShell->GetViewOptions()->GetZoom();
     241             : 
     242             :     // Werte aus der DocStatistik (werden aufjedenfall fuer die
     243             :     // DocStat-Felder benoetigt!)
     244           8 :     rDop.fWCFtnEdn = true; // because they are included in StarWriter
     245             : 
     246           8 :     const SwDocStat& rDStat = rWrt.pDoc->GetDocStat();
     247           8 :     rDop.cWords = rDStat.nWord;
     248           8 :     rDop.cCh = rDStat.nChar;
     249           8 :     rDop.cPg = static_cast< sal_Int16 >(rDStat.nPage);
     250           8 :     rDop.cParas = rDStat.nPara;
     251           8 :     rDop.cLines = rDStat.nPara;
     252             : 
     253           8 :     SwDocShell *pDocShell(rWrt.pDoc->GetDocShell());
     254             :     OSL_ENSURE(pDocShell, "no SwDocShell");
     255           8 :     uno::Reference<document::XDocumentProperties> xDocProps;
     256          16 :     uno::Reference<beans::XPropertySet> xProps;
     257           8 :     if (pDocShell) {
     258             :         uno::Reference<lang::XComponent> xModelComp(pDocShell->GetModel(),
     259           8 :            uno::UNO_QUERY);
     260          16 :         xProps = uno::Reference<beans::XPropertySet>(xModelComp,
     261           8 :            uno::UNO_QUERY);
     262             :         uno::Reference<document::XDocumentPropertiesSupplier> xDPS(
     263          16 :             xModelComp, uno::UNO_QUERY_THROW);
     264           8 :         xDocProps = xDPS->getDocumentProperties();
     265             :         OSL_ENSURE(xDocProps.is(), "DocumentProperties is null");
     266             : 
     267          16 :         rDop.lKeyProtDoc = pDocShell->GetModifyPasswordHash();
     268             :     }
     269             : 
     270          16 :     if ((rWrt.pSepx && rWrt.pSepx->DocumentIsProtected()) ||
     271           8 :         rDop.lKeyProtDoc != 0)
     272             :     {
     273           0 :         rDop.fProtEnabled =  1;
     274             :     }
     275             :     else
     276             :     {
     277           8 :         rDop.fProtEnabled = 0;
     278             :     }
     279             : 
     280           8 :     if (!xDocProps.is())
     281             :     {
     282           0 :         rDop.dttmCreated = rDop.dttmRevised = rDop.dttmLastPrint = 0x45FBAC69;
     283             :     }
     284             :     else
     285             :     {
     286           8 :         ::util::DateTime uDT = xDocProps->getCreationDate();
     287           8 :         Date aD(uDT.Day, uDT.Month, uDT.Year);
     288           8 :         Time aT(uDT.Hours, uDT.Minutes, uDT.Seconds, uDT.NanoSeconds);
     289           8 :         rDop.dttmCreated = sw::ms::DateTime2DTTM(DateTime(aD,aT));
     290           8 :         uDT = xDocProps->getModificationDate();
     291           8 :         Date aD2(uDT.Day, uDT.Month, uDT.Year);
     292           8 :         Time aT2(uDT.Hours, uDT.Minutes, uDT.Seconds, uDT.NanoSeconds);
     293           8 :         rDop.dttmRevised = sw::ms::DateTime2DTTM(DateTime(aD2,aT2));
     294           8 :         uDT = xDocProps->getPrintDate();
     295           8 :         Date aD3(uDT.Day, uDT.Month, uDT.Year);
     296           8 :         Time aT3(uDT.Hours, uDT.Minutes, uDT.Seconds, uDT.NanoSeconds);
     297           8 :         rDop.dttmLastPrint = sw::ms::DateTime2DTTM(DateTime(aD3,aT3));
     298             :     }
     299             : 
     300             :     // Also, the DocStat fields in headers, footers are not calculated correctly.
     301             :     // ( we do not have this fields! )
     302             : 
     303             :     // and also for the Headers and Footers
     304           8 :     rDop.cWordsFtnEnd   = rDStat.nWord;
     305           8 :     rDop.cChFtnEdn      = rDStat.nChar;
     306           8 :     rDop.cPgFtnEdn      = (sal_Int16)rDStat.nPage;
     307           8 :     rDop.cParasFtnEdn   = rDStat.nPara;
     308           8 :     rDop.cLinesFtnEdn   = rDStat.nPara;
     309             : 
     310           8 :     rDop.fDontUseHTMLAutoSpacing = (rWrt.pDoc->get(IDocumentSettingAccess::PARA_SPACE_MAX) != 0);
     311             : 
     312           8 :     rDop.fExpShRtn = !rWrt.pDoc->get(IDocumentSettingAccess::DO_NOT_JUSTIFY_LINES_WITH_MANUAL_BREAK); // #i56856#
     313             : 
     314          16 :     rDop.Write( *rWrt.pTableStrm, *rWrt.pFib );
     315           8 : }
     316             : 
     317          45 : const sal_Unicode *WW8DopTypography::GetJapanNotBeginLevel1()
     318             : {
     319             :     static const sal_Unicode aJapanNotBeginLevel1[nMaxFollowing] =
     320             :     //Japanese Level 1
     321             :     {
     322             :         0x0021, 0x0025, 0x0029, 0x002c, 0x002e, 0x003a, 0x003b, 0x003f,
     323             :         0x005d, 0x007d, 0x00a2, 0x00b0, 0x2019, 0x201d, 0x2030, 0x2032,
     324             :         0x2033, 0x2103, 0x3001, 0x3002, 0x3005, 0x3009, 0x300b, 0x300d,
     325             :         0x300f, 0x3011, 0x3015, 0x309b, 0x309c, 0x309d, 0x309e, 0x30fb,
     326             :         0x30fd, 0x30fe, 0xff01, 0xff05, 0xff09, 0xff0c, 0xff0e, 0xff1a,
     327             :         0xff1b, 0xff1f, 0xff3d, 0xff5d, 0xff61, 0xff63, 0xff64, 0xff65,
     328             :         0xff9e, 0xff9f, 0xffe0
     329             :     };
     330          45 :     return &aJapanNotBeginLevel1[0];
     331             : }
     332             : 
     333          45 : const sal_Unicode *WW8DopTypography::GetJapanNotEndLevel1()
     334             : {
     335             :     static const sal_Unicode aJapanNotEndLevel1[nMaxLeading] =
     336             :     //Japanese Level 1
     337             :     {
     338             :         0x0024, 0x0028, 0x005b, 0x005c, 0x007b, 0x00a3, 0x00a5, 0x2018,
     339             :         0x201c, 0x3008, 0x300a, 0x300c, 0x300e, 0x3010, 0x3014, 0xff04,
     340             :         0xff08, 0xff3b, 0xff5b, 0xff62, 0xffe1, 0xffe5
     341             :     };
     342          45 :     return &aJapanNotEndLevel1[0];
     343             : }
     344             : 
     345          16 : static int lcl_CmpBeginEndChars( const OUString& rSWStr,
     346             :     const sal_Unicode* pMSStr, int nMSStrByteLen )
     347             : {
     348          16 :     nMSStrByteLen /= sizeof( sal_Unicode );
     349          16 :     if( nMSStrByteLen > rSWStr.getLength() )
     350          16 :         nMSStrByteLen = rSWStr.getLength()+1;
     351          16 :     nMSStrByteLen *= sizeof( sal_Unicode );
     352             : 
     353          16 :     return memcmp( rSWStr.getStr(), pMSStr, nMSStrByteLen );
     354             : }
     355             : 
     356             : /*
     357             : Converts the OOo Asian Typography into a best fit match for Microsoft
     358             : Asian typography. This structure is actually dumped to disk within the
     359             : Dop Writer. Assumption is that rTypo is cleared to 0 on entry
     360             : */
     361           8 : void WW8Export::ExportDopTypography(WW8DopTypography &rTypo)
     362             : {
     363             :     static const sal_Unicode aLangNotBegin[4][WW8DopTypography::nMaxFollowing]=
     364             :     {
     365             :         //Japanese Level 1
     366             :         {
     367             :             0x0021, 0x0025, 0x0029, 0x002c, 0x002e, 0x003a, 0x003b, 0x003f,
     368             :             0x005d, 0x007d, 0x00a2, 0x00b0, 0x2019, 0x201d, 0x2030, 0x2032,
     369             :             0x2033, 0x2103, 0x3001, 0x3002, 0x3005, 0x3009, 0x300b, 0x300d,
     370             :             0x300f, 0x3011, 0x3015, 0x3041, 0x3043, 0x3045, 0x3047, 0x3049,
     371             :             0x3063, 0x3083, 0x3085, 0x3087, 0x308e, 0x309b, 0x309c, 0x309d,
     372             :             0x309e, 0x30a1, 0x30a3, 0x30a5, 0x30a7, 0x30a9, 0x30c3, 0x30e3,
     373             :             0x30e5, 0x30e7, 0x30ee, 0x30f5, 0x30f6, 0x30fb, 0x30fc, 0x30fd,
     374             :             0x30fe, 0xff01, 0xff05, 0xff09, 0xff0c, 0xff0e, 0xff1a, 0xff1b,
     375             :             0xff1f, 0xff3d, 0xff5d, 0xff61, 0xff63, 0xff64, 0xff65, 0xff67,
     376             :             0xff68, 0xff69, 0xff6a, 0xff6b, 0xff6c, 0xff6d, 0xff6e, 0xff6f,
     377             :             0xff70, 0xff9e, 0xff9f, 0xffe0
     378             :         },
     379             :         //Simplified Chinese
     380             :         {
     381             :             0x0021, 0x0029, 0x002c, 0x002e, 0x003a, 0x003b, 0x003f, 0x005d,
     382             :             0x007d, 0x00a8, 0x00b7, 0x02c7, 0x02c9, 0x2015, 0x2016, 0x2019,
     383             :             0x201d, 0x2026, 0x2236, 0x3001, 0x3002, 0x3003, 0x3005, 0x3009,
     384             :             0x300b, 0x300d, 0x300f, 0x3011, 0x3015, 0x3017, 0xff01, 0xff02,
     385             :             0xff07, 0xff09, 0xff0c, 0xff0e, 0xff1a, 0xff1b, 0xff1f, 0xff3d,
     386             :             0xff40, 0xff5c, 0xff5d, 0xff5e, 0xffe0
     387             :         },
     388             :         //Korean
     389             :         {
     390             :             0x0021, 0x0025, 0x0029, 0x002c, 0x002e, 0x003a, 0x003b, 0x003f,
     391             :             0x005d, 0x007d, 0x00a2, 0x00b0, 0x2019, 0x201d, 0x2032, 0x2033,
     392             :             0x2103, 0x3009, 0x300b, 0x300d, 0x300f, 0x3011, 0x3015, 0xff01,
     393             :             0xff05, 0xff09, 0xff0c, 0xff0e, 0xff1a, 0xff1b, 0xff1f, 0xff3d,
     394             :             0xff5d, 0xffe0
     395             :         },
     396             :         //Traditional Chinese
     397             :         {
     398             :             0x0021, 0x0029, 0x002c, 0x002e, 0x003a, 0x003b, 0x003f, 0x005d,
     399             :             0x007d, 0x00a2, 0x00b7, 0x2013, 0x2014, 0x2019, 0x201d, 0x2022,
     400             :             0x2025, 0x2026, 0x2027, 0x2032, 0x2574, 0x3001, 0x3002, 0x3009,
     401             :             0x300b, 0x300d, 0x300f, 0x3011, 0x3015, 0x301e, 0xfe30, 0xfe31,
     402             :             0xfe33, 0xfe34, 0xfe36, 0xfe38, 0xfe3a, 0xfe3c, 0xfe3e, 0xfe40,
     403             :             0xfe42, 0xfe44, 0xfe4f, 0xfe50, 0xfe51, 0xfe52, 0xfe54, 0xfe55,
     404             :             0xfe56, 0xfe57, 0xfe5a, 0xfe5c, 0xfe5e, 0xff01, 0xff09, 0xff0c,
     405             :             0xff0e, 0xff1a, 0xff1b, 0xff1f, 0xff5c, 0xff5d, 0xff64
     406             :         },
     407             :     };
     408             : 
     409             :     static const sal_Unicode aLangNotEnd[4][WW8DopTypography::nMaxLeading] =
     410             :     {
     411             :         //Japanese Level 1
     412             :         {
     413             :             0x0024, 0x0028, 0x005b, 0x005c, 0x007b, 0x00a3, 0x00a5, 0x2018,
     414             :             0x201c, 0x3008, 0x300a, 0x300c, 0x300e, 0x3010, 0x3014, 0xff04,
     415             :             0xff08, 0xff3b, 0xff5b, 0xff62, 0xffe1, 0xffe5
     416             :         },
     417             :         //Simplified Chinese
     418             :         {
     419             :             0x0028, 0x005b, 0x007b, 0x00b7, 0x2018, 0x201c, 0x3008, 0x300a,
     420             :             0x300c, 0x300e, 0x3010, 0x3014, 0x3016, 0xff08, 0xff0e, 0xff3b,
     421             :             0xff5b, 0xffe1, 0xffe5
     422             :         },
     423             :         //Korean
     424             :         {
     425             :             0x0028, 0x005b, 0x005c, 0x007b, 0x00a3, 0x00a5, 0x2018, 0x201c,
     426             :             0x3008, 0x300a, 0x300c, 0x300e, 0x3010, 0x3014, 0xff04, 0xff08,
     427             :             0xff3b, 0xff5b, 0xffe6
     428             :         },
     429             :         //Traditional Chinese
     430             :         {
     431             :             0x0028, 0x005b, 0x007b, 0x00a3, 0x00a5, 0x2018, 0x201c, 0x2035,
     432             :             0x3008, 0x300a, 0x300c, 0x300e, 0x3010, 0x3014, 0x301d, 0xfe35,
     433             :             0xfe37, 0xfe39, 0xfe3b, 0xfe3d, 0xfe3f, 0xfe41, 0xfe43, 0xfe59,
     434             :             0xfe5b, 0xfe5d, 0xff08, 0xff5b
     435             :         },
     436             :     };
     437             : 
     438           8 :     const i18n::ForbiddenCharacters *pForbidden = 0;
     439           8 :     const i18n::ForbiddenCharacters *pUseMe = 0;
     440           8 :     sal_uInt8 nUseReserved=0;
     441           8 :     int nNoNeeded=0;
     442             :     /*
     443             :     Now we have some minor difficult issues, to wit...
     444             :     a. MicroSoft Office can only store one set of begin and end characters in
     445             :     a given document, not one per language.
     446             :     b. StarOffice has only a concept of one set of begin and end characters for
     447             :     a given language, i.e. not the two levels of kinsoku in japanese
     448             : 
     449             :     What is unknown as yet is if our default begin and end chars for
     450             :     japanese, chinese tradition, chinese simplified and korean are different
     451             :     in Word and Writer. I already suspect that they are different between
     452             :     different version of word itself.
     453             : 
     454             :     So what have come up with is to simply see if any of the four languages
     455             :     in OOo have been changed away from OUR defaults, and if one has then
     456             :     export that. If more than one has in the future we may hack in something
     457             :     which examines our document properties to see which language is used the
     458             :     most and choose that, for now we choose the first and throw an ASSERT
     459             :     */
     460             : 
     461             :     /*Our default Japanese Level is 2, this is a special MS hack to set this*/
     462           8 :     rTypo.reserved2 = 1;
     463             : 
     464          40 :     for (rTypo.reserved1=8;rTypo.reserved1>0;rTypo.reserved1-=2)
     465             :     {
     466          64 :         if (0 != (pForbidden = pDoc->getForbiddenCharacters(rTypo.GetConvertedLang(),
     467          64 :             false)))
     468             :         {
     469           4 :             int nIdx = (rTypo.reserved1-2)/2;
     470           4 :             if( lcl_CmpBeginEndChars( pForbidden->endLine,
     471           8 :                     aLangNotEnd[ nIdx ], sizeof(aLangNotEnd[ nIdx ]) ) ||
     472             :                 lcl_CmpBeginEndChars( pForbidden->beginLine,
     473           4 :                     aLangNotBegin[ nIdx ], sizeof(aLangNotBegin[ nIdx ]) ) )
     474             :             {
     475             :                 //One exception for Japanese, if it matches a level 1 we
     476             :                 //can use one extra flag for that, rather than use a custom
     477           4 :                 if (rTypo.GetConvertedLang() == LANGUAGE_JAPANESE)
     478             :                 {
     479           4 :                     if (
     480             :                           !lcl_CmpBeginEndChars
     481             :                             (
     482             :                                 pForbidden->endLine,
     483             :                                 rTypo.GetJapanNotEndLevel1(),
     484           4 :                                 rTypo.nMaxLeading * sizeof(sal_Unicode)
     485           4 :                             )
     486           8 :                         &&
     487             :                           !lcl_CmpBeginEndChars
     488             :                             (
     489             :                                 pForbidden->beginLine,
     490             :                                 rTypo.GetJapanNotBeginLevel1(),
     491           4 :                                 rTypo.nMaxFollowing * sizeof(sal_Unicode)
     492           4 :                             )
     493             :                         )
     494             :                     {
     495           4 :                         rTypo.reserved2 = 0;
     496           4 :                         continue;
     497             :                     }
     498             :                 }
     499             : 
     500           0 :                 if (!pUseMe)
     501             :                 {
     502           0 :                     pUseMe = pForbidden;
     503           0 :                     nUseReserved = rTypo.reserved1;
     504           0 :                     rTypo.iLevelOfKinsoku = 2;
     505             :                 }
     506           0 :                 nNoNeeded++;
     507             :             }
     508             :         }
     509             :     }
     510             : 
     511             :     OSL_ENSURE( nNoNeeded<=1, "Example of unexportable forbidden chars" );
     512           8 :     rTypo.reserved1=nUseReserved;
     513           8 :     if (rTypo.iLevelOfKinsoku)
     514             :     {
     515             :         rTypo.cchFollowingPunct = msword_cast<sal_Int16>
     516           0 :             (pUseMe->beginLine.getLength());
     517           0 :         if (rTypo.cchFollowingPunct > WW8DopTypography::nMaxFollowing - 1)
     518           0 :             rTypo.cchFollowingPunct = WW8DopTypography::nMaxFollowing - 1;
     519             : 
     520             :         rTypo.cchLeadingPunct = msword_cast<sal_Int16>
     521           0 :             (pUseMe->endLine.getLength());
     522           0 :         if (rTypo.cchLeadingPunct > WW8DopTypography::nMaxLeading - 1)
     523           0 :             rTypo.cchLeadingPunct = WW8DopTypography::nMaxLeading -1;
     524             : 
     525           0 :         memcpy(rTypo.rgxchFPunct,pUseMe->beginLine.getStr(),
     526           0 :             (rTypo.cchFollowingPunct+1)*2);
     527             : 
     528           0 :         memcpy(rTypo.rgxchLPunct,pUseMe->endLine.getStr(),
     529           0 :             (rTypo.cchLeadingPunct+1)*2);
     530             :     }
     531             : 
     532           8 :     const IDocumentSettingAccess* pIDocumentSettingAccess = GetWriter().getIDocumentSettingAccess();
     533             : 
     534           8 :     rTypo.fKerningPunct = pIDocumentSettingAccess->get(IDocumentSettingAccess::KERN_ASIAN_PUNCTUATION);
     535           8 :     rTypo.iJustification = pDoc->getCharacterCompressionType();
     536           8 : }
     537             : 
     538             : // It can only be found something with this method, if it is used within
     539             : // WW8_SwAttrIter::OutAttr() and WW8Export::OutputItemSet()
     540         147 : const SfxPoolItem* MSWordExportBase::HasItem( sal_uInt16 nWhich ) const
     541             : {
     542         147 :     const SfxPoolItem* pItem=0;
     543         147 :     if (pISet)
     544             :     {
     545             :         // if write a EditEngine text, then the WhichIds are greater as
     546             :         // ourer own Ids. So the Id have to translate from our into the
     547             :         // EditEngine Range
     548         130 :         nWhich = sw::hack::GetSetWhichFromSwDocWhich(*pISet, *pDoc, nWhich);
     549         130 :         if (nWhich && SFX_ITEM_SET != pISet->GetItemState(nWhich, true, &pItem))
     550         130 :             pItem = 0;
     551             :     }
     552          17 :     else if( pChpIter )
     553          17 :         pItem = pChpIter->HasTextItem( nWhich );
     554             :     else
     555             :     {
     556             :         OSL_ENSURE( !this, "Where is my ItemSet / pChpIter ?" );
     557           0 :         pItem = 0;
     558             :     }
     559         147 :     return pItem;
     560             : }
     561             : 
     562          43 : const SfxPoolItem& MSWordExportBase::GetItem(sal_uInt16 nWhich) const
     563             : {
     564             :     const SfxPoolItem* pItem;
     565          43 :     if (pISet)
     566             :     {
     567             :         // if write a EditEngine text, then the WhichIds are greater as
     568             :         // ourer own Ids. So the Id have to translate from our into the
     569             :         // EditEngine Range
     570          43 :         nWhich = sw::hack::GetSetWhichFromSwDocWhich(*pISet, *pDoc, nWhich);
     571             :         OSL_ENSURE(nWhich != 0, "All broken, Impossible");
     572          43 :         pItem = &pISet->Get(nWhich, true);
     573             :     }
     574           0 :     else if( pChpIter )
     575           0 :         pItem = &pChpIter->GetItem( nWhich );
     576             :     else
     577             :     {
     578             :         OSL_ENSURE( !this, "Where is my ItemSet / pChpIter ?" );
     579           0 :         pItem = 0;
     580             :     }
     581          43 :     return *pItem;
     582             : }
     583             : 
     584             : //------------------------------------------------------------------------------
     585             : 
     586          64 : WW8_WrPlc1::WW8_WrPlc1( sal_uInt16 nStructSz )
     587          64 :     : nStructSiz( nStructSz )
     588             : {
     589          64 :     nDataLen = 16 * nStructSz;
     590          64 :     pData = new sal_uInt8[ nDataLen ];
     591          64 : }
     592             : 
     593         128 : WW8_WrPlc1::~WW8_WrPlc1()
     594             : {
     595          64 :     delete[] pData;
     596          64 : }
     597             : 
     598           0 : WW8_CP WW8_WrPlc1::Prev() const
     599             : {
     600           0 :     bool b = !aPos.empty();
     601             :     OSL_ENSURE(b,"Prev called on empty list");
     602           0 :     return b ? aPos.back() : 0;
     603             : }
     604             : 
     605          14 : void WW8_WrPlc1::Append( WW8_CP nCp, const void* pNewData )
     606             : {
     607          14 :     sal_uLong nInsPos = aPos.size() * nStructSiz;
     608          14 :     aPos.push_back( nCp );
     609          14 :     if( nDataLen < nInsPos + nStructSiz )
     610             :     {
     611           0 :         sal_uInt8* pNew = new sal_uInt8[ 2 * nDataLen ];
     612           0 :         memcpy( pNew, pData, nDataLen );
     613           0 :         delete[] pData;
     614           0 :         pData = pNew;
     615           0 :         nDataLen *= 2;
     616             :     }
     617          14 :     memcpy( pData + nInsPos, pNewData, nStructSiz );
     618          14 : }
     619             : 
     620          64 : void WW8_WrPlc1::Finish( sal_uLong nLastCp, sal_uLong nSttCp )
     621             : {
     622          64 :     if( !aPos.empty() )
     623             :     {
     624          10 :         aPos.push_back( nLastCp );
     625          10 :         if( nSttCp )
     626           5 :             for( sal_uInt32 n = 0; n < aPos.size(); ++n )
     627           4 :                 aPos[ n ] -= nSttCp;
     628             :     }
     629          64 : }
     630             : 
     631             : 
     632          10 : void WW8_WrPlc1::Write( SvStream& rStrm )
     633             : {
     634             :     sal_uInt32 i;
     635          34 :     for( i = 0; i < aPos.size(); ++i )
     636          24 :         SwWW8Writer::WriteLong( rStrm, aPos[i] );
     637          10 :     if( i )
     638          10 :         rStrm.Write( pData, (i-1) * nStructSiz );
     639          10 : }
     640             : 
     641             : 
     642             : // Class WW8_WrPlcFld for fields
     643             : 
     644          56 : bool WW8_WrPlcFld::Write( WW8Export& rWrt )
     645             : {
     646          56 :     if( WW8_WrPlc1::Count() <= 1 )
     647          54 :         return false;
     648             : 
     649             :     WW8_FC *pfc;
     650             :     sal_Int32 *plc;
     651           2 :     switch (nTxtTyp)
     652             :     {
     653             :         case TXT_MAINTEXT:
     654           1 :             pfc = &rWrt.pFib->fcPlcffldMom;
     655           1 :             plc = &rWrt.pFib->lcbPlcffldMom;
     656           1 :             break;
     657             :         case TXT_HDFT:
     658           0 :             pfc = &rWrt.pFib->fcPlcffldHdr;
     659           0 :             plc = &rWrt.pFib->lcbPlcffldHdr;
     660           0 :             break;
     661             : 
     662             :         case TXT_FTN:
     663           0 :             pfc = &rWrt.pFib->fcPlcffldFtn;
     664           0 :             plc = &rWrt.pFib->lcbPlcffldFtn;
     665           0 :             break;
     666             : 
     667             :         case TXT_EDN:
     668           0 :             pfc = &rWrt.pFib->fcPlcffldEdn;
     669           0 :             plc = &rWrt.pFib->lcbPlcffldEdn;
     670           0 :             break;
     671             : 
     672             :         case TXT_ATN:
     673           0 :             pfc = &rWrt.pFib->fcPlcffldAtn;
     674           0 :             plc = &rWrt.pFib->lcbPlcffldAtn;
     675           0 :             break;
     676             : 
     677             :         case TXT_TXTBOX:
     678           1 :             pfc = &rWrt.pFib->fcPlcffldTxbx;
     679           1 :             plc = &rWrt.pFib->lcbPlcffldTxbx;
     680           1 :             break;
     681             : 
     682             :         case TXT_HFTXTBOX:
     683           0 :             pfc = &rWrt.pFib->fcPlcffldHdrTxbx;
     684           0 :             plc = &rWrt.pFib->lcbPlcffldHdrTxbx;
     685           0 :             break;
     686             : 
     687             :         default:
     688           0 :             pfc = plc = 0;
     689           0 :             break;
     690             :     }
     691             : 
     692           2 :     if( pfc && plc )
     693             :     {
     694           2 :         sal_uLong nFcStart = rWrt.pTableStrm->Tell();
     695           2 :         WW8_WrPlc1::Write( *rWrt.pTableStrm );
     696           2 :         *pfc = nFcStart;
     697           2 :         *plc = rWrt.pTableStrm->Tell() - nFcStart;
     698             :     }
     699           2 :     return true;
     700             : }
     701             : 
     702           8 : bool WW8_WrMagicTable::Write( WW8Export& rWrt )
     703             : {
     704           8 :     if( WW8_WrPlc1::Count() <= 1 )
     705           0 :         return false;
     706           8 :     sal_uLong nFcStart = rWrt.pTableStrm->Tell();
     707           8 :     WW8_WrPlc1::Write( *rWrt.pTableStrm );
     708           8 :     rWrt.pFib->fcPlcfTch = nFcStart;
     709           8 :     rWrt.pFib->lcbPlcfTch = rWrt.pTableStrm->Tell() - nFcStart;
     710           8 :     return true;
     711             : }
     712             : 
     713           8 : void WW8_WrMagicTable::Append( WW8_CP nCp, sal_uLong nData)
     714             : {
     715             :     SVBT32 nLittle;
     716             :     /*
     717             :     Tell the undocumented table hack that everything between here and the last
     718             :     table position is nontable text, don't do it if the previous position is
     719             :     the same as this one, as that would be a region of 0 length
     720             :     */
     721           8 :     if ((!Count()) || (Prev() != nCp))
     722             :     {
     723           8 :         UInt32ToSVBT32(nData,nLittle);
     724           8 :         WW8_WrPlc1::Append(nCp, nLittle);
     725             :     }
     726           8 : }
     727             : 
     728             : //--------------------------------------------------------------------------
     729             : 
     730         106 : void SwWW8Writer::FillCount( SvStream& rStrm, sal_uLong nCount )
     731             : {
     732             :     static const sal_uInt32 aNulls[16] =
     733             :     {
     734             :         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 // 64 Byte
     735             :     };
     736             : 
     737         501 :     while (nCount > 64)
     738             :     {
     739         289 :         rStrm.Write( aNulls, 64 );          // in steps of 64-Byte
     740         289 :         nCount -= 64;
     741             :     }
     742         106 :     rStrm.Write( aNulls, nCount );          // write the rest ( 0 .. 64 Bytes )
     743         106 : }
     744             : 
     745          24 : sal_uLong SwWW8Writer::FillUntil( SvStream& rStrm, sal_uLong nEndPos )
     746             : {
     747          24 :     sal_uLong nCurPos = rStrm.Tell();
     748          24 :     if( !nEndPos )                          // nEndPos == 0 -> next Page
     749          16 :         nEndPos = (nCurPos + 0x1ff) & ~0x1ffUL;
     750             : 
     751          24 :     if( nEndPos > nCurPos )
     752          16 :         SwWW8Writer::FillCount( rStrm, nEndPos - nCurPos );
     753             : #if OSL_DEBUG_LEVEL > 0
     754             :     else
     755             :         OSL_ENSURE( nEndPos == nCurPos, "Falsches FillUntil()" );
     756             : #endif
     757          24 :     return rStrm.Tell();
     758             : }
     759             : 
     760             : 
     761             : //--------------------------------------------------------------------------
     762             : 
     763          16 : WW8_WrPlcPn::WW8_WrPlcPn( WW8Export& rWr, ePLCFT ePl, WW8_FC nStartFc )
     764          16 :     : rWrt(rWr), nFkpStartPage(0), ePlc(ePl), nMark(0)
     765             : {
     766          16 :     WW8_WrFkp* pF = new WW8_WrFkp( ePlc, nStartFc, rWrt.bWrtWW8 );
     767          16 :     aFkps.push_back( pF );
     768          16 : }
     769             : 
     770          16 : WW8_WrPlcPn::~WW8_WrPlcPn()
     771             : {
     772          16 : }
     773             : 
     774           8 : sal_uInt8 *WW8_WrPlcPn::CopyLastSprms(sal_uInt8 &rLen)
     775             : {
     776           8 :     WW8_WrFkp& rF = aFkps.back();
     777           8 :     return rF.CopyLastSprms(rLen, rWrt.bWrtWW8);
     778             : }
     779             : 
     780         849 : void WW8_WrPlcPn::AppendFkpEntry(WW8_FC nEndFc,short nVarLen,const sal_uInt8* pSprms)
     781             : {
     782         849 :     WW8_WrFkp* pF = &aFkps.back();
     783             : 
     784             :     // big sprm? build the sprmPHugePapx
     785         849 :     sal_uInt8* pNewSprms = (sal_uInt8*)pSprms;
     786             :     sal_uInt8 aHugePapx[ 8 ];
     787         849 :     if( rWrt.bWrtWW8 && PAP == ePlc && 488 < nVarLen )
     788             :     {
     789           3 :         sal_uInt8* p = aHugePapx;
     790           3 :         *p++ = *pSprms++;           // set style Id
     791           3 :         *p++ = *pSprms++;
     792           3 :         nVarLen -= 2;
     793             : 
     794           3 :         long nDataPos = rWrt.pDataStrm->Tell();
     795           3 :         SwWW8Writer::WriteShort( *rWrt.pDataStrm, nVarLen );
     796           3 :         rWrt.pDataStrm->Write( pSprms, nVarLen );
     797             : 
     798           3 :         Set_UInt16( p, 0x6646 );    // set SprmCode
     799           3 :         Set_UInt32( p, nDataPos );  // set startpos (FC) in the datastream
     800           3 :         nVarLen = static_cast< short >(p - aHugePapx);
     801           3 :         pSprms = pNewSprms = aHugePapx;
     802             :     }
     803             :     // if append at the same FC-EndPos and there are sprms, then get the old
     804             :     // sprms and erase it; they will append now with the new sprms
     805         846 :     else if( nVarLen && pF->IsEqualPos( nEndFc ))
     806           1 :         pF->MergeToNew( nVarLen, pNewSprms );
     807             :     // has the prev EndFC an empty sprm and the current is empty too, then
     808             :     // expand only the old EndFc to the new EndFc
     809         845 :     else if( !nVarLen && pF->IsEmptySprm() )
     810             :     {
     811          69 :         pF->SetNewEnd( nEndFc );
     812          69 :         return ;
     813             :     }
     814             : 
     815         780 :     bool bOk = pF->Append(nEndFc, nVarLen, pNewSprms);
     816         780 :     if( !bOk )
     817             :     {
     818          35 :         pF->Combine();
     819          35 :         pF = new WW8_WrFkp( ePlc, pF->GetEndFc(), rWrt.bWrtWW8 ); // Start new Fkp == end of old Fkp
     820             : 
     821          35 :         aFkps.push_back( pF );
     822          35 :         if( !pF->Append( nEndFc, nVarLen, pNewSprms ) )
     823             :         {
     824             :             OSL_ENSURE( !this, "Sprm liess sich nicht einfuegen" );
     825             :         }
     826             :     }
     827         780 :     if( pNewSprms != pSprms )   //Merge to new has created a new block
     828           1 :         delete[] pNewSprms;
     829             : }
     830             : 
     831          16 : void WW8_WrPlcPn::WriteFkps()
     832             : {
     833          16 :     nFkpStartPage = (sal_uInt16) ( SwWW8Writer::FillUntil( rWrt.Strm() ) >> 9 );
     834             : 
     835          67 :     for( sal_uInt16 i = 0; i < aFkps.size(); i++ )
     836          51 :         aFkps[ i ].Write( rWrt.Strm(), *rWrt.pGrf );
     837             : 
     838          16 :     if( CHP == ePlc )
     839             :     {
     840           8 :         rWrt.pFib->pnChpFirst = nFkpStartPage;
     841           8 :         rWrt.pFib->cpnBteChp = aFkps.size();
     842             :     }
     843             :     else
     844             :     {
     845           8 :         rWrt.pFib->pnPapFirst = nFkpStartPage;
     846           8 :         rWrt.pFib->cpnBtePap = aFkps.size();
     847             :     }
     848          16 : }
     849             : 
     850          16 : void WW8_WrPlcPn::WritePlc()
     851             : {
     852          16 :     sal_uLong nFcStart = rWrt.pTableStrm->Tell();
     853             :     sal_uInt16 i;
     854             : 
     855          67 :     for( i = 0; i < aFkps.size(); i++ )
     856             :         SwWW8Writer::WriteLong( *rWrt.pTableStrm,
     857          51 :                                 aFkps[ i ].GetStartFc() );
     858             : 
     859             :     SwWW8Writer::WriteLong( *rWrt.pTableStrm,
     860          16 :                                 aFkps[ i - 1 ].GetEndFc() );
     861             : 
     862             :     // fuer jedes FKP die Page ausgeben
     863          16 :     if( rWrt.bWrtWW8)                   // for WW97 Long output
     864          67 :         for ( i = 0; i < aFkps.size(); i++)
     865          51 :             SwWW8Writer::WriteLong( *rWrt.pTableStrm, i + nFkpStartPage );
     866             :     else                            // for WW95 Short output
     867           0 :         for ( i = 0; i < aFkps.size(); i++)
     868           0 :             SwWW8Writer::WriteShort( *rWrt.pTableStrm, i + nFkpStartPage );
     869             : 
     870          16 :     if( CHP == ePlc )
     871             :     {
     872           8 :         rWrt.pFib->fcPlcfbteChpx = nFcStart;
     873           8 :         rWrt.pFib->lcbPlcfbteChpx = rWrt.pTableStrm->Tell() - nFcStart;
     874             :     }
     875             :     else
     876             :     {
     877           8 :         rWrt.pFib->fcPlcfbtePapx = nFcStart;
     878           8 :         rWrt.pFib->lcbPlcfbtePapx = rWrt.pTableStrm->Tell() - nFcStart;
     879             :     }
     880          16 : }
     881             : 
     882             : //--------------------------------------------------------------------------
     883             : 
     884          51 : WW8_WrFkp::WW8_WrFkp(ePLCFT ePl, WW8_FC nStartFc, bool bWrtWW8)
     885             :     : ePlc(ePl), nStartGrp(511), nOldStartGrp(511),
     886             :     nItemSize( ( CHP == ePl ) ? 1 : ( bWrtWW8 ? 13 : 7 )),
     887          51 :     nIMax(0), nOldVarLen(0), bCombined(false)
     888             : {
     889          51 :     pFkp = (sal_uInt8*)new sal_Int32[128];           // 512 Byte
     890          51 :     pOfs = (sal_uInt8*)new sal_Int32[128];           // 512 Byte
     891          51 :     memset( pFkp, 0, 4 * 128 );
     892          51 :     memset( pOfs, 0, 4 * 128 );
     893          51 :     ( (sal_Int32*)pFkp )[0] = nStartFc;         // 0th entry FC at nStartFc
     894          51 : }
     895             : 
     896          51 : WW8_WrFkp::~WW8_WrFkp()
     897             : {
     898          51 :     delete[] (sal_Int32 *)pFkp;
     899          51 :     delete[] (sal_Int32 *)pOfs;
     900          51 : }
     901             : 
     902         747 : sal_uInt8 WW8_WrFkp::SearchSameSprm( sal_uInt16 nVarLen, const sal_uInt8* pSprms )
     903             : {
     904         747 :     if( 3 < nVarLen )
     905             :     {
     906             :         // if the sprms contained picture-references then never equal!
     907       13675 :         for( sal_uInt8 n = static_cast< sal_uInt8 >(nVarLen - 1); 3 < n; --n )
     908       13067 :             if( pSprms[ n ] == GRF_MAGIC_3 &&
     909           3 :                 pSprms[ n-1 ] == GRF_MAGIC_2 &&
     910           0 :                 pSprms[ n-2 ] == GRF_MAGIC_1 )
     911           0 :                     return 0;
     912             :     }
     913             : 
     914             :     short i;
     915        7226 :     for( i = 0; i < nIMax; i++ )
     916             :     {
     917        6858 :         sal_uInt8 nStart = pOfs[i * nItemSize];
     918        6858 :         if( nStart )
     919             :         {                               // has Sprms
     920        6180 :             const sal_uInt8* p = pFkp + ( (sal_uInt16)nStart << 1 );
     921       12360 :             if( ( CHP == ePlc
     922        4013 :                     ? (*p++ == nVarLen)
     923        2167 :                     : (((sal_uInt16)*p++ << 1 ) == (( nVarLen+1) & 0xfffe)) )
     924       12360 :                 && !memcmp( p, pSprms, nVarLen ) )
     925         379 :                     return nStart;                      // found it
     926             :         }
     927             :     }
     928         368 :     return 0;           // didn't found it
     929             : }
     930             : 
     931           8 : sal_uInt8 *WW8_WrFkp::CopyLastSprms(sal_uInt8 &rLen, bool bVer8)
     932             : {
     933           8 :     rLen=0;
     934           8 :     sal_uInt8 *pStart=0,*pRet=0;
     935             : 
     936           8 :     if (!bCombined)
     937           8 :         pStart = pOfs;
     938             :     else
     939           0 :         pStart = pFkp + ( nIMax + 1 ) * 4;
     940             : 
     941           8 :     sal_uInt8 nStart = *(pStart + (nIMax-1) * nItemSize);
     942             : 
     943           8 :     const sal_uInt8* p = pFkp + ( (sal_uInt16)nStart << 1 );
     944             : 
     945           8 :     if (!*p && bVer8)
     946           6 :         p++;
     947             : 
     948           8 :     if (*p)
     949             :     {
     950           8 :         rLen = *p++;
     951           8 :         if (PAP == ePlc)
     952           8 :             rLen *= 2;
     953           8 :         pRet = new sal_uInt8[rLen];
     954           8 :         memcpy(pRet,p,rLen);
     955             :     }
     956           8 :     return pRet;
     957             : }
     958             : 
     959         815 : bool WW8_WrFkp::Append( WW8_FC nEndFc, sal_uInt16 nVarLen, const sal_uInt8* pSprms )
     960             : {
     961             :     OSL_ENSURE( !nVarLen || pSprms, "Item pointer missing" );
     962             :     OSL_ENSURE( nVarLen < ( ( ePlc == PAP ) ? 497U : 502U ), "Sprms too long !" );
     963             : 
     964         815 :     if( bCombined )
     965             :     {
     966             :         OSL_ENSURE( !this, "Fkp::Append: Fkp is already combined" );
     967           0 :         return false;
     968             :     }
     969         815 :     sal_Int32 n = ((sal_Int32*)pFkp)[nIMax];        // last entry
     970         815 :     if( nEndFc <= n )
     971             :     {
     972             :         OSL_ENSURE( nEndFc >= n, "+Fkp: FC backwards" );
     973             :         OSL_ENSURE( !nVarLen || !pSprms || nEndFc != n,
     974             :                                     "+Fkp: selber FC mehrfach benutzt" );
     975             :                         // selber FC ohne Sprm wird ohne zu mosern ignoriert.
     976             : 
     977           7 :         return true;    // ignore (do not create a new Fkp)
     978             :     }
     979             : 
     980         808 :     sal_uInt8 nOldP = ( nVarLen ) ? SearchSameSprm( nVarLen, pSprms ) : 0;
     981             :                                             // Combine equal entries
     982         808 :     short nOffset=0, nPos = nStartGrp;
     983         808 :     if (nVarLen && !nOldP)
     984             :     {
     985         368 :         nPos = PAP == ePlc
     986         308 :                 ? ( 13 == nItemSize     // HACK: PAP and bWrtWW8 !!
     987             :                      ? (nStartGrp & 0xFFFE ) - nVarLen - 1
     988             :                      : (nStartGrp - (((nVarLen + 1) & 0xFFFE)+1)) & 0xFFFE )
     989         676 :                 : ((nStartGrp - nVarLen - 1) & 0xFFFE);
     990         368 :         if( nPos < 0 )
     991           5 :             return false;           // doesn't fit at all
     992         363 :         nOffset = nPos;             // save offset (can also be uneven!)
     993         363 :         nPos &= 0xFFFE;             // Pos for Sprms ( gerade Pos )
     994             :     }
     995             : 
     996         803 :     if( (sal_uInt16)nPos <= ( nIMax + 2U ) * 4U + ( nIMax + 1U ) * nItemSize )
     997             :                                             // does it fits behind the CPs and offsets?
     998          30 :         return false;                       // no
     999             : 
    1000         773 :     ((sal_Int32*)pFkp)[nIMax + 1] = nEndFc;     // insert FC
    1001             : 
    1002         773 :     nOldVarLen = (sal_uInt8)nVarLen;
    1003         773 :     if( nVarLen && !nOldP )
    1004             :     {               // insert it for real
    1005         343 :         nOldStartGrp = nStartGrp;
    1006             : 
    1007         343 :         nStartGrp = nPos;
    1008         343 :         pOfs[nIMax * nItemSize] = (sal_uInt8)( nStartGrp >> 1 );
    1009             :                                             // ( DatenAnfg >> 1 ) insert
    1010         343 :         sal_uInt8 nCnt = static_cast< sal_uInt8 >(CHP == ePlc
    1011             :                         ? ( nVarLen < 256 ) ? (sal_uInt8) nVarLen : 255
    1012         343 :                         : ( ( nVarLen + 1 ) >> 1 ));
    1013             : 
    1014         343 :         pFkp[ nOffset ] = nCnt;                     // Enter data length
    1015         343 :         memcpy( pFkp + nOffset + 1, pSprms, nVarLen );  // store Sprms
    1016             :     }
    1017             :     else
    1018             :     {
    1019             :         // do not enter for real ( no Sprms or recurrence )
    1020             :         // DatenAnfg 0 ( no data ) or recurrence
    1021         430 :         pOfs[nIMax * nItemSize] = nOldP;
    1022             :     }
    1023         773 :     nIMax++;
    1024         773 :     return true;
    1025             : }
    1026             : 
    1027          86 : bool WW8_WrFkp::Combine()
    1028             : {
    1029          86 :     if( bCombined )
    1030          35 :         return false;
    1031          51 :     if( nIMax )
    1032          51 :         memcpy( pFkp + ( nIMax + 1 ) * 4, pOfs, nIMax * nItemSize );
    1033          51 :     delete[] pOfs;
    1034          51 :     pOfs = 0;
    1035          51 :     ((sal_uInt8*)pFkp)[511] = nIMax;
    1036          51 :     bCombined = true;
    1037             : 
    1038             : #if defined OSL_BIGENDIAN           // only the FCs will be rotated here
    1039             :     sal_uInt16 i;                   // the Sprms must be rotated elsewhere
    1040             : 
    1041             :     sal_uInt32* p;
    1042             :     for( i = 0, p = (sal_uInt32*)pFkp; i <= nIMax; i++, p++ )
    1043             :         *p = OSL_SWAPDWORD( *p );
    1044             : #endif // ifdef OSL_BIGENDIAN
    1045             : 
    1046          51 :     return true;
    1047             : }
    1048             : 
    1049          51 : void WW8_WrFkp::Write( SvStream& rStrm, SwWW8WrGrf& rGrf )
    1050             : {
    1051          51 :     Combine();                      // If not already combined
    1052             : 
    1053             :     sal_uInt8* p;               //  Suche Magic fuer nPicLocFc
    1054          51 :     sal_uInt8* pEnd = pFkp + nStartGrp;
    1055        9847 :     for( p = pFkp + 511 - 4; p >= pEnd; p-- )
    1056             :     {
    1057        9796 :         if( *p != GRF_MAGIC_1 )     // search for signature 0x12 0x34 0x56 0xXX
    1058       19543 :             continue;
    1059          49 :         if( *(p+1) != GRF_MAGIC_2 )
    1060          49 :             continue;
    1061           0 :         if( *(p+2) != GRF_MAGIC_3 )
    1062           0 :             continue;
    1063             : 
    1064             :         SVBT32 nPos;                // signature found
    1065           0 :         UInt32ToSVBT32( rGrf.GetFPos(), nPos );   // FilePos the graphics
    1066           0 :         memcpy( p, nPos, 4 );       // patch FilePos over the signature
    1067             :     }
    1068          51 :     rStrm.Write( pFkp, 512 );
    1069          51 : }
    1070             : 
    1071           1 : void WW8_WrFkp::MergeToNew( short& rVarLen, sal_uInt8 *& rpNewSprms )
    1072             : {
    1073           1 :     sal_uInt8 nStart = pOfs[ (nIMax-1) * nItemSize ];
    1074           1 :     if( nStart )
    1075             :     {   // has Sprms
    1076           1 :         sal_uInt8* p = pFkp + ( (sal_uInt16)nStart << 1 );
    1077             : 
    1078             :         // old and new equal? Then copy only one into the new sprms
    1079           1 :         if( nOldVarLen == rVarLen && !memcmp( p+1, rpNewSprms, nOldVarLen ))
    1080             :         {
    1081           0 :             sal_uInt8* pNew = new sal_uInt8[ nOldVarLen ];
    1082           0 :             memcpy( pNew, p+1, nOldVarLen );
    1083           0 :             rpNewSprms = pNew;
    1084             :         }
    1085             :         else
    1086             :         {
    1087           1 :             sal_uInt8* pNew = new sal_uInt8[ nOldVarLen + rVarLen ];
    1088           1 :             memcpy( pNew, p+1, nOldVarLen );
    1089           1 :             memcpy( pNew + nOldVarLen, rpNewSprms, rVarLen );
    1090             : 
    1091           1 :             rpNewSprms = pNew;
    1092           1 :             rVarLen = rVarLen + nOldVarLen;
    1093             :         }
    1094           1 :         --nIMax;
    1095             :         // if this sprms dont used from others, remove it
    1096           1 :         bool bFnd = false;
    1097          20 :         for (sal_uInt16 n = 0; n < nIMax; ++n)
    1098             :         {
    1099          20 :             if (nStart == pOfs[n * nItemSize])
    1100             :             {
    1101           1 :                 bFnd = true;
    1102           1 :                 break;
    1103             :             }
    1104             :         }
    1105           1 :         if (!bFnd)
    1106             :         {
    1107           0 :             nStartGrp = nOldStartGrp;
    1108           0 :             memset( p, 0, nOldVarLen+1 );
    1109             :         }
    1110             :     }
    1111           1 : }
    1112             : 
    1113             : #ifdef __WW8_NEEDS_COPY
    1114             : 
    1115          51 : WW8_FC WW8_WrFkp::GetStartFc() const
    1116             : {
    1117             : // wenn bCombined, dann ist das Array ab pFkp schon Bytemaessig auf LittleEndian
    1118             : // umgedreht, d.h. zum Herausholen der Anfangs- und Endpositionen muss
    1119             : // zurueckgedreht werden.
    1120          51 :     if( bCombined )
    1121          51 :         return SVBT32ToUInt32( pFkp );        // 0. Element
    1122           0 :     return ((sal_Int32*)pFkp)[0];
    1123             : }
    1124             : 
    1125          51 : WW8_FC WW8_WrFkp::GetEndFc() const
    1126             : {
    1127          51 :     if( bCombined )
    1128          51 :         return SVBT32ToUInt32( &(pFkp[nIMax*4]) );    // nIMax-tes SVBT32-Element
    1129           0 :     return ((sal_Int32*)pFkp)[nIMax];
    1130             : }
    1131             : 
    1132             : #endif // defined __WW8_NEEDS_COPY
    1133             : 
    1134             : 
    1135             : // Method for managing the piece table
    1136           8 : WW8_WrPct::WW8_WrPct(WW8_FC nfcMin, bool bSaveUniCode)
    1137           8 :     : nOldFc(nfcMin), bIsUni(bSaveUniCode)
    1138             : {
    1139           8 :     AppendPc( nOldFc, bIsUni );
    1140           8 : }
    1141             : 
    1142           8 : WW8_WrPct::~WW8_WrPct()
    1143             : {
    1144           8 : }
    1145             : 
    1146             : // Fill the piece and create a new one
    1147           8 : void WW8_WrPct::AppendPc(WW8_FC nStartFc, bool bIsUnicode)
    1148             : {
    1149           8 :     WW8_CP nStartCp = nStartFc - nOldFc;    // substract the beginning of the text
    1150           8 :     if ( !nStartCp )
    1151             :     {
    1152           8 :         if ( !aPcts.empty() )
    1153             :         {
    1154             :             OSL_ENSURE( 1 == aPcts.size(), "Leeres Piece !!");
    1155           0 :             aPcts.pop_back( );
    1156             :         }
    1157             :     }
    1158             : 
    1159           8 :     nOldFc = nStartFc;                      // remember StartFc as old
    1160             : 
    1161           8 :     if( bIsUni )
    1162           8 :         nStartCp >>= 1;                 // for Unicode: number of characters / 2
    1163             : 
    1164             : 
    1165           8 :     if ( !bIsUnicode )
    1166             :     {
    1167           0 :         nStartFc <<= 1;                 // Adress * 2
    1168           0 :         nStartFc |= 0x40000000;         // second last bit for non-Unicode
    1169             :     }
    1170             : 
    1171           8 :     if( !aPcts.empty() )
    1172           0 :         nStartCp += aPcts.back().GetStartCp();
    1173             : 
    1174           8 :     WW8_WrPc* pPc = new WW8_WrPc( nStartFc, nStartCp );
    1175           8 :     aPcts.push_back( pPc );
    1176             : 
    1177           8 :     bIsUni = bIsUnicode;
    1178           8 : }
    1179             : 
    1180             : 
    1181           8 : void WW8_WrPct::WritePc( WW8Export& rWrt )
    1182             : {
    1183             :     sal_uLong nPctStart;
    1184             :     sal_uLong nOldPos, nEndPos;
    1185           8 :     boost::ptr_vector<WW8_WrPc>::iterator aIter;
    1186             : 
    1187           8 :     nPctStart = rWrt.pTableStrm->Tell();                    // Start piece table
    1188           8 :     *rWrt.pTableStrm << ( char )0x02;                       // Status byte PCT
    1189           8 :     nOldPos = nPctStart + 1;                                // remember Position
    1190           8 :     SwWW8Writer::WriteLong( *rWrt.pTableStrm, 0 );          // then the length
    1191             : 
    1192          16 :     for( aIter = aPcts.begin(); aIter != aPcts.end(); ++aIter )     // ranges
    1193             :         SwWW8Writer::WriteLong( *rWrt.pTableStrm,
    1194           8 :                                 aIter->GetStartCp() );
    1195             : 
    1196             : 
    1197             :     // calculate the last Pos
    1198           8 :     sal_uLong nStartCp = rWrt.pFib->fcMac - nOldFc;
    1199           8 :     if( bIsUni )
    1200           8 :         nStartCp >>= 1;             // For Unicode: number of characters / 2
    1201           8 :     nStartCp += aPcts.back().GetStartCp();
    1202           8 :     SwWW8Writer::WriteLong( *rWrt.pTableStrm, nStartCp );
    1203             : 
    1204             :     // piece references
    1205          16 :     for ( aIter = aPcts.begin(); aIter != aPcts.end(); ++aIter )
    1206             :     {
    1207           8 :         SwWW8Writer::WriteShort( *rWrt.pTableStrm, aIter->GetStatus());
    1208           8 :         SwWW8Writer::WriteLong( *rWrt.pTableStrm, aIter->GetStartFc());
    1209           8 :         SwWW8Writer::WriteShort( *rWrt.pTableStrm, 0);          // PRM=0
    1210             :     }
    1211             : 
    1212             :     // entries in the FIB
    1213           8 :     rWrt.pFib->fcClx = nPctStart;
    1214           8 :     nEndPos = rWrt.pTableStrm->Tell();
    1215           8 :     rWrt.pFib->lcbClx = nEndPos - nPctStart;
    1216             : 
    1217             :     // and register the length as well
    1218             :     SwWW8Writer::WriteLong( *rWrt.pTableStrm, nOldPos,
    1219           8 :                             nEndPos - nPctStart-5 );
    1220             : 
    1221           8 : }
    1222             : 
    1223         367 : void WW8_WrPct::SetParaBreak()
    1224             : {
    1225             :     OSL_ENSURE( !aPcts.empty(),"SetParaBreak : aPcts.empty()" );
    1226         367 :     aPcts.back().SetStatus();
    1227         367 : }
    1228             : 
    1229         164 : WW8_CP WW8_WrPct::Fc2Cp( sal_uLong nFc ) const
    1230             : {
    1231             :     OSL_ENSURE( nFc >= (sal_uLong)nOldFc, "FilePos lies in front of last piece" );
    1232             :     OSL_ENSURE( ! aPcts.empty(), "Fc2Cp no piece available" );
    1233             : 
    1234         164 :     nFc -= nOldFc;
    1235         164 :     if( bIsUni )
    1236         164 :         nFc /= 2;
    1237         164 :     return nFc + aPcts.back().GetStartCp();
    1238             : }
    1239             : 
    1240             : //--------------------------------------------------------------------------
    1241             : 
    1242           8 : WW8_WrtBookmarks::WW8_WrtBookmarks()
    1243             : {
    1244           8 : }
    1245             : 
    1246           8 : WW8_WrtBookmarks::~WW8_WrtBookmarks()
    1247             : {
    1248           8 : }
    1249             : 
    1250           4 : void WW8_WrtBookmarks::Append( WW8_CP nStartCp, const String& rNm,  const ::sw::mark::IMark* )
    1251             : {
    1252           4 :     BkmIter bkIter = GetPos( rNm );
    1253           4 :     if( bkIter == aBookmarks.end() )
    1254             :     {
    1255             :         // new bookmark -> insert with start==end
    1256           2 :         aBookmarks.push_back( BookmarkInfo(nStartCp, nStartCp, false, rNm) );
    1257             :     }
    1258             :     else
    1259             :     {
    1260             :         // old bookmark -> this should be the end position
    1261             :         OSL_ENSURE( bkIter->endPos == bkIter->startPos, "end position is valid" );
    1262             : 
    1263             :         //If this bookmark was around a field in writer, then we want to move
    1264             :         //it to the field result in word. The end is therefore one cp
    1265             :         //backwards from the 0x15 end mark that was inserted.
    1266           2 :         if (bkIter->isField)
    1267           0 :             --nStartCp;
    1268           2 :         bkIter->endPos = nStartCp;
    1269             :     }
    1270           4 : }
    1271             : 
    1272             : 
    1273           8 : void WW8_WrtBookmarks::Write( WW8Export& rWrt )
    1274             : {
    1275           8 :     if (!aBookmarks.empty())
    1276             :     {
    1277             :         //Make sure the bookmarks are sorted in order of start position.
    1278           1 :         std::sort(aBookmarks.begin(), aBookmarks.end());
    1279             : 
    1280             :         // First write the Bookmark Name Stringtable
    1281           1 :         std::vector<OUString> aNames;
    1282           1 :         aNames.reserve(aBookmarks.size());
    1283           3 :         for (BkmIter bIt = aBookmarks.begin(); bIt < aBookmarks.end(); ++bIt)
    1284           2 :             aNames.push_back(bIt->name);
    1285           1 :         rWrt.WriteAsStringTable(aNames, rWrt.pFib->fcSttbfbkmk, rWrt.pFib->lcbSttbfbkmk);
    1286             : 
    1287             :         // Second write the Bookmark start positions as pcf of longs
    1288           1 :         SvStream& rStrm = rWrt.bWrtWW8 ? *rWrt.pTableStrm : rWrt.Strm();
    1289           1 :         rWrt.pFib->fcPlcfbkf = rStrm.Tell();
    1290           3 :         for (BkmIter bIt = aBookmarks.begin(); bIt < aBookmarks.end(); ++bIt)
    1291           2 :             SwWW8Writer::WriteLong( rStrm, bIt->startPos );
    1292           1 :         SwWW8Writer::WriteLong(rStrm, rWrt.pFib->ccpText + rWrt.pFib->ccpTxbx);
    1293             : 
    1294             :         //Lastly, need to write out the end positions (sorted by end position). But
    1295             :         //before that we need a lookup table (sorted by start position) to link
    1296             :         //start and end positions.
    1297             :         //   Start by sorting the end positions.
    1298           2 :         std::vector<sal_uLong> aEndSortTab;
    1299           1 :         aEndSortTab.reserve(aBookmarks.size());
    1300           3 :         for (BkmIter bIt = aBookmarks.begin(); bIt < aBookmarks.end(); ++bIt)
    1301           2 :             aEndSortTab.push_back(bIt->endPos);
    1302           1 :         std::sort(aEndSortTab.begin(), aEndSortTab.end());
    1303             : 
    1304             :         //Now write out the lookups.
    1305             :         //Note that in most cases, the positions in both vectors will be very close.
    1306           3 :         for( sal_uLong i = 0; i < aBookmarks.size(); ++i )
    1307             :         {
    1308           2 :             sal_uLong nEndCP = aBookmarks[ i ].endPos;
    1309           2 :             sal_uInt16 nPos = i;
    1310           2 :             if( aEndSortTab[ nPos ] > nEndCP )
    1311             :             {
    1312           0 :                 while( aEndSortTab[ --nPos ] != nEndCP )
    1313             :                     ;
    1314             :             }
    1315           2 :             else if( aEndSortTab[ nPos ] < nEndCP )
    1316           0 :                 while( aEndSortTab[ ++nPos ] != nEndCP )
    1317             :                     ;
    1318           2 :             SwWW8Writer::WriteLong( rStrm, nPos );
    1319             :         }
    1320           1 :         rWrt.pFib->lcbPlcfbkf = rStrm.Tell() - rWrt.pFib->fcPlcfbkf;
    1321             : 
    1322             :         // Finally, the actual Bookmark end positions.
    1323           1 :         rWrt.pFib->fcPlcfbkl = rStrm.Tell();
    1324           3 :         for(sal_uLong i = 0; i < aEndSortTab.size(); ++i )
    1325           2 :             SwWW8Writer::WriteLong( rStrm, aEndSortTab[ i ] );
    1326           1 :         SwWW8Writer::WriteLong(rStrm, rWrt.pFib->ccpText + rWrt.pFib->ccpTxbx);
    1327           2 :         rWrt.pFib->lcbPlcfbkl = rStrm.Tell() - rWrt.pFib->fcPlcfbkl;
    1328             :     }
    1329           8 : }
    1330             : 
    1331           4 : WW8_WrtBookmarks::BkmIter WW8_WrtBookmarks::GetPos( const String& rNm )
    1332             : {
    1333           6 :     for (BkmIter bIt = aBookmarks.begin(); bIt < aBookmarks.end(); ++bIt) {
    1334           4 :         if (rNm == bIt->name)
    1335           2 :             return bIt;
    1336             :     }
    1337           2 :     return aBookmarks.end();
    1338             : }
    1339             : 
    1340           0 : void WW8_WrtBookmarks::MoveFieldMarks(sal_uLong nFrom, sal_uLong nTo)
    1341             : {
    1342           0 :     for (BkmIter i = aBookmarks.begin(); i < aBookmarks.end(); ++i)
    1343             :     {
    1344           0 :         if (i->startPos == nFrom)
    1345             :         {
    1346           0 :             i->startPos = nTo;
    1347           0 :             if (i->endPos == nFrom)
    1348             :             {
    1349           0 :                 i->isField = true;
    1350           0 :                 i->endPos = nTo;
    1351             :             }
    1352             :         }
    1353             :     }
    1354           0 : }
    1355             : 
    1356         622 : void WW8Export::AppendBookmarks( const SwTxtNode& rNd,
    1357             :     xub_StrLen nAktPos, xub_StrLen nLen )
    1358             : {
    1359         622 :     std::vector< const ::sw::mark::IMark* > aArr;
    1360             :     sal_uInt16 nCntnt;
    1361         622 :     xub_StrLen nAktEnd = nAktPos + nLen;
    1362         622 :     if( GetWriter().GetBookmarks( rNd, nAktPos, nAktEnd, aArr ))
    1363             :     {
    1364           2 :         sal_uLong nNd = rNd.GetIndex(), nSttCP = Fc2Cp( Strm().Tell() );
    1365           6 :         for( sal_uInt16 n = 0; n < aArr.size(); ++n )
    1366             :         {
    1367           4 :             const ::sw::mark::IMark& rBkmk = *(aArr[ n ]);
    1368           4 :             if(dynamic_cast< const ::sw::mark::IFieldmark *>(&rBkmk))
    1369           0 :                 continue;
    1370             : 
    1371           4 :             const SwPosition* pPos = &rBkmk.GetMarkPos();
    1372           4 :             const SwPosition* pOPos = 0;
    1373           4 :             if(rBkmk.IsExpanded())
    1374           4 :                 pOPos = &rBkmk.GetOtherMarkPos();
    1375           8 :             if( pOPos && pOPos->nNode == pPos->nNode &&
    1376           4 :                 pOPos->nContent < pPos->nContent )
    1377             :             {
    1378           0 :                 pPos = pOPos;
    1379           0 :                 pOPos = &rBkmk.GetMarkPos();
    1380             :             }
    1381             : 
    1382          10 :             if( !pOPos || ( nNd == pPos->nNode.GetIndex() &&
    1383           6 :                 ( nCntnt = pPos->nContent.GetIndex() ) >= nAktPos &&
    1384             :                 nCntnt < nAktEnd ) )
    1385             :             {
    1386           2 :                 sal_uLong nCp = nSttCP + pPos->nContent.GetIndex() - nAktPos;
    1387           2 :                 pBkmks->Append(nCp, BookmarkToWord(rBkmk.GetName()), &rBkmk);
    1388             :             }
    1389          12 :             if( pOPos && nNd == pOPos->nNode.GetIndex() &&
    1390          12 :                 ( nCntnt = pOPos->nContent.GetIndex() ) >= nAktPos &&
    1391             :                 nCntnt < nAktEnd )
    1392             :             {
    1393           2 :                 sal_uLong nCp = nSttCP + pOPos->nContent.GetIndex() - nAktPos;
    1394           2 :                 pBkmks->Append(nCp, BookmarkToWord(rBkmk.GetName()), &rBkmk);
    1395             :             }
    1396             :         }
    1397         622 :     }
    1398         622 : }
    1399             : 
    1400           0 : void WW8Export::MoveFieldMarks(sal_uLong nFrom, sal_uLong nTo)
    1401             : {
    1402           0 :     pBkmks->MoveFieldMarks(nFrom, nTo);
    1403           0 : }
    1404             : 
    1405           0 : void WW8Export::AppendBookmark( const OUString& rName, bool bSkip )
    1406             : {
    1407           0 :     sal_uLong nSttCP = Fc2Cp( Strm().Tell() ) + ( bSkip? 1: 0 );
    1408           0 :     pBkmks->Append( nSttCP, rName );
    1409           0 : }
    1410             : 
    1411             : // #i120928 collect all the graphics of bullets applied to paragraphs
    1412          57 : int MSWordExportBase::CollectGrfsOfBullets()
    1413             : {
    1414          57 :     m_vecBulletPic.clear();
    1415             : 
    1416          57 :     if ( pDoc )
    1417             :     {
    1418          57 :         int nCountRule = pDoc->GetNumRuleTbl().size();
    1419         121 :         for (int n = 0; n < nCountRule; ++n)
    1420             :         {
    1421          64 :             const SwNumRule &rRule = *( pDoc->GetNumRuleTbl().at(n) );
    1422          64 :             sal_uInt16 nLevels = rRule.IsContinusNum() ? 1 : 9;
    1423         624 :             for (sal_uInt16 nLvl = 0; nLvl < nLevels; ++nLvl)
    1424             :             {
    1425         560 :                 const SwNumFmt &rFmt = rRule.Get(nLvl);
    1426         560 :                 if (SVX_NUM_BITMAP != rFmt.GetNumberingType())
    1427             :                 {
    1428         558 :                     continue;
    1429             :                 }
    1430           2 :                 const Graphic *pGraf = rFmt.GetBrush()? rFmt.GetBrush()->GetGraphic():0;
    1431           2 :                 if ( pGraf )
    1432             :                 {
    1433           2 :                     bool bHas = false;
    1434           2 :                     for (unsigned i = 0; i < m_vecBulletPic.size(); ++i)
    1435             :                     {
    1436           0 :                         if (m_vecBulletPic[i]->GetChecksum() == pGraf->GetChecksum())
    1437             :                         {
    1438           0 :                             bHas = true;
    1439           0 :                             break;
    1440             :                         }
    1441             :                     }
    1442           2 :                     if (!bHas)
    1443             :                     {
    1444           2 :                         m_vecBulletPic.push_back(pGraf);
    1445             :                     }
    1446             :                 }
    1447             :             }
    1448             :         }
    1449             :     }
    1450             : 
    1451          57 :     return m_vecBulletPic.size();
    1452             : }
    1453             : 
    1454           2 : void MSWordExportBase::BulletDefinitions()
    1455             : {
    1456           4 :     for (size_t i = 0; i < m_vecBulletPic.size(); ++i)
    1457             :     {
    1458           2 :         const MapMode aMapMode(MAP_TWIP);
    1459           2 :         const Graphic& rGraphic = *m_vecBulletPic[i];
    1460           2 :         Size aSize(rGraphic.GetPrefSize());
    1461           2 :         if (MAP_PIXEL == rGraphic.GetPrefMapMode().GetMapUnit())
    1462           0 :             aSize = Application::GetDefaultDevice()->PixelToLogic(aSize, aMapMode);
    1463             :         else
    1464           2 :             aSize = OutputDevice::LogicToLogic(aSize,rGraphic.GetPrefMapMode(), aMapMode);
    1465           2 :         AttrOutput().BulletDefinition(i, rGraphic, aSize);
    1466           2 :     }
    1467           2 : }
    1468             : 
    1469             : //Export Graphic of Bullets
    1470           8 : void WW8Export::ExportGrfBullet(const SwTxtNode& rNd)
    1471             : {
    1472           8 :     int nCount = CollectGrfsOfBullets();
    1473           8 :     if (nCount > 0)
    1474             :     {
    1475           0 :         SwPosition aPos(rNd);
    1476           0 :         OUString aPicBullets("_PictureBullets");
    1477           0 :         AppendBookmark(aPicBullets);
    1478           0 :         for (int i = 0; i < nCount; i++)
    1479             :         {
    1480           0 :             sw::Frame aFrame(*(m_vecBulletPic[i]), aPos);
    1481           0 :             OutGrfBullets(aFrame);
    1482           0 :         }
    1483           0 :         AppendBookmark(aPicBullets);
    1484             :     }
    1485           8 : }
    1486             : 
    1487             : static sal_uInt8 nAttrMagicIdx = 0;
    1488           0 : void WW8Export::OutGrfBullets(const sw::Frame & rFrame)
    1489             : {
    1490           0 :     if ( !pGrf || !pChpPlc || !pO )
    1491           0 :         return;
    1492             : 
    1493           0 :     pGrf->Insert(rFrame);
    1494           0 :     pChpPlc->AppendFkpEntry( Strm().Tell(), pO->size(), pO->data() );
    1495           0 :     pO->clear();
    1496             :     //if links...
    1497           0 :     WriteChar( (char)1 );
    1498             : 
    1499             :     sal_uInt8 aArr[ 22 ];
    1500           0 :     sal_uInt8* pArr = aArr;
    1501             : 
    1502             :     // sprmCFSpec
    1503           0 :     if( bWrtWW8 )
    1504           0 :         Set_UInt16( pArr, 0x855 );
    1505             :     else
    1506           0 :         Set_UInt8( pArr, 117 );
    1507           0 :     Set_UInt8( pArr, 1 );
    1508             : 
    1509           0 :     Set_UInt16( pArr, 0x083c );
    1510           0 :     Set_UInt8( pArr, 0x81 );
    1511             : 
    1512             :     // sprmCPicLocation
    1513           0 :     if( bWrtWW8 )
    1514           0 :         Set_UInt16( pArr, 0x6a03 );
    1515             :     else
    1516             :     {
    1517           0 :         Set_UInt8( pArr, 68 );
    1518           0 :         Set_UInt8( pArr, 4 );
    1519             :     }
    1520           0 :     Set_UInt32( pArr, GRF_MAGIC_321 );
    1521             : 
    1522             :     //extern  nAttrMagicIdx;
    1523           0 :     --pArr;
    1524           0 :     Set_UInt8( pArr, nAttrMagicIdx++ );
    1525           0 :     pChpPlc->AppendFkpEntry( Strm().Tell(), static_cast< short >(pArr - aArr), aArr );
    1526             : }
    1527             : 
    1528           2 : int MSWordExportBase::GetGrfIndex(const SvxBrushItem& rBrush)
    1529             : {
    1530           2 :     int nIndex = -1;
    1531           2 :     if ( rBrush.GetGraphic() )
    1532             :     {
    1533           2 :         for (unsigned i = 0; i < m_vecBulletPic.size(); ++i)
    1534             :         {
    1535           2 :             if (m_vecBulletPic[i]->GetChecksum() == rBrush.GetGraphic()->GetChecksum())
    1536             :             {
    1537           2 :                 nIndex = i;
    1538           2 :                 break;
    1539             :             }
    1540             :         }
    1541             :     }
    1542             : 
    1543           2 :     return nIndex;
    1544             : }
    1545             : 
    1546           0 : void MSWordExportBase::AppendWordBookmark( const String& rName )
    1547             : {
    1548           0 :     AppendBookmark( BookmarkToWord( rName ) );
    1549           0 : }
    1550             : 
    1551             : 
    1552             : //--------------------------------------------------------------------------
    1553             : 
    1554           0 : void WW8_WrtRedlineAuthor::Write( Writer& rWrt )
    1555             : {
    1556           0 :     WW8Export & rWW8Wrt = *(((SwWW8Writer&)rWrt).m_pExport);
    1557             :     rWW8Wrt.WriteAsStringTable(maAuthors, rWW8Wrt.pFib->fcSttbfRMark,
    1558           0 :         rWW8Wrt.pFib->lcbSttbfRMark, rWW8Wrt.bWrtWW8 ? 0 : 2);
    1559           0 : }
    1560             : 
    1561           0 : sal_uInt16 WW8Export::AddRedlineAuthor( sal_uInt16 nId )
    1562             : {
    1563           0 :     if( !pRedlAuthors )
    1564             :     {
    1565           0 :         pRedlAuthors = new WW8_WrtRedlineAuthor;
    1566           0 :         pRedlAuthors->AddName(OUString("Unknown"));
    1567             :     }
    1568           0 :     return pRedlAuthors->AddName( SW_MOD()->GetRedlineAuthor( nId ) );
    1569             : }
    1570             : 
    1571             : //--------------------------------------------------------------------------
    1572             : 
    1573           6 : void WW8Export::WriteAsStringTable(const std::vector<OUString>& rStrings,
    1574             :     sal_Int32& rfcSttbf, sal_Int32& rlcbSttbf, sal_uInt16 nExtraLen)
    1575             : {
    1576           6 :     sal_uInt16 n, nCount = static_cast< sal_uInt16 >(rStrings.size());
    1577           6 :     if( nCount )
    1578             :     {
    1579             :         // we have some Redlines found in the document -> the
    1580             :         // Author Name Stringtable
    1581           5 :         SvStream& rStrm = bWrtWW8 ? *pTableStrm : Strm();
    1582           5 :         rfcSttbf = rStrm.Tell();
    1583           5 :         if( bWrtWW8 )
    1584             :         {
    1585           5 :             SwWW8Writer::WriteShort( rStrm, -1 );
    1586           5 :             SwWW8Writer::WriteLong( rStrm, nCount );
    1587          79 :             for( n = 0; n < nCount; ++n )
    1588             :             {
    1589          74 :                 const String& rNm = rStrings[n];
    1590          74 :                 SwWW8Writer::WriteShort( rStrm, rNm.Len() );
    1591          74 :                 SwWW8Writer::WriteString16(rStrm, rNm, false);
    1592          74 :                 if( nExtraLen )
    1593           0 :                     SwWW8Writer::FillCount(rStrm, nExtraLen);
    1594          74 :             }
    1595             :         }
    1596             :         else
    1597             :         {
    1598           0 :             SwWW8Writer::WriteShort( rStrm, 0 );
    1599           0 :             for( n = 0; n < nCount; ++n )
    1600             :             {
    1601           0 :                 const OUString &rString = rStrings[n];
    1602           0 :                 const String aNm(rString.copy(0, std::min<sal_Int32>(rString.getLength(), 255)));
    1603           0 :                 rStrm << (sal_uInt8)aNm.Len();
    1604             :                 SwWW8Writer::WriteString8(rStrm, aNm, false,
    1605           0 :                     RTL_TEXTENCODING_MS_1252);
    1606           0 :                 if (nExtraLen)
    1607           0 :                     SwWW8Writer::FillCount(rStrm, nExtraLen);
    1608           0 :             }
    1609             :         }
    1610           5 :         rlcbSttbf = rStrm.Tell() - rfcSttbf;
    1611           5 :         if( !bWrtWW8 )
    1612           0 :             SwWW8Writer::WriteShort( rStrm, rfcSttbf, (sal_uInt16)rlcbSttbf );
    1613             :     }
    1614           6 : }
    1615             : 
    1616             : // WriteShort() traegt an FilePos nPos den Wert nVal ein und seekt auf die
    1617             : // alte FilePos zurueck. Benutzt zum Nachtragen von Laengen.
    1618           8 : void SwWW8Writer::WriteShort( SvStream& rStrm, sal_uLong nPos, sal_Int16 nVal )
    1619             : {
    1620           8 :     sal_uLong nOldPos = rStrm.Tell();       // remember Pos
    1621           8 :     rStrm.Seek( nPos );
    1622           8 :     SwWW8Writer::WriteShort( rStrm, nVal );
    1623           8 :     rStrm.Seek( nOldPos );
    1624           8 : }
    1625             : 
    1626          19 : void SwWW8Writer::WriteLong( SvStream& rStrm, sal_uLong nPos, sal_Int32 nVal )
    1627             : {
    1628          19 :     sal_uLong nOldPos = rStrm.Tell();       // remember Pos
    1629          19 :     rStrm.Seek( nPos );
    1630          19 :     SwWW8Writer::WriteLong( rStrm, nVal );
    1631          19 :     rStrm.Seek( nOldPos );
    1632          19 : }
    1633             : 
    1634       13788 : void SwWW8Writer::InsUInt16(ww::bytes &rO, sal_uInt16 n)
    1635             : {
    1636             :     SVBT16 nL;
    1637       13788 :     ShortToSVBT16( n, nL );
    1638       13788 :     rO.push_back(nL[0]);
    1639       13788 :     rO.push_back(nL[1]);
    1640       13788 : }
    1641             : 
    1642         775 : void SwWW8Writer::InsUInt32(ww::bytes &rO, sal_uInt32 n)
    1643             : {
    1644             :     SVBT32 nL;
    1645         775 :     UInt32ToSVBT32( n, nL );
    1646         775 :     rO.push_back(nL[0]);
    1647         775 :     rO.push_back(nL[1]);
    1648         775 :     rO.push_back(nL[2]);
    1649         775 :     rO.push_back(nL[3]);
    1650         775 : }
    1651             : 
    1652         534 : void SwWW8Writer::InsAsString16(ww::bytes &rO, const String& rStr)
    1653             : {
    1654         534 :     const sal_Unicode* pStr = rStr.GetBuffer();
    1655        7198 :     for( xub_StrLen n = 0, nLen = rStr.Len(); n < nLen; ++n, ++pStr )
    1656        6664 :         SwWW8Writer::InsUInt16( rO, *pStr );
    1657         534 : }
    1658             : 
    1659           0 : void SwWW8Writer::InsAsString8(ww::bytes &rO, const String& rStr,
    1660             :         rtl_TextEncoding eCodeSet)
    1661             : {
    1662           0 :     OString sTmp(OUStringToOString(rStr, eCodeSet));
    1663           0 :     const sal_Char *pStart = sTmp.getStr();
    1664           0 :     const sal_Char *pEnd = pStart + sTmp.getLength();
    1665           0 :     rO.reserve(rO.size() + sTmp.getLength());
    1666             : 
    1667           0 :     std::copy(pStart, pEnd, std::inserter(rO, rO.end()));
    1668           0 : }
    1669             : 
    1670         360 : void SwWW8Writer::WriteString16(SvStream& rStrm, const String& rStr,
    1671             :     bool bAddZero)
    1672             : {
    1673         360 :     ww::bytes aBytes;
    1674         360 :     SwWW8Writer::InsAsString16(aBytes, rStr);
    1675         360 :     if (bAddZero)
    1676         101 :         SwWW8Writer::InsUInt16(aBytes, 0);
    1677             :     //vectors are guaranteed to have contiguous memory, so we can do
    1678             :     //this while migrating away from WW8Bytes. Meyers Effective STL, item 16
    1679         360 :     if (!aBytes.empty())
    1680         277 :         rStrm.Write(&aBytes[0], aBytes.size());
    1681         360 : }
    1682             : 
    1683           0 : void SwWW8Writer::WriteString_xstz(SvStream& rStrm, const String& rStr, bool bAddZero)
    1684             : {
    1685           0 :     ww::bytes aBytes;
    1686           0 :     SwWW8Writer::InsUInt16(aBytes, rStr.Len());
    1687           0 :     SwWW8Writer::InsAsString16(aBytes, rStr);
    1688           0 :     if (bAddZero)
    1689           0 :         SwWW8Writer::InsUInt16(aBytes, 0);
    1690           0 :     rStrm.Write(&aBytes[0], aBytes.size());
    1691           0 : }
    1692             : 
    1693             : 
    1694           0 : void SwWW8Writer::WriteString8(SvStream& rStrm, const String& rStr,
    1695             :     bool bAddZero, rtl_TextEncoding eCodeSet)
    1696             : {
    1697           0 :     ww::bytes aBytes;
    1698           0 :     SwWW8Writer::InsAsString8(aBytes, rStr, eCodeSet);
    1699           0 :     if (bAddZero)
    1700           0 :         aBytes.push_back(0);
    1701             :     //vectors are guaranteed to have contiguous memory, so we can do
    1702             :     ////this while migrating away from WW8Bytes. Meyers Effective STL, item 16
    1703           0 :     if (!aBytes.empty())
    1704           0 :         rStrm.Write(&aBytes[0], aBytes.size());
    1705           0 : }
    1706             : 
    1707          61 : void WW8Export::WriteStringAsPara( const String& rTxt, sal_uInt16 nStyleId )
    1708             : {
    1709          61 :     if( rTxt.Len() )
    1710           0 :         OutSwString( rTxt, 0, rTxt.Len(), IsUnicode(), RTL_TEXTENCODING_MS_1252 );
    1711          61 :     WriteCR();              // CR thereafter
    1712             : 
    1713          61 :     ww::bytes aArr;
    1714          61 :     SwWW8Writer::InsUInt16( aArr, nStyleId );
    1715          61 :     if( bOutTable )
    1716             :     {                                               // Tab-Attr
    1717             :         // sprmPFInTable
    1718           0 :         if( bWrtWW8 )
    1719           0 :             SwWW8Writer::InsUInt16( aArr, NS_sprm::LN_PFInTable );
    1720             :         else
    1721           0 :             aArr.push_back( 24 );
    1722           0 :         aArr.push_back( 1 );
    1723             :     }
    1724             : 
    1725          61 :     sal_uLong nPos = Strm().Tell();
    1726          61 :     pPapPlc->AppendFkpEntry( nPos, aArr.size(), aArr.data() );
    1727          61 :     pChpPlc->AppendFkpEntry( nPos );
    1728          61 : }
    1729             : 
    1730          46 : void MSWordExportBase::WriteSpecialText( sal_uLong nStart, sal_uLong nEnd, sal_uInt8 nTTyp )
    1731             : {
    1732          46 :     sal_uInt8 nOldTyp = nTxtTyp;
    1733          46 :     nTxtTyp = nTTyp;
    1734          46 :     SwPaM* pOldPam = pCurPam;       //!! Simply shifting the PaM without restoring should do the job too
    1735          46 :     SwPaM* pOldEnd = pOrigPam;
    1736          46 :     bool bOldPageDescs = bOutPageDescs;
    1737          46 :     bOutPageDescs = false;
    1738             :                                     // bOutKF was setted / stored in WriteKF1
    1739          46 :     pCurPam = Writer::NewSwPaM( *pDoc, nStart, nEnd );
    1740             : 
    1741             :     // Tabelle in Sonderbereichen erkennen
    1742          47 :     if ( ( nStart != pCurPam->GetMark()->nNode.GetIndex() ) &&
    1743           1 :          pDoc->GetNodes()[ nStart ]->IsTableNode() )
    1744             :     {
    1745           1 :         pCurPam->GetMark()->nNode = nStart;
    1746             :     }
    1747             : 
    1748          46 :     pOrigPam = pCurPam;
    1749          46 :     pCurPam->Exchange();
    1750             : 
    1751          46 :     WriteText();
    1752             : 
    1753          46 :     bOutPageDescs = bOldPageDescs;
    1754          46 :     delete pCurPam;                    // delete Pam
    1755          46 :     pCurPam = pOldPam;
    1756          46 :     pOrigPam = pOldEnd;
    1757          46 :     nTxtTyp = nOldTyp;
    1758          46 : }
    1759             : 
    1760         161 : void WW8Export::OutSwString(const String& rStr, xub_StrLen nStt,
    1761             :     xub_StrLen nLen, bool bUnicode, rtl_TextEncoding eChrSet)
    1762             : 
    1763             : {
    1764             :     SAL_INFO( "sw.ww8.level2", "<OutSwString>" );
    1765             : 
    1766         161 :     if( nLen )
    1767             :     {
    1768         161 :         if ( bUnicode != pPiece->IsUnicode() )
    1769           0 :             pPiece->AppendPc ( Strm().Tell(), bUnicode );
    1770             : 
    1771         161 :         if( nStt || nLen != rStr.Len() )
    1772             :         {
    1773           0 :             String sOut( rStr.Copy( nStt, nLen ) );
    1774             : 
    1775             :             SAL_INFO( "sw.ww8.level2", sOut );
    1776             : 
    1777           0 :             if (bUnicode)
    1778           0 :                 SwWW8Writer::WriteString16(Strm(), sOut, false);
    1779             :             else
    1780           0 :                 SwWW8Writer::WriteString8(Strm(), sOut, false, eChrSet);
    1781             :         }
    1782             :         else
    1783             :         {
    1784             :             SAL_INFO( "sw.ww8.level2", rStr );
    1785             : 
    1786         161 :             if (bUnicode)
    1787         161 :                 SwWW8Writer::WriteString16(Strm(), rStr, false);
    1788             :             else
    1789           0 :                 SwWW8Writer::WriteString8(Strm(), rStr, false, eChrSet);
    1790             :         }
    1791             :     }
    1792             : 
    1793             :     SAL_INFO( "sw.ww8.level2", "</OutSwString>" );
    1794         161 : }
    1795             : 
    1796         366 : void WW8Export::WriteCR(ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner)
    1797             : {
    1798         366 :     if (pTableTextNodeInfoInner.get() != NULL && pTableTextNodeInfoInner->getDepth() == 1 && pTableTextNodeInfoInner->isEndOfCell())
    1799         118 :         WriteChar('\007');
    1800             :     else
    1801         248 :         WriteChar( '\015' );
    1802             : 
    1803         366 :     pPiece->SetParaBreak();
    1804         366 : }
    1805             : 
    1806         418 : void WW8Export::WriteChar( sal_Unicode c )
    1807             : {
    1808         418 :     if( pPiece->IsUnicode() )
    1809         418 :         Strm() << c;
    1810             :     else
    1811           0 :         Strm() << (sal_uInt8)c;
    1812         418 : }
    1813             : 
    1814          16 : void MSWordExportBase::SaveData( sal_uLong nStt, sal_uLong nEnd )
    1815             : {
    1816             :     MSWordSaveData aData;
    1817             : 
    1818             :     // WW8Export only stuff - zeroed here not to issue warnings
    1819          16 :     aData.pOOld = NULL;
    1820             : 
    1821             :     // Common stuff
    1822          16 :     aData.pOldPam = pCurPam;
    1823          16 :     aData.pOldEnd = pOrigPam;
    1824          16 :     aData.pOldFlyFmt = mpParentFrame;
    1825          16 :     aData.pOldPageDesc = pAktPageDesc;
    1826             : 
    1827          16 :     aData.pOldFlyOffset = pFlyOffset;
    1828          16 :     aData.eOldAnchorType = eNewAnchorType;
    1829             : 
    1830          16 :     aData.bOldOutTable = bOutTable;
    1831          16 :     aData.bOldFlyFrmAttrs = bOutFlyFrmAttrs;
    1832          16 :     aData.bOldStartTOX = bStartTOX;
    1833          16 :     aData.bOldInWriteTOX = bInWriteTOX;
    1834             : 
    1835          16 :     pCurPam = Writer::NewSwPaM( *pDoc, nStt, nEnd );
    1836             : 
    1837             :     // Recognize tables in special cases
    1838          16 :     if ( nStt != pCurPam->GetMark()->nNode.GetIndex() &&
    1839           0 :          pDoc->GetNodes()[ nStt ]->IsTableNode() )
    1840             :     {
    1841           0 :         pCurPam->GetMark()->nNode = nStt;
    1842             :     }
    1843             : 
    1844          16 :     pOrigPam = pCurPam;
    1845          16 :     pCurPam->Exchange();
    1846             : 
    1847          16 :     bOutTable = false;
    1848             :     // Caution: bIsInTable should not be set here
    1849          16 :     bOutFlyFrmAttrs = false;
    1850          16 :     bStartTOX = false;
    1851          16 :     bInWriteTOX = false;
    1852             : 
    1853          16 :     maSaveData.push( aData );
    1854          16 : }
    1855             : 
    1856          16 : void MSWordExportBase::RestoreData()
    1857             : {
    1858          16 :     MSWordSaveData &rData = maSaveData.top();
    1859             : 
    1860          16 :     delete pCurPam;
    1861          16 :     pCurPam = rData.pOldPam;
    1862          16 :     pOrigPam = rData.pOldEnd;
    1863             : 
    1864          16 :     bOutTable = rData.bOldOutTable;
    1865          16 :     bOutFlyFrmAttrs = rData.bOldFlyFrmAttrs;
    1866          16 :     bStartTOX = rData.bOldStartTOX;
    1867          16 :     bInWriteTOX = rData.bOldInWriteTOX;
    1868             : 
    1869          16 :     mpParentFrame = rData.pOldFlyFmt;
    1870          16 :     pAktPageDesc = rData.pOldPageDesc;
    1871             : 
    1872          16 :     eNewAnchorType = rData.eOldAnchorType;
    1873          16 :     pFlyOffset = rData.pOldFlyOffset;
    1874             : 
    1875          16 :     maSaveData.pop();
    1876          16 : }
    1877             : 
    1878           0 : void WW8Export::SaveData( sal_uLong nStt, sal_uLong nEnd )
    1879             : {
    1880           0 :     MSWordExportBase::SaveData( nStt, nEnd );
    1881             : 
    1882           0 :     MSWordSaveData &rData = maSaveData.top();
    1883             : 
    1884           0 :     if ( !pO->empty() )
    1885             :     {
    1886           0 :         rData.pOOld = pO;
    1887           0 :         pO = new ww::bytes();
    1888             :     }
    1889             :     else
    1890           0 :         rData.pOOld = 0; // reuse pO
    1891             : 
    1892           0 :     rData.bOldWriteAll = GetWriter().bWriteAll;
    1893           0 :     GetWriter().bWriteAll = true;
    1894           0 : }
    1895             : 
    1896           0 : void WW8Export::RestoreData()
    1897             : {
    1898           0 :     MSWordSaveData &rData = maSaveData.top();
    1899             : 
    1900           0 :     GetWriter().bWriteAll = rData.bOldWriteAll;
    1901             : 
    1902             :     OSL_ENSURE( pO->empty(), "pO is not empty in WW8Export::RestoreData()" );
    1903           0 :     if ( rData.pOOld )
    1904             :     {
    1905           0 :         delete pO;
    1906           0 :         pO = rData.pOOld;
    1907             :     }
    1908             : 
    1909           0 :     MSWordExportBase::RestoreData();
    1910           0 : }
    1911             : 
    1912         227 : void WW8AttributeOutput::TableInfoCell( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
    1913             : {
    1914         227 :     sal_uInt32 nDepth = pTableTextNodeInfoInner->getDepth();
    1915             : 
    1916         227 :     if ( nDepth > 0 )
    1917             :     {
    1918             :         /* Cell */
    1919         227 :         m_rWW8Export.InsUInt16( NS_sprm::LN_PFInTable );
    1920         227 :         m_rWW8Export.pO->push_back( (sal_uInt8)0x1 );
    1921         227 :         m_rWW8Export.InsUInt16( NS_sprm::LN_PTableDepth );
    1922         227 :         m_rWW8Export.InsUInt32( nDepth );
    1923             : 
    1924         227 :         if ( nDepth > 1 && pTableTextNodeInfoInner->isEndOfCell() )
    1925             :         {
    1926           0 :             m_rWW8Export.InsUInt16( NS_sprm::LN_PCell );
    1927           0 :             m_rWW8Export.pO->push_back( (sal_uInt8)0x1 );
    1928             :         }
    1929             :     }
    1930         227 : }
    1931             : 
    1932          30 : void WW8AttributeOutput::TableInfoRow( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
    1933             : {
    1934          30 :     sal_uInt32 nDepth = pTableTextNodeInfoInner->getDepth();
    1935             : 
    1936          30 :     if ( nDepth > 0 )
    1937             :     {
    1938             :         /* Row */
    1939          30 :         if ( pTableTextNodeInfoInner->isEndOfLine() )
    1940             :         {
    1941          30 :             m_rWW8Export.InsUInt16( NS_sprm::LN_PFInTable );
    1942          30 :             m_rWW8Export.pO->push_back( (sal_uInt8)0x1 );
    1943             : 
    1944          30 :             if ( nDepth == 1 )
    1945             :             {
    1946          30 :                 m_rWW8Export.InsUInt16( NS_sprm::LN_PFTtp );
    1947          30 :                 m_rWW8Export.pO->push_back( (sal_uInt8)0x1 );
    1948             :             }
    1949             : 
    1950          30 :             m_rWW8Export.InsUInt16( NS_sprm::LN_PTableDepth );
    1951          30 :             m_rWW8Export.InsUInt32( nDepth );
    1952             : 
    1953          30 :             if ( nDepth > 1 )
    1954             :             {
    1955           0 :                 m_rWW8Export.InsUInt16( NS_sprm::LN_PCell );
    1956           0 :                 m_rWW8Export.pO->push_back( (sal_uInt8)0x1 );
    1957           0 :                 m_rWW8Export.InsUInt16( NS_sprm::LN_PRow );
    1958           0 :                 m_rWW8Export.pO->push_back( (sal_uInt8)0x1 );
    1959             :             }
    1960             : 
    1961          30 :             TableDefinition( pTableTextNodeInfoInner );
    1962          30 :             TableHeight( pTableTextNodeInfoInner );
    1963          30 :             TableBackgrounds( pTableTextNodeInfoInner );
    1964          30 :             TableDefaultBorders( pTableTextNodeInfoInner );
    1965          30 :             TableCanSplit( pTableTextNodeInfoInner );
    1966          30 :             TableBidi( pTableTextNodeInfoInner );
    1967          30 :             TableVerticalCell( pTableTextNodeInfoInner );
    1968          30 :             TableOrientation( pTableTextNodeInfoInner );
    1969          30 :             TableSpacing( pTableTextNodeInfoInner );
    1970             :         }
    1971             :     }
    1972          30 : }
    1973             : 
    1974         118 : static sal_uInt16 lcl_TCFlags(SwDoc &rDoc, const SwTableBox * pBox, sal_Int32 nRowSpan)
    1975             : {
    1976         118 :     sal_uInt16 nFlags = 0;
    1977             : 
    1978         118 :     if (nRowSpan > 1)
    1979           0 :         nFlags |= (3 << 5);
    1980         118 :     else if (nRowSpan < 0)
    1981           0 :         nFlags |= (1 << 5);
    1982             : 
    1983         118 :     if (pBox != NULL)
    1984             :     {
    1985         118 :         const SwFrmFmt * pFmt = pBox->GetFrmFmt();
    1986         118 :         switch (pFmt->GetVertOrient().GetVertOrient())
    1987             :         {
    1988             :             case text::VertOrientation::CENTER:
    1989          16 :                 nFlags |= (1 << 7);
    1990          16 :                 break;
    1991             :             case text::VertOrientation::BOTTOM:
    1992           0 :                 nFlags |= (2 << 7);
    1993           0 :                 break;
    1994             :             default:
    1995         102 :                 break;
    1996             :         }
    1997         118 :         const SwStartNode * pSttNd = pBox->GetSttNd();
    1998         118 :         if(pSttNd)
    1999             :         {
    2000         118 :             SwNodeIndex aIdx( *pSttNd );
    2001         118 :             const SwCntntNode * pCNd = pSttNd->GetNodes().GoNext( &aIdx );
    2002         118 :             if( pCNd && pCNd->IsTxtNode())
    2003             :             {
    2004         118 :                 SfxItemSet aCoreSet(rDoc.GetAttrPool(), RES_CHRATR_ROTATE, RES_CHRATR_ROTATE);
    2005         118 :                 ((SwTxtNode*)pCNd)->GetAttr( aCoreSet, 0, !((SwTxtNode*)pCNd)->GetTxt().isEmpty());
    2006         118 :                 const SvxCharRotateItem * pRotate = NULL;
    2007             :                 const SfxPoolItem * pRotItem;
    2008         118 :                 if ( SFX_ITEM_SET == aCoreSet.GetItemState(RES_CHRATR_ROTATE, sal_True, &pRotItem))
    2009             :                 {
    2010           0 :                     pRotate = (SvxCharRotateItem*)pRotItem;
    2011           0 :                     if(pRotate && pRotate->GetValue() == 900)
    2012             :                     {
    2013           0 :                         nFlags = nFlags | 0x0004 | 0x0008;
    2014             :                     }
    2015           0 :                     else if(pRotate && pRotate->GetValue() == 2700 )
    2016             :                     {
    2017           0 :                         nFlags = nFlags | 0x0004 | 0x0010;
    2018             :                     }
    2019         118 :                 }
    2020         118 :             }
    2021             :         }
    2022             :     }
    2023             : 
    2024         118 :     return nFlags;
    2025             : }
    2026             : 
    2027          30 : void WW8AttributeOutput::TableVerticalCell( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
    2028             : {
    2029          30 :     const SwTableBox * pTabBox = pTableTextNodeInfoInner->getTableBox();
    2030          30 :     const SwTableLine * pTabLine = pTabBox->GetUpper();
    2031          30 :     const SwTableBoxes & rTblBoxes = pTabLine->GetTabBoxes();
    2032             : 
    2033          30 :     sal_uInt8 nBoxes = rTblBoxes.size();
    2034         148 :     for ( sal_uInt8 n = 0; n < nBoxes; n++ )
    2035             :     {
    2036         118 :         const SwTableBox * pTabBox1 = rTblBoxes[n];
    2037         118 :         const SwFrmFmt * pFrmFmt = pTabBox1->GetFrmFmt();
    2038             : 
    2039         118 :         if ( FRMDIR_VERT_TOP_RIGHT == m_rWW8Export.TrueFrameDirection( *pFrmFmt ) )
    2040             :         {
    2041           0 :             m_rWW8Export.InsUInt16( NS_sprm::LN_TTextFlow );
    2042           0 :             m_rWW8Export.pO->push_back( sal_uInt8(n) );        //start range
    2043           0 :             m_rWW8Export.pO->push_back( sal_uInt8(n + 1) );    //end range
    2044           0 :             m_rWW8Export.InsUInt16( 5 ); //Equals vertical writing
    2045             :         }
    2046             :     }
    2047          30 : }
    2048             : 
    2049          30 : void WW8AttributeOutput::TableCanSplit( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
    2050             : {
    2051          30 :     const SwTableBox * pTabBox = pTableTextNodeInfoInner->getTableBox();
    2052          30 :     const SwTableLine * pTabLine = pTabBox->GetUpper();
    2053          30 :     const SwFrmFmt * pLineFmt = pTabLine->GetFrmFmt();
    2054             : 
    2055             :     /*
    2056             :      By default the row can be split in word, and now in writer we have a
    2057             :      feature equivalent to this, Word stores 1 for fCantSplit if the row
    2058             :      cannot be split, we set true if we can split it. An example is #i4569#
    2059             :      */
    2060             : 
    2061          30 :     const SwFmtRowSplit& rSplittable = pLineFmt->GetRowSplit();
    2062          30 :     sal_uInt8 nCantSplit = (!rSplittable.GetValue()) ? 1 : 0;
    2063          30 :     if ( m_rWW8Export.bWrtWW8 )
    2064             :     {
    2065          30 :         m_rWW8Export.InsUInt16( NS_sprm::LN_TFCantSplit );
    2066          30 :         m_rWW8Export.pO->push_back( nCantSplit );
    2067          30 :         m_rWW8Export.InsUInt16( NS_sprm::LN_TFCantSplit90 ); // also write fCantSplit90
    2068             :     }
    2069             :     else
    2070             :     {
    2071           0 :         m_rWW8Export.pO->push_back( 185 );
    2072             :     }
    2073          30 :     m_rWW8Export.pO->push_back( nCantSplit );
    2074          30 : }
    2075             : 
    2076          30 : void WW8AttributeOutput::TableBidi( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
    2077             : {
    2078          30 :     const SwTable * pTable = pTableTextNodeInfoInner->getTable();
    2079          30 :     const SwFrmFmt * pFrmFmt = pTable->GetFrmFmt();
    2080             : 
    2081          30 :     if ( m_rWW8Export.bWrtWW8 )
    2082             :     {
    2083          30 :         if ( m_rWW8Export.TrueFrameDirection(*pFrmFmt) == FRMDIR_HORI_RIGHT_TOP )
    2084             :         {
    2085           0 :             m_rWW8Export.InsUInt16( NS_sprm::LN_TFBiDi );
    2086           0 :             m_rWW8Export.InsUInt16( 1 );
    2087             :         }
    2088             :     }
    2089          30 : }
    2090             : 
    2091          30 : void WW8AttributeOutput::TableHeight( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
    2092             : {
    2093          30 :     const SwTableBox * pTabBox = pTableTextNodeInfoInner->getTableBox();
    2094          30 :     const SwTableLine * pTabLine = pTabBox->GetUpper();
    2095          30 :     const SwFrmFmt * pLineFmt = pTabLine->GetFrmFmt();
    2096             : 
    2097             :     // Zeilenhoehe ausgeben   sprmTDyaRowHeight
    2098          30 :     long nHeight = 0;
    2099          30 :     const SwFmtFrmSize& rLSz = pLineFmt->GetFrmSize();
    2100          30 :     if ( ATT_VAR_SIZE != rLSz.GetHeightSizeType() && rLSz.GetHeight() )
    2101             :     {
    2102          30 :         if ( ATT_MIN_SIZE == rLSz.GetHeightSizeType() )
    2103           8 :             nHeight = rLSz.GetHeight();
    2104             :         else
    2105          22 :             nHeight = -rLSz.GetHeight();
    2106             :     }
    2107             : 
    2108          30 :     if ( nHeight )
    2109             :     {
    2110          30 :         if ( m_rWW8Export.bWrtWW8 )
    2111          30 :             m_rWW8Export.InsUInt16( NS_sprm::LN_TDyaRowHeight );
    2112             :         else
    2113           0 :             m_rWW8Export.pO->push_back( 189 );
    2114          30 :         m_rWW8Export.InsUInt16( (sal_uInt16)nHeight );
    2115             :     }
    2116             : 
    2117          30 : }
    2118             : 
    2119          30 : void WW8AttributeOutput::TableOrientation( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
    2120             : {
    2121          30 :     const SwTable * pTable = pTableTextNodeInfoInner->getTable();
    2122             : 
    2123          30 :     const SwFrmFmt *pFmt = pTable->GetFrmFmt();
    2124             :     OSL_ENSURE(pFmt,"Impossible");
    2125          30 :     if (!pFmt)
    2126          30 :         return;
    2127             : 
    2128          30 :     const SwFmtHoriOrient &rHori = pFmt->GetHoriOrient();
    2129          30 :     const SwFmtVertOrient &rVert = pFmt->GetVertOrient();
    2130             : 
    2131          30 :     if (
    2132          30 :         (text::RelOrientation::PRINT_AREA == rHori.GetRelationOrient() ||
    2133           0 :          text::RelOrientation::FRAME == rHori.GetRelationOrient())
    2134          90 :         &&
    2135          30 :         (text::RelOrientation::PRINT_AREA == rVert.GetRelationOrient() ||
    2136           0 :          text::RelOrientation::FRAME == rVert.GetRelationOrient())
    2137             :         )
    2138             :     {
    2139          30 :         sal_Int16 eHOri = rHori.GetHoriOrient();
    2140          30 :         switch (eHOri)
    2141             :         {
    2142             :             case text::HoriOrientation::CENTER:
    2143             :             case text::HoriOrientation::RIGHT:
    2144           0 :                 if ( m_rWW8Export.bWrtWW8 )
    2145           0 :                     m_rWW8Export.InsUInt16( NS_sprm::LN_TJc );
    2146             :                 else
    2147           0 :                     m_rWW8Export.pO->push_back( 182 );
    2148           0 :                 m_rWW8Export.InsUInt16( text::HoriOrientation::RIGHT == eHOri ? 2 : 1 );
    2149           0 :                 break;
    2150             :             default:
    2151          30 :                 break;
    2152             :         }
    2153             :     }
    2154             : }
    2155             : 
    2156          30 : void WW8AttributeOutput::TableSpacing(ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner)
    2157             : {
    2158          30 :     const SwTable * pTable = pTableTextNodeInfoInner->getTable();
    2159          30 :     const SwTableFmt * pTableFmt = pTable->GetTableFmt();
    2160             : 
    2161             :     // Writing these SPRM's will make the table a floating one, so only write
    2162             :     // them in case the table is already inside a frame.
    2163          30 :     if (pTableFmt != NULL && pTable->GetTableNode()->GetFlyFmt())
    2164             :     {
    2165           3 :         const SvxULSpaceItem & rUL = pTableFmt->GetULSpace();
    2166             : 
    2167           3 :         if (rUL.GetUpper() > 0)
    2168             :         {
    2169           0 :             sal_uInt8 nPadding = 2;
    2170           0 :             sal_uInt8 nPcVert = 0;
    2171           0 :             sal_uInt8 nPcHorz = 0;
    2172             : 
    2173           0 :             sal_uInt8 nTPc = (nPadding << 4) | (nPcVert << 2) | nPcHorz;
    2174             : 
    2175           0 :             m_rWW8Export.InsUInt16(NS_sprm::LN_TPc);
    2176           0 :             m_rWW8Export.pO->push_back( nTPc );
    2177             : 
    2178           0 :             m_rWW8Export.InsUInt16(NS_sprm::LN_TDyaAbs);
    2179           0 :             m_rWW8Export.InsUInt16(rUL.GetUpper());
    2180             : 
    2181           0 :             m_rWW8Export.InsUInt16(NS_sprm::LN_TDyaFromText);
    2182           0 :             m_rWW8Export.InsUInt16(rUL.GetUpper());
    2183             :         }
    2184             : 
    2185           3 :         if (rUL.GetLower() > 0)
    2186             :         {
    2187           0 :             m_rWW8Export.InsUInt16(NS_sprm::LN_TDyaFromTextBottom);
    2188           0 :             m_rWW8Export.InsUInt16(rUL.GetLower());
    2189             :         }
    2190             :     }
    2191          30 : }
    2192             : 
    2193          30 : void WW8AttributeOutput::TableDefinition( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
    2194             : {
    2195          30 :     const SwTable * pTable = pTableTextNodeInfoInner->getTable();
    2196             : 
    2197          30 :     if ( pTable->GetRowsToRepeat() > pTableTextNodeInfoInner->getRow() )
    2198             :     {
    2199           0 :         if( m_rWW8Export.bWrtWW8 )
    2200           0 :             m_rWW8Export.InsUInt16( NS_sprm::LN_TTableHeader );
    2201             :         else
    2202           0 :             m_rWW8Export.pO->push_back( 186 );
    2203           0 :         m_rWW8Export.pO->push_back( 1 );
    2204             :     }
    2205             : 
    2206             :     ww8::TableBoxVectorPtr pTableBoxes =
    2207          30 :         pTableTextNodeInfoInner->getTableBoxesOfRow();
    2208             :     // number of cell written
    2209          30 :     sal_uInt32 nBoxes = pTableBoxes->size();
    2210          30 :     if (nBoxes > ww8::MAXTABLECELLS)
    2211           0 :         nBoxes = ww8::MAXTABLECELLS;
    2212             : 
    2213             :     // sprm header
    2214          30 :     m_rWW8Export.InsUInt16( NS_sprm::LN_TDefTable );
    2215          30 :     sal_uInt16 nSprmSize = 2 + (nBoxes + 1) * 2 + nBoxes * 20;
    2216          30 :     m_rWW8Export.InsUInt16( nSprmSize ); // length
    2217             : 
    2218             :     // number of boxes
    2219          30 :     m_rWW8Export.pO->push_back( static_cast<sal_uInt8>(nBoxes) );
    2220             : 
    2221             :     /* cellxs */
    2222             :     /*
    2223             :      ALWAYS relative when text::HoriOrientation::NONE (nPageSize + ( nPageSize / 10 )) < nTblSz,
    2224             :      in that case the cell width's and table width's are not real. The table
    2225             :      width is maxed and cells relative, so we need the frame (generally page)
    2226             :      width that the table is in to work out the true widths.
    2227             :      */
    2228             :     //const bool bNewTableModel = pTbl->IsNewModel();
    2229          30 :     const SwFrmFmt *pFmt = pTable->GetFrmFmt();
    2230             :     OSL_ENSURE(pFmt,"Impossible");
    2231          30 :     if (!pFmt)
    2232          30 :         return;
    2233             : 
    2234          30 :     const SwFmtHoriOrient &rHori = pFmt->GetHoriOrient();
    2235          30 :     const SwFmtVertOrient &rVert = pFmt->GetVertOrient();
    2236             : 
    2237          30 :     sal_uInt16 nTblOffset = 0;
    2238             : 
    2239          30 :     if (
    2240          30 :         (text::RelOrientation::PRINT_AREA == rHori.GetRelationOrient() ||
    2241           0 :          text::RelOrientation::FRAME == rHori.GetRelationOrient())
    2242          90 :         &&
    2243          30 :         (text::RelOrientation::PRINT_AREA == rVert.GetRelationOrient() ||
    2244           0 :          text::RelOrientation::FRAME == rVert.GetRelationOrient())
    2245             :         )
    2246             :     {
    2247          30 :         sal_Int16 eHOri = rHori.GetHoriOrient();
    2248          30 :         switch ( eHOri )
    2249             :         {
    2250             :             case text::HoriOrientation::CENTER:
    2251             :             case text::HoriOrientation::RIGHT:
    2252           0 :                 break;
    2253             : 
    2254             :             default:
    2255          30 :                 nTblOffset = rHori.GetPos();
    2256          30 :                 const SvxLRSpaceItem& rLRSp = pFmt->GetLRSpace();
    2257          30 :                 nTblOffset += rLRSp.GetLeft();
    2258          30 :                 break;
    2259             :         }
    2260             :     }
    2261             : 
    2262          30 :      m_rWW8Export.InsUInt16( nTblOffset );
    2263             : 
    2264          30 :     ww8::GridColsPtr pGridCols = GetGridCols( pTableTextNodeInfoInner );
    2265         178 :     for ( ww8::GridCols::const_iterator it = pGridCols->begin(),
    2266          30 :               end = pGridCols->end(); it != end; ++it )
    2267             :      {
    2268         118 :          m_rWW8Export.InsUInt16( static_cast<sal_uInt16>( *it ) + nTblOffset );
    2269             :      }
    2270             : 
    2271             :      /* TCs */
    2272          60 :     ww8::RowSpansPtr pRowSpans = pTableTextNodeInfoInner->getRowSpansOfRow();
    2273          30 :     ww8::RowSpans::const_iterator aItRowSpans = pRowSpans->begin();
    2274          30 :     ww8::TableBoxVector::const_iterator aIt;
    2275          30 :     ww8::TableBoxVector::const_iterator aItEnd = pTableBoxes->end();
    2276             : 
    2277             : #if OSL_DEBUG_LEVEL > 1
    2278             :     size_t nRowSpans = pRowSpans->size();
    2279             :     size_t nTableBoxes = pTableBoxes->size();
    2280             :     (void) nRowSpans;
    2281             :     (void) nTableBoxes;
    2282             : #endif
    2283             : 
    2284         148 :     for( aIt = pTableBoxes->begin(); aIt != aItEnd; ++aIt, ++aItRowSpans)
    2285             :     {
    2286         118 :         sal_uInt16 npOCount = m_rWW8Export.pO->size();
    2287             : 
    2288         118 :         const SwTableBox * pTabBox1 = *aIt;
    2289         118 :         const SwFrmFmt * pBoxFmt = NULL;
    2290         118 :         if (pTabBox1 != NULL)
    2291         118 :             pBoxFmt = pTabBox1->GetFrmFmt();
    2292             : 
    2293         118 :         if ( m_rWW8Export.bWrtWW8 )
    2294             :         {
    2295             :             sal_uInt16 nFlags =
    2296         118 :                 lcl_TCFlags(*m_rWW8Export.pDoc, pTabBox1, *aItRowSpans);
    2297         118 :              m_rWW8Export.InsUInt16( nFlags );
    2298             :         }
    2299             : 
    2300             :         static sal_uInt8 aNullBytes[] = { 0x0, 0x0 };
    2301             : 
    2302         118 :         m_rWW8Export.pO->insert( m_rWW8Export.pO->end(), aNullBytes, aNullBytes+2 );   // dummy
    2303         118 :         if (pBoxFmt != NULL)
    2304             :         {
    2305         118 :             const SvxBoxItem & rBoxItem = pBoxFmt->GetBox();
    2306             : 
    2307         118 :             m_rWW8Export.Out_SwFmtTableBox( *m_rWW8Export.pO, &rBoxItem ); // 8/16 Byte
    2308             :         }
    2309             :         else
    2310           0 :             m_rWW8Export.Out_SwFmtTableBox( *m_rWW8Export.pO, NULL); // 8/16 Byte
    2311             : 
    2312             :         SAL_INFO( "sw.ww8.level2", "<tclength>" << ( m_rWW8Export.pO->size() - npOCount ) << "</tclength>" );
    2313          30 :     }
    2314             : }
    2315             : 
    2316         116 : ww8::GridColsPtr AttributeOutputBase::GetGridCols( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
    2317             : {
    2318         116 :     return pTableTextNodeInfoInner->getGridColsOfRow(*this);
    2319             : }
    2320             : 
    2321         135 : void AttributeOutputBase::GetTablePageSize( ww8::WW8TableNodeInfoInner * pTableTextNodeInfoInner, sal_uInt32& rPageSize, bool& rRelBoxSize )
    2322             : {
    2323         135 :     sal_uInt32 nPageSize = 0;
    2324             : 
    2325         135 :     const SwNode *pTxtNd = pTableTextNodeInfoInner->getNode( );
    2326         135 :     const SwTable *pTable = pTableTextNodeInfoInner->getTable( );
    2327             : 
    2328         135 :     const SwFrmFmt *pFmt = pTable->GetFrmFmt();
    2329             :     OSL_ENSURE(pFmt,"Impossible");
    2330         135 :     if (!pFmt)
    2331         135 :         return;
    2332             : 
    2333         135 :     const SwFmtFrmSize &rSize = pFmt->GetFrmSize();
    2334         135 :     int nWidthPercent = rSize.GetWidthPercent();
    2335         135 :     bool bManualAligned = pFmt->GetHoriOrient().GetHoriOrient() == text::HoriOrientation::NONE;
    2336         135 :     if ( (pFmt->GetHoriOrient().GetHoriOrient() == text::HoriOrientation::FULL) || bManualAligned )
    2337           0 :         nWidthPercent = 100;
    2338         135 :     bool bRelBoxSize = nWidthPercent != 0;
    2339         135 :     unsigned long nTblSz = static_cast<unsigned long>(rSize.GetWidth());
    2340         135 :     if (nTblSz > USHRT_MAX/2 && !bRelBoxSize)
    2341             :     {
    2342             :         OSL_ENSURE(bRelBoxSize, "huge table width but not relative, suspicious");
    2343           0 :         bRelBoxSize = true;
    2344             :     }
    2345             : 
    2346         135 :     if ( bRelBoxSize )
    2347             :     {
    2348           0 :         Point aPt;
    2349           0 :         SwRect aRect( pFmt->FindLayoutRect( false, &aPt ) );
    2350           0 :         if ( aRect.IsEmpty() )
    2351             :         {
    2352             :             // dann besorge mal die Seitenbreite ohne Raender !!
    2353             :             const SwFrmFmt* pParentFmt =
    2354           0 :                 GetExport().mpParentFrame ?
    2355           0 :                 &(GetExport().mpParentFrame->GetFrmFmt()) :
    2356           0 :                     GetExport().pDoc->GetPageDesc(0).GetPageFmtOfNode(*pTxtNd, false);
    2357           0 :             aRect = pParentFmt->FindLayoutRect(true);
    2358           0 :             if ( 0 == ( nPageSize = aRect.Width() ) )
    2359             :             {
    2360           0 :                 const SvxLRSpaceItem& rLR = pParentFmt->GetLRSpace();
    2361           0 :                 nPageSize = pParentFmt->GetFrmSize().GetWidth() - rLR.GetLeft()
    2362           0 :                 - rLR.GetRight();
    2363             :             }
    2364             :         }
    2365             :         else
    2366             :         {
    2367           0 :             nPageSize = aRect.Width();
    2368           0 :             if ( bManualAligned )
    2369             :             {
    2370             :                 // #i37571# For manually aligned tables
    2371           0 :                 const SvxLRSpaceItem &rLR = pFmt->GetLRSpace();
    2372           0 :                 nPageSize -= (rLR.GetLeft() + rLR.GetRight());
    2373             :             }
    2374             : 
    2375             :         }
    2376             : 
    2377             :         OSL_ENSURE(nWidthPercent, "Impossible");
    2378           0 :         if (nWidthPercent)
    2379             :         {
    2380           0 :             nPageSize *= nWidthPercent;
    2381           0 :             nPageSize /= 100;
    2382             :         }
    2383             :     }
    2384             : 
    2385         135 :     rPageSize = nPageSize;
    2386         135 :     rRelBoxSize = bRelBoxSize;
    2387             : }
    2388             : 
    2389          30 : void WW8AttributeOutput::TableDefaultBorders( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
    2390             : {
    2391          30 :     const SwTableBox * pTabBox = pTableTextNodeInfoInner->getTableBox();
    2392          30 :     const SwFrmFmt * pFrmFmt = pTabBox->GetFrmFmt();
    2393             : 
    2394             :     //Set Default, just taken from the first cell of the first
    2395             :     //row
    2396             :     static sal_uInt16 aBorders[] =
    2397             :     {
    2398             :         BOX_LINE_TOP, BOX_LINE_LEFT,
    2399             :         BOX_LINE_BOTTOM, BOX_LINE_RIGHT
    2400             :     };
    2401             : 
    2402         150 :     for ( int i = 0; i < 4; ++i )
    2403             :     {
    2404         120 :         SwWW8Writer::InsUInt16( *m_rWW8Export.pO, 0xD634 );
    2405         120 :         m_rWW8Export.pO->push_back( sal_uInt8(6) );
    2406         120 :         m_rWW8Export.pO->push_back( sal_uInt8(0) );
    2407         120 :         m_rWW8Export.pO->push_back( sal_uInt8(1) );
    2408         120 :         m_rWW8Export.pO->push_back( sal_uInt8(1 << i) );
    2409         120 :         m_rWW8Export.pO->push_back( sal_uInt8(3) );
    2410             : 
    2411             :         SwWW8Writer::InsUInt16( *m_rWW8Export.pO,
    2412         120 :                 pFrmFmt->GetBox().GetDistance( aBorders[i] ) );
    2413             :     }
    2414          30 : }
    2415             : 
    2416          30 : void WW8AttributeOutput::TableBackgrounds( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
    2417             : {
    2418          30 :     const SwTableBox * pTabBox = pTableTextNodeInfoInner->getTableBox();
    2419          30 :     const SwTableLine * pTabLine = pTabBox->GetUpper();
    2420          30 :     const SwTableBoxes & rTabBoxes = pTabLine->GetTabBoxes();
    2421             : 
    2422          30 :     sal_uInt8 nBoxes = rTabBoxes.size();
    2423          30 :     if ( m_rWW8Export.bWrtWW8 )
    2424          30 :         m_rWW8Export.InsUInt16( NS_sprm::LN_TDefTableShd );
    2425             :     else
    2426           0 :         m_rWW8Export.pO->push_back( (sal_uInt8)191 );
    2427          30 :     m_rWW8Export.pO->push_back( (sal_uInt8)(nBoxes * 2) );  // Len
    2428             : 
    2429         148 :     for ( sal_uInt8 n = 0; n < nBoxes; n++ )
    2430             :     {
    2431         118 :         const SwTableBox * pBox1 = rTabBoxes[n];
    2432         118 :         const SwFrmFmt * pFrmFmt = pBox1->GetFrmFmt();
    2433         118 :         const SfxPoolItem * pI = NULL;
    2434         118 :         Color aColor;
    2435             : 
    2436         118 :         if ( SFX_ITEM_ON == pFrmFmt->GetAttrSet().GetItemState( RES_BACKGROUND, false, &pI ) )
    2437             :         {
    2438          13 :             aColor = dynamic_cast<const SvxBrushItem *>(pI)->GetColor();
    2439             :         }
    2440             :         else
    2441         105 :             aColor = COL_AUTO;
    2442             : 
    2443         118 :         WW8_SHD aShd;
    2444         118 :         m_rWW8Export.TransBrush( aColor, aShd );
    2445         118 :         m_rWW8Export.InsUInt16( aShd.GetValue() );
    2446             :     }
    2447             : 
    2448          30 :     if ( m_rWW8Export.bWrtWW8 )
    2449             :     {
    2450          30 :         sal_uInt32 aSprmIds[] = {NS_sprm::LN_TCellShd, NS_sprm::LN_TCellShadow};
    2451          30 :         sal_uInt8 nBoxes0 = rTabBoxes.size();
    2452          30 :         if (nBoxes0 > 21)
    2453           0 :             nBoxes0 = 21;
    2454             : 
    2455          90 :         for (sal_uInt32 m = 0; m < 2; m++)
    2456             :         {
    2457          60 :             m_rWW8Export.InsUInt16( aSprmIds[m] );
    2458          60 :             m_rWW8Export.pO->push_back( static_cast<sal_uInt8>(nBoxes0 * 10) );
    2459             : 
    2460         296 :         for ( sal_uInt8 n = 0; n < nBoxes0; n++ )
    2461             :         {
    2462         236 :             const SwTableBox * pBox1 = rTabBoxes[n];
    2463         236 :             const SwFrmFmt * pFrmFmt = pBox1->GetFrmFmt();
    2464         236 :             const SfxPoolItem * pI = NULL;
    2465         236 :             Color aColor;
    2466             : 
    2467         236 :                 if ( SFX_ITEM_ON ==
    2468         236 :                          pFrmFmt->GetAttrSet().
    2469         236 :                          GetItemState( RES_BACKGROUND, false, &pI ) )
    2470             :             {
    2471          26 :                 aColor = dynamic_cast<const SvxBrushItem *>(pI)->GetColor();
    2472             :             }
    2473             :             else
    2474         210 :                 aColor = COL_AUTO;
    2475             : 
    2476         236 :             WW8SHDLong aSHD;
    2477         236 :             aSHD.setCvFore( 0xFF000000 );
    2478             : 
    2479         236 :             sal_uInt32 nBgColor = aColor.GetColor();
    2480         236 :             if ( nBgColor == COL_AUTO )
    2481         210 :                 aSHD.setCvBack( 0xFF000000 );
    2482             :             else
    2483          26 :                 aSHD.setCvBack( wwUtility::RGBToBGR( nBgColor ) );
    2484             : 
    2485         236 :             aSHD.Write( m_rWW8Export );
    2486         236 :         }
    2487             :         }
    2488             :     }
    2489          30 : }
    2490             : 
    2491         298 : void WW8Export::SectionBreaksAndFrames( const SwTxtNode& rNode )
    2492             : {
    2493             :     // output page/section breaks
    2494         298 :     OutputSectionBreaks( rNode.GetpSwAttrSet(), rNode );
    2495             : 
    2496             :     // all textframes anchored as character for the winword 7- format
    2497         298 :     if ( !bWrtWW8 && !IsInTable() )
    2498           0 :         OutWW6FlyFrmsInCntnt( rNode );
    2499         298 : }
    2500             : 
    2501         159 : void MSWordExportBase::WriteText()
    2502             : {
    2503        2802 :     while( pCurPam->GetPoint()->nNode < pCurPam->GetMark()->nNode ||
    2504         380 :            ( pCurPam->GetPoint()->nNode == pCurPam->GetMark()->nNode &&
    2505         159 :              pCurPam->GetPoint()->nContent.GetIndex() <= pCurPam->GetMark()->nContent.GetIndex() ) )
    2506             :     {
    2507        1180 :         SwNode * pNd = pCurPam->GetNode();
    2508             : 
    2509        1180 :         if ( pNd->IsTxtNode() )
    2510         622 :             SectionBreaksAndFrames( *pNd->GetTxtNode() );
    2511             : 
    2512             :         // output the various types of nodes
    2513        1180 :         if ( pNd->IsCntntNode() )
    2514             :         {
    2515         622 :             SwCntntNode* pCNd = (SwCntntNode*)pNd;
    2516             : 
    2517         622 :             const SwPageDesc* pTemp = pCNd->GetSwAttrSet().GetPageDesc().GetPageDesc();
    2518         622 :             if ( pTemp )
    2519          80 :                 pAktPageDesc = pTemp;
    2520             : 
    2521         622 :             pCurPam->GetPoint()->nContent.Assign( pCNd, 0 );
    2522         622 :             OutputContentNode( *pCNd );
    2523             :         }
    2524         558 :         else if ( pNd->IsTableNode() )
    2525             :         {
    2526          15 :             mpTableInfo->processSwTable( &pNd->GetTableNode()->GetTable() );
    2527             :         }
    2528         543 :         else if ( pNd->IsSectionNode() && TXT_MAINTEXT == nTxtTyp )
    2529           0 :             OutputSectionNode( *pNd->GetSectionNode() );
    2530         809 :         else if ( TXT_MAINTEXT == nTxtTyp && pNd->IsEndNode() &&
    2531         266 :                   pNd->StartOfSectionNode()->IsSectionNode() )
    2532             :         {
    2533           0 :             const SwSection& rSect = pNd->StartOfSectionNode()->GetSectionNode()
    2534           0 :                                         ->GetSection();
    2535           0 :             if ( bStartTOX && TOX_CONTENT_SECTION == rSect.GetType() )
    2536           0 :                 bStartTOX = false;
    2537             : 
    2538           0 :             SwNodeIndex aIdx( *pNd, 1 );
    2539           0 :             if ( aIdx.GetNode().IsEndNode() && aIdx.GetNode().StartOfSectionNode()->IsSectionNode() )
    2540             :                 ;
    2541           0 :             else if ( aIdx.GetNode().IsSectionNode() )
    2542             :                 ;
    2543           0 :             else if ( !IsInTable() ) //No sections in table
    2544             :             {
    2545             :                 //#120140# Do not need to insert a page/section break after a section end. Check this case first
    2546           0 :                 sal_Bool bNeedExportBreakHere = sal_True;
    2547           0 :                 if ( aIdx.GetNode().IsTxtNode() )
    2548             :                 {
    2549           0 :                     SwTxtNode *pTempNext = aIdx.GetNode().GetTxtNode();
    2550           0 :                     if ( pTempNext )
    2551             :                     {
    2552           0 :                         const SfxPoolItem * pTempItem = NULL;
    2553           0 :                         if (pTempNext->GetpSwAttrSet() && SFX_ITEM_SET == pTempNext->GetpSwAttrSet()->GetItemState(RES_PAGEDESC, false, &pTempItem)
    2554           0 :                             && pTempItem && ((SwFmtPageDesc*)pTempItem)->GetRegisteredIn())
    2555             :                         {
    2556             :                             //Next node has a new page style which means this node is a section end. Do not insert another page/section break here
    2557           0 :                             bNeedExportBreakHere = sal_False;
    2558             :                         }
    2559             :                     }
    2560             :                 }
    2561           0 :                 if (bNeedExportBreakHere)  //#120140# End of check
    2562             :                 {
    2563           0 :                     ReplaceCr( (char)0xc ); // indicator for Page/Section-Break
    2564             : 
    2565           0 :                     const SwSectionFmt* pParentFmt = rSect.GetFmt()->GetParent();
    2566           0 :                     if ( !pParentFmt )
    2567           0 :                         pParentFmt = (SwSectionFmt*)0xFFFFFFFF;
    2568             : 
    2569             :                     sal_uLong nRstLnNum;
    2570           0 :                     if ( aIdx.GetNode().IsCntntNode() )
    2571           0 :                         nRstLnNum = ((SwCntntNode&)aIdx.GetNode()).GetSwAttrSet().
    2572           0 :                                                 GetLineNumber().GetStartValue();
    2573             :                     else
    2574           0 :                         nRstLnNum = 0;
    2575             : 
    2576           0 :                     AppendSection( pAktPageDesc, pParentFmt, nRstLnNum );
    2577             :                 }
    2578           0 :             }
    2579             :         }
    2580         543 :         else if ( pNd->IsStartNode() )
    2581             :         {
    2582         264 :             OutputStartNode( *pNd->GetStartNode() );
    2583             :         }
    2584         279 :         else if ( pNd->IsEndNode() )
    2585             :         {
    2586         279 :             OutputEndNode( *pNd->GetEndNode() );
    2587             :         }
    2588             : 
    2589        1180 :         if ( pNd == &pNd->GetNodes().GetEndOfContent() )
    2590          97 :             break;
    2591             : 
    2592        1083 :         SwNode * pCurrentNode = &pCurPam->GetPoint()->nNode.GetNode();
    2593        1083 :         const SwNode * pNextNode = mpTableInfo->getNextNode(pCurrentNode);
    2594             : 
    2595        1083 :         if (pNextNode != NULL)
    2596         610 :             pCurPam->GetPoint()->nNode = SwNodeIndex(*pNextNode);
    2597             :         else
    2598         473 :             pCurPam->GetPoint()->nNode++;
    2599             : 
    2600        1083 :         sal_uLong nPos = pCurPam->GetPoint()->nNode.GetIndex();
    2601        1083 :         ::SetProgressState( nPos, pCurPam->GetDoc()->GetDocShell() );
    2602             :     }
    2603             : 
    2604             :     SAL_INFO( "sw.ww8.level2", "</WriteText>" );
    2605         159 : }
    2606             : 
    2607           8 : void WW8Export::WriteMainText()
    2608             : {
    2609             :     SAL_INFO( "sw.ww8.level2", "<WriteMainText>" );
    2610             : 
    2611           8 :     pFib->fcMin = Strm().Tell();
    2612             : 
    2613           8 :     pCurPam->GetPoint()->nNode = pDoc->GetNodes().GetEndOfContent().StartOfSectionNode()->GetIndex();
    2614             : 
    2615           8 :     WriteText();
    2616             : 
    2617           8 :     if( 0 == Strm().Tell() - pFib->fcMin )  // no text ?
    2618           0 :         WriteCR();                  // then CR at the end ( otherwise WW will complain )
    2619             : 
    2620           8 :     pFib->ccpText = Fc2Cp( Strm().Tell() );
    2621           8 :     pFldMain->Finish( pFib->ccpText, 0 );
    2622             : 
    2623             :                     // ccpText includes Footnote and KF-text
    2624             :                     // therefore pFib->ccpText may get updated as well
    2625             :     // save the StyleId of the last paragraph. Because WW97 take the style
    2626             :     // from the last CR, that will be writen after footer/Header/footnotes/
    2627             :     // annotation usw.
    2628           8 :     const SwTxtNode* pLastNd = pCurPam->GetMark()->nNode.GetNode().GetTxtNode();
    2629           8 :     if( pLastNd )
    2630           0 :         nLastFmtId = GetId( (SwTxtFmtColl&)pLastNd->GetAnyFmtColl() );
    2631             : 
    2632             :     SAL_INFO( "sw.ww8.level2", "</WriteMainText>" );
    2633           8 : }
    2634             : 
    2635          50 : bool MSWordExportBase::IsInTable() const
    2636             : {
    2637          50 :     bool bResult = false;
    2638             : 
    2639          50 :     if (pCurPam != NULL)
    2640             :     {
    2641          50 :         SwNode * pNode = pCurPam->GetNode();
    2642             : 
    2643          50 :         if (pNode != NULL && mpTableInfo.get() != NULL)
    2644             :         {
    2645          50 :             ww8::WW8TableNodeInfo::Pointer_t pTableNodeInfo = mpTableInfo->getTableNodeInfo(pNode);
    2646             : 
    2647          50 :             if (pTableNodeInfo.get() != NULL && pTableNodeInfo->getDepth() > 0)
    2648             :             {
    2649           4 :                 bResult = true;
    2650          50 :             }
    2651             :         }
    2652             :     }
    2653             : 
    2654          50 :     return bResult;
    2655             : }
    2656             : 
    2657             : typedef ww8::WW8Sttb< ww8::WW8Struct >  WW8SttbAssoc;
    2658             : 
    2659           8 : void WW8Export::WriteFkpPlcUsw()
    2660             : {
    2661           8 :     if( !bWrtWW8 )
    2662             :     {
    2663             :         static const sal_uInt8 aSpec[2] =
    2664             :         {
    2665             :             117, 1
    2666             :         };
    2667             : 
    2668           0 :         pChpPlc->AppendFkpEntry( Strm().Tell() );   // Sepx with fSpecial
    2669           0 :         pSepx->WriteSepx( Strm() );                 // Slcx.Sepx
    2670           0 :         pGrf->Write();                              // Graphics
    2671           0 :         pChpPlc->AppendFkpEntry( Strm().Tell(), sizeof( aSpec ), aSpec );
    2672             : 
    2673           0 :         pChpPlc->WriteFkps();                   // Fkp.Chpx
    2674           0 :         pPapPlc->WriteFkps();                   // Fkp.Papx
    2675           0 :         pStyles->OutputStylesTable();           // Styles
    2676           0 :         pFtn->WritePlc( *this );                // Footnote-Ref & Text Plc
    2677           0 :         pEdn->WritePlc( *this );                // Endnote-Ref & Text Plc
    2678           0 :         pAtn->WritePlc( *this );                // Annotation-Ref & Text Plc
    2679           0 :         pSepx->WritePlcSed( *this );            // Slcx.PlcSed
    2680           0 :         pSepx->WritePlcHdd( *this );            // Slcx.PlcHdd
    2681           0 :         pChpPlc->WritePlc();                    // Plcx.Chpx
    2682           0 :         pPapPlc->WritePlc();                    // Plcx.Papx
    2683           0 :         maFontHelper.WriteFontTable(pTableStrm, *pFib); // FFNs
    2684           0 :         if( pRedlAuthors )
    2685           0 :             pRedlAuthors->Write( GetWriter() );       // sttbfRMark (RedlineAuthors)
    2686           0 :         pFldMain->Write( *this );               // Fields ( Main Text )
    2687           0 :         pFldHdFt->Write( *this );               // Fields ( Header/Footer )
    2688           0 :         pFldFtn->Write( *this );                // Fields ( FootNotes )
    2689           0 :         pFldEdn->Write( *this );                // Fields ( EndNotes )
    2690           0 :         pFldAtn->Write( *this );                // Fields ( Annotations )
    2691           0 :         pBkmks->Write( *this );                 // Bookmarks - sttbfBkmk/
    2692             :                                                 // plcfBkmkf/plcfBkmkl
    2693           0 :         WriteDop( *this );                      // Document-Properties
    2694             : 
    2695             :     }
    2696             :     else
    2697             :     {
    2698             :         // Graphics in the data stream
    2699           8 :         pGrf->Write();                          // Graphics
    2700             : 
    2701             :         // Ausgabe in WordDocument-Stream
    2702           8 :         pChpPlc->WriteFkps();                   // Fkp.Chpx
    2703           8 :         pPapPlc->WriteFkps();                   // Fkp.Papx
    2704           8 :         pSepx->WriteSepx( Strm() );             // Sepx
    2705             : 
    2706             :         // Ausagbe in Table-Stream
    2707           8 :         pStyles->OutputStylesTable();           // for WW8 StyleTab
    2708           8 :         pFtn->WritePlc( *this );                // Footnote-Ref & Text Plc
    2709           8 :         pEdn->WritePlc( *this );                // Endnote-Ref & Text Plc
    2710           8 :         pTxtBxs->WritePlc( *this );             // Textbox Text Plc
    2711           8 :         pHFTxtBxs->WritePlc( *this );           // Head/Foot-Textbox Text Plc
    2712           8 :         pAtn->WritePlc( *this );                // Annotation-Ref & Text Plc
    2713             : 
    2714           8 :         pSepx->WritePlcSed( *this );            // Slcx.PlcSed
    2715           8 :         pSepx->WritePlcHdd( *this );            // Slcx.PlcHdd
    2716             : 
    2717           8 :         pChpPlc->WritePlc();                    // Plcx.Chpx
    2718           8 :         pPapPlc->WritePlc();                    // Plcx.Papx
    2719             : 
    2720           8 :         if( pRedlAuthors )
    2721           0 :             pRedlAuthors->Write( GetWriter() );       // sttbfRMark (RedlineAuthors)
    2722           8 :         pFldMain->Write( *this );               // Fields ( Main Text )
    2723           8 :         pFldHdFt->Write( *this );               // Fields ( Header/Footer )
    2724           8 :         pFldFtn->Write( *this );                // Fields ( FootNotes )
    2725           8 :         pFldEdn->Write( *this );                // Fields ( EndNotes )
    2726           8 :         pFldAtn->Write( *this );                // Fields ( Annotations )
    2727           8 :         pFldTxtBxs->Write( *this );             // Fields ( Textboxes )
    2728           8 :         pFldHFTxtBxs->Write( *this );           // Fields ( Head/Foot-Textboxes )
    2729             : 
    2730           8 :         if (pEscher || pDoc->ContainsMSVBasic())
    2731             :         {
    2732             :             /*
    2733             :              Everytime MS 2000 creates an escher stream there is always
    2734             :              an ObjectPool dir (even if empty). It turns out that if a copy of
    2735             :              MS 2000 is used to open a document that contains escher graphics
    2736             :              exported from StarOffice without this empty dir then *if* that
    2737             :              copy of MS Office has never been used to open a MSOffice document
    2738             :              that has escher graphics (and an ObjectPool dir of course) and
    2739             :              that copy of office has not been used to draw escher graphics then
    2740             :              our exported graphics do not appear. Once you do open a ms
    2741             :              document with escher graphics or draw an escher graphic with that
    2742             :              copy of word, then all documents from staroffice that contain
    2743             :              escher work from then on. Tricky to track down, some sort of late
    2744             :              binding trickery in MS where solely for first time initialization
    2745             :              the existence of an ObjectPool dir is necessary for triggering
    2746             :              some magic. cmc
    2747             :             */
    2748             :             // avoid memory leak #i120098#, the unnamed obj will be released in destructor.
    2749           6 :             xEscherStg = GetWriter().GetStorage().OpenSotStorage(OUString(SL::aObjectPool),
    2750           3 :                 STREAM_READWRITE | STREAM_SHARE_DENYALL);
    2751             :         }
    2752             : 
    2753             :         // dggInfo - escher stream
    2754           8 :         WriteEscher();
    2755             : 
    2756           8 :         pSdrObjs->WritePlc( *this );
    2757           8 :         pHFSdrObjs->WritePlc( *this );
    2758             :         // spamom - office drawing table
    2759             :         // spahdr - header office drawing table
    2760             : 
    2761           8 :         pBkmks->Write( *this );                 // Bookmarks - sttbfBkmk/
    2762             :                                                 // plcfBkmkf/plcfBkmkl
    2763             : 
    2764           8 :         WriteNumbering();
    2765             : 
    2766           8 :         RestoreMacroCmds();
    2767             : 
    2768           8 :         pMagicTable->Write( *this );
    2769             : 
    2770           8 :         pPiece->WritePc( *this );               // Piece-Table
    2771           8 :         maFontHelper.WriteFontTable(pTableStrm, *pFib); // FFNs
    2772             : 
    2773             :         //Convert OOo asian typography into MS typography structure
    2774           8 :         ExportDopTypography(pDop->doptypography);
    2775             : 
    2776           8 :         WriteDop( *this );                      // Document-Properties
    2777             : 
    2778             :         // Write SttbfAssoc
    2779             :         WW8SttbAssoc * pSttbfAssoc = dynamic_cast<WW8SttbAssoc *>
    2780           8 :             (pDoc->getExternalData(::sw::STTBF_ASSOC).get());
    2781             : 
    2782           8 :         if ( pSttbfAssoc )                      // #i106057#
    2783             :         {
    2784           5 :         ::std::vector<OUString> aStrings;
    2785             : 
    2786           5 :         ::ww8::StringVector_t & aSttbStrings = pSttbfAssoc->getStrings();
    2787           5 :         ::ww8::StringVector_t::const_iterator aItEnd = aSttbStrings.end();
    2788          77 :         for (::ww8::StringVector_t::const_iterator aIt = aSttbStrings.begin();
    2789             :              aIt != aItEnd; ++aIt)
    2790             :         {
    2791          72 :             aStrings.push_back(aIt->getStr());
    2792             :         }
    2793             : 
    2794             :         WriteAsStringTable(aStrings, pFib->fcSttbfAssoc,
    2795           5 :                            pFib->lcbSttbfAssoc);
    2796             :         }
    2797             :     }
    2798           8 :     Strm().Seek( 0 );
    2799             : 
    2800             :     // Reclaim stored FIB data from document.
    2801             :     ::ww8::WW8FibData * pFibData = dynamic_cast<ww8::WW8FibData *>
    2802           8 :           (pDoc->getExternalData(::sw::FIB).get());
    2803             : 
    2804           8 :     if ( pFibData )
    2805             :     {
    2806             :     pFib->fReadOnlyRecommended =
    2807           5 :         pFibData->getReadOnlyRecommended() ? 1 : 0;
    2808             :     pFib->fWriteReservation =
    2809           5 :         pFibData->getWriteReservation() ? 1 : 0;
    2810             :     }
    2811             : 
    2812           8 :     pFib->Write( Strm() );  // FIB
    2813           8 : }
    2814             : 
    2815           8 : void WW8Export::StoreDoc1()
    2816             : {
    2817           8 :     bool bNeedsFinalPara = false;
    2818             :     // Start of Text ( Mangel ueber )
    2819           8 :     SwWW8Writer::FillUntil( Strm(), pFib->fcMin );
    2820             : 
    2821           8 :     WriteMainText();                    // main text
    2822             :     sal_uInt8 nSprmsLen;
    2823           8 :     sal_uInt8 *pLastSprms = pPapPlc->CopyLastSprms(nSprmsLen);
    2824             : 
    2825           8 :     bNeedsFinalPara |= pFtn->WriteTxt( *this );         // Footnote-Text
    2826           8 :     bNeedsFinalPara |= pSepx->WriteKFTxt( *this );          // K/F-Text
    2827           8 :     bNeedsFinalPara |= pAtn->WriteTxt( *this );         // Annotation-Text
    2828           8 :     bNeedsFinalPara |= pEdn->WriteTxt( *this );         // EndNote-Text
    2829             : 
    2830             :     // create the escher streams
    2831           8 :     if( bWrtWW8 )
    2832           8 :         CreateEscher();
    2833             : 
    2834           8 :     bNeedsFinalPara |= pTxtBxs->WriteTxt( *this );  //Textbox Text Plc
    2835           8 :     bNeedsFinalPara |= pHFTxtBxs->WriteTxt( *this );//Head/Foot-Textbox Text Plc
    2836             : 
    2837           8 :     if (bNeedsFinalPara)
    2838             :     {
    2839           7 :         WriteCR();
    2840           7 :         pPapPlc->AppendFkpEntry(Strm().Tell(), nSprmsLen, pLastSprms);
    2841             :     }
    2842           8 :     delete[] pLastSprms;
    2843             : 
    2844           8 :     pSepx->Finish( Fc2Cp( Strm().Tell() ));// Text + Ftn + HdFt als Section-Ende
    2845           8 :     pMagicTable->Finish( Fc2Cp( Strm().Tell() ),0);
    2846             : 
    2847           8 :     pFib->fcMac = Strm().Tell();        // End of all texts
    2848             : 
    2849           8 :     WriteFkpPlcUsw();                   // FKP, PLC, .....
    2850           8 : }
    2851             : 
    2852           5 : void MSWordExportBase::AddLinkTarget(const String& rURL)
    2853             : {
    2854           5 :     if( !rURL.Len() || rURL.GetChar(0) != INET_MARK_TOKEN )
    2855          10 :         return;
    2856             : 
    2857           0 :     String aURL( BookmarkToWriter( rURL.Copy( 1 ) ) );
    2858           0 :     xub_StrLen nPos = aURL.SearchBackward( cMarkSeparator );
    2859             : 
    2860           0 :     if( nPos < 2 )
    2861           0 :         return;
    2862             : 
    2863           0 :     String sCmp(comphelper::string::remove(aURL.Copy(nPos+1), ' '));
    2864           0 :     if( !sCmp.Len() )
    2865           0 :         return;
    2866             : 
    2867           0 :     sCmp.ToLowerAscii();
    2868             : 
    2869           0 :     if( sCmp.EqualsAscii( pMarkToOutline ) )
    2870             :     {
    2871           0 :         SwPosition aPos( *pCurPam->GetPoint() );
    2872           0 :         String aOutline( BookmarkToWriter(aURL.Copy( 0, nPos )) );
    2873             :         // If we can find the outline this bookmark refers to
    2874             :         // save the name of the bookmark and the
    2875             :         // node index number of where it points to
    2876           0 :         if( pDoc->GotoOutline( aPos, aOutline ) )
    2877             :         {
    2878           0 :             sal_uLong nIdx = aPos.nNode.GetIndex();
    2879           0 :             aBookmarkPair aImplicitBookmark;
    2880           0 :             aImplicitBookmark.first = aOutline;
    2881           0 :             aImplicitBookmark.second = nIdx;
    2882           0 :             maImplicitBookmarks.push_back(aImplicitBookmark);
    2883           0 :         }
    2884           0 :     }
    2885             : }
    2886             : 
    2887          97 : void MSWordExportBase::CollectOutlineBookmarks(const SwDoc &rDoc)
    2888             : {
    2889             :     const SwFmtINetFmt* pINetFmt;
    2890             :     const SwTxtINetFmt* pTxtAttr;
    2891             :     const SwTxtNode* pTxtNd;
    2892             : 
    2893          97 :     sal_uInt32 n, nMaxItems = rDoc.GetAttrPool().GetItemCount2( RES_TXTATR_INETFMT );
    2894         111 :     for( n = 0; n < nMaxItems; ++n )
    2895             :     {
    2896          28 :         if( 0 != (pINetFmt = (SwFmtINetFmt*)rDoc.GetAttrPool().GetItem2(
    2897          19 :             RES_TXTATR_INETFMT, n ) ) &&
    2898           5 :             0 != ( pTxtAttr = pINetFmt->GetTxtINetFmt()) &&
    2899          19 :             0 != ( pTxtNd = pTxtAttr->GetpTxtNode() ) &&
    2900           5 :             pTxtNd->GetNodes().IsDocNodes() )
    2901             :         {
    2902           5 :             AddLinkTarget( pINetFmt->GetValue() );
    2903             :         }
    2904             :     }
    2905             : 
    2906             :     const SwFmtURL *pURL;
    2907          97 :     nMaxItems = rDoc.GetAttrPool().GetItemCount2( RES_URL );
    2908          97 :     for( n = 0; n < nMaxItems; ++n )
    2909             :     {
    2910           0 :         if( 0 != (pURL = (SwFmtURL*)rDoc.GetAttrPool().GetItem2(
    2911           0 :             RES_URL, n ) ) )
    2912             :         {
    2913           0 :             AddLinkTarget( pURL->GetURL() );
    2914           0 :             const ImageMap *pIMap = pURL->GetMap();
    2915           0 :             if( pIMap )
    2916             :             {
    2917           0 :                 for( sal_uInt16 i=0; i<pIMap->GetIMapObjectCount(); i++ )
    2918             :                 {
    2919           0 :                     const IMapObject* pObj = pIMap->GetIMapObject( i );
    2920           0 :                     if( pObj )
    2921             :                     {
    2922           0 :                         AddLinkTarget( pObj->GetURL() );
    2923             :                     }
    2924             :                 }
    2925             :             }
    2926             :         }
    2927             :     }
    2928          97 : }
    2929             : 
    2930             : namespace
    2931             : {
    2932             :     const sal_uLong WW_BLOCKSIZE = 0x200;
    2933             : 
    2934           0 :     void EncryptRC4(msfilter::MSCodec_Std97& rCtx, SvStream &rIn, SvStream &rOut)
    2935             :     {
    2936           0 :         rIn.Seek(STREAM_SEEK_TO_END);
    2937           0 :         sal_uLong nLen = rIn.Tell();
    2938           0 :         rIn.Seek(0);
    2939             : 
    2940             :         sal_uInt8 in[WW_BLOCKSIZE];
    2941           0 :         for (sal_Size nI = 0, nBlock = 0; nI < nLen; nI += WW_BLOCKSIZE, ++nBlock)
    2942             :         {
    2943           0 :             sal_Size nBS = (nLen - nI > WW_BLOCKSIZE) ? WW_BLOCKSIZE : nLen - nI;
    2944           0 :             nBS = rIn.Read(in, nBS);
    2945           0 :             rCtx.InitCipher(nBlock);
    2946           0 :             rCtx.Encode(in, nBS, in, nBS);
    2947           0 :             rOut.Write(in, nBS);
    2948             :         }
    2949           0 :     }
    2950             : }
    2951             : 
    2952          97 : void MSWordExportBase::ExportDocument( bool bWriteAll )
    2953             : {
    2954          97 :     nCharFmtStart = ANZ_DEFAULT_STYLES;
    2955          97 :     nFmtCollStart = nCharFmtStart + pDoc->GetCharFmts()->size() - 1;
    2956             : 
    2957             :     bStyDef = bBreakBefore = bOutKF =
    2958             :         bOutFlyFrmAttrs = bOutPageDescs = bOutTable = bOutFirstPage =
    2959             :         bOutGrf = bInWriteEscher = bStartTOX =
    2960          97 :         bInWriteTOX = false;
    2961             : 
    2962          97 :     bFtnAtTxtEnd = bEndAtTxtEnd = true;
    2963             : 
    2964          97 :     mpParentFrame = 0;
    2965          97 :     pFlyOffset = 0;
    2966          97 :     eNewAnchorType = FLY_AT_PAGE;
    2967          97 :     nTxtTyp = TXT_MAINTEXT;
    2968          97 :     nStyleBeforeFly = nLastFmtId = 0;
    2969          97 :     pStyAttr = 0;
    2970          97 :     pCurrentStyle = NULL;
    2971          97 :     pOutFmtNode = 0;
    2972          97 :     pEscher = 0;
    2973          97 :     pRedlAuthors = 0;
    2974          97 :     aTOXArr.clear();
    2975             : 
    2976          97 :     if ( !pOLEExp )
    2977             :     {
    2978          97 :         sal_uInt32 nSvxMSDffOLEConvFlags = 0;
    2979          97 :         const SvtFilterOptions& rOpt = SvtFilterOptions::Get();
    2980          97 :         if ( rOpt.IsMath2MathType() )
    2981          97 :             nSvxMSDffOLEConvFlags |= OLE_STARMATH_2_MATHTYPE;
    2982          97 :         if ( rOpt.IsWriter2WinWord() )
    2983          97 :             nSvxMSDffOLEConvFlags |= OLE_STARWRITER_2_WINWORD;
    2984          97 :         if ( rOpt.IsCalc2Excel() )
    2985          97 :             nSvxMSDffOLEConvFlags |= OLE_STARCALC_2_EXCEL;
    2986          97 :         if ( rOpt.IsImpress2PowerPoint() )
    2987          97 :             nSvxMSDffOLEConvFlags |= OLE_STARIMPRESS_2_POWERPOINT;
    2988             : 
    2989          97 :         pOLEExp = new SvxMSExportOLEObjects( nSvxMSDffOLEConvFlags );
    2990             :     }
    2991             : 
    2992          97 :     if ( !pOCXExp && pDoc->GetDocShell() )
    2993          97 :         pOCXExp = new SwMSConvertControls( pDoc->GetDocShell(), pCurPam );
    2994             : 
    2995             :     // #i81405# - Collect anchored objects before changing the redline mode.
    2996          97 :     maFrames = GetFrames( *pDoc, bWriteAll? NULL : pOrigPam );
    2997             : 
    2998          97 :     mnRedlineMode = pDoc->GetRedlineMode();
    2999          97 :     if ( !pDoc->GetRedlineTbl().empty() )
    3000             :     {
    3001             :         pDoc->SetRedlineMode( (RedlineMode_t)(mnRedlineMode | nsRedlineMode_t::REDLINE_SHOW_DELETE |
    3002           4 :                                      nsRedlineMode_t::REDLINE_SHOW_INSERT) );
    3003             :     }
    3004             : 
    3005          97 :     maFontHelper.InitFontTable( SupportsUnicode(), *pDoc );
    3006          97 :     GatherChapterFields();
    3007             : 
    3008          97 :     CollectOutlineBookmarks(*pDoc);
    3009             : 
    3010             :     // make unique OrdNums (Z-Order) for all drawing-/fly Objects
    3011          97 :     if ( pDoc->GetDrawModel() )
    3012          97 :         pDoc->GetDrawModel()->GetPage( 0 )->RecalcObjOrdNums();
    3013             : 
    3014          97 :     ExportDocument_Impl();
    3015             : 
    3016          97 :     if ( mnRedlineMode != pDoc->GetRedlineMode() )
    3017           0 :         pDoc->SetRedlineMode( (RedlineMode_t)(mnRedlineMode) );
    3018          97 : }
    3019             : 
    3020           8 : bool SwWW8Writer::InitStd97CodecUpdateMedium( ::msfilter::MSCodec_Std97& rCodec )
    3021             : {
    3022           8 :     uno::Sequence< beans::NamedValue > aEncryptionData;
    3023             : 
    3024           8 :     if ( mpMedium )
    3025             :     {
    3026           8 :         SFX_ITEMSET_ARG( mpMedium->GetItemSet(), pEncryptionDataItem, SfxUnoAnyItem, SID_ENCRYPTIONDATA, sal_False );
    3027           8 :         if ( pEncryptionDataItem && ( pEncryptionDataItem->GetValue() >>= aEncryptionData ) && !rCodec.InitCodec( aEncryptionData ) )
    3028             :         {
    3029             :             OSL_ENSURE( false, "Unexpected EncryptionData!" );
    3030           0 :             aEncryptionData.realloc( 0 );
    3031             :         }
    3032             : 
    3033           8 :         if ( !aEncryptionData.getLength() )
    3034             :         {
    3035             :             // try to generate the encryption data based on password
    3036           8 :             SFX_ITEMSET_ARG( mpMedium->GetItemSet(), pPasswordItem, SfxStringItem, SID_PASSWORD, sal_False );
    3037           8 :             if ( pPasswordItem && !pPasswordItem->GetValue().isEmpty() && pPasswordItem->GetValue().getLength() <= 15 )
    3038             :             {
    3039             :                 // Generate random number with a seed of time as salt.
    3040             :                 TimeValue aTime;
    3041           0 :                 osl_getSystemTime( &aTime );
    3042           0 :                 rtlRandomPool aRandomPool = rtl_random_createPool ();
    3043           0 :                 rtl_random_addBytes ( aRandomPool, &aTime, 8 );
    3044             : 
    3045             :                 sal_uInt8 pDocId[ 16 ];
    3046           0 :                 rtl_random_getBytes( aRandomPool, pDocId, 16 );
    3047             : 
    3048           0 :                 rtl_random_destroyPool( aRandomPool );
    3049             : 
    3050             :                 sal_Unicode aPassword[16];
    3051           0 :                 memset( aPassword, 0, sizeof( aPassword ) );
    3052             : 
    3053           0 :                 OUString sPassword(pPasswordItem->GetValue());
    3054           0 :                 for ( sal_Int32 nChar = 0; nChar < sPassword.getLength(); ++nChar )
    3055           0 :                     aPassword[nChar] = sPassword[nChar];
    3056             : 
    3057           0 :                 rCodec.InitKey( aPassword, pDocId );
    3058           0 :                 aEncryptionData = rCodec.GetEncryptionData();
    3059             : 
    3060           0 :                 mpMedium->GetItemSet()->Put( SfxUnoAnyItem( SID_ENCRYPTIONDATA, uno::makeAny( aEncryptionData ) ) );
    3061             :             }
    3062             :         }
    3063             : 
    3064           8 :         if ( aEncryptionData.getLength() )
    3065           0 :             mpMedium->GetItemSet()->ClearItem( SID_PASSWORD );
    3066             :     }
    3067             : 
    3068             :     // nonempty encryption data means hier that the codec was successfully initialized
    3069           8 :     return ( aEncryptionData.getLength() != 0 );
    3070             : }
    3071             : 
    3072           8 : void WW8Export::ExportDocument_Impl()
    3073             : {
    3074           8 :     PrepareStorage();
    3075             : 
    3076           8 :     pFib = new WW8Fib( bWrtWW8 ? 8 : 6 );
    3077             : 
    3078           8 :     SvStorageStreamRef xWwStrm( GetWriter().GetStorage().OpenSotStream( aMainStg ) );
    3079          16 :     SvStorageStreamRef xTableStrm( xWwStrm ), xDataStrm( xWwStrm );
    3080           8 :     xWwStrm->SetBufferSize( 32768 );
    3081             : 
    3082           8 :     if( bWrtWW8 )
    3083             :     {
    3084           8 :         pFib->fWhichTblStm = 1;
    3085          16 :         xTableStrm = GetWriter().GetStorage().OpenSotStream(OUString(SL::a1Table),
    3086           8 :             STREAM_STD_WRITE );
    3087          16 :         xDataStrm = GetWriter().GetStorage().OpenSotStream(OUString(SL::aData),
    3088           8 :             STREAM_STD_WRITE );
    3089             : 
    3090           8 :         xDataStrm->SetBufferSize( 32768 );  // for graphics
    3091           8 :         xTableStrm->SetBufferSize( 16384 ); // for the Font-/Style-Table, etc.
    3092             : 
    3093           8 :         xTableStrm->SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
    3094           8 :         xDataStrm->SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
    3095             :     }
    3096             : 
    3097           8 :     GetWriter().SetStream( & *xWwStrm );
    3098           8 :     pTableStrm = &xTableStrm;
    3099           8 :     pDataStrm = &xDataStrm;
    3100             : 
    3101           8 :     Strm().SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
    3102             : 
    3103          16 :     utl::TempFile aTempMain;
    3104           8 :     aTempMain.EnableKillingFile();
    3105          16 :     utl::TempFile aTempTable;
    3106           8 :     aTempTable.EnableKillingFile();
    3107          16 :     utl::TempFile aTempData;
    3108           8 :     aTempData.EnableKillingFile();
    3109             : 
    3110          16 :     msfilter::MSCodec_Std97 aCtx;
    3111           8 :     bool bEncrypt = m_pWriter ? m_pWriter->InitStd97CodecUpdateMedium( aCtx ) : false;
    3112           8 :     if ( bEncrypt )
    3113             :     {
    3114           0 :         GetWriter().SetStream(
    3115           0 :             aTempMain.GetStream( STREAM_READWRITE | STREAM_SHARE_DENYWRITE ) );
    3116             : 
    3117           0 :         pTableStrm = aTempTable.GetStream( STREAM_READWRITE | STREAM_SHARE_DENYWRITE );
    3118             : 
    3119           0 :         pDataStrm = aTempData.GetStream( STREAM_READWRITE | STREAM_SHARE_DENYWRITE );
    3120             : 
    3121           0 :         sal_uInt8 aRC4EncryptionHeader[ 52 ] = {0};
    3122           0 :         pTableStrm->Write( aRC4EncryptionHeader, 52 );
    3123             :     }
    3124             : 
    3125             :     // Default: "Standard"
    3126           8 :     pSepx = new WW8_WrPlcSepx( *this );                         // Sections/headers/footers
    3127             : 
    3128           8 :     pFtn = new WW8_WrPlcFtnEdn( TXT_FTN );                      // Footnotes
    3129           8 :     pEdn = new WW8_WrPlcFtnEdn( TXT_EDN );                      // Endnotes
    3130           8 :     pAtn = new WW8_WrPlcAnnotations;                                 // PostIts
    3131           8 :     pTxtBxs = new WW8_WrPlcTxtBoxes( TXT_TXTBOX );
    3132           8 :     pHFTxtBxs = new WW8_WrPlcTxtBoxes( TXT_HFTXTBOX );
    3133             : 
    3134           8 :     pSdrObjs = new MainTxtPlcDrawObj;   // Draw-/Fly-Objects for main text
    3135           8 :     pHFSdrObjs = new HdFtPlcDrawObj;    // Draw-/Fly-Objects for header/footer
    3136             : 
    3137           8 :     pBkmks = new WW8_WrtBookmarks;                          // Bookmarks
    3138           8 :     GetWriter().CreateBookmarkTbl();
    3139             : 
    3140           8 :     pPapPlc = new WW8_WrPlcPn( *this, PAP, pFib->fcMin );
    3141           8 :     pChpPlc = new WW8_WrPlcPn( *this, CHP, pFib->fcMin );
    3142           8 :     pO = new ww::bytes();
    3143           8 :     pStyles = new MSWordStyles( *this );
    3144           8 :     pFldMain = new WW8_WrPlcFld( 2, TXT_MAINTEXT );
    3145           8 :     pFldHdFt = new WW8_WrPlcFld( 2, TXT_HDFT );
    3146           8 :     pFldFtn = new WW8_WrPlcFld( 2, TXT_FTN );
    3147           8 :     pFldEdn = new WW8_WrPlcFld( 2, TXT_EDN );
    3148           8 :     pFldAtn = new WW8_WrPlcFld( 2, TXT_ATN );
    3149           8 :     pFldTxtBxs = new WW8_WrPlcFld( 2, TXT_TXTBOX );
    3150           8 :     pFldHFTxtBxs = new WW8_WrPlcFld( 2, TXT_HFTXTBOX );
    3151             : 
    3152           8 :     pMagicTable = new WW8_WrMagicTable;
    3153             : 
    3154           8 :     pGrf = new SwWW8WrGrf( *this );
    3155           8 :     pPiece = new WW8_WrPct( pFib->fcMin, bWrtWW8 );
    3156           8 :     pDop = new WW8Dop;
    3157             : 
    3158             : 
    3159           8 :     pDop->fRevMarking = 0 != ( nsRedlineMode_t::REDLINE_ON & mnRedlineMode );
    3160           8 :     pDop->fRMView = 0 != ( nsRedlineMode_t::REDLINE_SHOW_DELETE & mnRedlineMode );
    3161           8 :     pDop->fRMPrint = pDop->fRMView;
    3162             : 
    3163             :     // set AutoHyphenation flag if found in default para style
    3164             :     const SfxPoolItem* pItem;
    3165             :     SwTxtFmtColl* pStdTxtFmtColl =
    3166           8 :         pDoc->GetTxtCollFromPool(RES_POOLCOLL_STANDARD, false);
    3167          16 :     if (pStdTxtFmtColl && SFX_ITEM_SET == pStdTxtFmtColl->GetItemState(
    3168           8 :         RES_PARATR_HYPHENZONE, false, &pItem))
    3169             :     {
    3170           3 :         pDop->fAutoHyphen = ((const SvxHyphenZoneItem*)pItem)->IsHyphen();
    3171             :     }
    3172             : 
    3173           8 :     StoreDoc1();
    3174             : 
    3175           8 :     if ( bEncrypt )
    3176             :     {
    3177             :         SvStream *pStrmTemp, *pTableStrmTemp, *pDataStrmTemp;
    3178           0 :         pStrmTemp = &xWwStrm;
    3179           0 :         pTableStrmTemp = &xTableStrm;
    3180           0 :         pDataStrmTemp = &xDataStrm;
    3181             : 
    3182           0 :         if ( pDataStrmTemp && pDataStrmTemp != pStrmTemp)
    3183           0 :             EncryptRC4(aCtx, *pDataStrm, *pDataStrmTemp);
    3184             : 
    3185           0 :         EncryptRC4(aCtx, *pTableStrm, *pTableStrmTemp);
    3186             : 
    3187             :         // Write Unencrypted Header 52 bytes to the start of the table stream
    3188             :         // EncryptionVersionInfo (4 bytes): A Version structure where Version.vMajor MUST be 0x0001, and Version.vMinor MUST be 0x0001.
    3189           0 :         pTableStrmTemp->Seek( 0 );
    3190           0 :         sal_uInt32 nEncType = 0x10001;
    3191           0 :         *pTableStrmTemp << nEncType;
    3192             : 
    3193             :         sal_uInt8 pDocId[16];
    3194           0 :         aCtx.GetDocId( pDocId );
    3195             : 
    3196             :         sal_uInt8 pSaltData[16];
    3197             :         sal_uInt8 pSaltDigest[16];
    3198           0 :         aCtx.GetEncryptKey( pDocId, pSaltData, pSaltDigest );
    3199             : 
    3200           0 :         pTableStrmTemp->Write( pDocId, 16 );
    3201           0 :         pTableStrmTemp->Write( pSaltData, 16 );
    3202           0 :         pTableStrmTemp->Write( pSaltDigest, 16 );
    3203             : 
    3204           0 :         EncryptRC4(aCtx, GetWriter().Strm(), *pStrmTemp);
    3205             : 
    3206             :         // Write Unencrypted Fib 68 bytes to the start of the workdocument stream
    3207           0 :         pFib->fEncrypted = 1; // fEncrypted indicates the document is encrypted.
    3208           0 :         pFib->fObfuscated = 0; // Must be 0 for RC4.
    3209           0 :         pFib->nHash = 0x34; // encrypt header bytes count of table stream.
    3210           0 :         pFib->nKey = 0; // lkey2 must be 0 for RC4.
    3211             : 
    3212           0 :         pStrmTemp->Seek( 0 );
    3213           0 :         pFib->WriteHeader( *pStrmTemp );
    3214             :     }
    3215             : 
    3216           8 :     if (pUsedNumTbl)           // all used NumRules
    3217             :     {
    3218             :         // clear the part of the list array that was copied from the document
    3219             :         // - it's an auto delete array, so the rest of the array which are
    3220             :         // duplicated lists that were added during the export will be deleted.
    3221           2 :         pUsedNumTbl->erase(pUsedNumTbl->begin(), pUsedNumTbl->begin() + pUsedNumTbl->size() - nUniqueList);
    3222           2 :         delete pUsedNumTbl;
    3223             :     }
    3224             : 
    3225           8 :     DELETEZ( pGrf );
    3226           8 :     DELETEZ( pMagicTable );
    3227           8 :     DELETEZ( pFldFtn );
    3228           8 :     DELETEZ( pFldTxtBxs );
    3229           8 :     DELETEZ( pFldHFTxtBxs );
    3230           8 :     DELETEZ( pFldAtn );
    3231           8 :     DELETEZ( pFldEdn );
    3232           8 :     DELETEZ( pFldHdFt );
    3233           8 :     DELETEZ( pFldMain );
    3234           8 :     DELETEZ( pStyles );
    3235           8 :     DELETEZ( pO );
    3236           8 :     DELETEZ( pChpPlc );
    3237           8 :     DELETEZ( pPapPlc );
    3238           8 :     DELETEZ( pSepx );
    3239             : 
    3240           8 :     delete pRedlAuthors;
    3241           8 :     delete pSdrObjs;
    3242           8 :     delete pHFSdrObjs;
    3243           8 :     delete pTxtBxs;
    3244           8 :     delete pHFTxtBxs;
    3245           8 :     delete pAtn;
    3246           8 :     delete pEdn;
    3247           8 :     delete pFtn;
    3248           8 :     delete pBkmks;
    3249           8 :     delete pPiece;
    3250           8 :     delete pDop;
    3251           8 :     delete pFib;
    3252           8 :     GetWriter().SetStream( 0 );
    3253             : 
    3254             : 
    3255           8 :     xWwStrm->SetBufferSize( 0 );
    3256           8 :     if( bWrtWW8 )
    3257             :     {
    3258           8 :         xTableStrm->SetBufferSize( 0 );
    3259           8 :         xDataStrm->SetBufferSize( 0 );
    3260           8 :         if( 0 == pDataStrm->Seek( STREAM_SEEK_TO_END ))
    3261             :         {
    3262           7 :             xDataStrm.Clear();
    3263           7 :             pDataStrm = 0;
    3264           7 :             GetWriter().GetStorage().Remove(OUString(SL::aData));
    3265             :         }
    3266           8 :     }
    3267           8 : }
    3268             : 
    3269             : 
    3270           8 : void WW8Export::PrepareStorage()
    3271             : {
    3272             :     sal_uLong nLen;
    3273             :     const sal_uInt8* pData;
    3274             :     const char* pName;
    3275             :     sal_uInt32 nId1;
    3276             : 
    3277           8 :     if (bWrtWW8)
    3278             :     {
    3279             :         static const char aUserName[] = "Microsoft Word-Document";
    3280             :         static const sal_uInt8 aCompObj[] =
    3281             :         {
    3282             :             0x01, 0x00, 0xFE, 0xFF, 0x03, 0x0A, 0x00, 0x00,
    3283             :             0xFF, 0xFF, 0xFF, 0xFF, 0x06, 0x09, 0x02, 0x00,
    3284             :             0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00,
    3285             :             0x00, 0x00, 0x00, 0x46, 0x18, 0x00, 0x00, 0x00,
    3286             :             0x4D, 0x69, 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66,
    3287             :             0x74, 0x20, 0x57, 0x6F, 0x72, 0x64, 0x2D, 0x44,
    3288             :             0x6F, 0x6B, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x00,
    3289             :             0x0A, 0x00, 0x00, 0x00, 0x4D, 0x53, 0x57, 0x6F,
    3290             :             0x72, 0x64, 0x44, 0x6F, 0x63, 0x00, 0x10, 0x00,
    3291             :             0x00, 0x00, 0x57, 0x6F, 0x72, 0x64, 0x2E, 0x44,
    3292             :             0x6F, 0x63, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x2E,
    3293             :             0x38, 0x00, 0xF4, 0x39, 0xB2, 0x71, 0x00, 0x00,
    3294             :             0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    3295             :             0x00, 0x00
    3296             :         };
    3297             : 
    3298           8 :         pName = aUserName;
    3299           8 :         pData = aCompObj;
    3300           8 :         nLen = sizeof( aCompObj );
    3301           8 :         nId1 = 0x00020906L;
    3302             :     }
    3303             :     else
    3304             :     {
    3305             :         static const char aUserName[] = "Microsoft Word 6.0 Document";
    3306             :         static const sal_uInt8 aCompObj[] =
    3307             :         {
    3308             :             0x01, 0x00, 0xFE, 0xFF, 0x03, 0x0A, 0x00, 0x00,
    3309             :             0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x09, 0x02, 0x00,
    3310             :             0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00,
    3311             :             0x00, 0x00, 0x00, 0x46, 0x1C, 0x00, 0x00, 0x00,
    3312             :             0x4D, 0x69, 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66,
    3313             :             0x74, 0x20, 0x57, 0x6F, 0x72, 0x64, 0x20, 0x36,
    3314             :             0x2E, 0x30, 0x2D, 0x44, 0x6F, 0x6B, 0x75, 0x6D,
    3315             :             0x65, 0x6E, 0x74, 0x00, 0x0A, 0x00, 0x00, 0x00,
    3316             :             0x4D, 0x53, 0x57, 0x6F, 0x72, 0x64, 0x44, 0x6F,
    3317             :             0x63, 0x00, 0x10, 0x00, 0x00, 0x00, 0x57, 0x6F,
    3318             :             0x72, 0x64, 0x2E, 0x44, 0x6F, 0x63, 0x75, 0x6D,
    3319             :             0x65, 0x6E, 0x74, 0x2E, 0x36, 0x00, 0x00, 0x00,
    3320             :             0x00, 0x00
    3321             :         };
    3322             : 
    3323           0 :         pName = aUserName;
    3324           0 :         pData = aCompObj;
    3325           0 :         nLen = sizeof( aCompObj );
    3326           0 :         nId1 = 0x00020900L;
    3327             :     }
    3328             : 
    3329             :     SvGlobalName aGName( nId1, 0x0000, 0x0000, 0xc0, 0x00, 0x00, 0x00,
    3330           8 :                          0x00, 0x00, 0x00, 0x46 );
    3331           8 :     GetWriter().GetStorage().SetClass( aGName, 0, OUString::createFromAscii( pName ));
    3332          16 :     SvStorageStreamRef xStor( GetWriter().GetStorage().OpenSotStream(sCompObj) );
    3333           8 :     xStor->Write( pData, nLen );
    3334             : 
    3335           8 :     SwDocShell* pDocShell = pDoc->GetDocShell ();
    3336             :     OSL_ENSURE(pDocShell, "no SwDocShell");
    3337             : 
    3338           8 :     if (pDocShell) {
    3339             :         uno::Reference<document::XDocumentPropertiesSupplier> xDPS(
    3340           8 :             pDocShell->GetModel(), uno::UNO_QUERY_THROW);
    3341             :         uno::Reference<document::XDocumentProperties> xDocProps(
    3342          16 :             xDPS->getDocumentProperties());
    3343             :         OSL_ENSURE(xDocProps.is(), "DocumentProperties is null");
    3344             : 
    3345           8 :         if (xDocProps.is())
    3346             :         {
    3347           8 :             if ( SvtFilterOptions::Get().IsEnableWordPreview() )
    3348             :             {
    3349             :                 ::boost::shared_ptr<GDIMetaFile> pMetaFile =
    3350           0 :                     pDocShell->GetPreviewMetaFile (sal_False);
    3351             :                 uno::Sequence<sal_uInt8> metaFile(
    3352           0 :                     sfx2::convertMetaFile(pMetaFile.get()));
    3353           0 :                 sfx2::SaveOlePropertySet(xDocProps, &GetWriter().GetStorage(), &metaFile);
    3354             :             }
    3355             :             else
    3356           8 :                 sfx2::SaveOlePropertySet( xDocProps, &GetWriter().GetStorage() );
    3357           8 :         }
    3358           8 :     }
    3359           8 : }
    3360             : 
    3361           8 : sal_uLong SwWW8Writer::WriteStorage()
    3362             : {
    3363             :     // #i34818# - update layout (if present), for SwWriteTable
    3364           8 :     ViewShell* pViewShell = NULL;
    3365           8 :     pDoc->GetEditShell( &pViewShell );
    3366           8 :     if( pViewShell != NULL )
    3367           8 :         pViewShell->CalcLayout();
    3368             : 
    3369           8 :     long nMaxNode = pDoc->GetNodes().Count();
    3370           8 :     ::StartProgress( STR_STATSTR_W4WWRITE, 0, nMaxNode, pDoc->GetDocShell() );
    3371             : 
    3372             :     // Respect table at the beginning of the document
    3373             :     {
    3374           8 :         SwTableNode * pTNd = pCurPam->GetNode()->FindTableNode();
    3375           8 :         if( pTNd && bWriteAll )
    3376             :             // start with the table node !!
    3377           0 :             pCurPam->GetPoint()->nNode = *pTNd;
    3378             :     }
    3379             : 
    3380             :     // Do the actual export
    3381             :     {
    3382           8 :         WW8Export aExport( this, pDoc, pCurPam, pOrigPam, m_bWrtWW8 );
    3383           8 :         m_pExport = &aExport;
    3384           8 :         aExport.ExportDocument( bWriteAll );
    3385           8 :         m_pExport = NULL;
    3386             :     }
    3387             : 
    3388           8 :     ::EndProgress( pDoc->GetDocShell() );
    3389           8 :     return 0;
    3390             : }
    3391             : 
    3392           0 : sal_uLong SwWW8Writer::WriteMedium( SfxMedium& )
    3393             : {
    3394           0 :     return WriteStorage();
    3395             : }
    3396             : 
    3397           8 : sal_uLong SwWW8Writer::Write( SwPaM& rPaM, SfxMedium& rMed,
    3398             :                           const String* pFileName )
    3399             : {
    3400           8 :     mpMedium = &rMed;
    3401           8 :     sal_uLong nRet = StgWriter::Write( rPaM, rMed, pFileName );
    3402           8 :     mpMedium = NULL;
    3403           8 :     return nRet;
    3404             : }
    3405             : 
    3406          97 : MSWordExportBase::MSWordExportBase( SwDoc *pDocument, SwPaM *pCurrentPam, SwPaM *pOriginalPam )
    3407             :     : aMainStg(sMainStream), pISet(0), pUsedNumTbl(0), mpTopNodeOfHdFtPage(0),
    3408             :     pBmpPal(0), pOLEExp(0), pOCXExp(0),
    3409           0 :     mpTableInfo(new ww8::WW8TableInfo()), nUniqueList(0),
    3410             :     mnHdFtIndex(0), pAktPageDesc(0), pPapPlc(0), pChpPlc(0), pChpIter(0),
    3411             :     pStyles( NULL ),
    3412             :     bHasHdr(false), bHasFtr(false), bSubstituteBullets(true),
    3413             :     mbExportModeRTF( false ),
    3414             :     mbOutOutlineOnly( false ),
    3415             :     pDoc( pDocument ),
    3416             :     pCurPam( pCurrentPam ),
    3417          97 :     pOrigPam( pOriginalPam )
    3418             : {
    3419          97 : }
    3420             : 
    3421         194 : MSWordExportBase::~MSWordExportBase()
    3422             : {
    3423          97 :     delete pBmpPal;
    3424          97 :     delete pOLEExp;
    3425          97 :     delete pOCXExp;
    3426          97 : }
    3427             : 
    3428           8 : WW8Export::WW8Export( SwWW8Writer *pWriter,
    3429             :         SwDoc *pDocument, SwPaM *pCurrentPam, SwPaM *pOriginalPam,
    3430             :         bool bIsWW8 )
    3431             :     : MSWordExportBase( pDocument, pCurrentPam, pOriginalPam ),
    3432             :       pO( NULL ),
    3433             :       pSepx( NULL ),
    3434             :       bWrtWW8( bIsWW8 ),
    3435             :       m_pWriter( pWriter ),
    3436           8 :       m_pAttrOutput( new WW8AttributeOutput( *this ) )
    3437             : {
    3438           8 : }
    3439             : 
    3440          16 : WW8Export::~WW8Export()
    3441             : {
    3442           8 :     delete m_pAttrOutput, m_pAttrOutput = NULL;
    3443           8 : }
    3444             : 
    3445        7828 : AttributeOutputBase& WW8Export::AttrOutput() const
    3446             : {
    3447        7828 :     return *m_pAttrOutput;
    3448             : }
    3449             : 
    3450           0 : MSWordSections& WW8Export::Sections() const
    3451             : {
    3452           0 :     return *pSepx;
    3453             : }
    3454             : 
    3455           8 : SwWW8Writer::SwWW8Writer(const String& rFltName, const String& rBaseURL)
    3456             :     : StgWriter(),
    3457           8 :       m_bWrtWW8( rFltName.EqualsAscii( FILTER_WW8 ) ),
    3458             :       m_pExport( NULL ),
    3459          16 :       mpMedium( 0 )
    3460             : {
    3461           8 :     SetBaseURL( rBaseURL );
    3462           8 : }
    3463             : 
    3464          16 : SwWW8Writer::~SwWW8Writer()
    3465             : {
    3466          16 : }
    3467             : 
    3468           0 : extern "C" SAL_DLLPUBLIC_EXPORT sal_uLong SAL_CALL SaveOrDelMSVBAStorage_ww8( SfxObjectShell& rDoc, SotStorage& rStor, sal_Bool bSaveInto, const String& rStorageName )
    3469             : {
    3470           0 :     SvxImportMSVBasic aTmp( rDoc, rStor );
    3471           0 :     return aTmp.SaveOrDelMSVBAStorage( bSaveInto, rStorageName );
    3472             : }
    3473             : 
    3474           8 : extern "C" SAL_DLLPUBLIC_EXPORT void SAL_CALL ExportDOC( const String& rFltName, const String& rBaseURL, WriterRef& xRet )
    3475             : {
    3476           8 :     xRet = new SwWW8Writer( rFltName, rBaseURL );
    3477           8 : }
    3478             : 
    3479             : 
    3480           0 : extern "C" SAL_DLLPUBLIC_EXPORT sal_uLong SAL_CALL GetSaveWarningOfMSVBAStorage_ww8(  SfxObjectShell &rDocS )
    3481             : {
    3482           0 :     return SvxImportMSVBasic::GetSaveWarningOfMSVBAStorage( rDocS );
    3483             : }
    3484             : 
    3485          16 : bool WW8_WrPlcFtnEdn::WriteTxt( WW8Export& rWrt )
    3486             : {
    3487          16 :     bool bRet = false;
    3488          16 :     if (TXT_FTN == nTyp)
    3489             :     {
    3490           8 :         bRet = WriteGenericTxt( rWrt, TXT_FTN, rWrt.pFib->ccpFtn );
    3491           8 :         rWrt.pFldFtn->Finish( rWrt.Fc2Cp( rWrt.Strm().Tell() ),
    3492          16 :                             rWrt.pFib->ccpText );
    3493             :     }
    3494             :     else
    3495             :     {
    3496           8 :         bRet = WriteGenericTxt( rWrt, TXT_EDN, rWrt.pFib->ccpEdn );
    3497           8 :         rWrt.pFldEdn->Finish( rWrt.Fc2Cp( rWrt.Strm().Tell() ),
    3498           8 :                             rWrt.pFib->ccpText + rWrt.pFib->ccpFtn
    3499          16 :                             + rWrt.pFib->ccpHdr + rWrt.pFib->ccpAtn );
    3500             :     }
    3501          16 :     return bRet;
    3502             : }
    3503             : 
    3504          16 : void WW8_WrPlcFtnEdn::WritePlc( WW8Export& rWrt ) const
    3505             : {
    3506          16 :     if( TXT_FTN == nTyp )
    3507             :     {
    3508             :         WriteGenericPlc( rWrt, TXT_FTN, rWrt.pFib->fcPlcffndTxt,
    3509             :             rWrt.pFib->lcbPlcffndTxt, rWrt.pFib->fcPlcffndRef,
    3510           8 :             rWrt.pFib->lcbPlcffndRef );
    3511             :     }
    3512             :     else
    3513             :     {
    3514             :         WriteGenericPlc( rWrt, TXT_EDN, rWrt.pFib->fcPlcfendTxt,
    3515             :             rWrt.pFib->lcbPlcfendTxt, rWrt.pFib->fcPlcfendRef,
    3516           8 :             rWrt.pFib->lcbPlcfendRef );
    3517             :     }
    3518          16 : }
    3519             : 
    3520             : 
    3521           8 : bool WW8_WrPlcAnnotations::WriteTxt( WW8Export& rWrt )
    3522             : {
    3523           8 :     bool bRet = WriteGenericTxt( rWrt, TXT_ATN, rWrt.pFib->ccpAtn );
    3524           8 :     rWrt.pFldAtn->Finish( rWrt.Fc2Cp( rWrt.Strm().Tell() ),
    3525           8 :                         rWrt.pFib->ccpText + rWrt.pFib->ccpFtn
    3526          16 :                         + rWrt.pFib->ccpHdr );
    3527           8 :     return bRet;
    3528             : }
    3529             : 
    3530           8 : void WW8_WrPlcAnnotations::WritePlc( WW8Export& rWrt ) const
    3531             : {
    3532             :     WriteGenericPlc( rWrt, TXT_ATN, rWrt.pFib->fcPlcfandTxt,
    3533             :         rWrt.pFib->lcbPlcfandTxt, rWrt.pFib->fcPlcfandRef,
    3534           8 :         rWrt.pFib->lcbPlcfandRef );
    3535           8 : }
    3536             : 
    3537          16 : void WW8_WrPlcTxtBoxes::WritePlc( WW8Export& rWrt ) const
    3538             : {
    3539          16 :     if( TXT_TXTBOX == nTyp )
    3540             :     {
    3541             :         WriteGenericPlc( rWrt, nTyp, rWrt.pFib->fcPlcftxbxBkd,
    3542             :             rWrt.pFib->lcbPlcftxbxBkd, rWrt.pFib->fcPlcftxbxTxt,
    3543           8 :             rWrt.pFib->lcbPlcftxbxTxt );
    3544             :     }
    3545             :     else
    3546             :     {
    3547             :         WriteGenericPlc( rWrt, nTyp, rWrt.pFib->fcPlcfHdrtxbxBkd,
    3548             :             rWrt.pFib->lcbPlcfHdrtxbxBkd, rWrt.pFib->fcPlcfHdrtxbxTxt,
    3549           8 :             rWrt.pFib->lcbPlcfHdrtxbxTxt );
    3550             :     }
    3551          16 : }
    3552             : 
    3553           8 : void WW8Export::RestoreMacroCmds()
    3554             : {
    3555           8 :     pFib->fcCmds = pTableStrm->Tell();
    3556             : 
    3557           8 :     uno::Reference < embed::XStorage > xSrcRoot(pDoc->GetDocShell()->GetStorage());
    3558             :     try
    3559             :     {
    3560             :         uno::Reference < io::XStream > xSrcStream =
    3561          12 :                 xSrcRoot->openStreamElement( OUString(SL::aMSMacroCmds), embed::ElementModes::READ );
    3562           4 :         SvStream* pStream = ::utl::UcbStreamHelper::CreateStream( xSrcStream );
    3563             : 
    3564           4 :         if ( pStream && SVSTREAM_OK == pStream->GetError())
    3565             :         {
    3566           4 :             pStream->Seek(STREAM_SEEK_TO_END);
    3567           4 :             pFib->lcbCmds = pStream->Tell();
    3568           4 :             pStream->Seek(0);
    3569             : 
    3570           4 :             sal_uInt8 *pBuffer = new sal_uInt8[pFib->lcbCmds];
    3571           4 :             bool bReadOk = checkRead(*pStream, pBuffer, pFib->lcbCmds);
    3572           4 :             if (bReadOk)
    3573           4 :                 pTableStrm->Write(pBuffer, pFib->lcbCmds);
    3574           4 :             delete[] pBuffer;
    3575             : 
    3576             :         }
    3577             : 
    3578           4 :         delete pStream;
    3579             :     }
    3580           4 :     catch ( const uno::Exception& )
    3581             :     {
    3582             :     }
    3583             : 
    3584             :     // set len to FIB
    3585           8 :     pFib->lcbCmds = pTableStrm->Tell() - pFib->fcCmds;
    3586           8 : }
    3587             : 
    3588         236 : void WW8SHDLong::Write( WW8Export& rExport )
    3589             : {
    3590         236 :     rExport.InsUInt32( m_cvFore );
    3591         236 :     rExport.InsUInt32( m_cvBack );
    3592         236 :     rExport.InsUInt16( m_ipat );
    3593         236 : }
    3594             : 
    3595           0 : void WW8Export::WriteFormData( const ::sw::mark::IFieldmark& rFieldmark )
    3596             : {
    3597             :     OSL_ENSURE( bWrtWW8, "No 95 export yet" );
    3598           0 :     if ( !bWrtWW8 )
    3599           0 :         return;
    3600             : 
    3601           0 :     const ::sw::mark::IFieldmark* pFieldmark = &rFieldmark;
    3602           0 :     const ::sw::mark::ICheckboxFieldmark* pAsCheckbox = dynamic_cast< const ::sw::mark::ICheckboxFieldmark* >( pFieldmark );
    3603             : 
    3604             : 
    3605             :     OSL_ENSURE(rFieldmark.GetFieldname() == ODF_FORMTEXT ||
    3606             :                 rFieldmark.GetFieldname() == ODF_FORMDROPDOWN ||
    3607             :                 rFieldmark.GetFieldname() == ODF_FORMCHECKBOX, "Unknown field type!!!");
    3608           0 :     if ( ! ( rFieldmark.GetFieldname() == ODF_FORMTEXT ||
    3609           0 :                 rFieldmark.GetFieldname() == ODF_FORMDROPDOWN ||
    3610           0 :                 rFieldmark.GetFieldname() == ODF_FORMCHECKBOX ) )
    3611           0 :         return;
    3612             : 
    3613           0 :     int type = 0; // TextFieldmark
    3614           0 :     if ( pAsCheckbox )
    3615           0 :         type = 1;
    3616           0 :     if ( rFieldmark.GetFieldname() == ODF_FORMDROPDOWN )
    3617           0 :         type=2;
    3618             : 
    3619           0 :     ::sw::mark::IFieldmark::parameter_map_t::const_iterator pNameParameter = rFieldmark.GetParameters()->find("name");
    3620           0 :     OUString ffname;
    3621           0 :     if(pNameParameter != rFieldmark.GetParameters()->end())
    3622           0 :         pNameParameter->second >>= ffname;
    3623             : 
    3624           0 :     sal_uLong nDataStt = pDataStrm->Tell();
    3625           0 :     pChpPlc->AppendFkpEntry(Strm().Tell());
    3626             : 
    3627           0 :     WriteChar(0x01);
    3628             :     static sal_uInt8 aArr1[] =
    3629             :     {
    3630             :         0x03, 0x6a, 0,0,0,0,    // sprmCPicLocation
    3631             : 
    3632             :         0x06, 0x08, 0x01,       // sprmCFData
    3633             :         0x55, 0x08, 0x01,       // sprmCFSpec
    3634             :         0x02, 0x08, 0x01        // sprmCFFldVanish
    3635             :     };
    3636           0 :     sal_uInt8* pDataAdr = aArr1 + 2;
    3637           0 :     Set_UInt32(pDataAdr, nDataStt);
    3638             : 
    3639           0 :     pChpPlc->AppendFkpEntry( Strm().Tell(), sizeof( aArr1 ), aArr1 );
    3640             : 
    3641             :     struct FFDataHeader
    3642             :     {
    3643             :         sal_uInt32 version;
    3644             :         sal_uInt16 bits;
    3645             :         sal_uInt16 cch;
    3646             :         sal_uInt16 hps;
    3647           0 :         FFDataHeader() : version( 0xFFFFFFFF ), bits(0), cch(0), hps(0) {}
    3648             :     };
    3649             : 
    3650             : 
    3651           0 :     FFDataHeader aFldHeader;
    3652           0 :     aFldHeader.bits |= (type & 0x03);
    3653             : 
    3654           0 :     sal_Int32 ffres = 0; // rFieldmark.GetFFRes();
    3655           0 :     if ( pAsCheckbox && pAsCheckbox->IsChecked() )
    3656           0 :         ffres = 1;
    3657           0 :     else if ( type == 2 )
    3658             :     {
    3659           0 :         ::sw::mark::IFieldmark::parameter_map_t::const_iterator pResParameter = rFieldmark.GetParameters()->find(ODF_FORMDROPDOWN_RESULT);
    3660           0 :         if(pResParameter != rFieldmark.GetParameters()->end())
    3661           0 :             pResParameter->second >>= ffres;
    3662             :         else
    3663           0 :             ffres = 0;
    3664             :     }
    3665           0 :     aFldHeader.bits |= ( (ffres<<2) & 0x7C );
    3666             : 
    3667           0 :     std::vector< OUString > aListItems;
    3668           0 :     if (type==2)
    3669             :     {
    3670           0 :         aFldHeader.bits |= 0x8000; // ffhaslistbox
    3671           0 :         const ::sw::mark::IFieldmark::parameter_map_t* const pParameters = rFieldmark.GetParameters();
    3672           0 :         ::sw::mark::IFieldmark::parameter_map_t::const_iterator pListEntries = pParameters->find(ODF_FORMDROPDOWN_LISTENTRY);
    3673           0 :         if(pListEntries != pParameters->end())
    3674             :         {
    3675           0 :             uno::Sequence< OUString > vListEntries;
    3676           0 :             pListEntries->second >>= vListEntries;
    3677           0 :             copy(::comphelper::stl_begin(vListEntries), ::comphelper::stl_end(vListEntries), back_inserter(aListItems));
    3678             :         }
    3679             :     }
    3680             : 
    3681           0 :     const OUString ffdeftext;
    3682           0 :     const OUString ffformat;
    3683           0 :     const OUString ffhelptext;
    3684           0 :     const OUString ffstattext;
    3685           0 :     const OUString ffentrymcr;
    3686           0 :     const OUString ffexitmcr;
    3687             : 
    3688             : 
    3689             :     const sal_uInt8 aFldData[] =
    3690             :     {
    3691             :         0x44,0,         // the start of "next" data
    3692             :         0,0,0,0,0,0,0,0,0,0,                // PIC-Structure!  /10
    3693             :         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,    //  |              /16
    3694             :         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,    //  |              /16
    3695             :         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,    //  |              /16
    3696             :         0,0,0,0,                            // /               /4
    3697           0 :     };
    3698             :    sal_uInt32 slen = sizeof(sal_uInt32)
    3699           0 :         + sizeof(aFldData)
    3700           0 :         + sizeof( aFldHeader.version ) + sizeof( aFldHeader.bits ) + sizeof( aFldHeader.cch ) + sizeof( aFldHeader.hps )
    3701           0 :         + 2*ffname.getLength() + 4
    3702           0 :         + 2*ffformat.getLength() + 4
    3703           0 :         + 2*ffhelptext.getLength() + 4
    3704           0 :         + 2*ffstattext.getLength() + 4
    3705           0 :         + 2*ffentrymcr.getLength() + 4
    3706           0 :         + 2*ffexitmcr.getLength() + 4;
    3707           0 :     if ( type )
    3708           0 :         slen += 2; // wDef
    3709             :     else
    3710           0 :         slen += 2*ffdeftext.getLength() + 4; //xstzTextDef
    3711           0 :     if ( type==2 ) {
    3712           0 :         slen += 2; // sttb ( fExtend )
    3713           0 :         slen += 4; // for num of list items
    3714           0 :         const int items = aListItems.size();
    3715           0 :         for( int i = 0; i < items; i++ ) {
    3716           0 :             OUString item = aListItems[i];
    3717           0 :             slen += 2 * item.getLength() + 2;
    3718           0 :         }
    3719             :     }
    3720             : 
    3721           0 :     *pDataStrm << slen;
    3722             : 
    3723           0 :     int len = sizeof( aFldData );
    3724             :     OSL_ENSURE( len == 0x44-sizeof(sal_uInt32), "SwWW8Writer::WriteFormData(..) - wrong aFldData length" );
    3725           0 :     pDataStrm->Write( aFldData, len );
    3726             : 
    3727           0 :     *pDataStrm << aFldHeader.version << aFldHeader.bits << aFldHeader.cch << aFldHeader.hps;
    3728             : 
    3729           0 :     SwWW8Writer::WriteString_xstz( *pDataStrm, ffname, true ); // Form field name
    3730             : 
    3731           0 :     if ( !type )
    3732           0 :         SwWW8Writer::WriteString_xstz( *pDataStrm, ffdeftext, true );
    3733           0 :     if ( type )
    3734           0 :         *pDataStrm << sal_uInt16(0);
    3735             : 
    3736             : 
    3737           0 :     SwWW8Writer::WriteString_xstz( *pDataStrm, String( ffformat ), true );
    3738           0 :     SwWW8Writer::WriteString_xstz( *pDataStrm, String( ffhelptext ), true );
    3739           0 :     SwWW8Writer::WriteString_xstz( *pDataStrm, String( ffstattext ), true );
    3740           0 :     SwWW8Writer::WriteString_xstz( *pDataStrm, String( ffentrymcr ), true );
    3741           0 :     SwWW8Writer::WriteString_xstz( *pDataStrm, String( ffexitmcr ), true );
    3742           0 :     if (type==2) {
    3743           0 :         *pDataStrm<<(sal_uInt16)0xFFFF;
    3744           0 :         const int items=aListItems.size();
    3745           0 :         *pDataStrm<<(sal_uInt32)items;
    3746           0 :         for(int i=0;i<items;i++) {
    3747           0 :             OUString item=aListItems[i];
    3748           0 :             SwWW8Writer::WriteString_xstz( *pDataStrm, item, false );
    3749           0 :         }
    3750           0 :     }
    3751             : }
    3752             : 
    3753           0 : void WW8Export::WriteHyperlinkData( const sw::mark::IFieldmark& /*rFieldmark*/ )
    3754             : {
    3755             :     //@TODO implement me !!!
    3756           0 : }
    3757             : 
    3758         236 : void WW8AttributeOutput::TableNodeInfoInner( ww8::WW8TableNodeInfoInner::Pointer_t pNodeInfoInner )
    3759             : {
    3760             :     SVBT16 nStyle;
    3761         236 :     ShortToSVBT16( m_rWW8Export.nStyleBeforeFly, nStyle );
    3762             : 
    3763             : #ifdef DBG_UTIL
    3764             :     SAL_INFO( "sw.ww8", "<OutWW8_TableNodeInfoInner>" << pNodeInfoInner->toString());
    3765             : #endif
    3766             : 
    3767         236 :     m_rWW8Export.pO->clear();
    3768             : 
    3769         236 :     sal_uInt32 nShadowsBefore = pNodeInfoInner->getShadowsBefore();
    3770         236 :     if (nShadowsBefore > 0)
    3771             :     {
    3772             :         ww8::WW8TableNodeInfoInner::Pointer_t
    3773           0 :             pTmpNodeInfoInner(new ww8::WW8TableNodeInfoInner(NULL));
    3774             : 
    3775           0 :         pTmpNodeInfoInner->setDepth(pNodeInfoInner->getDepth());
    3776           0 :         pTmpNodeInfoInner->setEndOfCell(true);
    3777             : 
    3778           0 :         for (sal_uInt32 n = 0; n < nShadowsBefore; ++n)
    3779             :         {
    3780           0 :             m_rWW8Export.WriteCR(pTmpNodeInfoInner);
    3781             : 
    3782           0 :             m_rWW8Export.pO->insert( m_rWW8Export.pO->end(), (sal_uInt8*)&nStyle, (sal_uInt8*)&nStyle+2 );     // Style #
    3783           0 :             TableInfoCell(pTmpNodeInfoInner);
    3784             :             m_rWW8Export.pPapPlc->AppendFkpEntry
    3785           0 :                 ( m_rWW8Export.Strm().Tell(), m_rWW8Export.pO->size(), m_rWW8Export.pO->data() );
    3786             : 
    3787           0 :             m_rWW8Export.pO->clear();
    3788           0 :         }
    3789             :     }
    3790             : 
    3791         236 :     if (pNodeInfoInner->isEndOfCell())
    3792             :     {
    3793             :         SAL_INFO( "sw.ww8", "<endOfCell/>" );
    3794             : 
    3795           0 :         m_rWW8Export.WriteCR(pNodeInfoInner);
    3796             : 
    3797           0 :         m_rWW8Export.pO->insert( m_rWW8Export.pO->end(), (sal_uInt8*)&nStyle, (sal_uInt8*)&nStyle+2 );     // Style #
    3798           0 :         TableInfoCell(pNodeInfoInner);
    3799           0 :         m_rWW8Export.pPapPlc->AppendFkpEntry( m_rWW8Export.Strm().Tell(), m_rWW8Export.pO->size(), m_rWW8Export.pO->data() );
    3800             : 
    3801           0 :         m_rWW8Export.pO->clear();
    3802             :     }
    3803             : 
    3804         236 :     sal_uInt32 nShadowsAfter = pNodeInfoInner->getShadowsAfter();
    3805         236 :     if (nShadowsAfter > 0)
    3806             :     {
    3807             :         ww8::WW8TableNodeInfoInner::Pointer_t
    3808           0 :             pTmpNodeInfoInner(new ww8::WW8TableNodeInfoInner(NULL));
    3809             : 
    3810           0 :         pTmpNodeInfoInner->setDepth(pNodeInfoInner->getDepth());
    3811           0 :         pTmpNodeInfoInner->setEndOfCell(true);
    3812             : 
    3813           0 :         for (sal_uInt32 n = 0; n < nShadowsAfter; ++n)
    3814             :         {
    3815           0 :             m_rWW8Export.WriteCR(pTmpNodeInfoInner);
    3816             : 
    3817           0 :             m_rWW8Export.pO->insert( m_rWW8Export.pO->end(), (sal_uInt8*)&nStyle, (sal_uInt8*)&nStyle+2 );     // Style #
    3818           0 :             TableInfoCell(pTmpNodeInfoInner);
    3819           0 :             m_rWW8Export.pPapPlc->AppendFkpEntry( m_rWW8Export.Strm().Tell(), m_rWW8Export.pO->size(), m_rWW8Export.pO->data() );
    3820             : 
    3821           0 :             m_rWW8Export.pO->clear();
    3822           0 :         }
    3823             :     }
    3824             : 
    3825         236 :     if (pNodeInfoInner->isEndOfLine())
    3826             :     {
    3827             :         SAL_INFO( "sw.ww8", "<endOfLine/>" );
    3828             : 
    3829           0 :         TableRowEnd(pNodeInfoInner->getDepth());
    3830             : 
    3831           0 :         ShortToSVBT16(0, nStyle);
    3832           0 :         m_rWW8Export.pO->insert( m_rWW8Export.pO->end(), (sal_uInt8*)&nStyle, (sal_uInt8*)&nStyle+2 );     // Style #
    3833           0 :         TableInfoRow(pNodeInfoInner);
    3834           0 :         m_rWW8Export.pPapPlc->AppendFkpEntry( m_rWW8Export.Strm().Tell(), m_rWW8Export.pO->size(), m_rWW8Export.pO->data() );
    3835             : 
    3836           0 :         m_rWW8Export.pO->clear();
    3837             :     }
    3838             :     SAL_INFO( "sw.ww8", "</OutWW8_TableNodeInfoInner>" );
    3839         236 : }
    3840             : 
    3841         264 : void MSWordExportBase::OutputStartNode( const SwStartNode & rNode)
    3842             : {
    3843             : 
    3844             :     ww8::WW8TableNodeInfo::Pointer_t pNodeInfo =
    3845         264 :         mpTableInfo->getTableNodeInfo( &rNode );
    3846             : 
    3847         264 :     if (pNodeInfo.get() != NULL)
    3848             :     {
    3849             : #ifdef DBG_UTIL
    3850             :         SAL_INFO( "sw.ww8", pNodeInfo->toString());
    3851             : #endif
    3852         167 :         const ww8::WW8TableNodeInfo::Inners_t aInners = pNodeInfo->getInners();
    3853         167 :         ww8::WW8TableNodeInfo::Inners_t::const_reverse_iterator aIt(aInners.rbegin());
    3854         167 :         ww8::WW8TableNodeInfo::Inners_t::const_reverse_iterator aEnd(aInners.rend());
    3855         501 :         while (aIt != aEnd)
    3856             :         {
    3857         167 :             ww8::WW8TableNodeInfoInner::Pointer_t pInner = aIt->second;
    3858             : 
    3859         167 :             AttrOutput().TableNodeInfoInner(pInner);
    3860         167 :             ++aIt;
    3861         334 :         }
    3862             :     }
    3863         264 :     SAL_INFO( "sw.ww8", "</OutWW8_SwStartNode>" );
    3864         264 : }
    3865             : 
    3866         279 : void MSWordExportBase::OutputEndNode( const SwEndNode &rNode )
    3867             : {
    3868             : #ifdef DBG_UTIL
    3869             :     SAL_INFO( "sw.ww8", "<OutWW8_SwEndNode>" << dbg_out(&rNode));
    3870             : #endif
    3871             : 
    3872         279 :     ww8::WW8TableNodeInfo::Pointer_t pNodeInfo = mpTableInfo->getTableNodeInfo( &rNode );
    3873             : 
    3874         279 :     if (pNodeInfo.get() != NULL)
    3875             :     {
    3876             : #ifdef DBG_UTIL
    3877             :         SAL_INFO( "sw.ww8", pNodeInfo->toString());
    3878             : #endif
    3879             : 
    3880         167 :         const ww8::WW8TableNodeInfo::Inners_t aInners = pNodeInfo->getInners();
    3881         167 :         ww8::WW8TableNodeInfo::Inners_t::const_iterator aIt(aInners.begin());
    3882         167 :         ww8::WW8TableNodeInfo::Inners_t::const_iterator aEnd(aInners.end());
    3883         501 :         while (aIt != aEnd)
    3884             :          {
    3885         167 :             ww8::WW8TableNodeInfoInner::Pointer_t pInner = aIt->second;
    3886         167 :             AttrOutput().TableNodeInfoInner(pInner);
    3887         167 :             ++aIt;
    3888         334 :          }
    3889             :     }
    3890         279 :     SAL_INFO( "sw.ww8", "</OutWW8_SwEndNode>" );
    3891         279 : }
    3892             : 
    3893           0 : const NfKeywordTable & MSWordExportBase::GetNfKeywordTable()
    3894             : {
    3895           0 :     if (pKeyMap.get() == NULL)
    3896             :     {
    3897           0 :         pKeyMap.reset(new NfKeywordTable);
    3898           0 :         NfKeywordTable & rKeywordTable = *pKeyMap;
    3899           0 :         rKeywordTable[NF_KEY_D] = "d";
    3900           0 :         rKeywordTable[NF_KEY_DD] = "dd";
    3901           0 :         rKeywordTable[NF_KEY_DDD] = "ddd";
    3902           0 :         rKeywordTable[NF_KEY_DDDD] = "dddd";
    3903           0 :         rKeywordTable[NF_KEY_M] = "M";
    3904           0 :         rKeywordTable[NF_KEY_MM] = "MM";
    3905           0 :         rKeywordTable[NF_KEY_MMM] = "MMM";
    3906           0 :         rKeywordTable[NF_KEY_MMMM] = "MMMM";
    3907           0 :         rKeywordTable[NF_KEY_NN] = "ddd";
    3908           0 :         rKeywordTable[NF_KEY_NNN] = "dddd";
    3909           0 :         rKeywordTable[NF_KEY_NNNN] = "dddd";
    3910           0 :         rKeywordTable[NF_KEY_YY] = "yy";
    3911           0 :         rKeywordTable[NF_KEY_YYYY] = "yyyy";
    3912           0 :         rKeywordTable[NF_KEY_H] = "H";
    3913           0 :         rKeywordTable[NF_KEY_HH] = "HH";
    3914           0 :         rKeywordTable[NF_KEY_MI] = "m";
    3915           0 :         rKeywordTable[NF_KEY_MMI] = "mm";
    3916           0 :         rKeywordTable[NF_KEY_S] = "s";
    3917           0 :         rKeywordTable[NF_KEY_SS] = "ss";
    3918           0 :         rKeywordTable[NF_KEY_AMPM] = "AM/PM";
    3919             :     }
    3920             : 
    3921           0 :     return *pKeyMap;
    3922          18 : }
    3923             : 
    3924             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10