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