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 #ifndef INCLUDED_SW_SOURCE_FILTER_WW8_WRTWW8_HXX
21 #define INCLUDED_SW_SOURCE_FILTER_WW8_WRTWW8_HXX
22 
23 #include <sot/storage.hxx>
24 #include <tools/solar.h>
25 #include <tools/gen.hxx>
26 #include <editeng/editdata.hxx>
27 
28 #include <shellio.hxx>
29 
30 #include "ww8struc.hxx"
31 #include "ww8scan.hxx"
32 #include "fields.hxx"
33 #include "types.hxx"
34 #include "writerhelper.hxx"
35 #include <msfilter.hxx>
36 #include <expfld.hxx>
37 #include "WW8TableInfo.hxx"
38 
39 #include <vcl/graph.hxx>
40 
41 #include <boost/optional.hpp>
42 #include <o3tl/typed_flags_set.hxx>
43 
44 #include <cstddef>
45 #include <memory>
46 #include <map>
47 #include <vector>
48 
49 
50 class SvxBrushItem;
51 class EditTextObject;
52 
53 // some forward declarations
54 class SwWW8AttrIter;
55 namespace msfilter
56 {
57     class MSCodec_Std97;
58 }
59 
60 namespace editeng { class SvxBorderLine; }
61 
62 class AttributeOutputBase;
63 class DocxAttributeOutput;
64 class RtfAttributeOutput;
65 class BitmapPalette;
66 class SwEscherEx;
67 class DateTime;
68 namespace vcl { class Font; }
69 class MSWordExportBase;
70 class SdrObject;
71 class SdrTextObj;
72 class SfxItemSet;
73 class SvStream;
74 class SvxFontItem;
75 class SvxBoxItem;
76 class SwAttrSet;
77 class SwCharFormat;
78 class SwContentNode;
79 class SwField;
80 class SwFormat;
81 class SwFormatContent;
82 class SwFormatFootnote;
83 class SwFrameFormat;
84 class SwGrfNode;
85 class SwModify;
86 class SwNumFormat;
87 class SwNumRule;
88 class SwNumRuleTable;
89 class SwPageDesc;
90 class SwFormatPageDesc;
91 class SwOLENode;
92 class SwPostItField;
93 class SwRedlineData;
94 class SwSectionFormat;
95 class SwSectionNode;
96 class SwTableNode;
97 class SwTOXType;
98 class SwTextFormatColl;
99 class SwTextNode;
100 class SwWW8WrGrf;
101 class SwWW8Writer;
102 class MSWordStyles;
103 class WW8AttributeOutput;
104 class WW8Export;
105 class MSWordAttrIter;
106 class WW8_WrFkp;
107 class WW8_WrPlc0;
108 class WW8_WrPlc1;
109 class WW8_WrPlcField;
110 class WW8_WrMagicTable;
111 class WW8_WrPlcFootnoteEdn;
112 class WW8_WrPlcPn;
113 class WW8_WrPlcAnnotations;
114 class WW8_WrtFactoids;
115 class MSWordSections;
116 class WW8_WrPlcTextBoxes;
117 class WW8_WrPct;            // administration
118 class WW8_WrtBookmarks;
119 class WW8_WrtRedlineAuthor;
120 class SvxMSExportOLEObjects;
121 class SwMSConvertControls;
122 class WW8_WrPc;
123 
124 namespace com { namespace sun { namespace star { namespace embed {
125 class XEmbeddedObject;
126 } } } }
127 typedef std::map<const css::embed::XEmbeddedObject*, sal_Int32> WW8OleMap;
128 struct WW8_PdAttrDesc;
129 class SvxBrushItem;
130 namespace sw
131 {
132 namespace mark
133 {
134 class IFieldmark;
135 }
136 }
137 typedef std::set< sal_Int32 > SwSoftPageBreakList;
138 
139 #define GRF_MAGIC_1 0x12    // 3 magic bytes for PicLocFc attribute
140 #define GRF_MAGIC_2 0x34
141 #define GRF_MAGIC_3 0x56
142 #define GRF_MAGIC_321 0x563412L
143 
144 #define OLE_PREVIEW_AS_EMF  //If we want to export ole2 previews as emf in ww8+
145 
146 enum class FieldFlags : sal_uInt8 // for InsertField- Method
147 {
148     NONE        = 0x00,
149     Start       = 0x01,
150     CmdStart    = 0x02,
151     CmdEnd      = 0x04,
152     End         = 0x10,
153     Close       = 0x20,
154     All         = 0x37
155 };
156 namespace o3tl {
157     template<> struct typed_flags<FieldFlags> : is_typed_flags<FieldFlags, 0x37> {};
158 }
159 
160 enum TextTypes  //enums for TextTypes
161 {
162     TXT_MAINTEXT = 0, /*TXT_FTNEDN = 1,*/ TXT_HDFT = 2, TXT_FTN = 3,
163     TXT_EDN = 4, TXT_ATN = 5, TXT_TXTBOX = 6, TXT_HFTXTBOX= 7
164 };
165 
166 /**
167 enum to state the present state of the fly
168 */
169 enum FlyProcessingState
170 {
171     FLY_PROCESSED,
172     FLY_POSTPONED,
173     FLY_NOT_PROCESSED
174 };
175 
176 struct WW8_SepInfo
177 {
178     const SwPageDesc* pPageDesc;
179     const SwSectionFormat* pSectionFormat;
180     const SwNode* pPDNd;
181     sal_uLong const  nLnNumRestartNo;
182     ::boost::optional<sal_uInt16> const oPgRestartNo;
183     bool const bIsFirstParagraph;
184 
WW8_SepInfoWW8_SepInfo185     WW8_SepInfo( const SwPageDesc* pPD, const SwSectionFormat* pFormat,
186                  sal_uLong nLnRestart, ::boost::optional<sal_uInt16> oPgRestart = boost::none,
187                  const SwNode* pNd = nullptr, bool bIsFirstPara = false )
188         : pPageDesc( pPD ), pSectionFormat( pFormat ), pPDNd( pNd ),
189           nLnNumRestartNo( nLnRestart ), oPgRestartNo( oPgRestart ),
190           bIsFirstParagraph( bIsFirstPara )
191     {}
192 
193     bool IsProtected() const;
194 };
195 
196 /// Class to collect and output the sections/headers/footers.
197 // Plc for PageDescs -> Sepx ( Section Extensions )
198 class MSWordSections
199 {
200 protected:
201     bool mbDocumentIsProtected;
202     std::vector<WW8_SepInfo> aSects;
203 
204     void CheckForFacinPg( const WW8Export& rWrt ) const;
205     void NeedsDocumentProtected(const WW8_SepInfo &rInfo);
206 
207     //No copy, no assign
208     MSWordSections( const MSWordSections& );
209     MSWordSections& operator=( const MSWordSections& );
210 public:
211     explicit MSWordSections( MSWordExportBase& rExport );
212     virtual ~MSWordSections();
213 
214     virtual bool HeaderFooterWritten();
215 
216     void AppendSection( const SwPageDesc* pPd,
217                     const SwSectionFormat* pSectionFormat,
218                     sal_uLong nLnNumRestartNo,
219                     bool bIsFirstParagraph = false );
220     void AppendSection( const SwFormatPageDesc& rPd,
221                     const SwNode& rNd,
222                     const SwSectionFormat* pSectionFormat,
223                     sal_uLong nLnNumRestartNo );
224 
225     /// Number of columns based on the most recent WW8_SepInfo.
226     sal_uInt16 CurrentNumberOfColumns( const SwDoc &rDoc ) const;
227 
228     /// Number of columns of the provided WW8_SepInfo.
229     static sal_uInt16 NumberOfColumns( const SwDoc &rDoc, const WW8_SepInfo& rInfo );
230 
DocumentIsProtected() const231     bool DocumentIsProtected() const { return mbDocumentIsProtected; }
232 
233     /// The most recent WW8_SepInfo.
234     const WW8_SepInfo* CurrentSectionInfo();
235 
236     static void SetHeaderFlag( sal_uInt8& rHeadFootFlags, const SwFormat& rFormat,
237                                   sal_uInt8 nFlag );
238     static void SetFooterFlag( sal_uInt8& rHeadFootFlags, const SwFormat& rFormat,
239                                    sal_uInt8 nFlag );
240 
241     /// Should we output borders?
242     static bool HasBorderItem( const SwFormat& rFormat );
243 };
244 
245 class WW8_WrPlcSepx : public MSWordSections
246 {
247     std::vector<WW8_CP> aCps;
248     std::vector< std::shared_ptr<WW8_PdAttrDesc> > m_SectionAttributes;
249     // hack to prevent adding sections in endnotes
250     bool m_bHeaderFooterWritten;
251     std::unique_ptr<WW8_WrPlc0> pTextPos;        // Position of the headers/footers
252 
253     WW8_WrPlcSepx( const WW8_WrPlcSepx& ) = delete;
254     WW8_WrPlcSepx& operator=( const WW8_WrPlcSepx& ) = delete;
255 
256 public:
257     explicit WW8_WrPlcSepx( MSWordExportBase& rExport );
258     virtual ~WW8_WrPlcSepx() override;
259 
260     virtual bool HeaderFooterWritten() override; // override
261 
262     void AppendSep( WW8_CP nStartCp,
263                     const SwPageDesc* pPd,
264                     const SwSectionFormat* pSectionFormat,
265                     sal_uLong nLnNumRestartNo );
266     void AppendSep( WW8_CP nStartCp, const SwFormatPageDesc& rPd,
267                     const SwNode& rNd,
268                     const SwSectionFormat* pSectionFormat,
269                     sal_uLong nLnNumRestartNo );
Finish(WW8_CP nEndCp)270     void Finish( WW8_CP nEndCp ) { aCps.push_back( nEndCp ); }
271 
272     bool WriteKFText( WW8Export& rWrt );
273     void WriteSepx( SvStream& rStrm ) const;
274     void WritePlcSed( WW8Export& rWrt ) const;
275     void WritePlcHdd( WW8Export& rWrt ) const;
276 
277 private:
278     void WriteFootnoteEndText( WW8Export& rWrt, sal_uLong nCpStt );
279 public:
280     void OutHeaderFooter(WW8Export& rWrt, bool bHeader,
281             const SwFormat& rFormat, sal_uLong& rCpPos, sal_uInt8 nHFFlags, sal_uInt8 nFlag,  sal_uInt8 nBreakCode);
282 };
283 
284 // class WW8_WrPct to construct the piece table
285 class WW8_WrPct
286 {
287     std::vector<std::unique_ptr<WW8_WrPc>> m_Pcts;
288     WW8_FC nOldFc;
289 public:
290     explicit WW8_WrPct(WW8_FC nStartFc);
291     ~WW8_WrPct();
292     void AppendPc(WW8_FC nStartFc);
293     void WritePc( WW8Export& rWrt );
294     void SetParaBreak();
295     WW8_CP Fc2Cp( sal_uLong nFc ) const;
296 };
297 
298 /// Collects and outputs fonts.
299 class wwFont
300 {
301 //In some future land the stream could be converted to a nice stream interface
302 //and we could have harmony
303 private:
304     sal_uInt8 maWW8_FFN[6] = {};
305     OUString msFamilyNm;
306     OUString msAltNm;
307     bool mbAlt;
308     FontPitch const mePitch;
309     FontFamily const meFamily;
310     rtl_TextEncoding const meChrSet;
311 public:
312      wwFont( const OUString &rFamilyName, FontPitch ePitch, FontFamily eFamily,
313         rtl_TextEncoding eChrSet);
314     void Write( SvStream *pTableStram ) const;
315     void WriteDocx( DocxAttributeOutput* rAttrOutput ) const;
316     void WriteRtf( const RtfAttributeOutput* rAttrOutput ) const;
GetFamilyName() const317     OUString const & GetFamilyName() const { return msFamilyNm; }
318     friend bool operator < (const wwFont &r1, const wwFont &r2);
319 };
320 
321 class wwFontHelper
322 {
323 private:
324     /// Keep track of fonts that need to be exported.
325     std::map<wwFont, sal_uInt16> maFonts;
326 
327     /// Convert from fast insertion map to linear vector in the order that we want to write.
328     std::vector< const wwFont* > AsVector() const;
329 
330 public:
wwFontHelper()331     wwFontHelper() : bLoadAllFonts(false) {}
332     /// rDoc used only to get the initial standard font(s) in use.
333     void InitFontTable(const SwDoc& rDoc);
334     sal_uInt16 GetId(const SvxFontItem& rFont);
335     sal_uInt16 GetId(const wwFont& rFont);
336     void WriteFontTable( SvStream *pTableStream, WW8Fib& pFib );
337     void WriteFontTable( DocxAttributeOutput& rAttrOutput );
338     void WriteFontTable( const RtfAttributeOutput& rAttrOutput );
339 
340     /// If true, all fonts are loaded before processing the document.
341     bool bLoadAllFonts: 1;
342 };
343 
344 class DrawObj
345 {
346 public:
347     WW8_CP const mnCp;                // CP-Pos of references
348     sal_uInt32 mnShapeId;       // ShapeId for the SwFrameFormats
349     ww8::Frame maContent;       // the frame itself
350     Point const maParentPos;          // Points
351     sal_Int32 mnThick;          // Border Thicknesses
352     SvxFrameDirection const mnDirection; // If BiDi or not
353     unsigned int const mnHdFtIndex;   // 0 for main text, +1 for each subsequent
354                                 // msword hd/ft
355 
DrawObj(const ww8::Frame & rContent,WW8_CP nCp,Point aParentPos,SvxFrameDirection nDir,unsigned int nHdFtIndex)356     DrawObj(const ww8::Frame &rContent, WW8_CP nCp, Point aParentPos, SvxFrameDirection nDir,
357             unsigned int nHdFtIndex)
358         : mnCp(nCp), mnShapeId(0), maContent(rContent), maParentPos(aParentPos),
359         mnThick(0), mnDirection(nDir), mnHdFtIndex(nHdFtIndex) {}
360     void SetShapeDetails(sal_uInt32 nId, sal_Int32 nThick);
361 };
362 
363 typedef std::vector<DrawObj> DrawObjVector;
364 typedef std::vector<DrawObj *> DrawObjPointerVector;
365 
366 class PlcDrawObj // PC for DrawObjects and Text-/OLE-/GRF-Boxes
367 {
368 private:
369     DrawObjVector maDrawObjs;  // vector of drawobjs
370 protected:
371     virtual void RegisterWithFib(WW8Fib &rFib, sal_uInt32 nStart,
372         sal_uInt32 nLen) const = 0;
373     virtual WW8_CP GetCpOffset(const WW8Fib &rFib) const = 0;
374 public:
PlcDrawObj()375     PlcDrawObj() {}
376     void WritePlc( WW8Export& rWrt ) const;
377     bool Append( WW8Export const &, WW8_CP nCp, const ww8::Frame& rFormat,
378         const Point& rNdTopLeft );
size()379     int size() { return maDrawObjs.size(); };
GetObjArr()380     DrawObjVector &GetObjArr() { return maDrawObjs; }
381     virtual ~PlcDrawObj();
382 private:
383     PlcDrawObj(const PlcDrawObj&) = delete;
384     PlcDrawObj& operator=(const PlcDrawObj&) = delete;
385 };
386 
387 class MainTextPlcDrawObj : public PlcDrawObj
388 {
389 public:
MainTextPlcDrawObj()390     MainTextPlcDrawObj() {}
391 private:
392     virtual void RegisterWithFib(WW8Fib &rFib, sal_uInt32 nStart,
393         sal_uInt32 nLen) const override;
394     virtual WW8_CP GetCpOffset(const WW8Fib &) const override;
395 private:
396     MainTextPlcDrawObj(const MainTextPlcDrawObj&) = delete;
397     MainTextPlcDrawObj& operator=(const MainTextPlcDrawObj&) = delete;
398 };
399 
400 class HdFtPlcDrawObj : public PlcDrawObj
401 {
402 public:
HdFtPlcDrawObj()403     HdFtPlcDrawObj() {}
404 private:
405     virtual void RegisterWithFib(WW8Fib &rFib, sal_uInt32 nStart,
406         sal_uInt32 nLen) const override;
407     virtual WW8_CP GetCpOffset(const WW8Fib &rFib) const override;
408 private:
409     HdFtPlcDrawObj(const HdFtPlcDrawObj&) = delete;
410     HdFtPlcDrawObj& operator=(const HdFtPlcDrawObj&) = delete;
411 };
412 
413 typedef std::pair<OUString, sal_uLong> aBookmarkPair;
414 
415 class WW8_WrtRedlineAuthor : public sw::util::WrtRedlineAuthor
416 {
417     public:
418     virtual void Write(Writer &rWrt) override;
419 };
420 
421 /** Structure that is used to save some of the WW8Export/DocxExport data.
422 
423     It is used to be able to recurse inside of the WW8Export/DocxExport (eg.
424     for the needs of the tables) - you need to tall WriteText() from there with
425     new values of PaM etc.
426 
427     It must contain all the stuff that might be saved either in WW8Export or in
428     DocxExport, because it makes no sense to do it abstract, and specialize it
429     for each of the cases.  If you implement other *Export, just add the needed
430     members here, and store them in the appropriate SaveData() method.
431  */
432 struct MSWordSaveData
433 {
434     Point* pOldFlyOffset;
435     RndStdIds eOldAnchorType;
436     std::unique_ptr<ww::bytes> pOOld; ///< WW8Export only
437     std::shared_ptr<SwUnoCursor> pOldPam;
438     SwPaM* pOldEnd;
439     sal_uLong nOldStart, nOldEnd;
440     const ww8::Frame* pOldFlyFormat;
441     const SwPageDesc* pOldPageDesc;
442 
443     bool bOldWriteAll : 1;          ///< WW8Export only
444     bool bOldOutTable : 1;
445     bool bOldFlyFrameAttrs : 1;
446     bool bOldStartTOX : 1;
447     bool bOldInWriteTOX : 1;
448     // m_bOutPageDescs does not have to be saved in MSWordExportBase::SaveData
449     // since it is only modified when outputting special texts.
450 };
451 
452 /// Base class for WW8Export and DocxExport
453 class MSWordExportBase
454 {
455 public:
456     wwFontHelper m_aFontHelper;
457     std::vector<sal_uLong> m_aChapterFieldLocs;
458     OUString const m_aMainStg;
459     std::vector<const SwTOXType*> m_aTOXArr;
460     const SfxItemSet* m_pISet;    // for double attributes
461     const SwFrameFormat* m_pFirstPageFormat = nullptr;
462     WW8_WrPct*  m_pPiece;         // Pointer to Piece-Table
463     std::unique_ptr<SwNumRuleTable> m_pUsedNumTable;  // all used NumRules
464     /// overriding numdef index -> (existing numdef index, abstractnumdef index)
465     std::map<size_t, std::pair<size_t, size_t>> m_OverridingNums;
466     /// list-id -> abstractnumdef index
467     std::map<OUString, size_t> m_Lists;
468 
469     /// Map of maps for list levels overrides
470     /// listid -> level number -> restart value
471     std::map < size_t, std::map<size_t, size_t> > m_ListLevelOverrides;
472 
473     const SwTextNode *m_pTopNodeOfHdFtPage; ///< Top node of host page when in hd/ft
474     std::stack< sal_Int32 > m_aCurrentCharPropStarts; ///< To remember the position in a run.
475     WW8_WrtBookmarks* m_pBkmks;
476     WW8_WrtRedlineAuthor* m_pRedlAuthors;
477     std::shared_ptr<NfKeywordTable> m_pKeyMap;
478     std::unique_ptr<SvxMSExportOLEObjects> m_pOLEExp;
479     std::unique_ptr<SwMSConvertControls> m_pOCXExp;
480     WW8OleMap m_aOleMap;    // To remember all already exported ole objects
481     ww8::WW8TableInfo::Pointer_t m_pTableInfo;
482 
483     sal_uInt16 m_nCharFormatStart;
484     sal_uInt16 m_nFormatCollStart;
485     sal_uInt16 m_nStyleBeforeFly;     ///< style number of the node
486                                 ///<       to which the Fly is connected
487     sal_uInt16 m_nLastFormatId;          ///< Style of last TextNode in normal range
488     sal_uInt16 m_nUniqueList;         ///< current number for creating unique list names
489     unsigned int m_nHdFtIndex;
490 
491     RedlineFlags m_nOrigRedlineFlags;   ///< Remember the original redline mode
492     bool m_bOrigShowChanges;            ///< Remember the original Show Changes mode
493 
494 public:
495     /* implicit bookmark vector containing pairs of node indexes and bookmark names */
496     std::vector<aBookmarkPair> m_aImplicitBookmarks;
497     ww8::Frames m_aFrames;             // The floating frames in this document
498     const SwPageDesc *m_pCurrentPageDesc;
499     bool m_bPrevTextNodeIsEmpty;
500     bool m_bFirstTOCNodeWithSection;
501     std::unique_ptr<WW8_WrPlcPn> m_pPapPlc;
502     std::unique_ptr<WW8_WrPlcPn> m_pChpPlc;
503     MSWordAttrIter* m_pChpIter;
504     std::unique_ptr<MSWordStyles> m_pStyles;
505     WW8_WrPlcAnnotations* m_pAtn;
506     std::unique_ptr<WW8_WrtFactoids> m_pFactoids;
507     WW8_WrPlcTextBoxes *m_pTextBxs, *m_pHFTextBxs;
508 
509     struct LinkedTextboxInfo        //help analyze textbox flow links
510     {
511         sal_Int32 nId;
512         sal_Int32 nSeq;
513         OUString sNextChain;
514         OUString sPrevChain;
LinkedTextboxInfoMSWordExportBase::LinkedTextboxInfo515         LinkedTextboxInfo(): nId(0), nSeq(0) {}
516     };
517     std::map<OUString,LinkedTextboxInfo> m_aLinkedTextboxesHelper;
518     bool m_bLinkedTextboxesHelperInitialized = false;
519     sal_Int32 m_nLinkedTextboxesChainId=0;
520 
521     const ww8::Frame *m_pParentFrame; // If set we are exporting content inside
522                                     // a frame, e.g. a graphic node
523 
524     Point* m_pFlyOffset;              // for adjusting of character-bound Fly in the Writer,
525     RndStdIds m_eNewAnchorType;       // that is paragraph-bound in the WW.
526 
527     std::unique_ptr<WW8_WrPlcField> m_pFieldMain;         // fields in MainText
528     std::unique_ptr<WW8_WrPlcField> m_pFieldHdFt;         // fields in Header/Footer
529     std::unique_ptr<WW8_WrPlcField> m_pFieldFootnote;          // fields in FootNotes
530     std::unique_ptr<WW8_WrPlcField> m_pFieldEdn;          // fields in EndNotes
531     std::unique_ptr<WW8_WrPlcField> m_pFieldAtn;          // fields in Annotations
532     std::unique_ptr<WW8_WrPlcField> m_pFieldTextBxs;       // fields in textboxes
533     std::unique_ptr<WW8_WrPlcField> m_pFieldHFTextBxs;     // fields in header/footer textboxes
534     std::unique_ptr<WW8_WrMagicTable> m_pMagicTable;  // keeps track of table cell positions, and
535                                     // marks those that contain graphics,
536                                     // which is required to make word display
537                                     // graphics inside tables
538     std::unique_ptr<SwWW8WrGrf> m_pGrf;
539     const SwAttrSet* m_pStyAttr;      // StyleAttr for Tabs
540     const SwModify* m_pOutFormatNode;    // write Format or Node
541     const SwFormat *m_pCurrentStyle;     // iff bStyDef=true, then this store the current style
542 
543     MainTextPlcDrawObj *m_pSdrObjs;   // Draw-/Fly-Objects
544     HdFtPlcDrawObj *m_pHFSdrObjs;     // Draw-/Fly-Objects in header or footer
545 
546     SwEscherEx* m_pEscher;            // escher export class
547     // #i43447# - removed
548 //    SwTwips nFlyWidth, nFlyHeight;  // for adaptation of graphics
549 
550     sal_uInt8 m_nTextTyp;
551 
552     bool m_bStyDef : 1;           // should Style be written?
553     bool m_bBreakBefore : 1;      // Breaks are being written 2 times
554     bool m_bOutKF : 1;            // Header/Footer texts are being written
555     bool m_bOutFlyFrameAttrs : 1;   // Frame-attr of Flys are being written
556     bool m_bOutPageDescs : 1;     ///< PageDescs (section properties) are being written
557     bool m_bOutFirstPage : 1;     // write Attrset of FirstPageDesc
558     bool m_bOutTable : 1;         // table is being written
559                                      // ( is reset e.g. for Flys in a table )
560     bool m_bOutGrf : 1;           // graphics are being written
561     bool m_bInWriteEscher : 1;    // in write textboxes
562     bool m_bStartTOX : 1;         // true: a TOX is started
563     bool m_bInWriteTOX : 1;       // true: all content are in a TOX
564     bool m_bFootnoteAtTextEnd : 1;      // true: all FTN at Textend
565     bool m_bEndAtTextEnd : 1;      // true: all END at Textend
566     bool m_bHasHdr : 1;
567     bool m_bHasFtr : 1;
568     bool m_bSubstituteBullets : 1; // true: SubstituteBullet() gets called
569     bool m_bTabInTOC : 1; //true for TOC field flag 'w'
570 
571     bool m_bHideTabLeaderAndPageNumbers : 1 ; // true: the 'z' field of TOC is set.
572     bool m_bExportModeRTF;
573     /// Is font size written already as part of the current character properties?
574     bool m_bFontSizeWritten;
575     bool m_bAddFootnoteTab;     // only one aesthetic spacing tab per footnote
576 
577     SwDoc *m_pDoc;
578     sal_uLong m_nCurStart, m_nCurEnd;
579     std::shared_ptr<SwUnoCursor> & m_pCurPam;
580     SwPaM *m_pOrigPam;
581 
582     /// Stack to remember the nesting (see MSWordSaveData for more)
583     std::stack< MSWordSaveData > m_aSaveData;
584 
585     /// Used to split the runs according to the bookmarks start and ends
586     typedef std::vector< ::sw::mark::IMark* > IMarkVector;
587     IMarkVector m_rSortedBookmarksStart;
588     IMarkVector m_rSortedBookmarksEnd;
589     IMarkVector m_rSortedAnnotationMarksStart;
590     IMarkVector m_rSortedAnnotationMarksEnd;
591 
592 public:
593     /// The main function to export the document.
594     ErrCode ExportDocument( bool bWriteAll );
595 
596     /// Iterate through the nodes and call the appropriate OutputNode() on them.
597     void WriteText();
598 
599     /// Return whether currently exported node is in table.
600     bool IsInTable() const;
601 
602     /// Set the pCurPam appropriately and call WriteText().
603     ///
604     /// Used to export paragraphs in footnotes/endnotes/etc.
605     void WriteSpecialText( sal_uLong nStart, sal_uLong nEnd, sal_uInt8 nTTyp );
606 
607     /// Export the pool items to attributes (through an attribute output class).
608     void ExportPoolItemsToCHP( ww8::PoolItems &rItems, sal_uInt16 nScript, const SvxFontItem *pFont, bool bWriteCombChars = false );
609 
610     /// Return the numeric id of the numbering rule
611     sal_uInt16 GetNumberingId( const SwNumRule& rNumRule );
612 
613     /// Return the numeric id of the style.
614     sal_uInt16 GetId( const SwTextFormatColl& rColl ) const;
615 
616     /// Return the numeric id of the style.
617     sal_uInt16 GetId( const SwCharFormat* pFormat ) const;
618 
619     sal_uInt16 GetId( const SwTOXType& rTOXType );
620 
621     /// Return the numeric id of the font (and add it to the font list if needed)
GetId(const SvxFontItem & rFont)622     sal_uInt16 GetId( const SvxFontItem& rFont)
623     {
624         return m_aFontHelper.GetId(rFont);
625     }
626     /// @overload
GetId(const wwFont & rFont)627     void GetId( const wwFont& rFont)
628     {
629         m_aFontHelper.GetId(rFont);
630     }
631 
632     const SfxPoolItem& GetItem( sal_uInt16 nWhich ) const;
GetItem(TypedWhichId<T> nWhich) const633     template<class T> const T& GetItem( TypedWhichId<T> nWhich ) const
634     {
635         return static_cast<const T&>(GetItem(sal_uInt16(nWhich)));
636     }
637 
638     /// Find the reference.
639     bool HasRefToObject( sal_uInt16 nTyp, const OUString* pName, sal_uInt16 nSeqNo );
640 
641     /// Find the bookmark name.
642     static OUString GetBookmarkName( sal_uInt16 nTyp, const OUString* pName, sal_uInt16 nSeqNo );
643 
644     /// Use OutputItem() on an item set according to the parameters.
645     void OutputItemSet( const SfxItemSet& rSet, bool bPapFormat, bool bChpFormat, sal_uInt16 nScript, bool bExportParentItemSet );
646 
647     SvxFrameDirection GetDefaultFrameDirection( ) const;
648 
649     /// Right to left?
650     SvxFrameDirection TrueFrameDirection( const SwFrameFormat& rFlyFormat ) const;
651 
652     /// Right to left?
653     SvxFrameDirection GetCurrentPageDirection() const;
654 
655     /// In case of numbering restart.
656 
657     /// List is set to restart at a particular value so for export make a
658     /// completely new list based on this one and export that instead,
659     /// which duplicates words behaviour in this respect.
660     SwNumRule * DuplicateNumRuleImpl(const SwNumRule *pRule);
661 
662     /// check if a new abstractNum is needed for this list
663     sal_uInt16 DuplicateAbsNum(OUString const& rListId,
664                                SwNumRule const& rAbstractRule);
665 
666 
667     /// Create a overriding numbering definition (if it does not yet exist)
668     /// @return index of the overriding numbering definition
669     sal_uInt16 OverrideNumRule(SwNumRule const& rExistingRule,
670                                OUString const& rListId,
671                                SwNumRule const& rAbstractRule);
672 
673     /// Store list level overrides (restart of list)
674     void AddListLevelOverride(sal_uInt16 nListId,
675                               sal_uInt16 nLevelNum,
676                               sal_uInt16 nStartAt);
677 
678     /// Access to the attribute output class.
679     virtual AttributeOutputBase& AttrOutput() const = 0;
680 
681     /// Access to the sections/headers/footres.
682     virtual MSWordSections& Sections() const = 0;
683 
684     /// Determines if column break with one column should be exported or not.
685     virtual bool SupportsOneColumnBreak() const = 0;
686 
687     /// Determines if the import filter already quoted fields or not.
688     virtual bool FieldsQuoted() const = 0;
689 
690     /// Determines the Section Breaks are to be added for TOX Section
691     virtual bool AddSectionBreaksForTOX() const = 0;
692 
693     /// Used to filter out attributes that can be e.g. written to .doc but not to .docx
ignoreAttributeForStyleDefaults(sal_uInt16) const694     virtual bool ignoreAttributeForStyleDefaults( sal_uInt16 /*nWhich*/ ) const { return false; }
695 
696     /// If saving page break is preferred as a paragraph attribute (yes) or as a special character (no).
697     virtual bool PreferPageBreakBefore() const = 0;
698 
699     /// Text in tables can be postponed except for .doc
AllowPostponedTextInTable() const700     virtual bool AllowPostponedTextInTable() const { return true; }
701 
702     /// Guess the script (asian/western).
703     ///
704     /// Sadly word does not have two different sizes for asian font size and
705     /// western font size, it has two different fonts, but not sizes, so we
706     /// have to use our guess as to the script used and disable the export of
707     /// one type. The same occurs for font weight and posture (bold and
708     /// italic).
709     ///
710     /// In addition WW7- has only one character language identifier while WW8+
711     /// has two
712     virtual bool CollapseScriptsforWordOk( sal_uInt16 nScript, sal_uInt16 nWhich ) = 0;
713 
714     virtual void AppendBookmarks( const SwTextNode& rNd, sal_Int32 nCurrentPos, sal_Int32 nLen ) = 0;
715 
716     virtual void AppendBookmark( const OUString& rName ) = 0;
717 
718     virtual void AppendAnnotationMarks( const SwWW8AttrIter& rAttrs, sal_Int32 nCurrentPos, sal_Int32 nLen ) = 0;
719 
AppendSmartTags(SwTextNode &)720     virtual void AppendSmartTags(SwTextNode& /*rTextNode*/) { }
721 
722     //For i120928,add this interface to export graphic of bullet
723     virtual void ExportGrfBullet(const SwTextNode& rNd) = 0;
724 
725     // FIXME probably a hack...
726     virtual void WriteCR( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner = ww8::WW8TableNodeInfoInner::Pointer_t() ) = 0;
727 
728     // FIXME definitely a hack, must not be here - it can't do anything
729     // sensible for docx
730     virtual void WriteChar( sal_Unicode c ) = 0;
731 
732     /// Output attributes.
733     void OutputFormat( const SwFormat& rFormat, bool bPapFormat, bool bChpFormat, bool bFlyFormat = false );
734 
735     /// Getter for pISet.
GetCurItemSet() const736     const SfxItemSet* GetCurItemSet() const { return m_pISet; }
737 
738     /// Setter for pISet.
SetCurItemSet(const SfxItemSet * pS)739     void SetCurItemSet( const SfxItemSet* pS ) { m_pISet = pS; }
740 
741     /// Remember some of the members so that we can recurse in WriteText().
742     virtual void SaveData( sal_uLong nStt, sal_uLong nEnd );
743 
744     /// Restore what was saved in SaveData().
745     virtual void RestoreData();
746 
747     /// The return value indicates, if a follow page desc is written.
748     bool OutputFollowPageDesc( const SfxItemSet* pSet,
749                                const SwTextNode* pNd );
750 
751     /// Write header/footer text.
752     void WriteHeaderFooterText( const SwFormat& rFormat, bool bHeader);
753 
754     /// Format of the section.
755     static const SwSectionFormat* GetSectionFormat( const SwNode& rNd );
756 
757     /// Line number of the section start.
758     static sal_uLong GetSectionLineNo( const SfxItemSet* pSet, const SwNode& rNd );
759 
760     /// Start new section.
761     void OutputSectionBreaks( const SfxItemSet *pSet, const SwNode& rNd, bool isCellOpen = false, bool isTextNodeEmpty = false);
762 
763     /// Write section properties.
764     ///
765     /// pA is ignored for docx.
766     void SectionProperties( const WW8_SepInfo& rSectionInfo, WW8_PdAttrDesc* pA = nullptr );
767 
768     /// Output the numbering table.
769     virtual void WriteNumbering() = 0;
770 
771     /// Write static data of SwNumRule - LSTF
772     void NumberingDefinitions();
773 
774     /// Write all Levels for all SwNumRules - LVLF
775     void AbstractNumberingDefinitions();
776 
777     /// Write one numbering level
778     void NumberingLevel(SwNumRule const& rRule, sal_uInt8 nLvl);
779 
780     // Convert the bullet according to the font.
781     void SubstituteBullet( OUString& rNumStr, rtl_TextEncoding& rChrSet,
782         OUString& rFontName ) const;
783 
784     /// Setup the pA's info.
SetupSectionPositions(WW8_PdAttrDesc *)785     virtual void SetupSectionPositions( WW8_PdAttrDesc* /*pA*/ ) {}
786 
787     /// Top node of host page when in header/footer.
SetHdFtPageRoot(const SwTextNode * pNd)788     void SetHdFtPageRoot( const SwTextNode *pNd ) { m_pTopNodeOfHdFtPage = pNd; }
789 
790     /// Top node of host page when in header/footer.
GetHdFtPageRoot() const791     const SwTextNode *GetHdFtPageRoot() const { return m_pTopNodeOfHdFtPage; }
792 
793     /// Output the actual headers and footers.
794     virtual void WriteHeadersFooters( sal_uInt8 nHeadFootFlags,
795             const SwFrameFormat& rFormat, const SwFrameFormat& rLeftFormat, const SwFrameFormat& rFirstPageFormat,
796         sal_uInt8 nBreakCode) = 0;
797 
798     /// Write the field
799     virtual void OutputField( const SwField* pField, ww::eField eFieldType,
800             const OUString& rFieldCmd, FieldFlags nMode = FieldFlags::All ) = 0;
801 
802     /// Write the data of the form field
803     virtual void WriteFormData( const ::sw::mark::IFieldmark& rFieldmark ) = 0;
804     virtual void WriteHyperlinkData( const ::sw::mark::IFieldmark& rFieldmark ) = 0;
805 
806     virtual void DoComboBox(const OUString &rName,
807                     const OUString &rHelp,
808                     const OUString &ToolTip,
809                     const OUString &rSelected,
810                     const css::uno::Sequence<OUString> &rListItems) = 0;
811 
812     virtual void DoFormText(const SwInputField * pField) = 0;
813 
814     static bool NoPageBreakSection( const SfxItemSet *pSet );
815 
816     // Compute the number format for WW dates
817     bool GetNumberFormat(const SwField& rField, OUString& rStr);
818 
819     virtual sal_uLong ReplaceCr( sal_uInt8 nChar ) = 0;
820 
821     const SfxPoolItem* HasItem( sal_uInt16 nWhich ) const;
822 
823     /// Returns the index of a picture bullet, used in numberings.
824     int GetGrfIndex(const SvxBrushItem& rBrush);
825 
826     enum ExportFormat { DOC = 0, RTF = 1, DOCX = 2};
827     virtual ExportFormat GetExportFormat() const = 0;
828 
829 protected:
830     /// Format-dependent part of the actual export.
831     virtual ErrCode ExportDocument_Impl() = 0;
832 
833     /// Get the next position in the text node to output
834     sal_Int32 GetNextPos( SwWW8AttrIter const * pAttrIter, const SwTextNode& rNode, sal_Int32 nCurrentPos );
835 
836     /// Update the information for GetNextPos().
837     void UpdatePosition( SwWW8AttrIter* pAttrIter, sal_Int32 nCurrentPos );
838 
839     /// Output SwTextNode
840     virtual void OutputTextNode( SwTextNode& );
841 
842     /// Setup the chapter fields (maChapterFieldLocs).
843     void GatherChapterFields();
844 
845     void AddLinkTarget( const OUString& rURL );
846     void CollectOutlineBookmarks( const SwDoc &rDoc );
847 
848     bool SetCurrentPageDescFromNode(const SwNode &rNd);
849     bool ContentContainsChapterField(const SwFormatContent &rContent) const;
850     bool FormatHdFtContainsChapterField(const SwFrameFormat &rFormat) const;
851 
852     virtual void SectionBreaksAndFrames( const SwTextNode& rNode ) = 0;
853 
854     virtual void PrepareNewPageDesc( const SfxItemSet* pSet,
855                                      const SwNode& rNd,
856                                      const SwFormatPageDesc* pNewPgDescFormat,
857                                      const SwPageDesc* pNewPgDesc ) = 0;
858 
859     /// Return value indicates if an inherited outline numbering is suppressed.
860     virtual bool DisallowInheritingOutlineNumbering(const SwFormat &rFormat) = 0;
861 
862     /// Output SwStartNode
863     void OutputStartNode( const SwStartNode& );
864 
865     /// Output SwEndNode
866     virtual void OutputEndNode( const SwEndNode& );
867 
868     /// Output SwGrfNode
869     virtual void OutputGrfNode( const SwGrfNode& ) = 0;
870 
871     /// Output SwOLENode
872     virtual void OutputOLENode( const SwOLENode& ) = 0;
873 
874     virtual void OutputLinkedOLE( const OUString& ) = 0;
875 
876     /// Output SwSectionNode
877     void OutputSectionNode( const SwSectionNode& );
878     static void UpdateTocSectionNodeProperties(const SwSectionNode& rSectionNode);
879 
880     virtual void AppendSection( const SwPageDesc *pPageDesc, const SwSectionFormat* pFormat, sal_uLong nLnNum ) = 0;
881 
882     /// Call the right (virtual) function according to the type of the item.
883     ///
884     /// One of OutputTextNode(), OutputGrfNode(), or OutputOLENode()
885     void OutputContentNode( SwContentNode& );
886 
887     /// Find the nearest bookmark from the current position.
888     ///
889     /// Returns false when there is no bookmark.
890     bool NearestBookmark( sal_Int32& rNearest, const sal_Int32 nCurrentPos, bool bNextPositionOnly );
891 
892     void GetSortedBookmarks( const SwTextNode& rNd, sal_Int32 nCurrentPos, sal_Int32 nLen );
893 
894     bool GetBookmarks( const SwTextNode& rNd, sal_Int32 nStt, sal_Int32 nEnd,
895             IMarkVector& rArr );
896 
897     /// Find the nearest annotation mark from the current position.
898     ///
899     void NearestAnnotationMark( sal_Int32& rNearest, const sal_Int32 nCurrentPos, bool bNextPositionOnly );
900 
901     void GetSortedAnnotationMarks( const SwWW8AttrIter& rAttrs, sal_Int32 nCurrentPos, sal_Int32 nLen );
902 
903     bool GetAnnotationMarks( const SwWW8AttrIter& rAttrs, sal_Int32 nStt, sal_Int32 nEnd,
904             IMarkVector& rArr );
905 
906     const NfKeywordTable & GetNfKeywordTable();
907 
908     void SetCurPam(sal_uLong nStt, sal_uLong nEnd);
909 
910     /// Get background color of the document, if there is one.
911     std::shared_ptr<SvxBrushItem> getBackground();
912     /// Populates m_vecBulletPic with all the bullet graphics used by numberings.
913     int CollectGrfsOfBullets();
914     /// Write the numbering picture bullets.
915     void BulletDefinitions();
916 
917     bool NeedSectionBreak( const SwNode& rNd ) const;
918     bool NeedTextNodeSplit( const SwTextNode& rNd, SwSoftPageBreakList& pList ) const;
919 
920     std::vector<const Graphic*> m_vecBulletPic; ///< Vector to record all the graphics of bullets
921 
922 public:
923     MSWordExportBase( SwDoc *pDocument, std::shared_ptr<SwUnoCursor> & pCurrentPam, SwPaM *pOriginalPam );
924     virtual ~MSWordExportBase();
925 
926     // TODO move as much as possible here from WW8Export! ;-)
927 
928     static void CorrectTabStopInSet( SfxItemSet& rSet, sal_Int32 nAbsLeft );
929 
930 private:
931     MSWordExportBase( const MSWordExportBase& ) = delete;
932     MSWordExportBase& operator=( const MSWordExportBase& ) = delete;
933 };
934 
935 /// The writer class that gets called for the WW8 filter.
936 class SwWW8Writer: public StgWriter
937 {
938 // friends to get access to m_pExport
939 // FIXME avoid that, this is probably not what we want
940 // (if yes, remove the friends, and provide here a GetExport() method)
941 friend void WW8_WrtRedlineAuthor::Write(Writer &rWrt);
942 
943     WW8Export *m_pExport;
944     SfxMedium *mpMedium;
945 
946 public:
947     SwWW8Writer(const OUString& rFltName, const OUString& rBaseURL);
948     virtual ~SwWW8Writer() override;
949 
950     virtual ErrCode WriteStorage() override;
951     virtual ErrCode WriteMedium( SfxMedium& ) override;
952 
953     // TODO most probably we want to be able to get these in
954     // MSExportFilterBase
955     using Writer::getIDocumentSettingAccess;
956 
957 public:
958     static void InsUInt16(ww::bytes &rO, sal_uInt16 n);
959     static void InsUInt32(ww::bytes &rO, sal_uInt32 n);
960     static void InsAsString16(ww::bytes &rO, const OUString& rStr);
961     static void InsAsString8(ww::bytes & O, const OUString& rStr,
962         rtl_TextEncoding eCodeSet);
963 
964     static sal_uLong FillUntil( SvStream& rStrm, sal_uLong nEndPos = 0 );
965     static void FillCount( SvStream& rStrm, sal_uLong nCount );
966 
WriteShort(SvStream & rStrm,sal_Int16 nVal)967     static void WriteShort( SvStream& rStrm, sal_Int16 nVal ) { rStrm.WriteInt16( nVal ); }
968     static void WriteShort( SvStream& rStrm, sal_uLong nPos, sal_Int16 nVal );
969 
WriteLong(SvStream & rStrm,sal_Int32 nVal)970     static void WriteLong( SvStream& rStrm, sal_Int32 nVal ) { rStrm.WriteInt32( nVal ); }
971     static void WriteLong( SvStream& rStrm, sal_uLong nPos, sal_Int32 nVal );
972 
973     static void WriteString16(SvStream& rStrm, const OUString& rStr,
974         bool bAddZero);
975     static void WriteString8(SvStream& rStrm, const OUString& rStr,
976         bool bAddZero, rtl_TextEncoding eCodeSet);
977 
978     static void WriteString_xstz(SvStream& rStrm, const OUString& rStr, bool bAddZero);
979 
980     bool InitStd97CodecUpdateMedium( ::msfilter::MSCodec_Std97& rCodec );
981 
982     using StgWriter::Write;
983     virtual ErrCode Write( SwPaM&, SfxMedium&, const OUString* ) override;
984     //Seems not an expected to provide method to access the private member
GetMedia()985     SfxMedium* GetMedia() { return mpMedium; }
986 
987 private:
988     SwWW8Writer(const SwWW8Writer&) = delete;
989     SwWW8Writer& operator=(const SwWW8Writer&) = delete;
990 };
991 
992 /// Exporter of the binary Word file formats.
993 class WW8Export : public MSWordExportBase
994 {
995 public:
996     std::unique_ptr<ww::bytes> pO;      ///< Buffer
997 
998     SvStream *pTableStrm, *pDataStrm;   ///< Streams for WW97 Export
999 
1000     std::unique_ptr<WW8Fib> pFib;                       ///< File Information Block
1001     std::unique_ptr<WW8Dop> pDop;                       ///< Document Properties
1002     std::unique_ptr<WW8_WrPlcFootnoteEdn> pFootnote;    ///< Footnotes - structure to remember them, and output
1003     std::unique_ptr<WW8_WrPlcFootnoteEdn> pEdn;         ///< Endnotes - structure to remember them, and output
1004     std::unique_ptr<WW8_WrPlcSepx> pSepx;               ///< Sections/headers/footers
1005 
1006     bool const m_bDot; ///< Template or document.
1007 
1008 protected:
1009     SwWW8Writer        *m_pWriter;      ///< Pointer to the writer
1010     std::unique_ptr<WW8AttributeOutput> m_pAttrOutput;  ///< Converting attributes to stream data
1011 
1012 private:
1013     tools::SvRef<SotStorage>       xEscherStg;      /// memory leak #i120098#, to hold the reference to unnamed SotStorage obj
1014 
1015 public:
1016     /// Access to the attribute output class.
1017     virtual AttributeOutputBase& AttrOutput() const override;
1018 
1019     /// Access to the sections/headers/footres.
1020     virtual MSWordSections& Sections() const override;
1021 
PreferPageBreakBefore() const1022     virtual bool PreferPageBreakBefore() const override { return true; }
1023 
AllowPostponedTextInTable() const1024     virtual bool AllowPostponedTextInTable() const override { return false; }
1025 
SupportsOneColumnBreak() const1026     virtual bool SupportsOneColumnBreak() const override { return false; }
1027 
FieldsQuoted() const1028     virtual bool FieldsQuoted() const override { return false; }
1029 
AddSectionBreaksForTOX() const1030     virtual bool AddSectionBreaksForTOX() const override { return false; }
1031 private:
1032     /// Format-dependent part of the actual export.
1033     virtual ErrCode ExportDocument_Impl() override;
1034 
1035     void PrepareStorage();
1036     void WriteFkpPlcUsw();
1037     void WriteMainText();
1038     void StoreDoc1();
1039 
1040     /// Output the numbering table.
1041     virtual void WriteNumbering() override;
1042 
1043     void OutOverrideListTab();
1044     void OutListNamesTab();
1045 
1046     void RestoreMacroCmds();
1047 
1048     void DoComboBox(css::uno::Reference<css::beans::XPropertySet> const & xPropSet);
1049 
1050 public:
1051 
1052     /// Setup the pA's info.
1053     virtual void SetupSectionPositions( WW8_PdAttrDesc* pA ) override;
1054 
1055     bool MiserableFormFieldExportHack(const SwFrameFormat& rFrameFormat);
1056 
GetOLEExp()1057     SvxMSExportOLEObjects& GetOLEExp()      { return *m_pOLEExp; }
GetOCXExp()1058     SwMSConvertControls& GetOCXExp()        { return *m_pOCXExp; }
1059     void ExportDopTypography(WW8DopTypography &rTypo);
1060 
1061     sal_uInt16 AddRedlineAuthor( std::size_t nId );
1062 
1063     void WriteFootnoteBegin( const SwFormatFootnote& rFootnote, ww::bytes* pO = nullptr );
1064     void WritePostItBegin( ww::bytes* pO = nullptr );
1065     const SvxBrushItem* GetCurrentPageBgBrush() const;
1066     std::shared_ptr<SvxBrushItem> TrueFrameBgBrush(const SwFrameFormat &rFlyFormat) const;
1067 
1068     void AppendFlyInFlys(const ww8::Frame& rFrameFormat, const Point& rNdTopLeft);
1069     void WriteOutliner(const OutlinerParaObject& rOutliner, sal_uInt8 nTyp);
1070     void WriteSdrTextObj(const SdrTextObj& rObj, sal_uInt8 nTyp);
1071 
1072     sal_uInt32 GetSdrOrdNum( const SwFrameFormat& rFormat ) const;
1073     void CreateEscher();
1074     void WriteEscher();
1075 
1076     /// Write the field
1077     virtual void OutputField( const SwField* pField, ww::eField eFieldType,
1078             const OUString& rFieldCmd, FieldFlags nMode = FieldFlags::All ) override;
1079 
1080     void StartCommentOutput( const OUString& rName );
1081     void EndCommentOutput(   const OUString& rName );
1082     void OutGrf(const ww8::Frame &rFrame);
1083     bool TestOleNeedsGraphic(const SwAttrSet& rSet, tools::SvRef<SotStorage> const& xOleStg,
1084                              const tools::SvRef<SotStorage>& xObjStg, OUString const& rStorageName,
1085                              SwOLENode* pOLENd);
1086 
1087     virtual void AppendBookmarks( const SwTextNode& rNd, sal_Int32 nCurrentPos, sal_Int32 nLen ) override;
1088     virtual void AppendBookmark( const OUString& rName ) override;
1089     void AppendBookmarkEndWithCorrection( const OUString& rName );
1090 
1091     virtual void AppendAnnotationMarks( const SwWW8AttrIter& rAttrs, sal_Int32 nCurrentPos, sal_Int32 nLen ) override;
1092 
1093     virtual void AppendSmartTags(SwTextNode& rTextNode) override;
1094 
1095     virtual void ExportGrfBullet(const SwTextNode& rNd) override;
1096     void OutGrfBullets(const ww8::Frame &rFrame);
1097 
1098     void MoveFieldMarks(WW8_CP nFrom, WW8_CP nTo);
1099 
1100     void WriteAsStringTable(const std::vector<OUString>&, sal_Int32& rfcSttbf,
1101         sal_Int32& rlcbSttbf);
1102 
1103     virtual sal_uLong ReplaceCr( sal_uInt8 nChar ) override;
1104 
1105     virtual void WriteCR( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner = ww8::WW8TableNodeInfoInner::Pointer_t() ) override;
1106     void WriteChar( sal_Unicode c ) override;
1107 
1108     void OutSwString(const OUString&, sal_Int32 nStt, sal_Int32 nLen);
1109 
Fc2Cp(sal_uLong nFc) const1110     WW8_CP Fc2Cp( sal_uLong nFc ) const          { return m_pPiece->Fc2Cp( nFc ); }
1111 
1112             // some partly static semi-internal function declarations
1113 
OutSprmBytes(sal_uInt8 * pBytes,sal_uInt16 nSiz)1114     void OutSprmBytes( sal_uInt8* pBytes, sal_uInt16 nSiz )
1115                                 { pO->insert( pO->end(), pBytes, pBytes+nSiz ); }
1116 
1117     virtual void SectionBreaksAndFrames( const SwTextNode& rNode ) override;
1118 
1119     /// Helper method for OutputSectionBreaks() and OutputFollowPageDesc().
1120     // #i76300#
1121     virtual void PrepareNewPageDesc( const SfxItemSet* pSet,
1122                                      const SwNode& rNd,
1123                                      const SwFormatPageDesc* pNewPgDescFormat,
1124                                      const SwPageDesc* pNewPgDesc ) override;
1125 
1126     static void Out_BorderLine(ww::bytes& rO, const ::editeng::SvxBorderLine* pLine,
1127         sal_uInt16 nDist, sal_uInt16 nSprmNo, sal_uInt16 nSprmNoVer9,
1128         bool bShadow);
1129 
1130     void Out_SwFormatBox(const SvxBoxItem& rBox, bool bShadow);
1131     static void Out_SwFormatTableBox( ww::bytes& rO, const SvxBoxItem * rBox );
1132     void Out_CellRangeBorders(const SvxBoxItem * pBox, sal_uInt8 nStart,
1133         sal_uInt8 nLimit);
1134     static bool TransBrush(const Color& rCol, WW8_SHD& rShd);
1135     static WW8_BRCVer9 TranslateBorderLine(const ::editeng::SvxBorderLine& pLine,
1136         sal_uInt16 nDist, bool bShadow);
1137 
1138     // #i77805# - new return value indicates, if an inherited outline numbering is suppressed
1139     virtual bool DisallowInheritingOutlineNumbering(const SwFormat &rFormat) override;
1140 
GetHdFtIndex() const1141     unsigned int GetHdFtIndex() const { return m_nHdFtIndex; }
SetHdFtIndex(unsigned int nHdFtIndex)1142     void SetHdFtIndex(unsigned int nHdFtIndex) { m_nHdFtIndex = nHdFtIndex; }
IncrementHdFtIndex()1143     void IncrementHdFtIndex() { ++m_nHdFtIndex; }
1144 
1145     /// Convert the SVX numbering type to id
1146     static sal_uInt8 GetNumId( sal_uInt16 eNumType );
1147 
1148     /// Guess the script (asian/western).
1149     virtual bool CollapseScriptsforWordOk( sal_uInt16 nScript, sal_uInt16 nWhich ) override;
1150 
1151     SwTwips CurrentPageWidth(SwTwips &rLeft, SwTwips &rRight) const;
1152 
1153     /// Nasty swap for bidi if necessary
1154     void MiserableRTLFrameFormatHack(SwTwips &rLeft, SwTwips &rRight,
1155         const ww8::Frame &rFrameFormat);
1156 
InsUInt16(sal_uInt16 n)1157     void InsUInt16( sal_uInt16 n )      { SwWW8Writer::InsUInt16( *pO, n ); }
InsInt16(sal_Int16 n)1158     void InsInt16(sal_Int16 n) { InsUInt16(sal_uInt16(n)); }
InsUInt32(sal_uInt32 n)1159     void InsUInt32( sal_uInt32 n )      { SwWW8Writer::InsUInt32( *pO, n ); }
1160     void WriteStringAsPara( const OUString& rText );
1161 
1162     /// Setup the exporter.
1163     WW8Export( SwWW8Writer *pWriter,
1164             SwDoc *pDocument, std::shared_ptr<SwUnoCursor> & pCurrentPam, SwPaM *pOriginalPam,
1165             bool bDot );
1166     virtual ~WW8Export() override;
1167 
1168     virtual void DoComboBox(const OUString &rName,
1169                     const OUString &rHelp,
1170                     const OUString &ToolTip,
1171                     const OUString &rSelected,
1172                     const css::uno::Sequence<OUString> &rListItems) override;
1173 
1174     virtual void DoFormText(const SwInputField * pField) override;
1175 
1176     void GetCurrentItems(ww::bytes &rItems) const;
1177 
1178     /// Write the data of the form field
1179     virtual void WriteFormData( const ::sw::mark::IFieldmark& rFieldmark ) override;
1180     virtual void WriteHyperlinkData( const ::sw::mark::IFieldmark& rFieldmark ) override;
1181 
1182     /// Fields.
1183     WW8_WrPlcField* CurrentFieldPlc() const;
1184 
GetWriter() const1185     SwWW8Writer& GetWriter() const { return *m_pWriter; }
Strm() const1186     SvStream& Strm() const { return m_pWriter->Strm(); }
1187 
1188     /// Remember some of the members so that we can recurse in WriteText().
1189     virtual void SaveData( sal_uLong nStt, sal_uLong nEnd ) override;
1190 
1191     /// Restore what was saved in SaveData().
1192     virtual void RestoreData() override;
1193 
1194     /// Output the actual headers and footers.
1195     virtual void WriteHeadersFooters( sal_uInt8 nHeadFootFlags,
1196             const SwFrameFormat& rFormat, const SwFrameFormat& rLeftFormat, const SwFrameFormat& rFirstPageFormat,
1197         sal_uInt8 nBreakCode) override;
1198 
GetExportFormat() const1199     virtual ExportFormat GetExportFormat() const override { return ExportFormat::DOC; }
1200 
1201 protected:
1202     /// Output SwGrfNode
1203     virtual void OutputGrfNode( const SwGrfNode& ) override;
1204 
1205     /// Output SwOLENode
1206     virtual void OutputOLENode( const SwOLENode& ) override;
1207 
1208     virtual void OutputLinkedOLE( const OUString& ) override;
1209 
1210     virtual void AppendSection( const SwPageDesc *pPageDesc, const SwSectionFormat* pFormat, sal_uLong nLnNum ) override;
1211 
1212 private:
1213     WW8Export(const WW8Export&) = delete;
1214     WW8Export& operator=(const WW8Export&) = delete;
1215 };
1216 
1217 class WW8_WrPlcSubDoc   // double Plc for Footnotes/Endnotes and Postits
1218 {
1219 private:
1220     WW8_WrPlcSubDoc(const WW8_WrPlcSubDoc&) = delete;
1221     WW8_WrPlcSubDoc& operator=(const WW8_WrPlcSubDoc&) = delete;
1222 protected:
1223     std::vector<WW8_CP> aCps;
1224     std::vector<const void*> aContent;                // PTRARR of SwFormatFootnote/PostIts/..
1225     std::vector<const SwFrameFormat*> aSpareFormats;  // a backup for aContent: if there's no SdrObject, stores the fmt directly here
1226     std::unique_ptr<WW8_WrPlc0> pTextPos;             // positions of the individual texts
1227 
1228     WW8_WrPlcSubDoc();
1229     virtual ~WW8_WrPlcSubDoc();
1230 
1231     bool WriteGenericText( WW8Export& rWrt, sal_uInt8 nTTyp, WW8_CP& rCount );
1232     void WriteGenericPlc( WW8Export& rWrt, sal_uInt8 nTTyp, WW8_FC& rTextStt,
1233         sal_Int32& rTextCnt, WW8_FC& rRefStt, sal_Int32& rRefCnt ) const;
1234 
1235     virtual const std::vector<sal_uInt32>* GetShapeIdArr() const;
1236 };
1237 
1238 // double Plc for Footnotes/Endnotes
1239 class WW8_WrPlcFootnoteEdn : public WW8_WrPlcSubDoc
1240 {
1241 private:
1242     sal_uInt8 const nTyp;
1243 
1244     WW8_WrPlcFootnoteEdn(const WW8_WrPlcFootnoteEdn&) = delete;
1245     WW8_WrPlcFootnoteEdn& operator=(WW8_WrPlcFootnoteEdn const &) = delete;
1246 public:
WW8_WrPlcFootnoteEdn(sal_uInt8 nTTyp)1247     explicit WW8_WrPlcFootnoteEdn( sal_uInt8 nTTyp ) : nTyp( nTTyp ) {}
1248 
1249     bool WriteText( WW8Export& rWrt );
1250     void WritePlc( WW8Export& rWrt ) const;
1251 
1252     void Append( WW8_CP nCp, const SwFormatFootnote& rFootnote );
1253 };
1254 
1255 struct WW8_Annotation
1256 {
1257     const OutlinerParaObject* mpRichText;
1258     OUString msSimpleText;
1259     OUString msOwner;
1260     OUString m_sInitials;
1261     DateTime maDateTime;
1262     WW8_CP m_nRangeStart, m_nRangeEnd;
1263     bool m_bIgnoreEmpty = true;
1264     WW8_Annotation(const SwPostItField* pPostIt, WW8_CP nRangeStart, WW8_CP nRangeEnd);
1265     explicit WW8_Annotation(const SwRedlineData* pRedline);
1266     /// An annotation has a range if start != end or the m_bIgnoreEmpty flag is cleared.
1267     bool HasRange() const;
1268 };
1269 
1270 class WW8_WrPlcAnnotations : public WW8_WrPlcSubDoc  // double Plc for Postits
1271 {
1272 private:
1273     WW8_WrPlcAnnotations(const WW8_WrPlcAnnotations&) = delete;
1274     WW8_WrPlcAnnotations& operator=(WW8_WrPlcAnnotations const &) = delete;
1275     std::set<const SwRedlineData*> maProcessedRedlines;
1276 
1277     std::map<const OUString, std::pair<WW8_CP, bool>> m_aRangeStartPositions;
1278 public:
WW8_WrPlcAnnotations()1279     WW8_WrPlcAnnotations() {}
1280     virtual ~WW8_WrPlcAnnotations() override;
1281 
1282     void AddRangeStartPosition(const OUString& rName, WW8_CP nStartCp, bool bIgnoreEmpty);
1283     void Append( WW8_CP nCp, const SwPostItField* pPostIt );
1284     void Append( WW8_CP nCp, const SwRedlineData* pRedLine );
1285     bool IsNewRedlineComment( const SwRedlineData* pRedLine );
1286     bool WriteText( WW8Export& rWrt );
1287     void WritePlc( WW8Export& rWrt ) const;
1288 };
1289 
1290 class WW8_WrPlcTextBoxes : public WW8_WrPlcSubDoc // double Plc for Textboxes
1291 {                        // Frame/DrawTextboxes!
1292 private:
1293     sal_uInt8 nTyp;
1294     std::vector<sal_uInt32> aShapeIds;        // VARARR of ShapeIds for the SwFrameFormats
1295     virtual const std::vector<sal_uInt32>* GetShapeIdArr() const override;
1296 
1297     WW8_WrPlcTextBoxes(const WW8_WrPlcTextBoxes&) = delete;
1298     WW8_WrPlcTextBoxes& operator=(WW8_WrPlcTextBoxes const &) = delete;
1299 public:
WW8_WrPlcTextBoxes(sal_uInt8 nTTyp)1300     explicit WW8_WrPlcTextBoxes( sal_uInt8 nTTyp ) : nTyp( nTTyp ) {}
1301 
1302     bool WriteText( WW8Export& rWrt );
1303     void WritePlc( WW8Export& rWrt ) const;
1304     void Append( const SdrObject& rObj, sal_uInt32 nShapeId );
1305     void Append( const SwFrameFormat* pFormat, sal_uInt32 nShapeId );
Count() const1306     sal_uInt16 Count() const { return aContent.size(); }
GetPos(const void * p) const1307     sal_uInt16 GetPos( const void* p ) const
1308     {
1309         std::vector<const void*>::const_iterator it
1310             = std::find( aContent.begin(), aContent.end(), p );
1311         return it == aContent.end() ? USHRT_MAX : it - aContent.begin();
1312     }
1313 };
1314 
1315 class WW8_WrPlcPn                   // Plc for Page Numbers
1316 {
1317 private:
1318     WW8Export& rWrt;
1319     // Plc for Chpx and Papx ( incl PN-Plc )
1320     std::vector<std::unique_ptr<WW8_WrFkp>> m_Fkps;
1321     sal_uInt16 nFkpStartPage;
1322     ePLCFT ePlc;
1323 
1324     WW8_WrPlcPn(const WW8_WrPlcPn&) = delete;
1325     WW8_WrPlcPn& operator=(const WW8_WrPlcPn&) = delete;
1326 public:
1327     WW8_WrPlcPn( WW8Export& rWrt, ePLCFT ePl, WW8_FC nStartFc );
1328     ~WW8_WrPlcPn();
1329     void AppendFkpEntry(WW8_FC nEndFc,short nVarLen = 0,const sal_uInt8* pSprms = nullptr);
1330     void WriteFkps();
1331     void WritePlc();
1332     sal_uInt8 *CopyLastSprms(sal_uInt8 &rLen);
1333 };
1334 
1335 // class WW8_WrPlc1 is only used for fields
1336 class WW8_WrPlc1
1337 {
1338 private:
1339     std::vector<WW8_CP> aPos;
1340     std::unique_ptr<sal_uInt8[]> pData;                // content ( structures )
1341     sal_uLong nDataLen;
1342     sal_uInt16 const nStructSiz;
1343 
1344     WW8_WrPlc1(const WW8_WrPlc1&) = delete;
1345     WW8_WrPlc1& operator=(const WW8_WrPlc1&) = delete;
1346 protected:
Count() const1347     sal_uInt16 Count() const { return aPos.size(); }
1348     void Write( SvStream& rStrm );
1349     WW8_CP Prev() const;
1350 public:
1351     explicit WW8_WrPlc1( sal_uInt16 nStructSz );
1352     ~WW8_WrPlc1();
1353     void Append( WW8_CP nCp, const void* pData );
1354     void Finish( sal_uLong nLastCp, sal_uLong nStartCp );
1355 };
1356 
1357 // class WW8_WrPlcField is for fields
1358 class WW8_WrPlcField : public WW8_WrPlc1
1359 {
1360 private:
1361     sal_uInt8 const nTextTyp;
1362     sal_uInt16 nResults;
1363 
1364     WW8_WrPlcField(const WW8_WrPlcField&) = delete;
1365     WW8_WrPlcField& operator=(const WW8_WrPlcField&) = delete;
1366 public:
WW8_WrPlcField(sal_uInt16 nStructSz,sal_uInt8 nTTyp)1367     WW8_WrPlcField( sal_uInt16 nStructSz, sal_uInt8 nTTyp )
1368         : WW8_WrPlc1( nStructSz ), nTextTyp( nTTyp ), nResults(0)
1369     {}
1370     void Write( WW8Export& rWrt );
ResultAdded()1371     void ResultAdded() { ++nResults; }
ResultCount() const1372     sal_uInt16 ResultCount() const { return nResults; }
1373 };
1374 
1375 class WW8_WrMagicTable : public WW8_WrPlc1
1376 {
1377 private:
1378     WW8_WrMagicTable(const WW8_WrMagicTable&) = delete;
1379     WW8_WrMagicTable& operator=(const WW8_WrMagicTable&) = delete;
1380 public:
WW8_WrMagicTable()1381     WW8_WrMagicTable() : WW8_WrPlc1( 4 ) {Append(0,0);}
1382     void Append( WW8_CP nCp, sal_uLong nData );
1383     void Write( WW8Export& rWrt );
1384 };
1385 
1386 class GraphicDetails
1387 {
1388 public:
1389     ww8::Frame const maFly;                // surrounding FlyFrames
1390     sal_uLong mnPos;                // FilePos of the graphics
1391     sal_uInt16 const mnWid;               // Width of the graphics
1392     sal_uInt16 const mnHei;               // Height of the graphics
1393 
GraphicDetails(const ww8::Frame & rFly,sal_uInt16 nWid,sal_uInt16 nHei)1394     GraphicDetails(const ww8::Frame &rFly, sal_uInt16 nWid, sal_uInt16 nHei)
1395         : maFly(rFly), mnPos(0), mnWid(nWid), mnHei(nHei)
1396     {}
1397 
operator ==(const GraphicDetails & rIn) const1398     bool operator==(const GraphicDetails& rIn) const
1399     {
1400         return (
1401                  (mnWid == rIn.mnWid) && (mnHei == rIn.mnHei) &&
1402                  (maFly.RefersToSameFrameAs(rIn.maFly))
1403                );
1404     }
1405 };
1406 
1407 // class SwWW8WrGrf collects graphics and issues them
1408 class SwWW8WrGrf
1409 {
1410 private:
1411     /// for access to the variables
1412     WW8Export& rWrt;
1413 
1414     std::vector<GraphicDetails> maDetails;
1415     sal_uInt16 mnIdx;       // index in file positions
1416 
1417     static void WritePICFHeader(SvStream& rStrm, const ww8::Frame &rFly,
1418             sal_uInt16 mm, sal_uInt16 nWidth, sal_uInt16 nHeight,
1419             const SwAttrSet* pAttrSet = nullptr);
1420     void WriteGraphicNode(SvStream& rStrm, const GraphicDetails &rItem);
1421     void WriteGrfFromGrfNode(SvStream& rStrm, const SwGrfNode &rNd,
1422         const ww8::Frame &rFly, sal_uInt16 nWidth, sal_uInt16 nHeight);
1423 
1424     static void WritePICBulletFHeader(SvStream& rStrm, const Graphic &rGrf, sal_uInt16 mm, sal_uInt16 nWidth, sal_uInt16 nHeight);
1425     void WriteGrfForBullet(SvStream& rStrm,  const Graphic &rGrf, sal_uInt16 nWidth, sal_uInt16 nHeight);
1426 
1427     SwWW8WrGrf(const SwWW8WrGrf&) = delete;
1428     SwWW8WrGrf& operator=(const SwWW8WrGrf&) = delete;
1429 public:
SwWW8WrGrf(WW8Export & rW)1430     explicit SwWW8WrGrf( WW8Export& rW ) : rWrt( rW ), mnIdx( 0 ) {}
1431     void Insert(const ww8::Frame &rFly);
1432     void Write();
GetFPos()1433     sal_uLong GetFPos()
1434         { return (mnIdx < maDetails.size()) ? maDetails[mnIdx++].mnPos : 0; }
1435 };
1436 
1437 /** The class MSWordAttrIter is a helper class to build the Fkp.chpx.
1438     This is a base class to output the SwTextAttrs and the EditEngineTextAttrs.
1439 */
1440 class MSWordAttrIter
1441 {
1442 private:
1443     MSWordAttrIter* const pOld;
1444     MSWordAttrIter(const MSWordAttrIter&) = delete;
1445     MSWordAttrIter& operator=(const MSWordAttrIter&) = delete;
1446 protected:
1447     MSWordExportBase& m_rExport;
1448 public:
1449     explicit MSWordAttrIter( MSWordExportBase& rExport );
1450     virtual ~MSWordAttrIter();
1451 
1452     virtual const SfxPoolItem* HasTextItem( sal_uInt16 nWhich ) const = 0;
1453     virtual const SfxPoolItem& GetItem( sal_uInt16 nWhich ) const = 0;
1454  };
1455 
1456 /// Used to export formatted text associated to drawings.
1457 class MSWord_SdrAttrIter : public MSWordAttrIter
1458 {
1459 private:
1460     const EditTextObject* pEditObj;
1461     const SfxItemPool* pEditPool;
1462     std::vector<EECharAttrib> aTextAtrArr;
1463     std::vector<const EECharAttrib*> aChrTextAtrArr;
1464     std::vector<rtl_TextEncoding> aChrSetArr;
1465     sal_Int32 nPara;
1466     sal_Int32 nCurrentSwPos;
1467     sal_Int32 nTmpSwPos;                   // for HasItem()
1468     rtl_TextEncoding eNdChrSet;
1469     sal_uInt16 nScript;
1470     sal_uInt8 const mnTyp;
1471 
1472     sal_Int32 SearchNext( sal_Int32 nStartPos );
1473     void SetCharSet(const EECharAttrib& rTextAttr, bool bStart);
1474 
1475     void SetItemsThatDifferFromStandard(bool bCharAttr, SfxItemSet& rSet);
1476 
1477     MSWord_SdrAttrIter(const MSWord_SdrAttrIter&) = delete;
1478     MSWord_SdrAttrIter& operator=(const MSWord_SdrAttrIter&) = delete;
1479 public:
1480     MSWord_SdrAttrIter( MSWordExportBase& rWr, const EditTextObject& rEditObj,
1481         sal_uInt8 nType );
1482     void NextPara( sal_Int32 nPar );
1483     void OutParaAttr(bool bCharAttr, const std::set<sal_uInt16>* pWhichsToIgnore = nullptr);
1484     void OutEEField(const SfxPoolItem& rHt);
1485 
1486     bool IsTextAttr(sal_Int32 nSwPos);
1487 
NextPos()1488     void NextPos() { if ( nCurrentSwPos < SAL_MAX_INT32 ) nCurrentSwPos = SearchNext( nCurrentSwPos + 1 ); }
1489 
1490     void OutAttr( sal_Int32 nSwPos );
1491     virtual const SfxPoolItem* HasTextItem( sal_uInt16 nWhich ) const override;
1492     virtual const SfxPoolItem& GetItem( sal_uInt16 nWhich ) const override;
WhereNext() const1493     sal_Int32 WhereNext() const                { return nCurrentSwPos; }
1494     rtl_TextEncoding GetNextCharSet() const;
GetNodeCharSet() const1495     rtl_TextEncoding GetNodeCharSet() const     { return eNdChrSet; }
1496 };
1497 
1498 // class SwWW8AttrIter is a helper for constructing the Fkp.chpx.
1499 // Only character attributes are considered; paragraph attributes do not need this treatment.
1500 // The paragraph and text attributes of the Writer are passed, and
1501 // Where() returns the next position where the attributes change.
1502 // IsTextAtr() tells if, at the position returned by Where(), there is
1503 // an attribute without end and with \xff in the text.
1504 // Using OutAttr(), the attributes on the passed SwPos are returned.
1505 class SwWW8AttrIter : public MSWordAttrIter
1506 {
1507 private:
1508     const SwTextNode& rNd;
1509 
1510     sw::util::CharRuns maCharRuns;
1511     sw::util::CharRuns::const_iterator maCharRunIter;
1512 
1513     rtl_TextEncoding meChrSet;
1514     sal_uInt16 mnScript;
1515     bool mbCharIsRTL;
1516 
1517     const SwRangeRedline* pCurRedline;
1518     sal_Int32 nCurrentSwPos;
1519     SwRedlineTable::size_type nCurRedlinePos;
1520 
1521     bool mbParaIsRTL;
1522 
1523     const SwFormatDrop &mrSwFormatDrop;
1524 
1525     ww8::Frames maFlyFrames;     // #i2916#
1526     ww8::FrameIter maFlyIter;
1527 
1528     sal_Int32 SearchNext( sal_Int32 nStartPos );
1529 
1530     void OutSwFormatRefMark(const SwFormatRefMark& rAttr);
1531 
1532     void IterToCurrent();
1533 
1534     SwWW8AttrIter(const SwWW8AttrIter&) = delete;
1535     SwWW8AttrIter& operator=(const SwWW8AttrIter&) = delete;
1536 
1537     void handleToggleProperty(SfxItemSet& rExportSet, const SwFormatCharFormat* pCharFormatItem, sal_uInt16 nWhich, const SfxPoolItem* pValue);
1538 public:
1539     SwWW8AttrIter( MSWordExportBase& rWr, const SwTextNode& rNd );
1540 
1541     bool IsTextAttr( sal_Int32 nSwPos ) const;
1542     bool IsExportableAttr(sal_Int32 nSwPos) const;
1543     bool IncludeEndOfParaCRInRedlineProperties(sal_Int32 nPos) const;
1544     bool IsDropCap( int nSwPos );
1545     bool RequiresImplicitBookmark();
1546 
NextPos()1547     void NextPos() { if ( nCurrentSwPos < SAL_MAX_INT32 ) nCurrentSwPos = SearchNext( nCurrentSwPos + 1 ); }
1548 
1549     void OutAttr( sal_Int32 nSwPos, bool bWriteCombinedChars );
1550     virtual const SfxPoolItem* HasTextItem( sal_uInt16 nWhich ) const override;
1551     virtual const SfxPoolItem& GetItem( sal_uInt16 nWhich ) const override;
1552     int OutAttrWithRange(const SwTextNode& rNode, sal_Int32 nPos);
1553     const SwRedlineData* GetParagraphLevelRedline( );
1554     const SwRedlineData* GetRunLevelRedline( sal_Int32 nPos );
1555     FlyProcessingState OutFlys(sal_Int32 nSwPos);
1556     bool HasFlysAt(sal_Int32 nSwPos) const;
1557 
WhereNext() const1558     sal_Int32 WhereNext() const { return nCurrentSwPos; }
GetScript() const1559     sal_uInt16 GetScript() const { return mnScript; }
IsParaRTL() const1560     bool IsParaRTL() const { return mbParaIsRTL; }
GetCharSet() const1561     rtl_TextEncoding GetCharSet() const { return meChrSet; }
1562     OUString GetSnippet(const OUString &rStr, sal_Int32 nCurrentPos,
1563         sal_Int32 nLen) const;
GetSwFormatDrop() const1564     const SwFormatDrop& GetSwFormatDrop() const { return mrSwFormatDrop; }
1565 
1566     bool IsWatermarkFrame();
1567     bool IsAnchorLinkedToThisNode( sal_uLong nNodePos );
1568 
1569     void SplitRun( sal_Int32 nSplitEndPos );
1570 
GetNode() const1571     const SwTextNode& GetNode() const { return rNd; }
1572 };
1573 
1574 /// Class to collect and output the styles table.
1575 class MSWordStyles
1576 {
1577     MSWordExportBase& m_rExport;
1578     sal_uInt16 m_aHeadingParagraphStyles[MAXLEVEL];
1579     std::unique_ptr<SwFormat*[]> m_pFormatA; ///< Slot <-> Character and paragraph style array (0 for list styles).
1580     sal_uInt16 m_nUsedSlots;
1581     bool const m_bListStyles; ///< If list styles are requested to be exported as well.
1582     std::map<sal_uInt16, const SwNumRule*> m_aNumRules; ///< Slot <-> List style map.
1583 
1584     /// We need to build style id's for DOCX export; ideally we should roundtrip that, but this is good enough.
1585     std::vector<OString> m_aStyleIds;
1586 
1587     /// Create the style table, called from the constructor.
1588     void BuildStylesTable();
1589 
1590     /// Based on pFormatA, fill in m_aStyleIds with unique, MS-like names.
1591     void BuildStyleIds();
1592 
1593     /// Get slot number during building the style table.
1594     sal_uInt16 BuildGetSlot( const SwFormat& rFormat );
BuildGetSlot(const SwNumRule &)1595     sal_uInt16 BuildGetSlot( const SwNumRule& /*rNumRule*/ ) { return m_nUsedSlots++;}
1596 
1597     /// Return information about one style.
1598     void GetStyleData( SwFormat* pFormat, bool& bFormatColl, sal_uInt16& nBase, sal_uInt16& nNext );
1599 
1600     /// Outputs attributes of one style.
1601     void WriteProperties( const SwFormat* pFormat, bool bPap, sal_uInt16 nPos, bool bInsDefCharSiz );
1602 
1603     static sal_uInt16 GetWWId( const SwFormat& rFormat );
1604 
1605     void SetStyleDefaults( const SwFormat& rFormat, bool bPap );
1606 
1607     /// Outputs one style - called (in a loop) from OutputStylesTable().
1608     void OutputStyle( SwFormat* pFormat, sal_uInt16 nPos );
1609     void OutputStyle( const SwNumRule* pNumRule, sal_uInt16 nPos );
1610 
1611     MSWordStyles( const MSWordStyles& ) = delete;
1612     MSWordStyles& operator=( const MSWordStyles& ) = delete;
1613 
1614 public:
1615     MSWordStyles( MSWordExportBase& rExport, bool bListStyles = false );
1616     ~MSWordStyles();
1617 
1618     /// Output the styles table.
1619     void OutputStylesTable();
1620 
1621     /// Get id of the style (rFormat).
1622     sal_uInt16 GetSlot( const SwFormat* pFormat ) const;
1623 
1624     /// create style id using only ASCII characters of the style name
1625     static OString CreateStyleId(const OUString &rName);
1626 
1627     /// Get styleId of the nId-th style (nId is its position in pFormatA).
1628     OString const & GetStyleId(sal_uInt16 nId) const;
1629 
GetSwFormat(sal_uInt16 nId) const1630     const SwFormat* GetSwFormat(sal_uInt16 nId) const { return m_pFormatA[nId]; }
1631     /// Get numbering rule of the nId-th style
1632     const SwNumRule* GetSwNumRule(sal_uInt16 nId) const;
GetHeadingParagraphStyleId(sal_uInt16 nLevel) const1633     sal_uInt16 GetHeadingParagraphStyleId(sal_uInt16 nLevel) const { return m_aHeadingParagraphStyles[ nLevel ]; }
1634 };
1635 
1636 #define MSWORD_MAX_STYLES_LIMIT 4091
1637 
1638 sal_Int16 GetWordFirstLineOffset(const SwNumFormat &rFormat);
1639 // A bit of a bag on the side for now
1640 OUString FieldString(ww::eField eIndex);
1641 OUString BookmarkToWord(const OUString &rBookmark);
1642 
1643 class WW8SHDLong
1644 {
1645     sal_uInt32 m_cvFore;
1646     sal_uInt32 m_cvBack;
1647 
1648 public:
WW8SHDLong()1649     WW8SHDLong() : m_cvFore(0), m_cvBack(0) {}
1650 
1651     void Write(WW8Export & rExport);
setCvFore(sal_uInt32 cvFore)1652     void setCvFore(sal_uInt32 cvFore) { m_cvFore = cvFore; }
setCvBack(sal_uInt32 cvBack)1653     void setCvBack(sal_uInt32 cvBack) { m_cvBack = cvBack; }
1654 };
1655 
1656 #endif // INCLUDED_SW_SOURCE_FILTER_WW8_WRTWW8_HXX
1657 
1658 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
1659