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