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