bump product version to 4.1.6.2
[LibreOffice.git] / sw / source / filter / ww8 / ww8par6.cxx
blob49fd40e070bbd3e9dddb848d1021ad4d691e346b
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <stdlib.h>
21 #include <svl/itemiter.hxx>
22 #include <rtl/tencinfo.h>
25 #include <hintids.hxx>
26 #include <editeng/lspcitem.hxx>
27 #include <editeng/wrlmitem.hxx>
28 #include <editeng/udlnitem.hxx>
29 #include <editeng/kernitem.hxx>
30 #include <editeng/langitem.hxx>
31 #include <editeng/cmapitem.hxx>
32 #include <editeng/shdditem.hxx>
33 #include <editeng/contouritem.hxx>
34 #include <editeng/crossedoutitem.hxx>
35 #include <editeng/postitem.hxx>
36 #include <editeng/wghtitem.hxx>
37 #include <editeng/colritem.hxx>
38 #include <editeng/brushitem.hxx>
39 #include <editeng/spltitem.hxx>
40 #include <editeng/keepitem.hxx>
41 #include <editeng/orphitem.hxx>
42 #include <editeng/widwitem.hxx>
43 #include <editeng/adjustitem.hxx>
44 #include <editeng/escapementitem.hxx>
45 #include <editeng/fhgtitem.hxx>
46 #include <editeng/fontitem.hxx>
47 #include <editeng/shaditem.hxx>
48 #include <editeng/boxitem.hxx>
49 #include <editeng/ulspitem.hxx>
50 #include <editeng/lrspitem.hxx>
51 #include <editeng/tstpitem.hxx>
52 #include <editeng/autokernitem.hxx>
53 #include <editeng/paperinf.hxx>
54 #include <editeng/emphasismarkitem.hxx>
55 #include <editeng/forbiddenruleitem.hxx>
56 #include <editeng/twolinesitem.hxx>
57 #include <editeng/scriptspaceitem.hxx>
58 #include <editeng/hngpnctitem.hxx>
59 #include <editeng/pbinitem.hxx>
60 #include <editeng/charscaleitem.hxx>
61 #include <editeng/charrotateitem.hxx>
62 #include <editeng/charreliefitem.hxx>
63 #include <editeng/blinkitem.hxx>
64 #include <editeng/hyphenzoneitem.hxx>
65 #include <editeng/paravertalignitem.hxx>
66 #include <editeng/pgrditem.hxx>
67 #include <editeng/frmdiritem.hxx>
68 #include <editeng/charhiddenitem.hxx>
69 #include <i18nlangtag/mslangid.hxx>
70 #include <doctok/sprmids.hxx>
71 #include <fmtpdsc.hxx>
72 #include <node.hxx>
73 #include <ndtxt.hxx> // SwTxtNode, siehe unten: JoinNode()
74 #include <pam.hxx> // fuer SwPam
75 #include <doc.hxx>
76 #include <pagedesc.hxx> // class SwPageDesc
77 #include <fmtanchr.hxx>
78 #include <fmtcntnt.hxx>
79 #include <fchrfmt.hxx>
80 #include <fmthdft.hxx>
81 #include <fmtclds.hxx>
82 #include <fmtftntx.hxx>
83 #include <frmatr.hxx>
84 #include <section.hxx>
85 #include <lineinfo.hxx>
86 #include <fmtline.hxx>
87 #include <txatbase.hxx>
88 #include <fmtflcnt.hxx>
89 #include <fmtclbl.hxx>
90 #include <tgrditem.hxx>
91 #include <hfspacingitem.hxx>
92 #include <swtable.hxx>
93 #include <fltini.hxx> //For CalculateFlySize
94 #include "writerhelper.hxx"
95 #include "writerwordglue.hxx"
96 #include "ww8scan.hxx"
97 #include "ww8par2.hxx" // class WW8RStyle, class WwAnchorPara
98 #include "ww8graf.hxx"
100 // #i27767#
101 #include <fmtwrapinfluenceonobjpos.hxx>
103 using namespace sw::util;
104 using namespace sw::types;
105 using namespace ::com::sun::star;
106 using namespace nsHdFtFlags;
108 //-----------------------------------------
109 // diverses
110 //-----------------------------------------
112 #define MM_250 1417 // WW-Default fuer Hor. Seitenraender: 2.5 cm
113 #define MM_200 1134 // WW-Default fuer u.Seitenrand: 2.0 cm
116 static sal_uInt8 lcl_ReadBorders(bool bVer67, WW8_BRC* brc, WW8PLCFx_Cp_FKP* pPap,
117 const WW8RStyle* pSty = 0, const WW8PLCFx_SEPX* pSep = 0);
120 ColorData SwWW8ImplReader::GetCol(sal_uInt8 nIco)
122 static const ColorData eSwWW8ColA[] =
124 COL_AUTO, COL_BLACK, COL_LIGHTBLUE, COL_LIGHTCYAN, COL_LIGHTGREEN,
125 COL_LIGHTMAGENTA, COL_LIGHTRED, COL_YELLOW, COL_WHITE, COL_BLUE,
126 COL_CYAN, COL_GREEN, COL_MAGENTA, COL_RED, COL_BROWN, COL_GRAY,
127 COL_LIGHTGRAY
130 return eSwWW8ColA[nIco];
133 inline sal_uInt32 MSRoundTweak(sal_uInt32 x)
135 return x;
138 /***************************************************************************
139 # Seiten - Attribute, die nicht ueber die Attribut-Verwaltung, sondern
140 # ueber ...->HasSprm abgearbeitet werden
141 # ( ausser OLST, dass weiterhin ein normales Attribut ist )
142 #**************************************************************************/
144 static short ReadSprm( const WW8PLCFx_SEPX* pSep, sal_uInt16 nId, short nDefaultVal )
146 const sal_uInt8* pS = pSep->HasSprm( nId ); // sprm da ?
147 short nVal = ( pS ) ? SVBT16ToShort( pS ) : nDefaultVal;
148 return nVal;
151 static sal_uInt16 ReadUSprm( const WW8PLCFx_SEPX* pSep, sal_uInt16 nId, short nDefaultVal )
153 const sal_uInt8* pS = pSep->HasSprm( nId ); // sprm da ?
154 sal_uInt16 nVal = ( pS ) ? SVBT16ToShort( pS ) : nDefaultVal;
155 return nVal;
158 static sal_uInt8 ReadBSprm( const WW8PLCFx_SEPX* pSep, sal_uInt16 nId, sal_uInt8 nDefaultVal )
160 const sal_uInt8* pS = pSep->HasSprm( nId ); // sprm da ?
161 sal_uInt8 nVal = ( pS ) ? SVBT8ToByte( pS ) : nDefaultVal;
162 return nVal;
165 void wwSection::SetDirection()
167 //sprmSTextFlow
168 switch (maSep.wTextFlow)
170 default:
171 OSL_ENSURE(!this, "Unknown layout type");
172 case 0:
173 meDir=FRMDIR_HORI_LEFT_TOP;
174 break;
175 case 1:
176 meDir=FRMDIR_VERT_TOP_RIGHT;
177 break;
178 case 2:
179 //asian letters are not rotated, western are. We can't import
180 //bottom to top going left to right, we can't do this in
181 //pages, (in drawboxes we could partly hack it with a rotated
182 //drawing box, though not frame)
183 meDir=FRMDIR_VERT_TOP_RIGHT;
184 break;
185 case 3:
186 //asian letters are not rotated, western are. We can't import
187 meDir=FRMDIR_VERT_TOP_RIGHT;
188 break;
189 case 4:
190 //asian letters are rotated, western not. We can't import
191 meDir=FRMDIR_HORI_LEFT_TOP;
192 break;
195 sal_uInt8 nRTLPgn = maSep.fBiDi;
196 if ((meDir == FRMDIR_HORI_LEFT_TOP) && nRTLPgn)
197 meDir = FRMDIR_HORI_RIGHT_TOP;
200 bool wwSection::IsVertical() const
202 if (meDir == FRMDIR_VERT_TOP_RIGHT || meDir == FRMDIR_VERT_TOP_LEFT)
203 return true;
204 return false;
208 This is something of festering mapping, I'm open to better ways of doing it,
209 but primarily the grid in writer is different to that in word. In writer the
210 grid elements are squares with ruby rows inbetween. While in word there is no
211 ruby stuff, and the elements are rectangles. By misusing the ruby row I can
212 handle distortions in one direction, but its all a bit of a mess:
214 void SwWW8ImplReader::SetDocumentGrid(SwFrmFmt &rFmt, const wwSection &rSection)
216 if (bVer67)
217 return;
219 rFmt.SetFmtAttr(SvxFrameDirectionItem(rSection.meDir, RES_FRAMEDIR));
221 SwTwips nTextareaHeight = rFmt.GetFrmSize().GetHeight();
222 const SvxULSpaceItem &rUL = ItemGet<SvxULSpaceItem>(rFmt, RES_UL_SPACE);
223 nTextareaHeight -= rUL.GetUpper();
224 nTextareaHeight -= rUL.GetLower();
226 SwTwips nTextareaWidth = rFmt.GetFrmSize().GetWidth();
227 const SvxLRSpaceItem &rLR = ItemGet<SvxLRSpaceItem>(rFmt, RES_LR_SPACE);
228 nTextareaWidth -= rLR.GetLeft();
229 nTextareaWidth -= rLR.GetRight();
231 if (rSection.IsVertical())
232 std::swap(nTextareaHeight, nTextareaWidth);
234 SwTextGridItem aGrid;
235 aGrid.SetDisplayGrid(false);
236 aGrid.SetPrintGrid(false);
237 SwTextGrid eType=GRID_NONE;
239 switch (rSection.maSep.clm)
241 case 0:
242 eType = GRID_NONE;
243 break;
244 default:
245 OSL_ENSURE(!this, "Unknown grid type");
246 case 3:
247 eType = GRID_LINES_CHARS;
248 aGrid.SetSnapToChars(sal_True);
249 break;
250 case 1:
251 eType = GRID_LINES_CHARS;
252 aGrid.SetSnapToChars(sal_False);
253 break;
254 case 2:
255 eType = GRID_LINES_ONLY;
256 break;
259 aGrid.SetGridType(eType);
261 // seem to not add external leading in word, or the character would run across
262 // two line in some cases.
263 if (eType != GRID_NONE)
264 rDoc.set(IDocumentSettingAccess::ADD_EXT_LEADING, false);
266 //force to set document as standard page mode
267 sal_Bool bSquaredMode = sal_False;
268 rDoc.SetDefaultPageMode( bSquaredMode );
269 aGrid.SetSquaredMode( bSquaredMode );
271 //Get the size of word's default styles font
272 sal_uInt32 nCharWidth=240;
273 for (sal_uInt16 nI = 0; nI < pStyles->GetCount(); ++nI)
275 if (vColl[nI].bValid && vColl[nI].pFmt &&
276 vColl[nI].GetWWStyleId() == 0)
278 nCharWidth = ItemGet<SvxFontHeightItem>(*(vColl[nI].pFmt),
279 RES_CHRATR_CJK_FONTSIZE).GetHeight();
280 break;
284 //dxtCharSpace
285 if (rSection.maSep.dxtCharSpace)
287 sal_uInt32 nCharSpace = rSection.maSep.dxtCharSpace;
288 //main lives in top 20 bits, and is signed.
289 sal_Int32 nMain = (nCharSpace & 0xFFFFF000);
290 nMain/=0x1000;
291 nCharWidth += nMain*20;
293 int nFraction = (nCharSpace & 0x00000FFF);
294 nFraction = (nFraction*20)/0xFFF;
295 nCharWidth += nFraction;
298 aGrid.SetBaseWidth( writer_cast<sal_uInt16>(nCharWidth));
300 //sep.dyaLinePitch
301 sal_Int32 nLinePitch = rSection.maSep.dyaLinePitch;
302 if (nLinePitch >= 1 && nLinePitch <= 31680)
304 aGrid.SetLines(writer_cast<sal_uInt16>(nTextareaHeight/nLinePitch));
305 aGrid.SetBaseHeight(writer_cast<sal_uInt16>(nLinePitch));
308 sal_Int32 nRubyHeight = 0;
309 aGrid.SetRubyHeight(writer_cast<sal_uInt16>(nRubyHeight));
311 rFmt.SetFmtAttr(aGrid);
314 void SwWW8ImplReader::Read_ParaBiDi(sal_uInt16, const sal_uInt8* pData, short nLen)
316 if( nLen < 0 )
317 pCtrlStck->SetAttr(*pPaM->GetPoint(), RES_FRAMEDIR);
318 else
320 SvxFrameDirection eDir =
321 *pData ? FRMDIR_HORI_RIGHT_TOP : FRMDIR_HORI_LEFT_TOP;
322 NewAttr(SvxFrameDirectionItem(eDir, RES_FRAMEDIR));
326 bool wwSectionManager::SetCols(SwFrmFmt &rFmt, const wwSection &rSection,
327 sal_uInt32 nNettoWidth) const
329 //sprmSCcolumns - number of columns - 1
330 const sal_Int16 nCols = rSection.NoCols();
332 if (nCols < 2) //check for no columns or other weird state
333 return false;
335 SwFmtCol aCol; // Create SwFmtCol
337 //sprmSDxaColumns - Default distance is 1.25 cm
338 sal_Int32 nColSpace = rSection.StandardColSeparation();
340 const SEPr& rSep = rSection.maSep;
342 // sprmSLBetween
343 if (rSep.fLBetween)
345 aCol.SetLineAdj(COLADJ_TOP); // Line
346 aCol.SetLineHeight(100);
347 aCol.SetLineColor(Color(COL_BLACK));
348 aCol.SetLineWidth(1);
351 aCol.Init(nCols, writer_cast<sal_uInt16>(nColSpace),
352 writer_cast<sal_uInt16>(nNettoWidth));
354 // sprmSFEvenlySpaced
355 if (!rSep.fEvenlySpaced)
357 aCol._SetOrtho(false);
358 const sal_uInt16 maxIdx = SAL_N_ELEMENTS(rSep.rgdxaColumnWidthSpacing);
359 for (sal_uInt16 i = 0, nIdx = 1; i < nCols && nIdx < maxIdx; i++, nIdx+=2 )
361 SwColumn* pCol = &aCol.GetColumns()[i];
362 const sal_Int32 nLeft = rSep.rgdxaColumnWidthSpacing[nIdx-1]/2;
363 const sal_Int32 nRight = rSep.rgdxaColumnWidthSpacing[nIdx+1]/2;
364 const sal_Int32 nWishWidth = rSep.rgdxaColumnWidthSpacing[nIdx]
365 + nLeft + nRight;
366 pCol->SetWishWidth(writer_cast<sal_uInt16>(nWishWidth));
367 pCol->SetLeft(writer_cast<sal_uInt16>(nLeft));
368 pCol->SetRight(writer_cast<sal_uInt16>(nRight));
370 aCol.SetWishWidth(writer_cast<sal_uInt16>(nNettoWidth));
372 rFmt.SetFmtAttr(aCol);
373 return true;
376 void wwSectionManager::SetLeftRight(wwSection &rSection)
378 // 3. LR-Raender
379 sal_uInt32 nWWLe = MSRoundTweak(rSection.maSep.dxaLeft);
380 sal_uInt32 nWWRi = MSRoundTweak(rSection.maSep.dxaRight);
381 sal_uInt32 nWWGu = rSection.maSep.dzaGutter;
384 fRTLGutter is set if the gutter is on the right, the gutter is otherwise
385 placed on the left unless the global dop options are to put it on top, that
386 case is handled in GetPageULData.
388 if (rSection.maSep.fRTLGutter)
389 nWWRi += nWWGu;
390 else if (!mrReader.pWDop->iGutterPos)
391 nWWLe += nWWGu;
393 // Left / Right
394 if ((rSection.nPgWidth - nWWLe - nWWRi) < MINLAY)
397 There are some label templates which are "broken", they specify
398 margins which make no sense e.g. Left 16.10cm, Right 16.10cm. So the
399 space left between the margins is less than 0 In word the left margin
400 is honoured and if the right margin would be past the left margin is
401 left at the left margin position.
403 Now this will work fine for importing, layout and exporting, *but* the
404 page layout dialog has a hardcoded minimum page width of 0.5cm so it
405 will report a different value than what is actually being used. i.e.
406 it will add up the values to give a wider page than is actually being
407 used.
409 nWWRi = rSection.nPgWidth - nWWLe - MINLAY;
412 rSection.nPgLeft = nWWLe;
413 rSection.nPgRight = nWWRi;
416 void wwSectionManager::SetPage(SwPageDesc &rInPageDesc, SwFrmFmt &rFmt,
417 const wwSection &rSection, bool bIgnoreCols) const
419 // 1. Orientierung
420 rInPageDesc.SetLandscape(rSection.IsLandScape());
422 // 2. Papiergroesse
423 SwFmtFrmSize aSz( rFmt.GetFrmSize() );
424 aSz.SetWidth(rSection.GetPageWidth());
425 aSz.SetHeight(SvxPaperInfo::GetSloppyPaperDimension(rSection.GetPageHeight()));
426 rFmt.SetFmtAttr(aSz);
428 rFmt.SetFmtAttr(
429 SvxLRSpaceItem(rSection.GetPageLeft(), rSection.GetPageRight(), 0, 0, RES_LR_SPACE));
431 if (!bIgnoreCols)
432 SetCols(rFmt, rSection, rSection.GetTextAreaWidth());
435 static sal_uInt16 lcl_MakeSafeNegativeSpacing(sal_uInt16 nIn)
437 if (nIn > SHRT_MAX)
438 nIn = 0;
439 return nIn;
442 void SwWW8ImplReader::SetPageBorder(SwFrmFmt &rFmt, const wwSection &rSection) const
444 if (!IsBorder(rSection.brc))
445 return;
447 SfxItemSet aSet(rFmt.GetAttrSet());
448 short aSizeArray[5]={0};
449 SetFlyBordersShadow(aSet, rSection.brc, &aSizeArray[0]);
450 SvxLRSpaceItem aLR(ItemGet<SvxLRSpaceItem>(aSet, RES_LR_SPACE));
451 SvxULSpaceItem aUL(ItemGet<SvxULSpaceItem>(aSet, RES_UL_SPACE));
453 SvxBoxItem aBox(ItemGet<SvxBoxItem>(aSet, RES_BOX));
454 short aOriginalBottomMargin = aBox.GetDistance(BOX_LINE_BOTTOM);
456 if (rSection.maSep.pgbOffsetFrom == 1)
458 sal_uInt16 nDist;
459 if (aBox.GetLeft())
461 nDist = aBox.GetDistance(BOX_LINE_LEFT);
462 aBox.SetDistance(lcl_MakeSafeNegativeSpacing(static_cast<sal_uInt16>(aLR.GetLeft() - nDist)), BOX_LINE_LEFT);
463 aSizeArray[WW8_LEFT] =
464 aSizeArray[WW8_LEFT] - nDist + aBox.GetDistance(BOX_LINE_LEFT);
467 if (aBox.GetRight())
469 nDist = aBox.GetDistance(BOX_LINE_RIGHT);
470 aBox.SetDistance(lcl_MakeSafeNegativeSpacing(static_cast<sal_uInt16>(aLR.GetRight() - nDist)), BOX_LINE_RIGHT);
471 aSizeArray[WW8_RIGHT] =
472 aSizeArray[WW8_RIGHT] - nDist + aBox.GetDistance(BOX_LINE_RIGHT);
475 if (aBox.GetTop())
477 nDist = aBox.GetDistance(BOX_LINE_TOP);
478 aBox.SetDistance(lcl_MakeSafeNegativeSpacing(static_cast<sal_uInt16>(aUL.GetUpper() - nDist)), BOX_LINE_TOP);
479 aSizeArray[WW8_TOP] =
480 aSizeArray[WW8_TOP] - nDist + aBox.GetDistance(BOX_LINE_TOP);
483 if (aBox.GetBottom())
485 nDist = aBox.GetDistance(BOX_LINE_BOTTOM);
486 aBox.SetDistance(lcl_MakeSafeNegativeSpacing(static_cast<sal_uInt16>(aUL.GetLower() - nDist)), BOX_LINE_BOTTOM);
487 aSizeArray[WW8_BOT] =
488 aSizeArray[WW8_BOT] - nDist + aBox.GetDistance(BOX_LINE_BOTTOM);
491 aSet.Put(aBox);
494 if (aBox.GetLeft())
495 aLR.SetLeft(lcl_MakeSafeNegativeSpacing(static_cast<sal_uInt16>(aLR.GetLeft() - aSizeArray[WW8_LEFT])));
496 if (aBox.GetRight())
497 aLR.SetRight(lcl_MakeSafeNegativeSpacing(static_cast<sal_uInt16>(aLR.GetRight() - aSizeArray[WW8_RIGHT])));
498 if (aBox.GetTop())
499 aUL.SetUpper(lcl_MakeSafeNegativeSpacing(static_cast<sal_uInt16>(aUL.GetUpper() - aSizeArray[WW8_TOP])));
500 if (aBox.GetBottom())
502 //#i30088# and #i30074# - do a final sanity check on
503 //bottom value. Do not allow a resulting zero if bottom
504 //Border margin value was not originally zero.
505 if(aUL.GetLower() != 0)
506 aUL.SetLower(lcl_MakeSafeNegativeSpacing(static_cast<sal_uInt16>(aUL.GetLower() - aSizeArray[WW8_BOT])));
507 else
508 aUL.SetLower(lcl_MakeSafeNegativeSpacing(static_cast<sal_uInt16>(aOriginalBottomMargin - aSizeArray[WW8_BOT])));
511 aSet.Put(aLR);
512 aSet.Put(aUL);
513 rFmt.SetFmtAttr(aSet);
516 void wwSectionManager::GetPageULData(const wwSection &rSection,
517 wwSectionManager::wwULSpaceData& rData) const
519 sal_Int32 nWWUp = rSection.maSep.dyaTop;
520 sal_Int32 nWWLo = rSection.maSep.dyaBottom;
521 sal_uInt32 nWWHTop = rSection.maSep.dyaHdrTop;
522 sal_uInt32 nWWFBot = rSection.maSep.dyaHdrBottom;
525 If there is gutter in 97+ and the dop says put it on top then get the
526 gutter distance and set it to the top margin. When we are "two pages
527 in one" the gutter is put at the top of odd pages, and bottom of
528 even pages, something we cannot do. So we will put it on top of all
529 pages, that way the pages are at least the right size.
531 if (
532 (!mrReader.bVer67 && mrReader.pWDop->iGutterPos &&
533 rSection.maSep.fRTLGutter)
536 nWWUp += rSection.maSep.dzaGutter;
539 rData.bHasHeader = (rSection.maSep.grpfIhdt &
540 (WW8_HEADER_EVEN | WW8_HEADER_ODD | WW8_HEADER_FIRST)) != 0;
542 if( rData.bHasHeader )
544 rData.nSwUp = nWWHTop; // Header -> umrechnen
545 // #i19922# - correction:
546 // consider that <nWWUp> can be negative, compare only if it's positive
547 if ( nWWUp > 0 &&
548 static_cast<sal_uInt32>(abs(nWWUp)) >= nWWHTop )
549 rData.nSwHLo = nWWUp - nWWHTop;
550 else
551 rData.nSwHLo = 0;
553 // #i19922# - minimum page header height is now 1mm
554 // use new constant <cMinHdFtHeight>
555 if (rData.nSwHLo < sal::static_int_cast< sal_uInt32 >(cMinHdFtHeight))
556 rData.nSwHLo = sal::static_int_cast< sal_uInt32 >(cMinHdFtHeight);
558 else // kein Header -> Up einfach uebernehmen
559 rData.nSwUp = std::abs(nWWUp);
561 rData.bHasFooter = (rSection.maSep.grpfIhdt &
562 (WW8_FOOTER_EVEN | WW8_FOOTER_ODD | WW8_FOOTER_FIRST)) != 0;
564 if( rData.bHasFooter )
566 rData.nSwLo = nWWFBot; // Footer -> Umrechnen
567 // #i19922# - correction: consider that <nWWLo> can be negative, compare only if it's positive
568 if ( nWWLo > 0 &&
569 static_cast<sal_uInt32>(abs(nWWLo)) >= nWWFBot )
570 rData.nSwFUp = nWWLo - nWWFBot;
571 else
572 rData.nSwFUp = 0;
574 // #i19922# - minimum page header height is now 1mm
575 // use new constant <cMinHdFtHeight>
576 if (rData.nSwFUp < sal::static_int_cast< sal_uInt32 >(cMinHdFtHeight))
577 rData.nSwFUp = sal::static_int_cast< sal_uInt32 >(cMinHdFtHeight);
579 else // kein Footer -> Lo einfach uebernehmen
580 rData.nSwLo = std::abs(nWWLo);
583 void wwSectionManager::SetPageULSpaceItems(SwFrmFmt &rFmt,
584 wwSectionManager::wwULSpaceData& rData, const wwSection &rSection) const
586 if (rData.bHasHeader) // ... und Header-Lower setzen
588 //Kopfzeilenhoehe minimal sezten
589 if (SwFrmFmt* pHdFmt = (SwFrmFmt*)rFmt.GetHeader().GetHeaderFmt())
591 SvxULSpaceItem aHdUL(pHdFmt->GetULSpace());
592 if (!rSection.IsFixedHeightHeader()) //normal
594 pHdFmt->SetFmtAttr(SwFmtFrmSize(ATT_MIN_SIZE, 0, rData.nSwHLo));
595 // #i19922# - minimum page header height is now 1mm
596 // use new constant <cMinHdFtHeight>
597 aHdUL.SetLower( writer_cast<sal_uInt16>(rData.nSwHLo - cMinHdFtHeight) );
598 pHdFmt->SetFmtAttr(SwHeaderAndFooterEatSpacingItem(
599 RES_HEADER_FOOTER_EAT_SPACING, true));
601 else
603 // #i48832# - set correct spacing between header and body.
604 const SwTwips nHdLowerSpace( std::abs(rSection.maSep.dyaTop) - rData.nSwUp - rData.nSwHLo );
605 pHdFmt->SetFmtAttr(SwFmtFrmSize(ATT_FIX_SIZE, 0, rData.nSwHLo + nHdLowerSpace));
606 aHdUL.SetLower( static_cast< sal_uInt16 >(nHdLowerSpace) );
607 pHdFmt->SetFmtAttr(SwHeaderAndFooterEatSpacingItem(
608 RES_HEADER_FOOTER_EAT_SPACING, false));
610 pHdFmt->SetFmtAttr(aHdUL);
614 if (rData.bHasFooter) // ... und Footer-Upper setzen
616 if (SwFrmFmt* pFtFmt = (SwFrmFmt*)rFmt.GetFooter().GetFooterFmt())
618 SvxULSpaceItem aFtUL(pFtFmt->GetULSpace());
619 if (!rSection.IsFixedHeightFooter()) //normal
621 pFtFmt->SetFmtAttr(SwFmtFrmSize(ATT_MIN_SIZE, 0, rData.nSwFUp));
622 // #i19922# - minimum page header height is now 1mm
623 // use new constant <cMinHdFtHeight>
624 aFtUL.SetUpper( writer_cast<sal_uInt16>(rData.nSwFUp - cMinHdFtHeight) );
625 pFtFmt->SetFmtAttr(SwHeaderAndFooterEatSpacingItem(
626 RES_HEADER_FOOTER_EAT_SPACING, true));
628 else
630 // #i48832# - set correct spacing between footer and body.
631 const SwTwips nFtUpperSpace( std::abs(rSection.maSep.dyaBottom) - rData.nSwLo - rData.nSwFUp );
632 pFtFmt->SetFmtAttr(SwFmtFrmSize(ATT_FIX_SIZE, 0, rData.nSwFUp + nFtUpperSpace));
633 aFtUL.SetUpper( static_cast< sal_uInt16 >(nFtUpperSpace) );
634 pFtFmt->SetFmtAttr(SwHeaderAndFooterEatSpacingItem(
635 RES_HEADER_FOOTER_EAT_SPACING, false));
637 pFtFmt->SetFmtAttr(aFtUL);
641 SvxULSpaceItem aUL(writer_cast<sal_uInt16>(rData.nSwUp),
642 writer_cast<sal_uInt16>(rData.nSwLo), RES_UL_SPACE);
643 rFmt.SetFmtAttr(aUL);
646 SwSectionFmt *wwSectionManager::InsertSection(
647 SwPaM& rMyPaM, wwSection &rSection)
649 SwSectionData aSection( CONTENT_SECTION,
650 mrReader.rDoc.GetUniqueSectionName() );
652 SfxItemSet aSet( mrReader.rDoc.GetAttrPool(), aFrmFmtSetRange );
654 sal_uInt8 nRTLPgn = maSegments.empty() ? 0 : maSegments.back().IsBiDi();
655 aSet.Put(SvxFrameDirectionItem(
656 nRTLPgn ? FRMDIR_HORI_RIGHT_TOP : FRMDIR_HORI_LEFT_TOP, RES_FRAMEDIR));
658 if (2 == mrReader.pWDop->fpc)
659 aSet.Put( SwFmtFtnAtTxtEnd(FTNEND_ATTXTEND));
660 if (0 == mrReader.pWDop->epc)
661 aSet.Put( SwFmtEndAtTxtEnd(FTNEND_ATTXTEND));
663 aSection.SetProtectFlag(SectionIsProtected(rSection));
665 rSection.mpSection =
666 mrReader.rDoc.InsertSwSection( rMyPaM, aSection, 0, & aSet );
667 OSL_ENSURE(rSection.mpSection, "section not inserted!");
668 if (!rSection.mpSection)
669 return 0;
671 SwPageDesc *pPage = 0;
672 mySegrIter aEnd = maSegments.rend();
673 for (mySegrIter aIter = maSegments.rbegin(); aIter != aEnd; ++aIter)
675 if (0 != (pPage = aIter->mpPage))
676 break;
679 OSL_ENSURE(pPage, "no page outside this section!");
681 if (!pPage)
682 pPage = &mrReader.rDoc.GetPageDesc(0);
684 if (!pPage)
685 return 0;
687 SwSectionFmt *pFmt = rSection.mpSection->GetFmt();
688 OSL_ENSURE(pFmt, "impossible");
689 if (!pFmt)
690 return 0;
692 SwFrmFmt& rFmt = pPage->GetMaster();
693 const SvxLRSpaceItem& rLR = rFmt.GetLRSpace();
694 long nPageLeft = rLR.GetLeft();
695 long nPageRight = rLR.GetRight();
696 long nSectionLeft = rSection.GetPageLeft() - nPageLeft;
697 long nSectionRight = rSection.GetPageRight() - nPageRight;
698 if ((nSectionLeft != 0) || (nSectionRight != 0))
700 SvxLRSpaceItem aLR(nSectionLeft, nSectionRight, 0, 0, RES_LR_SPACE);
701 pFmt->SetFmtAttr(aLR);
704 SetCols(*pFmt, rSection, rSection.GetTextAreaWidth());
705 return pFmt;
708 void SwWW8ImplReader::HandleLineNumbering(const wwSection &rSection)
710 // check if Line Numbering must be activated or resetted
711 if (mbNewDoc && rSection.maSep.nLnnMod)
713 // restart-numbering-mode: 0 per page, 1 per section, 2 never restart
714 bool bRestartLnNumPerSection = (1 == rSection.maSep.lnc);
716 if (bNoLnNumYet)
718 SwLineNumberInfo aInfo( rDoc.GetLineNumberInfo() );
720 aInfo.SetPaintLineNumbers(true);
722 aInfo.SetRestartEachPage(rSection.maSep.lnc == 0);
724 aInfo.SetPosFromLeft(writer_cast<sal_uInt16>(rSection.maSep.dxaLnn));
726 //Paint only for every n line
727 aInfo.SetCountBy(rSection.maSep.nLnnMod);
729 // to be defaulted features ( HARDCODED in MS Word 6,7,8,9 )
730 aInfo.SetCountBlankLines(true);
731 aInfo.SetCountInFlys(false);
732 aInfo.SetPos( LINENUMBER_POS_LEFT );
733 SvxNumberType aNumType; // this sets SVX_NUM_ARABIC per default
734 aInfo.SetNumType( aNumType );
736 rDoc.SetLineNumberInfo( aInfo );
737 bNoLnNumYet = false;
740 if (
741 (0 < rSection.maSep.lnnMin) ||
742 (bRestartLnNumPerSection && !bNoLnNumYet)
745 SwFmtLineNumber aLN;
746 if (const SwFmtLineNumber* pLN
747 = (const SwFmtLineNumber*)GetFmtAttr(RES_LINENUMBER))
749 aLN.SetCountLines( pLN->IsCount() );
751 aLN.SetStartValue(1 + rSection.maSep.lnnMin);
752 NewAttr(aLN);
753 pCtrlStck->SetAttr(*pPaM->GetPoint(), RES_LINENUMBER);
755 bNoLnNumYet = false;
759 wwSection::wwSection(const SwPosition &rPos) : maStart(rPos.nNode),
760 mpSection(0), mpPage(0), meDir(FRMDIR_HORI_LEFT_TOP),
761 nPgWidth(SvxPaperInfo::GetPaperSize(PAPER_A4).Width()),
762 nPgLeft(MM_250), nPgRight(MM_250), mnBorders(0), mbHasFootnote(false)
766 void wwSectionManager::SetNumberingType(const wwSection &rNewSection,
767 SwPageDesc &rPageDesc) const
769 // Seitennummernformat speichern
770 static const SvxExtNumType aNumTyp[5] =
772 SVX_NUM_ARABIC, SVX_NUM_ROMAN_UPPER, SVX_NUM_ROMAN_LOWER,
773 SVX_NUM_CHARS_UPPER_LETTER_N, SVX_NUM_CHARS_LOWER_LETTER_N
776 SvxNumberType aType;
777 aType.SetNumberingType( static_cast< sal_Int16 >(aNumTyp[rNewSection.maSep.nfcPgn]) );
778 rPageDesc.SetNumType(aType);
781 // Bei jedem Abschnittswechsel ( auch am Anfang eines Dokuments ) wird
782 // CreateSep gerufen, dass dann den / die Pagedesc(s) erzeugt und
783 // mit Attributen un KF-Texten fuellt.
784 // Dieses Vorgehen ist noetig geworden, da die UEbersetzung der verschiedenen
785 // Seiten-Attribute zu stark verflochten ist.
786 void wwSectionManager::CreateSep(const long nTxtPos, bool /*bMustHaveBreak*/)
789 #i1909# section/page breaks should not occur in tables or subpage
790 elements like frames. Word itself ignores them in this case. The bug is
791 more likely that this filter created such documents in the past!
793 if (mrReader.nInTable || mrReader.bTxbxFlySection || mrReader.InLocalApo())
794 return;
796 WW8PLCFx_SEPX* pSep = mrReader.pPlcxMan->GetSepPLCF();
797 OSL_ENSURE(pSep, "impossible!");
798 if (!pSep)
799 return;
801 ww::WordVersion eVer = mrReader.GetFib().GetFIBVersion();
803 // M.M. Create a linked section if the WkbPLCF
804 // has an entry for one at this cp
805 WW8PLCFspecial* pWkb = mrReader.pPlcxMan->GetWkbPLCF();
806 if (pWkb && pWkb->SeekPosExact(nTxtPos) &&
807 pWkb->Where() == nTxtPos)
809 void* pData;
810 WW8_CP nTest;
811 pWkb->Get(nTest, pData);
812 String sSectionName = mrReader.aLinkStringMap[SVBT16ToShort( ((WW8_WKB*)pData)->nLinkId) ];
813 mrReader.ConvertFFileName(sSectionName, sSectionName);
814 SwSectionData aSection(FILE_LINK_SECTION, sSectionName);
815 aSection.SetLinkFileName( sSectionName );
816 aSection.SetProtectFlag(true);
817 // #i19922# - improvement: return value of method <Insert> not used.
818 mrReader.rDoc.InsertSwSection(*mrReader.pPaM, aSection, 0, 0, false);
821 wwSection aLastSection(*mrReader.pPaM->GetPoint());
822 if (!maSegments.empty())
823 aLastSection = maSegments.back();
825 //Here
826 sal_uInt16 nLIdx = ( ( mrReader.pWwFib->lid & 0xff ) == 0x9 ) ? 1 : 0;
828 //BEGIN read section values
829 wwSection aNewSection(*mrReader.pPaM->GetPoint());
831 static const sal_uInt16 aVer2Ids0[] =
833 /*sprmSBkc*/ 117,
834 /*sprmSFTitlePage*/ 118,
835 /*sprmSNfcPgn*/ 122,
836 /*sprmSCcolumns*/ 119,
837 /*sprmSDxaColumns*/ 120,
838 /*sprmSLBetween*/ 133
841 static const sal_uInt16 aVer67Ids0[] =
843 /*sprmSBkc*/ 142,
844 /*sprmSFTitlePage*/ 143,
845 /*sprmSNfcPgn*/ 147,
846 /*sprmSCcolumns*/ 144,
847 /*sprmSDxaColumns*/ 145,
848 /*sprmSLBetween*/ 158
851 static const sal_uInt16 aVer8Ids0[] =
853 /*sprmSBkc*/ 0x3009,
854 /*sprmSFTitlePage*/ 0x300A,
855 /*sprmSNfcPgn*/ 0x300E,
856 /*sprmSCcolumns*/ 0x500B,
857 /*sprmSDxaColumns*/ 0x900C,
858 /*sprmSLBetween*/ 0x3019
861 const sal_uInt16* pIds = eVer <= ww::eWW2 ? aVer2Ids0 : eVer <= ww::eWW7 ? aVer67Ids0 : aVer8Ids0;
863 if (!maSegments.empty())
865 // Type of break: break codes are:
866 // 0 No break
867 // 1 New column
868 // 2 New page
869 // 3 Even page
870 // 4 Odd page
871 if (const sal_uInt8* pSprmBkc = pSep->HasSprm(pIds[0]))
872 aNewSection.maSep.bkc = *pSprmBkc;
875 // Has a table page
876 aNewSection.maSep.fTitlePage =
877 (0 != ReadBSprm( pSep, pIds[1], 0 ));
879 // sprmSNfcPgn
880 aNewSection.maSep.nfcPgn = ReadBSprm( pSep, pIds[2], 0 );
881 if (aNewSection.maSep.nfcPgn > 4)
882 aNewSection.maSep.nfcPgn = 0;
884 aNewSection.maSep.fUnlocked = eVer > ww::eWW2 ? ReadBSprm(pSep, (eVer <= ww::eWW7 ? 139 : 0x3006), 0 ) : 0;
886 // sprmSFBiDi
887 aNewSection.maSep.fBiDi = eVer >= ww::eWW8 ? ReadBSprm(pSep, 0x3228, 0) : 0;
889 aNewSection.maSep.ccolM1 = ReadSprm(pSep, pIds[3], 0 );
891 //sprmSDxaColumns - Default-Abstand 1.25 cm
892 aNewSection.maSep.dxaColumns = ReadUSprm( pSep, pIds[4], 708 );
894 // sprmSLBetween
895 aNewSection.maSep.fLBetween = ReadBSprm(pSep, pIds[5], 0 );
897 if (eVer >= ww::eWW6)
899 // sprmSFEvenlySpaced
900 aNewSection.maSep.fEvenlySpaced =
901 ReadBSprm(pSep, (eVer <= ww::eWW7 ? 138 : 0x3005), 1) ? true : false;
903 const sal_uInt8 numrgda = SAL_N_ELEMENTS(aNewSection.maSep.rgdxaColumnWidthSpacing);
904 if (aNewSection.maSep.ccolM1 > 0 && !aNewSection.maSep.fEvenlySpaced)
906 aNewSection.maSep.rgdxaColumnWidthSpacing[0] = 0;
907 int nCols = aNewSection.maSep.ccolM1 + 1;
908 int nIdx = 0;
909 for (int i = 0; i < nCols; ++i)
911 //sprmSDxaColWidth
912 const sal_uInt8* pSW = pSep->HasSprm( (eVer <= ww::eWW7 ? 136 : 0xF203), sal_uInt8( i ) );
914 OSL_ENSURE( pSW, "+Sprm 136 (bzw. 0xF203) (ColWidth) fehlt" );
915 sal_uInt16 nWidth = pSW ? SVBT16ToShort(pSW + 1) : 1440;
917 if (++nIdx < numrgda)
918 aNewSection.maSep.rgdxaColumnWidthSpacing[nIdx] = nWidth;
920 if (i < nCols-1)
922 //sprmSDxaColSpacing
923 const sal_uInt8* pSD = pSep->HasSprm( (eVer <= ww::eWW7 ? 137 : 0xF204), sal_uInt8( i ) );
925 OSL_ENSURE( pSD, "+Sprm 137 (bzw. 0xF204) (Colspacing) fehlt" );
926 if( pSD )
928 nWidth = SVBT16ToShort(pSD + 1);
929 if (++nIdx < numrgda)
930 aNewSection.maSep.rgdxaColumnWidthSpacing[nIdx] = nWidth;
937 static const sal_uInt16 aVer2Ids1[] =
939 /*sprmSBOrientation*/ 137,
940 /*sprmSXaPage*/ 139,
941 /*sprmSYaPage*/ 140,
942 /*sprmSDxaLeft*/ 141,
943 /*sprmSDxaRight*/ 142,
944 /*sprmSDzaGutter*/ 145,
945 /*sprmSFPgnRestart*/ 125,
946 /*sprmSPgnStart*/ 136,
947 /*sprmSDmBinFirst*/ 115,
948 /*sprmSDmBinOther*/ 116
951 static const sal_uInt16 aVer67Ids1[] =
953 /*sprmSBOrientation*/ 162,
954 /*sprmSXaPage*/ 164,
955 /*sprmSYaPage*/ 165,
956 /*sprmSDxaLeft*/ 166,
957 /*sprmSDxaRight*/ 167,
958 /*sprmSDzaGutter*/ 170,
959 /*sprmSFPgnRestart*/ 150,
960 /*sprmSPgnStart*/ 161,
961 /*sprmSDmBinFirst*/ 140,
962 /*sprmSDmBinOther*/ 141
965 static const sal_uInt16 aVer8Ids1[] =
967 /*sprmSBOrientation*/ 0x301d,
968 /*sprmSXaPage*/ 0xB01F,
969 /*sprmSYaPage*/ 0xB020,
970 /*sprmSDxaLeft*/ 0xB021,
971 /*sprmSDxaRight*/ 0xB022,
972 /*sprmSDzaGutter*/ 0xB025,
973 /*sprmSFPgnRestart*/ 0x3011,
974 /*sprmSPgnStart*/ 0x501C,
975 /*sprmSDmBinFirst*/ 0x5007,
976 /*sprmSDmBinOther*/ 0x5008
979 pIds = eVer <= ww::eWW2 ? aVer2Ids1 : eVer <= ww::eWW7 ? aVer67Ids1 : aVer8Ids1;
981 // 1. Orientierung
982 aNewSection.maSep.dmOrientPage = ReadBSprm(pSep, pIds[0], 0);
984 // 2. Papiergroesse
985 aNewSection.maSep.xaPage = ReadUSprm(pSep, pIds[1], lLetterWidth);
986 aNewSection.nPgWidth = SvxPaperInfo::GetSloppyPaperDimension(aNewSection.maSep.xaPage);
988 aNewSection.maSep.yaPage = ReadUSprm(pSep, pIds[2], lLetterHeight);
990 // 3. LR-Raender
991 static const sal_uInt16 nLef[] = { MM_250, 1800 };
992 static const sal_uInt16 nRig[] = { MM_250, 1800 };
994 aNewSection.maSep.dxaLeft = ReadUSprm( pSep, pIds[3], nLef[nLIdx]);
995 aNewSection.maSep.dxaRight = ReadUSprm( pSep, pIds[4], nRig[nLIdx]);
997 // 2pages in 1sheet hackery ?
998 // #i31806# but only swap if 2page in 1sheet is enabled.
999 // its not clear if dmOrientPage is the correct member to
1000 // decide on this but I am not about to 2nd guess cmc.
1001 if(mrReader.pWDop->doptypography.f2on1 &&
1002 aNewSection.maSep.dmOrientPage == 2)
1003 std::swap(aNewSection.maSep.dxaLeft, aNewSection.maSep.dxaRight);
1005 aNewSection.maSep.dzaGutter = ReadUSprm( pSep, pIds[5], 0);
1007 aNewSection.maSep.fRTLGutter = static_cast< sal_uInt8 >(eVer >= ww::eWW8 ? ReadUSprm( pSep, 0x322A, 0 ) : 0);
1009 // Page Number Restarts - sprmSFPgnRestart
1010 aNewSection.maSep.fPgnRestart = ReadBSprm(pSep, pIds[6], 0);
1012 aNewSection.maSep.pgnStart = ReadBSprm( pSep, pIds[7], 0 );
1014 if (eVer >= ww::eWW6)
1016 if (const sal_uInt8* p = pSep->HasSprm( (eVer <= ww::eWW7 ? 132 : 0x3001) ))
1017 aNewSection.maSep.iHeadingPgn = *p;
1019 if (const sal_uInt8* p = pSep->HasSprm( (eVer <= ww::eWW7 ? 131 : 0x3000) ))
1020 aNewSection.maSep.cnsPgn = *p;
1023 if(const sal_uInt8* pSprmSDmBinFirst = pSep->HasSprm( pIds[8] ))
1024 aNewSection.maSep.dmBinFirst = *pSprmSDmBinFirst;
1026 if (const sal_uInt8* pSprmSDmBinOther = pSep->HasSprm( pIds[9] ))
1027 aNewSection.maSep.dmBinOther = *pSprmSDmBinOther;
1029 static const sal_uInt16 nTop[] = { MM_250, 1440 };
1030 static const sal_uInt16 nBot[] = { MM_200, 1440 };
1032 static const sal_uInt16 aVer2Ids2[] =
1034 /*sprmSDyaTop*/ 143,
1035 /*sprmSDyaBottom*/ 144,
1036 /*sprmSDyaHdrTop*/ 131,
1037 /*sprmSDyaHdrBottom*/ 132,
1038 /*sprmSNLnnMod*/ 129,
1039 /*sprmSLnc*/ 127,
1040 /*sprmSDxaLnn*/ 130,
1041 /*sprmSLnnMin*/ 135
1044 static const sal_uInt16 aVer67Ids2[] =
1046 /*sprmSDyaTop*/ 168,
1047 /*sprmSDyaBottom*/ 169,
1048 /*sprmSDyaHdrTop*/ 156,
1049 /*sprmSDyaHdrBottom*/ 157,
1050 /*sprmSNLnnMod*/ 154,
1051 /*sprmSLnc*/ 152,
1052 /*sprmSDxaLnn*/ 155,
1053 /*sprmSLnnMin*/ 160
1055 static const sal_uInt16 aVer8Ids2[] =
1057 /*sprmSDyaTop*/ 0x9023,
1058 /*sprmSDyaBottom*/ 0x9024,
1059 /*sprmSDyaHdrTop*/ 0xB017,
1060 /*sprmSDyaHdrBottom*/ 0xB018,
1061 /*sprmSNLnnMod*/ 0x5015,
1062 /*sprmSLnc*/ 0x3013,
1063 /*sprmSDxaLnn*/ 0x9016,
1064 /*sprmSLnnMin*/ 0x501B
1067 pIds = eVer <= ww::eWW2 ? aVer2Ids2 : eVer <= ww::eWW7 ? aVer67Ids2 : aVer8Ids2;
1069 aNewSection.maSep.dyaTop = ReadSprm( pSep, pIds[0], nTop[nLIdx] );
1070 aNewSection.maSep.dyaBottom = ReadSprm( pSep, pIds[1], nBot[nLIdx] );
1071 aNewSection.maSep.dyaHdrTop = ReadUSprm( pSep, pIds[2], 720 );
1072 aNewSection.maSep.dyaHdrBottom = ReadUSprm( pSep, pIds[3], 720 );
1074 if (eVer >= ww::eWW8)
1076 aNewSection.maSep.wTextFlow = ReadUSprm(pSep, 0x5033, 0);
1077 aNewSection.maSep.clm = ReadUSprm( pSep, 0x5032, 0 );
1078 aNewSection.maSep.dyaLinePitch = ReadUSprm(pSep, 0x9031, 360);
1079 if (const sal_uInt8* pS = pSep->HasSprm(0x7030))
1080 aNewSection.maSep.dxtCharSpace = SVBT32ToUInt32(pS);
1082 //sprmSPgbProp
1083 sal_uInt16 pgbProp = ReadSprm( pSep, 0x522F, 0 );
1084 aNewSection.maSep.pgbApplyTo = pgbProp & 0x0007;
1085 aNewSection.maSep.pgbPageDepth = (pgbProp & 0x0018) >> 3;
1086 aNewSection.maSep.pgbOffsetFrom = (pgbProp & 0x00E0) >> 5;
1088 aNewSection.mnBorders =
1089 ::lcl_ReadBorders(eVer <= ww::eWW7, aNewSection.brc, 0, 0, pSep);
1092 // check if Line Numbering must be activated or resetted
1093 if (const sal_uInt8* pSprmSNLnnMod = pSep->HasSprm( pIds[4] ))
1094 aNewSection.maSep.nLnnMod = *pSprmSNLnnMod;
1096 if (const sal_uInt8* pSprmSLnc = pSep->HasSprm( pIds[5] ))
1097 aNewSection.maSep.lnc = *pSprmSLnc;
1099 if (const sal_uInt8* pSprmSDxaLnn = pSep->HasSprm( pIds[6] ))
1100 aNewSection.maSep.dxaLnn = SVBT16ToShort( pSprmSDxaLnn );
1102 if (const sal_uInt8* pSprmSLnnMin = pSep->HasSprm( pIds[7] ))
1103 aNewSection.maSep.lnnMin = *pSprmSLnnMin;
1105 if (eVer <= ww::eWW7)
1106 aNewSection.maSep.grpfIhdt = ReadBSprm(pSep, eVer <= ww::eWW2 ? 128 : 153, 0);
1107 else if (mrReader.pHdFt)
1109 aNewSection.maSep.grpfIhdt = WW8_HEADER_ODD | WW8_FOOTER_ODD
1110 | WW8_HEADER_FIRST | WW8_FOOTER_FIRST;
1112 // It is possible for a first page header to be provided
1113 // for this section, but not actually shown in this section. In this
1114 // case (aNewSection.maSep.grpfIhdt & WW8_HEADER_FIRST) will be nonzero
1115 // but aNewSection.HasTitlePage() will be false.
1116 // Likewise for first page footer.
1118 if (mrReader.pWDop->fFacingPages)
1119 aNewSection.maSep.grpfIhdt |= WW8_HEADER_EVEN | WW8_FOOTER_EVEN;
1121 //See if we have a header or footer for each enabled possibility
1122 //if we do not then we inherit the previous sections header/footer,
1123 for (int nI = 0, nMask = 1; nI < 6; ++nI, nMask <<= 1)
1125 if (aNewSection.maSep.grpfIhdt & nMask)
1127 WW8_CP nStart;
1128 long nLen;
1129 mrReader.pHdFt->GetTextPosExact( static_cast< short >(nI + ( maSegments.size() + 1) * 6), nStart, nLen);
1130 //No header or footer, inherit pervious one, or set to zero
1131 //if no previous one
1132 if (!nLen)
1134 if (
1135 maSegments.empty() ||
1136 !(maSegments.back().maSep.grpfIhdt & nMask)
1139 aNewSection.maSep.grpfIhdt &= ~nMask;
1146 SetLeftRight(aNewSection);
1147 //END read section values
1149 if (eVer >= ww::eWW8)
1150 aNewSection.SetDirection();
1152 mrReader.HandleLineNumbering(aNewSection);
1153 maSegments.push_back(aNewSection);
1156 void SwWW8ImplReader::CopyPageDescHdFt(const SwPageDesc* pOrgPageDesc,
1157 SwPageDesc* pNewPageDesc, sal_uInt8 nCode )
1159 // copy odd header content section
1160 if( nCode & WW8_HEADER_ODD )
1162 rDoc.CopyHeader(pOrgPageDesc->GetMaster(),
1163 pNewPageDesc->GetMaster() );
1165 // copy odd footer content section
1166 if( nCode & WW8_FOOTER_ODD )
1168 rDoc.CopyFooter(pOrgPageDesc->GetMaster(),
1169 pNewPageDesc->GetMaster());
1171 // copy even header content section
1172 if( nCode & WW8_HEADER_EVEN )
1174 rDoc.CopyHeader(pOrgPageDesc->GetLeft(),
1175 pNewPageDesc->GetLeft());
1177 // copy even footer content section
1178 if( nCode & WW8_FOOTER_EVEN )
1180 rDoc.CopyFooter(pOrgPageDesc->GetLeft(),
1181 pNewPageDesc->GetLeft());
1183 // copy first page header content section
1184 if( nCode & WW8_HEADER_FIRST )
1186 rDoc.CopyHeader(pOrgPageDesc->GetFirstMaster(),
1187 pNewPageDesc->GetFirstMaster());
1189 // copy first page footer content section
1190 if( nCode & WW8_FOOTER_FIRST )
1192 rDoc.CopyFooter(pOrgPageDesc->GetFirstMaster(),
1193 pNewPageDesc->GetFirstMaster());
1197 //------------------------------------------------------
1198 // Hilfsroutinen fuer Grafiken und Apos und Tabellen
1199 //------------------------------------------------------
1201 static bool _SetWW8_BRC(bool bVer67, WW8_BRC& rVar, const sal_uInt8* pS)
1203 if( pS )
1205 if( bVer67 )
1206 memcpy( rVar.aBits1, pS, sizeof( SVBT16 ) );
1207 else
1208 rVar = *((WW8_BRC*)pS);
1211 return 0 != pS;
1214 static sal_uInt8 lcl_ReadBorders(bool bVer67, WW8_BRC* brc, WW8PLCFx_Cp_FKP* pPap,
1215 const WW8RStyle* pSty, const WW8PLCFx_SEPX* pSep)
1218 //returns a sal_uInt8 filled with a bit for each position that had a sprm
1219 //setting that border
1221 sal_uInt8 nBorder = 0;
1222 if( pSep )
1224 if( !bVer67 )
1226 sal_uInt8* pSprm[4];
1228 // sprmSBrcTop, sprmSBrcLeft, sprmSBrcBottom, sprmSBrcRight
1229 if( pSep->Find4Sprms( 0x702B, 0x702C, 0x702D, 0x702E,
1230 pSprm[0], pSprm[1], pSprm[2], pSprm[3] ) )
1232 for( int i = 0; i < 4; ++i )
1233 nBorder |= (_SetWW8_BRC( bVer67, brc[ i ], pSprm[ i ] ))<<i;
1237 else
1240 static const sal_uInt16 aVer67Ids[5] = { 38, 39, 40, 41, 42 };
1242 static const sal_uInt16 aVer8Ids[5] =
1243 { 0x6424, 0x6425, 0x6426, 0x6427, 0x6428 };
1245 const sal_uInt16* pIds = bVer67 ? aVer67Ids : aVer8Ids;
1247 if( pPap )
1249 for( int i = 0; i < 5; ++i, ++pIds )
1250 nBorder |= (_SetWW8_BRC( bVer67, brc[ i ], pPap->HasSprm( *pIds )))<<i;
1252 else if( pSty )
1254 for( int i = 0; i < 5; ++i, ++pIds )
1255 nBorder |= (_SetWW8_BRC( bVer67, brc[ i ], pSty->HasParaSprm( *pIds )))<<i;
1257 else {
1258 OSL_ENSURE( pSty || pPap, "WW8PLCFx_Cp_FKP and WW8RStyle "
1259 "and WW8PLCFx_SEPX is 0" );
1263 return nBorder;
1266 void GetLineIndex(SvxBoxItem &rBox, short nLineThickness, short nSpace, sal_uInt8 nCol, short nIdx,
1267 sal_uInt16 nOOIndex, sal_uInt16 nWWIndex, short *pSize=0)
1269 ::editeng::SvxBorderStyle const eStyle(
1270 ::editeng::ConvertBorderStyleFromWord(nIdx));
1272 ::editeng::SvxBorderLine aLine;
1273 aLine.SetBorderLineStyle( eStyle );
1274 double const fConverted( (table::BorderLineStyle::NONE == eStyle) ? 0.0 :
1275 ::editeng::ConvertBorderWidthFromWord(eStyle, nLineThickness, nIdx));
1276 aLine.SetWidth(fConverted);
1278 //No AUTO for borders as yet, so if AUTO, use BLACK
1279 if (nCol == 0)
1280 nCol = 1;
1282 aLine.SetColor(SwWW8ImplReader::GetCol(nCol));
1284 if (pSize)
1285 pSize[nWWIndex] = fConverted + nSpace;
1287 rBox.SetLine(&aLine, nOOIndex);
1288 rBox.SetDistance(nSpace, nOOIndex);
1292 void Set1Border(bool bVer67, SvxBoxItem &rBox, const WW8_BRC& rBor,
1293 sal_uInt16 nOOIndex, sal_uInt16 nWWIndex, short *pSize=0)
1295 sal_uInt8 nCol;
1296 short nSpace, nIdx;
1297 short nLineThickness = rBor.DetermineBorderProperties(bVer67,&nSpace,&nCol,
1298 &nIdx);
1300 GetLineIndex(rBox, nLineThickness, nSpace, nCol, nIdx, nOOIndex, nWWIndex, pSize );
1304 static bool lcl_IsBorder(bool bVer67, const WW8_BRC* pbrc, bool bChkBtwn = false)
1306 if( bVer67 )
1307 return ( pbrc[WW8_TOP ].aBits1[0] & 0x18 ) || // brcType != 0
1308 ( pbrc[WW8_LEFT ].aBits1[0] & 0x18 ) ||
1309 ( pbrc[WW8_BOT ].aBits1[0] & 0x18 ) ||
1310 ( pbrc[WW8_RIGHT].aBits1[0] & 0x18 ) ||
1311 ( bChkBtwn && ( pbrc[WW8_BETW ].aBits1[0] )) ||
1312 //can have dotted and dashed with a brcType of 0
1313 ( (pbrc[WW8_TOP ].aBits1[0] & 0x07)+1 > 6) ||
1314 ( (pbrc[WW8_LEFT ].aBits1[0] & 0x07)+1 > 6) ||
1315 ( (pbrc[WW8_BOT ].aBits1[0] & 0x07)+1 > 6) ||
1316 ( (pbrc[WW8_RIGHT].aBits1[0] & 0x07)+1 > 6) ||
1317 ( bChkBtwn && ( (pbrc[WW8_BETW ].aBits1[0] & 0x07)+1 > 6))
1319 // Abfrage auf 0x1f statt 0x18 ist noetig, da zumindest einige
1320 // WW-Versionen ( 6.0 US ) bei dotted brcType auf 0 setzen
1321 else
1322 return pbrc[WW8_TOP ].aBits1[1] || // brcType != 0
1323 pbrc[WW8_LEFT ].aBits1[1] ||
1324 pbrc[WW8_BOT ].aBits1[1] ||
1325 pbrc[WW8_RIGHT].aBits1[1] ||
1326 (bChkBtwn && pbrc[WW8_BETW ].aBits1[1]);
1329 bool SwWW8ImplReader::IsBorder(const WW8_BRC* pbrc, bool bChkBtwn) const
1331 return lcl_IsBorder(bVer67, pbrc, bChkBtwn);
1334 bool WW8_BRC::IsEmpty(bool bVer67) const
1336 return (IsBlank() || IsZeroed(bVer67));
1339 bool WW8_BRC::IsBlank() const
1341 return (aBits1[0] == 0xff && aBits1[1] == 0xff);
1344 bool WW8_BRC::IsZeroed(bool bVer67) const
1346 return (!(bVer67 ? (aBits1[0] & 0x001f) : aBits1[1]));
1349 bool SwWW8ImplReader::SetBorder(SvxBoxItem& rBox, const WW8_BRC* pbrc,
1350 short *pSizeArray, sal_uInt8 nSetBorders) const
1352 bool bChange = false;
1353 static const sal_uInt16 aIdArr[ 10 ] =
1355 WW8_TOP, BOX_LINE_TOP,
1356 WW8_LEFT, BOX_LINE_LEFT,
1357 WW8_RIGHT, BOX_LINE_RIGHT,
1358 WW8_BOT, BOX_LINE_BOTTOM,
1359 WW8_BETW, BOX_LINE_BOTTOM
1362 for( int i = 0, nEnd = 8; i < nEnd; i += 2 )
1364 // ungueltige Borders ausfiltern
1365 const WW8_BRC& rB = pbrc[ aIdArr[ i ] ];
1366 if( !rB.IsEmpty(bVer67))
1368 Set1Border(bVer67, rBox, rB, aIdArr[i+1], aIdArr[i], pSizeArray);
1369 bChange = true;
1371 else if ( nSetBorders & (1 << aIdArr[i]) )
1374 ##826##, ##653##
1376 If a style has borders set,and the para attributes attempt remove
1377 the borders, then this is perfectably acceptable, so we shouldn't
1378 ignore this blank entry
1380 nSetBorders has a bit set for each location that a sprm set a
1381 border, so with a sprm set, but no border, then disable the
1382 appropriate border
1384 rBox.SetLine( 0, aIdArr[ i+1 ] );
1387 return bChange;
1391 bool SwWW8ImplReader::SetShadow(SvxShadowItem& rShadow, const short *pSizeArray,
1392 const WW8_BRC *pbrc) const
1394 bool bRet = (
1395 ( bVer67 ? (pbrc[WW8_RIGHT].aBits1[ 0 ] & 0x20 )
1396 : (pbrc[WW8_RIGHT].aBits2[ 1 ] & 0x20 ) )
1397 && (pSizeArray && pSizeArray[WW8_RIGHT])
1399 if (bRet)
1401 rShadow.SetColor(Color(COL_BLACK));
1402 short nVal = pSizeArray[WW8_RIGHT];
1403 if (nVal < 0x10)
1404 nVal = 0x10;
1405 rShadow.SetWidth(nVal);
1406 rShadow.SetLocation(SVX_SHADOW_BOTTOMRIGHT);
1407 bRet = true;
1409 return bRet;
1412 void SwWW8ImplReader::GetBorderDistance(const WW8_BRC* pbrc,
1413 Rectangle& rInnerDist) const
1415 // 'dptSpace' is stored in 3 bits of 'Border Code (BRC)'
1416 if (bVer67)
1418 rInnerDist = Rectangle(((pbrc[ 1 ].aBits1[1] >> 3) & 0x1f) * 20,
1419 ((pbrc[ 0 ].aBits1[1] >> 3) & 0x1f) * 20,
1420 ((pbrc[ 3 ].aBits1[1] >> 3) & 0x1f) * 20,
1421 ((pbrc[ 2 ].aBits1[1] >> 3) & 0x1f) * 20 );
1423 else
1425 rInnerDist = Rectangle( (pbrc[ 1 ].aBits2[1] & 0x1f) * 20,
1426 (pbrc[ 0 ].aBits2[1] & 0x1f) * 20,
1427 (pbrc[ 3 ].aBits2[1] & 0x1f) * 20,
1428 (pbrc[ 2 ].aBits2[1] & 0x1f) * 20 );
1433 bool SwWW8ImplReader::SetFlyBordersShadow(SfxItemSet& rFlySet,
1434 const WW8_BRC *pbrc, short *pSizeArray) const
1436 bool bShadowed = false;
1437 if (IsBorder(pbrc))
1439 SvxBoxItem aBox( RES_BOX );
1440 SetBorder(aBox, pbrc, pSizeArray);
1442 rFlySet.Put( aBox );
1444 // fShadow
1445 SvxShadowItem aShadow( RES_SHADOW );
1446 if( SetShadow( aShadow, pSizeArray, pbrc ))
1448 bShadowed = true;
1449 rFlySet.Put( aShadow );
1452 return bShadowed;
1455 //-----------------------------------------
1456 // APOs
1457 //-----------------------------------------
1458 // fuer Berechnung der minimalen FrameSize
1459 #define MAX_BORDER_SIZE 210 // so breit ist max. der Border
1460 #define MAX_EMPTY_BORDER 10 // fuer +-1-Fehler, mindestens 1
1462 static void FlySecur1(short& rSize, const bool bBorder)
1464 short nMin = MINFLY +
1465 (bBorder ? MAX_BORDER_SIZE : MAX_EMPTY_BORDER);
1467 if ( rSize < nMin )
1468 rSize = nMin;
1471 inline bool SetValSprm( sal_Int16* pVar, WW8PLCFx_Cp_FKP* pPap, sal_uInt16 nId )
1473 const sal_uInt8* pS = pPap->HasSprm( nId );
1474 if( pS )
1475 *pVar = (sal_Int16)SVBT16ToShort( pS );
1476 return ( pS != 0 );
1479 inline bool SetValSprm( sal_Int16* pVar, const WW8RStyle* pStyle, sal_uInt16 nId )
1481 const sal_uInt8* pS = pStyle->HasParaSprm( nId );
1482 if( pS )
1483 *pVar = (sal_Int16)SVBT16ToShort( pS );
1484 return ( pS != 0 );
1488 #i1930 revealed that sprm 0x360D as used in tables can affect the frame
1489 around the table. Its full structure is not fully understood as yet.
1491 void WW8FlyPara::ApplyTabPos(const WW8_TablePos *pTabPos)
1493 if (pTabPos)
1495 nSp26 = pTabPos->nSp26;
1496 nSp27 = pTabPos->nSp27;
1497 nSp29 = pTabPos->nSp29;
1498 nLeMgn = pTabPos->nLeMgn;
1499 nRiMgn = pTabPos->nRiMgn;
1500 nUpMgn = pTabPos->nUpMgn;
1501 nLoMgn = pTabPos->nLoMgn;
1502 nSp37 = pTabPos->nSp37;
1506 WW8FlyPara::WW8FlyPara(bool bIsVer67, const WW8FlyPara* pSrc /* = 0 */)
1508 if ( pSrc )
1509 memcpy( this, pSrc, sizeof( WW8FlyPara ) ); // Copy-Ctor
1510 else
1512 memset( this, 0, sizeof( WW8FlyPara ) ); // Default-Ctor
1513 nSp37 = 2; // Default: Umfluss
1515 bVer67 = bIsVer67;
1518 bool WW8FlyPara::operator==(const WW8FlyPara& rSrc) const
1521 Compare the parts that word seems to compare for equivalence.
1522 Interestingly being autoheight or absolute height (the & 0x7fff) doesn't
1523 matter to word
1525 return
1527 (nSp26 == rSrc.nSp26) &&
1528 (nSp27 == rSrc.nSp27) &&
1529 ((nSp45 & 0x7fff) == (rSrc.nSp45 & 0x7fff)) &&
1530 (nSp28 == rSrc.nSp28) &&
1531 (nLeMgn == rSrc.nLeMgn) &&
1532 (nRiMgn == rSrc.nRiMgn) &&
1533 (nUpMgn == rSrc.nUpMgn) &&
1534 (nLoMgn == rSrc.nLoMgn) &&
1535 (nSp29 == rSrc.nSp29) &&
1536 (nSp37 == rSrc.nSp37)
1540 // Read fuer normalen Text
1541 void WW8FlyPara::Read(sal_uInt8 nOrigSp29, WW8PLCFx_Cp_FKP* pPap)
1543 const sal_uInt8* pS = 0;
1544 if( bVer67 )
1546 SetValSprm( &nSp26, pPap, 26 ); // X-Position //sprmPDxaAbs
1547 //set in me or in parent style
1548 mbVertSet |= SetValSprm( &nSp27, pPap, 27 ); // Y-Position //sprmPDyaAbs
1549 SetValSprm( &nSp45, pPap, 45 ); // Hoehe //sprmPWHeightAbs
1550 SetValSprm( &nSp28, pPap, 28 ); // Breite //sprmPDxaWidth
1551 SetValSprm( &nLeMgn, pPap, 49 ); // L-Raender //sprmPDxaFromText
1552 SetValSprm( &nRiMgn, pPap, 49 ); // R-Raender //sprmPDxaFromText
1553 SetValSprm( &nUpMgn, pPap, 48 ); // U-Raender //sprmPDyaFromText
1554 SetValSprm( &nLoMgn, pPap, 48 ); // D-Raender //sprmPDyaFromText
1556 pS = pPap->HasSprm( 37 ); //sprmPWr
1557 if( pS )
1558 nSp37 = *pS;
1560 else
1562 SetValSprm( &nSp26, pPap, NS_sprm::LN_PDxaAbs ); // X-Position
1563 //set in me or in parent style
1564 mbVertSet |= SetValSprm( &nSp27, pPap, NS_sprm::LN_PDyaAbs ); // Y-Position
1565 SetValSprm( &nSp45, pPap, NS_sprm::LN_PWHeightAbs ); // Hoehe
1566 SetValSprm( &nSp28, pPap, NS_sprm::LN_PDxaWidth ); // Breite
1567 SetValSprm( &nLeMgn, pPap, NS_sprm::LN_PDxaFromText ); // L-Raender
1568 SetValSprm( &nRiMgn, pPap, NS_sprm::LN_PDxaFromText ); // R-Raender
1569 SetValSprm( &nUpMgn, pPap, NS_sprm::LN_PDyaFromText ); // U-Raender
1570 SetValSprm( &nLoMgn, pPap, NS_sprm::LN_PDyaFromText ); // D-Raender
1572 pS = pPap->HasSprm( NS_sprm::LN_PWr ); // Umfluss
1573 if( pS )
1574 nSp37 = *pS;
1577 if( ::lcl_ReadBorders( bVer67, brc, pPap )) // Umrandung
1578 bBorderLines = ::lcl_IsBorder( bVer67, brc );
1581 #i8798#
1582 Appears that with no dyaAbs set then the actual vert anchoring set is
1583 ignored and we remain relative to text, so if that is the case we are 0
1584 from para anchor, so we update the frame to have explicitly this type of
1585 anchoring
1587 if (!mbVertSet)
1588 nSp29 = (nOrigSp29 & 0xCF) | 0x20;
1589 else
1590 nSp29 = nOrigSp29;
1593 void WW8FlyPara::ReadFull(sal_uInt8 nOrigSp29, SwWW8ImplReader* pIo)
1595 WW8PLCFMan* pPlcxMan = pIo->pPlcxMan;
1596 WW8PLCFx_Cp_FKP* pPap = pPlcxMan->GetPapPLCF();
1598 Read(nOrigSp29, pPap); // Lies Apo-Parameter
1600 do{ // Block zum rausspringen
1601 if( nSp45 != 0 /* || nSp28 != 0 */ )
1602 break; // bGrafApo nur bei Hoehe automatisch
1603 if( pIo->pWwFib->fComplex )
1604 break; // (*pPap)++ geht bei FastSave schief
1605 // -> bei FastSave kein Test auf Grafik-APO
1606 SvStream* pIoStrm = pIo->pStrm;
1607 sal_uLong nPos = pIoStrm->Tell();
1608 WW8PLCFxSave1 aSave;
1609 pPlcxMan->GetPap()->Save( aSave );
1610 bGrafApo = false;
1612 do{ // Block zum rausspringen
1613 sal_uInt8 nTxt[2];
1615 if (!checkRead(*pIoStrm, nTxt, 2)) // lies Text
1616 break;
1618 if( nTxt[0] != 0x01 || nTxt[1] != 0x0d )// nur Grafik + CR ?
1619 break; // Nein
1621 pPap->advance(); // Naechste Zeile
1623 // In APO ?
1624 //sprmPPc
1625 const sal_uInt8* pS = pPap->HasSprm( bVer67 ? 29 : 0x261B );
1627 // Nein -> Grafik-Apo
1628 if (!pS)
1630 bGrafApo = true;
1631 break; // Ende des APO
1634 ww::WordVersion eVer = pIo->GetFib().GetFIBVersion();
1635 WW8FlyPara *pNowStyleApo=0;
1636 sal_uInt16 nColl = pPap->GetIstd();
1637 ww::sti eSti = eVer < ww::eWW6 ? ww::GetCanonicalStiFromStc( static_cast< sal_uInt8 >(nColl) ) : static_cast<ww::sti>(nColl);
1638 while (eSti != ww::stiNil && nColl < pIo->vColl.size() && 0 == (pNowStyleApo = pIo->vColl[nColl].pWWFly))
1640 nColl = pIo->vColl[nColl].nBase;
1641 eSti = eVer < ww::eWW6 ? ww::GetCanonicalStiFromStc( static_cast< sal_uInt8 >(nColl) ) : static_cast<ww::sti>(nColl);
1644 WW8FlyPara aF(bVer67, pNowStyleApo);
1645 // Neuer FlaPara zum Vergleich
1646 aF.Read( *pS, pPap ); // WWPara fuer neuen Para
1647 if( !( aF == *this ) ) // selber APO ? ( oder neuer ? )
1648 bGrafApo = true; // nein -> 1-zeiliger APO
1649 // -> Grafik-APO
1651 while( 0 ); // Block zum rausspringen
1653 pPlcxMan->GetPap()->Restore( aSave );
1654 pIoStrm->Seek( nPos );
1655 }while( 0 ); // Block zum rausspringen
1659 // Read fuer Apo-Defs in Styledefs
1660 void WW8FlyPara::Read(sal_uInt8 nOrigSp29, WW8RStyle* pStyle)
1662 const sal_uInt8* pS = 0;
1663 if (bVer67)
1665 SetValSprm( &nSp26, pStyle, 26 ); // X-Position
1666 //set in me or in parent style
1667 mbVertSet |= SetValSprm(&nSp27, pStyle, 27); // Y-Position
1668 SetValSprm( &nSp45, pStyle, 45 ); // Hoehe
1669 SetValSprm( &nSp28, pStyle, 28 ); // Breite
1670 SetValSprm( &nLeMgn, pStyle, 49 ); // L-Raender
1671 SetValSprm( &nRiMgn, pStyle, 49 ); // R-Raender
1672 SetValSprm( &nUpMgn, pStyle, 48 ); // U-Raender
1673 SetValSprm( &nLoMgn, pStyle, 48 ); // D-Raender
1675 pS = pStyle->HasParaSprm( 37 ); // Umfluss
1676 if( pS )
1677 nSp37 = *pS;
1679 else
1681 SetValSprm( &nSp26, pStyle, 0x8418 ); // X-Position
1682 //set in me or in parent style
1683 mbVertSet |= SetValSprm(&nSp27, pStyle, 0x8419); // Y-Position
1684 SetValSprm( &nSp45, pStyle, 0x442B ); // Hoehe
1685 SetValSprm( &nSp28, pStyle, 0x841A ); // Breite
1686 SetValSprm( &nLeMgn, pStyle, 0x842F ); // L-Raender
1687 SetValSprm( &nRiMgn, pStyle, 0x842F ); // R-Raender
1688 SetValSprm( &nUpMgn, pStyle, 0x842E ); // U-Raender
1689 SetValSprm( &nLoMgn, pStyle, 0x842E ); // D-Raender
1691 pS = pStyle->HasParaSprm( 0x2423 ); // Umfluss
1692 if( pS )
1693 nSp37 = *pS;
1696 if (::lcl_ReadBorders(bVer67, brc, 0, pStyle)) // Umrandung
1697 bBorderLines = ::lcl_IsBorder(bVer67, brc);
1700 #i8798#
1701 Appears that with no dyaAbs set then the actual vert anchoring set is
1702 ignored and we remain relative to text, so if that is the case we are 0
1703 from para anchor, so we update the frame to have explicitly this type of
1704 anchoring
1706 if (!mbVertSet)
1707 nSp29 = (nOrigSp29 & 0xCF) | 0x20;
1708 else
1709 nSp29 = nOrigSp29;
1712 bool WW8FlyPara::IsEmpty() const
1714 WW8FlyPara aEmpty(bVer67);
1716 wr of 0 like 2 appears to me to be equivalent for checking here. See
1717 #107103# if wrong, so given that the empty is 2, if we are 0 then set
1718 empty to 0 to make 0 equiv to 2 for empty checking
1720 OSL_ENSURE(aEmpty.nSp37 == 2, "this is not what we expect for nSp37");
1721 if (this->nSp37 == 0)
1722 aEmpty.nSp37 = 0;
1723 if (aEmpty == *this)
1724 return true;
1725 return false;
1728 // #i18732# - changes made on behalf of CMC
1729 WW8SwFlyPara::WW8SwFlyPara( SwPaM& rPaM,
1730 SwWW8ImplReader& rIo,
1731 WW8FlyPara& rWW,
1732 const sal_uInt32 nWWPgTop,
1733 const sal_uInt32 nPgLeft,
1734 const sal_uInt32 nPgWidth,
1735 const sal_Int32 nIniFlyDx,
1736 const sal_Int32 nIniFlyDy )
1738 (void) rPaM;
1739 (void) nPgLeft;
1741 memset( this, 0, sizeof( WW8SwFlyPara ) ); // Initialisieren
1742 nNewNettoWidth = MINFLY; // Minimum
1744 eSurround = ( rWW.nSp37 > 1 ) ? SURROUND_IDEAL : SURROUND_NONE;
1745 //#i119466 mapping "Around" wrap setting to "Parallel" for table
1746 const bool bIsTable = rIo.pPlcxMan->HasParaSprm(0x2416);
1747 if ( bIsTable && rWW.nSp37 == 2 )
1748 eSurround = SURROUND_PARALLEL;
1751 #95905#, #83307# seems to have gone away now, so reenable parallel
1752 wrapping support for frames in headers/footers. I don't know if we truly
1753 have an explictly specified behaviour for these circumstances.
1756 nHeight = rWW.nSp45;
1757 if( nHeight & 0x8000 )
1759 nHeight &= 0x7fff;
1760 eHeightFix = ATT_MIN_SIZE;
1762 else
1763 eHeightFix = ATT_FIX_SIZE;
1765 if( nHeight <= MINFLY )
1766 { // keine Angabe oder Stuss
1767 eHeightFix = ATT_MIN_SIZE;
1768 nHeight = MINFLY;
1771 nWidth = nNettoWidth = rWW.nSp28;
1772 if( nWidth <= 10 ) // Auto-Breite
1774 bAutoWidth = true;
1775 nWidth = nNettoWidth =
1776 msword_cast<sal_Int16>((nPgWidth ? nPgWidth : 2268)); // 4 cm
1778 if( nWidth <= MINFLY )
1779 nWidth = nNettoWidth = MINFLY; // Minimale Breite
1781 eVAlign = text::VertOrientation::NONE; // Defaults
1782 eHAlign = text::HoriOrientation::NONE;
1783 nYPos = 0;
1784 nXPos = 0;
1786 nRiMgn = rWW.nRiMgn;
1787 nLeMgn = rWW.nLeMgn;
1788 nLoMgn = rWW.nLoMgn;
1789 nUpMgn = rWW.nUpMgn;
1792 See issue #i9178# for the 9 anchoring options, and make sure they stay
1793 working if you modify the anchoring logic here.
1796 // Wenn der Fly links, rechts, oben oder unten aligned ist,
1797 // wird der aeussere Textabstand ignoriert, da sonst
1798 // der Fly an falscher Position landen wuerde
1799 // Problematisch wird es nur bei Innen/Aussen
1801 // Bindung
1802 nYBind = (( rWW.nSp29 & 0x30 ) >> 4);
1803 //#i53725# - absolute positioned objects have to be
1804 // anchored at-paragraph to assure its correct anchor position.
1805 eAnchor = FLY_AT_PARA;
1807 switch (nYBind)
1809 case 0: //relative to margin
1810 eVRel = text::RelOrientation::PAGE_PRINT_AREA;
1811 break;
1812 case 1: //relative to page
1813 eVRel = text::RelOrientation::PAGE_FRAME;
1814 break;
1815 default: //relative to text
1816 eVRel = text::RelOrientation::FRAME;
1817 break;
1820 // #i18732#
1821 switch( rWW.nSp27 ) // besondere Y-Positionen ?
1823 case -4:
1824 eVAlign = text::VertOrientation::TOP;
1825 if (nYBind < 2)
1826 nUpMgn = 0;
1827 break; // oben
1828 case -8:
1829 eVAlign = text::VertOrientation::CENTER;
1830 break; // zentriert
1831 case -12:
1832 eVAlign = text::VertOrientation::BOTTOM;
1833 if (nYBind < 2)
1834 nLoMgn = 0;
1835 break; // unten
1836 default:
1837 nYPos = rWW.nSp27 + (short)nIniFlyDy;
1838 break; // Korrekturen per Ini-Datei
1841 switch( rWW.nSp26 ) // besondere X-Positionen ?
1843 case 0:
1844 eHAlign = text::HoriOrientation::LEFT;
1845 nLeMgn = 0;
1846 break; // links
1847 case -4:
1848 eHAlign = text::HoriOrientation::CENTER;
1849 break; // zentriert
1850 case -8:
1851 eHAlign = text::HoriOrientation::RIGHT;
1852 nRiMgn = 0;
1853 break; // rechts
1854 case -12:
1855 eHAlign = text::HoriOrientation::LEFT;
1856 bToggelPos = true;
1857 break; // innen
1858 case -16:
1859 eHAlign = text::HoriOrientation::RIGHT;
1860 bToggelPos = true;
1861 break; // aussen
1862 default:
1863 nXPos = rWW.nSp26 + (short)nIniFlyDx;
1864 break; // Korrekturen per Ini-Datei
1867 nXBind = ( rWW.nSp29 & 0xc0 ) >> 6;
1868 // #i18732#
1869 switch (nXBind) // X - Bindung -> Koordinatentransformation
1871 case 0: //relative to column
1872 eHRel = text::RelOrientation::FRAME;
1873 break;
1874 case 1: //relative to margin
1875 eHRel = text::RelOrientation::PAGE_PRINT_AREA;
1876 break;
1877 default: //relative to page
1878 eHRel = text::RelOrientation::PAGE_FRAME;
1879 break;
1882 // #i36649# - adjustments for certain horizontal alignments
1883 // Note: These special adjustments found by an investigation of documents
1884 // containing frames with different left/right border distances and
1885 // distances to text. The outcome is some how strange.
1886 // Note: These adjustments causes wrong horizontal positions for frames,
1887 // which are aligned inside|outside to page|margin on even pages,
1888 // the left and right border distances are different.
1889 // no adjustments possible, if frame has automatic width.
1890 // determine left border distance
1891 sal_Int16 nLeBorderMgn( 0L );
1892 if ( !bAutoWidth )
1894 sal_Int16 nTemp = rWW.brc[WW8_LEFT].DetermineBorderProperties(rWW.bVer67,
1895 &nLeBorderMgn);
1896 nLeBorderMgn = nLeBorderMgn + nTemp;
1898 // determine right border distance
1899 sal_Int16 nRiBorderMgn( 0L );
1900 if ( !bAutoWidth )
1902 sal_Int16 nTemp = rWW.brc[WW8_RIGHT].DetermineBorderProperties(rWW.bVer67,
1903 &nRiBorderMgn);
1904 nRiBorderMgn = nRiBorderMgn + nTemp;
1906 if ( !bAutoWidth && eHAlign == text::HoriOrientation::LEFT && eHRel == text::RelOrientation::PAGE_FRAME )
1908 // convert 'left to page' to
1909 // 'from left -<width>-<2*left border distance>-<right wrap distance>
1910 // to page text area'
1911 eHAlign = text::HoriOrientation::NONE;
1912 eHRel = text::RelOrientation::PAGE_PRINT_AREA;
1913 nXPos = -nWidth - (2*nLeBorderMgn) - rWW.nRiMgn;
1914 // re-set left wrap distance
1915 nLeMgn = rWW.nLeMgn;
1917 else if ( !bAutoWidth && eHAlign == text::HoriOrientation::RIGHT && eHRel == text::RelOrientation::PAGE_FRAME )
1919 // convert 'right to page' to
1920 // 'from left <right border distance-left border distance>+<left wrap distance>
1921 // to right page border'
1922 eHAlign = text::HoriOrientation::NONE;
1923 eHRel = text::RelOrientation::PAGE_RIGHT;
1924 nXPos = ( nRiBorderMgn - nLeBorderMgn ) + rWW.nLeMgn;
1925 // re-set right wrap distance
1926 nRiMgn = rWW.nRiMgn;
1928 else if ( !bAutoWidth && eHAlign == text::HoriOrientation::LEFT && eHRel == text::RelOrientation::PAGE_PRINT_AREA )
1930 // convert 'left to margin' to
1931 // 'from left -<left border distance> to page text area'
1932 eHAlign = text::HoriOrientation::NONE;
1933 eHRel = text::RelOrientation::PAGE_PRINT_AREA;
1934 nXPos = -nLeBorderMgn;
1935 // re-set left wrap distance
1936 nLeMgn = rWW.nLeMgn;
1938 else if ( !bAutoWidth && eHAlign == text::HoriOrientation::RIGHT && eHRel == text::RelOrientation::PAGE_PRINT_AREA )
1940 // convert 'right to margin' to
1941 // 'from left -<width>-<left border distance> to right page border'
1942 eHAlign = text::HoriOrientation::NONE;
1943 eHRel = text::RelOrientation::PAGE_RIGHT;
1944 nXPos = -nWidth - nLeBorderMgn;
1945 // re-set right wrap distance
1946 nRiMgn = rWW.nRiMgn;
1948 else if (rWW.bBorderLines)
1951 #i582#
1952 Word has a curious bug where the offset stored do not take into
1953 account the internal distance from the corner both
1955 sal_Int16 nLeLMgn = 0;
1956 sal_Int16 nTemp = rWW.brc[WW8_LEFT].DetermineBorderProperties(rWW.bVer67,
1957 &nLeLMgn);
1958 nLeLMgn = nLeLMgn + nTemp;
1960 if (nLeLMgn)
1962 if (eHAlign == text::HoriOrientation::LEFT)
1963 eHAlign = text::HoriOrientation::NONE;
1964 nXPos = nXPos - nLeLMgn;
1968 // adjustments for certain vertical alignments
1969 if ( eVAlign == text::VertOrientation::NONE && eVRel == text::RelOrientation::PAGE_PRINT_AREA )
1971 // convert "<X> from top page text area" to
1972 // "<X + page top margin> from page"
1973 eVRel = text::RelOrientation::PAGE_FRAME;
1974 nYPos = static_cast< sal_Int16 >( nYPos + nWWPgTop );
1977 FlySecur1( nWidth, rWW.bBorderLines ); // passen Raender ?
1978 FlySecur1( nHeight, rWW.bBorderLines );
1982 // hat ein Fly in WW eine automatische Breite, dann muss das durch
1983 // nachtraegliches Anpassen der ( im SW festen ) Fly-Breite simuliert werden.
1984 // Dabei kann die Fly-Breite groesser oder kleiner werden, da der Default-Wert
1985 // ohne Wissen ueber den Inhalt eingesetzt wird.
1986 void WW8SwFlyPara::BoxUpWidth( long nInWidth )
1988 if( bAutoWidth && nInWidth > nNewNettoWidth )
1989 nNewNettoWidth = nInWidth;
1992 // Die Klasse WW8FlySet ist von SfxItemSet abgeleitet und stellt auch
1993 // im Prizip nicht mehr zur Verfuegung, ist aber fuer mich besser
1994 // zu handeln
1995 // WW8FlySet-ctor fuer Apos und Graf-Apos
1996 WW8FlySet::WW8FlySet(SwWW8ImplReader& rReader, const WW8FlyPara* pFW,
1997 const WW8SwFlyPara* pFS, bool bGraf)
1998 : SfxItemSet(rReader.rDoc.GetAttrPool(),RES_FRMATR_BEGIN,RES_FRMATR_END-1)
2000 if (!rReader.mbNewDoc)
2001 Reader::ResetFrmFmtAttrs(*this); // Abstand/Umrandung raus
2002 // Position
2003 Put(SvxFrameDirectionItem(FRMDIR_HORI_LEFT_TOP, RES_FRAMEDIR));
2005 /*Below can all go when we have from left in rtl mode*/
2006 SwTwips nXPos = pFS->nXPos;
2007 sal_Int16 eHRel = pFS->eHRel;
2008 rReader.MiserableRTLGraphicsHack(nXPos, pFS->nWidth, pFS->eHAlign, eHRel);
2009 /*Above can all go when we have from left in rtl mode*/
2010 Put( SwFmtHoriOrient(nXPos, pFS->eHAlign, pFS->eHRel, pFS->bToggelPos ));
2011 Put( SwFmtVertOrient( pFS->nYPos, pFS->eVAlign, pFS->eVRel ) );
2013 if (pFS->nLeMgn || pFS->nRiMgn) // Raender setzen
2014 Put(SvxLRSpaceItem(pFS->nLeMgn, pFS->nRiMgn, 0, 0, RES_LR_SPACE));
2016 if (pFS->nUpMgn || pFS->nLoMgn)
2017 Put(SvxULSpaceItem(pFS->nUpMgn, pFS->nLoMgn, RES_UL_SPACE));
2019 //we no longer need to hack around the header/footer problems
2020 SwFmtSurround aSurround(pFS->eSurround);
2021 if ( pFS->eSurround == SURROUND_IDEAL )
2022 aSurround.SetAnchorOnly( sal_True );
2023 Put( aSurround );
2025 short aSizeArray[5]={0};
2026 rReader.SetFlyBordersShadow(*this,(const WW8_BRC*)pFW->brc,&aSizeArray[0]);
2028 // der 5. Parameter ist immer 0, daher geht beim Cast nix verloren
2030 // #i27767#
2031 // #i35017# - constant name has changed
2032 Put( SwFmtWrapInfluenceOnObjPos(
2033 text::WrapInfluenceOnPosition::ONCE_SUCCESSIVE ) );
2035 if( !bGraf )
2037 Put( SwFmtAnchor(pFS->eAnchor) );
2038 // Groesse einstellen
2040 //Ordinarily with frames, the border width and spacing is
2041 //placed outside the frame, making it larger. With these
2042 //types of frames, the left right thickness and space makes
2043 //it wider, but the top bottom spacing and border thickness
2044 //is placed inside.
2045 Put( SwFmtFrmSize( pFS->eHeightFix, pFS->nWidth +
2046 aSizeArray[WW8_LEFT] + aSizeArray[WW8_RIGHT],
2047 pFS->nHeight));
2051 // WW8FlySet-ctor fuer zeichengebundene Grafiken
2052 WW8FlySet::WW8FlySet( SwWW8ImplReader& rReader, const SwPaM* pPaM,
2053 const WW8_PIC& rPic, long nWidth, long nHeight )
2054 : SfxItemSet(rReader.rDoc.GetAttrPool(),RES_FRMATR_BEGIN,RES_FRMATR_END-1)
2056 Init(rReader, pPaM);
2058 Put(SvxFrameDirectionItem(FRMDIR_HORI_LEFT_TOP, RES_FRAMEDIR));
2060 short aSizeArray[5]={0};
2062 If we have set borders then in word the graphic is displaced from the left
2063 and top the width of the borders of those sides, and then the shadow
2064 itself is drawn to the bottom and right of the displaced graphic. In word
2065 the total size is that of the graphic plus the borders, plus the total
2066 shadow around all edges, for this translation the top and left shadow
2067 region is translated spacing around the graphic to those sides, and the
2068 bottom and right shadow size is added to the graphic size.
2070 if (rReader.SetFlyBordersShadow( *this, rPic.rgbrc, &aSizeArray[0]))
2072 Put(SvxLRSpaceItem( aSizeArray[WW8_LEFT], 0, 0, 0, RES_LR_SPACE ) );
2073 Put(SvxULSpaceItem( aSizeArray[WW8_TOP], 0, RES_UL_SPACE ));
2074 aSizeArray[WW8_RIGHT]*=2;
2075 aSizeArray[WW8_BOT]*=2;
2078 Put( SwFmtFrmSize( ATT_FIX_SIZE, nWidth+aSizeArray[WW8_LEFT]+
2079 aSizeArray[WW8_RIGHT], nHeight+aSizeArray[WW8_TOP]
2080 + aSizeArray[WW8_BOT]) );
2083 void WW8FlySet::Init(const SwWW8ImplReader& rReader, const SwPaM* pPaM)
2085 if (!rReader.mbNewDoc)
2086 Reader::ResetFrmFmtAttrs(*this); // Abstand/Umrandung raus
2088 Put(SvxLRSpaceItem(RES_LR_SPACE)); //inline writer ole2 objects start with 0.2cm l/r
2089 SwFmtAnchor aAnchor(FLY_AS_CHAR);
2091 aAnchor.SetAnchor(pPaM->GetPoint());
2092 Put(aAnchor);
2094 //The horizontal default is on the baseline, the vertical is centered
2095 //around the character center it appears
2096 if (rReader.maSectionManager.CurrentSectionIsVertical())
2097 Put(SwFmtVertOrient(0, text::VertOrientation::CHAR_CENTER,text::RelOrientation::CHAR));
2098 else
2099 Put(SwFmtVertOrient(0, text::VertOrientation::TOP, text::RelOrientation::FRAME));
2102 WW8DupProperties::WW8DupProperties(SwDoc &rDoc, SwWW8FltControlStack *pStk)
2103 : pCtrlStck(pStk),
2104 aChrSet(rDoc.GetAttrPool(), RES_CHRATR_BEGIN, RES_CHRATR_END - 1 ),
2105 aParSet(rDoc.GetAttrPool(), RES_PARATR_BEGIN, RES_PARATR_END - 1 )
2107 //Close any open character properties and duplicate them inside the
2108 //first table cell
2109 size_t nCnt = pCtrlStck->size();
2110 for (size_t i=0; i < nCnt; ++i)
2112 const SwFltStackEntry& rEntry = (*pCtrlStck)[ i ];
2113 if (rEntry.bOpen)
2115 if (isCHRATR(rEntry.pAttr->Which()))
2117 aChrSet.Put( *rEntry.pAttr );
2120 else if (isPARATR(rEntry.pAttr->Which()))
2122 aParSet.Put( *rEntry.pAttr );
2128 void WW8DupProperties::Insert(const SwPosition &rPos)
2130 const SfxItemSet *pSet=&aChrSet;
2131 for(int i=0;i<2;i++)
2133 if (i==1)
2134 pSet = &aParSet;
2136 if( pSet->Count() )
2138 SfxItemIter aIter( *pSet );
2139 const SfxPoolItem* pItem = aIter.GetCurItem();
2142 pCtrlStck->NewAttr(rPos, *pItem);
2143 }while( !aIter.IsAtEnd() && 0 != ( pItem = aIter.NextItem() ) );
2148 void SwWW8ImplReader::MoveInsideFly(const SwFrmFmt *pFlyFmt)
2150 WW8DupProperties aDup(rDoc,pCtrlStck);
2152 pCtrlStck->SetAttr(*pPaM->GetPoint(), 0, false);
2154 // Setze Pam in den FlyFrame
2155 const SwFmtCntnt& rCntnt = pFlyFmt->GetCntnt();
2156 OSL_ENSURE( rCntnt.GetCntntIdx(), "Kein Inhalt vorbereitet." );
2157 pPaM->GetPoint()->nNode = rCntnt.GetCntntIdx()->GetIndex() + 1;
2158 pPaM->GetPoint()->nContent.Assign( pPaM->GetCntntNode(), 0 );
2160 aDup.Insert(*pPaM->GetPoint());
2163 SwTwips SwWW8ImplReader::MoveOutsideFly(SwFrmFmt *pFlyFmt,
2164 const SwPosition &rPos, bool bTableJoin)
2166 SwTwips nRetWidth = 0;
2167 if (!pFlyFmt)
2168 return nRetWidth;
2169 // Alle Attribute schliessen, da sonst Attribute entstehen koennen,
2170 // die aus Flys rausragen
2171 WW8DupProperties aDup(rDoc,pCtrlStck);
2172 pCtrlStck->SetAttr(*pPaM->GetPoint(), 0, false);
2175 #i1291
2176 If this fly frame consists entirely of one table inside a frame
2177 followed by an empty paragraph then we want to delete the empty
2178 paragraph so as to get the frame to autoshrink to the size of the
2179 table to emulate words behaviour closer.
2181 if (bTableJoin)
2183 const SwNodeIndex* pNodeIndex = pFlyFmt->GetCntnt().
2184 GetCntntIdx();
2185 if (pNodeIndex)
2187 SwNodeIndex aIdx( *pNodeIndex, 1 ),
2188 aEnd( *pNodeIndex->GetNode().EndOfSectionNode() );
2190 if (aIdx < aEnd)
2192 if(aIdx.GetNode().IsTableNode())
2194 SwTableNode *pTable = aIdx.GetNode().GetTableNode();
2195 aIdx = *aIdx.GetNode().EndOfSectionNode();
2196 ++aIdx;
2197 if ( (aIdx < aEnd) && aIdx.GetNode().IsTxtNode() )
2199 SwTxtNode *pNd = aIdx.GetNode().GetTxtNode();
2200 ++aIdx;
2201 if (aIdx == aEnd && pNd && pNd->GetTxt().isEmpty())
2203 //An extra pre-created by writer unused paragraph
2205 //delete after import is complete rather than now
2206 //to avoid the complication of managing uncommitted
2207 //ctrlstack properties that refer to it.
2208 m_aExtraneousParas.push_back(pNd);
2210 SwTable& rTable = pTable->GetTable();
2211 SwFrmFmt* pTblFmt = rTable.GetFrmFmt();
2213 if (pTblFmt)
2215 SwFmtFrmSize aSize = pTblFmt->GetFrmSize();
2216 aSize.SetHeightSizeType(ATT_MIN_SIZE);
2217 aSize.SetHeight(MINLAY);
2218 pFlyFmt->SetFmtAttr(aSize);
2219 SwFmtHoriOrient aHori = pTblFmt->GetHoriOrient();
2220 // passing the table orientaion of
2221 // LEFT_AND_WIDTH to the frame seems to
2222 // work better than FULL, especially if the
2223 // table width exceeds the page width, however
2224 // I am not brave enough to set it in all
2225 // instances
2226 pTblFmt->SetFmtAttr( SwFmtHoriOrient(0, ( aHori.GetHoriOrient() == text::HoriOrientation::LEFT_AND_WIDTH ) ? ::text::HoriOrientation::LEFT_AND_WIDTH : text::HoriOrientation::FULL ) );
2227 nRetWidth = aSize.GetWidth();
2236 *pPaM->GetPoint() = rPos;
2237 aDup.Insert(*pPaM->GetPoint());
2238 return nRetWidth;
2241 WW8FlyPara *SwWW8ImplReader::ConstructApo(const ApoTestResults &rApo,
2242 const WW8_TablePos *pTabPos)
2244 WW8FlyPara *pRet = 0;
2245 OSL_ENSURE(rApo.HasFrame() || pTabPos,
2246 "If no frame found, *MUST* be in a table");
2248 pRet = new WW8FlyPara(bVer67, rApo.mpStyleApo);
2250 // APO-Parameter ermitteln und Test auf bGrafApo
2251 if (rApo.HasFrame())
2252 pRet->ReadFull(rApo.m_nSprm29, this);
2254 pRet->ApplyTabPos(pTabPos);
2256 if (pRet->IsEmpty())
2257 delete pRet, pRet = 0;
2258 return pRet;
2261 bool SwWW8ImplReader::IsDropCap()
2263 // Find the DCS (Drop Cap Specifier) for the paragraph
2264 // if does not exist or if the first three bits are 0
2265 // then there is no dropcap on the paragraph
2266 WW8PLCFx_Cp_FKP *pPap = pPlcxMan ? pPlcxMan->GetPapPLCF() : 0;
2267 if (pPap)
2269 const sal_uInt8 *pDCS;
2270 if (bVer67)
2271 pDCS = pPap->HasSprm(46);
2272 else
2273 pDCS = pPlcxMan->GetPapPLCF()->HasSprm(0x442C);
2274 if(pDCS)
2276 short nDCS = SVBT16ToShort( pDCS );
2277 if((nDCS | 7) != 0)
2278 return true;
2281 return false;
2284 bool SwWW8ImplReader::StartApo(const ApoTestResults &rApo,
2285 const WW8_TablePos *pTabPos)
2287 if (0 == (pWFlyPara = ConstructApo(rApo, pTabPos)))
2288 return false;
2290 // <WW8SwFlyPara> constructor has changed - new 4th parameter
2291 // containing WW8 page top margin.
2292 pSFlyPara = new WW8SwFlyPara( *pPaM, *this, *pWFlyPara,
2293 maSectionManager.GetWWPageTopMargin(),
2294 maSectionManager.GetPageLeft(),
2295 maSectionManager.GetTextAreaWidth(),
2296 nIniFlyDx, nIniFlyDy);
2298 // If this paragraph is a Dropcap set the flag and we will deal with it later
2299 if (IsDropCap())
2301 bDropCap = true;
2302 pAktItemSet = new SfxItemSet( rDoc.GetAttrPool(), RES_CHRATR_BEGIN, RES_PARATR_END - 1 );
2303 return false;
2306 if( !pWFlyPara->bGrafApo )
2309 // Innerhalb des GrafApo muessen Textattribute ignoriert werden, da
2310 // sie sonst auf den folgenden Zeilen landen. Der Rahmen wird nur
2311 // eingefuegt, wenn er *nicht* nur zum Positionieren einer einzelnen
2312 // Grafik dient. Ist es ein Grafik-Rahmen, dann werden pWFlyPara und
2313 // pSFlyPara behalten und die
2314 // daraus resultierenden Attribute beim Einfuegen der Grafik auf die
2315 // Grafik angewendet.
2317 WW8FlySet aFlySet(*this, pWFlyPara, pSFlyPara, false);
2319 if (pTabPos && pTabPos->bNoFly)
2320 pSFlyPara->pFlyFmt = 0;
2321 else
2323 pSFlyPara->pFlyFmt = rDoc.MakeFlySection( pSFlyPara->eAnchor,
2324 pPaM->GetPoint(), &aFlySet );
2325 OSL_ENSURE(pSFlyPara->pFlyFmt->GetAnchor().GetAnchorId() ==
2326 pSFlyPara->eAnchor, "Not the anchor type requested!");
2329 if (pSFlyPara->pFlyFmt)
2331 if (!pDrawModel)
2332 GrafikCtor();
2334 SdrObject* pOurNewObject = CreateContactObject(pSFlyPara->pFlyFmt);
2335 pWWZOrder->InsertTextLayerObject(pOurNewObject);
2338 if (FLY_AS_CHAR != pSFlyPara->eAnchor && pSFlyPara->pFlyFmt)
2340 pAnchorStck->AddAnchor(*pPaM->GetPoint(),pSFlyPara->pFlyFmt);
2343 // merke Pos im Haupttext
2344 pSFlyPara->pMainTextPos = new SwPosition( *pPaM->GetPoint() );
2346 //remove fltanchors, otherwise they will be closed inside the
2347 //frame, which makes no sense, restore them after the frame is
2348 //closed
2349 pSFlyPara->pOldAnchorStck = pAnchorStck;
2350 pAnchorStck = new SwWW8FltAnchorStack(&rDoc, nFieldFlags);
2352 if (pSFlyPara->pFlyFmt)
2353 MoveInsideFly(pSFlyPara->pFlyFmt);
2355 // 1) ReadText() wird nicht wie beim W4W-Reader rekursiv aufgerufen,
2356 // da die Laenge des Apo zu diesen Zeitpunkt noch nicht feststeht,
2357 // ReadText() diese Angabe aber braucht.
2358 // 2) Der CtrlStck wird nicht neu erzeugt.
2359 // die Char-Attribute laufen weiter ( AErger mit SW-Attributen )
2360 // Paraattribute muessten am Ende jeden Absatzes zurueckgesetzt
2361 // sein, d.h. es duerften am Absatzende keine Paraattribute
2362 // auf dem Stack liegen
2364 return true;
2367 void wwSectionManager::JoinNode(const SwPosition &rPos, const SwNode &rNode)
2369 if ((!maSegments.empty()) && (maSegments.back().maStart == rPos.nNode))
2370 maSegments.back().maStart = SwNodeIndex(rNode);
2373 bool SwWW8ImplReader::JoinNode(SwPaM &rPam, bool bStealAttr)
2375 bool bRet = false;
2376 rPam.GetPoint()->nContent = 0; // an den Anfang der Zeile gehen
2378 SwNodeIndex aPref(rPam.GetPoint()->nNode, -1);
2380 if (SwTxtNode* pNode = aPref.GetNode().GetTxtNode())
2382 maSectionManager.JoinNode(*rPam.GetPoint(), aPref.GetNode());
2383 rPam.GetPoint()->nNode = aPref;
2384 rPam.GetPoint()->nContent.Assign(pNode, pNode->GetTxt().getLength());
2385 if (bStealAttr)
2386 pCtrlStck->StealAttr(rPam.GetPoint()->nNode);
2388 pNode->JoinNext();
2390 bRet = true;
2392 return bRet;
2395 void SwWW8ImplReader::StopApo()
2397 OSL_ENSURE(pWFlyPara, "no pWFlyPara to close");
2398 if (!pWFlyPara)
2399 return;
2400 if (pWFlyPara->bGrafApo)
2402 // Grafik-Rahmen, der *nicht* eingefuegt wurde leeren Absatz incl.
2403 // Attributen entfernen
2404 JoinNode(*pPaM, true);
2407 else
2409 if (!pSFlyPara->pMainTextPos || !pWFlyPara)
2411 OSL_ENSURE( pSFlyPara->pMainTextPos, "StopApo: pMainTextPos ist 0" );
2412 OSL_ENSURE( pWFlyPara, "StopApo: pWFlyPara ist 0" );
2413 return;
2417 What we are doing with this temporary nodeindex is as follows: The
2418 stack of attributes normally only places them into the document when
2419 the current insertion point has passed them by. Otherwise the end
2420 point of the attribute gets pushed along with the insertion point. The
2421 insertion point is moved and the properties commited during
2422 MoveOutsideFly. We also may want to remove the final paragraph in the
2423 frame, but we need to wait until the properties for that frame text
2424 have been commited otherwise they will be lost. So we first get a
2425 handle to the last the filter inserted. After the attributes are
2426 commited, if that paragraph exists we join it with the para after it
2427 that comes with the frame by default so that as normal we don't end up
2428 with one more paragraph than we wanted.
2430 SwNodeIndex aPref(pPaM->GetPoint()->nNode, -1);
2432 SwTwips nNewWidth =
2433 MoveOutsideFly(pSFlyPara->pFlyFmt, *pSFlyPara->pMainTextPos);
2434 if (nNewWidth)
2435 pSFlyPara->BoxUpWidth(nNewWidth);
2437 Color aBg(0xFE, 0xFF, 0xFF, 0xFF); //Transparent by default
2439 if (SwTxtNode* pNd = aPref.GetNode().GetTxtNode())
2442 #i582#
2443 Take the last paragraph background colour and fill the frame with
2444 it. Otherwise, make it transparent, this appears to be how MSWord
2445 works
2447 const SfxPoolItem &rItm = pNd->SwCntntNode::GetAttr(RES_BACKGROUND);
2448 const SvxBrushItem &rBrush = (const SvxBrushItem&)(rItm);
2449 if (rBrush.GetColor().GetColor() != COL_AUTO)
2450 aBg = rBrush.GetColor();
2452 //Get rid of extra empty paragraph
2453 pNd->JoinNext();
2456 if (pSFlyPara->pFlyFmt)
2457 pSFlyPara->pFlyFmt->SetFmtAttr(SvxBrushItem(aBg, RES_BACKGROUND));
2459 DeleteAnchorStk();
2460 pAnchorStck = pSFlyPara->pOldAnchorStck;
2462 // Ist die Fly-Breite durch eine innenliegende Grafik vergroessert
2463 // worden ( bei automatischer Breite des Flys ), dann muss die Breite
2464 // des SW-Flys entsprechend umgesetzt werden, da der SW keine
2465 // automatische Breite kennt.
2466 if( pSFlyPara->nNewNettoWidth > MINFLY ) // BoxUpWidth ?
2468 long nW = pSFlyPara->nNewNettoWidth;
2469 nW += pSFlyPara->nWidth - pSFlyPara->nNettoWidth; // Rand dazu
2470 pSFlyPara->pFlyFmt->SetFmtAttr(
2471 SwFmtFrmSize( pSFlyPara->eHeightFix, nW, pSFlyPara->nHeight ) );
2474 Word set *no* width meaning its an automatic width. The
2475 SwFlyPara reader will have already set a fallback width of the
2476 printable regions width, so we should reuse it. Despite the related
2477 problems with layout addressed with a hack in WW8FlyPara's constructor
2478 #i27204# Added AutoWidth setting. Left the old CalculateFlySize in place
2479 so that if the user unselects autowidth, the width doesn't max out
2481 else if( !pWFlyPara->nSp28 && pSFlyPara->pFlyFmt)
2483 using namespace sw::util;
2484 SfxItemSet aFlySet( pSFlyPara->pFlyFmt->GetAttrSet() );
2486 SwFmtFrmSize aSize(ItemGet<SwFmtFrmSize>(aFlySet, RES_FRM_SIZE));
2488 aFlySet.ClearItem(RES_FRM_SIZE);
2490 CalculateFlySize(aFlySet, pSFlyPara->pMainTextPos->nNode,
2491 pSFlyPara->nWidth);
2493 nNewWidth = ItemGet<SwFmtFrmSize>(aFlySet, RES_FRM_SIZE).GetWidth();
2495 aSize.SetWidth(nNewWidth);
2496 aSize.SetWidthSizeType(ATT_VAR_SIZE);
2498 pSFlyPara->pFlyFmt->SetFmtAttr(aSize);
2501 delete pSFlyPara->pMainTextPos, pSFlyPara->pMainTextPos = 0;
2503 // Damit die Frames bei Einfuegen in existierendes Doc erzeugt werden,
2504 // wird in fltshell.cxx beim Setzen des FltAnchor-Attributes
2505 // pFlyFrm->MakeFrms() gerufen
2509 //#i8062#
2510 if (pSFlyPara && pSFlyPara->pFlyFmt)
2511 pFmtOfJustInsertedApo = pSFlyPara->pFlyFmt;
2513 DELETEZ( pSFlyPara );
2514 DELETEZ( pWFlyPara );
2517 // TestSameApo() beantwortet die Frage, ob es dasselbe APO oder ein neues ist
2518 bool SwWW8ImplReader::TestSameApo(const ApoTestResults &rApo,
2519 const WW8_TablePos *pTabPos)
2521 if( !pWFlyPara )
2523 OSL_ENSURE( pWFlyPara, " Wo ist mein pWFlyPara ? " );
2524 return true;
2527 // Es muss ein kompletter Vergleich ( ausser Borders ) stattfinden, um
2528 // alle Kombinationen Style / Hart richtig einzuordnen. Deshalb wird ein
2529 // temporaerer WW8FlyPara angelegt ( abh. ob Style oder nicht ), darauf
2530 // die harten Attrs angewendet, und dann verglichen
2532 // Zum Vergleich
2533 WW8FlyPara aF(bVer67, rApo.mpStyleApo);
2534 // WWPara fuer akt. Para
2535 if (rApo.HasFrame())
2536 aF.Read(rApo.m_nSprm29, pPlcxMan->GetPapPLCF());
2537 aF.ApplyTabPos(pTabPos);
2539 return aF == *pWFlyPara;
2542 /***************************************************************************
2543 # Attribut - Verwaltung
2544 #**************************************************************************/
2546 void SwWW8ImplReader::NewAttr( const SfxPoolItem& rAttr,
2547 const bool bFirstLineOfStSet,
2548 const bool bLeftIndentSet )
2550 if( !bNoAttrImport ) // zum Ignorieren von Styles beim Doc-Einfuegen
2552 if (pAktColl)
2554 OSL_ENSURE(rAttr.Which() != RES_FLTR_REDLINE, "redline in style!");
2555 pAktColl->SetFmtAttr(rAttr);
2557 else if (pAktItemSet)
2559 pAktItemSet->Put(rAttr);
2561 else if (rAttr.Which() == RES_FLTR_REDLINE)
2563 mpRedlineStack->open(*pPaM->GetPoint(), rAttr);
2565 else
2567 pCtrlStck->NewAttr(*pPaM->GetPoint(), rAttr);
2568 // #i103711#
2569 if ( bFirstLineOfStSet )
2571 const SwNode* pNd = &(pPaM->GetPoint()->nNode.GetNode());
2572 maTxtNodesHavingFirstLineOfstSet.insert( pNd );
2574 // #i105414#
2575 if ( bLeftIndentSet )
2577 const SwNode* pNd = &(pPaM->GetPoint()->nNode.GetNode());
2578 maTxtNodesHavingLeftIndentSet.insert( pNd );
2582 if (mpPostProcessAttrsInfo && mpPostProcessAttrsInfo->mbCopy)
2583 mpPostProcessAttrsInfo->mItemSet.Put(rAttr);
2587 // holt Attribut aus der FmtColl / Stack / Doc
2588 const SfxPoolItem* SwWW8ImplReader::GetFmtAttr( sal_uInt16 nWhich )
2590 const SfxPoolItem* pRet = 0;
2591 if (pAktColl)
2592 pRet = &(pAktColl->GetFmtAttr(nWhich));
2593 else if (pAktItemSet)
2595 pRet = pAktItemSet->GetItem(nWhich);
2596 if (!pRet)
2597 pRet = pStandardFmtColl ? &(pStandardFmtColl->GetFmtAttr(nWhich)) : 0;
2598 if (!pRet)
2599 pRet = &rDoc.GetAttrPool().GetDefaultItem(nWhich);
2601 else if (pPlcxMan && pPlcxMan->GetDoingDrawTextBox())
2603 pRet = pCtrlStck->GetStackAttr(*pPaM->GetPoint(), nWhich);
2604 if (!pRet)
2606 if (nAktColl < vColl.size() && vColl[nAktColl].pFmt &&
2607 vColl[nAktColl].bColl)
2609 pRet = &(vColl[nAktColl].pFmt->GetFmtAttr(nWhich));
2612 if (!pRet)
2613 pRet = pStandardFmtColl ? &(pStandardFmtColl->GetFmtAttr(nWhich)) : 0;
2614 if (!pRet)
2615 pRet = &rDoc.GetAttrPool().GetDefaultItem(nWhich);
2617 else
2618 pRet = pCtrlStck->GetFmtAttr(*pPaM->GetPoint(), nWhich);
2619 return pRet;
2622 /***************************************************************************
2623 # eigentliche Attribute
2625 # Die Methoden erhalten die Token-Id und die Laenge der noch folgenden
2626 # Parameter gemaess Tabelle in WWScan.cxx als Parameter
2627 #**************************************************************************/
2629 /***************************************************************************
2630 # Spezial WW - Attribute
2631 #**************************************************************************/
2633 void SwWW8ImplReader::Read_Special(sal_uInt16, const sal_uInt8* pData, short nLen)
2635 if( nLen < 0 )
2637 bSpec = false;
2638 return;
2640 bSpec = ( *pData != 0 );
2643 // Read_Obj wird fuer fObj und fuer fOle2 benutzt !
2644 void SwWW8ImplReader::Read_Obj(sal_uInt16 , const sal_uInt8* pData, short nLen)
2646 if( nLen < 0 )
2647 bObj = false;
2648 else
2650 bObj = 0 != *pData;
2652 if( bObj && nPicLocFc && bEmbeddObj )
2654 if (!maFieldStack.empty() && maFieldStack.back().mnFieldId == 56)
2656 // For LINK fields, store the nObjLocFc value in the field entry
2657 maFieldStack.back().mnObjLocFc = nPicLocFc;
2659 else
2661 nObjLocFc = nPicLocFc;
2667 void SwWW8ImplReader::Read_PicLoc(sal_uInt16 , const sal_uInt8* pData, short nLen )
2669 if( nLen < 0 )
2671 nPicLocFc = 0;
2672 bSpec = false; // Stimmt das immer ?
2674 else
2676 nPicLocFc = SVBT32ToUInt32( pData );
2677 bSpec = true;
2679 if( bObj && nPicLocFc && bEmbeddObj )
2680 nObjLocFc = nPicLocFc;
2684 void SwWW8ImplReader::Read_POutLvl(sal_uInt16, const sal_uInt8* pData, short nLen )
2686 if (pAktColl && (0 < nLen))
2688 if (SwWW8StyInf* pSI = GetStyle(nAktColl))
2690 pSI->nOutlineLevel = static_cast< sal_uInt8 >(
2691 ( (1 <= pSI->GetWWStyleId()) && (9 >= pSI->GetWWStyleId()) )
2692 ? pSI->GetWWStyleId()-1
2693 : (pData ? *pData : 0) );
2698 void SwWW8ImplReader::Read_Symbol(sal_uInt16, const sal_uInt8* pData, short nLen )
2700 if( !bIgnoreText )
2702 if( nLen < 0 )
2704 //otherwise disable after we print the char
2705 if (pPlcxMan && pPlcxMan->GetDoingDrawTextBox())
2706 pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_CHRATR_FONT );
2707 bSymbol = false;
2709 else
2711 // Make new Font-Atribut
2712 // (will be closed in SwWW8ImplReader::ReadChars() )
2714 //Will not be added to the charencoding stack, for styles the real
2715 //font setting will be put in as the styles charset, and for plain
2716 //text encoding for symbols is moot. Drawing boxes will check bSymbol
2717 //themselves so they don't need to add it to the stack either.
2718 if (SetNewFontAttr(SVBT16ToShort( pData ), false, RES_CHRATR_FONT))
2720 if( bVer67 )
2722 //convert single byte from MS1252 to Unicode
2723 cSymbol = OUString(
2724 reinterpret_cast<const sal_Char*>(pData+2), 1,
2725 RTL_TEXTENCODING_MS_1252).toChar();
2727 else
2729 //already is Unicode
2730 cSymbol = SVBT16ToShort( pData+2 );
2732 bSymbol = true;
2738 SwWW8StyInf *SwWW8ImplReader::GetStyle(sal_uInt16 nColl) const
2740 return const_cast<SwWW8StyInf *>(nColl < vColl.size() ? &vColl[nColl] : 0);
2743 /***************************************************************************
2744 # Zeichen - Attribute
2745 #**************************************************************************/
2747 // Read_BoldUsw fuer Italic, Bold, Kapitaelchen, Versalien, durchgestrichen,
2748 // Contour und Shadow
2749 void SwWW8ImplReader::Read_BoldUsw( sal_uInt16 nId, const sal_uInt8* pData, short nLen )
2751 const int nContigiousWestern = 8;
2752 const int nWestern = nContigiousWestern + 1;
2753 const int nEastern = 2;
2754 const int nCTL = 2;
2755 const int nIds = nWestern + nEastern + nCTL;
2756 static const sal_uInt16 nEndIds[ nIds ] =
2758 RES_CHRATR_WEIGHT, RES_CHRATR_POSTURE,
2759 RES_CHRATR_CROSSEDOUT, RES_CHRATR_CONTOUR,
2760 RES_CHRATR_SHADOWED, RES_CHRATR_CASEMAP,
2761 RES_CHRATR_CASEMAP, RES_CHRATR_HIDDEN,
2763 RES_CHRATR_CROSSEDOUT,
2765 RES_CHRATR_CJK_WEIGHT, RES_CHRATR_CJK_POSTURE,
2767 RES_CHRATR_CTL_WEIGHT, RES_CHRATR_CTL_POSTURE
2770 ww::WordVersion eVersion = pWwFib->GetFIBVersion();
2772 sal_uInt8 nI;
2773 // die Attribut-Nr fuer "doppelt durchgestrichen" tanzt aus der Reihe
2774 if (0x2A53 == nId)
2775 nI = nContigiousWestern; // The out of sequence western id
2776 else
2778 // The contigious western ids
2779 if (eVersion <= ww::eWW2)
2780 nI = static_cast< sal_uInt8 >(nId - 60);
2781 else if (eVersion < ww::eWW8)
2782 nI = static_cast< sal_uInt8 >(nId - 85);
2783 else
2784 nI = static_cast< sal_uInt8 >(nId - 0x0835);
2787 sal_uInt16 nMask = 1 << nI;
2789 if (nLen < 0)
2791 if (nI < 2)
2793 if (eVersion <= ww::eWW6)
2795 // reset the CTL Weight and Posture, because they are the same as their
2796 // western equivalents in ww6
2797 pCtrlStck->SetAttr( *pPaM->GetPoint(), nEndIds[ nWestern + nEastern + nI ] );
2799 // reset the CJK Weight and Posture, because they are the same as their
2800 // western equivalents in word
2801 pCtrlStck->SetAttr( *pPaM->GetPoint(), nEndIds[ nWestern + nI ] );
2803 pCtrlStck->SetAttr( *pPaM->GetPoint(), nEndIds[ nI ] );
2804 pCtrlStck->SetToggleAttr(nI, false);
2805 return;
2807 // Wert: 0 = Aus, 1 = An, 128 = Wie Style, 129 entgegen Style
2808 bool bOn = *pData & 1;
2809 SwWW8StyInf* pSI = GetStyle(nAktColl);
2810 if (pPlcxMan && eVersion > ww::eWW2)
2812 const sal_uInt8 *pCharIstd =
2813 pPlcxMan->GetChpPLCF()->HasSprm(bVer67 ? 80 : 0x4A30);
2814 if (pCharIstd)
2815 pSI = GetStyle(SVBT16ToShort(pCharIstd));
2818 if( pAktColl ) // StyleDef -> Flags merken
2820 if (pSI)
2822 // The style based on has Bit 7 set ?
2823 if (
2824 pSI->nBase < vColl.size() && (*pData & 0x80) &&
2825 (vColl[pSI->nBase].n81Flags & nMask)
2828 bOn = !bOn; // umdrehen
2831 if (bOn)
2832 pSI->n81Flags |= nMask; // Flag setzen
2833 else
2834 pSI->n81Flags &= ~nMask; // Flag loeschen
2837 else
2840 // im Text -> Flags abfragen
2841 if( *pData & 0x80 ) // Bit 7 gesetzt ?
2843 if (pSI && pSI->n81Flags & nMask) // und in StyleDef an ?
2844 bOn = !bOn; // dann invertieren
2845 // am Stack vermerken, das dieses ein Toggle-Attribut ist
2846 pCtrlStck->SetToggleAttr(nI, true);
2850 SetToggleAttr( nI, bOn );
2853 void SwWW8ImplReader::Read_Bidi(sal_uInt16, const sal_uInt8*, short nLen)
2855 if (nLen > 0)
2856 bBidi = true;
2857 else
2858 bBidi = false;
2861 // Read_BoldUsw for BiDi Italic, Bold
2862 void SwWW8ImplReader::Read_BoldBiDiUsw(sal_uInt16 nId, const sal_uInt8* pData,
2863 short nLen)
2865 static const sal_uInt16 nEndIds[2] =
2867 RES_CHRATR_CTL_WEIGHT, RES_CHRATR_CTL_POSTURE,
2870 sal_uInt8 nI;
2871 ww::WordVersion eVersion = pWwFib->GetFIBVersion();
2872 if (eVersion <= ww::eWW2)
2873 nI = static_cast< sal_uInt8 >(nId - 80);
2874 else if (eVersion < ww::eWW8)
2875 nI = static_cast< sal_uInt8 >(nId - 111);
2876 else
2877 nI = static_cast< sal_uInt8 >(nId - 0x085C);
2879 OSL_ENSURE(nI <= 1, "not happening");
2880 if (nI > 1)
2881 return;
2883 sal_uInt16 nMask = 1 << nI;
2885 if( nLen < 0 )
2887 pCtrlStck->SetAttr(*pPaM->GetPoint(),nEndIds[nI]);
2888 pCtrlStck->SetToggleBiDiAttr(nI, false);
2889 return;
2891 bool bOn = *pData & 1;
2892 SwWW8StyInf* pSI = GetStyle(nAktColl);
2893 if (pPlcxMan)
2895 const sal_uInt8 *pCharIstd =
2896 pPlcxMan->GetChpPLCF()->HasSprm(bVer67 ? 80 : 0x4A30);
2897 if (pCharIstd)
2898 pSI = GetStyle(SVBT16ToShort(pCharIstd));
2901 if (pAktColl && eVersion > ww::eWW2) // StyleDef -> Flags merken
2903 if (pSI)
2905 if( pSI->nBase < vColl.size() // Style Based on
2906 && ( *pData & 0x80 ) // Bit 7 gesetzt ?
2907 && ( vColl[pSI->nBase].n81BiDiFlags & nMask ) ) // BasisMaske ?
2908 bOn = !bOn; // umdrehen
2910 if( bOn )
2911 pSI->n81BiDiFlags |= nMask; // Flag setzen
2912 else
2913 pSI->n81BiDiFlags &= ~nMask; // Flag loeschen
2916 else
2919 // im Text -> Flags abfragen
2920 if (*pData & 0x80) // Bit 7 gesetzt ?
2922 if (pSI && pSI->n81BiDiFlags & nMask) // und in StyleDef an ?
2923 bOn = !bOn; // dann invertieren
2924 // am Stack vermerken, das dieses ein Toggle-Attribut ist
2925 pCtrlStck->SetToggleBiDiAttr(nI, true);
2929 SetToggleBiDiAttr(nI, bOn);
2932 void SwWW8ImplReader::SetToggleBiDiAttr(sal_uInt8 nAttrId, bool bOn)
2934 switch (nAttrId)
2936 case 0:
2938 SvxWeightItem aAttr( bOn ? WEIGHT_BOLD : WEIGHT_NORMAL, RES_CHRATR_WEIGHT );
2939 aAttr.SetWhich( RES_CHRATR_CTL_WEIGHT );
2940 NewAttr( aAttr );
2942 break;
2943 case 1:
2945 SvxPostureItem aAttr( bOn ? ITALIC_NORMAL : ITALIC_NONE, RES_CHRATR_POSTURE );
2946 aAttr.SetWhich( RES_CHRATR_CTL_POSTURE );
2947 NewAttr( aAttr );
2949 break;
2950 default:
2951 OSL_ENSURE(!this, "Unhandled unknown bidi toggle attribute");
2952 break;
2957 void SwWW8ImplReader::SetToggleAttr(sal_uInt8 nAttrId, bool bOn)
2959 ww::WordVersion eVersion = pWwFib->GetFIBVersion();
2961 switch (nAttrId)
2963 case 0:
2965 SvxWeightItem aAttr( bOn ? WEIGHT_BOLD : WEIGHT_NORMAL, RES_CHRATR_WEIGHT );
2966 NewAttr( aAttr );
2967 aAttr.SetWhich( RES_CHRATR_CJK_WEIGHT );
2968 NewAttr( aAttr );
2969 if (eVersion <= ww::eWW6)
2971 aAttr.SetWhich( RES_CHRATR_CTL_WEIGHT );
2972 NewAttr( aAttr );
2975 break;
2976 case 1:
2978 SvxPostureItem aAttr( bOn ? ITALIC_NORMAL : ITALIC_NONE, RES_CHRATR_POSTURE );
2979 NewAttr( aAttr );
2980 aAttr.SetWhich( RES_CHRATR_CJK_POSTURE );
2981 NewAttr( aAttr );
2982 if (eVersion <= ww::eWW6)
2984 aAttr.SetWhich( RES_CHRATR_CTL_POSTURE );
2985 NewAttr( aAttr );
2988 break;
2989 case 2:
2990 NewAttr(SvxCrossedOutItem(bOn ? STRIKEOUT_SINGLE : STRIKEOUT_NONE, RES_CHRATR_CROSSEDOUT));
2991 break;
2992 case 3:
2993 NewAttr( SvxContourItem( bOn, RES_CHRATR_CONTOUR ) );
2994 break;
2995 case 4:
2996 NewAttr( SvxShadowedItem( bOn, RES_CHRATR_SHADOWED ) );
2997 break;
2998 case 5:
2999 NewAttr( SvxCaseMapItem( bOn ? SVX_CASEMAP_KAPITAELCHEN
3000 : SVX_CASEMAP_NOT_MAPPED, RES_CHRATR_CASEMAP ) );
3001 break;
3002 case 6:
3003 NewAttr( SvxCaseMapItem( bOn ? SVX_CASEMAP_VERSALIEN
3004 : SVX_CASEMAP_NOT_MAPPED, RES_CHRATR_CASEMAP ) );
3005 break;
3006 case 7:
3007 NewAttr(SvxCharHiddenItem(bOn, RES_CHRATR_HIDDEN));
3008 break;
3009 case 8:
3010 NewAttr( SvxCrossedOutItem( bOn ? STRIKEOUT_DOUBLE
3011 : STRIKEOUT_NONE, RES_CHRATR_CROSSEDOUT ) );
3012 break;
3013 default:
3014 OSL_ENSURE(!this, "Unhandled unknown toggle attribute");
3015 break;
3019 void SwWW8ImplReader::_ChkToggleAttr( sal_uInt16 nOldStyle81Mask,
3020 sal_uInt16 nNewStyle81Mask )
3022 sal_uInt16 i = 1, nToggleAttrFlags = pCtrlStck->GetToggleAttrFlags();
3023 for (sal_uInt8 n = 0; n < 7; ++n, i <<= 1)
3025 if (
3026 (i & nToggleAttrFlags) &&
3027 ((i & nOldStyle81Mask) != (i & nNewStyle81Mask))
3030 SetToggleAttr(n, (i & nOldStyle81Mask));
3035 void SwWW8ImplReader::_ChkToggleBiDiAttr( sal_uInt16 nOldStyle81Mask,
3036 sal_uInt16 nNewStyle81Mask )
3038 sal_uInt16 i = 1, nToggleAttrFlags = pCtrlStck->GetToggleBiDiAttrFlags();
3039 for (sal_uInt8 n = 0; n < 7; ++n, i <<= 1)
3041 if (
3042 (i & nToggleAttrFlags) &&
3043 ((i & nOldStyle81Mask) != (i & nNewStyle81Mask))
3046 SetToggleBiDiAttr(n, (i & nOldStyle81Mask));
3051 void SwWW8ImplReader::Read_SubSuper( sal_uInt16, const sal_uInt8* pData, short nLen )
3053 if( nLen < 0 ){
3054 pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_CHRATR_ESCAPEMENT );
3055 return;
3058 short nEs;
3059 sal_uInt8 nProp;
3060 switch( *pData )
3062 case 1:
3063 nEs = DFLT_ESC_AUTO_SUPER;
3064 nProp = DFLT_ESC_PROP;
3065 break;
3066 case 2:
3067 nEs = DFLT_ESC_AUTO_SUB;
3068 nProp = DFLT_ESC_PROP;
3069 break;
3070 default:
3071 nEs = 0;
3072 nProp = 100;
3073 break;
3075 NewAttr( SvxEscapementItem( nEs, nProp, RES_CHRATR_ESCAPEMENT ) );
3078 SwFrmFmt *SwWW8ImplReader::ContainsSingleInlineGraphic(const SwPaM &rRegion)
3081 For inline graphics and objects word has a hacked in feature to use
3082 subscripting to force the graphic into a centered position on the line, so
3083 we must check when applying sub/super to see if it the subscript range
3084 contains only a single graphic, and if that graphic is anchored as
3085 FLY_AS_CHAR and then we can change its anchoring to centered in the line.
3087 SwFrmFmt *pRet=0;
3088 SwNodeIndex aBegin(rRegion.Start()->nNode);
3089 xub_StrLen nBegin(rRegion.Start()->nContent.GetIndex());
3090 SwNodeIndex aEnd(rRegion.End()->nNode);
3091 xub_StrLen nEnd(rRegion.End()->nContent.GetIndex());
3092 const SwTxtNode* pTNd;
3093 const SwTxtAttr* pTFlyAttr;
3094 if (
3095 aBegin == aEnd && nBegin == nEnd - 1 &&
3096 0 != (pTNd = aBegin.GetNode().GetTxtNode()) &&
3097 0 != (pTFlyAttr = pTNd->GetTxtAttrForCharAt(nBegin, RES_TXTATR_FLYCNT))
3100 const SwFmtFlyCnt& rFly = pTFlyAttr->GetFlyCnt();
3101 SwFrmFmt *pFlyFmt = rFly.GetFrmFmt();
3102 if (pFlyFmt &&
3103 (FLY_AS_CHAR == pFlyFmt->GetAnchor().GetAnchorId()))
3105 pRet = pFlyFmt;
3108 return pRet;
3111 bool SwWW8ImplReader::ConvertSubToGraphicPlacement()
3114 For inline graphics and objects word has a hacked in feature to use
3115 subscripting to force the graphic into a centered position on the line, so
3116 we must check when applying sub/super to see if it the subscript range
3117 contains only a single graphic, and if that graphic is anchored as
3118 FLY_AS_CHAR and then we can change its anchoring to centered in the line.
3120 bool bIsGraphicPlacementHack = false;
3121 sal_uInt16 nPos;
3122 if (pCtrlStck->GetFmtStackAttr(RES_CHRATR_ESCAPEMENT, &nPos))
3124 SwPaM aRegion(*pPaM->GetPoint());
3126 SwFltPosition aMkPos((*pCtrlStck)[nPos].m_aMkPos);
3127 SwFltPosition aPtPos(*pPaM->GetPoint());
3129 SwFrmFmt *pFlyFmt = 0;
3130 if (
3131 SwFltStackEntry::MakeRegion(&rDoc,aRegion,false,aMkPos,aPtPos) &&
3132 0 != (pFlyFmt = ContainsSingleInlineGraphic(aRegion))
3135 pCtrlStck->DeleteAndDestroy(nPos);
3136 pFlyFmt->SetFmtAttr(SwFmtVertOrient(0, text::VertOrientation::CHAR_CENTER, text::RelOrientation::CHAR));
3137 bIsGraphicPlacementHack = true;
3140 return bIsGraphicPlacementHack;
3143 void SwWW8ImplReader::Read_SubSuperProp( sal_uInt16, const sal_uInt8* pData, short nLen )
3145 if( nLen < 0 )
3147 if (!ConvertSubToGraphicPlacement())
3148 pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_CHRATR_ESCAPEMENT );
3149 return;
3152 ww::WordVersion eVersion = pWwFib->GetFIBVersion();
3154 // Font-Position in HalfPoints
3155 short nPos = eVersion <= ww::eWW2 ? static_cast< sal_Int8 >( *pData ) : SVBT16ToShort( pData );
3156 sal_Int32 nPos2 = nPos * ( 10 * 100 ); // HalfPoints in 100 * tw
3157 const SvxFontHeightItem* pF
3158 = (const SvxFontHeightItem*)GetFmtAttr(RES_CHRATR_FONTSIZE);
3159 OSL_ENSURE(pF, "Expected to have the fontheight available here");
3161 // #i59022: Check ensure nHeight != 0. Div by zero otherwise.
3162 sal_Int32 nHeight = 240;
3163 if (pF != NULL && pF->GetHeight() != 0)
3164 nHeight = pF->GetHeight();
3165 nPos2 /= nHeight; // ... nun in % ( gerundet )
3166 if( nPos2 > 100 ) // zur Sicherheit
3167 nPos2 = 100;
3168 if( nPos2 < -100 )
3169 nPos2 = -100;
3170 SvxEscapementItem aEs( (short)nPos2, 100, RES_CHRATR_ESCAPEMENT );
3171 NewAttr( aEs );
3174 void SwWW8ImplReader::Read_Underline( sal_uInt16, const sal_uInt8* pData, short nLen )
3176 FontUnderline eUnderline = UNDERLINE_NONE;
3177 bool bWordLine = false;
3178 if( pData )
3180 // Parameter: 0 = none, 1 = single, 2 = by Word,
3181 // 3 = double, 4 = dotted, 5 = hidden
3182 // 6 = thick, 7 = dash, 8 = dot(not used)
3183 // 9 = dotdash 10 = dotdotdash 11 = wave
3186 // pruefe auf Sonderfall "fett+unterstrichen"
3187 bool bAlsoBold = /*( 6 == b )*/ false;
3188 // erst mal ggfs. *bold* einschalten!
3189 if( bAlsoBold )
3191 sal_uInt8 nOn = 1;
3192 Read_BoldUsw( 0x0835, &nOn, nLen );
3193 eUnderline = UNDERLINE_SINGLE;
3195 else
3197 switch( *pData )
3199 case 2: bWordLine = true; // no break;
3200 case 1: eUnderline = (FontUnderline)UNDERLINE_SINGLE; break;
3201 case 3: eUnderline = (FontUnderline)UNDERLINE_DOUBLE; break;
3202 case 4: eUnderline = (FontUnderline)UNDERLINE_DOTTED; break;
3203 case 7: eUnderline = (FontUnderline)UNDERLINE_DASH; break;
3204 case 9: eUnderline = (FontUnderline)UNDERLINE_DASHDOT; break;
3205 case 10:eUnderline = (FontUnderline)UNDERLINE_DASHDOTDOT; break;
3206 case 6: eUnderline = (FontUnderline)UNDERLINE_BOLD; break;
3207 case 11:eUnderline = (FontUnderline)UNDERLINE_WAVE; break;
3208 case 20:eUnderline = (FontUnderline)UNDERLINE_BOLDDOTTED; break;
3209 case 23:eUnderline = (FontUnderline)UNDERLINE_BOLDDASH; break;
3210 case 39:eUnderline = (FontUnderline)UNDERLINE_LONGDASH; break;
3211 case 55:eUnderline = (FontUnderline)UNDERLINE_BOLDLONGDASH; break;
3212 case 25:eUnderline = (FontUnderline)UNDERLINE_BOLDDASHDOT; break;
3213 case 26:eUnderline = (FontUnderline)UNDERLINE_BOLDDASHDOTDOT;break;
3214 case 27:eUnderline = (FontUnderline)UNDERLINE_BOLDWAVE; break;
3215 case 43:eUnderline = (FontUnderline)UNDERLINE_DOUBLEWAVE; break;
3220 // dann Stack ggfs. verwursteln und exit!
3221 if( nLen < 0 )
3223 pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_CHRATR_UNDERLINE );
3224 pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_CHRATR_WORDLINEMODE );
3226 else
3228 NewAttr( SvxUnderlineItem( eUnderline, RES_CHRATR_UNDERLINE ));
3229 if( bWordLine )
3230 NewAttr(SvxWordLineModeItem(true, RES_CHRATR_WORDLINEMODE));
3235 //The last three vary, measurements, rotation ? ?
3236 NoBracket 78 CA 06 - 02 00 00 02 34 52
3237 () 78 CA 06 - 02 01 00 02 34 52
3238 [] 78 CA 06 - 02 02 00 02 34 52
3239 <> 78 CA 06 - 02 03 00 02 34 52
3240 {} 78 CA 06 - 02 04 00 02 34 52
3242 void SwWW8ImplReader::Read_DoubleLine_Rotate( sal_uInt16, const sal_uInt8* pData,
3243 short nLen )
3245 if( nLen < 0 ) // close the tag
3247 pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_CHRATR_TWO_LINES );
3248 pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_CHRATR_ROTATE );
3250 else if( pData && 6 == nLen )
3252 switch( *pData )
3254 case 2: // double line
3256 sal_Unicode cStt = 0, cEnd = 0;
3257 switch( SVBT16ToShort( pData+1 ) )
3259 case 1: cStt = '(', cEnd = ')'; break;
3260 case 2: cStt = '[', cEnd = ']'; break;
3261 case 3: cStt = '<', cEnd = '>'; break;
3262 case 4: cStt = '{', cEnd = '}'; break;
3264 NewAttr( SvxTwoLinesItem( sal_True, cStt, cEnd, RES_CHRATR_TWO_LINES ));
3266 break;
3268 case 1: // rotated characters
3270 bool bFitToLine = 0 != *(pData+1);
3271 NewAttr( SvxCharRotateItem( 900, bFitToLine, RES_CHRATR_ROTATE ));
3273 break;
3278 void SwWW8ImplReader::Read_TxtColor( sal_uInt16, const sal_uInt8* pData, short nLen )
3280 //Has newer colour varient, ignore this old varient
3281 if (!bVer67 && pPlcxMan && pPlcxMan->GetChpPLCF()->HasSprm(0x6870))
3282 return;
3284 if( nLen < 0 )
3285 pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_CHRATR_COLOR );
3286 else
3288 sal_uInt8 b = *pData; // Parameter: 0 = Auto, 1..16 Farben
3290 if( b > 16 ) // unbekannt -> Black
3291 b = 0;
3293 NewAttr( SvxColorItem(Color(GetCol(b)), RES_CHRATR_COLOR));
3294 if (pAktColl && pStyles)
3295 pStyles->bTxtColChanged = true;
3299 void SwWW8ImplReader::Read_TxtForeColor(sal_uInt16, const sal_uInt8* pData, short nLen)
3301 if( nLen < 0 )
3302 pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_CHRATR_COLOR );
3303 else
3305 Color aColor(msfilter::util::BGRToRGB(SVBT32ToUInt32(pData)));
3306 NewAttr(SvxColorItem(aColor, RES_CHRATR_COLOR));
3307 if (pAktColl && pStyles)
3308 pStyles->bTxtColChanged = true;
3312 bool SwWW8ImplReader::GetFontParams( sal_uInt16 nFCode, FontFamily& reFamily,
3313 String& rName, FontPitch& rePitch, CharSet& reCharSet )
3315 // Die Defines, aus denen diese Tabellen erzeugt werden, stehen in windows.h
3316 static const FontPitch ePitchA[] =
3318 PITCH_DONTKNOW, PITCH_FIXED, PITCH_VARIABLE, PITCH_DONTKNOW
3321 static const FontFamily eFamilyA[] =
3323 FAMILY_DONTKNOW, FAMILY_ROMAN, FAMILY_SWISS, FAMILY_MODERN,
3324 FAMILY_SCRIPT, FAMILY_DECORATIVE
3327 const WW8_FFN* pF = pFonts->GetFont( nFCode ); // Info dazu
3328 if( !pF ) // FontNummer unbekannt ?
3329 return false; // dann ignorieren
3331 rName = String( pF->sFontname );
3333 // pF->prg : Pitch
3334 rePitch = ePitchA[pF->prg];
3336 // pF->chs: Charset
3337 if( 77 == pF->chs ) // Mac-Font im Mac-Charset oder
3338 reCharSet = eTextCharSet; // auf ANSI-Charset uebersetzt
3339 else
3340 { // patch from cmc for #i52786#
3341 // #i52786#, for word 67 we'll assume that ANSI is basically invalid,
3342 // might be true for (above) mac as well, but would need a mac example
3343 // that exercises this to be sure
3344 if (bVer67 && pF->chs == 0)
3345 reCharSet = RTL_TEXTENCODING_DONTKNOW;
3346 else
3347 reCharSet = rtl_getTextEncodingFromWindowsCharset( pF->chs );
3350 // pF->ff : Family
3351 sal_uInt8 b = pF->ff;
3353 // make sure Font Family Code is set correctly
3354 // at least for the most important fonts
3355 // ( might be set wrong when Doc was not created by
3356 // Winword but by third party program like Applixware... )
3358 0: FAMILY_DONTKNOW
3359 1: FAMILY_ROMAN
3360 2: FAMILY_SWISS
3361 3: FAMILY_MODERN
3362 4: FAMILY_SCRIPT
3363 5: FAMILY_DECORATIVE
3365 #define FONTNAMETAB_SZ 14
3366 #define MAX_FONTNAME_ROMAN 6
3367 static const sal_Char
3368 // first comes ROMAN
3369 sFontName0[] = "\x07""Tms Rmn",
3370 sFontName1[] = "\x07""Timmons",
3371 sFontName2[] = "\x08""CG Times",
3372 sFontName3[] = "\x08""MS Serif",
3373 sFontName4[] = "\x08""Garamond",
3374 sFontName5[] = "\x11""Times Roman",
3375 sFontName6[] = "\x15""Times New Roman",
3376 // from here SWISS --> see above: #define MAX_FONTNAME_ROMAN 6
3377 sFontName7[] = "\x04""Helv",
3378 sFontName8[] = "\x05""Arial",
3379 sFontName9[] = "\x07""Univers",
3380 sFontName10[]= "\x11""LinePrinter",
3381 sFontName11[]= "\x11""Lucida Sans",
3382 sFontName12[]= "\x11""Small Fonts",
3383 sFontName13[]= "\x13""MS Sans Serif";
3384 static const sal_Char* const aFontNameTab[ FONTNAMETAB_SZ ] =
3386 sFontName0, sFontName1, sFontName2, sFontName3,
3387 sFontName4, sFontName5, sFontName6, sFontName7,
3388 sFontName8, sFontName9, sFontName10, sFontName11,
3389 sFontName12, sFontName13
3392 for( sal_uInt16 n = 0; n < FONTNAMETAB_SZ; n++ )
3394 const sal_Char* pCmp = aFontNameTab[ n ];
3395 xub_StrLen nLen = *pCmp++;
3396 if( rName.EqualsIgnoreCaseAscii(pCmp, 0, nLen) )
3398 b = n <= MAX_FONTNAME_ROMAN ? 1 : 2;
3399 break;
3402 if (b < (sizeof(eFamilyA)/sizeof(eFamilyA[0])))
3403 reFamily = eFamilyA[b];
3404 else
3405 reFamily = FAMILY_DONTKNOW;
3407 return true;
3410 bool SwWW8ImplReader::SetNewFontAttr(sal_uInt16 nFCode, bool bSetEnums,
3411 sal_uInt16 nWhich)
3413 FontFamily eFamily;
3414 String aName;
3415 FontPitch ePitch;
3416 CharSet eSrcCharSet;
3418 if( !GetFontParams( nFCode, eFamily, aName, ePitch, eSrcCharSet ) )
3420 //If we fail (and are not doing a style) then put something into the
3421 //character encodings stack anyway so that the property end that pops
3422 //off the stack will keep in sync
3423 if (!pAktColl && IsListOrDropcap())
3425 if (nWhich == RES_CHRATR_CJK_FONT)
3427 if (!maFontSrcCJKCharSets.empty())
3429 eSrcCharSet = maFontSrcCJKCharSets.top();
3431 else
3433 eSrcCharSet = RTL_TEXTENCODING_DONTKNOW;
3436 maFontSrcCJKCharSets.push(eSrcCharSet);
3438 else
3440 if (!maFontSrcCharSets.empty())
3442 eSrcCharSet = maFontSrcCharSets.top();
3444 else
3446 eSrcCharSet = RTL_TEXTENCODING_DONTKNOW;
3449 maFontSrcCharSets.push(eSrcCharSet);
3452 return false;
3455 CharSet eDstCharSet = eSrcCharSet;
3457 SvxFontItem aFont( eFamily, aName, aEmptyStr, ePitch, eDstCharSet, nWhich);
3459 if( bSetEnums )
3461 if( pAktColl && nAktColl < vColl.size() ) // StyleDef
3463 switch(nWhich)
3465 default:
3466 case RES_CHRATR_FONT:
3467 vColl[nAktColl].eLTRFontSrcCharSet = eSrcCharSet;
3468 break;
3469 case RES_CHRATR_CTL_FONT:
3470 vColl[nAktColl].eRTLFontSrcCharSet = eSrcCharSet;
3471 break;
3472 case RES_CHRATR_CJK_FONT:
3473 vColl[nAktColl].eCJKFontSrcCharSet = eSrcCharSet;
3474 break;
3477 else if (IsListOrDropcap())
3479 //Add character text encoding to stack
3480 if (nWhich == RES_CHRATR_CJK_FONT)
3481 maFontSrcCJKCharSets.push(eSrcCharSet);
3482 else
3483 maFontSrcCharSets.push(eSrcCharSet);
3487 NewAttr( aFont ); // ...und 'reinsetzen
3489 return true;
3492 void SwWW8ImplReader::ResetCharSetVars()
3494 OSL_ENSURE(!maFontSrcCharSets.empty(),"no charset to remove");
3495 if (!maFontSrcCharSets.empty())
3496 maFontSrcCharSets.pop();
3499 void SwWW8ImplReader::ResetCJKCharSetVars()
3501 OSL_ENSURE(!maFontSrcCJKCharSets.empty(),"no charset to remove");
3502 if (!maFontSrcCJKCharSets.empty())
3503 maFontSrcCJKCharSets.pop();
3506 void SwWW8ImplReader::openFont(sal_uInt16 nFCode, sal_uInt16 nId)
3508 if (SetNewFontAttr(nFCode, true, nId) && pAktColl && pStyles)
3510 // merken zur Simulation Default-Font
3511 if (RES_CHRATR_CJK_FONT == nId)
3512 pStyles->bCJKFontChanged = true;
3513 else if (RES_CHRATR_CTL_FONT == nId)
3514 pStyles->bCTLFontChanged = true;
3515 else
3516 pStyles->bFontChanged = true;
3520 void SwWW8ImplReader::closeFont(sal_uInt16 nId)
3522 pCtrlStck->SetAttr( *pPaM->GetPoint(), nId );
3523 if (nId == RES_CHRATR_CJK_FONT)
3524 ResetCJKCharSetVars();
3525 else
3526 ResetCharSetVars();
3530 Font ein oder ausschalten:
3532 void SwWW8ImplReader::Read_FontCode( sal_uInt16 nId, const sal_uInt8* pData, short nLen )
3534 if (!bSymbol) // falls bSymbol, gilt der am Symbol
3535 { // (siehe sprmCSymbol) gesetzte Font !
3536 switch( nId )
3538 case 113: //WW7
3539 case 0x4A51: //"Other" font, override with BiDi if it exists
3540 case 0x4A5E: //BiDi Font
3541 nId = RES_CHRATR_CTL_FONT;
3542 break;
3543 case 93: //WW6
3544 case 111: //WW7
3545 case 0x4A4f:
3546 nId = RES_CHRATR_FONT;
3547 break;
3548 case 112: //WW7
3549 case 0x4A50:
3550 nId = RES_CHRATR_CJK_FONT;
3551 break;
3552 default:
3553 return ;
3556 ww::WordVersion eVersion = pWwFib->GetFIBVersion();
3558 if( nLen < 0 ) // Ende des Attributes
3560 if (eVersion <= ww::eWW6)
3562 closeFont(RES_CHRATR_CTL_FONT);
3563 closeFont(RES_CHRATR_CJK_FONT);
3565 closeFont(nId);
3567 else
3569 sal_uInt16 nFCode = SVBT16ToShort( pData ); // Font-Nummer
3570 openFont(nFCode, nId);
3571 if (eVersion <= ww::eWW6)
3573 openFont(nFCode, RES_CHRATR_CJK_FONT);
3574 openFont(nFCode, RES_CHRATR_CTL_FONT);
3580 void SwWW8ImplReader::Read_FontSize( sal_uInt16 nId, const sal_uInt8* pData, short nLen )
3582 switch( nId )
3584 case 74:
3585 case 99:
3586 case 0x4a43:
3587 nId = RES_CHRATR_FONTSIZE;
3588 break;
3589 case 85: //WW2
3590 case 116: //WW7
3591 case 0x4a61:
3592 nId = RES_CHRATR_CTL_FONTSIZE;
3593 break;
3594 default:
3595 return ;
3598 ww::WordVersion eVersion = pWwFib->GetFIBVersion();
3600 if( nLen < 0 ) // Ende des Attributes
3602 pCtrlStck->SetAttr( *pPaM->GetPoint(), nId );
3603 if (eVersion <= ww::eWW6) // reset additionally the CTL size
3604 pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_CHRATR_CTL_FONTSIZE );
3605 if (RES_CHRATR_FONTSIZE == nId) // reset additionally the CJK size
3606 pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_CHRATR_CJK_FONTSIZE );
3608 else
3610 // Font-Size in half points e.g. 10 = 1440 / ( 72 * 2 )
3611 sal_uInt16 nFSize = eVersion <= ww::eWW2 ? *pData : SVBT16ToShort(pData);
3612 nFSize*= 10;
3614 SvxFontHeightItem aSz( nFSize, 100, nId );
3615 NewAttr( aSz );
3616 if (RES_CHRATR_FONTSIZE == nId) // set additionally the CJK size
3618 aSz.SetWhich( RES_CHRATR_CJK_FONTSIZE );
3619 NewAttr( aSz );
3621 if (eVersion <= ww::eWW6) // set additionally the CTL size
3623 aSz.SetWhich( RES_CHRATR_CTL_FONTSIZE );
3624 NewAttr( aSz );
3626 if (pAktColl && pStyles) // Style-Def ?
3628 // merken zur Simulation Default-FontSize
3629 if (nId == RES_CHRATR_CTL_FONTSIZE)
3630 pStyles->bFCTLSizeChanged = true;
3631 else
3633 pStyles->bFSizeChanged = true;
3634 if (eVersion <= ww::eWW6)
3635 pStyles->bFCTLSizeChanged= true;
3643 void SwWW8ImplReader::Read_CharSet(sal_uInt16 , const sal_uInt8* pData, short nLen)
3645 if( nLen < 0 )
3646 { // Ende des Attributes
3647 eHardCharSet = RTL_TEXTENCODING_DONTKNOW;
3648 return;
3650 sal_uInt8 nfChsDiff = SVBT8ToByte( pData );
3652 if( nfChsDiff )
3653 eHardCharSet = rtl_getTextEncodingFromWindowsCharset( *(pData + 1) );
3654 else
3655 eHardCharSet = RTL_TEXTENCODING_DONTKNOW;
3658 void SwWW8ImplReader::Read_Language( sal_uInt16 nId, const sal_uInt8* pData, short nLen )
3660 switch( nId )
3662 case 97:
3663 case 0x486D: //sprmCRgLid0_80
3664 case 0x4873: //Methinks, uncertain
3665 nId = RES_CHRATR_LANGUAGE;
3666 break;
3667 case 0x486E: //sprmCRgLid1_80
3668 case 0x4874: //Methinks, uncertain
3669 nId = RES_CHRATR_CJK_LANGUAGE;
3670 break;
3671 case 83:
3672 case 114:
3673 case 0x485F:
3674 nId = RES_CHRATR_CTL_LANGUAGE;
3675 break;
3676 default:
3677 return;
3680 if( nLen < 0 ) // Ende des Attributes
3681 pCtrlStck->SetAttr( *pPaM->GetPoint(), nId );
3682 else
3684 sal_uInt16 nLang = SVBT16ToShort( pData ); // Language-Id
3685 NewAttr(SvxLanguageItem((const LanguageType)nLang, nId));
3690 Einschalten des Zeichen-Styles:
3692 void SwWW8ImplReader::Read_CColl( sal_uInt16, const sal_uInt8* pData, short nLen )
3694 if( nLen < 0 ){ // Ende des Attributes
3695 pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_TXTATR_CHARFMT );
3696 nCharFmt = -1;
3697 return;
3699 sal_uInt16 nId = SVBT16ToShort( pData ); // Style-Id (NICHT Sprm-Id!)
3701 if( nId >= vColl.size() || !vColl[nId].pFmt // ungueltige Id ?
3702 || vColl[nId].bColl ) // oder Para-Style ?
3703 return; // dann ignorieren
3705 NewAttr( SwFmtCharFmt( (SwCharFmt*)vColl[nId].pFmt ) );
3706 nCharFmt = (short) nId;
3711 enger oder weiter als normal:
3713 void SwWW8ImplReader::Read_Kern( sal_uInt16, const sal_uInt8* pData, short nLen )
3715 if( nLen < 0 ){ // Ende des Attributes
3716 pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_CHRATR_KERNING );
3717 return;
3719 sal_Int16 nKern = SVBT16ToShort( pData ); // Kerning in Twips
3720 NewAttr( SvxKerningItem( nKern, RES_CHRATR_KERNING ) );
3723 void SwWW8ImplReader::Read_FontKern( sal_uInt16, const sal_uInt8* , short nLen )
3725 if( nLen < 0 ) // Ende des Attributes
3726 pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_CHRATR_AUTOKERN );
3727 else
3728 NewAttr(SvxAutoKernItem(true, RES_CHRATR_AUTOKERN));
3731 void SwWW8ImplReader::Read_CharShadow( sal_uInt16, const sal_uInt8* pData, short nLen )
3733 //Has newer colour varient, ignore this old varient
3734 if (!bVer67 && pPlcxMan && pPlcxMan->GetChpPLCF()->HasSprm(0xCA71))
3735 return;
3737 if( nLen <= 0 )
3739 pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_CHRATR_BACKGROUND );
3740 if( bCharShdTxtCol )
3742 // Zeichenfarbe auch
3743 pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_CHRATR_COLOR );
3744 bCharShdTxtCol = false;
3747 else
3749 WW8_SHD aSHD;
3750 aSHD.SetWWValue( *(SVBT16*)pData );
3751 SwWW8Shade aSh( bVer67, aSHD );
3753 NewAttr( SvxBrushItem( aSh.aColor, RES_CHRATR_BACKGROUND ));
3757 void SwWW8ImplReader::Read_TxtBackColor(sal_uInt16, const sal_uInt8* pData, short nLen )
3759 if( nLen <= 0 )
3761 pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_CHRATR_BACKGROUND );
3762 if( bCharShdTxtCol )
3764 // Zeichenfarbe auch
3765 pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_CHRATR_COLOR );
3766 bCharShdTxtCol = false;
3769 else
3771 OSL_ENSURE(nLen == 10, "Len of para back colour not 10!");
3772 if (nLen != 10)
3773 return;
3774 Color aColour(ExtractColour(pData, bVer67));
3775 NewAttr(SvxBrushItem(aColour, RES_CHRATR_BACKGROUND));
3779 void SwWW8ImplReader::Read_CharHighlight(sal_uInt16, const sal_uInt8* pData, short nLen)
3781 if( nLen <= 0 )
3783 pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_CHRATR_BACKGROUND );
3784 if( bCharShdTxtCol )
3786 pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_CHRATR_COLOR ); // Zeichenfarbe auch
3787 bCharShdTxtCol = false;
3790 else
3792 sal_uInt8 b = *pData; // Parameter: 0 = Auto, 1..16 Farben
3794 if( b > 16 ) // unbekannt -> Black
3795 b = 0; // Auto -> Black
3797 Color aCol(GetCol(b));
3798 NewAttr( SvxBrushItem( aCol , RES_CHRATR_BACKGROUND ));
3803 /***************************************************************************
3804 # Absatz - Attribute
3805 #**************************************************************************/
3807 void SwWW8ImplReader::Read_NoLineNumb(sal_uInt16 , const sal_uInt8* pData, short nLen)
3809 if( nLen < 0 ) // Ende des Attributes
3811 pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_LINENUMBER );
3812 return;
3814 SwFmtLineNumber aLN;
3815 if (const SwFmtLineNumber* pLN
3816 = (const SwFmtLineNumber*)GetFmtAttr(RES_LINENUMBER))
3818 aLN.SetStartValue( pLN->GetStartValue() );
3821 aLN.SetCountLines( pData && (0 == *pData) );
3822 NewAttr( aLN );
3825 bool lcl_HasExplicitLeft(const WW8PLCFMan *pPlcxMan, bool bVer67)
3827 WW8PLCFx_Cp_FKP *pPap = pPlcxMan ? pPlcxMan->GetPapPLCF() : 0;
3828 if (pPap)
3830 if (bVer67)
3831 return pPap->HasSprm(17);
3832 else
3833 return (pPap->HasSprm(0x840F) || pPap->HasSprm(0x845E));
3835 return false;
3837 // Sprm 16, 17
3838 void SwWW8ImplReader::Read_LR( sal_uInt16 nId, const sal_uInt8* pData, short nLen )
3840 if (nLen < 0) // End of the Attributes
3842 pCtrlStck->SetAttr(*pPaM->GetPoint(), RES_LR_SPACE);
3843 return;
3846 short nPara = SVBT16ToShort( pData );
3848 SvxLRSpaceItem aLR( RES_LR_SPACE );
3849 const SfxPoolItem* pLR = GetFmtAttr(RES_LR_SPACE);
3850 if( pLR )
3851 aLR = *static_cast<const SvxLRSpaceItem*>(pLR);
3853 // Fix the regression issue: #i99822#: Discussion?
3854 // Since the list level formatting doesn't apply into paragraph style
3855 // for list levels of mode LABEL_ALIGNMENT.(see ww8par3.cxx
3856 // W8ImplReader::RegisterNumFmtOnTxtNode).
3857 // Need to apply the list format to the paragraph here.
3858 SwTxtNode* pTxtNode = pPaM->GetNode()->GetTxtNode();
3859 if( pTxtNode && pTxtNode->AreListLevelIndentsApplicable() )
3861 SwNumRule * pNumRule = pTxtNode->GetNumRule();
3862 if( pNumRule )
3864 sal_uInt8 nLvl = static_cast< sal_uInt8 >(pTxtNode->GetActualListLevel());
3865 const SwNumFmt* pFmt = pNumRule->GetNumFmt( nLvl );
3866 if ( pFmt && pFmt->GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_ALIGNMENT )
3868 aLR.SetTxtLeft( pFmt->GetIndentAt() );
3869 aLR.SetTxtFirstLineOfst( static_cast<short>(pFmt->GetFirstLineIndent()) );
3870 // make paragraph have hard-set indent attributes
3871 pTxtNode->SetAttr( aLR );
3877 The older word sprms mean left/right, while the new ones mean before/after.
3878 Writer now also works with before after, so when we see old left/right and
3879 we're RTL. We swap them
3881 if (IsRightToLeft())
3883 switch (nId)
3885 //Left becomes after;
3886 case 17:
3887 nId = 16;
3888 break;
3889 case 0x840F:
3890 nId = 0x840E;
3891 break;
3892 //Right becomes before;
3893 case 16:
3894 nId = 17;
3895 break;
3896 case 0x840E:
3897 nId = 0x840F;
3898 break;
3902 bool bFirstLinOfstSet( false ); // #i103711#
3903 bool bLeftIndentSet( false ); // #i105414#
3905 switch (nId)
3907 //sprmPDxaLeft
3908 case 17:
3909 case 0x840F:
3910 case 0x845E:
3911 aLR.SetTxtLeft( nPara );
3912 if (pAktColl && nAktColl < vColl.size())
3914 vColl[nAktColl].bListReleventIndentSet = true;
3916 bLeftIndentSet = true; // #i105414#
3917 break;
3918 //sprmPDxaLeft1
3919 case 19:
3920 case 0x8411:
3921 case 0x8460:
3923 As part of an attempt to break my spirit ww 8+ formats can contain
3924 ww 7- lists. If they do and the list is part of the style, then
3925 when removing the list from a paragraph of that style there
3926 appears to be a bug where the hanging indent value which the list
3927 set is still factored into the left indent of the paragraph. Its
3928 not listed in the winword dialogs, but it is clearly there. So if
3929 our style has a broken ww 7- list and we know that the list has
3930 been removed then we will factor the original list applied hanging
3931 into our calculation.
3933 if (pPlcxMan && nAktColl < vColl.size() && vColl[nAktColl].bHasBrokenWW6List)
3935 const sal_uInt8 *pIsZeroed = pPlcxMan->GetPapPLCF()->HasSprm(0x460B);
3936 if (pIsZeroed && *pIsZeroed == 0)
3938 const SvxLRSpaceItem &rLR =
3939 ItemGet<SvxLRSpaceItem>(*(vColl[nAktColl].pFmt),
3940 RES_LR_SPACE);
3941 nPara = nPara - rLR.GetTxtFirstLineOfst();
3945 aLR.SetTxtFirstLineOfst(nPara);
3947 if (!pAktColl)
3949 if (const SwTxtNode* pNode = pPaM->GetNode()->GetTxtNode())
3951 if ( const SwNumFmt *pNumFmt = GetNumFmtFromTxtNode(*pNode) )
3953 if (!lcl_HasExplicitLeft(pPlcxMan, bVer67))
3955 aLR.SetTxtLeft(pNumFmt->GetIndentAt());
3957 // If have not explicit left, set number format list tab position is doc default tab
3958 const SvxTabStopItem *pDefaultStopItem = (const SvxTabStopItem *)rDoc.GetAttrPool().GetPoolDefaultItem(RES_PARATR_TABSTOP);
3959 if ( pDefaultStopItem && pDefaultStopItem->Count() > 0 )
3960 ((SwNumFmt*)(pNumFmt))->SetListtabPos( ((SvxTabStop&)(*pDefaultStopItem)[0]).GetTabPos() );
3965 if (pAktColl && nAktColl < vColl.size())
3967 vColl[nAktColl].bListReleventIndentSet = true;
3969 bFirstLinOfstSet = true; // #i103711#
3970 break;
3971 //sprmPDxaRight
3972 case 16:
3973 case 0x840E:
3974 case 0x845D:
3975 aLR.SetRight( nPara );
3976 break;
3977 default:
3978 return;
3981 NewAttr( aLR, bFirstLinOfstSet, bLeftIndentSet ); // #i103711#, #i105414#
3984 // Sprm 20
3985 void SwWW8ImplReader::Read_LineSpace( sal_uInt16, const sal_uInt8* pData, short nLen )
3987 // Kommentear siehe Read_UL()
3988 if (bStyNormal && bWWBugNormal)
3989 return;
3991 if( nLen < 0 ){
3992 pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_PARATR_LINESPACING );
3993 if( !( nIniFlags & WW8FL_NO_IMPLPASP ) )
3994 pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_UL_SPACE );
3995 return;
3998 short nSpace = SVBT16ToShort( pData );
3999 ww::WordVersion eVersion = pWwFib->GetFIBVersion();
4000 short nMulti = (eVersion <= ww::eWW2) ? 1 : SVBT16ToShort( pData + 2 );
4002 SvxLineSpace eLnSpc;
4003 if( 0 > nSpace )
4005 nSpace = -nSpace;
4006 eLnSpc = SVX_LINE_SPACE_FIX;
4008 else
4009 eLnSpc = SVX_LINE_SPACE_MIN;
4011 // WW hat einen impliziten zusaetzlichen Absatzabstand abhaengig vom
4012 // Zeilenabstand. Er betraegt bei "genau", 0.8*Zeilenabstand "vor" und
4013 // 0.2*Zeilenabstand "nach".
4014 // Bei "Mindestens" sind es 1*Zeilenabstand "vor" und 0*Zeilenabstand "nach".
4015 // Bei Mehrfach sind es 0 "vor" und min( 0cm, FontSize*(nFach-1) ) "nach".
4017 // SW hat auch einen impliziten Zeilenabstand. er betraegt bei "mindestens"
4018 // 1*Zeilenabstand "vor" und 0 "nach"
4019 // bei proportional betraegt er min( 0cm, FontSize*(nFach-1) ) sowohl "vor"
4020 // wie auch "nach"
4022 sal_uInt16 nSpaceTw = 0;
4024 SvxLineSpacingItem aLSpc( LINE_SPACE_DEFAULT_HEIGHT, RES_PARATR_LINESPACING );
4026 if( 1 == nMulti ) // MultilineSpace ( proportional )
4028 long n = nSpace * 10 / 24; // WW: 240 = 100%, SW: 100 = 100%
4030 // nach Absprache mit AMA ist die Begrenzung unsinnig
4031 if( n>200 ) n = 200; // SW_UI-Maximum
4032 aLSpc.SetPropLineSpace( (const sal_uInt8)n );
4033 const SvxFontHeightItem* pH = (const SvxFontHeightItem*)
4034 GetFmtAttr( RES_CHRATR_FONTSIZE );
4035 nSpaceTw = (sal_uInt16)( n * pH->GetHeight() / 100 );
4037 else // Fixed / Minimum
4039 // bei negativen Space ist der Abstand exakt, sonst minimum
4040 nSpaceTw = (sal_uInt16)nSpace;
4041 aLSpc.SetLineHeight( nSpaceTw );
4042 aLSpc.GetLineSpaceRule() = eLnSpc;
4044 NewAttr( aLSpc );
4045 if( pSFlyPara )
4046 pSFlyPara->nLineSpace = nSpaceTw; // LineSpace fuer Graf-Apos
4049 //#i18519# AutoSpace value depends on Dop fDontUseHTMLAutoSpacing setting
4050 sal_uInt16 SwWW8ImplReader::GetParagraphAutoSpace(bool fDontUseHTMLAutoSpacing)
4052 if (fDontUseHTMLAutoSpacing)
4053 return 100; //Seems to be always 5points in this case
4054 else
4055 return 280; //Seems to be always 14points in this case
4058 void SwWW8ImplReader::Read_ParaAutoBefore(sal_uInt16, const sal_uInt8 *pData, short nLen)
4060 if (nLen < 0)
4062 pCtrlStck->SetAttr(*pPaM->GetPoint(), RES_UL_SPACE);
4063 return;
4066 if (*pData)
4068 SvxULSpaceItem aUL(*(const SvxULSpaceItem*)GetFmtAttr(RES_UL_SPACE));
4069 aUL.SetUpper(GetParagraphAutoSpace(pWDop->fDontUseHTMLAutoSpacing));
4070 NewAttr(aUL);
4071 if (pAktColl && nAktColl < vColl.size())
4072 vColl[nAktColl].bParaAutoBefore = true;
4073 else
4074 bParaAutoBefore = true;
4076 else
4078 if (pAktColl && nAktColl < vColl.size())
4079 vColl[nAktColl].bParaAutoBefore = false;
4080 else
4081 bParaAutoBefore = false;
4085 void SwWW8ImplReader::Read_ParaAutoAfter(sal_uInt16, const sal_uInt8 *pData, short nLen)
4087 if (nLen < 0)
4089 pCtrlStck->SetAttr(*pPaM->GetPoint(), RES_UL_SPACE);
4090 return;
4093 if (*pData)
4095 SvxULSpaceItem aUL(*(const SvxULSpaceItem*)GetFmtAttr(RES_UL_SPACE));
4096 aUL.SetLower(GetParagraphAutoSpace(pWDop->fDontUseHTMLAutoSpacing));
4097 NewAttr(aUL);
4098 if (pAktColl && nAktColl < vColl.size())
4099 vColl[nAktColl].bParaAutoAfter = true;
4100 else
4101 bParaAutoAfter = true;
4103 else
4105 if (pAktColl && nAktColl < vColl.size())
4106 vColl[nAktColl].bParaAutoAfter = false;
4107 else
4108 bParaAutoAfter = false;
4112 // Sprm 21, 22
4113 void SwWW8ImplReader::Read_UL( sal_uInt16 nId, const sal_uInt8* pData, short nLen )
4115 // Nun eine Umpopelung eines WW-Fehlers: Bei nProduct == 0c03d wird
4116 // faelschlicherweise ein DyaAfter 240 ( delta y abstand after, amn.d.?b.)
4117 // im Style "Normal" eingefuegt, der
4118 // gar nicht da ist. Ueber das IniFlag WW8FL_NO_STY_DYA laesst sich dieses
4119 // Verhalten auch fuer andere WW-Versionen erzwingen
4120 // OSL_ENSURE( !bStyNormal || bWWBugNormal, "+Dieses Doc deutet evtl. auf einen
4121 // Fehler in der benutzten WW-Version hin. Wenn sich die Styles <Standard> bzw.
4122 // <Normal> zwischen WW und SW im Absatz- oder Zeilenabstand unterscheiden,
4123 // dann bitte dieses Doc SH zukommen lassen." );
4124 // bWWBugNormal ist kein hinreichendes Kriterium dafuer, dass der
4125 // angegebene Abstand falsch ist
4127 if( nLen < 0 )
4129 // Ende des Attributes
4130 pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_UL_SPACE );
4131 return;
4133 short nPara = SVBT16ToShort( pData );
4134 if( nPara < 0 )
4135 nPara = -nPara;
4137 SvxULSpaceItem aUL( *(const SvxULSpaceItem*)GetFmtAttr( RES_UL_SPACE ));
4139 switch( nId )
4141 //sprmPDyaBefore
4142 case 21:
4143 case 0xA413:
4144 aUL.SetUpper( nPara );
4145 break;
4146 //sprmPDyaAfter
4147 case 22:
4148 case 0xA414:
4149 aUL.SetLower( nPara );
4150 break;
4151 default:
4152 return;
4155 NewAttr( aUL );
4158 void SwWW8ImplReader::Read_ParaContextualSpacing( sal_uInt16, const sal_uInt8* pData, short nLen )
4160 if( nLen < 0 )
4162 pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_UL_SPACE );
4163 return;
4165 SvxULSpaceItem aUL( *(const SvxULSpaceItem*)GetFmtAttr( RES_UL_SPACE ));
4166 aUL.SetContextValue(*pData);
4167 NewAttr( aUL );
4170 void SwWW8ImplReader::Read_IdctHint( sal_uInt16, const sal_uInt8* pData, short nLen )
4172 if (nLen < 0)
4173 nIdctHint = 0;
4174 else
4175 nIdctHint = *pData;
4178 void SwWW8ImplReader::Read_Justify( sal_uInt16, const sal_uInt8* pData, short nLen )
4180 if( nLen < 0 )
4182 pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_PARATR_ADJUST );
4183 return;
4186 SvxAdjust eAdjust(SVX_ADJUST_LEFT);
4187 bool bDistributed = false;
4188 switch (*pData)
4190 default:
4191 case 0:
4192 break;
4193 case 1:
4194 eAdjust = SVX_ADJUST_CENTER;
4195 break;
4196 case 2:
4197 eAdjust = SVX_ADJUST_RIGHT;
4198 break;
4199 case 3:
4200 eAdjust = SVX_ADJUST_BLOCK;
4201 break;
4202 case 4:
4203 eAdjust = SVX_ADJUST_BLOCK;
4204 bDistributed = true;
4205 break;
4207 SvxAdjustItem aAdjust(eAdjust, RES_PARATR_ADJUST);
4208 if (bDistributed)
4209 aAdjust.SetLastBlock(SVX_ADJUST_BLOCK);
4211 NewAttr(aAdjust);
4214 bool SwWW8ImplReader::IsRightToLeft()
4216 bool bRTL = false;
4217 const sal_uInt8 *pDir =
4218 pPlcxMan ? pPlcxMan->GetPapPLCF()->HasSprm(0x2441) : 0;
4219 if (pDir)
4220 bRTL = *pDir ? true : false;
4221 else
4223 const SvxFrameDirectionItem* pItem=
4224 (const SvxFrameDirectionItem*)GetFmtAttr(RES_FRAMEDIR);
4225 if (pItem && (pItem->GetValue() == FRMDIR_HORI_RIGHT_TOP))
4226 bRTL = true;
4228 return bRTL;
4231 void SwWW8ImplReader::Read_RTLJustify( sal_uInt16, const sal_uInt8* pData, short nLen )
4233 if( nLen < 0 )
4235 pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_PARATR_ADJUST );
4236 return;
4239 //If we are in a ltr paragraph this is the same as normal Justify,
4240 //If we are in a rtl paragraph the meaning is reversed.
4241 if (!IsRightToLeft())
4242 Read_Justify(0x2403 /*dummy*/, pData, nLen);
4243 else
4245 SvxAdjust eAdjust(SVX_ADJUST_RIGHT);
4246 bool bDistributed = false;
4247 switch (*pData)
4249 default:
4250 case 0:
4251 break;
4252 case 1:
4253 eAdjust = SVX_ADJUST_CENTER;
4254 break;
4255 case 2:
4256 eAdjust = SVX_ADJUST_LEFT;
4257 break;
4258 case 3:
4259 eAdjust = SVX_ADJUST_BLOCK;
4260 break;
4261 case 4:
4262 eAdjust = SVX_ADJUST_BLOCK;
4263 bDistributed = true;
4264 break;
4266 SvxAdjustItem aAdjust(eAdjust, RES_PARATR_ADJUST);
4267 if (bDistributed)
4268 aAdjust.SetLastBlock(SVX_ADJUST_BLOCK);
4270 NewAttr(aAdjust);
4274 void SwWW8ImplReader::Read_BoolItem( sal_uInt16 nId, const sal_uInt8* pData, short nLen )
4276 switch( nId )
4278 case 0x2433:
4279 nId = RES_PARATR_FORBIDDEN_RULES;
4280 break;
4281 case 0x2435:
4282 nId = RES_PARATR_HANGINGPUNCTUATION;
4283 break;
4284 case 0x2437:
4285 nId = RES_PARATR_SCRIPTSPACE;
4286 break;
4287 default:
4288 OSL_ENSURE( !this, "wrong Id" );
4289 return ;
4292 if( nLen < 0 )
4293 pCtrlStck->SetAttr( *pPaM->GetPoint(), nId );
4294 else
4296 SfxBoolItem* pI = (SfxBoolItem*)GetDfltAttr( nId )->Clone();
4297 pI->SetValue( 0 != *pData );
4298 NewAttr( *pI );
4299 delete pI;
4303 void SwWW8ImplReader::Read_Emphasis( sal_uInt16, const sal_uInt8* pData, short nLen )
4305 if( nLen < 0 )
4306 pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_CHRATR_EMPHASIS_MARK );
4307 else
4309 LanguageType nLang;
4310 //Check to see if there is an up and coming cjk language property. If
4311 //there is use it, if there is not fall back to the currently set one.
4312 //Only the cjk language setting seems to matter to word, the western
4313 //one is ignored
4314 const sal_uInt8 *pLang =
4315 pPlcxMan ? pPlcxMan->GetChpPLCF()->HasSprm(0x486E) : 0;
4317 if (pLang)
4318 nLang = SVBT16ToShort( pLang );
4319 else
4321 nLang = ((const SvxLanguageItem *)
4322 GetFmtAttr(RES_CHRATR_CJK_LANGUAGE))->GetLanguage();
4325 sal_uInt16 nVal;
4326 switch( *pData )
4328 case 0:
4329 nVal = EMPHASISMARK_NONE;
4330 break;
4331 case 2:
4332 if (MsLangId::isKorean(nLang) || MsLangId::isTraditionalChinese(nLang))
4333 nVal = EMPHASISMARK_CIRCLE_ABOVE;
4334 else if (nLang == LANGUAGE_JAPANESE)
4335 nVal = EMPHASISMARK_SIDE_DOTS;
4336 else
4337 nVal = EMPHASISMARK_DOTS_BELOW;
4338 break;
4339 case 3:
4340 nVal = EMPHASISMARK_CIRCLE_ABOVE;
4341 break;
4342 case 4:
4343 nVal = EMPHASISMARK_DOTS_BELOW;
4344 break;
4345 case 1:
4346 if (MsLangId::isSimplifiedChinese(nLang))
4347 nVal = EMPHASISMARK_DOTS_BELOW;
4348 else
4349 nVal = EMPHASISMARK_DOTS_ABOVE;
4350 break;
4351 default:
4352 nVal = EMPHASISMARK_DOTS_ABOVE;
4353 break;
4356 NewAttr( SvxEmphasisMarkItem( nVal, RES_CHRATR_EMPHASIS_MARK ) );
4360 void SwWW8ImplReader::Read_ScaleWidth( sal_uInt16, const sal_uInt8* pData, short nLen )
4362 if( nLen < 0 )
4363 pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_CHRATR_SCALEW );
4364 else
4366 sal_uInt16 nVal = SVBT16ToShort( pData );
4367 //The number must be between 1 and 600
4368 if (nVal < 1 || nVal > 600)
4369 nVal = 100;
4370 NewAttr( SvxCharScaleWidthItem( nVal, RES_CHRATR_SCALEW ) );
4374 void SwWW8ImplReader::Read_Relief( sal_uInt16 nId, const sal_uInt8* pData, short nLen )
4376 if( nLen < 0 )
4377 pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_CHRATR_RELIEF );
4378 else
4380 if( *pData )
4382 // not so eays because this is also a toggle attribute!
4383 // 2 x emboss on -> no emboss !!!
4384 // the actual value must be searched over the stack / template
4386 const SvxCharReliefItem* pOld = (const SvxCharReliefItem*)
4387 GetFmtAttr( RES_CHRATR_RELIEF );
4388 FontRelief nNewValue = 0x854 == nId ? RELIEF_ENGRAVED
4389 : ( 0x858 == nId ? RELIEF_EMBOSSED
4390 : RELIEF_NONE );
4391 if( pOld->GetValue() == nNewValue )
4393 if( RELIEF_NONE != nNewValue )
4394 nNewValue = RELIEF_NONE;
4396 NewAttr( SvxCharReliefItem( nNewValue, RES_CHRATR_RELIEF ));
4401 void SwWW8ImplReader::Read_TxtAnim(sal_uInt16 /*nId*/, const sal_uInt8* pData, short nLen)
4403 if (nLen < 0)
4404 pCtrlStck->SetAttr(*pPaM->GetPoint(), RES_CHRATR_BLINK);
4405 else
4407 if (*pData)
4409 bool bBlink;
4411 // The 7 animated text effects available in word all get
4412 // mapped to a blinking text effect in StarOffice
4413 // 0 no animation 1 Las Vegas lights
4414 // 2 background blink 3 sparkle text
4415 // 4 marching ants 5 marchine red ants
4416 // 6 shimmer
4417 if (*pData > 0 && *pData < 7 )
4418 bBlink = true;
4419 else
4420 bBlink = false;
4422 NewAttr(SvxBlinkItem(bBlink, RES_CHRATR_BLINK));
4427 SwWW8Shade::SwWW8Shade(bool bVer67, const WW8_SHD& rSHD)
4429 sal_uInt8 b = rSHD.GetFore();
4430 OSL_ENSURE(b < 17, "ww8: colour out of range");
4431 if (b >= 17)
4432 b = 0;
4434 ColorData nFore(SwWW8ImplReader::GetCol(b));
4436 b = rSHD.GetBack();
4437 OSL_ENSURE(b < 17, "ww8: colour out of range");
4438 if( b >= 17 )
4439 b = 0;
4441 ColorData nBack(SwWW8ImplReader::GetCol(b));
4443 b = rSHD.GetStyle(bVer67);
4445 SetShade(nFore, nBack, b);
4448 void SwWW8Shade::SetShade(ColorData nFore, ColorData nBack, sal_uInt16 nIndex)
4450 static const sal_uLong eMSGrayScale[] =
4452 // Nul-Brush
4453 0, // 0
4454 // Solid-Brush
4455 1000, // 1
4456 // promillemaessig abgestufte Schattierungen
4457 50, // 2
4458 100, // 3
4459 200, // 4
4460 250, // 5
4461 300, // 6
4462 400, // 7
4463 500, // 8
4464 600, // 9
4465 700, // 10
4466 750, // 11
4467 800, // 12
4468 900, // 13
4469 333, // 14 Dark Horizontal
4470 333, // 15 Dark Vertical
4471 333, // 16 Dark Forward Diagonal
4472 333, // 17 Dark Backward Diagonal
4473 333, // 18 Dark Cross
4474 333, // 19 Dark Diagonal Cross
4475 333, // 20 Horizontal
4476 333, // 21 Vertical
4477 333, // 22 Forward Diagonal
4478 333, // 23 Backward Diagonal
4479 333, // 24 Cross
4480 333, // 25 Diagonal Cross
4481 // neun Nummern ohne Bedeutung in Ver8
4482 500, // 26
4483 500, // 27
4484 500, // 28
4485 500, // 29
4486 500, // 30
4487 500, // 31
4488 500, // 32
4489 500, // 33
4490 500, // 34
4491 // und weiter gehts mit tollen Schattierungen ;-)
4492 25, // 35
4493 75, // 36
4494 125, // 37
4495 150, // 38
4496 175, // 39
4497 225, // 40
4498 275, // 41
4499 325, // 42
4500 350, // 43
4501 375, // 44
4502 425, // 45
4503 450, // 46
4504 475, // 47
4505 525, // 48
4506 550, // 49
4507 575, // 50
4508 625, // 51
4509 650, // 52
4510 675, // 53
4511 725, // 54
4512 775, // 55
4513 825, // 56
4514 850, // 57
4515 875, // 58
4516 925, // 59
4517 950, // 60
4518 975, // 61
4519 // und zu guter Letzt:
4521 };// 62
4524 //NO auto for shading so Foreground: Auto = Black
4525 if (nFore == COL_AUTO)
4526 nFore = COL_BLACK;
4528 //NO auto for shading so background: Auto = Weiss
4529 ColorData nUseBack = nBack;
4530 if (nUseBack == COL_AUTO)
4531 nUseBack = COL_WHITE;
4534 if( nIndex >= sizeof( eMSGrayScale ) / sizeof ( eMSGrayScale[ 0 ] ) )
4535 nIndex = 0;
4537 sal_uLong nWW8BrushStyle = eMSGrayScale[nIndex];
4539 switch (nWW8BrushStyle)
4541 case 0: // Null-Brush
4542 aColor.SetColor( nBack );
4543 break;
4544 default:
4546 Color aForeColor(nFore);
4547 Color aBackColor(nUseBack);
4549 sal_uInt32 nRed = aForeColor.GetRed() * nWW8BrushStyle;
4550 sal_uInt32 nGreen = aForeColor.GetGreen() * nWW8BrushStyle;
4551 sal_uInt32 nBlue = aForeColor.GetBlue() * nWW8BrushStyle;
4552 nRed += aBackColor.GetRed() * (1000L - nWW8BrushStyle);
4553 nGreen += aBackColor.GetGreen()* (1000L - nWW8BrushStyle);
4554 nBlue += aBackColor.GetBlue() * (1000L - nWW8BrushStyle);
4556 aColor.SetColor( RGB_COLORDATA( nRed/1000, nGreen/1000,
4557 nBlue/1000 ) );
4559 break;
4563 void SwWW8ImplReader::Read_Shade( sal_uInt16, const sal_uInt8* pData, short nLen )
4565 if (!bVer67 && pPlcxMan && pPlcxMan->GetPapPLCF()->HasSprm(0xC64D))
4566 return;
4568 if (nLen <= 0)
4570 // Ende des Attributes
4571 pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_BACKGROUND );
4572 if (bShdTxtCol)
4574 // Zeichenfarbe auch
4575 pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_CHRATR_COLOR );
4576 bShdTxtCol = false;
4579 else
4581 WW8_SHD aSHD;
4582 aSHD.SetWWValue( *(SVBT16*)pData );
4583 SwWW8Shade aSh( bVer67, aSHD );
4585 NewAttr(SvxBrushItem(aSh.aColor, RES_BACKGROUND));
4589 void SwWW8ImplReader::Read_ParaBackColor(sal_uInt16, const sal_uInt8* pData, short nLen)
4591 if (nLen <= 0)
4593 // Ende des Attributes
4594 pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_BACKGROUND );
4595 if (bShdTxtCol)
4597 // Zeichenfarbe auch
4598 pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_CHRATR_COLOR );
4599 bShdTxtCol = false;
4602 else
4604 OSL_ENSURE(nLen == 10, "Len of para back colour not 10!");
4605 if (nLen != 10)
4606 return;
4607 NewAttr(SvxBrushItem(Color(ExtractColour(pData, bVer67)), RES_BACKGROUND));
4611 sal_uInt32 SwWW8ImplReader::ExtractColour(const sal_uInt8* &rpData, bool bVer67)
4613 (void) bVer67; // unused in non-debug
4614 OSL_ENSURE(bVer67 == false, "Impossible");
4615 sal_uInt32 nFore = msfilter::util::BGRToRGB(SVBT32ToUInt32(rpData));
4616 rpData+=4;
4617 sal_uInt32 nBack = msfilter::util::BGRToRGB(SVBT32ToUInt32(rpData));
4618 rpData+=4;
4619 sal_uInt16 nIndex = SVBT16ToShort(rpData);
4620 rpData+=2;
4621 //Being a transparent background colour doesn't actually show the page
4622 //background through, it merely acts like white
4623 if (nBack == 0xFF000000)
4624 nBack = COL_AUTO;
4625 OSL_ENSURE(nBack == COL_AUTO || !(nBack & 0xFF000000),
4626 "ww8: don't know what to do with such a transparent bg colour, report");
4627 SwWW8Shade aShade(nFore, nBack, nIndex);
4628 return aShade.aColor.GetColor();
4631 void SwWW8ImplReader::Read_Border(sal_uInt16 , const sal_uInt8* , short nLen)
4633 if( nLen < 0 )
4635 if( bHasBorder )
4637 pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_BOX );
4638 pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_SHADOW );
4639 bHasBorder = false;
4642 else if( !bHasBorder )
4644 // die Borders auf allen 4 Seiten werden gebuendelt. dieses
4645 // vereinfacht die Verwaltung, d.h. die Box muss nicht 4 mal auf den
4646 // CtrlStack und wieder runter
4647 bHasBorder = true;
4649 WW8_BRC5 aBrcs; // Top, Left, Bottom, Right, Between
4650 sal_uInt8 nBorder;
4652 if( pAktColl )
4653 nBorder = ::lcl_ReadBorders(bVer67, aBrcs, 0, pStyles);
4654 else
4655 nBorder = ::lcl_ReadBorders(bVer67, aBrcs, pPlcxMan ? pPlcxMan->GetPapPLCF() : NULL);
4657 if( nBorder ) // Border
4659 bool bIsB = IsBorder(aBrcs, true);
4660 if (!InLocalApo() || !bIsB ||
4661 (pWFlyPara && !pWFlyPara->bBorderLines ))
4663 // in Apo keine Umrandungen *ein*-schalten, da ich
4664 // sonst die Flyumrandungen doppelt bekomme
4665 // aber nur wenn am Fly ein gesetzt ist, keine
4666 // uebernehmen. Sonst wird gar keine gesetzt!
4668 // auch wenn kein Rand gesetzt ist, muss das Attribut gesetzt
4669 // werden, sonst ist kein hartes Ausschalten von Style-Attrs
4670 // moeglich
4671 const SvxBoxItem* pBox
4672 = (const SvxBoxItem*)GetFmtAttr( RES_BOX );
4673 SvxBoxItem aBox(RES_BOX);
4674 if (pBox)
4675 aBox = *pBox;
4676 short aSizeArray[5]={0};
4678 SetBorder(aBox, aBrcs, &aSizeArray[0], nBorder);
4680 Rectangle aInnerDist;
4681 GetBorderDistance( aBrcs, aInnerDist );
4683 if ((nBorder & WW8_LEFT)==WW8_LEFT)
4684 aBox.SetDistance( (sal_uInt16)aInnerDist.Left(), BOX_LINE_LEFT );
4686 if ((nBorder & WW8_TOP)==WW8_TOP)
4687 aBox.SetDistance( (sal_uInt16)aInnerDist.Top(), BOX_LINE_TOP );
4689 if ((nBorder & WW8_RIGHT)==WW8_RIGHT)
4690 aBox.SetDistance( (sal_uInt16)aInnerDist.Right(), BOX_LINE_RIGHT );
4692 if ((nBorder & WW8_BOT)==WW8_BOT)
4693 aBox.SetDistance( (sal_uInt16)aInnerDist.Bottom(), BOX_LINE_BOTTOM );
4695 NewAttr( aBox );
4697 SvxShadowItem aS(RES_SHADOW);
4698 if( SetShadow( aS, &aSizeArray[0], aBrcs ) )
4699 NewAttr( aS );
4705 void SwWW8ImplReader::Read_Hyphenation( sal_uInt16, const sal_uInt8* pData, short nLen )
4707 // set Hyphenation flag
4708 if( nLen <= 0 )
4709 pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_PARATR_HYPHENZONE );
4710 else
4712 SvxHyphenZoneItem aAttr(
4713 *(const SvxHyphenZoneItem*)GetFmtAttr( RES_PARATR_HYPHENZONE ) );
4715 aAttr.SetHyphen( 0 == *pData ); // sic !
4717 if( !*pData )
4719 aAttr.GetMinLead() = 2;
4720 aAttr.GetMinTrail() = 2;
4721 aAttr.GetMaxHyphens() = 0;
4724 NewAttr( aAttr );
4728 void SwWW8ImplReader::Read_WidowControl( sal_uInt16, const sal_uInt8* pData, short nLen )
4730 if( nLen <= 0 )
4732 pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_PARATR_WIDOWS );
4733 pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_PARATR_ORPHANS );
4735 else
4737 sal_uInt8 nL = ( *pData & 1 ) ? 2 : 0;
4739 NewAttr( SvxWidowsItem( nL, RES_PARATR_WIDOWS ) ); // Aus -> nLines = 0
4740 NewAttr( SvxOrphansItem( nL, RES_PARATR_ORPHANS ) );
4742 if( pAktColl && pStyles ) // Style-Def ?
4743 pStyles->bWidowsChanged = true; // merken zur Simulation
4744 // Default-Widows
4748 void SwWW8ImplReader::Read_UsePgsuSettings(sal_uInt16,const sal_uInt8* pData,short nLen)
4750 if( nLen <= 0 )
4751 pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_PARATR_SNAPTOGRID);
4752 else
4754 if(nInTable)
4755 NewAttr( SvxParaGridItem(false, RES_PARATR_SNAPTOGRID) );
4756 else
4757 NewAttr( SvxParaGridItem(*pData, RES_PARATR_SNAPTOGRID) );
4761 void SwWW8ImplReader::Read_AlignFont( sal_uInt16, const sal_uInt8* pData, short nLen )
4763 if( nLen <= 0 )
4764 pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_PARATR_VERTALIGN);
4765 else
4767 sal_uInt16 nVal = SVBT16ToShort( pData );
4768 switch (nVal)
4770 case 0:
4771 nVal = SvxParaVertAlignItem::TOP;
4772 break;
4773 case 1:
4774 nVal = SvxParaVertAlignItem::CENTER;
4775 break;
4776 case 2:
4777 nVal = SvxParaVertAlignItem::BASELINE;
4778 break;
4779 case 3:
4780 nVal = SvxParaVertAlignItem::BOTTOM;
4781 break;
4782 case 4:
4783 nVal = SvxParaVertAlignItem::AUTOMATIC;
4784 break;
4785 default:
4786 nVal = SvxParaVertAlignItem::AUTOMATIC;
4787 OSL_ENSURE(!this,"Unknown paragraph vertical align");
4788 break;
4790 NewAttr( SvxParaVertAlignItem( nVal, RES_PARATR_VERTALIGN ) );
4794 void SwWW8ImplReader::Read_KeepLines( sal_uInt16, const sal_uInt8* pData, short nLen )
4796 if( nLen <= 0 )
4797 pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_PARATR_SPLIT );
4798 else
4799 NewAttr( SvxFmtSplitItem( ( *pData & 1 ) == 0, RES_PARATR_SPLIT ) );
4802 void SwWW8ImplReader::Read_KeepParas( sal_uInt16, const sal_uInt8* pData, short nLen )
4804 if( nLen <= 0 )
4805 pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_KEEP );
4806 else
4807 NewAttr( SvxFmtKeepItem( ( *pData & 1 ) != 0 , RES_KEEP) );
4810 void SwWW8ImplReader::Read_BreakBefore( sal_uInt16, const sal_uInt8* pData, short nLen )
4812 if( nLen <= 0 )
4813 pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_BREAK );
4814 else
4815 NewAttr( SvxFmtBreakItem(
4816 ( *pData & 1 ) ? SVX_BREAK_PAGE_BEFORE : SVX_BREAK_NONE, RES_BREAK ) );
4819 void SwWW8ImplReader::Read_ApoPPC( sal_uInt16, const sal_uInt8* pData, short )
4821 if (pAktColl && nAktColl < vColl.size()) // only for Styledef, sonst anders geloest
4823 SwWW8StyInf& rSI = vColl[nAktColl];
4824 WW8FlyPara* pFly = rSI.pWWFly ? rSI.pWWFly : new WW8FlyPara(bVer67);
4825 vColl[nAktColl].pWWFly = pFly;
4826 pFly->Read(*pData, pStyles);
4827 if (pFly->IsEmpty())
4828 delete vColl[nAktColl].pWWFly, vColl[nAktColl].pWWFly = 0;
4832 bool SwWW8ImplReader::ParseTabPos(WW8_TablePos *pTabPos, WW8PLCFx_Cp_FKP* pPap)
4834 bool bRet = false;
4835 const sal_uInt8 *pRes=0;
4836 memset(pTabPos, 0, sizeof(WW8_TablePos));
4837 if (0 != (pRes = pPap->HasSprm(0x360D)))
4839 pTabPos->nSp29 = *pRes;
4840 pTabPos->nSp37 = 2; //Possible fail area, always parallel wrap
4841 if (0 != (pRes = pPap->HasSprm(0x940E)))
4842 pTabPos->nSp26 = SVBT16ToShort(pRes);
4843 if (0 != (pRes = pPap->HasSprm(0x940F)))
4844 pTabPos->nSp27 = SVBT16ToShort(pRes);
4845 if (0 != (pRes = pPap->HasSprm(0x9410)))
4846 pTabPos->nLeMgn = SVBT16ToShort(pRes);
4847 if (0 != (pRes = pPap->HasSprm(0x941E)))
4848 pTabPos->nRiMgn = SVBT16ToShort(pRes);
4849 if (0 != (pRes = pPap->HasSprm(0x9411)))
4850 pTabPos->nUpMgn = SVBT16ToShort(pRes);
4851 if (0 != (pRes = pPap->HasSprm(0x941F)))
4852 pTabPos->nLoMgn = SVBT16ToShort(pRes);
4853 bRet = true;
4855 if (0 != (pRes = pPap->HasSprm(NS_sprm::LN_TDefTable)))
4857 WW8TabBandDesc aDesc;
4858 aDesc.ReadDef(false, pRes);
4859 int nTableWidth = aDesc.nCenter[aDesc.nWwCols] - aDesc.nCenter[0];
4860 int nTextAreaWidth = maSectionManager.GetTextAreaWidth();
4861 // If the table is wider than the text area, then don't create a fly
4862 // for the table: no wrapping will be performed anyway, but multi-page
4863 // tables will be broken.
4864 pTabPos->bNoFly = nTableWidth >= nTextAreaWidth;
4866 return bRet;
4869 /***************************************************************************
4870 # Seiten - Attribute werden nicht mehr als Attribute gehandhabt
4871 # ( ausser OLST )
4872 #**************************************************************************/
4875 long SwWW8ImplReader::ImportExtSprm(WW8PLCFManResult* pRes)
4877 /*************************************************************************
4878 # Arrays zum Lesen der erweiterten ( selbstdefinierten ) SPRMs
4879 #*************************************************************************/
4880 typedef long (SwWW8ImplReader:: *FNReadRecordExt)(WW8PLCFManResult*);
4882 static const FNReadRecordExt aWwSprmTab[] =
4884 /* 0 (256) */ &SwWW8ImplReader::Read_Ftn, // FootNote
4885 /* 1 (257) */ &SwWW8ImplReader::Read_Ftn, // EndNote
4886 /* 2 (258) */ &SwWW8ImplReader::Read_Field, // Feld
4887 /* 3 (259) */ &SwWW8ImplReader::Read_Book, // Bookmark
4888 /* 4 (260) */ &SwWW8ImplReader::Read_And // Annotation
4891 if( pRes->nSprmId < 280 )
4893 sal_uInt8 nIdx = static_cast< sal_uInt8 >(pRes->nSprmId - eFTN);
4894 if( nIdx < SAL_N_ELEMENTS(aWwSprmTab)
4895 && aWwSprmTab[nIdx] )
4896 return (this->*aWwSprmTab[nIdx])(pRes);
4897 else
4898 return 0;
4900 else
4901 return 0;
4904 void SwWW8ImplReader::EndExtSprm(sal_uInt16 nSprmId)
4906 typedef sal_uInt16 (SwWW8ImplReader:: *FNReadRecordExt)();
4908 static const FNReadRecordExt aWwSprmTab[] =
4910 /* 0 (256) */ &SwWW8ImplReader::End_Ftn, // FootNote
4911 /* 1 (257) */ &SwWW8ImplReader::End_Ftn, // EndNote
4912 /* 2 (258) */ &SwWW8ImplReader::End_Field, // Feld
4913 /* 3 (259) */ 0, // Bookmark
4914 /* 4 (260) */ 0 // Annotation
4917 sal_uInt8 nIdx = static_cast< sal_uInt8 >(nSprmId - eFTN);
4918 if( nIdx < SAL_N_ELEMENTS(aWwSprmTab)
4919 && aWwSprmTab[nIdx] )
4920 (this->*aWwSprmTab[nIdx])();
4923 /***************************************************************************
4924 # Arrays zum Lesen der SPRMs
4925 #**************************************************************************/
4927 // Funktion zum Einlesen von Sprms. Par1: SprmId
4928 typedef void (SwWW8ImplReader:: *FNReadRecord)( sal_uInt16, const sal_uInt8*, short );
4930 struct SprmReadInfo
4932 sal_uInt16 nId;
4933 FNReadRecord pReadFnc;
4936 bool operator==(const SprmReadInfo &rFirst, const SprmReadInfo &rSecond)
4938 return (rFirst.nId == rSecond.nId);
4941 bool operator<(const SprmReadInfo &rFirst, const SprmReadInfo &rSecond)
4943 return (rFirst.nId < rSecond.nId);
4946 typedef ww::SortedArray<SprmReadInfo> wwSprmDispatcher;
4948 const wwSprmDispatcher *GetWW2SprmDispatcher()
4950 static SprmReadInfo aSprms[] =
4952 {0, 0}, // "0" Default bzw. Error
4953 //wird uebersprungen! ,
4954 {2, &SwWW8ImplReader::Read_StyleCode}, //"sprmPIstd", pap.istd
4955 //(style code)
4956 {3, 0}, //"sprmPIstdPermute", pap.istd
4957 //permutation
4958 {4, 0}, //"sprmPIncLv1",
4959 //pap.istddifference
4960 {5, &SwWW8ImplReader::Read_Justify}, //"sprmPJc", pap.jc
4961 //(justification)
4962 {6, 0}, //"sprmPFSideBySide",
4963 //pap.fSideBySide
4964 {7, &SwWW8ImplReader::Read_KeepLines}, //"sprmPFKeep", pap.fKeep
4965 {8, &SwWW8ImplReader::Read_KeepParas}, //"sprmPFKeepFollow ",
4966 //pap.fKeepFollow
4967 {9, &SwWW8ImplReader::Read_BreakBefore}, //"sprmPPageBreakBefore",
4968 //pap.fPageBreakBefore
4969 {10, 0}, //"sprmPBrcl", pap.brcl
4970 {11, 0}, //"sprmPBrcp ", pap.brcp
4971 {12, &SwWW8ImplReader::Read_ANLevelDesc}, //"sprmPAnld", pap.anld (ANLD
4972 //structure)
4973 {13, &SwWW8ImplReader::Read_ANLevelNo}, //"sprmPNLvlAnm", pap.nLvlAnm
4974 //nn
4975 {14, &SwWW8ImplReader::Read_NoLineNumb}, //"sprmPFNoLineNumb", ap.fNoLnn
4976 {15, &SwWW8ImplReader::Read_Tab}, //"?sprmPChgTabsPapx",
4977 //pap.itbdMac, ...
4978 {16, &SwWW8ImplReader::Read_LR}, //"sprmPDxaRight", pap.dxaRight
4979 {17, &SwWW8ImplReader::Read_LR}, //"sprmPDxaLeft", pap.dxaLeft
4980 {18, 0}, //"sprmPNest", pap.dxaLeft
4981 {19, &SwWW8ImplReader::Read_LR}, //"sprmPDxaLeft1", pap.dxaLeft1
4982 {20, &SwWW8ImplReader::Read_LineSpace}, //"sprmPDyaLine", pap.lspd
4983 //an LSPD
4984 {21, &SwWW8ImplReader::Read_UL}, //"sprmPDyaBefore",
4985 //pap.dyaBefore
4986 {22, &SwWW8ImplReader::Read_UL}, //"sprmPDyaAfter", pap.dyaAfter
4987 {23, 0}, //"?sprmPChgTabs", pap.itbdMac,
4988 //pap.rgdxaTab, ...
4989 {24, 0}, //"sprmPFInTable", pap.fInTable
4990 {25, &SwWW8ImplReader::Read_TabRowEnd}, //"sprmPTtp", pap.fTtp
4991 {26, 0}, //"sprmPDxaAbs", pap.dxaAbs
4992 {27, 0}, //"sprmPDyaAbs", pap.dyaAbs
4993 {28, 0}, //"sprmPDxaWidth", pap.dxaWidth
4994 {29, &SwWW8ImplReader::Read_ApoPPC}, //"sprmPPc", pap.pcHorz,
4995 //pap.pcVert
4996 {30, 0}, //"sprmPBrcTop10", pap.brcTop
4997 //BRC10
4998 {31, 0}, //"sprmPBrcLeft10",
4999 //pap.brcLeft BRC10
5000 {32, 0}, //"sprmPBrcBottom10",
5001 //pap.brcBottom BRC10
5002 {33, 0}, //"sprmPBrcRight10",
5003 //pap.brcRight BRC10
5004 {34, 0}, //"sprmPBrcBetween10",
5005 //pap.brcBetween BRC10
5006 {35, 0}, //"sprmPBrcBar10", pap.brcBar
5007 //BRC10
5008 {36, 0}, //"sprmPFromText10",
5009 //pap.dxaFromText dxa
5010 {37, 0}, //"sprmPWr", pap.wr wr
5011 {38, &SwWW8ImplReader::Read_Border}, //"sprmPBrcTop", pap.brcTop BRC
5012 {39, &SwWW8ImplReader::Read_Border}, //"sprmPBrcLeft",
5013 //pap.brcLeft BRC
5014 {40, &SwWW8ImplReader::Read_Border}, //"sprmPBrcBottom",
5015 //pap.brcBottom BRC
5016 {41, &SwWW8ImplReader::Read_Border}, //"sprmPBrcRight",
5017 //pap.brcRight BRC
5018 {42, &SwWW8ImplReader::Read_Border}, //"sprmPBrcBetween",
5019 //pap.brcBetween BRC
5020 {43, 0}, //"sprmPBrcBar", pap.brcBar
5021 //BRC word
5022 {44, &SwWW8ImplReader::Read_Hyphenation}, //"sprmPFNoAutoHyph",
5023 //pap.fNoAutoHyph
5024 {45, 0}, //"sprmPWHeightAbs",
5025 //pap.wHeightAbs w
5026 {46, 0}, //"sprmPDcs", pap.dcs DCS
5027 {47, &SwWW8ImplReader::Read_Shade}, //"sprmPShd", pap.shd SHD
5028 {48, 0}, //"sprmPDyaFromText",
5029 //pap.dyaFromText dya
5030 {49, 0}, //"sprmPDxaFromText",
5031 //pap.dxaFromText dxa
5032 {50, 0}, //"sprmPFLocked", pap.fLocked
5033 //0 or 1 byte
5034 {51, &SwWW8ImplReader::Read_WidowControl}, //"sprmPFWidowControl",
5035 //pap.fWidowControl 0 or 1 byte
5036 {52, 0}, //"?sprmPRuler 52",
5037 {53, 0}, //"??53",
5038 {54, 0}, //"??54",
5039 {55, 0}, //"??55",
5040 {56, 0}, //"??56",
5041 {57, 0}, //"??57",
5042 {58, 0}, //"??58",
5043 {59, 0}, //"??59",
5045 {60, &SwWW8ImplReader::Read_BoldUsw}, //"sprmCFBold", chp.fBold 0,1,
5046 //128, or 129 byte
5047 {61, &SwWW8ImplReader::Read_BoldUsw}, //"sprmCFItalic", chp.fItalic
5048 //0,1, 128, or 129 byte
5049 {62, &SwWW8ImplReader::Read_BoldUsw}, //"sprmCFStrike", chp.fStrike
5050 //0,1, 128, or 129 byte
5051 {63, &SwWW8ImplReader::Read_BoldUsw}, //"sprmCFOutline", chp.fOutline
5052 //0,1, 128, or 129 byte
5053 {64, &SwWW8ImplReader::Read_BoldUsw}, //"sprmCFShadow", chp.fShadow
5054 //0,1, 128, or 129 byte
5055 {65, &SwWW8ImplReader::Read_BoldUsw}, //"sprmCFSmallCaps",
5056 //chp.fSmallCaps 0,1, 128, or
5057 //129 byte
5058 {66, &SwWW8ImplReader::Read_BoldUsw}, //"sprmCFCaps", chp.fCaps 0,1,
5059 //128, or 129 byte
5060 {67, &SwWW8ImplReader::Read_BoldUsw}, //"sprmCFVanish", chp.fVanish
5061 //0,1, 128, or 129 byte
5062 {68, &SwWW8ImplReader::Read_FontCode}, //"sprmCFtc", chp.ftc ftc word
5063 {69, &SwWW8ImplReader::Read_Underline}, // "sprmCKul", chp.kul kul byte
5064 {70, 0}, //"sprmCSizePos", chp.hps,
5065 //chp.hpsPos 3 bytes
5066 {71, &SwWW8ImplReader::Read_Kern}, //"sprmCDxaSpace",
5067 //chp.dxaSpace dxa word
5068 {72, &SwWW8ImplReader::Read_Language}, //"sprmCLid", chp.lid LID word
5069 {73, &SwWW8ImplReader::Read_TxtColor}, //"sprmCIco", chp.ico ico byte
5070 {74, &SwWW8ImplReader::Read_FontSize}, //"sprmCHps", chp.hps hps word!
5071 {75, 0}, //"sprmCHpsInc", chp.hps byte
5072 {76, &SwWW8ImplReader::Read_SubSuperProp}, //"sprmCHpsPos", chp.hpsPos
5073 //hps byte
5074 {77, 0}, //"sprmCHpsPosAdj", chp.hpsPos
5075 //hps byte
5076 {78, &SwWW8ImplReader::Read_Majority}, //"?sprmCMajority", chp.fBold,
5077 //chp.fItalic, chp.fSmallCaps
5078 {80, &SwWW8ImplReader::Read_BoldBiDiUsw}, //sprmCFBoldBi
5079 {81, &SwWW8ImplReader::Read_BoldBiDiUsw}, //sprmCFItalicBi
5080 {82, &SwWW8ImplReader::Read_FontCode}, //sprmCFtcBi
5081 {83, &SwWW8ImplReader::Read_Language}, //sprmClidBi
5082 {84, &SwWW8ImplReader::Read_TxtColor}, //sprmCIcoBi
5083 {85, &SwWW8ImplReader::Read_FontSize}, //sprmCHpsBi
5084 {86, 0}, //sprmCFBiDi
5085 {87, 0}, //sprmCFDiacColor
5086 {94, 0}, //"sprmPicBrcl", pic.brcl brcl
5087 //(see PIC structure
5088 //definition) byte
5089 {95, 0}, //"sprmPicScale", pic.mx,
5090 //pic.my, pic.dxaCropleft,
5091 {96, 0}, //"sprmPicBrcTop", pic.brcTop
5092 //BRC word
5093 {97, 0}, //"sprmPicBrcLeft",
5094 //pic.brcLeft BRC word
5095 {98, 0}, //"sprmPicBrcBottom",
5096 //pic.brcBottom BRC word
5097 {99, 0} //"sprmPicBrcRight",
5100 static wwSprmDispatcher aSprmSrch(aSprms, sizeof(aSprms) / sizeof(aSprms[0]));
5101 return &aSprmSrch;
5104 const wwSprmDispatcher *GetWW6SprmDispatcher()
5106 static SprmReadInfo aSprms[] =
5108 {0, 0}, // "0" Default bzw. Error
5109 //wird uebersprungen! ,
5110 {2, &SwWW8ImplReader::Read_StyleCode}, //"sprmPIstd", pap.istd
5111 //(style code)
5112 {3, 0}, //"sprmPIstdPermute", pap.istd
5113 //permutation
5114 {4, 0}, //"sprmPIncLv1",
5115 //pap.istddifference
5116 {5, &SwWW8ImplReader::Read_Justify}, //"sprmPJc", pap.jc
5117 //(justification)
5118 {6, 0}, //"sprmPFSideBySide",
5119 //pap.fSideBySide
5120 {7, &SwWW8ImplReader::Read_KeepLines}, //"sprmPFKeep", pap.fKeep
5121 {8, &SwWW8ImplReader::Read_KeepParas}, //"sprmPFKeepFollow ",
5122 //pap.fKeepFollow
5123 {9, &SwWW8ImplReader::Read_BreakBefore}, //"sprmPPageBreakBefore",
5124 //pap.fPageBreakBefore
5125 {10, 0}, //"sprmPBrcl", pap.brcl
5126 {11, 0}, //"sprmPBrcp ", pap.brcp
5127 {12, &SwWW8ImplReader::Read_ANLevelDesc}, //"sprmPAnld", pap.anld (ANLD
5128 //structure)
5129 {13, &SwWW8ImplReader::Read_ANLevelNo}, //"sprmPNLvlAnm", pap.nLvlAnm
5130 //nn
5131 {14, &SwWW8ImplReader::Read_NoLineNumb}, //"sprmPFNoLineNumb", ap.fNoLnn
5132 {15, &SwWW8ImplReader::Read_Tab}, //"?sprmPChgTabsPapx",
5133 //pap.itbdMac, ...
5134 {16, &SwWW8ImplReader::Read_LR}, //"sprmPDxaRight", pap.dxaRight
5135 {17, &SwWW8ImplReader::Read_LR}, //"sprmPDxaLeft", pap.dxaLeft
5136 {18, 0}, //"sprmPNest", pap.dxaLeft
5137 {19, &SwWW8ImplReader::Read_LR}, //"sprmPDxaLeft1", pap.dxaLeft1
5138 {20, &SwWW8ImplReader::Read_LineSpace}, //"sprmPDyaLine", pap.lspd
5139 //an LSPD
5140 {21, &SwWW8ImplReader::Read_UL}, //"sprmPDyaBefore",
5141 //pap.dyaBefore
5142 {22, &SwWW8ImplReader::Read_UL}, //"sprmPDyaAfter", pap.dyaAfter
5143 {23, 0}, //"?sprmPChgTabs", pap.itbdMac,
5144 //pap.rgdxaTab, ...
5145 {24, 0}, //"sprmPFInTable", pap.fInTable
5146 {25, &SwWW8ImplReader::Read_TabRowEnd}, //"sprmPTtp", pap.fTtp
5147 {26, 0}, //"sprmPDxaAbs", pap.dxaAbs
5148 {27, 0}, //"sprmPDyaAbs", pap.dyaAbs
5149 {28, 0}, //"sprmPDxaWidth", pap.dxaWidth
5150 {29, &SwWW8ImplReader::Read_ApoPPC}, //"sprmPPc", pap.pcHorz,
5151 //pap.pcVert
5152 {30, 0}, //"sprmPBrcTop10", pap.brcTop
5153 //BRC10
5154 {31, 0}, //"sprmPBrcLeft10",
5155 //pap.brcLeft BRC10
5156 {32, 0}, //"sprmPBrcBottom10",
5157 //pap.brcBottom BRC10
5158 {33, 0}, //"sprmPBrcRight10",
5159 //pap.brcRight BRC10
5160 {34, 0}, //"sprmPBrcBetween10",
5161 //pap.brcBetween BRC10
5162 {35, 0}, //"sprmPBrcBar10", pap.brcBar
5163 //BRC10
5164 {36, 0}, //"sprmPFromText10",
5165 //pap.dxaFromText dxa
5166 {37, 0}, //"sprmPWr", pap.wr wr
5167 {38, &SwWW8ImplReader::Read_Border}, //"sprmPBrcTop", pap.brcTop BRC
5168 {39, &SwWW8ImplReader::Read_Border}, //"sprmPBrcLeft",
5169 //pap.brcLeft BRC
5170 {40, &SwWW8ImplReader::Read_Border}, //"sprmPBrcBottom",
5171 //pap.brcBottom BRC
5172 {41, &SwWW8ImplReader::Read_Border}, //"sprmPBrcRight",
5173 //pap.brcRight BRC
5174 {42, &SwWW8ImplReader::Read_Border}, //"sprmPBrcBetween",
5175 //pap.brcBetween BRC
5176 {43, 0}, //"sprmPBrcBar", pap.brcBar
5177 //BRC word
5178 {44, &SwWW8ImplReader::Read_Hyphenation}, //"sprmPFNoAutoHyph",
5179 //pap.fNoAutoHyph
5180 {45, 0}, //"sprmPWHeightAbs",
5181 //pap.wHeightAbs w
5182 {46, 0}, //"sprmPDcs", pap.dcs DCS
5183 {47, &SwWW8ImplReader::Read_Shade}, //"sprmPShd", pap.shd SHD
5184 {48, 0}, //"sprmPDyaFromText",
5185 //pap.dyaFromText dya
5186 {49, 0}, //"sprmPDxaFromText",
5187 //pap.dxaFromText dxa
5188 {50, 0}, //"sprmPFLocked", pap.fLocked
5189 //0 or 1 byte
5190 {51, &SwWW8ImplReader::Read_WidowControl}, //"sprmPFWidowControl",
5191 //pap.fWidowControl 0 or 1 byte
5192 {52, 0}, //"?sprmPRuler 52",
5193 {53, 0}, //"??53",
5194 {54, 0}, //"??54",
5195 {55, 0}, //"??55",
5196 {56, 0}, //"??56",
5197 {57, 0}, //"??57",
5198 {58, 0}, //"??58",
5199 {59, 0}, //"??59",
5200 {60, 0}, //"??60",
5201 {61, 0}, //"??61",
5202 {62, 0}, //"??62",
5203 {63, 0}, //"??63",
5204 {64, &SwWW8ImplReader::Read_ParaBiDi}, //"rtl bidi ?
5205 {65, &SwWW8ImplReader::Read_CFRMarkDel}, //"sprmCFStrikeRM",
5206 //chp.fRMarkDel 1 or 0 bit
5207 {66, &SwWW8ImplReader::Read_CFRMark}, //"sprmCFRMark", chp.fRMark
5208 //1 or 0 bit
5209 {67, &SwWW8ImplReader::Read_FldVanish}, //"sprmCFFldVanish",
5210 //chp.fFldVanish 1 or 0 bit
5211 {68, &SwWW8ImplReader::Read_PicLoc}, //"sprmCPicLocation",
5212 //chp.fcPic and chp.fSpec
5213 {69, 0}, //"sprmCIbstRMark",
5214 //chp.ibstRMark index into
5215 //sttbRMark
5216 {70, 0}, //"sprmCDttmRMark", chp.dttm
5217 //DTTM long
5218 {71, 0}, //"sprmCFData", chp.fData 1 or
5219 //0 bit
5220 {72, 0}, //"sprmCRMReason",
5221 //chp.idslRMReason an index to
5222 //a table
5223 {73, &SwWW8ImplReader::Read_CharSet}, //"sprmCChse", chp.fChsDiff
5224 //and chp.chse 3 bytes
5225 {74, &SwWW8ImplReader::Read_Symbol}, //"sprmCSymbol", chp.fSpec,
5226 //chp.chSym and chp.ftcSym
5227 {75, &SwWW8ImplReader::Read_Obj}, //"sprmCFOle2", chp.fOle2 1
5228 //or 0 bit
5229 {76, 0}, //"??76",
5230 {77, 0}, //"??77",
5231 {78, 0}, //"??78",
5232 {79, 0}, //"??79",
5233 {80, &SwWW8ImplReader::Read_CColl}, //"sprmCIstd", chp.istd istd,
5234 //see stylesheet definition
5235 //short
5236 {81, 0}, //"sprmCIstdPermute", chp.istd
5237 //permutation vector
5238 {82, 0}, //"sprmCDefault", whole CHP
5239 //none variable length
5240 {83, 0}, //"sprmCPlain", whole CHP
5241 //none 0
5242 {84, 0}, //"??84",
5243 {85, &SwWW8ImplReader::Read_BoldUsw}, //"sprmCFBold", chp.fBold 0,1,
5244 //128, or 129 byte
5245 {86, &SwWW8ImplReader::Read_BoldUsw}, //"sprmCFItalic", chp.fItalic
5246 //0,1, 128, or 129 byte
5247 {87, &SwWW8ImplReader::Read_BoldUsw}, //"sprmCFStrike", chp.fStrike
5248 //0,1, 128, or 129 byte
5249 {88, &SwWW8ImplReader::Read_BoldUsw}, //"sprmCFOutline", chp.fOutline
5250 //0,1, 128, or 129 byte
5251 {89, &SwWW8ImplReader::Read_BoldUsw}, //"sprmCFShadow", chp.fShadow
5252 //0,1, 128, or 129 byte
5253 {90, &SwWW8ImplReader::Read_BoldUsw}, //"sprmCFSmallCaps",
5254 //chp.fSmallCaps 0,1, 128, or
5255 //129 byte
5256 {91, &SwWW8ImplReader::Read_BoldUsw}, //"sprmCFCaps", chp.fCaps 0,1,
5257 //128, or 129 byte
5258 {92, &SwWW8ImplReader::Read_BoldUsw}, //"sprmCFVanish", chp.fVanish
5259 //0,1, 128, or 129 byte
5260 {93, &SwWW8ImplReader::Read_FontCode}, //"sprmCFtc", chp.ftc ftc word
5261 {94, &SwWW8ImplReader::Read_Underline}, // "sprmCKul", chp.kul kul byte
5262 {95, 0}, //"sprmCSizePos", chp.hps,
5263 //chp.hpsPos 3 bytes
5264 {96, &SwWW8ImplReader::Read_Kern}, //"sprmCDxaSpace",
5265 //chp.dxaSpace dxa word
5266 {97, &SwWW8ImplReader::Read_Language}, //"sprmCLid", chp.lid LID word
5267 {98, &SwWW8ImplReader::Read_TxtColor}, //"sprmCIco", chp.ico ico byte
5268 {99, &SwWW8ImplReader::Read_FontSize}, //"sprmCHps", chp.hps hps word!
5269 {100, 0}, //"sprmCHpsInc", chp.hps byte
5270 {101, &SwWW8ImplReader::Read_SubSuperProp}, //"sprmCHpsPos", chp.hpsPos
5271 //hps byte
5272 {102, 0}, //"sprmCHpsPosAdj", chp.hpsPos
5273 //hps byte
5274 {103, &SwWW8ImplReader::Read_Majority}, //"?sprmCMajority", chp.fBold,
5275 //chp.fItalic, chp.fSmallCaps
5276 {104, &SwWW8ImplReader::Read_SubSuper}, //"sprmCIss", chp.iss iss byte
5277 {105, 0}, //"sprmCHpsNew50", chp.hps hps
5278 //variable width, length
5279 //always recorded as 2
5280 {106, 0}, //"sprmCHpsInc1", chp.hps
5281 //complex variable width,
5282 //length always recorded as 2
5283 {107, &SwWW8ImplReader::Read_FontKern}, //"sprmCHpsKern", chp.hpsKern
5284 //hps short
5285 {108, &SwWW8ImplReader::Read_Majority}, //"sprmCMajority50", chp.fBold,
5286 //chp.fItalic, chp.fSmallCaps,
5287 // chp.fVanish, ...
5288 {109, 0}, //"sprmCHpsMul", chp.hps
5289 //percentage to grow hps short
5290 {110, 0}, //"sprmCCondHyhen", chp.ysri
5291 //ysri short
5292 {111, &SwWW8ImplReader::Read_FontCode}, //ww7 font
5293 {112, &SwWW8ImplReader::Read_FontCode}, //ww7 CJK font
5294 {113, &SwWW8ImplReader::Read_FontCode}, //ww7 rtl font
5295 {114, &SwWW8ImplReader::Read_Language}, //ww7 lid
5296 {115, &SwWW8ImplReader::Read_TxtColor}, //ww7 rtl colour ?
5297 {116, &SwWW8ImplReader::Read_FontSize},
5298 {117, &SwWW8ImplReader::Read_Special}, //"sprmCFSpec", chp.fSpec 1
5299 //or 0 bit
5300 {118, &SwWW8ImplReader::Read_Obj}, //"sprmCFObj", chp.fObj 1 or 0
5301 //bit
5302 {119, 0}, //"sprmPicBrcl", pic.brcl brcl
5303 //(see PIC structure
5304 //definition) byte
5305 {120, 0}, //"sprmPicScale", pic.mx,
5306 //pic.my, pic.dxaCropleft,
5307 {121, 0}, //"sprmPicBrcTop", pic.brcTop
5308 //BRC word
5309 {122, 0}, //"sprmPicBrcLeft",
5310 //pic.brcLeft BRC word
5311 {123, 0}, //"sprmPicBrcBottom",
5312 //pic.brcBottom BRC word
5313 {124, 0}, //"sprmPicBrcRight",
5314 //pic.brcRight BRC word
5315 {125, 0}, //"??125",
5316 {126, 0}, //"??126",
5317 {127, 0}, //"??127",
5318 {128, 0}, //"??128",
5319 {129, 0}, //"??129",
5320 {130, 0}, //"??130",
5321 {131, 0}, //"sprmSScnsPgn", sep.cnsPgn
5322 //cns byte
5323 {132, 0}, //"sprmSiHeadingPgn",
5324 //sep.iHeadingPgn heading
5325 //number level byte
5326 {133, &SwWW8ImplReader::Read_OLST}, //"sprmSOlstAnm", sep.olstAnm
5327 //OLST variable length
5328 {134, 0}, //"??135",
5329 {135, 0}, //"??135",
5330 {136, 0}, //"sprmSDxaColWidth",
5331 //sep.rgdxaColWidthSpacing
5332 //complex 3 bytes
5333 {137, 0}, //"sprmSDxaColSpacing",
5334 //sep.rgdxaColWidthSpacing
5335 //complex 3 bytes
5336 {138, 0}, //"sprmSFEvenlySpaced",
5337 //sep.fEvenlySpaced 1 or 0 byte
5338 {139, 0}, //"sprmSFProtected",
5339 //sep.fUnlocked 1 or 0 byte
5340 {140, 0}, //"sprmSDmBinFirst",
5341 //sep.dmBinFirst word
5342 {141, 0}, //"sprmSDmBinOther",
5343 //sep.dmBinOther word
5344 {142, 0}, //"sprmSBkc", sep.bkc bkc
5345 //byte BreakCode
5346 {143, 0}, //"sprmSFTitlePage",
5347 //sep.fTitlePage 0 or 1 byte
5348 {144, 0}, //"sprmSCcolumns", sep.ccolM1
5349 //# of cols - 1 word
5350 {145, 0}, //"sprmSDxaColumns",
5351 //sep.dxaColumns dxa word
5352 {146, 0}, //"sprmSFAutoPgn",
5353 //sep.fAutoPgn obsolete byte
5354 {147, 0}, //"sprmSNfcPgn", sep.nfcPgn
5355 //nfc byte
5356 {148, 0}, //"sprmSDyaPgn", sep.dyaPgn
5357 //dya short
5358 {149, 0}, //"sprmSDxaPgn", sep.dxaPgn
5359 //dya short
5360 {150, 0}, //"sprmSFPgnRestart",
5361 //sep.fPgnRestart 0 or 1 byte
5362 {151, 0}, //"sprmSFEndnote", sep.fEndnote
5363 //0 or 1 byte
5364 {152, 0}, //"sprmSLnc", sep.lnc lnc byte
5365 {153, 0}, //"sprmSGprfIhdt", sep.grpfIhdt
5366 //grpfihdt byte
5367 {154, 0}, //"sprmSNLnnMod", sep.nLnnMod
5368 //non-neg int. word
5369 {155, 0}, //"sprmSDxaLnn", sep.dxaLnn
5370 //dxa word
5371 {156, 0}, //"sprmSDyaHdrTop",
5372 //sep.dyaHdrTop dya word
5373 {157, 0}, //"sprmSDyaHdrBottom",
5374 //sep.dyaHdrBottom dya word
5375 {158, 0}, //"sprmSLBetween",
5376 //sep.fLBetween 0 or 1 byte
5377 {159, 0}, //"sprmSVjc", sep.vjc vjc byte
5378 {160, 0}, //"sprmSLnnMin", sep.lnnMin
5379 //lnn word
5380 {161, 0}, //"sprmSPgnStart", sep.pgnStart
5381 //pgn word
5382 {162, 0}, //"sprmSBOrientation",
5383 //sep.dmOrientPage dm byte
5384 {163, 0}, //"?SprmSBCustomize 163", ?
5385 {164, 0}, //"sprmSXaPage", sep.xaPage xa
5386 //word
5387 {165, 0}, //"sprmSYaPage", sep.yaPage ya
5388 //word
5389 {166, 0}, //"sprmSDxaLeft", sep.dxaLeft
5390 //dxa word
5391 {167, 0}, //"sprmSDxaRight", sep.dxaRight
5392 //dxa word
5393 {168, 0}, //"sprmSDyaTop", sep.dyaTop //dya word
5394 {169, 0}, //"sprmSDyaBottom",
5395 //sep.dyaBottom dya word
5396 {170, 0}, //"sprmSDzaGutter",
5397 //sep.dzaGutter dza word
5398 {171, 0}, //"sprmSDMPaperReq",
5399 //sep.dmPaperReq dm word
5400 {172, 0}, //"??172",
5401 {173, 0}, //"??173",
5402 {174, 0}, //"??174",
5403 {175, 0}, //"??175",
5404 {176, 0}, //"??176",
5405 {177, 0}, //"??177",
5406 {178, 0}, //"??178",
5407 {179, 0}, //"??179",
5408 {180, 0}, //"??180",
5409 {181, 0}, //"??181",
5410 {182, 0}, //"sprmTJc", tap.jc jc word
5411 //(low order byte is
5412 //significant)
5413 {183, 0}, //"sprmTDxaLeft",
5414 //tap.rgdxaCenter dxa word
5415 {184, 0}, //"sprmTDxaGapHalf",
5416 //tap.dxaGapHalf,
5417 //tap.rgdxaCenter dxa word
5418 {185, 0}, //"sprmTFCantSplit"
5419 //tap.fCantSplit 1 or 0 byte
5420 {186, 0}, //"sprmTTableHeader",
5421 //tap.fTableHeader 1 or 0 byte
5422 {187, 0}, //"sprmTTableBorders",
5423 //tap.rgbrcTable complex
5424 //12 bytes
5425 {188, 0}, //"sprmTDefTable10",
5426 //tap.rgdxaCenter, tap.rgtc
5427 //complex variable length
5428 {189, 0}, //"sprmTDyaRowHeight",
5429 //tap.dyaRowHeight dya word
5430 {190, 0}, //"?sprmTDefTable", tap.rgtc
5431 //complex
5432 {191, 0}, //"?sprmTDefTableShd",
5433 //tap.rgshd complex
5434 {192, 0}, //"sprmTTlp", tap.tlp TLP
5435 //4 bytes
5436 {193, 0}, //"sprmTSetBrc",
5437 //tap.rgtc[].rgbrc complex
5438 //5 bytes
5439 {194, 0}, //"sprmTInsert",
5440 //tap.rgdxaCenter,
5441 //tap.rgtc complex 4 bytes
5442 {195, 0}, //"sprmTDelete",
5443 //tap.rgdxaCenter,
5444 //tap.rgtc complex word
5445 {196, 0}, //"sprmTDxaCol",
5446 //tap.rgdxaCenter complex
5447 //4 bytes
5448 {197, 0}, //"sprmTMerge",
5449 //tap.fFirstMerged,
5450 //tap.fMerged complex word
5451 {198, 0}, //"sprmTSplit",
5452 //tap.fFirstMerged,
5453 //tap.fMerged complex word
5454 {199, 0}, //"sprmTSetBrc10",
5455 //tap.rgtc[].rgbrc complex
5456 //5 bytes
5457 {200, 0}, //"sprmTSetShd", tap.rgshd
5458 //complex 4 bytes
5459 {207, 0}, //dunno
5462 static wwSprmDispatcher aSprmSrch(aSprms, sizeof(aSprms) / sizeof(aSprms[0]));
5463 return &aSprmSrch;
5466 const wwSprmDispatcher *GetWW8SprmDispatcher()
5468 static SprmReadInfo aSprms[] =
5470 {0, 0}, // "0" Default bzw. Error
5472 {0x4600, &SwWW8ImplReader::Read_StyleCode}, //"sprmPIstd" pap.istd;istd
5473 //(style code);short;
5474 {0xC601, 0}, //"sprmPIstdPermute" pap.istd;
5475 //permutation vector;
5476 //variable length;
5477 {0x2602, 0}, //"sprmPIncLvl" pap.istd,
5478 //pap.lvl;difference between
5479 //istd of base PAP and istd of
5480 //PAP to be produced; byte;
5481 {0x2403, &SwWW8ImplReader::Read_Justify}, //"sprmPJc" pap.jc;jc
5482 //(justification);byte;
5483 {0x2404, 0}, //"sprmPFSideBySide"
5484 //pap.fSideBySide;0 or 1;byte;
5485 {0x2405, &SwWW8ImplReader::Read_KeepLines}, //"sprmPFKeep" pap.fKeep;0 or
5486 //1;byte;
5487 {0x2406, &SwWW8ImplReader::Read_KeepParas}, //"sprmPFKeepFollow"
5488 //pap.fKeepFollow;0 or 1;byte;
5489 {0x2407, &SwWW8ImplReader::Read_BreakBefore},//"sprmPFPageBreakBefore"
5490 //pap.fPageBreakBefore;0 or 1;
5491 //byte;
5492 {0x2408, 0}, //"sprmPBrcl" pap.brcl;brcl;
5493 //byte;
5494 {0x2409, 0}, //"sprmPBrcp" pap.brcp;brcp;
5495 //byte;
5496 {0x260A, &SwWW8ImplReader::Read_ListLevel}, //"sprmPIlvl" pap.ilvl;ilvl;
5497 //byte;
5498 {0x460B, &SwWW8ImplReader::Read_LFOPosition},//"sprmPIlfo" pap.ilfo;ilfo
5499 //(list index) ;short;
5500 {0x240C, &SwWW8ImplReader::Read_NoLineNumb}, //"sprmPFNoLineNumb"
5501 //pap.fNoLnn;0 or 1;byte;
5502 {0xC60D, &SwWW8ImplReader::Read_Tab}, //"sprmPChgTabsPapx"
5503 //pap.itbdMac, pap.rgdxaTab,
5504 //pap.rgtbd;complex;variable
5505 //length
5506 {0x840E, &SwWW8ImplReader::Read_LR}, //Word 97 version of "sprmPDxaRight" pap.dxaRight;
5507 //dxa;word;
5508 {0x840F, &SwWW8ImplReader::Read_LR}, //Apparently Word 97 version of "sprmPDxaLeft" pap.dxaLeft;
5509 //dxa;word;
5510 {0x4610, 0}, //"sprmPNest" pap.dxaLeft;
5511 //dxa;word;
5512 {0x8411, &SwWW8ImplReader::Read_LR}, //Word 97 version of "sprmPDxaLeft1" pap.dxaLeft1;
5513 //dxa;word;
5514 {0x6412, &SwWW8ImplReader::Read_LineSpace}, //"sprmPDyaLine" pap.lspd;
5515 //an LSPD, a long word
5516 //structure consisting of a
5517 //short of dyaLine followed by
5518 //a short of fMultLinespace;
5519 //long;
5520 {0xA413, &SwWW8ImplReader::Read_UL}, //"sprmPDyaBefore"
5521 //pap.dyaBefore;dya;word;
5522 {0xA414, &SwWW8ImplReader::Read_UL}, //"sprmPDyaAfter" pap.dyaAfter;
5523 //dya;word;
5524 {0xC615, 0}, //"sprmPChgTabs" pap.itbdMac,
5525 //pap.rgdxaTab, pap.rgtbd;
5526 //complex;variable length;
5527 {0x2416, 0}, //"sprmPFInTable" pap.fInTable;
5528 //0 or 1;byte;
5529 {0x2417, &SwWW8ImplReader::Read_TabRowEnd}, //"sprmPFTtp" pap.fTtp;0 or 1;
5530 //byte;
5531 {0x8418, 0}, //"sprmPDxaAbs" pap.dxaAbs;dxa;
5532 //word;
5533 {0x8419, 0}, //"sprmPDyaAbs" pap.dyaAbs;dya;
5534 //word;
5535 {0x841A, 0}, //"sprmPDxaWidth" pap.dxaWidth;
5536 //dxa;word;
5537 {0x261B, &SwWW8ImplReader::Read_ApoPPC}, //"sprmPPc" pap.pcHorz,
5538 //pap.pcVert;complex;byte;
5539 {0x461C, 0}, //"sprmPBrcTop10" pap.brcTop;
5540 //BRC10;word;
5541 {0x461D, 0}, //"sprmPBrcLeft10" pap.brcLeft;
5542 //BRC10;word;
5543 {0x461E, 0}, //"sprmPBrcBottom10"
5544 //pap.brcBottom;BRC10;word;
5545 {0x461F, 0}, //"sprmPBrcRight10"
5546 //pap.brcRight;BRC10;word;
5547 {0x4620, 0}, //"sprmPBrcBetween10"
5548 //pap.brcBetween;BRC10;word;
5549 {0x4621, 0}, //"sprmPBrcBar10" pap.brcBar;
5550 //BRC10;word;
5551 {0x4622, 0}, //"sprmPDxaFromText10"
5552 //pap.dxaFromText;dxa;word;
5553 {0x2423, 0}, //"sprmPWr" pap.wr;wr;byte;
5554 {0x6424, &SwWW8ImplReader::Read_Border}, //"sprmPBrcTop" pap.brcTop;BRC;
5555 //long;
5556 {0x6425, &SwWW8ImplReader::Read_Border}, //"sprmPBrcLeft" pap.brcLeft;
5557 //BRC;long;
5558 {0x6426, &SwWW8ImplReader::Read_Border}, //"sprmPBrcBottom"
5559 //pap.brcBottom;BRC;long;
5560 {0x6427, &SwWW8ImplReader::Read_Border}, //"sprmPBrcRight" pap.brcRight;
5561 //BRC;long;
5562 {0x6428, &SwWW8ImplReader::Read_Border}, //"sprmPBrcBetween"
5563 //pap.brcBetween;BRC;long;
5564 {0x6629, 0}, //"sprmPBrcBar" pap.brcBar;BRC;
5565 //long;
5566 {0x242A, &SwWW8ImplReader::Read_Hyphenation},//"sprmPFNoAutoHyph"
5567 //pap.fNoAutoHyph;0 or 1;byte;
5568 {0x442B, 0}, //"sprmPWHeightAbs"
5569 //pap.wHeightAbs;w;word;
5570 {0x442C, 0}, //"sprmPDcs" pap.dcs;DCS;short;
5571 {0x442D, &SwWW8ImplReader::Read_Shade}, //"sprmPShd" pap.shd;SHD;word;
5572 {0x842E, 0}, //"sprmPDyaFromText"
5573 //pap.dyaFromText;dya;word;
5574 {0x842F, 0}, //"sprmPDxaFromText"
5575 //pap.dxaFromText;dxa;word;
5576 {0x2430, 0}, //"sprmPFLocked" pap.fLocked;
5577 //0 or 1;byte;
5578 {0x2431, &SwWW8ImplReader::Read_WidowControl},//"sprmPFWidowControl"
5579 //pap.fWidowControl;0 or 1;byte
5580 {0xC632, 0}, //"sprmPRuler" variable length;
5581 {0x2433, &SwWW8ImplReader::Read_BoolItem}, //"sprmPFKinsoku" pap.fKinsoku;
5582 //0 or 1;byte;
5583 {0x2434, 0}, //"sprmPFWordWrap"
5584 //pap.fWordWrap;0 or 1;byte;
5585 {0x2435, &SwWW8ImplReader::Read_BoolItem}, //"sprmPFOverflowPunct"
5586 //pap.fOverflowPunct; 0 or 1;
5587 //byte;
5588 {0x2436, 0}, //"sprmPFTopLinePunct"
5589 //pap.fTopLinePunct;0 or 1;byte
5590 {0x2437, &SwWW8ImplReader::Read_BoolItem}, //"sprmPFAutoSpaceDE"
5591 //pap.fAutoSpaceDE;0 or 1;byte;
5592 {0x2438, 0}, //"sprmPFAutoSpaceDN"
5593 //pap.fAutoSpaceDN;0 or 1;byte;
5594 {0x4439, &SwWW8ImplReader::Read_AlignFont}, //"sprmPWAlignFont"
5595 //pap.wAlignFont;iFa; word;
5596 {0x443A, 0}, //"sprmPFrameTextFlow"
5597 //pap.fVertical pap.fBackward
5598 //pap.fRotateFont;complex; word
5599 {0x243B, 0}, //"sprmPISnapBaseLine" obsolete
5600 //not applicable in Word97
5601 //and later versions;;byte;
5602 {0xC63E, &SwWW8ImplReader::Read_ANLevelDesc},//"sprmPAnld" pap.anld;;
5603 //variable length;
5604 {0xC63F, 0}, //"sprmPPropRMark"
5605 //pap.fPropRMark;complex;
5606 //variable length;
5607 {0x2640, &SwWW8ImplReader::Read_POutLvl}, //"sprmPOutLvl" pap.lvl;has no
5608 //effect if pap.istd is < 1 or
5609 //is > 9;byte;
5610 {0x2441, &SwWW8ImplReader::Read_ParaBiDi}, //"sprmPFBiDi" ;;byte;
5611 {0x2443, 0}, //"sprmPFNumRMIns"
5612 //pap.fNumRMIns;1 or 0;bit;
5613 {0x2444, 0}, //"sprmPCrLf" ;;byte;
5614 {0xC645, 0}, //"sprmPNumRM" pap.numrm;;
5615 //variable length;
5616 {0x6645, 0}, //"sprmPHugePapx" ;fc in the
5617 //data stream to locate the
5618 //huge grpprl; long;
5619 {0x6646, 0}, //"sprmPHugePapx" ;fc in the
5620 //data stream to locate the
5621 //huge grpprl; long;
5622 {0x2447, &SwWW8ImplReader::Read_UsePgsuSettings},//"sprmPFUsePgsuSettings"
5623 //pap.fUsePgsuSettings;1 or 0;
5624 //byte;
5625 {0x2448, 0}, //"sprmPFAdjustRight"
5626 //pap.fAdjustRight;1 or 0;byte;
5627 {0x0800, &SwWW8ImplReader::Read_CFRMarkDel}, //"sprmCFRMarkDel"
5628 //chp.fRMarkDel;1 or 0;bit;
5629 {0x0801, &SwWW8ImplReader::Read_CFRMark}, //"sprmCFRMark" chp.fRMark;1
5630 //or 0;bit;
5631 {0x0802, &SwWW8ImplReader::Read_FldVanish}, //"sprmCFFldVanish"
5632 //chp.fFldVanish;1 or 0;bit;
5633 {0x6A03, &SwWW8ImplReader::Read_PicLoc}, //"sprmCPicLocation" chp.fcPic
5634 //and chp.fSpec;variable
5635 //length, length recorded is
5636 //always 4;
5637 {0x4804, 0}, //"sprmCIbstRMark"
5638 //chp.ibstRMark;index into
5639 //sttbRMark;short;
5640 {0x6805, 0}, //"sprmCDttmRMark"
5641 //chp.dttmRMark;DTTM;long;
5642 {0x0806, 0}, //"sprmCFData" chp.fData;1 or
5643 //0;bit;
5644 {0x4807, 0}, //"sprmCIdslRMark"
5645 //chp.idslRMReason;an index to
5646 //a table of strings defined in
5647 //Word 6.0 executables;short;
5648 {0xEA08, &SwWW8ImplReader::Read_CharSet}, //"sprmCChs" chp.fChsDiff and
5649 //chp.chse;3 bytes;
5650 {0x6A09, &SwWW8ImplReader::Read_Symbol}, //"sprmCSymbol" chp.fSpec,
5651 //chp.xchSym and chp.ftcSym;
5652 //variable length, length
5653 //recorded is always 4;
5654 {0x080A, &SwWW8ImplReader::Read_Obj}, //"sprmCFOle2" chp.fOle2;1 or
5655 //0;bit;
5656 //0x480B, //"sprmCIdCharType", obsolete:
5657 //not applicable in Word97
5658 //and later versions
5659 {0x2A0C, &SwWW8ImplReader::Read_CharHighlight},//"sprmCHighlight"
5660 //chp.fHighlight,
5661 //chp.icoHighlight;ico
5662 //(fHighlight is set to 1 iff
5663 //ico is not 0);byte;
5664 {0x680E, &SwWW8ImplReader::Read_PicLoc}, //"sprmCObjLocation" chp.fcObj;
5665 //FC;long;
5666 //0x2A10, ? ? ?, //"sprmCFFtcAsciSymb"
5667 {0x4A30, &SwWW8ImplReader::Read_CColl}, //"sprmCIstd" chp.istd;istd,
5668 //short;
5669 {0xCA31, 0}, //"sprmCIstdPermute" chp.istd;
5670 //permutation vector; variable
5671 //length;
5672 {0x2A32, 0}, //"sprmCDefault" whole CHP;none
5673 //;variable length;
5674 {0x2A33, 0}, //"sprmCPlain" whole CHP;none;
5675 //Laenge: 0;
5676 {0x2A34, &SwWW8ImplReader::Read_Emphasis}, //"sprmCKcd"
5677 {0x0835, &SwWW8ImplReader::Read_BoldUsw}, //"sprmCFBold" chp.fBold;0,1,
5678 //128, or 129; byte;
5679 {0x0836, &SwWW8ImplReader::Read_BoldUsw}, //"sprmCFItalic" chp.fItalic;0,
5680 //1, 128, or 129; byte;
5681 {0x0837, &SwWW8ImplReader::Read_BoldUsw}, //"sprmCFStrike" chp.fStrike;0,
5682 //1, 128, or 129; byte;
5683 {0x0838, &SwWW8ImplReader::Read_BoldUsw}, //"sprmCFOutline" chp.fOutline;
5684 //0,1, 128, or 129; byte;
5685 {0x0839, &SwWW8ImplReader::Read_BoldUsw}, //"sprmCFShadow" chp.fShadow;0,
5686 //1, 128, or 129; byte;
5687 {0x083A, &SwWW8ImplReader::Read_BoldUsw}, //"sprmCFSmallCaps"
5688 //chp.fSmallCaps;0,1, 128, or
5689 //129;byte;
5690 {0x083B, &SwWW8ImplReader::Read_BoldUsw}, //"sprmCFCaps" chp.fCaps;0,1,
5691 //128, or 129; byte;
5692 {0x083C, &SwWW8ImplReader::Read_BoldUsw}, //"sprmCFVanish" chp.fVanish;0,
5693 //1, 128, or 129; byte;
5694 //0x4A3D, 0, //"sprmCFtcDefault" ftc, only
5695 //used internally, never
5696 //stored in file;word;
5697 {0x2A3E, &SwWW8ImplReader::Read_Underline}, //"sprmCKul" chp.kul;kul;byte;
5698 {0xEA3F, 0}, //"sprmCSizePos" chp.hps,
5699 //chp.hpsPos;3 bytes;
5700 {0x8840, &SwWW8ImplReader::Read_Kern}, //"sprmCDxaSpace" chp.dxaSpace;
5701 //dxa;word;
5702 {0x4A41, &SwWW8ImplReader::Read_Language}, //"sprmCLid" ;only used
5703 //internally never stored;word;
5704 {0x2A42, &SwWW8ImplReader::Read_TxtColor}, //"sprmCIco" chp.ico;ico;byte;
5705 {0x4A43, &SwWW8ImplReader::Read_FontSize}, //"sprmCHps" chp.hps;hps;byte;
5706 {0x2A44, 0}, //"sprmCHpsInc" chp.hps;byte;
5707 {0x4845, &SwWW8ImplReader::Read_SubSuperProp},//"sprmCHpsPos" chp.hpsPos;
5708 //hps; byte;
5709 {0x2A46, 0}, //"sprmCHpsPosAdj" chp.hpsPos;
5710 //hps; byte;
5711 {0xCA47, &SwWW8ImplReader::Read_Majority}, //"sprmCMajority" chp.fBold,
5712 //chp.fItalic, chp.fSmallCaps,
5713 //chp.fVanish, chp.fStrike,
5714 //chp.fCaps, chp.rgftc,
5715 //chp.hps, chp.hpsPos, chp.kul,
5716 //chp.dxaSpace, chp.ico,
5717 //chp.rglid;complex;variable
5718 //length, length byte plus
5719 //size of following grpprl;
5720 {0x2A48, &SwWW8ImplReader::Read_SubSuper}, //"sprmCIss" chp.iss;iss;byte;
5721 {0xCA49, 0}, //"sprmCHpsNew50" chp.hps;hps;
5722 //variable width, length
5723 //always recorded as 2;
5724 {0xCA4A, 0}, //"sprmCHpsInc1" chp.hps;
5725 //complex; variable width,
5726 //length always recorded as 2;
5727 {0x484B, &SwWW8ImplReader::Read_FontKern}, //"sprmCHpsKern" chp.hpsKern;
5728 //hps;short;
5729 {0xCA4C, &SwWW8ImplReader::Read_Majority}, //"sprmCMajority50" chp.fBold,
5730 //chp.fItalic, chp.fSmallCaps,
5731 //chp.fVanish, chp.fStrike,
5732 //chp.fCaps, chp.ftc, chp.hps,
5733 //chp.hpsPos, chp.kul,
5734 //chp.dxaSpace, chp.ico;
5735 //complex; variable length;
5736 {0x4A4D, 0}, //"sprmCHpsMul" chp.hps;
5737 //percentage to grow hps;short;
5738 {0x484E, 0}, //"sprmCYsri" chp.ysri;ysri;
5739 //short;
5740 {0x4A4F, &SwWW8ImplReader::Read_FontCode}, //"sprmCRgFtc0" chp.rgftc[0];
5741 //ftc for ASCII text; short;
5742 {0x4A50, &SwWW8ImplReader::Read_FontCode}, //"sprmCRgFtc1" chp.rgftc[1];
5743 //ftc for Far East text;short;
5744 {0x4A51, &SwWW8ImplReader::Read_FontCode}, //"sprmCRgFtc2" chp.rgftc[2];
5745 //ftc for non-Far East text;
5746 //short;
5747 {0x4852, &SwWW8ImplReader::Read_ScaleWidth}, //"sprmCCharScale"
5748 {0x2A53, &SwWW8ImplReader::Read_BoldUsw}, //"sprmCFDStrike" chp.fDStrike;
5749 //;byte;
5750 {0x0854, &SwWW8ImplReader::Read_Relief}, //"sprmCFImprint" chp.fImprint;
5751 //1 or 0;bit;
5752 {0x0855, &SwWW8ImplReader::Read_Special}, //"sprmCFSpec" chp.fSpec;
5753 //1 or 0;bit;
5754 {0x0856, &SwWW8ImplReader::Read_Obj}, //"sprmCFObj" chp.fObj;1 or 0;
5755 //bit;
5756 {0xCA57, &SwWW8ImplReader::Read_CPropRMark}, //"sprmCPropRMark"
5757 //chp.fPropRMark,
5758 //chp.ibstPropRMark,
5759 //chp.dttmPropRMark;Complex;
5760 //variable length always
5761 //recorded as 7 bytes;
5762 {0x0858, &SwWW8ImplReader::Read_Relief}, //"sprmCFEmboss" chp.fEmboss;
5763 //1 or 0;bit;
5764 {0x2859, &SwWW8ImplReader::Read_TxtAnim}, //"sprmCSfxText" chp.sfxtText;
5765 //text animation;byte;
5766 {0x085A, &SwWW8ImplReader::Read_Bidi}, //"sprmCFBiDi"
5767 {0x085B, 0}, //"sprmCFDiacColor"
5768 {0x085C, &SwWW8ImplReader::Read_BoldBiDiUsw},//"sprmCFBoldBi"
5769 {0x085D, &SwWW8ImplReader::Read_BoldBiDiUsw},//"sprmCFItalicBi"
5770 {0x4A5E, &SwWW8ImplReader::Read_FontCode}, //"sprmCFtcBi"
5771 {0x485F, &SwWW8ImplReader::Read_Language}, //"sprmCLidBi"
5772 //0x4A60, ? ? ?, //"sprmCIcoBi",
5773 {0x4A61, &SwWW8ImplReader::Read_FontSize}, //"sprmCHpsBi"
5774 {0xCA62, 0}, //"sprmCDispFldRMark"
5775 //chp.fDispFldRMark,
5776 //chp.ibstDispFldRMark,
5777 //chp.dttmDispFldRMark ;
5778 //Complex;variable length
5779 //always recorded as 39 bytes;
5780 {0x4863, 0}, //"sprmCIbstRMarkDel"
5781 //chp.ibstRMarkDel;index into
5782 //sttbRMark;short;
5783 {0x6864, 0}, //"sprmCDttmRMarkDel"
5784 //chp.dttmRMarkDel;DTTM;long;
5785 {0x6865, 0}, //"sprmCBrc" chp.brc;BRC;long;
5786 {0x4866, &SwWW8ImplReader::Read_CharShadow}, //"sprmCShd" chp.shd;SHD;short;
5787 {0x4867, 0}, //"sprmCIdslRMarkDel"
5788 //chp.idslRMReasonDel;an index
5789 //to a table of strings
5790 //defined in Word 6.0
5791 //executables;short;
5792 {0x0868, 0}, //"sprmCFUsePgsuSettings"
5793 //chp.fUsePgsuSettings; 1 or 0;
5794 //bit;
5795 {0x486B, 0}, //"sprmCCpg" ;;word;
5796 {0x486D, &SwWW8ImplReader::Read_Language}, //"sprmCRgLid0_80" chp.rglid[0];
5797 //LID: for non-Far East text;
5798 //word;
5799 {0x486E, &SwWW8ImplReader::Read_Language}, //"sprmCRgLid1_80" chp.rglid[1];
5800 //LID: for Far East text;word;
5801 {0x286F, &SwWW8ImplReader::Read_IdctHint}, //"sprmCIdctHint" chp.idctHint;
5802 //IDCT: byte;
5803 {0x2E00, 0}, //"sprmPicBrcl" pic.brcl;brcl
5804 //(see PIC structure
5805 //definition);byte;
5806 {0xCE01, 0}, //"sprmPicScale" pic.mx,
5807 //pic.my, pic.dxaCropleft,
5808 //pic.dyaCropTop
5809 //pic.dxaCropRight,
5810 //pic.dyaCropBottom;Complex;
5811 //length byte plus 12 bytes;
5812 {0x6C02, 0}, //"sprmPicBrcTop" pic.brcTop;
5813 //BRC;long;
5814 {0x6C03, 0}, //"sprmPicBrcLeft" pic.brcLeft;
5815 //BRC;long;
5816 {0x6C04, 0}, //"sprmPicBrcBottom"
5817 //pic.brcBottom;BRC;long;
5818 {0x6C05, 0}, //"sprmPicBrcRight"
5819 //pic.brcRight;BRC;long;
5820 {0x3000, 0}, //"sprmScnsPgn" sep.cnsPgn;cns;
5821 //byte;
5822 {0x3001, 0}, //"sprmSiHeadingPgn"
5823 //sep.iHeadingPgn;heading
5824 //number level;byte;
5825 {0xD202, &SwWW8ImplReader::Read_OLST}, //"sprmSOlstAnm" sep.olstAnm;
5826 //OLST;variable length;
5827 {0xF203, 0}, //"sprmSDxaColWidth"
5828 //sep.rgdxaColWidthSpacing;
5829 //complex; 3 bytes;
5830 {0xF204, 0}, //"sprmSDxaColSpacing"
5831 //sep.rgdxaColWidthSpacing;
5832 //complex; 3 bytes;
5833 {0x3005, 0}, //"sprmSFEvenlySpaced"
5834 //sep.fEvenlySpaced; 1 or 0;
5835 //byte;
5836 {0x3006, 0}, //"sprmSFProtected"
5837 //sep.fUnlocked;1 or 0;byte;
5838 {0x5007, 0}, //"sprmSDmBinFirst"
5839 //sep.dmBinFirst;;word;
5840 {0x5008, 0}, //"sprmSDmBinOther"
5841 //sep.dmBinOther;;word;
5842 {0x3009, 0}, //"sprmSBkc" sep.bkc;bkc;byte;
5843 {0x300A, 0}, //"sprmSFTitlePage"
5844 //sep.fTitlePage;0 or 1;byte;
5845 {0x500B, 0}, //"sprmSCcolumns" sep.ccolM1;
5846 //# of cols - 1;word;
5847 {0x900C, 0}, //"sprmSDxaColumns"
5848 //sep.dxaColumns;dxa;word;
5849 {0x300D, 0}, //"sprmSFAutoPgn" sep.fAutoPgn;
5850 //obsolete;byte;
5851 {0x300E, 0}, //"sprmSNfcPgn" sep.nfcPgn;nfc;
5852 //byte;
5853 {0xB00F, 0}, //"sprmSDyaPgn" sep.dyaPgn;dya;
5854 //short;
5855 {0xB010, 0}, //"sprmSDxaPgn" sep.dxaPgn;dya;
5856 //short;
5857 {0x3011, 0}, //"sprmSFPgnRestart"
5858 //sep.fPgnRestart;0 or 1;byte;
5859 {0x3012, 0}, //"sprmSFEndnote" sep.fEndnote;
5860 //0 or 1;byte;
5861 {0x3013, 0}, //"sprmSLnc" sep.lnc;lnc;byte;
5862 {0x3014, 0}, //"sprmSGprfIhdt" sep.grpfIhdt;
5863 //grpfihdt; byte;
5864 {0x5015, 0}, //"sprmSNLnnMod" sep.nLnnMod;
5865 //non-neg int.;word;
5866 {0x9016, 0}, //"sprmSDxaLnn" sep.dxaLnn;dxa;
5867 //word;
5868 {0xB017, 0}, //"sprmSDyaHdrTop"
5869 //sep.dyaHdrTop;dya;word;
5870 {0xB018, 0}, //"sprmSDyaHdrBottom"
5871 //sep.dyaHdrBottom;dya;word;
5872 {0x3019, 0}, //"sprmSLBetween"
5873 //sep.fLBetween;0 or 1;byte;
5874 {0x301A, 0}, //"sprmSVjc" sep.vjc;vjc;byte;
5875 {0x501B, 0}, //"sprmSLnnMin" sep.lnnMin;lnn;
5876 //word;
5877 {0x501C, 0}, //"sprmSPgnStart" sep.pgnStart;
5878 //pgn;word;
5879 {0x301D, 0}, //"sprmSBOrientation"
5880 //sep.dmOrientPage;dm;byte;
5881 //0x301E, ? ? ?, //"sprmSBCustomize"
5882 {0xB01F, 0}, //"sprmSXaPage" sep.xaPage;xa;
5883 //word;
5884 {0xB020, 0}, //"sprmSYaPage" sep.yaPage;ya;
5885 //word;
5886 {0x2205, 0}, //"sprmSDxaLeft" sep.dxaLeft;
5887 //dxa;word;
5888 {0xB022, 0}, //"sprmSDxaRight" sep.dxaRight;
5889 //dxa;word;
5890 {0x9023, 0}, //"sprmSDyaTop" sep.dyaTop;dya;
5891 //word;
5892 {0x9024, 0}, //"sprmSDyaBottom"
5893 //sep.dyaBottom;dya;word;
5894 {0xB025, 0}, //"sprmSDzaGutter"
5895 //sep.dzaGutter;dza;word;
5896 {0x5026, 0}, //"sprmSDmPaperReq"
5897 //sep.dmPaperReq;dm;word;
5898 {0xD227, 0}, //"sprmSPropRMark"
5899 //sep.fPropRMark,
5900 //sep.ibstPropRMark,
5901 //sep.dttmPropRMark ;complex;
5902 //variable length always
5903 //recorded as 7 bytes;
5904 //0x3228, ? ? ?, //"sprmSFBiDi",
5905 //0x3229, ? ? ?, //"sprmSFFacingCol"
5906 {0x322A, 0}, //"sprmSFRTLGutter", set to 1
5907 //if gutter is on the right.
5908 {0x702B, 0}, //"sprmSBrcTop" sep.brcTop;BRC;
5909 //long;
5910 {0x702C, 0}, //"sprmSBrcLeft" sep.brcLeft;
5911 //BRC;long;
5912 {0x702D, 0}, //"sprmSBrcBottom"
5913 //sep.brcBottom;BRC;long;
5914 {0x702E, 0}, //"sprmSBrcRight" sep.brcRight;
5915 //BRC;long;
5916 {0x522F, 0}, //"sprmSPgbProp" sep.pgbProp;
5917 //word;
5918 {0x7030, 0}, //"sprmSDxtCharSpace"
5919 //sep.dxtCharSpace;dxt;long;
5920 {0x9031, 0}, //"sprmSDyaLinePitch"
5921 //sep.dyaLinePitch;dya;
5922 //WRONG:long; RIGHT:short; !
5923 //0x5032, ? ? ?, //"sprmSClm"
5924 {0x5033, 0}, //"sprmSTextFlow"
5925 //sep.wTextFlow;complex ;short
5926 {0x5400, 0}, //"sprmTJc" tap.jc;jc;word (low
5927 //order byte is significant);
5928 {0x9601, 0}, //"sprmTDxaLeft"
5929 //tap.rgdxaCenter; dxa; word;
5930 {0x9602, 0}, //"sprmTDxaGapHalf"
5931 //tap.dxaGapHalf,
5932 //tap.rgdxaCenter; dxa; word;
5933 {0x3403, 0}, //"sprmTFCantSplit"
5934 //tap.fCantSplit;1 or 0;byte;
5935 {0x3404, 0}, //"sprmTTableHeader"
5936 //tap.fTableHeader;1 or 0;byte;
5937 {0x3466, 0}, //"sprmTFCantSplit90"
5938 //tap.fCantSplit90;1 or 0;byte;
5939 {0xD605, 0}, //"sprmTTableBorders"
5940 //tap.rgbrcTable;complex;
5941 //24 bytes;
5942 {0xD606, 0}, //"sprmTDefTable10"
5943 //tap.rgdxaCenter,
5944 //tap.rgtc;complex; variable
5945 //length;
5946 {0x9407, 0}, //"sprmTDyaRowHeight"
5947 //tap.dyaRowHeight;dya;word;
5948 {0xD608, 0}, //"sprmTDefTable"
5949 //tap.rgtc;complex
5950 {0xD609, 0}, //"sprmTDefTableShd"
5951 //tap.rgshd;complex
5952 {0x740A, 0}, //"sprmTTlp" tap.tlp;TLP;
5953 //4 bytes;
5954 //0x560B, ? ? ?, //"sprmTFBiDi"
5955 //0x740C, ? ? ?, //"sprmTHTMLProps"
5956 {0xD620, 0}, //"sprmTSetBrc"
5957 //tap.rgtc[].rgbrc;complex;
5958 //5 bytes;
5959 {0x7621, 0}, //"sprmTInsert"
5960 //tap.rgdxaCenter,
5961 //tap.rgtc;complex ;4 bytes;
5962 {0x5622, 0}, //"sprmTDelete"
5963 //tap.rgdxaCenter,
5964 //tap.rgtc;complex ;word;
5965 {0x7623, 0}, //"sprmTDxaCol"
5966 //tap.rgdxaCenter;complex;
5967 //4 bytes;
5968 {0x5624, 0}, //"sprmTMerge"
5969 //tap.fFirstMerged,
5970 //tap.fMerged;complex; word;
5971 {0x5625, 0}, //"sprmTSplit"
5972 //tap.fFirstMerged,
5973 //tap.fMerged;complex ;word;
5974 {0xD626, 0}, //"sprmTSetBrc10"
5975 //tap.rgtc[].rgbrc;complex;
5976 //5 bytes;
5977 {0x7627, 0}, //"sprmTSetShd" tap.rgshd;
5978 //complex; 4 bytes;
5979 {0x7628, 0}, //"sprmTSetShdOdd"
5980 //tap.rgshd;complex;4 bytes;
5981 {0x7629, 0}, //"sprmTTextFlow"
5982 //tap.rgtc[].fVertical
5983 //tap.rgtc[].fBackward
5984 //tap.rgtc[].fRotateFont
5985 //0 or 10 or 10 or 1;word;
5986 //0xD62A, ? ? ? , //"sprmTDiagLine"
5987 {0xD62B, 0}, //"sprmTVertMerge"
5988 //tap.rgtc[].vertMerge;complex;
5989 //variable length always
5990 //recorded as 2 bytes;
5991 {0xD62C, 0}, //"sprmTVertAlign"
5992 //tap.rgtc[].vertAlign;complex
5993 //variable length always
5994 //recorded as 3 byte;
5995 {0xCA78, &SwWW8ImplReader::Read_DoubleLine_Rotate},
5996 {0x6649, 0}, //undocumented
5997 {0xF614, 0}, //"sprmTTableWidth"
5998 //recorded as 3 bytes;
5999 {0xD612, 0}, //undocumented
6000 {0xD613, 0}, //undocumented
6001 {0xD61A, 0}, //undocumented
6002 {0xD61B, 0}, //undocumented
6003 {0xD61C, 0}, //undocumented
6004 {0xD61D, 0}, //undocumented
6005 {0xD634, 0}, //undocumented
6006 {0xD632, 0}, //undocumented
6007 {0xD238, 0}, //undocumented sep
6008 {0xC64E, 0}, //undocumented
6009 {0xC64F, 0}, //undocumented
6010 {0xC650, 0}, //undocumented
6011 {0xC651, 0}, //undocumented
6012 {0xF661, 0}, //undocumented
6013 {0x4873, &SwWW8ImplReader::Read_Language}, //"sprmCRgLid0" chp.rglid[0];
6014 //LID: for non-Far East text;
6015 //(like a duplicate of 486D)
6016 {0x4874, 0}, //"sprmCRgLid1" chp.rglid[1];
6017 //LID: for Far East text
6018 //(like a duplicate of 486E)
6019 {0x6463, 0}, //undocumented
6020 {0x2461, &SwWW8ImplReader::Read_RTLJustify}, //undoc, must be asian version
6021 //of "sprmPJc"
6022 {0x845E, &SwWW8ImplReader::Read_LR}, //Apparently post-Word 97 version of "sprmPDxaLeft"
6023 {0x8460, &SwWW8ImplReader::Read_LR}, //Post-Word 97 version of "sprmPDxaLeft1"
6024 {0x845D, &SwWW8ImplReader::Read_LR}, //Post-Word 97 version of "sprmPDxaRight"
6025 {0x3615, 0}, //undocumented
6026 {0x360D, 0}, //undocumented
6027 {0x940E, 0}, //undocumented
6028 {0x940F, 0}, //undocumented
6029 {0x9410, 0}, //undocumented
6030 {0x703A, 0}, //undocumented
6031 {0x303B, 0}, //undocumented
6032 {0x244B, &SwWW8ImplReader::Read_TabCellEnd}, //undocumented, must be
6033 //subtable "sprmPFInTable"
6034 {0x244C, &SwWW8ImplReader::Read_TabRowEnd}, //undocumented, must be
6035 // subtable "sprmPFTtp"
6036 {0x6815, 0}, //undocumented
6037 {0x6816, 0}, //undocumented
6038 {0x6870, &SwWW8ImplReader::Read_TxtForeColor},
6039 {0xC64D, &SwWW8ImplReader::Read_ParaBackColor},
6040 {0x6467, 0}, //undocumented
6041 {0xF617, 0}, //undocumented
6042 {0xD660, 0}, //undocumented
6043 {0xD670, 0}, //undocumented
6044 {0xCA71, &SwWW8ImplReader::Read_TxtBackColor},//undocumented
6045 {0x303C, 0}, //undocumented
6046 {0x245B, &SwWW8ImplReader::Read_ParaAutoBefore},//undocumented, para
6047 {0x245C, &SwWW8ImplReader::Read_ParaAutoAfter},//undocumented, para
6048 {0x246D, &SwWW8ImplReader::Read_ParaContextualSpacing} //"sprmPFContextualSpacing"
6051 static wwSprmDispatcher aSprmSrch(aSprms, sizeof(aSprms) / sizeof(aSprms[0]));
6052 return &aSprmSrch;
6055 //-----------------------------------------
6056 // Hilfsroutinen : SPRM finden
6057 //-----------------------------------------
6059 const SprmReadInfo& SwWW8ImplReader::GetSprmReadInfo(sal_uInt16 nId) const
6061 ww::WordVersion eVersion = pWwFib->GetFIBVersion();
6062 const wwSprmDispatcher *pDispatcher;
6063 if (eVersion <= ww::eWW2)
6064 pDispatcher = GetWW2SprmDispatcher();
6065 else if (eVersion < ww::eWW8)
6066 pDispatcher = GetWW6SprmDispatcher();
6067 else
6068 pDispatcher = GetWW8SprmDispatcher();
6070 SprmReadInfo aSrch = {0, 0};
6071 aSrch.nId = nId;
6072 const SprmReadInfo* pFound = pDispatcher->search(aSrch);
6074 if (!pFound)
6076 aSrch.nId = 0;
6077 pFound = pDispatcher->search(aSrch);
6080 return *pFound;
6083 //-----------------------------------------
6084 // Hilfsroutinen : SPRMs
6085 //-----------------------------------------
6086 void SwWW8ImplReader::EndSprm( sal_uInt16 nId )
6088 if( ( nId > 255 ) && ( nId < 0x0800 ) ) return;
6090 const SprmReadInfo& rSprm = GetSprmReadInfo( nId );
6092 if (rSprm.pReadFnc)
6093 (this->*rSprm.pReadFnc)( nId, 0, -1 );
6096 short SwWW8ImplReader::ImportSprm(const sal_uInt8* pPos,sal_uInt16 nId)
6098 if (!nId)
6099 nId = mpSprmParser->GetSprmId(pPos);
6101 OSL_ENSURE( nId != 0xff, "Sprm FF !!!!" );
6103 const SprmReadInfo& rSprm = GetSprmReadInfo(nId);
6105 sal_uInt16 nFixedLen = mpSprmParser->DistanceToData(nId);
6106 sal_uInt16 nL = mpSprmParser->GetSprmSize(nId, pPos);
6108 if (rSprm.pReadFnc)
6109 (this->*rSprm.pReadFnc)(nId, pPos + nFixedLen, nL - nFixedLen);
6111 return nL;
6114 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */