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