update dev300-m58
[ooovba.git] / sw / source / filter / ww8 / ww8par6.cxx
blobf1204591bd90fa7aa99cf09aab5fa3ec9799102d
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 = mrReader.rDoc.Insert( rMyPaM, aSection, &aSet );
702 ASSERT(rSection.mpSection, "section not inserted!");
703 if (!rSection.mpSection)
704 return 0;
706 SwPageDesc *pPage = 0;
707 mySegrIter aEnd = maSegments.rend();
708 for (mySegrIter aIter = maSegments.rbegin(); aIter != aEnd; ++aIter)
710 if (0 != (pPage = aIter->mpPage))
711 break;
714 ASSERT(pPage, "no page outside this section!");
716 if (!pPage)
717 pPage = &mrReader.rDoc._GetPageDesc(0);
719 if (!pPage)
720 return 0;
722 SwSectionFmt *pFmt = rSection.mpSection->GetFmt();
723 ASSERT(pFmt, "impossible");
724 if (!pFmt)
725 return 0;
727 SwFrmFmt& rFmt = pPage->GetMaster();
728 const SvxLRSpaceItem& rLR = rFmt.GetLRSpace();
729 long nPageLeft = rLR.GetLeft();
730 long nPageRight = rLR.GetRight();
731 long nSectionLeft = rSection.GetPageLeft() - nPageLeft;
732 long nSectionRight = rSection.GetPageRight() - nPageRight;
733 if ((nSectionLeft != 0) || (nSectionRight != 0))
735 SvxLRSpaceItem aLR(nSectionLeft, nSectionRight, 0, 0, RES_LR_SPACE);
736 pFmt->SetFmtAttr(aLR);
739 SetCols(*pFmt, rSection, rSection.GetTextAreaWidth());
740 return pFmt;
743 void SwWW8ImplReader::HandleLineNumbering(const wwSection &rSection)
745 // check if Line Numbering must be activated or resetted
746 if (mbNewDoc && rSection.maSep.nLnnMod)
748 // restart-numbering-mode: 0 per page, 1 per section, 2 never restart
749 bool bRestartLnNumPerSection = (1 == rSection.maSep.lnc);
751 if (bNoLnNumYet)
753 SwLineNumberInfo aInfo( rDoc.GetLineNumberInfo() );
755 aInfo.SetPaintLineNumbers(true);
757 aInfo.SetRestartEachPage(rSection.maSep.lnc == 0);
759 aInfo.SetPosFromLeft(writer_cast<USHORT>(rSection.maSep.dxaLnn));
761 //Paint only for every n line
762 aInfo.SetCountBy(rSection.maSep.nLnnMod);
764 // to be defaulted features ( HARDCODED in MS Word 6,7,8,9 )
765 aInfo.SetCountBlankLines(true);
766 aInfo.SetCountInFlys(false);
767 aInfo.SetPos( LINENUMBER_POS_LEFT );
768 SvxNumberType aNumType; // this sets SVX_NUM_ARABIC per default
769 aInfo.SetNumType( aNumType );
771 rDoc.SetLineNumberInfo( aInfo );
772 bNoLnNumYet = false;
775 if (
776 (0 < rSection.maSep.lnnMin) ||
777 (bRestartLnNumPerSection && !bNoLnNumYet)
780 SwFmtLineNumber aLN;
781 if (const SwFmtLineNumber* pLN
782 = (const SwFmtLineNumber*)GetFmtAttr(RES_LINENUMBER))
784 aLN.SetCountLines( pLN->IsCount() );
786 aLN.SetStartValue(1 + rSection.maSep.lnnMin);
787 NewAttr(aLN);
788 pCtrlStck->SetAttr(*pPaM->GetPoint(), RES_LINENUMBER);
790 bNoLnNumYet = false;
794 wwSection::wwSection(const SwPosition &rPos) : maStart(rPos.nNode),
795 mpSection(0), mpTitlePage(0), mpPage(0), meDir(FRMDIR_HORI_LEFT_TOP),
796 nPgWidth(SvxPaperInfo::GetPaperSize(PAPER_A4).Width()),
797 nPgLeft(MM_250), nPgRight(MM_250), mnBorders(0), mbHasFootnote(false)
801 void wwSectionManager::SetNumberingType(const wwSection &rNewSection,
802 SwPageDesc &rPageDesc) const
804 // Seitennummernformat speichern
805 static const SvxExtNumType aNumTyp[5] =
807 SVX_NUM_ARABIC, SVX_NUM_ROMAN_UPPER, SVX_NUM_ROMAN_LOWER,
808 SVX_NUM_CHARS_UPPER_LETTER_N, SVX_NUM_CHARS_LOWER_LETTER_N
811 SvxNumberType aType;
812 aType.SetNumberingType( static_cast< sal_Int16 >(aNumTyp[rNewSection.maSep.nfcPgn]) );
813 rPageDesc.SetNumType(aType);
816 // Bei jedem Abschnittswechsel ( auch am Anfang eines Dokuments ) wird
817 // CreateSep gerufen, dass dann den / die Pagedesc(s) erzeugt und
818 // mit Attributen un KF-Texten fuellt.
819 // Dieses Vorgehen ist noetig geworden, da die UEbersetzung der verschiedenen
820 // Seiten-Attribute zu stark verflochten ist.
821 void wwSectionManager::CreateSep(const long nTxtPos, bool /*bMustHaveBreak*/)
824 #i1909# #100688# section/page breaks should not occur in tables or subpage
825 elements like frames. Word itself ignores them in this case. The bug is
826 more likely that this filter created such documents in the past!
828 if (mrReader.nInTable || mrReader.bTxbxFlySection || mrReader.InLocalApo())
829 return;
831 WW8PLCFx_SEPX* pSep = mrReader.pPlcxMan->GetSepPLCF();
832 ASSERT(pSep, "impossible!");
833 if (!pSep)
834 return;
836 ww::WordVersion eVer = mrReader.GetFib().GetFIBVersion();
838 // M.M. Create a linked section if the WkbPLCF
839 // has an entry for one at this cp
840 WW8PLCFspecial* pWkb = mrReader.pPlcxMan->GetWkbPLCF();
841 if (pWkb && pWkb->SeekPosExact(nTxtPos) &&
842 pWkb->Where() == nTxtPos)
844 void* pData;
845 WW8_CP nTest;
846 pWkb->Get(nTest, pData);
847 String sSectionName = mrReader.aLinkStringMap[SVBT16ToShort( ((WW8_WKB*)pData)->nLinkId) ];
848 mrReader.ConvertFFileName(sSectionName, sSectionName);
849 SwSection aSection(FILE_LINK_SECTION, sSectionName);
850 aSection.SetLinkFileName( sSectionName );
851 aSection.SetProtect(true);
852 // --> CMC, OD 2004-06-18 #i19922# improvement:
853 // return value of method <Insert> not used.
854 mrReader.rDoc.Insert(*mrReader.pPaM, aSection, 0 ,false);
857 wwSection aLastSection(*mrReader.pPaM->GetPoint());
858 if (!maSegments.empty())
859 aLastSection = maSegments.back();
861 //Here
862 USHORT nLIdx = ( ( mrReader.pWwFib->lid & 0xff ) == 0x9 ) ? 1 : 0;
864 //BEGIN read section values
865 wwSection aNewSection(*mrReader.pPaM->GetPoint());
867 static const USHORT aVer2Ids0[] =
869 /*sprmSBkc*/ 117,
870 /*sprmSFTitlePage*/ 118,
871 /*sprmSNfcPgn*/ 122,
872 /*sprmSCcolumns*/ 119,
873 /*sprmSDxaColumns*/ 120,
874 /*sprmSLBetween*/ 133
877 static const USHORT aVer67Ids0[] =
879 /*sprmSBkc*/ 142,
880 /*sprmSFTitlePage*/ 143,
881 /*sprmSNfcPgn*/ 147,
882 /*sprmSCcolumns*/ 144,
883 /*sprmSDxaColumns*/ 145,
884 /*sprmSLBetween*/ 158
887 static const USHORT aVer8Ids0[] =
889 /*sprmSBkc*/ 0x3009,
890 /*sprmSFTitlePage*/ 0x300A,
891 /*sprmSNfcPgn*/ 0x300E,
892 /*sprmSCcolumns*/ 0x500B,
893 /*sprmSDxaColumns*/ 0x900C,
894 /*sprmSLBetween*/ 0x3019
897 const USHORT* pIds = eVer <= ww::eWW2 ? aVer2Ids0 : eVer <= ww::eWW7 ? aVer67Ids0 : aVer8Ids0;
899 if (!maSegments.empty())
901 // Type of break: break codes are:
902 // 0 No break
903 // 1 New column
904 // 2 New page
905 // 3 Even page
906 // 4 Odd page
907 if (const BYTE* pSprmBkc = pSep->HasSprm(pIds[0]))
908 aNewSection.maSep.bkc = *pSprmBkc;
911 // Has a table page
912 aNewSection.maSep.fTitlePage =
913 (0 != ReadBSprm( pSep, pIds[1], 0 ));
915 // sprmSNfcPgn
916 aNewSection.maSep.nfcPgn = ReadBSprm( pSep, pIds[2], 0 );
917 if (aNewSection.maSep.nfcPgn > 4)
918 aNewSection.maSep.nfcPgn = 0;
920 aNewSection.maSep.fUnlocked = eVer > ww::eWW2 ? ReadBSprm(pSep, (eVer <= ww::eWW7 ? 139 : 0x3006), 0 ) : 0;
922 // sprmSFBiDi
923 aNewSection.maSep.fBiDi = eVer >= ww::eWW8 ? ReadBSprm(pSep, 0x3228, 0) : 0;
925 aNewSection.maSep.ccolM1 = ReadSprm(pSep, pIds[3], 0 );
927 //sprmSDxaColumns - Default-Abstand 1.25 cm
928 aNewSection.maSep.dxaColumns = ReadUSprm( pSep, pIds[4], 708 );
930 // sprmSLBetween
931 aNewSection.maSep.fLBetween = ReadBSprm(pSep, pIds[5], 0 );
933 if (eVer >= ww::eWW6)
935 // sprmSFEvenlySpaced
936 aNewSection.maSep.fEvenlySpaced =
937 ReadBSprm(pSep, (eVer <= ww::eWW7 ? 138 : 0x3005), 1) ? true : false;
939 if (aNewSection.maSep.ccolM1 > 0 && !aNewSection.maSep.fEvenlySpaced)
941 aNewSection.maSep.rgdxaColumnWidthSpacing[0] = 0;
942 int nCols = aNewSection.maSep.ccolM1 + 1;
943 int nIdx = 0;
944 for (int i = 0; i < nCols; ++i)
946 //sprmSDxaColWidth
947 const BYTE* pSW = pSep->HasSprm( (eVer <= ww::eWW7 ? 136 : 0xF203), BYTE( i ) );
949 ASSERT( pSW, "+Sprm 136 (bzw. 0xF203) (ColWidth) fehlt" );
950 sal_uInt16 nWidth = pSW ? SVBT16ToShort(pSW + 1) : 1440;
952 aNewSection.maSep.rgdxaColumnWidthSpacing[++nIdx] = nWidth;
954 if (i < nCols-1)
956 //sprmSDxaColSpacing
957 const BYTE* pSD = pSep->HasSprm( (eVer <= ww::eWW7 ? 137 : 0xF204), BYTE( i ) );
959 ASSERT( pSD, "+Sprm 137 (bzw. 0xF204) (Colspacing) fehlt" );
960 if( pSD )
962 nWidth = SVBT16ToShort(pSD + 1);
963 aNewSection.maSep.rgdxaColumnWidthSpacing[++nIdx] = nWidth;
970 static const USHORT aVer2Ids1[] =
972 /*sprmSBOrientation*/ 137,
973 /*sprmSXaPage*/ 139,
974 /*sprmSYaPage*/ 140,
975 /*sprmSDxaLeft*/ 141,
976 /*sprmSDxaRight*/ 142,
977 /*sprmSDzaGutter*/ 145,
978 /*sprmSFPgnRestart*/ 125,
979 /*sprmSPgnStart*/ 136,
980 /*sprmSDmBinFirst*/ 115,
981 /*sprmSDmBinOther*/ 116
984 static const USHORT aVer67Ids1[] =
986 /*sprmSBOrientation*/ 162,
987 /*sprmSXaPage*/ 164,
988 /*sprmSYaPage*/ 165,
989 /*sprmSDxaLeft*/ 166,
990 /*sprmSDxaRight*/ 167,
991 /*sprmSDzaGutter*/ 170,
992 /*sprmSFPgnRestart*/ 150,
993 /*sprmSPgnStart*/ 161,
994 /*sprmSDmBinFirst*/ 140,
995 /*sprmSDmBinOther*/ 141
998 static const USHORT aVer8Ids1[] =
1000 /*sprmSBOrientation*/ 0x301d,
1001 /*sprmSXaPage*/ 0xB01F,
1002 /*sprmSYaPage*/ 0xB020,
1003 /*sprmSDxaLeft*/ 0xB021,
1004 /*sprmSDxaRight*/ 0xB022,
1005 /*sprmSDzaGutter*/ 0xB025,
1006 /*sprmSFPgnRestart*/ 0x3011,
1007 /*sprmSPgnStart*/ 0x501C,
1008 /*sprmSDmBinFirst*/ 0x5007,
1009 /*sprmSDmBinOther*/ 0x5008
1012 pIds = eVer <= ww::eWW2 ? aVer2Ids1 : eVer <= ww::eWW7 ? aVer67Ids1 : aVer8Ids1;
1014 // 1. Orientierung
1015 aNewSection.maSep.dmOrientPage = ReadBSprm(pSep, pIds[0], 0);
1017 // 2. Papiergroesse
1018 aNewSection.maSep.xaPage = ReadUSprm(pSep, pIds[1], lLetterWidth);
1019 aNewSection.nPgWidth = SvxPaperInfo::GetSloppyPaperDimension(aNewSection.maSep.xaPage);
1021 aNewSection.maSep.yaPage = ReadUSprm(pSep, pIds[2], lLetterHeight);
1023 // 3. LR-Raender
1024 static const USHORT nLef[] = { MM_250, 1800 };
1025 static const USHORT nRig[] = { MM_250, 1800 };
1027 aNewSection.maSep.dxaLeft = ReadUSprm( pSep, pIds[3], nLef[nLIdx]);
1028 aNewSection.maSep.dxaRight = ReadUSprm( pSep, pIds[4], nRig[nLIdx]);
1030 //#110175# 2pages in 1sheet hackery ?
1031 //#i31806# but only swap if 2page in 1sheet is enabled.
1032 // its not clear if dmOrientPage is the correct member to
1033 // decide on this but I am not about to 2nd guess cmc.
1034 if(mrReader.pWDop->doptypography.f2on1 &&
1035 aNewSection.maSep.dmOrientPage == 2)
1036 std::swap(aNewSection.maSep.dxaLeft, aNewSection.maSep.dxaRight);
1038 aNewSection.maSep.dzaGutter = ReadUSprm( pSep, pIds[5], 0);
1040 aNewSection.maSep.fRTLGutter = static_cast< sal_uInt8 >(eVer >= ww::eWW8 ? ReadUSprm( pSep, 0x322A, 0 ) : 0);
1042 // Page Number Restarts - sprmSFPgnRestart
1043 aNewSection.maSep.fPgnRestart = ReadBSprm(pSep, pIds[6], 0);
1045 aNewSection.maSep.pgnStart = ReadBSprm( pSep, pIds[7], 0 );
1047 if (eVer >= ww::eWW6)
1049 if (const BYTE* p = pSep->HasSprm( (eVer <= ww::eWW7 ? 132 : 0x3001) ))
1050 aNewSection.maSep.iHeadingPgn = *p;
1052 if (const BYTE* p = pSep->HasSprm( (eVer <= ww::eWW7 ? 131 : 0x3000) ))
1053 aNewSection.maSep.cnsPgn = *p;
1056 if(const BYTE* pSprmSDmBinFirst = pSep->HasSprm( pIds[8] ))
1057 aNewSection.maSep.dmBinFirst = *pSprmSDmBinFirst;
1059 if (const BYTE* pSprmSDmBinOther = pSep->HasSprm( pIds[9] ))
1060 aNewSection.maSep.dmBinOther = *pSprmSDmBinOther;
1062 static const USHORT nTop[] = { MM_250, 1440 };
1063 static const USHORT nBot[] = { MM_200, 1440 };
1065 static const USHORT aVer2Ids2[] =
1067 /*sprmSDyaTop*/ 143,
1068 /*sprmSDyaBottom*/ 144,
1069 /*sprmSDyaHdrTop*/ 131,
1070 /*sprmSDyaHdrBottom*/ 132,
1071 /*sprmSNLnnMod*/ 129,
1072 /*sprmSLnc*/ 127,
1073 /*sprmSDxaLnn*/ 130,
1074 /*sprmSLnnMin*/ 135
1077 static const USHORT aVer67Ids2[] =
1079 /*sprmSDyaTop*/ 168,
1080 /*sprmSDyaBottom*/ 169,
1081 /*sprmSDyaHdrTop*/ 156,
1082 /*sprmSDyaHdrBottom*/ 157,
1083 /*sprmSNLnnMod*/ 154,
1084 /*sprmSLnc*/ 152,
1085 /*sprmSDxaLnn*/ 155,
1086 /*sprmSLnnMin*/ 160
1088 static const USHORT aVer8Ids2[] =
1090 /*sprmSDyaTop*/ 0x9023,
1091 /*sprmSDyaBottom*/ 0x9024,
1092 /*sprmSDyaHdrTop*/ 0xB017,
1093 /*sprmSDyaHdrBottom*/ 0xB018,
1094 /*sprmSNLnnMod*/ 0x5015,
1095 /*sprmSLnc*/ 0x3013,
1096 /*sprmSDxaLnn*/ 0x9016,
1097 /*sprmSLnnMin*/ 0x501B
1100 pIds = eVer <= ww::eWW2 ? aVer2Ids2 : eVer <= ww::eWW7 ? aVer67Ids2 : aVer8Ids2;
1102 aNewSection.maSep.dyaTop = ReadSprm( pSep, pIds[0], nTop[nLIdx] );
1103 aNewSection.maSep.dyaBottom = ReadSprm( pSep, pIds[1], nBot[nLIdx] );
1104 aNewSection.maSep.dyaHdrTop = ReadUSprm( pSep, pIds[2], 720 );
1105 aNewSection.maSep.dyaHdrBottom = ReadUSprm( pSep, pIds[3], 720 );
1107 if (eVer >= ww::eWW8)
1109 aNewSection.maSep.wTextFlow = ReadUSprm(pSep, 0x5033, 0);
1110 aNewSection.maSep.clm = ReadUSprm( pSep, 0x5032, 0 );
1111 aNewSection.maSep.dyaLinePitch = ReadUSprm(pSep, 0x9031, 360);
1112 if (const BYTE* pS = pSep->HasSprm(0x7030))
1113 aNewSection.maSep.dxtCharSpace = SVBT32ToUInt32(pS);
1115 //sprmSPgbProp
1116 sal_uInt16 pgbProp = ReadSprm( pSep, 0x522F, 0 );
1117 aNewSection.maSep.pgbApplyTo = pgbProp & 0x0007;
1118 aNewSection.maSep.pgbPageDepth = (pgbProp & 0x0018) >> 3;
1119 aNewSection.maSep.pgbOffsetFrom = (pgbProp & 0x00E0) >> 5;
1121 aNewSection.mnBorders =
1122 ::lcl_ReadBorders(eVer <= ww::eWW7, aNewSection.brc, 0, 0, pSep);
1125 // check if Line Numbering must be activated or resetted
1126 if (const BYTE* pSprmSNLnnMod = pSep->HasSprm( pIds[4] ))
1127 aNewSection.maSep.nLnnMod = *pSprmSNLnnMod;
1129 if (const BYTE* pSprmSLnc = pSep->HasSprm( pIds[5] ))
1130 aNewSection.maSep.lnc = *pSprmSLnc;
1132 if (const BYTE* pSprmSDxaLnn = pSep->HasSprm( pIds[6] ))
1133 aNewSection.maSep.dxaLnn = SVBT16ToShort( pSprmSDxaLnn );
1135 if (const BYTE* pSprmSLnnMin = pSep->HasSprm( pIds[7] ))
1136 aNewSection.maSep.lnnMin = *pSprmSLnnMin;
1138 if (eVer <= ww::eWW7)
1139 aNewSection.maSep.grpfIhdt = ReadBSprm(pSep, eVer <= ww::eWW2 ? 128 : 153, 0);
1140 else if (mrReader.pHdFt)
1142 aNewSection.maSep.grpfIhdt = WW8_HEADER_ODD | WW8_FOOTER_ODD;
1144 if (aNewSection.HasTitlePage())
1145 aNewSection.maSep.grpfIhdt |= WW8_HEADER_FIRST | WW8_FOOTER_FIRST;
1147 if (mrReader.pWDop->fFacingPages)
1148 aNewSection.maSep.grpfIhdt |= WW8_HEADER_EVEN | WW8_FOOTER_EVEN;
1150 //See if we have a header or footer for each enabled possibility
1151 //if we do not then we inherit the previous sections header/footer,
1152 for (int nI = 0, nMask = 1; nI < 6; ++nI, nMask <<= 1)
1154 if (aNewSection.maSep.grpfIhdt & nMask)
1156 WW8_CP nStart;
1157 long nLen;
1158 mrReader.pHdFt->GetTextPosExact( static_cast< short >(nI + ( maSegments.size() + 1) * 6), nStart, nLen);
1159 //No header or footer, inherit pervious one, or set to zero
1160 //if no previous one
1161 if (!nLen)
1163 if (
1164 maSegments.empty() ||
1165 !(maSegments.back().maSep.grpfIhdt & nMask)
1168 aNewSection.maSep.grpfIhdt &= ~nMask;
1175 SetLeftRight(aNewSection);
1176 //END read section values
1178 if (eVer >= ww::eWW8)
1179 aNewSection.SetDirection();
1181 mrReader.HandleLineNumbering(aNewSection);
1182 maSegments.push_back(aNewSection);
1185 void SwWW8ImplReader::CopyPageDescHdFt(const SwPageDesc* pOrgPageDesc,
1186 SwPageDesc* pNewPageDesc, BYTE nCode )
1188 // copy first header content section
1189 if (nCode & WW8_HEADER_FIRST)
1190 rDoc.CopyHeader(pOrgPageDesc->GetMaster(), pNewPageDesc->GetMaster());
1192 // copy first footer content section
1193 if( nCode & WW8_FOOTER_FIRST )
1194 rDoc.CopyFooter(pOrgPageDesc->GetMaster(), pNewPageDesc->GetMaster());
1196 if( nCode & ( WW8_HEADER_ODD | WW8_FOOTER_ODD
1197 | WW8_HEADER_EVEN | WW8_FOOTER_EVEN ) )
1199 // copy odd header content section
1200 if( nCode & WW8_HEADER_ODD )
1202 rDoc.CopyHeader(pOrgPageDesc->GetMaster(),
1203 pNewPageDesc->GetMaster() );
1205 // copy odd footer content section
1206 if( nCode & WW8_FOOTER_ODD )
1208 rDoc.CopyFooter(pOrgPageDesc->GetMaster(),
1209 pNewPageDesc->GetMaster());
1211 // copy even header content section
1212 if( nCode & WW8_HEADER_EVEN )
1214 rDoc.CopyHeader(pOrgPageDesc->GetLeft(),
1215 pNewPageDesc->GetLeft());
1217 // copy even footer content section
1218 if( nCode & WW8_FOOTER_EVEN )
1220 rDoc.CopyFooter(pOrgPageDesc->GetLeft(),
1221 pNewPageDesc->GetLeft());
1226 //------------------------------------------------------
1227 // Hilfsroutinen fuer Grafiken und Apos und Tabellen
1228 //------------------------------------------------------
1230 static bool _SetWW8_BRC(bool bVer67, WW8_BRC& rVar, const BYTE* pS)
1232 if( pS )
1234 if( bVer67 )
1235 memcpy( rVar.aBits1, pS, sizeof( SVBT16 ) );
1236 else
1237 rVar = *((WW8_BRC*)pS);
1240 return 0 != pS;
1243 BYTE lcl_ReadBorders(bool bVer67, WW8_BRC* brc, WW8PLCFx_Cp_FKP* pPap,
1244 const WW8RStyle* pSty, const WW8PLCFx_SEPX* pSep)
1246 // Ausgegend von diesen defines:
1247 // #define WW8_TOP 0
1248 // #define WW8_LEFT 1
1249 // #define WW8_BOT 2
1250 // #define WW8_RIGHT 3
1251 // #define WW8_BETW 4
1253 //returns a BYTE filled with a bit for each position that had a sprm
1254 //setting that border
1256 BYTE nBorder = false;
1257 if( pSep )
1259 if( !bVer67 )
1261 BYTE* pSprm[4];
1263 // sprmSBrcTop, sprmSBrcLeft, sprmSBrcBottom, sprmSBrcRight
1264 if( pSep->Find4Sprms( 0x702B, 0x702C, 0x702D, 0x702E,
1265 pSprm[0], pSprm[1], pSprm[2], pSprm[3] ) )
1267 for( int i = 0; i < 4; ++i )
1268 nBorder |= (_SetWW8_BRC( bVer67, brc[ i ], pSprm[ i ] ))<<i;
1272 else
1275 static const USHORT aVer67Ids[5] = { 38, 39, 40, 41, 42 };
1277 static const USHORT aVer8Ids[5] =
1278 { 0x6424, 0x6425, 0x6426, 0x6427, 0x6428 };
1280 const USHORT* pIds = bVer67 ? aVer67Ids : aVer8Ids;
1282 if( pPap )
1284 for( int i = 0; i < 5; ++i, ++pIds )
1285 nBorder |= (_SetWW8_BRC( bVer67, brc[ i ], pPap->HasSprm( *pIds )))<<i;
1287 else if( pSty )
1289 for( int i = 0; i < 5; ++i, ++pIds )
1290 nBorder |= (_SetWW8_BRC( bVer67, brc[ i ], pSty->HasParaSprm( *pIds )))<<i;
1292 else {
1293 ASSERT( pSty || pPap, "WW8PLCFx_Cp_FKP and WW8RStyle "
1294 "and WW8PLCFx_SEPX is 0" );
1298 return nBorder;
1301 void GetLineIndex(SvxBoxItem &rBox, short nLineThickness, short nSpace, BYTE nCol, short nIdx,
1302 USHORT nOOIndex, USHORT nWWIndex, short *pSize=0)
1304 WW8_BordersSO::eBorderCode eCodeIdx;
1306 //Word mirrors some indexes inside outside depending on its position, we
1307 //don't do that, so flip them here
1308 if (nWWIndex == WW8_TOP || nWWIndex == WW8_LEFT)
1310 switch (nIdx)
1312 case 11:
1313 case 12:
1314 nIdx = (nIdx == 11) ? 12 : 11;
1315 break;
1316 case 14:
1317 case 15:
1318 nIdx = (nIdx == 14) ? 15 : 14;
1319 break;
1320 case 17:
1321 case 18:
1322 nIdx = (nIdx == 17) ? 18 : 17;
1323 break;
1324 case 24:
1325 case 25:
1326 nIdx = (nIdx == 24) ? 25 : 24;
1327 break;
1331 // Map to our border types, we should use of one equal line
1332 // thickness, or one of smaller thickness. If too small we
1333 // can make the defecit up in additional white space or
1334 // object size
1335 switch (nIdx)
1337 // First the single lines
1338 case 1:
1339 case 2:
1340 case 5:
1341 // and the unsupported special cases which we map to a single line
1342 case 6:
1343 case 7:
1344 case 8:
1345 case 9:
1346 case 22:
1347 // or if in necessary by a double line
1348 case 24:
1349 case 25:
1350 if( nLineThickness < 10)
1351 eCodeIdx = WW8_BordersSO::single0;// 1 Twip for us
1352 else if( nLineThickness < 20)
1353 eCodeIdx = WW8_BordersSO::single5;// 10 Twips for us
1354 else if (nLineThickness < 50)
1355 eCodeIdx = WW8_BordersSO::single1;// 20 Twips
1356 else if (nLineThickness < 80)
1357 eCodeIdx = WW8_BordersSO::single2;// 50
1358 else if (nLineThickness < 100)
1359 eCodeIdx = WW8_BordersSO::single3;// 80
1360 else if (nLineThickness < 150)
1361 eCodeIdx = WW8_BordersSO::single4;// 100
1362 // Hack: for the quite thick lines we must paint double lines,
1363 // because our singles lines don't come thicker than 5 points.
1364 else if (nLineThickness < 180)
1365 eCodeIdx = WW8_BordersSO::double2;// 150
1366 else
1367 eCodeIdx = WW8_BordersSO::double5;// 180
1368 break;
1369 // then the shading beams which we represent by a double line
1370 case 23:
1371 eCodeIdx = WW8_BordersSO::double1;
1372 break;
1373 // then the double lines, for which we have good matches
1374 case 3:
1375 case 10: //Don't have tripple so use double
1376 if (nLineThickness < 60)
1377 eCodeIdx = WW8_BordersSO::double0;// 22 Twips for us
1378 else if (nLineThickness < 135)
1379 eCodeIdx = WW8_BordersSO::double7;// some more space
1380 else if (nLineThickness < 180)
1381 eCodeIdx = WW8_BordersSO::double1;// 60
1382 else
1383 eCodeIdx = WW8_BordersSO::double2;// 150
1384 break;
1385 case 11:
1386 eCodeIdx = WW8_BordersSO::double4;// 90 Twips for us
1387 break;
1388 case 12:
1389 case 13: //Don't have thin thick thin, so use thick thin
1390 if (nLineThickness < 87)
1391 eCodeIdx = WW8_BordersSO::double8;// 71 Twips for us
1392 else if (nLineThickness < 117)
1393 eCodeIdx = WW8_BordersSO::double9;// 101
1394 else if (nLineThickness < 166)
1395 eCodeIdx = WW8_BordersSO::double10;// 131
1396 else
1397 eCodeIdx = WW8_BordersSO::double5;// 180
1398 break;
1399 case 14:
1400 if (nLineThickness < 46)
1401 eCodeIdx = WW8_BordersSO::double0;// 22 Twips for us
1402 else if (nLineThickness < 76)
1403 eCodeIdx = WW8_BordersSO::double1;// 60
1404 else if (nLineThickness < 121)
1405 eCodeIdx = WW8_BordersSO::double4;// 90
1406 else if (nLineThickness < 166)
1407 eCodeIdx = WW8_BordersSO::double2;// 150
1408 else
1409 eCodeIdx = WW8_BordersSO::double6;// 180
1410 break;
1411 case 15:
1412 case 16: //Don't have thin thick thin, so use thick thin
1413 if (nLineThickness < 46)
1414 eCodeIdx = WW8_BordersSO::double0;// 22 Twips for us
1415 else if (nLineThickness < 76)
1416 eCodeIdx = WW8_BordersSO::double1;// 60
1417 else if (nLineThickness < 121)
1418 eCodeIdx = WW8_BordersSO::double3;// 90
1419 else if (nLineThickness < 166)
1420 eCodeIdx = WW8_BordersSO::double2;// 150
1421 else
1422 eCodeIdx = WW8_BordersSO::double5;// 180
1423 break;
1424 case 17:
1425 if (nLineThickness < 46)
1426 eCodeIdx = WW8_BordersSO::double0;// 22 Twips for us
1427 else if (nLineThickness < 72)
1428 eCodeIdx = WW8_BordersSO::double7;// 52
1429 else if (nLineThickness < 137)
1430 eCodeIdx = WW8_BordersSO::double4;// 90
1431 else
1432 eCodeIdx = WW8_BordersSO::double6;// 180
1433 break;
1434 case 18:
1435 case 19: //Don't have thin thick thin, so use thick thin
1436 if (nLineThickness < 46)
1437 eCodeIdx = WW8_BordersSO::double0;// 22 Twips for us
1438 else if (nLineThickness < 62)
1439 eCodeIdx = WW8_BordersSO::double7;// 52
1440 else if (nLineThickness < 87)
1441 eCodeIdx = WW8_BordersSO::double8;// 71
1442 else if (nLineThickness < 117)
1443 eCodeIdx = WW8_BordersSO::double9;// 101
1444 else if (nLineThickness < 156)
1445 eCodeIdx = WW8_BordersSO::double10;// 131
1446 else
1447 eCodeIdx = WW8_BordersSO::double5;// 180
1448 break;
1449 case 20:
1450 if (nLineThickness < 46)
1451 eCodeIdx = WW8_BordersSO::single1; // 20 Twips for us
1452 else
1453 eCodeIdx = WW8_BordersSO::double1;// 60
1454 break;
1455 case 21:
1456 eCodeIdx = WW8_BordersSO::double1;// 60 Twips for us
1457 break;
1458 default:
1459 eCodeIdx = WW8_BordersSO::single0;
1460 break;
1463 const WW8_BordersSO& rBorders = WW8_BordersSO::Get0x01LineMatch(eCodeIdx);
1464 SvxBorderLine aLine;
1465 aLine.SetOutWidth(rBorders.mnOut);
1466 aLine.SetInWidth(rBorders.mnIn);
1467 aLine.SetDistance(rBorders.mnDist);
1469 //No AUTO for borders as yet, so if AUTO, use BLACK
1470 if (nCol == 0)
1471 nCol = 1;
1473 aLine.SetColor(SwWW8ImplReader::GetCol(nCol));
1475 if (pSize)
1476 pSize[nWWIndex] = nLineThickness+nSpace;
1478 rBox.SetLine(&aLine, nOOIndex);
1479 rBox.SetDistance(nSpace, nOOIndex);
1483 void Set1Border(bool bVer67, SvxBoxItem &rBox, const WW8_BRC& rBor,
1484 USHORT nOOIndex, USHORT nWWIndex, short *pSize=0)
1486 BYTE nCol;
1487 short nSpace, nIdx;
1488 short nLineThickness = rBor.DetermineBorderProperties(bVer67,&nSpace,&nCol,
1489 &nIdx);
1491 GetLineIndex(rBox, nLineThickness, nSpace, nCol, nIdx, nOOIndex, nWWIndex, pSize );
1495 bool lcl_IsBorder(bool bVer67, const WW8_BRC* pbrc, bool bChkBtwn = false)
1497 if( bVer67 )
1498 return ( pbrc[WW8_TOP ].aBits1[0] & 0x18 ) || // brcType != 0
1499 ( pbrc[WW8_LEFT ].aBits1[0] & 0x18 ) ||
1500 ( pbrc[WW8_BOT ].aBits1[0] & 0x18 ) ||
1501 ( pbrc[WW8_RIGHT].aBits1[0] & 0x18 ) ||
1502 ( bChkBtwn && ( pbrc[WW8_BETW ].aBits1[0] )) ||
1503 //can have dotted and dashed with a brcType of 0
1504 ( (pbrc[WW8_TOP ].aBits1[0] & 0x07)+1 > 6) ||
1505 ( (pbrc[WW8_LEFT ].aBits1[0] & 0x07)+1 > 6) ||
1506 ( (pbrc[WW8_BOT ].aBits1[0] & 0x07)+1 > 6) ||
1507 ( (pbrc[WW8_RIGHT].aBits1[0] & 0x07)+1 > 6) ||
1508 ( bChkBtwn && ( (pbrc[WW8_BETW ].aBits1[0] & 0x07)+1 > 6))
1510 // Abfrage auf 0x1f statt 0x18 ist noetig, da zumindest einige
1511 // WW-Versionen ( 6.0 US ) bei dotted brcType auf 0 setzen
1512 else
1513 return pbrc[WW8_TOP ].aBits1[1] || // brcType != 0
1514 pbrc[WW8_LEFT ].aBits1[1] ||
1515 pbrc[WW8_BOT ].aBits1[1] ||
1516 pbrc[WW8_RIGHT].aBits1[1] ||
1517 (bChkBtwn && pbrc[WW8_BETW ].aBits1[1]);
1520 bool SwWW8ImplReader::IsBorder(const WW8_BRC* pbrc, bool bChkBtwn) const
1522 return lcl_IsBorder(bVer67, pbrc, bChkBtwn);
1525 bool WW8_BRC::IsEmpty(bool bVer67) const
1527 return (IsBlank() || IsZeroed(bVer67));
1530 bool WW8_BRC::IsBlank() const
1532 return (aBits1[0] == 0xff && aBits1[1] == 0xff);
1535 bool WW8_BRC::IsZeroed(bool bVer67) const
1537 return (!(bVer67 ? (aBits1[0] & 0x001f) : aBits1[1]));
1540 bool SwWW8ImplReader::SetBorder(SvxBoxItem& rBox, const WW8_BRC* pbrc,
1541 short *pSizeArray, BYTE nSetBorders) const
1543 bool bChange = false;
1544 static const USHORT aIdArr[ 10 ] =
1546 WW8_TOP, BOX_LINE_TOP,
1547 WW8_LEFT, BOX_LINE_LEFT,
1548 WW8_RIGHT, BOX_LINE_RIGHT,
1549 WW8_BOT, BOX_LINE_BOTTOM,
1550 WW8_BETW, BOX_LINE_BOTTOM
1553 for( int i = 0, nEnd = 8; i < nEnd; i += 2 )
1555 // ungueltige Borders ausfiltern
1556 const WW8_BRC& rB = pbrc[ aIdArr[ i ] ];
1557 if( !rB.IsEmpty(bVer67))
1559 Set1Border(bVer67, rBox, rB, aIdArr[i+1], aIdArr[i], pSizeArray);
1560 bChange = true;
1562 else if ( nSetBorders & (1 << aIdArr[i]) )
1565 ##826##, ##653##
1567 If a style has borders set,and the para attributes attempt remove
1568 the borders, then this is perfectably acceptable, so we shouldn't
1569 ignore this blank entry
1571 nSetBorders has a bit set for each location that a sprm set a
1572 border, so with a sprm set, but no border, then disable the
1573 appropiate border
1575 rBox.SetLine( 0, aIdArr[ i+1 ] );
1578 return bChange;
1582 bool SwWW8ImplReader::SetShadow(SvxShadowItem& rShadow, const short *pSizeArray,
1583 const WW8_BRC *pbrc) const
1585 bool bRet = (
1586 ( bVer67 ? (pbrc[WW8_RIGHT].aBits1[ 1 ] & 0x20 )
1587 : (pbrc[WW8_RIGHT].aBits2[ 1 ] & 0x20 ) )
1588 && (pSizeArray && pSizeArray[WW8_RIGHT])
1590 if (bRet)
1592 rShadow.SetColor(Color(COL_BLACK));
1593 short nVal = pSizeArray[WW8_RIGHT];
1594 if (nVal < 0x10)
1595 nVal = 0x10;
1596 rShadow.SetWidth(nVal);
1597 rShadow.SetLocation(SVX_SHADOW_BOTTOMRIGHT);
1598 bRet = true;
1600 return bRet;
1603 void SwWW8ImplReader::GetBorderDistance(const WW8_BRC* pbrc,
1604 Rectangle& rInnerDist) const
1606 // 'dptSpace' is stored in 3 bits of 'Border Code (BRC)'
1607 if (bVer67)
1609 rInnerDist = Rectangle(((pbrc[ 1 ].aBits1[1] >> 3) & 0x1f) * 20,
1610 ((pbrc[ 0 ].aBits1[1] >> 3) & 0x1f) * 20,
1611 ((pbrc[ 3 ].aBits1[1] >> 3) & 0x1f) * 20,
1612 ((pbrc[ 2 ].aBits1[1] >> 3) & 0x1f) * 20 );
1614 else
1616 rInnerDist = Rectangle( (pbrc[ 1 ].aBits2[1] & 0x1f) * 20,
1617 (pbrc[ 0 ].aBits2[1] & 0x1f) * 20,
1618 (pbrc[ 3 ].aBits2[1] & 0x1f) * 20,
1619 (pbrc[ 2 ].aBits2[1] & 0x1f) * 20 );
1624 bool SwWW8ImplReader::SetFlyBordersShadow(SfxItemSet& rFlySet,
1625 const WW8_BRC *pbrc, short *pSizeArray) const
1627 bool bShadowed = false;
1628 if (IsBorder(pbrc))
1630 SvxBoxItem aBox( RES_BOX );
1631 SetBorder(aBox, pbrc, pSizeArray);
1633 rFlySet.Put( aBox );
1635 // fShadow
1636 SvxShadowItem aShadow( RES_SHADOW );
1637 if( SetShadow( aShadow, pSizeArray, pbrc ))
1639 bShadowed = true;
1640 rFlySet.Put( aShadow );
1643 return bShadowed;
1646 //-----------------------------------------
1647 // APOs
1648 //-----------------------------------------
1649 // fuer Berechnung der minimalen FrameSize
1650 #define MAX_BORDER_SIZE 210 // so breit ist max. der Border
1651 #define MAX_EMPTY_BORDER 10 // fuer +-1-Fehler, mindestens 1
1653 static void FlySecur1(short& rSize, const bool bBorder)
1655 short nMin = MINFLY +
1656 bBorder ? MAX_BORDER_SIZE : MAX_EMPTY_BORDER;
1658 if ( rSize < nMin )
1659 rSize = nMin;
1662 inline bool SetValSprm( INT16* pVar, WW8PLCFx_Cp_FKP* pPap, USHORT nId )
1664 const BYTE* pS = pPap->HasSprm( nId );
1665 if( pS )
1666 *pVar = (INT16)SVBT16ToShort( pS );
1667 return ( pS != 0 );
1670 inline bool SetValSprm( INT16* pVar, const WW8RStyle* pStyle, USHORT nId )
1672 const BYTE* pS = pStyle->HasParaSprm( nId );
1673 if( pS )
1674 *pVar = (INT16)SVBT16ToShort( pS );
1675 return ( pS != 0 );
1679 #i1930 revealed that sprm 0x360D as used in tables can affect the frame
1680 around the table. Its full structure is not fully understood as yet.
1682 void WW8FlyPara::ApplyTabPos(const WW8_TablePos *pTabPos)
1684 if (pTabPos)
1686 nSp26 = pTabPos->nSp26;
1687 nSp27 = pTabPos->nSp27;
1688 nSp29 = pTabPos->nSp29;
1689 nLeMgn = pTabPos->nLeMgn;
1690 nRiMgn = pTabPos->nRiMgn;
1691 nUpMgn = pTabPos->nUpMgn;
1692 nLoMgn = pTabPos->nLoMgn;
1693 nSp37 = pTabPos->nSp37;
1697 WW8FlyPara::WW8FlyPara(bool bIsVer67, const WW8FlyPara* pSrc /* = 0 */)
1699 if ( pSrc )
1700 memcpy( this, pSrc, sizeof( WW8FlyPara ) ); // Copy-Ctor
1701 else
1703 memset( this, 0, sizeof( WW8FlyPara ) ); // Default-Ctor
1704 nSp37 = 2; // Default: Umfluss
1706 bVer67 = bIsVer67;
1709 bool WW8FlyPara::operator==(const WW8FlyPara& rSrc) const
1712 Compare the parts that word seems to compare for equivalence.
1713 Interestingly being autoheight or absolute height (the & 0x7fff) doesn't
1714 matter to word e.g. #110507#
1716 return
1718 (nSp26 == rSrc.nSp26) &&
1719 (nSp27 == rSrc.nSp27) &&
1720 ((nSp45 & 0x7fff) == (rSrc.nSp45 & 0x7fff)) &&
1721 (nSp28 == rSrc.nSp28) &&
1722 (nLeMgn == rSrc.nLeMgn) &&
1723 (nRiMgn == rSrc.nRiMgn) &&
1724 (nUpMgn == rSrc.nUpMgn) &&
1725 (nLoMgn == rSrc.nLoMgn) &&
1726 (nSp29 == rSrc.nSp29) &&
1727 (nSp37 == rSrc.nSp37)
1731 // Read fuer normalen Text
1732 void WW8FlyPara::Read(const BYTE* pSprm29, WW8PLCFx_Cp_FKP* pPap)
1734 if (pSprm29)
1735 nOrigSp29 = *pSprm29; // PPC ( Bindung )
1737 const BYTE* pS = 0;
1738 if( bVer67 )
1740 SetValSprm( &nSp26, pPap, 26 ); // X-Position //sprmPDxaAbs
1741 //set in me or in parent style
1742 mbVertSet |= SetValSprm( &nSp27, pPap, 27 ); // Y-Position //sprmPDyaAbs
1743 SetValSprm( &nSp45, pPap, 45 ); // Hoehe //sprmPWHeightAbs
1744 SetValSprm( &nSp28, pPap, 28 ); // Breite //sprmPDxaWidth
1745 SetValSprm( &nLeMgn, pPap, 49 ); // L-Raender //sprmPDxaFromText
1746 SetValSprm( &nRiMgn, pPap, 49 ); // R-Raender //sprmPDxaFromText
1747 SetValSprm( &nUpMgn, pPap, 48 ); // U-Raender //sprmPDyaFromText
1748 SetValSprm( &nLoMgn, pPap, 48 ); // D-Raender //sprmPDyaFromText
1750 pS = pPap->HasSprm( 37 ); //sprmPWr
1751 if( pS )
1752 nSp37 = *pS;
1754 else
1756 SetValSprm( &nSp26, pPap, 0x8418 ); // X-Position
1757 //set in me or in parent style
1758 mbVertSet |= SetValSprm( &nSp27, pPap, 0x8419 ); // Y-Position
1759 SetValSprm( &nSp45, pPap, 0x442B ); // Hoehe
1760 SetValSprm( &nSp28, pPap, 0x841A ); // Breite
1761 SetValSprm( &nLeMgn, pPap, 0x842F ); // L-Raender
1762 SetValSprm( &nRiMgn, pPap, 0x842F ); // R-Raender
1763 SetValSprm( &nUpMgn, pPap, 0x842E ); // U-Raender
1764 SetValSprm( &nLoMgn, pPap, 0x842E ); // D-Raender
1766 pS = pPap->HasSprm( 0x2423 ); // Umfluss
1767 if( pS )
1768 nSp37 = *pS;
1771 if( ::lcl_ReadBorders( bVer67, brc, pPap )) // Umrandung
1772 bBorderLines = ::lcl_IsBorder( bVer67, brc );
1775 #i8798#
1776 Appears that with no dyaAbs set then the actual vert anchoring set is
1777 ignored and we remain relative to text, so if that is the case we are 0
1778 from para anchor, so we update the frame to have explicitly this type of
1779 anchoring
1781 if (!mbVertSet)
1782 nSp29 = (nOrigSp29 & 0xCF) | 0x20;
1783 else
1784 nSp29 = nOrigSp29;
1787 void WW8FlyPara::ReadFull(const BYTE* pSprm29, SwWW8ImplReader* pIo)
1789 WW8PLCFMan* pPlcxMan = pIo->pPlcxMan;
1790 WW8PLCFx_Cp_FKP* pPap = pPlcxMan->GetPapPLCF();
1792 Read(pSprm29, pPap); // Lies Apo-Parameter
1794 do{ // Block zum rausspringen
1795 if( nSp45 != 0 /* || nSp28 != 0 */ )
1796 break; // bGrafApo nur bei Hoehe automatisch
1797 if( pIo->pWwFib->fComplex )
1798 break; // (*pPap)++ geht bei FastSave schief
1799 // -> bei FastSave kein Test auf Grafik-APO
1800 SvStream* pIoStrm = pIo->pStrm;
1801 ULONG nPos = pIoStrm->Tell();
1802 WW8PLCFxSave1 aSave;
1803 pPlcxMan->GetPap()->Save( aSave );
1804 bGrafApo = false;
1806 do{ // Block zum rausspringen
1808 BYTE nTxt[2];
1810 pIoStrm->Read( nTxt, 2 ); // lies Text
1811 if( nTxt[0] != 0x01 || nTxt[1] != 0x0d )// nur Grafik + CR ?
1812 break; // Nein
1814 (*pPap)++; // Naechste Zeile
1816 // In APO ?
1817 //sprmPPc
1818 const BYTE* pS = pPap->HasSprm( bVer67 ? 29 : 0x261B );
1820 // Nein -> Grafik-Apo
1821 if( !pS ){
1822 bGrafApo = true;
1823 break; // Ende des APO
1826 ww::WordVersion eVer = pIo->GetFib().GetFIBVersion();
1827 WW8FlyPara *pNowStyleApo=0;
1828 USHORT nColl = pPap->GetIstd();
1829 ww::sti eSti = eVer < ww::eWW6 ? ww::GetCanonicalStiFromStc( static_cast< sal_uInt8 >(nColl) ) : static_cast<ww::sti>(nColl);
1830 while (eSti != ww::stiNil && 0 == (pNowStyleApo = pIo->pCollA[nColl].pWWFly))
1832 nColl = pIo->pCollA[nColl].nBase;
1833 eSti = eVer < ww::eWW6 ? ww::GetCanonicalStiFromStc( static_cast< sal_uInt8 >(nColl) ) : static_cast<ww::sti>(nColl);
1836 WW8FlyPara aF(bVer67, pNowStyleApo);
1837 // Neuer FlaPara zum Vergleich
1838 aF.Read( pS, pPap ); // WWPara fuer neuen Para
1839 if( !( aF == *this ) ) // selber APO ? ( oder neuer ? )
1840 bGrafApo = true; // nein -> 1-zeiliger APO
1841 // -> Grafik-APO
1843 while( 0 ); // Block zum rausspringen
1845 pPlcxMan->GetPap()->Restore( aSave );
1846 pIoStrm->Seek( nPos );
1847 }while( 0 ); // Block zum rausspringen
1851 // Read fuer Apo-Defs in Styledefs
1852 void WW8FlyPara::Read(const BYTE* pSprm29, WW8RStyle* pStyle)
1854 if (pSprm29)
1855 nOrigSp29 = *pSprm29; // PPC ( Bindung )
1857 const BYTE* pS = 0;
1858 if (bVer67)
1860 SetValSprm( &nSp26, pStyle, 26 ); // X-Position
1861 //set in me or in parent style
1862 mbVertSet |= SetValSprm(&nSp27, pStyle, 27); // Y-Position
1863 SetValSprm( &nSp45, pStyle, 45 ); // Hoehe
1864 SetValSprm( &nSp28, pStyle, 28 ); // Breite
1865 SetValSprm( &nLeMgn, pStyle, 49 ); // L-Raender
1866 SetValSprm( &nRiMgn, pStyle, 49 ); // R-Raender
1867 SetValSprm( &nUpMgn, pStyle, 48 ); // U-Raender
1868 SetValSprm( &nLoMgn, pStyle, 48 ); // D-Raender
1870 pS = pStyle->HasParaSprm( 37 ); // Umfluss
1871 if( pS )
1872 nSp37 = *pS;
1874 else
1876 SetValSprm( &nSp26, pStyle, 0x8418 ); // X-Position
1877 //set in me or in parent style
1878 mbVertSet |= SetValSprm(&nSp27, pStyle, 0x8419); // Y-Position
1879 SetValSprm( &nSp45, pStyle, 0x442B ); // Hoehe
1880 SetValSprm( &nSp28, pStyle, 0x841A ); // Breite
1881 SetValSprm( &nLeMgn, pStyle, 0x842F ); // L-Raender
1882 SetValSprm( &nRiMgn, pStyle, 0x842F ); // R-Raender
1883 SetValSprm( &nUpMgn, pStyle, 0x842E ); // U-Raender
1884 SetValSprm( &nLoMgn, pStyle, 0x842E ); // D-Raender
1886 pS = pStyle->HasParaSprm( 0x2423 ); // Umfluss
1887 if( pS )
1888 nSp37 = *pS;
1891 if (::lcl_ReadBorders(bVer67, brc, 0, pStyle)) // Umrandung
1892 bBorderLines = ::lcl_IsBorder(bVer67, brc);
1895 #i8798#
1896 Appears that with no dyaAbs set then the actual vert anchoring set is
1897 ignored and we remain relative to text, so if that is the case we are 0
1898 from para anchor, so we update the frame to have explicitly this type of
1899 anchoring
1901 if (!mbVertSet)
1902 nSp29 = (nOrigSp29 & 0xCF) | 0x20;
1903 else
1904 nSp29 = nOrigSp29;
1907 bool WW8FlyPara::IsEmpty() const
1909 WW8FlyPara aEmpty(bVer67);
1911 wr of 0 like 2 appears to me to be equivalent for checking here. See
1912 #107103# if wrong, so given that the empty is 2, if we are 0 then set
1913 empty to 0 to make 0 equiv to 2 for empty checking
1915 ASSERT(aEmpty.nSp37 == 2, "this is not what we expect for nSp37");
1916 if (this->nSp37 == 0)
1917 aEmpty.nSp37 = 0;
1918 if (aEmpty == *this)
1919 return true;
1920 return false;
1923 // OD 14.10.2003 #i18732# - changes made on behalf of CMC
1924 WW8SwFlyPara::WW8SwFlyPara( SwPaM& rPaM,
1925 SwWW8ImplReader& rIo,
1926 WW8FlyPara& rWW,
1927 const sal_uInt32 nWWPgTop,
1928 const sal_uInt32 nPgLeft,
1929 const sal_uInt32 nPgWidth,
1930 const INT32 nIniFlyDx,
1931 const INT32 nIniFlyDy )
1933 (void) rPaM;
1934 (void) nPgLeft;
1936 memset( this, 0, sizeof( WW8SwFlyPara ) ); // Initialisieren
1937 nNewNettoWidth = MINFLY; // Minimum
1939 eSurround = ( rWW.nSp37 > 1 ) ? SURROUND_IDEAL : SURROUND_NONE;
1942 #95905#, #83307# seems to have gone away now, so reenable parallel
1943 wrapping support for frames in headers/footers. I don't know if we truly
1944 have an explictly specified behaviour for these circumstances.
1947 nHeight = rWW.nSp45;
1948 if( nHeight & 0x8000 )
1950 nHeight &= 0x7fff;
1951 eHeightFix = ATT_MIN_SIZE;
1953 else
1954 eHeightFix = ATT_FIX_SIZE;
1956 if( nHeight <= MINFLY )
1957 { // keine Angabe oder Stuss
1958 eHeightFix = ATT_MIN_SIZE;
1959 nHeight = MINFLY;
1962 nWidth = nNettoWidth = rWW.nSp28;
1963 if( nWidth <= 10 ) // Auto-Breite
1965 bAutoWidth = true;
1966 rIo.maTracer.Log(sw::log::eAutoWidthFrame);
1967 nWidth = nNettoWidth =
1968 msword_cast<sal_Int16>((nPgWidth ? nPgWidth : 2268)); // 4 cm
1970 if( nWidth <= MINFLY )
1971 nWidth = nNettoWidth = MINFLY; // Minimale Breite
1973 eVAlign = text::VertOrientation::NONE; // Defaults
1974 eHAlign = text::HoriOrientation::NONE;
1975 nYPos = 0;
1976 nXPos = 0;
1978 nRiMgn = rWW.nRiMgn;
1979 nLeMgn = rWW.nLeMgn;
1980 nLoMgn = rWW.nLoMgn;
1981 nUpMgn = rWW.nUpMgn;
1984 See issue #i9178# for the 9 anchoring options, and make sure they stay
1985 working if you modify the anchoring logic here.
1988 // Wenn der Fly links, rechts, oben oder unten aligned ist,
1989 // wird der aeussere Textabstand ignoriert, da sonst
1990 // der Fly an falscher Position landen wuerde
1991 // JP 18.11.98: Problematisch wird es nur bei Innen/Aussen
1993 // Bindung
1994 nYBind = (( rWW.nSp29 & 0x30 ) >> 4);
1995 // --> OD 2005-08-24 #i53725# - absolute positioned objects have to be
1996 // anchored at-paragraph to assure its correct anchor position.
1997 eAnchor = FLY_AT_CNTNT;
1998 // <--
1999 switch (nYBind)
2001 case 0: //relative to margin
2002 eVRel = text::RelOrientation::PAGE_PRINT_AREA;
2003 break;
2004 case 1: //relative to page
2005 eVRel = text::RelOrientation::PAGE_FRAME;
2006 break;
2007 default: //relative to text
2008 eVRel = text::RelOrientation::FRAME;
2009 break;
2012 // OD 14.10.2003 #i18732#
2013 switch( rWW.nSp27 ) // besondere Y-Positionen ?
2015 case -4:
2016 eVAlign = text::VertOrientation::TOP;
2017 if (nYBind < 2)
2018 nUpMgn = 0;
2019 break; // oben
2020 case -8:
2021 eVAlign = text::VertOrientation::CENTER;
2022 break; // zentriert
2023 case -12:
2024 eVAlign = text::VertOrientation::BOTTOM;
2025 if (nYBind < 2)
2026 nLoMgn = 0;
2027 break; // unten
2028 default:
2029 nYPos = rWW.nSp27 + (short)nIniFlyDy;
2030 break; // Korrekturen per Ini-Datei
2033 switch( rWW.nSp26 ) // besondere X-Positionen ?
2035 case 0:
2036 eHAlign = text::HoriOrientation::LEFT;
2037 nLeMgn = 0;
2038 break; // links
2039 case -4:
2040 eHAlign = text::HoriOrientation::CENTER;
2041 break; // zentriert
2042 case -8:
2043 eHAlign = text::HoriOrientation::RIGHT;
2044 nRiMgn = 0;
2045 break; // rechts
2046 case -12:
2047 eHAlign = text::HoriOrientation::LEFT;
2048 bToggelPos = true;
2049 break; // innen
2050 case -16:
2051 eHAlign = text::HoriOrientation::RIGHT;
2052 bToggelPos = true;
2053 break; // aussen
2054 default:
2055 nXPos = rWW.nSp26 + (short)nIniFlyDx;
2056 break; // Korrekturen per Ini-Datei
2059 nXBind = ( rWW.nSp29 & 0xc0 ) >> 6;
2060 // OD 14.10.2003 #i18732#
2061 switch (nXBind) // X - Bindung -> Koordinatentransformation
2063 case 0: //relative to column
2064 eHRel = text::RelOrientation::FRAME;
2065 break;
2066 case 1: //relative to margin
2067 eHRel = text::RelOrientation::PAGE_PRINT_AREA;
2068 break;
2069 default: //relative to page
2070 eHRel = text::RelOrientation::PAGE_FRAME;
2071 break;
2074 // --> OD 2004-12-06 #i36649# - adjustments for certain horizontal alignments
2075 // Note: These special adjustments found by an investigation of documents
2076 // containing frames with different left/right border distances and
2077 // distances to text. The outcome is some how strange.
2078 // Note: These adjustments causes wrong horizontal positions for frames,
2079 // which are aligned inside|outside to page|margin on even pages,
2080 // the left and right border distances are different.
2081 // --> OD 2005-01-19 #119176# - no adjustments possible, if frame has
2082 // automatic width.
2083 // determine left border distance
2084 INT16 nLeBorderMgn( 0L );
2085 if ( !bAutoWidth )
2087 INT16 nTemp = rWW.brc[WW8_LEFT].DetermineBorderProperties(rWW.bVer67,
2088 &nLeBorderMgn);
2089 nLeBorderMgn = nLeBorderMgn + nTemp;
2091 // determine right border distance
2092 INT16 nRiBorderMgn( 0L );
2093 if ( !bAutoWidth )
2095 INT16 nTemp = rWW.brc[WW8_RIGHT].DetermineBorderProperties(rWW.bVer67,
2096 &nRiBorderMgn);
2097 nRiBorderMgn = nRiBorderMgn + nTemp;
2099 if ( !bAutoWidth && eHAlign == text::HoriOrientation::LEFT && eHRel == text::RelOrientation::PAGE_FRAME )
2101 // convert 'left to page' to
2102 // 'from left -<width>-<2*left border distance>-<right wrap distance>
2103 // to page text area'
2104 eHAlign = text::HoriOrientation::NONE;
2105 eHRel = text::RelOrientation::PAGE_PRINT_AREA;
2106 nXPos = -nWidth - (2*nLeBorderMgn) - rWW.nRiMgn;
2107 // re-set left wrap distance
2108 nLeMgn = rWW.nLeMgn;
2110 else if ( !bAutoWidth && eHAlign == text::HoriOrientation::RIGHT && eHRel == text::RelOrientation::PAGE_FRAME )
2112 // convert 'right to page' to
2113 // 'from left <right border distance-left border distance>+<left wrap distance>
2114 // to right page border'
2115 eHAlign = text::HoriOrientation::NONE;
2116 eHRel = text::RelOrientation::PAGE_RIGHT;
2117 nXPos = ( nRiBorderMgn - nLeBorderMgn ) + rWW.nLeMgn;
2118 // re-set right wrap distance
2119 nRiMgn = rWW.nRiMgn;
2121 else if ( !bAutoWidth && eHAlign == text::HoriOrientation::LEFT && eHRel == text::RelOrientation::PAGE_PRINT_AREA )
2123 // convert 'left to margin' to
2124 // 'from left -<left border distance> to page text area'
2125 eHAlign = text::HoriOrientation::NONE;
2126 eHRel = text::RelOrientation::PAGE_PRINT_AREA;
2127 nXPos = -nLeBorderMgn;
2128 // re-set left wrap distance
2129 nLeMgn = rWW.nLeMgn;
2131 else if ( !bAutoWidth && eHAlign == text::HoriOrientation::RIGHT && eHRel == text::RelOrientation::PAGE_PRINT_AREA )
2133 // convert 'right to margin' to
2134 // 'from left -<width>-<left border distance> to right page border'
2135 eHAlign = text::HoriOrientation::NONE;
2136 eHRel = text::RelOrientation::PAGE_RIGHT;
2137 nXPos = -nWidth - nLeBorderMgn;
2138 // re-set right wrap distance
2139 nRiMgn = rWW.nRiMgn;
2141 else if (rWW.bBorderLines)
2142 // <--
2145 #i582#
2146 Word has a curious bug where the offset stored do not take into
2147 account the internal distance from the corner both
2149 INT16 nLeLMgn = 0;
2150 INT16 nTemp = rWW.brc[WW8_LEFT].DetermineBorderProperties(rWW.bVer67,
2151 &nLeLMgn);
2152 nLeLMgn = nLeLMgn + nTemp;
2154 if (nLeLMgn)
2156 if (eHAlign == text::HoriOrientation::LEFT)
2157 eHAlign = text::HoriOrientation::NONE;
2158 nXPos = nXPos - nLeLMgn;
2162 // --> OD 2007-07-03 #148498#
2163 // adjustments for certain vertical alignments
2164 if ( eVAlign == text::VertOrientation::NONE && eVRel == text::RelOrientation::PAGE_PRINT_AREA )
2166 // convert "<X> from top page text area" to
2167 // "<X + page top margin> from page"
2168 eVRel = text::RelOrientation::PAGE_FRAME;
2169 nYPos = static_cast< INT16 >( nYPos + nWWPgTop );
2171 // <--
2173 FlySecur1( nWidth, rWW.bBorderLines ); // passen Raender ?
2174 FlySecur1( nHeight, rWW.bBorderLines );
2178 // hat ein Fly in WW eine automatische Breite, dann muss das durch
2179 // nachtraegliches Anpassen der ( im SW festen ) Fly-Breite simuliert werden.
2180 // Dabei kann die Fly-Breite groesser oder kleiner werden, da der Default-Wert
2181 // ohne Wissen ueber den Inhalt eingesetzt wird.
2182 void WW8SwFlyPara::BoxUpWidth( long nInWidth )
2184 if( bAutoWidth && nInWidth > nNewNettoWidth )
2185 nNewNettoWidth = nInWidth;
2188 // Die Klasse WW8FlySet ist von SfxItemSet abgeleitet und stellt auch
2189 // im Prizip nicht mehr zur Verfuegung, ist aber fuer mich besser
2190 // zu handeln
2191 // WW8FlySet-ctor fuer Apos und Graf-Apos
2192 WW8FlySet::WW8FlySet(SwWW8ImplReader& rReader, const WW8FlyPara* pFW,
2193 const WW8SwFlyPara* pFS, bool bGraf)
2194 : SfxItemSet(rReader.rDoc.GetAttrPool(),RES_FRMATR_BEGIN,RES_FRMATR_END-1)
2196 if (!rReader.mbNewDoc)
2197 Reader::ResetFrmFmtAttrs(*this); // Abstand/Umrandung raus
2198 // Position
2199 Put(SvxFrameDirectionItem(FRMDIR_HORI_LEFT_TOP, RES_FRAMEDIR));
2201 /*Below can all go when we have from left in rtl mode*/
2202 SwTwips nXPos = pFS->nXPos;
2203 sal_Int16 eHRel = pFS->eHRel;
2204 rReader.MiserableRTLGraphicsHack(nXPos, pFS->nWidth, pFS->eHAlign, eHRel);
2205 /*Above can all go when we have from left in rtl mode*/
2206 Put( SwFmtHoriOrient(nXPos, pFS->eHAlign, pFS->eHRel, pFS->bToggelPos ));
2207 Put( SwFmtVertOrient( pFS->nYPos, pFS->eVAlign, pFS->eVRel ) );
2209 if (pFS->nLeMgn || pFS->nRiMgn) // Raender setzen
2210 Put(SvxLRSpaceItem(pFS->nLeMgn, pFS->nRiMgn, 0, 0, RES_LR_SPACE));
2212 if (pFS->nUpMgn || pFS->nLoMgn)
2213 Put(SvxULSpaceItem(pFS->nUpMgn, pFS->nLoMgn, RES_UL_SPACE));
2215 //we no longer need to hack around the header/footer problems
2216 Put(SwFmtSurround(pFS->eSurround));
2218 short aSizeArray[5]={0};
2219 rReader.SetFlyBordersShadow(*this,(const WW8_BRC*)pFW->brc,&aSizeArray[0]);
2221 // der 5. Parameter ist immer 0, daher geht beim Cast nix verloren
2223 // OD 2004-05-18 #i27767#
2224 // --> OD 2004-10-18 #i35017# - constant name has changed
2225 Put( SwFmtWrapInfluenceOnObjPos(
2226 text::WrapInfluenceOnPosition::ONCE_SUCCESSIVE ) );
2227 // <--
2229 if( !bGraf )
2231 Put( SwFmtAnchor(pFS->eAnchor) );
2232 // Groesse einstellen
2234 //Ordinarily with frames, the border width and spacing is
2235 //placed outside the frame, making it larger. With these
2236 //types of frames, the left right thickness and space makes
2237 //it wider, but the top bottom spacing and border thickness
2238 //is placed inside.
2239 Put( SwFmtFrmSize( pFS->eHeightFix, pFS->nWidth +
2240 aSizeArray[WW8_LEFT] + aSizeArray[WW8_RIGHT],
2241 pFS->nHeight));
2245 // WW8FlySet-ctor fuer zeichengebundene Grafiken
2246 WW8FlySet::WW8FlySet( SwWW8ImplReader& rReader, const SwPaM* pPaM,
2247 const WW8_PIC& rPic, long nWidth, long nHeight )
2248 : SfxItemSet(rReader.rDoc.GetAttrPool(),RES_FRMATR_BEGIN,RES_FRMATR_END-1)
2250 Init(rReader, pPaM);
2252 Put(SvxFrameDirectionItem(FRMDIR_HORI_LEFT_TOP, RES_FRAMEDIR));
2254 short aSizeArray[5]={0};
2256 If we have set borders then in word the graphic is displaced from the left
2257 and top the width of the borders of those sides, and then the shadow
2258 itself is drawn to the bottom and right of the displaced graphic. In word
2259 the total size is that of the graphic plus the borders, plus the total
2260 shadow around all edges, for this translation the top and left shadow
2261 region is translated spacing around the graphic to those sides, and the
2262 bottom and right shadow size is added to the graphic size.
2264 if (rReader.SetFlyBordersShadow( *this, rPic.rgbrc, &aSizeArray[0]))
2266 Put(SvxLRSpaceItem( aSizeArray[WW8_LEFT], 0, 0, 0, RES_LR_SPACE ) );
2267 Put(SvxULSpaceItem( aSizeArray[WW8_TOP], 0, RES_UL_SPACE ));
2268 aSizeArray[WW8_RIGHT]*=2;
2269 aSizeArray[WW8_BOT]*=2;
2272 Put( SwFmtFrmSize( ATT_FIX_SIZE, nWidth+aSizeArray[WW8_LEFT]+
2273 aSizeArray[WW8_RIGHT], nHeight+aSizeArray[WW8_TOP]
2274 + aSizeArray[WW8_BOT]) );
2277 WW8FlySet::WW8FlySet(const SwWW8ImplReader& rReader, const SwPaM* pPaM)
2278 : SfxItemSet(rReader.rDoc.GetAttrPool(),RES_FRMATR_BEGIN,RES_FRMATR_END-1)
2280 Init(rReader, pPaM);
2283 void WW8FlySet::Init(const SwWW8ImplReader& rReader, const SwPaM* pPaM)
2285 if (!rReader.mbNewDoc)
2286 Reader::ResetFrmFmtAttrs(*this); // Abstand/Umrandung raus
2288 Put(SvxLRSpaceItem(RES_LR_SPACE)); //inline writer ole2 objects start with 0.2cm l/r
2289 SwFmtAnchor aAnchor(FLY_IN_CNTNT);
2291 aAnchor.SetAnchor(pPaM->GetPoint());
2292 Put(aAnchor);
2294 //The horizontal default is on the baseline, the vertical is centered
2295 //around the character center it appears
2296 if (rReader.maSectionManager.CurrentSectionIsVertical())
2297 Put(SwFmtVertOrient(0, text::VertOrientation::CHAR_CENTER,text::RelOrientation::CHAR));
2298 else
2299 Put(SwFmtVertOrient(0, text::VertOrientation::TOP, text::RelOrientation::FRAME));
2302 WW8DupProperties::WW8DupProperties(SwDoc &rDoc, SwWW8FltControlStack *pStk)
2303 : pCtrlStck(pStk),
2304 aChrSet(rDoc.GetAttrPool(), RES_CHRATR_BEGIN, RES_CHRATR_END - 1 ),
2305 aParSet(rDoc.GetAttrPool(), RES_PARATR_BEGIN, RES_PARATR_END - 1 )
2307 //Close any open character properties and duplicate them inside the
2308 //first table cell
2309 USHORT nCnt = static_cast< USHORT >(pCtrlStck->Count());
2310 for (USHORT i=0; i < nCnt; i++)
2312 const SwFltStackEntry* pEntry = (*pCtrlStck)[ i ];
2313 if(pEntry->bLocked)
2315 if (isCHRATR(pEntry->pAttr->Which()))
2317 aChrSet.Put( *pEntry->pAttr );
2320 else if (isPARATR(pEntry->pAttr->Which()))
2322 aParSet.Put( *pEntry->pAttr );
2328 void WW8DupProperties::Insert(const SwPosition &rPos)
2330 const SfxItemSet *pSet=&aChrSet;
2331 for(int i=0;i<2;i++)
2333 if (i==1)
2334 pSet = &aParSet;
2336 if( pSet->Count() )
2338 SfxItemIter aIter( *pSet );
2339 const SfxPoolItem* pItem = aIter.GetCurItem();
2342 pCtrlStck->NewAttr(rPos, *pItem);
2343 }while( !aIter.IsAtEnd() && 0 != ( pItem = aIter.NextItem() ) );
2348 void SwWW8ImplReader::MoveInsideFly(const SwFrmFmt *pFlyFmt)
2350 WW8DupProperties aDup(rDoc,pCtrlStck);
2352 pCtrlStck->SetAttr(*pPaM->GetPoint(), 0, false);
2354 // Setze Pam in den FlyFrame
2355 const SwFmtCntnt& rCntnt = pFlyFmt->GetCntnt();
2356 ASSERT( rCntnt.GetCntntIdx(), "Kein Inhalt vorbereitet." );
2357 pPaM->GetPoint()->nNode = rCntnt.GetCntntIdx()->GetIndex() + 1;
2358 pPaM->GetPoint()->nContent.Assign( pPaM->GetCntntNode(), 0 );
2360 aDup.Insert(*pPaM->GetPoint());
2363 SwTwips SwWW8ImplReader::MoveOutsideFly(SwFrmFmt *pFlyFmt,
2364 const SwPosition &rPos, bool bTableJoin)
2366 SwTwips nRetWidth = 0;
2367 // Alle Attribute schliessen, da sonst Attribute entstehen koennen,
2368 // die aus Flys rausragen
2369 WW8DupProperties aDup(rDoc,pCtrlStck);
2370 pCtrlStck->SetAttr(*pPaM->GetPoint(), 0, false);
2373 #i1291
2374 If this fly frame consists entirely of one table inside a frame
2375 followed by an empty paragraph then we want to delete the empty
2376 paragraph so as to get the frame to autoshrink to the size of the
2377 table to emulate words behaviour closer.
2379 if (bTableJoin)
2381 const SwNodeIndex* pNodeIndex = pFlyFmt->GetCntnt().
2382 GetCntntIdx();
2383 if (pNodeIndex)
2385 SwNodeIndex aIdx( *pNodeIndex, 1 ),
2386 aEnd( *pNodeIndex->GetNode().EndOfSectionNode() );
2388 if (aIdx < aEnd)
2390 if(aIdx.GetNode().IsTableNode())
2392 SwTableNode *pTable = aIdx.GetNode().GetTableNode();
2393 aIdx = *aIdx.GetNode().EndOfSectionNode();
2394 aIdx++;
2395 if ( (aIdx < aEnd) && aIdx.GetNode().IsTxtNode() )
2397 SwTxtNode *pNd = aIdx.GetNode().GetTxtNode();
2398 aIdx++;
2399 if (aIdx == aEnd && pNd && !pNd->GetTxt().Len())
2401 rDoc.DelFullPara( *pPaM );
2403 SwTable& rTable = pTable->GetTable();
2404 SwFrmFmt* pTblFmt = rTable.GetFrmFmt();
2406 if (pTblFmt)
2408 SwFmtFrmSize aSize = pTblFmt->GetFrmSize();
2409 aSize.SetHeightSizeType(ATT_MIN_SIZE);
2410 aSize.SetHeight(MINLAY);
2411 pFlyFmt->SetFmtAttr(aSize);
2412 pTblFmt->SetFmtAttr(SwFmtHoriOrient(0,text::HoriOrientation::FULL));
2413 nRetWidth = aSize.GetWidth();
2422 *pPaM->GetPoint() = rPos;
2423 aDup.Insert(*pPaM->GetPoint());
2424 return nRetWidth;
2427 WW8FlyPara *SwWW8ImplReader::ConstructApo(const ApoTestResults &rApo,
2428 const WW8_TablePos *pTabPos)
2430 WW8FlyPara *pRet = 0;
2431 ASSERT(rApo.HasFrame() || pTabPos,
2432 "If no frame found, *MUST* be in a table");
2434 pRet = new WW8FlyPara(bVer67, rApo.mpStyleApo);
2436 // APO-Parameter ermitteln und Test auf bGrafApo
2437 if (rApo.HasFrame())
2438 pRet->ReadFull(rApo.mpSprm29, this);
2440 pRet->ApplyTabPos(pTabPos);
2442 if (pRet->IsEmpty())
2443 delete pRet, pRet = 0;
2444 return pRet;
2447 bool SwWW8ImplReader::IsDropCap()
2449 // Find the DCS (Drop Cap Specifier) for the paragraph
2450 // if does not exist or if the first three bits are 0
2451 // then there is no dropcap on the paragraph
2452 WW8PLCFx_Cp_FKP *pPap = pPlcxMan ? pPlcxMan->GetPapPLCF() : 0;
2453 if (pPap)
2455 const BYTE *pDCS;
2456 if (bVer67)
2457 pDCS = pPap->HasSprm(46);
2458 else
2459 pDCS = pPlcxMan->GetPapPLCF()->HasSprm(0x442C);
2460 if(pDCS)
2462 short nDCS = SVBT16ToShort( pDCS );
2463 if((nDCS | 7) != 0)
2464 return true;
2467 return false;
2470 bool SwWW8ImplReader::StartApo(const ApoTestResults &rApo,
2471 const WW8_TablePos *pTabPos)
2473 if (0 == (pWFlyPara = ConstructApo(rApo, pTabPos)))
2474 return false;
2476 // --> OD 2007-07-03 #148498#
2477 // <WW8SwFlyPara> constructor has changed - new 4th parameter
2478 // containing WW8 page top margin.
2479 pSFlyPara = new WW8SwFlyPara( *pPaM, *this, *pWFlyPara,
2480 maSectionManager.GetWWPageTopMargin(),
2481 maSectionManager.GetPageLeft(),
2482 maSectionManager.GetTextAreaWidth(),
2483 nIniFlyDx, nIniFlyDy);
2484 // <--
2486 // If this paragraph is a Dropcap set the flag and we will deal with it later
2487 if (IsDropCap())
2489 bDropCap = true;
2490 pAktItemSet = new SfxItemSet( rDoc.GetAttrPool(), RES_CHRATR_BEGIN, RES_PARATR_END - 1 );
2491 return false;
2494 if( !pWFlyPara->bGrafApo )
2497 // Innerhalb des GrafApo muessen Textattribute ignoriert werden, da
2498 // sie sonst auf den folgenden Zeilen landen. Der Rahmen wird nur
2499 // eingefuegt, wenn er *nicht* nur zum Positionieren einer einzelnen
2500 // Grafik dient. Ist es ein Grafik-Rahmen, dann werden pWFlyPara und
2501 // pSFlyPara behalten und die
2502 // daraus resultierenden Attribute beim Einfuegen der Grafik auf die
2503 // Grafik angewendet.
2505 WW8FlySet aFlySet(*this, pWFlyPara, pSFlyPara, false);
2507 pSFlyPara->pFlyFmt = rDoc.MakeFlySection( pSFlyPara->eAnchor,
2508 pPaM->GetPoint(), &aFlySet );
2509 ASSERT(pSFlyPara->pFlyFmt->GetAnchor().GetAnchorId() ==
2510 pSFlyPara->eAnchor, "Not the anchor type requested!");
2512 if (pSFlyPara->pFlyFmt)
2514 if (!pDrawModel)
2515 GrafikCtor();
2517 SdrObject* pOurNewObject = CreateContactObject(pSFlyPara->pFlyFmt);
2518 pWWZOrder->InsertTextLayerObject(pOurNewObject);
2521 if (FLY_IN_CNTNT != pSFlyPara->eAnchor)
2522 pAnchorStck->AddAnchor(*pPaM->GetPoint(),pSFlyPara->pFlyFmt);
2524 // merke Pos im Haupttext
2525 pSFlyPara->pMainTextPos = new SwPosition( *pPaM->GetPoint() );
2527 //remove fltanchors, otherwise they will be closed inside the
2528 //frame, which makes no sense, restore them after the frame is
2529 //closed
2530 pSFlyPara->pOldAnchorStck = pAnchorStck;
2531 pAnchorStck = new SwWW8FltAnchorStack(&rDoc, nFieldFlags);
2533 MoveInsideFly(pSFlyPara->pFlyFmt);
2535 // 1) ReadText() wird nicht wie beim W4W-Reader rekursiv aufgerufen,
2536 // da die Laenge des Apo zu diesen Zeitpunkt noch nicht feststeht,
2537 // ReadText() diese Angabe aber braucht.
2538 // 2) Der CtrlStck wird nicht neu erzeugt.
2539 // die Char-Attribute laufen weiter ( AErger mit SW-Attributen )
2540 // Paraattribute muessten am Ende jeden Absatzes zurueckgesetzt
2541 // sein, d.h. es duerften am Absatzende keine Paraattribute
2542 // auf dem Stack liegen
2544 return true;
2547 void wwSectionManager::JoinNode(const SwPosition &rPos, const SwNode &rNode)
2549 if ((!maSegments.empty()) && (maSegments.back().maStart == rPos.nNode))
2550 maSegments.back().maStart = SwNodeIndex(rNode);
2553 bool SwWW8ImplReader::JoinNode(SwPaM &rPam, bool bStealAttr)
2555 bool bRet = false;
2556 rPam.GetPoint()->nContent = 0; // an den Anfang der Zeile gehen
2558 SwNodeIndex aPref(rPam.GetPoint()->nNode, -1);
2560 if (SwTxtNode* pNode = aPref.GetNode().GetTxtNode())
2562 maSectionManager.JoinNode(*rPam.GetPoint(), aPref.GetNode());
2563 rPam.GetPoint()->nNode = aPref;
2564 rPam.GetPoint()->nContent.Assign(pNode, pNode->GetTxt().Len());
2565 if (bStealAttr)
2566 pCtrlStck->StealAttr(rPam.GetPoint());
2568 pNode->JoinNext();
2570 bRet = true;
2572 return bRet;
2575 void SwWW8ImplReader::StopApo()
2577 ASSERT(pWFlyPara, "no pWFlyPara to close");
2578 if (!pWFlyPara)
2579 return;
2580 if (pWFlyPara->bGrafApo)
2582 // Grafik-Rahmen, der *nicht* eingefuegt wurde leeren Absatz incl.
2583 // Attributen entfernen
2584 JoinNode(*pPaM, true);
2587 else
2589 if (!pSFlyPara->pMainTextPos || !pWFlyPara)
2591 ASSERT( pSFlyPara->pMainTextPos, "StopApo: pMainTextPos ist 0" );
2592 ASSERT( pWFlyPara, "StopApo: pWFlyPara ist 0" );
2593 return;
2597 #104920#
2598 What we are doing with this temporary nodeindex is as follows: The
2599 stack of attributes normally only places them into the document when
2600 the current insertion point has passed them by. Otherwise the end
2601 point of the attribute gets pushed along with the insertion point. The
2602 insertion point is moved and the properties commited during
2603 MoveOutsideFly. We also may want to remove the final paragraph in the
2604 frame, but we need to wait until the properties for that frame text
2605 have been commited otherwise they will be lost. So we first get a
2606 handle to the last the filter inserted. After the attributes are
2607 commited, if that paragraph exists we join it with the para after it
2608 that comes with the frame by default so that as normal we don't end up
2609 with one more paragraph than we wanted.
2611 SwNodeIndex aPref(pPaM->GetPoint()->nNode, -1);
2613 SwTwips nNewWidth =
2614 MoveOutsideFly(pSFlyPara->pFlyFmt, *pSFlyPara->pMainTextPos);
2615 if (nNewWidth)
2616 pSFlyPara->BoxUpWidth(nNewWidth);
2618 Color aBg(0xFE, 0xFF, 0xFF, 0xFF); //Transparent by default
2620 if (SwTxtNode* pNd = aPref.GetNode().GetTxtNode())
2623 #i582#/#114238#
2624 Take the last paragraph background colour and fill the frame with
2625 it. Otherwise, make it transparent, this appears to be how MSWord
2626 works
2628 const SfxPoolItem &rItm = pNd->SwCntntNode::GetAttr(RES_BACKGROUND);
2629 const SvxBrushItem &rBrush = (const SvxBrushItem&)(rItm);
2630 if (rBrush.GetColor().GetColor() != COL_AUTO)
2631 aBg = rBrush.GetColor();
2633 //Get rid of extra empty paragraph
2634 pNd->JoinNext();
2637 pSFlyPara->pFlyFmt->SetFmtAttr(SvxBrushItem(aBg, RES_BACKGROUND));
2639 DeleteAnchorStk();
2640 pAnchorStck = pSFlyPara->pOldAnchorStck;
2642 // Ist die Fly-Breite durch eine innenliegende Grafik vergroessert
2643 // worden ( bei automatischer Breite des Flys ), dann muss die Breite
2644 // des SW-Flys entsprechend umgesetzt werden, da der SW keine
2645 // automatische Breite kennt.
2646 if( pSFlyPara->nNewNettoWidth > MINFLY ) // BoxUpWidth ?
2648 long nW = pSFlyPara->nNewNettoWidth;
2649 nW += pSFlyPara->nWidth - pSFlyPara->nNettoWidth; // Rand dazu
2650 pSFlyPara->pFlyFmt->SetFmtAttr(
2651 SwFmtFrmSize( pSFlyPara->eHeightFix, nW, pSFlyPara->nHeight ) );
2654 #83307# Word set *no* width meaning its an automatic width. The
2655 SwFlyPara reader will have already set a fallback width of the
2656 printable regions width, so we should reuse it. Despite the related
2657 problems with layout addressed with a hack in WW8FlyPara's constructor
2658 #i27204# Added AutoWidth setting. Left the old CalculateFlySize in place
2659 so that if the user unselects autowidth, the width doesn't max out
2661 else if( !pWFlyPara->nSp28 )
2663 using namespace sw::util;
2664 SfxItemSet aFlySet( pSFlyPara->pFlyFmt->GetAttrSet() );
2666 SwFmtFrmSize aSize(ItemGet<SwFmtFrmSize>(aFlySet, RES_FRM_SIZE));
2668 aFlySet.ClearItem(RES_FRM_SIZE);
2670 CalculateFlySize(aFlySet, pSFlyPara->pMainTextPos->nNode,
2671 pSFlyPara->nWidth);
2673 nNewWidth = ItemGet<SwFmtFrmSize>(aFlySet, RES_FRM_SIZE).GetWidth();
2675 aSize.SetWidth(nNewWidth);
2676 aSize.SetWidthSizeType(ATT_VAR_SIZE);
2678 pSFlyPara->pFlyFmt->SetFmtAttr(aSize);
2681 delete pSFlyPara->pMainTextPos, pSFlyPara->pMainTextPos = 0;
2683 // Damit die Frames bei Einfuegen in existierendes Doc erzeugt werden,
2684 // wird in fltshell.cxx beim Setzen des FltAnchor-Attributes
2685 // pFlyFrm->MakeFrms() gerufen
2689 //#i8062#
2690 if (pSFlyPara && pSFlyPara->pFlyFmt)
2691 pFmtOfJustInsertedApo = pSFlyPara->pFlyFmt;
2693 DELETEZ( pSFlyPara );
2694 DELETEZ( pWFlyPara );
2697 // TestSameApo() beantwortet die Frage, ob es dasselbe APO oder ein neues ist
2698 bool SwWW8ImplReader::TestSameApo(const ApoTestResults &rApo,
2699 const WW8_TablePos *pTabPos)
2701 if( !pWFlyPara )
2703 ASSERT( pWFlyPara, " Wo ist mein pWFlyPara ? " );
2704 return true;
2707 // Es muss ein kompletter Vergleich ( ausser Borders ) stattfinden, um
2708 // alle Kombinationen Style / Hart richtig einzuordnen. Deshalb wird ein
2709 // temporaerer WW8FlyPara angelegt ( abh. ob Style oder nicht ), darauf
2710 // die harten Attrs angewendet, und dann verglichen
2712 // Zum Vergleich
2713 WW8FlyPara aF(bVer67, rApo.mpStyleApo);
2714 // WWPara fuer akt. Para
2715 if (rApo.HasFrame())
2716 aF.Read(rApo.mpSprm29, pPlcxMan->GetPapPLCF());
2717 aF.ApplyTabPos(pTabPos);
2719 return aF == *pWFlyPara;
2722 /***************************************************************************
2723 # Attribut - Verwaltung
2724 #**************************************************************************/
2726 void SwWW8ImplReader::NewAttr( const SfxPoolItem& rAttr )
2728 if( !bNoAttrImport ) // zum Ignorieren von Styles beim Doc-Einfuegen
2730 if (pAktColl)
2732 ASSERT(rAttr.Which() != RES_FLTR_REDLINE, "redline in style!");
2733 pAktColl->SetFmtAttr(rAttr);
2735 else if (pAktItemSet)
2736 pAktItemSet->Put(rAttr);
2737 else if (rAttr.Which() == RES_FLTR_REDLINE)
2738 mpRedlineStack->open(*pPaM->GetPoint(), rAttr);
2739 else
2740 pCtrlStck->NewAttr(*pPaM->GetPoint(), rAttr);
2742 if (mpPostProcessAttrsInfo && mpPostProcessAttrsInfo->mbCopy)
2743 mpPostProcessAttrsInfo->mItemSet.Put(rAttr);
2747 // holt Attribut aus der FmtColl / Stack / Doc
2748 const SfxPoolItem* SwWW8ImplReader::GetFmtAttr( USHORT nWhich )
2750 const SfxPoolItem* pRet = 0;
2751 if (pAktColl)
2752 pRet = &(pAktColl->GetFmtAttr(nWhich));
2753 else if (pAktItemSet)
2755 pRet = pAktItemSet->GetItem(nWhich);
2756 if (!pRet)
2757 pRet = pStandardFmtColl ? &(pStandardFmtColl->GetFmtAttr(nWhich)) : 0;
2758 if (!pRet)
2759 pRet = &rDoc.GetAttrPool().GetDefaultItem(nWhich);
2761 else if (pPlcxMan && pPlcxMan->GetDoingDrawTextBox())
2763 pRet = pCtrlStck->GetStackAttr(*pPaM->GetPoint(), nWhich);
2764 if (!pRet)
2766 if (nAktColl < nColls && pCollA[nAktColl].pFmt &&
2767 pCollA[nAktColl].bColl)
2769 pRet = &(pCollA[nAktColl].pFmt->GetFmtAttr(nWhich));
2772 if (!pRet)
2773 pRet = pStandardFmtColl ? &(pStandardFmtColl->GetFmtAttr(nWhich)) : 0;
2774 if (!pRet)
2775 pRet = &rDoc.GetAttrPool().GetDefaultItem(nWhich);
2777 else
2778 pRet = pCtrlStck->GetFmtAttr(*pPaM->GetPoint(), nWhich);
2779 return pRet;
2782 /***************************************************************************
2783 # eigentliche Attribute
2785 # Die Methoden erhalten die Token-Id und die Laenge der noch folgenden
2786 # Parameter gemaess Tabelle in WWScan.cxx als Parameter
2787 #**************************************************************************/
2789 /***************************************************************************
2790 # Spezial WW - Attribute
2791 #**************************************************************************/
2793 void SwWW8ImplReader::Read_Special(USHORT, const BYTE* pData, short nLen)
2795 if( nLen < 0 )
2797 bSpec = false;
2798 return;
2800 bSpec = ( *pData != 0 );
2803 // Read_Obj wird fuer fObj und fuer fOle2 benutzt !
2804 void SwWW8ImplReader::Read_Obj(USHORT , const BYTE* pData, short nLen)
2806 if( nLen < 0 )
2807 bObj = false;
2808 else
2810 bObj = 0 != *pData;
2812 if( bObj && nPicLocFc && bEmbeddObj )
2813 nObjLocFc = nPicLocFc;
2817 void SwWW8ImplReader::Read_PicLoc(USHORT , const BYTE* pData, short nLen )
2819 if( nLen < 0 )
2821 nPicLocFc = 0;
2822 bSpec = false; // Stimmt das immer ?
2824 else
2826 nPicLocFc = SVBT32ToUInt32( pData );
2827 bSpec = true;
2829 if( bObj && nPicLocFc && bEmbeddObj )
2830 nObjLocFc = nPicLocFc;
2834 void SwWW8ImplReader::Read_POutLvl(USHORT, const BYTE* pData, short nLen )
2836 if (pAktColl && (0 < nLen))
2838 if (SwWW8StyInf* pSI = GetStyle(nAktColl))
2840 pSI->nOutlineLevel = static_cast< BYTE >(
2841 ( (1 <= pSI->GetWWStyleId()) && (9 >= pSI->GetWWStyleId()) )
2842 ? pSI->GetWWStyleId()-1
2843 : (pData ? *pData : 0) );
2848 void SwWW8ImplReader::Read_Symbol(USHORT, const BYTE* pData, short nLen )
2850 if( !bIgnoreText )
2852 if( nLen < 0 )
2854 //otherwise disable after we print the char
2855 if (pPlcxMan && pPlcxMan->GetDoingDrawTextBox())
2856 pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_CHRATR_FONT );
2857 bSymbol = false;
2859 else
2861 // Make new Font-Atribut
2862 // (will be closed in SwWW8ImplReader::ReadChars() )
2864 //Will not be added to the charencoding stack, for styles the real
2865 //font setting will be put in as the styles charset, and for plain
2866 //text encoding for symbols is moot. Drawing boxes will check bSymbol
2867 //themselves so they don't need to add it to the stack either.
2868 if (SetNewFontAttr(SVBT16ToShort( pData ), false, RES_CHRATR_FONT))
2870 if( bVer67 )
2872 cSymbol = ByteString::ConvertToUnicode(
2873 *(sal_Char*)(pData+2), RTL_TEXTENCODING_MS_1252 );
2875 else
2876 cSymbol = SVBT16ToShort( pData+2 );
2877 bSymbol = true;
2883 SwWW8StyInf *SwWW8ImplReader::GetStyle(USHORT nColl) const
2885 return nColl < nColls ? &pCollA[nColl] : 0;
2888 /***************************************************************************
2889 # Zeichen - Attribute
2890 #**************************************************************************/
2892 // Read_BoldUsw fuer Italic, Bold, Kapitaelchen, Versalien, durchgestrichen,
2893 // Contour und Shadow
2894 void SwWW8ImplReader::Read_BoldUsw( USHORT nId, const BYTE* pData, short nLen )
2896 const int nContigiousWestern = 8;
2897 const int nWestern = nContigiousWestern + 1;
2898 const int nEastern = 2;
2899 const int nIds = nWestern + nEastern;
2900 static const USHORT nEndIds[ nIds ] =
2902 RES_CHRATR_WEIGHT, RES_CHRATR_POSTURE,
2903 RES_CHRATR_CROSSEDOUT, RES_CHRATR_CONTOUR,
2904 RES_CHRATR_SHADOWED, RES_CHRATR_CASEMAP,
2905 RES_CHRATR_CASEMAP, RES_CHRATR_HIDDEN,
2907 RES_CHRATR_CROSSEDOUT,
2909 RES_CHRATR_CJK_WEIGHT, RES_CHRATR_CJK_POSTURE
2912 ww::WordVersion eVersion = pWwFib->GetFIBVersion();
2914 BYTE nI;
2915 // die Attribut-Nr fuer "doppelt durchgestrichen" tanzt aus der Reihe
2916 if (0x2A53 == nId)
2917 nI = nContigiousWestern; // The out of sequence western id
2918 else
2920 // The contigious western ids
2921 if (eVersion <= ww::eWW2)
2922 nI = static_cast< BYTE >(nId - 60);
2923 else if (eVersion < ww::eWW8)
2924 nI = static_cast< BYTE >(nId - 85);
2925 else
2926 nI = static_cast< BYTE >(nId - 0x0835);
2929 sal_uInt16 nMask = 1 << nI;
2931 if (nLen < 0)
2933 pCtrlStck->SetAttr( *pPaM->GetPoint(), nEndIds[ nI ] );
2934 // reset the CJK Weight and Posture, because they are the same as their
2935 // western equivalents in word
2936 if (nI < 2)
2937 pCtrlStck->SetAttr( *pPaM->GetPoint(), nEndIds[ nWestern + nI ] );
2938 pCtrlStck->SetToggleAttr(nI, false);
2939 return;
2941 // Wert: 0 = Aus, 1 = An, 128 = Wie Style, 129 entgegen Style
2942 bool bOn = *pData & 1;
2943 SwWW8StyInf* pSI = GetStyle(nAktColl);
2944 if (pPlcxMan && eVersion > ww::eWW2)
2946 const BYTE *pCharIstd =
2947 pPlcxMan->GetChpPLCF()->HasSprm(bVer67 ? 80 : 0x4A30);
2948 if (pCharIstd)
2949 pSI = GetStyle(SVBT16ToShort(pCharIstd));
2952 if( pAktColl ) // StyleDef -> Flags merken
2954 if (pSI)
2956 // The style based on has Bit 7 set ?
2957 if (
2958 pSI->nBase < nColls && (*pData & 0x80) &&
2959 (pCollA[pSI->nBase].n81Flags & nMask)
2962 bOn = !bOn; // umdrehen
2965 if (bOn)
2966 pSI->n81Flags |= nMask; // Flag setzen
2967 else
2968 pSI->n81Flags &= ~nMask; // Flag loeschen
2971 else
2974 // im Text -> Flags abfragen
2975 if( *pData & 0x80 ) // Bit 7 gesetzt ?
2977 if (pSI && pSI->n81Flags & nMask) // und in StyleDef an ?
2978 bOn = !bOn; // dann invertieren
2979 // am Stack vermerken, das dieses ein Toggle-Attribut ist
2980 pCtrlStck->SetToggleAttr(nI, true);
2984 SetToggleAttr( nI, bOn );
2987 void SwWW8ImplReader::Read_Bidi(USHORT, const BYTE*, short nLen)
2989 if (nLen > 0)
2990 bBidi = true;
2991 else
2992 bBidi = false;
2995 // Read_BoldUsw for BiDi Italic, Bold
2996 void SwWW8ImplReader::Read_BoldBiDiUsw(USHORT nId, const BYTE* pData,
2997 short nLen)
2999 static const USHORT nEndIds[2] =
3001 RES_CHRATR_CTL_WEIGHT, RES_CHRATR_CTL_POSTURE,
3004 BYTE nI;
3005 ww::WordVersion eVersion = pWwFib->GetFIBVersion();
3006 if (eVersion <= ww::eWW2)
3007 nI = static_cast< BYTE >(nId - 80);
3008 else if (eVersion < ww::eWW8)
3009 nI = static_cast< BYTE >(nId - 111);
3010 else
3011 nI = static_cast< BYTE >(nId - 0x085C);
3013 ASSERT(nI <= 1, "not happening");
3014 if (nI > 1)
3015 return;
3017 sal_uInt16 nMask = 1 << nI;
3019 if( nLen < 0 )
3021 pCtrlStck->SetAttr(*pPaM->GetPoint(),nEndIds[nI]);
3022 pCtrlStck->SetToggleBiDiAttr(nI, false);
3023 return;
3025 bool bOn = *pData & 1;
3026 SwWW8StyInf* pSI = GetStyle(nAktColl);
3027 if (pPlcxMan)
3029 const BYTE *pCharIstd =
3030 pPlcxMan->GetChpPLCF()->HasSprm(bVer67 ? 80 : 0x4A30);
3031 if (pCharIstd)
3032 pSI = GetStyle(SVBT16ToShort(pCharIstd));
3035 if (pAktColl && eVersion > ww::eWW2) // StyleDef -> Flags merken
3037 if (pSI)
3039 if( pSI->nBase < nColls // Style Based on
3040 && ( *pData & 0x80 ) // Bit 7 gesetzt ?
3041 && ( pCollA[pSI->nBase].n81BiDiFlags & nMask ) ) // BasisMaske ?
3042 bOn = !bOn; // umdrehen
3044 if( bOn )
3045 pSI->n81BiDiFlags |= nMask; // Flag setzen
3046 else
3047 pSI->n81BiDiFlags &= ~nMask; // Flag loeschen
3050 else
3053 // im Text -> Flags abfragen
3054 if (*pData & 0x80) // Bit 7 gesetzt ?
3056 if (pSI && pSI->n81BiDiFlags & nMask) // und in StyleDef an ?
3057 bOn = !bOn; // dann invertieren
3058 // am Stack vermerken, das dieses ein Toggle-Attribut ist
3059 pCtrlStck->SetToggleBiDiAttr(nI, true);
3063 SetToggleBiDiAttr(nI, bOn);
3066 void SwWW8ImplReader::SetToggleBiDiAttr(BYTE nAttrId, bool bOn)
3068 switch (nAttrId)
3070 case 0:
3072 SvxWeightItem aAttr( bOn ? WEIGHT_BOLD : WEIGHT_NORMAL, RES_CHRATR_WEIGHT );
3073 aAttr.SetWhich( RES_CHRATR_CTL_WEIGHT );
3074 NewAttr( aAttr );
3076 break;
3077 case 1:
3079 SvxPostureItem aAttr( bOn ? ITALIC_NORMAL : ITALIC_NONE, RES_CHRATR_POSTURE );
3080 aAttr.SetWhich( RES_CHRATR_CTL_POSTURE );
3081 NewAttr( aAttr );
3083 break;
3084 default:
3085 ASSERT(!this, "Unhandled unknown bidi toggle attribute");
3086 break;
3091 void SwWW8ImplReader::SetToggleAttr(BYTE nAttrId, bool bOn)
3093 switch (nAttrId)
3095 case 0:
3097 SvxWeightItem aAttr( bOn ? WEIGHT_BOLD : WEIGHT_NORMAL, RES_CHRATR_WEIGHT );
3098 NewAttr( aAttr );
3099 aAttr.SetWhich( RES_CHRATR_CJK_WEIGHT );
3100 NewAttr( aAttr );
3102 break;
3103 case 1:
3105 SvxPostureItem aAttr( bOn ? ITALIC_NORMAL : ITALIC_NONE, RES_CHRATR_POSTURE );
3106 NewAttr( aAttr );
3107 aAttr.SetWhich( RES_CHRATR_CJK_POSTURE );
3108 NewAttr( aAttr );
3110 break;
3111 case 2:
3112 NewAttr(SvxCrossedOutItem(bOn ? STRIKEOUT_SINGLE : STRIKEOUT_NONE, RES_CHRATR_CROSSEDOUT));
3113 break;
3114 case 3:
3115 NewAttr( SvxContourItem( bOn, RES_CHRATR_CONTOUR ) );
3116 break;
3117 case 4:
3118 NewAttr( SvxShadowedItem( bOn, RES_CHRATR_SHADOWED ) );
3119 break;
3120 case 5:
3121 NewAttr( SvxCaseMapItem( bOn ? SVX_CASEMAP_KAPITAELCHEN
3122 : SVX_CASEMAP_NOT_MAPPED, RES_CHRATR_CASEMAP ) );
3123 break;
3124 case 6:
3125 NewAttr( SvxCaseMapItem( bOn ? SVX_CASEMAP_VERSALIEN
3126 : SVX_CASEMAP_NOT_MAPPED, RES_CHRATR_CASEMAP ) );
3127 break;
3128 case 7:
3129 NewAttr(SvxCharHiddenItem(bOn, RES_CHRATR_HIDDEN));
3130 break;
3131 case 8:
3132 NewAttr( SvxCrossedOutItem( bOn ? STRIKEOUT_DOUBLE
3133 : STRIKEOUT_NONE, RES_CHRATR_CROSSEDOUT ) );
3134 break;
3135 default:
3136 ASSERT(!this, "Unhandled unknown toggle attribute");
3137 break;
3141 void SwWW8ImplReader::_ChkToggleAttr( USHORT nOldStyle81Mask,
3142 USHORT nNewStyle81Mask )
3144 USHORT i = 1, nToggleAttrFlags = pCtrlStck->GetToggleAttrFlags();
3145 for (BYTE n = 0; n < 7; ++n, i <<= 1)
3147 if (
3148 (i & nToggleAttrFlags) &&
3149 ((i & nOldStyle81Mask) != (i & nNewStyle81Mask))
3152 SetToggleAttr(n, (i & nOldStyle81Mask));
3157 void SwWW8ImplReader::_ChkToggleBiDiAttr( USHORT nOldStyle81Mask,
3158 USHORT nNewStyle81Mask )
3160 USHORT i = 1, nToggleAttrFlags = pCtrlStck->GetToggleBiDiAttrFlags();
3161 for (BYTE n = 0; n < 7; ++n, i <<= 1)
3163 if (
3164 (i & nToggleAttrFlags) &&
3165 ((i & nOldStyle81Mask) != (i & nNewStyle81Mask))
3168 SetToggleBiDiAttr(n, (i & nOldStyle81Mask));
3173 void SwWW8ImplReader::Read_SubSuper( USHORT, const BYTE* pData, short nLen )
3175 if( nLen < 0 ){
3176 pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_CHRATR_ESCAPEMENT );
3177 return;
3180 short nEs;
3181 BYTE nProp;
3182 switch( *pData )
3184 case 1:
3185 nEs = DFLT_ESC_AUTO_SUPER;
3186 nProp = DFLT_ESC_PROP;
3187 break;
3188 case 2:
3189 nEs = DFLT_ESC_AUTO_SUB;
3190 nProp = DFLT_ESC_PROP;
3191 break;
3192 default:
3193 nEs = 0;
3194 nProp = 100;
3195 break;
3197 NewAttr( SvxEscapementItem( nEs, nProp, RES_CHRATR_ESCAPEMENT ) );
3200 SwFrmFmt *SwWW8ImplReader::ContainsSingleInlineGraphic(const SwPaM &rRegion)
3203 #92489# & #92946#
3204 For inline graphics and objects word has a hacked in feature to use
3205 subscripting to force the graphic into a centered position on the line, so
3206 we must check when applying sub/super to see if it the subscript range
3207 contains only a single graphic, and if that graphic is anchored as
3208 FLY_IN_CNTNT and then we can change its anchoring to centered in the line.
3210 SwFrmFmt *pRet=0;
3211 SwNodeIndex aBegin(rRegion.Start()->nNode);
3212 xub_StrLen nBegin(rRegion.Start()->nContent.GetIndex());
3213 SwNodeIndex aEnd(rRegion.End()->nNode);
3214 xub_StrLen nEnd(rRegion.End()->nContent.GetIndex());
3215 const SwTxtNode* pTNd;
3216 const SwTxtAttr* pTFlyAttr;
3217 if (
3218 aBegin == aEnd && nBegin == nEnd - 1 &&
3219 0 != (pTNd = aBegin.GetNode().GetTxtNode()) &&
3220 0 != (pTFlyAttr = pTNd->GetTxtAttr(nBegin, RES_TXTATR_FLYCNT))
3223 const SwFmtFlyCnt& rFly = pTFlyAttr->GetFlyCnt();
3224 SwFrmFmt *pFlyFmt = rFly.GetFrmFmt();
3225 if( pFlyFmt &&
3226 FLY_IN_CNTNT == pFlyFmt->GetAnchor().GetAnchorId() )
3228 pRet = pFlyFmt;
3231 return pRet;
3234 bool SwWW8ImplReader::ConvertSubToGraphicPlacement()
3237 #92489# & #92946#
3238 For inline graphics and objects word has a hacked in feature to use
3239 subscripting to force the graphic into a centered position on the line, so
3240 we must check when applying sub/super to see if it the subscript range
3241 contains only a single graphic, and if that graphic is anchored as
3242 FLY_IN_CNTNT and then we can change its anchoring to centered in the line.
3244 bool bIsGraphicPlacementHack = false;
3245 USHORT nPos;
3246 if (pCtrlStck->GetFmtStackAttr(RES_CHRATR_ESCAPEMENT, &nPos))
3248 SwPaM aRegion(*pPaM->GetPoint());
3250 SwFltStackEntry aEntry = *((*pCtrlStck)[nPos]);
3251 aEntry.SetEndPos(*pPaM->GetPoint());
3253 SwFrmFmt *pFlyFmt = 0;
3254 if (
3255 aEntry.MakeRegion(&rDoc,aRegion,false) &&
3256 0 != (pFlyFmt = ContainsSingleInlineGraphic(aRegion))
3259 pCtrlStck->DeleteAndDestroy(nPos);
3260 pFlyFmt->SetFmtAttr(SwFmtVertOrient(0, text::VertOrientation::CHAR_CENTER, text::RelOrientation::CHAR));
3261 bIsGraphicPlacementHack = true;
3264 return bIsGraphicPlacementHack;
3267 void SwWW8ImplReader::Read_SubSuperProp( USHORT, const BYTE* pData, short nLen )
3269 if( nLen < 0 )
3271 if (!ConvertSubToGraphicPlacement())
3272 pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_CHRATR_ESCAPEMENT );
3273 return;
3276 ww::WordVersion eVersion = pWwFib->GetFIBVersion();
3278 // Font-Position in HalfPoints
3279 short nPos = eVersion <= ww::eWW2 ? *pData : SVBT16ToShort( pData );
3280 INT32 nPos2 = nPos * ( 10 * 100 ); // HalfPoints in 100 * tw
3281 const SvxFontHeightItem* pF
3282 = (const SvxFontHeightItem*)GetFmtAttr(RES_CHRATR_FONTSIZE);
3283 ASSERT(pF, "Expected to have the fontheight available here");
3285 // #i59022: Check ensure nHeight != 0. Div by zero otherwise.
3286 INT32 nHeight = 240;
3287 if (pF != NULL && pF->GetHeight() != 0)
3288 nHeight = pF->GetHeight();
3289 nPos2 /= nHeight; // ... nun in % ( gerundet )
3290 if( nPos2 > 100 ) // zur Sicherheit
3291 nPos2 = 100;
3292 if( nPos2 < -100 )
3293 nPos2 = -100;
3294 SvxEscapementItem aEs( (short)nPos2, 100, RES_CHRATR_ESCAPEMENT );
3295 NewAttr( aEs );
3298 void SwWW8ImplReader::Read_Underline( USHORT, const BYTE* pData, short nLen )
3300 FontUnderline eUnderline = UNDERLINE_NONE;
3301 bool bWordLine = false;
3302 if( pData )
3304 // Parameter: 0 = none, 1 = single, 2 = by Word,
3305 // 3 = double, 4 = dotted, 5 = hidden
3306 // 6 = thick, 7 = dash, 8 = dot(not used)
3307 // 9 = dotdash 10 = dotdotdash 11 = wave
3310 // pruefe auf Sonderfall "fett+unterstrichen"
3311 bool bAlsoBold = /*( 6 == b )*/ false;
3312 // erst mal ggfs. *bold* einschalten!
3313 if( bAlsoBold )
3315 BYTE nOn = 1;
3316 Read_BoldUsw( 0x0835, &nOn, nLen );
3317 eUnderline = UNDERLINE_SINGLE;
3319 else
3321 switch( *pData )
3323 case 2: bWordLine = true; // no break;
3324 case 1: eUnderline = (FontUnderline)UNDERLINE_SINGLE; break;
3325 case 3: eUnderline = (FontUnderline)UNDERLINE_DOUBLE; break;
3326 case 4: eUnderline = (FontUnderline)UNDERLINE_DOTTED; break;
3327 case 7: eUnderline = (FontUnderline)UNDERLINE_DASH; break;
3328 case 9: eUnderline = (FontUnderline)UNDERLINE_DASHDOT; break;
3329 case 10:eUnderline = (FontUnderline)UNDERLINE_DASHDOTDOT; break;
3330 case 6: eUnderline = (FontUnderline)UNDERLINE_BOLD; break;
3331 case 11:eUnderline = (FontUnderline)UNDERLINE_WAVE; break;
3332 case 20:eUnderline = (FontUnderline)UNDERLINE_BOLDDOTTED; break;
3333 case 23:eUnderline = (FontUnderline)UNDERLINE_BOLDDASH; break;
3334 case 39:eUnderline = (FontUnderline)UNDERLINE_LONGDASH; break;
3335 case 55:eUnderline = (FontUnderline)UNDERLINE_BOLDLONGDASH; break;
3336 case 25:eUnderline = (FontUnderline)UNDERLINE_BOLDDASHDOT; break;
3337 case 26:eUnderline = (FontUnderline)UNDERLINE_BOLDDASHDOTDOT;break;
3338 case 27:eUnderline = (FontUnderline)UNDERLINE_BOLDWAVE; break;
3339 case 43:eUnderline = (FontUnderline)UNDERLINE_DOUBLEWAVE; break;
3344 // dann Stack ggfs. verwursteln und exit!
3345 if( nLen < 0 )
3347 pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_CHRATR_UNDERLINE );
3348 pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_CHRATR_WORDLINEMODE );
3350 else
3352 NewAttr( SvxUnderlineItem( eUnderline, RES_CHRATR_UNDERLINE ));
3353 if( bWordLine )
3354 NewAttr(SvxWordLineModeItem(true, RES_CHRATR_WORDLINEMODE));
3359 //The last three vary, measurements, rotation ? ?
3360 NoBracket 78 CA 06 - 02 00 00 02 34 52
3361 () 78 CA 06 - 02 01 00 02 34 52
3362 [] 78 CA 06 - 02 02 00 02 34 52
3363 <> 78 CA 06 - 02 03 00 02 34 52
3364 {} 78 CA 06 - 02 04 00 02 34 52
3366 void SwWW8ImplReader::Read_DoubleLine_Rotate( USHORT, const BYTE* pData,
3367 short nLen )
3369 if( nLen < 0 ) // close the tag
3371 pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_CHRATR_TWO_LINES );
3372 pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_CHRATR_ROTATE );
3374 else if( pData && 6 == nLen )
3376 switch( *pData )
3378 case 2: // double line
3380 sal_Unicode cStt = 0, cEnd = 0;
3381 switch( SVBT16ToShort( pData+1 ) )
3383 case 1: cStt = '(', cEnd = ')'; break;
3384 case 2: cStt = '[', cEnd = ']'; break;
3385 case 3: cStt = '<', cEnd = '>'; break;
3386 case 4: cStt = '{', cEnd = '}'; break;
3388 NewAttr( SvxTwoLinesItem( sal_True, cStt, cEnd, RES_CHRATR_TWO_LINES ));
3390 break;
3392 case 1: // rotated characters
3394 bool bFitToLine = 0 != *(pData+1);
3395 NewAttr( SvxCharRotateItem( 900, bFitToLine, RES_CHRATR_ROTATE ));
3397 break;
3402 void SwWW8ImplReader::Read_TxtColor( USHORT, const BYTE* pData, short nLen )
3404 //Has newer colour varient, ignore this old varient
3405 if (!bVer67 && pPlcxMan && pPlcxMan->GetChpPLCF()->HasSprm(0x6870))
3406 return;
3408 if( nLen < 0 )
3409 pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_CHRATR_COLOR );
3410 else
3412 BYTE b = *pData; // Parameter: 0 = Auto, 1..16 Farben
3414 if( b > 16 ) // unbekannt -> Black
3415 b = 0;
3417 NewAttr( SvxColorItem(Color(GetCol(b)), RES_CHRATR_COLOR));
3418 if (pAktColl && pStyles)
3419 pStyles->bTxtColChanged = true;
3423 sal_uInt32 wwUtility::BGRToRGB(sal_uInt32 nColor)
3425 sal_uInt8
3426 r(static_cast<sal_uInt8>(nColor&0xFF)),
3427 g(static_cast<sal_uInt8>(((nColor)>>8)&0xFF)),
3428 b(static_cast<sal_uInt8>((nColor>>16)&0xFF)),
3429 t(static_cast<sal_uInt8>((nColor>>24)&0xFF));
3430 nColor = (t<<24) + (r<<16) + (g<<8) + b;
3431 return nColor;
3434 void SwWW8ImplReader::Read_TxtForeColor(USHORT, const BYTE* pData, short nLen)
3436 if( nLen < 0 )
3437 pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_CHRATR_COLOR );
3438 else
3440 Color aColor(wwUtility::BGRToRGB(SVBT32ToUInt32(pData)));
3441 NewAttr(SvxColorItem(aColor, RES_CHRATR_COLOR));
3442 if (pAktColl && pStyles)
3443 pStyles->bTxtColChanged = true;
3447 bool SwWW8ImplReader::GetFontParams( USHORT nFCode, FontFamily& reFamily,
3448 String& rName, FontPitch& rePitch, CharSet& reCharSet )
3450 // Die Defines, aus denen diese Tabellen erzeugt werden, stehen in windows.h
3451 static const FontPitch ePitchA[] =
3453 PITCH_DONTKNOW, PITCH_FIXED, PITCH_VARIABLE, PITCH_DONTKNOW
3456 static const FontFamily eFamilyA[] =
3458 FAMILY_DONTKNOW, FAMILY_ROMAN, FAMILY_SWISS, FAMILY_MODERN,
3459 FAMILY_SCRIPT, FAMILY_DECORATIVE
3462 const WW8_FFN* pF = pFonts->GetFont( nFCode ); // Info dazu
3463 if( !pF ) // FontNummer unbekannt ?
3464 return false; // dann ignorieren
3466 rName = String( pF->sFontname );
3468 // pF->prg : Pitch
3469 rePitch = ePitchA[pF->prg];
3471 // pF->chs: Charset
3472 if( 77 == pF->chs ) // Mac-Font im Mac-Charset oder
3473 reCharSet = eTextCharSet; // auf ANSI-Charset uebersetzt
3474 else
3475 { // patch from cmc for #i52786#
3476 // #i52786#, for word 67 we'll assume that ANSI is basically invalid,
3477 // might be true for (above) mac as well, but would need a mac example
3478 // that exercises this to be sure
3479 if (bVer67 && pF->chs == 0)
3480 reCharSet = RTL_TEXTENCODING_DONTKNOW;
3481 else
3482 reCharSet = rtl_getTextEncodingFromWindowsCharset( pF->chs );
3485 // pF->ff : Family
3486 BYTE b = pF->ff;
3488 // make sure Font Family Code is set correctly
3489 // at least for the most important fonts
3490 // ( might be set wrong when Doc was not created by
3491 // Winword but by third party program like Applixware... )
3493 0: FAMILY_DONTKNOW
3494 1: FAMILY_ROMAN
3495 2: FAMILY_SWISS
3496 3: FAMILY_MODERN
3497 4: FAMILY_SCRIPT
3498 5: FAMILY_DECORATIVE
3500 #define FONTNAMETAB_SZ 14
3501 #define MAX_FONTNAME_ROMAN 6
3502 static const sal_Char
3503 // first comes ROMAN
3504 sFontName0[] = "\x07""Tms Rmn",
3505 sFontName1[] = "\x07""Timmons",
3506 sFontName2[] = "\x08""CG Times",
3507 sFontName3[] = "\x08""MS Serif",
3508 sFontName4[] = "\x08""Garamond",
3509 sFontName5[] = "\x11""Times Roman",
3510 sFontName6[] = "\x15""Times New Roman",
3511 // from here SWISS --> see above: #define MAX_FONTNAME_ROMAN 6
3512 sFontName7[] = "\x04""Helv",
3513 sFontName8[] = "\x05""Arial",
3514 sFontName9[] = "\x07""Univers",
3515 sFontName10[]= "\x11""LinePrinter",
3516 sFontName11[]= "\x11""Lucida Sans",
3517 sFontName12[]= "\x11""Small Fonts",
3518 sFontName13[]= "\x13""MS Sans Serif";
3519 static const sal_Char* const aFontNameTab[ FONTNAMETAB_SZ ] =
3521 sFontName0, sFontName1, sFontName2, sFontName3,
3522 sFontName4, sFontName5, sFontName6, sFontName7,
3523 sFontName8, sFontName9, sFontName10, sFontName11,
3524 sFontName12, sFontName13
3527 for( USHORT n = 0; n < FONTNAMETAB_SZ; n++ )
3529 const sal_Char* pCmp = aFontNameTab[ n ];
3530 xub_StrLen nLen = *pCmp++;
3531 if( rName.EqualsIgnoreCaseAscii(pCmp, 0, nLen) )
3533 b = n <= MAX_FONTNAME_ROMAN ? 1 : 2;
3534 break;
3537 if( b < sizeof( eFamilyA ) )
3538 reFamily = eFamilyA[b];
3539 else
3540 reFamily = FAMILY_DONTKNOW;
3542 return true;
3545 bool SwWW8ImplReader::SetNewFontAttr(USHORT nFCode, bool bSetEnums,
3546 USHORT nWhich)
3548 FontFamily eFamily;
3549 String aName;
3550 FontPitch ePitch;
3551 CharSet eSrcCharSet;
3553 if( !GetFontParams( nFCode, eFamily, aName, ePitch, eSrcCharSet ) )
3555 //If we fail (and are not doing a style) then put something into the
3556 //character encodings stack anyway so that the property end that pops
3557 //off the stack will keep in sync
3558 if (!pAktColl && IsListOrDropcap())
3560 if (!maFontSrcCharSets.empty())
3561 eSrcCharSet = maFontSrcCharSets.top();
3562 else
3563 eSrcCharSet = RTL_TEXTENCODING_DONTKNOW;
3564 maFontSrcCharSets.push(eSrcCharSet);
3566 return false;
3569 CharSet eDstCharSet = eSrcCharSet;
3571 SvxFontItem aFont( eFamily, aName, aEmptyStr, ePitch, eDstCharSet, nWhich);
3573 if( bSetEnums )
3575 if( pAktColl ) // StyleDef
3577 switch(nWhich)
3579 default:
3580 case RES_CHRATR_FONT:
3581 pCollA[nAktColl].eLTRFontSrcCharSet = eSrcCharSet;
3582 break;
3583 case RES_CHRATR_CTL_FONT:
3584 pCollA[nAktColl].eRTLFontSrcCharSet = eSrcCharSet;
3585 break;
3586 case RES_CHRATR_CJK_FONT:
3587 pCollA[nAktColl].eCJKFontSrcCharSet = eSrcCharSet;
3588 break;
3591 else if (IsListOrDropcap())
3593 //Add character text encoding to stack
3594 maFontSrcCharSets.push(eSrcCharSet);
3598 NewAttr( aFont ); // ...und 'reinsetzen
3600 return true;
3603 void SwWW8ImplReader::ResetCharSetVars()
3605 ASSERT(!maFontSrcCharSets.empty(),"no charset to remove");
3606 if (!maFontSrcCharSets.empty())
3607 maFontSrcCharSets.pop();
3611 Font ein oder ausschalten:
3613 void SwWW8ImplReader::Read_FontCode( USHORT nId, const BYTE* pData, short nLen )
3615 if (!bSymbol) // falls bSymbol, gilt der am Symbol
3616 { // (siehe sprmCSymbol) gesetzte Font !
3617 switch( nId )
3619 // case 0x4a51: //font to bias towards all else being equal ?
3620 case 113:
3621 case 0x4a5E:
3622 nId = RES_CHRATR_CTL_FONT;
3623 break;
3624 case 93:
3625 case 111:
3626 case 0x4a4f:
3627 nId = RES_CHRATR_FONT;
3628 break;
3629 case 112:
3630 case 0x4a50:
3631 nId = RES_CHRATR_CJK_FONT;
3632 break;
3633 default:
3634 return ;
3637 if( nLen < 0 ) // Ende des Attributes
3639 pCtrlStck->SetAttr( *pPaM->GetPoint(), nId );
3640 ResetCharSetVars();
3642 else
3644 USHORT nFCode = SVBT16ToShort( pData ); // Font-Nummer
3645 if (SetNewFontAttr(nFCode, true, nId) // Lies Inhalt
3646 && pAktColl && pStyles ) // Style-Def ?
3648 // merken zur Simulation Default-Font
3649 if (RES_CHRATR_CJK_FONT == nId)
3650 pStyles->bCJKFontChanged = true;
3651 else if (RES_CHRATR_CTL_FONT == nId)
3652 pStyles->bCTLFontChanged = true;
3653 else
3654 pStyles->bFontChanged = true;
3660 void SwWW8ImplReader::Read_FontSize( USHORT nId, const BYTE* pData, short nLen )
3662 switch( nId )
3664 case 74:
3665 case 99:
3666 case 0x4a43:
3667 nId = RES_CHRATR_FONTSIZE;
3668 break;
3669 case 85:
3670 case 116:
3671 case 0x4a61:
3672 nId = RES_CHRATR_CTL_FONTSIZE;
3673 break;
3674 default:
3675 return ;
3678 if( nLen < 0 ) // Ende des Attributes
3680 pCtrlStck->SetAttr( *pPaM->GetPoint(), nId );
3681 if( RES_CHRATR_FONTSIZE == nId ) // reset additional the CJK size
3682 pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_CHRATR_CJK_FONTSIZE );
3684 else
3686 ww::WordVersion eVersion = pWwFib->GetFIBVersion();
3688 // Font-Size in half points e.g. 10 = 1440 / ( 72 * 2 )
3689 USHORT nFSize = eVersion <= ww::eWW2 ? *pData : SVBT16ToShort(pData);
3690 nFSize*= 10;
3692 SvxFontHeightItem aSz( nFSize, 100, nId );
3693 NewAttr( aSz );
3694 if( RES_CHRATR_FONTSIZE == nId ) // set additional the CJK size
3696 aSz.SetWhich( RES_CHRATR_CJK_FONTSIZE );
3697 NewAttr( aSz );
3699 if (pAktColl && pStyles) // Style-Def ?
3701 // merken zur Simulation Default-FontSize
3702 if (nId == RES_CHRATR_CTL_FONTSIZE)
3703 pStyles->bFCTLSizeChanged = true;
3704 else
3705 pStyles->bFSizeChanged = true;
3712 void SwWW8ImplReader::Read_CharSet(USHORT , const BYTE* pData, short nLen)
3714 if( nLen < 0 )
3715 { // Ende des Attributes
3716 eHardCharSet = RTL_TEXTENCODING_DONTKNOW;
3717 return;
3719 BYTE nfChsDiff = SVBT8ToByte( pData );
3721 if( nfChsDiff )
3722 eHardCharSet = rtl_getTextEncodingFromWindowsCharset( *(pData + 1) );
3723 else
3724 eHardCharSet = RTL_TEXTENCODING_DONTKNOW;
3727 void SwWW8ImplReader::Read_Language( USHORT nId, const BYTE* pData, short nLen )
3729 switch( nId )
3731 case 97:
3732 case 0x486D:
3733 case 0x4873: //Methinks, uncertain
3734 nId = RES_CHRATR_LANGUAGE;
3735 break;
3736 case 0x486E:
3737 nId = RES_CHRATR_CJK_LANGUAGE;
3738 break;
3739 case 83:
3740 case 114:
3741 case 0x485F:
3742 nId = RES_CHRATR_CTL_LANGUAGE;
3743 break;
3744 default:
3745 return;
3748 if( nLen < 0 ) // Ende des Attributes
3749 pCtrlStck->SetAttr( *pPaM->GetPoint(), nId );
3750 else
3752 USHORT nLang = SVBT16ToShort( pData ); // Language-Id
3753 NewAttr(SvxLanguageItem((const LanguageType)nLang, nId));
3758 Einschalten des Zeichen-Styles:
3760 void SwWW8ImplReader::Read_CColl( USHORT, const BYTE* pData, short nLen )
3762 if( nLen < 0 ){ // Ende des Attributes
3763 pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_TXTATR_CHARFMT );
3764 nCharFmt = -1;
3765 return;
3767 USHORT nId = SVBT16ToShort( pData ); // Style-Id (NICHT Sprm-Id!)
3769 if( nId >= nColls || !pCollA[nId].pFmt // ungueltige Id ?
3770 || pCollA[nId].bColl ) // oder Para-Style ?
3771 return; // dann ignorieren
3773 NewAttr( SwFmtCharFmt( (SwCharFmt*)pCollA[nId].pFmt ) );
3774 nCharFmt = (short) nId;
3779 enger oder weiter als normal:
3781 void SwWW8ImplReader::Read_Kern( USHORT, const BYTE* pData, short nLen )
3783 if( nLen < 0 ){ // Ende des Attributes
3784 pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_CHRATR_KERNING );
3785 return;
3787 INT16 nKern = SVBT16ToShort( pData ); // Kerning in Twips
3788 NewAttr( SvxKerningItem( nKern, RES_CHRATR_KERNING ) );
3791 void SwWW8ImplReader::Read_FontKern( USHORT, const BYTE* , short nLen )
3793 if( nLen < 0 ) // Ende des Attributes
3794 pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_CHRATR_AUTOKERN );
3795 else
3796 NewAttr(SvxAutoKernItem(true, RES_CHRATR_AUTOKERN));
3799 void SwWW8ImplReader::Read_CharShadow( USHORT, const BYTE* pData, short nLen )
3801 //Has newer colour varient, ignore this old varient
3802 if (!bVer67 && pPlcxMan && pPlcxMan->GetChpPLCF()->HasSprm(0xCA71))
3803 return;
3805 if( nLen <= 0 )
3807 pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_CHRATR_BACKGROUND );
3808 if( bCharShdTxtCol )
3810 // Zeichenfarbe auch
3811 pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_CHRATR_COLOR );
3812 bCharShdTxtCol = false;
3815 else
3817 WW8_SHD aSHD;
3818 aSHD.SetWWValue( *(SVBT16*)pData );
3819 SwWW8Shade aSh( bVer67, aSHD );
3821 NewAttr( SvxBrushItem( aSh.aColor, RES_CHRATR_BACKGROUND ));
3825 void SwWW8ImplReader::Read_TxtBackColor(USHORT, const BYTE* pData, short nLen )
3827 if( nLen <= 0 )
3829 pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_CHRATR_BACKGROUND );
3830 if( bCharShdTxtCol )
3832 // Zeichenfarbe auch
3833 pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_CHRATR_COLOR );
3834 bCharShdTxtCol = false;
3837 else
3839 ASSERT(nLen == 10, "Len of para back colour not 10!");
3840 if (nLen != 10)
3841 return;
3842 Color aColour(ExtractColour(pData, bVer67));
3843 NewAttr(SvxBrushItem(aColour, RES_CHRATR_BACKGROUND));
3847 void SwWW8ImplReader::Read_CharHighlight(USHORT, const BYTE* pData, short nLen)
3849 if( nLen <= 0 )
3851 pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_CHRATR_BACKGROUND );
3852 if( bCharShdTxtCol )
3854 pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_CHRATR_COLOR ); // Zeichenfarbe auch
3855 bCharShdTxtCol = false;
3858 else
3860 BYTE b = *pData; // Parameter: 0 = Auto, 1..16 Farben
3862 if( b > 16 ) // unbekannt -> Black
3863 b = 0; // Auto -> Black
3865 Color aCol(GetCol(b));
3866 NewAttr( SvxBrushItem( aCol , RES_CHRATR_BACKGROUND ));
3871 /***************************************************************************
3872 # Absatz - Attribute
3873 #**************************************************************************/
3875 void SwWW8ImplReader::Read_NoLineNumb(USHORT , const BYTE* pData, short nLen)
3877 if( nLen < 0 ) // Ende des Attributes
3879 pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_LINENUMBER );
3880 return;
3882 SwFmtLineNumber aLN;
3883 if (const SwFmtLineNumber* pLN
3884 = (const SwFmtLineNumber*)GetFmtAttr(RES_LINENUMBER))
3886 aLN.SetStartValue( pLN->GetStartValue() );
3889 aLN.SetCountLines( pData && (0 == *pData) );
3890 NewAttr( aLN );
3893 // Sprm 16, 17
3894 void SwWW8ImplReader::Read_LR( USHORT nId, const BYTE* pData, short nLen )
3896 if (nLen < 0) // End of the Attributes
3898 pCtrlStck->SetAttr(*pPaM->GetPoint(), RES_LR_SPACE);
3899 return;
3902 short nPara = SVBT16ToShort( pData );
3904 SvxLRSpaceItem aLR( RES_LR_SPACE );
3905 const SfxPoolItem* pLR = GetFmtAttr(RES_LR_SPACE);
3906 if( pLR )
3907 aLR = *(const SvxLRSpaceItem*)pLR;
3910 The older word sprms mean left/right, while the new ones mean before/after.
3911 Writer now also works with before after, so when we see old left/right and
3912 we're RTL. We swap them
3914 if (IsRightToLeft())
3916 switch (nId)
3918 //Left becomes after;
3919 case 17:
3920 nId = 16;
3921 break;
3922 case 0x840F:
3923 nId = 0x840E;
3924 break;
3925 //Right becomes before;
3926 case 16:
3927 nId = 17;
3928 break;
3929 case 0x840E:
3930 nId = 0x840F;
3931 break;
3935 switch (nId)
3937 //sprmPDxaLeft
3938 case 17:
3939 case 0x840F:
3940 case 0x845E:
3941 aLR.SetTxtLeft( nPara );
3942 if (pAktColl)
3943 pCollA[nAktColl].bListReleventIndentSet = true;
3944 break;
3945 //sprmPDxaLeft1
3946 case 19:
3947 case 0x8411:
3948 case 0x8460:
3950 #94672# #99584#
3951 As part of an attempt to break my spirit ww 8+ formats can contain
3952 ww 7- lists. If they do and the list is part of the style, then
3953 when removing the list from a paragraph of that style there
3954 appears to be a bug where the hanging indent value which the list
3955 set is still factored into the left indent of the paragraph. Its
3956 not listed in the winword dialogs, but it is clearly there. So if
3957 our style has a broken ww 7- list and we know that the list has
3958 been removed then we will factor the original list applied hanging
3959 into our calculation.
3961 if (pPlcxMan && pCollA[nAktColl].bHasBrokenWW6List)
3963 const BYTE *pIsZeroed = pPlcxMan->GetPapPLCF()->HasSprm(0x460B);
3964 if (pIsZeroed && *pIsZeroed == 0)
3966 const SvxLRSpaceItem &rLR =
3967 ItemGet<SvxLRSpaceItem>(*(pCollA[nAktColl].pFmt),
3968 RES_LR_SPACE);
3969 nPara = nPara - rLR.GetTxtFirstLineOfst();
3973 aLR.SetTxtFirstLineOfst(nPara);
3974 if (pAktColl)
3975 pCollA[nAktColl].bListReleventIndentSet = true;
3976 break;
3977 //sprmPDxaRight
3978 case 16:
3979 case 0x840E:
3980 case 0x845D:
3981 aLR.SetRight( nPara );
3982 break;
3983 default:
3984 return;
3987 NewAttr(aLR);
3990 // Sprm 20
3991 void SwWW8ImplReader::Read_LineSpace( USHORT, const BYTE* pData, short nLen )
3993 // Kommentear siehe Read_UL()
3994 if (bStyNormal && bWWBugNormal)
3995 return;
3997 if( nLen < 0 ){
3998 pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_PARATR_LINESPACING );
3999 if( !( nIniFlags & WW8FL_NO_IMPLPASP ) )
4000 pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_UL_SPACE );
4001 return;
4004 short nSpace = SVBT16ToShort( pData );
4005 ww::WordVersion eVersion = pWwFib->GetFIBVersion();
4006 short nMulti = (eVersion <= ww::eWW2) ? 1 : SVBT16ToShort( pData + 2 );
4008 SvxLineSpace eLnSpc;
4009 if( 0 > nSpace )
4011 nSpace = -nSpace;
4012 eLnSpc = SVX_LINE_SPACE_FIX;
4014 else
4015 eLnSpc = SVX_LINE_SPACE_MIN;
4017 // WW hat einen impliziten zusaetzlichen Absatzabstand abhaengig vom
4018 // Zeilenabstand. Er betraegt bei "genau", 0.8*Zeilenabstand "vor" und
4019 // 0.2*Zeilenabstand "nach".
4020 // Bei "Mindestens" sind es 1*Zeilenabstand "vor" und 0*Zeilenabstand "nach".
4021 // Bei Mehrfach sind es 0 "vor" und min( 0cm, FontSize*(nFach-1) ) "nach".
4023 // SW hat auch einen impliziten Zeilenabstand. er betraegt bei "mindestens"
4024 // 1*Zeilenabstand "vor" und 0 "nach"
4025 // bei proportional betraegt er min( 0cm, FontSize*(nFach-1) ) sowohl "vor"
4026 // wie auch "nach"
4028 USHORT nWwPre = 0;
4029 USHORT nWwPost = 0;
4030 USHORT nSwPre = 0;
4031 USHORT nSwPost = 0;
4032 USHORT nSpaceTw = 0;
4034 SvxLineSpacingItem aLSpc( LINE_SPACE_DEFAULT_HEIGHT, RES_PARATR_LINESPACING );
4036 if( 1 == nMulti ) // MultilineSpace ( proportional )
4038 long n = nSpace * 10 / 24; // WW: 240 = 100%, SW: 100 = 100%
4040 //JP 03.12.98: nach Absprache mit AMA ist die Begrenzung unsinnig
4041 if( n>200 ) n = 200; // SW_UI-Maximum
4042 aLSpc.SetPropLineSpace( (const BYTE)n );
4043 const SvxFontHeightItem* pH = (const SvxFontHeightItem*)
4044 GetFmtAttr( RES_CHRATR_FONTSIZE );
4045 nSpaceTw = (USHORT)( n * pH->GetHeight() / 100 );
4047 if( n > 100 )
4048 nWwPost = nSwPre = nSwPost = (USHORT)( ( n - 100 )
4049 * pH->GetHeight() / 100 );
4051 else // Fixed / Minimum
4053 // bei negativen Space ist der Abstand exakt, sonst minimum
4054 nSpaceTw = (USHORT)nSpace;
4055 aLSpc.SetLineHeight( nSpaceTw );
4056 aLSpc.GetLineSpaceRule() = eLnSpc;
4057 nSwPre = nSpace;
4059 if( SVX_LINE_SPACE_FIX == eLnSpc ) // Genau
4061 nWwPre = (USHORT)( 8L * nSpace / 10 );
4062 nWwPost = (USHORT)( 2L * nSpace / 10 );
4063 nSwPre = nSpace;
4065 else // Minimum
4067 nWwPre = (USHORT)( 129L * nSpace / 100 - 95 );// erst bei groesseren
4068 // Zeilenabstaenden
4071 NewAttr( aLSpc );
4072 if( pSFlyPara )
4073 pSFlyPara->nLineSpace = nSpaceTw; // LineSpace fuer Graf-Apos
4076 //#i18519# AutoSpace value depends on Dop fDontUseHTMLAutoSpacing setting
4077 sal_uInt16 SwWW8ImplReader::GetParagraphAutoSpace(bool fDontUseHTMLAutoSpacing)
4079 if (fDontUseHTMLAutoSpacing)
4080 return 100; //Seems to be always 5points in this case
4081 else
4082 return 280; //Seems to be always 14points in this case
4085 void SwWW8ImplReader::Read_DontAddEqual(USHORT, const BYTE *pData, short nLen)
4087 if (nLen < 0)
4088 return;
4090 if (*pData)
4091 maTracer.Log(sw::log::eDontAddSpaceForEqualStyles);
4094 void SwWW8ImplReader::Read_ParaAutoBefore(USHORT, const BYTE *pData, short nLen)
4096 if (nLen < 0)
4098 pCtrlStck->SetAttr(*pPaM->GetPoint(), RES_UL_SPACE);
4099 return;
4102 if (*pData)
4104 SvxULSpaceItem aUL(*(const SvxULSpaceItem*)GetFmtAttr(RES_UL_SPACE));
4105 aUL.SetUpper(GetParagraphAutoSpace(pWDop->fDontUseHTMLAutoSpacing));
4106 NewAttr(aUL);
4107 if (pAktColl)
4108 pCollA[nAktColl].bParaAutoBefore = true;
4109 else
4110 bParaAutoBefore = true;
4112 else
4114 if (pAktColl)
4115 pCollA[nAktColl].bParaAutoBefore = false;
4116 else
4117 bParaAutoBefore = false;
4121 void SwWW8ImplReader::Read_ParaAutoAfter(USHORT, const BYTE *pData, short nLen)
4123 if (nLen < 0)
4125 pCtrlStck->SetAttr(*pPaM->GetPoint(), RES_UL_SPACE);
4126 return;
4129 if (*pData)
4131 SvxULSpaceItem aUL(*(const SvxULSpaceItem*)GetFmtAttr(RES_UL_SPACE));
4132 aUL.SetLower(GetParagraphAutoSpace(pWDop->fDontUseHTMLAutoSpacing));
4133 NewAttr(aUL);
4134 if (pAktColl)
4135 pCollA[nAktColl].bParaAutoAfter = true;
4136 else
4137 bParaAutoAfter = true;
4139 else
4141 if (pAktColl)
4142 pCollA[nAktColl].bParaAutoAfter = false;
4143 else
4144 bParaAutoAfter = false;
4148 // Sprm 21, 22
4149 void SwWW8ImplReader::Read_UL( USHORT nId, const BYTE* pData, short nLen )
4151 // Nun eine Umpopelung eines WW-Fehlers: Bei nProduct == 0c03d wird
4152 // faelschlicherweise ein DyaAfter 240 ( delta y abstand after, amn.d.?b.)
4153 // im Style "Normal" eingefuegt, der
4154 // gar nicht da ist. Ueber das IniFlag WW8FL_NO_STY_DYA laesst sich dieses
4155 // Verhalten auch fuer andere WW-Versionen erzwingen
4156 // ASSERT( !bStyNormal || bWWBugNormal, "+Dieses Doc deutet evtl. auf einen
4157 // Fehler in der benutzten WW-Version hin. Wenn sich die Styles <Standard> bzw.
4158 // <Normal> zwischen WW und SW im Absatz- oder Zeilenabstand unterscheiden,
4159 // dann bitte dieses Doc SH zukommen lassen." );
4160 // bWWBugNormal ist kein hinreichendes Kriterium dafuer, dass der
4161 // angegebene Abstand falsch ist
4163 if( nLen < 0 )
4165 // Ende des Attributes
4166 pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_UL_SPACE );
4167 return;
4169 short nPara = SVBT16ToShort( pData );
4170 if( nPara < 0 )
4171 nPara = -nPara;
4173 SvxULSpaceItem aUL( *(const SvxULSpaceItem*)GetFmtAttr( RES_UL_SPACE ));
4175 switch( nId )
4177 //sprmPDyaBefore
4178 case 21:
4179 case 0xA413:
4180 aUL.SetUpper( nPara );
4181 break;
4182 //sprmPDyaAfter
4183 case 22:
4184 case 0xA414:
4185 aUL.SetLower( nPara );
4186 break;
4187 default:
4188 return;
4191 NewAttr( aUL );
4194 void SwWW8ImplReader::Read_IdctHint( USHORT, const BYTE* pData, short nLen )
4196 if (nLen < 0)
4197 nIdctHint = 0;
4198 else
4199 nIdctHint = *pData;
4202 void SwWW8ImplReader::Read_Justify( USHORT, const BYTE* pData, short nLen )
4204 if( nLen < 0 )
4206 pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_PARATR_ADJUST );
4207 return;
4210 SvxAdjust eAdjust(SVX_ADJUST_LEFT);
4211 bool bDistributed = false;
4212 switch (*pData)
4214 default:
4215 case 0:
4216 break;
4217 case 1:
4218 eAdjust = SVX_ADJUST_CENTER;
4219 break;
4220 case 2:
4221 eAdjust = SVX_ADJUST_RIGHT;
4222 break;
4223 case 3:
4224 eAdjust = SVX_ADJUST_BLOCK;
4225 break;
4226 case 4:
4227 eAdjust = SVX_ADJUST_BLOCK;
4228 bDistributed = true;
4229 break;
4231 SvxAdjustItem aAdjust(eAdjust, RES_PARATR_ADJUST);
4232 if (bDistributed)
4233 aAdjust.SetLastBlock(SVX_ADJUST_BLOCK);
4235 NewAttr(aAdjust);
4238 bool SwWW8ImplReader::IsRightToLeft()
4240 bool bRTL = false;
4241 const BYTE *pDir =
4242 pPlcxMan ? pPlcxMan->GetPapPLCF()->HasSprm(0x2441) : 0;
4243 if (pDir)
4244 bRTL = *pDir ? true : false;
4245 else
4247 const SvxFrameDirectionItem* pItem=
4248 (const SvxFrameDirectionItem*)GetFmtAttr(RES_FRAMEDIR);
4249 if (pItem && (pItem->GetValue() == FRMDIR_HORI_RIGHT_TOP))
4250 bRTL = true;
4252 return bRTL;
4255 void SwWW8ImplReader::Read_RTLJustify( USHORT, const BYTE* pData, short nLen )
4257 if( nLen < 0 )
4259 pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_PARATR_ADJUST );
4260 return;
4263 //If we are in a ltr paragraph this is the same as normal Justify,
4264 //If we are in a rtl paragraph the meaning is reversed.
4265 if (!IsRightToLeft())
4266 Read_Justify(0x2403 /*dummy*/, pData, nLen);
4267 else
4269 SvxAdjust eAdjust(SVX_ADJUST_RIGHT);
4270 bool bDistributed = false;
4271 switch (*pData)
4273 default:
4274 case 0:
4275 break;
4276 case 1:
4277 eAdjust = SVX_ADJUST_CENTER;
4278 break;
4279 case 2:
4280 eAdjust = SVX_ADJUST_LEFT;
4281 break;
4282 case 3:
4283 eAdjust = SVX_ADJUST_BLOCK;
4284 break;
4285 case 4:
4286 eAdjust = SVX_ADJUST_BLOCK;
4287 bDistributed = true;
4288 break;
4290 SvxAdjustItem aAdjust(eAdjust, RES_PARATR_ADJUST);
4291 if (bDistributed)
4292 aAdjust.SetLastBlock(SVX_ADJUST_BLOCK);
4294 NewAttr(aAdjust);
4298 void SwWW8ImplReader::Read_BoolItem( USHORT nId, const BYTE* pData, short nLen )
4300 switch( nId )
4302 case 0x2433:
4303 nId = RES_PARATR_FORBIDDEN_RULES;
4304 break;
4305 case 0x2435:
4306 nId = RES_PARATR_HANGINGPUNCTUATION;
4307 break;
4308 case 0x2437:
4309 nId = RES_PARATR_SCRIPTSPACE;
4310 break;
4311 default:
4312 ASSERT( !this, "wrong Id" );
4313 return ;
4316 if( nLen < 0 )
4317 pCtrlStck->SetAttr( *pPaM->GetPoint(), nId );
4318 else
4320 SfxBoolItem* pI = (SfxBoolItem*)GetDfltAttr( nId )->Clone();
4321 pI->SetValue( 0 != *pData );
4322 NewAttr( *pI );
4323 delete pI;
4327 void SwWW8ImplReader::Read_Emphasis( USHORT, const BYTE* pData, short nLen )
4329 if( nLen < 0 )
4330 pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_CHRATR_EMPHASIS_MARK );
4331 else
4333 LanguageType nLang;
4334 //Check to see if there is an up and coming cjk language property. If
4335 //there is use it, if there is not fall back to the currently set one.
4336 //Only the cjk language setting seems to matter to word, the western
4337 //one is ignored
4338 const BYTE *pLang =
4339 pPlcxMan ? pPlcxMan->GetChpPLCF()->HasSprm(0x486E) : 0;
4341 if (pLang)
4342 nLang = SVBT16ToShort( pLang );
4343 else
4345 nLang = ((const SvxLanguageItem *)
4346 GetFmtAttr(RES_CHRATR_CJK_LANGUAGE))->GetLanguage();
4349 sal_uInt16 nVal;
4350 switch( *pData )
4352 case 0:
4353 nVal = EMPHASISMARK_NONE;
4354 break;
4355 case 2:
4356 if ((nLang == LANGUAGE_CHINESE_HONGKONG) ||
4357 (nLang == LANGUAGE_CHINESE_MACAU) ||
4358 (nLang == LANGUAGE_CHINESE_TRADITIONAL) ||
4359 (nLang == LANGUAGE_KOREAN))
4360 nVal = EMPHASISMARK_CIRCLE_ABOVE;
4361 else if (nLang == LANGUAGE_JAPANESE)
4362 nVal = EMPHASISMARK_SIDE_DOTS;
4363 else
4364 nVal = EMPHASISMARK_DOTS_BELOW;
4365 break;
4366 case 3:
4367 nVal = EMPHASISMARK_CIRCLE_ABOVE;
4368 break;
4369 case 4:
4370 nVal = EMPHASISMARK_DOTS_BELOW;
4371 break;
4372 case 1:
4373 if ((nLang == LANGUAGE_CHINESE_SIMPLIFIED) ||
4374 (nLang == LANGUAGE_CHINESE_SINGAPORE))
4375 nVal = EMPHASISMARK_DOTS_BELOW;
4376 else
4377 nVal = EMPHASISMARK_DOTS_ABOVE;
4378 break;
4379 default:
4380 nVal = EMPHASISMARK_DOTS_ABOVE;
4381 break;
4384 NewAttr( SvxEmphasisMarkItem( nVal, RES_CHRATR_EMPHASIS_MARK ) );
4388 void SwWW8ImplReader::Read_ScaleWidth( USHORT, const BYTE* pData, short nLen )
4390 if( nLen < 0 )
4391 pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_CHRATR_SCALEW );
4392 else
4394 sal_uInt16 nVal = SVBT16ToShort( pData );
4395 //The number must be between 1 and 600
4396 if (nVal < 1 || nVal > 600)
4397 nVal = 100;
4398 NewAttr( SvxCharScaleWidthItem( nVal, RES_CHRATR_SCALEW ) );
4402 void SwWW8ImplReader::Read_Relief( USHORT nId, const BYTE* pData, short nLen )
4404 if( nLen < 0 )
4405 pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_CHRATR_RELIEF );
4406 else
4408 if( *pData )
4410 // JP 16.03.2001 - not so eays because this is also a toggle attribute!
4411 // 2 x emboss on -> no emboss !!!
4412 // the actual value must be searched over the stack / template
4414 const SvxCharReliefItem* pOld = (const SvxCharReliefItem*)
4415 GetFmtAttr( RES_CHRATR_RELIEF );
4416 FontRelief nNewValue = 0x854 == nId ? RELIEF_ENGRAVED
4417 : ( 0x858 == nId ? RELIEF_EMBOSSED
4418 : RELIEF_NONE );
4419 if( pOld->GetValue() == nNewValue )
4421 if( RELIEF_NONE != nNewValue )
4422 nNewValue = RELIEF_NONE;
4424 NewAttr( SvxCharReliefItem( nNewValue, RES_CHRATR_RELIEF ));
4429 void SwWW8ImplReader::Read_TxtAnim(USHORT /*nId*/, const BYTE* pData, short nLen)
4431 if (nLen < 0)
4432 pCtrlStck->SetAttr(*pPaM->GetPoint(), RES_CHRATR_BLINK);
4433 else
4435 if (*pData)
4437 bool bBlink;
4439 // #110851# The 7 animated text effects available in word all get
4440 // mapped to a blinking text effect in StarOffice
4441 // 0 no animation 1 Las Vegas lights
4442 // 2 background blink 3 sparkle text
4443 // 4 marching ants 5 marchine red ants
4444 // 6 shimmer
4445 if (*pData > 0 && *pData < 7 )
4446 bBlink = true;
4447 else
4448 bBlink = false;
4450 NewAttr(SvxBlinkItem(bBlink, RES_CHRATR_BLINK));
4455 SwWW8Shade::SwWW8Shade(bool bVer67, const WW8_SHD& rSHD)
4457 BYTE b = rSHD.GetFore();
4458 ASSERT(b < 17, "ww8: colour out of range");
4459 if (b >= 17)
4460 b = 0;
4462 ColorData nFore(SwWW8ImplReader::GetCol(b));
4464 b = rSHD.GetBack();
4465 ASSERT(b < 17, "ww8: colour out of range");
4466 if( b >= 17 )
4467 b = 0;
4469 ColorData nBack(SwWW8ImplReader::GetCol(b));
4471 b = rSHD.GetStyle(bVer67);
4473 SetShade(nFore, nBack, b);
4476 void SwWW8Shade::SetShade(ColorData nFore, ColorData nBack, sal_uInt16 nIndex)
4478 static const ULONG eMSGrayScale[] =
4480 // Nul-Brush
4481 0, // 0
4482 // Solid-Brush
4483 1000, // 1
4484 // promillemaessig abgestufte Schattierungen
4485 50, // 2
4486 100, // 3
4487 200, // 4
4488 250, // 5
4489 300, // 6
4490 400, // 7
4491 500, // 8
4492 600, // 9
4493 700, // 10
4494 750, // 11
4495 800, // 12
4496 900, // 13
4497 333, // 14 Dark Horizontal
4498 333, // 15 Dark Vertical
4499 333, // 16 Dark Forward Diagonal
4500 333, // 17 Dark Backward Diagonal
4501 333, // 18 Dark Cross
4502 333, // 19 Dark Diagonal Cross
4503 333, // 20 Horizontal
4504 333, // 21 Vertical
4505 333, // 22 Forward Diagonal
4506 333, // 23 Backward Diagonal
4507 333, // 24 Cross
4508 333, // 25 Diagonal Cross
4509 // neun Nummern ohne Bedeutung in Ver8
4510 500, // 26
4511 500, // 27
4512 500, // 28
4513 500, // 29
4514 500, // 30
4515 500, // 31
4516 500, // 32
4517 500, // 33
4518 500, // 34
4519 // und weiter gehts mit tollen Schattierungen ;-)
4520 25, // 35
4521 75, // 36
4522 125, // 37
4523 150, // 38
4524 175, // 39
4525 225, // 40
4526 275, // 41
4527 325, // 42
4528 350, // 43
4529 375, // 44
4530 425, // 45
4531 450, // 46
4532 475, // 47
4533 525, // 48
4534 550, // 49
4535 575, // 50
4536 625, // 51
4537 650, // 52
4538 675, // 53
4539 725, // 54
4540 775, // 55
4541 825, // 56
4542 850, // 57
4543 875, // 58
4544 925, // 59
4545 950, // 60
4546 975, // 61
4547 // und zu guter Letzt:
4549 };// 62
4552 //NO auto for shading so Foreground: Auto = Black
4553 if (nFore == COL_AUTO)
4554 nFore = COL_BLACK;
4556 //NO auto for shading so background: Auto = Weiss
4557 ColorData nUseBack = nBack;
4558 if (nUseBack == COL_AUTO)
4559 nUseBack = COL_WHITE;
4562 if( nIndex >= sizeof( eMSGrayScale ) / sizeof ( eMSGrayScale[ 0 ] ) )
4563 nIndex = 0;
4565 ULONG nWW8BrushStyle = eMSGrayScale[nIndex];
4567 switch (nWW8BrushStyle)
4569 case 0: // Null-Brush
4570 aColor.SetColor( nBack );
4571 break;
4572 default:
4574 Color aForeColor(nFore);
4575 Color aBackColor(nUseBack);
4577 sal_uInt32 nRed = aForeColor.GetRed() * nWW8BrushStyle;
4578 sal_uInt32 nGreen = aForeColor.GetGreen() * nWW8BrushStyle;
4579 sal_uInt32 nBlue = aForeColor.GetBlue() * nWW8BrushStyle;
4580 nRed += aBackColor.GetRed() * (1000L - nWW8BrushStyle);
4581 nGreen += aBackColor.GetGreen()* (1000L - nWW8BrushStyle);
4582 nBlue += aBackColor.GetBlue() * (1000L - nWW8BrushStyle);
4584 aColor.SetColor( RGB_COLORDATA( nRed/1000, nGreen/1000,
4585 nBlue/1000 ) );
4587 break;
4591 void SwWW8ImplReader::Read_Shade( USHORT, const BYTE* pData, short nLen )
4593 if (!bVer67 && pPlcxMan && pPlcxMan->GetPapPLCF()->HasSprm(0xC64D))
4594 return;
4596 if (nLen <= 0)
4598 // Ende des Attributes
4599 pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_BACKGROUND );
4600 if (bShdTxtCol)
4602 // Zeichenfarbe auch
4603 pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_CHRATR_COLOR );
4604 bShdTxtCol = false;
4607 else
4609 WW8_SHD aSHD;
4610 aSHD.SetWWValue( *(SVBT16*)pData );
4611 SwWW8Shade aSh( bVer67, aSHD );
4613 NewAttr(SvxBrushItem(aSh.aColor, RES_BACKGROUND));
4617 void SwWW8ImplReader::Read_ParaBackColor(USHORT, const BYTE* pData, short nLen)
4619 if (nLen <= 0)
4621 // Ende des Attributes
4622 pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_BACKGROUND );
4623 if (bShdTxtCol)
4625 // Zeichenfarbe auch
4626 pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_CHRATR_COLOR );
4627 bShdTxtCol = false;
4630 else
4632 ASSERT(nLen == 10, "Len of para back colour not 10!");
4633 if (nLen != 10)
4634 return;
4635 NewAttr(SvxBrushItem(Color(ExtractColour(pData, bVer67)), RES_BACKGROUND));
4639 sal_uInt32 SwWW8ImplReader::ExtractColour(const BYTE* &rpData,
4640 bool
4641 #ifndef PRODUCT
4642 bVer67
4643 #endif
4646 ASSERT(bVer67 == false, "Impossible");
4647 //ASSERT(SVBT32ToUInt32(rpData) == 0xFF000000, "Unknown 1 not 0xff000000");
4648 sal_uInt32 nFore = wwUtility::BGRToRGB(SVBT32ToUInt32(rpData));
4649 rpData+=4;
4650 sal_uInt32 nBack = wwUtility::BGRToRGB(SVBT32ToUInt32(rpData));
4651 rpData+=4;
4652 sal_uInt16 nIndex = SVBT16ToShort(rpData);
4653 rpData+=2;
4654 //Being a transparent background colour doesn't actually show the page
4655 //background through, it merely acts like white
4656 if (nBack == 0xFF000000)
4657 nBack = COL_AUTO;
4658 ASSERT(nBack == COL_AUTO || !(nBack & 0xFF000000),
4659 "ww8: don't know what to do with such a transparent bg colour, report");
4660 SwWW8Shade aShade(nFore, nBack, nIndex);
4661 return aShade.aColor.GetColor();
4664 void SwWW8ImplReader::Read_Border(USHORT , const BYTE* , short nLen)
4666 if( nLen < 0 )
4668 if( bHasBorder )
4670 pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_BOX );
4671 pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_SHADOW );
4672 bHasBorder = false;
4675 else if( !bHasBorder )
4677 // die Borders auf allen 4 Seiten werden gebuendelt. dieses
4678 // vereinfacht die Verwaltung, d.h. die Box muss nicht 4 mal auf den
4679 // CtrlStack und wieder runter
4680 bHasBorder = true;
4682 WW8_BRC5 aBrcs; // Top, Left, Bottom, Right, Between
4683 BYTE nBorder;
4685 if( pAktColl )
4686 nBorder = ::lcl_ReadBorders(bVer67, aBrcs, 0, pStyles);
4687 else
4688 nBorder = ::lcl_ReadBorders(bVer67, aBrcs, pPlcxMan->GetPapPLCF());
4690 if( nBorder ) // Border
4692 bool bIsB = IsBorder(aBrcs, true);
4693 if (!InLocalApo() || !bIsB ||
4694 (pWFlyPara && !pWFlyPara->bBorderLines ))
4696 // in Apo keine Umrandungen *ein*-schalten, da ich
4697 // sonst die Flyumrandungen doppelt bekomme
4698 // JP 04.12.98: aber nur wenn am Fly ein gesetzt ist, keine
4699 // uebernehmen. Sonst wird gar keine gesetzt!
4700 // Bug #59619#
4702 // auch wenn kein Rand gesetzt ist, muss das Attribut gesetzt
4703 // werden, sonst ist kein hartes Ausschalten von Style-Attrs
4704 // moeglich
4705 const SvxBoxItem* pBox
4706 = (const SvxBoxItem*)GetFmtAttr( RES_BOX );
4707 SvxBoxItem aBox(RES_BOX);
4708 if (pBox)
4709 aBox = *pBox;
4710 short aSizeArray[5]={0};
4712 SetBorder(aBox, aBrcs, &aSizeArray[0], nBorder);
4714 Rectangle aInnerDist;
4715 GetBorderDistance( aBrcs, aInnerDist );
4717 maTracer.Log(sw::log::eBorderDistOutside);
4719 if ((nBorder & WW8_LEFT)==WW8_LEFT) {
4720 aBox.SetDistance( (USHORT)aInnerDist.Left(), BOX_LINE_LEFT );
4722 if ((nBorder & WW8_TOP)==WW8_TOP) {
4723 aBox.SetDistance( (USHORT)aInnerDist.Top(), BOX_LINE_TOP );
4725 if ((nBorder & WW8_RIGHT)==WW8_RIGHT) {
4726 aBox.SetDistance( (USHORT)aInnerDist.Right(), BOX_LINE_RIGHT );
4729 if ((nBorder & WW8_BOT)==WW8_BOT) {
4730 aBox.SetDistance( (USHORT)aInnerDist.Bottom(), BOX_LINE_BOTTOM );
4733 NewAttr( aBox );
4735 SvxShadowItem aS(RES_SHADOW);
4736 if( SetShadow( aS, &aSizeArray[0], aBrcs ) )
4737 NewAttr( aS );
4743 void SwWW8ImplReader::Read_Hyphenation( USHORT, const BYTE* pData, short nLen )
4745 // set Hyphenation flag
4746 if( nLen <= 0 )
4747 pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_PARATR_HYPHENZONE );
4748 else
4750 SvxHyphenZoneItem aAttr(
4751 *(const SvxHyphenZoneItem*)GetFmtAttr( RES_PARATR_HYPHENZONE ) );
4753 aAttr.SetHyphen( 0 == *pData ); // sic !
4755 if( !*pData )
4757 aAttr.GetMinLead() = 2;
4758 aAttr.GetMinTrail() = 2;
4759 aAttr.GetMaxHyphens() = 0;
4762 NewAttr( aAttr );
4766 void SwWW8ImplReader::Read_WidowControl( USHORT, const BYTE* pData, short nLen )
4768 if( nLen <= 0 )
4770 pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_PARATR_WIDOWS );
4771 pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_PARATR_ORPHANS );
4773 else
4775 BYTE nL = ( *pData & 1 ) ? 2 : 0;
4777 NewAttr( SvxWidowsItem( nL, RES_PARATR_WIDOWS ) ); // Aus -> nLines = 0
4778 NewAttr( SvxOrphansItem( nL, RES_PARATR_ORPHANS ) );
4780 if( pAktColl && pStyles ) // Style-Def ?
4781 pStyles->bWidowsChanged = true; // merken zur Simulation
4782 // Default-Widows
4786 void SwWW8ImplReader::Read_UsePgsuSettings(USHORT,const BYTE* pData,short nLen)
4788 if( nLen <= 0 )
4789 pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_PARATR_SNAPTOGRID);
4790 else
4792 if(nInTable)
4793 NewAttr( SvxParaGridItem(false, RES_PARATR_SNAPTOGRID) );
4794 else
4795 NewAttr( SvxParaGridItem(*pData, RES_PARATR_SNAPTOGRID) );
4799 void SwWW8ImplReader::Read_AlignFont( USHORT, const BYTE* pData, short nLen )
4801 if( nLen <= 0 )
4802 pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_PARATR_VERTALIGN);
4803 else
4805 sal_uInt16 nVal = SVBT16ToShort( pData );
4806 switch (nVal)
4808 case 0:
4809 nVal = SvxParaVertAlignItem::TOP;
4810 break;
4811 case 1:
4812 nVal = SvxParaVertAlignItem::CENTER;
4813 break;
4814 case 2:
4815 nVal = SvxParaVertAlignItem::BASELINE;
4816 break;
4817 case 3:
4818 nVal = SvxParaVertAlignItem::BOTTOM;
4819 break;
4820 case 4:
4821 nVal = SvxParaVertAlignItem::AUTOMATIC;
4822 break;
4823 default:
4824 nVal = SvxParaVertAlignItem::AUTOMATIC;
4825 ASSERT(!this,"Unknown paragraph vertical align");
4826 break;
4828 NewAttr( SvxParaVertAlignItem( nVal, RES_PARATR_VERTALIGN ) );
4832 void SwWW8ImplReader::Read_KeepLines( USHORT, const BYTE* pData, short nLen )
4834 if( nLen <= 0 )
4835 pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_PARATR_SPLIT );
4836 else
4837 NewAttr( SvxFmtSplitItem( ( *pData & 1 ) == 0, RES_PARATR_SPLIT ) );
4840 void SwWW8ImplReader::Read_KeepParas( USHORT, const BYTE* pData, short nLen )
4842 if( nLen <= 0 )
4843 pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_KEEP );
4844 else
4845 NewAttr( SvxFmtKeepItem( ( *pData & 1 ) != 0 , RES_KEEP) );
4848 void SwWW8ImplReader::Read_BreakBefore( USHORT, const BYTE* pData, short nLen )
4850 if( nLen <= 0 )
4851 pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_BREAK );
4852 else
4853 NewAttr( SvxFmtBreakItem(
4854 ( *pData & 1 ) ? SVX_BREAK_PAGE_BEFORE : SVX_BREAK_NONE, RES_BREAK ) );
4857 void SwWW8ImplReader::Read_ApoPPC( USHORT, const BYTE* pData, short )
4859 if (pAktColl) // only for Styledef, sonst anders geloest
4861 SwWW8StyInf& rSI = pCollA[nAktColl];
4862 WW8FlyPara* pFly = rSI.pWWFly ? rSI.pWWFly : new WW8FlyPara(bVer67);
4863 pCollA[nAktColl].pWWFly = pFly;
4864 pFly->Read(pData, pStyles);
4865 if (pFly->IsEmpty())
4866 delete pCollA[nAktColl].pWWFly, pCollA[nAktColl].pWWFly = 0;
4870 bool SwWW8ImplReader::ParseTabPos(WW8_TablePos *pTabPos, WW8PLCFx_Cp_FKP* pPap)
4872 bool bRet = false;
4873 const BYTE *pRes=0;
4874 memset(pTabPos, 0, sizeof(WW8_TablePos));
4875 if (0 != (pRes = pPap->HasSprm(0x360D)))
4877 pTabPos->nSp29 = *pRes;
4878 pTabPos->nSp37 = 2; //Possible fail area, always parallel wrap
4879 if (0 != (pRes = pPap->HasSprm(0x940E)))
4880 pTabPos->nSp26 = SVBT16ToShort(pRes);
4881 if (0 != (pRes = pPap->HasSprm(0x940F)))
4882 pTabPos->nSp27 = SVBT16ToShort(pRes);
4883 if (0 != (pRes = pPap->HasSprm(0x9410)))
4884 pTabPos->nLeMgn = SVBT16ToShort(pRes);
4885 if (0 != (pRes = pPap->HasSprm(0x941E)))
4886 pTabPos->nRiMgn = SVBT16ToShort(pRes);
4887 if (0 != (pRes = pPap->HasSprm(0x9411)))
4888 pTabPos->nUpMgn = SVBT16ToShort(pRes);
4889 if (0 != (pRes = pPap->HasSprm(0x941F)))
4890 pTabPos->nLoMgn = SVBT16ToShort(pRes);
4891 bRet = true;
4893 return bRet;
4896 /***************************************************************************
4897 # Seiten - Attribute werden nicht mehr als Attribute gehandhabt
4898 # ( ausser OLST )
4899 #**************************************************************************/
4902 long SwWW8ImplReader::ImportExtSprm(WW8PLCFManResult* pRes)
4904 /*************************************************************************
4905 # Arrays zum Lesen der erweiterten ( selbstdefinierten ) SPRMs
4906 #*************************************************************************/
4907 typedef long (SwWW8ImplReader:: *FNReadRecordExt)(WW8PLCFManResult*);
4909 static const FNReadRecordExt aWwSprmTab[] =
4911 /* 0 (256) */ &SwWW8ImplReader::Read_Ftn, // FootNote
4912 /* 1 (257) */ &SwWW8ImplReader::Read_Ftn, // EndNote
4913 /* 2 (258) */ &SwWW8ImplReader::Read_Field, // Feld
4914 /* 3 (259) */ &SwWW8ImplReader::Read_Book, // Bookmark
4915 /* 4 (260) */ &SwWW8ImplReader::Read_And // Annotation
4918 if( pRes->nSprmId < 280 )
4920 BYTE nIdx = static_cast< BYTE >(pRes->nSprmId - eFTN);
4921 if( nIdx < sizeof( aWwSprmTab ) / sizeof( *aWwSprmTab )
4922 && aWwSprmTab[nIdx] )
4923 return (this->*aWwSprmTab[nIdx])(pRes);
4924 else
4925 return 0;
4927 else
4928 return 0;
4931 void SwWW8ImplReader::EndExtSprm(USHORT nSprmId)
4933 typedef sal_uInt16 (SwWW8ImplReader:: *FNReadRecordExt)();
4935 static const FNReadRecordExt aWwSprmTab[] =
4937 /* 0 (256) */ &SwWW8ImplReader::End_Ftn, // FootNote
4938 /* 1 (257) */ &SwWW8ImplReader::End_Ftn, // EndNote
4939 /* 2 (258) */ &SwWW8ImplReader::End_Field, // Feld
4940 /* 3 (259) */ 0, // Bookmark
4941 /* 4 (260) */ 0 // Annotation
4944 BYTE nIdx = static_cast< BYTE >(nSprmId - eFTN);
4945 if( nIdx < sizeof( aWwSprmTab ) / sizeof( *aWwSprmTab )
4946 && aWwSprmTab[nIdx] )
4947 (this->*aWwSprmTab[nIdx])();
4950 /***************************************************************************
4951 # Arrays zum Lesen der SPRMs
4952 #**************************************************************************/
4954 // Funktion zum Einlesen von Sprms. Par1: SprmId
4955 typedef void (SwWW8ImplReader:: *FNReadRecord)( USHORT, const BYTE*, short );
4957 struct SprmReadInfo
4959 USHORT nId;
4960 FNReadRecord pReadFnc;
4963 bool operator==(const SprmReadInfo &rFirst, const SprmReadInfo &rSecond)
4965 return (rFirst.nId == rSecond.nId);
4968 bool operator<(const SprmReadInfo &rFirst, const SprmReadInfo &rSecond)
4970 return (rFirst.nId < rSecond.nId);
4973 typedef ww::SortedArray<SprmReadInfo> wwSprmDispatcher;
4975 const wwSprmDispatcher *GetWW2SprmDispatcher()
4977 static SprmReadInfo aSprms[] =
4979 {0, 0}, // "0" Default bzw. Error
4980 //wird uebersprungen! ,
4981 {2, &SwWW8ImplReader::Read_StyleCode}, //"sprmPIstd", pap.istd
4982 //(style code)
4983 {3, 0}, //"sprmPIstdPermute", pap.istd
4984 //permutation
4985 {4, 0}, //"sprmPIncLv1",
4986 //pap.istddifference
4987 {5, &SwWW8ImplReader::Read_Justify}, //"sprmPJc", pap.jc
4988 //(justification)
4989 {6, 0}, //"sprmPFSideBySide",
4990 //pap.fSideBySide
4991 {7, &SwWW8ImplReader::Read_KeepLines}, //"sprmPFKeep", pap.fKeep
4992 {8, &SwWW8ImplReader::Read_KeepParas}, //"sprmPFKeepFollow ",
4993 //pap.fKeepFollow
4994 {9, &SwWW8ImplReader::Read_BreakBefore}, //"sprmPPageBreakBefore",
4995 //pap.fPageBreakBefore
4996 {10, 0}, //"sprmPBrcl", pap.brcl
4997 {11, 0}, //"sprmPBrcp ", pap.brcp
4998 {12, &SwWW8ImplReader::Read_ANLevelDesc}, //"sprmPAnld", pap.anld (ANLD
4999 //structure)
5000 {13, &SwWW8ImplReader::Read_ANLevelNo}, //"sprmPNLvlAnm", pap.nLvlAnm
5001 //nn
5002 {14, &SwWW8ImplReader::Read_NoLineNumb}, //"sprmPFNoLineNumb", ap.fNoLnn
5003 {15, &SwWW8ImplReader::Read_Tab}, //"?sprmPChgTabsPapx",
5004 //pap.itbdMac, ...
5005 {16, &SwWW8ImplReader::Read_LR}, //"sprmPDxaRight", pap.dxaRight
5006 {17, &SwWW8ImplReader::Read_LR}, //"sprmPDxaLeft", pap.dxaLeft
5007 {18, 0}, //"sprmPNest", pap.dxaLeft
5008 {19, &SwWW8ImplReader::Read_LR}, //"sprmPDxaLeft1", pap.dxaLeft1
5009 {20, &SwWW8ImplReader::Read_LineSpace}, //"sprmPDyaLine", pap.lspd
5010 //an LSPD
5011 {21, &SwWW8ImplReader::Read_UL}, //"sprmPDyaBefore",
5012 //pap.dyaBefore
5013 {22, &SwWW8ImplReader::Read_UL}, //"sprmPDyaAfter", pap.dyaAfter
5014 {23, 0}, //"?sprmPChgTabs", pap.itbdMac,
5015 //pap.rgdxaTab, ...
5016 {24, 0}, //"sprmPFInTable", pap.fInTable
5017 {25, &SwWW8ImplReader::Read_TabRowEnd}, //"sprmPTtp", pap.fTtp
5018 {26, 0}, //"sprmPDxaAbs", pap.dxaAbs
5019 {27, 0}, //"sprmPDyaAbs", pap.dyaAbs
5020 {28, 0}, //"sprmPDxaWidth", pap.dxaWidth
5021 {29, &SwWW8ImplReader::Read_ApoPPC}, //"sprmPPc", pap.pcHorz,
5022 //pap.pcVert
5023 {30, 0}, //"sprmPBrcTop10", pap.brcTop
5024 //BRC10
5025 {31, 0}, //"sprmPBrcLeft10",
5026 //pap.brcLeft BRC10
5027 {32, 0}, //"sprmPBrcBottom10",
5028 //pap.brcBottom BRC10
5029 {33, 0}, //"sprmPBrcRight10",
5030 //pap.brcRight BRC10
5031 {34, 0}, //"sprmPBrcBetween10",
5032 //pap.brcBetween BRC10
5033 {35, 0}, //"sprmPBrcBar10", pap.brcBar
5034 //BRC10
5035 {36, 0}, //"sprmPFromText10",
5036 //pap.dxaFromText dxa
5037 {37, 0}, //"sprmPWr", pap.wr wr
5038 {38, &SwWW8ImplReader::Read_Border}, //"sprmPBrcTop", pap.brcTop BRC
5039 {39, &SwWW8ImplReader::Read_Border}, //"sprmPBrcLeft",
5040 //pap.brcLeft BRC
5041 {40, &SwWW8ImplReader::Read_Border}, //"sprmPBrcBottom",
5042 //pap.brcBottom BRC
5043 {41, &SwWW8ImplReader::Read_Border}, //"sprmPBrcRight",
5044 //pap.brcRight BRC
5045 {42, &SwWW8ImplReader::Read_Border}, //"sprmPBrcBetween",
5046 //pap.brcBetween BRC
5047 {43, 0}, //"sprmPBrcBar", pap.brcBar
5048 //BRC word
5049 {44, &SwWW8ImplReader::Read_Hyphenation}, //"sprmPFNoAutoHyph",
5050 //pap.fNoAutoHyph
5051 {45, 0}, //"sprmPWHeightAbs",
5052 //pap.wHeightAbs w
5053 {46, 0}, //"sprmPDcs", pap.dcs DCS
5054 {47, &SwWW8ImplReader::Read_Shade}, //"sprmPShd", pap.shd SHD
5055 {48, 0}, //"sprmPDyaFromText",
5056 //pap.dyaFromText dya
5057 {49, 0}, //"sprmPDxaFromText",
5058 //pap.dxaFromText dxa
5059 {50, 0}, //"sprmPFLocked", pap.fLocked
5060 //0 or 1 byte
5061 {51, &SwWW8ImplReader::Read_WidowControl}, //"sprmPFWidowControl",
5062 //pap.fWidowControl 0 or 1 byte
5063 {52, 0}, //"?sprmPRuler 52",
5064 {53, 0}, //"??53",
5065 {54, 0}, //"??54",
5066 {55, 0}, //"??55",
5067 {56, 0}, //"??56",
5068 {57, 0}, //"??57",
5069 {58, 0}, //"??58",
5070 {59, 0}, //"??59",
5072 {60, &SwWW8ImplReader::Read_BoldUsw}, //"sprmCFBold", chp.fBold 0,1,
5073 //128, or 129 byte
5074 {61, &SwWW8ImplReader::Read_BoldUsw}, //"sprmCFItalic", chp.fItalic
5075 //0,1, 128, or 129 byte
5076 {62, &SwWW8ImplReader::Read_BoldUsw}, //"sprmCFStrike", chp.fStrike
5077 //0,1, 128, or 129 byte
5078 {63, &SwWW8ImplReader::Read_BoldUsw}, //"sprmCFOutline", chp.fOutline
5079 //0,1, 128, or 129 byte
5080 {64, &SwWW8ImplReader::Read_BoldUsw}, //"sprmCFShadow", chp.fShadow
5081 //0,1, 128, or 129 byte
5082 {65, &SwWW8ImplReader::Read_BoldUsw}, //"sprmCFSmallCaps",
5083 //chp.fSmallCaps 0,1, 128, or
5084 //129 byte
5085 {66, &SwWW8ImplReader::Read_BoldUsw}, //"sprmCFCaps", chp.fCaps 0,1,
5086 //128, or 129 byte
5087 {67, &SwWW8ImplReader::Read_BoldUsw}, //"sprmCFVanish", chp.fVanish
5088 //0,1, 128, or 129 byte
5089 {68, &SwWW8ImplReader::Read_FontCode}, //"sprmCFtc", chp.ftc ftc word
5090 {69, &SwWW8ImplReader::Read_Underline}, // "sprmCKul", chp.kul kul byte
5091 {70, 0}, //"sprmCSizePos", chp.hps,
5092 //chp.hpsPos 3 bytes
5093 {71, &SwWW8ImplReader::Read_Kern}, //"sprmCDxaSpace",
5094 //chp.dxaSpace dxa word
5095 {72, &SwWW8ImplReader::Read_Language}, //"sprmCLid", chp.lid LID word
5096 {73, &SwWW8ImplReader::Read_TxtColor}, //"sprmCIco", chp.ico ico byte
5097 {74, &SwWW8ImplReader::Read_FontSize}, //"sprmCHps", chp.hps hps word!
5098 {75, 0}, //"sprmCHpsInc", chp.hps byte
5099 {76, &SwWW8ImplReader::Read_SubSuperProp}, //"sprmCHpsPos", chp.hpsPos
5100 //hps byte
5101 {77, 0}, //"sprmCHpsPosAdj", chp.hpsPos
5102 //hps byte
5103 {78, &SwWW8ImplReader::Read_Majority}, //"?sprmCMajority", chp.fBold,
5104 //chp.fItalic, chp.fSmallCaps
5105 {80, &SwWW8ImplReader::Read_BoldBiDiUsw}, //sprmCFBoldBi
5106 {81, &SwWW8ImplReader::Read_BoldBiDiUsw}, //sprmCFItalicBi
5107 {82, &SwWW8ImplReader::Read_FontCode}, //sprmCFtcBi
5108 {83, &SwWW8ImplReader::Read_Language}, //sprmClidBi
5109 {84, &SwWW8ImplReader::Read_TxtColor}, //sprmCIcoBi
5110 {85, &SwWW8ImplReader::Read_FontSize}, //sprmCHpsBi
5111 {86, 0}, //sprmCFBiDi
5112 {87, 0}, //sprmCFDiacColor
5113 {94, 0}, //"sprmPicBrcl", pic.brcl brcl
5114 //(see PIC structure
5115 //definition) byte
5116 {95, 0}, //"sprmPicScale", pic.mx,
5117 //pic.my, pic.dxaCropleft,
5118 {96, 0}, //"sprmPicBrcTop", pic.brcTop
5119 //BRC word
5120 {97, 0}, //"sprmPicBrcLeft",
5121 //pic.brcLeft BRC word
5122 {98, 0}, //"sprmPicBrcBottom",
5123 //pic.brcBottom BRC word
5124 {99, 0} //"sprmPicBrcRight",
5127 static wwSprmDispatcher aSprmSrch(aSprms, sizeof(aSprms) / sizeof(aSprms[0]));
5128 return &aSprmSrch;
5131 const wwSprmDispatcher *GetWW6SprmDispatcher()
5133 static SprmReadInfo aSprms[] =
5135 {0, 0}, // "0" Default bzw. Error
5136 //wird uebersprungen! ,
5137 {2, &SwWW8ImplReader::Read_StyleCode}, //"sprmPIstd", pap.istd
5138 //(style code)
5139 {3, 0}, //"sprmPIstdPermute", pap.istd
5140 //permutation
5141 {4, 0}, //"sprmPIncLv1",
5142 //pap.istddifference
5143 {5, &SwWW8ImplReader::Read_Justify}, //"sprmPJc", pap.jc
5144 //(justification)
5145 {6, 0}, //"sprmPFSideBySide",
5146 //pap.fSideBySide
5147 {7, &SwWW8ImplReader::Read_KeepLines}, //"sprmPFKeep", pap.fKeep
5148 {8, &SwWW8ImplReader::Read_KeepParas}, //"sprmPFKeepFollow ",
5149 //pap.fKeepFollow
5150 {9, &SwWW8ImplReader::Read_BreakBefore}, //"sprmPPageBreakBefore",
5151 //pap.fPageBreakBefore
5152 {10, 0}, //"sprmPBrcl", pap.brcl
5153 {11, 0}, //"sprmPBrcp ", pap.brcp
5154 {12, &SwWW8ImplReader::Read_ANLevelDesc}, //"sprmPAnld", pap.anld (ANLD
5155 //structure)
5156 {13, &SwWW8ImplReader::Read_ANLevelNo}, //"sprmPNLvlAnm", pap.nLvlAnm
5157 //nn
5158 {14, &SwWW8ImplReader::Read_NoLineNumb}, //"sprmPFNoLineNumb", ap.fNoLnn
5159 {15, &SwWW8ImplReader::Read_Tab}, //"?sprmPChgTabsPapx",
5160 //pap.itbdMac, ...
5161 {16, &SwWW8ImplReader::Read_LR}, //"sprmPDxaRight", pap.dxaRight
5162 {17, &SwWW8ImplReader::Read_LR}, //"sprmPDxaLeft", pap.dxaLeft
5163 {18, 0}, //"sprmPNest", pap.dxaLeft
5164 {19, &SwWW8ImplReader::Read_LR}, //"sprmPDxaLeft1", pap.dxaLeft1
5165 {20, &SwWW8ImplReader::Read_LineSpace}, //"sprmPDyaLine", pap.lspd
5166 //an LSPD
5167 {21, &SwWW8ImplReader::Read_UL}, //"sprmPDyaBefore",
5168 //pap.dyaBefore
5169 {22, &SwWW8ImplReader::Read_UL}, //"sprmPDyaAfter", pap.dyaAfter
5170 {23, 0}, //"?sprmPChgTabs", pap.itbdMac,
5171 //pap.rgdxaTab, ...
5172 {24, 0}, //"sprmPFInTable", pap.fInTable
5173 {25, &SwWW8ImplReader::Read_TabRowEnd}, //"sprmPTtp", pap.fTtp
5174 {26, 0}, //"sprmPDxaAbs", pap.dxaAbs
5175 {27, 0}, //"sprmPDyaAbs", pap.dyaAbs
5176 {28, 0}, //"sprmPDxaWidth", pap.dxaWidth
5177 {29, &SwWW8ImplReader::Read_ApoPPC}, //"sprmPPc", pap.pcHorz,
5178 //pap.pcVert
5179 {30, 0}, //"sprmPBrcTop10", pap.brcTop
5180 //BRC10
5181 {31, 0}, //"sprmPBrcLeft10",
5182 //pap.brcLeft BRC10
5183 {32, 0}, //"sprmPBrcBottom10",
5184 //pap.brcBottom BRC10
5185 {33, 0}, //"sprmPBrcRight10",
5186 //pap.brcRight BRC10
5187 {34, 0}, //"sprmPBrcBetween10",
5188 //pap.brcBetween BRC10
5189 {35, 0}, //"sprmPBrcBar10", pap.brcBar
5190 //BRC10
5191 {36, 0}, //"sprmPFromText10",
5192 //pap.dxaFromText dxa
5193 {37, 0}, //"sprmPWr", pap.wr wr
5194 {38, &SwWW8ImplReader::Read_Border}, //"sprmPBrcTop", pap.brcTop BRC
5195 {39, &SwWW8ImplReader::Read_Border}, //"sprmPBrcLeft",
5196 //pap.brcLeft BRC
5197 {40, &SwWW8ImplReader::Read_Border}, //"sprmPBrcBottom",
5198 //pap.brcBottom BRC
5199 {41, &SwWW8ImplReader::Read_Border}, //"sprmPBrcRight",
5200 //pap.brcRight BRC
5201 {42, &SwWW8ImplReader::Read_Border}, //"sprmPBrcBetween",
5202 //pap.brcBetween BRC
5203 {43, 0}, //"sprmPBrcBar", pap.brcBar
5204 //BRC word
5205 {44, &SwWW8ImplReader::Read_Hyphenation}, //"sprmPFNoAutoHyph",
5206 //pap.fNoAutoHyph
5207 {45, 0}, //"sprmPWHeightAbs",
5208 //pap.wHeightAbs w
5209 {46, 0}, //"sprmPDcs", pap.dcs DCS
5210 {47, &SwWW8ImplReader::Read_Shade}, //"sprmPShd", pap.shd SHD
5211 {48, 0}, //"sprmPDyaFromText",
5212 //pap.dyaFromText dya
5213 {49, 0}, //"sprmPDxaFromText",
5214 //pap.dxaFromText dxa
5215 {50, 0}, //"sprmPFLocked", pap.fLocked
5216 //0 or 1 byte
5217 {51, &SwWW8ImplReader::Read_WidowControl}, //"sprmPFWidowControl",
5218 //pap.fWidowControl 0 or 1 byte
5219 {52, 0}, //"?sprmPRuler 52",
5220 {53, 0}, //"??53",
5221 {54, 0}, //"??54",
5222 {55, 0}, //"??55",
5223 {56, 0}, //"??56",
5224 {57, 0}, //"??57",
5225 {58, 0}, //"??58",
5226 {59, 0}, //"??59",
5227 {60, 0}, //"??60",
5228 {61, 0}, //"??61",
5229 {62, 0}, //"??62",
5230 {63, 0}, //"??63",
5231 {64, &SwWW8ImplReader::Read_ParaBiDi}, //"rtl bidi ?
5232 {65, &SwWW8ImplReader::Read_CFRMarkDel}, //"sprmCFStrikeRM",
5233 //chp.fRMarkDel 1 or 0 bit
5234 {66, &SwWW8ImplReader::Read_CFRMark}, //"sprmCFRMark", chp.fRMark
5235 //1 or 0 bit
5236 {67, &SwWW8ImplReader::Read_FldVanish}, //"sprmCFFldVanish",
5237 //chp.fFldVanish 1 or 0 bit
5238 {68, &SwWW8ImplReader::Read_PicLoc}, //"sprmCPicLocation",
5239 //chp.fcPic and chp.fSpec
5240 {69, 0}, //"sprmCIbstRMark",
5241 //chp.ibstRMark index into
5242 //sttbRMark
5243 {70, 0}, //"sprmCDttmRMark", chp.dttm
5244 //DTTM long
5245 {71, 0}, //"sprmCFData", chp.fData 1 or
5246 //0 bit
5247 {72, 0}, //"sprmCRMReason",
5248 //chp.idslRMReason an index to
5249 //a table
5250 {73, &SwWW8ImplReader::Read_CharSet}, //"sprmCChse", chp.fChsDiff
5251 //and chp.chse 3 bytes
5252 {74, &SwWW8ImplReader::Read_Symbol}, //"sprmCSymbol", chp.fSpec,
5253 //chp.chSym and chp.ftcSym
5254 {75, &SwWW8ImplReader::Read_Obj}, //"sprmCFOle2", chp.fOle2 1
5255 //or 0 bit
5256 {76, 0}, //"??76",
5257 {77, 0}, //"??77",
5258 {78, 0}, //"??78",
5259 {79, 0}, //"??79",
5260 {80, &SwWW8ImplReader::Read_CColl}, //"sprmCIstd", chp.istd istd,
5261 //see stylesheet definition
5262 //short
5263 {81, 0}, //"sprmCIstdPermute", chp.istd
5264 //permutation vector
5265 {82, 0}, //"sprmCDefault", whole CHP
5266 //none variable length
5267 {83, 0}, //"sprmCPlain", whole CHP
5268 //none 0
5269 {84, 0}, //"??84",
5270 {85, &SwWW8ImplReader::Read_BoldUsw}, //"sprmCFBold", chp.fBold 0,1,
5271 //128, or 129 byte
5272 {86, &SwWW8ImplReader::Read_BoldUsw}, //"sprmCFItalic", chp.fItalic
5273 //0,1, 128, or 129 byte
5274 {87, &SwWW8ImplReader::Read_BoldUsw}, //"sprmCFStrike", chp.fStrike
5275 //0,1, 128, or 129 byte
5276 {88, &SwWW8ImplReader::Read_BoldUsw}, //"sprmCFOutline", chp.fOutline
5277 //0,1, 128, or 129 byte
5278 {89, &SwWW8ImplReader::Read_BoldUsw}, //"sprmCFShadow", chp.fShadow
5279 //0,1, 128, or 129 byte
5280 {90, &SwWW8ImplReader::Read_BoldUsw}, //"sprmCFSmallCaps",
5281 //chp.fSmallCaps 0,1, 128, or
5282 //129 byte
5283 {91, &SwWW8ImplReader::Read_BoldUsw}, //"sprmCFCaps", chp.fCaps 0,1,
5284 //128, or 129 byte
5285 {92, &SwWW8ImplReader::Read_BoldUsw}, //"sprmCFVanish", chp.fVanish
5286 //0,1, 128, or 129 byte
5287 {93, &SwWW8ImplReader::Read_FontCode}, //"sprmCFtc", chp.ftc ftc word
5288 {94, &SwWW8ImplReader::Read_Underline}, // "sprmCKul", chp.kul kul byte
5289 {95, 0}, //"sprmCSizePos", chp.hps,
5290 //chp.hpsPos 3 bytes
5291 {96, &SwWW8ImplReader::Read_Kern}, //"sprmCDxaSpace",
5292 //chp.dxaSpace dxa word
5293 {97, &SwWW8ImplReader::Read_Language}, //"sprmCLid", chp.lid LID word
5294 {98, &SwWW8ImplReader::Read_TxtColor}, //"sprmCIco", chp.ico ico byte
5295 {99, &SwWW8ImplReader::Read_FontSize}, //"sprmCHps", chp.hps hps word!
5296 {100, 0}, //"sprmCHpsInc", chp.hps byte
5297 {101, &SwWW8ImplReader::Read_SubSuperProp}, //"sprmCHpsPos", chp.hpsPos
5298 //hps byte
5299 {102, 0}, //"sprmCHpsPosAdj", chp.hpsPos
5300 //hps byte
5301 {103, &SwWW8ImplReader::Read_Majority}, //"?sprmCMajority", chp.fBold,
5302 //chp.fItalic, chp.fSmallCaps
5303 {104, &SwWW8ImplReader::Read_SubSuper}, //"sprmCIss", chp.iss iss byte
5304 {105, 0}, //"sprmCHpsNew50", chp.hps hps
5305 //variable width, length
5306 //always recorded as 2
5307 {106, 0}, //"sprmCHpsInc1", chp.hps
5308 //complex variable width,
5309 //length always recorded as 2
5310 {107, &SwWW8ImplReader::Read_FontKern}, //"sprmCHpsKern", chp.hpsKern
5311 //hps short
5312 {108, &SwWW8ImplReader::Read_Majority}, //"sprmCMajority50", chp.fBold,
5313 //chp.fItalic, chp.fSmallCaps,
5314 // chp.fVanish, ...
5315 {109, 0}, //"sprmCHpsMul", chp.hps
5316 //percentage to grow hps short
5317 {110, 0}, //"sprmCCondHyhen", chp.ysri
5318 //ysri short
5319 {111, &SwWW8ImplReader::Read_FontCode}, //ww7 font
5320 {112, &SwWW8ImplReader::Read_FontCode}, //ww7 CJK font
5321 {113, &SwWW8ImplReader::Read_FontCode}, //ww7 rtl font
5322 {114, &SwWW8ImplReader::Read_Language}, //ww7 lid
5323 {115, &SwWW8ImplReader::Read_TxtColor}, //ww7 rtl colour ?
5324 {116, &SwWW8ImplReader::Read_FontSize},
5325 {117, &SwWW8ImplReader::Read_Special}, //"sprmCFSpec", chp.fSpec 1
5326 //or 0 bit
5327 {118, &SwWW8ImplReader::Read_Obj}, //"sprmCFObj", chp.fObj 1 or 0
5328 //bit
5329 {119, 0}, //"sprmPicBrcl", pic.brcl brcl
5330 //(see PIC structure
5331 //definition) byte
5332 {120, 0}, //"sprmPicScale", pic.mx,
5333 //pic.my, pic.dxaCropleft,
5334 {121, 0}, //"sprmPicBrcTop", pic.brcTop
5335 //BRC word
5336 {122, 0}, //"sprmPicBrcLeft",
5337 //pic.brcLeft BRC word
5338 {123, 0}, //"sprmPicBrcBottom",
5339 //pic.brcBottom BRC word
5340 {124, 0}, //"sprmPicBrcRight",
5341 //pic.brcRight BRC word
5342 {125, 0}, //"??125",
5343 {126, 0}, //"??126",
5344 {127, 0}, //"??127",
5345 {128, 0}, //"??128",
5346 {129, 0}, //"??129",
5347 {130, 0}, //"??130",
5348 {131, 0}, //"sprmSScnsPgn", sep.cnsPgn
5349 //cns byte
5350 {132, 0}, //"sprmSiHeadingPgn",
5351 //sep.iHeadingPgn heading
5352 //number level byte
5353 {133, &SwWW8ImplReader::Read_OLST}, //"sprmSOlstAnm", sep.olstAnm
5354 //OLST variable length
5355 {134, 0}, //"??135",
5356 {135, 0}, //"??135",
5357 {136, 0}, //"sprmSDxaColWidth",
5358 //sep.rgdxaColWidthSpacing
5359 //complex 3 bytes
5360 {137, 0}, //"sprmSDxaColSpacing",
5361 //sep.rgdxaColWidthSpacing
5362 //complex 3 bytes
5363 {138, 0}, //"sprmSFEvenlySpaced",
5364 //sep.fEvenlySpaced 1 or 0 byte
5365 {139, 0}, //"sprmSFProtected",
5366 //sep.fUnlocked 1 or 0 byte
5367 {140, 0}, //"sprmSDmBinFirst",
5368 //sep.dmBinFirst word
5369 {141, 0}, //"sprmSDmBinOther",
5370 //sep.dmBinOther word
5371 {142, 0}, //"sprmSBkc", sep.bkc bkc
5372 //byte BreakCode
5373 {143, 0}, //"sprmSFTitlePage",
5374 //sep.fTitlePage 0 or 1 byte
5375 {144, 0}, //"sprmSCcolumns", sep.ccolM1
5376 //# of cols - 1 word
5377 {145, 0}, //"sprmSDxaColumns",
5378 //sep.dxaColumns dxa word
5379 {146, 0}, //"sprmSFAutoPgn",
5380 //sep.fAutoPgn obsolete byte
5381 {147, 0}, //"sprmSNfcPgn", sep.nfcPgn
5382 //nfc byte
5383 {148, 0}, //"sprmSDyaPgn", sep.dyaPgn
5384 //dya short
5385 {149, 0}, //"sprmSDxaPgn", sep.dxaPgn
5386 //dya short
5387 {150, 0}, //"sprmSFPgnRestart",
5388 //sep.fPgnRestart 0 or 1 byte
5389 {151, 0}, //"sprmSFEndnote", sep.fEndnote
5390 //0 or 1 byte
5391 {152, 0}, //"sprmSLnc", sep.lnc lnc byte
5392 {153, 0}, //"sprmSGprfIhdt", sep.grpfIhdt
5393 //grpfihdt byte
5394 {154, 0}, //"sprmSNLnnMod", sep.nLnnMod
5395 //non-neg int. word
5396 {155, 0}, //"sprmSDxaLnn", sep.dxaLnn
5397 //dxa word
5398 {156, 0}, //"sprmSDyaHdrTop",
5399 //sep.dyaHdrTop dya word
5400 {157, 0}, //"sprmSDyaHdrBottom",
5401 //sep.dyaHdrBottom dya word
5402 {158, 0}, //"sprmSLBetween",
5403 //sep.fLBetween 0 or 1 byte
5404 {159, 0}, //"sprmSVjc", sep.vjc vjc byte
5405 {160, 0}, //"sprmSLnnMin", sep.lnnMin
5406 //lnn word
5407 {161, 0}, //"sprmSPgnStart", sep.pgnStart
5408 //pgn word
5409 {162, 0}, //"sprmSBOrientation",
5410 //sep.dmOrientPage dm byte
5411 {163, 0}, //"?SprmSBCustomize 163", ?
5412 {164, 0}, //"sprmSXaPage", sep.xaPage xa
5413 //word
5414 {165, 0}, //"sprmSYaPage", sep.yaPage ya
5415 //word
5416 {166, 0}, //"sprmSDxaLeft", sep.dxaLeft
5417 //dxa word
5418 {167, 0}, //"sprmSDxaRight", sep.dxaRight
5419 //dxa word
5420 {168, 0}, //"sprmSDyaTop", sep.dyaTop //dya word
5421 {169, 0}, //"sprmSDyaBottom",
5422 //sep.dyaBottom dya word
5423 {170, 0}, //"sprmSDzaGutter",
5424 //sep.dzaGutter dza word
5425 {171, 0}, //"sprmSDMPaperReq",
5426 //sep.dmPaperReq dm word
5427 {172, 0}, //"??172",
5428 {173, 0}, //"??173",
5429 {174, 0}, //"??174",
5430 {175, 0}, //"??175",
5431 {176, 0}, //"??176",
5432 {177, 0}, //"??177",
5433 {178, 0}, //"??178",
5434 {179, 0}, //"??179",
5435 {180, 0}, //"??180",
5436 {181, 0}, //"??181",
5437 {182, 0}, //"sprmTJc", tap.jc jc word
5438 //(low order byte is
5439 //significant)
5440 {183, 0}, //"sprmTDxaLeft",
5441 //tap.rgdxaCenter dxa word
5442 {184, 0}, //"sprmTDxaGapHalf",
5443 //tap.dxaGapHalf,
5444 //tap.rgdxaCenter dxa word
5445 {185, 0}, //"sprmTFCantSplit"
5446 //tap.fCantSplit 1 or 0 byte
5447 {186, 0}, //"sprmTTableHeader",
5448 //tap.fTableHeader 1 or 0 byte
5449 {187, 0}, //"sprmTTableBorders",
5450 //tap.rgbrcTable complex
5451 //12 bytes
5452 {188, 0}, //"sprmTDefTable10",
5453 //tap.rgdxaCenter, tap.rgtc
5454 //complex variable length
5455 {189, 0}, //"sprmTDyaRowHeight",
5456 //tap.dyaRowHeight dya word
5457 {190, 0}, //"?sprmTDefTable", tap.rgtc
5458 //complex
5459 {191, 0}, //"?sprmTDefTableShd",
5460 //tap.rgshd complex
5461 {192, 0}, //"sprmTTlp", tap.tlp TLP
5462 //4 bytes
5463 {193, 0}, //"sprmTSetBrc",
5464 //tap.rgtc[].rgbrc complex
5465 //5 bytes
5466 {194, 0}, //"sprmTInsert",
5467 //tap.rgdxaCenter,
5468 //tap.rgtc complex 4 bytes
5469 {195, 0}, //"sprmTDelete",
5470 //tap.rgdxaCenter,
5471 //tap.rgtc complex word
5472 {196, 0}, //"sprmTDxaCol",
5473 //tap.rgdxaCenter complex
5474 //4 bytes
5475 {197, 0}, //"sprmTMerge",
5476 //tap.fFirstMerged,
5477 //tap.fMerged complex word
5478 {198, 0}, //"sprmTSplit",
5479 //tap.fFirstMerged,
5480 //tap.fMerged complex word
5481 {199, 0}, //"sprmTSetBrc10",
5482 //tap.rgtc[].rgbrc complex
5483 //5 bytes
5484 {200, 0}, //"sprmTSetShd", tap.rgshd
5485 //complex 4 bytes
5486 {207, 0}, //dunno
5489 static wwSprmDispatcher aSprmSrch(aSprms, sizeof(aSprms) / sizeof(aSprms[0]));
5490 return &aSprmSrch;
5493 const wwSprmDispatcher *GetWW8SprmDispatcher()
5495 static SprmReadInfo aSprms[] =
5497 {0, 0}, // "0" Default bzw. Error
5499 {0x4600, &SwWW8ImplReader::Read_StyleCode}, //"sprmPIstd" pap.istd;istd
5500 //(style code);short;
5501 {0xC601, 0}, //"sprmPIstdPermute" pap.istd;
5502 //permutation vector;
5503 //variable length;
5504 {0x2602, 0}, //"sprmPIncLvl" pap.istd,
5505 //pap.lvl;difference between
5506 //istd of base PAP and istd of
5507 //PAP to be produced; byte;
5508 {0x2403, &SwWW8ImplReader::Read_Justify}, //"sprmPJc" pap.jc;jc
5509 //(justification);byte;
5510 {0x2404, 0}, //"sprmPFSideBySide"
5511 //pap.fSideBySide;0 or 1;byte;
5512 {0x2405, &SwWW8ImplReader::Read_KeepLines}, //"sprmPFKeep" pap.fKeep;0 or
5513 //1;byte;
5514 {0x2406, &SwWW8ImplReader::Read_KeepParas}, //"sprmPFKeepFollow"
5515 //pap.fKeepFollow;0 or 1;byte;
5516 {0x2407, &SwWW8ImplReader::Read_BreakBefore},//"sprmPFPageBreakBefore"
5517 //pap.fPageBreakBefore;0 or 1;
5518 //byte;
5519 {0x2408, 0}, //"sprmPBrcl" pap.brcl;brcl;
5520 //byte;
5521 {0x2409, 0}, //"sprmPBrcp" pap.brcp;brcp;
5522 //byte;
5523 {0x260A, &SwWW8ImplReader::Read_ListLevel}, //"sprmPIlvl" pap.ilvl;ilvl;
5524 //byte;
5525 {0x460B, &SwWW8ImplReader::Read_LFOPosition},//"sprmPIlfo" pap.ilfo;ilfo
5526 //(list index) ;short;
5527 {0x240C, &SwWW8ImplReader::Read_NoLineNumb}, //"sprmPFNoLineNumb"
5528 //pap.fNoLnn;0 or 1;byte;
5529 {0xC60D, &SwWW8ImplReader::Read_Tab}, //"sprmPChgTabsPapx"
5530 //pap.itbdMac, pap.rgdxaTab,
5531 //pap.rgtbd;complex;variable
5532 //length
5533 {0x840E, &SwWW8ImplReader::Read_LR}, //Word 97 version of "sprmPDxaRight" pap.dxaRight;
5534 //dxa;word;
5535 {0x840F, &SwWW8ImplReader::Read_LR}, //Apparently Word 97 version of "sprmPDxaLeft" pap.dxaLeft;
5536 //dxa;word;
5537 {0x4610, 0}, //"sprmPNest" pap.dxaLeft;
5538 //dxa;word;
5539 {0x8411, &SwWW8ImplReader::Read_LR}, //Word 97 version of "sprmPDxaLeft1" pap.dxaLeft1;
5540 //dxa;word;
5541 {0x6412, &SwWW8ImplReader::Read_LineSpace}, //"sprmPDyaLine" pap.lspd;
5542 //an LSPD, a long word
5543 //structure consisting of a
5544 //short of dyaLine followed by
5545 //a short of fMultLinespace;
5546 //long;
5547 {0xA413, &SwWW8ImplReader::Read_UL}, //"sprmPDyaBefore"
5548 //pap.dyaBefore;dya;word;
5549 {0xA414, &SwWW8ImplReader::Read_UL}, //"sprmPDyaAfter" pap.dyaAfter;
5550 //dya;word;
5551 {0xC615, 0}, //"sprmPChgTabs" pap.itbdMac,
5552 //pap.rgdxaTab, pap.rgtbd;
5553 //complex;variable length;
5554 {0x2416, 0}, //"sprmPFInTable" pap.fInTable;
5555 //0 or 1;byte;
5556 {0x2417, &SwWW8ImplReader::Read_TabRowEnd}, //"sprmPFTtp" pap.fTtp;0 or 1;
5557 //byte;
5558 {0x8418, 0}, //"sprmPDxaAbs" pap.dxaAbs;dxa;
5559 //word;
5560 {0x8419, 0}, //"sprmPDyaAbs" pap.dyaAbs;dya;
5561 //word;
5562 {0x841A, 0}, //"sprmPDxaWidth" pap.dxaWidth;
5563 //dxa;word;
5564 {0x261B, &SwWW8ImplReader::Read_ApoPPC}, //"sprmPPc" pap.pcHorz,
5565 //pap.pcVert;complex;byte;
5566 {0x461C, 0}, //"sprmPBrcTop10" pap.brcTop;
5567 //BRC10;word;
5568 {0x461D, 0}, //"sprmPBrcLeft10" pap.brcLeft;
5569 //BRC10;word;
5570 {0x461E, 0}, //"sprmPBrcBottom10"
5571 //pap.brcBottom;BRC10;word;
5572 {0x461F, 0}, //"sprmPBrcRight10"
5573 //pap.brcRight;BRC10;word;
5574 {0x4620, 0}, //"sprmPBrcBetween10"
5575 //pap.brcBetween;BRC10;word;
5576 {0x4621, 0}, //"sprmPBrcBar10" pap.brcBar;
5577 //BRC10;word;
5578 {0x4622, 0}, //"sprmPDxaFromText10"
5579 //pap.dxaFromText;dxa;word;
5580 {0x2423, 0}, //"sprmPWr" pap.wr;wr;byte;
5581 {0x6424, &SwWW8ImplReader::Read_Border}, //"sprmPBrcTop" pap.brcTop;BRC;
5582 //long;
5583 {0x6425, &SwWW8ImplReader::Read_Border}, //"sprmPBrcLeft" pap.brcLeft;
5584 //BRC;long;
5585 {0x6426, &SwWW8ImplReader::Read_Border}, //"sprmPBrcBottom"
5586 //pap.brcBottom;BRC;long;
5587 {0x6427, &SwWW8ImplReader::Read_Border}, //"sprmPBrcRight" pap.brcRight;
5588 //BRC;long;
5589 {0x6428, &SwWW8ImplReader::Read_Border}, //"sprmPBrcBetween"
5590 //pap.brcBetween;BRC;long;
5591 {0x6629, 0}, //"sprmPBrcBar" pap.brcBar;BRC;
5592 //long;
5593 {0x242A, &SwWW8ImplReader::Read_Hyphenation},//"sprmPFNoAutoHyph"
5594 //pap.fNoAutoHyph;0 or 1;byte;
5595 {0x442B, 0}, //"sprmPWHeightAbs"
5596 //pap.wHeightAbs;w;word;
5597 {0x442C, 0}, //"sprmPDcs" pap.dcs;DCS;short;
5598 {0x442D, &SwWW8ImplReader::Read_Shade}, //"sprmPShd" pap.shd;SHD;word;
5599 {0x842E, 0}, //"sprmPDyaFromText"
5600 //pap.dyaFromText;dya;word;
5601 {0x842F, 0}, //"sprmPDxaFromText"
5602 //pap.dxaFromText;dxa;word;
5603 {0x2430, 0}, //"sprmPFLocked" pap.fLocked;
5604 //0 or 1;byte;
5605 {0x2431, &SwWW8ImplReader::Read_WidowControl},//"sprmPFWidowControl"
5606 //pap.fWidowControl;0 or 1;byte
5607 {0xC632, 0}, //"sprmPRuler" variable length;
5608 {0x2433, &SwWW8ImplReader::Read_BoolItem}, //"sprmPFKinsoku" pap.fKinsoku;
5609 //0 or 1;byte;
5610 {0x2434, 0}, //"sprmPFWordWrap"
5611 //pap.fWordWrap;0 or 1;byte;
5612 {0x2435, &SwWW8ImplReader::Read_BoolItem}, //"sprmPFOverflowPunct"
5613 //pap.fOverflowPunct; 0 or 1;
5614 //byte;
5615 {0x2436, 0}, //"sprmPFTopLinePunct"
5616 //pap.fTopLinePunct;0 or 1;byte
5617 {0x2437, &SwWW8ImplReader::Read_BoolItem}, //"sprmPFAutoSpaceDE"
5618 //pap.fAutoSpaceDE;0 or 1;byte;
5619 {0x2438, 0}, //"sprmPFAutoSpaceDN"
5620 //pap.fAutoSpaceDN;0 or 1;byte;
5621 {0x4439, &SwWW8ImplReader::Read_AlignFont}, //"sprmPWAlignFont"
5622 //pap.wAlignFont;iFa; word;
5623 {0x443A, 0}, //"sprmPFrameTextFlow"
5624 //pap.fVertical pap.fBackward
5625 //pap.fRotateFont;complex; word
5626 {0x243B, 0}, //"sprmPISnapBaseLine" obsolete
5627 //not applicable in Word97
5628 //and later versions;;byte;
5629 {0xC63E, &SwWW8ImplReader::Read_ANLevelDesc},//"sprmPAnld" pap.anld;;
5630 //variable length;
5631 {0xC63F, 0}, //"sprmPPropRMark"
5632 //pap.fPropRMark;complex;
5633 //variable length;
5634 {0x2640, &SwWW8ImplReader::Read_POutLvl}, //"sprmPOutLvl" pap.lvl;has no
5635 //effect if pap.istd is < 1 or
5636 //is > 9;byte;
5637 {0x2441, &SwWW8ImplReader::Read_ParaBiDi}, //"sprmPFBiDi" ;;byte;
5638 {0x2443, 0}, //"sprmPFNumRMIns"
5639 //pap.fNumRMIns;1 or 0;bit;
5640 {0x2444, 0}, //"sprmPCrLf" ;;byte;
5641 {0xC645, 0}, //"sprmPNumRM" pap.numrm;;
5642 //variable length;
5643 {0x6645, 0}, //"sprmPHugePapx" ;fc in the
5644 //data stream to locate the
5645 //huge grpprl; long;
5646 {0x6646, 0}, //"sprmPHugePapx" ;fc in the
5647 //data stream to locate the
5648 //huge grpprl; long;
5649 {0x2447, &SwWW8ImplReader::Read_UsePgsuSettings},//"sprmPFUsePgsuSettings"
5650 //pap.fUsePgsuSettings;1 or 0;
5651 //byte;
5652 {0x2448, 0}, //"sprmPFAdjustRight"
5653 //pap.fAdjustRight;1 or 0;byte;
5654 {0x0800, &SwWW8ImplReader::Read_CFRMarkDel}, //"sprmCFRMarkDel"
5655 //chp.fRMarkDel;1 or 0;bit;
5656 {0x0801, &SwWW8ImplReader::Read_CFRMark}, //"sprmCFRMark" chp.fRMark;1
5657 //or 0;bit;
5658 {0x0802, &SwWW8ImplReader::Read_FldVanish}, //"sprmCFFldVanish"
5659 //chp.fFldVanish;1 or 0;bit;
5660 {0x6A03, &SwWW8ImplReader::Read_PicLoc}, //"sprmCPicLocation" chp.fcPic
5661 //and chp.fSpec;variable
5662 //length, length recorded is
5663 //always 4;
5664 {0x4804, 0}, //"sprmCIbstRMark"
5665 //chp.ibstRMark;index into
5666 //sttbRMark;short;
5667 {0x6805, 0}, //"sprmCDttmRMark"
5668 //chp.dttmRMark;DTTM;long;
5669 {0x0806, 0}, //"sprmCFData" chp.fData;1 or
5670 //0;bit;
5671 {0x4807, 0}, //"sprmCIdslRMark"
5672 //chp.idslRMReason;an index to
5673 //a table of strings defined in
5674 //Word 6.0 executables;short;
5675 {0xEA08, &SwWW8ImplReader::Read_CharSet}, //"sprmCChs" chp.fChsDiff and
5676 //chp.chse;3 bytes;
5677 {0x6A09, &SwWW8ImplReader::Read_Symbol}, //"sprmCSymbol" chp.fSpec,
5678 //chp.xchSym and chp.ftcSym;
5679 //variable length, length
5680 //recorded is always 4;
5681 {0x080A, &SwWW8ImplReader::Read_Obj}, //"sprmCFOle2" chp.fOle2;1 or
5682 //0;bit;
5683 //0x480B, //"sprmCIdCharType", obsolete:
5684 //not applicable in Word97
5685 //and later versions
5686 {0x2A0C, &SwWW8ImplReader::Read_CharHighlight},//"sprmCHighlight"
5687 //chp.fHighlight,
5688 //chp.icoHighlight;ico
5689 //(fHighlight is set to 1 iff
5690 //ico is not 0);byte;
5691 {0x680E, &SwWW8ImplReader::Read_PicLoc}, //"sprmCObjLocation" chp.fcObj;
5692 //FC;long;
5693 //0x2A10, ? ? ?, //"sprmCFFtcAsciSymb"
5694 {0x4A30, &SwWW8ImplReader::Read_CColl}, //"sprmCIstd" chp.istd;istd,
5695 //short;
5696 {0xCA31, 0}, //"sprmCIstdPermute" chp.istd;
5697 //permutation vector; variable
5698 //length;
5699 {0x2A32, 0}, //"sprmCDefault" whole CHP;none
5700 //;variable length;
5701 {0x2A33, 0}, //"sprmCPlain" whole CHP;none;
5702 //Laenge: 0;
5703 {0x2A34, &SwWW8ImplReader::Read_Emphasis}, //"sprmCKcd"
5704 {0x0835, &SwWW8ImplReader::Read_BoldUsw}, //"sprmCFBold" chp.fBold;0,1,
5705 //128, or 129; byte;
5706 {0x0836, &SwWW8ImplReader::Read_BoldUsw}, //"sprmCFItalic" chp.fItalic;0,
5707 //1, 128, or 129; byte;
5708 {0x0837, &SwWW8ImplReader::Read_BoldUsw}, //"sprmCFStrike" chp.fStrike;0,
5709 //1, 128, or 129; byte;
5710 {0x0838, &SwWW8ImplReader::Read_BoldUsw}, //"sprmCFOutline" chp.fOutline;
5711 //0,1, 128, or 129; byte;
5712 {0x0839, &SwWW8ImplReader::Read_BoldUsw}, //"sprmCFShadow" chp.fShadow;0,
5713 //1, 128, or 129; byte;
5714 {0x083A, &SwWW8ImplReader::Read_BoldUsw}, //"sprmCFSmallCaps"
5715 //chp.fSmallCaps;0,1, 128, or
5716 //129;byte;
5717 {0x083B, &SwWW8ImplReader::Read_BoldUsw}, //"sprmCFCaps" chp.fCaps;0,1,
5718 //128, or 129; byte;
5719 {0x083C, &SwWW8ImplReader::Read_BoldUsw}, //"sprmCFVanish" chp.fVanish;0,
5720 //1, 128, or 129; byte;
5721 //0x4A3D, 0, //"sprmCFtcDefault" ftc, only
5722 //used internally, never
5723 //stored in file;word;
5724 {0x2A3E, &SwWW8ImplReader::Read_Underline}, //"sprmCKul" chp.kul;kul;byte;
5725 {0xEA3F, 0}, //"sprmCSizePos" chp.hps,
5726 //chp.hpsPos;3 bytes;
5727 {0x8840, &SwWW8ImplReader::Read_Kern}, //"sprmCDxaSpace" chp.dxaSpace;
5728 //dxa;word;
5729 {0x4A41, &SwWW8ImplReader::Read_Language}, //"sprmCLid" ;only used
5730 //internally never stored;word;
5731 {0x2A42, &SwWW8ImplReader::Read_TxtColor}, //"sprmCIco" chp.ico;ico;byte;
5732 {0x4A43, &SwWW8ImplReader::Read_FontSize}, //"sprmCHps" chp.hps;hps;byte;
5733 {0x2A44, 0}, //"sprmCHpsInc" chp.hps;byte;
5734 {0x4845, &SwWW8ImplReader::Read_SubSuperProp},//"sprmCHpsPos" chp.hpsPos;
5735 //hps; byte;
5736 {0x2A46, 0}, //"sprmCHpsPosAdj" chp.hpsPos;
5737 //hps; byte;
5738 {0xCA47, &SwWW8ImplReader::Read_Majority}, //"sprmCMajority" chp.fBold,
5739 //chp.fItalic, chp.fSmallCaps,
5740 //chp.fVanish, chp.fStrike,
5741 //chp.fCaps, chp.rgftc,
5742 //chp.hps, chp.hpsPos, chp.kul,
5743 //chp.dxaSpace, chp.ico,
5744 //chp.rglid;complex;variable
5745 //length, length byte plus
5746 //size of following grpprl;
5747 {0x2A48, &SwWW8ImplReader::Read_SubSuper}, //"sprmCIss" chp.iss;iss;byte;
5748 {0xCA49, 0}, //"sprmCHpsNew50" chp.hps;hps;
5749 //variable width, length
5750 //always recorded as 2;
5751 {0xCA4A, 0}, //"sprmCHpsInc1" chp.hps;
5752 //complex; variable width,
5753 //length always recorded as 2;
5754 {0x484B, &SwWW8ImplReader::Read_FontKern}, //"sprmCHpsKern" chp.hpsKern;
5755 //hps;short;
5756 {0xCA4C, &SwWW8ImplReader::Read_Majority}, //"sprmCMajority50" chp.fBold,
5757 //chp.fItalic, chp.fSmallCaps,
5758 //chp.fVanish, chp.fStrike,
5759 //chp.fCaps, chp.ftc, chp.hps,
5760 //chp.hpsPos, chp.kul,
5761 //chp.dxaSpace, chp.ico;
5762 //complex; variable length;
5763 {0x4A4D, 0}, //"sprmCHpsMul" chp.hps;
5764 //percentage to grow hps;short;
5765 {0x484E, 0}, //"sprmCYsri" chp.ysri;ysri;
5766 //short;
5767 {0x4A4F, &SwWW8ImplReader::Read_FontCode}, //"sprmCRgFtc0" chp.rgftc[0];
5768 //ftc for ASCII text; short;
5769 {0x4A50, &SwWW8ImplReader::Read_FontCode}, //"sprmCRgFtc1" chp.rgftc[1];
5770 //ftc for Far East text;short;
5771 {0x4A51, &SwWW8ImplReader::Read_FontCode}, //"sprmCRgFtc2" chp.rgftc[2];
5772 //ftc for non-Far East text;
5773 //short;
5774 {0x4852, &SwWW8ImplReader::Read_ScaleWidth}, //"sprmCCharScale"
5775 {0x2A53, &SwWW8ImplReader::Read_BoldUsw}, //"sprmCFDStrike" chp.fDStrike;
5776 //;byte;
5777 {0x0854, &SwWW8ImplReader::Read_Relief}, //"sprmCFImprint" chp.fImprint;
5778 //1 or 0;bit;
5779 {0x0855, &SwWW8ImplReader::Read_Special}, //"sprmCFSpec" chp.fSpec;
5780 //1 or 0;bit;
5781 {0x0856, &SwWW8ImplReader::Read_Obj}, //"sprmCFObj" chp.fObj;1 or 0;
5782 //bit;
5783 {0xCA57, &SwWW8ImplReader::Read_CPropRMark}, //"sprmCPropRMark"
5784 //chp.fPropRMark,
5785 //chp.ibstPropRMark,
5786 //chp.dttmPropRMark;Complex;
5787 //variable length always
5788 //recorded as 7 bytes;
5789 {0x0858, &SwWW8ImplReader::Read_Relief}, //"sprmCFEmboss" chp.fEmboss;
5790 //1 or 0;bit;
5791 {0x2859, &SwWW8ImplReader::Read_TxtAnim}, //"sprmCSfxText" chp.sfxtText;
5792 //text animation;byte;
5793 {0x085A, &SwWW8ImplReader::Read_Bidi}, //"sprmCFBiDi"
5794 {0x085B, 0}, //"sprmCFDiacColor"
5795 {0x085C, &SwWW8ImplReader::Read_BoldBiDiUsw},//"sprmCFBoldBi"
5796 {0x085D, &SwWW8ImplReader::Read_BoldBiDiUsw},//"sprmCFItalicBi"
5797 {0x4A5E, &SwWW8ImplReader::Read_FontCode},
5798 {0x485F, &SwWW8ImplReader::Read_Language}, // "sprmCLidBi"
5799 //0x4A60, ? ? ?, //"sprmCIcoBi",
5800 {0x4A61, &SwWW8ImplReader::Read_FontSize}, //"sprmCHpsBi"
5801 {0xCA62, 0}, //"sprmCDispFldRMark"
5802 //chp.fDispFldRMark,
5803 //chp.ibstDispFldRMark,
5804 //chp.dttmDispFldRMark ;
5805 //Complex;variable length
5806 //always recorded as 39 bytes;
5807 {0x4863, 0}, //"sprmCIbstRMarkDel"
5808 //chp.ibstRMarkDel;index into
5809 //sttbRMark;short;
5810 {0x6864, 0}, //"sprmCDttmRMarkDel"
5811 //chp.dttmRMarkDel;DTTM;long;
5812 {0x6865, 0}, //"sprmCBrc" chp.brc;BRC;long;
5813 {0x4866, &SwWW8ImplReader::Read_CharShadow}, //"sprmCShd" chp.shd;SHD;short;
5814 {0x4867, 0}, //"sprmCIdslRMarkDel"
5815 //chp.idslRMReasonDel;an index
5816 //to a table of strings
5817 //defined in Word 6.0
5818 //executables;short;
5819 {0x0868, 0}, //"sprmCFUsePgsuSettings"
5820 //chp.fUsePgsuSettings; 1 or 0;
5821 //bit;
5822 {0x486B, 0}, //"sprmCCpg" ;;word;
5823 {0x486D, &SwWW8ImplReader::Read_Language}, //"sprmCRgLid0" chp.rglid[0];
5824 //LID: for non-Far East text;
5825 //word;
5826 {0x486E, &SwWW8ImplReader::Read_Language}, //"sprmCRgLid1" chp.rglid[1];
5827 //LID: for Far East text;word;
5828 {0x286F, &SwWW8ImplReader::Read_IdctHint}, //"sprmCIdctHint" chp.idctHint;
5829 //IDCT: byte;
5830 {0x2E00, 0}, //"sprmPicBrcl" pic.brcl;brcl
5831 //(see PIC structure
5832 //definition);byte;
5833 {0xCE01, 0}, //"sprmPicScale" pic.mx,
5834 //pic.my, pic.dxaCropleft,
5835 //pic.dyaCropTop
5836 //pic.dxaCropRight,
5837 //pic.dyaCropBottom;Complex;
5838 //length byte plus 12 bytes;
5839 {0x6C02, 0}, //"sprmPicBrcTop" pic.brcTop;
5840 //BRC;long;
5841 {0x6C03, 0}, //"sprmPicBrcLeft" pic.brcLeft;
5842 //BRC;long;
5843 {0x6C04, 0}, //"sprmPicBrcBottom"
5844 //pic.brcBottom;BRC;long;
5845 {0x6C05, 0}, //"sprmPicBrcRight"
5846 //pic.brcRight;BRC;long;
5847 {0x3000, 0}, //"sprmScnsPgn" sep.cnsPgn;cns;
5848 //byte;
5849 {0x3001, 0}, //"sprmSiHeadingPgn"
5850 //sep.iHeadingPgn;heading
5851 //number level;byte;
5852 {0xD202, &SwWW8ImplReader::Read_OLST}, //"sprmSOlstAnm" sep.olstAnm;
5853 //OLST;variable length;
5854 {0xF203, 0}, //"sprmSDxaColWidth"
5855 //sep.rgdxaColWidthSpacing;
5856 //complex; 3 bytes;
5857 {0xF204, 0}, //"sprmSDxaColSpacing"
5858 //sep.rgdxaColWidthSpacing;
5859 //complex; 3 bytes;
5860 {0x3005, 0}, //"sprmSFEvenlySpaced"
5861 //sep.fEvenlySpaced; 1 or 0;
5862 //byte;
5863 {0x3006, 0}, //"sprmSFProtected"
5864 //sep.fUnlocked;1 or 0;byte;
5865 {0x5007, 0}, //"sprmSDmBinFirst"
5866 //sep.dmBinFirst;;word;
5867 {0x5008, 0}, //"sprmSDmBinOther"
5868 //sep.dmBinOther;;word;
5869 {0x3009, 0}, //"sprmSBkc" sep.bkc;bkc;byte;
5870 {0x300A, 0}, //"sprmSFTitlePage"
5871 //sep.fTitlePage;0 or 1;byte;
5872 {0x500B, 0}, //"sprmSCcolumns" sep.ccolM1;
5873 //# of cols - 1;word;
5874 {0x900C, 0}, //"sprmSDxaColumns"
5875 //sep.dxaColumns;dxa;word;
5876 {0x300D, 0}, //"sprmSFAutoPgn" sep.fAutoPgn;
5877 //obsolete;byte;
5878 {0x300E, 0}, //"sprmSNfcPgn" sep.nfcPgn;nfc;
5879 //byte;
5880 {0xB00F, 0}, //"sprmSDyaPgn" sep.dyaPgn;dya;
5881 //short;
5882 {0xB010, 0}, //"sprmSDxaPgn" sep.dxaPgn;dya;
5883 //short;
5884 {0x3011, 0}, //"sprmSFPgnRestart"
5885 //sep.fPgnRestart;0 or 1;byte;
5886 {0x3012, 0}, //"sprmSFEndnote" sep.fEndnote;
5887 //0 or 1;byte;
5888 {0x3013, 0}, //"sprmSLnc" sep.lnc;lnc;byte;
5889 {0x3014, 0}, //"sprmSGprfIhdt" sep.grpfIhdt;
5890 //grpfihdt; byte;
5891 {0x5015, 0}, //"sprmSNLnnMod" sep.nLnnMod;
5892 //non-neg int.;word;
5893 {0x9016, 0}, //"sprmSDxaLnn" sep.dxaLnn;dxa;
5894 //word;
5895 {0xB017, 0}, //"sprmSDyaHdrTop"
5896 //sep.dyaHdrTop;dya;word;
5897 {0xB018, 0}, //"sprmSDyaHdrBottom"
5898 //sep.dyaHdrBottom;dya;word;
5899 {0x3019, 0}, //"sprmSLBetween"
5900 //sep.fLBetween;0 or 1;byte;
5901 {0x301A, 0}, //"sprmSVjc" sep.vjc;vjc;byte;
5902 {0x501B, 0}, //"sprmSLnnMin" sep.lnnMin;lnn;
5903 //word;
5904 {0x501C, 0}, //"sprmSPgnStart" sep.pgnStart;
5905 //pgn;word;
5906 {0x301D, 0}, //"sprmSBOrientation"
5907 //sep.dmOrientPage;dm;byte;
5908 //0x301E, ? ? ?, //"sprmSBCustomize"
5909 {0xB01F, 0}, //"sprmSXaPage" sep.xaPage;xa;
5910 //word;
5911 {0xB020, 0}, //"sprmSYaPage" sep.yaPage;ya;
5912 //word;
5913 {0x2205, 0}, //"sprmSDxaLeft" sep.dxaLeft;
5914 //dxa;word;
5915 {0xB022, 0}, //"sprmSDxaRight" sep.dxaRight;
5916 //dxa;word;
5917 {0x9023, 0}, //"sprmSDyaTop" sep.dyaTop;dya;
5918 //word;
5919 {0x9024, 0}, //"sprmSDyaBottom"
5920 //sep.dyaBottom;dya;word;
5921 {0xB025, 0}, //"sprmSDzaGutter"
5922 //sep.dzaGutter;dza;word;
5923 {0x5026, 0}, //"sprmSDmPaperReq"
5924 //sep.dmPaperReq;dm;word;
5925 {0xD227, 0}, //"sprmSPropRMark"
5926 //sep.fPropRMark,
5927 //sep.ibstPropRMark,
5928 //sep.dttmPropRMark ;complex;
5929 //variable length always
5930 //recorded as 7 bytes;
5931 //0x3228, ? ? ?, //"sprmSFBiDi",
5932 //0x3229, ? ? ?, //"sprmSFFacingCol"
5933 {0x322A, 0}, //"sprmSFRTLGutter", set to 1
5934 //if gutter is on the right.
5935 {0x702B, 0}, //"sprmSBrcTop" sep.brcTop;BRC;
5936 //long;
5937 {0x702C, 0}, //"sprmSBrcLeft" sep.brcLeft;
5938 //BRC;long;
5939 {0x702D, 0}, //"sprmSBrcBottom"
5940 //sep.brcBottom;BRC;long;
5941 {0x702E, 0}, //"sprmSBrcRight" sep.brcRight;
5942 //BRC;long;
5943 {0x522F, 0}, //"sprmSPgbProp" sep.pgbProp;
5944 //word;
5945 {0x7030, 0}, //"sprmSDxtCharSpace"
5946 //sep.dxtCharSpace;dxt;long;
5947 {0x9031, 0}, //"sprmSDyaLinePitch"
5948 //sep.dyaLinePitch;dya;
5949 //WRONG:long; RIGHT:short; !
5950 //0x5032, ? ? ?, //"sprmSClm"
5951 {0x5033, 0}, //"sprmSTextFlow"
5952 //sep.wTextFlow;complex ;short
5953 {0x5400, 0}, //"sprmTJc" tap.jc;jc;word (low
5954 //order byte is significant);
5955 {0x9601, 0}, //"sprmTDxaLeft"
5956 //tap.rgdxaCenter; dxa; word;
5957 {0x9602, 0}, //"sprmTDxaGapHalf"
5958 //tap.dxaGapHalf,
5959 //tap.rgdxaCenter; dxa; word;
5960 {0x3403, 0}, //"sprmTFCantSplit"
5961 //tap.fCantSplit;1 or 0;byte;
5962 {0x3404, 0}, //"sprmTTableHeader"
5963 //tap.fTableHeader;1 or 0;byte;
5964 {0x3466, 0}, //"sprmTFCantSplit90"
5965 //tap.fCantSplit90;1 or 0;byte;
5966 {0xD605, 0}, //"sprmTTableBorders"
5967 //tap.rgbrcTable;complex;
5968 //24 bytes;
5969 {0xD606, 0}, //"sprmTDefTable10"
5970 //tap.rgdxaCenter,
5971 //tap.rgtc;complex; variable
5972 //length;
5973 {0x9407, 0}, //"sprmTDyaRowHeight"
5974 //tap.dyaRowHeight;dya;word;
5975 {0xD608, 0}, //"sprmTDefTable"
5976 //tap.rgtc;complex
5977 {0xD609, 0}, //"sprmTDefTableShd"
5978 //tap.rgshd;complex
5979 {0x740A, 0}, //"sprmTTlp" tap.tlp;TLP;
5980 //4 bytes;
5981 //0x560B, ? ? ?, //"sprmTFBiDi"
5982 //0x740C, ? ? ?, //"sprmTHTMLProps"
5983 {0xD620, 0}, //"sprmTSetBrc"
5984 //tap.rgtc[].rgbrc;complex;
5985 //5 bytes;
5986 {0x7621, 0}, //"sprmTInsert"
5987 //tap.rgdxaCenter,
5988 //tap.rgtc;complex ;4 bytes;
5989 {0x5622, 0}, //"sprmTDelete"
5990 //tap.rgdxaCenter,
5991 //tap.rgtc;complex ;word;
5992 {0x7623, 0}, //"sprmTDxaCol"
5993 //tap.rgdxaCenter;complex;
5994 //4 bytes;
5995 {0x5624, 0}, //"sprmTMerge"
5996 //tap.fFirstMerged,
5997 //tap.fMerged;complex; word;
5998 {0x5625, 0}, //"sprmTSplit"
5999 //tap.fFirstMerged,
6000 //tap.fMerged;complex ;word;
6001 {0xD626, 0}, //"sprmTSetBrc10"
6002 //tap.rgtc[].rgbrc;complex;
6003 //5 bytes;
6004 {0x7627, 0}, //"sprmTSetShd" tap.rgshd;
6005 //complex; 4 bytes;
6006 {0x7628, 0}, //"sprmTSetShdOdd"
6007 //tap.rgshd;complex;4 bytes;
6008 {0x7629, 0}, //"sprmTTextFlow"
6009 //tap.rgtc[].fVertical
6010 //tap.rgtc[].fBackward
6011 //tap.rgtc[].fRotateFont
6012 //0 or 10 or 10 or 1;word;
6013 //0xD62A, ? ? ? , //"sprmTDiagLine"
6014 {0xD62B, 0}, //"sprmTVertMerge"
6015 //tap.rgtc[].vertMerge;complex;
6016 //variable length always
6017 //recorded as 2 bytes;
6018 {0xD62C, 0}, //"sprmTVertAlign"
6019 //tap.rgtc[].vertAlign;complex
6020 //variable length always
6021 //recorded as 3 byte;
6022 {0xCA78, &SwWW8ImplReader::Read_DoubleLine_Rotate},
6023 {0x6649, 0}, //undocumented
6024 {0xF614, 0}, //"sprmTTableWidth"
6025 //recorded as 3 bytes;
6026 {0xD612, 0}, //undocumented
6027 {0xD613, 0}, //undocumented
6028 {0xD61A, 0}, //undocumented
6029 {0xD61B, 0}, //undocumented
6030 {0xD61C, 0}, //undocumented
6031 {0xD61D, 0}, //undocumented
6032 {0xD634, 0}, //undocumented
6033 {0xD632, 0}, //undocumented
6034 {0xD238, 0}, //undocumented sep
6035 {0xC64E, 0}, //undocumented
6036 {0xC64F, 0}, //undocumented
6037 {0xC650, 0}, //undocumented
6038 {0xC651, 0}, //undocumented
6039 {0xF661, 0}, //undocumented
6040 {0x4873, &SwWW8ImplReader::Read_Language}, //"sprmCRgLid3?" chp.rglid[0];
6041 //LID: for non-Far East text
6042 //(like a duplicate of 486D)
6043 {0x4874, 0}, //undocumented
6044 {0x6463, 0}, //undocumented
6045 {0x2461, &SwWW8ImplReader::Read_RTLJustify}, //undoc, must be asian version
6046 //of "sprmPJc"
6047 {0x845E, &SwWW8ImplReader::Read_LR}, //Apparently post-Word 97 version of "sprmPDxaLeft"
6048 {0x8460, &SwWW8ImplReader::Read_LR}, //Post-Word 97 version of "sprmPDxaLeft1"
6049 {0x845D, &SwWW8ImplReader::Read_LR}, //Post-Word 97 version of "sprmPDxaRight"
6050 {0x3615, 0}, //undocumented
6051 {0x360D, 0}, //undocumented
6052 {0x940E, 0}, //undocumented
6053 {0x940F, 0}, //undocumented
6054 {0x9410, 0}, //undocumented
6055 {0x703A, 0}, //undocumented
6056 {0x303B, 0}, //undocumented
6057 {0x244B, &SwWW8ImplReader::Read_TabCellEnd}, //undocumented, must be
6058 //subtable "sprmPFInTable"
6059 {0x244C, &SwWW8ImplReader::Read_TabRowEnd}, //undocumented, must be
6060 // subtable "sprmPFTtp"
6061 {0x6815, 0}, //undocumented
6062 {0x6816, 0}, //undocumented
6063 {0x6870, &SwWW8ImplReader::Read_TxtForeColor},
6064 {0xC64D, &SwWW8ImplReader::Read_ParaBackColor},
6065 {0x6467, 0}, //undocumented
6066 {0xF617, 0}, //undocumented
6067 {0xD660, 0}, //undocumented
6068 {0xD670, 0}, //undocumented
6069 {0xCA71, &SwWW8ImplReader::Read_TxtBackColor},//undocumented
6070 {0x303C, 0}, //undocumented
6071 {0x245B, &SwWW8ImplReader::Read_ParaAutoBefore},//undocumented, para
6072 {0x245C, &SwWW8ImplReader::Read_ParaAutoAfter},//undocumented, para
6073 {0x246D, &SwWW8ImplReader::Read_DontAddEqual}//undocumented, para
6076 static wwSprmDispatcher aSprmSrch(aSprms, sizeof(aSprms) / sizeof(aSprms[0]));
6077 return &aSprmSrch;
6080 //-----------------------------------------
6081 // Hilfsroutinen : SPRM finden
6082 //-----------------------------------------
6084 const SprmReadInfo& SwWW8ImplReader::GetSprmReadInfo(USHORT nId) const
6086 ww::WordVersion eVersion = pWwFib->GetFIBVersion();
6087 const wwSprmDispatcher *pDispatcher;
6088 if (eVersion <= ww::eWW2)
6089 pDispatcher = GetWW2SprmDispatcher();
6090 else if (eVersion < ww::eWW8)
6091 pDispatcher = GetWW6SprmDispatcher();
6092 else
6093 pDispatcher = GetWW8SprmDispatcher();
6095 SprmReadInfo aSrch = {0, 0};
6096 aSrch.nId = nId;
6097 const SprmReadInfo* pFound = pDispatcher->search(aSrch);
6099 if (!pFound)
6101 aSrch.nId = 0;
6102 pFound = pDispatcher->search(aSrch);
6105 return *pFound;
6108 //-----------------------------------------
6109 // Hilfsroutinen : SPRMs
6110 //-----------------------------------------
6111 void SwWW8ImplReader::EndSprm( USHORT nId )
6113 if( ( nId > 255 ) && ( nId < 0x0800 ) ) return;
6115 const SprmReadInfo& rSprm = GetSprmReadInfo( nId );
6117 if (rSprm.pReadFnc)
6118 (this->*rSprm.pReadFnc)( nId, 0, -1 );
6121 short SwWW8ImplReader::ImportSprm(const BYTE* pPos,USHORT nId)
6123 if (!nId)
6124 nId = mpSprmParser->GetSprmId(pPos);
6126 #if OSL_DEBUG_LEVEL > 1
6127 ASSERT( nId != 0xff, "Sprm FF !!!!" );
6128 #endif
6130 const SprmReadInfo& rSprm = GetSprmReadInfo(nId);
6132 USHORT nFixedLen = mpSprmParser->DistanceToData(nId);
6133 USHORT nL = mpSprmParser->GetSprmSize(nId, pPos);
6135 if (rSprm.pReadFnc)
6136 (this->*rSprm.pReadFnc)(nId, pPos + nFixedLen, nL - nFixedLen);
6138 return nL;
6141 /* vi:set tabstop=4 shiftwidth=4 expandtab: */