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_WW8STRUC_HXX
21 #define INCLUDED_SW_SOURCE_FILTER_WW8_WW8STRUC_HXX
22 
23 #include <sal/config.h>
24 
25 #include <rtl/ustring.hxx>
26 
27 #include <filter/msfilter/util.hxx>
28 #include <i18nlangtag/lang.h>
29 #include <tools/color.hxx>
30 #include <tools/solar.h>
31 #include <tools/stream.hxx>
32 
33 #include <vector>
34 
35 #ifdef _WIN32
36 #   pragma pack(push, 2)
37 #endif
38 
39 class WW8Export;
40 
Set_UInt8(sal_uInt8 * & p,sal_uInt8 n)41 inline void Set_UInt8( sal_uInt8 *& p, sal_uInt8 n )
42 {
43     *p = n;
44     p+= 1;
45 }
46 
Set_UInt16(sal_uInt8 * & p,sal_uInt16 n)47 inline void Set_UInt16( sal_uInt8 *& p, sal_uInt16 n )
48 {
49     ShortToSVBT16( n, *reinterpret_cast<SVBT16*>(p) );
50     p+= 2;
51 }
52 
Set_UInt32(sal_uInt8 * & p,sal_uInt32 n)53 inline void Set_UInt32( sal_uInt8 *& p, sal_uInt32 n )
54 {
55     UInt32ToSVBT32( n, *reinterpret_cast<SVBT32*>(p) );
56     p+= 4;
57 }
58 
59 struct Word2CHPX
60 {
61     sal_uInt16 fBold:1;
62     sal_uInt16 fItalic:1;
63     sal_uInt16 fRMarkDel:1;
64     sal_uInt16 fOutline:1;
65     sal_uInt16 fFieldVanish:1;
66     sal_uInt16 fSmallCaps:1;
67     sal_uInt16 fCaps:1;
68     sal_uInt16 fVanish:1;
69     sal_uInt16 fRMark:1;
70     sal_uInt16 fSpec:1;
71     sal_uInt16 fStrike:1;
72     sal_uInt16 fObj:1;
73     sal_uInt16 fBoldBi:1;
74     sal_uInt16 fItalicBi:1;
75     sal_uInt16 fBiDi:1;
76     sal_uInt16 fDiacUSico:1;
77     sal_uInt16 fsIco:1;
78     sal_uInt16 fsFtc:1;
79     sal_uInt16 fsHps:1;
80     sal_uInt16 fsKul:1;
81     sal_uInt16 fsPos:1;
82     sal_uInt16 fsSpace:1;
83     sal_uInt16 fsLid:1;
84     sal_uInt16 fsIcoBi:1;
85     sal_uInt16 fsFtcBi:1;
86     sal_uInt16 fsHpsBi:1;
87     sal_uInt16 fsLidBi:1;
88 
89     sal_uInt16 ftc;
90     sal_uInt16 hps;
91     sal_uInt8 qpsSpace:6;
92     sal_uInt8 fSysVanish:1;
93     sal_uInt8 fNumRun:1;
94     sal_uInt8 ico:5;
95     sal_uInt8 kul:3;
96     sal_uInt8 hpsPos;
97     sal_uInt8 icoBi;
98     sal_uInt16 lid;
99     sal_uInt16 ftcBi;
100     sal_uInt16 hpsBi;
101     sal_uInt16 lidBi;
102     sal_uInt32 fcPic;
103 
Word2CHPXWord2CHPX104     Word2CHPX()
105     {
106         fBold = 0;
107         fItalic = 0;
108         fRMarkDel = 0;
109         fOutline = 0;
110         fFieldVanish = 0;
111         fSmallCaps = 0;
112         fCaps = 0;
113         fVanish = 0;
114         fRMark = 0;
115         fSpec = 0;
116         fStrike = 0;
117         fObj = 0;
118         fBoldBi = 0;
119         fItalicBi = 0;
120         fBiDi = 0;
121         fDiacUSico = 0;
122         fsIco = 0;
123         fsFtc = 0;
124         fsHps = 0;
125         fsKul = 0;
126         fsPos = 0;
127         fsSpace = 0;
128         fsLid = 0;
129         fsIcoBi = 0;
130         fsFtcBi = 0;
131         fsHpsBi = 0;
132         fsLidBi = 0;
133 
134         ftc = 0;
135         hps = 0;
136         qpsSpace = 0;
137         fSysVanish = 0;
138         fNumRun = 0;
139         ico = 0;
140         kul = 0;
141         hpsPos = 0;
142         icoBi = 0;
143         lid = 0;
144         ftcBi = 0;
145         hpsBi = 0;
146         lidBi = 0;
147         fcPic = 0;
148     }
149 };
150 
151 typedef sal_Int16 WW8_PN;
152 typedef sal_Int32 WW8_FC;
153 typedef sal_Int32 WW8_CP;
154 
155 const WW8_FC WW8_FC_MAX = SAL_MAX_INT32;
156 const WW8_CP WW8_CP_MAX = SAL_MAX_INT32;
157 
158 /** STD - STyle Definition
159 
160     The STD contains the entire definition of a style.
161     It has two parts, a fixed-length base (cbSTDBase bytes long)
162     and a variable length remainder holding the name, and the upx and upe
163     arrays (a upx and upe for each type stored in the style, std.cupx)
164     Note that new fields can be added to the BASE of the STD without
165     invalidating the file format, because the STSHI contains the length
166     that is stored in the file.  When reading STDs from an older version,
167     new fields will be zero.
168 */
169 struct WW8_STD
170 {
171     // Base part of STD:
172     sal_uInt16  sti : 12;          // invariant style identifier
173     sal_uInt16  fScratch : 1;      // spare field for any temporary use,
174                                                          // always reset back to zero!
175     sal_uInt16  fInvalHeight : 1;  // PHEs of all text with this style are wrong
176     sal_uInt16  fHasUpe : 1;       // UPEs have been generated
177     sal_uInt16  fMassCopy : 1;     // std has been mass-copied; if unused at
178                                                          // save time, style should be deleted
179     sal_uInt16  sgc : 4;           // style type code
180     sal_uInt16  istdBase : 12;     // base style
181     sal_uInt16  cupx : 4;          // # of UPXs (and UPEs)
182     sal_uInt16  istdNext : 12;     // next style
183     sal_uInt16  bchUpe;            // offset to end of upx's, start of upe's
184     // new:
185     // from Ver8 on there are two more fields:
186   sal_uInt16    fAutoRedef : 1;    /* auto redefine style when appropriate */
187   sal_uInt16    fHidden : 1;       /* hidden from UI? */
188   sal_uInt16    : 14;              /* unused bits */
189 
190     // Variable length part of STD:
191     //  sal_uInt8   stzName[2];        /* sub-names are separated by chDelimStyle
192     // char grupx[];
193             // the UPEs are not stored on the file; they are a cache of the based-on
194         // chain
195     // char grupe[];
196 };
197 
198 static_assert(sizeof (WW8_STD) == 10, "this has to match the msword size");
199 
200 /** base for reading AND working on (will have different subclasses */
201 struct WW8_FFN_BASE     // Font Descriptor
202 {
203     // from Ver6 on
204     sal_uInt8    cbFfnM1;        //  0x0     total length of FFN - 1.
205 
206     sal_uInt8    prg: 2;         //  0x1:03  pitch request
207     sal_uInt8    fTrueType : 1;  //  0x1:04  when 1, font is a TrueType font
208     sal_uInt8    _reserved1 : 1; //  0x1:08  reserved
209     sal_uInt8    ff : 3;         //  0x1:70  font family id
210     sal_uInt8    _reserved2 : 1; //  0x1:80  reserved
211 
212     short wWeight;          //  0x2     base weight of font
213     sal_uInt8    chs;            //  0x4     character set identifier
214     sal_uInt8    ibszAlt;        //  0x5     index into ffn.szFfn to the name of the alternate font
215 };
216 
217 static_assert(sizeof (WW8_FFN_BASE) == 6, "this has to match the msword size");
218 
219 /** This is what we use in the Parser (and Dumper)
220 */
221 struct WW8_FFN
222 {
223     // from Ver8 on as Unicode
224     OUString sFontname;// 0x6 or 0x40 resp. from Ver8 on zero terminated string that
225                                         // records name of font.
226                                         // Maximal size of szFfn is 65 characters.
227                                         // Attention: This array can be smaller!!!
228                                         // Possibly followed by a second sz which records the
229                                         // name of an alternate font to use if the first named
230                                         // font does not exist on this system.
231     WW8_FFN_BASE aFFNBase;
232 };
233 
234 struct WW8_BRCVer6  // BoRder Code (WW6 version)
235 {
236     SVBT16 aBits1 = {};
237 //  sal_uInt16 dxpLineWidth : 3;// 0007 When dxpLineWidth is 0, 1, 2, 3, 4, or 5, this field is the width of
238                             //      a single line of border in units of 0.75 points
239                             //      Must be nonzero when brcType is nonzero.
240                             //      6 == dotted, 7 == dashed.
241 //  sal_uInt16 brcType : 2;     // 0018 border type code: 0 == none, 1 == single, 2 == thick, 3 == double
242 //  sal_uInt16 fShadow : 1;     // 0020 when 1, border is drawn with shadow. Must be 0 when BRC is a substructure of the TC
243 //  sal_uInt16 ico : 5;         // 07C0 color code (see chp.ico)
244 //  sal_uInt16 dxpSpace : 5;    // F800 width of space to maintain between border and text within border.
245                             //      Must be 0 when BRC is a substructure of the TC.  Stored in points for Windows.
246     WW8_BRCVer6() = default;
247 
dxpLineWidthWW8_BRCVer6248     sal_uInt8 dxpLineWidth() const
249         { return aBits1[0] & 0x07; }
brcTypeWW8_BRCVer6250     sal_uInt8 brcType() const
251         { return (aBits1[0] & 0x18) >> 3; }
fShadowWW8_BRCVer6252     bool fShadow() const
253         { return !!(aBits1[0] & 0x20); }
icoWW8_BRCVer6254     sal_uInt8 ico() const
255         { return ((aBits1[0] & 0xc0) >> 6) | ((aBits1[1] & 0x07) << 2); }
dxpSpaceWW8_BRCVer6256     sal_uInt8 dxpSpace() const
257         { return aBits1[1] >> 3; }
258 };
259 
260 struct WW8_BRC  // BoRder Code (WW8 version)
261 // Documented at http://msdn.microsoft.com/en-us/library/dd952599.aspx
262 {
263     SVBT16 aBits1 = {};
264     SVBT16 aBits2 = {};
265 //  sal_uInt8 dptLineWidth;
266 //  sal_uInt8 brcType;
267 //  sal_uInt8 ico;
268 //  sal_uInt8 dptSpace : 5
269 //  bool fShadow : 1;
270 //  bool fFrame : 1;
271 //  bool fReserved : 1;
272     WW8_BRC() = default;
273 
dptLineWidthWW8_BRC274     sal_uInt8 dptLineWidth() const // border line width (1/8pt)
275         { return aBits1[0]; }
brcTypeWW8_BRC276     sal_uInt8 brcType() const      // border type (eg single, double, dotted)
277         { return aBits1[1]; }
icoWW8_BRC278     sal_uInt8 ico() const          // colour index, 1-17 or 0=auto
279         { return aBits2[0]; }
dptSpaceWW8_BRC280     sal_uInt8 dptSpace() const     // space between text & border (pt)
281         { return aBits2[1] & 0x1f; }
fShadowWW8_BRC282     bool fShadow() const           // shadow effect
283         { return !!(aBits2[1] & 0x20); }
fFrameWW8_BRC284     bool fFrame() const            // 3D frame effect
285         { return !!(aBits2[1] & 0x40); }
isNilWW8_BRC286     bool isNil() const             // nil = no border
287         { return aBits1[0] == 0xff && aBits1[1] == 0xff; }
288 
WW8_BRCWW8_BRC289     WW8_BRC(sal_uInt8 _dptLineWidth, sal_uInt8 _brcType, sal_uInt8 _ico,
290         sal_uInt8 _dptSpace, bool _fShadow, bool _fFrame)
291     {
292         assert(_dptSpace < 0x20);
293         aBits1[0] = _dptLineWidth;
294         aBits1[1] = _brcType;
295         aBits2[0] = _ico;
296         aBits2[1] = _dptSpace | (static_cast<sal_uInt8>(_fShadow) << 5)
297             | (static_cast<sal_uInt8>(_fFrame) << 6);
298     }
299     // Convert BRC from WW6 to WW8 format
300     explicit WW8_BRC(const WW8_BRCVer6& brcVer6);
301 
302     // Returns LO border width in twips=1/20pt, taking into account brcType
303     short DetermineBorderProperties(short *pSpace) const;
304 };
305 
306 typedef WW8_BRC WW8_BRC5[5];        // 5 * Border Code
307 
308 struct WW8_BRCVer9  // BoRder Code (WW9 version)
309 // Documented at http://msdn.microsoft.com/en-us/library/dd907496.aspx
310 {
311     SVBT32 aBits1 = {}; // border colour (RGB)
312     SVBT32 aBits2 = {};
313 //  sal_uInt8 dptLineWidth;   // border line width (1/8pt)
314 //  sal_uInt8 brcType;        // border type (eg single, double, dotted)
315 //  sal_uInt8 dptSpace : 5;   // space between text & border (pt)
316 //  bool fShadow : 1;         // border has shadow effect
317 //  bool fFrame : 1;          // border has 3D effect
318 //  sal_uInt16 fReserved : 9; // unused
319     WW8_BRCVer9() = default;
320 
cvWW8_BRCVer9321     sal_uInt32 cv() const          // colour value (BGR)
322         { return SVBT32ToUInt32(aBits1); }
dptLineWidthWW8_BRCVer9323     sal_uInt8 dptLineWidth() const // border line width (1/8pt)
324         { return aBits2[0]; }
brcTypeWW8_BRCVer9325     sal_uInt8 brcType() const      // border type (eg single, double, dotted)
326         { return aBits2[1]; }
dptSpaceWW8_BRCVer9327     sal_uInt8 dptSpace() const     // space between text & border (pt)
328         { return aBits2[2] & 0x1f; }
fShadowWW8_BRCVer9329     bool fShadow() const           // shadow effect
330         { return !!(aBits2[2] & 0x20); }
fFrameWW8_BRCVer9331     bool fFrame() const            // 3D frame effect
332         { return !!(aBits2[2] & 0x40); }
isNilWW8_BRCVer9333     bool isNil() const             // nil = no border
334         { return SVBT32ToUInt32(aBits2) == 0xffffffff; }
335 
WW8_BRCVer9WW8_BRCVer9336     WW8_BRCVer9(sal_uInt32 _cv, sal_uInt8 _dptLineWidth, sal_uInt8 _brcType,
337         sal_uInt8 _dptSpace, bool _fShadow, bool _fFrame)
338     {
339         assert(_dptSpace < 0x20);
340         UInt32ToSVBT32(_cv, aBits1);
341         aBits2[0] = _dptLineWidth;
342         aBits2[1] = _brcType;
343         aBits2[2] = _dptSpace | (static_cast<sal_uInt8>(_fShadow) << 5)
344             | (static_cast<sal_uInt8>(_fFrame) << 6);
345         aBits2[3] = 0;
346     }
347     // Convert BRC from WW8 to WW9 format
348     explicit WW8_BRCVer9(const WW8_BRC& brcVer8);
349 
350     // Returns LO border width in twips=1/20pt, taking into account brcType
351     short DetermineBorderProperties(short *pSpace=nullptr) const;
352 };
353 
354 typedef WW8_BRCVer9 WW8_BRCVer9_5[5];        // 5 * Border Code
355 
356 enum BRC_Sides
357 {
358     WW8_TOP = 0, WW8_LEFT = 1, WW8_BOT = 2, WW8_RIGHT = 3, WW8_BETW = 4
359 };
360 
361 /*
362 Document Typography Info (DOPTYPOGRAPHY) These options are Far East only,
363 and are accessible through the Typography tab of the Tools/Options dialog.
364 */
365 class WW8DopTypography
366 {
367 public:
368     void ReadFromMem(sal_uInt8 *&pData);
369     void WriteToMem(sal_uInt8 *&pData) const;
370 
371     //Maps what I think is the language this is to affect to the OOo language
372     LanguageType GetConvertedLang() const;
373 
374     sal_uInt16 m_fKerningPunct  : 1;  // true if we're kerning punctuation
375     sal_uInt16 m_iJustification : 2;  // Kinsoku method of justification:
376                                 //  0 = always expand
377                                 //  1 = compress punctuation
378                                 //  2 = compress punctuation and kana.
379     sal_uInt16 m_iLevelOfKinsoku : 2; // Level of Kinsoku:
380                                 //  0 = Level 1
381                                 //  1 = Level 2
382                                 //  2 = Custom
383     sal_uInt16 m_f2on1          : 1;  // 2-page-on-1 feature is turned on.
384     sal_uInt16 m_reserved1      : 4;  // in 97 its marked as reserved BUT
385     sal_uInt16 m_reserved2      : 6;  // reserved ?
386     //we find that the following applies,
387     //2 == Japanese
388     //4 == Chinese (VR...
389     //6 == Korean
390     //8 == Chinese (Ta...
391     //perhaps a bit field where the DOP can possibly relate to more than
392     //one language at a time, nevertheless MS seems to have painted
393     //themselves into a small corner with one DopTypography for the
394     //full document, might not matter all that much though ?
395 
396     enum RuleLengths {nMaxFollowing = 101, nMaxLeading = 51};
397     static const sal_Unicode * GetJapanNotBeginLevel1();
398     static const sal_Unicode * GetJapanNotEndLevel1();
399 
400     sal_Int16 m_cchFollowingPunct;    // length of rgxchFPunct
401     sal_Int16 m_cchLeadingPunct;      // length of rgxchLPunct
402 
403     // array of characters that should never appear at the start of a line
404     sal_Unicode m_rgxchFPunct[nMaxFollowing];
405     // array of characters that should never appear at the end of a line
406     sal_Unicode m_rgxchLPunct[nMaxLeading];
407 };
408 
409 struct WW8_DOGRID
410 {
411     short xaGrid;       // x-coord of the upper left-hand corner of the grid
412     short yaGrid;       // y-coord of the upper left-hand corner of the grid
413     short dxaGrid;  // width of each grid square
414     short dyaGrid;  // height of each grid square
415 
416     /* attention: you must not put bit fields on top of such a byte array read from a file!
417        instead put an aBits1 on it and read it out with &.
418        reason: compilers on Intel and Sparc sort the bits differently
419     */
420 
421     short dyGridDisplay:7;  // the number of grid squares (in the y direction)
422                                                     // between each gridline drawn on the screen. 0 means
423                                                     // don't display any gridlines in the y direction.
424     short fTurnItOff   :1;  // suppress display of gridlines
425     short dxGridDisplay:7;  // the number of grid squares (in the x direction)
426                                                     // between each gridline drawn on the screen. 0 means
427                                                     // don't display any gridlines in the y direction.
428     short fFollowMargins:1; // if true, the grid will start at the left and top
429                                                     // margins and ignore xaGrid and yaGrid.
430 };
431 
432 static_assert(sizeof (WW8_DOGRID) == 10, "this has to match the msword size");
433 
434 struct WW8_PIC
435 {
436     sal_Int32 lcb;          // 0x0 number of bytes in the PIC structure plus size of following picture data which may be a Window's metafile, a bitmap, or the filename of a TIFF file.
437     sal_uInt16 cbHeader;    // 0x4 number of bytes in the PIC (to allow for future expansion).
438     struct {
439         sal_Int16 mm;       // 0x6  int
440         sal_Int16 xExt;     // 0x8  int
441         sal_Int16 yExt;     // 0xa  int
442         sal_Int16 hMF;      // 0xc  int
443     }MFP;
444 //  sal_uInt8 bm[14];        // 0xe  BITMAP(14 bytes)    Window's bitmap structure when PIC describes a BITMAP.
445     sal_uInt8 rcWinMF[14];   // 0xe  rc (rectangle - 8 bytes) rect for window origin
446                         //      and extents when  metafile is stored -- ignored if 0
447     sal_Int16 dxaGoal;      // 0x1c horizontal  measurement in twips of the  rectangle the picture should be imaged within.
448     sal_Int16 dyaGoal;      // 0x1e vertical  measurement in twips of the  rectangle the picture should be imaged within.
449     sal_uInt16 mx;          // 0x20 horizontal scaling factor supplied by user in .1% units.
450     sal_uInt16 my;          // 0x22 vertical scaling factor supplied by user in .1% units.
451     sal_Int16 dxaCropLeft;  // 0x24 the amount the picture has been cropped on the left in twips.
452     sal_Int16 dyaCropTop;   // 0x26 the amount the picture has been cropped on the top in twips.
453     sal_Int16 dxaCropRight; // 0x28 the amount the picture has been cropped on the right in twips.
454     sal_Int16 dyaCropBottom;// 0x2a the amount the picture has been cropped on the bottom in twips.
455     sal_Int16 brcl : 4;     // 000F Obsolete, superseded by brcTop, etc.  In
456     sal_Int16 fFrameEmpty : 1;  // 0010 picture consists of a single frame
457     sal_Int16 fBitmap : 1;      // 0020 ==1, when picture is just a bitmap
458     sal_Int16 fDrawHatch : 1;   // 0040 ==1, when picture is an active OLE object
459     sal_Int16 fError : 1;       // 0080 ==1, when picture is just an error message
460     sal_Int16 bpp : 8;      // FF00 bits per pixel, 0 = unknown
461     WW8_BRC rgbrc[4];
462 //  BRC brcTop;         // 0x2e specification for border above picture
463 //  BRC brcLeft;        // 0x30 specification for border to the left
464 //  BRC brcBottom;      // 0x32 specification for border below picture
465 //  BRC brcRight;       // 0x34 specification for border to the right
466     sal_Int16 dxaOrigin;    // 0x36 horizontal offset of hand annotation origin
467     sal_Int16 dyaOrigin;    // 0x38 vertical offset of hand annotation origin
468 //  sal_uInt8 rgb[];         // 0x3a variable array of bytes containing Window's metafile, bitmap or TIFF file filename.
469 };
470 
471 struct WW8_PIC_SHADOW
472 {
473     SVBT32 lcb;         // 0x0 number of bytes in the PIC structure plus size of following picture data which may be a Window's metafile, a bitmap, or the filename of a TIFF file.
474     SVBT16 cbHeader;    // 0x4 number of bytes in the PIC (to allow for future expansion).
475     struct {
476         SVBT16 mm;      // 0x6  int
477         SVBT16 xExt;        // 0x8  int
478         SVBT16 yExt;        // 0xa  int
479         SVBT16 hMF;     // 0xc  int
480     }MFP;
481 //  sal_uInt8 bm[14];       // 0xe  BITMAP(14 bytes)    Window's bitmap structure when PIC describes a BITMAP.
482     sal_uInt8 rcWinMF[14];  // 0xe  rc (rectangle - 8 bytes) rect for window origin
483                         //      and extents when  metafile is stored -- ignored if 0
484     SVBT16 dxaGoal;     // 0x1c horizontal  measurement in twips of the  rectangle the picture should be imaged within.
485     SVBT16 dyaGoal;     // 0x1e vertical  measurement in twips of the  rectangle the picture should be imaged within.
486     SVBT16 mx;          // 0x20 horizontal scaling factor supplied by user in .1% units.
487     SVBT16 my;          // 0x22 vertical scaling factor supplied by user in .1% units.
488     SVBT16 dxaCropLeft; // 0x24 the amount the picture has been cropped on the left in twips.
489     SVBT16 dyaCropTop;  // 0x26 the amount the picture has been cropped on the top in twips.
490     SVBT16 dxaCropRight;    // 0x28 the amount the picture has been cropped on the right in twips.
491     SVBT16 dyaCropBottom;// 0x2a    the amount the picture has been cropped on the bottom in twips.
492     sal_uInt8 aBits1; //0x2c
493     sal_uInt8 aBits2;
494 //  WW8_BRC rgbrc[4];
495 //  BRC brcTop;         // 0x2e specification for border above picture
496 //  BRC brcLeft;        // 0x30 specification for border to the left
497 //  BRC brcBottom;      // 0x32 specification for border below picture
498 //  BRC brcRight;       // 0x34 specification for border to the right
499 //  SVBT16 dxaOrigin;   // 0x36 horizontal offset of hand annotation origin
500 //  SVBT16 dyaOrigin;   // 0x38 vertical offset of hand annotation origin
501 //  sal_uInt8 rgb[];            // 0x3a variable array of bytes containing Window's metafile, bitmap or TIFF file filename.
502 };
503 
504 static_assert(sizeof (WW8_PIC_SHADOW) == 0x2E, "this has to match the msword size");
505     // "0x2E": cf. SwWW8ImplReader::PicRead pDataStream->Read call
506 
507 struct WW8_TBD
508 {
509     sal_uInt8 aBits1;
510 //  sal_uInt8 jc : 3;        // 0x07 justification code: 0=left tab, 1=centered tab, 2=right tab, 3=decimal tab, 4=bar
511 //  sal_uInt8 tlc : 3;       // 0x38 tab leader code: 0=no leader, 1=dotted leader,
512                         // 2=hyphenated leader, 3=single line leader, 4=heavy line leader
513 //  *   int :2  C0  reserved
514 };
515 
516 struct WW8_TCell    // this is the base for further work (corresponds mostly to the Ver8 format)
517 {
518     // The single-bit fields should ideally be bool, but probably need to keep
519     // them as sal_uInt8 to make them combine with the following two-bit
520     // nVertAlign:
521     sal_uInt8 bFirstMerged   : 1;// 0001 set to 1 when cell is first cell of a range of cells that have been merged.
522     sal_uInt8 bMerged        : 1;// 0002 set to 1 when cell has been merged with preceding cell.
523     sal_uInt8 bVertical      : 1;// set to 1 when cell has vertical text flow
524     sal_uInt8 bBackward      : 1;// for a vertical table cell, text flow is bottom to top when 1 and is bottom to top when 0.
525     sal_uInt8 bRotateFont    : 1;// set to 1 when cell has rotated characters (i.e. uses @font)
526     sal_uInt8 bVertMerge     : 1;// set to 1 when cell is vertically merged with the cell(s) above and/or below. When cells are vertically merged, the display area of the merged cells are consolidated. The consolidated area is used to display the contents of the first vertically merged cell (the cell with fVertRestart set to 1), and all other vertically merged cells (those with fVertRestart set to 0) must be empty. Cells can only be merged vertically if their left and right boundaries are (nearly) identical (i.e. if corresponding entries in rgdxaCenter of the table rows differ by at most 3).
527     sal_uInt8 bVertRestart   : 1;// set to 1 when the cell is the first of a set of vertically merged cells. The contents of a cell with fVertStart set to 1 are displayed in the consolidated area belonging to the entire set of vertically merged cells. Vertically merged cells with fVertRestart set to 0 must be empty.
528     sal_uInt8 nVertAlign     : 2;// specifies the alignment of the cell contents relative to text flow (e.g. in a cell with bottom to top text flow and bottom vertical alignment, the text is shifted horizontally to match the cell's right boundary):
529                                                     //          0 top
530                                                     //          1 center
531                                                     //          2 bottom
532     sal_uInt16 fUnused      : 7;// reserved - do not remove, fills up the sal_uInt16!
533 
534     WW8_BRCVer9 rgbrc[4];   // border codes
535 //notational convenience for referring to brcTop, brcLeft, etc fields.
536 //  BRC brcTop;             // specification of the top border of a table cell
537 //  BRC brcLeft;            // specification of left border of table row
538 //  BRC brcBottom;          // specification of bottom border of table row
539 //  BRC brcRight;           // specification of right border of table row.
540 
WW8_TCellWW8_TCell541     WW8_TCell():
542         bFirstMerged(0), bMerged(0), bVertical(0), bBackward(0), bRotateFont(0), bVertMerge(0),
543         bVertRestart(0), nVertAlign(0), fUnused(0) {}
544         // default member initializers for the bitfields will only work in C++20
545 };
546 // cbTC (count of bytes of a TC) is 18(decimal), 12(hex).
547 
548 struct WW8_TCellVer6    // read from file
549 {
550     sal_uInt8  aBits1Ver6;
551     sal_uInt8  aBits2Ver6;
552 //  sal_uInt16 fFirstMerged : 1;// 0001 set to 1 when cell is first cell of a range of cells that have been merged.
553 //  sal_uInt16 fMerged : 1;     // 0002 set to 1 when cell has been merged with preceding cell.
554 //  sal_uInt16 fUnused : 14;    // FFFC reserved
555     WW8_BRCVer6 rgbrcVer6[4];
556 // notational convenience for referring to brcTop, brcLeft, etc fields:
557 //          BRC brcTop;             // specification of the top border of a table cell
558 //          BRC brcLeft;            // specification of left border of table row
559 //          BRC brcBottom;          // specification of bottom border of table row
560 //          BRC brcRight;           // specification of right border of table row.
561 };
562 // cbTC (count of bytes of a TC) is 10(decimal), A(hex).
563 
564 struct WW8_TCellVer8    // read from file
565 {
566     SVBT16 aBits1Ver8;      // Documentation: see above at WW8_TCell
567     SVBT16 aUnused;         // reserve
568     WW8_BRC rgbrcVer8[4];   // Documentation: see above at WW8_TCell
569 };
570 // cbTC (count of bytes of a TC) is 20(decimal), 14(hex).
571 
572 struct WW8_SHD              // struct SHD is missing from the description
573 {
574 private:
575     sal_uInt16 maBits;
576 //  sal_uInt16 nFore : 5;       // 0x001f ForegroundColor
577 //  sal_uInt16 nBack : 5;       // 0x03e0 BackgroundColor
578 //  sal_uInt16 nStyle : 5;      // 0x7c00 Percentage and Style
579 //  sal_uInt16 nDontKnow : 1;   // 0x8000 ???   from Ver8: also for Style
580 
581 public:
WW8_SHDWW8_SHD582     WW8_SHD() : maBits(0) {}
583 
GetForeWW8_SHD584     sal_uInt8 GetFore() const { return static_cast<sal_uInt8>( maBits & 0x1f); }
GetBackWW8_SHD585     sal_uInt8 GetBack() const { return static_cast<sal_uInt8>((maBits >> 5 ) & 0x1f); }
GetStyleWW8_SHD586     sal_uInt8 GetStyle(bool bVer67)  const
587         { return static_cast<sal_uInt8>((maBits >> 10) & ( bVer67 ? 0x1f : 0x3f ) ); }
588 
GetValueWW8_SHD589     sal_uInt16 GetValue() const { return maBits; }
590 
SetWWValueWW8_SHD591     void SetWWValue(SVBT16 const nVal) { maBits = SVBT16ToUInt16(nVal); }
592 
SetForeWW8_SHD593     void SetFore(sal_uInt8 nVal)
594     {
595         maBits &= 0xffe0;
596         maBits |= (nVal & 0x1f);
597     }
SetBackWW8_SHD598     void SetBack(sal_uInt8 nVal)
599     {
600         maBits &= 0xfc1f;
601         maBits |= (nVal & 0x1f) << 5;
602     }
SetStyleWW8_SHD603     void SetStyle(sal_uInt8 nVal)
604     {
605         maBits &= 0x03ff;
606         maBits |= (nVal & 0x3f) << 10;
607     }
608 };
609 
610 struct WW8_ANLV
611 {
612     sal_uInt8 nfc;          // 0        number format code, 0=Arabic, 1=Upper case Roman, 2=Lower case Roman
613                         //          3=Upper case Letter, 4=Lower case letter, 5=Ordinal
614     sal_uInt8 cbTextBefore; // 1        offset into anld.rgch limit of prefix text
615     sal_uInt8 cbTextAfter;  // 2
616     sal_uInt8 aBits1;
617 //  sal_uInt8 jc : 2;        // 3 : 0x03 justification code, 0=left, 1=center, 2=right, 3=left and right justify
618 //  sal_uInt8 fPrev : 1;     //     0x04 when ==1, include previous levels
619 //  sal_uInt8 fHang : 1;     //     0x08 when ==1, number will be displayed using a hanging indent
620 //  sal_uInt8 fSetBold : 1;  //     0x10 when ==1, boldness of number will be determined by anld.fBold.
621 //  sal_uInt8 fSetItalic : 1;//     0x20 when ==1, italicness of number will be determined by anld.fItalic
622 //  sal_uInt8 fSetSmallCaps : 1;//  0x40 when ==1, anld.fSmallCaps will determine whether number will be displayed in small caps or not.
623 //  sal_uInt8 fSetCaps : 1;  //     0x80 when ==1, anld.fCaps will determine whether number will be displayed capitalized or not
624     sal_uInt8 aBits2;
625 //  sal_uInt8 fSetStrike : 1;// 4 : 0x01 when ==1, anld.fStrike will determine whether the number will be displayed using strikethrough or not.
626 //  sal_uInt8 fSetKul : 1;   //     0x02 when ==1, anld.kul will determine the underlining state of the autonumber.
627 //  sal_uInt8 fPrevSpace : 1;//     0x04 when ==1, autonumber will be displayed with a single prefixing space character
628 //  sal_uInt8 fBold : 1;     //     0x08 determines boldness of autonumber when anld.fSetBold == 1.
629 //  sal_uInt8 fItalic : 1;   //     0x10 determines italicness of autonumber when anld.fSetItalic == 1.
630 //  sal_uInt8 fSmallCaps : 1;//     0x20 determines whether autonumber will be displayed using small caps when anld.fSetSmallCaps == 1.
631 //  sal_uInt8 fCaps : 1;     //     0x40 determines whether autonumber will be displayed using caps when anld.fSetCaps == 1.
632 //  sal_uInt8 fStrike : 1;   //     0x80 determines whether autonumber will be displayed using caps when anld.fSetStrike == 1.
633     sal_uInt8 aBits3;
634 //  sal_uInt8 kul : 3;       // 5 : 0x07 determines whether  autonumber will be displayed with underlining when anld.fSetKul == 1.
635 //  sal_uInt8 ico : 5;       //     0xF1 color of autonumber
636     SVBT16 ftc;         // 6        font code of  autonumber
637     SVBT16 hps;         // 8        font half point size (or 0=auto)
638     SVBT16 iStartAt;    // 0x0a     starting value (0 to 65535)
639     SVBT16 dxaIndent;   // 0x0c     *short?* *sal_uInt16?* width of prefix text (same as indent)
640     SVBT16 dxaSpace;    // 0x0e     minimum space between number and paragraph
641 };
642 // *cbANLV (count of bytes of ANLV) is 16 (decimal), 10(hex).
643 
644 struct WW8_ANLD
645 {
646     WW8_ANLV eAnlv;     // 0
647     sal_uInt8 fNumber1;     // 0x10     number only 1 item per table cell
648     sal_uInt8 fNumberAcross;    // 0x11     number across cells in table rows(instead of down)
649     sal_uInt8 fRestartHdn;  // 0x12     restart heading number on section boundary
650     sal_uInt8 fSpareX;      // 0x13     unused( should be 0)
651     sal_uInt8 rgchAnld[32]; // 0x14 characters displayed before/after autonumber
652 };
653 
654 struct WW8_OLST
655 {
656     WW8_ANLV rganlv[9]; // 0    an array of 9 ANLV structures (heading levels)
657     sal_uInt8 fRestartHdr;  // 0x90 when ==1, restart heading on section break
658     sal_uInt8 fSpareOlst2;  // 0x91 reserved
659     sal_uInt8 fSpareOlst3;  // 0x92 reserved
660     sal_uInt8 fSpareOlst4;  // 0x93 reserved
661     sal_uInt8 rgch[64];      // 0x94 array of 64 chars       text before/after number
662 };
663 // cbOLST is 212(decimal), D4(hex).
664 
665 struct WW8_FDOA
666 {
667     SVBT32 fc;          // 0  FC pointing to drawing object data
668     SVBT16 ctxbx;       // 4  count of textboxes in the drawing object
669 };
670 
671 struct WW8_DO
672 {
673     SVBT16 dok;             // 0    Drawn Object Kind, currently this is always 0
674     SVBT16 cb;              // 2    size (count of bytes) of the entire DO
675     sal_uInt8  bx;              // 4    x position relative to anchor CP
676     sal_uInt8  by;              // 5    y position relative to anchor CP
677 
678     /*
679      bx and by above are apparently better described by this info from the rtf standard...
680 
681     \dobxpage   The drawing object is page relative in the x-direction.
682     \dobxcolumn The drawing object is column relative in the x-direction.
683     \dobxmargin The drawing object is margin relative in the x-direction.
684 
685     \dobypage   The drawing object is page relative in the y-direction.
686     \dobypara   The drawing object is paragraph relative in the y-direction.
687     \dobymargin The drawing object is margin relative in the y-direction.
688 
689     */
690 
691     SVBT16 dhgt;                // 6    height of DO
692     SVBT16 aBits1;
693 //  sal_uInt16 fAnchorLock : 1; // 8    1 if the DO anchor is locked
694 //  sal_uInt8[] rgdp;            // 0xa  variable length array of drawing primitives
695 };
696 
697 struct WW8_DPHEAD
698 {
699     SVBT16 dpk;         //  0   Drawn Primitive Kind  REVIEW davebu
700   //        0=start of grouping, 1=line, 2=textbox, 3=rectangle,
701   //        4=arc, 5=elipse, 6=polyline, 7=callout textbox,
702   //        8=end of grouping, 9=sample primitive holding default values
703     SVBT16 cb;          // 2    size (count of bytes) of this DP
704     SVBT16 xa;          // 4    These 2 points describe the rectangle
705     SVBT16 ya;          // 6    enclosing this DP relative to the origin of
706     SVBT16 dxa;         // 8    the DO
707     SVBT16 dya;         // 0xa
708 };
709 
710 struct WW8_DP_LINETYPE
711 {
712     SVBT32 lnpc;            // LiNe Property Color -- RGB color value
713     SVBT16 lnpw;            // line property weight in twips
714     SVBT16 lnps;            // line property style : 0=Solid, 1=Dashed
715                             // 2=Dotted, 3=Dash Dot, 4=Dash Dot Dot, 5=Hollow
716 };
717 
718 struct WW8_DP_SHADOW    // shading!
719 {
720     SVBT16 shdwpi;          // Shadow Property Intensity
721     SVBT16 xaOffset;        // x offset of shadow
722     SVBT16 yaOffset;        // y offset of shadow
723 };
724 
725 struct WW8_DP_FILL
726 {
727     SVBT32 dlpcFg;          // FiLl Property Color ForeGround -- RGB color value
728     SVBT32 dlpcBg;          // Property Color BackGround -- RGB color value
729     SVBT16 flpp;            // FiLl Property Pattern REVIEW davebu
730 };
731 
732 struct WW8_DP_LINEEND
733 {
734     SVBT16 aStartBits;
735 //  sal_uInt16 eppsStart : 2;   // Start EndPoint Property Style
736                             // 0=None, 1=Hollow, 2=Filled
737 //  sal_uInt16 eppwStart : 2;   // Start EndPoint Property Weight
738 //  sal_uInt16 epplStart : 2;   // Start EndPoint Property length
739 //  sal_uInt16 dummyStart : 10; // Alignment
740     SVBT16 aEndBits;
741 //  sal_uInt16 eppsEnd : 2;     // End EndPoint Property Style
742 //  sal_uInt16 eppwEnd : 2;     // End EndPoint Property Weight
743 //  sal_uInt16 epplEnd : 2;     // End EndPoint Property length
744 //  sal_uInt16 dummyEnd : 10;   // Alignment
745 };
746 
747 struct WW8_DP_LINE
748 {
749 //  WW8_DPHEAD dphead;      // 0    Common header for a drawing primitive
750     SVBT16 xaStart;         // starting point for line
751     SVBT16 yaStart;
752     SVBT16 xaEnd;           // ending point for line
753     SVBT16 yaEnd;
754     WW8_DP_LINETYPE aLnt;
755     WW8_DP_LINEEND aEpp;
756     WW8_DP_SHADOW aShd;
757 };
758 
759 struct WW8_DP_TXTBOX
760 {
761     WW8_DP_LINETYPE aLnt;
762     WW8_DP_FILL aFill;
763     WW8_DP_SHADOW aShd;
764     SVBT16 aBits1;
765 //  sal_uInt16 fRoundCorners : 1; //0x24    0001    1 if the textbox has rounded corners
766 //  sal_uInt16 zaShape : 15;    // 0x24     000e    REVIEW davebu
767     SVBT16 dzaInternalMargin; // 0x26   REVIEW davebu
768 };
769 
770 struct WW8_DP_RECT
771 {
772     WW8_DP_LINETYPE aLnt;
773     WW8_DP_FILL aFill;
774     WW8_DP_SHADOW aShd;
775     SVBT16 aBits1;
776 //  sal_uInt16 fRoundCorners : 1; // 0x24   0001    1 if the textbox has rounded corners
777 //  sal_uInt16 zaShape : 15; // 0x24 000e   REVIEW davebu
778 };
779 
780 struct WW8_DP_ARC
781 {
782     WW8_DP_LINETYPE aLnt;
783     WW8_DP_FILL aFill;
784     WW8_DP_SHADOW aShd;
785     sal_uInt8 fLeft;        // 0x24 00ff    REVIEW davebu
786     sal_uInt8 fUp;          // 0x24 ff00    REVIEW davebu
787 //  sal_uInt16 fLeft : 8;   // 0x24 00ff    REVIEW davebu
788 //  sal_uInt16 fUp : 8;     // 0x24 ff00    REVIEW davebu
789 };
790 
791 struct WW8_DP_ELIPSE
792 {
793     WW8_DP_LINETYPE aLnt;
794     WW8_DP_FILL aFill;
795     WW8_DP_SHADOW aShd;
796 };
797 
798 struct WW8_DP_POLYLINE
799 {
800     WW8_DP_LINETYPE aLnt;
801     WW8_DP_FILL aFill;
802     WW8_DP_LINEEND aEpp;
803     WW8_DP_SHADOW aShd;
804     SVBT16 aBits1;
805 //  sal_uInt16 fPolygon : 1; // 0x28  0001  1 if this is a polygon
806 //  sal_uInt16 cpt : 15;    // 0x28   00fe  count of points
807 //  short xaFirst;      // 0x2a These are the endpoints of the first line.
808 //  short yaFirst;      // 0x2c
809 //  short xaEnd;        // 0x2e
810 //  short yaEnd;        // 0x30
811 //  short rgpta[];      // 0x32 An array of xa,ya pairs for the remaining points
812 };
813 
814 struct WW8_DP_CALLOUT_TXTBOX
815 {
816     SVBT16 flags;               // 0x0c REVIEW davebu flags
817     SVBT16 dzaOffset;           // 0x0e REVIEW davebu
818     SVBT16 dzaDescent;          // 0x10 REVIEW davebu
819     SVBT16 dzaLength;           // 0x12 REVIEW davebu
820     WW8_DPHEAD dpheadTxbx;      // 0x14 DPHEAD for a textbox
821     WW8_DP_TXTBOX dptxbx;       // 0x20 DP for a textbox
822     WW8_DPHEAD dpheadPolyLine;  // 0x4c DPHEAD for a Polyline
823     WW8_DP_POLYLINE dpPolyLine; // 0x48 DP for a polyline
824 };
825 
826 struct WW8_PCD
827 {
828     sal_uInt8 aBits1;
829 //  sal_uInt8 fNoParaLast : 1;   // when 1, means that piece contains no end of paragraph marks.
830 //  sal_uInt8 fPaphNil : 1;      // used internally by Word
831 //  sal_uInt8 fCopied : 1;       // used internally by Word
832 //          *   int :5
833     sal_uInt8 aBits2;           // fn int:8, used internally by Word
834     SVBT32 fc;              // file offset of beginning of piece. The size of the
835                             // ithpiece can be determined by subtracting rgcp[i] of
836                             // the containing plcfpcd from its rgcp[i+1].
837     SVBT16 prm;             // PRM contains either a single sprm or else an index number
838                             // of the grpprl which contains the sprms that modify the
839                             // properties of the piece.
840 };
841 
842 // AnnoTation References Descriptor (ATRD)
843 struct WW8_ATRD                 // for version 8
844 {
845     SVBT16 xstUsrInitl[ 10 ];       // pascal-style String holding initials
846                                     // of annotation author
847     SVBT16 ibst;                    // index into GrpXstAtnOwners
848     SVBT16 ak;                      // not used
849     SVBT16 grfbmc;                  // not used
850     SVBT32 ITagBkmk;                // when not -1, this tag identifies the
851                                     // annotation bookmark that locates the
852                                     // range of CPs in the main document which
853                                     // this annotation references.
854 };
855 
856 struct WW8_ATRDEXTRA
857 {
858     // ---  Extended bit since Word 2002 ---
859 
860     SVBT32 dttm;
861     SVBT16 bf;
862     SVBT32 cDepth;
863     SVBT32 diatrdParent;
864     SVBT32 Discussitem;
865 };
866 
867 struct WW67_ATRD                // for versions 6/7
868 {
869     sal_Char xstUsrInitl[ 10 ];     // pascal-style String holding initials
870                                     // of annotation author
871     SVBT16 ibst;                    // index into GrpXstAtnOwners
872     SVBT16 ak;                      // not used
873     SVBT16 grfbmc;                  // not used
874     SVBT32 ITagBkmk;                // when not -1, this tag identifies the
875                                     // annotation bookmark that locates the
876                                     // range of CPs in the main document which
877                                     // this annotation references.
878 };
879 
880 struct WW8_TablePos
881 {
882     sal_Int16 nSp26;
883     sal_Int16 nSp27;
884     sal_Int16 nLeMgn;
885     sal_Int16 nRiMgn;
886     sal_Int16 nUpMgn;
887     sal_Int16 nLoMgn;
888     sal_uInt8 nSp29;
889     sal_uInt8 nSp37;
890     bool bNoFly;
891 };
892 
893 struct WW8_FSPA
894 {
895 public:
896     sal_Int32 nSpId;     //Shape Identifier. Used in conjunction with the office art data (found via fcDggInfo in the FIB) to find the actual data for this shape.
897     sal_Int32 nXaLeft;   //left of rectangle enclosing shape relative to the origin of the shape
898     sal_Int32 nYaTop;        //top of rectangle enclosing shape relative to the origin of the shape
899     sal_Int32 nXaRight;  //right of rectangle enclosing shape relative to the origin of the shape
900     sal_Int32 nYaBottom;//bottom of the rectangle enclosing shape relative to the origin of the shape
901     sal_uInt16 bHdr:1;
902     //0001 1 in the undo doc when shape is from the header doc, 0 otherwise (undefined when not in the undo doc)
903     sal_uInt16 nbx:2;
904     //0006 x position of shape relative to anchor CP
905     //0 relative to page margin
906     //1 relative to top of page
907     //2 relative to text (column for horizontal text; paragraph for vertical text)
908     //3 reserved for future use
909     sal_uInt16 nby:2;
910     //0018 y position of shape relative to anchor CP
911     //0 relative to page margin
912     //1 relative to top of page
913     //2 relative to text (paragraph for horizontal text; column for vertical text)
914     sal_uInt16 nwr:4;
915     //01E0 text wrapping mode
916     //0 like 2, but doesn't require absolute object
917     //1 no text next to shape
918     //2 wrap around absolute object
919     //3 wrap as if no object present
920     //4 wrap tightly around object
921     //5 wrap tightly, but allow holes
922     //6-15 reserved for future use
923     sal_uInt16 nwrk:4;
924     //1E00 text wrapping mode type (valid only for wrapping modes 2 and 4
925     //0 wrap both sides
926     //1 wrap only on left
927     //2 wrap only on right
928     //3 wrap only on largest side
929     sal_uInt16 bRcaSimple:1;
930     //2000 when set, temporarily overrides bx, by, forcing the xaLeft, xaRight, yaTop, and yaBottom fields to all be page relative.
931     sal_uInt16 bBelowText:1;
932     //4000
933     //1 shape is below text
934     //0 shape is above text
935     sal_uInt16 bAnchorLock:1;
936     //8000  1 anchor is locked
937     //      0 anchor is not locked
938     sal_Int32 nTxbx; //count of textboxes in shape (undo doc only)
939 public:
940     enum FSPAOrient {RelPgMargin, RelPageBorder, RelText};
941 };
942 
943 struct WW8_FSPA_SHADOW  // all members at same position and size
944 {                                               // due to:  pF = (WW8_FSPA*)pFS;
945     SVBT32 nSpId;
946     SVBT32 nXaLeft;
947     SVBT32 nYaTop;
948     SVBT32 nXaRight;
949     SVBT32 nYaBottom;
950     SVBT16 aBits1;
951     SVBT32 nTxbx;
952 };
953 
954 static_assert(sizeof (WW8_FSPA_SHADOW) == 26, "this has to match the msword size");
955     // "26": cf. WW8ScannerBase ctor case 8 creation of pMainFdoa and pHdFtFdoa
956 
957 struct WW8_TXBXS
958 {
959     SVBT32 cTxbx_iNextReuse;
960     SVBT32 cReusable;
961     SVBT16 fReusable;
962     SVBT32 reserved;
963     SVBT32 ShapeId;
964     SVBT32 txidUndo;
965 };
966 
967 struct WW8_STRINGID
968 {
969     // M.M. This is the extra data stored in the SttbfFnm
970     // For now I only need the String Id
971     SVBT16 nStringId;
972     SVBT16 reserved1;
973     SVBT16 reserved2;
974     SVBT16 reserved3;
975 };
976 
977 struct WW8_WKB
978 {
979     // M.M. This is the WkbPLCF struct
980     // For now I only need the Link Id
981     SVBT16 reserved1;
982     SVBT16 reserved2;
983     SVBT16 reserved3;
984     SVBT16 nLinkId;
985     SVBT16 reserved4;
986     SVBT16 reserved5;
987 };
988 
989 #ifdef _WIN32
990 #   pragma pack(pop)
991 #endif
992 
993 // Maximum number of columns according the WW8 specification
994 static const sal_uInt8 MAX_NO_OF_SEP_COLUMNS = 44;
995 
996 struct SEPr
997 {
998     SEPr();
999     sal_uInt8 bkc;
1000     sal_uInt8 fTitlePage;
1001     sal_Int8 fAutoPgn;
1002     sal_uInt8 nfcPgn;
1003     sal_uInt8 fUnlocked;
1004     sal_uInt8 cnsPgn;
1005     sal_uInt8 fPgnRestart;
1006     sal_uInt8 fEndNote;
1007     sal_Int8 lnc;
1008     sal_Int8 grpfIhdt;
1009     sal_uInt16 nLnnMod;
1010     sal_Int32 dxaLnn;
1011     sal_Int16 dxaPgn;
1012     sal_Int16 dyaPgn;
1013     sal_Int8 fLBetween;
1014     sal_Int8 vjc;
1015     sal_uInt16 dmBinFirst;
1016     sal_uInt16 dmBinOther;
1017     sal_uInt16 dmPaperReq;
1018 /*
1019     28  1C  brcTop                    BRC                   top page border
1020 
1021     32  20  brcLeft                   BRC                   left page border
1022 
1023     36  24  brcBottom                 BRC                   bottom page border
1024 
1025     40  28  brcRight                  BRC                   right page border
1026 */
1027     sal_Int16 fPropRMark;
1028     sal_Int16 ibstPropRMark;
1029     sal_Int32 dttmPropRMark;        //DTTM
1030     sal_Int32 dxtCharSpace;
1031     sal_Int32 dyaLinePitch;
1032     sal_uInt16 clm;
1033     sal_Int16 reserved1;
1034     sal_uInt8 dmOrientPage;
1035     sal_uInt8 iHeadingPgn;
1036     sal_uInt16 pgnStart;
1037     sal_Int16 lnnMin;
1038     sal_uInt16 wTextFlow;
1039     sal_Int16 reserved2;
1040     sal_uInt16 pgbApplyTo:3;
1041     sal_uInt16 pgbPageDepth:2;
1042     sal_Int16 pgbOffsetFrom:3;
1043     sal_Int16 :8;
1044     sal_uInt32 xaPage;
1045     sal_uInt32 yaPage;
1046     sal_uInt32 xaPageNUp;
1047     sal_uInt32 yaPageNUp;
1048     sal_uInt32 dxaLeft;
1049     sal_uInt32 dxaRight;
1050     sal_Int32 dyaTop;
1051     sal_Int32 dyaBottom;
1052     sal_uInt32 dzaGutter;
1053     sal_uInt32 dyaHdrTop;
1054     sal_uInt32 dyaHdrBottom;
1055     sal_Int16 ccolM1;   // have to be less than MAX_NO_OF_SEP_COLUMNS according the WW8 specification
1056     sal_Int8 fEvenlySpaced;
1057     sal_Int8 reserved3;
1058     sal_uInt8 fBiDi;
1059     sal_uInt8 fFacingCol;
1060     sal_uInt8 fRTLGutter;
1061     sal_uInt8 fRTLAlignment;
1062     sal_Int32 dxaColumns;
1063 
1064     // Fixed array - two entries for each SEP column to store width of column and spacing to next column.
1065     // At odd index values [1,3,5,...] the column widths are stored.
1066     // At even index values [2,4,6,...] the spacings to the next columns are stored.
1067     // Value at index 0 is initialized with 0 and used for easier iteration on the array
1068     sal_Int32 rgdxaColumnWidthSpacing[MAX_NO_OF_SEP_COLUMNS*2 + 1] = {};
1069 
1070     sal_Int32 dxaColumnWidth;
1071     sal_uInt8 dmOrientFirst;
1072     sal_uInt8 fLayout;
1073     sal_Int16 reserved4;
1074 };
1075 
1076 namespace wwUtility
1077 {
RGBToBGR(::Color nColour)1078     inline sal_uInt32 RGBToBGR(::Color nColour)
1079     {
1080         // we can use this because the translation is symmetric
1081         return msfilter::util::BGRToRGB(sal_uInt32(nColour));
1082     }
1083 }
1084 
1085 /// [MS-OSHARED] FactoidType: one smart tag type.
1086 class MSOFactoidType
1087 {
1088 public:
1089     MSOFactoidType();
1090     void Read(SvStream& rStream);
1091     void Write(WW8Export& rExport);
1092 
1093     sal_uInt32 m_nId;
1094     OUString m_aUri;
1095     OUString m_aTag;
1096 };
1097 
1098 /// [MS-OSHARED] PropertyBagStore: smart tag types and string store.
1099 class MSOPropertyBagStore
1100 {
1101 public:
1102     void Read(SvStream& rStream);
1103     void Write(WW8Export& rExport);
1104 
1105     std::vector<MSOFactoidType> m_aFactoidTypes;
1106     std::vector<OUString> m_aStringTable;
1107 };
1108 
1109 /// [MS-OSHARED] Property: stores information about one smart-tag key/value.
1110 class MSOProperty
1111 {
1112 public:
1113     MSOProperty();
1114     void Read(SvStream& rStream);
1115     void Write(SvStream& rStream);
1116 
1117     /// Index into MSOPropertyBagStore::m_aStringTable.
1118     sal_uInt32 m_nKey;
1119     /// Index into MSOPropertyBagStore::m_aStringTable.
1120     sal_uInt32 m_nValue;
1121 };
1122 
1123 /// [MS-OSHARED] PropertyBag: stores information about one smart tag.
1124 class MSOPropertyBag
1125 {
1126 public:
1127     MSOPropertyBag();
1128     bool Read(SvStream& rStream);
1129     void Write(WW8Export& rExport);
1130 
1131     /// Matches MSOFactoidType::m_nId in MSOPropertyBagStore::m_aFactoidTypes.
1132     sal_uInt16 m_nId;
1133     std::vector<MSOProperty> m_aProperties;
1134 };
1135 
1136 /// [MS-DOC] SmartTagData: stores information about all smart tags in the document.
1137 class WW8SmartTagData
1138 {
1139 public:
1140     void Read(SvStream& rStream, WW8_FC fcFactoidData, sal_uInt32 lcbFactoidData);
1141     void Write(WW8Export& rExport);
1142 
1143     MSOPropertyBagStore m_aPropBagStore;
1144     std::vector<MSOPropertyBag> m_aPropBags;
1145 };
1146 
1147 #endif
1148 
1149 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
1150