xref: /trunk/main/sw/source/filter/ww8/ww8par6.cxx (revision 870262e3)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_sw.hxx"
26 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil -*- */
27 #include <stdlib.h>
28 #include <svl/itemiter.hxx>
29 #include <rtl/tencinfo.h>
30 
31 
32 #include <hintids.hxx>
33 #include <editeng/lspcitem.hxx>
34 #include <editeng/wrlmitem.hxx>
35 #include <editeng/udlnitem.hxx>
36 #include <editeng/kernitem.hxx>
37 #include <editeng/langitem.hxx>
38 #include <editeng/cmapitem.hxx>
39 #include <editeng/shdditem.hxx>
40 #include <editeng/cntritem.hxx>
41 #include <editeng/crsditem.hxx>
42 #include <editeng/postitem.hxx>
43 #include <editeng/wghtitem.hxx>
44 #include <editeng/adjitem.hxx>
45 #include <editeng/colritem.hxx>
46 #include <editeng/brshitem.hxx>
47 #include <editeng/spltitem.hxx>
48 #include <editeng/keepitem.hxx>
49 #include <editeng/orphitem.hxx>
50 #include <editeng/widwitem.hxx>
51 #include <editeng/adjitem.hxx>
52 #include <editeng/escpitem.hxx>
53 #include <editeng/fhgtitem.hxx>
54 #include <editeng/fontitem.hxx>
55 #include <editeng/shaditem.hxx>
56 #include <editeng/boxitem.hxx>
57 #include <editeng/ulspitem.hxx>
58 #include <editeng/lrspitem.hxx>
59 #include <editeng/tstpitem.hxx>
60 #include <editeng/akrnitem.hxx>
61 #include <editeng/paperinf.hxx>
62 #include <editeng/emphitem.hxx>
63 #include <editeng/forbiddenruleitem.hxx>
64 #include <editeng/twolinesitem.hxx>
65 #include <editeng/scriptspaceitem.hxx>
66 #include <editeng/hngpnctitem.hxx>
67 #include <editeng/pbinitem.hxx>
68 #include <editeng/charscaleitem.hxx>
69 #include <editeng/charrotateitem.hxx>
70 #include <editeng/charreliefitem.hxx>
71 #include <editeng/blnkitem.hxx>
72 #include <editeng/hyznitem.hxx>
73 #include <editeng/paravertalignitem.hxx>
74 #include <editeng/pgrditem.hxx>
75 #include <editeng/frmdiritem.hxx>
76 #include <editeng/charhiddenitem.hxx>
77 #include <fmtpdsc.hxx>
78 #include <node.hxx>
79 #include <ndtxt.hxx> // SwTxtNode, siehe unten: JoinNode()
80 #include <pam.hxx>              // fuer SwPam
81 #include <doc.hxx>
82 #include <pagedesc.hxx>         // class SwPageDesc
83 #include <fmtanchr.hxx>
84 #include <fmtcntnt.hxx>
85 #include <fchrfmt.hxx>
86 #include <fmthdft.hxx>
87 #include <fmtclds.hxx>
88 #include <fmtftntx.hxx>
89 #include <frmatr.hxx>
90 #include <section.hxx>
91 #include <lineinfo.hxx>
92 #include <fmtline.hxx>
93 #include <txatbase.hxx>
94 #include <fmtflcnt.hxx>
95 #include <fmtclbl.hxx>
96 #include <tgrditem.hxx>
97 #include <hfspacingitem.hxx>
98 #include <swtable.hxx>
99 #include <fltini.hxx>   //For CalculateFlySize
100 #include "writerhelper.hxx"
101 #include "writerwordglue.hxx"
102 #include "ww8scan.hxx"
103 #include "ww8par2.hxx"          // class WW8RStyle, class WwAnchorPara
104 #include "ww8graf.hxx"
105 
106 // OD 2004-05-18 #i27767#
107 #include <fmtwrapinfluenceonobjpos.hxx>
108 
109 using namespace sw::util;
110 using namespace sw::types;
111 using namespace ::com::sun::star;
112 using namespace nsHdFtFlags;
113 
114 //-----------------------------------------
115 //              diverses
116 //-----------------------------------------
117 
118 #define MM_250 1417             // WW-Default fuer Hor. Seitenraender: 2.5 cm
119 #define MM_200 1134             // WW-Default fuer u.Seitenrand: 2.0 cm
120 
121 
122 sal_uInt8 lcl_ReadBorders(bool bVer67, WW8_BRC* brc, WW8PLCFx_Cp_FKP* pPap,
123     const WW8RStyle* pSty = 0, const WW8PLCFx_SEPX* pSep = 0);
124 
125 
GetCol(sal_uInt8 nIco)126 ColorData SwWW8ImplReader::GetCol(sal_uInt8 nIco)
127 {
128     static const ColorData eSwWW8ColA[] =
129     {
130         COL_AUTO, COL_BLACK, COL_LIGHTBLUE, COL_LIGHTCYAN, COL_LIGHTGREEN,
131         COL_LIGHTMAGENTA, COL_LIGHTRED, COL_YELLOW, COL_WHITE, COL_BLUE,
132         COL_CYAN, COL_GREEN, COL_MAGENTA, COL_RED, COL_BROWN, COL_GRAY,
133         COL_LIGHTGRAY
134     };
135 
136     return eSwWW8ColA[nIco];
137 }
138 
MSRoundTweak(sal_uInt32 x)139 inline sal_uInt32 MSRoundTweak(sal_uInt32 x)
140 {
141     return x;
142 }
143 
144 /***************************************************************************
145 #  Seiten - Attribute, die nicht ueber die Attribut-Verwaltung, sondern
146 #   ueber ...->HasSprm abgearbeitet werden
147 #   ( ausser OLST, dass weiterhin ein normales Attribut ist )
148 #**************************************************************************/
149 
ReadSprm(const WW8PLCFx_SEPX * pSep,sal_uInt16 nId,short nDefaultVal)150 static short ReadSprm( const WW8PLCFx_SEPX* pSep, sal_uInt16 nId, short nDefaultVal )
151 {
152     const sal_uInt8* pS = pSep->HasSprm( nId );          // sprm da ?
153     short nVal = ( pS ) ? SVBT16ToShort( pS ) : nDefaultVal;
154     return nVal;
155 }
156 
ReadUSprm(const WW8PLCFx_SEPX * pSep,sal_uInt16 nId,short nDefaultVal)157 static sal_uInt16 ReadUSprm( const WW8PLCFx_SEPX* pSep, sal_uInt16 nId, short nDefaultVal )
158 {
159     const sal_uInt8* pS = pSep->HasSprm( nId );          // sprm da ?
160     sal_uInt16 nVal = ( pS ) ? SVBT16ToShort( pS ) : nDefaultVal;
161     return nVal;
162 }
163 
ReadBSprm(const WW8PLCFx_SEPX * pSep,sal_uInt16 nId,sal_uInt8 nDefaultVal)164 static sal_uInt8 ReadBSprm( const WW8PLCFx_SEPX* pSep, sal_uInt16 nId, sal_uInt8 nDefaultVal )
165 {
166     const sal_uInt8* pS = pSep->HasSprm( nId );          // sprm da ?
167     sal_uInt8 nVal = ( pS ) ? SVBT8ToByte( pS ) : nDefaultVal;
168     return nVal;
169 }
170 
SetDirection()171 void wwSection::SetDirection()
172 {
173     //sprmSTextFlow
174     switch (maSep.wTextFlow)
175     {
176         default:
177             ASSERT(sal_False, "Unknown layout type");
178         case 0:
179             meDir=FRMDIR_HORI_LEFT_TOP;
180             break;
181         case 1:
182             meDir=FRMDIR_VERT_TOP_RIGHT;
183             break;
184         case 2:
185             //asian letters are not rotated, western are. We can't import
186             //bottom to top going left to right, we can't do this in
187             //pages, (in drawboxes we could partly hack it with a rotated
188             //drawing box, though not frame)
189             meDir=FRMDIR_VERT_TOP_RIGHT;
190             break;
191         case 3:
192             //asian letters are not rotated, western are. We can't import
193             meDir=FRMDIR_VERT_TOP_RIGHT;
194             break;
195         case 4:
196             //asian letters are rotated, western not. We can't import
197             meDir=FRMDIR_HORI_LEFT_TOP;
198             break;
199     }
200 
201     sal_uInt8 nRTLPgn = maSep.fBiDi;
202     if ((meDir == FRMDIR_HORI_LEFT_TOP) && nRTLPgn)
203         meDir = FRMDIR_HORI_RIGHT_TOP;
204 }
205 
IsVertical() const206 bool wwSection::IsVertical() const
207 {
208     if (meDir == FRMDIR_VERT_TOP_RIGHT || meDir == FRMDIR_VERT_TOP_LEFT)
209         return true;
210     return false;
211 }
212 
213 /*
214   #113694#
215   This is something of festering mapping, I'm open to better ways of doing it,
216   but primarily the grid in writer is different to that in word. In writer the
217   grid elements are squares with ruby rows inbetween. While in word there is no
218   ruby stuff, and the elements are rectangles. By misusing the ruby row I can
219   handle distortions in one direction, but its all a bit of a mess:
220 */
SetDocumentGrid(SwFrmFmt & rFmt,const wwSection & rSection)221 void SwWW8ImplReader::SetDocumentGrid(SwFrmFmt &rFmt, const wwSection &rSection)
222 {
223     if (bVer67)
224         return;
225 
226     rFmt.SetFmtAttr(SvxFrameDirectionItem(rSection.meDir, RES_FRAMEDIR));
227 
228     SwTwips nTextareaHeight = rFmt.GetFrmSize().GetHeight();
229     const SvxULSpaceItem &rUL = ItemGet<SvxULSpaceItem>(rFmt, RES_UL_SPACE);
230     nTextareaHeight -= rUL.GetUpper();
231     nTextareaHeight -= rUL.GetLower();
232 
233     SwTextGridItem aGrid;
234     aGrid.SetDisplayGrid(false);
235     aGrid.SetPrintGrid(false);
236     SwTextGrid eType=GRID_NONE;
237 
238     switch (rSection.maSep.clm)
239     {
240         case 0:
241             eType = GRID_NONE;
242             break;
243         default:
244             ASSERT(sal_False, "Unknown grid type");
245         case 3:
246             eType = GRID_LINES_CHARS;
247 			aGrid.SetSnapToChars(sal_True);
248             break;
249         case 1:
250             eType = GRID_LINES_CHARS;
251 			aGrid.SetSnapToChars(sal_False);
252             break;
253         case 2:
254             eType = GRID_LINES_ONLY;
255             break;
256     }
257 
258     aGrid.SetGridType(eType);
259 
260     // seem to not add external leading in word, or the character would run across
261     // two line in some cases.
262     if (eType != GRID_NONE)
263         rDoc.set(IDocumentSettingAccess::ADD_EXT_LEADING, false);
264 
265    //force to set document as standard page mode
266     sal_Bool bSquaredMode = sal_False;
267     rDoc.SetDefaultPageMode( bSquaredMode );
268     aGrid.SetSquaredMode( bSquaredMode );
269 
270     if ( eType != GRID_NONE )
271     {
272 
273         //sep.dyaLinePitch
274         const sal_Int32 nLinePitch = rSection.maSep.dyaLinePitch;
275 
276         //Get the size of word's default styles font
277         sal_uInt32 nCharWidth=240;
278         for (sal_uInt16 nI = 0; nI < pStyles->GetCount(); ++nI)
279         {
280             if (pCollA[nI].bValid
281                 && pCollA[nI].pFmt != NULL
282                 && pCollA[nI].IsWW8BuiltInDefaultStyle())
283             {
284                 nCharWidth = ItemGet<SvxFontHeightItem>(*(pCollA[nI].pFmt),
285                     RES_CHRATR_CJK_FONTSIZE).GetHeight();
286                 break;
287             }
288         }
289 
290         //dxtCharSpace
291         if (rSection.maSep.dxtCharSpace)
292         {
293             sal_uInt32 nCharSpace = rSection.maSep.dxtCharSpace;
294             //main lives in top 20 bits, and is signed.
295             sal_Int32 nMain = (nCharSpace & 0xFFFFF000);
296             nMain/=0x1000;
297             nCharWidth += nMain*20;
298 
299             int nFraction = (nCharSpace & 0x00000FFF);
300             nFraction = (nFraction*20)/0xFFF;
301             nCharWidth += nFraction;
302         }
303 
304         SwTwips nTextareaWidth = rFmt.GetFrmSize().GetWidth();
305         {
306             const SvxLRSpaceItem &rLR = ItemGet<SvxLRSpaceItem>(rFmt, RES_LR_SPACE);
307             nTextareaWidth -= rLR.GetLeft();
308             nTextareaWidth -= rLR.GetRight();
309 
310             if (rSection.IsVertical())
311                 std::swap(nTextareaHeight, nTextareaWidth);
312         }
313 
314         // only apply sensible grid property values
315         if ( nLinePitch > 0
316              && nCharWidth > 0
317              && nTextareaHeight > nLinePitch )
318         {
319             aGrid.SetBaseWidth( writer_cast<sal_uInt16>(nCharWidth));
320             aGrid.SetLines(writer_cast<sal_uInt16>(nTextareaHeight/nLinePitch));
321             aGrid.SetBaseHeight(writer_cast<sal_uInt16>(nLinePitch));
322         }
323 
324         // ruby height is not supported in ww8
325         //sal_Int32 nRubyHeight = nLinePitch - nCharWidth;
326         //if (nRubyHeight < 0)
327         //    nRubyHeight = 0;
328         sal_Int32 nRubyHeight = 0;
329         aGrid.SetRubyHeight(writer_cast<sal_uInt16>(nRubyHeight));
330     }
331 
332     rFmt.SetFmtAttr(aGrid);
333 }
334 
Read_ParaBiDi(sal_uInt16,const sal_uInt8 * pData,short nLen)335 void SwWW8ImplReader::Read_ParaBiDi(sal_uInt16, const sal_uInt8* pData, short nLen)
336 {
337     if( nLen < 0 )
338         pCtrlStck->SetAttr(*pPaM->GetPoint(), RES_FRAMEDIR);
339     else
340     {
341         SvxFrameDirection eDir =
342             *pData ? FRMDIR_HORI_RIGHT_TOP : FRMDIR_HORI_LEFT_TOP;
343         NewAttr(SvxFrameDirectionItem(eDir, RES_FRAMEDIR));
344     }
345 }
346 
SetCols(SwFrmFmt & rFmt,const wwSection & rSection,sal_uInt32 nNettoWidth) const347 bool wwSectionManager::SetCols(SwFrmFmt &rFmt, const wwSection &rSection,
348     sal_uInt32 nNettoWidth) const
349 {
350     //sprmSCcolumns - Anzahl der Spalten - 1
351     sal_Int16 nCols = rSection.NoCols();
352 
353     if (nCols < 2)
354         return false;                   // keine oder bloedsinnige Spalten
355 
356     SwFmtCol aCol;                      // Erzeuge SwFmtCol
357 
358     //sprmSDxaColumns   - Default-Abstand 1.25 cm
359     sal_Int32 nColSpace = rSection.StandardColSeperation();
360 
361     // sprmSLBetween
362     if (rSection.maSep.fLBetween)
363     {
364         aCol.SetLineAdj(COLADJ_TOP);      // Line
365         aCol.SetLineHeight(100);
366         aCol.SetLineColor(Color(COL_BLACK));
367         aCol.SetLineWidth(1);
368     }
369 
370     aCol.Init(nCols, writer_cast<sal_uInt16>(nColSpace),
371         writer_cast<sal_uInt16>(nNettoWidth));
372 
373     // sprmSFEvenlySpaced
374     if (!rSection.maSep.fEvenlySpaced)
375     {
376         aCol._SetOrtho(false);
377         int nIdx = 1;
378         for (sal_uInt16 i = 0; i < nCols; i++ )
379         {
380             SwColumn* pCol = aCol.GetColumns()[i];
381             sal_Int32 nLeft = rSection.maSep.rgdxaColumnWidthSpacing[nIdx-1]/2;
382             sal_Int32 nRight = rSection.maSep.rgdxaColumnWidthSpacing[nIdx+1]/2;
383             sal_Int32 nWishWidth = rSection.maSep.rgdxaColumnWidthSpacing[nIdx]
384                 + nLeft + nRight;
385             pCol->SetWishWidth(writer_cast<sal_uInt16>(nWishWidth));
386             pCol->SetLeft(writer_cast<sal_uInt16>(nLeft));
387             pCol->SetRight(writer_cast<sal_uInt16>(nRight));
388             nIdx += 2;
389         }
390         aCol.SetWishWidth(writer_cast<sal_uInt16>(nNettoWidth));
391     }
392     rFmt.SetFmtAttr(aCol);
393     return true;
394 }
395 
SetLeftRight(wwSection & rSection)396 void wwSectionManager::SetLeftRight(wwSection &rSection)
397 {
398     // 3. LR-Raender
399     sal_uInt32 nWWLe = MSRoundTweak(rSection.maSep.dxaLeft);
400     sal_uInt32 nWWRi = MSRoundTweak(rSection.maSep.dxaRight);
401     sal_uInt32 nWWGu = rSection.maSep.dzaGutter;
402 
403     /*
404     fRTLGutter is set if the gutter is on the right, the gutter is otherwise
405     placed on the left unless the global dop options are to put it on top, that
406     case is handled in GetPageULData.
407     */
408     if (rSection.maSep.fRTLGutter)
409         nWWRi += nWWGu;
410     else if (!mrReader.pWDop->iGutterPos)
411         nWWLe += nWWGu;
412 
413     // Left / Right
414     if ((rSection.nPgWidth - nWWLe - nWWRi) < MINLAY)
415     {
416         /*
417         There are some label templates which are "broken", they specify
418         margins which make no sense e.g. Left 16.10cm, Right 16.10cm. So the
419         space left between the margins is less than 0 In word the left margin
420         is honoured and if the right margin would be past the left margin is
421         left at the left margin position.
422 
423         Now this will work fine for importing, layout and exporting, *but* the
424         page layout dialog has a hardcoded minimum page width of 0.5cm so it
425         will report a different value than what is actually being used. i.e.
426         it will add up the values to give a wider page than is actually being
427         used.
428         */
429         nWWRi = rSection.nPgWidth - nWWLe - MINLAY;
430     }
431 
432     rSection.nPgLeft = nWWLe;
433     rSection.nPgRight = nWWRi;
434 }
435 
SetPage(SwPageDesc & rInPageDesc,SwFrmFmt & rFmt,const wwSection & rSection,bool bIgnoreCols) const436 void wwSectionManager::SetPage(SwPageDesc &rInPageDesc, SwFrmFmt &rFmt,
437     const wwSection &rSection, bool bIgnoreCols) const
438 {
439     // 1. Orientierung
440     rInPageDesc.SetLandscape(rSection.IsLandScape());
441 
442     // 2. Papiergroesse
443     SwFmtFrmSize aSz( rFmt.GetFrmSize() );
444     aSz.SetWidth(rSection.GetPageWidth());
445     aSz.SetHeight(SvxPaperInfo::GetSloppyPaperDimension(rSection.GetPageHeight()));
446     rFmt.SetFmtAttr(aSz);
447 
448     rFmt.SetFmtAttr(
449         SvxLRSpaceItem(rSection.GetPageLeft(), rSection.GetPageRight(), 0, 0, RES_LR_SPACE));
450 
451     if (!bIgnoreCols)
452         SetCols(rFmt, rSection, rSection.GetTextAreaWidth());
453 }
454 
lcl_MakeSafeNegativeSpacing(sal_uInt16 nIn)455 sal_uInt16 lcl_MakeSafeNegativeSpacing(sal_uInt16 nIn)
456 {
457     if (nIn > SHRT_MAX)
458         nIn = 0;
459     return nIn;
460 }
461 
SetPageBorder(SwFrmFmt & rFmt,const wwSection & rSection) const462 void SwWW8ImplReader::SetPageBorder(SwFrmFmt &rFmt, const wwSection &rSection) const
463 {
464     if (!IsBorder(rSection.brc))
465         return;
466 
467     SfxItemSet aSet(rFmt.GetAttrSet());
468     short aSizeArray[5]={0};
469     SetFlyBordersShadow(aSet, rSection.brc, &aSizeArray[0]);
470     SvxLRSpaceItem aLR(ItemGet<SvxLRSpaceItem>(aSet, RES_LR_SPACE));
471     SvxULSpaceItem aUL(ItemGet<SvxULSpaceItem>(aSet, RES_UL_SPACE));
472 
473     SvxBoxItem aBox(ItemGet<SvxBoxItem>(aSet, RES_BOX));
474     short aOriginalBottomMargin = aBox.GetDistance(BOX_LINE_BOTTOM);
475 
476     if (rSection.maSep.pgbOffsetFrom == 1)
477     {
478         sal_uInt16 nDist;
479         if (aBox.GetLeft())
480         {
481             nDist = aBox.GetDistance(BOX_LINE_LEFT);
482             aBox.SetDistance(lcl_MakeSafeNegativeSpacing(static_cast<sal_uInt16>(aLR.GetLeft() - nDist)), BOX_LINE_LEFT);
483             aSizeArray[WW8_LEFT] =
484                 aSizeArray[WW8_LEFT] - nDist + aBox.GetDistance(BOX_LINE_LEFT);
485         }
486 
487         if (aBox.GetRight())
488         {
489             nDist = aBox.GetDistance(BOX_LINE_RIGHT);
490             aBox.SetDistance(lcl_MakeSafeNegativeSpacing(static_cast<sal_uInt16>(aLR.GetRight() - nDist)), BOX_LINE_RIGHT);
491             aSizeArray[WW8_RIGHT] =
492                 aSizeArray[WW8_RIGHT] - nDist + aBox.GetDistance(BOX_LINE_RIGHT);
493         }
494 
495         if (aBox.GetTop())
496         {
497             nDist = aBox.GetDistance(BOX_LINE_TOP);
498             aBox.SetDistance(lcl_MakeSafeNegativeSpacing(static_cast<sal_uInt16>(aUL.GetUpper() - nDist)), BOX_LINE_TOP);
499             aSizeArray[WW8_TOP] =
500                 aSizeArray[WW8_TOP] - nDist + aBox.GetDistance(BOX_LINE_TOP);
501         }
502 
503         if (aBox.GetBottom())
504         {
505             nDist = aBox.GetDistance(BOX_LINE_BOTTOM);
506             aBox.SetDistance(lcl_MakeSafeNegativeSpacing(static_cast<sal_uInt16>(aUL.GetLower() - nDist)), BOX_LINE_BOTTOM);
507             aSizeArray[WW8_BOT] =
508                 aSizeArray[WW8_BOT] - nDist + aBox.GetDistance(BOX_LINE_BOTTOM);
509         }
510 
511         aSet.Put(aBox);
512     }
513 
514     if (aBox.GetLeft())
515         aLR.SetLeft(lcl_MakeSafeNegativeSpacing(static_cast<sal_uInt16>(aLR.GetLeft() - aSizeArray[WW8_LEFT])));
516     if (aBox.GetRight())
517         aLR.SetRight(lcl_MakeSafeNegativeSpacing(static_cast<sal_uInt16>(aLR.GetRight() - aSizeArray[WW8_RIGHT])));
518     if (aBox.GetTop())
519         aUL.SetUpper(lcl_MakeSafeNegativeSpacing(static_cast<sal_uInt16>(aUL.GetUpper() - aSizeArray[WW8_TOP])));
520     if (aBox.GetBottom())
521     {
522         //#i30088# and #i30074# - do a final sanity check on
523         //bottom value. Do not allow a resulting zero if bottom
524         //Border margin value was not originally zero.
525         if(aUL.GetLower() != 0)
526             aUL.SetLower(lcl_MakeSafeNegativeSpacing(static_cast<sal_uInt16>(aUL.GetLower() - aSizeArray[WW8_BOT])));
527         else
528             aUL.SetLower(lcl_MakeSafeNegativeSpacing(static_cast<sal_uInt16>(aOriginalBottomMargin - aSizeArray[WW8_BOT])));
529     }
530 
531     aSet.Put(aLR);
532     aSet.Put(aUL);
533     rFmt.SetFmtAttr(aSet);
534 }
535 
GetPageULData(const wwSection & rSection,bool bFirst,wwSectionManager::wwULSpaceData & rData) const536 void wwSectionManager::GetPageULData(const wwSection &rSection, bool bFirst,
537     wwSectionManager::wwULSpaceData& rData) const
538 {
539     sal_Int32 nWWUp = rSection.maSep.dyaTop;
540     sal_Int32 nWWLo = rSection.maSep.dyaBottom;
541     sal_uInt32 nWWHTop = rSection.maSep.dyaHdrTop;
542     sal_uInt32 nWWFBot = rSection.maSep.dyaHdrBottom;
543 
544     /*
545     If there is gutter in 97+ and the dop says put it on top then get the
546     gutter distance and set it to the top margin. When we are "two pages
547     in one" the gutter is put at the top of odd pages, and bottom of
548     even pages, something we cannot do. So we will put it on top of all
549     pages, that way the pages are at least the right size.
550     */
551     if (
552          (!mrReader.bVer67 && mrReader.pWDop->iGutterPos &&
553          rSection.maSep.fRTLGutter)
554        )
555     {
556         nWWUp += rSection.maSep.dzaGutter;
557     }
558 
559     if( bFirst )
560         rData.bHasHeader = (rSection.maSep.grpfIhdt & WW8_HEADER_FIRST) !=0;
561     else
562     {
563         rData.bHasHeader = (rSection.maSep.grpfIhdt &
564             (WW8_HEADER_EVEN | WW8_HEADER_ODD)) != 0;
565     }
566 
567     if( rData.bHasHeader )
568     {
569         rData.nSwUp  = nWWHTop;             // Header -> umrechnen
570         // --> CMC, OD 2004-06-18 #i19922# - correction:
571         // consider that <nWWUp> can be negative, compare only if it's positive
572         if ( nWWUp > 0 &&
573              static_cast<sal_uInt32>(abs(nWWUp)) >= nWWHTop )
574             rData.nSwHLo = nWWUp - nWWHTop;
575         else
576             rData.nSwHLo = 0;
577 
578         // --> OD 2004-06-18 #i19922# - minimum page header height is now 1mm
579         // use new constant <cMinHdFtHeight>
580         if (rData.nSwHLo < sal::static_int_cast< sal_uInt32 >(cMinHdFtHeight))
581             rData.nSwHLo = sal::static_int_cast< sal_uInt32 >(cMinHdFtHeight);
582     }
583     else // kein Header -> Up einfach uebernehmen
584         rData.nSwUp = Abs(nWWUp);
585 
586     if( bFirst )
587         rData.bHasFooter = (rSection.maSep.grpfIhdt &  WW8_FOOTER_FIRST) !=0;
588     else
589     {
590         rData.bHasFooter = (rSection.maSep.grpfIhdt &
591             (WW8_FOOTER_EVEN | WW8_FOOTER_ODD)) != 0;
592     }
593 
594     if( rData.bHasFooter )
595     {
596         rData.nSwLo = nWWFBot;              // Footer -> Umrechnen
597         // --> CMC, OD 2004-06-18 #i19922# - correction:
598         // consider that <nWWLo> can be negative, compare only if it's positive
599         if ( nWWLo > 0 &&
600              static_cast<sal_uInt32>(abs(nWWLo)) >= nWWFBot )
601             rData.nSwFUp = nWWLo - nWWFBot;
602         else
603             rData.nSwFUp = 0;
604 
605         // --> OD 2004-06-18 #i19922# - minimum page header height is now 1mm
606         // use new constant <cMinHdFtHeight>
607         if (rData.nSwFUp < sal::static_int_cast< sal_uInt32 >(cMinHdFtHeight))
608             rData.nSwFUp = sal::static_int_cast< sal_uInt32 >(cMinHdFtHeight);
609     }
610     else // kein Footer -> Lo einfach uebernehmen
611         rData.nSwLo = Abs(nWWLo);
612 }
613 
SetPageULSpaceItems(SwFrmFmt & rFmt,wwSectionManager::wwULSpaceData & rData,const wwSection & rSection) const614 void wwSectionManager::SetPageULSpaceItems(SwFrmFmt &rFmt,
615     wwSectionManager::wwULSpaceData& rData, const wwSection &rSection) const
616 {
617     if (rData.bHasHeader)               // ... und Header-Lower setzen
618     {
619         //Kopfzeilenhoehe minimal sezten
620         if (SwFrmFmt* pHdFmt = (SwFrmFmt*)rFmt.GetHeader().GetHeaderFmt())
621         {
622             SvxULSpaceItem aHdUL(pHdFmt->GetULSpace());
623             if (!rSection.IsFixedHeightHeader())    //normal
624             {
625                 pHdFmt->SetFmtAttr(SwFmtFrmSize(ATT_MIN_SIZE, 0, rData.nSwHLo));
626                 // --> OD 2004-06-18 #i19922# - minimum page header height is now 1mm
627                 // use new constant <cMinHdFtHeight>
628                 aHdUL.SetLower( writer_cast<sal_uInt16>(rData.nSwHLo - cMinHdFtHeight) );
629                 pHdFmt->SetFmtAttr(SwHeaderAndFooterEatSpacingItem(
630                     RES_HEADER_FOOTER_EAT_SPACING, true));
631             }
632             else
633             {
634                 // --> OD 2005-05-20 #i48832# - set correct spacing between
635                 // header and body.
636                 const SwTwips nHdLowerSpace( Abs(rSection.maSep.dyaTop) - rData.nSwUp - rData.nSwHLo );
637                 pHdFmt->SetFmtAttr(SwFmtFrmSize(ATT_FIX_SIZE, 0, rData.nSwHLo + nHdLowerSpace));
638                 aHdUL.SetLower( static_cast< sal_uInt16 >(nHdLowerSpace) );
639                 // <--
640                 pHdFmt->SetFmtAttr(SwHeaderAndFooterEatSpacingItem(
641                     RES_HEADER_FOOTER_EAT_SPACING, false));
642             }
643             pHdFmt->SetFmtAttr(aHdUL);
644         }
645     }
646 
647     if (rData.bHasFooter)               // ... und Footer-Upper setzen
648     {
649         if (SwFrmFmt* pFtFmt = (SwFrmFmt*)rFmt.GetFooter().GetFooterFmt())
650         {
651             SvxULSpaceItem aFtUL(pFtFmt->GetULSpace());
652             if (!rSection.IsFixedHeightFooter())    //normal
653             {
654                 pFtFmt->SetFmtAttr(SwFmtFrmSize(ATT_MIN_SIZE, 0, rData.nSwFUp));
655                 // --> OD 2004-06-18 #i19922# - minimum page header height is now 1mm
656                 // use new constant <cMinHdFtHeight>
657                 aFtUL.SetUpper( writer_cast<sal_uInt16>(rData.nSwFUp - cMinHdFtHeight) );
658                 pFtFmt->SetFmtAttr(SwHeaderAndFooterEatSpacingItem(
659                     RES_HEADER_FOOTER_EAT_SPACING, true));
660             }
661             else
662             {
663                 // --> OD 2005-05-20 #i48832# - set correct spacing between
664                 // footer and body.
665                 const SwTwips nFtUpperSpace( Abs(rSection.maSep.dyaBottom) - rData.nSwLo - rData.nSwFUp );
666                 pFtFmt->SetFmtAttr(SwFmtFrmSize(ATT_FIX_SIZE, 0, rData.nSwFUp + nFtUpperSpace));
667                 aFtUL.SetUpper( static_cast< sal_uInt16 >(nFtUpperSpace) );
668                 // <--
669                 pFtFmt->SetFmtAttr(SwHeaderAndFooterEatSpacingItem(
670                     RES_HEADER_FOOTER_EAT_SPACING, false));
671             }
672             pFtFmt->SetFmtAttr(aFtUL);
673         }
674     }
675 
676     SvxULSpaceItem aUL(writer_cast<sal_uInt16>(rData.nSwUp),
677         writer_cast<sal_uInt16>(rData.nSwLo), RES_UL_SPACE);
678     rFmt.SetFmtAttr(aUL);
679 }
680 
InsertSection(SwPaM & rMyPaM,wwSection & rSection)681 SwSectionFmt *wwSectionManager::InsertSection(
682     SwPaM& rMyPaM, wwSection &rSection)
683 {
684     SwSectionData aSection( CONTENT_SECTION,
685             mrReader.rDoc.GetUniqueSectionName() );
686 
687     SfxItemSet aSet( mrReader.rDoc.GetAttrPool(), aFrmFmtSetRange );
688 
689     sal_uInt8 nRTLPgn = maSegments.empty() ? 0 : maSegments.back().IsBiDi();
690     aSet.Put(SvxFrameDirectionItem(
691         nRTLPgn ? FRMDIR_HORI_RIGHT_TOP : FRMDIR_HORI_LEFT_TOP, RES_FRAMEDIR));
692 
693     if (2 == mrReader.pWDop->fpc)
694         aSet.Put( SwFmtFtnAtTxtEnd(FTNEND_ATTXTEND));
695     if (0 == mrReader.pWDop->epc)
696         aSet.Put( SwFmtEndAtTxtEnd(FTNEND_ATTXTEND));
697 
698     aSection.SetProtectFlag(SectionIsProtected(rSection));
699 
700     rSection.mpSection =
701         mrReader.rDoc.InsertSwSection( rMyPaM, aSection, 0, & aSet );
702     ASSERT(rSection.mpSection, "section not inserted!");
703     if (!rSection.mpSection)
704         return 0;
705 
706     SwPageDesc *pPage = 0;
707     mySegrIter aEnd = maSegments.rend();
708     for (mySegrIter aIter = maSegments.rbegin(); aIter != aEnd; ++aIter)
709     {
710         if (0 != (pPage = aIter->mpPage))
711             break;
712     }
713 
714     ASSERT(pPage, "no page outside this section!");
715 
716     if (!pPage)
717         pPage = &mrReader.rDoc._GetPageDesc(0);
718 
719     if (!pPage)
720         return 0;
721 
722     SwSectionFmt *pFmt = rSection.mpSection->GetFmt();
723     ASSERT(pFmt, "impossible");
724     if (!pFmt)
725         return 0;
726 
727     SwFrmFmt& rFmt = pPage->GetMaster();
728     const SvxLRSpaceItem& rLR = rFmt.GetLRSpace();
729     long nPageLeft  = rLR.GetLeft();
730     long nPageRight = rLR.GetRight();
731     long nSectionLeft = rSection.GetPageLeft() - nPageLeft;
732     long nSectionRight = rSection.GetPageRight() - nPageRight;
733     if ((nSectionLeft != 0) || (nSectionRight != 0))
734     {
735         SvxLRSpaceItem aLR(nSectionLeft, nSectionRight, 0, 0, RES_LR_SPACE);
736         pFmt->SetFmtAttr(aLR);
737     }
738 
739     SetCols(*pFmt, rSection, rSection.GetTextAreaWidth());
740     return pFmt;
741 }
742 
HandleLineNumbering(const wwSection & rSection)743 void SwWW8ImplReader::HandleLineNumbering(const wwSection &rSection)
744 {
745     // check if Line Numbering must be activated or resetted
746     if (mbNewDoc && rSection.maSep.nLnnMod)
747     {
748         // restart-numbering-mode: 0 per page, 1 per section, 2 never restart
749         bool bRestartLnNumPerSection = (1 == rSection.maSep.lnc);
750 
751         if (bNoLnNumYet)
752         {
753             SwLineNumberInfo aInfo( rDoc.GetLineNumberInfo() );
754 
755             aInfo.SetPaintLineNumbers(true);
756 
757             aInfo.SetRestartEachPage(rSection.maSep.lnc == 0);
758 
759             aInfo.SetPosFromLeft(writer_cast<sal_uInt16>(rSection.maSep.dxaLnn));
760 
761             //Paint only for every n line
762             aInfo.SetCountBy(rSection.maSep.nLnnMod);
763 
764             // to be defaulted features ( HARDCODED in MS Word 6,7,8,9 )
765             aInfo.SetCountBlankLines(true);
766             aInfo.SetCountInFlys(false);
767             aInfo.SetPos( LINENUMBER_POS_LEFT );
768             SvxNumberType aNumType; // this sets SVX_NUM_ARABIC per default
769             aInfo.SetNumType( aNumType );
770 
771             rDoc.SetLineNumberInfo( aInfo );
772             bNoLnNumYet = false;
773         }
774 
775         if (
776             (0 < rSection.maSep.lnnMin) ||
777             (bRestartLnNumPerSection && !bNoLnNumYet)
778            )
779         {
780             SwFmtLineNumber aLN;
781             if (const SwFmtLineNumber* pLN
782                 = (const SwFmtLineNumber*)GetFmtAttr(RES_LINENUMBER))
783             {
784                 aLN.SetCountLines( pLN->IsCount() );
785             }
786             aLN.SetStartValue(1 + rSection.maSep.lnnMin);
787             NewAttr(aLN);
788             pCtrlStck->SetAttr(*pPaM->GetPoint(), RES_LINENUMBER);
789         }
790         bNoLnNumYet = false;
791     }
792 }
793 
wwSection(const SwPosition & rPos)794 wwSection::wwSection(const SwPosition &rPos) : maStart(rPos.nNode),
795     mpSection(0), mpTitlePage(0), mpPage(0), meDir(FRMDIR_HORI_LEFT_TOP),
796     nPgWidth(SvxPaperInfo::GetPaperSize(PAPER_A4).Width()),
797     nPgLeft(MM_250), nPgRight(MM_250), mnBorders(0), mbHasFootnote(false)
798 {
799 }
800 
SetNumberingType(const wwSection & rNewSection,SwPageDesc & rPageDesc) const801 void wwSectionManager::SetNumberingType(const wwSection &rNewSection,
802     SwPageDesc &rPageDesc) const
803 {
804     // Seitennummernformat speichern
805     static const SvxExtNumType aNumTyp[5] =
806     {
807         SVX_NUM_ARABIC, SVX_NUM_ROMAN_UPPER, SVX_NUM_ROMAN_LOWER,
808         SVX_NUM_CHARS_UPPER_LETTER_N, SVX_NUM_CHARS_LOWER_LETTER_N
809     };
810 
811     SvxNumberType aType;
812     aType.SetNumberingType( static_cast< sal_Int16 >(aNumTyp[rNewSection.maSep.nfcPgn]) );
813     rPageDesc.SetNumType(aType);
814 }
815 
816 // Bei jedem Abschnittswechsel ( auch am Anfang eines Dokuments ) wird
817 // CreateSep gerufen, dass dann den / die Pagedesc(s) erzeugt und
818 // mit Attributen un KF-Texten fuellt.
819 // Dieses Vorgehen ist noetig geworden, da die UEbersetzung der verschiedenen
820 // Seiten-Attribute zu stark verflochten ist.
CreateSep(const long nTxtPos,bool)821 void wwSectionManager::CreateSep(const long nTxtPos, bool /*bMustHaveBreak*/)
822 {
823     /*
824     #i1909# #100688# section/page breaks should not occur in tables or subpage
825     elements like frames. Word itself ignores them in this case. The bug is
826     more likely that this filter created such documents in the past!
827     */
828     if (mrReader.nInTable || mrReader.bTxbxFlySection || mrReader.InLocalApo())
829         return;
830 
831     WW8PLCFx_SEPX* pSep = mrReader.pPlcxMan->GetSepPLCF();
832     ASSERT(pSep, "impossible!");
833     if (!pSep)
834         return;
835 
836     ww::WordVersion eVer = mrReader.GetFib().GetFIBVersion();
837 
838     // M.M. Create a linked section if the WkbPLCF
839     // has an entry for one at this cp
840     WW8PLCFspecial* pWkb = mrReader.pPlcxMan->GetWkbPLCF();
841     if (pWkb && pWkb->SeekPosExact(nTxtPos) &&
842             pWkb->Where() == nTxtPos)
843     {
844         void* pData;
845         WW8_CP nTest;
846         pWkb->Get(nTest, pData);
847         String sSectionName = mrReader.aLinkStringMap[SVBT16ToShort( ((WW8_WKB*)pData)->nLinkId) ];
848         mrReader.ConvertFFileName(sSectionName, sSectionName);
849         SwSectionData aSection(FILE_LINK_SECTION, sSectionName);
850         aSection.SetLinkFileName( sSectionName );
851         aSection.SetProtectFlag(true);
852         // --> CMC, OD 2004-06-18 #i19922# improvement:
853         // return value of method <Insert> not used.
854         mrReader.rDoc.InsertSwSection(*mrReader.pPaM, aSection, 0, 0, false);
855     }
856 
857     wwSection aLastSection(*mrReader.pPaM->GetPoint());
858     if (!maSegments.empty())
859         aLastSection = maSegments.back();
860 
861     //Here
862     sal_uInt16 nLIdx = ( ( mrReader.pWwFib->lid & 0xff ) == 0x9 ) ? 1 : 0;
863 
864     //BEGIN read section values
865     wwSection aNewSection(*mrReader.pPaM->GetPoint());
866 
867     static const sal_uInt16 aVer2Ids0[] =
868     {
869         /*sprmSBkc*/           117,
870         /*sprmSFTitlePage*/    118,
871         /*sprmSNfcPgn*/        122,
872         /*sprmSCcolumns*/      119,
873         /*sprmSDxaColumns*/    120,
874         /*sprmSLBetween*/      133
875     };
876 
877     static const sal_uInt16 aVer67Ids0[] =
878     {
879         /*sprmSBkc*/           142,
880         /*sprmSFTitlePage*/    143,
881         /*sprmSNfcPgn*/        147,
882         /*sprmSCcolumns*/      144,
883         /*sprmSDxaColumns*/    145,
884         /*sprmSLBetween*/      158
885     };
886 
887     static const sal_uInt16 aVer8Ids0[] =
888     {
889         /*sprmSBkc*/           0x3009,
890         /*sprmSFTitlePage*/    0x300A,
891         /*sprmSNfcPgn*/        0x300E,
892         /*sprmSCcolumns*/      0x500B,
893         /*sprmSDxaColumns*/    0x900C,
894         /*sprmSLBetween*/      0x3019
895     };
896 
897     const sal_uInt16* pIds = eVer <= ww::eWW2 ? aVer2Ids0 : eVer <= ww::eWW7 ? aVer67Ids0 : aVer8Ids0;
898 
899     if (!maSegments.empty())
900     {
901         // Type of break: break codes are:
902         // 0 No break
903         // 1 New column
904         // 2 New page
905         // 3 Even page
906         // 4 Odd page
907         if (const sal_uInt8* pSprmBkc = pSep->HasSprm(pIds[0]))
908             aNewSection.maSep.bkc = *pSprmBkc;
909     }
910 
911     // Has a table page
912     aNewSection.maSep.fTitlePage =
913         (0 != ReadBSprm( pSep, pIds[1], 0 ));
914 
915     // sprmSNfcPgn
916     aNewSection.maSep.nfcPgn = ReadBSprm( pSep, pIds[2], 0 );
917     if (aNewSection.maSep.nfcPgn > 4)
918         aNewSection.maSep.nfcPgn = 0;
919 
920     aNewSection.maSep.fUnlocked = eVer > ww::eWW2 ? ReadBSprm(pSep, (eVer <= ww::eWW7 ? 139 : 0x3006), 0 ) : 0;
921 
922     // sprmSFBiDi
923     aNewSection.maSep.fBiDi = eVer >= ww::eWW8 ? ReadBSprm(pSep, 0x3228, 0) : 0;
924 
925     // Reading section property sprmSCcolumns - one less than the number of columns in the section.
926     // It must be less than MAX_NO_OF_SEP_COLUMNS according the WW8 specification.
927     aNewSection.maSep.ccolM1 = ReadSprm(pSep, pIds[3], 0 );
928     if ( aNewSection.maSep.ccolM1 >= MAX_NO_OF_SEP_COLUMNS )
929     {
930         // fallback to one column
931         aNewSection.maSep.ccolM1 = 0;
932     }
933 
934     //sprmSDxaColumns   - Default-Abstand 1.25 cm
935     aNewSection.maSep.dxaColumns = ReadUSprm( pSep, pIds[4], 708 );
936 
937     // sprmSLBetween
938     aNewSection.maSep.fLBetween = ReadBSprm(pSep, pIds[5], 0 );
939 
940     if (eVer >= ww::eWW6)
941     {
942         // sprmSFEvenlySpaced
943         aNewSection.maSep.fEvenlySpaced = ReadBSprm( pSep, ( eVer <= ww::eWW7 ? 138 : 0x3005 ), 1 ) ? true : false;
944 
945         if ( aNewSection.maSep.ccolM1 > 0 && !aNewSection.maSep.fEvenlySpaced )
946         {
947             int nColumnDataIdx = 0;
948             aNewSection.maSep.rgdxaColumnWidthSpacing[nColumnDataIdx] = 0;
949 
950             const sal_uInt16 nColumnWidthSprmId = ( eVer <= ww::eWW7 ? 136 : 0xF203 );
951             const sal_uInt16 nColumnSpacingSprmId = ( eVer <= ww::eWW7 ? 137 : 0xF204 );
952             const sal_uInt8 nColumnCount = static_cast< sal_uInt8 >(aNewSection.maSep.ccolM1 + 1);
953             for ( sal_uInt8 nColumn = 0; nColumn < nColumnCount; ++nColumn )
954             {
955                 //sprmSDxaColWidth
956                 const sal_uInt8* pSW = pSep->HasSprm( nColumnWidthSprmId, nColumn );
957 
958                 ASSERT( pSW != NULL, "+Sprm 136 (bzw. 0xF203) (ColWidth) fehlt" );
959                 sal_uInt16 nWidth = pSW != NULL ? SVBT16ToShort( pSW + 1 ) : 1440;
960 
961                 aNewSection.maSep.rgdxaColumnWidthSpacing[++nColumnDataIdx] = nWidth;
962 
963                 if ( nColumn < nColumnCount - 1 )
964                 {
965                     //sprmSDxaColSpacing
966                     const sal_uInt8* pSD = pSep->HasSprm( nColumnSpacingSprmId, nColumn );
967 
968                     ASSERT( pSD, "+Sprm 137 (bzw. 0xF204) (Colspacing) fehlt" );
969                     if ( pSD )
970                     {
971                         nWidth = SVBT16ToShort( pSD + 1 );
972                         aNewSection.maSep.rgdxaColumnWidthSpacing[++nColumnDataIdx] = nWidth;
973                     }
974                 }
975             }
976         }
977     }
978 
979     static const sal_uInt16 aVer2Ids1[] =
980     {
981         /*sprmSBOrientation*/   137,
982         /*sprmSXaPage*/         139,
983         /*sprmSYaPage*/         140,
984         /*sprmSDxaLeft*/        141,
985         /*sprmSDxaRight*/       142,
986         /*sprmSDzaGutter*/      145,
987         /*sprmSFPgnRestart*/    125,
988         /*sprmSPgnStart*/       136,
989         /*sprmSDmBinFirst*/     115,
990         /*sprmSDmBinOther*/     116
991     };
992 
993     static const sal_uInt16 aVer67Ids1[] =
994     {
995         /*sprmSBOrientation*/   162,
996         /*sprmSXaPage*/         164,
997         /*sprmSYaPage*/         165,
998         /*sprmSDxaLeft*/        166,
999         /*sprmSDxaRight*/       167,
1000         /*sprmSDzaGutter*/      170,
1001         /*sprmSFPgnRestart*/    150,
1002         /*sprmSPgnStart*/       161,
1003         /*sprmSDmBinFirst*/     140,
1004         /*sprmSDmBinOther*/     141
1005     };
1006 
1007     static const sal_uInt16 aVer8Ids1[] =
1008     {
1009         /*sprmSBOrientation*/   0x301d,
1010         /*sprmSXaPage*/         0xB01F,
1011         /*sprmSYaPage*/         0xB020,
1012         /*sprmSDxaLeft*/        0xB021,
1013         /*sprmSDxaRight*/       0xB022,
1014         /*sprmSDzaGutter*/      0xB025,
1015         /*sprmSFPgnRestart*/    0x3011,
1016         /*sprmSPgnStart*/       0x501C,
1017            /*sprmSDmBinFirst*/     0x5007,
1018         /*sprmSDmBinOther*/     0x5008
1019     };
1020 
1021     pIds = eVer <= ww::eWW2 ? aVer2Ids1 : eVer <= ww::eWW7 ? aVer67Ids1 : aVer8Ids1;
1022 
1023                                             // 1. Orientierung
1024     aNewSection.maSep.dmOrientPage = ReadBSprm(pSep, pIds[0], 0);
1025 
1026     // 2. Papiergroesse
1027     aNewSection.maSep.xaPage = ReadUSprm(pSep, pIds[1], lLetterWidth);
1028     aNewSection.nPgWidth = SvxPaperInfo::GetSloppyPaperDimension(aNewSection.maSep.xaPage);
1029 
1030     aNewSection.maSep.yaPage = ReadUSprm(pSep, pIds[2], lLetterHeight);
1031 
1032     // 3. LR-Raender
1033     static const sal_uInt16 nLef[] = { MM_250, 1800 };
1034     static const sal_uInt16 nRig[] = { MM_250, 1800 };
1035 
1036     aNewSection.maSep.dxaLeft = ReadUSprm( pSep, pIds[3], nLef[nLIdx]);
1037     aNewSection.maSep.dxaRight = ReadUSprm( pSep, pIds[4], nRig[nLIdx]);
1038 
1039     //#110175# 2pages in 1sheet hackery ?
1040     //#i31806# but only swap if 2page in 1sheet is enabled.
1041     // its not clear if dmOrientPage is the correct member to
1042     // decide on this but I am not about to 2nd guess cmc.
1043     if(mrReader.pWDop->doptypography.f2on1 &&
1044             aNewSection.maSep.dmOrientPage == 2)
1045         std::swap(aNewSection.maSep.dxaLeft, aNewSection.maSep.dxaRight);
1046 
1047     aNewSection.maSep.dzaGutter = ReadUSprm( pSep, pIds[5], 0);
1048 
1049     aNewSection.maSep.fRTLGutter = static_cast< sal_uInt8 >(eVer >= ww::eWW8 ? ReadUSprm( pSep, 0x322A, 0 ) : 0);
1050 
1051     // Page Number Restarts - sprmSFPgnRestart
1052     aNewSection.maSep.fPgnRestart = ReadBSprm(pSep, pIds[6], 0);
1053 
1054     aNewSection.maSep.pgnStart = ReadBSprm( pSep, pIds[7], 0 );
1055 
1056     if (eVer >= ww::eWW6)
1057     {
1058         if (const sal_uInt8* p = pSep->HasSprm( (eVer <= ww::eWW7 ? 132 : 0x3001) ))
1059             aNewSection.maSep.iHeadingPgn = *p;
1060 
1061         if (const sal_uInt8* p = pSep->HasSprm( (eVer <= ww::eWW7 ? 131 : 0x3000) ))
1062             aNewSection.maSep.cnsPgn = *p;
1063     }
1064 
1065     if(const sal_uInt8* pSprmSDmBinFirst = pSep->HasSprm( pIds[8] ))
1066         aNewSection.maSep.dmBinFirst = *pSprmSDmBinFirst;
1067 
1068     if (const sal_uInt8* pSprmSDmBinOther = pSep->HasSprm( pIds[9] ))
1069         aNewSection.maSep.dmBinOther = *pSprmSDmBinOther;
1070 
1071     static const sal_uInt16 nTop[] = { MM_250, 1440 };
1072     static const sal_uInt16 nBot[] = { MM_200, 1440 };
1073 
1074     static const sal_uInt16 aVer2Ids2[] =
1075     {
1076         /*sprmSDyaTop*/         143,
1077         /*sprmSDyaBottom*/      144,
1078         /*sprmSDyaHdrTop*/      131,
1079         /*sprmSDyaHdrBottom*/   132,
1080         /*sprmSNLnnMod*/        129,
1081         /*sprmSLnc*/            127,
1082         /*sprmSDxaLnn*/         130,
1083         /*sprmSLnnMin*/         135
1084     };
1085 
1086     static const sal_uInt16 aVer67Ids2[] =
1087     {
1088         /*sprmSDyaTop*/         168,
1089         /*sprmSDyaBottom*/      169,
1090         /*sprmSDyaHdrTop*/      156,
1091         /*sprmSDyaHdrBottom*/   157,
1092         /*sprmSNLnnMod*/        154,
1093         /*sprmSLnc*/            152,
1094         /*sprmSDxaLnn*/         155,
1095         /*sprmSLnnMin*/         160
1096     };
1097     static const sal_uInt16 aVer8Ids2[] =
1098     {
1099         /*sprmSDyaTop*/         0x9023,
1100         /*sprmSDyaBottom*/      0x9024,
1101         /*sprmSDyaHdrTop*/      0xB017,
1102         /*sprmSDyaHdrBottom*/   0xB018,
1103         /*sprmSNLnnMod*/        0x5015,
1104         /*sprmSLnc*/            0x3013,
1105         /*sprmSDxaLnn*/         0x9016,
1106         /*sprmSLnnMin*/         0x501B
1107     };
1108 
1109     pIds = eVer <= ww::eWW2 ? aVer2Ids2 : eVer <= ww::eWW7 ? aVer67Ids2 : aVer8Ids2;
1110 
1111     aNewSection.maSep.dyaTop = ReadSprm( pSep, pIds[0], nTop[nLIdx] );
1112     aNewSection.maSep.dyaBottom = ReadSprm( pSep, pIds[1], nBot[nLIdx] );
1113     aNewSection.maSep.dyaHdrTop = ReadUSprm( pSep, pIds[2], 720 );
1114     aNewSection.maSep.dyaHdrBottom = ReadUSprm( pSep, pIds[3], 720 );
1115 
1116     if (eVer >= ww::eWW8)
1117     {
1118         aNewSection.maSep.wTextFlow = ReadUSprm(pSep, 0x5033, 0);
1119         aNewSection.maSep.clm = ReadUSprm( pSep, 0x5032, 0 );
1120         aNewSection.maSep.dyaLinePitch = ReadUSprm(pSep, 0x9031, 360);
1121         if (const sal_uInt8* pS = pSep->HasSprm(0x7030))
1122             aNewSection.maSep.dxtCharSpace = SVBT32ToUInt32(pS);
1123 
1124         //sprmSPgbProp
1125         sal_uInt16 pgbProp = ReadSprm( pSep, 0x522F, 0 );
1126         aNewSection.maSep.pgbApplyTo = pgbProp & 0x0007;
1127         aNewSection.maSep.pgbPageDepth = (pgbProp & 0x0018) >> 3;
1128         aNewSection.maSep.pgbOffsetFrom = (pgbProp & 0x00E0) >> 5;
1129 
1130         aNewSection.mnBorders =
1131             ::lcl_ReadBorders(eVer <= ww::eWW7, aNewSection.brc, 0, 0, pSep);
1132     }
1133 
1134     // check if Line Numbering must be activated or resetted
1135     if (const sal_uInt8* pSprmSNLnnMod = pSep->HasSprm( pIds[4] ))
1136         aNewSection.maSep.nLnnMod = *pSprmSNLnnMod;
1137 
1138     if (const sal_uInt8* pSprmSLnc = pSep->HasSprm( pIds[5] ))
1139         aNewSection.maSep.lnc = *pSprmSLnc;
1140 
1141     if (const sal_uInt8* pSprmSDxaLnn = pSep->HasSprm( pIds[6] ))
1142         aNewSection.maSep.dxaLnn = SVBT16ToShort( pSprmSDxaLnn );
1143 
1144     if (const sal_uInt8* pSprmSLnnMin = pSep->HasSprm( pIds[7] ))
1145         aNewSection.maSep.lnnMin = *pSprmSLnnMin;
1146 
1147     if (eVer <= ww::eWW7)
1148         aNewSection.maSep.grpfIhdt = ReadBSprm(pSep, eVer <= ww::eWW2 ? 128 : 153, 0);
1149     else if (mrReader.pHdFt)
1150     {
1151         aNewSection.maSep.grpfIhdt = WW8_HEADER_ODD | WW8_FOOTER_ODD;
1152 
1153         if (aNewSection.HasTitlePage())
1154             aNewSection.maSep.grpfIhdt |= WW8_HEADER_FIRST | WW8_FOOTER_FIRST;
1155 
1156         if (mrReader.pWDop->fFacingPages)
1157             aNewSection.maSep.grpfIhdt |= WW8_HEADER_EVEN | WW8_FOOTER_EVEN;
1158 
1159         //See if we have a header or footer for each enabled possibility
1160         //if we do not then we inherit the previous sections header/footer,
1161         for (int nI = 0, nMask = 1; nI < 6; ++nI, nMask <<= 1)
1162         {
1163             if (aNewSection.maSep.grpfIhdt & nMask)
1164             {
1165                 WW8_CP nStart;
1166                 long nLen;
1167                 mrReader.pHdFt->GetTextPosExact( static_cast< short >(nI + ( maSegments.size() + 1) * 6), nStart, nLen);
1168                 //No header or footer, inherit pervious one, or set to zero
1169                 //if no previous one
1170                 if (!nLen)
1171                 {
1172                     if (
1173                         maSegments.empty() ||
1174                         !(maSegments.back().maSep.grpfIhdt & nMask)
1175                        )
1176                     {
1177                         aNewSection.maSep.grpfIhdt &= ~nMask;
1178                     }
1179                 }
1180             }
1181         }
1182     }
1183 
1184     SetLeftRight(aNewSection);
1185     //END read section values
1186 
1187     if (eVer >= ww::eWW8)
1188         aNewSection.SetDirection();
1189 
1190     mrReader.HandleLineNumbering(aNewSection);
1191     maSegments.push_back(aNewSection);
1192 }
1193 
CopyPageDescHdFt(const SwPageDesc * pOrgPageDesc,SwPageDesc * pNewPageDesc,sal_uInt8 nCode)1194 void SwWW8ImplReader::CopyPageDescHdFt(const SwPageDesc* pOrgPageDesc,
1195     SwPageDesc* pNewPageDesc, sal_uInt8 nCode )
1196 {
1197     // copy first header content section
1198     if (nCode & WW8_HEADER_FIRST)
1199         rDoc.CopyHeader(pOrgPageDesc->GetMaster(), pNewPageDesc->GetMaster());
1200 
1201     // copy first footer content section
1202     if( nCode & WW8_FOOTER_FIRST )
1203         rDoc.CopyFooter(pOrgPageDesc->GetMaster(), pNewPageDesc->GetMaster());
1204 
1205     if( nCode & (   WW8_HEADER_ODD  | WW8_FOOTER_ODD
1206                   | WW8_HEADER_EVEN | WW8_FOOTER_EVEN ) )
1207     {
1208         // copy odd header content section
1209         if( nCode & WW8_HEADER_ODD )
1210         {
1211             rDoc.CopyHeader(pOrgPageDesc->GetMaster(),
1212                             pNewPageDesc->GetMaster() );
1213         }
1214         // copy odd footer content section
1215         if( nCode & WW8_FOOTER_ODD )
1216         {
1217             rDoc.CopyFooter(pOrgPageDesc->GetMaster(),
1218                             pNewPageDesc->GetMaster());
1219         }
1220         // copy even header content section
1221         if( nCode & WW8_HEADER_EVEN )
1222         {
1223             rDoc.CopyHeader(pOrgPageDesc->GetLeft(),
1224                             pNewPageDesc->GetLeft());
1225         }
1226         // copy even footer content section
1227         if( nCode & WW8_FOOTER_EVEN )
1228         {
1229             rDoc.CopyFooter(pOrgPageDesc->GetLeft(),
1230                             pNewPageDesc->GetLeft());
1231         }
1232     }
1233 }
1234 
1235 //------------------------------------------------------
1236 //   Hilfsroutinen fuer Grafiken und Apos und Tabellen
1237 //------------------------------------------------------
1238 
_SetWW8_BRC(bool bVer67,WW8_BRC & rVar,const sal_uInt8 * pS)1239 static bool _SetWW8_BRC(bool bVer67, WW8_BRC& rVar, const sal_uInt8* pS)
1240 {
1241     if( pS )
1242     {
1243         if( bVer67 )
1244             memcpy( rVar.aBits1, pS, sizeof( SVBT16 ) );
1245         else
1246             rVar = *((WW8_BRC*)pS);
1247     }
1248 
1249     return 0 != pS;
1250 }
1251 
lcl_ReadBorders(bool bVer67,WW8_BRC * brc,WW8PLCFx_Cp_FKP * pPap,const WW8RStyle * pSty,const WW8PLCFx_SEPX * pSep)1252 sal_uInt8 lcl_ReadBorders(bool bVer67, WW8_BRC* brc, WW8PLCFx_Cp_FKP* pPap,
1253     const WW8RStyle* pSty, const WW8PLCFx_SEPX* pSep)
1254 {
1255 // Ausgegend von diesen defines:
1256 //      #define WW8_TOP 0
1257 //      #define WW8_LEFT 1
1258 //      #define WW8_BOT 2
1259 //      #define WW8_RIGHT 3
1260 //      #define WW8_BETW 4
1261 
1262 //returns a sal_uInt8 filled with a bit for each position that had a sprm
1263 //setting that border
1264 
1265     sal_uInt8 nBorder = false;
1266     if( pSep )
1267     {
1268         if( !bVer67 )
1269         {
1270              sal_uInt8* pSprm[4];
1271 
1272             //  sprmSBrcTop, sprmSBrcLeft, sprmSBrcBottom, sprmSBrcRight
1273              if( pSep->Find4Sprms(  0x702B,   0x702C,   0x702D,   0x702E,
1274                                     pSprm[0], pSprm[1], pSprm[2], pSprm[3] ) )
1275              {
1276                 for( int i = 0; i < 4; ++i )
1277                     nBorder |= (_SetWW8_BRC( bVer67, brc[ i ], pSprm[ i ] ))<<i;
1278              }
1279         }
1280     }
1281     else
1282     {
1283 
1284         static const sal_uInt16 aVer67Ids[5] = { 38, 39, 40, 41, 42 };
1285 
1286         static const sal_uInt16 aVer8Ids[5] =
1287                 { 0x6424, 0x6425, 0x6426, 0x6427, 0x6428 };
1288 
1289         const sal_uInt16* pIds = bVer67 ? aVer67Ids : aVer8Ids;
1290 
1291         if( pPap )
1292         {
1293             for( int i = 0; i < 5; ++i, ++pIds )
1294                 nBorder |= (_SetWW8_BRC( bVer67, brc[ i ], pPap->HasSprm( *pIds )))<<i;
1295         }
1296         else if( pSty )
1297         {
1298             for( int i = 0; i < 5; ++i, ++pIds )
1299                 nBorder |= (_SetWW8_BRC( bVer67, brc[ i ], pSty->HasParaSprm( *pIds )))<<i;
1300         }
1301         else {
1302             ASSERT( pSty || pPap, "WW8PLCFx_Cp_FKP and WW8RStyle "
1303                                "and WW8PLCFx_SEPX is 0" );
1304         }
1305     }
1306 
1307     return nBorder;
1308 }
1309 
GetLineIndex(SvxBoxItem & rBox,short nLineThickness,short nSpace,sal_uInt8 nCol,short nIdx,sal_uInt16 nOOIndex,sal_uInt16 nWWIndex,short * pSize=0)1310 void GetLineIndex(SvxBoxItem &rBox, short nLineThickness, short nSpace, sal_uInt8 nCol, short nIdx,
1311     sal_uInt16 nOOIndex, sal_uInt16 nWWIndex, short *pSize=0)
1312 {
1313     WW8_BordersSO::eBorderCode eCodeIdx;
1314 
1315     //Word mirrors some indexes inside outside depending on its position, we
1316     //don't do that, so flip them here
1317     if (nWWIndex == WW8_TOP || nWWIndex == WW8_LEFT)
1318     {
1319         switch (nIdx)
1320         {
1321             case 11:
1322             case 12:
1323                 nIdx = (nIdx == 11) ? 12 : 11;
1324                 break;
1325             case 14:
1326             case 15:
1327                 nIdx = (nIdx == 14) ? 15 : 14;
1328                 break;
1329             case 17:
1330             case 18:
1331                 nIdx = (nIdx == 17) ? 18 : 17;
1332                 break;
1333             case 24:
1334             case 25:
1335                 nIdx = (nIdx == 24) ? 25 : 24;
1336                 break;
1337         }
1338     }
1339 
1340     // Map to our border types, we should use of one equal line
1341     // thickness, or one of smaller thickness. If too small we
1342     // can make the defecit up in additional white space or
1343     // object size
1344     switch (nIdx)
1345     {
1346         // First the single lines
1347         case  1:
1348         case  2:
1349         case  5:
1350         // and the unsupported special cases which we map to a single line
1351         case  6:
1352         case  7:
1353         case  8:
1354         case  9:
1355         case 22:
1356         // or if in necessary by a double line
1357         case 24:
1358         case 25:
1359             if( nLineThickness < 10)
1360                 eCodeIdx = WW8_BordersSO::single0;//   1 Twip for us
1361             else if( nLineThickness < 20)
1362                 eCodeIdx = WW8_BordersSO::single5;//   10 Twips for us
1363             else if (nLineThickness < 45) //Modified for i120716
1364                 eCodeIdx = WW8_BordersSO::single1;//  20 Twips
1365             else if (nLineThickness < 80)
1366                 eCodeIdx = WW8_BordersSO::single2;//  50
1367             else if (nLineThickness < 100)
1368                 eCodeIdx = WW8_BordersSO::single3;//  80
1369             else if (nLineThickness < 150)
1370                 eCodeIdx = WW8_BordersSO::single4;// 100
1371             // Hack: for the quite thick lines we must paint double lines,
1372             // because our singles lines don't come thicker than 5 points.
1373             else if (nLineThickness < 180)
1374                 eCodeIdx = WW8_BordersSO::double2;// 150
1375             else
1376                 eCodeIdx = WW8_BordersSO::double5;// 180
1377         break;
1378         // then the shading beams which we represent by a double line
1379         case 23:
1380             eCodeIdx = WW8_BordersSO::double1;
1381         break;
1382         // then the double lines, for which we have good matches
1383         case  3:
1384         case 10: //Don't have tripple so use double
1385             if (nLineThickness < 60)
1386                 eCodeIdx = WW8_BordersSO::double0;// 22 Twips for us
1387             else if (nLineThickness < 135)
1388                 eCodeIdx = WW8_BordersSO::double7;// some more space
1389             else if (nLineThickness < 180)
1390                 eCodeIdx = WW8_BordersSO::double1;// 60
1391             else
1392                 eCodeIdx = WW8_BordersSO::double2;// 150
1393             break;
1394         case 11:
1395             eCodeIdx = WW8_BordersSO::double4;//  90 Twips for us
1396             break;
1397         case 12:
1398         case 13: //Don't have thin thick thin, so use thick thin
1399             if (nLineThickness < 87)
1400                 eCodeIdx = WW8_BordersSO::double8;//  71 Twips for us
1401             else if (nLineThickness < 117)
1402                 eCodeIdx = WW8_BordersSO::double9;// 101
1403             else if (nLineThickness < 166)
1404                 eCodeIdx = WW8_BordersSO::double10;// 131
1405             else
1406                 eCodeIdx = WW8_BordersSO::double5;// 180
1407             break;
1408         case 14:
1409             if (nLineThickness < 46)
1410                 eCodeIdx = WW8_BordersSO::double0;//  22 Twips for us
1411             else if (nLineThickness < 76)
1412                 eCodeIdx = WW8_BordersSO::double1;//  60
1413             else if (nLineThickness < 121)
1414                 eCodeIdx = WW8_BordersSO::double4;//  90
1415             else if (nLineThickness < 166)
1416                 eCodeIdx = WW8_BordersSO::double2;// 150
1417             else
1418                 eCodeIdx = WW8_BordersSO::double6;// 180
1419             break;
1420         case 15:
1421         case 16: //Don't have thin thick thin, so use thick thin
1422             if (nLineThickness < 46)
1423                 eCodeIdx = WW8_BordersSO::double0;//  22 Twips for us
1424             else if (nLineThickness < 76)
1425                 eCodeIdx = WW8_BordersSO::double1;//  60
1426             else if (nLineThickness < 121)
1427                 eCodeIdx = WW8_BordersSO::double3;//  90
1428             else if (nLineThickness < 166)
1429                 eCodeIdx = WW8_BordersSO::double2;// 150
1430             else
1431                 eCodeIdx = WW8_BordersSO::double5;// 180
1432             break;
1433         case 17:
1434             if (nLineThickness < 46)
1435                 eCodeIdx = WW8_BordersSO::double0;//  22 Twips for us
1436             else if (nLineThickness < 72)
1437                 eCodeIdx = WW8_BordersSO::double7;//  52
1438             else if (nLineThickness < 137)
1439                 eCodeIdx = WW8_BordersSO::double4;//  90
1440             else
1441                 eCodeIdx = WW8_BordersSO::double6;// 180
1442         break;
1443         case 18:
1444         case 19: //Don't have thin thick thin, so use thick thin
1445             if (nLineThickness < 46)
1446                 eCodeIdx = WW8_BordersSO::double0;//  22 Twips for us
1447             else if (nLineThickness < 62)
1448                 eCodeIdx = WW8_BordersSO::double7;//  52
1449             else if (nLineThickness < 87)
1450                 eCodeIdx = WW8_BordersSO::double8;//  71
1451             else if (nLineThickness < 117)
1452                 eCodeIdx = WW8_BordersSO::double9;// 101
1453             else if (nLineThickness < 156)
1454                 eCodeIdx = WW8_BordersSO::double10;// 131
1455             else
1456                 eCodeIdx = WW8_BordersSO::double5;// 180
1457             break;
1458         case 20:
1459             if (nLineThickness < 46)
1460                 eCodeIdx = WW8_BordersSO::single1; //  20 Twips for us
1461             else
1462                 eCodeIdx = WW8_BordersSO::double1;//  60
1463             break;
1464         case 21:
1465             eCodeIdx = WW8_BordersSO::double1;//  60 Twips for us
1466             break;
1467         default:
1468             eCodeIdx = WW8_BordersSO::single0;
1469             break;
1470     }
1471 
1472     const WW8_BordersSO& rBorders = WW8_BordersSO::Get0x01LineMatch(eCodeIdx);
1473     SvxBorderLine aLine;
1474     aLine.SetOutWidth(rBorders.mnOut);
1475     aLine.SetInWidth(rBorders.mnIn);
1476     aLine.SetDistance(rBorders.mnDist);
1477 
1478     //No AUTO for borders as yet, so if AUTO, use BLACK
1479     if (nCol == 0)
1480         nCol = 1;
1481 
1482     aLine.SetColor(SwWW8ImplReader::GetCol(nCol));
1483 
1484     if (pSize)
1485         pSize[nWWIndex] = nLineThickness+nSpace;
1486 
1487     rBox.SetLine(&aLine, nOOIndex);
1488     rBox.SetDistance(nSpace, nOOIndex);
1489 
1490 }
1491 
Set1Border(bool bVer67,SvxBoxItem & rBox,const WW8_BRC & rBor,sal_uInt16 nOOIndex,sal_uInt16 nWWIndex,short * pSize=0)1492 void Set1Border(bool bVer67, SvxBoxItem &rBox, const WW8_BRC& rBor,
1493     sal_uInt16 nOOIndex, sal_uInt16 nWWIndex, short *pSize=0)
1494 {
1495     sal_uInt8 nCol;
1496     short nSpace, nIdx;
1497     short nLineThickness = rBor.DetermineBorderProperties(bVer67,&nSpace,&nCol,
1498         &nIdx);
1499 
1500     GetLineIndex(rBox, nLineThickness, nSpace, nCol, nIdx, nOOIndex, nWWIndex, pSize );
1501 
1502 }
1503 
lcl_IsBorder(bool bVer67,const WW8_BRC * pbrc,bool bChkBtwn=false)1504 bool lcl_IsBorder(bool bVer67, const WW8_BRC* pbrc, bool bChkBtwn = false)
1505 {
1506     if( bVer67  )
1507         return ( pbrc[WW8_TOP  ].aBits1[0] & 0x18 ) ||  // brcType  != 0
1508                ( pbrc[WW8_LEFT ].aBits1[0] & 0x18 ) ||
1509                ( pbrc[WW8_BOT  ].aBits1[0] & 0x18 ) ||
1510                ( pbrc[WW8_RIGHT].aBits1[0] & 0x18 ) ||
1511                ( bChkBtwn && ( pbrc[WW8_BETW ].aBits1[0] )) ||
1512                //can have dotted and dashed with a brcType of 0
1513                ( (pbrc[WW8_TOP  ].aBits1[0] & 0x07)+1 > 6) ||
1514                ( (pbrc[WW8_LEFT ].aBits1[0] & 0x07)+1 > 6) ||
1515                ( (pbrc[WW8_BOT  ].aBits1[0] & 0x07)+1 > 6) ||
1516                ( (pbrc[WW8_RIGHT].aBits1[0] & 0x07)+1 > 6) ||
1517                ( bChkBtwn && ( (pbrc[WW8_BETW ].aBits1[0] & 0x07)+1 > 6))
1518                ;
1519                 // Abfrage auf 0x1f statt 0x18 ist noetig, da zumindest einige
1520                 // WW-Versionen ( 6.0 US ) bei dotted brcType auf 0 setzen
1521     else
1522         return pbrc[WW8_TOP  ].aBits1[1] ||         // brcType  != 0
1523                pbrc[WW8_LEFT ].aBits1[1] ||
1524                pbrc[WW8_BOT  ].aBits1[1] ||
1525                pbrc[WW8_RIGHT].aBits1[1] ||
1526                (bChkBtwn && pbrc[WW8_BETW ].aBits1[1]);
1527 }
1528 
IsBorder(const WW8_BRC * pbrc,bool bChkBtwn) const1529 bool SwWW8ImplReader::IsBorder(const WW8_BRC* pbrc, bool bChkBtwn) const
1530 {
1531     return lcl_IsBorder(bVer67, pbrc, bChkBtwn);
1532 }
1533 
IsEmpty(bool bVer67) const1534 bool WW8_BRC::IsEmpty(bool bVer67) const
1535 {
1536     return (IsBlank() || IsZeroed(bVer67));
1537 }
1538 
IsBlank() const1539 bool WW8_BRC::IsBlank() const
1540 {
1541     return (aBits1[0] == 0xff && aBits1[1] == 0xff);
1542 }
1543 
IsZeroed(bool bVer67) const1544 bool WW8_BRC::IsZeroed(bool bVer67) const
1545 {
1546     return (!(bVer67 ? (aBits1[0] & 0x001f) : aBits1[1]));
1547 }
1548 
SetBorder(SvxBoxItem & rBox,const WW8_BRC * pbrc,short * pSizeArray,sal_uInt8 nSetBorders) const1549 bool SwWW8ImplReader::SetBorder(SvxBoxItem& rBox, const WW8_BRC* pbrc,
1550     short *pSizeArray, sal_uInt8 nSetBorders) const
1551 {
1552     bool bChange = false;
1553     static const sal_uInt16 aIdArr[ 10 ] =
1554     {
1555         WW8_TOP,    BOX_LINE_TOP,
1556         WW8_LEFT,   BOX_LINE_LEFT,
1557         WW8_RIGHT,  BOX_LINE_RIGHT,
1558         WW8_BOT,    BOX_LINE_BOTTOM,
1559         WW8_BETW,   BOX_LINE_BOTTOM
1560     };
1561 
1562     for( int i = 0, nEnd = 8; i < nEnd; i += 2 )
1563     {
1564         // ungueltige Borders ausfiltern
1565         const WW8_BRC& rB = pbrc[ aIdArr[ i ] ];
1566         if( !rB.IsEmpty(bVer67))
1567         {
1568             Set1Border(bVer67, rBox, rB, aIdArr[i+1], aIdArr[i], pSizeArray);
1569             bChange = true;
1570         }
1571         else if ( nSetBorders & (1 << aIdArr[i]) )
1572         {
1573             /*
1574             ##826##, ##653##
1575 
1576             If a style has borders set,and the para attributes attempt remove
1577             the borders, then this is perfectably acceptable, so we shouldn't
1578             ignore this blank entry
1579 
1580             nSetBorders has a bit set for each location that a sprm set a
1581             border, so with a sprm set, but no border, then disable the
1582             appropriate border
1583             */
1584             rBox.SetLine( 0, aIdArr[ i+1 ] );
1585         }
1586     }
1587     return bChange;
1588 }
1589 
1590 
SetShadow(SvxShadowItem & rShadow,const short * pSizeArray,const WW8_BRC * pbrc) const1591 bool SwWW8ImplReader::SetShadow(SvxShadowItem& rShadow, const short *pSizeArray,
1592     const WW8_BRC *pbrc) const
1593 {
1594     bool bRet = (
1595                 ( bVer67 ? (pbrc[WW8_RIGHT].aBits1[ 1 ] & 0x20 )
1596                          : (pbrc[WW8_RIGHT].aBits2[ 1 ] & 0x20 ) )
1597                 && (pSizeArray && pSizeArray[WW8_RIGHT])
1598                 );
1599     if (bRet)
1600     {
1601         rShadow.SetColor(Color(COL_BLACK));
1602 	//i120718
1603         short nVal = pbrc[WW8_RIGHT].DetermineBorderProperties(bVer67);
1604 	//End
1605         if (nVal < 0x10)
1606             nVal = 0x10;
1607         rShadow.SetWidth(nVal);
1608         rShadow.SetLocation(SVX_SHADOW_BOTTOMRIGHT);
1609         bRet = true;
1610     }
1611     return bRet;
1612 }
1613 
GetBorderDistance(const WW8_BRC * pbrc,Rectangle & rInnerDist) const1614 void SwWW8ImplReader::GetBorderDistance(const WW8_BRC* pbrc,
1615     Rectangle& rInnerDist) const
1616 {
1617     // 'dptSpace' is stored in 3 bits of 'Border Code (BRC)'
1618     if (bVer67)
1619     {
1620         rInnerDist = Rectangle(((pbrc[ 1 ].aBits1[1] >> 3) & 0x1f) * 20,
1621                                ((pbrc[ 0 ].aBits1[1] >> 3) & 0x1f) * 20,
1622                                ((pbrc[ 3 ].aBits1[1] >> 3) & 0x1f) * 20,
1623                                ((pbrc[ 2 ].aBits1[1] >> 3) & 0x1f) * 20 );
1624     }
1625     else
1626     {
1627         rInnerDist = Rectangle( (pbrc[ 1 ].aBits2[1]       & 0x1f) * 20,
1628                                 (pbrc[ 0 ].aBits2[1]       & 0x1f) * 20,
1629                                 (pbrc[ 3 ].aBits2[1]       & 0x1f) * 20,
1630                                 (pbrc[ 2 ].aBits2[1]       & 0x1f) * 20 );
1631     }
1632 }
1633 
1634 
SetFlyBordersShadow(SfxItemSet & rFlySet,const WW8_BRC * pbrc,short * pSizeArray) const1635 bool SwWW8ImplReader::SetFlyBordersShadow(SfxItemSet& rFlySet,
1636     const WW8_BRC *pbrc, short *pSizeArray) const
1637 {
1638     bool bShadowed = false;
1639     if (IsBorder(pbrc))
1640     {
1641         SvxBoxItem aBox( RES_BOX );
1642         SetBorder(aBox, pbrc, pSizeArray);
1643 
1644         rFlySet.Put( aBox );
1645 
1646         // fShadow
1647         SvxShadowItem aShadow( RES_SHADOW );
1648         if( SetShadow( aShadow, pSizeArray, pbrc ))
1649         {
1650             bShadowed = true;
1651             rFlySet.Put( aShadow );
1652         }
1653     }
1654     return bShadowed;
1655 }
1656 
1657 //-----------------------------------------
1658 //              APOs
1659 //-----------------------------------------
1660                             // fuer Berechnung der minimalen FrameSize
1661 #define MAX_BORDER_SIZE 210         // so breit ist max. der Border
1662 #define MAX_EMPTY_BORDER 10         // fuer +-1-Fehler, mindestens 1
1663 
FlySecur1(short & rSize,const bool bBorder)1664 static void FlySecur1(short& rSize, const bool bBorder)
1665 {
1666     const short nMin = MINFLY +
1667         (bBorder ? MAX_BORDER_SIZE : MAX_EMPTY_BORDER);
1668 
1669     if ( rSize < nMin )
1670         rSize = nMin;
1671 }
1672 
SetValSprm(sal_Int16 * pVar,WW8PLCFx_Cp_FKP * pPap,sal_uInt16 nId)1673 inline bool SetValSprm( sal_Int16* pVar, WW8PLCFx_Cp_FKP* pPap, sal_uInt16 nId )
1674 {
1675     const sal_uInt8* pS = pPap->HasSprm( nId );
1676     if( pS )
1677         *pVar = (sal_Int16)SVBT16ToShort( pS );
1678     return ( pS != 0 );
1679 }
1680 
SetValSprm(sal_Int16 * pVar,const WW8RStyle * pStyle,sal_uInt16 nId)1681 inline bool SetValSprm( sal_Int16* pVar, const WW8RStyle* pStyle, sal_uInt16 nId )
1682 {
1683     const sal_uInt8* pS = pStyle->HasParaSprm( nId );
1684     if( pS )
1685         *pVar = (sal_Int16)SVBT16ToShort( pS );
1686     return ( pS != 0 );
1687 }
1688 
1689 /*
1690 #i1930 revealed that sprm 0x360D as used in tables can affect the frame
1691 around the table. Its full structure is not fully understood as yet.
1692 */
ApplyTabPos(const WW8_TablePos * pTabPos)1693 void WW8FlyPara::ApplyTabPos(const WW8_TablePos *pTabPos)
1694 {
1695     if (pTabPos)
1696     {
1697         nSp26 = pTabPos->nSp26;
1698         nSp27 = pTabPos->nSp27;
1699         nSp29 = pTabPos->nSp29;
1700         nLeMgn = pTabPos->nLeMgn;
1701         nRiMgn = pTabPos->nRiMgn;
1702         nUpMgn = pTabPos->nUpMgn;
1703         nLoMgn = pTabPos->nLoMgn;
1704         nSp37 = pTabPos->nSp37;
1705     }
1706 }
1707 
WW8FlyPara(bool bIsVer67,const WW8FlyPara * pSrc)1708 WW8FlyPara::WW8FlyPara(bool bIsVer67, const WW8FlyPara* pSrc /* = 0 */)
1709 {
1710     if ( pSrc )
1711         memcpy( this, pSrc, sizeof( WW8FlyPara ) ); // Copy-Ctor
1712     else
1713     {
1714         memset( this, 0, sizeof( WW8FlyPara ) );    // Default-Ctor
1715         nSp37 = 2;                                  // Default: Umfluss
1716     }
1717     bVer67 = bIsVer67;
1718 }
1719 
operator ==(const WW8FlyPara & rSrc) const1720 bool WW8FlyPara::operator==(const WW8FlyPara& rSrc) const
1721 {
1722     /*
1723      Compare the parts that word seems to compare for equivalence.
1724      Interestingly being autoheight or absolute height (the & 0x7fff) doesn't
1725      matter to word e.g. #110507#
1726     */
1727     return
1728        (
1729          (nSp26 == rSrc.nSp26) &&
1730          (nSp27 == rSrc.nSp27) &&
1731          ((nSp45 & 0x7fff) == (rSrc.nSp45 & 0x7fff)) &&
1732          (nSp28 == rSrc.nSp28) &&
1733          (nLeMgn == rSrc.nLeMgn) &&
1734          (nRiMgn == rSrc.nRiMgn) &&
1735          (nUpMgn == rSrc.nUpMgn) &&
1736          (nLoMgn == rSrc.nLoMgn) &&
1737          (nSp29 == rSrc.nSp29) &&
1738          (nSp37 == rSrc.nSp37)
1739        );
1740 }
1741 
1742 // Read fuer normalen Text
Read(const sal_uInt8 * pSprm29,WW8PLCFx_Cp_FKP * pPap)1743 void WW8FlyPara::Read(const sal_uInt8* pSprm29, WW8PLCFx_Cp_FKP* pPap)
1744 {
1745     if (pSprm29)
1746         nOrigSp29 = *pSprm29;                           // PPC ( Bindung )
1747 
1748     const sal_uInt8* pS = 0;
1749     if( bVer67 )
1750     {
1751         SetValSprm( &nSp26, pPap, 26 ); // X-Position   //sprmPDxaAbs
1752         //set in me or in parent style
1753         mbVertSet |= SetValSprm( &nSp27, pPap, 27 );    // Y-Position   //sprmPDyaAbs
1754         SetValSprm( &nSp45, pPap, 45 ); // Hoehe        //sprmPWHeightAbs
1755         SetValSprm( &nSp28, pPap, 28 ); // Breite       //sprmPDxaWidth
1756         SetValSprm( &nLeMgn, pPap, 49 ); // L-Raender   //sprmPDxaFromText
1757         SetValSprm( &nRiMgn, pPap, 49 ); // R-Raender   //sprmPDxaFromText
1758         SetValSprm( &nUpMgn, pPap, 48 ); // U-Raender   //sprmPDyaFromText
1759         SetValSprm( &nLoMgn, pPap, 48 ); // D-Raender   //sprmPDyaFromText
1760 
1761         pS = pPap->HasSprm( 37 );                       //sprmPWr
1762         if( pS )
1763             nSp37 = *pS;
1764     }
1765     else
1766     {
1767         SetValSprm( &nSp26, pPap, 0x8418 ); // X-Position
1768         //set in me or in parent style
1769         mbVertSet |= SetValSprm( &nSp27, pPap, 0x8419 );    // Y-Position
1770         SetValSprm( &nSp45, pPap, 0x442B ); // Hoehe
1771         SetValSprm( &nSp28, pPap, 0x841A ); // Breite
1772         SetValSprm( &nLeMgn, pPap, 0x842F );    // L-Raender
1773         SetValSprm( &nRiMgn, pPap, 0x842F );    // R-Raender
1774         SetValSprm( &nUpMgn, pPap, 0x842E );    // U-Raender
1775         SetValSprm( &nLoMgn, pPap, 0x842E );    // D-Raender
1776 
1777         pS = pPap->HasSprm( 0x2423 );                               // Umfluss
1778         if( pS )
1779             nSp37 = *pS;
1780     }
1781 
1782     if( ::lcl_ReadBorders( bVer67, brc, pPap ))     // Umrandung
1783         bBorderLines = ::lcl_IsBorder( bVer67, brc );
1784 
1785     /*
1786      #i8798#
1787      Appears that with no dyaAbs set then the actual vert anchoring set is
1788      ignored and we remain relative to text, so if that is the case we are 0
1789      from para anchor, so we update the frame to have explicitly this type of
1790      anchoring
1791     */
1792     if (!mbVertSet)
1793         nSp29 = (nOrigSp29 & 0xCF) | 0x20;
1794     else
1795         nSp29 = nOrigSp29;
1796 }
1797 
ReadFull(const sal_uInt8 * pSprm29,SwWW8ImplReader * pIo)1798 void WW8FlyPara::ReadFull(const sal_uInt8* pSprm29, SwWW8ImplReader* pIo)
1799 {
1800     WW8PLCFMan* pPlcxMan = pIo->pPlcxMan;
1801     WW8PLCFx_Cp_FKP* pPap = pPlcxMan->GetPapPLCF();
1802 
1803     Read(pSprm29, pPap);    // Lies Apo-Parameter
1804 
1805     do{             // Block zum rausspringen
1806         if( nSp45 != 0 /* || nSp28 != 0 */ )
1807             break;                      // bGrafApo nur bei Hoehe automatisch
1808         if( pIo->pWwFib->fComplex )
1809             break;                      // (*pPap)++ geht bei FastSave schief
1810                                         // -> bei FastSave kein Test auf Grafik-APO
1811         SvStream* pIoStrm = pIo->pStrm;
1812         sal_uLong nPos = pIoStrm->Tell();
1813         WW8PLCFxSave1 aSave;
1814         pPlcxMan->GetPap()->Save( aSave );
1815         bGrafApo = false;
1816 
1817         do{             // Block zum rausspringen
1818 
1819             sal_uInt8 nTxt[2];
1820 
1821             pIoStrm->Read( nTxt, 2 );                   // lies Text
1822             if( nTxt[0] != 0x01 || nTxt[1] != 0x0d )// nur Grafik + CR ?
1823                 break;                              // Nein
1824 
1825             (*pPap)++;                              // Naechste Zeile
1826 
1827             // In APO ?
1828             //sprmPPc
1829             const sal_uInt8* pS = pPap->HasSprm( bVer67 ? 29 : 0x261B );
1830 
1831             // Nein -> Grafik-Apo
1832             if( !pS ){
1833                 bGrafApo = true;
1834                 break;                              // Ende des APO
1835             }
1836 
1837             ww::WordVersion eVer = pIo->GetFib().GetFIBVersion();
1838             WW8FlyPara *pNowStyleApo=0;
1839             sal_uInt16 nColl = pPap->GetIstd();
1840             ww::sti eSti = eVer < ww::eWW6 ? ww::GetCanonicalStiFromStc( static_cast< sal_uInt8 >(nColl) ) : static_cast<ww::sti>(nColl);
1841             while (eSti != ww::stiNil && 0 == (pNowStyleApo = pIo->pCollA[nColl].pWWFly))
1842             {
1843                 nColl = pIo->pCollA[nColl].nBase;
1844                 eSti = eVer < ww::eWW6 ? ww::GetCanonicalStiFromStc( static_cast< sal_uInt8 >(nColl) ) : static_cast<ww::sti>(nColl);
1845             }
1846 
1847             WW8FlyPara aF(bVer67, pNowStyleApo);
1848                                                 // Neuer FlaPara zum Vergleich
1849             aF.Read( pS, pPap );                // WWPara fuer neuen Para
1850             if( !( aF == *this ) )              // selber APO ? ( oder neuer ? )
1851                 bGrafApo = true;                // nein -> 1-zeiliger APO
1852                                                 //      -> Grafik-APO
1853         }
1854         while( 0 );                             // Block zum rausspringen
1855 
1856         pPlcxMan->GetPap()->Restore( aSave );
1857         pIoStrm->Seek( nPos );
1858     }while( 0 );                                    // Block zum rausspringen
1859 }
1860 
1861 
1862 // Read fuer Apo-Defs in Styledefs
Read(const sal_uInt8 * pSprm29,WW8RStyle * pStyle)1863 void WW8FlyPara::Read(const sal_uInt8* pSprm29, WW8RStyle* pStyle)
1864 {
1865     if (pSprm29)
1866         nOrigSp29 = *pSprm29;                           // PPC ( Bindung )
1867 
1868     const sal_uInt8* pS = 0;
1869     if (bVer67)
1870     {
1871         SetValSprm( &nSp26, pStyle, 26 );   // X-Position
1872         //set in me or in parent style
1873         mbVertSet |= SetValSprm(&nSp27, pStyle, 27);    // Y-Position
1874         SetValSprm( &nSp45, pStyle, 45 );   // Hoehe
1875         SetValSprm( &nSp28, pStyle, 28 );   // Breite
1876         SetValSprm( &nLeMgn,    pStyle, 49 );   // L-Raender
1877         SetValSprm( &nRiMgn,    pStyle, 49 );   // R-Raender
1878         SetValSprm( &nUpMgn,    pStyle, 48 );   // U-Raender
1879         SetValSprm( &nLoMgn,    pStyle, 48 );   // D-Raender
1880 
1881         pS = pStyle->HasParaSprm( 37 );             // Umfluss
1882         if( pS )
1883             nSp37 = *pS;
1884     }
1885     else
1886     {
1887         SetValSprm( &nSp26, pStyle, 0x8418 );   // X-Position
1888         //set in me or in parent style
1889         mbVertSet |= SetValSprm(&nSp27, pStyle, 0x8419);    // Y-Position
1890         SetValSprm( &nSp45, pStyle, 0x442B );   // Hoehe
1891         SetValSprm( &nSp28, pStyle, 0x841A );   // Breite
1892         SetValSprm( &nLeMgn, pStyle, 0x842F );  // L-Raender
1893         SetValSprm( &nRiMgn, pStyle, 0x842F );  // R-Raender
1894         SetValSprm( &nUpMgn, pStyle, 0x842E );  // U-Raender
1895         SetValSprm( &nLoMgn, pStyle, 0x842E );  // D-Raender
1896 
1897         pS = pStyle->HasParaSprm( 0x2423 );             // Umfluss
1898         if( pS )
1899             nSp37 = *pS;
1900     }
1901 
1902     if (::lcl_ReadBorders(bVer67, brc, 0, pStyle))      // Umrandung
1903         bBorderLines = ::lcl_IsBorder(bVer67, brc);
1904 
1905     /*
1906      #i8798#
1907      Appears that with no dyaAbs set then the actual vert anchoring set is
1908      ignored and we remain relative to text, so if that is the case we are 0
1909      from para anchor, so we update the frame to have explicitly this type of
1910      anchoring
1911     */
1912     if (!mbVertSet)
1913         nSp29 = (nOrigSp29 & 0xCF) | 0x20;
1914     else
1915         nSp29 = nOrigSp29;
1916 }
1917 
IsEmpty() const1918 bool WW8FlyPara::IsEmpty() const
1919 {
1920     WW8FlyPara aEmpty(bVer67);
1921     /*
1922      wr of 0 like 2 appears to me to be equivalent for checking here. See
1923      #107103# if wrong, so given that the empty is 2, if we are 0 then set
1924      empty to 0 to make 0 equiv to 2 for empty checking
1925     */
1926     ASSERT(aEmpty.nSp37 == 2, "this is not what we expect for nSp37");
1927     if (this->nSp37 == 0)
1928         aEmpty.nSp37 = 0;
1929     if (aEmpty == *this)
1930         return true;
1931     return false;
1932 }
1933 
1934 // OD 14.10.2003 #i18732# - changes made on behalf of CMC
WW8SwFlyPara(SwPaM & rPaM,SwWW8ImplReader & rIo,WW8FlyPara & rWW,const sal_uInt32 nWWPgTop,const sal_uInt32 nPgLeft,const sal_uInt32 nPgWidth,const sal_Int32 nIniFlyDx,const sal_Int32 nIniFlyDy)1935 WW8SwFlyPara::WW8SwFlyPara( SwPaM& rPaM,
1936                             SwWW8ImplReader& rIo,
1937                             WW8FlyPara& rWW,
1938                             const sal_uInt32 nWWPgTop,
1939                             const sal_uInt32 nPgLeft,
1940                             const sal_uInt32 nPgWidth,
1941                             const sal_Int32 nIniFlyDx,
1942                             const sal_Int32 nIniFlyDy )
1943 {
1944     (void) rPaM;
1945     (void) nPgLeft;
1946 
1947     memset( this, 0, sizeof( WW8SwFlyPara ) );  // Initialisieren
1948     nNewNettoWidth = MINFLY;                    // Minimum
1949 
1950     eSurround = ( rWW.nSp37 > 1 ) ? SURROUND_IDEAL : SURROUND_NONE;
1951     //#i119466 mapping "Around" wrap setting to "Parallel" for table
1952     const bool bIsTable = rIo.pPlcxMan->HasParaSprm(0x2416);
1953 	if (  bIsTable && rWW.nSp37 == 2 )
1954 		eSurround = SURROUND_PARALLEL;
1955 
1956     /*
1957      #95905#, #83307# seems to have gone away now, so reenable parallel
1958      wrapping support for frames in headers/footers. I don't know if we truly
1959      have an explicitly specified behaviour for these circumstances.
1960     */
1961 
1962     nHeight = rWW.nSp45;
1963     if( nHeight & 0x8000 )
1964     {
1965         nHeight &= 0x7fff;
1966         eHeightFix = ATT_MIN_SIZE;
1967     }
1968     else
1969         eHeightFix = ATT_FIX_SIZE;
1970 
1971     if( nHeight <= MINFLY )
1972     {                           // keine Angabe oder Stuss
1973         eHeightFix = ATT_MIN_SIZE;
1974         nHeight = MINFLY;
1975     }
1976 
1977     nWidth = nNettoWidth = rWW.nSp28;
1978     if( nWidth <= 10 )                              // Auto-Breite
1979     {
1980         bAutoWidth = true;
1981         rIo.maTracer.Log(sw::log::eAutoWidthFrame);
1982         nWidth = nNettoWidth =
1983             msword_cast<sal_Int16>((nPgWidth ? nPgWidth : 2268)); // 4 cm
1984     }
1985     if( nWidth <= MINFLY )
1986         nWidth = nNettoWidth = MINFLY;              // Minimale Breite
1987 
1988     eVAlign = text::VertOrientation::NONE;                            // Defaults
1989     eHAlign = text::HoriOrientation::NONE;
1990     nYPos = 0;
1991     nXPos = 0;
1992 
1993     nRiMgn = rWW.nRiMgn;
1994     nLeMgn = rWW.nLeMgn;
1995     nLoMgn = rWW.nLoMgn;
1996     nUpMgn = rWW.nUpMgn;
1997 
1998     /*
1999     See issue #i9178# for the 9 anchoring options, and make sure they stay
2000     working if you modify the anchoring logic here.
2001     */
2002 
2003     // Wenn der Fly links, rechts, oben oder unten aligned ist,
2004     // wird der aeussere Textabstand ignoriert, da sonst
2005     // der Fly an falscher Position landen wuerde
2006     // JP 18.11.98: Problematisch wird es nur bei Innen/Aussen
2007 
2008     // Bindung
2009     nYBind = (( rWW.nSp29 & 0x30 ) >> 4);
2010     // --> OD 2005-08-24 #i53725# - absolute positioned objects have to be
2011     // anchored at-paragraph to assure its correct anchor position.
2012     eAnchor = FLY_AT_PARA;
2013     // <--
2014     switch (nYBind)
2015     {
2016         case 0:     //relative to margin
2017             eVRel = text::RelOrientation::PAGE_PRINT_AREA;
2018             break;
2019         case 1:     //relative to page
2020             eVRel = text::RelOrientation::PAGE_FRAME;
2021             break;
2022         default:    //relative to text
2023             eVRel = text::RelOrientation::FRAME;
2024             break;
2025     }
2026 
2027 // OD 14.10.2003 #i18732#
2028     switch( rWW.nSp27 )             // besondere Y-Positionen ?
2029     {
2030         case -4:
2031             eVAlign = text::VertOrientation::TOP;
2032             if (nYBind < 2)
2033                 nUpMgn = 0;
2034             break;  // oben
2035         case -8:
2036             eVAlign = text::VertOrientation::CENTER;
2037             break;  // zentriert
2038         case -12:
2039             eVAlign = text::VertOrientation::BOTTOM;
2040             if (nYBind < 2)
2041                 nLoMgn = 0;
2042             break;  // unten
2043         default:
2044             nYPos = rWW.nSp27 + (short)nIniFlyDy;
2045             break;  // Korrekturen per Ini-Datei
2046     }
2047 
2048     switch( rWW.nSp26 )                 // besondere X-Positionen ?
2049     {
2050         case 0:
2051             eHAlign = text::HoriOrientation::LEFT;
2052             nLeMgn = 0;
2053             break;  // links
2054         case -4:
2055             eHAlign = text::HoriOrientation::CENTER;
2056             break;  // zentriert
2057         case -8:
2058             eHAlign = text::HoriOrientation::RIGHT;
2059             nRiMgn = 0;
2060             break;  // rechts
2061         case -12:
2062             eHAlign = text::HoriOrientation::LEFT;
2063             bToggelPos = true;
2064             break;  // innen
2065         case -16:
2066             eHAlign = text::HoriOrientation::RIGHT;
2067             bToggelPos = true;
2068             break;  // aussen
2069         default:
2070             nXPos = rWW.nSp26 + (short)nIniFlyDx;
2071             break;  // Korrekturen per Ini-Datei
2072     }
2073 
2074     nXBind = ( rWW.nSp29 & 0xc0 ) >> 6;
2075 // OD 14.10.2003 #i18732#
2076     switch (nXBind)           // X - Bindung -> Koordinatentransformation
2077     {
2078         case 0:     //relative to column
2079             eHRel = text::RelOrientation::FRAME;
2080             break;
2081         case 1:     //relative to margin
2082             eHRel = text::RelOrientation::PAGE_PRINT_AREA;
2083             break;
2084         default:    //relative to page
2085             eHRel = text::RelOrientation::PAGE_FRAME;
2086             break;
2087     }
2088 
2089     // --> OD 2004-12-06 #i36649# - adjustments for certain horizontal alignments
2090     // Note: These special adjustments found by an investigation of documents
2091     //       containing frames with different left/right border distances and
2092     //       distances to text. The outcome is some how strange.
2093     // Note: These adjustments causes wrong horizontal positions for frames,
2094     //       which are aligned inside|outside to page|margin on even pages,
2095     //       the left and right border distances are different.
2096     // --> OD 2005-01-19 #119176# - no adjustments possible, if frame has
2097     // automatic width.
2098     // determine left border distance
2099     sal_Int16 nLeBorderMgn( 0L );
2100     if ( !bAutoWidth )
2101     {
2102         sal_Int16 nTemp = rWW.brc[WW8_LEFT].DetermineBorderProperties(rWW.bVer67,
2103             &nLeBorderMgn);
2104         nLeBorderMgn = nLeBorderMgn + nTemp;
2105     }
2106     // determine right border distance
2107     sal_Int16 nRiBorderMgn( 0L );
2108     if ( !bAutoWidth )
2109     {
2110         sal_Int16 nTemp = rWW.brc[WW8_RIGHT].DetermineBorderProperties(rWW.bVer67,
2111             &nRiBorderMgn);
2112         nRiBorderMgn = nRiBorderMgn + nTemp;
2113     }
2114     if ( !bAutoWidth && eHAlign == text::HoriOrientation::LEFT && eHRel == text::RelOrientation::PAGE_FRAME )
2115     {
2116         // convert 'left to page' to
2117         // 'from left -<width>-<2*left border distance>-<right wrap distance>
2118         // to page text area'
2119         eHAlign = text::HoriOrientation::NONE;
2120         eHRel = text::RelOrientation::PAGE_PRINT_AREA;
2121         nXPos = -nWidth - (2*nLeBorderMgn) - rWW.nRiMgn;
2122         // re-set left wrap distance
2123         nLeMgn = rWW.nLeMgn;
2124     }
2125     else if ( !bAutoWidth && eHAlign == text::HoriOrientation::RIGHT && eHRel == text::RelOrientation::PAGE_FRAME )
2126     {
2127         // convert 'right to page' to
2128         // 'from left <right border distance-left border distance>+<left wrap distance>
2129         // to right page border'
2130         eHAlign = text::HoriOrientation::NONE;
2131         eHRel = text::RelOrientation::PAGE_RIGHT;
2132         nXPos = ( nRiBorderMgn - nLeBorderMgn ) + rWW.nLeMgn;
2133         // re-set right wrap distance
2134         nRiMgn = rWW.nRiMgn;
2135     }
2136     else if ( !bAutoWidth && eHAlign == text::HoriOrientation::LEFT && eHRel == text::RelOrientation::PAGE_PRINT_AREA )
2137     {
2138         // convert 'left to margin' to
2139         // 'from left -<left border distance> to page text area'
2140         eHAlign = text::HoriOrientation::NONE;
2141         eHRel = text::RelOrientation::PAGE_PRINT_AREA;
2142         nXPos = -nLeBorderMgn;
2143         // re-set left wrap distance
2144         nLeMgn = rWW.nLeMgn;
2145     }
2146     else if ( !bAutoWidth && eHAlign == text::HoriOrientation::RIGHT && eHRel == text::RelOrientation::PAGE_PRINT_AREA )
2147     {
2148         // convert 'right to margin' to
2149         // 'from left -<width>-<left border distance> to right page border'
2150         eHAlign = text::HoriOrientation::NONE;
2151         eHRel = text::RelOrientation::PAGE_RIGHT;
2152         nXPos = -nWidth - nLeBorderMgn;
2153         // re-set right wrap distance
2154         nRiMgn = rWW.nRiMgn;
2155     }
2156     else if (rWW.bBorderLines)
2157     // <--
2158     {
2159         /*
2160         #i582#
2161         Word has a curious bug where the offset stored do not take into
2162         account the internal distance from the corner both
2163         */
2164         sal_Int16 nLeLMgn = 0;
2165         sal_Int16 nTemp = rWW.brc[WW8_LEFT].DetermineBorderProperties(rWW.bVer67,
2166             &nLeLMgn);
2167         nLeLMgn = nLeLMgn + nTemp;
2168 
2169         if (nLeLMgn)
2170         {
2171             if (eHAlign == text::HoriOrientation::LEFT)
2172                 eHAlign = text::HoriOrientation::NONE;
2173             nXPos = nXPos - nLeLMgn;
2174         }
2175     }
2176 
2177     // --> OD 2007-07-03 #148498#
2178     // adjustments for certain vertical alignments
2179     if ( eVAlign == text::VertOrientation::NONE && eVRel == text::RelOrientation::PAGE_PRINT_AREA )
2180     {
2181         // convert "<X> from top page text area" to
2182         // "<X + page top margin> from page"
2183         eVRel = text::RelOrientation::PAGE_FRAME;
2184         nYPos = static_cast< sal_Int16 >( nYPos + nWWPgTop );
2185     }
2186     // <--
2187 
2188     FlySecur1( nWidth, rWW.bBorderLines );          // passen Raender ?
2189     FlySecur1( nHeight, rWW.bBorderLines );
2190 
2191 }
2192 
2193 // hat ein Fly in WW eine automatische Breite, dann muss das durch
2194 // nachtraegliches Anpassen der ( im SW festen ) Fly-Breite simuliert werden.
2195 // Dabei kann die Fly-Breite groesser oder kleiner werden, da der Default-Wert
2196 // ohne Wissen ueber den Inhalt eingesetzt wird.
BoxUpWidth(long nInWidth)2197 void WW8SwFlyPara::BoxUpWidth( long nInWidth )
2198 {
2199     if( bAutoWidth && nInWidth > nNewNettoWidth )
2200         nNewNettoWidth = nInWidth;
2201 };
2202 
2203 // Die Klasse WW8FlySet ist von SfxItemSet abgeleitet und stellt auch
2204 // im Prizip nicht mehr zur Verfuegung, ist aber fuer mich besser
2205 // zu handeln
2206 // WW8FlySet-ctor fuer Apos und Graf-Apos
WW8FlySet(SwWW8ImplReader & rReader,const WW8FlyPara * pFW,const WW8SwFlyPara * pFS,bool bGraf)2207 WW8FlySet::WW8FlySet(SwWW8ImplReader& rReader, const WW8FlyPara* pFW,
2208     const WW8SwFlyPara* pFS, bool bGraf)
2209     : SfxItemSet(rReader.rDoc.GetAttrPool(),RES_FRMATR_BEGIN,RES_FRMATR_END-1)
2210 {
2211     if (!rReader.mbNewDoc)
2212         Reader::ResetFrmFmtAttrs(*this);    // Abstand/Umrandung raus
2213                                             // Position
2214     Put(SvxFrameDirectionItem(FRMDIR_HORI_LEFT_TOP, RES_FRAMEDIR));
2215 
2216 /*Below can all go when we have from left in rtl mode*/
2217     SwTwips nXPos = pFS->nXPos;
2218     sal_Int16 eHRel = pFS->eHRel;
2219     rReader.MiserableRTLGraphicsHack(nXPos, pFS->nWidth, pFS->eHAlign, eHRel);
2220 /*Above can all go when we have from left in rtl mode*/
2221     Put( SwFmtHoriOrient(nXPos, pFS->eHAlign, pFS->eHRel, pFS->bToggelPos ));
2222     Put( SwFmtVertOrient( pFS->nYPos, pFS->eVAlign, pFS->eVRel ) );
2223 
2224     if (pFS->nLeMgn || pFS->nRiMgn)     // Raender setzen
2225         Put(SvxLRSpaceItem(pFS->nLeMgn, pFS->nRiMgn, 0, 0, RES_LR_SPACE));
2226 
2227     if (pFS->nUpMgn || pFS->nLoMgn)
2228         Put(SvxULSpaceItem(pFS->nUpMgn, pFS->nLoMgn, RES_UL_SPACE));
2229 
2230     //we no longer need to hack around the header/footer problems
2231     Put(SwFmtSurround(pFS->eSurround));
2232 
2233     short aSizeArray[5]={0};
2234     rReader.SetFlyBordersShadow(*this,(const WW8_BRC*)pFW->brc,&aSizeArray[0]);
2235 
2236     // der 5. Parameter ist immer 0, daher geht beim Cast nix verloren
2237 
2238     // OD 2004-05-18 #i27767#
2239     // --> OD 2004-10-18 #i35017# - constant name has changed
2240     Put( SwFmtWrapInfluenceOnObjPos(
2241                 text::WrapInfluenceOnPosition::ONCE_SUCCESSIVE ) );
2242     // <--
2243 
2244     if( !bGraf )
2245     {
2246         Put( SwFmtAnchor(pFS->eAnchor) );
2247         // Groesse einstellen
2248 
2249         //Ordinarily with frames, the border width and spacing is
2250         //placed outside the frame, making it larger. With these
2251         //types of frames, the left right thickness and space makes
2252         //it wider, but the top bottom spacing and border thickness
2253         //is placed inside.
2254         Put( SwFmtFrmSize( pFS->eHeightFix, pFS->nWidth +
2255             aSizeArray[WW8_LEFT] + aSizeArray[WW8_RIGHT],
2256             pFS->nHeight));
2257     }
2258 }
2259 
2260 // WW8FlySet-ctor fuer zeichengebundene Grafiken
WW8FlySet(SwWW8ImplReader & rReader,const SwPaM * pPaM,const WW8_PIC & rPic,long nWidth,long nHeight)2261 WW8FlySet::WW8FlySet( SwWW8ImplReader& rReader, const SwPaM* pPaM,
2262     const WW8_PIC& rPic, long nWidth, long nHeight )
2263     : SfxItemSet(rReader.rDoc.GetAttrPool(),RES_FRMATR_BEGIN,RES_FRMATR_END-1)
2264 {
2265     Init(rReader, pPaM);
2266 
2267     Put(SvxFrameDirectionItem(FRMDIR_HORI_LEFT_TOP, RES_FRAMEDIR));
2268 
2269     short aSizeArray[5]={0};
2270     /*
2271     If we have set borders then in word the graphic is displaced from the left
2272     and top the width of the borders of those sides, and then the shadow
2273     itself is drawn to the bottom and right of the displaced graphic.  In word
2274     the total size is that of the graphic plus the borders, plus the total
2275     shadow around all edges, for this translation the top and left shadow
2276     region is translated spacing around the graphic to those sides, and the
2277     bottom and right shadow size is added to the graphic size.
2278     */
2279     if (rReader.SetFlyBordersShadow( *this, rPic.rgbrc, &aSizeArray[0]))
2280     {
2281         Put(SvxLRSpaceItem( aSizeArray[WW8_LEFT], 0, 0, 0, RES_LR_SPACE ) );
2282         Put(SvxULSpaceItem( aSizeArray[WW8_TOP], 0, RES_UL_SPACE ));
2283         aSizeArray[WW8_RIGHT]*=2;
2284         aSizeArray[WW8_BOT]*=2;
2285     }
2286 
2287     Put( SwFmtFrmSize( ATT_FIX_SIZE, nWidth+aSizeArray[WW8_LEFT]+
2288         aSizeArray[WW8_RIGHT], nHeight+aSizeArray[WW8_TOP]
2289         + aSizeArray[WW8_BOT]) );
2290 }
2291 
Init(const SwWW8ImplReader & rReader,const SwPaM * pPaM)2292 void WW8FlySet::Init(const SwWW8ImplReader& rReader, const SwPaM* pPaM)
2293 {
2294     if (!rReader.mbNewDoc)
2295         Reader::ResetFrmFmtAttrs(*this);  // Abstand/Umrandung raus
2296 
2297     Put(SvxLRSpaceItem(RES_LR_SPACE)); //inline writer ole2 objects start with 0.2cm l/r
2298     SwFmtAnchor aAnchor(FLY_AS_CHAR);
2299 
2300     aAnchor.SetAnchor(pPaM->GetPoint());
2301     Put(aAnchor);
2302 
2303     //The horizontal default is on the baseline, the vertical is centered
2304     //around the character center it appears
2305     if (rReader.maSectionManager.CurrentSectionIsVertical())
2306         Put(SwFmtVertOrient(0, text::VertOrientation::CHAR_CENTER,text::RelOrientation::CHAR));
2307     else
2308         Put(SwFmtVertOrient(0, text::VertOrientation::TOP, text::RelOrientation::FRAME));
2309 }
2310 
WW8DupProperties(SwDoc & rDoc,SwWW8FltControlStack * pStk)2311 WW8DupProperties::WW8DupProperties(SwDoc &rDoc, SwWW8FltControlStack *pStk)
2312     : pCtrlStck(pStk),
2313     aChrSet(rDoc.GetAttrPool(), RES_CHRATR_BEGIN, RES_CHRATR_END - 1 ),
2314     aParSet(rDoc.GetAttrPool(), RES_PARATR_BEGIN, RES_PARATR_END - 1 )
2315 {
2316     //Close any open character properties and duplicate them inside the
2317     //first table cell
2318     sal_uInt16 nCnt = static_cast< sal_uInt16 >(pCtrlStck->Count());
2319     for (sal_uInt16 i=0; i < nCnt; i++)
2320     {
2321         const SwFltStackEntry* pEntry = (*pCtrlStck)[ i ];
2322         if(pEntry->bLocked)
2323         {
2324             if (isCHRATR(pEntry->pAttr->Which()))
2325             {
2326                 aChrSet.Put( *pEntry->pAttr );
2327 
2328             }
2329             else if (isPARATR(pEntry->pAttr->Which()))
2330             {
2331                 aParSet.Put( *pEntry->pAttr );
2332             }
2333         }
2334     }
2335 }
2336 
Insert(const SwPosition & rPos)2337 void WW8DupProperties::Insert(const SwPosition &rPos)
2338 {
2339     const SfxItemSet *pSet=&aChrSet;
2340     for(int i=0;i<2;i++)
2341     {
2342         if (i==1)
2343             pSet = &aParSet;
2344 
2345         if( pSet->Count() )
2346         {
2347             SfxItemIter aIter( *pSet );
2348             const SfxPoolItem* pItem = aIter.GetCurItem();
2349             do
2350             {
2351                 pCtrlStck->NewAttr(rPos, *pItem);
2352             }while( !aIter.IsAtEnd() && 0 != ( pItem = aIter.NextItem() ) );
2353         }
2354     }
2355 }
2356 
MoveInsideFly(const SwFrmFmt * pFlyFmt)2357 void SwWW8ImplReader::MoveInsideFly(const SwFrmFmt *pFlyFmt)
2358 {
2359     WW8DupProperties aDup(rDoc,pCtrlStck);
2360 
2361     pCtrlStck->SetAttr(*pPaM->GetPoint(), 0, false);
2362 
2363     // Setze Pam in den FlyFrame
2364     const SwFmtCntnt& rCntnt = pFlyFmt->GetCntnt();
2365     ASSERT( rCntnt.GetCntntIdx(), "Kein Inhalt vorbereitet." );
2366     pPaM->GetPoint()->nNode = rCntnt.GetCntntIdx()->GetIndex() + 1;
2367     pPaM->GetPoint()->nContent.Assign( pPaM->GetCntntNode(), 0 );
2368 
2369     aDup.Insert(*pPaM->GetPoint());
2370 }
2371 
MoveOutsideFly(SwFrmFmt * pFlyFmt,const SwPosition & rPos,bool bTableJoin)2372 SwTwips SwWW8ImplReader::MoveOutsideFly(SwFrmFmt *pFlyFmt,
2373     const SwPosition &rPos, bool bTableJoin)
2374 {
2375     SwTwips nRetWidth = 0;
2376     // Alle Attribute schliessen, da sonst Attribute entstehen koennen,
2377     // die aus Flys rausragen
2378     WW8DupProperties aDup(rDoc,pCtrlStck);
2379     pCtrlStck->SetAttr(*pPaM->GetPoint(), 0, false);
2380 
2381     /*
2382     #i1291
2383     If this fly frame consists entirely of one table inside a frame
2384     followed by an empty paragraph then we want to delete the empty
2385     paragraph so as to get the frame to autoshrink to the size of the
2386     table to emulate words behaviour closer.
2387     */
2388     if (bTableJoin)
2389     {
2390         const SwNodeIndex* pNodeIndex = pFlyFmt->GetCntnt().
2391             GetCntntIdx();
2392         if (pNodeIndex)
2393         {
2394             SwNodeIndex aIdx( *pNodeIndex, 1 ),
2395             aEnd( *pNodeIndex->GetNode().EndOfSectionNode() );
2396 
2397             if (aIdx < aEnd)
2398             {
2399                 if(aIdx.GetNode().IsTableNode())
2400                 {
2401                     SwTableNode *pTable = aIdx.GetNode().GetTableNode();
2402                     aIdx = *aIdx.GetNode().EndOfSectionNode();
2403                     aIdx++;
2404                     if ( (aIdx < aEnd) && aIdx.GetNode().IsTxtNode() )
2405                     {
2406                         SwTxtNode *pNd = aIdx.GetNode().GetTxtNode();
2407                         aIdx++;
2408                         if (aIdx == aEnd && pNd && !pNd->GetTxt().Len())
2409                         {
2410                             rDoc.DelFullPara( *pPaM );
2411 
2412                             SwTable& rTable = pTable->GetTable();
2413                             SwFrmFmt* pTblFmt = rTable.GetFrmFmt();
2414 
2415                             if (pTblFmt)
2416                             {
2417                                 SwFmtFrmSize aSize = pTblFmt->GetFrmSize();
2418                                 aSize.SetHeightSizeType(ATT_MIN_SIZE);
2419                                 aSize.SetHeight(MINLAY);
2420                                 pFlyFmt->SetFmtAttr(aSize);
2421                                 pTblFmt->SetFmtAttr(SwFmtHoriOrient(0,text::HoriOrientation::FULL));
2422                                 nRetWidth = aSize.GetWidth();
2423                             }
2424                         }
2425                     }
2426                 }
2427             }
2428         }
2429     }
2430 
2431     *pPaM->GetPoint() = rPos;
2432     aDup.Insert(*pPaM->GetPoint());
2433     return nRetWidth;
2434 }
2435 
ConstructApo(const ApoTestResults & rApo,const WW8_TablePos * pTabPos)2436 WW8FlyPara *SwWW8ImplReader::ConstructApo(const ApoTestResults &rApo,
2437     const WW8_TablePos *pTabPos)
2438 {
2439     WW8FlyPara *pRet = 0;
2440     ASSERT(rApo.HasFrame() || pTabPos,
2441         "If no frame found, *MUST* be in a table");
2442 
2443     pRet = new WW8FlyPara(bVer67, rApo.mpStyleApo);
2444 
2445     // APO-Parameter ermitteln und Test auf bGrafApo
2446     if (rApo.HasFrame())
2447         pRet->ReadFull(rApo.mpSprm29, this);
2448 
2449     pRet->ApplyTabPos(pTabPos);
2450 
2451     if (pRet->IsEmpty())
2452         delete pRet, pRet = 0;
2453     return pRet;
2454 }
2455 
IsDropCap()2456 bool SwWW8ImplReader::IsDropCap()
2457 {
2458     // Find the DCS (Drop Cap Specifier) for the paragraph
2459     // if does not exist or if the first three bits are 0
2460     // then there is no dropcap on the paragraph
2461     WW8PLCFx_Cp_FKP *pPap = pPlcxMan ? pPlcxMan->GetPapPLCF() : 0;
2462     if (pPap)
2463     {
2464         const sal_uInt8 *pDCS;
2465         if (bVer67)
2466             pDCS = pPap->HasSprm(46);
2467         else
2468             pDCS = pPlcxMan->GetPapPLCF()->HasSprm(0x442C);
2469         if(pDCS)
2470         {
2471             short nDCS = SVBT16ToShort( pDCS );
2472             if((nDCS | 7) != 0)
2473                 return true;
2474         }
2475     }
2476     return false;
2477 }
2478 
StartApo(const ApoTestResults & rApo,const WW8_TablePos * pTabPos)2479 bool SwWW8ImplReader::StartApo(const ApoTestResults &rApo,
2480     const WW8_TablePos *pTabPos)
2481 {
2482     if (0 == (pWFlyPara = ConstructApo(rApo, pTabPos)))
2483         return false;
2484 
2485     // --> OD 2007-07-03 #148498#
2486     // <WW8SwFlyPara> constructor has changed - new 4th parameter
2487     // containing WW8 page top margin.
2488     pSFlyPara = new WW8SwFlyPara( *pPaM, *this, *pWFlyPara,
2489                                   maSectionManager.GetWWPageTopMargin(),
2490                                   maSectionManager.GetPageLeft(),
2491                                   maSectionManager.GetTextAreaWidth(),
2492                                   nIniFlyDx, nIniFlyDy);
2493     // <--
2494 
2495     // If this paragraph is a Dropcap set the flag and we will deal with it later
2496     if (IsDropCap())
2497     {
2498         bDropCap = true;
2499         pAktItemSet = new SfxItemSet( rDoc.GetAttrPool(), RES_CHRATR_BEGIN, RES_PARATR_END - 1 );
2500         return false;
2501     }
2502 
2503     if( !pWFlyPara->bGrafApo )
2504     {
2505 
2506         // Innerhalb des GrafApo muessen Textattribute ignoriert werden, da
2507         // sie sonst auf den folgenden Zeilen landen.  Der Rahmen wird nur
2508         // eingefuegt, wenn er *nicht* nur zum Positionieren einer einzelnen
2509         // Grafik dient.  Ist es ein Grafik-Rahmen, dann werden pWFlyPara und
2510         // pSFlyPara behalten und die
2511         // daraus resultierenden Attribute beim Einfuegen der Grafik auf die
2512         // Grafik angewendet.
2513 
2514         WW8FlySet aFlySet(*this, pWFlyPara, pSFlyPara, false);
2515 
2516         pSFlyPara->pFlyFmt = rDoc.MakeFlySection( pSFlyPara->eAnchor,
2517             pPaM->GetPoint(), &aFlySet );
2518         ASSERT(pSFlyPara->pFlyFmt->GetAnchor().GetAnchorId() ==
2519             pSFlyPara->eAnchor, "Not the anchor type requested!");
2520 
2521         if (pSFlyPara->pFlyFmt)
2522         {
2523             if (!pDrawModel)
2524                 GrafikCtor();
2525 
2526             SdrObject* pOurNewObject = CreateContactObject(pSFlyPara->pFlyFmt);
2527             pWWZOrder->InsertTextLayerObject(pOurNewObject);
2528         }
2529 
2530         if (FLY_AS_CHAR != pSFlyPara->eAnchor)
2531         {
2532             pAnchorStck->AddAnchor(*pPaM->GetPoint(),pSFlyPara->pFlyFmt);
2533         }
2534 
2535         // merke Pos im Haupttext
2536         pSFlyPara->pMainTextPos = new SwPosition( *pPaM->GetPoint() );
2537 
2538         //remove fltanchors, otherwise they will be closed inside the
2539         //frame, which makes no sense, restore them after the frame is
2540         //closed
2541         pSFlyPara->pOldAnchorStck = pAnchorStck;
2542         pAnchorStck = new SwWW8FltAnchorStack(&rDoc, nFieldFlags);
2543 
2544         MoveInsideFly(pSFlyPara->pFlyFmt);
2545 
2546         // 1) ReadText() wird nicht wie beim W4W-Reader rekursiv aufgerufen,
2547         //    da die Laenge des Apo zu diesen Zeitpunkt noch nicht feststeht,
2548         //    ReadText() diese Angabe aber braucht.
2549         // 2) Der CtrlStck wird nicht neu erzeugt.
2550         //    die Char-Attribute laufen weiter ( AErger mit SW-Attributen )
2551         //    Paraattribute muessten am Ende jeden Absatzes zurueckgesetzt
2552         //    sein, d.h. es duerften am Absatzende keine Paraattribute
2553         //    auf dem Stack liegen
2554     }
2555     return true;
2556 }
2557 
JoinNode(const SwPosition & rPos,const SwNode & rNode)2558 void wwSectionManager::JoinNode(const SwPosition &rPos, const SwNode &rNode)
2559 {
2560     if ((!maSegments.empty()) && (maSegments.back().maStart == rPos.nNode))
2561         maSegments.back().maStart = SwNodeIndex(rNode);
2562 }
2563 
JoinNode(SwPaM & rPam,bool bStealAttr)2564 bool SwWW8ImplReader::JoinNode(SwPaM &rPam, bool bStealAttr)
2565 {
2566     bool bRet = false;
2567     rPam.GetPoint()->nContent = 0;          // an den Anfang der Zeile gehen
2568 
2569     SwNodeIndex aPref(rPam.GetPoint()->nNode, -1);
2570 
2571     if (SwTxtNode* pNode = aPref.GetNode().GetTxtNode())
2572     {
2573         maSectionManager.JoinNode(*rPam.GetPoint(), aPref.GetNode());
2574         rPam.GetPoint()->nNode = aPref;
2575         rPam.GetPoint()->nContent.Assign(pNode, pNode->GetTxt().Len());
2576         if (bStealAttr)
2577             pCtrlStck->StealAttr(rPam.GetPoint());
2578 
2579         pNode->JoinNext();
2580 
2581         bRet = true;
2582     }
2583     return bRet;
2584 }
2585 
StopApo()2586 void SwWW8ImplReader::StopApo()
2587 {
2588     ASSERT(pWFlyPara, "no pWFlyPara to close");
2589     if (!pWFlyPara)
2590         return;
2591     if (pWFlyPara->bGrafApo)
2592     {
2593         // Grafik-Rahmen, der *nicht* eingefuegt wurde leeren Absatz incl.
2594         // Attributen entfernen
2595         JoinNode(*pPaM, true);
2596 
2597     }
2598     else
2599     {
2600         if (!pSFlyPara->pMainTextPos || !pWFlyPara)
2601         {
2602             ASSERT( pSFlyPara->pMainTextPos, "StopApo: pMainTextPos ist 0" );
2603             ASSERT( pWFlyPara, "StopApo: pWFlyPara ist 0" );
2604             return;
2605         }
2606 
2607         /*
2608         #104920#
2609         What we are doing with this temporary nodeindex is as follows: The
2610         stack of attributes normally only places them into the document when
2611         the current insertion point has passed them by. Otherwise the end
2612         point of the attribute gets pushed along with the insertion point. The
2613         insertion point is moved and the properties committed during
2614         MoveOutsideFly. We also may want to remove the final paragraph in the
2615         frame, but we need to wait until the properties for that frame text
2616         have been committed otherwise they will be lost. So we first get a
2617         handle to the last the filter inserted. After the attributes are
2618         committed, if that paragraph exists we join it with the para after it
2619         that comes with the frame by default so that as normal we don't end up
2620         with one more paragraph than we wanted.
2621         */
2622         SwNodeIndex aPref(pPaM->GetPoint()->nNode, -1);
2623 
2624         SwTwips nNewWidth =
2625             MoveOutsideFly(pSFlyPara->pFlyFmt, *pSFlyPara->pMainTextPos);
2626         if (nNewWidth)
2627             pSFlyPara->BoxUpWidth(nNewWidth);
2628 
2629         Color aBg(0xFE, 0xFF, 0xFF, 0xFF);  //Transparent by default
2630 
2631         if (SwTxtNode* pNd = aPref.GetNode().GetTxtNode())
2632         {
2633             /*
2634             #i582#/#114238#
2635             Take the last paragraph background colour and fill the frame with
2636             it.  Otherwise, make it transparent, this appears to be how MSWord
2637             works
2638             */
2639             const SfxPoolItem &rItm = pNd->SwCntntNode::GetAttr(RES_BACKGROUND);
2640             const SvxBrushItem &rBrush = (const SvxBrushItem&)(rItm);
2641             if (rBrush.GetColor().GetColor() != COL_AUTO)
2642                 aBg = rBrush.GetColor();
2643 
2644             //Get rid of extra empty paragraph
2645             pNd->JoinNext();
2646         }
2647 
2648         pSFlyPara->pFlyFmt->SetFmtAttr(SvxBrushItem(aBg, RES_BACKGROUND));
2649 
2650         DeleteAnchorStk();
2651         pAnchorStck = pSFlyPara->pOldAnchorStck;
2652 
2653         // Ist die Fly-Breite durch eine innenliegende Grafik vergroessert
2654         // worden ( bei automatischer Breite des Flys ), dann muss die Breite
2655         // des SW-Flys entsprechend umgesetzt werden, da der SW keine
2656         // automatische Breite kennt.
2657         if( pSFlyPara->nNewNettoWidth > MINFLY )    // BoxUpWidth ?
2658         {
2659             long nW = pSFlyPara->nNewNettoWidth;
2660             nW += pSFlyPara->nWidth - pSFlyPara->nNettoWidth;   // Rand dazu
2661             pSFlyPara->pFlyFmt->SetFmtAttr(
2662                 SwFmtFrmSize( pSFlyPara->eHeightFix, nW, pSFlyPara->nHeight ) );
2663         }
2664         /*
2665         #83307# Word set *no* width meaning its an automatic width. The
2666         SwFlyPara reader will have already set a fallback width of the
2667         printable regions width, so we should reuse it. Despite the related
2668         problems with layout addressed with a hack in WW8FlyPara's constructor
2669         #i27204# Added AutoWidth setting. Left the old CalculateFlySize in place
2670         so that if the user unselects autowidth, the width doesn't max out
2671         */
2672         else if( !pWFlyPara->nSp28 )
2673         {
2674             using namespace sw::util;
2675             SfxItemSet aFlySet( pSFlyPara->pFlyFmt->GetAttrSet() );
2676 
2677             SwFmtFrmSize aSize(ItemGet<SwFmtFrmSize>(aFlySet, RES_FRM_SIZE));
2678 
2679             aFlySet.ClearItem(RES_FRM_SIZE);
2680 
2681             CalculateFlySize(aFlySet, pSFlyPara->pMainTextPos->nNode,
2682                 pSFlyPara->nWidth);
2683 
2684             nNewWidth = ItemGet<SwFmtFrmSize>(aFlySet, RES_FRM_SIZE).GetWidth();
2685 
2686             aSize.SetWidth(nNewWidth);
2687             aSize.SetWidthSizeType(ATT_VAR_SIZE);
2688 
2689             pSFlyPara->pFlyFmt->SetFmtAttr(aSize);
2690         }
2691 
2692         delete pSFlyPara->pMainTextPos, pSFlyPara->pMainTextPos = 0;
2693 
2694 // Damit die Frames bei Einfuegen in existierendes Doc erzeugt werden,
2695 // wird in fltshell.cxx beim Setzen des FltAnchor-Attributes
2696 // pFlyFrm->MakeFrms() gerufen
2697 
2698     }
2699 
2700     //#i8062#
2701     if (pSFlyPara && pSFlyPara->pFlyFmt)
2702         pFmtOfJustInsertedApo = pSFlyPara->pFlyFmt;
2703 
2704     DELETEZ( pSFlyPara );
2705     DELETEZ( pWFlyPara );
2706 }
2707 
2708 // TestSameApo() beantwortet die Frage, ob es dasselbe APO oder ein neues ist
TestSameApo(const ApoTestResults & rApo,const WW8_TablePos * pTabPos)2709 bool SwWW8ImplReader::TestSameApo(const ApoTestResults &rApo,
2710     const WW8_TablePos *pTabPos)
2711 {
2712     if( !pWFlyPara )
2713     {
2714         ASSERT( pWFlyPara, " Wo ist mein pWFlyPara ? " );
2715         return true;
2716     }
2717 
2718     // Es muss ein kompletter Vergleich ( ausser Borders ) stattfinden, um
2719     // alle Kombinationen Style / Hart richtig einzuordnen. Deshalb wird ein
2720     // temporaerer WW8FlyPara angelegt ( abh. ob Style oder nicht ), darauf
2721     // die harten Attrs angewendet, und dann verglichen
2722 
2723     // Zum Vergleich
2724     WW8FlyPara aF(bVer67, rApo.mpStyleApo);
2725     // WWPara fuer akt. Para
2726     if (rApo.HasFrame())
2727         aF.Read(rApo.mpSprm29, pPlcxMan->GetPapPLCF());
2728     aF.ApplyTabPos(pTabPos);
2729 
2730     return aF == *pWFlyPara;
2731 }
2732 
2733 /***************************************************************************
2734 #       Attribut - Verwaltung
2735 #**************************************************************************/
2736 
NewAttr(const SfxPoolItem & rAttr,const bool bFirstLineOfStSet,const bool bLeftIndentSet)2737 void SwWW8ImplReader::NewAttr( const SfxPoolItem& rAttr,
2738                                const bool bFirstLineOfStSet,
2739                                const bool bLeftIndentSet )
2740 {
2741     if( !bNoAttrImport ) // zum Ignorieren von Styles beim Doc-Einfuegen
2742     {
2743         if (pAktColl)
2744         {
2745             ASSERT(rAttr.Which() != RES_FLTR_REDLINE, "redline in style!");
2746             pAktColl->SetFmtAttr(rAttr);
2747         }
2748         else if (pAktItemSet)
2749         {
2750             pAktItemSet->Put(rAttr);
2751         }
2752         else if (rAttr.Which() == RES_FLTR_REDLINE)
2753         {
2754             mpRedlineStack->open(*pPaM->GetPoint(), rAttr);
2755         }
2756         else
2757         {
2758             pCtrlStck->NewAttr(*pPaM->GetPoint(), rAttr);
2759             // --> OD 2010-05-06 #i103711#
2760             if ( bFirstLineOfStSet )
2761             {
2762                 const SwNode* pNd = &(pPaM->GetPoint()->nNode.GetNode());
2763                 maTxtNodesHavingFirstLineOfstSet.insert( pNd );
2764             }
2765             // <--
2766             // --> OD 2010-05-11 #i105414#
2767             if ( bLeftIndentSet )
2768             {
2769                 const SwNode* pNd = &(pPaM->GetPoint()->nNode.GetNode());
2770                 maTxtNodesHavingLeftIndentSet.insert( pNd );
2771             }
2772             // <--
2773         }
2774 
2775         if (mpPostProcessAttrsInfo && mpPostProcessAttrsInfo->mbCopy)
2776             mpPostProcessAttrsInfo->mItemSet.Put(rAttr);
2777     }
2778 }
2779 
2780 // holt Attribut aus der FmtColl / Stack / Doc
GetFmtAttr(sal_uInt16 nWhich)2781 const SfxPoolItem* SwWW8ImplReader::GetFmtAttr( sal_uInt16 nWhich )
2782 {
2783     const SfxPoolItem* pRet = 0;
2784     if (pAktColl)
2785         pRet = &(pAktColl->GetFmtAttr(nWhich));
2786     else if (pAktItemSet)
2787     {
2788         pRet = pAktItemSet->GetItem(nWhich);
2789         if (!pRet)
2790             pRet = pStandardFmtColl ? &(pStandardFmtColl->GetFmtAttr(nWhich)) : 0;
2791         if (!pRet)
2792             pRet = &rDoc.GetAttrPool().GetDefaultItem(nWhich);
2793     }
2794     else if (pPlcxMan && pPlcxMan->GetDoingDrawTextBox())
2795     {
2796         pRet = pCtrlStck->GetStackAttr(*pPaM->GetPoint(), nWhich);
2797         if (!pRet)
2798         {
2799             if (nAktColl < nColls && pCollA[nAktColl].pFmt &&
2800                 pCollA[nAktColl].bColl)
2801             {
2802                 pRet = &(pCollA[nAktColl].pFmt->GetFmtAttr(nWhich));
2803             }
2804         }
2805         if (!pRet)
2806             pRet = pStandardFmtColl ? &(pStandardFmtColl->GetFmtAttr(nWhich)) : 0;
2807         if (!pRet)
2808             pRet = &rDoc.GetAttrPool().GetDefaultItem(nWhich);
2809     }
2810     else
2811         pRet = pCtrlStck->GetFmtAttr(*pPaM->GetPoint(), nWhich);
2812     return pRet;
2813 }
2814 
2815 /***************************************************************************
2816 #       eigentliche Attribute
2817 #
2818 # Die Methoden erhalten die Token-Id und die Laenge der noch folgenden
2819 # Parameter gemaess Tabelle in WWScan.cxx als Parameter
2820 #**************************************************************************/
2821 
2822 /***************************************************************************
2823 #  Spezial WW - Attribute
2824 #**************************************************************************/
2825 
Read_Special(sal_uInt16,const sal_uInt8 * pData,short nLen)2826 void SwWW8ImplReader::Read_Special(sal_uInt16, const sal_uInt8* pData, short nLen)
2827 {
2828     if( nLen < 0 )
2829     {
2830         bSpec = false;
2831         return;
2832     }
2833     bSpec = ( *pData != 0 );
2834 }
2835 
2836 // Read_Obj wird fuer fObj und fuer fOle2 benutzt !
Read_Obj(sal_uInt16,const sal_uInt8 * pData,short nLen)2837 void SwWW8ImplReader::Read_Obj(sal_uInt16 , const sal_uInt8* pData, short nLen)
2838 {
2839     if( nLen < 0 )
2840         bObj = false;
2841     else
2842     {
2843         bObj = 0 != *pData;
2844 
2845         if( bObj && nPicLocFc && bEmbeddObj )
2846             nObjLocFc = nPicLocFc;
2847     }
2848 }
2849 
Read_PicLoc(sal_uInt16,const sal_uInt8 * pData,short nLen)2850 void SwWW8ImplReader::Read_PicLoc(sal_uInt16 , const sal_uInt8* pData, short nLen )
2851 {
2852     if( nLen < 0 )
2853     {
2854         nPicLocFc = 0;
2855         bSpec = false;  // Stimmt das immer ?
2856     }
2857     else
2858     {
2859         nPicLocFc = SVBT32ToUInt32( pData );
2860         bSpec = true;
2861 
2862         if( bObj && nPicLocFc && bEmbeddObj )
2863             nObjLocFc = nPicLocFc;
2864     }
2865 }
2866 
2867 
Read_POutLvl(sal_uInt16,const sal_uInt8 * pData,short nLen)2868 void SwWW8ImplReader::Read_POutLvl(sal_uInt16, const sal_uInt8* pData, short nLen )
2869 {
2870     if ( nLen < 0 )
2871     {
2872         pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_PARATR_OUTLINELEVEL );
2873         return;
2874     }
2875 
2876     if ( pAktColl != NULL )
2877     {
2878         SwWW8StyInf* pSI = GetStyle( nAktColl );
2879         if ( pSI != NULL )
2880         {
2881             pSI->mnWW8OutlineLevel =
2882                     static_cast< sal_uInt8 >( ( pData ? *pData : 0 ) );
2883             NewAttr( SfxUInt16Item( RES_PARATR_OUTLINELEVEL, SwWW8StyInf::WW8OutlineLevelToOutlinelevel( pSI->mnWW8OutlineLevel ) ) );
2884         }
2885     }
2886     else if ( pPaM != NULL )
2887     {
2888         const sal_uInt8 nOutlineLevel =
2889                 SwWW8StyInf::WW8OutlineLevelToOutlinelevel( static_cast< sal_uInt8 >( ( pData ? *pData : 0 ) ) );
2890         NewAttr( SfxUInt16Item( RES_PARATR_OUTLINELEVEL, nOutlineLevel ) );
2891     }
2892 }
2893 
2894 
Read_Symbol(sal_uInt16,const sal_uInt8 * pData,short nLen)2895 void SwWW8ImplReader::Read_Symbol(sal_uInt16, const sal_uInt8* pData, short nLen )
2896 {
2897     if( !bIgnoreText )
2898     {
2899         if( nLen < 0 )
2900         {
2901             //otherwise disable after we print the char
2902             if (pPlcxMan && pPlcxMan->GetDoingDrawTextBox())
2903                 pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_CHRATR_FONT );
2904             bSymbol = false;
2905         }
2906         else
2907         {
2908             // Make new Font-Atribut
2909             // (will be closed in SwWW8ImplReader::ReadChars() )
2910 
2911             //Will not be added to the charencoding stack, for styles the real
2912             //font setting will be put in as the styles charset, and for plain
2913             //text encoding for symbols is moot. Drawing boxes will check bSymbol
2914             //themselves so they don't need to add it to the stack either.
2915             if (SetNewFontAttr(SVBT16ToShort( pData ), false, RES_CHRATR_FONT))
2916             {
2917                 if( bVer67 )
2918                 {
2919                     cSymbol = ByteString::ConvertToUnicode(
2920                         *(sal_Char*)(pData+2), RTL_TEXTENCODING_MS_1252 );
2921                 }
2922                 else
2923                     cSymbol = SVBT16ToShort( pData+2 );
2924                 bSymbol = true;
2925             }
2926         }
2927     }
2928 }
2929 
GetStyle(sal_uInt16 nColl) const2930 SwWW8StyInf *SwWW8ImplReader::GetStyle(sal_uInt16 nColl) const
2931 {
2932     return nColl < nColls ? &pCollA[nColl] : 0;
2933 }
2934 
2935 /***************************************************************************
2936 #  Zeichen - Attribute
2937 #**************************************************************************/
2938 
2939 // Read_BoldUsw fuer Italic, Bold, Kapitaelchen, Versalien, durchgestrichen,
2940 // Contour und Shadow
Read_BoldUsw(sal_uInt16 nId,const sal_uInt8 * pData,short nLen)2941 void SwWW8ImplReader::Read_BoldUsw( sal_uInt16 nId, const sal_uInt8* pData, short nLen )
2942 {
2943     const int nContigiousWestern = 8;
2944     const int nWestern = nContigiousWestern + 1;
2945     const int nEastern = 2;
2946     const int nIds = nWestern + nEastern;
2947     static const sal_uInt16 nEndIds[ nIds ] =
2948     {
2949         RES_CHRATR_WEIGHT,          RES_CHRATR_POSTURE,
2950         RES_CHRATR_CROSSEDOUT,      RES_CHRATR_CONTOUR,
2951         RES_CHRATR_SHADOWED,        RES_CHRATR_CASEMAP,
2952         RES_CHRATR_CASEMAP,         RES_CHRATR_HIDDEN,
2953 
2954         RES_CHRATR_CROSSEDOUT,
2955 
2956         RES_CHRATR_CJK_WEIGHT,      RES_CHRATR_CJK_POSTURE
2957     };
2958 
2959     ww::WordVersion eVersion = pWwFib->GetFIBVersion();
2960 
2961     sal_uInt8 nI;
2962     // die Attribut-Nr fuer "doppelt durchgestrichen" tanzt aus der Reihe
2963     if (0x2A53 == nId)
2964         nI = nContigiousWestern;               // The out of sequence western id
2965     else
2966     {
2967         // The contiguous western ids
2968         if (eVersion <= ww::eWW2)
2969             nI = static_cast< sal_uInt8 >(nId - 60);
2970         else if (eVersion < ww::eWW8)
2971             nI = static_cast< sal_uInt8 >(nId - 85);
2972         else
2973             nI = static_cast< sal_uInt8 >(nId - 0x0835);
2974     }
2975 
2976     sal_uInt16 nMask = 1 << nI;
2977 
2978     if (nLen < 0)
2979     {
2980         pCtrlStck->SetAttr( *pPaM->GetPoint(), nEndIds[ nI ] );
2981         // reset the CJK Weight and Posture, because they are the same as their
2982         // western equivalents in word
2983         if (nI < 2)
2984             pCtrlStck->SetAttr( *pPaM->GetPoint(), nEndIds[ nWestern + nI ] );
2985         pCtrlStck->SetToggleAttr(nI, false);
2986         return;
2987     }
2988     // Wert: 0 = Aus, 1 = An, 128 = Wie Style, 129 entgegen Style
2989     bool bOn = *pData & 1;
2990     SwWW8StyInf* pSI = GetStyle(nAktColl);
2991     if (pPlcxMan && eVersion > ww::eWW2)
2992     {
2993         const sal_uInt8 *pCharIstd =
2994             pPlcxMan->GetChpPLCF()->HasSprm(bVer67 ? 80 : 0x4A30);
2995         if (pCharIstd)
2996             pSI = GetStyle(SVBT16ToShort(pCharIstd));
2997     }
2998 
2999     if( pAktColl )                          // StyleDef -> Flags merken
3000     {
3001         if (pSI)
3002         {
3003             // The style based on has Bit 7 set ?
3004             if (
3005                 pSI->nBase < nColls && (*pData & 0x80) &&
3006                 (pCollA[pSI->nBase].n81Flags & nMask)
3007                )
3008             {
3009                 bOn = !bOn;                     // umdrehen
3010             }
3011 
3012             if (bOn)
3013                 pSI->n81Flags |= nMask;         // Flag setzen
3014             else
3015                 pSI->n81Flags &= ~nMask;        // Flag loeschen
3016        }
3017     }
3018     else
3019     {
3020 
3021         // im Text -> Flags abfragen
3022         if( *pData & 0x80 )                 // Bit 7 gesetzt ?
3023         {
3024             if (pSI && pSI->n81Flags & nMask)       // und in StyleDef an ?
3025                 bOn = !bOn;                 // dann invertieren
3026             // am Stack vermerken, das dieses ein Toggle-Attribut ist
3027             pCtrlStck->SetToggleAttr(nI, true);
3028         }
3029     }
3030 
3031     SetToggleAttr( nI, bOn );
3032 }
3033 
Read_Bidi(sal_uInt16,const sal_uInt8 * pData,short nLen)3034 void SwWW8ImplReader::Read_Bidi(sal_uInt16, const sal_uInt8* pData, short nLen)
3035 {
3036 	if( nLen < 0 )	//Property end
3037 	{
3038 		bBidi = sal_False;
3039 		pCtrlStck->SetAttr(*pPaM->GetPoint(),RES_CHRATR_BIDIRTL);
3040 	}
3041 	else	//Property start
3042 	{
3043 		bBidi = sal_True;
3044 		sal_uInt8 nBidi = SVBT8ToByte( pData );
3045 		NewAttr( SfxInt16Item( RES_CHRATR_BIDIRTL, (nBidi!=0)? 1 : 0 ) );
3046 	}
3047 }
3048 
3049 // Read_BoldUsw for BiDi Italic, Bold
Read_BoldBiDiUsw(sal_uInt16 nId,const sal_uInt8 * pData,short nLen)3050 void SwWW8ImplReader::Read_BoldBiDiUsw(sal_uInt16 nId, const sal_uInt8* pData,
3051     short nLen)
3052 {
3053     static const sal_uInt16 nEndIds[2] =
3054     {
3055         RES_CHRATR_CTL_WEIGHT, RES_CHRATR_CTL_POSTURE,
3056     };
3057 
3058     sal_uInt8 nI;
3059     ww::WordVersion eVersion = pWwFib->GetFIBVersion();
3060     if (eVersion <= ww::eWW2)
3061         nI = static_cast< sal_uInt8 >(nId - 80);
3062     else if (eVersion < ww::eWW8)
3063         nI = static_cast< sal_uInt8 >(nId - 111);
3064     else
3065         nI = static_cast< sal_uInt8 >(nId - 0x085C);
3066 
3067     ASSERT(nI <= 1, "not happening");
3068     if (nI > 1)
3069         return;
3070 
3071     sal_uInt16 nMask = 1 << nI;
3072 
3073     if( nLen < 0 )
3074     {
3075         pCtrlStck->SetAttr(*pPaM->GetPoint(),nEndIds[nI]);
3076         pCtrlStck->SetToggleBiDiAttr(nI, false);
3077         return;
3078     }
3079     bool bOn = *pData & 1;
3080     SwWW8StyInf* pSI = GetStyle(nAktColl);
3081     if (pPlcxMan)
3082     {
3083         const sal_uInt8 *pCharIstd =
3084             pPlcxMan->GetChpPLCF()->HasSprm(bVer67 ? 80 : 0x4A30);
3085         if (pCharIstd)
3086             pSI = GetStyle(SVBT16ToShort(pCharIstd));
3087     }
3088 
3089     if (pAktColl && eVersion > ww::eWW2)        // StyleDef -> Flags merken
3090     {
3091         if (pSI)
3092         {
3093             if( pSI->nBase < nColls             // Style Based on
3094                 && ( *pData & 0x80 )            // Bit 7 gesetzt ?
3095                 && ( pCollA[pSI->nBase].n81BiDiFlags & nMask ) ) // BasisMaske ?
3096                     bOn = !bOn;                     // umdrehen
3097 
3098             if( bOn )
3099                 pSI->n81BiDiFlags |= nMask;         // Flag setzen
3100             else
3101                 pSI->n81BiDiFlags &= ~nMask;        // Flag loeschen
3102         }
3103     }
3104     else
3105     {
3106 
3107         // im Text -> Flags abfragen
3108         if (*pData & 0x80)                  // Bit 7 gesetzt ?
3109         {
3110             if (pSI && pSI->n81BiDiFlags & nMask) // und in StyleDef an ?
3111                 bOn = !bOn;                     // dann invertieren
3112             // am Stack vermerken, das dieses ein Toggle-Attribut ist
3113             pCtrlStck->SetToggleBiDiAttr(nI, true);
3114         }
3115     }
3116 
3117     SetToggleBiDiAttr(nI, bOn);
3118 }
3119 
SetToggleBiDiAttr(sal_uInt8 nAttrId,bool bOn)3120 void SwWW8ImplReader::SetToggleBiDiAttr(sal_uInt8 nAttrId, bool bOn)
3121 {
3122     switch (nAttrId)
3123     {
3124         case 0:
3125             {
3126                 SvxWeightItem aAttr( bOn ? WEIGHT_BOLD : WEIGHT_NORMAL, RES_CHRATR_WEIGHT );
3127                 aAttr.SetWhich( RES_CHRATR_CTL_WEIGHT );
3128                 NewAttr( aAttr );
3129             }
3130             break;
3131         case 1:
3132             {
3133                 SvxPostureItem aAttr( bOn ? ITALIC_NORMAL : ITALIC_NONE, RES_CHRATR_POSTURE );
3134                 aAttr.SetWhich( RES_CHRATR_CTL_POSTURE );
3135                 NewAttr( aAttr );
3136             }
3137             break;
3138         default:
3139             ASSERT(sal_False, "Unhandled unknown bidi toggle attribute");
3140             break;
3141 
3142     }
3143 }
3144 
SetToggleAttr(sal_uInt8 nAttrId,bool bOn)3145 void SwWW8ImplReader::SetToggleAttr(sal_uInt8 nAttrId, bool bOn)
3146 {
3147     switch (nAttrId)
3148     {
3149         case 0:
3150             {
3151                 SvxWeightItem aAttr( bOn ? WEIGHT_BOLD : WEIGHT_NORMAL, RES_CHRATR_WEIGHT );
3152                 NewAttr( aAttr );
3153                 aAttr.SetWhich( RES_CHRATR_CJK_WEIGHT );
3154                 NewAttr( aAttr );
3155             }
3156             break;
3157         case 1:
3158             {
3159                 SvxPostureItem aAttr( bOn ? ITALIC_NORMAL : ITALIC_NONE, RES_CHRATR_POSTURE );
3160                 NewAttr( aAttr );
3161                 aAttr.SetWhich( RES_CHRATR_CJK_POSTURE );
3162                 NewAttr( aAttr );
3163             }
3164             break;
3165         case 2:
3166             NewAttr(SvxCrossedOutItem(bOn ? STRIKEOUT_SINGLE : STRIKEOUT_NONE, RES_CHRATR_CROSSEDOUT));
3167             break;
3168         case 3:
3169             NewAttr( SvxContourItem( bOn, RES_CHRATR_CONTOUR ) );
3170             break;
3171         case 4:
3172             NewAttr( SvxShadowedItem( bOn, RES_CHRATR_SHADOWED ) );
3173             break;
3174         case 5:
3175             NewAttr( SvxCaseMapItem( bOn ? SVX_CASEMAP_KAPITAELCHEN
3176                                               : SVX_CASEMAP_NOT_MAPPED, RES_CHRATR_CASEMAP ) );
3177             break;
3178         case 6:
3179             NewAttr( SvxCaseMapItem( bOn ? SVX_CASEMAP_VERSALIEN
3180                                              : SVX_CASEMAP_NOT_MAPPED, RES_CHRATR_CASEMAP ) );
3181             break;
3182         case 7:
3183             NewAttr(SvxCharHiddenItem(bOn, RES_CHRATR_HIDDEN));
3184             break;
3185         case 8:
3186             NewAttr( SvxCrossedOutItem( bOn ? STRIKEOUT_DOUBLE
3187                                                 : STRIKEOUT_NONE, RES_CHRATR_CROSSEDOUT ) );
3188             break;
3189         default:
3190             ASSERT(sal_False, "Unhandled unknown toggle attribute");
3191             break;
3192     }
3193 }
3194 
_ChkToggleAttr(sal_uInt16 nOldStyle81Mask,sal_uInt16 nNewStyle81Mask)3195 void SwWW8ImplReader::_ChkToggleAttr( sal_uInt16 nOldStyle81Mask,
3196                                         sal_uInt16 nNewStyle81Mask )
3197 {
3198     sal_uInt16 i = 1, nToggleAttrFlags = pCtrlStck->GetToggleAttrFlags();
3199     for (sal_uInt8 n = 0; n < 7; ++n, i <<= 1)
3200     {
3201         if (
3202             (i & nToggleAttrFlags) &&
3203             ((i & nOldStyle81Mask) != (i & nNewStyle81Mask))
3204            )
3205         {
3206             SetToggleAttr(n, (i & nOldStyle81Mask));
3207         }
3208     }
3209 }
3210 
_ChkToggleBiDiAttr(sal_uInt16 nOldStyle81Mask,sal_uInt16 nNewStyle81Mask)3211 void SwWW8ImplReader::_ChkToggleBiDiAttr( sal_uInt16 nOldStyle81Mask,
3212                                         sal_uInt16 nNewStyle81Mask )
3213 {
3214     sal_uInt16 i = 1, nToggleAttrFlags = pCtrlStck->GetToggleBiDiAttrFlags();
3215     for (sal_uInt8 n = 0; n < 7; ++n, i <<= 1)
3216     {
3217         if (
3218             (i & nToggleAttrFlags) &&
3219             ((i & nOldStyle81Mask) != (i & nNewStyle81Mask))
3220            )
3221         {
3222             SetToggleBiDiAttr(n, (i & nOldStyle81Mask));
3223         }
3224     }
3225 }
3226 
Read_SubSuper(sal_uInt16,const sal_uInt8 * pData,short nLen)3227 void SwWW8ImplReader::Read_SubSuper( sal_uInt16, const sal_uInt8* pData, short nLen )
3228 {
3229     if( nLen < 0 ){
3230         pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_CHRATR_ESCAPEMENT );
3231         return;
3232     }
3233 
3234     short nEs;
3235     sal_uInt8 nProp;
3236     switch( *pData )
3237     {
3238         case 1:
3239             nEs = DFLT_ESC_AUTO_SUPER;
3240             nProp = DFLT_ESC_PROP;
3241             break;
3242         case 2:
3243             nEs = DFLT_ESC_AUTO_SUB;
3244             nProp = DFLT_ESC_PROP;
3245             break;
3246         default:
3247             nEs = 0;
3248             nProp = 100;
3249             break;
3250     }
3251     NewAttr( SvxEscapementItem( nEs, nProp, RES_CHRATR_ESCAPEMENT ) );
3252 }
3253 
ContainsSingleInlineGraphic(const SwPaM & rRegion)3254 SwFrmFmt *SwWW8ImplReader::ContainsSingleInlineGraphic(const SwPaM &rRegion)
3255 {
3256     /*
3257     #92489# & #92946#
3258     For inline graphics and objects word has a hacked in feature to use
3259     subscripting to force the graphic into a centered position on the line, so
3260     we must check when applying sub/super to see if it the subscript range
3261     contains only a single graphic, and if that graphic is anchored as
3262     FLY_AS_CHAR and then we can change its anchoring to centered in the line.
3263     */
3264     SwFrmFmt *pRet=0;
3265     SwNodeIndex aBegin(rRegion.Start()->nNode);
3266     xub_StrLen nBegin(rRegion.Start()->nContent.GetIndex());
3267     SwNodeIndex aEnd(rRegion.End()->nNode);
3268     xub_StrLen nEnd(rRegion.End()->nContent.GetIndex());
3269     const SwTxtNode* pTNd;
3270     const SwTxtAttr* pTFlyAttr;
3271     if (
3272          aBegin == aEnd && nBegin == nEnd - 1 &&
3273          0 != (pTNd = aBegin.GetNode().GetTxtNode()) &&
3274          0 != (pTFlyAttr = pTNd->GetTxtAttrForCharAt(nBegin, RES_TXTATR_FLYCNT))
3275        )
3276     {
3277         const SwFmtFlyCnt& rFly = pTFlyAttr->GetFlyCnt();
3278         SwFrmFmt *pFlyFmt = rFly.GetFrmFmt();
3279         if (pFlyFmt &&
3280             (FLY_AS_CHAR == pFlyFmt->GetAnchor().GetAnchorId()))
3281         {
3282             pRet = pFlyFmt;
3283         }
3284     }
3285     return pRet;
3286 }
3287 
ConvertSubToGraphicPlacement()3288 bool SwWW8ImplReader::ConvertSubToGraphicPlacement()
3289 {
3290     /*
3291     #92489# & #92946#
3292     For inline graphics and objects word has a hacked in feature to use
3293     subscripting to force the graphic into a centered position on the line, so
3294     we must check when applying sub/super to see if it the subscript range
3295     contains only a single graphic, and if that graphic is anchored as
3296     FLY_AS_CHAR and then we can change its anchoring to centered in the line.
3297     */
3298     bool bIsGraphicPlacementHack = false;
3299     sal_uInt16 nPos;
3300     if (pCtrlStck->GetFmtStackAttr(RES_CHRATR_ESCAPEMENT, &nPos))
3301     {
3302         SwPaM aRegion(*pPaM->GetPoint());
3303 
3304         SwFltStackEntry aEntry = *((*pCtrlStck)[nPos]);
3305         aEntry.SetEndPos(*pPaM->GetPoint());
3306 
3307         SwFrmFmt *pFlyFmt = 0;
3308         if (
3309              aEntry.MakeRegion(&rDoc,aRegion,false) &&
3310              0 != (pFlyFmt = ContainsSingleInlineGraphic(aRegion))
3311            )
3312         {
3313             pCtrlStck->DeleteAndDestroy(nPos);
3314             pFlyFmt->SetFmtAttr(SwFmtVertOrient(0, text::VertOrientation::CHAR_CENTER, text::RelOrientation::CHAR));
3315             bIsGraphicPlacementHack = true;
3316         }
3317     }
3318     return bIsGraphicPlacementHack;
3319 }
3320 
Read_SubSuperProp(sal_uInt16,const sal_uInt8 * pData,short nLen)3321 void SwWW8ImplReader::Read_SubSuperProp( sal_uInt16, const sal_uInt8* pData, short nLen )
3322 {
3323     if( nLen < 0 )
3324     {
3325         if (!ConvertSubToGraphicPlacement())
3326             pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_CHRATR_ESCAPEMENT );
3327         return;
3328     }
3329 
3330     ww::WordVersion eVersion = pWwFib->GetFIBVersion();
3331 
3332     // Font-Position in HalfPoints
3333     short nPos = eVersion <= ww::eWW2 ? *pData : SVBT16ToShort( pData );
3334     sal_Int32 nPos2 = nPos * ( 10 * 100 );      // HalfPoints in 100 * tw
3335     const SvxFontHeightItem* pF
3336         = (const SvxFontHeightItem*)GetFmtAttr(RES_CHRATR_FONTSIZE);
3337     ASSERT(pF, "Expected to have the fontheight available here");
3338 
3339 	// #i59022: Check ensure nHeight != 0. Div by zero otherwise.
3340     sal_Int32 nHeight = 240;
3341 	if (pF != NULL && pF->GetHeight() != 0)
3342 		nHeight = pF->GetHeight();
3343     nPos2 /= nHeight;                       // ... nun in % ( gerundet )
3344     if( nPos2 > 100 )                       // zur Sicherheit
3345         nPos2 = 100;
3346     if( nPos2 < -100 )
3347         nPos2 = -100;
3348     SvxEscapementItem aEs( (short)nPos2, 100, RES_CHRATR_ESCAPEMENT );
3349     NewAttr( aEs );
3350 }
3351 
Read_Underline(sal_uInt16,const sal_uInt8 * pData,short nLen)3352 void SwWW8ImplReader::Read_Underline( sal_uInt16, const sal_uInt8* pData, short nLen )
3353 {
3354     FontUnderline eUnderline = UNDERLINE_NONE;
3355     bool bWordLine = false;
3356     if( pData )
3357     {
3358         // Parameter:  0 = none,    1 = single,  2 = by Word,
3359                     // 3 = double,  4 = dotted,  5 = hidden
3360                     // 6 = thick,   7 = dash,    8 = dot(not used)
3361                     // 9 = dotdash 10 = dotdotdash 11 = wave
3362 
3363 
3364         // pruefe auf Sonderfall "fett+unterstrichen"
3365         bool bAlsoBold = /*( 6 == b )*/ false;
3366         // erst mal ggfs. *bold* einschalten!
3367         if( bAlsoBold )
3368         {
3369             sal_uInt8 nOn = 1;
3370             Read_BoldUsw( 0x0835, &nOn, nLen );
3371             eUnderline = UNDERLINE_SINGLE;
3372         }
3373         else
3374         {
3375             switch( *pData )
3376             {
3377             case 2: bWordLine = true;       // no break;
3378             case 1: eUnderline = (FontUnderline)UNDERLINE_SINGLE;       break;
3379             case 3: eUnderline = (FontUnderline)UNDERLINE_DOUBLE;       break;
3380             case 4: eUnderline = (FontUnderline)UNDERLINE_DOTTED;       break;
3381             case 7: eUnderline = (FontUnderline)UNDERLINE_DASH;         break;
3382             case 9: eUnderline = (FontUnderline)UNDERLINE_DASHDOT;      break;
3383             case 10:eUnderline = (FontUnderline)UNDERLINE_DASHDOTDOT;   break;
3384             case 6: eUnderline = (FontUnderline)UNDERLINE_BOLD;         break;
3385             case 11:eUnderline = (FontUnderline)UNDERLINE_WAVE;         break;
3386             case 20:eUnderline = (FontUnderline)UNDERLINE_BOLDDOTTED;   break;
3387             case 23:eUnderline = (FontUnderline)UNDERLINE_BOLDDASH;     break;
3388             case 39:eUnderline = (FontUnderline)UNDERLINE_LONGDASH;     break;
3389             case 55:eUnderline = (FontUnderline)UNDERLINE_BOLDLONGDASH; break;
3390             case 25:eUnderline = (FontUnderline)UNDERLINE_BOLDDASHDOT;  break;
3391             case 26:eUnderline = (FontUnderline)UNDERLINE_BOLDDASHDOTDOT;break;
3392             case 27:eUnderline = (FontUnderline)UNDERLINE_BOLDWAVE;     break;
3393             case 43:eUnderline = (FontUnderline)UNDERLINE_DOUBLEWAVE;   break;
3394             }
3395         }
3396     }
3397 
3398     // dann Stack ggfs. verwursteln und exit!
3399     if( nLen < 0 )
3400     {
3401         pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_CHRATR_UNDERLINE );
3402         pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_CHRATR_WORDLINEMODE );
3403     }
3404     else
3405     {
3406         NewAttr( SvxUnderlineItem( eUnderline, RES_CHRATR_UNDERLINE ));
3407         if( bWordLine )
3408             NewAttr(SvxWordLineModeItem(true, RES_CHRATR_WORDLINEMODE));
3409     }
3410 }
3411 
3412 /*
3413 //The last three vary, measurements, rotation ? ?
3414 NoBracket   78 CA 06 -  02 00 00 02 34 52
3415 ()          78 CA 06 -  02 01 00 02 34 52
3416 []          78 CA 06 -  02 02 00 02 34 52
3417 <>          78 CA 06 -  02 03 00 02 34 52
3418 {}          78 CA 06 -  02 04 00 02 34 52
3419 */
Read_DoubleLine_Rotate(sal_uInt16,const sal_uInt8 * pData,short nLen)3420 void SwWW8ImplReader::Read_DoubleLine_Rotate( sal_uInt16, const sal_uInt8* pData,
3421     short nLen )
3422 {
3423     if( nLen < 0 ) // close the tag
3424     {
3425         pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_CHRATR_TWO_LINES );
3426         pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_CHRATR_ROTATE );
3427     }
3428     else if( pData && 6 == nLen )
3429     {
3430         switch( *pData )
3431         {
3432         case 2:                     // double line
3433             {
3434                 sal_Unicode cStt = 0, cEnd = 0;
3435                 switch( SVBT16ToShort( pData+1 ) )
3436                 {
3437                 case 1: cStt = '(', cEnd = ')'; break;
3438                 case 2: cStt = '[', cEnd = ']'; break;
3439                 case 3: cStt = '<', cEnd = '>'; break;
3440                 case 4: cStt = '{', cEnd = '}'; break;
3441                 }
3442                 NewAttr( SvxTwoLinesItem( sal_True, cStt, cEnd, RES_CHRATR_TWO_LINES ));
3443             }
3444             break;
3445 
3446         case 1:                         // rotated characters
3447             {
3448                 bool bFitToLine = 0 != *(pData+1);
3449                 NewAttr( SvxCharRotateItem( 900, bFitToLine, RES_CHRATR_ROTATE ));
3450             }
3451             break;
3452         }
3453     }
3454 }
3455 
Read_TxtColor(sal_uInt16,const sal_uInt8 * pData,short nLen)3456 void SwWW8ImplReader::Read_TxtColor( sal_uInt16, const sal_uInt8* pData, short nLen )
3457 {
3458     //Has newer colour variant, ignore this old variant
3459     if (!bVer67 && pPlcxMan && pPlcxMan->GetChpPLCF()->HasSprm(0x6870))
3460         return;
3461 
3462     if( nLen < 0 )
3463         pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_CHRATR_COLOR );
3464     else
3465     {
3466         sal_uInt8 b = *pData;            // Parameter: 0 = Auto, 1..16 Farben
3467 
3468         if( b > 16 )                // unbekannt -> Black
3469             b = 0;
3470 
3471         NewAttr( SvxColorItem(Color(GetCol(b)), RES_CHRATR_COLOR));
3472         if (pAktColl && pStyles)
3473             pStyles->bTxtColChanged = true;
3474     }
3475 }
3476 
BGRToRGB(sal_uInt32 nColor)3477 sal_uInt32 wwUtility::BGRToRGB(sal_uInt32 nColor)
3478 {
3479     sal_uInt8
3480         r(static_cast<sal_uInt8>(nColor&0xFF)),
3481         g(static_cast<sal_uInt8>(((nColor)>>8)&0xFF)),
3482         b(static_cast<sal_uInt8>((nColor>>16)&0xFF)),
3483         t(static_cast<sal_uInt8>((nColor>>24)&0xFF));
3484     nColor = (t<<24) + (r<<16) + (g<<8) + b;
3485     return nColor;
3486 }
3487 
Read_TxtForeColor(sal_uInt16,const sal_uInt8 * pData,short nLen)3488 void SwWW8ImplReader::Read_TxtForeColor(sal_uInt16, const sal_uInt8* pData, short nLen)
3489 {
3490     if( nLen < 0 )
3491         pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_CHRATR_COLOR );
3492     else
3493     {
3494         Color aColor(wwUtility::BGRToRGB(SVBT32ToUInt32(pData)));
3495         NewAttr(SvxColorItem(aColor, RES_CHRATR_COLOR));
3496         if (pAktColl && pStyles)
3497             pStyles->bTxtColChanged = true;
3498     }
3499 }
3500 
Read_UnderlineColor(sal_uInt16,const sal_uInt8 * pData,short nLen)3501 void SwWW8ImplReader::Read_UnderlineColor(sal_uInt16, const sal_uInt8* pData, short nLen)
3502 {
3503 	if( nLen < 0 )
3504 	{
3505 		//because the UnderlineColor is not a standalone attribute in SW, it belongs to the underline attribute.
3506 		//And, the .doc file stores attributes separately, this attribute ends here, the "underline"
3507 		//attribute also terminates (if the character next owns underline, that will be a new underline attribute).
3508 		//so nothing is left to be done here.
3509         return;
3510 	}
3511 	else
3512 	{
3513 		if ( pAktColl )	//importing style
3514 		{
3515 			if( SFX_ITEM_SET == pAktColl->GetItemState( RES_CHRATR_UNDERLINE, sal_False ) )
3516 			{
3517 				const SwAttrSet& aSet = pAktColl->GetAttrSet();
3518 				SvxUnderlineItem *pUnderline
3519 					= (SvxUnderlineItem *)(aSet.Get( RES_CHRATR_UNDERLINE, sal_False ).Clone());
3520 				if(pUnderline){
3521 					pUnderline->SetColor( Color( wwUtility::BGRToRGB(SVBT32ToUInt32(pData)) ) );
3522 					pAktColl->SetFmtAttr( *pUnderline );
3523 					delete pUnderline;
3524 				}
3525 			}
3526 		}
3527 		else if ( pAktItemSet )
3528 		{
3529 			if ( SFX_ITEM_SET == pAktItemSet->GetItemState( RES_CHRATR_UNDERLINE, sal_False ) )
3530 			{
3531 				SvxUnderlineItem *pUnderline
3532 					= (SvxUnderlineItem *)(pAktItemSet->Get( RES_CHRATR_UNDERLINE, sal_False ) .Clone());
3533 				if(pUnderline){
3534 					pUnderline->SetColor( Color( wwUtility::BGRToRGB(SVBT32ToUInt32(pData)) ) );
3535 					pAktItemSet->Put( *pUnderline );
3536 					delete pUnderline;
3537 				}
3538 			}
3539 		}
3540 		else
3541 		{
3542 			SvxUnderlineItem* pUnderlineAttr = (SvxUnderlineItem*)pCtrlStck->GetOpenStackAttr( *pPaM->GetPoint(), RES_CHRATR_UNDERLINE );
3543 			if( pUnderlineAttr != NULL )
3544 				pUnderlineAttr->SetColor( Color( wwUtility::BGRToRGB(SVBT32ToUInt32( pData ))));
3545 		}
3546 	}
3547 }
GetFontParams(sal_uInt16 nFCode,FontFamily & reFamily,String & rName,FontPitch & rePitch,CharSet & reCharSet)3548 bool SwWW8ImplReader::GetFontParams( sal_uInt16 nFCode, FontFamily& reFamily,
3549     String& rName, FontPitch& rePitch, CharSet& reCharSet )
3550 {
3551     // Die Defines, aus denen diese Tabellen erzeugt werden, stehen in windows.h
3552     static const FontPitch ePitchA[] =
3553     {
3554         PITCH_DONTKNOW, PITCH_FIXED, PITCH_VARIABLE, PITCH_DONTKNOW
3555     };
3556 
3557     static const FontFamily eFamilyA[] =
3558     {
3559         FAMILY_DONTKNOW, FAMILY_ROMAN, FAMILY_SWISS, FAMILY_MODERN,
3560         FAMILY_SCRIPT, FAMILY_DECORATIVE
3561     };
3562 
3563     const WW8_FFN* pF = pFonts->GetFont( nFCode );  // Info dazu
3564     if( !pF )                                   // FontNummer unbekannt ?
3565         return false;                           // dann ignorieren
3566 
3567     rName = String( pF->sFontname );
3568 
3569     // pF->prg : Pitch
3570     rePitch = ePitchA[pF->prg];
3571 
3572     // pF->chs: Charset
3573     if( 77 == pF->chs )             // Mac-Font im Mac-Charset oder
3574         reCharSet = eTextCharSet;   // auf ANSI-Charset uebersetzt
3575     else
3576     { // patch from cmc for #i52786#
3577         // #i52786#, for word 67 we'll assume that ANSI is basically invalid,
3578         // might be true for (above) mac as well, but would need a mac example
3579         // that exercises this to be sure
3580         if (bVer67 && pF->chs == 0)
3581             reCharSet = RTL_TEXTENCODING_DONTKNOW;
3582         else
3583             reCharSet = rtl_getTextEncodingFromWindowsCharset( pF->chs );
3584     }
3585 
3586     // pF->ff : Family
3587     sal_uInt8 b = pF->ff;
3588 
3589     // make sure Font Family Code is set correctly
3590     // at least for the most important fonts
3591     // ( might be set wrong when Doc was not created by
3592     //   Winword but by third party program like Applixware... )
3593         /*
3594         0: FAMILY_DONTKNOW
3595         1: FAMILY_ROMAN
3596         2: FAMILY_SWISS
3597         3: FAMILY_MODERN
3598         4: FAMILY_SCRIPT
3599         5: FAMILY_DECORATIVE
3600     */
3601 #define FONTNAMETAB_SZ    14
3602 #define MAX_FONTNAME_ROMAN 6
3603     static const sal_Char
3604         // first comes ROMAN
3605         sFontName0[] = "\x07""Tms Rmn",
3606         sFontName1[] = "\x07""Timmons",
3607         sFontName2[] = "\x08""CG Times",
3608         sFontName3[] = "\x08""MS Serif",
3609         sFontName4[] = "\x08""Garamond",
3610         sFontName5[] = "\x11""Times Roman",
3611         sFontName6[] = "\x15""Times New Roman",
3612         // from here SWISS --> see above: #define MAX_FONTNAME_ROMAN 6
3613         sFontName7[] = "\x04""Helv",
3614         sFontName8[] = "\x05""Arial",
3615         sFontName9[] = "\x07""Univers",
3616         sFontName10[]= "\x11""LinePrinter",
3617         sFontName11[]= "\x11""Lucida Sans",
3618         sFontName12[]= "\x11""Small Fonts",
3619         sFontName13[]= "\x13""MS Sans Serif";
3620     static const sal_Char* const aFontNameTab[ FONTNAMETAB_SZ ] =
3621     {
3622         sFontName0,  sFontName1,  sFontName2,  sFontName3,
3623         sFontName4,  sFontName5,  sFontName6,  sFontName7,
3624         sFontName8,  sFontName9,  sFontName10, sFontName11,
3625         sFontName12, sFontName13
3626     };
3627 
3628     for( sal_uInt16 n = 0;  n < FONTNAMETAB_SZ; n++ )
3629     {
3630         const sal_Char* pCmp = aFontNameTab[ n ];
3631         xub_StrLen nLen = *pCmp++;
3632         if( rName.EqualsIgnoreCaseAscii(pCmp, 0, nLen) )
3633         {
3634             b = n <= MAX_FONTNAME_ROMAN ? 1 : 2;
3635             break;
3636         }
3637     }
3638     if (b < (sizeof(eFamilyA)/sizeof(eFamilyA[0])))
3639         reFamily = eFamilyA[b];
3640     else
3641         reFamily = FAMILY_DONTKNOW;
3642 
3643     return true;
3644 }
3645 
CorrectResIdForCharset(CharSet nCharSet,sal_uInt16 nWhich)3646 sal_uInt16 SwWW8ImplReader::CorrectResIdForCharset(CharSet nCharSet, sal_uInt16 nWhich)
3647 {
3648     sal_uInt16 nResult = 0;
3649 
3650     switch (nCharSet) {
3651         case RTL_TEXTENCODING_MS_932:
3652             nResult = RES_CHRATR_CJK_FONT;
3653             break;
3654 
3655         default:
3656             nResult = nWhich;
3657             break;
3658     }
3659 
3660     return nResult;
3661 }
3662 
SetNewFontAttr(sal_uInt16 nFCode,bool bSetEnums,sal_uInt16 nWhich)3663 bool SwWW8ImplReader::SetNewFontAttr(sal_uInt16 nFCode, bool bSetEnums,
3664     sal_uInt16 nWhich)
3665 {
3666     FontFamily eFamily;
3667     String aName;
3668     FontPitch ePitch;
3669     CharSet eSrcCharSet;
3670 
3671     if( !GetFontParams( nFCode, eFamily, aName, ePitch, eSrcCharSet ) )
3672     {
3673         //If we fail (and are not doing a style) then put something into the
3674         //character encodings stack anyway so that the property end that pops
3675         //off the stack will keep in sync
3676         if (!pAktColl && IsListOrDropcap())
3677         {
3678             if (nWhich == RES_CHRATR_CJK_FONT)
3679             {
3680                 if (!maFontSrcCJKCharSets.empty())
3681                 {
3682                     eSrcCharSet = maFontSrcCJKCharSets.top();
3683                 }
3684                 else
3685                 {
3686                     eSrcCharSet = RTL_TEXTENCODING_DONTKNOW;
3687                 }
3688 
3689                 maFontSrcCJKCharSets.push(eSrcCharSet);
3690             }
3691             else
3692             {
3693                 if (!maFontSrcCharSets.empty())
3694                 {
3695                     eSrcCharSet = maFontSrcCharSets.top();
3696                 }
3697                 else
3698                 {
3699                     eSrcCharSet = RTL_TEXTENCODING_DONTKNOW;
3700                 }
3701 
3702                 maFontSrcCharSets.push(eSrcCharSet);
3703             }
3704         }
3705         return false;
3706     }
3707 
3708     CharSet eDstCharSet = eSrcCharSet;
3709 
3710     SvxFontItem aFont( eFamily, aName, aEmptyStr, ePitch, eDstCharSet, nWhich);
3711 
3712     nWhich = CorrectResIdForCharset(eSrcCharSet, nWhich);
3713 
3714     if( bSetEnums )
3715     {
3716         if( pAktColl ) // StyleDef
3717         {
3718             switch(nWhich)
3719             {
3720                 default:
3721                 case RES_CHRATR_FONT:
3722                     pCollA[nAktColl].eLTRFontSrcCharSet = eSrcCharSet;
3723                     break;
3724                 case RES_CHRATR_CTL_FONT:
3725                     pCollA[nAktColl].eRTLFontSrcCharSet = eSrcCharSet;
3726                     break;
3727                 case RES_CHRATR_CJK_FONT:
3728                     pCollA[nAktColl].eCJKFontSrcCharSet = eSrcCharSet;
3729                     break;
3730             }
3731         }
3732         else if (IsListOrDropcap())
3733         {
3734             //Add character text encoding to stack
3735             if (nWhich  == RES_CHRATR_CJK_FONT)
3736                 maFontSrcCJKCharSets.push(eSrcCharSet);
3737             else
3738                 maFontSrcCharSets.push(eSrcCharSet);
3739         }
3740     }
3741 
3742     NewAttr( aFont );                       // ...und 'reinsetzen
3743 
3744     return true;
3745 }
3746 
ResetCharSetVars()3747 void SwWW8ImplReader::ResetCharSetVars()
3748 {
3749     ASSERT(!maFontSrcCharSets.empty(),"no charset to remove");
3750     if (!maFontSrcCharSets.empty())
3751         maFontSrcCharSets.pop();
3752 }
3753 
ResetCJKCharSetVars()3754 void SwWW8ImplReader::ResetCJKCharSetVars()
3755 {
3756     ASSERT(!maFontSrcCJKCharSets.empty(),"no charset to remove");
3757     if (!maFontSrcCJKCharSets.empty())
3758         maFontSrcCJKCharSets.pop();
3759 }
3760 
3761 /*
3762     Font ein oder ausschalten:
3763 */
Read_FontCode(sal_uInt16 nId,const sal_uInt8 * pData,short nLen)3764 void SwWW8ImplReader::Read_FontCode( sal_uInt16 nId, const sal_uInt8* pData, short nLen )
3765 {
3766     if (!bSymbol)           // falls bSymbol, gilt der am Symbol
3767     {                       // (siehe sprmCSymbol) gesetzte Font !
3768         switch( nId )
3769         {
3770             case 113:
3771             case 0x4A51:    //"Other" font, override with BiDi if it exists
3772             case 0x4A5E:    //BiDi Font
3773                 nId = RES_CHRATR_CTL_FONT;
3774                 break;
3775             case 93:
3776             case 111:
3777             case 0x4A4f:
3778                 nId = RES_CHRATR_FONT;
3779                 break;
3780             case 112:
3781             case 0x4A50:
3782                 nId = RES_CHRATR_CJK_FONT;
3783                 break;
3784             default:
3785                 return ;
3786         }
3787 
3788         if( nLen < 0 ) // Ende des Attributes
3789         {
3790             pCtrlStck->SetAttr( *pPaM->GetPoint(), nId );
3791             if (nId == RES_CHRATR_CJK_FONT)
3792                 ResetCJKCharSetVars();
3793             else
3794                 ResetCharSetVars();
3795         }
3796         else
3797         {
3798             sal_uInt16 nFCode = SVBT16ToShort( pData );     // Font-Nummer
3799             if (SetNewFontAttr(nFCode, true, nId)   // Lies Inhalt
3800                 && pAktColl && pStyles )                // Style-Def ?
3801             {
3802                 // merken zur Simulation Default-Font
3803                 if (RES_CHRATR_CJK_FONT == nId)
3804                     pStyles->bCJKFontChanged = true;
3805                 else if (RES_CHRATR_CTL_FONT == nId)
3806                     pStyles->bCTLFontChanged = true;
3807                 else
3808                     pStyles->bFontChanged = true;
3809             }
3810         }
3811     }
3812 }
3813 
Read_FontSize(sal_uInt16 nId,const sal_uInt8 * pData,short nLen)3814 void SwWW8ImplReader::Read_FontSize( sal_uInt16 nId, const sal_uInt8* pData, short nLen )
3815 {
3816     switch( nId )
3817     {
3818         case 74:
3819         case 99:
3820         case 0x4a43:
3821             nId = RES_CHRATR_FONTSIZE;
3822 			break;
3823         case 85:
3824         case 116:
3825         case 0x4a61:
3826             nId = RES_CHRATR_CTL_FONTSIZE;
3827             break;
3828         default:
3829             return ;
3830     }
3831 
3832     if( nLen < 0 )          // Ende des Attributes
3833     {
3834         pCtrlStck->SetAttr( *pPaM->GetPoint(), nId  );
3835         if( RES_CHRATR_FONTSIZE == nId )  // reset additional the CJK size
3836             pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_CHRATR_CJK_FONTSIZE );
3837     }
3838     else
3839     {
3840         ww::WordVersion eVersion = pWwFib->GetFIBVersion();
3841 
3842         // Font-Size in half points e.g. 10 = 1440 / ( 72 * 2 )
3843         sal_uInt16 nFSize = eVersion <= ww::eWW2 ? *pData : SVBT16ToShort(pData);
3844         nFSize*= 10;
3845 
3846         SvxFontHeightItem aSz( nFSize, 100, nId );
3847         NewAttr( aSz );
3848         if( RES_CHRATR_FONTSIZE == nId )  // set additional the CJK size
3849         {
3850             aSz.SetWhich( RES_CHRATR_CJK_FONTSIZE );
3851             NewAttr( aSz );
3852         }
3853         if (pAktColl && pStyles)            // Style-Def ?
3854         {
3855             // merken zur Simulation Default-FontSize
3856             if (nId == RES_CHRATR_CTL_FONTSIZE)
3857                 pStyles->bFCTLSizeChanged = true;
3858             else
3859                 pStyles->bFSizeChanged = true;
3860         }
3861     }
3862 }
3863 
3864 
3865 
Read_CharSet(sal_uInt16,const sal_uInt8 * pData,short nLen)3866 void SwWW8ImplReader::Read_CharSet(sal_uInt16 , const sal_uInt8* pData, short nLen)
3867 {
3868     if( nLen < 0 )
3869     {                   // Ende des Attributes
3870         eHardCharSet = RTL_TEXTENCODING_DONTKNOW;
3871         return;
3872     }
3873     sal_uInt8 nfChsDiff = SVBT8ToByte( pData );
3874 
3875     if( nfChsDiff )
3876         eHardCharSet = rtl_getTextEncodingFromWindowsCharset( *(pData + 1) );
3877     else
3878         eHardCharSet = RTL_TEXTENCODING_DONTKNOW;
3879 }
3880 
Read_Language(sal_uInt16 nId,const sal_uInt8 * pData,short nLen)3881 void SwWW8ImplReader::Read_Language( sal_uInt16 nId, const sal_uInt8* pData, short nLen )
3882 {
3883     switch( nId )
3884     {
3885         case 97:
3886         case 0x486D:
3887         case 0x4873: //Methinks, uncertain
3888             nId = RES_CHRATR_LANGUAGE;
3889             break;
3890         case 0x486E:
3891             nId = RES_CHRATR_CJK_LANGUAGE;
3892             break;
3893         case 83:
3894         case 114:
3895         case 0x485F:
3896             nId = RES_CHRATR_CTL_LANGUAGE;
3897 			break;
3898         default:
3899             return;
3900     }
3901 
3902     if( nLen < 0 )                  // Ende des Attributes
3903         pCtrlStck->SetAttr( *pPaM->GetPoint(), nId );
3904     else
3905     {
3906         sal_uInt16 nLang = SVBT16ToShort( pData );  // Language-Id
3907         NewAttr(SvxLanguageItem((const LanguageType)nLang, nId));
3908     }
3909 }
3910 
3911 /*
3912     Einschalten des Zeichen-Styles:
3913 */
Read_CColl(sal_uInt16,const sal_uInt8 * pData,short nLen)3914 void SwWW8ImplReader::Read_CColl( sal_uInt16, const sal_uInt8* pData, short nLen )
3915 {
3916     if( nLen < 0 ){                 // Ende des Attributes
3917         pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_TXTATR_CHARFMT );
3918         nCharFmt = -1;
3919         return;
3920     }
3921     sal_uInt16 nId = SVBT16ToShort( pData );    // Style-Id (NICHT Sprm-Id!)
3922 
3923     if( nId >= nColls || !pCollA[nId].pFmt  // ungueltige Id ?
3924         || pCollA[nId].bColl )              // oder Para-Style ?
3925         return;                             // dann ignorieren
3926 
3927     // if current on loading a TOX field, and current trying to apply a hyperlink character style,
3928     // just ignore. For the hyperlinks inside TOX in MS Word is not same with a common hyperlink
3929     // Character styles: without underline and blue font color. And such type style will be applied in others
3930     // processes.
3931     if (mbLoadingTOXCache && pCollA[nId].GetWWStyleId() == ww::stiHyperlink)
3932     {
3933         return;
3934     }
3935 
3936     NewAttr( SwFmtCharFmt( (SwCharFmt*)pCollA[nId].pFmt ) );
3937     nCharFmt = (short) nId;
3938 }
3939 
3940 
3941 /*
3942     enger oder weiter als normal:
3943 */
Read_Kern(sal_uInt16,const sal_uInt8 * pData,short nLen)3944 void SwWW8ImplReader::Read_Kern( sal_uInt16, const sal_uInt8* pData, short nLen )
3945 {
3946     if( nLen < 0 ){                 // Ende des Attributes
3947         pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_CHRATR_KERNING );
3948         return;
3949     }
3950     sal_Int16 nKern = SVBT16ToShort( pData );    // Kerning in Twips
3951     NewAttr( SvxKerningItem( nKern, RES_CHRATR_KERNING ) );
3952 }
3953 
Read_FontKern(sal_uInt16,const sal_uInt8 *,short nLen)3954 void SwWW8ImplReader::Read_FontKern( sal_uInt16, const sal_uInt8* , short nLen )
3955 {
3956     if( nLen < 0 ) // Ende des Attributes
3957         pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_CHRATR_AUTOKERN );
3958     else
3959         NewAttr(SvxAutoKernItem(true, RES_CHRATR_AUTOKERN));
3960 }
3961 
Read_CharShadow(sal_uInt16,const sal_uInt8 * pData,short nLen)3962 void SwWW8ImplReader::Read_CharShadow(  sal_uInt16, const sal_uInt8* pData, short nLen )
3963 {
3964     //Has newer colour variant, ignore this old variant
3965     if (!bVer67 && pPlcxMan && pPlcxMan->GetChpPLCF()->HasSprm(0xCA71))
3966         return;
3967 
3968     if( nLen <= 0 )
3969     {
3970         pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_CHRATR_BACKGROUND );
3971         if( bCharShdTxtCol )
3972         {
3973             // Zeichenfarbe auch
3974             pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_CHRATR_COLOR );
3975             bCharShdTxtCol = false;
3976         }
3977     }
3978     else
3979     {
3980         WW8_SHD aSHD;
3981         aSHD.SetWWValue( *(SVBT16*)pData );
3982         SwWW8Shade aSh( bVer67, aSHD );
3983 
3984         NewAttr( SvxBrushItem( aSh.aColor, RES_CHRATR_BACKGROUND ));
3985     }
3986 }
3987 
Read_TxtBackColor(sal_uInt16,const sal_uInt8 * pData,short nLen)3988 void SwWW8ImplReader::Read_TxtBackColor(sal_uInt16, const sal_uInt8* pData, short nLen )
3989 {
3990     if( nLen <= 0 )
3991     {
3992         pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_CHRATR_BACKGROUND );
3993         if( bCharShdTxtCol )
3994         {
3995             // Zeichenfarbe auch
3996             pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_CHRATR_COLOR );
3997             bCharShdTxtCol = false;
3998         }
3999     }
4000     else
4001     {
4002         ASSERT(nLen == 10, "Len of para back colour not 10!");
4003         if (nLen != 10)
4004             return;
4005         Color aColour(ExtractColour(pData, bVer67));
4006         NewAttr(SvxBrushItem(aColour, RES_CHRATR_BACKGROUND));
4007     }
4008 }
4009 
Read_CharHighlight(sal_uInt16,const sal_uInt8 * pData,short nLen)4010 void SwWW8ImplReader::Read_CharHighlight(sal_uInt16, const sal_uInt8* pData, short nLen)
4011 {
4012     if( nLen <= 0 )
4013     {
4014         pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_CHRATR_BACKGROUND );
4015         if( bCharShdTxtCol )
4016         {
4017             pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_CHRATR_COLOR );  // Zeichenfarbe auch
4018             bCharShdTxtCol = false;
4019         }
4020     }
4021     else
4022     {
4023         sal_uInt8 b = *pData;            // Parameter: 0 = Auto, 1..16 Farben
4024 
4025         if( b > 16 )                // unbekannt -> Black
4026             b = 0;                  // Auto -> Black
4027 
4028         Color aCol(GetCol(b));
4029         NewAttr( SvxBrushItem( aCol , RES_CHRATR_BACKGROUND ));
4030     }
4031 }
4032 
4033 
4034 /***************************************************************************
4035 #  Absatz - Attribute
4036 #**************************************************************************/
4037 
Read_NoLineNumb(sal_uInt16,const sal_uInt8 * pData,short nLen)4038 void SwWW8ImplReader::Read_NoLineNumb(sal_uInt16 , const sal_uInt8* pData, short nLen)
4039 {
4040     if( nLen < 0 )  // Ende des Attributes
4041     {
4042         pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_LINENUMBER );
4043         return;
4044     }
4045     SwFmtLineNumber aLN;
4046     if (const SwFmtLineNumber* pLN
4047         = (const SwFmtLineNumber*)GetFmtAttr(RES_LINENUMBER))
4048     {
4049         aLN.SetStartValue( pLN->GetStartValue() );
4050     }
4051 
4052     aLN.SetCountLines( pData && (0 == *pData) );
4053     NewAttr( aLN );
4054 }
4055 
lcl_HasExplicitLeft(const WW8PLCFMan * pPlcxMan,bool bVer67)4056 bool lcl_HasExplicitLeft(const WW8PLCFMan *pPlcxMan, bool bVer67)
4057 {
4058 	WW8PLCFx_Cp_FKP *pPap = pPlcxMan ? pPlcxMan->GetPapPLCF() : 0;
4059 	if (pPap)
4060 	{
4061 		if (bVer67)
4062 			return pPap->HasSprm(17);
4063 		else
4064 			return (pPap->HasSprm(0x840F) || pPap->HasSprm(0x845E));
4065 	}
4066 	return false;
4067 }
4068 // Sprm 16, 17
Read_LR(sal_uInt16 nId,const sal_uInt8 * pData,short nLen)4069 void SwWW8ImplReader::Read_LR( sal_uInt16 nId, const sal_uInt8* pData, short nLen )
4070 {
4071     if (nLen < 0)  // End of the Attributes
4072     {
4073         pCtrlStck->SetAttr(*pPaM->GetPoint(), RES_LR_SPACE);
4074         return;
4075     }
4076 
4077     short nPara = SVBT16ToShort( pData );
4078 
4079     SvxLRSpaceItem aLR( RES_LR_SPACE );
4080     const SfxPoolItem* pLR = GetFmtAttr(RES_LR_SPACE);
4081     if( pLR )
4082         aLR = *(const SvxLRSpaceItem*)pLR;
4083 
4084     /*
4085     The older word sprms mean left/right, while the new ones mean before/after.
4086     Writer now also works with before after, so when we see old left/right and
4087     we're RTL. We swap them
4088     */
4089     if (IsRightToLeft())
4090     {
4091         switch (nId)
4092         {
4093             //Left becomes after;
4094             case 17:
4095                 nId = 16;
4096                 break;
4097             case 0x840F:
4098                 nId = 0x840E;
4099                 break;
4100             //Right becomes before;
4101             case 16:
4102                 nId = 17;
4103                 break;
4104             case 0x840E:
4105                 nId = 0x840F;
4106                 break;
4107         }
4108     }
4109 
4110     // --> OD 2010-05-06 #i103711#
4111     bool bFirstLinOfstSet( false );
4112     // <--
4113     // --> OD 2010-05-11 #i105414#
4114     bool bLeftIndentSet( false );
4115     // <--
4116 
4117     switch (nId)
4118     {
4119         //sprmPDxaLeft
4120         case     17:
4121         case 0x840F:
4122         case 0x845E:
4123             aLR.SetTxtLeft( nPara );
4124             if (pAktColl)
4125             {
4126                 pCollA[nAktColl].bListReleventIndentSet = true;
4127             }
4128             // --> OD 2010-05-11 #i105414#
4129             bLeftIndentSet = true;
4130             // <--
4131             break;
4132         //sprmPDxaLeft1
4133         case     19:
4134         case 0x8411:
4135         case 0x8460:
4136             /*
4137             #94672# #99584#
4138             As part of an attempt to break my spirit ww 8+ formats can contain
4139             ww 7- lists. If they do and the list is part of the style, then
4140             when removing the list from a paragraph of that style there
4141             appears to be a bug where the hanging indent value which the list
4142             set is still factored into the left indent of the paragraph. Its
4143             not listed in the winword dialogs, but it is clearly there. So if
4144             our style has a broken ww 7- list and we know that the list has
4145             been removed then we will factor the original list applied hanging
4146             into our calculation.
4147             */
4148             if (pPlcxMan && pCollA[nAktColl].bHasBrokenWW6List)
4149             {
4150                 const sal_uInt8 *pIsZeroed = pPlcxMan->GetPapPLCF()->HasSprm(0x460B);
4151                 if (pIsZeroed && *pIsZeroed == 0)
4152                 {
4153                     const SvxLRSpaceItem &rLR =
4154                         ItemGet<SvxLRSpaceItem>(*(pCollA[nAktColl].pFmt),
4155                         RES_LR_SPACE);
4156                     nPara = nPara - rLR.GetTxtFirstLineOfst();
4157                 }
4158             }
4159 
4160             aLR.SetTxtFirstLineOfst(nPara);
4161 
4162             if (!pAktColl)
4163             {
4164 				if (const SwTxtNode* pNode = pPaM->GetNode()->GetTxtNode())
4165 				{
4166 					if ( const SwNumFmt *pNumFmt = GetNumFmtFromTxtNode(*pNode) )
4167 					{
4168 						if (!lcl_HasExplicitLeft(pPlcxMan, bVer67))
4169 						{
4170 							aLR.SetTxtLeft(pNumFmt->GetIndentAt());
4171 
4172 							// If have not explicit left, set number format list tab position is doc default tab
4173 							const SvxTabStopItem *pDefaultStopItem = (const SvxTabStopItem *)rDoc.GetAttrPool().GetPoolDefaultItem(RES_PARATR_TABSTOP);
4174 							if ( pDefaultStopItem &&  pDefaultStopItem->Count() > 0 )
4175 								((SwNumFmt*)(pNumFmt))->SetListtabPos( ((SvxTabStop&)(*pDefaultStopItem)[0]).GetTabPos() );
4176 						}
4177 					}
4178 				}
4179 		}
4180 
4181 
4182             if (pAktColl)
4183             {
4184                 pCollA[nAktColl].bListReleventIndentSet = true;
4185             }
4186             // --> OD 2010-05-06 #i103711#
4187             bFirstLinOfstSet = true;
4188             // <--
4189             break;
4190         //sprmPDxaRight
4191         case     16:
4192         case 0x840E:
4193         case 0x845D:
4194             aLR.SetRight( nPara );
4195             break;
4196         default:
4197             return;
4198     }
4199 
4200     // --> OD 2010-05-06 #i103711#
4201     // --> OD 2010-05-11 #i105414#
4202     NewAttr( aLR, bFirstLinOfstSet, bLeftIndentSet );
4203     // <--
4204 }
4205 
4206 // Sprm 20
Read_LineSpace(sal_uInt16,const sal_uInt8 * pData,short nLen)4207 void SwWW8ImplReader::Read_LineSpace( sal_uInt16, const sal_uInt8* pData, short nLen )
4208 {
4209 // Kommentear siehe Read_UL()
4210     if (bStyNormal && bWWBugNormal)
4211         return;
4212 
4213     if( nLen < 0 ){
4214         pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_PARATR_LINESPACING );
4215         if( !( nIniFlags & WW8FL_NO_IMPLPASP ) )
4216             pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_UL_SPACE );
4217         return;
4218     }
4219 
4220     short nSpace = SVBT16ToShort( pData );
4221     ww::WordVersion eVersion = pWwFib->GetFIBVersion();
4222     short nMulti = (eVersion <= ww::eWW2) ? 1 : SVBT16ToShort( pData + 2 );
4223 
4224     SvxLineSpace eLnSpc;
4225     if( 0 > nSpace )
4226     {
4227         nSpace = -nSpace;
4228         eLnSpc = SVX_LINE_SPACE_FIX;
4229     }
4230     else
4231         eLnSpc = SVX_LINE_SPACE_MIN;
4232 
4233 // WW hat einen impliziten zusaetzlichen Absatzabstand abhaengig vom
4234 // Zeilenabstand. Er betraegt bei "genau", 0.8*Zeilenabstand "vor" und
4235 // 0.2*Zeilenabstand "nach".
4236 // Bei "Mindestens" sind es 1*Zeilenabstand "vor" und 0*Zeilenabstand "nach".
4237 // Bei Mehrfach sind es 0 "vor" und min( 0cm, FontSize*(nFach-1) ) "nach".
4238 //
4239 // SW hat auch einen impliziten Zeilenabstand. er betraegt bei "mindestens"
4240 // 1*Zeilenabstand "vor" und 0 "nach"
4241 // bei proportional betraegt er min( 0cm, FontSize*(nFach-1) ) sowohl "vor"
4242 // wie auch "nach"
4243 
4244     sal_uInt16 nWwPre = 0;
4245     sal_uInt16 nWwPost = 0;
4246     sal_uInt16 nSwPre = 0;
4247     sal_uInt16 nSwPost = 0;
4248     sal_uInt16 nSpaceTw = 0;
4249 
4250     SvxLineSpacingItem aLSpc( LINE_SPACE_DEFAULT_HEIGHT, RES_PARATR_LINESPACING );
4251 
4252     if( 1 == nMulti )               // MultilineSpace ( proportional )
4253     {
4254         long n = nSpace * 10 / 24;  // WW: 240 = 100%, SW: 100 = 100%
4255 
4256 //JP 03.12.98: nach Absprache mit AMA ist die Begrenzung unsinnig
4257         if( n>200 ) n = 200;        // SW_UI-Maximum
4258         aLSpc.SetPropLineSpace( (const sal_uInt8)n );
4259         const SvxFontHeightItem* pH = (const SvxFontHeightItem*)
4260             GetFmtAttr( RES_CHRATR_FONTSIZE );
4261         nSpaceTw = (sal_uInt16)( n * pH->GetHeight() / 100 );
4262 
4263         if( n > 100 )
4264             nWwPost = nSwPre = nSwPost = (sal_uInt16)( ( n - 100 )
4265                                                     * pH->GetHeight() / 100 );
4266     }
4267     else                            // Fixed / Minimum
4268     {
4269         // bei negativen Space ist der Abstand exakt, sonst minimum
4270         nSpaceTw = (sal_uInt16)nSpace;
4271         aLSpc.SetLineHeight( nSpaceTw );
4272         aLSpc.GetLineSpaceRule() = eLnSpc;
4273         nSwPre = nSpace;
4274 
4275         if( SVX_LINE_SPACE_FIX == eLnSpc )                  // Genau
4276         {
4277             nWwPre = (sal_uInt16)( 8L * nSpace / 10 );
4278             nWwPost = (sal_uInt16)( 2L * nSpace / 10 );
4279             nSwPre = nSpace;
4280         }
4281         else                                                // Minimum
4282         {
4283             nWwPre = (sal_uInt16)( 129L * nSpace / 100 - 95 );// erst bei groesseren
4284                                                           // Zeilenabstaenden
4285         }
4286     }
4287     NewAttr( aLSpc );
4288     if( pSFlyPara )
4289         pSFlyPara->nLineSpace = nSpaceTw;   // LineSpace fuer Graf-Apos
4290 }
4291 
4292 //#i18519# AutoSpace value depends on Dop fDontUseHTMLAutoSpacing setting
GetParagraphAutoSpace(bool fDontUseHTMLAutoSpacing)4293 sal_uInt16 SwWW8ImplReader::GetParagraphAutoSpace(bool fDontUseHTMLAutoSpacing)
4294 {
4295     if (fDontUseHTMLAutoSpacing)
4296         return 100;  //Seems to be always 5points in this case
4297     else
4298         return 280;  //Seems to be always 14points in this case
4299 }
4300 
Read_DontAddEqual(sal_uInt16,const sal_uInt8 * pData,short nLen)4301 void SwWW8ImplReader::Read_DontAddEqual(sal_uInt16, const sal_uInt8 *pData, short nLen)
4302 {
4303     if (nLen < 0)
4304         return;
4305 
4306     if (*pData)
4307         maTracer.Log(sw::log::eDontAddSpaceForEqualStyles);
4308 }
4309 
Read_ParaAutoBefore(sal_uInt16,const sal_uInt8 * pData,short nLen)4310 void SwWW8ImplReader::Read_ParaAutoBefore(sal_uInt16, const sal_uInt8 *pData, short nLen)
4311 {
4312     if (nLen < 0)
4313     {
4314         pCtrlStck->SetAttr(*pPaM->GetPoint(), RES_UL_SPACE);
4315         return;
4316     }
4317 
4318     if (*pData)
4319     {
4320         SvxULSpaceItem aUL(*(const SvxULSpaceItem*)GetFmtAttr(RES_UL_SPACE));
4321         aUL.SetUpper(GetParagraphAutoSpace(pWDop->fDontUseHTMLAutoSpacing));
4322         NewAttr(aUL);
4323         if (pAktColl)
4324             pCollA[nAktColl].bParaAutoBefore = true;
4325         else
4326             bParaAutoBefore = true;
4327     }
4328     else
4329     {
4330         if (pAktColl)
4331             pCollA[nAktColl].bParaAutoBefore = false;
4332         else
4333             bParaAutoBefore = false;
4334     }
4335 }
4336 
Read_ParaAutoAfter(sal_uInt16,const sal_uInt8 * pData,short nLen)4337 void SwWW8ImplReader::Read_ParaAutoAfter(sal_uInt16, const sal_uInt8 *pData, short nLen)
4338 {
4339     if (nLen < 0)
4340     {
4341         pCtrlStck->SetAttr(*pPaM->GetPoint(), RES_UL_SPACE);
4342         return;
4343     }
4344 
4345     if (*pData)
4346     {
4347         SvxULSpaceItem aUL(*(const SvxULSpaceItem*)GetFmtAttr(RES_UL_SPACE));
4348         aUL.SetLower(GetParagraphAutoSpace(pWDop->fDontUseHTMLAutoSpacing));
4349         NewAttr(aUL);
4350         if (pAktColl)
4351             pCollA[nAktColl].bParaAutoAfter = true;
4352         else
4353             bParaAutoAfter = true;
4354     }
4355     else
4356     {
4357         if (pAktColl)
4358             pCollA[nAktColl].bParaAutoAfter = false;
4359         else
4360             bParaAutoAfter = false;
4361     }
4362 }
4363 
4364 // Sprm 21, 22
Read_UL(sal_uInt16 nId,const sal_uInt8 * pData,short nLen)4365 void SwWW8ImplReader::Read_UL( sal_uInt16 nId, const sal_uInt8* pData, short nLen )
4366 {
4367 // Nun eine Umpopelung eines WW-Fehlers: Bei nProduct == 0c03d wird
4368 // faelschlicherweise ein DyaAfter 240 ( delta y abstand after, amn.d.?b.)
4369 // im Style "Normal" eingefuegt, der
4370 // gar nicht da ist. Ueber das IniFlag WW8FL_NO_STY_DYA laesst sich dieses
4371 // Verhalten auch fuer andere WW-Versionen erzwingen
4372 //  ASSERT( !bStyNormal || bWWBugNormal, "+Dieses Doc deutet evtl. auf einen
4373 // Fehler in der benutzten WW-Version hin. Wenn sich die Styles <Standard> bzw.
4374 // <Normal> zwischen WW und SW im Absatz- oder Zeilenabstand unterscheiden,
4375 // dann bitte dieses Doc SH zukommen lassen." );
4376 // bWWBugNormal ist kein hinreichendes Kriterium dafuer, dass der
4377 // angegebene Abstand falsch ist
4378 
4379     if( nLen < 0 )
4380     {
4381         // Ende des Attributes
4382         pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_UL_SPACE );
4383         return;
4384     }
4385     short nPara = SVBT16ToShort( pData );
4386     if( nPara < 0 )
4387         nPara = -nPara;
4388 
4389     SvxULSpaceItem aUL( *(const SvxULSpaceItem*)GetFmtAttr( RES_UL_SPACE ));
4390 
4391     switch( nId )
4392     {
4393         //sprmPDyaBefore
4394         case     21:
4395         case 0xA413:
4396             aUL.SetUpper( nPara );
4397             break;
4398         //sprmPDyaAfter
4399         case     22:
4400         case 0xA414:
4401             aUL.SetLower( nPara );
4402             break;
4403         default:
4404             return;
4405     };
4406 
4407     NewAttr( aUL );
4408 }
4409 
Read_IdctHint(sal_uInt16,const sal_uInt8 * pData,short nLen)4410 void SwWW8ImplReader::Read_IdctHint( sal_uInt16, const sal_uInt8* pData, short nLen )
4411 {
4412     // sprmcidcthint (opcode 0x286f) specifies a script bias for the text in the run.
4413     // for unicode characters that are shared between far east and non-far east scripts,
4414     // this property determines what font and language the character will use.
4415     // when this value is 0, text properties bias towards non-far east properties.
4416     // when this value is 1, text properties bias towards far east properties.
4417 	if( nLen < 0 )	//Property end
4418 	{
4419 		pCtrlStck->SetAttr(*pPaM->GetPoint(),RES_CHRATR_IDCTHINT);
4420 	}
4421 	else	//Property start
4422 	{
4423 		sal_uInt8 nVal = SVBT8ToByte( pData );
4424 		NewAttr( SfxInt16Item( RES_CHRATR_IDCTHINT, (nVal!=0)? 1 : 0 ) );
4425 	}
4426 }
4427 
Read_Justify(sal_uInt16,const sal_uInt8 * pData,short nLen)4428 void SwWW8ImplReader::Read_Justify( sal_uInt16, const sal_uInt8* pData, short nLen )
4429 {
4430     if( nLen < 0 )
4431     {
4432         pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_PARATR_ADJUST );
4433         return;
4434     }
4435 
4436     SvxAdjust eAdjust(SVX_ADJUST_LEFT);
4437     bool bDistributed = false;
4438     switch (*pData)
4439     {
4440         default:
4441         case 0:
4442             break;
4443         case 1:
4444             eAdjust = SVX_ADJUST_CENTER;
4445             break;
4446         case 2:
4447             eAdjust = SVX_ADJUST_RIGHT;
4448             break;
4449         case 3:
4450             eAdjust = SVX_ADJUST_BLOCK;
4451             break;
4452         case 4:
4453             eAdjust = SVX_ADJUST_BLOCK;
4454             bDistributed = true;
4455             break;
4456     }
4457     SvxAdjustItem aAdjust(eAdjust, RES_PARATR_ADJUST);
4458     if (bDistributed)
4459         aAdjust.SetLastBlock(SVX_ADJUST_BLOCK);
4460 
4461     NewAttr(aAdjust);
4462 }
4463 
IsRightToLeft()4464 bool SwWW8ImplReader::IsRightToLeft()
4465 {
4466     bool bRTL = false;
4467     const sal_uInt8 *pDir =
4468         pPlcxMan ? pPlcxMan->GetPapPLCF()->HasSprm(0x2441) : 0;
4469     if (pDir)
4470         bRTL = *pDir ? true : false;
4471     else
4472     {
4473         const SvxFrameDirectionItem* pItem=
4474             (const SvxFrameDirectionItem*)GetFmtAttr(RES_FRAMEDIR);
4475         if (pItem && (pItem->GetValue() == FRMDIR_HORI_RIGHT_TOP))
4476             bRTL = true;
4477     }
4478     return bRTL;
4479 }
4480 
Read_RTLJustify(sal_uInt16,const sal_uInt8 * pData,short nLen)4481 void SwWW8ImplReader::Read_RTLJustify( sal_uInt16, const sal_uInt8* pData, short nLen )
4482 {
4483     if( nLen < 0 )
4484     {
4485         pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_PARATR_ADJUST );
4486         return;
4487     }
4488 
4489     //If we are in a ltr paragraph this is the same as normal Justify,
4490     //If we are in a rtl paragraph the meaning is reversed.
4491     if (!IsRightToLeft())
4492         Read_Justify(0x2403 /*dummy*/, pData, nLen);
4493     else
4494     {
4495         SvxAdjust eAdjust(SVX_ADJUST_RIGHT);
4496         bool bDistributed = false;
4497         switch (*pData)
4498         {
4499             default:
4500             case 0:
4501                 break;
4502             case 1:
4503                 eAdjust = SVX_ADJUST_CENTER;
4504                 break;
4505             case 2:
4506                 eAdjust = SVX_ADJUST_LEFT;
4507                 break;
4508             case 3:
4509                 eAdjust = SVX_ADJUST_BLOCK;
4510                 break;
4511             case 4:
4512                 eAdjust = SVX_ADJUST_BLOCK;
4513                 bDistributed = true;
4514                 break;
4515         }
4516         SvxAdjustItem aAdjust(eAdjust, RES_PARATR_ADJUST);
4517         if (bDistributed)
4518             aAdjust.SetLastBlock(SVX_ADJUST_BLOCK);
4519 
4520         NewAttr(aAdjust);
4521     }
4522 }
4523 
Read_BoolItem(sal_uInt16 nId,const sal_uInt8 * pData,short nLen)4524 void SwWW8ImplReader::Read_BoolItem( sal_uInt16 nId, const sal_uInt8* pData, short nLen )
4525 {
4526     switch( nId )
4527     {
4528         case 0x2433:
4529             nId = RES_PARATR_FORBIDDEN_RULES;
4530             break;
4531         case 0x2435:
4532             nId = RES_PARATR_HANGINGPUNCTUATION;
4533             break;
4534         case 0x2437:
4535             nId = RES_PARATR_SCRIPTSPACE;
4536             break;
4537         default:
4538             ASSERT( sal_False, "wrong Id" );
4539             return ;
4540     }
4541 
4542     if( nLen < 0 )
4543         pCtrlStck->SetAttr( *pPaM->GetPoint(), nId );
4544     else
4545     {
4546         SfxBoolItem* pI = (SfxBoolItem*)GetDfltAttr( nId )->Clone();
4547         pI->SetValue( 0 != *pData );
4548         NewAttr( *pI );
4549         delete pI;
4550     }
4551 }
4552 
Read_Emphasis(sal_uInt16,const sal_uInt8 * pData,short nLen)4553 void SwWW8ImplReader::Read_Emphasis( sal_uInt16, const sal_uInt8* pData, short nLen )
4554 {
4555     if( nLen < 0 )
4556         pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_CHRATR_EMPHASIS_MARK );
4557     else
4558     {
4559         LanguageType nLang;
4560         //Check to see if there is an up and coming cjk language property. If
4561         //there is use it, if there is not fall back to the currently set one.
4562         //Only the cjk language setting seems to matter to word, the western
4563         //one is ignored
4564         const sal_uInt8 *pLang =
4565             pPlcxMan ? pPlcxMan->GetChpPLCF()->HasSprm(0x486E) : 0;
4566 
4567         if (pLang)
4568             nLang = SVBT16ToShort( pLang );
4569         else
4570         {
4571             nLang = ((const SvxLanguageItem *)
4572                 GetFmtAttr(RES_CHRATR_CJK_LANGUAGE))->GetLanguage();
4573         }
4574 
4575         sal_uInt16 nVal;
4576         switch( *pData )
4577         {
4578         case 0:
4579             nVal = EMPHASISMARK_NONE;
4580             break;
4581         case 2:
4582             if ((nLang == LANGUAGE_CHINESE_HONGKONG) ||
4583                 (nLang == LANGUAGE_CHINESE_MACAU) ||
4584                 (nLang == LANGUAGE_CHINESE_TRADITIONAL) ||
4585                 (nLang == LANGUAGE_KOREAN))
4586                 nVal = EMPHASISMARK_CIRCLE_ABOVE;
4587             else if (nLang == LANGUAGE_JAPANESE)
4588                 nVal = EMPHASISMARK_SIDE_DOTS;
4589             else
4590                 nVal = EMPHASISMARK_DOTS_BELOW;
4591             break;
4592         case 3:
4593             nVal = EMPHASISMARK_CIRCLE_ABOVE;
4594             break;
4595         case 4:
4596             nVal = EMPHASISMARK_DOTS_BELOW;
4597             break;
4598         case 1:
4599             if ((nLang == LANGUAGE_CHINESE_SIMPLIFIED) ||
4600                 (nLang == LANGUAGE_CHINESE_SINGAPORE))
4601                 nVal = EMPHASISMARK_DOTS_BELOW;
4602             else
4603                 nVal = EMPHASISMARK_DOTS_ABOVE;
4604             break;
4605         default:
4606             nVal = EMPHASISMARK_DOTS_ABOVE;
4607             break;
4608         }
4609 
4610         NewAttr( SvxEmphasisMarkItem( nVal, RES_CHRATR_EMPHASIS_MARK ) );
4611     }
4612 }
4613 
Read_ScaleWidth(sal_uInt16,const sal_uInt8 * pData,short nLen)4614 void SwWW8ImplReader::Read_ScaleWidth( sal_uInt16, const sal_uInt8* pData, short nLen )
4615 {
4616     if( nLen < 0 )
4617         pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_CHRATR_SCALEW );
4618     else
4619     {
4620         sal_uInt16 nVal = SVBT16ToShort( pData );
4621         //The number must be between 1 and 600
4622         if (nVal < 1 || nVal > 600)
4623             nVal = 100;
4624         NewAttr( SvxCharScaleWidthItem( nVal, RES_CHRATR_SCALEW ) );
4625     }
4626 }
4627 
Read_Relief(sal_uInt16 nId,const sal_uInt8 * pData,short nLen)4628 void SwWW8ImplReader::Read_Relief( sal_uInt16 nId, const sal_uInt8* pData, short nLen )
4629 {
4630     if( nLen < 0 )
4631         pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_CHRATR_RELIEF );
4632     else
4633     {
4634         if( *pData )
4635         {
4636 // JP 16.03.2001 - not so eays because this is also a toggle attribute!
4637 //  2 x emboss on -> no emboss !!!
4638 // the actual value must be searched over the stack / template
4639 
4640             const SvxCharReliefItem* pOld = (const SvxCharReliefItem*)
4641                                             GetFmtAttr( RES_CHRATR_RELIEF );
4642             FontRelief nNewValue = 0x854 == nId ? RELIEF_ENGRAVED
4643                                         : ( 0x858 == nId ? RELIEF_EMBOSSED
4644                                                          : RELIEF_NONE );
4645             if( pOld->GetValue() == nNewValue )
4646             {
4647                 if( RELIEF_NONE != nNewValue )
4648                     nNewValue = RELIEF_NONE;
4649             }
4650             NewAttr( SvxCharReliefItem( nNewValue, RES_CHRATR_RELIEF ));
4651         }
4652     }
4653 }
4654 
Read_TxtAnim(sal_uInt16,const sal_uInt8 * pData,short nLen)4655 void SwWW8ImplReader::Read_TxtAnim(sal_uInt16 /*nId*/, const sal_uInt8* pData, short nLen)
4656 {
4657     if (nLen < 0)
4658         pCtrlStck->SetAttr(*pPaM->GetPoint(), RES_CHRATR_BLINK);
4659     else
4660     {
4661         if (*pData)
4662         {
4663             bool bBlink;
4664 
4665             // #110851# The 7 animated text effects available in word all get
4666             // mapped to a blinking text effect in StarOffice
4667             // 0 no animation       1 Las Vegas lights
4668             // 2 background blink   3 sparkle text
4669             // 4 marching ants      5 marchine red ants
4670             // 6 shimmer
4671             if (*pData > 0 && *pData < 7 )
4672                 bBlink = true;
4673             else
4674                 bBlink = false;
4675 
4676             NewAttr(SvxBlinkItem(bBlink, RES_CHRATR_BLINK));
4677         }
4678     }
4679 }
4680 
SwWW8Shade(bool bVer67,const WW8_SHD & rSHD)4681 SwWW8Shade::SwWW8Shade(bool bVer67, const WW8_SHD& rSHD)
4682 {
4683     sal_uInt8 b = rSHD.GetFore();
4684     ASSERT(b < 17, "ww8: colour out of range");
4685     if (b >= 17)
4686         b = 0;
4687 
4688     ColorData nFore(SwWW8ImplReader::GetCol(b));
4689 
4690     b = rSHD.GetBack();
4691     ASSERT(b < 17, "ww8: colour out of range");
4692     if( b >=  17 )
4693         b = 0;
4694 
4695     ColorData nBack(SwWW8ImplReader::GetCol(b));
4696 
4697     b = rSHD.GetStyle(bVer67);
4698 
4699     SetShade(nFore, nBack, b);
4700 }
4701 
SetShade(ColorData nFore,ColorData nBack,sal_uInt16 nIndex)4702 void SwWW8Shade::SetShade(ColorData nFore, ColorData nBack, sal_uInt16 nIndex)
4703 {
4704     static const sal_uLong eMSGrayScale[] =
4705     {
4706         // Nul-Brush
4707            0,   // 0
4708         // Solid-Brush
4709         1000,   // 1
4710         // promillemaessig abgestufte Schattierungen
4711           50,   // 2
4712          100,   // 3
4713          200,   // 4
4714          250,   // 5
4715          300,   // 6
4716          400,   // 7
4717          500,   // 8
4718          600,   // 9
4719          700,   // 10
4720          750,   // 11
4721          800,   // 12
4722          900,   // 13
4723          333, // 14 Dark Horizontal
4724          333, // 15 Dark Vertical
4725          333, // 16 Dark Forward Diagonal
4726          333, // 17 Dark Backward Diagonal
4727          333, // 18 Dark Cross
4728          333, // 19 Dark Diagonal Cross
4729          333, // 20 Horizontal
4730          333, // 21 Vertical
4731          333, // 22 Forward Diagonal
4732          333, // 23 Backward Diagonal
4733          333, // 24 Cross
4734          333, // 25 Diagonal Cross
4735          // neun Nummern ohne Bedeutung in Ver8
4736          500, // 26
4737          500, // 27
4738          500, // 28
4739          500, // 29
4740          500, // 30
4741          500, // 31
4742          500, // 32
4743          500, // 33
4744          500, // 34
4745          // und weiter gehts mit tollen Schattierungen ;-)
4746           25,   // 35
4747           75,   // 36
4748          125,   // 37
4749          150,   // 38
4750          175,   // 39
4751          225,   // 40
4752          275,   // 41
4753          325,   // 42
4754          350,   // 43
4755          375,   // 44
4756          425,   // 45
4757          450,   // 46
4758          475,   // 47
4759          525,   // 48
4760          550,   // 49
4761          575,   // 50
4762          625,   // 51
4763          650,   // 52
4764          675,   // 53
4765          725,   // 54
4766          775,   // 55
4767          825,   // 56
4768          850,   // 57
4769          875,   // 58
4770          925,   // 59
4771          950,   // 60
4772          975,   // 61
4773          // und zu guter Letzt:
4774          970
4775     };// 62
4776 
4777 
4778     //NO auto for shading so Foreground: Auto = Black
4779     if (nFore == COL_AUTO)
4780         nFore = COL_BLACK;
4781 
4782     //NO auto for shading so background: Auto = Weiss
4783     ColorData nUseBack = nBack;
4784     if (nUseBack == COL_AUTO)
4785         nUseBack = COL_WHITE;
4786 
4787 
4788     if( nIndex >= sizeof( eMSGrayScale ) / sizeof ( eMSGrayScale[ 0 ] ) )
4789         nIndex = 0;
4790 
4791     sal_uLong nWW8BrushStyle = eMSGrayScale[nIndex];
4792 
4793     switch (nWW8BrushStyle)
4794     {
4795         case 0: // Null-Brush
4796             aColor.SetColor( nBack );
4797             break;
4798         default:
4799             {
4800                 Color aForeColor(nFore);
4801                 Color aBackColor(nUseBack);
4802 
4803                 sal_uInt32 nRed = aForeColor.GetRed() * nWW8BrushStyle;
4804                 sal_uInt32 nGreen = aForeColor.GetGreen() * nWW8BrushStyle;
4805                 sal_uInt32 nBlue = aForeColor.GetBlue() * nWW8BrushStyle;
4806                 nRed += aBackColor.GetRed()  * (1000L - nWW8BrushStyle);
4807                 nGreen += aBackColor.GetGreen()* (1000L - nWW8BrushStyle);
4808                 nBlue += aBackColor.GetBlue() * (1000L - nWW8BrushStyle);
4809 
4810                 aColor.SetColor( RGB_COLORDATA( nRed/1000, nGreen/1000,
4811                     nBlue/1000 ) );
4812             }
4813             break;
4814     }
4815 }
4816 
Read_Shade(sal_uInt16,const sal_uInt8 * pData,short nLen)4817 void SwWW8ImplReader::Read_Shade( sal_uInt16, const sal_uInt8* pData, short nLen )
4818 {
4819     if (!bVer67 && pPlcxMan && pPlcxMan->GetPapPLCF()->HasSprm(0xC64D))
4820         return;
4821 
4822     if (nLen <= 0)
4823     {
4824         // Ende des Attributes
4825         pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_BACKGROUND );
4826         if (bShdTxtCol)
4827         {
4828             // Zeichenfarbe auch
4829             pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_CHRATR_COLOR );
4830             bShdTxtCol = false;
4831         }
4832     }
4833     else
4834     {
4835         WW8_SHD aSHD;
4836         aSHD.SetWWValue( *(SVBT16*)pData );
4837         SwWW8Shade aSh( bVer67, aSHD );
4838 
4839         NewAttr(SvxBrushItem(aSh.aColor, RES_BACKGROUND));
4840     }
4841 }
4842 
Read_ParaBackColor(sal_uInt16,const sal_uInt8 * pData,short nLen)4843 void SwWW8ImplReader::Read_ParaBackColor(sal_uInt16, const sal_uInt8* pData, short nLen)
4844 {
4845     if (nLen <= 0)
4846     {
4847         // Ende des Attributes
4848         pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_BACKGROUND );
4849         if (bShdTxtCol)
4850         {
4851             // Zeichenfarbe auch
4852             pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_CHRATR_COLOR );
4853             bShdTxtCol = false;
4854         }
4855     }
4856     else
4857     {
4858         ASSERT(nLen == 10, "Len of para back colour not 10!");
4859         if (nLen != 10)
4860             return;
4861         NewAttr(SvxBrushItem(Color(ExtractColour(pData, bVer67)), RES_BACKGROUND));
4862     }
4863 }
4864 
ExtractColour(const sal_uInt8 * & rpData,bool bVer67)4865 sal_uInt32 SwWW8ImplReader::ExtractColour(const sal_uInt8* &rpData,
4866 	bool
4867 #ifdef DBG_UTIL
4868 		bVer67
4869 #endif
4870 	)
4871 {
4872     ASSERT(bVer67 == false, "Impossible");
4873     //ASSERT(SVBT32ToUInt32(rpData) == 0xFF000000, "Unknown 1 not 0xff000000");
4874     sal_uInt32 nFore = wwUtility::BGRToRGB(SVBT32ToUInt32(rpData));
4875     rpData+=4;
4876     sal_uInt32 nBack = wwUtility::BGRToRGB(SVBT32ToUInt32(rpData));
4877     rpData+=4;
4878     sal_uInt16 nIndex = SVBT16ToShort(rpData);
4879     rpData+=2;
4880     //Being a transparent background colour doesn't actually show the page
4881     //background through, it merely acts like white
4882     if (nBack == 0xFF000000)
4883         nBack = COL_AUTO;
4884     ASSERT(nBack == COL_AUTO || !(nBack & 0xFF000000),
4885         "ww8: don't know what to do with such a transparent bg colour, report");
4886     SwWW8Shade aShade(nFore, nBack, nIndex);
4887     return aShade.aColor.GetColor();
4888 }
4889 
Read_Border(sal_uInt16,const sal_uInt8 *,short nLen)4890 void SwWW8ImplReader::Read_Border(sal_uInt16 , const sal_uInt8* , short nLen)
4891 {
4892     if( nLen < 0 )
4893     {
4894         if( bHasBorder )
4895         {
4896             pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_BOX );
4897             pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_SHADOW );
4898             bHasBorder = false;
4899         }
4900     }
4901     else if( !bHasBorder )
4902     {
4903         // die Borders auf allen 4 Seiten werden gebuendelt.  dieses
4904         // vereinfacht die Verwaltung, d.h. die Box muss nicht 4 mal auf den
4905         // CtrlStack und wieder runter
4906         bHasBorder = true;
4907 
4908         WW8_BRC5 aBrcs;   // Top, Left, Bottom, Right, Between
4909         sal_uInt8 nBorder;
4910 
4911         if( pAktColl )
4912             nBorder = ::lcl_ReadBorders(bVer67, aBrcs, 0, pStyles);
4913         else
4914             nBorder = ::lcl_ReadBorders(bVer67, aBrcs, pPlcxMan->GetPapPLCF());
4915 
4916         if( nBorder )                                   // Border
4917         {
4918             bool bIsB = IsBorder(aBrcs, true);
4919             if (!InLocalApo() || !bIsB ||
4920                 (pWFlyPara && !pWFlyPara->bBorderLines ))
4921             {
4922                 // in Apo keine Umrandungen *ein*-schalten, da ich
4923                 // sonst die Flyumrandungen doppelt bekomme
4924                 // JP 04.12.98: aber nur wenn am Fly ein gesetzt ist, keine
4925                 //              uebernehmen. Sonst wird gar keine gesetzt!
4926                 //              Bug #59619#
4927 
4928                 // auch wenn kein Rand gesetzt ist, muss das Attribut gesetzt
4929                 // werden, sonst ist kein hartes Ausschalten von Style-Attrs
4930                 // moeglich
4931                 const SvxBoxItem* pBox
4932                     = (const SvxBoxItem*)GetFmtAttr( RES_BOX );
4933                 SvxBoxItem aBox(RES_BOX);
4934                 if (pBox)
4935                     aBox = *pBox;
4936                 short aSizeArray[5]={0};
4937 
4938                 SetBorder(aBox, aBrcs, &aSizeArray[0], nBorder);
4939 
4940                 Rectangle aInnerDist;
4941                 GetBorderDistance( aBrcs, aInnerDist );
4942 
4943                 maTracer.Log(sw::log::eBorderDistOutside);
4944 
4945                 aBox.SetDistance( (sal_uInt16)aInnerDist.Left(), BOX_LINE_LEFT );
4946                 aBox.SetDistance( (sal_uInt16)aInnerDist.Top(), BOX_LINE_TOP );
4947                 aBox.SetDistance( (sal_uInt16)aInnerDist.Right(), BOX_LINE_RIGHT );
4948                 aBox.SetDistance( (sal_uInt16)aInnerDist.Bottom(), BOX_LINE_BOTTOM );
4949 
4950                 NewAttr( aBox );
4951 
4952                 SvxShadowItem aS(RES_SHADOW);
4953                 if( SetShadow( aS, &aSizeArray[0], aBrcs ) )
4954                     NewAttr( aS );
4955             }
4956         }
4957     }
4958 }
4959 
Read_Hyphenation(sal_uInt16,const sal_uInt8 * pData,short nLen)4960 void SwWW8ImplReader::Read_Hyphenation( sal_uInt16, const sal_uInt8* pData, short nLen )
4961 {
4962     // set Hyphenation flag
4963     if( nLen <= 0 )
4964         pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_PARATR_HYPHENZONE );
4965     else
4966     {
4967         SvxHyphenZoneItem aAttr(
4968             *(const SvxHyphenZoneItem*)GetFmtAttr( RES_PARATR_HYPHENZONE ) );
4969 
4970         aAttr.SetHyphen( 0 == *pData ); // sic !
4971 
4972         if( !*pData )
4973         {
4974             aAttr.GetMinLead()    = 2;
4975             aAttr.GetMinTrail()   = 2;
4976             aAttr.GetMaxHyphens() = 0;
4977         }
4978 
4979         NewAttr( aAttr );
4980     }
4981 }
4982 
Read_WidowControl(sal_uInt16,const sal_uInt8 * pData,short nLen)4983 void SwWW8ImplReader::Read_WidowControl( sal_uInt16, const sal_uInt8* pData, short nLen )
4984 {
4985     if( nLen <= 0 )
4986     {
4987         pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_PARATR_WIDOWS );
4988         pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_PARATR_ORPHANS );
4989     }
4990     else
4991     {
4992         sal_uInt8 nL = ( *pData & 1 ) ? 2 : 0;
4993 
4994         NewAttr( SvxWidowsItem( nL, RES_PARATR_WIDOWS ) );     // Aus -> nLines = 0
4995         NewAttr( SvxOrphansItem( nL, RES_PARATR_ORPHANS ) );
4996 
4997         if( pAktColl && pStyles )           // Style-Def ?
4998             pStyles->bWidowsChanged = true; // merken zur Simulation
4999                                             // Default-Widows
5000     }
5001 }
5002 
Read_UsePgsuSettings(sal_uInt16,const sal_uInt8 * pData,short nLen)5003 void SwWW8ImplReader::Read_UsePgsuSettings(sal_uInt16,const sal_uInt8* pData,short nLen)
5004 {
5005     if( nLen <= 0 )
5006         pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_PARATR_SNAPTOGRID);
5007     else
5008     {
5009         if(nInTable)
5010             NewAttr( SvxParaGridItem(false, RES_PARATR_SNAPTOGRID) );
5011         else
5012             NewAttr( SvxParaGridItem(*pData, RES_PARATR_SNAPTOGRID) );
5013     }
5014 }
5015 
Read_AlignFont(sal_uInt16,const sal_uInt8 * pData,short nLen)5016 void SwWW8ImplReader::Read_AlignFont( sal_uInt16, const sal_uInt8* pData, short nLen )
5017 {
5018     if( nLen <= 0 )
5019         pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_PARATR_VERTALIGN);
5020     else
5021     {
5022         sal_uInt16 nVal = SVBT16ToShort( pData );
5023         switch (nVal)
5024         {
5025             case 0:
5026                 nVal = SvxParaVertAlignItem::TOP;
5027                 break;
5028             case 1:
5029                 nVal = SvxParaVertAlignItem::CENTER;
5030                 break;
5031             case 2:
5032                 nVal = SvxParaVertAlignItem::BASELINE;
5033                 break;
5034             case 3:
5035                 nVal = SvxParaVertAlignItem::BOTTOM;
5036                 break;
5037             case 4:
5038                 nVal = SvxParaVertAlignItem::AUTOMATIC;
5039                 break;
5040             default:
5041                 nVal = SvxParaVertAlignItem::AUTOMATIC;
5042                 ASSERT(sal_False,"Unknown paragraph vertical align");
5043                 break;
5044         }
5045         NewAttr( SvxParaVertAlignItem( nVal, RES_PARATR_VERTALIGN ) );
5046     }
5047 }
5048 
Read_KeepLines(sal_uInt16,const sal_uInt8 * pData,short nLen)5049 void SwWW8ImplReader::Read_KeepLines( sal_uInt16, const sal_uInt8* pData, short nLen )
5050 {
5051     if( nLen <= 0 )
5052         pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_PARATR_SPLIT );
5053     else
5054         NewAttr( SvxFmtSplitItem( ( *pData & 1 ) == 0, RES_PARATR_SPLIT ) );
5055 }
5056 
Read_KeepParas(sal_uInt16,const sal_uInt8 * pData,short nLen)5057 void SwWW8ImplReader::Read_KeepParas( sal_uInt16, const sal_uInt8* pData, short nLen )
5058 {
5059     if( nLen <= 0 )
5060         pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_KEEP );
5061     else
5062         NewAttr( SvxFmtKeepItem( ( *pData & 1 ) != 0 , RES_KEEP) );
5063 }
5064 
Read_BreakBefore(sal_uInt16,const sal_uInt8 * pData,short nLen)5065 void SwWW8ImplReader::Read_BreakBefore( sal_uInt16, const sal_uInt8* pData, short nLen )
5066 {
5067     if( nLen <= 0 )
5068         pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_BREAK );
5069     else
5070         NewAttr( SvxFmtBreakItem(
5071                 ( *pData & 1 ) ? SVX_BREAK_PAGE_BEFORE : SVX_BREAK_NONE, RES_BREAK ) );
5072 }
5073 
Read_ApoPPC(sal_uInt16,const sal_uInt8 * pData,short)5074 void SwWW8ImplReader::Read_ApoPPC( sal_uInt16, const sal_uInt8* pData, short )
5075 {
5076     if (pAktColl) // only for Styledef, sonst anders geloest
5077     {
5078         SwWW8StyInf& rSI = pCollA[nAktColl];
5079         WW8FlyPara* pFly = rSI.pWWFly ? rSI.pWWFly : new WW8FlyPara(bVer67);
5080         pCollA[nAktColl].pWWFly = pFly;
5081         pFly->Read(pData, pStyles);
5082         if (pFly->IsEmpty())
5083             delete pCollA[nAktColl].pWWFly, pCollA[nAktColl].pWWFly = 0;
5084     }
5085 }
5086 
ParseTabPos(WW8_TablePos * pTabPos,WW8PLCFx_Cp_FKP * pPap)5087 bool SwWW8ImplReader::ParseTabPos(WW8_TablePos *pTabPos, WW8PLCFx_Cp_FKP* pPap)
5088 {
5089     bool bRet = false;
5090     const sal_uInt8 *pRes=0;
5091     memset(pTabPos, 0, sizeof(WW8_TablePos));
5092     if (0 != (pRes = pPap->HasSprm(0x360D)))
5093     {
5094         pTabPos->nSp29 = *pRes;
5095         pTabPos->nSp37 = 2;     //Possible fail area, always parallel wrap
5096         if (0 != (pRes = pPap->HasSprm(0x940E)))
5097             pTabPos->nSp26 = SVBT16ToShort(pRes);
5098         if (0 != (pRes = pPap->HasSprm(0x940F)))
5099             pTabPos->nSp27 = SVBT16ToShort(pRes);
5100         if (0 != (pRes = pPap->HasSprm(0x9410)))
5101             pTabPos->nLeMgn = SVBT16ToShort(pRes);
5102         if (0 != (pRes = pPap->HasSprm(0x941E)))
5103             pTabPos->nRiMgn = SVBT16ToShort(pRes);
5104         if (0 != (pRes = pPap->HasSprm(0x9411)))
5105             pTabPos->nUpMgn = SVBT16ToShort(pRes);
5106         if (0 != (pRes = pPap->HasSprm(0x941F)))
5107             pTabPos->nLoMgn = SVBT16ToShort(pRes);
5108         bRet = true;
5109     }
5110     return bRet;
5111 }
5112 
5113 /***************************************************************************
5114 #  Seiten - Attribute werden nicht mehr als Attribute gehandhabt
5115 #   ( ausser OLST )
5116 #**************************************************************************/
5117 
5118 
ImportExtSprm(WW8PLCFManResult * pRes)5119 long SwWW8ImplReader::ImportExtSprm(WW8PLCFManResult* pRes)
5120 {
5121     /*************************************************************************
5122     #       Arrays zum Lesen der erweiterten ( selbstdefinierten ) SPRMs
5123     #*************************************************************************/
5124     typedef long (SwWW8ImplReader:: *FNReadRecordExt)(WW8PLCFManResult*);
5125 
5126     static const FNReadRecordExt aWwSprmTab[] =
5127     {
5128         /* 0 (256) */   &SwWW8ImplReader::Read_Ftn,     // FootNote
5129         /* 1 (257) */   &SwWW8ImplReader::Read_Ftn,     // EndNote
5130         /* 2 (258) */   &SwWW8ImplReader::Read_Field,  // Feld
5131         /* 3 (259) */   &SwWW8ImplReader::Read_Book,   // Bookmark
5132         /* 4 (260) */   &SwWW8ImplReader::Read_And     // Annotation
5133     };
5134 
5135     if( pRes->nSprmId < 280 )
5136     {
5137         sal_uInt8 nIdx = static_cast< sal_uInt8 >(pRes->nSprmId - eFTN);
5138         if( nIdx < sizeof( aWwSprmTab ) / sizeof( *aWwSprmTab )
5139             && aWwSprmTab[nIdx] )
5140             return (this->*aWwSprmTab[nIdx])(pRes);
5141         else
5142             return 0;
5143     }
5144     else
5145         return 0;
5146 }
5147 
EndExtSprm(sal_uInt16 nSprmId)5148 void SwWW8ImplReader::EndExtSprm(sal_uInt16 nSprmId)
5149 {
5150     typedef sal_uInt16 (SwWW8ImplReader:: *FNReadRecordExt)();
5151 
5152     static const FNReadRecordExt aWwSprmTab[] =
5153     {
5154         /* 0 (256) */   &SwWW8ImplReader::End_Ftn,      // FootNote
5155         /* 1 (257) */   &SwWW8ImplReader::End_Ftn,      // EndNote
5156         /* 2 (258) */   &SwWW8ImplReader::End_Field,  // Feld
5157         /* 3 (259) */   0,   // Bookmark
5158         /* 4 (260) */   0     // Annotation
5159     };
5160 
5161     sal_uInt8 nIdx = static_cast< sal_uInt8 >(nSprmId - eFTN);
5162     if( nIdx < sizeof( aWwSprmTab ) / sizeof( *aWwSprmTab )
5163         && aWwSprmTab[nIdx] )
5164         (this->*aWwSprmTab[nIdx])();
5165 }
5166 
5167 /***************************************************************************
5168 #       Arrays zum Lesen der SPRMs
5169 #**************************************************************************/
5170 
5171 // Funktion zum Einlesen von Sprms. Par1: SprmId
5172 typedef void (SwWW8ImplReader:: *FNReadRecord)( sal_uInt16, const sal_uInt8*, short );
5173 
5174 struct SprmReadInfo
5175 {
5176     sal_uInt16       nId;
5177     FNReadRecord pReadFnc;
5178 };
5179 
operator ==(const SprmReadInfo & rFirst,const SprmReadInfo & rSecond)5180 bool operator==(const SprmReadInfo &rFirst, const SprmReadInfo &rSecond)
5181 {
5182     return (rFirst.nId == rSecond.nId);
5183 }
5184 
operator <(const SprmReadInfo & rFirst,const SprmReadInfo & rSecond)5185 bool operator<(const SprmReadInfo &rFirst, const SprmReadInfo &rSecond)
5186 {
5187     return (rFirst.nId < rSecond.nId);
5188 }
5189 
5190 typedef ww::SortedArray<SprmReadInfo> wwSprmDispatcher;
5191 
GetWW2SprmDispatcher()5192 const wwSprmDispatcher *GetWW2SprmDispatcher()
5193 {
5194     static SprmReadInfo aSprms[] =
5195     {
5196           {0, 0},                                    // "0" Default bzw. Error
5197                                                      //wird uebersprungen! ,
5198           {2, &SwWW8ImplReader::Read_StyleCode},     //"sprmPIstd",  pap.istd
5199                                                      //(style code)
5200           {3, 0},                                    //"sprmPIstdPermute", pap.istd
5201                                                      //permutation
5202           {4, 0},                                    //"sprmPIncLv1",
5203                                                      //pap.istddifference
5204           {5, &SwWW8ImplReader::Read_Justify},       //"sprmPJc", pap.jc
5205                                                      //(justification)
5206           {6, 0},                                    //"sprmPFSideBySide",
5207                                                      //pap.fSideBySide
5208           {7, &SwWW8ImplReader::Read_KeepLines},     //"sprmPFKeep", pap.fKeep
5209           {8, &SwWW8ImplReader::Read_KeepParas},     //"sprmPFKeepFollow ",
5210                                                      //pap.fKeepFollow
5211           {9, &SwWW8ImplReader::Read_BreakBefore},   //"sprmPPageBreakBefore",
5212                                                      //pap.fPageBreakBefore
5213          {10, 0},                                    //"sprmPBrcl", pap.brcl
5214          {11, 0},                                    //"sprmPBrcp ", pap.brcp
5215          {12, &SwWW8ImplReader::Read_ANLevelDesc},   //"sprmPAnld", pap.anld (ANLD
5216                                                      //structure)
5217          {13, &SwWW8ImplReader::Read_ANLevelNo},     //"sprmPNLvlAnm", pap.nLvlAnm
5218                                                      //nn
5219          {14, &SwWW8ImplReader::Read_NoLineNumb},    //"sprmPFNoLineNumb", ap.fNoLnn
5220          {15, &SwWW8ImplReader::Read_Tab},           //"?sprmPChgTabsPapx",
5221                                                      //pap.itbdMac, ...
5222          {16, &SwWW8ImplReader::Read_LR},            //"sprmPDxaRight", pap.dxaRight
5223          {17, &SwWW8ImplReader::Read_LR},            //"sprmPDxaLeft", pap.dxaLeft
5224          {18, 0},                                    //"sprmPNest", pap.dxaLeft
5225          {19, &SwWW8ImplReader::Read_LR},            //"sprmPDxaLeft1", pap.dxaLeft1
5226          {20, &SwWW8ImplReader::Read_LineSpace},     //"sprmPDyaLine", pap.lspd
5227                                                      //an LSPD
5228          {21, &SwWW8ImplReader::Read_UL},            //"sprmPDyaBefore",
5229                                                      //pap.dyaBefore
5230          {22, &SwWW8ImplReader::Read_UL},            //"sprmPDyaAfter", pap.dyaAfter
5231          {23, 0},                                    //"?sprmPChgTabs", pap.itbdMac,
5232                                                      //pap.rgdxaTab, ...
5233          {24, 0},                                    //"sprmPFInTable", pap.fInTable
5234          {25, &SwWW8ImplReader::Read_TabRowEnd},     //"sprmPTtp", pap.fTtp
5235          {26, 0},                                    //"sprmPDxaAbs", pap.dxaAbs
5236          {27, 0},                                    //"sprmPDyaAbs", pap.dyaAbs
5237          {28, 0},                                    //"sprmPDxaWidth", pap.dxaWidth
5238          {29, &SwWW8ImplReader::Read_ApoPPC},        //"sprmPPc", pap.pcHorz,
5239                                                      //pap.pcVert
5240          {30, 0},                                    //"sprmPBrcTop10", pap.brcTop
5241                                                      //BRC10
5242          {31, 0},                                    //"sprmPBrcLeft10",
5243                                                      //pap.brcLeft BRC10
5244          {32, 0},                                    //"sprmPBrcBottom10",
5245                                                      //pap.brcBottom BRC10
5246          {33, 0},                                    //"sprmPBrcRight10",
5247                                                      //pap.brcRight BRC10
5248          {34, 0},                                    //"sprmPBrcBetween10",
5249                                                      //pap.brcBetween BRC10
5250          {35, 0},                                    //"sprmPBrcBar10", pap.brcBar
5251                                                      //BRC10
5252          {36, 0},                                    //"sprmPFromText10",
5253                                                      //pap.dxaFromText dxa
5254          {37, 0},                                    //"sprmPWr", pap.wr wr
5255          {38, &SwWW8ImplReader::Read_Border},        //"sprmPBrcTop", pap.brcTop BRC
5256          {39, &SwWW8ImplReader::Read_Border},        //"sprmPBrcLeft",
5257                                                      //pap.brcLeft BRC
5258          {40, &SwWW8ImplReader::Read_Border},        //"sprmPBrcBottom",
5259                                                      //pap.brcBottom BRC
5260          {41, &SwWW8ImplReader::Read_Border},        //"sprmPBrcRight",
5261                                                      //pap.brcRight BRC
5262          {42, &SwWW8ImplReader::Read_Border},        //"sprmPBrcBetween",
5263                                                      //pap.brcBetween BRC
5264          {43, 0},                                    //"sprmPBrcBar", pap.brcBar
5265                                                      //BRC word
5266          {44, &SwWW8ImplReader::Read_Hyphenation},   //"sprmPFNoAutoHyph",
5267                                                      //pap.fNoAutoHyph
5268          {45, 0},                                    //"sprmPWHeightAbs",
5269                                                      //pap.wHeightAbs w
5270          {46, 0},                                    //"sprmPDcs", pap.dcs DCS
5271          {47, &SwWW8ImplReader::Read_Shade},         //"sprmPShd", pap.shd SHD
5272          {48, 0},                                    //"sprmPDyaFromText",
5273                                                      //pap.dyaFromText dya
5274          {49, 0},                                    //"sprmPDxaFromText",
5275                                                      //pap.dxaFromText dxa
5276          {50, 0},                                    //"sprmPFLocked", pap.fLocked
5277                                                      //0 or 1 byte
5278          {51, &SwWW8ImplReader::Read_WidowControl},  //"sprmPFWidowControl",
5279                                                      //pap.fWidowControl 0 or 1 byte
5280          {52, 0},                                    //"?sprmPRuler 52",
5281          {53, 0},                                    //"??53",
5282          {54, 0},                                    //"??54",
5283          {55, 0},                                    //"??55",
5284          {56, 0},                                    //"??56",
5285          {57, 0},                                    //"??57",
5286          {58, 0},                                    //"??58",
5287          {59, 0},                                    //"??59",
5288 
5289          {60, &SwWW8ImplReader::Read_BoldUsw},       //"sprmCFBold", chp.fBold 0,1,
5290                                                      //128, or 129 byte
5291          {61, &SwWW8ImplReader::Read_BoldUsw},       //"sprmCFItalic", chp.fItalic
5292                                                      //0,1, 128, or 129 byte
5293          {62, &SwWW8ImplReader::Read_BoldUsw},       //"sprmCFStrike", chp.fStrike
5294                                                      //0,1, 128, or 129 byte
5295          {63, &SwWW8ImplReader::Read_BoldUsw},       //"sprmCFOutline", chp.fOutline
5296                                                      //0,1, 128, or 129 byte
5297          {64, &SwWW8ImplReader::Read_BoldUsw},       //"sprmCFShadow", chp.fShadow
5298                                                      //0,1, 128, or 129 byte
5299          {65, &SwWW8ImplReader::Read_BoldUsw},       //"sprmCFSmallCaps",
5300                                                      //chp.fSmallCaps 0,1, 128, or
5301                                                      //129 byte
5302          {66, &SwWW8ImplReader::Read_BoldUsw},       //"sprmCFCaps", chp.fCaps 0,1,
5303                                                      //128, or 129 byte
5304          {67, &SwWW8ImplReader::Read_BoldUsw},       //"sprmCFVanish", chp.fVanish
5305                                                      //0,1, 128, or 129 byte
5306          {68, &SwWW8ImplReader::Read_FontCode},      //"sprmCFtc", chp.ftc ftc word
5307          {69, &SwWW8ImplReader::Read_Underline},     // "sprmCKul", chp.kul kul byte
5308          {70, 0},                                    //"sprmCSizePos", chp.hps,
5309                                                      //chp.hpsPos 3 bytes
5310          {71, &SwWW8ImplReader::Read_Kern},          //"sprmCDxaSpace",
5311                                                      //chp.dxaSpace dxa word
5312          {72, &SwWW8ImplReader::Read_Language},      //"sprmCLid", chp.lid LID word
5313          {73, &SwWW8ImplReader::Read_TxtColor},      //"sprmCIco", chp.ico ico byte
5314          {74, &SwWW8ImplReader::Read_FontSize},      //"sprmCHps", chp.hps hps word!
5315          {75, 0},                                    //"sprmCHpsInc", chp.hps byte
5316          {76, &SwWW8ImplReader::Read_SubSuperProp},  //"sprmCHpsPos", chp.hpsPos
5317                                                      //hps byte
5318          {77, 0},                                    //"sprmCHpsPosAdj", chp.hpsPos
5319                                                      //hps byte
5320          {78, &SwWW8ImplReader::Read_Majority},      //"?sprmCMajority", chp.fBold,
5321                                                      //chp.fItalic, chp.fSmallCaps
5322          {80, &SwWW8ImplReader::Read_BoldBiDiUsw},   //sprmCFBoldBi
5323          {81, &SwWW8ImplReader::Read_BoldBiDiUsw},   //sprmCFItalicBi
5324          {82, &SwWW8ImplReader::Read_FontCode},      //sprmCFtcBi
5325          {83, &SwWW8ImplReader::Read_Language},      //sprmClidBi
5326          {84, &SwWW8ImplReader::Read_TxtColor},      //sprmCIcoBi
5327          {85, &SwWW8ImplReader::Read_FontSize},      //sprmCHpsBi
5328          {86, 0},                                    //sprmCFBiDi
5329          {87, 0},                                    //sprmCFDiacColor
5330          {94, 0},                                    //"sprmPicBrcl", pic.brcl brcl
5331                                                      //(see PIC structure
5332                                                      //definition) byte
5333          {95, 0},                                    //"sprmPicScale", pic.mx,
5334                                                      //pic.my, pic.dxaCropleft,
5335          {96, 0},                                    //"sprmPicBrcTop", pic.brcTop
5336                                                      //BRC word
5337          {97, 0},                                    //"sprmPicBrcLeft",
5338                                                      //pic.brcLeft BRC word
5339          {98, 0},                                    //"sprmPicBrcBottom",
5340                                                      //pic.brcBottom BRC word
5341          {99, 0}                                     //"sprmPicBrcRight",
5342     };
5343 
5344     static wwSprmDispatcher aSprmSrch(aSprms, sizeof(aSprms) / sizeof(aSprms[0]));
5345     return &aSprmSrch;
5346 }
5347 
GetWW6SprmDispatcher()5348 const wwSprmDispatcher *GetWW6SprmDispatcher()
5349 {
5350     static SprmReadInfo aSprms[] =
5351     {
5352           {0, 0},                                    // "0" Default bzw. Error
5353                                                      //wird uebersprungen! ,
5354           {2, &SwWW8ImplReader::Read_StyleCode},     //"sprmPIstd",  pap.istd
5355                                                      //(style code)
5356           {3, 0},                                    //"sprmPIstdPermute", pap.istd
5357                                                      //permutation
5358           {4, 0},                                    //"sprmPIncLv1",
5359                                                      //pap.istddifference
5360           {5, &SwWW8ImplReader::Read_Justify},       //"sprmPJc", pap.jc
5361                                                      //(justification)
5362           {6, 0},                                    //"sprmPFSideBySide",
5363                                                      //pap.fSideBySide
5364           {7, &SwWW8ImplReader::Read_KeepLines},     //"sprmPFKeep", pap.fKeep
5365           {8, &SwWW8ImplReader::Read_KeepParas},     //"sprmPFKeepFollow ",
5366                                                      //pap.fKeepFollow
5367           {9, &SwWW8ImplReader::Read_BreakBefore},   //"sprmPPageBreakBefore",
5368                                                      //pap.fPageBreakBefore
5369          {10, 0},                                    //"sprmPBrcl", pap.brcl
5370          {11, 0},                                    //"sprmPBrcp ", pap.brcp
5371          {12, &SwWW8ImplReader::Read_ANLevelDesc},   //"sprmPAnld", pap.anld (ANLD
5372                                                      //structure)
5373          {13, &SwWW8ImplReader::Read_ANLevelNo},     //"sprmPNLvlAnm", pap.nLvlAnm
5374                                                      //nn
5375          {14, &SwWW8ImplReader::Read_NoLineNumb},    //"sprmPFNoLineNumb", ap.fNoLnn
5376          {15, &SwWW8ImplReader::Read_Tab},           //"?sprmPChgTabsPapx",
5377                                                      //pap.itbdMac, ...
5378          {16, &SwWW8ImplReader::Read_LR},            //"sprmPDxaRight", pap.dxaRight
5379          {17, &SwWW8ImplReader::Read_LR},            //"sprmPDxaLeft", pap.dxaLeft
5380          {18, 0},                                    //"sprmPNest", pap.dxaLeft
5381          {19, &SwWW8ImplReader::Read_LR},            //"sprmPDxaLeft1", pap.dxaLeft1
5382          {20, &SwWW8ImplReader::Read_LineSpace},     //"sprmPDyaLine", pap.lspd
5383                                                      //an LSPD
5384          {21, &SwWW8ImplReader::Read_UL},            //"sprmPDyaBefore",
5385                                                      //pap.dyaBefore
5386          {22, &SwWW8ImplReader::Read_UL},            //"sprmPDyaAfter", pap.dyaAfter
5387          {23, 0},                                    //"?sprmPChgTabs", pap.itbdMac,
5388                                                      //pap.rgdxaTab, ...
5389          {24, 0},                                    //"sprmPFInTable", pap.fInTable
5390          {25, &SwWW8ImplReader::Read_TabRowEnd},     //"sprmPTtp", pap.fTtp
5391          {26, 0},                                    //"sprmPDxaAbs", pap.dxaAbs
5392          {27, 0},                                    //"sprmPDyaAbs", pap.dyaAbs
5393          {28, 0},                                    //"sprmPDxaWidth", pap.dxaWidth
5394          {29, &SwWW8ImplReader::Read_ApoPPC},        //"sprmPPc", pap.pcHorz,
5395                                                      //pap.pcVert
5396          {30, 0},                                    //"sprmPBrcTop10", pap.brcTop
5397                                                      //BRC10
5398          {31, 0},                                    //"sprmPBrcLeft10",
5399                                                      //pap.brcLeft BRC10
5400          {32, 0},                                    //"sprmPBrcBottom10",
5401                                                      //pap.brcBottom BRC10
5402          {33, 0},                                    //"sprmPBrcRight10",
5403                                                      //pap.brcRight BRC10
5404          {34, 0},                                    //"sprmPBrcBetween10",
5405                                                      //pap.brcBetween BRC10
5406          {35, 0},                                    //"sprmPBrcBar10", pap.brcBar
5407                                                      //BRC10
5408          {36, 0},                                    //"sprmPFromText10",
5409                                                      //pap.dxaFromText dxa
5410          {37, 0},                                    //"sprmPWr", pap.wr wr
5411          {38, &SwWW8ImplReader::Read_Border},        //"sprmPBrcTop", pap.brcTop BRC
5412          {39, &SwWW8ImplReader::Read_Border},        //"sprmPBrcLeft",
5413                                                      //pap.brcLeft BRC
5414          {40, &SwWW8ImplReader::Read_Border},        //"sprmPBrcBottom",
5415                                                      //pap.brcBottom BRC
5416          {41, &SwWW8ImplReader::Read_Border},        //"sprmPBrcRight",
5417                                                      //pap.brcRight BRC
5418          {42, &SwWW8ImplReader::Read_Border},        //"sprmPBrcBetween",
5419                                                      //pap.brcBetween BRC
5420          {43, 0},                                    //"sprmPBrcBar", pap.brcBar
5421                                                      //BRC word
5422          {44, &SwWW8ImplReader::Read_Hyphenation},   //"sprmPFNoAutoHyph",
5423                                                      //pap.fNoAutoHyph
5424          {45, 0},                                    //"sprmPWHeightAbs",
5425                                                      //pap.wHeightAbs w
5426          {46, 0},                                    //"sprmPDcs", pap.dcs DCS
5427          {47, &SwWW8ImplReader::Read_Shade},         //"sprmPShd", pap.shd SHD
5428          {48, 0},                                    //"sprmPDyaFromText",
5429                                                      //pap.dyaFromText dya
5430          {49, 0},                                    //"sprmPDxaFromText",
5431                                                      //pap.dxaFromText dxa
5432          {50, 0},                                    //"sprmPFLocked", pap.fLocked
5433                                                      //0 or 1 byte
5434          {51, &SwWW8ImplReader::Read_WidowControl},  //"sprmPFWidowControl",
5435                                                      //pap.fWidowControl 0 or 1 byte
5436          {52, 0},                                    //"?sprmPRuler 52",
5437          {53, 0},                                    //"??53",
5438          {54, 0},                                    //"??54",
5439          {55, 0},                                    //"??55",
5440          {56, 0},                                    //"??56",
5441          {57, 0},                                    //"??57",
5442          {58, 0},                                    //"??58",
5443          {59, 0},                                    //"??59",
5444          {60, 0},                                    //"??60",
5445          {61, 0},                                    //"??61",
5446          {62, 0},                                    //"??62",
5447          {63, 0},                                    //"??63",
5448          {64, &SwWW8ImplReader::Read_ParaBiDi},      //"rtl bidi ?
5449          {65, &SwWW8ImplReader::Read_CFRMarkDel},    //"sprmCFStrikeRM",
5450                                                      //chp.fRMarkDel 1 or 0 bit
5451          {66, &SwWW8ImplReader::Read_CFRMark},       //"sprmCFRMark", chp.fRMark
5452                                                      //1 or 0 bit
5453          {67, &SwWW8ImplReader::Read_FldVanish},     //"sprmCFFldVanish",
5454                                                      //chp.fFldVanish 1 or 0 bit
5455          {68, &SwWW8ImplReader::Read_PicLoc},        //"sprmCPicLocation",
5456                                                      //chp.fcPic and chp.fSpec
5457          {69, 0},                                    //"sprmCIbstRMark",
5458                                                      //chp.ibstRMark index into
5459                                                      //sttbRMark
5460          {70, 0},                                    //"sprmCDttmRMark", chp.dttm
5461                                                      //DTTM long
5462          {71, 0},                                    //"sprmCFData", chp.fData 1 or
5463                                                      //0 bit
5464          {72, 0},                                    //"sprmCRMReason",
5465                                                      //chp.idslRMReason an index to
5466                                                      //a table
5467          {73, &SwWW8ImplReader::Read_CharSet},       //"sprmCChse", chp.fChsDiff
5468                                                      //and chp.chse 3 bytes
5469          {74, &SwWW8ImplReader::Read_Symbol},        //"sprmCSymbol", chp.fSpec,
5470                                                      //chp.chSym and chp.ftcSym
5471          {75, &SwWW8ImplReader::Read_Obj},           //"sprmCFOle2", chp.fOle2 1
5472                                                      //or 0 bit
5473          {76, 0},                                    //"??76",
5474          {77, 0},                                    //"??77",
5475          {78, 0},                                    //"??78",
5476          {79, 0},                                    //"??79",
5477          {80, &SwWW8ImplReader::Read_CColl},         //"sprmCIstd", chp.istd istd,
5478                                                      //see stylesheet definition
5479                                                      //short
5480          {81, 0},                                    //"sprmCIstdPermute", chp.istd
5481                                                      //permutation vector
5482          {82, 0},                                    //"sprmCDefault", whole CHP
5483                                                      //none variable length
5484          {83, 0},                                    //"sprmCPlain", whole CHP
5485                                                      //none 0
5486          {84, 0},                                    //"??84",
5487          {85, &SwWW8ImplReader::Read_BoldUsw},       //"sprmCFBold", chp.fBold 0,1,
5488                                                      //128, or 129 byte
5489          {86, &SwWW8ImplReader::Read_BoldUsw},       //"sprmCFItalic", chp.fItalic
5490                                                      //0,1, 128, or 129 byte
5491          {87, &SwWW8ImplReader::Read_BoldUsw},       //"sprmCFStrike", chp.fStrike
5492                                                      //0,1, 128, or 129 byte
5493          {88, &SwWW8ImplReader::Read_BoldUsw},       //"sprmCFOutline", chp.fOutline
5494                                                      //0,1, 128, or 129 byte
5495          {89, &SwWW8ImplReader::Read_BoldUsw},       //"sprmCFShadow", chp.fShadow
5496                                                      //0,1, 128, or 129 byte
5497          {90, &SwWW8ImplReader::Read_BoldUsw},       //"sprmCFSmallCaps",
5498                                                      //chp.fSmallCaps 0,1, 128, or
5499                                                      //129 byte
5500          {91, &SwWW8ImplReader::Read_BoldUsw},       //"sprmCFCaps", chp.fCaps 0,1,
5501                                                      //128, or 129 byte
5502          {92, &SwWW8ImplReader::Read_BoldUsw},       //"sprmCFVanish", chp.fVanish
5503                                                      //0,1, 128, or 129 byte
5504          {93, &SwWW8ImplReader::Read_FontCode},      //"sprmCFtc", chp.ftc ftc word
5505          {94, &SwWW8ImplReader::Read_Underline},     // "sprmCKul", chp.kul kul byte
5506          {95, 0},                                    //"sprmCSizePos", chp.hps,
5507                                                      //chp.hpsPos 3 bytes
5508          {96, &SwWW8ImplReader::Read_Kern},          //"sprmCDxaSpace",
5509                                                      //chp.dxaSpace dxa word
5510          {97, &SwWW8ImplReader::Read_Language},      //"sprmCLid", chp.lid LID word
5511          {98, &SwWW8ImplReader::Read_TxtColor},      //"sprmCIco", chp.ico ico byte
5512          {99, &SwWW8ImplReader::Read_FontSize},      //"sprmCHps", chp.hps hps word!
5513         {100, 0},                                    //"sprmCHpsInc", chp.hps byte
5514         {101, &SwWW8ImplReader::Read_SubSuperProp},  //"sprmCHpsPos", chp.hpsPos
5515                                                      //hps byte
5516         {102, 0},                                    //"sprmCHpsPosAdj", chp.hpsPos
5517                                                      //hps byte
5518         {103, &SwWW8ImplReader::Read_Majority},      //"?sprmCMajority", chp.fBold,
5519                                                      //chp.fItalic, chp.fSmallCaps
5520         {104, &SwWW8ImplReader::Read_SubSuper},      //"sprmCIss", chp.iss iss byte
5521         {105, 0},                                    //"sprmCHpsNew50", chp.hps hps
5522                                                      //variable width, length
5523                                                      //always recorded as 2
5524         {106, 0},                                    //"sprmCHpsInc1", chp.hps
5525                                                      //complex variable width,
5526                                                      //length always recorded as 2
5527         {107, &SwWW8ImplReader::Read_FontKern},      //"sprmCHpsKern", chp.hpsKern
5528                                                      //hps short
5529         {108, &SwWW8ImplReader::Read_Majority},      //"sprmCMajority50", chp.fBold,
5530                                                      //chp.fItalic, chp.fSmallCaps,
5531                                                      // chp.fVanish, ...
5532         {109, 0},                                    //"sprmCHpsMul", chp.hps
5533                                                      //percentage to grow hps short
5534         {110, 0},                                    //"sprmCCondHyhen", chp.ysri
5535                                                      //ysri short
5536         {111, &SwWW8ImplReader::Read_FontCode},      //ww7 font
5537         {112, &SwWW8ImplReader::Read_FontCode},      //ww7 CJK font
5538         {113, &SwWW8ImplReader::Read_FontCode},      //ww7 rtl font
5539         {114, &SwWW8ImplReader::Read_Language},      //ww7 lid
5540         {115, &SwWW8ImplReader::Read_TxtColor},      //ww7 rtl colour ?
5541         {116, &SwWW8ImplReader::Read_FontSize},
5542         {117, &SwWW8ImplReader::Read_Special},       //"sprmCFSpec", chp.fSpec 1
5543                                                      //or 0 bit
5544         {118, &SwWW8ImplReader::Read_Obj},           //"sprmCFObj", chp.fObj 1 or 0
5545                                                      //bit
5546         {119, 0},                                    //"sprmPicBrcl", pic.brcl brcl
5547                                                      //(see PIC structure
5548                                                      //definition) byte
5549         {120, 0},                                    //"sprmPicScale", pic.mx,
5550                                                      //pic.my, pic.dxaCropleft,
5551         {121, 0},                                    //"sprmPicBrcTop", pic.brcTop
5552                                                      //BRC word
5553         {122, 0},                                    //"sprmPicBrcLeft",
5554                                                      //pic.brcLeft BRC word
5555         {123, 0},                                    //"sprmPicBrcBottom",
5556                                                      //pic.brcBottom BRC word
5557         {124, 0},                                    //"sprmPicBrcRight",
5558                                                      //pic.brcRight BRC word
5559         {125, 0},                                    //"??125",
5560         {126, 0},                                    //"??126",
5561         {127, 0},                                    //"??127",
5562         {128, 0},                                    //"??128",
5563         {129, 0},                                    //"??129",
5564         {130, 0},                                    //"??130",
5565         {131, 0},                                    //"sprmSScnsPgn", sep.cnsPgn
5566                                                      //cns byte
5567         {132, 0},                                    //"sprmSiHeadingPgn",
5568                                                      //sep.iHeadingPgn heading
5569                                                      //number level byte
5570         {133, &SwWW8ImplReader::Read_OLST},          //"sprmSOlstAnm", sep.olstAnm
5571                                                      //OLST variable length
5572         {134, 0},                                    //"??135",
5573         {135, 0},                                    //"??135",
5574         {136, 0},                                    //"sprmSDxaColWidth",
5575                                                      //sep.rgdxaColWidthSpacing
5576                                                      //complex 3 bytes
5577         {137, 0},                                    //"sprmSDxaColSpacing",
5578                                                      //sep.rgdxaColWidthSpacing
5579                                                      //complex 3 bytes
5580         {138, 0},                                    //"sprmSFEvenlySpaced",
5581                                                      //sep.fEvenlySpaced 1 or 0 byte
5582         {139, 0},                                    //"sprmSFProtected",
5583                                                      //sep.fUnlocked 1 or 0 byte
5584         {140, 0},                                    //"sprmSDmBinFirst",
5585                                                      //sep.dmBinFirst  word
5586         {141, 0},                                    //"sprmSDmBinOther",
5587                                                      //sep.dmBinOther  word
5588         {142, 0},                                    //"sprmSBkc", sep.bkc bkc
5589                                                      //byte BreakCode
5590         {143, 0},                                    //"sprmSFTitlePage",
5591                                                      //sep.fTitlePage 0 or 1 byte
5592         {144, 0},                                    //"sprmSCcolumns", sep.ccolM1
5593                                                      //# of cols - 1 word
5594         {145, 0},                                    //"sprmSDxaColumns",
5595                                                      //sep.dxaColumns dxa word
5596         {146, 0},                                    //"sprmSFAutoPgn",
5597                                                      //sep.fAutoPgn obsolete byte
5598         {147, 0},                                    //"sprmSNfcPgn", sep.nfcPgn
5599                                                      //nfc byte
5600         {148, 0},                                    //"sprmSDyaPgn", sep.dyaPgn
5601                                                      //dya short
5602         {149, 0},                                    //"sprmSDxaPgn", sep.dxaPgn
5603                                                      //dya short
5604         {150, 0},                                    //"sprmSFPgnRestart",
5605                                                      //sep.fPgnRestart 0 or 1 byte
5606         {151, 0},                                    //"sprmSFEndnote", sep.fEndnote
5607                                                      //0 or 1 byte
5608         {152, 0},                                    //"sprmSLnc", sep.lnc lnc byte
5609         {153, 0},                                    //"sprmSGprfIhdt", sep.grpfIhdt
5610                                                      //grpfihdt byte
5611         {154, 0},                                    //"sprmSNLnnMod", sep.nLnnMod
5612                                                      //non-neg int. word
5613         {155, 0},                                    //"sprmSDxaLnn", sep.dxaLnn
5614                                                      //dxa word
5615         {156, 0},                                    //"sprmSDyaHdrTop",
5616                                                      //sep.dyaHdrTop dya word
5617         {157, 0},                                    //"sprmSDyaHdrBottom",
5618                                                      //sep.dyaHdrBottom dya word
5619         {158, 0},                                    //"sprmSLBetween",
5620                                                      //sep.fLBetween 0 or 1 byte
5621         {159, 0},                                    //"sprmSVjc", sep.vjc vjc byte
5622         {160, 0},                                    //"sprmSLnnMin", sep.lnnMin
5623                                                      //lnn word
5624         {161, 0},                                    //"sprmSPgnStart", sep.pgnStart
5625                                                      //pgn word
5626         {162, 0},                                    //"sprmSBOrientation",
5627                                                      //sep.dmOrientPage dm byte
5628         {163, 0},                                    //"?SprmSBCustomize 163", ?
5629         {164, 0},                                    //"sprmSXaPage", sep.xaPage xa
5630                                                      //word
5631         {165, 0},                                    //"sprmSYaPage", sep.yaPage ya
5632                                                      //word
5633         {166, 0},                                    //"sprmSDxaLeft", sep.dxaLeft
5634                                                      //dxa word
5635         {167, 0},                                    //"sprmSDxaRight", sep.dxaRight
5636                                                      //dxa word
5637         {168, 0},                                    //"sprmSDyaTop", sep.dyaTop                                                     //dya word
5638         {169, 0},                                    //"sprmSDyaBottom",
5639                                                      //sep.dyaBottom dya word
5640         {170, 0},                                    //"sprmSDzaGutter",
5641                                                      //sep.dzaGutter dza word
5642         {171, 0},                                    //"sprmSDMPaperReq",
5643                                                      //sep.dmPaperReq dm word
5644         {172, 0},                                    //"??172",
5645         {173, 0},                                    //"??173",
5646         {174, 0},                                    //"??174",
5647         {175, 0},                                    //"??175",
5648         {176, 0},                                    //"??176",
5649         {177, 0},                                    //"??177",
5650         {178, 0},                                    //"??178",
5651         {179, 0},                                    //"??179",
5652         {180, 0},                                    //"??180",
5653         {181, 0},                                    //"??181",
5654         {182, 0},                                    //"sprmTJc", tap.jc jc word
5655                                                      //(low order byte is
5656                                                      //significant)
5657         {183, 0},                                    //"sprmTDxaLeft",
5658                                                      //tap.rgdxaCenter dxa word
5659         {184, 0},                                    //"sprmTDxaGapHalf",
5660                                                      //tap.dxaGapHalf,
5661                                                      //tap.rgdxaCenter dxa word
5662         {185, 0},                                    //"sprmTFCantSplit"
5663                                                      //tap.fCantSplit 1 or 0 byte
5664         {186, 0},                                    //"sprmTTableHeader",
5665                                                      //tap.fTableHeader 1 or 0 byte
5666         {187, 0},                                    //"sprmTTableBorders",
5667                                                      //tap.rgbrcTable complex
5668                                                      //12 bytes
5669         {188, 0},                                    //"sprmTDefTable10",
5670                                                      //tap.rgdxaCenter, tap.rgtc
5671                                                      //complex variable length
5672         {189, 0},                                    //"sprmTDyaRowHeight",
5673                                                      //tap.dyaRowHeight dya word
5674         {190, 0},                                    //"?sprmTDefTable", tap.rgtc
5675                                                      //complex
5676         {191, 0},                                    //"?sprmTDefTableShd",
5677                                                      //tap.rgshd complex
5678         {192, 0},                                    //"sprmTTlp", tap.tlp TLP
5679                                                      //4 bytes
5680         {193, 0},                                    //"sprmTSetBrc",
5681                                                      //tap.rgtc[].rgbrc complex
5682                                                      //5 bytes
5683         {194, 0},                                    //"sprmTInsert",
5684                                                      //tap.rgdxaCenter,
5685                                                      //tap.rgtc complex 4 bytes
5686         {195, 0},                                    //"sprmTDelete",
5687                                                      //tap.rgdxaCenter,
5688                                                      //tap.rgtc complex word
5689         {196, 0},                                    //"sprmTDxaCol",
5690                                                      //tap.rgdxaCenter complex
5691                                                      //4 bytes
5692         {197, 0},                                    //"sprmTMerge",
5693                                                      //tap.fFirstMerged,
5694                                                      //tap.fMerged complex word
5695         {198, 0},                                    //"sprmTSplit",
5696                                                      //tap.fFirstMerged,
5697                                                      //tap.fMerged complex word
5698         {199, 0},                                    //"sprmTSetBrc10",
5699                                                      //tap.rgtc[].rgbrc complex
5700                                                      //5 bytes
5701         {200, 0},                                    //"sprmTSetShd", tap.rgshd
5702                                                      //complex 4 bytes
5703         {207, 0},                                    //dunno
5704     };
5705 
5706     static wwSprmDispatcher aSprmSrch(aSprms, sizeof(aSprms) / sizeof(aSprms[0]));
5707     return &aSprmSrch;
5708 }
5709 
GetWW8SprmDispatcher()5710 const wwSprmDispatcher *GetWW8SprmDispatcher()
5711 {
5712     static SprmReadInfo aSprms[] =
5713     {
5714         {0,      0},                                 // "0" Default bzw. Error
5715 
5716         {0x4600, &SwWW8ImplReader::Read_StyleCode},  //"sprmPIstd" pap.istd;istd
5717                                                      //(style code);short;
5718         {0xC601, 0},                                 //"sprmPIstdPermute" pap.istd;
5719                                                      //permutation vector;
5720                                                      //variable length;
5721         {0x2602, 0},                                 //"sprmPIncLvl" pap.istd,
5722                                                      //pap.lvl;difference between
5723                                                      //istd of base PAP and istd of
5724                                                      //PAP to be produced; byte;
5725         {0x2403, &SwWW8ImplReader::Read_Justify},    //"sprmPJc" pap.jc;jc
5726                                                      //(justification);byte;
5727         {0x2404, 0},                                 //"sprmPFSideBySide"
5728                                                      //pap.fSideBySide;0 or 1;byte;
5729         {0x2405, &SwWW8ImplReader::Read_KeepLines},  //"sprmPFKeep" pap.fKeep;0 or
5730                                                      //1;byte;
5731         {0x2406, &SwWW8ImplReader::Read_KeepParas},  //"sprmPFKeepFollow"
5732                                                      //pap.fKeepFollow;0 or 1;byte;
5733         {0x2407, &SwWW8ImplReader::Read_BreakBefore},//"sprmPFPageBreakBefore"
5734                                                      //pap.fPageBreakBefore;0 or 1;
5735                                                      //byte;
5736         {0x2408, 0},                                 //"sprmPBrcl" pap.brcl;brcl;
5737                                                      //byte;
5738         {0x2409, 0},                                 //"sprmPBrcp" pap.brcp;brcp;
5739                                                      //byte;
5740         {0x260A, &SwWW8ImplReader::Read_ListLevel},  //"sprmPIlvl" pap.ilvl;ilvl;
5741                                                      //byte;
5742         {0x460B, &SwWW8ImplReader::Read_LFOPosition},//"sprmPIlfo" pap.ilfo;ilfo
5743                                                      //(list index) ;short;
5744         {0x240C, &SwWW8ImplReader::Read_NoLineNumb}, //"sprmPFNoLineNumb"
5745                                                      //pap.fNoLnn;0 or 1;byte;
5746         {0xC60D, &SwWW8ImplReader::Read_Tab},        //"sprmPChgTabsPapx"
5747                                                      //pap.itbdMac, pap.rgdxaTab,
5748                                                      //pap.rgtbd;complex;variable
5749                                                      //length
5750         {0x840E, &SwWW8ImplReader::Read_LR},         //Word 97 version of "sprmPDxaRight" pap.dxaRight;
5751                                                      //dxa;word;
5752         {0x840F, &SwWW8ImplReader::Read_LR},         //Apparently Word 97 version of "sprmPDxaLeft" pap.dxaLeft;
5753                                                      //dxa;word;
5754         {0x4610, 0},                                 //"sprmPNest" pap.dxaLeft;
5755                                                      //dxa;word;
5756         {0x8411, &SwWW8ImplReader::Read_LR},         //Word 97 version of "sprmPDxaLeft1" pap.dxaLeft1;
5757                                                      //dxa;word;
5758         {0x6412, &SwWW8ImplReader::Read_LineSpace},  //"sprmPDyaLine" pap.lspd;
5759                                                      //an LSPD, a long word
5760                                                      //structure consisting of a
5761                                                      //short of dyaLine followed by
5762                                                      //a short of fMultLinespace;
5763                                                      //long;
5764         {0xA413, &SwWW8ImplReader::Read_UL},         //"sprmPDyaBefore"
5765                                                      //pap.dyaBefore;dya;word;
5766         {0xA414, &SwWW8ImplReader::Read_UL},         //"sprmPDyaAfter" pap.dyaAfter;
5767                                                      //dya;word;
5768         {0xC615, 0},                                 //"sprmPChgTabs" pap.itbdMac,
5769                                                      //pap.rgdxaTab, pap.rgtbd;
5770                                                      //complex;variable length;
5771         {0x2416, 0},                                 //"sprmPFInTable" pap.fInTable;
5772                                                      //0 or 1;byte;
5773         {0x2417, &SwWW8ImplReader::Read_TabRowEnd},  //"sprmPFTtp" pap.fTtp;0 or 1;
5774                                                      //byte;
5775         {0x8418, 0},                                 //"sprmPDxaAbs" pap.dxaAbs;dxa;
5776                                                      //word;
5777         {0x8419, 0},                                 //"sprmPDyaAbs" pap.dyaAbs;dya;
5778                                                      //word;
5779         {0x841A, 0},                                 //"sprmPDxaWidth" pap.dxaWidth;
5780                                                      //dxa;word;
5781         {0x261B, &SwWW8ImplReader::Read_ApoPPC},     //"sprmPPc" pap.pcHorz,
5782                                                      //pap.pcVert;complex;byte;
5783         {0x461C, 0},                                 //"sprmPBrcTop10" pap.brcTop;
5784                                                      //BRC10;word;
5785         {0x461D, 0},                                 //"sprmPBrcLeft10" pap.brcLeft;
5786                                                      //BRC10;word;
5787         {0x461E, 0},                                 //"sprmPBrcBottom10"
5788                                                      //pap.brcBottom;BRC10;word;
5789         {0x461F, 0},                                 //"sprmPBrcRight10"
5790                                                      //pap.brcRight;BRC10;word;
5791         {0x4620, 0},                                 //"sprmPBrcBetween10"
5792                                                      //pap.brcBetween;BRC10;word;
5793         {0x4621, 0},                                 //"sprmPBrcBar10" pap.brcBar;
5794                                                      //BRC10;word;
5795         {0x4622, 0},                                 //"sprmPDxaFromText10"
5796                                                      //pap.dxaFromText;dxa;word;
5797         {0x2423, 0},                                 //"sprmPWr" pap.wr;wr;byte;
5798         {0x6424, &SwWW8ImplReader::Read_Border},     //"sprmPBrcTop" pap.brcTop;BRC;
5799                                                      //long;
5800         {0x6425, &SwWW8ImplReader::Read_Border},     //"sprmPBrcLeft" pap.brcLeft;
5801                                                      //BRC;long;
5802         {0x6426, &SwWW8ImplReader::Read_Border},     //"sprmPBrcBottom"
5803                                                      //pap.brcBottom;BRC;long;
5804         {0x6427, &SwWW8ImplReader::Read_Border},     //"sprmPBrcRight" pap.brcRight;
5805                                                      //BRC;long;
5806         {0x6428, &SwWW8ImplReader::Read_Border},     //"sprmPBrcBetween"
5807                                                      //pap.brcBetween;BRC;long;
5808         {0x6629, 0},                                 //"sprmPBrcBar" pap.brcBar;BRC;
5809                                                      //long;
5810         {0x242A, &SwWW8ImplReader::Read_Hyphenation},//"sprmPFNoAutoHyph"
5811                                                      //pap.fNoAutoHyph;0 or 1;byte;
5812         {0x442B, 0},                                 //"sprmPWHeightAbs"
5813                                                      //pap.wHeightAbs;w;word;
5814         {0x442C, 0},                                 //"sprmPDcs" pap.dcs;DCS;short;
5815         {0x442D, &SwWW8ImplReader::Read_Shade},      //"sprmPShd" pap.shd;SHD;word;
5816         {0x842E, 0},                                 //"sprmPDyaFromText"
5817                                                      //pap.dyaFromText;dya;word;
5818         {0x842F, 0},                                 //"sprmPDxaFromText"
5819                                                      //pap.dxaFromText;dxa;word;
5820         {0x2430, 0},                                 //"sprmPFLocked" pap.fLocked;
5821                                                      //0 or 1;byte;
5822         {0x2431, &SwWW8ImplReader::Read_WidowControl},//"sprmPFWidowControl"
5823                                                      //pap.fWidowControl;0 or 1;byte
5824         {0xC632, 0},                                 //"sprmPRuler" variable length;
5825         {0x2433, &SwWW8ImplReader::Read_BoolItem},   //"sprmPFKinsoku" pap.fKinsoku;
5826                                                      //0 or 1;byte;
5827         {0x2434, 0},                                 //"sprmPFWordWrap"
5828                                                      //pap.fWordWrap;0 or 1;byte;
5829         {0x2435, &SwWW8ImplReader::Read_BoolItem},   //"sprmPFOverflowPunct"
5830                                                      //pap.fOverflowPunct; 0 or 1;
5831                                                      //byte;
5832         {0x2436, 0},                                 //"sprmPFTopLinePunct"
5833                                                      //pap.fTopLinePunct;0 or 1;byte
5834         {0x2437, &SwWW8ImplReader::Read_BoolItem},   //"sprmPFAutoSpaceDE"
5835                                                      //pap.fAutoSpaceDE;0 or 1;byte;
5836         {0x2438, 0},                                 //"sprmPFAutoSpaceDN"
5837                                                      //pap.fAutoSpaceDN;0 or 1;byte;
5838         {0x4439, &SwWW8ImplReader::Read_AlignFont},  //"sprmPWAlignFont"
5839                                                      //pap.wAlignFont;iFa; word;
5840         {0x443A, 0},                                 //"sprmPFrameTextFlow"
5841                                                      //pap.fVertical pap.fBackward
5842                                                      //pap.fRotateFont;complex; word
5843         {0x243B, 0},                                 //"sprmPISnapBaseLine" obsolete
5844                                                      //not applicable in Word97
5845                                                      //and later versions;;byte;
5846         {0xC63E, &SwWW8ImplReader::Read_ANLevelDesc},//"sprmPAnld" pap.anld;;
5847                                                      //variable length;
5848         {0xC63F, 0},                                 //"sprmPPropRMark"
5849                                                      //pap.fPropRMark;complex;
5850                                                      //variable length;
5851         {0x2640,  &SwWW8ImplReader::Read_POutLvl},   //"sprmPOutLvl" pap.lvl;has no
5852                                                      //effect if pap.istd is < 1 or
5853                                                      //is > 9;byte;
5854         {0x2441, &SwWW8ImplReader::Read_ParaBiDi},   //"sprmPFBiDi" ;;byte;
5855         {0x2443, 0},                                 //"sprmPFNumRMIns"
5856                                                      //pap.fNumRMIns;1 or 0;bit;
5857         {0x2444, 0},                                 //"sprmPCrLf" ;;byte;
5858         {0xC645, 0},                                 //"sprmPNumRM" pap.numrm;;
5859                                                      //variable length;
5860         {0x6645, 0},                                 //"sprmPHugePapx" ;fc in the
5861                                                      //data stream to locate the
5862                                                      //huge grpprl; long;
5863         {0x6646, 0},                                 //"sprmPHugePapx" ;fc in the
5864                                                      //data stream to locate the
5865                                                      //huge grpprl; long;
5866         {0x2447, &SwWW8ImplReader::Read_UsePgsuSettings},//"sprmPFUsePgsuSettings"
5867                                                      //pap.fUsePgsuSettings;1 or 0;
5868                                                      //byte;
5869         {0x2448, 0},                                 //"sprmPFAdjustRight"
5870                                                      //pap.fAdjustRight;1 or 0;byte;
5871         {0x0800, &SwWW8ImplReader::Read_CFRMarkDel}, //"sprmCFRMarkDel"
5872                                                      //chp.fRMarkDel;1 or 0;bit;
5873         {0x0801, &SwWW8ImplReader::Read_CFRMark},    //"sprmCFRMark" chp.fRMark;1
5874                                                      //or 0;bit;
5875         {0x0802, &SwWW8ImplReader::Read_FldVanish},  //"sprmCFFldVanish"
5876                                                      //chp.fFldVanish;1 or 0;bit;
5877         {0x6A03, &SwWW8ImplReader::Read_PicLoc},     //"sprmCPicLocation" chp.fcPic
5878                                                      //and chp.fSpec;variable
5879                                                      //length, length recorded is
5880                                                      //always 4;
5881         {0x4804, 0},                                 //"sprmCIbstRMark"
5882                                                      //chp.ibstRMark;index into
5883                                                      //sttbRMark;short;
5884         {0x6805, 0},                                 //"sprmCDttmRMark"
5885                                                      //chp.dttmRMark;DTTM;long;
5886         {0x0806, 0},                                 //"sprmCFData" chp.fData;1 or
5887                                                      //0;bit;
5888         {0x4807, 0},                                 //"sprmCIdslRMark"
5889                                                      //chp.idslRMReason;an index to
5890                                                      //a table of strings defined in
5891                                                      //Word 6.0 executables;short;
5892         {0xEA08, &SwWW8ImplReader::Read_CharSet},    //"sprmCChs" chp.fChsDiff and
5893                                                      //chp.chse;3 bytes;
5894         {0x6A09, &SwWW8ImplReader::Read_Symbol},     //"sprmCSymbol" chp.fSpec,
5895                                                      //chp.xchSym and chp.ftcSym;
5896                                                      //variable length, length
5897                                                      //recorded is always 4;
5898         {0x080A, &SwWW8ImplReader::Read_Obj},        //"sprmCFOle2" chp.fOle2;1 or
5899                                                      //0;bit;
5900       //0x480B,                                      //"sprmCIdCharType", obsolete:
5901                                                      //not applicable in Word97
5902                                                      //and later versions
5903         {0x2A0C, &SwWW8ImplReader::Read_CharHighlight},//"sprmCHighlight"
5904                                                      //chp.fHighlight,
5905                                                      //chp.icoHighlight;ico
5906                                                      //(fHighlight is set to 1 iff
5907                                                      //ico is not 0);byte;
5908         {0x680E, &SwWW8ImplReader::Read_PicLoc},     //"sprmCObjLocation" chp.fcObj;
5909                                                      //FC;long;
5910       //0x2A10, ? ? ?,                               //"sprmCFFtcAsciSymb"
5911         {0x4A30, &SwWW8ImplReader::Read_CColl},      //"sprmCIstd" chp.istd;istd,
5912                                                      //short;
5913         {0xCA31, 0},                                 //"sprmCIstdPermute" chp.istd;
5914                                                      //permutation vector; variable
5915                                                      //length;
5916         {0x2A32, 0},                                 //"sprmCDefault" whole CHP;none
5917                                                      //;variable length;
5918         {0x2A33, 0},                                 //"sprmCPlain" whole CHP;none;
5919                                                      //Laenge: 0;
5920         {0x2A34, &SwWW8ImplReader::Read_Emphasis},   //"sprmCKcd"
5921         {0x0835, &SwWW8ImplReader::Read_BoldUsw},    //"sprmCFBold" chp.fBold;0,1,
5922                                                      //128, or 129; byte;
5923         {0x0836, &SwWW8ImplReader::Read_BoldUsw},    //"sprmCFItalic" chp.fItalic;0,
5924                                                      //1, 128, or 129; byte;
5925         {0x0837, &SwWW8ImplReader::Read_BoldUsw},    //"sprmCFStrike" chp.fStrike;0,
5926                                                      //1, 128, or 129; byte;
5927         {0x0838, &SwWW8ImplReader::Read_BoldUsw},    //"sprmCFOutline" chp.fOutline;
5928                                                      //0,1, 128, or 129; byte;
5929         {0x0839, &SwWW8ImplReader::Read_BoldUsw},    //"sprmCFShadow" chp.fShadow;0,
5930                                                      //1, 128, or 129; byte;
5931         {0x083A, &SwWW8ImplReader::Read_BoldUsw},    //"sprmCFSmallCaps"
5932                                                      //chp.fSmallCaps;0,1, 128, or
5933                                                      //129;byte;
5934         {0x083B, &SwWW8ImplReader::Read_BoldUsw},    //"sprmCFCaps" chp.fCaps;0,1,
5935                                                      //128, or 129; byte;
5936         {0x083C, &SwWW8ImplReader::Read_BoldUsw},    //"sprmCFVanish" chp.fVanish;0,
5937                                                      //1, 128, or 129; byte;
5938       //0x4A3D, 0,                                   //"sprmCFtcDefault" ftc, only
5939                                                      //used internally, never
5940                                                      //stored in file;word;
5941         {0x2A3E, &SwWW8ImplReader::Read_Underline},  //"sprmCKul" chp.kul;kul;byte;
5942         {0xEA3F, 0},                                 //"sprmCSizePos" chp.hps,
5943                                                      //chp.hpsPos;3 bytes;
5944         {0x8840, &SwWW8ImplReader::Read_Kern},       //"sprmCDxaSpace" chp.dxaSpace;
5945                                                      //dxa;word;
5946         {0x4A41, &SwWW8ImplReader::Read_Language},   //"sprmCLid" ;only used
5947                                                      //internally never stored;word;
5948         {0x2A42, &SwWW8ImplReader::Read_TxtColor},   //"sprmCIco" chp.ico;ico;byte;
5949         {0x4A43, &SwWW8ImplReader::Read_FontSize},   //"sprmCHps" chp.hps;hps;byte;
5950         {0x2A44, 0},                                 //"sprmCHpsInc" chp.hps;byte;
5951         {0x4845, &SwWW8ImplReader::Read_SubSuperProp},//"sprmCHpsPos" chp.hpsPos;
5952                                                      //hps; byte;
5953         {0x2A46, 0},                                 //"sprmCHpsPosAdj" chp.hpsPos;
5954                                                      //hps; byte;
5955         {0xCA47, &SwWW8ImplReader::Read_Majority},   //"sprmCMajority" chp.fBold,
5956                                                      //chp.fItalic, chp.fSmallCaps,
5957                                                      //chp.fVanish, chp.fStrike,
5958                                                      //chp.fCaps, chp.rgftc,
5959                                                      //chp.hps, chp.hpsPos, chp.kul,
5960                                                      //chp.dxaSpace, chp.ico,
5961                                                      //chp.rglid;complex;variable
5962                                                      //length, length byte plus
5963                                                      //size of following grpprl;
5964         {0x2A48, &SwWW8ImplReader::Read_SubSuper},   //"sprmCIss" chp.iss;iss;byte;
5965         {0xCA49, 0},                                 //"sprmCHpsNew50" chp.hps;hps;
5966                                                      //variable width, length
5967                                                      //always recorded as 2;
5968         {0xCA4A, 0},                                 //"sprmCHpsInc1" chp.hps;
5969                                                      //complex; variable width,
5970                                                      //length always recorded as 2;
5971         {0x484B, &SwWW8ImplReader::Read_FontKern},   //"sprmCHpsKern" chp.hpsKern;
5972                                                      //hps;short;
5973         {0xCA4C, &SwWW8ImplReader::Read_Majority},   //"sprmCMajority50" chp.fBold,
5974                                                      //chp.fItalic, chp.fSmallCaps,
5975                                                      //chp.fVanish, chp.fStrike,
5976                                                      //chp.fCaps, chp.ftc, chp.hps,
5977                                                      //chp.hpsPos, chp.kul,
5978                                                      //chp.dxaSpace, chp.ico;
5979                                                      //complex; variable length;
5980         {0x4A4D, 0},                                 //"sprmCHpsMul" chp.hps;
5981                                                      //percentage to grow hps;short;
5982         {0x484E, 0},                                 //"sprmCYsri" chp.ysri;ysri;
5983                                                      //short;
5984         {0x4A4F, &SwWW8ImplReader::Read_FontCode},   //"sprmCRgFtc0" chp.rgftc[0];
5985                                                      //ftc for ASCII text; short;
5986         {0x4A50, &SwWW8ImplReader::Read_FontCode},   //"sprmCRgFtc1" chp.rgftc[1];
5987                                                      //ftc for Far East text;short;
5988         {0x4A51, &SwWW8ImplReader::Read_FontCode},   //"sprmCRgFtc2" chp.rgftc[2];
5989                                                      //ftc for non-Far East text;
5990                                                      //short;
5991         {0x4852, &SwWW8ImplReader::Read_ScaleWidth}, //"sprmCCharScale"
5992         {0x2A53, &SwWW8ImplReader::Read_BoldUsw},    //"sprmCFDStrike" chp.fDStrike;
5993                                                      //;byte;
5994         {0x0854, &SwWW8ImplReader::Read_Relief},     //"sprmCFImprint" chp.fImprint;
5995                                                      //1 or 0;bit;
5996         {0x0855, &SwWW8ImplReader::Read_Special},    //"sprmCFSpec" chp.fSpec;
5997                                                      //1 or 0;bit;
5998         {0x0856, &SwWW8ImplReader::Read_Obj},        //"sprmCFObj" chp.fObj;1 or 0;
5999                                                      //bit;
6000         {0xCA57, &SwWW8ImplReader::Read_CPropRMark}, //"sprmCPropRMark"
6001                                                      //chp.fPropRMark,
6002                                                      //chp.ibstPropRMark,
6003                                                      //chp.dttmPropRMark;Complex;
6004                                                      //variable length always
6005                                                      //recorded as 7 bytes;
6006         {0x0858, &SwWW8ImplReader::Read_Relief},     //"sprmCFEmboss" chp.fEmboss;
6007                                                      //1 or 0;bit;
6008         {0x2859, &SwWW8ImplReader::Read_TxtAnim},    //"sprmCSfxText" chp.sfxtText;
6009                                                      //text animation;byte;
6010         {0x085A, &SwWW8ImplReader::Read_Bidi},                                 //"sprmCFBiDi"
6011         {0x085B, 0},                                 //"sprmCFDiacColor"
6012         {0x085C, &SwWW8ImplReader::Read_BoldBiDiUsw},//"sprmCFBoldBi"
6013         {0x085D, &SwWW8ImplReader::Read_BoldBiDiUsw},//"sprmCFItalicBi"
6014         {0x4A5E, &SwWW8ImplReader::Read_FontCode},   //"sprmCFtcBi"
6015         {0x485F, &SwWW8ImplReader::Read_Language},   //"sprmCLidBi"
6016       //0x4A60, ? ? ?,                               //"sprmCIcoBi",
6017         {0x4A61, &SwWW8ImplReader::Read_FontSize},   //"sprmCHpsBi"
6018         {0xCA62, 0},                                 //"sprmCDispFldRMark"
6019                                                      //chp.fDispFldRMark,
6020                                                      //chp.ibstDispFldRMark,
6021                                                      //chp.dttmDispFldRMark ;
6022                                                      //Complex;variable length
6023                                                      //always recorded as 39 bytes;
6024         {0x4863, 0},                                 //"sprmCIbstRMarkDel"
6025                                                      //chp.ibstRMarkDel;index into
6026                                                      //sttbRMark;short;
6027         {0x6864, 0},                                 //"sprmCDttmRMarkDel"
6028                                                      //chp.dttmRMarkDel;DTTM;long;
6029         {0x6865, 0},                                 //"sprmCBrc" chp.brc;BRC;long;
6030         {0x4866, &SwWW8ImplReader::Read_CharShadow}, //"sprmCShd" chp.shd;SHD;short;
6031         {0x4867, 0},                                 //"sprmCIdslRMarkDel"
6032                                                      //chp.idslRMReasonDel;an index
6033                                                      //to a table of strings
6034                                                      //defined in Word 6.0
6035                                                      //executables;short;
6036         {0x0868, 0},                                 //"sprmCFUsePgsuSettings"
6037                                                      //chp.fUsePgsuSettings; 1 or 0;
6038                                                      //bit;
6039         {0x486B, 0},                                 //"sprmCCpg" ;;word;
6040         {0x486D, &SwWW8ImplReader::Read_Language},   //"sprmCRgLid0" chp.rglid[0];
6041                                                      //LID: for non-Far East text;
6042                                                      //word;
6043         {0x486E, &SwWW8ImplReader::Read_Language},   //"sprmCRgLid1" chp.rglid[1];
6044                                                      //LID: for Far East text;word;
6045         {0x286F, &SwWW8ImplReader::Read_IdctHint},   //"sprmCIdctHint" chp.idctHint;
6046                                                      //IDCT: byte;
6047         {0x2E00, 0},                                 //"sprmPicBrcl" pic.brcl;brcl
6048                                                      //(see PIC structure
6049                                                      //definition);byte;
6050         {0xCE01, 0},                                 //"sprmPicScale" pic.mx,
6051                                                      //pic.my, pic.dxaCropleft,
6052                                                      //pic.dyaCropTop
6053                                                      //pic.dxaCropRight,
6054                                                      //pic.dyaCropBottom;Complex;
6055                                                      //length byte plus 12 bytes;
6056         {0x6C02, 0},                                 //"sprmPicBrcTop" pic.brcTop;
6057                                                      //BRC;long;
6058         {0x6C03, 0},                                 //"sprmPicBrcLeft" pic.brcLeft;
6059                                                      //BRC;long;
6060         {0x6C04, 0},                                 //"sprmPicBrcBottom"
6061                                                      //pic.brcBottom;BRC;long;
6062         {0x6C05, 0},                                 //"sprmPicBrcRight"
6063                                                      //pic.brcRight;BRC;long;
6064         {0x3000, 0},                                 //"sprmScnsPgn" sep.cnsPgn;cns;
6065                                                      //byte;
6066         {0x3001, 0},                                 //"sprmSiHeadingPgn"
6067                                                      //sep.iHeadingPgn;heading
6068                                                      //number level;byte;
6069         {0xD202, &SwWW8ImplReader::Read_OLST},       //"sprmSOlstAnm" sep.olstAnm;
6070                                                      //OLST;variable length;
6071         {0xF203, 0},                                 //"sprmSDxaColWidth"
6072                                                      //sep.rgdxaColWidthSpacing;
6073                                                      //complex; 3 bytes;
6074         {0xF204, 0},                                 //"sprmSDxaColSpacing"
6075                                                      //sep.rgdxaColWidthSpacing;
6076                                                      //complex; 3 bytes;
6077         {0x3005, 0},                                 //"sprmSFEvenlySpaced"
6078                                                      //sep.fEvenlySpaced; 1 or 0;
6079                                                      //byte;
6080         {0x3006, 0},                                 //"sprmSFProtected"
6081                                                      //sep.fUnlocked;1 or 0;byte;
6082         {0x5007, 0},                                 //"sprmSDmBinFirst"
6083                                                      //sep.dmBinFirst;;word;
6084         {0x5008, 0},                                 //"sprmSDmBinOther"
6085                                                      //sep.dmBinOther;;word;
6086         {0x3009, 0},                                 //"sprmSBkc" sep.bkc;bkc;byte;
6087         {0x300A, 0},                                 //"sprmSFTitlePage"
6088                                                      //sep.fTitlePage;0 or 1;byte;
6089         {0x500B, 0},                                 //"sprmSCcolumns" sep.ccolM1;
6090                                                      //# of cols - 1;word;
6091         {0x900C, 0},                                 //"sprmSDxaColumns"
6092                                                      //sep.dxaColumns;dxa;word;
6093         {0x300D, 0},                                 //"sprmSFAutoPgn" sep.fAutoPgn;
6094                                                      //obsolete;byte;
6095         {0x300E, 0},                                 //"sprmSNfcPgn" sep.nfcPgn;nfc;
6096                                                      //byte;
6097         {0xB00F, 0},                                 //"sprmSDyaPgn" sep.dyaPgn;dya;
6098                                                      //short;
6099         {0xB010, 0},                                 //"sprmSDxaPgn" sep.dxaPgn;dya;
6100                                                      //short;
6101         {0x3011, 0},                                 //"sprmSFPgnRestart"
6102                                                      //sep.fPgnRestart;0 or 1;byte;
6103         {0x3012, 0},                                 //"sprmSFEndnote" sep.fEndnote;
6104                                                      //0 or 1;byte;
6105         {0x3013, 0},                                 //"sprmSLnc" sep.lnc;lnc;byte;
6106         {0x3014, 0},                                 //"sprmSGprfIhdt" sep.grpfIhdt;
6107                                                      //grpfihdt; byte;
6108         {0x5015, 0},                                 //"sprmSNLnnMod" sep.nLnnMod;
6109                                                      //non-neg int.;word;
6110         {0x9016, 0},                                 //"sprmSDxaLnn" sep.dxaLnn;dxa;
6111                                                      //word;
6112         {0xB017, 0},                                 //"sprmSDyaHdrTop"
6113                                                      //sep.dyaHdrTop;dya;word;
6114         {0xB018, 0},                                 //"sprmSDyaHdrBottom"
6115                                                      //sep.dyaHdrBottom;dya;word;
6116         {0x3019, 0},                                 //"sprmSLBetween"
6117                                                      //sep.fLBetween;0 or 1;byte;
6118         {0x301A, 0},                                 //"sprmSVjc" sep.vjc;vjc;byte;
6119         {0x501B, 0},                                 //"sprmSLnnMin" sep.lnnMin;lnn;
6120                                                      //word;
6121         {0x501C, 0},                                 //"sprmSPgnStart" sep.pgnStart;
6122                                                      //pgn;word;
6123         {0x301D, 0},                                 //"sprmSBOrientation"
6124                                                      //sep.dmOrientPage;dm;byte;
6125       //0x301E, ? ? ?,                               //"sprmSBCustomize"
6126         {0xB01F, 0},                                 //"sprmSXaPage" sep.xaPage;xa;
6127                                                      //word;
6128         {0xB020, 0},                                 //"sprmSYaPage" sep.yaPage;ya;
6129                                                      //word;
6130         {0x2205, 0},                                 //"sprmSDxaLeft" sep.dxaLeft;
6131                                                      //dxa;word;
6132         {0xB022, 0},                                 //"sprmSDxaRight" sep.dxaRight;
6133                                                      //dxa;word;
6134         {0x9023, 0},                                 //"sprmSDyaTop" sep.dyaTop;dya;
6135                                                      //word;
6136         {0x9024, 0},                                 //"sprmSDyaBottom"
6137                                                      //sep.dyaBottom;dya;word;
6138         {0xB025, 0},                                 //"sprmSDzaGutter"
6139                                                      //sep.dzaGutter;dza;word;
6140         {0x5026, 0},                                 //"sprmSDmPaperReq"
6141                                                      //sep.dmPaperReq;dm;word;
6142         {0xD227, 0},                                 //"sprmSPropRMark"
6143                                                      //sep.fPropRMark,
6144                                                      //sep.ibstPropRMark,
6145                                                      //sep.dttmPropRMark ;complex;
6146                                                      //variable length always
6147                                                      //recorded as 7 bytes;
6148       //0x3228, ? ? ?,                               //"sprmSFBiDi",
6149       //0x3229, ? ? ?,                               //"sprmSFFacingCol"
6150         {0x322A, 0},                                 //"sprmSFRTLGutter", set to 1
6151                                                      //if gutter is on the right.
6152         {0x702B, 0},                                 //"sprmSBrcTop" sep.brcTop;BRC;
6153                                                      //long;
6154         {0x702C, 0},                                 //"sprmSBrcLeft" sep.brcLeft;
6155                                                      //BRC;long;
6156         {0x702D, 0},                                 //"sprmSBrcBottom"
6157                                                      //sep.brcBottom;BRC;long;
6158         {0x702E, 0},                                 //"sprmSBrcRight" sep.brcRight;
6159                                                      //BRC;long;
6160         {0x522F, 0},                                 //"sprmSPgbProp" sep.pgbProp;
6161                                                      //word;
6162         {0x7030, 0},                                 //"sprmSDxtCharSpace"
6163                                                      //sep.dxtCharSpace;dxt;long;
6164         {0x9031, 0},                                 //"sprmSDyaLinePitch"
6165                                                      //sep.dyaLinePitch;dya;
6166                                                      //WRONG:long; RIGHT:short; !
6167       //0x5032, ? ? ?,                               //"sprmSClm"
6168         {0x5033, 0},                                 //"sprmSTextFlow"
6169                                                      //sep.wTextFlow;complex ;short
6170         {0x5400, 0},                                 //"sprmTJc" tap.jc;jc;word (low
6171                                                      //order byte is significant);
6172         {0x9601, 0},                                 //"sprmTDxaLeft"
6173                                                      //tap.rgdxaCenter; dxa; word;
6174         {0x9602, 0},                                 //"sprmTDxaGapHalf"
6175                                                      //tap.dxaGapHalf,
6176                                                      //tap.rgdxaCenter; dxa; word;
6177         {0x3403, 0},                                 //"sprmTFCantSplit"
6178                                                      //tap.fCantSplit;1 or 0;byte;
6179         {0x3404, 0},                                 //"sprmTTableHeader"
6180                                                      //tap.fTableHeader;1 or 0;byte;
6181         {0x3466, 0},                                 //"sprmTFCantSplit90"
6182                                                      //tap.fCantSplit90;1 or 0;byte;
6183         {0xD605, 0},                                 //"sprmTTableBorders"
6184                                                      //tap.rgbrcTable;complex;
6185                                                      //24 bytes;
6186         {0xD606, 0},                                 //"sprmTDefTable10"
6187                                                      //tap.rgdxaCenter,
6188                                                      //tap.rgtc;complex; variable
6189                                                      //length;
6190         {0x9407, 0},                                 //"sprmTDyaRowHeight"
6191                                                      //tap.dyaRowHeight;dya;word;
6192         {0xD608, 0},                                 //"sprmTDefTable"
6193                                                      //tap.rgtc;complex
6194         {0xD609, 0},                                 //"sprmTDefTableShd"
6195                                                      //tap.rgshd;complex
6196         {0x740A, 0},                                 //"sprmTTlp" tap.tlp;TLP;
6197                                                      //4 bytes;
6198       //0x560B, ? ? ?,                               //"sprmTFBiDi"
6199       //0x740C, ? ? ?,                               //"sprmTHTMLProps"
6200         {0xD620, 0},                                 //"sprmTSetBrc"
6201                                                      //tap.rgtc[].rgbrc;complex;
6202                                                      //5 bytes;
6203         {0x7621, 0},                                 //"sprmTInsert"
6204                                                      //tap.rgdxaCenter,
6205                                                      //tap.rgtc;complex ;4 bytes;
6206         {0x5622, 0},                                 //"sprmTDelete"
6207                                                      //tap.rgdxaCenter,
6208                                                      //tap.rgtc;complex ;word;
6209         {0x7623, 0},                                 //"sprmTDxaCol"
6210                                                      //tap.rgdxaCenter;complex;
6211                                                      //4 bytes;
6212         {0x5624, 0},                                 //"sprmTMerge"
6213                                                      //tap.fFirstMerged,
6214                                                      //tap.fMerged;complex; word;
6215         {0x5625, 0},                                 //"sprmTSplit"
6216                                                      //tap.fFirstMerged,
6217                                                      //tap.fMerged;complex ;word;
6218         {0xD626, 0},                                 //"sprmTSetBrc10"
6219                                                      //tap.rgtc[].rgbrc;complex;
6220                                                      //5 bytes;
6221         {0x7627, 0},                                 //"sprmTSetShd" tap.rgshd;
6222                                                      //complex; 4 bytes;
6223         {0x7628, 0},                                 //"sprmTSetShdOdd"
6224                                                      //tap.rgshd;complex;4 bytes;
6225         {0x7629, 0},                                 //"sprmTTextFlow"
6226                                                      //tap.rgtc[].fVertical
6227                                                      //tap.rgtc[].fBackward
6228                                                      //tap.rgtc[].fRotateFont
6229                                                      //0 or 10 or 10 or 1;word;
6230       //0xD62A, ? ? ?  ,                             //"sprmTDiagLine"
6231         {0xD62B, 0},                                 //"sprmTVertMerge"
6232                                                      //tap.rgtc[].vertMerge;complex;
6233                                                      //variable length always
6234                                                      //recorded as 2 bytes;
6235         {0xD62C, 0},                                 //"sprmTVertAlign"
6236                                                      //tap.rgtc[].vertAlign;complex
6237                                                      //variable length always
6238                                                      //recorded as 3 byte;
6239         {0xCA78, &SwWW8ImplReader::Read_DoubleLine_Rotate},
6240         {0x6649, 0},                                 //undocumented
6241         {0xF614, 0},                                 //"sprmTTableWidth"
6242                                                      //recorded as 3 bytes;
6243         {0xD612, 0},                                 //undocumented
6244         {0xD613, 0},                                 //undocumented
6245         {0xD61A, 0},                                 //undocumented
6246         {0xD61B, 0},                                 //undocumented
6247         {0xD61C, 0},                                 //undocumented
6248         {0xD61D, 0},                                 //undocumented
6249         {0xD634, 0},                                 //undocumented
6250         {0xD632, 0},                                 //undocumented
6251         {0xD238, 0},                                 //undocumented sep
6252         {0xC64E, 0},                                 //undocumented
6253         {0xC64F, 0},                                 //undocumented
6254         {0xC650, 0},                                 //undocumented
6255         {0xC651, 0},                                 //undocumented
6256         {0xF661, 0},                                 //undocumented
6257         {0x4873, &SwWW8ImplReader::Read_Language},   //"sprmCRgLid3?" chp.rglid[0];
6258                                                      //LID: for non-Far East text
6259                                                      //(like a duplicate of 486D)
6260         {0x4874, 0},                                 //undocumented
6261         {0x6463, 0},                                 //undocumented
6262         {0x2461, &SwWW8ImplReader::Read_RTLJustify}, //undoc, must be asian version
6263                                                      //of "sprmPJc"
6264         {0x845E, &SwWW8ImplReader::Read_LR},         //Apparently post-Word 97 version of "sprmPDxaLeft"
6265         {0x8460, &SwWW8ImplReader::Read_LR},         //Post-Word 97 version of "sprmPDxaLeft1"
6266         {0x845D, &SwWW8ImplReader::Read_LR},         //Post-Word 97 version of "sprmPDxaRight"
6267         {0x3615, 0},                                 //undocumented
6268         {0x360D, 0},                                 //undocumented
6269         {0x940E, 0},                                 //undocumented
6270         {0x940F, 0},                                 //undocumented
6271         {0x9410, 0},                                 //undocumented
6272         {0x703A, 0},                                 //undocumented
6273         {0x303B, 0},                                 //undocumented
6274         {0x244B, &SwWW8ImplReader::Read_TabCellEnd}, //undocumented, must be
6275                                                      //subtable "sprmPFInTable"
6276         {0x244C, &SwWW8ImplReader::Read_TabRowEnd},  //undocumented, must be
6277                                                      // subtable "sprmPFTtp"
6278         {0x6815, 0},                                 //undocumented
6279         {0x6816, 0},                                 //undocumented
6280         {0x6870, &SwWW8ImplReader::Read_TxtForeColor},
6281 		{0x6877, &SwWW8ImplReader::Read_UnderlineColor},
6282         {0xC64D, &SwWW8ImplReader::Read_ParaBackColor},
6283         {0x6467, 0},                                 //undocumented
6284         {0xF617, 0},                                 //undocumented
6285         {0xD660, 0},                                 //undocumented
6286         {0xD670, 0},                                 //undocumented
6287         {0xCA71, &SwWW8ImplReader::Read_TxtBackColor},//undocumented
6288         {0x303C, 0},                                 //undocumented
6289         {0x245B, &SwWW8ImplReader::Read_ParaAutoBefore},//undocumented, para
6290         {0x245C, &SwWW8ImplReader::Read_ParaAutoAfter},//undocumented, para
6291         {0x246D, &SwWW8ImplReader::Read_DontAddEqual}//undocumented, para
6292     };
6293 
6294     static wwSprmDispatcher aSprmSrch(aSprms, sizeof(aSprms) / sizeof(aSprms[0]));
6295     return &aSprmSrch;
6296 }
6297 
6298 //-----------------------------------------
6299 //      Hilfsroutinen : SPRM finden
6300 //-----------------------------------------
6301 
GetSprmReadInfo(sal_uInt16 nId) const6302 const SprmReadInfo& SwWW8ImplReader::GetSprmReadInfo(sal_uInt16 nId) const
6303 {
6304     ww::WordVersion eVersion = pWwFib->GetFIBVersion();
6305     const wwSprmDispatcher *pDispatcher;
6306     if (eVersion <= ww::eWW2)
6307         pDispatcher = GetWW2SprmDispatcher();
6308     else if (eVersion < ww::eWW8)
6309         pDispatcher = GetWW6SprmDispatcher();
6310     else
6311         pDispatcher = GetWW8SprmDispatcher();
6312 
6313     SprmReadInfo aSrch = {0, 0};
6314     aSrch.nId = nId;
6315     const SprmReadInfo* pFound = pDispatcher->search(aSrch);
6316 
6317     if (!pFound)
6318     {
6319         aSrch.nId = 0;
6320         pFound = pDispatcher->search(aSrch);
6321     }
6322 
6323     return *pFound;
6324 }
6325 
6326 //-----------------------------------------
6327 //      Hilfsroutinen : SPRMs
6328 //-----------------------------------------
EndSprm(sal_uInt16 nId)6329 void SwWW8ImplReader::EndSprm( sal_uInt16 nId )
6330 {
6331     if( ( nId > 255 ) && ( nId < 0x0800 ) ) return;
6332 
6333     const SprmReadInfo& rSprm = GetSprmReadInfo( nId );
6334 
6335     if (rSprm.pReadFnc)
6336         (this->*rSprm.pReadFnc)( nId, 0, -1 );
6337 }
6338 
ImportSprm(const sal_uInt8 * pPos,sal_uInt16 nId)6339 short SwWW8ImplReader::ImportSprm(const sal_uInt8* pPos,sal_uInt16 nId)
6340 {
6341     if (!nId)
6342         nId = mpSprmParser->GetSprmId(pPos);
6343 
6344 #if OSL_DEBUG_LEVEL > 1
6345     ASSERT( nId != 0xff, "Sprm FF !!!!" );
6346 #endif
6347 
6348     const SprmReadInfo& rSprm = GetSprmReadInfo(nId);
6349 
6350     sal_uInt16 nFixedLen = mpSprmParser->DistanceToData(nId);
6351     sal_uInt16 nL = mpSprmParser->GetSprmSize(nId, pPos);
6352 
6353     if (rSprm.pReadFnc)
6354         (this->*rSprm.pReadFnc)(nId, pPos + nFixedLen, nL - nFixedLen);
6355 
6356     return nL;
6357 }
6358 
6359 /* vi:set tabstop=4 shiftwidth=4 expandtab: */
6360