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